Skip to content

Routing & Handoffs

When a conversation can go to multiple specialists, you need a router. Kuralle’s routes + routing setup handles the decision and the handoff without surfacing triage logic to the user.

Add routes and routing to defineAgent:

import { openai } from '@ai-sdk/openai';
import { defineAgent } from '@kuralle-agents/core';
const triage = defineAgent({
id: 'triage',
instructions: 'Route the user to the right specialist.',
model: openai('gpt-4o-mini'),
routes: [
{ agent: 'billing', when: 'billing question or payment issue' },
{ agent: 'support', when: 'product support request' },
],
routing: { mode: 'structured', default: 'support' },
});

Each routes entry has an agent (the destination agent’s id) and a when description. The model uses these descriptions to select the right route.

mode: 'structured' routes via schema — the model outputs a structured decision object, not a user-facing message. The routing choice never appears in the user’s conversation.

default is the fallback agent when no route matches closely enough.

A handoff moves the conversation to another agent and carries full session context. The receiving agent picks up with the complete message history.

For tool-based handoffs — where the agent decides explicitly when to transfer — declare which agent IDs the agent can hand off to with handoffs, and wire a handoff tool:

const transferToSpanish = defineTool({
name: 'transfer_to_spanish',
description: 'Transfer to a Spanish-speaking agent when the user requests Spanish.',
input: z.object({ reason: z.string() }),
execute: async ({ reason }) => ({
__handoff: true,
targetAgentId: 'spanish-agent',
reason,
}),
});
const englishAgent = defineAgent({
id: 'english',
instructions: 'Friendly assistant. If the user speaks Spanish, use transfer_to_spanish.',
model: openai('gpt-4o-mini'),
handoffs: ['spanish-agent'],
agents: [spanishAgent],
tools: buildToolSet({ transfer_to_spanish: transferToSpanish }),
effectTools: { transfer_to_spanish: transferToSpanish },
});

The runtime intercepts { __handoff: true, targetAgentId } in the tool result and routes the session to the target agent.

triage.ts
import { openai } from '@ai-sdk/openai';
import { defineAgent, createRuntime } from '@kuralle-agents/core';
const billingAgent = defineAgent({
id: 'billing',
instructions: 'You handle billing questions and payment issues.',
model: openai('gpt-4o-mini'),
});
const supportAgent = defineAgent({
id: 'support',
instructions: 'You handle product support requests.',
model: openai('gpt-4o-mini'),
});
// mode: 'structured' routes via schema — the routing decision never surfaces to the user
const triage = defineAgent({
id: 'triage',
instructions: 'Route the user to the right specialist.',
model: openai('gpt-4o-mini'),
routes: [
{ agent: 'billing', when: 'billing question or payment issue' },
{ agent: 'support', when: 'product support request' },
],
routing: { mode: 'structured', default: 'support' },
});
const runtime = createRuntime({
agents: [triage, billingAgent, supportAgent],
defaultAgentId: 'triage',
});