langchain 1.2.20 → 1.2.21

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,14 @@
1
1
  # langchain
2
2
 
3
+ ## 1.2.21
4
+
5
+ ### Patch Changes
6
+
7
+ - [#9996](https://github.com/langchain-ai/langchainjs/pull/9996) [`5113204`](https://github.com/langchain-ai/langchainjs/commit/5113204bba5eb1d0b23a4d3aae2c02ba3caf8b6b) Thanks [@christian-bromann](https://github.com/christian-bromann)! - fix(langchain): propagate subagent name in metadata
8
+
9
+ - Updated dependencies [[`8f166b1`](https://github.com/langchain-ai/langchainjs/commit/8f166b159343ae6fd0d6d44c0835ab56c0b153f4)]:
10
+ - @langchain/core@1.1.22
11
+
3
12
  ## 1.2.20
4
13
 
5
14
  ### Patch Changes
@@ -52,6 +52,7 @@ var ReactAgent = class ReactAgent {
52
52
  constructor(options, defaultConfig) {
53
53
  this.options = options;
54
54
  this.#defaultConfig = defaultConfig ?? {};
55
+ if (options.name) this.#defaultConfig = (0, __langchain_core_runnables.mergeConfigs)(this.#defaultConfig, { metadata: { lc_agent_name: options.name } });
55
56
  this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;
56
57
  /**
57
58
  * validate that model option is provided
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.cjs","names":["StateManager","options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >","defaultConfig?: RunnableConfig","#defaultConfig","#toolBehaviorVersion","validateLLMHasNoBoundTools","isClientTool","createAgentState","StateGraph","beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][]","#agentNode","AgentNode","normalizeSystemPrompt","beforeAgentNode: BeforeAgentNode | undefined","beforeModelNode: BeforeModelNode | undefined","afterModelNode: AfterModelNode | undefined","afterAgentNode: AfterAgentNode | undefined","BeforeAgentNode","#stateManager","getHookConstraint","BeforeModelNode","AfterModelNode","AfterAgentNode","AGENT_NODE_NAME","ToolNode","wrapToolCall","TOOLS_NODE_NAME","entryNode: string","END","START","parseJumpToTarget","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">","toolClasses: (ClientTool | ServerTool)[]","includeModelRequest: boolean","hasToolsAvailable: boolean","paths: BaseGraphDestination[]","shouldReturnDirect: Set<string>","exitNode: string | typeof END","state: Record<string, unknown>","ToolMessage","AIMessage","Send","allowJump: boolean","allowed: string[]","nextDefault: string","#initializeMiddlewareStates","state: InvokeStateParameter<Types>","config: RunnableConfig","Command","initializeMiddlewareStates","config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >","config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TEncoding\n >","params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\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 \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" }","streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]","config?: RunnableConfig","options?: GetStateOptions","options?: CheckpointListOptions","namespace?: string","recurse?: boolean","inputConfig: LangGraphRunnableConfig","values: Record<string, unknown> | unknown","asNode?: string"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type { CheckpointListOptions } from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaInput,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaInput<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = defaultConfig ?? {};\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(shouldReturnDirect, exitNode),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n /**\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 ) {\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 ? AGENT_NODE_NAME : exitNode;\n }\n\n // For non-returnDirect tools, always route back to agent\n return AGENT_NODE_NAME;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * For routing from afterModel nodes, always use simple string paths\n * The Send API is handled at the model_request node level\n */\n return TOOLS_NODE_NAME;\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n 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 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 false,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReactAgent.cjs","names":["StateManager","options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >","defaultConfig?: RunnableConfig","#defaultConfig","#toolBehaviorVersion","validateLLMHasNoBoundTools","isClientTool","createAgentState","StateGraph","beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][]","#agentNode","AgentNode","normalizeSystemPrompt","beforeAgentNode: BeforeAgentNode | undefined","beforeModelNode: BeforeModelNode | undefined","afterModelNode: AfterModelNode | undefined","afterAgentNode: AfterAgentNode | undefined","BeforeAgentNode","#stateManager","getHookConstraint","BeforeModelNode","AfterModelNode","AfterAgentNode","AGENT_NODE_NAME","ToolNode","wrapToolCall","TOOLS_NODE_NAME","entryNode: string","END","START","parseJumpToTarget","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">","toolClasses: (ClientTool | ServerTool)[]","includeModelRequest: boolean","hasToolsAvailable: boolean","paths: BaseGraphDestination[]","shouldReturnDirect: Set<string>","exitNode: string | typeof END","state: Record<string, unknown>","ToolMessage","AIMessage","Send","allowJump: boolean","allowed: string[]","nextDefault: string","#initializeMiddlewareStates","state: InvokeStateParameter<Types>","config: RunnableConfig","Command","initializeMiddlewareStates","config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >","config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TEncoding\n >","params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\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 \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" }","streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]","config?: RunnableConfig","options?: GetStateOptions","options?: CheckpointListOptions","namespace?: string","recurse?: boolean","inputConfig: LangGraphRunnableConfig","values: Record<string, unknown> | unknown","asNode?: string"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type { CheckpointListOptions } from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaInput,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaInput<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = defaultConfig ?? {};\n if (options.name) {\n this.#defaultConfig = mergeConfigs(this.#defaultConfig, {\n metadata: { lc_agent_name: options.name },\n });\n }\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(shouldReturnDirect, exitNode),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n /**\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 ) {\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 ? AGENT_NODE_NAME : exitNode;\n }\n\n // For non-returnDirect tools, always route back to agent\n return AGENT_NODE_NAME;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * For routing from afterModel nodes, always use simple string paths\n * The Send API is handled at the model_request node level\n */\n return TOOLS_NODE_NAME;\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n 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 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 false,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":"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"}
@@ -51,6 +51,7 @@ var ReactAgent = class ReactAgent {
51
51
  constructor(options, defaultConfig) {
52
52
  this.options = options;
53
53
  this.#defaultConfig = defaultConfig ?? {};
54
+ if (options.name) this.#defaultConfig = mergeConfigs(this.#defaultConfig, { metadata: { lc_agent_name: options.name } });
54
55
  this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;
55
56
  /**
56
57
  * validate that model option is provided
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.js","names":["options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >","defaultConfig?: RunnableConfig","#defaultConfig","#toolBehaviorVersion","beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][]","#agentNode","beforeAgentNode: BeforeAgentNode | undefined","beforeModelNode: BeforeModelNode | undefined","afterModelNode: AfterModelNode | undefined","afterAgentNode: AfterAgentNode | undefined","#stateManager","entryNode: string","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">","toolClasses: (ClientTool | ServerTool)[]","includeModelRequest: boolean","hasToolsAvailable: boolean","paths: BaseGraphDestination[]","shouldReturnDirect: Set<string>","exitNode: string | typeof END","state: Record<string, unknown>","allowJump: boolean","allowed: string[]","nextDefault: string","#initializeMiddlewareStates","state: InvokeStateParameter<Types>","config: RunnableConfig","config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >","config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TEncoding\n >","params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\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 \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" }","streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]","config?: RunnableConfig","options?: GetStateOptions","options?: CheckpointListOptions","namespace?: string","recurse?: boolean","inputConfig: LangGraphRunnableConfig","values: Record<string, unknown> | unknown","asNode?: string"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type { CheckpointListOptions } from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaInput,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaInput<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = defaultConfig ?? {};\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(shouldReturnDirect, exitNode),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n /**\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 ) {\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 ? AGENT_NODE_NAME : exitNode;\n }\n\n // For non-returnDirect tools, always route back to agent\n return AGENT_NODE_NAME;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * For routing from afterModel nodes, always use simple string paths\n * The Send API is handled at the model_request node level\n */\n return TOOLS_NODE_NAME;\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n 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 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 false,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuJA,IAAa,aAAb,MAAa,WAQX;CAQA;CAEA,uBAAoC;CAEpC;CAEA,gBAAgB,IAAI;CAEpB;CAEA,YACSA,SAKPC,eACA;EANO;EAOP,KAAKC,iBAAiB,iBAAiB,CAAE;EACzC,KAAKC,uBAAuB,QAAQ,WAAW,KAAKA;;;;AAKpD,MAAI,CAAC,QAAQ,MACX,OAAM,IAAI,MAAM;;;;AAMlB,MAAI,OAAO,QAAQ,UAAU,UAC3B,2BAA2B,QAAQ,MAAM;;;;EAM3C,MAAM,kBAAmB,KAAK,QAAQ,YAClC,OAAO,CAAC,MAAM,EAAE,MAAM,CACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAE;EAChC,MAAM,cAAc,CAAC,GAAI,QAAQ,SAAS,CAAE,GAAG,GAAG,eAAgB;;;;;EAMlE,MAAM,qBAAqB,IAAI,IAC7B,YACG,OAAO,aAAa,CACpB,OAAO,CAAC,SAAS,kBAAkB,QAAQ,KAAK,aAAa,CAC7D,IAAI,CAAC,SAAS,KAAK,KAAK;;;;;EAO7B,MAAM,EAAE,OAAO,OAAO,QAAQ,GAAG,iBAI/B,KAAK,QAAQ,mBAAmB,QAChC,KAAK,QAAQ,aACb,KAAK,QAAQ,WACd;EAED,MAAM,WAAW,IAAI,WAAW,OAAO;GACrC;GACA;GACA,SAAS,KAAK,QAAQ;EACvB;EAED,MAAM,mBAAmB;EAMzB,MAAMC,mBAIA,CAAE;EACR,MAAMC,mBAIA,CAAE;EACR,MAAMC,kBAIA,CAAE;EACR,MAAMC,kBAIA,CAAE;EACR,MAAMC,8BAMA,CAAE;EAER,KAAKC,aAAa,IAAI,UAAU;GAC9B,OAAO,KAAK,QAAQ;GACpB,eAAe,sBAAsB,KAAK,QAAQ,aAAa;GAC/D,kBAAkB,KAAK,QAAQ;GAC/B,MAAM,KAAK,QAAQ;GACnB,gBAAgB,KAAK,QAAQ;GAC7B,YAAY,KAAK,QAAQ;GACzB;GACA;GACA,QAAQ,KAAK,QAAQ;GACrB;EACD;EAED,MAAM,kCAAkB,IAAI;EAC5B,MAAM,aAAa,KAAK,QAAQ,cAAc,CAAE;AAChD,OAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;GAC1C,IAAIC;GACJ,IAAIC;GACJ,IAAIC;GACJ,IAAIC;GACJ,MAAM,IAAI,WAAW;AACrB,OAAI,gBAAgB,IAAI,EAAE,KAAK,CAC7B,OAAM,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,KAAK,0BAA0B,CAAC;GAGlE,gBAAgB,IAAI,EAAE,KAAK;AAC3B,OAAI,EAAE,aAAa;IACjB,kBAAkB,IAAI,gBAAgB,GAAG,EACvC,UAAU,MAAM,KAAKC,cAAc,SAAS,EAAE,KAAK,CACpD;IACD,KAAKA,cAAc,QAAQ,GAAG,gBAAgB;IAC9C,MAAM,OAAO,GAAG,EAAE,KAAK,aAAa,CAAC;IACrC,iBAAiB,KAAK;KACpB,OAAO;KACP;KACA,SAAS,kBAAkB,EAAE,YAAY;IAC1C,EAAC;IACF,iBAAiB,QACf,MACA,iBACA,gBAAgB,YACjB;GACF;AACD,OAAI,EAAE,aAAa;IACjB,kBAAkB,IAAI,gBAAgB,GAAG,EACvC,UAAU,MAAM,KAAKA,cAAc,SAAS,EAAE,KAAK,CACpD;IACD,KAAKA,cAAc,QAAQ,GAAG,gBAAgB;IAC9C,MAAM,OAAO,GAAG,EAAE,KAAK,aAAa,CAAC;IACrC,iBAAiB,KAAK;KACpB,OAAO;KACP;KACA,SAAS,kBAAkB,EAAE,YAAY;IAC1C,EAAC;IACF,iBAAiB,QACf,MACA,iBACA,gBAAgB,YACjB;GACF;AACD,OAAI,EAAE,YAAY;IAChB,iBAAiB,IAAI,eAAe,GAAG,EACrC,UAAU,MAAM,KAAKA,cAAc,SAAS,EAAE,KAAK,CACpD;IACD,KAAKA,cAAc,QAAQ,GAAG,eAAe;IAC7C,MAAM,OAAO,GAAG,EAAE,KAAK,YAAY,CAAC;IACpC,gBAAgB,KAAK;KACnB,OAAO;KACP;KACA,SAAS,kBAAkB,EAAE,WAAW;IACzC,EAAC;IACF,iBAAiB,QACf,MACA,gBACA,eAAe,YAChB;GACF;AACD,OAAI,EAAE,YAAY;IAChB,iBAAiB,IAAI,eAAe,GAAG,EACrC,UAAU,MAAM,KAAKA,cAAc,SAAS,EAAE,KAAK,CACpD;IACD,KAAKA,cAAc,QAAQ,GAAG,eAAe;IAC7C,MAAM,OAAO,GAAG,EAAE,KAAK,YAAY,CAAC;IACpC,gBAAgB,KAAK;KACnB,OAAO;KACP;KACA,SAAS,kBAAkB,EAAE,WAAW;IACzC,EAAC;IACF,iBAAiB,QACf,MACA,gBACA,eAAe,YAChB;GACF;AAED,OAAI,EAAE,eACJ,4BAA4B,KAAK,CAC/B,GACA,MAAM,KAAKA,cAAc,SAAS,EAAE,KAAK,AAC1C,EAAC;EAEL;;;;EAKD,iBAAiB,QAAQ,iBAAiB,KAAKL,WAAW;;;;;;EAO1D,MAAM,4BAA4B,WAAW,KAAK,CAAC,MAAM,EAAE,aAAa;EACxE,MAAM,cAAc,YAAY,OAAO,aAAa;;;;;AAMpD,MAAI,YAAY,SAAS,KAAK,2BAA2B;GACvD,MAAM,WAAW,IAAI,SAAS,aAAa;IACzC,QAAQ,KAAK,QAAQ;IACrB,cAAc,aAAa,WAAW;GACvC;GACD,iBAAiB,QAAQ,iBAAiB,SAAS;EACpD;;;;EAMD,IAAIM;AACJ,MAAI,iBAAiB,SAAS,GAC5B,YAAY,iBAAiB,GAAG;WACvB,iBAAiB,SAAS,GACnC,YAAY,iBAAiB,GAAG;OAEhC,YAAY;EAKd,MAAM,gBACJ,iBAAiB,SAAS,IAAI,iBAAiB,GAAG,OAAO;EAG3D,MAAM,WACJ,gBAAgB,SAAS,IACrB,gBAAgB,gBAAgB,SAAS,GAAG,OAC5C;EAEN,iBAAiB,QAAQ,OAAO,UAAU;;;;;EAM1C,MAAM,oBACJ,YAAY,SAAS,KAAK;AAG5B,OAAK,IAAI,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;GAChD,MAAM,OAAO,iBAAiB;GAC9B,MAAM,UAAU,KAAK;GACrB,MAAM,SAAS,MAAM,iBAAiB,SAAS;GAC/C,MAAM,cAAc,SAAS,gBAAgB,iBAAiB,IAAI,GAAG;AAErE,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;IAElE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CACN,aACA,GAAG,cAAc,IAAI,CAAC,SAAU,SAAS,MAAM,WAAW,KAAM,AACjE,GACF;IAED,iBAAiB,oBACf,SACA,KAAKC,yBACH,aACA,aACA,UACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,SAAS,YAAY;EAEjD;AAGD,OAAK,IAAI,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;GAChD,MAAM,OAAO,iBAAiB;GAC9B,MAAM,UAAU,KAAK;GACrB,MAAM,SAAS,MAAM,iBAAiB,SAAS;GAC/C,MAAM,cAAc,SAChB,kBACA,iBAAiB,IAAI,GAAG;AAE5B,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;IAClE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,aAAa,GAAG,aAAc,GACxC;IAED,iBAAiB,oBACf,SACA,KAAKC,yBACH,aACA,aACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,SAAS,YAAY;EAEjD;EAGD,MAAM,qBAAqB,gBAAgB,GAAG,GAAG;AACjD,MAAI,gBAAgB,SAAS,KAAK,oBAChC,iBAAiB,QAAQ,iBAAiB,mBAAmB,KAAK;OAC7D;GAEL,MAAM,aAAa,KAAKC,eACtB,aACA,OACA,kBACD;GAED,MAAM,eAAe,WAAW,IAAI,CAAC,MACnC,MAAM,MAAM,WAAW,EACxB;AACD,OAAI,aAAa,WAAW,GAC1B,iBAAiB,QAAQ,iBAAiB,aAAa,GAAG;QAE1D,iBAAiB,oBACf,iBACA,KAAKC,mBAAmB,SAAS,EACjC,aACD;EAEJ;AAGD,OAAK,IAAI,IAAI,gBAAgB,SAAS,GAAG,IAAI,GAAG,KAAK;GACnD,MAAM,OAAO,gBAAgB;GAC7B,MAAM,UAAU,KAAK;GACrB,MAAM,cAAc,gBAAgB,IAAI,GAAG;AAE3C,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;IAClE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,aAAa,GAAG,aAAc,GACxC;IAED,iBAAiB,oBACf,SACA,KAAKC,gCACH,aACA,KAAK,SACL,aACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,SAAS,YAAY;EAEjD;AAGD,MAAI,gBAAgB,SAAS,GAAG;GAC9B,MAAM,kBAAkB,gBAAgB;GACxC,MAAM,sBAAsB,gBAAgB;GAG5C,MAAM,aAAa,KAAKF,eACtB,aACA,MACA,kBACD,CAAC,OAAO,CAAC,MAAM,MAAM,mBAAmB,kBAAkB;GAE3D,MAAM,YAAY,QAChB,gBAAgB,WAAW,gBAAgB,QAAQ,SAAS,EAC7D;GAGD,MAAM,eAAe,WAAW,IAAI,CAAC,MACnC,MAAM,MAAM,WAAW,EACxB;GAED,iBAAiB,oBACf,qBACA,KAAKG,wBACH,aACA,WACA,UACA,kBACD,EACD,aACD;EACF;AAGD,OAAK,IAAI,IAAI,gBAAgB,SAAS,GAAG,IAAI,GAAG,KAAK;GACnD,MAAM,OAAO,gBAAgB;GAC7B,MAAM,UAAU,KAAK;GACrB,MAAM,cAAc,gBAAgB,IAAI,GAAG;AAE3C,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;IAClE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,aAAa,GAAG,aAAc,GACxC;IAED,iBAAiB,oBACf,SACA,KAAKD,gCACH,aACA,KAAK,SACL,aACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,SAAS,YAAY;EAEjD;AAGD,MAAI,gBAAgB,SAAS,GAAG;GAC9B,MAAM,kBAAkB,gBAAgB;GACxC,MAAM,sBAAsB,gBAAgB;AAE5C,OAAI,gBAAgB,WAAW,gBAAgB,QAAQ,SAAS,GAAG;IACjE,MAAM,gBAAgB,gBAAgB,QACnC,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;;;;;IAMlE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,KAAK,GAAG,aAAc,GAChC;IAED,iBAAiB,oBACf,qBACA,KAAKA,gCACH,aACA,gBAAgB,SAChB,KACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,qBAAqB,IAAI;EAErD;;;;AAKD,MAAI,mBAAmB;GAErB,MAAM,mBAAmB;AAEzB,OAAI,mBAAmB,OAAO,GAC5B,iBAAiB,oBACf,iBACA,KAAKE,mBAAmB,oBAAoB,SAAS,EACrD,CAAC,kBAAkB,QAAmB,EACvC;QAED,iBAAiB,QAAQ,iBAAiB,iBAAiB;EAE9D;;;;EAKD,KAAKC,SAAS,iBAAiB,QAAQ;GACrC,cAAc,KAAK,QAAQ;GAC3B,OAAO,KAAK,QAAQ;GACpB,MAAM,KAAK,QAAQ;GACnB,aAAa,KAAK,QAAQ;EAC3B,EAAC;CACH;;;;CAKD,IAAI,QAA2B;AAC7B,SAAO,KAAKA;CACb;;;;;;;;;;;;;;;;;;;;;;;;CAyBD,WACEC,QACmB;AACnB,SAAO,IAAI,WACT,KAAK,SACL,aAAa,KAAKtB,gBAAgB,OAAO;CAE5C;;;;;;;;CASD,eACEuB,aACAC,sBAA+B,OAC/BC,oBAA6B,YAAY,SAAS,GAC1B;EACxB,MAAMC,QAAgC,CAAE;AACxC,MAAI,mBACF,MAAM,KAAK,gBAAgB;AAG7B,MAAI,qBACF,MAAM,KAAK,gBAAgB;EAG7B,MAAM,KAAK,IAAI;AAEf,SAAO;CACR;;;;CAKD,mBACEC,oBACAC,UACA;AACA,SAAO,CAACC,UAAmC;GACzC,MAAM,eAAe;GACrB,MAAM,WAAW,aAAa;GAC9B,MAAM,cAAc,SAAS,SAAS,SAAS;AAG/C,OACE,YAAY,WAAW,YAAY,IACnC,YAAY,QACZ,mBAAmB,IAAI,YAAY,KAAK,CAIxC,QAAO,KAAK,QAAQ,iBAAiB,kBAAkB;AAIzD,UAAO;EACR;CACF;;;;;CAMD,mBAAmBD,WAAgC,KAAK;;;;AAItD,SAAO,CAACC,UAAmC;GACzC,MAAM,eAAe;GACrB,MAAM,WAAW,aAAa;GAC9B,MAAM,cAAc,SAAS,GAAG,GAAG;AAEnC,OACE,CAAC,UAAU,WAAW,YAAY,IAClC,CAAC,YAAY,cACb,YAAY,WAAW,WAAW,EAElC,QAAO;GAIT,MAAM,iCAAiC,YAAY,WAAW,MAC5D,CAAC,aAAa,SAAS,KAAK,WAAW,WAAW,CACnD;AAED,OAAI,+BAGF,QAAO;;;;AAMT,OAAI,KAAK5B,yBAAyB,KAChC,QAAO;;;;GAMT,MAAM,mBAAmB,YAAY,WAAW,OAC9C,CAAC,aAAa,CAAC,SAAS,KAAK,WAAW,WAAW,CACpD;AAED,OAAI,iBAAiB,WAAW,EAC9B,QAAO;AAGT,UAAO,iBAAiB,IACtB,CAAC,aACC,IAAI,KAAK,iBAAiB;IAAE,GAAG;IAAO,cAAc;GAAU,GACjE;EACF;CACF;;;;;;;;;;;;;;;;CAiBD,wBACEsB,aACAO,WACAF,UACAH,oBAA6B,YAAY,SAAS,GAClD;EACA,MAAM,wBAAwB,QAAQ,KAAK,QAAQ,eAAe;AAElE,SAAO,CAACI,UAAmC;GACzC,MAAM,eAAe;GAKrB,MAAM,WAAW,aAAa;GAC9B,MAAM,cAAc,SAAS,GAAG,GAAG;AACnC,OACE,UAAU,WAAW,YAAY,KAChC,CAAC,YAAY,cAAc,YAAY,WAAW,WAAW,GAE9D,QAAO;AAIT,OAAI,aAAa,aAAa,QAAQ;IACpC,MAAM,cAAc,kBAAkB,aAAa,OAAO;AAC1D,QAAI,gBAAgB,IAClB,QAAO;AAET,QAAI,gBAAgB,iBAAiB;AAEnC,SAAI,CAAC,kBACH,QAAO;AAET,YAAO,IAAI,KAAK,iBAAiB;MAAE,GAAG;MAAO,QAAQ;KAAW;IACjE;AAED,WAAO,IAAI,KAAK,iBAAiB;KAAE,GAAG;KAAO,QAAQ;IAAW;GACjE;GAGD,MAAM,eAAe,SAAS,OAAO,YAAY,WAAW;GAC5D,MAAM,gBAAgB,SAAS,OAAO,UAAU,WAAW,CAAC,GAAG,GAAG;GAClE,MAAM,mBAAmB,eAAe,YAAY,OAClD,CAAC,SAAS,CAAC,aAAa,KAAK,CAAC,MAAM,EAAE,iBAAiB,KAAK,GAAG,CAChE;AACD,OAAI,oBAAoB,iBAAiB,SAAS,EAChD,QAAO,iBAAiB,IACtB,CAAC,aACC,IAAI,KAAK,iBAAiB;IAAE,GAAG;IAAO,cAAc;GAAU,GACjE;GAKH,MAAM,6BAA6B,eAAe,YAAY,KAC5D,CAAC,aAAa,SAAS,KAAK,WAAW,WAAW,CACnD;AAED,OACE,oBACA,iBAAiB,WAAW,KAC5B,CAAC,8BACD,sBAEA,QAAO;AAGT,OACE,CAAC,UAAU,WAAW,YAAY,IAClC,CAAC,YAAY,cACb,YAAY,WAAW,WAAW,EAElC,QAAO;GAIT,MAAM,iCAAiC,YAAY,WAAW,MAC5D,CAAC,aAAa,SAAS,KAAK,WAAW,WAAW,CACnD;GAGD,MAAM,sBAAsB,YAAY,WAAW,KACjD,CAAC,aAAa,CAAC,SAAS,KAAK,WAAW,WAAW,CACpD;AAED,OAAI,kCAAkC,CAAC,oBACrC,QAAO;;;;;AAOT,UAAO;EACR;CACF;;;;;;;;;CAUD,gCACEN,aACAQ,SACAC,aACAP,oBAA6B,YAAY,SAAS,GAClD;EACA,MAAM,aAAa,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC;AACnE,SAAO,CAACI,UAAmC;GACzC,MAAM,eAAe;AACrB,OAAI,aAAa,QAAQ;IACvB,MAAM,OAAO,kBAAkB,aAAa,OAAO;AACnD,QAAI,SAAS,OAAO,WAAW,IAAI,IAAI,CACrC,QAAO;AAET,QAAI,SAAS,mBAAmB,WAAW,IAAI,gBAAgB,EAAE;AAC/D,SAAI,CAAC,kBAAmB,QAAO;AAC/B,YAAO,IAAI,KAAK,iBAAiB;MAAE,GAAG;MAAO,QAAQ;KAAW;IACjE;AACD,QAAI,SAAS,mBAAmB,WAAW,IAAI,gBAAgB,CAC7D,QAAO,IAAI,KAAK,iBAAiB;KAAE,GAAG;KAAO,QAAQ;IAAW;GAEnE;AACD,UAAO;EACR;CACF;;;;;;;;;;CAWD,yBACEN,aACAS,aACAJ,UACAH,oBAA6B,YAAY,SAAS,GAClD;AACA,SAAO,CAACI,UAAmC;GACzC,MAAM,eAAe;AACrB,OAAI,CAAC,aAAa,OAChB,QAAO;GAET,MAAM,cAAc,kBAAkB,aAAa,OAAO;AAC1D,OAAI,gBAAgB;;;;AAIlB,UAAO;AAET,OAAI,gBAAgB,iBAAiB;AACnC,QAAI,CAAC,kBACH,QAAO;AAET,WAAO,IAAI,KAAK,iBAAiB;KAAE,GAAG;KAAO,QAAQ;IAAW;GACjE;AACD,UAAO,IAAI,KAAK,iBAAiB;IAAE,GAAG;IAAO,QAAQ;GAAW;EACjE;CACF;;;;;;;;CASD,yBACEN,aACAS,aACAP,oBAA6B,YAAY,SAAS,GAClD;AACA,SAAO,CAACI,UAAmC;GACzC,MAAM,eAAe;AACrB,OAAI,CAAC,aAAa,OAChB,QAAO;GAET,MAAM,cAAc,kBAAkB,aAAa,OAAO;AAC1D,OAAI,gBAAgB,IAClB,QAAO;AAET,OAAI,gBAAgB,iBAAiB;AACnC,QAAI,CAAC,kBACH,QAAO;AAET,WAAO,IAAI,KAAK,iBAAiB;KAAE,GAAG;KAAO,QAAQ;IAAW;GACjE;AACD,UAAO,IAAI,KAAK,iBAAiB;IAAE,GAAG;IAAO,QAAQ;GAAW;EACjE;CACF;;;;CAKD,MAAMI,4BACJC,OACAC,QACsC;AACtC,MACE,CAAC,KAAK,QAAQ,cACd,KAAK,QAAQ,WAAW,WAAW,KACnC,iBAAiB,WACjB,CAAC,MAED,QAAO;EAGT,MAAM,gBAAgB,MAAM,2BAC1B,KAAK,QAAQ,YACb,MACD;EACD,MAAM,cAAc,MAAM,KAAKd,OAC5B,SAAS,OAAO,CAChB,MAAM,OAAO,EAAE,QAAQ,CAAE,EAAE,GAAE;EAChC,MAAM,eAAe;GACnB,GAAG,YAAY;GACf,GAAG;EACJ;AACD,MAAI,CAAC,aACH,QAAO;AAIT,OAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,cAAc,CACtD,KAAI,EAAE,OAAO,eACX,aAAa,OAAoC;AAIrD,SAAO;CACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CD,MAAM,OACJa,OACAE,QAQA;EAEA,MAAM,eAAe,aAAa,KAAKpC,gBAAgB,OAAO;EAC9D,MAAM,mBAAmB,MAAM,KAAKiC,4BAClC,OACA,aACD;AAED,SAAO,KAAKZ,OAAO,OACjB,kBACA,aAMD;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CD,MAAM,OAIJa,OACAG,QAUA;EACA,MAAM,eAAe,aAAa,KAAKrC,gBAAgB,OAAO;EAC9D,MAAM,mBAAmB,MAAM,KAAKiC,4BAClC,OACA,aACD;AACD,SAAO,KAAKZ,OAAO,OACjB,kBACA,aACD;CAcF;;;;;;;;;;;CAYD,MAAM,eAAeiB,QAMlB;EACD,MAAM,iBAAiB,MAAM,KAAKjB,OAAO,eAAe;EACxD,MAAM,QAAQ,MAAM,eAAe,eAAe,OAAO;EACzD,MAAM,cAAc,MAAM,MAAM,aAAa;EAC7C,MAAM,SAAS,IAAI,WAAW;AAC9B,SAAO;CACR;;;;;;;;;;;CAYD,MAAM,YAAYiB,QAMf;EACD,MAAM,iBAAiB,MAAM,KAAKjB,OAAO,eAAe;AACxD,SAAO,eAAe,YAAY,OAAO;CAC1C;;;;;;;;;;CAYD,aACEa,OACAK,QAUAC,eACqC;EACrC,MAAM,eAAe,aAAa,KAAKxC,gBAAgB,OAAO;AAC9D,SAAO,KAAKqB,OAAO,aACjB,OACA;GACE,GAAI;GAUJ,SAAS,QAAQ,WAAW;EAC7B,GACD,cACD;CACF;;;;CAID,cAAcoB,QAAyB;AACrC,SAAO,KAAKpB,OAAO,cAAc,OAAO;CACzC;;;;CAID,SAASc,QAAwBO,SAA2B;AAC1D,SAAO,KAAKrB,OAAO,SAAS,QAAQ,QAAQ;CAC7C;;;;CAID,gBAAgBc,QAAwBQ,SAAiC;AACvE,SAAO,KAAKtB,OAAO,gBAAgB,QAAQ,QAAQ;CACpD;;;;CAID,aAAauB,WAAoBC,SAAmB;AAClD,SAAO,KAAKxB,OAAO,aAAa,WAAW,QAAQ;CACpD;;;;CAID,iBAAiBuB,WAAoBC,SAAmB;AACtD,SAAO,KAAKxB,OAAO,kBAAkB,WAAW,QAAQ;CACzD;;;;CAID,YACEyB,aACAC,QACAC,QACA;AACA,SAAO,KAAK3B,OAAO,YAAY,aAAa,QAAQ,OAAO;CAC5D;;;;CAKD,IAAI,UAAU;AACZ,SAAO,KAAKA,OAAO;CACpB;AACF"}
1
+ {"version":3,"file":"ReactAgent.js","names":["options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >","defaultConfig?: RunnableConfig","#defaultConfig","#toolBehaviorVersion","beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][]","#agentNode","beforeAgentNode: BeforeAgentNode | undefined","beforeModelNode: BeforeModelNode | undefined","afterModelNode: AfterModelNode | undefined","afterAgentNode: AfterAgentNode | undefined","#stateManager","entryNode: string","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">","toolClasses: (ClientTool | ServerTool)[]","includeModelRequest: boolean","hasToolsAvailable: boolean","paths: BaseGraphDestination[]","shouldReturnDirect: Set<string>","exitNode: string | typeof END","state: Record<string, unknown>","allowJump: boolean","allowed: string[]","nextDefault: string","#initializeMiddlewareStates","state: InvokeStateParameter<Types>","config: RunnableConfig","config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >","config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TEncoding\n >","params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\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 \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" }","streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]","config?: RunnableConfig","options?: GetStateOptions","options?: CheckpointListOptions","namespace?: string","recurse?: boolean","inputConfig: LangGraphRunnableConfig","values: Record<string, unknown> | unknown","asNode?: string"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type { CheckpointListOptions } from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaInput,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaInput<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = defaultConfig ?? {};\n if (options.name) {\n this.#defaultConfig = mergeConfigs(this.#defaultConfig, {\n metadata: { lc_agent_name: options.name },\n });\n }\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(shouldReturnDirect, exitNode),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n /**\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 ) {\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 ? AGENT_NODE_NAME : exitNode;\n }\n\n // For non-returnDirect tools, always route back to agent\n return AGENT_NODE_NAME;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * For routing from afterModel nodes, always use simple string paths\n * The Send API is handled at the model_request node level\n */\n return TOOLS_NODE_NAME;\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n 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 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 false,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuJA,IAAa,aAAb,MAAa,WAQX;CAQA;CAEA,uBAAoC;CAEpC;CAEA,gBAAgB,IAAI;CAEpB;CAEA,YACSA,SAKPC,eACA;EANO;EAOP,KAAKC,iBAAiB,iBAAiB,CAAE;AACzC,MAAI,QAAQ,MACV,KAAKA,iBAAiB,aAAa,KAAKA,gBAAgB,EACtD,UAAU,EAAE,eAAe,QAAQ,KAAM,EAC1C,EAAC;EAEJ,KAAKC,uBAAuB,QAAQ,WAAW,KAAKA;;;;AAKpD,MAAI,CAAC,QAAQ,MACX,OAAM,IAAI,MAAM;;;;AAMlB,MAAI,OAAO,QAAQ,UAAU,UAC3B,2BAA2B,QAAQ,MAAM;;;;EAM3C,MAAM,kBAAmB,KAAK,QAAQ,YAClC,OAAO,CAAC,MAAM,EAAE,MAAM,CACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAE;EAChC,MAAM,cAAc,CAAC,GAAI,QAAQ,SAAS,CAAE,GAAG,GAAG,eAAgB;;;;;EAMlE,MAAM,qBAAqB,IAAI,IAC7B,YACG,OAAO,aAAa,CACpB,OAAO,CAAC,SAAS,kBAAkB,QAAQ,KAAK,aAAa,CAC7D,IAAI,CAAC,SAAS,KAAK,KAAK;;;;;EAO7B,MAAM,EAAE,OAAO,OAAO,QAAQ,GAAG,iBAI/B,KAAK,QAAQ,mBAAmB,QAChC,KAAK,QAAQ,aACb,KAAK,QAAQ,WACd;EAED,MAAM,WAAW,IAAI,WAAW,OAAO;GACrC;GACA;GACA,SAAS,KAAK,QAAQ;EACvB;EAED,MAAM,mBAAmB;EAMzB,MAAMC,mBAIA,CAAE;EACR,MAAMC,mBAIA,CAAE;EACR,MAAMC,kBAIA,CAAE;EACR,MAAMC,kBAIA,CAAE;EACR,MAAMC,8BAMA,CAAE;EAER,KAAKC,aAAa,IAAI,UAAU;GAC9B,OAAO,KAAK,QAAQ;GACpB,eAAe,sBAAsB,KAAK,QAAQ,aAAa;GAC/D,kBAAkB,KAAK,QAAQ;GAC/B,MAAM,KAAK,QAAQ;GACnB,gBAAgB,KAAK,QAAQ;GAC7B,YAAY,KAAK,QAAQ;GACzB;GACA;GACA,QAAQ,KAAK,QAAQ;GACrB;EACD;EAED,MAAM,kCAAkB,IAAI;EAC5B,MAAM,aAAa,KAAK,QAAQ,cAAc,CAAE;AAChD,OAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;GAC1C,IAAIC;GACJ,IAAIC;GACJ,IAAIC;GACJ,IAAIC;GACJ,MAAM,IAAI,WAAW;AACrB,OAAI,gBAAgB,IAAI,EAAE,KAAK,CAC7B,OAAM,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,KAAK,0BAA0B,CAAC;GAGlE,gBAAgB,IAAI,EAAE,KAAK;AAC3B,OAAI,EAAE,aAAa;IACjB,kBAAkB,IAAI,gBAAgB,GAAG,EACvC,UAAU,MAAM,KAAKC,cAAc,SAAS,EAAE,KAAK,CACpD;IACD,KAAKA,cAAc,QAAQ,GAAG,gBAAgB;IAC9C,MAAM,OAAO,GAAG,EAAE,KAAK,aAAa,CAAC;IACrC,iBAAiB,KAAK;KACpB,OAAO;KACP;KACA,SAAS,kBAAkB,EAAE,YAAY;IAC1C,EAAC;IACF,iBAAiB,QACf,MACA,iBACA,gBAAgB,YACjB;GACF;AACD,OAAI,EAAE,aAAa;IACjB,kBAAkB,IAAI,gBAAgB,GAAG,EACvC,UAAU,MAAM,KAAKA,cAAc,SAAS,EAAE,KAAK,CACpD;IACD,KAAKA,cAAc,QAAQ,GAAG,gBAAgB;IAC9C,MAAM,OAAO,GAAG,EAAE,KAAK,aAAa,CAAC;IACrC,iBAAiB,KAAK;KACpB,OAAO;KACP;KACA,SAAS,kBAAkB,EAAE,YAAY;IAC1C,EAAC;IACF,iBAAiB,QACf,MACA,iBACA,gBAAgB,YACjB;GACF;AACD,OAAI,EAAE,YAAY;IAChB,iBAAiB,IAAI,eAAe,GAAG,EACrC,UAAU,MAAM,KAAKA,cAAc,SAAS,EAAE,KAAK,CACpD;IACD,KAAKA,cAAc,QAAQ,GAAG,eAAe;IAC7C,MAAM,OAAO,GAAG,EAAE,KAAK,YAAY,CAAC;IACpC,gBAAgB,KAAK;KACnB,OAAO;KACP;KACA,SAAS,kBAAkB,EAAE,WAAW;IACzC,EAAC;IACF,iBAAiB,QACf,MACA,gBACA,eAAe,YAChB;GACF;AACD,OAAI,EAAE,YAAY;IAChB,iBAAiB,IAAI,eAAe,GAAG,EACrC,UAAU,MAAM,KAAKA,cAAc,SAAS,EAAE,KAAK,CACpD;IACD,KAAKA,cAAc,QAAQ,GAAG,eAAe;IAC7C,MAAM,OAAO,GAAG,EAAE,KAAK,YAAY,CAAC;IACpC,gBAAgB,KAAK;KACnB,OAAO;KACP;KACA,SAAS,kBAAkB,EAAE,WAAW;IACzC,EAAC;IACF,iBAAiB,QACf,MACA,gBACA,eAAe,YAChB;GACF;AAED,OAAI,EAAE,eACJ,4BAA4B,KAAK,CAC/B,GACA,MAAM,KAAKA,cAAc,SAAS,EAAE,KAAK,AAC1C,EAAC;EAEL;;;;EAKD,iBAAiB,QAAQ,iBAAiB,KAAKL,WAAW;;;;;;EAO1D,MAAM,4BAA4B,WAAW,KAAK,CAAC,MAAM,EAAE,aAAa;EACxE,MAAM,cAAc,YAAY,OAAO,aAAa;;;;;AAMpD,MAAI,YAAY,SAAS,KAAK,2BAA2B;GACvD,MAAM,WAAW,IAAI,SAAS,aAAa;IACzC,QAAQ,KAAK,QAAQ;IACrB,cAAc,aAAa,WAAW;GACvC;GACD,iBAAiB,QAAQ,iBAAiB,SAAS;EACpD;;;;EAMD,IAAIM;AACJ,MAAI,iBAAiB,SAAS,GAC5B,YAAY,iBAAiB,GAAG;WACvB,iBAAiB,SAAS,GACnC,YAAY,iBAAiB,GAAG;OAEhC,YAAY;EAKd,MAAM,gBACJ,iBAAiB,SAAS,IAAI,iBAAiB,GAAG,OAAO;EAG3D,MAAM,WACJ,gBAAgB,SAAS,IACrB,gBAAgB,gBAAgB,SAAS,GAAG,OAC5C;EAEN,iBAAiB,QAAQ,OAAO,UAAU;;;;;EAM1C,MAAM,oBACJ,YAAY,SAAS,KAAK;AAG5B,OAAK,IAAI,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;GAChD,MAAM,OAAO,iBAAiB;GAC9B,MAAM,UAAU,KAAK;GACrB,MAAM,SAAS,MAAM,iBAAiB,SAAS;GAC/C,MAAM,cAAc,SAAS,gBAAgB,iBAAiB,IAAI,GAAG;AAErE,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;IAElE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CACN,aACA,GAAG,cAAc,IAAI,CAAC,SAAU,SAAS,MAAM,WAAW,KAAM,AACjE,GACF;IAED,iBAAiB,oBACf,SACA,KAAKC,yBACH,aACA,aACA,UACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,SAAS,YAAY;EAEjD;AAGD,OAAK,IAAI,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;GAChD,MAAM,OAAO,iBAAiB;GAC9B,MAAM,UAAU,KAAK;GACrB,MAAM,SAAS,MAAM,iBAAiB,SAAS;GAC/C,MAAM,cAAc,SAChB,kBACA,iBAAiB,IAAI,GAAG;AAE5B,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;IAClE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,aAAa,GAAG,aAAc,GACxC;IAED,iBAAiB,oBACf,SACA,KAAKC,yBACH,aACA,aACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,SAAS,YAAY;EAEjD;EAGD,MAAM,qBAAqB,gBAAgB,GAAG,GAAG;AACjD,MAAI,gBAAgB,SAAS,KAAK,oBAChC,iBAAiB,QAAQ,iBAAiB,mBAAmB,KAAK;OAC7D;GAEL,MAAM,aAAa,KAAKC,eACtB,aACA,OACA,kBACD;GAED,MAAM,eAAe,WAAW,IAAI,CAAC,MACnC,MAAM,MAAM,WAAW,EACxB;AACD,OAAI,aAAa,WAAW,GAC1B,iBAAiB,QAAQ,iBAAiB,aAAa,GAAG;QAE1D,iBAAiB,oBACf,iBACA,KAAKC,mBAAmB,SAAS,EACjC,aACD;EAEJ;AAGD,OAAK,IAAI,IAAI,gBAAgB,SAAS,GAAG,IAAI,GAAG,KAAK;GACnD,MAAM,OAAO,gBAAgB;GAC7B,MAAM,UAAU,KAAK;GACrB,MAAM,cAAc,gBAAgB,IAAI,GAAG;AAE3C,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;IAClE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,aAAa,GAAG,aAAc,GACxC;IAED,iBAAiB,oBACf,SACA,KAAKC,gCACH,aACA,KAAK,SACL,aACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,SAAS,YAAY;EAEjD;AAGD,MAAI,gBAAgB,SAAS,GAAG;GAC9B,MAAM,kBAAkB,gBAAgB;GACxC,MAAM,sBAAsB,gBAAgB;GAG5C,MAAM,aAAa,KAAKF,eACtB,aACA,MACA,kBACD,CAAC,OAAO,CAAC,MAAM,MAAM,mBAAmB,kBAAkB;GAE3D,MAAM,YAAY,QAChB,gBAAgB,WAAW,gBAAgB,QAAQ,SAAS,EAC7D;GAGD,MAAM,eAAe,WAAW,IAAI,CAAC,MACnC,MAAM,MAAM,WAAW,EACxB;GAED,iBAAiB,oBACf,qBACA,KAAKG,wBACH,aACA,WACA,UACA,kBACD,EACD,aACD;EACF;AAGD,OAAK,IAAI,IAAI,gBAAgB,SAAS,GAAG,IAAI,GAAG,KAAK;GACnD,MAAM,OAAO,gBAAgB;GAC7B,MAAM,UAAU,KAAK;GACrB,MAAM,cAAc,gBAAgB,IAAI,GAAG;AAE3C,OAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;IAC3C,MAAM,gBAAgB,KAAK,QACxB,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;IAClE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,aAAa,GAAG,aAAc,GACxC;IAED,iBAAiB,oBACf,SACA,KAAKD,gCACH,aACA,KAAK,SACL,aACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,SAAS,YAAY;EAEjD;AAGD,MAAI,gBAAgB,SAAS,GAAG;GAC9B,MAAM,kBAAkB,gBAAgB;GACxC,MAAM,sBAAsB,gBAAgB;AAE5C,OAAI,gBAAgB,WAAW,gBAAgB,QAAQ,SAAS,GAAG;IACjE,MAAM,gBAAgB,gBAAgB,QACnC,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAChC,OAAO,CAAC,SAAS,SAAS,mBAAmB,kBAAkB;;;;;IAMlE,MAAM,eAAe,MAAM,KACzB,IAAI,IAAI,CAAC,KAAK,GAAG,aAAc,GAChC;IAED,iBAAiB,oBACf,qBACA,KAAKA,gCACH,aACA,gBAAgB,SAChB,KACA,kBACD,EACD,aACD;GACF,OACC,iBAAiB,QAAQ,qBAAqB,IAAI;EAErD;;;;AAKD,MAAI,mBAAmB;GAErB,MAAM,mBAAmB;AAEzB,OAAI,mBAAmB,OAAO,GAC5B,iBAAiB,oBACf,iBACA,KAAKE,mBAAmB,oBAAoB,SAAS,EACrD,CAAC,kBAAkB,QAAmB,EACvC;QAED,iBAAiB,QAAQ,iBAAiB,iBAAiB;EAE9D;;;;EAKD,KAAKC,SAAS,iBAAiB,QAAQ;GACrC,cAAc,KAAK,QAAQ;GAC3B,OAAO,KAAK,QAAQ;GACpB,MAAM,KAAK,QAAQ;GACnB,aAAa,KAAK,QAAQ;EAC3B,EAAC;CACH;;;;CAKD,IAAI,QAA2B;AAC7B,SAAO,KAAKA;CACb;;;;;;;;;;;;;;;;;;;;;;;;CAyBD,WACEC,QACmB;AACnB,SAAO,IAAI,WACT,KAAK,SACL,aAAa,KAAKtB,gBAAgB,OAAO;CAE5C;;;;;;;;CASD,eACEuB,aACAC,sBAA+B,OAC/BC,oBAA6B,YAAY,SAAS,GAC1B;EACxB,MAAMC,QAAgC,CAAE;AACxC,MAAI,mBACF,MAAM,KAAK,gBAAgB;AAG7B,MAAI,qBACF,MAAM,KAAK,gBAAgB;EAG7B,MAAM,KAAK,IAAI;AAEf,SAAO;CACR;;;;CAKD,mBACEC,oBACAC,UACA;AACA,SAAO,CAACC,UAAmC;GACzC,MAAM,eAAe;GACrB,MAAM,WAAW,aAAa;GAC9B,MAAM,cAAc,SAAS,SAAS,SAAS;AAG/C,OACE,YAAY,WAAW,YAAY,IACnC,YAAY,QACZ,mBAAmB,IAAI,YAAY,KAAK,CAIxC,QAAO,KAAK,QAAQ,iBAAiB,kBAAkB;AAIzD,UAAO;EACR;CACF;;;;;CAMD,mBAAmBD,WAAgC,KAAK;;;;AAItD,SAAO,CAACC,UAAmC;GACzC,MAAM,eAAe;GACrB,MAAM,WAAW,aAAa;GAC9B,MAAM,cAAc,SAAS,GAAG,GAAG;AAEnC,OACE,CAAC,UAAU,WAAW,YAAY,IAClC,CAAC,YAAY,cACb,YAAY,WAAW,WAAW,EAElC,QAAO;GAIT,MAAM,iCAAiC,YAAY,WAAW,MAC5D,CAAC,aAAa,SAAS,KAAK,WAAW,WAAW,CACnD;AAED,OAAI,+BAGF,QAAO;;;;AAMT,OAAI,KAAK5B,yBAAyB,KAChC,QAAO;;;;GAMT,MAAM,mBAAmB,YAAY,WAAW,OAC9C,CAAC,aAAa,CAAC,SAAS,KAAK,WAAW,WAAW,CACpD;AAED,OAAI,iBAAiB,WAAW,EAC9B,QAAO;AAGT,UAAO,iBAAiB,IACtB,CAAC,aACC,IAAI,KAAK,iBAAiB;IAAE,GAAG;IAAO,cAAc;GAAU,GACjE;EACF;CACF;;;;;;;;;;;;;;;;CAiBD,wBACEsB,aACAO,WACAF,UACAH,oBAA6B,YAAY,SAAS,GAClD;EACA,MAAM,wBAAwB,QAAQ,KAAK,QAAQ,eAAe;AAElE,SAAO,CAACI,UAAmC;GACzC,MAAM,eAAe;GAKrB,MAAM,WAAW,aAAa;GAC9B,MAAM,cAAc,SAAS,GAAG,GAAG;AACnC,OACE,UAAU,WAAW,YAAY,KAChC,CAAC,YAAY,cAAc,YAAY,WAAW,WAAW,GAE9D,QAAO;AAIT,OAAI,aAAa,aAAa,QAAQ;IACpC,MAAM,cAAc,kBAAkB,aAAa,OAAO;AAC1D,QAAI,gBAAgB,IAClB,QAAO;AAET,QAAI,gBAAgB,iBAAiB;AAEnC,SAAI,CAAC,kBACH,QAAO;AAET,YAAO,IAAI,KAAK,iBAAiB;MAAE,GAAG;MAAO,QAAQ;KAAW;IACjE;AAED,WAAO,IAAI,KAAK,iBAAiB;KAAE,GAAG;KAAO,QAAQ;IAAW;GACjE;GAGD,MAAM,eAAe,SAAS,OAAO,YAAY,WAAW;GAC5D,MAAM,gBAAgB,SAAS,OAAO,UAAU,WAAW,CAAC,GAAG,GAAG;GAClE,MAAM,mBAAmB,eAAe,YAAY,OAClD,CAAC,SAAS,CAAC,aAAa,KAAK,CAAC,MAAM,EAAE,iBAAiB,KAAK,GAAG,CAChE;AACD,OAAI,oBAAoB,iBAAiB,SAAS,EAChD,QAAO,iBAAiB,IACtB,CAAC,aACC,IAAI,KAAK,iBAAiB;IAAE,GAAG;IAAO,cAAc;GAAU,GACjE;GAKH,MAAM,6BAA6B,eAAe,YAAY,KAC5D,CAAC,aAAa,SAAS,KAAK,WAAW,WAAW,CACnD;AAED,OACE,oBACA,iBAAiB,WAAW,KAC5B,CAAC,8BACD,sBAEA,QAAO;AAGT,OACE,CAAC,UAAU,WAAW,YAAY,IAClC,CAAC,YAAY,cACb,YAAY,WAAW,WAAW,EAElC,QAAO;GAIT,MAAM,iCAAiC,YAAY,WAAW,MAC5D,CAAC,aAAa,SAAS,KAAK,WAAW,WAAW,CACnD;GAGD,MAAM,sBAAsB,YAAY,WAAW,KACjD,CAAC,aAAa,CAAC,SAAS,KAAK,WAAW,WAAW,CACpD;AAED,OAAI,kCAAkC,CAAC,oBACrC,QAAO;;;;;AAOT,UAAO;EACR;CACF;;;;;;;;;CAUD,gCACEN,aACAQ,SACAC,aACAP,oBAA6B,YAAY,SAAS,GAClD;EACA,MAAM,aAAa,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,kBAAkB,EAAE,CAAC;AACnE,SAAO,CAACI,UAAmC;GACzC,MAAM,eAAe;AACrB,OAAI,aAAa,QAAQ;IACvB,MAAM,OAAO,kBAAkB,aAAa,OAAO;AACnD,QAAI,SAAS,OAAO,WAAW,IAAI,IAAI,CACrC,QAAO;AAET,QAAI,SAAS,mBAAmB,WAAW,IAAI,gBAAgB,EAAE;AAC/D,SAAI,CAAC,kBAAmB,QAAO;AAC/B,YAAO,IAAI,KAAK,iBAAiB;MAAE,GAAG;MAAO,QAAQ;KAAW;IACjE;AACD,QAAI,SAAS,mBAAmB,WAAW,IAAI,gBAAgB,CAC7D,QAAO,IAAI,KAAK,iBAAiB;KAAE,GAAG;KAAO,QAAQ;IAAW;GAEnE;AACD,UAAO;EACR;CACF;;;;;;;;;;CAWD,yBACEN,aACAS,aACAJ,UACAH,oBAA6B,YAAY,SAAS,GAClD;AACA,SAAO,CAACI,UAAmC;GACzC,MAAM,eAAe;AACrB,OAAI,CAAC,aAAa,OAChB,QAAO;GAET,MAAM,cAAc,kBAAkB,aAAa,OAAO;AAC1D,OAAI,gBAAgB;;;;AAIlB,UAAO;AAET,OAAI,gBAAgB,iBAAiB;AACnC,QAAI,CAAC,kBACH,QAAO;AAET,WAAO,IAAI,KAAK,iBAAiB;KAAE,GAAG;KAAO,QAAQ;IAAW;GACjE;AACD,UAAO,IAAI,KAAK,iBAAiB;IAAE,GAAG;IAAO,QAAQ;GAAW;EACjE;CACF;;;;;;;;CASD,yBACEN,aACAS,aACAP,oBAA6B,YAAY,SAAS,GAClD;AACA,SAAO,CAACI,UAAmC;GACzC,MAAM,eAAe;AACrB,OAAI,CAAC,aAAa,OAChB,QAAO;GAET,MAAM,cAAc,kBAAkB,aAAa,OAAO;AAC1D,OAAI,gBAAgB,IAClB,QAAO;AAET,OAAI,gBAAgB,iBAAiB;AACnC,QAAI,CAAC,kBACH,QAAO;AAET,WAAO,IAAI,KAAK,iBAAiB;KAAE,GAAG;KAAO,QAAQ;IAAW;GACjE;AACD,UAAO,IAAI,KAAK,iBAAiB;IAAE,GAAG;IAAO,QAAQ;GAAW;EACjE;CACF;;;;CAKD,MAAMI,4BACJC,OACAC,QACsC;AACtC,MACE,CAAC,KAAK,QAAQ,cACd,KAAK,QAAQ,WAAW,WAAW,KACnC,iBAAiB,WACjB,CAAC,MAED,QAAO;EAGT,MAAM,gBAAgB,MAAM,2BAC1B,KAAK,QAAQ,YACb,MACD;EACD,MAAM,cAAc,MAAM,KAAKd,OAC5B,SAAS,OAAO,CAChB,MAAM,OAAO,EAAE,QAAQ,CAAE,EAAE,GAAE;EAChC,MAAM,eAAe;GACnB,GAAG,YAAY;GACf,GAAG;EACJ;AACD,MAAI,CAAC,aACH,QAAO;AAIT,OAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,cAAc,CACtD,KAAI,EAAE,OAAO,eACX,aAAa,OAAoC;AAIrD,SAAO;CACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CD,MAAM,OACJa,OACAE,QAQA;EAEA,MAAM,eAAe,aAAa,KAAKpC,gBAAgB,OAAO;EAC9D,MAAM,mBAAmB,MAAM,KAAKiC,4BAClC,OACA,aACD;AAED,SAAO,KAAKZ,OAAO,OACjB,kBACA,aAMD;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CD,MAAM,OAIJa,OACAG,QAUA;EACA,MAAM,eAAe,aAAa,KAAKrC,gBAAgB,OAAO;EAC9D,MAAM,mBAAmB,MAAM,KAAKiC,4BAClC,OACA,aACD;AACD,SAAO,KAAKZ,OAAO,OACjB,kBACA,aACD;CAcF;;;;;;;;;;;CAYD,MAAM,eAAeiB,QAMlB;EACD,MAAM,iBAAiB,MAAM,KAAKjB,OAAO,eAAe;EACxD,MAAM,QAAQ,MAAM,eAAe,eAAe,OAAO;EACzD,MAAM,cAAc,MAAM,MAAM,aAAa;EAC7C,MAAM,SAAS,IAAI,WAAW;AAC9B,SAAO;CACR;;;;;;;;;;;CAYD,MAAM,YAAYiB,QAMf;EACD,MAAM,iBAAiB,MAAM,KAAKjB,OAAO,eAAe;AACxD,SAAO,eAAe,YAAY,OAAO;CAC1C;;;;;;;;;;CAYD,aACEa,OACAK,QAUAC,eACqC;EACrC,MAAM,eAAe,aAAa,KAAKxC,gBAAgB,OAAO;AAC9D,SAAO,KAAKqB,OAAO,aACjB,OACA;GACE,GAAI;GAUJ,SAAS,QAAQ,WAAW;EAC7B,GACD,cACD;CACF;;;;CAID,cAAcoB,QAAyB;AACrC,SAAO,KAAKpB,OAAO,cAAc,OAAO;CACzC;;;;CAID,SAASc,QAAwBO,SAA2B;AAC1D,SAAO,KAAKrB,OAAO,SAAS,QAAQ,QAAQ;CAC7C;;;;CAID,gBAAgBc,QAAwBQ,SAAiC;AACvE,SAAO,KAAKtB,OAAO,gBAAgB,QAAQ,QAAQ;CACpD;;;;CAID,aAAauB,WAAoBC,SAAmB;AAClD,SAAO,KAAKxB,OAAO,aAAa,WAAW,QAAQ;CACpD;;;;CAID,iBAAiBuB,WAAoBC,SAAmB;AACtD,SAAO,KAAKxB,OAAO,kBAAkB,WAAW,QAAQ;CACzD;;;;CAID,YACEyB,aACAC,QACAC,QACA;AACA,SAAO,KAAK3B,OAAO,YAAY,aAAa,QAAQ,OAAO;CAC5D;;;;CAKD,IAAI,UAAU;AACZ,SAAO,KAAKA,OAAO;CACpB;AACF"}
@@ -2,7 +2,7 @@ import { AgentMiddleware } from "./types.cjs";
2
2
  import { ContextSize, KeepSize, TokenCounter } from "./summarization.cjs";
3
3
  import { BaseLanguageModel } from "@langchain/core/language_models/base";
4
4
  import { BaseMessage } from "@langchain/core/messages";
5
- import * as _langchain_core_tools5 from "@langchain/core/tools";
5
+ import * as _langchain_core_tools6 from "@langchain/core/tools";
6
6
 
7
7
  //#region src/agents/middleware/contextEditing.d.ts
8
8
 
@@ -334,7 +334,7 @@ interface ContextEditingMiddlewareConfig {
334
334
  * @param config - Configuration options for the middleware
335
335
  * @returns A middleware instance that can be used with `createAgent`
336
336
  */
337
- declare function contextEditingMiddleware(config?: ContextEditingMiddlewareConfig): AgentMiddleware<undefined, undefined, unknown, readonly (_langchain_core_tools5.ServerTool | _langchain_core_tools5.ClientTool)[]>;
337
+ declare function contextEditingMiddleware(config?: ContextEditingMiddlewareConfig): AgentMiddleware<undefined, undefined, unknown, readonly (_langchain_core_tools6.ServerTool | _langchain_core_tools6.ClientTool)[]>;
338
338
  //#endregion
339
339
  export { ClearToolUsesEdit, ClearToolUsesEditConfig, ContextEdit, ContextEditingMiddlewareConfig, contextEditingMiddleware };
340
340
  //# sourceMappingURL=contextEditing.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contextEditing.d.cts","names":["__types_js10","BaseMessage","BaseLanguageModel","ContextSize","KeepSize","TokenCounter","ContextEdit","Promise","ClearToolUsesEditConfig","ClearToolUsesEdit","Set","ContextEditingMiddlewareConfig","contextEditingMiddleware","_langchain_core_tools5","ServerTool","ClientTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/contextEditing.d.ts"],"sourcesContent":["/**\n * Context editing middleware.\n *\n * This middleware mirrors Anthropic's context editing capabilities by clearing\n * older tool results once the conversation grows beyond a configurable token\n * threshold. The implementation is intentionally model-agnostic so it can be used\n * with any LangChain chat model.\n */\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { BaseLanguageModel } from \"@langchain/core/language_models/base\";\nimport { type ContextSize, type KeepSize, type TokenCounter } from \"./summarization.js\";\n/**\n * Protocol describing a context editing strategy.\n *\n * Implement this interface to create custom strategies for managing\n * conversation context size. The `apply` method should modify the\n * messages array in-place and return the updated token count.\n *\n * @example\n * ```ts\n * import { HumanMessage, type ContextEdit, type BaseMessage } from \"langchain\";\n *\n * class RemoveOldHumanMessages implements ContextEdit {\n * constructor(private keepRecent: number = 10) {}\n *\n * async apply({ messages, countTokens }) {\n * // Check current token count\n * const tokens = await countTokens(messages);\n *\n * // Remove old human messages if over limit, keeping the most recent ones\n * if (tokens > 50000) {\n * const humanMessages: number[] = [];\n *\n * // Find all human message indices\n * for (let i = 0; i < messages.length; i++) {\n * if (HumanMessage.isInstance(messages[i])) {\n * humanMessages.push(i);\n * }\n * }\n *\n * // Remove old human messages (keep only the most recent N)\n * const toRemove = humanMessages.slice(0, -this.keepRecent);\n * for (let i = toRemove.length - 1; i >= 0; i--) {\n * messages.splice(toRemove[i]!, 1);\n * }\n * }\n * }\n * }\n * ```\n */\nexport interface ContextEdit {\n /**\n * Apply an edit to the message list, returning the new token count.\n *\n * This method should:\n * 1. Check if editing is needed based on `tokens` parameter\n * 2. Modify the `messages` array in-place (if needed)\n * 3. Return the new token count after modifications\n *\n * @param params - Parameters for the editing operation\n * @returns The updated token count after applying edits\n */\n apply(params: {\n /**\n * Array of messages to potentially edit (modify in-place)\n */\n messages: BaseMessage[];\n /**\n * Function to count tokens in a message array\n */\n countTokens: TokenCounter;\n /**\n * Optional model instance for model profile information\n */\n model?: BaseLanguageModel;\n }): void | Promise<void>;\n}\n/**\n * Configuration for clearing tool outputs when token limits are exceeded.\n */\nexport interface ClearToolUsesEditConfig {\n /**\n * Trigger conditions for context editing.\n * Can be a single condition object (all properties must be met) or an array of conditions (any condition must be met).\n *\n * @example\n * ```ts\n * // Single condition: trigger if tokens >= 100000 AND messages >= 50\n * trigger: { tokens: 100000, messages: 50 }\n *\n * // Multiple conditions: trigger if (tokens >= 100000 AND messages >= 50) OR (tokens >= 50000 AND messages >= 100)\n * trigger: [\n * { tokens: 100000, messages: 50 },\n * { tokens: 50000, messages: 100 }\n * ]\n *\n * // Fractional trigger: trigger at 80% of model's max input tokens\n * trigger: { fraction: 0.8 }\n * ```\n */\n trigger?: ContextSize | ContextSize[];\n /**\n * Context retention policy applied after editing.\n * Specify how many tool results to preserve using messages, tokens, or fraction.\n *\n * @example\n * ```ts\n * // Keep 3 most recent tool results\n * keep: { messages: 3 }\n *\n * // Keep tool results that fit within 1000 tokens\n * keep: { tokens: 1000 }\n *\n * // Keep tool results that fit within 30% of model's max input tokens\n * keep: { fraction: 0.3 }\n * ```\n */\n keep?: KeepSize;\n /**\n * Whether to clear the originating tool call parameters on the AI message.\n * @default false\n */\n clearToolInputs?: boolean;\n /**\n * List of tool names to exclude from clearing.\n * @default []\n */\n excludeTools?: string[];\n /**\n * Placeholder text inserted for cleared tool outputs.\n * @default \"[cleared]\"\n */\n placeholder?: string;\n /**\n * @deprecated Use `trigger: { tokens: value }` instead.\n */\n triggerTokens?: number;\n /**\n * @deprecated Use `keep: { messages: value }` instead.\n */\n keepMessages?: number;\n /**\n * @deprecated This property is deprecated and will be removed in a future version.\n * Use `keep: { tokens: value }` or `keep: { messages: value }` instead to control retention.\n */\n clearAtLeast?: number;\n}\n/**\n * Strategy for clearing tool outputs when token limits are exceeded.\n *\n * This strategy mirrors Anthropic's `clear_tool_uses_20250919` behavior by\n * replacing older tool results with a placeholder text when the conversation\n * grows too large. It preserves the most recent tool results and can exclude\n * specific tools from being cleared.\n *\n * @example\n * ```ts\n * import { ClearToolUsesEdit } from \"langchain\";\n *\n * const edit = new ClearToolUsesEdit({\n * trigger: { tokens: 100000 }, // Start clearing at 100K tokens\n * keep: { messages: 3 }, // Keep 3 most recent tool results\n * excludeTools: [\"important\"], // Never clear \"important\" tool\n * clearToolInputs: false, // Keep tool call arguments\n * placeholder: \"[cleared]\", // Replacement text\n * });\n *\n * // Multiple trigger conditions\n * const edit2 = new ClearToolUsesEdit({\n * trigger: [\n * { tokens: 100000, messages: 50 },\n * { tokens: 50000, messages: 100 }\n * ],\n * keep: { messages: 3 },\n * });\n *\n * // Fractional trigger with model profile\n * const edit3 = new ClearToolUsesEdit({\n * trigger: { fraction: 0.8 }, // Trigger at 80% of model's max tokens\n * keep: { fraction: 0.3 }, // Keep 30% of model's max tokens\n * });\n * ```\n */\nexport declare class ClearToolUsesEdit implements ContextEdit {\n #private;\n trigger: ContextSize | ContextSize[];\n keep: KeepSize;\n clearToolInputs: boolean;\n excludeTools: Set<string>;\n placeholder: string;\n model: BaseLanguageModel;\n clearAtLeast: number;\n constructor(config?: ClearToolUsesEditConfig);\n apply(params: {\n messages: BaseMessage[];\n model: BaseLanguageModel;\n countTokens: TokenCounter;\n }): Promise<void>;\n}\n/**\n * Configuration for the Context Editing Middleware.\n */\nexport interface ContextEditingMiddlewareConfig {\n /**\n * Sequence of edit strategies to apply. Defaults to a single\n * ClearToolUsesEdit mirroring Anthropic defaults.\n */\n edits?: ContextEdit[];\n /**\n * Whether to use approximate token counting (faster, less accurate)\n * or exact counting implemented by the chat model (potentially slower, more accurate).\n * Currently only OpenAI models support exact counting.\n * @default \"approx\"\n */\n tokenCountMethod?: \"approx\" | \"model\";\n}\n/**\n * Middleware that automatically prunes tool results to manage context size.\n *\n * This middleware applies a sequence of edits when the total input token count\n * exceeds configured thresholds. By default, it uses the `ClearToolUsesEdit` strategy\n * which mirrors Anthropic's `clear_tool_uses_20250919` behaviour by clearing older\n * tool results once the conversation exceeds 100,000 tokens.\n *\n * ## Basic Usage\n *\n * Use the middleware with default settings to automatically manage context:\n *\n * @example Basic usage with defaults\n * ```ts\n * import { contextEditingMiddleware } from \"langchain\";\n * import { createAgent } from \"langchain\";\n *\n * const agent = createAgent({\n * model: \"anthropic:claude-sonnet-4-5\",\n * tools: [searchTool, calculatorTool],\n * middleware: [\n * contextEditingMiddleware(),\n * ],\n * });\n * ```\n *\n * The default configuration:\n * - Triggers when context exceeds **100,000 tokens**\n * - Keeps the **3 most recent** tool results\n * - Uses **approximate token counting** (fast)\n * - Does not clear tool call arguments\n *\n * ## Custom Configuration\n *\n * Customize the clearing behavior with `ClearToolUsesEdit`:\n *\n * @example Custom ClearToolUsesEdit configuration\n * ```ts\n * import { contextEditingMiddleware, ClearToolUsesEdit } from \"langchain\";\n *\n * // Single condition: trigger if tokens >= 50000 AND messages >= 20\n * const agent1 = createAgent({\n * model: \"anthropic:claude-sonnet-4-5\",\n * tools: [searchTool, calculatorTool],\n * middleware: [\n * contextEditingMiddleware({\n * edits: [\n * new ClearToolUsesEdit({\n * trigger: { tokens: 50000, messages: 20 },\n * keep: { messages: 5 },\n * excludeTools: [\"search\"],\n * clearToolInputs: true,\n * }),\n * ],\n * tokenCountMethod: \"approx\",\n * }),\n * ],\n * });\n *\n * // Multiple conditions: trigger if (tokens >= 50000 AND messages >= 20) OR (tokens >= 30000 AND messages >= 50)\n * const agent2 = createAgent({\n * model: \"anthropic:claude-sonnet-4-5\",\n * tools: [searchTool, calculatorTool],\n * middleware: [\n * contextEditingMiddleware({\n * edits: [\n * new ClearToolUsesEdit({\n * trigger: [\n * { tokens: 50000, messages: 20 },\n * { tokens: 30000, messages: 50 },\n * ],\n * keep: { messages: 5 },\n * }),\n * ],\n * }),\n * ],\n * });\n *\n * // Fractional trigger with model profile\n * const agent3 = createAgent({\n * model: chatModel,\n * tools: [searchTool, calculatorTool],\n * middleware: [\n * contextEditingMiddleware({\n * edits: [\n * new ClearToolUsesEdit({\n * trigger: { fraction: 0.8 }, // Trigger at 80% of model's max tokens\n * keep: { fraction: 0.3 }, // Keep 30% of model's max tokens\n * model: chatModel,\n * }),\n * ],\n * }),\n * ],\n * });\n * ```\n *\n * ## Custom Editing Strategies\n *\n * Implement your own context editing strategy by creating a class that\n * implements the `ContextEdit` interface:\n *\n * @example Custom editing strategy\n * ```ts\n * import { contextEditingMiddleware, type ContextEdit, type TokenCounter } from \"langchain\";\n * import type { BaseMessage } from \"@langchain/core/messages\";\n *\n * class CustomEdit implements ContextEdit {\n * async apply(params: {\n * tokens: number;\n * messages: BaseMessage[];\n * countTokens: TokenCounter;\n * }): Promise<number> {\n * // Implement your custom editing logic here\n * // and apply it to the messages array, then\n * // return the new token count after edits\n * return countTokens(messages);\n * }\n * }\n * ```\n *\n * @param config - Configuration options for the middleware\n * @returns A middleware instance that can be used with `createAgent`\n */\nexport declare function contextEditingMiddleware(config?: ContextEditingMiddlewareConfig): import(\"./types.js\").AgentMiddleware<undefined, undefined, unknown, readonly (import(\"@langchain/core/tools\").ServerTool | import(\"@langchain/core/tools\").ClientTool)[]>;\n//# sourceMappingURL=contextEditing.d.ts.map"],"mappings":";;;;;;;;;AA2EsB;AAKtB;;;;AAqCmB;AAkEnB;;;;;;;;;;;;AAA6D;AAmB7D;AAyIA;;;;;AAA+H;;;;;;;;;;;;;UAjS9GM,WAAAA;;;;;;;;;;;;;;;;cAgBCL;;;;iBAIGI;;;;YAILH;aACDK;;;;;UAKEC,uBAAAA;;;;;;;;;;;;;;;;;;;;YAoBHL,cAAcA;;;;;;;;;;;;;;;;;SAiBjBC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkEUK,iBAAAA,YAA6BH;;WAErCH,cAAcA;QACjBC;;gBAEQM;;SAEPR;;uBAEcM;;cAEPP;WACHC;iBACMG;MACbE;;;;;UAKSI,8BAAAA;;;;;UAKLL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoIYM,wBAAAA,UAAkCD,0FAA8BE,sBAAAA,CAAiHC,UAAAA,GAAUD,sBAAAA,CAAmCE"}
1
+ {"version":3,"file":"contextEditing.d.cts","names":["__types_js11","BaseMessage","BaseLanguageModel","ContextSize","KeepSize","TokenCounter","ContextEdit","Promise","ClearToolUsesEditConfig","ClearToolUsesEdit","Set","ContextEditingMiddlewareConfig","contextEditingMiddleware","_langchain_core_tools6","ServerTool","ClientTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/contextEditing.d.ts"],"sourcesContent":["/**\n * Context editing middleware.\n *\n * This middleware mirrors Anthropic's context editing capabilities by clearing\n * older tool results once the conversation grows beyond a configurable token\n * threshold. The implementation is intentionally model-agnostic so it can be used\n * with any LangChain chat model.\n */\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { BaseLanguageModel } from \"@langchain/core/language_models/base\";\nimport { type ContextSize, type KeepSize, type TokenCounter } from \"./summarization.js\";\n/**\n * Protocol describing a context editing strategy.\n *\n * Implement this interface to create custom strategies for managing\n * conversation context size. The `apply` method should modify the\n * messages array in-place and return the updated token count.\n *\n * @example\n * ```ts\n * import { HumanMessage, type ContextEdit, type BaseMessage } from \"langchain\";\n *\n * class RemoveOldHumanMessages implements ContextEdit {\n * constructor(private keepRecent: number = 10) {}\n *\n * async apply({ messages, countTokens }) {\n * // Check current token count\n * const tokens = await countTokens(messages);\n *\n * // Remove old human messages if over limit, keeping the most recent ones\n * if (tokens > 50000) {\n * const humanMessages: number[] = [];\n *\n * // Find all human message indices\n * for (let i = 0; i < messages.length; i++) {\n * if (HumanMessage.isInstance(messages[i])) {\n * humanMessages.push(i);\n * }\n * }\n *\n * // Remove old human messages (keep only the most recent N)\n * const toRemove = humanMessages.slice(0, -this.keepRecent);\n * for (let i = toRemove.length - 1; i >= 0; i--) {\n * messages.splice(toRemove[i]!, 1);\n * }\n * }\n * }\n * }\n * ```\n */\nexport interface ContextEdit {\n /**\n * Apply an edit to the message list, returning the new token count.\n *\n * This method should:\n * 1. Check if editing is needed based on `tokens` parameter\n * 2. Modify the `messages` array in-place (if needed)\n * 3. Return the new token count after modifications\n *\n * @param params - Parameters for the editing operation\n * @returns The updated token count after applying edits\n */\n apply(params: {\n /**\n * Array of messages to potentially edit (modify in-place)\n */\n messages: BaseMessage[];\n /**\n * Function to count tokens in a message array\n */\n countTokens: TokenCounter;\n /**\n * Optional model instance for model profile information\n */\n model?: BaseLanguageModel;\n }): void | Promise<void>;\n}\n/**\n * Configuration for clearing tool outputs when token limits are exceeded.\n */\nexport interface ClearToolUsesEditConfig {\n /**\n * Trigger conditions for context editing.\n * Can be a single condition object (all properties must be met) or an array of conditions (any condition must be met).\n *\n * @example\n * ```ts\n * // Single condition: trigger if tokens >= 100000 AND messages >= 50\n * trigger: { tokens: 100000, messages: 50 }\n *\n * // Multiple conditions: trigger if (tokens >= 100000 AND messages >= 50) OR (tokens >= 50000 AND messages >= 100)\n * trigger: [\n * { tokens: 100000, messages: 50 },\n * { tokens: 50000, messages: 100 }\n * ]\n *\n * // Fractional trigger: trigger at 80% of model's max input tokens\n * trigger: { fraction: 0.8 }\n * ```\n */\n trigger?: ContextSize | ContextSize[];\n /**\n * Context retention policy applied after editing.\n * Specify how many tool results to preserve using messages, tokens, or fraction.\n *\n * @example\n * ```ts\n * // Keep 3 most recent tool results\n * keep: { messages: 3 }\n *\n * // Keep tool results that fit within 1000 tokens\n * keep: { tokens: 1000 }\n *\n * // Keep tool results that fit within 30% of model's max input tokens\n * keep: { fraction: 0.3 }\n * ```\n */\n keep?: KeepSize;\n /**\n * Whether to clear the originating tool call parameters on the AI message.\n * @default false\n */\n clearToolInputs?: boolean;\n /**\n * List of tool names to exclude from clearing.\n * @default []\n */\n excludeTools?: string[];\n /**\n * Placeholder text inserted for cleared tool outputs.\n * @default \"[cleared]\"\n */\n placeholder?: string;\n /**\n * @deprecated Use `trigger: { tokens: value }` instead.\n */\n triggerTokens?: number;\n /**\n * @deprecated Use `keep: { messages: value }` instead.\n */\n keepMessages?: number;\n /**\n * @deprecated This property is deprecated and will be removed in a future version.\n * Use `keep: { tokens: value }` or `keep: { messages: value }` instead to control retention.\n */\n clearAtLeast?: number;\n}\n/**\n * Strategy for clearing tool outputs when token limits are exceeded.\n *\n * This strategy mirrors Anthropic's `clear_tool_uses_20250919` behavior by\n * replacing older tool results with a placeholder text when the conversation\n * grows too large. It preserves the most recent tool results and can exclude\n * specific tools from being cleared.\n *\n * @example\n * ```ts\n * import { ClearToolUsesEdit } from \"langchain\";\n *\n * const edit = new ClearToolUsesEdit({\n * trigger: { tokens: 100000 }, // Start clearing at 100K tokens\n * keep: { messages: 3 }, // Keep 3 most recent tool results\n * excludeTools: [\"important\"], // Never clear \"important\" tool\n * clearToolInputs: false, // Keep tool call arguments\n * placeholder: \"[cleared]\", // Replacement text\n * });\n *\n * // Multiple trigger conditions\n * const edit2 = new ClearToolUsesEdit({\n * trigger: [\n * { tokens: 100000, messages: 50 },\n * { tokens: 50000, messages: 100 }\n * ],\n * keep: { messages: 3 },\n * });\n *\n * // Fractional trigger with model profile\n * const edit3 = new ClearToolUsesEdit({\n * trigger: { fraction: 0.8 }, // Trigger at 80% of model's max tokens\n * keep: { fraction: 0.3 }, // Keep 30% of model's max tokens\n * });\n * ```\n */\nexport declare class ClearToolUsesEdit implements ContextEdit {\n #private;\n trigger: ContextSize | ContextSize[];\n keep: KeepSize;\n clearToolInputs: boolean;\n excludeTools: Set<string>;\n placeholder: string;\n model: BaseLanguageModel;\n clearAtLeast: number;\n constructor(config?: ClearToolUsesEditConfig);\n apply(params: {\n messages: BaseMessage[];\n model: BaseLanguageModel;\n countTokens: TokenCounter;\n }): Promise<void>;\n}\n/**\n * Configuration for the Context Editing Middleware.\n */\nexport interface ContextEditingMiddlewareConfig {\n /**\n * Sequence of edit strategies to apply. Defaults to a single\n * ClearToolUsesEdit mirroring Anthropic defaults.\n */\n edits?: ContextEdit[];\n /**\n * Whether to use approximate token counting (faster, less accurate)\n * or exact counting implemented by the chat model (potentially slower, more accurate).\n * Currently only OpenAI models support exact counting.\n * @default \"approx\"\n */\n tokenCountMethod?: \"approx\" | \"model\";\n}\n/**\n * Middleware that automatically prunes tool results to manage context size.\n *\n * This middleware applies a sequence of edits when the total input token count\n * exceeds configured thresholds. By default, it uses the `ClearToolUsesEdit` strategy\n * which mirrors Anthropic's `clear_tool_uses_20250919` behaviour by clearing older\n * tool results once the conversation exceeds 100,000 tokens.\n *\n * ## Basic Usage\n *\n * Use the middleware with default settings to automatically manage context:\n *\n * @example Basic usage with defaults\n * ```ts\n * import { contextEditingMiddleware } from \"langchain\";\n * import { createAgent } from \"langchain\";\n *\n * const agent = createAgent({\n * model: \"anthropic:claude-sonnet-4-5\",\n * tools: [searchTool, calculatorTool],\n * middleware: [\n * contextEditingMiddleware(),\n * ],\n * });\n * ```\n *\n * The default configuration:\n * - Triggers when context exceeds **100,000 tokens**\n * - Keeps the **3 most recent** tool results\n * - Uses **approximate token counting** (fast)\n * - Does not clear tool call arguments\n *\n * ## Custom Configuration\n *\n * Customize the clearing behavior with `ClearToolUsesEdit`:\n *\n * @example Custom ClearToolUsesEdit configuration\n * ```ts\n * import { contextEditingMiddleware, ClearToolUsesEdit } from \"langchain\";\n *\n * // Single condition: trigger if tokens >= 50000 AND messages >= 20\n * const agent1 = createAgent({\n * model: \"anthropic:claude-sonnet-4-5\",\n * tools: [searchTool, calculatorTool],\n * middleware: [\n * contextEditingMiddleware({\n * edits: [\n * new ClearToolUsesEdit({\n * trigger: { tokens: 50000, messages: 20 },\n * keep: { messages: 5 },\n * excludeTools: [\"search\"],\n * clearToolInputs: true,\n * }),\n * ],\n * tokenCountMethod: \"approx\",\n * }),\n * ],\n * });\n *\n * // Multiple conditions: trigger if (tokens >= 50000 AND messages >= 20) OR (tokens >= 30000 AND messages >= 50)\n * const agent2 = createAgent({\n * model: \"anthropic:claude-sonnet-4-5\",\n * tools: [searchTool, calculatorTool],\n * middleware: [\n * contextEditingMiddleware({\n * edits: [\n * new ClearToolUsesEdit({\n * trigger: [\n * { tokens: 50000, messages: 20 },\n * { tokens: 30000, messages: 50 },\n * ],\n * keep: { messages: 5 },\n * }),\n * ],\n * }),\n * ],\n * });\n *\n * // Fractional trigger with model profile\n * const agent3 = createAgent({\n * model: chatModel,\n * tools: [searchTool, calculatorTool],\n * middleware: [\n * contextEditingMiddleware({\n * edits: [\n * new ClearToolUsesEdit({\n * trigger: { fraction: 0.8 }, // Trigger at 80% of model's max tokens\n * keep: { fraction: 0.3 }, // Keep 30% of model's max tokens\n * model: chatModel,\n * }),\n * ],\n * }),\n * ],\n * });\n * ```\n *\n * ## Custom Editing Strategies\n *\n * Implement your own context editing strategy by creating a class that\n * implements the `ContextEdit` interface:\n *\n * @example Custom editing strategy\n * ```ts\n * import { contextEditingMiddleware, type ContextEdit, type TokenCounter } from \"langchain\";\n * import type { BaseMessage } from \"@langchain/core/messages\";\n *\n * class CustomEdit implements ContextEdit {\n * async apply(params: {\n * tokens: number;\n * messages: BaseMessage[];\n * countTokens: TokenCounter;\n * }): Promise<number> {\n * // Implement your custom editing logic here\n * // and apply it to the messages array, then\n * // return the new token count after edits\n * return countTokens(messages);\n * }\n * }\n * ```\n *\n * @param config - Configuration options for the middleware\n * @returns A middleware instance that can be used with `createAgent`\n */\nexport declare function contextEditingMiddleware(config?: ContextEditingMiddlewareConfig): import(\"./types.js\").AgentMiddleware<undefined, undefined, unknown, readonly (import(\"@langchain/core/tools\").ServerTool | import(\"@langchain/core/tools\").ClientTool)[]>;\n//# sourceMappingURL=contextEditing.d.ts.map"],"mappings":";;;;;;;;;AA2EsB;AAKtB;;;;AAqCmB;AAkEnB;;;;;;;;;;;;AAA6D;AAmB7D;AAyIA;;;;;AAA+H;;;;;;;;;;;;;UAjS9GM,WAAAA;;;;;;;;;;;;;;;;cAgBCL;;;;iBAIGI;;;;YAILH;aACDK;;;;;UAKEC,uBAAAA;;;;;;;;;;;;;;;;;;;;YAoBHL,cAAcA;;;;;;;;;;;;;;;;;SAiBjBC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkEUK,iBAAAA,YAA6BH;;WAErCH,cAAcA;QACjBC;;gBAEQM;;SAEPR;;uBAEcM;;cAEPP;WACHC;iBACMG;MACbE;;;;;UAKSI,8BAAAA;;;;;UAKLL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoIYM,wBAAAA,UAAkCD,0FAA8BE,sBAAAA,CAAiHC,UAAAA,GAAUD,sBAAAA,CAAmCE"}
@@ -1,7 +1,7 @@
1
1
  import { AgentBuiltInState, Runtime } from "../runtime.cjs";
2
2
  import { AgentMiddleware } from "./types.cjs";
3
3
  import { SystemMessage } from "@langchain/core/messages";
4
- import * as _langchain_core_tools3 from "@langchain/core/tools";
4
+ import * as _langchain_core_tools4 from "@langchain/core/tools";
5
5
 
6
6
  //#region src/agents/middleware/dynamicSystemPrompt.d.ts
7
7
  type DynamicSystemPromptMiddlewareConfig<TContextSchema> = (state: AgentBuiltInState, runtime: Runtime<TContextSchema>) => string | SystemMessage | Promise<string | SystemMessage>;
@@ -43,7 +43,7 @@ type DynamicSystemPromptMiddlewareConfig<TContextSchema> = (state: AgentBuiltInS
43
43
  *
44
44
  * @public
45
45
  */
46
- declare function dynamicSystemPromptMiddleware<TContextSchema = unknown>(fn: DynamicSystemPromptMiddlewareConfig<TContextSchema>): AgentMiddleware<undefined, undefined, unknown, readonly (_langchain_core_tools3.ServerTool | _langchain_core_tools3.ClientTool)[]>;
46
+ declare function dynamicSystemPromptMiddleware<TContextSchema = unknown>(fn: DynamicSystemPromptMiddlewareConfig<TContextSchema>): AgentMiddleware<undefined, undefined, unknown, readonly (_langchain_core_tools4.ServerTool | _langchain_core_tools4.ClientTool)[]>;
47
47
  //#endregion
48
48
  export { DynamicSystemPromptMiddlewareConfig, dynamicSystemPromptMiddleware };
49
49
  //# sourceMappingURL=dynamicSystemPrompt.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dynamicSystemPrompt.d.cts","names":["__types_js9","SystemMessage","Runtime","AgentBuiltInState","DynamicSystemPromptMiddlewareConfig","TContextSchema","Promise","dynamicSystemPromptMiddleware","_langchain_core_tools3","ServerTool","ClientTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/dynamicSystemPrompt.d.ts"],"sourcesContent":["import { SystemMessage } from \"@langchain/core/messages\";\nimport type { Runtime, AgentBuiltInState } from \"../runtime.js\";\nexport type DynamicSystemPromptMiddlewareConfig<TContextSchema> = (state: AgentBuiltInState, runtime: Runtime<TContextSchema>) => string | SystemMessage | Promise<string | SystemMessage>;\n/**\n * Dynamic System Prompt Middleware\n *\n * Allows setting the system prompt dynamically right before each model invocation.\n * Useful when the prompt depends on the current agent state or per-invocation context.\n *\n * @typeParam TContextSchema - The shape of the runtime context available at invocation time.\n * If your agent defines a `contextSchema`, pass the inferred type here to get full type-safety\n * for `runtime.context`.\n *\n * @param fn - Function that receives the current agent `state` and `runtime`, and\n * returns the system prompt for the next model call as a string.\n *\n * @returns A middleware instance that sets `systemPrompt` for the next model call.\n *\n * @example Basic usage with typed context\n * ```ts\n * import { z } from \"zod\";\n * import { dynamicSystemPrompt } from \"langchain\";\n * import { createAgent, SystemMessage } from \"langchain\";\n *\n * const contextSchema = z.object({ region: z.string().optional() });\n *\n * const middleware = dynamicSystemPrompt<z.infer<typeof contextSchema>>(\n * (_state, runtime) => `You are a helpful assistant. Region: ${runtime.context.region ?? \"n/a\"}`\n * );\n *\n * const agent = createAgent({\n * model: \"anthropic:claude-3-5-sonnet\",\n * contextSchema,\n * middleware: [middleware],\n * });\n *\n * await agent.invoke({ messages }, { context: { region: \"EU\" } });\n * ```\n *\n * @public\n */\nexport declare function dynamicSystemPromptMiddleware<TContextSchema = unknown>(fn: DynamicSystemPromptMiddlewareConfig<TContextSchema>): import(\"./types.js\").AgentMiddleware<undefined, undefined, unknown, readonly (import(\"@langchain/core/tools\").ServerTool | import(\"@langchain/core/tools\").ClientTool)[]>;\n//# sourceMappingURL=dynamicSystemPrompt.d.ts.map"],"mappings":";;;;;;KAEYI,8DAA8DD,4BAA4BD,QAAQG,6BAA6BJ,gBAAgBK,iBAAiBL;;;;AAA5K;;;;;;;AAAkK;AAuClK;;;;;;AAA8K;;;;;;;;;;;;;;;;;;;;;iBAAtJM,4DAA4DH,oCAAoCC,2EAADG,sBAAAA,CAAiIC,UAAAA,GAAUD,sBAAAA,CAAmCE"}
1
+ {"version":3,"file":"dynamicSystemPrompt.d.cts","names":["__types_js10","SystemMessage","Runtime","AgentBuiltInState","DynamicSystemPromptMiddlewareConfig","TContextSchema","Promise","dynamicSystemPromptMiddleware","_langchain_core_tools4","ServerTool","ClientTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/dynamicSystemPrompt.d.ts"],"sourcesContent":["import { SystemMessage } from \"@langchain/core/messages\";\nimport type { Runtime, AgentBuiltInState } from \"../runtime.js\";\nexport type DynamicSystemPromptMiddlewareConfig<TContextSchema> = (state: AgentBuiltInState, runtime: Runtime<TContextSchema>) => string | SystemMessage | Promise<string | SystemMessage>;\n/**\n * Dynamic System Prompt Middleware\n *\n * Allows setting the system prompt dynamically right before each model invocation.\n * Useful when the prompt depends on the current agent state or per-invocation context.\n *\n * @typeParam TContextSchema - The shape of the runtime context available at invocation time.\n * If your agent defines a `contextSchema`, pass the inferred type here to get full type-safety\n * for `runtime.context`.\n *\n * @param fn - Function that receives the current agent `state` and `runtime`, and\n * returns the system prompt for the next model call as a string.\n *\n * @returns A middleware instance that sets `systemPrompt` for the next model call.\n *\n * @example Basic usage with typed context\n * ```ts\n * import { z } from \"zod\";\n * import { dynamicSystemPrompt } from \"langchain\";\n * import { createAgent, SystemMessage } from \"langchain\";\n *\n * const contextSchema = z.object({ region: z.string().optional() });\n *\n * const middleware = dynamicSystemPrompt<z.infer<typeof contextSchema>>(\n * (_state, runtime) => `You are a helpful assistant. Region: ${runtime.context.region ?? \"n/a\"}`\n * );\n *\n * const agent = createAgent({\n * model: \"anthropic:claude-3-5-sonnet\",\n * contextSchema,\n * middleware: [middleware],\n * });\n *\n * await agent.invoke({ messages }, { context: { region: \"EU\" } });\n * ```\n *\n * @public\n */\nexport declare function dynamicSystemPromptMiddleware<TContextSchema = unknown>(fn: DynamicSystemPromptMiddlewareConfig<TContextSchema>): import(\"./types.js\").AgentMiddleware<undefined, undefined, unknown, readonly (import(\"@langchain/core/tools\").ServerTool | import(\"@langchain/core/tools\").ClientTool)[]>;\n//# sourceMappingURL=dynamicSystemPrompt.d.ts.map"],"mappings":";;;;;;KAEYI,8DAA8DD,4BAA4BD,QAAQG,6BAA6BJ,gBAAgBK,iBAAiBL;;;;AAA5K;;;;;;;AAAkK;AAuClK;;;;;;AAA8K;;;;;;;;;;;;;;;;;;;;;iBAAtJM,4DAA4DH,oCAAoCC,2EAADG,sBAAAA,CAAiIC,UAAAA,GAAUD,sBAAAA,CAAmCE"}
@@ -1,5 +1,5 @@
1
1
  import { AgentMiddleware } from "./types.js";
2
- import * as _langchain_core_tools10 from "@langchain/core/tools";
2
+ import * as _langchain_core_tools9 from "@langchain/core/tools";
3
3
  import { InferInteropZodInput } from "@langchain/core/utils/types";
4
4
  import { z } from "zod/v3";
5
5
 
@@ -127,7 +127,7 @@ declare function modelCallLimitMiddleware(middlewareOptions?: ModelCallLimitMidd
127
127
  threadLimit?: number | undefined;
128
128
  runLimit?: number | undefined;
129
129
  exitBehavior?: "end" | "error" | undefined;
130
- }, readonly (_langchain_core_tools10.ServerTool | _langchain_core_tools10.ClientTool)[]>;
130
+ }, readonly (_langchain_core_tools9.ServerTool | _langchain_core_tools9.ClientTool)[]>;
131
131
  //#endregion
132
132
  export { ModelCallLimitMiddlewareConfig, modelCallLimitMiddleware };
133
133
  //# sourceMappingURL=modelCallLimit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modelCallLimit.d.ts","names":["__types_js13","z","InferInteropZodInput","contextSchema","ZodNumber","ZodOptional","ZodEnum","ZodTypeAny","ZodObject","ModelCallLimitMiddlewareConfig","Partial","modelCallLimitMiddleware","ZodDefault","_langchain_core_tools10","ServerTool","ClientTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/modelCallLimit.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { InferInteropZodInput } from \"@langchain/core/utils/types\";\ndeclare const contextSchema: z.ZodObject<{\n /**\n * The maximum number of model calls allowed per thread.\n */\n threadLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * The maximum number of model calls allowed per run.\n */\n runLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * The behavior to take when the limit is exceeded.\n * - \"error\" will throw an error and stop the agent.\n * - \"end\" will end the agent.\n * @default \"end\"\n */\n exitBehavior: z.ZodOptional<z.ZodEnum<[\"error\", \"end\"]>>;\n}, \"strip\", z.ZodTypeAny, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}>;\nexport type ModelCallLimitMiddlewareConfig = Partial<InferInteropZodInput<typeof contextSchema>>;\n/**\n * Creates a middleware to limit the number of model calls at both thread and run levels.\n *\n * This middleware helps prevent excessive model API calls by enforcing limits on how many\n * times the model can be invoked. It supports two types of limits:\n *\n * - **Thread-level limit**: Restricts the total number of model calls across an entire conversation thread\n * - **Run-level limit**: Restricts the number of model calls within a single agent run/invocation\n *\n * ## How It Works\n *\n * The middleware intercepts model requests before they are sent and checks the current call counts\n * against the configured limits. If either limit is exceeded, it throws a `ModelCallLimitMiddlewareError`\n * to stop execution and prevent further API calls.\n *\n * ## Use Cases\n *\n * - **Cost Control**: Prevent runaway costs from excessive model calls in production\n * - **Testing**: Ensure agents don't make too many calls during development/testing\n * - **Safety**: Limit potential infinite loops or recursive agent behaviors\n * - **Rate Limiting**: Enforce organizational policies on model usage per conversation\n *\n * @param middlewareOptions - Configuration options for the call limits\n * @param middlewareOptions.threadLimit - Maximum number of model calls allowed per thread (optional)\n * @param middlewareOptions.runLimit - Maximum number of model calls allowed per run (optional)\n *\n * @returns A middleware instance that can be passed to `createAgent`\n *\n * @throws {ModelCallLimitMiddlewareError} When either the thread or run limit is exceeded\n *\n * @example\n * ```typescript\n * import { createAgent, modelCallLimitMiddleware } from \"langchain\";\n *\n * // Limit to 10 calls per thread and 3 calls per run\n * const agent = createAgent({\n * model: \"openai:gpt-4o-mini\",\n * tools: [myTool],\n * middleware: [\n * modelCallLimitMiddleware({\n * threadLimit: 10,\n * runLimit: 3\n * })\n * ]\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Limits can also be configured at runtime via context\n * const result = await agent.invoke(\n * { messages: [\"Hello\"] },\n * {\n * configurable: {\n * threadLimit: 5 // Override the default limit for this run\n * }\n * }\n * );\n * ```\n */\nexport declare function modelCallLimitMiddleware(middlewareOptions?: ModelCallLimitMiddlewareConfig): import(\"./types.js\").AgentMiddleware<z.ZodObject<{\n threadModelCallCount: z.ZodDefault<z.ZodNumber>;\n runModelCallCount: z.ZodDefault<z.ZodNumber>;\n}, \"strip\", z.ZodTypeAny, {\n threadModelCallCount: number;\n runModelCallCount: number;\n}, {\n threadModelCallCount?: number | undefined;\n runModelCallCount?: number | undefined;\n}>, z.ZodObject<{\n /**\n * The maximum number of model calls allowed per thread.\n */\n threadLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * The maximum number of model calls allowed per run.\n */\n runLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * The behavior to take when the limit is exceeded.\n * - \"error\" will throw an error and stop the agent.\n * - \"end\" will end the agent.\n * @default \"end\"\n */\n exitBehavior: z.ZodOptional<z.ZodEnum<[\"error\", \"end\"]>>;\n}, \"strip\", z.ZodTypeAny, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}>, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}, readonly (import(\"@langchain/core/tools\").ServerTool | import(\"@langchain/core/tools\").ClientTool)[]>;\nexport {};\n//# sourceMappingURL=modelCallLimit.d.ts.map"],"mappings":";;;;;;cAEcG,eAAeF,CAAAA,CAAEO;;;;EAAjBL,WAAAA,EAIGF,CAAAA,CAAEI,WAoBjB,CApB6BJ,CAAAA,CAAEG,SAoB/B,CAAA;EApB+BA;;;EAIjBC,QAAAA,EAAFJ,CAAAA,CAAEI,WAAAA,CAAYJ,CAAAA,CAAEG,SAAdC,CAAAA;EAOkBC;;;;AAfM;AAyBxC;EAAiFH,YAAAA,EAV/DF,CAAAA,CAAEI,WAU6DF,CAVjDF,CAAAA,CAAEK,OAU+CH,CAAAA,CAAAA,OAAAA,EAAAA,KAAAA,CAAAA,CAAAA,CAAAA;CAA5BD,EAAAA,OAAAA,EATzCD,CAAAA,CAAEM,UASuCL,EAAAA;EAARQ,WAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAO,QAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EA6D5BC,YAAAA,CAAAA,EAAAA,KAAAA,GAAAA,OAAwB,GAAA,SAAA;CAAqBF,EAAAA;EAC5BL,WAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAbQ,QAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EACUR,YAAAA,CAAAA,EAAAA,KAAAA,GAAAA,OAAAA,GAAAA,SAAAA;CAAfH,CAAAA;AACTM,KAhEFE,8BAAAA,GAAiCC,OAgE/BH,CAhEuCL,oBAgEvCK,CAAAA,OAhEmEJ,aAgEnEI,CAAAA,CAAAA;;;;;;;;;;;;;AAH4H;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAlHI,wBAAAA,qBAA6CF,iDAAsER,CAAAA,CAAEO;wBACnHP,CAAAA,CAAEW,WAAWX,CAAAA,CAAEG;qBAClBH,CAAAA,CAAEW,WAAWX,CAAAA,CAAEG;YAC1BH,CAAAA,CAAEM;;;;;;IAMVN,CAAAA,CAAEO;;;;eAIWP,CAAAA,CAAEI,YAAYJ,CAAAA,CAAEG;;;;YAInBH,CAAAA,CAAEI,YAAYJ,CAAAA,CAAEG;;;;;;;gBAOZH,CAAAA,CAAEI,YAAYJ,CAAAA,CAAEK;YACtBL,CAAAA,CAAEM;;;;;;;;;;;;aAhBCM,uBAAAA,CA4B8BC,UAAAA,GAAUD,uBAAAA,CAAmCE"}
1
+ {"version":3,"file":"modelCallLimit.d.ts","names":["__types_js12","z","InferInteropZodInput","contextSchema","ZodNumber","ZodOptional","ZodEnum","ZodTypeAny","ZodObject","ModelCallLimitMiddlewareConfig","Partial","modelCallLimitMiddleware","ZodDefault","_langchain_core_tools9","ServerTool","ClientTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/modelCallLimit.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { InferInteropZodInput } from \"@langchain/core/utils/types\";\ndeclare const contextSchema: z.ZodObject<{\n /**\n * The maximum number of model calls allowed per thread.\n */\n threadLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * The maximum number of model calls allowed per run.\n */\n runLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * The behavior to take when the limit is exceeded.\n * - \"error\" will throw an error and stop the agent.\n * - \"end\" will end the agent.\n * @default \"end\"\n */\n exitBehavior: z.ZodOptional<z.ZodEnum<[\"error\", \"end\"]>>;\n}, \"strip\", z.ZodTypeAny, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}>;\nexport type ModelCallLimitMiddlewareConfig = Partial<InferInteropZodInput<typeof contextSchema>>;\n/**\n * Creates a middleware to limit the number of model calls at both thread and run levels.\n *\n * This middleware helps prevent excessive model API calls by enforcing limits on how many\n * times the model can be invoked. It supports two types of limits:\n *\n * - **Thread-level limit**: Restricts the total number of model calls across an entire conversation thread\n * - **Run-level limit**: Restricts the number of model calls within a single agent run/invocation\n *\n * ## How It Works\n *\n * The middleware intercepts model requests before they are sent and checks the current call counts\n * against the configured limits. If either limit is exceeded, it throws a `ModelCallLimitMiddlewareError`\n * to stop execution and prevent further API calls.\n *\n * ## Use Cases\n *\n * - **Cost Control**: Prevent runaway costs from excessive model calls in production\n * - **Testing**: Ensure agents don't make too many calls during development/testing\n * - **Safety**: Limit potential infinite loops or recursive agent behaviors\n * - **Rate Limiting**: Enforce organizational policies on model usage per conversation\n *\n * @param middlewareOptions - Configuration options for the call limits\n * @param middlewareOptions.threadLimit - Maximum number of model calls allowed per thread (optional)\n * @param middlewareOptions.runLimit - Maximum number of model calls allowed per run (optional)\n *\n * @returns A middleware instance that can be passed to `createAgent`\n *\n * @throws {ModelCallLimitMiddlewareError} When either the thread or run limit is exceeded\n *\n * @example\n * ```typescript\n * import { createAgent, modelCallLimitMiddleware } from \"langchain\";\n *\n * // Limit to 10 calls per thread and 3 calls per run\n * const agent = createAgent({\n * model: \"openai:gpt-4o-mini\",\n * tools: [myTool],\n * middleware: [\n * modelCallLimitMiddleware({\n * threadLimit: 10,\n * runLimit: 3\n * })\n * ]\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Limits can also be configured at runtime via context\n * const result = await agent.invoke(\n * { messages: [\"Hello\"] },\n * {\n * configurable: {\n * threadLimit: 5 // Override the default limit for this run\n * }\n * }\n * );\n * ```\n */\nexport declare function modelCallLimitMiddleware(middlewareOptions?: ModelCallLimitMiddlewareConfig): import(\"./types.js\").AgentMiddleware<z.ZodObject<{\n threadModelCallCount: z.ZodDefault<z.ZodNumber>;\n runModelCallCount: z.ZodDefault<z.ZodNumber>;\n}, \"strip\", z.ZodTypeAny, {\n threadModelCallCount: number;\n runModelCallCount: number;\n}, {\n threadModelCallCount?: number | undefined;\n runModelCallCount?: number | undefined;\n}>, z.ZodObject<{\n /**\n * The maximum number of model calls allowed per thread.\n */\n threadLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * The maximum number of model calls allowed per run.\n */\n runLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * The behavior to take when the limit is exceeded.\n * - \"error\" will throw an error and stop the agent.\n * - \"end\" will end the agent.\n * @default \"end\"\n */\n exitBehavior: z.ZodOptional<z.ZodEnum<[\"error\", \"end\"]>>;\n}, \"strip\", z.ZodTypeAny, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}>, {\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"end\" | \"error\" | undefined;\n}, readonly (import(\"@langchain/core/tools\").ServerTool | import(\"@langchain/core/tools\").ClientTool)[]>;\nexport {};\n//# sourceMappingURL=modelCallLimit.d.ts.map"],"mappings":";;;;;;cAEcG,eAAeF,CAAAA,CAAEO;;;;EAAjBL,WAAAA,EAIGF,CAAAA,CAAEI,WAoBjB,CApB6BJ,CAAAA,CAAEG,SAoB/B,CAAA;EApB+BA;;;EAIjBC,QAAAA,EAAFJ,CAAAA,CAAEI,WAAAA,CAAYJ,CAAAA,CAAEG,SAAdC,CAAAA;EAOkBC;;;;AAfM;AAyBxC;EAAiFH,YAAAA,EAV/DF,CAAAA,CAAEI,WAU6DF,CAVjDF,CAAAA,CAAEK,OAU+CH,CAAAA,CAAAA,OAAAA,EAAAA,KAAAA,CAAAA,CAAAA,CAAAA;CAA5BD,EAAAA,OAAAA,EATzCD,CAAAA,CAAEM,UASuCL,EAAAA;EAARQ,WAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAO,QAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EA6D5BC,YAAAA,CAAAA,EAAAA,KAAAA,GAAAA,OAAwB,GAAA,SAAA;CAAqBF,EAAAA;EAC5BL,WAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAbQ,QAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EACUR,YAAAA,CAAAA,EAAAA,KAAAA,GAAAA,OAAAA,GAAAA,SAAAA;CAAfH,CAAAA;AACTM,KAhEFE,8BAAAA,GAAiCC,OAgE/BH,CAhEuCL,oBAgEvCK,CAAAA,OAhEmEJ,aAgEnEI,CAAAA,CAAAA;;;;;;;;;;;;;AAH4H;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAlHI,wBAAAA,qBAA6CF,iDAAsER,CAAAA,CAAEO;wBACnHP,CAAAA,CAAEW,WAAWX,CAAAA,CAAEG;qBAClBH,CAAAA,CAAEW,WAAWX,CAAAA,CAAEG;YAC1BH,CAAAA,CAAEM;;;;;;IAMVN,CAAAA,CAAEO;;;;eAIWP,CAAAA,CAAEI,YAAYJ,CAAAA,CAAEG;;;;YAInBH,CAAAA,CAAEI,YAAYJ,CAAAA,CAAEG;;;;;;;gBAOZH,CAAAA,CAAEI,YAAYJ,CAAAA,CAAEK;YACtBL,CAAAA,CAAEM;;;;;;;;;;;;aAhBCM,sBAAAA,CA4B8BC,UAAAA,GAAUD,sBAAAA,CAAmCE"}
@@ -1,7 +1,7 @@
1
1
  import { AgentMiddleware } from "./types.cjs";
2
2
  import * as _langchain_core_messages26 from "@langchain/core/messages";
3
3
  import { ToolMessage } from "@langchain/core/messages";
4
- import * as _langchain_core_tools9 from "@langchain/core/tools";
4
+ import * as _langchain_core_tools3 from "@langchain/core/tools";
5
5
  import { Command } from "@langchain/langgraph";
6
6
  import { z } from "zod/v3";
7
7
 
@@ -75,7 +75,7 @@ declare function todoListMiddleware(options?: TodoListMiddlewareOptions): AgentM
75
75
  content: string;
76
76
  status: "completed" | "in_progress" | "pending";
77
77
  }[] | undefined;
78
- }>, undefined, unknown, readonly [_langchain_core_tools9.DynamicStructuredTool<z.ZodObject<{
78
+ }>, undefined, unknown, readonly [_langchain_core_tools3.DynamicStructuredTool<z.ZodObject<{
79
79
  todos: z.ZodArray<z.ZodObject<{
80
80
  content: z.ZodString;
81
81
  status: z.ZodEnum<["pending", "in_progress", "completed"]>;
@@ -1 +1 @@
1
- {"version":3,"file":"todoListMiddleware.d.cts","names":["_langchain_core_tools9","__types_js12","z","Command","ToolMessage","TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT","stateSchema","ZodString","ZodEnum","ZodTypeAny","ZodObject","ZodArray","ZodDefault","TodoMiddlewareState","infer","TodoListMiddlewareOptions","todoListMiddleware","_langchain_core_messages26","MessageToolSet","MessageStructure","DynamicStructuredTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/todoListMiddleware.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { Command } from \"@langchain/langgraph\";\nimport { ToolMessage } from \"@langchain/core/messages\";\nexport declare const TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT = \"## `write_todos`\\n\\nYou have access to the `write_todos` tool to help you manage and plan complex objectives. \\nUse this tool for complex objectives to ensure that you are tracking each necessary step and giving the user visibility into your progress.\\nThis tool is very helpful for planning complex objectives, and for breaking down these larger complex objectives into smaller steps.\\n\\nIt is critical that you mark todos as completed as soon as you are done with a step. Do not batch up multiple steps before marking them as completed.\\nFor simple objectives that only require a few steps, it is better to just complete the objective directly and NOT use this tool.\\nWriting todos takes time and tokens, use it when it is helpful for managing complex many-step problems! But not for simple few-step requests.\\n\\n## Important To-Do List Usage Notes to Remember\\n- The `write_todos` tool should never be called multiple times in parallel.\\n- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.\";\ndeclare const stateSchema: z.ZodObject<{\n todos: z.ZodDefault<z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">>;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos?: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[] | undefined;\n}>;\nexport type TodoMiddlewareState = z.infer<typeof stateSchema>;\nexport interface TodoListMiddlewareOptions {\n /**\n * Custom system prompt to guide the agent on using the todo tool.\n * If not provided, uses the default {@link PLANNING_MIDDLEWARE_SYSTEM_PROMPT}.\n */\n systemPrompt?: string;\n /**\n * Custom description for the {@link writeTodos} tool.\n * If not provided, uses the default {@link WRITE_TODOS_DESCRIPTION}.\n */\n toolDescription?: string;\n}\n/**\n * Creates a middleware that provides todo list management capabilities to agents.\n *\n * This middleware adds a `write_todos` tool that allows agents to create and manage\n * structured task lists for complex multi-step operations. It's designed to help\n * agents track progress, organize complex tasks, and provide users with visibility\n * into task completion status.\n *\n * The middleware automatically injects system prompts that guide the agent on when\n * and how to use the todo functionality effectively. It also enforces that the\n * `write_todos` tool is called at most once per model turn, since the tool replaces\n * the entire todo list and parallel calls would create ambiguity about precedence.\n *\n * @example\n * ```typescript\n * import { todoListMiddleware, createAgent } from 'langchain';\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [todoListMiddleware()],\n * });\n *\n * // Agent now has access to write_todos tool and todo state tracking\n * const result = await agent.invoke({\n * messages: [new HumanMessage(\"Help me refactor my codebase\")]\n * });\n *\n * console.log(result.todos); // Array of todo items with status tracking\n * ```\n *\n * @returns A configured middleware instance that provides todo management capabilities\n *\n * @see {@link TodoMiddlewareState} for the state schema\n * @see {@link writeTodos} for the tool implementation\n */\nexport declare function todoListMiddleware(options?: TodoListMiddlewareOptions): import(\"./types.js\").AgentMiddleware<z.ZodObject<{\n todos: z.ZodDefault<z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">>;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos?: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[] | undefined;\n}>, undefined, unknown, readonly [import(\"@langchain/core/tools\").DynamicStructuredTool<z.ZodObject<{\n todos: z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}>, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, Command<unknown, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n messages: ToolMessage<import(\"@langchain/core/messages\").MessageStructure<import(\"@langchain/core/messages\").MessageToolSet>>[];\n}, string>, \"write_todos\">]>;\nexport {};\n//# sourceMappingURL=todoListMiddleware.d.ts.map"],"mappings":";;;;;;;;cAGqBK,kCAAAA;AA4F8EY,UApElFF,yBAAAA,CAwGgGG;EAAcD;;;;;EAzDV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA7FD,kBAAAA,WAA6BD,4CAAiEb,CAAAA,CAAEQ;SAC7GR,CAAAA,CAAEU,WAAWV,CAAAA,CAAES,SAAST,CAAAA,CAAEQ;aACpBR,CAAAA,CAAEK;YACHL,CAAAA,CAAEM;cACFN,CAAAA,CAAEO;;;;;;;YAONP,CAAAA,CAAEO;;;;;;;;;;kCAyCJT,sBAAAA,CA/BwDoB,sBAAsBlB,CAAAA,CAAEQ;SAC/ER,CAAAA,CAAES,SAAST,CAAAA,CAAEQ;aACPR,CAAAA,CAAEK;YACHL,CAAAA,CAAEM;cACFN,CAAAA,CAAEO;;;;;;;YAONP,CAAAA,CAAEO;;;;;;;;;;;;;;;;;;;;GAoBXN;;;;;YAKWC,YAAiHa,0BAAAA,CAAlEE,iBApCsCF,0BAAAA,CAoCcC,cAAAA"}
1
+ {"version":3,"file":"todoListMiddleware.d.cts","names":["_langchain_core_tools3","__types_js9","z","Command","ToolMessage","TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT","stateSchema","ZodString","ZodEnum","ZodTypeAny","ZodObject","ZodArray","ZodDefault","TodoMiddlewareState","infer","TodoListMiddlewareOptions","todoListMiddleware","_langchain_core_messages26","MessageToolSet","MessageStructure","DynamicStructuredTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/todoListMiddleware.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { Command } from \"@langchain/langgraph\";\nimport { ToolMessage } from \"@langchain/core/messages\";\nexport declare const TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT = \"## `write_todos`\\n\\nYou have access to the `write_todos` tool to help you manage and plan complex objectives. \\nUse this tool for complex objectives to ensure that you are tracking each necessary step and giving the user visibility into your progress.\\nThis tool is very helpful for planning complex objectives, and for breaking down these larger complex objectives into smaller steps.\\n\\nIt is critical that you mark todos as completed as soon as you are done with a step. Do not batch up multiple steps before marking them as completed.\\nFor simple objectives that only require a few steps, it is better to just complete the objective directly and NOT use this tool.\\nWriting todos takes time and tokens, use it when it is helpful for managing complex many-step problems! But not for simple few-step requests.\\n\\n## Important To-Do List Usage Notes to Remember\\n- The `write_todos` tool should never be called multiple times in parallel.\\n- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.\";\ndeclare const stateSchema: z.ZodObject<{\n todos: z.ZodDefault<z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">>;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos?: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[] | undefined;\n}>;\nexport type TodoMiddlewareState = z.infer<typeof stateSchema>;\nexport interface TodoListMiddlewareOptions {\n /**\n * Custom system prompt to guide the agent on using the todo tool.\n * If not provided, uses the default {@link PLANNING_MIDDLEWARE_SYSTEM_PROMPT}.\n */\n systemPrompt?: string;\n /**\n * Custom description for the {@link writeTodos} tool.\n * If not provided, uses the default {@link WRITE_TODOS_DESCRIPTION}.\n */\n toolDescription?: string;\n}\n/**\n * Creates a middleware that provides todo list management capabilities to agents.\n *\n * This middleware adds a `write_todos` tool that allows agents to create and manage\n * structured task lists for complex multi-step operations. It's designed to help\n * agents track progress, organize complex tasks, and provide users with visibility\n * into task completion status.\n *\n * The middleware automatically injects system prompts that guide the agent on when\n * and how to use the todo functionality effectively. It also enforces that the\n * `write_todos` tool is called at most once per model turn, since the tool replaces\n * the entire todo list and parallel calls would create ambiguity about precedence.\n *\n * @example\n * ```typescript\n * import { todoListMiddleware, createAgent } from 'langchain';\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [todoListMiddleware()],\n * });\n *\n * // Agent now has access to write_todos tool and todo state tracking\n * const result = await agent.invoke({\n * messages: [new HumanMessage(\"Help me refactor my codebase\")]\n * });\n *\n * console.log(result.todos); // Array of todo items with status tracking\n * ```\n *\n * @returns A configured middleware instance that provides todo management capabilities\n *\n * @see {@link TodoMiddlewareState} for the state schema\n * @see {@link writeTodos} for the tool implementation\n */\nexport declare function todoListMiddleware(options?: TodoListMiddlewareOptions): import(\"./types.js\").AgentMiddleware<z.ZodObject<{\n todos: z.ZodDefault<z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">>;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos?: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[] | undefined;\n}>, undefined, unknown, readonly [import(\"@langchain/core/tools\").DynamicStructuredTool<z.ZodObject<{\n todos: z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}>, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, Command<unknown, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n messages: ToolMessage<import(\"@langchain/core/messages\").MessageStructure<import(\"@langchain/core/messages\").MessageToolSet>>[];\n}, string>, \"write_todos\">]>;\nexport {};\n//# sourceMappingURL=todoListMiddleware.d.ts.map"],"mappings":";;;;;;;;cAGqBK,kCAAAA;AA4F8EY,UApElFF,yBAAAA,CAwGgGG;EAAcD;;;;;EAzDV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA7FD,kBAAAA,WAA6BD,4CAAiEb,CAAAA,CAAEQ;SAC7GR,CAAAA,CAAEU,WAAWV,CAAAA,CAAES,SAAST,CAAAA,CAAEQ;aACpBR,CAAAA,CAAEK;YACHL,CAAAA,CAAEM;cACFN,CAAAA,CAAEO;;;;;;;YAONP,CAAAA,CAAEO;;;;;;;;;;kCAyCJT,sBAAAA,CA/BwDoB,sBAAsBlB,CAAAA,CAAEQ;SAC/ER,CAAAA,CAAES,SAAST,CAAAA,CAAEQ;aACPR,CAAAA,CAAEK;YACHL,CAAAA,CAAEM;cACFN,CAAAA,CAAEO;;;;;;;YAONP,CAAAA,CAAEO;;;;;;;;;;;;;;;;;;;;GAoBXN;;;;;YAKWC,YAAiHa,0BAAAA,CAAlEE,iBApCsCF,0BAAAA,CAoCcC,cAAAA"}
@@ -1,7 +1,7 @@
1
1
  import { AgentMiddleware } from "./types.js";
2
2
  import * as _langchain_core_messages26 from "@langchain/core/messages";
3
3
  import { ToolMessage } from "@langchain/core/messages";
4
- import * as _langchain_core_tools9 from "@langchain/core/tools";
4
+ import * as _langchain_core_tools11 from "@langchain/core/tools";
5
5
  import { Command } from "@langchain/langgraph";
6
6
  import { z } from "zod/v3";
7
7
 
@@ -75,7 +75,7 @@ declare function todoListMiddleware(options?: TodoListMiddlewareOptions): AgentM
75
75
  content: string;
76
76
  status: "completed" | "in_progress" | "pending";
77
77
  }[] | undefined;
78
- }>, undefined, unknown, readonly [_langchain_core_tools9.DynamicStructuredTool<z.ZodObject<{
78
+ }>, undefined, unknown, readonly [_langchain_core_tools11.DynamicStructuredTool<z.ZodObject<{
79
79
  todos: z.ZodArray<z.ZodObject<{
80
80
  content: z.ZodString;
81
81
  status: z.ZodEnum<["pending", "in_progress", "completed"]>;
@@ -1 +1 @@
1
- {"version":3,"file":"todoListMiddleware.d.ts","names":["_langchain_core_tools9","__types_js12","z","Command","ToolMessage","TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT","stateSchema","ZodString","ZodEnum","ZodTypeAny","ZodObject","ZodArray","ZodDefault","TodoMiddlewareState","infer","TodoListMiddlewareOptions","todoListMiddleware","_langchain_core_messages26","MessageToolSet","MessageStructure","DynamicStructuredTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/todoListMiddleware.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { Command } from \"@langchain/langgraph\";\nimport { ToolMessage } from \"@langchain/core/messages\";\nexport declare const TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT = \"## `write_todos`\\n\\nYou have access to the `write_todos` tool to help you manage and plan complex objectives. \\nUse this tool for complex objectives to ensure that you are tracking each necessary step and giving the user visibility into your progress.\\nThis tool is very helpful for planning complex objectives, and for breaking down these larger complex objectives into smaller steps.\\n\\nIt is critical that you mark todos as completed as soon as you are done with a step. Do not batch up multiple steps before marking them as completed.\\nFor simple objectives that only require a few steps, it is better to just complete the objective directly and NOT use this tool.\\nWriting todos takes time and tokens, use it when it is helpful for managing complex many-step problems! But not for simple few-step requests.\\n\\n## Important To-Do List Usage Notes to Remember\\n- The `write_todos` tool should never be called multiple times in parallel.\\n- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.\";\ndeclare const stateSchema: z.ZodObject<{\n todos: z.ZodDefault<z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">>;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos?: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[] | undefined;\n}>;\nexport type TodoMiddlewareState = z.infer<typeof stateSchema>;\nexport interface TodoListMiddlewareOptions {\n /**\n * Custom system prompt to guide the agent on using the todo tool.\n * If not provided, uses the default {@link PLANNING_MIDDLEWARE_SYSTEM_PROMPT}.\n */\n systemPrompt?: string;\n /**\n * Custom description for the {@link writeTodos} tool.\n * If not provided, uses the default {@link WRITE_TODOS_DESCRIPTION}.\n */\n toolDescription?: string;\n}\n/**\n * Creates a middleware that provides todo list management capabilities to agents.\n *\n * This middleware adds a `write_todos` tool that allows agents to create and manage\n * structured task lists for complex multi-step operations. It's designed to help\n * agents track progress, organize complex tasks, and provide users with visibility\n * into task completion status.\n *\n * The middleware automatically injects system prompts that guide the agent on when\n * and how to use the todo functionality effectively. It also enforces that the\n * `write_todos` tool is called at most once per model turn, since the tool replaces\n * the entire todo list and parallel calls would create ambiguity about precedence.\n *\n * @example\n * ```typescript\n * import { todoListMiddleware, createAgent } from 'langchain';\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [todoListMiddleware()],\n * });\n *\n * // Agent now has access to write_todos tool and todo state tracking\n * const result = await agent.invoke({\n * messages: [new HumanMessage(\"Help me refactor my codebase\")]\n * });\n *\n * console.log(result.todos); // Array of todo items with status tracking\n * ```\n *\n * @returns A configured middleware instance that provides todo management capabilities\n *\n * @see {@link TodoMiddlewareState} for the state schema\n * @see {@link writeTodos} for the tool implementation\n */\nexport declare function todoListMiddleware(options?: TodoListMiddlewareOptions): import(\"./types.js\").AgentMiddleware<z.ZodObject<{\n todos: z.ZodDefault<z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">>;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos?: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[] | undefined;\n}>, undefined, unknown, readonly [import(\"@langchain/core/tools\").DynamicStructuredTool<z.ZodObject<{\n todos: z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}>, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, Command<unknown, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n messages: ToolMessage<import(\"@langchain/core/messages\").MessageStructure<import(\"@langchain/core/messages\").MessageToolSet>>[];\n}, string>, \"write_todos\">]>;\nexport {};\n//# sourceMappingURL=todoListMiddleware.d.ts.map"],"mappings":";;;;;;;;cAGqBK,kCAAAA;AA4F8EY,UApElFF,yBAAAA,CAwGgGG;EAAcD;;;;;EAzDV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA7FD,kBAAAA,WAA6BD,4CAAiEb,CAAAA,CAAEQ;SAC7GR,CAAAA,CAAEU,WAAWV,CAAAA,CAAES,SAAST,CAAAA,CAAEQ;aACpBR,CAAAA,CAAEK;YACHL,CAAAA,CAAEM;cACFN,CAAAA,CAAEO;;;;;;;YAONP,CAAAA,CAAEO;;;;;;;;;;kCAyCJT,sBAAAA,CA/BwDoB,sBAAsBlB,CAAAA,CAAEQ;SAC/ER,CAAAA,CAAES,SAAST,CAAAA,CAAEQ;aACPR,CAAAA,CAAEK;YACHL,CAAAA,CAAEM;cACFN,CAAAA,CAAEO;;;;;;;YAONP,CAAAA,CAAEO;;;;;;;;;;;;;;;;;;;;GAoBXN;;;;;YAKWC,YAAiHa,0BAAAA,CAAlEE,iBApCsCF,0BAAAA,CAoCcC,cAAAA"}
1
+ {"version":3,"file":"todoListMiddleware.d.ts","names":["_langchain_core_tools11","__types_js13","z","Command","ToolMessage","TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT","stateSchema","ZodString","ZodEnum","ZodTypeAny","ZodObject","ZodArray","ZodDefault","TodoMiddlewareState","infer","TodoListMiddlewareOptions","todoListMiddleware","_langchain_core_messages26","MessageToolSet","MessageStructure","DynamicStructuredTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/todoListMiddleware.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { Command } from \"@langchain/langgraph\";\nimport { ToolMessage } from \"@langchain/core/messages\";\nexport declare const TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT = \"## `write_todos`\\n\\nYou have access to the `write_todos` tool to help you manage and plan complex objectives. \\nUse this tool for complex objectives to ensure that you are tracking each necessary step and giving the user visibility into your progress.\\nThis tool is very helpful for planning complex objectives, and for breaking down these larger complex objectives into smaller steps.\\n\\nIt is critical that you mark todos as completed as soon as you are done with a step. Do not batch up multiple steps before marking them as completed.\\nFor simple objectives that only require a few steps, it is better to just complete the objective directly and NOT use this tool.\\nWriting todos takes time and tokens, use it when it is helpful for managing complex many-step problems! But not for simple few-step requests.\\n\\n## Important To-Do List Usage Notes to Remember\\n- The `write_todos` tool should never be called multiple times in parallel.\\n- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.\";\ndeclare const stateSchema: z.ZodObject<{\n todos: z.ZodDefault<z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">>;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos?: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[] | undefined;\n}>;\nexport type TodoMiddlewareState = z.infer<typeof stateSchema>;\nexport interface TodoListMiddlewareOptions {\n /**\n * Custom system prompt to guide the agent on using the todo tool.\n * If not provided, uses the default {@link PLANNING_MIDDLEWARE_SYSTEM_PROMPT}.\n */\n systemPrompt?: string;\n /**\n * Custom description for the {@link writeTodos} tool.\n * If not provided, uses the default {@link WRITE_TODOS_DESCRIPTION}.\n */\n toolDescription?: string;\n}\n/**\n * Creates a middleware that provides todo list management capabilities to agents.\n *\n * This middleware adds a `write_todos` tool that allows agents to create and manage\n * structured task lists for complex multi-step operations. It's designed to help\n * agents track progress, organize complex tasks, and provide users with visibility\n * into task completion status.\n *\n * The middleware automatically injects system prompts that guide the agent on when\n * and how to use the todo functionality effectively. It also enforces that the\n * `write_todos` tool is called at most once per model turn, since the tool replaces\n * the entire todo list and parallel calls would create ambiguity about precedence.\n *\n * @example\n * ```typescript\n * import { todoListMiddleware, createAgent } from 'langchain';\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [todoListMiddleware()],\n * });\n *\n * // Agent now has access to write_todos tool and todo state tracking\n * const result = await agent.invoke({\n * messages: [new HumanMessage(\"Help me refactor my codebase\")]\n * });\n *\n * console.log(result.todos); // Array of todo items with status tracking\n * ```\n *\n * @returns A configured middleware instance that provides todo management capabilities\n *\n * @see {@link TodoMiddlewareState} for the state schema\n * @see {@link writeTodos} for the tool implementation\n */\nexport declare function todoListMiddleware(options?: TodoListMiddlewareOptions): import(\"./types.js\").AgentMiddleware<z.ZodObject<{\n todos: z.ZodDefault<z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">>;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos?: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[] | undefined;\n}>, undefined, unknown, readonly [import(\"@langchain/core/tools\").DynamicStructuredTool<z.ZodObject<{\n todos: z.ZodArray<z.ZodObject<{\n content: z.ZodString;\n status: z.ZodEnum<[\"pending\", \"in_progress\", \"completed\"]>;\n }, \"strip\", z.ZodTypeAny, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }, {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }>, \"many\">;\n}, \"strip\", z.ZodTypeAny, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}>, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n}, Command<unknown, {\n todos: {\n content: string;\n status: \"completed\" | \"in_progress\" | \"pending\";\n }[];\n messages: ToolMessage<import(\"@langchain/core/messages\").MessageStructure<import(\"@langchain/core/messages\").MessageToolSet>>[];\n}, string>, \"write_todos\">]>;\nexport {};\n//# sourceMappingURL=todoListMiddleware.d.ts.map"],"mappings":";;;;;;;;cAGqBK,kCAAAA;AA4F8EY,UApElFF,yBAAAA,CAwGgGG;EAAcD;;;;;EAzDV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA7FD,kBAAAA,WAA6BD,4CAAiEb,CAAAA,CAAEQ;SAC7GR,CAAAA,CAAEU,WAAWV,CAAAA,CAAES,SAAST,CAAAA,CAAEQ;aACpBR,CAAAA,CAAEK;YACHL,CAAAA,CAAEM;cACFN,CAAAA,CAAEO;;;;;;;YAONP,CAAAA,CAAEO;;;;;;;;;;kCAyCJT,uBAAAA,CA/BwDoB,sBAAsBlB,CAAAA,CAAEQ;SAC/ER,CAAAA,CAAES,SAAST,CAAAA,CAAEQ;aACPR,CAAAA,CAAEK;YACHL,CAAAA,CAAEM;cACFN,CAAAA,CAAEO;;;;;;;YAONP,CAAAA,CAAEO;;;;;;;;;;;;;;;;;;;;GAoBXN;;;;;YAKWC,YAAiHa,0BAAAA,CAAlEE,iBApCsCF,0BAAAA,CAoCcC,cAAAA"}
@@ -1,5 +1,5 @@
1
1
  import { AgentMiddleware } from "./types.cjs";
2
- import * as _langchain_core_tools7 from "@langchain/core/tools";
2
+ import * as _langchain_core_tools8 from "@langchain/core/tools";
3
3
  import { InferInteropZodInput } from "@langchain/core/utils/types";
4
4
  import { z } from "zod/v3";
5
5
 
@@ -164,7 +164,7 @@ declare function toolCallLimitMiddleware(options: ToolCallLimitConfig): AgentMid
164
164
  }, {
165
165
  threadToolCallCount?: Record<string, number> | undefined;
166
166
  runToolCallCount?: Record<string, number> | undefined;
167
- }>, undefined, unknown, readonly (_langchain_core_tools7.ServerTool | _langchain_core_tools7.ClientTool)[]>;
167
+ }>, undefined, unknown, readonly (_langchain_core_tools8.ServerTool | _langchain_core_tools8.ClientTool)[]>;
168
168
  //#endregion
169
169
  export { ToolCallLimitConfig, ToolCallLimitExceededError, toolCallLimitMiddleware };
170
170
  //# sourceMappingURL=toolCallLimit.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"toolCallLimit.d.cts","names":["__types_js11","z","InferInteropZodInput","ToolCallLimitExceededError","Error","ToolCallLimitOptionsSchema","ZodString","ZodOptional","ZodNumber","ZodEnum","ZodDefault","ZodTypeAny","ZodObject","ToolCallLimitConfig","toolCallLimitMiddleware","ZodRecord","Record","_langchain_core_tools7","ServerTool","ClientTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/toolCallLimit.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport type { InferInteropZodInput } from \"@langchain/core/utils/types\";\n/**\n * Exception raised when tool call limits are exceeded.\n *\n * This exception is raised when the configured exit behavior is 'error'\n * and either the thread or run tool call limit has been exceeded.\n */\nexport declare class ToolCallLimitExceededError extends Error {\n /**\n * Current thread tool call count.\n */\n threadCount: number;\n /**\n * Current run tool call count.\n */\n runCount: number;\n /**\n * Thread tool call limit (if set).\n */\n threadLimit: number | undefined;\n /**\n * Run tool call limit (if set).\n */\n runLimit: number | undefined;\n /**\n * Tool name being limited (if specific tool), or undefined for all tools.\n */\n toolName: string | undefined;\n constructor(threadCount: number, runCount: number, threadLimit: number | undefined, runLimit: number | undefined, toolName?: string | undefined);\n}\n/**\n * Options for configuring the Tool Call Limit middleware.\n */\nexport declare const ToolCallLimitOptionsSchema: z.ZodObject<{\n /**\n * Name of the specific tool to limit. If undefined, limits apply to all tools.\n */\n toolName: z.ZodOptional<z.ZodString>;\n /**\n * Maximum number of tool calls allowed per thread.\n * undefined means no limit.\n */\n threadLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * Maximum number of tool calls allowed per run.\n * undefined means no limit.\n */\n runLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * What to do when limits are exceeded.\n * - \"continue\": Block exceeded tools with error messages, let other tools continue (default)\n * - \"error\": Raise a ToolCallLimitExceededError exception\n * - \"end\": Stop execution immediately, injecting a ToolMessage and an AI message\n * for the single tool call that exceeded the limit. Raises NotImplementedError\n * if there are multiple tool calls.\n *\n * @default \"continue\"\n */\n exitBehavior: z.ZodDefault<z.ZodEnum<[\"continue\", \"error\", \"end\"]>>;\n}, \"strip\", z.ZodTypeAny, {\n toolName?: string | undefined;\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior: \"continue\" | \"end\" | \"error\";\n}, {\n toolName?: string | undefined;\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"continue\" | \"end\" | \"error\" | undefined;\n}>;\nexport type ToolCallLimitConfig = InferInteropZodInput<typeof ToolCallLimitOptionsSchema>;\n/**\n * Middleware that tracks tool call counts and enforces limits.\n *\n * This middleware monitors the number of tool calls made during agent execution\n * and can terminate the agent when specified limits are reached. It supports\n * both thread-level and run-level call counting with configurable exit behaviors.\n *\n * Thread-level: The middleware counts all tool calls in the entire message history\n * and persists this count across multiple runs (invocations) of the agent.\n *\n * Run-level: The middleware counts tool calls made after the last HumanMessage,\n * representing the current run (invocation) of the agent.\n *\n * @param options - Configuration options for the middleware\n * @param options.toolName - Name of the specific tool to limit. If undefined, limits apply to all tools.\n * @param options.threadLimit - Maximum number of tool calls allowed per thread. undefined means no limit.\n * @param options.runLimit - Maximum number of tool calls allowed per run. undefined means no limit.\n * @param options.exitBehavior - What to do when limits are exceeded.\n * - \"continue\": Block exceeded tools with error messages, let other tools continue. Model decides when to end. (default)\n * - \"error\": Raise a ToolCallLimitExceededError exception\n * - \"end\": Stop execution immediately with a ToolMessage + AI message for the single tool call that exceeded the limit. Raises NotImplementedError if there are multiple tool calls.\n *\n * @throws {Error} If both limits are undefined, if exitBehavior is invalid, or if runLimit exceeds threadLimit.\n * @throws {NotImplementedError} If exitBehavior is \"end\" and there are multiple tool calls.\n *\n * @example Continue execution with blocked tools (default)\n * ```ts\n * import { toolCallLimitMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * // Block exceeded tools but let other tools and model continue\n * const limiter = toolCallLimitMiddleware({\n * threadLimit: 20,\n * runLimit: 10,\n * exitBehavior: \"continue\", // default\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n * ```\n *\n * @example Stop immediately when limit exceeded\n * ```ts\n * // End execution immediately with an AI message\n * const limiter = toolCallLimitMiddleware({\n * runLimit: 5,\n * exitBehavior: \"end\"\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n * ```\n *\n * @example Raise exception on limit\n * ```ts\n * // Strict limit with exception handling\n * const limiter = toolCallLimitMiddleware({\n * toolName: \"search\",\n * threadLimit: 5,\n * exitBehavior: \"error\"\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n *\n * try {\n * const result = await agent.invoke({ messages: [new HumanMessage(\"Task\")] });\n * } catch (error) {\n * if (error instanceof ToolCallLimitExceededError) {\n * console.log(`Search limit exceeded: ${error}`);\n * }\n * }\n * ```\n */\nexport declare function toolCallLimitMiddleware(options: ToolCallLimitConfig): import(\"./types.js\").AgentMiddleware<z.ZodObject<{\n threadToolCallCount: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;\n runToolCallCount: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;\n}, \"strip\", z.ZodTypeAny, {\n threadToolCallCount: Record<string, number>;\n runToolCallCount: Record<string, number>;\n}, {\n threadToolCallCount?: Record<string, number> | undefined;\n runToolCallCount?: Record<string, number> | undefined;\n}>, undefined, unknown, readonly (import(\"@langchain/core/tools\").ServerTool | import(\"@langchain/core/tools\").ClientTool)[]>;\n//# sourceMappingURL=toolCallLimit.d.ts.map"],"mappings":";;;;;;;;;;;AAQA;AA0BA;AAI8BM,cA9BTH,0BAAAA,SAAmCC,KAAK,CA8B/BE;EAAdC;;;EAUcC,WAAAA,EAAAA,MAAAA;EAAdD;;;EAYFI,QAAAA,EAAAA,MAAAA;EA1BqCC;AAAS;AAqC5D;EAiFwBE,WAAAA,EAAAA,MAAAA,GAAAA,SAAuB;EAAUD;;;EACjBE,QAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAbL;;;EACUK,QAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAbL,WAAAA,CAAAA,WAAAA,EAAAA,MAAAA,EAAAA,QAAAA,EAAAA,MAAAA,EAAAA,WAAAA,EAAAA,MAAAA,GAAAA,SAAAA,EAAAA,QAAAA,EAAAA,MAAAA,GAAAA,SAAAA,EAAAA,QAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;;;;;AAMDM,cA9HFX,0BA8HEW,EA9H0Bf,CAAAA,CAAEW,SA8H5BI,CAAAA;EAR+FJ;;;YAlHxGX,CAAAA,CAAEM,YAAYN,CAAAA,CAAEK;EAkHqF;;;;eA7GlGL,CAAAA,CAAEM,YAAYN,CAAAA,CAAEO;;;;;YAKnBP,CAAAA,CAAEM,YAAYN,CAAAA,CAAEO;;;;;;;;;;;gBAWZP,CAAAA,CAAES,WAAWT,CAAAA,CAAEQ;YACrBR,CAAAA,CAAEU;;;;;;;;;;;KAWFE,mBAAAA,GAAsBX,4BAA4BG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiFtCS,uBAAAA,UAAiCD,sCAA2DZ,CAAAA,CAAEW;uBAC7FX,CAAAA,CAAES,WAAWT,CAAAA,CAAEc,UAAUd,CAAAA,CAAEK,WAAWL,CAAAA,CAAEO;oBAC3CP,CAAAA,CAAES,WAAWT,CAAAA,CAAEc,UAAUd,CAAAA,CAAEK,WAAWL,CAAAA,CAAEO;YAClDP,CAAAA,CAAEU;uBACWK;oBACHA;;wBAEIA;qBACHA;kCARwGC,sBAAAA,CAS7DC,UAAAA,GAAUD,sBAAAA,CAAmCE"}
1
+ {"version":3,"file":"toolCallLimit.d.cts","names":["__types_js12","z","InferInteropZodInput","ToolCallLimitExceededError","Error","ToolCallLimitOptionsSchema","ZodString","ZodOptional","ZodNumber","ZodEnum","ZodDefault","ZodTypeAny","ZodObject","ToolCallLimitConfig","toolCallLimitMiddleware","ZodRecord","Record","_langchain_core_tools8","ServerTool","ClientTool","AgentMiddleware"],"sources":["../../../src/agents/middleware/toolCallLimit.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport type { InferInteropZodInput } from \"@langchain/core/utils/types\";\n/**\n * Exception raised when tool call limits are exceeded.\n *\n * This exception is raised when the configured exit behavior is 'error'\n * and either the thread or run tool call limit has been exceeded.\n */\nexport declare class ToolCallLimitExceededError extends Error {\n /**\n * Current thread tool call count.\n */\n threadCount: number;\n /**\n * Current run tool call count.\n */\n runCount: number;\n /**\n * Thread tool call limit (if set).\n */\n threadLimit: number | undefined;\n /**\n * Run tool call limit (if set).\n */\n runLimit: number | undefined;\n /**\n * Tool name being limited (if specific tool), or undefined for all tools.\n */\n toolName: string | undefined;\n constructor(threadCount: number, runCount: number, threadLimit: number | undefined, runLimit: number | undefined, toolName?: string | undefined);\n}\n/**\n * Options for configuring the Tool Call Limit middleware.\n */\nexport declare const ToolCallLimitOptionsSchema: z.ZodObject<{\n /**\n * Name of the specific tool to limit. If undefined, limits apply to all tools.\n */\n toolName: z.ZodOptional<z.ZodString>;\n /**\n * Maximum number of tool calls allowed per thread.\n * undefined means no limit.\n */\n threadLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * Maximum number of tool calls allowed per run.\n * undefined means no limit.\n */\n runLimit: z.ZodOptional<z.ZodNumber>;\n /**\n * What to do when limits are exceeded.\n * - \"continue\": Block exceeded tools with error messages, let other tools continue (default)\n * - \"error\": Raise a ToolCallLimitExceededError exception\n * - \"end\": Stop execution immediately, injecting a ToolMessage and an AI message\n * for the single tool call that exceeded the limit. Raises NotImplementedError\n * if there are multiple tool calls.\n *\n * @default \"continue\"\n */\n exitBehavior: z.ZodDefault<z.ZodEnum<[\"continue\", \"error\", \"end\"]>>;\n}, \"strip\", z.ZodTypeAny, {\n toolName?: string | undefined;\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior: \"continue\" | \"end\" | \"error\";\n}, {\n toolName?: string | undefined;\n threadLimit?: number | undefined;\n runLimit?: number | undefined;\n exitBehavior?: \"continue\" | \"end\" | \"error\" | undefined;\n}>;\nexport type ToolCallLimitConfig = InferInteropZodInput<typeof ToolCallLimitOptionsSchema>;\n/**\n * Middleware that tracks tool call counts and enforces limits.\n *\n * This middleware monitors the number of tool calls made during agent execution\n * and can terminate the agent when specified limits are reached. It supports\n * both thread-level and run-level call counting with configurable exit behaviors.\n *\n * Thread-level: The middleware counts all tool calls in the entire message history\n * and persists this count across multiple runs (invocations) of the agent.\n *\n * Run-level: The middleware counts tool calls made after the last HumanMessage,\n * representing the current run (invocation) of the agent.\n *\n * @param options - Configuration options for the middleware\n * @param options.toolName - Name of the specific tool to limit. If undefined, limits apply to all tools.\n * @param options.threadLimit - Maximum number of tool calls allowed per thread. undefined means no limit.\n * @param options.runLimit - Maximum number of tool calls allowed per run. undefined means no limit.\n * @param options.exitBehavior - What to do when limits are exceeded.\n * - \"continue\": Block exceeded tools with error messages, let other tools continue. Model decides when to end. (default)\n * - \"error\": Raise a ToolCallLimitExceededError exception\n * - \"end\": Stop execution immediately with a ToolMessage + AI message for the single tool call that exceeded the limit. Raises NotImplementedError if there are multiple tool calls.\n *\n * @throws {Error} If both limits are undefined, if exitBehavior is invalid, or if runLimit exceeds threadLimit.\n * @throws {NotImplementedError} If exitBehavior is \"end\" and there are multiple tool calls.\n *\n * @example Continue execution with blocked tools (default)\n * ```ts\n * import { toolCallLimitMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * // Block exceeded tools but let other tools and model continue\n * const limiter = toolCallLimitMiddleware({\n * threadLimit: 20,\n * runLimit: 10,\n * exitBehavior: \"continue\", // default\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n * ```\n *\n * @example Stop immediately when limit exceeded\n * ```ts\n * // End execution immediately with an AI message\n * const limiter = toolCallLimitMiddleware({\n * runLimit: 5,\n * exitBehavior: \"end\"\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n * ```\n *\n * @example Raise exception on limit\n * ```ts\n * // Strict limit with exception handling\n * const limiter = toolCallLimitMiddleware({\n * toolName: \"search\",\n * threadLimit: 5,\n * exitBehavior: \"error\"\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n *\n * try {\n * const result = await agent.invoke({ messages: [new HumanMessage(\"Task\")] });\n * } catch (error) {\n * if (error instanceof ToolCallLimitExceededError) {\n * console.log(`Search limit exceeded: ${error}`);\n * }\n * }\n * ```\n */\nexport declare function toolCallLimitMiddleware(options: ToolCallLimitConfig): import(\"./types.js\").AgentMiddleware<z.ZodObject<{\n threadToolCallCount: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;\n runToolCallCount: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;\n}, \"strip\", z.ZodTypeAny, {\n threadToolCallCount: Record<string, number>;\n runToolCallCount: Record<string, number>;\n}, {\n threadToolCallCount?: Record<string, number> | undefined;\n runToolCallCount?: Record<string, number> | undefined;\n}>, undefined, unknown, readonly (import(\"@langchain/core/tools\").ServerTool | import(\"@langchain/core/tools\").ClientTool)[]>;\n//# sourceMappingURL=toolCallLimit.d.ts.map"],"mappings":";;;;;;;;;;;AAQA;AA0BA;AAI8BM,cA9BTH,0BAAAA,SAAmCC,KAAK,CA8B/BE;EAAdC;;;EAUcC,WAAAA,EAAAA,MAAAA;EAAdD;;;EAYFI,QAAAA,EAAAA,MAAAA;EA1BqCC;AAAS;AAqC5D;EAiFwBE,WAAAA,EAAAA,MAAAA,GAAAA,SAAuB;EAAUD;;;EACjBE,QAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAbL;;;EACUK,QAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAbL,WAAAA,CAAAA,WAAAA,EAAAA,MAAAA,EAAAA,QAAAA,EAAAA,MAAAA,EAAAA,WAAAA,EAAAA,MAAAA,GAAAA,SAAAA,EAAAA,QAAAA,EAAAA,MAAAA,GAAAA,SAAAA,EAAAA,QAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;;;;;AAMDM,cA9HFX,0BA8HEW,EA9H0Bf,CAAAA,CAAEW,SA8H5BI,CAAAA;EAR+FJ;;;YAlHxGX,CAAAA,CAAEM,YAAYN,CAAAA,CAAEK;EAkHqF;;;;eA7GlGL,CAAAA,CAAEM,YAAYN,CAAAA,CAAEO;;;;;YAKnBP,CAAAA,CAAEM,YAAYN,CAAAA,CAAEO;;;;;;;;;;;gBAWZP,CAAAA,CAAES,WAAWT,CAAAA,CAAEQ;YACrBR,CAAAA,CAAEU;;;;;;;;;;;KAWFE,mBAAAA,GAAsBX,4BAA4BG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiFtCS,uBAAAA,UAAiCD,sCAA2DZ,CAAAA,CAAEW;uBAC7FX,CAAAA,CAAES,WAAWT,CAAAA,CAAEc,UAAUd,CAAAA,CAAEK,WAAWL,CAAAA,CAAEO;oBAC3CP,CAAAA,CAAES,WAAWT,CAAAA,CAAEc,UAAUd,CAAAA,CAAEK,WAAWL,CAAAA,CAAEO;YAClDP,CAAAA,CAAEU;uBACWK;oBACHA;;wBAEIA;qBACHA;kCARwGC,sBAAAA,CAS7DC,UAAAA,GAAUD,sBAAAA,CAAmCE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langchain",
3
- "version": "1.2.20",
3
+ "version": "1.2.21",
4
4
  "description": "Typescript bindings for langchain",
5
5
  "author": "LangChain",
6
6
  "license": "MIT",
@@ -54,13 +54,13 @@
54
54
  "yaml": "^2.8.1",
55
55
  "@langchain/anthropic": "1.3.17",
56
56
  "@langchain/cohere": "1.0.2",
57
- "@langchain/core": "^1.1.21",
57
+ "@langchain/core": "^1.1.22",
58
58
  "@langchain/eslint": "0.1.1",
59
59
  "@langchain/openai": "1.2.7",
60
60
  "@langchain/tsconfig": "0.0.1"
61
61
  },
62
62
  "peerDependencies": {
63
- "@langchain/core": "^1.1.21"
63
+ "@langchain/core": "^1.1.22"
64
64
  },
65
65
  "dependencies": {
66
66
  "@langchain/langgraph": "^1.1.2",