Context
Multi-agent frameworks increasingly support agent handoff as a first-class pattern — the ability for one agent to transfer control to another agent mid-conversation. OpenAI Swarm, Anthropic Agent SDK, and LangGraph all have handoff primitives. Today, agents in open-multi-agent collaborate via SharedMemory (write results for others to read) and MessageBus (point-to-point messages), but there is no way for an agent to delegate a sub-task to another agent and get the result back within a single conversation loop.
This means:
- An agent can't say "I need the researcher to look this up" and get the answer in-context
- Multi-step workflows that require dynamic routing (e.g. "if code review fails, hand off to the fixer agent") must be orchestrated externally
- The coordinator pattern works for pre-planned DAGs, but not for emergent, runtime delegation
A delegate_to_agent tool fills this gap without changing the framework's architecture.
Proposed Implementation
New built-in tool: delegate_to_agent
Register a new tool in src/tool/built-in/ that allows any agent to invoke another agent in the same team:
const researcher: AgentConfig = {
name: 'researcher',
model: 'claude-sonnet-4-6',
systemPrompt: 'You research topics thoroughly.',
tools: ['file_read', 'grep'],
}
const writer: AgentConfig = {
name: 'writer',
model: 'claude-sonnet-4-6',
systemPrompt: 'You write clear documentation.',
tools: ['file_write', 'delegate_to_agent'], // <-- can delegate
}
// During execution, the writer agent can call:
// delegate_to_agent({ agent: "researcher", task: "Find the latest benchmarks for Claude vs GPT" })
// → receives the researcher's output as a tool result
Tool schema
defineTool({
name: 'delegate_to_agent',
description: 'Delegate a sub-task to another agent on the team and get the result back.',
inputSchema: z.object({
agent: z.string().describe('Name of the agent to delegate to'),
task: z.string().describe('Description of the sub-task for the delegate agent'),
}),
execute: async ({ agent, task }, context) => {
// 1. Look up the target agent in context.team
// 2. Run the target agent with `task` as prompt
// 3. Return the agent's output as the tool result
// 4. Write to SharedMemory for audit trail
},
})
Integration points
-
ToolUseContext (types.ts:126): Already has team?: TeamInfo — the delegation tool needs access to the team's agent pool. Extend TeamInfo or the context to include a reference to a run function (e.g. delegateFn).
-
AgentRunner (agent/runner.ts): No changes needed — the tool executes like any other tool. The target agent run happens inside the tool's execute function.
-
Built-in tools (tool/built-in/): Add delegate.ts alongside existing tools. Register it in registerBuiltInTools() conditionally (only when team context is available).
-
SharedMemory: Delegation results are written to shared memory under the delegating agent's namespace (writer/delegation:researcher:result) for observability.
Key decisions
- Tool-based, not protocol-based — handoff is just another tool call. The LLM decides when to delegate, no special routing logic needed. This keeps the framework's conversation loop unchanged.
- Synchronous delegation — the calling agent blocks on the tool result, same as any other tool. No need for async messaging or callbacks.
- Team-scoped — delegation only works within the same team. Cross-team delegation is out of scope for now.
- Depth limit — add a
maxDelegationDepth (default: 3) to prevent infinite delegation chains (agent A delegates to B which delegates to A).
- Concurrency — delegation runs through the same
AgentPool semaphore, so it respects the team's maxConcurrency setting. Deadlock risk: if all slots are occupied by agents waiting on delegations, the pool deadlocks. Mitigation: document this constraint, and optionally reserve one slot for delegations.
Deadlock prevention
When agent A delegates to agent B, A holds a pool slot while waiting. If all N slots are held by delegating agents, the system deadlocks. Two mitigation options (can start with the simpler one):
- Documentation — note that
maxConcurrency should be > max delegation depth
- Dedicated delegation slots — reserve
ceil(maxConcurrency / 2) slots for top-level tasks, allow delegations to exceed the cap
Acceptance Criteria
Context
Multi-agent frameworks increasingly support agent handoff as a first-class pattern — the ability for one agent to transfer control to another agent mid-conversation. OpenAI Swarm, Anthropic Agent SDK, and LangGraph all have handoff primitives. Today, agents in open-multi-agent collaborate via SharedMemory (write results for others to read) and MessageBus (point-to-point messages), but there is no way for an agent to delegate a sub-task to another agent and get the result back within a single conversation loop.
This means:
A
delegate_to_agenttool fills this gap without changing the framework's architecture.Proposed Implementation
New built-in tool:
delegate_to_agentRegister a new tool in
src/tool/built-in/that allows any agent to invoke another agent in the same team:Tool schema
Integration points
ToolUseContext (
types.ts:126): Already hasteam?: TeamInfo— the delegation tool needs access to the team's agent pool. ExtendTeamInfoor the context to include a reference to a run function (e.g.delegateFn).AgentRunner (
agent/runner.ts): No changes needed — the tool executes like any other tool. The target agent run happens inside the tool'sexecutefunction.Built-in tools (
tool/built-in/): Adddelegate.tsalongside existing tools. Register it inregisterBuiltInTools()conditionally (only when team context is available).SharedMemory: Delegation results are written to shared memory under the delegating agent's namespace (
writer/delegation:researcher:result) for observability.Key decisions
maxDelegationDepth(default: 3) to prevent infinite delegation chains (agent A delegates to B which delegates to A).AgentPoolsemaphore, so it respects the team'smaxConcurrencysetting. Deadlock risk: if all slots are occupied by agents waiting on delegations, the pool deadlocks. Mitigation: document this constraint, and optionally reserve one slot for delegations.Deadlock prevention
When agent A delegates to agent B, A holds a pool slot while waiting. If all N slots are held by delegating agents, the system deadlocks. Two mitigation options (can start with the simpler one):
maxConcurrencyshould be > max delegation depthceil(maxConcurrency / 2)slots for top-level tasks, allow delegations to exceed the capAcceptance Criteria
delegate_to_agenttool registered intool/built-in/delegate.tsrunTeam()andrunTasks()flows (team context available)onTraceemits trace events for delegated agent runsexamples/14-agent-handoff.ts