An agent can spawn sub-agents to delegate work to independent child sessions. Each sub-agent gets its own LLM session and tool access, runs concurrently with the parent, and returns its result when finished. This is useful for parallelizing research, isolating risky operations, or breaking complex tasks into focused pieces.
Sub-agents are only available with the API backend (the default). Agents using the CLI backend cannot spawn sub-agents.
Sub-agent management is exposed through four built-in tools:
| Tool | Description |
|---|
spawn_agent | Create a new sub-agent with a task prompt |
send_input | Send a follow-up message to a running sub-agent |
wait | Block until a sub-agent completes and return its result |
close_agent | Cancel and remove a running sub-agent |
These tools are registered automatically when the session starts. They inherit the parent’s permissions — no additional approval is needed for sub-agent tool calls.
spawn_agent
Creates a new sub-agent session and starts it working on the given task.
| Parameter | Type | Required | Description |
|---|
task | string | yes | The task description for the sub-agent |
working_dir | string | no | Working directory for the sub-agent |
model | string | no | Model to use for the sub-agent |
max_turns | integer | no | Maximum number of turns (default: 50) |
Returns the agent_id string used to reference this sub-agent in subsequent calls.
Sends a follow-up message to a running sub-agent. The message is queued and processed by the sub-agent on its next turn.
| Parameter | Type | Required | Description |
|---|
agent_id | string | yes | The ID returned by spawn_agent |
message | string | yes | The message to send |
wait
Blocks until the specified sub-agent completes, then returns its result. The result includes whether the sub-agent succeeded, how many turns it used, and the final text output.
| Parameter | Type | Required | Description |
|---|
agent_id | string | yes | The ID returned by spawn_agent |
Returns a formatted string:
Agent completed (success: true, turns: 12)
<final assistant message text>
close_agent
Cancels a running sub-agent and removes it. Use this to clean up sub-agents that are no longer needed.
| Parameter | Type | Required | Description |
|---|
agent_id | string | yes | The ID returned by spawn_agent |
Session isolation
Each sub-agent runs in its own independent session:
- Own LLM conversation — the sub-agent has a fresh conversation history starting from the task prompt. It does not see the parent’s prior conversation.
- Own tool access — the sub-agent has the same tools as the parent (shell, file editing, grep, etc.) and can use them independently.
- Concurrent execution — after
spawn_agent, the parent continues working immediately. The sub-agent runs in a background task. Use wait to collect the result when needed.
The parent can spawn multiple sub-agents and let them work in parallel, then wait on each to collect results:
1. spawn_agent("Research authentication patterns") -> agent_a
2. spawn_agent("Analyze the test suite structure") -> agent_b
3. ... parent does its own work ...
4. wait(agent_a) -> result_a
5. wait(agent_b) -> result_b
6. Synthesize both results
Depth limits
Sub-agents can themselves spawn sub-agents, creating a hierarchy. The maximum nesting depth prevents runaway chains. By default, the depth limit is 1 — a parent agent can spawn sub-agents, but those sub-agents cannot spawn their own children.
If a sub-agent tries to spawn beyond the depth limit, the spawn_agent call returns an error:
Maximum subagent depth (1) reached
The depth limit is set via the max_subagent_depth field in the session configuration.
Error handling
When a sub-agent fails, the error is captured and returned to the parent via the wait tool — the parent stage does not automatically fail. The parent LLM sees the error message and decides how to respond: retry, try a different approach, or report the failure.
Specific failure modes:
- Sub-agent hits
max_turns — The sub-agent stops naturally and returns its last output as a successful result. The parent sees a normal completion with the final assistant message.
- Sub-agent panics or errors — The error is captured and returned through
wait as a failure result. The parent can inspect the error and decide what to do.
spawn_agent fails (e.g. depth limit exceeded) — The error is returned immediately as a tool result. The parent can adjust its approach without waiting.
Event forwarding
Sub-agent events (tool calls, assistant messages, errors) are forwarded to the parent session’s event stream as SubAgentEvent wrappers. This means the parent’s progress log captures the full activity of all children, giving you visibility into what sub-agents are doing.
Key lifecycle events:
| Event | When |
|---|
SubAgentSpawned | A sub-agent was created |
SubAgentCompleted | A sub-agent finished successfully |
SubAgentFailed | A sub-agent encountered an error |
SubAgentClosed | A sub-agent was cancelled |
Streaming events (text deltas, tool output deltas) from sub-agents are filtered out to reduce noise.
When to use sub-agents
Sub-agents are most useful when:
- Parallel research — gather information from multiple parts of a codebase simultaneously
- Isolation — let a sub-agent try a risky approach without polluting the parent’s context
- Divide and conquer — break a large task into independent pieces that can be worked on concurrently
- Context management — offload work to a sub-agent when the parent’s context window is getting full
Sub-agents have a default turn limit of 50. For larger tasks, pass a higher max_turns when spawning. The parent agent is blocked during a wait call, so spawn sub-agents before starting the wait to maximize concurrency.