langchain.js
    Preparing search index...

    ToolNode has been moved to langchain package. Update your import to import { ToolNode } from "langchain";

    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.

    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 execution

    Type Parameters

    • T = any

    Hierarchy

    • RunnableCallable<T, T>
      • ToolNode
    Index

    Constructors

    • Type Parameters

      • T = any

      Parameters

      • tools: (
            | StructuredToolInterface<ToolInputSchemaBase, any, any>
            | RunnableToolLike<InteropZodType, unknown>
            | DynamicTool<any>
        )[]
      • Optionaloptions: ToolNodeOptions

      Returns ToolNode<T>

    Properties

    config?: RunnableConfig<Record<string, any>>
    func: (...args: any[]) => any
    handleToolErrors: boolean = true
    lc_namespace: string[] = ...

    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.

    recurse: boolean = true
    tags?: string[]
    tools: (
        | StructuredToolInterface<ToolInputSchemaBase, any, any>
        | RunnableToolLike<InteropZodType, unknown>
        | DynamicTool<any>
    )[]
    trace: boolean = false

    Methods

    • Parameters

      • input: T
      • Optionalconfig: Partial<RunnableConfig<Record<string, any>>>
      • OptionalrunManager: CallbackManagerForChainRun

      Returns Promise<T>

    • Parameters

      • input: T
      • Optionaloptions: Partial<RunnableConfig<Record<string, any>>>

      Returns Promise<T>

    • Parameters

      • input: unknown
      • config: RunnableConfig

      Returns Promise<T>

    • Parameters

      • call: ToolCall
      • config: RunnableConfig

      Returns Promise<
          | Command<unknown, Record<string, unknown>, string>
          | ToolMessage<MessageStructure>,
      >