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 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.0

Run 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.yaml

InitRunner 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 SpecInitRunner role.yaml
modelspec.model (parses provider:name)
instructionsspec.role
name / metadata.name / filename stemmetadata.name (in that precedence)
descriptionmetadata.description
model_settings.max_tokens / .temperaturespec.model.max_tokens / .temperature
capabilitiesspec.capabilities (same NamedSpec format)
retries, output_retries, end_strategy, tool_timeoutspec.execution.*
deps_schemaspec.deps_schema (verbatim)
output_schemaspec.output with type: json_schema

Dropped with a warning at import time:

  • instrument — use spec.observability instead.
  • json_schema_path — InitRunner doesn't need the companion schema path.
  • Any model_settings keys beyond max_tokens and temperature.

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.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).

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