langchain 1.0.2 → 1.0.4
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 +18 -0
- package/dist/agents/ReactAgent.cjs +21 -41
- package/dist/agents/ReactAgent.cjs.map +1 -1
- package/dist/agents/ReactAgent.js +21 -41
- package/dist/agents/ReactAgent.js.map +1 -1
- package/dist/agents/annotation.cjs +7 -4
- package/dist/agents/annotation.cjs.map +1 -1
- package/dist/agents/annotation.js +8 -5
- package/dist/agents/annotation.js.map +1 -1
- package/dist/agents/middleware/contextEditing.d.cts.map +1 -1
- package/dist/agents/middleware/contextEditing.d.ts.map +1 -1
- package/dist/agents/middleware/dynamicSystemPrompt.d.cts.map +1 -1
- package/dist/agents/middleware/dynamicSystemPrompt.d.ts.map +1 -1
- package/dist/agents/middleware/hitl.cjs +7 -2
- package/dist/agents/middleware/hitl.cjs.map +1 -1
- package/dist/agents/middleware/hitl.d.cts.map +1 -1
- package/dist/agents/middleware/hitl.d.ts.map +1 -1
- package/dist/agents/middleware/hitl.js +7 -2
- package/dist/agents/middleware/hitl.js.map +1 -1
- package/dist/agents/middleware/index.cjs +2 -1
- package/dist/agents/middleware/index.js +2 -1
- package/dist/agents/middleware/llmToolSelector.d.cts +4 -4
- package/dist/agents/middleware/llmToolSelector.d.cts.map +1 -1
- package/dist/agents/middleware/{callLimit.cjs → modelCallLimit.cjs} +22 -7
- package/dist/agents/middleware/modelCallLimit.cjs.map +1 -0
- package/dist/agents/middleware/{callLimit.d.cts → modelCallLimit.d.cts} +12 -3
- package/dist/agents/middleware/modelCallLimit.d.cts.map +1 -0
- package/dist/agents/middleware/{callLimit.d.ts → modelCallLimit.d.ts} +12 -3
- package/dist/agents/middleware/modelCallLimit.d.ts.map +1 -0
- package/dist/agents/middleware/{callLimit.js → modelCallLimit.js} +22 -7
- package/dist/agents/middleware/modelCallLimit.js.map +1 -0
- package/dist/agents/middleware/promptCaching.d.cts.map +1 -1
- package/dist/agents/middleware/promptCaching.d.ts.map +1 -1
- package/dist/agents/middleware/summarization.cjs +274 -52
- package/dist/agents/middleware/summarization.cjs.map +1 -1
- package/dist/agents/middleware/summarization.d.cts +326 -30
- package/dist/agents/middleware/summarization.d.cts.map +1 -1
- package/dist/agents/middleware/summarization.d.ts +325 -29
- package/dist/agents/middleware/summarization.d.ts.map +1 -1
- package/dist/agents/middleware/summarization.js +276 -54
- package/dist/agents/middleware/summarization.js.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.cts.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.ts.map +1 -1
- package/dist/agents/middleware/toolCallLimit.cjs +215 -93
- package/dist/agents/middleware/toolCallLimit.cjs.map +1 -1
- package/dist/agents/middleware/toolCallLimit.d.cts +48 -37
- package/dist/agents/middleware/toolCallLimit.d.cts.map +1 -1
- package/dist/agents/middleware/toolCallLimit.d.ts +48 -37
- package/dist/agents/middleware/toolCallLimit.d.ts.map +1 -1
- package/dist/agents/middleware/toolCallLimit.js +216 -94
- package/dist/agents/middleware/toolCallLimit.js.map +1 -1
- package/dist/agents/middleware/toolRetry.cjs +224 -0
- package/dist/agents/middleware/toolRetry.cjs.map +1 -0
- package/dist/agents/middleware/toolRetry.d.cts +179 -0
- package/dist/agents/middleware/toolRetry.d.cts.map +1 -0
- package/dist/agents/middleware/toolRetry.d.ts +179 -0
- package/dist/agents/middleware/toolRetry.d.ts.map +1 -0
- package/dist/agents/middleware/toolRetry.js +223 -0
- package/dist/agents/middleware/toolRetry.js.map +1 -0
- package/dist/agents/middleware/types.d.cts +21 -19
- package/dist/agents/middleware/types.d.cts.map +1 -1
- package/dist/agents/middleware/types.d.ts +21 -19
- package/dist/agents/middleware/types.d.ts.map +1 -1
- package/dist/agents/middleware/utils.cjs +7 -0
- package/dist/agents/middleware/utils.cjs.map +1 -1
- package/dist/agents/middleware/utils.d.cts.map +1 -1
- package/dist/agents/middleware/utils.d.ts.map +1 -1
- package/dist/agents/middleware/utils.js +7 -1
- package/dist/agents/middleware/utils.js.map +1 -1
- package/dist/agents/middleware.cjs.map +1 -1
- package/dist/agents/middleware.d.cts +4 -4
- package/dist/agents/middleware.d.cts.map +1 -1
- package/dist/agents/middleware.d.ts +4 -4
- package/dist/agents/middleware.d.ts.map +1 -1
- package/dist/agents/middleware.js.map +1 -1
- package/dist/agents/nodes/AgentNode.cjs +21 -51
- package/dist/agents/nodes/AgentNode.cjs.map +1 -1
- package/dist/agents/nodes/AgentNode.js +23 -53
- package/dist/agents/nodes/AgentNode.js.map +1 -1
- package/dist/agents/nodes/ToolNode.cjs +12 -18
- package/dist/agents/nodes/ToolNode.cjs.map +1 -1
- package/dist/agents/nodes/ToolNode.js +12 -18
- package/dist/agents/nodes/ToolNode.js.map +1 -1
- package/dist/agents/nodes/middleware.cjs +9 -7
- package/dist/agents/nodes/middleware.cjs.map +1 -1
- package/dist/agents/nodes/middleware.js +10 -8
- package/dist/agents/nodes/middleware.js.map +1 -1
- package/dist/agents/nodes/types.d.cts +1 -1
- package/dist/agents/nodes/types.d.cts.map +1 -1
- package/dist/agents/nodes/types.d.ts +1 -1
- package/dist/agents/nodes/types.d.ts.map +1 -1
- package/dist/agents/nodes/utils.cjs +5 -1
- package/dist/agents/nodes/utils.cjs.map +1 -1
- package/dist/agents/nodes/utils.js +5 -1
- package/dist/agents/nodes/utils.js.map +1 -1
- package/dist/agents/responses.cjs +0 -1
- package/dist/agents/responses.js +1 -1
- package/dist/agents/runtime.d.cts +11 -27
- package/dist/agents/runtime.d.cts.map +1 -1
- package/dist/agents/runtime.d.ts +11 -27
- package/dist/agents/runtime.d.ts.map +1 -1
- package/dist/agents/state.cjs +45 -0
- package/dist/agents/state.cjs.map +1 -0
- package/dist/agents/state.js +44 -0
- package/dist/agents/state.js.map +1 -0
- package/dist/agents/types.d.cts +1 -1
- package/dist/agents/types.d.cts.map +1 -1
- package/dist/agents/types.d.ts +1 -1
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/utils.cjs +10 -2
- package/dist/agents/utils.cjs.map +1 -1
- package/dist/agents/utils.js +10 -2
- package/dist/agents/utils.js.map +1 -1
- package/dist/chat_models/universal.cjs +2 -2
- package/dist/chat_models/universal.cjs.map +1 -1
- package/dist/chat_models/universal.js +2 -2
- package/dist/chat_models/universal.js.map +1 -1
- package/dist/index.cjs +6 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -5
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/dist/agents/middleware/callLimit.cjs.map +0 -1
- package/dist/agents/middleware/callLimit.d.cts.map +0 -1
- package/dist/agents/middleware/callLimit.d.ts.map +0 -1
- package/dist/agents/middleware/callLimit.js.map +0 -1
- package/dist/agents/tools.d.cts +0 -9
- package/dist/agents/tools.d.cts.map +0 -1
- package/dist/agents/tools.d.ts +0 -9
- package/dist/agents/tools.d.ts.map +0 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { AgentMiddleware } from "./types.js";
|
|
2
|
+
import { ClientTool, ServerTool } from "@langchain/core/tools";
|
|
3
|
+
import { z } from "zod/v3";
|
|
4
|
+
|
|
5
|
+
//#region src/agents/middleware/toolRetry.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configuration options for the Tool Retry Middleware.
|
|
9
|
+
*/
|
|
10
|
+
declare const ToolRetryMiddlewareOptionsSchema: z.ZodObject<{
|
|
11
|
+
/**
|
|
12
|
+
* Maximum number of retry attempts after the initial call.
|
|
13
|
+
* Default is 2 retries (3 total attempts). Must be >= 0.
|
|
14
|
+
*/
|
|
15
|
+
maxRetries: z.ZodDefault<z.ZodNumber>;
|
|
16
|
+
/**
|
|
17
|
+
* Optional list of tools or tool names to apply retry logic to.
|
|
18
|
+
* Can be a list of `BaseTool` instances or tool name strings.
|
|
19
|
+
* If `undefined`, applies to all tools. Default is `undefined`.
|
|
20
|
+
*/
|
|
21
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodType<ClientTool, z.ZodTypeDef, ClientTool>, z.ZodType<ServerTool, z.ZodTypeDef, ServerTool>, z.ZodString]>, "many">>;
|
|
22
|
+
/**
|
|
23
|
+
* Either an array of error constructors to retry on, or a function
|
|
24
|
+
* that takes an error and returns `true` if it should be retried.
|
|
25
|
+
* Default is to retry on all errors.
|
|
26
|
+
*/
|
|
27
|
+
retryOn: z.ZodDefault<z.ZodUnion<[z.ZodFunction<z.ZodTuple<[z.ZodType<Error, z.ZodTypeDef, Error>], z.ZodUnknown>, z.ZodBoolean>, z.ZodArray<z.ZodType<new (...args: any[]) => Error, z.ZodTypeDef, new (...args: any[]) => Error>, "many">]>>;
|
|
28
|
+
/**
|
|
29
|
+
* Behavior when all retries are exhausted. Options:
|
|
30
|
+
* - `"return_message"` (default): Return a ToolMessage with error details,
|
|
31
|
+
* allowing the LLM to handle the failure and potentially recover.
|
|
32
|
+
* - `"raise"`: Re-raise the exception, stopping agent execution.
|
|
33
|
+
* - Custom function: Function that takes the exception and returns a string
|
|
34
|
+
* for the ToolMessage content, allowing custom error formatting.
|
|
35
|
+
*/
|
|
36
|
+
onFailure: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"raise">, z.ZodLiteral<"return_message">, z.ZodFunction<z.ZodTuple<[z.ZodType<Error, z.ZodTypeDef, Error>], z.ZodUnknown>, z.ZodString>]>>;
|
|
37
|
+
/**
|
|
38
|
+
* Multiplier for exponential backoff. Each retry waits
|
|
39
|
+
* `initialDelayMs * (backoffFactor ** retryNumber)` milliseconds.
|
|
40
|
+
* Set to 0.0 for constant delay. Default is 2.0.
|
|
41
|
+
*/
|
|
42
|
+
backoffFactor: z.ZodDefault<z.ZodNumber>;
|
|
43
|
+
/**
|
|
44
|
+
* Initial delay in milliseconds before first retry. Default is 1000 (1 second).
|
|
45
|
+
*/
|
|
46
|
+
initialDelayMs: z.ZodDefault<z.ZodNumber>;
|
|
47
|
+
/**
|
|
48
|
+
* Maximum delay in milliseconds between retries. Caps exponential
|
|
49
|
+
* backoff growth. Default is 60000 (60 seconds).
|
|
50
|
+
*/
|
|
51
|
+
maxDelayMs: z.ZodDefault<z.ZodNumber>;
|
|
52
|
+
/**
|
|
53
|
+
* Whether to add random jitter (±25%) to delay to avoid thundering herd.
|
|
54
|
+
* Default is `true`.
|
|
55
|
+
*/
|
|
56
|
+
jitter: z.ZodDefault<z.ZodBoolean>;
|
|
57
|
+
}, "strip", z.ZodTypeAny, {
|
|
58
|
+
maxRetries: number;
|
|
59
|
+
tools?: (string | ServerTool | ClientTool)[] | undefined;
|
|
60
|
+
retryOn: (new (...args: any[]) => Error)[] | ((args_0: Error, ...args: unknown[]) => boolean);
|
|
61
|
+
onFailure: "raise" | "return_message" | ((args_0: Error, ...args: unknown[]) => string);
|
|
62
|
+
backoffFactor: number;
|
|
63
|
+
initialDelayMs: number;
|
|
64
|
+
maxDelayMs: number;
|
|
65
|
+
jitter: boolean;
|
|
66
|
+
}, {
|
|
67
|
+
maxRetries?: number | undefined;
|
|
68
|
+
tools?: (string | ServerTool | ClientTool)[] | undefined;
|
|
69
|
+
retryOn?: (new (...args: any[]) => Error)[] | ((args_0: Error, ...args: unknown[]) => boolean) | undefined;
|
|
70
|
+
onFailure?: "raise" | "return_message" | ((args_0: Error, ...args: unknown[]) => string) | undefined;
|
|
71
|
+
backoffFactor?: number | undefined;
|
|
72
|
+
initialDelayMs?: number | undefined;
|
|
73
|
+
maxDelayMs?: number | undefined;
|
|
74
|
+
jitter?: boolean | undefined;
|
|
75
|
+
}>;
|
|
76
|
+
type ToolRetryMiddlewareConfig = z.input<typeof ToolRetryMiddlewareOptionsSchema>;
|
|
77
|
+
/**
|
|
78
|
+
* Middleware that automatically retries failed tool calls with configurable backoff.
|
|
79
|
+
*
|
|
80
|
+
* Supports retrying on specific exceptions and exponential backoff.
|
|
81
|
+
*
|
|
82
|
+
* @example Basic usage with default settings (2 retries, exponential backoff)
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { createAgent, toolRetryMiddleware } from "langchain";
|
|
85
|
+
*
|
|
86
|
+
* const agent = createAgent({
|
|
87
|
+
* model: "openai:gpt-4o",
|
|
88
|
+
* tools: [searchTool],
|
|
89
|
+
* middleware: [toolRetryMiddleware()],
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @example Retry specific exceptions only
|
|
94
|
+
* ```ts
|
|
95
|
+
* import { toolRetryMiddleware } from "langchain";
|
|
96
|
+
*
|
|
97
|
+
* const retry = toolRetryMiddleware({
|
|
98
|
+
* maxRetries: 4,
|
|
99
|
+
* retryOn: [TimeoutError, NetworkError],
|
|
100
|
+
* backoffFactor: 1.5,
|
|
101
|
+
* });
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @example Custom exception filtering
|
|
105
|
+
* ```ts
|
|
106
|
+
* function shouldRetry(error: Error): boolean {
|
|
107
|
+
* // Only retry on 5xx errors
|
|
108
|
+
* if (error.name === "HTTPError" && "statusCode" in error) {
|
|
109
|
+
* const statusCode = (error as any).statusCode;
|
|
110
|
+
* return 500 <= statusCode && statusCode < 600;
|
|
111
|
+
* }
|
|
112
|
+
* return false;
|
|
113
|
+
* }
|
|
114
|
+
*
|
|
115
|
+
* const retry = toolRetryMiddleware({
|
|
116
|
+
* maxRetries: 3,
|
|
117
|
+
* retryOn: shouldRetry,
|
|
118
|
+
* });
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* @example Apply to specific tools with custom error handling
|
|
122
|
+
* ```ts
|
|
123
|
+
* const formatError = (error: Error) =>
|
|
124
|
+
* "Database temporarily unavailable. Please try again later.";
|
|
125
|
+
*
|
|
126
|
+
* const retry = toolRetryMiddleware({
|
|
127
|
+
* maxRetries: 4,
|
|
128
|
+
* tools: ["search_database"],
|
|
129
|
+
* onFailure: formatError,
|
|
130
|
+
* });
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @example Apply to specific tools using BaseTool instances
|
|
134
|
+
* ```ts
|
|
135
|
+
* import { tool } from "@langchain/core/tools";
|
|
136
|
+
* import { z } from "zod";
|
|
137
|
+
*
|
|
138
|
+
* const searchDatabase = tool(
|
|
139
|
+
* async ({ query }) => {
|
|
140
|
+
* // Search implementation
|
|
141
|
+
* return results;
|
|
142
|
+
* },
|
|
143
|
+
* {
|
|
144
|
+
* name: "search_database",
|
|
145
|
+
* description: "Search the database",
|
|
146
|
+
* schema: z.object({ query: z.string() }),
|
|
147
|
+
* }
|
|
148
|
+
* );
|
|
149
|
+
*
|
|
150
|
+
* const retry = toolRetryMiddleware({
|
|
151
|
+
* maxRetries: 4,
|
|
152
|
+
* tools: [searchDatabase], // Pass BaseTool instance
|
|
153
|
+
* });
|
|
154
|
+
* ```
|
|
155
|
+
*
|
|
156
|
+
* @example Constant backoff (no exponential growth)
|
|
157
|
+
* ```ts
|
|
158
|
+
* const retry = toolRetryMiddleware({
|
|
159
|
+
* maxRetries: 5,
|
|
160
|
+
* backoffFactor: 0.0, // No exponential growth
|
|
161
|
+
* initialDelayMs: 2000, // Always wait 2 seconds
|
|
162
|
+
* });
|
|
163
|
+
* ```
|
|
164
|
+
*
|
|
165
|
+
* @example Raise exception on failure
|
|
166
|
+
* ```ts
|
|
167
|
+
* const retry = toolRetryMiddleware({
|
|
168
|
+
* maxRetries: 2,
|
|
169
|
+
* onFailure: "raise", // Re-raise exception instead of returning message
|
|
170
|
+
* });
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
173
|
+
* @param config - Configuration options for the retry middleware
|
|
174
|
+
* @returns A middleware instance that handles tool failures with retries
|
|
175
|
+
*/
|
|
176
|
+
declare function toolRetryMiddleware(config?: ToolRetryMiddlewareConfig): AgentMiddleware;
|
|
177
|
+
//#endregion
|
|
178
|
+
export { ToolRetryMiddlewareConfig, toolRetryMiddleware };
|
|
179
|
+
//# sourceMappingURL=toolRetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolRetry.d.ts","names":["z","ClientTool","ServerTool","AgentMiddleware","calculateRetryDelay","ToolRetryMiddlewareOptionsSchema","ZodNumber","ZodDefault","ZodTypeDef","ZodType","ZodString","ZodUnion","ZodArray","ZodOptional","Error","ZodUnknown","ZodTuple","ZodBoolean","ZodFunction","ZodLiteral","ZodTypeAny","ZodObject","ToolRetryMiddlewareConfig","input","toolRetryMiddleware"],"sources":["../../../src/agents/middleware/toolRetry.d.ts"],"sourcesContent":["/**\n * Tool retry middleware for agents.\n */\nimport { z } from \"zod/v3\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport type { AgentMiddleware } from \"./types.js\";\n/**\n * Calculate delay for a retry attempt with exponential backoff and jitter.\n *\n * @param retryNumber - The retry attempt number (0-indexed)\n * @param config - Configuration for backoff calculation\n * @returns Delay in milliseconds before next retry\n *\n * @internal Exported for testing purposes\n */\nexport declare function calculateRetryDelay(config: {\n backoffFactor: number;\n initialDelayMs: number;\n maxDelayMs: number;\n jitter: boolean;\n}, retryNumber: number): number;\n/**\n * Configuration options for the Tool Retry Middleware.\n */\nexport declare const ToolRetryMiddlewareOptionsSchema: z.ZodObject<{\n /**\n * Maximum number of retry attempts after the initial call.\n * Default is 2 retries (3 total attempts). Must be >= 0.\n */\n maxRetries: z.ZodDefault<z.ZodNumber>;\n /**\n * Optional list of tools or tool names to apply retry logic to.\n * Can be a list of `BaseTool` instances or tool name strings.\n * If `undefined`, applies to all tools. Default is `undefined`.\n */\n tools: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodType<ClientTool, z.ZodTypeDef, ClientTool>, z.ZodType<ServerTool, z.ZodTypeDef, ServerTool>, z.ZodString]>, \"many\">>;\n /**\n * Either an array of error constructors to retry on, or a function\n * that takes an error and returns `true` if it should be retried.\n * Default is to retry on all errors.\n */\n retryOn: z.ZodDefault<z.ZodUnion<[z.ZodFunction<z.ZodTuple<[z.ZodType<Error, z.ZodTypeDef, Error>], z.ZodUnknown>, z.ZodBoolean>, z.ZodArray<z.ZodType<new (...args: any[]) => Error, z.ZodTypeDef, new (...args: any[]) => Error>, \"many\">]>>;\n /**\n * Behavior when all retries are exhausted. Options:\n * - `\"return_message\"` (default): Return a ToolMessage with error details,\n * allowing the LLM to handle the failure and potentially recover.\n * - `\"raise\"`: Re-raise the exception, stopping agent execution.\n * - Custom function: Function that takes the exception and returns a string\n * for the ToolMessage content, allowing custom error formatting.\n */\n onFailure: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<\"raise\">, z.ZodLiteral<\"return_message\">, z.ZodFunction<z.ZodTuple<[z.ZodType<Error, z.ZodTypeDef, Error>], z.ZodUnknown>, z.ZodString>]>>;\n /**\n * Multiplier for exponential backoff. Each retry waits\n * `initialDelayMs * (backoffFactor ** retryNumber)` milliseconds.\n * Set to 0.0 for constant delay. Default is 2.0.\n */\n backoffFactor: z.ZodDefault<z.ZodNumber>;\n /**\n * Initial delay in milliseconds before first retry. Default is 1000 (1 second).\n */\n initialDelayMs: z.ZodDefault<z.ZodNumber>;\n /**\n * Maximum delay in milliseconds between retries. Caps exponential\n * backoff growth. Default is 60000 (60 seconds).\n */\n maxDelayMs: z.ZodDefault<z.ZodNumber>;\n /**\n * Whether to add random jitter (±25%) to delay to avoid thundering herd.\n * Default is `true`.\n */\n jitter: z.ZodDefault<z.ZodBoolean>;\n}, \"strip\", z.ZodTypeAny, {\n maxRetries: number;\n tools?: (string | ServerTool | ClientTool)[] | undefined;\n retryOn: (new (...args: any[]) => Error)[] | ((args_0: Error, ...args: unknown[]) => boolean);\n onFailure: \"raise\" | \"return_message\" | ((args_0: Error, ...args: unknown[]) => string);\n backoffFactor: number;\n initialDelayMs: number;\n maxDelayMs: number;\n jitter: boolean;\n}, {\n maxRetries?: number | undefined;\n tools?: (string | ServerTool | ClientTool)[] | undefined;\n retryOn?: (new (...args: any[]) => Error)[] | ((args_0: Error, ...args: unknown[]) => boolean) | undefined;\n onFailure?: \"raise\" | \"return_message\" | ((args_0: Error, ...args: unknown[]) => string) | undefined;\n backoffFactor?: number | undefined;\n initialDelayMs?: number | undefined;\n maxDelayMs?: number | undefined;\n jitter?: boolean | undefined;\n}>;\nexport type ToolRetryMiddlewareConfig = z.input<typeof ToolRetryMiddlewareOptionsSchema>;\n/**\n * Middleware that automatically retries failed tool calls with configurable backoff.\n *\n * Supports retrying on specific exceptions and exponential backoff.\n *\n * @example Basic usage with default settings (2 retries, exponential backoff)\n * ```ts\n * import { createAgent, toolRetryMiddleware } from \"langchain\";\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [searchTool],\n * middleware: [toolRetryMiddleware()],\n * });\n * ```\n *\n * @example Retry specific exceptions only\n * ```ts\n * import { toolRetryMiddleware } from \"langchain\";\n *\n * const retry = toolRetryMiddleware({\n * maxRetries: 4,\n * retryOn: [TimeoutError, NetworkError],\n * backoffFactor: 1.5,\n * });\n * ```\n *\n * @example Custom exception filtering\n * ```ts\n * function shouldRetry(error: Error): boolean {\n * // Only retry on 5xx errors\n * if (error.name === \"HTTPError\" && \"statusCode\" in error) {\n * const statusCode = (error as any).statusCode;\n * return 500 <= statusCode && statusCode < 600;\n * }\n * return false;\n * }\n *\n * const retry = toolRetryMiddleware({\n * maxRetries: 3,\n * retryOn: shouldRetry,\n * });\n * ```\n *\n * @example Apply to specific tools with custom error handling\n * ```ts\n * const formatError = (error: Error) =>\n * \"Database temporarily unavailable. Please try again later.\";\n *\n * const retry = toolRetryMiddleware({\n * maxRetries: 4,\n * tools: [\"search_database\"],\n * onFailure: formatError,\n * });\n * ```\n *\n * @example Apply to specific tools using BaseTool instances\n * ```ts\n * import { tool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n *\n * const searchDatabase = tool(\n * async ({ query }) => {\n * // Search implementation\n * return results;\n * },\n * {\n * name: \"search_database\",\n * description: \"Search the database\",\n * schema: z.object({ query: z.string() }),\n * }\n * );\n *\n * const retry = toolRetryMiddleware({\n * maxRetries: 4,\n * tools: [searchDatabase], // Pass BaseTool instance\n * });\n * ```\n *\n * @example Constant backoff (no exponential growth)\n * ```ts\n * const retry = toolRetryMiddleware({\n * maxRetries: 5,\n * backoffFactor: 0.0, // No exponential growth\n * initialDelayMs: 2000, // Always wait 2 seconds\n * });\n * ```\n *\n * @example Raise exception on failure\n * ```ts\n * const retry = toolRetryMiddleware({\n * maxRetries: 2,\n * onFailure: \"raise\", // Re-raise exception instead of returning message\n * });\n * ```\n *\n * @param config - Configuration options for the retry middleware\n * @returns A middleware instance that handles tool failures with retries\n */\nexport declare function toolRetryMiddleware(config?: ToolRetryMiddlewareConfig): AgentMiddleware;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { sleep } from "./utils.js";
|
|
2
|
+
import { createMiddleware } from "../middleware.js";
|
|
3
|
+
import { ToolMessage } from "@langchain/core/messages";
|
|
4
|
+
import { z } from "zod/v3";
|
|
5
|
+
|
|
6
|
+
//#region src/agents/middleware/toolRetry.ts
|
|
7
|
+
/**
|
|
8
|
+
* Calculate delay for a retry attempt with exponential backoff and jitter.
|
|
9
|
+
*
|
|
10
|
+
* @param retryNumber - The retry attempt number (0-indexed)
|
|
11
|
+
* @param config - Configuration for backoff calculation
|
|
12
|
+
* @returns Delay in milliseconds before next retry
|
|
13
|
+
*
|
|
14
|
+
* @internal Exported for testing purposes
|
|
15
|
+
*/
|
|
16
|
+
function calculateRetryDelay(config, retryNumber) {
|
|
17
|
+
const { backoffFactor, initialDelayMs, maxDelayMs, jitter } = config;
|
|
18
|
+
let delay;
|
|
19
|
+
if (backoffFactor === 0) delay = initialDelayMs;
|
|
20
|
+
else delay = initialDelayMs * backoffFactor ** retryNumber;
|
|
21
|
+
delay = Math.min(delay, maxDelayMs);
|
|
22
|
+
if (jitter && delay > 0) {
|
|
23
|
+
const jitterAmount = delay * .25;
|
|
24
|
+
delay = delay + (Math.random() * 2 - 1) * jitterAmount;
|
|
25
|
+
delay = Math.max(0, delay);
|
|
26
|
+
}
|
|
27
|
+
return delay;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Configuration options for the Tool Retry Middleware.
|
|
31
|
+
*/
|
|
32
|
+
const ToolRetryMiddlewareOptionsSchema = z.object({
|
|
33
|
+
maxRetries: z.number().min(0).default(2),
|
|
34
|
+
tools: z.array(z.union([
|
|
35
|
+
z.custom(),
|
|
36
|
+
z.custom(),
|
|
37
|
+
z.string()
|
|
38
|
+
])).optional(),
|
|
39
|
+
retryOn: z.union([z.function().args(z.instanceof(Error)).returns(z.boolean()), z.array(z.custom())]).default(() => () => true),
|
|
40
|
+
onFailure: z.union([
|
|
41
|
+
z.literal("raise"),
|
|
42
|
+
z.literal("return_message"),
|
|
43
|
+
z.function().args(z.instanceof(Error)).returns(z.string())
|
|
44
|
+
]).default("return_message"),
|
|
45
|
+
backoffFactor: z.number().min(0).default(2),
|
|
46
|
+
initialDelayMs: z.number().min(0).default(1e3),
|
|
47
|
+
maxDelayMs: z.number().min(0).default(6e4),
|
|
48
|
+
jitter: z.boolean().default(true)
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* Middleware that automatically retries failed tool calls with configurable backoff.
|
|
52
|
+
*
|
|
53
|
+
* Supports retrying on specific exceptions and exponential backoff.
|
|
54
|
+
*
|
|
55
|
+
* @example Basic usage with default settings (2 retries, exponential backoff)
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { createAgent, toolRetryMiddleware } from "langchain";
|
|
58
|
+
*
|
|
59
|
+
* const agent = createAgent({
|
|
60
|
+
* model: "openai:gpt-4o",
|
|
61
|
+
* tools: [searchTool],
|
|
62
|
+
* middleware: [toolRetryMiddleware()],
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @example Retry specific exceptions only
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { toolRetryMiddleware } from "langchain";
|
|
69
|
+
*
|
|
70
|
+
* const retry = toolRetryMiddleware({
|
|
71
|
+
* maxRetries: 4,
|
|
72
|
+
* retryOn: [TimeoutError, NetworkError],
|
|
73
|
+
* backoffFactor: 1.5,
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example Custom exception filtering
|
|
78
|
+
* ```ts
|
|
79
|
+
* function shouldRetry(error: Error): boolean {
|
|
80
|
+
* // Only retry on 5xx errors
|
|
81
|
+
* if (error.name === "HTTPError" && "statusCode" in error) {
|
|
82
|
+
* const statusCode = (error as any).statusCode;
|
|
83
|
+
* return 500 <= statusCode && statusCode < 600;
|
|
84
|
+
* }
|
|
85
|
+
* return false;
|
|
86
|
+
* }
|
|
87
|
+
*
|
|
88
|
+
* const retry = toolRetryMiddleware({
|
|
89
|
+
* maxRetries: 3,
|
|
90
|
+
* retryOn: shouldRetry,
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @example Apply to specific tools with custom error handling
|
|
95
|
+
* ```ts
|
|
96
|
+
* const formatError = (error: Error) =>
|
|
97
|
+
* "Database temporarily unavailable. Please try again later.";
|
|
98
|
+
*
|
|
99
|
+
* const retry = toolRetryMiddleware({
|
|
100
|
+
* maxRetries: 4,
|
|
101
|
+
* tools: ["search_database"],
|
|
102
|
+
* onFailure: formatError,
|
|
103
|
+
* });
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @example Apply to specific tools using BaseTool instances
|
|
107
|
+
* ```ts
|
|
108
|
+
* import { tool } from "@langchain/core/tools";
|
|
109
|
+
* import { z } from "zod";
|
|
110
|
+
*
|
|
111
|
+
* const searchDatabase = tool(
|
|
112
|
+
* async ({ query }) => {
|
|
113
|
+
* // Search implementation
|
|
114
|
+
* return results;
|
|
115
|
+
* },
|
|
116
|
+
* {
|
|
117
|
+
* name: "search_database",
|
|
118
|
+
* description: "Search the database",
|
|
119
|
+
* schema: z.object({ query: z.string() }),
|
|
120
|
+
* }
|
|
121
|
+
* );
|
|
122
|
+
*
|
|
123
|
+
* const retry = toolRetryMiddleware({
|
|
124
|
+
* maxRetries: 4,
|
|
125
|
+
* tools: [searchDatabase], // Pass BaseTool instance
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @example Constant backoff (no exponential growth)
|
|
130
|
+
* ```ts
|
|
131
|
+
* const retry = toolRetryMiddleware({
|
|
132
|
+
* maxRetries: 5,
|
|
133
|
+
* backoffFactor: 0.0, // No exponential growth
|
|
134
|
+
* initialDelayMs: 2000, // Always wait 2 seconds
|
|
135
|
+
* });
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* @example Raise exception on failure
|
|
139
|
+
* ```ts
|
|
140
|
+
* const retry = toolRetryMiddleware({
|
|
141
|
+
* maxRetries: 2,
|
|
142
|
+
* onFailure: "raise", // Re-raise exception instead of returning message
|
|
143
|
+
* });
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* @param config - Configuration options for the retry middleware
|
|
147
|
+
* @returns A middleware instance that handles tool failures with retries
|
|
148
|
+
*/
|
|
149
|
+
function toolRetryMiddleware(config = {}) {
|
|
150
|
+
const { maxRetries, tools, retryOn, onFailure, backoffFactor, initialDelayMs, maxDelayMs, jitter } = ToolRetryMiddlewareOptionsSchema.parse(config);
|
|
151
|
+
const toolFilter = [];
|
|
152
|
+
for (const tool of tools ?? []) if (typeof tool === "string") toolFilter.push(tool);
|
|
153
|
+
else if ("name" in tool && typeof tool.name === "string") toolFilter.push(tool.name);
|
|
154
|
+
else throw new TypeError("Expected a tool name string or tool instance to be passed to toolRetryMiddleware");
|
|
155
|
+
/**
|
|
156
|
+
* Check if retry logic should apply to this tool.
|
|
157
|
+
*/
|
|
158
|
+
const shouldRetryTool = (toolName) => {
|
|
159
|
+
if (toolFilter.length === 0) return true;
|
|
160
|
+
return toolFilter.includes(toolName);
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Check if the exception should trigger a retry.
|
|
164
|
+
*/
|
|
165
|
+
const shouldRetryException = (error) => {
|
|
166
|
+
if (typeof retryOn === "function") return retryOn(error);
|
|
167
|
+
return retryOn.some((ErrorConstructor) => error.constructor === ErrorConstructor);
|
|
168
|
+
};
|
|
169
|
+
const delayConfig = {
|
|
170
|
+
backoffFactor,
|
|
171
|
+
initialDelayMs,
|
|
172
|
+
maxDelayMs,
|
|
173
|
+
jitter
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Format the failure message when retries are exhausted.
|
|
177
|
+
*/
|
|
178
|
+
const formatFailureMessage = (toolName, error, attemptsMade) => {
|
|
179
|
+
const errorType = error.constructor.name;
|
|
180
|
+
const attemptWord = attemptsMade === 1 ? "attempt" : "attempts";
|
|
181
|
+
return `Tool '${toolName}' failed after ${attemptsMade} ${attemptWord} with ${errorType}`;
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Handle failure when all retries are exhausted.
|
|
185
|
+
*/
|
|
186
|
+
const handleFailure = (toolName, toolCallId, error, attemptsMade) => {
|
|
187
|
+
if (onFailure === "raise") throw error;
|
|
188
|
+
let content;
|
|
189
|
+
if (typeof onFailure === "function") content = onFailure(error);
|
|
190
|
+
else content = formatFailureMessage(toolName, error, attemptsMade);
|
|
191
|
+
return new ToolMessage({
|
|
192
|
+
content,
|
|
193
|
+
tool_call_id: toolCallId,
|
|
194
|
+
name: toolName,
|
|
195
|
+
status: "error"
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
return createMiddleware({
|
|
199
|
+
name: "toolRetryMiddleware",
|
|
200
|
+
contextSchema: ToolRetryMiddlewareOptionsSchema,
|
|
201
|
+
wrapToolCall: async (request, handler) => {
|
|
202
|
+
const toolName = request.tool.name;
|
|
203
|
+
if (!shouldRetryTool(toolName)) return handler(request);
|
|
204
|
+
const toolCallId = request.toolCall.id ?? "";
|
|
205
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) try {
|
|
206
|
+
return await handler(request);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
const attemptsMade = attempt + 1;
|
|
209
|
+
const err = error && typeof error === "object" && "message" in error ? error : new Error(String(error));
|
|
210
|
+
if (!shouldRetryException(err)) return handleFailure(toolName, toolCallId, err, attemptsMade);
|
|
211
|
+
if (attempt < maxRetries) {
|
|
212
|
+
const delay = calculateRetryDelay(delayConfig, attempt);
|
|
213
|
+
if (delay > 0) await sleep(delay);
|
|
214
|
+
} else return handleFailure(toolName, toolCallId, err, attemptsMade);
|
|
215
|
+
}
|
|
216
|
+
throw new Error("Unexpected: retry loop completed without returning");
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
//#endregion
|
|
222
|
+
export { toolRetryMiddleware };
|
|
223
|
+
//# sourceMappingURL=toolRetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolRetry.js","names":["config: {\n backoffFactor: number;\n initialDelayMs: number;\n maxDelayMs: number;\n jitter: boolean;\n }","retryNumber: number","delay: number","config: ToolRetryMiddlewareConfig","toolFilter: string[]","toolName: string","error: Error","attemptsMade: number","toolCallId: string","content: string"],"sources":["../../../src/agents/middleware/toolRetry.ts"],"sourcesContent":["/**\n * Tool retry middleware for agents.\n */\nimport { z } from \"zod/v3\";\nimport { ToolMessage } from \"@langchain/core/messages\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\n\nimport { createMiddleware } from \"../middleware.js\";\nimport type { AgentMiddleware } from \"./types.js\";\nimport { sleep } from \"./utils.js\";\n\n/**\n * Calculate delay for a retry attempt with exponential backoff and jitter.\n *\n * @param retryNumber - The retry attempt number (0-indexed)\n * @param config - Configuration for backoff calculation\n * @returns Delay in milliseconds before next retry\n *\n * @internal Exported for testing purposes\n */\nexport function calculateRetryDelay(\n config: {\n backoffFactor: number;\n initialDelayMs: number;\n maxDelayMs: number;\n jitter: boolean;\n },\n retryNumber: number\n): number {\n const { backoffFactor, initialDelayMs, maxDelayMs, jitter } = config;\n\n let delay: number;\n if (backoffFactor === 0.0) {\n delay = initialDelayMs;\n } else {\n delay = initialDelayMs * backoffFactor ** retryNumber;\n }\n\n // Cap at maxDelayMs\n delay = Math.min(delay, maxDelayMs);\n\n if (jitter && delay > 0) {\n const jitterAmount = delay * 0.25;\n delay = delay + (Math.random() * 2 - 1) * jitterAmount;\n // Ensure delay is not negative after jitter\n delay = Math.max(0, delay);\n }\n\n return delay;\n}\n\n/**\n * Configuration options for the Tool Retry Middleware.\n */\nexport const ToolRetryMiddlewareOptionsSchema = z.object({\n /**\n * Maximum number of retry attempts after the initial call.\n * Default is 2 retries (3 total attempts). Must be >= 0.\n */\n maxRetries: z.number().min(0).default(2),\n\n /**\n * Optional list of tools or tool names to apply retry logic to.\n * Can be a list of `BaseTool` instances or tool name strings.\n * If `undefined`, applies to all tools. Default is `undefined`.\n */\n tools: z\n .array(\n z.union([z.custom<ClientTool>(), z.custom<ServerTool>(), z.string()])\n )\n .optional(),\n\n /**\n * Either an array of error constructors to retry on, or a function\n * that takes an error and returns `true` if it should be retried.\n * Default is to retry on all errors.\n */\n retryOn: z\n .union([\n z.function().args(z.instanceof(Error)).returns(z.boolean()),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n z.array(z.custom<new (...args: any[]) => Error>()),\n ])\n .default(() => () => true),\n\n /**\n * Behavior when all retries are exhausted. Options:\n * - `\"return_message\"` (default): Return a ToolMessage with error details,\n * allowing the LLM to handle the failure and potentially recover.\n * - `\"raise\"`: Re-raise the exception, stopping agent execution.\n * - Custom function: Function that takes the exception and returns a string\n * for the ToolMessage content, allowing custom error formatting.\n */\n onFailure: z\n .union([\n z.literal(\"raise\"),\n z.literal(\"return_message\"),\n z.function().args(z.instanceof(Error)).returns(z.string()),\n ])\n .default(\"return_message\"),\n\n /**\n * Multiplier for exponential backoff. Each retry waits\n * `initialDelayMs * (backoffFactor ** retryNumber)` milliseconds.\n * Set to 0.0 for constant delay. Default is 2.0.\n */\n backoffFactor: z.number().min(0).default(2.0),\n\n /**\n * Initial delay in milliseconds before first retry. Default is 1000 (1 second).\n */\n initialDelayMs: z.number().min(0).default(1000),\n\n /**\n * Maximum delay in milliseconds between retries. Caps exponential\n * backoff growth. Default is 60000 (60 seconds).\n */\n maxDelayMs: z.number().min(0).default(60000),\n\n /**\n * Whether to add random jitter (±25%) to delay to avoid thundering herd.\n * Default is `true`.\n */\n jitter: z.boolean().default(true),\n});\n\nexport type ToolRetryMiddlewareConfig = z.input<\n typeof ToolRetryMiddlewareOptionsSchema\n>;\n\n/**\n * Middleware that automatically retries failed tool calls with configurable backoff.\n *\n * Supports retrying on specific exceptions and exponential backoff.\n *\n * @example Basic usage with default settings (2 retries, exponential backoff)\n * ```ts\n * import { createAgent, toolRetryMiddleware } from \"langchain\";\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [searchTool],\n * middleware: [toolRetryMiddleware()],\n * });\n * ```\n *\n * @example Retry specific exceptions only\n * ```ts\n * import { toolRetryMiddleware } from \"langchain\";\n *\n * const retry = toolRetryMiddleware({\n * maxRetries: 4,\n * retryOn: [TimeoutError, NetworkError],\n * backoffFactor: 1.5,\n * });\n * ```\n *\n * @example Custom exception filtering\n * ```ts\n * function shouldRetry(error: Error): boolean {\n * // Only retry on 5xx errors\n * if (error.name === \"HTTPError\" && \"statusCode\" in error) {\n * const statusCode = (error as any).statusCode;\n * return 500 <= statusCode && statusCode < 600;\n * }\n * return false;\n * }\n *\n * const retry = toolRetryMiddleware({\n * maxRetries: 3,\n * retryOn: shouldRetry,\n * });\n * ```\n *\n * @example Apply to specific tools with custom error handling\n * ```ts\n * const formatError = (error: Error) =>\n * \"Database temporarily unavailable. Please try again later.\";\n *\n * const retry = toolRetryMiddleware({\n * maxRetries: 4,\n * tools: [\"search_database\"],\n * onFailure: formatError,\n * });\n * ```\n *\n * @example Apply to specific tools using BaseTool instances\n * ```ts\n * import { tool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n *\n * const searchDatabase = tool(\n * async ({ query }) => {\n * // Search implementation\n * return results;\n * },\n * {\n * name: \"search_database\",\n * description: \"Search the database\",\n * schema: z.object({ query: z.string() }),\n * }\n * );\n *\n * const retry = toolRetryMiddleware({\n * maxRetries: 4,\n * tools: [searchDatabase], // Pass BaseTool instance\n * });\n * ```\n *\n * @example Constant backoff (no exponential growth)\n * ```ts\n * const retry = toolRetryMiddleware({\n * maxRetries: 5,\n * backoffFactor: 0.0, // No exponential growth\n * initialDelayMs: 2000, // Always wait 2 seconds\n * });\n * ```\n *\n * @example Raise exception on failure\n * ```ts\n * const retry = toolRetryMiddleware({\n * maxRetries: 2,\n * onFailure: \"raise\", // Re-raise exception instead of returning message\n * });\n * ```\n *\n * @param config - Configuration options for the retry middleware\n * @returns A middleware instance that handles tool failures with retries\n */\nexport function toolRetryMiddleware(\n config: ToolRetryMiddlewareConfig = {}\n): AgentMiddleware {\n const {\n maxRetries,\n tools,\n retryOn,\n onFailure,\n backoffFactor,\n initialDelayMs,\n maxDelayMs,\n jitter,\n } = ToolRetryMiddlewareOptionsSchema.parse(config);\n\n // Extract tool names from BaseTool instances or strings\n const toolFilter: string[] = [];\n for (const tool of tools ?? []) {\n if (typeof tool === \"string\") {\n toolFilter.push(tool);\n } else if (\"name\" in tool && typeof tool.name === \"string\") {\n toolFilter.push(tool.name);\n } else {\n throw new TypeError(\n \"Expected a tool name string or tool instance to be passed to toolRetryMiddleware\"\n );\n }\n }\n\n /**\n * Check if retry logic should apply to this tool.\n */\n const shouldRetryTool = (toolName: string): boolean => {\n if (toolFilter.length === 0) {\n return true;\n }\n return toolFilter.includes(toolName);\n };\n\n /**\n * Check if the exception should trigger a retry.\n */\n const shouldRetryException = (error: Error): boolean => {\n if (typeof retryOn === \"function\") {\n return retryOn(error);\n }\n // retryOn is an array of error constructors\n return retryOn.some(\n (ErrorConstructor) => error.constructor === ErrorConstructor\n );\n };\n\n // Use the exported calculateRetryDelay function with our config\n const delayConfig = { backoffFactor, initialDelayMs, maxDelayMs, jitter };\n\n /**\n * Format the failure message when retries are exhausted.\n */\n const formatFailureMessage = (\n toolName: string,\n error: Error,\n attemptsMade: number\n ): string => {\n const errorType = error.constructor.name;\n const attemptWord = attemptsMade === 1 ? \"attempt\" : \"attempts\";\n return `Tool '${toolName}' failed after ${attemptsMade} ${attemptWord} with ${errorType}`;\n };\n\n /**\n * Handle failure when all retries are exhausted.\n */\n const handleFailure = (\n toolName: string,\n toolCallId: string,\n error: Error,\n attemptsMade: number\n ): ToolMessage => {\n if (onFailure === \"raise\") {\n throw error;\n }\n\n let content: string;\n if (typeof onFailure === \"function\") {\n content = onFailure(error);\n } else {\n content = formatFailureMessage(toolName, error, attemptsMade);\n }\n\n return new ToolMessage({\n content,\n tool_call_id: toolCallId,\n name: toolName,\n status: \"error\",\n });\n };\n\n return createMiddleware({\n name: \"toolRetryMiddleware\",\n contextSchema: ToolRetryMiddlewareOptionsSchema,\n wrapToolCall: async (request, handler) => {\n const toolName = request.tool.name as string;\n\n // Check if retry should apply to this tool\n if (!shouldRetryTool(toolName)) {\n return handler(request);\n }\n\n const toolCallId = request.toolCall.id ?? \"\";\n\n // Initial attempt + retries\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await handler(request);\n } catch (error) {\n const attemptsMade = attempt + 1; // attempt is 0-indexed\n\n // Ensure error is an Error instance\n const err =\n error && typeof error === \"object\" && \"message\" in error\n ? (error as Error)\n : new Error(String(error));\n\n // Check if we should retry this exception\n if (!shouldRetryException(err)) {\n // Exception is not retryable, handle failure immediately\n return handleFailure(toolName, toolCallId, err, attemptsMade);\n }\n\n // Check if we have more retries left\n if (attempt < maxRetries) {\n // Calculate and apply backoff delay\n const delay = calculateRetryDelay(delayConfig, attempt);\n if (delay > 0) {\n await sleep(delay);\n }\n // Continue to next retry\n } else {\n // No more retries, handle failure\n return handleFailure(toolName, toolCallId, err, attemptsMade);\n }\n }\n }\n\n // Unreachable: loop always returns via handler success or handleFailure\n throw new Error(\"Unexpected: retry loop completed without returning\");\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,SAAgB,oBACdA,QAMAC,aACQ;CACR,MAAM,EAAE,eAAe,gBAAgB,YAAY,QAAQ,GAAG;CAE9D,IAAIC;AACJ,KAAI,kBAAkB,GACpB,QAAQ;MAER,QAAQ,iBAAiB,iBAAiB;CAI5C,QAAQ,KAAK,IAAI,OAAO,WAAW;AAEnC,KAAI,UAAU,QAAQ,GAAG;EACvB,MAAM,eAAe,QAAQ;EAC7B,QAAQ,SAAS,KAAK,QAAQ,GAAG,IAAI,KAAK;EAE1C,QAAQ,KAAK,IAAI,GAAG,MAAM;CAC3B;AAED,QAAO;AACR;;;;AAKD,MAAa,mCAAmC,EAAE,OAAO;CAKvD,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;CAOxC,OAAO,EACJ,MACC,EAAE,MAAM;EAAC,EAAE,QAAoB;EAAE,EAAE,QAAoB;EAAE,EAAE,QAAQ;CAAC,EAAC,CACtE,CACA,UAAU;CAOb,SAAS,EACN,MAAM,CACL,EAAE,UAAU,CAAC,KAAK,EAAE,WAAW,MAAM,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,EAE3D,EAAE,MAAM,EAAE,QAAuC,CAAC,AACnD,EAAC,CACD,QAAQ,MAAM,MAAM,KAAK;CAU5B,WAAW,EACR,MAAM;EACL,EAAE,QAAQ,QAAQ;EAClB,EAAE,QAAQ,iBAAiB;EAC3B,EAAE,UAAU,CAAC,KAAK,EAAE,WAAW,MAAM,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC3D,EAAC,CACD,QAAQ,iBAAiB;CAO5B,eAAe,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAI;CAK7C,gBAAgB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,IAAK;CAM/C,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,IAAM;CAM5C,QAAQ,EAAE,SAAS,CAAC,QAAQ,KAAK;AAClC,EAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyGF,SAAgB,oBACdC,SAAoC,CAAE,GACrB;CACjB,MAAM,EACJ,YACA,OACA,SACA,WACA,eACA,gBACA,YACA,QACD,GAAG,iCAAiC,MAAM,OAAO;CAGlD,MAAMC,aAAuB,CAAE;AAC/B,MAAK,MAAM,QAAQ,SAAS,CAAE,EAC5B,KAAI,OAAO,SAAS,UAClB,WAAW,KAAK,KAAK;UACZ,UAAU,QAAQ,OAAO,KAAK,SAAS,UAChD,WAAW,KAAK,KAAK,KAAK;KAE1B,OAAM,IAAI,UACR;;;;CAQN,MAAM,kBAAkB,CAACC,aAA8B;AACrD,MAAI,WAAW,WAAW,EACxB,QAAO;AAET,SAAO,WAAW,SAAS,SAAS;CACrC;;;;CAKD,MAAM,uBAAuB,CAACC,UAA0B;AACtD,MAAI,OAAO,YAAY,WACrB,QAAO,QAAQ,MAAM;AAGvB,SAAO,QAAQ,KACb,CAAC,qBAAqB,MAAM,gBAAgB,iBAC7C;CACF;CAGD,MAAM,cAAc;EAAE;EAAe;EAAgB;EAAY;CAAQ;;;;CAKzE,MAAM,uBAAuB,CAC3BD,UACAC,OACAC,iBACW;EACX,MAAM,YAAY,MAAM,YAAY;EACpC,MAAM,cAAc,iBAAiB,IAAI,YAAY;AACrD,SAAO,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,aAAa,CAAC,EAAE,YAAY,MAAM,EAAE,WAAW;CAC1F;;;;CAKD,MAAM,gBAAgB,CACpBF,UACAG,YACAF,OACAC,iBACgB;AAChB,MAAI,cAAc,QAChB,OAAM;EAGR,IAAIE;AACJ,MAAI,OAAO,cAAc,YACvB,UAAU,UAAU,MAAM;OAE1B,UAAU,qBAAqB,UAAU,OAAO,aAAa;AAG/D,SAAO,IAAI,YAAY;GACrB;GACA,cAAc;GACd,MAAM;GACN,QAAQ;EACT;CACF;AAED,QAAO,iBAAiB;EACtB,MAAM;EACN,eAAe;EACf,cAAc,OAAO,SAAS,YAAY;GACxC,MAAM,WAAW,QAAQ,KAAK;AAG9B,OAAI,CAAC,gBAAgB,SAAS,CAC5B,QAAO,QAAQ,QAAQ;GAGzB,MAAM,aAAa,QAAQ,SAAS,MAAM;AAG1C,QAAK,IAAI,UAAU,GAAG,WAAW,YAAY,UAC3C,KAAI;AACF,WAAO,MAAM,QAAQ,QAAQ;GAC9B,SAAQ,OAAO;IACd,MAAM,eAAe,UAAU;IAG/B,MAAM,MACJ,SAAS,OAAO,UAAU,YAAY,aAAa,QAC9C,QACD,IAAI,MAAM,OAAO,MAAM;AAG7B,QAAI,CAAC,qBAAqB,IAAI,CAE5B,QAAO,cAAc,UAAU,YAAY,KAAK,aAAa;AAI/D,QAAI,UAAU,YAAY;KAExB,MAAM,QAAQ,oBAAoB,aAAa,QAAQ;AACvD,SAAI,QAAQ,GACV,MAAM,MAAM,MAAM;IAGrB,MAEC,QAAO,cAAc,UAAU,YAAY,KAAK,aAAa;GAEhE;AAIH,SAAM,IAAI,MAAM;EACjB;CACF,EAAC;AACH"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { JumpToTarget } from "../constants.cjs";
|
|
2
|
-
import { ClientTool, ServerTool } from "../tools.cjs";
|
|
3
2
|
import { AgentBuiltInState, Runtime } from "../runtime.cjs";
|
|
4
3
|
import { ModelRequest } from "../nodes/types.cjs";
|
|
5
4
|
import { AIMessage, ToolMessage } from "@langchain/core/messages";
|
|
5
|
+
import { ClientTool, ServerTool } from "@langchain/core/tools";
|
|
6
6
|
import { InferInteropZodInput, InferInteropZodOutput, InteropZodDefault, InteropZodObject, InteropZodOptional } from "@langchain/core/utils/types";
|
|
7
7
|
import { ToolCall as ToolCall$1 } from "@langchain/core/messages/tool";
|
|
8
8
|
import { AnnotationRoot, Command } from "@langchain/langgraph";
|
|
@@ -11,11 +11,13 @@ import { InteropZodToStateDefinition } from "@langchain/langgraph/zod";
|
|
|
11
11
|
//#region src/agents/middleware/types.d.ts
|
|
12
12
|
type PromiseOrValue<T> = T | Promise<T>;
|
|
13
13
|
type AnyAnnotationRoot = AnnotationRoot<any>;
|
|
14
|
-
type NormalizedSchemaInput<TSchema extends InteropZodObject | undefined = any> = TSchema extends InteropZodObject ?
|
|
14
|
+
type NormalizedSchemaInput<TSchema extends InteropZodObject | undefined | never = any> = [TSchema] extends [never] ? AgentBuiltInState : TSchema extends InteropZodObject ? InferInteropZodOutput<TSchema> & AgentBuiltInState : TSchema extends Record<string, unknown> ? TSchema & AgentBuiltInState : AgentBuiltInState;
|
|
15
15
|
/**
|
|
16
16
|
* Result type for middleware functions.
|
|
17
17
|
*/
|
|
18
|
-
type MiddlewareResult<TState> = TState
|
|
18
|
+
type MiddlewareResult<TState> = (TState & {
|
|
19
|
+
jumpTo?: JumpToTarget;
|
|
20
|
+
}) | void;
|
|
19
21
|
/**
|
|
20
22
|
* Represents a tool call request for the wrapToolCall hook.
|
|
21
23
|
* Contains the tool call information along with the agent's current state and runtime.
|
|
@@ -43,12 +45,12 @@ interface ToolCallRequest<TState extends Record<string, unknown> = Record<string
|
|
|
43
45
|
* Handler function type for wrapping tool calls.
|
|
44
46
|
* Takes a tool call request and returns the tool result or a command.
|
|
45
47
|
*/
|
|
46
|
-
type ToolCallHandler<TSchema extends
|
|
48
|
+
type ToolCallHandler<TSchema extends Record<string, unknown> = AgentBuiltInState, TContext = unknown> = (request: ToolCallRequest<TSchema, TContext>) => PromiseOrValue<ToolMessage | Command>;
|
|
47
49
|
/**
|
|
48
50
|
* Wrapper function type for the wrapToolCall hook.
|
|
49
51
|
* Allows middleware to intercept and modify tool execution.
|
|
50
52
|
*/
|
|
51
|
-
type WrapToolCallHook<TSchema extends InteropZodObject | undefined =
|
|
53
|
+
type WrapToolCallHook<TSchema extends InteropZodObject | undefined = undefined, TContext = unknown> = (request: ToolCallRequest<NormalizedSchemaInput<TSchema>, TContext>, handler: ToolCallHandler<NormalizedSchemaInput<TSchema>, TContext>) => PromiseOrValue<ToolMessage | Command>;
|
|
52
54
|
/**
|
|
53
55
|
* Handler function type for wrapping model calls.
|
|
54
56
|
* Takes a model request and returns the AI message response.
|
|
@@ -56,7 +58,7 @@ type WrapToolCallHook<TSchema extends InteropZodObject | undefined = any, TConte
|
|
|
56
58
|
* @param request - The model request containing model, messages, systemPrompt, tools, state, and runtime
|
|
57
59
|
* @returns The AI message response from the model
|
|
58
60
|
*/
|
|
59
|
-
type WrapModelCallHandler<TSchema extends InteropZodObject | undefined =
|
|
61
|
+
type WrapModelCallHandler<TSchema extends InteropZodObject | undefined = undefined, TContext = unknown> = (request: ModelRequest<NormalizedSchemaInput<TSchema>, TContext>) => PromiseOrValue<AIMessage>;
|
|
60
62
|
/**
|
|
61
63
|
* Wrapper function type for the wrapModelCall hook.
|
|
62
64
|
* Allows middleware to intercept and modify model execution.
|
|
@@ -70,7 +72,7 @@ type WrapModelCallHandler<TSchema extends InteropZodObject | undefined = any, TC
|
|
|
70
72
|
* @param handler - The function that invokes the model. Call this with a ModelRequest to get the response
|
|
71
73
|
* @returns The AI message response from the model (or a modified version)
|
|
72
74
|
*/
|
|
73
|
-
type WrapModelCallHook<TSchema extends InteropZodObject | undefined =
|
|
75
|
+
type WrapModelCallHook<TSchema extends InteropZodObject | undefined = undefined, TContext = unknown> = (request: ModelRequest<NormalizedSchemaInput<TSchema>, TContext>, handler: WrapModelCallHandler<TSchema, TContext>) => PromiseOrValue<AIMessage>;
|
|
74
76
|
/**
|
|
75
77
|
* Handler function type for the beforeAgent hook.
|
|
76
78
|
* Called once at the start of agent invocation before any model calls or tool executions.
|
|
@@ -79,14 +81,14 @@ type WrapModelCallHook<TSchema extends InteropZodObject | undefined = any, TCont
|
|
|
79
81
|
* @param runtime - The runtime context containing metadata, signal, writer, interrupt, etc.
|
|
80
82
|
* @returns A middleware result containing partial state updates or undefined to pass through
|
|
81
83
|
*/
|
|
82
|
-
type BeforeAgentHandler<TSchema
|
|
84
|
+
type BeforeAgentHandler<TSchema, TContext> = (state: TSchema, runtime: Runtime<TContext>) => PromiseOrValue<MiddlewareResult<Partial<TSchema>>>;
|
|
83
85
|
/**
|
|
84
86
|
* Hook type for the beforeAgent lifecycle event.
|
|
85
87
|
* Can be either a handler function or an object with a handler and optional jump targets.
|
|
86
88
|
* This hook is called once at the start of the agent invocation.
|
|
87
89
|
*/
|
|
88
|
-
type BeforeAgentHook<TSchema extends InteropZodObject | undefined =
|
|
89
|
-
hook: BeforeAgentHandler<TSchema
|
|
90
|
+
type BeforeAgentHook<TSchema extends InteropZodObject | undefined = undefined, TContext = unknown> = BeforeAgentHandler<NormalizedSchemaInput<TSchema>, TContext> | {
|
|
91
|
+
hook: BeforeAgentHandler<NormalizedSchemaInput<TSchema>, TContext>;
|
|
90
92
|
canJumpTo?: JumpToTarget[];
|
|
91
93
|
};
|
|
92
94
|
/**
|
|
@@ -97,14 +99,14 @@ type BeforeAgentHook<TSchema extends InteropZodObject | undefined = any, TContex
|
|
|
97
99
|
* @param runtime - The runtime context containing metadata, signal, writer, interrupt, etc.
|
|
98
100
|
* @returns A middleware result containing partial state updates or undefined to pass through
|
|
99
101
|
*/
|
|
100
|
-
type BeforeModelHandler<TSchema
|
|
102
|
+
type BeforeModelHandler<TSchema, TContext> = (state: TSchema, runtime: Runtime<TContext>) => PromiseOrValue<MiddlewareResult<Partial<TSchema>>>;
|
|
101
103
|
/**
|
|
102
104
|
* Hook type for the beforeModel lifecycle event.
|
|
103
105
|
* Can be either a handler function or an object with a handler and optional jump targets.
|
|
104
106
|
* This hook is called before each model invocation.
|
|
105
107
|
*/
|
|
106
|
-
type BeforeModelHook<TSchema extends InteropZodObject | undefined =
|
|
107
|
-
hook: BeforeModelHandler<TSchema
|
|
108
|
+
type BeforeModelHook<TSchema extends InteropZodObject | undefined = undefined, TContext = unknown> = BeforeModelHandler<NormalizedSchemaInput<TSchema>, TContext> | {
|
|
109
|
+
hook: BeforeModelHandler<NormalizedSchemaInput<TSchema>, TContext>;
|
|
108
110
|
canJumpTo?: JumpToTarget[];
|
|
109
111
|
};
|
|
110
112
|
/**
|
|
@@ -116,14 +118,14 @@ type BeforeModelHook<TSchema extends InteropZodObject | undefined = any, TContex
|
|
|
116
118
|
* @param runtime - The runtime context containing metadata, signal, writer, interrupt, etc.
|
|
117
119
|
* @returns A middleware result containing partial state updates or undefined to pass through
|
|
118
120
|
*/
|
|
119
|
-
type AfterModelHandler<TSchema
|
|
121
|
+
type AfterModelHandler<TSchema, TContext> = (state: TSchema, runtime: Runtime<TContext>) => PromiseOrValue<MiddlewareResult<Partial<TSchema>>>;
|
|
120
122
|
/**
|
|
121
123
|
* Hook type for the afterModel lifecycle event.
|
|
122
124
|
* Can be either a handler function or an object with a handler and optional jump targets.
|
|
123
125
|
* This hook is called after each model invocation.
|
|
124
126
|
*/
|
|
125
|
-
type AfterModelHook<TSchema extends InteropZodObject | undefined =
|
|
126
|
-
hook: AfterModelHandler<TSchema
|
|
127
|
+
type AfterModelHook<TSchema extends InteropZodObject | undefined = undefined, TContext = unknown> = AfterModelHandler<NormalizedSchemaInput<TSchema>, TContext> | {
|
|
128
|
+
hook: AfterModelHandler<NormalizedSchemaInput<TSchema>, TContext>;
|
|
127
129
|
canJumpTo?: JumpToTarget[];
|
|
128
130
|
};
|
|
129
131
|
/**
|
|
@@ -134,14 +136,14 @@ type AfterModelHook<TSchema extends InteropZodObject | undefined = any, TContext
|
|
|
134
136
|
* @param runtime - The runtime context containing metadata, signal, writer, interrupt, etc.
|
|
135
137
|
* @returns A middleware result containing partial state updates or undefined to pass through
|
|
136
138
|
*/
|
|
137
|
-
type AfterAgentHandler<TSchema
|
|
139
|
+
type AfterAgentHandler<TSchema, TContext> = (state: TSchema, runtime: Runtime<TContext>) => PromiseOrValue<MiddlewareResult<Partial<TSchema>>>;
|
|
138
140
|
/**
|
|
139
141
|
* Hook type for the afterAgent lifecycle event.
|
|
140
142
|
* Can be either a handler function or an object with a handler and optional jump targets.
|
|
141
143
|
* This hook is called once at the end of the agent invocation.
|
|
142
144
|
*/
|
|
143
|
-
type AfterAgentHook<TSchema extends InteropZodObject | undefined =
|
|
144
|
-
hook: AfterAgentHandler<TSchema
|
|
145
|
+
type AfterAgentHook<TSchema extends InteropZodObject | undefined = undefined, TContext = unknown> = AfterAgentHandler<NormalizedSchemaInput<TSchema>, TContext> | {
|
|
146
|
+
hook: AfterAgentHandler<NormalizedSchemaInput<TSchema>, TContext>;
|
|
145
147
|
canJumpTo?: JumpToTarget[];
|
|
146
148
|
};
|
|
147
149
|
/**
|