langchain 1.5.17 → 1.5.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/agents/ReactAgent.cjs +8 -14
- package/dist/agents/ReactAgent.cjs.map +1 -1
- package/dist/agents/ReactAgent.d.cts.map +1 -1
- package/dist/agents/ReactAgent.d.ts.map +1 -1
- package/dist/agents/ReactAgent.js +8 -14
- package/dist/agents/ReactAgent.js.map +1 -1
- package/dist/agents/middleware/hitl.cjs +184 -14
- package/dist/agents/middleware/hitl.cjs.map +1 -1
- package/dist/agents/middleware/hitl.d.cts +113 -9
- package/dist/agents/middleware/hitl.d.cts.map +1 -1
- package/dist/agents/middleware/hitl.d.ts +145 -41
- package/dist/agents/middleware/hitl.d.ts.map +1 -1
- package/dist/agents/middleware/hitl.js +196 -27
- package/dist/agents/middleware/hitl.js.map +1 -1
- package/dist/agents/middleware/index.cjs +1 -0
- package/dist/agents/middleware/index.d.cts +2 -2
- package/dist/agents/middleware/index.d.ts +2 -2
- package/dist/agents/middleware/index.js +2 -2
- package/dist/agents/middleware/todoListMiddleware.cjs +41 -183
- package/dist/agents/middleware/todoListMiddleware.cjs.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.cts +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.cts.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.ts +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.ts.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.js +41 -183
- package/dist/agents/middleware/todoListMiddleware.js.map +1 -1
- package/dist/agents/nodes/ToolNode.cjs +14 -2
- package/dist/agents/nodes/ToolNode.cjs.map +1 -1
- package/dist/agents/nodes/ToolNode.js +14 -2
- package/dist/agents/nodes/ToolNode.js.map +1 -1
- package/dist/agents/tests/utils.cjs.map +1 -1
- package/dist/agents/tests/utils.d.cts +1 -1
- package/dist/agents/tests/utils.d.ts +1 -1
- package/dist/agents/tests/utils.js.map +1 -1
- package/dist/agents/types.d.cts +6 -0
- package/dist/agents/types.d.cts.map +1 -1
- package/dist/agents/types.d.ts +6 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/browser.cjs +2 -0
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +3 -2
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -2
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolNode.js","names":[],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n/* oxlint-disable no-instanceof/no-instanceof */\nimport { BaseMessage, ToolMessage, AIMessage } from \"@langchain/core/messages\";\nimport { RunnableConfig, RunnableToolLike } from \"@langchain/core/runnables\";\nimport {\n DynamicTool,\n StructuredToolInterface,\n ToolInputParsingException,\n} from \"@langchain/core/tools\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport type { InteropZodObject } from \"@langchain/core/utils/types\";\nimport {\n isCommand,\n Command,\n Send,\n isGraphInterrupt,\n type LangGraphRunnableConfig,\n StateDefinitionInit,\n} from \"@langchain/langgraph\";\n\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport { mergeAbortSignals } from \"./utils.js\";\nimport { MiddlewareError, ToolInvocationError } from \"../errors.js\";\nimport type {\n WrapToolCallHook,\n ToolCallRequest,\n ToAnnotationRoot,\n} from \"../middleware/types.js\";\nimport type { AgentBuiltInState } from \"../runtime.js\";\n\n/**\n * Error message template for when middleware adds tools that can't be executed.\n * This happens when middleware modifies tools in wrapModelCall but doesn't provide\n * a wrapToolCall handler to execute them.\n */\nconst getInvalidToolError = (\n toolName: string,\n availableTools: string[]\n): string =>\n `Error: ${toolName} is not a valid tool, try one of [${availableTools.join(\", \")}].`;\n\n/**\n * The name of the tool node in the state graph.\n */\nexport const TOOLS_NODE_NAME = \"tools\";\n\nexport interface ToolNodeOptions {\n /**\n * The name of the tool node.\n */\n name?: string;\n /**\n * The tags to add to the tool call.\n */\n tags?: string[];\n /**\n * The abort signal to cancel the tool call.\n */\n signal?: AbortSignal;\n /**\n * Whether to throw the error immediately if the tool fails or handle it by the `onToolError` function or via ToolMessage.\n *\n * **Default behavior** (matches Python):\n * - Catches only `ToolInvocationError` (invalid arguments from model) and converts to ToolMessage\n * - Re-raises all other errors including errors from `wrapToolCall` middleware\n *\n * If `true`:\n * - Catches all errors and returns a ToolMessage with the error\n *\n * If `false`:\n * - All errors are thrown immediately\n *\n * If a function is provided:\n * - If function returns a `ToolMessage`, use it as the result\n * - If function returns `undefined`, re-raise the error\n *\n * @default A function that only catches ToolInvocationError\n */\n handleToolErrors?:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined);\n /**\n * Optional wrapper function for tool execution.\n * Allows middleware to intercept and modify tool calls before execution.\n * The wrapper receives the tool call request and a handler function to execute the tool.\n */\n wrapToolCall?: WrapToolCallHook;\n}\n\nconst isBaseMessageArray = (input: unknown): input is BaseMessage[] =>\n Array.isArray(input) && input.every(BaseMessage.isInstance);\n\nconst isMessagesState = (\n input: unknown\n): input is { messages: BaseMessage[] } =>\n typeof input === \"object\" &&\n input != null &&\n \"messages\" in input &&\n isBaseMessageArray(input.messages);\n\nconst isSendInput = (\n input: unknown\n): input is { lg_tool_call: ToolCall; jumpTo?: string } =>\n typeof input === \"object\" && input != null && \"lg_tool_call\" in input;\n\n/**\n * Default error handler for tool errors.\n *\n * This is applied to errors from baseHandler (tool execution).\n * For errors from wrapToolCall middleware, those are handled separately\n * and will bubble up by default.\n *\n * Catches all tool execution errors and converts them to ToolMessage.\n * This allows the LLM to see the error and potentially retry with different arguments.\n */\nfunction defaultHandleToolErrors(\n error: unknown,\n toolCall: ToolCall\n): ToolMessage | undefined {\n if (ToolInvocationError.isInstance(error)) {\n return new ToolMessage({\n content: error.message,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n }\n /**\n * Catch all other tool errors and convert to ToolMessage\n */\n return new ToolMessage({\n content: `${error}\\n Please fix your mistakes.`,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n}\n\n/**\n * `ToolNode` is a built-in LangGraph component that handles tool calls within an agent's workflow.\n * It works seamlessly with `createAgent`, offering advanced tool execution control, built\n * in parallelism, and error handling.\n *\n * @example\n * ```ts\n * import { ToolNode, tool, AIMessage } from \"langchain\";\n * import { z } from \"zod/v3\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const toolNode = new ToolNode(tools);\n *\n * const messageWithSingleToolCall = new AIMessage({\n * content: \"\",\n * tool_calls: [\n * {\n * name: \"get_weather\",\n * args: { location: \"sf\" },\n * id: \"tool_call_id\",\n * type: \"tool_call\",\n * }\n * ]\n * })\n *\n * await toolNode.invoke({ messages: [messageWithSingleToolCall] });\n * // Returns tool invocation responses as:\n * // { messages: ToolMessage[] }\n * ```\n */\nexport class ToolNode<\n StateSchema extends StateDefinitionInit = any,\n ContextSchema extends InteropZodObject = any,\n> extends RunnableCallable<StateSchema, ContextSchema> {\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[];\n\n trace = false;\n\n signal?: AbortSignal;\n\n handleToolErrors:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined) =\n defaultHandleToolErrors;\n\n wrapToolCall: WrapToolCallHook | undefined;\n\n constructor(\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[],\n public options?: ToolNodeOptions\n ) {\n const { name, tags, handleToolErrors, signal, wrapToolCall } =\n options ?? {};\n super({\n name,\n tags,\n func: (state, config) =>\n this.run(\n state as ToAnnotationRoot<StateDefinitionInit>[\"State\"] &\n AgentBuiltInState,\n config as RunnableConfig\n ),\n });\n this.tools = tools;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n this.signal = signal;\n this.wrapToolCall = wrapToolCall;\n }\n\n /**\n * Handle errors from tool execution or middleware.\n * @param error - The error to handle\n * @param call - The tool call that caused the error\n * @param isMiddlewareError - Whether the error came from wrapToolCall middleware\n * @returns ToolMessage if error is handled, otherwise re-throws\n */\n #handleError(\n error: unknown,\n call: ToolCall,\n isMiddlewareError: boolean\n ): ToolMessage {\n /**\n * {@link NodeInterrupt} errors are a breakpoint to bring a human into the loop.\n * As such, they are not recoverable by the agent and shouldn't be fed\n * back. Instead, re-throw these errors even when `handleToolErrors = true`.\n */\n if (isGraphInterrupt(error)) {\n throw error;\n }\n\n /**\n * If the signal is aborted, we want to bubble up the error to the invoke caller.\n */\n if (this.signal?.aborted) {\n throw error;\n }\n\n /**\n * A recoverable tool error (e.g. tool-input schema validation) can be\n * rewrapped as a {@link MiddlewareError} with the original error on `.cause`\n * — once per `wrapToolCall` middleware, so it may be nested several layers\n * deep. Walk the cause chain to the root; if it's a {@link ToolInvocationError},\n * unwrap it so the intended `handleToolErrors` self-correction path still\n * applies. Genuine middleware errors stay fatal by default.\n */\n let effectiveError = error;\n let errorFromMiddleware = isMiddlewareError;\n if (isMiddlewareError) {\n let unwrapped: unknown = error;\n while (MiddlewareError.isInstance(unwrapped)) {\n unwrapped = unwrapped.cause;\n }\n if (ToolInvocationError.isInstance(unwrapped)) {\n effectiveError = unwrapped;\n errorFromMiddleware = false;\n }\n }\n\n /**\n * If error is from middleware and handleToolErrors is not true, bubble up\n * (default handler and false both re-raise middleware errors)\n */\n if (errorFromMiddleware && this.handleToolErrors !== true) {\n throw effectiveError;\n }\n\n /**\n * If handleToolErrors is false, throw all errors\n */\n if (!this.handleToolErrors) {\n throw effectiveError;\n }\n\n /**\n * Apply handleToolErrors to the error\n */\n if (typeof this.handleToolErrors === \"function\") {\n const result = this.handleToolErrors(effectiveError, call);\n if (result && ToolMessage.isInstance(result)) {\n result.status ??= \"error\";\n return result;\n }\n\n /**\n * `handleToolErrors` returned undefined - re-raise\n */\n throw effectiveError;\n } else if (this.handleToolErrors) {\n return new ToolMessage({\n name: call.name,\n content: `${effectiveError}\\n Please fix your mistakes.`,\n tool_call_id: call.id!,\n status: \"error\",\n });\n }\n\n /**\n * Shouldn't reach here, but throw as fallback\n */\n throw effectiveError;\n }\n\n protected async runTool(\n call: ToolCall,\n config: RunnableConfig,\n state: AgentBuiltInState\n ): Promise<ToolMessage | Command> {\n /**\n * Build runtime from LangGraph config\n */\n const lgConfig = config as LangGraphRunnableConfig;\n const runtime = {\n context: lgConfig?.context,\n store: lgConfig?.store,\n configurable: lgConfig?.configurable,\n writer: lgConfig?.writer,\n interrupt: lgConfig?.interrupt,\n signal: lgConfig?.signal,\n };\n\n /**\n * Find the tool instance to include in the request.\n * For dynamically registered tools, this may be undefined.\n */\n const registeredTool = this.tools.find((t) => t.name === call.name);\n\n /**\n * Define the base handler that executes the tool.\n * When wrapToolCall middleware is present, this handler does NOT catch errors\n * so the middleware can handle them.\n * When no middleware, errors are caught and handled here.\n *\n * The handler now accepts an overridden tool from the request, allowing\n * middleware to provide tool implementations for dynamically registered tools.\n */\n const baseHandler = async (\n request: ToolCallRequest\n ): Promise<ToolMessage | Command> => {\n const { toolCall, tool: requestTool } = request;\n\n /**\n * Use the tool from the request (which may be overridden via spread syntax)\n * or fall back to finding it in registered tools.\n * This allows middleware to provide dynamic tool implementations.\n */\n const tool =\n requestTool ?? this.tools.find((t) => t.name === toolCall.name);\n\n if (tool === undefined) {\n /**\n * Tool not found - return a graceful error message rather than throwing.\n * This allows the LLM to see the error and potentially retry.\n */\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(toolCall.name, availableTools),\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n }\n\n /**\n * Cast tool to a common invokable type.\n * The tool can be from registered tools (StructuredToolInterface | DynamicTool | RunnableToolLike)\n * or from middleware override (ClientTool | ServerTool).\n */\n const invokableTool = tool as\n | StructuredToolInterface\n | DynamicTool\n | RunnableToolLike;\n\n try {\n const output = await invokableTool.invoke(\n { ...toolCall, type: \"tool_call\" },\n {\n ...config,\n /**\n * extend to match ToolRuntime\n */\n config,\n toolCallId: toolCall.id!,\n state: config.configurable?.__pregel_scratchpad?.currentTaskInput,\n signal: mergeAbortSignals(this.signal, config.signal),\n }\n );\n\n if (ToolMessage.isInstance(output) || isCommand(output)) {\n return output as ToolMessage | Command;\n }\n\n return new ToolMessage({\n name: invokableTool.name,\n content: typeof output === \"string\" ? output : JSON.stringify(output),\n tool_call_id: toolCall.id!,\n });\n } catch (e: unknown) {\n /**\n * Handle errors from tool execution (not from wrapToolCall)\n * If tool invocation fails due to input parsing error, throw a {@link ToolInvocationError}\n */\n if (e instanceof ToolInputParsingException) {\n throw new ToolInvocationError(e, toolCall);\n }\n /**\n * Re-throw to be handled by caller\n */\n throw e;\n }\n };\n\n /**\n * Create request object for middleware\n * Cast to ToolCallRequest<AgentBuiltInState> to satisfy type constraints\n * of wrapToolCall which expects AgentBuiltInState\n */\n const request: ToolCallRequest<AgentBuiltInState> = {\n toolCall: call,\n tool: registeredTool,\n state,\n runtime,\n };\n\n /**\n * If wrapToolCall is provided, use it to wrap the tool execution\n */\n if (this.wrapToolCall) {\n try {\n return await this.wrapToolCall(request, baseHandler);\n } catch (e: unknown) {\n /**\n * Handle middleware errors\n */\n return this.#handleError(e, call, true);\n }\n }\n\n /**\n * No wrapToolCall - if tool wasn't found, return graceful error\n */\n if (!registeredTool) {\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(call.name, availableTools),\n tool_call_id: call.id!,\n name: call.name,\n status: \"error\",\n });\n }\n\n /**\n * No wrapToolCall - execute tool directly and handle errors here\n */\n try {\n return await baseHandler(request);\n } catch (e: unknown) {\n /**\n * Handle tool errors when no middleware provided\n */\n return this.#handleError(e, call, false);\n }\n }\n\n protected async run(\n state: ToAnnotationRoot<StateSchema>[\"State\"] & AgentBuiltInState,\n config: RunnableConfig\n ): Promise<ContextSchema> {\n let outputs: (ToolMessage | Command)[];\n\n if (isSendInput(state)) {\n const { lg_tool_call: _, jumpTo: __, ...newState } = state;\n outputs = [await this.runTool(state.lg_tool_call, config, newState)];\n } else {\n let messages: BaseMessage[];\n if (isBaseMessageArray(state)) {\n messages = state;\n } else if (isMessagesState(state)) {\n messages = state.messages;\n } else {\n throw new Error(\n \"ToolNode only accepts BaseMessage[] or { messages: BaseMessage[] } as input.\"\n );\n }\n\n const toolMessageIds: Set<string> = new Set(\n messages\n .filter((msg) => msg.getType() === \"tool\")\n .map((msg) => (msg as ToolMessage).tool_call_id)\n );\n\n let aiMessage: AIMessage | undefined;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (AIMessage.isInstance(message)) {\n aiMessage = message;\n break;\n }\n }\n\n if (!AIMessage.isInstance(aiMessage)) {\n throw new Error(\"ToolNode only accepts AIMessages as input.\");\n }\n\n outputs = await Promise.all(\n aiMessage.tool_calls\n ?.filter((call) => call.id == null || !toolMessageIds.has(call.id))\n .map((call) => this.runTool(call, config, state)) ?? []\n );\n }\n\n // Preserve existing behavior for non-command tool outputs for backwards compatibility\n if (!outputs.some(isCommand)) {\n return (Array.isArray(state)\n ? outputs\n : { messages: outputs }) as unknown as ContextSchema;\n }\n\n // Handle mixed Command and non-Command outputs\n const combinedOutputs: (\n | { messages: BaseMessage[] }\n | BaseMessage[]\n | Command\n )[] = [];\n let parentCommand: Command | null = null;\n\n for (const output of outputs) {\n if (isCommand(output)) {\n if (\n output.graph === Command.PARENT &&\n Array.isArray(output.goto) &&\n output.goto.every((send) => isSend(send))\n ) {\n if (parentCommand) {\n (parentCommand.goto as Send[]).push(...(output.goto as Send[]));\n } else {\n parentCommand = new Command({\n graph: Command.PARENT,\n goto: output.goto,\n });\n }\n } else {\n combinedOutputs.push(output);\n }\n } else {\n combinedOutputs.push(\n Array.isArray(state) ? [output] : { messages: [output] }\n );\n }\n }\n\n if (parentCommand) {\n combinedOutputs.push(parentCommand);\n }\n\n return combinedOutputs as unknown as ContextSchema;\n }\n}\n\nexport function isSend(x: unknown): x is Send {\n return x instanceof Send;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ToolNode.js","names":[],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n/* oxlint-disable no-instanceof/no-instanceof */\nimport { BaseMessage, ToolMessage, AIMessage } from \"@langchain/core/messages\";\nimport { RunnableConfig, RunnableToolLike } from \"@langchain/core/runnables\";\nimport {\n DynamicTool,\n StructuredToolInterface,\n ToolInputParsingException,\n} from \"@langchain/core/tools\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport type { InteropZodObject } from \"@langchain/core/utils/types\";\nimport {\n isCommand,\n Command,\n Send,\n isGraphInterrupt,\n type LangGraphRunnableConfig,\n StateDefinitionInit,\n} from \"@langchain/langgraph\";\n\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport { mergeAbortSignals } from \"./utils.js\";\nimport { MiddlewareError, ToolInvocationError } from \"../errors.js\";\nimport type {\n WrapToolCallHook,\n ToolCallRequest,\n ToAnnotationRoot,\n} from \"../middleware/types.js\";\nimport type { AgentBuiltInState } from \"../runtime.js\";\n\n/**\n * Error message template for when middleware adds tools that can't be executed.\n * This happens when middleware modifies tools in wrapModelCall but doesn't provide\n * a wrapToolCall handler to execute them.\n */\nconst getInvalidToolError = (\n toolName: string,\n availableTools: string[]\n): string =>\n `Error: ${toolName} is not a valid tool, try one of [${availableTools.join(\", \")}].`;\n\n/**\n * The name of the tool node in the state graph.\n */\nexport const TOOLS_NODE_NAME = \"tools\";\n\nexport interface ToolNodeOptions {\n /**\n * The name of the tool node.\n */\n name?: string;\n /**\n * The tags to add to the tool call.\n */\n tags?: string[];\n /**\n * The abort signal to cancel the tool call.\n */\n signal?: AbortSignal;\n /**\n * Whether to throw the error immediately if the tool fails or handle it by the `onToolError` function or via ToolMessage.\n *\n * **Default behavior** (matches Python):\n * - Catches only `ToolInvocationError` (invalid arguments from model) and converts to ToolMessage\n * - Re-raises all other errors including errors from `wrapToolCall` middleware\n *\n * If `true`:\n * - Catches all errors and returns a ToolMessage with the error\n *\n * If `false`:\n * - All errors are thrown immediately\n *\n * If a function is provided:\n * - If function returns a `ToolMessage`, use it as the result\n * - If function returns `undefined`, re-raise the error\n *\n * @default A function that only catches ToolInvocationError\n */\n handleToolErrors?:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined);\n /**\n * Optional wrapper function for tool execution.\n * Allows middleware to intercept and modify tool calls before execution.\n * The wrapper receives the tool call request and a handler function to execute the tool.\n */\n wrapToolCall?: WrapToolCallHook;\n /** Graph channels to read for tool-call-only Send inputs. */\n stateKeys?: string[];\n}\n\nconst isBaseMessageArray = (input: unknown): input is BaseMessage[] =>\n Array.isArray(input) && input.every(BaseMessage.isInstance);\n\nconst isMessagesState = (\n input: unknown\n): input is { messages: BaseMessage[] } =>\n typeof input === \"object\" &&\n input != null &&\n \"messages\" in input &&\n isBaseMessageArray(input.messages);\n\nconst isSendInput = (\n input: unknown\n): input is { lg_tool_call: ToolCall; jumpTo?: string } =>\n typeof input === \"object\" && input != null && \"lg_tool_call\" in input;\n\n/**\n * Default error handler for tool errors.\n *\n * This is applied to errors from baseHandler (tool execution).\n * For errors from wrapToolCall middleware, those are handled separately\n * and will bubble up by default.\n *\n * Catches all tool execution errors and converts them to ToolMessage.\n * This allows the LLM to see the error and potentially retry with different arguments.\n */\nfunction defaultHandleToolErrors(\n error: unknown,\n toolCall: ToolCall\n): ToolMessage | undefined {\n if (ToolInvocationError.isInstance(error)) {\n return new ToolMessage({\n content: error.message,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n }\n /**\n * Catch all other tool errors and convert to ToolMessage\n */\n return new ToolMessage({\n content: `${error}\\n Please fix your mistakes.`,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n}\n\n/**\n * `ToolNode` is a built-in LangGraph component that handles tool calls within an agent's workflow.\n * It works seamlessly with `createAgent`, offering advanced tool execution control, built\n * in parallelism, and error handling.\n *\n * @example\n * ```ts\n * import { ToolNode, tool, AIMessage } from \"langchain\";\n * import { z } from \"zod/v3\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const toolNode = new ToolNode(tools);\n *\n * const messageWithSingleToolCall = new AIMessage({\n * content: \"\",\n * tool_calls: [\n * {\n * name: \"get_weather\",\n * args: { location: \"sf\" },\n * id: \"tool_call_id\",\n * type: \"tool_call\",\n * }\n * ]\n * })\n *\n * await toolNode.invoke({ messages: [messageWithSingleToolCall] });\n * // Returns tool invocation responses as:\n * // { messages: ToolMessage[] }\n * ```\n */\nexport class ToolNode<\n StateSchema extends StateDefinitionInit = any,\n ContextSchema extends InteropZodObject = any,\n> extends RunnableCallable<StateSchema, ContextSchema> {\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[];\n\n trace = false;\n\n signal?: AbortSignal;\n\n handleToolErrors:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined) =\n defaultHandleToolErrors;\n\n wrapToolCall: WrapToolCallHook | undefined;\n\n constructor(\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[],\n public options?: ToolNodeOptions\n ) {\n const { name, tags, handleToolErrors, signal, wrapToolCall } =\n options ?? {};\n super({\n name,\n tags,\n func: (state, config) =>\n this.run(\n state as ToAnnotationRoot<StateDefinitionInit>[\"State\"] &\n AgentBuiltInState,\n config as RunnableConfig\n ),\n });\n this.tools = tools;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n this.signal = signal;\n this.wrapToolCall = wrapToolCall;\n }\n\n /**\n * Handle errors from tool execution or middleware.\n * @param error - The error to handle\n * @param call - The tool call that caused the error\n * @param isMiddlewareError - Whether the error came from wrapToolCall middleware\n * @returns ToolMessage if error is handled, otherwise re-throws\n */\n #handleError(\n error: unknown,\n call: ToolCall,\n isMiddlewareError: boolean\n ): ToolMessage {\n /**\n * {@link NodeInterrupt} errors are a breakpoint to bring a human into the loop.\n * As such, they are not recoverable by the agent and shouldn't be fed\n * back. Instead, re-throw these errors even when `handleToolErrors = true`.\n */\n if (isGraphInterrupt(error)) {\n throw error;\n }\n\n /**\n * If the signal is aborted, we want to bubble up the error to the invoke caller.\n */\n if (this.signal?.aborted) {\n throw error;\n }\n\n /**\n * A recoverable tool error (e.g. tool-input schema validation) can be\n * rewrapped as a {@link MiddlewareError} with the original error on `.cause`\n * — once per `wrapToolCall` middleware, so it may be nested several layers\n * deep. Walk the cause chain to the root; if it's a {@link ToolInvocationError},\n * unwrap it so the intended `handleToolErrors` self-correction path still\n * applies. Genuine middleware errors stay fatal by default.\n */\n let effectiveError = error;\n let errorFromMiddleware = isMiddlewareError;\n if (isMiddlewareError) {\n let unwrapped: unknown = error;\n while (MiddlewareError.isInstance(unwrapped)) {\n unwrapped = unwrapped.cause;\n }\n if (ToolInvocationError.isInstance(unwrapped)) {\n effectiveError = unwrapped;\n errorFromMiddleware = false;\n }\n }\n\n /**\n * If error is from middleware and handleToolErrors is not true, bubble up\n * (default handler and false both re-raise middleware errors)\n */\n if (errorFromMiddleware && this.handleToolErrors !== true) {\n throw effectiveError;\n }\n\n /**\n * If handleToolErrors is false, throw all errors\n */\n if (!this.handleToolErrors) {\n throw effectiveError;\n }\n\n /**\n * Apply handleToolErrors to the error\n */\n if (typeof this.handleToolErrors === \"function\") {\n const result = this.handleToolErrors(effectiveError, call);\n if (result && ToolMessage.isInstance(result)) {\n result.status ??= \"error\";\n return result;\n }\n\n /**\n * `handleToolErrors` returned undefined - re-raise\n */\n throw effectiveError;\n } else if (this.handleToolErrors) {\n return new ToolMessage({\n name: call.name,\n content: `${effectiveError}\\n Please fix your mistakes.`,\n tool_call_id: call.id!,\n status: \"error\",\n });\n }\n\n /**\n * Shouldn't reach here, but throw as fallback\n */\n throw effectiveError;\n }\n\n protected async runTool(\n call: ToolCall,\n config: RunnableConfig,\n state: AgentBuiltInState\n ): Promise<ToolMessage | Command> {\n /**\n * Build runtime from LangGraph config\n */\n const lgConfig = config as LangGraphRunnableConfig;\n const runtime = {\n context: lgConfig?.context,\n store: lgConfig?.store,\n configurable: lgConfig?.configurable,\n writer: lgConfig?.writer,\n interrupt: lgConfig?.interrupt,\n signal: lgConfig?.signal,\n };\n\n /**\n * Find the tool instance to include in the request.\n * For dynamically registered tools, this may be undefined.\n */\n const registeredTool = this.tools.find((t) => t.name === call.name);\n\n /**\n * Define the base handler that executes the tool.\n * When wrapToolCall middleware is present, this handler does NOT catch errors\n * so the middleware can handle them.\n * When no middleware, errors are caught and handled here.\n *\n * The handler now accepts an overridden tool from the request, allowing\n * middleware to provide tool implementations for dynamically registered tools.\n */\n const baseHandler = async (\n request: ToolCallRequest\n ): Promise<ToolMessage | Command> => {\n const { toolCall, tool: requestTool } = request;\n\n /**\n * Use the tool from the request (which may be overridden via spread syntax)\n * or fall back to finding it in registered tools.\n * This allows middleware to provide dynamic tool implementations.\n */\n const tool =\n requestTool ?? this.tools.find((t) => t.name === toolCall.name);\n\n if (tool === undefined) {\n /**\n * Tool not found - return a graceful error message rather than throwing.\n * This allows the LLM to see the error and potentially retry.\n */\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(toolCall.name, availableTools),\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n }\n\n /**\n * Cast tool to a common invokable type.\n * The tool can be from registered tools (StructuredToolInterface | DynamicTool | RunnableToolLike)\n * or from middleware override (ClientTool | ServerTool).\n */\n const invokableTool = tool as\n | StructuredToolInterface\n | DynamicTool\n | RunnableToolLike;\n\n try {\n const output = await invokableTool.invoke(\n { ...toolCall, type: \"tool_call\" },\n {\n ...config,\n /**\n * extend to match ToolRuntime\n */\n config,\n toolCallId: toolCall.id!,\n state,\n signal: mergeAbortSignals(this.signal, config.signal),\n }\n );\n\n if (ToolMessage.isInstance(output) || isCommand(output)) {\n return output as ToolMessage | Command;\n }\n\n return new ToolMessage({\n name: invokableTool.name,\n content: typeof output === \"string\" ? output : JSON.stringify(output),\n tool_call_id: toolCall.id!,\n });\n } catch (e: unknown) {\n /**\n * Handle errors from tool execution (not from wrapToolCall)\n * If tool invocation fails due to input parsing error, throw a {@link ToolInvocationError}\n */\n if (e instanceof ToolInputParsingException) {\n throw new ToolInvocationError(e, toolCall);\n }\n /**\n * Re-throw to be handled by caller\n */\n throw e;\n }\n };\n\n /**\n * Create request object for middleware\n * Cast to ToolCallRequest<AgentBuiltInState> to satisfy type constraints\n * of wrapToolCall which expects AgentBuiltInState\n */\n const request: ToolCallRequest<AgentBuiltInState> = {\n toolCall: call,\n tool: registeredTool,\n state,\n runtime,\n };\n\n /**\n * If wrapToolCall is provided, use it to wrap the tool execution\n */\n if (this.wrapToolCall) {\n try {\n return await this.wrapToolCall(request, baseHandler);\n } catch (e: unknown) {\n /**\n * Handle middleware errors\n */\n return this.#handleError(e, call, true);\n }\n }\n\n /**\n * No wrapToolCall - if tool wasn't found, return graceful error\n */\n if (!registeredTool) {\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(call.name, availableTools),\n tool_call_id: call.id!,\n name: call.name,\n status: \"error\",\n });\n }\n\n /**\n * No wrapToolCall - execute tool directly and handle errors here\n */\n try {\n return await baseHandler(request);\n } catch (e: unknown) {\n /**\n * Handle tool errors when no middleware provided\n */\n return this.#handleError(e, call, false);\n }\n }\n\n protected async run(\n state: ToAnnotationRoot<StateSchema>[\"State\"] & AgentBuiltInState,\n config: RunnableConfig\n ): Promise<ContextSchema> {\n let outputs: (ToolMessage | Command)[];\n\n if (isSendInput(state)) {\n const { lg_tool_call: _, jumpTo: __, ...newState } = state;\n let toolState = newState;\n if (Object.keys(newState).length === 0 && this.options?.stateKeys) {\n const read = config.configurable?.__pregel_read;\n if (typeof read !== \"function\") {\n throw new Error(\n \"ToolNode requires a graph state reader for compact Send inputs.\"\n );\n }\n toolState = read(this.options.stateKeys, true);\n if (!isMessagesState(toolState)) {\n throw new Error(\"ToolNode could not read messages from graph state.\");\n }\n const scratchpad = config.configurable?.__pregel_scratchpad;\n if (scratchpad) {\n scratchpad.currentTaskInput = { ...toolState, ...state };\n }\n }\n outputs = [await this.runTool(state.lg_tool_call, config, toolState)];\n } else {\n let messages: BaseMessage[];\n if (isBaseMessageArray(state)) {\n messages = state;\n } else if (isMessagesState(state)) {\n messages = state.messages;\n } else {\n throw new Error(\n \"ToolNode only accepts BaseMessage[] or { messages: BaseMessage[] } as input.\"\n );\n }\n\n const toolMessageIds: Set<string> = new Set(\n messages\n .filter((msg) => msg.getType() === \"tool\")\n .map((msg) => (msg as ToolMessage).tool_call_id)\n );\n\n let aiMessage: AIMessage | undefined;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (AIMessage.isInstance(message)) {\n aiMessage = message;\n break;\n }\n }\n\n if (!AIMessage.isInstance(aiMessage)) {\n throw new Error(\"ToolNode only accepts AIMessages as input.\");\n }\n\n outputs = await Promise.all(\n aiMessage.tool_calls\n ?.filter((call) => call.id == null || !toolMessageIds.has(call.id))\n .map((call) => this.runTool(call, config, state)) ?? []\n );\n }\n\n // Preserve existing behavior for non-command tool outputs for backwards compatibility\n if (!outputs.some(isCommand)) {\n return (Array.isArray(state)\n ? outputs\n : { messages: outputs }) as unknown as ContextSchema;\n }\n\n // Handle mixed Command and non-Command outputs\n const combinedOutputs: (\n | { messages: BaseMessage[] }\n | BaseMessage[]\n | Command\n )[] = [];\n let parentCommand: Command | null = null;\n\n for (const output of outputs) {\n if (isCommand(output)) {\n if (\n output.graph === Command.PARENT &&\n Array.isArray(output.goto) &&\n output.goto.every((send) => isSend(send))\n ) {\n if (parentCommand) {\n (parentCommand.goto as Send[]).push(...(output.goto as Send[]));\n } else {\n parentCommand = new Command({\n graph: Command.PARENT,\n goto: output.goto,\n });\n }\n } else {\n combinedOutputs.push(output);\n }\n } else {\n combinedOutputs.push(\n Array.isArray(state) ? [output] : { messages: [output] }\n );\n }\n }\n\n if (parentCommand) {\n combinedOutputs.push(parentCommand);\n }\n\n return combinedOutputs as unknown as ContextSchema;\n }\n}\n\nexport function isSend(x: unknown): x is Send {\n return x instanceof Send;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","names":["BaseChatModel","RunnableLambda","HumanMessage","AIMessage"],"sources":["../../../src/agents/tests/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n BaseChatModel,\n BaseChatModelParams,\n BaseChatModelCallOptions,\n BindToolsInput,\n ToolChoice,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport { StructuredTool } from \"@langchain/core/tools\";\nimport {\n BaseMessage,\n AIMessage,\n HumanMessage,\n BaseMessageFields,\n AIMessageFields,\n ToolMessage,\n ToolMessageFields,\n} from \"@langchain/core/messages\";\nimport { ChatResult } from \"@langchain/core/outputs\";\nimport {\n Runnable,\n RunnableConfig,\n RunnableLambda,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport {\n MemorySaver,\n Checkpoint,\n CheckpointMetadata,\n type BaseCheckpointSaver,\n} from \"@langchain/langgraph-checkpoint\";\nimport { LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { z } from \"zod/v3\";\n\n/**\n * Custom asymmetric matcher that matches any string value.\n * Works with both Jest and Vitest's toEqual() assertions.\n */\nclass AnyString {\n asymmetricMatch(other: unknown): boolean {\n return typeof other === \"string\";\n }\n\n toString(): string {\n return \"Any<String>\";\n }\n\n toAsymmetricMatcher(): string {\n return \"Any<String>\";\n }\n}\n\nexport class _AnyIdAIMessage extends AIMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"AIMessage\"];\n }\n\n constructor(fields: AIMessageFields | string) {\n let fieldsWithJestMatcher: Partial<AIMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as AIMessageFields);\n }\n}\n\nexport class _AnyIdHumanMessage extends HumanMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"HumanMessage\"];\n }\n\n constructor(fields: BaseMessageFields | string) {\n let fieldsWithJestMatcher: Partial<BaseMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as BaseMessageFields);\n }\n}\n\nexport class _AnyIdToolMessage extends ToolMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"ToolMessage\"];\n }\n\n constructor(fields: ToolMessageFields) {\n const fieldsWithJestMatcher: Partial<ToolMessageFields> = {\n id: new AnyString() as unknown as string,\n ...fields,\n };\n super(fieldsWithJestMatcher as ToolMessageFields);\n }\n}\n\nexport class FakeConfigurableModel extends BaseChatModel {\n _queuedMethodOperations: Record<string, any> = {};\n\n _chatModel: LanguageModelLike;\n\n constructor(\n fields: {\n model: LanguageModelLike;\n } & BaseChatModelParams\n ) {\n super(fields);\n this._chatModel = fields.model;\n }\n\n _llmType() {\n return \"fake_configurable\";\n }\n\n async _generate(\n _messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n throw new Error(\"Not implemented\");\n }\n\n async _model() {\n return this._chatModel;\n }\n\n bindTools(tools: BindToolsInput[]) {\n const modelWithTools = new FakeConfigurableModel({\n model: (this._chatModel as FakeToolCallingChatModel).bindTools(tools),\n });\n modelWithTools._queuedMethodOperations.bindTools = tools;\n return modelWithTools;\n }\n}\n\nexport class FakeToolCallingChatModel extends BaseChatModel {\n sleep?: number = 50;\n\n responses?: BaseMessage[];\n\n thrownErrorString?: string;\n\n idx: number;\n\n toolStyle: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\" = \"openai\";\n\n structuredResponse?: Record<string, unknown>;\n\n // Track messages passed to structured output calls\n structuredOutputMessages: BaseMessage[][] = [];\n\n constructor(\n fields: {\n sleep?: number;\n responses?: BaseMessage[];\n thrownErrorString?: string;\n toolStyle?: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\";\n structuredResponse?: Record<string, unknown>;\n } & BaseChatModelParams\n ) {\n super(fields);\n this.sleep = fields.sleep ?? this.sleep;\n this.responses = fields.responses;\n this.thrownErrorString = fields.thrownErrorString;\n this.idx = 0;\n this.toolStyle = fields.toolStyle ?? this.toolStyle;\n this.structuredResponse = fields.structuredResponse;\n this.structuredOutputMessages = [];\n }\n\n _llmType() {\n return \"fake\";\n }\n\n get profile(): ModelProfile {\n return {\n toolCalling: true,\n structuredOutput: true,\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.thrownErrorString) {\n throw new Error(this.thrownErrorString);\n }\n if (this.sleep !== undefined) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n const responses = this.responses?.length ? this.responses : messages;\n const msg = responses[this.idx % responses.length];\n const generation: ChatResult = {\n generations: [\n {\n text: \"\",\n message: msg,\n },\n ],\n };\n this.idx += 1;\n\n if (typeof msg.content === \"string\") {\n await runManager?.handleLLMNewToken(msg.content);\n }\n return generation;\n }\n\n bindTools(tools: BindToolsInput[]): Runnable<any> {\n const toolDicts = [];\n const serverTools = [];\n for (const tool of tools) {\n if (!(\"name\" in tool)) {\n serverTools.push(tool);\n continue;\n }\n\n // NOTE: this is a simplified tool spec for testing purposes only\n if (this.toolStyle === \"openai\") {\n toolDicts.push({\n type: \"function\",\n function: {\n name: tool.name,\n },\n });\n } else if ([\"anthropic\", \"google\"].includes(this.toolStyle)) {\n toolDicts.push({\n name: tool.name,\n });\n } else if (this.toolStyle === \"bedrock\") {\n toolDicts.push({\n toolSpec: {\n name: tool.name,\n },\n });\n }\n }\n let toolsToBind: BindToolsInput[] = toolDicts;\n if (this.toolStyle === \"google\") {\n toolsToBind = [{ functionDeclarations: toolDicts }];\n }\n return this.withConfig({\n tools: [...toolsToBind, ...serverTools],\n } as BaseChatModelCallOptions);\n }\n\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(_: unknown): Runnable<any> {\n if (!this.structuredResponse) {\n throw new Error(\"No structured response provided\");\n }\n // Create a runnable that returns the proper structured format\n return RunnableLambda.from(async (messages: BaseMessage[]) => {\n if (this.sleep) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n\n // Store the messages that were sent to generate structured output\n this.structuredOutputMessages.push([...messages]);\n\n // Return in the format expected: { raw: BaseMessage, parsed: RunOutput }\n return this.structuredResponse as RunOutput;\n });\n }\n}\n\nexport class MemorySaverAssertImmutable extends MemorySaver {\n storageForCopies: Record<string, Record<string, Uint8Array>> = {};\n\n constructor() {\n super();\n this.storageForCopies = {};\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata\n ): Promise<RunnableConfig> {\n const thread_id = config.configurable?.thread_id;\n this.storageForCopies[thread_id] ??= {};\n\n // assert checkpoint hasn't been modified since last written\n const saved = await this.get(config);\n if (saved) {\n const savedId = saved.id;\n if (this.storageForCopies[thread_id][savedId]) {\n const [, serializedSaved] = await this.serde.dumpsTyped(saved);\n const serializedCopy = this.storageForCopies[thread_id][savedId];\n\n // Compare Uint8Array contents by converting to string\n const savedStr = new TextDecoder().decode(serializedSaved);\n const copyStr = new TextDecoder().decode(serializedCopy);\n if (savedStr !== copyStr) {\n throw new Error(\n `Checkpoint [${savedId}] has been modified since last written`\n );\n }\n }\n }\n const [, serializedCheckpoint] = await this.serde.dumpsTyped(checkpoint);\n // save a copy of the checkpoint\n this.storageForCopies[thread_id][checkpoint.id] = serializedCheckpoint;\n\n return super.put(config, checkpoint, metadata);\n }\n}\n\ninterface ToolCall {\n name: string;\n args: Record<string, any>;\n id: string;\n type?: \"tool_call\";\n}\n\ninterface FakeToolCallingModelFields {\n toolCalls?: ToolCall[][];\n toolStyle?: \"openai\" | \"anthropic\";\n index?: number;\n structuredResponse?: any;\n}\n\n// Helper function to create checkpointer\nexport function createCheckpointer(): BaseCheckpointSaver {\n return new MemorySaver();\n}\n\n/**\n * Fake chat model for testing tool calling functionality\n */\nexport class FakeToolCallingModel extends BaseChatModel {\n toolCalls: ToolCall[][];\n\n toolStyle: \"openai\" | \"anthropic\";\n\n // Use a shared reference object so the index persists across bindTools calls\n private indexRef: { current: number };\n\n structuredResponse?: any;\n\n private tools: StructuredTool[] = [];\n\n constructor({\n toolCalls = [],\n toolStyle = \"openai\",\n index = 0,\n structuredResponse,\n indexRef,\n ...rest\n }: FakeToolCallingModelFields & { indexRef?: { current: number } } = {}) {\n super(rest);\n this.toolCalls = toolCalls;\n this.toolStyle = toolStyle;\n // Share the same index reference across instances\n this.indexRef = indexRef ?? { current: index };\n this.structuredResponse = structuredResponse;\n }\n\n // Getter/setter for backwards compatibility\n get index(): number {\n return this.indexRef.current;\n }\n\n set index(value: number) {\n this.indexRef.current = value;\n }\n\n _llmType(): string {\n return \"fake-tool-calling\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n bindTools(\n tools: StructuredTool[]\n ):\n | FakeToolCallingModel\n | RunnableBinding<\n any,\n any,\n any & { tool_choice?: ToolChoice | undefined }\n > {\n const newInstance = new FakeToolCallingModel({\n toolCalls: this.toolCalls,\n toolStyle: this.toolStyle,\n structuredResponse: this.structuredResponse,\n // Pass the same indexRef so all instances share the same index state\n indexRef: this.indexRef,\n });\n newInstance.tools = [...this.tools, ...tools];\n return newInstance;\n }\n\n withStructuredOutput(_schema: any) {\n return new RunnableLambda({\n func: async () => {\n return this.structuredResponse;\n },\n });\n }\n\n async _generate(\n messages: BaseMessage[],\n _options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const lastMessage = messages[messages.length - 1];\n let content = lastMessage.content as string;\n\n // Handle prompt concatenation\n if (messages.length > 1) {\n const parts = messages.map((m) => m.content).filter(Boolean);\n content = parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n } else if (typeof part === \"object\" && \"text\" in part) {\n return part.text;\n } else if (Array.isArray(part)) {\n return part\n .map((p) => {\n if (typeof p === \"string\") {\n return p;\n } else if (typeof p === \"object\" && \"text\" in p) {\n return p.text;\n }\n return \"\";\n })\n .join(\"-\");\n } else {\n return JSON.stringify(part);\n }\n })\n .join(\"-\");\n }\n\n // Reset index at the start of a new conversation (only human message)\n // This allows the model to be reused across multiple agent.invoke() calls\n const isStartOfConversation =\n messages.length === 1 ||\n (messages.length === 2 && messages.every(HumanMessage.isInstance));\n if (isStartOfConversation && this.index !== 0) {\n this.index = 0;\n }\n\n const currentToolCalls = this.toolCalls[this.index] || [];\n const messageId = this.index.toString();\n\n // Move to next set of tool calls for subsequent invocations\n this.index = (this.index + 1) % Math.max(1, this.toolCalls.length);\n\n const message = new AIMessage({\n content,\n id: messageId,\n tool_calls:\n currentToolCalls.length > 0\n ? currentToolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [\n {\n text: content,\n message,\n },\n ],\n llmOutput: {},\n };\n }\n}\n\nexport class SearchAPI extends StructuredTool {\n name = \"search_api\";\n\n description = \"A simple API that returns the input string.\";\n\n schema = z.object({\n query: z.string().describe(\"The query to search for.\"),\n });\n\n async _call(input: z.infer<typeof this.schema>) {\n if (input?.query === \"error\") {\n throw new Error(\"Error\");\n }\n return `result for ${input?.query}`;\n }\n}\n\nexport async function collectV3Messages(\n messages: AsyncIterable<any>\n): Promise<{ texts: string[]; deltaCount: number }> {\n const texts: string[] = [];\n let deltaCount = 0;\n for await (const stream of messages) {\n let text = \"\";\n for await (const event of stream) {\n if (event.event === \"content-block-delta\") {\n deltaCount += 1;\n text += event.delta?.text ?? \"\";\n }\n if (event.event === \"content-block-start\") {\n text += (event.contentBlock ?? event.content_block)?.text ?? \"\";\n }\n }\n texts.push(text);\n }\n return { texts, deltaCount };\n}\n\nexport async function collectClassicMessages(\n agent: any,\n input: any\n): Promise<{ model: string[]; tools: string[] }> {\n const model: string[] = [];\n const tools: string[] = [];\n for await (const chunk of await agent.stream(input, {\n streamMode: \"messages\",\n })) {\n const message = chunk[0];\n const text = typeof message?.content === \"string\" ? message.content : \"\";\n if (!text) continue;\n if (message.getType?.() === \"tool\") tools.push(text);\n else model.push(text);\n }\n return { model, tools };\n}\n"],"mappings":";;;;;;;;;;AAiWA,IAAa,uBAAb,MAAa,6BAA6BA,4CAAAA,cAAc;CACtD;CAEA;CAGA;CAEA;CAEA,QAAkC,CAAC;CAEnC,YAAY,EACV,YAAY,CAAC,GACb,YAAY,UACZ,QAAQ,GACR,oBACA,UACA,GAAG,SACgE,CAAC,GAAG;EACvE,MAAM,IAAI;EACV,KAAK,YAAY;EACjB,KAAK,YAAY;EAEjB,KAAK,WAAW,YAAY,EAAE,SAAS,MAAM;EAC7C,KAAK,qBAAqB;CAC5B;CAGA,IAAI,QAAgB;EAClB,OAAO,KAAK,SAAS;CACvB;CAEA,IAAI,MAAM,OAAe;EACvB,KAAK,SAAS,UAAU;CAC1B;CAEA,WAAmB;EACjB,OAAO;CACT;CAEA,oBAAoB;EAClB,OAAO,CAAC;CACV;CAEA,UACE,OAOI;EACJ,MAAM,cAAc,IAAI,qBAAqB;GAC3C,WAAW,KAAK;GAChB,WAAW,KAAK;GAChB,oBAAoB,KAAK;GAEzB,UAAU,KAAK;EACjB,CAAC;EACD,YAAY,QAAQ,CAAC,GAAG,KAAK,OAAO,GAAG,KAAK;EAC5C,OAAO;CACT;CAEA,qBAAqB,SAAc;EACjC,OAAO,IAAIC,0BAAAA,eAAe,EACxB,MAAM,YAAY;GAChB,OAAO,KAAK;EACd,EACF,CAAC;CACH;CAEA,MAAM,UACJ,UACA,UACA,aACqB;EAErB,IAAI,UADgB,SAAS,SAAS,SAAS,EACtB,CAAC;EAG1B,IAAI,SAAS,SAAS,GAEpB,UADc,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,OACtC,CAAC,CACZ,KAAK,SAAS;GACb,IAAI,OAAO,SAAS,UAClB,OAAO;QACF,IAAI,OAAO,SAAS,YAAY,UAAU,MAC/C,OAAO,KAAK;QACP,IAAI,MAAM,QAAQ,IAAI,GAC3B,OAAO,KACJ,KAAK,MAAM;IACV,IAAI,OAAO,MAAM,UACf,OAAO;SACF,IAAI,OAAO,MAAM,YAAY,UAAU,GAC5C,OAAO,EAAE;IAEX,OAAO;GACT,CAAC,CAAC,CACD,KAAK,GAAG;QAEX,OAAO,KAAK,UAAU,IAAI;EAE9B,CAAC,CAAC,CACD,KAAK,GAAG;EAQb,KAFE,SAAS,WAAW,KACnB,SAAS,WAAW,KAAK,SAAS,MAAMC,yBAAAA,aAAa,UAAU,MACrC,KAAK,UAAU,GAC1C,KAAK,QAAQ;EAGf,MAAM,mBAAmB,KAAK,UAAU,KAAK,UAAU,CAAC;EACxD,MAAM,YAAY,KAAK,MAAM,SAAS;EAGtC,KAAK,SAAS,KAAK,QAAQ,KAAK,KAAK,IAAI,GAAG,KAAK,UAAU,MAAM;EAEjE,MAAM,UAAU,IAAIC,yBAAAA,UAAU;GAC5B;GACA,IAAI;GACJ,YACE,iBAAiB,SAAS,IACtB,iBAAiB,KAAK,QAAQ;IAC5B,GAAG;IACH,MAAM;GACR,EAAE,IACF,KAAA;EACR,CAAC;EAED,OAAO;GACL,aAAa,CACX;IACE,MAAM;IACN;GACF,CACF;GACA,WAAW,CAAC;EACd;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["BaseChatModel","RunnableLambda","HumanMessage","AIMessage"],"sources":["../../../src/agents/tests/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n BaseChatModel,\n BaseChatModelParams,\n BaseChatModelCallOptions,\n BindToolsInput,\n ToolChoice,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport { StructuredTool } from \"@langchain/core/tools\";\nimport {\n BaseMessage,\n AIMessage,\n HumanMessage,\n BaseMessageFields,\n AIMessageFields,\n ToolMessage,\n ToolMessageFields,\n} from \"@langchain/core/messages\";\nimport { ChatResult } from \"@langchain/core/outputs\";\nimport {\n Runnable,\n RunnableConfig,\n RunnableLambda,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport {\n MemorySaver,\n Checkpoint,\n CheckpointMetadata,\n type BaseCheckpointSaver,\n} from \"@langchain/langgraph-checkpoint\";\nimport { LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { z } from \"zod/v3\";\n\n/**\n * Custom asymmetric matcher that matches any string value.\n * Works with both Jest and Vitest's toEqual() assertions.\n */\nclass AnyString {\n asymmetricMatch(other: unknown): boolean {\n return typeof other === \"string\";\n }\n\n toString(): string {\n return \"Any<String>\";\n }\n\n toAsymmetricMatcher(): string {\n return \"Any<String>\";\n }\n}\n\nexport class _AnyIdAIMessage extends AIMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"AIMessage\"];\n }\n\n constructor(fields: AIMessageFields | string) {\n let fieldsWithJestMatcher: Partial<AIMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as AIMessageFields);\n }\n}\n\nexport class _AnyIdHumanMessage extends HumanMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"HumanMessage\"];\n }\n\n constructor(fields: BaseMessageFields | string) {\n let fieldsWithJestMatcher: Partial<BaseMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as BaseMessageFields);\n }\n}\n\nexport class _AnyIdToolMessage extends ToolMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"ToolMessage\"];\n }\n\n constructor(fields: ToolMessageFields) {\n const fieldsWithJestMatcher: Partial<ToolMessageFields> = {\n id: new AnyString() as unknown as string,\n ...fields,\n };\n super(fieldsWithJestMatcher as ToolMessageFields);\n }\n}\n\nexport class FakeConfigurableModel extends BaseChatModel {\n _queuedMethodOperations: Record<string, any> = {};\n\n _chatModel: LanguageModelLike;\n\n constructor(\n fields: {\n model: LanguageModelLike;\n } & BaseChatModelParams\n ) {\n super(fields);\n this._chatModel = fields.model;\n }\n\n _llmType() {\n return \"fake_configurable\";\n }\n\n async _generate(\n _messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n throw new Error(\"Not implemented\");\n }\n\n async _model() {\n return this._chatModel;\n }\n\n bindTools(tools: BindToolsInput[]) {\n const modelWithTools = new FakeConfigurableModel({\n model: (this._chatModel as FakeToolCallingChatModel).bindTools(tools),\n });\n modelWithTools._queuedMethodOperations.bindTools = tools;\n return modelWithTools;\n }\n}\n\nexport class FakeToolCallingChatModel extends BaseChatModel {\n sleep?: number = 50;\n\n responses?: BaseMessage[];\n\n thrownErrorString?: string;\n\n idx: number;\n\n toolStyle: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\" = \"openai\";\n\n structuredResponse?: Record<string, unknown>;\n\n // Track messages passed to structured output calls\n structuredOutputMessages: BaseMessage[][] = [];\n\n constructor(\n fields: {\n sleep?: number;\n responses?: BaseMessage[];\n thrownErrorString?: string;\n toolStyle?: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\";\n structuredResponse?: Record<string, unknown>;\n } & BaseChatModelParams\n ) {\n super(fields);\n this.sleep = fields.sleep ?? this.sleep;\n this.responses = fields.responses;\n this.thrownErrorString = fields.thrownErrorString;\n this.idx = 0;\n this.toolStyle = fields.toolStyle ?? this.toolStyle;\n this.structuredResponse = fields.structuredResponse;\n this.structuredOutputMessages = [];\n }\n\n _llmType() {\n return \"fake\";\n }\n\n get profile(): ModelProfile {\n return {\n toolCalling: true,\n structuredOutput: true,\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.thrownErrorString) {\n throw new Error(this.thrownErrorString);\n }\n if (this.sleep !== undefined) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n const responses = this.responses?.length ? this.responses : messages;\n const msg = responses[this.idx % responses.length];\n const generation: ChatResult = {\n generations: [\n {\n text: \"\",\n message: msg,\n },\n ],\n };\n this.idx += 1;\n\n if (typeof msg.content === \"string\") {\n await runManager?.handleLLMNewToken(msg.content);\n }\n return generation;\n }\n\n bindTools(tools: BindToolsInput[]): Runnable<any> {\n const toolDicts = [];\n const serverTools = [];\n for (const tool of tools) {\n if (!(\"name\" in tool)) {\n serverTools.push(tool);\n continue;\n }\n\n // NOTE: this is a simplified tool spec for testing purposes only\n if (this.toolStyle === \"openai\") {\n toolDicts.push({\n type: \"function\",\n function: {\n name: tool.name,\n },\n });\n } else if ([\"anthropic\", \"google\"].includes(this.toolStyle)) {\n toolDicts.push({\n name: tool.name,\n });\n } else if (this.toolStyle === \"bedrock\") {\n toolDicts.push({\n toolSpec: {\n name: tool.name,\n },\n });\n }\n }\n let toolsToBind: BindToolsInput[] = toolDicts;\n if (this.toolStyle === \"google\") {\n toolsToBind = [{ functionDeclarations: toolDicts }];\n }\n return this.withConfig({\n tools: [...toolsToBind, ...serverTools],\n } as BaseChatModelCallOptions);\n }\n\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(_: unknown): Runnable<any> {\n if (!this.structuredResponse) {\n throw new Error(\"No structured response provided\");\n }\n // Create a runnable that returns the proper structured format\n return RunnableLambda.from(async (messages: BaseMessage[]) => {\n if (this.sleep) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n\n // Store the messages that were sent to generate structured output\n this.structuredOutputMessages.push([...messages]);\n\n // Return in the format expected: { raw: BaseMessage, parsed: RunOutput }\n return this.structuredResponse as RunOutput;\n });\n }\n}\n\nexport class MemorySaverAssertImmutable extends MemorySaver {\n storageForCopies: Record<string, Record<string, Uint8Array>> = {};\n\n constructor() {\n super();\n this.storageForCopies = {};\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata\n ): Promise<RunnableConfig> {\n const thread_id = config.configurable?.thread_id;\n this.storageForCopies[thread_id] ??= {};\n\n // assert checkpoint hasn't been modified since last written\n const saved = await this.get(config);\n if (saved) {\n const savedId = saved.id;\n if (this.storageForCopies[thread_id][savedId]) {\n const [, serializedSaved] = await this.serde.dumpsTyped(saved);\n const serializedCopy = this.storageForCopies[thread_id][savedId];\n\n // Compare Uint8Array contents by converting to string\n const savedStr = new TextDecoder().decode(serializedSaved);\n const copyStr = new TextDecoder().decode(serializedCopy);\n if (savedStr !== copyStr) {\n throw new Error(\n `Checkpoint [${savedId}] has been modified since last written`\n );\n }\n }\n }\n const [, serializedCheckpoint] = await this.serde.dumpsTyped(checkpoint);\n // save a copy of the checkpoint\n this.storageForCopies[thread_id][checkpoint.id] = serializedCheckpoint;\n\n return super.put(config, checkpoint, metadata);\n }\n}\n\ninterface ToolCall {\n name: string;\n args: Record<string, any>;\n id?: string;\n type?: \"tool_call\";\n}\n\ninterface FakeToolCallingModelFields {\n toolCalls?: ToolCall[][];\n toolStyle?: \"openai\" | \"anthropic\";\n index?: number;\n structuredResponse?: any;\n}\n\n// Helper function to create checkpointer\nexport function createCheckpointer(): BaseCheckpointSaver {\n return new MemorySaver();\n}\n\n/**\n * Fake chat model for testing tool calling functionality\n */\nexport class FakeToolCallingModel extends BaseChatModel {\n toolCalls: ToolCall[][];\n\n toolStyle: \"openai\" | \"anthropic\";\n\n // Use a shared reference object so the index persists across bindTools calls\n private indexRef: { current: number };\n\n structuredResponse?: any;\n\n private tools: StructuredTool[] = [];\n\n constructor({\n toolCalls = [],\n toolStyle = \"openai\",\n index = 0,\n structuredResponse,\n indexRef,\n ...rest\n }: FakeToolCallingModelFields & { indexRef?: { current: number } } = {}) {\n super(rest);\n this.toolCalls = toolCalls;\n this.toolStyle = toolStyle;\n // Share the same index reference across instances\n this.indexRef = indexRef ?? { current: index };\n this.structuredResponse = structuredResponse;\n }\n\n // Getter/setter for backwards compatibility\n get index(): number {\n return this.indexRef.current;\n }\n\n set index(value: number) {\n this.indexRef.current = value;\n }\n\n _llmType(): string {\n return \"fake-tool-calling\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n bindTools(\n tools: StructuredTool[]\n ):\n | FakeToolCallingModel\n | RunnableBinding<\n any,\n any,\n any & { tool_choice?: ToolChoice | undefined }\n > {\n const newInstance = new FakeToolCallingModel({\n toolCalls: this.toolCalls,\n toolStyle: this.toolStyle,\n structuredResponse: this.structuredResponse,\n // Pass the same indexRef so all instances share the same index state\n indexRef: this.indexRef,\n });\n newInstance.tools = [...this.tools, ...tools];\n return newInstance;\n }\n\n withStructuredOutput(_schema: any) {\n return new RunnableLambda({\n func: async () => {\n return this.structuredResponse;\n },\n });\n }\n\n async _generate(\n messages: BaseMessage[],\n _options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const lastMessage = messages[messages.length - 1];\n let content = lastMessage.content as string;\n\n // Handle prompt concatenation\n if (messages.length > 1) {\n const parts = messages.map((m) => m.content).filter(Boolean);\n content = parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n } else if (typeof part === \"object\" && \"text\" in part) {\n return part.text;\n } else if (Array.isArray(part)) {\n return part\n .map((p) => {\n if (typeof p === \"string\") {\n return p;\n } else if (typeof p === \"object\" && \"text\" in p) {\n return p.text;\n }\n return \"\";\n })\n .join(\"-\");\n } else {\n return JSON.stringify(part);\n }\n })\n .join(\"-\");\n }\n\n // Reset index at the start of a new conversation (only human message)\n // This allows the model to be reused across multiple agent.invoke() calls\n const isStartOfConversation =\n messages.length === 1 ||\n (messages.length === 2 && messages.every(HumanMessage.isInstance));\n if (isStartOfConversation && this.index !== 0) {\n this.index = 0;\n }\n\n const currentToolCalls = this.toolCalls[this.index] || [];\n const messageId = this.index.toString();\n\n // Move to next set of tool calls for subsequent invocations\n this.index = (this.index + 1) % Math.max(1, this.toolCalls.length);\n\n const message = new AIMessage({\n content,\n id: messageId,\n tool_calls:\n currentToolCalls.length > 0\n ? currentToolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [\n {\n text: content,\n message,\n },\n ],\n llmOutput: {},\n };\n }\n}\n\nexport class SearchAPI extends StructuredTool {\n name = \"search_api\";\n\n description = \"A simple API that returns the input string.\";\n\n schema = z.object({\n query: z.string().describe(\"The query to search for.\"),\n });\n\n async _call(input: z.infer<typeof this.schema>) {\n if (input?.query === \"error\") {\n throw new Error(\"Error\");\n }\n return `result for ${input?.query}`;\n }\n}\n\nexport async function collectV3Messages(\n messages: AsyncIterable<any>\n): Promise<{ texts: string[]; deltaCount: number }> {\n const texts: string[] = [];\n let deltaCount = 0;\n for await (const stream of messages) {\n let text = \"\";\n for await (const event of stream) {\n if (event.event === \"content-block-delta\") {\n deltaCount += 1;\n text += event.delta?.text ?? \"\";\n }\n if (event.event === \"content-block-start\") {\n text += (event.contentBlock ?? event.content_block)?.text ?? \"\";\n }\n }\n texts.push(text);\n }\n return { texts, deltaCount };\n}\n\nexport async function collectClassicMessages(\n agent: any,\n input: any\n): Promise<{ model: string[]; tools: string[] }> {\n const model: string[] = [];\n const tools: string[] = [];\n for await (const chunk of await agent.stream(input, {\n streamMode: \"messages\",\n })) {\n const message = chunk[0];\n const text = typeof message?.content === \"string\" ? message.content : \"\";\n if (!text) continue;\n if (message.getType?.() === \"tool\") tools.push(text);\n else model.push(text);\n }\n return { model, tools };\n}\n"],"mappings":";;;;;;;;;;AAiWA,IAAa,uBAAb,MAAa,6BAA6BA,4CAAAA,cAAc;CACtD;CAEA;CAGA;CAEA;CAEA,QAAkC,CAAC;CAEnC,YAAY,EACV,YAAY,CAAC,GACb,YAAY,UACZ,QAAQ,GACR,oBACA,UACA,GAAG,SACgE,CAAC,GAAG;EACvE,MAAM,IAAI;EACV,KAAK,YAAY;EACjB,KAAK,YAAY;EAEjB,KAAK,WAAW,YAAY,EAAE,SAAS,MAAM;EAC7C,KAAK,qBAAqB;CAC5B;CAGA,IAAI,QAAgB;EAClB,OAAO,KAAK,SAAS;CACvB;CAEA,IAAI,MAAM,OAAe;EACvB,KAAK,SAAS,UAAU;CAC1B;CAEA,WAAmB;EACjB,OAAO;CACT;CAEA,oBAAoB;EAClB,OAAO,CAAC;CACV;CAEA,UACE,OAOI;EACJ,MAAM,cAAc,IAAI,qBAAqB;GAC3C,WAAW,KAAK;GAChB,WAAW,KAAK;GAChB,oBAAoB,KAAK;GAEzB,UAAU,KAAK;EACjB,CAAC;EACD,YAAY,QAAQ,CAAC,GAAG,KAAK,OAAO,GAAG,KAAK;EAC5C,OAAO;CACT;CAEA,qBAAqB,SAAc;EACjC,OAAO,IAAIC,0BAAAA,eAAe,EACxB,MAAM,YAAY;GAChB,OAAO,KAAK;EACd,EACF,CAAC;CACH;CAEA,MAAM,UACJ,UACA,UACA,aACqB;EAErB,IAAI,UADgB,SAAS,SAAS,SAAS,EACtB,CAAC;EAG1B,IAAI,SAAS,SAAS,GAEpB,UADc,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,OACtC,CAAC,CACZ,KAAK,SAAS;GACb,IAAI,OAAO,SAAS,UAClB,OAAO;QACF,IAAI,OAAO,SAAS,YAAY,UAAU,MAC/C,OAAO,KAAK;QACP,IAAI,MAAM,QAAQ,IAAI,GAC3B,OAAO,KACJ,KAAK,MAAM;IACV,IAAI,OAAO,MAAM,UACf,OAAO;SACF,IAAI,OAAO,MAAM,YAAY,UAAU,GAC5C,OAAO,EAAE;IAEX,OAAO;GACT,CAAC,CAAC,CACD,KAAK,GAAG;QAEX,OAAO,KAAK,UAAU,IAAI;EAE9B,CAAC,CAAC,CACD,KAAK,GAAG;EAQb,KAFE,SAAS,WAAW,KACnB,SAAS,WAAW,KAAK,SAAS,MAAMC,yBAAAA,aAAa,UAAU,MACrC,KAAK,UAAU,GAC1C,KAAK,QAAQ;EAGf,MAAM,mBAAmB,KAAK,UAAU,KAAK,UAAU,CAAC;EACxD,MAAM,YAAY,KAAK,MAAM,SAAS;EAGtC,KAAK,SAAS,KAAK,QAAQ,KAAK,KAAK,IAAI,GAAG,KAAK,UAAU,MAAM;EAEjE,MAAM,UAAU,IAAIC,yBAAAA,UAAU;GAC5B;GACA,IAAI;GACJ,YACE,iBAAiB,SAAS,IACtB,iBAAiB,KAAK,QAAQ;IAC5B,GAAG;IACH,MAAM;GACR,EAAE,IACF,KAAA;EACR,CAAC;EAED,OAAO;GACL,aAAa,CACX;IACE,MAAM;IACN;GACF,CACF;GACA,WAAW,CAAC;EACd;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/agents/tests/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n BaseChatModel,\n BaseChatModelParams,\n BaseChatModelCallOptions,\n BindToolsInput,\n ToolChoice,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport { StructuredTool } from \"@langchain/core/tools\";\nimport {\n BaseMessage,\n AIMessage,\n HumanMessage,\n BaseMessageFields,\n AIMessageFields,\n ToolMessage,\n ToolMessageFields,\n} from \"@langchain/core/messages\";\nimport { ChatResult } from \"@langchain/core/outputs\";\nimport {\n Runnable,\n RunnableConfig,\n RunnableLambda,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport {\n MemorySaver,\n Checkpoint,\n CheckpointMetadata,\n type BaseCheckpointSaver,\n} from \"@langchain/langgraph-checkpoint\";\nimport { LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { z } from \"zod/v3\";\n\n/**\n * Custom asymmetric matcher that matches any string value.\n * Works with both Jest and Vitest's toEqual() assertions.\n */\nclass AnyString {\n asymmetricMatch(other: unknown): boolean {\n return typeof other === \"string\";\n }\n\n toString(): string {\n return \"Any<String>\";\n }\n\n toAsymmetricMatcher(): string {\n return \"Any<String>\";\n }\n}\n\nexport class _AnyIdAIMessage extends AIMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"AIMessage\"];\n }\n\n constructor(fields: AIMessageFields | string) {\n let fieldsWithJestMatcher: Partial<AIMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as AIMessageFields);\n }\n}\n\nexport class _AnyIdHumanMessage extends HumanMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"HumanMessage\"];\n }\n\n constructor(fields: BaseMessageFields | string) {\n let fieldsWithJestMatcher: Partial<BaseMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as BaseMessageFields);\n }\n}\n\nexport class _AnyIdToolMessage extends ToolMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"ToolMessage\"];\n }\n\n constructor(fields: ToolMessageFields) {\n const fieldsWithJestMatcher: Partial<ToolMessageFields> = {\n id: new AnyString() as unknown as string,\n ...fields,\n };\n super(fieldsWithJestMatcher as ToolMessageFields);\n }\n}\n\nexport class FakeConfigurableModel extends BaseChatModel {\n _queuedMethodOperations: Record<string, any> = {};\n\n _chatModel: LanguageModelLike;\n\n constructor(\n fields: {\n model: LanguageModelLike;\n } & BaseChatModelParams\n ) {\n super(fields);\n this._chatModel = fields.model;\n }\n\n _llmType() {\n return \"fake_configurable\";\n }\n\n async _generate(\n _messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n throw new Error(\"Not implemented\");\n }\n\n async _model() {\n return this._chatModel;\n }\n\n bindTools(tools: BindToolsInput[]) {\n const modelWithTools = new FakeConfigurableModel({\n model: (this._chatModel as FakeToolCallingChatModel).bindTools(tools),\n });\n modelWithTools._queuedMethodOperations.bindTools = tools;\n return modelWithTools;\n }\n}\n\nexport class FakeToolCallingChatModel extends BaseChatModel {\n sleep?: number = 50;\n\n responses?: BaseMessage[];\n\n thrownErrorString?: string;\n\n idx: number;\n\n toolStyle: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\" = \"openai\";\n\n structuredResponse?: Record<string, unknown>;\n\n // Track messages passed to structured output calls\n structuredOutputMessages: BaseMessage[][] = [];\n\n constructor(\n fields: {\n sleep?: number;\n responses?: BaseMessage[];\n thrownErrorString?: string;\n toolStyle?: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\";\n structuredResponse?: Record<string, unknown>;\n } & BaseChatModelParams\n ) {\n super(fields);\n this.sleep = fields.sleep ?? this.sleep;\n this.responses = fields.responses;\n this.thrownErrorString = fields.thrownErrorString;\n this.idx = 0;\n this.toolStyle = fields.toolStyle ?? this.toolStyle;\n this.structuredResponse = fields.structuredResponse;\n this.structuredOutputMessages = [];\n }\n\n _llmType() {\n return \"fake\";\n }\n\n get profile(): ModelProfile {\n return {\n toolCalling: true,\n structuredOutput: true,\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.thrownErrorString) {\n throw new Error(this.thrownErrorString);\n }\n if (this.sleep !== undefined) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n const responses = this.responses?.length ? this.responses : messages;\n const msg = responses[this.idx % responses.length];\n const generation: ChatResult = {\n generations: [\n {\n text: \"\",\n message: msg,\n },\n ],\n };\n this.idx += 1;\n\n if (typeof msg.content === \"string\") {\n await runManager?.handleLLMNewToken(msg.content);\n }\n return generation;\n }\n\n bindTools(tools: BindToolsInput[]): Runnable<any> {\n const toolDicts = [];\n const serverTools = [];\n for (const tool of tools) {\n if (!(\"name\" in tool)) {\n serverTools.push(tool);\n continue;\n }\n\n // NOTE: this is a simplified tool spec for testing purposes only\n if (this.toolStyle === \"openai\") {\n toolDicts.push({\n type: \"function\",\n function: {\n name: tool.name,\n },\n });\n } else if ([\"anthropic\", \"google\"].includes(this.toolStyle)) {\n toolDicts.push({\n name: tool.name,\n });\n } else if (this.toolStyle === \"bedrock\") {\n toolDicts.push({\n toolSpec: {\n name: tool.name,\n },\n });\n }\n }\n let toolsToBind: BindToolsInput[] = toolDicts;\n if (this.toolStyle === \"google\") {\n toolsToBind = [{ functionDeclarations: toolDicts }];\n }\n return this.withConfig({\n tools: [...toolsToBind, ...serverTools],\n } as BaseChatModelCallOptions);\n }\n\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(_: unknown): Runnable<any> {\n if (!this.structuredResponse) {\n throw new Error(\"No structured response provided\");\n }\n // Create a runnable that returns the proper structured format\n return RunnableLambda.from(async (messages: BaseMessage[]) => {\n if (this.sleep) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n\n // Store the messages that were sent to generate structured output\n this.structuredOutputMessages.push([...messages]);\n\n // Return in the format expected: { raw: BaseMessage, parsed: RunOutput }\n return this.structuredResponse as RunOutput;\n });\n }\n}\n\nexport class MemorySaverAssertImmutable extends MemorySaver {\n storageForCopies: Record<string, Record<string, Uint8Array>> = {};\n\n constructor() {\n super();\n this.storageForCopies = {};\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata\n ): Promise<RunnableConfig> {\n const thread_id = config.configurable?.thread_id;\n this.storageForCopies[thread_id] ??= {};\n\n // assert checkpoint hasn't been modified since last written\n const saved = await this.get(config);\n if (saved) {\n const savedId = saved.id;\n if (this.storageForCopies[thread_id][savedId]) {\n const [, serializedSaved] = await this.serde.dumpsTyped(saved);\n const serializedCopy = this.storageForCopies[thread_id][savedId];\n\n // Compare Uint8Array contents by converting to string\n const savedStr = new TextDecoder().decode(serializedSaved);\n const copyStr = new TextDecoder().decode(serializedCopy);\n if (savedStr !== copyStr) {\n throw new Error(\n `Checkpoint [${savedId}] has been modified since last written`\n );\n }\n }\n }\n const [, serializedCheckpoint] = await this.serde.dumpsTyped(checkpoint);\n // save a copy of the checkpoint\n this.storageForCopies[thread_id][checkpoint.id] = serializedCheckpoint;\n\n return super.put(config, checkpoint, metadata);\n }\n}\n\ninterface ToolCall {\n name: string;\n args: Record<string, any>;\n id: string;\n type?: \"tool_call\";\n}\n\ninterface FakeToolCallingModelFields {\n toolCalls?: ToolCall[][];\n toolStyle?: \"openai\" | \"anthropic\";\n index?: number;\n structuredResponse?: any;\n}\n\n// Helper function to create checkpointer\nexport function createCheckpointer(): BaseCheckpointSaver {\n return new MemorySaver();\n}\n\n/**\n * Fake chat model for testing tool calling functionality\n */\nexport class FakeToolCallingModel extends BaseChatModel {\n toolCalls: ToolCall[][];\n\n toolStyle: \"openai\" | \"anthropic\";\n\n // Use a shared reference object so the index persists across bindTools calls\n private indexRef: { current: number };\n\n structuredResponse?: any;\n\n private tools: StructuredTool[] = [];\n\n constructor({\n toolCalls = [],\n toolStyle = \"openai\",\n index = 0,\n structuredResponse,\n indexRef,\n ...rest\n }: FakeToolCallingModelFields & { indexRef?: { current: number } } = {}) {\n super(rest);\n this.toolCalls = toolCalls;\n this.toolStyle = toolStyle;\n // Share the same index reference across instances\n this.indexRef = indexRef ?? { current: index };\n this.structuredResponse = structuredResponse;\n }\n\n // Getter/setter for backwards compatibility\n get index(): number {\n return this.indexRef.current;\n }\n\n set index(value: number) {\n this.indexRef.current = value;\n }\n\n _llmType(): string {\n return \"fake-tool-calling\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n bindTools(\n tools: StructuredTool[]\n ):\n | FakeToolCallingModel\n | RunnableBinding<\n any,\n any,\n any & { tool_choice?: ToolChoice | undefined }\n > {\n const newInstance = new FakeToolCallingModel({\n toolCalls: this.toolCalls,\n toolStyle: this.toolStyle,\n structuredResponse: this.structuredResponse,\n // Pass the same indexRef so all instances share the same index state\n indexRef: this.indexRef,\n });\n newInstance.tools = [...this.tools, ...tools];\n return newInstance;\n }\n\n withStructuredOutput(_schema: any) {\n return new RunnableLambda({\n func: async () => {\n return this.structuredResponse;\n },\n });\n }\n\n async _generate(\n messages: BaseMessage[],\n _options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const lastMessage = messages[messages.length - 1];\n let content = lastMessage.content as string;\n\n // Handle prompt concatenation\n if (messages.length > 1) {\n const parts = messages.map((m) => m.content).filter(Boolean);\n content = parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n } else if (typeof part === \"object\" && \"text\" in part) {\n return part.text;\n } else if (Array.isArray(part)) {\n return part\n .map((p) => {\n if (typeof p === \"string\") {\n return p;\n } else if (typeof p === \"object\" && \"text\" in p) {\n return p.text;\n }\n return \"\";\n })\n .join(\"-\");\n } else {\n return JSON.stringify(part);\n }\n })\n .join(\"-\");\n }\n\n // Reset index at the start of a new conversation (only human message)\n // This allows the model to be reused across multiple agent.invoke() calls\n const isStartOfConversation =\n messages.length === 1 ||\n (messages.length === 2 && messages.every(HumanMessage.isInstance));\n if (isStartOfConversation && this.index !== 0) {\n this.index = 0;\n }\n\n const currentToolCalls = this.toolCalls[this.index] || [];\n const messageId = this.index.toString();\n\n // Move to next set of tool calls for subsequent invocations\n this.index = (this.index + 1) % Math.max(1, this.toolCalls.length);\n\n const message = new AIMessage({\n content,\n id: messageId,\n tool_calls:\n currentToolCalls.length > 0\n ? currentToolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [\n {\n text: content,\n message,\n },\n ],\n llmOutput: {},\n };\n }\n}\n\nexport class SearchAPI extends StructuredTool {\n name = \"search_api\";\n\n description = \"A simple API that returns the input string.\";\n\n schema = z.object({\n query: z.string().describe(\"The query to search for.\"),\n });\n\n async _call(input: z.infer<typeof this.schema>) {\n if (input?.query === \"error\") {\n throw new Error(\"Error\");\n }\n return `result for ${input?.query}`;\n }\n}\n\nexport async function collectV3Messages(\n messages: AsyncIterable<any>\n): Promise<{ texts: string[]; deltaCount: number }> {\n const texts: string[] = [];\n let deltaCount = 0;\n for await (const stream of messages) {\n let text = \"\";\n for await (const event of stream) {\n if (event.event === \"content-block-delta\") {\n deltaCount += 1;\n text += event.delta?.text ?? \"\";\n }\n if (event.event === \"content-block-start\") {\n text += (event.contentBlock ?? event.content_block)?.text ?? \"\";\n }\n }\n texts.push(text);\n }\n return { texts, deltaCount };\n}\n\nexport async function collectClassicMessages(\n agent: any,\n input: any\n): Promise<{ model: string[]; tools: string[] }> {\n const model: string[] = [];\n const tools: string[] = [];\n for await (const chunk of await agent.stream(input, {\n streamMode: \"messages\",\n })) {\n const message = chunk[0];\n const text = typeof message?.content === \"string\" ? message.content : \"\";\n if (!text) continue;\n if (message.getType?.() === \"tool\") tools.push(text);\n else model.push(text);\n }\n return { model, tools };\n}\n"],"mappings":";;;;;;;;;;AAiWA,IAAa,uBAAb,MAAa,6BAA6B,cAAc;CACtD;CAEA;CAGA;CAEA;CAEA,QAAkC,CAAC;CAEnC,YAAY,EACV,YAAY,CAAC,GACb,YAAY,UACZ,QAAQ,GACR,oBACA,UACA,GAAG,SACgE,CAAC,GAAG;EACvE,MAAM,IAAI;EACV,KAAK,YAAY;EACjB,KAAK,YAAY;EAEjB,KAAK,WAAW,YAAY,EAAE,SAAS,MAAM;EAC7C,KAAK,qBAAqB;CAC5B;CAGA,IAAI,QAAgB;EAClB,OAAO,KAAK,SAAS;CACvB;CAEA,IAAI,MAAM,OAAe;EACvB,KAAK,SAAS,UAAU;CAC1B;CAEA,WAAmB;EACjB,OAAO;CACT;CAEA,oBAAoB;EAClB,OAAO,CAAC;CACV;CAEA,UACE,OAOI;EACJ,MAAM,cAAc,IAAI,qBAAqB;GAC3C,WAAW,KAAK;GAChB,WAAW,KAAK;GAChB,oBAAoB,KAAK;GAEzB,UAAU,KAAK;EACjB,CAAC;EACD,YAAY,QAAQ,CAAC,GAAG,KAAK,OAAO,GAAG,KAAK;EAC5C,OAAO;CACT;CAEA,qBAAqB,SAAc;EACjC,OAAO,IAAI,eAAe,EACxB,MAAM,YAAY;GAChB,OAAO,KAAK;EACd,EACF,CAAC;CACH;CAEA,MAAM,UACJ,UACA,UACA,aACqB;EAErB,IAAI,UADgB,SAAS,SAAS,SAAS,EACtB,CAAC;EAG1B,IAAI,SAAS,SAAS,GAEpB,UADc,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,OACtC,CAAC,CACZ,KAAK,SAAS;GACb,IAAI,OAAO,SAAS,UAClB,OAAO;QACF,IAAI,OAAO,SAAS,YAAY,UAAU,MAC/C,OAAO,KAAK;QACP,IAAI,MAAM,QAAQ,IAAI,GAC3B,OAAO,KACJ,KAAK,MAAM;IACV,IAAI,OAAO,MAAM,UACf,OAAO;SACF,IAAI,OAAO,MAAM,YAAY,UAAU,GAC5C,OAAO,EAAE;IAEX,OAAO;GACT,CAAC,CAAC,CACD,KAAK,GAAG;QAEX,OAAO,KAAK,UAAU,IAAI;EAE9B,CAAC,CAAC,CACD,KAAK,GAAG;EAQb,KAFE,SAAS,WAAW,KACnB,SAAS,WAAW,KAAK,SAAS,MAAM,aAAa,UAAU,MACrC,KAAK,UAAU,GAC1C,KAAK,QAAQ;EAGf,MAAM,mBAAmB,KAAK,UAAU,KAAK,UAAU,CAAC;EACxD,MAAM,YAAY,KAAK,MAAM,SAAS;EAGtC,KAAK,SAAS,KAAK,QAAQ,KAAK,KAAK,IAAI,GAAG,KAAK,UAAU,MAAM;EAEjE,MAAM,UAAU,IAAI,UAAU;GAC5B;GACA,IAAI;GACJ,YACE,iBAAiB,SAAS,IACtB,iBAAiB,KAAK,QAAQ;IAC5B,GAAG;IACH,MAAM;GACR,EAAE,IACF,KAAA;EACR,CAAC;EAED,OAAO;GACL,aAAa,CACX;IACE,MAAM;IACN;GACF,CACF;GACA,WAAW,CAAC;EACd;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/agents/tests/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n BaseChatModel,\n BaseChatModelParams,\n BaseChatModelCallOptions,\n BindToolsInput,\n ToolChoice,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport { StructuredTool } from \"@langchain/core/tools\";\nimport {\n BaseMessage,\n AIMessage,\n HumanMessage,\n BaseMessageFields,\n AIMessageFields,\n ToolMessage,\n ToolMessageFields,\n} from \"@langchain/core/messages\";\nimport { ChatResult } from \"@langchain/core/outputs\";\nimport {\n Runnable,\n RunnableConfig,\n RunnableLambda,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport {\n MemorySaver,\n Checkpoint,\n CheckpointMetadata,\n type BaseCheckpointSaver,\n} from \"@langchain/langgraph-checkpoint\";\nimport { LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { z } from \"zod/v3\";\n\n/**\n * Custom asymmetric matcher that matches any string value.\n * Works with both Jest and Vitest's toEqual() assertions.\n */\nclass AnyString {\n asymmetricMatch(other: unknown): boolean {\n return typeof other === \"string\";\n }\n\n toString(): string {\n return \"Any<String>\";\n }\n\n toAsymmetricMatcher(): string {\n return \"Any<String>\";\n }\n}\n\nexport class _AnyIdAIMessage extends AIMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"AIMessage\"];\n }\n\n constructor(fields: AIMessageFields | string) {\n let fieldsWithJestMatcher: Partial<AIMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as AIMessageFields);\n }\n}\n\nexport class _AnyIdHumanMessage extends HumanMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"HumanMessage\"];\n }\n\n constructor(fields: BaseMessageFields | string) {\n let fieldsWithJestMatcher: Partial<BaseMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as BaseMessageFields);\n }\n}\n\nexport class _AnyIdToolMessage extends ToolMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"ToolMessage\"];\n }\n\n constructor(fields: ToolMessageFields) {\n const fieldsWithJestMatcher: Partial<ToolMessageFields> = {\n id: new AnyString() as unknown as string,\n ...fields,\n };\n super(fieldsWithJestMatcher as ToolMessageFields);\n }\n}\n\nexport class FakeConfigurableModel extends BaseChatModel {\n _queuedMethodOperations: Record<string, any> = {};\n\n _chatModel: LanguageModelLike;\n\n constructor(\n fields: {\n model: LanguageModelLike;\n } & BaseChatModelParams\n ) {\n super(fields);\n this._chatModel = fields.model;\n }\n\n _llmType() {\n return \"fake_configurable\";\n }\n\n async _generate(\n _messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n throw new Error(\"Not implemented\");\n }\n\n async _model() {\n return this._chatModel;\n }\n\n bindTools(tools: BindToolsInput[]) {\n const modelWithTools = new FakeConfigurableModel({\n model: (this._chatModel as FakeToolCallingChatModel).bindTools(tools),\n });\n modelWithTools._queuedMethodOperations.bindTools = tools;\n return modelWithTools;\n }\n}\n\nexport class FakeToolCallingChatModel extends BaseChatModel {\n sleep?: number = 50;\n\n responses?: BaseMessage[];\n\n thrownErrorString?: string;\n\n idx: number;\n\n toolStyle: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\" = \"openai\";\n\n structuredResponse?: Record<string, unknown>;\n\n // Track messages passed to structured output calls\n structuredOutputMessages: BaseMessage[][] = [];\n\n constructor(\n fields: {\n sleep?: number;\n responses?: BaseMessage[];\n thrownErrorString?: string;\n toolStyle?: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\";\n structuredResponse?: Record<string, unknown>;\n } & BaseChatModelParams\n ) {\n super(fields);\n this.sleep = fields.sleep ?? this.sleep;\n this.responses = fields.responses;\n this.thrownErrorString = fields.thrownErrorString;\n this.idx = 0;\n this.toolStyle = fields.toolStyle ?? this.toolStyle;\n this.structuredResponse = fields.structuredResponse;\n this.structuredOutputMessages = [];\n }\n\n _llmType() {\n return \"fake\";\n }\n\n get profile(): ModelProfile {\n return {\n toolCalling: true,\n structuredOutput: true,\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.thrownErrorString) {\n throw new Error(this.thrownErrorString);\n }\n if (this.sleep !== undefined) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n const responses = this.responses?.length ? this.responses : messages;\n const msg = responses[this.idx % responses.length];\n const generation: ChatResult = {\n generations: [\n {\n text: \"\",\n message: msg,\n },\n ],\n };\n this.idx += 1;\n\n if (typeof msg.content === \"string\") {\n await runManager?.handleLLMNewToken(msg.content);\n }\n return generation;\n }\n\n bindTools(tools: BindToolsInput[]): Runnable<any> {\n const toolDicts = [];\n const serverTools = [];\n for (const tool of tools) {\n if (!(\"name\" in tool)) {\n serverTools.push(tool);\n continue;\n }\n\n // NOTE: this is a simplified tool spec for testing purposes only\n if (this.toolStyle === \"openai\") {\n toolDicts.push({\n type: \"function\",\n function: {\n name: tool.name,\n },\n });\n } else if ([\"anthropic\", \"google\"].includes(this.toolStyle)) {\n toolDicts.push({\n name: tool.name,\n });\n } else if (this.toolStyle === \"bedrock\") {\n toolDicts.push({\n toolSpec: {\n name: tool.name,\n },\n });\n }\n }\n let toolsToBind: BindToolsInput[] = toolDicts;\n if (this.toolStyle === \"google\") {\n toolsToBind = [{ functionDeclarations: toolDicts }];\n }\n return this.withConfig({\n tools: [...toolsToBind, ...serverTools],\n } as BaseChatModelCallOptions);\n }\n\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(_: unknown): Runnable<any> {\n if (!this.structuredResponse) {\n throw new Error(\"No structured response provided\");\n }\n // Create a runnable that returns the proper structured format\n return RunnableLambda.from(async (messages: BaseMessage[]) => {\n if (this.sleep) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n\n // Store the messages that were sent to generate structured output\n this.structuredOutputMessages.push([...messages]);\n\n // Return in the format expected: { raw: BaseMessage, parsed: RunOutput }\n return this.structuredResponse as RunOutput;\n });\n }\n}\n\nexport class MemorySaverAssertImmutable extends MemorySaver {\n storageForCopies: Record<string, Record<string, Uint8Array>> = {};\n\n constructor() {\n super();\n this.storageForCopies = {};\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata\n ): Promise<RunnableConfig> {\n const thread_id = config.configurable?.thread_id;\n this.storageForCopies[thread_id] ??= {};\n\n // assert checkpoint hasn't been modified since last written\n const saved = await this.get(config);\n if (saved) {\n const savedId = saved.id;\n if (this.storageForCopies[thread_id][savedId]) {\n const [, serializedSaved] = await this.serde.dumpsTyped(saved);\n const serializedCopy = this.storageForCopies[thread_id][savedId];\n\n // Compare Uint8Array contents by converting to string\n const savedStr = new TextDecoder().decode(serializedSaved);\n const copyStr = new TextDecoder().decode(serializedCopy);\n if (savedStr !== copyStr) {\n throw new Error(\n `Checkpoint [${savedId}] has been modified since last written`\n );\n }\n }\n }\n const [, serializedCheckpoint] = await this.serde.dumpsTyped(checkpoint);\n // save a copy of the checkpoint\n this.storageForCopies[thread_id][checkpoint.id] = serializedCheckpoint;\n\n return super.put(config, checkpoint, metadata);\n }\n}\n\ninterface ToolCall {\n name: string;\n args: Record<string, any>;\n id?: string;\n type?: \"tool_call\";\n}\n\ninterface FakeToolCallingModelFields {\n toolCalls?: ToolCall[][];\n toolStyle?: \"openai\" | \"anthropic\";\n index?: number;\n structuredResponse?: any;\n}\n\n// Helper function to create checkpointer\nexport function createCheckpointer(): BaseCheckpointSaver {\n return new MemorySaver();\n}\n\n/**\n * Fake chat model for testing tool calling functionality\n */\nexport class FakeToolCallingModel extends BaseChatModel {\n toolCalls: ToolCall[][];\n\n toolStyle: \"openai\" | \"anthropic\";\n\n // Use a shared reference object so the index persists across bindTools calls\n private indexRef: { current: number };\n\n structuredResponse?: any;\n\n private tools: StructuredTool[] = [];\n\n constructor({\n toolCalls = [],\n toolStyle = \"openai\",\n index = 0,\n structuredResponse,\n indexRef,\n ...rest\n }: FakeToolCallingModelFields & { indexRef?: { current: number } } = {}) {\n super(rest);\n this.toolCalls = toolCalls;\n this.toolStyle = toolStyle;\n // Share the same index reference across instances\n this.indexRef = indexRef ?? { current: index };\n this.structuredResponse = structuredResponse;\n }\n\n // Getter/setter for backwards compatibility\n get index(): number {\n return this.indexRef.current;\n }\n\n set index(value: number) {\n this.indexRef.current = value;\n }\n\n _llmType(): string {\n return \"fake-tool-calling\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n bindTools(\n tools: StructuredTool[]\n ):\n | FakeToolCallingModel\n | RunnableBinding<\n any,\n any,\n any & { tool_choice?: ToolChoice | undefined }\n > {\n const newInstance = new FakeToolCallingModel({\n toolCalls: this.toolCalls,\n toolStyle: this.toolStyle,\n structuredResponse: this.structuredResponse,\n // Pass the same indexRef so all instances share the same index state\n indexRef: this.indexRef,\n });\n newInstance.tools = [...this.tools, ...tools];\n return newInstance;\n }\n\n withStructuredOutput(_schema: any) {\n return new RunnableLambda({\n func: async () => {\n return this.structuredResponse;\n },\n });\n }\n\n async _generate(\n messages: BaseMessage[],\n _options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const lastMessage = messages[messages.length - 1];\n let content = lastMessage.content as string;\n\n // Handle prompt concatenation\n if (messages.length > 1) {\n const parts = messages.map((m) => m.content).filter(Boolean);\n content = parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n } else if (typeof part === \"object\" && \"text\" in part) {\n return part.text;\n } else if (Array.isArray(part)) {\n return part\n .map((p) => {\n if (typeof p === \"string\") {\n return p;\n } else if (typeof p === \"object\" && \"text\" in p) {\n return p.text;\n }\n return \"\";\n })\n .join(\"-\");\n } else {\n return JSON.stringify(part);\n }\n })\n .join(\"-\");\n }\n\n // Reset index at the start of a new conversation (only human message)\n // This allows the model to be reused across multiple agent.invoke() calls\n const isStartOfConversation =\n messages.length === 1 ||\n (messages.length === 2 && messages.every(HumanMessage.isInstance));\n if (isStartOfConversation && this.index !== 0) {\n this.index = 0;\n }\n\n const currentToolCalls = this.toolCalls[this.index] || [];\n const messageId = this.index.toString();\n\n // Move to next set of tool calls for subsequent invocations\n this.index = (this.index + 1) % Math.max(1, this.toolCalls.length);\n\n const message = new AIMessage({\n content,\n id: messageId,\n tool_calls:\n currentToolCalls.length > 0\n ? currentToolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [\n {\n text: content,\n message,\n },\n ],\n llmOutput: {},\n };\n }\n}\n\nexport class SearchAPI extends StructuredTool {\n name = \"search_api\";\n\n description = \"A simple API that returns the input string.\";\n\n schema = z.object({\n query: z.string().describe(\"The query to search for.\"),\n });\n\n async _call(input: z.infer<typeof this.schema>) {\n if (input?.query === \"error\") {\n throw new Error(\"Error\");\n }\n return `result for ${input?.query}`;\n }\n}\n\nexport async function collectV3Messages(\n messages: AsyncIterable<any>\n): Promise<{ texts: string[]; deltaCount: number }> {\n const texts: string[] = [];\n let deltaCount = 0;\n for await (const stream of messages) {\n let text = \"\";\n for await (const event of stream) {\n if (event.event === \"content-block-delta\") {\n deltaCount += 1;\n text += event.delta?.text ?? \"\";\n }\n if (event.event === \"content-block-start\") {\n text += (event.contentBlock ?? event.content_block)?.text ?? \"\";\n }\n }\n texts.push(text);\n }\n return { texts, deltaCount };\n}\n\nexport async function collectClassicMessages(\n agent: any,\n input: any\n): Promise<{ model: string[]; tools: string[] }> {\n const model: string[] = [];\n const tools: string[] = [];\n for await (const chunk of await agent.stream(input, {\n streamMode: \"messages\",\n })) {\n const message = chunk[0];\n const text = typeof message?.content === \"string\" ? message.content : \"\";\n if (!text) continue;\n if (message.getType?.() === \"tool\") tools.push(text);\n else model.push(text);\n }\n return { model, tools };\n}\n"],"mappings":";;;;;;;;;;AAiWA,IAAa,uBAAb,MAAa,6BAA6B,cAAc;CACtD;CAEA;CAGA;CAEA;CAEA,QAAkC,CAAC;CAEnC,YAAY,EACV,YAAY,CAAC,GACb,YAAY,UACZ,QAAQ,GACR,oBACA,UACA,GAAG,SACgE,CAAC,GAAG;EACvE,MAAM,IAAI;EACV,KAAK,YAAY;EACjB,KAAK,YAAY;EAEjB,KAAK,WAAW,YAAY,EAAE,SAAS,MAAM;EAC7C,KAAK,qBAAqB;CAC5B;CAGA,IAAI,QAAgB;EAClB,OAAO,KAAK,SAAS;CACvB;CAEA,IAAI,MAAM,OAAe;EACvB,KAAK,SAAS,UAAU;CAC1B;CAEA,WAAmB;EACjB,OAAO;CACT;CAEA,oBAAoB;EAClB,OAAO,CAAC;CACV;CAEA,UACE,OAOI;EACJ,MAAM,cAAc,IAAI,qBAAqB;GAC3C,WAAW,KAAK;GAChB,WAAW,KAAK;GAChB,oBAAoB,KAAK;GAEzB,UAAU,KAAK;EACjB,CAAC;EACD,YAAY,QAAQ,CAAC,GAAG,KAAK,OAAO,GAAG,KAAK;EAC5C,OAAO;CACT;CAEA,qBAAqB,SAAc;EACjC,OAAO,IAAI,eAAe,EACxB,MAAM,YAAY;GAChB,OAAO,KAAK;EACd,EACF,CAAC;CACH;CAEA,MAAM,UACJ,UACA,UACA,aACqB;EAErB,IAAI,UADgB,SAAS,SAAS,SAAS,EACtB,CAAC;EAG1B,IAAI,SAAS,SAAS,GAEpB,UADc,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,OACtC,CAAC,CACZ,KAAK,SAAS;GACb,IAAI,OAAO,SAAS,UAClB,OAAO;QACF,IAAI,OAAO,SAAS,YAAY,UAAU,MAC/C,OAAO,KAAK;QACP,IAAI,MAAM,QAAQ,IAAI,GAC3B,OAAO,KACJ,KAAK,MAAM;IACV,IAAI,OAAO,MAAM,UACf,OAAO;SACF,IAAI,OAAO,MAAM,YAAY,UAAU,GAC5C,OAAO,EAAE;IAEX,OAAO;GACT,CAAC,CAAC,CACD,KAAK,GAAG;QAEX,OAAO,KAAK,UAAU,IAAI;EAE9B,CAAC,CAAC,CACD,KAAK,GAAG;EAQb,KAFE,SAAS,WAAW,KACnB,SAAS,WAAW,KAAK,SAAS,MAAM,aAAa,UAAU,MACrC,KAAK,UAAU,GAC1C,KAAK,QAAQ;EAGf,MAAM,mBAAmB,KAAK,UAAU,KAAK,UAAU,CAAC;EACxD,MAAM,YAAY,KAAK,MAAM,SAAS;EAGtC,KAAK,SAAS,KAAK,QAAQ,KAAK,KAAK,IAAI,GAAG,KAAK,UAAU,MAAM;EAEjE,MAAM,UAAU,IAAI,UAAU;GAC5B;GACA,IAAI;GACJ,YACE,iBAAiB,SAAS,IACtB,iBAAiB,KAAK,QAAQ;IAC5B,GAAG;IACH,MAAM;GACR,EAAE,IACF,KAAA;EACR,CAAC;EAED,OAAO;GACL,aAAa,CACX;IACE,MAAM;IACN;GACF,CACF;GACA,WAAW,CAAC;EACd;CACF;AACF"}
|
package/dist/agents/types.d.cts
CHANGED
|
@@ -6,6 +6,7 @@ import { BaseMessage, MessageStructure, MessageToolDefinition, SystemMessage } f
|
|
|
6
6
|
import { ClientTool, DynamicStructuredTool, ServerTool, StructuredToolInterface } from "@langchain/core/tools";
|
|
7
7
|
import { InteropZodObject, InteropZodType } from "@langchain/core/utils/types";
|
|
8
8
|
import { END, START, StateDefinitionInit, StateGraph, StreamTransformer } from "@langchain/langgraph";
|
|
9
|
+
import { JSONSchema } from "@langchain/core/utils/json_schema";
|
|
9
10
|
import { BaseCheckpointSaver, BaseStore } from "@langchain/langgraph-checkpoint";
|
|
10
11
|
import { Messages } from "@langchain/langgraph/";
|
|
11
12
|
//#region src/agents/types.d.ts
|
|
@@ -308,6 +309,11 @@ export interface Interrupt<TValue = unknown> {
|
|
|
308
309
|
* The requests for human input.
|
|
309
310
|
*/
|
|
310
311
|
value: TValue;
|
|
312
|
+
/**
|
|
313
|
+
* JSON schema for the expected resume value, when the interrupt sets one (for
|
|
314
|
+
* example, a `humanInTheLoopMiddleware` tool approval in `"per_call"` mode).
|
|
315
|
+
*/
|
|
316
|
+
response_schema?: JSONSchema;
|
|
311
317
|
}
|
|
312
318
|
export interface BuiltInState<TMessageStructure extends MessageStructure = MessageStructure> {
|
|
313
319
|
messages: BaseMessage<TMessageStructure>[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":["ToolCall"],"sources":["../../src/agents/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":["ToolCall"],"sources":["../../src/agents/types.ts"],"mappings":"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"}
|
package/dist/agents/types.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { BaseMessage, MessageStructure, MessageToolDefinition, SystemMessage } f
|
|
|
6
6
|
import { ClientTool, DynamicStructuredTool, ServerTool, StructuredToolInterface } from "@langchain/core/tools";
|
|
7
7
|
import { END, START, StateDefinitionInit, StateGraph, StreamTransformer } from "@langchain/langgraph";
|
|
8
8
|
import { InteropZodObject, InteropZodType } from "@langchain/core/utils/types";
|
|
9
|
+
import { JSONSchema } from "@langchain/core/utils/json_schema";
|
|
9
10
|
import { BaseCheckpointSaver, BaseStore } from "@langchain/langgraph-checkpoint";
|
|
10
11
|
import { Messages } from "@langchain/langgraph/";
|
|
11
12
|
//#region src/agents/types.d.ts
|
|
@@ -308,6 +309,11 @@ export interface Interrupt<TValue = unknown> {
|
|
|
308
309
|
* The requests for human input.
|
|
309
310
|
*/
|
|
310
311
|
value: TValue;
|
|
312
|
+
/**
|
|
313
|
+
* JSON schema for the expected resume value, when the interrupt sets one (for
|
|
314
|
+
* example, a `humanInTheLoopMiddleware` tool approval in `"per_call"` mode).
|
|
315
|
+
*/
|
|
316
|
+
response_schema?: JSONSchema;
|
|
311
317
|
}
|
|
312
318
|
export interface BuiltInState<TMessageStructure extends MessageStructure = MessageStructure> {
|
|
313
319
|
messages: BaseMessage<TMessageStructure>[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":["ToolCall"],"sources":["../../src/agents/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":["ToolCall"],"sources":["../../src/agents/types.ts"],"mappings":"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"}
|
package/dist/browser.cjs
CHANGED
|
@@ -88,6 +88,7 @@ var browser_exports = /* @__PURE__ */ require_runtime.__exportAll({
|
|
|
88
88
|
filterMessages: () => _langchain_core_messages.filterMessages,
|
|
89
89
|
humanInTheLoopMiddleware: () => require_hitl.humanInTheLoopMiddleware,
|
|
90
90
|
initChatModel: () => require_chat_models_universal.initChatModel,
|
|
91
|
+
isToolApprovalInterrupt: () => require_hitl.isToolApprovalInterrupt,
|
|
91
92
|
langchainMatchers: () => _langchain_core_testing.langchainMatchers,
|
|
92
93
|
llmToolSelectorMiddleware: () => require_llmToolSelector.llmToolSelectorMiddleware,
|
|
93
94
|
modelCallLimitMiddleware: () => require_modelCallLimit.modelCallLimitMiddleware,
|
|
@@ -260,6 +261,7 @@ Object.defineProperty(exports, "filterMessages", {
|
|
|
260
261
|
});
|
|
261
262
|
exports.humanInTheLoopMiddleware = require_hitl.humanInTheLoopMiddleware;
|
|
262
263
|
exports.initChatModel = require_chat_models_universal.initChatModel;
|
|
264
|
+
exports.isToolApprovalInterrupt = require_hitl.isToolApprovalInterrupt;
|
|
263
265
|
Object.defineProperty(exports, "langchainMatchers", {
|
|
264
266
|
enumerable: true,
|
|
265
267
|
get: function() {
|
package/dist/browser.d.cts
CHANGED
|
@@ -14,7 +14,7 @@ import { ReactAgent } from "./agents/ReactAgent.cjs";
|
|
|
14
14
|
import { createMiddleware } from "./agents/middleware.cjs";
|
|
15
15
|
import { FakeToolCallingModel } from "./agents/tests/utils.cjs";
|
|
16
16
|
import { createAgent } from "./agents/index.cjs";
|
|
17
|
-
import { Action, ActionRequest, ApproveDecision, Decision, DecisionType, DescriptionFactory, EditDecision, HITLRequest, HITLResponse, HumanInTheLoopMiddlewareConfig, InterruptOnConfig, RejectDecision, RespondDecision, ReviewConfig, WhenPredicate, humanInTheLoopMiddleware } from "./agents/middleware/hitl.cjs";
|
|
17
|
+
import { Action, ActionRequest, ApproveDecision, Decision, DecisionType, DescriptionFactory, EditDecision, HITLRequest, HITLResponse, HumanInTheLoopMiddlewareConfig, InterruptOnConfig, RejectDecision, RespondDecision, ReviewConfig, ToolApprovalDecision, ToolApprovalRequest, WhenPredicate, humanInTheLoopMiddleware, isToolApprovalInterrupt } from "./agents/middleware/hitl.cjs";
|
|
18
18
|
import { SummarizationMiddlewareConfig, TokenCounter, summarizationMiddleware } from "./agents/middleware/summarization.cjs";
|
|
19
19
|
import { DynamicSystemPromptMiddlewareConfig, dynamicSystemPromptMiddleware } from "./agents/middleware/dynamicSystemPrompt.cjs";
|
|
20
20
|
import { LLMToolSelectorConfig, llmToolSelectorMiddleware } from "./agents/middleware/llmToolSelector.cjs";
|
|
@@ -41,4 +41,4 @@ import { context } from "@langchain/core/utils/context";
|
|
|
41
41
|
import { InMemoryStore } from "@langchain/core/stores";
|
|
42
42
|
import { Document, DocumentInput } from "@langchain/core/documents";
|
|
43
43
|
import { LangChainMatchers, fakeModel, langchainMatchers } from "@langchain/core/testing";
|
|
44
|
-
export { AIMessage, AIMessageChunk, Action, ActionRequest, type AfterAgentHook, type AfterModelHook, type AgentMiddleware, type AgentRunStream, AgentTypeConfig, type AnyAgentMiddleware, type AnyAnnotationRoot, ApproveDecision, BaseMessage, BaseMessageChunk, type BedrockConversePromptCachingMiddlewareConfig, type BeforeAgentHook, type BeforeModelHook, type BuiltInPIIType, BuiltInState, ClearToolUsesEdit, type ClearToolUsesEditConfig, CombineStreamTransformers, CombineTools, type ContentBlock, type ContextEdit, type ContextEditingMiddlewareConfig, CreateAgentParams, Decision, DecisionType, DefaultAgentTypeConfig, type DefaultMiddlewareTypeConfig, DescriptionFactory, Document, type DocumentInput, DynamicStructuredTool, type DynamicSystemPromptMiddlewareConfig, DynamicTool, EditDecision, ExecutedToolCall, ExtractZodArrayTypes, FakeToolCallingModel, HITLRequest, HITLResponse, type HeadlessTool, type HeadlessToolFields, type HeadlessToolImplementation, HumanInTheLoopMiddlewareConfig, HumanMessage, HumanMessageChunk, InMemoryStore, InferAgentContext, InferAgentContextSchema, InferAgentMiddleware, InferAgentResponse, InferAgentState, InferAgentStateSchema, InferAgentStreamTransformers, InferAgentTools, InferAgentType, type InferChannelType, type InferContextInput, type InferMergedInputState, type InferMergedState, type InferMiddlewareContext, type InferMiddlewareContextInput, type InferMiddlewareContextInputs, type InferMiddlewareContextSchema, type InferMiddlewareContexts, type InferMiddlewareFullContext, type InferMiddlewareInputState, type InferMiddlewareInputStates, type InferMiddlewareSchema, type InferMiddlewareState, type InferMiddlewareStates, InferMiddlewareStreamTransformers, InferMiddlewareStreamTransformersArray, type InferMiddlewareStreamTransformersFromConfig, InferMiddlewareTools, InferMiddlewareToolsArray, type InferMiddlewareToolsFromConfig, type InferMiddlewareType, type InferSchemaInput, type InferSchemaUpdateType, type InferSchemaValue, type InferSchemaValueType, Interrupt, InterruptOnConfig, JumpTo, type JumpToTarget, type LLMToolSelectorConfig, type LangChainMatchers, MIDDLEWARE_BRAND, MiddlewareError, type MiddlewareResult, type MiddlewareTypeConfig, type ModelCallLimitMiddlewareConfig, ModelRequest, type ModelRetryMiddlewareConfig, MultipleStructuredOutputsError, MultipleToolsBoundError, N, type NormalizedSchemaInput, type NormalizedSchemaUpdate, type OpenAIModerationMiddlewareOptions, PIIDetectionError, type PIIDetector, type PIIMatch, type PIIMiddlewareConfig, type PIIRedactionMiddlewareConfig, type PIIStrategy, type PromptCachingMiddlewareConfig, ProviderStrategy, type ProviderToolSearchMiddlewareConfig, type ReactAgent, type RedactionRuleConfig, RejectDecision, ResolveAgentTypeConfig, type ResolveMiddlewareTypeConfig, type ResolvedRedactionRule, RespondDecision, type ResponseFormat, type ResponseFormatUndefined, ReviewConfig, type Runtime, StructuredOutputParsingError, StructuredTool, type SubagentRunStream, type SummarizationMiddlewareConfig, SystemMessage, SystemMessageChunk, TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, type ToAnnotationRoot, type Todo, type TodoListMiddlewareOptions, type TokenCounter, Tool, ToolCall, type ToolCallHandler, type ToolCallLimitConfig, ToolCallLimitExceededError, type ToolCallRequest, type ToolCallStreamUnion, type ToolEmulatorOptions, type ToolErrorHandler, type ToolErrorMiddlewareConfig, ToolInvocationError, ToolMessage, ToolMessageChunk, ToolResult, type ToolRetryMiddlewareConfig, type ToolRuntime, ToolStrategy, ToolsToMessageToolSet, type TypedToolStrategy, UserInput, WhenPredicate, WithStateGraphNodes, type WrapModelCallHandler, type WrapModelCallHook, type WrapToolCallHook, anthropicPromptCachingMiddleware, applyStrategy, bedrockPromptCachingMiddleware, context, contextEditingMiddleware, countTokensApproximately, createAgent, createMiddleware, createSubagentTransformer, createToolCallTransformer, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, dynamicSystemPromptMiddleware, fakeModel, filterMessages, humanInTheLoopMiddleware, initChatModel, langchainMatchers, llmToolSelectorMiddleware, modelCallLimitMiddleware, modelFallbackMiddleware, modelRetryMiddleware, openAIModerationMiddleware, piiMiddleware, piiRedactionMiddleware, providerStrategy, providerToolSearchMiddleware, resolveRedactionRule, summarizationMiddleware, todoListMiddleware, tool, toolCallLimitMiddleware, toolEmulatorMiddleware, toolErrorMiddleware, toolRetryMiddleware, toolStrategy, trimMessages };
|
|
44
|
+
export { AIMessage, AIMessageChunk, Action, ActionRequest, type AfterAgentHook, type AfterModelHook, type AgentMiddleware, type AgentRunStream, AgentTypeConfig, type AnyAgentMiddleware, type AnyAnnotationRoot, ApproveDecision, BaseMessage, BaseMessageChunk, type BedrockConversePromptCachingMiddlewareConfig, type BeforeAgentHook, type BeforeModelHook, type BuiltInPIIType, BuiltInState, ClearToolUsesEdit, type ClearToolUsesEditConfig, CombineStreamTransformers, CombineTools, type ContentBlock, type ContextEdit, type ContextEditingMiddlewareConfig, CreateAgentParams, Decision, DecisionType, DefaultAgentTypeConfig, type DefaultMiddlewareTypeConfig, DescriptionFactory, Document, type DocumentInput, DynamicStructuredTool, type DynamicSystemPromptMiddlewareConfig, DynamicTool, EditDecision, ExecutedToolCall, ExtractZodArrayTypes, FakeToolCallingModel, HITLRequest, HITLResponse, type HeadlessTool, type HeadlessToolFields, type HeadlessToolImplementation, HumanInTheLoopMiddlewareConfig, HumanMessage, HumanMessageChunk, InMemoryStore, InferAgentContext, InferAgentContextSchema, InferAgentMiddleware, InferAgentResponse, InferAgentState, InferAgentStateSchema, InferAgentStreamTransformers, InferAgentTools, InferAgentType, type InferChannelType, type InferContextInput, type InferMergedInputState, type InferMergedState, type InferMiddlewareContext, type InferMiddlewareContextInput, type InferMiddlewareContextInputs, type InferMiddlewareContextSchema, type InferMiddlewareContexts, type InferMiddlewareFullContext, type InferMiddlewareInputState, type InferMiddlewareInputStates, type InferMiddlewareSchema, type InferMiddlewareState, type InferMiddlewareStates, InferMiddlewareStreamTransformers, InferMiddlewareStreamTransformersArray, type InferMiddlewareStreamTransformersFromConfig, InferMiddlewareTools, InferMiddlewareToolsArray, type InferMiddlewareToolsFromConfig, type InferMiddlewareType, type InferSchemaInput, type InferSchemaUpdateType, type InferSchemaValue, type InferSchemaValueType, Interrupt, InterruptOnConfig, JumpTo, type JumpToTarget, type LLMToolSelectorConfig, type LangChainMatchers, MIDDLEWARE_BRAND, MiddlewareError, type MiddlewareResult, type MiddlewareTypeConfig, type ModelCallLimitMiddlewareConfig, ModelRequest, type ModelRetryMiddlewareConfig, MultipleStructuredOutputsError, MultipleToolsBoundError, N, type NormalizedSchemaInput, type NormalizedSchemaUpdate, type OpenAIModerationMiddlewareOptions, PIIDetectionError, type PIIDetector, type PIIMatch, type PIIMiddlewareConfig, type PIIRedactionMiddlewareConfig, type PIIStrategy, type PromptCachingMiddlewareConfig, ProviderStrategy, type ProviderToolSearchMiddlewareConfig, type ReactAgent, type RedactionRuleConfig, RejectDecision, ResolveAgentTypeConfig, type ResolveMiddlewareTypeConfig, type ResolvedRedactionRule, RespondDecision, type ResponseFormat, type ResponseFormatUndefined, ReviewConfig, type Runtime, StructuredOutputParsingError, StructuredTool, type SubagentRunStream, type SummarizationMiddlewareConfig, SystemMessage, SystemMessageChunk, TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, type ToAnnotationRoot, type Todo, type TodoListMiddlewareOptions, type TokenCounter, Tool, ToolApprovalDecision, ToolApprovalRequest, ToolCall, type ToolCallHandler, type ToolCallLimitConfig, ToolCallLimitExceededError, type ToolCallRequest, type ToolCallStreamUnion, type ToolEmulatorOptions, type ToolErrorHandler, type ToolErrorMiddlewareConfig, ToolInvocationError, ToolMessage, ToolMessageChunk, ToolResult, type ToolRetryMiddlewareConfig, type ToolRuntime, ToolStrategy, ToolsToMessageToolSet, type TypedToolStrategy, UserInput, WhenPredicate, WithStateGraphNodes, type WrapModelCallHandler, type WrapModelCallHook, type WrapToolCallHook, anthropicPromptCachingMiddleware, applyStrategy, bedrockPromptCachingMiddleware, context, contextEditingMiddleware, countTokensApproximately, createAgent, createMiddleware, createSubagentTransformer, createToolCallTransformer, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, dynamicSystemPromptMiddleware, fakeModel, filterMessages, humanInTheLoopMiddleware, initChatModel, isToolApprovalInterrupt, langchainMatchers, llmToolSelectorMiddleware, modelCallLimitMiddleware, modelFallbackMiddleware, modelRetryMiddleware, openAIModerationMiddleware, piiMiddleware, piiRedactionMiddleware, providerStrategy, providerToolSearchMiddleware, resolveRedactionRule, summarizationMiddleware, todoListMiddleware, tool, toolCallLimitMiddleware, toolEmulatorMiddleware, toolErrorMiddleware, toolRetryMiddleware, toolStrategy, trimMessages };
|
package/dist/browser.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { ReactAgent } from "./agents/ReactAgent.js";
|
|
|
14
14
|
import { createMiddleware } from "./agents/middleware.js";
|
|
15
15
|
import { FakeToolCallingModel } from "./agents/tests/utils.js";
|
|
16
16
|
import { createAgent } from "./agents/index.js";
|
|
17
|
-
import { Action, ActionRequest, ApproveDecision, Decision, DecisionType, DescriptionFactory, EditDecision, HITLRequest, HITLResponse, HumanInTheLoopMiddlewareConfig, InterruptOnConfig, RejectDecision, RespondDecision, ReviewConfig, WhenPredicate, humanInTheLoopMiddleware } from "./agents/middleware/hitl.js";
|
|
17
|
+
import { Action, ActionRequest, ApproveDecision, Decision, DecisionType, DescriptionFactory, EditDecision, HITLRequest, HITLResponse, HumanInTheLoopMiddlewareConfig, InterruptOnConfig, RejectDecision, RespondDecision, ReviewConfig, ToolApprovalDecision, ToolApprovalRequest, WhenPredicate, humanInTheLoopMiddleware, isToolApprovalInterrupt } from "./agents/middleware/hitl.js";
|
|
18
18
|
import { SummarizationMiddlewareConfig, TokenCounter, summarizationMiddleware } from "./agents/middleware/summarization.js";
|
|
19
19
|
import { DynamicSystemPromptMiddlewareConfig, dynamicSystemPromptMiddleware } from "./agents/middleware/dynamicSystemPrompt.js";
|
|
20
20
|
import { LLMToolSelectorConfig, llmToolSelectorMiddleware } from "./agents/middleware/llmToolSelector.js";
|
|
@@ -41,4 +41,4 @@ import { context } from "@langchain/core/utils/context";
|
|
|
41
41
|
import { InMemoryStore } from "@langchain/core/stores";
|
|
42
42
|
import { Document, DocumentInput } from "@langchain/core/documents";
|
|
43
43
|
import { LangChainMatchers, fakeModel, langchainMatchers } from "@langchain/core/testing";
|
|
44
|
-
export { AIMessage, AIMessageChunk, Action, ActionRequest, type AfterAgentHook, type AfterModelHook, type AgentMiddleware, type AgentRunStream, AgentTypeConfig, type AnyAgentMiddleware, type AnyAnnotationRoot, ApproveDecision, BaseMessage, BaseMessageChunk, type BedrockConversePromptCachingMiddlewareConfig, type BeforeAgentHook, type BeforeModelHook, type BuiltInPIIType, BuiltInState, ClearToolUsesEdit, type ClearToolUsesEditConfig, CombineStreamTransformers, CombineTools, type ContentBlock, type ContextEdit, type ContextEditingMiddlewareConfig, CreateAgentParams, Decision, DecisionType, DefaultAgentTypeConfig, type DefaultMiddlewareTypeConfig, DescriptionFactory, Document, type DocumentInput, DynamicStructuredTool, type DynamicSystemPromptMiddlewareConfig, DynamicTool, EditDecision, ExecutedToolCall, ExtractZodArrayTypes, FakeToolCallingModel, HITLRequest, HITLResponse, type HeadlessTool, type HeadlessToolFields, type HeadlessToolImplementation, HumanInTheLoopMiddlewareConfig, HumanMessage, HumanMessageChunk, InMemoryStore, InferAgentContext, InferAgentContextSchema, InferAgentMiddleware, InferAgentResponse, InferAgentState, InferAgentStateSchema, InferAgentStreamTransformers, InferAgentTools, InferAgentType, type InferChannelType, type InferContextInput, type InferMergedInputState, type InferMergedState, type InferMiddlewareContext, type InferMiddlewareContextInput, type InferMiddlewareContextInputs, type InferMiddlewareContextSchema, type InferMiddlewareContexts, type InferMiddlewareFullContext, type InferMiddlewareInputState, type InferMiddlewareInputStates, type InferMiddlewareSchema, type InferMiddlewareState, type InferMiddlewareStates, InferMiddlewareStreamTransformers, InferMiddlewareStreamTransformersArray, type InferMiddlewareStreamTransformersFromConfig, InferMiddlewareTools, InferMiddlewareToolsArray, type InferMiddlewareToolsFromConfig, type InferMiddlewareType, type InferSchemaInput, type InferSchemaUpdateType, type InferSchemaValue, type InferSchemaValueType, Interrupt, InterruptOnConfig, JumpTo, type JumpToTarget, type LLMToolSelectorConfig, type LangChainMatchers, MIDDLEWARE_BRAND, MiddlewareError, type MiddlewareResult, type MiddlewareTypeConfig, type ModelCallLimitMiddlewareConfig, ModelRequest, type ModelRetryMiddlewareConfig, MultipleStructuredOutputsError, MultipleToolsBoundError, N, type NormalizedSchemaInput, type NormalizedSchemaUpdate, type OpenAIModerationMiddlewareOptions, PIIDetectionError, type PIIDetector, type PIIMatch, type PIIMiddlewareConfig, type PIIRedactionMiddlewareConfig, type PIIStrategy, type PromptCachingMiddlewareConfig, ProviderStrategy, type ProviderToolSearchMiddlewareConfig, type ReactAgent, type RedactionRuleConfig, RejectDecision, ResolveAgentTypeConfig, type ResolveMiddlewareTypeConfig, type ResolvedRedactionRule, RespondDecision, type ResponseFormat, type ResponseFormatUndefined, ReviewConfig, type Runtime, StructuredOutputParsingError, StructuredTool, type SubagentRunStream, type SummarizationMiddlewareConfig, SystemMessage, SystemMessageChunk, TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, type ToAnnotationRoot, type Todo, type TodoListMiddlewareOptions, type TokenCounter, Tool, ToolCall, type ToolCallHandler, type ToolCallLimitConfig, ToolCallLimitExceededError, type ToolCallRequest, type ToolCallStreamUnion, type ToolEmulatorOptions, type ToolErrorHandler, type ToolErrorMiddlewareConfig, ToolInvocationError, ToolMessage, ToolMessageChunk, ToolResult, type ToolRetryMiddlewareConfig, type ToolRuntime, ToolStrategy, ToolsToMessageToolSet, type TypedToolStrategy, UserInput, WhenPredicate, WithStateGraphNodes, type WrapModelCallHandler, type WrapModelCallHook, type WrapToolCallHook, anthropicPromptCachingMiddleware, applyStrategy, bedrockPromptCachingMiddleware, context, contextEditingMiddleware, countTokensApproximately, createAgent, createMiddleware, createSubagentTransformer, createToolCallTransformer, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, dynamicSystemPromptMiddleware, fakeModel, filterMessages, humanInTheLoopMiddleware, initChatModel, langchainMatchers, llmToolSelectorMiddleware, modelCallLimitMiddleware, modelFallbackMiddleware, modelRetryMiddleware, openAIModerationMiddleware, piiMiddleware, piiRedactionMiddleware, providerStrategy, providerToolSearchMiddleware, resolveRedactionRule, summarizationMiddleware, todoListMiddleware, tool, toolCallLimitMiddleware, toolEmulatorMiddleware, toolErrorMiddleware, toolRetryMiddleware, toolStrategy, trimMessages };
|
|
44
|
+
export { AIMessage, AIMessageChunk, Action, ActionRequest, type AfterAgentHook, type AfterModelHook, type AgentMiddleware, type AgentRunStream, AgentTypeConfig, type AnyAgentMiddleware, type AnyAnnotationRoot, ApproveDecision, BaseMessage, BaseMessageChunk, type BedrockConversePromptCachingMiddlewareConfig, type BeforeAgentHook, type BeforeModelHook, type BuiltInPIIType, BuiltInState, ClearToolUsesEdit, type ClearToolUsesEditConfig, CombineStreamTransformers, CombineTools, type ContentBlock, type ContextEdit, type ContextEditingMiddlewareConfig, CreateAgentParams, Decision, DecisionType, DefaultAgentTypeConfig, type DefaultMiddlewareTypeConfig, DescriptionFactory, Document, type DocumentInput, DynamicStructuredTool, type DynamicSystemPromptMiddlewareConfig, DynamicTool, EditDecision, ExecutedToolCall, ExtractZodArrayTypes, FakeToolCallingModel, HITLRequest, HITLResponse, type HeadlessTool, type HeadlessToolFields, type HeadlessToolImplementation, HumanInTheLoopMiddlewareConfig, HumanMessage, HumanMessageChunk, InMemoryStore, InferAgentContext, InferAgentContextSchema, InferAgentMiddleware, InferAgentResponse, InferAgentState, InferAgentStateSchema, InferAgentStreamTransformers, InferAgentTools, InferAgentType, type InferChannelType, type InferContextInput, type InferMergedInputState, type InferMergedState, type InferMiddlewareContext, type InferMiddlewareContextInput, type InferMiddlewareContextInputs, type InferMiddlewareContextSchema, type InferMiddlewareContexts, type InferMiddlewareFullContext, type InferMiddlewareInputState, type InferMiddlewareInputStates, type InferMiddlewareSchema, type InferMiddlewareState, type InferMiddlewareStates, InferMiddlewareStreamTransformers, InferMiddlewareStreamTransformersArray, type InferMiddlewareStreamTransformersFromConfig, InferMiddlewareTools, InferMiddlewareToolsArray, type InferMiddlewareToolsFromConfig, type InferMiddlewareType, type InferSchemaInput, type InferSchemaUpdateType, type InferSchemaValue, type InferSchemaValueType, Interrupt, InterruptOnConfig, JumpTo, type JumpToTarget, type LLMToolSelectorConfig, type LangChainMatchers, MIDDLEWARE_BRAND, MiddlewareError, type MiddlewareResult, type MiddlewareTypeConfig, type ModelCallLimitMiddlewareConfig, ModelRequest, type ModelRetryMiddlewareConfig, MultipleStructuredOutputsError, MultipleToolsBoundError, N, type NormalizedSchemaInput, type NormalizedSchemaUpdate, type OpenAIModerationMiddlewareOptions, PIIDetectionError, type PIIDetector, type PIIMatch, type PIIMiddlewareConfig, type PIIRedactionMiddlewareConfig, type PIIStrategy, type PromptCachingMiddlewareConfig, ProviderStrategy, type ProviderToolSearchMiddlewareConfig, type ReactAgent, type RedactionRuleConfig, RejectDecision, ResolveAgentTypeConfig, type ResolveMiddlewareTypeConfig, type ResolvedRedactionRule, RespondDecision, type ResponseFormat, type ResponseFormatUndefined, ReviewConfig, type Runtime, StructuredOutputParsingError, StructuredTool, type SubagentRunStream, type SummarizationMiddlewareConfig, SystemMessage, SystemMessageChunk, TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, type ToAnnotationRoot, type Todo, type TodoListMiddlewareOptions, type TokenCounter, Tool, ToolApprovalDecision, ToolApprovalRequest, ToolCall, type ToolCallHandler, type ToolCallLimitConfig, ToolCallLimitExceededError, type ToolCallRequest, type ToolCallStreamUnion, type ToolEmulatorOptions, type ToolErrorHandler, type ToolErrorMiddlewareConfig, ToolInvocationError, ToolMessage, ToolMessageChunk, ToolResult, type ToolRetryMiddlewareConfig, type ToolRuntime, ToolStrategy, ToolsToMessageToolSet, type TypedToolStrategy, UserInput, WhenPredicate, WithStateGraphNodes, type WrapModelCallHandler, type WrapModelCallHook, type WrapToolCallHook, anthropicPromptCachingMiddleware, applyStrategy, bedrockPromptCachingMiddleware, context, contextEditingMiddleware, countTokensApproximately, createAgent, createMiddleware, createSubagentTransformer, createToolCallTransformer, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, dynamicSystemPromptMiddleware, fakeModel, filterMessages, humanInTheLoopMiddleware, initChatModel, isToolApprovalInterrupt, langchainMatchers, llmToolSelectorMiddleware, modelCallLimitMiddleware, modelFallbackMiddleware, modelRetryMiddleware, openAIModerationMiddleware, piiMiddleware, piiRedactionMiddleware, providerStrategy, providerToolSearchMiddleware, resolveRedactionRule, summarizationMiddleware, todoListMiddleware, tool, toolCallLimitMiddleware, toolEmulatorMiddleware, toolErrorMiddleware, toolRetryMiddleware, toolStrategy, trimMessages };
|
package/dist/browser.js
CHANGED
|
@@ -10,7 +10,7 @@ import { MIDDLEWARE_BRAND } from "./agents/middleware/types.js";
|
|
|
10
10
|
import { createMiddleware } from "./agents/middleware.js";
|
|
11
11
|
import { FakeToolCallingModel } from "./agents/tests/utils.js";
|
|
12
12
|
import { createAgent } from "./agents/index.js";
|
|
13
|
-
import { humanInTheLoopMiddleware } from "./agents/middleware/hitl.js";
|
|
13
|
+
import { humanInTheLoopMiddleware, isToolApprovalInterrupt } from "./agents/middleware/hitl.js";
|
|
14
14
|
import { summarizationMiddleware } from "./agents/middleware/summarization.js";
|
|
15
15
|
import { dynamicSystemPromptMiddleware } from "./agents/middleware/dynamicSystemPrompt.js";
|
|
16
16
|
import { llmToolSelectorMiddleware } from "./agents/middleware/llmToolSelector.js";
|
|
@@ -87,6 +87,7 @@ var browser_exports = /* @__PURE__ */ __exportAll({
|
|
|
87
87
|
filterMessages: () => filterMessages,
|
|
88
88
|
humanInTheLoopMiddleware: () => humanInTheLoopMiddleware,
|
|
89
89
|
initChatModel: () => initChatModel,
|
|
90
|
+
isToolApprovalInterrupt: () => isToolApprovalInterrupt,
|
|
90
91
|
langchainMatchers: () => langchainMatchers,
|
|
91
92
|
llmToolSelectorMiddleware: () => llmToolSelectorMiddleware,
|
|
92
93
|
modelCallLimitMiddleware: () => modelCallLimitMiddleware,
|
|
@@ -109,6 +110,6 @@ var browser_exports = /* @__PURE__ */ __exportAll({
|
|
|
109
110
|
trimMessages: () => trimMessages
|
|
110
111
|
});
|
|
111
112
|
//#endregion
|
|
112
|
-
export { AIMessage, AIMessageChunk, BaseMessage, BaseMessageChunk, ClearToolUsesEdit, Document, DynamicStructuredTool, DynamicTool, FakeToolCallingModel, HumanMessage, HumanMessageChunk, InMemoryStore, MIDDLEWARE_BRAND, MiddlewareError, MultipleStructuredOutputsError, MultipleToolsBoundError, PIIDetectionError, ProviderStrategy, StructuredOutputParsingError, StructuredTool, SystemMessage, SystemMessageChunk, TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, Tool, ToolCallLimitExceededError, ToolInvocationError, ToolMessage, ToolMessageChunk, ToolStrategy, anthropicPromptCachingMiddleware, applyStrategy, bedrockPromptCachingMiddleware, browser_exports, context, contextEditingMiddleware, countTokensApproximately, createAgent, createMiddleware, createSubagentTransformer, createToolCallTransformer, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, dynamicSystemPromptMiddleware, fakeModel, filterMessages, humanInTheLoopMiddleware, initChatModel, langchainMatchers, llmToolSelectorMiddleware, modelCallLimitMiddleware, modelFallbackMiddleware, modelRetryMiddleware, openAIModerationMiddleware, piiMiddleware, piiRedactionMiddleware, providerStrategy, providerToolSearchMiddleware, resolveRedactionRule, summarizationMiddleware, todoListMiddleware, tool, toolCallLimitMiddleware, toolEmulatorMiddleware, toolErrorMiddleware, toolRetryMiddleware, toolStrategy, trimMessages };
|
|
113
|
+
export { AIMessage, AIMessageChunk, BaseMessage, BaseMessageChunk, ClearToolUsesEdit, Document, DynamicStructuredTool, DynamicTool, FakeToolCallingModel, HumanMessage, HumanMessageChunk, InMemoryStore, MIDDLEWARE_BRAND, MiddlewareError, MultipleStructuredOutputsError, MultipleToolsBoundError, PIIDetectionError, ProviderStrategy, StructuredOutputParsingError, StructuredTool, SystemMessage, SystemMessageChunk, TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, Tool, ToolCallLimitExceededError, ToolInvocationError, ToolMessage, ToolMessageChunk, ToolStrategy, anthropicPromptCachingMiddleware, applyStrategy, bedrockPromptCachingMiddleware, browser_exports, context, contextEditingMiddleware, countTokensApproximately, createAgent, createMiddleware, createSubagentTransformer, createToolCallTransformer, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, dynamicSystemPromptMiddleware, fakeModel, filterMessages, humanInTheLoopMiddleware, initChatModel, isToolApprovalInterrupt, langchainMatchers, llmToolSelectorMiddleware, modelCallLimitMiddleware, modelFallbackMiddleware, modelRetryMiddleware, openAIModerationMiddleware, piiMiddleware, piiRedactionMiddleware, providerStrategy, providerToolSearchMiddleware, resolveRedactionRule, summarizationMiddleware, todoListMiddleware, tool, toolCallLimitMiddleware, toolEmulatorMiddleware, toolErrorMiddleware, toolRetryMiddleware, toolStrategy, trimMessages };
|
|
113
114
|
|
|
114
115
|
//# sourceMappingURL=browser.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -88,6 +88,7 @@ var src_exports = /* @__PURE__ */ require_runtime.__exportAll({
|
|
|
88
88
|
filterMessages: () => _langchain_core_messages.filterMessages,
|
|
89
89
|
humanInTheLoopMiddleware: () => require_hitl.humanInTheLoopMiddleware,
|
|
90
90
|
initChatModel: () => require_chat_models_universal.initChatModel,
|
|
91
|
+
isToolApprovalInterrupt: () => require_hitl.isToolApprovalInterrupt,
|
|
91
92
|
langchainMatchers: () => _langchain_core_testing.langchainMatchers,
|
|
92
93
|
llmToolSelectorMiddleware: () => require_llmToolSelector.llmToolSelectorMiddleware,
|
|
93
94
|
modelCallLimitMiddleware: () => require_modelCallLimit.modelCallLimitMiddleware,
|
|
@@ -254,6 +255,7 @@ Object.defineProperty(exports, "filterMessages", {
|
|
|
254
255
|
});
|
|
255
256
|
exports.humanInTheLoopMiddleware = require_hitl.humanInTheLoopMiddleware;
|
|
256
257
|
exports.initChatModel = require_chat_models_universal.initChatModel;
|
|
258
|
+
exports.isToolApprovalInterrupt = require_hitl.isToolApprovalInterrupt;
|
|
257
259
|
Object.defineProperty(exports, "langchainMatchers", {
|
|
258
260
|
enumerable: true,
|
|
259
261
|
get: function() {
|
package/dist/index.d.cts
CHANGED
|
@@ -14,7 +14,7 @@ import { ReactAgent } from "./agents/ReactAgent.cjs";
|
|
|
14
14
|
import { createMiddleware } from "./agents/middleware.cjs";
|
|
15
15
|
import { FakeToolCallingModel } from "./agents/tests/utils.cjs";
|
|
16
16
|
import { createAgent } from "./agents/index.cjs";
|
|
17
|
-
import { Action, ActionRequest, ApproveDecision, Decision, DecisionType, DescriptionFactory, EditDecision, HITLRequest, HITLResponse, HumanInTheLoopMiddlewareConfig, InterruptOnConfig, RejectDecision, RespondDecision, ReviewConfig, WhenPredicate, humanInTheLoopMiddleware } from "./agents/middleware/hitl.cjs";
|
|
17
|
+
import { Action, ActionRequest, ApproveDecision, Decision, DecisionType, DescriptionFactory, EditDecision, HITLRequest, HITLResponse, HumanInTheLoopMiddlewareConfig, InterruptOnConfig, RejectDecision, RespondDecision, ReviewConfig, ToolApprovalDecision, ToolApprovalRequest, WhenPredicate, humanInTheLoopMiddleware, isToolApprovalInterrupt } from "./agents/middleware/hitl.cjs";
|
|
18
18
|
import { SummarizationMiddlewareConfig, TokenCounter, summarizationMiddleware } from "./agents/middleware/summarization.cjs";
|
|
19
19
|
import { DynamicSystemPromptMiddlewareConfig, dynamicSystemPromptMiddleware } from "./agents/middleware/dynamicSystemPrompt.cjs";
|
|
20
20
|
import { LLMToolSelectorConfig, llmToolSelectorMiddleware } from "./agents/middleware/llmToolSelector.cjs";
|
|
@@ -41,4 +41,4 @@ import { context } from "@langchain/core/utils/context";
|
|
|
41
41
|
import { InMemoryStore } from "@langchain/core/stores";
|
|
42
42
|
import { Document, DocumentInput } from "@langchain/core/documents";
|
|
43
43
|
import { LangChainMatchers, fakeModel, langchainMatchers } from "@langchain/core/testing";
|
|
44
|
-
export { AIMessage, AIMessageChunk, Action, ActionRequest, type AfterAgentHook, type AfterModelHook, type AgentMiddleware, type AgentRunStream, AgentTypeConfig, type AnyAgentMiddleware, type AnyAnnotationRoot, ApproveDecision, BaseMessage, BaseMessageChunk, type BedrockConversePromptCachingMiddlewareConfig, type BeforeAgentHook, type BeforeModelHook, type BuiltInPIIType, BuiltInState, ClearToolUsesEdit, type ClearToolUsesEditConfig, CombineStreamTransformers, CombineTools, type ContentBlock, type ContextEdit, type ContextEditingMiddlewareConfig, CreateAgentParams, Decision, DecisionType, DefaultAgentTypeConfig, type DefaultMiddlewareTypeConfig, DescriptionFactory, Document, type DocumentInput, DynamicStructuredTool, type DynamicSystemPromptMiddlewareConfig, DynamicTool, EditDecision, ExecutedToolCall, ExtractZodArrayTypes, FakeToolCallingModel, HITLRequest, HITLResponse, type HeadlessTool, type HeadlessToolFields, type HeadlessToolImplementation, HumanInTheLoopMiddlewareConfig, HumanMessage, HumanMessageChunk, InMemoryStore, InferAgentContext, InferAgentContextSchema, InferAgentMiddleware, InferAgentResponse, InferAgentState, InferAgentStateSchema, InferAgentStreamTransformers, InferAgentTools, InferAgentType, type InferChannelType, type InferContextInput, type InferMergedInputState, type InferMergedState, type InferMiddlewareContext, type InferMiddlewareContextInput, type InferMiddlewareContextInputs, type InferMiddlewareContextSchema, type InferMiddlewareContexts, type InferMiddlewareFullContext, type InferMiddlewareInputState, type InferMiddlewareInputStates, type InferMiddlewareSchema, type InferMiddlewareState, type InferMiddlewareStates, InferMiddlewareStreamTransformers, InferMiddlewareStreamTransformersArray, type InferMiddlewareStreamTransformersFromConfig, InferMiddlewareTools, InferMiddlewareToolsArray, type InferMiddlewareToolsFromConfig, type InferMiddlewareType, type InferSchemaInput, type InferSchemaUpdateType, type InferSchemaValue, type InferSchemaValueType, Interrupt, InterruptOnConfig, JumpTo, type JumpToTarget, type LLMToolSelectorConfig, type LangChainMatchers, MIDDLEWARE_BRAND, MiddlewareError, type MiddlewareResult, type MiddlewareTypeConfig, type ModelCallLimitMiddlewareConfig, ModelRequest, type ModelRetryMiddlewareConfig, MultipleStructuredOutputsError, MultipleToolsBoundError, N, type NormalizedSchemaInput, type NormalizedSchemaUpdate, type OpenAIModerationMiddlewareOptions, PIIDetectionError, type PIIDetector, type PIIMatch, type PIIMiddlewareConfig, type PIIRedactionMiddlewareConfig, type PIIStrategy, type PromptCachingMiddlewareConfig, ProviderStrategy, type ProviderToolSearchMiddlewareConfig, type ReactAgent, type RedactionRuleConfig, RejectDecision, ResolveAgentTypeConfig, type ResolveMiddlewareTypeConfig, type ResolvedRedactionRule, RespondDecision, type ResponseFormat, type ResponseFormatUndefined, ReviewConfig, type Runtime, StructuredOutputParsingError, StructuredTool, type SubagentRunStream, type SummarizationMiddlewareConfig, SystemMessage, SystemMessageChunk, TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, type ToAnnotationRoot, type Todo, type TodoListMiddlewareOptions, type TokenCounter, Tool, ToolCall, type ToolCallHandler, type ToolCallLimitConfig, ToolCallLimitExceededError, type ToolCallRequest, type ToolCallStreamUnion, type ToolEmulatorOptions, type ToolErrorHandler, type ToolErrorMiddlewareConfig, ToolInvocationError, ToolMessage, ToolMessageChunk, ToolResult, type ToolRetryMiddlewareConfig, type ToolRuntime, ToolStrategy, ToolsToMessageToolSet, type TypedToolStrategy, UserInput, WhenPredicate, WithStateGraphNodes, type WrapModelCallHandler, type WrapModelCallHook, type WrapToolCallHook, anthropicPromptCachingMiddleware, applyStrategy, bedrockPromptCachingMiddleware, context, contextEditingMiddleware, countTokensApproximately, createAgent, createMiddleware, createSubagentTransformer, createToolCallTransformer, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, dynamicSystemPromptMiddleware, fakeModel, filterMessages, humanInTheLoopMiddleware, initChatModel, langchainMatchers, llmToolSelectorMiddleware, modelCallLimitMiddleware, modelFallbackMiddleware, modelRetryMiddleware, openAIModerationMiddleware, piiMiddleware, piiRedactionMiddleware, providerStrategy, providerToolSearchMiddleware, resolveRedactionRule, summarizationMiddleware, todoListMiddleware, tool, toolCallLimitMiddleware, toolEmulatorMiddleware, toolErrorMiddleware, toolRetryMiddleware, toolStrategy, trimMessages };
|
|
44
|
+
export { AIMessage, AIMessageChunk, Action, ActionRequest, type AfterAgentHook, type AfterModelHook, type AgentMiddleware, type AgentRunStream, AgentTypeConfig, type AnyAgentMiddleware, type AnyAnnotationRoot, ApproveDecision, BaseMessage, BaseMessageChunk, type BedrockConversePromptCachingMiddlewareConfig, type BeforeAgentHook, type BeforeModelHook, type BuiltInPIIType, BuiltInState, ClearToolUsesEdit, type ClearToolUsesEditConfig, CombineStreamTransformers, CombineTools, type ContentBlock, type ContextEdit, type ContextEditingMiddlewareConfig, CreateAgentParams, Decision, DecisionType, DefaultAgentTypeConfig, type DefaultMiddlewareTypeConfig, DescriptionFactory, Document, type DocumentInput, DynamicStructuredTool, type DynamicSystemPromptMiddlewareConfig, DynamicTool, EditDecision, ExecutedToolCall, ExtractZodArrayTypes, FakeToolCallingModel, HITLRequest, HITLResponse, type HeadlessTool, type HeadlessToolFields, type HeadlessToolImplementation, HumanInTheLoopMiddlewareConfig, HumanMessage, HumanMessageChunk, InMemoryStore, InferAgentContext, InferAgentContextSchema, InferAgentMiddleware, InferAgentResponse, InferAgentState, InferAgentStateSchema, InferAgentStreamTransformers, InferAgentTools, InferAgentType, type InferChannelType, type InferContextInput, type InferMergedInputState, type InferMergedState, type InferMiddlewareContext, type InferMiddlewareContextInput, type InferMiddlewareContextInputs, type InferMiddlewareContextSchema, type InferMiddlewareContexts, type InferMiddlewareFullContext, type InferMiddlewareInputState, type InferMiddlewareInputStates, type InferMiddlewareSchema, type InferMiddlewareState, type InferMiddlewareStates, InferMiddlewareStreamTransformers, InferMiddlewareStreamTransformersArray, type InferMiddlewareStreamTransformersFromConfig, InferMiddlewareTools, InferMiddlewareToolsArray, type InferMiddlewareToolsFromConfig, type InferMiddlewareType, type InferSchemaInput, type InferSchemaUpdateType, type InferSchemaValue, type InferSchemaValueType, Interrupt, InterruptOnConfig, JumpTo, type JumpToTarget, type LLMToolSelectorConfig, type LangChainMatchers, MIDDLEWARE_BRAND, MiddlewareError, type MiddlewareResult, type MiddlewareTypeConfig, type ModelCallLimitMiddlewareConfig, ModelRequest, type ModelRetryMiddlewareConfig, MultipleStructuredOutputsError, MultipleToolsBoundError, N, type NormalizedSchemaInput, type NormalizedSchemaUpdate, type OpenAIModerationMiddlewareOptions, PIIDetectionError, type PIIDetector, type PIIMatch, type PIIMiddlewareConfig, type PIIRedactionMiddlewareConfig, type PIIStrategy, type PromptCachingMiddlewareConfig, ProviderStrategy, type ProviderToolSearchMiddlewareConfig, type ReactAgent, type RedactionRuleConfig, RejectDecision, ResolveAgentTypeConfig, type ResolveMiddlewareTypeConfig, type ResolvedRedactionRule, RespondDecision, type ResponseFormat, type ResponseFormatUndefined, ReviewConfig, type Runtime, StructuredOutputParsingError, StructuredTool, type SubagentRunStream, type SummarizationMiddlewareConfig, SystemMessage, SystemMessageChunk, TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, type ToAnnotationRoot, type Todo, type TodoListMiddlewareOptions, type TokenCounter, Tool, ToolApprovalDecision, ToolApprovalRequest, ToolCall, type ToolCallHandler, type ToolCallLimitConfig, ToolCallLimitExceededError, type ToolCallRequest, type ToolCallStreamUnion, type ToolEmulatorOptions, type ToolErrorHandler, type ToolErrorMiddlewareConfig, ToolInvocationError, ToolMessage, ToolMessageChunk, ToolResult, type ToolRetryMiddlewareConfig, type ToolRuntime, ToolStrategy, ToolsToMessageToolSet, type TypedToolStrategy, UserInput, WhenPredicate, WithStateGraphNodes, type WrapModelCallHandler, type WrapModelCallHook, type WrapToolCallHook, anthropicPromptCachingMiddleware, applyStrategy, bedrockPromptCachingMiddleware, context, contextEditingMiddleware, countTokensApproximately, createAgent, createMiddleware, createSubagentTransformer, createToolCallTransformer, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, dynamicSystemPromptMiddleware, fakeModel, filterMessages, humanInTheLoopMiddleware, initChatModel, isToolApprovalInterrupt, langchainMatchers, llmToolSelectorMiddleware, modelCallLimitMiddleware, modelFallbackMiddleware, modelRetryMiddleware, openAIModerationMiddleware, piiMiddleware, piiRedactionMiddleware, providerStrategy, providerToolSearchMiddleware, resolveRedactionRule, summarizationMiddleware, todoListMiddleware, tool, toolCallLimitMiddleware, toolEmulatorMiddleware, toolErrorMiddleware, toolRetryMiddleware, toolStrategy, trimMessages };
|