> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ziro-agent.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Build a code-first agent with ziro.create_agent, the AgentSpec tree, and ziro.profiles.load.

This page will document the code-first API in the `ziro` package. `ziro.create_agent(...)`
assembles an agent from pluggable objects (an `LLMAdapter`, guardrail backends,
`BaseTool` instances, a `BaseStore`, a `BaseCheckpointSaver`, and policy configs)
into the frozen `AgentSpec` tree defined in `ziro/spec.py`. A `SpecProfile` adapts
that spec to the same `AgentProfile` duck-type the engine consumes, so a
code-first agent runs through the identical graph as a YAML one. Chatting is
`agent.chat("hi", user="alice")`, with the user bound at chat time.

`ziro.profiles.load(<agent-id-or-path>)` goes the other way: it parses a YAML agent
folder into an `AgentSpec`, and is tested for equivalence against the shipped
agents.

The defaults are deliberately hermetic, so the same script behaves the same on two
machines. A spec-driven agent reads **no** project config layers (only spec fields
and library defaults), runs **outside** flavours, and surfaces **zero** plugins.
Opt into plugins explicitly with `create_agent(plugins=True)`, an allowlist such as
`plugins=["cc/x"]`, or a full `PluginConfig`; a bare string raises `TypeError`.

<Note>
  This page is in progress. See [architecture](/concepts/architecture) for the graph
  the SDK builds against and [agent files](/reference/agent-files) for the YAML
  equivalents of each spec field.
</Note>

<Columns cols={2}>
  <Card title="Architecture" icon="layers" href="/concepts/architecture">
    The agent loop an `AgentSpec` is compiled into.
  </Card>

  <Card title="Agent files" icon="folder" href="/reference/agent-files">
    The YAML side of the same configuration surface.
  </Card>
</Columns>
