Documentation Index
Fetch the complete documentation index at: https://docs.xhipai.com/llms.txt
Use this file to discover all available pages before exploring further.
Agent Handoff
Agent Handoff enables seamless mid-conversation transfers between agents. When a user’s request falls outside the current agent’s expertise, it can transfer to a specialist agent while carrying over the full conversation context.
Quick Start
import { Agent, openai } from "@agentium/core";
const billing = new Agent({
name: "billing",
model: openai("gpt-4o-mini"),
instructions: "You are a billing specialist.",
});
const support = new Agent({
name: "support",
model: openai("gpt-4o-mini"),
instructions: "You are a tech support agent.",
});
const frontDesk = new Agent({
name: "front-desk",
model: openai("gpt-4o"),
instructions: "Route the user to the right specialist.",
handoff: {
targets: [
{ agent: billing, description: "Billing, invoices, payments" },
{ agent: support, description: "Technical issues, debugging" },
],
maxHandoffs: 3,
},
});
const result = await frontDesk.run("I need help with my invoice");
// Automatically transfers to billing agent
How It Works
- The agent receives a
transfer_to_agent tool based on the configured targets
- When the LLM decides a handoff is needed, it calls the tool with the target agent name
- The
HandoffManager catches the signal and transfers the conversation
- The target agent receives the full conversation history and continues naturally
Configuration
interface HandoffConfig {
targets: HandoffTarget[]; // Specialist agents
maxHandoffs?: number; // Prevent infinite loops (default: 5)
carryMessages?: boolean; // Pass conversation history (default: true)
carrySessionState?: boolean; // Pass session state (default: true)
}
interface HandoffTarget {
agent: Agent;
description: string; // LLM sees this to decide when to handoff
onHandoff?: (ctx: RunContext) => Promise<void>; // Hook before handoff
}
Team Handoff Mode
For managed teams, use TeamMode.Handoff:
import { Agent, Team, TeamMode, openai } from "@agentium/core";
const billing = new Agent({
name: "billing",
model: openai("gpt-4o-mini"),
instructions: `You are a billing specialist. Handle invoices, payments, and refunds.
When the issue is resolved, use the complete tool to end the conversation.`,
});
const support = new Agent({
name: "technical-support",
model: openai("gpt-4o-mini"),
instructions: `You are a tech support agent. Troubleshoot software and hardware issues.
When the issue is resolved, use the complete tool to end the conversation.`,
});
const frontDesk = new Agent({
name: "front-desk",
model: openai("gpt-4o"),
instructions: `You are the front desk receptionist. Understand the user's needs
and route them to the right specialist. Do not try to solve issues yourself.`,
});
const team = new Team({
name: "support-team",
mode: TeamMode.Handoff,
model: openai("gpt-4o"),
members: [frontDesk, billing, support],
maxRounds: 5,
});
const result = await team.run("I got charged twice for my subscription");
console.log(result.text);
// The front-desk routes to billing, which handles the duplicate charge
console.log(result.handoffChain);
// ["front-desk", "billing"]
Events
| Event | Payload |
|---|
handoff.transfer | { runId, fromAgent, toAgent, reason } |
handoff.complete | { runId, chain: string[], finalAgent } |
Cycle Detection
Agentium prevents infinite handoff loops automatically. If agent A hands off to agent B, which hands off back to A, the system detects the cycle and stops:
const agentA = new Agent({
name: "agent-a",
model: openai("gpt-4o-mini"),
instructions: "Transfer to agent-b for everything.",
handoff: {
targets: [{ agent: agentB, description: "Agent B" }],
maxHandoffs: 5,
},
});
const agentB = new Agent({
name: "agent-b",
model: openai("gpt-4o-mini"),
instructions: "Transfer to agent-a for everything.",
handoff: {
targets: [{ agent: agentA, description: "Agent A" }],
maxHandoffs: 5,
},
});
// This won't loop forever — stops after maxHandoffs is reached
const result = await agentA.run("Help me");
// result.handoffChain: ["agent-a", "agent-b", "agent-a", "agent-b", "agent-a"]
onHandoff Callback
Use onHandoff to log, validate, or modify behavior when a handoff occurs:
const frontDesk = new Agent({
name: "front-desk",
model: openai("gpt-4o"),
instructions: "Route users to the right agent.",
handoff: {
targets: [
{
agent: billing,
description: "Billing and payment issues",
onHandoff: async (ctx) => {
console.log(`[Handoff] ${ctx.runId}: front-desk → billing`);
// Log to analytics
await analytics.track("agent_handoff", {
from: "front-desk",
to: "billing",
sessionId: ctx.sessionId,
});
},
},
{
agent: support,
description: "Technical issues",
onHandoff: async (ctx) => {
console.log(`[Handoff] ${ctx.runId}: front-desk → support`);
},
},
],
},
});
Each agent in a handoff chain receives a complete tool. Calling it signals that the task is done and no further handoffs are needed:
const billing = new Agent({
name: "billing",
model: openai("gpt-4o-mini"),
instructions: `You handle billing. When the issue is resolved,
call the complete tool with a summary of what was done.`,
handoff: { targets: [] }, // No further handoff targets
});
// When the agent calls complete({ summary: "Refund of $12.99 issued" }),
// the handoff chain ends and the result is returned to the caller.
Cross-References
- Teams — Team orchestration modes (Handoff, Broadcast, Sequential)
- Events — Listen for
handoff.transfer and handoff.complete events
- Observability — Trace handoff chains across agents