@shop-os/modelkit 0.1.3 → 0.1.5
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/README.md +42 -19
- package/dist/index.cjs +500 -339
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -3
- package/dist/index.d.ts +14 -3
- package/dist/index.js +500 -339
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -165,7 +165,19 @@ var Catalog = class _Catalog {
|
|
|
165
165
|
|
|
166
166
|
// src/catalog/image.ts
|
|
167
167
|
var IMAGE_USAGE = { unit: "images", modality: "IMAGE" };
|
|
168
|
-
var GEMINI_RATIOS = [
|
|
168
|
+
var GEMINI_RATIOS = [
|
|
169
|
+
"1:1",
|
|
170
|
+
"2:3",
|
|
171
|
+
"3:2",
|
|
172
|
+
"16:9",
|
|
173
|
+
"9:16",
|
|
174
|
+
"4:3",
|
|
175
|
+
"3:4",
|
|
176
|
+
"21:9",
|
|
177
|
+
"4:5",
|
|
178
|
+
"5:4",
|
|
179
|
+
"adaptive"
|
|
180
|
+
];
|
|
169
181
|
function geminiImage(id, label, aliases, sizes) {
|
|
170
182
|
const model = {
|
|
171
183
|
id,
|
|
@@ -175,7 +187,7 @@ function geminiImage(id, label, aliases, sizes) {
|
|
|
175
187
|
adapter: "google-image",
|
|
176
188
|
providerModelId: id,
|
|
177
189
|
lifecycle: "active",
|
|
178
|
-
constraints: { aspectRatios: [...GEMINI_RATIOS], sizes },
|
|
190
|
+
constraints: { aspectRatios: [...GEMINI_RATIOS], sizes, supports: ["safetySettings"] },
|
|
179
191
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
180
192
|
usage: { ...IMAGE_USAGE },
|
|
181
193
|
pricingKind: "image_size"
|
|
@@ -188,7 +200,8 @@ var IMAGE_MODELS = [
|
|
|
188
200
|
"gemini-3.1-flash-image-preview",
|
|
189
201
|
"Nano Banana Flash",
|
|
190
202
|
["nb-2"],
|
|
191
|
-
|
|
203
|
+
// Flash 3.1 is the only Gemini image model with the 512 tier.
|
|
204
|
+
["512", "1K", "2K", "4K"]
|
|
192
205
|
),
|
|
193
206
|
geminiImage("gemini-3.1-flash-lite-image", "Nano Banana Lite", ["nb-lite"], ["1K"]),
|
|
194
207
|
// trigger-workflows validates 1K only; pricing seeds 2K/4K rows so allow all three.
|
|
@@ -271,7 +284,8 @@ var IMAGE_MODELS = [
|
|
|
271
284
|
"9:16",
|
|
272
285
|
"4:5",
|
|
273
286
|
"5:4",
|
|
274
|
-
"9:21"
|
|
287
|
+
"9:21",
|
|
288
|
+
"adaptive"
|
|
275
289
|
],
|
|
276
290
|
sizes: ["1K"],
|
|
277
291
|
references: { images: 10 },
|
|
@@ -332,9 +346,10 @@ var IMAGE_MODELS = [
|
|
|
332
346
|
constraints: {
|
|
333
347
|
aspectRatios: ["1:1", "2:3", "3:2", "16:9", "9:16", "4:3", "3:4", "4:5", "5:4", "21:9"],
|
|
334
348
|
sizes: ["1K"],
|
|
335
|
-
|
|
349
|
+
// flux-2-pro's job type always returns image/png; only the seed is forwarded.
|
|
350
|
+
supports: ["seed"]
|
|
336
351
|
},
|
|
337
|
-
defaults: { size: "1K", aspectRatio: "1:1"
|
|
352
|
+
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
338
353
|
usage: { ...IMAGE_USAGE },
|
|
339
354
|
pricingKind: "image_size"
|
|
340
355
|
},
|
|
@@ -352,7 +367,8 @@ var IMAGE_MODELS = [
|
|
|
352
367
|
constraints: {
|
|
353
368
|
aspectRatios: ["1:1", "2:3", "3:2", "4:3", "3:4", "4:5", "5:4", "9:16", "16:9", "21:9"],
|
|
354
369
|
sizes: ["1K", "2K", "4K"],
|
|
355
|
-
requires: ["references"]
|
|
370
|
+
requires: ["references"],
|
|
371
|
+
supports: ["seed"]
|
|
356
372
|
},
|
|
357
373
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
358
374
|
usage: { ...IMAGE_USAGE },
|
|
@@ -371,7 +387,8 @@ var IMAGE_MODELS = [
|
|
|
371
387
|
constraints: {
|
|
372
388
|
aspectRatios: ["1:1", "2:3", "3:4", "4:3", "9:16", "16:9", "21:9"],
|
|
373
389
|
sizes: ["1K"],
|
|
374
|
-
requires: ["references"]
|
|
390
|
+
requires: ["references"],
|
|
391
|
+
supports: ["seed"]
|
|
375
392
|
},
|
|
376
393
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
377
394
|
usage: { ...IMAGE_USAGE },
|
|
@@ -391,7 +408,8 @@ var IMAGE_MODELS = [
|
|
|
391
408
|
constraints: {
|
|
392
409
|
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4"],
|
|
393
410
|
sizes: ["1K", "2K", "4K"],
|
|
394
|
-
references: { images: 9 }
|
|
411
|
+
references: { images: 9 },
|
|
412
|
+
supports: []
|
|
395
413
|
},
|
|
396
414
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
397
415
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
@@ -412,7 +430,8 @@ var IMAGE_MODELS = [
|
|
|
412
430
|
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"],
|
|
413
431
|
sizes: [],
|
|
414
432
|
references: { images: 1 },
|
|
415
|
-
requires: ["references"]
|
|
433
|
+
requires: ["references"],
|
|
434
|
+
supports: []
|
|
416
435
|
},
|
|
417
436
|
defaults: { aspectRatio: "1:1" },
|
|
418
437
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
@@ -454,7 +473,8 @@ var OTHER_MODELS = [
|
|
|
454
473
|
lifecycle: "active",
|
|
455
474
|
constraints: {
|
|
456
475
|
durations: [30],
|
|
457
|
-
references: { images: 10 }
|
|
476
|
+
references: { images: 10 },
|
|
477
|
+
supports: []
|
|
458
478
|
},
|
|
459
479
|
defaults: {},
|
|
460
480
|
usage: { unit: "images", modality: "AUDIO" },
|
|
@@ -469,7 +489,8 @@ var OTHER_MODELS = [
|
|
|
469
489
|
providerModelId: "lyria-3-pro-preview",
|
|
470
490
|
lifecycle: "active",
|
|
471
491
|
constraints: {
|
|
472
|
-
references: { images: 10 }
|
|
492
|
+
references: { images: 10 },
|
|
493
|
+
supports: []
|
|
473
494
|
},
|
|
474
495
|
defaults: {},
|
|
475
496
|
usage: { unit: "images", modality: "AUDIO" },
|
|
@@ -533,8 +554,12 @@ var OTHER_MODELS = [
|
|
|
533
554
|
adapter: "replicate",
|
|
534
555
|
providerModelId: "topazlabs/image-upscale",
|
|
535
556
|
lifecycle: "active",
|
|
536
|
-
constraints: {
|
|
537
|
-
|
|
557
|
+
constraints: {
|
|
558
|
+
references: { images: 1 },
|
|
559
|
+
requires: ["references"],
|
|
560
|
+
supports: ["scaleFactor", "outputFormat"]
|
|
561
|
+
},
|
|
562
|
+
defaults: { scaleFactor: 2, outputFormat: "png" },
|
|
538
563
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
539
564
|
pricingKind: "flat"
|
|
540
565
|
},
|
|
@@ -548,7 +573,8 @@ var OTHER_MODELS = [
|
|
|
548
573
|
lifecycle: "active",
|
|
549
574
|
constraints: {
|
|
550
575
|
references: { images: 1 },
|
|
551
|
-
requires: ["references"]
|
|
576
|
+
requires: ["references"],
|
|
577
|
+
supports: []
|
|
552
578
|
},
|
|
553
579
|
defaults: {},
|
|
554
580
|
usage: { unit: "images", modality: "IMAGE" },
|
|
@@ -567,7 +593,7 @@ function text(id, label, providerModelId, extra) {
|
|
|
567
593
|
adapter: "ai-sdk-text",
|
|
568
594
|
providerModelId,
|
|
569
595
|
lifecycle: "active",
|
|
570
|
-
constraints: {},
|
|
596
|
+
constraints: { supports: [] },
|
|
571
597
|
defaults: {},
|
|
572
598
|
usage: { ...TEXT_USAGE },
|
|
573
599
|
pricingKind: "token",
|
|
@@ -590,7 +616,7 @@ var TEXT_MODELS = [
|
|
|
590
616
|
text("gpt-5.6-sol", "GPT-5.6 Sol", "gpt-5.6-sol"),
|
|
591
617
|
// Library key "claude-sonnet-4.5" maps to the SDK id "claude-sonnet-4-5".
|
|
592
618
|
text("claude-sonnet-4-5", "Claude Sonnet 4.5", "claude-sonnet-4-5", {
|
|
593
|
-
aliases: ["claude-sonnet-4.5"]
|
|
619
|
+
aliases: ["claude-sonnet-4.5", "claude-sonnet-4-5-20250929"]
|
|
594
620
|
}),
|
|
595
621
|
// Anthropic retired the dated 4.0 ids; callers that still send them get 4.6.
|
|
596
622
|
text("claude-sonnet-4-6", "Claude Sonnet 4.6", "claude-sonnet-4-6", {
|
|
@@ -606,7 +632,7 @@ var TEXT_MODELS = [
|
|
|
606
632
|
aliases: ["claude-opus-4.8", "claude-opus-4", "claude-opus-4.0", "claude-opus-4-20250514"]
|
|
607
633
|
}),
|
|
608
634
|
text("claude-haiku-4-5", "Claude Haiku 4.5", "claude-haiku-4-5", {
|
|
609
|
-
aliases: ["claude-haiku-4.5", "claude-haiku-4-5-20251001"]
|
|
635
|
+
aliases: ["claude-haiku-4.5", "claude-haiku-4-5-20251001", "claude-haiku-4"]
|
|
610
636
|
}),
|
|
611
637
|
text("claude-opus-5", "Claude Opus 5", "claude-opus-5", {
|
|
612
638
|
aliases: ["claude-opus-5.0"]
|
|
@@ -640,7 +666,7 @@ var TEXT_MODELS = [
|
|
|
640
666
|
// src/catalog/video.ts
|
|
641
667
|
var VIDEO_USAGE = { unit: "seconds", modality: "VIDEO" };
|
|
642
668
|
var SEEDANCE_RATIOS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16", "adaptive"];
|
|
643
|
-
var KLING_RATIOS = ["16:9", "9:16", "1:1"];
|
|
669
|
+
var KLING_RATIOS = ["16:9", "9:16", "1:1", "adaptive"];
|
|
644
670
|
var OMNI_RATIOS = ["16:9", "9:16"];
|
|
645
671
|
var GROK_RATIOS = ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"];
|
|
646
672
|
var H3_RATIOS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16"];
|
|
@@ -732,12 +758,15 @@ var VIDEO_MODELS = [
|
|
|
732
758
|
providerModelId: "gemini-omni-flash-preview",
|
|
733
759
|
lifecycle: "active",
|
|
734
760
|
constraints: {
|
|
761
|
+
// 1.0 rejects `resolution`; it renders 720p. No defaults: the adapter
|
|
762
|
+
// sends ratio and duration only when the caller set them, so a
|
|
763
|
+
// reference clip keeps its own framing.
|
|
735
764
|
aspectRatios: [...OMNI_RATIOS],
|
|
736
|
-
resolutions: ["720p"],
|
|
737
765
|
durations: [3, 4, 5, 6, 7, 8, 9, 10],
|
|
738
|
-
references: { images: 6, videos: 1 }
|
|
766
|
+
references: { images: 6, videos: 1 },
|
|
767
|
+
supports: []
|
|
739
768
|
},
|
|
740
|
-
defaults: {
|
|
769
|
+
defaults: {},
|
|
741
770
|
usage: { ...VIDEO_USAGE },
|
|
742
771
|
pricingKind: "video_per_second"
|
|
743
772
|
},
|
|
@@ -753,9 +782,10 @@ var VIDEO_MODELS = [
|
|
|
753
782
|
aspectRatios: [...OMNI_RATIOS],
|
|
754
783
|
resolutions: ["360p", "720p", "1080p", "4k"],
|
|
755
784
|
durations: [3, 4, 5, 6, 7, 8, 9, 10],
|
|
756
|
-
references: { images: 6, videos: 1 }
|
|
785
|
+
references: { images: 6, videos: 1 },
|
|
786
|
+
supports: []
|
|
757
787
|
},
|
|
758
|
-
defaults: {
|
|
788
|
+
defaults: {},
|
|
759
789
|
usage: { ...VIDEO_USAGE },
|
|
760
790
|
pricingKind: "video_per_second"
|
|
761
791
|
},
|
|
@@ -849,7 +879,8 @@ var VIDEO_MODELS = [
|
|
|
849
879
|
aspectRatios: [...GROK_RATIOS],
|
|
850
880
|
resolutions: ["480p", "720p"],
|
|
851
881
|
durations: { min: 1, max: 15 },
|
|
852
|
-
references: { images: 7 }
|
|
882
|
+
references: { images: 7 },
|
|
883
|
+
supports: []
|
|
853
884
|
},
|
|
854
885
|
defaults: { durationSeconds: 8, resolution: "720p", aspectRatio: "16:9" },
|
|
855
886
|
usage: { unit: "reported_cost_usd", modality: "VIDEO" },
|
|
@@ -1039,7 +1070,8 @@ var VIDEO_MODELS = [
|
|
|
1039
1070
|
constraints: {
|
|
1040
1071
|
aspectRatios: [...KLING_RATIOS],
|
|
1041
1072
|
durations: { min: 3, max: 10 },
|
|
1042
|
-
requires: ["sourceVideo"]
|
|
1073
|
+
requires: ["sourceVideo"],
|
|
1074
|
+
supports: []
|
|
1043
1075
|
},
|
|
1044
1076
|
defaults: { durationSeconds: 5, aspectRatio: "16:9" },
|
|
1045
1077
|
usage: { ...VIDEO_USAGE },
|
|
@@ -1072,7 +1104,7 @@ var VIDEO_MODELS = [
|
|
|
1072
1104
|
lifecycle: "active",
|
|
1073
1105
|
constraints: {
|
|
1074
1106
|
requires: ["firstFrame"],
|
|
1075
|
-
supports: ["seed"]
|
|
1107
|
+
supports: ["seed", "lastFrame"]
|
|
1076
1108
|
},
|
|
1077
1109
|
defaults: {},
|
|
1078
1110
|
usage: { ...VIDEO_USAGE },
|
|
@@ -1089,7 +1121,7 @@ var MODELS = [
|
|
|
1089
1121
|
];
|
|
1090
1122
|
|
|
1091
1123
|
// src/resolve-options.ts
|
|
1092
|
-
var SIZE_ORDER = ["1K", "2K", "4K"];
|
|
1124
|
+
var SIZE_ORDER = ["512", "1K", "2K", "4K"];
|
|
1093
1125
|
var RESOLUTION_ORDER = ["360p", "480p", "720p", "768p", "1080p", "2k", "4k"];
|
|
1094
1126
|
function ratioValue(r) {
|
|
1095
1127
|
if (r === "adaptive") return 1;
|
|
@@ -1183,7 +1215,7 @@ function resolveImageOptions(model, request, onUnsupported = "error") {
|
|
|
1183
1215
|
const warnings = [];
|
|
1184
1216
|
const c = model.constraints;
|
|
1185
1217
|
const merged = { ...model.defaults, ...stripUndefined(request), model: model.id };
|
|
1186
|
-
if (merged.aspectRatio && c.aspectRatios && !c.aspectRatios.includes(merged.aspectRatio)) {
|
|
1218
|
+
if (merged.aspectRatio !== void 0 && merged.aspectRatio !== "adaptive" && c.aspectRatios !== void 0 && !c.aspectRatios.includes(merged.aspectRatio)) {
|
|
1187
1219
|
const to = nearestAspectRatio(merged.aspectRatio, c.aspectRatios);
|
|
1188
1220
|
warnings.push({
|
|
1189
1221
|
code: "ratio_coerced",
|
|
@@ -1221,7 +1253,14 @@ function resolveImageOptions(model, request, onUnsupported = "error") {
|
|
|
1221
1253
|
model: model.id
|
|
1222
1254
|
});
|
|
1223
1255
|
}
|
|
1224
|
-
dropUnsupported(merged, model, warnings, [
|
|
1256
|
+
dropUnsupported(merged, model, warnings, [
|
|
1257
|
+
"seed",
|
|
1258
|
+
"quality",
|
|
1259
|
+
"count",
|
|
1260
|
+
"outputFormat",
|
|
1261
|
+
"scaleFactor",
|
|
1262
|
+
"safetySettings"
|
|
1263
|
+
]);
|
|
1225
1264
|
return { request: merged, warnings };
|
|
1226
1265
|
}
|
|
1227
1266
|
function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
@@ -1250,7 +1289,7 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
1250
1289
|
delete merged.aspectRatio;
|
|
1251
1290
|
}
|
|
1252
1291
|
}
|
|
1253
|
-
if (merged.aspectRatio && c.aspectRatios && !c.aspectRatios.includes(merged.aspectRatio)) {
|
|
1292
|
+
if (merged.aspectRatio !== void 0 && merged.aspectRatio !== "adaptive" && c.aspectRatios !== void 0 && !c.aspectRatios.includes(merged.aspectRatio)) {
|
|
1254
1293
|
const to = nearestAspectRatio(merged.aspectRatio, c.aspectRatios);
|
|
1255
1294
|
warnings.push({
|
|
1256
1295
|
code: "ratio_coerced",
|
|
@@ -1332,8 +1371,7 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
1332
1371
|
return { request: merged, warnings };
|
|
1333
1372
|
}
|
|
1334
1373
|
function dropUnsupported(req, model, warnings, fields) {
|
|
1335
|
-
const supports = model.constraints.supports;
|
|
1336
|
-
if (!supports) return;
|
|
1374
|
+
const supports = model.constraints.supports ?? [];
|
|
1337
1375
|
for (const field of fields) {
|
|
1338
1376
|
if (req[field] !== void 0 && !supports.includes(field)) {
|
|
1339
1377
|
warnings.push({
|
|
@@ -1411,8 +1449,45 @@ function keysFromEnv(env, prefix = "") {
|
|
|
1411
1449
|
}
|
|
1412
1450
|
|
|
1413
1451
|
// src/retry.ts
|
|
1452
|
+
var import_zod2 = require("zod");
|
|
1453
|
+
|
|
1454
|
+
// src/json.ts
|
|
1414
1455
|
var import_zod = require("zod");
|
|
1415
|
-
var
|
|
1456
|
+
var JsonValueSchema = import_zod.z.lazy(
|
|
1457
|
+
() => import_zod.z.union([
|
|
1458
|
+
import_zod.z.string(),
|
|
1459
|
+
import_zod.z.number(),
|
|
1460
|
+
import_zod.z.boolean(),
|
|
1461
|
+
import_zod.z.null(),
|
|
1462
|
+
import_zod.z.array(JsonValueSchema),
|
|
1463
|
+
import_zod.z.record(import_zod.z.string(), JsonValueSchema)
|
|
1464
|
+
])
|
|
1465
|
+
);
|
|
1466
|
+
var JsonObjectSchema = import_zod.z.record(import_zod.z.string(), JsonValueSchema);
|
|
1467
|
+
async function readErrorBody(res) {
|
|
1468
|
+
const text2 = await res.text().catch(() => "");
|
|
1469
|
+
try {
|
|
1470
|
+
return JsonValueSchema.parse(JSON.parse(text2));
|
|
1471
|
+
} catch {
|
|
1472
|
+
return text2;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
var thrownErrorSchema = import_zod.z.object({
|
|
1476
|
+
message: import_zod.z.string().optional(),
|
|
1477
|
+
status: import_zod.z.number().optional(),
|
|
1478
|
+
statusCode: import_zod.z.number().optional(),
|
|
1479
|
+
responseBody: import_zod.z.string().optional()
|
|
1480
|
+
});
|
|
1481
|
+
function describeThrown(cause) {
|
|
1482
|
+
const parsed = thrownErrorSchema.safeParse(cause);
|
|
1483
|
+
if (!parsed.success) return { message: String(cause), status: void 0, body: String(cause) };
|
|
1484
|
+
const { message, status, statusCode, responseBody } = parsed.data;
|
|
1485
|
+
const body = responseBody ?? message ?? String(cause);
|
|
1486
|
+
return { message: message ?? String(cause), status: status ?? statusCode, body };
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
// src/retry.ts
|
|
1490
|
+
var textBody = import_zod2.z.string();
|
|
1416
1491
|
function classifyHttpError(status, body, provider, model) {
|
|
1417
1492
|
const asText = textBody.safeParse(body);
|
|
1418
1493
|
const text2 = asText.success ? asText.data : JSON.stringify(body);
|
|
@@ -1495,6 +1570,13 @@ function transportError(provider, cause, model) {
|
|
|
1495
1570
|
if (model !== void 0) init.model = model;
|
|
1496
1571
|
return new ModelKitError(init);
|
|
1497
1572
|
}
|
|
1573
|
+
function classifyThrown(provider, cause, model, override = {}) {
|
|
1574
|
+
if (cause instanceof ModelKitError) return cause;
|
|
1575
|
+
const info = describeThrown(cause);
|
|
1576
|
+
const status = override.status ?? info.status;
|
|
1577
|
+
if (status === void 0) return transportError(provider, cause, model);
|
|
1578
|
+
return classifyHttpError(status, override.body ?? info.body, provider, model);
|
|
1579
|
+
}
|
|
1498
1580
|
async function pollUntil(check, opts) {
|
|
1499
1581
|
const start = Date.now();
|
|
1500
1582
|
let interval = opts.intervalMs;
|
|
@@ -1610,7 +1692,7 @@ function createTextSteps(initial, resolve, callerProviderOptions) {
|
|
|
1610
1692
|
|
|
1611
1693
|
// src/client.ts
|
|
1612
1694
|
var import_ai2 = require("ai");
|
|
1613
|
-
var
|
|
1695
|
+
var import_zod4 = require("zod");
|
|
1614
1696
|
|
|
1615
1697
|
// src/adapters/media-ref.ts
|
|
1616
1698
|
function isUrlRef(ref) {
|
|
@@ -1665,7 +1747,7 @@ var import_perplexity = require("@ai-sdk/perplexity");
|
|
|
1665
1747
|
var import_xai = require("@ai-sdk/xai");
|
|
1666
1748
|
var import_deepseek = require("@ai-sdk/deepseek");
|
|
1667
1749
|
var import_moonshotai = require("@ai-sdk/moonshotai");
|
|
1668
|
-
var
|
|
1750
|
+
var import_zod3 = require("zod");
|
|
1669
1751
|
var TEXT_PROVIDERS = [
|
|
1670
1752
|
"openai",
|
|
1671
1753
|
"anthropic",
|
|
@@ -1676,7 +1758,7 @@ var TEXT_PROVIDERS = [
|
|
|
1676
1758
|
"moonshot",
|
|
1677
1759
|
"minimax"
|
|
1678
1760
|
];
|
|
1679
|
-
var textProviderSchema =
|
|
1761
|
+
var textProviderSchema = import_zod3.z.enum(TEXT_PROVIDERS);
|
|
1680
1762
|
function isTextProvider(value) {
|
|
1681
1763
|
return textProviderSchema.safeParse(value).success;
|
|
1682
1764
|
}
|
|
@@ -1685,9 +1767,9 @@ var OPENAI_COMPATIBLE_BASE_URLS = {
|
|
|
1685
1767
|
};
|
|
1686
1768
|
var GATEWAY_SLUGS = {
|
|
1687
1769
|
openai: "openai",
|
|
1688
|
-
anthropic: "anthropic",
|
|
1770
|
+
anthropic: "anthropic/v1",
|
|
1689
1771
|
google: "google-ai-studio/v1beta",
|
|
1690
|
-
xai: "grok",
|
|
1772
|
+
xai: "grok/v1",
|
|
1691
1773
|
perplexity: "perplexity-ai",
|
|
1692
1774
|
deepseek: "deepseek"
|
|
1693
1775
|
};
|
|
@@ -1862,10 +1944,10 @@ function textAbortOptions(sdk, context) {
|
|
|
1862
1944
|
if (abortSignal) return { abortSignal };
|
|
1863
1945
|
return {};
|
|
1864
1946
|
}
|
|
1865
|
-
var catalogId =
|
|
1866
|
-
var exactSize =
|
|
1867
|
-
var sdkRatio =
|
|
1868
|
-
var sizeTier =
|
|
1947
|
+
var catalogId = import_zod4.z.string();
|
|
1948
|
+
var exactSize = import_zod4.z.templateLiteral([import_zod4.z.number(), "x", import_zod4.z.number()]);
|
|
1949
|
+
var sdkRatio = import_zod4.z.templateLiteral([import_zod4.z.number(), ":", import_zod4.z.number()]);
|
|
1950
|
+
var sizeTier = import_zod4.z.enum(["512", "1K", "2K", "4K"]);
|
|
1869
1951
|
function isCatalogId(model) {
|
|
1870
1952
|
return catalogId.safeParse(model).success;
|
|
1871
1953
|
}
|
|
@@ -1922,6 +2004,10 @@ function pushIgnored(warnings, field, from, modelId) {
|
|
|
1922
2004
|
message: `${modelId} provider instance does not support ${field}; ignored`
|
|
1923
2005
|
});
|
|
1924
2006
|
}
|
|
2007
|
+
function logCoercions(logger, modelId, warnings) {
|
|
2008
|
+
if (warnings.length === 0) return;
|
|
2009
|
+
logger.warn(`[modelkit] ${modelId} request coerced`, { model: modelId, warnings });
|
|
2010
|
+
}
|
|
1925
2011
|
function createModelKit(config, adapters) {
|
|
1926
2012
|
const catalog = new Catalog(MODELS).withOverrides(config.catalogOverride ?? []);
|
|
1927
2013
|
const logger = config.logger ?? console;
|
|
@@ -1955,6 +2041,10 @@ function createModelKit(config, adapters) {
|
|
|
1955
2041
|
logger.warn("[modelkit] usage emit failed", err);
|
|
1956
2042
|
}
|
|
1957
2043
|
}
|
|
2044
|
+
function withRowUnit(event) {
|
|
2045
|
+
const row = catalog.get(event.model);
|
|
2046
|
+
return row ? { ...event, unit: row.usage.unit } : event;
|
|
2047
|
+
}
|
|
1958
2048
|
function textTarget(model, call) {
|
|
1959
2049
|
if (!isCatalogId(model)) {
|
|
1960
2050
|
return {
|
|
@@ -1995,6 +2085,7 @@ function createModelKit(config, adapters) {
|
|
|
1995
2085
|
providerOptions,
|
|
1996
2086
|
references,
|
|
1997
2087
|
exactSize: exactSizeField,
|
|
2088
|
+
scaleFactor,
|
|
1998
2089
|
quality: _quality,
|
|
1999
2090
|
outputFormat: _outputFormat
|
|
2000
2091
|
} = req;
|
|
@@ -2020,6 +2111,9 @@ function createModelKit(config, adapters) {
|
|
|
2020
2111
|
if (_quality !== void 0) pushIgnored(warnings, "quality", _quality, model.modelId);
|
|
2021
2112
|
if (_outputFormat !== void 0)
|
|
2022
2113
|
pushIgnored(warnings, "outputFormat", _outputFormat, model.modelId);
|
|
2114
|
+
if (scaleFactor !== void 0)
|
|
2115
|
+
pushIgnored(warnings, "scaleFactor", scaleFactor, model.modelId);
|
|
2116
|
+
logCoercions(logger, model.modelId, warnings);
|
|
2023
2117
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
2024
2118
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
2025
2119
|
const result = await (0, import_ai2.generateImage)(options);
|
|
@@ -2103,6 +2197,7 @@ function createModelKit(config, adapters) {
|
|
|
2103
2197
|
if (_mode !== void 0) pushIgnored(warnings, "mode", _mode, model.modelId);
|
|
2104
2198
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
2105
2199
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
2200
|
+
logCoercions(logger, model.modelId, warnings);
|
|
2106
2201
|
const pending = (0, import_ai2.experimental_generateVideo)(options);
|
|
2107
2202
|
let settled;
|
|
2108
2203
|
let failed = false;
|
|
@@ -2161,6 +2256,7 @@ function createModelKit(config, adapters) {
|
|
|
2161
2256
|
call.onUnsupported ?? "error"
|
|
2162
2257
|
);
|
|
2163
2258
|
warnings.push(...inputWarnings);
|
|
2259
|
+
logCoercions(logger, model.id, warnings);
|
|
2164
2260
|
const signal = combineSignals(req.abortSignal, call.signal);
|
|
2165
2261
|
const { adapter, ctx } = context(model, signal ? { ...call, signal } : call, warnings);
|
|
2166
2262
|
if (!adapter.generateImage)
|
|
@@ -2170,7 +2266,7 @@ function createModelKit(config, adapters) {
|
|
|
2170
2266
|
model: model.id
|
|
2171
2267
|
});
|
|
2172
2268
|
const result = await adapter.generateImage(request, ctx);
|
|
2173
|
-
const usage2 = { ...result.usage, model: model.id };
|
|
2269
|
+
const usage2 = { ...result.usage, model: model.id, unit: model.usage.unit };
|
|
2174
2270
|
await emit(usage2);
|
|
2175
2271
|
const images = result.images.map(toGeneratedImage);
|
|
2176
2272
|
const first = images[0];
|
|
@@ -2203,6 +2299,7 @@ function createModelKit(config, adapters) {
|
|
|
2203
2299
|
call.onUnsupported ?? "error"
|
|
2204
2300
|
);
|
|
2205
2301
|
warnings.push(...inputWarnings);
|
|
2302
|
+
logCoercions(logger, model.id, warnings);
|
|
2206
2303
|
const signal = combineSignals(req.abortSignal, call.signal);
|
|
2207
2304
|
const { adapter, ctx } = context(model, signal ? { ...call, signal } : call, warnings);
|
|
2208
2305
|
if (!adapter.generateVideo)
|
|
@@ -2220,7 +2317,11 @@ function createModelKit(config, adapters) {
|
|
|
2220
2317
|
result(opts) {
|
|
2221
2318
|
if (settled) return settled;
|
|
2222
2319
|
const pending = result(opts).then(
|
|
2223
|
-
(out) => emit({
|
|
2320
|
+
(out) => emit({
|
|
2321
|
+
...out.usage,
|
|
2322
|
+
model: model.id,
|
|
2323
|
+
unit: model.usage.unit
|
|
2324
|
+
}).then(() => out),
|
|
2224
2325
|
(cause) => {
|
|
2225
2326
|
settled = void 0;
|
|
2226
2327
|
throw cause;
|
|
@@ -2240,7 +2341,8 @@ function createModelKit(config, adapters) {
|
|
|
2240
2341
|
model: model.id
|
|
2241
2342
|
});
|
|
2242
2343
|
}
|
|
2243
|
-
const
|
|
2344
|
+
const warnings = [];
|
|
2345
|
+
const { adapter, ctx } = context(model, call, warnings);
|
|
2244
2346
|
if (!adapter.generateAudio) {
|
|
2245
2347
|
throw new ModelKitError({
|
|
2246
2348
|
code: "unsupported_option",
|
|
@@ -2252,7 +2354,8 @@ function createModelKit(config, adapters) {
|
|
|
2252
2354
|
{ ...model.defaults, ...req, model: model.id },
|
|
2253
2355
|
ctx
|
|
2254
2356
|
);
|
|
2255
|
-
|
|
2357
|
+
logCoercions(logger, model.id, warnings);
|
|
2358
|
+
await emit({ ...result.usage, model: model.id, unit: model.usage.unit });
|
|
2256
2359
|
return result;
|
|
2257
2360
|
},
|
|
2258
2361
|
async prepareMediaPart(modelId, ref, mediaType, call = {}) {
|
|
@@ -2292,7 +2395,7 @@ function createModelKit(config, adapters) {
|
|
|
2292
2395
|
options.prepareStep ?? options.experimental_prepareStep
|
|
2293
2396
|
)
|
|
2294
2397
|
});
|
|
2295
|
-
for (const event of steps.usage(result.steps)) await emit(event);
|
|
2398
|
+
for (const event of steps.usage(result.steps)) await emit(withRowUnit(event));
|
|
2296
2399
|
return result;
|
|
2297
2400
|
},
|
|
2298
2401
|
streamText(options, call = {}) {
|
|
@@ -2310,7 +2413,7 @@ function createModelKit(config, adapters) {
|
|
|
2310
2413
|
providerOptions: {},
|
|
2311
2414
|
prepareStep: steps.wrap(options.prepareStep),
|
|
2312
2415
|
onFinish: async (event) => {
|
|
2313
|
-
for (const usage2 of steps.usage(event.steps)) await emit(usage2);
|
|
2416
|
+
for (const usage2 of steps.usage(event.steps)) await emit(withRowUnit(usage2));
|
|
2314
2417
|
await callerOnFinish?.(event);
|
|
2315
2418
|
}
|
|
2316
2419
|
});
|
|
@@ -2324,7 +2427,7 @@ function createModelKit(config, adapters) {
|
|
|
2324
2427
|
providerOptions: mergeTextProviderOptions(entry, options.providerOptions)
|
|
2325
2428
|
};
|
|
2326
2429
|
const result = await (0, import_ai2.generateObject)(sdkOptions);
|
|
2327
|
-
await emit(textUsageEvent(entry, provider, result.usage));
|
|
2430
|
+
await emit(withRowUnit(textUsageEvent(entry, provider, result.usage)));
|
|
2328
2431
|
return result;
|
|
2329
2432
|
},
|
|
2330
2433
|
streamObject(options, call = {}) {
|
|
@@ -2336,7 +2439,7 @@ function createModelKit(config, adapters) {
|
|
|
2336
2439
|
model: languageModel2,
|
|
2337
2440
|
providerOptions: mergeTextProviderOptions(entry, options.providerOptions),
|
|
2338
2441
|
onFinish: async (event) => {
|
|
2339
|
-
await emit(textUsageEvent(entry, provider, event.usage));
|
|
2442
|
+
await emit(withRowUnit(textUsageEvent(entry, provider, event.usage)));
|
|
2340
2443
|
await callerOnFinish?.(event);
|
|
2341
2444
|
}
|
|
2342
2445
|
};
|
|
@@ -2346,7 +2449,7 @@ function createModelKit(config, adapters) {
|
|
|
2346
2449
|
}
|
|
2347
2450
|
|
|
2348
2451
|
// src/adapters/ark.ts
|
|
2349
|
-
var
|
|
2452
|
+
var import_zod5 = require("zod");
|
|
2350
2453
|
var ARK_BASE_URL = "https://ark.ap-southeast.bytepluses.com/api/v3";
|
|
2351
2454
|
var SUBMIT_PATH = "/contents/generations/tasks";
|
|
2352
2455
|
var SEEDANCE_POLL_INTERVAL_MS = 15e3;
|
|
@@ -2404,7 +2507,7 @@ function arkKey(ctx) {
|
|
|
2404
2507
|
return key;
|
|
2405
2508
|
}
|
|
2406
2509
|
function throwArkError(status, body, model) {
|
|
2407
|
-
const parsed =
|
|
2510
|
+
const parsed = import_zod5.z.string().safeParse(body);
|
|
2408
2511
|
const text2 = parsed.success ? parsed.data : JSON.stringify(body ?? "");
|
|
2409
2512
|
if (/sensitive.?content|inputimage|human.?face/i.test(text2)) {
|
|
2410
2513
|
const init = {
|
|
@@ -2418,6 +2521,16 @@ function throwArkError(status, body, model) {
|
|
|
2418
2521
|
if (status !== void 0) init.status = status;
|
|
2419
2522
|
throw new ModelKitError(init);
|
|
2420
2523
|
}
|
|
2524
|
+
if (status === void 0) {
|
|
2525
|
+
throw new ModelKitError({
|
|
2526
|
+
code: "provider_rejected",
|
|
2527
|
+
message: `ark rejected the request: ${text2.slice(0, 500)}`,
|
|
2528
|
+
provider: "ark",
|
|
2529
|
+
model,
|
|
2530
|
+
body,
|
|
2531
|
+
retryable: false
|
|
2532
|
+
});
|
|
2533
|
+
}
|
|
2421
2534
|
throw classifyHttpError(status, body, "ark", model);
|
|
2422
2535
|
}
|
|
2423
2536
|
function seedreamSize(aspect, size) {
|
|
@@ -2436,13 +2549,13 @@ function arkUrl(ref) {
|
|
|
2436
2549
|
if ("url" in ref) return ref.url;
|
|
2437
2550
|
return `data:${ref.mime};base64,${Buffer.from(ref.bytes).toString("base64")}`;
|
|
2438
2551
|
}
|
|
2439
|
-
var SeedreamImageSchema =
|
|
2440
|
-
url:
|
|
2441
|
-
b64_json:
|
|
2552
|
+
var SeedreamImageSchema = import_zod5.z.object({
|
|
2553
|
+
url: import_zod5.z.string().optional(),
|
|
2554
|
+
b64_json: import_zod5.z.string().optional()
|
|
2442
2555
|
});
|
|
2443
|
-
var SeedreamResponseSchema =
|
|
2444
|
-
data:
|
|
2445
|
-
error:
|
|
2556
|
+
var SeedreamResponseSchema = import_zod5.z.object({
|
|
2557
|
+
data: import_zod5.z.array(SeedreamImageSchema).optional(),
|
|
2558
|
+
error: import_zod5.z.object({ message: import_zod5.z.string().optional(), code: import_zod5.z.string().optional() }).optional()
|
|
2446
2559
|
});
|
|
2447
2560
|
function retryOptsFor(ctx, attempts = 3) {
|
|
2448
2561
|
const opts = { attempts };
|
|
@@ -2453,6 +2566,11 @@ function fetchInitFor(ctx, init) {
|
|
|
2453
2566
|
if (ctx.signal !== void 0) init.signal = ctx.signal;
|
|
2454
2567
|
return init;
|
|
2455
2568
|
}
|
|
2569
|
+
function arkFetch(ctx, url, init) {
|
|
2570
|
+
return ctx.fetch(url, fetchInitFor(ctx, init)).catch((cause) => {
|
|
2571
|
+
throw classifyThrown("ark", cause, ctx.model.id);
|
|
2572
|
+
});
|
|
2573
|
+
}
|
|
2456
2574
|
async function generateSeedreamImage(req, ctx) {
|
|
2457
2575
|
const key = arkKey(ctx);
|
|
2458
2576
|
const modelId = ctx.model.id;
|
|
@@ -2470,14 +2588,11 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2470
2588
|
if (refs.length === 1 && firstRef !== void 0) body.image = firstRef;
|
|
2471
2589
|
else if (refs.length > 1) body.image = refs;
|
|
2472
2590
|
const data = await withRetry(async () => {
|
|
2473
|
-
const res = await ctx
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
body: JSON.stringify(body)
|
|
2479
|
-
})
|
|
2480
|
-
);
|
|
2591
|
+
const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}/images/generations`, {
|
|
2592
|
+
method: "POST",
|
|
2593
|
+
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
2594
|
+
body: JSON.stringify(body)
|
|
2595
|
+
});
|
|
2481
2596
|
if (!res.ok) {
|
|
2482
2597
|
const text2 = await res.text().catch(() => "");
|
|
2483
2598
|
throwArkError(res.status, text2, modelId);
|
|
@@ -2492,7 +2607,7 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2492
2607
|
bytes = Buffer.from(first.b64_json, "base64");
|
|
2493
2608
|
} else if (first?.url) {
|
|
2494
2609
|
const imageUrl = first.url;
|
|
2495
|
-
const res = await ctx
|
|
2610
|
+
const res = await arkFetch(ctx, imageUrl, {});
|
|
2496
2611
|
if (!res.ok) {
|
|
2497
2612
|
const text2 = await res.text().catch(() => "");
|
|
2498
2613
|
throwArkError(res.status, text2, modelId);
|
|
@@ -2512,13 +2627,13 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2512
2627
|
if (req.quality !== void 0) usage2.imageQuality = req.quality;
|
|
2513
2628
|
return { images: [{ bytes, mime: sniffedImageMime(bytes) }], usage: usage2, raw: data };
|
|
2514
2629
|
}
|
|
2515
|
-
var SeedanceResponseSchema =
|
|
2516
|
-
id:
|
|
2517
|
-
status:
|
|
2518
|
-
content:
|
|
2519
|
-
error:
|
|
2630
|
+
var SeedanceResponseSchema = import_zod5.z.object({
|
|
2631
|
+
id: import_zod5.z.string().optional(),
|
|
2632
|
+
status: import_zod5.z.string().optional(),
|
|
2633
|
+
content: import_zod5.z.object({ video_url: import_zod5.z.string().optional() }).optional(),
|
|
2634
|
+
error: import_zod5.z.union([import_zod5.z.string(), import_zod5.z.object({ message: import_zod5.z.string().optional() })]).optional()
|
|
2520
2635
|
});
|
|
2521
|
-
var SeedanceErrorMessageSchema =
|
|
2636
|
+
var SeedanceErrorMessageSchema = import_zod5.z.object({ message: import_zod5.z.string().optional() });
|
|
2522
2637
|
function seedanceUsage(ctx, req, duration) {
|
|
2523
2638
|
const usage2 = {
|
|
2524
2639
|
model: ctx.model.id,
|
|
@@ -2532,7 +2647,7 @@ function seedanceUsage(ctx, req, duration) {
|
|
|
2532
2647
|
return usage2;
|
|
2533
2648
|
}
|
|
2534
2649
|
function seedanceErrorMessage(error, status) {
|
|
2535
|
-
const asString =
|
|
2650
|
+
const asString = import_zod5.z.string().safeParse(error);
|
|
2536
2651
|
if (asString.success) return asString.data;
|
|
2537
2652
|
const asObject = SeedanceErrorMessageSchema.safeParse(error);
|
|
2538
2653
|
if (asObject.success && asObject.data.message !== void 0) return asObject.data.message;
|
|
@@ -2597,14 +2712,11 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2597
2712
|
if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
|
|
2598
2713
|
if (req.seed !== void 0) body.seed = req.seed;
|
|
2599
2714
|
const submit = await withRetry(async () => {
|
|
2600
|
-
const res = await ctx
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
body: JSON.stringify(body)
|
|
2606
|
-
})
|
|
2607
|
-
);
|
|
2715
|
+
const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}`, {
|
|
2716
|
+
method: "POST",
|
|
2717
|
+
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
2718
|
+
body: JSON.stringify(body)
|
|
2719
|
+
});
|
|
2608
2720
|
if (!res.ok) {
|
|
2609
2721
|
const text2 = await res.text().catch(() => "");
|
|
2610
2722
|
throwArkError(res.status, text2, modelId);
|
|
@@ -2617,12 +2729,9 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2617
2729
|
const jobId = submit.id;
|
|
2618
2730
|
const usage2 = seedanceUsage(ctx, req, duration);
|
|
2619
2731
|
const fetchStatus = async () => {
|
|
2620
|
-
const res = await ctx
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
headers: { Authorization: `Bearer ${key}` }
|
|
2624
|
-
})
|
|
2625
|
-
);
|
|
2732
|
+
const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}/${jobId}`, {
|
|
2733
|
+
headers: { Authorization: `Bearer ${key}` }
|
|
2734
|
+
});
|
|
2626
2735
|
if (!res.ok) {
|
|
2627
2736
|
if (res.status === 429 || res.status >= 500) return void 0;
|
|
2628
2737
|
const text2 = await res.text().catch(() => "");
|
|
@@ -2683,43 +2792,6 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2683
2792
|
// src/adapters/fal.ts
|
|
2684
2793
|
var import_zod6 = require("zod");
|
|
2685
2794
|
var import_client = require("@fal-ai/client");
|
|
2686
|
-
|
|
2687
|
-
// src/json.ts
|
|
2688
|
-
var import_zod5 = require("zod");
|
|
2689
|
-
var JsonValueSchema = import_zod5.z.lazy(
|
|
2690
|
-
() => import_zod5.z.union([
|
|
2691
|
-
import_zod5.z.string(),
|
|
2692
|
-
import_zod5.z.number(),
|
|
2693
|
-
import_zod5.z.boolean(),
|
|
2694
|
-
import_zod5.z.null(),
|
|
2695
|
-
import_zod5.z.array(JsonValueSchema),
|
|
2696
|
-
import_zod5.z.record(import_zod5.z.string(), JsonValueSchema)
|
|
2697
|
-
])
|
|
2698
|
-
);
|
|
2699
|
-
var JsonObjectSchema = import_zod5.z.record(import_zod5.z.string(), JsonValueSchema);
|
|
2700
|
-
async function readErrorBody(res) {
|
|
2701
|
-
const text2 = await res.text().catch(() => "");
|
|
2702
|
-
try {
|
|
2703
|
-
return JsonValueSchema.parse(JSON.parse(text2));
|
|
2704
|
-
} catch {
|
|
2705
|
-
return text2;
|
|
2706
|
-
}
|
|
2707
|
-
}
|
|
2708
|
-
var thrownErrorSchema = import_zod5.z.object({
|
|
2709
|
-
message: import_zod5.z.string().optional(),
|
|
2710
|
-
status: import_zod5.z.number().optional(),
|
|
2711
|
-
statusCode: import_zod5.z.number().optional(),
|
|
2712
|
-
responseBody: import_zod5.z.string().optional()
|
|
2713
|
-
});
|
|
2714
|
-
function describeThrown(cause) {
|
|
2715
|
-
const parsed = thrownErrorSchema.safeParse(cause);
|
|
2716
|
-
if (!parsed.success) return { message: String(cause), status: void 0, body: String(cause) };
|
|
2717
|
-
const { message, status, statusCode, responseBody } = parsed.data;
|
|
2718
|
-
const body = responseBody ?? message ?? String(cause);
|
|
2719
|
-
return { message: message ?? String(cause), status: status ?? statusCode, body };
|
|
2720
|
-
}
|
|
2721
|
-
|
|
2722
|
-
// src/adapters/fal.ts
|
|
2723
2795
|
var MUSE_T2I_ENDPOINT = "meta/muse-image/text-to-image";
|
|
2724
2796
|
var MUSE_EDIT_ENDPOINT = "meta/muse-image/edit";
|
|
2725
2797
|
var KLING_O1_ENDPOINT = "fal-ai/kling-video/o1/video-to-video/reference";
|
|
@@ -2731,10 +2803,33 @@ function defaultCreateFalClient(opts) {
|
|
|
2731
2803
|
const client2 = (0, import_client.createFalClient)(opts);
|
|
2732
2804
|
return {
|
|
2733
2805
|
async subscribe(endpoint, options) {
|
|
2734
|
-
const outcome = await client2.subscribe(endpoint,
|
|
2806
|
+
const outcome = await client2.subscribe(endpoint, options);
|
|
2735
2807
|
const unwrapped = falSubscribePayloadSchema.safeParse(outcome);
|
|
2736
2808
|
if (unwrapped.success) return unwrapped.data.data;
|
|
2737
2809
|
return JsonValueSchema.parse(outcome);
|
|
2810
|
+
},
|
|
2811
|
+
queue: {
|
|
2812
|
+
async submit(endpoint, options) {
|
|
2813
|
+
const submitted = await client2.queue.submit(endpoint, {
|
|
2814
|
+
input: options.input,
|
|
2815
|
+
...options.abortSignal !== void 0 ? { abortSignal: options.abortSignal } : {}
|
|
2816
|
+
});
|
|
2817
|
+
return { requestId: submitted.request_id };
|
|
2818
|
+
},
|
|
2819
|
+
async status(endpoint, options) {
|
|
2820
|
+
const current = await client2.queue.status(endpoint, {
|
|
2821
|
+
requestId: options.requestId,
|
|
2822
|
+
...options.abortSignal !== void 0 ? { abortSignal: options.abortSignal } : {}
|
|
2823
|
+
});
|
|
2824
|
+
return { status: current.status };
|
|
2825
|
+
},
|
|
2826
|
+
async result(endpoint, options) {
|
|
2827
|
+
const outcome = await client2.queue.result(endpoint, {
|
|
2828
|
+
requestId: options.requestId,
|
|
2829
|
+
...options.abortSignal !== void 0 ? { abortSignal: options.abortSignal } : {}
|
|
2830
|
+
});
|
|
2831
|
+
return JsonValueSchema.parse(outcome.data);
|
|
2832
|
+
}
|
|
2738
2833
|
}
|
|
2739
2834
|
};
|
|
2740
2835
|
}
|
|
@@ -2776,15 +2871,17 @@ var falSdkThrownSchema = import_zod6.z.object({
|
|
|
2776
2871
|
message: import_zod6.z.string().optional()
|
|
2777
2872
|
});
|
|
2778
2873
|
function falSdkError(cause, model) {
|
|
2779
|
-
if (isModelKitError(cause)) return cause;
|
|
2780
2874
|
const parsed = falSdkThrownSchema.safeParse(cause);
|
|
2781
2875
|
if (parsed.success) {
|
|
2782
2876
|
const status = parsed.data.status ?? parsed.data.statusCode;
|
|
2783
2877
|
const body = parsed.data.body ?? parsed.data.message ?? String(cause);
|
|
2784
|
-
return
|
|
2878
|
+
return classifyThrown("fal", cause, model, { status, body: liftDetail(body) });
|
|
2785
2879
|
}
|
|
2786
2880
|
const info = describeThrown(cause);
|
|
2787
|
-
return
|
|
2881
|
+
return classifyThrown("fal", cause, model, {
|
|
2882
|
+
status: info.status,
|
|
2883
|
+
body: liftDetail(info.body)
|
|
2884
|
+
});
|
|
2788
2885
|
}
|
|
2789
2886
|
function gatewayConfig(ctx) {
|
|
2790
2887
|
const cf = ctx.routing.cloudflare;
|
|
@@ -2866,7 +2963,7 @@ async function passthroughRequest(ctx, endpoint, input) {
|
|
|
2866
2963
|
}
|
|
2867
2964
|
return JsonValueSchema.parse(await resultRes.json());
|
|
2868
2965
|
}
|
|
2869
|
-
|
|
2966
|
+
function falClientOf(ctx, deps) {
|
|
2870
2967
|
const falKey = ctx.keys.fal;
|
|
2871
2968
|
if (!falKey) {
|
|
2872
2969
|
throw new ModelKitError({
|
|
@@ -2877,12 +2974,19 @@ async function subscribe(ctx, deps, endpoint, input) {
|
|
|
2877
2974
|
retryable: false
|
|
2878
2975
|
});
|
|
2879
2976
|
}
|
|
2880
|
-
|
|
2977
|
+
return deps.createFalClient({ credentials: falKey, fetch: ctx.fetch });
|
|
2978
|
+
}
|
|
2979
|
+
async function subscribe(ctx, deps, endpoint, input) {
|
|
2980
|
+
const client2 = falClientOf(ctx, deps);
|
|
2981
|
+
const options = {
|
|
2982
|
+
input,
|
|
2983
|
+
...ctx.signal !== void 0 ? { abortSignal: ctx.signal } : {}
|
|
2984
|
+
};
|
|
2881
2985
|
try {
|
|
2882
2986
|
return await withRetry(
|
|
2883
2987
|
async () => {
|
|
2884
2988
|
try {
|
|
2885
|
-
return await client2.subscribe(endpoint,
|
|
2989
|
+
return await client2.subscribe(endpoint, options);
|
|
2886
2990
|
} catch (cause) {
|
|
2887
2991
|
throw falSdkError(cause, ctx.model.id);
|
|
2888
2992
|
}
|
|
@@ -3016,13 +3120,14 @@ function klingO1Input(req) {
|
|
|
3016
3120
|
});
|
|
3017
3121
|
}
|
|
3018
3122
|
const duration = Math.min(10, Math.max(3, Math.round(req.durationSeconds ?? 5)));
|
|
3019
|
-
const ratio = req.aspectRatio === "16:9" || req.aspectRatio === "9:16" || req.aspectRatio === "1:1" ? req.aspectRatio : "auto";
|
|
3020
3123
|
const input = {
|
|
3021
3124
|
prompt: req.prompt,
|
|
3022
3125
|
video_url: source,
|
|
3023
|
-
duration: String(duration)
|
|
3024
|
-
aspect_ratio: ratio
|
|
3126
|
+
duration: String(duration)
|
|
3025
3127
|
};
|
|
3128
|
+
if (req.aspectRatio !== "adaptive") {
|
|
3129
|
+
input.aspect_ratio = req.aspectRatio === "16:9" || req.aspectRatio === "9:16" || req.aspectRatio === "1:1" ? req.aspectRatio : "auto";
|
|
3130
|
+
}
|
|
3026
3131
|
const refs = (req.referenceImages ?? []).map(refToUrl);
|
|
3027
3132
|
if (refs.length > 0) input.image_urls = refs;
|
|
3028
3133
|
return input;
|
|
@@ -3051,13 +3156,7 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
3051
3156
|
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
3052
3157
|
return await passthroughVideoJob(ctx, req, KLING_O1_ENDPOINT, input);
|
|
3053
3158
|
}
|
|
3054
|
-
|
|
3055
|
-
return completedVideoJob(
|
|
3056
|
-
ctx,
|
|
3057
|
-
req,
|
|
3058
|
-
extractVideoUrl(result2, KLING_O1_ENDPOINT, ctx.model.id),
|
|
3059
|
-
result2
|
|
3060
|
-
);
|
|
3159
|
+
return await submitQueueJob(ctx, req, deps, KLING_O1_ENDPOINT, input);
|
|
3061
3160
|
}
|
|
3062
3161
|
const family = minimaxFamily(providerModelId);
|
|
3063
3162
|
const refs = {
|
|
@@ -3086,19 +3185,81 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
3086
3185
|
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
3087
3186
|
return await passthroughVideoJob(ctx, req, endpoint, base);
|
|
3088
3187
|
}
|
|
3089
|
-
|
|
3090
|
-
|
|
3188
|
+
return await submitQueueJob(ctx, req, deps, endpoint, base);
|
|
3189
|
+
}
|
|
3190
|
+
async function submitQueueJob(ctx, req, deps, endpoint, input) {
|
|
3191
|
+
const client2 = falClientOf(ctx, deps);
|
|
3192
|
+
let submitted;
|
|
3193
|
+
try {
|
|
3194
|
+
submitted = await withRetry(
|
|
3195
|
+
async () => {
|
|
3196
|
+
try {
|
|
3197
|
+
return await client2.queue.submit(endpoint, {
|
|
3198
|
+
input,
|
|
3199
|
+
...ctx.signal !== void 0 ? { abortSignal: ctx.signal } : {}
|
|
3200
|
+
});
|
|
3201
|
+
} catch (cause) {
|
|
3202
|
+
throw falSdkError(cause, ctx.model.id);
|
|
3203
|
+
}
|
|
3204
|
+
},
|
|
3205
|
+
ctx.signal !== void 0 ? { signal: ctx.signal } : {}
|
|
3206
|
+
);
|
|
3207
|
+
} catch (cause) {
|
|
3208
|
+
throw falSdkError(cause, ctx.model.id);
|
|
3209
|
+
}
|
|
3210
|
+
return queuedVideoJob(ctx, req, client2, endpoint, submitted.requestId);
|
|
3091
3211
|
}
|
|
3092
|
-
function
|
|
3212
|
+
function queuedVideoJob(ctx, req, client2, endpoint, requestId) {
|
|
3213
|
+
const readStatus = async () => {
|
|
3214
|
+
try {
|
|
3215
|
+
const options = {
|
|
3216
|
+
requestId,
|
|
3217
|
+
...ctx.signal !== void 0 ? { abortSignal: ctx.signal } : {}
|
|
3218
|
+
};
|
|
3219
|
+
return (await client2.queue.status(endpoint, options)).status;
|
|
3220
|
+
} catch (cause) {
|
|
3221
|
+
throw falSdkError(cause, ctx.model.id);
|
|
3222
|
+
}
|
|
3223
|
+
};
|
|
3093
3224
|
const duration = req.durationSeconds ?? 5;
|
|
3094
|
-
const result = { video: { url }, usage: videoUsage(ctx, req, duration), raw };
|
|
3095
3225
|
return {
|
|
3096
|
-
jobId:
|
|
3226
|
+
jobId: requestId,
|
|
3097
3227
|
async poll() {
|
|
3098
|
-
|
|
3228
|
+
try {
|
|
3229
|
+
const status = await readStatus();
|
|
3230
|
+
if (status === "COMPLETED") return { status: "succeeded" };
|
|
3231
|
+
if (status === "IN_QUEUE") return { status: "pending" };
|
|
3232
|
+
return { status: "running" };
|
|
3233
|
+
} catch (cause) {
|
|
3234
|
+
if (isModelKitError(cause) && !cause.retryable)
|
|
3235
|
+
return { status: "failed" };
|
|
3236
|
+
return { status: "pending" };
|
|
3237
|
+
}
|
|
3099
3238
|
},
|
|
3100
|
-
async result() {
|
|
3101
|
-
|
|
3239
|
+
async result(opts) {
|
|
3240
|
+
const signal = opts?.signal ?? ctx.signal;
|
|
3241
|
+
const pollOptions = {
|
|
3242
|
+
intervalMs: opts?.pollIntervalMs ?? PASSTHROUGH_POLL_MS,
|
|
3243
|
+
timeoutMs: opts?.timeoutMs ?? 15 * 6e4
|
|
3244
|
+
};
|
|
3245
|
+
if (signal !== void 0) pollOptions.signal = signal;
|
|
3246
|
+
const queueOptions = {
|
|
3247
|
+
requestId,
|
|
3248
|
+
...signal !== void 0 ? { abortSignal: signal } : {}
|
|
3249
|
+
};
|
|
3250
|
+
const payload = await pollUntil(async () => {
|
|
3251
|
+
try {
|
|
3252
|
+
const current = await client2.queue.status(endpoint, queueOptions);
|
|
3253
|
+
if (current.status !== "COMPLETED") return void 0;
|
|
3254
|
+
return await client2.queue.result(endpoint, queueOptions);
|
|
3255
|
+
} catch (cause) {
|
|
3256
|
+
const err = falSdkError(cause, ctx.model.id);
|
|
3257
|
+
if (err.retryable) return void 0;
|
|
3258
|
+
throw err;
|
|
3259
|
+
}
|
|
3260
|
+
}, pollOptions);
|
|
3261
|
+
const url = extractVideoUrl(payload, endpoint, ctx.model.id);
|
|
3262
|
+
return { video: { url }, usage: videoUsage(ctx, req, duration), raw: payload };
|
|
3102
3263
|
}
|
|
3103
3264
|
};
|
|
3104
3265
|
}
|
|
@@ -3449,9 +3610,7 @@ function sdkStatus(cause) {
|
|
|
3449
3610
|
return describeThrown(cause).status;
|
|
3450
3611
|
}
|
|
3451
3612
|
function throwSdkError(cause, model) {
|
|
3452
|
-
|
|
3453
|
-
const info = describeThrown(cause);
|
|
3454
|
-
throw classifyHttpError(info.status, info.body, "google-genai", model);
|
|
3613
|
+
throw classifyThrown("google-genai", cause, model);
|
|
3455
3614
|
}
|
|
3456
3615
|
function toBase64(bytes) {
|
|
3457
3616
|
return Buffer.from(bytes).toString("base64");
|
|
@@ -3655,12 +3814,17 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3655
3814
|
const duration = req.durationSeconds ?? 8;
|
|
3656
3815
|
const images = req.referenceImages ?? [];
|
|
3657
3816
|
const videos = req.referenceVideos ?? [];
|
|
3658
|
-
const task = req.sourceVideo ? "edit" :
|
|
3659
|
-
const
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3817
|
+
const task = req.sourceVideo ? "edit" : req.firstFrame ? "image_to_video" : images.length > 0 || videos.length > 0 ? "reference_to_video" : "text_to_video";
|
|
3818
|
+
const isOmniV1 = providerModelId === "gemini-omni-flash-preview";
|
|
3819
|
+
const responseFormat = { type: "video", delivery: "uri" };
|
|
3820
|
+
if (req.sourceVideo === void 0 && req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
3821
|
+
responseFormat.aspect_ratio = toOmniAspect(req.aspectRatio);
|
|
3822
|
+
}
|
|
3823
|
+
if (!isOmniV1) {
|
|
3824
|
+
const omniResolution = toOmniResolution(req.resolution);
|
|
3825
|
+
if (omniResolution !== void 0) responseFormat.resolution = omniResolution;
|
|
3826
|
+
}
|
|
3827
|
+
if (req.durationSeconds !== void 0) responseFormat.duration = `${req.durationSeconds}s`;
|
|
3664
3828
|
const client2 = createGenAIClient({ apiKey });
|
|
3665
3829
|
const uploadedByUri = /* @__PURE__ */ new Map();
|
|
3666
3830
|
const uploadedNames = [];
|
|
@@ -3684,7 +3848,8 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3684
3848
|
model: providerModelId,
|
|
3685
3849
|
input,
|
|
3686
3850
|
response_format: responseFormat,
|
|
3687
|
-
generation_config: { video_config: { task } }
|
|
3851
|
+
generation_config: { video_config: { task } },
|
|
3852
|
+
store: true
|
|
3688
3853
|
});
|
|
3689
3854
|
const createRetryOptions = { attempts: 3 };
|
|
3690
3855
|
if (ctx.signal !== void 0) createRetryOptions.signal = ctx.signal;
|
|
@@ -3766,23 +3931,14 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3766
3931
|
};
|
|
3767
3932
|
return inline;
|
|
3768
3933
|
});
|
|
3769
|
-
const inlineRetryOptions = { attempts: 3 };
|
|
3770
|
-
if (ctx.signal !== void 0) inlineRetryOptions.signal = ctx.signal;
|
|
3771
3934
|
try {
|
|
3772
|
-
interaction = await
|
|
3773
|
-
try {
|
|
3774
|
-
return await callCreate(inlineParts);
|
|
3775
|
-
} catch (inlineCause) {
|
|
3776
|
-
throwSdkError(inlineCause, modelId);
|
|
3777
|
-
}
|
|
3778
|
-
}, inlineRetryOptions);
|
|
3935
|
+
interaction = await callCreate(inlineParts);
|
|
3779
3936
|
} catch (inlineCause) {
|
|
3780
3937
|
throwSdkError(inlineCause, modelId);
|
|
3781
3938
|
}
|
|
3782
3939
|
}
|
|
3783
|
-
}
|
|
3940
|
+
} finally {
|
|
3784
3941
|
await cleanupUploads();
|
|
3785
|
-
throw cause;
|
|
3786
3942
|
}
|
|
3787
3943
|
const jobId = interaction.id ?? "gemini-omni-interaction";
|
|
3788
3944
|
const usage2 = videoUsage2(ctx, req, duration);
|
|
@@ -3811,47 +3967,43 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3811
3967
|
timeoutMs: opts?.timeoutMs ?? RESULT_TIMEOUT_MS2
|
|
3812
3968
|
};
|
|
3813
3969
|
if (signal !== void 0) pollOptions.signal = signal;
|
|
3814
|
-
|
|
3815
|
-
const
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
);
|
|
3826
|
-
}
|
|
3827
|
-
return void 0;
|
|
3828
|
-
}, pollOptions);
|
|
3829
|
-
const video = extractOmniVideo(done, modelId);
|
|
3830
|
-
if (video.data) {
|
|
3831
|
-
return {
|
|
3832
|
-
video: {
|
|
3833
|
-
bytes: Buffer.from(video.data, "base64"),
|
|
3834
|
-
mime: video.mime_type ?? "video/mp4"
|
|
3835
|
-
},
|
|
3836
|
-
usage: usage2,
|
|
3837
|
-
raw: done
|
|
3838
|
-
};
|
|
3970
|
+
const done = await pollUntil(async () => {
|
|
3971
|
+
const current = await getInteraction();
|
|
3972
|
+
const status = (current.status ?? "").toUpperCase();
|
|
3973
|
+
if (status === "COMPLETED") return current;
|
|
3974
|
+
if (status === "FAILED") {
|
|
3975
|
+
throw classifyHttpError(
|
|
3976
|
+
void 0,
|
|
3977
|
+
`Gemini Omni interaction failed: ${JSON.stringify(current).slice(0, 500)}`,
|
|
3978
|
+
"google-genai",
|
|
3979
|
+
modelId
|
|
3980
|
+
);
|
|
3839
3981
|
}
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
} finally {
|
|
3853
|
-
await cleanupUploads();
|
|
3982
|
+
return void 0;
|
|
3983
|
+
}, pollOptions);
|
|
3984
|
+
const video = extractOmniVideo(done, modelId);
|
|
3985
|
+
if (video.data) {
|
|
3986
|
+
return {
|
|
3987
|
+
video: {
|
|
3988
|
+
bytes: Buffer.from(video.data, "base64"),
|
|
3989
|
+
mime: video.mime_type ?? "video/mp4"
|
|
3990
|
+
},
|
|
3991
|
+
usage: usage2,
|
|
3992
|
+
raw: done
|
|
3993
|
+
};
|
|
3854
3994
|
}
|
|
3995
|
+
if (video.uri)
|
|
3996
|
+
return {
|
|
3997
|
+
video: await downloadVideo(ctx, video.uri, apiKey, signal),
|
|
3998
|
+
usage: usage2,
|
|
3999
|
+
raw: done
|
|
4000
|
+
};
|
|
4001
|
+
throw classifyHttpError(
|
|
4002
|
+
void 0,
|
|
4003
|
+
"No video content in Gemini Omni response",
|
|
4004
|
+
"google-genai",
|
|
4005
|
+
modelId
|
|
4006
|
+
);
|
|
3855
4007
|
}
|
|
3856
4008
|
};
|
|
3857
4009
|
}
|
|
@@ -4020,8 +4172,14 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
4020
4172
|
content.push({ type: "text", text: req.prompt });
|
|
4021
4173
|
void ctx.call.postCropToAspect;
|
|
4022
4174
|
const imageConfig = {};
|
|
4023
|
-
if (req.aspectRatio !== void 0
|
|
4175
|
+
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive")
|
|
4176
|
+
imageConfig.aspectRatio = req.aspectRatio;
|
|
4024
4177
|
if (req.size !== void 0) imageConfig.imageSize = req.size;
|
|
4178
|
+
const googleOptions = {
|
|
4179
|
+
imageConfig,
|
|
4180
|
+
responseModalities: ["IMAGE"]
|
|
4181
|
+
};
|
|
4182
|
+
if (req.safetySettings !== void 0) googleOptions.safetySettings = req.safetySettings;
|
|
4025
4183
|
const retryOptions = {};
|
|
4026
4184
|
if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
|
|
4027
4185
|
const result = await withRetry(async () => {
|
|
@@ -4033,22 +4191,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
4033
4191
|
messages: [{ role: "user", content }],
|
|
4034
4192
|
maxRetries: 0,
|
|
4035
4193
|
providerOptions: {
|
|
4036
|
-
google:
|
|
4037
|
-
imageConfig,
|
|
4038
|
-
responseModalities: ["IMAGE"],
|
|
4039
|
-
safetySettings: [
|
|
4040
|
-
{
|
|
4041
|
-
category: "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
|
4042
|
-
threshold: "OFF"
|
|
4043
|
-
},
|
|
4044
|
-
{ category: "HARM_CATEGORY_HATE_SPEECH", threshold: "OFF" },
|
|
4045
|
-
{
|
|
4046
|
-
category: "HARM_CATEGORY_DANGEROUS_CONTENT",
|
|
4047
|
-
threshold: "OFF"
|
|
4048
|
-
},
|
|
4049
|
-
{ category: "HARM_CATEGORY_HARASSMENT", threshold: "OFF" }
|
|
4050
|
-
]
|
|
4051
|
-
}
|
|
4194
|
+
google: googleOptions
|
|
4052
4195
|
},
|
|
4053
4196
|
abortSignal: signal
|
|
4054
4197
|
});
|
|
@@ -4077,6 +4220,10 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
4077
4220
|
imageQuality: "auto"
|
|
4078
4221
|
};
|
|
4079
4222
|
if (req.size !== void 0) usage2.imageSize = req.size;
|
|
4223
|
+
if (result.usage?.inputTokens !== void 0)
|
|
4224
|
+
usage2.inputTokens = result.usage.inputTokens;
|
|
4225
|
+
if (result.usage?.outputTokens !== void 0)
|
|
4226
|
+
usage2.outputTokens = result.usage.outputTokens;
|
|
4080
4227
|
return { images, usage: usage2, raw: result };
|
|
4081
4228
|
}
|
|
4082
4229
|
};
|
|
@@ -4231,6 +4378,7 @@ var KLING_MAX_INTERVAL_MS = 1e4;
|
|
|
4231
4378
|
var KLING_TIMEOUT_MS = 15 * 6e4;
|
|
4232
4379
|
var DOP_INTERVAL_MS = 5e3;
|
|
4233
4380
|
var DOP_TIMEOUT_MS = 5 * 6e4;
|
|
4381
|
+
var DOP_FALLBACK_DURATION_SECONDS = 5;
|
|
4234
4382
|
var DEFAULT_NEGATIVE_PROMPT = "text, watermark, copyright, blur, low quality, distortion, abstract, weird, deformed";
|
|
4235
4383
|
function credentials(ctx) {
|
|
4236
4384
|
const key = ctx.keys.higgsfield;
|
|
@@ -4305,6 +4453,18 @@ function requestInit(ctx, init) {
|
|
|
4305
4453
|
if (ctx.signal !== void 0) request.signal = ctx.signal;
|
|
4306
4454
|
return request;
|
|
4307
4455
|
}
|
|
4456
|
+
async function createRequest(ctx, url, init) {
|
|
4457
|
+
let res;
|
|
4458
|
+
try {
|
|
4459
|
+
res = await ctx.fetch(url, requestInit(ctx, init));
|
|
4460
|
+
} catch (cause) {
|
|
4461
|
+
throw classifyThrown("higgsfield", cause, ctx.model.id);
|
|
4462
|
+
}
|
|
4463
|
+
if (!res.ok) {
|
|
4464
|
+
throw classifyHttpError(res.status, await readBody2(res), "higgsfield", ctx.model.id);
|
|
4465
|
+
}
|
|
4466
|
+
return res;
|
|
4467
|
+
}
|
|
4308
4468
|
async function generateKlingVideo(req, ctx) {
|
|
4309
4469
|
const firstFrame = req.firstFrame ? refToUrl2(req.firstFrame) : void 0;
|
|
4310
4470
|
if (!firstFrame) {
|
|
@@ -4323,26 +4483,16 @@ async function generateKlingVideo(req, ctx) {
|
|
|
4323
4483
|
negative_prompt: req.negativePrompt ?? DEFAULT_NEGATIVE_PROMPT
|
|
4324
4484
|
};
|
|
4325
4485
|
if (req.durationSeconds !== void 0) body.duration = req.durationSeconds;
|
|
4326
|
-
if (req.aspectRatio !== void 0
|
|
4486
|
+
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive")
|
|
4487
|
+
body.aspect_ratio = req.aspectRatio;
|
|
4327
4488
|
if (req.lastFrame) body.last_image_url = refToUrl2(req.lastFrame);
|
|
4328
4489
|
const endpoint = klingEndpoint(ctx.model.providerModelId);
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
} catch (cause) {
|
|
4336
|
-
throw networkError(cause, ctx);
|
|
4337
|
-
}
|
|
4338
|
-
if (!createRes.ok) {
|
|
4339
|
-
throw classifyHttpError(
|
|
4340
|
-
createRes.status,
|
|
4341
|
-
await readBody2(createRes),
|
|
4342
|
-
"higgsfield",
|
|
4343
|
-
ctx.model.id
|
|
4344
|
-
);
|
|
4345
|
-
}
|
|
4490
|
+
const retryOptions = {};
|
|
4491
|
+
if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
|
|
4492
|
+
const createRes = await withRetry(
|
|
4493
|
+
() => createRequest(ctx, endpoint, { method: "POST", body: JSON.stringify(body) }),
|
|
4494
|
+
retryOptions
|
|
4495
|
+
);
|
|
4346
4496
|
const created = klingCreateSchema.safeParse(await createRes.json());
|
|
4347
4497
|
if (!created.success) {
|
|
4348
4498
|
throw new ModelKitError({
|
|
@@ -4422,11 +4572,6 @@ async function generateKlingVideo(req, ctx) {
|
|
|
4422
4572
|
}
|
|
4423
4573
|
};
|
|
4424
4574
|
}
|
|
4425
|
-
function networkError(cause, ctx) {
|
|
4426
|
-
if (isModelKitError(cause)) return cause;
|
|
4427
|
-
const info = describeThrown(cause);
|
|
4428
|
-
return classifyHttpError(info.status, info.body, "higgsfield", ctx.model.id);
|
|
4429
|
-
}
|
|
4430
4575
|
var dopMotionOptionsSchema = import_zod10.z.object({
|
|
4431
4576
|
modelkit: import_zod10.z.object({ motion: import_zod10.z.string().optional() }).optional()
|
|
4432
4577
|
});
|
|
@@ -4498,26 +4643,15 @@ async function generateDopVideo(req, ctx) {
|
|
|
4498
4643
|
params.input_images_end = [{ type: "image_url", image_url: refToUrl2(req.lastFrame) }];
|
|
4499
4644
|
}
|
|
4500
4645
|
if (req.seed !== void 0) params.seed = req.seed;
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
} catch (cause) {
|
|
4511
|
-
throw networkError(cause, ctx);
|
|
4512
|
-
}
|
|
4513
|
-
if (!createRes.ok) {
|
|
4514
|
-
throw classifyHttpError(
|
|
4515
|
-
createRes.status,
|
|
4516
|
-
await readBody2(createRes),
|
|
4517
|
-
"higgsfield",
|
|
4518
|
-
ctx.model.id
|
|
4519
|
-
);
|
|
4520
|
-
}
|
|
4646
|
+
const retryOptions = {};
|
|
4647
|
+
if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
|
|
4648
|
+
const createRes = await withRetry(
|
|
4649
|
+
() => createRequest(ctx, DOP_ENDPOINT, {
|
|
4650
|
+
method: "POST",
|
|
4651
|
+
body: JSON.stringify({ params, webhook: null })
|
|
4652
|
+
}),
|
|
4653
|
+
retryOptions
|
|
4654
|
+
);
|
|
4521
4655
|
const created = dopCreateSchema.safeParse(await createRes.json());
|
|
4522
4656
|
if (!created.success) {
|
|
4523
4657
|
throw new ModelKitError({
|
|
@@ -4586,7 +4720,10 @@ async function generateDopVideo(req, ctx) {
|
|
|
4586
4720
|
};
|
|
4587
4721
|
if (dopSignal !== void 0) pollSettings.signal = dopSignal;
|
|
4588
4722
|
const url = await pollUntil(check, pollSettings);
|
|
4589
|
-
const result = {
|
|
4723
|
+
const result = {
|
|
4724
|
+
video: { url },
|
|
4725
|
+
usage: videoUsage3(ctx, req, req.durationSeconds ?? DOP_FALLBACK_DURATION_SECONDS)
|
|
4726
|
+
};
|
|
4590
4727
|
return result;
|
|
4591
4728
|
}
|
|
4592
4729
|
};
|
|
@@ -4608,7 +4745,7 @@ function aspectRatioToSize(ratio, tier) {
|
|
|
4608
4745
|
};
|
|
4609
4746
|
const MIN_PIXELS = 655360;
|
|
4610
4747
|
const MAX_PIXELS = 8294400;
|
|
4611
|
-
const maxLong = TIER_LONG_EDGE[tier];
|
|
4748
|
+
const maxLong = TIER_LONG_EDGE[tier] ?? 1024;
|
|
4612
4749
|
const RATIO_MAP = /* @__PURE__ */ new Map([
|
|
4613
4750
|
["1:1", [1, 1]],
|
|
4614
4751
|
["16:9", [16, 9]],
|
|
@@ -4768,28 +4905,16 @@ var openaiImageAdapter = {
|
|
|
4768
4905
|
const usageParsed = openaiUsageSchema.safeParse(response.usage);
|
|
4769
4906
|
const inputTokens = usageParsed.success ? usageParsed.data.input_tokens : void 0;
|
|
4770
4907
|
const outputTokens = usageParsed.success ? usageParsed.data.output_tokens : void 0;
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
if (inputTokens !== void 0) usage2.inputTokens = inputTokens;
|
|
4782
|
-
if (outputTokens !== void 0) usage2.outputTokens = outputTokens;
|
|
4783
|
-
} else {
|
|
4784
|
-
usage2 = {
|
|
4785
|
-
model: ctx.model.id,
|
|
4786
|
-
provider: "openai-image",
|
|
4787
|
-
modality: "IMAGE",
|
|
4788
|
-
unit: "images",
|
|
4789
|
-
quantity: images.length,
|
|
4790
|
-
imageQuality: quality
|
|
4791
|
-
};
|
|
4792
|
-
}
|
|
4908
|
+
const usage2 = {
|
|
4909
|
+
model: ctx.model.id,
|
|
4910
|
+
provider: "openai-image",
|
|
4911
|
+
modality: "IMAGE",
|
|
4912
|
+
unit: "images",
|
|
4913
|
+
quantity: images.length,
|
|
4914
|
+
imageQuality: quality
|
|
4915
|
+
};
|
|
4916
|
+
if (inputTokens !== void 0) usage2.inputTokens = inputTokens;
|
|
4917
|
+
if (outputTokens !== void 0) usage2.outputTokens = outputTokens;
|
|
4793
4918
|
if (req.size !== void 0) usage2.imageSize = req.size;
|
|
4794
4919
|
return { images, usage: usage2, raw: response };
|
|
4795
4920
|
}
|
|
@@ -4842,7 +4967,12 @@ var NANO_BANANA_RATIOS = /* @__PURE__ */ new Set([
|
|
|
4842
4967
|
]);
|
|
4843
4968
|
async function refToBytes(ctx, ref) {
|
|
4844
4969
|
if ("bytes" in ref) return { bytes: ref.bytes, mime: ref.mime };
|
|
4845
|
-
|
|
4970
|
+
let res;
|
|
4971
|
+
try {
|
|
4972
|
+
res = await ctx.fetch(ref.url);
|
|
4973
|
+
} catch (cause) {
|
|
4974
|
+
throw classifyThrown("prodia", cause, ctx.model.id);
|
|
4975
|
+
}
|
|
4846
4976
|
if (!res.ok) {
|
|
4847
4977
|
const text2 = await res.text().catch(() => "");
|
|
4848
4978
|
throw classifyHttpError(res.status, text2, "prodia", ctx.model.id);
|
|
@@ -5012,8 +5142,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
5012
5142
|
body: form
|
|
5013
5143
|
});
|
|
5014
5144
|
} catch (err) {
|
|
5015
|
-
|
|
5016
|
-
throw transportError("prodia", err, ctx.model.id);
|
|
5145
|
+
throw classifyThrown("prodia", err, ctx.model.id);
|
|
5017
5146
|
}
|
|
5018
5147
|
if (!attemptRes.ok) {
|
|
5019
5148
|
const text2 = await attemptRes.text().catch(() => "");
|
|
@@ -5022,8 +5151,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
5022
5151
|
return attemptRes;
|
|
5023
5152
|
}, retryOpts);
|
|
5024
5153
|
} catch (err) {
|
|
5025
|
-
|
|
5026
|
-
throw transportError("prodia", err, ctx.model.id);
|
|
5154
|
+
throw classifyThrown("prodia", err, ctx.model.id);
|
|
5027
5155
|
}
|
|
5028
5156
|
const bytes = parseImageResponse(
|
|
5029
5157
|
new Uint8Array(await res.arrayBuffer()),
|
|
@@ -5095,7 +5223,7 @@ function replicateError(cause, ctx) {
|
|
|
5095
5223
|
const info = describeThrown(cause);
|
|
5096
5224
|
const nested = replicateResponseStatusSchema.safeParse(cause);
|
|
5097
5225
|
const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
|
|
5098
|
-
return
|
|
5226
|
+
return classifyThrown("replicate", cause, ctx.model.id, { status, body: info.body });
|
|
5099
5227
|
}
|
|
5100
5228
|
function isLower(id) {
|
|
5101
5229
|
return id.toLowerCase();
|
|
@@ -5242,6 +5370,9 @@ function isUpscaler(providerModelId) {
|
|
|
5242
5370
|
const id = isLower(providerModelId);
|
|
5243
5371
|
return id.includes("upscal") || id.includes("crystal") || id.includes("topaz");
|
|
5244
5372
|
}
|
|
5373
|
+
function isTopazUpscaler(providerModelId) {
|
|
5374
|
+
return isLower(providerModelId).includes("topazlabs/image-upscale");
|
|
5375
|
+
}
|
|
5245
5376
|
function isQwen(providerModelId) {
|
|
5246
5377
|
return isLower(providerModelId).includes("qwen");
|
|
5247
5378
|
}
|
|
@@ -5291,8 +5422,36 @@ function wanImageSize(aspectRatio, size) {
|
|
|
5291
5422
|
}
|
|
5292
5423
|
async function generateReplicateImage(req, ctx, deps) {
|
|
5293
5424
|
const id = ctx.model.providerModelId;
|
|
5294
|
-
|
|
5295
|
-
if (
|
|
5425
|
+
let input;
|
|
5426
|
+
if (isTopazUpscaler(id)) {
|
|
5427
|
+
const first = (req.references ?? [])[0];
|
|
5428
|
+
if (!first) {
|
|
5429
|
+
throw new ModelKitError({
|
|
5430
|
+
code: "missing_input",
|
|
5431
|
+
message: `${ctx.model.id} requires a reference image to upscale`,
|
|
5432
|
+
provider: "replicate",
|
|
5433
|
+
model: ctx.model.id,
|
|
5434
|
+
retryable: false
|
|
5435
|
+
});
|
|
5436
|
+
}
|
|
5437
|
+
let format = req.outputFormat === "jpeg" ? "jpg" : req.outputFormat ?? "png";
|
|
5438
|
+
if (format !== "png" && format !== "jpg") {
|
|
5439
|
+
ctx.warnings.push({
|
|
5440
|
+
code: "option_ignored",
|
|
5441
|
+
field: "outputFormat",
|
|
5442
|
+
from: format,
|
|
5443
|
+
message: "topazlabs/image-upscale supports only png and jpg; using png"
|
|
5444
|
+
});
|
|
5445
|
+
format = "png";
|
|
5446
|
+
}
|
|
5447
|
+
input = {
|
|
5448
|
+
image: refToUrl3(first),
|
|
5449
|
+
enhance_model: "Standard V2",
|
|
5450
|
+
output_format: format,
|
|
5451
|
+
upscale_factor: `${req.scaleFactor ?? 2}x`,
|
|
5452
|
+
face_enhancement: true
|
|
5453
|
+
};
|
|
5454
|
+
} else if (isUpscaler(id)) {
|
|
5296
5455
|
const refs = req.references ?? [];
|
|
5297
5456
|
const first = refs[0];
|
|
5298
5457
|
if (!first) {
|
|
@@ -5304,24 +5463,29 @@ async function generateReplicateImage(req, ctx, deps) {
|
|
|
5304
5463
|
retryable: false
|
|
5305
5464
|
});
|
|
5306
5465
|
}
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5466
|
+
const imageInput = { prompt: req.prompt };
|
|
5467
|
+
imageInput.image = refToUrl3(first);
|
|
5468
|
+
imageInput.creativity = 0;
|
|
5469
|
+
imageInput.scale_factor = 2;
|
|
5470
|
+
imageInput.output_format = "png";
|
|
5471
|
+
input = imageInput;
|
|
5311
5472
|
} else if (isWanImage(id)) {
|
|
5312
5473
|
const refs = (req.references ?? []).map(refToUrl3);
|
|
5313
|
-
|
|
5314
|
-
|
|
5474
|
+
const imageInput = { prompt: req.prompt };
|
|
5475
|
+
if (refs.length > 0) imageInput.images = refs;
|
|
5476
|
+
imageInput.size = wanImageSize(req.aspectRatio, req.size);
|
|
5477
|
+
input = imageInput;
|
|
5315
5478
|
} else if (isQwen(id)) {
|
|
5316
5479
|
const refs = (req.references ?? []).map(refToUrl3);
|
|
5317
5480
|
const firstUrl = refs[0];
|
|
5481
|
+
const imageInput = { prompt: req.prompt };
|
|
5318
5482
|
if (firstUrl !== void 0) {
|
|
5319
|
-
|
|
5320
|
-
if (!isQwenEditPlus(id))
|
|
5483
|
+
imageInput.image = firstUrl;
|
|
5484
|
+
if (!isQwenEditPlus(id)) imageInput.match_input_image = true;
|
|
5321
5485
|
}
|
|
5322
5486
|
const ratios = isQwenEditPlus(id) ? QWEN_EDIT_RATIOS : QWEN_IMAGE_RATIOS;
|
|
5323
5487
|
if (req.aspectRatio !== void 0) {
|
|
5324
|
-
if (ratios.has(req.aspectRatio))
|
|
5488
|
+
if (ratios.has(req.aspectRatio)) imageInput.aspect_ratio = req.aspectRatio;
|
|
5325
5489
|
else
|
|
5326
5490
|
ctx.warnings.push({
|
|
5327
5491
|
code: "option_ignored",
|
|
@@ -5331,18 +5495,21 @@ async function generateReplicateImage(req, ctx, deps) {
|
|
|
5331
5495
|
});
|
|
5332
5496
|
}
|
|
5333
5497
|
if (isQwenEditPlus(id) && req.outputFormat !== void 0) {
|
|
5334
|
-
|
|
5498
|
+
imageInput.output_format = req.outputFormat === "jpeg" ? "jpg" : req.outputFormat;
|
|
5335
5499
|
}
|
|
5500
|
+
input = imageInput;
|
|
5336
5501
|
} else {
|
|
5337
5502
|
const refs = req.references ?? [];
|
|
5338
5503
|
const first = refs[0];
|
|
5339
|
-
|
|
5504
|
+
const imageInput = { prompt: req.prompt };
|
|
5505
|
+
if (first) imageInput.image = refToUrl3(first);
|
|
5506
|
+
input = imageInput;
|
|
5340
5507
|
}
|
|
5341
5508
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|
|
5342
5509
|
const file = await download(ctx, url);
|
|
5343
5510
|
const usage2 = imageUsage2(ctx, req);
|
|
5344
5511
|
usage2.quantity = predictTime;
|
|
5345
|
-
return { images: [{ bytes: file.bytes, mime: file.mime }], usage: usage2, raw };
|
|
5512
|
+
return { images: [{ bytes: file.bytes, mime: file.mime }], usage: usage2, raw, outputUrl: url };
|
|
5346
5513
|
}
|
|
5347
5514
|
function wanSize(aspectRatio) {
|
|
5348
5515
|
if (!aspectRatio || aspectRatio === "adaptive" || aspectRatio === "1:1") return "2K";
|
|
@@ -5366,7 +5533,7 @@ function klingInput(req) {
|
|
|
5366
5533
|
input.start_image = startImage;
|
|
5367
5534
|
const endImage = images[1];
|
|
5368
5535
|
if (endImage !== void 0) input.end_image = endImage;
|
|
5369
|
-
} else {
|
|
5536
|
+
} else if (req.aspectRatio !== "adaptive") {
|
|
5370
5537
|
input.aspect_ratio = req.aspectRatio ?? "16:9";
|
|
5371
5538
|
}
|
|
5372
5539
|
if (req.negativePrompt !== void 0) input.negative_prompt = req.negativePrompt;
|
|
@@ -5386,7 +5553,7 @@ function klingOmniInput(req) {
|
|
|
5386
5553
|
input.start_image = startImage;
|
|
5387
5554
|
const endImage = images[1];
|
|
5388
5555
|
if (endImage !== void 0) input.end_image = endImage;
|
|
5389
|
-
} else {
|
|
5556
|
+
} else if (req.aspectRatio !== "adaptive") {
|
|
5390
5557
|
input.aspect_ratio = req.aspectRatio ?? "16:9";
|
|
5391
5558
|
}
|
|
5392
5559
|
const refs = (req.referenceImages ?? []).map(refToUrl3);
|
|
@@ -5595,11 +5762,10 @@ var xaiResponseStatusSchema = import_zod13.z.object({
|
|
|
5595
5762
|
response: import_zod13.z.object({ status: import_zod13.z.number() }).partial()
|
|
5596
5763
|
});
|
|
5597
5764
|
function xaiError(cause, ctx) {
|
|
5598
|
-
if (isModelKitError(cause)) return cause;
|
|
5599
5765
|
const info = describeThrown(cause);
|
|
5600
5766
|
const nested = xaiResponseStatusSchema.safeParse(cause);
|
|
5601
5767
|
const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
|
|
5602
|
-
return
|
|
5768
|
+
return classifyThrown("xai-video", cause, ctx.model.id, { status, body: info.body });
|
|
5603
5769
|
}
|
|
5604
5770
|
var xaiMetaSchema = import_zod13.z.object({
|
|
5605
5771
|
videoUrl: JsonValueSchema.optional(),
|
|
@@ -5623,10 +5789,7 @@ async function generateXaiVideo(req, ctx, deps) {
|
|
|
5623
5789
|
retryable: false
|
|
5624
5790
|
});
|
|
5625
5791
|
}
|
|
5626
|
-
const
|
|
5627
|
-
(r) => r !== void 0
|
|
5628
|
-
);
|
|
5629
|
-
const refUrls = frames.map(refToUrl4).slice(0, 5);
|
|
5792
|
+
const refUrls = (req.referenceImages ?? []).map(refToUrl4).slice(0, 7);
|
|
5630
5793
|
const resolution = req.resolution === "480p" ? "480p" : "720p";
|
|
5631
5794
|
const xaiOptions = {
|
|
5632
5795
|
resolution,
|
|
@@ -5637,13 +5800,23 @@ async function generateXaiVideo(req, ctx, deps) {
|
|
|
5637
5800
|
xaiOptions.mode = "reference-to-video";
|
|
5638
5801
|
xaiOptions.referenceImageUrls = refUrls;
|
|
5639
5802
|
}
|
|
5803
|
+
if (req.lastFrame !== void 0) {
|
|
5804
|
+
ctx.warnings.push({
|
|
5805
|
+
code: "option_ignored",
|
|
5806
|
+
field: "lastFrame",
|
|
5807
|
+
message: "xai-video does not support lastFrame; ignored"
|
|
5808
|
+
});
|
|
5809
|
+
}
|
|
5640
5810
|
const client2 = deps.createXaiClient({ apiKey });
|
|
5641
|
-
const model = (0, import_xai2.createXai)({ apiKey }).video(ctx.model.providerModelId);
|
|
5811
|
+
const model = (0, import_xai2.createXai)({ apiKey, fetch: ctx.fetch }).video(ctx.model.providerModelId);
|
|
5642
5812
|
const callBody = {
|
|
5643
5813
|
model,
|
|
5644
5814
|
prompt: req.prompt,
|
|
5645
5815
|
providerOptions: { xai: xaiOptions }
|
|
5646
5816
|
};
|
|
5817
|
+
if (req.firstFrame) {
|
|
5818
|
+
callBody.frameImages = [{ image: refToUrl4(req.firstFrame), frameType: "first_frame" }];
|
|
5819
|
+
}
|
|
5647
5820
|
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
5648
5821
|
callBody.aspectRatio = req.aspectRatio;
|
|
5649
5822
|
}
|
|
@@ -5729,26 +5902,14 @@ async function mapResult(ctx, req, result) {
|
|
|
5729
5902
|
function usage(ctx, req, meta) {
|
|
5730
5903
|
const costTicks = import_zod13.z.number().safeParse(meta.costInUsdTicks);
|
|
5731
5904
|
const cost = costTicks.success ? costTicks.data / 1e10 : void 0;
|
|
5732
|
-
if (cost !== void 0) {
|
|
5733
|
-
const event2 = {
|
|
5734
|
-
model: ctx.model.id,
|
|
5735
|
-
provider: "xai-video",
|
|
5736
|
-
modality: "VIDEO",
|
|
5737
|
-
unit: "reported_cost_usd",
|
|
5738
|
-
quantity: cost,
|
|
5739
|
-
reportedCostUsd: cost
|
|
5740
|
-
};
|
|
5741
|
-
if (req.durationSeconds !== void 0) event2.durationSeconds = req.durationSeconds;
|
|
5742
|
-
if (req.resolution !== void 0) event2.resolution = req.resolution;
|
|
5743
|
-
return event2;
|
|
5744
|
-
}
|
|
5745
5905
|
const event = {
|
|
5746
5906
|
model: ctx.model.id,
|
|
5747
5907
|
provider: "xai-video",
|
|
5748
5908
|
modality: "VIDEO",
|
|
5749
|
-
unit: "
|
|
5750
|
-
quantity:
|
|
5909
|
+
unit: "reported_cost_usd",
|
|
5910
|
+
quantity: cost ?? 0
|
|
5751
5911
|
};
|
|
5912
|
+
if (cost !== void 0) event.reportedCostUsd = cost;
|
|
5752
5913
|
if (req.durationSeconds !== void 0) event.durationSeconds = req.durationSeconds;
|
|
5753
5914
|
if (req.resolution !== void 0) event.resolution = req.resolution;
|
|
5754
5915
|
return event;
|