Sub-agents
A sub-agent is a delegation target the model sees as a tool. Calling it spawns a full child session; the child's result folds back into the parent like a tool result.
Example
The parent declares a sub-agent. Both agents live on one worker, told apart by
agent_id.
function assistant({ trigger, proposed }) {
if (trigger.type === "session.start") {
return {
agent: {
model: "claude-haiku-4-5-20251001",
stream: true,
sub_agents: [{ id: "poet", description: "Writes a haiku on any topic." }]
}
};
}
return proposed;
}
function poet({ trigger, proposed }) {
if (trigger.type === "session.start") {
return {
agent: {
model: "claude-haiku-4-5-20251001",
stream: true,
system: "You are a poet. Respond with a single haiku."
}
};
}
return proposed;
}
// One worker, two agents told apart by agent_id.
const decide = (req) => (req.agent_id === "poet" ? poet(req) : assistant(req));Declaring
sub_agents lists the agents this one can delegate to. Each appears to the
model as a tool named by its id, taking a single message argument. That id
shares the model's tool namespace, so it must not collide with a tool name.
Delegating
When the model calls a sub-agent, proposed spawns a child session and sends
its opening message, the message argument. The child runs as an ordinary
session with its own agent_id, transcript, and cost. Its decision requests
carry an ancestry list of the parent sessions above it.
Completing
When the child's turn finishes, the parent receives a sub_agent.finished
trigger. proposed records the result as the delegating tool's result and
re-prompts the parent, exactly as a tool.finished does. The child's cost and
token usage roll up into the parent's turn.
Spec
type SubAgent = { id: string; description?: string }
// actions that open a child, proposed for you
{ type: "sub_agent.spawn"; session_id: string; agent_id: string; tool_call_id: string; retry?: RetryPolicy }
{ type: "message.send"; session_id: string; message: DraftMessage }
// trigger
{ type: "sub_agent.finished"; id: string; ok: boolean; session_id: string; agent_id: string; result?: string; error?: string }On sub_agent.finished, id is the delegating tool call and session_id is
the child. Full types in Protocol.
Next
- Tool calls: delegation folds back like a tool result.
- Durability: child sessions are persisted and resume.
- Protocol: the spawn actions and finish trigger.