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)
¶
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]
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 |
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
|
None
|
summarization_model
|
str | None
|
Model to use for LLM-based context compression
summaries (e.g., |
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 |
False
|
memory_dir
|
str | None
|
Base directory for memory files in the backend.
Each agent gets its own subdirectory:
|
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
|
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
|
False
|
checkpoint_frequency
|
str
|
When to auto-save checkpoints:
|
'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 |
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 |
False
|
web_search_provider
|
Any | None
|
Custom search provider implementing
:class: |
None
|
include_history_archive
|
bool
|
Whether to persist full conversation history
before context compression discards messages. Adds a
|
True
|
history_messages_path
|
str
|
Path to the messages.json file that stores
the full conversation history. Defaults to
|
'.pydantic-deep/messages.json'
|
middleware
|
Sequence[Any] | None
|
List of AgentMiddleware instances to wrap the agent with.
Requires pydantic-ai-middleware package (install with
|
None
|
permission_handler
|
Any | None
|
Async callback for tool permission decisions.
Called when middleware returns ToolDecision.ASK. Signature:
|
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 |
None
|
model_settings
|
dict[str, Any] | None
|
Provider-specific model settings (temperature, thinking,
etc.). Passed directly to the pydantic-ai Agent. Common keys:
|
None
|
instrument
|
bool | None
|
Enable OpenTelemetry/Logfire instrumentation. When True,
the agent emits spans for LLM calls, tool invocations, and token
usage. Requires |
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
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¶
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¶
Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
backend |
BackendProtocol \| None |
StateBackend() |
File storage backend |
Returns¶
DeepAgentDeps - Configured dependencies instance.
Example¶
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") |
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¶
@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¶
Generate system prompt section for current todos.
get_files_summary¶
Generate summary of files in memory.
get_subagents_summary¶
Generate summary of available subagents.
clone_for_subagent¶
Create isolated dependencies for a subagent.
- Same backend (shared)
- Empty todos (isolated)
- Empty subagents (no nested delegation)
- Same files (shared reference)
Example¶
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