@theokit/sdk-handoff 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +239 -0
- package/LICENSE +2 -2
- package/README.md +13 -0
- package/dist/handoff-D7malWe_.d.cts +255 -0
- package/dist/handoff-D7malWe_.d.ts +255 -0
- package/dist/index.cjs +117 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +143 -28
- package/dist/index.d.ts +143 -28
- package/dist/index.js +118 -39
- package/dist/index.js.map +1 -1
- package/dist/internal/tool-injector.cjs +26 -11
- package/dist/internal/tool-injector.cjs.map +1 -1
- package/dist/internal/tool-injector.d.cts +2 -2
- package/dist/internal/tool-injector.d.ts +2 -2
- package/dist/internal/tool-injector.js +26 -11
- package/dist/internal/tool-injector.js.map +1 -1
- package/package.json +14 -6
- package/dist/handoff-D-Ujv-lA.d.cts +0 -131
- package/dist/handoff-D-Ujv-lA.d.ts +0 -131
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/handoff.ts","../src/internal/registry.ts","../src/internal/telemetry.ts","../src/internal/dispatcher.ts","../src/internal/to-json-schema.ts","../src/internal/tool-injector.ts","../src/handoff.ts","../src/index.ts"],"names":["HandoffLoopError","HandoffPairLoopError","HandoffSelfReferenceError","HandoffReceiverDisposedError","HandoffNameCollisionError","createRequire","z","toJSONSchema","Plugin","normalizeHandoffs","buildHandoffTool","dispatchHandoff","createChainState"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * `HandoffDescriptor` pinned to `SDKAgent` — back-compat shape for callers\n * that imported `import type { HandoffDescriptor } from \"@theokit/sdk\"`\n * before T4.1 follow-up.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/** Throw when handoff depth exceeds `maxHandoffDepth` (default 5; D218). */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/** Throw when the same (sender, receiver) pair invoked twice in one send() (D221). */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when an agent's `handoffs[]` includes a self-reference (EC-6). */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/** Throw when receiver is disposed at dispatch time (EC-5). */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/** Throw when two handoffs in the same parent collide on tool name (D215). */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const m = history.messages[i] as {\n type?: string;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type !== \"user\" || m.message?.role !== \"user\") continue;\n const text = extractUserText(m.message.content);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n const run = await receiver.send(lastUserMessage);\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // The schema param is `unknown` (callers pass `T extends ZodType` generics that\n // don't structurally satisfy Zod v4's `$ZodType`); cast to the exact parameter\n // type `toJSONSchema` expects rather than `any` — any z.* schema IS valid at runtime.\n return toJSONSchema(schema as Parameters<typeof toJSONSchema>[0], options) as Record<\n string,\n unknown\n >;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugify(candidate);\n}\n\nfunction slugify(input: string): string {\n return (\n input\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (input: unknown): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n history: { messages: [] }, // v1: history replay deferred\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n","/**\n * Public `Handoff` class — factory for handoff descriptors (Adoption\n * Roadmap #4; ADRs D214-D229).\n *\n * Usage:\n *\n * import { Agent, Handoff } from \"@theokit/sdk\";\n *\n * const billing = await Agent.create({\n * name: \"billing\",\n * systemPrompt: \"You handle billing questions.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * });\n *\n * const triage = await Agent.create({\n * name: \"triage\",\n * systemPrompt: \"Classify the user's intent and transfer to the right specialist.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * handoffs: [\n * billing, // auto-wrapped as Handoff.create(billing)\n * Handoff.create(supportAgent, { inputFilter: redactCreditCards }),\n * ],\n * });\n *\n * @public\n */\n\nimport { Plugin, type PluginContext, type SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\n\n/** Recommended system-prompt prefix for senders (D215 / EC-13). */\nexport const RECOMMENDED_HANDOFF_PROMPT_PREFIX = `\nYou can transfer the conversation to other specialist agents when their\nexpertise matches the user's request. Invoke the appropriate\ntransfer_to_<agent> tool with a short reason. The receiving agent will\ntake over the conversation; do not duplicate their work.\n`.trim();\n\nexport class Handoff {\n private constructor() {}\n\n /**\n * Build a `HandoffDescriptor` for a target agent. Wrap with custom options\n * (filter / inputType / callback / whitelist / etc); pass to\n * `Agent.create({ handoffs: [...] })`.\n *\n * Raw `SDKAgent` instances in `handoffs[]` are auto-wrapped by the runtime\n * — call `Handoff.create()` explicitly only when you need to customize.\n */\n static create<TInput extends ZodType = ZodType>(\n target: SDKAgent,\n options: HandoffOptions<TInput> = {} as HandoffOptions<TInput>,\n ): HandoffDescriptor<TInput> {\n if (target === undefined || target === null) {\n throw new Error(\"Handoff.create: target agent is required\");\n }\n if (typeof target.send !== \"function\") {\n throw new Error(\"Handoff.create: target must be an SDKAgent instance\");\n }\n const resolvedToolName = options.toolName ?? `transfer_to_${slugifyName(target)}`;\n return {\n target,\n options,\n resolvedToolName,\n };\n }\n\n /**\n * Plugin-based wiring (SDK 2.x preferred). Wraps `targets` in synthetic\n * `transfer_to_<receiver>` tools and registers them via `ctx.registerTool`\n * at agent init time.\n *\n * Replaces the legacy `Agent.create({ handoffs: [...] })` option (which is\n * still supported as a transitional convenience while sdk-handoff is\n * installed — the framework lazy-imports the tool-injector at runtime).\n *\n * @example\n * const support = await Agent.create({\n * name: \"support\",\n * plugins: [Handoff.asPlugin({ parentAgentId: \"support\", targets: [billing] })],\n * });\n */\n static asPlugin(opts: AsPluginOptions): Plugin {\n const parent = opts.parentAgentId ?? \"anonymous\";\n const maxDepth = opts.maxHandoffDepth ?? 5;\n const targets = opts.targets;\n return Plugin.create({\n name: `handoff-${parent}`,\n version: \"1.0.0\",\n kind: \"general\" as const,\n register(ctx: PluginContext): void {\n if (maxDepth === 0 || targets.length === 0) return;\n // Lazy import — keeps cold path lean if asPlugin is constructed but\n // its register hook is never invoked (e.g., disabled by config).\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n void (async () => {\n const { normalizeHandoffs, buildHandoffTool } = await import(\n \"./internal/tool-injector.js\"\n );\n const normalized = normalizeHandoffs(parent, targets);\n for (const { descriptor } of normalized) {\n ctx.registerTool(buildHandoffTool(parent, descriptor, maxDepth));\n }\n })();\n },\n });\n }\n}\n\n/**\n * Options for `Handoff.asPlugin()`. `parentAgentId` defaults to `\"anonymous\"`;\n * pass the host agent's `name` for correct loop detection in chains.\n */\nexport interface AsPluginOptions {\n readonly targets: ReadonlyArray<SDKAgent | HandoffDescriptor>;\n readonly parentAgentId?: string;\n readonly maxHandoffDepth?: number;\n}\n\nfunction slugifyName(agent: SDKAgent): string {\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return (\n candidate\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n\n/**\n * Imperative escape hatch (D225). Useful for tests / programmatic flows\n * that need deterministic handoff without LLM routing.\n *\n * NOTE: this is a STANDALONE helper rather than a method on `SDKAgent`\n * to avoid invasive refactor of the agent class. Behavior is identical\n * to invoking the corresponding synthetic tool would be.\n */\nexport async function handoffTo(\n sender: SDKAgent,\n target: SDKAgent,\n message: string,\n options: HandoffOptions = {},\n): Promise<string> {\n const descriptor = Handoff.create(target, options);\n // Lazy import to avoid loading internal module unless this is called.\n const { dispatchHandoff } = await import(\"./internal/dispatcher.js\");\n const { createChainState } = await import(\"./internal/registry.js\");\n const chainState = createChainState(sender.agentId, 5);\n const { reply } = await dispatchHandoff({\n descriptor,\n senderAgentId: sender.agentId,\n chainState,\n rawInputJson: undefined,\n history: { messages: [] },\n messageOverride: message,\n });\n return reply;\n}\n","/**\n * `@theokit/sdk-handoff` — inter-agent dispatch for `@theokit/sdk`.\n *\n * Extracted from `@theokit/sdk@1.7.0` as part of the SDK 2.0 package split\n * (Phase 4 / T4.1). Integrates with `Agent` via the Plugin protocol —\n * `Handoff.asPlugin({ targets })` returns a `Plugin` consumed by\n * `Agent.create({ plugins: [...] })`.\n *\n * @packageDocumentation\n */\n\nexport {\n type AsPluginOptions,\n Handoff,\n handoffTo,\n RECOMMENDED_HANDOFF_PROMPT_PREFIX,\n} from \"./handoff.js\";\nexport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\nexport {\n HandoffLoopError,\n HandoffNameCollisionError,\n HandoffPairLoopError,\n HandoffReceiverDisposedError,\n HandoffSelfReferenceError,\n} from \"./types/handoff.js\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/slugify-agent-name.ts","../src/types/handoff.ts","../src/internal/registry.ts","../src/internal/telemetry.ts","../src/internal/dispatcher.ts","../src/internal/to-json-schema.ts","../src/internal/tool-injector.ts","../src/handoff.ts","../src/index.ts"],"names":["HandoffLoopError","HandoffPairLoopError","HandoffSelfReferenceError","HandoffReceiverDisposedError","HandoffNameCollisionError","createRequire","z","toJSONSchema","ConfigurationError","Plugin","normalizeHandoffs","buildHandoffTool","dispatchHandoff","createChainState"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Turns an agent's display name into a tool-name-safe slug.\n *\n * Extracted because the identical function existed twice — `handoff.ts`'s `slugifyName` and\n * `tool-injector.ts`'s `slugify`, byte-identical apart from a parameter name — with no test\n * covering either. Two copies of one rule is the DRY violation `CLAUDE.md` § 12 describes: the\n * two would have drifted the moment one of them was adjusted.\n */\n\n/**\n * Longest input the slug rules are applied to.\n *\n * The result is capped at 64 characters regardless, so nothing beyond this bound can survive;\n * bounding the INPUT is what keeps the cost of getting there linear in a value the caller\n * controls. CodeQL flags `/^_+|_+$/g` as `js/polynomial-redos` (alerts #10, #11).\n *\n * **Stated honestly: the quadratic cost could not be reproduced.** V8 resolves 100_000\n * underscores, with and without a trailing non-underscore, in under a millisecond — measured\n * 2026-08-22. So this bound is defence in depth against a regex engine that does not optimise\n * the shape, not a fix for an exploit anyone demonstrated. The duplication above is the defect\n * this change is really about.\n *\n * 1024 rather than 64: truncating to the output width before stripping the `agent-` prefix would\n * change results for real names, and a bound only has to be far below \"unbounded\" to do its job.\n */\nconst MAX_INPUT_LENGTH = 1024;\n\n/**\n * @param candidate - raw agent name, id, or anything a caller supplied\n * @returns a slug of at most 64 characters, or `\"anonymous\"` when nothing survives\n */\nexport function slugifyAgentName(candidate: string): string {\n return (\n candidate\n .slice(0, MAX_INPUT_LENGTH)\n .replace(/^agent-/i, \"\")\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 64) || \"anonymous\"\n );\n}\n","/**\n * Public types for `Agent.create({ handoffs })` + `Handoff.create()` +\n * `Agent.handoffTo()` (Adoption Roadmap #4; ADRs D214-D229).\n *\n * Pattern: handoff-as-tool. Each handoff destination becomes a synthetic\n * `transfer_to_<receiver>` function tool exposed to the LLM. Runtime\n * intercepts the tool call and routes the next turn to the receiver.\n *\n * T4.1 follow-up (cycle #4 closed): `HandoffDescriptor` + its leaf-friendly\n * sibling types now live in `./handoff-descriptor.ts` (generic over\n * `TAgent`). This module re-exports the leaf types pinned to `SDKAgent`,\n * keeps the runtime error classes, and removes the back-edge to `agent.ts`.\n *\n * @public\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor as HandoffDescriptorGeneric,\n HandoffHistory,\n HandoffOptions,\n HandoffResult,\n} from \"./handoff-descriptor.js\";\n\nexport type { HandoffContext, HandoffHistory, HandoffOptions, HandoffResult };\n\n/**\n * What `Handoff.create` returns: a target plus its options plus the resolved tool name.\n *\n * Pinned to `SDKAgent` — the back-compat shape for callers who imported\n * `import type { HandoffDescriptor } from \"@theokit/sdk\"` before the T4.1 follow-up. It is a plain\n * data record: constructing one by hand works, and skips the target validation `Handoff.create`\n * performs.\n *\n * @public\n */\nexport type HandoffDescriptor<TInput extends ZodType = ZodType> = HandoffDescriptorGeneric<\n TInput,\n SDKAgent\n>;\n\n/**\n * Thrown when a chain exceeds `maxHandoffDepth` (default 5). `depth` is the CAP that was exceeded,\n * not the depth reached; `chain` is the full path of agent ids.\n *\n * Rare in practice: chain state is rebuilt per dispatch, so depth restarts at 1 on every tool call.\n * Repeated ping-pong surfaces as {@link HandoffPairLoopError} instead. *\n * WHERE YOU SEE IT: only when you drive a handoff yourself, via `handoffTo(...)`. In the\n * tool-based wirings (`Handoff.asPlugin` / `Agent.create({ handoffs })`) the handler catches every\n * error and hands the MODEL a `{\"ok\":false,\"error\":\"<name>\",\"message\":\"…\"}` tool result, so this\n * class is observable there only as that `error` string.\n */\nexport class HandoffLoopError extends Error {\n override readonly name = \"HandoffLoopError\";\n readonly depth: number;\n readonly chain: ReadonlyArray<string>;\n constructor(depth: number, chain: ReadonlyArray<string>) {\n super(\n `Handoff loop exceeded max depth ${depth}. Chain: ${chain.join(\" -> \")}. ` +\n `Use Agent.create({ maxHandoffDepth: N }) to raise the cap.`,\n );\n this.depth = depth;\n this.chain = chain;\n }\n}\n\n/**\n * Thrown when the same `sender -> receiver` pair fires twice inside one dispatch — the ping-pong\n * guard, and the loop protection that actually fires in practice.\n *\n * A -> B -> A is allowed by this check (different pairs); a repeated A -> B is not. *\n * WHERE YOU SEE IT: only when you drive a handoff yourself, via `handoffTo(...)`. In the\n * tool-based wirings (`Handoff.asPlugin` / `Agent.create({ handoffs })`) the handler catches every\n * error and hands the MODEL a `{\"ok\":false,\"error\":\"<name>\",\"message\":\"…\"}` tool result, so this\n * class is observable there only as that `error` string.\n */\nexport class HandoffPairLoopError extends Error {\n override readonly name = \"HandoffPairLoopError\";\n readonly senderAgentId: string;\n readonly receiverAgentId: string;\n constructor(senderAgentId: string, receiverAgentId: string) {\n super(\n `Handoff loop: ${senderAgentId} -> ${receiverAgentId} already invoked in this send() call. ` +\n `Likely a ping-pong loop; revisit your handoff conditions.`,\n );\n this.senderAgentId = senderAgentId;\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/**\n * Thrown when a target's `agentId` equals the parent's — self-handoff, which recurses forever.\n *\n * Compared against `parentAgentId` as a STRING, which defaults to `\"anonymous\"` in\n * `Handoff.asPlugin`: leave it unset and a genuine self-reference goes undetected.\n *\n * Raised while the target list is normalised, which in `Handoff.asPlugin` happens inside an\n * unawaited async registration — it arrives as an unhandled rejection there, not as a throw from\n * `Agent.create`.\n */\nexport class HandoffSelfReferenceError extends Error {\n override readonly name = \"HandoffSelfReferenceError\";\n readonly agentId: string;\n constructor(agentId: string) {\n super(\n `Agent \"${agentId}\" has a self-reference in its handoffs[]. ` +\n `Self-handoff causes infinite recursion; introduce a sibling agent for re-entry.`,\n );\n this.agentId = agentId;\n }\n}\n\n/**\n * Thrown when the target agent was disposed before the handoff reached it — detected at dispatch\n * time, since nothing unregisters the tool when an agent is disposed.\n *\n * Typical cause: the receiver was created in a narrower scope than the sender and cleaned up first. *\n * WHERE YOU SEE IT: only when you drive a handoff yourself, via `handoffTo(...)`. In the\n * tool-based wirings (`Handoff.asPlugin` / `Agent.create({ handoffs })`) the handler catches every\n * error and hands the MODEL a `{\"ok\":false,\"error\":\"<name>\",\"message\":\"…\"}` tool result, so this\n * class is observable there only as that `error` string.\n */\nexport class HandoffReceiverDisposedError extends Error {\n override readonly name = \"HandoffReceiverDisposedError\";\n readonly receiverAgentId: string;\n constructor(receiverAgentId: string) {\n super(\n `Handoff target agent \"${receiverAgentId}\" is disposed. ` +\n `Don't dispose receivers while their parent is still active.`,\n );\n this.receiverAgentId = receiverAgentId;\n }\n}\n\n/**\n * Thrown when two targets of the same parent resolve to the same `transfer_to_*` name — the model\n * would have no way to pick between them.\n *\n * Easy to hit without duplicate agents, but not in the way the folding rule suggests: `-` and `_`\n * SURVIVE the slug, and only runs of other characters fold to a single `_`, which is then trimmed\n * at both ends. So `\"billing EU\"`, `\"billing_EU\"`, `\"billing.EU\"` and `\"billing (EU)\"` all resolve\n * to `transfer_to_billing_EU` and collide — the last one because the `_` left by the closing paren\n * is trimmed off the end. `\"billing-EU\"` keeps its hyphen, resolves to `transfer_to_billing-EU`,\n * and collides with none of them. Set `toolName` on one of the colliding pair.\n *\n * Raised while the target list is normalised, which in `Handoff.asPlugin` happens inside an\n * unawaited async registration — it arrives as an unhandled rejection there, not as a throw from\n * `Agent.create`.\n */\nexport class HandoffNameCollisionError extends Error {\n override readonly name = \"HandoffNameCollisionError\";\n readonly conflictingName: string;\n constructor(conflictingName: string) {\n super(\n `Two handoffs share the same tool name \"${conflictingName}\". ` +\n `Set { toolName } on at least one of them to disambiguate.`,\n );\n this.conflictingName = conflictingName;\n }\n}\n","/**\n * Handoff registry — pure state container per `Agent` instance.\n *\n * Holds the active dispatch chain (for depth + pair tracking) across the\n * lifetime of a single `agent.send()` call. Cleared between calls.\n *\n * @internal\n */\n\nimport { HandoffLoopError, HandoffPairLoopError } from \"../types/handoff.js\";\n\nexport interface HandoffChainState {\n /** Ordered chain of agentIds traversed so far (oldest first). */\n readonly chain: string[];\n /** Set of \"<sender>-><receiver>\" keys for pair-level loop detection (D221). */\n readonly seenPairs: Set<string>;\n /** Caller-supplied max depth (D218). */\n readonly maxDepth: number;\n}\n\nexport function createChainState(rootAgentId: string, maxDepth: number): HandoffChainState {\n return {\n chain: [rootAgentId],\n seenPairs: new Set(),\n maxDepth,\n };\n}\n\n/**\n * Record a handoff hop. Throws on depth-exceed (D218) or pair-loop (D221).\n * Mutates the state in place.\n */\nexport function recordHop(\n state: HandoffChainState,\n senderAgentId: string,\n receiverAgentId: string,\n): void {\n const pairKey = `${senderAgentId}->${receiverAgentId}`;\n if (state.seenPairs.has(pairKey)) {\n throw new HandoffPairLoopError(senderAgentId, receiverAgentId);\n }\n state.seenPairs.add(pairKey);\n state.chain.push(receiverAgentId);\n // chain.length = nodes; depth = hops = chain.length - 1.\n const depth = state.chain.length - 1;\n if (depth > state.maxDepth) {\n throw new HandoffLoopError(state.maxDepth, [...state.chain]);\n }\n}\n\nexport function currentDepth(state: HandoffChainState): number {\n return state.chain.length - 1;\n}\n","/**\n * D220 — Lazy-loaded OTel `handoff.transfer` span emitter.\n *\n * Emitted ONLY when `@opentelemetry/api` resolves from THIS package's directory.\n * It is an optional peer dependency: not installed for you, and under an isolated\n * node_modules layout a copy installed for some other package is not visible here.\n * When the require fails, `getTracer` caches `null` and every span becomes a no-op\n * — silently, with no warning, unlike `@theokit/sdk`'s own tracer, which prints one\n * when `telemetry.enabled = true` and OTel is absent.\n *\n * @internal\n */\n\n// Inline tracer-loader (same workaround as @theokit/sdk-cache/internal/telemetry.ts):\n// rollup-plugin-dts emits incomplete index.d.ts for newly-modified internal/ barrels\n// in @theokit/sdk. Runtime via the sub-path works; TypeScript users hit TS2305.\n// Inlining keeps sdk-handoff self-contained for the (small) observability hook.\nimport { createRequire } from \"node:module\";\n\ninterface SpanLike {\n setAttribute(key: string, value: string | number | boolean): SpanLike;\n end(): void;\n}\n\nconst _NOOP_SPAN: SpanLike = {\n setAttribute: () => _NOOP_SPAN,\n end: () => undefined,\n};\n\ninterface TracerLike {\n startSpan(\n name: string,\n options?: { attributes?: Record<string, string | number | boolean> },\n ): SpanLike;\n}\n\ninterface TracerCacheEntry {\n tracer: TracerLike | null;\n}\nconst tracerCache = new Map<string, TracerCacheEntry>();\n\nfunction getTracer(name: string, version = \"1.0.0\"): TracerLike | undefined {\n const cached = tracerCache.get(name);\n if (cached !== undefined) return cached.tracer ?? undefined;\n try {\n const r = createRequire(import.meta.url);\n const otel = r(\"@opentelemetry/api\") as {\n trace?: { getTracer: (n: string, v?: string) => TracerLike };\n };\n if (otel.trace?.getTracer === undefined) {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n const tracer = otel.trace.getTracer(name, version);\n tracerCache.set(name, { tracer });\n return tracer;\n } catch {\n tracerCache.set(name, { tracer: null });\n return undefined;\n }\n}\n\nconst TRACER_NAME = \"theokit-sdk-handoff\";\n\ninterface HandoffSpanHandle {\n setAttribute(key: string, value: string | number | boolean): void;\n end(): void;\n}\n\nconst NOOP: HandoffSpanHandle = { setAttribute: () => undefined, end: () => undefined };\n\nfunction safe<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport function startHandoffSpan(attrs: {\n from: string;\n to: string;\n reason: string;\n depth: number;\n toolName: string;\n}): HandoffSpanHandle {\n const tracer = getTracer(TRACER_NAME);\n if (tracer === undefined) return NOOP;\n const span: SpanLike | undefined = safe(\n () =>\n tracer.startSpan(\"handoff.transfer\", {\n attributes: {\n \"handoff.from\": attrs.from,\n \"handoff.to\": attrs.to,\n \"handoff.reason\": attrs.reason,\n \"handoff.depth\": attrs.depth,\n \"handoff.tool_name\": attrs.toolName,\n },\n }),\n undefined,\n );\n if (span === undefined) return NOOP;\n return {\n setAttribute: (k, v) => safe(() => span.setAttribute(k, v), undefined),\n end: () => safe(() => span.end(), undefined),\n };\n}\n","/**\n * Handoff dispatch orchestration.\n *\n * Pragmatic v1: when a handoff fires, the sender calls `receiver.send()`\n * with the (optionally filtered) history. The receiver's reply is returned\n * to the sender, which captures it as the answer to the user's question.\n *\n * NOTE: this is NOT pure peer-to-peer (the sender stays on the call stack\n * until the receiver returns). Pure intercept-and-swap requires deeper\n * agent-loop refactor; deferred to v2. v1 still validates the user-facing\n * value: \"agent A reasoned about routing, agent B answered.\"\n *\n * @internal\n */\n\nimport type { SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport type {\n HandoffContext,\n HandoffDescriptor,\n HandoffHistory,\n HandoffResult,\n} from \"../types/handoff.js\";\nimport { HandoffReceiverDisposedError } from \"../types/handoff.js\";\nimport { type HandoffChainState, recordHop } from \"./registry.js\";\nimport { startHandoffSpan } from \"./telemetry.js\";\n\n/**\n * EC-2 / D228 — `safeFilter` wraps `inputFilter`. On exception, falls back\n * to the un-filtered history and warns to stderr once per process.\n */\nlet warnedFilterOnce = false;\nasync function safeFilter(\n filter: ((h: HandoffHistory) => HandoffHistory | Promise<HandoffHistory>) | undefined,\n history: HandoffHistory,\n): Promise<HandoffHistory> {\n if (filter === undefined) return history;\n try {\n const result = filter(history);\n return result instanceof Promise ? await result : result;\n } catch (err) {\n if (!warnedFilterOnce) {\n warnedFilterOnce = true;\n process.stderr.write(\n `[handoff] inputFilter threw, falling back to full history: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n return history;\n }\n}\n\n/**\n * EC-4 / D229 — parse the LLM-provided JSON args. Returns undefined when\n * no `inputType` set; returns parsed value otherwise (default to `{}` on\n * empty/null input before Zod refinements).\n */\nfunction parseHandoffInput(descriptor: HandoffDescriptor, raw: unknown): unknown {\n const inputType = descriptor.options.inputType;\n if (inputType === undefined) return undefined;\n const candidate = raw === null || raw === undefined ? {} : raw;\n return inputType.parse(candidate);\n}\n\nfunction isAgentDisposed(agent: SDKAgent): boolean {\n // SDKAgent doesn't expose `disposed` publicly; check via duck-typing on\n // a known internal flag. Safe fallback: if we can't tell, assume alive.\n const maybe = agent as unknown as { disposed?: boolean };\n return maybe.disposed === true;\n}\n\n/**\n * Run a single handoff hop. Returns the receiver's reply text.\n *\n * Algorithm:\n * 1. EC-5: refuse if receiver disposed.\n * 2. Build HandoffContext.\n * 3. Check isEnabled() — if false, refuse with a clear error message.\n * 4. Parse inputType (D229).\n * 5. Run onHandoff(ctx, parsed) — throw aborts (D227).\n * 6. Apply inputFilter (safeFilter — D228).\n * 7. Record hop in chain state (depth + pair guards).\n * 8. Open OTel span (D220).\n * 9. Receiver: build the user-facing message and `await receiver.send(msg).then(wait)`.\n * 10. Close span + return reply.\n */\nasync function assertHandoffEnabled(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n receiverAgentId: string,\n): Promise<void> {\n const opt = descriptor.options.isEnabled;\n let enabled = true;\n if (typeof opt === \"boolean\") enabled = opt;\n else if (typeof opt === \"function\") {\n const r = opt(ctx);\n enabled = r instanceof Promise ? await r : r;\n }\n if (!enabled) {\n throw new Error(`Handoff to ${receiverAgentId} is disabled (isEnabled returned false)`);\n }\n}\n\nfunction parseAndValidate(descriptor: HandoffDescriptor, rawInputJson: unknown): unknown {\n try {\n return parseHandoffInput(descriptor, rawInputJson);\n } catch (err) {\n const detail =\n err instanceof z.ZodError\n ? (err.issues[0]?.message ?? \"schema_invalid\")\n : err instanceof Error\n ? err.message\n : String(err);\n throw new Error(`Handoff input validation failed: ${detail}`);\n }\n}\n\nasync function runOnHandoff(\n descriptor: HandoffDescriptor,\n ctx: HandoffContext,\n parsedInput: unknown,\n): Promise<void> {\n const onHandoff = descriptor.options.onHandoff;\n if (onHandoff === undefined) return;\n // biome-ignore lint/suspicious/noExplicitAny: parsedInput is typed unknown by design.\n const result = onHandoff(ctx, parsedInput as any);\n if (result instanceof Promise) await result;\n}\n\nfunction extractUserText(content: unknown): string | undefined {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return undefined;\n const text = content\n .filter((c): c is { type: \"text\"; text: string } => (c as { type?: string })?.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\");\n return text.length > 0 ? text : undefined;\n}\n\n/**\n * The user turn's text, for either transcript shape reaching this function.\n *\n * `HandoffHistory.messages` is `unknown[]` by design (it must not import the message types), and\n * two real shapes arrive through it: the SDK's flat `ToolContextMessage` (`{ role, content }`),\n * which is what a tool handler's `ctx.messages` carries, and the nested `SDKMessage`\n * (`{ type: \"user\", message: { role, content } }`). Reading only the nested one is half of why\n * #354 went unnoticed — the flat shape would have been skipped even had it been passed.\n */\nfunction userTextOf(entry: unknown): string | undefined {\n const m = entry as {\n type?: string;\n role?: string;\n content?: unknown;\n message?: { role?: string; content?: unknown };\n };\n if (m?.type === \"user\" && m.message?.role === \"user\") return extractUserText(m.message.content);\n if (m?.role === \"user\") return extractUserText(m.content);\n return undefined;\n}\n\nfunction extractLastUserMessage(history: HandoffHistory, senderAgentId: string): string {\n for (let i = history.messages.length - 1; i >= 0; i -= 1) {\n const text = userTextOf(history.messages[i]);\n if (text !== undefined) return text;\n }\n return `(Handoff from ${senderAgentId} — no prior user message in history.)`;\n}\n\nexport async function dispatchHandoff(args: {\n descriptor: HandoffDescriptor;\n senderAgentId: string;\n chainState: HandoffChainState;\n rawInputJson: unknown;\n /** The conversation so far (history wrapper). v1: just the LAST user message. */\n history: HandoffHistory;\n /** Override the message text sent to the receiver. Used by `Agent.handoffTo` imperative. */\n messageOverride?: string;\n}): Promise<{ reply: string; result: HandoffResult }> {\n const { descriptor, senderAgentId, chainState, rawInputJson, history, messageOverride } = args;\n const receiver = descriptor.target;\n\n if (isAgentDisposed(receiver)) {\n throw new HandoffReceiverDisposedError(receiver.agentId);\n }\n\n const depthAfterThisHop = chainState.chain.length;\n const ctx: HandoffContext = {\n senderAgentId,\n receiverAgentId: receiver.agentId,\n currentDepth: depthAfterThisHop,\n chain: [...chainState.chain, receiver.agentId],\n };\n\n await assertHandoffEnabled(descriptor, ctx, receiver.agentId);\n const parsedInput = parseAndValidate(descriptor, rawInputJson);\n await runOnHandoff(descriptor, ctx, parsedInput);\n\n // Filter history (D228 — resilient)\n const filteredHistory = await safeFilter(descriptor.options.inputFilter, history);\n\n // Record hop — may throw HandoffLoopError or HandoffPairLoopError\n recordHop(chainState, senderAgentId, receiver.agentId);\n\n const lastUserMessage = messageOverride ?? extractLastUserMessage(filteredHistory, senderAgentId);\n const reason = extractReason(parsedInput);\n\n const span = startHandoffSpan({\n from: senderAgentId,\n to: receiver.agentId,\n reason,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n });\n\n try {\n // #356 — `HandoffOptions.tools` was presented as an allowlist and read by nothing, so a caller\n // who set it got no restriction and no warning. It is wired to `SendOptions.activeTools`, the\n // same `withToolWhitelist` path `Agent.fork`'s `allowedTools` uses. An empty list means the\n // empty set (fail-closed), matching that contract; omitting the option means no restriction.\n const toolAllowlist = descriptor.options.tools;\n const run = await receiver.send(\n lastUserMessage,\n toolAllowlist !== undefined ? { activeTools: [...toolAllowlist] } : {},\n );\n const result = await run.wait();\n const reply = buildReply(result, receiver.agentId);\n return {\n reply,\n result: {\n from: senderAgentId,\n to: receiver.agentId,\n depth: depthAfterThisHop,\n toolName: descriptor.resolvedToolName,\n ...(reason !== \"\" ? { reasonFromLlm: reason } : {}),\n },\n };\n } finally {\n span.end();\n }\n}\n\nfunction extractReason(parsedInput: unknown): string {\n if (typeof parsedInput !== \"object\" || parsedInput === null) return \"\";\n if (!(\"reason\" in parsedInput)) return \"\";\n return String((parsedInput as { reason: unknown }).reason ?? \"\");\n}\n\nfunction buildReply(\n result: { status: string; result?: string; error?: { message: string } },\n receiverAgentId: string,\n): string {\n if (result.status === \"finished\" && result.result !== undefined) return result.result;\n const suffix = result.error !== undefined ? `: ${result.error.message}` : \"\";\n return `(Handoff target ${receiverAgentId} returned status=${result.status}${suffix})`;\n}\n","/**\n * Zod v4 → JSON Schema adapter for sdk-handoff.\n *\n * Uses Zod v4's native `z.toJSONSchema()` directly. v3 fallback removed\n * after zod-v4-migration plan (ADR D2).\n *\n * @internal\n */\n\nimport { toJSONSchema } from \"zod\";\n\ninterface ToJsonSchemaOptions {\n /** `\"any\"` keeps transforms/refinements as `{}` (loose). Default: `\"any\"`. */\n unrepresentable?: \"any\" | \"throw\";\n}\n\n/**\n * Convert a Zod schema to a JSON Schema object via Zod v4 native.\n *\n * @internal\n */\nexport function toJsonSchema(\n schema: unknown,\n options: ToJsonSchemaOptions = { unrepresentable: \"any\" },\n): Record<string, unknown> {\n // The schema param is `unknown` (callers pass `T extends ZodType` generics that\n // don't structurally satisfy Zod v4's `$ZodType`); cast to the exact parameter\n // type `toJSONSchema` expects rather than `any` — any z.* schema IS valid at runtime.\n return toJSONSchema(schema as Parameters<typeof toJSONSchema>[0], options) as Record<\n string,\n unknown\n >;\n}\n","/**\n * Convert `handoffs[]` entries into synthetic `transfer_to_<receiver>` tools\n * for injection into the agent's tool registry at construction time.\n *\n * The synthesized tool's handler calls `dispatchHandoff` internally and\n * returns the receiver's reply as `tool_result`. v1 trade-off documented\n * in dispatcher.ts.\n *\n * @internal\n */\n\nimport type { CustomTool, SDKAgent } from \"@theokit/sdk\";\nimport { z } from \"zod\";\nimport {\n type HandoffDescriptor,\n HandoffNameCollisionError,\n HandoffSelfReferenceError,\n} from \"../types/handoff.js\";\nimport { dispatchHandoff } from \"./dispatcher.js\";\nimport { createChainState } from \"./registry.js\";\nimport { slugifyAgentName } from \"./slugify-agent-name.js\";\nimport { toJsonSchema } from \"./to-json-schema.js\";\n\ninterface NormalizedHandoff {\n descriptor: HandoffDescriptor;\n}\n\n/**\n * Normalize each `handoffs[]` entry to a `HandoffDescriptor`. Raw `SDKAgent`\n * instances are auto-wrapped with default options. Validates:\n * - EC-6: no self-reference (would cause infinite recursion).\n * - D215: resolved tool names must be unique.\n */\nexport function normalizeHandoffs(\n parentAgentId: string,\n entries: ReadonlyArray<SDKAgent | HandoffDescriptor>,\n): NormalizedHandoff[] {\n if (entries.length === 0) return [];\n const out: NormalizedHandoff[] = [];\n const seenNames = new Set<string>();\n for (const entry of entries) {\n // Detect raw Agent vs HandoffDescriptor by presence of `.target`.\n const isDescriptor =\n typeof entry === \"object\" &&\n entry !== null &&\n \"target\" in entry &&\n \"options\" in entry &&\n \"resolvedToolName\" in entry;\n const descriptor = isDescriptor ? (entry as HandoffDescriptor) : autoWrap(entry as SDKAgent);\n if (descriptor.target.agentId === parentAgentId) {\n throw new HandoffSelfReferenceError(parentAgentId);\n }\n const name = descriptor.resolvedToolName;\n if (seenNames.has(name)) {\n throw new HandoffNameCollisionError(name);\n }\n seenNames.add(name);\n out.push({ descriptor });\n }\n return out;\n}\n\nfunction autoWrap(agent: SDKAgent): HandoffDescriptor {\n const name = resolveTargetName(agent);\n return {\n target: agent,\n options: {},\n resolvedToolName: `transfer_to_${name}`,\n };\n}\n\nfunction resolveTargetName(agent: SDKAgent): string {\n // Prefer a `name` field if exposed; fall back to a short agentId slug.\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugifyAgentName(candidate);\n}\n\n/**\n * Build a `CustomTool` for one handoff descriptor. The handler dispatches\n * the handoff using a fresh chain state per `send()`-level invocation.\n *\n * NOTE: this v1 builds a NEW chain state per tool invocation. Pure\n * cross-tool depth tracking within one send() requires per-Agent context\n * — deferred. The single-flight pair guard catches direct ping-pong even\n * without cross-invocation chain (since each call wraps the same depth\n * counter from 1).\n */\nexport function buildHandoffTool(\n parentAgentId: string,\n descriptor: HandoffDescriptor,\n maxHandoffDepth: number,\n): CustomTool {\n const description =\n descriptor.options.toolDescription ??\n `Transfer the conversation to the ${descriptor.target.agentId} agent. ` +\n `Use this when the user's request matches their specialty.`;\n\n const inputZod =\n descriptor.options.inputType ??\n z.object({\n reason: z.string().optional().describe(\"Brief reason for the transfer (one short sentence).\"),\n });\n // CustomTool.inputSchema expects a JSON schema (Record<string, unknown>),\n // not the raw Zod type. Convert lazily so we don't fail when Zod is missing.\n // Universal Zod 3+4 conversion (feature-detects native v4, falls back to lib on v3).\n const inputSchema = toJsonSchema(inputZod);\n\n return {\n name: descriptor.resolvedToolName,\n description,\n inputSchema,\n handler: async (\n input: unknown,\n ctx?: { messages?: ReadonlyArray<unknown> },\n ): Promise<string> => {\n const chainState = createChainState(parentAgentId, maxHandoffDepth);\n try {\n const { reply, result } = await dispatchHandoff({\n descriptor,\n senderAgentId: parentAgentId,\n chainState,\n rawInputJson: input,\n // #354 — the supervisor's transcript, which the SDK hands every tool handler as\n // `ctx.messages`. This used to be `{ messages: [] }` with the note \"v1: history replay\n // deferred\", so the dispatcher found no user message and sent the receiver the\n // placeholder instead of the question — and `inputFilter`, the documented redaction\n // hook, was handed an empty transcript to redact.\n history: { messages: ctx?.messages ?? [] },\n });\n return JSON.stringify({\n ok: true,\n transferred_to: result.to,\n depth: result.depth,\n reply,\n });\n } catch (err) {\n return JSON.stringify({\n ok: false,\n error: err instanceof Error ? err.name : \"HandoffError\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n },\n };\n}\n","/**\n * Public `Handoff` class — factory for handoff descriptors (Adoption\n * Roadmap #4; ADRs D214-D229).\n *\n * Usage:\n *\n * import { Agent } from \"@theokit/sdk\";\n * import { Handoff } from \"@theokit/sdk-handoff\";\n *\n * const billing = await Agent.create({\n * name: \"billing\",\n * systemPrompt: \"You handle billing questions.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * });\n *\n * const triage = await Agent.create({\n * name: \"triage\",\n * systemPrompt: \"Classify the user's intent and transfer to the right specialist.\",\n * model: { id: \"openai/gpt-4o-mini\" },\n * apiKey: process.env.OPENROUTER_API_KEY,\n * handoffs: [\n * billing, // auto-wrapped as Handoff.create(billing)\n * Handoff.create(supportAgent, { inputFilter: redactCreditCards }),\n * ],\n * });\n *\n * @public\n */\n\nimport { ConfigurationError, Plugin, type PluginContext, type SDKAgent } from \"@theokit/sdk\";\nimport type { ZodType } from \"zod\";\nimport { slugifyAgentName } from \"./internal/slugify-agent-name.js\";\nimport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\n\n/**\n * Prose to prepend to a SENDING agent's `systemPrompt` so the model knows the `transfer_to_*` tools\n * exist and what they mean.\n *\n * ```ts\n * systemPrompt: `${RECOMMENDED_HANDOFF_PROMPT_PREFIX}\\n\\nYou triage support requests.`\n * ```\n *\n * Nothing applies it for you — neither {@link Handoff.create} nor {@link Handoff.asPlugin} touches\n * the system prompt, so omitting it is legal and usually shows up as a model that never transfers.\n * Only the sender needs it; the receiver is unaware it was handed a conversation.\n *\n * @public\n */\nexport const RECOMMENDED_HANDOFF_PROMPT_PREFIX = `\nYou can transfer the conversation to other specialist agents when their\nexpertise matches the user's request. Invoke the appropriate\ntransfer_to_<agent> tool with a short reason. The receiving agent will\ntake over the conversation; do not duplicate their work.\n`.trim();\n\n/**\n * Peer-to-peer delegation: one agent hands the conversation to another and stops.\n *\n * A handoff is not a subagent call. A subagent runs, returns a result, and the parent continues; a\n * handoff TRANSFERS the turn — the target answers the user directly and the source does not resume.\n * Reach for it when the right responder is a different agent (billing, escalation, a specialist),\n * and for a tool-shaped \"go find this out and come back\", use `agents` / `Tool.create` instead.\n *\n * Two entry points, and they are not interchangeable:\n *\n * - {@link Handoff.create} builds one descriptor, for `Agent.create({ handoffs: [...] })`. A bare\n * `SDKAgent` in that array is auto-wrapped, so call this explicitly only to customise (input\n * schema, filter, callback).\n * - {@link Handoff.asPlugin} installs a whole set as a plugin, which is the SDK 2.x+ shape and what\n * the README's migration section points at.\n *\n * A namespace class: `new Handoff()` is a compile error, matching `Agent.create` / `Tool.create`.\n */\nexport class Handoff {\n private constructor() {}\n\n /**\n * Describe one handoff target. Pass the result inside `Handoff.asPlugin({ targets })` or\n * `Agent.create({ handoffs })`.\n *\n * ```ts\n * Handoff.create(billing, { toolName: \"escalate_billing\" })\n * ```\n *\n * A bare `SDKAgent` in either array is auto-wrapped with empty options, so call this explicitly\n * only to customise — see {@link HandoffOptions}, and note that `tools` there is currently\n * ignored.\n *\n * The tool the model sees is named `transfer_to_<slug>`, where the slug comes from the target's\n * `name` (falling back to its `agentId`, then to `\"anonymous\"`) with a leading `agent-` stripped,\n * every run of characters OUTSIDE `[A-Za-z0-9_-]` folded to a single `_`, leading and trailing\n * `_` trimmed, and a 64-char truncation. Hyphens and underscores are preserved, so `\"billing EU\"`\n * and `\"billing (EU)\"` both become `billing_EU` while `\"billing-EU\"` stays distinct. Two targets\n * whose names collapse to the same slug are NOT caught here — the collision is raised later, when\n * the set is normalised.\n *\n * Throws `ConfigurationError` with `code: \"handoff_target_required\"` for a null/undefined target,\n * and `code: \"handoff_target_invalid\"` for anything without a `send` method. It validates the\n * target only, never the options.\n */\n static create<TInput extends ZodType = ZodType>(\n target: SDKAgent,\n options: HandoffOptions<TInput> = {} as HandoffOptions<TInput>,\n ): HandoffDescriptor<TInput> {\n if (target === undefined || target === null) {\n // B-135: typed rather than bare, because `Handoff.create` is `@public` and a caller could\n // otherwise only distinguish these two refusals by matching the message string — which is not\n // a contract. Additive, not breaking: `ConfigurationError extends TheokitAgentError extends\n // Error`, and the messages are unchanged.\n throw new ConfigurationError(\"Handoff.create: target agent is required\", {\n code: \"handoff_target_required\",\n });\n }\n if (typeof target.send !== \"function\") {\n throw new ConfigurationError(\"Handoff.create: target must be an SDKAgent instance\", {\n code: \"handoff_target_invalid\",\n });\n }\n const resolvedToolName = options.toolName ?? `transfer_to_${slugifyName(target)}`;\n return {\n target,\n options,\n resolvedToolName,\n };\n }\n\n /**\n * Expose each target as a `transfer_to_<receiver>` tool on the host agent — the SDK 2.x way to\n * wire handoffs.\n *\n * ```ts\n * const support = await Agent.create({\n * name: \"support\",\n * systemPrompt: `${RECOMMENDED_HANDOFF_PROMPT_PREFIX}\\n\\nYou answer support requests.`,\n * plugins: [Handoff.asPlugin({ parentAgentId: \"support\", targets: [billing] })],\n * });\n * ```\n *\n * Pass `parentAgentId` — it defaults to `\"anonymous\"`, and it is what self-reference detection\n * and the chain trace compare against, so leaving it out weakens both. `maxHandoffDepth` defaults\n * to 5.\n *\n * Four behaviours that are easy to be surprised by:\n *\n * - **`maxHandoffDepth: 0`, or an empty `targets`, registers NOTHING** and returns a plugin that\n * silently does nothing. There is no error and no warning; the model simply never sees a\n * transfer tool.\n * - **Registration is awaited.** `register()` returns a promise that settles once the tools are\n * registered, and the plugin manager awaits it — so the transfer tools exist before the first\n * `send()`, and a failure in the lazy import or in target validation reaches the caller.\n * Before #355 it returned immediately and both of those were untrue.\n * - **The receiver gets the user's LAST message, not the whole conversation.** The tool handler\n * forwards the supervisor's transcript, from which the dispatcher takes the most recent user\n * turn (#354 — before that it forwarded nothing, and the receiver was sent the literal string\n * `` `(Handoff from <sender> — no prior user message in history.)` ``). That placeholder is\n * still what a receiver gets when there genuinely is no prior user turn. Anything beyond the\n * last question has to be in the target's own system prompt, or you drive the handoff yourself\n * with {@link handoffTo}, which passes an explicit message through.\n * - **The handoff tool never throws at the caller.** Every failure — loop detected, depth\n * exceeded, disposed receiver, `isEnabled` false, input that fails `inputType` — is caught\n * inside the tool handler and returned to the MODEL as\n * `{\"ok\":false,\"error\":\"<ErrorName>\",\"message\":\"…\"}`. The exported error classes are real, but\n * in this wiring they never reach your `try`/`catch`; watch the tool results instead.\n *\n * A self-referencing target and two targets resolving to the same tool name are both rejected —\n * from `register`, which the plugin manager awaits — so `HandoffSelfReferenceError` and\n * `HandoffNameCollisionError` reject the `Agent.create` you can `catch` around (#355; they used\n * to arrive as an unhandled rejection instead, leaving an agent silently without handoff tools).\n */\n static asPlugin(opts: AsPluginOptions): Plugin {\n const parent = opts.parentAgentId ?? \"anonymous\";\n const maxDepth = opts.maxHandoffDepth ?? 5;\n const targets = opts.targets;\n return Plugin.create({\n name: `handoff-${parent}`,\n version: \"1.0.0\",\n kind: \"general\" as const,\n // #355 — `async`, and the promise is RETURNED. The plugin contract types `register` as\n // `(ctx) => void | Promise<void>` and the manager awaits it, so returning it is all this\n // needed. It used to run an unawaited async IIFE and return immediately: the tools appeared a\n // module-load later, so whether they existed for the first `send()` depended on timing no\n // caller controls, and `normalizeHandoffs`' validation errors became unhandled rejections\n // that could not be caught around `Agent.create`.\n //\n // The import stays lazy — deferring it until `register` runs is what keeps the cold path\n // lean, and that never required leaving it unawaited INSIDE `register`.\n async register(ctx: PluginContext): Promise<void> {\n if (maxDepth === 0 || targets.length === 0) return;\n const { normalizeHandoffs, buildHandoffTool } = await import(\"./internal/tool-injector.js\");\n const normalized = normalizeHandoffs(parent, targets);\n for (const { descriptor } of normalized) {\n ctx.registerTool(buildHandoffTool(parent, descriptor, maxDepth));\n }\n },\n });\n }\n}\n\n/**\n * Options for {@link Handoff.asPlugin}.\n *\n * @public\n */\nexport interface AsPluginOptions {\n /**\n * Agents this one may transfer to. A bare `SDKAgent` is auto-wrapped; use\n * {@link Handoff.create} for a customised entry.\n *\n * An EMPTY array registers no tools at all and produces a plugin that does nothing — silently.\n */\n readonly targets: ReadonlyArray<SDKAgent | HandoffDescriptor>;\n /**\n * Identity of the HOST agent, as it will appear in the chain trace. Default `\"anonymous\"`.\n *\n * Self-reference detection compares `target.agentId` against this exact string, so a default\n * `\"anonymous\"` means an agent listing itself among `targets` is NOT caught, and the pair-loop\n * guard is the only thing left between you and a recursion.\n */\n readonly parentAgentId?: string;\n /**\n * Maximum hops in one chain before `HandoffLoopError`. Default 5. `0` disables handoffs entirely\n * rather than allowing zero hops.\n *\n * The counter is created FRESH for each tool invocation, so it bounds one dispatch, not the whole\n * `send()` — cross-tool depth accumulation is not implemented. In practice a single invocation\n * makes one hop, so this rarely fires; the pair guard (same sender → same receiver twice) is what\n * actually catches ping-pong.\n */\n readonly maxHandoffDepth?: number;\n}\n\nfunction slugifyName(agent: SDKAgent): string {\n const candidate = (agent as unknown as { name?: string }).name ?? agent.agentId ?? \"anonymous\";\n return slugifyAgentName(candidate);\n}\n\n/**\n * Hand `message` to `target` right now and return its reply text — no LLM routing, no tool call.\n *\n * ```ts\n * const reply = await handoffTo(triage, billing, \"refund for order 42\");\n * ```\n *\n * Use it for tests and for flows where YOU decide the destination. Unlike the plugin wiring, this\n * passes the message through verbatim, so the receiver actually sees what the user said.\n *\n * It THROWS, where the tool-based path swallows: a disposed receiver raises\n * `HandoffReceiverDisposedError`, `isEnabled: false` raises a plain `Error`, and an\n * `inputType` that rejects raises a plain `Error` wrapping the Zod message. Depth is fixed at 5 and\n * the chain state is fresh per call, so `HandoffLoopError` is unreachable here and only the\n * same-pair guard can fire — within a single call, never across calls.\n *\n * A receiver that does not finish cleanly does not throw either: you get the sentinel string\n * `` `(Handoff target <id> returned status=<status>)` `` as the reply. Check for it if the\n * distinction matters.\n *\n * Standalone rather than a method on `SDKAgent` so the agent class need not know about handoffs.\n *\n * @public\n */\nexport async function handoffTo(\n sender: SDKAgent,\n target: SDKAgent,\n message: string,\n options: HandoffOptions = {},\n): Promise<string> {\n const descriptor = Handoff.create(target, options);\n // Lazy import to avoid loading internal module unless this is called.\n const { dispatchHandoff } = await import(\"./internal/dispatcher.js\");\n const { createChainState } = await import(\"./internal/registry.js\");\n const chainState = createChainState(sender.agentId, 5);\n const { reply } = await dispatchHandoff({\n descriptor,\n senderAgentId: sender.agentId,\n chainState,\n rawInputJson: undefined,\n history: { messages: [] },\n messageOverride: message,\n });\n return reply;\n}\n","/**\n * `@theokit/sdk-handoff` — inter-agent dispatch for `@theokit/sdk`.\n *\n * Extracted from `@theokit/sdk@1.7.0` as part of the SDK 2.0 package split\n * (Phase 4 / T4.1). Integrates with `Agent` via the Plugin protocol —\n * `Handoff.asPlugin({ targets })` returns a `Plugin` consumed by\n * `Agent.create({ plugins: [...] })`.\n *\n * @packageDocumentation\n */\n\nexport {\n type AsPluginOptions,\n Handoff,\n handoffTo,\n RECOMMENDED_HANDOFF_PROMPT_PREFIX,\n} from \"./handoff.js\";\nexport type { HandoffDescriptor, HandoffOptions } from \"./types/handoff.js\";\nexport {\n HandoffLoopError,\n HandoffNameCollisionError,\n HandoffPairLoopError,\n HandoffReceiverDisposedError,\n HandoffSelfReferenceError,\n} from \"./types/handoff.js\";\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SDKAgent, Plugin } from '@theokit/sdk';
|
|
2
2
|
import { ZodType } from 'zod';
|
|
3
|
-
import { H as HandoffDescriptor, a as HandoffOptions } from './handoff-
|
|
4
|
-
export { b as HandoffLoopError, c as HandoffNameCollisionError, d as HandoffPairLoopError, e as HandoffReceiverDisposedError, f as HandoffSelfReferenceError } from './handoff-
|
|
3
|
+
import { H as HandoffDescriptor, a as HandoffOptions } from './handoff-D7malWe_.cjs';
|
|
4
|
+
export { b as HandoffLoopError, c as HandoffNameCollisionError, d as HandoffPairLoopError, e as HandoffReceiverDisposedError, f as HandoffSelfReferenceError } from './handoff-D7malWe_.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Public `Handoff` class — factory for handoff descriptors (Adoption
|
|
@@ -9,7 +9,8 @@ export { b as HandoffLoopError, c as HandoffNameCollisionError, d as HandoffPair
|
|
|
9
9
|
*
|
|
10
10
|
* Usage:
|
|
11
11
|
*
|
|
12
|
-
* import { Agent
|
|
12
|
+
* import { Agent } from "@theokit/sdk";
|
|
13
|
+
* import { Handoff } from "@theokit/sdk-handoff";
|
|
13
14
|
*
|
|
14
15
|
* const billing = await Agent.create({
|
|
15
16
|
* name: "billing",
|
|
@@ -32,53 +33,167 @@ export { b as HandoffLoopError, c as HandoffNameCollisionError, d as HandoffPair
|
|
|
32
33
|
* @public
|
|
33
34
|
*/
|
|
34
35
|
|
|
35
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Prose to prepend to a SENDING agent's `systemPrompt` so the model knows the `transfer_to_*` tools
|
|
38
|
+
* exist and what they mean.
|
|
39
|
+
*
|
|
40
|
+
* ```ts
|
|
41
|
+
* systemPrompt: `${RECOMMENDED_HANDOFF_PROMPT_PREFIX}\n\nYou triage support requests.`
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* Nothing applies it for you — neither {@link Handoff.create} nor {@link Handoff.asPlugin} touches
|
|
45
|
+
* the system prompt, so omitting it is legal and usually shows up as a model that never transfers.
|
|
46
|
+
* Only the sender needs it; the receiver is unaware it was handed a conversation.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
36
50
|
declare const RECOMMENDED_HANDOFF_PROMPT_PREFIX: string;
|
|
51
|
+
/**
|
|
52
|
+
* Peer-to-peer delegation: one agent hands the conversation to another and stops.
|
|
53
|
+
*
|
|
54
|
+
* A handoff is not a subagent call. A subagent runs, returns a result, and the parent continues; a
|
|
55
|
+
* handoff TRANSFERS the turn — the target answers the user directly and the source does not resume.
|
|
56
|
+
* Reach for it when the right responder is a different agent (billing, escalation, a specialist),
|
|
57
|
+
* and for a tool-shaped "go find this out and come back", use `agents` / `Tool.create` instead.
|
|
58
|
+
*
|
|
59
|
+
* Two entry points, and they are not interchangeable:
|
|
60
|
+
*
|
|
61
|
+
* - {@link Handoff.create} builds one descriptor, for `Agent.create({ handoffs: [...] })`. A bare
|
|
62
|
+
* `SDKAgent` in that array is auto-wrapped, so call this explicitly only to customise (input
|
|
63
|
+
* schema, filter, callback).
|
|
64
|
+
* - {@link Handoff.asPlugin} installs a whole set as a plugin, which is the SDK 2.x+ shape and what
|
|
65
|
+
* the README's migration section points at.
|
|
66
|
+
*
|
|
67
|
+
* A namespace class: `new Handoff()` is a compile error, matching `Agent.create` / `Tool.create`.
|
|
68
|
+
*/
|
|
37
69
|
declare class Handoff {
|
|
38
70
|
private constructor();
|
|
39
71
|
/**
|
|
40
|
-
*
|
|
41
|
-
* (
|
|
42
|
-
*
|
|
72
|
+
* Describe one handoff target. Pass the result inside `Handoff.asPlugin({ targets })` or
|
|
73
|
+
* `Agent.create({ handoffs })`.
|
|
74
|
+
*
|
|
75
|
+
* ```ts
|
|
76
|
+
* Handoff.create(billing, { toolName: "escalate_billing" })
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* A bare `SDKAgent` in either array is auto-wrapped with empty options, so call this explicitly
|
|
80
|
+
* only to customise — see {@link HandoffOptions}, and note that `tools` there is currently
|
|
81
|
+
* ignored.
|
|
43
82
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
83
|
+
* The tool the model sees is named `transfer_to_<slug>`, where the slug comes from the target's
|
|
84
|
+
* `name` (falling back to its `agentId`, then to `"anonymous"`) with a leading `agent-` stripped,
|
|
85
|
+
* every run of characters OUTSIDE `[A-Za-z0-9_-]` folded to a single `_`, leading and trailing
|
|
86
|
+
* `_` trimmed, and a 64-char truncation. Hyphens and underscores are preserved, so `"billing EU"`
|
|
87
|
+
* and `"billing (EU)"` both become `billing_EU` while `"billing-EU"` stays distinct. Two targets
|
|
88
|
+
* whose names collapse to the same slug are NOT caught here — the collision is raised later, when
|
|
89
|
+
* the set is normalised.
|
|
90
|
+
*
|
|
91
|
+
* Throws `ConfigurationError` with `code: "handoff_target_required"` for a null/undefined target,
|
|
92
|
+
* and `code: "handoff_target_invalid"` for anything without a `send` method. It validates the
|
|
93
|
+
* target only, never the options.
|
|
46
94
|
*/
|
|
47
95
|
static create<TInput extends ZodType = ZodType>(target: SDKAgent, options?: HandoffOptions<TInput>): HandoffDescriptor<TInput>;
|
|
48
96
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
97
|
+
* Expose each target as a `transfer_to_<receiver>` tool on the host agent — the SDK 2.x way to
|
|
98
|
+
* wire handoffs.
|
|
99
|
+
*
|
|
100
|
+
* ```ts
|
|
101
|
+
* const support = await Agent.create({
|
|
102
|
+
* name: "support",
|
|
103
|
+
* systemPrompt: `${RECOMMENDED_HANDOFF_PROMPT_PREFIX}\n\nYou answer support requests.`,
|
|
104
|
+
* plugins: [Handoff.asPlugin({ parentAgentId: "support", targets: [billing] })],
|
|
105
|
+
* });
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* Pass `parentAgentId` — it defaults to `"anonymous"`, and it is what self-reference detection
|
|
109
|
+
* and the chain trace compare against, so leaving it out weakens both. `maxHandoffDepth` defaults
|
|
110
|
+
* to 5.
|
|
111
|
+
*
|
|
112
|
+
* Four behaviours that are easy to be surprised by:
|
|
52
113
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
114
|
+
* - **`maxHandoffDepth: 0`, or an empty `targets`, registers NOTHING** and returns a plugin that
|
|
115
|
+
* silently does nothing. There is no error and no warning; the model simply never sees a
|
|
116
|
+
* transfer tool.
|
|
117
|
+
* - **Registration is awaited.** `register()` returns a promise that settles once the tools are
|
|
118
|
+
* registered, and the plugin manager awaits it — so the transfer tools exist before the first
|
|
119
|
+
* `send()`, and a failure in the lazy import or in target validation reaches the caller.
|
|
120
|
+
* Before #355 it returned immediately and both of those were untrue.
|
|
121
|
+
* - **The receiver gets the user's LAST message, not the whole conversation.** The tool handler
|
|
122
|
+
* forwards the supervisor's transcript, from which the dispatcher takes the most recent user
|
|
123
|
+
* turn (#354 — before that it forwarded nothing, and the receiver was sent the literal string
|
|
124
|
+
* `` `(Handoff from <sender> — no prior user message in history.)` ``). That placeholder is
|
|
125
|
+
* still what a receiver gets when there genuinely is no prior user turn. Anything beyond the
|
|
126
|
+
* last question has to be in the target's own system prompt, or you drive the handoff yourself
|
|
127
|
+
* with {@link handoffTo}, which passes an explicit message through.
|
|
128
|
+
* - **The handoff tool never throws at the caller.** Every failure — loop detected, depth
|
|
129
|
+
* exceeded, disposed receiver, `isEnabled` false, input that fails `inputType` — is caught
|
|
130
|
+
* inside the tool handler and returned to the MODEL as
|
|
131
|
+
* `{"ok":false,"error":"<ErrorName>","message":"…"}`. The exported error classes are real, but
|
|
132
|
+
* in this wiring they never reach your `try`/`catch`; watch the tool results instead.
|
|
56
133
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* });
|
|
134
|
+
* A self-referencing target and two targets resolving to the same tool name are both rejected —
|
|
135
|
+
* from `register`, which the plugin manager awaits — so `HandoffSelfReferenceError` and
|
|
136
|
+
* `HandoffNameCollisionError` reject the `Agent.create` you can `catch` around (#355; they used
|
|
137
|
+
* to arrive as an unhandled rejection instead, leaving an agent silently without handoff tools).
|
|
62
138
|
*/
|
|
63
139
|
static asPlugin(opts: AsPluginOptions): Plugin;
|
|
64
140
|
}
|
|
65
141
|
/**
|
|
66
|
-
* Options for
|
|
67
|
-
*
|
|
142
|
+
* Options for {@link Handoff.asPlugin}.
|
|
143
|
+
*
|
|
144
|
+
* @public
|
|
68
145
|
*/
|
|
69
146
|
interface AsPluginOptions {
|
|
147
|
+
/**
|
|
148
|
+
* Agents this one may transfer to. A bare `SDKAgent` is auto-wrapped; use
|
|
149
|
+
* {@link Handoff.create} for a customised entry.
|
|
150
|
+
*
|
|
151
|
+
* An EMPTY array registers no tools at all and produces a plugin that does nothing — silently.
|
|
152
|
+
*/
|
|
70
153
|
readonly targets: ReadonlyArray<SDKAgent | HandoffDescriptor>;
|
|
154
|
+
/**
|
|
155
|
+
* Identity of the HOST agent, as it will appear in the chain trace. Default `"anonymous"`.
|
|
156
|
+
*
|
|
157
|
+
* Self-reference detection compares `target.agentId` against this exact string, so a default
|
|
158
|
+
* `"anonymous"` means an agent listing itself among `targets` is NOT caught, and the pair-loop
|
|
159
|
+
* guard is the only thing left between you and a recursion.
|
|
160
|
+
*/
|
|
71
161
|
readonly parentAgentId?: string;
|
|
162
|
+
/**
|
|
163
|
+
* Maximum hops in one chain before `HandoffLoopError`. Default 5. `0` disables handoffs entirely
|
|
164
|
+
* rather than allowing zero hops.
|
|
165
|
+
*
|
|
166
|
+
* The counter is created FRESH for each tool invocation, so it bounds one dispatch, not the whole
|
|
167
|
+
* `send()` — cross-tool depth accumulation is not implemented. In practice a single invocation
|
|
168
|
+
* makes one hop, so this rarely fires; the pair guard (same sender → same receiver twice) is what
|
|
169
|
+
* actually catches ping-pong.
|
|
170
|
+
*/
|
|
72
171
|
readonly maxHandoffDepth?: number;
|
|
73
172
|
}
|
|
74
173
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
174
|
+
* Hand `message` to `target` right now and return its reply text — no LLM routing, no tool call.
|
|
175
|
+
*
|
|
176
|
+
* ```ts
|
|
177
|
+
* const reply = await handoffTo(triage, billing, "refund for order 42");
|
|
178
|
+
* ```
|
|
179
|
+
*
|
|
180
|
+
* Use it for tests and for flows where YOU decide the destination. Unlike the plugin wiring, this
|
|
181
|
+
* passes the message through verbatim, so the receiver actually sees what the user said.
|
|
77
182
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
183
|
+
* It THROWS, where the tool-based path swallows: a disposed receiver raises
|
|
184
|
+
* `HandoffReceiverDisposedError`, `isEnabled: false` raises a plain `Error`, and an
|
|
185
|
+
* `inputType` that rejects raises a plain `Error` wrapping the Zod message. Depth is fixed at 5 and
|
|
186
|
+
* the chain state is fresh per call, so `HandoffLoopError` is unreachable here and only the
|
|
187
|
+
* same-pair guard can fire — within a single call, never across calls.
|
|
188
|
+
*
|
|
189
|
+
* A receiver that does not finish cleanly does not throw either: you get the sentinel string
|
|
190
|
+
* `` `(Handoff target <id> returned status=<status>)` `` as the reply. Check for it if the
|
|
191
|
+
* distinction matters.
|
|
192
|
+
*
|
|
193
|
+
* Standalone rather than a method on `SDKAgent` so the agent class need not know about handoffs.
|
|
194
|
+
*
|
|
195
|
+
* @public
|
|
81
196
|
*/
|
|
82
197
|
declare function handoffTo(sender: SDKAgent, target: SDKAgent, message: string, options?: HandoffOptions): Promise<string>;
|
|
83
198
|
|
|
84
|
-
export { type AsPluginOptions, Handoff, HandoffDescriptor, HandoffOptions, RECOMMENDED_HANDOFF_PROMPT_PREFIX, handoffTo };
|
|
199
|
+
export { type AsPluginOptions, Handoff, type HandoffDescriptor, type HandoffOptions, RECOMMENDED_HANDOFF_PROMPT_PREFIX, handoffTo };
|