langchain 1.1.6-dev-1765433794876 → 1.1.6
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 +21 -0
- package/chat_models/universal.cjs +1 -0
- package/chat_models/universal.d.cts +1 -0
- package/chat_models/universal.d.ts +1 -0
- package/chat_models/universal.js +1 -0
- package/dist/agents/index.cjs +1 -0
- package/dist/agents/index.cjs.map +1 -1
- package/dist/agents/index.d.cts +1 -1
- package/dist/agents/index.d.cts.map +1 -1
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +1 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/middleware/dynamicSystemPrompt.d.ts.map +1 -1
- package/dist/agents/middleware/hitl.d.ts.map +1 -1
- package/dist/agents/middleware/llmToolSelector.d.cts +4 -4
- package/dist/agents/middleware/llmToolSelector.d.cts.map +1 -1
- package/dist/agents/middleware/summarization.cjs +10 -2
- package/dist/agents/middleware/summarization.cjs.map +1 -1
- package/dist/agents/middleware/summarization.d.cts +7 -7
- package/dist/agents/middleware/summarization.d.cts.map +1 -1
- package/dist/agents/middleware/summarization.d.ts.map +1 -1
- package/dist/agents/middleware/summarization.js +10 -2
- package/dist/agents/middleware/summarization.js.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.ts.map +1 -1
- package/dist/agents/middleware/toolCallLimit.d.ts.map +1 -1
- package/dist/agents/middleware/types.cjs +12 -0
- package/dist/agents/middleware/types.cjs.map +1 -0
- package/dist/agents/middleware/types.d.cts +12 -1
- package/dist/agents/middleware/types.d.cts.map +1 -1
- package/dist/agents/middleware/types.d.ts +12 -1
- package/dist/agents/middleware/types.d.ts.map +1 -1
- package/dist/agents/middleware/types.js +11 -0
- package/dist/agents/middleware/types.js.map +1 -0
- package/dist/agents/middleware.cjs +2 -0
- package/dist/agents/middleware.cjs.map +1 -1
- package/dist/agents/middleware.d.cts.map +1 -1
- package/dist/agents/middleware.d.ts.map +1 -1
- package/dist/agents/middleware.js +3 -0
- package/dist/agents/middleware.js.map +1 -1
- package/dist/agents/nodes/AgentNode.cjs +3 -2
- package/dist/agents/nodes/AgentNode.cjs.map +1 -1
- package/dist/agents/nodes/AgentNode.js +3 -2
- package/dist/agents/nodes/AgentNode.js.map +1 -1
- package/dist/agents/responses.cjs +94 -14
- package/dist/agents/responses.cjs.map +1 -1
- package/dist/agents/responses.d.cts +67 -6
- package/dist/agents/responses.d.cts.map +1 -1
- package/dist/agents/responses.d.ts +67 -6
- package/dist/agents/responses.d.ts.map +1 -1
- package/dist/agents/responses.js +94 -14
- package/dist/agents/responses.js.map +1 -1
- package/dist/agents/tests/utils.cjs.map +1 -1
- package/dist/agents/tests/utils.js.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -1
- package/hub/node.cjs +1 -0
- package/hub/node.d.cts +1 -0
- package/hub/node.d.ts +1 -0
- package/hub/node.js +1 -0
- package/hub.cjs +1 -0
- package/hub.d.cts +1 -0
- package/hub.d.ts +1 -0
- package/hub.js +1 -0
- package/load/serializable.cjs +1 -0
- package/load/serializable.d.cts +1 -0
- package/load/serializable.d.ts +1 -0
- package/load/serializable.js +1 -0
- package/load.cjs +1 -0
- package/load.d.cts +1 -0
- package/load.d.ts +1 -0
- package/load.js +1 -0
- package/package.json +5 -5
- package/storage/encoder_backed.cjs +1 -0
- package/storage/encoder_backed.d.cts +1 -0
- package/storage/encoder_backed.d.ts +1 -0
- package/storage/encoder_backed.js +1 -0
- package/storage/file_system.cjs +1 -0
- package/storage/file_system.d.cts +1 -0
- package/storage/file_system.d.ts +1 -0
- package/storage/file_system.js +1 -0
- package/storage/in_memory.cjs +1 -0
- package/storage/in_memory.d.cts +1 -0
- package/storage/in_memory.d.ts +1 -0
- package/storage/in_memory.js +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hitl.d.ts","names":["z","ToolCall","InferInteropZodInput","AgentBuiltInState","Runtime","DescriptionFunctionSchema","Record","ZodTypeDef","ZodType","ZodUnknown","ZodTuple","ZodString","ZodPromise","ZodUnion","ZodFunction","DescriptionFactory","infer","DecisionType","ZodEnum","InterruptOnConfigSchema","ZodArray","ZodOptional","ZodAny","ZodRecord","ZodTypeAny","Promise","ZodObject","InterruptOnConfig","input","Action","ActionRequest","ReviewConfig","HITLRequest","ApproveDecision","EditDecision","RejectDecision","Decision","HITLResponse","contextSchema","ZodBoolean","ZodDefault","HumanInTheLoopMiddlewareConfig","humanInTheLoopMiddleware","NonNullable","__types_js8","AgentMiddleware"],"sources":["../../../src/agents/middleware/hitl.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { ToolCall } from \"@langchain/core/messages\";\nimport { InferInteropZodInput } from \"@langchain/core/utils/types\";\nimport type { AgentBuiltInState, Runtime } from \"../runtime.js\";\ndeclare const DescriptionFunctionSchema: z.ZodFunction<z.ZodTuple<[z.ZodType<ToolCall<string, Record<string, any>>, z.ZodTypeDef, ToolCall<string, Record<string, any>>>, z.ZodType<AgentBuiltInState, z.ZodTypeDef, AgentBuiltInState>, z.ZodType<Runtime<unknown>, z.ZodTypeDef, Runtime<unknown>>], z.ZodUnknown>, z.ZodUnion<[z.ZodString, z.ZodPromise<z.ZodString>]>>;\n/**\n * Function type that dynamically generates a description for a tool call approval request.\n *\n * @param toolCall - The tool call being reviewed\n * @param state - The current agent state\n * @param runtime - The agent runtime context\n * @returns A string description or Promise that resolves to a string description\n *\n * @example\n * ```typescript\n * import { type DescriptionFactory, type ToolCall } from \"langchain\";\n *\n * const descriptionFactory: DescriptionFactory = (toolCall, state, runtime) => {\n * return `Please review: ${toolCall.name}(${JSON.stringify(toolCall.args)})`;\n * };\n * ```\n */\nexport type DescriptionFactory = z.infer<typeof DescriptionFunctionSchema>;\ndeclare const DecisionType: z.ZodEnum<[\"approve\", \"edit\", \"reject\"]>;\nexport type DecisionType = z.infer<typeof DecisionType>;\ndeclare const InterruptOnConfigSchema: z.ZodObject<{\n /**\n * The decisions that are allowed for this action.\n */\n allowedDecisions: z.ZodArray<z.ZodEnum<[\"approve\", \"edit\", \"reject\"]>, \"many\">;\n /**\n * The description attached to the request for human input.\n * Can be either:\n * - A static string describing the approval request\n * - A callable that dynamically generates the description based on agent state,\n * runtime, and tool call information\n *\n * @example\n * Static string description\n * ```typescript\n * import type { InterruptOnConfig } from \"langchain\";\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: \"Please review this tool execution\"\n * };\n * ```\n *\n * @example\n * Dynamic callable description\n * ```typescript\n * import type {\n * AgentBuiltInState,\n * Runtime,\n * DescriptionFactory,\n * ToolCall,\n * InterruptOnConfig\n * } from \"langchain\";\n *\n * const formatToolDescription: DescriptionFactory = (\n * toolCall: ToolCall,\n * state: AgentBuiltInState,\n * runtime: Runtime<unknown>\n * ) => {\n * return `Tool: ${toolCall.name}\\nArguments:\\n${JSON.stringify(toolCall.args, null, 2)}`;\n * };\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"edit\"],\n * description: formatToolDescription\n * };\n * ```\n */\n description: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodType<ToolCall<string, Record<string, any>>, z.ZodTypeDef, ToolCall<string, Record<string, any>>>, z.ZodType<AgentBuiltInState, z.ZodTypeDef, AgentBuiltInState>, z.ZodType<Runtime<unknown>, z.ZodTypeDef, Runtime<unknown>>], z.ZodUnknown>, z.ZodUnion<[z.ZodString, z.ZodPromise<z.ZodString>]>>]>>;\n /**\n * JSON schema for the arguments associated with the action, if edits are allowed.\n */\n argsSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;\n}, \"strip\", z.ZodTypeAny, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n}, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n}>;\nexport type InterruptOnConfig = z.input<typeof InterruptOnConfigSchema>;\n/**\n * Represents an action with a name and arguments.\n */\nexport interface Action {\n /**\n * The type or name of action being requested (e.g., \"add_numbers\").\n */\n name: string;\n /**\n * Key-value pairs of arguments needed for the action (e.g., {\"a\": 1, \"b\": 2}).\n */\n args: Record<string, any>;\n}\n/**\n * Represents an action request with a name, arguments, and description.\n */\nexport interface ActionRequest {\n /**\n * The name of the action being requested.\n */\n name: string;\n /**\n * Key-value pairs of arguments needed for the action (e.g., {\"a\": 1, \"b\": 2}).\n */\n args: Record<string, any>;\n /**\n * The description of the action to be reviewed.\n */\n description?: string;\n}\n/**\n * Policy for reviewing a HITL request.\n */\nexport interface ReviewConfig {\n /**\n * Name of the action associated with this review configuration.\n */\n actionName: string;\n /**\n * The decisions that are allowed for this request.\n */\n allowedDecisions: DecisionType[];\n /**\n * JSON schema for the arguments associated with the action, if edits are allowed.\n */\n argsSchema?: Record<string, any>;\n}\n/**\n * Request for human feedback on a sequence of actions requested by a model.\n *\n * @example\n * ```ts\n * const hitlRequest: HITLRequest = {\n * actionRequests: [\n * { name: \"send_email\", args: { to: \"user@example.com\", subject: \"Hello\" } }\n * ],\n * reviewConfigs: [\n * {\n * actionName: \"send_email\",\n * allowedDecisions: [\"approve\", \"edit\", \"reject\"],\n * description: \"Please review the email before sending\"\n * }\n * ]\n * };\n * const response = interrupt(hitlRequest);\n * ```\n */\nexport interface HITLRequest {\n /**\n * A list of agent actions for human review.\n */\n actionRequests: ActionRequest[];\n /**\n * Review configuration for all possible actions.\n */\n reviewConfigs: ReviewConfig[];\n}\n/**\n * Response when a human approves the action.\n */\nexport interface ApproveDecision {\n type: \"approve\";\n}\n/**\n * Response when a human edits the action.\n */\nexport interface EditDecision {\n type: \"edit\";\n /**\n * Edited action for the agent to perform.\n * Ex: for a tool call, a human reviewer can edit the tool name and args.\n */\n editedAction: Action;\n}\n/**\n * Response when a human rejects the action.\n */\nexport interface RejectDecision {\n type: \"reject\";\n /**\n * The message sent to the model explaining why the action was rejected.\n */\n message?: string;\n}\n/**\n * Union of all possible decision types.\n */\nexport type Decision = ApproveDecision | EditDecision | RejectDecision;\n/**\n * Response payload for a HITLRequest.\n */\nexport interface HITLResponse {\n /**\n * The decisions made by the human.\n */\n decisions: Decision[];\n}\ndeclare const contextSchema: z.ZodObject<{\n /**\n * Mapping of tool name to allowed reviewer responses.\n * If a tool doesn't have an entry, it's auto-approved by default.\n *\n * - `true` -> pause for approval and allow approve/edit/reject decisions\n * - `false` -> auto-approve (no human review)\n * - `InterruptOnConfig` -> explicitly specify which decisions are allowed for this tool\n */\n interruptOn: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodBoolean, z.ZodObject<{\n /**\n * The decisions that are allowed for this action.\n */\n allowedDecisions: z.ZodArray<z.ZodEnum<[\"approve\", \"edit\", \"reject\"]>, \"many\">;\n /**\n * The description attached to the request for human input.\n * Can be either:\n * - A static string describing the approval request\n * - A callable that dynamically generates the description based on agent state,\n * runtime, and tool call information\n *\n * @example\n * Static string description\n * ```typescript\n * import type { InterruptOnConfig } from \"langchain\";\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: \"Please review this tool execution\"\n * };\n * ```\n *\n * @example\n * Dynamic callable description\n * ```typescript\n * import type {\n * AgentBuiltInState,\n * Runtime,\n * DescriptionFactory,\n * ToolCall,\n * InterruptOnConfig\n * } from \"langchain\";\n *\n * const formatToolDescription: DescriptionFactory = (\n * toolCall: ToolCall,\n * state: AgentBuiltInState,\n * runtime: Runtime<unknown>\n * ) => {\n * return `Tool: ${toolCall.name}\\nArguments:\\n${JSON.stringify(toolCall.args, null, 2)}`;\n * };\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"edit\"],\n * description: formatToolDescription\n * };\n * ```\n */\n description: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodType<ToolCall<string, Record<string, any>>, z.ZodTypeDef, ToolCall<string, Record<string, any>>>, z.ZodType<AgentBuiltInState, z.ZodTypeDef, AgentBuiltInState>, z.ZodType<Runtime<unknown>, z.ZodTypeDef, Runtime<unknown>>], z.ZodUnknown>, z.ZodUnion<[z.ZodString, z.ZodPromise<z.ZodString>]>>]>>;\n /**\n * JSON schema for the arguments associated with the action, if edits are allowed.\n */\n argsSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;\n }, \"strip\", z.ZodTypeAny, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }>]>>>;\n /**\n * Prefix used when constructing human-facing approval messages.\n * Provides context about the tool call being reviewed; does not change the underlying action.\n *\n * Note: This prefix is only applied for tools that do not provide a custom\n * `description` via their {@link InterruptOnConfig}. If a tool specifies a custom\n * `description`, that per-tool text is used and this prefix is ignored.\n */\n descriptionPrefix: z.ZodDefault<z.ZodString>;\n}, \"strip\", z.ZodTypeAny, {\n interruptOn?: Record<string, boolean | {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }> | undefined;\n descriptionPrefix: string;\n}, {\n interruptOn?: Record<string, boolean | {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }> | undefined;\n descriptionPrefix?: string | undefined;\n}>;\nexport type HumanInTheLoopMiddlewareConfig = InferInteropZodInput<typeof contextSchema>;\n/**\n * Creates a Human-in-the-Loop (HITL) middleware for tool approval and oversight.\n *\n * This middleware intercepts tool calls made by an AI agent and provides human oversight\n * capabilities before execution. It enables selective approval workflows where certain tools\n * require human intervention while others can execute automatically.\n *\n * A invocation result that has been interrupted by the middleware will have a `__interrupt__`\n * property that contains the interrupt request.\n *\n * ```ts\n * import { type HITLRequest, type HITLResponse } from \"langchain\";\n * import { type Interrupt } from \"langchain\";\n *\n * const result = await agent.invoke(request);\n * const interruptRequest = result.__interrupt__?.[0] as Interrupt<HITLRequest>;\n *\n * // Examine the action requests and review configs\n * const actionRequests = interruptRequest.value.actionRequests;\n * const reviewConfigs = interruptRequest.value.reviewConfigs;\n *\n * // Create decisions for each action\n * const resume: HITLResponse = {\n * decisions: actionRequests.map((action, i) => {\n * if (action.name === \"calculator\") {\n * return { type: \"approve\" };\n * } else if (action.name === \"write_file\") {\n * return {\n * type: \"edit\",\n * editedAction: { name: \"write_file\", args: { filename: \"safe.txt\", content: \"Safe content\" } }\n * };\n * }\n * return { type: \"reject\", message: \"Action not allowed\" };\n * })\n * };\n *\n * // Resume with decisions\n * await agent.invoke(new Command({ resume }), config);\n * ```\n *\n * ## Features\n *\n * - **Selective Tool Approval**: Configure which tools require human approval\n * - **Multiple Decision Types**: Approve, edit, or reject tool calls\n * - **Asynchronous Workflow**: Uses LangGraph's interrupt mechanism for non-blocking approval\n * - **Custom Approval Messages**: Provide context-specific descriptions for approval requests\n *\n * ## Decision Types\n *\n * When a tool requires approval, the human operator can respond with:\n * - `approve`: Execute the tool with original arguments\n * - `edit`: Modify the tool name and/or arguments before execution\n * - `reject`: Provide a manual response instead of executing the tool\n *\n * @param options - Configuration options for the middleware\n * @param options.interruptOn - Per-tool configuration mapping tool names to their settings\n * @param options.interruptOn[toolName].allowedDecisions - Array of decision types allowed for this tool (e.g., [\"approve\", \"edit\", \"reject\"])\n * @param options.interruptOn[toolName].description - Custom approval message for the tool. Can be either a static string or a callable that dynamically generates the description based on agent state, runtime, and tool call information\n * @param options.interruptOn[toolName].argsSchema - JSON schema for the arguments associated with the action, if edits are allowed\n * @param options.descriptionPrefix - Default prefix for approval messages (default: \"Tool execution requires approval\"). Only used for tools that do not define a custom `description` in their InterruptOnConfig.\n *\n * @returns A middleware instance that can be passed to `createAgent`\n *\n * @example\n * Basic usage with selective tool approval\n * ```typescript\n * import { humanInTheLoopMiddleware } from \"langchain\";\n * import { createAgent } from \"langchain\";\n *\n * const hitlMiddleware = humanInTheLoopMiddleware({\n * interruptOn: {\n * // Interrupt write_file tool and allow edits or approvals\n * \"write_file\": {\n * allowedDecisions: [\"approve\", \"edit\"],\n * description: \"⚠️ File write operation requires approval\"\n * },\n * // Auto-approve read_file tool\n * \"read_file\": false\n * }\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4\",\n * tools: [writeFileTool, readFileTool],\n * middleware: [hitlMiddleware]\n * });\n * ```\n *\n * @example\n * Handling approval requests\n * ```typescript\n * import { type HITLRequest, type HITLResponse, type Interrupt } from \"langchain\";\n * import { Command } from \"@langchain/langgraph\";\n *\n * // Initial agent invocation\n * const result = await agent.invoke({\n * messages: [new HumanMessage(\"Write 'Hello' to output.txt\")]\n * }, config);\n *\n * // Check if agent is paused for approval\n * if (result.__interrupt__) {\n * const interruptRequest = result.__interrupt__?.[0] as Interrupt<HITLRequest>;\n *\n * // Show tool call details to user\n * console.log(\"Actions:\", interruptRequest.value.actionRequests);\n * console.log(\"Review configs:\", interruptRequest.value.reviewConfigs);\n *\n * // Resume with approval\n * const resume: HITLResponse = {\n * decisions: [{ type: \"approve\" }]\n * };\n * await agent.invoke(\n * new Command({ resume }),\n * config\n * );\n * }\n * ```\n *\n * @example\n * Different decision types\n * ```typescript\n * import { type HITLResponse } from \"langchain\";\n *\n * // Approve the tool call as-is\n * const resume: HITLResponse = {\n * decisions: [{ type: \"approve\" }]\n * };\n *\n * // Edit the tool arguments\n * const resume: HITLResponse = {\n * decisions: [{\n * type: \"edit\",\n * editedAction: { name: \"write_file\", args: { filename: \"safe.txt\", content: \"Modified\" } }\n * }]\n * };\n *\n * // Reject with feedback\n * const resume: HITLResponse = {\n * decisions: [{\n * type: \"reject\",\n * message: \"File operation not allowed in demo mode\"\n * }]\n * };\n * ```\n *\n * @example\n * Production use case with database operations\n * ```typescript\n * const hitlMiddleware = humanInTheLoopMiddleware({\n * interruptOn: {\n * \"execute_sql\": {\n * allowedDecisions: [\"approve\", \"edit\", \"reject\"],\n * description: \"🚨 SQL query requires DBA approval\\nPlease review for safety and performance\"\n * },\n * \"read_schema\": false, // Reading metadata is safe\n * \"delete_records\": {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: \"⛔ DESTRUCTIVE OPERATION - Requires manager approval\"\n * }\n * },\n * descriptionPrefix: \"Database operation pending approval\"\n * });\n * ```\n *\n * @example\n * Using dynamic callable descriptions\n * ```typescript\n * import { type DescriptionFactory, type ToolCall } from \"langchain\";\n * import type { AgentBuiltInState, Runtime } from \"langchain/agents\";\n *\n * // Define a dynamic description factory\n * const formatToolDescription: DescriptionFactory = (\n * toolCall: ToolCall,\n * state: AgentBuiltInState,\n * runtime: Runtime<unknown>\n * ) => {\n * return `Tool: ${toolCall.name}\\nArguments:\\n${JSON.stringify(toolCall.args, null, 2)}`;\n * };\n *\n * const hitlMiddleware = humanInTheLoopMiddleware({\n * interruptOn: {\n * \"write_file\": {\n * allowedDecisions: [\"approve\", \"edit\"],\n * // Use dynamic description that can access tool call, state, and runtime\n * description: formatToolDescription\n * },\n * // Or use an inline function\n * \"send_email\": {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: (toolCall, state, runtime) => {\n * const { to, subject } = toolCall.args;\n * return `Email to ${to}\\nSubject: ${subject}\\n\\nRequires approval before sending`;\n * }\n * }\n * }\n * });\n * ```\n *\n * @remarks\n * - Tool calls are processed in the order they appear in the AI message\n * - Auto-approved tools execute immediately without interruption\n * - Multiple tools requiring approval are bundled into a single interrupt request\n * - The middleware operates in the `afterModel` phase, intercepting before tool execution\n * - Requires a checkpointer to maintain state across interruptions\n *\n * @see {@link createAgent} for agent creation\n * @see {@link Command} for resuming interrupted execution\n * @public\n */\nexport declare function humanInTheLoopMiddleware(options: NonNullable<HumanInTheLoopMiddlewareConfig>): import(\"./types.js\").AgentMiddleware<undefined, z.ZodObject<{\n /**\n * Mapping of tool name to allowed reviewer responses.\n * If a tool doesn't have an entry, it's auto-approved by default.\n *\n * - `true` -> pause for approval and allow approve/edit/reject decisions\n * - `false` -> auto-approve (no human review)\n * - `InterruptOnConfig` -> explicitly specify which decisions are allowed for this tool\n */\n interruptOn: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodBoolean, z.ZodObject<{\n /**\n * The decisions that are allowed for this action.\n */\n allowedDecisions: z.ZodArray<z.ZodEnum<[\"approve\", \"edit\", \"reject\"]>, \"many\">;\n /**\n * The description attached to the request for human input.\n * Can be either:\n * - A static string describing the approval request\n * - A callable that dynamically generates the description based on agent state,\n * runtime, and tool call information\n *\n * @example\n * Static string description\n * ```typescript\n * import type { InterruptOnConfig } from \"langchain\";\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: \"Please review this tool execution\"\n * };\n * ```\n *\n * @example\n * Dynamic callable description\n * ```typescript\n * import type {\n * AgentBuiltInState,\n * Runtime,\n * DescriptionFactory,\n * ToolCall,\n * InterruptOnConfig\n * } from \"langchain\";\n *\n * const formatToolDescription: DescriptionFactory = (\n * toolCall: ToolCall,\n * state: AgentBuiltInState,\n * runtime: Runtime<unknown>\n * ) => {\n * return `Tool: ${toolCall.name}\\nArguments:\\n${JSON.stringify(toolCall.args, null, 2)}`;\n * };\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"edit\"],\n * description: formatToolDescription\n * };\n * ```\n */\n description: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodType<ToolCall<string, Record<string, any>>, z.ZodTypeDef, ToolCall<string, Record<string, any>>>, z.ZodType<AgentBuiltInState, z.ZodTypeDef, AgentBuiltInState>, z.ZodType<Runtime<unknown>, z.ZodTypeDef, Runtime<unknown>>], z.ZodUnknown>, z.ZodUnion<[z.ZodString, z.ZodPromise<z.ZodString>]>>]>>;\n /**\n * JSON schema for the arguments associated with the action, if edits are allowed.\n */\n argsSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;\n }, \"strip\", z.ZodTypeAny, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }>]>>>;\n /**\n * Prefix used when constructing human-facing approval messages.\n * Provides context about the tool call being reviewed; does not change the underlying action.\n *\n * Note: This prefix is only applied for tools that do not provide a custom\n * `description` via their {@link InterruptOnConfig}. If a tool specifies a custom\n * `description`, that per-tool text is used and this prefix is ignored.\n */\n descriptionPrefix: z.ZodDefault<z.ZodString>;\n}, \"strip\", z.ZodTypeAny, {\n interruptOn?: Record<string, boolean | {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }> | undefined;\n descriptionPrefix: string;\n}, {\n interruptOn?: Record<string, boolean | {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }> | undefined;\n descriptionPrefix?: string | undefined;\n}>, any>;\nexport {};\n//# sourceMappingURL=hitl.d.ts.map"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hitl.d.ts","names":["z","ToolCall","InferInteropZodInput","AgentBuiltInState","Runtime","DescriptionFunctionSchema","Record","ZodTypeDef","ZodType","ZodUnknown","ZodTuple","ZodString","ZodPromise","ZodUnion","ZodFunction","DescriptionFactory","infer","DecisionType","ZodEnum","InterruptOnConfigSchema","ZodArray","ZodOptional","ZodAny","ZodRecord","ZodTypeAny","Promise","ZodObject","InterruptOnConfig","input","Action","ActionRequest","ReviewConfig","HITLRequest","ApproveDecision","EditDecision","RejectDecision","Decision","HITLResponse","contextSchema","ZodBoolean","ZodDefault","HumanInTheLoopMiddlewareConfig","humanInTheLoopMiddleware","NonNullable","__types_js7","AgentMiddleware"],"sources":["../../../src/agents/middleware/hitl.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { ToolCall } from \"@langchain/core/messages\";\nimport { InferInteropZodInput } from \"@langchain/core/utils/types\";\nimport type { AgentBuiltInState, Runtime } from \"../runtime.js\";\ndeclare const DescriptionFunctionSchema: z.ZodFunction<z.ZodTuple<[z.ZodType<ToolCall<string, Record<string, any>>, z.ZodTypeDef, ToolCall<string, Record<string, any>>>, z.ZodType<AgentBuiltInState, z.ZodTypeDef, AgentBuiltInState>, z.ZodType<Runtime<unknown>, z.ZodTypeDef, Runtime<unknown>>], z.ZodUnknown>, z.ZodUnion<[z.ZodString, z.ZodPromise<z.ZodString>]>>;\n/**\n * Function type that dynamically generates a description for a tool call approval request.\n *\n * @param toolCall - The tool call being reviewed\n * @param state - The current agent state\n * @param runtime - The agent runtime context\n * @returns A string description or Promise that resolves to a string description\n *\n * @example\n * ```typescript\n * import { type DescriptionFactory, type ToolCall } from \"langchain\";\n *\n * const descriptionFactory: DescriptionFactory = (toolCall, state, runtime) => {\n * return `Please review: ${toolCall.name}(${JSON.stringify(toolCall.args)})`;\n * };\n * ```\n */\nexport type DescriptionFactory = z.infer<typeof DescriptionFunctionSchema>;\ndeclare const DecisionType: z.ZodEnum<[\"approve\", \"edit\", \"reject\"]>;\nexport type DecisionType = z.infer<typeof DecisionType>;\ndeclare const InterruptOnConfigSchema: z.ZodObject<{\n /**\n * The decisions that are allowed for this action.\n */\n allowedDecisions: z.ZodArray<z.ZodEnum<[\"approve\", \"edit\", \"reject\"]>, \"many\">;\n /**\n * The description attached to the request for human input.\n * Can be either:\n * - A static string describing the approval request\n * - A callable that dynamically generates the description based on agent state,\n * runtime, and tool call information\n *\n * @example\n * Static string description\n * ```typescript\n * import type { InterruptOnConfig } from \"langchain\";\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: \"Please review this tool execution\"\n * };\n * ```\n *\n * @example\n * Dynamic callable description\n * ```typescript\n * import type {\n * AgentBuiltInState,\n * Runtime,\n * DescriptionFactory,\n * ToolCall,\n * InterruptOnConfig\n * } from \"langchain\";\n *\n * const formatToolDescription: DescriptionFactory = (\n * toolCall: ToolCall,\n * state: AgentBuiltInState,\n * runtime: Runtime<unknown>\n * ) => {\n * return `Tool: ${toolCall.name}\\nArguments:\\n${JSON.stringify(toolCall.args, null, 2)}`;\n * };\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"edit\"],\n * description: formatToolDescription\n * };\n * ```\n */\n description: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodType<ToolCall<string, Record<string, any>>, z.ZodTypeDef, ToolCall<string, Record<string, any>>>, z.ZodType<AgentBuiltInState, z.ZodTypeDef, AgentBuiltInState>, z.ZodType<Runtime<unknown>, z.ZodTypeDef, Runtime<unknown>>], z.ZodUnknown>, z.ZodUnion<[z.ZodString, z.ZodPromise<z.ZodString>]>>]>>;\n /**\n * JSON schema for the arguments associated with the action, if edits are allowed.\n */\n argsSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;\n}, \"strip\", z.ZodTypeAny, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n}, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n}>;\nexport type InterruptOnConfig = z.input<typeof InterruptOnConfigSchema>;\n/**\n * Represents an action with a name and arguments.\n */\nexport interface Action {\n /**\n * The type or name of action being requested (e.g., \"add_numbers\").\n */\n name: string;\n /**\n * Key-value pairs of arguments needed for the action (e.g., {\"a\": 1, \"b\": 2}).\n */\n args: Record<string, any>;\n}\n/**\n * Represents an action request with a name, arguments, and description.\n */\nexport interface ActionRequest {\n /**\n * The name of the action being requested.\n */\n name: string;\n /**\n * Key-value pairs of arguments needed for the action (e.g., {\"a\": 1, \"b\": 2}).\n */\n args: Record<string, any>;\n /**\n * The description of the action to be reviewed.\n */\n description?: string;\n}\n/**\n * Policy for reviewing a HITL request.\n */\nexport interface ReviewConfig {\n /**\n * Name of the action associated with this review configuration.\n */\n actionName: string;\n /**\n * The decisions that are allowed for this request.\n */\n allowedDecisions: DecisionType[];\n /**\n * JSON schema for the arguments associated with the action, if edits are allowed.\n */\n argsSchema?: Record<string, any>;\n}\n/**\n * Request for human feedback on a sequence of actions requested by a model.\n *\n * @example\n * ```ts\n * const hitlRequest: HITLRequest = {\n * actionRequests: [\n * { name: \"send_email\", args: { to: \"user@example.com\", subject: \"Hello\" } }\n * ],\n * reviewConfigs: [\n * {\n * actionName: \"send_email\",\n * allowedDecisions: [\"approve\", \"edit\", \"reject\"],\n * description: \"Please review the email before sending\"\n * }\n * ]\n * };\n * const response = interrupt(hitlRequest);\n * ```\n */\nexport interface HITLRequest {\n /**\n * A list of agent actions for human review.\n */\n actionRequests: ActionRequest[];\n /**\n * Review configuration for all possible actions.\n */\n reviewConfigs: ReviewConfig[];\n}\n/**\n * Response when a human approves the action.\n */\nexport interface ApproveDecision {\n type: \"approve\";\n}\n/**\n * Response when a human edits the action.\n */\nexport interface EditDecision {\n type: \"edit\";\n /**\n * Edited action for the agent to perform.\n * Ex: for a tool call, a human reviewer can edit the tool name and args.\n */\n editedAction: Action;\n}\n/**\n * Response when a human rejects the action.\n */\nexport interface RejectDecision {\n type: \"reject\";\n /**\n * The message sent to the model explaining why the action was rejected.\n */\n message?: string;\n}\n/**\n * Union of all possible decision types.\n */\nexport type Decision = ApproveDecision | EditDecision | RejectDecision;\n/**\n * Response payload for a HITLRequest.\n */\nexport interface HITLResponse {\n /**\n * The decisions made by the human.\n */\n decisions: Decision[];\n}\ndeclare const contextSchema: z.ZodObject<{\n /**\n * Mapping of tool name to allowed reviewer responses.\n * If a tool doesn't have an entry, it's auto-approved by default.\n *\n * - `true` -> pause for approval and allow approve/edit/reject decisions\n * - `false` -> auto-approve (no human review)\n * - `InterruptOnConfig` -> explicitly specify which decisions are allowed for this tool\n */\n interruptOn: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodBoolean, z.ZodObject<{\n /**\n * The decisions that are allowed for this action.\n */\n allowedDecisions: z.ZodArray<z.ZodEnum<[\"approve\", \"edit\", \"reject\"]>, \"many\">;\n /**\n * The description attached to the request for human input.\n * Can be either:\n * - A static string describing the approval request\n * - A callable that dynamically generates the description based on agent state,\n * runtime, and tool call information\n *\n * @example\n * Static string description\n * ```typescript\n * import type { InterruptOnConfig } from \"langchain\";\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: \"Please review this tool execution\"\n * };\n * ```\n *\n * @example\n * Dynamic callable description\n * ```typescript\n * import type {\n * AgentBuiltInState,\n * Runtime,\n * DescriptionFactory,\n * ToolCall,\n * InterruptOnConfig\n * } from \"langchain\";\n *\n * const formatToolDescription: DescriptionFactory = (\n * toolCall: ToolCall,\n * state: AgentBuiltInState,\n * runtime: Runtime<unknown>\n * ) => {\n * return `Tool: ${toolCall.name}\\nArguments:\\n${JSON.stringify(toolCall.args, null, 2)}`;\n * };\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"edit\"],\n * description: formatToolDescription\n * };\n * ```\n */\n description: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodType<ToolCall<string, Record<string, any>>, z.ZodTypeDef, ToolCall<string, Record<string, any>>>, z.ZodType<AgentBuiltInState, z.ZodTypeDef, AgentBuiltInState>, z.ZodType<Runtime<unknown>, z.ZodTypeDef, Runtime<unknown>>], z.ZodUnknown>, z.ZodUnion<[z.ZodString, z.ZodPromise<z.ZodString>]>>]>>;\n /**\n * JSON schema for the arguments associated with the action, if edits are allowed.\n */\n argsSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;\n }, \"strip\", z.ZodTypeAny, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }>]>>>;\n /**\n * Prefix used when constructing human-facing approval messages.\n * Provides context about the tool call being reviewed; does not change the underlying action.\n *\n * Note: This prefix is only applied for tools that do not provide a custom\n * `description` via their {@link InterruptOnConfig}. If a tool specifies a custom\n * `description`, that per-tool text is used and this prefix is ignored.\n */\n descriptionPrefix: z.ZodDefault<z.ZodString>;\n}, \"strip\", z.ZodTypeAny, {\n interruptOn?: Record<string, boolean | {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }> | undefined;\n descriptionPrefix: string;\n}, {\n interruptOn?: Record<string, boolean | {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }> | undefined;\n descriptionPrefix?: string | undefined;\n}>;\nexport type HumanInTheLoopMiddlewareConfig = InferInteropZodInput<typeof contextSchema>;\n/**\n * Creates a Human-in-the-Loop (HITL) middleware for tool approval and oversight.\n *\n * This middleware intercepts tool calls made by an AI agent and provides human oversight\n * capabilities before execution. It enables selective approval workflows where certain tools\n * require human intervention while others can execute automatically.\n *\n * A invocation result that has been interrupted by the middleware will have a `__interrupt__`\n * property that contains the interrupt request.\n *\n * ```ts\n * import { type HITLRequest, type HITLResponse } from \"langchain\";\n * import { type Interrupt } from \"langchain\";\n *\n * const result = await agent.invoke(request);\n * const interruptRequest = result.__interrupt__?.[0] as Interrupt<HITLRequest>;\n *\n * // Examine the action requests and review configs\n * const actionRequests = interruptRequest.value.actionRequests;\n * const reviewConfigs = interruptRequest.value.reviewConfigs;\n *\n * // Create decisions for each action\n * const resume: HITLResponse = {\n * decisions: actionRequests.map((action, i) => {\n * if (action.name === \"calculator\") {\n * return { type: \"approve\" };\n * } else if (action.name === \"write_file\") {\n * return {\n * type: \"edit\",\n * editedAction: { name: \"write_file\", args: { filename: \"safe.txt\", content: \"Safe content\" } }\n * };\n * }\n * return { type: \"reject\", message: \"Action not allowed\" };\n * })\n * };\n *\n * // Resume with decisions\n * await agent.invoke(new Command({ resume }), config);\n * ```\n *\n * ## Features\n *\n * - **Selective Tool Approval**: Configure which tools require human approval\n * - **Multiple Decision Types**: Approve, edit, or reject tool calls\n * - **Asynchronous Workflow**: Uses LangGraph's interrupt mechanism for non-blocking approval\n * - **Custom Approval Messages**: Provide context-specific descriptions for approval requests\n *\n * ## Decision Types\n *\n * When a tool requires approval, the human operator can respond with:\n * - `approve`: Execute the tool with original arguments\n * - `edit`: Modify the tool name and/or arguments before execution\n * - `reject`: Provide a manual response instead of executing the tool\n *\n * @param options - Configuration options for the middleware\n * @param options.interruptOn - Per-tool configuration mapping tool names to their settings\n * @param options.interruptOn[toolName].allowedDecisions - Array of decision types allowed for this tool (e.g., [\"approve\", \"edit\", \"reject\"])\n * @param options.interruptOn[toolName].description - Custom approval message for the tool. Can be either a static string or a callable that dynamically generates the description based on agent state, runtime, and tool call information\n * @param options.interruptOn[toolName].argsSchema - JSON schema for the arguments associated with the action, if edits are allowed\n * @param options.descriptionPrefix - Default prefix for approval messages (default: \"Tool execution requires approval\"). Only used for tools that do not define a custom `description` in their InterruptOnConfig.\n *\n * @returns A middleware instance that can be passed to `createAgent`\n *\n * @example\n * Basic usage with selective tool approval\n * ```typescript\n * import { humanInTheLoopMiddleware } from \"langchain\";\n * import { createAgent } from \"langchain\";\n *\n * const hitlMiddleware = humanInTheLoopMiddleware({\n * interruptOn: {\n * // Interrupt write_file tool and allow edits or approvals\n * \"write_file\": {\n * allowedDecisions: [\"approve\", \"edit\"],\n * description: \"⚠️ File write operation requires approval\"\n * },\n * // Auto-approve read_file tool\n * \"read_file\": false\n * }\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4\",\n * tools: [writeFileTool, readFileTool],\n * middleware: [hitlMiddleware]\n * });\n * ```\n *\n * @example\n * Handling approval requests\n * ```typescript\n * import { type HITLRequest, type HITLResponse, type Interrupt } from \"langchain\";\n * import { Command } from \"@langchain/langgraph\";\n *\n * // Initial agent invocation\n * const result = await agent.invoke({\n * messages: [new HumanMessage(\"Write 'Hello' to output.txt\")]\n * }, config);\n *\n * // Check if agent is paused for approval\n * if (result.__interrupt__) {\n * const interruptRequest = result.__interrupt__?.[0] as Interrupt<HITLRequest>;\n *\n * // Show tool call details to user\n * console.log(\"Actions:\", interruptRequest.value.actionRequests);\n * console.log(\"Review configs:\", interruptRequest.value.reviewConfigs);\n *\n * // Resume with approval\n * const resume: HITLResponse = {\n * decisions: [{ type: \"approve\" }]\n * };\n * await agent.invoke(\n * new Command({ resume }),\n * config\n * );\n * }\n * ```\n *\n * @example\n * Different decision types\n * ```typescript\n * import { type HITLResponse } from \"langchain\";\n *\n * // Approve the tool call as-is\n * const resume: HITLResponse = {\n * decisions: [{ type: \"approve\" }]\n * };\n *\n * // Edit the tool arguments\n * const resume: HITLResponse = {\n * decisions: [{\n * type: \"edit\",\n * editedAction: { name: \"write_file\", args: { filename: \"safe.txt\", content: \"Modified\" } }\n * }]\n * };\n *\n * // Reject with feedback\n * const resume: HITLResponse = {\n * decisions: [{\n * type: \"reject\",\n * message: \"File operation not allowed in demo mode\"\n * }]\n * };\n * ```\n *\n * @example\n * Production use case with database operations\n * ```typescript\n * const hitlMiddleware = humanInTheLoopMiddleware({\n * interruptOn: {\n * \"execute_sql\": {\n * allowedDecisions: [\"approve\", \"edit\", \"reject\"],\n * description: \"🚨 SQL query requires DBA approval\\nPlease review for safety and performance\"\n * },\n * \"read_schema\": false, // Reading metadata is safe\n * \"delete_records\": {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: \"⛔ DESTRUCTIVE OPERATION - Requires manager approval\"\n * }\n * },\n * descriptionPrefix: \"Database operation pending approval\"\n * });\n * ```\n *\n * @example\n * Using dynamic callable descriptions\n * ```typescript\n * import { type DescriptionFactory, type ToolCall } from \"langchain\";\n * import type { AgentBuiltInState, Runtime } from \"langchain/agents\";\n *\n * // Define a dynamic description factory\n * const formatToolDescription: DescriptionFactory = (\n * toolCall: ToolCall,\n * state: AgentBuiltInState,\n * runtime: Runtime<unknown>\n * ) => {\n * return `Tool: ${toolCall.name}\\nArguments:\\n${JSON.stringify(toolCall.args, null, 2)}`;\n * };\n *\n * const hitlMiddleware = humanInTheLoopMiddleware({\n * interruptOn: {\n * \"write_file\": {\n * allowedDecisions: [\"approve\", \"edit\"],\n * // Use dynamic description that can access tool call, state, and runtime\n * description: formatToolDescription\n * },\n * // Or use an inline function\n * \"send_email\": {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: (toolCall, state, runtime) => {\n * const { to, subject } = toolCall.args;\n * return `Email to ${to}\\nSubject: ${subject}\\n\\nRequires approval before sending`;\n * }\n * }\n * }\n * });\n * ```\n *\n * @remarks\n * - Tool calls are processed in the order they appear in the AI message\n * - Auto-approved tools execute immediately without interruption\n * - Multiple tools requiring approval are bundled into a single interrupt request\n * - The middleware operates in the `afterModel` phase, intercepting before tool execution\n * - Requires a checkpointer to maintain state across interruptions\n *\n * @see {@link createAgent} for agent creation\n * @see {@link Command} for resuming interrupted execution\n * @public\n */\nexport declare function humanInTheLoopMiddleware(options: NonNullable<HumanInTheLoopMiddlewareConfig>): import(\"./types.js\").AgentMiddleware<undefined, z.ZodObject<{\n /**\n * Mapping of tool name to allowed reviewer responses.\n * If a tool doesn't have an entry, it's auto-approved by default.\n *\n * - `true` -> pause for approval and allow approve/edit/reject decisions\n * - `false` -> auto-approve (no human review)\n * - `InterruptOnConfig` -> explicitly specify which decisions are allowed for this tool\n */\n interruptOn: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodBoolean, z.ZodObject<{\n /**\n * The decisions that are allowed for this action.\n */\n allowedDecisions: z.ZodArray<z.ZodEnum<[\"approve\", \"edit\", \"reject\"]>, \"many\">;\n /**\n * The description attached to the request for human input.\n * Can be either:\n * - A static string describing the approval request\n * - A callable that dynamically generates the description based on agent state,\n * runtime, and tool call information\n *\n * @example\n * Static string description\n * ```typescript\n * import type { InterruptOnConfig } from \"langchain\";\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"reject\"],\n * description: \"Please review this tool execution\"\n * };\n * ```\n *\n * @example\n * Dynamic callable description\n * ```typescript\n * import type {\n * AgentBuiltInState,\n * Runtime,\n * DescriptionFactory,\n * ToolCall,\n * InterruptOnConfig\n * } from \"langchain\";\n *\n * const formatToolDescription: DescriptionFactory = (\n * toolCall: ToolCall,\n * state: AgentBuiltInState,\n * runtime: Runtime<unknown>\n * ) => {\n * return `Tool: ${toolCall.name}\\nArguments:\\n${JSON.stringify(toolCall.args, null, 2)}`;\n * };\n *\n * const config: InterruptOnConfig = {\n * allowedDecisions: [\"approve\", \"edit\"],\n * description: formatToolDescription\n * };\n * ```\n */\n description: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodType<ToolCall<string, Record<string, any>>, z.ZodTypeDef, ToolCall<string, Record<string, any>>>, z.ZodType<AgentBuiltInState, z.ZodTypeDef, AgentBuiltInState>, z.ZodType<Runtime<unknown>, z.ZodTypeDef, Runtime<unknown>>], z.ZodUnknown>, z.ZodUnion<[z.ZodString, z.ZodPromise<z.ZodString>]>>]>>;\n /**\n * JSON schema for the arguments associated with the action, if edits are allowed.\n */\n argsSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;\n }, \"strip\", z.ZodTypeAny, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }, {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }>]>>>;\n /**\n * Prefix used when constructing human-facing approval messages.\n * Provides context about the tool call being reviewed; does not change the underlying action.\n *\n * Note: This prefix is only applied for tools that do not provide a custom\n * `description` via their {@link InterruptOnConfig}. If a tool specifies a custom\n * `description`, that per-tool text is used and this prefix is ignored.\n */\n descriptionPrefix: z.ZodDefault<z.ZodString>;\n}, \"strip\", z.ZodTypeAny, {\n interruptOn?: Record<string, boolean | {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }> | undefined;\n descriptionPrefix: string;\n}, {\n interruptOn?: Record<string, boolean | {\n allowedDecisions: (\"approve\" | \"edit\" | \"reject\")[];\n description?: string | ((args_0: ToolCall<string, Record<string, any>>, args_1: AgentBuiltInState, args_2: Runtime<unknown>, ...args: unknown[]) => string | Promise<string>) | undefined;\n argsSchema?: Record<string, any> | undefined;\n }> | undefined;\n descriptionPrefix?: string | undefined;\n}>, any>;\nexport {};\n//# sourceMappingURL=hitl.d.ts.map"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createMiddleware } from "../middleware.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as _langchain_core_language_models_base0 from "@langchain/core/language_models/base";
|
|
3
3
|
import { BaseLanguageModel } from "@langchain/core/language_models/base";
|
|
4
4
|
import { InferInteropZodInput } from "@langchain/core/utils/types";
|
|
5
5
|
import { z } from "zod/v3";
|
|
@@ -12,7 +12,7 @@ declare const LLMToolSelectorOptionsSchema: z.ZodObject<{
|
|
|
12
12
|
/**
|
|
13
13
|
* The language model to use for tool selection (default: the provided model from the agent options).
|
|
14
14
|
*/
|
|
15
|
-
model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown,
|
|
15
|
+
model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, _langchain_core_language_models_base0.BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, _langchain_core_language_models_base0.BaseLanguageModelCallOptions>>]>>;
|
|
16
16
|
/**
|
|
17
17
|
* System prompt for the tool selection model.
|
|
18
18
|
*/
|
|
@@ -28,12 +28,12 @@ declare const LLMToolSelectorOptionsSchema: z.ZodObject<{
|
|
|
28
28
|
*/
|
|
29
29
|
alwaysInclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
30
30
|
}, "strip", z.ZodTypeAny, {
|
|
31
|
-
model?: string | BaseLanguageModel<unknown,
|
|
31
|
+
model?: string | BaseLanguageModel<unknown, _langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
|
|
32
32
|
systemPrompt?: string | undefined;
|
|
33
33
|
maxTools?: number | undefined;
|
|
34
34
|
alwaysInclude?: string[] | undefined;
|
|
35
35
|
}, {
|
|
36
|
-
model?: string | BaseLanguageModel<unknown,
|
|
36
|
+
model?: string | BaseLanguageModel<unknown, _langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
|
|
37
37
|
systemPrompt?: string | undefined;
|
|
38
38
|
maxTools?: number | undefined;
|
|
39
39
|
alwaysInclude?: string[] | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llmToolSelector.d.cts","names":["z","BaseLanguageModel","InferInteropZodInput","createMiddleware","LLMToolSelectorOptionsSchema","ZodString","
|
|
1
|
+
{"version":3,"file":"llmToolSelector.d.cts","names":["z","BaseLanguageModel","InferInteropZodInput","createMiddleware","LLMToolSelectorOptionsSchema","ZodString","_langchain_core_language_models_base0","BaseLanguageModelCallOptions","ZodTypeDef","ZodType","ZodUnion","ZodOptional","ZodNumber","ZodArray","ZodTypeAny","ZodObject","LLMToolSelectorConfig","llmToolSelectorMiddleware","ReturnType"],"sources":["../../../src/agents/middleware/llmToolSelector.d.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { BaseLanguageModel } from \"@langchain/core/language_models/base\";\nimport type { InferInteropZodInput } from \"@langchain/core/utils/types\";\nimport { createMiddleware } from \"../middleware.js\";\n/**\n * Options for configuring the LLM Tool Selector middleware.\n */\nexport declare const LLMToolSelectorOptionsSchema: z.ZodObject<{\n /**\n * The language model to use for tool selection (default: the provided model from the agent options).\n */\n model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, import(\"@langchain/core/language_models/base\").BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, import(\"@langchain/core/language_models/base\").BaseLanguageModelCallOptions>>]>>;\n /**\n * System prompt for the tool selection model.\n */\n systemPrompt: z.ZodOptional<z.ZodString>;\n /**\n * Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n */\n maxTools: z.ZodOptional<z.ZodNumber>;\n /**\n * Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n */\n alwaysInclude: z.ZodOptional<z.ZodArray<z.ZodString, \"many\">>;\n}, \"strip\", z.ZodTypeAny, {\n model?: string | BaseLanguageModel<unknown, import(\"@langchain/core/language_models/base\").BaseLanguageModelCallOptions> | undefined;\n systemPrompt?: string | undefined;\n maxTools?: number | undefined;\n alwaysInclude?: string[] | undefined;\n}, {\n model?: string | BaseLanguageModel<unknown, import(\"@langchain/core/language_models/base\").BaseLanguageModelCallOptions> | undefined;\n systemPrompt?: string | undefined;\n maxTools?: number | undefined;\n alwaysInclude?: string[] | undefined;\n}>;\nexport type LLMToolSelectorConfig = InferInteropZodInput<typeof LLMToolSelectorOptionsSchema>;\n/**\n * Middleware for selecting tools using an LLM-based strategy.\n *\n * When an agent has many tools available, this middleware filters them down\n * to only the most relevant ones for the user's query. This reduces token usage\n * and helps the main model focus on the right tools.\n *\n * @param options - Configuration options for the middleware\n * @param options.model - The language model to use for tool selection (default: the provided model from the agent options).\n * @param options.systemPrompt - Instructions for the selection model.\n * @param options.maxTools - Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n * @param options.alwaysInclude - Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n *\n * @example\n * Limit to 3 tools:\n * ```ts\n * import { llmToolSelectorMiddleware } from \"langchain/agents/middleware\";\n *\n * const middleware = llmToolSelectorMiddleware({ maxTools: 3 });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [tool1, tool2, tool3, tool4, tool5],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example\n * Use a smaller model for selection:\n * ```ts\n * const middleware = llmToolSelectorMiddleware({\n * model: \"openai:gpt-4o-mini\",\n * maxTools: 2\n * });\n * ```\n */\nexport declare function llmToolSelectorMiddleware(options: LLMToolSelectorConfig): ReturnType<typeof createMiddleware>;\n//# sourceMappingURL=llmToolSelector.d.ts.map"],"mappings":";;;;;;;;;;AAOqBI,cAAAA,4BA6BnB,EA7BiDJ,CAAAA,CAAEe,SA6BnD,CAAA;EAzBqCV;;;EAAgIG,KAAAA,EAA5JR,CAAAA,CAAEW,WAA0JH,CAA9IR,CAAAA,CAAEU,QAA4IF,CAAAA,CAAlIR,CAAAA,CAAEK,SAAgIG,EAArHR,CAAAA,CAAES,OAAmHD,CAA3GP,iBAA2GO,CAAAA,OAAAA,EAAvHF,qCAAAA,CAAsFC,4BAAAA,CAAiCC,EAAFR,CAAAA,CAAEQ,UAAAA,EAAYP,iBAAZO,CAAAA,OAAAA,EAAUF,qCAAAA,CAA4EC,4BAAAA,CAAtFC,CAAAA,CAAAA,CAAAA,CAAAA;EAAUF;;;EAAtJI,YAAAA,EAITV,CAAAA,CAAEW,WAJOD,CAIKV,CAAAA,CAAEK,SAJPK,CAAAA;EAAdC;;;;EASGA,QAAAA,EAAFX,CAAAA,CAAEW,WAAAA,CAAYX,CAAAA,CAAEY,SAAdD,CAAAA;EAK8BN;;;;EACtBC,aAAAA,EADLN,CAAAA,CAAEW,WACGL,CADSN,CAAAA,CAAEa,QAE4DN,CAFnDP,CAAAA,CAAEK,SAEiDE,EAAAA,MAAAA,CAAAA,CAAAA;CAA1EN,EAAAA,OAAAA,EADTD,CAAAA,CAAEc,UACOb,EAAAA;EAAiBK,KAAAA,CAAAA,EAAAA,MAAAA,GAAjBL,iBAAiBK,CAKyDC,OAAAA,EANvED,qCAAAA,CACuEC,4BAAAA,CAKAA,GAAAA,SAAAA;EAA1EN,YAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAzBgCc,QAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAS,aAAA,CAAA,EAAA,MAAA,EAAA,GAAA,SAAA;AA8B9D,CAAA,EAAA;EAuCwBE,KAAAA,CAAAA,EAAAA,MAAAA,GA5CHhB,iBA4C4B,CAAA,OAAA,EAjDXK,qCAAAA,CAKyDC,4BAAAA,CA4C9C,GAAA,SAAA;EAAUS,YAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAA0Cb,QAAAA,CAAAA,EAAAA,MAAAA,GAAAA,SAAAA;EAAlBe,aAAAA,CAAAA,EAAAA,MAAAA,EAAAA,GAAAA,SAAAA;AAAU,CAAA,CAAA;KAvCjFF,qBAAAA,GAAwBd,4BAA4BE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCxCa,yBAAAA,UAAmCD,wBAAwBE,kBAAkBf"}
|
|
@@ -39,6 +39,7 @@ Respond ONLY with the extracted context. Do not include any additional informati
|
|
|
39
39
|
Messages to summarize:
|
|
40
40
|
{messages}
|
|
41
41
|
</messages>`;
|
|
42
|
+
const DEFAULT_SUMMARY_PREFIX = "Here is a summary of the conversation to date:";
|
|
42
43
|
const DEFAULT_MESSAGES_TO_KEEP = 20;
|
|
43
44
|
const DEFAULT_TRIM_TOKEN_LIMIT = 4e3;
|
|
44
45
|
const DEFAULT_FALLBACK_MESSAGE_COUNT = 15;
|
|
@@ -188,6 +189,7 @@ function summarizationMiddleware(options) {
|
|
|
188
189
|
const model = typeof userOptions.model === "string" ? await require_chat_models_universal.initChatModel(userOptions.model) : userOptions.model;
|
|
189
190
|
if (requiresProfile && !getProfileLimits(model)) throw new Error("Model profile information is required to use fractional token limits. Use absolute token counts instead.");
|
|
190
191
|
const summaryPrompt = runtime.context?.summaryPrompt === DEFAULT_SUMMARY_PROMPT ? userOptions.summaryPrompt ?? DEFAULT_SUMMARY_PROMPT : runtime.context?.summaryPrompt ?? userOptions.summaryPrompt ?? DEFAULT_SUMMARY_PROMPT;
|
|
192
|
+
const summaryPrefix = runtime.context.summaryPrefix ?? userOptions.summaryPrefix ?? DEFAULT_SUMMARY_PREFIX;
|
|
191
193
|
const trimTokensToSummarize = runtime.context?.trimTokensToSummarize !== void 0 ? runtime.context.trimTokensToSummarize : userOptions.trimTokensToSummarize ?? DEFAULT_TRIM_TOKEN_LIMIT;
|
|
192
194
|
/**
|
|
193
195
|
* Ensure all messages have IDs
|
|
@@ -203,7 +205,7 @@ function summarizationMiddleware(options) {
|
|
|
203
205
|
const { messagesToSummarize, preservedMessages } = partitionMessages(systemPrompt, conversationMessages, cutoffIndex);
|
|
204
206
|
const summary = await createSummary(messagesToSummarize, model, summaryPrompt, tokenCounter, trimTokensToSummarize);
|
|
205
207
|
const summaryMessage = new __langchain_core_messages.HumanMessage({
|
|
206
|
-
content:
|
|
208
|
+
content: `${summaryPrefix}\n\n${summary}`,
|
|
207
209
|
id: (0, uuid.v4)()
|
|
208
210
|
});
|
|
209
211
|
return { messages: [
|
|
@@ -411,7 +413,13 @@ async function createSummary(messagesToSummarize, model, summaryPrompt, tokenCou
|
|
|
411
413
|
if (!trimmedMessages.length) return "Previous conversation was too long to summarize.";
|
|
412
414
|
try {
|
|
413
415
|
const formattedPrompt = summaryPrompt.replace("{messages}", JSON.stringify(trimmedMessages, null, 2));
|
|
414
|
-
|
|
416
|
+
/**
|
|
417
|
+
* Invoke the model with an empty callbacks array to prevent the internal
|
|
418
|
+
* summarization call from being streamed to the UI. This ensures the
|
|
419
|
+
* summarization is an internal housekeeping step that doesn't leak
|
|
420
|
+
* assistant messages or streaming events.
|
|
421
|
+
*/
|
|
422
|
+
const response = await model.invoke(formattedPrompt, { callbacks: [] });
|
|
415
423
|
const content = response.content;
|
|
416
424
|
/**
|
|
417
425
|
* Handle both string content and MessageContent array
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarization.cjs","names":["z","input: BaseLanguageModel","options: SummarizationMiddlewareConfig","z4","createMiddleware","trigger: ContextSize | ContextSize[] | undefined","keep: ContextSize","triggerConditions: ContextSize[]","initChatModel","countTokensApproximately","HumanMessage","RemoveMessage","REMOVE_ALL_MESSAGES","messages: BaseMessage[]","SystemMessage","systemPrompt: SystemMessage | undefined","conversationMessages: BaseMessage[]","cutoffIndex: number","totalTokens: number","model: BaseLanguageModel","tokenCounter: TokenCounter","targetTokenCount: number","messagesToKeep: number","AIMessage","hasToolCalls","aiMessage: AIMessage","aiMessageIndex: number","toolCallIds: Set<string>","ToolMessage","messagesToSummarize: BaseMessage[]","summaryPrompt: string","trimTokensToSummarize: number | undefined"],"sources":["../../../src/agents/middleware/summarization.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { z as z4 } from \"zod/v4\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n BaseMessage,\n AIMessage,\n SystemMessage,\n ToolMessage,\n RemoveMessage,\n trimMessages,\n HumanMessage,\n} from \"@langchain/core/messages\";\nimport {\n BaseLanguageModel,\n getModelContextSize,\n} from \"@langchain/core/language_models/base\";\nimport {\n interopSafeParse,\n InferInteropZodInput,\n InferInteropZodOutput,\n} from \"@langchain/core/utils/types\";\nimport { REMOVE_ALL_MESSAGES } from \"@langchain/langgraph\";\nimport { createMiddleware } from \"../middleware.js\";\nimport { countTokensApproximately } from \"./utils.js\";\nimport { hasToolCalls } from \"../utils.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\n\nexport const DEFAULT_SUMMARY_PROMPT = `<role>\nContext Extraction Assistant\n</role>\n\n<primary_objective>\nYour sole objective in this task is to extract the highest quality/most relevant context from the conversation history below.\n</primary_objective>\n\n<objective_information>\nYou're nearing the total number of input tokens you can accept, so you must extract the highest quality/most relevant pieces of information from your conversation history.\nThis context will then overwrite the conversation history presented below. Because of this, ensure the context you extract is only the most important information to your overall goal.\n</objective_information>\n\n<instructions>\nThe conversation history below will be replaced with the context you extract in this step. Because of this, you must do your very best to extract and record all of the most important context from the conversation history.\nYou want to ensure that you don't repeat any actions you've already completed, so the context you extract from the conversation history should be focused on the most important information to your overall goal.\n</instructions>\n\nThe user will message you with the full message history you'll be extracting context from, to then replace. Carefully read over it all, and think deeply about what information is most important to your overall goal that should be saved:\n\nWith all of this in mind, please carefully read over the entire conversation history, and extract the most important and relevant context to replace it so that you can free up space in the conversation history.\nRespond ONLY with the extracted context. Do not include any additional information, or text before or after the extracted context.\n\n<messages>\nMessages to summarize:\n{messages}\n</messages>`;\n\nconst DEFAULT_MESSAGES_TO_KEEP = 20;\nconst DEFAULT_TRIM_TOKEN_LIMIT = 4000;\nconst DEFAULT_FALLBACK_MESSAGE_COUNT = 15;\nconst SEARCH_RANGE_FOR_TOOL_PAIRS = 5;\n\nconst tokenCounterSchema = z\n .function()\n .args(z.array(z.custom<BaseMessage>()))\n .returns(z.union([z.number(), z.promise(z.number())]));\nexport type TokenCounter = (\n messages: BaseMessage[]\n) => number | Promise<number>;\n\nexport const contextSizeSchema = z\n .object({\n /**\n * Fraction of the model's context size to use as the trigger\n */\n fraction: z\n .number()\n .gt(0, \"Fraction must be greater than 0\")\n .max(1, \"Fraction must be less than or equal to 1\")\n .optional(),\n /**\n * Number of tokens to use as the trigger\n */\n tokens: z.number().positive(\"Tokens must be greater than 0\").optional(),\n /**\n * Number of messages to use as the trigger\n */\n messages: z\n .number()\n .int(\"Messages must be an integer\")\n .positive(\"Messages must be greater than 0\")\n .optional(),\n })\n .refine(\n (data) => {\n const count = [data.fraction, data.tokens, data.messages].filter(\n (v) => v !== undefined\n ).length;\n return count >= 1;\n },\n {\n message: \"At least one of fraction, tokens, or messages must be provided\",\n }\n );\nexport type ContextSize = z.infer<typeof contextSizeSchema>;\n\nexport const keepSchema = z\n .object({\n /**\n * Fraction of the model's context size to keep\n */\n fraction: z\n .number()\n .min(0, \"Messages must be non-negative\")\n .max(1, \"Fraction must be less than or equal to 1\")\n .optional(),\n /**\n * Number of tokens to keep\n */\n tokens: z\n .number()\n .min(0, \"Tokens must be greater than or equal to 0\")\n .optional(),\n messages: z\n .number()\n .int(\"Messages must be an integer\")\n .min(0, \"Messages must be non-negative\")\n .optional(),\n })\n .refine(\n (data) => {\n const count = [data.fraction, data.tokens, data.messages].filter(\n (v) => v !== undefined\n ).length;\n return count === 1;\n },\n {\n message: \"Exactly one of fraction, tokens, or messages must be provided\",\n }\n );\nexport type KeepSize = z.infer<typeof keepSchema>;\n\nconst contextSchema = z.object({\n /**\n * Model to use for summarization\n */\n model: z.custom<string | BaseLanguageModel>(),\n /**\n * Trigger conditions for summarization.\n * Can be a single condition object (all properties must be met) or an array of conditions (any condition must be met).\n *\n * @example\n * ```ts\n * // Single condition: trigger if tokens >= 5000 AND messages >= 3\n * trigger: { tokens: 5000, messages: 3 }\n *\n * // Multiple conditions: trigger if (tokens >= 5000 AND messages >= 3) OR (tokens >= 3000 AND messages >= 6)\n * trigger: [\n * { tokens: 5000, messages: 3 },\n * { tokens: 3000, messages: 6 }\n * ]\n * ```\n */\n trigger: z.union([contextSizeSchema, z.array(contextSizeSchema)]).optional(),\n /**\n * Keep conditions for summarization\n */\n keep: keepSchema.optional(),\n /**\n * Token counter function to use for summarization\n */\n tokenCounter: tokenCounterSchema.optional(),\n /**\n * Summary prompt to use for summarization\n * @default {@link DEFAULT_SUMMARY_PROMPT}\n */\n summaryPrompt: z.string().default(DEFAULT_SUMMARY_PROMPT),\n /**\n * Number of tokens to trim to before summarizing\n */\n trimTokensToSummarize: z.number().optional(),\n /**\n * Prefix to add to the summary\n */\n summaryPrefix: z.string().optional(),\n /**\n * @deprecated Use `trigger: { tokens: value }` instead.\n */\n maxTokensBeforeSummary: z.number().optional(),\n /**\n * @deprecated Use `keep: { messages: value }` instead.\n */\n messagesToKeep: z.number().optional(),\n});\n\nexport type SummarizationMiddlewareConfig = InferInteropZodInput<\n typeof contextSchema\n>;\n\n/**\n * Get max input tokens from model profile or fallback to model name lookup\n */\nexport function getProfileLimits(input: BaseLanguageModel): number | undefined {\n // Access maxInputTokens on the model profile directly if available\n if (\n \"profile\" in input &&\n typeof input.profile === \"object\" &&\n input.profile &&\n \"maxInputTokens\" in input.profile &&\n (typeof input.profile.maxInputTokens === \"number\" ||\n input.profile.maxInputTokens == null)\n ) {\n return input.profile.maxInputTokens ?? undefined;\n }\n\n // Fallback to using model name if available\n if (\"model\" in input && typeof input.model === \"string\") {\n return getModelContextSize(input.model);\n }\n if (\"modelName\" in input && typeof input.modelName === \"string\") {\n return getModelContextSize(input.modelName);\n }\n\n return undefined;\n}\n\n/**\n * Summarization middleware that automatically summarizes conversation history when token limits are approached.\n *\n * This middleware monitors message token counts and automatically summarizes older\n * messages when a threshold is reached, preserving recent messages and maintaining\n * context continuity by ensuring AI/Tool message pairs remain together.\n *\n * @param options Configuration options for the summarization middleware\n * @returns A middleware instance\n *\n * @example\n * ```ts\n * import { summarizationMiddleware } from \"langchain\";\n * import { createAgent } from \"langchain\";\n *\n * // Single condition: trigger if tokens >= 4000 AND messages >= 10\n * const agent1 = createAgent({\n * llm: model,\n * tools: [getWeather],\n * middleware: [\n * summarizationMiddleware({\n * model: new ChatOpenAI({ model: \"gpt-4o\" }),\n * trigger: { tokens: 4000, messages: 10 },\n * keep: { messages: 20 },\n * })\n * ],\n * });\n *\n * // Multiple conditions: trigger if (tokens >= 5000 AND messages >= 3) OR (tokens >= 3000 AND messages >= 6)\n * const agent2 = createAgent({\n * llm: model,\n * tools: [getWeather],\n * middleware: [\n * summarizationMiddleware({\n * model: new ChatOpenAI({ model: \"gpt-4o\" }),\n * trigger: [\n * { tokens: 5000, messages: 3 },\n * { tokens: 3000, messages: 6 },\n * ],\n * keep: { messages: 20 },\n * })\n * ],\n * });\n *\n * ```\n */\nexport function summarizationMiddleware(\n options: SummarizationMiddlewareConfig\n) {\n /**\n * Parse user options to get their explicit values\n */\n const { data: userOptions, error } = interopSafeParse(contextSchema, options);\n if (error) {\n throw new Error(\n `Invalid summarization middleware options: ${z4.prettifyError(error)}`\n );\n }\n\n return createMiddleware({\n name: \"SummarizationMiddleware\",\n contextSchema: contextSchema.extend({\n /**\n * `model` should be required when initializing the middleware,\n * but can be omitted within context when invoking the middleware.\n */\n model: z.custom<BaseLanguageModel>().optional(),\n }),\n beforeModel: async (state, runtime) => {\n let trigger: ContextSize | ContextSize[] | undefined =\n userOptions.trigger;\n let keep: ContextSize = userOptions.keep as InferInteropZodOutput<\n typeof keepSchema\n >;\n\n /**\n * Handle deprecated parameters\n */\n if (userOptions.maxTokensBeforeSummary !== undefined) {\n console.warn(\n \"maxTokensBeforeSummary is deprecated. Use `trigger: { tokens: value }` instead.\"\n );\n if (trigger === undefined) {\n trigger = { tokens: userOptions.maxTokensBeforeSummary };\n }\n }\n\n /**\n * Handle deprecated parameters\n */\n if (userOptions.messagesToKeep !== undefined) {\n console.warn(\n \"messagesToKeep is deprecated. Use `keep: { messages: value }` instead.\"\n );\n if (\n !keep ||\n (keep &&\n \"messages\" in keep &&\n keep.messages === DEFAULT_MESSAGES_TO_KEEP)\n ) {\n keep = { messages: userOptions.messagesToKeep };\n }\n }\n\n /**\n * Merge context with user options\n */\n const resolvedTrigger =\n runtime.context?.trigger !== undefined\n ? runtime.context.trigger\n : trigger;\n const resolvedKeep =\n runtime.context?.keep !== undefined\n ? runtime.context.keep\n : keep ?? { messages: DEFAULT_MESSAGES_TO_KEEP };\n\n const validatedKeep = keepSchema.parse(resolvedKeep);\n\n /**\n * Validate trigger conditions\n */\n let triggerConditions: ContextSize[] = [];\n if (resolvedTrigger === undefined) {\n triggerConditions = [];\n } else if (Array.isArray(resolvedTrigger)) {\n /**\n * It's an array of ContextSize objects\n */\n triggerConditions = (resolvedTrigger as ContextSize[]).map((t) =>\n contextSizeSchema.parse(t)\n );\n } else {\n /**\n * Single ContextSize object - all properties must be satisfied (AND logic)\n */\n triggerConditions = [contextSizeSchema.parse(resolvedTrigger)];\n }\n\n /**\n * Check if profile is required\n */\n const requiresProfile =\n triggerConditions.some((c) => \"fraction\" in c) ||\n \"fraction\" in validatedKeep;\n\n const model =\n typeof userOptions.model === \"string\"\n ? await initChatModel(userOptions.model)\n : userOptions.model;\n\n if (requiresProfile && !getProfileLimits(model)) {\n throw new Error(\n \"Model profile information is required to use fractional token limits. \" +\n \"Use absolute token counts instead.\"\n );\n }\n\n const summaryPrompt =\n runtime.context?.summaryPrompt === DEFAULT_SUMMARY_PROMPT\n ? userOptions.summaryPrompt ?? DEFAULT_SUMMARY_PROMPT\n : runtime.context?.summaryPrompt ??\n userOptions.summaryPrompt ??\n DEFAULT_SUMMARY_PROMPT;\n const trimTokensToSummarize =\n runtime.context?.trimTokensToSummarize !== undefined\n ? runtime.context.trimTokensToSummarize\n : userOptions.trimTokensToSummarize ?? DEFAULT_TRIM_TOKEN_LIMIT;\n\n /**\n * Ensure all messages have IDs\n */\n ensureMessageIds(state.messages);\n\n const tokenCounter =\n runtime.context?.tokenCounter !== undefined\n ? runtime.context.tokenCounter\n : userOptions.tokenCounter ?? countTokensApproximately;\n const totalTokens = await tokenCounter(state.messages);\n const doSummarize = await shouldSummarize(\n state.messages,\n totalTokens,\n triggerConditions,\n model\n );\n\n if (!doSummarize) {\n return;\n }\n\n const { systemPrompt, conversationMessages } = splitSystemMessage(\n state.messages\n );\n const cutoffIndex = await determineCutoffIndex(\n conversationMessages,\n validatedKeep,\n tokenCounter,\n model\n );\n\n if (cutoffIndex <= 0) {\n return;\n }\n\n const { messagesToSummarize, preservedMessages } = partitionMessages(\n systemPrompt,\n conversationMessages,\n cutoffIndex\n );\n\n const summary = await createSummary(\n messagesToSummarize,\n model,\n summaryPrompt,\n tokenCounter,\n trimTokensToSummarize\n );\n\n const summaryMessage = new HumanMessage({\n content: `Here is a summary of the conversation to date:\\n\\n${summary}`,\n id: uuid(),\n });\n\n return {\n messages: [\n new RemoveMessage({ id: REMOVE_ALL_MESSAGES }),\n summaryMessage,\n ...preservedMessages,\n ],\n };\n },\n });\n}\n\n/**\n * Ensure all messages have unique IDs\n */\nfunction ensureMessageIds(messages: BaseMessage[]): void {\n for (const msg of messages) {\n if (!msg.id) {\n msg.id = uuid();\n }\n }\n}\n\n/**\n * Separate system message from conversation messages\n */\nfunction splitSystemMessage(messages: BaseMessage[]): {\n systemPrompt?: SystemMessage;\n conversationMessages: BaseMessage[];\n} {\n if (messages.length > 0 && SystemMessage.isInstance(messages[0])) {\n return {\n systemPrompt: messages[0] as SystemMessage,\n conversationMessages: messages.slice(1),\n };\n }\n return {\n conversationMessages: messages,\n };\n}\n\n/**\n * Partition messages into those to summarize and those to preserve\n */\nfunction partitionMessages(\n systemPrompt: SystemMessage | undefined,\n conversationMessages: BaseMessage[],\n cutoffIndex: number\n): { messagesToSummarize: BaseMessage[]; preservedMessages: BaseMessage[] } {\n const messagesToSummarize = conversationMessages.slice(0, cutoffIndex);\n const preservedMessages = conversationMessages.slice(cutoffIndex);\n\n // Include system message in messages to summarize to capture previous summaries\n if (systemPrompt) {\n messagesToSummarize.unshift(systemPrompt);\n }\n\n return { messagesToSummarize, preservedMessages };\n}\n\n/**\n * Determine whether summarization should run for the current token usage\n *\n * @param messages - Current messages in the conversation\n * @param totalTokens - Total token count for all messages\n * @param triggerConditions - Array of trigger conditions. Returns true if ANY condition is satisfied (OR logic).\n * Within each condition, ALL specified properties must be satisfied (AND logic).\n * @param model - The language model being used\n * @returns true if summarization should be triggered\n */\nasync function shouldSummarize(\n messages: BaseMessage[],\n totalTokens: number,\n triggerConditions: ContextSize[],\n model: BaseLanguageModel\n): Promise<boolean> {\n if (triggerConditions.length === 0) {\n return false;\n }\n\n /**\n * Check each condition (OR logic between conditions)\n */\n for (const trigger of triggerConditions) {\n /**\n * Within a single condition, all specified properties must be satisfied (AND logic)\n */\n let conditionMet = true;\n let hasAnyProperty = false;\n\n if (trigger.messages !== undefined) {\n hasAnyProperty = true;\n if (messages.length < trigger.messages) {\n conditionMet = false;\n }\n }\n\n if (trigger.tokens !== undefined) {\n hasAnyProperty = true;\n if (totalTokens < trigger.tokens) {\n conditionMet = false;\n }\n }\n\n if (trigger.fraction !== undefined) {\n hasAnyProperty = true;\n const maxInputTokens = getProfileLimits(model);\n if (typeof maxInputTokens === \"number\") {\n const threshold = Math.floor(maxInputTokens * trigger.fraction);\n if (totalTokens < threshold) {\n conditionMet = false;\n }\n } else {\n /**\n * If fraction is specified but we can't get model limits, skip this condition\n */\n conditionMet = false;\n }\n }\n\n /**\n * If condition has at least one property and all properties are satisfied, trigger summarization\n */\n if (hasAnyProperty && conditionMet) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Determine cutoff index respecting retention configuration\n */\nasync function determineCutoffIndex(\n messages: BaseMessage[],\n keep: ContextSize,\n tokenCounter: TokenCounter,\n model: BaseLanguageModel\n): Promise<number> {\n if (\"tokens\" in keep || \"fraction\" in keep) {\n const tokenBasedCutoff = await findTokenBasedCutoff(\n messages,\n keep,\n tokenCounter,\n model\n );\n if (typeof tokenBasedCutoff === \"number\") {\n return tokenBasedCutoff;\n }\n /**\n * Fallback to message count if token-based fails\n */\n return findSafeCutoff(messages, DEFAULT_MESSAGES_TO_KEEP);\n }\n /**\n * find cutoff index based on message count\n */\n return findSafeCutoff(messages, keep.messages ?? DEFAULT_MESSAGES_TO_KEEP);\n}\n\n/**\n * Find cutoff index based on target token retention\n */\nasync function findTokenBasedCutoff(\n messages: BaseMessage[],\n keep: ContextSize,\n tokenCounter: TokenCounter,\n model: BaseLanguageModel\n): Promise<number | undefined> {\n if (messages.length === 0) {\n return 0;\n }\n\n let targetTokenCount: number;\n\n if (\"fraction\" in keep && keep.fraction !== undefined) {\n const maxInputTokens = getProfileLimits(model);\n if (typeof maxInputTokens !== \"number\") {\n return;\n }\n targetTokenCount = Math.floor(maxInputTokens * keep.fraction);\n } else if (\"tokens\" in keep && keep.tokens !== undefined) {\n targetTokenCount = Math.floor(keep.tokens);\n } else {\n return;\n }\n\n if (targetTokenCount <= 0) {\n targetTokenCount = 1;\n }\n\n const totalTokens = await tokenCounter(messages);\n if (totalTokens <= targetTokenCount) {\n return 0;\n }\n\n /**\n * Use binary search to identify the earliest message index that keeps the\n * suffix within the token budget.\n */\n let left = 0;\n let right = messages.length;\n let cutoffCandidate = messages.length;\n const maxIterations = Math.floor(Math.log2(messages.length)) + 1;\n\n for (let i = 0; i < maxIterations; i++) {\n if (left >= right) {\n break;\n }\n\n const mid = Math.floor((left + right) / 2);\n const suffixTokens = await tokenCounter(messages.slice(mid));\n if (suffixTokens <= targetTokenCount) {\n cutoffCandidate = mid;\n right = mid;\n } else {\n left = mid + 1;\n }\n }\n\n if (cutoffCandidate === messages.length) {\n cutoffCandidate = left;\n }\n\n if (cutoffCandidate >= messages.length) {\n if (messages.length === 1) {\n return 0;\n }\n cutoffCandidate = messages.length - 1;\n }\n\n /**\n * Find safe cutoff point that preserves tool pairs\n */\n for (let i = cutoffCandidate; i >= 0; i--) {\n if (isSafeCutoffPoint(messages, i)) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Find safe cutoff point that preserves AI/Tool message pairs\n */\nfunction findSafeCutoff(\n messages: BaseMessage[],\n messagesToKeep: number\n): number {\n if (messages.length <= messagesToKeep) {\n return 0;\n }\n\n const targetCutoff = messages.length - messagesToKeep;\n\n for (let i = targetCutoff; i >= 0; i--) {\n if (isSafeCutoffPoint(messages, i)) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Check if cutting at index would separate AI/Tool message pairs\n */\nfunction isSafeCutoffPoint(\n messages: BaseMessage[],\n cutoffIndex: number\n): boolean {\n if (cutoffIndex >= messages.length) {\n return true;\n }\n\n /**\n * Prevent preserved messages from starting with AI message containing tool calls\n */\n if (\n cutoffIndex < messages.length &&\n AIMessage.isInstance(messages[cutoffIndex]) &&\n hasToolCalls(messages[cutoffIndex])\n ) {\n return false;\n }\n\n const searchStart = Math.max(0, cutoffIndex - SEARCH_RANGE_FOR_TOOL_PAIRS);\n const searchEnd = Math.min(\n messages.length,\n cutoffIndex + SEARCH_RANGE_FOR_TOOL_PAIRS\n );\n\n for (let i = searchStart; i < searchEnd; i++) {\n if (!hasToolCalls(messages[i])) {\n continue;\n }\n\n const toolCallIds = extractToolCallIds(messages[i] as AIMessage);\n if (cutoffSeparatesToolPair(messages, i, cutoffIndex, toolCallIds)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Extract tool call IDs from an AI message\n */\nfunction extractToolCallIds(aiMessage: AIMessage): Set<string> {\n const toolCallIds = new Set<string>();\n if (aiMessage.tool_calls) {\n for (const toolCall of aiMessage.tool_calls) {\n const id =\n typeof toolCall === \"object\" && \"id\" in toolCall ? toolCall.id : null;\n if (id) {\n toolCallIds.add(id);\n }\n }\n }\n return toolCallIds;\n}\n\n/**\n * Check if cutoff separates an AI message from its corresponding tool messages\n */\nfunction cutoffSeparatesToolPair(\n messages: BaseMessage[],\n aiMessageIndex: number,\n cutoffIndex: number,\n toolCallIds: Set<string>\n): boolean {\n for (let j = aiMessageIndex + 1; j < messages.length; j++) {\n const message = messages[j];\n if (\n ToolMessage.isInstance(message) &&\n toolCallIds.has(message.tool_call_id)\n ) {\n const aiBeforeCutoff = aiMessageIndex < cutoffIndex;\n const toolBeforeCutoff = j < cutoffIndex;\n if (aiBeforeCutoff !== toolBeforeCutoff) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Generate summary for the given messages\n */\nasync function createSummary(\n messagesToSummarize: BaseMessage[],\n model: BaseLanguageModel,\n summaryPrompt: string,\n tokenCounter: TokenCounter,\n trimTokensToSummarize: number | undefined\n): Promise<string> {\n if (!messagesToSummarize.length) {\n return \"No previous conversation history.\";\n }\n\n const trimmedMessages = await trimMessagesForSummary(\n messagesToSummarize,\n tokenCounter,\n trimTokensToSummarize\n );\n\n if (!trimmedMessages.length) {\n return \"Previous conversation was too long to summarize.\";\n }\n\n try {\n const formattedPrompt = summaryPrompt.replace(\n \"{messages}\",\n JSON.stringify(trimmedMessages, null, 2)\n );\n const response = await model.invoke(formattedPrompt);\n const content = response.content;\n /**\n * Handle both string content and MessageContent array\n */\n if (typeof content === \"string\") {\n return content.trim();\n } else if (Array.isArray(content)) {\n /**\n * Extract text from MessageContent array\n */\n const textContent = content\n .map((item) => {\n if (typeof item === \"string\") return item;\n if (typeof item === \"object\" && item !== null && \"text\" in item) {\n return (item as { text: string }).text;\n }\n return \"\";\n })\n .join(\"\");\n return textContent.trim();\n }\n return \"Error generating summary: Invalid response format\";\n } catch (e) {\n return `Error generating summary: ${e}`;\n }\n}\n\n/**\n * Trim messages to fit within summary generation limits\n */\nasync function trimMessagesForSummary(\n messages: BaseMessage[],\n tokenCounter: TokenCounter,\n trimTokensToSummarize: number | undefined\n): Promise<BaseMessage[]> {\n if (trimTokensToSummarize === undefined) {\n return messages;\n }\n\n try {\n return await trimMessages(messages, {\n maxTokens: trimTokensToSummarize,\n tokenCounter: async (msgs) => tokenCounter(msgs),\n strategy: \"last\",\n allowPartial: true,\n includeSystem: true,\n });\n } catch {\n /**\n * Fallback to last N messages if trimming fails\n */\n return messages.slice(-DEFAULT_FALLBACK_MESSAGE_COUNT);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"summarization.cjs","names":["z","input: BaseLanguageModel","options: SummarizationMiddlewareConfig","z4","createMiddleware","trigger: ContextSize | ContextSize[] | undefined","keep: ContextSize","triggerConditions: ContextSize[]","initChatModel","countTokensApproximately","HumanMessage","RemoveMessage","REMOVE_ALL_MESSAGES","messages: BaseMessage[]","SystemMessage","systemPrompt: SystemMessage | undefined","conversationMessages: BaseMessage[]","cutoffIndex: number","totalTokens: number","model: BaseLanguageModel","tokenCounter: TokenCounter","targetTokenCount: number","messagesToKeep: number","AIMessage","hasToolCalls","aiMessage: AIMessage","aiMessageIndex: number","toolCallIds: Set<string>","ToolMessage","messagesToSummarize: BaseMessage[]","summaryPrompt: string","trimTokensToSummarize: number | undefined"],"sources":["../../../src/agents/middleware/summarization.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { z as z4 } from \"zod/v4\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n BaseMessage,\n AIMessage,\n SystemMessage,\n ToolMessage,\n RemoveMessage,\n trimMessages,\n HumanMessage,\n} from \"@langchain/core/messages\";\nimport {\n BaseLanguageModel,\n getModelContextSize,\n} from \"@langchain/core/language_models/base\";\nimport {\n interopSafeParse,\n InferInteropZodInput,\n InferInteropZodOutput,\n} from \"@langchain/core/utils/types\";\nimport { REMOVE_ALL_MESSAGES } from \"@langchain/langgraph\";\nimport { createMiddleware } from \"../middleware.js\";\nimport { countTokensApproximately } from \"./utils.js\";\nimport { hasToolCalls } from \"../utils.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\n\nexport const DEFAULT_SUMMARY_PROMPT = `<role>\nContext Extraction Assistant\n</role>\n\n<primary_objective>\nYour sole objective in this task is to extract the highest quality/most relevant context from the conversation history below.\n</primary_objective>\n\n<objective_information>\nYou're nearing the total number of input tokens you can accept, so you must extract the highest quality/most relevant pieces of information from your conversation history.\nThis context will then overwrite the conversation history presented below. Because of this, ensure the context you extract is only the most important information to your overall goal.\n</objective_information>\n\n<instructions>\nThe conversation history below will be replaced with the context you extract in this step. Because of this, you must do your very best to extract and record all of the most important context from the conversation history.\nYou want to ensure that you don't repeat any actions you've already completed, so the context you extract from the conversation history should be focused on the most important information to your overall goal.\n</instructions>\n\nThe user will message you with the full message history you'll be extracting context from, to then replace. Carefully read over it all, and think deeply about what information is most important to your overall goal that should be saved:\n\nWith all of this in mind, please carefully read over the entire conversation history, and extract the most important and relevant context to replace it so that you can free up space in the conversation history.\nRespond ONLY with the extracted context. Do not include any additional information, or text before or after the extracted context.\n\n<messages>\nMessages to summarize:\n{messages}\n</messages>`;\n\nconst DEFAULT_SUMMARY_PREFIX = \"Here is a summary of the conversation to date:\";\nconst DEFAULT_MESSAGES_TO_KEEP = 20;\nconst DEFAULT_TRIM_TOKEN_LIMIT = 4000;\nconst DEFAULT_FALLBACK_MESSAGE_COUNT = 15;\nconst SEARCH_RANGE_FOR_TOOL_PAIRS = 5;\n\nconst tokenCounterSchema = z\n .function()\n .args(z.array(z.custom<BaseMessage>()))\n .returns(z.union([z.number(), z.promise(z.number())]));\nexport type TokenCounter = (\n messages: BaseMessage[]\n) => number | Promise<number>;\n\nexport const contextSizeSchema = z\n .object({\n /**\n * Fraction of the model's context size to use as the trigger\n */\n fraction: z\n .number()\n .gt(0, \"Fraction must be greater than 0\")\n .max(1, \"Fraction must be less than or equal to 1\")\n .optional(),\n /**\n * Number of tokens to use as the trigger\n */\n tokens: z.number().positive(\"Tokens must be greater than 0\").optional(),\n /**\n * Number of messages to use as the trigger\n */\n messages: z\n .number()\n .int(\"Messages must be an integer\")\n .positive(\"Messages must be greater than 0\")\n .optional(),\n })\n .refine(\n (data) => {\n const count = [data.fraction, data.tokens, data.messages].filter(\n (v) => v !== undefined\n ).length;\n return count >= 1;\n },\n {\n message: \"At least one of fraction, tokens, or messages must be provided\",\n }\n );\nexport type ContextSize = z.infer<typeof contextSizeSchema>;\n\nexport const keepSchema = z\n .object({\n /**\n * Fraction of the model's context size to keep\n */\n fraction: z\n .number()\n .min(0, \"Messages must be non-negative\")\n .max(1, \"Fraction must be less than or equal to 1\")\n .optional(),\n /**\n * Number of tokens to keep\n */\n tokens: z\n .number()\n .min(0, \"Tokens must be greater than or equal to 0\")\n .optional(),\n messages: z\n .number()\n .int(\"Messages must be an integer\")\n .min(0, \"Messages must be non-negative\")\n .optional(),\n })\n .refine(\n (data) => {\n const count = [data.fraction, data.tokens, data.messages].filter(\n (v) => v !== undefined\n ).length;\n return count === 1;\n },\n {\n message: \"Exactly one of fraction, tokens, or messages must be provided\",\n }\n );\nexport type KeepSize = z.infer<typeof keepSchema>;\n\nconst contextSchema = z.object({\n /**\n * Model to use for summarization\n */\n model: z.custom<string | BaseLanguageModel>(),\n /**\n * Trigger conditions for summarization.\n * Can be a single condition object (all properties must be met) or an array of conditions (any condition must be met).\n *\n * @example\n * ```ts\n * // Single condition: trigger if tokens >= 5000 AND messages >= 3\n * trigger: { tokens: 5000, messages: 3 }\n *\n * // Multiple conditions: trigger if (tokens >= 5000 AND messages >= 3) OR (tokens >= 3000 AND messages >= 6)\n * trigger: [\n * { tokens: 5000, messages: 3 },\n * { tokens: 3000, messages: 6 }\n * ]\n * ```\n */\n trigger: z.union([contextSizeSchema, z.array(contextSizeSchema)]).optional(),\n /**\n * Keep conditions for summarization\n */\n keep: keepSchema.optional(),\n /**\n * Token counter function to use for summarization\n */\n tokenCounter: tokenCounterSchema.optional(),\n /**\n * Summary prompt to use for summarization\n * @default {@link DEFAULT_SUMMARY_PROMPT}\n */\n summaryPrompt: z.string().default(DEFAULT_SUMMARY_PROMPT),\n /**\n * Number of tokens to trim to before summarizing\n */\n trimTokensToSummarize: z.number().optional(),\n /**\n * Prefix to add to the summary\n */\n summaryPrefix: z.string().optional(),\n /**\n * @deprecated Use `trigger: { tokens: value }` instead.\n */\n maxTokensBeforeSummary: z.number().optional(),\n /**\n * @deprecated Use `keep: { messages: value }` instead.\n */\n messagesToKeep: z.number().optional(),\n});\n\nexport type SummarizationMiddlewareConfig = InferInteropZodInput<\n typeof contextSchema\n>;\n\n/**\n * Get max input tokens from model profile or fallback to model name lookup\n */\nexport function getProfileLimits(input: BaseLanguageModel): number | undefined {\n // Access maxInputTokens on the model profile directly if available\n if (\n \"profile\" in input &&\n typeof input.profile === \"object\" &&\n input.profile &&\n \"maxInputTokens\" in input.profile &&\n (typeof input.profile.maxInputTokens === \"number\" ||\n input.profile.maxInputTokens == null)\n ) {\n return input.profile.maxInputTokens ?? undefined;\n }\n\n // Fallback to using model name if available\n if (\"model\" in input && typeof input.model === \"string\") {\n return getModelContextSize(input.model);\n }\n if (\"modelName\" in input && typeof input.modelName === \"string\") {\n return getModelContextSize(input.modelName);\n }\n\n return undefined;\n}\n\n/**\n * Summarization middleware that automatically summarizes conversation history when token limits are approached.\n *\n * This middleware monitors message token counts and automatically summarizes older\n * messages when a threshold is reached, preserving recent messages and maintaining\n * context continuity by ensuring AI/Tool message pairs remain together.\n *\n * @param options Configuration options for the summarization middleware\n * @returns A middleware instance\n *\n * @example\n * ```ts\n * import { summarizationMiddleware } from \"langchain\";\n * import { createAgent } from \"langchain\";\n *\n * // Single condition: trigger if tokens >= 4000 AND messages >= 10\n * const agent1 = createAgent({\n * llm: model,\n * tools: [getWeather],\n * middleware: [\n * summarizationMiddleware({\n * model: new ChatOpenAI({ model: \"gpt-4o\" }),\n * trigger: { tokens: 4000, messages: 10 },\n * keep: { messages: 20 },\n * })\n * ],\n * });\n *\n * // Multiple conditions: trigger if (tokens >= 5000 AND messages >= 3) OR (tokens >= 3000 AND messages >= 6)\n * const agent2 = createAgent({\n * llm: model,\n * tools: [getWeather],\n * middleware: [\n * summarizationMiddleware({\n * model: new ChatOpenAI({ model: \"gpt-4o\" }),\n * trigger: [\n * { tokens: 5000, messages: 3 },\n * { tokens: 3000, messages: 6 },\n * ],\n * keep: { messages: 20 },\n * })\n * ],\n * });\n *\n * ```\n */\nexport function summarizationMiddleware(\n options: SummarizationMiddlewareConfig\n) {\n /**\n * Parse user options to get their explicit values\n */\n const { data: userOptions, error } = interopSafeParse(contextSchema, options);\n if (error) {\n throw new Error(\n `Invalid summarization middleware options: ${z4.prettifyError(error)}`\n );\n }\n\n return createMiddleware({\n name: \"SummarizationMiddleware\",\n contextSchema: contextSchema.extend({\n /**\n * `model` should be required when initializing the middleware,\n * but can be omitted within context when invoking the middleware.\n */\n model: z.custom<BaseLanguageModel>().optional(),\n }),\n beforeModel: async (state, runtime) => {\n let trigger: ContextSize | ContextSize[] | undefined =\n userOptions.trigger;\n let keep: ContextSize = userOptions.keep as InferInteropZodOutput<\n typeof keepSchema\n >;\n\n /**\n * Handle deprecated parameters\n */\n if (userOptions.maxTokensBeforeSummary !== undefined) {\n console.warn(\n \"maxTokensBeforeSummary is deprecated. Use `trigger: { tokens: value }` instead.\"\n );\n if (trigger === undefined) {\n trigger = { tokens: userOptions.maxTokensBeforeSummary };\n }\n }\n\n /**\n * Handle deprecated parameters\n */\n if (userOptions.messagesToKeep !== undefined) {\n console.warn(\n \"messagesToKeep is deprecated. Use `keep: { messages: value }` instead.\"\n );\n if (\n !keep ||\n (keep &&\n \"messages\" in keep &&\n keep.messages === DEFAULT_MESSAGES_TO_KEEP)\n ) {\n keep = { messages: userOptions.messagesToKeep };\n }\n }\n\n /**\n * Merge context with user options\n */\n const resolvedTrigger =\n runtime.context?.trigger !== undefined\n ? runtime.context.trigger\n : trigger;\n const resolvedKeep =\n runtime.context?.keep !== undefined\n ? runtime.context.keep\n : keep ?? { messages: DEFAULT_MESSAGES_TO_KEEP };\n\n const validatedKeep = keepSchema.parse(resolvedKeep);\n\n /**\n * Validate trigger conditions\n */\n let triggerConditions: ContextSize[] = [];\n if (resolvedTrigger === undefined) {\n triggerConditions = [];\n } else if (Array.isArray(resolvedTrigger)) {\n /**\n * It's an array of ContextSize objects\n */\n triggerConditions = (resolvedTrigger as ContextSize[]).map((t) =>\n contextSizeSchema.parse(t)\n );\n } else {\n /**\n * Single ContextSize object - all properties must be satisfied (AND logic)\n */\n triggerConditions = [contextSizeSchema.parse(resolvedTrigger)];\n }\n\n /**\n * Check if profile is required\n */\n const requiresProfile =\n triggerConditions.some((c) => \"fraction\" in c) ||\n \"fraction\" in validatedKeep;\n\n const model =\n typeof userOptions.model === \"string\"\n ? await initChatModel(userOptions.model)\n : userOptions.model;\n\n if (requiresProfile && !getProfileLimits(model)) {\n throw new Error(\n \"Model profile information is required to use fractional token limits. \" +\n \"Use absolute token counts instead.\"\n );\n }\n\n const summaryPrompt =\n runtime.context?.summaryPrompt === DEFAULT_SUMMARY_PROMPT\n ? userOptions.summaryPrompt ?? DEFAULT_SUMMARY_PROMPT\n : runtime.context?.summaryPrompt ??\n userOptions.summaryPrompt ??\n DEFAULT_SUMMARY_PROMPT;\n const summaryPrefix =\n runtime.context.summaryPrefix ??\n userOptions.summaryPrefix ??\n DEFAULT_SUMMARY_PREFIX;\n const trimTokensToSummarize =\n runtime.context?.trimTokensToSummarize !== undefined\n ? runtime.context.trimTokensToSummarize\n : userOptions.trimTokensToSummarize ?? DEFAULT_TRIM_TOKEN_LIMIT;\n\n /**\n * Ensure all messages have IDs\n */\n ensureMessageIds(state.messages);\n\n const tokenCounter =\n runtime.context?.tokenCounter !== undefined\n ? runtime.context.tokenCounter\n : userOptions.tokenCounter ?? countTokensApproximately;\n const totalTokens = await tokenCounter(state.messages);\n const doSummarize = await shouldSummarize(\n state.messages,\n totalTokens,\n triggerConditions,\n model\n );\n\n if (!doSummarize) {\n return;\n }\n\n const { systemPrompt, conversationMessages } = splitSystemMessage(\n state.messages\n );\n const cutoffIndex = await determineCutoffIndex(\n conversationMessages,\n validatedKeep,\n tokenCounter,\n model\n );\n\n if (cutoffIndex <= 0) {\n return;\n }\n\n const { messagesToSummarize, preservedMessages } = partitionMessages(\n systemPrompt,\n conversationMessages,\n cutoffIndex\n );\n\n const summary = await createSummary(\n messagesToSummarize,\n model,\n summaryPrompt,\n tokenCounter,\n trimTokensToSummarize\n );\n\n const summaryMessage = new HumanMessage({\n content: `${summaryPrefix}\\n\\n${summary}`,\n id: uuid(),\n });\n\n return {\n messages: [\n new RemoveMessage({ id: REMOVE_ALL_MESSAGES }),\n summaryMessage,\n ...preservedMessages,\n ],\n };\n },\n });\n}\n\n/**\n * Ensure all messages have unique IDs\n */\nfunction ensureMessageIds(messages: BaseMessage[]): void {\n for (const msg of messages) {\n if (!msg.id) {\n msg.id = uuid();\n }\n }\n}\n\n/**\n * Separate system message from conversation messages\n */\nfunction splitSystemMessage(messages: BaseMessage[]): {\n systemPrompt?: SystemMessage;\n conversationMessages: BaseMessage[];\n} {\n if (messages.length > 0 && SystemMessage.isInstance(messages[0])) {\n return {\n systemPrompt: messages[0] as SystemMessage,\n conversationMessages: messages.slice(1),\n };\n }\n return {\n conversationMessages: messages,\n };\n}\n\n/**\n * Partition messages into those to summarize and those to preserve\n */\nfunction partitionMessages(\n systemPrompt: SystemMessage | undefined,\n conversationMessages: BaseMessage[],\n cutoffIndex: number\n): { messagesToSummarize: BaseMessage[]; preservedMessages: BaseMessage[] } {\n const messagesToSummarize = conversationMessages.slice(0, cutoffIndex);\n const preservedMessages = conversationMessages.slice(cutoffIndex);\n\n // Include system message in messages to summarize to capture previous summaries\n if (systemPrompt) {\n messagesToSummarize.unshift(systemPrompt);\n }\n\n return { messagesToSummarize, preservedMessages };\n}\n\n/**\n * Determine whether summarization should run for the current token usage\n *\n * @param messages - Current messages in the conversation\n * @param totalTokens - Total token count for all messages\n * @param triggerConditions - Array of trigger conditions. Returns true if ANY condition is satisfied (OR logic).\n * Within each condition, ALL specified properties must be satisfied (AND logic).\n * @param model - The language model being used\n * @returns true if summarization should be triggered\n */\nasync function shouldSummarize(\n messages: BaseMessage[],\n totalTokens: number,\n triggerConditions: ContextSize[],\n model: BaseLanguageModel\n): Promise<boolean> {\n if (triggerConditions.length === 0) {\n return false;\n }\n\n /**\n * Check each condition (OR logic between conditions)\n */\n for (const trigger of triggerConditions) {\n /**\n * Within a single condition, all specified properties must be satisfied (AND logic)\n */\n let conditionMet = true;\n let hasAnyProperty = false;\n\n if (trigger.messages !== undefined) {\n hasAnyProperty = true;\n if (messages.length < trigger.messages) {\n conditionMet = false;\n }\n }\n\n if (trigger.tokens !== undefined) {\n hasAnyProperty = true;\n if (totalTokens < trigger.tokens) {\n conditionMet = false;\n }\n }\n\n if (trigger.fraction !== undefined) {\n hasAnyProperty = true;\n const maxInputTokens = getProfileLimits(model);\n if (typeof maxInputTokens === \"number\") {\n const threshold = Math.floor(maxInputTokens * trigger.fraction);\n if (totalTokens < threshold) {\n conditionMet = false;\n }\n } else {\n /**\n * If fraction is specified but we can't get model limits, skip this condition\n */\n conditionMet = false;\n }\n }\n\n /**\n * If condition has at least one property and all properties are satisfied, trigger summarization\n */\n if (hasAnyProperty && conditionMet) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Determine cutoff index respecting retention configuration\n */\nasync function determineCutoffIndex(\n messages: BaseMessage[],\n keep: ContextSize,\n tokenCounter: TokenCounter,\n model: BaseLanguageModel\n): Promise<number> {\n if (\"tokens\" in keep || \"fraction\" in keep) {\n const tokenBasedCutoff = await findTokenBasedCutoff(\n messages,\n keep,\n tokenCounter,\n model\n );\n if (typeof tokenBasedCutoff === \"number\") {\n return tokenBasedCutoff;\n }\n /**\n * Fallback to message count if token-based fails\n */\n return findSafeCutoff(messages, DEFAULT_MESSAGES_TO_KEEP);\n }\n /**\n * find cutoff index based on message count\n */\n return findSafeCutoff(messages, keep.messages ?? DEFAULT_MESSAGES_TO_KEEP);\n}\n\n/**\n * Find cutoff index based on target token retention\n */\nasync function findTokenBasedCutoff(\n messages: BaseMessage[],\n keep: ContextSize,\n tokenCounter: TokenCounter,\n model: BaseLanguageModel\n): Promise<number | undefined> {\n if (messages.length === 0) {\n return 0;\n }\n\n let targetTokenCount: number;\n\n if (\"fraction\" in keep && keep.fraction !== undefined) {\n const maxInputTokens = getProfileLimits(model);\n if (typeof maxInputTokens !== \"number\") {\n return;\n }\n targetTokenCount = Math.floor(maxInputTokens * keep.fraction);\n } else if (\"tokens\" in keep && keep.tokens !== undefined) {\n targetTokenCount = Math.floor(keep.tokens);\n } else {\n return;\n }\n\n if (targetTokenCount <= 0) {\n targetTokenCount = 1;\n }\n\n const totalTokens = await tokenCounter(messages);\n if (totalTokens <= targetTokenCount) {\n return 0;\n }\n\n /**\n * Use binary search to identify the earliest message index that keeps the\n * suffix within the token budget.\n */\n let left = 0;\n let right = messages.length;\n let cutoffCandidate = messages.length;\n const maxIterations = Math.floor(Math.log2(messages.length)) + 1;\n\n for (let i = 0; i < maxIterations; i++) {\n if (left >= right) {\n break;\n }\n\n const mid = Math.floor((left + right) / 2);\n const suffixTokens = await tokenCounter(messages.slice(mid));\n if (suffixTokens <= targetTokenCount) {\n cutoffCandidate = mid;\n right = mid;\n } else {\n left = mid + 1;\n }\n }\n\n if (cutoffCandidate === messages.length) {\n cutoffCandidate = left;\n }\n\n if (cutoffCandidate >= messages.length) {\n if (messages.length === 1) {\n return 0;\n }\n cutoffCandidate = messages.length - 1;\n }\n\n /**\n * Find safe cutoff point that preserves tool pairs\n */\n for (let i = cutoffCandidate; i >= 0; i--) {\n if (isSafeCutoffPoint(messages, i)) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Find safe cutoff point that preserves AI/Tool message pairs\n */\nfunction findSafeCutoff(\n messages: BaseMessage[],\n messagesToKeep: number\n): number {\n if (messages.length <= messagesToKeep) {\n return 0;\n }\n\n const targetCutoff = messages.length - messagesToKeep;\n\n for (let i = targetCutoff; i >= 0; i--) {\n if (isSafeCutoffPoint(messages, i)) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Check if cutting at index would separate AI/Tool message pairs\n */\nfunction isSafeCutoffPoint(\n messages: BaseMessage[],\n cutoffIndex: number\n): boolean {\n if (cutoffIndex >= messages.length) {\n return true;\n }\n\n /**\n * Prevent preserved messages from starting with AI message containing tool calls\n */\n if (\n cutoffIndex < messages.length &&\n AIMessage.isInstance(messages[cutoffIndex]) &&\n hasToolCalls(messages[cutoffIndex])\n ) {\n return false;\n }\n\n const searchStart = Math.max(0, cutoffIndex - SEARCH_RANGE_FOR_TOOL_PAIRS);\n const searchEnd = Math.min(\n messages.length,\n cutoffIndex + SEARCH_RANGE_FOR_TOOL_PAIRS\n );\n\n for (let i = searchStart; i < searchEnd; i++) {\n if (!hasToolCalls(messages[i])) {\n continue;\n }\n\n const toolCallIds = extractToolCallIds(messages[i] as AIMessage);\n if (cutoffSeparatesToolPair(messages, i, cutoffIndex, toolCallIds)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Extract tool call IDs from an AI message\n */\nfunction extractToolCallIds(aiMessage: AIMessage): Set<string> {\n const toolCallIds = new Set<string>();\n if (aiMessage.tool_calls) {\n for (const toolCall of aiMessage.tool_calls) {\n const id =\n typeof toolCall === \"object\" && \"id\" in toolCall ? toolCall.id : null;\n if (id) {\n toolCallIds.add(id);\n }\n }\n }\n return toolCallIds;\n}\n\n/**\n * Check if cutoff separates an AI message from its corresponding tool messages\n */\nfunction cutoffSeparatesToolPair(\n messages: BaseMessage[],\n aiMessageIndex: number,\n cutoffIndex: number,\n toolCallIds: Set<string>\n): boolean {\n for (let j = aiMessageIndex + 1; j < messages.length; j++) {\n const message = messages[j];\n if (\n ToolMessage.isInstance(message) &&\n toolCallIds.has(message.tool_call_id)\n ) {\n const aiBeforeCutoff = aiMessageIndex < cutoffIndex;\n const toolBeforeCutoff = j < cutoffIndex;\n if (aiBeforeCutoff !== toolBeforeCutoff) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Generate summary for the given messages\n */\nasync function createSummary(\n messagesToSummarize: BaseMessage[],\n model: BaseLanguageModel,\n summaryPrompt: string,\n tokenCounter: TokenCounter,\n trimTokensToSummarize: number | undefined\n): Promise<string> {\n if (!messagesToSummarize.length) {\n return \"No previous conversation history.\";\n }\n\n const trimmedMessages = await trimMessagesForSummary(\n messagesToSummarize,\n tokenCounter,\n trimTokensToSummarize\n );\n\n if (!trimmedMessages.length) {\n return \"Previous conversation was too long to summarize.\";\n }\n\n try {\n const formattedPrompt = summaryPrompt.replace(\n \"{messages}\",\n JSON.stringify(trimmedMessages, null, 2)\n );\n /**\n * Invoke the model with an empty callbacks array to prevent the internal\n * summarization call from being streamed to the UI. This ensures the\n * summarization is an internal housekeeping step that doesn't leak\n * assistant messages or streaming events.\n */\n const response = await model.invoke(formattedPrompt, { callbacks: [] });\n const content = response.content;\n /**\n * Handle both string content and MessageContent array\n */\n if (typeof content === \"string\") {\n return content.trim();\n } else if (Array.isArray(content)) {\n /**\n * Extract text from MessageContent array\n */\n const textContent = content\n .map((item) => {\n if (typeof item === \"string\") return item;\n if (typeof item === \"object\" && item !== null && \"text\" in item) {\n return (item as { text: string }).text;\n }\n return \"\";\n })\n .join(\"\");\n return textContent.trim();\n }\n return \"Error generating summary: Invalid response format\";\n } catch (e) {\n return `Error generating summary: ${e}`;\n }\n}\n\n/**\n * Trim messages to fit within summary generation limits\n */\nasync function trimMessagesForSummary(\n messages: BaseMessage[],\n tokenCounter: TokenCounter,\n trimTokensToSummarize: number | undefined\n): Promise<BaseMessage[]> {\n if (trimTokensToSummarize === undefined) {\n return messages;\n }\n\n try {\n return await trimMessages(messages, {\n maxTokens: trimTokensToSummarize,\n tokenCounter: async (msgs) => tokenCounter(msgs),\n strategy: \"last\",\n allowPartial: true,\n includeSystem: true,\n });\n } catch {\n /**\n * Fallback to last N messages if trimming fails\n */\n return messages.slice(-DEFAULT_FALLBACK_MESSAGE_COUNT);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentMiddleware } from "./types.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as _langchain_core_language_models_base3 from "@langchain/core/language_models/base";
|
|
3
3
|
import { BaseLanguageModel } from "@langchain/core/language_models/base";
|
|
4
4
|
import * as _langchain_core_messages0 from "@langchain/core/messages";
|
|
5
5
|
import { BaseMessage } from "@langchain/core/messages";
|
|
@@ -71,7 +71,7 @@ declare const contextSchema: z.ZodObject<{
|
|
|
71
71
|
/**
|
|
72
72
|
* Model to use for summarization
|
|
73
73
|
*/
|
|
74
|
-
model: z.ZodType<string | BaseLanguageModel<any,
|
|
74
|
+
model: z.ZodType<string | BaseLanguageModel<any, _langchain_core_language_models_base3.BaseLanguageModelCallOptions>, z.ZodTypeDef, string | BaseLanguageModel<any, _langchain_core_language_models_base3.BaseLanguageModelCallOptions>>;
|
|
75
75
|
/**
|
|
76
76
|
* Trigger conditions for summarization.
|
|
77
77
|
* Can be a single condition object (all properties must be met) or an array of conditions (any condition must be met).
|
|
@@ -203,7 +203,7 @@ declare const contextSchema: z.ZodObject<{
|
|
|
203
203
|
*/
|
|
204
204
|
messagesToKeep: z.ZodOptional<z.ZodNumber>;
|
|
205
205
|
}, "strip", z.ZodTypeAny, {
|
|
206
|
-
model: string | BaseLanguageModel<any,
|
|
206
|
+
model: string | BaseLanguageModel<any, _langchain_core_language_models_base3.BaseLanguageModelCallOptions>;
|
|
207
207
|
trigger?: {
|
|
208
208
|
fraction?: number | undefined;
|
|
209
209
|
tokens?: number | undefined;
|
|
@@ -225,7 +225,7 @@ declare const contextSchema: z.ZodObject<{
|
|
|
225
225
|
maxTokensBeforeSummary?: number | undefined;
|
|
226
226
|
messagesToKeep?: number | undefined;
|
|
227
227
|
}, {
|
|
228
|
-
model: string | BaseLanguageModel<any,
|
|
228
|
+
model: string | BaseLanguageModel<any, _langchain_core_language_models_base3.BaseLanguageModelCallOptions>;
|
|
229
229
|
trigger?: {
|
|
230
230
|
fraction?: number | undefined;
|
|
231
231
|
tokens?: number | undefined;
|
|
@@ -388,7 +388,7 @@ declare function summarizationMiddleware(options: SummarizationMiddlewareConfig)
|
|
|
388
388
|
maxTokensBeforeSummary: z.ZodOptional<z.ZodNumber>;
|
|
389
389
|
messagesToKeep: z.ZodOptional<z.ZodNumber>;
|
|
390
390
|
} & {
|
|
391
|
-
model: z.ZodOptional<z.ZodType<BaseLanguageModel<any,
|
|
391
|
+
model: z.ZodOptional<z.ZodType<BaseLanguageModel<any, _langchain_core_language_models_base3.BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<any, _langchain_core_language_models_base3.BaseLanguageModelCallOptions>>>;
|
|
392
392
|
}, "strip", z.ZodTypeAny, {
|
|
393
393
|
trigger?: {
|
|
394
394
|
fraction?: number | undefined;
|
|
@@ -410,7 +410,7 @@ declare function summarizationMiddleware(options: SummarizationMiddlewareConfig)
|
|
|
410
410
|
summaryPrefix?: string | undefined;
|
|
411
411
|
maxTokensBeforeSummary?: number | undefined;
|
|
412
412
|
messagesToKeep?: number | undefined;
|
|
413
|
-
model?: BaseLanguageModel<any,
|
|
413
|
+
model?: BaseLanguageModel<any, _langchain_core_language_models_base3.BaseLanguageModelCallOptions> | undefined;
|
|
414
414
|
}, {
|
|
415
415
|
trigger?: {
|
|
416
416
|
fraction?: number | undefined;
|
|
@@ -432,7 +432,7 @@ declare function summarizationMiddleware(options: SummarizationMiddlewareConfig)
|
|
|
432
432
|
summaryPrefix?: string | undefined;
|
|
433
433
|
maxTokensBeforeSummary?: number | undefined;
|
|
434
434
|
messagesToKeep?: number | undefined;
|
|
435
|
-
model?: BaseLanguageModel<any,
|
|
435
|
+
model?: BaseLanguageModel<any, _langchain_core_language_models_base3.BaseLanguageModelCallOptions> | undefined;
|
|
436
436
|
}>, any>;
|
|
437
437
|
//#endregion
|
|
438
438
|
export { ContextSize, KeepSize, SummarizationMiddlewareConfig, TokenCounter, summarizationMiddleware };
|