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 reads Agent Specs directly for one-off runs and can export a role back to the same format.
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
Transient run
Run any Agent Spec as a one-off without converting it to a role:
initrunner run --agent-spec ./greeter.agent-spec.yaml -p "hello"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.0Run it with template variables:
initrunner run --agent-spec greeter.agent-spec.yaml \
--var name=Alice --var city=Berlin \
-p "please say hi"Persistent role
To keep the imported role on disk, use initrunner new:
initrunner new greeter --agent-spec ./greeter.agent-spec.yamlInitRunner writes a valid role.yaml:
apiVersion: initrunner/v1
kind: Agent
metadata:
name: greeter
description: Friendly greeter with templated instructions.
spec:
role: "You are greeting {{name}} from {{city}}."
model:
provider: anthropic
name: claude-sonnet-4-6
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 Spec | InitRunner role.yaml |
|---|---|
model | spec.model (parses provider:name) |
instructions | spec.role |
name / metadata.name / filename stem | metadata.name (in that precedence) |
description | metadata.description |
model_settings.max_tokens / .temperature | spec.model.max_tokens / .temperature |
capabilities | spec.capabilities (same NamedSpec format) |
retries, output_retries, end_strategy, tool_timeout | spec.execution.* |
deps_schema | spec.deps_schema (verbatim) |
output_schema | spec.output with type: json_schema |
Dropped with a warning at import time:
instrument— usespec.observabilityinstead.json_schema_path— InitRunner doesn't need the companion schema path.- Any
model_settingskeys beyondmax_tokensandtemperature.
Template variables
If the spec's instructions (or a role's spec.role) contains {{var}} placeholders, declare them in spec.deps_schema and supply values at run time with --var:
initrunner run greeter/role.yaml "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 is wired into single-shot initrunner run only; interactive, autonomous, and daemon modes do not thread variables yet.
Execution semantics
Agent Spec's retries, output_retries, end_strategy, and tool_timeout map onto spec.execution on the InitRunner side, distinct from spec.guardrails budgets. spec.execution is also available directly in a handwritten role.yaml.
Export
initrunner export agent-spec ./greeter/role.yamlWrites 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).
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
- CLI Reference:
run --agent-specandexport agent-spec - Configuration:
spec.execution - PydanticAI import for code-based PydanticAI agents
- LangChain import for LangChain agents