@shop-os/modelkit 0.2.27 → 0.3.1
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/CHANGELOG.md +31 -0
- package/README.md +23 -4
- package/dist/catalog.cjs +314 -19
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +158 -2
- package/dist/catalog.d.ts +158 -2
- package/dist/catalog.js +314 -19
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +811 -260
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +195 -2
- package/dist/index.d.ts +195 -2
- package/dist/index.js +806 -260
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1304,6 +1304,11 @@ var NEGATIVE_PROMPT = "blur, distort, and low quality";
|
|
|
1304
1304
|
var FRAMES_EXCLUDE_REFERENCES = { framesExcludeReferences: true };
|
|
1305
1305
|
var KLING_PROMPT = { referenceSyntax: "numbered", maxChars: 2500 };
|
|
1306
1306
|
var SEEDANCE_PROMPT = { referenceSyntax: "numbered", maxChars: 3e4 };
|
|
1307
|
+
var SEEDANCE_2_AUDIO = {
|
|
1308
|
+
audioSeconds: { min: 2, max: 15, total: 15 },
|
|
1309
|
+
audioFormats: ["wav", "mp3"],
|
|
1310
|
+
audioMaxBytes: 15 * 1024 * 1024
|
|
1311
|
+
};
|
|
1307
1312
|
var H3_PROMPT = { referenceSyntax: "numbered", maxChars: 5e4 };
|
|
1308
1313
|
var OMNI_PROMPT = { referenceSyntax: "caption", maxChars: 5e4 };
|
|
1309
1314
|
var BYTEDANCE_LOGO = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/3bba5d81-4e57-4e71-911b-cdfa05acca2c_compressed.png";
|
|
@@ -1440,7 +1445,7 @@ var VIDEO_MODELS = [
|
|
|
1440
1445
|
description: "Google's conversational video model with native audio, human support, and natural language editing. Aspect ratio only \u2014 resolution and duration are model-determined.",
|
|
1441
1446
|
logo: GOOGLE_LOGO2
|
|
1442
1447
|
},
|
|
1443
|
-
capabilities: { acceptsSourceVideo: true }
|
|
1448
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: true }
|
|
1444
1449
|
},
|
|
1445
1450
|
{
|
|
1446
1451
|
id: "gemini-omni-1.1-flash",
|
|
@@ -1465,7 +1470,7 @@ var VIDEO_MODELS = [
|
|
|
1465
1470
|
// with a video task, so those calls carry the prompt alone).
|
|
1466
1471
|
// First-to-last-frame interpolation: `<LAST_FRAME>` goes with `<FIRST_FRAME>`.
|
|
1467
1472
|
supports: ["videoExtension", "lastFrame"],
|
|
1468
|
-
extension: { segmentSeconds: 10, maxTotalSeconds: 40 },
|
|
1473
|
+
extension: { segmentSeconds: 10, maxTotalSeconds: 40, returns: "joined" },
|
|
1469
1474
|
prompt: OMNI_PROMPT,
|
|
1470
1475
|
audio: "always"
|
|
1471
1476
|
},
|
|
@@ -1477,7 +1482,11 @@ var VIDEO_MODELS = [
|
|
|
1477
1482
|
logo: GOOGLE_LOGO2,
|
|
1478
1483
|
description: "Google Gemini Omni Flash 1.1 conversational video generation, editing and extension; text, image, and up to 10-second video input, 3-10 second output at up to 4K and 24 FPS, extendable to 40 seconds."
|
|
1479
1484
|
},
|
|
1480
|
-
capabilities: {
|
|
1485
|
+
capabilities: {
|
|
1486
|
+
acceptsSourceVideo: true,
|
|
1487
|
+
videoEdit: true,
|
|
1488
|
+
lastFrameRequiresFirstFrame: true
|
|
1489
|
+
}
|
|
1481
1490
|
},
|
|
1482
1491
|
{
|
|
1483
1492
|
// vibe-triggers and Space Builder drop the ratio when a frame is wired; Cowork always sends it.
|
|
@@ -1499,7 +1508,8 @@ var VIDEO_MODELS = [
|
|
|
1499
1508
|
videos: 3,
|
|
1500
1509
|
audios: 3,
|
|
1501
1510
|
audioOnly: false,
|
|
1502
|
-
videoSeconds: { min: 2, max: 15, total: 15 }
|
|
1511
|
+
videoSeconds: { min: 2, max: 15, total: 15 },
|
|
1512
|
+
...SEEDANCE_2_AUDIO
|
|
1503
1513
|
},
|
|
1504
1514
|
sourceVideoSeconds: { min: 2, max: 15, inReferenceTotal: true },
|
|
1505
1515
|
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
@@ -1521,7 +1531,7 @@ var VIDEO_MODELS = [
|
|
|
1521
1531
|
description: "High-quality AI video generation with reference image conditioning. Supports 4-15 second clips with human preprocessing.",
|
|
1522
1532
|
logo: BYTEDANCE_LOGO
|
|
1523
1533
|
},
|
|
1524
|
-
capabilities: { acceptsSourceVideo: true, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1534
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: false, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1525
1535
|
},
|
|
1526
1536
|
{
|
|
1527
1537
|
id: "seedance-2.0-fast",
|
|
@@ -1541,7 +1551,8 @@ var VIDEO_MODELS = [
|
|
|
1541
1551
|
videos: 3,
|
|
1542
1552
|
audios: 3,
|
|
1543
1553
|
audioOnly: false,
|
|
1544
|
-
videoSeconds: { min: 2, max: 15, total: 15 }
|
|
1554
|
+
videoSeconds: { min: 2, max: 15, total: 15 },
|
|
1555
|
+
...SEEDANCE_2_AUDIO
|
|
1545
1556
|
},
|
|
1546
1557
|
sourceVideoSeconds: { min: 2, max: 15, inReferenceTotal: true },
|
|
1547
1558
|
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
@@ -1563,7 +1574,7 @@ var VIDEO_MODELS = [
|
|
|
1563
1574
|
logo: BYTEDANCE_LOGO,
|
|
1564
1575
|
description: "Speed- and cost-optimized ByteDance Seedance 2.0 Fast; text plus image, video, and audio references to generate or edit 4-15 second clips."
|
|
1565
1576
|
},
|
|
1566
|
-
capabilities: { acceptsSourceVideo: true, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1577
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: false, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1567
1578
|
},
|
|
1568
1579
|
{
|
|
1569
1580
|
// omni_reference_task_type edit/extend: adaptive ratio, edit sends duration -1.
|
|
@@ -1583,12 +1594,20 @@ var VIDEO_MODELS = [
|
|
|
1583
1594
|
images: 30,
|
|
1584
1595
|
videos: 10,
|
|
1585
1596
|
audios: 10,
|
|
1586
|
-
videoSeconds: { min: 2, max: 30, total: 30, editMin: 4 }
|
|
1597
|
+
videoSeconds: { min: 2, max: 30, total: 30, editMin: 4 },
|
|
1598
|
+
// BytePlus: 2-30 s per clip, 30 s in all, wav/mp3, 15 MB each.
|
|
1599
|
+
audioSeconds: { min: 2, max: 30, total: 30 },
|
|
1600
|
+
audioFormats: ["wav", "mp3"],
|
|
1601
|
+
audioMaxBytes: 15 * 1024 * 1024
|
|
1587
1602
|
},
|
|
1588
1603
|
sourceVideoSeconds: { min: 2, max: 30, editMin: 4, inReferenceTotal: true },
|
|
1589
1604
|
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
1590
1605
|
// No seed: 2.x echoes it but does not honour it (two seeded runs differed, 2026-10-01).
|
|
1591
|
-
supports: ["generateAudio", "lastFrame", "watermark", "taskType"],
|
|
1606
|
+
supports: ["generateAudio", "lastFrame", "watermark", "taskType", "videoExtension"],
|
|
1607
|
+
// Extend (probe 2026-10-02, 480p): returns ONLY the added footage, continuing from
|
|
1608
|
+
// the source's last frame at the source's framing and fps but at the requested
|
|
1609
|
+
// resolution, so the caller joins the clips. Forward only in practice.
|
|
1610
|
+
extension: { segmentSeconds: 30, maxTotalSeconds: 60, returns: "new" },
|
|
1592
1611
|
prompt: SEEDANCE_PROMPT,
|
|
1593
1612
|
audio: "optional"
|
|
1594
1613
|
},
|
|
@@ -1605,7 +1624,7 @@ var VIDEO_MODELS = [
|
|
|
1605
1624
|
logo: BYTEDANCE_LOGO,
|
|
1606
1625
|
description: "ByteDance Seedance 2.5 for long-form storytelling and omni-reference generation/editing; up to 50 reference assets and 4-30 second clips at up to 1080p."
|
|
1607
1626
|
},
|
|
1608
|
-
capabilities: { acceptsSourceVideo: true, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1627
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: true, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1609
1628
|
},
|
|
1610
1629
|
{
|
|
1611
1630
|
id: "grok-imagine",
|
|
@@ -1969,11 +1988,116 @@ var VIDEO_MODELS = [
|
|
|
1969
1988
|
}
|
|
1970
1989
|
];
|
|
1971
1990
|
|
|
1991
|
+
// src/catalog/video-tools.ts
|
|
1992
|
+
var TOPAZ_LOGO = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/topazlabs.png";
|
|
1993
|
+
var TOPAZ_SOURCE_SECONDS = { max: 300 };
|
|
1994
|
+
var TOPAZ_USAGE = { unit: "seconds" };
|
|
1995
|
+
var VIDEO_TOOL_MODELS = [
|
|
1996
|
+
{
|
|
1997
|
+
id: "topaz-precision",
|
|
1998
|
+
aliases: [],
|
|
1999
|
+
label: "Topaz Precision",
|
|
2000
|
+
type: "video-tool",
|
|
2001
|
+
adapter: "fal",
|
|
2002
|
+
providerModelId: "topaz/upscale/video/precision",
|
|
2003
|
+
lifecycle: "active",
|
|
2004
|
+
exposure: ["cowork"],
|
|
2005
|
+
constraints: {
|
|
2006
|
+
supports: [],
|
|
2007
|
+
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
2008
|
+
tool: { kind: "upscale", upscaleFactor: { min: 1, max: 4 }, maxOutputLongEdge: 3840 }
|
|
2009
|
+
},
|
|
2010
|
+
defaults: {},
|
|
2011
|
+
providerOptions: { fal: { model: "Proteus" } },
|
|
2012
|
+
usage: TOPAZ_USAGE,
|
|
2013
|
+
pricingKind: "video_per_second",
|
|
2014
|
+
display: {
|
|
2015
|
+
provider: "topaz",
|
|
2016
|
+
logo: TOPAZ_LOGO,
|
|
2017
|
+
description: "Topaz Proteus upscaling: sharper, cleaner footage up to 4K while staying faithful to the source.",
|
|
2018
|
+
sortOrder: 20
|
|
2019
|
+
}
|
|
2020
|
+
},
|
|
2021
|
+
{
|
|
2022
|
+
id: "topaz-starlight",
|
|
2023
|
+
aliases: [],
|
|
2024
|
+
label: "Topaz Starlight",
|
|
2025
|
+
type: "video-tool",
|
|
2026
|
+
adapter: "fal",
|
|
2027
|
+
providerModelId: "topaz/upscale/video/generative",
|
|
2028
|
+
lifecycle: "active",
|
|
2029
|
+
exposure: ["cowork"],
|
|
2030
|
+
constraints: {
|
|
2031
|
+
supports: [],
|
|
2032
|
+
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
2033
|
+
tool: { kind: "upscale", upscaleFactor: { min: 1, max: 4 }, maxOutputLongEdge: 3840 }
|
|
2034
|
+
},
|
|
2035
|
+
defaults: {},
|
|
2036
|
+
providerOptions: { fal: { model: "Starlight Precise 2.6" } },
|
|
2037
|
+
usage: TOPAZ_USAGE,
|
|
2038
|
+
pricingKind: "video_per_second",
|
|
2039
|
+
display: {
|
|
2040
|
+
provider: "topaz",
|
|
2041
|
+
logo: TOPAZ_LOGO,
|
|
2042
|
+
description: "Topaz Starlight Precise 2.6: generative upscaling that rebuilds fine detail, up to 4K. Slower and costlier than Precision.",
|
|
2043
|
+
sortOrder: 10
|
|
2044
|
+
}
|
|
2045
|
+
},
|
|
2046
|
+
{
|
|
2047
|
+
id: "topaz-apollo",
|
|
2048
|
+
aliases: [],
|
|
2049
|
+
label: "Topaz Apollo",
|
|
2050
|
+
type: "video-tool",
|
|
2051
|
+
adapter: "fal",
|
|
2052
|
+
providerModelId: "topaz/interpolate/video",
|
|
2053
|
+
lifecycle: "active",
|
|
2054
|
+
exposure: ["cowork"],
|
|
2055
|
+
constraints: {
|
|
2056
|
+
supports: [],
|
|
2057
|
+
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
2058
|
+
tool: { kind: "interpolate", fps: { min: 16, max: 120 } }
|
|
2059
|
+
},
|
|
2060
|
+
defaults: {},
|
|
2061
|
+
providerOptions: { fal: { model: "Apollo" } },
|
|
2062
|
+
usage: TOPAZ_USAGE,
|
|
2063
|
+
pricingKind: "video_per_second",
|
|
2064
|
+
display: {
|
|
2065
|
+
provider: "topaz",
|
|
2066
|
+
logo: TOPAZ_LOGO,
|
|
2067
|
+
description: "Topaz Apollo frame interpolation: smoother motion at up to 120 fps, same length as the source."
|
|
2068
|
+
}
|
|
2069
|
+
},
|
|
2070
|
+
{
|
|
2071
|
+
id: "topaz-hyperion-2.5",
|
|
2072
|
+
aliases: [],
|
|
2073
|
+
label: "Topaz Hyperion 2.5",
|
|
2074
|
+
type: "video-tool",
|
|
2075
|
+
adapter: "fal",
|
|
2076
|
+
providerModelId: "topaz/sdr-to-hdr/video",
|
|
2077
|
+
lifecycle: "active",
|
|
2078
|
+
exposure: ["cowork"],
|
|
2079
|
+
constraints: {
|
|
2080
|
+
supports: [],
|
|
2081
|
+
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
2082
|
+
tool: { kind: "hdr", outputFormats: ["h265", "prores"] }
|
|
2083
|
+
},
|
|
2084
|
+
defaults: {},
|
|
2085
|
+
usage: TOPAZ_USAGE,
|
|
2086
|
+
pricingKind: "video_per_second",
|
|
2087
|
+
display: {
|
|
2088
|
+
provider: "topaz",
|
|
2089
|
+
logo: TOPAZ_LOGO,
|
|
2090
|
+
description: "Topaz Hyperion 2.5 SDR to HDR: a 10-bit HDR master in H.265 (HDR10) or ProRes 422 HQ, at the source's size and frame rate."
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
];
|
|
2094
|
+
|
|
1972
2095
|
// src/catalog/models.ts
|
|
1973
2096
|
var MODELS = [
|
|
1974
2097
|
...TEXT_MODELS,
|
|
1975
2098
|
...IMAGE_MODELS,
|
|
1976
2099
|
...VIDEO_MODELS,
|
|
2100
|
+
...VIDEO_TOOL_MODELS,
|
|
1977
2101
|
...OTHER_MODELS
|
|
1978
2102
|
];
|
|
1979
2103
|
|
|
@@ -2128,6 +2252,10 @@ var ALL_KEY_SET = /* @__PURE__ */ new Set([
|
|
|
2128
2252
|
...IMAGE_INPUT_SPEC_KEYS,
|
|
2129
2253
|
...AUDIO_INPUT_SPEC_KEYS
|
|
2130
2254
|
]);
|
|
2255
|
+
var TYPES_BY_ADAPTER = /* @__PURE__ */ new Map([
|
|
2256
|
+
["replicate", ["video", "image", "audio"]],
|
|
2257
|
+
["fal", ["image"]]
|
|
2258
|
+
]);
|
|
2131
2259
|
var ALLOWED_KEYS_BY_TYPE = /* @__PURE__ */ new Map([
|
|
2132
2260
|
["video", VIDEO_KEY_SET],
|
|
2133
2261
|
["image", IMAGE_KEY_SET],
|
|
@@ -2166,7 +2294,8 @@ var StaticSchema = z2.record(z2.string(), ProviderScalarSchema);
|
|
|
2166
2294
|
var InputSpecSchema = z2.strictObject({
|
|
2167
2295
|
fields: FieldsSchema,
|
|
2168
2296
|
values: ValuesSchema.optional(),
|
|
2169
|
-
static: StaticSchema.optional()
|
|
2297
|
+
static: StaticSchema.optional(),
|
|
2298
|
+
editEndpoint: z2.string().min(1).optional()
|
|
2170
2299
|
}).superRefine((spec, ctx) => {
|
|
2171
2300
|
const mappedNames = new Set(Object.values(spec.fields));
|
|
2172
2301
|
for (const key of Object.keys(spec.static ?? {})) {
|
|
@@ -2194,18 +2323,21 @@ function validateInputSpec(raw, row) {
|
|
|
2194
2323
|
};
|
|
2195
2324
|
}
|
|
2196
2325
|
const spec = parsed.data;
|
|
2197
|
-
|
|
2326
|
+
const supportedTypes = TYPES_BY_ADAPTER.get(row.adapter);
|
|
2327
|
+
if (supportedTypes === void 0) {
|
|
2198
2328
|
return {
|
|
2199
2329
|
ok: false,
|
|
2200
|
-
issues: [
|
|
2330
|
+
issues: [
|
|
2331
|
+
{ path: [], message: "inputSpec is only supported on replicate and fal rows" }
|
|
2332
|
+
]
|
|
2201
2333
|
};
|
|
2202
2334
|
}
|
|
2203
2335
|
const issues = [];
|
|
2204
2336
|
const allowed = ALLOWED_KEYS_BY_TYPE.get(row.type);
|
|
2205
|
-
if (allowed === void 0) {
|
|
2337
|
+
if (allowed === void 0 || !supportedTypes.includes(row.type)) {
|
|
2206
2338
|
issues.push({
|
|
2207
2339
|
path: [],
|
|
2208
|
-
message: `inputSpec is not supported for "${row.type}" rows`
|
|
2340
|
+
message: row.adapter === "fal" ? `inputSpec on fal rows is only supported for image rows, not "${row.type}"` : `inputSpec is not supported for "${row.type}" rows`
|
|
2209
2341
|
});
|
|
2210
2342
|
} else {
|
|
2211
2343
|
for (const key of Object.keys(spec.fields)) {
|
|
@@ -2225,6 +2357,19 @@ function validateInputSpec(raw, row) {
|
|
|
2225
2357
|
}
|
|
2226
2358
|
}
|
|
2227
2359
|
}
|
|
2360
|
+
if (spec.editEndpoint !== void 0) {
|
|
2361
|
+
if (row.adapter !== "fal") {
|
|
2362
|
+
issues.push({
|
|
2363
|
+
path: ["editEndpoint"],
|
|
2364
|
+
message: "inputSpec.editEndpoint is only supported on fal rows"
|
|
2365
|
+
});
|
|
2366
|
+
} else if (!("references" in spec.fields)) {
|
|
2367
|
+
issues.push({
|
|
2368
|
+
path: ["editEndpoint"],
|
|
2369
|
+
message: 'inputSpec.editEndpoint needs a "references" entry in inputSpec.fields'
|
|
2370
|
+
});
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2228
2373
|
const seenNames = /* @__PURE__ */ new Map();
|
|
2229
2374
|
for (const [key, name] of Object.entries(spec.fields)) {
|
|
2230
2375
|
const first = seenNames.get(name);
|
|
@@ -2270,7 +2415,15 @@ var ADAPTER_IDS = [
|
|
|
2270
2415
|
"higgsfield",
|
|
2271
2416
|
"xai-video"
|
|
2272
2417
|
];
|
|
2273
|
-
var ModelTypeSchema = z3.enum([
|
|
2418
|
+
var ModelTypeSchema = z3.enum([
|
|
2419
|
+
"text",
|
|
2420
|
+
"image",
|
|
2421
|
+
"video",
|
|
2422
|
+
"audio",
|
|
2423
|
+
"upscale",
|
|
2424
|
+
"bg-remove",
|
|
2425
|
+
"video-tool"
|
|
2426
|
+
]);
|
|
2274
2427
|
var LifecycleSchema = z3.enum(["active", "deprecated", "retired"]);
|
|
2275
2428
|
var SurfaceSchema = z3.enum(["cowork", "space_builder"]);
|
|
2276
2429
|
var SURFACES2 = SurfaceSchema.options;
|
|
@@ -2350,7 +2503,22 @@ var ReferenceLimitsSchema = z3.looseObject({
|
|
|
2350
2503
|
audios: z3.number().optional(),
|
|
2351
2504
|
total: z3.number().optional(),
|
|
2352
2505
|
audioOnly: z3.boolean().optional(),
|
|
2353
|
-
videoSeconds: VideoSecondsLimitsSchema.optional()
|
|
2506
|
+
videoSeconds: VideoSecondsLimitsSchema.optional(),
|
|
2507
|
+
audioSeconds: z3.looseObject({
|
|
2508
|
+
min: z3.number().optional(),
|
|
2509
|
+
max: z3.number().optional(),
|
|
2510
|
+
total: z3.number().optional()
|
|
2511
|
+
}).optional(),
|
|
2512
|
+
audioFormats: z3.array(z3.string()).optional(),
|
|
2513
|
+
audioMaxBytes: z3.number().positive().optional()
|
|
2514
|
+
});
|
|
2515
|
+
var RangeSchema = z3.looseObject({ min: z3.number(), max: z3.number() });
|
|
2516
|
+
var VideoToolConstraintsSchema = z3.looseObject({
|
|
2517
|
+
kind: z3.enum(["upscale", "interpolate", "hdr"]),
|
|
2518
|
+
upscaleFactor: RangeSchema.optional(),
|
|
2519
|
+
maxOutputLongEdge: z3.number().positive().optional(),
|
|
2520
|
+
fps: RangeSchema.optional(),
|
|
2521
|
+
outputFormats: z3.array(z3.enum(["h265", "prores"])).min(1).optional()
|
|
2354
2522
|
});
|
|
2355
2523
|
var ModelConstraintsSchema = z3.looseObject({
|
|
2356
2524
|
aspectRatios: z3.array(AspectRatioSchema).optional(),
|
|
@@ -2365,7 +2533,14 @@ var ModelConstraintsSchema = z3.looseObject({
|
|
|
2365
2533
|
supports: z3.array(SupportedOptionSchema).optional(),
|
|
2366
2534
|
ratioIgnoredWith: z3.array(z3.enum(["firstFrame", "sourceVideo"])).optional(),
|
|
2367
2535
|
sourceVideoSeconds: VideoSecondsLimitsSchema.omit({ total: true }).extend({ inReferenceTotal: z3.boolean().optional() }).optional(),
|
|
2368
|
-
|
|
2536
|
+
// segmentSeconds/maxTotalSeconds stay required: a kit before 0.3.0 drops a row whose
|
|
2537
|
+
// extension lacks them, so every extension block keeps them.
|
|
2538
|
+
extension: z3.looseObject({
|
|
2539
|
+
segmentSeconds: z3.number(),
|
|
2540
|
+
maxTotalSeconds: z3.number(),
|
|
2541
|
+
returns: z3.enum(["new", "joined"]).optional()
|
|
2542
|
+
}).optional(),
|
|
2543
|
+
tool: VideoToolConstraintsSchema.optional(),
|
|
2369
2544
|
// Loose on purpose: the read path keeps a row whose value is invalid (the accessors in
|
|
2370
2545
|
// conventions.ts read it as "not set"); CatalogModelSchema below rejects it on write.
|
|
2371
2546
|
audio: z3.unknown().optional(),
|
|
@@ -2437,6 +2612,7 @@ var CatalogDisplaySchema = z3.looseObject({
|
|
|
2437
2612
|
});
|
|
2438
2613
|
var CatalogCapabilitiesSchema = z3.looseObject({
|
|
2439
2614
|
acceptsSourceVideo: z3.boolean().optional(),
|
|
2615
|
+
videoEdit: z3.boolean().optional(),
|
|
2440
2616
|
framesExcludeReferences: z3.boolean().optional(),
|
|
2441
2617
|
lastFrameRequiresFirstFrame: z3.boolean().optional(),
|
|
2442
2618
|
reasoning: z3.boolean().optional(),
|
|
@@ -2479,6 +2655,13 @@ var CatalogModelSchemaBase = z3.looseObject({
|
|
|
2479
2655
|
message: "active text rows need contextWindow"
|
|
2480
2656
|
});
|
|
2481
2657
|
}
|
|
2658
|
+
if (row.type === "video-tool" && row.constraints.tool === void 0) {
|
|
2659
|
+
ctx.addIssue({
|
|
2660
|
+
code: "custom",
|
|
2661
|
+
path: ["constraints", "tool"],
|
|
2662
|
+
message: "video-tool rows need constraints.tool"
|
|
2663
|
+
});
|
|
2664
|
+
}
|
|
2482
2665
|
if (row.replacedBy !== void 0 && row.replacedBy === row.id) {
|
|
2483
2666
|
ctx.addIssue({
|
|
2484
2667
|
code: "custom",
|
|
@@ -3485,7 +3668,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
3485
3668
|
}
|
|
3486
3669
|
|
|
3487
3670
|
// src/adapters/fal.ts
|
|
3488
|
-
import { z as
|
|
3671
|
+
import { z as z12 } from "zod";
|
|
3489
3672
|
import { createFalClient } from "@fal-ai/client";
|
|
3490
3673
|
|
|
3491
3674
|
// src/adapters/fal-http.ts
|
|
@@ -3573,6 +3756,428 @@ function createFalHttpClient(opts) {
|
|
|
3573
3756
|
};
|
|
3574
3757
|
}
|
|
3575
3758
|
|
|
3759
|
+
// src/adapters/fal-gateway.ts
|
|
3760
|
+
import { z as z9 } from "zod";
|
|
3761
|
+
var falDetailSchema = z9.object({ detail: JsonValueSchema });
|
|
3762
|
+
function liftDetail(body) {
|
|
3763
|
+
const parsed = falDetailSchema.safeParse(body);
|
|
3764
|
+
const detail = parsed.success ? parsed.data.detail : void 0;
|
|
3765
|
+
return detail ?? body;
|
|
3766
|
+
}
|
|
3767
|
+
function falError(status, body, model) {
|
|
3768
|
+
return classifyHttpError(status, liftDetail(body), "fal", model);
|
|
3769
|
+
}
|
|
3770
|
+
function gatewayConfig(ctx) {
|
|
3771
|
+
const cf = ctx.routing.cloudflare;
|
|
3772
|
+
const falKey = ctx.keys.fal;
|
|
3773
|
+
const cfToken = ctx.keys.cloudflare;
|
|
3774
|
+
if (!cf?.accountId || !cf?.gatewayId || !falKey && !cfToken) {
|
|
3775
|
+
throw new ModelKitError({
|
|
3776
|
+
code: "auth",
|
|
3777
|
+
message: "fal passthrough is not configured. Set routing.cloudflare and FAL_KEY or the gateway token (BYOK).",
|
|
3778
|
+
provider: "fal",
|
|
3779
|
+
model: ctx.model.id,
|
|
3780
|
+
retryable: false
|
|
3781
|
+
});
|
|
3782
|
+
}
|
|
3783
|
+
const config = {
|
|
3784
|
+
baseUrl: `https://gateway.ai.cloudflare.com/v1/${cf.accountId}/${cf.gatewayId}/fal`
|
|
3785
|
+
};
|
|
3786
|
+
if (falKey) config.falKey = falKey;
|
|
3787
|
+
if (cfToken) config.cfToken = cfToken;
|
|
3788
|
+
if (ctx.call.maxRetries !== void 0) config.singleAttempt = true;
|
|
3789
|
+
if (ctx.signal !== void 0) config.signal = ctx.signal;
|
|
3790
|
+
return config;
|
|
3791
|
+
}
|
|
3792
|
+
async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
|
|
3793
|
+
const headers2 = { "x-fal-target-url": targetUrl };
|
|
3794
|
+
if (cfg.falKey) headers2.Authorization = `Bearer ${cfg.falKey}`;
|
|
3795
|
+
if (init.body) headers2["Content-Type"] = "application/json";
|
|
3796
|
+
if (cfg.cfToken) headers2["cf-aig-authorization"] = `Bearer ${cfg.cfToken}`;
|
|
3797
|
+
if (cfg.singleAttempt) headers2["cf-aig-max-attempts"] = "1";
|
|
3798
|
+
const request = { method: init.method, headers: headers2 };
|
|
3799
|
+
if (cfg.signal !== void 0) request.signal = cfg.signal;
|
|
3800
|
+
if (init.body !== void 0) request.body = init.body;
|
|
3801
|
+
return fetchImpl(cfg.baseUrl, request);
|
|
3802
|
+
}
|
|
3803
|
+
|
|
3804
|
+
// src/adapters/fal-video-tools.ts
|
|
3805
|
+
import { z as z11 } from "zod";
|
|
3806
|
+
|
|
3807
|
+
// src/catalog/video-tools-spec.ts
|
|
3808
|
+
import { z as z10 } from "zod";
|
|
3809
|
+
var RangeSchema2 = z10.object({ min: z10.number(), max: z10.number() });
|
|
3810
|
+
var ToolSchema = z10.object({
|
|
3811
|
+
kind: z10.enum(["upscale", "interpolate", "hdr"]),
|
|
3812
|
+
upscaleFactor: RangeSchema2.optional(),
|
|
3813
|
+
maxOutputLongEdge: z10.number().positive().optional(),
|
|
3814
|
+
fps: RangeSchema2.optional(),
|
|
3815
|
+
outputFormats: z10.array(z10.enum(["h265", "prores"])).min(1).optional()
|
|
3816
|
+
});
|
|
3817
|
+
function videoToolConstraints(row) {
|
|
3818
|
+
if (row.type !== "video-tool") return void 0;
|
|
3819
|
+
const parsed = ToolSchema.safeParse(row.constraints.tool);
|
|
3820
|
+
if (!parsed.success) return void 0;
|
|
3821
|
+
const { kind, upscaleFactor, maxOutputLongEdge, fps, outputFormats } = parsed.data;
|
|
3822
|
+
return {
|
|
3823
|
+
kind,
|
|
3824
|
+
...upscaleFactor !== void 0 && { upscaleFactor },
|
|
3825
|
+
...maxOutputLongEdge !== void 0 && { maxOutputLongEdge },
|
|
3826
|
+
...fps !== void 0 && { fps },
|
|
3827
|
+
...outputFormats !== void 0 && { outputFormats }
|
|
3828
|
+
};
|
|
3829
|
+
}
|
|
3830
|
+
function resolutionTier(width, height) {
|
|
3831
|
+
const shortEdge = Math.min(width, height);
|
|
3832
|
+
if (shortEdge <= 360) return "360p";
|
|
3833
|
+
if (shortEdge <= 480) return "480p";
|
|
3834
|
+
if (shortEdge <= 720) return "720p";
|
|
3835
|
+
if (shortEdge <= 1080) return "1080p";
|
|
3836
|
+
if (shortEdge <= 1440) return "2k";
|
|
3837
|
+
return "4k";
|
|
3838
|
+
}
|
|
3839
|
+
function fail(error) {
|
|
3840
|
+
return { ok: false, error };
|
|
3841
|
+
}
|
|
3842
|
+
function planVideoTool(row, req) {
|
|
3843
|
+
const tool = videoToolConstraints(row);
|
|
3844
|
+
if (!tool) return fail(`${row.id} is not a video tool`);
|
|
3845
|
+
const { width, height, durationSeconds, fps } = req.source;
|
|
3846
|
+
if (!(width > 0 && height > 0 && durationSeconds > 0)) {
|
|
3847
|
+
return fail("The source video's width, height and duration are required");
|
|
3848
|
+
}
|
|
3849
|
+
const maxSeconds = row.constraints.sourceVideoSeconds?.max;
|
|
3850
|
+
if (maxSeconds !== void 0 && durationSeconds > maxSeconds) {
|
|
3851
|
+
return fail(`${row.label} takes source videos up to ${maxSeconds} seconds.`);
|
|
3852
|
+
}
|
|
3853
|
+
const base = {
|
|
3854
|
+
durationSeconds,
|
|
3855
|
+
...fps !== void 0 && { fps }
|
|
3856
|
+
};
|
|
3857
|
+
if (tool.kind === "upscale") {
|
|
3858
|
+
const factor = req.upscaleFactor;
|
|
3859
|
+
if (factor === void 0) return fail("An upscale factor is required");
|
|
3860
|
+
const range = tool.upscaleFactor;
|
|
3861
|
+
if (range && (factor < range.min || factor > range.max)) {
|
|
3862
|
+
return fail(`${row.label} upscales by ${range.min}x to ${range.max}x.`);
|
|
3863
|
+
}
|
|
3864
|
+
const outWidth = Math.round(width * factor);
|
|
3865
|
+
const outHeight = Math.round(height * factor);
|
|
3866
|
+
const limit = tool.maxOutputLongEdge;
|
|
3867
|
+
if (limit !== void 0 && Math.max(outWidth, outHeight) > limit) {
|
|
3868
|
+
return fail(
|
|
3869
|
+
`A ${factor}x upscale of a ${width}x${height} video passes the ${limit}px limit.`
|
|
3870
|
+
);
|
|
3871
|
+
}
|
|
3872
|
+
return {
|
|
3873
|
+
ok: true,
|
|
3874
|
+
output: {
|
|
3875
|
+
...base,
|
|
3876
|
+
width: outWidth,
|
|
3877
|
+
height: outHeight,
|
|
3878
|
+
resolution: resolutionTier(outWidth, outHeight),
|
|
3879
|
+
format: "h264"
|
|
3880
|
+
}
|
|
3881
|
+
};
|
|
3882
|
+
}
|
|
3883
|
+
if (tool.kind === "interpolate") {
|
|
3884
|
+
const target = req.targetFps;
|
|
3885
|
+
if (target === void 0 || !Number.isInteger(target)) {
|
|
3886
|
+
return fail("A whole-number target frame rate is required");
|
|
3887
|
+
}
|
|
3888
|
+
const range = tool.fps;
|
|
3889
|
+
if (range && (target < range.min || target > range.max)) {
|
|
3890
|
+
return fail(`${row.label} outputs ${range.min} to ${range.max} fps.`);
|
|
3891
|
+
}
|
|
3892
|
+
return {
|
|
3893
|
+
ok: true,
|
|
3894
|
+
output: {
|
|
3895
|
+
durationSeconds,
|
|
3896
|
+
fps: target,
|
|
3897
|
+
width,
|
|
3898
|
+
height,
|
|
3899
|
+
resolution: resolutionTier(width, height),
|
|
3900
|
+
format: "h264"
|
|
3901
|
+
}
|
|
3902
|
+
};
|
|
3903
|
+
}
|
|
3904
|
+
const formats = tool.outputFormats ?? ["h265"];
|
|
3905
|
+
const format = req.outputFormat ?? formats[0] ?? "h265";
|
|
3906
|
+
if (!formats.includes(format)) {
|
|
3907
|
+
return fail(`${row.label} writes ${formats.join(" or ")}.`);
|
|
3908
|
+
}
|
|
3909
|
+
return {
|
|
3910
|
+
ok: true,
|
|
3911
|
+
output: { ...base, width, height, resolution: resolutionTier(width, height), format }
|
|
3912
|
+
};
|
|
3913
|
+
}
|
|
3914
|
+
|
|
3915
|
+
// src/adapters/fal-video-tools.ts
|
|
3916
|
+
var FAL_QUEUE_ORIGIN = "https://queue.fal.run";
|
|
3917
|
+
var queueUrlSchema = z11.url().refine((value) => new URL(value).origin === FAL_QUEUE_ORIGIN, {
|
|
3918
|
+
message: "not a fal queue URL"
|
|
3919
|
+
});
|
|
3920
|
+
var submitResponseSchema = z11.object({
|
|
3921
|
+
request_id: z11.string().min(1),
|
|
3922
|
+
status_url: queueUrlSchema,
|
|
3923
|
+
response_url: queueUrlSchema,
|
|
3924
|
+
cancel_url: queueUrlSchema
|
|
3925
|
+
});
|
|
3926
|
+
var statusResponseSchema = z11.object({ status: z11.string() });
|
|
3927
|
+
var videoFileSchema = z11.object({
|
|
3928
|
+
url: z11.url(),
|
|
3929
|
+
content_type: z11.string().nullish(),
|
|
3930
|
+
file_size: z11.number().nullish()
|
|
3931
|
+
});
|
|
3932
|
+
var toolOutputSchema = z11.object({ video: videoFileSchema });
|
|
3933
|
+
var falWebhookBodySchema = z11.object({
|
|
3934
|
+
request_id: z11.string().min(1),
|
|
3935
|
+
gateway_request_id: z11.string().nullish(),
|
|
3936
|
+
status: z11.enum(["OK", "ERROR"]),
|
|
3937
|
+
payload: JsonValueSchema.nullish(),
|
|
3938
|
+
error: z11.string().nullish(),
|
|
3939
|
+
payload_error: JsonValueSchema.nullish()
|
|
3940
|
+
});
|
|
3941
|
+
async function queueFetch(ctx, url, method, body) {
|
|
3942
|
+
const payload = body === void 0 ? void 0 : JSON.stringify(body);
|
|
3943
|
+
try {
|
|
3944
|
+
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
3945
|
+
return await gatewayFetch(gatewayConfig(ctx), ctx.fetch, url, {
|
|
3946
|
+
method,
|
|
3947
|
+
...payload !== void 0 && { body: payload }
|
|
3948
|
+
});
|
|
3949
|
+
}
|
|
3950
|
+
const falKey = ctx.keys.fal;
|
|
3951
|
+
if (!falKey) {
|
|
3952
|
+
throw new ModelKitError({
|
|
3953
|
+
code: "auth",
|
|
3954
|
+
message: "Missing API key for fal",
|
|
3955
|
+
provider: "fal",
|
|
3956
|
+
model: ctx.model.id,
|
|
3957
|
+
retryable: false
|
|
3958
|
+
});
|
|
3959
|
+
}
|
|
3960
|
+
return await ctx.fetch(url, {
|
|
3961
|
+
method,
|
|
3962
|
+
headers: {
|
|
3963
|
+
Authorization: `Key ${falKey}`,
|
|
3964
|
+
...payload !== void 0 && { "Content-Type": "application/json" }
|
|
3965
|
+
},
|
|
3966
|
+
...payload !== void 0 && { body: payload },
|
|
3967
|
+
...ctx.signal !== void 0 && { signal: ctx.signal }
|
|
3968
|
+
});
|
|
3969
|
+
} catch (cause) {
|
|
3970
|
+
if (cause instanceof ModelKitError) throw cause;
|
|
3971
|
+
throw classifyThrown("fal", cause, ctx.model.id);
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
async function readJson(ctx, res) {
|
|
3975
|
+
if (!res.ok) throw falError(res.status, await readBody(res), ctx.model.id);
|
|
3976
|
+
return JsonValueSchema.parse(await res.json());
|
|
3977
|
+
}
|
|
3978
|
+
function providerModelName(ctx) {
|
|
3979
|
+
return z11.string().safeParse(ctx.model.providerOptions?.["fal"]?.["model"]).data;
|
|
3980
|
+
}
|
|
3981
|
+
function toolInput(ctx, req, output) {
|
|
3982
|
+
const tool = videoToolConstraints(ctx.model);
|
|
3983
|
+
const model = providerModelName(ctx);
|
|
3984
|
+
const input = { video_url: req.source.url };
|
|
3985
|
+
if (tool?.kind === "upscale") {
|
|
3986
|
+
if (model !== void 0) input["model"] = model;
|
|
3987
|
+
input["upscale_factor"] = req.upscaleFactor ?? 1;
|
|
3988
|
+
input["H264_output"] = true;
|
|
3989
|
+
} else if (tool?.kind === "interpolate") {
|
|
3990
|
+
if (model !== void 0) input["model"] = model;
|
|
3991
|
+
input["target_fps"] = req.targetFps ?? 60;
|
|
3992
|
+
input["slowdown_factor"] = 1;
|
|
3993
|
+
input["H264_output"] = true;
|
|
3994
|
+
} else {
|
|
3995
|
+
input["output_format"] = output.format === "prores" ? "prores" : "mp4";
|
|
3996
|
+
}
|
|
3997
|
+
return input;
|
|
3998
|
+
}
|
|
3999
|
+
async function submitFalVideoTool(req, ctx, opts) {
|
|
4000
|
+
const plan = planVideoTool(ctx.model, req);
|
|
4001
|
+
if (!plan.ok) {
|
|
4002
|
+
throw new ModelKitError({
|
|
4003
|
+
code: "unsupported_option",
|
|
4004
|
+
message: plan.error,
|
|
4005
|
+
provider: "fal",
|
|
4006
|
+
model: ctx.model.id,
|
|
4007
|
+
retryable: false
|
|
4008
|
+
});
|
|
4009
|
+
}
|
|
4010
|
+
const target = new URL(`${FAL_QUEUE_ORIGIN}/${ctx.model.providerModelId}`);
|
|
4011
|
+
if (opts.webhookUrl !== void 0) target.searchParams.set("fal_webhook", opts.webhookUrl);
|
|
4012
|
+
const res = await queueFetch(ctx, target.toString(), "POST", toolInput(ctx, req, plan.output));
|
|
4013
|
+
const parsed = submitResponseSchema.safeParse(await readJson(ctx, res));
|
|
4014
|
+
if (!parsed.success) {
|
|
4015
|
+
throw new ModelKitError({
|
|
4016
|
+
code: "provider_rejected",
|
|
4017
|
+
message: `fal ${ctx.model.providerModelId} submit returned no queue URLs`,
|
|
4018
|
+
provider: "fal",
|
|
4019
|
+
model: ctx.model.id,
|
|
4020
|
+
retryable: false
|
|
4021
|
+
});
|
|
4022
|
+
}
|
|
4023
|
+
return {
|
|
4024
|
+
model: ctx.model.id,
|
|
4025
|
+
provider: "fal",
|
|
4026
|
+
requestId: parsed.data.request_id,
|
|
4027
|
+
statusUrl: parsed.data.status_url,
|
|
4028
|
+
responseUrl: parsed.data.response_url,
|
|
4029
|
+
cancelUrl: parsed.data.cancel_url,
|
|
4030
|
+
output: plan.output
|
|
4031
|
+
};
|
|
4032
|
+
}
|
|
4033
|
+
function checkedQueueUrl(ctx, url) {
|
|
4034
|
+
if (!queueUrlSchema.safeParse(url).success) {
|
|
4035
|
+
throw new ModelKitError({
|
|
4036
|
+
code: "provider_rejected",
|
|
4037
|
+
message: "Video-tool submission carries a URL outside fal's queue",
|
|
4038
|
+
provider: "fal",
|
|
4039
|
+
model: ctx.model.id,
|
|
4040
|
+
retryable: false
|
|
4041
|
+
});
|
|
4042
|
+
}
|
|
4043
|
+
return url;
|
|
4044
|
+
}
|
|
4045
|
+
async function falVideoToolStatus(sub, ctx) {
|
|
4046
|
+
const res = await queueFetch(ctx, checkedQueueUrl(ctx, sub.statusUrl), "GET");
|
|
4047
|
+
const { status } = statusResponseSchema.parse(await readJson(ctx, res));
|
|
4048
|
+
if (status === "IN_QUEUE") return "queued";
|
|
4049
|
+
if (status === "COMPLETED") return "completed";
|
|
4050
|
+
return "running";
|
|
4051
|
+
}
|
|
4052
|
+
function usageOf(ctx, output) {
|
|
4053
|
+
return {
|
|
4054
|
+
model: ctx.model.id,
|
|
4055
|
+
provider: "fal",
|
|
4056
|
+
modality: "VIDEO",
|
|
4057
|
+
unit: "seconds",
|
|
4058
|
+
quantity: output.durationSeconds,
|
|
4059
|
+
durationSeconds: output.durationSeconds,
|
|
4060
|
+
resolution: output.resolution,
|
|
4061
|
+
...output.fps !== void 0 && { fps: output.fps }
|
|
4062
|
+
};
|
|
4063
|
+
}
|
|
4064
|
+
function resultOf(ctx, sub, payload) {
|
|
4065
|
+
const parsed = toolOutputSchema.safeParse(payload);
|
|
4066
|
+
if (!parsed.success) {
|
|
4067
|
+
throw new ModelKitError({
|
|
4068
|
+
code: "provider_rejected",
|
|
4069
|
+
message: `fal ${ctx.model.providerModelId} returned no video`,
|
|
4070
|
+
provider: "fal",
|
|
4071
|
+
model: ctx.model.id,
|
|
4072
|
+
retryable: false
|
|
4073
|
+
});
|
|
4074
|
+
}
|
|
4075
|
+
const file = parsed.data.video;
|
|
4076
|
+
return {
|
|
4077
|
+
video: {
|
|
4078
|
+
url: file.url,
|
|
4079
|
+
...file.content_type != null && { mime: file.content_type },
|
|
4080
|
+
...file.file_size != null && { bytes: file.file_size }
|
|
4081
|
+
},
|
|
4082
|
+
output: sub.output,
|
|
4083
|
+
usage: usageOf(ctx, sub.output),
|
|
4084
|
+
raw: payload
|
|
4085
|
+
};
|
|
4086
|
+
}
|
|
4087
|
+
async function falVideoToolResult(sub, ctx, webhook) {
|
|
4088
|
+
if (webhook !== void 0) {
|
|
4089
|
+
if (webhook.request_id !== sub.requestId) {
|
|
4090
|
+
throw new ModelKitError({
|
|
4091
|
+
code: "provider_rejected",
|
|
4092
|
+
message: "fal webhook is for a different request",
|
|
4093
|
+
provider: "fal",
|
|
4094
|
+
model: ctx.model.id,
|
|
4095
|
+
retryable: false
|
|
4096
|
+
});
|
|
4097
|
+
}
|
|
4098
|
+
if (webhook.status === "ERROR") {
|
|
4099
|
+
throw falError(
|
|
4100
|
+
void 0,
|
|
4101
|
+
webhook.payload ?? webhook.error ?? "fal job failed",
|
|
4102
|
+
ctx.model.id
|
|
4103
|
+
);
|
|
4104
|
+
}
|
|
4105
|
+
return resultOf(ctx, sub, webhook.payload);
|
|
4106
|
+
}
|
|
4107
|
+
const res = await queueFetch(ctx, checkedQueueUrl(ctx, sub.responseUrl), "GET");
|
|
4108
|
+
return resultOf(ctx, sub, await readJson(ctx, res));
|
|
4109
|
+
}
|
|
4110
|
+
async function cancelFalVideoTool(sub, ctx) {
|
|
4111
|
+
const res = await queueFetch(ctx, checkedQueueUrl(ctx, sub.cancelUrl), "PUT");
|
|
4112
|
+
if (res.ok) return true;
|
|
4113
|
+
if (res.status === 400) return false;
|
|
4114
|
+
throw falError(res.status, await readBody(res), ctx.model.id);
|
|
4115
|
+
}
|
|
4116
|
+
|
|
4117
|
+
// src/adapters/input-spec-mapper.ts
|
|
4118
|
+
function canonicalValue(req, key) {
|
|
4119
|
+
return req[key];
|
|
4120
|
+
}
|
|
4121
|
+
function isMediaRef(value) {
|
|
4122
|
+
return value instanceof Object && ("url" in value || "bytes" in value);
|
|
4123
|
+
}
|
|
4124
|
+
function toProviderValue(value, refToUrl2) {
|
|
4125
|
+
if (Array.isArray(value)) {
|
|
4126
|
+
return value.map(refToUrl2);
|
|
4127
|
+
}
|
|
4128
|
+
if (isMediaRef(value)) {
|
|
4129
|
+
return refToUrl2(value);
|
|
4130
|
+
}
|
|
4131
|
+
return value;
|
|
4132
|
+
}
|
|
4133
|
+
function applyInputSpec(spec, req, refToUrl2, opts) {
|
|
4134
|
+
const out = {};
|
|
4135
|
+
for (const [canonical, providerField] of Object.entries(spec.fields)) {
|
|
4136
|
+
if (!isInputSpecKey(canonical)) continue;
|
|
4137
|
+
const value = canonicalValue(req, canonical);
|
|
4138
|
+
if (value === void 0) continue;
|
|
4139
|
+
if (opts?.omit?.(canonical, value)) continue;
|
|
4140
|
+
const serialised = toProviderValue(value, refToUrl2);
|
|
4141
|
+
const mapped = spec.values?.[canonical]?.[String(value)];
|
|
4142
|
+
out[providerField] = mapped ?? serialised;
|
|
4143
|
+
}
|
|
4144
|
+
for (const [key, value] of Object.entries(spec.static ?? {})) {
|
|
4145
|
+
out[key] = value;
|
|
4146
|
+
}
|
|
4147
|
+
return out;
|
|
4148
|
+
}
|
|
4149
|
+
function resolveRowInputSpec(req, ctx) {
|
|
4150
|
+
const raw = ctx.model.providerOptions?.["modelkit"]?.["inputSpec"];
|
|
4151
|
+
if (raw === void 0) return { kind: "absent" };
|
|
4152
|
+
const result = validateInputSpec(raw, ctx.model);
|
|
4153
|
+
if (!result.ok) {
|
|
4154
|
+
ctx.logger.warn(
|
|
4155
|
+
`[modelkit] ${ctx.model.id} has an invalid providerOptions.modelkit.inputSpec; the call fails`
|
|
4156
|
+
);
|
|
4157
|
+
return { kind: "invalid", issues: result.issues };
|
|
4158
|
+
}
|
|
4159
|
+
return {
|
|
4160
|
+
kind: "ok",
|
|
4161
|
+
spec: result.spec,
|
|
4162
|
+
input: applyInputSpec(result.spec, req, refToUrl, {
|
|
4163
|
+
omit: (key, value) => key === "aspectRatio" && value === "adaptive"
|
|
4164
|
+
})
|
|
4165
|
+
};
|
|
4166
|
+
}
|
|
4167
|
+
function describeInputSpecIssue(issue) {
|
|
4168
|
+
if (!issue) return "invalid inputSpec";
|
|
4169
|
+
return issue.path.length === 0 ? issue.message : `${issue.path.map((part) => String(part)).join(".")} ${issue.message}`;
|
|
4170
|
+
}
|
|
4171
|
+
function invalidInputSpecError(provider, ctx, issues) {
|
|
4172
|
+
return new ModelKitError({
|
|
4173
|
+
code: "unsupported_option",
|
|
4174
|
+
message: `${provider} row "${ctx.model.id}" has an invalid providerOptions.modelkit.inputSpec: ${describeInputSpecIssue(issues[0])}`,
|
|
4175
|
+
provider,
|
|
4176
|
+
model: ctx.model.id,
|
|
4177
|
+
retryable: false
|
|
4178
|
+
});
|
|
4179
|
+
}
|
|
4180
|
+
|
|
3576
4181
|
// src/adapters/fal.ts
|
|
3577
4182
|
var MUSE_T2I_ENDPOINT = "meta/muse-image/text-to-image";
|
|
3578
4183
|
var MUSE_EDIT_ENDPOINT = "meta/muse-image/edit";
|
|
@@ -3580,7 +4185,7 @@ var KLING_O1_ENDPOINT = "fal-ai/kling-video/o1/video-to-video/reference";
|
|
|
3580
4185
|
var FAL_QUEUE_HOST = "https://queue.fal.run";
|
|
3581
4186
|
var PASSTHROUGH_POLL_MS = 2e3;
|
|
3582
4187
|
var PASSTHROUGH_MAX_WAIT_MS = 18e4;
|
|
3583
|
-
var falSubscribePayloadSchema =
|
|
4188
|
+
var falSubscribePayloadSchema = z12.object({ data: JsonValueSchema });
|
|
3584
4189
|
function defaultCreateFalClient(opts) {
|
|
3585
4190
|
if (opts.maxRetries !== void 0)
|
|
3586
4191
|
return createFalHttpClient({
|
|
@@ -3627,30 +4232,30 @@ function createFalAdapter(deps = defaultDeps) {
|
|
|
3627
4232
|
id: "fal",
|
|
3628
4233
|
generateImage: (req, ctx) => {
|
|
3629
4234
|
throwIfAborted(ctx.signal);
|
|
4235
|
+
const spec = resolveRowInputSpec(req, ctx);
|
|
4236
|
+
if (spec.kind === "invalid") {
|
|
4237
|
+
return Promise.reject(invalidInputSpecError("fal", ctx, spec.issues));
|
|
4238
|
+
}
|
|
4239
|
+
if (spec.kind === "ok") return generateSpecImage(req, ctx, deps, spec);
|
|
3630
4240
|
if (isIdeogram(ctx.model.providerModelId)) return generateIdeogramImage(req, ctx, deps);
|
|
3631
4241
|
return generateMuseImage(req, ctx, deps);
|
|
3632
4242
|
},
|
|
3633
4243
|
generateVideo: (req, ctx) => {
|
|
3634
4244
|
throwIfAborted(ctx.signal);
|
|
3635
4245
|
return generateFalVideo(req, ctx, deps);
|
|
3636
|
-
}
|
|
4246
|
+
},
|
|
4247
|
+
submitVideoTool: submitFalVideoTool,
|
|
4248
|
+
videoToolStatus: falVideoToolStatus,
|
|
4249
|
+
videoToolResult: falVideoToolResult,
|
|
4250
|
+
cancelVideoTool: cancelFalVideoTool
|
|
3637
4251
|
};
|
|
3638
4252
|
}
|
|
3639
4253
|
var falAdapter = createFalAdapter();
|
|
3640
|
-
var
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
const detail = parsed.success ? parsed.data.detail : void 0;
|
|
3644
|
-
return detail ?? body;
|
|
3645
|
-
}
|
|
3646
|
-
function falError(status, body, model) {
|
|
3647
|
-
return classifyHttpError(status, liftDetail(body), "fal", model);
|
|
3648
|
-
}
|
|
3649
|
-
var falSdkThrownSchema = z9.object({
|
|
3650
|
-
status: z9.number().optional(),
|
|
3651
|
-
statusCode: z9.number().optional(),
|
|
4254
|
+
var falSdkThrownSchema = z12.object({
|
|
4255
|
+
status: z12.number().optional(),
|
|
4256
|
+
statusCode: z12.number().optional(),
|
|
3652
4257
|
body: JsonValueSchema.optional(),
|
|
3653
|
-
message:
|
|
4258
|
+
message: z12.string().optional()
|
|
3654
4259
|
});
|
|
3655
4260
|
function falSdkError(cause, model) {
|
|
3656
4261
|
const parsed = falSdkThrownSchema.safeParse(cause);
|
|
@@ -3665,45 +4270,12 @@ function falSdkError(cause, model) {
|
|
|
3665
4270
|
body: liftDetail(info.body)
|
|
3666
4271
|
});
|
|
3667
4272
|
}
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
if (!cf?.accountId || !cf?.gatewayId || !falKey && !cfToken) {
|
|
3673
|
-
throw new ModelKitError({
|
|
3674
|
-
code: "auth",
|
|
3675
|
-
message: "fal passthrough is not configured. Set routing.cloudflare and FAL_KEY or the gateway token (BYOK).",
|
|
3676
|
-
provider: "fal",
|
|
3677
|
-
model: ctx.model.id,
|
|
3678
|
-
retryable: false
|
|
3679
|
-
});
|
|
3680
|
-
}
|
|
3681
|
-
const config = {
|
|
3682
|
-
baseUrl: `https://gateway.ai.cloudflare.com/v1/${cf.accountId}/${cf.gatewayId}/fal`
|
|
3683
|
-
};
|
|
3684
|
-
if (falKey) config.falKey = falKey;
|
|
3685
|
-
if (cfToken) config.cfToken = cfToken;
|
|
3686
|
-
if (ctx.call.maxRetries !== void 0) config.singleAttempt = true;
|
|
3687
|
-
if (ctx.signal !== void 0) config.signal = ctx.signal;
|
|
3688
|
-
return config;
|
|
3689
|
-
}
|
|
3690
|
-
async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
|
|
3691
|
-
const headers2 = { "x-fal-target-url": targetUrl };
|
|
3692
|
-
if (cfg.falKey) headers2.Authorization = `Bearer ${cfg.falKey}`;
|
|
3693
|
-
if (init.body) headers2["Content-Type"] = "application/json";
|
|
3694
|
-
if (cfg.cfToken) headers2["cf-aig-authorization"] = `Bearer ${cfg.cfToken}`;
|
|
3695
|
-
if (cfg.singleAttempt) headers2["cf-aig-max-attempts"] = "1";
|
|
3696
|
-
const request = { method: init.method, headers: headers2 };
|
|
3697
|
-
if (cfg.signal !== void 0) request.signal = cfg.signal;
|
|
3698
|
-
if (init.body !== void 0) request.body = init.body;
|
|
3699
|
-
return fetchImpl(cfg.baseUrl, request);
|
|
3700
|
-
}
|
|
3701
|
-
var falQueueSubmitSchema = z9.object({
|
|
3702
|
-
request_id: z9.string(),
|
|
3703
|
-
status_url: z9.string(),
|
|
3704
|
-
response_url: z9.string()
|
|
4273
|
+
var falQueueSubmitSchema = z12.object({
|
|
4274
|
+
request_id: z12.string(),
|
|
4275
|
+
status_url: z12.string(),
|
|
4276
|
+
response_url: z12.string()
|
|
3705
4277
|
});
|
|
3706
|
-
var falQueueStatusSchema =
|
|
4278
|
+
var falQueueStatusSchema = z12.object({ status: z12.string() });
|
|
3707
4279
|
async function passthroughRequest(ctx, endpoint, input) {
|
|
3708
4280
|
const cfg = gatewayConfig(ctx);
|
|
3709
4281
|
const submitRes = await gatewayFetch(cfg, ctx.fetch, `${FAL_QUEUE_HOST}/${endpoint}`, {
|
|
@@ -3836,14 +4408,44 @@ async function decodeImage(ctx, url, contentType) {
|
|
|
3836
4408
|
const mime = res.headers.get("content-type") ?? contentType ?? "image/png";
|
|
3837
4409
|
return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
|
|
3838
4410
|
}
|
|
3839
|
-
var museImageResultSchema =
|
|
3840
|
-
images:
|
|
3841
|
-
|
|
3842
|
-
url:
|
|
3843
|
-
content_type:
|
|
4411
|
+
var museImageResultSchema = z12.object({
|
|
4412
|
+
images: z12.array(
|
|
4413
|
+
z12.object({
|
|
4414
|
+
url: z12.string().optional(),
|
|
4415
|
+
content_type: z12.string().nullable().optional()
|
|
3844
4416
|
})
|
|
3845
4417
|
).optional()
|
|
3846
4418
|
});
|
|
4419
|
+
async function collectFalImages(payload, ctx, req, label) {
|
|
4420
|
+
const parsed = museImageResultSchema.safeParse(payload);
|
|
4421
|
+
const images = parsed.success ? parsed.data.images ?? [] : [];
|
|
4422
|
+
const files = await Promise.all(
|
|
4423
|
+
images.flatMap((img) => {
|
|
4424
|
+
if (img.url === void 0) return [];
|
|
4425
|
+
return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
|
|
4426
|
+
})
|
|
4427
|
+
);
|
|
4428
|
+
if (files.length === 0) {
|
|
4429
|
+
throw new ModelKitError({
|
|
4430
|
+
code: "provider_rejected",
|
|
4431
|
+
message: `${label} returned no image`,
|
|
4432
|
+
provider: "fal",
|
|
4433
|
+
model: ctx.model.id,
|
|
4434
|
+
retryable: false
|
|
4435
|
+
});
|
|
4436
|
+
}
|
|
4437
|
+
return {
|
|
4438
|
+
images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
|
|
4439
|
+
usage: imageUsage(ctx, req, files.length),
|
|
4440
|
+
raw: payload
|
|
4441
|
+
};
|
|
4442
|
+
}
|
|
4443
|
+
async function generateSpecImage(req, ctx, deps, spec) {
|
|
4444
|
+
const hasReferences = (req.references ?? []).length > 0;
|
|
4445
|
+
const endpoint = hasReferences && spec.spec.editEndpoint !== void 0 ? spec.spec.editEndpoint : ctx.model.providerModelId;
|
|
4446
|
+
const payload = await runJob(ctx, deps, endpoint, spec.input);
|
|
4447
|
+
return collectFalImages(payload, ctx, req, `fal ${endpoint}`);
|
|
4448
|
+
}
|
|
3847
4449
|
async function generateMuseImage(req, ctx, deps) {
|
|
3848
4450
|
const refs = (req.references ?? []).map(refToUrl);
|
|
3849
4451
|
const isEdit = refs.length > 0;
|
|
@@ -3860,29 +4462,7 @@ async function generateMuseImage(req, ctx, deps) {
|
|
|
3860
4462
|
const custom = id.includes("/") && !id.startsWith("meta/muse-image") ? id : void 0;
|
|
3861
4463
|
const endpoint = custom ?? (isEdit ? MUSE_EDIT_ENDPOINT : MUSE_T2I_ENDPOINT);
|
|
3862
4464
|
const payload = await runJob(ctx, deps, endpoint, input);
|
|
3863
|
-
|
|
3864
|
-
const images = parsed.success ? parsed.data.images ?? [] : [];
|
|
3865
|
-
const firstUrl = images[0]?.url;
|
|
3866
|
-
if (images.length === 0 || firstUrl === void 0) {
|
|
3867
|
-
throw new ModelKitError({
|
|
3868
|
-
code: "provider_rejected",
|
|
3869
|
-
message: "fal Meta Muse returned no image",
|
|
3870
|
-
provider: "fal",
|
|
3871
|
-
model: ctx.model.id,
|
|
3872
|
-
retryable: false
|
|
3873
|
-
});
|
|
3874
|
-
}
|
|
3875
|
-
const files = await Promise.all(
|
|
3876
|
-
images.flatMap((img) => {
|
|
3877
|
-
if (img.url === void 0) return [];
|
|
3878
|
-
return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
|
|
3879
|
-
})
|
|
3880
|
-
);
|
|
3881
|
-
return {
|
|
3882
|
-
images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
|
|
3883
|
-
usage: imageUsage(ctx, req, files.length),
|
|
3884
|
-
raw: payload
|
|
3885
|
-
};
|
|
4465
|
+
return collectFalImages(payload, ctx, req, "fal Meta Muse");
|
|
3886
4466
|
}
|
|
3887
4467
|
var IDEOGRAM_MODEL_IDS = /* @__PURE__ */ new Set(["ideogram/v4.5"]);
|
|
3888
4468
|
function isIdeogram(providerModelId) {
|
|
@@ -3927,28 +4507,7 @@ async function generateIdeogramImage(req, ctx, deps) {
|
|
|
3927
4507
|
if (references.length > 0) input.reference_image_urls = references;
|
|
3928
4508
|
}
|
|
3929
4509
|
const payload = await runJob(ctx, deps, endpoint, input);
|
|
3930
|
-
|
|
3931
|
-
const images = parsed.success ? parsed.data.images ?? [] : [];
|
|
3932
|
-
const files = await Promise.all(
|
|
3933
|
-
images.flatMap((img) => {
|
|
3934
|
-
if (img.url === void 0) return [];
|
|
3935
|
-
return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
|
|
3936
|
-
})
|
|
3937
|
-
);
|
|
3938
|
-
if (files.length === 0) {
|
|
3939
|
-
throw new ModelKitError({
|
|
3940
|
-
code: "provider_rejected",
|
|
3941
|
-
message: "fal Ideogram returned no image",
|
|
3942
|
-
provider: "fal",
|
|
3943
|
-
model: ctx.model.id,
|
|
3944
|
-
retryable: false
|
|
3945
|
-
});
|
|
3946
|
-
}
|
|
3947
|
-
return {
|
|
3948
|
-
images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
|
|
3949
|
-
usage: imageUsage(ctx, req, files.length),
|
|
3950
|
-
raw: payload
|
|
3951
|
-
};
|
|
4510
|
+
return collectFalImages(payload, ctx, req, "fal Ideogram");
|
|
3952
4511
|
}
|
|
3953
4512
|
var H3_MAX_MODEL_IDS = /* @__PURE__ */ new Set([
|
|
3954
4513
|
"minimax/h3-max",
|
|
@@ -4010,8 +4569,8 @@ function klingO1Input(req) {
|
|
|
4010
4569
|
if (refs.length > 0) input.image_urls = refs;
|
|
4011
4570
|
return input;
|
|
4012
4571
|
}
|
|
4013
|
-
var falVideoResultSchema =
|
|
4014
|
-
video:
|
|
4572
|
+
var falVideoResultSchema = z12.object({
|
|
4573
|
+
video: z12.object({ url: z12.string().optional() }).optional()
|
|
4015
4574
|
});
|
|
4016
4575
|
function extractVideoUrl(result, endpoint, model) {
|
|
4017
4576
|
const parsed = falVideoResultSchema.safeParse(result);
|
|
@@ -4212,13 +4771,13 @@ async function passthroughVideoJob(ctx, req, endpoint, input) {
|
|
|
4212
4771
|
}
|
|
4213
4772
|
|
|
4214
4773
|
// src/adapters/google-genai.ts
|
|
4215
|
-
import { z as
|
|
4774
|
+
import { z as z14 } from "zod";
|
|
4216
4775
|
import {
|
|
4217
4776
|
GoogleGenAI
|
|
4218
4777
|
} from "@google/genai";
|
|
4219
4778
|
|
|
4220
4779
|
// src/adapters/google-files.ts
|
|
4221
|
-
import { z as
|
|
4780
|
+
import { z as z13 } from "zod";
|
|
4222
4781
|
var GOOGLE_FILES_BASE = "https://generativelanguage.googleapis.com";
|
|
4223
4782
|
var GOOGLE_FILES_POLL_INTERVAL_MS = 2e3;
|
|
4224
4783
|
var GOOGLE_FILES_POLL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
@@ -4228,17 +4787,17 @@ var GENERIC_MEDIA_TYPES = /* @__PURE__ */ new Set([
|
|
|
4228
4787
|
"binary/octet-stream",
|
|
4229
4788
|
"application/binary"
|
|
4230
4789
|
]);
|
|
4231
|
-
var uploadedFileSchema =
|
|
4232
|
-
file:
|
|
4233
|
-
uri:
|
|
4234
|
-
name:
|
|
4235
|
-
state:
|
|
4236
|
-
mimeType:
|
|
4790
|
+
var uploadedFileSchema = z13.object({
|
|
4791
|
+
file: z13.object({
|
|
4792
|
+
uri: z13.string().optional(),
|
|
4793
|
+
name: z13.string().optional(),
|
|
4794
|
+
state: z13.string().optional(),
|
|
4795
|
+
mimeType: z13.string().optional()
|
|
4237
4796
|
}).optional()
|
|
4238
4797
|
});
|
|
4239
|
-
var fileStateSchema =
|
|
4240
|
-
state:
|
|
4241
|
-
error:
|
|
4798
|
+
var fileStateSchema = z13.object({
|
|
4799
|
+
state: z13.string().optional(),
|
|
4800
|
+
error: z13.object({ message: z13.string().optional() }).optional()
|
|
4242
4801
|
});
|
|
4243
4802
|
function resolveMime(declared, fallback) {
|
|
4244
4803
|
const clean = declared?.split(";")[0]?.trim().toLowerCase();
|
|
@@ -4455,7 +5014,7 @@ var OMNI_POLL_INTERVAL_MS = 1e4;
|
|
|
4455
5014
|
var RESULT_TIMEOUT_MS2 = 15 * 60 * 1e3;
|
|
4456
5015
|
var OMNI_INLINE_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
4457
5016
|
var MEDIA_PART_INLINE_LIMIT_BYTES = 20 * 1024 * 1024;
|
|
4458
|
-
var errorTextSchema =
|
|
5017
|
+
var errorTextSchema = z14.string();
|
|
4459
5018
|
function isGoogleGenaiVideoKnown(providerModelId) {
|
|
4460
5019
|
return providerModelId.startsWith("veo-") || providerModelId.startsWith("gemini-omni");
|
|
4461
5020
|
}
|
|
@@ -5061,15 +5620,15 @@ async function prepareGoogleMediaPart(ref, mediaType, ctx) {
|
|
|
5061
5620
|
// src/adapters/google-image.ts
|
|
5062
5621
|
import { createGoogleGenerativeAI as createGoogleGenerativeAI2 } from "@ai-sdk/google";
|
|
5063
5622
|
import { generateText } from "ai";
|
|
5064
|
-
import { z as
|
|
5623
|
+
import { z as z15 } from "zod";
|
|
5065
5624
|
var GEMINI_IMAGE_TIMEOUT_MS = 6e5;
|
|
5066
5625
|
var defaultGoogleImageDeps = {
|
|
5067
5626
|
createGoogleClient: (opts) => createGoogleGenerativeAI2(opts),
|
|
5068
5627
|
runTextGeneration: (opts) => generateText(opts)
|
|
5069
5628
|
};
|
|
5070
|
-
var causeChainNodeSchema =
|
|
5071
|
-
message:
|
|
5072
|
-
cause:
|
|
5629
|
+
var causeChainNodeSchema = z15.object({
|
|
5630
|
+
message: z15.string().optional(),
|
|
5631
|
+
cause: z15.unknown().optional()
|
|
5073
5632
|
});
|
|
5074
5633
|
function extractBlockReason(cause) {
|
|
5075
5634
|
let current = cause;
|
|
@@ -5189,7 +5748,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
5189
5748
|
var googleImageAdapter = createGoogleImageAdapter();
|
|
5190
5749
|
|
|
5191
5750
|
// src/adapters/higgsfield.ts
|
|
5192
|
-
import { z as
|
|
5751
|
+
import { z as z16 } from "zod";
|
|
5193
5752
|
|
|
5194
5753
|
// src/adapters/higgsfield-motions.ts
|
|
5195
5754
|
var MOTION_MAP = {
|
|
@@ -5408,14 +5967,14 @@ function klingEndpointFields(providerModelId) {
|
|
|
5408
5967
|
const path = (providerModelId.startsWith("/") ? providerModelId.slice(1) : providerModelId).toLowerCase();
|
|
5409
5968
|
return KLING_ENDPOINT_FIELDS.get(path) ?? UNLISTED_KLING_FIELDS;
|
|
5410
5969
|
}
|
|
5411
|
-
var klingCreateSchema =
|
|
5412
|
-
var klingStatusSchema =
|
|
5413
|
-
status:
|
|
5414
|
-
video:
|
|
5970
|
+
var klingCreateSchema = z16.object({ status_url: z16.string() });
|
|
5971
|
+
var klingStatusSchema = z16.object({
|
|
5972
|
+
status: z16.string().optional(),
|
|
5973
|
+
video: z16.object({ url: z16.string().optional() }).optional(),
|
|
5415
5974
|
error: JsonValueSchema.optional()
|
|
5416
5975
|
});
|
|
5417
|
-
var errorMessageSchema =
|
|
5418
|
-
var textValueSchema =
|
|
5976
|
+
var errorMessageSchema = z16.object({ message: z16.string().optional() });
|
|
5977
|
+
var textValueSchema = z16.string();
|
|
5419
5978
|
function klingErrorDetail(error) {
|
|
5420
5979
|
if (error === void 0) return "unknown_error";
|
|
5421
5980
|
const asText = textValueSchema.safeParse(error);
|
|
@@ -5571,8 +6130,8 @@ async function generateKlingVideo(req, ctx) {
|
|
|
5571
6130
|
}
|
|
5572
6131
|
};
|
|
5573
6132
|
}
|
|
5574
|
-
var dopMotionOptionsSchema =
|
|
5575
|
-
modelkit:
|
|
6133
|
+
var dopMotionOptionsSchema = z16.object({
|
|
6134
|
+
modelkit: z16.object({ motion: z16.string().optional() }).optional()
|
|
5576
6135
|
});
|
|
5577
6136
|
function dopMotionId(ctx) {
|
|
5578
6137
|
const parsed = dopMotionOptionsSchema.safeParse(ctx.model.providerOptions);
|
|
@@ -5588,7 +6147,7 @@ function dopMotionId(ctx) {
|
|
|
5588
6147
|
});
|
|
5589
6148
|
return id;
|
|
5590
6149
|
}
|
|
5591
|
-
var jsonRecordSchema =
|
|
6150
|
+
var jsonRecordSchema = z16.record(z16.string(), JsonValueSchema);
|
|
5592
6151
|
var DOP_URL_KEYS = ["url", "video_url", "output_url", "result_url", "download_url"];
|
|
5593
6152
|
var DOP_NESTED_KEYS = ["video", "result", "results"];
|
|
5594
6153
|
function dopUrl(body) {
|
|
@@ -5616,8 +6175,8 @@ function dopUrl(body) {
|
|
|
5616
6175
|
}
|
|
5617
6176
|
return void 0;
|
|
5618
6177
|
}
|
|
5619
|
-
var dopCreateSchema =
|
|
5620
|
-
var dopStatusSchema =
|
|
6178
|
+
var dopCreateSchema = z16.object({ id: z16.string() });
|
|
6179
|
+
var dopStatusSchema = z16.object({ status: z16.string().optional() });
|
|
5621
6180
|
async function generateDopVideo(req, ctx) {
|
|
5622
6181
|
const firstFrame = req.firstFrame ? refToUrl(req.firstFrame) : void 0;
|
|
5623
6182
|
if (!firstFrame) {
|
|
@@ -5745,7 +6304,7 @@ var higgsfieldAdapter = {
|
|
|
5745
6304
|
|
|
5746
6305
|
// src/adapters/openai-image.ts
|
|
5747
6306
|
import OpenAI from "openai";
|
|
5748
|
-
import { z as
|
|
6307
|
+
import { z as z17 } from "zod";
|
|
5749
6308
|
var MAX_EDIT_REFERENCES = 16;
|
|
5750
6309
|
function aspectRatioToSize(ratio, tier) {
|
|
5751
6310
|
const TIER_LONG_EDGE = {
|
|
@@ -5828,9 +6387,9 @@ function toProviderError2(cause, ctx) {
|
|
|
5828
6387
|
ctx.model.id
|
|
5829
6388
|
);
|
|
5830
6389
|
}
|
|
5831
|
-
var openaiUsageSchema =
|
|
5832
|
-
input_tokens:
|
|
5833
|
-
output_tokens:
|
|
6390
|
+
var openaiUsageSchema = z17.object({
|
|
6391
|
+
input_tokens: z17.number().optional(),
|
|
6392
|
+
output_tokens: z17.number().optional()
|
|
5834
6393
|
});
|
|
5835
6394
|
var openaiImageAdapter = {
|
|
5836
6395
|
id: "openai-image",
|
|
@@ -6241,13 +6800,13 @@ var prodiaAdapter = {
|
|
|
6241
6800
|
import Replicate from "replicate";
|
|
6242
6801
|
|
|
6243
6802
|
// src/adapters/replicate-http.ts
|
|
6244
|
-
import { z as
|
|
6245
|
-
var predictionSchema =
|
|
6246
|
-
id:
|
|
6247
|
-
status:
|
|
6803
|
+
import { z as z18 } from "zod";
|
|
6804
|
+
var predictionSchema = z18.object({
|
|
6805
|
+
id: z18.string(),
|
|
6806
|
+
status: z18.string(),
|
|
6248
6807
|
output: JsonValueSchema.optional(),
|
|
6249
6808
|
error: JsonValueSchema.optional(),
|
|
6250
|
-
metrics:
|
|
6809
|
+
metrics: z18.object({ predict_time: z18.number().optional() }).optional()
|
|
6251
6810
|
});
|
|
6252
6811
|
function createReplicateHttpClient(opts) {
|
|
6253
6812
|
async function request(path, body, signal) {
|
|
@@ -6298,42 +6857,7 @@ function createReplicateHttpClient(opts) {
|
|
|
6298
6857
|
}
|
|
6299
6858
|
|
|
6300
6859
|
// src/adapters/replicate.ts
|
|
6301
|
-
import { z as
|
|
6302
|
-
|
|
6303
|
-
// src/adapters/input-spec-mapper.ts
|
|
6304
|
-
function canonicalValue(req, key) {
|
|
6305
|
-
return req[key];
|
|
6306
|
-
}
|
|
6307
|
-
function isMediaRef(value) {
|
|
6308
|
-
return value instanceof Object && ("url" in value || "bytes" in value);
|
|
6309
|
-
}
|
|
6310
|
-
function toProviderValue(value, refToUrl2) {
|
|
6311
|
-
if (Array.isArray(value)) {
|
|
6312
|
-
return value.map(refToUrl2);
|
|
6313
|
-
}
|
|
6314
|
-
if (isMediaRef(value)) {
|
|
6315
|
-
return refToUrl2(value);
|
|
6316
|
-
}
|
|
6317
|
-
return value;
|
|
6318
|
-
}
|
|
6319
|
-
function applyInputSpec(spec, req, refToUrl2, opts) {
|
|
6320
|
-
const out = {};
|
|
6321
|
-
for (const [canonical, providerField] of Object.entries(spec.fields)) {
|
|
6322
|
-
if (!isInputSpecKey(canonical)) continue;
|
|
6323
|
-
const value = canonicalValue(req, canonical);
|
|
6324
|
-
if (value === void 0) continue;
|
|
6325
|
-
if (opts?.omit?.(canonical, value)) continue;
|
|
6326
|
-
const serialised = toProviderValue(value, refToUrl2);
|
|
6327
|
-
const mapped = spec.values?.[canonical]?.[String(value)];
|
|
6328
|
-
out[providerField] = mapped ?? serialised;
|
|
6329
|
-
}
|
|
6330
|
-
for (const [key, value] of Object.entries(spec.static ?? {})) {
|
|
6331
|
-
out[key] = value;
|
|
6332
|
-
}
|
|
6333
|
-
return out;
|
|
6334
|
-
}
|
|
6335
|
-
|
|
6336
|
-
// src/adapters/replicate.ts
|
|
6860
|
+
import { z as z19 } from "zod";
|
|
6337
6861
|
var POLL_INTERVAL_MS = 1e3;
|
|
6338
6862
|
var POLL_TIMEOUT_MS = 15 * 6e4;
|
|
6339
6863
|
var defaultReplicateDeps = {
|
|
@@ -6373,8 +6897,8 @@ function route(providerModelId) {
|
|
|
6373
6897
|
if (!providerModelId.includes("/")) return { version: providerModelId };
|
|
6374
6898
|
return { model: providerModelId };
|
|
6375
6899
|
}
|
|
6376
|
-
var replicateResponseStatusSchema =
|
|
6377
|
-
response:
|
|
6900
|
+
var replicateResponseStatusSchema = z19.object({
|
|
6901
|
+
response: z19.object({ status: z19.number() }).partial()
|
|
6378
6902
|
});
|
|
6379
6903
|
function replicateError(cause, ctx) {
|
|
6380
6904
|
if (isModelKitError(cause)) return cause;
|
|
@@ -6401,7 +6925,7 @@ function isUrlFn(value) {
|
|
|
6401
6925
|
function extractOutputUrl(output) {
|
|
6402
6926
|
const root = Array.isArray(output) ? output[0] : output;
|
|
6403
6927
|
if (root === void 0) throw noOutput();
|
|
6404
|
-
const asString =
|
|
6928
|
+
const asString = z19.string().safeParse(root);
|
|
6405
6929
|
if (asString.success && asString.data) return asString.data;
|
|
6406
6930
|
if (root instanceof URL) return root.href;
|
|
6407
6931
|
if (isObjectOutput(root)) {
|
|
@@ -6410,15 +6934,15 @@ function extractOutputUrl(output) {
|
|
|
6410
6934
|
if (urlValue !== void 0 && isUrlFn(urlValue)) {
|
|
6411
6935
|
const called = urlValue();
|
|
6412
6936
|
if (called instanceof URL) return called.href;
|
|
6413
|
-
const calledString =
|
|
6937
|
+
const calledString = z19.string().safeParse(called);
|
|
6414
6938
|
if (calledString.success && calledString.data) return calledString.data;
|
|
6415
6939
|
} else {
|
|
6416
|
-
const direct =
|
|
6940
|
+
const direct = z19.string().safeParse(urlValue);
|
|
6417
6941
|
if (direct.success && direct.data) return direct.data;
|
|
6418
6942
|
}
|
|
6419
6943
|
}
|
|
6420
6944
|
if ("default" in root) {
|
|
6421
|
-
const fallback =
|
|
6945
|
+
const fallback = z19.string().safeParse(root.default);
|
|
6422
6946
|
if (fallback.success && fallback.data) return fallback.data;
|
|
6423
6947
|
}
|
|
6424
6948
|
}
|
|
@@ -6479,7 +7003,7 @@ async function runPrediction(ctx, input, deps) {
|
|
|
6479
7003
|
}
|
|
6480
7004
|
return void 0;
|
|
6481
7005
|
}, pollOpts);
|
|
6482
|
-
const predictTime =
|
|
7006
|
+
const predictTime = z19.number().safeParse(done.metrics?.predict_time);
|
|
6483
7007
|
if (done.output === void 0) throw noOutput();
|
|
6484
7008
|
return {
|
|
6485
7009
|
url: extractOutputUrl(done.output),
|
|
@@ -6576,38 +7100,6 @@ function replicateNoMapper(ctx, section) {
|
|
|
6576
7100
|
retryable: false
|
|
6577
7101
|
});
|
|
6578
7102
|
}
|
|
6579
|
-
function describeInputSpecIssue(issue) {
|
|
6580
|
-
if (!issue) return "invalid inputSpec";
|
|
6581
|
-
return issue.path.length === 0 ? issue.message : `${issue.path.map((part) => String(part)).join(".")} ${issue.message}`;
|
|
6582
|
-
}
|
|
6583
|
-
function replicateInvalidSpec(ctx, issues) {
|
|
6584
|
-
const detail = describeInputSpecIssue(issues[0]);
|
|
6585
|
-
return new ModelKitError({
|
|
6586
|
-
code: "unsupported_option",
|
|
6587
|
-
message: `replicate row "${ctx.model.id}" has an invalid providerOptions.modelkit.inputSpec: ${detail}`,
|
|
6588
|
-
provider: "replicate",
|
|
6589
|
-
model: ctx.model.id,
|
|
6590
|
-
retryable: false
|
|
6591
|
-
});
|
|
6592
|
-
}
|
|
6593
|
-
function omitAdaptive(key, value) {
|
|
6594
|
-
return key === "aspectRatio" && value === "adaptive";
|
|
6595
|
-
}
|
|
6596
|
-
function replicateInputSpec(req, ctx) {
|
|
6597
|
-
const raw = ctx.model.providerOptions?.["modelkit"]?.["inputSpec"];
|
|
6598
|
-
if (raw === void 0) return { kind: "absent" };
|
|
6599
|
-
const result = validateInputSpec(raw, ctx.model);
|
|
6600
|
-
if (!result.ok) {
|
|
6601
|
-
ctx.logger.warn(
|
|
6602
|
-
`[modelkit] ${ctx.model.id} has an invalid providerOptions.modelkit.inputSpec; the call fails`
|
|
6603
|
-
);
|
|
6604
|
-
return { kind: "invalid", issues: result.issues };
|
|
6605
|
-
}
|
|
6606
|
-
return {
|
|
6607
|
-
kind: "ok",
|
|
6608
|
-
input: applyInputSpec(result.spec, req, refToUrl, { omit: omitAdaptive })
|
|
6609
|
-
};
|
|
6610
|
-
}
|
|
6611
7103
|
var QWEN_IMAGE_RATIOS = /* @__PURE__ */ new Set([
|
|
6612
7104
|
"1:1",
|
|
6613
7105
|
"16:9",
|
|
@@ -6751,8 +7243,9 @@ async function generateReplicateImage(req, ctx, deps) {
|
|
|
6751
7243
|
break;
|
|
6752
7244
|
}
|
|
6753
7245
|
default: {
|
|
6754
|
-
const specResult =
|
|
6755
|
-
if (specResult.kind === "invalid")
|
|
7246
|
+
const specResult = resolveRowInputSpec(req, ctx);
|
|
7247
|
+
if (specResult.kind === "invalid")
|
|
7248
|
+
throw invalidInputSpecError("replicate", ctx, specResult.issues);
|
|
6756
7249
|
if (specResult.kind === "ok") {
|
|
6757
7250
|
input = specResult.input;
|
|
6758
7251
|
break;
|
|
@@ -6832,9 +7325,10 @@ async function generateReplicateVideo(req, ctx, deps) {
|
|
|
6832
7325
|
else if (kind === "kling-omni") input = klingOmniInput(req);
|
|
6833
7326
|
else if (kind === "hailuo") input = hailuoInput(req);
|
|
6834
7327
|
else {
|
|
6835
|
-
const specResult =
|
|
7328
|
+
const specResult = resolveRowInputSpec(req, ctx);
|
|
6836
7329
|
if (specResult.kind === "absent") throw replicateNoMapper(ctx, "video");
|
|
6837
|
-
if (specResult.kind === "invalid")
|
|
7330
|
+
if (specResult.kind === "invalid")
|
|
7331
|
+
throw invalidInputSpecError("replicate", ctx, specResult.issues);
|
|
6838
7332
|
input = specResult.input;
|
|
6839
7333
|
}
|
|
6840
7334
|
const api = client(ctx, deps);
|
|
@@ -6868,7 +7362,7 @@ async function generateReplicateVideo(req, ctx, deps) {
|
|
|
6868
7362
|
throw replicateError(cause, ctx);
|
|
6869
7363
|
}
|
|
6870
7364
|
if (current.status === "succeeded") {
|
|
6871
|
-
const predictTime =
|
|
7365
|
+
const predictTime = z19.number().safeParse(current.metrics?.predict_time);
|
|
6872
7366
|
if (current.output === void 0) throw noOutput();
|
|
6873
7367
|
return {
|
|
6874
7368
|
url: extractOutputUrl(current.output),
|
|
@@ -6989,9 +7483,10 @@ async function generateReplicateAudio(req, ctx, deps) {
|
|
|
6989
7483
|
else if (kind === "elevenlabs") input = elevenLabsMusicInput(req, ctx);
|
|
6990
7484
|
else if (kind === "lyria") input = lyriaAudioInput(req, ctx);
|
|
6991
7485
|
else {
|
|
6992
|
-
const specResult =
|
|
7486
|
+
const specResult = resolveRowInputSpec(req, ctx);
|
|
6993
7487
|
if (specResult.kind === "absent") throw replicateNoMapper(ctx, "audio");
|
|
6994
|
-
if (specResult.kind === "invalid")
|
|
7488
|
+
if (specResult.kind === "invalid")
|
|
7489
|
+
throw invalidInputSpecError("replicate", ctx, specResult.issues);
|
|
6995
7490
|
input = specResult.input;
|
|
6996
7491
|
}
|
|
6997
7492
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|
|
@@ -7009,7 +7504,7 @@ async function generateReplicateAudio(req, ctx, deps) {
|
|
|
7009
7504
|
// src/adapters/xai-video.ts
|
|
7010
7505
|
import { experimental_generateVideo } from "ai";
|
|
7011
7506
|
import { createXai as createXai2 } from "@ai-sdk/xai";
|
|
7012
|
-
import { z as
|
|
7507
|
+
import { z as z20 } from "zod";
|
|
7013
7508
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
7014
7509
|
var POLL_TIMEOUT_MS2 = 15 * 6e4;
|
|
7015
7510
|
var defaultXaiDeps = {
|
|
@@ -7022,8 +7517,8 @@ function createXaiVideoAdapter(deps = defaultXaiDeps) {
|
|
|
7022
7517
|
};
|
|
7023
7518
|
}
|
|
7024
7519
|
var xaiVideoAdapter = createXaiVideoAdapter();
|
|
7025
|
-
var xaiResponseStatusSchema =
|
|
7026
|
-
response:
|
|
7520
|
+
var xaiResponseStatusSchema = z20.object({
|
|
7521
|
+
response: z20.object({ status: z20.number() }).partial()
|
|
7027
7522
|
});
|
|
7028
7523
|
function xaiError(cause, ctx) {
|
|
7029
7524
|
const info = describeThrown(cause);
|
|
@@ -7031,12 +7526,12 @@ function xaiError(cause, ctx) {
|
|
|
7031
7526
|
const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
|
|
7032
7527
|
return classifyThrown("xai-video", cause, ctx.model.id, { status, body: info.body });
|
|
7033
7528
|
}
|
|
7034
|
-
var xaiMetaSchema =
|
|
7529
|
+
var xaiMetaSchema = z20.object({
|
|
7035
7530
|
videoUrl: JsonValueSchema.optional(),
|
|
7036
7531
|
costInUsdTicks: JsonValueSchema.optional(),
|
|
7037
7532
|
duration: JsonValueSchema.optional()
|
|
7038
7533
|
});
|
|
7039
|
-
var xaiProviderMetadataSchema =
|
|
7534
|
+
var xaiProviderMetadataSchema = z20.object({ xai: xaiMetaSchema });
|
|
7040
7535
|
function metaOf(result) {
|
|
7041
7536
|
const parsed = xaiProviderMetadataSchema.partial().safeParse(result.providerMetadata);
|
|
7042
7537
|
if (!parsed.success) return {};
|
|
@@ -7144,7 +7639,7 @@ async function mapResult(ctx, req, result) {
|
|
|
7144
7639
|
};
|
|
7145
7640
|
}
|
|
7146
7641
|
const meta = metaOf(result);
|
|
7147
|
-
const videoUrl =
|
|
7642
|
+
const videoUrl = z20.string().safeParse(meta.videoUrl);
|
|
7148
7643
|
if (videoUrl.success && videoUrl.data) {
|
|
7149
7644
|
const res = await ctx.fetch(videoUrl.data);
|
|
7150
7645
|
if (!res.ok) {
|
|
@@ -7167,7 +7662,7 @@ async function mapResult(ctx, req, result) {
|
|
|
7167
7662
|
});
|
|
7168
7663
|
}
|
|
7169
7664
|
function usage(ctx, req, meta) {
|
|
7170
|
-
const costTicks =
|
|
7665
|
+
const costTicks = z20.number().safeParse(meta.costInUsdTicks);
|
|
7171
7666
|
const cost = costTicks.success ? costTicks.data / 1e10 : void 0;
|
|
7172
7667
|
const event = {
|
|
7173
7668
|
model: ctx.model.id,
|
|
@@ -7300,22 +7795,22 @@ var liveState = store[KEY] ??= {
|
|
|
7300
7795
|
var liveCatalog = liveState.catalog;
|
|
7301
7796
|
|
|
7302
7797
|
// src/catalog/load.ts
|
|
7303
|
-
import { z as
|
|
7798
|
+
import { z as z21 } from "zod";
|
|
7304
7799
|
function rowCount() {
|
|
7305
7800
|
return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
|
|
7306
7801
|
}
|
|
7307
7802
|
function authHeaders(auth) {
|
|
7308
7803
|
return "bearer" in auth ? { Authorization: `Bearer ${auth.bearer}` } : { "x-api-key": auth.apiKey };
|
|
7309
7804
|
}
|
|
7310
|
-
var EnvelopeSchema =
|
|
7311
|
-
rows:
|
|
7312
|
-
revision:
|
|
7805
|
+
var EnvelopeSchema = z21.object({
|
|
7806
|
+
rows: z21.array(JsonValueSchema),
|
|
7807
|
+
revision: z21.string().optional()
|
|
7313
7808
|
});
|
|
7314
7809
|
function dropReason(path, message) {
|
|
7315
7810
|
return path.length === 0 ? message : `${path.map((part) => String(part)).join(".")} ${message}`;
|
|
7316
7811
|
}
|
|
7317
7812
|
function rowId(raw) {
|
|
7318
|
-
const parsed =
|
|
7813
|
+
const parsed = z21.object({ id: z21.string().min(1) }).loose().safeParse(raw);
|
|
7319
7814
|
if (!parsed.success) return "?";
|
|
7320
7815
|
return parsed.data.id;
|
|
7321
7816
|
}
|
|
@@ -8179,7 +8674,7 @@ import {
|
|
|
8179
8674
|
streamObject as aiStreamObject2,
|
|
8180
8675
|
streamText as aiStreamText2
|
|
8181
8676
|
} from "ai";
|
|
8182
|
-
import { z as
|
|
8677
|
+
import { z as z22 } from "zod";
|
|
8183
8678
|
|
|
8184
8679
|
// src/generated-image.ts
|
|
8185
8680
|
function toGeneratedImage(image) {
|
|
@@ -8261,10 +8756,10 @@ function textAbortOptions(sdk, context) {
|
|
|
8261
8756
|
if (abortSignal) return { abortSignal };
|
|
8262
8757
|
return {};
|
|
8263
8758
|
}
|
|
8264
|
-
var catalogId =
|
|
8265
|
-
var exactSize =
|
|
8266
|
-
var sdkRatio =
|
|
8267
|
-
var sizeTier =
|
|
8759
|
+
var catalogId = z22.string();
|
|
8760
|
+
var exactSize = z22.templateLiteral([z22.number(), "x", z22.number()]);
|
|
8761
|
+
var sdkRatio = z22.templateLiteral([z22.number(), ":", z22.number()]);
|
|
8762
|
+
var sizeTier = z22.enum(["512", "1K", "2K", "4K"]);
|
|
8268
8763
|
function isCatalogId(model) {
|
|
8269
8764
|
return catalogId.safeParse(model).success;
|
|
8270
8765
|
}
|
|
@@ -8374,6 +8869,24 @@ function createModelKit(config, adapters) {
|
|
|
8374
8869
|
if (call.signal) ctx.signal = call.signal;
|
|
8375
8870
|
return { adapter, ctx };
|
|
8376
8871
|
}
|
|
8872
|
+
function videoToolTarget(modelId, call) {
|
|
8873
|
+
mediaRetryOptions(call);
|
|
8874
|
+
const model = catalog.require(modelId);
|
|
8875
|
+
if (model.type !== "video-tool")
|
|
8876
|
+
throw new ModelKitError({
|
|
8877
|
+
code: "unsupported_option",
|
|
8878
|
+
message: `${model.id} is not a video tool`,
|
|
8879
|
+
model: model.id
|
|
8880
|
+
});
|
|
8881
|
+
return context(model, call, []);
|
|
8882
|
+
}
|
|
8883
|
+
function noVideoTools(adapter, model) {
|
|
8884
|
+
return new ModelKitError({
|
|
8885
|
+
code: "unsupported_option",
|
|
8886
|
+
message: `${adapter.id} has no video tools`,
|
|
8887
|
+
model: model.id
|
|
8888
|
+
});
|
|
8889
|
+
}
|
|
8377
8890
|
async function emit(event) {
|
|
8378
8891
|
try {
|
|
8379
8892
|
await config.onUsage?.(event);
|
|
@@ -8729,6 +9242,34 @@ function createModelKit(config, adapters) {
|
|
|
8729
9242
|
usageProvider: provider
|
|
8730
9243
|
};
|
|
8731
9244
|
},
|
|
9245
|
+
async submitVideoTool(req, call = {}) {
|
|
9246
|
+
const { webhookUrl, ...rest } = call;
|
|
9247
|
+
const { adapter, ctx } = videoToolTarget(req.model, rest);
|
|
9248
|
+
if (!adapter.submitVideoTool) throw noVideoTools(adapter, ctx.model);
|
|
9249
|
+
return adapter.submitVideoTool(
|
|
9250
|
+
req,
|
|
9251
|
+
ctx,
|
|
9252
|
+
webhookUrl !== void 0 ? { webhookUrl } : {}
|
|
9253
|
+
);
|
|
9254
|
+
},
|
|
9255
|
+
async videoToolStatus(sub, call = {}) {
|
|
9256
|
+
const { adapter, ctx } = videoToolTarget(sub.model, call);
|
|
9257
|
+
if (!adapter.videoToolStatus) throw noVideoTools(adapter, ctx.model);
|
|
9258
|
+
return adapter.videoToolStatus(sub, ctx);
|
|
9259
|
+
},
|
|
9260
|
+
async videoToolResult(sub, call = {}) {
|
|
9261
|
+
const { webhook, ...rest } = call;
|
|
9262
|
+
const { adapter, ctx } = videoToolTarget(sub.model, rest);
|
|
9263
|
+
if (!adapter.videoToolResult) throw noVideoTools(adapter, ctx.model);
|
|
9264
|
+
const result = await adapter.videoToolResult(sub, ctx, webhook);
|
|
9265
|
+
await emit({ ...result.usage, model: ctx.model.id, unit: ctx.model.usage.unit });
|
|
9266
|
+
return result;
|
|
9267
|
+
},
|
|
9268
|
+
async cancelVideoTool(sub, call = {}) {
|
|
9269
|
+
const { adapter, ctx } = videoToolTarget(sub.model, call);
|
|
9270
|
+
if (!adapter.cancelVideoTool) throw noVideoTools(adapter, ctx.model);
|
|
9271
|
+
return adapter.cancelVideoTool(sub, ctx);
|
|
9272
|
+
},
|
|
8732
9273
|
usageProvider(modelId, call = {}) {
|
|
8733
9274
|
const entry = catalog.require(modelId);
|
|
8734
9275
|
if (entry.type !== "text") return entry.adapter;
|
|
@@ -8854,6 +9395,7 @@ export {
|
|
|
8854
9395
|
SURFACES2 as SURFACES,
|
|
8855
9396
|
SurfaceSchema,
|
|
8856
9397
|
VIDEO_INPUT_SPEC_KEYS,
|
|
9398
|
+
VIDEO_TOOL_MODELS,
|
|
8857
9399
|
adapterServesType,
|
|
8858
9400
|
aiSdkTextAdapter,
|
|
8859
9401
|
arkAdapter,
|
|
@@ -8867,6 +9409,7 @@ export {
|
|
|
8867
9409
|
describeThrown,
|
|
8868
9410
|
generateImage as experimental_generateImage,
|
|
8869
9411
|
falAdapter,
|
|
9412
|
+
falWebhookBodySchema,
|
|
8870
9413
|
fileCatalogCache,
|
|
8871
9414
|
generateAudio,
|
|
8872
9415
|
generateImage,
|
|
@@ -8891,6 +9434,7 @@ export {
|
|
|
8891
9434
|
normalizeExposure,
|
|
8892
9435
|
openaiImageAdapter,
|
|
8893
9436
|
passthroughTextModel,
|
|
9437
|
+
planVideoTool,
|
|
8894
9438
|
pollUntil,
|
|
8895
9439
|
prepareMediaPart,
|
|
8896
9440
|
primeCatalog,
|
|
@@ -8898,6 +9442,7 @@ export {
|
|
|
8898
9442
|
readErrorBody,
|
|
8899
9443
|
replicateAdapter,
|
|
8900
9444
|
resetLiveCatalog,
|
|
9445
|
+
resolutionTier,
|
|
8901
9446
|
resolveAudioOptions,
|
|
8902
9447
|
resolveImageOptions,
|
|
8903
9448
|
resolveKeys,
|
|
@@ -8911,6 +9456,7 @@ export {
|
|
|
8911
9456
|
toGeneratedImage,
|
|
8912
9457
|
validateInputSpec,
|
|
8913
9458
|
videoLengthViolation,
|
|
9459
|
+
videoToolConstraints,
|
|
8914
9460
|
withRetry,
|
|
8915
9461
|
xaiVideoAdapter
|
|
8916
9462
|
};
|