langchain 1.0.5 → 1.1.0

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.
Files changed (216) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +1 -1
  3. package/chat_models/universal.cjs +1 -0
  4. package/chat_models/universal.d.cts +1 -0
  5. package/chat_models/universal.d.ts +1 -0
  6. package/chat_models/universal.js +1 -0
  7. package/dist/agents/ReactAgent.cjs +43 -39
  8. package/dist/agents/ReactAgent.cjs.map +1 -1
  9. package/dist/agents/ReactAgent.js +46 -42
  10. package/dist/agents/ReactAgent.js.map +1 -1
  11. package/dist/agents/index.d.cts +0 -2
  12. package/dist/agents/index.d.ts +0 -2
  13. package/dist/agents/middleware/constants.cjs +16 -0
  14. package/dist/agents/middleware/constants.cjs.map +1 -0
  15. package/dist/agents/middleware/constants.js +15 -0
  16. package/dist/agents/middleware/constants.js.map +1 -0
  17. package/dist/agents/middleware/contextEditing.cjs.map +1 -1
  18. package/dist/agents/middleware/contextEditing.d.cts +23 -7
  19. package/dist/agents/middleware/contextEditing.d.ts +23 -7
  20. package/dist/agents/middleware/contextEditing.js.map +1 -1
  21. package/dist/agents/middleware/dynamicSystemPrompt.cjs +5 -2
  22. package/dist/agents/middleware/dynamicSystemPrompt.cjs.map +1 -1
  23. package/dist/agents/middleware/dynamicSystemPrompt.d.cts +2 -1
  24. package/dist/agents/middleware/dynamicSystemPrompt.d.ts +2 -1
  25. package/dist/agents/middleware/dynamicSystemPrompt.js +4 -2
  26. package/dist/agents/middleware/dynamicSystemPrompt.js.map +1 -1
  27. package/dist/agents/middleware/error.cjs +20 -0
  28. package/dist/agents/middleware/error.cjs.map +1 -0
  29. package/dist/agents/middleware/error.js +19 -0
  30. package/dist/agents/middleware/error.js.map +1 -0
  31. package/dist/agents/middleware/index.cjs +4 -2
  32. package/dist/agents/middleware/index.d.ts +18 -0
  33. package/dist/agents/middleware/index.js +4 -2
  34. package/dist/agents/middleware/modelRetry.cjs +162 -0
  35. package/dist/agents/middleware/modelRetry.cjs.map +1 -0
  36. package/dist/agents/middleware/modelRetry.d.cts +134 -0
  37. package/dist/agents/middleware/modelRetry.d.ts +134 -0
  38. package/dist/agents/middleware/modelRetry.js +161 -0
  39. package/dist/agents/middleware/modelRetry.js.map +1 -0
  40. package/dist/agents/middleware/{promptCaching.cjs → provider/anthropic/promptCaching.cjs} +3 -3
  41. package/dist/agents/middleware/provider/anthropic/promptCaching.cjs.map +1 -0
  42. package/dist/agents/middleware/{promptCaching.d.cts → provider/anthropic/promptCaching.d.cts} +2 -2
  43. package/dist/agents/middleware/{promptCaching.d.ts → provider/anthropic/promptCaching.d.ts} +2 -2
  44. package/dist/agents/middleware/{promptCaching.js → provider/anthropic/promptCaching.js} +2 -2
  45. package/dist/agents/middleware/provider/anthropic/promptCaching.js.map +1 -0
  46. package/dist/agents/middleware/provider/openai/moderation.cjs +299 -0
  47. package/dist/agents/middleware/provider/openai/moderation.cjs.map +1 -0
  48. package/dist/agents/middleware/provider/openai/moderation.d.cts +133 -0
  49. package/dist/agents/middleware/provider/openai/moderation.d.ts +133 -0
  50. package/dist/agents/middleware/provider/openai/moderation.js +298 -0
  51. package/dist/agents/middleware/provider/openai/moderation.js.map +1 -0
  52. package/dist/agents/middleware/summarization.d.cts +0 -4
  53. package/dist/agents/middleware/summarization.d.ts +0 -4
  54. package/dist/agents/middleware/todoListMiddleware.cjs +1 -1
  55. package/dist/agents/middleware/todoListMiddleware.cjs.map +1 -1
  56. package/dist/agents/middleware/todoListMiddleware.js +1 -1
  57. package/dist/agents/middleware/todoListMiddleware.js.map +1 -1
  58. package/dist/agents/middleware/toolRetry.cjs +32 -44
  59. package/dist/agents/middleware/toolRetry.cjs.map +1 -1
  60. package/dist/agents/middleware/toolRetry.d.cts +16 -36
  61. package/dist/agents/middleware/toolRetry.d.ts +16 -36
  62. package/dist/agents/middleware/toolRetry.js +32 -44
  63. package/dist/agents/middleware/toolRetry.js.map +1 -1
  64. package/dist/agents/middleware/types.d.cts +9 -10
  65. package/dist/agents/middleware/types.d.ts +9 -10
  66. package/dist/agents/middleware/utils.cjs +23 -0
  67. package/dist/agents/middleware/utils.cjs.map +1 -1
  68. package/dist/agents/middleware/utils.d.ts +2 -0
  69. package/dist/agents/middleware/utils.js +23 -1
  70. package/dist/agents/middleware/utils.js.map +1 -1
  71. package/dist/agents/nodes/AgentNode.cjs +72 -28
  72. package/dist/agents/nodes/AgentNode.cjs.map +1 -1
  73. package/dist/agents/nodes/AgentNode.js +74 -31
  74. package/dist/agents/nodes/AgentNode.js.map +1 -1
  75. package/dist/agents/nodes/ToolNode.cjs +5 -0
  76. package/dist/agents/nodes/ToolNode.cjs.map +1 -1
  77. package/dist/agents/nodes/ToolNode.js +5 -1
  78. package/dist/agents/nodes/ToolNode.js.map +1 -1
  79. package/dist/agents/nodes/types.d.cts +39 -3
  80. package/dist/agents/nodes/types.d.ts +39 -3
  81. package/dist/agents/responses.cjs.map +1 -1
  82. package/dist/agents/responses.d.cts +2 -19
  83. package/dist/agents/responses.d.ts +2 -19
  84. package/dist/agents/responses.js.map +1 -1
  85. package/dist/agents/runtime.d.ts +1 -0
  86. package/dist/agents/tests/utils.cjs +10 -1
  87. package/dist/agents/tests/utils.cjs.map +1 -1
  88. package/dist/agents/tests/utils.js +10 -1
  89. package/dist/agents/tests/utils.js.map +1 -1
  90. package/dist/agents/types.d.cts +68 -2
  91. package/dist/agents/types.d.ts +68 -2
  92. package/dist/agents/utils.cjs +15 -12
  93. package/dist/agents/utils.cjs.map +1 -1
  94. package/dist/agents/utils.js +16 -13
  95. package/dist/agents/utils.js.map +1 -1
  96. package/dist/chat_models/universal.cjs +50 -16
  97. package/dist/chat_models/universal.cjs.map +1 -1
  98. package/dist/chat_models/universal.d.cts +19 -1
  99. package/dist/chat_models/universal.d.ts +19 -1
  100. package/dist/chat_models/universal.js +50 -16
  101. package/dist/chat_models/universal.js.map +1 -1
  102. package/dist/index.cjs +8 -2
  103. package/dist/index.d.cts +5 -3
  104. package/dist/index.d.ts +6 -3
  105. package/dist/index.js +7 -3
  106. package/dist/load/import_constants.cjs +2 -1
  107. package/dist/load/import_constants.cjs.map +1 -1
  108. package/dist/load/import_constants.js +2 -1
  109. package/dist/load/import_constants.js.map +1 -1
  110. package/dist/load/import_map.cjs +2 -19
  111. package/dist/load/import_map.cjs.map +1 -1
  112. package/dist/load/import_map.js +2 -19
  113. package/dist/load/import_map.js.map +1 -1
  114. package/hub/node.cjs +1 -0
  115. package/hub/node.d.cts +1 -0
  116. package/hub/node.d.ts +1 -0
  117. package/hub/node.js +1 -0
  118. package/hub.cjs +1 -0
  119. package/hub.d.cts +1 -0
  120. package/hub.d.ts +1 -0
  121. package/hub.js +1 -0
  122. package/load/serializable.cjs +1 -0
  123. package/load/serializable.d.cts +1 -0
  124. package/load/serializable.d.ts +1 -0
  125. package/load/serializable.js +1 -0
  126. package/load.cjs +1 -0
  127. package/load.d.cts +1 -0
  128. package/load.d.ts +1 -0
  129. package/load.js +1 -0
  130. package/package.json +65 -52
  131. package/storage/encoder_backed.cjs +1 -0
  132. package/storage/encoder_backed.d.cts +1 -0
  133. package/storage/encoder_backed.d.ts +1 -0
  134. package/storage/encoder_backed.js +1 -0
  135. package/storage/file_system.cjs +1 -0
  136. package/storage/file_system.d.cts +1 -0
  137. package/storage/file_system.d.ts +1 -0
  138. package/storage/file_system.js +1 -0
  139. package/storage/in_memory.cjs +1 -0
  140. package/storage/in_memory.d.cts +1 -0
  141. package/storage/in_memory.d.ts +1 -0
  142. package/storage/in_memory.js +1 -0
  143. package/dist/agents/ReactAgent.d.cts.map +0 -1
  144. package/dist/agents/ReactAgent.d.ts.map +0 -1
  145. package/dist/agents/constants.cjs +0 -7
  146. package/dist/agents/constants.cjs.map +0 -1
  147. package/dist/agents/constants.d.cts.map +0 -1
  148. package/dist/agents/constants.d.ts.map +0 -1
  149. package/dist/agents/constants.js +0 -6
  150. package/dist/agents/constants.js.map +0 -1
  151. package/dist/agents/errors.d.cts.map +0 -1
  152. package/dist/agents/errors.d.ts.map +0 -1
  153. package/dist/agents/index.d.cts.map +0 -1
  154. package/dist/agents/index.d.ts.map +0 -1
  155. package/dist/agents/middleware/contextEditing.d.cts.map +0 -1
  156. package/dist/agents/middleware/contextEditing.d.ts.map +0 -1
  157. package/dist/agents/middleware/dynamicSystemPrompt.d.cts.map +0 -1
  158. package/dist/agents/middleware/dynamicSystemPrompt.d.ts.map +0 -1
  159. package/dist/agents/middleware/hitl.d.cts.map +0 -1
  160. package/dist/agents/middleware/hitl.d.ts.map +0 -1
  161. package/dist/agents/middleware/llmToolSelector.d.cts.map +0 -1
  162. package/dist/agents/middleware/llmToolSelector.d.ts.map +0 -1
  163. package/dist/agents/middleware/modelCallLimit.d.cts.map +0 -1
  164. package/dist/agents/middleware/modelCallLimit.d.ts.map +0 -1
  165. package/dist/agents/middleware/modelFallback.d.cts.map +0 -1
  166. package/dist/agents/middleware/modelFallback.d.ts.map +0 -1
  167. package/dist/agents/middleware/pii.d.cts.map +0 -1
  168. package/dist/agents/middleware/pii.d.ts.map +0 -1
  169. package/dist/agents/middleware/piiRedaction.d.cts.map +0 -1
  170. package/dist/agents/middleware/piiRedaction.d.ts.map +0 -1
  171. package/dist/agents/middleware/promptCaching.cjs.map +0 -1
  172. package/dist/agents/middleware/promptCaching.d.cts.map +0 -1
  173. package/dist/agents/middleware/promptCaching.d.ts.map +0 -1
  174. package/dist/agents/middleware/promptCaching.js.map +0 -1
  175. package/dist/agents/middleware/summarization.d.cts.map +0 -1
  176. package/dist/agents/middleware/summarization.d.ts.map +0 -1
  177. package/dist/agents/middleware/todoListMiddleware.d.cts.map +0 -1
  178. package/dist/agents/middleware/todoListMiddleware.d.ts.map +0 -1
  179. package/dist/agents/middleware/toolCallLimit.d.cts.map +0 -1
  180. package/dist/agents/middleware/toolCallLimit.d.ts.map +0 -1
  181. package/dist/agents/middleware/toolEmulator.d.cts.map +0 -1
  182. package/dist/agents/middleware/toolEmulator.d.ts.map +0 -1
  183. package/dist/agents/middleware/toolRetry.d.cts.map +0 -1
  184. package/dist/agents/middleware/toolRetry.d.ts.map +0 -1
  185. package/dist/agents/middleware/types.d.cts.map +0 -1
  186. package/dist/agents/middleware/types.d.ts.map +0 -1
  187. package/dist/agents/middleware/utils.d.cts.map +0 -1
  188. package/dist/agents/middleware/utils.d.ts.map +0 -1
  189. package/dist/agents/middleware.d.cts.map +0 -1
  190. package/dist/agents/middleware.d.ts.map +0 -1
  191. package/dist/agents/nodes/types.d.cts.map +0 -1
  192. package/dist/agents/nodes/types.d.ts.map +0 -1
  193. package/dist/agents/responses.d.cts.map +0 -1
  194. package/dist/agents/responses.d.ts.map +0 -1
  195. package/dist/agents/runtime.d.cts.map +0 -1
  196. package/dist/agents/runtime.d.ts.map +0 -1
  197. package/dist/agents/tests/utils.d.cts.map +0 -1
  198. package/dist/agents/tests/utils.d.ts.map +0 -1
  199. package/dist/agents/types.d.cts.map +0 -1
  200. package/dist/agents/types.d.ts.map +0 -1
  201. package/dist/chat_models/universal.d.cts.map +0 -1
  202. package/dist/chat_models/universal.d.ts.map +0 -1
  203. package/dist/hub/base.d.cts.map +0 -1
  204. package/dist/hub/base.d.ts.map +0 -1
  205. package/dist/hub/index.d.cts.map +0 -1
  206. package/dist/hub/index.d.ts.map +0 -1
  207. package/dist/hub/node.d.cts.map +0 -1
  208. package/dist/hub/node.d.ts.map +0 -1
  209. package/dist/load/import_type.d.cts.map +0 -1
  210. package/dist/load/import_type.d.ts.map +0 -1
  211. package/dist/load/index.d.cts.map +0 -1
  212. package/dist/load/index.d.ts.map +0 -1
  213. package/dist/storage/encoder_backed.d.cts.map +0 -1
  214. package/dist/storage/encoder_backed.d.ts.map +0 -1
  215. package/dist/storage/file_system.d.cts.map +0 -1
  216. package/dist/storage/file_system.d.ts.map +0 -1
@@ -1,7 +1,6 @@
1
1
  const require_utils = require('./utils.cjs');
2
- const require_summarization = require('./summarization.cjs');
3
2
  const require_hitl = require('./hitl.cjs');
4
- const require_promptCaching = require('./promptCaching.cjs');
3
+ const require_summarization = require('./summarization.cjs');
5
4
  const require_dynamicSystemPrompt = require('./dynamicSystemPrompt.cjs');
6
5
  const require_llmToolSelector = require('./llmToolSelector.cjs');
7
6
  const require_pii = require('./pii.cjs');
@@ -11,5 +10,8 @@ const require_toolCallLimit = require('./toolCallLimit.cjs');
11
10
  const require_todoListMiddleware = require('./todoListMiddleware.cjs');
12
11
  const require_modelCallLimit = require('./modelCallLimit.cjs');
13
12
  const require_modelFallback = require('./modelFallback.cjs');
13
+ const require_modelRetry = require('./modelRetry.cjs');
14
14
  const require_toolRetry = require('./toolRetry.cjs');
15
15
  const require_toolEmulator = require('./toolEmulator.cjs');
16
+ const require_moderation = require('./provider/openai/moderation.cjs');
17
+ const require_promptCaching = require('./provider/anthropic/promptCaching.cjs');
@@ -0,0 +1,18 @@
1
+ import { AgentMiddleware } from "./types.js";
2
+ import { Action, ActionRequest, ApproveDecision, Decision, DecisionType, DescriptionFactory, EditDecision, HITLRequest, HITLResponse, HumanInTheLoopMiddlewareConfig, InterruptOnConfig, RejectDecision, ReviewConfig, humanInTheLoopMiddleware } from "./hitl.js";
3
+ import { SummarizationMiddlewareConfig, TokenCounter, summarizationMiddleware } from "./summarization.js";
4
+ import { DynamicSystemPromptMiddlewareConfig, dynamicSystemPromptMiddleware } from "./dynamicSystemPrompt.js";
5
+ import { LLMToolSelectorConfig, llmToolSelectorMiddleware } from "./llmToolSelector.js";
6
+ import { BuiltInPIIType, PIIDetectionError, PIIDetector, PIIMatch, PIIMiddlewareConfig, PIIStrategy, RedactionRuleConfig, ResolvedRedactionRule, applyStrategy, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, piiMiddleware, resolveRedactionRule } from "./pii.js";
7
+ import { PIIRedactionMiddlewareConfig, piiRedactionMiddleware } from "./piiRedaction.js";
8
+ import { ClearToolUsesEdit, ClearToolUsesEditConfig, ContextEdit, ContextEditingMiddlewareConfig, contextEditingMiddleware } from "./contextEditing.js";
9
+ import { ToolCallLimitConfig, ToolCallLimitExceededError, toolCallLimitMiddleware } from "./toolCallLimit.js";
10
+ import { TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, TodoListMiddlewareOptions, todoListMiddleware } from "./todoListMiddleware.js";
11
+ import { ModelCallLimitMiddlewareConfig, modelCallLimitMiddleware } from "./modelCallLimit.js";
12
+ import { modelFallbackMiddleware } from "./modelFallback.js";
13
+ import { ModelRetryMiddlewareConfig, modelRetryMiddleware } from "./modelRetry.js";
14
+ import { ToolRetryMiddlewareConfig, toolRetryMiddleware } from "./toolRetry.js";
15
+ import { ToolEmulatorOptions, toolEmulatorMiddleware } from "./toolEmulator.js";
16
+ import { OpenAIModerationMiddlewareOptions, openAIModerationMiddleware } from "./provider/openai/moderation.js";
17
+ import { PromptCachingMiddlewareConfig, anthropicPromptCachingMiddleware } from "./provider/anthropic/promptCaching.js";
18
+ import { countTokensApproximately } from "./utils.js";
@@ -1,7 +1,6 @@
1
1
  import { countTokensApproximately } from "./utils.js";
2
- import { summarizationMiddleware } from "./summarization.js";
3
2
  import { humanInTheLoopMiddleware } from "./hitl.js";
4
- import { anthropicPromptCachingMiddleware } from "./promptCaching.js";
3
+ import { summarizationMiddleware } from "./summarization.js";
5
4
  import { dynamicSystemPromptMiddleware } from "./dynamicSystemPrompt.js";
6
5
  import { llmToolSelectorMiddleware } from "./llmToolSelector.js";
7
6
  import { PIIDetectionError, applyStrategy, detectCreditCard, detectEmail, detectIP, detectMacAddress, detectUrl, piiMiddleware, resolveRedactionRule } from "./pii.js";
@@ -11,5 +10,8 @@ import { ToolCallLimitExceededError, toolCallLimitMiddleware } from "./toolCallL
11
10
  import { TODO_LIST_MIDDLEWARE_SYSTEM_PROMPT, todoListMiddleware } from "./todoListMiddleware.js";
12
11
  import { modelCallLimitMiddleware } from "./modelCallLimit.js";
13
12
  import { modelFallbackMiddleware } from "./modelFallback.js";
13
+ import { modelRetryMiddleware } from "./modelRetry.js";
14
14
  import { toolRetryMiddleware } from "./toolRetry.js";
15
15
  import { toolEmulatorMiddleware } from "./toolEmulator.js";
16
+ import { openAIModerationMiddleware } from "./provider/openai/moderation.js";
17
+ import { anthropicPromptCachingMiddleware } from "./provider/anthropic/promptCaching.js";
@@ -0,0 +1,162 @@
1
+ const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
+ const require_utils = require('./utils.cjs');
3
+ const require_middleware = require('../middleware.cjs');
4
+ const require_constants = require('./constants.cjs');
5
+ const require_error = require('./error.cjs');
6
+ const __langchain_core_messages = require_rolldown_runtime.__toESM(require("@langchain/core/messages"));
7
+ const zod_v3 = require_rolldown_runtime.__toESM(require("zod/v3"));
8
+
9
+ //#region src/agents/middleware/modelRetry.ts
10
+ /**
11
+ * Configuration options for the Model Retry Middleware.
12
+ */
13
+ const ModelRetryMiddlewareOptionsSchema = zod_v3.z.object({ onFailure: zod_v3.z.union([
14
+ zod_v3.z.literal("error"),
15
+ zod_v3.z.literal("continue"),
16
+ zod_v3.z.function().args(zod_v3.z.instanceof(Error)).returns(zod_v3.z.string())
17
+ ]).default("continue") }).merge(require_constants.RetrySchema);
18
+ /**
19
+ * Middleware that automatically retries failed model calls with configurable backoff.
20
+ *
21
+ * Supports retrying on specific exceptions and exponential backoff.
22
+ *
23
+ * @example Basic usage with default settings (2 retries, exponential backoff)
24
+ * ```ts
25
+ * import { createAgent, modelRetryMiddleware } from "langchain";
26
+ *
27
+ * const agent = createAgent({
28
+ * model: "openai:gpt-4o",
29
+ * tools: [searchTool],
30
+ * middleware: [modelRetryMiddleware()],
31
+ * });
32
+ * ```
33
+ *
34
+ * @example Retry specific exceptions only
35
+ * ```ts
36
+ * import { modelRetryMiddleware } from "langchain";
37
+ *
38
+ * const retry = modelRetryMiddleware({
39
+ * maxRetries: 4,
40
+ * retryOn: [TimeoutError, NetworkError],
41
+ * backoffFactor: 1.5,
42
+ * });
43
+ * ```
44
+ *
45
+ * @example Custom exception filtering
46
+ * ```ts
47
+ * function shouldRetry(error: Error): boolean {
48
+ * // Only retry on rate limit errors
49
+ * if (error.name === "RateLimitError") {
50
+ * return true;
51
+ * }
52
+ * // Or check for specific HTTP status codes
53
+ * if (error.name === "HTTPError" && "statusCode" in error) {
54
+ * const statusCode = (error as any).statusCode;
55
+ * return statusCode === 429 || statusCode === 503;
56
+ * }
57
+ * return false;
58
+ * }
59
+ *
60
+ * const retry = modelRetryMiddleware({
61
+ * maxRetries: 3,
62
+ * retryOn: shouldRetry,
63
+ * });
64
+ * ```
65
+ *
66
+ * @example Return error message instead of raising
67
+ * ```ts
68
+ * const retry = modelRetryMiddleware({
69
+ * maxRetries: 4,
70
+ * onFailure: "continue", // Return AIMessage with error instead of throwing
71
+ * });
72
+ * ```
73
+ *
74
+ * @example Custom error message formatting
75
+ * ```ts
76
+ * const formatError = (error: Error) =>
77
+ * `Model call failed: ${error.message}. Please try again later.`;
78
+ *
79
+ * const retry = modelRetryMiddleware({
80
+ * maxRetries: 4,
81
+ * onFailure: formatError,
82
+ * });
83
+ * ```
84
+ *
85
+ * @example Constant backoff (no exponential growth)
86
+ * ```ts
87
+ * const retry = modelRetryMiddleware({
88
+ * maxRetries: 5,
89
+ * backoffFactor: 0.0, // No exponential growth
90
+ * initialDelayMs: 2000, // Always wait 2 seconds
91
+ * });
92
+ * ```
93
+ *
94
+ * @example Raise exception on failure
95
+ * ```ts
96
+ * const retry = modelRetryMiddleware({
97
+ * maxRetries: 2,
98
+ * onFailure: "error", // Re-raise exception instead of returning message
99
+ * });
100
+ * ```
101
+ *
102
+ * @param config - Configuration options for the retry middleware
103
+ * @returns A middleware instance that handles model failures with retries
104
+ */
105
+ function modelRetryMiddleware(config = {}) {
106
+ const { success, error, data } = ModelRetryMiddlewareOptionsSchema.safeParse(config);
107
+ if (!success) throw new require_error.InvalidRetryConfigError(error);
108
+ const { maxRetries, retryOn, onFailure, backoffFactor, initialDelayMs, maxDelayMs, jitter } = data;
109
+ /**
110
+ * Check if the exception should trigger a retry.
111
+ */
112
+ const shouldRetryException = (error$1) => {
113
+ if (typeof retryOn === "function") return retryOn(error$1);
114
+ return retryOn.some((ErrorConstructor) => error$1.constructor === ErrorConstructor);
115
+ };
116
+ const delayConfig = {
117
+ backoffFactor,
118
+ initialDelayMs,
119
+ maxDelayMs,
120
+ jitter
121
+ };
122
+ /**
123
+ * Format the failure message when retries are exhausted.
124
+ */
125
+ const formatFailureMessage = (error$1, attemptsMade) => {
126
+ const errorType = error$1.constructor.name;
127
+ const attemptWord = attemptsMade === 1 ? "attempt" : "attempts";
128
+ return `Model call failed after ${attemptsMade} ${attemptWord} with ${errorType}: ${error$1.message}`;
129
+ };
130
+ /**
131
+ * Handle failure when all retries are exhausted.
132
+ */
133
+ const handleFailure = (error$1, attemptsMade) => {
134
+ if (onFailure === "error") throw error$1;
135
+ let content;
136
+ if (typeof onFailure === "function") content = onFailure(error$1);
137
+ else content = formatFailureMessage(error$1, attemptsMade);
138
+ return new __langchain_core_messages.AIMessage({ content });
139
+ };
140
+ return require_middleware.createMiddleware({
141
+ name: "modelRetryMiddleware",
142
+ contextSchema: ModelRetryMiddlewareOptionsSchema,
143
+ wrapModelCall: async (request, handler) => {
144
+ for (let attempt = 0; attempt <= maxRetries; attempt++) try {
145
+ return await handler(request);
146
+ } catch (error$1) {
147
+ const attemptsMade = attempt + 1;
148
+ const err = error$1 && typeof error$1 === "object" && "message" in error$1 ? error$1 : new Error(String(error$1));
149
+ if (!shouldRetryException(err)) return handleFailure(err, attemptsMade);
150
+ if (attempt < maxRetries) {
151
+ const delay = require_utils.calculateRetryDelay(delayConfig, attempt);
152
+ if (delay > 0) await require_utils.sleep(delay);
153
+ } else return handleFailure(err, attemptsMade);
154
+ }
155
+ throw new Error("Unexpected: retry loop completed without returning");
156
+ }
157
+ });
158
+ }
159
+
160
+ //#endregion
161
+ exports.modelRetryMiddleware = modelRetryMiddleware;
162
+ //# sourceMappingURL=modelRetry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelRetry.cjs","names":["z","RetrySchema","config: ModelRetryMiddlewareConfig","InvalidRetryConfigError","error: Error","error","attemptsMade: number","content: string","AIMessage","createMiddleware","calculateRetryDelay","sleep"],"sources":["../../../src/agents/middleware/modelRetry.ts"],"sourcesContent":["/**\n * Model retry middleware for agents.\n */\nimport { z } from \"zod/v3\";\nimport { AIMessage } from \"@langchain/core/messages\";\n\nimport { createMiddleware } from \"../middleware.js\";\nimport type { AgentMiddleware } from \"./types.js\";\nimport { sleep, calculateRetryDelay } from \"./utils.js\";\nimport { RetrySchema } from \"./constants.js\";\nimport { InvalidRetryConfigError } from \"./error.js\";\n\n/**\n * Configuration options for the Model Retry Middleware.\n */\nexport const ModelRetryMiddlewareOptionsSchema = z\n .object({\n /**\n * Behavior when all retries are exhausted. Options:\n * - `\"continue\"` (default): Return an AIMessage with error details, allowing\n * the agent to potentially handle the failure gracefully.\n * - `\"error\"`: Re-raise the exception, stopping agent execution.\n * - Custom function: Function that takes the exception and returns a string\n * for the AIMessage content, allowing custom error formatting.\n */\n onFailure: z\n .union([\n z.literal(\"error\"),\n z.literal(\"continue\"),\n z.function().args(z.instanceof(Error)).returns(z.string()),\n ])\n .default(\"continue\"),\n })\n .merge(RetrySchema);\n\nexport type ModelRetryMiddlewareConfig = z.input<\n typeof ModelRetryMiddlewareOptionsSchema\n>;\n\n/**\n * Middleware that automatically retries failed model 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, modelRetryMiddleware } from \"langchain\";\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [searchTool],\n * middleware: [modelRetryMiddleware()],\n * });\n * ```\n *\n * @example Retry specific exceptions only\n * ```ts\n * import { modelRetryMiddleware } from \"langchain\";\n *\n * const retry = modelRetryMiddleware({\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 rate limit errors\n * if (error.name === \"RateLimitError\") {\n * return true;\n * }\n * // Or check for specific HTTP status codes\n * if (error.name === \"HTTPError\" && \"statusCode\" in error) {\n * const statusCode = (error as any).statusCode;\n * return statusCode === 429 || statusCode === 503;\n * }\n * return false;\n * }\n *\n * const retry = modelRetryMiddleware({\n * maxRetries: 3,\n * retryOn: shouldRetry,\n * });\n * ```\n *\n * @example Return error message instead of raising\n * ```ts\n * const retry = modelRetryMiddleware({\n * maxRetries: 4,\n * onFailure: \"continue\", // Return AIMessage with error instead of throwing\n * });\n * ```\n *\n * @example Custom error message formatting\n * ```ts\n * const formatError = (error: Error) =>\n * `Model call failed: ${error.message}. Please try again later.`;\n *\n * const retry = modelRetryMiddleware({\n * maxRetries: 4,\n * onFailure: formatError,\n * });\n * ```\n *\n * @example Constant backoff (no exponential growth)\n * ```ts\n * const retry = modelRetryMiddleware({\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 = modelRetryMiddleware({\n * maxRetries: 2,\n * onFailure: \"error\", // 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 model failures with retries\n */\nexport function modelRetryMiddleware(\n config: ModelRetryMiddlewareConfig = {}\n): AgentMiddleware {\n const { success, error, data } =\n ModelRetryMiddlewareOptionsSchema.safeParse(config);\n if (!success) {\n throw new InvalidRetryConfigError(error);\n }\n const {\n maxRetries,\n retryOn,\n onFailure,\n backoffFactor,\n initialDelayMs,\n maxDelayMs,\n jitter,\n } = data;\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 = (error: Error, attemptsMade: number): string => {\n const errorType = error.constructor.name;\n const attemptWord = attemptsMade === 1 ? \"attempt\" : \"attempts\";\n return `Model call failed after ${attemptsMade} ${attemptWord} with ${errorType}: ${error.message}`;\n };\n\n /**\n * Handle failure when all retries are exhausted.\n */\n const handleFailure = (error: Error, attemptsMade: number): AIMessage => {\n if (onFailure === \"error\") {\n throw error;\n }\n\n let content: string;\n if (typeof onFailure === \"function\") {\n content = onFailure(error);\n } else {\n content = formatFailureMessage(error, attemptsMade);\n }\n\n return new AIMessage({\n content,\n });\n };\n\n return createMiddleware({\n name: \"modelRetryMiddleware\",\n contextSchema: ModelRetryMiddlewareOptionsSchema,\n wrapModelCall: async (request, handler) => {\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(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(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":";;;;;;;;;;;;AAeA,MAAa,oCAAoCA,SAC9C,OAAO,EASN,WAAWA,SACR,MAAM;CACLA,SAAE,QAAQ,QAAQ;CAClBA,SAAE,QAAQ,WAAW;CACrBA,SAAE,UAAU,CAAC,KAAKA,SAAE,WAAW,MAAM,CAAC,CAAC,QAAQA,SAAE,QAAQ,CAAC;AAC3D,EAAC,CACD,QAAQ,WAAW,CACvB,EAAC,CACD,MAAMC,8BAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6FrB,SAAgB,qBACdC,SAAqC,CAAE,GACtB;CACjB,MAAM,EAAE,SAAS,OAAO,MAAM,GAC5B,kCAAkC,UAAU,OAAO;AACrD,KAAI,CAAC,QACH,OAAM,IAAIC,sCAAwB;CAEpC,MAAM,EACJ,YACA,SACA,WACA,eACA,gBACA,YACA,QACD,GAAG;;;;CAKJ,MAAM,uBAAuB,CAACC,YAA0B;AACtD,MAAI,OAAO,YAAY,WACrB,QAAO,QAAQC,QAAM;AAGvB,SAAO,QAAQ,KACb,CAAC,qBAAqBA,QAAM,gBAAgB,iBAC7C;CACF;CAGD,MAAM,cAAc;EAAE;EAAe;EAAgB;EAAY;CAAQ;;;;CAKzE,MAAM,uBAAuB,CAACD,SAAcE,iBAAiC;EAC3E,MAAM,YAAYD,QAAM,YAAY;EACpC,MAAM,cAAc,iBAAiB,IAAI,YAAY;AACrD,SAAO,CAAC,wBAAwB,EAAE,aAAa,CAAC,EAAE,YAAY,MAAM,EAAE,UAAU,EAAE,EAAEA,QAAM,SAAS;CACpG;;;;CAKD,MAAM,gBAAgB,CAACD,SAAcE,iBAAoC;AACvE,MAAI,cAAc,QAChB,OAAMD;EAGR,IAAIE;AACJ,MAAI,OAAO,cAAc,YACvB,UAAU,UAAUF,QAAM;OAE1B,UAAU,qBAAqBA,SAAO,aAAa;AAGrD,SAAO,IAAIG,oCAAU,EACnB,QACD;CACF;AAED,QAAOC,oCAAiB;EACtB,MAAM;EACN,eAAe;EACf,eAAe,OAAO,SAAS,YAAY;AAEzC,QAAK,IAAI,UAAU,GAAG,WAAW,YAAY,UAC3C,KAAI;AACF,WAAO,MAAM,QAAQ,QAAQ;GAC9B,SAAQJ,SAAO;IACd,MAAM,eAAe,UAAU;IAG/B,MAAM,MACJA,WAAS,OAAOA,YAAU,YAAY,aAAaA,UAC9CA,UACD,IAAI,MAAM,OAAOA,QAAM;AAG7B,QAAI,CAAC,qBAAqB,IAAI,CAE5B,QAAO,cAAc,KAAK,aAAa;AAIzC,QAAI,UAAU,YAAY;KAExB,MAAM,QAAQK,kCAAoB,aAAa,QAAQ;AACvD,SAAI,QAAQ,GACV,MAAMC,oBAAM,MAAM;IAGrB,MAEC,QAAO,cAAc,KAAK,aAAa;GAE1C;AAIH,SAAM,IAAI,MAAM;EACjB;CACF,EAAC;AACH"}
@@ -0,0 +1,134 @@
1
+ import { AgentMiddleware } from "./types.cjs";
2
+ import { z } from "zod/v3";
3
+
4
+ //#region src/agents/middleware/modelRetry.d.ts
5
+
6
+ /**
7
+ * Configuration options for the Model Retry Middleware.
8
+ */
9
+ declare const ModelRetryMiddlewareOptionsSchema: z.ZodObject<{
10
+ /**
11
+ * Behavior when all retries are exhausted. Options:
12
+ * - `"continue"` (default): Return an AIMessage with error details, allowing
13
+ * the agent to potentially handle the failure gracefully.
14
+ * - `"error"`: Re-raise the exception, stopping agent execution.
15
+ * - Custom function: Function that takes the exception and returns a string
16
+ * for the AIMessage content, allowing custom error formatting.
17
+ */
18
+ onFailure: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"error">, z.ZodLiteral<"continue">, z.ZodFunction<z.ZodTuple<[z.ZodType<Error, z.ZodTypeDef, Error>], z.ZodUnknown>, z.ZodString>]>>;
19
+ } & {
20
+ maxRetries: z.ZodDefault<z.ZodNumber>;
21
+ 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">]>>;
22
+ backoffFactor: z.ZodDefault<z.ZodNumber>;
23
+ initialDelayMs: z.ZodDefault<z.ZodNumber>;
24
+ maxDelayMs: z.ZodDefault<z.ZodNumber>;
25
+ jitter: z.ZodDefault<z.ZodBoolean>;
26
+ }, "strip", z.ZodTypeAny, {
27
+ maxRetries: number;
28
+ retryOn: (new (...args: any[]) => Error)[] | ((args_0: Error, ...args: unknown[]) => boolean);
29
+ backoffFactor: number;
30
+ initialDelayMs: number;
31
+ maxDelayMs: number;
32
+ jitter: boolean;
33
+ onFailure: "continue" | "error" | ((args_0: Error, ...args: unknown[]) => string);
34
+ }, {
35
+ maxRetries?: number | undefined;
36
+ retryOn?: (new (...args: any[]) => Error)[] | ((args_0: Error, ...args: unknown[]) => boolean) | undefined;
37
+ backoffFactor?: number | undefined;
38
+ initialDelayMs?: number | undefined;
39
+ maxDelayMs?: number | undefined;
40
+ jitter?: boolean | undefined;
41
+ onFailure?: "continue" | "error" | ((args_0: Error, ...args: unknown[]) => string) | undefined;
42
+ }>;
43
+ type ModelRetryMiddlewareConfig = z.input<typeof ModelRetryMiddlewareOptionsSchema>;
44
+ /**
45
+ * Middleware that automatically retries failed model calls with configurable backoff.
46
+ *
47
+ * Supports retrying on specific exceptions and exponential backoff.
48
+ *
49
+ * @example Basic usage with default settings (2 retries, exponential backoff)
50
+ * ```ts
51
+ * import { createAgent, modelRetryMiddleware } from "langchain";
52
+ *
53
+ * const agent = createAgent({
54
+ * model: "openai:gpt-4o",
55
+ * tools: [searchTool],
56
+ * middleware: [modelRetryMiddleware()],
57
+ * });
58
+ * ```
59
+ *
60
+ * @example Retry specific exceptions only
61
+ * ```ts
62
+ * import { modelRetryMiddleware } from "langchain";
63
+ *
64
+ * const retry = modelRetryMiddleware({
65
+ * maxRetries: 4,
66
+ * retryOn: [TimeoutError, NetworkError],
67
+ * backoffFactor: 1.5,
68
+ * });
69
+ * ```
70
+ *
71
+ * @example Custom exception filtering
72
+ * ```ts
73
+ * function shouldRetry(error: Error): boolean {
74
+ * // Only retry on rate limit errors
75
+ * if (error.name === "RateLimitError") {
76
+ * return true;
77
+ * }
78
+ * // Or check for specific HTTP status codes
79
+ * if (error.name === "HTTPError" && "statusCode" in error) {
80
+ * const statusCode = (error as any).statusCode;
81
+ * return statusCode === 429 || statusCode === 503;
82
+ * }
83
+ * return false;
84
+ * }
85
+ *
86
+ * const retry = modelRetryMiddleware({
87
+ * maxRetries: 3,
88
+ * retryOn: shouldRetry,
89
+ * });
90
+ * ```
91
+ *
92
+ * @example Return error message instead of raising
93
+ * ```ts
94
+ * const retry = modelRetryMiddleware({
95
+ * maxRetries: 4,
96
+ * onFailure: "continue", // Return AIMessage with error instead of throwing
97
+ * });
98
+ * ```
99
+ *
100
+ * @example Custom error message formatting
101
+ * ```ts
102
+ * const formatError = (error: Error) =>
103
+ * `Model call failed: ${error.message}. Please try again later.`;
104
+ *
105
+ * const retry = modelRetryMiddleware({
106
+ * maxRetries: 4,
107
+ * onFailure: formatError,
108
+ * });
109
+ * ```
110
+ *
111
+ * @example Constant backoff (no exponential growth)
112
+ * ```ts
113
+ * const retry = modelRetryMiddleware({
114
+ * maxRetries: 5,
115
+ * backoffFactor: 0.0, // No exponential growth
116
+ * initialDelayMs: 2000, // Always wait 2 seconds
117
+ * });
118
+ * ```
119
+ *
120
+ * @example Raise exception on failure
121
+ * ```ts
122
+ * const retry = modelRetryMiddleware({
123
+ * maxRetries: 2,
124
+ * onFailure: "error", // Re-raise exception instead of returning message
125
+ * });
126
+ * ```
127
+ *
128
+ * @param config - Configuration options for the retry middleware
129
+ * @returns A middleware instance that handles model failures with retries
130
+ */
131
+ declare function modelRetryMiddleware(config?: ModelRetryMiddlewareConfig): AgentMiddleware;
132
+ //#endregion
133
+ export { ModelRetryMiddlewareConfig, modelRetryMiddleware };
134
+ //# sourceMappingURL=modelRetry.d.cts.map
@@ -0,0 +1,134 @@
1
+ import { AgentMiddleware } from "./types.js";
2
+ import { z } from "zod/v3";
3
+
4
+ //#region src/agents/middleware/modelRetry.d.ts
5
+
6
+ /**
7
+ * Configuration options for the Model Retry Middleware.
8
+ */
9
+ declare const ModelRetryMiddlewareOptionsSchema: z.ZodObject<{
10
+ /**
11
+ * Behavior when all retries are exhausted. Options:
12
+ * - `"continue"` (default): Return an AIMessage with error details, allowing
13
+ * the agent to potentially handle the failure gracefully.
14
+ * - `"error"`: Re-raise the exception, stopping agent execution.
15
+ * - Custom function: Function that takes the exception and returns a string
16
+ * for the AIMessage content, allowing custom error formatting.
17
+ */
18
+ onFailure: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"error">, z.ZodLiteral<"continue">, z.ZodFunction<z.ZodTuple<[z.ZodType<Error, z.ZodTypeDef, Error>], z.ZodUnknown>, z.ZodString>]>>;
19
+ } & {
20
+ maxRetries: z.ZodDefault<z.ZodNumber>;
21
+ 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">]>>;
22
+ backoffFactor: z.ZodDefault<z.ZodNumber>;
23
+ initialDelayMs: z.ZodDefault<z.ZodNumber>;
24
+ maxDelayMs: z.ZodDefault<z.ZodNumber>;
25
+ jitter: z.ZodDefault<z.ZodBoolean>;
26
+ }, "strip", z.ZodTypeAny, {
27
+ maxRetries: number;
28
+ retryOn: (new (...args: any[]) => Error)[] | ((args_0: Error, ...args: unknown[]) => boolean);
29
+ backoffFactor: number;
30
+ initialDelayMs: number;
31
+ maxDelayMs: number;
32
+ jitter: boolean;
33
+ onFailure: "continue" | "error" | ((args_0: Error, ...args: unknown[]) => string);
34
+ }, {
35
+ maxRetries?: number | undefined;
36
+ retryOn?: (new (...args: any[]) => Error)[] | ((args_0: Error, ...args: unknown[]) => boolean) | undefined;
37
+ backoffFactor?: number | undefined;
38
+ initialDelayMs?: number | undefined;
39
+ maxDelayMs?: number | undefined;
40
+ jitter?: boolean | undefined;
41
+ onFailure?: "continue" | "error" | ((args_0: Error, ...args: unknown[]) => string) | undefined;
42
+ }>;
43
+ type ModelRetryMiddlewareConfig = z.input<typeof ModelRetryMiddlewareOptionsSchema>;
44
+ /**
45
+ * Middleware that automatically retries failed model calls with configurable backoff.
46
+ *
47
+ * Supports retrying on specific exceptions and exponential backoff.
48
+ *
49
+ * @example Basic usage with default settings (2 retries, exponential backoff)
50
+ * ```ts
51
+ * import { createAgent, modelRetryMiddleware } from "langchain";
52
+ *
53
+ * const agent = createAgent({
54
+ * model: "openai:gpt-4o",
55
+ * tools: [searchTool],
56
+ * middleware: [modelRetryMiddleware()],
57
+ * });
58
+ * ```
59
+ *
60
+ * @example Retry specific exceptions only
61
+ * ```ts
62
+ * import { modelRetryMiddleware } from "langchain";
63
+ *
64
+ * const retry = modelRetryMiddleware({
65
+ * maxRetries: 4,
66
+ * retryOn: [TimeoutError, NetworkError],
67
+ * backoffFactor: 1.5,
68
+ * });
69
+ * ```
70
+ *
71
+ * @example Custom exception filtering
72
+ * ```ts
73
+ * function shouldRetry(error: Error): boolean {
74
+ * // Only retry on rate limit errors
75
+ * if (error.name === "RateLimitError") {
76
+ * return true;
77
+ * }
78
+ * // Or check for specific HTTP status codes
79
+ * if (error.name === "HTTPError" && "statusCode" in error) {
80
+ * const statusCode = (error as any).statusCode;
81
+ * return statusCode === 429 || statusCode === 503;
82
+ * }
83
+ * return false;
84
+ * }
85
+ *
86
+ * const retry = modelRetryMiddleware({
87
+ * maxRetries: 3,
88
+ * retryOn: shouldRetry,
89
+ * });
90
+ * ```
91
+ *
92
+ * @example Return error message instead of raising
93
+ * ```ts
94
+ * const retry = modelRetryMiddleware({
95
+ * maxRetries: 4,
96
+ * onFailure: "continue", // Return AIMessage with error instead of throwing
97
+ * });
98
+ * ```
99
+ *
100
+ * @example Custom error message formatting
101
+ * ```ts
102
+ * const formatError = (error: Error) =>
103
+ * `Model call failed: ${error.message}. Please try again later.`;
104
+ *
105
+ * const retry = modelRetryMiddleware({
106
+ * maxRetries: 4,
107
+ * onFailure: formatError,
108
+ * });
109
+ * ```
110
+ *
111
+ * @example Constant backoff (no exponential growth)
112
+ * ```ts
113
+ * const retry = modelRetryMiddleware({
114
+ * maxRetries: 5,
115
+ * backoffFactor: 0.0, // No exponential growth
116
+ * initialDelayMs: 2000, // Always wait 2 seconds
117
+ * });
118
+ * ```
119
+ *
120
+ * @example Raise exception on failure
121
+ * ```ts
122
+ * const retry = modelRetryMiddleware({
123
+ * maxRetries: 2,
124
+ * onFailure: "error", // Re-raise exception instead of returning message
125
+ * });
126
+ * ```
127
+ *
128
+ * @param config - Configuration options for the retry middleware
129
+ * @returns A middleware instance that handles model failures with retries
130
+ */
131
+ declare function modelRetryMiddleware(config?: ModelRetryMiddlewareConfig): AgentMiddleware;
132
+ //#endregion
133
+ export { ModelRetryMiddlewareConfig, modelRetryMiddleware };
134
+ //# sourceMappingURL=modelRetry.d.ts.map
@@ -0,0 +1,161 @@
1
+ import { calculateRetryDelay, sleep } from "./utils.js";
2
+ import { createMiddleware } from "../middleware.js";
3
+ import { RetrySchema } from "./constants.js";
4
+ import { InvalidRetryConfigError } from "./error.js";
5
+ import { AIMessage } from "@langchain/core/messages";
6
+ import { z } from "zod/v3";
7
+
8
+ //#region src/agents/middleware/modelRetry.ts
9
+ /**
10
+ * Configuration options for the Model Retry Middleware.
11
+ */
12
+ const ModelRetryMiddlewareOptionsSchema = z.object({ onFailure: z.union([
13
+ z.literal("error"),
14
+ z.literal("continue"),
15
+ z.function().args(z.instanceof(Error)).returns(z.string())
16
+ ]).default("continue") }).merge(RetrySchema);
17
+ /**
18
+ * Middleware that automatically retries failed model calls with configurable backoff.
19
+ *
20
+ * Supports retrying on specific exceptions and exponential backoff.
21
+ *
22
+ * @example Basic usage with default settings (2 retries, exponential backoff)
23
+ * ```ts
24
+ * import { createAgent, modelRetryMiddleware } from "langchain";
25
+ *
26
+ * const agent = createAgent({
27
+ * model: "openai:gpt-4o",
28
+ * tools: [searchTool],
29
+ * middleware: [modelRetryMiddleware()],
30
+ * });
31
+ * ```
32
+ *
33
+ * @example Retry specific exceptions only
34
+ * ```ts
35
+ * import { modelRetryMiddleware } from "langchain";
36
+ *
37
+ * const retry = modelRetryMiddleware({
38
+ * maxRetries: 4,
39
+ * retryOn: [TimeoutError, NetworkError],
40
+ * backoffFactor: 1.5,
41
+ * });
42
+ * ```
43
+ *
44
+ * @example Custom exception filtering
45
+ * ```ts
46
+ * function shouldRetry(error: Error): boolean {
47
+ * // Only retry on rate limit errors
48
+ * if (error.name === "RateLimitError") {
49
+ * return true;
50
+ * }
51
+ * // Or check for specific HTTP status codes
52
+ * if (error.name === "HTTPError" && "statusCode" in error) {
53
+ * const statusCode = (error as any).statusCode;
54
+ * return statusCode === 429 || statusCode === 503;
55
+ * }
56
+ * return false;
57
+ * }
58
+ *
59
+ * const retry = modelRetryMiddleware({
60
+ * maxRetries: 3,
61
+ * retryOn: shouldRetry,
62
+ * });
63
+ * ```
64
+ *
65
+ * @example Return error message instead of raising
66
+ * ```ts
67
+ * const retry = modelRetryMiddleware({
68
+ * maxRetries: 4,
69
+ * onFailure: "continue", // Return AIMessage with error instead of throwing
70
+ * });
71
+ * ```
72
+ *
73
+ * @example Custom error message formatting
74
+ * ```ts
75
+ * const formatError = (error: Error) =>
76
+ * `Model call failed: ${error.message}. Please try again later.`;
77
+ *
78
+ * const retry = modelRetryMiddleware({
79
+ * maxRetries: 4,
80
+ * onFailure: formatError,
81
+ * });
82
+ * ```
83
+ *
84
+ * @example Constant backoff (no exponential growth)
85
+ * ```ts
86
+ * const retry = modelRetryMiddleware({
87
+ * maxRetries: 5,
88
+ * backoffFactor: 0.0, // No exponential growth
89
+ * initialDelayMs: 2000, // Always wait 2 seconds
90
+ * });
91
+ * ```
92
+ *
93
+ * @example Raise exception on failure
94
+ * ```ts
95
+ * const retry = modelRetryMiddleware({
96
+ * maxRetries: 2,
97
+ * onFailure: "error", // Re-raise exception instead of returning message
98
+ * });
99
+ * ```
100
+ *
101
+ * @param config - Configuration options for the retry middleware
102
+ * @returns A middleware instance that handles model failures with retries
103
+ */
104
+ function modelRetryMiddleware(config = {}) {
105
+ const { success, error, data } = ModelRetryMiddlewareOptionsSchema.safeParse(config);
106
+ if (!success) throw new InvalidRetryConfigError(error);
107
+ const { maxRetries, retryOn, onFailure, backoffFactor, initialDelayMs, maxDelayMs, jitter } = data;
108
+ /**
109
+ * Check if the exception should trigger a retry.
110
+ */
111
+ const shouldRetryException = (error$1) => {
112
+ if (typeof retryOn === "function") return retryOn(error$1);
113
+ return retryOn.some((ErrorConstructor) => error$1.constructor === ErrorConstructor);
114
+ };
115
+ const delayConfig = {
116
+ backoffFactor,
117
+ initialDelayMs,
118
+ maxDelayMs,
119
+ jitter
120
+ };
121
+ /**
122
+ * Format the failure message when retries are exhausted.
123
+ */
124
+ const formatFailureMessage = (error$1, attemptsMade) => {
125
+ const errorType = error$1.constructor.name;
126
+ const attemptWord = attemptsMade === 1 ? "attempt" : "attempts";
127
+ return `Model call failed after ${attemptsMade} ${attemptWord} with ${errorType}: ${error$1.message}`;
128
+ };
129
+ /**
130
+ * Handle failure when all retries are exhausted.
131
+ */
132
+ const handleFailure = (error$1, attemptsMade) => {
133
+ if (onFailure === "error") throw error$1;
134
+ let content;
135
+ if (typeof onFailure === "function") content = onFailure(error$1);
136
+ else content = formatFailureMessage(error$1, attemptsMade);
137
+ return new AIMessage({ content });
138
+ };
139
+ return createMiddleware({
140
+ name: "modelRetryMiddleware",
141
+ contextSchema: ModelRetryMiddlewareOptionsSchema,
142
+ wrapModelCall: async (request, handler) => {
143
+ for (let attempt = 0; attempt <= maxRetries; attempt++) try {
144
+ return await handler(request);
145
+ } catch (error$1) {
146
+ const attemptsMade = attempt + 1;
147
+ const err = error$1 && typeof error$1 === "object" && "message" in error$1 ? error$1 : new Error(String(error$1));
148
+ if (!shouldRetryException(err)) return handleFailure(err, attemptsMade);
149
+ if (attempt < maxRetries) {
150
+ const delay = calculateRetryDelay(delayConfig, attempt);
151
+ if (delay > 0) await sleep(delay);
152
+ } else return handleFailure(err, attemptsMade);
153
+ }
154
+ throw new Error("Unexpected: retry loop completed without returning");
155
+ }
156
+ });
157
+ }
158
+
159
+ //#endregion
160
+ export { modelRetryMiddleware };
161
+ //# sourceMappingURL=modelRetry.js.map