langchain 1.2.13 → 1.2.15

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":"AgentNode.js","names":["response: unknown","options: AgentNodeOptions<StructuredResponseFormat, ContextSchema>","#run","#options","#systemMessage","model: string | LanguageModelLike","state: InternalAgentState<StructuredResponseFormat>","config: RunnableConfig","#invokeModel","#areMoreStepsNeeded","options: {\n lastMessage?: string;\n }","#deriveModel","request: ModelRequest","#getResponseFormat","#bindTools","#currentSystemMessage","#handleMultipleStructuredOutputs","#handleSingleStructuredOutput","wrappedHandler: (\n request: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >\n ) => Promise<InternalModelResponse<StructuredResponseFormat>>","request: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >","runtime: Runtime<unknown>","requestWithStateAndRuntime: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >","req: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >","initialRequest: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >","response: AIMessage","toolCalls: ToolCall[]","responseFormat: ToolResponseFormat","#handleToolStrategyError","toolCall: ToolCall","lastMessage?: string","error: ToolStrategyError","response: BaseMessage","model: LanguageModelLike","preparedOptions: ModelRequest | undefined","structuredResponseFormat: ResponseFormat | undefined","options: Partial<BaseChatModelCallOptions>"],"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 { Command, type LangGraphRunnableConfig } 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 interopZodObjectPartial,\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 } 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\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 (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\n | AnyAnnotationRoot\n | InteropZodObject = 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\n | AnyAnnotationRoot\n | InteropZodObject = AnyAnnotationRoot,\n> extends RunnableCallable<\n InternalAgentState<StructuredResponseFormat>,\n | (\n | { messages: BaseMessage[] }\n | { structuredResponse: StructuredResponseFormat }\n )\n | Command\n> {\n #options: AgentNodeOptions<StructuredResponseFormat, ContextSchema>;\n #systemMessage: SystemMessage;\n #currentSystemMessage: 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 /**\n * return directly without invoking the model again\n */\n return { messages: [] };\n }\n\n const response = await this.#invokeModel(state, config);\n\n /**\n * if we were able to generate a structured response, return it\n */\n if (\"structuredResponse\" in response) {\n return {\n messages: [...state.messages, ...(response.messages || [])],\n structuredResponse: response.structuredResponse,\n };\n }\n\n /**\n * if we need to direct the agent to the model, return the update\n */\n if (response instanceof Command) {\n return response;\n }\n\n response.name = this.name;\n response.lc_kwargs.name = this.name;\n\n if (this.#areMoreStepsNeeded(state, response)) {\n return {\n messages: [\n new AIMessage({\n content: \"Sorry, need more steps to process this request.\",\n name: this.name,\n id: response.id,\n }),\n ],\n };\n }\n\n return { messages: [response] };\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<AIMessage | ResponseHandlerResult<StructuredResponseFormat>> {\n const model = await this.#deriveModel();\n const lgConfig = config as LangGraphRunnableConfig;\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 ...(this.#currentSystemMessage.text === \"\"\n ? []\n : [this.#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 /**\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 /**\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 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 interopZodObjectPartial(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 /**\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 !== this.#currentSystemMessage.text;\n const hasSystemMessageChanged =\n req.systemMessage !== this.#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 this.#currentSystemMessage = new SystemMessage({\n content: [{ type: \"text\", text: req.systemPrompt }],\n });\n normalizedReq = {\n ...req,\n systemPrompt: this.#currentSystemMessage.text,\n systemMessage: this.#currentSystemMessage,\n };\n }\n /**\n * If the systemMessage was changed, update the current system message\n */\n if (hasSystemMessageChanged) {\n this.#currentSystemMessage = new SystemMessage({\n ...req.systemMessage,\n });\n normalizedReq = {\n ...req,\n systemPrompt: this.#currentSystemMessage.text,\n systemMessage: this.#currentSystemMessage,\n };\n }\n\n return innerHandler(normalizedReq);\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 AIMessage\n */\n if (!isInternalModelResponse(middlewareResponse)) {\n throw new Error(\n `Invalid response from \"wrapModelCall\" in middleware \"${\n currentMiddleware.name\n }\": expected AIMessage, got ${typeof middlewareResponse}`\n );\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 this.#currentSystemMessage = this.#systemMessage;\n const initialRequest: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n > = {\n model,\n systemPrompt: this.#currentSystemMessage?.text,\n systemMessage: this.#currentSystemMessage,\n messages: state.messages,\n tools: this.#options.toolClasses,\n state,\n runtime: Object.freeze({\n context: lgConfig?.context,\n writer: lgConfig.writer,\n interrupt: lgConfig.interrupt,\n signal: lgConfig.signal,\n }) as Runtime<unknown>,\n };\n\n return wrappedHandler(initialRequest);\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 response_format: {\n type: \"json_schema\",\n json_schema: jsonSchemaParams,\n },\n output_format: {\n type: \"json_schema\",\n schema: structuredResponseFormat.strategy.schema,\n },\n headers: {\n \"anthropic-beta\": \"structured-outputs-2025-11-13\",\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 getState(): {\n messages: BaseMessage[];\n } {\n const state = super.getState();\n const origState = state && !(state instanceof Command) ? state : {};\n\n return {\n messages: [],\n ...origState,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AgentNode.js","names":["response: unknown","options: AgentNodeOptions<StructuredResponseFormat, ContextSchema>","#run","#options","#systemMessage","model: string | LanguageModelLike","state: InternalAgentState<StructuredResponseFormat>","config: RunnableConfig","#invokeModel","#areMoreStepsNeeded","options: {\n lastMessage?: string;\n }","#deriveModel","request: ModelRequest","#getResponseFormat","#bindTools","#currentSystemMessage","#handleMultipleStructuredOutputs","#handleSingleStructuredOutput","wrappedHandler: (\n request: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >\n ) => Promise<InternalModelResponse<StructuredResponseFormat>>","request: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >","runtime: Runtime<unknown>","requestWithStateAndRuntime: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >","req: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >","initialRequest: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n >","response: AIMessage","toolCalls: ToolCall[]","responseFormat: ToolResponseFormat","#handleToolStrategyError","toolCall: ToolCall","lastMessage?: string","error: ToolStrategyError","response: BaseMessage","model: LanguageModelLike","preparedOptions: ModelRequest | undefined","structuredResponseFormat: ResponseFormat | undefined","options: Partial<BaseChatModelCallOptions>"],"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 { Command, type LangGraphRunnableConfig } 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\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 (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\n | AnyAnnotationRoot\n | InteropZodObject = 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\n | AnyAnnotationRoot\n | InteropZodObject = AnyAnnotationRoot,\n> extends RunnableCallable<\n InternalAgentState<StructuredResponseFormat>,\n | (\n | { messages: BaseMessage[] }\n | { structuredResponse: StructuredResponseFormat }\n )\n | Command\n> {\n #options: AgentNodeOptions<StructuredResponseFormat, ContextSchema>;\n #systemMessage: SystemMessage;\n #currentSystemMessage: 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 /**\n * return directly without invoking the model again\n */\n return { messages: [] };\n }\n\n const response = await this.#invokeModel(state, config);\n\n /**\n * if we were able to generate a structured response, return it\n */\n if (\"structuredResponse\" in response) {\n return {\n messages: [...state.messages, ...(response.messages || [])],\n structuredResponse: response.structuredResponse,\n };\n }\n\n /**\n * if we need to direct the agent to the model, return the update\n */\n if (response instanceof Command) {\n return response;\n }\n\n response.name = this.name;\n response.lc_kwargs.name = this.name;\n\n if (this.#areMoreStepsNeeded(state, response)) {\n return {\n messages: [\n new AIMessage({\n content: \"Sorry, need more steps to process this request.\",\n name: this.name,\n id: response.id,\n }),\n ],\n };\n }\n\n return { messages: [response] };\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<AIMessage | ResponseHandlerResult<StructuredResponseFormat>> {\n const model = await this.#deriveModel();\n const lgConfig = config as LangGraphRunnableConfig;\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 ...(this.#currentSystemMessage.text === \"\"\n ? []\n : [this.#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 /**\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 /**\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 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 /**\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 !== this.#currentSystemMessage.text;\n const hasSystemMessageChanged =\n req.systemMessage !== this.#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 this.#currentSystemMessage = new SystemMessage({\n content: [{ type: \"text\", text: req.systemPrompt }],\n });\n normalizedReq = {\n ...req,\n systemPrompt: this.#currentSystemMessage.text,\n systemMessage: this.#currentSystemMessage,\n };\n }\n /**\n * If the systemMessage was changed, update the current system message\n */\n if (hasSystemMessageChanged) {\n this.#currentSystemMessage = new SystemMessage({\n ...req.systemMessage,\n });\n normalizedReq = {\n ...req,\n systemPrompt: this.#currentSystemMessage.text,\n systemMessage: this.#currentSystemMessage,\n };\n }\n\n return innerHandler(normalizedReq);\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 AIMessage\n */\n if (!isInternalModelResponse(middlewareResponse)) {\n throw new Error(\n `Invalid response from \"wrapModelCall\" in middleware \"${\n currentMiddleware.name\n }\": expected AIMessage, got ${typeof middlewareResponse}`\n );\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 this.#currentSystemMessage = this.#systemMessage;\n const initialRequest: ModelRequest<\n InternalAgentState<StructuredResponseFormat>,\n unknown\n > = {\n model,\n systemPrompt: this.#currentSystemMessage?.text,\n systemMessage: this.#currentSystemMessage,\n messages: state.messages,\n tools: this.#options.toolClasses,\n state,\n runtime: Object.freeze({\n context: lgConfig?.context,\n writer: lgConfig.writer,\n interrupt: lgConfig.interrupt,\n signal: lgConfig.signal,\n }) as Runtime<unknown>,\n };\n\n return wrappedHandler(initialRequest);\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 response_format: {\n type: \"json_schema\",\n json_schema: jsonSchemaParams,\n },\n output_format: {\n type: \"json_schema\",\n schema: structuredResponseFormat.strategy.schema,\n },\n headers: {\n \"anthropic-beta\": \"structured-outputs-2025-11-13\",\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 getState(): {\n messages: BaseMessage[];\n } {\n const state = super.getState();\n const origState = state && !(state instanceof Command) ? state : {};\n\n return {\n messages: [],\n ...origState,\n };\n }\n}\n"],"mappings":"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"}
@@ -63,6 +63,27 @@ function derivePrivateState(stateSchema) {
63
63
  else privateShape[key] = value;
64
64
  return zod_v4.z.object(privateShape);
65
65
  }
66
+ /**
67
+ * Converts any supported schema type (ZodObject, StateSchema, AnnotationRoot) to a partial Zod object.
68
+ * This is useful for parsing state loosely where all fields are optional.
69
+ *
70
+ * @param schema - The schema to convert (InteropZodObject, StateSchema, or AnnotationRoot)
71
+ * @returns A partial Zod object schema where all fields are optional
72
+ */
73
+ function toPartialZodObject(schema) {
74
+ if ((0, __langchain_core_utils_types.isInteropZodObject)(schema)) return (0, __langchain_core_utils_types.interopZodObjectPartial)(schema);
75
+ if (__langchain_langgraph.StateSchema.isInstance(schema)) {
76
+ const partialShape = {};
77
+ for (const [key, field] of Object.entries(schema.fields)) {
78
+ let fieldSchema;
79
+ if (__langchain_langgraph.ReducedValue.isInstance(field)) fieldSchema = field.inputSchema || field.valueSchema;
80
+ else fieldSchema = field;
81
+ partialShape[key] = (0, __langchain_core_utils_types.isZodSchemaV4)(fieldSchema) ? fieldSchema.optional() : zod_v4.z.any().optional();
82
+ }
83
+ return zod_v4.z.object(partialShape);
84
+ }
85
+ return zod_v4.z.object({});
86
+ }
66
87
  function parseJumpToTarget(target) {
67
88
  if (!target) return void 0;
68
89
  /**
@@ -95,4 +116,5 @@ exports.derivePrivateState = derivePrivateState;
95
116
  exports.initializeMiddlewareStates = initializeMiddlewareStates;
96
117
  exports.mergeAbortSignals = mergeAbortSignals;
97
118
  exports.parseJumpToTarget = parseJumpToTarget;
119
+ exports.toPartialZodObject = toPartialZodObject;
98
120
  //# sourceMappingURL=utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","names":["middlewareList: readonly AgentMiddleware[]","state: unknown","middlewareStates: Record<string, any>","StateSchema","zodShape: Record<string, any>","ReducedValue","z","stateSchema?: z.ZodObject<z.ZodRawShape> | StateSchema<any>","shape: Record<string, any>","privateShape: Record<string, any>","target?: string","END"],"sources":["../../../src/agents/nodes/utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport {\n interopSafeParseAsync,\n interopZodObjectMakeFieldsOptional,\n} from \"@langchain/core/utils/types\";\nimport { END, StateSchema, ReducedValue } from \"@langchain/langgraph\";\n\nimport type { JumpTo } from \"../types.js\";\nimport type { AgentMiddleware } from \"../middleware/types.js\";\n\n/**\n * Helper function to initialize middleware state defaults.\n * This is used to ensure all middleware state properties are initialized.\n *\n * Private properties (starting with _) are automatically made optional since\n * users cannot provide them when invoking the agent.\n */\nexport async function initializeMiddlewareStates(\n middlewareList: readonly AgentMiddleware[],\n state: unknown\n): Promise<Record<string, any>> {\n const middlewareStates: Record<string, any> = {};\n\n for (const middleware of middlewareList) {\n /**\n * skip middleware if it doesn't have a state schema\n */\n if (!middleware.stateSchema) {\n continue;\n }\n\n // Convert StateSchema to Zod object if needed\n let zodSchema = middleware.stateSchema;\n if (StateSchema.isInstance(middleware.stateSchema)) {\n const zodShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(\n middleware.stateSchema.fields\n )) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n zodShape[key] = field.inputSchema || field.valueSchema;\n } else {\n zodShape[key] = field;\n }\n }\n zodSchema = z.object(zodShape);\n }\n\n // Create a modified schema where private properties are optional\n const modifiedSchema = interopZodObjectMakeFieldsOptional(\n zodSchema,\n (key) => key.startsWith(\"_\")\n );\n\n // Use safeParse with the modified schema\n const parseResult = await interopSafeParseAsync(modifiedSchema, state);\n if (parseResult.success) {\n Object.assign(middlewareStates, parseResult.data);\n continue;\n }\n\n /**\n * If safeParse fails, there are required public fields missing.\n * Note: Zod v3 uses message \"Required\", Zod v4 uses \"Invalid input: expected X, received undefined\"\n */\n const requiredFields = parseResult.error.issues\n .filter((issue) => issue.code === \"invalid_type\")\n .map((issue) => ` - ${issue.path.join(\".\")}: Required`)\n .join(\"\\n\");\n\n throw new Error(\n `Middleware \"${middleware.name}\" has required state fields that must be initialized:\\n` +\n `${requiredFields}\\n\\n` +\n `To fix this, either:\\n` +\n `1. Provide default values in your middleware's state schema using .default():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().default(\"default value\")\\n` +\n ` })\\n\\n` +\n `2. Or make the fields optional using .optional():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().optional()\\n` +\n ` })\\n\\n` +\n `3. Or ensure you pass these values when invoking the agent:\\n` +\n ` agent.invoke({\\n` +\n ` messages: [...],\\n` +\n ` ${parseResult.error.issues[0]?.path.join(\".\")}: \"value\"\\n` +\n ` })`\n );\n }\n\n return middlewareStates;\n}\n\n/**\n * Users can define private and public state for a middleware. Private state properties start with an underscore.\n * This function will return the private state properties from the state schema, making all of them optional.\n * @param stateSchema - The middleware state schema\n * @returns A new schema containing only the private properties (underscore-prefixed), all made optional\n */\nexport function derivePrivateState(\n stateSchema?: z.ZodObject<z.ZodRawShape> | StateSchema<any>\n): z.ZodObject<z.ZodRawShape> {\n const builtInStateSchema = {\n messages: z.custom<BaseMessage[]>(() => []),\n // Include optional structuredResponse so after_agent hooks can access/modify it\n structuredResponse: z.any().optional(),\n };\n\n if (!stateSchema) {\n return z.object(builtInStateSchema);\n }\n\n // Extract shape from either StateSchema or Zod object\n let shape: Record<string, any>;\n if (StateSchema.isInstance(stateSchema)) {\n // For StateSchema, extract Zod schemas from fields\n shape = {};\n for (const [key, field] of Object.entries(stateSchema.fields)) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n shape[key] = field.inputSchema || field.valueSchema;\n } else {\n shape[key] = field;\n }\n }\n } else {\n shape = stateSchema.shape;\n }\n\n const privateShape: Record<string, any> = { ...builtInStateSchema };\n\n // Filter properties that start with underscore and make them optional\n for (const [key, value] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) {\n // Make the private property optional\n privateShape[key] = value.optional();\n } else {\n privateShape[key] = value;\n }\n }\n\n // Return a new schema with only private properties (all optional)\n return z.object(privateShape);\n}\n\n/**\n * Parse `jumpTo` target from user facing labels to a LangGraph node names\n */\nexport function parseJumpToTarget(target: string): JumpTo;\nexport function parseJumpToTarget(target?: string): JumpTo | undefined {\n if (!target) {\n return undefined;\n }\n\n /**\n * if target is already a valid jump target, return it\n */\n if ([\"model_request\", \"tools\", END].includes(target)) {\n return target as JumpTo;\n }\n\n if (target === \"model\") {\n return \"model_request\";\n }\n if (target === \"tools\") {\n return \"tools\";\n }\n if (target === \"end\") {\n return END;\n }\n\n throw new Error(\n `Invalid jump target: ${target}, must be \"model\", \"tools\" or \"end\".`\n );\n}\n\n/**\n * TypeScript currently doesn't support types for `AbortSignal.any`\n * @see https://github.com/microsoft/TypeScript/issues/60695\n */\ndeclare const AbortSignal: {\n any(signals: AbortSignal[]): AbortSignal;\n};\n\n/**\n * `config` always contains a signal from LangGraphs Pregel class.\n * To ensure we acknowledge the abort signal from the user, we merge it\n * with the signal from the ToolNode.\n *\n * @param signals - The signals to merge.\n * @returns The merged signal.\n */\nexport function mergeAbortSignals(\n ...signals: (AbortSignal | undefined)[]\n): AbortSignal {\n return AbortSignal.any(\n signals.filter(\n (maybeSignal): maybeSignal is AbortSignal =>\n maybeSignal !== null &&\n maybeSignal !== undefined &&\n typeof maybeSignal === \"object\" &&\n \"aborted\" in maybeSignal &&\n typeof maybeSignal.aborted === \"boolean\"\n )\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAmBA,eAAsB,2BACpBA,gBACAC,OAC8B;CAC9B,MAAMC,mBAAwC,CAAE;AAEhD,MAAK,MAAM,cAAc,gBAAgB;;;;AAIvC,MAAI,CAAC,WAAW,YACd;EAIF,IAAI,YAAY,WAAW;AAC3B,MAAIC,kCAAY,WAAW,WAAW,YAAY,EAAE;GAClD,MAAMC,WAAgC,CAAE;AACxC,QAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAChC,WAAW,YAAY,OACxB,CACC,KAAIC,mCAAa,WAAW,MAAM,EAEhC,SAAS,OAAO,MAAM,eAAe,MAAM;QAE3C,SAAS,OAAO;GAGpB,YAAYC,SAAE,OAAO,SAAS;EAC/B;EAGD,MAAM,sFACJ,WACA,CAAC,QAAQ,IAAI,WAAW,IAAI,CAC7B;EAGD,MAAM,cAAc,8DAA4B,gBAAgB,MAAM;AACtE,MAAI,YAAY,SAAS;GACvB,OAAO,OAAO,kBAAkB,YAAY,KAAK;AACjD;EACD;;;;;EAMD,MAAM,iBAAiB,YAAY,MAAM,OACtC,OAAO,CAAC,UAAU,MAAM,SAAS,eAAe,CAChD,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC,CACvD,KAAK,KAAK;AAEb,QAAM,IAAI,MACR,CAAC,YAAY,EAAE,WAAW,KAAK,uDAAuD,EACjF,eAAe,0aAAI,EAad,YAAY,MAAM,OAAO,IAAI,KAAK,KAAK,IAAI,CAAC,gBAAW,CACxD;CAEZ;AAED,QAAO;AACR;;;;;;;AAQD,SAAgB,mBACdC,aAC4B;CAC5B,MAAM,qBAAqB;EACzB,UAAUD,SAAE,OAAsB,MAAM,CAAE,EAAC;EAE3C,oBAAoBA,SAAE,KAAK,CAAC,UAAU;CACvC;AAED,KAAI,CAAC,YACH,QAAOA,SAAE,OAAO,mBAAmB;CAIrC,IAAIE;AACJ,KAAIL,kCAAY,WAAW,YAAY,EAAE;EAEvC,QAAQ,CAAE;AACV,OAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,YAAY,OAAO,CAC3D,KAAIE,mCAAa,WAAW,MAAM,EAEhC,MAAM,OAAO,MAAM,eAAe,MAAM;OAExC,MAAM,OAAO;CAGlB,OACC,QAAQ,YAAY;CAGtB,MAAMI,eAAoC,EAAE,GAAG,mBAAoB;AAGnE,MAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,MAAM,CAC9C,KAAI,IAAI,WAAW,IAAI,EAErB,aAAa,OAAO,MAAM,UAAU;MAEpC,aAAa,OAAO;AAKxB,QAAOH,SAAE,OAAO,aAAa;AAC9B;AAMD,SAAgB,kBAAkBI,QAAqC;AACrE,KAAI,CAAC,OACH,QAAO;;;;AAMT,KAAI;EAAC;EAAiB;EAASC;CAAI,EAAC,SAAS,OAAO,CAClD,QAAO;AAGT,KAAI,WAAW,QACb,QAAO;AAET,KAAI,WAAW,QACb,QAAO;AAET,KAAI,WAAW,MACb,QAAOA;AAGT,OAAM,IAAI,MACR,CAAC,qBAAqB,EAAE,OAAO,oCAAoC,CAAC;AAEvE;;;;;;;;;AAkBD,SAAgB,kBACd,GAAG,SACU;AACb,QAAO,YAAY,IACjB,QAAQ,OACN,CAAC,gBACC,gBAAgB,QAChB,gBAAgB,UAChB,OAAO,gBAAgB,YACvB,aAAa,eACb,OAAO,YAAY,YAAY,UAClC,CACF;AACF"}
1
+ {"version":3,"file":"utils.cjs","names":["middlewareList: readonly AgentMiddleware[]","state: unknown","middlewareStates: Record<string, any>","StateSchema","zodShape: Record<string, any>","ReducedValue","z","stateSchema?: z.ZodObject<z.ZodRawShape> | StateSchema<any>","shape: Record<string, any>","privateShape: Record<string, any>","schema: StateDefinitionInit","partialShape: Record<string, any>","fieldSchema: unknown","target?: string","END"],"sources":["../../../src/agents/nodes/utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport {\n interopSafeParseAsync,\n interopZodObjectMakeFieldsOptional,\n interopZodObjectPartial,\n isInteropZodObject,\n isZodSchemaV4,\n type InteropZodObject,\n} from \"@langchain/core/utils/types\";\nimport type { StateDefinitionInit } from \"@langchain/langgraph\";\nimport { END, StateSchema, ReducedValue } from \"@langchain/langgraph\";\n\nimport type { JumpTo } from \"../types.js\";\nimport type { AgentMiddleware } from \"../middleware/types.js\";\n\n/**\n * Helper function to initialize middleware state defaults.\n * This is used to ensure all middleware state properties are initialized.\n *\n * Private properties (starting with _) are automatically made optional since\n * users cannot provide them when invoking the agent.\n */\nexport async function initializeMiddlewareStates(\n middlewareList: readonly AgentMiddleware[],\n state: unknown\n): Promise<Record<string, any>> {\n const middlewareStates: Record<string, any> = {};\n\n for (const middleware of middlewareList) {\n /**\n * skip middleware if it doesn't have a state schema\n */\n if (!middleware.stateSchema) {\n continue;\n }\n\n // Convert StateSchema to Zod object if needed\n let zodSchema = middleware.stateSchema;\n if (StateSchema.isInstance(middleware.stateSchema)) {\n const zodShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(\n middleware.stateSchema.fields\n )) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n zodShape[key] = field.inputSchema || field.valueSchema;\n } else {\n zodShape[key] = field;\n }\n }\n zodSchema = z.object(zodShape);\n }\n\n // Create a modified schema where private properties are optional\n const modifiedSchema = interopZodObjectMakeFieldsOptional(\n zodSchema,\n (key) => key.startsWith(\"_\")\n );\n\n // Use safeParse with the modified schema\n const parseResult = await interopSafeParseAsync(modifiedSchema, state);\n if (parseResult.success) {\n Object.assign(middlewareStates, parseResult.data);\n continue;\n }\n\n /**\n * If safeParse fails, there are required public fields missing.\n * Note: Zod v3 uses message \"Required\", Zod v4 uses \"Invalid input: expected X, received undefined\"\n */\n const requiredFields = parseResult.error.issues\n .filter((issue) => issue.code === \"invalid_type\")\n .map((issue) => ` - ${issue.path.join(\".\")}: Required`)\n .join(\"\\n\");\n\n throw new Error(\n `Middleware \"${middleware.name}\" has required state fields that must be initialized:\\n` +\n `${requiredFields}\\n\\n` +\n `To fix this, either:\\n` +\n `1. Provide default values in your middleware's state schema using .default():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().default(\"default value\")\\n` +\n ` })\\n\\n` +\n `2. Or make the fields optional using .optional():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().optional()\\n` +\n ` })\\n\\n` +\n `3. Or ensure you pass these values when invoking the agent:\\n` +\n ` agent.invoke({\\n` +\n ` messages: [...],\\n` +\n ` ${parseResult.error.issues[0]?.path.join(\".\")}: \"value\"\\n` +\n ` })`\n );\n }\n\n return middlewareStates;\n}\n\n/**\n * Users can define private and public state for a middleware. Private state properties start with an underscore.\n * This function will return the private state properties from the state schema, making all of them optional.\n * @param stateSchema - The middleware state schema\n * @returns A new schema containing only the private properties (underscore-prefixed), all made optional\n */\nexport function derivePrivateState(\n stateSchema?: z.ZodObject<z.ZodRawShape> | StateSchema<any>\n): z.ZodObject<z.ZodRawShape> {\n const builtInStateSchema = {\n messages: z.custom<BaseMessage[]>(() => []),\n // Include optional structuredResponse so after_agent hooks can access/modify it\n structuredResponse: z.any().optional(),\n };\n\n if (!stateSchema) {\n return z.object(builtInStateSchema);\n }\n\n // Extract shape from either StateSchema or Zod object\n let shape: Record<string, any>;\n if (StateSchema.isInstance(stateSchema)) {\n // For StateSchema, extract Zod schemas from fields\n shape = {};\n for (const [key, field] of Object.entries(stateSchema.fields)) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n shape[key] = field.inputSchema || field.valueSchema;\n } else {\n shape[key] = field;\n }\n }\n } else {\n shape = stateSchema.shape;\n }\n\n const privateShape: Record<string, any> = { ...builtInStateSchema };\n\n // Filter properties that start with underscore and make them optional\n for (const [key, value] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) {\n // Make the private property optional\n privateShape[key] = value.optional();\n } else {\n privateShape[key] = value;\n }\n }\n\n // Return a new schema with only private properties (all optional)\n return z.object(privateShape);\n}\n\n/**\n * Converts any supported schema type (ZodObject, StateSchema, AnnotationRoot) to a partial Zod object.\n * This is useful for parsing state loosely where all fields are optional.\n *\n * @param schema - The schema to convert (InteropZodObject, StateSchema, or AnnotationRoot)\n * @returns A partial Zod object schema where all fields are optional\n */\nexport function toPartialZodObject(\n schema: StateDefinitionInit\n): InteropZodObject {\n // Handle ZodObject directly\n if (isInteropZodObject(schema)) {\n return interopZodObjectPartial(schema);\n }\n\n // Handle StateSchema: convert fields to Zod shape, then make partial\n if (StateSchema.isInstance(schema)) {\n const partialShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(schema.fields)) {\n let fieldSchema: unknown;\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n fieldSchema = field.inputSchema || field.valueSchema;\n } else {\n fieldSchema = field;\n }\n // Only call .optional() on Zod v4 schemas, otherwise use z.any()\n partialShape[key] = isZodSchemaV4(fieldSchema)\n ? (fieldSchema as any).optional()\n : z.any().optional();\n }\n return z.object(partialShape);\n }\n\n // Fallback: return empty object schema\n return z.object({});\n}\n\n/**\n * Parse `jumpTo` target from user facing labels to a LangGraph node names\n */\nexport function parseJumpToTarget(target: string): JumpTo;\nexport function parseJumpToTarget(target?: string): JumpTo | undefined {\n if (!target) {\n return undefined;\n }\n\n /**\n * if target is already a valid jump target, return it\n */\n if ([\"model_request\", \"tools\", END].includes(target)) {\n return target as JumpTo;\n }\n\n if (target === \"model\") {\n return \"model_request\";\n }\n if (target === \"tools\") {\n return \"tools\";\n }\n if (target === \"end\") {\n return END;\n }\n\n throw new Error(\n `Invalid jump target: ${target}, must be \"model\", \"tools\" or \"end\".`\n );\n}\n\n/**\n * TypeScript currently doesn't support types for `AbortSignal.any`\n * @see https://github.com/microsoft/TypeScript/issues/60695\n */\ndeclare const AbortSignal: {\n any(signals: AbortSignal[]): AbortSignal;\n};\n\n/**\n * `config` always contains a signal from LangGraphs Pregel class.\n * To ensure we acknowledge the abort signal from the user, we merge it\n * with the signal from the ToolNode.\n *\n * @param signals - The signals to merge.\n * @returns The merged signal.\n */\nexport function mergeAbortSignals(\n ...signals: (AbortSignal | undefined)[]\n): AbortSignal {\n return AbortSignal.any(\n signals.filter(\n (maybeSignal): maybeSignal is AbortSignal =>\n maybeSignal !== null &&\n maybeSignal !== undefined &&\n typeof maybeSignal === \"object\" &&\n \"aborted\" in maybeSignal &&\n typeof maybeSignal.aborted === \"boolean\"\n )\n );\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { END, ReducedValue, StateSchema } from "@langchain/langgraph";
2
- import { interopSafeParseAsync, interopZodObjectMakeFieldsOptional } from "@langchain/core/utils/types";
2
+ import { interopSafeParseAsync, interopZodObjectMakeFieldsOptional, interopZodObjectPartial, isInteropZodObject, isZodSchemaV4 } from "@langchain/core/utils/types";
3
3
  import { z } from "zod/v4";
4
4
 
5
5
  //#region src/agents/nodes/utils.ts
@@ -62,6 +62,27 @@ function derivePrivateState(stateSchema) {
62
62
  else privateShape[key] = value;
63
63
  return z.object(privateShape);
64
64
  }
65
+ /**
66
+ * Converts any supported schema type (ZodObject, StateSchema, AnnotationRoot) to a partial Zod object.
67
+ * This is useful for parsing state loosely where all fields are optional.
68
+ *
69
+ * @param schema - The schema to convert (InteropZodObject, StateSchema, or AnnotationRoot)
70
+ * @returns A partial Zod object schema where all fields are optional
71
+ */
72
+ function toPartialZodObject(schema) {
73
+ if (isInteropZodObject(schema)) return interopZodObjectPartial(schema);
74
+ if (StateSchema.isInstance(schema)) {
75
+ const partialShape = {};
76
+ for (const [key, field] of Object.entries(schema.fields)) {
77
+ let fieldSchema;
78
+ if (ReducedValue.isInstance(field)) fieldSchema = field.inputSchema || field.valueSchema;
79
+ else fieldSchema = field;
80
+ partialShape[key] = isZodSchemaV4(fieldSchema) ? fieldSchema.optional() : z.any().optional();
81
+ }
82
+ return z.object(partialShape);
83
+ }
84
+ return z.object({});
85
+ }
65
86
  function parseJumpToTarget(target) {
66
87
  if (!target) return void 0;
67
88
  /**
@@ -90,5 +111,5 @@ function mergeAbortSignals(...signals) {
90
111
  }
91
112
 
92
113
  //#endregion
93
- export { derivePrivateState, initializeMiddlewareStates, mergeAbortSignals, parseJumpToTarget };
114
+ export { derivePrivateState, initializeMiddlewareStates, mergeAbortSignals, parseJumpToTarget, toPartialZodObject };
94
115
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["middlewareList: readonly AgentMiddleware[]","state: unknown","middlewareStates: Record<string, any>","zodShape: Record<string, any>","stateSchema?: z.ZodObject<z.ZodRawShape> | StateSchema<any>","shape: Record<string, any>","privateShape: Record<string, any>","target?: string"],"sources":["../../../src/agents/nodes/utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport {\n interopSafeParseAsync,\n interopZodObjectMakeFieldsOptional,\n} from \"@langchain/core/utils/types\";\nimport { END, StateSchema, ReducedValue } from \"@langchain/langgraph\";\n\nimport type { JumpTo } from \"../types.js\";\nimport type { AgentMiddleware } from \"../middleware/types.js\";\n\n/**\n * Helper function to initialize middleware state defaults.\n * This is used to ensure all middleware state properties are initialized.\n *\n * Private properties (starting with _) are automatically made optional since\n * users cannot provide them when invoking the agent.\n */\nexport async function initializeMiddlewareStates(\n middlewareList: readonly AgentMiddleware[],\n state: unknown\n): Promise<Record<string, any>> {\n const middlewareStates: Record<string, any> = {};\n\n for (const middleware of middlewareList) {\n /**\n * skip middleware if it doesn't have a state schema\n */\n if (!middleware.stateSchema) {\n continue;\n }\n\n // Convert StateSchema to Zod object if needed\n let zodSchema = middleware.stateSchema;\n if (StateSchema.isInstance(middleware.stateSchema)) {\n const zodShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(\n middleware.stateSchema.fields\n )) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n zodShape[key] = field.inputSchema || field.valueSchema;\n } else {\n zodShape[key] = field;\n }\n }\n zodSchema = z.object(zodShape);\n }\n\n // Create a modified schema where private properties are optional\n const modifiedSchema = interopZodObjectMakeFieldsOptional(\n zodSchema,\n (key) => key.startsWith(\"_\")\n );\n\n // Use safeParse with the modified schema\n const parseResult = await interopSafeParseAsync(modifiedSchema, state);\n if (parseResult.success) {\n Object.assign(middlewareStates, parseResult.data);\n continue;\n }\n\n /**\n * If safeParse fails, there are required public fields missing.\n * Note: Zod v3 uses message \"Required\", Zod v4 uses \"Invalid input: expected X, received undefined\"\n */\n const requiredFields = parseResult.error.issues\n .filter((issue) => issue.code === \"invalid_type\")\n .map((issue) => ` - ${issue.path.join(\".\")}: Required`)\n .join(\"\\n\");\n\n throw new Error(\n `Middleware \"${middleware.name}\" has required state fields that must be initialized:\\n` +\n `${requiredFields}\\n\\n` +\n `To fix this, either:\\n` +\n `1. Provide default values in your middleware's state schema using .default():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().default(\"default value\")\\n` +\n ` })\\n\\n` +\n `2. Or make the fields optional using .optional():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().optional()\\n` +\n ` })\\n\\n` +\n `3. Or ensure you pass these values when invoking the agent:\\n` +\n ` agent.invoke({\\n` +\n ` messages: [...],\\n` +\n ` ${parseResult.error.issues[0]?.path.join(\".\")}: \"value\"\\n` +\n ` })`\n );\n }\n\n return middlewareStates;\n}\n\n/**\n * Users can define private and public state for a middleware. Private state properties start with an underscore.\n * This function will return the private state properties from the state schema, making all of them optional.\n * @param stateSchema - The middleware state schema\n * @returns A new schema containing only the private properties (underscore-prefixed), all made optional\n */\nexport function derivePrivateState(\n stateSchema?: z.ZodObject<z.ZodRawShape> | StateSchema<any>\n): z.ZodObject<z.ZodRawShape> {\n const builtInStateSchema = {\n messages: z.custom<BaseMessage[]>(() => []),\n // Include optional structuredResponse so after_agent hooks can access/modify it\n structuredResponse: z.any().optional(),\n };\n\n if (!stateSchema) {\n return z.object(builtInStateSchema);\n }\n\n // Extract shape from either StateSchema or Zod object\n let shape: Record<string, any>;\n if (StateSchema.isInstance(stateSchema)) {\n // For StateSchema, extract Zod schemas from fields\n shape = {};\n for (const [key, field] of Object.entries(stateSchema.fields)) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n shape[key] = field.inputSchema || field.valueSchema;\n } else {\n shape[key] = field;\n }\n }\n } else {\n shape = stateSchema.shape;\n }\n\n const privateShape: Record<string, any> = { ...builtInStateSchema };\n\n // Filter properties that start with underscore and make them optional\n for (const [key, value] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) {\n // Make the private property optional\n privateShape[key] = value.optional();\n } else {\n privateShape[key] = value;\n }\n }\n\n // Return a new schema with only private properties (all optional)\n return z.object(privateShape);\n}\n\n/**\n * Parse `jumpTo` target from user facing labels to a LangGraph node names\n */\nexport function parseJumpToTarget(target: string): JumpTo;\nexport function parseJumpToTarget(target?: string): JumpTo | undefined {\n if (!target) {\n return undefined;\n }\n\n /**\n * if target is already a valid jump target, return it\n */\n if ([\"model_request\", \"tools\", END].includes(target)) {\n return target as JumpTo;\n }\n\n if (target === \"model\") {\n return \"model_request\";\n }\n if (target === \"tools\") {\n return \"tools\";\n }\n if (target === \"end\") {\n return END;\n }\n\n throw new Error(\n `Invalid jump target: ${target}, must be \"model\", \"tools\" or \"end\".`\n );\n}\n\n/**\n * TypeScript currently doesn't support types for `AbortSignal.any`\n * @see https://github.com/microsoft/TypeScript/issues/60695\n */\ndeclare const AbortSignal: {\n any(signals: AbortSignal[]): AbortSignal;\n};\n\n/**\n * `config` always contains a signal from LangGraphs Pregel class.\n * To ensure we acknowledge the abort signal from the user, we merge it\n * with the signal from the ToolNode.\n *\n * @param signals - The signals to merge.\n * @returns The merged signal.\n */\nexport function mergeAbortSignals(\n ...signals: (AbortSignal | undefined)[]\n): AbortSignal {\n return AbortSignal.any(\n signals.filter(\n (maybeSignal): maybeSignal is AbortSignal =>\n maybeSignal !== null &&\n maybeSignal !== undefined &&\n typeof maybeSignal === \"object\" &&\n \"aborted\" in maybeSignal &&\n typeof maybeSignal.aborted === \"boolean\"\n )\n );\n}\n"],"mappings":";;;;;;;;;;;;AAmBA,eAAsB,2BACpBA,gBACAC,OAC8B;CAC9B,MAAMC,mBAAwC,CAAE;AAEhD,MAAK,MAAM,cAAc,gBAAgB;;;;AAIvC,MAAI,CAAC,WAAW,YACd;EAIF,IAAI,YAAY,WAAW;AAC3B,MAAI,YAAY,WAAW,WAAW,YAAY,EAAE;GAClD,MAAMC,WAAgC,CAAE;AACxC,QAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAChC,WAAW,YAAY,OACxB,CACC,KAAI,aAAa,WAAW,MAAM,EAEhC,SAAS,OAAO,MAAM,eAAe,MAAM;QAE3C,SAAS,OAAO;GAGpB,YAAY,EAAE,OAAO,SAAS;EAC/B;EAGD,MAAM,iBAAiB,mCACrB,WACA,CAAC,QAAQ,IAAI,WAAW,IAAI,CAC7B;EAGD,MAAM,cAAc,MAAM,sBAAsB,gBAAgB,MAAM;AACtE,MAAI,YAAY,SAAS;GACvB,OAAO,OAAO,kBAAkB,YAAY,KAAK;AACjD;EACD;;;;;EAMD,MAAM,iBAAiB,YAAY,MAAM,OACtC,OAAO,CAAC,UAAU,MAAM,SAAS,eAAe,CAChD,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC,CACvD,KAAK,KAAK;AAEb,QAAM,IAAI,MACR,CAAC,YAAY,EAAE,WAAW,KAAK,uDAAuD,EACjF,eAAe,0aAAI,EAad,YAAY,MAAM,OAAO,IAAI,KAAK,KAAK,IAAI,CAAC,gBAAW,CACxD;CAEZ;AAED,QAAO;AACR;;;;;;;AAQD,SAAgB,mBACdC,aAC4B;CAC5B,MAAM,qBAAqB;EACzB,UAAU,EAAE,OAAsB,MAAM,CAAE,EAAC;EAE3C,oBAAoB,EAAE,KAAK,CAAC,UAAU;CACvC;AAED,KAAI,CAAC,YACH,QAAO,EAAE,OAAO,mBAAmB;CAIrC,IAAIC;AACJ,KAAI,YAAY,WAAW,YAAY,EAAE;EAEvC,QAAQ,CAAE;AACV,OAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,YAAY,OAAO,CAC3D,KAAI,aAAa,WAAW,MAAM,EAEhC,MAAM,OAAO,MAAM,eAAe,MAAM;OAExC,MAAM,OAAO;CAGlB,OACC,QAAQ,YAAY;CAGtB,MAAMC,eAAoC,EAAE,GAAG,mBAAoB;AAGnE,MAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,MAAM,CAC9C,KAAI,IAAI,WAAW,IAAI,EAErB,aAAa,OAAO,MAAM,UAAU;MAEpC,aAAa,OAAO;AAKxB,QAAO,EAAE,OAAO,aAAa;AAC9B;AAMD,SAAgB,kBAAkBC,QAAqC;AACrE,KAAI,CAAC,OACH,QAAO;;;;AAMT,KAAI;EAAC;EAAiB;EAAS;CAAI,EAAC,SAAS,OAAO,CAClD,QAAO;AAGT,KAAI,WAAW,QACb,QAAO;AAET,KAAI,WAAW,QACb,QAAO;AAET,KAAI,WAAW,MACb,QAAO;AAGT,OAAM,IAAI,MACR,CAAC,qBAAqB,EAAE,OAAO,oCAAoC,CAAC;AAEvE;;;;;;;;;AAkBD,SAAgB,kBACd,GAAG,SACU;AACb,QAAO,YAAY,IACjB,QAAQ,OACN,CAAC,gBACC,gBAAgB,QAChB,gBAAgB,UAChB,OAAO,gBAAgB,YACvB,aAAa,eACb,OAAO,YAAY,YAAY,UAClC,CACF;AACF"}
1
+ {"version":3,"file":"utils.js","names":["middlewareList: readonly AgentMiddleware[]","state: unknown","middlewareStates: Record<string, any>","zodShape: Record<string, any>","stateSchema?: z.ZodObject<z.ZodRawShape> | StateSchema<any>","shape: Record<string, any>","privateShape: Record<string, any>","schema: StateDefinitionInit","partialShape: Record<string, any>","fieldSchema: unknown","target?: string"],"sources":["../../../src/agents/nodes/utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport {\n interopSafeParseAsync,\n interopZodObjectMakeFieldsOptional,\n interopZodObjectPartial,\n isInteropZodObject,\n isZodSchemaV4,\n type InteropZodObject,\n} from \"@langchain/core/utils/types\";\nimport type { StateDefinitionInit } from \"@langchain/langgraph\";\nimport { END, StateSchema, ReducedValue } from \"@langchain/langgraph\";\n\nimport type { JumpTo } from \"../types.js\";\nimport type { AgentMiddleware } from \"../middleware/types.js\";\n\n/**\n * Helper function to initialize middleware state defaults.\n * This is used to ensure all middleware state properties are initialized.\n *\n * Private properties (starting with _) are automatically made optional since\n * users cannot provide them when invoking the agent.\n */\nexport async function initializeMiddlewareStates(\n middlewareList: readonly AgentMiddleware[],\n state: unknown\n): Promise<Record<string, any>> {\n const middlewareStates: Record<string, any> = {};\n\n for (const middleware of middlewareList) {\n /**\n * skip middleware if it doesn't have a state schema\n */\n if (!middleware.stateSchema) {\n continue;\n }\n\n // Convert StateSchema to Zod object if needed\n let zodSchema = middleware.stateSchema;\n if (StateSchema.isInstance(middleware.stateSchema)) {\n const zodShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(\n middleware.stateSchema.fields\n )) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n zodShape[key] = field.inputSchema || field.valueSchema;\n } else {\n zodShape[key] = field;\n }\n }\n zodSchema = z.object(zodShape);\n }\n\n // Create a modified schema where private properties are optional\n const modifiedSchema = interopZodObjectMakeFieldsOptional(\n zodSchema,\n (key) => key.startsWith(\"_\")\n );\n\n // Use safeParse with the modified schema\n const parseResult = await interopSafeParseAsync(modifiedSchema, state);\n if (parseResult.success) {\n Object.assign(middlewareStates, parseResult.data);\n continue;\n }\n\n /**\n * If safeParse fails, there are required public fields missing.\n * Note: Zod v3 uses message \"Required\", Zod v4 uses \"Invalid input: expected X, received undefined\"\n */\n const requiredFields = parseResult.error.issues\n .filter((issue) => issue.code === \"invalid_type\")\n .map((issue) => ` - ${issue.path.join(\".\")}: Required`)\n .join(\"\\n\");\n\n throw new Error(\n `Middleware \"${middleware.name}\" has required state fields that must be initialized:\\n` +\n `${requiredFields}\\n\\n` +\n `To fix this, either:\\n` +\n `1. Provide default values in your middleware's state schema using .default():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().default(\"default value\")\\n` +\n ` })\\n\\n` +\n `2. Or make the fields optional using .optional():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().optional()\\n` +\n ` })\\n\\n` +\n `3. Or ensure you pass these values when invoking the agent:\\n` +\n ` agent.invoke({\\n` +\n ` messages: [...],\\n` +\n ` ${parseResult.error.issues[0]?.path.join(\".\")}: \"value\"\\n` +\n ` })`\n );\n }\n\n return middlewareStates;\n}\n\n/**\n * Users can define private and public state for a middleware. Private state properties start with an underscore.\n * This function will return the private state properties from the state schema, making all of them optional.\n * @param stateSchema - The middleware state schema\n * @returns A new schema containing only the private properties (underscore-prefixed), all made optional\n */\nexport function derivePrivateState(\n stateSchema?: z.ZodObject<z.ZodRawShape> | StateSchema<any>\n): z.ZodObject<z.ZodRawShape> {\n const builtInStateSchema = {\n messages: z.custom<BaseMessage[]>(() => []),\n // Include optional structuredResponse so after_agent hooks can access/modify it\n structuredResponse: z.any().optional(),\n };\n\n if (!stateSchema) {\n return z.object(builtInStateSchema);\n }\n\n // Extract shape from either StateSchema or Zod object\n let shape: Record<string, any>;\n if (StateSchema.isInstance(stateSchema)) {\n // For StateSchema, extract Zod schemas from fields\n shape = {};\n for (const [key, field] of Object.entries(stateSchema.fields)) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n shape[key] = field.inputSchema || field.valueSchema;\n } else {\n shape[key] = field;\n }\n }\n } else {\n shape = stateSchema.shape;\n }\n\n const privateShape: Record<string, any> = { ...builtInStateSchema };\n\n // Filter properties that start with underscore and make them optional\n for (const [key, value] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) {\n // Make the private property optional\n privateShape[key] = value.optional();\n } else {\n privateShape[key] = value;\n }\n }\n\n // Return a new schema with only private properties (all optional)\n return z.object(privateShape);\n}\n\n/**\n * Converts any supported schema type (ZodObject, StateSchema, AnnotationRoot) to a partial Zod object.\n * This is useful for parsing state loosely where all fields are optional.\n *\n * @param schema - The schema to convert (InteropZodObject, StateSchema, or AnnotationRoot)\n * @returns A partial Zod object schema where all fields are optional\n */\nexport function toPartialZodObject(\n schema: StateDefinitionInit\n): InteropZodObject {\n // Handle ZodObject directly\n if (isInteropZodObject(schema)) {\n return interopZodObjectPartial(schema);\n }\n\n // Handle StateSchema: convert fields to Zod shape, then make partial\n if (StateSchema.isInstance(schema)) {\n const partialShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(schema.fields)) {\n let fieldSchema: unknown;\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n fieldSchema = field.inputSchema || field.valueSchema;\n } else {\n fieldSchema = field;\n }\n // Only call .optional() on Zod v4 schemas, otherwise use z.any()\n partialShape[key] = isZodSchemaV4(fieldSchema)\n ? (fieldSchema as any).optional()\n : z.any().optional();\n }\n return z.object(partialShape);\n }\n\n // Fallback: return empty object schema\n return z.object({});\n}\n\n/**\n * Parse `jumpTo` target from user facing labels to a LangGraph node names\n */\nexport function parseJumpToTarget(target: string): JumpTo;\nexport function parseJumpToTarget(target?: string): JumpTo | undefined {\n if (!target) {\n return undefined;\n }\n\n /**\n * if target is already a valid jump target, return it\n */\n if ([\"model_request\", \"tools\", END].includes(target)) {\n return target as JumpTo;\n }\n\n if (target === \"model\") {\n return \"model_request\";\n }\n if (target === \"tools\") {\n return \"tools\";\n }\n if (target === \"end\") {\n return END;\n }\n\n throw new Error(\n `Invalid jump target: ${target}, must be \"model\", \"tools\" or \"end\".`\n );\n}\n\n/**\n * TypeScript currently doesn't support types for `AbortSignal.any`\n * @see https://github.com/microsoft/TypeScript/issues/60695\n */\ndeclare const AbortSignal: {\n any(signals: AbortSignal[]): AbortSignal;\n};\n\n/**\n * `config` always contains a signal from LangGraphs Pregel class.\n * To ensure we acknowledge the abort signal from the user, we merge it\n * with the signal from the ToolNode.\n *\n * @param signals - The signals to merge.\n * @returns The merged signal.\n */\nexport function mergeAbortSignals(\n ...signals: (AbortSignal | undefined)[]\n): AbortSignal {\n return AbortSignal.any(\n signals.filter(\n (maybeSignal): maybeSignal is AbortSignal =>\n maybeSignal !== null &&\n maybeSignal !== undefined &&\n typeof maybeSignal === \"object\" &&\n \"aborted\" in maybeSignal &&\n typeof maybeSignal.aborted === \"boolean\"\n )\n );\n}\n"],"mappings":";;;;;;;;;;;;AAwBA,eAAsB,2BACpBA,gBACAC,OAC8B;CAC9B,MAAMC,mBAAwC,CAAE;AAEhD,MAAK,MAAM,cAAc,gBAAgB;;;;AAIvC,MAAI,CAAC,WAAW,YACd;EAIF,IAAI,YAAY,WAAW;AAC3B,MAAI,YAAY,WAAW,WAAW,YAAY,EAAE;GAClD,MAAMC,WAAgC,CAAE;AACxC,QAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAChC,WAAW,YAAY,OACxB,CACC,KAAI,aAAa,WAAW,MAAM,EAEhC,SAAS,OAAO,MAAM,eAAe,MAAM;QAE3C,SAAS,OAAO;GAGpB,YAAY,EAAE,OAAO,SAAS;EAC/B;EAGD,MAAM,iBAAiB,mCACrB,WACA,CAAC,QAAQ,IAAI,WAAW,IAAI,CAC7B;EAGD,MAAM,cAAc,MAAM,sBAAsB,gBAAgB,MAAM;AACtE,MAAI,YAAY,SAAS;GACvB,OAAO,OAAO,kBAAkB,YAAY,KAAK;AACjD;EACD;;;;;EAMD,MAAM,iBAAiB,YAAY,MAAM,OACtC,OAAO,CAAC,UAAU,MAAM,SAAS,eAAe,CAChD,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC,CACvD,KAAK,KAAK;AAEb,QAAM,IAAI,MACR,CAAC,YAAY,EAAE,WAAW,KAAK,uDAAuD,EACjF,eAAe,0aAAI,EAad,YAAY,MAAM,OAAO,IAAI,KAAK,KAAK,IAAI,CAAC,gBAAW,CACxD;CAEZ;AAED,QAAO;AACR;;;;;;;AAQD,SAAgB,mBACdC,aAC4B;CAC5B,MAAM,qBAAqB;EACzB,UAAU,EAAE,OAAsB,MAAM,CAAE,EAAC;EAE3C,oBAAoB,EAAE,KAAK,CAAC,UAAU;CACvC;AAED,KAAI,CAAC,YACH,QAAO,EAAE,OAAO,mBAAmB;CAIrC,IAAIC;AACJ,KAAI,YAAY,WAAW,YAAY,EAAE;EAEvC,QAAQ,CAAE;AACV,OAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,YAAY,OAAO,CAC3D,KAAI,aAAa,WAAW,MAAM,EAEhC,MAAM,OAAO,MAAM,eAAe,MAAM;OAExC,MAAM,OAAO;CAGlB,OACC,QAAQ,YAAY;CAGtB,MAAMC,eAAoC,EAAE,GAAG,mBAAoB;AAGnE,MAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,MAAM,CAC9C,KAAI,IAAI,WAAW,IAAI,EAErB,aAAa,OAAO,MAAM,UAAU;MAEpC,aAAa,OAAO;AAKxB,QAAO,EAAE,OAAO,aAAa;AAC9B;;;;;;;;AASD,SAAgB,mBACdC,QACkB;AAElB,KAAI,mBAAmB,OAAO,CAC5B,QAAO,wBAAwB,OAAO;AAIxC,KAAI,YAAY,WAAW,OAAO,EAAE;EAClC,MAAMC,eAAoC,CAAE;AAC5C,OAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,OAAO,OAAO,EAAE;GACxD,IAAIC;AACJ,OAAI,aAAa,WAAW,MAAM,EAEhC,cAAc,MAAM,eAAe,MAAM;QAEzC,cAAc;GAGhB,aAAa,OAAO,cAAc,YAAY,GACzC,YAAoB,UAAU,GAC/B,EAAE,KAAK,CAAC,UAAU;EACvB;AACD,SAAO,EAAE,OAAO,aAAa;CAC9B;AAGD,QAAO,EAAE,OAAO,CAAE,EAAC;AACpB;AAMD,SAAgB,kBAAkBC,QAAqC;AACrE,KAAI,CAAC,OACH,QAAO;;;;AAMT,KAAI;EAAC;EAAiB;EAAS;CAAI,EAAC,SAAS,OAAO,CAClD,QAAO;AAGT,KAAI,WAAW,QACb,QAAO;AAET,KAAI,WAAW,QACb,QAAO;AAET,KAAI,WAAW,MACb,QAAO;AAGT,OAAM,IAAI,MACR,CAAC,qBAAqB,EAAE,OAAO,oCAAoC,CAAC;AAEvE;;;;;;;;;AAkBD,SAAgB,kBACd,GAAG,SACU;AACb,QAAO,YAAY,IACjB,QAAQ,OACN,CAAC,gBACC,gBAAgB,QAChB,gBAAgB,UAChB,OAAO,gBAAgB,YACvB,aAAa,eACb,OAAO,YAAY,YAAY,UAClC,CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"responses.d.cts","names":["InteropZodObject","InteropZodType","AIMessage","LanguageModelLike","FunctionDefinition","StructuredOutputParsingError","MultipleStructuredOutputsError","ResponseFormatUndefined","ToolStrategy","S","_T","Record","ToolStrategyOptions","U","ProviderStrategy","T","ResponseFormat","transformResponseFormat","JsonSchemaFormat","TypedToolStrategy","Array","ToolStrategyError","Promise","toolStrategy","K","providerStrategy","hasSupportForJsonSchemaOutput"],"sources":["../../src/agents/responses.d.ts"],"sourcesContent":["import { InteropZodObject, InteropZodType } from \"@langchain/core/utils/types\";\nimport { type AIMessage } from \"@langchain/core/messages\";\nimport { type LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { type FunctionDefinition } from \"@langchain/core/language_models/base\";\nimport { StructuredOutputParsingError, MultipleStructuredOutputsError } from \"./errors.js\";\n/**\n * Special type to indicate that no response format is provided.\n * When this type is used, the structuredResponse property should not be present in the result.\n */\nexport type ResponseFormatUndefined = {\n __responseFormatUndefined: true;\n};\n/**\n * Information for tracking structured output tool metadata.\n * This contains all necessary information to handle structured responses generated\n * via tool calls, including the original schema, its type classification, and the\n * corresponding tool implementation used by the tools strategy.\n */\nexport declare class ToolStrategy<_T = unknown> {\n readonly schema: Record<string, unknown>;\n readonly tool: {\n type: \"function\";\n function: FunctionDefinition;\n };\n readonly options?: ToolStrategyOptions | undefined;\n private constructor();\n get name(): string;\n static fromSchema<S extends InteropZodObject>(schema: S, outputOptions?: ToolStrategyOptions): ToolStrategy<S extends InteropZodType<infer U> ? U : unknown>;\n static fromSchema(schema: Record<string, unknown>, outputOptions?: ToolStrategyOptions): ToolStrategy<Record<string, unknown>>;\n /**\n * Parse tool arguments according to the schema.\n *\n * @throws {StructuredOutputParsingError} if the response is not valid\n * @param toolArgs - The arguments from the tool call\n * @returns The parsed response according to the schema type\n */\n parse(toolArgs: Record<string, unknown>): Record<string, unknown>;\n}\nexport declare class ProviderStrategy<T = unknown> {\n private _schemaType?;\n /**\n * The schema to use for the provider strategy\n */\n readonly schema: Record<string, unknown>;\n /**\n * Whether to use strict mode for the provider strategy\n */\n readonly strict: boolean;\n private constructor();\n private constructor();\n static fromSchema<T>(schema: InteropZodType<T>, strict?: boolean): ProviderStrategy<T>;\n static fromSchema(schema: Record<string, unknown>, strict?: boolean): ProviderStrategy<Record<string, unknown>>;\n /**\n * Parse tool arguments according to the schema. If the response is not valid, return undefined.\n *\n * @param response - The AI message response to parse\n * @returns The parsed response according to the schema type\n */\n parse(response: AIMessage): any;\n}\nexport type ResponseFormat = ToolStrategy<any> | ProviderStrategy<any>;\n/**\n * Handle user input for `responseFormat` parameter of `CreateAgentParams`.\n * This function defines the default behavior for the `responseFormat` parameter, which is:\n *\n * - if value is a Zod schema, default to structured output via tool calling\n * - if value is a JSON schema, default to structured output via tool calling\n * - if value is a custom response format, return it as is\n * - if value is an array, ensure all array elements are instance of `ToolStrategy`\n * @param responseFormat - The response format to transform, provided by the user\n * @param options - The response format options for tool strategy\n * @param model - The model to check if it supports JSON schema output\n * @returns\n */\nexport declare function transformResponseFormat(responseFormat?: InteropZodType<any> | InteropZodType<any>[] | JsonSchemaFormat | JsonSchemaFormat[] | ResponseFormat | ToolStrategy<any>[] | ResponseFormatUndefined, options?: ToolStrategyOptions, model?: LanguageModelLike | string): ResponseFormat[];\n/**\n * Branded type for ToolStrategy arrays that preserves type information\n */\nexport interface TypedToolStrategy<T = unknown> extends Array<ToolStrategy<any>> {\n _schemaType?: T;\n}\nexport type ToolStrategyError = StructuredOutputParsingError | MultipleStructuredOutputsError;\nexport interface ToolStrategyOptions {\n /**\n * Allows you to customize the message that appears in the conversation history when structured\n * output is generated.\n */\n toolMessageContent?: string;\n /**\n * Handle errors from the structured output tool call. Using tools to generate structured output\n * can cause errors, e.g. if:\n * - you provide multiple structured output schemas and the model calls multiple structured output tools\n * - if the structured output generated by the tool call doesn't match provided schema\n *\n * This property allows to handle these errors in different ways:\n * - `true` - retry the tool call\n * - `false` - throw an error\n * - `string` - retry the tool call with the provided message\n * - `(error: ToolStrategyError) => Promise<string> | string` - retry with the provided message or throw the error\n *\n * @default true\n */\n handleError?: boolean | string | ((error: ToolStrategyError) => Promise<string> | string);\n}\nexport declare function toolStrategy<T extends InteropZodType<any>>(responseFormat: T, options?: ToolStrategyOptions): TypedToolStrategy<T extends InteropZodType<infer U> ? U : never>;\nexport declare function toolStrategy<T extends readonly InteropZodType<any>[]>(responseFormat: T, options?: ToolStrategyOptions): TypedToolStrategy<{\n [K in keyof T]: T[K] extends InteropZodType<infer U> ? U : never;\n}[number]>;\nexport declare function toolStrategy(responseFormat: JsonSchemaFormat, options?: ToolStrategyOptions): TypedToolStrategy<Record<string, unknown>>;\nexport declare function toolStrategy(responseFormat: JsonSchemaFormat[], options?: ToolStrategyOptions): TypedToolStrategy<Record<string, unknown>>;\n/**\n * Creates a provider strategy for structured output using native JSON schema support.\n *\n * This function is used to configure structured output for agents when the underlying model\n * supports native JSON schema output (e.g., OpenAI's `gpt-4o`, `gpt-4o-mini`, and newer models).\n * Unlike `toolStrategy`, which uses function calling to extract structured output, `providerStrategy`\n * leverages the provider's native structured output capabilities, resulting in more efficient\n * and reliable schema enforcement.\n *\n * When used with a model that supports JSON schema output, the model will return responses\n * that directly conform to the provided schema without requiring tool calls. This is the\n * recommended approach for structured output when your model supports it.\n *\n * @param responseFormat - The schema to enforce, either a Zod schema, a JSON schema object, or an options object with `schema` and optional `strict` flag\n * @returns A `ProviderStrategy` instance that can be used as the `responseFormat` in `createAgent`\n *\n * @example\n * ```ts\n * import { providerStrategy, createAgent } from \"langchain\";\n * import { z } from \"zod\";\n *\n * const agent = createAgent({\n * model: \"claude-haiku-4-5\",\n * responseFormat: providerStrategy(\n * z.object({\n * answer: z.string().describe(\"The answer to the question\"),\n * confidence: z.number().min(0).max(1),\n * })\n * ),\n * });\n * ```\n *\n * @example\n * ```ts\n * // Using strict mode for stricter schema enforcement\n * const agent = createAgent({\n * model: \"claude-haiku-4-5\",\n * responseFormat: providerStrategy({\n * schema: z.object({\n * name: z.string(),\n * age: z.number(),\n * }),\n * strict: true\n * }),\n * });\n * ```\n */\nexport declare function providerStrategy<T extends InteropZodType<unknown>>(responseFormat: T | {\n schema: T;\n strict?: boolean;\n}): ProviderStrategy<T extends InteropZodType<infer U> ? U : never>;\nexport declare function providerStrategy(responseFormat: JsonSchemaFormat | {\n schema: JsonSchemaFormat;\n strict?: boolean;\n}): ProviderStrategy<Record<string, unknown>>;\n/**\n * Type representing a JSON Schema object format.\n * This is a strict type that excludes ToolStrategy and ProviderStrategy instances.\n */\nexport type JsonSchemaFormat = {\n type: \"null\" | \"boolean\" | \"object\" | \"array\" | \"number\" | \"string\" | \"integer\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n [key: string]: unknown;\n} & {\n __brand?: never;\n};\n/**\n * Identifies the models that support JSON schema output\n * @param model - The model to check\n * @returns True if the model supports JSON schema output, false otherwise\n */\nexport declare function hasSupportForJsonSchemaOutput(model?: LanguageModelLike | string): boolean;\n//# sourceMappingURL=responses.d.ts.map"],"mappings":"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"}
1
+ {"version":3,"file":"responses.d.cts","names":["InteropZodObject","InteropZodType","AIMessage","LanguageModelLike","FunctionDefinition","StructuredOutputParsingError","MultipleStructuredOutputsError","ResponseFormatUndefined","ToolStrategy","S","_T","Record","ToolStrategyOptions","U","ProviderStrategy","T","ResponseFormat","transformResponseFormat","JsonSchemaFormat","TypedToolStrategy","Array","ToolStrategyError","Promise","toolStrategy","K","providerStrategy","hasSupportForJsonSchemaOutput"],"sources":["../../src/agents/responses.d.ts"],"sourcesContent":["import { InteropZodObject, InteropZodType } from \"@langchain/core/utils/types\";\nimport { type AIMessage } from \"@langchain/core/messages\";\nimport { type LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { type FunctionDefinition } from \"@langchain/core/language_models/base\";\nimport { StructuredOutputParsingError, MultipleStructuredOutputsError } from \"./errors.js\";\n/**\n * Special type to indicate that no response format is provided.\n * When this type is used, the structuredResponse property should not be present in the result.\n */\nexport type ResponseFormatUndefined = {\n __responseFormatUndefined: true;\n};\n/**\n * Information for tracking structured output tool metadata.\n * This contains all necessary information to handle structured responses generated\n * via tool calls, including the original schema, its type classification, and the\n * corresponding tool implementation used by the tools strategy.\n */\nexport declare class ToolStrategy<_T = unknown> {\n readonly schema: Record<string, unknown>;\n readonly tool: {\n type: \"function\";\n function: FunctionDefinition;\n };\n readonly options?: ToolStrategyOptions | undefined;\n private constructor();\n get name(): string;\n static fromSchema<S extends InteropZodObject>(schema: S, outputOptions?: ToolStrategyOptions): ToolStrategy<S extends InteropZodType<infer U> ? U : unknown>;\n static fromSchema(schema: Record<string, unknown>, outputOptions?: ToolStrategyOptions): ToolStrategy<Record<string, unknown>>;\n /**\n * Parse tool arguments according to the schema.\n *\n * @throws {StructuredOutputParsingError} if the response is not valid\n * @param toolArgs - The arguments from the tool call\n * @returns The parsed response according to the schema type\n */\n parse(toolArgs: Record<string, unknown>): Record<string, unknown>;\n}\nexport declare class ProviderStrategy<T = unknown> {\n private _schemaType?;\n /**\n * The schema to use for the provider strategy\n */\n readonly schema: Record<string, unknown>;\n /**\n * Whether to use strict mode for the provider strategy\n */\n readonly strict: boolean;\n private constructor();\n private constructor();\n static fromSchema<T>(schema: InteropZodType<T>, strict?: boolean): ProviderStrategy<T>;\n static fromSchema(schema: Record<string, unknown>, strict?: boolean): ProviderStrategy<Record<string, unknown>>;\n /**\n * Parse tool arguments according to the schema. If the response is not valid, return undefined.\n *\n * @param response - The AI message response to parse\n * @returns The parsed response according to the schema type\n */\n parse(response: AIMessage): any;\n}\nexport type ResponseFormat = ToolStrategy<any> | ProviderStrategy<any>;\n/**\n * Handle user input for `responseFormat` parameter of `CreateAgentParams`.\n * This function defines the default behavior for the `responseFormat` parameter, which is:\n *\n * - if value is a Zod schema, default to structured output via tool calling\n * - if value is a JSON schema, default to structured output via tool calling\n * - if value is a custom response format, return it as is\n * - if value is an array, ensure all array elements are instance of `ToolStrategy`\n * @param responseFormat - The response format to transform, provided by the user\n * @param options - The response format options for tool strategy\n * @param model - The model to check if it supports JSON schema output\n * @returns\n */\nexport declare function transformResponseFormat(responseFormat?: InteropZodType<any> | InteropZodType<any>[] | JsonSchemaFormat | JsonSchemaFormat[] | ResponseFormat | ToolStrategy<any>[] | ResponseFormatUndefined, options?: ToolStrategyOptions, model?: LanguageModelLike | string): ResponseFormat[];\n/**\n * Branded type for ToolStrategy arrays that preserves type information\n */\nexport interface TypedToolStrategy<T = unknown> extends Array<ToolStrategy<any>> {\n _schemaType?: T;\n}\nexport type ToolStrategyError = StructuredOutputParsingError | MultipleStructuredOutputsError;\nexport interface ToolStrategyOptions {\n /**\n * Allows you to customize the message that appears in the conversation history when structured\n * output is generated.\n */\n toolMessageContent?: string;\n /**\n * Handle errors from the structured output tool call. Using tools to generate structured output\n * can cause errors, e.g. if:\n * - you provide multiple structured output schemas and the model calls multiple structured output tools\n * - if the structured output generated by the tool call doesn't match provided schema\n *\n * This property allows to handle these errors in different ways:\n * - `true` - retry the tool call\n * - `false` - throw an error\n * - `string` - retry the tool call with the provided message\n * - `(error: ToolStrategyError) => Promise<string> | string` - retry with the provided message or throw the error\n *\n * @default true\n */\n handleError?: boolean | string | ((error: ToolStrategyError) => Promise<string> | string);\n}\nexport declare function toolStrategy<T extends InteropZodType<any>>(responseFormat: T, options?: ToolStrategyOptions): TypedToolStrategy<T extends InteropZodType<infer U> ? U : never>;\nexport declare function toolStrategy<T extends readonly InteropZodType<any>[]>(responseFormat: T, options?: ToolStrategyOptions): TypedToolStrategy<{\n [K in keyof T]: T[K] extends InteropZodType<infer U> ? U : never;\n}[number]>;\nexport declare function toolStrategy(responseFormat: JsonSchemaFormat, options?: ToolStrategyOptions): TypedToolStrategy<Record<string, unknown>>;\nexport declare function toolStrategy(responseFormat: JsonSchemaFormat[], options?: ToolStrategyOptions): TypedToolStrategy<Record<string, unknown>>;\n/**\n * Creates a provider strategy for structured output using native JSON schema support.\n *\n * This function is used to configure structured output for agents when the underlying model\n * supports native JSON schema output (e.g., OpenAI's `gpt-4o`, `gpt-4o-mini`, and newer models).\n * Unlike `toolStrategy`, which uses function calling to extract structured output, `providerStrategy`\n * leverages the provider's native structured output capabilities, resulting in more efficient\n * and reliable schema enforcement.\n *\n * When used with a model that supports JSON schema output, the model will return responses\n * that directly conform to the provided schema without requiring tool calls. This is the\n * recommended approach for structured output when your model supports it.\n *\n * @param responseFormat - The schema to enforce, either a Zod schema, a JSON schema object, or an options object with `schema` and optional `strict` flag\n * @returns A `ProviderStrategy` instance that can be used as the `responseFormat` in `createAgent`\n *\n * @example\n * ```ts\n * import { providerStrategy, createAgent } from \"langchain\";\n * import { z } from \"zod\";\n *\n * const agent = createAgent({\n * model: \"claude-haiku-4-5\",\n * responseFormat: providerStrategy(\n * z.object({\n * answer: z.string().describe(\"The answer to the question\"),\n * confidence: z.number().min(0).max(1),\n * })\n * ),\n * });\n * ```\n *\n * @example\n * ```ts\n * // Using strict mode for stricter schema enforcement\n * const agent = createAgent({\n * model: \"claude-haiku-4-5\",\n * responseFormat: providerStrategy({\n * schema: z.object({\n * name: z.string(),\n * age: z.number(),\n * }),\n * strict: true\n * }),\n * });\n * ```\n */\nexport declare function providerStrategy<T extends InteropZodType<unknown>>(responseFormat: T | {\n schema: T;\n strict?: boolean;\n}): ProviderStrategy<T extends InteropZodType<infer U> ? U : never>;\nexport declare function providerStrategy(responseFormat: JsonSchemaFormat | {\n schema: JsonSchemaFormat;\n strict?: boolean;\n}): ProviderStrategy<Record<string, unknown>>;\n/**\n * Type representing a JSON Schema object format.\n * This is a strict type that excludes ToolStrategy and ProviderStrategy instances.\n */\nexport type JsonSchemaFormat = {\n type: \"null\" | \"boolean\" | \"object\" | \"array\" | \"number\" | \"string\" | \"integer\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n [key: string]: unknown;\n} & {\n __brand?: never;\n};\n/**\n * Identifies the models that support JSON schema output\n * @param model - The model to check\n * @returns True if the model supports JSON schema output, false otherwise\n */\nexport declare function hasSupportForJsonSchemaOutput(model?: LanguageModelLike | string): boolean;\n//# sourceMappingURL=responses.d.ts.map"],"mappings":"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"}