@shop-os/modelkit 0.2.13 → 0.2.15

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
  }
@@ -1371,7 +1373,8 @@ var VIDEO_MODELS = [
1371
1373
  // reference clip keeps its own framing.
1372
1374
  aspectRatios: [...OMNI_RATIOS],
1373
1375
  durations: [3, 4, 5, 6, 7, 8, 9, 10],
1374
- references: { images: 6, videos: 1 },
1376
+ references: { images: 6, videos: 1, videoSeconds: { max: 10 } },
1377
+ sourceVideoSeconds: { max: 10 },
1375
1378
  supports: []
1376
1379
  },
1377
1380
  defaults: {},
@@ -1397,7 +1400,8 @@ var VIDEO_MODELS = [
1397
1400
  aspectRatios: [...OMNI_RATIOS],
1398
1401
  resolutions: ["360p", "720p", "1080p", "4k"],
1399
1402
  durations: [3, 4, 5, 6, 7, 8, 9, 10],
1400
- references: { images: 6, videos: 1 },
1403
+ references: { images: 6, videos: 1, videoSeconds: { max: 10 } },
1404
+ sourceVideoSeconds: { max: 10 },
1401
1405
  supports: []
1402
1406
  },
1403
1407
  defaults: {},
@@ -1425,7 +1429,14 @@ var VIDEO_MODELS = [
1425
1429
  resolutions: ["480p", "720p", "1080p", "4k"],
1426
1430
  durations: { min: 4, max: 15 },
1427
1431
  durationPresets: [4, 6, 8, 10, 12, 15],
1428
- references: { images: 9, videos: 3, audios: 3, audioOnly: false },
1432
+ references: {
1433
+ images: 9,
1434
+ videos: 3,
1435
+ audios: 3,
1436
+ audioOnly: false,
1437
+ videoSeconds: { min: 2, max: 15, total: 15 }
1438
+ },
1439
+ sourceVideoSeconds: { min: 2, max: 15, inReferenceTotal: true },
1429
1440
  ratioIgnoredWith: ["firstFrame", "sourceVideo"],
1430
1441
  supports: ["generateAudio", "seed", "lastFrame", "watermark"]
1431
1442
  },
@@ -1457,7 +1468,14 @@ var VIDEO_MODELS = [
1457
1468
  aspectRatios: [...SEEDANCE_RATIOS],
1458
1469
  resolutions: ["480p", "720p"],
1459
1470
  durations: { min: 4, max: 15 },
1460
- references: { images: 9, videos: 3, audios: 3, audioOnly: false },
1471
+ references: {
1472
+ images: 9,
1473
+ videos: 3,
1474
+ audios: 3,
1475
+ audioOnly: false,
1476
+ videoSeconds: { min: 2, max: 15, total: 15 }
1477
+ },
1478
+ sourceVideoSeconds: { min: 2, max: 15, inReferenceTotal: true },
1461
1479
  ratioIgnoredWith: ["firstFrame", "sourceVideo"],
1462
1480
  supports: ["generateAudio", "seed", "lastFrame", "watermark"]
1463
1481
  },
@@ -1491,7 +1509,13 @@ var VIDEO_MODELS = [
1491
1509
  aspectRatios: [...SEEDANCE_RATIOS],
1492
1510
  resolutions: ["480p", "720p", "1080p"],
1493
1511
  durations: { min: 4, max: 30 },
1494
- references: { images: 30, videos: 10, audios: 10 },
1512
+ references: {
1513
+ images: 30,
1514
+ videos: 10,
1515
+ audios: 10,
1516
+ videoSeconds: { min: 2, max: 30, total: 30, editMin: 4 }
1517
+ },
1518
+ sourceVideoSeconds: { min: 2, max: 30, editMin: 4, inReferenceTotal: true },
1495
1519
  ratioIgnoredWith: ["firstFrame", "sourceVideo"],
1496
1520
  supports: ["generateAudio", "seed", "lastFrame", "watermark", "taskType"]
1497
1521
  },
@@ -1703,7 +1727,14 @@ var VIDEO_MODELS = [
1703
1727
  aspectRatios: [...H3_REFERENCE_RATIOS],
1704
1728
  resolutions: ["480p", "768p", "2k", "4k"],
1705
1729
  durations: { min: 5, max: 15 },
1706
- references: { images: 9, videos: 3, audios: 3, total: 12, audioOnly: false },
1730
+ references: {
1731
+ images: 9,
1732
+ videos: 3,
1733
+ audios: 3,
1734
+ total: 12,
1735
+ audioOnly: false,
1736
+ videoSeconds: { min: 2, max: 15, total: 15 }
1737
+ },
1707
1738
  supports: ["seed", "promptExpansion", "safetyChecker"]
1708
1739
  },
1709
1740
  defaults: {
@@ -1734,7 +1765,14 @@ var VIDEO_MODELS = [
1734
1765
  aspectRatios: [...H3_REFERENCE_RATIOS],
1735
1766
  resolutions: ["480p", "768p"],
1736
1767
  durations: { min: 5, max: 15 },
1737
- references: { images: 9, videos: 3, audios: 3, total: 12, audioOnly: false },
1768
+ references: {
1769
+ images: 9,
1770
+ videos: 3,
1771
+ audios: 3,
1772
+ total: 12,
1773
+ audioOnly: false,
1774
+ videoSeconds: { min: 2, max: 15, total: 15 }
1775
+ },
1738
1776
  supports: ["seed", "promptExpansion", "safetyChecker"]
1739
1777
  },
1740
1778
  defaults: {
@@ -1766,6 +1804,7 @@ var VIDEO_MODELS = [
1766
1804
  aspectRatios: [...KLING_RATIOS],
1767
1805
  durations: { min: 3, max: 10 },
1768
1806
  requires: ["sourceVideo"],
1807
+ sourceVideoSeconds: { min: 3, max: 10.05 },
1769
1808
  supports: []
1770
1809
  },
1771
1810
  defaults: { durationSeconds: 5, aspectRatio: "16:9" },
@@ -2125,13 +2164,20 @@ var ProviderOptionValueSchema = z2.lazy(
2125
2164
  ])
2126
2165
  );
2127
2166
  var ProviderOptionsSchema = z2.record(z2.string(), z2.record(z2.string(), ProviderOptionValueSchema));
2167
+ var VideoSecondsLimitsSchema = z2.looseObject({
2168
+ min: z2.number().optional(),
2169
+ max: z2.number().optional(),
2170
+ total: z2.number().optional(),
2171
+ editMin: z2.number().optional()
2172
+ });
2128
2173
  var ReferenceLimitsSchema = z2.looseObject({
2129
2174
  images: z2.number().optional(),
2130
2175
  imagesWithVideo: z2.number().optional(),
2131
2176
  videos: z2.number().optional(),
2132
2177
  audios: z2.number().optional(),
2133
2178
  total: z2.number().optional(),
2134
- audioOnly: z2.boolean().optional()
2179
+ audioOnly: z2.boolean().optional(),
2180
+ videoSeconds: VideoSecondsLimitsSchema.optional()
2135
2181
  });
2136
2182
  var ModelConstraintsSchema = z2.looseObject({
2137
2183
  aspectRatios: z2.array(AspectRatioSchema).optional(),
@@ -2144,14 +2190,20 @@ var ModelConstraintsSchema = z2.looseObject({
2144
2190
  references: ReferenceLimitsSchema.optional(),
2145
2191
  requires: z2.array(RequiredInputSchema).optional(),
2146
2192
  supports: z2.array(SupportedOptionSchema).optional(),
2147
- ratioIgnoredWith: z2.array(z2.enum(["firstFrame", "sourceVideo"])).optional()
2193
+ ratioIgnoredWith: z2.array(z2.enum(["firstFrame", "sourceVideo"])).optional(),
2194
+ sourceVideoSeconds: VideoSecondsLimitsSchema.omit({ total: true }).extend({ inReferenceTotal: z2.boolean().optional() }).optional()
2148
2195
  });
2149
2196
  var MediaRefSchema = z2.union([
2150
- z2.looseObject({ url: z2.string(), label: z2.string().optional() }),
2197
+ z2.looseObject({
2198
+ url: z2.string(),
2199
+ label: z2.string().optional(),
2200
+ durationSeconds: z2.number().optional()
2201
+ }),
2151
2202
  z2.looseObject({
2152
2203
  bytes: z2.instanceof(Uint8Array),
2153
2204
  mime: z2.string(),
2154
- label: z2.string().optional()
2205
+ label: z2.string().optional(),
2206
+ durationSeconds: z2.number().optional()
2155
2207
  })
2156
2208
  ]);
2157
2209
  var ImageSafetySettingSchema = z2.looseObject({ category: z2.string(), threshold: z2.string() });
@@ -2678,6 +2730,19 @@ function shouldRetry(err) {
2678
2730
  if (/ECONNRESET|ETIMEDOUT|fetch failed|socket hang up/i.test(err.message)) return true;
2679
2731
  return false;
2680
2732
  }
2733
+ function mediaRetryOptions(call, signal, defaultAttempts = 3) {
2734
+ if (call.maxRetries !== void 0 && (!Number.isSafeInteger(call.maxRetries + 1) || call.maxRetries < 0)) {
2735
+ throw new ModelKitError({
2736
+ code: "unsupported_option",
2737
+ message: "maxRetries must be a non-negative safe integer",
2738
+ retryable: false
2739
+ });
2740
+ }
2741
+ return {
2742
+ attempts: call.maxRetries === void 0 ? defaultAttempts : call.maxRetries + 1,
2743
+ ...signal !== void 0 ? { signal } : {}
2744
+ };
2745
+ }
2681
2746
  async function withRetry(fn, opts = {}) {
2682
2747
  const attempts = opts.attempts ?? 3;
2683
2748
  const base = opts.baseDelayMs ?? 1e3;
@@ -2685,6 +2750,7 @@ async function withRetry(fn, opts = {}) {
2685
2750
  const factor = opts.factor ?? 2;
2686
2751
  let last;
2687
2752
  for (let attempt = 1; attempt <= attempts; attempt++) {
2753
+ if (opts.signal?.aborted) throw throwAborted();
2688
2754
  try {
2689
2755
  return await fn(attempt);
2690
2756
  } catch (cause) {
@@ -2797,11 +2863,11 @@ async function readBody(res) {
2797
2863
  return text2;
2798
2864
  }
2799
2865
  }
2800
- async function mediaRefToBytes(ref, fetch, options = {}) {
2866
+ async function mediaRefToBytes(ref, fetch2, options = {}) {
2801
2867
  if (!isUrlRef(ref)) return { bytes: ref.bytes, mime: ref.mime };
2802
2868
  const init = {};
2803
2869
  if (options.signal !== void 0) init.signal = options.signal;
2804
- const res = await fetch(ref.url, init);
2870
+ const res = await fetch2(ref.url, init);
2805
2871
  if (!res.ok) {
2806
2872
  const text2 = await res.text().catch(() => "");
2807
2873
  throw classifyHttpError(
@@ -2938,11 +3004,6 @@ var SeedreamResponseSchema = z6.object({
2938
3004
  data: z6.array(SeedreamImageSchema).optional(),
2939
3005
  error: z6.object({ message: z6.string().optional(), code: z6.string().optional() }).optional()
2940
3006
  });
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
3007
  function fetchInitFor(ctx, init) {
2947
3008
  if (ctx.signal !== void 0) init.signal = ctx.signal;
2948
3009
  return init;
@@ -2980,20 +3041,23 @@ async function generateSeedreamImage(req, ctx) {
2980
3041
  const firstRef = refs[0];
2981
3042
  if (refs.length === 1 && firstRef !== void 0) body.image = firstRef;
2982
3043
  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));
3044
+ const data = await withRetry(
3045
+ async () => {
3046
+ const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}/images/generations`, {
3047
+ method: "POST",
3048
+ headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
3049
+ body: JSON.stringify(body)
3050
+ });
3051
+ if (!res.ok) {
3052
+ const text2 = await res.text().catch(() => "");
3053
+ throwArkError(res.status, text2, modelId);
3054
+ }
3055
+ const parsed = SeedreamResponseSchema.safeParse(await res.json());
3056
+ const decoded = parsed.success ? parsed.data : {};
3057
+ return decoded;
3058
+ },
3059
+ mediaRetryOptions(ctx.call, ctx.signal)
3060
+ );
2997
3061
  const first = data.data?.[0];
2998
3062
  let bytes;
2999
3063
  if (first?.b64_json) {
@@ -3129,20 +3193,23 @@ async function generateSeedanceVideo(req, ctx) {
3129
3193
  if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
3130
3194
  if (req.seed !== void 0) body.seed = req.seed;
3131
3195
  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));
3196
+ const submit = await withRetry(
3197
+ async () => {
3198
+ const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}`, {
3199
+ method: "POST",
3200
+ headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
3201
+ body: JSON.stringify(body)
3202
+ });
3203
+ if (!res.ok) {
3204
+ const text2 = await res.text().catch(() => "");
3205
+ throwArkError(res.status, text2, modelId);
3206
+ }
3207
+ const parsed = SeedanceResponseSchema.safeParse(await res.json());
3208
+ const decoded = parsed.success ? parsed.data : {};
3209
+ return decoded;
3210
+ },
3211
+ mediaRetryOptions(ctx.call, ctx.signal)
3212
+ );
3146
3213
  if (!submit.id) throwArkError(void 0, "Seedance task create returned no id", modelId);
3147
3214
  const jobId = submit.id;
3148
3215
  const usage2 = seedanceUsage(ctx, req, taskType === "edit" ? requestedDuration : duration);
@@ -3151,7 +3218,8 @@ async function generateSeedanceVideo(req, ctx) {
3151
3218
  headers: { Authorization: `Bearer ${key}` }
3152
3219
  });
3153
3220
  if (!res.ok) {
3154
- if (res.status === 429 || res.status >= 500) return void 0;
3221
+ if (ctx.call.maxRetries !== 0 && (res.status === 429 || res.status >= 500))
3222
+ return void 0;
3155
3223
  const text2 = await res.text().catch(() => "");
3156
3224
  throwArkError(res.status, text2, modelId);
3157
3225
  }
@@ -3217,16 +3285,109 @@ async function generateSeedanceVideo(req, ctx) {
3217
3285
  }
3218
3286
 
3219
3287
  // src/adapters/fal.ts
3220
- import { z as z7 } from "zod";
3288
+ import { z as z8 } from "zod";
3221
3289
  import { createFalClient } from "@fal-ai/client";
3290
+
3291
+ // src/adapters/fal-http.ts
3292
+ import { z as z7 } from "zod";
3293
+ var queueUrl = z7.url().refine((value) => new URL(value).origin === "https://queue.fal.run");
3294
+ var submissionSchema = z7.object({
3295
+ request_id: z7.string(),
3296
+ status_url: queueUrl,
3297
+ response_url: queueUrl
3298
+ });
3299
+ var statusSchema = z7.object({ status: z7.string() });
3300
+ function createFalHttpClient(opts) {
3301
+ const jobs = /* @__PURE__ */ new Map();
3302
+ async function request(url, input, signal) {
3303
+ let response;
3304
+ try {
3305
+ response = await opts.fetch(url, {
3306
+ method: input === void 0 ? "GET" : "POST",
3307
+ headers: {
3308
+ Authorization: `Key ${opts.credentials}`,
3309
+ "Content-Type": "application/json"
3310
+ },
3311
+ ...input !== void 0 ? { body: JSON.stringify(input) } : {},
3312
+ ...signal !== void 0 ? { signal } : {}
3313
+ });
3314
+ } catch (cause) {
3315
+ throw classifyThrown("fal", cause);
3316
+ }
3317
+ if (!response.ok) throw classifyHttpError(response.status, await response.text(), "fal");
3318
+ return JsonValueSchema.parse(await response.json());
3319
+ }
3320
+ function job(id) {
3321
+ const saved = jobs.get(id);
3322
+ if (!saved)
3323
+ throw new ModelKitError({
3324
+ code: "provider_rejected",
3325
+ provider: "fal",
3326
+ message: "Unknown fal queue request"
3327
+ });
3328
+ return saved;
3329
+ }
3330
+ const queue = {
3331
+ async submit(endpoint, options) {
3332
+ const submitted = submissionSchema.parse(
3333
+ await request(
3334
+ `https://queue.fal.run/${endpoint}`,
3335
+ options.input,
3336
+ options.abortSignal
3337
+ )
3338
+ );
3339
+ jobs.set(submitted.request_id, submitted);
3340
+ return { requestId: submitted.request_id };
3341
+ },
3342
+ async status(_endpoint, options) {
3343
+ return statusSchema.parse(
3344
+ await request(job(options.requestId).status_url, void 0, options.abortSignal)
3345
+ );
3346
+ },
3347
+ result: (_endpoint, options) => request(job(options.requestId).response_url, void 0, options.abortSignal)
3348
+ };
3349
+ return {
3350
+ queue,
3351
+ async subscribe(endpoint, options) {
3352
+ const submitted = await withRetry(
3353
+ () => queue.submit(endpoint, options),
3354
+ mediaRetryOptions(opts, options.abortSignal)
3355
+ );
3356
+ return pollUntil(
3357
+ async () => {
3358
+ const readOptions = {
3359
+ requestId: submitted.requestId,
3360
+ ...options.abortSignal !== void 0 ? { abortSignal: options.abortSignal } : {}
3361
+ };
3362
+ const current = await queue.status(endpoint, readOptions);
3363
+ if (current.status !== "COMPLETED") return void 0;
3364
+ return queue.result(endpoint, readOptions);
3365
+ },
3366
+ {
3367
+ intervalMs: 1e3,
3368
+ timeoutMs: 18e4,
3369
+ ...options.abortSignal !== void 0 ? { signal: options.abortSignal } : {}
3370
+ }
3371
+ );
3372
+ }
3373
+ };
3374
+ }
3375
+
3376
+ // src/adapters/fal.ts
3222
3377
  var MUSE_T2I_ENDPOINT = "meta/muse-image/text-to-image";
3223
3378
  var MUSE_EDIT_ENDPOINT = "meta/muse-image/edit";
3224
3379
  var KLING_O1_ENDPOINT = "fal-ai/kling-video/o1/video-to-video/reference";
3225
3380
  var FAL_QUEUE_HOST = "https://queue.fal.run";
3226
3381
  var PASSTHROUGH_POLL_MS = 2e3;
3227
3382
  var PASSTHROUGH_MAX_WAIT_MS = 18e4;
3228
- var falSubscribePayloadSchema = z7.object({ data: JsonValueSchema });
3383
+ var falSubscribePayloadSchema = z8.object({ data: JsonValueSchema });
3229
3384
  function defaultCreateFalClient(opts) {
3385
+ if (opts.maxRetries !== void 0)
3386
+ return createFalHttpClient({
3387
+ credentials: opts.credentials,
3388
+ fetch: opts.fetch ?? fetch,
3389
+ maxRetries: opts.maxRetries
3390
+ });
3230
3391
  const client2 = createFalClient(opts);
3231
3392
  return {
3232
3393
  async subscribe(endpoint, options) {
@@ -3275,7 +3436,7 @@ function createFalAdapter(deps = defaultDeps) {
3275
3436
  };
3276
3437
  }
3277
3438
  var falAdapter = createFalAdapter();
3278
- var falDetailSchema = z7.object({ detail: JsonValueSchema });
3439
+ var falDetailSchema = z8.object({ detail: JsonValueSchema });
3279
3440
  function liftDetail(body) {
3280
3441
  const parsed = falDetailSchema.safeParse(body);
3281
3442
  const detail = parsed.success ? parsed.data.detail : void 0;
@@ -3284,11 +3445,11 @@ function liftDetail(body) {
3284
3445
  function falError(status, body, model) {
3285
3446
  return classifyHttpError(status, liftDetail(body), "fal", model);
3286
3447
  }
3287
- var falSdkThrownSchema = z7.object({
3288
- status: z7.number().optional(),
3289
- statusCode: z7.number().optional(),
3448
+ var falSdkThrownSchema = z8.object({
3449
+ status: z8.number().optional(),
3450
+ statusCode: z8.number().optional(),
3290
3451
  body: JsonValueSchema.optional(),
3291
- message: z7.string().optional()
3452
+ message: z8.string().optional()
3292
3453
  });
3293
3454
  function falSdkError(cause, model) {
3294
3455
  const parsed = falSdkThrownSchema.safeParse(cause);
@@ -3321,6 +3482,8 @@ function gatewayConfig(ctx) {
3321
3482
  };
3322
3483
  if (falKey) config.falKey = falKey;
3323
3484
  if (cfToken) config.cfToken = cfToken;
3485
+ if (ctx.call.maxRetries !== void 0) config.singleAttempt = true;
3486
+ if (ctx.signal !== void 0) config.signal = ctx.signal;
3324
3487
  return config;
3325
3488
  }
3326
3489
  async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
@@ -3328,16 +3491,18 @@ async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
3328
3491
  if (cfg.falKey) headers2.Authorization = `Bearer ${cfg.falKey}`;
3329
3492
  if (init.body) headers2["Content-Type"] = "application/json";
3330
3493
  if (cfg.cfToken) headers2["cf-aig-authorization"] = `Bearer ${cfg.cfToken}`;
3494
+ if (cfg.singleAttempt) headers2["cf-aig-max-attempts"] = "1";
3331
3495
  const request = { method: init.method, headers: headers2 };
3496
+ if (cfg.signal !== void 0) request.signal = cfg.signal;
3332
3497
  if (init.body !== void 0) request.body = init.body;
3333
3498
  return fetchImpl(cfg.baseUrl, request);
3334
3499
  }
3335
- var falQueueSubmitSchema = z7.object({
3336
- request_id: z7.string(),
3337
- status_url: z7.string(),
3338
- response_url: z7.string()
3500
+ var falQueueSubmitSchema = z8.object({
3501
+ request_id: z8.string(),
3502
+ status_url: z8.string(),
3503
+ response_url: z8.string()
3339
3504
  });
3340
- var falQueueStatusSchema = z7.object({ status: z7.string() });
3505
+ var falQueueStatusSchema = z8.object({ status: z8.string() });
3341
3506
  async function passthroughRequest(ctx, endpoint, input) {
3342
3507
  const cfg = gatewayConfig(ctx);
3343
3508
  const submitRes = await gatewayFetch(cfg, ctx.fetch, `${FAL_QUEUE_HOST}/${endpoint}`, {
@@ -3394,7 +3559,11 @@ function falClientOf(ctx, deps) {
3394
3559
  retryable: false
3395
3560
  });
3396
3561
  }
3397
- return deps.createFalClient({ credentials: falKey, fetch: ctx.fetch });
3562
+ return deps.createFalClient({
3563
+ credentials: falKey,
3564
+ fetch: ctx.fetch,
3565
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {}
3566
+ });
3398
3567
  }
3399
3568
  async function subscribe(ctx, deps, endpoint, input) {
3400
3569
  const client2 = falClientOf(ctx, deps);
@@ -3411,7 +3580,10 @@ async function subscribe(ctx, deps, endpoint, input) {
3411
3580
  throw falSdkError(cause, ctx.model.id);
3412
3581
  }
3413
3582
  },
3414
- ctx.signal !== void 0 ? { signal: ctx.signal } : {}
3583
+ mediaRetryOptions(
3584
+ ctx.call.maxRetries === void 0 ? {} : { maxRetries: 0 },
3585
+ ctx.signal
3586
+ )
3415
3587
  );
3416
3588
  } catch (cause) {
3417
3589
  throw falSdkError(cause, ctx.model.id);
@@ -3463,11 +3635,11 @@ async function decodeImage(ctx, url, contentType) {
3463
3635
  const mime = res.headers.get("content-type") ?? contentType ?? "image/png";
3464
3636
  return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
3465
3637
  }
3466
- var museImageResultSchema = z7.object({
3467
- images: z7.array(
3468
- z7.object({
3469
- url: z7.string().optional(),
3470
- content_type: z7.string().nullable().optional()
3638
+ var museImageResultSchema = z8.object({
3639
+ images: z8.array(
3640
+ z8.object({
3641
+ url: z8.string().optional(),
3642
+ content_type: z8.string().nullable().optional()
3471
3643
  })
3472
3644
  ).optional()
3473
3645
  });
@@ -3571,8 +3743,8 @@ function klingO1Input(req) {
3571
3743
  if (refs.length > 0) input.image_urls = refs;
3572
3744
  return input;
3573
3745
  }
3574
- var falVideoResultSchema = z7.object({
3575
- video: z7.object({ url: z7.string().optional() }).optional()
3746
+ var falVideoResultSchema = z8.object({
3747
+ video: z8.object({ url: z8.string().optional() }).optional()
3576
3748
  });
3577
3749
  function extractVideoUrl(result, endpoint, model) {
3578
3750
  const parsed = falVideoResultSchema.safeParse(result);
@@ -3652,7 +3824,7 @@ async function submitQueueJob(ctx, req, deps, endpoint, input) {
3652
3824
  throw falSdkError(cause, ctx.model.id);
3653
3825
  }
3654
3826
  },
3655
- ctx.signal !== void 0 ? { signal: ctx.signal } : {}
3827
+ mediaRetryOptions(ctx.call, ctx.signal)
3656
3828
  );
3657
3829
  } catch (cause) {
3658
3830
  throw falSdkError(cause, ctx.model.id);
@@ -3681,6 +3853,7 @@ function queuedVideoJob(ctx, req, client2, endpoint, requestId) {
3681
3853
  if (status === "IN_QUEUE") return { status: "pending" };
3682
3854
  return { status: "running" };
3683
3855
  } catch (cause) {
3856
+ if (ctx.call.maxRetries === 0) throw cause;
3684
3857
  if (isModelKitError(cause) && !cause.retryable)
3685
3858
  return { status: "failed" };
3686
3859
  return { status: "pending" };
@@ -3704,7 +3877,7 @@ function queuedVideoJob(ctx, req, client2, endpoint, requestId) {
3704
3877
  return await client2.queue.result(endpoint, queueOptions);
3705
3878
  } catch (cause) {
3706
3879
  const err = falSdkError(cause, ctx.model.id);
3707
- if (err.retryable) return void 0;
3880
+ if (ctx.call.maxRetries !== 0 && err.retryable) return void 0;
3708
3881
  throw err;
3709
3882
  }
3710
3883
  }, pollOptions);
@@ -3752,6 +3925,7 @@ async function passthroughVideoJob(ctx, req, endpoint, input) {
3752
3925
  const url = await checkStatus();
3753
3926
  return url ? { status: "succeeded" } : { status: "pending" };
3754
3927
  } catch (cause) {
3928
+ if (ctx.call.maxRetries === 0) throw cause;
3755
3929
  if (isModelKitError(cause) && !cause.retryable)
3756
3930
  return { status: "failed" };
3757
3931
  return { status: "pending" };
@@ -3771,13 +3945,13 @@ async function passthroughVideoJob(ctx, req, endpoint, input) {
3771
3945
  }
3772
3946
 
3773
3947
  // src/adapters/google-genai.ts
3774
- import { z as z9 } from "zod";
3948
+ import { z as z10 } from "zod";
3775
3949
  import {
3776
3950
  GoogleGenAI
3777
3951
  } from "@google/genai";
3778
3952
 
3779
3953
  // src/adapters/google-files.ts
3780
- import { z as z8 } from "zod";
3954
+ import { z as z9 } from "zod";
3781
3955
  var GOOGLE_FILES_BASE = "https://generativelanguage.googleapis.com";
3782
3956
  var GOOGLE_FILES_POLL_INTERVAL_MS = 2e3;
3783
3957
  var GOOGLE_FILES_POLL_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -3787,17 +3961,17 @@ var GENERIC_MEDIA_TYPES = /* @__PURE__ */ new Set([
3787
3961
  "binary/octet-stream",
3788
3962
  "application/binary"
3789
3963
  ]);
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()
3964
+ var uploadedFileSchema = z9.object({
3965
+ file: z9.object({
3966
+ uri: z9.string().optional(),
3967
+ name: z9.string().optional(),
3968
+ state: z9.string().optional(),
3969
+ mimeType: z9.string().optional()
3796
3970
  }).optional()
3797
3971
  });
3798
- var fileStateSchema = z8.object({
3799
- state: z8.string().optional(),
3800
- error: z8.object({ message: z8.string().optional() }).optional()
3972
+ var fileStateSchema = z9.object({
3973
+ state: z9.string().optional(),
3974
+ error: z9.object({ message: z9.string().optional() }).optional()
3801
3975
  });
3802
3976
  function resolveMime(declared, fallback) {
3803
3977
  const clean = declared?.split(";")[0]?.trim().toLowerCase();
@@ -3931,7 +4105,7 @@ async function waitForActive(fileName, opts) {
3931
4105
  }
3932
4106
  return void 0;
3933
4107
  }
3934
- if (res.status === 429 || res.status >= 500) return void 0;
4108
+ if (opts.maxRetries !== 0 && (res.status === 429 || res.status >= 500)) return void 0;
3935
4109
  const text2 = await res.text().catch(() => "");
3936
4110
  throw classifyHttpError(res.status, text2, "google-genai", opts.model);
3937
4111
  }, pollOptions);
@@ -3955,8 +4129,7 @@ async function uploadGoogleFile(source, opts) {
3955
4129
  opts.model
3956
4130
  );
3957
4131
  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;
4132
+ const retryOptions = mediaRetryOptions(opts, opts.signal);
3960
4133
  const uploaded = await withRetry(() => startAndUpload(bytes, mimeType, opts), retryOptions);
3961
4134
  if (uploaded.state !== "ACTIVE") {
3962
4135
  try {
@@ -3971,7 +4144,12 @@ async function uploadGoogleFile(source, opts) {
3971
4144
 
3972
4145
  // src/adapters/google-genai.ts
3973
4146
  function defaultCreateGenAIClient(opts) {
3974
- const sdk = new GoogleGenAI({ ...opts, vertexai: false });
4147
+ const sdk = new GoogleGenAI({
4148
+ apiKey: opts.apiKey,
4149
+ vertexai: false,
4150
+ ...opts.maxRetries !== void 0 ? { httpOptions: { retryOptions: { attempts: 1 } } } : {}
4151
+ });
4152
+ const interactionOptions = opts.maxRetries === void 0 ? void 0 : { maxRetries: 0, ...opts.signal !== void 0 ? { signal: opts.signal } : {} };
3975
4153
  return {
3976
4154
  models: {
3977
4155
  generateVideos: async (body) => {
@@ -3992,11 +4170,11 @@ function defaultCreateGenAIClient(opts) {
3992
4170
  interactions: {
3993
4171
  create: async (args) => {
3994
4172
  const params = args;
3995
- const response = await sdk.interactions.create(params);
4173
+ const response = await sdk.interactions.create(params, interactionOptions);
3996
4174
  return response;
3997
4175
  },
3998
4176
  get: async (jobId, params) => {
3999
- const response = await sdk.interactions.get(jobId, params);
4177
+ const response = await sdk.interactions.get(jobId, params, interactionOptions);
4000
4178
  return response;
4001
4179
  }
4002
4180
  }
@@ -4010,7 +4188,7 @@ var OMNI_POLL_INTERVAL_MS = 1e4;
4010
4188
  var RESULT_TIMEOUT_MS2 = 15 * 60 * 1e3;
4011
4189
  var OMNI_INLINE_LIMIT_BYTES = 4 * 1024 * 1024;
4012
4190
  var MEDIA_PART_INLINE_LIMIT_BYTES = 20 * 1024 * 1024;
4013
- var errorTextSchema = z9.string();
4191
+ var errorTextSchema = z10.string();
4014
4192
  function isGoogleGenaiVideoKnown(providerModelId) {
4015
4193
  return providerModelId.startsWith("veo-") || providerModelId.startsWith("gemini-omni");
4016
4194
  }
@@ -4165,7 +4343,11 @@ async function generateVeoVideo(req, ctx, createGenAIClient) {
4165
4343
  referenceType: "ASSET"
4166
4344
  }));
4167
4345
  }
4168
- const client2 = createGenAIClient({ apiKey });
4346
+ const client2 = createGenAIClient({
4347
+ apiKey,
4348
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {},
4349
+ ...ctx.signal !== void 0 ? { signal: ctx.signal } : {}
4350
+ });
4169
4351
  const config = { durationSeconds: duration, personGeneration };
4170
4352
  if (req.aspectRatio !== void 0) config.aspectRatio = req.aspectRatio;
4171
4353
  if (req.resolution !== void 0) config.resolution = req.resolution;
@@ -4178,8 +4360,7 @@ async function generateVeoVideo(req, ctx, createGenAIClient) {
4178
4360
  config
4179
4361
  };
4180
4362
  if (image !== void 0) requestBody.image = image;
4181
- const retryOptions = { attempts: 3 };
4182
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
4363
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4183
4364
  let operation;
4184
4365
  try {
4185
4366
  operation = await withRetry(async () => {
@@ -4292,7 +4473,11 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4292
4473
  if (omniResolution !== void 0) responseFormat.resolution = omniResolution;
4293
4474
  }
4294
4475
  if (req.durationSeconds !== void 0) responseFormat.duration = `${req.durationSeconds}s`;
4295
- const client2 = createGenAIClient({ apiKey });
4476
+ const client2 = createGenAIClient({
4477
+ apiKey,
4478
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {},
4479
+ ...ctx.signal !== void 0 ? { signal: ctx.signal } : {}
4480
+ });
4296
4481
  const uploadedByUri = /* @__PURE__ */ new Map();
4297
4482
  const uploadedNames = [];
4298
4483
  const uploadOne = async (kind, bytes, mime) => {
@@ -4303,6 +4488,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4303
4488
  label: "gemini-omni"
4304
4489
  };
4305
4490
  if (ctx.signal !== void 0) uploadOptions.signal = ctx.signal;
4491
+ if (ctx.call.maxRetries !== void 0) uploadOptions.maxRetries = ctx.call.maxRetries;
4306
4492
  const file = await uploadGoogleFile({ bytes, mime }, uploadOptions);
4307
4493
  uploadedByUri.set(file.fileUri, { type: kind, bytes, mime: file.mimeType });
4308
4494
  uploadedNames.push(file.fileName);
@@ -4318,8 +4504,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4318
4504
  generation_config: { video_config: { task } },
4319
4505
  store: true
4320
4506
  });
4321
- const createRetryOptions = { attempts: 3 };
4322
- if (ctx.signal !== void 0) createRetryOptions.signal = ctx.signal;
4507
+ const createRetryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4323
4508
  let interaction;
4324
4509
  try {
4325
4510
  const parts = [];
@@ -4389,7 +4574,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
4389
4574
  }
4390
4575
  }, createRetryOptions);
4391
4576
  } catch (cause) {
4392
- if (uploadedByUri.size === 0 || !isFileReferenceRejected(cause))
4577
+ if (ctx.call.maxRetries !== void 0 || uploadedByUri.size === 0 || !isFileReferenceRejected(cause))
4393
4578
  throwSdkError(cause, modelId);
4394
4579
  const inlineParts = parts.map((part) => {
4395
4580
  if (part.uri === void 0) return part;
@@ -4499,9 +4684,12 @@ async function generateLyriaAudio(req, ctx, createGenAIClient) {
4499
4684
  const image = await resolveMedia(ref, ctx.fetch, ctx.signal, "image/jpeg", modelId);
4500
4685
  parts.push({ inlineData: { mimeType: image.mime, data: toBase64(image.bytes) } });
4501
4686
  }
4502
- const client2 = createGenAIClient({ apiKey });
4503
- const retryOptions = { attempts: 3 };
4504
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
4687
+ const client2 = createGenAIClient({
4688
+ apiKey,
4689
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {},
4690
+ ...ctx.signal !== void 0 ? { signal: ctx.signal } : {}
4691
+ });
4692
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4505
4693
  let response;
4506
4694
  try {
4507
4695
  response = await withRetry(async () => {
@@ -4563,6 +4751,7 @@ async function prepareGoogleMediaPart(ref, mediaType, ctx) {
4563
4751
  label: "media-part"
4564
4752
  };
4565
4753
  if (ctx.signal !== void 0) uploadOptions.signal = ctx.signal;
4754
+ if (ctx.call.maxRetries !== void 0) uploadOptions.maxRetries = ctx.call.maxRetries;
4566
4755
  const file = await uploadGoogleFile({ bytes: ref.bytes, mime: mediaType }, uploadOptions);
4567
4756
  return {
4568
4757
  type: "file",
@@ -4575,15 +4764,15 @@ async function prepareGoogleMediaPart(ref, mediaType, ctx) {
4575
4764
  // src/adapters/google-image.ts
4576
4765
  import { createGoogleGenerativeAI as createGoogleGenerativeAI2 } from "@ai-sdk/google";
4577
4766
  import { generateText } from "ai";
4578
- import { z as z10 } from "zod";
4767
+ import { z as z11 } from "zod";
4579
4768
  var GEMINI_IMAGE_TIMEOUT_MS = 6e5;
4580
4769
  var defaultGoogleImageDeps = {
4581
4770
  createGoogleClient: (opts) => createGoogleGenerativeAI2(opts),
4582
4771
  runTextGeneration: (opts) => generateText(opts)
4583
4772
  };
4584
- var causeChainNodeSchema = z10.object({
4585
- message: z10.string().optional(),
4586
- cause: z10.unknown().optional()
4773
+ var causeChainNodeSchema = z11.object({
4774
+ message: z11.string().optional(),
4775
+ cause: z11.unknown().optional()
4587
4776
  });
4588
4777
  function extractBlockReason(cause) {
4589
4778
  let current = cause;
@@ -4651,8 +4840,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
4651
4840
  responseModalities: ["IMAGE"]
4652
4841
  };
4653
4842
  if (req.safetySettings !== void 0) googleOptions.safetySettings = req.safetySettings;
4654
- const retryOptions = {};
4655
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
4843
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4656
4844
  const result = await withRetry(async () => {
4657
4845
  const timeout = AbortSignal.timeout(GEMINI_IMAGE_TIMEOUT_MS);
4658
4846
  const signal = ctx.signal !== void 0 ? AbortSignal.any([ctx.signal, timeout]) : timeout;
@@ -4704,7 +4892,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
4704
4892
  var googleImageAdapter = createGoogleImageAdapter();
4705
4893
 
4706
4894
  // src/adapters/higgsfield.ts
4707
- import { z as z11 } from "zod";
4895
+ import { z as z12 } from "zod";
4708
4896
 
4709
4897
  // src/adapters/higgsfield-motions.ts
4710
4898
  var MOTION_MAP = {
@@ -4903,14 +5091,14 @@ function videoUsage3(ctx, req, duration) {
4903
5091
  if (req.durationSeconds !== void 0) event.durationSeconds = req.durationSeconds;
4904
5092
  return event;
4905
5093
  }
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(),
5094
+ var klingCreateSchema = z12.object({ status_url: z12.string() });
5095
+ var klingStatusSchema = z12.object({
5096
+ status: z12.string().optional(),
5097
+ video: z12.object({ url: z12.string().optional() }).optional(),
4910
5098
  error: JsonValueSchema.optional()
4911
5099
  });
4912
- var errorMessageSchema = z11.object({ message: z11.string().optional() });
4913
- var textValueSchema = z11.string();
5100
+ var errorMessageSchema = z12.object({ message: z12.string().optional() });
5101
+ var textValueSchema = z12.string();
4914
5102
  function klingErrorDetail(error) {
4915
5103
  if (error === void 0) return "unknown_error";
4916
5104
  const asText = textValueSchema.safeParse(error);
@@ -4959,8 +5147,7 @@ async function generateKlingVideo(req, ctx) {
4959
5147
  body.aspect_ratio = req.aspectRatio;
4960
5148
  if (req.lastFrame) body.last_image_url = refToUrl(req.lastFrame);
4961
5149
  const endpoint = klingEndpoint(ctx.model.providerModelId, ctx.model.id);
4962
- const retryOptions = {};
4963
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
5150
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
4964
5151
  const createRes = await withRetry(
4965
5152
  () => createRequest(ctx, endpoint, { method: "POST", body: JSON.stringify(body) }),
4966
5153
  retryOptions
@@ -4980,10 +5167,12 @@ async function generateKlingVideo(req, ctx) {
4980
5167
  let res;
4981
5168
  try {
4982
5169
  res = await ctx.fetch(statusUrl, requestInit(ctx, { method: "GET" }));
4983
- } catch {
5170
+ } catch (cause) {
5171
+ if (ctx.call.maxRetries === 0) throw classifyThrown("higgsfield", cause, ctx.model.id);
4984
5172
  return void 0;
4985
5173
  }
4986
- if (res.status === 429 || res.status >= 500) return void 0;
5174
+ if (ctx.call.maxRetries !== 0 && (res.status === 429 || res.status >= 500))
5175
+ return void 0;
4987
5176
  if (!res.ok) {
4988
5177
  throw classifyHttpError(res.status, await readBody(res), "higgsfield", ctx.model.id);
4989
5178
  }
@@ -5025,6 +5214,7 @@ async function generateKlingVideo(req, ctx) {
5025
5214
  const url = await check();
5026
5215
  return url ? { status: "succeeded" } : { status: "pending" };
5027
5216
  } catch (cause) {
5217
+ if (ctx.call.maxRetries === 0) throw cause;
5028
5218
  if (isModelKitError(cause) && !cause.retryable) return { status: "failed" };
5029
5219
  throw cause;
5030
5220
  }
@@ -5044,8 +5234,8 @@ async function generateKlingVideo(req, ctx) {
5044
5234
  }
5045
5235
  };
5046
5236
  }
5047
- var dopMotionOptionsSchema = z11.object({
5048
- modelkit: z11.object({ motion: z11.string().optional() }).optional()
5237
+ var dopMotionOptionsSchema = z12.object({
5238
+ modelkit: z12.object({ motion: z12.string().optional() }).optional()
5049
5239
  });
5050
5240
  function dopMotionId(ctx) {
5051
5241
  const parsed = dopMotionOptionsSchema.safeParse(ctx.model.providerOptions);
@@ -5061,7 +5251,7 @@ function dopMotionId(ctx) {
5061
5251
  });
5062
5252
  return id;
5063
5253
  }
5064
- var jsonRecordSchema = z11.record(z11.string(), JsonValueSchema);
5254
+ var jsonRecordSchema = z12.record(z12.string(), JsonValueSchema);
5065
5255
  var DOP_URL_KEYS = ["url", "video_url", "output_url", "result_url", "download_url"];
5066
5256
  var DOP_NESTED_KEYS = ["video", "result", "results"];
5067
5257
  function dopUrl(body) {
@@ -5089,8 +5279,8 @@ function dopUrl(body) {
5089
5279
  }
5090
5280
  return void 0;
5091
5281
  }
5092
- var dopCreateSchema = z11.object({ id: z11.string() });
5093
- var dopStatusSchema = z11.object({ status: z11.string().optional() });
5282
+ var dopCreateSchema = z12.object({ id: z12.string() });
5283
+ var dopStatusSchema = z12.object({ status: z12.string().optional() });
5094
5284
  async function generateDopVideo(req, ctx) {
5095
5285
  const firstFrame = req.firstFrame ? refToUrl(req.firstFrame) : void 0;
5096
5286
  if (!firstFrame) {
@@ -5115,8 +5305,7 @@ async function generateDopVideo(req, ctx) {
5115
5305
  params.input_images_end = [{ type: "image_url", image_url: refToUrl(req.lastFrame) }];
5116
5306
  }
5117
5307
  if (req.seed !== void 0) params.seed = req.seed;
5118
- const retryOptions = {};
5119
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
5308
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
5120
5309
  const createRes = await withRetry(
5121
5310
  () => createRequest(ctx, DOP_ENDPOINT, {
5122
5311
  method: "POST",
@@ -5140,10 +5329,18 @@ async function generateDopVideo(req, ctx) {
5140
5329
  let res;
5141
5330
  try {
5142
5331
  res = await ctx.fetch(statusUrl, requestInit(ctx, { method: "GET" }));
5143
- } catch {
5332
+ } catch (cause) {
5333
+ if (ctx.call.maxRetries === 0) throw classifyThrown("higgsfield", cause, ctx.model.id);
5144
5334
  return void 0;
5145
5335
  }
5146
5336
  if (!res.ok) {
5337
+ if (ctx.call.maxRetries === 0)
5338
+ throw classifyHttpError(
5339
+ res.status,
5340
+ await readBody(res),
5341
+ "higgsfield",
5342
+ ctx.model.id
5343
+ );
5147
5344
  return void 0;
5148
5345
  }
5149
5346
  const payload = JsonValueSchema.parse(await res.json());
@@ -5180,6 +5377,7 @@ async function generateDopVideo(req, ctx) {
5180
5377
  const url = await check();
5181
5378
  return url ? { status: "succeeded" } : { status: "pending" };
5182
5379
  } catch (cause) {
5380
+ if (ctx.call.maxRetries === 0) throw cause;
5183
5381
  if (isModelKitError(cause) && !cause.retryable) return { status: "failed" };
5184
5382
  throw cause;
5185
5383
  }
@@ -5210,7 +5408,7 @@ var higgsfieldAdapter = {
5210
5408
 
5211
5409
  // src/adapters/openai-image.ts
5212
5410
  import OpenAI from "openai";
5213
- import { z as z12 } from "zod";
5411
+ import { z as z13 } from "zod";
5214
5412
  var MAX_EDIT_REFERENCES = 16;
5215
5413
  function aspectRatioToSize(ratio, tier) {
5216
5414
  const TIER_LONG_EDGE = {
@@ -5293,9 +5491,9 @@ function toProviderError2(cause, ctx) {
5293
5491
  ctx.model.id
5294
5492
  );
5295
5493
  }
5296
- var openaiUsageSchema = z12.object({
5297
- input_tokens: z12.number().optional(),
5298
- output_tokens: z12.number().optional()
5494
+ var openaiUsageSchema = z13.object({
5495
+ input_tokens: z13.number().optional(),
5496
+ output_tokens: z13.number().optional()
5299
5497
  });
5300
5498
  var openaiImageAdapter = {
5301
5499
  id: "openai-image",
@@ -5337,8 +5535,7 @@ var openaiImageAdapter = {
5337
5535
  }
5338
5536
  const format = outputFormat !== void 0 ? { output_format: outputFormat } : {};
5339
5537
  const mime = outputFormat === "jpeg" ? "image/jpeg" : "image/png";
5340
- const retryOptions = {};
5341
- if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
5538
+ const retryOptions = mediaRetryOptions(ctx.call, ctx.signal);
5342
5539
  const response = await withRetry(async () => {
5343
5540
  try {
5344
5541
  if (!isEdit) {
@@ -5658,13 +5855,7 @@ async function generateProdiaImage(req, ctx) {
5658
5855
  })
5659
5856
  );
5660
5857
  });
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;
5858
+ const retryOpts = mediaRetryOptions(ctx.call, ctx.signal);
5668
5859
  let res;
5669
5860
  try {
5670
5861
  res = await withRetry(async () => {
@@ -5711,7 +5902,66 @@ var prodiaAdapter = {
5711
5902
 
5712
5903
  // src/adapters/replicate.ts
5713
5904
  import Replicate from "replicate";
5714
- import { z as z13 } from "zod";
5905
+
5906
+ // src/adapters/replicate-http.ts
5907
+ import { z as z14 } from "zod";
5908
+ var predictionSchema = z14.object({
5909
+ id: z14.string(),
5910
+ status: z14.string(),
5911
+ output: JsonValueSchema.optional(),
5912
+ error: JsonValueSchema.optional(),
5913
+ metrics: z14.object({ predict_time: z14.number().optional() }).optional()
5914
+ });
5915
+ function createReplicateHttpClient(opts) {
5916
+ async function request(path, body, signal) {
5917
+ let response;
5918
+ try {
5919
+ response = await opts.fetch(`https://api.replicate.com/v1${path}`, {
5920
+ method: body === void 0 ? "GET" : "POST",
5921
+ headers: {
5922
+ Authorization: `Bearer ${opts.auth}`,
5923
+ "Content-Type": "application/json"
5924
+ },
5925
+ ...body !== void 0 ? { body: JSON.stringify(body) } : {},
5926
+ ...signal !== void 0 ? { signal } : {}
5927
+ });
5928
+ } catch (cause) {
5929
+ throw classifyThrown("replicate", cause);
5930
+ }
5931
+ if (!response.ok)
5932
+ throw classifyHttpError(response.status, await response.text(), "replicate");
5933
+ const parsed = predictionSchema.parse(await response.json());
5934
+ return {
5935
+ id: parsed.id,
5936
+ status: parsed.status,
5937
+ ...parsed.output !== void 0 ? { output: parsed.output } : {},
5938
+ ...parsed.error !== void 0 ? { error: parsed.error } : {},
5939
+ ...parsed.metrics?.predict_time !== void 0 ? { metrics: { predict_time: parsed.metrics.predict_time } } : {}
5940
+ };
5941
+ }
5942
+ return {
5943
+ predictions: {
5944
+ create(options) {
5945
+ if (options.version) {
5946
+ return request(
5947
+ "/predictions",
5948
+ { input: options.input, version: options.version },
5949
+ options.signal
5950
+ );
5951
+ }
5952
+ return request(
5953
+ `/models/${options.model}/predictions`,
5954
+ { input: options.input },
5955
+ options.signal
5956
+ );
5957
+ },
5958
+ get: (id, options) => request(`/predictions/${encodeURIComponent(id)}`, void 0, options?.signal)
5959
+ }
5960
+ };
5961
+ }
5962
+
5963
+ // src/adapters/replicate.ts
5964
+ import { z as z15 } from "zod";
5715
5965
 
5716
5966
  // src/adapters/input-spec-mapper.ts
5717
5967
  function canonicalValue(req, key) {
@@ -5750,7 +6000,7 @@ function applyInputSpec(spec, req, refToUrl2, opts) {
5750
6000
  var POLL_INTERVAL_MS = 1e3;
5751
6001
  var POLL_TIMEOUT_MS = 15 * 6e4;
5752
6002
  var defaultReplicateDeps = {
5753
- createReplicateClient: (opts) => new Replicate(opts)
6003
+ createReplicateClient: (opts) => opts.maxRetries === void 0 ? new Replicate(opts) : createReplicateHttpClient(opts)
5754
6004
  };
5755
6005
  function createReplicateAdapter(deps = defaultReplicateDeps) {
5756
6006
  return {
@@ -5772,7 +6022,11 @@ function client(ctx, deps) {
5772
6022
  retryable: false
5773
6023
  });
5774
6024
  }
5775
- return deps.createReplicateClient({ auth: token, fetch: ctx.fetch });
6025
+ return deps.createReplicateClient({
6026
+ auth: token,
6027
+ fetch: ctx.fetch,
6028
+ ...ctx.call.maxRetries !== void 0 ? { maxRetries: ctx.call.maxRetries } : {}
6029
+ });
5776
6030
  }
5777
6031
  function route(providerModelId) {
5778
6032
  if (providerModelId.includes(":")) {
@@ -5782,8 +6036,8 @@ function route(providerModelId) {
5782
6036
  if (!providerModelId.includes("/")) return { version: providerModelId };
5783
6037
  return { model: providerModelId };
5784
6038
  }
5785
- var replicateResponseStatusSchema = z13.object({
5786
- response: z13.object({ status: z13.number() }).partial()
6039
+ var replicateResponseStatusSchema = z15.object({
6040
+ response: z15.object({ status: z15.number() }).partial()
5787
6041
  });
5788
6042
  function replicateError(cause, ctx) {
5789
6043
  if (isModelKitError(cause)) return cause;
@@ -5810,7 +6064,7 @@ function isUrlFn(value) {
5810
6064
  function extractOutputUrl(output) {
5811
6065
  const root = Array.isArray(output) ? output[0] : output;
5812
6066
  if (root === void 0) throw noOutput();
5813
- const asString = z13.string().safeParse(root);
6067
+ const asString = z15.string().safeParse(root);
5814
6068
  if (asString.success && asString.data) return asString.data;
5815
6069
  if (root instanceof URL) return root.href;
5816
6070
  if (isObjectOutput(root)) {
@@ -5819,15 +6073,15 @@ function extractOutputUrl(output) {
5819
6073
  if (urlValue !== void 0 && isUrlFn(urlValue)) {
5820
6074
  const called = urlValue();
5821
6075
  if (called instanceof URL) return called.href;
5822
- const calledString = z13.string().safeParse(called);
6076
+ const calledString = z15.string().safeParse(called);
5823
6077
  if (calledString.success && calledString.data) return calledString.data;
5824
6078
  } else {
5825
- const direct = z13.string().safeParse(urlValue);
6079
+ const direct = z15.string().safeParse(urlValue);
5826
6080
  if (direct.success && direct.data) return direct.data;
5827
6081
  }
5828
6082
  }
5829
6083
  if ("default" in root) {
5830
- const fallback = z13.string().safeParse(root.default);
6084
+ const fallback = z15.string().safeParse(root.default);
5831
6085
  if (fallback.success && fallback.data) return fallback.data;
5832
6086
  }
5833
6087
  }
@@ -5857,7 +6111,7 @@ async function runPrediction(ctx, input, deps) {
5857
6111
  throw replicateError(cause, ctx);
5858
6112
  }
5859
6113
  },
5860
- { attempts: 1 }
6114
+ mediaRetryOptions(ctx.call, ctx.signal, 1)
5861
6115
  );
5862
6116
  } catch (cause) {
5863
6117
  throw replicateError(cause, ctx);
@@ -5888,7 +6142,7 @@ async function runPrediction(ctx, input, deps) {
5888
6142
  }
5889
6143
  return void 0;
5890
6144
  }, pollOpts);
5891
- const predictTime = z13.number().safeParse(done.metrics?.predict_time);
6145
+ const predictTime = z15.number().safeParse(done.metrics?.predict_time);
5892
6146
  if (done.output === void 0) throw noOutput();
5893
6147
  return {
5894
6148
  url: extractOutputUrl(done.output),
@@ -6256,7 +6510,7 @@ async function generateReplicateVideo(req, ctx, deps) {
6256
6510
  throw replicateError(cause, ctx);
6257
6511
  }
6258
6512
  },
6259
- { attempts: 1 }
6513
+ mediaRetryOptions(ctx.call, ctx.signal, 1)
6260
6514
  );
6261
6515
  } catch (cause) {
6262
6516
  throw replicateError(cause, ctx);
@@ -6273,7 +6527,7 @@ async function generateReplicateVideo(req, ctx, deps) {
6273
6527
  throw replicateError(cause, ctx);
6274
6528
  }
6275
6529
  if (current.status === "succeeded") {
6276
- const predictTime = z13.number().safeParse(current.metrics?.predict_time);
6530
+ const predictTime = z15.number().safeParse(current.metrics?.predict_time);
6277
6531
  if (current.output === void 0) throw noOutput();
6278
6532
  return {
6279
6533
  url: extractOutputUrl(current.output),
@@ -6336,8 +6590,8 @@ function lyriaAudioInput(req, ctx) {
6336
6590
  if (negative) input.negative_prompt = negative;
6337
6591
  return input;
6338
6592
  }
6339
- function elevenLabsMusicDuration(seconds) {
6340
- return Math.min(300, Math.max(5, seconds ?? 15));
6593
+ function elevenLabsMusicDuration(seconds2) {
6594
+ return Math.min(300, Math.max(5, seconds2 ?? 15));
6341
6595
  }
6342
6596
  function elevenLabsMusicInput(req, ctx) {
6343
6597
  const prompt = req.prompt.trim();
@@ -6402,9 +6656,9 @@ async function generateReplicateAudio(req, ctx, deps) {
6402
6656
  const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
6403
6657
  const usage2 = audioUsage(ctx, req);
6404
6658
  if (ctx.model.usage.unit === "seconds") {
6405
- const seconds = elevenLabsMusicDuration(req.durationSeconds);
6406
- usage2.quantity = seconds;
6407
- usage2.durationSeconds = seconds;
6659
+ const seconds2 = elevenLabsMusicDuration(req.durationSeconds);
6660
+ usage2.quantity = seconds2;
6661
+ usage2.durationSeconds = seconds2;
6408
6662
  } else {
6409
6663
  usage2.quantity = predictTime;
6410
6664
  }
@@ -6414,7 +6668,7 @@ async function generateReplicateAudio(req, ctx, deps) {
6414
6668
  // src/adapters/xai-video.ts
6415
6669
  import { experimental_generateVideo } from "ai";
6416
6670
  import { createXai as createXai2 } from "@ai-sdk/xai";
6417
- import { z as z14 } from "zod";
6671
+ import { z as z16 } from "zod";
6418
6672
  var POLL_INTERVAL_MS2 = 1e4;
6419
6673
  var POLL_TIMEOUT_MS2 = 15 * 6e4;
6420
6674
  var defaultXaiDeps = {
@@ -6427,8 +6681,8 @@ function createXaiVideoAdapter(deps = defaultXaiDeps) {
6427
6681
  };
6428
6682
  }
6429
6683
  var xaiVideoAdapter = createXaiVideoAdapter();
6430
- var xaiResponseStatusSchema = z14.object({
6431
- response: z14.object({ status: z14.number() }).partial()
6684
+ var xaiResponseStatusSchema = z16.object({
6685
+ response: z16.object({ status: z16.number() }).partial()
6432
6686
  });
6433
6687
  function xaiError(cause, ctx) {
6434
6688
  const info = describeThrown(cause);
@@ -6436,12 +6690,12 @@ function xaiError(cause, ctx) {
6436
6690
  const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
6437
6691
  return classifyThrown("xai-video", cause, ctx.model.id, { status, body: info.body });
6438
6692
  }
6439
- var xaiMetaSchema = z14.object({
6693
+ var xaiMetaSchema = z16.object({
6440
6694
  videoUrl: JsonValueSchema.optional(),
6441
6695
  costInUsdTicks: JsonValueSchema.optional(),
6442
6696
  duration: JsonValueSchema.optional()
6443
6697
  });
6444
- var xaiProviderMetadataSchema = z14.object({ xai: xaiMetaSchema });
6698
+ var xaiProviderMetadataSchema = z16.object({ xai: xaiMetaSchema });
6445
6699
  function metaOf(result) {
6446
6700
  const parsed = xaiProviderMetadataSchema.partial().safeParse(result.providerMetadata);
6447
6701
  if (!parsed.success) return {};
@@ -6492,6 +6746,7 @@ async function generateXaiVideo(req, ctx, deps) {
6492
6746
  }
6493
6747
  if (req.durationSeconds !== void 0) callBody.duration = req.durationSeconds;
6494
6748
  if (ctx.signal) callBody.abortSignal = ctx.signal;
6749
+ if (ctx.call.maxRetries !== void 0) callBody.maxRetries = ctx.call.maxRetries;
6495
6750
  const pending = (async () => {
6496
6751
  try {
6497
6752
  return await client2.generateVideo(callBody);
@@ -6548,7 +6803,7 @@ async function mapResult(ctx, req, result) {
6548
6803
  };
6549
6804
  }
6550
6805
  const meta = metaOf(result);
6551
- const videoUrl = z14.string().safeParse(meta.videoUrl);
6806
+ const videoUrl = z16.string().safeParse(meta.videoUrl);
6552
6807
  if (videoUrl.success && videoUrl.data) {
6553
6808
  const res = await ctx.fetch(videoUrl.data);
6554
6809
  if (!res.ok) {
@@ -6571,7 +6826,7 @@ async function mapResult(ctx, req, result) {
6571
6826
  });
6572
6827
  }
6573
6828
  function usage(ctx, req, meta) {
6574
- const costTicks = z14.number().safeParse(meta.costInUsdTicks);
6829
+ const costTicks = z16.number().safeParse(meta.costInUsdTicks);
6575
6830
  const cost = costTicks.success ? costTicks.data / 1e10 : void 0;
6576
6831
  const event = {
6577
6832
  model: ctx.model.id,
@@ -6704,22 +6959,22 @@ var liveState = store[KEY] ??= {
6704
6959
  var liveCatalog = liveState.catalog;
6705
6960
 
6706
6961
  // src/catalog/load.ts
6707
- import { z as z15 } from "zod";
6962
+ import { z as z17 } from "zod";
6708
6963
  function rowCount() {
6709
6964
  return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
6710
6965
  }
6711
6966
  function authHeaders(auth) {
6712
6967
  return "bearer" in auth ? { Authorization: `Bearer ${auth.bearer}` } : { "x-api-key": auth.apiKey };
6713
6968
  }
6714
- var EnvelopeSchema = z15.object({
6715
- rows: z15.array(JsonValueSchema),
6716
- revision: z15.string().optional()
6969
+ var EnvelopeSchema = z17.object({
6970
+ rows: z17.array(JsonValueSchema),
6971
+ revision: z17.string().optional()
6717
6972
  });
6718
6973
  function dropReason(path, message) {
6719
6974
  return path.length === 0 ? message : `${path.map((part) => String(part)).join(".")} ${message}`;
6720
6975
  }
6721
6976
  function rowId(raw) {
6722
- const parsed = z15.object({ id: z15.string().min(1) }).loose().safeParse(raw);
6977
+ const parsed = z17.object({ id: z17.string().min(1) }).loose().safeParse(raw);
6723
6978
  if (!parsed.success) return "?";
6724
6979
  return parsed.data.id;
6725
6980
  }
@@ -7043,6 +7298,49 @@ function trim(field, refs, limit, model, warnings) {
7043
7298
  });
7044
7299
  return refs.slice(0, limit);
7045
7300
  }
7301
+ function knownLength(value) {
7302
+ return value !== void 0 && Number.isFinite(value) ? value : void 0;
7303
+ }
7304
+ function seconds(len, limit) {
7305
+ let digits = 1;
7306
+ while (digits < 3 && Number(len.toFixed(digits)) === limit) digits++;
7307
+ return len.toFixed(digits);
7308
+ }
7309
+ function effectiveMin(limits, taskType) {
7310
+ if (taskType !== "edit" || limits?.editMin === void 0) return limits?.min;
7311
+ return Math.max(limits.min ?? 0, limits.editMin);
7312
+ }
7313
+ function videoLengthViolation(model, input) {
7314
+ const limits = model.constraints.references?.videoSeconds;
7315
+ const refMin = effectiveMin(limits, input.taskType);
7316
+ const lengths = (input.referenceVideos ?? []).map(knownLength);
7317
+ if (limits?.max !== void 0) {
7318
+ const max = limits.max;
7319
+ const i = lengths.findIndex((len) => len !== void 0 && len > max);
7320
+ if (i >= 0)
7321
+ return `${model.label} takes reference videos up to ${String(max)} s each; video ${i + 1} is ${seconds(lengths[i], max)} s.`;
7322
+ }
7323
+ if (refMin !== void 0) {
7324
+ const i = lengths.findIndex((len) => len !== void 0 && len < refMin);
7325
+ if (i >= 0)
7326
+ return `${model.label} takes reference videos of at least ${String(refMin)} s each; video ${i + 1} is ${seconds(lengths[i], refMin)} s.`;
7327
+ }
7328
+ const source = knownLength(input.sourceVideo);
7329
+ const sourceLimits = model.constraints.sourceVideoSeconds;
7330
+ if (limits?.total !== void 0) {
7331
+ const refSum = lengths.reduce((acc, len) => acc + (len ?? 0), 0);
7332
+ const sum = refSum + (sourceLimits?.inReferenceTotal ? source ?? 0 : 0);
7333
+ if (sum > limits.total)
7334
+ return `${model.label} takes reference videos up to ${String(limits.total)} s combined; these add up to ${seconds(sum, limits.total)} s.`;
7335
+ }
7336
+ if (source === void 0) return void 0;
7337
+ const sourceMin = effectiveMin(sourceLimits, input.taskType);
7338
+ if (sourceLimits?.max !== void 0 && source > sourceLimits.max)
7339
+ return `${model.label} takes a source video up to ${String(sourceLimits.max)} s; this one is ${seconds(source, sourceLimits.max)} s.`;
7340
+ if (sourceMin !== void 0 && source < sourceMin)
7341
+ return `${model.label} takes a source video of at least ${String(sourceMin)} s; this one is ${seconds(source, sourceMin)} s.`;
7342
+ return void 0;
7343
+ }
7046
7344
  function resolveImageOptions(model, request, onUnsupported = "error") {
7047
7345
  const warnings = [];
7048
7346
  const c = model.constraints;
@@ -7228,6 +7526,21 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
7228
7526
  model: model.id
7229
7527
  });
7230
7528
  }
7529
+ const lengthViolation = videoLengthViolation(model, {
7530
+ referenceVideos: videos.map((v) => v.durationSeconds),
7531
+ taskType: merged.taskType,
7532
+ ...merged.sourceVideo?.durationSeconds !== void 0 && {
7533
+ sourceVideo: merged.sourceVideo.durationSeconds
7534
+ }
7535
+ });
7536
+ if (lengthViolation !== void 0) {
7537
+ throw new ModelKitError({
7538
+ code: "unsupported_option",
7539
+ message: lengthViolation,
7540
+ model: model.id,
7541
+ retryable: false
7542
+ });
7543
+ }
7231
7544
  setOrDelete(merged, "referenceImages", images);
7232
7545
  setOrDelete(merged, "referenceVideos", videos);
7233
7546
  setOrDelete(merged, "referenceAudios", audios);
@@ -7479,7 +7792,7 @@ import {
7479
7792
  streamObject as aiStreamObject2,
7480
7793
  streamText as aiStreamText2
7481
7794
  } from "ai";
7482
- import { z as z16 } from "zod";
7795
+ import { z as z18 } from "zod";
7483
7796
 
7484
7797
  // src/generated-image.ts
7485
7798
  function toGeneratedImage(image) {
@@ -7554,10 +7867,10 @@ function textAbortOptions(sdk, context) {
7554
7867
  if (abortSignal) return { abortSignal };
7555
7868
  return {};
7556
7869
  }
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"]);
7870
+ var catalogId = z18.string();
7871
+ var exactSize = z18.templateLiteral([z18.number(), "x", z18.number()]);
7872
+ var sdkRatio = z18.templateLiteral([z18.number(), ":", z18.number()]);
7873
+ var sizeTier = z18.enum(["512", "1K", "2K", "4K"]);
7561
7874
  function isCatalogId(model) {
7562
7875
  return catalogId.safeParse(model).success;
7563
7876
  }
@@ -7748,6 +8061,7 @@ function createModelKit(config, adapters) {
7748
8061
  logCoercions(logger, model.modelId, warnings);
7749
8062
  const abortSignal = combineSignals(req.abortSignal, call.signal);
7750
8063
  if (abortSignal) options.abortSignal = abortSignal;
8064
+ if (call.maxRetries !== void 0) options.maxRetries = call.maxRetries;
7751
8065
  const result = await aiGenerateImage(options);
7752
8066
  const images = result.images.map(
7753
8067
  (file) => toGeneratedImage({ bytes: file.uint8Array, mime: file.mediaType })
@@ -7784,15 +8098,16 @@ function createModelKit(config, adapters) {
7784
8098
  promptExpansion: _promptExpansion,
7785
8099
  mode: _mode
7786
8100
  } = req;
7787
- const seconds = duration ?? durationSeconds;
8101
+ const seconds2 = duration ?? durationSeconds;
7788
8102
  const abortSignal = combineSignals(req.abortSignal, call.signal);
7789
8103
  const options = { model, prompt };
8104
+ if (call.maxRetries !== void 0) options.maxRetries = call.maxRetries;
7790
8105
  const warnings = [];
7791
8106
  const ratio = sdkAspectRatio(aspectRatio) ?? (aspectRatio === "adaptive" ? "adaptive" : void 0);
7792
8107
  if (ratio) options.aspectRatio = ratio;
7793
8108
  else if (aspectRatio !== void 0)
7794
8109
  pushIgnored(warnings, "aspectRatio", aspectRatio, model.modelId);
7795
- if (seconds !== void 0) options.duration = seconds;
8110
+ if (seconds2 !== void 0) options.duration = seconds2;
7796
8111
  if (seed !== void 0) options.seed = seed;
7797
8112
  if (generateAudio2 !== void 0) options.generateAudio = generateAudio2;
7798
8113
  const frames = [
@@ -7839,8 +8154,8 @@ function createModelKit(config, adapters) {
7839
8154
  provider: model.provider,
7840
8155
  modality: "VIDEO",
7841
8156
  unit: "seconds",
7842
- quantity: seconds ?? 0,
7843
- ...seconds !== void 0 && { durationSeconds: seconds }
8157
+ quantity: seconds2 ?? 0,
8158
+ ...seconds2 !== void 0 && { durationSeconds: seconds2 }
7844
8159
  };
7845
8160
  settled = {
7846
8161
  video: { bytes: result.video.uint8Array, mime: result.video.mediaType },
@@ -7868,6 +8183,7 @@ function createModelKit(config, adapters) {
7868
8183
  catalog,
7869
8184
  describe: (id) => catalog.require(id),
7870
8185
  async generateImage(req, call = {}) {
8186
+ mediaRetryOptions(call);
7871
8187
  if (!isCatalogId(req.model)) {
7872
8188
  return passthroughImage({ ...req, model: req.model }, call);
7873
8189
  }
@@ -7911,6 +8227,7 @@ function createModelKit(config, adapters) {
7911
8227
  return { ...result, usage: usage2, image: first, images, warnings };
7912
8228
  },
7913
8229
  async generateVideo(req, call = {}) {
8230
+ mediaRetryOptions(call);
7914
8231
  if (!isCatalogId(req.model)) {
7915
8232
  return passthroughVideo({ ...req, model: req.model }, call);
7916
8233
  }
@@ -7965,6 +8282,7 @@ function createModelKit(config, adapters) {
7965
8282
  };
7966
8283
  },
7967
8284
  async generateAudio(req, call = {}) {
8285
+ mediaRetryOptions(call);
7968
8286
  const model = catalog.require(req.model);
7969
8287
  if (model.type !== "audio") {
7970
8288
  throw new ModelKitError({
@@ -7994,6 +8312,7 @@ function createModelKit(config, adapters) {
7994
8312
  return result;
7995
8313
  },
7996
8314
  async prepareMediaPart(modelId, ref, mediaType, call = {}) {
8315
+ mediaRetryOptions(call);
7997
8316
  const model = catalog.require(modelId);
7998
8317
  const { adapter, ctx } = context(model, call, []);
7999
8318
  const fileStore = model.adapter === "ai-sdk-text" && textKeyName(model) === "google" ? adapters["google-genai"] : adapter;
@@ -8186,6 +8505,7 @@ export {
8186
8505
  textUsageEvent,
8187
8506
  toGeneratedImage,
8188
8507
  validateInputSpec,
8508
+ videoLengthViolation,
8189
8509
  withRetry,
8190
8510
  xaiVideoAdapter
8191
8511
  };