import { z } from 'zod'; import type { ToolDefinitionOptions, ToolDefinitionSchema } from './types.js'; import type { Agent } from './agent.js'; /** * Symbol-tagged marker identifying a handoff tool. Looked up via * `Symbol.for(...)` so cross-bundle / cross-realm checks succeed even when * `@gemstack/ai-sdk` is loaded twice (rare, but possible in monorepo + linked * setups). */ export declare const HANDOFF_MARKER: unique symbol; /** * Internal spec attached to a handoff tool. The agent loop reads this when * it sees a tool call that lands on a `HandoffTool` — it does NOT execute * the tool's body (there isn't one). Instead it short-circuits the loop, * synthesizes a tool result, and pivots control to a new instance of * `AgentClass` for the rest of the conversation. */ export interface HandoffSpec { readonly AgentClass: new (...args: unknown[]) => Agent; readonly name: string; readonly description: string; readonly inputSchema: z.ZodType; } /** * A tool returned by {@link handoff}. The loop recognizes it via the * `HANDOFF_MARKER` symbol property and treats it as a control-transfer, * not a normal server tool. Its `execute` is intentionally absent. */ export interface HandoffTool { readonly [HANDOFF_MARKER]: true; readonly __handoffSpec: HandoffSpec; readonly definition: ToolDefinitionOptions; readonly execute?: undefined; toSchema(): ToolDefinitionSchema; } /** * Options for {@link handoff}. All fields optional — by default, a handoff * tool is named `handoffTo${AgentClass.name}` and accepts a single * `message: string` argument that becomes the transition prompt seen by * the new agent as its first user message. */ export interface HandoffOptions { /** Override the tool name. Default: `handoffTo${AgentClass.name}`. */ name?: string; /** * Trigger guidance — a short phrase appended to the description so the * model knows when to pick this handoff. Example: `'pricing or sales'` * → "Hand off the conversation to SalesAgent for pricing or sales." */ when?: string; /** Override the entire description. If set, takes precedence over `when`. */ description?: string; /** * Zod schema for the handoff payload. Defaults to * `z.object({ message: z.string() })` — the parent's model writes a * transition prompt that becomes the child's first user message. * * Custom schemas are supported but the loop reads `args.message` (string) * as the transition prompt. Schemas without a `message` string field will * pass an empty transition message; the carried conversation history is * still surfaced to the child. */ inputSchema?: TInput; } /** * Define a handoff tool — a control-transfer tool the parent agent's model * can call to pivot the conversation to another agent. After the model * calls it, the parent's loop ends and the child agent runs from the same * message history with its own instructions, tools, and model. * * Distinct from {@link Agent.asTool} (which is call-and-return: the parent * resumes after the child finishes and incorporates the child's text as a * tool result). Handoffs do not return — the child owns the rest of the * conversation. * * @example * ```ts * class TriageAgent extends Agent { * tools() { * return [ * handoff(SalesAgent, { when: 'pricing or sales questions' }), * handoff(SupportAgent, { when: 'bug reports or technical issues' }), * ] * } * } * ``` */ export declare function handoff(AgentClass: new (...args: never[]) => Agent, opts?: HandoffOptions): HandoffTool; /** * Structural typeguard. Used by the agent loop to detect handoff tools * without coupling to a class hierarchy — handoff tools are plain objects * tagged with the {@link HANDOFF_MARKER} symbol. */ export declare function isHandoffTool(t: unknown): t is HandoffTool; //# sourceMappingURL=handoff.d.ts.map