ai-retry 1.7.2 → 1.7.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.
@@ -1,4 +1,4 @@
1
- import { a as isModel, c as isStreamContentPart, i as isImageModel, n as isErrorAttempt, o as isObject, r as isGenerateResult, s as isResultAttempt, t as isEmbeddingModel } from "./guards-D8UJtxDK.mjs";
1
+ import { a as isModel, c as isStreamContentPart, i as isImageModel, n as isErrorAttempt, o as isObject, r as isGenerateResult, s as isResultAttempt, t as isEmbeddingModel, u as isTimeoutError } from "./guards-D8UJtxDK.mjs";
2
2
  import { RetryError, gateway } from "ai";
3
3
  import { delay } from "@ai-sdk/provider-utils";
4
4
  import { getErrorMessage } from "@ai-sdk/provider";
@@ -199,16 +199,25 @@ function resolveProviderOptions(base, currentRetry, onRetryOverrides) {
199
199
  *
200
200
  * If `currentRetry.timeout` is set, a fresh `AbortSignal.timeout(...)` is
201
201
  * created. When the base signal is still alive, the fresh deadline is
202
- * composed with it via `AbortSignal.any` so the user can still cancel
203
- * mid-retry. When the base is already aborted, it is dropped so the retry
204
- * runs against the fresh deadline alone. Without a retry timeout, the base
205
- * is preserved unchanged.
202
+ * composed with the base so user cancellation still propagates mid-retry,
203
+ * but a base `TimeoutError` (`AbortSignal.timeout` used as a wall-clock
204
+ * budget) is ignored so it cannot truncate the retry's own deadline. When
205
+ * the base is already aborted with a `TimeoutError`, it is dropped; with any
206
+ * other reason it propagates. Without a retry timeout, the base is preserved
207
+ * unchanged.
206
208
  */
207
209
  function resolveAbortSignal(base, currentRetry) {
208
210
  if (currentRetry?.timeout === void 0) return base;
209
211
  const fresh = AbortSignal.timeout(currentRetry.timeout);
210
- if (base !== void 0 && !base.aborted) return AbortSignal.any([base, fresh]);
211
- return fresh;
212
+ if (base === void 0) return fresh;
213
+ if (base.aborted) return isTimeoutError(base.reason) ? fresh : base;
214
+ const controller = new AbortController();
215
+ fresh.addEventListener("abort", () => controller.abort(fresh.reason), { once: true });
216
+ base.addEventListener("abort", () => {
217
+ if (isTimeoutError(base.reason)) return;
218
+ controller.abort(base.reason);
219
+ }, { once: true });
220
+ return controller.signal;
212
221
  }
213
222
  /**
214
223
  * Merge call options for the upcoming language model retry attempt.
@@ -136,10 +136,13 @@ function createErrorAPI() {
136
136
  * predicate runs only when the current attempt failed with an error;
137
137
  * result attempts return false.
138
138
  *
139
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
140
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
141
+ *
139
142
  * @example
140
143
  * error<MODEL, APICallError>(
141
144
  * (e) => APICallError.isInstance(e) && e.statusCode === 418,
142
- * )
145
+ * ).switch({ model: fallback })
143
146
  */
144
147
  function error(predicate) {
145
148
  return new Condition(async (ctx) => {
@@ -150,6 +153,9 @@ function createErrorAPI() {
150
153
  /**
151
154
  * Match when the error explicitly carries `isRetryable === flag`.
152
155
  *
156
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
157
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
158
+ *
153
159
  * @example
154
160
  * error.isRetryable(true).retry({ delay: 1000 })
155
161
  * error.isRetryable(false).switch({ model: fallback })
@@ -161,9 +167,12 @@ function createErrorAPI() {
161
167
  * Match by HTTP status code. Numbers match exactly; regular expressions
162
168
  * match against the stringified code, useful for range checks.
163
169
  *
170
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
171
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
172
+ *
164
173
  * @example
165
- * error.statusCode(429, 503)
166
- * error.statusCode(/^5\d\d$/)
174
+ * error.statusCode(429, 503).retry({ delay: 1000 })
175
+ * error.statusCode(/^5\d\d$/).switch({ model: fallback })
167
176
  */
168
177
  error.statusCode = function statusCode(...patterns) {
169
178
  return error((e) => {
@@ -179,10 +188,12 @@ function createErrorAPI() {
179
188
  * message are lowercased before matching. Regular expressions match
180
189
  * as written; use the `i` flag for case-insensitive regex matching.
181
190
  *
191
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
192
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
193
+ *
182
194
  * @example
183
- * error.message('overloaded')
184
- * error.message(/rate.?limit/i)
185
- * error.message('overloaded', /rate.?limit/i)
195
+ * error.message('overloaded').switch({ model: fallback })
196
+ * error.message(/rate.?limit/i).retry({ delay: 1000 })
186
197
  */
187
198
  error.message = function message(...patterns) {
188
199
  return error((e) => {
@@ -198,11 +209,12 @@ function createErrorAPI() {
198
209
  * message. Mix any combination in a single call; matches when any
199
210
  * pattern matches.
200
211
  *
212
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
213
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
214
+ *
201
215
  * @example
202
- * httpStatus(529)
203
- * httpStatus(529, 'overloaded')
204
- * httpStatus(/^5\d\d$/)
205
- * httpStatus(529, 'overloaded', /rate.?limit/i)
216
+ * httpStatus(529).switch({ model: fallback })
217
+ * httpStatus(529, 'overloaded').retry({ delay: 1000 })
206
218
  */
207
219
  function httpStatus(...patterns) {
208
220
  const numbers = patterns.filter((p) => typeof p === "number");
@@ -218,8 +230,12 @@ function createErrorAPI() {
218
230
  * which `AbortSignal.timeout()` produces when the timeout fires.
219
231
  * Distinct from `aborted()`, which matches manual aborts.
220
232
  *
233
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
234
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
235
+ *
221
236
  * @example
222
237
  * timeout().switch({ model: fallback, timeout: 60_000 })
238
+ * timeout().retry({ delay: 1000 })
223
239
  */
224
240
  function timeout() {
225
241
  return error((err) => err instanceof Error && err.name === "TimeoutError");
@@ -229,6 +245,9 @@ function createErrorAPI() {
229
245
  * `controller.abort()` produces. Distinct from `timeout()`, which
230
246
  * matches `AbortSignal.timeout()` firing.
231
247
  *
248
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
249
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
250
+ *
232
251
  * @example
233
252
  * aborted().switch({ model: fallback })
234
253
  */
@@ -1,5 +1,5 @@
1
- import { t as createRetryable$1 } from "../../create-retryable-model-HLobeUXU.mjs";
2
- import "../../error-_63RHJTp.mjs";
1
+ import { t as createRetryable$1 } from "../../create-retryable-model-Bgf7SQFz.mjs";
2
+ import "../../error-CaTT-xX8.mjs";
3
3
  import { aborted, error, httpStatus, timeout } from "./retryables/index.mjs";
4
4
 
5
5
  //#region src/experimental/embedding-model/index.ts
@@ -1,6 +1,6 @@
1
1
  import { k as RetryContext } from "../../../types-DYMm5YMu.mjs";
2
2
  import { n as Condition, t as StatusPattern } from "../../../error-CPbAtI-h.mjs";
3
- import * as _ai_sdk_provider21 from "@ai-sdk/provider";
3
+ import * as _ai_sdk_provider13 from "@ai-sdk/provider";
4
4
 
5
5
  //#region src/experimental/embedding-model/retryables/index.d.ts
6
6
  /**
@@ -11,10 +11,10 @@ import * as _ai_sdk_provider21 from "@ai-sdk/provider";
11
11
  * from 'ai-retry/experimental/embedding-model/retryables';
12
12
  */
13
13
  declare const error: {
14
- <MODEL extends _ai_sdk_provider21.EmbeddingModelV3 = _ai_sdk_provider21.EmbeddingModelV3, E = unknown>(predicate: (err: E, ctx: RetryContext<MODEL>) => boolean | Promise<boolean>): Condition<MODEL>;
15
- isRetryable<MODEL extends _ai_sdk_provider21.EmbeddingModelV3 = _ai_sdk_provider21.EmbeddingModelV3>(flag?: boolean): Condition<MODEL>;
16
- statusCode<MODEL extends _ai_sdk_provider21.EmbeddingModelV3 = _ai_sdk_provider21.EmbeddingModelV3>(...patterns: Array<number | RegExp>): Condition<MODEL>;
17
- message<MODEL extends _ai_sdk_provider21.EmbeddingModelV3 = _ai_sdk_provider21.EmbeddingModelV3>(...patterns: Array<string | RegExp>): Condition<MODEL>;
18
- }, httpStatus: <MODEL extends _ai_sdk_provider21.EmbeddingModelV3 = _ai_sdk_provider21.EmbeddingModelV3>(...patterns: Array<StatusPattern>) => Condition<MODEL>, timeout: <MODEL extends _ai_sdk_provider21.EmbeddingModelV3 = _ai_sdk_provider21.EmbeddingModelV3>() => Condition<MODEL>, aborted: <MODEL extends _ai_sdk_provider21.EmbeddingModelV3 = _ai_sdk_provider21.EmbeddingModelV3>() => Condition<MODEL>;
14
+ <MODEL extends _ai_sdk_provider13.EmbeddingModelV3 = _ai_sdk_provider13.EmbeddingModelV3, E = unknown>(predicate: (err: E, ctx: RetryContext<MODEL>) => boolean | Promise<boolean>): Condition<MODEL>;
15
+ isRetryable<MODEL extends _ai_sdk_provider13.EmbeddingModelV3 = _ai_sdk_provider13.EmbeddingModelV3>(flag?: boolean): Condition<MODEL>;
16
+ statusCode<MODEL extends _ai_sdk_provider13.EmbeddingModelV3 = _ai_sdk_provider13.EmbeddingModelV3>(...patterns: Array<number | RegExp>): Condition<MODEL>;
17
+ message<MODEL extends _ai_sdk_provider13.EmbeddingModelV3 = _ai_sdk_provider13.EmbeddingModelV3>(...patterns: Array<string | RegExp>): Condition<MODEL>;
18
+ }, httpStatus: <MODEL extends _ai_sdk_provider13.EmbeddingModelV3 = _ai_sdk_provider13.EmbeddingModelV3>(...patterns: Array<StatusPattern>) => Condition<MODEL>, timeout: <MODEL extends _ai_sdk_provider13.EmbeddingModelV3 = _ai_sdk_provider13.EmbeddingModelV3>() => Condition<MODEL>, aborted: <MODEL extends _ai_sdk_provider13.EmbeddingModelV3 = _ai_sdk_provider13.EmbeddingModelV3>() => Condition<MODEL>;
19
19
  //#endregion
20
20
  export { aborted, error, httpStatus, timeout };
@@ -1,4 +1,4 @@
1
- import { t as createErrorAPI } from "../../../error-_63RHJTp.mjs";
1
+ import { t as createErrorAPI } from "../../../error-CaTT-xX8.mjs";
2
2
 
3
3
  //#region src/experimental/embedding-model/retryables/index.ts
4
4
  const { error, httpStatus, timeout, aborted } = createErrorAPI();
@@ -1,6 +1,6 @@
1
1
  import { N as RetryableModelOptions, s as ImageModel } from "../../types-DYMm5YMu.mjs";
2
2
  import "../../error-CPbAtI-h.mjs";
3
- import { a as noImage, i as timeout, n as error, r as httpStatus, t as aborted } from "../../index-TcUPTMfl.mjs";
3
+ import { a as noImage, i as timeout, n as error, r as httpStatus, t as aborted } from "../../index-CNEL_aJP.mjs";
4
4
 
5
5
  //#region src/experimental/image-model/index.d.ts
6
6
  declare function createRetryable<MODEL extends ImageModel>(options: RetryableModelOptions<MODEL>): ImageModel;
@@ -1,6 +1,6 @@
1
- import { t as createRetryable$1 } from "../../create-retryable-model-HLobeUXU.mjs";
2
- import "../../error-_63RHJTp.mjs";
3
- import { a as noImage, i as timeout, n as error, r as httpStatus, t as aborted } from "../../retryables-D0wMy6Qt.mjs";
1
+ import { t as createRetryable$1 } from "../../create-retryable-model-Bgf7SQFz.mjs";
2
+ import "../../error-CaTT-xX8.mjs";
3
+ import { a as noImage, i as timeout, n as error, r as httpStatus, t as aborted } from "../../retryables-CPAbu_M3.mjs";
4
4
 
5
5
  //#region src/experimental/image-model/index.ts
6
6
  /**
@@ -1,4 +1,4 @@
1
1
  import "../../../types-DYMm5YMu.mjs";
2
2
  import "../../../error-CPbAtI-h.mjs";
3
- import { a as noImage, i as timeout, n as error, r as httpStatus, t as aborted } from "../../../index-TcUPTMfl.mjs";
3
+ import { a as noImage, i as timeout, n as error, r as httpStatus, t as aborted } from "../../../index-CNEL_aJP.mjs";
4
4
  export { aborted, error, httpStatus, noImage, timeout };
@@ -1,4 +1,4 @@
1
- import "../../../error-_63RHJTp.mjs";
2
- import { a as noImage, i as timeout, n as error, r as httpStatus, t as aborted } from "../../../retryables-D0wMy6Qt.mjs";
1
+ import "../../../error-CaTT-xX8.mjs";
2
+ import { a as noImage, i as timeout, n as error, r as httpStatus, t as aborted } from "../../../retryables-CPAbu_M3.mjs";
3
3
 
4
4
  export { aborted, error, httpStatus, noImage, timeout };
@@ -1,6 +1,6 @@
1
1
  import { N as RetryableModelOptions, d as LanguageModel, o as GatewayLanguageModelId } from "../../types-DYMm5YMu.mjs";
2
2
  import "../../error-CPbAtI-h.mjs";
3
- import { a as result, i as httpStatus, n as error, o as schemaInvalid, r as finishReason, s as timeout, t as aborted } from "../../index-C9DEYXL_.mjs";
3
+ import { a as result, i as httpStatus, n as error, o as schemaInvalid, r as finishReason, s as timeout, t as aborted } from "../../index-BygX0XfC.mjs";
4
4
 
5
5
  //#region src/experimental/language-model/index.d.ts
6
6
  declare function createRetryable(options: Omit<RetryableModelOptions<LanguageModel>, 'model'> & {
@@ -1,6 +1,6 @@
1
- import { t as createRetryable$1 } from "../../create-retryable-model-HLobeUXU.mjs";
2
- import "../../error-_63RHJTp.mjs";
3
- import { a as result, i as httpStatus, n as error, o as schemaInvalid, r as finishReason, s as timeout, t as aborted } from "../../retryables-DBiDOfIF.mjs";
1
+ import { t as createRetryable$1 } from "../../create-retryable-model-Bgf7SQFz.mjs";
2
+ import "../../error-CaTT-xX8.mjs";
3
+ import { a as result, i as httpStatus, n as error, o as schemaInvalid, r as finishReason, s as timeout, t as aborted } from "../../retryables-M5l_6w9k.mjs";
4
4
 
5
5
  //#region src/experimental/language-model/index.ts
6
6
  /**
@@ -1,4 +1,4 @@
1
1
  import "../../../types-DYMm5YMu.mjs";
2
2
  import "../../../error-CPbAtI-h.mjs";
3
- import { a as result, i as httpStatus, n as error, o as schemaInvalid, r as finishReason, s as timeout, t as aborted } from "../../../index-C9DEYXL_.mjs";
3
+ import { a as result, i as httpStatus, n as error, o as schemaInvalid, r as finishReason, s as timeout, t as aborted } from "../../../index-BygX0XfC.mjs";
4
4
  export { aborted, error, finishReason, httpStatus, result, schemaInvalid, timeout };
@@ -1,4 +1,4 @@
1
- import "../../../error-_63RHJTp.mjs";
2
- import { a as result, i as httpStatus, n as error, o as schemaInvalid, r as finishReason, s as timeout, t as aborted } from "../../../retryables-DBiDOfIF.mjs";
1
+ import "../../../error-CaTT-xX8.mjs";
2
+ import { a as result, i as httpStatus, n as error, o as schemaInvalid, r as finishReason, s as timeout, t as aborted } from "../../../retryables-M5l_6w9k.mjs";
3
3
 
4
4
  export { aborted, error, finishReason, httpStatus, result, schemaInvalid, timeout };
@@ -0,0 +1,27 @@
1
+ import { k as RetryContext, m as LanguageModelResult, x as ResolvableLanguageModel } from "./types-DYMm5YMu.mjs";
2
+ import { n as Condition, t as StatusPattern } from "./error-CPbAtI-h.mjs";
3
+
4
+ //#region src/experimental/internal/result.d.ts
5
+ /**
6
+ * The unified finish reason produced by the AI SDK.
7
+ */
8
+ type FinishReason = LanguageModelResult['finishReason']['unified'];
9
+ //#endregion
10
+ //#region src/experimental/language-model/retryables/index.d.ts
11
+ /**
12
+ * Conditions are bound to `ResolvableLanguageModel` (instance or
13
+ * gateway string literal) so `.switch({ model: 'openai/gpt-5' })` is
14
+ * accepted alongside `.switch({ model: openai('gpt-4o') })`.
15
+ */
16
+ declare const error: {
17
+ <MODEL extends ResolvableLanguageModel = ResolvableLanguageModel, E = unknown>(predicate: (err: E, ctx: RetryContext<MODEL>) => boolean | Promise<boolean>): Condition<MODEL>;
18
+ isRetryable<MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>(flag?: boolean): Condition<MODEL>;
19
+ statusCode<MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>(...patterns: Array<number | RegExp>): Condition<MODEL>;
20
+ message<MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>(...patterns: Array<string | RegExp>): Condition<MODEL>;
21
+ }, httpStatus: <MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>(...patterns: Array<StatusPattern>) => Condition<MODEL>, timeout: <MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>() => Condition<MODEL>, aborted: <MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>() => Condition<MODEL>;
22
+ declare const result: {
23
+ <MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>(predicate: (res: LanguageModelResult, ctx: RetryContext<MODEL>) => boolean | Promise<boolean>): Condition<MODEL>;
24
+ finishReason<MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>(...reasons: Array<FinishReason>): Condition<MODEL>;
25
+ }, finishReason: <MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>(...reasons: Array<FinishReason>) => Condition<MODEL>, schemaInvalid: <MODEL extends ResolvableLanguageModel = ResolvableLanguageModel>() => Condition<MODEL>;
26
+ //#endregion
27
+ export { result as a, httpStatus as i, error as n, schemaInvalid as o, finishReason as r, timeout as s, aborted as t };
@@ -0,0 +1,34 @@
1
+ import { k as RetryContext, s as ImageModel } from "./types-DYMm5YMu.mjs";
2
+ import { n as Condition, t as StatusPattern } from "./error-CPbAtI-h.mjs";
3
+ import * as _ai_sdk_provider0 from "@ai-sdk/provider";
4
+
5
+ //#region src/experimental/internal/no-image.d.ts
6
+ /**
7
+ * Match when image generation produced no images
8
+ * (`NoImageGeneratedError`).
9
+ *
10
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
11
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
12
+ *
13
+ * @example
14
+ * noImage().switch({ model: fallback })
15
+ * noImage().retry({ maxAttempts: 3 })
16
+ */
17
+ declare function noImage<MODEL extends ImageModel = ImageModel>(): Condition<MODEL>;
18
+ //#endregion
19
+ //#region src/experimental/image-model/retryables/index.d.ts
20
+ /**
21
+ * Experimental composable conditions bound to `ImageModel`. For use with
22
+ * `generateImage`.
23
+ *
24
+ * import { error, noImage, ... }
25
+ * from 'ai-retry/experimental/image-model/retryables';
26
+ */
27
+ declare const error: {
28
+ <MODEL extends _ai_sdk_provider0.ImageModelV3 = _ai_sdk_provider0.ImageModelV3, E = unknown>(predicate: (err: E, ctx: RetryContext<MODEL>) => boolean | Promise<boolean>): Condition<MODEL>;
29
+ isRetryable<MODEL extends _ai_sdk_provider0.ImageModelV3 = _ai_sdk_provider0.ImageModelV3>(flag?: boolean): Condition<MODEL>;
30
+ statusCode<MODEL extends _ai_sdk_provider0.ImageModelV3 = _ai_sdk_provider0.ImageModelV3>(...patterns: Array<number | RegExp>): Condition<MODEL>;
31
+ message<MODEL extends _ai_sdk_provider0.ImageModelV3 = _ai_sdk_provider0.ImageModelV3>(...patterns: Array<string | RegExp>): Condition<MODEL>;
32
+ }, httpStatus: <MODEL extends _ai_sdk_provider0.ImageModelV3 = _ai_sdk_provider0.ImageModelV3>(...patterns: Array<StatusPattern>) => Condition<MODEL>, timeout: <MODEL extends _ai_sdk_provider0.ImageModelV3 = _ai_sdk_provider0.ImageModelV3>() => Condition<MODEL>, aborted: <MODEL extends _ai_sdk_provider0.ImageModelV3 = _ai_sdk_provider0.ImageModelV3>() => Condition<MODEL>;
33
+ //#endregion
34
+ export { noImage as a, timeout as i, error as n, httpStatus as r, aborted as t };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as getModelKey, t as createRetryable } from "./create-retryable-model-HLobeUXU.mjs";
1
+ import { n as getModelKey, t as createRetryable } from "./create-retryable-model-Bgf7SQFz.mjs";
2
2
  import { n as isErrorAttempt, s as isResultAttempt } from "./guards-D8UJtxDK.mjs";
3
3
 
4
4
  export { createRetryable, getModelKey, isErrorAttempt, isResultAttempt };
@@ -1,5 +1,5 @@
1
1
  import { n as isErrorAttempt } from "./guards-D8UJtxDK.mjs";
2
- import { n as Condition, t as createErrorAPI } from "./error-_63RHJTp.mjs";
2
+ import { n as Condition, t as createErrorAPI } from "./error-CaTT-xX8.mjs";
3
3
  import { NoImageGeneratedError } from "ai";
4
4
 
5
5
  //#region src/experimental/internal/no-image.ts
@@ -7,8 +7,12 @@ import { NoImageGeneratedError } from "ai";
7
7
  * Match when image generation produced no images
8
8
  * (`NoImageGeneratedError`).
9
9
  *
10
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
11
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
12
+ *
10
13
  * @example
11
14
  * noImage().switch({ model: fallback })
15
+ * noImage().retry({ maxAttempts: 3 })
12
16
  */
13
17
  function noImage() {
14
18
  return new Condition(async (ctx) => {
@@ -1,5 +1,5 @@
1
1
  import { s as isResultAttempt } from "./guards-D8UJtxDK.mjs";
2
- import { n as Condition, t as createErrorAPI } from "./error-_63RHJTp.mjs";
2
+ import { n as Condition, t as createErrorAPI } from "./error-CaTT-xX8.mjs";
3
3
  import { safeParseJSON } from "@ai-sdk/provider-utils";
4
4
  import { fromJSONSchema } from "zod";
5
5
 
@@ -19,8 +19,12 @@ function createResultAPI() {
19
19
  * The predicate runs only when the current attempt succeeded; error
20
20
  * attempts return false.
21
21
  *
22
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
23
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
24
+ *
22
25
  * @example
23
26
  * result<MODEL>((res) => res.finishReason.unified === 'length')
27
+ * .switch({ model: fallback })
24
28
  */
25
29
  function result(predicate) {
26
30
  return new Condition(async (ctx) => {
@@ -31,20 +35,25 @@ function createResultAPI() {
31
35
  /**
32
36
  * Match the result's finish reason against one of the given values.
33
37
  *
38
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
39
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
40
+ *
34
41
  * @example
35
- * result.finishReason('content-filter')
36
- * result.finishReason('content-filter', 'length')
42
+ * result.finishReason('content-filter').switch({ model: fallback })
43
+ * result.finishReason('length').retry({ maxAttempts: 3 })
37
44
  */
38
45
  result.finishReason = function finishReason(...reasons) {
39
46
  return result((res) => reasons.includes(res.finishReason.unified));
40
47
  };
41
48
  /**
42
49
  * Match the result's finish reason against one of the given values.
43
- * Thin wrapper around `result.finishReason(...)`.
50
+ *
51
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
52
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
44
53
  *
45
54
  * @example
46
- * finishReason('content-filter')
47
- * finishReason('content-filter', 'length')
55
+ * finishReason('content-filter').switch({ model: fallback })
56
+ * finishReason('length').retry({ maxAttempts: 3 })
48
57
  */
49
58
  function finishReason(...reasons) {
50
59
  return result.finishReason(...reasons);
@@ -54,8 +63,12 @@ function createResultAPI() {
54
63
  * is read from the call's `responseFormat`, which `Output.object()`
55
64
  * sets automatically. No-op when no schema is configured.
56
65
  *
66
+ * **Important:** returns a `Condition`, not a `Retryable`. Call
67
+ * `.switch()` or `.retry()` to plug it into `retries: [...]`.
68
+ *
57
69
  * @example
58
70
  * schemaInvalid().switch({ model: fallback })
71
+ * schemaInvalid().retry({ maxAttempts: 3 })
59
72
  */
60
73
  function schemaInvalid() {
61
74
  return result(async (res, ctx) => {
@@ -80,6 +93,11 @@ function createResultAPI() {
80
93
 
81
94
  //#endregion
82
95
  //#region src/experimental/language-model/retryables/index.ts
96
+ /**
97
+ * Conditions are bound to `ResolvableLanguageModel` (instance or
98
+ * gateway string literal) so `.switch({ model: 'openai/gpt-5' })` is
99
+ * accepted alongside `.switch({ model: openai('gpt-4o') })`.
100
+ */
83
101
  const { error, httpStatus, timeout, aborted } = createErrorAPI();
84
102
  const { result, finishReason, schemaInvalid } = createResultAPI();
85
103
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-retry",
3
- "version": "1.7.2",
3
+ "version": "1.7.4",
4
4
  "description": "Retry and fallback mechanisms for AI SDK",
5
5
  "keywords": [
6
6
  "ai",
@@ -1,30 +0,0 @@
1
- import { k as RetryContext, m as LanguageModelResult } from "./types-DYMm5YMu.mjs";
2
- import { n as Condition, t as StatusPattern } from "./error-CPbAtI-h.mjs";
3
- import * as _ai_sdk_provider0 from "@ai-sdk/provider";
4
-
5
- //#region src/experimental/internal/result.d.ts
6
- /**
7
- * The unified finish reason produced by the AI SDK.
8
- */
9
- type FinishReason = LanguageModelResult['finishReason']['unified'];
10
- //#endregion
11
- //#region src/experimental/language-model/retryables/index.d.ts
12
- /**
13
- * Experimental composable conditions bound to `LanguageModel`. For use
14
- * with `generateText`, `generateObject`, `streamText`, `streamObject`.
15
- *
16
- * import { error, httpStatus, finishReason, ... }
17
- * from 'ai-retry/experimental/language-model/retryables';
18
- */
19
- declare const error: {
20
- <MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3, E = unknown>(predicate: (err: E, ctx: RetryContext<MODEL>) => boolean | Promise<boolean>): Condition<MODEL>;
21
- isRetryable<MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>(flag?: boolean): Condition<MODEL>;
22
- statusCode<MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>(...patterns: Array<number | RegExp>): Condition<MODEL>;
23
- message<MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>(...patterns: Array<string | RegExp>): Condition<MODEL>;
24
- }, httpStatus: <MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>(...patterns: Array<StatusPattern>) => Condition<MODEL>, timeout: <MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>() => Condition<MODEL>, aborted: <MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>() => Condition<MODEL>;
25
- declare const result: {
26
- <MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>(predicate: (res: LanguageModelResult, ctx: RetryContext<MODEL>) => boolean | Promise<boolean>): Condition<MODEL>;
27
- finishReason<MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>(...reasons: Array<FinishReason>): Condition<MODEL>;
28
- }, finishReason: <MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>(...reasons: Array<FinishReason>) => Condition<MODEL>, schemaInvalid: <MODEL extends _ai_sdk_provider0.LanguageModelV3 = _ai_sdk_provider0.LanguageModelV3>() => Condition<MODEL>;
29
- //#endregion
30
- export { result as a, httpStatus as i, error as n, schemaInvalid as o, finishReason as r, timeout as s, aborted as t };
@@ -1,30 +0,0 @@
1
- import { k as RetryContext, s as ImageModel } from "./types-DYMm5YMu.mjs";
2
- import { n as Condition, t as StatusPattern } from "./error-CPbAtI-h.mjs";
3
- import * as _ai_sdk_provider35 from "@ai-sdk/provider";
4
-
5
- //#region src/experimental/internal/no-image.d.ts
6
- /**
7
- * Match when image generation produced no images
8
- * (`NoImageGeneratedError`).
9
- *
10
- * @example
11
- * noImage().switch({ model: fallback })
12
- */
13
- declare function noImage<MODEL extends ImageModel = ImageModel>(): Condition<MODEL>;
14
- //#endregion
15
- //#region src/experimental/image-model/retryables/index.d.ts
16
- /**
17
- * Experimental composable conditions bound to `ImageModel`. For use with
18
- * `generateImage`.
19
- *
20
- * import { error, noImage, ... }
21
- * from 'ai-retry/experimental/image-model/retryables';
22
- */
23
- declare const error: {
24
- <MODEL extends _ai_sdk_provider35.ImageModelV3 = _ai_sdk_provider35.ImageModelV3, E = unknown>(predicate: (err: E, ctx: RetryContext<MODEL>) => boolean | Promise<boolean>): Condition<MODEL>;
25
- isRetryable<MODEL extends _ai_sdk_provider35.ImageModelV3 = _ai_sdk_provider35.ImageModelV3>(flag?: boolean): Condition<MODEL>;
26
- statusCode<MODEL extends _ai_sdk_provider35.ImageModelV3 = _ai_sdk_provider35.ImageModelV3>(...patterns: Array<number | RegExp>): Condition<MODEL>;
27
- message<MODEL extends _ai_sdk_provider35.ImageModelV3 = _ai_sdk_provider35.ImageModelV3>(...patterns: Array<string | RegExp>): Condition<MODEL>;
28
- }, httpStatus: <MODEL extends _ai_sdk_provider35.ImageModelV3 = _ai_sdk_provider35.ImageModelV3>(...patterns: Array<StatusPattern>) => Condition<MODEL>, timeout: <MODEL extends _ai_sdk_provider35.ImageModelV3 = _ai_sdk_provider35.ImageModelV3>() => Condition<MODEL>, aborted: <MODEL extends _ai_sdk_provider35.ImageModelV3 = _ai_sdk_provider35.ImageModelV3>() => Condition<MODEL>;
29
- //#endregion
30
- export { noImage as a, timeout as i, error as n, httpStatus as r, aborted as t };