Quick Start
1
Simple Usage
2
With Configuration
User Interaction Flow
Configuration Levels
Generated tool name
Each handoff is exposed to the model as a tool namedtransfer_to_<lowercased_snake_of_agent_name>. The SDK sanitizes the agent name so any name — including spaces or punctuation — becomes a provider-legal tool name (capped at 64 characters).
Pass a
name: on handoff() to override it. This matters when you reference the tool in prompts or read it in logs.
Generated tool description
The tool’s description is what the model reads to decide when to hand off. When you don’t pass adescription:, the SDK builds one from the target agent’s name, role, and goal.
role and goal on handoff targets and the main agent routes more accurately — no custom description: needed.
When to Transfer
Safety Features
Handoffs include built-in protections, all controllable per handoff:- Cycle detection: Prevents A → B → A loops. Toggle via
detectCycles; enabled by default. RaisesHandoffCycleErrorbefore touching the target. - Depth limits: Maximum 10 handoffs in a chain by default; override with
maxDepth. RaisesHandoffDepthErrorbefore touching the target. - Timeouts: Handoffs time out after 5 minutes by default; override with
timeoutSeconds(in seconds;<= 0disables). RaisesHandoffTimeoutError(always retryable). - Concurrency: Each
Handoffinstance has its own concurrency semaphore (default 5); override withmaxConcurrent. Not process-wide.
Controlling context, safety, and concurrency
handoff() accepts eight settings that steer what the target sees and how the transfer behaves. Add them one at a time.
1
Steer what the target sees
Show the target only the last N messages instead of the summary default.
2
Cap tokens and keep the system prompt
Drop the oldest messages until the context fits a token budget, but never drop
system messages.3
Bound execution
Give the target a time limit and cap how many copies run at once.
4
Add safety guards
Refuse cycles and cap the chain depth.
5
Set everything at once
Combine all eight in one config object.
Which context policy should I pick?
contextPolicy decides how much history the target sees.
Inside a handoff
execute() runs a safety check, selects the context, seeds it onto the target, runs the target, then restores the target’s original history.
HandoffConfig reference
Every option lives on theHandoffConfig object passed to handoff() (or new Handoff({ agent, ... })).
Python’s
HandoffConfig declares max_context_tokens and serialises it, but no code path reads it. TypeScript implements the documented meaning, so maxContextTokens actually caps tokens here. If you port behavioural tests from Python, expect this one divergence.Chain threading
The handoff chain tracks the agents already traversed to reach the current point.HandoffContext carries it on an optional field:
execute() writes the extended chain back onto the result’s context, so passing result.context onward threads it by hand.
The handoff module exposes helpers for advanced flows: currentHandoffChain() reads the chain in scope (oldest first), currentHandoffDepth() its length, runWithHandoffChain(chain, fn) runs fn under a given chain, selectHandoffMessages(messages, config) is the standalone context selector, and resetHandoffChain() clears the module-level fallback used where AsyncLocalStorage is unavailable (Node 18, browsers).
parallelHandoffs snapshots the current chain once and passes each sibling an explicit copy, so fan-out never reads the ambient value — each sibling gets an isolated chain, and cycle detection and maxDepth are enforced per task, not shared across siblings.
API Reference
Agent Module
Agent module with handoff support
AgentConfig
Agent configuration
Best Practices
Create focused specialists
Create focused specialists
Each agent should handle one domain well. This makes handoffs accurate.
Give agents clear roles and goals
Give agents clear roles and goals
Set
role and goal on each handoff target. They are woven into the auto-generated handoff description (Transfer task to <name> (<role>) - <goal>), so the main agent routes more accurately without a custom description:.Write clear descriptions
Write clear descriptions
The main agent uses descriptions to decide when to transfer.
Explain transfers to users
Explain transfers to users
Let users know they’re being connected to a specialist.
Tool-Boundary Policy & Parallel Handoffs
The TypeScript handoff stack matches the Python surface: aHandoffToolPolicy controls which tools survive a transfer, and parallel_handoffs fans a source agent’s work out across several specialists at once.
HandoffToolPolicy modes
HandoffToolPolicy modes
resolveHandoffToolPolicy and HandoffToolPolicyMode enforce the tool boundary during a transfer — decide whether the target keeps the source’s tools, only its own, or a filtered set. DEFAULT_HANDOFF_TOOL_POLICY is applied when you don’t pass one.HandoffTimeoutError is always retryable
HandoffTimeoutError is always retryable
A
HandoffTimeoutError sets isRetryable === true unconditionally — a timeout may succeed on a second attempt. Cycle and depth failures raise HandoffCycleError (carrying context.cycle_path) and HandoffDepthError (carrying context.max_depth / context.current_depth).Back-compat context aliases: chain / depth / max_depth
Back-compat context aliases: chain / depth / max_depth
The handoff context accepts the legacy aliases
chain, depth, and max_depth so older Python-shaped snippets keep working without a rewrite.Related
Agent
Create AI agents
Teams
Multi-agent teams

