Which thread gets which tool
All of the first four follow the agent’s
handoffs: false and none is offered. A member that asks for wait: true is refused as a tool result — it cannot delegate and cannot be talked into delegating — which is how the one-level depth bound is enforced at runtime; the save-time check is the other half. A member may still hand work on with wait: false, which starts a top-level session on the target’s own budget rather than a thread of this team.
The delegation tools
tool
Send one agent one message. It returns immediately — with the new session’s id,
status, and the wait it ran under — so a coordinator can start several and then wait once, rather than serialising them. With wait: true the member’s answer arrives later, when the coordinator wakes; with wait: false nothing comes back, and the target’s session is its own.tool
Park until the delegations you name are done. The coordinator’s turn ends here and resumes with the results. A session yielding here reports the
awaiting_delegation stop reason and nothing else — awaiting_input would claim a person can unblock it and end_turn would claim the task is finished, and a caller acts on both.With nothing outstanding it is an immediate no-op — { parked: false, outstanding: 0 } — rather than a park, because parking a coordinator that has delegated nothing is a session that never wakes.The park is the turn’s, not the call’s. send_to_agent returns at once, so a coordinator can start four and wait once; the whole fan-out is dispatched when the turn ends, and this is what ends it. Calling it in a turn that delegated reports awaiting_delegation. Calling it in a turn that delegated nothing — you were resumed by one teammate and another is still running — parks the session idle instead, and the wake gate resumes you on the last one. Either way the turn stops here: it does not run on and it does not poll.tool
Who this agent may send work to, and how much of the concurrency budget is spent. Takes an optional
query that narrows by a word in the name or description. Each agent comes back with its name, description (truncated to 160 characters), project, team — whether it is on this agent’s roster, so wait: true runs its pinned version — and typed — whether its harness can honour an output_schema at all. Alongside them: concurrency: { running, limit }.typed is derived for the model rather than left for it to infer from harness, because the model does not carry the harness catalogue and this is the one fact that decides whether a send_to_agent call may carry output_schema.Nothing throws — a refusal is a tool result
Every way a delegation can fail to happen comes back as a tool result the model can read and act on, never as an exception that would end the turn.Delegation is about context isolation
The point of delegation is not parallelism first and foremost — it is context isolation and cost. When the coordinator callssend_to_agent, the member’s session starts fresh: its opening context is only the message, not the coordinator’s (possibly enormous) transcript. That has two consequences:
- Focus. The member reasons over a small, relevant context instead of wading through unrelated history.
- Cost. Every model call in that session carries far fewer tokens, so the same work is materially cheaper than expanding the coordinator’s own context. See Context & budgets.
Isolated sessions, and what carries between them
Every member runs in its own session with its own conversation history. Two sessions never share conversation context: a member cannot see the coordinator’s transcript or any sibling’s, only thebrief it was handed and its own turns.
That isolation is the point, but it means the message is the whole hand-off. There is no argument that continues an earlier member session — a delegation is one-shot. If a member needs to know what another member already did, that has to reach it some other way, and the way is the board: a card’s notes are readable by every thread on the team, which a transcript is not.
A card, or a message?
send_to_agent and the board both hand work to a teammate, and they are not interchangeable.
- A card is the hand-over. It is durable, on the record, and it starts the teammate: assign a
todocard with no open blocker to an agent by name, and the board’s clock starts a top-level session of that agent on it — on the agent’s own budget, with the card’s notes and comments as its brief, expected to end by moving the card todonewith a note orblockedwith a comment. That session is a member of the crew: seated on the coordinator’s board by roster, answerable to the board, and not a thread of anyone’s session. The coordinator does not park on it; it hears back through the board’s digest. - A message is a nudge.
send_to_agent({ wait: true })starts a member thread of your own session, on your budget, and you park until it answers. Nothing about it is on the record but the thread itself. It is the right tool for a question whose answer you need inside this turn — a fact to check, a shape to fill — not for work that has an owner and a state. wait: falseis neither. It hands a message to a normal top-level session of the target’s own, markedmetadata.handoff, and nothing comes back. Use it to hand work off your team; use a card to hand work within it, where the teammate’s progress should be readable.
doing or stuck and on what, and the note the holder left when it finished — none of which survives a transcript. The coordinator page sets the two side by side.
A coordinator that has delegated and parked wakes when its threads finish, not on a teammate’s board write. Cards that reach
done or blocked reach the coordinator as one digest session per board, on the next tick after the change.Typed results
By default a member returns free-form text. Pass anoutput_schema on send_to_agent and the hand-off becomes a typed contract instead: the member’s session must go idle producing a structured_output object that validates against the schema.
Not every harness can do this. list_agents reports typed per member, and a call carrying output_schema for a member that cannot is refused up front as no_structured_output — named, rather than quietly served as prose the coordinator’s merge code then has to parse. The refusal is deliberately at call time and not at save time: whether any delegation will carry a schema is unknowable when the roster is written, and banning a text-only teammate outright would also ban the prose work it serves well.
Fan-out: several members at once
The coordinator may have several members running at the same time — each in its own session with its own isolated history — and then park once onwait_for_agents. Give each the same output_schema and merging the batch is just collecting typed objects.
CLI
thread.created when a member session is spawned (with its agent_id and member name), and thread.idle as each result folds back. See Context & budgets.
Each member is billed independently and quoted against the org balance before it runs.
Bounds
Delegation is deliberately shallow and bounded to keep teams reproducible and cost-safe.Next: the team board
The other mechanism — durable, broadcast, and the one that outlives the run.