@shop-os/modelkit 0.1.4 → 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 +35 -12
- package/dist/index.cjs +411 -318
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +411 -318
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -93,7 +93,8 @@ var GEMINI_RATIOS = [
|
|
|
93
93
|
"3:4",
|
|
94
94
|
"21:9",
|
|
95
95
|
"4:5",
|
|
96
|
-
"5:4"
|
|
96
|
+
"5:4",
|
|
97
|
+
"adaptive"
|
|
97
98
|
];
|
|
98
99
|
function geminiImage(id, label, aliases, sizes) {
|
|
99
100
|
const model = {
|
|
@@ -104,7 +105,7 @@ function geminiImage(id, label, aliases, sizes) {
|
|
|
104
105
|
adapter: "google-image",
|
|
105
106
|
providerModelId: id,
|
|
106
107
|
lifecycle: "active",
|
|
107
|
-
constraints: { aspectRatios: [...GEMINI_RATIOS], sizes },
|
|
108
|
+
constraints: { aspectRatios: [...GEMINI_RATIOS], sizes, supports: ["safetySettings"] },
|
|
108
109
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
109
110
|
usage: { ...IMAGE_USAGE },
|
|
110
111
|
pricingKind: "image_size"
|
|
@@ -201,7 +202,8 @@ var IMAGE_MODELS = [
|
|
|
201
202
|
"9:16",
|
|
202
203
|
"4:5",
|
|
203
204
|
"5:4",
|
|
204
|
-
"9:21"
|
|
205
|
+
"9:21",
|
|
206
|
+
"adaptive"
|
|
205
207
|
],
|
|
206
208
|
sizes: ["1K"],
|
|
207
209
|
references: { images: 10 },
|
|
@@ -262,9 +264,10 @@ var IMAGE_MODELS = [
|
|
|
262
264
|
constraints: {
|
|
263
265
|
aspectRatios: ["1:1", "2:3", "3:2", "16:9", "9:16", "4:3", "3:4", "4:5", "5:4", "21:9"],
|
|
264
266
|
sizes: ["1K"],
|
|
265
|
-
|
|
267
|
+
// flux-2-pro's job type always returns image/png; only the seed is forwarded.
|
|
268
|
+
supports: ["seed"]
|
|
266
269
|
},
|
|
267
|
-
defaults: { size: "1K", aspectRatio: "1:1"
|
|
270
|
+
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
268
271
|
usage: { ...IMAGE_USAGE },
|
|
269
272
|
pricingKind: "image_size"
|
|
270
273
|
},
|
|
@@ -282,7 +285,8 @@ var IMAGE_MODELS = [
|
|
|
282
285
|
constraints: {
|
|
283
286
|
aspectRatios: ["1:1", "2:3", "3:2", "4:3", "3:4", "4:5", "5:4", "9:16", "16:9", "21:9"],
|
|
284
287
|
sizes: ["1K", "2K", "4K"],
|
|
285
|
-
requires: ["references"]
|
|
288
|
+
requires: ["references"],
|
|
289
|
+
supports: ["seed"]
|
|
286
290
|
},
|
|
287
291
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
288
292
|
usage: { ...IMAGE_USAGE },
|
|
@@ -301,7 +305,8 @@ var IMAGE_MODELS = [
|
|
|
301
305
|
constraints: {
|
|
302
306
|
aspectRatios: ["1:1", "2:3", "3:4", "4:3", "9:16", "16:9", "21:9"],
|
|
303
307
|
sizes: ["1K"],
|
|
304
|
-
requires: ["references"]
|
|
308
|
+
requires: ["references"],
|
|
309
|
+
supports: ["seed"]
|
|
305
310
|
},
|
|
306
311
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
307
312
|
usage: { ...IMAGE_USAGE },
|
|
@@ -321,7 +326,8 @@ var IMAGE_MODELS = [
|
|
|
321
326
|
constraints: {
|
|
322
327
|
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4"],
|
|
323
328
|
sizes: ["1K", "2K", "4K"],
|
|
324
|
-
references: { images: 9 }
|
|
329
|
+
references: { images: 9 },
|
|
330
|
+
supports: []
|
|
325
331
|
},
|
|
326
332
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
327
333
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
@@ -342,7 +348,8 @@ var IMAGE_MODELS = [
|
|
|
342
348
|
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"],
|
|
343
349
|
sizes: [],
|
|
344
350
|
references: { images: 1 },
|
|
345
|
-
requires: ["references"]
|
|
351
|
+
requires: ["references"],
|
|
352
|
+
supports: []
|
|
346
353
|
},
|
|
347
354
|
defaults: { aspectRatio: "1:1" },
|
|
348
355
|
usage: { unit: "compute_seconds", modality: "IMAGE" },
|
|
@@ -384,7 +391,8 @@ var OTHER_MODELS = [
|
|
|
384
391
|
lifecycle: "active",
|
|
385
392
|
constraints: {
|
|
386
393
|
durations: [30],
|
|
387
|
-
references: { images: 10 }
|
|
394
|
+
references: { images: 10 },
|
|
395
|
+
supports: []
|
|
388
396
|
},
|
|
389
397
|
defaults: {},
|
|
390
398
|
usage: { unit: "images", modality: "AUDIO" },
|
|
@@ -399,7 +407,8 @@ var OTHER_MODELS = [
|
|
|
399
407
|
providerModelId: "lyria-3-pro-preview",
|
|
400
408
|
lifecycle: "active",
|
|
401
409
|
constraints: {
|
|
402
|
-
references: { images: 10 }
|
|
410
|
+
references: { images: 10 },
|
|
411
|
+
supports: []
|
|
403
412
|
},
|
|
404
413
|
defaults: {},
|
|
405
414
|
usage: { unit: "images", modality: "AUDIO" },
|
|
@@ -482,7 +491,8 @@ var OTHER_MODELS = [
|
|
|
482
491
|
lifecycle: "active",
|
|
483
492
|
constraints: {
|
|
484
493
|
references: { images: 1 },
|
|
485
|
-
requires: ["references"]
|
|
494
|
+
requires: ["references"],
|
|
495
|
+
supports: []
|
|
486
496
|
},
|
|
487
497
|
defaults: {},
|
|
488
498
|
usage: { unit: "images", modality: "IMAGE" },
|
|
@@ -501,7 +511,7 @@ function text(id, label, providerModelId, extra) {
|
|
|
501
511
|
adapter: "ai-sdk-text",
|
|
502
512
|
providerModelId,
|
|
503
513
|
lifecycle: "active",
|
|
504
|
-
constraints: {},
|
|
514
|
+
constraints: { supports: [] },
|
|
505
515
|
defaults: {},
|
|
506
516
|
usage: { ...TEXT_USAGE },
|
|
507
517
|
pricingKind: "token",
|
|
@@ -574,7 +584,7 @@ var TEXT_MODELS = [
|
|
|
574
584
|
// src/catalog/video.ts
|
|
575
585
|
var VIDEO_USAGE = { unit: "seconds", modality: "VIDEO" };
|
|
576
586
|
var SEEDANCE_RATIOS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16", "adaptive"];
|
|
577
|
-
var KLING_RATIOS = ["16:9", "9:16", "1:1"];
|
|
587
|
+
var KLING_RATIOS = ["16:9", "9:16", "1:1", "adaptive"];
|
|
578
588
|
var OMNI_RATIOS = ["16:9", "9:16"];
|
|
579
589
|
var GROK_RATIOS = ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"];
|
|
580
590
|
var H3_RATIOS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16"];
|
|
@@ -666,12 +676,15 @@ var VIDEO_MODELS = [
|
|
|
666
676
|
providerModelId: "gemini-omni-flash-preview",
|
|
667
677
|
lifecycle: "active",
|
|
668
678
|
constraints: {
|
|
679
|
+
// 1.0 rejects `resolution`; it renders 720p. No defaults: the adapter
|
|
680
|
+
// sends ratio and duration only when the caller set them, so a
|
|
681
|
+
// reference clip keeps its own framing.
|
|
669
682
|
aspectRatios: [...OMNI_RATIOS],
|
|
670
|
-
resolutions: ["720p"],
|
|
671
683
|
durations: [3, 4, 5, 6, 7, 8, 9, 10],
|
|
672
|
-
references: { images: 6, videos: 1 }
|
|
684
|
+
references: { images: 6, videos: 1 },
|
|
685
|
+
supports: []
|
|
673
686
|
},
|
|
674
|
-
defaults: {
|
|
687
|
+
defaults: {},
|
|
675
688
|
usage: { ...VIDEO_USAGE },
|
|
676
689
|
pricingKind: "video_per_second"
|
|
677
690
|
},
|
|
@@ -687,9 +700,10 @@ var VIDEO_MODELS = [
|
|
|
687
700
|
aspectRatios: [...OMNI_RATIOS],
|
|
688
701
|
resolutions: ["360p", "720p", "1080p", "4k"],
|
|
689
702
|
durations: [3, 4, 5, 6, 7, 8, 9, 10],
|
|
690
|
-
references: { images: 6, videos: 1 }
|
|
703
|
+
references: { images: 6, videos: 1 },
|
|
704
|
+
supports: []
|
|
691
705
|
},
|
|
692
|
-
defaults: {
|
|
706
|
+
defaults: {},
|
|
693
707
|
usage: { ...VIDEO_USAGE },
|
|
694
708
|
pricingKind: "video_per_second"
|
|
695
709
|
},
|
|
@@ -783,7 +797,8 @@ var VIDEO_MODELS = [
|
|
|
783
797
|
aspectRatios: [...GROK_RATIOS],
|
|
784
798
|
resolutions: ["480p", "720p"],
|
|
785
799
|
durations: { min: 1, max: 15 },
|
|
786
|
-
references: { images: 7 }
|
|
800
|
+
references: { images: 7 },
|
|
801
|
+
supports: []
|
|
787
802
|
},
|
|
788
803
|
defaults: { durationSeconds: 8, resolution: "720p", aspectRatio: "16:9" },
|
|
789
804
|
usage: { unit: "reported_cost_usd", modality: "VIDEO" },
|
|
@@ -973,7 +988,8 @@ var VIDEO_MODELS = [
|
|
|
973
988
|
constraints: {
|
|
974
989
|
aspectRatios: [...KLING_RATIOS],
|
|
975
990
|
durations: { min: 3, max: 10 },
|
|
976
|
-
requires: ["sourceVideo"]
|
|
991
|
+
requires: ["sourceVideo"],
|
|
992
|
+
supports: []
|
|
977
993
|
},
|
|
978
994
|
defaults: { durationSeconds: 5, aspectRatio: "16:9" },
|
|
979
995
|
usage: { ...VIDEO_USAGE },
|
|
@@ -1006,7 +1022,7 @@ var VIDEO_MODELS = [
|
|
|
1006
1022
|
lifecycle: "active",
|
|
1007
1023
|
constraints: {
|
|
1008
1024
|
requires: ["firstFrame"],
|
|
1009
|
-
supports: ["seed"]
|
|
1025
|
+
supports: ["seed", "lastFrame"]
|
|
1010
1026
|
},
|
|
1011
1027
|
defaults: {},
|
|
1012
1028
|
usage: { ...VIDEO_USAGE },
|
|
@@ -1117,7 +1133,7 @@ function resolveImageOptions(model, request, onUnsupported = "error") {
|
|
|
1117
1133
|
const warnings = [];
|
|
1118
1134
|
const c = model.constraints;
|
|
1119
1135
|
const merged = { ...model.defaults, ...stripUndefined(request), model: model.id };
|
|
1120
|
-
if (merged.aspectRatio && c.aspectRatios && !c.aspectRatios.includes(merged.aspectRatio)) {
|
|
1136
|
+
if (merged.aspectRatio !== void 0 && merged.aspectRatio !== "adaptive" && c.aspectRatios !== void 0 && !c.aspectRatios.includes(merged.aspectRatio)) {
|
|
1121
1137
|
const to = nearestAspectRatio(merged.aspectRatio, c.aspectRatios);
|
|
1122
1138
|
warnings.push({
|
|
1123
1139
|
code: "ratio_coerced",
|
|
@@ -1160,7 +1176,8 @@ function resolveImageOptions(model, request, onUnsupported = "error") {
|
|
|
1160
1176
|
"quality",
|
|
1161
1177
|
"count",
|
|
1162
1178
|
"outputFormat",
|
|
1163
|
-
"scaleFactor"
|
|
1179
|
+
"scaleFactor",
|
|
1180
|
+
"safetySettings"
|
|
1164
1181
|
]);
|
|
1165
1182
|
return { request: merged, warnings };
|
|
1166
1183
|
}
|
|
@@ -1190,7 +1207,7 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
1190
1207
|
delete merged.aspectRatio;
|
|
1191
1208
|
}
|
|
1192
1209
|
}
|
|
1193
|
-
if (merged.aspectRatio && c.aspectRatios && !c.aspectRatios.includes(merged.aspectRatio)) {
|
|
1210
|
+
if (merged.aspectRatio !== void 0 && merged.aspectRatio !== "adaptive" && c.aspectRatios !== void 0 && !c.aspectRatios.includes(merged.aspectRatio)) {
|
|
1194
1211
|
const to = nearestAspectRatio(merged.aspectRatio, c.aspectRatios);
|
|
1195
1212
|
warnings.push({
|
|
1196
1213
|
code: "ratio_coerced",
|
|
@@ -1272,8 +1289,7 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
1272
1289
|
return { request: merged, warnings };
|
|
1273
1290
|
}
|
|
1274
1291
|
function dropUnsupported(req, model, warnings, fields) {
|
|
1275
|
-
const supports = model.constraints.supports;
|
|
1276
|
-
if (!supports) return;
|
|
1292
|
+
const supports = model.constraints.supports ?? [];
|
|
1277
1293
|
for (const field of fields) {
|
|
1278
1294
|
if (req[field] !== void 0 && !supports.includes(field)) {
|
|
1279
1295
|
warnings.push({
|
|
@@ -1351,8 +1367,45 @@ function keysFromEnv(env, prefix = "") {
|
|
|
1351
1367
|
}
|
|
1352
1368
|
|
|
1353
1369
|
// src/retry.ts
|
|
1370
|
+
import { z as z2 } from "zod";
|
|
1371
|
+
|
|
1372
|
+
// src/json.ts
|
|
1354
1373
|
import { z } from "zod";
|
|
1355
|
-
var
|
|
1374
|
+
var JsonValueSchema = z.lazy(
|
|
1375
|
+
() => z.union([
|
|
1376
|
+
z.string(),
|
|
1377
|
+
z.number(),
|
|
1378
|
+
z.boolean(),
|
|
1379
|
+
z.null(),
|
|
1380
|
+
z.array(JsonValueSchema),
|
|
1381
|
+
z.record(z.string(), JsonValueSchema)
|
|
1382
|
+
])
|
|
1383
|
+
);
|
|
1384
|
+
var JsonObjectSchema = z.record(z.string(), JsonValueSchema);
|
|
1385
|
+
async function readErrorBody(res) {
|
|
1386
|
+
const text2 = await res.text().catch(() => "");
|
|
1387
|
+
try {
|
|
1388
|
+
return JsonValueSchema.parse(JSON.parse(text2));
|
|
1389
|
+
} catch {
|
|
1390
|
+
return text2;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
var thrownErrorSchema = z.object({
|
|
1394
|
+
message: z.string().optional(),
|
|
1395
|
+
status: z.number().optional(),
|
|
1396
|
+
statusCode: z.number().optional(),
|
|
1397
|
+
responseBody: z.string().optional()
|
|
1398
|
+
});
|
|
1399
|
+
function describeThrown(cause) {
|
|
1400
|
+
const parsed = thrownErrorSchema.safeParse(cause);
|
|
1401
|
+
if (!parsed.success) return { message: String(cause), status: void 0, body: String(cause) };
|
|
1402
|
+
const { message, status, statusCode, responseBody } = parsed.data;
|
|
1403
|
+
const body = responseBody ?? message ?? String(cause);
|
|
1404
|
+
return { message: message ?? String(cause), status: status ?? statusCode, body };
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
// src/retry.ts
|
|
1408
|
+
var textBody = z2.string();
|
|
1356
1409
|
function classifyHttpError(status, body, provider, model) {
|
|
1357
1410
|
const asText = textBody.safeParse(body);
|
|
1358
1411
|
const text2 = asText.success ? asText.data : JSON.stringify(body);
|
|
@@ -1435,6 +1488,13 @@ function transportError(provider, cause, model) {
|
|
|
1435
1488
|
if (model !== void 0) init.model = model;
|
|
1436
1489
|
return new ModelKitError(init);
|
|
1437
1490
|
}
|
|
1491
|
+
function classifyThrown(provider, cause, model, override = {}) {
|
|
1492
|
+
if (cause instanceof ModelKitError) return cause;
|
|
1493
|
+
const info = describeThrown(cause);
|
|
1494
|
+
const status = override.status ?? info.status;
|
|
1495
|
+
if (status === void 0) return transportError(provider, cause, model);
|
|
1496
|
+
return classifyHttpError(status, override.body ?? info.body, provider, model);
|
|
1497
|
+
}
|
|
1438
1498
|
async function pollUntil(check, opts) {
|
|
1439
1499
|
const start = Date.now();
|
|
1440
1500
|
let interval = opts.intervalMs;
|
|
@@ -1557,7 +1617,7 @@ import {
|
|
|
1557
1617
|
streamObject as aiStreamObject2,
|
|
1558
1618
|
streamText as aiStreamText2
|
|
1559
1619
|
} from "ai";
|
|
1560
|
-
import { z as
|
|
1620
|
+
import { z as z4 } from "zod";
|
|
1561
1621
|
|
|
1562
1622
|
// src/adapters/media-ref.ts
|
|
1563
1623
|
function isUrlRef(ref) {
|
|
@@ -1612,7 +1672,7 @@ import { createPerplexity } from "@ai-sdk/perplexity";
|
|
|
1612
1672
|
import { createXai } from "@ai-sdk/xai";
|
|
1613
1673
|
import { createDeepSeek } from "@ai-sdk/deepseek";
|
|
1614
1674
|
import { createMoonshotAI } from "@ai-sdk/moonshotai";
|
|
1615
|
-
import { z as
|
|
1675
|
+
import { z as z3 } from "zod";
|
|
1616
1676
|
var TEXT_PROVIDERS = [
|
|
1617
1677
|
"openai",
|
|
1618
1678
|
"anthropic",
|
|
@@ -1623,7 +1683,7 @@ var TEXT_PROVIDERS = [
|
|
|
1623
1683
|
"moonshot",
|
|
1624
1684
|
"minimax"
|
|
1625
1685
|
];
|
|
1626
|
-
var textProviderSchema =
|
|
1686
|
+
var textProviderSchema = z3.enum(TEXT_PROVIDERS);
|
|
1627
1687
|
function isTextProvider(value) {
|
|
1628
1688
|
return textProviderSchema.safeParse(value).success;
|
|
1629
1689
|
}
|
|
@@ -1632,9 +1692,9 @@ var OPENAI_COMPATIBLE_BASE_URLS = {
|
|
|
1632
1692
|
};
|
|
1633
1693
|
var GATEWAY_SLUGS = {
|
|
1634
1694
|
openai: "openai",
|
|
1635
|
-
anthropic: "anthropic",
|
|
1695
|
+
anthropic: "anthropic/v1",
|
|
1636
1696
|
google: "google-ai-studio/v1beta",
|
|
1637
|
-
xai: "grok",
|
|
1697
|
+
xai: "grok/v1",
|
|
1638
1698
|
perplexity: "perplexity-ai",
|
|
1639
1699
|
deepseek: "deepseek"
|
|
1640
1700
|
};
|
|
@@ -1809,10 +1869,10 @@ function textAbortOptions(sdk, context) {
|
|
|
1809
1869
|
if (abortSignal) return { abortSignal };
|
|
1810
1870
|
return {};
|
|
1811
1871
|
}
|
|
1812
|
-
var catalogId =
|
|
1813
|
-
var exactSize =
|
|
1814
|
-
var sdkRatio =
|
|
1815
|
-
var sizeTier =
|
|
1872
|
+
var catalogId = z4.string();
|
|
1873
|
+
var exactSize = z4.templateLiteral([z4.number(), "x", z4.number()]);
|
|
1874
|
+
var sdkRatio = z4.templateLiteral([z4.number(), ":", z4.number()]);
|
|
1875
|
+
var sizeTier = z4.enum(["512", "1K", "2K", "4K"]);
|
|
1816
1876
|
function isCatalogId(model) {
|
|
1817
1877
|
return catalogId.safeParse(model).success;
|
|
1818
1878
|
}
|
|
@@ -1869,6 +1929,10 @@ function pushIgnored(warnings, field, from, modelId) {
|
|
|
1869
1929
|
message: `${modelId} provider instance does not support ${field}; ignored`
|
|
1870
1930
|
});
|
|
1871
1931
|
}
|
|
1932
|
+
function logCoercions(logger, modelId, warnings) {
|
|
1933
|
+
if (warnings.length === 0) return;
|
|
1934
|
+
logger.warn(`[modelkit] ${modelId} request coerced`, { model: modelId, warnings });
|
|
1935
|
+
}
|
|
1872
1936
|
function createModelKit(config, adapters) {
|
|
1873
1937
|
const catalog = new Catalog(MODELS).withOverrides(config.catalogOverride ?? []);
|
|
1874
1938
|
const logger = config.logger ?? console;
|
|
@@ -1902,6 +1966,10 @@ function createModelKit(config, adapters) {
|
|
|
1902
1966
|
logger.warn("[modelkit] usage emit failed", err);
|
|
1903
1967
|
}
|
|
1904
1968
|
}
|
|
1969
|
+
function withRowUnit(event) {
|
|
1970
|
+
const row = catalog.get(event.model);
|
|
1971
|
+
return row ? { ...event, unit: row.usage.unit } : event;
|
|
1972
|
+
}
|
|
1905
1973
|
function textTarget(model, call) {
|
|
1906
1974
|
if (!isCatalogId(model)) {
|
|
1907
1975
|
return {
|
|
@@ -1970,6 +2038,7 @@ function createModelKit(config, adapters) {
|
|
|
1970
2038
|
pushIgnored(warnings, "outputFormat", _outputFormat, model.modelId);
|
|
1971
2039
|
if (scaleFactor !== void 0)
|
|
1972
2040
|
pushIgnored(warnings, "scaleFactor", scaleFactor, model.modelId);
|
|
2041
|
+
logCoercions(logger, model.modelId, warnings);
|
|
1973
2042
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
1974
2043
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
1975
2044
|
const result = await aiGenerateImage(options);
|
|
@@ -2053,6 +2122,7 @@ function createModelKit(config, adapters) {
|
|
|
2053
2122
|
if (_mode !== void 0) pushIgnored(warnings, "mode", _mode, model.modelId);
|
|
2054
2123
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
2055
2124
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
2125
|
+
logCoercions(logger, model.modelId, warnings);
|
|
2056
2126
|
const pending = aiGenerateVideo(options);
|
|
2057
2127
|
let settled;
|
|
2058
2128
|
let failed = false;
|
|
@@ -2111,6 +2181,7 @@ function createModelKit(config, adapters) {
|
|
|
2111
2181
|
call.onUnsupported ?? "error"
|
|
2112
2182
|
);
|
|
2113
2183
|
warnings.push(...inputWarnings);
|
|
2184
|
+
logCoercions(logger, model.id, warnings);
|
|
2114
2185
|
const signal = combineSignals(req.abortSignal, call.signal);
|
|
2115
2186
|
const { adapter, ctx } = context(model, signal ? { ...call, signal } : call, warnings);
|
|
2116
2187
|
if (!adapter.generateImage)
|
|
@@ -2120,7 +2191,7 @@ function createModelKit(config, adapters) {
|
|
|
2120
2191
|
model: model.id
|
|
2121
2192
|
});
|
|
2122
2193
|
const result = await adapter.generateImage(request, ctx);
|
|
2123
|
-
const usage2 = { ...result.usage, model: model.id };
|
|
2194
|
+
const usage2 = { ...result.usage, model: model.id, unit: model.usage.unit };
|
|
2124
2195
|
await emit(usage2);
|
|
2125
2196
|
const images = result.images.map(toGeneratedImage);
|
|
2126
2197
|
const first = images[0];
|
|
@@ -2153,6 +2224,7 @@ function createModelKit(config, adapters) {
|
|
|
2153
2224
|
call.onUnsupported ?? "error"
|
|
2154
2225
|
);
|
|
2155
2226
|
warnings.push(...inputWarnings);
|
|
2227
|
+
logCoercions(logger, model.id, warnings);
|
|
2156
2228
|
const signal = combineSignals(req.abortSignal, call.signal);
|
|
2157
2229
|
const { adapter, ctx } = context(model, signal ? { ...call, signal } : call, warnings);
|
|
2158
2230
|
if (!adapter.generateVideo)
|
|
@@ -2170,7 +2242,11 @@ function createModelKit(config, adapters) {
|
|
|
2170
2242
|
result(opts) {
|
|
2171
2243
|
if (settled) return settled;
|
|
2172
2244
|
const pending = result(opts).then(
|
|
2173
|
-
(out) => emit({
|
|
2245
|
+
(out) => emit({
|
|
2246
|
+
...out.usage,
|
|
2247
|
+
model: model.id,
|
|
2248
|
+
unit: model.usage.unit
|
|
2249
|
+
}).then(() => out),
|
|
2174
2250
|
(cause) => {
|
|
2175
2251
|
settled = void 0;
|
|
2176
2252
|
throw cause;
|
|
@@ -2190,7 +2266,8 @@ function createModelKit(config, adapters) {
|
|
|
2190
2266
|
model: model.id
|
|
2191
2267
|
});
|
|
2192
2268
|
}
|
|
2193
|
-
const
|
|
2269
|
+
const warnings = [];
|
|
2270
|
+
const { adapter, ctx } = context(model, call, warnings);
|
|
2194
2271
|
if (!adapter.generateAudio) {
|
|
2195
2272
|
throw new ModelKitError({
|
|
2196
2273
|
code: "unsupported_option",
|
|
@@ -2202,7 +2279,8 @@ function createModelKit(config, adapters) {
|
|
|
2202
2279
|
{ ...model.defaults, ...req, model: model.id },
|
|
2203
2280
|
ctx
|
|
2204
2281
|
);
|
|
2205
|
-
|
|
2282
|
+
logCoercions(logger, model.id, warnings);
|
|
2283
|
+
await emit({ ...result.usage, model: model.id, unit: model.usage.unit });
|
|
2206
2284
|
return result;
|
|
2207
2285
|
},
|
|
2208
2286
|
async prepareMediaPart(modelId, ref, mediaType, call = {}) {
|
|
@@ -2242,7 +2320,7 @@ function createModelKit(config, adapters) {
|
|
|
2242
2320
|
options.prepareStep ?? options.experimental_prepareStep
|
|
2243
2321
|
)
|
|
2244
2322
|
});
|
|
2245
|
-
for (const event of steps.usage(result.steps)) await emit(event);
|
|
2323
|
+
for (const event of steps.usage(result.steps)) await emit(withRowUnit(event));
|
|
2246
2324
|
return result;
|
|
2247
2325
|
},
|
|
2248
2326
|
streamText(options, call = {}) {
|
|
@@ -2260,7 +2338,7 @@ function createModelKit(config, adapters) {
|
|
|
2260
2338
|
providerOptions: {},
|
|
2261
2339
|
prepareStep: steps.wrap(options.prepareStep),
|
|
2262
2340
|
onFinish: async (event) => {
|
|
2263
|
-
for (const usage2 of steps.usage(event.steps)) await emit(usage2);
|
|
2341
|
+
for (const usage2 of steps.usage(event.steps)) await emit(withRowUnit(usage2));
|
|
2264
2342
|
await callerOnFinish?.(event);
|
|
2265
2343
|
}
|
|
2266
2344
|
});
|
|
@@ -2274,7 +2352,7 @@ function createModelKit(config, adapters) {
|
|
|
2274
2352
|
providerOptions: mergeTextProviderOptions(entry, options.providerOptions)
|
|
2275
2353
|
};
|
|
2276
2354
|
const result = await aiGenerateObject2(sdkOptions);
|
|
2277
|
-
await emit(textUsageEvent(entry, provider, result.usage));
|
|
2355
|
+
await emit(withRowUnit(textUsageEvent(entry, provider, result.usage)));
|
|
2278
2356
|
return result;
|
|
2279
2357
|
},
|
|
2280
2358
|
streamObject(options, call = {}) {
|
|
@@ -2286,7 +2364,7 @@ function createModelKit(config, adapters) {
|
|
|
2286
2364
|
model: languageModel2,
|
|
2287
2365
|
providerOptions: mergeTextProviderOptions(entry, options.providerOptions),
|
|
2288
2366
|
onFinish: async (event) => {
|
|
2289
|
-
await emit(textUsageEvent(entry, provider, event.usage));
|
|
2367
|
+
await emit(withRowUnit(textUsageEvent(entry, provider, event.usage)));
|
|
2290
2368
|
await callerOnFinish?.(event);
|
|
2291
2369
|
}
|
|
2292
2370
|
};
|
|
@@ -2296,7 +2374,7 @@ function createModelKit(config, adapters) {
|
|
|
2296
2374
|
}
|
|
2297
2375
|
|
|
2298
2376
|
// src/adapters/ark.ts
|
|
2299
|
-
import { z as
|
|
2377
|
+
import { z as z5 } from "zod";
|
|
2300
2378
|
var ARK_BASE_URL = "https://ark.ap-southeast.bytepluses.com/api/v3";
|
|
2301
2379
|
var SUBMIT_PATH = "/contents/generations/tasks";
|
|
2302
2380
|
var SEEDANCE_POLL_INTERVAL_MS = 15e3;
|
|
@@ -2354,7 +2432,7 @@ function arkKey(ctx) {
|
|
|
2354
2432
|
return key;
|
|
2355
2433
|
}
|
|
2356
2434
|
function throwArkError(status, body, model) {
|
|
2357
|
-
const parsed =
|
|
2435
|
+
const parsed = z5.string().safeParse(body);
|
|
2358
2436
|
const text2 = parsed.success ? parsed.data : JSON.stringify(body ?? "");
|
|
2359
2437
|
if (/sensitive.?content|inputimage|human.?face/i.test(text2)) {
|
|
2360
2438
|
const init = {
|
|
@@ -2368,6 +2446,16 @@ function throwArkError(status, body, model) {
|
|
|
2368
2446
|
if (status !== void 0) init.status = status;
|
|
2369
2447
|
throw new ModelKitError(init);
|
|
2370
2448
|
}
|
|
2449
|
+
if (status === void 0) {
|
|
2450
|
+
throw new ModelKitError({
|
|
2451
|
+
code: "provider_rejected",
|
|
2452
|
+
message: `ark rejected the request: ${text2.slice(0, 500)}`,
|
|
2453
|
+
provider: "ark",
|
|
2454
|
+
model,
|
|
2455
|
+
body,
|
|
2456
|
+
retryable: false
|
|
2457
|
+
});
|
|
2458
|
+
}
|
|
2371
2459
|
throw classifyHttpError(status, body, "ark", model);
|
|
2372
2460
|
}
|
|
2373
2461
|
function seedreamSize(aspect, size) {
|
|
@@ -2386,13 +2474,13 @@ function arkUrl(ref) {
|
|
|
2386
2474
|
if ("url" in ref) return ref.url;
|
|
2387
2475
|
return `data:${ref.mime};base64,${Buffer.from(ref.bytes).toString("base64")}`;
|
|
2388
2476
|
}
|
|
2389
|
-
var SeedreamImageSchema =
|
|
2390
|
-
url:
|
|
2391
|
-
b64_json:
|
|
2477
|
+
var SeedreamImageSchema = z5.object({
|
|
2478
|
+
url: z5.string().optional(),
|
|
2479
|
+
b64_json: z5.string().optional()
|
|
2392
2480
|
});
|
|
2393
|
-
var SeedreamResponseSchema =
|
|
2394
|
-
data:
|
|
2395
|
-
error:
|
|
2481
|
+
var SeedreamResponseSchema = z5.object({
|
|
2482
|
+
data: z5.array(SeedreamImageSchema).optional(),
|
|
2483
|
+
error: z5.object({ message: z5.string().optional(), code: z5.string().optional() }).optional()
|
|
2396
2484
|
});
|
|
2397
2485
|
function retryOptsFor(ctx, attempts = 3) {
|
|
2398
2486
|
const opts = { attempts };
|
|
@@ -2403,6 +2491,11 @@ function fetchInitFor(ctx, init) {
|
|
|
2403
2491
|
if (ctx.signal !== void 0) init.signal = ctx.signal;
|
|
2404
2492
|
return init;
|
|
2405
2493
|
}
|
|
2494
|
+
function arkFetch(ctx, url, init) {
|
|
2495
|
+
return ctx.fetch(url, fetchInitFor(ctx, init)).catch((cause) => {
|
|
2496
|
+
throw classifyThrown("ark", cause, ctx.model.id);
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2406
2499
|
async function generateSeedreamImage(req, ctx) {
|
|
2407
2500
|
const key = arkKey(ctx);
|
|
2408
2501
|
const modelId = ctx.model.id;
|
|
@@ -2420,14 +2513,11 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2420
2513
|
if (refs.length === 1 && firstRef !== void 0) body.image = firstRef;
|
|
2421
2514
|
else if (refs.length > 1) body.image = refs;
|
|
2422
2515
|
const data = await withRetry(async () => {
|
|
2423
|
-
const res = await ctx
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
body: JSON.stringify(body)
|
|
2429
|
-
})
|
|
2430
|
-
);
|
|
2516
|
+
const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}/images/generations`, {
|
|
2517
|
+
method: "POST",
|
|
2518
|
+
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
2519
|
+
body: JSON.stringify(body)
|
|
2520
|
+
});
|
|
2431
2521
|
if (!res.ok) {
|
|
2432
2522
|
const text2 = await res.text().catch(() => "");
|
|
2433
2523
|
throwArkError(res.status, text2, modelId);
|
|
@@ -2442,7 +2532,7 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2442
2532
|
bytes = Buffer.from(first.b64_json, "base64");
|
|
2443
2533
|
} else if (first?.url) {
|
|
2444
2534
|
const imageUrl = first.url;
|
|
2445
|
-
const res = await ctx
|
|
2535
|
+
const res = await arkFetch(ctx, imageUrl, {});
|
|
2446
2536
|
if (!res.ok) {
|
|
2447
2537
|
const text2 = await res.text().catch(() => "");
|
|
2448
2538
|
throwArkError(res.status, text2, modelId);
|
|
@@ -2462,13 +2552,13 @@ async function generateSeedreamImage(req, ctx) {
|
|
|
2462
2552
|
if (req.quality !== void 0) usage2.imageQuality = req.quality;
|
|
2463
2553
|
return { images: [{ bytes, mime: sniffedImageMime(bytes) }], usage: usage2, raw: data };
|
|
2464
2554
|
}
|
|
2465
|
-
var SeedanceResponseSchema =
|
|
2466
|
-
id:
|
|
2467
|
-
status:
|
|
2468
|
-
content:
|
|
2469
|
-
error:
|
|
2555
|
+
var SeedanceResponseSchema = z5.object({
|
|
2556
|
+
id: z5.string().optional(),
|
|
2557
|
+
status: z5.string().optional(),
|
|
2558
|
+
content: z5.object({ video_url: z5.string().optional() }).optional(),
|
|
2559
|
+
error: z5.union([z5.string(), z5.object({ message: z5.string().optional() })]).optional()
|
|
2470
2560
|
});
|
|
2471
|
-
var SeedanceErrorMessageSchema =
|
|
2561
|
+
var SeedanceErrorMessageSchema = z5.object({ message: z5.string().optional() });
|
|
2472
2562
|
function seedanceUsage(ctx, req, duration) {
|
|
2473
2563
|
const usage2 = {
|
|
2474
2564
|
model: ctx.model.id,
|
|
@@ -2482,7 +2572,7 @@ function seedanceUsage(ctx, req, duration) {
|
|
|
2482
2572
|
return usage2;
|
|
2483
2573
|
}
|
|
2484
2574
|
function seedanceErrorMessage(error, status) {
|
|
2485
|
-
const asString =
|
|
2575
|
+
const asString = z5.string().safeParse(error);
|
|
2486
2576
|
if (asString.success) return asString.data;
|
|
2487
2577
|
const asObject = SeedanceErrorMessageSchema.safeParse(error);
|
|
2488
2578
|
if (asObject.success && asObject.data.message !== void 0) return asObject.data.message;
|
|
@@ -2547,14 +2637,11 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2547
2637
|
if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
|
|
2548
2638
|
if (req.seed !== void 0) body.seed = req.seed;
|
|
2549
2639
|
const submit = await withRetry(async () => {
|
|
2550
|
-
const res = await ctx
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
body: JSON.stringify(body)
|
|
2556
|
-
})
|
|
2557
|
-
);
|
|
2640
|
+
const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}`, {
|
|
2641
|
+
method: "POST",
|
|
2642
|
+
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
|
|
2643
|
+
body: JSON.stringify(body)
|
|
2644
|
+
});
|
|
2558
2645
|
if (!res.ok) {
|
|
2559
2646
|
const text2 = await res.text().catch(() => "");
|
|
2560
2647
|
throwArkError(res.status, text2, modelId);
|
|
@@ -2567,12 +2654,9 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2567
2654
|
const jobId = submit.id;
|
|
2568
2655
|
const usage2 = seedanceUsage(ctx, req, duration);
|
|
2569
2656
|
const fetchStatus = async () => {
|
|
2570
|
-
const res = await ctx
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
headers: { Authorization: `Bearer ${key}` }
|
|
2574
|
-
})
|
|
2575
|
-
);
|
|
2657
|
+
const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}/${jobId}`, {
|
|
2658
|
+
headers: { Authorization: `Bearer ${key}` }
|
|
2659
|
+
});
|
|
2576
2660
|
if (!res.ok) {
|
|
2577
2661
|
if (res.status === 429 || res.status >= 500) return void 0;
|
|
2578
2662
|
const text2 = await res.text().catch(() => "");
|
|
@@ -2633,43 +2717,6 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
2633
2717
|
// src/adapters/fal.ts
|
|
2634
2718
|
import { z as z6 } from "zod";
|
|
2635
2719
|
import { createFalClient } from "@fal-ai/client";
|
|
2636
|
-
|
|
2637
|
-
// src/json.ts
|
|
2638
|
-
import { z as z5 } from "zod";
|
|
2639
|
-
var JsonValueSchema = z5.lazy(
|
|
2640
|
-
() => z5.union([
|
|
2641
|
-
z5.string(),
|
|
2642
|
-
z5.number(),
|
|
2643
|
-
z5.boolean(),
|
|
2644
|
-
z5.null(),
|
|
2645
|
-
z5.array(JsonValueSchema),
|
|
2646
|
-
z5.record(z5.string(), JsonValueSchema)
|
|
2647
|
-
])
|
|
2648
|
-
);
|
|
2649
|
-
var JsonObjectSchema = z5.record(z5.string(), JsonValueSchema);
|
|
2650
|
-
async function readErrorBody(res) {
|
|
2651
|
-
const text2 = await res.text().catch(() => "");
|
|
2652
|
-
try {
|
|
2653
|
-
return JsonValueSchema.parse(JSON.parse(text2));
|
|
2654
|
-
} catch {
|
|
2655
|
-
return text2;
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
var thrownErrorSchema = z5.object({
|
|
2659
|
-
message: z5.string().optional(),
|
|
2660
|
-
status: z5.number().optional(),
|
|
2661
|
-
statusCode: z5.number().optional(),
|
|
2662
|
-
responseBody: z5.string().optional()
|
|
2663
|
-
});
|
|
2664
|
-
function describeThrown(cause) {
|
|
2665
|
-
const parsed = thrownErrorSchema.safeParse(cause);
|
|
2666
|
-
if (!parsed.success) return { message: String(cause), status: void 0, body: String(cause) };
|
|
2667
|
-
const { message, status, statusCode, responseBody } = parsed.data;
|
|
2668
|
-
const body = responseBody ?? message ?? String(cause);
|
|
2669
|
-
return { message: message ?? String(cause), status: status ?? statusCode, body };
|
|
2670
|
-
}
|
|
2671
|
-
|
|
2672
|
-
// src/adapters/fal.ts
|
|
2673
2720
|
var MUSE_T2I_ENDPOINT = "meta/muse-image/text-to-image";
|
|
2674
2721
|
var MUSE_EDIT_ENDPOINT = "meta/muse-image/edit";
|
|
2675
2722
|
var KLING_O1_ENDPOINT = "fal-ai/kling-video/o1/video-to-video/reference";
|
|
@@ -2681,10 +2728,33 @@ function defaultCreateFalClient(opts) {
|
|
|
2681
2728
|
const client2 = createFalClient(opts);
|
|
2682
2729
|
return {
|
|
2683
2730
|
async subscribe(endpoint, options) {
|
|
2684
|
-
const outcome = await client2.subscribe(endpoint,
|
|
2731
|
+
const outcome = await client2.subscribe(endpoint, options);
|
|
2685
2732
|
const unwrapped = falSubscribePayloadSchema.safeParse(outcome);
|
|
2686
2733
|
if (unwrapped.success) return unwrapped.data.data;
|
|
2687
2734
|
return JsonValueSchema.parse(outcome);
|
|
2735
|
+
},
|
|
2736
|
+
queue: {
|
|
2737
|
+
async submit(endpoint, options) {
|
|
2738
|
+
const submitted = await client2.queue.submit(endpoint, {
|
|
2739
|
+
input: options.input,
|
|
2740
|
+
...options.abortSignal !== void 0 ? { abortSignal: options.abortSignal } : {}
|
|
2741
|
+
});
|
|
2742
|
+
return { requestId: submitted.request_id };
|
|
2743
|
+
},
|
|
2744
|
+
async status(endpoint, options) {
|
|
2745
|
+
const current = await client2.queue.status(endpoint, {
|
|
2746
|
+
requestId: options.requestId,
|
|
2747
|
+
...options.abortSignal !== void 0 ? { abortSignal: options.abortSignal } : {}
|
|
2748
|
+
});
|
|
2749
|
+
return { status: current.status };
|
|
2750
|
+
},
|
|
2751
|
+
async result(endpoint, options) {
|
|
2752
|
+
const outcome = await client2.queue.result(endpoint, {
|
|
2753
|
+
requestId: options.requestId,
|
|
2754
|
+
...options.abortSignal !== void 0 ? { abortSignal: options.abortSignal } : {}
|
|
2755
|
+
});
|
|
2756
|
+
return JsonValueSchema.parse(outcome.data);
|
|
2757
|
+
}
|
|
2688
2758
|
}
|
|
2689
2759
|
};
|
|
2690
2760
|
}
|
|
@@ -2726,15 +2796,17 @@ var falSdkThrownSchema = z6.object({
|
|
|
2726
2796
|
message: z6.string().optional()
|
|
2727
2797
|
});
|
|
2728
2798
|
function falSdkError(cause, model) {
|
|
2729
|
-
if (isModelKitError(cause)) return cause;
|
|
2730
2799
|
const parsed = falSdkThrownSchema.safeParse(cause);
|
|
2731
2800
|
if (parsed.success) {
|
|
2732
2801
|
const status = parsed.data.status ?? parsed.data.statusCode;
|
|
2733
2802
|
const body = parsed.data.body ?? parsed.data.message ?? String(cause);
|
|
2734
|
-
return
|
|
2803
|
+
return classifyThrown("fal", cause, model, { status, body: liftDetail(body) });
|
|
2735
2804
|
}
|
|
2736
2805
|
const info = describeThrown(cause);
|
|
2737
|
-
return
|
|
2806
|
+
return classifyThrown("fal", cause, model, {
|
|
2807
|
+
status: info.status,
|
|
2808
|
+
body: liftDetail(info.body)
|
|
2809
|
+
});
|
|
2738
2810
|
}
|
|
2739
2811
|
function gatewayConfig(ctx) {
|
|
2740
2812
|
const cf = ctx.routing.cloudflare;
|
|
@@ -2816,7 +2888,7 @@ async function passthroughRequest(ctx, endpoint, input) {
|
|
|
2816
2888
|
}
|
|
2817
2889
|
return JsonValueSchema.parse(await resultRes.json());
|
|
2818
2890
|
}
|
|
2819
|
-
|
|
2891
|
+
function falClientOf(ctx, deps) {
|
|
2820
2892
|
const falKey = ctx.keys.fal;
|
|
2821
2893
|
if (!falKey) {
|
|
2822
2894
|
throw new ModelKitError({
|
|
@@ -2827,12 +2899,19 @@ async function subscribe(ctx, deps, endpoint, input) {
|
|
|
2827
2899
|
retryable: false
|
|
2828
2900
|
});
|
|
2829
2901
|
}
|
|
2830
|
-
|
|
2902
|
+
return deps.createFalClient({ credentials: falKey, fetch: ctx.fetch });
|
|
2903
|
+
}
|
|
2904
|
+
async function subscribe(ctx, deps, endpoint, input) {
|
|
2905
|
+
const client2 = falClientOf(ctx, deps);
|
|
2906
|
+
const options = {
|
|
2907
|
+
input,
|
|
2908
|
+
...ctx.signal !== void 0 ? { abortSignal: ctx.signal } : {}
|
|
2909
|
+
};
|
|
2831
2910
|
try {
|
|
2832
2911
|
return await withRetry(
|
|
2833
2912
|
async () => {
|
|
2834
2913
|
try {
|
|
2835
|
-
return await client2.subscribe(endpoint,
|
|
2914
|
+
return await client2.subscribe(endpoint, options);
|
|
2836
2915
|
} catch (cause) {
|
|
2837
2916
|
throw falSdkError(cause, ctx.model.id);
|
|
2838
2917
|
}
|
|
@@ -2966,13 +3045,14 @@ function klingO1Input(req) {
|
|
|
2966
3045
|
});
|
|
2967
3046
|
}
|
|
2968
3047
|
const duration = Math.min(10, Math.max(3, Math.round(req.durationSeconds ?? 5)));
|
|
2969
|
-
const ratio = req.aspectRatio === "16:9" || req.aspectRatio === "9:16" || req.aspectRatio === "1:1" ? req.aspectRatio : "auto";
|
|
2970
3048
|
const input = {
|
|
2971
3049
|
prompt: req.prompt,
|
|
2972
3050
|
video_url: source,
|
|
2973
|
-
duration: String(duration)
|
|
2974
|
-
aspect_ratio: ratio
|
|
3051
|
+
duration: String(duration)
|
|
2975
3052
|
};
|
|
3053
|
+
if (req.aspectRatio !== "adaptive") {
|
|
3054
|
+
input.aspect_ratio = req.aspectRatio === "16:9" || req.aspectRatio === "9:16" || req.aspectRatio === "1:1" ? req.aspectRatio : "auto";
|
|
3055
|
+
}
|
|
2976
3056
|
const refs = (req.referenceImages ?? []).map(refToUrl);
|
|
2977
3057
|
if (refs.length > 0) input.image_urls = refs;
|
|
2978
3058
|
return input;
|
|
@@ -3001,13 +3081,7 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
3001
3081
|
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
3002
3082
|
return await passthroughVideoJob(ctx, req, KLING_O1_ENDPOINT, input);
|
|
3003
3083
|
}
|
|
3004
|
-
|
|
3005
|
-
return completedVideoJob(
|
|
3006
|
-
ctx,
|
|
3007
|
-
req,
|
|
3008
|
-
extractVideoUrl(result2, KLING_O1_ENDPOINT, ctx.model.id),
|
|
3009
|
-
result2
|
|
3010
|
-
);
|
|
3084
|
+
return await submitQueueJob(ctx, req, deps, KLING_O1_ENDPOINT, input);
|
|
3011
3085
|
}
|
|
3012
3086
|
const family = minimaxFamily(providerModelId);
|
|
3013
3087
|
const refs = {
|
|
@@ -3036,19 +3110,81 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
3036
3110
|
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
3037
3111
|
return await passthroughVideoJob(ctx, req, endpoint, base);
|
|
3038
3112
|
}
|
|
3039
|
-
|
|
3040
|
-
return completedVideoJob(ctx, req, extractVideoUrl(result, endpoint, ctx.model.id), result);
|
|
3113
|
+
return await submitQueueJob(ctx, req, deps, endpoint, base);
|
|
3041
3114
|
}
|
|
3042
|
-
function
|
|
3115
|
+
async function submitQueueJob(ctx, req, deps, endpoint, input) {
|
|
3116
|
+
const client2 = falClientOf(ctx, deps);
|
|
3117
|
+
let submitted;
|
|
3118
|
+
try {
|
|
3119
|
+
submitted = await withRetry(
|
|
3120
|
+
async () => {
|
|
3121
|
+
try {
|
|
3122
|
+
return await client2.queue.submit(endpoint, {
|
|
3123
|
+
input,
|
|
3124
|
+
...ctx.signal !== void 0 ? { abortSignal: ctx.signal } : {}
|
|
3125
|
+
});
|
|
3126
|
+
} catch (cause) {
|
|
3127
|
+
throw falSdkError(cause, ctx.model.id);
|
|
3128
|
+
}
|
|
3129
|
+
},
|
|
3130
|
+
ctx.signal !== void 0 ? { signal: ctx.signal } : {}
|
|
3131
|
+
);
|
|
3132
|
+
} catch (cause) {
|
|
3133
|
+
throw falSdkError(cause, ctx.model.id);
|
|
3134
|
+
}
|
|
3135
|
+
return queuedVideoJob(ctx, req, client2, endpoint, submitted.requestId);
|
|
3136
|
+
}
|
|
3137
|
+
function queuedVideoJob(ctx, req, client2, endpoint, requestId) {
|
|
3138
|
+
const readStatus = async () => {
|
|
3139
|
+
try {
|
|
3140
|
+
const options = {
|
|
3141
|
+
requestId,
|
|
3142
|
+
...ctx.signal !== void 0 ? { abortSignal: ctx.signal } : {}
|
|
3143
|
+
};
|
|
3144
|
+
return (await client2.queue.status(endpoint, options)).status;
|
|
3145
|
+
} catch (cause) {
|
|
3146
|
+
throw falSdkError(cause, ctx.model.id);
|
|
3147
|
+
}
|
|
3148
|
+
};
|
|
3043
3149
|
const duration = req.durationSeconds ?? 5;
|
|
3044
|
-
const result = { video: { url }, usage: videoUsage(ctx, req, duration), raw };
|
|
3045
3150
|
return {
|
|
3046
|
-
jobId:
|
|
3151
|
+
jobId: requestId,
|
|
3047
3152
|
async poll() {
|
|
3048
|
-
|
|
3153
|
+
try {
|
|
3154
|
+
const status = await readStatus();
|
|
3155
|
+
if (status === "COMPLETED") return { status: "succeeded" };
|
|
3156
|
+
if (status === "IN_QUEUE") return { status: "pending" };
|
|
3157
|
+
return { status: "running" };
|
|
3158
|
+
} catch (cause) {
|
|
3159
|
+
if (isModelKitError(cause) && !cause.retryable)
|
|
3160
|
+
return { status: "failed" };
|
|
3161
|
+
return { status: "pending" };
|
|
3162
|
+
}
|
|
3049
3163
|
},
|
|
3050
|
-
async result() {
|
|
3051
|
-
|
|
3164
|
+
async result(opts) {
|
|
3165
|
+
const signal = opts?.signal ?? ctx.signal;
|
|
3166
|
+
const pollOptions = {
|
|
3167
|
+
intervalMs: opts?.pollIntervalMs ?? PASSTHROUGH_POLL_MS,
|
|
3168
|
+
timeoutMs: opts?.timeoutMs ?? 15 * 6e4
|
|
3169
|
+
};
|
|
3170
|
+
if (signal !== void 0) pollOptions.signal = signal;
|
|
3171
|
+
const queueOptions = {
|
|
3172
|
+
requestId,
|
|
3173
|
+
...signal !== void 0 ? { abortSignal: signal } : {}
|
|
3174
|
+
};
|
|
3175
|
+
const payload = await pollUntil(async () => {
|
|
3176
|
+
try {
|
|
3177
|
+
const current = await client2.queue.status(endpoint, queueOptions);
|
|
3178
|
+
if (current.status !== "COMPLETED") return void 0;
|
|
3179
|
+
return await client2.queue.result(endpoint, queueOptions);
|
|
3180
|
+
} catch (cause) {
|
|
3181
|
+
const err = falSdkError(cause, ctx.model.id);
|
|
3182
|
+
if (err.retryable) return void 0;
|
|
3183
|
+
throw err;
|
|
3184
|
+
}
|
|
3185
|
+
}, pollOptions);
|
|
3186
|
+
const url = extractVideoUrl(payload, endpoint, ctx.model.id);
|
|
3187
|
+
return { video: { url }, usage: videoUsage(ctx, req, duration), raw: payload };
|
|
3052
3188
|
}
|
|
3053
3189
|
};
|
|
3054
3190
|
}
|
|
@@ -3401,9 +3537,7 @@ function sdkStatus(cause) {
|
|
|
3401
3537
|
return describeThrown(cause).status;
|
|
3402
3538
|
}
|
|
3403
3539
|
function throwSdkError(cause, model) {
|
|
3404
|
-
|
|
3405
|
-
const info = describeThrown(cause);
|
|
3406
|
-
throw classifyHttpError(info.status, info.body, "google-genai", model);
|
|
3540
|
+
throw classifyThrown("google-genai", cause, model);
|
|
3407
3541
|
}
|
|
3408
3542
|
function toBase64(bytes) {
|
|
3409
3543
|
return Buffer.from(bytes).toString("base64");
|
|
@@ -3607,12 +3741,17 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3607
3741
|
const duration = req.durationSeconds ?? 8;
|
|
3608
3742
|
const images = req.referenceImages ?? [];
|
|
3609
3743
|
const videos = req.referenceVideos ?? [];
|
|
3610
|
-
const task = req.sourceVideo ? "edit" :
|
|
3611
|
-
const
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3744
|
+
const task = req.sourceVideo ? "edit" : req.firstFrame ? "image_to_video" : images.length > 0 || videos.length > 0 ? "reference_to_video" : "text_to_video";
|
|
3745
|
+
const isOmniV1 = providerModelId === "gemini-omni-flash-preview";
|
|
3746
|
+
const responseFormat = { type: "video", delivery: "uri" };
|
|
3747
|
+
if (req.sourceVideo === void 0 && req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
3748
|
+
responseFormat.aspect_ratio = toOmniAspect(req.aspectRatio);
|
|
3749
|
+
}
|
|
3750
|
+
if (!isOmniV1) {
|
|
3751
|
+
const omniResolution = toOmniResolution(req.resolution);
|
|
3752
|
+
if (omniResolution !== void 0) responseFormat.resolution = omniResolution;
|
|
3753
|
+
}
|
|
3754
|
+
if (req.durationSeconds !== void 0) responseFormat.duration = `${req.durationSeconds}s`;
|
|
3616
3755
|
const client2 = createGenAIClient({ apiKey });
|
|
3617
3756
|
const uploadedByUri = /* @__PURE__ */ new Map();
|
|
3618
3757
|
const uploadedNames = [];
|
|
@@ -3636,7 +3775,8 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3636
3775
|
model: providerModelId,
|
|
3637
3776
|
input,
|
|
3638
3777
|
response_format: responseFormat,
|
|
3639
|
-
generation_config: { video_config: { task } }
|
|
3778
|
+
generation_config: { video_config: { task } },
|
|
3779
|
+
store: true
|
|
3640
3780
|
});
|
|
3641
3781
|
const createRetryOptions = { attempts: 3 };
|
|
3642
3782
|
if (ctx.signal !== void 0) createRetryOptions.signal = ctx.signal;
|
|
@@ -3718,23 +3858,14 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3718
3858
|
};
|
|
3719
3859
|
return inline;
|
|
3720
3860
|
});
|
|
3721
|
-
const inlineRetryOptions = { attempts: 3 };
|
|
3722
|
-
if (ctx.signal !== void 0) inlineRetryOptions.signal = ctx.signal;
|
|
3723
3861
|
try {
|
|
3724
|
-
interaction = await
|
|
3725
|
-
try {
|
|
3726
|
-
return await callCreate(inlineParts);
|
|
3727
|
-
} catch (inlineCause) {
|
|
3728
|
-
throwSdkError(inlineCause, modelId);
|
|
3729
|
-
}
|
|
3730
|
-
}, inlineRetryOptions);
|
|
3862
|
+
interaction = await callCreate(inlineParts);
|
|
3731
3863
|
} catch (inlineCause) {
|
|
3732
3864
|
throwSdkError(inlineCause, modelId);
|
|
3733
3865
|
}
|
|
3734
3866
|
}
|
|
3735
|
-
}
|
|
3867
|
+
} finally {
|
|
3736
3868
|
await cleanupUploads();
|
|
3737
|
-
throw cause;
|
|
3738
3869
|
}
|
|
3739
3870
|
const jobId = interaction.id ?? "gemini-omni-interaction";
|
|
3740
3871
|
const usage2 = videoUsage2(ctx, req, duration);
|
|
@@ -3763,47 +3894,43 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
3763
3894
|
timeoutMs: opts?.timeoutMs ?? RESULT_TIMEOUT_MS2
|
|
3764
3895
|
};
|
|
3765
3896
|
if (signal !== void 0) pollOptions.signal = signal;
|
|
3766
|
-
|
|
3767
|
-
const
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
);
|
|
3778
|
-
}
|
|
3779
|
-
return void 0;
|
|
3780
|
-
}, pollOptions);
|
|
3781
|
-
const video = extractOmniVideo(done, modelId);
|
|
3782
|
-
if (video.data) {
|
|
3783
|
-
return {
|
|
3784
|
-
video: {
|
|
3785
|
-
bytes: Buffer.from(video.data, "base64"),
|
|
3786
|
-
mime: video.mime_type ?? "video/mp4"
|
|
3787
|
-
},
|
|
3788
|
-
usage: usage2,
|
|
3789
|
-
raw: done
|
|
3790
|
-
};
|
|
3897
|
+
const done = await pollUntil(async () => {
|
|
3898
|
+
const current = await getInteraction();
|
|
3899
|
+
const status = (current.status ?? "").toUpperCase();
|
|
3900
|
+
if (status === "COMPLETED") return current;
|
|
3901
|
+
if (status === "FAILED") {
|
|
3902
|
+
throw classifyHttpError(
|
|
3903
|
+
void 0,
|
|
3904
|
+
`Gemini Omni interaction failed: ${JSON.stringify(current).slice(0, 500)}`,
|
|
3905
|
+
"google-genai",
|
|
3906
|
+
modelId
|
|
3907
|
+
);
|
|
3791
3908
|
}
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
} finally {
|
|
3805
|
-
await cleanupUploads();
|
|
3909
|
+
return void 0;
|
|
3910
|
+
}, pollOptions);
|
|
3911
|
+
const video = extractOmniVideo(done, modelId);
|
|
3912
|
+
if (video.data) {
|
|
3913
|
+
return {
|
|
3914
|
+
video: {
|
|
3915
|
+
bytes: Buffer.from(video.data, "base64"),
|
|
3916
|
+
mime: video.mime_type ?? "video/mp4"
|
|
3917
|
+
},
|
|
3918
|
+
usage: usage2,
|
|
3919
|
+
raw: done
|
|
3920
|
+
};
|
|
3806
3921
|
}
|
|
3922
|
+
if (video.uri)
|
|
3923
|
+
return {
|
|
3924
|
+
video: await downloadVideo(ctx, video.uri, apiKey, signal),
|
|
3925
|
+
usage: usage2,
|
|
3926
|
+
raw: done
|
|
3927
|
+
};
|
|
3928
|
+
throw classifyHttpError(
|
|
3929
|
+
void 0,
|
|
3930
|
+
"No video content in Gemini Omni response",
|
|
3931
|
+
"google-genai",
|
|
3932
|
+
modelId
|
|
3933
|
+
);
|
|
3807
3934
|
}
|
|
3808
3935
|
};
|
|
3809
3936
|
}
|
|
@@ -3972,8 +4099,14 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
3972
4099
|
content.push({ type: "text", text: req.prompt });
|
|
3973
4100
|
void ctx.call.postCropToAspect;
|
|
3974
4101
|
const imageConfig = {};
|
|
3975
|
-
if (req.aspectRatio !== void 0
|
|
4102
|
+
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive")
|
|
4103
|
+
imageConfig.aspectRatio = req.aspectRatio;
|
|
3976
4104
|
if (req.size !== void 0) imageConfig.imageSize = req.size;
|
|
4105
|
+
const googleOptions = {
|
|
4106
|
+
imageConfig,
|
|
4107
|
+
responseModalities: ["IMAGE"]
|
|
4108
|
+
};
|
|
4109
|
+
if (req.safetySettings !== void 0) googleOptions.safetySettings = req.safetySettings;
|
|
3977
4110
|
const retryOptions = {};
|
|
3978
4111
|
if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
|
|
3979
4112
|
const result = await withRetry(async () => {
|
|
@@ -3985,22 +4118,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
3985
4118
|
messages: [{ role: "user", content }],
|
|
3986
4119
|
maxRetries: 0,
|
|
3987
4120
|
providerOptions: {
|
|
3988
|
-
google:
|
|
3989
|
-
imageConfig,
|
|
3990
|
-
responseModalities: ["IMAGE"],
|
|
3991
|
-
safetySettings: [
|
|
3992
|
-
{
|
|
3993
|
-
category: "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
|
3994
|
-
threshold: "OFF"
|
|
3995
|
-
},
|
|
3996
|
-
{ category: "HARM_CATEGORY_HATE_SPEECH", threshold: "OFF" },
|
|
3997
|
-
{
|
|
3998
|
-
category: "HARM_CATEGORY_DANGEROUS_CONTENT",
|
|
3999
|
-
threshold: "OFF"
|
|
4000
|
-
},
|
|
4001
|
-
{ category: "HARM_CATEGORY_HARASSMENT", threshold: "OFF" }
|
|
4002
|
-
]
|
|
4003
|
-
}
|
|
4121
|
+
google: googleOptions
|
|
4004
4122
|
},
|
|
4005
4123
|
abortSignal: signal
|
|
4006
4124
|
});
|
|
@@ -4187,6 +4305,7 @@ var KLING_MAX_INTERVAL_MS = 1e4;
|
|
|
4187
4305
|
var KLING_TIMEOUT_MS = 15 * 6e4;
|
|
4188
4306
|
var DOP_INTERVAL_MS = 5e3;
|
|
4189
4307
|
var DOP_TIMEOUT_MS = 5 * 6e4;
|
|
4308
|
+
var DOP_FALLBACK_DURATION_SECONDS = 5;
|
|
4190
4309
|
var DEFAULT_NEGATIVE_PROMPT = "text, watermark, copyright, blur, low quality, distortion, abstract, weird, deformed";
|
|
4191
4310
|
function credentials(ctx) {
|
|
4192
4311
|
const key = ctx.keys.higgsfield;
|
|
@@ -4261,6 +4380,18 @@ function requestInit(ctx, init) {
|
|
|
4261
4380
|
if (ctx.signal !== void 0) request.signal = ctx.signal;
|
|
4262
4381
|
return request;
|
|
4263
4382
|
}
|
|
4383
|
+
async function createRequest(ctx, url, init) {
|
|
4384
|
+
let res;
|
|
4385
|
+
try {
|
|
4386
|
+
res = await ctx.fetch(url, requestInit(ctx, init));
|
|
4387
|
+
} catch (cause) {
|
|
4388
|
+
throw classifyThrown("higgsfield", cause, ctx.model.id);
|
|
4389
|
+
}
|
|
4390
|
+
if (!res.ok) {
|
|
4391
|
+
throw classifyHttpError(res.status, await readBody2(res), "higgsfield", ctx.model.id);
|
|
4392
|
+
}
|
|
4393
|
+
return res;
|
|
4394
|
+
}
|
|
4264
4395
|
async function generateKlingVideo(req, ctx) {
|
|
4265
4396
|
const firstFrame = req.firstFrame ? refToUrl2(req.firstFrame) : void 0;
|
|
4266
4397
|
if (!firstFrame) {
|
|
@@ -4279,26 +4410,16 @@ async function generateKlingVideo(req, ctx) {
|
|
|
4279
4410
|
negative_prompt: req.negativePrompt ?? DEFAULT_NEGATIVE_PROMPT
|
|
4280
4411
|
};
|
|
4281
4412
|
if (req.durationSeconds !== void 0) body.duration = req.durationSeconds;
|
|
4282
|
-
if (req.aspectRatio !== void 0
|
|
4413
|
+
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive")
|
|
4414
|
+
body.aspect_ratio = req.aspectRatio;
|
|
4283
4415
|
if (req.lastFrame) body.last_image_url = refToUrl2(req.lastFrame);
|
|
4284
4416
|
const endpoint = klingEndpoint(ctx.model.providerModelId);
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
} catch (cause) {
|
|
4292
|
-
throw networkError(cause, ctx);
|
|
4293
|
-
}
|
|
4294
|
-
if (!createRes.ok) {
|
|
4295
|
-
throw classifyHttpError(
|
|
4296
|
-
createRes.status,
|
|
4297
|
-
await readBody2(createRes),
|
|
4298
|
-
"higgsfield",
|
|
4299
|
-
ctx.model.id
|
|
4300
|
-
);
|
|
4301
|
-
}
|
|
4417
|
+
const retryOptions = {};
|
|
4418
|
+
if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
|
|
4419
|
+
const createRes = await withRetry(
|
|
4420
|
+
() => createRequest(ctx, endpoint, { method: "POST", body: JSON.stringify(body) }),
|
|
4421
|
+
retryOptions
|
|
4422
|
+
);
|
|
4302
4423
|
const created = klingCreateSchema.safeParse(await createRes.json());
|
|
4303
4424
|
if (!created.success) {
|
|
4304
4425
|
throw new ModelKitError({
|
|
@@ -4378,11 +4499,6 @@ async function generateKlingVideo(req, ctx) {
|
|
|
4378
4499
|
}
|
|
4379
4500
|
};
|
|
4380
4501
|
}
|
|
4381
|
-
function networkError(cause, ctx) {
|
|
4382
|
-
if (isModelKitError(cause)) return cause;
|
|
4383
|
-
const info = describeThrown(cause);
|
|
4384
|
-
return classifyHttpError(info.status, info.body, "higgsfield", ctx.model.id);
|
|
4385
|
-
}
|
|
4386
4502
|
var dopMotionOptionsSchema = z10.object({
|
|
4387
4503
|
modelkit: z10.object({ motion: z10.string().optional() }).optional()
|
|
4388
4504
|
});
|
|
@@ -4454,26 +4570,15 @@ async function generateDopVideo(req, ctx) {
|
|
|
4454
4570
|
params.input_images_end = [{ type: "image_url", image_url: refToUrl2(req.lastFrame) }];
|
|
4455
4571
|
}
|
|
4456
4572
|
if (req.seed !== void 0) params.seed = req.seed;
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
} catch (cause) {
|
|
4467
|
-
throw networkError(cause, ctx);
|
|
4468
|
-
}
|
|
4469
|
-
if (!createRes.ok) {
|
|
4470
|
-
throw classifyHttpError(
|
|
4471
|
-
createRes.status,
|
|
4472
|
-
await readBody2(createRes),
|
|
4473
|
-
"higgsfield",
|
|
4474
|
-
ctx.model.id
|
|
4475
|
-
);
|
|
4476
|
-
}
|
|
4573
|
+
const retryOptions = {};
|
|
4574
|
+
if (ctx.signal !== void 0) retryOptions.signal = ctx.signal;
|
|
4575
|
+
const createRes = await withRetry(
|
|
4576
|
+
() => createRequest(ctx, DOP_ENDPOINT, {
|
|
4577
|
+
method: "POST",
|
|
4578
|
+
body: JSON.stringify({ params, webhook: null })
|
|
4579
|
+
}),
|
|
4580
|
+
retryOptions
|
|
4581
|
+
);
|
|
4477
4582
|
const created = dopCreateSchema.safeParse(await createRes.json());
|
|
4478
4583
|
if (!created.success) {
|
|
4479
4584
|
throw new ModelKitError({
|
|
@@ -4542,7 +4647,10 @@ async function generateDopVideo(req, ctx) {
|
|
|
4542
4647
|
};
|
|
4543
4648
|
if (dopSignal !== void 0) pollSettings.signal = dopSignal;
|
|
4544
4649
|
const url = await pollUntil(check, pollSettings);
|
|
4545
|
-
const result = {
|
|
4650
|
+
const result = {
|
|
4651
|
+
video: { url },
|
|
4652
|
+
usage: videoUsage3(ctx, req, req.durationSeconds ?? DOP_FALLBACK_DURATION_SECONDS)
|
|
4653
|
+
};
|
|
4546
4654
|
return result;
|
|
4547
4655
|
}
|
|
4548
4656
|
};
|
|
@@ -4724,28 +4832,16 @@ var openaiImageAdapter = {
|
|
|
4724
4832
|
const usageParsed = openaiUsageSchema.safeParse(response.usage);
|
|
4725
4833
|
const inputTokens = usageParsed.success ? usageParsed.data.input_tokens : void 0;
|
|
4726
4834
|
const outputTokens = usageParsed.success ? usageParsed.data.output_tokens : void 0;
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
if (inputTokens !== void 0) usage2.inputTokens = inputTokens;
|
|
4738
|
-
if (outputTokens !== void 0) usage2.outputTokens = outputTokens;
|
|
4739
|
-
} else {
|
|
4740
|
-
usage2 = {
|
|
4741
|
-
model: ctx.model.id,
|
|
4742
|
-
provider: "openai-image",
|
|
4743
|
-
modality: "IMAGE",
|
|
4744
|
-
unit: "images",
|
|
4745
|
-
quantity: images.length,
|
|
4746
|
-
imageQuality: quality
|
|
4747
|
-
};
|
|
4748
|
-
}
|
|
4835
|
+
const usage2 = {
|
|
4836
|
+
model: ctx.model.id,
|
|
4837
|
+
provider: "openai-image",
|
|
4838
|
+
modality: "IMAGE",
|
|
4839
|
+
unit: "images",
|
|
4840
|
+
quantity: images.length,
|
|
4841
|
+
imageQuality: quality
|
|
4842
|
+
};
|
|
4843
|
+
if (inputTokens !== void 0) usage2.inputTokens = inputTokens;
|
|
4844
|
+
if (outputTokens !== void 0) usage2.outputTokens = outputTokens;
|
|
4749
4845
|
if (req.size !== void 0) usage2.imageSize = req.size;
|
|
4750
4846
|
return { images, usage: usage2, raw: response };
|
|
4751
4847
|
}
|
|
@@ -4798,7 +4894,12 @@ var NANO_BANANA_RATIOS = /* @__PURE__ */ new Set([
|
|
|
4798
4894
|
]);
|
|
4799
4895
|
async function refToBytes(ctx, ref) {
|
|
4800
4896
|
if ("bytes" in ref) return { bytes: ref.bytes, mime: ref.mime };
|
|
4801
|
-
|
|
4897
|
+
let res;
|
|
4898
|
+
try {
|
|
4899
|
+
res = await ctx.fetch(ref.url);
|
|
4900
|
+
} catch (cause) {
|
|
4901
|
+
throw classifyThrown("prodia", cause, ctx.model.id);
|
|
4902
|
+
}
|
|
4802
4903
|
if (!res.ok) {
|
|
4803
4904
|
const text2 = await res.text().catch(() => "");
|
|
4804
4905
|
throw classifyHttpError(res.status, text2, "prodia", ctx.model.id);
|
|
@@ -4968,8 +5069,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4968
5069
|
body: form
|
|
4969
5070
|
});
|
|
4970
5071
|
} catch (err) {
|
|
4971
|
-
|
|
4972
|
-
throw transportError("prodia", err, ctx.model.id);
|
|
5072
|
+
throw classifyThrown("prodia", err, ctx.model.id);
|
|
4973
5073
|
}
|
|
4974
5074
|
if (!attemptRes.ok) {
|
|
4975
5075
|
const text2 = await attemptRes.text().catch(() => "");
|
|
@@ -4978,8 +5078,7 @@ async function generateProdiaImage(req, ctx) {
|
|
|
4978
5078
|
return attemptRes;
|
|
4979
5079
|
}, retryOpts);
|
|
4980
5080
|
} catch (err) {
|
|
4981
|
-
|
|
4982
|
-
throw transportError("prodia", err, ctx.model.id);
|
|
5081
|
+
throw classifyThrown("prodia", err, ctx.model.id);
|
|
4983
5082
|
}
|
|
4984
5083
|
const bytes = parseImageResponse(
|
|
4985
5084
|
new Uint8Array(await res.arrayBuffer()),
|
|
@@ -5051,7 +5150,7 @@ function replicateError(cause, ctx) {
|
|
|
5051
5150
|
const info = describeThrown(cause);
|
|
5052
5151
|
const nested = replicateResponseStatusSchema.safeParse(cause);
|
|
5053
5152
|
const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
|
|
5054
|
-
return
|
|
5153
|
+
return classifyThrown("replicate", cause, ctx.model.id, { status, body: info.body });
|
|
5055
5154
|
}
|
|
5056
5155
|
function isLower(id) {
|
|
5057
5156
|
return id.toLowerCase();
|
|
@@ -5361,7 +5460,7 @@ function klingInput(req) {
|
|
|
5361
5460
|
input.start_image = startImage;
|
|
5362
5461
|
const endImage = images[1];
|
|
5363
5462
|
if (endImage !== void 0) input.end_image = endImage;
|
|
5364
|
-
} else {
|
|
5463
|
+
} else if (req.aspectRatio !== "adaptive") {
|
|
5365
5464
|
input.aspect_ratio = req.aspectRatio ?? "16:9";
|
|
5366
5465
|
}
|
|
5367
5466
|
if (req.negativePrompt !== void 0) input.negative_prompt = req.negativePrompt;
|
|
@@ -5381,7 +5480,7 @@ function klingOmniInput(req) {
|
|
|
5381
5480
|
input.start_image = startImage;
|
|
5382
5481
|
const endImage = images[1];
|
|
5383
5482
|
if (endImage !== void 0) input.end_image = endImage;
|
|
5384
|
-
} else {
|
|
5483
|
+
} else if (req.aspectRatio !== "adaptive") {
|
|
5385
5484
|
input.aspect_ratio = req.aspectRatio ?? "16:9";
|
|
5386
5485
|
}
|
|
5387
5486
|
const refs = (req.referenceImages ?? []).map(refToUrl3);
|
|
@@ -5590,11 +5689,10 @@ var xaiResponseStatusSchema = z13.object({
|
|
|
5590
5689
|
response: z13.object({ status: z13.number() }).partial()
|
|
5591
5690
|
});
|
|
5592
5691
|
function xaiError(cause, ctx) {
|
|
5593
|
-
if (isModelKitError(cause)) return cause;
|
|
5594
5692
|
const info = describeThrown(cause);
|
|
5595
5693
|
const nested = xaiResponseStatusSchema.safeParse(cause);
|
|
5596
5694
|
const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
|
|
5597
|
-
return
|
|
5695
|
+
return classifyThrown("xai-video", cause, ctx.model.id, { status, body: info.body });
|
|
5598
5696
|
}
|
|
5599
5697
|
var xaiMetaSchema = z13.object({
|
|
5600
5698
|
videoUrl: JsonValueSchema.optional(),
|
|
@@ -5618,10 +5716,7 @@ async function generateXaiVideo(req, ctx, deps) {
|
|
|
5618
5716
|
retryable: false
|
|
5619
5717
|
});
|
|
5620
5718
|
}
|
|
5621
|
-
const
|
|
5622
|
-
(r) => r !== void 0
|
|
5623
|
-
);
|
|
5624
|
-
const refUrls = frames.map(refToUrl4).slice(0, 5);
|
|
5719
|
+
const refUrls = (req.referenceImages ?? []).map(refToUrl4).slice(0, 7);
|
|
5625
5720
|
const resolution = req.resolution === "480p" ? "480p" : "720p";
|
|
5626
5721
|
const xaiOptions = {
|
|
5627
5722
|
resolution,
|
|
@@ -5632,13 +5727,23 @@ async function generateXaiVideo(req, ctx, deps) {
|
|
|
5632
5727
|
xaiOptions.mode = "reference-to-video";
|
|
5633
5728
|
xaiOptions.referenceImageUrls = refUrls;
|
|
5634
5729
|
}
|
|
5730
|
+
if (req.lastFrame !== void 0) {
|
|
5731
|
+
ctx.warnings.push({
|
|
5732
|
+
code: "option_ignored",
|
|
5733
|
+
field: "lastFrame",
|
|
5734
|
+
message: "xai-video does not support lastFrame; ignored"
|
|
5735
|
+
});
|
|
5736
|
+
}
|
|
5635
5737
|
const client2 = deps.createXaiClient({ apiKey });
|
|
5636
|
-
const model = createXai2({ apiKey }).video(ctx.model.providerModelId);
|
|
5738
|
+
const model = createXai2({ apiKey, fetch: ctx.fetch }).video(ctx.model.providerModelId);
|
|
5637
5739
|
const callBody = {
|
|
5638
5740
|
model,
|
|
5639
5741
|
prompt: req.prompt,
|
|
5640
5742
|
providerOptions: { xai: xaiOptions }
|
|
5641
5743
|
};
|
|
5744
|
+
if (req.firstFrame) {
|
|
5745
|
+
callBody.frameImages = [{ image: refToUrl4(req.firstFrame), frameType: "first_frame" }];
|
|
5746
|
+
}
|
|
5642
5747
|
if (req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
5643
5748
|
callBody.aspectRatio = req.aspectRatio;
|
|
5644
5749
|
}
|
|
@@ -5724,26 +5829,14 @@ async function mapResult(ctx, req, result) {
|
|
|
5724
5829
|
function usage(ctx, req, meta) {
|
|
5725
5830
|
const costTicks = z13.number().safeParse(meta.costInUsdTicks);
|
|
5726
5831
|
const cost = costTicks.success ? costTicks.data / 1e10 : void 0;
|
|
5727
|
-
if (cost !== void 0) {
|
|
5728
|
-
const event2 = {
|
|
5729
|
-
model: ctx.model.id,
|
|
5730
|
-
provider: "xai-video",
|
|
5731
|
-
modality: "VIDEO",
|
|
5732
|
-
unit: "reported_cost_usd",
|
|
5733
|
-
quantity: cost,
|
|
5734
|
-
reportedCostUsd: cost
|
|
5735
|
-
};
|
|
5736
|
-
if (req.durationSeconds !== void 0) event2.durationSeconds = req.durationSeconds;
|
|
5737
|
-
if (req.resolution !== void 0) event2.resolution = req.resolution;
|
|
5738
|
-
return event2;
|
|
5739
|
-
}
|
|
5740
5832
|
const event = {
|
|
5741
5833
|
model: ctx.model.id,
|
|
5742
5834
|
provider: "xai-video",
|
|
5743
5835
|
modality: "VIDEO",
|
|
5744
|
-
unit: "
|
|
5745
|
-
quantity:
|
|
5836
|
+
unit: "reported_cost_usd",
|
|
5837
|
+
quantity: cost ?? 0
|
|
5746
5838
|
};
|
|
5839
|
+
if (cost !== void 0) event.reportedCostUsd = cost;
|
|
5747
5840
|
if (req.durationSeconds !== void 0) event.durationSeconds = req.durationSeconds;
|
|
5748
5841
|
if (req.resolution !== void 0) event.resolution = req.resolution;
|
|
5749
5842
|
return event;
|