import { Command, END } from "../constants.js"; import { RunnableCallable } from "../utils.js"; import { MessagesAnnotation } from "../graph/messages_annotation.js"; import { RunnableConfig, RunnableToolLike } from "@langchain/core/runnables"; import { BaseMessage, ToolMessage } from "@langchain/core/messages"; import { DynamicTool, StructuredToolInterface } from "@langchain/core/tools"; import { ToolCall } from "@langchain/core/messages/tool"; //#region src/prebuilt/tool_node.d.ts type ToolNodeOptions = { name?: string; tags?: string[]; handleToolErrors?: boolean; }; /** * A node that runs the tools requested in the last AIMessage. It can be used * either in StateGraph with a "messages" key or in MessageGraph. If multiple * tool calls are requested, they will be run in parallel. The output will be * a list of ToolMessages, one for each tool call. * * @example * ```ts * import { ToolNode } from "@langchain/langgraph/prebuilt"; * import { tool } from "@langchain/core/tools"; * import { z } from "zod"; * import { AIMessage } from "@langchain/core/messages"; * * const getWeather = tool((input) => { * if (["sf", "san francisco"].includes(input.location.toLowerCase())) { * return "It's 60 degrees and foggy."; * } else { * return "It's 90 degrees and sunny."; * } * }, { * name: "get_weather", * description: "Call to get the current weather.", * schema: z.object({ * location: z.string().describe("Location to get the weather for."), * }), * }); * * const tools = [getWeather]; * const toolNode = new ToolNode(tools); * * const messageWithSingleToolCall = new AIMessage({ * content: "", * tool_calls: [ * { * name: "get_weather", * args: { location: "sf" }, * id: "tool_call_id", * type: "tool_call", * } * ] * }) * * await toolNode.invoke({ messages: [messageWithSingleToolCall] }); * // Returns tool invocation responses as: * // { messages: ToolMessage[] } * ``` * * @example * ```ts * import { * StateGraph, * MessagesAnnotation, * } from "@langchain/langgraph"; * import { ToolNode } from "@langchain/langgraph/prebuilt"; * import { tool } from "@langchain/core/tools"; * import { z } from "zod"; * import { ChatAnthropic } from "@langchain/anthropic"; * * const getWeather = tool((input) => { * if (["sf", "san francisco"].includes(input.location.toLowerCase())) { * return "It's 60 degrees and foggy."; * } else { * return "It's 90 degrees and sunny."; * } * }, { * name: "get_weather", * description: "Call to get the current weather.", * schema: z.object({ * location: z.string().describe("Location to get the weather for."), * }), * }); * * const tools = [getWeather]; * const modelWithTools = new ChatAnthropic({ * model: "claude-3-haiku-20240307", * temperature: 0 * }).bindTools(tools); * * const toolNodeForGraph = new ToolNode(tools) * * const shouldContinue = (state: typeof MessagesAnnotation.State) => { * const { messages } = state; * const lastMessage = messages[messages.length - 1]; * if ("tool_calls" in lastMessage && Array.isArray(lastMessage.tool_calls) && lastMessage.tool_calls?.length) { * return "tools"; * } * return "__end__"; * } * * const callModel = async (state: typeof MessagesAnnotation.State) => { * const { messages } = state; * const response = await modelWithTools.invoke(messages); * return { messages: response }; * } * * const graph = new StateGraph(MessagesAnnotation) * .addNode("agent", callModel) * .addNode("tools", toolNodeForGraph) * .addEdge("__start__", "agent") * .addConditionalEdges("agent", shouldContinue) * .addEdge("tools", "agent") * .compile(); * * const inputs = { * messages: [{ role: "user", content: "what is the weather in SF?" }], * }; * * const stream = await graph.stream(inputs, { * streamMode: "values", * }); * * for await (const { messages } of stream) { * console.log(messages); * } * // Returns the messages in the state at each step of execution * ``` */ declare class ToolNode extends RunnableCallable { tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[]; handleToolErrors: boolean; trace: boolean; constructor(tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[], options?: ToolNodeOptions); protected runTool(call: ToolCall, config: RunnableConfig): Promise; protected run(input: unknown, config: RunnableConfig): Promise; } /** * A conditional edge function that determines whether to route to a tools node or end the graph. * * This function is designed to be used as a conditional edge in a LangGraph state graph to implement * the common pattern of checking if an AI message contains tool calls that need to be executed. * * @param state - The current state of the graph, which can be either: * - An array of `BaseMessage` objects, where the last message is checked for tool calls * - A state object conforming to `MessagesAnnotation.State`, which contains a `messages` array * * @returns A string indicating the next node to route to: * - `"tools"` - If the last message contains tool calls that need to be executed * - `END` - If there are no tool calls, indicating the graph should terminate * * @example * ```typescript * import { StateGraph, MessagesAnnotation, END, START } from "@langchain/langgraph"; * import { ToolNode, toolsCondition } from "@langchain/langgraph/prebuilt"; * * const graph = new StateGraph(MessagesAnnotation) * .addNode("agent", agentNode) * .addNode("tools", new ToolNode([searchTool, calculatorTool])) * .addEdge(START, "agent") * .addConditionalEdges("agent", toolsCondition, ["tools", END]) * .addEdge("tools", "agent") * .compile(); * ``` * * @remarks * The function checks the last message in the state for the presence of `tool_calls`. * If the message is an `AIMessage` with one or more tool calls, it returns `"tools"`, * indicating that the graph should route to a tools node (typically a `ToolNode`) to * execute those tool calls. Otherwise, it returns `END` to terminate the graph execution. * * This is a common pattern in agentic workflows where an AI model decides whether to * use tools or provide a final response. */ declare function toolsCondition(state: BaseMessage[] | typeof MessagesAnnotation.State): "tools" | typeof END; //#endregion export { ToolNode, ToolNodeOptions, toolsCondition }; //# sourceMappingURL=tool_node.d.ts.map