{"version":3,"sources":["../../src/llm/tool_context.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { JSONSchema7 } from 'json-schema';\nimport { z } from 'zod';\nimport * as z4 from 'zod/v4';\nimport type { Agent } from '../voice/agent.js';\nimport type { RunContext, UnknownUserData } from '../voice/run_context.js';\nimport { isZod4Schema, isZodObjectSchema, isZodSchema } from './zod-utils.js';\n\n// heavily inspired by Vercel AI's `tool()`:\n// https://github.com/vercel/ai/blob/3b0983b/packages/ai/core/tool/tool.ts\n\nconst TOOL_SYMBOL = Symbol('tool');\nconst FUNCTION_TOOL_SYMBOL = Symbol('function_tool');\nconst PROVIDER_TOOL_SYMBOL = Symbol('provider_tool');\nconst TOOLSET_SYMBOL = Symbol('toolset');\nconst TOOL_ERROR_SYMBOL = Symbol('tool_error');\nconst HANDOFF_SYMBOL = Symbol('handoff');\n\nexport type JSONValue = null | string | number | boolean | JSONObject | JSONArray;\n\nexport type JSONArray = JSONValue[];\n\nexport type JSONObject = {\n  [key: string]: JSONValue;\n};\n\n// Supports both Zod v3 and v4 schemas, as well as raw JSON schema\n// Adapted from Vercel AI SDK's FlexibleSchema approach\n// Source: https://github.com/vercel/ai/blob/main/packages/provider-utils/src/schema.ts#L67-L70\n//\n// Vercel uses StandardSchemaV1 from @standard-schema/spec package.\n// We use a simpler approach by directly checking for schema properties:\n// - Zod v3: Has `_output` property\n// - Zod v4: Implements Standard Schema spec with `~standard` property\n// - JSON Schema: Plain object fallback\nexport type ToolInputSchema<T = JSONObject> =\n  | {\n      // Zod v3 schema - has _output property for type inference\n      _output: T;\n    }\n  | {\n      // Zod v4 schema (Standard Schema) - has ~standard property\n      '~standard': {\n        types?: { output: T };\n      };\n    }\n  | JSONSchema7;\n\n/**\n * Infer the output type from a ToolInputSchema.\n * Adapted from Vercel AI SDK's InferSchema type.\n * Source: https://github.com/vercel/ai/blob/main/packages/provider-utils/src/schema.ts#L72-L79\n */\nexport type InferToolInput<T> = T extends { _output: infer O }\n  ? O\n  : T extends { '~standard': { types?: { output: infer O } } }\n    ? O\n    : any; // eslint-disable-line @typescript-eslint/no-explicit-any -- Fallback type for JSON Schema objects without type inference\n\n/**\n * Tool argument type for a (possibly absent) parameters schema. When `parameters` is omitted the\n * generic defaults to `undefined`, yielding an empty-args type; otherwise the args are inferred\n * from the schema via {@link InferToolInput}. Wrapped in tuples to keep the check non-distributive.\n * @internal\n */\nexport type ToolArgs<Schema> = [Schema] extends [undefined]\n  ? Record<string, never>\n  : InferToolInput<Schema>;\n\nexport type ToolType = 'function' | 'provider';\n\nexport type ToolChoice =\n  | 'auto'\n  | 'none'\n  | 'required'\n  | {\n      type: 'function';\n      function: {\n        name: string;\n      };\n    };\n\nexport type DuplicateMode = 'allow' | 'reject' | 'replace' | 'confirm';\n\nexport const CONFIRM_DUPLICATE_PARAM = 'lk_agents_confirm_duplicate';\n\nconst CONFIRM_DUPLICATE_DESCRIPTION =\n  'Set this to true to confirm you want to run a duplicate. ' +\n  'Only do this when user confirms the duplication is needed.';\n\nexport class ToolError extends Error {\n  constructor(message: string) {\n    super(message);\n\n    Object.defineProperty(this, TOOL_ERROR_SYMBOL, {\n      value: true,\n    });\n  }\n}\n\nexport const ToolFlag = {\n  NONE: 0,\n  IGNORE_ON_ENTER: 1 << 0,\n  CANCELLABLE: 1 << 1,\n} as const;\n\nexport type ToolFlag = (typeof ToolFlag)[keyof typeof ToolFlag];\n\nexport interface AgentHandoff {\n  /**\n   * The agent to handoff to.\n   */\n  agent: Agent;\n\n  /**\n   * The return value of the tool.\n   */\n  returns?: any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n  [HANDOFF_SYMBOL]: true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function handoff(options: { agent: Agent; returns?: any }): AgentHandoff {\n  return {\n    agent: options.agent,\n    returns: options.returns,\n    [HANDOFF_SYMBOL]: true,\n  };\n}\n\nexport interface ToolOptions<UserData = UnknownUserData> {\n  /**\n   * RunContext for the current agent session.\n   */\n  ctx: RunContext<UserData>;\n\n  /**\n   * The ID of the tool call.\n   */\n  toolCallId: string;\n\n  /**\n   * An abort signal that indicates that the overall operation should be aborted.\n   */\n  abortSignal: AbortSignal;\n}\n\nexport type ToolExecuteFunction<\n  Parameters extends JSONObject,\n  UserData = UnknownUserData,\n  Result = unknown,\n> = (args: Parameters, opts: ToolOptions<UserData>) => Promise<Result>;\n\nexport interface Tool {\n  /**\n   * The type of the tool.\n   * @internal Either user-defined function tool or provider-side tool.\n   */\n  type: ToolType;\n\n  /**\n   * Stable identifier used to key the tool inside a `ToolContext`. For function tools this\n   * mirrors `name`; for provider tools this is the provider tool id.\n   */\n  id: string;\n\n  [TOOL_SYMBOL]: true;\n}\n\n// TODO(AJS-112): support provider tools\nexport abstract class ProviderTool implements Tool {\n  readonly type = 'provider' as const;\n\n  readonly id: string;\n\n  readonly [TOOL_SYMBOL] = true as const;\n\n  readonly [PROVIDER_TOOL_SYMBOL] = true as const;\n\n  constructor({ id }: { id: string }) {\n    this.id = id;\n  }\n}\n\nexport interface FunctionTool<\n  Parameters extends JSONObject = JSONObject,\n  UserData = UnknownUserData,\n  Result = unknown,\n> extends Tool {\n  type: 'function';\n\n  /**\n   * The name of the tool. Used to identify it inside a `ToolContext` and exposed to the LLM\n   * as the function name to call. Also surfaced as the inherited `Tool.id`.\n   */\n  name: string;\n\n  /**\n   * The description of the tool. Will be used by the language model to decide whether to use the tool.\n   */\n  description: string;\n\n  /**\n   * The schema of the input that the tool expects. The language model will use this to generate the input.\n   * It is also used to validate the output of the language model.\n   * Use descriptions to make the input understandable for the language model.\n   */\n  parameters: ToolInputSchema<Parameters>;\n\n  /**\n   * An async function that is called with the arguments from the tool call and produces a result.\n   * It also carries context about current session, user-defined data, and the tool call id, etc.\n   */\n  execute: ToolExecuteFunction<Parameters, UserData, Result>;\n\n  flags: number;\n\n  onDuplicate: DuplicateMode;\n\n  [FUNCTION_TOOL_SYMBOL]: true;\n}\n\n/**\n * A function tool without `id`/`name`. Returned by {@link tool} when `name` is omitted; the\n * containing object key supplies the name when registered via an object-map tool definition.\n */\nexport type AnonFunctionTool<\n  Parameters extends JSONObject = JSONObject,\n  UserData = UnknownUserData,\n  Result = unknown,\n> = Omit<FunctionTool<Parameters, UserData, Result>, 'id' | 'name'> & {\n  id?: never;\n  name?: never;\n};\n\nexport interface ToolCalledEvent<UserData = UnknownUserData> {\n  ctx: RunContext<UserData>;\n  arguments: Record<string, unknown>;\n}\n\nexport interface ToolCompletedEvent<UserData = UnknownUserData> {\n  ctx: RunContext<UserData>;\n  output?: { type: 'output'; value: unknown } | { type: 'error'; value: Error };\n}\n\n/** Context passed to a {@link Toolset}'s `setup` hook when it activates. */\nexport interface ToolsetContext {\n  /**\n   * Replace the toolset's tools. Useful for dynamic sources\n   * (e.g. an MCP server) whose tools are discovered after `setup` or change at runtime.\n   */\n  updateTools(tools: readonly ToolContextEntry[]): void;\n}\n\n/**\n * Function tools of a `ToolContext`, sorted by name for deterministic provider payloads.\n * Provider tools are intentionally excluded — callers that need them iterate `flatten()`.\n * @internal\n */\nexport function sortedToolEntries<UserData = UnknownUserData>(\n  toolCtx: ToolContext<UserData>,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- entries are generic function tools\n): Array<[string, FunctionTool<any, UserData, any>]> {\n  return Object.entries(toolCtx.functionTools).sort(([nameA], [nameB]) =>\n    nameA.localeCompare(nameB),\n  );\n}\n\n/** Function tool names of a `ToolContext`, sorted for deterministic output. @internal */\nexport function sortedToolNames(toolCtx: ToolContext | undefined): string[] {\n  if (!toolCtx) return [];\n  return Object.keys(toolCtx.functionTools).sort((nameA, nameB) => nameA.localeCompare(nameB));\n}\n\n/**\n * A stateful collection of tools sharing a lifecycle. Tools registered through a `Toolset` are\n * flattened into the surrounding `ToolContext`, while the `Toolset` itself is tracked so its\n * `setup()` / `aclose()` hooks can be invoked by the agent runtime.\n */\nexport class Toolset {\n  readonly #id: string;\n\n  #tools: readonly ToolContextEntry[];\n\n  readonly [TOOLSET_SYMBOL] = true as const;\n\n  constructor({ id, tools }: { id: string; tools: readonly ToolContextEntry[] }) {\n    this.#id = id;\n    this.#tools = [...tools];\n  }\n\n  /**\n   * For when your tools share something that needs setup or cleanup, like a DB pool, an open MCP\n   * client, or listeners on a shared bus. `setup` runs once at activation, `aclose` once at\n   * teardown. If the tool list itself is dynamic (e.g. an MCP server), push it from `setup` via\n   * {@link ToolsetContext.updateTools}.\n   *\n   * @example Static tool list with a shared backing resource\n   * ```ts\n   * function createPostgresToolset(connectionUrl: string): Toolset {\n   *   const pool = new pg.Pool({ connectionString: connectionUrl });\n   *   return Toolset.create({\n   *     id: 'postgres',\n   *     tools: [queryOrders, queryCustomers],\n   *     aclose: () => pool.end(),\n   *   });\n   * }\n   * ```\n   *\n   * @example Dynamic tool list bound to an external source\n   * ```ts\n   * function createMcpToolset(url: string): Toolset {\n   *   const client = new MCPClient({ url });\n   *   return Toolset.create({\n   *     id: 'mcp_remote',\n   *     // setup connects and wires listeners that push the server's tools whenever they change;\n   *     // the runtime re-advertises without re-running anything.\n   *     setup: async ({ updateTools }) => {\n   *       const sync = async () => updateTools(await client.listTools());\n   *       client.on('connect', sync);\n   *       client.on('tool_list_changed', sync);\n   *       await client.connect();\n   *     },\n   *     tools: [],\n   *     aclose: () => client.disconnect(),\n   *   });\n   * }\n   * ```\n   */\n  static create(options: ToolsetCreateOptions): Toolset {\n    return new ToolsetFactory(options);\n  }\n\n  get id(): string {\n    return this.#id;\n  }\n\n  get tools(): readonly ToolContextEntry[] {\n    return this.#tools;\n  }\n\n  /**\n   * Replace the toolset's current tools. Backs {@link ToolsetContext.updateTools}; the runtime\n   * re-flattens and re-advertises after calling it.\n   *\n   * @internal\n   */\n  _setTools(tools: readonly ToolContextEntry[]): void {\n    this.#tools = [...tools];\n  }\n\n  async setup(_ctx: ToolsetContext): Promise<void> {}\n\n  async aclose(): Promise<void> {}\n}\n\n/** Options accepted by `Toolset.create()` — id + tools plus optional setup/teardown hooks. */\nexport interface ToolsetCreateOptions {\n  id: string;\n  /**\n   * One-time async initialization run when the toolset activates — e.g. connecting to a server\n   * and wiring listeners. Push a changed tool list via {@link ToolsetContext.updateTools}.\n   */\n  setup?: (ctx: ToolsetContext) => Promise<void>;\n  /** The toolset's initial tools. */\n  tools: readonly ToolContextEntry[];\n  /** Invoked when the toolset is being torn down. Release awaitable resources here. */\n  aclose?: () => Promise<void>;\n}\n\n/** Backing implementation of `Toolset.create()`. Kept private so callers go through the factory. */\nclass ToolsetFactory extends Toolset {\n  readonly #setupFn?: (ctx: ToolsetContext) => Promise<void>;\n\n  readonly #acloseFn?: () => Promise<void>;\n\n  constructor({ id, setup, tools, aclose }: ToolsetCreateOptions) {\n    super({ id, tools });\n    this.#setupFn = setup;\n    this.#acloseFn = aclose;\n  }\n\n  override async setup(ctx: ToolsetContext): Promise<void> {\n    if (this.#setupFn) await this.#setupFn(ctx);\n  }\n\n  override async aclose(): Promise<void> {\n    if (this.#acloseFn) await this.#acloseFn();\n  }\n}\n\n/**\n * Tool context or data that can be normalized into one. Used by APIs that accept an already-built\n * context as well as direct tool lists or tool maps.\n */\nexport type ToolContextLike<UserData = UnknownUserData> =\n  | ToolContext<UserData>\n  | ToolContextInit<UserData>;\n\n/**\n * Initial tool data accepted by `ToolContext` constructors and update methods.\n */\nexport type ToolContextInit<UserData = UnknownUserData> =\n  | readonly ToolContextEntry<UserData>[]\n  | ToolDefinitionMap<UserData>;\n\n/**\n * Object shorthand for declaring anonymous function tools keyed by their model-visible names.\n */\nexport type ToolDefinitionMap<UserData = UnknownUserData> = {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- entries accept any parameter/result types\n  readonly [toolName: string]: AnonFunctionTool<any, UserData, any>;\n};\n\nexport function toToolContext<UserData = UnknownUserData>(\n  input: ToolContextLike<UserData>,\n): ToolContext<UserData>;\n\nexport function toToolContext<UserData = UnknownUserData>(\n  input: ToolContextLike<UserData> | undefined,\n): ToolContext<UserData> | undefined;\n\nexport function toToolContext<UserData = UnknownUserData>(\n  input: ToolContextLike<UserData> | undefined,\n): ToolContext<UserData> | undefined {\n  if (input === undefined) return undefined;\n  return input instanceof ToolContext ? input : new ToolContext(input);\n}\n\nexport function normalizeToolContextInit<UserData = UnknownUserData>(\n  input: ToolContextInit<UserData>,\n): ToolContextEntry<UserData>[] {\n  if (Array.isArray(input)) {\n    return [...input];\n  }\n\n  return Object.entries(input).map(([name, toolValue]) => {\n    if (name.length === 0) {\n      throw new Error('tools object keys must be non-empty');\n    }\n\n    if (!isAnonFunctionTool(toolValue)) {\n      throw new Error(`tools object entry \"${name}\" must be an anonymous function tool`);\n    }\n\n    if ('name' in toolValue || 'id' in toolValue) {\n      throw new Error(`tools object entry \"${name}\" must be anonymous`);\n    }\n\n    return {\n      ...toolValue,\n      id: name,\n      name,\n    };\n  });\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ToolContext entries accept any function-tool parameter/result types\nexport type ToolContextEntry<UserData = any> =\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  FunctionTool<any, UserData, any> | ProviderTool | Toolset;\n\nexport class ToolContext<UserData = UnknownUserData> {\n  private _tools: ToolContextEntry<UserData>[] = [];\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ToolContext stores generic function tools\n  private _functionToolsMap: Map<string, FunctionTool<any, UserData, any>> = new Map();\n  private _providerTools: ProviderTool[] = [];\n  private _toolsets: Toolset[] = [];\n\n  constructor(tools: ToolContextInit<UserData> = []) {\n    this.updateTools(tools);\n  }\n\n  static empty<UserData = UnknownUserData>(): ToolContext<UserData> {\n    return new ToolContext<UserData>([]);\n  }\n\n  /** A copy of all function tools in the tool context, including those in tool sets. */\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  get functionTools(): Record<string, FunctionTool<any, UserData, any>> {\n    return Object.fromEntries(this._functionToolsMap);\n  }\n\n  /** A copy of all provider tools in the tool context, including those in tool sets. */\n  get providerTools(): ProviderTool[] {\n    return [...this._providerTools];\n  }\n\n  /** A copy of all toolsets registered in the context. */\n  get toolsets(): readonly Toolset[] {\n    return [...this._toolsets];\n  }\n\n  /**\n   * A copy of the raw tool list this context was constructed with.\n   */\n  get tools(): readonly ToolContextEntry<UserData>[] {\n    return [...this._tools];\n  }\n\n  /** Flatten the tool context to a list of tools. */\n  flatten(): Tool[] {\n    return [...this._functionToolsMap.values(), ...this._providerTools];\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic registry over any parameter/result types\n  getFunctionTool(id: string): FunctionTool<any, UserData, any> | undefined {\n    return this._functionToolsMap.get(id);\n  }\n\n  hasTool(id: string): boolean {\n    if (this._functionToolsMap.has(id)) {\n      return true;\n    }\n    return this._providerTools.some((tool) => tool.id === id);\n  }\n\n  updateTools(tools: ToolContextInit<UserData>): void {\n    this._updateTools(tools);\n  }\n\n  private _updateTools(tools: ToolContextInit<UserData>, exclude: readonly Tool[] = []): void {\n    const normalizedTools = normalizeToolContextInit(tools);\n    const excludedTools = new Set<unknown>(exclude);\n    this._tools = normalizedTools;\n    this._functionToolsMap = new Map();\n    this._providerTools = [];\n    this._toolsets = [];\n\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any tool shape\n    const addTool = (tool: any): void => {\n      if (excludedTools.has(tool)) {\n        return;\n      }\n\n      if (isToolset(tool)) {\n        for (const inner of tool.tools) {\n          addTool(inner);\n        }\n        this._toolsets.push(tool);\n        return;\n      }\n\n      if (isProviderTool(tool)) {\n        this._providerTools.push(tool);\n        return;\n      }\n\n      if (isFunctionTool(tool)) {\n        const existing = this._functionToolsMap.get(tool.id);\n        if (existing !== undefined) {\n          if (existing !== tool) {\n            throw new Error(`duplicate function name: ${tool.id}`);\n          }\n          return; // same instance, skip\n        }\n        this._functionToolsMap.set(tool.id, tool);\n        return;\n      }\n\n      throw new Error(`unknown tool type: ${typeof tool}`);\n    };\n\n    for (const tool of normalizedTools) {\n      addTool(tool);\n    }\n  }\n\n  private _syncFlattened(tools: readonly Tool[]): void {\n    const current = this.flatten();\n    const currentTools = new Set(current);\n    const nextTools = new Set(tools);\n    if (currentTools.size === nextTools.size && current.every((tool) => nextTools.has(tool))) {\n      return;\n    }\n\n    const added: Extract<ToolContextEntry<UserData>, Tool>[] = tools\n      .filter((tool) => !currentTools.has(tool))\n      .filter(\n        (tool): tool is Extract<ToolContextEntry<UserData>, Tool> =>\n          isFunctionTool(tool) || isProviderTool(tool),\n      );\n    const removed = current.filter((tool) => !nextTools.has(tool));\n    const structured = this._tools.filter((tool) => !removed.includes(tool as Tool));\n    this._updateTools([...structured, ...added], removed);\n  }\n\n  /** Hide tools from the callable set while keeping their toolsets intact. @internal */\n  _exclude(tools: readonly Tool[]): void {\n    if (tools.length === 0) {\n      return;\n    }\n\n    const excludedTools = new Set(tools);\n    this._syncFlattened(this.flatten().filter((tool) => !excludedTools.has(tool)));\n  }\n\n  /** Return a copy containing only flattened callable/provider entries. @internal */\n  _flattenedCopy(): ToolContext<UserData> {\n    const copy = ToolContext.empty<UserData>();\n    copy._syncFlattened(this.flatten());\n    return copy;\n  }\n\n  copy(): ToolContext<UserData> {\n    return new ToolContext<UserData>([...this._tools]);\n  }\n\n  equals(other: ToolContext): boolean {\n    if (this._functionToolsMap.size !== other._functionToolsMap.size) {\n      return false;\n    }\n\n    for (const [id, tool] of this._functionToolsMap) {\n      if (other._functionToolsMap.get(id) !== tool) {\n        return false;\n      }\n    }\n\n    if (this._providerTools.length !== other._providerTools.length) {\n      return false;\n    }\n\n    // Provider tools compare as identity sets to match Python's `set(id(t) for t in ...)`\n    // semantics — order is not significant.\n    const otherProviderIds = new Set(other._providerTools);\n    for (const tool of this._providerTools) {\n      if (!otherProviderIds.has(tool)) {\n        return false;\n      }\n    }\n\n    if (this._toolsets.length !== other._toolsets.length) {\n      return false;\n    }\n\n    const otherToolsets = new Set(other._toolsets);\n    for (const ts of this._toolsets) {\n      if (!otherToolsets.has(ts)) {\n        return false;\n      }\n    }\n    return true;\n  }\n}\n\nexport function isSameToolChoice(choice1: ToolChoice | null, choice2: ToolChoice | null): boolean {\n  if (choice1 === choice2) {\n    return true;\n  }\n  if (choice1 === null || choice2 === null) {\n    return false;\n  }\n  if (typeof choice1 === 'string' && typeof choice2 === 'string') {\n    return choice1 === choice2;\n  }\n  if (typeof choice1 === 'object' && typeof choice2 === 'object') {\n    return choice1.type === choice2.type && choice1.function.name === choice2.function.name;\n  }\n  return false;\n}\n\n/**\n * Create a function tool. Parameters are inferred from the schema; omit `parameters` for a tool\n * that takes no arguments.\n */\nexport function tool<\n  UserData = UnknownUserData,\n  Schema extends ToolInputSchema<any> | undefined = undefined, // eslint-disable-line @typescript-eslint/no-explicit-any -- Generic constraint needs to accept any JSONObject type\n  Result = unknown,\n>({\n  name,\n  description,\n  parameters,\n  execute,\n  flags,\n  onDuplicate,\n}: {\n  /** Unique name the model calls the tool by. Must be non-empty. */\n  name: string;\n  /** Natural-language description that tells the model when to use this tool. */\n  description: string;\n  /**\n   * Input schema for the tool's arguments — either a Zod object schema (args\n   * are type-inferred) or a raw JSON Schema. Omit for a tool that takes no\n   * arguments.\n   */\n  parameters?: Schema;\n  /**\n   * Called when the model invokes the tool. Receives the parsed arguments (an\n   * empty object when `parameters` is omitted) and a {@link RunContext}\n   * (`ctx`); the returned value is sent back to the model.\n   */\n  execute: ToolExecuteFunction<ToolArgs<Schema>, UserData, Result>;\n  /**\n   * Bitmask of {@link ToolFlag}s, e.g. `ToolFlag.CANCELLABLE` to allow the call\n   * to be cancelled mid-flight. Defaults to `ToolFlag.NONE`.\n   */\n  flags?: number;\n  /**\n   * How a concurrent duplicate call of this tool is handled while one is still\n   * running: `'allow'` | `'reject'` | `'replace'` | `'confirm'`. Defaults to\n   * `'allow'`.\n   */\n  onDuplicate?: DuplicateMode;\n}): FunctionTool<ToolArgs<Schema>, UserData, Result>;\n\n/**\n * Create an anonymous (name-less) function tool. Parameters are inferred from the schema; omit\n * `parameters` for a tool that takes no arguments.\n */\nexport function tool<\n  UserData = UnknownUserData,\n  Schema extends ToolInputSchema<any> | undefined = undefined, // eslint-disable-line @typescript-eslint/no-explicit-any -- Generic constraint needs to accept any JSONObject type\n  Result = unknown,\n>({\n  description,\n  parameters,\n  execute,\n  flags,\n  onDuplicate,\n}: {\n  /** Omitted in object syntax; the containing object key becomes the tool name. */\n  name?: never;\n  /** Natural-language description that tells the model when to use this tool. */\n  description: string;\n  /**\n   * Input schema for the tool's arguments — either a Zod object schema (args\n   * are type-inferred) or a raw JSON Schema. Omit for a tool that takes no\n   * arguments.\n   */\n  parameters?: Schema;\n  /**\n   * Called when the model invokes the tool. Receives the parsed arguments (an\n   * empty object when `parameters` is omitted) and a {@link RunContext}\n   * (`ctx`); the returned value is sent back to the model.\n   */\n  execute: ToolExecuteFunction<ToolArgs<Schema>, UserData, Result>;\n  /**\n   * Bitmask of {@link ToolFlag}s, e.g. `ToolFlag.CANCELLABLE` to allow the call\n   * to be cancelled mid-flight. Defaults to `ToolFlag.NONE`.\n   */\n  flags?: number;\n  /**\n   * How a concurrent duplicate call of this tool is handled while one is still\n   * running: `'allow'` | `'reject'` | `'replace'` | `'confirm'`. Defaults to\n   * `'allow'`.\n   */\n  onDuplicate?: DuplicateMode;\n}): AnonFunctionTool<ToolArgs<Schema>, UserData, Result>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function tool(tool: any): any {\n  if (tool.name !== undefined && (typeof tool.name !== 'string' || tool.name.length === 0)) {\n    throw new Error('tool({ name, ... }) requires a non-empty name');\n  }\n\n  const onDuplicate: DuplicateMode = tool.onDuplicate ?? 'allow';\n\n  // Default parameters to z.object({}) if not provided\n  let parameters = tool.parameters ?? z.object({});\n\n  // if parameters is a Zod schema, ensure it's an object schema\n  if (isZodSchema(parameters) && !isZodObjectSchema(parameters)) {\n    throw new Error('Tool parameters must be a Zod object schema (z.object(...))');\n  }\n\n  // Ensure parameters is either a Zod schema or a plain object (JSON schema)\n  if (!isZodSchema(parameters) && !(typeof parameters === 'object')) {\n    throw new Error('Tool parameters must be a Zod object schema or a raw JSON schema');\n  }\n\n  if (onDuplicate === 'confirm') {\n    parameters = injectConfirmDuplicateParameter(parameters);\n  }\n\n  const execute =\n    onDuplicate === 'confirm' ? wrapConfirmDuplicateExecute(tool.execute) : tool.execute;\n\n  const functionTool = {\n    type: 'function',\n    description: tool.description,\n    parameters,\n    execute,\n    flags: tool.flags ?? ToolFlag.NONE,\n    onDuplicate,\n    [TOOL_SYMBOL]: true,\n    [FUNCTION_TOOL_SYMBOL]: true,\n  };\n\n  if (tool.name === undefined) {\n    return functionTool;\n  }\n\n  return {\n    ...functionTool,\n    id: tool.name,\n    name: tool.name,\n  };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction injectConfirmDuplicateParameter(parameters: any): any {\n  if (isZodSchema(parameters)) {\n    const maybeObjectSchema = parameters as {\n      extend?: (shape: Record<string, unknown>) => unknown;\n    };\n    if (typeof maybeObjectSchema.extend === 'function') {\n      const confirmSchema = isZod4Schema(parameters)\n        ? z4.boolean().nullable().describe(CONFIRM_DUPLICATE_DESCRIPTION)\n        : z.boolean().nullable().describe(CONFIRM_DUPLICATE_DESCRIPTION);\n      return maybeObjectSchema.extend({ [CONFIRM_DUPLICATE_PARAM]: confirmSchema });\n    }\n    throw new Error('Tool parameters must be a Zod object schema (z.object(...))');\n  }\n\n  const properties = {\n    ...(parameters.properties ?? {}),\n    [CONFIRM_DUPLICATE_PARAM]: {\n      type: ['boolean', 'null'],\n      description: CONFIRM_DUPLICATE_DESCRIPTION,\n    },\n  };\n  const required = [...(parameters.required ?? [])];\n  if (!required.includes(CONFIRM_DUPLICATE_PARAM)) {\n    required.push(CONFIRM_DUPLICATE_PARAM);\n  }\n\n  return {\n    ...parameters,\n    properties,\n    required,\n  };\n}\n\nfunction wrapConfirmDuplicateExecute<\n  Parameters extends JSONObject,\n  UserData = UnknownUserData,\n  Result = unknown,\n>(\n  execute: ToolExecuteFunction<Parameters, UserData, Result>,\n): ToolExecuteFunction<Parameters, UserData, Result> {\n  return async (args, opts) => {\n    if (args && typeof args === 'object' && !Array.isArray(args)) {\n      const stripped = { ...args };\n      delete stripped[CONFIRM_DUPLICATE_PARAM];\n      return execute(stripped, opts);\n    }\n    return execute(args, opts);\n  };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isTool(tool: any): tool is Tool {\n  return !!tool && tool[TOOL_SYMBOL] === true;\n}\n\nexport function isFunctionTool(tool: unknown): tool is FunctionTool {\n  const maybeTool = tool as Partial<FunctionTool>;\n  return (\n    isAnonFunctionTool(tool) &&\n    typeof maybeTool.id === 'string' &&\n    typeof maybeTool.name === 'string'\n  );\n}\n\nfunction isAnonFunctionTool(tool: unknown): tool is AnonFunctionTool {\n  const maybeTool = tool as Partial<AnonFunctionTool>;\n  return isTool(tool) && maybeTool[FUNCTION_TOOL_SYMBOL] === true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isProviderTool(tool: any): tool is ProviderTool {\n  return isTool(tool) && (tool as ProviderTool)[PROVIDER_TOOL_SYMBOL] === true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isToolset(value: any): value is Toolset {\n  return !!value && value[TOOLSET_SYMBOL] === true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isToolError(error: any): error is ToolError {\n  return !!error && error[TOOL_ERROR_SYMBOL] === true;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isAgentHandoff(handoff: any): handoff is AgentHandoff {\n  return !!handoff && handoff[HANDOFF_SYMBOL] === true;\n}\n"],"mappings":"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","names":["tool","handoff"]}