langchain 1.5.11 → 1.5.12

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,11 @@
1
1
  # langchain
2
2
 
3
+ ## 1.5.12
4
+
5
+ ### Patch Changes
6
+
7
+ - [#11682](https://github.com/langchain-ai/langchainjs/pull/11682) [`a8c336f`](https://github.com/langchain-ai/langchainjs/commit/a8c336f3c75b76e9d94236cb4a05f2b2f414cac6) Thanks [@casparb](https://github.com/casparb)! - Preserve ReactAgent callbacks when its compiled graph is extracted, without duplicate calls through the agent.
8
+
3
9
  ## 1.5.11
4
10
 
5
11
  ### Patch Changes
@@ -339,6 +339,12 @@ var ReactAgent = class ReactAgent {
339
339
  withConfig(config) {
340
340
  return new ReactAgent(this.options, (0, _langchain_core_runnables.mergeConfigs)(this.#defaultConfig, config));
341
341
  }
342
+ #getGraphConfig(config) {
343
+ return (0, _langchain_core_runnables.mergeConfigs)({
344
+ ...this.#defaultConfig,
345
+ callbacks: void 0
346
+ }, config);
347
+ }
342
348
  /**
343
349
  * Get possible edge destinations from model node.
344
350
  * @param toolClasses names of tools to call
@@ -612,7 +618,7 @@ var ReactAgent = class ReactAgent {
612
618
  * ```
613
619
  */
614
620
  async invoke(state, config) {
615
- const mergedConfig = (0, _langchain_core_runnables.mergeConfigs)(this.#defaultConfig, config);
621
+ const mergedConfig = this.#getGraphConfig(config);
616
622
  const initializedState = await this.#initializeMiddlewareStates(state, mergedConfig);
617
623
  return this.#graph.invoke(initializedState, mergedConfig);
618
624
  }
@@ -659,13 +665,13 @@ var ReactAgent = class ReactAgent {
659
665
  * ```
660
666
  */
661
667
  async stream(state, config) {
662
- const mergedConfig = (0, _langchain_core_runnables.mergeConfigs)(this.#defaultConfig, config);
668
+ const mergedConfig = this.#getGraphConfig(config);
663
669
  const initializedState = await this.#initializeMiddlewareStates(state, mergedConfig);
664
670
  return this.#graph.stream(initializedState, mergedConfig);
665
671
  }
666
672
  streamEvents(state, config, streamOptions) {
667
673
  if (config?.version !== "v3" || streamOptions != null) {
668
- const mergedConfig = (0, _langchain_core_runnables.mergeConfigs)(this.#defaultConfig, config);
674
+ const mergedConfig = this.#getGraphConfig(config);
669
675
  const version = config?.version === "v1" || config?.version === "v2" ? config.version : "v2";
670
676
  return this.#graph.streamEvents(state, {
671
677
  ...mergedConfig,
@@ -674,7 +680,7 @@ var ReactAgent = class ReactAgent {
674
680
  }
675
681
  return (async () => {
676
682
  const { transformers: callSiteTransformers, version: _version, ...restConfig } = config ?? {};
677
- const mergedConfig = (0, _langchain_core_runnables.mergeConfigs)(this.#defaultConfig, restConfig);
683
+ const mergedConfig = this.#getGraphConfig(restConfig);
678
684
  const initializedState = await this.#initializeMiddlewareStates(state, mergedConfig);
679
685
  return await this.#graph.streamEvents(initializedState, {
680
686
  ...mergedConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.cjs","names":["mergeConfigs","isClientTool","createAgentState","StateGraph","AgentNode","normalizeSystemPrompt","BeforeAgentNode","getHookConstraint","BeforeModelNode","AfterModelNode","AfterAgentNode","AGENT_NODE_NAME","ToolNode","wrapToolCall","TOOLS_NODE_NAME","END","START","parseJumpToTarget","createToolCallTransformer","createSubagentTransformer","toGraphDefaultConfig","builtInState","ToolMessage","AIMessage","Send","Command","initializeMiddlewareStates","agentConfig"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* oxlint-disable no-instanceof/no-instanceof */\n/* oxlint-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 type StreamTransformer,\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 {\n createToolCallTransformer,\n createSubagentTransformer,\n type AgentRunStream,\n type InferStreamExtensions,\n} from \"./transformers/index.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 AnyAgentMiddleware,\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\";\nimport { toGraphDefaultConfig } from \"./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 AnyAgentMiddleware[],\n readonly (ClientTool | ServerTool)[],\n ReadonlyArray<() => StreamTransformer<any>>\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: CompiledStateGraph<any, any, any, any, any, any, unknown>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\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 = mergeConfigs(defaultConfig ?? {}, {\n metadata: { ls_integration: \"langchain_create_agent\" },\n configurable: { ls_agent_type: \"root\" },\n });\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 hasDynamicStructuredResponse = Boolean(\n this.options.middleware?.some((middleware) => middleware.wrapModelCall)\n );\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined || hasDynamicStructuredResponse,\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: AgentMiddleware[] = [];\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 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 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 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 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(m);\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 with native + user-defined stream transformers\n */\n const middlewareStreamTransformers = (\n this.options.middleware ?? []\n ).flatMap((m) => m.streamTransformers ?? []);\n const compileTransformers = [\n /* built-in stream transformers */\n createToolCallTransformer([]),\n createSubagentTransformer([]),\n /* middleware stream transformers */\n ...middlewareStreamTransformers,\n /* user-defined stream transformers */\n ...(this.options.streamTransformers ?? []),\n ];\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 transformers: compileTransformers,\n }) as unknown as AgentGraph<Types>;\n\n /**\n * LangGraph API resolves exported agents by unwrapping ReactAgent to the\n * inner compiled graph (see langgraph-api load.utils `afterResolve`) and\n * calls streamEvents on that pregel directly. That path only sees config\n * baked into the graph via `.withConfig()`, not ReactAgent's #defaultConfig\n * merged at invoke/stream time — so propagate static defaults here.\n */\n const graphDefaultConfig = toGraphDefaultConfig(this.#defaultConfig);\n if (Object.keys(graphDefaultConfig).length > 0) {\n this.#graph = this.#graph.withConfig(graphDefaultConfig);\n }\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 * Executes the agent with the v3 streaming interface, returning an\n * {@link AgentRunStream} that provides ergonomic, typed projections for\n * messages, tool calls, and middleware events — without requiring knowledge\n * of Pregel channels, stream modes, or namespace routing.\n *\n * Pass `version: \"v3\"` to opt into this projection-oriented stream. Omitting\n * `version` preserves the legacy internal LangGraph event-stream behavior\n * for compatibility with LangGraph Platform integrations.\n *\n * This v3 stream is experimental and its API may change in future releases.\n * It will become the default in a future major release.\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 - Runtime configuration including:\n * @param config.version - Must be `\"v3\"` to use the {@link AgentRunStream}\n * interface. The default legacy event stream is maintained for internal\n * integrations and should not be used for new user-facing agent streaming.\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.\n * @param config.signal - An optional AbortSignal for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n * @param config.transformers - Additional call-site stream transformers. These\n * run after the built-in agent transformers and any transformers registered\n * at creation time via `createAgent({ streamTransformers })`.\n *\n * @returns A Promise that resolves to an {@link AgentRunStream} providing:\n * - `run.messages` — all AI message lifecycles with streaming `.text` and `.reasoning`\n * - `run.toolCalls` — individual tool call streams with `.input`, `.output`, `.status`\n * - `run.middleware` — middleware lifecycle events (before/after agent/model)\n * - `run.values` — state snapshots (async iterable + promise-like)\n * - `run.output` — final agent state when the run completes\n * - `run.subgraphs` — child subgraph run streams\n * - `run.extensions` — merged projections from user-supplied transformers\n *\n * @example\n * ```typescript\n * const run = await agent.streamEvents(\n * {\n * messages: [{ role: \"user\", content: \"What's the weather in Paris?\" }],\n * },\n * { version: \"v3\" }\n * );\n *\n * // Stream all messages\n * for await (const msg of run.messages) {\n * for await (const token of msg.text) {\n * process.stdout.write(token);\n * }\n * }\n *\n * // Observe tool calls\n * for await (const call of run.toolCalls) {\n * console.log(`Tool: ${call.name}`, call.input);\n * console.log(`Result:`, await call.output);\n * }\n *\n * // Get final state\n * const state = await run.output;\n * ```\n */\n streamEvents(\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 version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n }\n ): Promise<\n AgentRunStream<\n MergedAgentState<Types>,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\n >\n >;\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\n streamEvents(\n state: InvokeStateParameter<Types>,\n config:\n | (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 | undefined,\n streamOptions: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent>;\n\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?:\n | (InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n > & {\n version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n })\n | (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 ):\n | Promise<\n AgentRunStream<\n MergedAgentState<Types>,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\n >\n >\n | IterableReadableStream<StreamEvent> {\n if (config?.version !== \"v3\" || streamOptions != null) {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const version =\n config?.version === \"v1\" || config?.version === \"v2\"\n ? config.version\n : \"v2\";\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,\n },\n streamOptions\n );\n }\n\n return (async () => {\n type FullState = MergedAgentState<Types>;\n const agentConfig = config as InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n > & {\n version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n };\n\n const {\n transformers: callSiteTransformers,\n version: _version,\n ...restConfig\n } = agentConfig ?? {};\n const mergedConfig = mergeConfigs(this.#defaultConfig, restConfig);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return (await this.#graph.streamEvents(initializedState, {\n ...(mergedConfig as Record<string, any>),\n version: \"v3\",\n transformers: callSiteTransformers,\n })) as unknown as AgentRunStream<\n FullState,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\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 * @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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"}
1
+ {"version":3,"file":"ReactAgent.cjs","names":["mergeConfigs","isClientTool","createAgentState","StateGraph","AgentNode","normalizeSystemPrompt","BeforeAgentNode","getHookConstraint","BeforeModelNode","AfterModelNode","AfterAgentNode","AGENT_NODE_NAME","ToolNode","wrapToolCall","TOOLS_NODE_NAME","END","START","parseJumpToTarget","createToolCallTransformer","createSubagentTransformer","toGraphDefaultConfig","builtInState","ToolMessage","AIMessage","Send","Command","initializeMiddlewareStates","agentConfig"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* oxlint-disable no-instanceof/no-instanceof */\n/* oxlint-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 type StreamTransformer,\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 {\n createToolCallTransformer,\n createSubagentTransformer,\n type AgentRunStream,\n type InferStreamExtensions,\n} from \"./transformers/index.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 AnyAgentMiddleware,\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\";\nimport { toGraphDefaultConfig } from \"./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 AnyAgentMiddleware[],\n readonly (ClientTool | ServerTool)[],\n ReadonlyArray<() => StreamTransformer<any>>\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: CompiledStateGraph<any, any, any, any, any, any, unknown>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\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 = mergeConfigs(defaultConfig ?? {}, {\n metadata: { ls_integration: \"langchain_create_agent\" },\n configurable: { ls_agent_type: \"root\" },\n });\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 hasDynamicStructuredResponse = Boolean(\n this.options.middleware?.some((middleware) => middleware.wrapModelCall)\n );\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined || hasDynamicStructuredResponse,\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: AgentMiddleware[] = [];\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 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 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 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 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(m);\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 with native + user-defined stream transformers\n */\n const middlewareStreamTransformers = (\n this.options.middleware ?? []\n ).flatMap((m) => m.streamTransformers ?? []);\n const compileTransformers = [\n /* built-in stream transformers */\n createToolCallTransformer([]),\n createSubagentTransformer([]),\n /* middleware stream transformers */\n ...middlewareStreamTransformers,\n /* user-defined stream transformers */\n ...(this.options.streamTransformers ?? []),\n ];\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 transformers: compileTransformers,\n }) as unknown as AgentGraph<Types>;\n\n /**\n * LangGraph API resolves exported agents by unwrapping ReactAgent to the\n * inner compiled graph (see langgraph-api load.utils `afterResolve`) and\n * calls streamEvents on that pregel directly. That path only sees config\n * baked into the graph via `.withConfig()`, not ReactAgent's #defaultConfig\n * merged at invoke/stream time — so propagate static defaults here.\n */\n const graphDefaultConfig = toGraphDefaultConfig(this.#defaultConfig);\n if (Object.keys(graphDefaultConfig).length > 0) {\n this.#graph = this.#graph.withConfig(graphDefaultConfig);\n }\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 #getGraphConfig(config?: RunnableConfig) {\n return mergeConfigs(\n { ...this.#defaultConfig, callbacks: undefined },\n 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 = this.#getGraphConfig(config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig\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 = this.#getGraphConfig(config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n return this.#graph.stream(initializedState, mergedConfig) 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 * Executes the agent with the v3 streaming interface, returning an\n * {@link AgentRunStream} that provides ergonomic, typed projections for\n * messages, tool calls, and middleware events — without requiring knowledge\n * of Pregel channels, stream modes, or namespace routing.\n *\n * Pass `version: \"v3\"` to opt into this projection-oriented stream. Omitting\n * `version` preserves the legacy internal LangGraph event-stream behavior\n * for compatibility with LangGraph Platform integrations.\n *\n * This v3 stream is experimental and its API may change in future releases.\n * It will become the default in a future major release.\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 - Runtime configuration including:\n * @param config.version - Must be `\"v3\"` to use the {@link AgentRunStream}\n * interface. The default legacy event stream is maintained for internal\n * integrations and should not be used for new user-facing agent streaming.\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.\n * @param config.signal - An optional AbortSignal for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n * @param config.transformers - Additional call-site stream transformers. These\n * run after the built-in agent transformers and any transformers registered\n * at creation time via `createAgent({ streamTransformers })`.\n *\n * @returns A Promise that resolves to an {@link AgentRunStream} providing:\n * - `run.messages` — all AI message lifecycles with streaming `.text` and `.reasoning`\n * - `run.toolCalls` — individual tool call streams with `.input`, `.output`, `.status`\n * - `run.middleware` — middleware lifecycle events (before/after agent/model)\n * - `run.values` — state snapshots (async iterable + promise-like)\n * - `run.output` — final agent state when the run completes\n * - `run.subgraphs` — child subgraph run streams\n * - `run.extensions` — merged projections from user-supplied transformers\n *\n * @example\n * ```typescript\n * const run = await agent.streamEvents(\n * {\n * messages: [{ role: \"user\", content: \"What's the weather in Paris?\" }],\n * },\n * { version: \"v3\" }\n * );\n *\n * // Stream all messages\n * for await (const msg of run.messages) {\n * for await (const token of msg.text) {\n * process.stdout.write(token);\n * }\n * }\n *\n * // Observe tool calls\n * for await (const call of run.toolCalls) {\n * console.log(`Tool: ${call.name}`, call.input);\n * console.log(`Result:`, await call.output);\n * }\n *\n * // Get final state\n * const state = await run.output;\n * ```\n */\n streamEvents(\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 version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n }\n ): Promise<\n AgentRunStream<\n MergedAgentState<Types>,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\n >\n >;\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\n streamEvents(\n state: InvokeStateParameter<Types>,\n config:\n | (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 | undefined,\n streamOptions: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent>;\n\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?:\n | (InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n > & {\n version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n })\n | (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 ):\n | Promise<\n AgentRunStream<\n MergedAgentState<Types>,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\n >\n >\n | IterableReadableStream<StreamEvent> {\n if (config?.version !== \"v3\" || streamOptions != null) {\n const mergedConfig = this.#getGraphConfig(config);\n const version =\n config?.version === \"v1\" || config?.version === \"v2\"\n ? config.version\n : \"v2\";\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,\n },\n streamOptions\n );\n }\n\n return (async () => {\n type FullState = MergedAgentState<Types>;\n const agentConfig = config as InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n > & {\n version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n };\n\n const {\n transformers: callSiteTransformers,\n version: _version,\n ...restConfig\n } = agentConfig ?? {};\n const mergedConfig = this.#getGraphConfig(restConfig);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return (await this.#graph.streamEvents(initializedState, {\n ...(mergedConfig as Record<string, any>),\n version: \"v3\",\n transformers: callSiteTransformers,\n })) as unknown as AgentRunStream<\n FullState,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\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 * @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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.d.cts","names":[],"sources":["../../src/agents/ReactAgent.ts"],"mappings":";;;;;;;;;;;;;;;KAmGK,iBAAiB,cAAc,mBAAmB,iBACrD,mBAEC,0BAA0B,0BACvB,KACE,aAAa,iBAAiB,sBAAsB,+BAGtD,KACE,aAAa,iBAAiB,sBAAsB;EAGpD,oBAAoB;KAE1B,sBAAsB;KAEnB,qBAAqB,cAAc,oBACnC,UAAU,kBACT,2BAA2B,wBAC7B;KAGC,WAAW,cAAc,mBAAmB,uCAK/C,iBAAiB,QACjB,iBACE,yBAAyB,oBAAoB,mBACzC,mBACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiCK,WACX,cAAc,kBAAkB,gBAC9B,gCAEA,4BACS,gCACC,aAAa,eACvB,oBAAoB;;EAmBb,SAAS,kBACd,mBACA,gBACA;;;;;;0BAd4B;EAUhC,YACS,SAAS,kBACd,mBACA,gBACA,mBAEF,gBAAgB;;;;MAugBd,SAAS,WAAW;MAIpB,gBAAgB;MAIhB,aAAa,OAAO;MAIpB,SAAS;MAIT,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EA2BjB,WACE,QAAQ,KAAK,oDACZ,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6bR,OACJ,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,wBAChC,QAAA,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8DG,OACJ,oBAAoB,aAAa,0BACjC,4BACA,mDAEA,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aACA,YACA,aACD,QAAA,uBAAA,gBAAA,aAAA,YAAA,iBAAA,QAAA,iBAAA,kCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2FH,aACE,OAAO,qBAAqB,QAC5B,QAAQ,oBACN,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B;IAE/B;IACA,eAAe,oBAAoB;MAEpC,QACD,eACE,iBAAiB,QACjB,gBACA,sBAAsB;EAI1B,aACE,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aAAa;IAGT;KACN,gBAAgB,WAAW,+BAC1B,uBAAuB;EAE1B,aACE,OAAO,qBAAqB,QAC5B,SACK,oBACC,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aAAa;IAGT;kBAEV,eAAe,WAAW,+BACzB,uBAAuB;;;;;;;;;;;EA6GpB,eAAe;IACnB;IACA;IACA,aAAa;IACb;IACA;MACD,QAAA,WAAA;;;;;;;;;;;EAkBK,YAAY;IAChB;IACA;IACA,aAAa;IACb;IACA;MACD;;;;;;;;;;EAcD,cAAc,SAAS;;;;EAMvB,SAAS,QAAQ,gBAAgB,UAAU;;;;EAM3C,gBAAgB,QAAQ,gBAAgB,UAAU;;;;EAMlD,aAAa,oBAAoB;;;;EAMjC,kBAAkB,oBAAoB;;;;EAMtC,YACE,aAAa,yBACb,QAAQ,mCACR;;;;MAQE,WAAO"}
1
+ {"version":3,"file":"ReactAgent.d.cts","names":[],"sources":["../../src/agents/ReactAgent.ts"],"mappings":";;;;;;;;;;;;;;;KAmGK,iBAAiB,cAAc,mBAAmB,iBACrD,mBAEC,0BAA0B,0BACvB,KACE,aAAa,iBAAiB,sBAAsB,+BAGtD,KACE,aAAa,iBAAiB,sBAAsB;EAGpD,oBAAoB;KAE1B,sBAAsB;KAEnB,qBAAqB,cAAc,oBACnC,UAAU,kBACT,2BAA2B,wBAC7B;KAGC,WAAW,cAAc,mBAAmB,uCAK/C,iBAAiB,QACjB,iBACE,yBAAyB,oBAAoB,mBACzC,mBACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiCK,WACX,cAAc,kBAAkB,gBAC9B,gCAEA,4BACS,gCACC,aAAa,eACvB,oBAAoB;;EAmBb,SAAS,kBACd,mBACA,gBACA;;;;;;0BAd4B;EAUhC,YACS,SAAS,kBACd,mBACA,gBACA,mBAEF,gBAAgB;;;;MAugBd,SAAS,WAAW;MAIpB,gBAAgB;MAIhB,aAAa,OAAO;MAIpB,SAAS;MAIT,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EA2BjB,WACE,QAAQ,KAAK,oDACZ,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAocR,OACJ,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,wBAChC,QAAA,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyDG,OACJ,oBAAoB,aAAa,0BACjC,4BACA,mDAEA,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aACA,YACA,aACD,QAAA,uBAAA,gBAAA,aAAA,YAAA,iBAAA,QAAA,iBAAA,kCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwFH,aACE,OAAO,qBAAqB,QAC5B,QAAQ,oBACN,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B;IAE/B;IACA,eAAe,oBAAoB;MAEpC,QACD,eACE,iBAAiB,QACjB,gBACA,sBAAsB;EAI1B,aACE,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aAAa;IAGT;KACN,gBAAgB,WAAW,+BAC1B,uBAAuB;EAE1B,aACE,OAAO,qBAAqB,QAC5B,SACK,oBACC,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aAAa;IAGT;kBAEV,eAAe,WAAW,+BACzB,uBAAuB;;;;;;;;;;;EA6GpB,eAAe;IACnB;IACA;IACA,aAAa;IACb;IACA;MACD,QAAA,WAAA;;;;;;;;;;;EAkBK,YAAY;IAChB;IACA;IACA,aAAa;IACb;IACA;MACD;;;;;;;;;;EAcD,cAAc,SAAS;;;;EAMvB,SAAS,QAAQ,gBAAgB,UAAU;;;;EAM3C,gBAAgB,QAAQ,gBAAgB,UAAU;;;;EAMlD,aAAa,oBAAoB;;;;EAMjC,kBAAkB,oBAAoB;;;;EAMtC,YACE,aAAa,yBACb,QAAQ,mCACR;;;;MAQE,WAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.d.ts","names":[],"sources":["../../src/agents/ReactAgent.ts"],"mappings":";;;;;;;;;;;;;;;KAmGK,iBAAiB,cAAc,mBAAmB,iBACrD,mBAEC,0BAA0B,0BACvB,KACE,aAAa,iBAAiB,sBAAsB,+BAGtD,KACE,aAAa,iBAAiB,sBAAsB;EAGpD,oBAAoB;KAE1B,sBAAsB;KAEnB,qBAAqB,cAAc,oBACnC,UAAU,kBACT,2BAA2B,wBAC7B;KAGC,WAAW,cAAc,mBAAmB,uCAK/C,iBAAiB,QACjB,iBACE,yBAAyB,oBAAoB,mBACzC,mBACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiCK,WACX,cAAc,kBAAkB,gBAC9B,gCAEA,4BACS,gCACC,aAAa,eACvB,oBAAoB;;EAmBb,SAAS,kBACd,mBACA,gBACA;;;;;;0BAd4B;EAUhC,YACS,SAAS,kBACd,mBACA,gBACA,mBAEF,gBAAgB;;;;MAugBd,SAAS,WAAW;MAIpB,gBAAgB;MAIhB,aAAa,OAAO;MAIpB,SAAS;MAIT,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EA2BjB,WACE,QAAQ,KAAK,oDACZ,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6bR,OACJ,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,wBAChC,QAAA,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8DG,OACJ,oBAAoB,aAAa,0BACjC,4BACA,mDAEA,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aACA,YACA,aACD,QAAA,uBAAA,gBAAA,aAAA,YAAA,iBAAA,QAAA,iBAAA,kCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2FH,aACE,OAAO,qBAAqB,QAC5B,QAAQ,oBACN,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B;IAE/B;IACA,eAAe,oBAAoB;MAEpC,QACD,eACE,iBAAiB,QACjB,gBACA,sBAAsB;EAI1B,aACE,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aAAa;IAGT;KACN,gBAAgB,WAAW,+BAC1B,uBAAuB;EAE1B,aACE,OAAO,qBAAqB,QAC5B,SACK,oBACC,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aAAa;IAGT;kBAEV,eAAe,WAAW,+BACzB,uBAAuB;;;;;;;;;;;EA6GpB,eAAe;IACnB;IACA;IACA,aAAa;IACb;IACA;MACD,QAAA,WAAA;;;;;;;;;;;EAkBK,YAAY;IAChB;IACA;IACA,aAAa;IACb;IACA;MACD;;;;;;;;;;EAcD,cAAc,SAAS;;;;EAMvB,SAAS,QAAQ,gBAAgB,UAAU;;;;EAM3C,gBAAgB,QAAQ,gBAAgB,UAAU;;;;EAMlD,aAAa,oBAAoB;;;;EAMjC,kBAAkB,oBAAoB;;;;EAMtC,YACE,aAAa,yBACb,QAAQ,mCACR;;;;MAQE,WAAO"}
1
+ {"version":3,"file":"ReactAgent.d.ts","names":[],"sources":["../../src/agents/ReactAgent.ts"],"mappings":";;;;;;;;;;;;;;;KAmGK,iBAAiB,cAAc,mBAAmB,iBACrD,mBAEC,0BAA0B,0BACvB,KACE,aAAa,iBAAiB,sBAAsB,+BAGtD,KACE,aAAa,iBAAiB,sBAAsB;EAGpD,oBAAoB;KAE1B,sBAAsB;KAEnB,qBAAqB,cAAc,oBACnC,UAAU,kBACT,2BAA2B,wBAC7B;KAGC,WAAW,cAAc,mBAAmB,uCAK/C,iBAAiB,QACjB,iBACE,yBAAyB,oBAAoB,mBACzC,mBACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiCK,WACX,cAAc,kBAAkB,gBAC9B,gCAEA,4BACS,gCACC,aAAa,eACvB,oBAAoB;;EAmBb,SAAS,kBACd,mBACA,gBACA;;;;;;0BAd4B;EAUhC,YACS,SAAS,kBACd,mBACA,gBACA,mBAEF,gBAAgB;;;;MAugBd,SAAS,WAAW;MAIpB,gBAAgB;MAIhB,aAAa,OAAO;MAIpB,SAAS;MAIT,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EA2BjB,WACE,QAAQ,KAAK,oDACZ,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAocR,OACJ,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,wBAChC,QAAA,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyDG,OACJ,oBAAoB,aAAa,0BACjC,4BACA,mDAEA,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aACA,YACA,aACD,QAAA,uBAAA,gBAAA,aAAA,YAAA,iBAAA,QAAA,iBAAA,kCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwFH,aACE,OAAO,qBAAqB,QAC5B,QAAQ,oBACN,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B;IAE/B;IACA,eAAe,oBAAoB;MAEpC,QACD,eACE,iBAAiB,QACjB,gBACA,sBAAsB;EAI1B,aACE,OAAO,qBAAqB,QAC5B,SAAS,oBACP,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aAAa;IAGT;KACN,gBAAgB,WAAW,+BAC1B,uBAAuB;EAE1B,aACE,OAAO,qBAAqB,QAC5B,SACK,oBACC,kBACE,yBAAyB,oBAAoB,mBACzC,mBACA,qBAEJ,6BAA6B,sBAC/B,aAAa;IAGT;kBAEV,eAAe,WAAW,+BACzB,uBAAuB;;;;;;;;;;;EA6GpB,eAAe;IACnB;IACA;IACA,aAAa;IACb;IACA;MACD,QAAA,WAAA;;;;;;;;;;;EAkBK,YAAY;IAChB;IACA;IACA,aAAa;IACb;IACA;MACD;;;;;;;;;;EAcD,cAAc,SAAS;;;;EAMvB,SAAS,QAAQ,gBAAgB,UAAU;;;;EAM3C,gBAAgB,QAAQ,gBAAgB,UAAU;;;;EAMlD,aAAa,oBAAoB;;;;EAMjC,kBAAkB,oBAAoB;;;;EAMtC,YACE,aAAa,yBACb,QAAQ,mCACR;;;;MAQE,WAAO"}
@@ -339,6 +339,12 @@ var ReactAgent = class ReactAgent {
339
339
  withConfig(config) {
340
340
  return new ReactAgent(this.options, mergeConfigs(this.#defaultConfig, config));
341
341
  }
342
+ #getGraphConfig(config) {
343
+ return mergeConfigs({
344
+ ...this.#defaultConfig,
345
+ callbacks: void 0
346
+ }, config);
347
+ }
342
348
  /**
343
349
  * Get possible edge destinations from model node.
344
350
  * @param toolClasses names of tools to call
@@ -612,7 +618,7 @@ var ReactAgent = class ReactAgent {
612
618
  * ```
613
619
  */
614
620
  async invoke(state, config) {
615
- const mergedConfig = mergeConfigs(this.#defaultConfig, config);
621
+ const mergedConfig = this.#getGraphConfig(config);
616
622
  const initializedState = await this.#initializeMiddlewareStates(state, mergedConfig);
617
623
  return this.#graph.invoke(initializedState, mergedConfig);
618
624
  }
@@ -659,13 +665,13 @@ var ReactAgent = class ReactAgent {
659
665
  * ```
660
666
  */
661
667
  async stream(state, config) {
662
- const mergedConfig = mergeConfigs(this.#defaultConfig, config);
668
+ const mergedConfig = this.#getGraphConfig(config);
663
669
  const initializedState = await this.#initializeMiddlewareStates(state, mergedConfig);
664
670
  return this.#graph.stream(initializedState, mergedConfig);
665
671
  }
666
672
  streamEvents(state, config, streamOptions) {
667
673
  if (config?.version !== "v3" || streamOptions != null) {
668
- const mergedConfig = mergeConfigs(this.#defaultConfig, config);
674
+ const mergedConfig = this.#getGraphConfig(config);
669
675
  const version = config?.version === "v1" || config?.version === "v2" ? config.version : "v2";
670
676
  return this.#graph.streamEvents(state, {
671
677
  ...mergedConfig,
@@ -674,7 +680,7 @@ var ReactAgent = class ReactAgent {
674
680
  }
675
681
  return (async () => {
676
682
  const { transformers: callSiteTransformers, version: _version, ...restConfig } = config ?? {};
677
- const mergedConfig = mergeConfigs(this.#defaultConfig, restConfig);
683
+ const mergedConfig = this.#getGraphConfig(restConfig);
678
684
  const initializedState = await this.#initializeMiddlewareStates(state, mergedConfig);
679
685
  return await this.#graph.streamEvents(initializedState, {
680
686
  ...mergedConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.js","names":["builtInState","agentConfig"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* oxlint-disable no-instanceof/no-instanceof */\n/* oxlint-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 type StreamTransformer,\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 {\n createToolCallTransformer,\n createSubagentTransformer,\n type AgentRunStream,\n type InferStreamExtensions,\n} from \"./transformers/index.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 AnyAgentMiddleware,\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\";\nimport { toGraphDefaultConfig } from \"./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 AnyAgentMiddleware[],\n readonly (ClientTool | ServerTool)[],\n ReadonlyArray<() => StreamTransformer<any>>\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: CompiledStateGraph<any, any, any, any, any, any, unknown>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\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 = mergeConfigs(defaultConfig ?? {}, {\n metadata: { ls_integration: \"langchain_create_agent\" },\n configurable: { ls_agent_type: \"root\" },\n });\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 hasDynamicStructuredResponse = Boolean(\n this.options.middleware?.some((middleware) => middleware.wrapModelCall)\n );\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined || hasDynamicStructuredResponse,\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: AgentMiddleware[] = [];\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 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 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 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 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(m);\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 with native + user-defined stream transformers\n */\n const middlewareStreamTransformers = (\n this.options.middleware ?? []\n ).flatMap((m) => m.streamTransformers ?? []);\n const compileTransformers = [\n /* built-in stream transformers */\n createToolCallTransformer([]),\n createSubagentTransformer([]),\n /* middleware stream transformers */\n ...middlewareStreamTransformers,\n /* user-defined stream transformers */\n ...(this.options.streamTransformers ?? []),\n ];\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 transformers: compileTransformers,\n }) as unknown as AgentGraph<Types>;\n\n /**\n * LangGraph API resolves exported agents by unwrapping ReactAgent to the\n * inner compiled graph (see langgraph-api load.utils `afterResolve`) and\n * calls streamEvents on that pregel directly. That path only sees config\n * baked into the graph via `.withConfig()`, not ReactAgent's #defaultConfig\n * merged at invoke/stream time — so propagate static defaults here.\n */\n const graphDefaultConfig = toGraphDefaultConfig(this.#defaultConfig);\n if (Object.keys(graphDefaultConfig).length > 0) {\n this.#graph = this.#graph.withConfig(graphDefaultConfig);\n }\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 * Executes the agent with the v3 streaming interface, returning an\n * {@link AgentRunStream} that provides ergonomic, typed projections for\n * messages, tool calls, and middleware events — without requiring knowledge\n * of Pregel channels, stream modes, or namespace routing.\n *\n * Pass `version: \"v3\"` to opt into this projection-oriented stream. Omitting\n * `version` preserves the legacy internal LangGraph event-stream behavior\n * for compatibility with LangGraph Platform integrations.\n *\n * This v3 stream is experimental and its API may change in future releases.\n * It will become the default in a future major release.\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 - Runtime configuration including:\n * @param config.version - Must be `\"v3\"` to use the {@link AgentRunStream}\n * interface. The default legacy event stream is maintained for internal\n * integrations and should not be used for new user-facing agent streaming.\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.\n * @param config.signal - An optional AbortSignal for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n * @param config.transformers - Additional call-site stream transformers. These\n * run after the built-in agent transformers and any transformers registered\n * at creation time via `createAgent({ streamTransformers })`.\n *\n * @returns A Promise that resolves to an {@link AgentRunStream} providing:\n * - `run.messages` — all AI message lifecycles with streaming `.text` and `.reasoning`\n * - `run.toolCalls` — individual tool call streams with `.input`, `.output`, `.status`\n * - `run.middleware` — middleware lifecycle events (before/after agent/model)\n * - `run.values` — state snapshots (async iterable + promise-like)\n * - `run.output` — final agent state when the run completes\n * - `run.subgraphs` — child subgraph run streams\n * - `run.extensions` — merged projections from user-supplied transformers\n *\n * @example\n * ```typescript\n * const run = await agent.streamEvents(\n * {\n * messages: [{ role: \"user\", content: \"What's the weather in Paris?\" }],\n * },\n * { version: \"v3\" }\n * );\n *\n * // Stream all messages\n * for await (const msg of run.messages) {\n * for await (const token of msg.text) {\n * process.stdout.write(token);\n * }\n * }\n *\n * // Observe tool calls\n * for await (const call of run.toolCalls) {\n * console.log(`Tool: ${call.name}`, call.input);\n * console.log(`Result:`, await call.output);\n * }\n *\n * // Get final state\n * const state = await run.output;\n * ```\n */\n streamEvents(\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 version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n }\n ): Promise<\n AgentRunStream<\n MergedAgentState<Types>,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\n >\n >;\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\n streamEvents(\n state: InvokeStateParameter<Types>,\n config:\n | (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 | undefined,\n streamOptions: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent>;\n\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?:\n | (InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n > & {\n version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n })\n | (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 ):\n | Promise<\n AgentRunStream<\n MergedAgentState<Types>,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\n >\n >\n | IterableReadableStream<StreamEvent> {\n if (config?.version !== \"v3\" || streamOptions != null) {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const version =\n config?.version === \"v1\" || config?.version === \"v2\"\n ? config.version\n : \"v2\";\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,\n },\n streamOptions\n );\n }\n\n return (async () => {\n type FullState = MergedAgentState<Types>;\n const agentConfig = config as InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n > & {\n version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n };\n\n const {\n transformers: callSiteTransformers,\n version: _version,\n ...restConfig\n } = agentConfig ?? {};\n const mergedConfig = mergeConfigs(this.#defaultConfig, restConfig);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return (await this.#graph.streamEvents(initializedState, {\n ...(mergedConfig as Record<string, any>),\n version: \"v3\",\n transformers: callSiteTransformers,\n })) as unknown as AgentRunStream<\n FullState,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\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 * @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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"}
1
+ {"version":3,"file":"ReactAgent.js","names":["builtInState","agentConfig"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* oxlint-disable no-instanceof/no-instanceof */\n/* oxlint-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 type StreamTransformer,\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 {\n createToolCallTransformer,\n createSubagentTransformer,\n type AgentRunStream,\n type InferStreamExtensions,\n} from \"./transformers/index.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 AnyAgentMiddleware,\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\";\nimport { toGraphDefaultConfig } from \"./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 AnyAgentMiddleware[],\n readonly (ClientTool | ServerTool)[],\n ReadonlyArray<() => StreamTransformer<any>>\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: CompiledStateGraph<any, any, any, any, any, any, unknown>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\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 = mergeConfigs(defaultConfig ?? {}, {\n metadata: { ls_integration: \"langchain_create_agent\" },\n configurable: { ls_agent_type: \"root\" },\n });\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 hasDynamicStructuredResponse = Boolean(\n this.options.middleware?.some((middleware) => middleware.wrapModelCall)\n );\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined || hasDynamicStructuredResponse,\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: AgentMiddleware[] = [];\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 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 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 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 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(m);\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 with native + user-defined stream transformers\n */\n const middlewareStreamTransformers = (\n this.options.middleware ?? []\n ).flatMap((m) => m.streamTransformers ?? []);\n const compileTransformers = [\n /* built-in stream transformers */\n createToolCallTransformer([]),\n createSubagentTransformer([]),\n /* middleware stream transformers */\n ...middlewareStreamTransformers,\n /* user-defined stream transformers */\n ...(this.options.streamTransformers ?? []),\n ];\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 transformers: compileTransformers,\n }) as unknown as AgentGraph<Types>;\n\n /**\n * LangGraph API resolves exported agents by unwrapping ReactAgent to the\n * inner compiled graph (see langgraph-api load.utils `afterResolve`) and\n * calls streamEvents on that pregel directly. That path only sees config\n * baked into the graph via `.withConfig()`, not ReactAgent's #defaultConfig\n * merged at invoke/stream time — so propagate static defaults here.\n */\n const graphDefaultConfig = toGraphDefaultConfig(this.#defaultConfig);\n if (Object.keys(graphDefaultConfig).length > 0) {\n this.#graph = this.#graph.withConfig(graphDefaultConfig);\n }\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 #getGraphConfig(config?: RunnableConfig) {\n return mergeConfigs(\n { ...this.#defaultConfig, callbacks: undefined },\n 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 = this.#getGraphConfig(config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig\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 = this.#getGraphConfig(config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n return this.#graph.stream(initializedState, mergedConfig) 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 * Executes the agent with the v3 streaming interface, returning an\n * {@link AgentRunStream} that provides ergonomic, typed projections for\n * messages, tool calls, and middleware events — without requiring knowledge\n * of Pregel channels, stream modes, or namespace routing.\n *\n * Pass `version: \"v3\"` to opt into this projection-oriented stream. Omitting\n * `version` preserves the legacy internal LangGraph event-stream behavior\n * for compatibility with LangGraph Platform integrations.\n *\n * This v3 stream is experimental and its API may change in future releases.\n * It will become the default in a future major release.\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 - Runtime configuration including:\n * @param config.version - Must be `\"v3\"` to use the {@link AgentRunStream}\n * interface. The default legacy event stream is maintained for internal\n * integrations and should not be used for new user-facing agent streaming.\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.\n * @param config.signal - An optional AbortSignal for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n * @param config.transformers - Additional call-site stream transformers. These\n * run after the built-in agent transformers and any transformers registered\n * at creation time via `createAgent({ streamTransformers })`.\n *\n * @returns A Promise that resolves to an {@link AgentRunStream} providing:\n * - `run.messages` — all AI message lifecycles with streaming `.text` and `.reasoning`\n * - `run.toolCalls` — individual tool call streams with `.input`, `.output`, `.status`\n * - `run.middleware` — middleware lifecycle events (before/after agent/model)\n * - `run.values` — state snapshots (async iterable + promise-like)\n * - `run.output` — final agent state when the run completes\n * - `run.subgraphs` — child subgraph run streams\n * - `run.extensions` — merged projections from user-supplied transformers\n *\n * @example\n * ```typescript\n * const run = await agent.streamEvents(\n * {\n * messages: [{ role: \"user\", content: \"What's the weather in Paris?\" }],\n * },\n * { version: \"v3\" }\n * );\n *\n * // Stream all messages\n * for await (const msg of run.messages) {\n * for await (const token of msg.text) {\n * process.stdout.write(token);\n * }\n * }\n *\n * // Observe tool calls\n * for await (const call of run.toolCalls) {\n * console.log(`Tool: ${call.name}`, call.input);\n * console.log(`Result:`, await call.output);\n * }\n *\n * // Get final state\n * const state = await run.output;\n * ```\n */\n streamEvents(\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 version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n }\n ): Promise<\n AgentRunStream<\n MergedAgentState<Types>,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\n >\n >;\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\n streamEvents(\n state: InvokeStateParameter<Types>,\n config:\n | (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 | undefined,\n streamOptions: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent>;\n\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?:\n | (InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n > & {\n version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n })\n | (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 ):\n | Promise<\n AgentRunStream<\n MergedAgentState<Types>,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\n >\n >\n | IterableReadableStream<StreamEvent> {\n if (config?.version !== \"v3\" || streamOptions != null) {\n const mergedConfig = this.#getGraphConfig(config);\n const version =\n config?.version === \"v1\" || config?.version === \"v2\"\n ? config.version\n : \"v2\";\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,\n },\n streamOptions\n );\n }\n\n return (async () => {\n type FullState = MergedAgentState<Types>;\n const agentConfig = config as InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n > & {\n version: \"v3\";\n transformers?: ReadonlyArray<() => StreamTransformer<any>>;\n };\n\n const {\n transformers: callSiteTransformers,\n version: _version,\n ...restConfig\n } = agentConfig ?? {};\n const mergedConfig = this.#getGraphConfig(restConfig);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return (await this.#graph.streamEvents(initializedState, {\n ...(mergedConfig as Record<string, any>),\n version: \"v3\",\n transformers: callSiteTransformers,\n })) as unknown as AgentRunStream<\n FullState,\n Types[\"Tools\"],\n InferStreamExtensions<Types[\"StreamTransformers\"]>\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 * @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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"}
@@ -395,6 +395,7 @@ function wrapToolCall(middleware) {
395
395
  * LangGraph API loading, which unwraps ReactAgent to `.graph` before execution.
396
396
  */
397
397
  const GRAPH_DEFAULT_CONFIG_KEYS = [
398
+ "callbacks",
398
399
  "tags",
399
400
  "metadata",
400
401
  "runName",
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","names":["StateSchema","isInteropZodSchema","interopParse","AIMessage","AIMessageChunk","Runnable","isBaseChatModel","RunnableBinding","RunnableSequence","isConfigurableModel","MultipleToolsBoundError","SystemMessage","ToolMessage","isCommand","MiddlewareError"],"sources":["../../src/agents/utils.ts"],"sourcesContent":["import {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n BaseMessageLike,\n SystemMessage,\n MessageContent,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport { isCommand, StateSchema } from \"@langchain/langgraph\";\nimport {\n type InteropZodObject,\n interopParse,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n BaseChatModel,\n type BaseChatModelCallOptions,\n} from \"@langchain/core/language_models/chat_models\";\nimport { BaseLanguageModelInput } from \"@langchain/core/language_models/base\";\nimport {\n Runnable,\n RunnableLike,\n RunnableConfig,\n RunnableSequence,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\n\nimport {\n isBaseChatModel,\n isConfigurableModel,\n type AgentLanguageModelLike as LanguageModelLike,\n} from \"./model.js\";\nimport { MultipleToolsBoundError, MiddlewareError } from \"./errors.js\";\nimport type { AgentBuiltInState } from \"./runtime.js\";\nimport type {\n ToolCallHandler,\n AnyAgentMiddleware,\n ToolCallRequest,\n WrapToolCallHook,\n} from \"./middleware/types.js\";\n\nconst NAME_PATTERN = /<name>(.*?)<\\/name>/s;\nconst CONTENT_PATTERN = /<content>(.*?)<\\/content>/s;\n\n/**\n * Parse middleware state from the full agent state based on the middleware's stateSchema.\n *\n * Handles two types of state schemas:\n * 1. Zod schemas (v3 or v4) - parsed using interopParse\n * 2. LangGraph StateSchema - extracts only the keys defined in `fields`\n *\n * @param stateSchema - The middleware's state schema (Zod or LangGraph StateSchema)\n * @param state - The full agent state to parse from\n * @returns Parsed state containing only the keys defined in the schema\n */\nfunction parseMiddlewareState(\n stateSchema: unknown,\n state: Record<string, unknown>\n): Record<string, unknown> {\n // Handle LangGraph StateSchema (has `fields` property)\n if (StateSchema.isInstance(stateSchema)) {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(stateSchema.fields)) {\n if (key in state) {\n result[key] = state[key];\n }\n }\n return result;\n }\n\n // Handle Zod schemas using interopParse\n if (isInteropZodSchema(stateSchema)) {\n return interopParse(stateSchema as InteropZodObject, state);\n }\n\n throw new Error(`Invalid state schema type: ${typeof stateSchema}`);\n}\n\nexport type AgentNameMode = \"inline\";\n\n/**\n * Attach formatted agent names to the messages passed to and from a language model.\n *\n * This is useful for making a message history with multiple agents more coherent.\n *\n * NOTE: agent name is consumed from the message.name field.\n * If you're using an agent built with createAgent, name is automatically set.\n * If you're building a custom agent, make sure to set the name on the AI message returned by the LLM.\n *\n * @param message - Message to add agent name formatting to\n * @returns Message with agent name formatting\n *\n * @internal\n */\nexport function _addInlineAgentName<T extends BaseMessageLike>(\n message: T\n): T | AIMessage {\n if (!AIMessage.isInstance(message) || AIMessageChunk.isInstance(message)) {\n return message;\n }\n\n if (!message.name) {\n return message;\n }\n\n const { name } = message;\n\n if (typeof message.content === \"string\") {\n return new AIMessage({\n ...message.lc_kwargs,\n content: `<name>${name}</name><content>${message.content}</content>`,\n name: undefined,\n });\n }\n\n const updatedContent = [];\n let textBlockCount = 0;\n\n for (const contentBlock of message.content) {\n if (typeof contentBlock === \"string\") {\n textBlockCount += 1;\n updatedContent.push(\n `<name>${name}</name><content>${contentBlock}</content>`\n );\n } else if (\n typeof contentBlock === \"object\" &&\n \"type\" in contentBlock &&\n contentBlock.type === \"text\"\n ) {\n textBlockCount += 1;\n updatedContent.push({\n ...contentBlock,\n text: `<name>${name}</name><content>${contentBlock.text}</content>`,\n });\n } else {\n updatedContent.push(contentBlock);\n }\n }\n\n if (!textBlockCount) {\n updatedContent.unshift({\n type: \"text\",\n text: `<name>${name}</name><content></content>`,\n });\n }\n return new AIMessage({\n ...message.lc_kwargs,\n content: updatedContent as MessageContent,\n name: undefined,\n });\n}\n\n/**\n * Remove explicit name and content XML tags from the AI message content.\n *\n * Examples:\n *\n * @example\n * ```typescript\n * removeInlineAgentName(new AIMessage({ content: \"<name>assistant</name><content>Hello</content>\", name: \"assistant\" }))\n * // AIMessage with content: \"Hello\"\n *\n * removeInlineAgentName(new AIMessage({ content: [{type: \"text\", text: \"<name>assistant</name><content>Hello</content>\"}], name: \"assistant\" }))\n * // AIMessage with content: [{type: \"text\", text: \"Hello\"}]\n * ```\n *\n * @internal\n */\nexport function _removeInlineAgentName<T extends BaseMessage>(message: T): T {\n if (!AIMessage.isInstance(message) || !message.content) {\n return message;\n }\n\n let updatedContent: MessageContent = [];\n let updatedName: string | undefined;\n\n if (Array.isArray(message.content)) {\n updatedContent = message.content\n .filter((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n // don't include empty content blocks that were added because there was no text block to modify\n if (nameMatch && (!contentMatch || contentMatch[1] === \"\")) {\n // capture name from text block\n updatedName = nameMatch[1];\n return false;\n }\n return true;\n }\n return true;\n })\n .map((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return block;\n }\n\n // capture name from text block\n updatedName = nameMatch[1];\n\n return {\n ...block,\n text: contentMatch[1],\n };\n }\n return block;\n });\n } else {\n const content = message.content as string;\n const nameMatch = content.match(NAME_PATTERN);\n const contentMatch = content.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return message;\n }\n\n updatedName = nameMatch[1];\n updatedContent = contentMatch[1];\n }\n\n return new AIMessage({\n ...(Object.keys(message.lc_kwargs ?? {}).length > 0\n ? message.lc_kwargs\n : message),\n content: updatedContent,\n name: updatedName,\n }) as T;\n}\n\nexport function isClientTool(\n tool: ClientTool | ServerTool\n): tool is ClientTool {\n return Runnable.isRunnable(tool);\n}\n\n/**\n * Helper function to check if a language model has a bindTools method.\n * @param llm - The language model to check if it has a bindTools method.\n * @returns True if the language model has a bindTools method, false otherwise.\n */\nfunction _isChatModelWithBindTools(\n llm: LanguageModelLike\n): llm is BaseChatModel & Required<Pick<BaseChatModel, \"bindTools\">> {\n if (!isBaseChatModel(llm)) return false;\n return \"bindTools\" in llm && typeof llm.bindTools === \"function\";\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nconst _simpleBindTools = (\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n) => {\n if (_isChatModelWithBindTools(llm)) {\n return llm.bindTools(toolClasses, options);\n }\n\n if (\n RunnableBinding.isRunnableBinding(llm) &&\n _isChatModelWithBindTools(llm.bound)\n ) {\n const newBound = llm.bound.bindTools(toolClasses, options);\n\n if (RunnableBinding.isRunnableBinding(newBound)) {\n return new RunnableBinding({\n bound: newBound.bound,\n config: { ...llm.config, ...newBound.config },\n kwargs: { ...llm.kwargs, ...newBound.kwargs },\n configFactories: newBound.configFactories ?? llm.configFactories,\n });\n }\n\n return new RunnableBinding({\n bound: newBound,\n config: llm.config,\n kwargs: llm.kwargs,\n configFactories: llm.configFactories,\n });\n }\n\n return null;\n};\n\n/**\n * Check if the LLM already has bound tools and throw if it does.\n *\n * @param llm - The LLM to check.\n * @returns void\n */\nexport function validateLLMHasNoBoundTools(llm: LanguageModelLike): void {\n /**\n * If llm is a function, we can't validate until runtime, so skip\n */\n if (typeof llm === \"function\") {\n return;\n }\n\n let model = llm;\n\n /**\n * If model is a RunnableSequence, find a RunnableBinding in its steps\n */\n if (RunnableSequence.isRunnableSequence(model)) {\n model =\n model.steps.find((step: RunnableLike) =>\n RunnableBinding.isRunnableBinding(step)\n ) || model;\n }\n\n /**\n * If model is configurable, get the underlying model\n */\n if (isConfigurableModel(model)) {\n /**\n * Can't validate async model retrieval in constructor\n */\n return;\n }\n\n /**\n * Check if model is a RunnableBinding with bound tools\n */\n if (RunnableBinding.isRunnableBinding(model)) {\n const hasToolsInKwargs =\n model.kwargs != null &&\n typeof model.kwargs === \"object\" &&\n \"tools\" in model.kwargs &&\n Array.isArray(model.kwargs.tools) &&\n model.kwargs.tools.length > 0;\n\n const hasToolsInConfig =\n model.config != null &&\n typeof model.config === \"object\" &&\n \"tools\" in model.config &&\n Array.isArray(model.config.tools) &&\n model.config.tools.length > 0;\n\n if (hasToolsInKwargs || hasToolsInConfig) {\n throw new MultipleToolsBoundError();\n }\n }\n\n /**\n * Also check if model has tools property directly (e.g., FakeToolCallingModel)\n */\n if (\n \"tools\" in model &&\n model.tools !== undefined &&\n Array.isArray(model.tools) &&\n model.tools.length > 0\n ) {\n throw new MultipleToolsBoundError();\n }\n}\n\n/**\n * Check if the last message in the messages array has tool calls.\n *\n * @param messages - The messages to check.\n * @returns True if the last message has tool calls, false otherwise.\n */\nexport function hasToolCalls(message?: BaseMessage): boolean {\n return Boolean(\n AIMessage.isInstance(message) &&\n message.tool_calls &&\n message.tool_calls.length > 0\n );\n}\n\n/**\n * Normalizes a system prompt to a SystemMessage object.\n * If it's already a SystemMessage, returns it as-is.\n * If it's a string, converts it to a SystemMessage.\n * If it's undefined, creates an empty system message so it is easier to append to it later.\n */\nexport function normalizeSystemPrompt(\n systemPrompt?: string | SystemMessage\n): SystemMessage {\n if (systemPrompt == null) {\n return new SystemMessage(\"\");\n }\n if (SystemMessage.isInstance(systemPrompt)) {\n return systemPrompt;\n }\n if (typeof systemPrompt === \"string\") {\n return new SystemMessage({\n content: [{ type: \"text\", text: systemPrompt }],\n });\n }\n throw new Error(\n `Invalid systemPrompt type: expected string or SystemMessage, got ${typeof systemPrompt}`\n );\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nexport async function bindTools(\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n): Promise<\n | RunnableSequence<unknown, unknown>\n | RunnableBinding<unknown, unknown, RunnableConfig<Record<string, unknown>>>\n | Runnable<BaseLanguageModelInput, AIMessageChunk, BaseChatModelCallOptions>\n> {\n const model = _simpleBindTools(llm, toolClasses, options);\n if (model) return model;\n\n if (isConfigurableModel(llm)) {\n const model = _simpleBindTools(\n await llm._getModelInstance(),\n toolClasses,\n options\n );\n if (model) return model;\n }\n\n if (RunnableSequence.isRunnableSequence(llm)) {\n const modelStep = llm.steps.findIndex(\n (step) =>\n RunnableBinding.isRunnableBinding(step) ||\n isBaseChatModel(step) ||\n isConfigurableModel(step)\n );\n\n if (modelStep >= 0) {\n const model = _simpleBindTools(\n llm.steps[modelStep],\n toolClasses,\n options\n );\n if (model) {\n const nextSteps: unknown[] = llm.steps.slice();\n nextSteps.splice(modelStep, 1, model);\n\n return RunnableSequence.from(\n nextSteps as [RunnableLike, ...RunnableLike[], RunnableLike]\n );\n }\n }\n }\n\n throw new Error(`llm ${llm} must define bindTools method.`);\n}\n\n/**\n * Compose multiple wrapToolCall handlers into a single middleware stack.\n *\n * Composes handlers so the first in the list becomes the outermost layer.\n * Each handler receives a handler callback to execute inner layers.\n *\n * @param handlers - List of handlers. First handler wraps all others.\n * @returns Composed handler, or undefined if handlers array is empty.\n *\n * @example\n * ```typescript\n * // handlers=[auth, retry] means: auth wraps retry\n * // Flow: auth calls retry, retry calls base handler\n * const auth: ToolCallWrapper = async (request, handler) => {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (error.message === \"Unauthorized\") {\n * await refreshToken();\n * return await handler(request);\n * }\n * throw error;\n * }\n * };\n *\n * const retry: ToolCallWrapper = async (request, handler) => {\n * for (let attempt = 0; attempt < 3; attempt++) {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (attempt === 2) throw error;\n * }\n * }\n * throw new Error(\"Unreachable\");\n * };\n *\n * const composedHandler = chainToolCallHandlers([auth, retry]);\n * ```\n */\nfunction chainToolCallHandlers(\n handlers: WrapToolCallHook[]\n): WrapToolCallHook | undefined {\n if (handlers.length === 0) {\n return undefined;\n }\n\n if (handlers.length === 1) {\n return handlers[0];\n }\n\n // Compose two handlers where outer wraps inner\n // The key is to properly propagate request modifications through the chain\n function composeTwo(\n outer: WrapToolCallHook,\n inner: WrapToolCallHook\n ): WrapToolCallHook {\n return async (request, handler) => {\n // Create a wrapper that calls inner with the base handler\n // The innerHandler receives the (possibly modified) request from outer\n // and passes it to inner, which then calls the base handler\n const innerHandler: ToolCallHandler = async (passedRequest) => {\n // inner receives the request passed by outer (which may be modified)\n return inner(passedRequest, handler);\n };\n\n // Call outer with the wrapped inner as its handler\n return outer(request, innerHandler);\n };\n }\n\n // Compose right-to-left: outer(inner(innermost(handler)))\n let result = handlers[handlers.length - 1];\n for (let i = handlers.length - 2; i >= 0; i--) {\n result = composeTwo(handlers[i], result);\n }\n\n return result;\n}\n\n/**\n * Wrapping `wrapToolCall` invocation so we can inject middleware name into\n * the error message.\n *\n * @param middleware list of middleware passed to the agent\n * @param state state of the agent\n * @returns single wrap function\n */\nexport function wrapToolCall(middleware: readonly AnyAgentMiddleware[]) {\n const middlewareWithWrapToolCall = middleware.filter((m) => m.wrapToolCall);\n\n if (middlewareWithWrapToolCall.length === 0) {\n return;\n }\n\n return chainToolCallHandlers(\n middlewareWithWrapToolCall.map((m) => {\n const originalHandler = m.wrapToolCall!;\n /**\n * Wrap with error handling and validation\n */\n const wrappedHandler: WrapToolCallHook = async (request, handler) => {\n /**\n * Capture the original state for this middleware's schema parsing.\n * This is important because the request may be modified (via override)\n * as it passes through the middleware chain, but each middleware\n * should always see the full original state for its schema parsing.\n */\n const originalState = request.state;\n\n /**\n * Create a handler that preserves state parsing for this middleware\n * while allowing tool/toolCall/state modifications from inner middleware\n */\n // Track exact values thrown by the downstream handler so unchanged\n // propagation is not misclassified as a failure in this middleware.\n const downstreamErrors = new Set<unknown>();\n const wrappedInnerHandler: ToolCallHandler = async (passedRequest) => {\n /**\n * Merge the passed request with the original state for parsing.\n * This ensures middleware can override tool/toolCall while\n * maintaining proper state parsing for each middleware in the chain.\n */\n const mergedState = {\n ...originalState,\n ...passedRequest.state,\n };\n try {\n return await handler({\n ...passedRequest,\n state: mergedState,\n });\n } catch (error: unknown) {\n downstreamErrors.add(error);\n throw error;\n }\n };\n\n try {\n const result = await originalHandler(\n {\n ...request,\n /**\n * override state with the state from the specific middleware\n */\n state: {\n messages: originalState.messages,\n ...(m.stateSchema\n ? parseMiddlewareState(m.stateSchema, { ...originalState })\n : {}),\n },\n } as ToolCallRequest<AgentBuiltInState, unknown>,\n wrappedInnerHandler\n );\n\n /**\n * Validate return type\n */\n if (!ToolMessage.isInstance(result) && !isCommand(result)) {\n throw new Error(\n `Invalid response from \"wrapToolCall\" in middleware \"${m.name}\": ` +\n `expected ToolMessage or Command, got ${typeof result}`\n );\n }\n\n return result;\n } catch (error: unknown) {\n if (downstreamErrors.has(error)) {\n throw error;\n }\n throw MiddlewareError.wrap(error, m.name);\n }\n };\n return wrappedHandler;\n })\n );\n}\n\n/**\n * Static LangGraph config keys propagated from ReactAgent defaults onto the\n * compiled inner graph. This ensures values set via `withConfig()` survive\n * LangGraph API loading, which unwraps ReactAgent to `.graph` before execution.\n */\nconst GRAPH_DEFAULT_CONFIG_KEYS = [\n \"tags\",\n \"metadata\",\n \"runName\",\n \"maxConcurrency\",\n \"recursionLimit\",\n \"configurable\",\n] as const satisfies readonly (keyof RunnableConfig)[];\n\nexport function toGraphDefaultConfig(\n config: RunnableConfig\n): Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\"> {\n const result: Record<string, unknown> = {};\n for (const key of GRAPH_DEFAULT_CONFIG_KEYS) {\n const value = config[key];\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result as Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"utils.cjs","names":["StateSchema","isInteropZodSchema","interopParse","AIMessage","AIMessageChunk","Runnable","isBaseChatModel","RunnableBinding","RunnableSequence","isConfigurableModel","MultipleToolsBoundError","SystemMessage","ToolMessage","isCommand","MiddlewareError"],"sources":["../../src/agents/utils.ts"],"sourcesContent":["import {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n BaseMessageLike,\n SystemMessage,\n MessageContent,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport { isCommand, StateSchema } from \"@langchain/langgraph\";\nimport {\n type InteropZodObject,\n interopParse,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n BaseChatModel,\n type BaseChatModelCallOptions,\n} from \"@langchain/core/language_models/chat_models\";\nimport { BaseLanguageModelInput } from \"@langchain/core/language_models/base\";\nimport {\n Runnable,\n RunnableLike,\n RunnableConfig,\n RunnableSequence,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\n\nimport {\n isBaseChatModel,\n isConfigurableModel,\n type AgentLanguageModelLike as LanguageModelLike,\n} from \"./model.js\";\nimport { MultipleToolsBoundError, MiddlewareError } from \"./errors.js\";\nimport type { AgentBuiltInState } from \"./runtime.js\";\nimport type {\n ToolCallHandler,\n AnyAgentMiddleware,\n ToolCallRequest,\n WrapToolCallHook,\n} from \"./middleware/types.js\";\n\nconst NAME_PATTERN = /<name>(.*?)<\\/name>/s;\nconst CONTENT_PATTERN = /<content>(.*?)<\\/content>/s;\n\n/**\n * Parse middleware state from the full agent state based on the middleware's stateSchema.\n *\n * Handles two types of state schemas:\n * 1. Zod schemas (v3 or v4) - parsed using interopParse\n * 2. LangGraph StateSchema - extracts only the keys defined in `fields`\n *\n * @param stateSchema - The middleware's state schema (Zod or LangGraph StateSchema)\n * @param state - The full agent state to parse from\n * @returns Parsed state containing only the keys defined in the schema\n */\nfunction parseMiddlewareState(\n stateSchema: unknown,\n state: Record<string, unknown>\n): Record<string, unknown> {\n // Handle LangGraph StateSchema (has `fields` property)\n if (StateSchema.isInstance(stateSchema)) {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(stateSchema.fields)) {\n if (key in state) {\n result[key] = state[key];\n }\n }\n return result;\n }\n\n // Handle Zod schemas using interopParse\n if (isInteropZodSchema(stateSchema)) {\n return interopParse(stateSchema as InteropZodObject, state);\n }\n\n throw new Error(`Invalid state schema type: ${typeof stateSchema}`);\n}\n\nexport type AgentNameMode = \"inline\";\n\n/**\n * Attach formatted agent names to the messages passed to and from a language model.\n *\n * This is useful for making a message history with multiple agents more coherent.\n *\n * NOTE: agent name is consumed from the message.name field.\n * If you're using an agent built with createAgent, name is automatically set.\n * If you're building a custom agent, make sure to set the name on the AI message returned by the LLM.\n *\n * @param message - Message to add agent name formatting to\n * @returns Message with agent name formatting\n *\n * @internal\n */\nexport function _addInlineAgentName<T extends BaseMessageLike>(\n message: T\n): T | AIMessage {\n if (!AIMessage.isInstance(message) || AIMessageChunk.isInstance(message)) {\n return message;\n }\n\n if (!message.name) {\n return message;\n }\n\n const { name } = message;\n\n if (typeof message.content === \"string\") {\n return new AIMessage({\n ...message.lc_kwargs,\n content: `<name>${name}</name><content>${message.content}</content>`,\n name: undefined,\n });\n }\n\n const updatedContent = [];\n let textBlockCount = 0;\n\n for (const contentBlock of message.content) {\n if (typeof contentBlock === \"string\") {\n textBlockCount += 1;\n updatedContent.push(\n `<name>${name}</name><content>${contentBlock}</content>`\n );\n } else if (\n typeof contentBlock === \"object\" &&\n \"type\" in contentBlock &&\n contentBlock.type === \"text\"\n ) {\n textBlockCount += 1;\n updatedContent.push({\n ...contentBlock,\n text: `<name>${name}</name><content>${contentBlock.text}</content>`,\n });\n } else {\n updatedContent.push(contentBlock);\n }\n }\n\n if (!textBlockCount) {\n updatedContent.unshift({\n type: \"text\",\n text: `<name>${name}</name><content></content>`,\n });\n }\n return new AIMessage({\n ...message.lc_kwargs,\n content: updatedContent as MessageContent,\n name: undefined,\n });\n}\n\n/**\n * Remove explicit name and content XML tags from the AI message content.\n *\n * Examples:\n *\n * @example\n * ```typescript\n * removeInlineAgentName(new AIMessage({ content: \"<name>assistant</name><content>Hello</content>\", name: \"assistant\" }))\n * // AIMessage with content: \"Hello\"\n *\n * removeInlineAgentName(new AIMessage({ content: [{type: \"text\", text: \"<name>assistant</name><content>Hello</content>\"}], name: \"assistant\" }))\n * // AIMessage with content: [{type: \"text\", text: \"Hello\"}]\n * ```\n *\n * @internal\n */\nexport function _removeInlineAgentName<T extends BaseMessage>(message: T): T {\n if (!AIMessage.isInstance(message) || !message.content) {\n return message;\n }\n\n let updatedContent: MessageContent = [];\n let updatedName: string | undefined;\n\n if (Array.isArray(message.content)) {\n updatedContent = message.content\n .filter((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n // don't include empty content blocks that were added because there was no text block to modify\n if (nameMatch && (!contentMatch || contentMatch[1] === \"\")) {\n // capture name from text block\n updatedName = nameMatch[1];\n return false;\n }\n return true;\n }\n return true;\n })\n .map((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return block;\n }\n\n // capture name from text block\n updatedName = nameMatch[1];\n\n return {\n ...block,\n text: contentMatch[1],\n };\n }\n return block;\n });\n } else {\n const content = message.content as string;\n const nameMatch = content.match(NAME_PATTERN);\n const contentMatch = content.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return message;\n }\n\n updatedName = nameMatch[1];\n updatedContent = contentMatch[1];\n }\n\n return new AIMessage({\n ...(Object.keys(message.lc_kwargs ?? {}).length > 0\n ? message.lc_kwargs\n : message),\n content: updatedContent,\n name: updatedName,\n }) as T;\n}\n\nexport function isClientTool(\n tool: ClientTool | ServerTool\n): tool is ClientTool {\n return Runnable.isRunnable(tool);\n}\n\n/**\n * Helper function to check if a language model has a bindTools method.\n * @param llm - The language model to check if it has a bindTools method.\n * @returns True if the language model has a bindTools method, false otherwise.\n */\nfunction _isChatModelWithBindTools(\n llm: LanguageModelLike\n): llm is BaseChatModel & Required<Pick<BaseChatModel, \"bindTools\">> {\n if (!isBaseChatModel(llm)) return false;\n return \"bindTools\" in llm && typeof llm.bindTools === \"function\";\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nconst _simpleBindTools = (\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n) => {\n if (_isChatModelWithBindTools(llm)) {\n return llm.bindTools(toolClasses, options);\n }\n\n if (\n RunnableBinding.isRunnableBinding(llm) &&\n _isChatModelWithBindTools(llm.bound)\n ) {\n const newBound = llm.bound.bindTools(toolClasses, options);\n\n if (RunnableBinding.isRunnableBinding(newBound)) {\n return new RunnableBinding({\n bound: newBound.bound,\n config: { ...llm.config, ...newBound.config },\n kwargs: { ...llm.kwargs, ...newBound.kwargs },\n configFactories: newBound.configFactories ?? llm.configFactories,\n });\n }\n\n return new RunnableBinding({\n bound: newBound,\n config: llm.config,\n kwargs: llm.kwargs,\n configFactories: llm.configFactories,\n });\n }\n\n return null;\n};\n\n/**\n * Check if the LLM already has bound tools and throw if it does.\n *\n * @param llm - The LLM to check.\n * @returns void\n */\nexport function validateLLMHasNoBoundTools(llm: LanguageModelLike): void {\n /**\n * If llm is a function, we can't validate until runtime, so skip\n */\n if (typeof llm === \"function\") {\n return;\n }\n\n let model = llm;\n\n /**\n * If model is a RunnableSequence, find a RunnableBinding in its steps\n */\n if (RunnableSequence.isRunnableSequence(model)) {\n model =\n model.steps.find((step: RunnableLike) =>\n RunnableBinding.isRunnableBinding(step)\n ) || model;\n }\n\n /**\n * If model is configurable, get the underlying model\n */\n if (isConfigurableModel(model)) {\n /**\n * Can't validate async model retrieval in constructor\n */\n return;\n }\n\n /**\n * Check if model is a RunnableBinding with bound tools\n */\n if (RunnableBinding.isRunnableBinding(model)) {\n const hasToolsInKwargs =\n model.kwargs != null &&\n typeof model.kwargs === \"object\" &&\n \"tools\" in model.kwargs &&\n Array.isArray(model.kwargs.tools) &&\n model.kwargs.tools.length > 0;\n\n const hasToolsInConfig =\n model.config != null &&\n typeof model.config === \"object\" &&\n \"tools\" in model.config &&\n Array.isArray(model.config.tools) &&\n model.config.tools.length > 0;\n\n if (hasToolsInKwargs || hasToolsInConfig) {\n throw new MultipleToolsBoundError();\n }\n }\n\n /**\n * Also check if model has tools property directly (e.g., FakeToolCallingModel)\n */\n if (\n \"tools\" in model &&\n model.tools !== undefined &&\n Array.isArray(model.tools) &&\n model.tools.length > 0\n ) {\n throw new MultipleToolsBoundError();\n }\n}\n\n/**\n * Check if the last message in the messages array has tool calls.\n *\n * @param messages - The messages to check.\n * @returns True if the last message has tool calls, false otherwise.\n */\nexport function hasToolCalls(message?: BaseMessage): boolean {\n return Boolean(\n AIMessage.isInstance(message) &&\n message.tool_calls &&\n message.tool_calls.length > 0\n );\n}\n\n/**\n * Normalizes a system prompt to a SystemMessage object.\n * If it's already a SystemMessage, returns it as-is.\n * If it's a string, converts it to a SystemMessage.\n * If it's undefined, creates an empty system message so it is easier to append to it later.\n */\nexport function normalizeSystemPrompt(\n systemPrompt?: string | SystemMessage\n): SystemMessage {\n if (systemPrompt == null) {\n return new SystemMessage(\"\");\n }\n if (SystemMessage.isInstance(systemPrompt)) {\n return systemPrompt;\n }\n if (typeof systemPrompt === \"string\") {\n return new SystemMessage({\n content: [{ type: \"text\", text: systemPrompt }],\n });\n }\n throw new Error(\n `Invalid systemPrompt type: expected string or SystemMessage, got ${typeof systemPrompt}`\n );\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nexport async function bindTools(\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n): Promise<\n | RunnableSequence<unknown, unknown>\n | RunnableBinding<unknown, unknown, RunnableConfig<Record<string, unknown>>>\n | Runnable<BaseLanguageModelInput, AIMessageChunk, BaseChatModelCallOptions>\n> {\n const model = _simpleBindTools(llm, toolClasses, options);\n if (model) return model;\n\n if (isConfigurableModel(llm)) {\n const model = _simpleBindTools(\n await llm._getModelInstance(),\n toolClasses,\n options\n );\n if (model) return model;\n }\n\n if (RunnableSequence.isRunnableSequence(llm)) {\n const modelStep = llm.steps.findIndex(\n (step) =>\n RunnableBinding.isRunnableBinding(step) ||\n isBaseChatModel(step) ||\n isConfigurableModel(step)\n );\n\n if (modelStep >= 0) {\n const model = _simpleBindTools(\n llm.steps[modelStep],\n toolClasses,\n options\n );\n if (model) {\n const nextSteps: unknown[] = llm.steps.slice();\n nextSteps.splice(modelStep, 1, model);\n\n return RunnableSequence.from(\n nextSteps as [RunnableLike, ...RunnableLike[], RunnableLike]\n );\n }\n }\n }\n\n throw new Error(`llm ${llm} must define bindTools method.`);\n}\n\n/**\n * Compose multiple wrapToolCall handlers into a single middleware stack.\n *\n * Composes handlers so the first in the list becomes the outermost layer.\n * Each handler receives a handler callback to execute inner layers.\n *\n * @param handlers - List of handlers. First handler wraps all others.\n * @returns Composed handler, or undefined if handlers array is empty.\n *\n * @example\n * ```typescript\n * // handlers=[auth, retry] means: auth wraps retry\n * // Flow: auth calls retry, retry calls base handler\n * const auth: ToolCallWrapper = async (request, handler) => {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (error.message === \"Unauthorized\") {\n * await refreshToken();\n * return await handler(request);\n * }\n * throw error;\n * }\n * };\n *\n * const retry: ToolCallWrapper = async (request, handler) => {\n * for (let attempt = 0; attempt < 3; attempt++) {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (attempt === 2) throw error;\n * }\n * }\n * throw new Error(\"Unreachable\");\n * };\n *\n * const composedHandler = chainToolCallHandlers([auth, retry]);\n * ```\n */\nfunction chainToolCallHandlers(\n handlers: WrapToolCallHook[]\n): WrapToolCallHook | undefined {\n if (handlers.length === 0) {\n return undefined;\n }\n\n if (handlers.length === 1) {\n return handlers[0];\n }\n\n // Compose two handlers where outer wraps inner\n // The key is to properly propagate request modifications through the chain\n function composeTwo(\n outer: WrapToolCallHook,\n inner: WrapToolCallHook\n ): WrapToolCallHook {\n return async (request, handler) => {\n // Create a wrapper that calls inner with the base handler\n // The innerHandler receives the (possibly modified) request from outer\n // and passes it to inner, which then calls the base handler\n const innerHandler: ToolCallHandler = async (passedRequest) => {\n // inner receives the request passed by outer (which may be modified)\n return inner(passedRequest, handler);\n };\n\n // Call outer with the wrapped inner as its handler\n return outer(request, innerHandler);\n };\n }\n\n // Compose right-to-left: outer(inner(innermost(handler)))\n let result = handlers[handlers.length - 1];\n for (let i = handlers.length - 2; i >= 0; i--) {\n result = composeTwo(handlers[i], result);\n }\n\n return result;\n}\n\n/**\n * Wrapping `wrapToolCall` invocation so we can inject middleware name into\n * the error message.\n *\n * @param middleware list of middleware passed to the agent\n * @param state state of the agent\n * @returns single wrap function\n */\nexport function wrapToolCall(middleware: readonly AnyAgentMiddleware[]) {\n const middlewareWithWrapToolCall = middleware.filter((m) => m.wrapToolCall);\n\n if (middlewareWithWrapToolCall.length === 0) {\n return;\n }\n\n return chainToolCallHandlers(\n middlewareWithWrapToolCall.map((m) => {\n const originalHandler = m.wrapToolCall!;\n /**\n * Wrap with error handling and validation\n */\n const wrappedHandler: WrapToolCallHook = async (request, handler) => {\n /**\n * Capture the original state for this middleware's schema parsing.\n * This is important because the request may be modified (via override)\n * as it passes through the middleware chain, but each middleware\n * should always see the full original state for its schema parsing.\n */\n const originalState = request.state;\n\n /**\n * Create a handler that preserves state parsing for this middleware\n * while allowing tool/toolCall/state modifications from inner middleware\n */\n // Track exact values thrown by the downstream handler so unchanged\n // propagation is not misclassified as a failure in this middleware.\n const downstreamErrors = new Set<unknown>();\n const wrappedInnerHandler: ToolCallHandler = async (passedRequest) => {\n /**\n * Merge the passed request with the original state for parsing.\n * This ensures middleware can override tool/toolCall while\n * maintaining proper state parsing for each middleware in the chain.\n */\n const mergedState = {\n ...originalState,\n ...passedRequest.state,\n };\n try {\n return await handler({\n ...passedRequest,\n state: mergedState,\n });\n } catch (error: unknown) {\n downstreamErrors.add(error);\n throw error;\n }\n };\n\n try {\n const result = await originalHandler(\n {\n ...request,\n /**\n * override state with the state from the specific middleware\n */\n state: {\n messages: originalState.messages,\n ...(m.stateSchema\n ? parseMiddlewareState(m.stateSchema, { ...originalState })\n : {}),\n },\n } as ToolCallRequest<AgentBuiltInState, unknown>,\n wrappedInnerHandler\n );\n\n /**\n * Validate return type\n */\n if (!ToolMessage.isInstance(result) && !isCommand(result)) {\n throw new Error(\n `Invalid response from \"wrapToolCall\" in middleware \"${m.name}\": ` +\n `expected ToolMessage or Command, got ${typeof result}`\n );\n }\n\n return result;\n } catch (error: unknown) {\n if (downstreamErrors.has(error)) {\n throw error;\n }\n throw MiddlewareError.wrap(error, m.name);\n }\n };\n return wrappedHandler;\n })\n );\n}\n\n/**\n * Static LangGraph config keys propagated from ReactAgent defaults onto the\n * compiled inner graph. This ensures values set via `withConfig()` survive\n * LangGraph API loading, which unwraps ReactAgent to `.graph` before execution.\n */\nconst GRAPH_DEFAULT_CONFIG_KEYS = [\n \"callbacks\",\n \"tags\",\n \"metadata\",\n \"runName\",\n \"maxConcurrency\",\n \"recursionLimit\",\n \"configurable\",\n] as const satisfies readonly (keyof RunnableConfig)[];\n\nexport function toGraphDefaultConfig(\n config: RunnableConfig\n): Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\"> {\n const result: Record<string, unknown> = {};\n for (const key of GRAPH_DEFAULT_CONFIG_KEYS) {\n const value = config[key];\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result as Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">;\n}\n"],"mappings":"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"}
@@ -395,6 +395,7 @@ function wrapToolCall(middleware) {
395
395
  * LangGraph API loading, which unwraps ReactAgent to `.graph` before execution.
396
396
  */
397
397
  const GRAPH_DEFAULT_CONFIG_KEYS = [
398
+ "callbacks",
398
399
  "tags",
399
400
  "metadata",
400
401
  "runName",
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../src/agents/utils.ts"],"sourcesContent":["import {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n BaseMessageLike,\n SystemMessage,\n MessageContent,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport { isCommand, StateSchema } from \"@langchain/langgraph\";\nimport {\n type InteropZodObject,\n interopParse,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n BaseChatModel,\n type BaseChatModelCallOptions,\n} from \"@langchain/core/language_models/chat_models\";\nimport { BaseLanguageModelInput } from \"@langchain/core/language_models/base\";\nimport {\n Runnable,\n RunnableLike,\n RunnableConfig,\n RunnableSequence,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\n\nimport {\n isBaseChatModel,\n isConfigurableModel,\n type AgentLanguageModelLike as LanguageModelLike,\n} from \"./model.js\";\nimport { MultipleToolsBoundError, MiddlewareError } from \"./errors.js\";\nimport type { AgentBuiltInState } from \"./runtime.js\";\nimport type {\n ToolCallHandler,\n AnyAgentMiddleware,\n ToolCallRequest,\n WrapToolCallHook,\n} from \"./middleware/types.js\";\n\nconst NAME_PATTERN = /<name>(.*?)<\\/name>/s;\nconst CONTENT_PATTERN = /<content>(.*?)<\\/content>/s;\n\n/**\n * Parse middleware state from the full agent state based on the middleware's stateSchema.\n *\n * Handles two types of state schemas:\n * 1. Zod schemas (v3 or v4) - parsed using interopParse\n * 2. LangGraph StateSchema - extracts only the keys defined in `fields`\n *\n * @param stateSchema - The middleware's state schema (Zod or LangGraph StateSchema)\n * @param state - The full agent state to parse from\n * @returns Parsed state containing only the keys defined in the schema\n */\nfunction parseMiddlewareState(\n stateSchema: unknown,\n state: Record<string, unknown>\n): Record<string, unknown> {\n // Handle LangGraph StateSchema (has `fields` property)\n if (StateSchema.isInstance(stateSchema)) {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(stateSchema.fields)) {\n if (key in state) {\n result[key] = state[key];\n }\n }\n return result;\n }\n\n // Handle Zod schemas using interopParse\n if (isInteropZodSchema(stateSchema)) {\n return interopParse(stateSchema as InteropZodObject, state);\n }\n\n throw new Error(`Invalid state schema type: ${typeof stateSchema}`);\n}\n\nexport type AgentNameMode = \"inline\";\n\n/**\n * Attach formatted agent names to the messages passed to and from a language model.\n *\n * This is useful for making a message history with multiple agents more coherent.\n *\n * NOTE: agent name is consumed from the message.name field.\n * If you're using an agent built with createAgent, name is automatically set.\n * If you're building a custom agent, make sure to set the name on the AI message returned by the LLM.\n *\n * @param message - Message to add agent name formatting to\n * @returns Message with agent name formatting\n *\n * @internal\n */\nexport function _addInlineAgentName<T extends BaseMessageLike>(\n message: T\n): T | AIMessage {\n if (!AIMessage.isInstance(message) || AIMessageChunk.isInstance(message)) {\n return message;\n }\n\n if (!message.name) {\n return message;\n }\n\n const { name } = message;\n\n if (typeof message.content === \"string\") {\n return new AIMessage({\n ...message.lc_kwargs,\n content: `<name>${name}</name><content>${message.content}</content>`,\n name: undefined,\n });\n }\n\n const updatedContent = [];\n let textBlockCount = 0;\n\n for (const contentBlock of message.content) {\n if (typeof contentBlock === \"string\") {\n textBlockCount += 1;\n updatedContent.push(\n `<name>${name}</name><content>${contentBlock}</content>`\n );\n } else if (\n typeof contentBlock === \"object\" &&\n \"type\" in contentBlock &&\n contentBlock.type === \"text\"\n ) {\n textBlockCount += 1;\n updatedContent.push({\n ...contentBlock,\n text: `<name>${name}</name><content>${contentBlock.text}</content>`,\n });\n } else {\n updatedContent.push(contentBlock);\n }\n }\n\n if (!textBlockCount) {\n updatedContent.unshift({\n type: \"text\",\n text: `<name>${name}</name><content></content>`,\n });\n }\n return new AIMessage({\n ...message.lc_kwargs,\n content: updatedContent as MessageContent,\n name: undefined,\n });\n}\n\n/**\n * Remove explicit name and content XML tags from the AI message content.\n *\n * Examples:\n *\n * @example\n * ```typescript\n * removeInlineAgentName(new AIMessage({ content: \"<name>assistant</name><content>Hello</content>\", name: \"assistant\" }))\n * // AIMessage with content: \"Hello\"\n *\n * removeInlineAgentName(new AIMessage({ content: [{type: \"text\", text: \"<name>assistant</name><content>Hello</content>\"}], name: \"assistant\" }))\n * // AIMessage with content: [{type: \"text\", text: \"Hello\"}]\n * ```\n *\n * @internal\n */\nexport function _removeInlineAgentName<T extends BaseMessage>(message: T): T {\n if (!AIMessage.isInstance(message) || !message.content) {\n return message;\n }\n\n let updatedContent: MessageContent = [];\n let updatedName: string | undefined;\n\n if (Array.isArray(message.content)) {\n updatedContent = message.content\n .filter((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n // don't include empty content blocks that were added because there was no text block to modify\n if (nameMatch && (!contentMatch || contentMatch[1] === \"\")) {\n // capture name from text block\n updatedName = nameMatch[1];\n return false;\n }\n return true;\n }\n return true;\n })\n .map((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return block;\n }\n\n // capture name from text block\n updatedName = nameMatch[1];\n\n return {\n ...block,\n text: contentMatch[1],\n };\n }\n return block;\n });\n } else {\n const content = message.content as string;\n const nameMatch = content.match(NAME_PATTERN);\n const contentMatch = content.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return message;\n }\n\n updatedName = nameMatch[1];\n updatedContent = contentMatch[1];\n }\n\n return new AIMessage({\n ...(Object.keys(message.lc_kwargs ?? {}).length > 0\n ? message.lc_kwargs\n : message),\n content: updatedContent,\n name: updatedName,\n }) as T;\n}\n\nexport function isClientTool(\n tool: ClientTool | ServerTool\n): tool is ClientTool {\n return Runnable.isRunnable(tool);\n}\n\n/**\n * Helper function to check if a language model has a bindTools method.\n * @param llm - The language model to check if it has a bindTools method.\n * @returns True if the language model has a bindTools method, false otherwise.\n */\nfunction _isChatModelWithBindTools(\n llm: LanguageModelLike\n): llm is BaseChatModel & Required<Pick<BaseChatModel, \"bindTools\">> {\n if (!isBaseChatModel(llm)) return false;\n return \"bindTools\" in llm && typeof llm.bindTools === \"function\";\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nconst _simpleBindTools = (\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n) => {\n if (_isChatModelWithBindTools(llm)) {\n return llm.bindTools(toolClasses, options);\n }\n\n if (\n RunnableBinding.isRunnableBinding(llm) &&\n _isChatModelWithBindTools(llm.bound)\n ) {\n const newBound = llm.bound.bindTools(toolClasses, options);\n\n if (RunnableBinding.isRunnableBinding(newBound)) {\n return new RunnableBinding({\n bound: newBound.bound,\n config: { ...llm.config, ...newBound.config },\n kwargs: { ...llm.kwargs, ...newBound.kwargs },\n configFactories: newBound.configFactories ?? llm.configFactories,\n });\n }\n\n return new RunnableBinding({\n bound: newBound,\n config: llm.config,\n kwargs: llm.kwargs,\n configFactories: llm.configFactories,\n });\n }\n\n return null;\n};\n\n/**\n * Check if the LLM already has bound tools and throw if it does.\n *\n * @param llm - The LLM to check.\n * @returns void\n */\nexport function validateLLMHasNoBoundTools(llm: LanguageModelLike): void {\n /**\n * If llm is a function, we can't validate until runtime, so skip\n */\n if (typeof llm === \"function\") {\n return;\n }\n\n let model = llm;\n\n /**\n * If model is a RunnableSequence, find a RunnableBinding in its steps\n */\n if (RunnableSequence.isRunnableSequence(model)) {\n model =\n model.steps.find((step: RunnableLike) =>\n RunnableBinding.isRunnableBinding(step)\n ) || model;\n }\n\n /**\n * If model is configurable, get the underlying model\n */\n if (isConfigurableModel(model)) {\n /**\n * Can't validate async model retrieval in constructor\n */\n return;\n }\n\n /**\n * Check if model is a RunnableBinding with bound tools\n */\n if (RunnableBinding.isRunnableBinding(model)) {\n const hasToolsInKwargs =\n model.kwargs != null &&\n typeof model.kwargs === \"object\" &&\n \"tools\" in model.kwargs &&\n Array.isArray(model.kwargs.tools) &&\n model.kwargs.tools.length > 0;\n\n const hasToolsInConfig =\n model.config != null &&\n typeof model.config === \"object\" &&\n \"tools\" in model.config &&\n Array.isArray(model.config.tools) &&\n model.config.tools.length > 0;\n\n if (hasToolsInKwargs || hasToolsInConfig) {\n throw new MultipleToolsBoundError();\n }\n }\n\n /**\n * Also check if model has tools property directly (e.g., FakeToolCallingModel)\n */\n if (\n \"tools\" in model &&\n model.tools !== undefined &&\n Array.isArray(model.tools) &&\n model.tools.length > 0\n ) {\n throw new MultipleToolsBoundError();\n }\n}\n\n/**\n * Check if the last message in the messages array has tool calls.\n *\n * @param messages - The messages to check.\n * @returns True if the last message has tool calls, false otherwise.\n */\nexport function hasToolCalls(message?: BaseMessage): boolean {\n return Boolean(\n AIMessage.isInstance(message) &&\n message.tool_calls &&\n message.tool_calls.length > 0\n );\n}\n\n/**\n * Normalizes a system prompt to a SystemMessage object.\n * If it's already a SystemMessage, returns it as-is.\n * If it's a string, converts it to a SystemMessage.\n * If it's undefined, creates an empty system message so it is easier to append to it later.\n */\nexport function normalizeSystemPrompt(\n systemPrompt?: string | SystemMessage\n): SystemMessage {\n if (systemPrompt == null) {\n return new SystemMessage(\"\");\n }\n if (SystemMessage.isInstance(systemPrompt)) {\n return systemPrompt;\n }\n if (typeof systemPrompt === \"string\") {\n return new SystemMessage({\n content: [{ type: \"text\", text: systemPrompt }],\n });\n }\n throw new Error(\n `Invalid systemPrompt type: expected string or SystemMessage, got ${typeof systemPrompt}`\n );\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nexport async function bindTools(\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n): Promise<\n | RunnableSequence<unknown, unknown>\n | RunnableBinding<unknown, unknown, RunnableConfig<Record<string, unknown>>>\n | Runnable<BaseLanguageModelInput, AIMessageChunk, BaseChatModelCallOptions>\n> {\n const model = _simpleBindTools(llm, toolClasses, options);\n if (model) return model;\n\n if (isConfigurableModel(llm)) {\n const model = _simpleBindTools(\n await llm._getModelInstance(),\n toolClasses,\n options\n );\n if (model) return model;\n }\n\n if (RunnableSequence.isRunnableSequence(llm)) {\n const modelStep = llm.steps.findIndex(\n (step) =>\n RunnableBinding.isRunnableBinding(step) ||\n isBaseChatModel(step) ||\n isConfigurableModel(step)\n );\n\n if (modelStep >= 0) {\n const model = _simpleBindTools(\n llm.steps[modelStep],\n toolClasses,\n options\n );\n if (model) {\n const nextSteps: unknown[] = llm.steps.slice();\n nextSteps.splice(modelStep, 1, model);\n\n return RunnableSequence.from(\n nextSteps as [RunnableLike, ...RunnableLike[], RunnableLike]\n );\n }\n }\n }\n\n throw new Error(`llm ${llm} must define bindTools method.`);\n}\n\n/**\n * Compose multiple wrapToolCall handlers into a single middleware stack.\n *\n * Composes handlers so the first in the list becomes the outermost layer.\n * Each handler receives a handler callback to execute inner layers.\n *\n * @param handlers - List of handlers. First handler wraps all others.\n * @returns Composed handler, or undefined if handlers array is empty.\n *\n * @example\n * ```typescript\n * // handlers=[auth, retry] means: auth wraps retry\n * // Flow: auth calls retry, retry calls base handler\n * const auth: ToolCallWrapper = async (request, handler) => {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (error.message === \"Unauthorized\") {\n * await refreshToken();\n * return await handler(request);\n * }\n * throw error;\n * }\n * };\n *\n * const retry: ToolCallWrapper = async (request, handler) => {\n * for (let attempt = 0; attempt < 3; attempt++) {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (attempt === 2) throw error;\n * }\n * }\n * throw new Error(\"Unreachable\");\n * };\n *\n * const composedHandler = chainToolCallHandlers([auth, retry]);\n * ```\n */\nfunction chainToolCallHandlers(\n handlers: WrapToolCallHook[]\n): WrapToolCallHook | undefined {\n if (handlers.length === 0) {\n return undefined;\n }\n\n if (handlers.length === 1) {\n return handlers[0];\n }\n\n // Compose two handlers where outer wraps inner\n // The key is to properly propagate request modifications through the chain\n function composeTwo(\n outer: WrapToolCallHook,\n inner: WrapToolCallHook\n ): WrapToolCallHook {\n return async (request, handler) => {\n // Create a wrapper that calls inner with the base handler\n // The innerHandler receives the (possibly modified) request from outer\n // and passes it to inner, which then calls the base handler\n const innerHandler: ToolCallHandler = async (passedRequest) => {\n // inner receives the request passed by outer (which may be modified)\n return inner(passedRequest, handler);\n };\n\n // Call outer with the wrapped inner as its handler\n return outer(request, innerHandler);\n };\n }\n\n // Compose right-to-left: outer(inner(innermost(handler)))\n let result = handlers[handlers.length - 1];\n for (let i = handlers.length - 2; i >= 0; i--) {\n result = composeTwo(handlers[i], result);\n }\n\n return result;\n}\n\n/**\n * Wrapping `wrapToolCall` invocation so we can inject middleware name into\n * the error message.\n *\n * @param middleware list of middleware passed to the agent\n * @param state state of the agent\n * @returns single wrap function\n */\nexport function wrapToolCall(middleware: readonly AnyAgentMiddleware[]) {\n const middlewareWithWrapToolCall = middleware.filter((m) => m.wrapToolCall);\n\n if (middlewareWithWrapToolCall.length === 0) {\n return;\n }\n\n return chainToolCallHandlers(\n middlewareWithWrapToolCall.map((m) => {\n const originalHandler = m.wrapToolCall!;\n /**\n * Wrap with error handling and validation\n */\n const wrappedHandler: WrapToolCallHook = async (request, handler) => {\n /**\n * Capture the original state for this middleware's schema parsing.\n * This is important because the request may be modified (via override)\n * as it passes through the middleware chain, but each middleware\n * should always see the full original state for its schema parsing.\n */\n const originalState = request.state;\n\n /**\n * Create a handler that preserves state parsing for this middleware\n * while allowing tool/toolCall/state modifications from inner middleware\n */\n // Track exact values thrown by the downstream handler so unchanged\n // propagation is not misclassified as a failure in this middleware.\n const downstreamErrors = new Set<unknown>();\n const wrappedInnerHandler: ToolCallHandler = async (passedRequest) => {\n /**\n * Merge the passed request with the original state for parsing.\n * This ensures middleware can override tool/toolCall while\n * maintaining proper state parsing for each middleware in the chain.\n */\n const mergedState = {\n ...originalState,\n ...passedRequest.state,\n };\n try {\n return await handler({\n ...passedRequest,\n state: mergedState,\n });\n } catch (error: unknown) {\n downstreamErrors.add(error);\n throw error;\n }\n };\n\n try {\n const result = await originalHandler(\n {\n ...request,\n /**\n * override state with the state from the specific middleware\n */\n state: {\n messages: originalState.messages,\n ...(m.stateSchema\n ? parseMiddlewareState(m.stateSchema, { ...originalState })\n : {}),\n },\n } as ToolCallRequest<AgentBuiltInState, unknown>,\n wrappedInnerHandler\n );\n\n /**\n * Validate return type\n */\n if (!ToolMessage.isInstance(result) && !isCommand(result)) {\n throw new Error(\n `Invalid response from \"wrapToolCall\" in middleware \"${m.name}\": ` +\n `expected ToolMessage or Command, got ${typeof result}`\n );\n }\n\n return result;\n } catch (error: unknown) {\n if (downstreamErrors.has(error)) {\n throw error;\n }\n throw MiddlewareError.wrap(error, m.name);\n }\n };\n return wrappedHandler;\n })\n );\n}\n\n/**\n * Static LangGraph config keys propagated from ReactAgent defaults onto the\n * compiled inner graph. This ensures values set via `withConfig()` survive\n * LangGraph API loading, which unwraps ReactAgent to `.graph` before execution.\n */\nconst GRAPH_DEFAULT_CONFIG_KEYS = [\n \"tags\",\n \"metadata\",\n \"runName\",\n \"maxConcurrency\",\n \"recursionLimit\",\n \"configurable\",\n] as const satisfies readonly (keyof RunnableConfig)[];\n\nexport function toGraphDefaultConfig(\n config: RunnableConfig\n): Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\"> {\n const result: Record<string, unknown> = {};\n for (const key of GRAPH_DEFAULT_CONFIG_KEYS) {\n const value = config[key];\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result as Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">;\n}\n"],"mappings":";;;;;;;AA2CA,MAAM,eAAe;AACrB,MAAM,kBAAkB;;;;;;;;;;;;AAaxB,SAAS,qBACP,aACA,OACyB;CAEzB,IAAI,YAAY,WAAW,WAAW,GAAG;EACvC,MAAM,SAAkC,CAAC;EACzC,KAAK,MAAM,OAAO,OAAO,KAAK,YAAY,MAAM,GAC9C,IAAI,OAAO,OACT,OAAO,OAAO,MAAM;EAGxB,OAAO;CACT;CAGA,IAAI,mBAAmB,WAAW,GAChC,OAAO,aAAa,aAAiC,KAAK;CAG5D,MAAM,IAAI,MAAM,8BAA8B,OAAO,aAAa;AACpE;;;;;;;;;;;;;;;AAkBA,SAAgB,oBACd,SACe;CACf,IAAI,CAAC,UAAU,WAAW,OAAO,KAAK,eAAe,WAAW,OAAO,GACrE,OAAO;CAGT,IAAI,CAAC,QAAQ,MACX,OAAO;CAGT,MAAM,EAAE,SAAS;CAEjB,IAAI,OAAO,QAAQ,YAAY,UAC7B,OAAO,IAAI,UAAU;EACnB,GAAG,QAAQ;EACX,SAAS,SAAS,KAAK,kBAAkB,QAAQ,QAAQ;EACzD,MAAM,KAAA;CACR,CAAC;CAGH,MAAM,iBAAiB,CAAC;CACxB,IAAI,iBAAiB;CAErB,KAAK,MAAM,gBAAgB,QAAQ,SACjC,IAAI,OAAO,iBAAiB,UAAU;EACpC,kBAAkB;EAClB,eAAe,KACb,SAAS,KAAK,kBAAkB,aAAa,WAC/C;CACF,OAAO,IACL,OAAO,iBAAiB,YACxB,UAAU,gBACV,aAAa,SAAS,QACtB;EACA,kBAAkB;EAClB,eAAe,KAAK;GAClB,GAAG;GACH,MAAM,SAAS,KAAK,kBAAkB,aAAa,KAAK;EAC1D,CAAC;CACH,OACE,eAAe,KAAK,YAAY;CAIpC,IAAI,CAAC,gBACH,eAAe,QAAQ;EACrB,MAAM;EACN,MAAM,SAAS,KAAK;CACtB,CAAC;CAEH,OAAO,IAAI,UAAU;EACnB,GAAG,QAAQ;EACX,SAAS;EACT,MAAM,KAAA;CACR,CAAC;AACH;;;;;;;;;;;;;;;;;AAkBA,SAAgB,uBAA8C,SAAe;CAC3E,IAAI,CAAC,UAAU,WAAW,OAAO,KAAK,CAAC,QAAQ,SAC7C,OAAO;CAGT,IAAI,iBAAiC,CAAC;CACtC,IAAI;CAEJ,IAAI,MAAM,QAAQ,QAAQ,OAAO,GAC/B,iBAAiB,QAAQ,QACtB,QAAQ,UAAU;EACjB,IAAI,MAAM,SAAS,UAAU,OAAO,MAAM,SAAS,UAAU;GAC3D,MAAM,YAAY,MAAM,KAAK,MAAM,YAAY;GAC/C,MAAM,eAAe,MAAM,KAAK,MAAM,eAAe;GAErD,IAAI,cAAc,CAAC,gBAAgB,aAAa,OAAO,KAAK;IAE1D,cAAc,UAAU;IACxB,OAAO;GACT;GACA,OAAO;EACT;EACA,OAAO;CACT,CAAC,CAAC,CACD,KAAK,UAAU;EACd,IAAI,MAAM,SAAS,UAAU,OAAO,MAAM,SAAS,UAAU;GAC3D,MAAM,YAAY,MAAM,KAAK,MAAM,YAAY;GAC/C,MAAM,eAAe,MAAM,KAAK,MAAM,eAAe;GAErD,IAAI,CAAC,aAAa,CAAC,cACjB,OAAO;GAIT,cAAc,UAAU;GAExB,OAAO;IACL,GAAG;IACH,MAAM,aAAa;GACrB;EACF;EACA,OAAO;CACT,CAAC;MACE;EACL,MAAM,UAAU,QAAQ;EACxB,MAAM,YAAY,QAAQ,MAAM,YAAY;EAC5C,MAAM,eAAe,QAAQ,MAAM,eAAe;EAElD,IAAI,CAAC,aAAa,CAAC,cACjB,OAAO;EAGT,cAAc,UAAU;EACxB,iBAAiB,aAAa;CAChC;CAEA,OAAO,IAAI,UAAU;EACnB,GAAI,OAAO,KAAK,QAAQ,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,IAC9C,QAAQ,YACR;EACJ,SAAS;EACT,MAAM;CACR,CAAC;AACH;AAEA,SAAgB,aACd,MACoB;CACpB,OAAO,SAAS,WAAW,IAAI;AACjC;;;;;;AAOA,SAAS,0BACP,KACmE;CACnE,IAAI,CAAC,gBAAgB,GAAG,GAAG,OAAO;CAClC,OAAO,eAAe,OAAO,OAAO,IAAI,cAAc;AACxD;;;;;;;;AASA,MAAM,oBACJ,KACA,aACA,UAA6C,CAAC,MAC3C;CACH,IAAI,0BAA0B,GAAG,GAC/B,OAAO,IAAI,UAAU,aAAa,OAAO;CAG3C,IACE,gBAAgB,kBAAkB,GAAG,KACrC,0BAA0B,IAAI,KAAK,GACnC;EACA,MAAM,WAAW,IAAI,MAAM,UAAU,aAAa,OAAO;EAEzD,IAAI,gBAAgB,kBAAkB,QAAQ,GAC5C,OAAO,IAAI,gBAAgB;GACzB,OAAO,SAAS;GAChB,QAAQ;IAAE,GAAG,IAAI;IAAQ,GAAG,SAAS;GAAO;GAC5C,QAAQ;IAAE,GAAG,IAAI;IAAQ,GAAG,SAAS;GAAO;GAC5C,iBAAiB,SAAS,mBAAmB,IAAI;EACnD,CAAC;EAGH,OAAO,IAAI,gBAAgB;GACzB,OAAO;GACP,QAAQ,IAAI;GACZ,QAAQ,IAAI;GACZ,iBAAiB,IAAI;EACvB,CAAC;CACH;CAEA,OAAO;AACT;;;;;;;AAQA,SAAgB,2BAA2B,KAA8B;;;;CAIvE,IAAI,OAAO,QAAQ,YACjB;CAGF,IAAI,QAAQ;;;;CAKZ,IAAI,iBAAiB,mBAAmB,KAAK,GAC3C,QACE,MAAM,MAAM,MAAM,SAChB,gBAAgB,kBAAkB,IAAI,CACxC,KAAK;;;;CAMT,IAAI,oBAAoB,KAAK;;;;CAI3B;;;;CAMF,IAAI,gBAAgB,kBAAkB,KAAK,GAAG;EAC5C,MAAM,mBACJ,MAAM,UAAU,QAChB,OAAO,MAAM,WAAW,YACxB,WAAW,MAAM,UACjB,MAAM,QAAQ,MAAM,OAAO,KAAK,KAChC,MAAM,OAAO,MAAM,SAAS;EAE9B,MAAM,mBACJ,MAAM,UAAU,QAChB,OAAO,MAAM,WAAW,YACxB,WAAW,MAAM,UACjB,MAAM,QAAQ,MAAM,OAAO,KAAK,KAChC,MAAM,OAAO,MAAM,SAAS;EAE9B,IAAI,oBAAoB,kBACtB,MAAM,IAAI,wBAAwB;CAEtC;;;;CAKA,IACE,WAAW,SACX,MAAM,UAAU,KAAA,KAChB,MAAM,QAAQ,MAAM,KAAK,KACzB,MAAM,MAAM,SAAS,GAErB,MAAM,IAAI,wBAAwB;AAEtC;;;;;;;AAQA,SAAgB,aAAa,SAAgC;CAC3D,OAAO,QACL,UAAU,WAAW,OAAO,KAC5B,QAAQ,cACR,QAAQ,WAAW,SAAS,CAC9B;AACF;;;;;;;AAQA,SAAgB,sBACd,cACe;CACf,IAAI,gBAAgB,MAClB,OAAO,IAAI,cAAc,EAAE;CAE7B,IAAI,cAAc,WAAW,YAAY,GACvC,OAAO;CAET,IAAI,OAAO,iBAAiB,UAC1B,OAAO,IAAI,cAAc,EACvB,SAAS,CAAC;EAAE,MAAM;EAAQ,MAAM;CAAa,CAAC,EAChD,CAAC;CAEH,MAAM,IAAI,MACR,oEAAoE,OAAO,cAC7E;AACF;;;;;;;;AASA,eAAsB,UACpB,KACA,aACA,UAA6C,CAAC,GAK9C;CACA,MAAM,QAAQ,iBAAiB,KAAK,aAAa,OAAO;CACxD,IAAI,OAAO,OAAO;CAElB,IAAI,oBAAoB,GAAG,GAAG;EAC5B,MAAM,QAAQ,iBACZ,MAAM,IAAI,kBAAkB,GAC5B,aACA,OACF;EACA,IAAI,OAAO,OAAO;CACpB;CAEA,IAAI,iBAAiB,mBAAmB,GAAG,GAAG;EAC5C,MAAM,YAAY,IAAI,MAAM,WACzB,SACC,gBAAgB,kBAAkB,IAAI,KACtC,gBAAgB,IAAI,KACpB,oBAAoB,IAAI,CAC5B;EAEA,IAAI,aAAa,GAAG;GAClB,MAAM,QAAQ,iBACZ,IAAI,MAAM,YACV,aACA,OACF;GACA,IAAI,OAAO;IACT,MAAM,YAAuB,IAAI,MAAM,MAAM;IAC7C,UAAU,OAAO,WAAW,GAAG,KAAK;IAEpC,OAAO,iBAAiB,KACtB,SACF;GACF;EACF;CACF;CAEA,MAAM,IAAI,MAAM,OAAO,IAAI,+BAA+B;AAC5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,SAAS,sBACP,UAC8B;CAC9B,IAAI,SAAS,WAAW,GACtB;CAGF,IAAI,SAAS,WAAW,GACtB,OAAO,SAAS;CAKlB,SAAS,WACP,OACA,OACkB;EAClB,OAAO,OAAO,SAAS,YAAY;GAIjC,MAAM,eAAgC,OAAO,kBAAkB;IAE7D,OAAO,MAAM,eAAe,OAAO;GACrC;GAGA,OAAO,MAAM,SAAS,YAAY;EACpC;CACF;CAGA,IAAI,SAAS,SAAS,SAAS,SAAS;CACxC,KAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KACxC,SAAS,WAAW,SAAS,IAAI,MAAM;CAGzC,OAAO;AACT;;;;;;;;;AAUA,SAAgB,aAAa,YAA2C;CACtE,MAAM,6BAA6B,WAAW,QAAQ,MAAM,EAAE,YAAY;CAE1E,IAAI,2BAA2B,WAAW,GACxC;CAGF,OAAO,sBACL,2BAA2B,KAAK,MAAM;EACpC,MAAM,kBAAkB,EAAE;;;;EAI1B,MAAM,iBAAmC,OAAO,SAAS,YAAY;;;;;;;GAOnE,MAAM,gBAAgB,QAAQ;;;;;GAQ9B,MAAM,mCAAmB,IAAI,IAAa;GAC1C,MAAM,sBAAuC,OAAO,kBAAkB;;;;;;IAMpE,MAAM,cAAc;KAClB,GAAG;KACH,GAAG,cAAc;IACnB;IACA,IAAI;KACF,OAAO,MAAM,QAAQ;MACnB,GAAG;MACH,OAAO;KACT,CAAC;IACH,SAAS,OAAgB;KACvB,iBAAiB,IAAI,KAAK;KAC1B,MAAM;IACR;GACF;GAEA,IAAI;IACF,MAAM,SAAS,MAAM,gBACnB;KACE,GAAG;;;;KAIH,OAAO;MACL,UAAU,cAAc;MACxB,GAAI,EAAE,cACF,qBAAqB,EAAE,aAAa,EAAE,GAAG,cAAc,CAAC,IACxD,CAAC;KACP;IACF,GACA,mBACF;;;;IAKA,IAAI,CAAC,YAAY,WAAW,MAAM,KAAK,CAAC,UAAU,MAAM,GACtD,MAAM,IAAI,MACR,uDAAuD,EAAE,KAAK,0CACpB,OAAO,QACnD;IAGF,OAAO;GACT,SAAS,OAAgB;IACvB,IAAI,iBAAiB,IAAI,KAAK,GAC5B,MAAM;IAER,MAAM,gBAAgB,KAAK,OAAO,EAAE,IAAI;GAC1C;EACF;EACA,OAAO;CACT,CAAC,CACH;AACF;;;;;;AAOA,MAAM,4BAA4B;CAChC;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,qBACd,QACwD;CACxD,MAAM,SAAkC,CAAC;CACzC,KAAK,MAAM,OAAO,2BAA2B;EAC3C,MAAM,QAAQ,OAAO;EACrB,IAAI,UAAU,KAAA,GACZ,OAAO,OAAO;CAElB;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../src/agents/utils.ts"],"sourcesContent":["import {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n BaseMessageLike,\n SystemMessage,\n MessageContent,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport { isCommand, StateSchema } from \"@langchain/langgraph\";\nimport {\n type InteropZodObject,\n interopParse,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n BaseChatModel,\n type BaseChatModelCallOptions,\n} from \"@langchain/core/language_models/chat_models\";\nimport { BaseLanguageModelInput } from \"@langchain/core/language_models/base\";\nimport {\n Runnable,\n RunnableLike,\n RunnableConfig,\n RunnableSequence,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\n\nimport {\n isBaseChatModel,\n isConfigurableModel,\n type AgentLanguageModelLike as LanguageModelLike,\n} from \"./model.js\";\nimport { MultipleToolsBoundError, MiddlewareError } from \"./errors.js\";\nimport type { AgentBuiltInState } from \"./runtime.js\";\nimport type {\n ToolCallHandler,\n AnyAgentMiddleware,\n ToolCallRequest,\n WrapToolCallHook,\n} from \"./middleware/types.js\";\n\nconst NAME_PATTERN = /<name>(.*?)<\\/name>/s;\nconst CONTENT_PATTERN = /<content>(.*?)<\\/content>/s;\n\n/**\n * Parse middleware state from the full agent state based on the middleware's stateSchema.\n *\n * Handles two types of state schemas:\n * 1. Zod schemas (v3 or v4) - parsed using interopParse\n * 2. LangGraph StateSchema - extracts only the keys defined in `fields`\n *\n * @param stateSchema - The middleware's state schema (Zod or LangGraph StateSchema)\n * @param state - The full agent state to parse from\n * @returns Parsed state containing only the keys defined in the schema\n */\nfunction parseMiddlewareState(\n stateSchema: unknown,\n state: Record<string, unknown>\n): Record<string, unknown> {\n // Handle LangGraph StateSchema (has `fields` property)\n if (StateSchema.isInstance(stateSchema)) {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(stateSchema.fields)) {\n if (key in state) {\n result[key] = state[key];\n }\n }\n return result;\n }\n\n // Handle Zod schemas using interopParse\n if (isInteropZodSchema(stateSchema)) {\n return interopParse(stateSchema as InteropZodObject, state);\n }\n\n throw new Error(`Invalid state schema type: ${typeof stateSchema}`);\n}\n\nexport type AgentNameMode = \"inline\";\n\n/**\n * Attach formatted agent names to the messages passed to and from a language model.\n *\n * This is useful for making a message history with multiple agents more coherent.\n *\n * NOTE: agent name is consumed from the message.name field.\n * If you're using an agent built with createAgent, name is automatically set.\n * If you're building a custom agent, make sure to set the name on the AI message returned by the LLM.\n *\n * @param message - Message to add agent name formatting to\n * @returns Message with agent name formatting\n *\n * @internal\n */\nexport function _addInlineAgentName<T extends BaseMessageLike>(\n message: T\n): T | AIMessage {\n if (!AIMessage.isInstance(message) || AIMessageChunk.isInstance(message)) {\n return message;\n }\n\n if (!message.name) {\n return message;\n }\n\n const { name } = message;\n\n if (typeof message.content === \"string\") {\n return new AIMessage({\n ...message.lc_kwargs,\n content: `<name>${name}</name><content>${message.content}</content>`,\n name: undefined,\n });\n }\n\n const updatedContent = [];\n let textBlockCount = 0;\n\n for (const contentBlock of message.content) {\n if (typeof contentBlock === \"string\") {\n textBlockCount += 1;\n updatedContent.push(\n `<name>${name}</name><content>${contentBlock}</content>`\n );\n } else if (\n typeof contentBlock === \"object\" &&\n \"type\" in contentBlock &&\n contentBlock.type === \"text\"\n ) {\n textBlockCount += 1;\n updatedContent.push({\n ...contentBlock,\n text: `<name>${name}</name><content>${contentBlock.text}</content>`,\n });\n } else {\n updatedContent.push(contentBlock);\n }\n }\n\n if (!textBlockCount) {\n updatedContent.unshift({\n type: \"text\",\n text: `<name>${name}</name><content></content>`,\n });\n }\n return new AIMessage({\n ...message.lc_kwargs,\n content: updatedContent as MessageContent,\n name: undefined,\n });\n}\n\n/**\n * Remove explicit name and content XML tags from the AI message content.\n *\n * Examples:\n *\n * @example\n * ```typescript\n * removeInlineAgentName(new AIMessage({ content: \"<name>assistant</name><content>Hello</content>\", name: \"assistant\" }))\n * // AIMessage with content: \"Hello\"\n *\n * removeInlineAgentName(new AIMessage({ content: [{type: \"text\", text: \"<name>assistant</name><content>Hello</content>\"}], name: \"assistant\" }))\n * // AIMessage with content: [{type: \"text\", text: \"Hello\"}]\n * ```\n *\n * @internal\n */\nexport function _removeInlineAgentName<T extends BaseMessage>(message: T): T {\n if (!AIMessage.isInstance(message) || !message.content) {\n return message;\n }\n\n let updatedContent: MessageContent = [];\n let updatedName: string | undefined;\n\n if (Array.isArray(message.content)) {\n updatedContent = message.content\n .filter((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n // don't include empty content blocks that were added because there was no text block to modify\n if (nameMatch && (!contentMatch || contentMatch[1] === \"\")) {\n // capture name from text block\n updatedName = nameMatch[1];\n return false;\n }\n return true;\n }\n return true;\n })\n .map((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return block;\n }\n\n // capture name from text block\n updatedName = nameMatch[1];\n\n return {\n ...block,\n text: contentMatch[1],\n };\n }\n return block;\n });\n } else {\n const content = message.content as string;\n const nameMatch = content.match(NAME_PATTERN);\n const contentMatch = content.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return message;\n }\n\n updatedName = nameMatch[1];\n updatedContent = contentMatch[1];\n }\n\n return new AIMessage({\n ...(Object.keys(message.lc_kwargs ?? {}).length > 0\n ? message.lc_kwargs\n : message),\n content: updatedContent,\n name: updatedName,\n }) as T;\n}\n\nexport function isClientTool(\n tool: ClientTool | ServerTool\n): tool is ClientTool {\n return Runnable.isRunnable(tool);\n}\n\n/**\n * Helper function to check if a language model has a bindTools method.\n * @param llm - The language model to check if it has a bindTools method.\n * @returns True if the language model has a bindTools method, false otherwise.\n */\nfunction _isChatModelWithBindTools(\n llm: LanguageModelLike\n): llm is BaseChatModel & Required<Pick<BaseChatModel, \"bindTools\">> {\n if (!isBaseChatModel(llm)) return false;\n return \"bindTools\" in llm && typeof llm.bindTools === \"function\";\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nconst _simpleBindTools = (\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n) => {\n if (_isChatModelWithBindTools(llm)) {\n return llm.bindTools(toolClasses, options);\n }\n\n if (\n RunnableBinding.isRunnableBinding(llm) &&\n _isChatModelWithBindTools(llm.bound)\n ) {\n const newBound = llm.bound.bindTools(toolClasses, options);\n\n if (RunnableBinding.isRunnableBinding(newBound)) {\n return new RunnableBinding({\n bound: newBound.bound,\n config: { ...llm.config, ...newBound.config },\n kwargs: { ...llm.kwargs, ...newBound.kwargs },\n configFactories: newBound.configFactories ?? llm.configFactories,\n });\n }\n\n return new RunnableBinding({\n bound: newBound,\n config: llm.config,\n kwargs: llm.kwargs,\n configFactories: llm.configFactories,\n });\n }\n\n return null;\n};\n\n/**\n * Check if the LLM already has bound tools and throw if it does.\n *\n * @param llm - The LLM to check.\n * @returns void\n */\nexport function validateLLMHasNoBoundTools(llm: LanguageModelLike): void {\n /**\n * If llm is a function, we can't validate until runtime, so skip\n */\n if (typeof llm === \"function\") {\n return;\n }\n\n let model = llm;\n\n /**\n * If model is a RunnableSequence, find a RunnableBinding in its steps\n */\n if (RunnableSequence.isRunnableSequence(model)) {\n model =\n model.steps.find((step: RunnableLike) =>\n RunnableBinding.isRunnableBinding(step)\n ) || model;\n }\n\n /**\n * If model is configurable, get the underlying model\n */\n if (isConfigurableModel(model)) {\n /**\n * Can't validate async model retrieval in constructor\n */\n return;\n }\n\n /**\n * Check if model is a RunnableBinding with bound tools\n */\n if (RunnableBinding.isRunnableBinding(model)) {\n const hasToolsInKwargs =\n model.kwargs != null &&\n typeof model.kwargs === \"object\" &&\n \"tools\" in model.kwargs &&\n Array.isArray(model.kwargs.tools) &&\n model.kwargs.tools.length > 0;\n\n const hasToolsInConfig =\n model.config != null &&\n typeof model.config === \"object\" &&\n \"tools\" in model.config &&\n Array.isArray(model.config.tools) &&\n model.config.tools.length > 0;\n\n if (hasToolsInKwargs || hasToolsInConfig) {\n throw new MultipleToolsBoundError();\n }\n }\n\n /**\n * Also check if model has tools property directly (e.g., FakeToolCallingModel)\n */\n if (\n \"tools\" in model &&\n model.tools !== undefined &&\n Array.isArray(model.tools) &&\n model.tools.length > 0\n ) {\n throw new MultipleToolsBoundError();\n }\n}\n\n/**\n * Check if the last message in the messages array has tool calls.\n *\n * @param messages - The messages to check.\n * @returns True if the last message has tool calls, false otherwise.\n */\nexport function hasToolCalls(message?: BaseMessage): boolean {\n return Boolean(\n AIMessage.isInstance(message) &&\n message.tool_calls &&\n message.tool_calls.length > 0\n );\n}\n\n/**\n * Normalizes a system prompt to a SystemMessage object.\n * If it's already a SystemMessage, returns it as-is.\n * If it's a string, converts it to a SystemMessage.\n * If it's undefined, creates an empty system message so it is easier to append to it later.\n */\nexport function normalizeSystemPrompt(\n systemPrompt?: string | SystemMessage\n): SystemMessage {\n if (systemPrompt == null) {\n return new SystemMessage(\"\");\n }\n if (SystemMessage.isInstance(systemPrompt)) {\n return systemPrompt;\n }\n if (typeof systemPrompt === \"string\") {\n return new SystemMessage({\n content: [{ type: \"text\", text: systemPrompt }],\n });\n }\n throw new Error(\n `Invalid systemPrompt type: expected string or SystemMessage, got ${typeof systemPrompt}`\n );\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nexport async function bindTools(\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n): Promise<\n | RunnableSequence<unknown, unknown>\n | RunnableBinding<unknown, unknown, RunnableConfig<Record<string, unknown>>>\n | Runnable<BaseLanguageModelInput, AIMessageChunk, BaseChatModelCallOptions>\n> {\n const model = _simpleBindTools(llm, toolClasses, options);\n if (model) return model;\n\n if (isConfigurableModel(llm)) {\n const model = _simpleBindTools(\n await llm._getModelInstance(),\n toolClasses,\n options\n );\n if (model) return model;\n }\n\n if (RunnableSequence.isRunnableSequence(llm)) {\n const modelStep = llm.steps.findIndex(\n (step) =>\n RunnableBinding.isRunnableBinding(step) ||\n isBaseChatModel(step) ||\n isConfigurableModel(step)\n );\n\n if (modelStep >= 0) {\n const model = _simpleBindTools(\n llm.steps[modelStep],\n toolClasses,\n options\n );\n if (model) {\n const nextSteps: unknown[] = llm.steps.slice();\n nextSteps.splice(modelStep, 1, model);\n\n return RunnableSequence.from(\n nextSteps as [RunnableLike, ...RunnableLike[], RunnableLike]\n );\n }\n }\n }\n\n throw new Error(`llm ${llm} must define bindTools method.`);\n}\n\n/**\n * Compose multiple wrapToolCall handlers into a single middleware stack.\n *\n * Composes handlers so the first in the list becomes the outermost layer.\n * Each handler receives a handler callback to execute inner layers.\n *\n * @param handlers - List of handlers. First handler wraps all others.\n * @returns Composed handler, or undefined if handlers array is empty.\n *\n * @example\n * ```typescript\n * // handlers=[auth, retry] means: auth wraps retry\n * // Flow: auth calls retry, retry calls base handler\n * const auth: ToolCallWrapper = async (request, handler) => {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (error.message === \"Unauthorized\") {\n * await refreshToken();\n * return await handler(request);\n * }\n * throw error;\n * }\n * };\n *\n * const retry: ToolCallWrapper = async (request, handler) => {\n * for (let attempt = 0; attempt < 3; attempt++) {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (attempt === 2) throw error;\n * }\n * }\n * throw new Error(\"Unreachable\");\n * };\n *\n * const composedHandler = chainToolCallHandlers([auth, retry]);\n * ```\n */\nfunction chainToolCallHandlers(\n handlers: WrapToolCallHook[]\n): WrapToolCallHook | undefined {\n if (handlers.length === 0) {\n return undefined;\n }\n\n if (handlers.length === 1) {\n return handlers[0];\n }\n\n // Compose two handlers where outer wraps inner\n // The key is to properly propagate request modifications through the chain\n function composeTwo(\n outer: WrapToolCallHook,\n inner: WrapToolCallHook\n ): WrapToolCallHook {\n return async (request, handler) => {\n // Create a wrapper that calls inner with the base handler\n // The innerHandler receives the (possibly modified) request from outer\n // and passes it to inner, which then calls the base handler\n const innerHandler: ToolCallHandler = async (passedRequest) => {\n // inner receives the request passed by outer (which may be modified)\n return inner(passedRequest, handler);\n };\n\n // Call outer with the wrapped inner as its handler\n return outer(request, innerHandler);\n };\n }\n\n // Compose right-to-left: outer(inner(innermost(handler)))\n let result = handlers[handlers.length - 1];\n for (let i = handlers.length - 2; i >= 0; i--) {\n result = composeTwo(handlers[i], result);\n }\n\n return result;\n}\n\n/**\n * Wrapping `wrapToolCall` invocation so we can inject middleware name into\n * the error message.\n *\n * @param middleware list of middleware passed to the agent\n * @param state state of the agent\n * @returns single wrap function\n */\nexport function wrapToolCall(middleware: readonly AnyAgentMiddleware[]) {\n const middlewareWithWrapToolCall = middleware.filter((m) => m.wrapToolCall);\n\n if (middlewareWithWrapToolCall.length === 0) {\n return;\n }\n\n return chainToolCallHandlers(\n middlewareWithWrapToolCall.map((m) => {\n const originalHandler = m.wrapToolCall!;\n /**\n * Wrap with error handling and validation\n */\n const wrappedHandler: WrapToolCallHook = async (request, handler) => {\n /**\n * Capture the original state for this middleware's schema parsing.\n * This is important because the request may be modified (via override)\n * as it passes through the middleware chain, but each middleware\n * should always see the full original state for its schema parsing.\n */\n const originalState = request.state;\n\n /**\n * Create a handler that preserves state parsing for this middleware\n * while allowing tool/toolCall/state modifications from inner middleware\n */\n // Track exact values thrown by the downstream handler so unchanged\n // propagation is not misclassified as a failure in this middleware.\n const downstreamErrors = new Set<unknown>();\n const wrappedInnerHandler: ToolCallHandler = async (passedRequest) => {\n /**\n * Merge the passed request with the original state for parsing.\n * This ensures middleware can override tool/toolCall while\n * maintaining proper state parsing for each middleware in the chain.\n */\n const mergedState = {\n ...originalState,\n ...passedRequest.state,\n };\n try {\n return await handler({\n ...passedRequest,\n state: mergedState,\n });\n } catch (error: unknown) {\n downstreamErrors.add(error);\n throw error;\n }\n };\n\n try {\n const result = await originalHandler(\n {\n ...request,\n /**\n * override state with the state from the specific middleware\n */\n state: {\n messages: originalState.messages,\n ...(m.stateSchema\n ? parseMiddlewareState(m.stateSchema, { ...originalState })\n : {}),\n },\n } as ToolCallRequest<AgentBuiltInState, unknown>,\n wrappedInnerHandler\n );\n\n /**\n * Validate return type\n */\n if (!ToolMessage.isInstance(result) && !isCommand(result)) {\n throw new Error(\n `Invalid response from \"wrapToolCall\" in middleware \"${m.name}\": ` +\n `expected ToolMessage or Command, got ${typeof result}`\n );\n }\n\n return result;\n } catch (error: unknown) {\n if (downstreamErrors.has(error)) {\n throw error;\n }\n throw MiddlewareError.wrap(error, m.name);\n }\n };\n return wrappedHandler;\n })\n );\n}\n\n/**\n * Static LangGraph config keys propagated from ReactAgent defaults onto the\n * compiled inner graph. This ensures values set via `withConfig()` survive\n * LangGraph API loading, which unwraps ReactAgent to `.graph` before execution.\n */\nconst GRAPH_DEFAULT_CONFIG_KEYS = [\n \"callbacks\",\n \"tags\",\n \"metadata\",\n \"runName\",\n \"maxConcurrency\",\n \"recursionLimit\",\n \"configurable\",\n] as const satisfies readonly (keyof RunnableConfig)[];\n\nexport function toGraphDefaultConfig(\n config: RunnableConfig\n): Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\"> {\n const result: Record<string, unknown> = {};\n for (const key of GRAPH_DEFAULT_CONFIG_KEYS) {\n const value = config[key];\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result as Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langchain",
3
- "version": "1.5.11",
3
+ "version": "1.5.12",
4
4
  "description": "Typescript bindings for langchain",
5
5
  "author": "LangChain",
6
6
  "license": "MIT",
@@ -51,17 +51,17 @@
51
51
  "tinybench": "^6.1.4",
52
52
  "typeorm": "^1.1.0",
53
53
  "typescript": "~7.0.2",
54
- "vitest": "^4.1.8",
54
+ "vitest": "^4.1.11",
55
55
  "yaml": "^2.9.0",
56
- "@langchain/anthropic": "1.5.10",
56
+ "@langchain/anthropic": "1.5.11",
57
57
  "@langchain/aws": "1.4.5",
58
- "@langchain/core": "^1.2.10",
59
- "@langchain/fireworks": "0.2.12",
60
- "@langchain/openai": "1.5.12",
58
+ "@langchain/core": "^1.2.12",
59
+ "@langchain/fireworks": "0.2.13",
60
+ "@langchain/openai": "1.5.13",
61
61
  "@langchain/tsconfig": "0.0.1"
62
62
  },
63
63
  "peerDependencies": {
64
- "@langchain/core": "^1.2.10"
64
+ "@langchain/core": "^1.2.12"
65
65
  },
66
66
  "dependencies": {
67
67
  "@langchain/langgraph": "^1.4.13",