The contract every swarm call must satisfy — and why the model cannot mix AgentSwarm with other tools in the same turn.
Every AgentSwarm call is a structured fan-out. You provide a template with a {{item}} placeholder and an items array — each string becomes one subagent's concrete prompt. Default profile is coder; use explore for read-only parallel scans.
Validation rules from the binary (Zod AgentSwarmToolInputSchema):
resume_agent_ids is providedprompt_template must contain {{item}} when using itemsresume_agent_ids is a map (agent_id → resume prompt), not an array. It resumes existing subagents before launching new ones from items.
Then there's the exclusive-deny policy: AgentSwarm must be the only tool call in the model's response. No Read + AgentSwarm in the same turn. Explore first, swarm alone next.
Think of it like… a bulk mail merge. The template is your letter; each item fills in the recipient line. You can't mail-merge and file paperwork in the same breath — the runtime forces one action at a time so the swarm launch is atomic and auditable.
type AgentSwarmInput = { description: string; subagent_type?: string; // default "coder" prompt_template?: string; // required when items present items?: string[]; // max 128 resume_agent_ids?: Record<string, string>; };
<agent_swarm_result> <summary>completed: 8</summary> <subagent agent_id="agent-0" item="claude" outcome="completed">...</subagent> <resume_hint>Call AgentSwarm with resume_agent_ids...</resume_hint> </agent_swarm_result>
Outcomes per subagent: completed, failed, aborted (from renderSwarmSummary in binary).
agent-swarm-exclusive-deny rejects mixed or duplicate swarm calls in one turn.Real call from session 30e21381 — 8 parallel subagents, all completed.
{
"name": "AgentSwarm",
"args": {
"description": "Extract agent sessions & assets",
"subagent_type": "coder",
"items": ["claude", "grok", "kimi", "codex",
"appfy-projects", "loop-engineering-suite",
"agent-swarm", "gmail-auth"],
"prompt_template": "Your specific scope is: {{item}}. ..."
}
}
agent-swarm-exclusive-deny.ts (embedded in binary)
evaluate(context) { const n = toolCalls.filter(t => t.name === "AgentSwarm").length; if (n === 0) return; if (n === 1 && toolCalls.length === 1) return; // OK return { kind: "deny", message: "AgentSwarm must be called one swarm at a time." }; }
Agent — one subagent, one full prompt. AgentSwarm — N subagents, same template + different items. Swarm is the structured parallelism primitive. Subagents do not receive AgentSwarm or Agent in their tool list.
Pick a tool-call pattern. See whether agent-swarm-exclusive-deny allows or blocks it.
wire.jsonl and state.json.