InitRunner

Agent Spec Import & Export

PydanticAI 1.71 introduced Agent Spec — a declarative JSON/YAML format for agents, loaded via Agent.from_file() / Agent.from_spec(). Since v2026.4.17, InitRunner imports Agent Specs into a role and can export a role back to the same format.

Old envelopes still load. Convert them with initrunner doctor --fix PATH. See Envelope Migration.

Use this when you want to adopt InitRunner's triggers, memory, RAG, or sandboxing on top of someone else's PydanticAI YAML — or when you need to hand off to a pure-PydanticAI runtime (CI, a non-InitRunner service, a colleague who doesn't use InitRunner yet). For tool-heavy custom agents, initrunner new --pydantic-ai and --langchain offer richer imports.

Import

Convert and run

There is no flag that runs an Agent Spec in place. Convert it to a role file first:

initrunner new --agent-spec ./greeter.agent-spec.yaml --output greeter.yaml

Given this spec:

# greeter.agent-spec.yaml
model: anthropic:claude-sonnet-4-6
name: greeter
description: Friendly greeter with templated instructions.
instructions: "You are greeting {{name}} from {{city}}."
deps_schema:
  type: object
  properties:
    name: {type: string}
    city: {type: string}
  required: [name, city]
retries: 3
end_strategy: exhaustive
tool_timeout: 15.0

Run the converted role with template variables:

initrunner run greeter.yaml \
  --var name=Alice --var city=Berlin \
  -p "please say hi"

Generated role

InitRunner writes a valid greeter.yaml:

name: greeter
description: Friendly greeter with templated instructions.
model:
  provider: anthropic
  name: claude-sonnet-4-6
prompt: "You are greeting {{name}} from {{city}}."
execution:
  retries: 3
  end_strategy: exhaustive
  tool_timeout_seconds: 15.0
deps_schema:
  type: object
  properties:
    name: {type: string}
    city: {type: string}
  required: [name, city]

Field mapping

PydanticAI Agent SpecInitRunner agent YAML
modelmodel (parses provider:name)
instructionsprompt
name / metadata.name / filename stemname (in that precedence)
descriptiondescription
model_settings.max_tokens / .temperaturemodel.max_tokens / .temperature
capabilitiescapabilities (same NamedSpec format)
retries, output_retries, end_strategy, tool_timeoutexecution.*
deps_schemadeps_schema (verbatim)
output_schemaoutput with type: json_schema
metadata.tags / .author / .team / .versiontags / author / team / version (round-trips through export too, since v2026.6.4)

Dropped with a warning at import time:

  • instrument — use observability instead.
  • json_schema_path — InitRunner doesn't need the companion schema path.
  • Any model_settings keys beyond max_tokens and temperature.
  • Any Agent Spec metadata keys beyond name, tags, author, team, and version (the descriptive four since v2026.6.4; supported keys are imported, the rest dropped).

Template variables

If the spec's instructions (or a role's prompt) contains {{var}} placeholders, declare them in deps_schema and supply values at run time with --var:

initrunner run greeter/role.yaml -p "be polite" --var name=Alice --var city=Berlin

--var is repeatable. Missing required variables raise an error at run time; undeclared variables raise at load time. Rendering happens through a dynamic system-prompt hook — the raw {{...}} never reaches the model.

v1 scope. deps_schema is enforced as a flat-scalar object: string, integer, number, boolean. Nested objects, arrays, $ref, and oneOf raise RoleLoadError. The --var flag applies to CLI initrunner run. Since v2026.6.5, daemon, trigger, bot, and flow runs resolve declared variables from INITRUNNER_VAR_<NAME> environment variables (the uppercased deps_schema property name), since those runtimes have no --var. CLI --var still takes precedence.

Execution semantics

Agent Spec's retries, output_retries, end_strategy, and tool_timeout map onto execution on the InitRunner side, distinct from guardrails budgets. execution is also available directly in a handwritten role.yaml.

The importer accepts end_strategy: early, graceful, or exhaustive. Since v2026.6.7 the default is graceful, and the exporter omits end_strategy from the Agent Spec when it equals that default.

Export

initrunner export agent-spec ./greeter/role.yaml

Writes greeter.agent-spec.yaml plus a companion JSON Schema (.schema.json) in the same directory. The schema covers only the overlap between role.yaml and Agent Spec — fields like triggers, ingest, memory, skills, sinks, autonomy, reasoning, guardrails, and security are dropped (the CLI prints a warning table showing which ones).

Since v2026.6.4, the descriptive identity fields tags, author, team, and version survive export into the Agent Spec's free-form metadata block (and import back from it), so they round-trip rather than being dropped.

Round-trip validation:

uv run python -c "
from pydantic_ai.agent.spec import AgentSpec
import yaml
AgentSpec.model_validate(yaml.safe_load(open('greeter.agent-spec.yaml')))
"

This passes on any export — the emitted spec is always upstream-valid, minus pydantic-handlebars for templated instructions (that's an optional extra on the upstream package).

Export is lossy by design. Agent Spec models a smaller surface area than role.yaml.

See also

On this page