@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.js CHANGED
@@ -137,7 +137,9 @@ function normalizeExposure(value) {
137
137
  if (value === "catalog") return ["cowork", "space_builder"];
138
138
  if (value === "internal") return [];
139
139
  if (Array.isArray(value)) {
140
- if (value.every((entry) => SURFACES.includes(entry))) {
140
+ if (value.every(
141
+ (entry) => SURFACES.includes(entry)
142
+ )) {
141
143
  const present = new Set(value);
142
144
  return SURFACES.filter((surface) => present.has(surface));
143
145
  }
@@ -2678,6 +2680,19 @@ function shouldRetry(err) {
2678
2680
  if (/ECONNRESET|ETIMEDOUT|fetch failed|socket hang up/i.test(err.message)) return true;
2679
2681
  return false;
2680
2682
  }
2683
+ function mediaRetryOptions(call, signal, defaultAttempts = 3) {
2684
+ if (call.maxRetries !== void 0 && (!Number.isSafeInteger(call.maxRetries + 1) || call.maxRetries < 0)) {
2685
+ throw new ModelKitError({
2686
+ code: "unsupported_option",
2687
+ message: "maxRetries must be a non-negative safe integer",
2688
+ retryable: false
2689
+ });
2690
+ }
2691
+ return {
2692
+ attempts: call.maxRetries === void 0 ? defaultAttempts : call.maxRetries + 1,
2693
+ ...signal !== void 0 ? { signal } : {}
2694
+ };
2695
+ }
2681
2696
  async function withRetry(fn, opts = {}) {
2682
2697
  const attempts = opts.attempts ?? 3;
2683
2698
  const base = opts.baseDelayMs ?? 1e3;
@@ -2685,6 +2700,7 @@ async function withRetry(fn, opts = {}) {
2685
2700
  const factor = opts.factor ?? 2;
2686
2701
  let last;
2687
2702
  for (let attempt = 1; attempt <= attempts; attempt++) {
2703
+ if (opts.signal?.aborted) throw throwAborted();
2688
2704
  try {
2689
2705
  return await fn(attempt);
2690
2706
  } catch (cause) {
@@ -2797,11 +2813,11 @@ async function readBody(res) {
2797
2813
  return text2;
2798
2814
  }
2799
2815
  }
2800
- async function mediaRefToBytes(ref, fetch, options = {}) {
2816
+ async function mediaRefToBytes(ref, fetch2, options = {}) {
2801
2817
  if (!isUrlRef(ref)) return { bytes: ref.bytes, mime: ref.mime };
2802
2818
  const init = {};
2803
2819
  if (options.signal !== void 0) init.signal = options.signal;
2804
- const res = await fetch(ref.url, init);
2820
+ const res = await fetch2(ref.url, init);
2805
2821
  if (!res.ok) {
2806
2822
  const text2 = await res.text().catch(() => "");
2807
2823
  throw classifyHttpError(
@@ -2938,11 +2954,6 @@ var SeedreamResponseSchema = z6.object({
2938
2954
  data: z6.array(SeedreamImageSchema).optional(),
2939
2955
  error: z6.object({ message: z6.string().optional(), code: z6.string().optional() }).optional()
2940
2956
  });
2941
- function retryOptsFor(ctx, attempts = 3) {
2942
- const opts = { attempts };
2943
- if (ctx.signal !== void 0) opts.signal = ctx.signal;
2944
- return opts;
2945
- }
2946
2957
  function fetchInitFor(ctx, init) {
2947
2958
  if (ctx.signal !== void 0) init.signal = ctx.signal;
2948
2959
  return init;
@@ -2980,20 +2991,23 @@ async function generateSeedreamImage(req, ctx) {
2980
2991
  const firstRef = refs[0];
2981
2992
  if (refs.length === 1 && firstRef !== void 0) body.image = firstRef;
2982
2993
  else if (refs.length > 1) body.image = refs;
2983
- const data = await withRetry(async () => {
2984
- const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}/images/generations`, {
2985
- method: "POST",
2986
- headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
2987
- body: JSON.stringify(body)
2988
- });
2989
- if (!res.ok) {
2990
- const text2 = await res.text().catch(() => "");
2991
- throwArkError(res.status, text2, modelId);
2992
- }
2993
- const parsed = SeedreamResponseSchema.safeParse(await res.json());
2994
- const decoded = parsed.success ? parsed.data : {};
2995
- return decoded;
2996
- }, retryOptsFor(ctx));
2994
+ const data = await withRetry(
2995
+ async () => {
2996
+ const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}/images/generations`, {
2997
+ method: "POST",
2998
+ headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
2999
+ body: JSON.stringify(body)
3000
+ });
3001
+ if (!res.ok) {
3002
+ const text2 = await res.text().catch(() => "");
3003
+ throwArkError(res.status, text2, modelId);
3004
+ }
3005
+ const parsed = SeedreamResponseSchema.safeParse(await res.json());
3006
+ const decoded = parsed.success ? parsed.data : {};
3007
+ return decoded;
3008
+ },
3009
+ mediaRetryOptions(ctx.call, ctx.signal)
3010
+ );
2997
3011
  const first = data.data?.[0];
2998
3012
  let bytes;
2999
3013
  if (first?.b64_json) {
@@ -3129,20 +3143,23 @@ async function generateSeedanceVideo(req, ctx) {
3129
3143
  if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
3130
3144
  if (req.seed !== void 0) body.seed = req.seed;
3131
3145
  if (req.watermark !== void 0) body.watermark = req.watermark;
3132
- const submit = await withRetry(async () => {
3133
- const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}`, {
3134
- method: "POST",
3135
- headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
3136
- body: JSON.stringify(body)
3137
- });
3138
- if (!res.ok) {
3139
- const text2 = await res.text().catch(() => "");
3140
- throwArkError(res.status, text2, modelId);
3141
- }
3142
- const parsed = SeedanceResponseSchema.safeParse(await res.json());
3143
- const decoded = parsed.success ? parsed.data : {};
3144
- return decoded;
3145
- }, retryOptsFor(ctx));
3146
+ const submit = await withRetry(
3147
+ async () => {
3148
+ const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}`, {
3149
+ method: "POST",
3150
+ headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
3151
+ body: JSON.stringify(body)
3152
+ });
3153
+ if (!res.ok) {
3154
+ const text2 = await res.text().catch(() => "");
3155
+ throwArkError(res.status, text2, modelId);
3156
+ }
3157
+ const parsed = SeedanceResponseSchema.safeParse(await res.json());
3158
+ const decoded = parsed.success ? parsed.data : {};
3159
+ return decoded;
3160
+ },
3161
+ mediaRetryOptions(ctx.call, ctx.signal)
3162
+ );
3146
3163
  if (!submit.id) throwArkError(void 0, "Seedance task create returned no id", modelId);
3147
3164
  const jobId = submit.id;
3148
3165
  const usage2 = seedanceUsage(ctx, req, taskType === "edit" ? requestedDuration : duration);
@@ -3151,7 +3168,8 @@ async function generateSeedanceVideo(req, ctx) {
3151
3168
  headers: { Authorization: `Bearer ${key}` }
3152
3169
  });
3153
3170
  if (!res.ok) {
3154
- if (res.status === 429 || res.status >= 500) return void 0;
3171
+ if (ctx.call.maxRetries !== 0 && (res.status === 429 || res.status >= 500))
3172
+ return void 0;
3155
3173
  const text2 = await res.text().catch(() => "");
3156
3174
  throwArkError(res.status, text2, modelId);
3157
3175
  }
@@ -3217,16 +3235,109 @@ async function generateSeedanceVideo(req, ctx) {
3217
3235
  }
3218
3236
 
3219
3237
  // src/adapters/fal.ts
3220
- import { z as z7 } from "zod";
3238
+ import { z as z8 } from "zod";
3221
3239
  import { createFalClient } from "@fal-ai/client";
3240
+
3241
+ // src/adapters/fal-http.ts
3242
+ import { z as z7 } from "zod";
3243
+ var queueUrl = z7.url().refine((value) => new URL(value).origin === "https://queue.fal.run");
3244
+ var submissionSchema = z7.object({
3245
+ request_id: z7.string(),
3246
+ status_url: queueUrl,
3247
+ response_url: queueUrl
3248
+ });
3249
+ var statusSchema = z7.object({ status: z7.string() });
3250
+ function createFalHttpClient(opts) {
3251
+ const jobs = /* @__PURE__ */ new Map();
3252
+ async function request(url, input, signal) {
3253
+ let response;
3254
+ try {
3255
+ response = await opts.fetch(url, {
3256
+ method: input === void 0 ? "GET" : "POST",
3257
+ headers: {
3258
+ Authorization: `Key ${opts.credentials}`,
3259
+ "Content-Type": "application/json"
3260
+ },
3261
+ ...input !== void 0 ? { body: JSON.stringify(input) } : {},
3262
+ ...signal !== void 0 ? { signal } : {}
3263
+ });
3264
+ } catch (cause) {
3265
+ throw classifyThrown("fal", cause);
3266
+ }
3267
+ if (!response.ok) throw classifyHttpError(response.status, await response.text(), "fal");
3268
+ return JsonValueSchema.parse(await response.json());
3269
+ }
3270
+ function job(id) {
3271
+ const saved = jobs.get(id);
3272
+ if (!saved)
3273
+ throw new ModelKitError({
3274
+ code: "provider_rejected",
3275
+ provider: "fal",
3276
+ message: "Unknown fal queue request"
3277
+ });
3278
+ return saved;
3279
+ }
3280
+ const queue = {
3281
+ async submit(endpoint, options) {
3282
+ const submitted = submissionSchema.parse(
3283
+ await request(
3284
+ `https://queue.fal.run/${endpoint}`,
3285
+ options.input,
3286
+ options.abortSignal
3287
+ )
3288
+ );
3289
+ jobs.set(submitted.request_id, submitted);
3290
+ return { requestId: submitted.request_id };
3291
+ },
3292
+ async status(_endpoint, options) {
3293
+ return statusSchema.parse(
3294
+ await request(job(options.requestId).status_url, void 0, options.abortSignal)
3295
+ );
3296
+ },
3297
+ result: (_endpoint, options) => request(job(options.requestId).response_url, void 0, options.abortSignal)
3298
+ };
3299
+ return {
3300
+ queue,
3301
+ async subscribe(endpoint, options) {
3302
+ const submitted = await withRetry(
3303
+ () => queue.submit(endpoint, options),
3304
+ mediaRetryOptions(opts, options.abortSignal)
3305
+ );
3306
+ return pollUntil(
3307
+ async () => {
3308
+ const readOptions = {
3309
+ requestId: submitted.requestId,
3310
+ ...options.abortSignal !== void 0 ? { abortSignal: options.abortSignal } : {}
3311
+ };
3312
+ const current = await queue.status(endpoint, readOptions);
3313
+ if (current.status !== "COMPLETED") return void 0;
3314
+ return queue.result(endpoint, readOptions);
3315
+ },
3316
+ {
3317
+ intervalMs: 1e3,
3318
+ timeoutMs: 18e4,
3319
+ ...options.abortSignal !== void 0 ? { signal: options.abortSignal } : {}
3320
+ }
3321
+ );
3322
+ }
3323
+ };
3324
+ }
3325
+
3326
+ // src/adapters/fal.ts
3222
3327
  var MUSE_T2I_ENDPOINT = "meta/muse-image/text-to-image";
3223
3328
  var MUSE_EDIT_ENDPOINT = "meta/muse-image/edit";
3224
3329
  var KLING_O1_ENDPOINT = "fal-ai/kling-video/o1/video-to-video/reference";
3225
3330
  var FAL_QUEUE_HOST = "https://queue.fal.run";
3226
3331
  var PASSTHROUGH_POLL_MS = 2e3;
3227
3332
  var PASSTHROUGH_MAX_WAIT_MS = 18e4;
3228
- var falSubscribePayloadSchema = z7.object({ data: JsonValueSchema });
3333
+ var falSubscribePayloadSchema = z8.object({ data: JsonValueSchema });
3229
3334
  function defaultCreateFalClient(opts) {
3335
+ if (opts.maxRetries !== void 0)
3336
+ return createFalHttpClient({
3337
+ credentials: opts.credentials,
3338
+ fetch: opts.fetch ?? fetch,
3339
+ maxRetries: opts.maxRetries
3340
+ });
3230
3341
  const client2 = createFalClient(opts);
3231
3342
  return {
3232
3343
  async subscribe(endpoint, options) {
@@ -3275,7 +3386,7 @@ function createFalAdapter(deps = defaultDeps) {
3275
3386
  };
3276
3387
  }
3277
3388
  var falAdapter = createFalAdapter();
3278
- var falDetailSchema = z7.object({ detail: JsonValueSchema });
3389
+ var falDetailSchema = z8.object({ detail: JsonValueSchema });
3279
3390
  function liftDetail(body) {
3280
3391
  const parsed = falDetailSchema.safeParse(body);
3281
3392
  const detail = parsed.success ? parsed.data.detail : void 0;
@@ -3284,11 +3395,11 @@ function liftDetail(body) {
3284
3395
  function falError(status, body, model) {
3285
3396
  return classifyHttpError(status, liftDetail(body), "fal", model);
3286
3397
  }
3287
- var falSdkThrownSchema = z7.object({
3288
- status: z7.number().optional(),
3289
- statusCode: z7.number().optional(),
3398
+ var falSdkThrownSchema = z8.object({
3399
+ status: z8.number().optional(),
3400
+ statusCode: z8.number().optional(),
3290
3401
  body: JsonValueSchema.optional(),
3291
- message: z7.string().optional()
3402
+ message: z8.string().optional()
3292
3403
  });
3293
3404
  function falSdkError(cause, model) {
3294
3405
  const parsed = falSdkThrownSchema.safeParse(cause);
@@ -3321,6 +3432,8 @@ function gatewayConfig(ctx) {
3321
3432
  };
3322
3433
  if (falKey) config.falKey = falKey;
3323
3434
  if (cfToken) config.cfToken = cfToken;
3435
+ if (ctx.call.maxRetries !== void 0) config.singleAttempt = true;
3436
+ if (ctx.signal !== void 0) config.signal = ctx.signal;
3324
3437
  return config;
3325
3438
  }
3326
3439
  async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
@@ -3328,16 +3441,18 @@ async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
3328
3441
  if (cfg.falKey) headers2.Authorization = `Bearer ${cfg.falKey}`;
3329
3442
  if (init.body) headers2["Content-Type"] = "application/json";
3330
3443
  if (cfg.cfToken) headers2["cf-aig-authorization"] = `Bearer ${cfg.cfToken}`;
3444
+ if (cfg.singleAttempt) headers2["cf-aig-max-attempts"] = "1";
3331
3445
  const request = { method: init.method, headers: headers2 };
3446
+ if (cfg.signal !== void 0) request.signal = cfg.signal;
3332
3447
  if (init.body !== void 0) request.body = init.body;
3333
3448
  return fetchImpl(cfg.baseUrl, request);
3334
3449
  }
3335
- var falQueueSubmitSchema = z7.object({
3336
- request_id: z7.string(),
3337
- status_url: z7.string(),
3338
- response_url: z7.string()
3450
+ var falQueueSubmitSchema = z8.object({
3451
+ request_id: z8.string(),
3452
+ status_url: z8.string(),
3453
+ response_url: z8.string()
3339
3454
  });
3340
- var falQueueStatusSchema = z7.object({ status: z7.string() });
3455
+ var falQueueStatusSchema = z8.object({ status: z8.string() });
3341
3456
  async function passthroughRequest(ctx, endpoint, input) {
3342
3457
  const cfg = gatewayConfig(ctx);
3343
3458
  const submitRes = await gatewayFetch(cfg, ctx.fetch, `${FAL_QUEUE_HOST}/${endpoint}`, {
@@ -3394,7 +3509,11 @@ function falClientOf(ctx, deps) {
3394
3509
  retryable: false
3395
3510
  });
3396
3511
  }
3397
- return deps.createFalClient({ credentials: falKey, fetch: ctx.fetch });
3512
+ return deps.createFalClient({
3513
+ credentials: falKey,
3514
+ fetch: ctx.fetch,
3515
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {}
3516
+ });
3398
3517
  }
3399
3518
  async function subscribe(ctx, deps, endpoint, input) {
3400
3519
  const client2 = falClientOf(ctx, deps);
@@ -3411,7 +3530,10 @@ async function subscribe(ctx, deps, endpoint, input) {
3411
3530
  throw falSdkError(cause, ctx.model.id);
3412
3531
  }
3413
3532
  },
3414
- ctx.signal !== void 0 ? { signal: ctx.signal } : {}
3533
+ mediaRetryOptions(
3534
+ ctx.call.maxRetries === void 0 ? {} : { maxRetries: 0 },
3535
+ ctx.signal
3536
+ )
3415
3537
  );
3416
3538
  } catch (cause) {
3417
3539
  throw falSdkError(cause, ctx.model.id);
@@ -3463,11 +3585,11 @@ async function decodeImage(ctx, url, contentType) {
3463
3585
  const mime = res.headers.get("content-type") ?? contentType ?? "image/png";
3464
3586
  return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
3465
3587
  }
3466
- var museImageResultSchema = z7.object({
3467
- images: z7.array(
3468
- z7.object({
3469
- url: z7.string().optional(),
3470
- content_type: z7.string().nullable().optional()
3588
+ var museImageResultSchema = z8.object({
3589
+ images: z8.array(
3590
+ z8.object({
3591
+ url: z8.string().optional(),
3592
+ content_type: z8.string().nullable().optional()
3471
3593
  })
3472
3594
  ).optional()
3473
3595
  });
@@ -3571,8 +3693,8 @@ function klingO1Input(req) {
3571
3693
  if (refs.length > 0) input.image_urls = refs;
3572
3694
  return input;
3573
3695
  }
3574
- var falVideoResultSchema = z7.object({
3575
- video: z7.object({ url: z7.string().optional() }).optional()
3696
+ var falVideoResultSchema = z8.object({
3697
+ video: z8.object({ url: z8.string().optional() }).optional()
3576
3698
  });
3577
3699
  function extractVideoUrl(result, endpoint, model) {
3578
3700
  const parsed = falVideoResultSchema.safeParse(result);
@@ -3652,7 +3774,7 @@ async function submitQueueJob(ctx, req, deps, endpoint, input) {
3652
3774
  throw falSdkError(cause, ctx.model.id);
3653
3775
  }
3654
3776
  },
3655
- ctx.signal !== void 0 ? { signal: ctx.signal } : {}
3777
+ mediaRetryOptions(ctx.call, ctx.signal)
3656
3778
  );
3657
3779
  } catch (cause) {
3658
3780
  throw falSdkError(cause, ctx.model.id);
@@ -3681,6 +3803,7 @@ function queuedVideoJob(ctx, req, client2, endpoint, requestId) {
3681
3803
  if (status === "IN_QUEUE") return { status: "pending" };
3682
3804
  return { status: "running" };
3683
3805
  } catch (cause) {
3806
+ if (ctx.call.maxRetries === 0) throw cause;
3684
3807
  if (isModelKitError(cause) && !cause.retryable)
3685
3808
  return { status: "failed" };
3686
3809
  return { status: "pending" };
@@ -3704,7 +3827,7 @@ function queuedVideoJob(ctx, req, client2, endpoint, requestId) {
3704
3827
  return await client2.queue.result(endpoint, queueOptions);
3705
3828
  } catch (cause) {
3706
3829
  const err = falSdkError(cause, ctx.model.id);
3707
- if (err.retryable) return void 0;
3830
+ if (ctx.call.maxRetries !== 0 && err.retryable) return void 0;
3708
3831
  throw err;
3709
3832
  }
3710
3833
  }, pollOptions);
@@ -3752,6 +3875,7 @@ async function passthroughVideoJob(ctx, req, endpoint, input) {
3752
3875
  const url = await checkStatus();
3753
3876
  return url ? { status: "succeeded" } : { status: "pending" };
3754
3877
  } catch (cause) {
3878
+ if (ctx.call.maxRetries === 0) throw cause;
3755
3879
  if (isModelKitError(cause) && !cause.retryable)
3756
3880
  return { status: "failed" };
3757
3881
  return { status: "pending" };
@@ -3771,13 +3895,13 @@ async function passthroughVideoJob(ctx, req, endpoint, input) {
3771
3895
  }
3772
3896
 
3773
3897
  // src/adapters/google-genai.ts
3774
- import { z as z9 } from "zod";
3898
+ import { z as z10 } from "zod";
3775
3899
  import {
3776
3900
  GoogleGenAI
3777
3901
  } from "@google/genai";
3778
3902
 
3779
3903
  // src/adapters/google-files.ts
3780
- import { z as z8 } from "zod";
3904
+ import { z as z9 } from "zod";
3781
3905
  var GOOGLE_FILES_BASE = "https://generativelanguage.googleapis.com";
3782
3906
  var GOOGLE_FILES_POLL_INTERVAL_MS = 2e3;
3783
3907
  var GOOGLE_FILES_POLL_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -3787,17 +3911,17 @@ var GENERIC_MEDIA_TYPES = /* @__PURE__ */ new Set([
3787
3911
  "binary/octet-stream",
3788
3912
  "application/binary"
3789
3913
  ]);
3790
- var uploadedFileSchema = z8.object({
3791
- file: z8.object({
3792
- uri: z8.string().optional(),
3793
- name: z8.string().optional(),
3794
- state: z8.string().optional(),
3795
- mimeType: z8.string().optional()
3914
+ var uploadedFileSchema = z9.object({
3915
+ file: z9.object({
3916
+ uri: z9.string().optional(),
3917
+ name: z9.string().optional(),
3918
+ state: z9.string().optional(),
3919
+ mimeType: z9.string().optional()
3796
3920
  }).optional()
3797
3921
  });
3798
- var fileStateSchema = z8.object({
3799
- state: z8.string().optional(),
3800
- error: z8.object({ message: z8.string().optional() }).optional()
3922
+ var fileStateSchema = z9.object({
3923
+ state: z9.string().optional(),
3924
+ error: z9.object({ message: z9.string().optional() }).optional()
3801
3925
  });
3802
3926
  function resolveMime(declared, fallback) {
3803
3927
  const clean = declared?.split(";")[0]?.trim().toLowerCase();
@@ -3931,7 +4055,7 @@ async function waitForActive(fileName, opts) {
3931
4055
  }
3932
4056
  return void 0;
3933
4057
  }
3934
- if (res.status === 429 || res.status >= 500) return void 0;
4058
+ if (opts.maxRetries !== 0 && (res.status === 429 || res.status >= 500)) return void 0;
3935
4059
  const text2 = await res.text().catch(() => "");
3936
4060
  throw classifyHttpError(res.status, text2, "google-genai", opts.model);
3937
4061
  }, pollOptions);
@@ -3955,8 +4079,7 @@ async function uploadGoogleFile(source, opts) {
3955
4079
  opts.model
3956
4080
  );
3957
4081
  if (bytes.length > GOOGLE_FILES_MAX_BYTES) throw oversizeError(bytes.length, label, opts.model);
3958
- const retryOptions = { attempts: 3 };
3959
- if (opts.signal !== void 0) retryOptions.signal = opts.signal;
4082
+ const retryOptions = mediaRetryOptions(opts, opts.signal);
3960
4083
  const uploaded = await withRetry(() => startAndUpload(bytes, mimeType, opts), retryOptions);
3961
4084
  if (uploaded.state !== "ACTIVE") {
3962
4085
  try {
@@ -3971,7 +4094,12 @@ async function uploadGoogleFile(source, opts) {
3971
4094
 
3972
4095
  // src/adapters/google-genai.ts
3973
4096
  function defaultCreateGenAIClient(opts) {
3974
- const sdk = new GoogleGenAI({ ...opts, vertexai: false });
4097
+ const sdk = new GoogleGenAI({
4098
+ apiKey: opts.apiKey,
4099
+ vertexai: false,
4100
+ ...opts.maxRetries !== void 0 ? { httpOptions: { retryOptions: { attempts: 1 } } } : {}
4101
+ });
4102
+ const interactionOptions = opts.maxRetries === void 0 ? void 0 : { maxRetries: 0, ...opts.signal !== void 0 ? { signal: opts.signal } : {} };
3975
4103
  return {
3976
4104
  models: {
3977
4105
  generateVideos: async (body) => {
@@ -3992,11 +4120,11 @@ function defaultCreateGenAIClient(opts) {
3992
4120
  interactions: {
3993
4121
  create: async (args) => {
3994
4122
  const params = args;
3995
- const response = await sdk.interactions.create(params);
4123
+ const response = await sdk.interactions.create(params, interactionOptions);
3996
4124
  return response;
3997
4125
  },
3998
4126
  get: async (jobId, params) => {
3999
- const response = await sdk.interactions.get(jobId, params);
4127
+ const response = await sdk.interactions.get(jobId, params, interactionOptions);
4000
4128
  return response;
4001
4129
  }
4002
4130
  }
@@ -4010,7 +4138,7 @@ var OMNI_POLL_INTERVAL_MS = 1e4;
4010
4138
  var RESULT_TIMEOUT_MS2 = 15 * 60 * 1e3;
4011
4139
  var OMNI_INLINE_LIMIT_BYTES = 4 * 1024 * 1024;
4012
4140
  var MEDIA_PART_INLINE_LIMIT_BYTES = 20 * 1024 * 1024;
4013
- var errorTextSchema = z9.string();
4141
+ var errorTextSchema = z10.string();
4014
4142
  function isGoogleGenaiVideoKnown(providerModelId) {
4015
4143
  return providerModelId.startsWith("veo-") || providerModelId.startsWith("gemini-omni");
4016
4144
  }
@@ -4165,7 +4293,11 @@ async function generateVeoVideo(req, ctx, createGenAIClient) {
4165
4293
  referenceType: "ASSET"
4166
4294
  }));
4167
4295
  }
4168
- const client2 = createGenAIClient({ apiKey });
4296
+ const client2 = createGenAIClient({
4297
+ apiKey,
4298
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {},
4299
+ ...ctx.signal !== void 0 ? { signal: ctx.signal } : {}
4300
+ });
4169
4301
  const config = { durationSeconds: duration, personGeneration };
4170
4302
  if (req.aspectRatio !== void 0) config.aspectRatio = req.aspectRatio;
4171
4303
  if (req.resolution !== void 0) config.resolution = req.resolution;
@@ -4178,8 +4310,7 @@ async function generateVeoVideo(req, ctx, createGenAIClient) {
4178
4310
  config
4179
4311
  };
4180
4312
  if (image !== void 0) requestBody.image = image;
4181
- const retryOptions = { attempts: 3 };
4182
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
4313
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4183
4314
  let operation;
4184
4315
  try {
4185
4316
  operation = await withRetry(async () => {
@@ -4292,7 +4423,11 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4292
4423
  if (omniResolution !== void 0) responseFormat.resolution = omniResolution;
4293
4424
  }
4294
4425
  if (req.durationSeconds !== void 0) responseFormat.duration = `${req.durationSeconds}s`;
4295
- const client2 = createGenAIClient({ apiKey });
4426
+ const client2 = createGenAIClient({
4427
+ apiKey,
4428
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {},
4429
+ ...ctx.signal !== void 0 ? { signal: ctx.signal } : {}
4430
+ });
4296
4431
  const uploadedByUri = /* @__PURE__ */ new Map();
4297
4432
  const uploadedNames = [];
4298
4433
  const uploadOne = async (kind, bytes, mime) => {
@@ -4303,6 +4438,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4303
4438
  label: "gemini-omni"
4304
4439
  };
4305
4440
  if (ctx.signal !== void 0) uploadOptions.signal = ctx.signal;
4441
+ if (ctx.call.maxRetries !== void 0) uploadOptions.maxRetries = ctx.call.maxRetries;
4306
4442
  const file = await uploadGoogleFile({ bytes, mime }, uploadOptions);
4307
4443
  uploadedByUri.set(file.fileUri, { type: kind, bytes, mime: file.mimeType });
4308
4444
  uploadedNames.push(file.fileName);
@@ -4318,8 +4454,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4318
4454
  generation_config: { video_config: { task } },
4319
4455
  store: true
4320
4456
  });
4321
- const createRetryOptions = { attempts: 3 };
4322
- if (ctx.signal !== void 0) createRetryOptions.signal = ctx.signal;
4457
+ const createRetryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4323
4458
  let interaction;
4324
4459
  try {
4325
4460
  const parts = [];
@@ -4389,7 +4524,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4389
4524
  }
4390
4525
  }, createRetryOptions);
4391
4526
  } catch (cause) {
4392
- if (uploadedByUri.size === 0 || !isFileReferenceRejected(cause))
4527
+ if (ctx.call.maxRetries !== void 0 || uploadedByUri.size === 0 || !isFileReferenceRejected(cause))
4393
4528
  throwSdkError(cause, modelId);
4394
4529
  const inlineParts = parts.map((part) => {
4395
4530
  if (part.uri === void 0) return part;
@@ -4499,9 +4634,12 @@ async function generateLyriaAudio(req, ctx, createGenAIClient) {
4499
4634
  const image = await resolveMedia(ref, ctx.fetch, ctx.signal, "image/jpeg", modelId);
4500
4635
  parts.push({ inlineData: { mimeType: image.mime, data: toBase64(image.bytes) } });
4501
4636
  }
4502
- const client2 = createGenAIClient({ apiKey });
4503
- const retryOptions = { attempts: 3 };
4504
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
4637
+ const client2 = createGenAIClient({
4638
+ apiKey,
4639
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {},
4640
+ ...ctx.signal !== void 0 ? { signal: ctx.signal } : {}
4641
+ });
4642
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4505
4643
  let response;
4506
4644
  try {
4507
4645
  response = await withRetry(async () => {
@@ -4563,6 +4701,7 @@ async function prepareGoogleMediaPart(ref, mediaType, ctx) {
4563
4701
  label: "media-part"
4564
4702
  };
4565
4703
  if (ctx.signal !== void 0) uploadOptions.signal = ctx.signal;
4704
+ if (ctx.call.maxRetries !== void 0) uploadOptions.maxRetries = ctx.call.maxRetries;
4566
4705
  const file = await uploadGoogleFile({ bytes: ref.bytes, mime: mediaType }, uploadOptions);
4567
4706
  return {
4568
4707
  type: "file",
@@ -4575,15 +4714,15 @@ async function prepareGoogleMediaPart(ref, mediaType, ctx) {
4575
4714
  // src/adapters/google-image.ts
4576
4715
  import { createGoogleGenerativeAI as createGoogleGenerativeAI2 } from "@ai-sdk/google";
4577
4716
  import { generateText } from "ai";
4578
- import { z as z10 } from "zod";
4717
+ import { z as z11 } from "zod";
4579
4718
  var GEMINI_IMAGE_TIMEOUT_MS = 6e5;
4580
4719
  var defaultGoogleImageDeps = {
4581
4720
  createGoogleClient: (opts) => createGoogleGenerativeAI2(opts),
4582
4721
  runTextGeneration: (opts) => generateText(opts)
4583
4722
  };
4584
- var causeChainNodeSchema = z10.object({
4585
- message: z10.string().optional(),
4586
- cause: z10.unknown().optional()
4723
+ var causeChainNodeSchema = z11.object({
4724
+ message: z11.string().optional(),
4725
+ cause: z11.unknown().optional()
4587
4726
  });
4588
4727
  function extractBlockReason(cause) {
4589
4728
  let current = cause;
@@ -4651,8 +4790,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
4651
4790
  responseModalities: ["IMAGE"]
4652
4791
  };
4653
4792
  if (req.safetySettings !== void 0) googleOptions.safetySettings = req.safetySettings;
4654
- const retryOptions = {};
4655
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
4793
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4656
4794
  const result = await withRetry(async () => {
4657
4795
  const timeout = AbortSignal.timeout(GEMINI_IMAGE_TIMEOUT_MS);
4658
4796
  const signal = ctx.signal !== void 0 ? AbortSignal.any([ctx.signal, timeout]) : timeout;
@@ -4704,7 +4842,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
4704
4842
  var googleImageAdapter = createGoogleImageAdapter();
4705
4843
 
4706
4844
  // src/adapters/higgsfield.ts
4707
- import { z as z11 } from "zod";
4845
+ import { z as z12 } from "zod";
4708
4846
 
4709
4847
  // src/adapters/higgsfield-motions.ts
4710
4848
  var MOTION_MAP = {
@@ -4903,14 +5041,14 @@ function videoUsage3(ctx, req, duration) {
4903
5041
  if (req.durationSeconds !== void 0) event.durationSeconds = req.durationSeconds;
4904
5042
  return event;
4905
5043
  }
4906
- var klingCreateSchema = z11.object({ status_url: z11.string() });
4907
- var klingStatusSchema = z11.object({
4908
- status: z11.string().optional(),
4909
- video: z11.object({ url: z11.string().optional() }).optional(),
5044
+ var klingCreateSchema = z12.object({ status_url: z12.string() });
5045
+ var klingStatusSchema = z12.object({
5046
+ status: z12.string().optional(),
5047
+ video: z12.object({ url: z12.string().optional() }).optional(),
4910
5048
  error: JsonValueSchema.optional()
4911
5049
  });
4912
- var errorMessageSchema = z11.object({ message: z11.string().optional() });
4913
- var textValueSchema = z11.string();
5050
+ var errorMessageSchema = z12.object({ message: z12.string().optional() });
5051
+ var textValueSchema = z12.string();
4914
5052
  function klingErrorDetail(error) {
4915
5053
  if (error === void 0) return "unknown_error";
4916
5054
  const asText = textValueSchema.safeParse(error);
@@ -4959,8 +5097,7 @@ async function generateKlingVideo(req, ctx) {
4959
5097
  body.aspect_ratio = req.aspectRatio;
4960
5098
  if (req.lastFrame) body.last_image_url = refToUrl(req.lastFrame);
4961
5099
  const endpoint = klingEndpoint(ctx.model.providerModelId, ctx.model.id);
4962
- const retryOptions = {};
4963
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
5100
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4964
5101
  const createRes = await withRetry(
4965
5102
  () => createRequest(ctx, endpoint, { method: "POST", body: JSON.stringify(body) }),
4966
5103
  retryOptions
@@ -4980,10 +5117,12 @@ async function generateKlingVideo(req, ctx) {
4980
5117
  let res;
4981
5118
  try {
4982
5119
  res = await ctx.fetch(statusUrl, requestInit(ctx, { method: "GET" }));
4983
- } catch {
5120
+ } catch (cause) {
5121
+ if (ctx.call.maxRetries === 0) throw classifyThrown("higgsfield", cause, ctx.model.id);
4984
5122
  return void 0;
4985
5123
  }
4986
- if (res.status === 429 || res.status >= 500) return void 0;
5124
+ if (ctx.call.maxRetries !== 0 && (res.status === 429 || res.status >= 500))
5125
+ return void 0;
4987
5126
  if (!res.ok) {
4988
5127
  throw classifyHttpError(res.status, await readBody(res), "higgsfield", ctx.model.id);
4989
5128
  }
@@ -5025,6 +5164,7 @@ async function generateKlingVideo(req, ctx) {
5025
5164
  const url = await check();
5026
5165
  return url ? { status: "succeeded" } : { status: "pending" };
5027
5166
  } catch (cause) {
5167
+ if (ctx.call.maxRetries === 0) throw cause;
5028
5168
  if (isModelKitError(cause) && !cause.retryable) return { status: "failed" };
5029
5169
  throw cause;
5030
5170
  }
@@ -5044,8 +5184,8 @@ async function generateKlingVideo(req, ctx) {
5044
5184
  }
5045
5185
  };
5046
5186
  }
5047
- var dopMotionOptionsSchema = z11.object({
5048
- modelkit: z11.object({ motion: z11.string().optional() }).optional()
5187
+ var dopMotionOptionsSchema = z12.object({
5188
+ modelkit: z12.object({ motion: z12.string().optional() }).optional()
5049
5189
  });
5050
5190
  function dopMotionId(ctx) {
5051
5191
  const parsed = dopMotionOptionsSchema.safeParse(ctx.model.providerOptions);
@@ -5061,7 +5201,7 @@ function dopMotionId(ctx) {
5061
5201
  });
5062
5202
  return id;
5063
5203
  }
5064
- var jsonRecordSchema = z11.record(z11.string(), JsonValueSchema);
5204
+ var jsonRecordSchema = z12.record(z12.string(), JsonValueSchema);
5065
5205
  var DOP_URL_KEYS = ["url", "video_url", "output_url", "result_url", "download_url"];
5066
5206
  var DOP_NESTED_KEYS = ["video", "result", "results"];
5067
5207
  function dopUrl(body) {
@@ -5089,8 +5229,8 @@ function dopUrl(body) {
5089
5229
  }
5090
5230
  return void 0;
5091
5231
  }
5092
- var dopCreateSchema = z11.object({ id: z11.string() });
5093
- var dopStatusSchema = z11.object({ status: z11.string().optional() });
5232
+ var dopCreateSchema = z12.object({ id: z12.string() });
5233
+ var dopStatusSchema = z12.object({ status: z12.string().optional() });
5094
5234
  async function generateDopVideo(req, ctx) {
5095
5235
  const firstFrame = req.firstFrame ? refToUrl(req.firstFrame) : void 0;
5096
5236
  if (!firstFrame) {
@@ -5115,8 +5255,7 @@ async function generateDopVideo(req, ctx) {
5115
5255
  params.input_images_end = [{ type: "image_url", image_url: refToUrl(req.lastFrame) }];
5116
5256
  }
5117
5257
  if (req.seed !== void 0) params.seed = req.seed;
5118
- const retryOptions = {};
5119
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
5258
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
5120
5259
  const createRes = await withRetry(
5121
5260
  () => createRequest(ctx, DOP_ENDPOINT, {
5122
5261
  method: "POST",
@@ -5140,10 +5279,18 @@ async function generateDopVideo(req, ctx) {
5140
5279
  let res;
5141
5280
  try {
5142
5281
  res = await ctx.fetch(statusUrl, requestInit(ctx, { method: "GET" }));
5143
- } catch {
5282
+ } catch (cause) {
5283
+ if (ctx.call.maxRetries === 0) throw classifyThrown("higgsfield", cause, ctx.model.id);
5144
5284
  return void 0;
5145
5285
  }
5146
5286
  if (!res.ok) {
5287
+ if (ctx.call.maxRetries === 0)
5288
+ throw classifyHttpError(
5289
+ res.status,
5290
+ await readBody(res),
5291
+ "higgsfield",
5292
+ ctx.model.id
5293
+ );
5147
5294
  return void 0;
5148
5295
  }
5149
5296
  const payload = JsonValueSchema.parse(await res.json());
@@ -5180,6 +5327,7 @@ async function generateDopVideo(req, ctx) {
5180
5327
  const url = await check();
5181
5328
  return url ? { status: "succeeded" } : { status: "pending" };
5182
5329
  } catch (cause) {
5330
+ if (ctx.call.maxRetries === 0) throw cause;
5183
5331
  if (isModelKitError(cause) && !cause.retryable) return { status: "failed" };
5184
5332
  throw cause;
5185
5333
  }
@@ -5210,7 +5358,7 @@ var higgsfieldAdapter = {
5210
5358
 
5211
5359
  // src/adapters/openai-image.ts
5212
5360
  import OpenAI from "openai";
5213
- import { z as z12 } from "zod";
5361
+ import { z as z13 } from "zod";
5214
5362
  var MAX_EDIT_REFERENCES = 16;
5215
5363
  function aspectRatioToSize(ratio, tier) {
5216
5364
  const TIER_LONG_EDGE = {
@@ -5293,9 +5441,9 @@ function toProviderError2(cause, ctx) {
5293
5441
  ctx.model.id
5294
5442
  );
5295
5443
  }
5296
- var openaiUsageSchema = z12.object({
5297
- input_tokens: z12.number().optional(),
5298
- output_tokens: z12.number().optional()
5444
+ var openaiUsageSchema = z13.object({
5445
+ input_tokens: z13.number().optional(),
5446
+ output_tokens: z13.number().optional()
5299
5447
  });
5300
5448
  var openaiImageAdapter = {
5301
5449
  id: "openai-image",
@@ -5337,8 +5485,7 @@ var openaiImageAdapter = {
5337
5485
  }
5338
5486
  const format = outputFormat !== void 0 ? { output_format: outputFormat } : {};
5339
5487
  const mime = outputFormat === "jpeg" ? "image/jpeg" : "image/png";
5340
- const retryOptions = {};
5341
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
5488
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
5342
5489
  const response = await withRetry(async () => {
5343
5490
  try {
5344
5491
  if (!isEdit) {
@@ -5658,13 +5805,7 @@ async function generateProdiaImage(req, ctx) {
5658
5805
  })
5659
5806
  );
5660
5807
  });
5661
- const retryOpts = {
5662
- attempts: 3,
5663
- baseDelayMs: 1e3,
5664
- factor: 2,
5665
- maxDelayMs: 1e4
5666
- };
5667
- if (ctx.signal !== void 0) retryOpts.signal = ctx.signal;
5808
+ const retryOpts = mediaRetryOptions(ctx.call, ctx.signal);
5668
5809
  let res;
5669
5810
  try {
5670
5811
  res = await withRetry(async () => {
@@ -5711,7 +5852,66 @@ var prodiaAdapter = {
5711
5852
 
5712
5853
  // src/adapters/replicate.ts
5713
5854
  import Replicate from "replicate";
5714
- import { z as z13 } from "zod";
5855
+
5856
+ // src/adapters/replicate-http.ts
5857
+ import { z as z14 } from "zod";
5858
+ var predictionSchema = z14.object({
5859
+ id: z14.string(),
5860
+ status: z14.string(),
5861
+ output: JsonValueSchema.optional(),
5862
+ error: JsonValueSchema.optional(),
5863
+ metrics: z14.object({ predict_time: z14.number().optional() }).optional()
5864
+ });
5865
+ function createReplicateHttpClient(opts) {
5866
+ async function request(path, body, signal) {
5867
+ let response;
5868
+ try {
5869
+ response = await opts.fetch(`https://api.replicate.com/v1${path}`, {
5870
+ method: body === void 0 ? "GET" : "POST",
5871
+ headers: {
5872
+ Authorization: `Bearer ${opts.auth}`,
5873
+ "Content-Type": "application/json"
5874
+ },
5875
+ ...body !== void 0 ? { body: JSON.stringify(body) } : {},
5876
+ ...signal !== void 0 ? { signal } : {}
5877
+ });
5878
+ } catch (cause) {
5879
+ throw classifyThrown("replicate", cause);
5880
+ }
5881
+ if (!response.ok)
5882
+ throw classifyHttpError(response.status, await response.text(), "replicate");
5883
+ const parsed = predictionSchema.parse(await response.json());
5884
+ return {
5885
+ id: parsed.id,
5886
+ status: parsed.status,
5887
+ ...parsed.output !== void 0 ? { output: parsed.output } : {},
5888
+ ...parsed.error !== void 0 ? { error: parsed.error } : {},
5889
+ ...parsed.metrics?.predict_time !== void 0 ? { metrics: { predict_time: parsed.metrics.predict_time } } : {}
5890
+ };
5891
+ }
5892
+ return {
5893
+ predictions: {
5894
+ create(options) {
5895
+ if (options.version) {
5896
+ return request(
5897
+ "/predictions",
5898
+ { input: options.input, version: options.version },
5899
+ options.signal
5900
+ );
5901
+ }
5902
+ return request(
5903
+ `/models/${options.model}/predictions`,
5904
+ { input: options.input },
5905
+ options.signal
5906
+ );
5907
+ },
5908
+ get: (id, options) => request(`/predictions/${encodeURIComponent(id)}`, void 0, options?.signal)
5909
+ }
5910
+ };
5911
+ }
5912
+
5913
+ // src/adapters/replicate.ts
5914
+ import { z as z15 } from "zod";
5715
5915
 
5716
5916
  // src/adapters/input-spec-mapper.ts
5717
5917
  function canonicalValue(req, key) {
@@ -5750,7 +5950,7 @@ function applyInputSpec(spec, req, refToUrl2, opts) {
5750
5950
  var POLL_INTERVAL_MS = 1e3;
5751
5951
  var POLL_TIMEOUT_MS = 15 * 6e4;
5752
5952
  var defaultReplicateDeps = {
5753
- createReplicateClient: (opts) => new Replicate(opts)
5953
+ createReplicateClient: (opts) => opts.maxRetries === void 0 ? new Replicate(opts) : createReplicateHttpClient(opts)
5754
5954
  };
5755
5955
  function createReplicateAdapter(deps = defaultReplicateDeps) {
5756
5956
  return {
@@ -5772,7 +5972,11 @@ function client(ctx, deps) {
5772
5972
  retryable: false
5773
5973
  });
5774
5974
  }
5775
- return deps.createReplicateClient({ auth: token, fetch: ctx.fetch });
5975
+ return deps.createReplicateClient({
5976
+ auth: token,
5977
+ fetch: ctx.fetch,
5978
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {}
5979
+ });
5776
5980
  }
5777
5981
  function route(providerModelId) {
5778
5982
  if (providerModelId.includes(":")) {
@@ -5782,8 +5986,8 @@ function route(providerModelId) {
5782
5986
  if (!providerModelId.includes("/")) return { version: providerModelId };
5783
5987
  return { model: providerModelId };
5784
5988
  }
5785
- var replicateResponseStatusSchema = z13.object({
5786
- response: z13.object({ status: z13.number() }).partial()
5989
+ var replicateResponseStatusSchema = z15.object({
5990
+ response: z15.object({ status: z15.number() }).partial()
5787
5991
  });
5788
5992
  function replicateError(cause, ctx) {
5789
5993
  if (isModelKitError(cause)) return cause;
@@ -5810,7 +6014,7 @@ function isUrlFn(value) {
5810
6014
  function extractOutputUrl(output) {
5811
6015
  const root = Array.isArray(output) ? output[0] : output;
5812
6016
  if (root === void 0) throw noOutput();
5813
- const asString = z13.string().safeParse(root);
6017
+ const asString = z15.string().safeParse(root);
5814
6018
  if (asString.success && asString.data) return asString.data;
5815
6019
  if (root instanceof URL) return root.href;
5816
6020
  if (isObjectOutput(root)) {
@@ -5819,15 +6023,15 @@ function extractOutputUrl(output) {
5819
6023
  if (urlValue !== void 0 && isUrlFn(urlValue)) {
5820
6024
  const called = urlValue();
5821
6025
  if (called instanceof URL) return called.href;
5822
- const calledString = z13.string().safeParse(called);
6026
+ const calledString = z15.string().safeParse(called);
5823
6027
  if (calledString.success && calledString.data) return calledString.data;
5824
6028
  } else {
5825
- const direct = z13.string().safeParse(urlValue);
6029
+ const direct = z15.string().safeParse(urlValue);
5826
6030
  if (direct.success && direct.data) return direct.data;
5827
6031
  }
5828
6032
  }
5829
6033
  if ("default" in root) {
5830
- const fallback = z13.string().safeParse(root.default);
6034
+ const fallback = z15.string().safeParse(root.default);
5831
6035
  if (fallback.success && fallback.data) return fallback.data;
5832
6036
  }
5833
6037
  }
@@ -5857,7 +6061,7 @@ async function runPrediction(ctx, input, deps) {
5857
6061
  throw replicateError(cause, ctx);
5858
6062
  }
5859
6063
  },
5860
- { attempts: 1 }
6064
+ mediaRetryOptions(ctx.call, ctx.signal, 1)
5861
6065
  );
5862
6066
  } catch (cause) {
5863
6067
  throw replicateError(cause, ctx);
@@ -5888,7 +6092,7 @@ async function runPrediction(ctx, input, deps) {
5888
6092
  }
5889
6093
  return void 0;
5890
6094
  }, pollOpts);
5891
- const predictTime = z13.number().safeParse(done.metrics?.predict_time);
6095
+ const predictTime = z15.number().safeParse(done.metrics?.predict_time);
5892
6096
  if (done.output === void 0) throw noOutput();
5893
6097
  return {
5894
6098
  url: extractOutputUrl(done.output),
@@ -6256,7 +6460,7 @@ async function generateReplicateVideo(req, ctx, deps) {
6256
6460
  throw replicateError(cause, ctx);
6257
6461
  }
6258
6462
  },
6259
- { attempts: 1 }
6463
+ mediaRetryOptions(ctx.call, ctx.signal, 1)
6260
6464
  );
6261
6465
  } catch (cause) {
6262
6466
  throw replicateError(cause, ctx);
@@ -6273,7 +6477,7 @@ async function generateReplicateVideo(req, ctx, deps) {
6273
6477
  throw replicateError(cause, ctx);
6274
6478
  }
6275
6479
  if (current.status === "succeeded") {
6276
- const predictTime = z13.number().safeParse(current.metrics?.predict_time);
6480
+ const predictTime = z15.number().safeParse(current.metrics?.predict_time);
6277
6481
  if (current.output === void 0) throw noOutput();
6278
6482
  return {
6279
6483
  url: extractOutputUrl(current.output),
@@ -6414,7 +6618,7 @@ async function generateReplicateAudio(req, ctx, deps) {
6414
6618
  // src/adapters/xai-video.ts
6415
6619
  import { experimental_generateVideo } from "ai";
6416
6620
  import { createXai as createXai2 } from "@ai-sdk/xai";
6417
- import { z as z14 } from "zod";
6621
+ import { z as z16 } from "zod";
6418
6622
  var POLL_INTERVAL_MS2 = 1e4;
6419
6623
  var POLL_TIMEOUT_MS2 = 15 * 6e4;
6420
6624
  var defaultXaiDeps = {
@@ -6427,8 +6631,8 @@ function createXaiVideoAdapter(deps = defaultXaiDeps) {
6427
6631
  };
6428
6632
  }
6429
6633
  var xaiVideoAdapter = createXaiVideoAdapter();
6430
- var xaiResponseStatusSchema = z14.object({
6431
- response: z14.object({ status: z14.number() }).partial()
6634
+ var xaiResponseStatusSchema = z16.object({
6635
+ response: z16.object({ status: z16.number() }).partial()
6432
6636
  });
6433
6637
  function xaiError(cause, ctx) {
6434
6638
  const info = describeThrown(cause);
@@ -6436,12 +6640,12 @@ function xaiError(cause, ctx) {
6436
6640
  const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
6437
6641
  return classifyThrown("xai-video", cause, ctx.model.id, { status, body: info.body });
6438
6642
  }
6439
- var xaiMetaSchema = z14.object({
6643
+ var xaiMetaSchema = z16.object({
6440
6644
  videoUrl: JsonValueSchema.optional(),
6441
6645
  costInUsdTicks: JsonValueSchema.optional(),
6442
6646
  duration: JsonValueSchema.optional()
6443
6647
  });
6444
- var xaiProviderMetadataSchema = z14.object({ xai: xaiMetaSchema });
6648
+ var xaiProviderMetadataSchema = z16.object({ xai: xaiMetaSchema });
6445
6649
  function metaOf(result) {
6446
6650
  const parsed = xaiProviderMetadataSchema.partial().safeParse(result.providerMetadata);
6447
6651
  if (!parsed.success) return {};
@@ -6492,6 +6696,7 @@ async function generateXaiVideo(req, ctx, deps) {
6492
6696
  }
6493
6697
  if (req.durationSeconds !== void 0) callBody.duration = req.durationSeconds;
6494
6698
  if (ctx.signal) callBody.abortSignal = ctx.signal;
6699
+ if (ctx.call.maxRetries !== void 0) callBody.maxRetries = ctx.call.maxRetries;
6495
6700
  const pending = (async () => {
6496
6701
  try {
6497
6702
  return await client2.generateVideo(callBody);
@@ -6548,7 +6753,7 @@ async function mapResult(ctx, req, result) {
6548
6753
  };
6549
6754
  }
6550
6755
  const meta = metaOf(result);
6551
- const videoUrl = z14.string().safeParse(meta.videoUrl);
6756
+ const videoUrl = z16.string().safeParse(meta.videoUrl);
6552
6757
  if (videoUrl.success && videoUrl.data) {
6553
6758
  const res = await ctx.fetch(videoUrl.data);
6554
6759
  if (!res.ok) {
@@ -6571,7 +6776,7 @@ async function mapResult(ctx, req, result) {
6571
6776
  });
6572
6777
  }
6573
6778
  function usage(ctx, req, meta) {
6574
- const costTicks = z14.number().safeParse(meta.costInUsdTicks);
6779
+ const costTicks = z16.number().safeParse(meta.costInUsdTicks);
6575
6780
  const cost = costTicks.success ? costTicks.data / 1e10 : void 0;
6576
6781
  const event = {
6577
6782
  model: ctx.model.id,
@@ -6704,22 +6909,22 @@ var liveState = store[KEY] ??= {
6704
6909
  var liveCatalog = liveState.catalog;
6705
6910
 
6706
6911
  // src/catalog/load.ts
6707
- import { z as z15 } from "zod";
6912
+ import { z as z17 } from "zod";
6708
6913
  function rowCount() {
6709
6914
  return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
6710
6915
  }
6711
6916
  function authHeaders(auth) {
6712
6917
  return "bearer" in auth ? { Authorization: `Bearer ${auth.bearer}` } : { "x-api-key": auth.apiKey };
6713
6918
  }
6714
- var EnvelopeSchema = z15.object({
6715
- rows: z15.array(JsonValueSchema),
6716
- revision: z15.string().optional()
6919
+ var EnvelopeSchema = z17.object({
6920
+ rows: z17.array(JsonValueSchema),
6921
+ revision: z17.string().optional()
6717
6922
  });
6718
6923
  function dropReason(path, message) {
6719
6924
  return path.length === 0 ? message : `${path.map((part) => String(part)).join(".")} ${message}`;
6720
6925
  }
6721
6926
  function rowId(raw) {
6722
- const parsed = z15.object({ id: z15.string().min(1) }).loose().safeParse(raw);
6927
+ const parsed = z17.object({ id: z17.string().min(1) }).loose().safeParse(raw);
6723
6928
  if (!parsed.success) return "?";
6724
6929
  return parsed.data.id;
6725
6930
  }
@@ -7479,7 +7684,7 @@ import {
7479
7684
  streamObject as aiStreamObject2,
7480
7685
  streamText as aiStreamText2
7481
7686
  } from "ai";
7482
- import { z as z16 } from "zod";
7687
+ import { z as z18 } from "zod";
7483
7688
 
7484
7689
  // src/generated-image.ts
7485
7690
  function toGeneratedImage(image) {
@@ -7554,10 +7759,10 @@ function textAbortOptions(sdk, context) {
7554
7759
  if (abortSignal) return { abortSignal };
7555
7760
  return {};
7556
7761
  }
7557
- var catalogId = z16.string();
7558
- var exactSize = z16.templateLiteral([z16.number(), "x", z16.number()]);
7559
- var sdkRatio = z16.templateLiteral([z16.number(), ":", z16.number()]);
7560
- var sizeTier = z16.enum(["512", "1K", "2K", "4K"]);
7762
+ var catalogId = z18.string();
7763
+ var exactSize = z18.templateLiteral([z18.number(), "x", z18.number()]);
7764
+ var sdkRatio = z18.templateLiteral([z18.number(), ":", z18.number()]);
7765
+ var sizeTier = z18.enum(["512", "1K", "2K", "4K"]);
7561
7766
  function isCatalogId(model) {
7562
7767
  return catalogId.safeParse(model).success;
7563
7768
  }
@@ -7748,6 +7953,7 @@ function createModelKit(config, adapters) {
7748
7953
  logCoercions(logger, model.modelId, warnings);
7749
7954
  const abortSignal = combineSignals(req.abortSignal, call.signal);
7750
7955
  if (abortSignal) options.abortSignal = abortSignal;
7956
+ if (call.maxRetries !== void 0) options.maxRetries = call.maxRetries;
7751
7957
  const result = await aiGenerateImage(options);
7752
7958
  const images = result.images.map(
7753
7959
  (file) => toGeneratedImage({ bytes: file.uint8Array, mime: file.mediaType })
@@ -7787,6 +7993,7 @@ function createModelKit(config, adapters) {
7787
7993
  const seconds = duration ?? durationSeconds;
7788
7994
  const abortSignal = combineSignals(req.abortSignal, call.signal);
7789
7995
  const options = { model, prompt };
7996
+ if (call.maxRetries !== void 0) options.maxRetries = call.maxRetries;
7790
7997
  const warnings = [];
7791
7998
  const ratio = sdkAspectRatio(aspectRatio) ?? (aspectRatio === "adaptive" ? "adaptive" : void 0);
7792
7999
  if (ratio) options.aspectRatio = ratio;
@@ -7868,6 +8075,7 @@ function createModelKit(config, adapters) {
7868
8075
  catalog,
7869
8076
  describe: (id) => catalog.require(id),
7870
8077
  async generateImage(req, call = {}) {
8078
+ mediaRetryOptions(call);
7871
8079
  if (!isCatalogId(req.model)) {
7872
8080
  return passthroughImage({ ...req, model: req.model }, call);
7873
8081
  }
@@ -7911,6 +8119,7 @@ function createModelKit(config, adapters) {
7911
8119
  return { ...result, usage: usage2, image: first, images, warnings };
7912
8120
  },
7913
8121
  async generateVideo(req, call = {}) {
8122
+ mediaRetryOptions(call);
7914
8123
  if (!isCatalogId(req.model)) {
7915
8124
  return passthroughVideo({ ...req, model: req.model }, call);
7916
8125
  }
@@ -7965,6 +8174,7 @@ function createModelKit(config, adapters) {
7965
8174
  };
7966
8175
  },
7967
8176
  async generateAudio(req, call = {}) {
8177
+ mediaRetryOptions(call);
7968
8178
  const model = catalog.require(req.model);
7969
8179
  if (model.type !== "audio") {
7970
8180
  throw new ModelKitError({
@@ -7994,6 +8204,7 @@ function createModelKit(config, adapters) {
7994
8204
  return result;
7995
8205
  },
7996
8206
  async prepareMediaPart(modelId, ref, mediaType, call = {}) {
8207
+ mediaRetryOptions(call);
7997
8208
  const model = catalog.require(modelId);
7998
8209
  const { adapter, ctx } = context(model, call, []);
7999
8210
  const fileStore = model.adapter === "ai-sdk-text" && textKeyName(model) === "google" ? adapters["google-genai"] : adapter;