{"version":3,"file":"ToolNode.cjs","names":["BaseMessage","ToolInvocationError","ToolMessage","RunnableCallable","mergeAbortSignals","ToolInputParsingException","#handleError","AIMessage","isCommand","Command","Send"],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n/* oxlint-disable no-instanceof/no-instanceof */\nimport { BaseMessage, ToolMessage, AIMessage } from \"@langchain/core/messages\";\nimport { RunnableConfig, RunnableToolLike } from \"@langchain/core/runnables\";\nimport {\n  DynamicTool,\n  StructuredToolInterface,\n  ToolInputParsingException,\n} from \"@langchain/core/tools\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport type { InteropZodObject } from \"@langchain/core/utils/types\";\nimport {\n  isCommand,\n  Command,\n  Send,\n  isGraphInterrupt,\n  type LangGraphRunnableConfig,\n  StateDefinitionInit,\n} from \"@langchain/langgraph\";\n\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport { mergeAbortSignals } from \"./utils.js\";\nimport { ToolInvocationError } from \"../errors.js\";\nimport type {\n  WrapToolCallHook,\n  ToolCallRequest,\n  ToAnnotationRoot,\n} from \"../middleware/types.js\";\nimport type { AgentBuiltInState } from \"../runtime.js\";\n\n/**\n * Error message template for when middleware adds tools that can't be executed.\n * This happens when middleware modifies tools in wrapModelCall but doesn't provide\n * a wrapToolCall handler to execute them.\n */\nconst getInvalidToolError = (\n  toolName: string,\n  availableTools: string[]\n): string =>\n  `Error: ${toolName} is not a valid tool, try one of [${availableTools.join(\", \")}].`;\n\n/**\n * The name of the tool node in the state graph.\n */\nexport const TOOLS_NODE_NAME = \"tools\";\n\nexport interface ToolNodeOptions {\n  /**\n   * The name of the tool node.\n   */\n  name?: string;\n  /**\n   * The tags to add to the tool call.\n   */\n  tags?: string[];\n  /**\n   * The abort signal to cancel the tool call.\n   */\n  signal?: AbortSignal;\n  /**\n   * Whether to throw the error immediately if the tool fails or handle it by the `onToolError` function or via ToolMessage.\n   *\n   * **Default behavior** (matches Python):\n   *   - Catches only `ToolInvocationError` (invalid arguments from model) and converts to ToolMessage\n   *   - Re-raises all other errors including errors from `wrapToolCall` middleware\n   *\n   * If `true`:\n   *   - Catches all errors and returns a ToolMessage with the error\n   *\n   * If `false`:\n   *   - All errors are thrown immediately\n   *\n   * If a function is provided:\n   *   - If function returns a `ToolMessage`, use it as the result\n   *   - If function returns `undefined`, re-raise the error\n   *\n   * @default A function that only catches ToolInvocationError\n   */\n  handleToolErrors?:\n    | boolean\n    | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined);\n  /**\n   * Optional wrapper function for tool execution.\n   * Allows middleware to intercept and modify tool calls before execution.\n   * The wrapper receives the tool call request and a handler function to execute the tool.\n   */\n  wrapToolCall?: WrapToolCallHook;\n}\n\nconst isBaseMessageArray = (input: unknown): input is BaseMessage[] =>\n  Array.isArray(input) && input.every(BaseMessage.isInstance);\n\nconst isMessagesState = (\n  input: unknown\n): input is { messages: BaseMessage[] } =>\n  typeof input === \"object\" &&\n  input != null &&\n  \"messages\" in input &&\n  isBaseMessageArray(input.messages);\n\nconst isSendInput = (\n  input: unknown\n): input is { lg_tool_call: ToolCall; jumpTo?: string } =>\n  typeof input === \"object\" && input != null && \"lg_tool_call\" in input;\n\n/**\n * Default error handler for tool errors.\n *\n * This is applied to errors from baseHandler (tool execution).\n * For errors from wrapToolCall middleware, those are handled separately\n * and will bubble up by default.\n *\n * Catches all tool execution errors and converts them to ToolMessage.\n * This allows the LLM to see the error and potentially retry with different arguments.\n */\nfunction defaultHandleToolErrors(\n  error: unknown,\n  toolCall: ToolCall\n): ToolMessage | undefined {\n  if (error instanceof ToolInvocationError) {\n    return new ToolMessage({\n      content: error.message,\n      tool_call_id: toolCall.id!,\n      name: toolCall.name,\n    });\n  }\n  /**\n   * Catch all other tool errors and convert to ToolMessage\n   */\n  return new ToolMessage({\n    content: `${error}\\n Please fix your mistakes.`,\n    tool_call_id: toolCall.id!,\n    name: toolCall.name,\n  });\n}\n\n/**\n * `ToolNode` is a built-in LangGraph component that handles tool calls within an agent's workflow.\n * It works seamlessly with `createAgent`, offering advanced tool execution control, built\n * in parallelism, and error handling.\n *\n * @example\n * ```ts\n * import { ToolNode, tool, AIMessage } from \"langchain\";\n * import { z } from \"zod/v3\";\n *\n * const getWeather = tool((input) => {\n *   if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n *     return \"It's 60 degrees and foggy.\";\n *   } else {\n *     return \"It's 90 degrees and sunny.\";\n *   }\n * }, {\n *   name: \"get_weather\",\n *   description: \"Call to get the current weather.\",\n *   schema: z.object({\n *     location: z.string().describe(\"Location to get the weather for.\"),\n *   }),\n * });\n *\n * const tools = [getWeather];\n * const toolNode = new ToolNode(tools);\n *\n * const messageWithSingleToolCall = new AIMessage({\n *   content: \"\",\n *   tool_calls: [\n *     {\n *       name: \"get_weather\",\n *       args: { location: \"sf\" },\n *       id: \"tool_call_id\",\n *       type: \"tool_call\",\n *     }\n *   ]\n * })\n *\n * await toolNode.invoke({ messages: [messageWithSingleToolCall] });\n * // Returns tool invocation responses as:\n * // { messages: ToolMessage[] }\n * ```\n */\nexport class ToolNode<\n  StateSchema extends StateDefinitionInit = any,\n  ContextSchema extends InteropZodObject = any,\n> extends RunnableCallable<StateSchema, ContextSchema> {\n  tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[];\n\n  trace = false;\n\n  signal?: AbortSignal;\n\n  handleToolErrors:\n    | boolean\n    | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined) =\n    defaultHandleToolErrors;\n\n  wrapToolCall: WrapToolCallHook | undefined;\n\n  constructor(\n    tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[],\n    public options?: ToolNodeOptions\n  ) {\n    const { name, tags, handleToolErrors, signal, wrapToolCall } =\n      options ?? {};\n    super({\n      name,\n      tags,\n      func: (state, config) =>\n        this.run(\n          state as ToAnnotationRoot<StateDefinitionInit>[\"State\"] &\n            AgentBuiltInState,\n          config as RunnableConfig\n        ),\n    });\n    this.tools = tools;\n    this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n    this.signal = signal;\n    this.wrapToolCall = wrapToolCall;\n  }\n\n  /**\n   * Handle errors from tool execution or middleware.\n   * @param error - The error to handle\n   * @param call - The tool call that caused the error\n   * @param isMiddlewareError - Whether the error came from wrapToolCall middleware\n   * @returns ToolMessage if error is handled, otherwise re-throws\n   */\n  #handleError(\n    error: unknown,\n    call: ToolCall,\n    isMiddlewareError: boolean\n  ): ToolMessage {\n    /**\n     * {@link NodeInterrupt} errors are a breakpoint to bring a human into the loop.\n     * As such, they are not recoverable by the agent and shouldn't be fed\n     * back. Instead, re-throw these errors even when `handleToolErrors = true`.\n     */\n    if (isGraphInterrupt(error)) {\n      throw error;\n    }\n\n    /**\n     * If the signal is aborted, we want to bubble up the error to the invoke caller.\n     */\n    if (this.signal?.aborted) {\n      throw error;\n    }\n\n    /**\n     * If error is from middleware and handleToolErrors is not true, bubble up\n     * (default handler and false both re-raise middleware errors)\n     */\n    if (isMiddlewareError && this.handleToolErrors !== true) {\n      throw error;\n    }\n\n    /**\n     * If handleToolErrors is false, throw all errors\n     */\n    if (!this.handleToolErrors) {\n      throw error;\n    }\n\n    /**\n     * Apply handleToolErrors to the error\n     */\n    if (typeof this.handleToolErrors === \"function\") {\n      const result = this.handleToolErrors(error, call);\n      if (result && ToolMessage.isInstance(result)) {\n        return result;\n      }\n\n      /**\n       * `handleToolErrors` returned undefined - re-raise\n       */\n      throw error;\n    } else if (this.handleToolErrors) {\n      return new ToolMessage({\n        name: call.name,\n        content: `${error}\\n Please fix your mistakes.`,\n        tool_call_id: call.id!,\n      });\n    }\n\n    /**\n     * Shouldn't reach here, but throw as fallback\n     */\n    throw error;\n  }\n\n  protected async runTool(\n    call: ToolCall,\n    config: RunnableConfig,\n    state: AgentBuiltInState\n  ): Promise<ToolMessage | Command> {\n    /**\n     * Build runtime from LangGraph config\n     */\n    const lgConfig = config as LangGraphRunnableConfig;\n    const runtime = {\n      context: lgConfig?.context,\n      store: lgConfig?.store,\n      configurable: lgConfig?.configurable,\n      writer: lgConfig?.writer,\n      interrupt: lgConfig?.interrupt,\n      signal: lgConfig?.signal,\n    };\n\n    /**\n     * Find the tool instance to include in the request.\n     * For dynamically registered tools, this may be undefined.\n     */\n    const registeredTool = this.tools.find((t) => t.name === call.name);\n\n    /**\n     * Define the base handler that executes the tool.\n     * When wrapToolCall middleware is present, this handler does NOT catch errors\n     * so the middleware can handle them.\n     * When no middleware, errors are caught and handled here.\n     *\n     * The handler now accepts an overridden tool from the request, allowing\n     * middleware to provide tool implementations for dynamically registered tools.\n     */\n    const baseHandler = async (\n      request: ToolCallRequest\n    ): Promise<ToolMessage | Command> => {\n      const { toolCall, tool: requestTool } = request;\n\n      /**\n       * Use the tool from the request (which may be overridden via spread syntax)\n       * or fall back to finding it in registered tools.\n       * This allows middleware to provide dynamic tool implementations.\n       */\n      const tool =\n        requestTool ?? this.tools.find((t) => t.name === toolCall.name);\n\n      if (tool === undefined) {\n        /**\n         * Tool not found - return a graceful error message rather than throwing.\n         * This allows the LLM to see the error and potentially retry.\n         */\n        const availableTools = this.tools.map((t) => t.name);\n        return new ToolMessage({\n          content: getInvalidToolError(toolCall.name, availableTools),\n          tool_call_id: toolCall.id!,\n          name: toolCall.name,\n          status: \"error\",\n        });\n      }\n\n      /**\n       * Cast tool to a common invokable type.\n       * The tool can be from registered tools (StructuredToolInterface | DynamicTool | RunnableToolLike)\n       * or from middleware override (ClientTool | ServerTool).\n       */\n      const invokableTool = tool as\n        | StructuredToolInterface\n        | DynamicTool\n        | RunnableToolLike;\n\n      try {\n        const output = await invokableTool.invoke(\n          { ...toolCall, type: \"tool_call\" },\n          {\n            ...config,\n            /**\n             * extend to match ToolRuntime\n             */\n            config,\n            toolCallId: toolCall.id!,\n            state: config.configurable?.__pregel_scratchpad?.currentTaskInput,\n            signal: mergeAbortSignals(this.signal, config.signal),\n          }\n        );\n\n        if (ToolMessage.isInstance(output) || isCommand(output)) {\n          return output as ToolMessage | Command;\n        }\n\n        return new ToolMessage({\n          name: invokableTool.name,\n          content: typeof output === \"string\" ? output : JSON.stringify(output),\n          tool_call_id: toolCall.id!,\n        });\n      } catch (e: unknown) {\n        /**\n         * Handle errors from tool execution (not from wrapToolCall)\n         * If tool invocation fails due to input parsing error, throw a {@link ToolInvocationError}\n         */\n        if (e instanceof ToolInputParsingException) {\n          throw new ToolInvocationError(e, toolCall);\n        }\n        /**\n         * Re-throw to be handled by caller\n         */\n        throw e;\n      }\n    };\n\n    /**\n     * Create request object for middleware\n     * Cast to ToolCallRequest<AgentBuiltInState> to satisfy type constraints\n     * of wrapToolCall which expects AgentBuiltInState\n     */\n    const request: ToolCallRequest<AgentBuiltInState> = {\n      toolCall: call,\n      tool: registeredTool,\n      state,\n      runtime,\n    };\n\n    /**\n     * If wrapToolCall is provided, use it to wrap the tool execution\n     */\n    if (this.wrapToolCall) {\n      try {\n        return await this.wrapToolCall(request, baseHandler);\n      } catch (e: unknown) {\n        /**\n         * Handle middleware errors\n         */\n        return this.#handleError(e, call, true);\n      }\n    }\n\n    /**\n     * No wrapToolCall - if tool wasn't found, return graceful error\n     */\n    if (!registeredTool) {\n      const availableTools = this.tools.map((t) => t.name);\n      return new ToolMessage({\n        content: getInvalidToolError(call.name, availableTools),\n        tool_call_id: call.id!,\n        name: call.name,\n        status: \"error\",\n      });\n    }\n\n    /**\n     * No wrapToolCall - execute tool directly and handle errors here\n     */\n    try {\n      return await baseHandler(request);\n    } catch (e: unknown) {\n      /**\n       * Handle tool errors when no middleware provided\n       */\n      return this.#handleError(e, call, false);\n    }\n  }\n\n  protected async run(\n    state: ToAnnotationRoot<StateSchema>[\"State\"] & AgentBuiltInState,\n    config: RunnableConfig\n  ): Promise<ContextSchema> {\n    let outputs: (ToolMessage | Command)[];\n\n    if (isSendInput(state)) {\n      const { lg_tool_call: _, jumpTo: __, ...newState } = state;\n      outputs = [await this.runTool(state.lg_tool_call, config, newState)];\n    } else {\n      let messages: BaseMessage[];\n      if (isBaseMessageArray(state)) {\n        messages = state;\n      } else if (isMessagesState(state)) {\n        messages = state.messages;\n      } else {\n        throw new Error(\n          \"ToolNode only accepts BaseMessage[] or { messages: BaseMessage[] } as input.\"\n        );\n      }\n\n      const toolMessageIds: Set<string> = new Set(\n        messages\n          .filter((msg) => msg.getType() === \"tool\")\n          .map((msg) => (msg as ToolMessage).tool_call_id)\n      );\n\n      let aiMessage: AIMessage | undefined;\n      for (let i = messages.length - 1; i >= 0; i -= 1) {\n        const message = messages[i];\n        if (AIMessage.isInstance(message)) {\n          aiMessage = message;\n          break;\n        }\n      }\n\n      if (!AIMessage.isInstance(aiMessage)) {\n        throw new Error(\"ToolNode only accepts AIMessages as input.\");\n      }\n\n      outputs = await Promise.all(\n        aiMessage.tool_calls\n          ?.filter((call) => call.id == null || !toolMessageIds.has(call.id))\n          .map((call) => this.runTool(call, config, state)) ?? []\n      );\n    }\n\n    // Preserve existing behavior for non-command tool outputs for backwards compatibility\n    if (!outputs.some(isCommand)) {\n      return (Array.isArray(state)\n        ? outputs\n        : { messages: outputs }) as unknown as ContextSchema;\n    }\n\n    // Handle mixed Command and non-Command outputs\n    const combinedOutputs: (\n      | { messages: BaseMessage[] }\n      | BaseMessage[]\n      | Command\n    )[] = [];\n    let parentCommand: Command | null = null;\n\n    for (const output of outputs) {\n      if (isCommand(output)) {\n        if (\n          output.graph === Command.PARENT &&\n          Array.isArray(output.goto) &&\n          output.goto.every((send) => isSend(send))\n        ) {\n          if (parentCommand) {\n            (parentCommand.goto as Send[]).push(...(output.goto as Send[]));\n          } else {\n            parentCommand = new Command({\n              graph: Command.PARENT,\n              goto: output.goto,\n            });\n          }\n        } else {\n          combinedOutputs.push(output);\n        }\n      } else {\n        combinedOutputs.push(\n          Array.isArray(state) ? [output] : { messages: [output] }\n        );\n      }\n    }\n\n    if (parentCommand) {\n      combinedOutputs.push(parentCommand);\n    }\n\n    return combinedOutputs as unknown as ContextSchema;\n  }\n}\n\nexport function isSend(x: unknown): x is Send {\n  return x instanceof Send;\n}\n"],"mappings":"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"}