UNPKG

langchain

Version:
1 lines • 24.3 kB
{"version":3,"file":"ToolNode.cjs","names":["BaseMessage","ToolInvocationError","ToolMessage","RunnableCallable","isGraphInterrupt","isGraphDrained","MiddlewareError","mergeAbortSignals","isCommand","ToolInputParsingException","AIMessage","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 isGraphDrained,\n isGraphInterrupt,\n type LangGraphRunnableConfig,\n StateDefinitionInit,\n} from \"@langchain/langgraph\";\n\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport { mergeAbortSignals } from \"./utils.js\";\nimport { MiddlewareError, 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 /** Graph channels to read for tool-call-only Send inputs. */\n stateKeys?: string[];\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 (ToolInvocationError.isInstance(error)) {\n return new ToolMessage({\n content: error.message,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\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 status: \"error\",\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 * and a drain stops the run to resume it later. Neither is recoverable\n * by the agent, so neither is fed back: re-throw them even when\n * `handleToolErrors = true`.\n */\n if (isGraphInterrupt(error) || isGraphDrained(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 * A recoverable tool error (e.g. tool-input schema validation) can be\n * rewrapped as a {@link MiddlewareError} with the original error on `.cause`\n * — once per `wrapToolCall` middleware, so it may be nested several layers\n * deep. Walk the cause chain to the root; if it's a {@link ToolInvocationError},\n * unwrap it so the intended `handleToolErrors` self-correction path still\n * applies. Genuine middleware errors stay fatal by default.\n */\n let effectiveError = error;\n let errorFromMiddleware = isMiddlewareError;\n if (isMiddlewareError) {\n let unwrapped: unknown = error;\n while (MiddlewareError.isInstance(unwrapped)) {\n unwrapped = unwrapped.cause;\n }\n if (ToolInvocationError.isInstance(unwrapped)) {\n effectiveError = unwrapped;\n errorFromMiddleware = false;\n }\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 (errorFromMiddleware && this.handleToolErrors !== true) {\n throw effectiveError;\n }\n\n /**\n * If handleToolErrors is false, throw all errors\n */\n if (!this.handleToolErrors) {\n throw effectiveError;\n }\n\n /**\n * Apply handleToolErrors to the error\n */\n if (typeof this.handleToolErrors === \"function\") {\n const result = this.handleToolErrors(effectiveError, call);\n if (result && ToolMessage.isInstance(result)) {\n result.status ??= \"error\";\n return result;\n }\n\n /**\n * `handleToolErrors` returned undefined - re-raise\n */\n throw effectiveError;\n } else if (this.handleToolErrors) {\n return new ToolMessage({\n name: call.name,\n content: `${effectiveError}\\n Please fix your mistakes.`,\n tool_call_id: call.id!,\n status: \"error\",\n });\n }\n\n /**\n * Shouldn't reach here, but throw as fallback\n */\n throw effectiveError;\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,\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 let toolState = newState;\n if (Object.keys(newState).length === 0 && this.options?.stateKeys) {\n const read = config.configurable?.__pregel_read;\n if (typeof read !== \"function\") {\n throw new Error(\n \"ToolNode requires a graph state reader for compact Send inputs.\"\n );\n }\n toolState = read(this.options.stateKeys, true);\n if (!isMessagesState(toolState)) {\n throw new Error(\"ToolNode could not read messages from graph state.\");\n }\n const scratchpad = config.configurable?.__pregel_scratchpad;\n if (scratchpad) {\n scratchpad.currentTaskInput = { ...toolState, ...state };\n }\n }\n outputs = [await this.runTool(state.lg_tool_call, config, toolState)];\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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"}