@shop-os/modelkit 0.1.5 → 0.1.6
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 +11 -11
- package/dist/index.cjs +538 -302
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -9
- package/dist/index.d.ts +41 -9
- package/dist/index.js +537 -302
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -68,6 +68,7 @@ __export(index_exports, {
|
|
|
68
68
|
prodiaAdapter: () => prodiaAdapter,
|
|
69
69
|
readErrorBody: () => readErrorBody,
|
|
70
70
|
replicateAdapter: () => replicateAdapter,
|
|
71
|
+
resolveAudioOptions: () => resolveAudioOptions,
|
|
71
72
|
resolveImageOptions: () => resolveImageOptions,
|
|
72
73
|
resolveKeys: () => resolveKeys,
|
|
73
74
|
resolveVideoOptions: () => resolveVideoOptions,
|
|
@@ -187,7 +188,11 @@ function geminiImage(id, label, aliases, sizes) {
|
|
|
187
188
|
adapter: "google-image",
|
|
188
189
|
providerModelId: id,
|
|
189
190
|
lifecycle: "active",
|
|
190
|
-
constraints: {
|
|
191
|
+
constraints: {
|
|
192
|
+
aspectRatios: [...GEMINI_RATIOS],
|
|
193
|
+
sizes,
|
|
194
|
+
supports: ["safetySettings", "temperature"]
|
|
195
|
+
},
|
|
191
196
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
192
197
|
usage: { ...IMAGE_USAGE },
|
|
193
198
|
pricingKind: "image_size"
|
|
@@ -326,8 +331,20 @@ var IMAGE_MODELS = [
|
|
|
326
331
|
constraints: {
|
|
327
332
|
// 97:30 has no Ark size spelling; the A+ flow pads inputs to 97:30 and
|
|
328
333
|
// omits the ratio instead. Advertise only sizes the adapter can send.
|
|
329
|
-
aspectRatios: [
|
|
330
|
-
|
|
334
|
+
aspectRatios: [
|
|
335
|
+
"1:1",
|
|
336
|
+
"2:3",
|
|
337
|
+
"3:2",
|
|
338
|
+
"4:3",
|
|
339
|
+
"3:4",
|
|
340
|
+
"4:5",
|
|
341
|
+
"5:4",
|
|
342
|
+
"9:16",
|
|
343
|
+
"16:9",
|
|
344
|
+
"21:9",
|
|
345
|
+
"9:21"
|
|
346
|
+
],
|
|
347
|
+
sizes: ["1K", "2K", "4K"],
|
|
331
348
|
references: { images: 10 },
|
|
332
349
|
supports: ["seed"]
|
|
333
350
|
},
|
|
@@ -557,7 +574,7 @@ var OTHER_MODELS = [
|
|
|
557
574
|
constraints: {
|
|
558
575
|
references: { images: 1 },
|
|
559
576
|
requires: ["references"],
|
|
560
|
-
supports: ["scaleFactor", "outputFormat"]
|
|
577
|
+
supports: ["scaleFactor", "outputFormat", "upscale"]
|
|
561
578
|
},
|
|
562
579
|
defaults: { scaleFactor: 2, outputFormat: "png" },
|
|
563
580
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
@@ -804,7 +821,7 @@ var VIDEO_MODELS = [
|
|
|
804
821
|
durations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
805
822
|
references: { images: 9, videos: 3, audios: 3, audioOnly: false },
|
|
806
823
|
ratioIgnoredWith: ["firstFrame"],
|
|
807
|
-
supports: ["generateAudio", "seed", "lastFrame"]
|
|
824
|
+
supports: ["generateAudio", "seed", "lastFrame", "watermark"]
|
|
808
825
|
},
|
|
809
826
|
defaults: {
|
|
810
827
|
durationSeconds: 5,
|
|
@@ -829,7 +846,7 @@ var VIDEO_MODELS = [
|
|
|
829
846
|
durations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
|
830
847
|
references: { images: 9, videos: 3, audios: 3, audioOnly: false },
|
|
831
848
|
ratioIgnoredWith: ["firstFrame"],
|
|
832
|
-
supports: ["generateAudio", "seed", "lastFrame"]
|
|
849
|
+
supports: ["generateAudio", "seed", "lastFrame", "watermark"]
|
|
833
850
|
},
|
|
834
851
|
defaults: {
|
|
835
852
|
durationSeconds: 5,
|
|
@@ -855,7 +872,7 @@ var VIDEO_MODELS = [
|
|
|
855
872
|
durations: { min: 4, max: 30 },
|
|
856
873
|
references: { images: 30, videos: 10, audios: 10 },
|
|
857
874
|
ratioIgnoredWith: ["firstFrame"],
|
|
858
|
-
supports: ["generateAudio", "seed", "lastFrame"]
|
|
875
|
+
supports: ["generateAudio", "seed", "lastFrame", "watermark"]
|
|
859
876
|
},
|
|
860
877
|
defaults: {
|
|
861
878
|
durationSeconds: 5,
|
|
@@ -882,7 +899,8 @@ var VIDEO_MODELS = [
|
|
|
882
899
|
references: { images: 7 },
|
|
883
900
|
supports: []
|
|
884
901
|
},
|
|
885
|
-
|
|
902
|
+
// No resolution default: xAI picks its own unless the caller asks.
|
|
903
|
+
defaults: { durationSeconds: 8, aspectRatio: "16:9" },
|
|
886
904
|
usage: { unit: "reported_cost_usd", modality: "VIDEO" },
|
|
887
905
|
pricingKind: "video_per_second"
|
|
888
906
|
},
|
|
@@ -976,7 +994,7 @@ var VIDEO_MODELS = [
|
|
|
976
994
|
aspectRatios: [...H3_RATIOS],
|
|
977
995
|
resolutions: ["480p", "768p", "2k", "4k"],
|
|
978
996
|
durations: { min: 5, max: 15 },
|
|
979
|
-
supports: ["seed", "promptExpansion"]
|
|
997
|
+
supports: ["seed", "promptExpansion", "lastFrame", "safetyChecker"]
|
|
980
998
|
},
|
|
981
999
|
defaults: {
|
|
982
1000
|
durationSeconds: 5,
|
|
@@ -999,7 +1017,7 @@ var VIDEO_MODELS = [
|
|
|
999
1017
|
aspectRatios: [...H3_RATIOS],
|
|
1000
1018
|
resolutions: ["480p", "768p"],
|
|
1001
1019
|
durations: { min: 5, max: 15 },
|
|
1002
|
-
supports: ["seed", "promptExpansion"]
|
|
1020
|
+
supports: ["seed", "promptExpansion", "lastFrame", "safetyChecker"]
|
|
1003
1021
|
},
|
|
1004
1022
|
defaults: {
|
|
1005
1023
|
durationSeconds: 5,
|
|
@@ -1023,7 +1041,7 @@ var VIDEO_MODELS = [
|
|
|
1023
1041
|
resolutions: ["480p", "768p", "2k", "4k"],
|
|
1024
1042
|
durations: { min: 5, max: 15 },
|
|
1025
1043
|
references: { images: 9, videos: 3, audios: 3, total: 12, audioOnly: false },
|
|
1026
|
-
supports: ["seed", "promptExpansion"]
|
|
1044
|
+
supports: ["seed", "promptExpansion", "safetyChecker"]
|
|
1027
1045
|
},
|
|
1028
1046
|
defaults: {
|
|
1029
1047
|
durationSeconds: 5,
|
|
@@ -1047,7 +1065,7 @@ var VIDEO_MODELS = [
|
|
|
1047
1065
|
resolutions: ["480p", "768p"],
|
|
1048
1066
|
durations: { min: 5, max: 15 },
|
|
1049
1067
|
references: { images: 9, videos: 3, audios: 3, total: 12, audioOnly: false },
|
|
1050
|
-
supports: ["seed", "promptExpansion"]
|
|
1068
|
+
supports: ["seed", "promptExpansion", "safetyChecker"]
|
|
1051
1069
|
},
|
|
1052
1070
|
defaults: {
|
|
1053
1071
|
durationSeconds: 5,
|
|
@@ -1175,19 +1193,22 @@ function resolveTier(field, code, requested, supported, order, model, onUnsuppor
|
|
|
1175
1193
|
});
|
|
1176
1194
|
return to;
|
|
1177
1195
|
}
|
|
1178
|
-
function resolveDuration(requested, durations, model, warnings) {
|
|
1196
|
+
function resolveDuration(requested, durations, model, onUnsupported, warnings) {
|
|
1179
1197
|
if (requested === void 0 || !durations) return requested;
|
|
1180
|
-
|
|
1181
|
-
if (
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
if (to === requested) return requested;
|
|
1198
|
+
const inSet = Array.isArray(durations) ? durations.includes(requested) : requested >= durations.min && requested <= durations.max;
|
|
1199
|
+
if (inSet) return requested;
|
|
1200
|
+
if (onUnsupported === "error") {
|
|
1201
|
+
const supported = Array.isArray(durations) ? `Supported: ${durations.join(", ")}.` : `Supported range: ${durations.min}-${durations.max}.`;
|
|
1202
|
+
throw new ModelKitError({
|
|
1203
|
+
code: "unsupported_option",
|
|
1204
|
+
message: `${model.id} does not support durationSeconds ${requested}. ${supported}`,
|
|
1205
|
+
model: model.id
|
|
1206
|
+
});
|
|
1190
1207
|
}
|
|
1208
|
+
const to = Array.isArray(durations) ? durations.reduce(
|
|
1209
|
+
(best, d) => Math.abs(d - requested) < Math.abs(best - requested) ? d : best,
|
|
1210
|
+
durations[0] ?? requested
|
|
1211
|
+
) : Math.min(Math.max(requested, durations.min), durations.max);
|
|
1191
1212
|
warnings.push({
|
|
1192
1213
|
code: "duration_coerced",
|
|
1193
1214
|
field: "durationSeconds",
|
|
@@ -1197,6 +1218,26 @@ function resolveDuration(requested, durations, model, warnings) {
|
|
|
1197
1218
|
});
|
|
1198
1219
|
return to;
|
|
1199
1220
|
}
|
|
1221
|
+
function resolveAspectRatio(requested, supported, model, onUnsupported, warnings) {
|
|
1222
|
+
if (requested === void 0 || requested === "adaptive" || !supported) return requested;
|
|
1223
|
+
if (supported.includes(requested)) return requested;
|
|
1224
|
+
if (onUnsupported === "error") {
|
|
1225
|
+
throw new ModelKitError({
|
|
1226
|
+
code: "unsupported_option",
|
|
1227
|
+
message: `${model.id} does not support aspectRatio "${requested}". Supported: ${supported.join(", ")}.`,
|
|
1228
|
+
model: model.id
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
const to = nearestAspectRatio(requested, supported);
|
|
1232
|
+
warnings.push({
|
|
1233
|
+
code: "ratio_coerced",
|
|
1234
|
+
field: "aspectRatio",
|
|
1235
|
+
from: requested,
|
|
1236
|
+
to,
|
|
1237
|
+
message: `aspect ratio ${requested} coerced to ${to} for ${model.id}`
|
|
1238
|
+
});
|
|
1239
|
+
return to;
|
|
1240
|
+
}
|
|
1200
1241
|
function compact(refs) {
|
|
1201
1242
|
return (refs ?? []).filter((r) => Boolean(r));
|
|
1202
1243
|
}
|
|
@@ -1215,17 +1256,14 @@ function resolveImageOptions(model, request, onUnsupported = "error") {
|
|
|
1215
1256
|
const warnings = [];
|
|
1216
1257
|
const c = model.constraints;
|
|
1217
1258
|
const merged = { ...model.defaults, ...stripUndefined(request), model: model.id };
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
});
|
|
1227
|
-
merged.aspectRatio = to;
|
|
1228
|
-
}
|
|
1259
|
+
const aspectRatio = resolveAspectRatio(
|
|
1260
|
+
merged.aspectRatio,
|
|
1261
|
+
c.aspectRatios,
|
|
1262
|
+
model,
|
|
1263
|
+
onUnsupported,
|
|
1264
|
+
warnings
|
|
1265
|
+
);
|
|
1266
|
+
if (aspectRatio !== void 0) merged.aspectRatio = aspectRatio;
|
|
1229
1267
|
const size = resolveTier(
|
|
1230
1268
|
"size",
|
|
1231
1269
|
"size_coerced",
|
|
@@ -1259,7 +1297,9 @@ function resolveImageOptions(model, request, onUnsupported = "error") {
|
|
|
1259
1297
|
"count",
|
|
1260
1298
|
"outputFormat",
|
|
1261
1299
|
"scaleFactor",
|
|
1262
|
-
"safetySettings"
|
|
1300
|
+
"safetySettings",
|
|
1301
|
+
"temperature",
|
|
1302
|
+
"upscale"
|
|
1263
1303
|
]);
|
|
1264
1304
|
return { request: merged, warnings };
|
|
1265
1305
|
}
|
|
@@ -1289,17 +1329,14 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
1289
1329
|
delete merged.aspectRatio;
|
|
1290
1330
|
}
|
|
1291
1331
|
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
});
|
|
1301
|
-
merged.aspectRatio = to;
|
|
1302
|
-
}
|
|
1332
|
+
const aspectRatio = resolveAspectRatio(
|
|
1333
|
+
merged.aspectRatio,
|
|
1334
|
+
c.aspectRatios,
|
|
1335
|
+
model,
|
|
1336
|
+
onUnsupported,
|
|
1337
|
+
warnings
|
|
1338
|
+
);
|
|
1339
|
+
if (aspectRatio !== void 0) merged.aspectRatio = aspectRatio;
|
|
1303
1340
|
const resolution = resolveTier(
|
|
1304
1341
|
"resolution",
|
|
1305
1342
|
"resolution_coerced",
|
|
@@ -1311,7 +1348,13 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
1311
1348
|
warnings
|
|
1312
1349
|
);
|
|
1313
1350
|
if (resolution !== void 0) merged.resolution = resolution;
|
|
1314
|
-
const duration = resolveDuration(
|
|
1351
|
+
const duration = resolveDuration(
|
|
1352
|
+
merged.durationSeconds,
|
|
1353
|
+
c.durations,
|
|
1354
|
+
model,
|
|
1355
|
+
onUnsupported,
|
|
1356
|
+
warnings
|
|
1357
|
+
);
|
|
1315
1358
|
if (duration !== void 0) merged.durationSeconds = duration;
|
|
1316
1359
|
const limits = c.references ?? {};
|
|
1317
1360
|
let images = trim(
|
|
@@ -1366,10 +1409,45 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
1366
1409
|
"cfgScale",
|
|
1367
1410
|
"generateAudio",
|
|
1368
1411
|
"promptExpansion",
|
|
1369
|
-
"lastFrame"
|
|
1412
|
+
"lastFrame",
|
|
1413
|
+
"watermark",
|
|
1414
|
+
"safetyChecker"
|
|
1370
1415
|
]);
|
|
1371
1416
|
return { request: merged, warnings };
|
|
1372
1417
|
}
|
|
1418
|
+
function resolveAudioOptions(model, request, onUnsupported = "error") {
|
|
1419
|
+
const warnings = [];
|
|
1420
|
+
const c = model.constraints;
|
|
1421
|
+
const merged = { ...model.defaults, ...stripUndefined(request), model: model.id };
|
|
1422
|
+
for (const input of c.requires ?? []) {
|
|
1423
|
+
const present = input === "references" ? compact(merged.references).length > 0 : input === "sourceVideo" && merged.sourceVideo !== void 0;
|
|
1424
|
+
if (!present)
|
|
1425
|
+
throw new ModelKitError({
|
|
1426
|
+
code: "missing_input",
|
|
1427
|
+
message: `${model.id} requires ${input}`,
|
|
1428
|
+
model: model.id
|
|
1429
|
+
});
|
|
1430
|
+
}
|
|
1431
|
+
const duration = resolveDuration(
|
|
1432
|
+
merged.durationSeconds,
|
|
1433
|
+
c.durations,
|
|
1434
|
+
model,
|
|
1435
|
+
onUnsupported,
|
|
1436
|
+
warnings
|
|
1437
|
+
);
|
|
1438
|
+
if (duration !== void 0) merged.durationSeconds = duration;
|
|
1439
|
+
const references = trim(
|
|
1440
|
+
"references",
|
|
1441
|
+
compact(merged.references),
|
|
1442
|
+
c.references?.images ?? c.references?.total,
|
|
1443
|
+
model,
|
|
1444
|
+
warnings
|
|
1445
|
+
);
|
|
1446
|
+
if (references.length > 0) merged.references = references;
|
|
1447
|
+
else delete merged.references;
|
|
1448
|
+
dropUnsupported(merged, model, warnings, ["seed", "negativePrompt", "instrumental"]);
|
|
1449
|
+
return { request: merged, warnings };
|
|
1450
|
+
}
|
|
1373
1451
|
function dropUnsupported(req, model, warnings, fields) {
|
|
1374
1452
|
const supports = model.constraints.supports ?? [];
|
|
1375
1453
|
for (const field of fields) {
|
|
@@ -1411,6 +1489,9 @@ function hasAll(keys, names) {
|
|
|
1411
1489
|
(n) => Boolean(keys[n]) && (n !== "higgsfield" || Boolean(keys.higgsfieldSecret))
|
|
1412
1490
|
);
|
|
1413
1491
|
}
|
|
1492
|
+
function missingEnterpriseKeys(config, names) {
|
|
1493
|
+
return names.filter((name) => !hasAll(config.keys.enterprise, [name]));
|
|
1494
|
+
}
|
|
1414
1495
|
function resolveKeys(config, names, tier = "pro") {
|
|
1415
1496
|
if (tier === "enterprise" && hasAll(config.keys.enterprise, names))
|
|
1416
1497
|
return config.keys.enterprise;
|
|
@@ -1443,7 +1524,6 @@ function keysFromEnv(env, prefix = "") {
|
|
|
1443
1524
|
set("prodia", pick("PRODIA_API_KEY", "PRODIA_TOKEN"));
|
|
1444
1525
|
set("higgsfield", pick("HIGGSFIELD_API_KEY"));
|
|
1445
1526
|
set("higgsfieldSecret", pick("HIGGSFIELD_API_SECRET"));
|
|
1446
|
-
set("openrouter", pick("OPENROUTER_API_KEY"));
|
|
1447
1527
|
set("cloudflare", pick("CLOUDFLARE_AI_GATEWAY_TOKEN", "CF_AIG_TOKEN"));
|
|
1448
1528
|
return keys;
|
|
1449
1529
|
}
|
|
@@ -1491,7 +1571,9 @@ var textBody = import_zod2.z.string();
|
|
|
1491
1571
|
function classifyHttpError(status, body, provider, model) {
|
|
1492
1572
|
const asText = textBody.safeParse(body);
|
|
1493
1573
|
const text2 = asText.success ? asText.data : JSON.stringify(body);
|
|
1494
|
-
const blocked = /
|
|
1574
|
+
const blocked = /content_policy_violation|blockReason|PROHIBITED_CONTENT|moderation_blocked|safety(?![_A-Za-z])/i.test(
|
|
1575
|
+
text2
|
|
1576
|
+
);
|
|
1495
1577
|
let code = "provider_rejected";
|
|
1496
1578
|
if (blocked) code = "content_blocked";
|
|
1497
1579
|
else if (status === 401 || status === 403) code = "auth";
|
|
@@ -1512,8 +1594,8 @@ function classifyHttpError(status, body, provider, model) {
|
|
|
1512
1594
|
}
|
|
1513
1595
|
function shouldRetry(err) {
|
|
1514
1596
|
if (err instanceof ModelKitError) return err.retryable;
|
|
1515
|
-
if (err.name === "AbortError"
|
|
1516
|
-
|
|
1597
|
+
if (err.name === "AbortError") return false;
|
|
1598
|
+
if (/ECONNRESET|ETIMEDOUT|fetch failed|socket hang up/i.test(err.message)) return true;
|
|
1517
1599
|
return false;
|
|
1518
1600
|
}
|
|
1519
1601
|
async function withRetry(fn, opts = {}) {
|
|
@@ -1698,6 +1780,12 @@ var import_zod4 = require("zod");
|
|
|
1698
1780
|
function isUrlRef(ref) {
|
|
1699
1781
|
return "url" in ref;
|
|
1700
1782
|
}
|
|
1783
|
+
function abortedError() {
|
|
1784
|
+
return new ModelKitError({ code: "timeout", message: "aborted", retryable: false });
|
|
1785
|
+
}
|
|
1786
|
+
function throwIfAborted(signal) {
|
|
1787
|
+
if (signal?.aborted) throw abortedError();
|
|
1788
|
+
}
|
|
1701
1789
|
function mediaRefToBase64(bytes) {
|
|
1702
1790
|
let binary = "";
|
|
1703
1791
|
const CHUNK = 32768;
|
|
@@ -1712,10 +1800,34 @@ function base64ToBytes(b64) {
|
|
|
1712
1800
|
for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);
|
|
1713
1801
|
return out;
|
|
1714
1802
|
}
|
|
1715
|
-
|
|
1803
|
+
function mediaRefToDataUrl(ref) {
|
|
1804
|
+
if (isUrlRef(ref)) return ref.url;
|
|
1805
|
+
return `data:${ref.mime};base64,${mediaRefToBase64(ref.bytes)}`;
|
|
1806
|
+
}
|
|
1807
|
+
var refToUrl = mediaRefToDataUrl;
|
|
1808
|
+
async function readBody(res) {
|
|
1809
|
+
const text2 = await res.text().catch(() => "");
|
|
1810
|
+
try {
|
|
1811
|
+
const decoded = JsonValueSchema.safeParse(JSON.parse(text2));
|
|
1812
|
+
return decoded.success ? decoded.data : text2;
|
|
1813
|
+
} catch {
|
|
1814
|
+
return text2;
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
async function mediaRefToBytes(ref, fetch, options = {}) {
|
|
1716
1818
|
if (!isUrlRef(ref)) return { bytes: ref.bytes, mime: ref.mime };
|
|
1717
|
-
const
|
|
1718
|
-
if (
|
|
1819
|
+
const init = {};
|
|
1820
|
+
if (options.signal !== void 0) init.signal = options.signal;
|
|
1821
|
+
const res = await fetch(ref.url, init);
|
|
1822
|
+
if (!res.ok) {
|
|
1823
|
+
const text2 = await res.text().catch(() => "");
|
|
1824
|
+
throw classifyHttpError(
|
|
1825
|
+
res.status,
|
|
1826
|
+
text2,
|
|
1827
|
+
options.provider ?? "media-reference",
|
|
1828
|
+
options.model
|
|
1829
|
+
);
|
|
1830
|
+
}
|
|
1719
1831
|
const mime = res.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase() || "image/png";
|
|
1720
1832
|
return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
|
|
1721
1833
|
}
|
|
@@ -1773,16 +1885,6 @@ var GATEWAY_SLUGS = {
|
|
|
1773
1885
|
perplexity: "perplexity-ai",
|
|
1774
1886
|
deepseek: "deepseek"
|
|
1775
1887
|
};
|
|
1776
|
-
var OPENROUTER_VENDORS = {
|
|
1777
|
-
openai: "openai",
|
|
1778
|
-
anthropic: "anthropic",
|
|
1779
|
-
google: "google",
|
|
1780
|
-
xai: "x-ai",
|
|
1781
|
-
perplexity: "perplexity",
|
|
1782
|
-
deepseek: "deepseek",
|
|
1783
|
-
moonshot: "moonshotai",
|
|
1784
|
-
minimax: "minimax"
|
|
1785
|
-
};
|
|
1786
1888
|
function detectTextProvider(modelId) {
|
|
1787
1889
|
const id = modelId.toLowerCase();
|
|
1788
1890
|
if (id.startsWith("claude") || id.includes("anthropic.")) return "anthropic";
|
|
@@ -1799,14 +1901,17 @@ function detectTextProvider(modelId) {
|
|
|
1799
1901
|
message: `ai-sdk-text cannot detect a provider for "${modelId}". Set providerOptions.provider to one of ${TEXT_PROVIDERS.join(", ")}.`
|
|
1800
1902
|
});
|
|
1801
1903
|
}
|
|
1802
|
-
function textKeyName(model,
|
|
1803
|
-
if (routing.text === "openrouter") return "openrouter";
|
|
1904
|
+
function textKeyName(model, _routing) {
|
|
1804
1905
|
return textProviderOf(model);
|
|
1805
1906
|
}
|
|
1806
1907
|
function textProviderOf(model) {
|
|
1807
1908
|
const explicit = model.providerOptions?.["modelkit"]?.["provider"];
|
|
1808
1909
|
return isTextProvider(explicit) ? explicit : detectTextProvider(model.providerModelId);
|
|
1809
1910
|
}
|
|
1911
|
+
function textUsesCloudflareGateway(model, routing) {
|
|
1912
|
+
if (routing.text !== "cloudflare") return false;
|
|
1913
|
+
return GATEWAY_SLUGS[textProviderOf(model)] !== void 0;
|
|
1914
|
+
}
|
|
1810
1915
|
function nativeClientFor(provider) {
|
|
1811
1916
|
switch (provider) {
|
|
1812
1917
|
case "openai":
|
|
@@ -1839,16 +1944,6 @@ function resolveTextRoute(ctx) {
|
|
|
1839
1944
|
retryable: false
|
|
1840
1945
|
});
|
|
1841
1946
|
}
|
|
1842
|
-
if (mode === "openrouter") {
|
|
1843
|
-
const modelId = ctx.model.providerModelId.includes("/") ? ctx.model.providerModelId : `${OPENROUTER_VENDORS[provider]}/${ctx.model.providerModelId}`;
|
|
1844
|
-
return {
|
|
1845
|
-
provider,
|
|
1846
|
-
client: "openai-compatible",
|
|
1847
|
-
modelId,
|
|
1848
|
-
keyName: "openrouter",
|
|
1849
|
-
baseURL: "https://openrouter.ai/api/v1"
|
|
1850
|
-
};
|
|
1851
|
-
}
|
|
1852
1947
|
const compatBase = OPENAI_COMPATIBLE_BASE_URLS[provider];
|
|
1853
1948
|
const route2 = {
|
|
1854
1949
|
provider,
|
|
@@ -1916,7 +2011,7 @@ var aiSdkTextAdapter = {
|
|
|
1916
2011
|
case "openai-compatible":
|
|
1917
2012
|
return (0, import_openai.createOpenAI)({
|
|
1918
2013
|
...settings,
|
|
1919
|
-
name: route2.provider
|
|
2014
|
+
name: route2.provider
|
|
1920
2015
|
}).chat(route2.modelId);
|
|
1921
2016
|
case "openai":
|
|
1922
2017
|
return (0, import_openai.createOpenAI)(settings)(route2.modelId);
|
|
@@ -1929,8 +2024,9 @@ function requiredKeys(model, config) {
|
|
|
1929
2024
|
if (model.adapter === "fal" && config.routing?.fal === "cloudflare-passthrough")
|
|
1930
2025
|
return ["cloudflare"];
|
|
1931
2026
|
if (model.adapter === "ai-sdk-text") {
|
|
1932
|
-
const
|
|
1933
|
-
|
|
2027
|
+
const routing = config.routing ?? {};
|
|
2028
|
+
const names = [textKeyName(model, routing)];
|
|
2029
|
+
if (textUsesCloudflareGateway(model, routing)) names.push("cloudflare");
|
|
1934
2030
|
return names;
|
|
1935
2031
|
}
|
|
1936
2032
|
return ADAPTER_KEYS[model.adapter];
|
|
@@ -2004,6 +2100,11 @@ function pushIgnored(warnings, field, from, modelId) {
|
|
|
2004
2100
|
message: `${modelId} provider instance does not support ${field}; ignored`
|
|
2005
2101
|
});
|
|
2006
2102
|
}
|
|
2103
|
+
function withoutModelkit(options) {
|
|
2104
|
+
if (!options) return {};
|
|
2105
|
+
const { modelkit: _modelkit, ...rest } = options;
|
|
2106
|
+
return rest;
|
|
2107
|
+
}
|
|
2007
2108
|
function logCoercions(logger, modelId, warnings) {
|
|
2008
2109
|
if (warnings.length === 0) return;
|
|
2009
2110
|
logger.warn(`[modelkit] ${modelId} request coerced`, { model: modelId, warnings });
|
|
@@ -2020,7 +2121,16 @@ function createModelKit(config, adapters) {
|
|
|
2020
2121
|
message: `No adapter registered for ${model.adapter}`,
|
|
2021
2122
|
model: model.id
|
|
2022
2123
|
});
|
|
2023
|
-
const
|
|
2124
|
+
const names = requiredKeys(model, config);
|
|
2125
|
+
if (call.tier === "enterprise") {
|
|
2126
|
+
const missing = missingEnterpriseKeys(config, names);
|
|
2127
|
+
if (missing.length > 0)
|
|
2128
|
+
logger.warn(
|
|
2129
|
+
`[modelkit] enterprise keys incomplete for ${model.adapter}; using pro`,
|
|
2130
|
+
{ missing }
|
|
2131
|
+
);
|
|
2132
|
+
}
|
|
2133
|
+
const keys = resolveKeys(config, names, call.tier);
|
|
2024
2134
|
const ctx = {
|
|
2025
2135
|
model,
|
|
2026
2136
|
keys,
|
|
@@ -2341,8 +2451,15 @@ function createModelKit(config, adapters) {
|
|
|
2341
2451
|
model: model.id
|
|
2342
2452
|
});
|
|
2343
2453
|
}
|
|
2344
|
-
const
|
|
2345
|
-
const {
|
|
2454
|
+
const { abortSignal: _signal, ...request } = req;
|
|
2455
|
+
const { request: resolved, warnings } = resolveAudioOptions(
|
|
2456
|
+
model,
|
|
2457
|
+
request,
|
|
2458
|
+
call.onUnsupported ?? "error"
|
|
2459
|
+
);
|
|
2460
|
+
logCoercions(logger, model.id, warnings);
|
|
2461
|
+
const signal = combineSignals(req.abortSignal, call.signal);
|
|
2462
|
+
const { adapter, ctx } = context(model, signal ? { ...call, signal } : call, warnings);
|
|
2346
2463
|
if (!adapter.generateAudio) {
|
|
2347
2464
|
throw new ModelKitError({
|
|
2348
2465
|
code: "unsupported_option",
|
|
@@ -2350,11 +2467,7 @@ function createModelKit(config, adapters) {
|
|
|
2350
2467
|
model: model.id
|
|
2351
2468
|
});
|
|
2352
2469
|
}
|
|
2353
|
-
const result = await adapter.generateAudio(
|
|
2354
|
-
{ ...model.defaults, ...req, model: model.id },
|
|
2355
|
-
ctx
|
|
2356
|
-
);
|
|
2357
|
-
logCoercions(logger, model.id, warnings);
|
|
2470
|
+
const result = await adapter.generateAudio(resolved, ctx);
|
|
2358
2471
|
await emit({ ...result.usage, model: model.id, unit: model.usage.unit });
|
|
2359
2472
|
return result;
|
|
2360
2473
|
},
|
|
@@ -2375,7 +2488,7 @@ function createModelKit(config, adapters) {
|
|
|
2375
2488
|
});
|
|
2376
2489
|
return {
|
|
2377
2490
|
model,
|
|
2378
|
-
providerOptions: entry.providerOptions
|
|
2491
|
+
providerOptions: withoutModelkit(entry.providerOptions),
|
|
2379
2492
|
catalog: entry
|
|
2380
2493
|
};
|
|
2381
2494
|
},
|
|
@@ -2411,7 +2524,9 @@ function createModelKit(config, adapters) {
|
|
|
2411
2524
|
...textAbortOptions(options.abortSignal, call.signal),
|
|
2412
2525
|
model: target.languageModel,
|
|
2413
2526
|
providerOptions: {},
|
|
2414
|
-
prepareStep: steps.wrap(
|
|
2527
|
+
prepareStep: steps.wrap(
|
|
2528
|
+
options.prepareStep ?? options.experimental_prepareStep
|
|
2529
|
+
),
|
|
2415
2530
|
onFinish: async (event) => {
|
|
2416
2531
|
for (const usage2 of steps.usage(event.steps)) await emit(withRowUnit(usage2));
|
|
2417
2532
|
await callerOnFinish?.(event);
|
|
@@ -2468,6 +2583,7 @@ var SEEDREAM_SIZES = {
|
|
|
2468
2583
|
"3:2": "1248x832",
|
|
2469
2584
|
"2:3": "832x1248",
|
|
2470
2585
|
"21:9": "1568x672",
|
|
2586
|
+
"9:21": "672x1568",
|
|
2471
2587
|
"4:5": "864x1080",
|
|
2472
2588
|
"5:4": "1080x864"
|
|
2473
2589
|
},
|
|
@@ -2480,16 +2596,34 @@ var SEEDREAM_SIZES = {
|
|
|
2480
2596
|
"3:2": "2496x1664",
|
|
2481
2597
|
"2:3": "1664x2496",
|
|
2482
2598
|
"21:9": "3136x1344",
|
|
2599
|
+
"9:21": "1344x3136",
|
|
2483
2600
|
"4:5": "1728x2160",
|
|
2484
2601
|
"5:4": "2160x1728"
|
|
2602
|
+
},
|
|
2603
|
+
// 4K keeps the long edge at Ark's 4096 cap (a doubled 2K entry would exceed
|
|
2604
|
+
// it); sides are multiples of 16.
|
|
2605
|
+
"4K": {
|
|
2606
|
+
"1:1": "4096x4096",
|
|
2607
|
+
"4:3": "4096x3072",
|
|
2608
|
+
"3:4": "3072x4096",
|
|
2609
|
+
"16:9": "4096x2304",
|
|
2610
|
+
"9:16": "2304x4096",
|
|
2611
|
+
"3:2": "4096x2736",
|
|
2612
|
+
"2:3": "2736x4096",
|
|
2613
|
+
"21:9": "4096x1760",
|
|
2614
|
+
"9:21": "1760x4096",
|
|
2615
|
+
"4:5": "3280x4096",
|
|
2616
|
+
"5:4": "4096x3280"
|
|
2485
2617
|
}
|
|
2486
2618
|
};
|
|
2487
2619
|
var arkAdapter = {
|
|
2488
2620
|
id: "ark",
|
|
2489
2621
|
async generateImage(req, ctx) {
|
|
2622
|
+
throwIfAborted(ctx.signal);
|
|
2490
2623
|
return generateSeedreamImage(req, ctx);
|
|
2491
2624
|
},
|
|
2492
2625
|
async generateVideo(req, ctx) {
|
|
2626
|
+
throwIfAborted(ctx.signal);
|
|
2493
2627
|
return generateSeedanceVideo(req, ctx);
|
|
2494
2628
|
}
|
|
2495
2629
|
};
|
|
@@ -2509,7 +2643,7 @@ function arkKey(ctx) {
|
|
|
2509
2643
|
function throwArkError(status, body, model) {
|
|
2510
2644
|
const parsed = import_zod5.z.string().safeParse(body);
|
|
2511
2645
|
const text2 = parsed.success ? parsed.data : JSON.stringify(body ?? "");
|
|
2512
|
-
if (/sensitive.?content|
|
|
2646
|
+
if (/sensitive.?content|human.?face/i.test(text2)) {
|
|
2513
2647
|
const init = {
|
|
2514
2648
|
code: "content_blocked",
|
|
2515
2649
|
message: `ark rejected the request: ${text2.slice(0, 500)}`,
|
|
@@ -2534,7 +2668,7 @@ function throwArkError(status, body, model) {
|
|
|
2534
2668
|
throw classifyHttpError(status, body, "ark", model);
|
|
2535
2669
|
}
|
|
2536
2670
|
function seedreamSize(aspect, size) {
|
|
2537
|
-
const tier = size === "
|
|
2671
|
+
const tier = size === "4K" || size === "1K" ? size : "2K";
|
|
2538
2672
|
const table = SEEDREAM_SIZES[tier];
|
|
2539
2673
|
return table[aspect ?? ""] ?? table["1:1"] ?? "2048x2048";
|
|
2540
2674
|
}
|
|
@@ -2545,10 +2679,6 @@ function sniffedImageMime(bytes) {
|
|
|
2545
2679
|
return "image/webp";
|
|
2546
2680
|
return "image/jpeg";
|
|
2547
2681
|
}
|
|
2548
|
-
function arkUrl(ref) {
|
|
2549
|
-
if ("url" in ref) return ref.url;
|
|
2550
|
-
return `data:${ref.mime};base64,${Buffer.from(ref.bytes).toString("base64")}`;
|
|
2551
|
-
}
|
|
2552
2682
|
var SeedreamImageSchema = import_zod5.z.object({
|
|
2553
2683
|
url: import_zod5.z.string().optional(),
|
|
2554
2684
|
b64_json: import_zod5.z.string().optional()
|
|
@@ -2575,7 +2705,7 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2575
2705
|
const key = arkKey(ctx);
|
|
2576
2706
|
const modelId = ctx.model.id;
|
|
2577
2707
|
const size = seedreamSize(req.aspectRatio, req.size);
|
|
2578
|
-
const refs = (req.references ?? []).map(
|
|
2708
|
+
const refs = (req.references ?? []).map(refToUrl);
|
|
2579
2709
|
const body = {
|
|
2580
2710
|
model: ctx.model.providerModelId,
|
|
2581
2711
|
prompt: req.prompt,
|
|
@@ -2627,10 +2757,18 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2627
2757
|
if (req.quality !== void 0) usage2.imageQuality = req.quality;
|
|
2628
2758
|
return { images: [{ bytes, mime: sniffedImageMime(bytes) }], usage: usage2, raw: data };
|
|
2629
2759
|
}
|
|
2760
|
+
var SeedanceUsageSchema = import_zod5.z.object({
|
|
2761
|
+
total_tokens: import_zod5.z.number().optional(),
|
|
2762
|
+
completion_tokens: import_zod5.z.number().optional()
|
|
2763
|
+
});
|
|
2630
2764
|
var SeedanceResponseSchema = import_zod5.z.object({
|
|
2631
2765
|
id: import_zod5.z.string().optional(),
|
|
2632
2766
|
status: import_zod5.z.string().optional(),
|
|
2633
2767
|
content: import_zod5.z.object({ video_url: import_zod5.z.string().optional() }).optional(),
|
|
2768
|
+
usage: SeedanceUsageSchema.optional(),
|
|
2769
|
+
duration: import_zod5.z.number().optional(),
|
|
2770
|
+
framespersecond: import_zod5.z.number().optional(),
|
|
2771
|
+
resolution: import_zod5.z.string().optional(),
|
|
2634
2772
|
error: import_zod5.z.union([import_zod5.z.string(), import_zod5.z.object({ message: import_zod5.z.string().optional() })]).optional()
|
|
2635
2773
|
});
|
|
2636
2774
|
var SeedanceErrorMessageSchema = import_zod5.z.object({ message: import_zod5.z.string().optional() });
|
|
@@ -2662,42 +2800,42 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2662
2800
|
if (req.firstFrame) {
|
|
2663
2801
|
content.push({
|
|
2664
2802
|
type: "image_url",
|
|
2665
|
-
image_url: { url:
|
|
2803
|
+
image_url: { url: refToUrl(req.firstFrame) },
|
|
2666
2804
|
role: "first_frame"
|
|
2667
2805
|
});
|
|
2668
2806
|
}
|
|
2669
2807
|
if (req.lastFrame) {
|
|
2670
2808
|
content.push({
|
|
2671
2809
|
type: "image_url",
|
|
2672
|
-
image_url: { url:
|
|
2810
|
+
image_url: { url: refToUrl(req.lastFrame) },
|
|
2673
2811
|
role: "last_frame"
|
|
2674
2812
|
});
|
|
2675
2813
|
}
|
|
2676
2814
|
for (const ref of req.referenceImages ?? []) {
|
|
2677
2815
|
content.push({
|
|
2678
2816
|
type: "image_url",
|
|
2679
|
-
image_url: { url:
|
|
2817
|
+
image_url: { url: refToUrl(ref) },
|
|
2680
2818
|
role: "reference_image"
|
|
2681
2819
|
});
|
|
2682
2820
|
}
|
|
2683
2821
|
if (req.sourceVideo) {
|
|
2684
2822
|
content.push({
|
|
2685
2823
|
type: "video_url",
|
|
2686
|
-
video_url: { url:
|
|
2824
|
+
video_url: { url: refToUrl(req.sourceVideo) },
|
|
2687
2825
|
role: "reference_video"
|
|
2688
2826
|
});
|
|
2689
2827
|
}
|
|
2690
2828
|
for (const ref of req.referenceVideos ?? []) {
|
|
2691
2829
|
content.push({
|
|
2692
2830
|
type: "video_url",
|
|
2693
|
-
video_url: { url:
|
|
2831
|
+
video_url: { url: refToUrl(ref) },
|
|
2694
2832
|
role: "reference_video"
|
|
2695
2833
|
});
|
|
2696
2834
|
}
|
|
2697
2835
|
for (const ref of req.referenceAudios ?? []) {
|
|
2698
2836
|
content.push({
|
|
2699
2837
|
type: "audio_url",
|
|
2700
|
-
audio_url: { url:
|
|
2838
|
+
audio_url: { url: refToUrl(ref) },
|
|
2701
2839
|
role: "reference_audio"
|
|
2702
2840
|
});
|
|
2703
2841
|
}
|
|
@@ -2711,6 +2849,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2711
2849
|
if (!hasFrameAnchor && req.aspectRatio !== void 0) body.ratio = req.aspectRatio;
|
|
2712
2850
|
if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
|
|
2713
2851
|
if (req.seed !== void 0) body.seed = req.seed;
|
|
2852
|
+
if (req.watermark !== void 0) body.watermark = req.watermark;
|
|
2714
2853
|
const submit = await withRetry(async () => {
|
|
2715
2854
|
const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}`, {
|
|
2716
2855
|
method: "POST",
|
|
@@ -2774,6 +2913,11 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2774
2913
|
"Seedance task succeeded but returned no video_url",
|
|
2775
2914
|
modelId
|
|
2776
2915
|
);
|
|
2916
|
+
const tokens = polled.usage;
|
|
2917
|
+
if (tokens?.total_tokens !== void 0 && tokens.completion_tokens !== void 0) {
|
|
2918
|
+
usage2.inputTokens = tokens.total_tokens - tokens.completion_tokens;
|
|
2919
|
+
usage2.outputTokens = tokens.completion_tokens;
|
|
2920
|
+
}
|
|
2777
2921
|
return {
|
|
2778
2922
|
video: { url, expiresAt: new Date(Date.now() + VIDEO_URL_TTL_MS) },
|
|
2779
2923
|
usage: usage2,
|
|
@@ -2837,24 +2981,17 @@ var defaultDeps = { createFalClient: defaultCreateFalClient };
|
|
|
2837
2981
|
function createFalAdapter(deps = defaultDeps) {
|
|
2838
2982
|
return {
|
|
2839
2983
|
id: "fal",
|
|
2840
|
-
generateImage: (req, ctx) =>
|
|
2841
|
-
|
|
2984
|
+
generateImage: (req, ctx) => {
|
|
2985
|
+
throwIfAborted(ctx.signal);
|
|
2986
|
+
return generateMuseImage(req, ctx, deps);
|
|
2987
|
+
},
|
|
2988
|
+
generateVideo: (req, ctx) => {
|
|
2989
|
+
throwIfAborted(ctx.signal);
|
|
2990
|
+
return generateFalVideo(req, ctx, deps);
|
|
2991
|
+
}
|
|
2842
2992
|
};
|
|
2843
2993
|
}
|
|
2844
2994
|
var falAdapter = createFalAdapter();
|
|
2845
|
-
function refToUrl(ref) {
|
|
2846
|
-
if ("url" in ref) return ref.url;
|
|
2847
|
-
return `data:${ref.mime};base64,${Buffer.from(ref.bytes).toString("base64")}`;
|
|
2848
|
-
}
|
|
2849
|
-
async function readBody(res) {
|
|
2850
|
-
const text2 = await res.text().catch(() => "");
|
|
2851
|
-
try {
|
|
2852
|
-
const decoded = JsonValueSchema.safeParse(JSON.parse(text2));
|
|
2853
|
-
return decoded.success ? decoded.data : text2;
|
|
2854
|
-
} catch {
|
|
2855
|
-
return text2;
|
|
2856
|
-
}
|
|
2857
|
-
}
|
|
2858
2995
|
var falDetailSchema = import_zod6.z.object({ detail: JsonValueSchema });
|
|
2859
2996
|
function liftDetail(body) {
|
|
2860
2997
|
const parsed = falDetailSchema.safeParse(body);
|
|
@@ -3091,8 +3228,12 @@ async function generateMuseImage(req, ctx, deps) {
|
|
|
3091
3228
|
raw: payload
|
|
3092
3229
|
};
|
|
3093
3230
|
}
|
|
3231
|
+
var H3_MAX_MODEL_IDS = /* @__PURE__ */ new Set([
|
|
3232
|
+
"minimax/h3-max",
|
|
3233
|
+
"minimax/h3-max/reference-to-video"
|
|
3234
|
+
]);
|
|
3094
3235
|
function minimaxFamily(providerModelId) {
|
|
3095
|
-
return providerModelId.toLowerCase()
|
|
3236
|
+
return H3_MAX_MODEL_IDS.has(providerModelId.toLowerCase()) ? "h3-max" : "h3";
|
|
3096
3237
|
}
|
|
3097
3238
|
function minimaxBase(req, family) {
|
|
3098
3239
|
const resolution = (family === "h3-max" ? req.resolution ?? "768p" : req.resolution ?? "2k").toUpperCase();
|
|
@@ -3100,14 +3241,17 @@ function minimaxBase(req, family) {
|
|
|
3100
3241
|
prompt: req.prompt.trim(),
|
|
3101
3242
|
duration: req.durationSeconds ?? 5,
|
|
3102
3243
|
resolution,
|
|
3103
|
-
prompt_expansion_mode: req.promptExpansion ?? "balanced"
|
|
3104
|
-
enable_safety_checker: true
|
|
3244
|
+
prompt_expansion_mode: req.promptExpansion ?? "balanced"
|
|
3105
3245
|
};
|
|
3246
|
+
if (req.safetyChecker !== void 0) input.enable_safety_checker = req.safetyChecker;
|
|
3106
3247
|
if (req.seed !== void 0) input.seed = req.seed;
|
|
3107
3248
|
return input;
|
|
3108
3249
|
}
|
|
3250
|
+
var KLING_MODEL_IDS = /* @__PURE__ */ new Set([
|
|
3251
|
+
"fal-ai/kling-video/o1/video-to-video/reference"
|
|
3252
|
+
]);
|
|
3109
3253
|
function isKling(providerModelId) {
|
|
3110
|
-
return providerModelId.toLowerCase()
|
|
3254
|
+
return KLING_MODEL_IDS.has(providerModelId.toLowerCase());
|
|
3111
3255
|
}
|
|
3112
3256
|
function klingO1Input(req) {
|
|
3113
3257
|
const source = req.sourceVideo ? refToUrl(req.sourceVideo) : void 0;
|
|
@@ -3180,7 +3324,9 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
3180
3324
|
if (lastFrame) base.end_image_url = lastFrame;
|
|
3181
3325
|
} else {
|
|
3182
3326
|
endpoint = `minimax/${family}/text-to-video`;
|
|
3183
|
-
|
|
3327
|
+
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
3328
|
+
base.aspect_ratio = req.aspectRatio;
|
|
3329
|
+
}
|
|
3184
3330
|
}
|
|
3185
3331
|
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
3186
3332
|
return await passthroughVideoJob(ctx, req, endpoint, base);
|
|
@@ -3666,6 +3812,14 @@ async function generateVeoVideo(req, ctx, createGenAIClient) {
|
|
|
3666
3812
|
model: modelId
|
|
3667
3813
|
});
|
|
3668
3814
|
}
|
|
3815
|
+
if (req.lastFrame !== void 0 && req.firstFrame === void 0) {
|
|
3816
|
+
throw new ModelKitError({
|
|
3817
|
+
code: "missing_input",
|
|
3818
|
+
message: `${modelId} requires firstFrame when lastFrame is set`,
|
|
3819
|
+
provider: "google-genai",
|
|
3820
|
+
model: modelId
|
|
3821
|
+
});
|
|
3822
|
+
}
|
|
3669
3823
|
const duration = req.durationSeconds ?? 8;
|
|
3670
3824
|
const personGeneration = req.firstFrame ?? refs.length > 0 ? "allow_adult" : "allow_all";
|
|
3671
3825
|
let image;
|
|
@@ -3732,7 +3886,7 @@ async function generateVeoVideo(req, ctx, createGenAIClient) {
|
|
|
3732
3886
|
throwSdkError(cause, modelId);
|
|
3733
3887
|
}
|
|
3734
3888
|
};
|
|
3735
|
-
const jobId = operation.name ??
|
|
3889
|
+
const jobId = operation.name ?? crypto.randomUUID();
|
|
3736
3890
|
const usage2 = videoUsage2(ctx, req, duration);
|
|
3737
3891
|
return {
|
|
3738
3892
|
jobId,
|
|
@@ -3871,6 +4025,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3871
4025
|
});
|
|
3872
4026
|
}
|
|
3873
4027
|
for (const ref of videos) {
|
|
4028
|
+
if (ref.label !== void 0) parts.push({ type: "text", text: ref.label });
|
|
3874
4029
|
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "video/mp4", modelId);
|
|
3875
4030
|
parts.push({
|
|
3876
4031
|
type: "video",
|
|
@@ -3879,6 +4034,8 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3879
4034
|
});
|
|
3880
4035
|
}
|
|
3881
4036
|
if (req.firstFrame) {
|
|
4037
|
+
if (req.firstFrame.label !== void 0)
|
|
4038
|
+
parts.push({ type: "text", text: req.firstFrame.label });
|
|
3882
4039
|
const media = await resolveMedia(
|
|
3883
4040
|
req.firstFrame,
|
|
3884
4041
|
ctx.fetch,
|
|
@@ -3897,6 +4054,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3897
4054
|
}
|
|
3898
4055
|
}
|
|
3899
4056
|
for (const ref of images) {
|
|
4057
|
+
if (ref.label !== void 0) parts.push({ type: "text", text: ref.label });
|
|
3900
4058
|
const media = await resolveMedia(ref, ctx.fetch, ctx.signal, "image/png", modelId);
|
|
3901
4059
|
if (media.bytes.length > OMNI_INLINE_LIMIT_BYTES) {
|
|
3902
4060
|
parts.push({
|
|
@@ -3940,7 +4098,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3940
4098
|
} finally {
|
|
3941
4099
|
await cleanupUploads();
|
|
3942
4100
|
}
|
|
3943
|
-
const jobId = interaction.id ??
|
|
4101
|
+
const jobId = interaction.id ?? crypto.randomUUID();
|
|
3944
4102
|
const usage2 = videoUsage2(ctx, req, duration);
|
|
3945
4103
|
const getInteraction = async () => {
|
|
3946
4104
|
try {
|
|
@@ -4166,11 +4324,11 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
4166
4324
|
const model = google(ctx.model.providerModelId);
|
|
4167
4325
|
const content = [];
|
|
4168
4326
|
for (const ref of req.references ?? []) {
|
|
4327
|
+
if (ref.label !== void 0) content.push({ type: "text", text: ref.label });
|
|
4169
4328
|
if ("url" in ref) content.push({ type: "image", image: ref.url });
|
|
4170
4329
|
else content.push({ type: "image", image: ref.bytes, mediaType: ref.mime });
|
|
4171
4330
|
}
|
|
4172
4331
|
content.push({ type: "text", text: req.prompt });
|
|
4173
|
-
void ctx.call.postCropToAspect;
|
|
4174
4332
|
const imageConfig = {};
|
|
4175
4333
|
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive")
|
|
4176
4334
|
imageConfig.aspectRatio = req.aspectRatio;
|
|
@@ -4186,7 +4344,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
4186
4344
|
const timeout = AbortSignal.timeout(GEMINI_IMAGE_TIMEOUT_MS);
|
|
4187
4345
|
const signal = ctx.signal !== void 0 ? AbortSignal.any([ctx.signal, timeout]) : timeout;
|
|
4188
4346
|
try {
|
|
4189
|
-
|
|
4347
|
+
const genOptions = {
|
|
4190
4348
|
model,
|
|
4191
4349
|
messages: [{ role: "user", content }],
|
|
4192
4350
|
maxRetries: 0,
|
|
@@ -4194,7 +4352,9 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
4194
4352
|
google: googleOptions
|
|
4195
4353
|
},
|
|
4196
4354
|
abortSignal: signal
|
|
4197
|
-
}
|
|
4355
|
+
};
|
|
4356
|
+
if (req.temperature !== void 0) genOptions.temperature = req.temperature;
|
|
4357
|
+
return await deps.runTextGeneration(genOptions);
|
|
4198
4358
|
} catch (cause) {
|
|
4199
4359
|
throw toProviderError(cause, ctx);
|
|
4200
4360
|
}
|
|
@@ -4398,26 +4558,14 @@ function headers(ctx) {
|
|
|
4398
4558
|
const { key, secret } = credentials(ctx);
|
|
4399
4559
|
return { "Content-Type": "application/json", "hf-api-key": key, "hf-secret": secret };
|
|
4400
4560
|
}
|
|
4401
|
-
function refToUrl2(ref) {
|
|
4402
|
-
if ("url" in ref) return ref.url;
|
|
4403
|
-
return `data:${ref.mime};base64,${Buffer.from(ref.bytes).toString("base64")}`;
|
|
4404
|
-
}
|
|
4405
|
-
async function readBody2(res) {
|
|
4406
|
-
const text2 = await res.text().catch(() => "");
|
|
4407
|
-
try {
|
|
4408
|
-
const decoded = JsonValueSchema.safeParse(JSON.parse(text2));
|
|
4409
|
-
return decoded.success ? decoded.data : text2;
|
|
4410
|
-
} catch {
|
|
4411
|
-
return text2;
|
|
4412
|
-
}
|
|
4413
|
-
}
|
|
4414
4561
|
function klingEndpoint(providerModelId) {
|
|
4415
4562
|
if (providerModelId.startsWith("http")) return providerModelId;
|
|
4416
4563
|
const path = providerModelId.startsWith("/") ? providerModelId.slice(1) : providerModelId;
|
|
4417
4564
|
return `${PLATFORM}/${path}`;
|
|
4418
4565
|
}
|
|
4419
|
-
|
|
4420
|
-
|
|
4566
|
+
var DOP_MODEL_IDS = /* @__PURE__ */ new Set(["dop", "dop-preview"]);
|
|
4567
|
+
function higgsfieldVideoKind(providerModelId) {
|
|
4568
|
+
return DOP_MODEL_IDS.has(providerModelId.toLowerCase()) ? "dop" : "kling";
|
|
4421
4569
|
}
|
|
4422
4570
|
function videoUsage3(ctx, req, duration) {
|
|
4423
4571
|
const event = {
|
|
@@ -4461,12 +4609,12 @@ async function createRequest(ctx, url, init) {
|
|
|
4461
4609
|
throw classifyThrown("higgsfield", cause, ctx.model.id);
|
|
4462
4610
|
}
|
|
4463
4611
|
if (!res.ok) {
|
|
4464
|
-
throw classifyHttpError(res.status, await
|
|
4612
|
+
throw classifyHttpError(res.status, await readBody(res), "higgsfield", ctx.model.id);
|
|
4465
4613
|
}
|
|
4466
4614
|
return res;
|
|
4467
4615
|
}
|
|
4468
4616
|
async function generateKlingVideo(req, ctx) {
|
|
4469
|
-
const firstFrame = req.firstFrame ?
|
|
4617
|
+
const firstFrame = req.firstFrame ? refToUrl(req.firstFrame) : void 0;
|
|
4470
4618
|
if (!firstFrame) {
|
|
4471
4619
|
throw new ModelKitError({
|
|
4472
4620
|
code: "missing_input",
|
|
@@ -4485,7 +4633,7 @@ async function generateKlingVideo(req, ctx) {
|
|
|
4485
4633
|
if (req.durationSeconds !== void 0) body.duration = req.durationSeconds;
|
|
4486
4634
|
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive")
|
|
4487
4635
|
body.aspect_ratio = req.aspectRatio;
|
|
4488
|
-
if (req.lastFrame) body.last_image_url =
|
|
4636
|
+
if (req.lastFrame) body.last_image_url = refToUrl(req.lastFrame);
|
|
4489
4637
|
const endpoint = klingEndpoint(ctx.model.providerModelId);
|
|
4490
4638
|
const retryOptions = {};
|
|
4491
4639
|
if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
|
|
@@ -4511,9 +4659,9 @@ async function generateKlingVideo(req, ctx) {
|
|
|
4511
4659
|
} catch {
|
|
4512
4660
|
return void 0;
|
|
4513
4661
|
}
|
|
4514
|
-
if (res.status >= 500) return void 0;
|
|
4662
|
+
if (res.status === 429 || res.status >= 500) return void 0;
|
|
4515
4663
|
if (!res.ok) {
|
|
4516
|
-
throw classifyHttpError(res.status, await
|
|
4664
|
+
throw classifyHttpError(res.status, await readBody(res), "higgsfield", ctx.model.id);
|
|
4517
4665
|
}
|
|
4518
4666
|
const payload = JsonValueSchema.parse(await res.json());
|
|
4519
4667
|
const parsed = klingStatusSchema.safeParse(payload);
|
|
@@ -4620,7 +4768,7 @@ function dopUrl(body) {
|
|
|
4620
4768
|
var dopCreateSchema = import_zod10.z.object({ id: import_zod10.z.string() });
|
|
4621
4769
|
var dopStatusSchema = import_zod10.z.object({ status: import_zod10.z.string().optional() });
|
|
4622
4770
|
async function generateDopVideo(req, ctx) {
|
|
4623
|
-
const firstFrame = req.firstFrame ?
|
|
4771
|
+
const firstFrame = req.firstFrame ? refToUrl(req.firstFrame) : void 0;
|
|
4624
4772
|
if (!firstFrame) {
|
|
4625
4773
|
throw new ModelKitError({
|
|
4626
4774
|
code: "missing_input",
|
|
@@ -4640,7 +4788,7 @@ async function generateDopVideo(req, ctx) {
|
|
|
4640
4788
|
webhook: null
|
|
4641
4789
|
};
|
|
4642
4790
|
if (req.lastFrame) {
|
|
4643
|
-
params.input_images_end = [{ type: "image_url", image_url:
|
|
4791
|
+
params.input_images_end = [{ type: "image_url", image_url: refToUrl(req.lastFrame) }];
|
|
4644
4792
|
}
|
|
4645
4793
|
if (req.seed !== void 0) params.seed = req.seed;
|
|
4646
4794
|
const retryOptions = {};
|
|
@@ -4730,7 +4878,10 @@ async function generateDopVideo(req, ctx) {
|
|
|
4730
4878
|
}
|
|
4731
4879
|
var higgsfieldAdapter = {
|
|
4732
4880
|
id: "higgsfield",
|
|
4733
|
-
generateVideo: (req, ctx) =>
|
|
4881
|
+
generateVideo: (req, ctx) => {
|
|
4882
|
+
throwIfAborted(ctx.signal);
|
|
4883
|
+
return higgsfieldVideoKind(ctx.model.providerModelId) === "dop" ? generateDopVideo(req, ctx) : generateKlingVideo(req, ctx);
|
|
4884
|
+
}
|
|
4734
4885
|
};
|
|
4735
4886
|
|
|
4736
4887
|
// src/adapters/openai-image.ts
|
|
@@ -4825,6 +4976,7 @@ var openaiUsageSchema = import_zod11.z.object({
|
|
|
4825
4976
|
var openaiImageAdapter = {
|
|
4826
4977
|
id: "openai-image",
|
|
4827
4978
|
async generateImage(req, ctx) {
|
|
4979
|
+
throwIfAborted(ctx.signal);
|
|
4828
4980
|
const apiKey = ctx.keys.openai;
|
|
4829
4981
|
if (!apiKey)
|
|
4830
4982
|
throw new ModelKitError({
|
|
@@ -4834,6 +4986,13 @@ var openaiImageAdapter = {
|
|
|
4834
4986
|
model: ctx.model.id,
|
|
4835
4987
|
retryable: false
|
|
4836
4988
|
});
|
|
4989
|
+
if ((req.references ?? []).some((ref) => ref.label !== void 0)) {
|
|
4990
|
+
ctx.warnings.push({
|
|
4991
|
+
code: "option_ignored",
|
|
4992
|
+
field: "references.label",
|
|
4993
|
+
message: "openai-image cannot express reference labels; ignoring them"
|
|
4994
|
+
});
|
|
4995
|
+
}
|
|
4837
4996
|
const client2 = new import_openai2.default({ apiKey, fetch: ctx.fetch, maxRetries: 0 });
|
|
4838
4997
|
const size = req.exactSize !== void 0 ? req.exactSize : req.aspectRatio === void 0 || req.aspectRatio === "adaptive" ? void 0 : aspectRatioToSize(req.aspectRatio, req.size ?? "1K");
|
|
4839
4998
|
const refs = req.references ?? [];
|
|
@@ -4847,24 +5006,34 @@ var openaiImageAdapter = {
|
|
|
4847
5006
|
try {
|
|
4848
5007
|
if (!isEdit) {
|
|
4849
5008
|
if (size !== void 0) {
|
|
4850
|
-
return await client2.images.generate(
|
|
5009
|
+
return await client2.images.generate(
|
|
5010
|
+
{
|
|
5011
|
+
model: ctx.model.providerModelId,
|
|
5012
|
+
prompt: req.prompt,
|
|
5013
|
+
size,
|
|
5014
|
+
quality: sdkQuality,
|
|
5015
|
+
...count
|
|
5016
|
+
},
|
|
5017
|
+
{ signal: ctx.signal }
|
|
5018
|
+
);
|
|
5019
|
+
}
|
|
5020
|
+
return await client2.images.generate(
|
|
5021
|
+
{
|
|
4851
5022
|
model: ctx.model.providerModelId,
|
|
4852
5023
|
prompt: req.prompt,
|
|
4853
|
-
size,
|
|
4854
5024
|
quality: sdkQuality,
|
|
4855
5025
|
...count
|
|
4856
|
-
}
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
model: ctx.model.providerModelId,
|
|
4860
|
-
prompt: req.prompt,
|
|
4861
|
-
quality: sdkQuality,
|
|
4862
|
-
...count
|
|
4863
|
-
});
|
|
5026
|
+
},
|
|
5027
|
+
{ signal: ctx.signal }
|
|
5028
|
+
);
|
|
4864
5029
|
}
|
|
4865
5030
|
const files = await Promise.all(
|
|
4866
5031
|
refs.slice(0, MAX_EDIT_REFERENCES).map(async (ref, i) => {
|
|
4867
|
-
const { bytes, mime } = await mediaRefToBytes(ref, ctx.fetch
|
|
5032
|
+
const { bytes, mime } = await mediaRefToBytes(ref, ctx.fetch, {
|
|
5033
|
+
signal: ctx.signal,
|
|
5034
|
+
provider: "openai-image",
|
|
5035
|
+
model: ctx.model.id
|
|
5036
|
+
});
|
|
4868
5037
|
const ext = mime.includes("jpeg") ? "jpg" : mime.includes("webp") ? "webp" : "png";
|
|
4869
5038
|
return new File([bytes], `ref-${i}.${ext}`, { type: mime });
|
|
4870
5039
|
})
|
|
@@ -4872,22 +5041,28 @@ var openaiImageAdapter = {
|
|
|
4872
5041
|
const single = files.length === 1 ? files[0] : void 0;
|
|
4873
5042
|
const imageInput = single ?? files;
|
|
4874
5043
|
if (size !== void 0) {
|
|
4875
|
-
return await client2.images.edit(
|
|
5044
|
+
return await client2.images.edit(
|
|
5045
|
+
{
|
|
5046
|
+
model: ctx.model.providerModelId,
|
|
5047
|
+
image: imageInput,
|
|
5048
|
+
prompt: req.prompt,
|
|
5049
|
+
size,
|
|
5050
|
+
quality: sdkQuality,
|
|
5051
|
+
...count
|
|
5052
|
+
},
|
|
5053
|
+
{ signal: ctx.signal }
|
|
5054
|
+
);
|
|
5055
|
+
}
|
|
5056
|
+
return await client2.images.edit(
|
|
5057
|
+
{
|
|
4876
5058
|
model: ctx.model.providerModelId,
|
|
4877
5059
|
image: imageInput,
|
|
4878
5060
|
prompt: req.prompt,
|
|
4879
|
-
size,
|
|
4880
5061
|
quality: sdkQuality,
|
|
4881
5062
|
...count
|
|
4882
|
-
}
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
model: ctx.model.providerModelId,
|
|
4886
|
-
image: imageInput,
|
|
4887
|
-
prompt: req.prompt,
|
|
4888
|
-
quality: sdkQuality,
|
|
4889
|
-
...count
|
|
4890
|
-
});
|
|
5063
|
+
},
|
|
5064
|
+
{ signal: ctx.signal }
|
|
5065
|
+
);
|
|
4891
5066
|
} catch (cause) {
|
|
4892
5067
|
throw toProviderError2(cause, ctx);
|
|
4893
5068
|
}
|
|
@@ -4969,7 +5144,7 @@ async function refToBytes(ctx, ref) {
|
|
|
4969
5144
|
if ("bytes" in ref) return { bytes: ref.bytes, mime: ref.mime };
|
|
4970
5145
|
let res;
|
|
4971
5146
|
try {
|
|
4972
|
-
res = await ctx.fetch(ref.url);
|
|
5147
|
+
res = await ctx.fetch(ref.url, ctx.signal ? { signal: ctx.signal } : {});
|
|
4973
5148
|
} catch (cause) {
|
|
4974
5149
|
throw classifyThrown("prodia", cause, ctx.model.id);
|
|
4975
5150
|
}
|
|
@@ -5015,6 +5190,12 @@ function emptyImage() {
|
|
|
5015
5190
|
retryable: false
|
|
5016
5191
|
});
|
|
5017
5192
|
}
|
|
5193
|
+
function inputExtension(mime) {
|
|
5194
|
+
if (mime.includes("jpeg") || mime.includes("jpg")) return "jpg";
|
|
5195
|
+
if (mime.includes("webp")) return "webp";
|
|
5196
|
+
if (mime.includes("gif")) return "gif";
|
|
5197
|
+
return "png";
|
|
5198
|
+
}
|
|
5018
5199
|
function isBgRemove(providerModelId) {
|
|
5019
5200
|
const id = providerModelId.toLowerCase();
|
|
5020
5201
|
return id.includes("remove-background") || id.includes("bg-remove");
|
|
@@ -5023,6 +5204,7 @@ function isKlein(providerModelId) {
|
|
|
5023
5204
|
return providerModelId.toLowerCase().includes("klein");
|
|
5024
5205
|
}
|
|
5025
5206
|
async function generateProdiaImage(req, ctx) {
|
|
5207
|
+
throwIfAborted(ctx.signal);
|
|
5026
5208
|
const key = ctx.keys.prodia;
|
|
5027
5209
|
if (!key) {
|
|
5028
5210
|
throw new ModelKitError({
|
|
@@ -5121,7 +5303,9 @@ async function generateProdiaImage(req, ctx) {
|
|
|
5121
5303
|
"input",
|
|
5122
5304
|
// Uint8Array<ArrayBufferLike> is not a valid BlobPart under the
|
|
5123
5305
|
// strict lib types; copy into a fresh ArrayBuffer-backed view.
|
|
5124
|
-
new File([new Uint8Array(input.bytes)], `input-${i}.
|
|
5306
|
+
new File([new Uint8Array(input.bytes)], `input-${i}.${inputExtension(input.mime)}`, {
|
|
5307
|
+
type: input.mime
|
|
5308
|
+
})
|
|
5125
5309
|
);
|
|
5126
5310
|
});
|
|
5127
5311
|
const retryOpts = {
|
|
@@ -5136,11 +5320,13 @@ async function generateProdiaImage(req, ctx) {
|
|
|
5136
5320
|
res = await withRetry(async () => {
|
|
5137
5321
|
let attemptRes;
|
|
5138
5322
|
try {
|
|
5139
|
-
|
|
5323
|
+
const init = {
|
|
5140
5324
|
method: "POST",
|
|
5141
5325
|
headers: { Authorization: `Bearer ${key}`, Accept: accept },
|
|
5142
5326
|
body: form
|
|
5143
|
-
}
|
|
5327
|
+
};
|
|
5328
|
+
if (ctx.signal !== void 0) init.signal = ctx.signal;
|
|
5329
|
+
attemptRes = await ctx.fetch(PRODIA_JOB_URL, init);
|
|
5144
5330
|
} catch (err) {
|
|
5145
5331
|
throw classifyThrown("prodia", err, ctx.model.id);
|
|
5146
5332
|
}
|
|
@@ -5201,11 +5387,7 @@ function client(ctx, deps) {
|
|
|
5201
5387
|
retryable: false
|
|
5202
5388
|
});
|
|
5203
5389
|
}
|
|
5204
|
-
return deps.createReplicateClient({ auth: token });
|
|
5205
|
-
}
|
|
5206
|
-
function refToUrl3(ref) {
|
|
5207
|
-
if ("url" in ref) return ref.url;
|
|
5208
|
-
return `data:${ref.mime};base64,${Buffer.from(ref.bytes).toString("base64")}`;
|
|
5390
|
+
return deps.createReplicateClient({ auth: token, fetch: ctx.fetch });
|
|
5209
5391
|
}
|
|
5210
5392
|
function route(providerModelId) {
|
|
5211
5393
|
if (providerModelId.includes(":")) {
|
|
@@ -5225,8 +5407,9 @@ function replicateError(cause, ctx) {
|
|
|
5225
5407
|
const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
|
|
5226
5408
|
return classifyThrown("replicate", cause, ctx.model.id, { status, body: info.body });
|
|
5227
5409
|
}
|
|
5228
|
-
function
|
|
5229
|
-
|
|
5410
|
+
function baseModelId(providerModelId) {
|
|
5411
|
+
const colon = providerModelId.indexOf(":");
|
|
5412
|
+
return colon === -1 ? providerModelId : providerModelId.slice(0, colon);
|
|
5230
5413
|
}
|
|
5231
5414
|
function predictionErrorBody(cause) {
|
|
5232
5415
|
const parsed = JsonValueSchema.safeParse(cause);
|
|
@@ -5274,6 +5457,7 @@ function noOutput() {
|
|
|
5274
5457
|
});
|
|
5275
5458
|
}
|
|
5276
5459
|
async function runPrediction(ctx, input, deps) {
|
|
5460
|
+
throwIfAborted(ctx.signal);
|
|
5277
5461
|
const api = client(ctx, deps);
|
|
5278
5462
|
const createOptions = { ...route(ctx.model.providerModelId), input };
|
|
5279
5463
|
let prediction;
|
|
@@ -5281,12 +5465,14 @@ async function runPrediction(ctx, input, deps) {
|
|
|
5281
5465
|
prediction = await withRetry(
|
|
5282
5466
|
async () => {
|
|
5283
5467
|
try {
|
|
5284
|
-
return await api.predictions.create(
|
|
5468
|
+
return await api.predictions.create(
|
|
5469
|
+
ctx.signal ? { ...createOptions, signal: ctx.signal } : createOptions
|
|
5470
|
+
);
|
|
5285
5471
|
} catch (cause) {
|
|
5286
5472
|
throw replicateError(cause, ctx);
|
|
5287
5473
|
}
|
|
5288
5474
|
},
|
|
5289
|
-
|
|
5475
|
+
{ attempts: 1 }
|
|
5290
5476
|
);
|
|
5291
5477
|
} catch (cause) {
|
|
5292
5478
|
throw replicateError(cause, ctx);
|
|
@@ -5299,7 +5485,10 @@ async function runPrediction(ctx, input, deps) {
|
|
|
5299
5485
|
const done = await pollUntil(async () => {
|
|
5300
5486
|
let current;
|
|
5301
5487
|
try {
|
|
5302
|
-
current = await api.predictions.get(
|
|
5488
|
+
current = await api.predictions.get(
|
|
5489
|
+
prediction.id,
|
|
5490
|
+
ctx.signal ? { signal: ctx.signal } : void 0
|
|
5491
|
+
);
|
|
5303
5492
|
} catch (cause) {
|
|
5304
5493
|
throw replicateError(cause, ctx);
|
|
5305
5494
|
}
|
|
@@ -5366,21 +5555,32 @@ async function download(ctx, url) {
|
|
|
5366
5555
|
const mime = res.headers.get("content-type") ?? "image/png";
|
|
5367
5556
|
return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
|
|
5368
5557
|
}
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
}
|
|
5376
|
-
function
|
|
5377
|
-
return
|
|
5378
|
-
}
|
|
5379
|
-
|
|
5380
|
-
|
|
5558
|
+
var REPLICATE_IMAGE_KINDS = {
|
|
5559
|
+
"topazlabs/image-upscale": "topaz",
|
|
5560
|
+
"philz1337x/crystal-upscaler": "upscaler",
|
|
5561
|
+
"wan-video/wan-2.7-image-pro": "wan",
|
|
5562
|
+
"qwen/qwen-image-2-pro": "qwen-image",
|
|
5563
|
+
"qwen-edit-apps/qwen-image-edit-plus-lora-skin": "qwen-edit"
|
|
5564
|
+
};
|
|
5565
|
+
function imageKind(providerModelId) {
|
|
5566
|
+
return REPLICATE_IMAGE_KINDS[baseModelId(providerModelId)] ?? "generic";
|
|
5567
|
+
}
|
|
5568
|
+
var REPLICATE_VIDEO_KINDS = {
|
|
5569
|
+
"kling-video/v2.5-turbo/pro/image-to-video": "kling",
|
|
5570
|
+
"kling-video/v3.0/pro/image-to-video": "kling",
|
|
5571
|
+
"kwaivgi/kling-v3-video": "kling",
|
|
5572
|
+
"kwaivgi/kling-v3-omni-video": "kling-omni",
|
|
5573
|
+
"minimax/hailuo-02": "hailuo"
|
|
5574
|
+
};
|
|
5575
|
+
function videoKind(providerModelId) {
|
|
5576
|
+
return REPLICATE_VIDEO_KINDS[baseModelId(providerModelId)] ?? "wan";
|
|
5381
5577
|
}
|
|
5382
|
-
|
|
5383
|
-
|
|
5578
|
+
var REPLICATE_AUDIO_KINDS = {
|
|
5579
|
+
"zsxkib/mmaudio": "mmaudio",
|
|
5580
|
+
"elevenlabs/music": "elevenlabs"
|
|
5581
|
+
};
|
|
5582
|
+
function audioKind(providerModelId) {
|
|
5583
|
+
return REPLICATE_AUDIO_KINDS[baseModelId(providerModelId)] ?? "lyria";
|
|
5384
5584
|
}
|
|
5385
5585
|
var QWEN_IMAGE_RATIOS = /* @__PURE__ */ new Set([
|
|
5386
5586
|
"1:1",
|
|
@@ -5423,87 +5623,113 @@ function wanImageSize(aspectRatio, size) {
|
|
|
5423
5623
|
async function generateReplicateImage(req, ctx, deps) {
|
|
5424
5624
|
const id = ctx.model.providerModelId;
|
|
5425
5625
|
let input;
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5626
|
+
switch (imageKind(id)) {
|
|
5627
|
+
case "topaz": {
|
|
5628
|
+
const first = (req.references ?? [])[0];
|
|
5629
|
+
if (!first) {
|
|
5630
|
+
throw new ModelKitError({
|
|
5631
|
+
code: "missing_input",
|
|
5632
|
+
message: `${ctx.model.id} requires a reference image to upscale`,
|
|
5633
|
+
provider: "replicate",
|
|
5634
|
+
model: ctx.model.id,
|
|
5635
|
+
retryable: false
|
|
5636
|
+
});
|
|
5637
|
+
}
|
|
5638
|
+
let format = req.outputFormat === "jpeg" ? "jpg" : req.outputFormat ?? "png";
|
|
5639
|
+
if (format !== "png" && format !== "jpg") {
|
|
5640
|
+
ctx.warnings.push({
|
|
5641
|
+
code: "option_ignored",
|
|
5642
|
+
field: "outputFormat",
|
|
5643
|
+
from: format,
|
|
5644
|
+
message: "topazlabs/image-upscale supports only png and jpg; using png"
|
|
5645
|
+
});
|
|
5646
|
+
format = "png";
|
|
5647
|
+
}
|
|
5648
|
+
const upscale = req.upscale;
|
|
5649
|
+
const topaz = {
|
|
5650
|
+
image: refToUrl(first),
|
|
5651
|
+
enhance_model: upscale?.enhanceModel ?? "Standard V2",
|
|
5652
|
+
output_format: format,
|
|
5653
|
+
upscale_factor: `${req.scaleFactor ?? 2}x`,
|
|
5654
|
+
face_enhancement: upscale?.faceEnhancement ?? false
|
|
5655
|
+
};
|
|
5656
|
+
if (upscale?.subjectDetection !== void 0)
|
|
5657
|
+
topaz.subject_detection = upscale.subjectDetection;
|
|
5658
|
+
if (upscale?.faceEnhancementCreativity !== void 0)
|
|
5659
|
+
topaz.face_enhancement_creativity = upscale.faceEnhancementCreativity;
|
|
5660
|
+
if (upscale?.faceEnhancementStrength !== void 0)
|
|
5661
|
+
topaz.face_enhancement_strength = upscale.faceEnhancementStrength;
|
|
5662
|
+
input = topaz;
|
|
5663
|
+
break;
|
|
5436
5664
|
}
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5665
|
+
case "upscaler": {
|
|
5666
|
+
const first = (req.references ?? [])[0];
|
|
5667
|
+
if (!first) {
|
|
5668
|
+
throw new ModelKitError({
|
|
5669
|
+
code: "missing_input",
|
|
5670
|
+
message: `${ctx.model.id} requires a reference image to upscale`,
|
|
5671
|
+
provider: "replicate",
|
|
5672
|
+
model: ctx.model.id,
|
|
5673
|
+
retryable: false
|
|
5674
|
+
});
|
|
5675
|
+
}
|
|
5676
|
+
const imageInput = { prompt: req.prompt };
|
|
5677
|
+
imageInput.image = refToUrl(first);
|
|
5678
|
+
imageInput.creativity = 0;
|
|
5679
|
+
imageInput.scale_factor = 2;
|
|
5680
|
+
imageInput.output_format = "png";
|
|
5681
|
+
input = imageInput;
|
|
5682
|
+
break;
|
|
5446
5683
|
}
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
} else if (isUpscaler(id)) {
|
|
5455
|
-
const refs = req.references ?? [];
|
|
5456
|
-
const first = refs[0];
|
|
5457
|
-
if (!first) {
|
|
5458
|
-
throw new ModelKitError({
|
|
5459
|
-
code: "missing_input",
|
|
5460
|
-
message: `${ctx.model.id} requires a reference image to upscale`,
|
|
5461
|
-
provider: "replicate",
|
|
5462
|
-
model: ctx.model.id,
|
|
5463
|
-
retryable: false
|
|
5464
|
-
});
|
|
5684
|
+
case "wan": {
|
|
5685
|
+
const refs = (req.references ?? []).map(refToUrl);
|
|
5686
|
+
const imageInput = { prompt: req.prompt };
|
|
5687
|
+
if (refs.length > 0) imageInput.images = refs;
|
|
5688
|
+
imageInput.size = wanImageSize(req.aspectRatio, req.size);
|
|
5689
|
+
input = imageInput;
|
|
5690
|
+
break;
|
|
5465
5691
|
}
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
} else if (isQwen(id)) {
|
|
5479
|
-
const refs = (req.references ?? []).map(refToUrl3);
|
|
5480
|
-
const firstUrl = refs[0];
|
|
5481
|
-
const imageInput = { prompt: req.prompt };
|
|
5482
|
-
if (firstUrl !== void 0) {
|
|
5483
|
-
imageInput.image = firstUrl;
|
|
5484
|
-
if (!isQwenEditPlus(id)) imageInput.match_input_image = true;
|
|
5692
|
+
case "qwen-image": {
|
|
5693
|
+
const refs = (req.references ?? []).map(refToUrl);
|
|
5694
|
+
const firstUrl = refs[0];
|
|
5695
|
+
const imageInput = { prompt: req.prompt };
|
|
5696
|
+
if (firstUrl !== void 0) {
|
|
5697
|
+
imageInput.image = firstUrl;
|
|
5698
|
+
imageInput.match_input_image = true;
|
|
5699
|
+
} else if (req.aspectRatio !== void 0 && QWEN_IMAGE_RATIOS.has(req.aspectRatio)) {
|
|
5700
|
+
imageInput.aspect_ratio = req.aspectRatio;
|
|
5701
|
+
}
|
|
5702
|
+
input = imageInput;
|
|
5703
|
+
break;
|
|
5485
5704
|
}
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5705
|
+
case "qwen-edit": {
|
|
5706
|
+
const refs = (req.references ?? []).map(refToUrl);
|
|
5707
|
+
const firstUrl = refs[0];
|
|
5708
|
+
const imageInput = { prompt: req.prompt };
|
|
5709
|
+
if (firstUrl !== void 0) imageInput.image = firstUrl;
|
|
5710
|
+
if (req.aspectRatio !== void 0) {
|
|
5711
|
+
if (QWEN_EDIT_RATIOS.has(req.aspectRatio))
|
|
5712
|
+
imageInput.aspect_ratio = req.aspectRatio;
|
|
5713
|
+
else
|
|
5714
|
+
ctx.warnings.push({
|
|
5715
|
+
code: "option_ignored",
|
|
5716
|
+
field: "aspectRatio",
|
|
5717
|
+
from: req.aspectRatio,
|
|
5718
|
+
message: `${id} has no ${req.aspectRatio} aspect_ratio; using the provider default`
|
|
5719
|
+
});
|
|
5720
|
+
}
|
|
5721
|
+
if (req.outputFormat !== void 0) {
|
|
5722
|
+
imageInput.output_format = req.outputFormat === "jpeg" ? "jpg" : req.outputFormat;
|
|
5723
|
+
}
|
|
5724
|
+
input = imageInput;
|
|
5725
|
+
break;
|
|
5496
5726
|
}
|
|
5497
|
-
|
|
5498
|
-
|
|
5727
|
+
default: {
|
|
5728
|
+
const first = (req.references ?? [])[0];
|
|
5729
|
+
const imageInput = { prompt: req.prompt };
|
|
5730
|
+
if (first) imageInput.image = refToUrl(first);
|
|
5731
|
+
input = imageInput;
|
|
5499
5732
|
}
|
|
5500
|
-
input = imageInput;
|
|
5501
|
-
} else {
|
|
5502
|
-
const refs = req.references ?? [];
|
|
5503
|
-
const first = refs[0];
|
|
5504
|
-
const imageInput = { prompt: req.prompt };
|
|
5505
|
-
if (first) imageInput.image = refToUrl3(first);
|
|
5506
|
-
input = imageInput;
|
|
5507
5733
|
}
|
|
5508
5734
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|
|
5509
5735
|
const file = await download(ctx, url);
|
|
@@ -5520,8 +5746,8 @@ function wanSize(aspectRatio) {
|
|
|
5520
5746
|
return w > h ? "2048*1152" : "1536*2048";
|
|
5521
5747
|
}
|
|
5522
5748
|
function klingInput(req) {
|
|
5523
|
-
const images = (req.firstFrame ? [req.firstFrame] : []).map(
|
|
5524
|
-
if (req.lastFrame) images.push(
|
|
5749
|
+
const images = (req.firstFrame ? [req.firstFrame] : []).map(refToUrl);
|
|
5750
|
+
if (req.lastFrame) images.push(refToUrl(req.lastFrame));
|
|
5525
5751
|
const input = {
|
|
5526
5752
|
prompt: req.prompt,
|
|
5527
5753
|
duration: req.durationSeconds ?? 10,
|
|
@@ -5539,13 +5765,18 @@ function klingInput(req) {
|
|
|
5539
5765
|
if (req.negativePrompt !== void 0) input.negative_prompt = req.negativePrompt;
|
|
5540
5766
|
return input;
|
|
5541
5767
|
}
|
|
5768
|
+
function klingOmniMode(req) {
|
|
5769
|
+
if (req.resolution === "1080p") return "pro";
|
|
5770
|
+
if (req.resolution === "720p") return "standard";
|
|
5771
|
+
return req.mode ?? "standard";
|
|
5772
|
+
}
|
|
5542
5773
|
function klingOmniInput(req) {
|
|
5543
|
-
const images = (req.firstFrame ? [req.firstFrame] : []).map(
|
|
5544
|
-
if (req.lastFrame) images.push(
|
|
5774
|
+
const images = (req.firstFrame ? [req.firstFrame] : []).map(refToUrl);
|
|
5775
|
+
if (req.lastFrame) images.push(refToUrl(req.lastFrame));
|
|
5545
5776
|
const input = {
|
|
5546
5777
|
prompt: req.prompt,
|
|
5547
5778
|
duration: req.durationSeconds ?? 10,
|
|
5548
|
-
mode: req
|
|
5779
|
+
mode: klingOmniMode(req),
|
|
5549
5780
|
generate_audio: req.generateAudio ?? false
|
|
5550
5781
|
};
|
|
5551
5782
|
const startImage = images[0];
|
|
@@ -5556,7 +5787,7 @@ function klingOmniInput(req) {
|
|
|
5556
5787
|
} else if (req.aspectRatio !== "adaptive") {
|
|
5557
5788
|
input.aspect_ratio = req.aspectRatio ?? "16:9";
|
|
5558
5789
|
}
|
|
5559
|
-
const refs = (req.referenceImages ?? []).map(
|
|
5790
|
+
const refs = (req.referenceImages ?? []).map(refToUrl);
|
|
5560
5791
|
if (refs.length > 0) input.reference_images = refs;
|
|
5561
5792
|
return input;
|
|
5562
5793
|
}
|
|
@@ -5567,8 +5798,8 @@ function hailuoInput(req) {
|
|
|
5567
5798
|
resolution: req.resolution ?? "768p",
|
|
5568
5799
|
prompt_optimizer: true
|
|
5569
5800
|
};
|
|
5570
|
-
if (req.firstFrame) input.first_frame_image =
|
|
5571
|
-
if (req.lastFrame) input.last_frame_image =
|
|
5801
|
+
if (req.firstFrame) input.first_frame_image = refToUrl(req.firstFrame);
|
|
5802
|
+
if (req.lastFrame) input.last_frame_image = refToUrl(req.lastFrame);
|
|
5572
5803
|
return input;
|
|
5573
5804
|
}
|
|
5574
5805
|
function wanInput(req) {
|
|
@@ -5577,12 +5808,13 @@ function wanInput(req) {
|
|
|
5577
5808
|
duration: req.durationSeconds ?? 5,
|
|
5578
5809
|
size: wanSize(req.aspectRatio)
|
|
5579
5810
|
};
|
|
5580
|
-
if (req.firstFrame) input.image =
|
|
5811
|
+
if (req.firstFrame) input.image = refToUrl(req.firstFrame);
|
|
5581
5812
|
return input;
|
|
5582
5813
|
}
|
|
5583
5814
|
async function generateReplicateVideo(req, ctx, deps) {
|
|
5584
|
-
|
|
5585
|
-
const
|
|
5815
|
+
throwIfAborted(ctx.signal);
|
|
5816
|
+
const kind = videoKind(ctx.model.providerModelId);
|
|
5817
|
+
const input = kind === "kling" ? klingInput(req) : kind === "kling-omni" ? klingOmniInput(req) : kind === "hailuo" ? hailuoInput(req) : wanInput(req);
|
|
5586
5818
|
const api = client(ctx, deps);
|
|
5587
5819
|
const createOptions = { ...route(ctx.model.providerModelId), input };
|
|
5588
5820
|
let prediction;
|
|
@@ -5590,12 +5822,14 @@ async function generateReplicateVideo(req, ctx, deps) {
|
|
|
5590
5822
|
prediction = await withRetry(
|
|
5591
5823
|
async () => {
|
|
5592
5824
|
try {
|
|
5593
|
-
return await api.predictions.create(
|
|
5825
|
+
return await api.predictions.create(
|
|
5826
|
+
ctx.signal ? { ...createOptions, signal: ctx.signal } : createOptions
|
|
5827
|
+
);
|
|
5594
5828
|
} catch (cause) {
|
|
5595
5829
|
throw replicateError(cause, ctx);
|
|
5596
5830
|
}
|
|
5597
5831
|
},
|
|
5598
|
-
|
|
5832
|
+
{ attempts: 1 }
|
|
5599
5833
|
);
|
|
5600
5834
|
} catch (cause) {
|
|
5601
5835
|
throw replicateError(cause, ctx);
|
|
@@ -5604,7 +5838,10 @@ async function generateReplicateVideo(req, ctx, deps) {
|
|
|
5604
5838
|
const check = async () => {
|
|
5605
5839
|
let current;
|
|
5606
5840
|
try {
|
|
5607
|
-
current = await api.predictions.get(
|
|
5841
|
+
current = await api.predictions.get(
|
|
5842
|
+
jobId,
|
|
5843
|
+
ctx.signal ? { signal: ctx.signal } : void 0
|
|
5844
|
+
);
|
|
5608
5845
|
} catch (cause) {
|
|
5609
5846
|
throw replicateError(cause, ctx);
|
|
5610
5847
|
}
|
|
@@ -5705,7 +5942,7 @@ function mmaudioInput(req, ctx) {
|
|
|
5705
5942
|
});
|
|
5706
5943
|
}
|
|
5707
5944
|
const input = {
|
|
5708
|
-
video:
|
|
5945
|
+
video: refToUrl(video),
|
|
5709
5946
|
duration: req.durationSeconds ?? 8,
|
|
5710
5947
|
seed: req.seed ?? -1
|
|
5711
5948
|
};
|
|
@@ -5724,8 +5961,8 @@ function predictionRaw(prediction) {
|
|
|
5724
5961
|
return raw;
|
|
5725
5962
|
}
|
|
5726
5963
|
async function generateReplicateAudio(req, ctx, deps) {
|
|
5727
|
-
const
|
|
5728
|
-
const input =
|
|
5964
|
+
const kind = audioKind(ctx.model.providerModelId);
|
|
5965
|
+
const input = kind === "mmaudio" ? mmaudioInput(req, ctx) : kind === "elevenlabs" ? elevenLabsMusicInput(req, ctx) : lyriaAudioInput(req, ctx);
|
|
5729
5966
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|
|
5730
5967
|
const usage2 = audioUsage(ctx, req);
|
|
5731
5968
|
if (ctx.model.usage.unit === "seconds") {
|
|
@@ -5754,10 +5991,6 @@ function createXaiVideoAdapter(deps = defaultXaiDeps) {
|
|
|
5754
5991
|
};
|
|
5755
5992
|
}
|
|
5756
5993
|
var xaiVideoAdapter = createXaiVideoAdapter();
|
|
5757
|
-
function refToUrl4(ref) {
|
|
5758
|
-
if ("url" in ref) return ref.url;
|
|
5759
|
-
return `data:${ref.mime};base64,${Buffer.from(ref.bytes).toString("base64")}`;
|
|
5760
|
-
}
|
|
5761
5994
|
var xaiResponseStatusSchema = import_zod13.z.object({
|
|
5762
5995
|
response: import_zod13.z.object({ status: import_zod13.z.number() }).partial()
|
|
5763
5996
|
});
|
|
@@ -5789,13 +6022,14 @@ async function generateXaiVideo(req, ctx, deps) {
|
|
|
5789
6022
|
retryable: false
|
|
5790
6023
|
});
|
|
5791
6024
|
}
|
|
5792
|
-
const refUrls = (req.referenceImages ?? []).map(
|
|
5793
|
-
const resolution = req.resolution === "480p" ? "480p" : "720p";
|
|
6025
|
+
const refUrls = (req.referenceImages ?? []).map(refToUrl).slice(0, 7);
|
|
5794
6026
|
const xaiOptions = {
|
|
5795
|
-
resolution,
|
|
5796
6027
|
pollIntervalMs: POLL_INTERVAL_MS2,
|
|
5797
6028
|
pollTimeoutMs: POLL_TIMEOUT_MS2
|
|
5798
6029
|
};
|
|
6030
|
+
if (req.resolution === "480p" || req.resolution === "720p" || req.resolution === "1080p") {
|
|
6031
|
+
xaiOptions.resolution = req.resolution;
|
|
6032
|
+
}
|
|
5799
6033
|
if (refUrls.length > 0) {
|
|
5800
6034
|
xaiOptions.mode = "reference-to-video";
|
|
5801
6035
|
xaiOptions.referenceImageUrls = refUrls;
|
|
@@ -5815,7 +6049,7 @@ async function generateXaiVideo(req, ctx, deps) {
|
|
|
5815
6049
|
providerOptions: { xai: xaiOptions }
|
|
5816
6050
|
};
|
|
5817
6051
|
if (req.firstFrame) {
|
|
5818
|
-
callBody.frameImages = [{ image:
|
|
6052
|
+
callBody.frameImages = [{ image: refToUrl(req.firstFrame), frameType: "first_frame" }];
|
|
5819
6053
|
}
|
|
5820
6054
|
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
5821
6055
|
callBody.aspectRatio = req.aspectRatio;
|
|
@@ -5851,7 +6085,8 @@ async function generateXaiVideo(req, ctx, deps) {
|
|
|
5851
6085
|
return settled;
|
|
5852
6086
|
};
|
|
5853
6087
|
return {
|
|
5854
|
-
|
|
6088
|
+
// xAI exposes no request id on the synchronous handle, so each job gets a fresh one.
|
|
6089
|
+
jobId: crypto.randomUUID(),
|
|
5855
6090
|
async poll() {
|
|
5856
6091
|
if (failed !== void 0) return { status: "failed" };
|
|
5857
6092
|
return settled ? { status: "succeeded" } : { status: "pending" };
|
|
@@ -5986,6 +6221,7 @@ var describe = (modelId) => createDefaultModelKit().describe(modelId);
|
|
|
5986
6221
|
prodiaAdapter,
|
|
5987
6222
|
readErrorBody,
|
|
5988
6223
|
replicateAdapter,
|
|
6224
|
+
resolveAudioOptions,
|
|
5989
6225
|
resolveImageOptions,
|
|
5990
6226
|
resolveKeys,
|
|
5991
6227
|
resolveVideoOptions,
|