langchain 1.2.33 → 1.2.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # langchain
2
2
 
3
+ ## 1.2.35
4
+
5
+ ### Patch Changes
6
+
7
+ - [#10466](https://github.com/langchain-ai/langchainjs/pull/10466) [`4b1a874`](https://github.com/langchain-ai/langchainjs/commit/4b1a874a93d8475a98421e157fe7a1e65ec94076) Thanks [@hntrl](https://github.com/hntrl)! - fix: renamed getSubgraphAsync -> getSubgraphsAsync
8
+
9
+ - Updated dependencies [[`bfb7944`](https://github.com/langchain-ai/langchainjs/commit/bfb7944a105470eee98fe4a0eef91e586600e1de)]:
10
+ - @langchain/core@1.1.34
11
+
12
+ ## 1.2.34
13
+
14
+ ### Patch Changes
15
+
16
+ - [#10443](https://github.com/langchain-ai/langchainjs/pull/10443) [`ff6822e`](https://github.com/langchain-ai/langchainjs/commit/ff6822e43c38c4328d3f2c0ef1cf67998741339a) Thanks [@christian-bromann](https://github.com/christian-bromann)! - fix(langchain): respect version:"v1" in afterModel router's pending tool call path
17
+
18
+ - [#10446](https://github.com/langchain-ai/langchainjs/pull/10446) [`888224c`](https://github.com/langchain-ai/langchainjs/commit/888224c64e4c95935836a5089f8b28a8c90da5e6) Thanks [@hntrl](https://github.com/hntrl)! - fix(agents): propagate store and configurable to ToolNode middleware runtime
19
+
20
+ - [#10444](https://github.com/langchain-ai/langchainjs/pull/10444) [`82d56cb`](https://github.com/langchain-ai/langchainjs/commit/82d56cbdfb59b48b3f8d98a294e4d4720e12c733) Thanks [@christian-bromann](https://github.com/christian-bromann)! - fix(langchain/agents): dispatch tool calls via Send in afterModel router for version:"v2"
21
+
22
+ **Breaking change for `version: "v2"` + `afterModel` middleware users.**
23
+
24
+ Previously, when `afterModel` middleware was present, `createAgent` always routed all tool calls from an `AIMessage` to a single `ToolNode` invocation — regardless of the `version` option. This meant `version: "v2"` silently behaved like `version: "v1"` (parallel via `Promise.all` in one node) whenever `afterModel` middleware was used.
25
+
26
+ `#createAfterModelRouter` now correctly respects `#toolBehaviorVersion`:
27
+ - `version: "v1"` — routes the full `AIMessage` to a single `ToolNode` invocation; all tool calls run concurrently via `Promise.all` (unchanged behaviour).
28
+ - `version: "v2"` — dispatches each tool call as a separate `Send` task, matching the behaviour of `#createModelRouter` when no `afterModel` middleware is present, and matching Python LangGraph's `post_model_hook_router`.
29
+
30
+ **Migration:** If you use `version: "v2"` (the default) together with `afterModel` middleware and rely on the previous single-node parallel execution, switch to `version: "v1"` to preserve that behaviour. See the `version` JSDoc on `CreateAgentParams` for guidance on which option to choose.
31
+
3
32
  ## 1.2.33
4
33
 
5
34
  ### Patch Changes
@@ -413,10 +413,18 @@ var ReactAgent = class ReactAgent {
413
413
  const toolMessages = messages.filter(_langchain_core_messages.ToolMessage.isInstance);
414
414
  const lastAiMessage = messages.filter(_langchain_core_messages.AIMessage.isInstance).at(-1);
415
415
  const pendingToolCalls = lastAiMessage?.tool_calls?.filter((call) => !toolMessages.some((m) => m.tool_call_id === call.id));
416
- if (pendingToolCalls && pendingToolCalls.length > 0) return pendingToolCalls.map((toolCall) => new _langchain_langgraph.Send(require_ToolNode.TOOLS_NODE_NAME, {
417
- ...state,
418
- lg_tool_call: toolCall
419
- }));
416
+ if (pendingToolCalls && pendingToolCalls.length > 0) {
417
+ /**
418
+ * v1: route the full message to the ToolNode; it filters already-processed
419
+ * calls internally and runs the remaining ones via Promise.all.
420
+ * v2: dispatch each pending call as a separate Send task.
421
+ */
422
+ if (this.#toolBehaviorVersion === "v1") return require_ToolNode.TOOLS_NODE_NAME;
423
+ return pendingToolCalls.map((toolCall) => new _langchain_langgraph.Send(require_ToolNode.TOOLS_NODE_NAME, {
424
+ ...state,
425
+ lg_tool_call: toolCall
426
+ }));
427
+ }
420
428
  const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some((toolCall) => toolCall.name.startsWith("extract-"));
421
429
  if (pendingToolCalls && pendingToolCalls.length === 0 && !hasStructuredResponseCalls && hasStructuredResponse) return require_AgentNode.AGENT_NODE_NAME;
422
430
  if (!_langchain_core_messages.AIMessage.isInstance(lastMessage) || !lastMessage.tool_calls || lastMessage.tool_calls.length === 0) return exitNode;
@@ -424,10 +432,20 @@ var ReactAgent = class ReactAgent {
424
432
  const hasRegularToolCalls = lastMessage.tool_calls.some((toolCall) => !toolCall.name.startsWith("extract-"));
425
433
  if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) return exitNode;
426
434
  /**
427
- * For routing from afterModel nodes, always use simple string paths
428
- * The Send API is handled at the model_request node level
435
+ * v1: route the full AIMessage to a single ToolNode invocation so all
436
+ * tool calls run concurrently via Promise.all.
437
+ *
438
+ * v2: dispatch each regular tool call as a separate Send task, matching
439
+ * the behaviour of #createModelRouter when no afterModel middleware is
440
+ * present.
429
441
  */
430
- return require_ToolNode.TOOLS_NODE_NAME;
442
+ if (this.#toolBehaviorVersion === "v1") return require_ToolNode.TOOLS_NODE_NAME;
443
+ const regularToolCalls = lastMessage.tool_calls.filter((toolCall) => !toolCall.name.startsWith("extract-"));
444
+ if (regularToolCalls.length === 0) return exitNode;
445
+ return regularToolCalls.map((toolCall) => new _langchain_langgraph.Send(require_ToolNode.TOOLS_NODE_NAME, {
446
+ ...state,
447
+ lg_tool_call: toolCall
448
+ }));
431
449
  };
432
450
  }
433
451
  /**
@@ -697,7 +715,7 @@ var ReactAgent = class ReactAgent {
697
715
  /**
698
716
  * @internal
699
717
  */
700
- getSubgraphAsync(namespace, recurse) {
718
+ getSubgraphsAsync(namespace, recurse) {
701
719
  return this.#graph.getSubgraphsAsync(namespace, recurse);
702
720
  }
703
721
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.cjs","names":["StateManager","#defaultConfig","#toolBehaviorVersion","isClientTool","createAgentState","StateGraph","#agentNode","AgentNode","normalizeSystemPrompt","BeforeAgentNode","#stateManager","getHookConstraint","BeforeModelNode","AfterModelNode","AfterAgentNode","AGENT_NODE_NAME","ToolNode","wrapToolCall","TOOLS_NODE_NAME","END","START","parseJumpToTarget","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","ToolMessage","AIMessage","Send","#initializeMiddlewareStates","Command","initializeMiddlewareStates"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type {\n BaseCheckpointSaver,\n BaseStore,\n CheckpointListOptions,\n} from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaValue,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaValue<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = defaultConfig ?? {};\n if (options.name) {\n this.#defaultConfig = mergeConfigs(this.#defaultConfig, {\n metadata: { lc_agent_name: options.name },\n });\n }\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(\n shouldReturnDirect,\n exitNode,\n toolReturnTarget\n ),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n get checkpointer(): BaseCheckpointSaver | boolean | undefined {\n return this.#graph.checkpointer;\n }\n\n set checkpointer(value: BaseCheckpointSaver | boolean | undefined) {\n this.#graph.checkpointer = value;\n }\n\n get store(): BaseStore | undefined {\n return this.#graph.store;\n }\n\n set store(value: BaseStore | undefined) {\n this.#graph.store = value;\n }\n\n /**\n * Creates a new ReactAgent with the given config merged into the existing config.\n * Follows the same pattern as LangGraph's Pregel.withConfig().\n *\n * The merged config is applied as a default that gets merged with any config\n * passed at invocation time (invoke/stream). Invocation-time config takes precedence.\n *\n * @param config - Configuration to merge with existing config\n * @returns A new ReactAgent instance with the merged configuration\n *\n * @example\n * ```typescript\n * const agent = createAgent({ model: \"gpt-4o\", tools: [...] });\n *\n * // Set a default recursion limit\n * const configuredAgent = agent.withConfig({ recursionLimit: 1000 });\n *\n * // Chain multiple configs\n * const debugAgent = agent\n * .withConfig({ recursionLimit: 1000 })\n * .withConfig({ tags: [\"debug\"] });\n * ```\n */\n withConfig(\n config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">\n ): ReactAgent<Types> {\n return new ReactAgent(\n this.options,\n mergeConfigs(this.#defaultConfig, config)\n );\n }\n\n /**\n * Get possible edge destinations from model node.\n * @param toolClasses names of tools to call\n * @param includeModelRequest whether to include \"model_request\" as a valid path (for jumpTo routing)\n * @param hasToolsAvailable whether tools are available (includes dynamic tools via middleware)\n * @returns list of possible edge destinations\n */\n #getModelPaths(\n toolClasses: (ClientTool | ServerTool)[],\n includeModelRequest: boolean = false,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ): BaseGraphDestination[] {\n const paths: BaseGraphDestination[] = [];\n if (hasToolsAvailable) {\n paths.push(TOOLS_NODE_NAME);\n }\n\n if (includeModelRequest) {\n paths.push(AGENT_NODE_NAME);\n }\n\n paths.push(END);\n\n return paths;\n }\n\n /**\n * Create routing function for tools node conditional edges.\n */\n #createToolsRouter(\n shouldReturnDirect: Set<string>,\n exitNode: string | typeof END,\n toolReturnTarget: string\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages[messages.length - 1];\n\n // Check if we just executed a returnDirect tool\n if (\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n shouldReturnDirect.has(lastMessage.name)\n ) {\n // If we have a response format, route to agent to generate structured response\n // Otherwise, return directly to exit node (could be after_agent or END)\n return this.options.responseFormat ? toolReturnTarget : exitNode;\n }\n\n // For non-returnDirect tools, route back to loop entry node (could be middleware or agent)\n return toolReturnTarget;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * For routing from afterModel nodes, always use simple string paths\n * The Send API is handled at the model_request node level\n */\n return TOOLS_NODE_NAME;\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n TSubgraphs extends boolean,\n TEncoding extends \"text/event-stream\" | undefined,\n >(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TSubgraphs,\n TEncoding\n >\n ) {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n return this.#graph.stream(\n initializedState,\n mergedConfig as Record<string, any>\n ) as Promise<\n IterableReadableStream<\n StreamOutputMap<\n TStreamMode,\n TSubgraphs,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReactAgent.cjs","names":["StateManager","#defaultConfig","#toolBehaviorVersion","isClientTool","createAgentState","StateGraph","#agentNode","AgentNode","normalizeSystemPrompt","BeforeAgentNode","#stateManager","getHookConstraint","BeforeModelNode","AfterModelNode","AfterAgentNode","AGENT_NODE_NAME","ToolNode","wrapToolCall","TOOLS_NODE_NAME","END","START","parseJumpToTarget","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","ToolMessage","AIMessage","Send","#initializeMiddlewareStates","Command","initializeMiddlewareStates"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type {\n BaseCheckpointSaver,\n BaseStore,\n CheckpointListOptions,\n} from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaValue,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaValue<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = defaultConfig ?? {};\n if (options.name) {\n this.#defaultConfig = mergeConfigs(this.#defaultConfig, {\n metadata: { lc_agent_name: options.name },\n });\n }\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(\n shouldReturnDirect,\n exitNode,\n toolReturnTarget\n ),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n get checkpointer(): BaseCheckpointSaver | boolean | undefined {\n return this.#graph.checkpointer;\n }\n\n set checkpointer(value: BaseCheckpointSaver | boolean | undefined) {\n this.#graph.checkpointer = value;\n }\n\n get store(): BaseStore | undefined {\n return this.#graph.store;\n }\n\n set store(value: BaseStore | undefined) {\n this.#graph.store = value;\n }\n\n /**\n * Creates a new ReactAgent with the given config merged into the existing config.\n * Follows the same pattern as LangGraph's Pregel.withConfig().\n *\n * The merged config is applied as a default that gets merged with any config\n * passed at invocation time (invoke/stream). Invocation-time config takes precedence.\n *\n * @param config - Configuration to merge with existing config\n * @returns A new ReactAgent instance with the merged configuration\n *\n * @example\n * ```typescript\n * const agent = createAgent({ model: \"gpt-4o\", tools: [...] });\n *\n * // Set a default recursion limit\n * const configuredAgent = agent.withConfig({ recursionLimit: 1000 });\n *\n * // Chain multiple configs\n * const debugAgent = agent\n * .withConfig({ recursionLimit: 1000 })\n * .withConfig({ tags: [\"debug\"] });\n * ```\n */\n withConfig(\n config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">\n ): ReactAgent<Types> {\n return new ReactAgent(\n this.options,\n mergeConfigs(this.#defaultConfig, config)\n );\n }\n\n /**\n * Get possible edge destinations from model node.\n * @param toolClasses names of tools to call\n * @param includeModelRequest whether to include \"model_request\" as a valid path (for jumpTo routing)\n * @param hasToolsAvailable whether tools are available (includes dynamic tools via middleware)\n * @returns list of possible edge destinations\n */\n #getModelPaths(\n toolClasses: (ClientTool | ServerTool)[],\n includeModelRequest: boolean = false,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ): BaseGraphDestination[] {\n const paths: BaseGraphDestination[] = [];\n if (hasToolsAvailable) {\n paths.push(TOOLS_NODE_NAME);\n }\n\n if (includeModelRequest) {\n paths.push(AGENT_NODE_NAME);\n }\n\n paths.push(END);\n\n return paths;\n }\n\n /**\n * Create routing function for tools node conditional edges.\n */\n #createToolsRouter(\n shouldReturnDirect: Set<string>,\n exitNode: string | typeof END,\n toolReturnTarget: string\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages[messages.length - 1];\n\n // Check if we just executed a returnDirect tool\n if (\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n shouldReturnDirect.has(lastMessage.name)\n ) {\n // If we have a response format, route to agent to generate structured response\n // Otherwise, return directly to exit node (could be after_agent or END)\n return this.options.responseFormat ? toolReturnTarget : exitNode;\n }\n\n // For non-returnDirect tools, route back to loop entry node (could be middleware or agent)\n return toolReturnTarget;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n /**\n * v1: route the full message to the ToolNode; it filters already-processed\n * calls internally and runs the remaining ones via Promise.all.\n * v2: dispatch each pending call as a separate Send task.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * v1: route the full AIMessage to a single ToolNode invocation so all\n * tool calls run concurrently via Promise.all.\n *\n * v2: dispatch each regular tool call as a separate Send task, matching\n * the behaviour of #createModelRouter when no afterModel middleware is\n * present.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n const regularToolCalls = (lastMessage as AIMessage).tool_calls!.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n TSubgraphs extends boolean,\n TEncoding extends \"text/event-stream\" | undefined,\n >(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TSubgraphs,\n TEncoding\n >\n ) {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n return this.#graph.stream(\n initializedState,\n mergedConfig as Record<string, any>\n ) as Promise<\n IterableReadableStream<\n StreamOutputMap<\n TStreamMode,\n TSubgraphs,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphsAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2JA,IAAa,aAAb,MAAa,WAQX;CAQA;CAEA,uBAAoC;CAEpC;CAEA,gBAAgB,IAAIA,cAAAA,cAAc;CAElC;CAEA,YACE,SAKA,eACA;AANO,OAAA,UAAA;AAOP,QAAA,gBAAsB,iBAAiB,EAAE;AACzC,MAAI,QAAQ,KACV,OAAA,iBAAKC,GAAAA,0BAAAA,cAA8B,MAAA,eAAqB,EACtD,UAAU,EAAE,eAAe,QAAQ,MAAM,EAC1C,CAAC;AAEJ,QAAA,sBAA4B,QAAQ,WAAW,MAAA;;;;AAK/C,MAAI,CAAC,QAAQ,MACX,OAAM,IAAI,MAAM,iDAAiD;;;;AAMnE,MAAI,OAAO,QAAQ,UAAU,SAC3B,eAAA,2BAA2B,QAAQ,MAAM;;;;EAM3C,MAAM,kBAAmB,KAAK,QAAQ,YAClC,QAAQ,MAAM,EAAE,MAAM,CACvB,SAAS,MAAM,EAAE,MAAM,IAAI,EAAE;EAChC,MAAM,cAAc,CAAC,GAAI,QAAQ,SAAS,EAAE,EAAG,GAAG,gBAAgB;;;;;EAMlE,MAAM,qBAAqB,IAAI,IAC7B,YACG,OAAOE,cAAAA,aAAa,CACpB,QAAQ,SAAS,kBAAkB,QAAQ,KAAK,aAAa,CAC7D,KAAK,SAAS,KAAK,KAAK,CAC5B;;;;;EAMD,MAAM,EAAE,OAAO,OAAO,WAAWC,mBAAAA,iBAI/B,KAAK,QAAQ,mBAAmB,KAAA,GAChC,KAAK,QAAQ,aACb,KAAK,QAAQ,WACd;EAQD,MAAM,mBANW,IAAIC,qBAAAA,WAAW,OAAO;GACrC;GACA;GACA,SAAS,KAAK,QAAQ;GACvB,CAAC;EAQF,MAAM,mBAIA,EAAE;EACR,MAAM,mBAIA,EAAE;EACR,MAAM,kBAIA,EAAE;EACR,MAAM,kBAIA,EAAE;EACR,MAAM,8BAMA,EAAE;AAER,QAAA,YAAkB,IAAIE,kBAAAA,UAAU;GAC9B,OAAO,KAAK,QAAQ;GACpB,eAAeC,cAAAA,sBAAsB,KAAK,QAAQ,aAAa;GAC/D,kBAAkB,KAAK,QAAQ;GAC/B,MAAM,KAAK,QAAQ;GACnB,gBAAgB,KAAK,QAAQ;GAC7B,YAAY,KAAK,QAAQ;GACzB;GACA;GACA,QAAQ,KAAK,QAAQ;GACrB;GACD,CAAC;EAEF,MAAM,kCAAkB,IAAI,KAAa;EACzC,MAAM,aAAa,KAAK,QAAQ,cAAc,EAAE;AAChD,OAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;GAC1C,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM,IAAI,WAAW;AACrB,OAAI,gBAAgB,IAAI,EAAE,KAAK,CAC7B,OAAM,IAAI,MAAM,cAAc,EAAE,KAAK,4BAA4B;AAGnE,mBAAgB,IAAI,EAAE,KAAK;AAC3B,OAAI,EAAE,aAAa;AACjB,sBAAkB,IAAIC,wBAAAA,gBAAgB,GAAG,EACvC,gBAAgB,MAAA,aAAmB,SAAS,EAAE,KAAK,EACpD,CAAC;AACF,UAAA,aAAmB,QAAQ,GAAG,gBAAgB;IAC9C,MAAM,OAAO,GAAG,EAAE,KAAK;AACvB,qBAAiB,KAAK;KACpB,OAAO;KACP;KACA,SAASE,gBAAAA,kBAAkB,EAAE,YAAY;KAC1C,CAAC;AACF,qBAAiB,QACf,MACA,iBACA,gBAAgB,YACjB;;AAEH,OAAI,EAAE,aAAa;AACjB,sBAAkB,IAAIC,wBAAAA,gBAAgB,GAAG,EACvC,gBAAgB,MAAA,aAAmB,SAAS,EAAE,KAAK,EACpD,CAAC;AACF,UAAA,aAAmB,QAAQ,GAAG,gBAAgB;IAC9C,MAAM,OAAO,GAAG,EAAE,KAAK;AACvB,qBAAiB,KAAK;KACpB,OAAO;KACP;KACA,SAASD,gBAAAA,kBAAkB,EAAE,YAAY;KAC1C,CAAC;AACF,qBAAiB,QACf,MACA,iBACA,gBAAgB,YACjB;;AAEH,OAAI,EAAE,YAAY;AAChB,qBAAiB,IAAIE,uBAAAA,eAAe,GAAG,EACrC,gBAAgB,MAAA,aAAmB,SAAS,EAAE,KAAK,EACpD,CAAC;AACF,UAAA,aAAmB,QAAQ,GAAG,eAAe;IAC7C,MAAM,OAAO,GAAG,EAAE,KAAK;AACvB,oBAAgB,KAAK;KACnB,OAAO;KACP;KACA,SAASF,gBAAAA,kBAAkB,EAAE,WAAW;KACzC,CAAC;AACF,qBAAiB,QACf,MACA,gBACA,eAAe,YAChB;;AAEH,OAAI,EAAE,YAAY;AAChB,qBAAiB,IAAIG,uBAAAA,eAAe,GAAG,EACrC,gBAAgB,MAAA,aAAmB,SAAS,EAAE,KAAK,EACpD,CAAC;AACF,UAAA,aAAmB,QAAQ,GAAG,eAAe;IAC7C,MAAM,OAAO,GAAG,EAAE,KAAK;AACvB,oBAAgB,KAAK;KACnB,OAAO;KACP;KACA,SAASH,gBAAAA,kBAAkB,EAAE,WAAW;KACzC,CAAC;AACF,qBAAiB,QACf,MACA,gBACA,eAAe,YAChB;;AAGH,OAAI,EAAE,cACJ,6BAA4B,KAAK,CAC/B,SACM,MAAA,aAAmB,SAAS,EAAE,KAAK,CAC1C,CAAC;;;;;AAON,mBAAiB,QAAQI,kBAAAA,iBAAiB,MAAA,UAAgB;;;;;;EAO1D,MAAM,4BAA4B,WAAW,MAAM,MAAM,EAAE,aAAa;EACxE,MAAM,cAAc,YAAY,OAAOZ,cAAAA,aAAa;;;;;AAMpD,MAAI,YAAY,SAAS,KAAK,2BAA2B;GACvD,MAAM,WAAW,IAAIa,iBAAAA,SAAS,aAAa;IACzC,QAAQ,KAAK,QAAQ;IACrB,cAAcC,cAAAA,aAAa,WAAW;IACvC,CAAC;AACF,oBAAiB,QAAQC,iBAAAA,iBAAiB,SAAS;;;;;EAOrD,IAAI;AACJ,MAAI,iBAAiB,SAAS,EAC5B,aAAY,iBAAiB,GAAG;WACvB,iBAAiB,SAAS,EACnC,aAAY,iBAAiB,GAAG;MAEhC,aAAYH,kBAAAA;EAKd,MAAM,gBACJ,iBAAiB,SAAS,IAAI,iBAAiB,GAAG,OAAOA,kBAAAA;EAG3D,MAAM,WACJ,gBAAgB,SAAS,IACrB,gBAAgB,gBAAgB,SAAS,GAAG,OAC5CI,qBAAAA;AAEN,mBAAiB,QAAQC,qBAAAA,OAAO,UAAU;;;;;EAM1C,MAAM,oBACJ,YAAY,SAAS,KAAK;AAG5B,OAAK,IAAI,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;GAChD,MAAM,OAAO,iBAAiB;GAC9B,MAAM,UAAU,KAAK;GAErB,MAAM,cADS,MAAM,iBAAiB,SAAS,IAClB,gBAAgB,iBAAiB,IAAI,GAAG;AAErE,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,KAAK,MAAMC,gBAAAA,kBAAkB,EAAE,CAAC,CAChC,QAAQ,SAAS,SAAA,WAA4B,kBAAkB;IAElE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CACN,aACA,GAAG,cAAc,KAAK,SAAU,SAASF,qBAAAA,MAAM,WAAW,KAAM,CACjE,CAAC,CACH;AAED,qBAAiB,oBACf,SACA,MAAA,wBACE,aACA,aACA,UACA,kBACD,EACD,aACD;SAED,kBAAiB,QAAQ,SAAS,YAAY;;AAKlD,OAAK,IAAI,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;GAChD,MAAM,OAAO,iBAAiB;GAC9B,MAAM,UAAU,KAAK;GAErB,MAAM,cADS,MAAM,iBAAiB,SAAS,IAE3CJ,kBAAAA,kBACA,iBAAiB,IAAI,GAAG;AAE5B,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,KAAK,MAAMM,gBAAAA,kBAAkB,EAAE,CAAC,CAChC,QAAQ,SAAS,SAAA,WAA4B,kBAAkB;IAClE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC,CACzC;AAED,qBAAiB,oBACf,SACA,MAAA,wBACE,aACA,aACA,kBACD,EACD,aACD;SAED,kBAAiB,QAAQ,SAAS,YAAY;;EAKlD,MAAM,qBAAqB,gBAAgB,GAAG,GAAG;AACjD,MAAI,gBAAgB,SAAS,KAAK,mBAChC,kBAAiB,QAAQN,kBAAAA,iBAAiB,mBAAmB,KAAK;OAC7D;GAQL,MAAM,eANa,MAAA,cACjB,aACA,OACA,kBACD,CAE+B,KAAK,MACnC,MAAMI,qBAAAA,MAAM,WAAW,EACxB;AACD,OAAI,aAAa,WAAW,EAC1B,kBAAiB,QAAQJ,kBAAAA,iBAAiB,aAAa,GAAG;OAE1D,kBAAiB,oBACfA,kBAAAA,iBACA,MAAA,kBAAwB,SAAS,EACjC,aACD;;AAKL,OAAK,IAAI,IAAI,gBAAgB,SAAS,GAAG,IAAI,GAAG,KAAK;GACnD,MAAM,OAAO,gBAAgB;GAC7B,MAAM,UAAU,KAAK;GACrB,MAAM,cAAc,gBAAgB,IAAI,GAAG;AAE3C,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,KAAK,MAAMM,gBAAAA,kBAAkB,EAAE,CAAC,CAChC,QAAQ,SAAS,SAAA,WAA4B,kBAAkB;IAClE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC,CACzC;AAED,qBAAiB,oBACf,SACA,MAAA,+BACE,aACA,KAAK,SACL,aACA,kBACD,EACD,aACD;SAED,kBAAiB,QAAQ,SAAS,YAAY;;AAKlD,MAAI,gBAAgB,SAAS,GAAG;GAC9B,MAAM,kBAAkB,gBAAgB;GACxC,MAAM,sBAAsB,gBAAgB;GAG5C,MAAM,aAAa,MAAA,cACjB,aACA,MACA,kBACD,CAAC,QAAQ,MAAM,MAAA,WAAyB,kBAAkB;GAE3D,MAAM,YAAY,QAChB,gBAAgB,WAAW,gBAAgB,QAAQ,SAAS,EAC7D;GAGD,MAAM,eAAe,WAAW,KAAK,MACnC,MAAMF,qBAAAA,MAAM,WAAW,EACxB;AAED,oBAAiB,oBACf,qBACA,MAAA,uBACE,aACA,WACA,UACA,kBACD,EACD,aACD;;AAIH,OAAK,IAAI,IAAI,gBAAgB,SAAS,GAAG,IAAI,GAAG,KAAK;GACnD,MAAM,OAAO,gBAAgB;GAC7B,MAAM,UAAU,KAAK;GACrB,MAAM,cAAc,gBAAgB,IAAI,GAAG;AAE3C,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,KAAK,MAAME,gBAAAA,kBAAkB,EAAE,CAAC,CAChC,QAAQ,SAAS,SAAA,WAA4B,kBAAkB;IAClE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC,CACzC;AAED,qBAAiB,oBACf,SACA,MAAA,+BACE,aACA,KAAK,SACL,aACA,kBACD,EACD,aACD;SAED,kBAAiB,QAAQ,SAAS,YAAY;;AAKlD,MAAI,gBAAgB,SAAS,GAAG;GAC9B,MAAM,kBAAkB,gBAAgB;GACxC,MAAM,sBAAsB,gBAAgB;AAE5C,OAAI,gBAAgB,WAAW,gBAAgB,QAAQ,SAAS,GAAG;IACjE,MAAM,gBAAgB,gBAAgB,QACnC,KAAK,MAAMA,gBAAAA,kBAAkB,EAAE,CAAC,CAChC,QAAQ,SAAS,SAAA,WAA4B,kBAAkB;;;;;IAMlE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAACF,qBAAAA,KAAK,GAAG,cAAc,CAAC,CACjC;AAED,qBAAiB,oBACf,qBACA,MAAA,+BACE,aACA,gBAAgB,SAChBA,qBAAAA,KACA,kBACD,EACD,aACD;SAED,kBAAiB,QAAQ,qBAAqBA,qBAAAA,IAAI;;;;;AAOtD,MAAI,mBAAmB;GAErB,MAAM,mBAAmB;AAEzB,OAAI,mBAAmB,OAAO,EAC5B,kBAAiB,oBACfD,iBAAAA,iBACA,MAAA,kBACE,oBACA,UACA,iBACD,EACD,CAAC,kBAAkB,SAAmB,CACvC;OAED,kBAAiB,QAAQA,iBAAAA,iBAAiB,iBAAiB;;;;;AAO/D,QAAA,QAAc,iBAAiB,QAAQ;GACrC,cAAc,KAAK,QAAQ;GAC3B,OAAO,KAAK,QAAQ;GACpB,MAAM,KAAK,QAAQ;GACnB,aAAa,KAAK,QAAQ;GAC3B,CAAC;;;;;CAMJ,IAAI,QAA2B;AAC7B,SAAO,MAAA;;CAGT,IAAI,eAA0D;AAC5D,SAAO,MAAA,MAAY;;CAGrB,IAAI,aAAa,OAAkD;AACjE,QAAA,MAAY,eAAe;;CAG7B,IAAI,QAA+B;AACjC,SAAO,MAAA,MAAY;;CAGrB,IAAI,MAAM,OAA8B;AACtC,QAAA,MAAY,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;CA0BtB,WACE,QACmB;AACnB,SAAO,IAAI,WACT,KAAK,UAAA,GAAA,0BAAA,cACQ,MAAA,eAAqB,OAAO,CAC1C;;;;;;;;;CAUH,eACE,aACA,sBAA+B,OAC/B,oBAA6B,YAAY,SAAS,GAC1B;EACxB,MAAM,QAAgC,EAAE;AACxC,MAAI,kBACF,OAAM,KAAKA,iBAAAA,gBAAgB;AAG7B,MAAI,oBACF,OAAM,KAAKH,kBAAAA,gBAAgB;AAG7B,QAAM,KAAKI,qBAAAA,IAAI;AAEf,SAAO;;;;;CAMT,mBACE,oBACA,UACA,kBACA;AACA,UAAQ,UAAmC;GAEzC,MAAM,WADe,MACS;GAC9B,MAAM,cAAc,SAAS,SAAS,SAAS;AAG/C,OACEW,yBAAAA,YAAY,WAAW,YAAY,IACnC,YAAY,QACZ,mBAAmB,IAAI,YAAY,KAAK,CAIxC,QAAO,KAAK,QAAQ,iBAAiB,mBAAmB;AAI1D,UAAO;;;;;;;CAQX,mBAAmB,WAAgCX,qBAAAA,KAAK;;;;AAItD,UAAQ,UAAmC;GAGzC,MAAM,cAFe,MACS,SACD,GAAG,GAAG;AAEnC,OACE,CAACY,yBAAAA,UAAU,WAAW,YAAY,IAClC,CAAC,YAAY,cACb,YAAY,WAAW,WAAW,EAElC,QAAO;AAQT,OAJuC,YAAY,WAAW,OAC3D,aAAa,SAAS,KAAK,WAAW,WAAW,CACnD,CAKC,QAAO;;;;AAMT,OAAI,MAAA,wBAA8B,KAChC,QAAOb,iBAAAA;;;;GAMT,MAAM,mBAAmB,YAAY,WAAW,QAC7C,aAAa,CAAC,SAAS,KAAK,WAAW,WAAW,CACpD;AAED,OAAI,iBAAiB,WAAW,EAC9B,QAAO;AAGT,UAAO,iBAAiB,KACrB,aACC,IAAIc,qBAAAA,KAAKd,iBAAAA,iBAAiB;IAAE,GAAG;IAAO,cAAc;IAAU,CAAC,CAClE;;;;;;;;;;;;;;;;;;CAmBL,wBACE,aACA,WACA,UACA,oBAA6B,YAAY,SAAS,GAClD;EACA,MAAM,wBAAwB,QAAQ,KAAK,QAAQ,eAAe;AAElE,UAAQ,UAAmC;GACzC,MAAM,eAAe;GAKrB,MAAM,WAAW,aAAa;GAC9B,MAAM,cAAc,SAAS,GAAG,GAAG;AACnC,OACEa,yBAAAA,UAAU,WAAW,YAAY,KAChC,CAAC,YAAY,cAAc,YAAY,WAAW,WAAW,GAE9D,QAAO;AAIT,OAAI,aAAa,aAAa,QAAQ;IACpC,MAAM,cAAcV,gBAAAA,kBAAkB,aAAa,OAAO;AAC1D,QAAI,gBAAgBF,qBAAAA,IAClB,QAAO;AAET,QAAI,gBAAA,SAAiC;AAEnC,SAAI,CAAC,kBACH,QAAO;AAET,YAAO,IAAIa,qBAAAA,KAAKd,iBAAAA,iBAAiB;MAAE,GAAG;MAAO,QAAQ,KAAA;MAAW,CAAC;;AAGnE,WAAO,IAAIc,qBAAAA,KAAKjB,kBAAAA,iBAAiB;KAAE,GAAG;KAAO,QAAQ,KAAA;KAAW,CAAC;;GAInE,MAAM,eAAe,SAAS,OAAOe,yBAAAA,YAAY,WAAW;GAC5D,MAAM,gBAAgB,SAAS,OAAOC,yBAAAA,UAAU,WAAW,CAAC,GAAG,GAAG;GAClE,MAAM,mBAAmB,eAAe,YAAY,QACjD,SAAS,CAAC,aAAa,MAAM,MAAM,EAAE,iBAAiB,KAAK,GAAG,CAChE;AACD,OAAI,oBAAoB,iBAAiB,SAAS,GAAG;;;;;;AAMnD,QAAI,MAAA,wBAA8B,KAChC,QAAOb,iBAAAA;AAET,WAAO,iBAAiB,KACrB,aACC,IAAIc,qBAAAA,KAAKd,iBAAAA,iBAAiB;KAAE,GAAG;KAAO,cAAc;KAAU,CAAC,CAClE;;GAKH,MAAM,6BAA6B,eAAe,YAAY,MAC3D,aAAa,SAAS,KAAK,WAAW,WAAW,CACnD;AAED,OACE,oBACA,iBAAiB,WAAW,KAC5B,CAAC,8BACD,sBAEA,QAAOH,kBAAAA;AAGT,OACE,CAACgB,yBAAAA,UAAU,WAAW,YAAY,IAClC,CAAC,YAAY,cACb,YAAY,WAAW,WAAW,EAElC,QAAO;GAIT,MAAM,iCAAiC,YAAY,WAAW,OAC3D,aAAa,SAAS,KAAK,WAAW,WAAW,CACnD;GAGD,MAAM,sBAAsB,YAAY,WAAW,MAChD,aAAa,CAAC,SAAS,KAAK,WAAW,WAAW,CACpD;AAED,OAAI,kCAAkC,CAAC,oBACrC,QAAO;;;;;;;;;AAWT,OAAI,MAAA,wBAA8B,KAChC,QAAOb,iBAAAA;GAGT,MAAM,mBAAoB,YAA0B,WAAY,QAC7D,aAAa,CAAC,SAAS,KAAK,WAAW,WAAW,CACpD;AAED,OAAI,iBAAiB,WAAW,EAC9B,QAAO;AAGT,UAAO,iBAAiB,KACrB,aACC,IAAIc,qBAAAA,KAAKd,iBAAAA,iBAAiB;IAAE,GAAG;IAAO,cAAc;IAAU,CAAC,CAClE;;;;;;;;;;;CAYL,gCACE,aACA,SACA,aACA,oBAA6B,YAAY,SAAS,GAClD;EACA,MAAM,aAAa,IAAI,IAAI,QAAQ,KAAK,MAAMG,gBAAAA,kBAAkB,EAAE,CAAC,CAAC;AACpE,UAAQ,UAAmC;GACzC,MAAM,eAAe;AACrB,OAAI,aAAa,QAAQ;IACvB,MAAM,OAAOA,gBAAAA,kBAAkB,aAAa,OAAO;AACnD,QAAI,SAASF,qBAAAA,OAAO,WAAW,IAAIA,qBAAAA,IAAI,CACrC,QAAOA,qBAAAA;AAET,QAAI,SAAA,WAA4B,WAAW,IAAA,QAAoB,EAAE;AAC/D,SAAI,CAAC,kBAAmB,QAAOA,qBAAAA;AAC/B,YAAO,IAAIa,qBAAAA,KAAKd,iBAAAA,iBAAiB;MAAE,GAAG;MAAO,QAAQ,KAAA;MAAW,CAAC;;AAEnE,QAAI,SAAA,mBAA4B,WAAW,IAAA,gBAAoB,CAC7D,QAAO,IAAIc,qBAAAA,KAAKjB,kBAAAA,iBAAiB;KAAE,GAAG;KAAO,QAAQ,KAAA;KAAW,CAAC;;AAGrE,UAAO;;;;;;;;;;;;CAaX,yBACE,aACA,aACA,UACA,oBAA6B,YAAY,SAAS,GAClD;AACA,UAAQ,UAAmC;GACzC,MAAM,eAAe;AACrB,OAAI,CAAC,aAAa,OAChB,QAAO;GAET,MAAM,cAAcM,gBAAAA,kBAAkB,aAAa,OAAO;AAC1D,OAAI,gBAAgBF,qBAAAA;;;;AAIlB,UAAO;AAET,OAAI,gBAAA,SAAiC;AACnC,QAAI,CAAC,kBACH,QAAO;AAET,WAAO,IAAIa,qBAAAA,KAAKd,iBAAAA,iBAAiB;KAAE,GAAG;KAAO,QAAQ,KAAA;KAAW,CAAC;;AAEnE,UAAO,IAAIc,qBAAAA,KAAKjB,kBAAAA,iBAAiB;IAAE,GAAG;IAAO,QAAQ,KAAA;IAAW,CAAC;;;;;;;;;;CAWrE,yBACE,aACA,aACA,oBAA6B,YAAY,SAAS,GAClD;AACA,UAAQ,UAAmC;GACzC,MAAM,eAAe;AACrB,OAAI,CAAC,aAAa,OAChB,QAAO;GAET,MAAM,cAAcM,gBAAAA,kBAAkB,aAAa,OAAO;AAC1D,OAAI,gBAAgBF,qBAAAA,IAClB,QAAOA,qBAAAA;AAET,OAAI,gBAAA,SAAiC;AACnC,QAAI,CAAC,kBACH,QAAOA,qBAAAA;AAET,WAAO,IAAIa,qBAAAA,KAAKd,iBAAAA,iBAAiB;KAAE,GAAG;KAAO,QAAQ,KAAA;KAAW,CAAC;;AAEnE,UAAO,IAAIc,qBAAAA,KAAKjB,kBAAAA,iBAAiB;IAAE,GAAG;IAAO,QAAQ,KAAA;IAAW,CAAC;;;;;;CAOrE,OAAA,2BACE,OACA,QACsC;AACtC,MACE,CAAC,KAAK,QAAQ,cACd,KAAK,QAAQ,WAAW,WAAW,KACnC,iBAAiBmB,qBAAAA,WACjB,CAAC,MAED,QAAO;EAGT,MAAM,gBAAgB,MAAMC,gBAAAA,2BAC1B,KAAK,QAAQ,YACb,MACD;EAID,MAAM,eAAe;GACnB,IAJkB,MAAM,MAAA,MACvB,SAAS,OAAO,CAChB,aAAa,EAAE,QAAQ,EAAE,EAAE,EAAE,EAEf;GACf,GAAG;GACJ;AACD,MAAI,CAAC,aACH,QAAO;AAIT,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,cAAc,CACtD,KAAI,EAAE,OAAO,cACX,cAAa,OAAoC;AAIrD,SAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CT,MAAM,OACJ,OACA,QAQA;EAEA,MAAM,gBAAA,GAAA,0BAAA,cAA4B,MAAA,eAAqB,OAAO;EAC9D,MAAM,mBAAmB,MAAM,MAAA,2BAC7B,OACA,aACD;AAED,SAAO,MAAA,MAAY,OACjB,kBACA,aAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CH,MAAM,OAKJ,OACA,QAWA;EACA,MAAM,gBAAA,GAAA,0BAAA,cAA4B,MAAA,eAAqB,OAAO;EAC9D,MAAM,mBAAmB,MAAM,MAAA,2BAC7B,OACA,aACD;AACD,SAAO,MAAA,MAAY,OACjB,kBACA,aACD;;;;;;;;;;;;CA0BH,MAAM,eAAe,QAMlB;EAGD,MAAM,cAAc,OADN,OADS,MAAM,MAAA,MAAY,eAAe,EACrB,eAAe,OAAO,EACzB,aAAa;AAE7C,SADe,IAAI,WAAW,YAAY;;;;;;;;;;;;CAc5C,MAAM,YAAY,QAMf;AAED,UADuB,MAAM,MAAA,MAAY,eAAe,EAClC,YAAY,OAAO;;;;;;;;;;;CAa3C,aACE,OACA,QAWA,eACqC;EACrC,MAAM,gBAAA,GAAA,0BAAA,cAA4B,MAAA,eAAqB,OAAO;AAC9D,SAAO,MAAA,MAAY,aACjB,OACA;GACE,GAAI;GAUJ,SAAS,QAAQ,WAAW;GAC7B,EACD,cACD;;;;;CAKH,cAAc,QAAyB;AACrC,SAAO,MAAA,MAAY,cAAc,OAAO;;;;;CAK1C,SAAS,QAAwB,SAA2B;AAC1D,SAAO,MAAA,MAAY,SAAS,QAAQ,QAAQ;;;;;CAK9C,gBAAgB,QAAwB,SAAiC;AACvE,SAAO,MAAA,MAAY,gBAAgB,QAAQ,QAAQ;;;;;CAKrD,aAAa,WAAoB,SAAmB;AAClD,SAAO,MAAA,MAAY,aAAa,WAAW,QAAQ;;;;;CAKrD,kBAAkB,WAAoB,SAAmB;AACvD,SAAO,MAAA,MAAY,kBAAkB,WAAW,QAAQ;;;;;CAK1D,YACE,aACA,QACA,QACA;AACA,SAAO,MAAA,MAAY,YAAY,aAAa,QAAQ,OAAO;;;;;CAM7D,IAAI,UAAU;AACZ,SAAO,MAAA,MAAY"}
@@ -239,7 +239,7 @@ declare class ReactAgent<Types extends AgentTypeConfig = AgentTypeConfig<Record<
239
239
  /**
240
240
  * @internal
241
241
  */
242
- getSubgraphAsync(namespace?: string, recurse?: boolean): never;
242
+ getSubgraphsAsync(namespace?: string, recurse?: boolean): never;
243
243
  /**
244
244
  * @internal
245
245
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.d.cts","names":[],"sources":["../../src/agents/ReactAgent.ts"],"mappings":"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"}
1
+ {"version":3,"file":"ReactAgent.d.cts","names":[],"sources":["../../src/agents/ReactAgent.ts"],"mappings":"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"}
@@ -239,7 +239,7 @@ declare class ReactAgent<Types extends AgentTypeConfig = AgentTypeConfig<Record<
239
239
  /**
240
240
  * @internal
241
241
  */
242
- getSubgraphAsync(namespace?: string, recurse?: boolean): never;
242
+ getSubgraphsAsync(namespace?: string, recurse?: boolean): never;
243
243
  /**
244
244
  * @internal
245
245
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.d.ts","names":[],"sources":["../../src/agents/ReactAgent.ts"],"mappings":"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"}
1
+ {"version":3,"file":"ReactAgent.d.ts","names":[],"sources":["../../src/agents/ReactAgent.ts"],"mappings":"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"}
@@ -412,10 +412,18 @@ var ReactAgent = class ReactAgent {
412
412
  const toolMessages = messages.filter(ToolMessage.isInstance);
413
413
  const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);
414
414
  const pendingToolCalls = lastAiMessage?.tool_calls?.filter((call) => !toolMessages.some((m) => m.tool_call_id === call.id));
415
- if (pendingToolCalls && pendingToolCalls.length > 0) return pendingToolCalls.map((toolCall) => new Send(TOOLS_NODE_NAME, {
416
- ...state,
417
- lg_tool_call: toolCall
418
- }));
415
+ if (pendingToolCalls && pendingToolCalls.length > 0) {
416
+ /**
417
+ * v1: route the full message to the ToolNode; it filters already-processed
418
+ * calls internally and runs the remaining ones via Promise.all.
419
+ * v2: dispatch each pending call as a separate Send task.
420
+ */
421
+ if (this.#toolBehaviorVersion === "v1") return TOOLS_NODE_NAME;
422
+ return pendingToolCalls.map((toolCall) => new Send(TOOLS_NODE_NAME, {
423
+ ...state,
424
+ lg_tool_call: toolCall
425
+ }));
426
+ }
419
427
  const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some((toolCall) => toolCall.name.startsWith("extract-"));
420
428
  if (pendingToolCalls && pendingToolCalls.length === 0 && !hasStructuredResponseCalls && hasStructuredResponse) return AGENT_NODE_NAME;
421
429
  if (!AIMessage.isInstance(lastMessage) || !lastMessage.tool_calls || lastMessage.tool_calls.length === 0) return exitNode;
@@ -423,10 +431,20 @@ var ReactAgent = class ReactAgent {
423
431
  const hasRegularToolCalls = lastMessage.tool_calls.some((toolCall) => !toolCall.name.startsWith("extract-"));
424
432
  if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) return exitNode;
425
433
  /**
426
- * For routing from afterModel nodes, always use simple string paths
427
- * The Send API is handled at the model_request node level
434
+ * v1: route the full AIMessage to a single ToolNode invocation so all
435
+ * tool calls run concurrently via Promise.all.
436
+ *
437
+ * v2: dispatch each regular tool call as a separate Send task, matching
438
+ * the behaviour of #createModelRouter when no afterModel middleware is
439
+ * present.
428
440
  */
429
- return TOOLS_NODE_NAME;
441
+ if (this.#toolBehaviorVersion === "v1") return TOOLS_NODE_NAME;
442
+ const regularToolCalls = lastMessage.tool_calls.filter((toolCall) => !toolCall.name.startsWith("extract-"));
443
+ if (regularToolCalls.length === 0) return exitNode;
444
+ return regularToolCalls.map((toolCall) => new Send(TOOLS_NODE_NAME, {
445
+ ...state,
446
+ lg_tool_call: toolCall
447
+ }));
430
448
  };
431
449
  }
432
450
  /**
@@ -696,7 +714,7 @@ var ReactAgent = class ReactAgent {
696
714
  /**
697
715
  * @internal
698
716
  */
699
- getSubgraphAsync(namespace, recurse) {
717
+ getSubgraphsAsync(namespace, recurse) {
700
718
  return this.#graph.getSubgraphsAsync(namespace, recurse);
701
719
  }
702
720
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.js","names":["#defaultConfig","#toolBehaviorVersion","#agentNode","#stateManager","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","#initializeMiddlewareStates"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type {\n BaseCheckpointSaver,\n BaseStore,\n CheckpointListOptions,\n} from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaValue,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaValue<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = defaultConfig ?? {};\n if (options.name) {\n this.#defaultConfig = mergeConfigs(this.#defaultConfig, {\n metadata: { lc_agent_name: options.name },\n });\n }\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(\n shouldReturnDirect,\n exitNode,\n toolReturnTarget\n ),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n get checkpointer(): BaseCheckpointSaver | boolean | undefined {\n return this.#graph.checkpointer;\n }\n\n set checkpointer(value: BaseCheckpointSaver | boolean | undefined) {\n this.#graph.checkpointer = value;\n }\n\n get store(): BaseStore | undefined {\n return this.#graph.store;\n }\n\n set store(value: BaseStore | undefined) {\n this.#graph.store = value;\n }\n\n /**\n * Creates a new ReactAgent with the given config merged into the existing config.\n * Follows the same pattern as LangGraph's Pregel.withConfig().\n *\n * The merged config is applied as a default that gets merged with any config\n * passed at invocation time (invoke/stream). Invocation-time config takes precedence.\n *\n * @param config - Configuration to merge with existing config\n * @returns A new ReactAgent instance with the merged configuration\n *\n * @example\n * ```typescript\n * const agent = createAgent({ model: \"gpt-4o\", tools: [...] });\n *\n * // Set a default recursion limit\n * const configuredAgent = agent.withConfig({ recursionLimit: 1000 });\n *\n * // Chain multiple configs\n * const debugAgent = agent\n * .withConfig({ recursionLimit: 1000 })\n * .withConfig({ tags: [\"debug\"] });\n * ```\n */\n withConfig(\n config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">\n ): ReactAgent<Types> {\n return new ReactAgent(\n this.options,\n mergeConfigs(this.#defaultConfig, config)\n );\n }\n\n /**\n * Get possible edge destinations from model node.\n * @param toolClasses names of tools to call\n * @param includeModelRequest whether to include \"model_request\" as a valid path (for jumpTo routing)\n * @param hasToolsAvailable whether tools are available (includes dynamic tools via middleware)\n * @returns list of possible edge destinations\n */\n #getModelPaths(\n toolClasses: (ClientTool | ServerTool)[],\n includeModelRequest: boolean = false,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ): BaseGraphDestination[] {\n const paths: BaseGraphDestination[] = [];\n if (hasToolsAvailable) {\n paths.push(TOOLS_NODE_NAME);\n }\n\n if (includeModelRequest) {\n paths.push(AGENT_NODE_NAME);\n }\n\n paths.push(END);\n\n return paths;\n }\n\n /**\n * Create routing function for tools node conditional edges.\n */\n #createToolsRouter(\n shouldReturnDirect: Set<string>,\n exitNode: string | typeof END,\n toolReturnTarget: string\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages[messages.length - 1];\n\n // Check if we just executed a returnDirect tool\n if (\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n shouldReturnDirect.has(lastMessage.name)\n ) {\n // If we have a response format, route to agent to generate structured response\n // Otherwise, return directly to exit node (could be after_agent or END)\n return this.options.responseFormat ? toolReturnTarget : exitNode;\n }\n\n // For non-returnDirect tools, route back to loop entry node (could be middleware or agent)\n return toolReturnTarget;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * For routing from afterModel nodes, always use simple string paths\n * The Send API is handled at the model_request node level\n */\n return TOOLS_NODE_NAME;\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n TSubgraphs extends boolean,\n TEncoding extends \"text/event-stream\" | undefined,\n >(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TSubgraphs,\n TEncoding\n >\n ) {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n return this.#graph.stream(\n initializedState,\n mergedConfig as Record<string, any>\n ) as Promise<\n IterableReadableStream<\n StreamOutputMap<\n TStreamMode,\n TSubgraphs,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReactAgent.js","names":["#defaultConfig","#toolBehaviorVersion","#agentNode","#stateManager","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","#initializeMiddlewareStates"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type {\n BaseCheckpointSaver,\n BaseStore,\n CheckpointListOptions,\n} from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaValue,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaValue<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = defaultConfig ?? {};\n if (options.name) {\n this.#defaultConfig = mergeConfigs(this.#defaultConfig, {\n metadata: { lc_agent_name: options.name },\n });\n }\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(\n shouldReturnDirect,\n exitNode,\n toolReturnTarget\n ),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n get checkpointer(): BaseCheckpointSaver | boolean | undefined {\n return this.#graph.checkpointer;\n }\n\n set checkpointer(value: BaseCheckpointSaver | boolean | undefined) {\n this.#graph.checkpointer = value;\n }\n\n get store(): BaseStore | undefined {\n return this.#graph.store;\n }\n\n set store(value: BaseStore | undefined) {\n this.#graph.store = value;\n }\n\n /**\n * Creates a new ReactAgent with the given config merged into the existing config.\n * Follows the same pattern as LangGraph's Pregel.withConfig().\n *\n * The merged config is applied as a default that gets merged with any config\n * passed at invocation time (invoke/stream). Invocation-time config takes precedence.\n *\n * @param config - Configuration to merge with existing config\n * @returns A new ReactAgent instance with the merged configuration\n *\n * @example\n * ```typescript\n * const agent = createAgent({ model: \"gpt-4o\", tools: [...] });\n *\n * // Set a default recursion limit\n * const configuredAgent = agent.withConfig({ recursionLimit: 1000 });\n *\n * // Chain multiple configs\n * const debugAgent = agent\n * .withConfig({ recursionLimit: 1000 })\n * .withConfig({ tags: [\"debug\"] });\n * ```\n */\n withConfig(\n config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">\n ): ReactAgent<Types> {\n return new ReactAgent(\n this.options,\n mergeConfigs(this.#defaultConfig, config)\n );\n }\n\n /**\n * Get possible edge destinations from model node.\n * @param toolClasses names of tools to call\n * @param includeModelRequest whether to include \"model_request\" as a valid path (for jumpTo routing)\n * @param hasToolsAvailable whether tools are available (includes dynamic tools via middleware)\n * @returns list of possible edge destinations\n */\n #getModelPaths(\n toolClasses: (ClientTool | ServerTool)[],\n includeModelRequest: boolean = false,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ): BaseGraphDestination[] {\n const paths: BaseGraphDestination[] = [];\n if (hasToolsAvailable) {\n paths.push(TOOLS_NODE_NAME);\n }\n\n if (includeModelRequest) {\n paths.push(AGENT_NODE_NAME);\n }\n\n paths.push(END);\n\n return paths;\n }\n\n /**\n * Create routing function for tools node conditional edges.\n */\n #createToolsRouter(\n shouldReturnDirect: Set<string>,\n exitNode: string | typeof END,\n toolReturnTarget: string\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages[messages.length - 1];\n\n // Check if we just executed a returnDirect tool\n if (\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n shouldReturnDirect.has(lastMessage.name)\n ) {\n // If we have a response format, route to agent to generate structured response\n // Otherwise, return directly to exit node (could be after_agent or END)\n return this.options.responseFormat ? toolReturnTarget : exitNode;\n }\n\n // For non-returnDirect tools, route back to loop entry node (could be middleware or agent)\n return toolReturnTarget;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n /**\n * v1: route the full message to the ToolNode; it filters already-processed\n * calls internally and runs the remaining ones via Promise.all.\n * v2: dispatch each pending call as a separate Send task.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * v1: route the full AIMessage to a single ToolNode invocation so all\n * tool calls run concurrently via Promise.all.\n *\n * v2: dispatch each regular tool call as a separate Send task, matching\n * the behaviour of #createModelRouter when no afterModel middleware is\n * present.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n const regularToolCalls = (lastMessage as AIMessage).tool_calls!.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n TSubgraphs extends boolean,\n TEncoding extends \"text/event-stream\" | undefined,\n >(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TSubgraphs,\n TEncoding\n >\n ) {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n return this.#graph.stream(\n initializedState,\n mergedConfig as Record<string, any>\n ) as Promise<\n IterableReadableStream<\n StreamOutputMap<\n TStreamMode,\n TSubgraphs,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphsAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":"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"}
@@ -161,6 +161,8 @@ var ToolNode = class extends require_RunnableCallable.RunnableCallable {
161
161
  const lgConfig = config;
162
162
  const runtime = {
163
163
  context: lgConfig?.context,
164
+ store: lgConfig?.store,
165
+ configurable: lgConfig?.configurable,
164
166
  writer: lgConfig?.writer,
165
167
  interrupt: lgConfig?.interrupt,
166
168
  signal: lgConfig?.signal
@@ -1 +1 @@
1
- {"version":3,"file":"ToolNode.cjs","names":["BaseMessage","ToolInvocationError","ToolMessage","RunnableCallable","mergeAbortSignals","ToolInputParsingException","#handleError","AIMessage","isCommand","Command","Send"],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-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 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":";;;;;;;;;;;;;AAmCA,MAAM,uBACJ,UACA,mBAEA,UAAU,SAAS,oCAAoC,eAAe,KAAK,KAAK,CAAC;;;;AAKnF,MAAa,kBAAkB;AA6C/B,MAAM,sBAAsB,UAC1B,MAAM,QAAQ,MAAM,IAAI,MAAM,MAAMA,yBAAAA,YAAY,WAAW;AAE7D,MAAM,mBACJ,UAEA,OAAO,UAAU,YACjB,SAAS,QACT,cAAc,SACd,mBAAmB,MAAM,SAAS;AAEpC,MAAM,eACJ,UAEA,OAAO,UAAU,YAAY,SAAS,QAAQ,kBAAkB;;;;;;;;;;;AAYlE,SAAS,wBACP,OACA,UACyB;AACzB,KAAI,iBAAiBC,eAAAA,oBACnB,QAAO,IAAIC,yBAAAA,YAAY;EACrB,SAAS,MAAM;EACf,cAAc,SAAS;EACvB,MAAM,SAAS;EAChB,CAAC;;;;AAKJ,QAAO,IAAIA,yBAAAA,YAAY;EACrB,SAAS,GAAG,MAAM;EAClB,cAAc,SAAS;EACvB,MAAM,SAAS;EAChB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CJ,IAAa,WAAb,cAGUC,yBAAAA,iBAA6C;CACrD;CAEA,QAAQ;CAER;CAEA,mBAGE;CAEF;CAEA,YACE,OACA,SACA;EACA,MAAM,EAAE,MAAM,MAAM,kBAAkB,QAAQ,iBAC5C,WAAW,EAAE;AACf,QAAM;GACJ;GACA;GACA,OAAO,OAAO,WACZ,KAAK,IACH,OAEA,OACD;GACJ,CAAC;AAbK,OAAA,UAAA;AAcP,OAAK,QAAQ;AACb,OAAK,mBAAmB,oBAAoB,KAAK;AACjD,OAAK,SAAS;AACd,OAAK,eAAe;;;;;;;;;CAUtB,aACE,OACA,MACA,mBACa;;;;;;AAMb,OAAA,GAAA,qBAAA,kBAAqB,MAAM,CACzB,OAAM;;;;AAMR,MAAI,KAAK,QAAQ,QACf,OAAM;;;;;AAOR,MAAI,qBAAqB,KAAK,qBAAqB,KACjD,OAAM;;;;AAMR,MAAI,CAAC,KAAK,iBACR,OAAM;;;;AAMR,MAAI,OAAO,KAAK,qBAAqB,YAAY;GAC/C,MAAM,SAAS,KAAK,iBAAiB,OAAO,KAAK;AACjD,OAAI,UAAUD,yBAAAA,YAAY,WAAW,OAAO,CAC1C,QAAO;;;;AAMT,SAAM;aACG,KAAK,iBACd,QAAO,IAAIA,yBAAAA,YAAY;GACrB,MAAM,KAAK;GACX,SAAS,GAAG,MAAM;GAClB,cAAc,KAAK;GACpB,CAAC;;;;AAMJ,QAAM;;CAGR,MAAgB,QACd,MACA,QACA,OACgC;;;;EAIhC,MAAM,WAAW;EACjB,MAAM,UAAU;GACd,SAAS,UAAU;GACnB,QAAQ,UAAU;GAClB,WAAW,UAAU;GACrB,QAAQ,UAAU;GACnB;;;;;EAMD,MAAM,iBAAiB,KAAK,MAAM,MAAM,MAAM,EAAE,SAAS,KAAK,KAAK;;;;;;;;;;EAWnE,MAAM,cAAc,OAClB,YACmC;GACnC,MAAM,EAAE,UAAU,MAAM,gBAAgB;;;;;;GAOxC,MAAM,OACJ,eAAe,KAAK,MAAM,MAAM,MAAM,EAAE,SAAS,SAAS,KAAK;AAEjE,OAAI,SAAS,KAAA,GAAW;;;;;IAKtB,MAAM,iBAAiB,KAAK,MAAM,KAAK,MAAM,EAAE,KAAK;AACpD,WAAO,IAAIA,yBAAAA,YAAY;KACrB,SAAS,oBAAoB,SAAS,MAAM,eAAe;KAC3D,cAAc,SAAS;KACvB,MAAM,SAAS;KACf,QAAQ;KACT,CAAC;;;;;;;GAQJ,MAAM,gBAAgB;AAKtB,OAAI;IACF,MAAM,SAAS,MAAM,cAAc,OACjC;KAAE,GAAG;KAAU,MAAM;KAAa,EAClC;KACE,GAAG;KAIH;KACA,YAAY,SAAS;KACrB,OAAO,OAAO,cAAc,qBAAqB;KACjD,QAAQE,cAAAA,kBAAkB,KAAK,QAAQ,OAAO,OAAO;KACtD,CACF;AAED,QAAIF,yBAAAA,YAAY,WAAW,OAAO,KAAA,GAAA,qBAAA,WAAc,OAAO,CACrD,QAAO;AAGT,WAAO,IAAIA,yBAAAA,YAAY;KACrB,MAAM,cAAc;KACpB,SAAS,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,OAAO;KACrE,cAAc,SAAS;KACxB,CAAC;YACK,GAAY;;;;;AAKnB,QAAI,aAAaG,sBAAAA,0BACf,OAAM,IAAIJ,eAAAA,oBAAoB,GAAG,SAAS;;;;AAK5C,UAAM;;;;;;;;EASV,MAAM,UAA8C;GAClD,UAAU;GACV,MAAM;GACN;GACA;GACD;;;;AAKD,MAAI,KAAK,aACP,KAAI;AACF,UAAO,MAAM,KAAK,aAAa,SAAS,YAAY;WAC7C,GAAY;;;;AAInB,UAAO,MAAA,YAAkB,GAAG,MAAM,KAAK;;;;;AAO3C,MAAI,CAAC,gBAAgB;GACnB,MAAM,iBAAiB,KAAK,MAAM,KAAK,MAAM,EAAE,KAAK;AACpD,UAAO,IAAIC,yBAAAA,YAAY;IACrB,SAAS,oBAAoB,KAAK,MAAM,eAAe;IACvD,cAAc,KAAK;IACnB,MAAM,KAAK;IACX,QAAQ;IACT,CAAC;;;;;AAMJ,MAAI;AACF,UAAO,MAAM,YAAY,QAAQ;WAC1B,GAAY;;;;AAInB,UAAO,MAAA,YAAkB,GAAG,MAAM,MAAM;;;CAI5C,MAAgB,IACd,OACA,QACwB;EACxB,IAAI;AAEJ,MAAI,YAAY,MAAM,EAAE;GACtB,MAAM,EAAE,cAAc,GAAG,QAAQ,IAAI,GAAG,aAAa;AACrD,aAAU,CAAC,MAAM,KAAK,QAAQ,MAAM,cAAc,QAAQ,SAAS,CAAC;SAC/D;GACL,IAAI;AACJ,OAAI,mBAAmB,MAAM,CAC3B,YAAW;YACF,gBAAgB,MAAM,CAC/B,YAAW,MAAM;OAEjB,OAAM,IAAI,MACR,+EACD;GAGH,MAAM,iBAA8B,IAAI,IACtC,SACG,QAAQ,QAAQ,IAAI,SAAS,KAAK,OAAO,CACzC,KAAK,QAAS,IAAoB,aAAa,CACnD;GAED,IAAI;AACJ,QAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;IAChD,MAAM,UAAU,SAAS;AACzB,QAAIK,yBAAAA,UAAU,WAAW,QAAQ,EAAE;AACjC,iBAAY;AACZ;;;AAIJ,OAAI,CAACA,yBAAAA,UAAU,WAAW,UAAU,CAClC,OAAM,IAAI,MAAM,6CAA6C;AAG/D,aAAU,MAAM,QAAQ,IACtB,UAAU,YACN,QAAQ,SAAS,KAAK,MAAM,QAAQ,CAAC,eAAe,IAAI,KAAK,GAAG,CAAC,CAClE,KAAK,SAAS,KAAK,QAAQ,MAAM,QAAQ,MAAM,CAAC,IAAI,EAAE,CAC1D;;AAIH,MAAI,CAAC,QAAQ,KAAKC,qBAAAA,UAAU,CAC1B,QAAQ,MAAM,QAAQ,MAAM,GACxB,UACA,EAAE,UAAU,SAAS;EAI3B,MAAM,kBAIA,EAAE;EACR,IAAI,gBAAgC;AAEpC,OAAK,MAAM,UAAU,QACnB,MAAA,GAAA,qBAAA,WAAc,OAAO,CACnB,KACE,OAAO,UAAUC,qBAAAA,QAAQ,UACzB,MAAM,QAAQ,OAAO,KAAK,IAC1B,OAAO,KAAK,OAAO,SAAS,OAAO,KAAK,CAAC,CAEzC,KAAI,cACD,eAAc,KAAgB,KAAK,GAAI,OAAO,KAAgB;MAE/D,iBAAgB,IAAIA,qBAAAA,QAAQ;GAC1B,OAAOA,qBAAAA,QAAQ;GACf,MAAM,OAAO;GACd,CAAC;MAGJ,iBAAgB,KAAK,OAAO;MAG9B,iBAAgB,KACd,MAAM,QAAQ,MAAM,GAAG,CAAC,OAAO,GAAG,EAAE,UAAU,CAAC,OAAO,EAAE,CACzD;AAIL,MAAI,cACF,iBAAgB,KAAK,cAAc;AAGrC,SAAO;;;AAIX,SAAgB,OAAO,GAAuB;AAC5C,QAAO,aAAaC,qBAAAA"}
1
+ {"version":3,"file":"ToolNode.cjs","names":["BaseMessage","ToolInvocationError","ToolMessage","RunnableCallable","mergeAbortSignals","ToolInputParsingException","#handleError","AIMessage","isCommand","Command","Send"],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-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":";;;;;;;;;;;;;AAmCA,MAAM,uBACJ,UACA,mBAEA,UAAU,SAAS,oCAAoC,eAAe,KAAK,KAAK,CAAC;;;;AAKnF,MAAa,kBAAkB;AA6C/B,MAAM,sBAAsB,UAC1B,MAAM,QAAQ,MAAM,IAAI,MAAM,MAAMA,yBAAAA,YAAY,WAAW;AAE7D,MAAM,mBACJ,UAEA,OAAO,UAAU,YACjB,SAAS,QACT,cAAc,SACd,mBAAmB,MAAM,SAAS;AAEpC,MAAM,eACJ,UAEA,OAAO,UAAU,YAAY,SAAS,QAAQ,kBAAkB;;;;;;;;;;;AAYlE,SAAS,wBACP,OACA,UACyB;AACzB,KAAI,iBAAiBC,eAAAA,oBACnB,QAAO,IAAIC,yBAAAA,YAAY;EACrB,SAAS,MAAM;EACf,cAAc,SAAS;EACvB,MAAM,SAAS;EAChB,CAAC;;;;AAKJ,QAAO,IAAIA,yBAAAA,YAAY;EACrB,SAAS,GAAG,MAAM;EAClB,cAAc,SAAS;EACvB,MAAM,SAAS;EAChB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CJ,IAAa,WAAb,cAGUC,yBAAAA,iBAA6C;CACrD;CAEA,QAAQ;CAER;CAEA,mBAGE;CAEF;CAEA,YACE,OACA,SACA;EACA,MAAM,EAAE,MAAM,MAAM,kBAAkB,QAAQ,iBAC5C,WAAW,EAAE;AACf,QAAM;GACJ;GACA;GACA,OAAO,OAAO,WACZ,KAAK,IACH,OAEA,OACD;GACJ,CAAC;AAbK,OAAA,UAAA;AAcP,OAAK,QAAQ;AACb,OAAK,mBAAmB,oBAAoB,KAAK;AACjD,OAAK,SAAS;AACd,OAAK,eAAe;;;;;;;;;CAUtB,aACE,OACA,MACA,mBACa;;;;;;AAMb,OAAA,GAAA,qBAAA,kBAAqB,MAAM,CACzB,OAAM;;;;AAMR,MAAI,KAAK,QAAQ,QACf,OAAM;;;;;AAOR,MAAI,qBAAqB,KAAK,qBAAqB,KACjD,OAAM;;;;AAMR,MAAI,CAAC,KAAK,iBACR,OAAM;;;;AAMR,MAAI,OAAO,KAAK,qBAAqB,YAAY;GAC/C,MAAM,SAAS,KAAK,iBAAiB,OAAO,KAAK;AACjD,OAAI,UAAUD,yBAAAA,YAAY,WAAW,OAAO,CAC1C,QAAO;;;;AAMT,SAAM;aACG,KAAK,iBACd,QAAO,IAAIA,yBAAAA,YAAY;GACrB,MAAM,KAAK;GACX,SAAS,GAAG,MAAM;GAClB,cAAc,KAAK;GACpB,CAAC;;;;AAMJ,QAAM;;CAGR,MAAgB,QACd,MACA,QACA,OACgC;;;;EAIhC,MAAM,WAAW;EACjB,MAAM,UAAU;GACd,SAAS,UAAU;GACnB,OAAO,UAAU;GACjB,cAAc,UAAU;GACxB,QAAQ,UAAU;GAClB,WAAW,UAAU;GACrB,QAAQ,UAAU;GACnB;;;;;EAMD,MAAM,iBAAiB,KAAK,MAAM,MAAM,MAAM,EAAE,SAAS,KAAK,KAAK;;;;;;;;;;EAWnE,MAAM,cAAc,OAClB,YACmC;GACnC,MAAM,EAAE,UAAU,MAAM,gBAAgB;;;;;;GAOxC,MAAM,OACJ,eAAe,KAAK,MAAM,MAAM,MAAM,EAAE,SAAS,SAAS,KAAK;AAEjE,OAAI,SAAS,KAAA,GAAW;;;;;IAKtB,MAAM,iBAAiB,KAAK,MAAM,KAAK,MAAM,EAAE,KAAK;AACpD,WAAO,IAAIA,yBAAAA,YAAY;KACrB,SAAS,oBAAoB,SAAS,MAAM,eAAe;KAC3D,cAAc,SAAS;KACvB,MAAM,SAAS;KACf,QAAQ;KACT,CAAC;;;;;;;GAQJ,MAAM,gBAAgB;AAKtB,OAAI;IACF,MAAM,SAAS,MAAM,cAAc,OACjC;KAAE,GAAG;KAAU,MAAM;KAAa,EAClC;KACE,GAAG;KAIH;KACA,YAAY,SAAS;KACrB,OAAO,OAAO,cAAc,qBAAqB;KACjD,QAAQE,cAAAA,kBAAkB,KAAK,QAAQ,OAAO,OAAO;KACtD,CACF;AAED,QAAIF,yBAAAA,YAAY,WAAW,OAAO,KAAA,GAAA,qBAAA,WAAc,OAAO,CACrD,QAAO;AAGT,WAAO,IAAIA,yBAAAA,YAAY;KACrB,MAAM,cAAc;KACpB,SAAS,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,OAAO;KACrE,cAAc,SAAS;KACxB,CAAC;YACK,GAAY;;;;;AAKnB,QAAI,aAAaG,sBAAAA,0BACf,OAAM,IAAIJ,eAAAA,oBAAoB,GAAG,SAAS;;;;AAK5C,UAAM;;;;;;;;EASV,MAAM,UAA8C;GAClD,UAAU;GACV,MAAM;GACN;GACA;GACD;;;;AAKD,MAAI,KAAK,aACP,KAAI;AACF,UAAO,MAAM,KAAK,aAAa,SAAS,YAAY;WAC7C,GAAY;;;;AAInB,UAAO,MAAA,YAAkB,GAAG,MAAM,KAAK;;;;;AAO3C,MAAI,CAAC,gBAAgB;GACnB,MAAM,iBAAiB,KAAK,MAAM,KAAK,MAAM,EAAE,KAAK;AACpD,UAAO,IAAIC,yBAAAA,YAAY;IACrB,SAAS,oBAAoB,KAAK,MAAM,eAAe;IACvD,cAAc,KAAK;IACnB,MAAM,KAAK;IACX,QAAQ;IACT,CAAC;;;;;AAMJ,MAAI;AACF,UAAO,MAAM,YAAY,QAAQ;WAC1B,GAAY;;;;AAInB,UAAO,MAAA,YAAkB,GAAG,MAAM,MAAM;;;CAI5C,MAAgB,IACd,OACA,QACwB;EACxB,IAAI;AAEJ,MAAI,YAAY,MAAM,EAAE;GACtB,MAAM,EAAE,cAAc,GAAG,QAAQ,IAAI,GAAG,aAAa;AACrD,aAAU,CAAC,MAAM,KAAK,QAAQ,MAAM,cAAc,QAAQ,SAAS,CAAC;SAC/D;GACL,IAAI;AACJ,OAAI,mBAAmB,MAAM,CAC3B,YAAW;YACF,gBAAgB,MAAM,CAC/B,YAAW,MAAM;OAEjB,OAAM,IAAI,MACR,+EACD;GAGH,MAAM,iBAA8B,IAAI,IACtC,SACG,QAAQ,QAAQ,IAAI,SAAS,KAAK,OAAO,CACzC,KAAK,QAAS,IAAoB,aAAa,CACnD;GAED,IAAI;AACJ,QAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;IAChD,MAAM,UAAU,SAAS;AACzB,QAAIK,yBAAAA,UAAU,WAAW,QAAQ,EAAE;AACjC,iBAAY;AACZ;;;AAIJ,OAAI,CAACA,yBAAAA,UAAU,WAAW,UAAU,CAClC,OAAM,IAAI,MAAM,6CAA6C;AAG/D,aAAU,MAAM,QAAQ,IACtB,UAAU,YACN,QAAQ,SAAS,KAAK,MAAM,QAAQ,CAAC,eAAe,IAAI,KAAK,GAAG,CAAC,CAClE,KAAK,SAAS,KAAK,QAAQ,MAAM,QAAQ,MAAM,CAAC,IAAI,EAAE,CAC1D;;AAIH,MAAI,CAAC,QAAQ,KAAKC,qBAAAA,UAAU,CAC1B,QAAQ,MAAM,QAAQ,MAAM,GACxB,UACA,EAAE,UAAU,SAAS;EAI3B,MAAM,kBAIA,EAAE;EACR,IAAI,gBAAgC;AAEpC,OAAK,MAAM,UAAU,QACnB,MAAA,GAAA,qBAAA,WAAc,OAAO,CACnB,KACE,OAAO,UAAUC,qBAAAA,QAAQ,UACzB,MAAM,QAAQ,OAAO,KAAK,IAC1B,OAAO,KAAK,OAAO,SAAS,OAAO,KAAK,CAAC,CAEzC,KAAI,cACD,eAAc,KAAgB,KAAK,GAAI,OAAO,KAAgB;MAE/D,iBAAgB,IAAIA,qBAAAA,QAAQ;GAC1B,OAAOA,qBAAAA,QAAQ;GACf,MAAM,OAAO;GACd,CAAC;MAGJ,iBAAgB,KAAK,OAAO;MAG9B,iBAAgB,KACd,MAAM,QAAQ,MAAM,GAAG,CAAC,OAAO,GAAG,EAAE,UAAU,CAAC,OAAO,EAAE,CACzD;AAIL,MAAI,cACF,iBAAgB,KAAK,cAAc;AAGrC,SAAO;;;AAIX,SAAgB,OAAO,GAAuB;AAC5C,QAAO,aAAaC,qBAAAA"}
@@ -160,6 +160,8 @@ var ToolNode = class extends RunnableCallable {
160
160
  const lgConfig = config;
161
161
  const runtime = {
162
162
  context: lgConfig?.context,
163
+ store: lgConfig?.store,
164
+ configurable: lgConfig?.configurable,
163
165
  writer: lgConfig?.writer,
164
166
  interrupt: lgConfig?.interrupt,
165
167
  signal: lgConfig?.signal
@@ -1 +1 @@
1
- {"version":3,"file":"ToolNode.js","names":["#handleError"],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-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 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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"}
1
+ {"version":3,"file":"ToolNode.js","names":["#handleError"],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-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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"}
@@ -647,10 +647,18 @@ type CreateAgentParams<StructuredResponseType extends Record<string, any> = Reco
647
647
  * Determines the version of the graph to create.
648
648
  *
649
649
  * Can be one of
650
- * - `"v1"`: The tool node processes a single message. All tool calls in the message are
651
- * executed in parallel within the tool node.
652
- * - `"v2"`: The tool node processes a single tool call. Tool calls are distributed across
653
- * multiple instances of the tool node using the Send API.
650
+ * - `"v1"`: The tool node processes the full `AIMessage` containing all tool calls. All tool
651
+ * calls are executed concurrently via `Promise.all` inside a single graph node.
652
+ * **Choose v1** when your tools invoke sub-graphs or other long-running async work
653
+ * and you need true parallelism — the `Promise.all` approach is unaffected by
654
+ * LangGraph's per-task checkpoint serialisation.
655
+ *
656
+ * - `"v2"`: Each tool call is dispatched as an independent graph task using the Send API.
657
+ * Tasks are scheduled in parallel by LangGraph, but when tools invoke sub-graphs
658
+ * the underlying checkpoint writes can cause effective serialisation, making
659
+ * concurrent tool calls execute sequentially. v2 is the better choice when you
660
+ * need per-tool-call checkpointing, independent fault isolation, or `interrupt()`
661
+ * support inside individual tool calls.
654
662
  *
655
663
  * @default `"v2"`
656
664
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/agents/types.ts"],"mappings":";;;;;;;;;;;;;;;AAwFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAAiB,eAAA,mBACG,MAAA,gBAAsB,uBAAA,GACpC,MAAA,gBACA,uBAAA,iBACW,mBAAA,eACX,mBAAA,+BAEa,iBAAA,GAAoB,gBAAA,GACjC,iBAAA,GACA,gBAAA,+BACyB,eAAA,cAA6B,eAAA,6BACjC,UAAA,GAAa,UAAA,gBAClC,UAAA,GACA,UAAA;EAJA;EAQJ,QAAA,EAAU,SAAA;EAPmB;EAS7B,KAAA,EAAO,MAAA;EARP;EAUA,OAAA,EAAS,QAAA;EAV6B;EAYtC,UAAA,EAAY,WAAA;EAVR;EAYJ,KAAA,EAAO,MAAA;AAAA;;;;;UAOQ,sBAAA,SAA+B,eAAA;EAC9C,QAAA,EAAU,MAAA;EACV,KAAA;EACA,OAAA,EAAS,iBAAA;EACT,UAAA,WAAqB,eAAA;EACrB,KAAA,YAAiB,UAAA,GAAa,UAAA;AAAA;;;;;KAOpB,oBAAA,WAA+B,eAAA,IACzC,CAAA,SAAU,eAAA,gCACN,MAAA,mBAAyB,UAAA,GAAa,UAAA,MACpC,MAAA;;;;;KAQI,yBAAA,oBAA6C,eAAA,MACvD,CAAA,qCAEI,CAAA,iDACE,KAAA,SAAc,eAAA,GACZ,IAAA,kBAAsB,eAAA,kBAEf,oBAAA,CAAqB,KAAA,MACrB,yBAAA,CAA0B,IAAA,KAE/B,oBAAA,CAAqB,KAAA;;;;KAOrB,YAAA,+BACoB,UAAA,GAAa,UAAA,kCACd,eAAA,mBACd,WAAA,KAAgB,yBAAA,CAA0B,WAAA;;;;;KAMtD,qBAAA,MACH,CAAA,SAAU,qBAAA,iHAQN,qBAAA,CAAsB,YAAA,EAAc,WAAA,IACpC,CAAA,SAAU,uBAAA,0DAKR,qBAAA,CAAsB,YAAA,EAAc,WAAA,IACpC,qBAAA;;AArDR;;;;;;;;;;;;;;;KAuEY,qBAAA,qBACU,UAAA,GAAa,UAAA,eAE3B,CAAA,YAAa,CAAA;EAAY,IAAA;AAAA,IAC3B,CAAA,WACQ,qBAAA,CAAsB,CAAA;;AAjEpC;;;;;;;;;;;;;;;KAoFY,sBAAA,MAA4B,CAAA;EACtC,aAAA;AAAA,IAEE,KAAA,SAAc,eAAA,GACZ,KAAA,WAEF,CAAA,SAAU,eAAA,GACR,CAAA;;;;;;;;;;;;;;;;;AA1EN;KA8FY,cAAA,oBAEM,eAAA,IACd,sBAAA,CAAuB,CAAA,EAAG,CAAA;;;;;;;;;;KAWlB,kBAAA,MAAwB,cAAA,CAAe,CAAA;;;;;;;;;;AAzGsB;;;KAuH7D,qBAAA,MAA2B,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KA2B1C,eAAA,MAAqB,gBAAA,CAAiB,cAAA,CAAe,CAAA,cAC/D,qBAAA,CAAsB,cAAA,CAAe,CAAA;;;;;;;;;;AA3GvC;;;KAyHY,uBAAA,MAA6B,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;;;;;;;AAjGxD;;;;;KA4HY,iBAAA,MAAuB,gBAAA,CACjC,cAAA,CAAe,CAAA,gBAEf,uBAAA,CAAwB,cAAA,CAAe,CAAA;;;;;;;;;;KAW7B,oBAAA,MAA0B,cAAA,CAAe,CAAA;;;;;;;AA/GrD;;;KA0HY,eAAA,MAAqB,cAAA,CAAe,CAAA;AAAA,KAEpC,CAAA,UAAW,KAAA;;;;UAKN,SAAA;EAhIf;;;EAoIA,EAAA;EAlIyB;;;EAsIzB,KAAA,EAAO,MAAA;AAAA;AAAA,UAGQ,YAAA,2BACW,gBAAA,GAAmB,gBAAA;EAE7C,QAAA,EAAU,WAAA,CAAY,iBAAA;EACtB,aAAA,GAAgB,SAAA;EAlIa;;;;;AAc/B;;;EA6HE,MAAA,GAAS,YAAA;AAAA;;;;KAMC,SAAA,sBACW,mBAAA,4BACnB,gBAAA,CAAiB,YAAA;EACnB,QAAA,EAAU,QAAA;AAAA;;;;UAMK,UAAA;EAhHsB;;;EAoHrC,EAAA;EApHqB;;;EAwHrB,IAAA;EAzH+D;;;EA6H/D,IAAA,EAAM,MAAA;EA5HgC;;AAcxC;EAkHE,MAAA;EAlHiC;;;EAsHjC,KAAA;AAAA;;;AA3FF;UAiGiB,UAAA;EAjGY;;;EAqG3B,EAAA;EAlGuC;;;EAsGvC,MAAA;EAtGuB;;;EA0GvB,KAAA;AAAA;;;;KAMU,MAAA,sCAA4C,GAAA;;AArGxD;;UA0GiB,gBAAA;EA1GmC;;;EA8GlD,IAAA;EA9GoD;;AAWtD;EAuGE,IAAA,EAAM,MAAA;EAvGmB;;;EA2GzB,OAAA;EA3G8C;;;EA+G9C,MAAA;AAAA;AAAA,KAGU,iBAAA,gCACqB,MAAA,gBAAsB,MAAA,oCAChC,mBAAA,gDACC,iBAAA,GAAoB,gBAAA,GACxC,iBAAA,uBAEE,cAAA,CAAe,sBAAA,IACf,cAAA,cACA,kBAAA,CAAmB,sBAAA,IACnB,kBAAA,KACA,gBAAA,GACA,gBAAA,KACA,cAAA,GACA,iBAAA,CAAkB,sBAAA,IAClB,YAAA,CAAa,sBAAA,IACb,gBAAA,CAAiB,sBAAA,IACjB,uBAAA;EAhIiB;;AAKvB;;;;;;;;;;AAWA;;;;;;;;;;;EAyIE,KAAA,WAAgB,iBAAA;EAxIU;;;;;;;;;;;AAkB5B;;;;;;;;;;EA6IE,KAAA,IAAS,UAAA,GAAa,UAAA;EA3IpB;;;;;;AAOJ;;;;;;;;;;;;AA0BA;;;;;;;;;AAkBA;;;;;AAKA;;;;;;;;;;;AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;EAuIE,YAAA,YAAwB,aAAA;EAvEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqHtB,WAAA,GAAc,YAAA;EAAA;;;;;;;;;;;;;;;;;;;AAqJhB;;;;;;;;;;;;;;EAnHE,aAAA,GAAgB,aAAA;EAoHI;;;;EA/GpB,YAAA,GAAe,mBAAA;EAiHT;;;;EA5GN,KAAA,GAAQ,SAAA;EA6GD;AAGT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA1DE,cAAA,GAAiB,kBAAA;;;;;;;EAQjB,UAAA,YAAsB,eAAA;;;;EAKtB,IAAA;;;;;EAMA,WAAA;;;;;;;EAQA,gBAAA;;;;EAKA,MAAA,GAAS,WAAA;;;;;;;;;;;;EAaT,OAAA;AAAA;;;;KAMU,oBAAA,oBAAwC,cAAA,WAClD,CAAA,mBAAoB,cAAA,4BAChB,IAAA,kBAAsB,cAAA,UACpB,CAAA,GAAI,oBAAA,CAAqB,IAAA,IACzB,CAAA;AAAA,KAGI,mBAAA,4BACV,KAAA,SAAc,UAAA,mEASV,UAAA,CAAW,EAAA,EAAI,CAAA,EAAG,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA"}
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/agents/types.ts"],"mappings":"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"}
@@ -647,10 +647,18 @@ type CreateAgentParams<StructuredResponseType extends Record<string, any> = Reco
647
647
  * Determines the version of the graph to create.
648
648
  *
649
649
  * Can be one of
650
- * - `"v1"`: The tool node processes a single message. All tool calls in the message are
651
- * executed in parallel within the tool node.
652
- * - `"v2"`: The tool node processes a single tool call. Tool calls are distributed across
653
- * multiple instances of the tool node using the Send API.
650
+ * - `"v1"`: The tool node processes the full `AIMessage` containing all tool calls. All tool
651
+ * calls are executed concurrently via `Promise.all` inside a single graph node.
652
+ * **Choose v1** when your tools invoke sub-graphs or other long-running async work
653
+ * and you need true parallelism — the `Promise.all` approach is unaffected by
654
+ * LangGraph's per-task checkpoint serialisation.
655
+ *
656
+ * - `"v2"`: Each tool call is dispatched as an independent graph task using the Send API.
657
+ * Tasks are scheduled in parallel by LangGraph, but when tools invoke sub-graphs
658
+ * the underlying checkpoint writes can cause effective serialisation, making
659
+ * concurrent tool calls execute sequentially. v2 is the better choice when you
660
+ * need per-tool-call checkpointing, independent fault isolation, or `interrupt()`
661
+ * support inside individual tool calls.
654
662
  *
655
663
  * @default `"v2"`
656
664
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/agents/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/agents/types.ts"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langchain",
3
- "version": "1.2.33",
3
+ "version": "1.2.35",
4
4
  "description": "Typescript bindings for langchain",
5
5
  "author": "LangChain",
6
6
  "license": "MIT",
@@ -52,15 +52,15 @@
52
52
  "typescript": "~5.8.3",
53
53
  "vitest": "^3.2.4",
54
54
  "yaml": "^2.8.1",
55
- "@langchain/anthropic": "1.3.24",
55
+ "@langchain/anthropic": "1.3.25",
56
56
  "@langchain/cohere": "1.0.4",
57
- "@langchain/core": "^1.1.33",
57
+ "@langchain/core": "^1.1.34",
58
58
  "@langchain/eslint": "0.1.1",
59
59
  "@langchain/openai": "1.3.0",
60
60
  "@langchain/tsconfig": "0.0.1"
61
61
  },
62
62
  "peerDependencies": {
63
- "@langchain/core": "^1.1.33"
63
+ "@langchain/core": "^1.1.34"
64
64
  },
65
65
  "dependencies": {
66
66
  "@langchain/langgraph": "^1.1.2",