Theo Docs
TheoKitTheoKit-SDKTheoUITheo PaaS
Concepts

Handoffs

Peer-to-peer agent handoffs — declarative handoffs[] + Handoff.create.

Canonical contract: packages/sdk/docs.md — "Agent handoffs (v1.16+)".

Handoffs let an agent transfer control to another peer agent — useful for routing, specialization, and multi-agent flows.

Declarative

const billing = await Agent.create({
  apiKey, model,
  name: "billing-agent",
  systemPrompt: "You handle billing questions.",
});

const router = await Agent.create({
  apiKey, model,
  name: "router",
  systemPrompt: "Triage. Transfer to billing-agent if the user mentions invoice or charge.",
  handoffs: [billing], // synthesized tool: transfer_to_billing-agent
});

await (await router.send("I was charged twice this month")).wait();
// Router calls transfer_to_billing-agent → billing handles the rest.

Handoff-as-tool

Handoffs are implemented as synthetic tools (ADR D214). The agent decides to "call" transfer_to_<name> like any other tool. Inspired by openai-agents-python — proven pattern.

Handoff.create for customization

import { Handoff } from "@theokit/sdk";
import { z } from "zod";

const handoff = Handoff.create(billing, {
  toolName: "escalate_to_billing",
  inputType: z.object({ reason: z.string() }),
  onHandoff: async (input) => console.log("[handoff]", input.reason),
  inputFilter: (history) => history.slice(-5), // only last 5 messages
});

Guards

  • Peer-to-peer (D217) — handoffs are not parent-child. The receiver runs independently.
  • Max depth 5 (D218) — default chain limit. Configurable.
  • Single-flight per pair (D221) — same (sender, receiver) pair can't recurse within one send().
  • First-wins on parallel handoff tools (D226) — if the model emits 2 handoffs in one turn, only the first executes.
  • CloudAgent throws UnsupportedRunOperationError (D122) — handoffs are local-only in v1.

API reference

On this page