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.
class ToolNodeRunnableCallable<T, T>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[] }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 executionThe default configuration for graph execution, can be overridden on a per-invocation basis
A path to the module that contains the class, eg. ["langchain", "llms"] Usually should be the same as the entrypoint the class is exported from.
The name of the task, analogous to the node name in StateGraph.
Default streaming implementation. Subclasses should override this method if they support streaming output.
Execute multiple operations in a single batch. This is more efficient than executing operations individually.
Run the graph with a single input and config.
Create a new runnable sequence that runs each individual runnable in series, piping the output of one runnable into another runnable or runnable-like.
Streams the execution of the graph, emitting state updates as they occur. This is the primary method for observing graph execution in real-time.
Stream modes:
Creates a new instance of the Pregel graph with updated configuration. This method follows the immutable pattern - instead of modifying the current instance, it returns a new instance with the merged configuration.
The name of the serializable. Override to provide an alias or to preserve the serialized module name in minified environments.
Implemented as a static method to support loading logic.
Returns a drawable representation of the computation graph.