Skip to content

Agent API

create_deep_agent

pydantic_deep.agent.create_deep_agent(model=None, instructions=None, output_style=None, styles_dir=None, tools=None, toolsets=None, subagents=None, skills=None, skill_directories=None, backend=None, include_todo=True, include_filesystem=True, include_subagents=True, include_skills=True, include_general_purpose_subagent=True, include_plan=True, max_nesting_depth=0, subagent_registry=None, subagent_extra_toolsets=None, include_execute=None, interrupt_on=None, output_type=None, history_processors=None, eviction_token_limit=None, image_support=False, edit_format='hashline', context_manager=True, context_manager_max_tokens=None, on_context_update=None, summarization_model=None, context_files=None, context_discovery=False, include_memory=False, memory_dir=None, retries=3, hooks=None, patch_tool_calls=False, include_checkpoints=False, checkpoint_frequency='every_tool', max_checkpoints=20, checkpoint_store=None, include_teams=False, include_web=False, web_search_provider=None, include_history_archive=True, history_messages_path='.pydantic-deep/messages.json', cost_tracking=True, cost_budget_usd=None, on_cost_update=None, middleware=None, permission_handler=None, middleware_context=None, plans_dir=None, model_settings=None, instrument=None, **agent_kwargs)

Python
create_deep_agent(model: str | Model | None = None, instructions: str | None = None, output_style: str | Any | None = None, styles_dir: str | list[str] | None = None, tools: Sequence[Tool[DeepAgentDeps] | Any] | None = None, toolsets: Sequence[AbstractToolset[DeepAgentDeps]] | None = None, subagents: list[SubAgentConfig] | None = None, skills: list[Skill] | None = None, skill_directories: list[SkillDirectory] | list[str] | list[BackendSkillsDirectory] | None = None, backend: BackendProtocol | None = None, include_todo: bool = True, include_filesystem: bool = True, include_subagents: bool = True, include_skills: bool = True, include_general_purpose_subagent: bool = True, include_plan: bool = True, max_nesting_depth: int = 0, subagent_registry: Any | None = None, subagent_extra_toolsets: Sequence[AbstractToolset[Any]] | None = None, include_execute: bool | None = None, interrupt_on: dict[str, bool] | None = None, output_type: None = None, history_processors: Sequence[HistoryProcessor[DeepAgentDeps]] | None = None, eviction_token_limit: int | None = None, image_support: bool = False, edit_format: str = 'hashline', context_manager: bool = True, context_manager_max_tokens: int | None = None, on_context_update: Any | None = None, summarization_model: str | None = None, context_files: list[str] | None = None, context_discovery: bool = False, include_memory: bool = False, memory_dir: str | None = None, retries: int = 3, hooks: list[Any] | None = None, patch_tool_calls: bool = False, include_checkpoints: bool = False, checkpoint_frequency: str = 'every_tool', max_checkpoints: int = 20, checkpoint_store: Any | None = None, include_teams: bool = False, include_web: bool = False, web_search_provider: Any | None = None, include_history_archive: bool = True, history_messages_path: str = '.pydantic-deep/messages.json', cost_tracking: bool = True, cost_budget_usd: float | None = None, on_cost_update: Any | None = None, middleware: Sequence[Any] | None = None, permission_handler: Any | None = None, middleware_context: Any | None = None, plans_dir: str | None = None, model_settings: dict[str, Any] | None = None, instrument: bool | None = None, **agent_kwargs: Any) -> Agent[DeepAgentDeps, str]
Python
create_deep_agent(model: str | Model | None = None, instructions: str | None = None, output_style: str | Any | None = None, styles_dir: str | list[str] | None = None, tools: Sequence[Tool[DeepAgentDeps] | Any] | None = None, toolsets: Sequence[AbstractToolset[DeepAgentDeps]] | None = None, subagents: list[SubAgentConfig] | None = None, skills: list[Skill] | None = None, skill_directories: list[SkillDirectory] | list[str] | list[BackendSkillsDirectory] | None = None, backend: BackendProtocol | None = None, include_todo: bool = True, include_filesystem: bool = True, include_subagents: bool = True, include_skills: bool = True, include_general_purpose_subagent: bool = True, include_plan: bool = True, max_nesting_depth: int = 0, subagent_registry: Any | None = None, subagent_extra_toolsets: Sequence[AbstractToolset[Any]] | None = None, include_execute: bool | None = None, interrupt_on: dict[str, bool] | None = None, *, output_type: OutputSpec[OutputDataT], history_processors: Sequence[HistoryProcessor[DeepAgentDeps]] | None = None, eviction_token_limit: int | None = None, image_support: bool = False, edit_format: str = 'hashline', context_manager: bool = True, context_manager_max_tokens: int | None = None, on_context_update: Any | None = None, summarization_model: str | None = None, context_files: list[str] | None = None, context_discovery: bool = False, include_memory: bool = False, memory_dir: str | None = None, retries: int = 3, hooks: list[Any] | None = None, patch_tool_calls: bool = False, include_checkpoints: bool = False, checkpoint_frequency: str = 'every_tool', max_checkpoints: int = 20, checkpoint_store: Any | None = None, include_teams: bool = False, include_web: bool = False, web_search_provider: Any | None = None, include_history_archive: bool = True, history_messages_path: str = '.pydantic-deep/messages.json', cost_tracking: bool = True, cost_budget_usd: float | None = None, on_cost_update: Any | None = None, middleware: Sequence[Any] | None = None, permission_handler: Any | None = None, middleware_context: Any | None = None, plans_dir: str | None = None, model_settings: dict[str, Any] | None = None, instrument: bool | None = None, **agent_kwargs: Any) -> Agent[DeepAgentDeps, OutputDataT]

Create a deep agent with planning, filesystem, subagent, and skills capabilities.

This factory function creates a fully-configured Agent with: - Todo toolset for task planning and tracking - Filesystem toolset for file operations - Subagent toolset for task delegation - Skills toolset for modular capability extension - Dynamic system prompts based on current state - Optional structured output via output_type - Optional history processing (e.g., summarization)

Parameters:

Name Type Description Default
model str | Model | None

Model to use (default: openai:gpt-4.1).

None
instructions str | None

Custom instructions for the agent.

None
output_style str | Any | None

Output style to apply to agent responses. Can be a string name of a built-in style ("concise", "explanatory", "formal", "conversational"), a custom OutputStyle instance, or a string name to look up in styles_dir. None (default) means no style override.

None
styles_dir str | list[str] | None

Directory or list of directories to discover custom output styles from. Style files are markdown files with YAML frontmatter (name, description) in the directory root.

None
tools Sequence[Tool[DeepAgentDeps] | Any] | None

Additional tools to register.

None
toolsets Sequence[AbstractToolset[DeepAgentDeps]] | None

Additional toolsets to register.

None
subagents list[SubAgentConfig] | None

Subagent configurations for the task tool.

None
skills list[Skill] | None

Pre-loaded skills to make available (new Skill dataclass instances).

None
skill_directories list[SkillDirectory] | list[str] | list[BackendSkillsDirectory] | None

Directories to discover skills from. Accepts legacy SkillDirectory TypedDicts, plain string paths, or BackendSkillsDirectory instances for backend-based skills.

None
backend BackendProtocol | None

File storage backend (default: StateBackend).

None
include_todo bool

Whether to include the todo toolset.

True
include_filesystem bool

Whether to include the filesystem toolset.

True
include_subagents bool

Whether to include the subagent toolset.

True
include_skills bool

Whether to include the skills toolset.

True
include_general_purpose_subagent bool

Whether to include a general-purpose subagent.

True
include_plan bool

Whether to include the built-in 'planner' subagent that provides Claude Code-style plan mode. The planner analyzes code, asks clarifying questions via ask_user, and creates step-by-step implementation plans saved to markdown files. Requires include_subagents=True. Defaults to True.

True
max_nesting_depth int

Maximum subagent nesting depth. 0 (default) means subagents cannot spawn their own subagents. Set to 1+ to allow nested delegation (subagents creating subagents).

0
subagent_registry Any | None

Optional DynamicAgentRegistry instance. When provided, the task tool will also look up dynamically created agents from the registry (created via create_agent_factory_toolset).

None
include_execute bool | None

Whether to include the execute tool. If None (default), automatically determined based on whether backend is a SandboxProtocol. Set to True to force include even when backend is None (useful when backend is provided via deps at runtime).

None
interrupt_on dict[str, bool] | None

Map of tool names to approval requirements. e.g., {"execute": True, "write_file": True}

None
output_type OutputSpec[OutputDataT] | None

Structured output type (Pydantic model, dataclass, TypedDict). When specified, the agent will return this type instead of str.

None
history_processors Sequence[HistoryProcessor[DeepAgentDeps]] | None

Sequence of history processors to apply to messages before sending to the model. Useful for summarization, filtering, etc.

None
eviction_token_limit int | None

Token threshold for large tool output eviction. When set, tool outputs exceeding this limit are saved to files and replaced with a preview + file reference. None (default) disables eviction. Typical value: 20000.

None
image_support bool

Whether to enable image file handling in read_file.

False
context_manager bool

Whether to enable the ContextManagerMiddleware for automatic token tracking and auto-compression. When True (default), the middleware monitors token usage and triggers LLM-based summarization when approaching the token budget. Also provides tool output truncation when middleware wrapping is active.

True
context_manager_max_tokens int | None

Maximum token budget for the conversation. When None (default), auto-detected from genai-prices based on the model name. Falls back to 200,000 if model is not found. Used by ContextManagerMiddleware to calculate usage percentage and determine when to trigger auto-compression. Defaults to 200,000.

None
on_context_update Any | None

Callback for context usage updates. Called with (percentage, current_tokens, max_tokens) before each model call. Supports both sync and async callables. Useful for UI display. When True, reading image files (.png, .jpg, .jpeg, .gif, .webp) returns a BinaryContent object that multimodal models can see, instead of garbled text. Defaults to False.

None
summarization_model str | None

Model to use for LLM-based context compression summaries (e.g., "openai:gpt-4.1-mini"). When None (default), the middleware uses its own default. Passed through to ContextManagerMiddleware.summarization_model.

None
context_files list[str] | None

List of paths to context files in the backend (e.g., ["/project/DEEP.md", "/project/SOUL.md"]). Files are loaded from the runtime backend (ctx.deps.backend) and injected into the system prompt. Missing files are silently skipped.

None
context_discovery bool

Whether to auto-discover context files at the backend root (/). Scans for DEEP.md, AGENTS.md, CLAUDE.md, SOUL.md. Defaults to False.

False
include_memory bool

Whether to include the agent memory toolset. When True, the main agent and all subagents get persistent memory stored as MEMORY.md files in the backend. Memory is auto-loaded into the system prompt and writable via tools (read_memory, write_memory, update_memory). Per-subagent memory can be disabled via extra={"memory": False} in SubAgentConfig. Defaults to False.

False
memory_dir str | None

Base directory for memory files in the backend. Each agent gets its own subdirectory: {memory_dir}/{agent_name}/MEMORY.md. Defaults to /.deep/memory.

None
retries int

Maximum number of retries for tool calls. Defaults to 3.

3
hooks list[Any] | None

List of Hook instances for Claude Code-style lifecycle hooks. Hooks execute shell commands or Python handlers on tool events (PRE_TOOL_USE, POST_TOOL_USE, POST_TOOL_USE_FAILURE). Command hooks require a SandboxProtocol backend (LocalBackend or DockerSandbox). Automatically wraps the agent with HooksMiddleware (requires pydantic-ai-middleware package).

None
cost_tracking bool

Whether to enable automatic cost tracking via CostTrackingMiddleware. When True (default), token usage and USD costs are tracked across runs. Requires wrapping with MiddlewareAgent (triggered automatically). Disable with cost_tracking=False for plain Agent without middleware.

True
cost_budget_usd float | None

Maximum allowed cumulative cost in USD. When exceeded, the next run raises BudgetExceededError. None (default) means unlimited.

None
on_cost_update Any | None

Callback for cost updates after each run. Called with a CostInfo object containing run and cumulative token/cost data. Supports sync and async callables.

None
patch_tool_calls bool

Whether to enable PatchToolCallsProcessor that fixes orphaned tool calls in message history. Useful when resuming interrupted conversations. Defaults to False.

False
include_checkpoints bool

Whether to enable conversation checkpointing. When True, adds CheckpointMiddleware (auto-saves snapshots) and CheckpointToolset (save_checkpoint, list_checkpoints, rewind_to tools). The checkpoint store is resolved from checkpoint_store param or deps.checkpoint_store at runtime. Defaults to False.

False
checkpoint_frequency str

When to auto-save checkpoints: "every_tool" (default) — after each tool call, "every_turn" — before each model request, "manual_only" — only via the save_checkpoint tool.

'every_tool'
max_checkpoints int

Maximum number of checkpoints to keep. Oldest checkpoints are pruned when this limit is exceeded. Defaults to 20.

20
checkpoint_store Any | None

Checkpoint storage backend. When None (default), uses InMemoryCheckpointStore. Can also be set per-session via deps.checkpoint_store.

None
include_teams bool

Whether to include the team management toolset. When True, adds tools for spawning agent teams, assigning tasks via shared todo lists, messaging teammates, and dissolving teams. Defaults to False.

False
include_web bool

Whether to include the web toolset (web_search, fetch_url, http_request). Requires pip install 'pydantic-deep[web-tools]'. Defaults to False.

False
web_search_provider Any | None

Custom search provider implementing :class:~pydantic_deep.toolsets.web.SearchProvider. Defaults to :class:~pydantic_deep.toolsets.web.TavilySearchProvider (requires TAVILY_API_KEY env var).

None
include_history_archive bool

Whether to persist full conversation history before context compression discards messages. Adds a search_conversation_history tool so the agent can look up details from before compression. Only active when context_manager=True. Defaults to True.

True
history_messages_path str

Path to the messages.json file that stores the full conversation history. Defaults to ".pydantic-deep/messages.json".

'.pydantic-deep/messages.json'
middleware Sequence[Any] | None

List of AgentMiddleware instances to wrap the agent with. Requires pydantic-ai-middleware package (install with pip install pydantic-deep[middleware]). When provided, the agent is wrapped in a MiddlewareAgent with lifecycle hooks.

None
permission_handler Any | None

Async callback for tool permission decisions. Called when middleware returns ToolDecision.ASK. Signature: async (tool_name, tool_args, reason) -> bool.

None
middleware_context Any | None

MiddlewareContext instance for sharing state between middleware hooks. Optional.

None
plans_dir str | None

Directory to save plan files from the planner subagent. Defaults to /plans (relative to backend root).

None
model_settings dict[str, Any] | None

Provider-specific model settings (temperature, thinking, etc.). Passed directly to the pydantic-ai Agent. Common keys: temperature, max_tokens, anthropic_thinking, openai_reasoning_effort. See pydantic-ai ModelSettings docs.

None
instrument bool | None

Enable OpenTelemetry/Logfire instrumentation. When True, the agent emits spans for LLM calls, tool invocations, and token usage. Requires logfire or OpenTelemetry SDK. None (default) means no instrumentation.

None
**agent_kwargs Any

Additional arguments passed to Agent constructor.

{}

Returns:

Type Description
Agent[DeepAgentDeps, OutputDataT] | Agent[DeepAgentDeps, str]

Configured Agent instance. Returns Agent[DeepAgentDeps, OutputDataT] if

Agent[DeepAgentDeps, OutputDataT] | Agent[DeepAgentDeps, str]

output_type is specified, otherwise Agent[DeepAgentDeps, str].

Example
Python
from pydantic import BaseModel
from pydantic_deep import (
    create_deep_agent, DeepAgentDeps, StateBackend, create_summarization_processor
)

# Basic usage with string output
agent = create_deep_agent(
    model="openai:gpt-4.1",
    instructions="You are a coding assistant",
)

# With structured output
class CodeAnalysis(BaseModel):
    language: str
    issues: list[str]
    suggestions: list[str]

agent = create_deep_agent(
    output_type=CodeAnalysis,
)

# Context management is ON by default (token tracking + auto-compression)
# Disable it or customize:
agent = create_deep_agent(context_manager=False)
agent = create_deep_agent(
    context_manager_max_tokens=128_000,
    on_context_update=lambda pct, cur, mx: print(f"{pct:.0%} used"),
)

deps = DeepAgentDeps(backend=StateBackend())
result = await agent.run("Analyze this code", deps=deps)

Parameters

Core

Parameter Type Default Description
model str \| Model \| None "openai:gpt-4.1" LLM model identifier
instructions str \| None Default instructions System prompt for the agent
output_style str \| OutputStyle \| None None Output style (built-in name or custom)
styles_dir str \| list[str] \| None None Directories for custom style files
tools Sequence[Tool \| Any] \| None None Additional custom tools
toolsets Sequence[AbstractToolset] \| None None Additional toolsets
backend BackendProtocol \| None StateBackend() File storage backend
output_type OutputSpec \| None None Pydantic model for structured output
retries int 3 Max retries for tool calls

Feature Toggles

Parameter Type Default Description
include_todo bool True Include TodoToolset
include_filesystem bool True Include Console Toolset
include_subagents bool True Include SubAgentToolset
include_skills bool True Include SkillsToolset
include_general_purpose_subagent bool True Include general-purpose subagent
include_plan bool True Include planner subagent
include_execute bool \| None None Include execute tool (auto-detected)
include_memory bool False Persistent agent memory
include_checkpoints bool False Conversation checkpointing
include_teams bool False Agent teams with shared todos
image_support bool False Image file handling
patch_tool_calls bool False Fix orphaned tool calls

Subagents

Parameter Type Default Description
subagents list[SubAgentConfig] \| None None Subagent configurations
max_nesting_depth int 0 Max subagent nesting depth
subagent_registry DynamicAgentRegistry \| None None Dynamic agent registry

Skills

Parameter Type Default Description
skills list[Skill] \| None None Pre-loaded skills
skill_directories list \| None None Skill discovery directories

Context Management

Parameter Type Default Description
context_manager bool True Token tracking + auto-compression
context_manager_max_tokens int 200,000 Token budget
on_context_update Callable \| None None Callback: (pct, current, max)
context_files list[str] \| None None Context file paths
context_discovery bool False Auto-discover DEEP.md, AGENTS.md, etc.
history_processors Sequence \| None None History processors
eviction_token_limit int \| None None Large output eviction threshold

Checkpointing

Parameter Type Default Description
checkpoint_frequency str "every_tool" Auto-save frequency
max_checkpoints int 20 Max checkpoints to keep
checkpoint_store CheckpointStore \| None None Checkpoint storage backend

Memory

Parameter Type Default Description
memory_dir str \| None "/.deep/memory" Base directory for memory files

Cost Tracking

Parameter Type Default Description
cost_tracking bool True Enable cost tracking
cost_budget_usd float \| None None Max cumulative cost
on_cost_update Callable \| None None Callback with CostInfo

Middleware

Parameter Type Default Description
middleware Sequence[AgentMiddleware] \| None None Custom middleware
permission_handler Callable \| None None Permission callback
middleware_context MiddlewareContext \| None None Shared middleware state
hooks list[Hook] \| None None Claude Code-style hooks

Other

Parameter Type Default Description
interrupt_on dict[str, bool] \| None None Tools requiring approval
plans_dir str \| None "/plans" Directory for plan files
**agent_kwargs Any - Additional Agent constructor args

Returns

Agent[DeepAgentDeps, str] or Agent[DeepAgentDeps, OutputDataT] - Configured Pydantic AI agent.

When output_type is provided, returns an agent typed with the output model.

Example

Python
from pydantic_deep import create_deep_agent, SubAgentConfig

agent = create_deep_agent(
    model="openai:gpt-4.1",
    instructions="You are a coding assistant.",
    subagents=[
        SubAgentConfig(
            name="reviewer",
            description="Reviews code",
            instructions="Review code for issues.",
        ),
    ],
    skill_directories=[
        {"path": "~/.pydantic-deep/skills", "recursive": True},
    ],
    interrupt_on={"execute": True},
)

create_default_deps

pydantic_deep.agent.create_default_deps(backend=None)

Create default dependencies for a deep agent.

Parameters:

Name Type Description Default
backend BackendProtocol | None

File storage backend (default: StateBackend).

None

Returns:

Type Description
DeepAgentDeps

DeepAgentDeps instance.

Signature

Python
def create_default_deps(
    backend: BackendProtocol | None = None,
) -> DeepAgentDeps

Parameters

Parameter Type Default Description
backend BackendProtocol \| None StateBackend() File storage backend

Returns

DeepAgentDeps - Configured dependencies instance.

Example

Python
from pydantic_deep import create_default_deps
from pydantic_ai_backends import LocalBackend

# With default StateBackend
deps = create_default_deps()

# With custom backend
deps = create_default_deps(backend=LocalBackend("/workspace"))

DeepAgentDeps

pydantic_deep.deps.DeepAgentDeps dataclass

Dependencies for deep agents.

This container holds all the state and resources needed by the agent and its tools during execution.

Attributes:

Name Type Description
backend BackendProtocol

File storage backend (StateBackend, FilesystemBackend, etc.)

files dict[str, FileData]

In-memory file cache (used with StateBackend)

todos list[Todo]

Task list for planning

subagents dict[str, Any]

Pre-configured subagents available for delegation

__post_init__()

Initialize backend with files if using StateBackend.

get_todo_prompt()

Generate system prompt section for todos.

get_files_summary()

Generate summary of files in memory.

get_subagents_summary()

Generate summary of available subagents.

upload_file(name, content, *, upload_dir='/uploads')

Upload a file to the backend and track it.

The file is written to the backend and its metadata is stored for display in the system prompt.

Parameters:

Name Type Description Default
name str

Original filename (e.g., "sales.csv")

required
content bytes

File content as bytes

required
upload_dir str

Directory to store uploads (default: "/uploads")

'/uploads'

Returns:

Type Description
str

The path where the file was stored (e.g., "/uploads/sales.csv")

Example
Python
deps = DeepAgentDeps(backend=StateBackend())
path = deps.upload_file("data.csv", csv_bytes)
# Agent can now access the file at /uploads/data.csv

get_uploads_summary()

Generate summary of uploaded files for system prompt.

clone_for_subagent(max_depth=0)

Create a new deps instance for a subagent.

Subagents get: - Same backend (shared) - Empty todos (isolated) — or same todos if share_todos=True - Empty subagents (no nested delegation by default) - Same files (shared) - Same uploads (shared)

Parameters:

Name Type Description Default
max_depth int

Maximum nesting depth for subagent. If > 0, subagents dict is copied to allow nested delegation.

0

Definition

Python
@dataclass
class DeepAgentDeps:
    backend: BackendProtocol = field(default_factory=StateBackend)
    files: dict[str, FileData] = field(default_factory=dict)
    todos: list[Todo] = field(default_factory=list)
    subagents: dict[str, Any] = field(default_factory=dict)
    uploads: dict[str, UploadedFile] = field(default_factory=dict)
    ask_user: Callable | None = None
    share_todos: bool = False
    checkpoint_store: CheckpointStore | None = None

Attributes

Attribute Type Description
backend BackendProtocol File storage backend
files dict[str, FileData] In-memory file cache
todos list[Todo] Task list
subagents dict[str, Any] Pre-configured subagent instances
uploads dict[str, UploadedFile] Uploaded files metadata
ask_user Callable \| None Callback for planner's ask_user tool
share_todos bool When True, subagents share parent's todo list
checkpoint_store CheckpointStore \| None Per-session checkpoint store

Methods

get_todo_prompt

Python
def get_todo_prompt(self) -> str

Generate system prompt section for current todos.

get_files_summary

Python
def get_files_summary(self) -> str

Generate summary of files in memory.

get_subagents_summary

Python
def get_subagents_summary(self) -> str

Generate summary of available subagents.

clone_for_subagent

Python
def clone_for_subagent(self) -> DeepAgentDeps

Create isolated dependencies for a subagent.

  • Same backend (shared)
  • Empty todos (isolated)
  • Empty subagents (no nested delegation)
  • Same files (shared reference)

Example

Python
from pydantic_deep import DeepAgentDeps, StateBackend, Todo

deps = DeepAgentDeps(
    backend=StateBackend(),
    todos=[
        Todo(
            content="Review code",
            status="pending",
            active_form="Reviewing code",
        ),
    ],
)

# Access todo prompt
print(deps.get_todo_prompt())

# Clone for subagent
subagent_deps = deps.clone_for_subagent()
assert subagent_deps.todos == []  # Isolated
assert subagent_deps.backend is deps.backend  # Shared