langchain 1.2.35 → 1.2.36

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ReactAgent.js","names":["#defaultConfig","#toolBehaviorVersion","#agentNode","#stateManager","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","#initializeMiddlewareStates"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type {\n BaseCheckpointSaver,\n BaseStore,\n CheckpointListOptions,\n} from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaValue,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaValue<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = defaultConfig ?? {};\n if (options.name) {\n this.#defaultConfig = mergeConfigs(this.#defaultConfig, {\n metadata: { lc_agent_name: options.name },\n });\n }\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(\n shouldReturnDirect,\n exitNode,\n toolReturnTarget\n ),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n get checkpointer(): BaseCheckpointSaver | boolean | undefined {\n return this.#graph.checkpointer;\n }\n\n set checkpointer(value: BaseCheckpointSaver | boolean | undefined) {\n this.#graph.checkpointer = value;\n }\n\n get store(): BaseStore | undefined {\n return this.#graph.store;\n }\n\n set store(value: BaseStore | undefined) {\n this.#graph.store = value;\n }\n\n /**\n * Creates a new ReactAgent with the given config merged into the existing config.\n * Follows the same pattern as LangGraph's Pregel.withConfig().\n *\n * The merged config is applied as a default that gets merged with any config\n * passed at invocation time (invoke/stream). Invocation-time config takes precedence.\n *\n * @param config - Configuration to merge with existing config\n * @returns A new ReactAgent instance with the merged configuration\n *\n * @example\n * ```typescript\n * const agent = createAgent({ model: \"gpt-4o\", tools: [...] });\n *\n * // Set a default recursion limit\n * const configuredAgent = agent.withConfig({ recursionLimit: 1000 });\n *\n * // Chain multiple configs\n * const debugAgent = agent\n * .withConfig({ recursionLimit: 1000 })\n * .withConfig({ tags: [\"debug\"] });\n * ```\n */\n withConfig(\n config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">\n ): ReactAgent<Types> {\n return new ReactAgent(\n this.options,\n mergeConfigs(this.#defaultConfig, config)\n );\n }\n\n /**\n * Get possible edge destinations from model node.\n * @param toolClasses names of tools to call\n * @param includeModelRequest whether to include \"model_request\" as a valid path (for jumpTo routing)\n * @param hasToolsAvailable whether tools are available (includes dynamic tools via middleware)\n * @returns list of possible edge destinations\n */\n #getModelPaths(\n toolClasses: (ClientTool | ServerTool)[],\n includeModelRequest: boolean = false,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ): BaseGraphDestination[] {\n const paths: BaseGraphDestination[] = [];\n if (hasToolsAvailable) {\n paths.push(TOOLS_NODE_NAME);\n }\n\n if (includeModelRequest) {\n paths.push(AGENT_NODE_NAME);\n }\n\n paths.push(END);\n\n return paths;\n }\n\n /**\n * Create routing function for tools node conditional edges.\n */\n #createToolsRouter(\n shouldReturnDirect: Set<string>,\n exitNode: string | typeof END,\n toolReturnTarget: string\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages[messages.length - 1];\n\n // Check if we just executed a returnDirect tool\n if (\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n shouldReturnDirect.has(lastMessage.name)\n ) {\n // If we have a response format, route to agent to generate structured response\n // Otherwise, return directly to exit node (could be after_agent or END)\n return this.options.responseFormat ? toolReturnTarget : exitNode;\n }\n\n // For non-returnDirect tools, route back to loop entry node (could be middleware or agent)\n return toolReturnTarget;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n /**\n * v1: route the full message to the ToolNode; it filters already-processed\n * calls internally and runs the remaining ones via Promise.all.\n * v2: dispatch each pending call as a separate Send task.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * v1: route the full AIMessage to a single ToolNode invocation so all\n * tool calls run concurrently via Promise.all.\n *\n * v2: dispatch each regular tool call as a separate Send task, matching\n * the behaviour of #createModelRouter when no afterModel middleware is\n * present.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n const regularToolCalls = (lastMessage as AIMessage).tool_calls!.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n TSubgraphs extends boolean,\n TEncoding extends \"text/event-stream\" | undefined,\n >(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TSubgraphs,\n TEncoding\n >\n ) {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n return this.#graph.stream(\n initializedState,\n mergedConfig as Record<string, any>\n ) as Promise<\n IterableReadableStream<\n StreamOutputMap<\n TStreamMode,\n TSubgraphs,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphsAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReactAgent.js","names":["#defaultConfig","#toolBehaviorVersion","#agentNode","#stateManager","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","#initializeMiddlewareStates"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type {\n BaseCheckpointSaver,\n BaseStore,\n CheckpointListOptions,\n} from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport {\n mergeConfigs,\n type Runnable,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaValue,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaValue<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n #defaultConfig: RunnableConfig;\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >,\n defaultConfig?: RunnableConfig\n ) {\n this.#defaultConfig = mergeConfigs(defaultConfig ?? {}, {\n metadata: { ls_integration: \"langchain_create_agent\" },\n });\n if (options.name) {\n this.#defaultConfig = mergeConfigs(this.#defaultConfig, {\n metadata: { lc_agent_name: options.name },\n });\n }\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(\n shouldReturnDirect,\n exitNode,\n toolReturnTarget\n ),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n get checkpointer(): BaseCheckpointSaver | boolean | undefined {\n return this.#graph.checkpointer;\n }\n\n set checkpointer(value: BaseCheckpointSaver | boolean | undefined) {\n this.#graph.checkpointer = value;\n }\n\n get store(): BaseStore | undefined {\n return this.#graph.store;\n }\n\n set store(value: BaseStore | undefined) {\n this.#graph.store = value;\n }\n\n /**\n * Creates a new ReactAgent with the given config merged into the existing config.\n * Follows the same pattern as LangGraph's Pregel.withConfig().\n *\n * The merged config is applied as a default that gets merged with any config\n * passed at invocation time (invoke/stream). Invocation-time config takes precedence.\n *\n * @param config - Configuration to merge with existing config\n * @returns A new ReactAgent instance with the merged configuration\n *\n * @example\n * ```typescript\n * const agent = createAgent({ model: \"gpt-4o\", tools: [...] });\n *\n * // Set a default recursion limit\n * const configuredAgent = agent.withConfig({ recursionLimit: 1000 });\n *\n * // Chain multiple configs\n * const debugAgent = agent\n * .withConfig({ recursionLimit: 1000 })\n * .withConfig({ tags: [\"debug\"] });\n * ```\n */\n withConfig(\n config: Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">\n ): ReactAgent<Types> {\n return new ReactAgent(\n this.options,\n mergeConfigs(this.#defaultConfig, config)\n );\n }\n\n /**\n * Get possible edge destinations from model node.\n * @param toolClasses names of tools to call\n * @param includeModelRequest whether to include \"model_request\" as a valid path (for jumpTo routing)\n * @param hasToolsAvailable whether tools are available (includes dynamic tools via middleware)\n * @returns list of possible edge destinations\n */\n #getModelPaths(\n toolClasses: (ClientTool | ServerTool)[],\n includeModelRequest: boolean = false,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ): BaseGraphDestination[] {\n const paths: BaseGraphDestination[] = [];\n if (hasToolsAvailable) {\n paths.push(TOOLS_NODE_NAME);\n }\n\n if (includeModelRequest) {\n paths.push(AGENT_NODE_NAME);\n }\n\n paths.push(END);\n\n return paths;\n }\n\n /**\n * Create routing function for tools node conditional edges.\n */\n #createToolsRouter(\n shouldReturnDirect: Set<string>,\n exitNode: string | typeof END,\n toolReturnTarget: string\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages[messages.length - 1];\n\n // Check if we just executed a returnDirect tool\n if (\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n shouldReturnDirect.has(lastMessage.name)\n ) {\n // If we have a response format, route to agent to generate structured response\n // Otherwise, return directly to exit node (could be after_agent or END)\n return this.options.responseFormat ? toolReturnTarget : exitNode;\n }\n\n // For non-returnDirect tools, route back to loop entry node (could be middleware or agent)\n return toolReturnTarget;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n /**\n * v1: route the full message to the ToolNode; it filters already-processed\n * calls internally and runs the remaining ones via Promise.all.\n * v2: dispatch each pending call as a separate Send task.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * v1: route the full AIMessage to a single ToolNode invocation so all\n * tool calls run concurrently via Promise.all.\n *\n * v2: dispatch each regular tool call as a separate Send task, matching\n * the behaviour of #createModelRouter when no afterModel middleware is\n * present.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n const regularToolCalls = (lastMessage as AIMessage).tool_calls!.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n mergedConfig as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n TSubgraphs extends boolean,\n TEncoding extends \"text/event-stream\" | undefined,\n >(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TSubgraphs,\n TEncoding\n >\n ) {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n mergedConfig as RunnableConfig\n );\n return this.#graph.stream(\n initializedState,\n mergedConfig as Record<string, any>\n ) as Promise<\n IterableReadableStream<\n StreamOutputMap<\n TStreamMode,\n TSubgraphs,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n const mergedConfig = mergeConfigs(this.#defaultConfig, config);\n return this.#graph.streamEvents(\n state,\n {\n ...(mergedConfig as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphsAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  require("../../_virtual/_rolldown/runtime.cjs");
2
2
  const require_chat_models_universal = require("../../chat_models/universal.cjs");
3
+ const require_model = require("../model.cjs");
3
4
  const require_errors = require("../errors.cjs");
4
5
  const require_utils = require("../utils.cjs");
5
6
  const require_RunnableCallable = require("../RunnableCallable.cjs");
@@ -46,9 +47,12 @@ var AgentNode = class extends require_RunnableCallable.RunnableCallable {
46
47
  * @param model - The model to get the response format for.
47
48
  * @returns The response format.
48
49
  */
49
- #getResponseFormat(model) {
50
+ async #getResponseFormat(model) {
50
51
  if (!this.#options.responseFormat) return;
51
- const strategies = require_responses.transformResponseFormat(this.#options.responseFormat, void 0, model);
52
+ let resolvedModel;
53
+ if (require_model.isConfigurableModel(model)) resolvedModel = await model._getModelInstance();
54
+ else if (typeof model !== "string") resolvedModel = model;
55
+ const strategies = require_responses.transformResponseFormat(this.#options.responseFormat, void 0, resolvedModel);
52
56
  /**
53
57
  * Populate a list of structured tool info.
54
58
  */
@@ -134,7 +138,7 @@ var AgentNode = class extends require_RunnableCallable.RunnableCallable {
134
138
  * Check if the LLM already has bound tools and throw if it does.
135
139
  */
136
140
  require_utils.validateLLMHasNoBoundTools(request.model);
137
- const structuredResponseFormat = this.#getResponseFormat(request.model);
141
+ const structuredResponseFormat = await this.#getResponseFormat(request.model);
138
142
  const modelWithTools = await this.#bindTools(request.model, request, structuredResponseFormat);
139
143
  /**
140
144
  * prepend the system message to the messages if it is not empty
@@ -453,6 +457,7 @@ var AgentNode = class extends require_RunnableCallable.RunnableCallable {
453
457
  type: "json_schema",
454
458
  schema: structuredResponseFormat.strategy.schema
455
459
  } },
460
+ responseSchema: structuredResponseFormat.strategy.schema,
456
461
  ls_structured_output_format: {
457
462
  kwargs: { method: "json_schema" },
458
463
  schema: structuredResponseFormat.strategy.schema
@@ -1 +1 @@
1
- {"version":3,"file":"AgentNode.cjs","names":["AIMessage","RunnableCallable","#run","#options","#systemMessage","transformResponseFormat","ProviderStrategy","ToolStrategy","ToolMessage","Command","#invokeModel","#areMoreStepsNeeded","initChatModel","#deriveModel","#getResponseFormat","#bindTools","mergeAbortSignals","#handleMultipleStructuredOutputs","#handleSingleStructuredOutput","toPartialZodObject","isClientTool","SystemMessage","MiddlewareError","MultipleStructuredOutputsError","#handleToolStrategyError","hasToolCalls","bindTools","withAgentName"],"sources":["../../../src/agents/nodes/AgentNode.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\nimport { Runnable, RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n BaseMessage,\n AIMessage,\n ToolMessage,\n SystemMessage,\n} from \"@langchain/core/messages\";\nimport {\n Command,\n isCommand,\n type LangGraphRunnableConfig,\n} from \"@langchain/langgraph\";\nimport { type LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { type BaseChatModelCallOptions } from \"@langchain/core/language_models/chat_models\";\nimport {\n InteropZodObject,\n getSchemaDescription,\n interopParse,\n} from \"@langchain/core/utils/types\";\nimport { raceWithSignal } from \"@langchain/core/runnables\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\n\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { MultipleStructuredOutputsError, MiddlewareError } from \"../errors.js\";\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport {\n bindTools,\n validateLLMHasNoBoundTools,\n hasToolCalls,\n isClientTool,\n} from \"../utils.js\";\nimport { mergeAbortSignals, toPartialZodObject } from \"../nodes/utils.js\";\nimport { CreateAgentParams } from \"../types.js\";\nimport type { InternalAgentState, Runtime } from \"../runtime.js\";\nimport type {\n AgentMiddleware,\n AnyAnnotationRoot,\n WrapModelCallHandler,\n} from \"../middleware/types.js\";\nimport type { ModelRequest } from \"./types.js\";\nimport { withAgentName } from \"../withAgentName.js\";\nimport {\n ToolStrategy,\n ProviderStrategy,\n transformResponseFormat,\n ToolStrategyError,\n} from \"../responses.js\";\n\ntype ResponseHandlerResult<StructuredResponseFormat> =\n | {\n structuredResponse: StructuredResponseFormat;\n messages: BaseMessage[];\n }\n | Promise<Command>;\n\n/**\n * Wrap the base handler with middleware wrapModelCall hooks\n * Middleware are composed so the first middleware is the outermost wrapper\n * Example: [auth, retry, cache] means auth wraps retry wraps cache wraps baseHandler\n */\ntype InternalModelResponse<StructuredResponseFormat> =\n | AIMessage\n | ResponseHandlerResult<StructuredResponseFormat>\n | Command;\n\n/**\n * Check if the response is an internal model response.\n * @param response - The response to check.\n * @returns True if the response is an internal model response, false otherwise.\n */\nfunction isInternalModelResponse<StructuredResponseFormat>(\n response: unknown\n): response is InternalModelResponse<StructuredResponseFormat> {\n return (\n AIMessage.isInstance(response) ||\n isCommand(response) ||\n (typeof response === \"object\" &&\n response !== null &&\n \"structuredResponse\" in response &&\n \"messages\" in response)\n );\n}\n\n/**\n * The name of the agent node in the state graph.\n */\nexport const AGENT_NODE_NAME = \"model_request\";\n\nexport interface AgentNodeOptions<\n StructuredResponseFormat extends Record<string, unknown> = Record<\n string,\n unknown\n >,\n StateSchema extends AnyAnnotationRoot | InteropZodObject = AnyAnnotationRoot,\n ContextSchema extends AnyAnnotationRoot | InteropZodObject =\n AnyAnnotationRoot,\n> extends Pick<\n CreateAgentParams<StructuredResponseFormat, StateSchema, ContextSchema>,\n \"model\" | \"includeAgentName\" | \"name\" | \"responseFormat\" | \"middleware\"\n> {\n toolClasses: (ClientTool | ServerTool)[];\n shouldReturnDirect: Set<string>;\n signal?: AbortSignal;\n systemMessage: SystemMessage;\n wrapModelCallHookMiddleware?: [\n AgentMiddleware,\n () => Record<string, unknown>,\n ][];\n}\n\ninterface NativeResponseFormat {\n type: \"native\";\n strategy: ProviderStrategy;\n}\n\ninterface ToolResponseFormat {\n type: \"tool\";\n tools: Record<string, ToolStrategy>;\n}\n\ntype ResponseFormat = NativeResponseFormat | ToolResponseFormat;\n\nexport class AgentNode<\n StructuredResponseFormat extends Record<string, unknown> = Record<\n string,\n unknown\n >,\n ContextSchema extends AnyAnnotationRoot | InteropZodObject =\n AnyAnnotationRoot,\n> extends RunnableCallable<\n InternalAgentState<StructuredResponseFormat>,\n | Command[]\n | {\n messages: BaseMessage[];\n structuredResponse: StructuredResponseFormat;\n }\n> {\n #options: AgentNodeOptions<StructuredResponseFormat, ContextSchema>;\n #systemMessage: SystemMessage;\n\n constructor(\n options: AgentNodeOptions<StructuredResponseFormat, ContextSchema>\n ) {\n super({\n name: options.name ?? \"model\",\n func: (input, config) => this.#run(input, config as RunnableConfig),\n });\n\n this.#options = options;\n this.#systemMessage = options.systemMessage;\n }\n\n /**\n * Returns response format primtivies based on given model and response format provided by the user.\n *\n * If the user selects a tool output:\n * - return a record of tools to extract structured output from the model's response\n *\n * if the the user selects a native schema output or if the model supports JSON schema output:\n * - return a provider strategy to extract structured output from the model's response\n *\n * @param model - The model to get the response format for.\n * @returns The response format.\n */\n #getResponseFormat(\n model: string | LanguageModelLike\n ): ResponseFormat | undefined {\n if (!this.#options.responseFormat) {\n return undefined;\n }\n\n const strategies = transformResponseFormat(\n this.#options.responseFormat,\n undefined,\n model\n );\n\n /**\n * we either define a list of provider strategies or a list of tool strategies\n */\n const isProviderStrategy = strategies.every(\n (format) => format instanceof ProviderStrategy\n );\n\n /**\n * Populate a list of structured tool info.\n */\n if (!isProviderStrategy) {\n return {\n type: \"tool\",\n tools: (\n strategies.filter(\n (format) => format instanceof ToolStrategy\n ) as ToolStrategy[]\n ).reduce(\n (acc, format) => {\n acc[format.name] = format;\n return acc;\n },\n {} as Record<string, ToolStrategy>\n ),\n };\n }\n\n return {\n type: \"native\",\n /**\n * there can only be one provider strategy\n */\n strategy: strategies[0] as ProviderStrategy,\n };\n }\n\n async #run(\n state: InternalAgentState<StructuredResponseFormat>,\n config: RunnableConfig\n ) {\n /**\n * Check if we just executed a returnDirect tool\n * If so, we should generate structured response (if needed) and stop\n */\n const lastMessage = state.messages.at(-1);\n if (\n lastMessage &&\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n this.#options.shouldReturnDirect.has(lastMessage.name)\n ) {\n return [new Command({ update: { messages: [] } })];\n }\n\n const { response, lastAiMessage, collectedCommands } =\n await this.#invokeModel(state, config);\n\n /**\n * structuredResponse — return as a plain state update dict (not a Command)\n * because the structuredResponse channel uses UntrackedValue(guard=true)\n * which only allows a single write per step.\n */\n if (\n typeof response === \"object\" &&\n response !== null &&\n \"structuredResponse\" in response &&\n \"messages\" in response\n ) {\n const { structuredResponse, messages } = response as {\n structuredResponse: StructuredResponseFormat;\n messages: BaseMessage[];\n };\n return {\n messages: [...state.messages, ...messages],\n structuredResponse,\n };\n }\n\n const commands: Command[] = [];\n const aiMessage: AIMessage | null = AIMessage.isInstance(response)\n ? response\n : lastAiMessage;\n\n // messages\n if (aiMessage) {\n aiMessage.name = this.name;\n aiMessage.lc_kwargs.name = this.name;\n\n if (this.#areMoreStepsNeeded(state, aiMessage)) {\n commands.push(\n new Command({\n update: {\n messages: [\n new AIMessage({\n content: \"Sorry, need more steps to process this request.\",\n name: this.name,\n id: aiMessage.id,\n }),\n ],\n },\n })\n );\n } else {\n commands.push(new Command({ update: { messages: [aiMessage] } }));\n }\n }\n\n // Commands (from base handler retries or middleware)\n if (isCommand(response) && !collectedCommands.includes(response)) {\n commands.push(response);\n }\n commands.push(...collectedCommands);\n\n return commands;\n }\n\n /**\n * Derive the model from the options.\n * @param state - The state of the agent.\n * @param config - The config of the agent.\n * @returns The model.\n */\n #deriveModel() {\n if (typeof this.#options.model === \"string\") {\n return initChatModel(this.#options.model);\n }\n\n if (this.#options.model) {\n return this.#options.model;\n }\n\n throw new Error(\"No model option was provided, either via `model` option.\");\n }\n\n async #invokeModel(\n state: InternalAgentState<StructuredResponseFormat>,\n config: RunnableConfig,\n options: {\n lastMessage?: string;\n } = {}\n ): Promise<{\n response: InternalModelResponse<StructuredResponseFormat>;\n lastAiMessage: AIMessage | null;\n collectedCommands: Command[];\n }> {\n const model = await this.#deriveModel();\n const lgConfig = config as LangGraphRunnableConfig;\n\n /**\n * Create a local variable for current system message to avoid concurrency issues\n * Each invocation gets its own copy\n */\n let currentSystemMessage = this.#systemMessage;\n\n /**\n * Shared tracking state for AIMessage and Command collection.\n * lastAiMessage tracks the effective AIMessage through the middleware chain.\n * collectedCommands accumulates Commands returned by middleware (not base handler).\n */\n let lastAiMessage: AIMessage | null = null;\n const collectedCommands: Command[] = [];\n\n /**\n * Create the base handler that performs the actual model invocation\n */\n const baseHandler = async (\n request: ModelRequest\n ): Promise<AIMessage | ResponseHandlerResult<StructuredResponseFormat>> => {\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n validateLLMHasNoBoundTools(request.model);\n\n const structuredResponseFormat = this.#getResponseFormat(request.model);\n const modelWithTools = await this.#bindTools(\n request.model,\n request,\n structuredResponseFormat\n );\n\n /**\n * prepend the system message to the messages if it is not empty\n */\n const messages = [\n ...(currentSystemMessage.text === \"\" ? [] : [currentSystemMessage]),\n ...request.messages,\n ];\n\n const signal = mergeAbortSignals(this.#options.signal, config.signal);\n const response = (await raceWithSignal(\n modelWithTools.invoke(messages, {\n ...config,\n signal,\n }),\n signal\n )) as AIMessage;\n\n lastAiMessage = response;\n\n /**\n * if the user requests a native schema output, try to parse the response\n * and return the structured response if it is valid\n */\n if (structuredResponseFormat?.type === \"native\") {\n const structuredResponse =\n structuredResponseFormat.strategy.parse(response);\n if (structuredResponse) {\n return { structuredResponse, messages: [response] };\n }\n\n return response;\n }\n\n if (!structuredResponseFormat || !response.tool_calls) {\n return response;\n }\n\n const toolCalls = response.tool_calls.filter(\n (call) => call.name in structuredResponseFormat.tools\n );\n\n /**\n * if there were not structured tool calls, we can return the response\n */\n if (toolCalls.length === 0) {\n return response;\n }\n\n /**\n * if there were multiple structured tool calls, we should throw an error as this\n * scenario is not defined/supported.\n */\n if (toolCalls.length > 1) {\n return this.#handleMultipleStructuredOutputs(\n response,\n toolCalls,\n structuredResponseFormat\n );\n }\n\n const toolStrategy = structuredResponseFormat.tools[toolCalls[0].name];\n const toolMessageContent = toolStrategy?.options?.toolMessageContent;\n return this.#handleSingleStructuredOutput(\n response,\n toolCalls[0],\n structuredResponseFormat,\n toolMessageContent ?? options.lastMessage\n );\n };\n\n const wrapperMiddleware = this.#options.wrapModelCallHookMiddleware ?? [];\n let wrappedHandler: (\n request: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >\n ) => Promise<InternalModelResponse<StructuredResponseFormat>> = baseHandler;\n\n /**\n * Build composed handler from last to first so first middleware becomes outermost\n */\n for (let i = wrapperMiddleware.length - 1; i >= 0; i--) {\n const [middleware, getMiddlewareState] = wrapperMiddleware[i];\n if (middleware.wrapModelCall) {\n const innerHandler = wrappedHandler;\n const currentMiddleware = middleware;\n const currentGetState = getMiddlewareState;\n\n wrappedHandler = async (\n request: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >\n ): Promise<InternalModelResponse<StructuredResponseFormat>> => {\n const baselineSystemMessage = currentSystemMessage;\n\n /**\n * Merge context with default context of middleware\n */\n const context = currentMiddleware.contextSchema\n ? interopParse(\n currentMiddleware.contextSchema,\n lgConfig?.context || {}\n )\n : lgConfig?.context;\n\n /**\n * Create runtime\n */\n const runtime: Runtime<unknown> = Object.freeze({\n context,\n store: lgConfig.store,\n configurable: lgConfig.configurable,\n writer: lgConfig.writer,\n interrupt: lgConfig.interrupt,\n signal: lgConfig.signal,\n });\n\n /**\n * Create the request with state and runtime\n */\n const requestWithStateAndRuntime: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n > = {\n ...request,\n state: {\n ...(middleware.stateSchema\n ? interopParse(\n toPartialZodObject(middleware.stateSchema),\n state\n )\n : {}),\n ...currentGetState(),\n messages: state.messages,\n } as InternalAgentState<StructuredResponseFormat>,\n runtime,\n };\n\n /**\n * Create handler that validates tools and calls the inner handler\n */\n const handlerWithValidation = async (\n req: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >\n ): Promise<InternalModelResponse<StructuredResponseFormat>> => {\n currentSystemMessage = baselineSystemMessage;\n\n /**\n * Verify that the user didn't add any new tools.\n * We can't allow this as the ToolNode is already initiated with given tools.\n */\n const modifiedTools = req.tools ?? [];\n const newTools = modifiedTools.filter(\n (tool) =>\n isClientTool(tool) &&\n !this.#options.toolClasses.some((t) => t.name === tool.name)\n );\n if (newTools.length > 0) {\n throw new Error(\n `You have added a new tool in \"wrapModelCall\" hook of middleware \"${\n currentMiddleware.name\n }\": ${newTools\n .map((tool) => tool.name)\n .join(\", \")}. This is not supported.`\n );\n }\n\n /**\n * Verify that user has not added or modified a tool with the same name.\n * We can't allow this as the ToolNode is already initiated with given tools.\n */\n const invalidTools = modifiedTools.filter(\n (tool) =>\n isClientTool(tool) &&\n this.#options.toolClasses.every((t) => t !== tool)\n );\n if (invalidTools.length > 0) {\n throw new Error(\n `You have modified a tool in \"wrapModelCall\" hook of middleware \"${\n currentMiddleware.name\n }\": ${invalidTools\n .map((tool) => tool.name)\n .join(\", \")}. This is not supported.`\n );\n }\n\n let normalizedReq = req;\n const hasSystemPromptChanged =\n req.systemPrompt !== currentSystemMessage.text;\n const hasSystemMessageChanged =\n req.systemMessage !== currentSystemMessage;\n if (hasSystemPromptChanged && hasSystemMessageChanged) {\n throw new Error(\n \"Cannot change both systemPrompt and systemMessage in the same request.\"\n );\n }\n\n /**\n * Check if systemPrompt is a string was changed, if so create a new SystemMessage\n */\n if (hasSystemPromptChanged) {\n currentSystemMessage = new SystemMessage({\n content: [{ type: \"text\", text: req.systemPrompt }],\n });\n normalizedReq = {\n ...req,\n systemPrompt: currentSystemMessage.text,\n systemMessage: currentSystemMessage,\n };\n }\n /**\n * If the systemMessage was changed, update the current system message\n */\n if (hasSystemMessageChanged) {\n currentSystemMessage = new SystemMessage({\n ...req.systemMessage,\n });\n normalizedReq = {\n ...req,\n systemPrompt: currentSystemMessage.text,\n systemMessage: currentSystemMessage,\n };\n }\n\n const innerHandlerResult = await innerHandler(normalizedReq);\n\n /**\n * Normalize Commands so middleware always sees AIMessage from handler().\n * When an inner handler (base handler or nested middleware) returns a\n * Command (e.g. structured-output retry), substitute the tracked\n * lastAiMessage so the middleware sees an AIMessage, and collect the\n * raw Command so the framework can still propagate it (e.g. for retries).\n *\n * Only collect if not already present: Commands from inner middleware\n * are already tracked via the middleware validation layer (line ~627).\n */\n if (isCommand(innerHandlerResult) && lastAiMessage) {\n if (!collectedCommands.includes(innerHandlerResult)) {\n collectedCommands.push(innerHandlerResult);\n }\n return lastAiMessage as InternalModelResponse<StructuredResponseFormat>;\n }\n\n return innerHandlerResult;\n };\n\n // Call middleware's wrapModelCall with the validation handler\n if (!currentMiddleware.wrapModelCall) {\n return handlerWithValidation(requestWithStateAndRuntime);\n }\n\n try {\n const middlewareResponse = await currentMiddleware.wrapModelCall(\n requestWithStateAndRuntime,\n handlerWithValidation as WrapModelCallHandler\n );\n\n /**\n * Validate that this specific middleware returned a valid response\n */\n if (!isInternalModelResponse(middlewareResponse)) {\n throw new Error(\n `Invalid response from \"wrapModelCall\" in middleware \"${\n currentMiddleware.name\n }\": expected AIMessage or Command, got ${typeof middlewareResponse}`\n );\n }\n\n if (AIMessage.isInstance(middlewareResponse)) {\n lastAiMessage = middlewareResponse;\n } else if (isCommand(middlewareResponse)) {\n collectedCommands.push(middlewareResponse);\n }\n\n return middlewareResponse;\n } catch (error) {\n throw MiddlewareError.wrap(error, currentMiddleware.name);\n }\n };\n }\n }\n\n /**\n * Execute the wrapped handler with the initial request\n * Reset current system prompt to initial state and convert to string using .text getter\n * for backwards compatibility with ModelRequest\n */\n currentSystemMessage = this.#systemMessage;\n const initialRequest: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n > = {\n model,\n systemPrompt: currentSystemMessage?.text,\n systemMessage: currentSystemMessage,\n messages: state.messages,\n tools: this.#options.toolClasses,\n state,\n runtime: Object.freeze({\n context: lgConfig?.context,\n store: lgConfig.store,\n configurable: lgConfig.configurable,\n writer: lgConfig.writer,\n interrupt: lgConfig.interrupt,\n signal: lgConfig.signal,\n }) as Runtime<unknown>,\n };\n\n const response = await wrappedHandler(initialRequest);\n return { response, lastAiMessage, collectedCommands };\n }\n\n /**\n * If the model returns multiple structured outputs, we need to handle it.\n * @param response - The response from the model\n * @param toolCalls - The tool calls that were made\n * @returns The response from the model\n */\n #handleMultipleStructuredOutputs(\n response: AIMessage,\n toolCalls: ToolCall[],\n responseFormat: ToolResponseFormat\n ): Promise<Command> {\n const multipleStructuredOutputsError = new MultipleStructuredOutputsError(\n toolCalls.map((call) => call.name)\n );\n\n return this.#handleToolStrategyError(\n multipleStructuredOutputsError,\n response,\n toolCalls[0],\n responseFormat\n );\n }\n\n /**\n * If the model returns a single structured output, we need to handle it.\n * @param toolCall - The tool call that was made\n * @returns The structured response and a message to the LLM if needed\n */\n #handleSingleStructuredOutput(\n response: AIMessage,\n toolCall: ToolCall,\n responseFormat: ToolResponseFormat,\n lastMessage?: string\n ): ResponseHandlerResult<StructuredResponseFormat> {\n const tool = responseFormat.tools[toolCall.name];\n\n try {\n const structuredResponse = tool.parse(\n toolCall.args\n ) as StructuredResponseFormat;\n\n return {\n structuredResponse,\n messages: [\n response,\n new ToolMessage({\n tool_call_id: toolCall.id ?? \"\",\n content: JSON.stringify(structuredResponse),\n name: toolCall.name,\n }),\n new AIMessage(\n lastMessage ??\n `Returning structured response: ${JSON.stringify(\n structuredResponse\n )}`\n ),\n ],\n };\n } catch (error) {\n return this.#handleToolStrategyError(\n error as ToolStrategyError,\n response,\n toolCall,\n responseFormat\n );\n }\n }\n\n async #handleToolStrategyError(\n error: ToolStrategyError,\n response: AIMessage,\n toolCall: ToolCall,\n responseFormat: ToolResponseFormat\n ): Promise<Command> {\n /**\n * Using the `errorHandler` option of the first `ToolStrategy` entry is sufficient here.\n * There is technically only one `ToolStrategy` entry in `structuredToolInfo` if the user\n * uses `toolStrategy` to define the response format. If the user applies a list of json\n * schema objects, these will be transformed into multiple `ToolStrategy` entries but all\n * with the same `handleError` option.\n */\n const errorHandler = Object.values(responseFormat.tools).at(0)?.options\n ?.handleError;\n\n const toolCallId = toolCall.id;\n if (!toolCallId) {\n throw new Error(\n \"Tool call ID is required to handle tool output errors. Please provide a tool call ID.\"\n );\n }\n\n /**\n * Default behavior: retry if `errorHandler` is undefined or truthy.\n * Only throw if explicitly set to `false`.\n */\n if (errorHandler === false) {\n throw error;\n }\n\n /**\n * retry if:\n */\n if (\n /**\n * if the user has provided truthy value as the `errorHandler`, return a new AIMessage\n * with the error message and retry the tool call.\n */\n errorHandler === undefined ||\n (typeof errorHandler === \"boolean\" && errorHandler) ||\n /**\n * if `errorHandler` is an array and contains MultipleStructuredOutputsError\n */\n (Array.isArray(errorHandler) &&\n errorHandler.some((h) => h instanceof MultipleStructuredOutputsError))\n ) {\n return new Command({\n update: {\n messages: [\n response,\n new ToolMessage({\n content: error.message,\n tool_call_id: toolCallId,\n }),\n ],\n },\n goto: AGENT_NODE_NAME,\n });\n }\n\n /**\n * if `errorHandler` is a string, retry the tool call with given string\n */\n if (typeof errorHandler === \"string\") {\n return new Command({\n update: {\n messages: [\n response,\n new ToolMessage({\n content: errorHandler,\n tool_call_id: toolCallId,\n }),\n ],\n },\n goto: AGENT_NODE_NAME,\n });\n }\n\n /**\n * if `errorHandler` is a function, retry the tool call with the function\n */\n if (typeof errorHandler === \"function\") {\n const content = await errorHandler(error);\n if (typeof content !== \"string\") {\n throw new Error(\"Error handler must return a string.\");\n }\n\n return new Command({\n update: {\n messages: [\n response,\n new ToolMessage({\n content,\n tool_call_id: toolCallId,\n }),\n ],\n },\n goto: AGENT_NODE_NAME,\n });\n }\n\n /**\n * Default: retry if we reach here\n */\n return new Command({\n update: {\n messages: [\n response,\n new ToolMessage({\n content: error.message,\n tool_call_id: toolCallId,\n }),\n ],\n },\n goto: AGENT_NODE_NAME,\n });\n }\n\n #areMoreStepsNeeded(\n state: InternalAgentState<StructuredResponseFormat>,\n response: BaseMessage\n ): boolean {\n const allToolsReturnDirect =\n AIMessage.isInstance(response) &&\n response.tool_calls?.every((call) =>\n this.#options.shouldReturnDirect.has(call.name)\n );\n const remainingSteps =\n \"remainingSteps\" in state ? (state.remainingSteps as number) : undefined;\n return Boolean(\n remainingSteps &&\n ((remainingSteps < 1 && allToolsReturnDirect) ||\n (remainingSteps < 2 && hasToolCalls(state.messages.at(-1))))\n );\n }\n\n async #bindTools(\n model: LanguageModelLike,\n preparedOptions: ModelRequest | undefined,\n structuredResponseFormat: ResponseFormat | undefined\n ): Promise<Runnable> {\n const options: Partial<BaseChatModelCallOptions> = {};\n const structuredTools = Object.values(\n structuredResponseFormat && \"tools\" in structuredResponseFormat\n ? structuredResponseFormat.tools\n : {}\n );\n\n /**\n * Use tools from preparedOptions if provided, otherwise use default tools\n */\n const allTools = [\n ...(preparedOptions?.tools ?? this.#options.toolClasses),\n ...structuredTools.map((toolStrategy) => toolStrategy.tool),\n ];\n\n /**\n * If there are structured tools, we need to set the tool choice to \"any\"\n * so that the model can choose to use a structured tool or not.\n */\n const toolChoice =\n preparedOptions?.toolChoice ||\n (structuredTools.length > 0 ? \"any\" : undefined);\n\n /**\n * check if the user requests a native schema output\n */\n if (structuredResponseFormat?.type === \"native\") {\n const resolvedStrict =\n preparedOptions?.modelSettings?.strict ??\n structuredResponseFormat?.strategy?.strict ??\n true;\n\n const jsonSchemaParams = {\n name: structuredResponseFormat.strategy.schema?.name ?? \"extract\",\n description: getSchemaDescription(\n structuredResponseFormat.strategy.schema\n ),\n schema: structuredResponseFormat.strategy.schema,\n strict: resolvedStrict,\n };\n\n Object.assign(options, {\n /**\n * OpenAI-style options\n * Used by ChatOpenAI, ChatXAI, and other OpenAI-compatible providers.\n */\n response_format: {\n type: \"json_schema\",\n json_schema: jsonSchemaParams,\n },\n\n /**\n * Anthropic-style options\n */\n outputConfig: {\n format: {\n type: \"json_schema\",\n schema: structuredResponseFormat.strategy.schema,\n },\n },\n\n /**\n * for LangSmith structured output tracing\n */\n ls_structured_output_format: {\n kwargs: { method: \"json_schema\" },\n schema: structuredResponseFormat.strategy.schema,\n },\n strict: resolvedStrict,\n });\n }\n\n /**\n * Bind tools to the model if they are not already bound.\n */\n const modelWithTools = await bindTools(model, allTools, {\n ...options,\n ...preparedOptions?.modelSettings,\n tool_choice: toolChoice,\n });\n\n /**\n * Create a model runnable with the prompt and agent name\n * Use current SystemMessage state (which may have been modified by middleware)\n */\n const modelRunnable =\n this.#options.includeAgentName === \"inline\"\n ? withAgentName(modelWithTools, this.#options.includeAgentName)\n : modelWithTools;\n\n return modelRunnable;\n }\n\n /**\n * Returns internal bookkeeping state for StateManager, not graph output.\n * The return shape differs from the node's output type (Command).\n */\n // @ts-expect-error Internal state shape differs from graph output type\n getState(): { messages: BaseMessage[] } {\n const state = super.getState();\n const origState = state && !isCommand(state) ? state : {};\n\n return {\n messages: [],\n ...origState,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AgentNode.cjs","names":["AIMessage","RunnableCallable","#run","#options","#systemMessage","#getResponseFormat","isConfigurableModel","transformResponseFormat","ProviderStrategy","ToolStrategy","ToolMessage","Command","#invokeModel","#areMoreStepsNeeded","initChatModel","#deriveModel","#bindTools","mergeAbortSignals","#handleMultipleStructuredOutputs","#handleSingleStructuredOutput","toPartialZodObject","isClientTool","SystemMessage","MiddlewareError","MultipleStructuredOutputsError","#handleToolStrategyError","hasToolCalls","bindTools","withAgentName"],"sources":["../../../src/agents/nodes/AgentNode.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\nimport { Runnable, RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n BaseMessage,\n AIMessage,\n ToolMessage,\n SystemMessage,\n} from \"@langchain/core/messages\";\nimport {\n Command,\n isCommand,\n type LangGraphRunnableConfig,\n} from \"@langchain/langgraph\";\nimport { type LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { type BaseChatModelCallOptions } from \"@langchain/core/language_models/chat_models\";\nimport {\n InteropZodObject,\n getSchemaDescription,\n interopParse,\n} from \"@langchain/core/utils/types\";\nimport { raceWithSignal } from \"@langchain/core/runnables\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\n\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { MultipleStructuredOutputsError, MiddlewareError } from \"../errors.js\";\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport {\n bindTools,\n validateLLMHasNoBoundTools,\n hasToolCalls,\n isClientTool,\n} from \"../utils.js\";\nimport { isConfigurableModel } from \"../model.js\";\nimport { mergeAbortSignals, toPartialZodObject } from \"../nodes/utils.js\";\nimport { CreateAgentParams } from \"../types.js\";\nimport type { InternalAgentState, Runtime } from \"../runtime.js\";\nimport type {\n AgentMiddleware,\n AnyAnnotationRoot,\n WrapModelCallHandler,\n} from \"../middleware/types.js\";\nimport type { ModelRequest } from \"./types.js\";\nimport { withAgentName } from \"../withAgentName.js\";\nimport {\n ToolStrategy,\n ProviderStrategy,\n transformResponseFormat,\n ToolStrategyError,\n} from \"../responses.js\";\n\ntype ResponseHandlerResult<StructuredResponseFormat> =\n | {\n structuredResponse: StructuredResponseFormat;\n messages: BaseMessage[];\n }\n | Promise<Command>;\n\n/**\n * Wrap the base handler with middleware wrapModelCall hooks\n * Middleware are composed so the first middleware is the outermost wrapper\n * Example: [auth, retry, cache] means auth wraps retry wraps cache wraps baseHandler\n */\ntype InternalModelResponse<StructuredResponseFormat> =\n | AIMessage\n | ResponseHandlerResult<StructuredResponseFormat>\n | Command;\n\n/**\n * Check if the response is an internal model response.\n * @param response - The response to check.\n * @returns True if the response is an internal model response, false otherwise.\n */\nfunction isInternalModelResponse<StructuredResponseFormat>(\n response: unknown\n): response is InternalModelResponse<StructuredResponseFormat> {\n return (\n AIMessage.isInstance(response) ||\n isCommand(response) ||\n (typeof response === \"object\" &&\n response !== null &&\n \"structuredResponse\" in response &&\n \"messages\" in response)\n );\n}\n\n/**\n * The name of the agent node in the state graph.\n */\nexport const AGENT_NODE_NAME = \"model_request\";\n\nexport interface AgentNodeOptions<\n StructuredResponseFormat extends Record<string, unknown> = Record<\n string,\n unknown\n >,\n StateSchema extends AnyAnnotationRoot | InteropZodObject = AnyAnnotationRoot,\n ContextSchema extends AnyAnnotationRoot | InteropZodObject =\n AnyAnnotationRoot,\n> extends Pick<\n CreateAgentParams<StructuredResponseFormat, StateSchema, ContextSchema>,\n \"model\" | \"includeAgentName\" | \"name\" | \"responseFormat\" | \"middleware\"\n> {\n toolClasses: (ClientTool | ServerTool)[];\n shouldReturnDirect: Set<string>;\n signal?: AbortSignal;\n systemMessage: SystemMessage;\n wrapModelCallHookMiddleware?: [\n AgentMiddleware,\n () => Record<string, unknown>,\n ][];\n}\n\ninterface NativeResponseFormat {\n type: \"native\";\n strategy: ProviderStrategy;\n}\n\ninterface ToolResponseFormat {\n type: \"tool\";\n tools: Record<string, ToolStrategy>;\n}\n\ntype ResponseFormat = NativeResponseFormat | ToolResponseFormat;\n\nexport class AgentNode<\n StructuredResponseFormat extends Record<string, unknown> = Record<\n string,\n unknown\n >,\n ContextSchema extends AnyAnnotationRoot | InteropZodObject =\n AnyAnnotationRoot,\n> extends RunnableCallable<\n InternalAgentState<StructuredResponseFormat>,\n | Command[]\n | {\n messages: BaseMessage[];\n structuredResponse: StructuredResponseFormat;\n }\n> {\n #options: AgentNodeOptions<StructuredResponseFormat, ContextSchema>;\n #systemMessage: SystemMessage;\n\n constructor(\n options: AgentNodeOptions<StructuredResponseFormat, ContextSchema>\n ) {\n super({\n name: options.name ?? \"model\",\n func: (input, config) => this.#run(input, config as RunnableConfig),\n });\n\n this.#options = options;\n this.#systemMessage = options.systemMessage;\n }\n\n /**\n * Returns response format primtivies based on given model and response format provided by the user.\n *\n * If the user selects a tool output:\n * - return a record of tools to extract structured output from the model's response\n *\n * if the the user selects a native schema output or if the model supports JSON schema output:\n * - return a provider strategy to extract structured output from the model's response\n *\n * @param model - The model to get the response format for.\n * @returns The response format.\n */\n async #getResponseFormat(\n model: string | LanguageModelLike\n ): Promise<ResponseFormat | undefined> {\n if (!this.#options.responseFormat) {\n return undefined;\n }\n\n let resolvedModel: LanguageModelLike | undefined;\n if (isConfigurableModel(model)) {\n resolvedModel = await (\n model as unknown as {\n _getModelInstance: () => Promise<LanguageModelLike>;\n }\n )._getModelInstance();\n } else if (typeof model !== \"string\") {\n resolvedModel = model;\n }\n\n const strategies = transformResponseFormat(\n this.#options.responseFormat,\n undefined,\n resolvedModel\n );\n\n /**\n * we either define a list of provider strategies or a list of tool strategies\n */\n const isProviderStrategy = strategies.every(\n (format) => format instanceof ProviderStrategy\n );\n\n /**\n * Populate a list of structured tool info.\n */\n if (!isProviderStrategy) {\n return {\n type: \"tool\",\n tools: (\n strategies.filter(\n (format) => format instanceof ToolStrategy\n ) as ToolStrategy[]\n ).reduce(\n (acc, format) => {\n acc[format.name] = format;\n return acc;\n },\n {} as Record<string, ToolStrategy>\n ),\n };\n }\n\n return {\n type: \"native\",\n /**\n * there can only be one provider strategy\n */\n strategy: strategies[0] as ProviderStrategy,\n };\n }\n\n async #run(\n state: InternalAgentState<StructuredResponseFormat>,\n config: RunnableConfig\n ) {\n /**\n * Check if we just executed a returnDirect tool\n * If so, we should generate structured response (if needed) and stop\n */\n const lastMessage = state.messages.at(-1);\n if (\n lastMessage &&\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n this.#options.shouldReturnDirect.has(lastMessage.name)\n ) {\n return [new Command({ update: { messages: [] } })];\n }\n\n const { response, lastAiMessage, collectedCommands } =\n await this.#invokeModel(state, config);\n\n /**\n * structuredResponse — return as a plain state update dict (not a Command)\n * because the structuredResponse channel uses UntrackedValue(guard=true)\n * which only allows a single write per step.\n */\n if (\n typeof response === \"object\" &&\n response !== null &&\n \"structuredResponse\" in response &&\n \"messages\" in response\n ) {\n const { structuredResponse, messages } = response as {\n structuredResponse: StructuredResponseFormat;\n messages: BaseMessage[];\n };\n return {\n messages: [...state.messages, ...messages],\n structuredResponse,\n };\n }\n\n const commands: Command[] = [];\n const aiMessage: AIMessage | null = AIMessage.isInstance(response)\n ? response\n : lastAiMessage;\n\n // messages\n if (aiMessage) {\n aiMessage.name = this.name;\n aiMessage.lc_kwargs.name = this.name;\n\n if (this.#areMoreStepsNeeded(state, aiMessage)) {\n commands.push(\n new Command({\n update: {\n messages: [\n new AIMessage({\n content: \"Sorry, need more steps to process this request.\",\n name: this.name,\n id: aiMessage.id,\n }),\n ],\n },\n })\n );\n } else {\n commands.push(new Command({ update: { messages: [aiMessage] } }));\n }\n }\n\n // Commands (from base handler retries or middleware)\n if (isCommand(response) && !collectedCommands.includes(response)) {\n commands.push(response);\n }\n commands.push(...collectedCommands);\n\n return commands;\n }\n\n /**\n * Derive the model from the options.\n * @param state - The state of the agent.\n * @param config - The config of the agent.\n * @returns The model.\n */\n #deriveModel() {\n if (typeof this.#options.model === \"string\") {\n return initChatModel(this.#options.model);\n }\n\n if (this.#options.model) {\n return this.#options.model;\n }\n\n throw new Error(\"No model option was provided, either via `model` option.\");\n }\n\n async #invokeModel(\n state: InternalAgentState<StructuredResponseFormat>,\n config: RunnableConfig,\n options: {\n lastMessage?: string;\n } = {}\n ): Promise<{\n response: InternalModelResponse<StructuredResponseFormat>;\n lastAiMessage: AIMessage | null;\n collectedCommands: Command[];\n }> {\n const model = await this.#deriveModel();\n const lgConfig = config as LangGraphRunnableConfig;\n\n /**\n * Create a local variable for current system message to avoid concurrency issues\n * Each invocation gets its own copy\n */\n let currentSystemMessage = this.#systemMessage;\n\n /**\n * Shared tracking state for AIMessage and Command collection.\n * lastAiMessage tracks the effective AIMessage through the middleware chain.\n * collectedCommands accumulates Commands returned by middleware (not base handler).\n */\n let lastAiMessage: AIMessage | null = null;\n const collectedCommands: Command[] = [];\n\n /**\n * Create the base handler that performs the actual model invocation\n */\n const baseHandler = async (\n request: ModelRequest\n ): Promise<AIMessage | ResponseHandlerResult<StructuredResponseFormat>> => {\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n validateLLMHasNoBoundTools(request.model);\n\n const structuredResponseFormat = await this.#getResponseFormat(\n request.model\n );\n const modelWithTools = await this.#bindTools(\n request.model,\n request,\n structuredResponseFormat\n );\n\n /**\n * prepend the system message to the messages if it is not empty\n */\n const messages = [\n ...(currentSystemMessage.text === \"\" ? [] : [currentSystemMessage]),\n ...request.messages,\n ];\n\n const signal = mergeAbortSignals(this.#options.signal, config.signal);\n const response = (await raceWithSignal(\n modelWithTools.invoke(messages, {\n ...config,\n signal,\n }),\n signal\n )) as AIMessage;\n\n lastAiMessage = response;\n\n /**\n * if the user requests a native schema output, try to parse the response\n * and return the structured response if it is valid\n */\n if (structuredResponseFormat?.type === \"native\") {\n const structuredResponse =\n structuredResponseFormat.strategy.parse(response);\n if (structuredResponse) {\n return { structuredResponse, messages: [response] };\n }\n\n return response;\n }\n\n if (!structuredResponseFormat || !response.tool_calls) {\n return response;\n }\n\n const toolCalls = response.tool_calls.filter(\n (call) => call.name in structuredResponseFormat.tools\n );\n\n /**\n * if there were not structured tool calls, we can return the response\n */\n if (toolCalls.length === 0) {\n return response;\n }\n\n /**\n * if there were multiple structured tool calls, we should throw an error as this\n * scenario is not defined/supported.\n */\n if (toolCalls.length > 1) {\n return this.#handleMultipleStructuredOutputs(\n response,\n toolCalls,\n structuredResponseFormat\n );\n }\n\n const toolStrategy = structuredResponseFormat.tools[toolCalls[0].name];\n const toolMessageContent = toolStrategy?.options?.toolMessageContent;\n return this.#handleSingleStructuredOutput(\n response,\n toolCalls[0],\n structuredResponseFormat,\n toolMessageContent ?? options.lastMessage\n );\n };\n\n const wrapperMiddleware = this.#options.wrapModelCallHookMiddleware ?? [];\n let wrappedHandler: (\n request: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >\n ) => Promise<InternalModelResponse<StructuredResponseFormat>> = baseHandler;\n\n /**\n * Build composed handler from last to first so first middleware becomes outermost\n */\n for (let i = wrapperMiddleware.length - 1; i >= 0; i--) {\n const [middleware, getMiddlewareState] = wrapperMiddleware[i];\n if (middleware.wrapModelCall) {\n const innerHandler = wrappedHandler;\n const currentMiddleware = middleware;\n const currentGetState = getMiddlewareState;\n\n wrappedHandler = async (\n request: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >\n ): Promise<InternalModelResponse<StructuredResponseFormat>> => {\n const baselineSystemMessage = currentSystemMessage;\n\n /**\n * Merge context with default context of middleware\n */\n const context = currentMiddleware.contextSchema\n ? interopParse(\n currentMiddleware.contextSchema,\n lgConfig?.context || {}\n )\n : lgConfig?.context;\n\n /**\n * Create runtime\n */\n const runtime: Runtime<unknown> = Object.freeze({\n context,\n store: lgConfig.store,\n configurable: lgConfig.configurable,\n writer: lgConfig.writer,\n interrupt: lgConfig.interrupt,\n signal: lgConfig.signal,\n });\n\n /**\n * Create the request with state and runtime\n */\n const requestWithStateAndRuntime: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n > = {\n ...request,\n state: {\n ...(middleware.stateSchema\n ? interopParse(\n toPartialZodObject(middleware.stateSchema),\n state\n )\n : {}),\n ...currentGetState(),\n messages: state.messages,\n } as InternalAgentState<StructuredResponseFormat>,\n runtime,\n };\n\n /**\n * Create handler that validates tools and calls the inner handler\n */\n const handlerWithValidation = async (\n req: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >\n ): Promise<InternalModelResponse<StructuredResponseFormat>> => {\n currentSystemMessage = baselineSystemMessage;\n\n /**\n * Verify that the user didn't add any new tools.\n * We can't allow this as the ToolNode is already initiated with given tools.\n */\n const modifiedTools = req.tools ?? [];\n const newTools = modifiedTools.filter(\n (tool) =>\n isClientTool(tool) &&\n !this.#options.toolClasses.some((t) => t.name === tool.name)\n );\n if (newTools.length > 0) {\n throw new Error(\n `You have added a new tool in \"wrapModelCall\" hook of middleware \"${\n currentMiddleware.name\n }\": ${newTools\n .map((tool) => tool.name)\n .join(\", \")}. This is not supported.`\n );\n }\n\n /**\n * Verify that user has not added or modified a tool with the same name.\n * We can't allow this as the ToolNode is already initiated with given tools.\n */\n const invalidTools = modifiedTools.filter(\n (tool) =>\n isClientTool(tool) &&\n this.#options.toolClasses.every((t) => t !== tool)\n );\n if (invalidTools.length > 0) {\n throw new Error(\n `You have modified a tool in \"wrapModelCall\" hook of middleware \"${\n currentMiddleware.name\n }\": ${invalidTools\n .map((tool) => tool.name)\n .join(\", \")}. This is not supported.`\n );\n }\n\n let normalizedReq = req;\n const hasSystemPromptChanged =\n req.systemPrompt !== currentSystemMessage.text;\n const hasSystemMessageChanged =\n req.systemMessage !== currentSystemMessage;\n if (hasSystemPromptChanged && hasSystemMessageChanged) {\n throw new Error(\n \"Cannot change both systemPrompt and systemMessage in the same request.\"\n );\n }\n\n /**\n * Check if systemPrompt is a string was changed, if so create a new SystemMessage\n */\n if (hasSystemPromptChanged) {\n currentSystemMessage = new SystemMessage({\n content: [{ type: \"text\", text: req.systemPrompt }],\n });\n normalizedReq = {\n ...req,\n systemPrompt: currentSystemMessage.text,\n systemMessage: currentSystemMessage,\n };\n }\n /**\n * If the systemMessage was changed, update the current system message\n */\n if (hasSystemMessageChanged) {\n currentSystemMessage = new SystemMessage({\n ...req.systemMessage,\n });\n normalizedReq = {\n ...req,\n systemPrompt: currentSystemMessage.text,\n systemMessage: currentSystemMessage,\n };\n }\n\n const innerHandlerResult = await innerHandler(normalizedReq);\n\n /**\n * Normalize Commands so middleware always sees AIMessage from handler().\n * When an inner handler (base handler or nested middleware) returns a\n * Command (e.g. structured-output retry), substitute the tracked\n * lastAiMessage so the middleware sees an AIMessage, and collect the\n * raw Command so the framework can still propagate it (e.g. for retries).\n *\n * Only collect if not already present: Commands from inner middleware\n * are already tracked via the middleware validation layer (line ~627).\n */\n if (isCommand(innerHandlerResult) && lastAiMessage) {\n if (!collectedCommands.includes(innerHandlerResult)) {\n collectedCommands.push(innerHandlerResult);\n }\n return lastAiMessage as InternalModelResponse<StructuredResponseFormat>;\n }\n\n return innerHandlerResult;\n };\n\n // Call middleware's wrapModelCall with the validation handler\n if (!currentMiddleware.wrapModelCall) {\n return handlerWithValidation(requestWithStateAndRuntime);\n }\n\n try {\n const middlewareResponse = await currentMiddleware.wrapModelCall(\n requestWithStateAndRuntime,\n handlerWithValidation as WrapModelCallHandler\n );\n\n /**\n * Validate that this specific middleware returned a valid response\n */\n if (!isInternalModelResponse(middlewareResponse)) {\n throw new Error(\n `Invalid response from \"wrapModelCall\" in middleware \"${\n currentMiddleware.name\n }\": expected AIMessage or Command, got ${typeof middlewareResponse}`\n );\n }\n\n if (AIMessage.isInstance(middlewareResponse)) {\n lastAiMessage = middlewareResponse;\n } else if (isCommand(middlewareResponse)) {\n collectedCommands.push(middlewareResponse);\n }\n\n return middlewareResponse;\n } catch (error) {\n throw MiddlewareError.wrap(error, currentMiddleware.name);\n }\n };\n }\n }\n\n /**\n * Execute the wrapped handler with the initial request\n * Reset current system prompt to initial state and convert to string using .text getter\n * for backwards compatibility with ModelRequest\n */\n currentSystemMessage = this.#systemMessage;\n const initialRequest: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n > = {\n model,\n systemPrompt: currentSystemMessage?.text,\n systemMessage: currentSystemMessage,\n messages: state.messages,\n tools: this.#options.toolClasses,\n state,\n runtime: Object.freeze({\n context: lgConfig?.context,\n store: lgConfig.store,\n configurable: lgConfig.configurable,\n writer: lgConfig.writer,\n interrupt: lgConfig.interrupt,\n signal: lgConfig.signal,\n }) as Runtime<unknown>,\n };\n\n const response = await wrappedHandler(initialRequest);\n return { response, lastAiMessage, collectedCommands };\n }\n\n /**\n * If the model returns multiple structured outputs, we need to handle it.\n * @param response - The response from the model\n * @param toolCalls - The tool calls that were made\n * @returns The response from the model\n */\n #handleMultipleStructuredOutputs(\n response: AIMessage,\n toolCalls: ToolCall[],\n responseFormat: ToolResponseFormat\n ): Promise<Command> {\n const multipleStructuredOutputsError = new MultipleStructuredOutputsError(\n toolCalls.map((call) => call.name)\n );\n\n return this.#handleToolStrategyError(\n multipleStructuredOutputsError,\n response,\n toolCalls[0],\n responseFormat\n );\n }\n\n /**\n * If the model returns a single structured output, we need to handle it.\n * @param toolCall - The tool call that was made\n * @returns The structured response and a message to the LLM if needed\n */\n #handleSingleStructuredOutput(\n response: AIMessage,\n toolCall: ToolCall,\n responseFormat: ToolResponseFormat,\n lastMessage?: string\n ): ResponseHandlerResult<StructuredResponseFormat> {\n const tool = responseFormat.tools[toolCall.name];\n\n try {\n const structuredResponse = tool.parse(\n toolCall.args\n ) as StructuredResponseFormat;\n\n return {\n structuredResponse,\n messages: [\n response,\n new ToolMessage({\n tool_call_id: toolCall.id ?? \"\",\n content: JSON.stringify(structuredResponse),\n name: toolCall.name,\n }),\n new AIMessage(\n lastMessage ??\n `Returning structured response: ${JSON.stringify(\n structuredResponse\n )}`\n ),\n ],\n };\n } catch (error) {\n return this.#handleToolStrategyError(\n error as ToolStrategyError,\n response,\n toolCall,\n responseFormat\n );\n }\n }\n\n async #handleToolStrategyError(\n error: ToolStrategyError,\n response: AIMessage,\n toolCall: ToolCall,\n responseFormat: ToolResponseFormat\n ): Promise<Command> {\n /**\n * Using the `errorHandler` option of the first `ToolStrategy` entry is sufficient here.\n * There is technically only one `ToolStrategy` entry in `structuredToolInfo` if the user\n * uses `toolStrategy` to define the response format. If the user applies a list of json\n * schema objects, these will be transformed into multiple `ToolStrategy` entries but all\n * with the same `handleError` option.\n */\n const errorHandler = Object.values(responseFormat.tools).at(0)?.options\n ?.handleError;\n\n const toolCallId = toolCall.id;\n if (!toolCallId) {\n throw new Error(\n \"Tool call ID is required to handle tool output errors. Please provide a tool call ID.\"\n );\n }\n\n /**\n * Default behavior: retry if `errorHandler` is undefined or truthy.\n * Only throw if explicitly set to `false`.\n */\n if (errorHandler === false) {\n throw error;\n }\n\n /**\n * retry if:\n */\n if (\n /**\n * if the user has provided truthy value as the `errorHandler`, return a new AIMessage\n * with the error message and retry the tool call.\n */\n errorHandler === undefined ||\n (typeof errorHandler === \"boolean\" && errorHandler) ||\n /**\n * if `errorHandler` is an array and contains MultipleStructuredOutputsError\n */\n (Array.isArray(errorHandler) &&\n errorHandler.some((h) => h instanceof MultipleStructuredOutputsError))\n ) {\n return new Command({\n update: {\n messages: [\n response,\n new ToolMessage({\n content: error.message,\n tool_call_id: toolCallId,\n }),\n ],\n },\n goto: AGENT_NODE_NAME,\n });\n }\n\n /**\n * if `errorHandler` is a string, retry the tool call with given string\n */\n if (typeof errorHandler === \"string\") {\n return new Command({\n update: {\n messages: [\n response,\n new ToolMessage({\n content: errorHandler,\n tool_call_id: toolCallId,\n }),\n ],\n },\n goto: AGENT_NODE_NAME,\n });\n }\n\n /**\n * if `errorHandler` is a function, retry the tool call with the function\n */\n if (typeof errorHandler === \"function\") {\n const content = await errorHandler(error);\n if (typeof content !== \"string\") {\n throw new Error(\"Error handler must return a string.\");\n }\n\n return new Command({\n update: {\n messages: [\n response,\n new ToolMessage({\n content,\n tool_call_id: toolCallId,\n }),\n ],\n },\n goto: AGENT_NODE_NAME,\n });\n }\n\n /**\n * Default: retry if we reach here\n */\n return new Command({\n update: {\n messages: [\n response,\n new ToolMessage({\n content: error.message,\n tool_call_id: toolCallId,\n }),\n ],\n },\n goto: AGENT_NODE_NAME,\n });\n }\n\n #areMoreStepsNeeded(\n state: InternalAgentState<StructuredResponseFormat>,\n response: BaseMessage\n ): boolean {\n const allToolsReturnDirect =\n AIMessage.isInstance(response) &&\n response.tool_calls?.every((call) =>\n this.#options.shouldReturnDirect.has(call.name)\n );\n const remainingSteps =\n \"remainingSteps\" in state ? (state.remainingSteps as number) : undefined;\n return Boolean(\n remainingSteps &&\n ((remainingSteps < 1 && allToolsReturnDirect) ||\n (remainingSteps < 2 && hasToolCalls(state.messages.at(-1))))\n );\n }\n\n async #bindTools(\n model: LanguageModelLike,\n preparedOptions: ModelRequest | undefined,\n structuredResponseFormat: ResponseFormat | undefined\n ): Promise<Runnable> {\n const options: Partial<BaseChatModelCallOptions> = {};\n const structuredTools = Object.values(\n structuredResponseFormat && \"tools\" in structuredResponseFormat\n ? structuredResponseFormat.tools\n : {}\n );\n\n /**\n * Use tools from preparedOptions if provided, otherwise use default tools\n */\n const allTools = [\n ...(preparedOptions?.tools ?? this.#options.toolClasses),\n ...structuredTools.map((toolStrategy) => toolStrategy.tool),\n ];\n\n /**\n * If there are structured tools, we need to set the tool choice to \"any\"\n * so that the model can choose to use a structured tool or not.\n */\n const toolChoice =\n preparedOptions?.toolChoice ||\n (structuredTools.length > 0 ? \"any\" : undefined);\n\n /**\n * check if the user requests a native schema output\n */\n if (structuredResponseFormat?.type === \"native\") {\n const resolvedStrict =\n preparedOptions?.modelSettings?.strict ??\n structuredResponseFormat?.strategy?.strict ??\n true;\n\n const jsonSchemaParams = {\n name: structuredResponseFormat.strategy.schema?.name ?? \"extract\",\n description: getSchemaDescription(\n structuredResponseFormat.strategy.schema\n ),\n schema: structuredResponseFormat.strategy.schema,\n strict: resolvedStrict,\n };\n\n Object.assign(options, {\n /**\n * OpenAI-style options\n * Used by ChatOpenAI, ChatXAI, and other OpenAI-compatible providers.\n */\n response_format: {\n type: \"json_schema\",\n json_schema: jsonSchemaParams,\n },\n\n /**\n * Anthropic-style options\n */\n outputConfig: {\n format: {\n type: \"json_schema\",\n schema: structuredResponseFormat.strategy.schema,\n },\n },\n\n /**\n * Google-style options\n * Used by ChatGoogle and other Gemini-based providers.\n */\n responseSchema: structuredResponseFormat.strategy.schema,\n\n /**\n * for LangSmith structured output tracing\n */\n ls_structured_output_format: {\n kwargs: { method: \"json_schema\" },\n schema: structuredResponseFormat.strategy.schema,\n },\n strict: resolvedStrict,\n });\n }\n\n /**\n * Bind tools to the model if they are not already bound.\n */\n const modelWithTools = await bindTools(model, allTools, {\n ...options,\n ...preparedOptions?.modelSettings,\n tool_choice: toolChoice,\n });\n\n /**\n * Create a model runnable with the prompt and agent name\n * Use current SystemMessage state (which may have been modified by middleware)\n */\n const modelRunnable =\n this.#options.includeAgentName === \"inline\"\n ? withAgentName(modelWithTools, this.#options.includeAgentName)\n : modelWithTools;\n\n return modelRunnable;\n }\n\n /**\n * Returns internal bookkeeping state for StateManager, not graph output.\n * The return shape differs from the node's output type (Command).\n */\n // @ts-expect-error Internal state shape differs from graph output type\n getState(): { messages: BaseMessage[] } {\n const state = super.getState();\n const origState = state && !isCommand(state) ? state : {};\n\n return {\n messages: [],\n ...origState,\n };\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { initChatModel } from "../../chat_models/universal.js";
2
+ import { isConfigurableModel } from "../model.js";
2
3
  import { MiddlewareError, MultipleStructuredOutputsError } from "../errors.js";
3
4
  import { bindTools, hasToolCalls, isClientTool, validateLLMHasNoBoundTools } from "../utils.js";
4
5
  import { RunnableCallable } from "../RunnableCallable.js";
@@ -45,9 +46,12 @@ var AgentNode = class extends RunnableCallable {
45
46
  * @param model - The model to get the response format for.
46
47
  * @returns The response format.
47
48
  */
48
- #getResponseFormat(model) {
49
+ async #getResponseFormat(model) {
49
50
  if (!this.#options.responseFormat) return;
50
- const strategies = transformResponseFormat(this.#options.responseFormat, void 0, model);
51
+ let resolvedModel;
52
+ if (isConfigurableModel(model)) resolvedModel = await model._getModelInstance();
53
+ else if (typeof model !== "string") resolvedModel = model;
54
+ const strategies = transformResponseFormat(this.#options.responseFormat, void 0, resolvedModel);
51
55
  /**
52
56
  * Populate a list of structured tool info.
53
57
  */
@@ -133,7 +137,7 @@ var AgentNode = class extends RunnableCallable {
133
137
  * Check if the LLM already has bound tools and throw if it does.
134
138
  */
135
139
  validateLLMHasNoBoundTools(request.model);
136
- const structuredResponseFormat = this.#getResponseFormat(request.model);
140
+ const structuredResponseFormat = await this.#getResponseFormat(request.model);
137
141
  const modelWithTools = await this.#bindTools(request.model, request, structuredResponseFormat);
138
142
  /**
139
143
  * prepend the system message to the messages if it is not empty
@@ -452,6 +456,7 @@ var AgentNode = class extends RunnableCallable {
452
456
  type: "json_schema",
453
457
  schema: structuredResponseFormat.strategy.schema
454
458
  } },
459
+ responseSchema: structuredResponseFormat.strategy.schema,
455
460
  ls_structured_output_format: {
456
461
  kwargs: { method: "json_schema" },
457
462
  schema: structuredResponseFormat.strategy.schema