@shop-os/modelkit 0.2.13 → 0.2.14

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/dist/index.cjs CHANGED
@@ -246,7 +246,9 @@ function normalizeExposure(value) {
246
246
  if (value === "catalog") return ["cowork", "space_builder"];
247
247
  if (value === "internal") return [];
248
248
  if (Array.isArray(value)) {
249
- if (value.every((entry) => SURFACES.includes(entry))) {
249
+ if (value.every(
250
+ (entry) => SURFACES.includes(entry)
251
+ )) {
250
252
  const present = new Set(value);
251
253
  return SURFACES.filter((surface) => present.has(surface));
252
254
  }
@@ -2787,6 +2789,19 @@ function shouldRetry(err) {
2787
2789
  if (/ECONNRESET|ETIMEDOUT|fetch failed|socket hang up/i.test(err.message)) return true;
2788
2790
  return false;
2789
2791
  }
2792
+ function mediaRetryOptions(call, signal, defaultAttempts = 3) {
2793
+ if (call.maxRetries !== void 0 && (!Number.isSafeInteger(call.maxRetries + 1) || call.maxRetries < 0)) {
2794
+ throw new ModelKitError({
2795
+ code: "unsupported_option",
2796
+ message: "maxRetries must be a non-negative safe integer",
2797
+ retryable: false
2798
+ });
2799
+ }
2800
+ return {
2801
+ attempts: call.maxRetries === void 0 ? defaultAttempts : call.maxRetries + 1,
2802
+ ...signal !== void 0 ? { signal } : {}
2803
+ };
2804
+ }
2790
2805
  async function withRetry(fn, opts = {}) {
2791
2806
  const attempts = opts.attempts ?? 3;
2792
2807
  const base = opts.baseDelayMs ?? 1e3;
@@ -2794,6 +2809,7 @@ async function withRetry(fn, opts = {}) {
2794
2809
  const factor = opts.factor ?? 2;
2795
2810
  let last;
2796
2811
  for (let attempt = 1; attempt <= attempts; attempt++) {
2812
+ if (opts.signal?.aborted) throw throwAborted();
2797
2813
  try {
2798
2814
  return await fn(attempt);
2799
2815
  } catch (cause) {
@@ -2906,11 +2922,11 @@ async function readBody(res) {
2906
2922
  return text2;
2907
2923
  }
2908
2924
  }
2909
- async function mediaRefToBytes(ref, fetch, options = {}) {
2925
+ async function mediaRefToBytes(ref, fetch2, options = {}) {
2910
2926
  if (!isUrlRef(ref)) return { bytes: ref.bytes, mime: ref.mime };
2911
2927
  const init = {};
2912
2928
  if (options.signal !== void 0) init.signal = options.signal;
2913
- const res = await fetch(ref.url, init);
2929
+ const res = await fetch2(ref.url, init);
2914
2930
  if (!res.ok) {
2915
2931
  const text2 = await res.text().catch(() => "");
2916
2932
  throw classifyHttpError(
@@ -3047,11 +3063,6 @@ var SeedreamResponseSchema = import_zod6.z.object({
3047
3063
  data: import_zod6.z.array(SeedreamImageSchema).optional(),
3048
3064
  error: import_zod6.z.object({ message: import_zod6.z.string().optional(), code: import_zod6.z.string().optional() }).optional()
3049
3065
  });
3050
- function retryOptsFor(ctx, attempts = 3) {
3051
- const opts = { attempts };
3052
- if (ctx.signal !== void 0) opts.signal = ctx.signal;
3053
- return opts;
3054
- }
3055
3066
  function fetchInitFor(ctx, init) {
3056
3067
  if (ctx.signal !== void 0) init.signal = ctx.signal;
3057
3068
  return init;
@@ -3089,20 +3100,23 @@ async function generateSeedreamImage(req, ctx) {
3089
3100
  const firstRef = refs[0];
3090
3101
  if (refs.length === 1 && firstRef !== void 0) body.image = firstRef;
3091
3102
  else if (refs.length > 1) body.image = refs;
3092
- const data = await withRetry(async () => {
3093
- const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}/images/generations`, {
3094
- method: "POST",
3095
- headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
3096
- body: JSON.stringify(body)
3097
- });
3098
- if (!res.ok) {
3099
- const text2 = await res.text().catch(() => "");
3100
- throwArkError(res.status, text2, modelId);
3101
- }
3102
- const parsed = SeedreamResponseSchema.safeParse(await res.json());
3103
- const decoded = parsed.success ? parsed.data : {};
3104
- return decoded;
3105
- }, retryOptsFor(ctx));
3103
+ const data = await withRetry(
3104
+ async () => {
3105
+ const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}/images/generations`, {
3106
+ method: "POST",
3107
+ headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
3108
+ body: JSON.stringify(body)
3109
+ });
3110
+ if (!res.ok) {
3111
+ const text2 = await res.text().catch(() => "");
3112
+ throwArkError(res.status, text2, modelId);
3113
+ }
3114
+ const parsed = SeedreamResponseSchema.safeParse(await res.json());
3115
+ const decoded = parsed.success ? parsed.data : {};
3116
+ return decoded;
3117
+ },
3118
+ mediaRetryOptions(ctx.call, ctx.signal)
3119
+ );
3106
3120
  const first = data.data?.[0];
3107
3121
  let bytes;
3108
3122
  if (first?.b64_json) {
@@ -3238,20 +3252,23 @@ async function generateSeedanceVideo(req, ctx) {
3238
3252
  if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
3239
3253
  if (req.seed !== void 0) body.seed = req.seed;
3240
3254
  if (req.watermark !== void 0) body.watermark = req.watermark;
3241
- const submit = await withRetry(async () => {
3242
- const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}`, {
3243
- method: "POST",
3244
- headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
3245
- body: JSON.stringify(body)
3246
- });
3247
- if (!res.ok) {
3248
- const text2 = await res.text().catch(() => "");
3249
- throwArkError(res.status, text2, modelId);
3250
- }
3251
- const parsed = SeedanceResponseSchema.safeParse(await res.json());
3252
- const decoded = parsed.success ? parsed.data : {};
3253
- return decoded;
3254
- }, retryOptsFor(ctx));
3255
+ const submit = await withRetry(
3256
+ async () => {
3257
+ const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}`, {
3258
+ method: "POST",
3259
+ headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
3260
+ body: JSON.stringify(body)
3261
+ });
3262
+ if (!res.ok) {
3263
+ const text2 = await res.text().catch(() => "");
3264
+ throwArkError(res.status, text2, modelId);
3265
+ }
3266
+ const parsed = SeedanceResponseSchema.safeParse(await res.json());
3267
+ const decoded = parsed.success ? parsed.data : {};
3268
+ return decoded;
3269
+ },
3270
+ mediaRetryOptions(ctx.call, ctx.signal)
3271
+ );
3255
3272
  if (!submit.id) throwArkError(void 0, "Seedance task create returned no id", modelId);
3256
3273
  const jobId = submit.id;
3257
3274
  const usage2 = seedanceUsage(ctx, req, taskType === "edit" ? requestedDuration : duration);
@@ -3260,7 +3277,8 @@ async function generateSeedanceVideo(req, ctx) {
3260
3277
  headers: { Authorization: `Bearer ${key}` }
3261
3278
  });
3262
3279
  if (!res.ok) {
3263
- if (res.status === 429 || res.status >= 500) return void 0;
3280
+ if (ctx.call.maxRetries !== 0 && (res.status === 429 || res.status >= 500))
3281
+ return void 0;
3264
3282
  const text2 = await res.text().catch(() => "");
3265
3283
  throwArkError(res.status, text2, modelId);
3266
3284
  }
@@ -3326,16 +3344,109 @@ async function generateSeedanceVideo(req, ctx) {
3326
3344
  }
3327
3345
 
3328
3346
  // src/adapters/fal.ts
3329
- var import_zod7 = require("zod");
3347
+ var import_zod8 = require("zod");
3330
3348
  var import_client = require("@fal-ai/client");
3349
+
3350
+ // src/adapters/fal-http.ts
3351
+ var import_zod7 = require("zod");
3352
+ var queueUrl = import_zod7.z.url().refine((value) => new URL(value).origin === "https://queue.fal.run");
3353
+ var submissionSchema = import_zod7.z.object({
3354
+ request_id: import_zod7.z.string(),
3355
+ status_url: queueUrl,
3356
+ response_url: queueUrl
3357
+ });
3358
+ var statusSchema = import_zod7.z.object({ status: import_zod7.z.string() });
3359
+ function createFalHttpClient(opts) {
3360
+ const jobs = /* @__PURE__ */ new Map();
3361
+ async function request(url, input, signal) {
3362
+ let response;
3363
+ try {
3364
+ response = await opts.fetch(url, {
3365
+ method: input === void 0 ? "GET" : "POST",
3366
+ headers: {
3367
+ Authorization: `Key ${opts.credentials}`,
3368
+ "Content-Type": "application/json"
3369
+ },
3370
+ ...input !== void 0 ? { body: JSON.stringify(input) } : {},
3371
+ ...signal !== void 0 ? { signal } : {}
3372
+ });
3373
+ } catch (cause) {
3374
+ throw classifyThrown("fal", cause);
3375
+ }
3376
+ if (!response.ok) throw classifyHttpError(response.status, await response.text(), "fal");
3377
+ return JsonValueSchema.parse(await response.json());
3378
+ }
3379
+ function job(id) {
3380
+ const saved = jobs.get(id);
3381
+ if (!saved)
3382
+ throw new ModelKitError({
3383
+ code: "provider_rejected",
3384
+ provider: "fal",
3385
+ message: "Unknown fal queue request"
3386
+ });
3387
+ return saved;
3388
+ }
3389
+ const queue = {
3390
+ async submit(endpoint, options) {
3391
+ const submitted = submissionSchema.parse(
3392
+ await request(
3393
+ `https://queue.fal.run/${endpoint}`,
3394
+ options.input,
3395
+ options.abortSignal
3396
+ )
3397
+ );
3398
+ jobs.set(submitted.request_id, submitted);
3399
+ return { requestId: submitted.request_id };
3400
+ },
3401
+ async status(_endpoint, options) {
3402
+ return statusSchema.parse(
3403
+ await request(job(options.requestId).status_url, void 0, options.abortSignal)
3404
+ );
3405
+ },
3406
+ result: (_endpoint, options) => request(job(options.requestId).response_url, void 0, options.abortSignal)
3407
+ };
3408
+ return {
3409
+ queue,
3410
+ async subscribe(endpoint, options) {
3411
+ const submitted = await withRetry(
3412
+ () => queue.submit(endpoint, options),
3413
+ mediaRetryOptions(opts, options.abortSignal)
3414
+ );
3415
+ return pollUntil(
3416
+ async () => {
3417
+ const readOptions = {
3418
+ requestId: submitted.requestId,
3419
+ ...options.abortSignal !== void 0 ? { abortSignal: options.abortSignal } : {}
3420
+ };
3421
+ const current = await queue.status(endpoint, readOptions);
3422
+ if (current.status !== "COMPLETED") return void 0;
3423
+ return queue.result(endpoint, readOptions);
3424
+ },
3425
+ {
3426
+ intervalMs: 1e3,
3427
+ timeoutMs: 18e4,
3428
+ ...options.abortSignal !== void 0 ? { signal: options.abortSignal } : {}
3429
+ }
3430
+ );
3431
+ }
3432
+ };
3433
+ }
3434
+
3435
+ // src/adapters/fal.ts
3331
3436
  var MUSE_T2I_ENDPOINT = "meta/muse-image/text-to-image";
3332
3437
  var MUSE_EDIT_ENDPOINT = "meta/muse-image/edit";
3333
3438
  var KLING_O1_ENDPOINT = "fal-ai/kling-video/o1/video-to-video/reference";
3334
3439
  var FAL_QUEUE_HOST = "https://queue.fal.run";
3335
3440
  var PASSTHROUGH_POLL_MS = 2e3;
3336
3441
  var PASSTHROUGH_MAX_WAIT_MS = 18e4;
3337
- var falSubscribePayloadSchema = import_zod7.z.object({ data: JsonValueSchema });
3442
+ var falSubscribePayloadSchema = import_zod8.z.object({ data: JsonValueSchema });
3338
3443
  function defaultCreateFalClient(opts) {
3444
+ if (opts.maxRetries !== void 0)
3445
+ return createFalHttpClient({
3446
+ credentials: opts.credentials,
3447
+ fetch: opts.fetch ?? fetch,
3448
+ maxRetries: opts.maxRetries
3449
+ });
3339
3450
  const client2 = (0, import_client.createFalClient)(opts);
3340
3451
  return {
3341
3452
  async subscribe(endpoint, options) {
@@ -3384,7 +3495,7 @@ function createFalAdapter(deps = defaultDeps) {
3384
3495
  };
3385
3496
  }
3386
3497
  var falAdapter = createFalAdapter();
3387
- var falDetailSchema = import_zod7.z.object({ detail: JsonValueSchema });
3498
+ var falDetailSchema = import_zod8.z.object({ detail: JsonValueSchema });
3388
3499
  function liftDetail(body) {
3389
3500
  const parsed = falDetailSchema.safeParse(body);
3390
3501
  const detail = parsed.success ? parsed.data.detail : void 0;
@@ -3393,11 +3504,11 @@ function liftDetail(body) {
3393
3504
  function falError(status, body, model) {
3394
3505
  return classifyHttpError(status, liftDetail(body), "fal", model);
3395
3506
  }
3396
- var falSdkThrownSchema = import_zod7.z.object({
3397
- status: import_zod7.z.number().optional(),
3398
- statusCode: import_zod7.z.number().optional(),
3507
+ var falSdkThrownSchema = import_zod8.z.object({
3508
+ status: import_zod8.z.number().optional(),
3509
+ statusCode: import_zod8.z.number().optional(),
3399
3510
  body: JsonValueSchema.optional(),
3400
- message: import_zod7.z.string().optional()
3511
+ message: import_zod8.z.string().optional()
3401
3512
  });
3402
3513
  function falSdkError(cause, model) {
3403
3514
  const parsed = falSdkThrownSchema.safeParse(cause);
@@ -3430,6 +3541,8 @@ function gatewayConfig(ctx) {
3430
3541
  };
3431
3542
  if (falKey) config.falKey = falKey;
3432
3543
  if (cfToken) config.cfToken = cfToken;
3544
+ if (ctx.call.maxRetries !== void 0) config.singleAttempt = true;
3545
+ if (ctx.signal !== void 0) config.signal = ctx.signal;
3433
3546
  return config;
3434
3547
  }
3435
3548
  async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
@@ -3437,16 +3550,18 @@ async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
3437
3550
  if (cfg.falKey) headers2.Authorization = `Bearer ${cfg.falKey}`;
3438
3551
  if (init.body) headers2["Content-Type"] = "application/json";
3439
3552
  if (cfg.cfToken) headers2["cf-aig-authorization"] = `Bearer ${cfg.cfToken}`;
3553
+ if (cfg.singleAttempt) headers2["cf-aig-max-attempts"] = "1";
3440
3554
  const request = { method: init.method, headers: headers2 };
3555
+ if (cfg.signal !== void 0) request.signal = cfg.signal;
3441
3556
  if (init.body !== void 0) request.body = init.body;
3442
3557
  return fetchImpl(cfg.baseUrl, request);
3443
3558
  }
3444
- var falQueueSubmitSchema = import_zod7.z.object({
3445
- request_id: import_zod7.z.string(),
3446
- status_url: import_zod7.z.string(),
3447
- response_url: import_zod7.z.string()
3559
+ var falQueueSubmitSchema = import_zod8.z.object({
3560
+ request_id: import_zod8.z.string(),
3561
+ status_url: import_zod8.z.string(),
3562
+ response_url: import_zod8.z.string()
3448
3563
  });
3449
- var falQueueStatusSchema = import_zod7.z.object({ status: import_zod7.z.string() });
3564
+ var falQueueStatusSchema = import_zod8.z.object({ status: import_zod8.z.string() });
3450
3565
  async function passthroughRequest(ctx, endpoint, input) {
3451
3566
  const cfg = gatewayConfig(ctx);
3452
3567
  const submitRes = await gatewayFetch(cfg, ctx.fetch, `${FAL_QUEUE_HOST}/${endpoint}`, {
@@ -3503,7 +3618,11 @@ function falClientOf(ctx, deps) {
3503
3618
  retryable: false
3504
3619
  });
3505
3620
  }
3506
- return deps.createFalClient({ credentials: falKey, fetch: ctx.fetch });
3621
+ return deps.createFalClient({
3622
+ credentials: falKey,
3623
+ fetch: ctx.fetch,
3624
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {}
3625
+ });
3507
3626
  }
3508
3627
  async function subscribe(ctx, deps, endpoint, input) {
3509
3628
  const client2 = falClientOf(ctx, deps);
@@ -3520,7 +3639,10 @@ async function subscribe(ctx, deps, endpoint, input) {
3520
3639
  throw falSdkError(cause, ctx.model.id);
3521
3640
  }
3522
3641
  },
3523
- ctx.signal !== void 0 ? { signal: ctx.signal } : {}
3642
+ mediaRetryOptions(
3643
+ ctx.call.maxRetries === void 0 ? {} : { maxRetries: 0 },
3644
+ ctx.signal
3645
+ )
3524
3646
  );
3525
3647
  } catch (cause) {
3526
3648
  throw falSdkError(cause, ctx.model.id);
@@ -3572,11 +3694,11 @@ async function decodeImage(ctx, url, contentType) {
3572
3694
  const mime = res.headers.get("content-type") ?? contentType ?? "image/png";
3573
3695
  return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
3574
3696
  }
3575
- var museImageResultSchema = import_zod7.z.object({
3576
- images: import_zod7.z.array(
3577
- import_zod7.z.object({
3578
- url: import_zod7.z.string().optional(),
3579
- content_type: import_zod7.z.string().nullable().optional()
3697
+ var museImageResultSchema = import_zod8.z.object({
3698
+ images: import_zod8.z.array(
3699
+ import_zod8.z.object({
3700
+ url: import_zod8.z.string().optional(),
3701
+ content_type: import_zod8.z.string().nullable().optional()
3580
3702
  })
3581
3703
  ).optional()
3582
3704
  });
@@ -3680,8 +3802,8 @@ function klingO1Input(req) {
3680
3802
  if (refs.length > 0) input.image_urls = refs;
3681
3803
  return input;
3682
3804
  }
3683
- var falVideoResultSchema = import_zod7.z.object({
3684
- video: import_zod7.z.object({ url: import_zod7.z.string().optional() }).optional()
3805
+ var falVideoResultSchema = import_zod8.z.object({
3806
+ video: import_zod8.z.object({ url: import_zod8.z.string().optional() }).optional()
3685
3807
  });
3686
3808
  function extractVideoUrl(result, endpoint, model) {
3687
3809
  const parsed = falVideoResultSchema.safeParse(result);
@@ -3761,7 +3883,7 @@ async function submitQueueJob(ctx, req, deps, endpoint, input) {
3761
3883
  throw falSdkError(cause, ctx.model.id);
3762
3884
  }
3763
3885
  },
3764
- ctx.signal !== void 0 ? { signal: ctx.signal } : {}
3886
+ mediaRetryOptions(ctx.call, ctx.signal)
3765
3887
  );
3766
3888
  } catch (cause) {
3767
3889
  throw falSdkError(cause, ctx.model.id);
@@ -3790,6 +3912,7 @@ function queuedVideoJob(ctx, req, client2, endpoint, requestId) {
3790
3912
  if (status === "IN_QUEUE") return { status: "pending" };
3791
3913
  return { status: "running" };
3792
3914
  } catch (cause) {
3915
+ if (ctx.call.maxRetries === 0) throw cause;
3793
3916
  if (isModelKitError(cause) && !cause.retryable)
3794
3917
  return { status: "failed" };
3795
3918
  return { status: "pending" };
@@ -3813,7 +3936,7 @@ function queuedVideoJob(ctx, req, client2, endpoint, requestId) {
3813
3936
  return await client2.queue.result(endpoint, queueOptions);
3814
3937
  } catch (cause) {
3815
3938
  const err = falSdkError(cause, ctx.model.id);
3816
- if (err.retryable) return void 0;
3939
+ if (ctx.call.maxRetries !== 0 && err.retryable) return void 0;
3817
3940
  throw err;
3818
3941
  }
3819
3942
  }, pollOptions);
@@ -3861,6 +3984,7 @@ async function passthroughVideoJob(ctx, req, endpoint, input) {
3861
3984
  const url = await checkStatus();
3862
3985
  return url ? { status: "succeeded" } : { status: "pending" };
3863
3986
  } catch (cause) {
3987
+ if (ctx.call.maxRetries === 0) throw cause;
3864
3988
  if (isModelKitError(cause) && !cause.retryable)
3865
3989
  return { status: "failed" };
3866
3990
  return { status: "pending" };
@@ -3880,11 +4004,11 @@ async function passthroughVideoJob(ctx, req, endpoint, input) {
3880
4004
  }
3881
4005
 
3882
4006
  // src/adapters/google-genai.ts
3883
- var import_zod9 = require("zod");
4007
+ var import_zod10 = require("zod");
3884
4008
  var import_genai = require("@google/genai");
3885
4009
 
3886
4010
  // src/adapters/google-files.ts
3887
- var import_zod8 = require("zod");
4011
+ var import_zod9 = require("zod");
3888
4012
  var GOOGLE_FILES_BASE = "https://generativelanguage.googleapis.com";
3889
4013
  var GOOGLE_FILES_POLL_INTERVAL_MS = 2e3;
3890
4014
  var GOOGLE_FILES_POLL_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -3894,17 +4018,17 @@ var GENERIC_MEDIA_TYPES = /* @__PURE__ */ new Set([
3894
4018
  "binary/octet-stream",
3895
4019
  "application/binary"
3896
4020
  ]);
3897
- var uploadedFileSchema = import_zod8.z.object({
3898
- file: import_zod8.z.object({
3899
- uri: import_zod8.z.string().optional(),
3900
- name: import_zod8.z.string().optional(),
3901
- state: import_zod8.z.string().optional(),
3902
- mimeType: import_zod8.z.string().optional()
4021
+ var uploadedFileSchema = import_zod9.z.object({
4022
+ file: import_zod9.z.object({
4023
+ uri: import_zod9.z.string().optional(),
4024
+ name: import_zod9.z.string().optional(),
4025
+ state: import_zod9.z.string().optional(),
4026
+ mimeType: import_zod9.z.string().optional()
3903
4027
  }).optional()
3904
4028
  });
3905
- var fileStateSchema = import_zod8.z.object({
3906
- state: import_zod8.z.string().optional(),
3907
- error: import_zod8.z.object({ message: import_zod8.z.string().optional() }).optional()
4029
+ var fileStateSchema = import_zod9.z.object({
4030
+ state: import_zod9.z.string().optional(),
4031
+ error: import_zod9.z.object({ message: import_zod9.z.string().optional() }).optional()
3908
4032
  });
3909
4033
  function resolveMime(declared, fallback) {
3910
4034
  const clean = declared?.split(";")[0]?.trim().toLowerCase();
@@ -4038,7 +4162,7 @@ async function waitForActive(fileName, opts) {
4038
4162
  }
4039
4163
  return void 0;
4040
4164
  }
4041
- if (res.status === 429 || res.status >= 500) return void 0;
4165
+ if (opts.maxRetries !== 0 && (res.status === 429 || res.status >= 500)) return void 0;
4042
4166
  const text2 = await res.text().catch(() => "");
4043
4167
  throw classifyHttpError(res.status, text2, "google-genai", opts.model);
4044
4168
  }, pollOptions);
@@ -4062,8 +4186,7 @@ async function uploadGoogleFile(source, opts) {
4062
4186
  opts.model
4063
4187
  );
4064
4188
  if (bytes.length > GOOGLE_FILES_MAX_BYTES) throw oversizeError(bytes.length, label, opts.model);
4065
- const retryOptions = { attempts: 3 };
4066
- if (opts.signal !== void 0) retryOptions.signal = opts.signal;
4189
+ const retryOptions = mediaRetryOptions(opts, opts.signal);
4067
4190
  const uploaded = await withRetry(() => startAndUpload(bytes, mimeType, opts), retryOptions);
4068
4191
  if (uploaded.state !== "ACTIVE") {
4069
4192
  try {
@@ -4078,7 +4201,12 @@ async function uploadGoogleFile(source, opts) {
4078
4201
 
4079
4202
  // src/adapters/google-genai.ts
4080
4203
  function defaultCreateGenAIClient(opts) {
4081
- const sdk = new import_genai.GoogleGenAI({ ...opts, vertexai: false });
4204
+ const sdk = new import_genai.GoogleGenAI({
4205
+ apiKey: opts.apiKey,
4206
+ vertexai: false,
4207
+ ...opts.maxRetries !== void 0 ? { httpOptions: { retryOptions: { attempts: 1 } } } : {}
4208
+ });
4209
+ const interactionOptions = opts.maxRetries === void 0 ? void 0 : { maxRetries: 0, ...opts.signal !== void 0 ? { signal: opts.signal } : {} };
4082
4210
  return {
4083
4211
  models: {
4084
4212
  generateVideos: async (body) => {
@@ -4099,11 +4227,11 @@ function defaultCreateGenAIClient(opts) {
4099
4227
  interactions: {
4100
4228
  create: async (args) => {
4101
4229
  const params = args;
4102
- const response = await sdk.interactions.create(params);
4230
+ const response = await sdk.interactions.create(params, interactionOptions);
4103
4231
  return response;
4104
4232
  },
4105
4233
  get: async (jobId, params) => {
4106
- const response = await sdk.interactions.get(jobId, params);
4234
+ const response = await sdk.interactions.get(jobId, params, interactionOptions);
4107
4235
  return response;
4108
4236
  }
4109
4237
  }
@@ -4117,7 +4245,7 @@ var OMNI_POLL_INTERVAL_MS = 1e4;
4117
4245
  var RESULT_TIMEOUT_MS2 = 15 * 60 * 1e3;
4118
4246
  var OMNI_INLINE_LIMIT_BYTES = 4 * 1024 * 1024;
4119
4247
  var MEDIA_PART_INLINE_LIMIT_BYTES = 20 * 1024 * 1024;
4120
- var errorTextSchema = import_zod9.z.string();
4248
+ var errorTextSchema = import_zod10.z.string();
4121
4249
  function isGoogleGenaiVideoKnown(providerModelId) {
4122
4250
  return providerModelId.startsWith("veo-") || providerModelId.startsWith("gemini-omni");
4123
4251
  }
@@ -4272,7 +4400,11 @@ async function generateVeoVideo(req, ctx, createGenAIClient) {
4272
4400
  referenceType: "ASSET"
4273
4401
  }));
4274
4402
  }
4275
- const client2 = createGenAIClient({ apiKey });
4403
+ const client2 = createGenAIClient({
4404
+ apiKey,
4405
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {},
4406
+ ...ctx.signal !== void 0 ? { signal: ctx.signal } : {}
4407
+ });
4276
4408
  const config = { durationSeconds: duration, personGeneration };
4277
4409
  if (req.aspectRatio !== void 0) config.aspectRatio = req.aspectRatio;
4278
4410
  if (req.resolution !== void 0) config.resolution = req.resolution;
@@ -4285,8 +4417,7 @@ async function generateVeoVideo(req, ctx, createGenAIClient) {
4285
4417
  config
4286
4418
  };
4287
4419
  if (image !== void 0) requestBody.image = image;
4288
- const retryOptions = { attempts: 3 };
4289
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
4420
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4290
4421
  let operation;
4291
4422
  try {
4292
4423
  operation = await withRetry(async () => {
@@ -4399,7 +4530,11 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4399
4530
  if (omniResolution !== void 0) responseFormat.resolution = omniResolution;
4400
4531
  }
4401
4532
  if (req.durationSeconds !== void 0) responseFormat.duration = `${req.durationSeconds}s`;
4402
- const client2 = createGenAIClient({ apiKey });
4533
+ const client2 = createGenAIClient({
4534
+ apiKey,
4535
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {},
4536
+ ...ctx.signal !== void 0 ? { signal: ctx.signal } : {}
4537
+ });
4403
4538
  const uploadedByUri = /* @__PURE__ */ new Map();
4404
4539
  const uploadedNames = [];
4405
4540
  const uploadOne = async (kind, bytes, mime) => {
@@ -4410,6 +4545,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4410
4545
  label: "gemini-omni"
4411
4546
  };
4412
4547
  if (ctx.signal !== void 0) uploadOptions.signal = ctx.signal;
4548
+ if (ctx.call.maxRetries !== void 0) uploadOptions.maxRetries = ctx.call.maxRetries;
4413
4549
  const file = await uploadGoogleFile({ bytes, mime }, uploadOptions);
4414
4550
  uploadedByUri.set(file.fileUri, { type: kind, bytes, mime: file.mimeType });
4415
4551
  uploadedNames.push(file.fileName);
@@ -4425,8 +4561,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4425
4561
  generation_config: { video_config: { task } },
4426
4562
  store: true
4427
4563
  });
4428
- const createRetryOptions = { attempts: 3 };
4429
- if (ctx.signal !== void 0) createRetryOptions.signal = ctx.signal;
4564
+ const createRetryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4430
4565
  let interaction;
4431
4566
  try {
4432
4567
  const parts = [];
@@ -4496,7 +4631,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4496
4631
  }
4497
4632
  }, createRetryOptions);
4498
4633
  } catch (cause) {
4499
- if (uploadedByUri.size === 0 || !isFileReferenceRejected(cause))
4634
+ if (ctx.call.maxRetries !== void 0 || uploadedByUri.size === 0 || !isFileReferenceRejected(cause))
4500
4635
  throwSdkError(cause, modelId);
4501
4636
  const inlineParts = parts.map((part) => {
4502
4637
  if (part.uri === void 0) return part;
@@ -4606,9 +4741,12 @@ async function generateLyriaAudio(req, ctx, createGenAIClient) {
4606
4741
  const image = await resolveMedia(ref, ctx.fetch, ctx.signal, "image/jpeg", modelId);
4607
4742
  parts.push({ inlineData: { mimeType: image.mime, data: toBase64(image.bytes) } });
4608
4743
  }
4609
- const client2 = createGenAIClient({ apiKey });
4610
- const retryOptions = { attempts: 3 };
4611
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
4744
+ const client2 = createGenAIClient({
4745
+ apiKey,
4746
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {},
4747
+ ...ctx.signal !== void 0 ? { signal: ctx.signal } : {}
4748
+ });
4749
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4612
4750
  let response;
4613
4751
  try {
4614
4752
  response = await withRetry(async () => {
@@ -4670,6 +4808,7 @@ async function prepareGoogleMediaPart(ref, mediaType, ctx) {
4670
4808
  label: "media-part"
4671
4809
  };
4672
4810
  if (ctx.signal !== void 0) uploadOptions.signal = ctx.signal;
4811
+ if (ctx.call.maxRetries !== void 0) uploadOptions.maxRetries = ctx.call.maxRetries;
4673
4812
  const file = await uploadGoogleFile({ bytes: ref.bytes, mime: mediaType }, uploadOptions);
4674
4813
  return {
4675
4814
  type: "file",
@@ -4682,15 +4821,15 @@ async function prepareGoogleMediaPart(ref, mediaType, ctx) {
4682
4821
  // src/adapters/google-image.ts
4683
4822
  var import_google2 = require("@ai-sdk/google");
4684
4823
  var import_ai2 = require("ai");
4685
- var import_zod10 = require("zod");
4824
+ var import_zod11 = require("zod");
4686
4825
  var GEMINI_IMAGE_TIMEOUT_MS = 6e5;
4687
4826
  var defaultGoogleImageDeps = {
4688
4827
  createGoogleClient: (opts) => (0, import_google2.createGoogleGenerativeAI)(opts),
4689
4828
  runTextGeneration: (opts) => (0, import_ai2.generateText)(opts)
4690
4829
  };
4691
- var causeChainNodeSchema = import_zod10.z.object({
4692
- message: import_zod10.z.string().optional(),
4693
- cause: import_zod10.z.unknown().optional()
4830
+ var causeChainNodeSchema = import_zod11.z.object({
4831
+ message: import_zod11.z.string().optional(),
4832
+ cause: import_zod11.z.unknown().optional()
4694
4833
  });
4695
4834
  function extractBlockReason(cause) {
4696
4835
  let current = cause;
@@ -4758,8 +4897,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
4758
4897
  responseModalities: ["IMAGE"]
4759
4898
  };
4760
4899
  if (req.safetySettings !== void 0) googleOptions.safetySettings = req.safetySettings;
4761
- const retryOptions = {};
4762
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
4900
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4763
4901
  const result = await withRetry(async () => {
4764
4902
  const timeout = AbortSignal.timeout(GEMINI_IMAGE_TIMEOUT_MS);
4765
4903
  const signal = ctx.signal !== void 0 ? AbortSignal.any([ctx.signal, timeout]) : timeout;
@@ -4811,7 +4949,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
4811
4949
  var googleImageAdapter = createGoogleImageAdapter();
4812
4950
 
4813
4951
  // src/adapters/higgsfield.ts
4814
- var import_zod11 = require("zod");
4952
+ var import_zod12 = require("zod");
4815
4953
 
4816
4954
  // src/adapters/higgsfield-motions.ts
4817
4955
  var MOTION_MAP = {
@@ -5010,14 +5148,14 @@ function videoUsage3(ctx, req, duration) {
5010
5148
  if (req.durationSeconds !== void 0) event.durationSeconds = req.durationSeconds;
5011
5149
  return event;
5012
5150
  }
5013
- var klingCreateSchema = import_zod11.z.object({ status_url: import_zod11.z.string() });
5014
- var klingStatusSchema = import_zod11.z.object({
5015
- status: import_zod11.z.string().optional(),
5016
- video: import_zod11.z.object({ url: import_zod11.z.string().optional() }).optional(),
5151
+ var klingCreateSchema = import_zod12.z.object({ status_url: import_zod12.z.string() });
5152
+ var klingStatusSchema = import_zod12.z.object({
5153
+ status: import_zod12.z.string().optional(),
5154
+ video: import_zod12.z.object({ url: import_zod12.z.string().optional() }).optional(),
5017
5155
  error: JsonValueSchema.optional()
5018
5156
  });
5019
- var errorMessageSchema = import_zod11.z.object({ message: import_zod11.z.string().optional() });
5020
- var textValueSchema = import_zod11.z.string();
5157
+ var errorMessageSchema = import_zod12.z.object({ message: import_zod12.z.string().optional() });
5158
+ var textValueSchema = import_zod12.z.string();
5021
5159
  function klingErrorDetail(error) {
5022
5160
  if (error === void 0) return "unknown_error";
5023
5161
  const asText = textValueSchema.safeParse(error);
@@ -5066,8 +5204,7 @@ async function generateKlingVideo(req, ctx) {
5066
5204
  body.aspect_ratio = req.aspectRatio;
5067
5205
  if (req.lastFrame) body.last_image_url = refToUrl(req.lastFrame);
5068
5206
  const endpoint = klingEndpoint(ctx.model.providerModelId, ctx.model.id);
5069
- const retryOptions = {};
5070
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
5207
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
5071
5208
  const createRes = await withRetry(
5072
5209
  () => createRequest(ctx, endpoint, { method: "POST", body: JSON.stringify(body) }),
5073
5210
  retryOptions
@@ -5087,10 +5224,12 @@ async function generateKlingVideo(req, ctx) {
5087
5224
  let res;
5088
5225
  try {
5089
5226
  res = await ctx.fetch(statusUrl, requestInit(ctx, { method: "GET" }));
5090
- } catch {
5227
+ } catch (cause) {
5228
+ if (ctx.call.maxRetries === 0) throw classifyThrown("higgsfield", cause, ctx.model.id);
5091
5229
  return void 0;
5092
5230
  }
5093
- if (res.status === 429 || res.status >= 500) return void 0;
5231
+ if (ctx.call.maxRetries !== 0 && (res.status === 429 || res.status >= 500))
5232
+ return void 0;
5094
5233
  if (!res.ok) {
5095
5234
  throw classifyHttpError(res.status, await readBody(res), "higgsfield", ctx.model.id);
5096
5235
  }
@@ -5132,6 +5271,7 @@ async function generateKlingVideo(req, ctx) {
5132
5271
  const url = await check();
5133
5272
  return url ? { status: "succeeded" } : { status: "pending" };
5134
5273
  } catch (cause) {
5274
+ if (ctx.call.maxRetries === 0) throw cause;
5135
5275
  if (isModelKitError(cause) && !cause.retryable) return { status: "failed" };
5136
5276
  throw cause;
5137
5277
  }
@@ -5151,8 +5291,8 @@ async function generateKlingVideo(req, ctx) {
5151
5291
  }
5152
5292
  };
5153
5293
  }
5154
- var dopMotionOptionsSchema = import_zod11.z.object({
5155
- modelkit: import_zod11.z.object({ motion: import_zod11.z.string().optional() }).optional()
5294
+ var dopMotionOptionsSchema = import_zod12.z.object({
5295
+ modelkit: import_zod12.z.object({ motion: import_zod12.z.string().optional() }).optional()
5156
5296
  });
5157
5297
  function dopMotionId(ctx) {
5158
5298
  const parsed = dopMotionOptionsSchema.safeParse(ctx.model.providerOptions);
@@ -5168,7 +5308,7 @@ function dopMotionId(ctx) {
5168
5308
  });
5169
5309
  return id;
5170
5310
  }
5171
- var jsonRecordSchema = import_zod11.z.record(import_zod11.z.string(), JsonValueSchema);
5311
+ var jsonRecordSchema = import_zod12.z.record(import_zod12.z.string(), JsonValueSchema);
5172
5312
  var DOP_URL_KEYS = ["url", "video_url", "output_url", "result_url", "download_url"];
5173
5313
  var DOP_NESTED_KEYS = ["video", "result", "results"];
5174
5314
  function dopUrl(body) {
@@ -5196,8 +5336,8 @@ function dopUrl(body) {
5196
5336
  }
5197
5337
  return void 0;
5198
5338
  }
5199
- var dopCreateSchema = import_zod11.z.object({ id: import_zod11.z.string() });
5200
- var dopStatusSchema = import_zod11.z.object({ status: import_zod11.z.string().optional() });
5339
+ var dopCreateSchema = import_zod12.z.object({ id: import_zod12.z.string() });
5340
+ var dopStatusSchema = import_zod12.z.object({ status: import_zod12.z.string().optional() });
5201
5341
  async function generateDopVideo(req, ctx) {
5202
5342
  const firstFrame = req.firstFrame ? refToUrl(req.firstFrame) : void 0;
5203
5343
  if (!firstFrame) {
@@ -5222,8 +5362,7 @@ async function generateDopVideo(req, ctx) {
5222
5362
  params.input_images_end = [{ type: "image_url", image_url: refToUrl(req.lastFrame) }];
5223
5363
  }
5224
5364
  if (req.seed !== void 0) params.seed = req.seed;
5225
- const retryOptions = {};
5226
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
5365
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
5227
5366
  const createRes = await withRetry(
5228
5367
  () => createRequest(ctx, DOP_ENDPOINT, {
5229
5368
  method: "POST",
@@ -5247,10 +5386,18 @@ async function generateDopVideo(req, ctx) {
5247
5386
  let res;
5248
5387
  try {
5249
5388
  res = await ctx.fetch(statusUrl, requestInit(ctx, { method: "GET" }));
5250
- } catch {
5389
+ } catch (cause) {
5390
+ if (ctx.call.maxRetries === 0) throw classifyThrown("higgsfield", cause, ctx.model.id);
5251
5391
  return void 0;
5252
5392
  }
5253
5393
  if (!res.ok) {
5394
+ if (ctx.call.maxRetries === 0)
5395
+ throw classifyHttpError(
5396
+ res.status,
5397
+ await readBody(res),
5398
+ "higgsfield",
5399
+ ctx.model.id
5400
+ );
5254
5401
  return void 0;
5255
5402
  }
5256
5403
  const payload = JsonValueSchema.parse(await res.json());
@@ -5287,6 +5434,7 @@ async function generateDopVideo(req, ctx) {
5287
5434
  const url = await check();
5288
5435
  return url ? { status: "succeeded" } : { status: "pending" };
5289
5436
  } catch (cause) {
5437
+ if (ctx.call.maxRetries === 0) throw cause;
5290
5438
  if (isModelKitError(cause) && !cause.retryable) return { status: "failed" };
5291
5439
  throw cause;
5292
5440
  }
@@ -5317,7 +5465,7 @@ var higgsfieldAdapter = {
5317
5465
 
5318
5466
  // src/adapters/openai-image.ts
5319
5467
  var import_openai2 = __toESM(require("openai"), 1);
5320
- var import_zod12 = require("zod");
5468
+ var import_zod13 = require("zod");
5321
5469
  var MAX_EDIT_REFERENCES = 16;
5322
5470
  function aspectRatioToSize(ratio, tier) {
5323
5471
  const TIER_LONG_EDGE = {
@@ -5400,9 +5548,9 @@ function toProviderError2(cause, ctx) {
5400
5548
  ctx.model.id
5401
5549
  );
5402
5550
  }
5403
- var openaiUsageSchema = import_zod12.z.object({
5404
- input_tokens: import_zod12.z.number().optional(),
5405
- output_tokens: import_zod12.z.number().optional()
5551
+ var openaiUsageSchema = import_zod13.z.object({
5552
+ input_tokens: import_zod13.z.number().optional(),
5553
+ output_tokens: import_zod13.z.number().optional()
5406
5554
  });
5407
5555
  var openaiImageAdapter = {
5408
5556
  id: "openai-image",
@@ -5444,8 +5592,7 @@ var openaiImageAdapter = {
5444
5592
  }
5445
5593
  const format = outputFormat !== void 0 ? { output_format: outputFormat } : {};
5446
5594
  const mime = outputFormat === "jpeg" ? "image/jpeg" : "image/png";
5447
- const retryOptions = {};
5448
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
5595
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
5449
5596
  const response = await withRetry(async () => {
5450
5597
  try {
5451
5598
  if (!isEdit) {
@@ -5765,13 +5912,7 @@ async function generateProdiaImage(req, ctx) {
5765
5912
  })
5766
5913
  );
5767
5914
  });
5768
- const retryOpts = {
5769
- attempts: 3,
5770
- baseDelayMs: 1e3,
5771
- factor: 2,
5772
- maxDelayMs: 1e4
5773
- };
5774
- if (ctx.signal !== void 0) retryOpts.signal = ctx.signal;
5915
+ const retryOpts = mediaRetryOptions(ctx.call, ctx.signal);
5775
5916
  let res;
5776
5917
  try {
5777
5918
  res = await withRetry(async () => {
@@ -5818,7 +5959,66 @@ var prodiaAdapter = {
5818
5959
 
5819
5960
  // src/adapters/replicate.ts
5820
5961
  var import_replicate = __toESM(require("replicate"), 1);
5821
- var import_zod13 = require("zod");
5962
+
5963
+ // src/adapters/replicate-http.ts
5964
+ var import_zod14 = require("zod");
5965
+ var predictionSchema = import_zod14.z.object({
5966
+ id: import_zod14.z.string(),
5967
+ status: import_zod14.z.string(),
5968
+ output: JsonValueSchema.optional(),
5969
+ error: JsonValueSchema.optional(),
5970
+ metrics: import_zod14.z.object({ predict_time: import_zod14.z.number().optional() }).optional()
5971
+ });
5972
+ function createReplicateHttpClient(opts) {
5973
+ async function request(path, body, signal) {
5974
+ let response;
5975
+ try {
5976
+ response = await opts.fetch(`https://api.replicate.com/v1${path}`, {
5977
+ method: body === void 0 ? "GET" : "POST",
5978
+ headers: {
5979
+ Authorization: `Bearer ${opts.auth}`,
5980
+ "Content-Type": "application/json"
5981
+ },
5982
+ ...body !== void 0 ? { body: JSON.stringify(body) } : {},
5983
+ ...signal !== void 0 ? { signal } : {}
5984
+ });
5985
+ } catch (cause) {
5986
+ throw classifyThrown("replicate", cause);
5987
+ }
5988
+ if (!response.ok)
5989
+ throw classifyHttpError(response.status, await response.text(), "replicate");
5990
+ const parsed = predictionSchema.parse(await response.json());
5991
+ return {
5992
+ id: parsed.id,
5993
+ status: parsed.status,
5994
+ ...parsed.output !== void 0 ? { output: parsed.output } : {},
5995
+ ...parsed.error !== void 0 ? { error: parsed.error } : {},
5996
+ ...parsed.metrics?.predict_time !== void 0 ? { metrics: { predict_time: parsed.metrics.predict_time } } : {}
5997
+ };
5998
+ }
5999
+ return {
6000
+ predictions: {
6001
+ create(options) {
6002
+ if (options.version) {
6003
+ return request(
6004
+ "/predictions",
6005
+ { input: options.input, version: options.version },
6006
+ options.signal
6007
+ );
6008
+ }
6009
+ return request(
6010
+ `/models/${options.model}/predictions`,
6011
+ { input: options.input },
6012
+ options.signal
6013
+ );
6014
+ },
6015
+ get: (id, options) => request(`/predictions/${encodeURIComponent(id)}`, void 0, options?.signal)
6016
+ }
6017
+ };
6018
+ }
6019
+
6020
+ // src/adapters/replicate.ts
6021
+ var import_zod15 = require("zod");
5822
6022
 
5823
6023
  // src/adapters/input-spec-mapper.ts
5824
6024
  function canonicalValue(req, key) {
@@ -5857,7 +6057,7 @@ function applyInputSpec(spec, req, refToUrl2, opts) {
5857
6057
  var POLL_INTERVAL_MS = 1e3;
5858
6058
  var POLL_TIMEOUT_MS = 15 * 6e4;
5859
6059
  var defaultReplicateDeps = {
5860
- createReplicateClient: (opts) => new import_replicate.default(opts)
6060
+ createReplicateClient: (opts) => opts.maxRetries === void 0 ? new import_replicate.default(opts) : createReplicateHttpClient(opts)
5861
6061
  };
5862
6062
  function createReplicateAdapter(deps = defaultReplicateDeps) {
5863
6063
  return {
@@ -5879,7 +6079,11 @@ function client(ctx, deps) {
5879
6079
  retryable: false
5880
6080
  });
5881
6081
  }
5882
- return deps.createReplicateClient({ auth: token, fetch: ctx.fetch });
6082
+ return deps.createReplicateClient({
6083
+ auth: token,
6084
+ fetch: ctx.fetch,
6085
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {}
6086
+ });
5883
6087
  }
5884
6088
  function route(providerModelId) {
5885
6089
  if (providerModelId.includes(":")) {
@@ -5889,8 +6093,8 @@ function route(providerModelId) {
5889
6093
  if (!providerModelId.includes("/")) return { version: providerModelId };
5890
6094
  return { model: providerModelId };
5891
6095
  }
5892
- var replicateResponseStatusSchema = import_zod13.z.object({
5893
- response: import_zod13.z.object({ status: import_zod13.z.number() }).partial()
6096
+ var replicateResponseStatusSchema = import_zod15.z.object({
6097
+ response: import_zod15.z.object({ status: import_zod15.z.number() }).partial()
5894
6098
  });
5895
6099
  function replicateError(cause, ctx) {
5896
6100
  if (isModelKitError(cause)) return cause;
@@ -5917,7 +6121,7 @@ function isUrlFn(value) {
5917
6121
  function extractOutputUrl(output) {
5918
6122
  const root = Array.isArray(output) ? output[0] : output;
5919
6123
  if (root === void 0) throw noOutput();
5920
- const asString = import_zod13.z.string().safeParse(root);
6124
+ const asString = import_zod15.z.string().safeParse(root);
5921
6125
  if (asString.success && asString.data) return asString.data;
5922
6126
  if (root instanceof URL) return root.href;
5923
6127
  if (isObjectOutput(root)) {
@@ -5926,15 +6130,15 @@ function extractOutputUrl(output) {
5926
6130
  if (urlValue !== void 0 && isUrlFn(urlValue)) {
5927
6131
  const called = urlValue();
5928
6132
  if (called instanceof URL) return called.href;
5929
- const calledString = import_zod13.z.string().safeParse(called);
6133
+ const calledString = import_zod15.z.string().safeParse(called);
5930
6134
  if (calledString.success && calledString.data) return calledString.data;
5931
6135
  } else {
5932
- const direct = import_zod13.z.string().safeParse(urlValue);
6136
+ const direct = import_zod15.z.string().safeParse(urlValue);
5933
6137
  if (direct.success && direct.data) return direct.data;
5934
6138
  }
5935
6139
  }
5936
6140
  if ("default" in root) {
5937
- const fallback = import_zod13.z.string().safeParse(root.default);
6141
+ const fallback = import_zod15.z.string().safeParse(root.default);
5938
6142
  if (fallback.success && fallback.data) return fallback.data;
5939
6143
  }
5940
6144
  }
@@ -5964,7 +6168,7 @@ async function runPrediction(ctx, input, deps) {
5964
6168
  throw replicateError(cause, ctx);
5965
6169
  }
5966
6170
  },
5967
- { attempts: 1 }
6171
+ mediaRetryOptions(ctx.call, ctx.signal, 1)
5968
6172
  );
5969
6173
  } catch (cause) {
5970
6174
  throw replicateError(cause, ctx);
@@ -5995,7 +6199,7 @@ async function runPrediction(ctx, input, deps) {
5995
6199
  }
5996
6200
  return void 0;
5997
6201
  }, pollOpts);
5998
- const predictTime = import_zod13.z.number().safeParse(done.metrics?.predict_time);
6202
+ const predictTime = import_zod15.z.number().safeParse(done.metrics?.predict_time);
5999
6203
  if (done.output === void 0) throw noOutput();
6000
6204
  return {
6001
6205
  url: extractOutputUrl(done.output),
@@ -6363,7 +6567,7 @@ async function generateReplicateVideo(req, ctx, deps) {
6363
6567
  throw replicateError(cause, ctx);
6364
6568
  }
6365
6569
  },
6366
- { attempts: 1 }
6570
+ mediaRetryOptions(ctx.call, ctx.signal, 1)
6367
6571
  );
6368
6572
  } catch (cause) {
6369
6573
  throw replicateError(cause, ctx);
@@ -6380,7 +6584,7 @@ async function generateReplicateVideo(req, ctx, deps) {
6380
6584
  throw replicateError(cause, ctx);
6381
6585
  }
6382
6586
  if (current.status === "succeeded") {
6383
- const predictTime = import_zod13.z.number().safeParse(current.metrics?.predict_time);
6587
+ const predictTime = import_zod15.z.number().safeParse(current.metrics?.predict_time);
6384
6588
  if (current.output === void 0) throw noOutput();
6385
6589
  return {
6386
6590
  url: extractOutputUrl(current.output),
@@ -6521,7 +6725,7 @@ async function generateReplicateAudio(req, ctx, deps) {
6521
6725
  // src/adapters/xai-video.ts
6522
6726
  var import_ai3 = require("ai");
6523
6727
  var import_xai2 = require("@ai-sdk/xai");
6524
- var import_zod14 = require("zod");
6728
+ var import_zod16 = require("zod");
6525
6729
  var POLL_INTERVAL_MS2 = 1e4;
6526
6730
  var POLL_TIMEOUT_MS2 = 15 * 6e4;
6527
6731
  var defaultXaiDeps = {
@@ -6534,8 +6738,8 @@ function createXaiVideoAdapter(deps = defaultXaiDeps) {
6534
6738
  };
6535
6739
  }
6536
6740
  var xaiVideoAdapter = createXaiVideoAdapter();
6537
- var xaiResponseStatusSchema = import_zod14.z.object({
6538
- response: import_zod14.z.object({ status: import_zod14.z.number() }).partial()
6741
+ var xaiResponseStatusSchema = import_zod16.z.object({
6742
+ response: import_zod16.z.object({ status: import_zod16.z.number() }).partial()
6539
6743
  });
6540
6744
  function xaiError(cause, ctx) {
6541
6745
  const info = describeThrown(cause);
@@ -6543,12 +6747,12 @@ function xaiError(cause, ctx) {
6543
6747
  const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
6544
6748
  return classifyThrown("xai-video", cause, ctx.model.id, { status, body: info.body });
6545
6749
  }
6546
- var xaiMetaSchema = import_zod14.z.object({
6750
+ var xaiMetaSchema = import_zod16.z.object({
6547
6751
  videoUrl: JsonValueSchema.optional(),
6548
6752
  costInUsdTicks: JsonValueSchema.optional(),
6549
6753
  duration: JsonValueSchema.optional()
6550
6754
  });
6551
- var xaiProviderMetadataSchema = import_zod14.z.object({ xai: xaiMetaSchema });
6755
+ var xaiProviderMetadataSchema = import_zod16.z.object({ xai: xaiMetaSchema });
6552
6756
  function metaOf(result) {
6553
6757
  const parsed = xaiProviderMetadataSchema.partial().safeParse(result.providerMetadata);
6554
6758
  if (!parsed.success) return {};
@@ -6599,6 +6803,7 @@ async function generateXaiVideo(req, ctx, deps) {
6599
6803
  }
6600
6804
  if (req.durationSeconds !== void 0) callBody.duration = req.durationSeconds;
6601
6805
  if (ctx.signal) callBody.abortSignal = ctx.signal;
6806
+ if (ctx.call.maxRetries !== void 0) callBody.maxRetries = ctx.call.maxRetries;
6602
6807
  const pending = (async () => {
6603
6808
  try {
6604
6809
  return await client2.generateVideo(callBody);
@@ -6655,7 +6860,7 @@ async function mapResult(ctx, req, result) {
6655
6860
  };
6656
6861
  }
6657
6862
  const meta = metaOf(result);
6658
- const videoUrl = import_zod14.z.string().safeParse(meta.videoUrl);
6863
+ const videoUrl = import_zod16.z.string().safeParse(meta.videoUrl);
6659
6864
  if (videoUrl.success && videoUrl.data) {
6660
6865
  const res = await ctx.fetch(videoUrl.data);
6661
6866
  if (!res.ok) {
@@ -6678,7 +6883,7 @@ async function mapResult(ctx, req, result) {
6678
6883
  });
6679
6884
  }
6680
6885
  function usage(ctx, req, meta) {
6681
- const costTicks = import_zod14.z.number().safeParse(meta.costInUsdTicks);
6886
+ const costTicks = import_zod16.z.number().safeParse(meta.costInUsdTicks);
6682
6887
  const cost = costTicks.success ? costTicks.data / 1e10 : void 0;
6683
6888
  const event = {
6684
6889
  model: ctx.model.id,
@@ -6811,22 +7016,22 @@ var liveState = store[KEY] ??= {
6811
7016
  var liveCatalog = liveState.catalog;
6812
7017
 
6813
7018
  // src/catalog/load.ts
6814
- var import_zod15 = require("zod");
7019
+ var import_zod17 = require("zod");
6815
7020
  function rowCount() {
6816
7021
  return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
6817
7022
  }
6818
7023
  function authHeaders(auth) {
6819
7024
  return "bearer" in auth ? { Authorization: `Bearer ${auth.bearer}` } : { "x-api-key": auth.apiKey };
6820
7025
  }
6821
- var EnvelopeSchema = import_zod15.z.object({
6822
- rows: import_zod15.z.array(JsonValueSchema),
6823
- revision: import_zod15.z.string().optional()
7026
+ var EnvelopeSchema = import_zod17.z.object({
7027
+ rows: import_zod17.z.array(JsonValueSchema),
7028
+ revision: import_zod17.z.string().optional()
6824
7029
  });
6825
7030
  function dropReason(path, message) {
6826
7031
  return path.length === 0 ? message : `${path.map((part) => String(part)).join(".")} ${message}`;
6827
7032
  }
6828
7033
  function rowId(raw) {
6829
- const parsed = import_zod15.z.object({ id: import_zod15.z.string().min(1) }).loose().safeParse(raw);
7034
+ const parsed = import_zod17.z.object({ id: import_zod17.z.string().min(1) }).loose().safeParse(raw);
6830
7035
  if (!parsed.success) return "?";
6831
7036
  return parsed.data.id;
6832
7037
  }
@@ -7579,7 +7784,7 @@ function createTextSteps(initial, resolve, callerProviderOptions) {
7579
7784
 
7580
7785
  // src/client.ts
7581
7786
  var import_ai5 = require("ai");
7582
- var import_zod16 = require("zod");
7787
+ var import_zod18 = require("zod");
7583
7788
 
7584
7789
  // src/generated-image.ts
7585
7790
  function toGeneratedImage(image) {
@@ -7654,10 +7859,10 @@ function textAbortOptions(sdk, context) {
7654
7859
  if (abortSignal) return { abortSignal };
7655
7860
  return {};
7656
7861
  }
7657
- var catalogId = import_zod16.z.string();
7658
- var exactSize = import_zod16.z.templateLiteral([import_zod16.z.number(), "x", import_zod16.z.number()]);
7659
- var sdkRatio = import_zod16.z.templateLiteral([import_zod16.z.number(), ":", import_zod16.z.number()]);
7660
- var sizeTier = import_zod16.z.enum(["512", "1K", "2K", "4K"]);
7862
+ var catalogId = import_zod18.z.string();
7863
+ var exactSize = import_zod18.z.templateLiteral([import_zod18.z.number(), "x", import_zod18.z.number()]);
7864
+ var sdkRatio = import_zod18.z.templateLiteral([import_zod18.z.number(), ":", import_zod18.z.number()]);
7865
+ var sizeTier = import_zod18.z.enum(["512", "1K", "2K", "4K"]);
7661
7866
  function isCatalogId(model) {
7662
7867
  return catalogId.safeParse(model).success;
7663
7868
  }
@@ -7848,6 +8053,7 @@ function createModelKit(config, adapters) {
7848
8053
  logCoercions(logger, model.modelId, warnings);
7849
8054
  const abortSignal = combineSignals(req.abortSignal, call.signal);
7850
8055
  if (abortSignal) options.abortSignal = abortSignal;
8056
+ if (call.maxRetries !== void 0) options.maxRetries = call.maxRetries;
7851
8057
  const result = await (0, import_ai5.generateImage)(options);
7852
8058
  const images = result.images.map(
7853
8059
  (file) => toGeneratedImage({ bytes: file.uint8Array, mime: file.mediaType })
@@ -7887,6 +8093,7 @@ function createModelKit(config, adapters) {
7887
8093
  const seconds = duration ?? durationSeconds;
7888
8094
  const abortSignal = combineSignals(req.abortSignal, call.signal);
7889
8095
  const options = { model, prompt };
8096
+ if (call.maxRetries !== void 0) options.maxRetries = call.maxRetries;
7890
8097
  const warnings = [];
7891
8098
  const ratio = sdkAspectRatio(aspectRatio) ?? (aspectRatio === "adaptive" ? "adaptive" : void 0);
7892
8099
  if (ratio) options.aspectRatio = ratio;
@@ -7968,6 +8175,7 @@ function createModelKit(config, adapters) {
7968
8175
  catalog,
7969
8176
  describe: (id) => catalog.require(id),
7970
8177
  async generateImage(req, call = {}) {
8178
+ mediaRetryOptions(call);
7971
8179
  if (!isCatalogId(req.model)) {
7972
8180
  return passthroughImage({ ...req, model: req.model }, call);
7973
8181
  }
@@ -8011,6 +8219,7 @@ function createModelKit(config, adapters) {
8011
8219
  return { ...result, usage: usage2, image: first, images, warnings };
8012
8220
  },
8013
8221
  async generateVideo(req, call = {}) {
8222
+ mediaRetryOptions(call);
8014
8223
  if (!isCatalogId(req.model)) {
8015
8224
  return passthroughVideo({ ...req, model: req.model }, call);
8016
8225
  }
@@ -8065,6 +8274,7 @@ function createModelKit(config, adapters) {
8065
8274
  };
8066
8275
  },
8067
8276
  async generateAudio(req, call = {}) {
8277
+ mediaRetryOptions(call);
8068
8278
  const model = catalog.require(req.model);
8069
8279
  if (model.type !== "audio") {
8070
8280
  throw new ModelKitError({
@@ -8094,6 +8304,7 @@ function createModelKit(config, adapters) {
8094
8304
  return result;
8095
8305
  },
8096
8306
  async prepareMediaPart(modelId, ref, mediaType, call = {}) {
8307
+ mediaRetryOptions(call);
8097
8308
  const model = catalog.require(modelId);
8098
8309
  const { adapter, ctx } = context(model, call, []);
8099
8310
  const fileStore = model.adapter === "ai-sdk-text" && textKeyName(model) === "google" ? adapters["google-genai"] : adapter;