@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.cjs
CHANGED
|
@@ -50,6 +50,7 @@ __export(index_exports, {
|
|
|
50
50
|
SURFACES: () => SURFACES2,
|
|
51
51
|
SurfaceSchema: () => SurfaceSchema,
|
|
52
52
|
VIDEO_INPUT_SPEC_KEYS: () => VIDEO_INPUT_SPEC_KEYS,
|
|
53
|
+
VIDEO_TOOL_MODELS: () => VIDEO_TOOL_MODELS,
|
|
53
54
|
adapterServesType: () => adapterServesType,
|
|
54
55
|
aiSdkTextAdapter: () => aiSdkTextAdapter,
|
|
55
56
|
arkAdapter: () => arkAdapter,
|
|
@@ -63,6 +64,7 @@ __export(index_exports, {
|
|
|
63
64
|
describeThrown: () => describeThrown,
|
|
64
65
|
experimental_generateImage: () => generateImage,
|
|
65
66
|
falAdapter: () => falAdapter,
|
|
67
|
+
falWebhookBodySchema: () => falWebhookBodySchema,
|
|
66
68
|
fileCatalogCache: () => fileCatalogCache,
|
|
67
69
|
generateAudio: () => generateAudio,
|
|
68
70
|
generateImage: () => generateImage,
|
|
@@ -87,6 +89,7 @@ __export(index_exports, {
|
|
|
87
89
|
normalizeExposure: () => normalizeExposure,
|
|
88
90
|
openaiImageAdapter: () => openaiImageAdapter,
|
|
89
91
|
passthroughTextModel: () => passthroughTextModel,
|
|
92
|
+
planVideoTool: () => planVideoTool,
|
|
90
93
|
pollUntil: () => pollUntil,
|
|
91
94
|
prepareMediaPart: () => prepareMediaPart,
|
|
92
95
|
primeCatalog: () => primeCatalog,
|
|
@@ -94,6 +97,7 @@ __export(index_exports, {
|
|
|
94
97
|
readErrorBody: () => readErrorBody,
|
|
95
98
|
replicateAdapter: () => replicateAdapter,
|
|
96
99
|
resetLiveCatalog: () => resetLiveCatalog,
|
|
100
|
+
resolutionTier: () => resolutionTier,
|
|
97
101
|
resolveAudioOptions: () => resolveAudioOptions,
|
|
98
102
|
resolveImageOptions: () => resolveImageOptions,
|
|
99
103
|
resolveKeys: () => resolveKeys,
|
|
@@ -107,6 +111,7 @@ __export(index_exports, {
|
|
|
107
111
|
toGeneratedImage: () => toGeneratedImage,
|
|
108
112
|
validateInputSpec: () => validateInputSpec,
|
|
109
113
|
videoLengthViolation: () => videoLengthViolation,
|
|
114
|
+
videoToolConstraints: () => videoToolConstraints,
|
|
110
115
|
withRetry: () => withRetry,
|
|
111
116
|
xaiVideoAdapter: () => xaiVideoAdapter
|
|
112
117
|
});
|
|
@@ -1416,6 +1421,11 @@ var NEGATIVE_PROMPT = "blur, distort, and low quality";
|
|
|
1416
1421
|
var FRAMES_EXCLUDE_REFERENCES = { framesExcludeReferences: true };
|
|
1417
1422
|
var KLING_PROMPT = { referenceSyntax: "numbered", maxChars: 2500 };
|
|
1418
1423
|
var SEEDANCE_PROMPT = { referenceSyntax: "numbered", maxChars: 3e4 };
|
|
1424
|
+
var SEEDANCE_2_AUDIO = {
|
|
1425
|
+
audioSeconds: { min: 2, max: 15, total: 15 },
|
|
1426
|
+
audioFormats: ["wav", "mp3"],
|
|
1427
|
+
audioMaxBytes: 15 * 1024 * 1024
|
|
1428
|
+
};
|
|
1419
1429
|
var H3_PROMPT = { referenceSyntax: "numbered", maxChars: 5e4 };
|
|
1420
1430
|
var OMNI_PROMPT = { referenceSyntax: "caption", maxChars: 5e4 };
|
|
1421
1431
|
var BYTEDANCE_LOGO = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/3bba5d81-4e57-4e71-911b-cdfa05acca2c_compressed.png";
|
|
@@ -1552,7 +1562,7 @@ var VIDEO_MODELS = [
|
|
|
1552
1562
|
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.",
|
|
1553
1563
|
logo: GOOGLE_LOGO2
|
|
1554
1564
|
},
|
|
1555
|
-
capabilities: { acceptsSourceVideo: true }
|
|
1565
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: true }
|
|
1556
1566
|
},
|
|
1557
1567
|
{
|
|
1558
1568
|
id: "gemini-omni-1.1-flash",
|
|
@@ -1577,7 +1587,7 @@ var VIDEO_MODELS = [
|
|
|
1577
1587
|
// with a video task, so those calls carry the prompt alone).
|
|
1578
1588
|
// First-to-last-frame interpolation: `<LAST_FRAME>` goes with `<FIRST_FRAME>`.
|
|
1579
1589
|
supports: ["videoExtension", "lastFrame"],
|
|
1580
|
-
extension: { segmentSeconds: 10, maxTotalSeconds: 40 },
|
|
1590
|
+
extension: { segmentSeconds: 10, maxTotalSeconds: 40, returns: "joined" },
|
|
1581
1591
|
prompt: OMNI_PROMPT,
|
|
1582
1592
|
audio: "always"
|
|
1583
1593
|
},
|
|
@@ -1589,7 +1599,11 @@ var VIDEO_MODELS = [
|
|
|
1589
1599
|
logo: GOOGLE_LOGO2,
|
|
1590
1600
|
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."
|
|
1591
1601
|
},
|
|
1592
|
-
capabilities: {
|
|
1602
|
+
capabilities: {
|
|
1603
|
+
acceptsSourceVideo: true,
|
|
1604
|
+
videoEdit: true,
|
|
1605
|
+
lastFrameRequiresFirstFrame: true
|
|
1606
|
+
}
|
|
1593
1607
|
},
|
|
1594
1608
|
{
|
|
1595
1609
|
// vibe-triggers and Space Builder drop the ratio when a frame is wired; Cowork always sends it.
|
|
@@ -1611,7 +1625,8 @@ var VIDEO_MODELS = [
|
|
|
1611
1625
|
videos: 3,
|
|
1612
1626
|
audios: 3,
|
|
1613
1627
|
audioOnly: false,
|
|
1614
|
-
videoSeconds: { min: 2, max: 15, total: 15 }
|
|
1628
|
+
videoSeconds: { min: 2, max: 15, total: 15 },
|
|
1629
|
+
...SEEDANCE_2_AUDIO
|
|
1615
1630
|
},
|
|
1616
1631
|
sourceVideoSeconds: { min: 2, max: 15, inReferenceTotal: true },
|
|
1617
1632
|
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
@@ -1633,7 +1648,7 @@ var VIDEO_MODELS = [
|
|
|
1633
1648
|
description: "High-quality AI video generation with reference image conditioning. Supports 4-15 second clips with human preprocessing.",
|
|
1634
1649
|
logo: BYTEDANCE_LOGO
|
|
1635
1650
|
},
|
|
1636
|
-
capabilities: { acceptsSourceVideo: true, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1651
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: false, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1637
1652
|
},
|
|
1638
1653
|
{
|
|
1639
1654
|
id: "seedance-2.0-fast",
|
|
@@ -1653,7 +1668,8 @@ var VIDEO_MODELS = [
|
|
|
1653
1668
|
videos: 3,
|
|
1654
1669
|
audios: 3,
|
|
1655
1670
|
audioOnly: false,
|
|
1656
|
-
videoSeconds: { min: 2, max: 15, total: 15 }
|
|
1671
|
+
videoSeconds: { min: 2, max: 15, total: 15 },
|
|
1672
|
+
...SEEDANCE_2_AUDIO
|
|
1657
1673
|
},
|
|
1658
1674
|
sourceVideoSeconds: { min: 2, max: 15, inReferenceTotal: true },
|
|
1659
1675
|
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
@@ -1675,7 +1691,7 @@ var VIDEO_MODELS = [
|
|
|
1675
1691
|
logo: BYTEDANCE_LOGO,
|
|
1676
1692
|
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."
|
|
1677
1693
|
},
|
|
1678
|
-
capabilities: { acceptsSourceVideo: true, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1694
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: false, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1679
1695
|
},
|
|
1680
1696
|
{
|
|
1681
1697
|
// omni_reference_task_type edit/extend: adaptive ratio, edit sends duration -1.
|
|
@@ -1695,12 +1711,20 @@ var VIDEO_MODELS = [
|
|
|
1695
1711
|
images: 30,
|
|
1696
1712
|
videos: 10,
|
|
1697
1713
|
audios: 10,
|
|
1698
|
-
videoSeconds: { min: 2, max: 30, total: 30, editMin: 4 }
|
|
1714
|
+
videoSeconds: { min: 2, max: 30, total: 30, editMin: 4 },
|
|
1715
|
+
// BytePlus: 2-30 s per clip, 30 s in all, wav/mp3, 15 MB each.
|
|
1716
|
+
audioSeconds: { min: 2, max: 30, total: 30 },
|
|
1717
|
+
audioFormats: ["wav", "mp3"],
|
|
1718
|
+
audioMaxBytes: 15 * 1024 * 1024
|
|
1699
1719
|
},
|
|
1700
1720
|
sourceVideoSeconds: { min: 2, max: 30, editMin: 4, inReferenceTotal: true },
|
|
1701
1721
|
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
1702
1722
|
// No seed: 2.x echoes it but does not honour it (two seeded runs differed, 2026-10-01).
|
|
1703
|
-
supports: ["generateAudio", "lastFrame", "watermark", "taskType"],
|
|
1723
|
+
supports: ["generateAudio", "lastFrame", "watermark", "taskType", "videoExtension"],
|
|
1724
|
+
// Extend (probe 2026-10-02, 480p): returns ONLY the added footage, continuing from
|
|
1725
|
+
// the source's last frame at the source's framing and fps but at the requested
|
|
1726
|
+
// resolution, so the caller joins the clips. Forward only in practice.
|
|
1727
|
+
extension: { segmentSeconds: 30, maxTotalSeconds: 60, returns: "new" },
|
|
1704
1728
|
prompt: SEEDANCE_PROMPT,
|
|
1705
1729
|
audio: "optional"
|
|
1706
1730
|
},
|
|
@@ -1717,7 +1741,7 @@ var VIDEO_MODELS = [
|
|
|
1717
1741
|
logo: BYTEDANCE_LOGO,
|
|
1718
1742
|
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."
|
|
1719
1743
|
},
|
|
1720
|
-
capabilities: { acceptsSourceVideo: true, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1744
|
+
capabilities: { acceptsSourceVideo: true, videoEdit: true, ...FRAMES_EXCLUDE_REFERENCES }
|
|
1721
1745
|
},
|
|
1722
1746
|
{
|
|
1723
1747
|
id: "grok-imagine",
|
|
@@ -2081,11 +2105,116 @@ var VIDEO_MODELS = [
|
|
|
2081
2105
|
}
|
|
2082
2106
|
];
|
|
2083
2107
|
|
|
2108
|
+
// src/catalog/video-tools.ts
|
|
2109
|
+
var TOPAZ_LOGO = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/topazlabs.png";
|
|
2110
|
+
var TOPAZ_SOURCE_SECONDS = { max: 300 };
|
|
2111
|
+
var TOPAZ_USAGE = { unit: "seconds" };
|
|
2112
|
+
var VIDEO_TOOL_MODELS = [
|
|
2113
|
+
{
|
|
2114
|
+
id: "topaz-precision",
|
|
2115
|
+
aliases: [],
|
|
2116
|
+
label: "Topaz Precision",
|
|
2117
|
+
type: "video-tool",
|
|
2118
|
+
adapter: "fal",
|
|
2119
|
+
providerModelId: "topaz/upscale/video/precision",
|
|
2120
|
+
lifecycle: "active",
|
|
2121
|
+
exposure: ["cowork"],
|
|
2122
|
+
constraints: {
|
|
2123
|
+
supports: [],
|
|
2124
|
+
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
2125
|
+
tool: { kind: "upscale", upscaleFactor: { min: 1, max: 4 }, maxOutputLongEdge: 3840 }
|
|
2126
|
+
},
|
|
2127
|
+
defaults: {},
|
|
2128
|
+
providerOptions: { fal: { model: "Proteus" } },
|
|
2129
|
+
usage: TOPAZ_USAGE,
|
|
2130
|
+
pricingKind: "video_per_second",
|
|
2131
|
+
display: {
|
|
2132
|
+
provider: "topaz",
|
|
2133
|
+
logo: TOPAZ_LOGO,
|
|
2134
|
+
description: "Topaz Proteus upscaling: sharper, cleaner footage up to 4K while staying faithful to the source.",
|
|
2135
|
+
sortOrder: 20
|
|
2136
|
+
}
|
|
2137
|
+
},
|
|
2138
|
+
{
|
|
2139
|
+
id: "topaz-starlight",
|
|
2140
|
+
aliases: [],
|
|
2141
|
+
label: "Topaz Starlight",
|
|
2142
|
+
type: "video-tool",
|
|
2143
|
+
adapter: "fal",
|
|
2144
|
+
providerModelId: "topaz/upscale/video/generative",
|
|
2145
|
+
lifecycle: "active",
|
|
2146
|
+
exposure: ["cowork"],
|
|
2147
|
+
constraints: {
|
|
2148
|
+
supports: [],
|
|
2149
|
+
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
2150
|
+
tool: { kind: "upscale", upscaleFactor: { min: 1, max: 4 }, maxOutputLongEdge: 3840 }
|
|
2151
|
+
},
|
|
2152
|
+
defaults: {},
|
|
2153
|
+
providerOptions: { fal: { model: "Starlight Precise 2.6" } },
|
|
2154
|
+
usage: TOPAZ_USAGE,
|
|
2155
|
+
pricingKind: "video_per_second",
|
|
2156
|
+
display: {
|
|
2157
|
+
provider: "topaz",
|
|
2158
|
+
logo: TOPAZ_LOGO,
|
|
2159
|
+
description: "Topaz Starlight Precise 2.6: generative upscaling that rebuilds fine detail, up to 4K. Slower and costlier than Precision.",
|
|
2160
|
+
sortOrder: 10
|
|
2161
|
+
}
|
|
2162
|
+
},
|
|
2163
|
+
{
|
|
2164
|
+
id: "topaz-apollo",
|
|
2165
|
+
aliases: [],
|
|
2166
|
+
label: "Topaz Apollo",
|
|
2167
|
+
type: "video-tool",
|
|
2168
|
+
adapter: "fal",
|
|
2169
|
+
providerModelId: "topaz/interpolate/video",
|
|
2170
|
+
lifecycle: "active",
|
|
2171
|
+
exposure: ["cowork"],
|
|
2172
|
+
constraints: {
|
|
2173
|
+
supports: [],
|
|
2174
|
+
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
2175
|
+
tool: { kind: "interpolate", fps: { min: 16, max: 120 } }
|
|
2176
|
+
},
|
|
2177
|
+
defaults: {},
|
|
2178
|
+
providerOptions: { fal: { model: "Apollo" } },
|
|
2179
|
+
usage: TOPAZ_USAGE,
|
|
2180
|
+
pricingKind: "video_per_second",
|
|
2181
|
+
display: {
|
|
2182
|
+
provider: "topaz",
|
|
2183
|
+
logo: TOPAZ_LOGO,
|
|
2184
|
+
description: "Topaz Apollo frame interpolation: smoother motion at up to 120 fps, same length as the source."
|
|
2185
|
+
}
|
|
2186
|
+
},
|
|
2187
|
+
{
|
|
2188
|
+
id: "topaz-hyperion-2.5",
|
|
2189
|
+
aliases: [],
|
|
2190
|
+
label: "Topaz Hyperion 2.5",
|
|
2191
|
+
type: "video-tool",
|
|
2192
|
+
adapter: "fal",
|
|
2193
|
+
providerModelId: "topaz/sdr-to-hdr/video",
|
|
2194
|
+
lifecycle: "active",
|
|
2195
|
+
exposure: ["cowork"],
|
|
2196
|
+
constraints: {
|
|
2197
|
+
supports: [],
|
|
2198
|
+
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
2199
|
+
tool: { kind: "hdr", outputFormats: ["h265", "prores"] }
|
|
2200
|
+
},
|
|
2201
|
+
defaults: {},
|
|
2202
|
+
usage: TOPAZ_USAGE,
|
|
2203
|
+
pricingKind: "video_per_second",
|
|
2204
|
+
display: {
|
|
2205
|
+
provider: "topaz",
|
|
2206
|
+
logo: TOPAZ_LOGO,
|
|
2207
|
+
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."
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
];
|
|
2211
|
+
|
|
2084
2212
|
// src/catalog/models.ts
|
|
2085
2213
|
var MODELS = [
|
|
2086
2214
|
...TEXT_MODELS,
|
|
2087
2215
|
...IMAGE_MODELS,
|
|
2088
2216
|
...VIDEO_MODELS,
|
|
2217
|
+
...VIDEO_TOOL_MODELS,
|
|
2089
2218
|
...OTHER_MODELS
|
|
2090
2219
|
];
|
|
2091
2220
|
|
|
@@ -2240,6 +2369,10 @@ var ALL_KEY_SET = /* @__PURE__ */ new Set([
|
|
|
2240
2369
|
...IMAGE_INPUT_SPEC_KEYS,
|
|
2241
2370
|
...AUDIO_INPUT_SPEC_KEYS
|
|
2242
2371
|
]);
|
|
2372
|
+
var TYPES_BY_ADAPTER = /* @__PURE__ */ new Map([
|
|
2373
|
+
["replicate", ["video", "image", "audio"]],
|
|
2374
|
+
["fal", ["image"]]
|
|
2375
|
+
]);
|
|
2243
2376
|
var ALLOWED_KEYS_BY_TYPE = /* @__PURE__ */ new Map([
|
|
2244
2377
|
["video", VIDEO_KEY_SET],
|
|
2245
2378
|
["image", IMAGE_KEY_SET],
|
|
@@ -2278,7 +2411,8 @@ var StaticSchema = import_zod2.z.record(import_zod2.z.string(), ProviderScalarSc
|
|
|
2278
2411
|
var InputSpecSchema = import_zod2.z.strictObject({
|
|
2279
2412
|
fields: FieldsSchema,
|
|
2280
2413
|
values: ValuesSchema.optional(),
|
|
2281
|
-
static: StaticSchema.optional()
|
|
2414
|
+
static: StaticSchema.optional(),
|
|
2415
|
+
editEndpoint: import_zod2.z.string().min(1).optional()
|
|
2282
2416
|
}).superRefine((spec, ctx) => {
|
|
2283
2417
|
const mappedNames = new Set(Object.values(spec.fields));
|
|
2284
2418
|
for (const key of Object.keys(spec.static ?? {})) {
|
|
@@ -2306,18 +2440,21 @@ function validateInputSpec(raw, row) {
|
|
|
2306
2440
|
};
|
|
2307
2441
|
}
|
|
2308
2442
|
const spec = parsed.data;
|
|
2309
|
-
|
|
2443
|
+
const supportedTypes = TYPES_BY_ADAPTER.get(row.adapter);
|
|
2444
|
+
if (supportedTypes === void 0) {
|
|
2310
2445
|
return {
|
|
2311
2446
|
ok: false,
|
|
2312
|
-
issues: [
|
|
2447
|
+
issues: [
|
|
2448
|
+
{ path: [], message: "inputSpec is only supported on replicate and fal rows" }
|
|
2449
|
+
]
|
|
2313
2450
|
};
|
|
2314
2451
|
}
|
|
2315
2452
|
const issues = [];
|
|
2316
2453
|
const allowed = ALLOWED_KEYS_BY_TYPE.get(row.type);
|
|
2317
|
-
if (allowed === void 0) {
|
|
2454
|
+
if (allowed === void 0 || !supportedTypes.includes(row.type)) {
|
|
2318
2455
|
issues.push({
|
|
2319
2456
|
path: [],
|
|
2320
|
-
message: `inputSpec is not supported for "${row.type}" rows`
|
|
2457
|
+
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`
|
|
2321
2458
|
});
|
|
2322
2459
|
} else {
|
|
2323
2460
|
for (const key of Object.keys(spec.fields)) {
|
|
@@ -2337,6 +2474,19 @@ function validateInputSpec(raw, row) {
|
|
|
2337
2474
|
}
|
|
2338
2475
|
}
|
|
2339
2476
|
}
|
|
2477
|
+
if (spec.editEndpoint !== void 0) {
|
|
2478
|
+
if (row.adapter !== "fal") {
|
|
2479
|
+
issues.push({
|
|
2480
|
+
path: ["editEndpoint"],
|
|
2481
|
+
message: "inputSpec.editEndpoint is only supported on fal rows"
|
|
2482
|
+
});
|
|
2483
|
+
} else if (!("references" in spec.fields)) {
|
|
2484
|
+
issues.push({
|
|
2485
|
+
path: ["editEndpoint"],
|
|
2486
|
+
message: 'inputSpec.editEndpoint needs a "references" entry in inputSpec.fields'
|
|
2487
|
+
});
|
|
2488
|
+
}
|
|
2489
|
+
}
|
|
2340
2490
|
const seenNames = /* @__PURE__ */ new Map();
|
|
2341
2491
|
for (const [key, name] of Object.entries(spec.fields)) {
|
|
2342
2492
|
const first = seenNames.get(name);
|
|
@@ -2382,7 +2532,15 @@ var ADAPTER_IDS = [
|
|
|
2382
2532
|
"higgsfield",
|
|
2383
2533
|
"xai-video"
|
|
2384
2534
|
];
|
|
2385
|
-
var ModelTypeSchema = import_zod3.z.enum([
|
|
2535
|
+
var ModelTypeSchema = import_zod3.z.enum([
|
|
2536
|
+
"text",
|
|
2537
|
+
"image",
|
|
2538
|
+
"video",
|
|
2539
|
+
"audio",
|
|
2540
|
+
"upscale",
|
|
2541
|
+
"bg-remove",
|
|
2542
|
+
"video-tool"
|
|
2543
|
+
]);
|
|
2386
2544
|
var LifecycleSchema = import_zod3.z.enum(["active", "deprecated", "retired"]);
|
|
2387
2545
|
var SurfaceSchema = import_zod3.z.enum(["cowork", "space_builder"]);
|
|
2388
2546
|
var SURFACES2 = SurfaceSchema.options;
|
|
@@ -2462,7 +2620,22 @@ var ReferenceLimitsSchema = import_zod3.z.looseObject({
|
|
|
2462
2620
|
audios: import_zod3.z.number().optional(),
|
|
2463
2621
|
total: import_zod3.z.number().optional(),
|
|
2464
2622
|
audioOnly: import_zod3.z.boolean().optional(),
|
|
2465
|
-
videoSeconds: VideoSecondsLimitsSchema.optional()
|
|
2623
|
+
videoSeconds: VideoSecondsLimitsSchema.optional(),
|
|
2624
|
+
audioSeconds: import_zod3.z.looseObject({
|
|
2625
|
+
min: import_zod3.z.number().optional(),
|
|
2626
|
+
max: import_zod3.z.number().optional(),
|
|
2627
|
+
total: import_zod3.z.number().optional()
|
|
2628
|
+
}).optional(),
|
|
2629
|
+
audioFormats: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
2630
|
+
audioMaxBytes: import_zod3.z.number().positive().optional()
|
|
2631
|
+
});
|
|
2632
|
+
var RangeSchema = import_zod3.z.looseObject({ min: import_zod3.z.number(), max: import_zod3.z.number() });
|
|
2633
|
+
var VideoToolConstraintsSchema = import_zod3.z.looseObject({
|
|
2634
|
+
kind: import_zod3.z.enum(["upscale", "interpolate", "hdr"]),
|
|
2635
|
+
upscaleFactor: RangeSchema.optional(),
|
|
2636
|
+
maxOutputLongEdge: import_zod3.z.number().positive().optional(),
|
|
2637
|
+
fps: RangeSchema.optional(),
|
|
2638
|
+
outputFormats: import_zod3.z.array(import_zod3.z.enum(["h265", "prores"])).min(1).optional()
|
|
2466
2639
|
});
|
|
2467
2640
|
var ModelConstraintsSchema = import_zod3.z.looseObject({
|
|
2468
2641
|
aspectRatios: import_zod3.z.array(AspectRatioSchema).optional(),
|
|
@@ -2477,7 +2650,14 @@ var ModelConstraintsSchema = import_zod3.z.looseObject({
|
|
|
2477
2650
|
supports: import_zod3.z.array(SupportedOptionSchema).optional(),
|
|
2478
2651
|
ratioIgnoredWith: import_zod3.z.array(import_zod3.z.enum(["firstFrame", "sourceVideo"])).optional(),
|
|
2479
2652
|
sourceVideoSeconds: VideoSecondsLimitsSchema.omit({ total: true }).extend({ inReferenceTotal: import_zod3.z.boolean().optional() }).optional(),
|
|
2480
|
-
|
|
2653
|
+
// segmentSeconds/maxTotalSeconds stay required: a kit before 0.3.0 drops a row whose
|
|
2654
|
+
// extension lacks them, so every extension block keeps them.
|
|
2655
|
+
extension: import_zod3.z.looseObject({
|
|
2656
|
+
segmentSeconds: import_zod3.z.number(),
|
|
2657
|
+
maxTotalSeconds: import_zod3.z.number(),
|
|
2658
|
+
returns: import_zod3.z.enum(["new", "joined"]).optional()
|
|
2659
|
+
}).optional(),
|
|
2660
|
+
tool: VideoToolConstraintsSchema.optional(),
|
|
2481
2661
|
// Loose on purpose: the read path keeps a row whose value is invalid (the accessors in
|
|
2482
2662
|
// conventions.ts read it as "not set"); CatalogModelSchema below rejects it on write.
|
|
2483
2663
|
audio: import_zod3.z.unknown().optional(),
|
|
@@ -2549,6 +2729,7 @@ var CatalogDisplaySchema = import_zod3.z.looseObject({
|
|
|
2549
2729
|
});
|
|
2550
2730
|
var CatalogCapabilitiesSchema = import_zod3.z.looseObject({
|
|
2551
2731
|
acceptsSourceVideo: import_zod3.z.boolean().optional(),
|
|
2732
|
+
videoEdit: import_zod3.z.boolean().optional(),
|
|
2552
2733
|
framesExcludeReferences: import_zod3.z.boolean().optional(),
|
|
2553
2734
|
lastFrameRequiresFirstFrame: import_zod3.z.boolean().optional(),
|
|
2554
2735
|
reasoning: import_zod3.z.boolean().optional(),
|
|
@@ -2591,6 +2772,13 @@ var CatalogModelSchemaBase = import_zod3.z.looseObject({
|
|
|
2591
2772
|
message: "active text rows need contextWindow"
|
|
2592
2773
|
});
|
|
2593
2774
|
}
|
|
2775
|
+
if (row.type === "video-tool" && row.constraints.tool === void 0) {
|
|
2776
|
+
ctx.addIssue({
|
|
2777
|
+
code: "custom",
|
|
2778
|
+
path: ["constraints", "tool"],
|
|
2779
|
+
message: "video-tool rows need constraints.tool"
|
|
2780
|
+
});
|
|
2781
|
+
}
|
|
2594
2782
|
if (row.replacedBy !== void 0 && row.replacedBy === row.id) {
|
|
2595
2783
|
ctx.addIssue({
|
|
2596
2784
|
code: "custom",
|
|
@@ -3597,7 +3785,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
3597
3785
|
}
|
|
3598
3786
|
|
|
3599
3787
|
// src/adapters/fal.ts
|
|
3600
|
-
var
|
|
3788
|
+
var import_zod12 = require("zod");
|
|
3601
3789
|
var import_client = require("@fal-ai/client");
|
|
3602
3790
|
|
|
3603
3791
|
// src/adapters/fal-http.ts
|
|
@@ -3685,6 +3873,428 @@ function createFalHttpClient(opts) {
|
|
|
3685
3873
|
};
|
|
3686
3874
|
}
|
|
3687
3875
|
|
|
3876
|
+
// src/adapters/fal-gateway.ts
|
|
3877
|
+
var import_zod9 = require("zod");
|
|
3878
|
+
var falDetailSchema = import_zod9.z.object({ detail: JsonValueSchema });
|
|
3879
|
+
function liftDetail(body) {
|
|
3880
|
+
const parsed = falDetailSchema.safeParse(body);
|
|
3881
|
+
const detail = parsed.success ? parsed.data.detail : void 0;
|
|
3882
|
+
return detail ?? body;
|
|
3883
|
+
}
|
|
3884
|
+
function falError(status, body, model) {
|
|
3885
|
+
return classifyHttpError(status, liftDetail(body), "fal", model);
|
|
3886
|
+
}
|
|
3887
|
+
function gatewayConfig(ctx) {
|
|
3888
|
+
const cf = ctx.routing.cloudflare;
|
|
3889
|
+
const falKey = ctx.keys.fal;
|
|
3890
|
+
const cfToken = ctx.keys.cloudflare;
|
|
3891
|
+
if (!cf?.accountId || !cf?.gatewayId || !falKey && !cfToken) {
|
|
3892
|
+
throw new ModelKitError({
|
|
3893
|
+
code: "auth",
|
|
3894
|
+
message: "fal passthrough is not configured. Set routing.cloudflare and FAL_KEY or the gateway token (BYOK).",
|
|
3895
|
+
provider: "fal",
|
|
3896
|
+
model: ctx.model.id,
|
|
3897
|
+
retryable: false
|
|
3898
|
+
});
|
|
3899
|
+
}
|
|
3900
|
+
const config = {
|
|
3901
|
+
baseUrl: `https://gateway.ai.cloudflare.com/v1/${cf.accountId}/${cf.gatewayId}/fal`
|
|
3902
|
+
};
|
|
3903
|
+
if (falKey) config.falKey = falKey;
|
|
3904
|
+
if (cfToken) config.cfToken = cfToken;
|
|
3905
|
+
if (ctx.call.maxRetries !== void 0) config.singleAttempt = true;
|
|
3906
|
+
if (ctx.signal !== void 0) config.signal = ctx.signal;
|
|
3907
|
+
return config;
|
|
3908
|
+
}
|
|
3909
|
+
async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
|
|
3910
|
+
const headers2 = { "x-fal-target-url": targetUrl };
|
|
3911
|
+
if (cfg.falKey) headers2.Authorization = `Bearer ${cfg.falKey}`;
|
|
3912
|
+
if (init.body) headers2["Content-Type"] = "application/json";
|
|
3913
|
+
if (cfg.cfToken) headers2["cf-aig-authorization"] = `Bearer ${cfg.cfToken}`;
|
|
3914
|
+
if (cfg.singleAttempt) headers2["cf-aig-max-attempts"] = "1";
|
|
3915
|
+
const request = { method: init.method, headers: headers2 };
|
|
3916
|
+
if (cfg.signal !== void 0) request.signal = cfg.signal;
|
|
3917
|
+
if (init.body !== void 0) request.body = init.body;
|
|
3918
|
+
return fetchImpl(cfg.baseUrl, request);
|
|
3919
|
+
}
|
|
3920
|
+
|
|
3921
|
+
// src/adapters/fal-video-tools.ts
|
|
3922
|
+
var import_zod11 = require("zod");
|
|
3923
|
+
|
|
3924
|
+
// src/catalog/video-tools-spec.ts
|
|
3925
|
+
var import_zod10 = require("zod");
|
|
3926
|
+
var RangeSchema2 = import_zod10.z.object({ min: import_zod10.z.number(), max: import_zod10.z.number() });
|
|
3927
|
+
var ToolSchema = import_zod10.z.object({
|
|
3928
|
+
kind: import_zod10.z.enum(["upscale", "interpolate", "hdr"]),
|
|
3929
|
+
upscaleFactor: RangeSchema2.optional(),
|
|
3930
|
+
maxOutputLongEdge: import_zod10.z.number().positive().optional(),
|
|
3931
|
+
fps: RangeSchema2.optional(),
|
|
3932
|
+
outputFormats: import_zod10.z.array(import_zod10.z.enum(["h265", "prores"])).min(1).optional()
|
|
3933
|
+
});
|
|
3934
|
+
function videoToolConstraints(row) {
|
|
3935
|
+
if (row.type !== "video-tool") return void 0;
|
|
3936
|
+
const parsed = ToolSchema.safeParse(row.constraints.tool);
|
|
3937
|
+
if (!parsed.success) return void 0;
|
|
3938
|
+
const { kind, upscaleFactor, maxOutputLongEdge, fps, outputFormats } = parsed.data;
|
|
3939
|
+
return {
|
|
3940
|
+
kind,
|
|
3941
|
+
...upscaleFactor !== void 0 && { upscaleFactor },
|
|
3942
|
+
...maxOutputLongEdge !== void 0 && { maxOutputLongEdge },
|
|
3943
|
+
...fps !== void 0 && { fps },
|
|
3944
|
+
...outputFormats !== void 0 && { outputFormats }
|
|
3945
|
+
};
|
|
3946
|
+
}
|
|
3947
|
+
function resolutionTier(width, height) {
|
|
3948
|
+
const shortEdge = Math.min(width, height);
|
|
3949
|
+
if (shortEdge <= 360) return "360p";
|
|
3950
|
+
if (shortEdge <= 480) return "480p";
|
|
3951
|
+
if (shortEdge <= 720) return "720p";
|
|
3952
|
+
if (shortEdge <= 1080) return "1080p";
|
|
3953
|
+
if (shortEdge <= 1440) return "2k";
|
|
3954
|
+
return "4k";
|
|
3955
|
+
}
|
|
3956
|
+
function fail(error) {
|
|
3957
|
+
return { ok: false, error };
|
|
3958
|
+
}
|
|
3959
|
+
function planVideoTool(row, req) {
|
|
3960
|
+
const tool = videoToolConstraints(row);
|
|
3961
|
+
if (!tool) return fail(`${row.id} is not a video tool`);
|
|
3962
|
+
const { width, height, durationSeconds, fps } = req.source;
|
|
3963
|
+
if (!(width > 0 && height > 0 && durationSeconds > 0)) {
|
|
3964
|
+
return fail("The source video's width, height and duration are required");
|
|
3965
|
+
}
|
|
3966
|
+
const maxSeconds = row.constraints.sourceVideoSeconds?.max;
|
|
3967
|
+
if (maxSeconds !== void 0 && durationSeconds > maxSeconds) {
|
|
3968
|
+
return fail(`${row.label} takes source videos up to ${maxSeconds} seconds.`);
|
|
3969
|
+
}
|
|
3970
|
+
const base = {
|
|
3971
|
+
durationSeconds,
|
|
3972
|
+
...fps !== void 0 && { fps }
|
|
3973
|
+
};
|
|
3974
|
+
if (tool.kind === "upscale") {
|
|
3975
|
+
const factor = req.upscaleFactor;
|
|
3976
|
+
if (factor === void 0) return fail("An upscale factor is required");
|
|
3977
|
+
const range = tool.upscaleFactor;
|
|
3978
|
+
if (range && (factor < range.min || factor > range.max)) {
|
|
3979
|
+
return fail(`${row.label} upscales by ${range.min}x to ${range.max}x.`);
|
|
3980
|
+
}
|
|
3981
|
+
const outWidth = Math.round(width * factor);
|
|
3982
|
+
const outHeight = Math.round(height * factor);
|
|
3983
|
+
const limit = tool.maxOutputLongEdge;
|
|
3984
|
+
if (limit !== void 0 && Math.max(outWidth, outHeight) > limit) {
|
|
3985
|
+
return fail(
|
|
3986
|
+
`A ${factor}x upscale of a ${width}x${height} video passes the ${limit}px limit.`
|
|
3987
|
+
);
|
|
3988
|
+
}
|
|
3989
|
+
return {
|
|
3990
|
+
ok: true,
|
|
3991
|
+
output: {
|
|
3992
|
+
...base,
|
|
3993
|
+
width: outWidth,
|
|
3994
|
+
height: outHeight,
|
|
3995
|
+
resolution: resolutionTier(outWidth, outHeight),
|
|
3996
|
+
format: "h264"
|
|
3997
|
+
}
|
|
3998
|
+
};
|
|
3999
|
+
}
|
|
4000
|
+
if (tool.kind === "interpolate") {
|
|
4001
|
+
const target = req.targetFps;
|
|
4002
|
+
if (target === void 0 || !Number.isInteger(target)) {
|
|
4003
|
+
return fail("A whole-number target frame rate is required");
|
|
4004
|
+
}
|
|
4005
|
+
const range = tool.fps;
|
|
4006
|
+
if (range && (target < range.min || target > range.max)) {
|
|
4007
|
+
return fail(`${row.label} outputs ${range.min} to ${range.max} fps.`);
|
|
4008
|
+
}
|
|
4009
|
+
return {
|
|
4010
|
+
ok: true,
|
|
4011
|
+
output: {
|
|
4012
|
+
durationSeconds,
|
|
4013
|
+
fps: target,
|
|
4014
|
+
width,
|
|
4015
|
+
height,
|
|
4016
|
+
resolution: resolutionTier(width, height),
|
|
4017
|
+
format: "h264"
|
|
4018
|
+
}
|
|
4019
|
+
};
|
|
4020
|
+
}
|
|
4021
|
+
const formats = tool.outputFormats ?? ["h265"];
|
|
4022
|
+
const format = req.outputFormat ?? formats[0] ?? "h265";
|
|
4023
|
+
if (!formats.includes(format)) {
|
|
4024
|
+
return fail(`${row.label} writes ${formats.join(" or ")}.`);
|
|
4025
|
+
}
|
|
4026
|
+
return {
|
|
4027
|
+
ok: true,
|
|
4028
|
+
output: { ...base, width, height, resolution: resolutionTier(width, height), format }
|
|
4029
|
+
};
|
|
4030
|
+
}
|
|
4031
|
+
|
|
4032
|
+
// src/adapters/fal-video-tools.ts
|
|
4033
|
+
var FAL_QUEUE_ORIGIN = "https://queue.fal.run";
|
|
4034
|
+
var queueUrlSchema = import_zod11.z.url().refine((value) => new URL(value).origin === FAL_QUEUE_ORIGIN, {
|
|
4035
|
+
message: "not a fal queue URL"
|
|
4036
|
+
});
|
|
4037
|
+
var submitResponseSchema = import_zod11.z.object({
|
|
4038
|
+
request_id: import_zod11.z.string().min(1),
|
|
4039
|
+
status_url: queueUrlSchema,
|
|
4040
|
+
response_url: queueUrlSchema,
|
|
4041
|
+
cancel_url: queueUrlSchema
|
|
4042
|
+
});
|
|
4043
|
+
var statusResponseSchema = import_zod11.z.object({ status: import_zod11.z.string() });
|
|
4044
|
+
var videoFileSchema = import_zod11.z.object({
|
|
4045
|
+
url: import_zod11.z.url(),
|
|
4046
|
+
content_type: import_zod11.z.string().nullish(),
|
|
4047
|
+
file_size: import_zod11.z.number().nullish()
|
|
4048
|
+
});
|
|
4049
|
+
var toolOutputSchema = import_zod11.z.object({ video: videoFileSchema });
|
|
4050
|
+
var falWebhookBodySchema = import_zod11.z.object({
|
|
4051
|
+
request_id: import_zod11.z.string().min(1),
|
|
4052
|
+
gateway_request_id: import_zod11.z.string().nullish(),
|
|
4053
|
+
status: import_zod11.z.enum(["OK", "ERROR"]),
|
|
4054
|
+
payload: JsonValueSchema.nullish(),
|
|
4055
|
+
error: import_zod11.z.string().nullish(),
|
|
4056
|
+
payload_error: JsonValueSchema.nullish()
|
|
4057
|
+
});
|
|
4058
|
+
async function queueFetch(ctx, url, method, body) {
|
|
4059
|
+
const payload = body === void 0 ? void 0 : JSON.stringify(body);
|
|
4060
|
+
try {
|
|
4061
|
+
if (ctx.routing.fal === "cloudflare-passthrough") {
|
|
4062
|
+
return await gatewayFetch(gatewayConfig(ctx), ctx.fetch, url, {
|
|
4063
|
+
method,
|
|
4064
|
+
...payload !== void 0 && { body: payload }
|
|
4065
|
+
});
|
|
4066
|
+
}
|
|
4067
|
+
const falKey = ctx.keys.fal;
|
|
4068
|
+
if (!falKey) {
|
|
4069
|
+
throw new ModelKitError({
|
|
4070
|
+
code: "auth",
|
|
4071
|
+
message: "Missing API key for fal",
|
|
4072
|
+
provider: "fal",
|
|
4073
|
+
model: ctx.model.id,
|
|
4074
|
+
retryable: false
|
|
4075
|
+
});
|
|
4076
|
+
}
|
|
4077
|
+
return await ctx.fetch(url, {
|
|
4078
|
+
method,
|
|
4079
|
+
headers: {
|
|
4080
|
+
Authorization: `Key ${falKey}`,
|
|
4081
|
+
...payload !== void 0 && { "Content-Type": "application/json" }
|
|
4082
|
+
},
|
|
4083
|
+
...payload !== void 0 && { body: payload },
|
|
4084
|
+
...ctx.signal !== void 0 && { signal: ctx.signal }
|
|
4085
|
+
});
|
|
4086
|
+
} catch (cause) {
|
|
4087
|
+
if (cause instanceof ModelKitError) throw cause;
|
|
4088
|
+
throw classifyThrown("fal", cause, ctx.model.id);
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
async function readJson(ctx, res) {
|
|
4092
|
+
if (!res.ok) throw falError(res.status, await readBody(res), ctx.model.id);
|
|
4093
|
+
return JsonValueSchema.parse(await res.json());
|
|
4094
|
+
}
|
|
4095
|
+
function providerModelName(ctx) {
|
|
4096
|
+
return import_zod11.z.string().safeParse(ctx.model.providerOptions?.["fal"]?.["model"]).data;
|
|
4097
|
+
}
|
|
4098
|
+
function toolInput(ctx, req, output) {
|
|
4099
|
+
const tool = videoToolConstraints(ctx.model);
|
|
4100
|
+
const model = providerModelName(ctx);
|
|
4101
|
+
const input = { video_url: req.source.url };
|
|
4102
|
+
if (tool?.kind === "upscale") {
|
|
4103
|
+
if (model !== void 0) input["model"] = model;
|
|
4104
|
+
input["upscale_factor"] = req.upscaleFactor ?? 1;
|
|
4105
|
+
input["H264_output"] = true;
|
|
4106
|
+
} else if (tool?.kind === "interpolate") {
|
|
4107
|
+
if (model !== void 0) input["model"] = model;
|
|
4108
|
+
input["target_fps"] = req.targetFps ?? 60;
|
|
4109
|
+
input["slowdown_factor"] = 1;
|
|
4110
|
+
input["H264_output"] = true;
|
|
4111
|
+
} else {
|
|
4112
|
+
input["output_format"] = output.format === "prores" ? "prores" : "mp4";
|
|
4113
|
+
}
|
|
4114
|
+
return input;
|
|
4115
|
+
}
|
|
4116
|
+
async function submitFalVideoTool(req, ctx, opts) {
|
|
4117
|
+
const plan = planVideoTool(ctx.model, req);
|
|
4118
|
+
if (!plan.ok) {
|
|
4119
|
+
throw new ModelKitError({
|
|
4120
|
+
code: "unsupported_option",
|
|
4121
|
+
message: plan.error,
|
|
4122
|
+
provider: "fal",
|
|
4123
|
+
model: ctx.model.id,
|
|
4124
|
+
retryable: false
|
|
4125
|
+
});
|
|
4126
|
+
}
|
|
4127
|
+
const target = new URL(`${FAL_QUEUE_ORIGIN}/${ctx.model.providerModelId}`);
|
|
4128
|
+
if (opts.webhookUrl !== void 0) target.searchParams.set("fal_webhook", opts.webhookUrl);
|
|
4129
|
+
const res = await queueFetch(ctx, target.toString(), "POST", toolInput(ctx, req, plan.output));
|
|
4130
|
+
const parsed = submitResponseSchema.safeParse(await readJson(ctx, res));
|
|
4131
|
+
if (!parsed.success) {
|
|
4132
|
+
throw new ModelKitError({
|
|
4133
|
+
code: "provider_rejected",
|
|
4134
|
+
message: `fal ${ctx.model.providerModelId} submit returned no queue URLs`,
|
|
4135
|
+
provider: "fal",
|
|
4136
|
+
model: ctx.model.id,
|
|
4137
|
+
retryable: false
|
|
4138
|
+
});
|
|
4139
|
+
}
|
|
4140
|
+
return {
|
|
4141
|
+
model: ctx.model.id,
|
|
4142
|
+
provider: "fal",
|
|
4143
|
+
requestId: parsed.data.request_id,
|
|
4144
|
+
statusUrl: parsed.data.status_url,
|
|
4145
|
+
responseUrl: parsed.data.response_url,
|
|
4146
|
+
cancelUrl: parsed.data.cancel_url,
|
|
4147
|
+
output: plan.output
|
|
4148
|
+
};
|
|
4149
|
+
}
|
|
4150
|
+
function checkedQueueUrl(ctx, url) {
|
|
4151
|
+
if (!queueUrlSchema.safeParse(url).success) {
|
|
4152
|
+
throw new ModelKitError({
|
|
4153
|
+
code: "provider_rejected",
|
|
4154
|
+
message: "Video-tool submission carries a URL outside fal's queue",
|
|
4155
|
+
provider: "fal",
|
|
4156
|
+
model: ctx.model.id,
|
|
4157
|
+
retryable: false
|
|
4158
|
+
});
|
|
4159
|
+
}
|
|
4160
|
+
return url;
|
|
4161
|
+
}
|
|
4162
|
+
async function falVideoToolStatus(sub, ctx) {
|
|
4163
|
+
const res = await queueFetch(ctx, checkedQueueUrl(ctx, sub.statusUrl), "GET");
|
|
4164
|
+
const { status } = statusResponseSchema.parse(await readJson(ctx, res));
|
|
4165
|
+
if (status === "IN_QUEUE") return "queued";
|
|
4166
|
+
if (status === "COMPLETED") return "completed";
|
|
4167
|
+
return "running";
|
|
4168
|
+
}
|
|
4169
|
+
function usageOf(ctx, output) {
|
|
4170
|
+
return {
|
|
4171
|
+
model: ctx.model.id,
|
|
4172
|
+
provider: "fal",
|
|
4173
|
+
modality: "VIDEO",
|
|
4174
|
+
unit: "seconds",
|
|
4175
|
+
quantity: output.durationSeconds,
|
|
4176
|
+
durationSeconds: output.durationSeconds,
|
|
4177
|
+
resolution: output.resolution,
|
|
4178
|
+
...output.fps !== void 0 && { fps: output.fps }
|
|
4179
|
+
};
|
|
4180
|
+
}
|
|
4181
|
+
function resultOf(ctx, sub, payload) {
|
|
4182
|
+
const parsed = toolOutputSchema.safeParse(payload);
|
|
4183
|
+
if (!parsed.success) {
|
|
4184
|
+
throw new ModelKitError({
|
|
4185
|
+
code: "provider_rejected",
|
|
4186
|
+
message: `fal ${ctx.model.providerModelId} returned no video`,
|
|
4187
|
+
provider: "fal",
|
|
4188
|
+
model: ctx.model.id,
|
|
4189
|
+
retryable: false
|
|
4190
|
+
});
|
|
4191
|
+
}
|
|
4192
|
+
const file = parsed.data.video;
|
|
4193
|
+
return {
|
|
4194
|
+
video: {
|
|
4195
|
+
url: file.url,
|
|
4196
|
+
...file.content_type != null && { mime: file.content_type },
|
|
4197
|
+
...file.file_size != null && { bytes: file.file_size }
|
|
4198
|
+
},
|
|
4199
|
+
output: sub.output,
|
|
4200
|
+
usage: usageOf(ctx, sub.output),
|
|
4201
|
+
raw: payload
|
|
4202
|
+
};
|
|
4203
|
+
}
|
|
4204
|
+
async function falVideoToolResult(sub, ctx, webhook) {
|
|
4205
|
+
if (webhook !== void 0) {
|
|
4206
|
+
if (webhook.request_id !== sub.requestId) {
|
|
4207
|
+
throw new ModelKitError({
|
|
4208
|
+
code: "provider_rejected",
|
|
4209
|
+
message: "fal webhook is for a different request",
|
|
4210
|
+
provider: "fal",
|
|
4211
|
+
model: ctx.model.id,
|
|
4212
|
+
retryable: false
|
|
4213
|
+
});
|
|
4214
|
+
}
|
|
4215
|
+
if (webhook.status === "ERROR") {
|
|
4216
|
+
throw falError(
|
|
4217
|
+
void 0,
|
|
4218
|
+
webhook.payload ?? webhook.error ?? "fal job failed",
|
|
4219
|
+
ctx.model.id
|
|
4220
|
+
);
|
|
4221
|
+
}
|
|
4222
|
+
return resultOf(ctx, sub, webhook.payload);
|
|
4223
|
+
}
|
|
4224
|
+
const res = await queueFetch(ctx, checkedQueueUrl(ctx, sub.responseUrl), "GET");
|
|
4225
|
+
return resultOf(ctx, sub, await readJson(ctx, res));
|
|
4226
|
+
}
|
|
4227
|
+
async function cancelFalVideoTool(sub, ctx) {
|
|
4228
|
+
const res = await queueFetch(ctx, checkedQueueUrl(ctx, sub.cancelUrl), "PUT");
|
|
4229
|
+
if (res.ok) return true;
|
|
4230
|
+
if (res.status === 400) return false;
|
|
4231
|
+
throw falError(res.status, await readBody(res), ctx.model.id);
|
|
4232
|
+
}
|
|
4233
|
+
|
|
4234
|
+
// src/adapters/input-spec-mapper.ts
|
|
4235
|
+
function canonicalValue(req, key) {
|
|
4236
|
+
return req[key];
|
|
4237
|
+
}
|
|
4238
|
+
function isMediaRef(value) {
|
|
4239
|
+
return value instanceof Object && ("url" in value || "bytes" in value);
|
|
4240
|
+
}
|
|
4241
|
+
function toProviderValue(value, refToUrl2) {
|
|
4242
|
+
if (Array.isArray(value)) {
|
|
4243
|
+
return value.map(refToUrl2);
|
|
4244
|
+
}
|
|
4245
|
+
if (isMediaRef(value)) {
|
|
4246
|
+
return refToUrl2(value);
|
|
4247
|
+
}
|
|
4248
|
+
return value;
|
|
4249
|
+
}
|
|
4250
|
+
function applyInputSpec(spec, req, refToUrl2, opts) {
|
|
4251
|
+
const out = {};
|
|
4252
|
+
for (const [canonical, providerField] of Object.entries(spec.fields)) {
|
|
4253
|
+
if (!isInputSpecKey(canonical)) continue;
|
|
4254
|
+
const value = canonicalValue(req, canonical);
|
|
4255
|
+
if (value === void 0) continue;
|
|
4256
|
+
if (opts?.omit?.(canonical, value)) continue;
|
|
4257
|
+
const serialised = toProviderValue(value, refToUrl2);
|
|
4258
|
+
const mapped = spec.values?.[canonical]?.[String(value)];
|
|
4259
|
+
out[providerField] = mapped ?? serialised;
|
|
4260
|
+
}
|
|
4261
|
+
for (const [key, value] of Object.entries(spec.static ?? {})) {
|
|
4262
|
+
out[key] = value;
|
|
4263
|
+
}
|
|
4264
|
+
return out;
|
|
4265
|
+
}
|
|
4266
|
+
function resolveRowInputSpec(req, ctx) {
|
|
4267
|
+
const raw = ctx.model.providerOptions?.["modelkit"]?.["inputSpec"];
|
|
4268
|
+
if (raw === void 0) return { kind: "absent" };
|
|
4269
|
+
const result = validateInputSpec(raw, ctx.model);
|
|
4270
|
+
if (!result.ok) {
|
|
4271
|
+
ctx.logger.warn(
|
|
4272
|
+
`[modelkit] ${ctx.model.id} has an invalid providerOptions.modelkit.inputSpec; the call fails`
|
|
4273
|
+
);
|
|
4274
|
+
return { kind: "invalid", issues: result.issues };
|
|
4275
|
+
}
|
|
4276
|
+
return {
|
|
4277
|
+
kind: "ok",
|
|
4278
|
+
spec: result.spec,
|
|
4279
|
+
input: applyInputSpec(result.spec, req, refToUrl, {
|
|
4280
|
+
omit: (key, value) => key === "aspectRatio" && value === "adaptive"
|
|
4281
|
+
})
|
|
4282
|
+
};
|
|
4283
|
+
}
|
|
4284
|
+
function describeInputSpecIssue(issue) {
|
|
4285
|
+
if (!issue) return "invalid inputSpec";
|
|
4286
|
+
return issue.path.length === 0 ? issue.message : `${issue.path.map((part) => String(part)).join(".")} ${issue.message}`;
|
|
4287
|
+
}
|
|
4288
|
+
function invalidInputSpecError(provider, ctx, issues) {
|
|
4289
|
+
return new ModelKitError({
|
|
4290
|
+
code: "unsupported_option",
|
|
4291
|
+
message: `${provider} row "${ctx.model.id}" has an invalid providerOptions.modelkit.inputSpec: ${describeInputSpecIssue(issues[0])}`,
|
|
4292
|
+
provider,
|
|
4293
|
+
model: ctx.model.id,
|
|
4294
|
+
retryable: false
|
|
4295
|
+
});
|
|
4296
|
+
}
|
|
4297
|
+
|
|
3688
4298
|
// src/adapters/fal.ts
|
|
3689
4299
|
var MUSE_T2I_ENDPOINT = "meta/muse-image/text-to-image";
|
|
3690
4300
|
var MUSE_EDIT_ENDPOINT = "meta/muse-image/edit";
|
|
@@ -3692,7 +4302,7 @@ var KLING_O1_ENDPOINT = "fal-ai/kling-video/o1/video-to-video/reference";
|
|
|
3692
4302
|
var FAL_QUEUE_HOST = "https://queue.fal.run";
|
|
3693
4303
|
var PASSTHROUGH_POLL_MS = 2e3;
|
|
3694
4304
|
var PASSTHROUGH_MAX_WAIT_MS = 18e4;
|
|
3695
|
-
var falSubscribePayloadSchema =
|
|
4305
|
+
var falSubscribePayloadSchema = import_zod12.z.object({ data: JsonValueSchema });
|
|
3696
4306
|
function defaultCreateFalClient(opts) {
|
|
3697
4307
|
if (opts.maxRetries !== void 0)
|
|
3698
4308
|
return createFalHttpClient({
|
|
@@ -3739,30 +4349,30 @@ function createFalAdapter(deps = defaultDeps) {
|
|
|
3739
4349
|
id: "fal",
|
|
3740
4350
|
generateImage: (req, ctx) => {
|
|
3741
4351
|
throwIfAborted(ctx.signal);
|
|
4352
|
+
const spec = resolveRowInputSpec(req, ctx);
|
|
4353
|
+
if (spec.kind === "invalid") {
|
|
4354
|
+
return Promise.reject(invalidInputSpecError("fal", ctx, spec.issues));
|
|
4355
|
+
}
|
|
4356
|
+
if (spec.kind === "ok") return generateSpecImage(req, ctx, deps, spec);
|
|
3742
4357
|
if (isIdeogram(ctx.model.providerModelId)) return generateIdeogramImage(req, ctx, deps);
|
|
3743
4358
|
return generateMuseImage(req, ctx, deps);
|
|
3744
4359
|
},
|
|
3745
4360
|
generateVideo: (req, ctx) => {
|
|
3746
4361
|
throwIfAborted(ctx.signal);
|
|
3747
4362
|
return generateFalVideo(req, ctx, deps);
|
|
3748
|
-
}
|
|
4363
|
+
},
|
|
4364
|
+
submitVideoTool: submitFalVideoTool,
|
|
4365
|
+
videoToolStatus: falVideoToolStatus,
|
|
4366
|
+
videoToolResult: falVideoToolResult,
|
|
4367
|
+
cancelVideoTool: cancelFalVideoTool
|
|
3749
4368
|
};
|
|
3750
4369
|
}
|
|
3751
4370
|
var falAdapter = createFalAdapter();
|
|
3752
|
-
var
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
const detail = parsed.success ? parsed.data.detail : void 0;
|
|
3756
|
-
return detail ?? body;
|
|
3757
|
-
}
|
|
3758
|
-
function falError(status, body, model) {
|
|
3759
|
-
return classifyHttpError(status, liftDetail(body), "fal", model);
|
|
3760
|
-
}
|
|
3761
|
-
var falSdkThrownSchema = import_zod9.z.object({
|
|
3762
|
-
status: import_zod9.z.number().optional(),
|
|
3763
|
-
statusCode: import_zod9.z.number().optional(),
|
|
4371
|
+
var falSdkThrownSchema = import_zod12.z.object({
|
|
4372
|
+
status: import_zod12.z.number().optional(),
|
|
4373
|
+
statusCode: import_zod12.z.number().optional(),
|
|
3764
4374
|
body: JsonValueSchema.optional(),
|
|
3765
|
-
message:
|
|
4375
|
+
message: import_zod12.z.string().optional()
|
|
3766
4376
|
});
|
|
3767
4377
|
function falSdkError(cause, model) {
|
|
3768
4378
|
const parsed = falSdkThrownSchema.safeParse(cause);
|
|
@@ -3777,45 +4387,12 @@ function falSdkError(cause, model) {
|
|
|
3777
4387
|
body: liftDetail(info.body)
|
|
3778
4388
|
});
|
|
3779
4389
|
}
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
if (!cf?.accountId || !cf?.gatewayId || !falKey && !cfToken) {
|
|
3785
|
-
throw new ModelKitError({
|
|
3786
|
-
code: "auth",
|
|
3787
|
-
message: "fal passthrough is not configured. Set routing.cloudflare and FAL_KEY or the gateway token (BYOK).",
|
|
3788
|
-
provider: "fal",
|
|
3789
|
-
model: ctx.model.id,
|
|
3790
|
-
retryable: false
|
|
3791
|
-
});
|
|
3792
|
-
}
|
|
3793
|
-
const config = {
|
|
3794
|
-
baseUrl: `https://gateway.ai.cloudflare.com/v1/${cf.accountId}/${cf.gatewayId}/fal`
|
|
3795
|
-
};
|
|
3796
|
-
if (falKey) config.falKey = falKey;
|
|
3797
|
-
if (cfToken) config.cfToken = cfToken;
|
|
3798
|
-
if (ctx.call.maxRetries !== void 0) config.singleAttempt = true;
|
|
3799
|
-
if (ctx.signal !== void 0) config.signal = ctx.signal;
|
|
3800
|
-
return config;
|
|
3801
|
-
}
|
|
3802
|
-
async function gatewayFetch(cfg, fetchImpl, targetUrl, init) {
|
|
3803
|
-
const headers2 = { "x-fal-target-url": targetUrl };
|
|
3804
|
-
if (cfg.falKey) headers2.Authorization = `Bearer ${cfg.falKey}`;
|
|
3805
|
-
if (init.body) headers2["Content-Type"] = "application/json";
|
|
3806
|
-
if (cfg.cfToken) headers2["cf-aig-authorization"] = `Bearer ${cfg.cfToken}`;
|
|
3807
|
-
if (cfg.singleAttempt) headers2["cf-aig-max-attempts"] = "1";
|
|
3808
|
-
const request = { method: init.method, headers: headers2 };
|
|
3809
|
-
if (cfg.signal !== void 0) request.signal = cfg.signal;
|
|
3810
|
-
if (init.body !== void 0) request.body = init.body;
|
|
3811
|
-
return fetchImpl(cfg.baseUrl, request);
|
|
3812
|
-
}
|
|
3813
|
-
var falQueueSubmitSchema = import_zod9.z.object({
|
|
3814
|
-
request_id: import_zod9.z.string(),
|
|
3815
|
-
status_url: import_zod9.z.string(),
|
|
3816
|
-
response_url: import_zod9.z.string()
|
|
4390
|
+
var falQueueSubmitSchema = import_zod12.z.object({
|
|
4391
|
+
request_id: import_zod12.z.string(),
|
|
4392
|
+
status_url: import_zod12.z.string(),
|
|
4393
|
+
response_url: import_zod12.z.string()
|
|
3817
4394
|
});
|
|
3818
|
-
var falQueueStatusSchema =
|
|
4395
|
+
var falQueueStatusSchema = import_zod12.z.object({ status: import_zod12.z.string() });
|
|
3819
4396
|
async function passthroughRequest(ctx, endpoint, input) {
|
|
3820
4397
|
const cfg = gatewayConfig(ctx);
|
|
3821
4398
|
const submitRes = await gatewayFetch(cfg, ctx.fetch, `${FAL_QUEUE_HOST}/${endpoint}`, {
|
|
@@ -3948,14 +4525,44 @@ async function decodeImage(ctx, url, contentType) {
|
|
|
3948
4525
|
const mime = res.headers.get("content-type") ?? contentType ?? "image/png";
|
|
3949
4526
|
return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
|
|
3950
4527
|
}
|
|
3951
|
-
var museImageResultSchema =
|
|
3952
|
-
images:
|
|
3953
|
-
|
|
3954
|
-
url:
|
|
3955
|
-
content_type:
|
|
4528
|
+
var museImageResultSchema = import_zod12.z.object({
|
|
4529
|
+
images: import_zod12.z.array(
|
|
4530
|
+
import_zod12.z.object({
|
|
4531
|
+
url: import_zod12.z.string().optional(),
|
|
4532
|
+
content_type: import_zod12.z.string().nullable().optional()
|
|
3956
4533
|
})
|
|
3957
4534
|
).optional()
|
|
3958
4535
|
});
|
|
4536
|
+
async function collectFalImages(payload, ctx, req, label) {
|
|
4537
|
+
const parsed = museImageResultSchema.safeParse(payload);
|
|
4538
|
+
const images = parsed.success ? parsed.data.images ?? [] : [];
|
|
4539
|
+
const files = await Promise.all(
|
|
4540
|
+
images.flatMap((img) => {
|
|
4541
|
+
if (img.url === void 0) return [];
|
|
4542
|
+
return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
|
|
4543
|
+
})
|
|
4544
|
+
);
|
|
4545
|
+
if (files.length === 0) {
|
|
4546
|
+
throw new ModelKitError({
|
|
4547
|
+
code: "provider_rejected",
|
|
4548
|
+
message: `${label} returned no image`,
|
|
4549
|
+
provider: "fal",
|
|
4550
|
+
model: ctx.model.id,
|
|
4551
|
+
retryable: false
|
|
4552
|
+
});
|
|
4553
|
+
}
|
|
4554
|
+
return {
|
|
4555
|
+
images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
|
|
4556
|
+
usage: imageUsage(ctx, req, files.length),
|
|
4557
|
+
raw: payload
|
|
4558
|
+
};
|
|
4559
|
+
}
|
|
4560
|
+
async function generateSpecImage(req, ctx, deps, spec) {
|
|
4561
|
+
const hasReferences = (req.references ?? []).length > 0;
|
|
4562
|
+
const endpoint = hasReferences && spec.spec.editEndpoint !== void 0 ? spec.spec.editEndpoint : ctx.model.providerModelId;
|
|
4563
|
+
const payload = await runJob(ctx, deps, endpoint, spec.input);
|
|
4564
|
+
return collectFalImages(payload, ctx, req, `fal ${endpoint}`);
|
|
4565
|
+
}
|
|
3959
4566
|
async function generateMuseImage(req, ctx, deps) {
|
|
3960
4567
|
const refs = (req.references ?? []).map(refToUrl);
|
|
3961
4568
|
const isEdit = refs.length > 0;
|
|
@@ -3972,29 +4579,7 @@ async function generateMuseImage(req, ctx, deps) {
|
|
|
3972
4579
|
const custom = id.includes("/") && !id.startsWith("meta/muse-image") ? id : void 0;
|
|
3973
4580
|
const endpoint = custom ?? (isEdit ? MUSE_EDIT_ENDPOINT : MUSE_T2I_ENDPOINT);
|
|
3974
4581
|
const payload = await runJob(ctx, deps, endpoint, input);
|
|
3975
|
-
|
|
3976
|
-
const images = parsed.success ? parsed.data.images ?? [] : [];
|
|
3977
|
-
const firstUrl = images[0]?.url;
|
|
3978
|
-
if (images.length === 0 || firstUrl === void 0) {
|
|
3979
|
-
throw new ModelKitError({
|
|
3980
|
-
code: "provider_rejected",
|
|
3981
|
-
message: "fal Meta Muse returned no image",
|
|
3982
|
-
provider: "fal",
|
|
3983
|
-
model: ctx.model.id,
|
|
3984
|
-
retryable: false
|
|
3985
|
-
});
|
|
3986
|
-
}
|
|
3987
|
-
const files = await Promise.all(
|
|
3988
|
-
images.flatMap((img) => {
|
|
3989
|
-
if (img.url === void 0) return [];
|
|
3990
|
-
return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
|
|
3991
|
-
})
|
|
3992
|
-
);
|
|
3993
|
-
return {
|
|
3994
|
-
images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
|
|
3995
|
-
usage: imageUsage(ctx, req, files.length),
|
|
3996
|
-
raw: payload
|
|
3997
|
-
};
|
|
4582
|
+
return collectFalImages(payload, ctx, req, "fal Meta Muse");
|
|
3998
4583
|
}
|
|
3999
4584
|
var IDEOGRAM_MODEL_IDS = /* @__PURE__ */ new Set(["ideogram/v4.5"]);
|
|
4000
4585
|
function isIdeogram(providerModelId) {
|
|
@@ -4039,28 +4624,7 @@ async function generateIdeogramImage(req, ctx, deps) {
|
|
|
4039
4624
|
if (references.length > 0) input.reference_image_urls = references;
|
|
4040
4625
|
}
|
|
4041
4626
|
const payload = await runJob(ctx, deps, endpoint, input);
|
|
4042
|
-
|
|
4043
|
-
const images = parsed.success ? parsed.data.images ?? [] : [];
|
|
4044
|
-
const files = await Promise.all(
|
|
4045
|
-
images.flatMap((img) => {
|
|
4046
|
-
if (img.url === void 0) return [];
|
|
4047
|
-
return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
|
|
4048
|
-
})
|
|
4049
|
-
);
|
|
4050
|
-
if (files.length === 0) {
|
|
4051
|
-
throw new ModelKitError({
|
|
4052
|
-
code: "provider_rejected",
|
|
4053
|
-
message: "fal Ideogram returned no image",
|
|
4054
|
-
provider: "fal",
|
|
4055
|
-
model: ctx.model.id,
|
|
4056
|
-
retryable: false
|
|
4057
|
-
});
|
|
4058
|
-
}
|
|
4059
|
-
return {
|
|
4060
|
-
images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
|
|
4061
|
-
usage: imageUsage(ctx, req, files.length),
|
|
4062
|
-
raw: payload
|
|
4063
|
-
};
|
|
4627
|
+
return collectFalImages(payload, ctx, req, "fal Ideogram");
|
|
4064
4628
|
}
|
|
4065
4629
|
var H3_MAX_MODEL_IDS = /* @__PURE__ */ new Set([
|
|
4066
4630
|
"minimax/h3-max",
|
|
@@ -4122,8 +4686,8 @@ function klingO1Input(req) {
|
|
|
4122
4686
|
if (refs.length > 0) input.image_urls = refs;
|
|
4123
4687
|
return input;
|
|
4124
4688
|
}
|
|
4125
|
-
var falVideoResultSchema =
|
|
4126
|
-
video:
|
|
4689
|
+
var falVideoResultSchema = import_zod12.z.object({
|
|
4690
|
+
video: import_zod12.z.object({ url: import_zod12.z.string().optional() }).optional()
|
|
4127
4691
|
});
|
|
4128
4692
|
function extractVideoUrl(result, endpoint, model) {
|
|
4129
4693
|
const parsed = falVideoResultSchema.safeParse(result);
|
|
@@ -4324,11 +4888,11 @@ async function passthroughVideoJob(ctx, req, endpoint, input) {
|
|
|
4324
4888
|
}
|
|
4325
4889
|
|
|
4326
4890
|
// src/adapters/google-genai.ts
|
|
4327
|
-
var
|
|
4891
|
+
var import_zod14 = require("zod");
|
|
4328
4892
|
var import_genai = require("@google/genai");
|
|
4329
4893
|
|
|
4330
4894
|
// src/adapters/google-files.ts
|
|
4331
|
-
var
|
|
4895
|
+
var import_zod13 = require("zod");
|
|
4332
4896
|
var GOOGLE_FILES_BASE = "https://generativelanguage.googleapis.com";
|
|
4333
4897
|
var GOOGLE_FILES_POLL_INTERVAL_MS = 2e3;
|
|
4334
4898
|
var GOOGLE_FILES_POLL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
@@ -4338,17 +4902,17 @@ var GENERIC_MEDIA_TYPES = /* @__PURE__ */ new Set([
|
|
|
4338
4902
|
"binary/octet-stream",
|
|
4339
4903
|
"application/binary"
|
|
4340
4904
|
]);
|
|
4341
|
-
var uploadedFileSchema =
|
|
4342
|
-
file:
|
|
4343
|
-
uri:
|
|
4344
|
-
name:
|
|
4345
|
-
state:
|
|
4346
|
-
mimeType:
|
|
4905
|
+
var uploadedFileSchema = import_zod13.z.object({
|
|
4906
|
+
file: import_zod13.z.object({
|
|
4907
|
+
uri: import_zod13.z.string().optional(),
|
|
4908
|
+
name: import_zod13.z.string().optional(),
|
|
4909
|
+
state: import_zod13.z.string().optional(),
|
|
4910
|
+
mimeType: import_zod13.z.string().optional()
|
|
4347
4911
|
}).optional()
|
|
4348
4912
|
});
|
|
4349
|
-
var fileStateSchema =
|
|
4350
|
-
state:
|
|
4351
|
-
error:
|
|
4913
|
+
var fileStateSchema = import_zod13.z.object({
|
|
4914
|
+
state: import_zod13.z.string().optional(),
|
|
4915
|
+
error: import_zod13.z.object({ message: import_zod13.z.string().optional() }).optional()
|
|
4352
4916
|
});
|
|
4353
4917
|
function resolveMime(declared, fallback) {
|
|
4354
4918
|
const clean = declared?.split(";")[0]?.trim().toLowerCase();
|
|
@@ -4565,7 +5129,7 @@ var OMNI_POLL_INTERVAL_MS = 1e4;
|
|
|
4565
5129
|
var RESULT_TIMEOUT_MS2 = 15 * 60 * 1e3;
|
|
4566
5130
|
var OMNI_INLINE_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
4567
5131
|
var MEDIA_PART_INLINE_LIMIT_BYTES = 20 * 1024 * 1024;
|
|
4568
|
-
var errorTextSchema =
|
|
5132
|
+
var errorTextSchema = import_zod14.z.string();
|
|
4569
5133
|
function isGoogleGenaiVideoKnown(providerModelId) {
|
|
4570
5134
|
return providerModelId.startsWith("veo-") || providerModelId.startsWith("gemini-omni");
|
|
4571
5135
|
}
|
|
@@ -5171,15 +5735,15 @@ async function prepareGoogleMediaPart(ref, mediaType, ctx) {
|
|
|
5171
5735
|
// src/adapters/google-image.ts
|
|
5172
5736
|
var import_google2 = require("@ai-sdk/google");
|
|
5173
5737
|
var import_ai2 = require("ai");
|
|
5174
|
-
var
|
|
5738
|
+
var import_zod15 = require("zod");
|
|
5175
5739
|
var GEMINI_IMAGE_TIMEOUT_MS = 6e5;
|
|
5176
5740
|
var defaultGoogleImageDeps = {
|
|
5177
5741
|
createGoogleClient: (opts) => (0, import_google2.createGoogleGenerativeAI)(opts),
|
|
5178
5742
|
runTextGeneration: (opts) => (0, import_ai2.generateText)(opts)
|
|
5179
5743
|
};
|
|
5180
|
-
var causeChainNodeSchema =
|
|
5181
|
-
message:
|
|
5182
|
-
cause:
|
|
5744
|
+
var causeChainNodeSchema = import_zod15.z.object({
|
|
5745
|
+
message: import_zod15.z.string().optional(),
|
|
5746
|
+
cause: import_zod15.z.unknown().optional()
|
|
5183
5747
|
});
|
|
5184
5748
|
function extractBlockReason(cause) {
|
|
5185
5749
|
let current = cause;
|
|
@@ -5299,7 +5863,7 @@ function createGoogleImageAdapter(deps = defaultGoogleImageDeps) {
|
|
|
5299
5863
|
var googleImageAdapter = createGoogleImageAdapter();
|
|
5300
5864
|
|
|
5301
5865
|
// src/adapters/higgsfield.ts
|
|
5302
|
-
var
|
|
5866
|
+
var import_zod16 = require("zod");
|
|
5303
5867
|
|
|
5304
5868
|
// src/adapters/higgsfield-motions.ts
|
|
5305
5869
|
var MOTION_MAP = {
|
|
@@ -5518,14 +6082,14 @@ function klingEndpointFields(providerModelId) {
|
|
|
5518
6082
|
const path = (providerModelId.startsWith("/") ? providerModelId.slice(1) : providerModelId).toLowerCase();
|
|
5519
6083
|
return KLING_ENDPOINT_FIELDS.get(path) ?? UNLISTED_KLING_FIELDS;
|
|
5520
6084
|
}
|
|
5521
|
-
var klingCreateSchema =
|
|
5522
|
-
var klingStatusSchema =
|
|
5523
|
-
status:
|
|
5524
|
-
video:
|
|
6085
|
+
var klingCreateSchema = import_zod16.z.object({ status_url: import_zod16.z.string() });
|
|
6086
|
+
var klingStatusSchema = import_zod16.z.object({
|
|
6087
|
+
status: import_zod16.z.string().optional(),
|
|
6088
|
+
video: import_zod16.z.object({ url: import_zod16.z.string().optional() }).optional(),
|
|
5525
6089
|
error: JsonValueSchema.optional()
|
|
5526
6090
|
});
|
|
5527
|
-
var errorMessageSchema =
|
|
5528
|
-
var textValueSchema =
|
|
6091
|
+
var errorMessageSchema = import_zod16.z.object({ message: import_zod16.z.string().optional() });
|
|
6092
|
+
var textValueSchema = import_zod16.z.string();
|
|
5529
6093
|
function klingErrorDetail(error) {
|
|
5530
6094
|
if (error === void 0) return "unknown_error";
|
|
5531
6095
|
const asText = textValueSchema.safeParse(error);
|
|
@@ -5681,8 +6245,8 @@ async function generateKlingVideo(req, ctx) {
|
|
|
5681
6245
|
}
|
|
5682
6246
|
};
|
|
5683
6247
|
}
|
|
5684
|
-
var dopMotionOptionsSchema =
|
|
5685
|
-
modelkit:
|
|
6248
|
+
var dopMotionOptionsSchema = import_zod16.z.object({
|
|
6249
|
+
modelkit: import_zod16.z.object({ motion: import_zod16.z.string().optional() }).optional()
|
|
5686
6250
|
});
|
|
5687
6251
|
function dopMotionId(ctx) {
|
|
5688
6252
|
const parsed = dopMotionOptionsSchema.safeParse(ctx.model.providerOptions);
|
|
@@ -5698,7 +6262,7 @@ function dopMotionId(ctx) {
|
|
|
5698
6262
|
});
|
|
5699
6263
|
return id;
|
|
5700
6264
|
}
|
|
5701
|
-
var jsonRecordSchema =
|
|
6265
|
+
var jsonRecordSchema = import_zod16.z.record(import_zod16.z.string(), JsonValueSchema);
|
|
5702
6266
|
var DOP_URL_KEYS = ["url", "video_url", "output_url", "result_url", "download_url"];
|
|
5703
6267
|
var DOP_NESTED_KEYS = ["video", "result", "results"];
|
|
5704
6268
|
function dopUrl(body) {
|
|
@@ -5726,8 +6290,8 @@ function dopUrl(body) {
|
|
|
5726
6290
|
}
|
|
5727
6291
|
return void 0;
|
|
5728
6292
|
}
|
|
5729
|
-
var dopCreateSchema =
|
|
5730
|
-
var dopStatusSchema =
|
|
6293
|
+
var dopCreateSchema = import_zod16.z.object({ id: import_zod16.z.string() });
|
|
6294
|
+
var dopStatusSchema = import_zod16.z.object({ status: import_zod16.z.string().optional() });
|
|
5731
6295
|
async function generateDopVideo(req, ctx) {
|
|
5732
6296
|
const firstFrame = req.firstFrame ? refToUrl(req.firstFrame) : void 0;
|
|
5733
6297
|
if (!firstFrame) {
|
|
@@ -5855,7 +6419,7 @@ var higgsfieldAdapter = {
|
|
|
5855
6419
|
|
|
5856
6420
|
// src/adapters/openai-image.ts
|
|
5857
6421
|
var import_openai2 = __toESM(require("openai"), 1);
|
|
5858
|
-
var
|
|
6422
|
+
var import_zod17 = require("zod");
|
|
5859
6423
|
var MAX_EDIT_REFERENCES = 16;
|
|
5860
6424
|
function aspectRatioToSize(ratio, tier) {
|
|
5861
6425
|
const TIER_LONG_EDGE = {
|
|
@@ -5938,9 +6502,9 @@ function toProviderError2(cause, ctx) {
|
|
|
5938
6502
|
ctx.model.id
|
|
5939
6503
|
);
|
|
5940
6504
|
}
|
|
5941
|
-
var openaiUsageSchema =
|
|
5942
|
-
input_tokens:
|
|
5943
|
-
output_tokens:
|
|
6505
|
+
var openaiUsageSchema = import_zod17.z.object({
|
|
6506
|
+
input_tokens: import_zod17.z.number().optional(),
|
|
6507
|
+
output_tokens: import_zod17.z.number().optional()
|
|
5944
6508
|
});
|
|
5945
6509
|
var openaiImageAdapter = {
|
|
5946
6510
|
id: "openai-image",
|
|
@@ -6351,13 +6915,13 @@ var prodiaAdapter = {
|
|
|
6351
6915
|
var import_replicate = __toESM(require("replicate"), 1);
|
|
6352
6916
|
|
|
6353
6917
|
// src/adapters/replicate-http.ts
|
|
6354
|
-
var
|
|
6355
|
-
var predictionSchema =
|
|
6356
|
-
id:
|
|
6357
|
-
status:
|
|
6918
|
+
var import_zod18 = require("zod");
|
|
6919
|
+
var predictionSchema = import_zod18.z.object({
|
|
6920
|
+
id: import_zod18.z.string(),
|
|
6921
|
+
status: import_zod18.z.string(),
|
|
6358
6922
|
output: JsonValueSchema.optional(),
|
|
6359
6923
|
error: JsonValueSchema.optional(),
|
|
6360
|
-
metrics:
|
|
6924
|
+
metrics: import_zod18.z.object({ predict_time: import_zod18.z.number().optional() }).optional()
|
|
6361
6925
|
});
|
|
6362
6926
|
function createReplicateHttpClient(opts) {
|
|
6363
6927
|
async function request(path, body, signal) {
|
|
@@ -6408,42 +6972,7 @@ function createReplicateHttpClient(opts) {
|
|
|
6408
6972
|
}
|
|
6409
6973
|
|
|
6410
6974
|
// src/adapters/replicate.ts
|
|
6411
|
-
var
|
|
6412
|
-
|
|
6413
|
-
// src/adapters/input-spec-mapper.ts
|
|
6414
|
-
function canonicalValue(req, key) {
|
|
6415
|
-
return req[key];
|
|
6416
|
-
}
|
|
6417
|
-
function isMediaRef(value) {
|
|
6418
|
-
return value instanceof Object && ("url" in value || "bytes" in value);
|
|
6419
|
-
}
|
|
6420
|
-
function toProviderValue(value, refToUrl2) {
|
|
6421
|
-
if (Array.isArray(value)) {
|
|
6422
|
-
return value.map(refToUrl2);
|
|
6423
|
-
}
|
|
6424
|
-
if (isMediaRef(value)) {
|
|
6425
|
-
return refToUrl2(value);
|
|
6426
|
-
}
|
|
6427
|
-
return value;
|
|
6428
|
-
}
|
|
6429
|
-
function applyInputSpec(spec, req, refToUrl2, opts) {
|
|
6430
|
-
const out = {};
|
|
6431
|
-
for (const [canonical, providerField] of Object.entries(spec.fields)) {
|
|
6432
|
-
if (!isInputSpecKey(canonical)) continue;
|
|
6433
|
-
const value = canonicalValue(req, canonical);
|
|
6434
|
-
if (value === void 0) continue;
|
|
6435
|
-
if (opts?.omit?.(canonical, value)) continue;
|
|
6436
|
-
const serialised = toProviderValue(value, refToUrl2);
|
|
6437
|
-
const mapped = spec.values?.[canonical]?.[String(value)];
|
|
6438
|
-
out[providerField] = mapped ?? serialised;
|
|
6439
|
-
}
|
|
6440
|
-
for (const [key, value] of Object.entries(spec.static ?? {})) {
|
|
6441
|
-
out[key] = value;
|
|
6442
|
-
}
|
|
6443
|
-
return out;
|
|
6444
|
-
}
|
|
6445
|
-
|
|
6446
|
-
// src/adapters/replicate.ts
|
|
6975
|
+
var import_zod19 = require("zod");
|
|
6447
6976
|
var POLL_INTERVAL_MS = 1e3;
|
|
6448
6977
|
var POLL_TIMEOUT_MS = 15 * 6e4;
|
|
6449
6978
|
var defaultReplicateDeps = {
|
|
@@ -6483,8 +7012,8 @@ function route(providerModelId) {
|
|
|
6483
7012
|
if (!providerModelId.includes("/")) return { version: providerModelId };
|
|
6484
7013
|
return { model: providerModelId };
|
|
6485
7014
|
}
|
|
6486
|
-
var replicateResponseStatusSchema =
|
|
6487
|
-
response:
|
|
7015
|
+
var replicateResponseStatusSchema = import_zod19.z.object({
|
|
7016
|
+
response: import_zod19.z.object({ status: import_zod19.z.number() }).partial()
|
|
6488
7017
|
});
|
|
6489
7018
|
function replicateError(cause, ctx) {
|
|
6490
7019
|
if (isModelKitError(cause)) return cause;
|
|
@@ -6511,7 +7040,7 @@ function isUrlFn(value) {
|
|
|
6511
7040
|
function extractOutputUrl(output) {
|
|
6512
7041
|
const root = Array.isArray(output) ? output[0] : output;
|
|
6513
7042
|
if (root === void 0) throw noOutput();
|
|
6514
|
-
const asString =
|
|
7043
|
+
const asString = import_zod19.z.string().safeParse(root);
|
|
6515
7044
|
if (asString.success && asString.data) return asString.data;
|
|
6516
7045
|
if (root instanceof URL) return root.href;
|
|
6517
7046
|
if (isObjectOutput(root)) {
|
|
@@ -6520,15 +7049,15 @@ function extractOutputUrl(output) {
|
|
|
6520
7049
|
if (urlValue !== void 0 && isUrlFn(urlValue)) {
|
|
6521
7050
|
const called = urlValue();
|
|
6522
7051
|
if (called instanceof URL) return called.href;
|
|
6523
|
-
const calledString =
|
|
7052
|
+
const calledString = import_zod19.z.string().safeParse(called);
|
|
6524
7053
|
if (calledString.success && calledString.data) return calledString.data;
|
|
6525
7054
|
} else {
|
|
6526
|
-
const direct =
|
|
7055
|
+
const direct = import_zod19.z.string().safeParse(urlValue);
|
|
6527
7056
|
if (direct.success && direct.data) return direct.data;
|
|
6528
7057
|
}
|
|
6529
7058
|
}
|
|
6530
7059
|
if ("default" in root) {
|
|
6531
|
-
const fallback =
|
|
7060
|
+
const fallback = import_zod19.z.string().safeParse(root.default);
|
|
6532
7061
|
if (fallback.success && fallback.data) return fallback.data;
|
|
6533
7062
|
}
|
|
6534
7063
|
}
|
|
@@ -6589,7 +7118,7 @@ async function runPrediction(ctx, input, deps) {
|
|
|
6589
7118
|
}
|
|
6590
7119
|
return void 0;
|
|
6591
7120
|
}, pollOpts);
|
|
6592
|
-
const predictTime =
|
|
7121
|
+
const predictTime = import_zod19.z.number().safeParse(done.metrics?.predict_time);
|
|
6593
7122
|
if (done.output === void 0) throw noOutput();
|
|
6594
7123
|
return {
|
|
6595
7124
|
url: extractOutputUrl(done.output),
|
|
@@ -6686,38 +7215,6 @@ function replicateNoMapper(ctx, section) {
|
|
|
6686
7215
|
retryable: false
|
|
6687
7216
|
});
|
|
6688
7217
|
}
|
|
6689
|
-
function describeInputSpecIssue(issue) {
|
|
6690
|
-
if (!issue) return "invalid inputSpec";
|
|
6691
|
-
return issue.path.length === 0 ? issue.message : `${issue.path.map((part) => String(part)).join(".")} ${issue.message}`;
|
|
6692
|
-
}
|
|
6693
|
-
function replicateInvalidSpec(ctx, issues) {
|
|
6694
|
-
const detail = describeInputSpecIssue(issues[0]);
|
|
6695
|
-
return new ModelKitError({
|
|
6696
|
-
code: "unsupported_option",
|
|
6697
|
-
message: `replicate row "${ctx.model.id}" has an invalid providerOptions.modelkit.inputSpec: ${detail}`,
|
|
6698
|
-
provider: "replicate",
|
|
6699
|
-
model: ctx.model.id,
|
|
6700
|
-
retryable: false
|
|
6701
|
-
});
|
|
6702
|
-
}
|
|
6703
|
-
function omitAdaptive(key, value) {
|
|
6704
|
-
return key === "aspectRatio" && value === "adaptive";
|
|
6705
|
-
}
|
|
6706
|
-
function replicateInputSpec(req, ctx) {
|
|
6707
|
-
const raw = ctx.model.providerOptions?.["modelkit"]?.["inputSpec"];
|
|
6708
|
-
if (raw === void 0) return { kind: "absent" };
|
|
6709
|
-
const result = validateInputSpec(raw, ctx.model);
|
|
6710
|
-
if (!result.ok) {
|
|
6711
|
-
ctx.logger.warn(
|
|
6712
|
-
`[modelkit] ${ctx.model.id} has an invalid providerOptions.modelkit.inputSpec; the call fails`
|
|
6713
|
-
);
|
|
6714
|
-
return { kind: "invalid", issues: result.issues };
|
|
6715
|
-
}
|
|
6716
|
-
return {
|
|
6717
|
-
kind: "ok",
|
|
6718
|
-
input: applyInputSpec(result.spec, req, refToUrl, { omit: omitAdaptive })
|
|
6719
|
-
};
|
|
6720
|
-
}
|
|
6721
7218
|
var QWEN_IMAGE_RATIOS = /* @__PURE__ */ new Set([
|
|
6722
7219
|
"1:1",
|
|
6723
7220
|
"16:9",
|
|
@@ -6861,8 +7358,9 @@ async function generateReplicateImage(req, ctx, deps) {
|
|
|
6861
7358
|
break;
|
|
6862
7359
|
}
|
|
6863
7360
|
default: {
|
|
6864
|
-
const specResult =
|
|
6865
|
-
if (specResult.kind === "invalid")
|
|
7361
|
+
const specResult = resolveRowInputSpec(req, ctx);
|
|
7362
|
+
if (specResult.kind === "invalid")
|
|
7363
|
+
throw invalidInputSpecError("replicate", ctx, specResult.issues);
|
|
6866
7364
|
if (specResult.kind === "ok") {
|
|
6867
7365
|
input = specResult.input;
|
|
6868
7366
|
break;
|
|
@@ -6942,9 +7440,10 @@ async function generateReplicateVideo(req, ctx, deps) {
|
|
|
6942
7440
|
else if (kind === "kling-omni") input = klingOmniInput(req);
|
|
6943
7441
|
else if (kind === "hailuo") input = hailuoInput(req);
|
|
6944
7442
|
else {
|
|
6945
|
-
const specResult =
|
|
7443
|
+
const specResult = resolveRowInputSpec(req, ctx);
|
|
6946
7444
|
if (specResult.kind === "absent") throw replicateNoMapper(ctx, "video");
|
|
6947
|
-
if (specResult.kind === "invalid")
|
|
7445
|
+
if (specResult.kind === "invalid")
|
|
7446
|
+
throw invalidInputSpecError("replicate", ctx, specResult.issues);
|
|
6948
7447
|
input = specResult.input;
|
|
6949
7448
|
}
|
|
6950
7449
|
const api = client(ctx, deps);
|
|
@@ -6978,7 +7477,7 @@ async function generateReplicateVideo(req, ctx, deps) {
|
|
|
6978
7477
|
throw replicateError(cause, ctx);
|
|
6979
7478
|
}
|
|
6980
7479
|
if (current.status === "succeeded") {
|
|
6981
|
-
const predictTime =
|
|
7480
|
+
const predictTime = import_zod19.z.number().safeParse(current.metrics?.predict_time);
|
|
6982
7481
|
if (current.output === void 0) throw noOutput();
|
|
6983
7482
|
return {
|
|
6984
7483
|
url: extractOutputUrl(current.output),
|
|
@@ -7099,9 +7598,10 @@ async function generateReplicateAudio(req, ctx, deps) {
|
|
|
7099
7598
|
else if (kind === "elevenlabs") input = elevenLabsMusicInput(req, ctx);
|
|
7100
7599
|
else if (kind === "lyria") input = lyriaAudioInput(req, ctx);
|
|
7101
7600
|
else {
|
|
7102
|
-
const specResult =
|
|
7601
|
+
const specResult = resolveRowInputSpec(req, ctx);
|
|
7103
7602
|
if (specResult.kind === "absent") throw replicateNoMapper(ctx, "audio");
|
|
7104
|
-
if (specResult.kind === "invalid")
|
|
7603
|
+
if (specResult.kind === "invalid")
|
|
7604
|
+
throw invalidInputSpecError("replicate", ctx, specResult.issues);
|
|
7105
7605
|
input = specResult.input;
|
|
7106
7606
|
}
|
|
7107
7607
|
const { url, predictTime, raw } = await runPrediction(ctx, input, deps);
|
|
@@ -7119,7 +7619,7 @@ async function generateReplicateAudio(req, ctx, deps) {
|
|
|
7119
7619
|
// src/adapters/xai-video.ts
|
|
7120
7620
|
var import_ai3 = require("ai");
|
|
7121
7621
|
var import_xai2 = require("@ai-sdk/xai");
|
|
7122
|
-
var
|
|
7622
|
+
var import_zod20 = require("zod");
|
|
7123
7623
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
7124
7624
|
var POLL_TIMEOUT_MS2 = 15 * 6e4;
|
|
7125
7625
|
var defaultXaiDeps = {
|
|
@@ -7132,8 +7632,8 @@ function createXaiVideoAdapter(deps = defaultXaiDeps) {
|
|
|
7132
7632
|
};
|
|
7133
7633
|
}
|
|
7134
7634
|
var xaiVideoAdapter = createXaiVideoAdapter();
|
|
7135
|
-
var xaiResponseStatusSchema =
|
|
7136
|
-
response:
|
|
7635
|
+
var xaiResponseStatusSchema = import_zod20.z.object({
|
|
7636
|
+
response: import_zod20.z.object({ status: import_zod20.z.number() }).partial()
|
|
7137
7637
|
});
|
|
7138
7638
|
function xaiError(cause, ctx) {
|
|
7139
7639
|
const info = describeThrown(cause);
|
|
@@ -7141,12 +7641,12 @@ function xaiError(cause, ctx) {
|
|
|
7141
7641
|
const status = info.status ?? (nested.success ? nested.data.response?.status : void 0);
|
|
7142
7642
|
return classifyThrown("xai-video", cause, ctx.model.id, { status, body: info.body });
|
|
7143
7643
|
}
|
|
7144
|
-
var xaiMetaSchema =
|
|
7644
|
+
var xaiMetaSchema = import_zod20.z.object({
|
|
7145
7645
|
videoUrl: JsonValueSchema.optional(),
|
|
7146
7646
|
costInUsdTicks: JsonValueSchema.optional(),
|
|
7147
7647
|
duration: JsonValueSchema.optional()
|
|
7148
7648
|
});
|
|
7149
|
-
var xaiProviderMetadataSchema =
|
|
7649
|
+
var xaiProviderMetadataSchema = import_zod20.z.object({ xai: xaiMetaSchema });
|
|
7150
7650
|
function metaOf(result) {
|
|
7151
7651
|
const parsed = xaiProviderMetadataSchema.partial().safeParse(result.providerMetadata);
|
|
7152
7652
|
if (!parsed.success) return {};
|
|
@@ -7254,7 +7754,7 @@ async function mapResult(ctx, req, result) {
|
|
|
7254
7754
|
};
|
|
7255
7755
|
}
|
|
7256
7756
|
const meta = metaOf(result);
|
|
7257
|
-
const videoUrl =
|
|
7757
|
+
const videoUrl = import_zod20.z.string().safeParse(meta.videoUrl);
|
|
7258
7758
|
if (videoUrl.success && videoUrl.data) {
|
|
7259
7759
|
const res = await ctx.fetch(videoUrl.data);
|
|
7260
7760
|
if (!res.ok) {
|
|
@@ -7277,7 +7777,7 @@ async function mapResult(ctx, req, result) {
|
|
|
7277
7777
|
});
|
|
7278
7778
|
}
|
|
7279
7779
|
function usage(ctx, req, meta) {
|
|
7280
|
-
const costTicks =
|
|
7780
|
+
const costTicks = import_zod20.z.number().safeParse(meta.costInUsdTicks);
|
|
7281
7781
|
const cost = costTicks.success ? costTicks.data / 1e10 : void 0;
|
|
7282
7782
|
const event = {
|
|
7283
7783
|
model: ctx.model.id,
|
|
@@ -7410,22 +7910,22 @@ var liveState = store[KEY] ??= {
|
|
|
7410
7910
|
var liveCatalog = liveState.catalog;
|
|
7411
7911
|
|
|
7412
7912
|
// src/catalog/load.ts
|
|
7413
|
-
var
|
|
7913
|
+
var import_zod21 = require("zod");
|
|
7414
7914
|
function rowCount() {
|
|
7415
7915
|
return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
|
|
7416
7916
|
}
|
|
7417
7917
|
function authHeaders(auth) {
|
|
7418
7918
|
return "bearer" in auth ? { Authorization: `Bearer ${auth.bearer}` } : { "x-api-key": auth.apiKey };
|
|
7419
7919
|
}
|
|
7420
|
-
var EnvelopeSchema =
|
|
7421
|
-
rows:
|
|
7422
|
-
revision:
|
|
7920
|
+
var EnvelopeSchema = import_zod21.z.object({
|
|
7921
|
+
rows: import_zod21.z.array(JsonValueSchema),
|
|
7922
|
+
revision: import_zod21.z.string().optional()
|
|
7423
7923
|
});
|
|
7424
7924
|
function dropReason(path, message) {
|
|
7425
7925
|
return path.length === 0 ? message : `${path.map((part) => String(part)).join(".")} ${message}`;
|
|
7426
7926
|
}
|
|
7427
7927
|
function rowId(raw) {
|
|
7428
|
-
const parsed =
|
|
7928
|
+
const parsed = import_zod21.z.object({ id: import_zod21.z.string().min(1) }).loose().safeParse(raw);
|
|
7429
7929
|
if (!parsed.success) return "?";
|
|
7430
7930
|
return parsed.data.id;
|
|
7431
7931
|
}
|
|
@@ -8282,7 +8782,7 @@ function createTextSteps(initial, resolve, callerProviderOptions) {
|
|
|
8282
8782
|
|
|
8283
8783
|
// src/client.ts
|
|
8284
8784
|
var import_ai5 = require("ai");
|
|
8285
|
-
var
|
|
8785
|
+
var import_zod22 = require("zod");
|
|
8286
8786
|
|
|
8287
8787
|
// src/generated-image.ts
|
|
8288
8788
|
function toGeneratedImage(image) {
|
|
@@ -8364,10 +8864,10 @@ function textAbortOptions(sdk, context) {
|
|
|
8364
8864
|
if (abortSignal) return { abortSignal };
|
|
8365
8865
|
return {};
|
|
8366
8866
|
}
|
|
8367
|
-
var catalogId =
|
|
8368
|
-
var exactSize =
|
|
8369
|
-
var sdkRatio =
|
|
8370
|
-
var sizeTier =
|
|
8867
|
+
var catalogId = import_zod22.z.string();
|
|
8868
|
+
var exactSize = import_zod22.z.templateLiteral([import_zod22.z.number(), "x", import_zod22.z.number()]);
|
|
8869
|
+
var sdkRatio = import_zod22.z.templateLiteral([import_zod22.z.number(), ":", import_zod22.z.number()]);
|
|
8870
|
+
var sizeTier = import_zod22.z.enum(["512", "1K", "2K", "4K"]);
|
|
8371
8871
|
function isCatalogId(model) {
|
|
8372
8872
|
return catalogId.safeParse(model).success;
|
|
8373
8873
|
}
|
|
@@ -8477,6 +8977,24 @@ function createModelKit(config, adapters) {
|
|
|
8477
8977
|
if (call.signal) ctx.signal = call.signal;
|
|
8478
8978
|
return { adapter, ctx };
|
|
8479
8979
|
}
|
|
8980
|
+
function videoToolTarget(modelId, call) {
|
|
8981
|
+
mediaRetryOptions(call);
|
|
8982
|
+
const model = catalog.require(modelId);
|
|
8983
|
+
if (model.type !== "video-tool")
|
|
8984
|
+
throw new ModelKitError({
|
|
8985
|
+
code: "unsupported_option",
|
|
8986
|
+
message: `${model.id} is not a video tool`,
|
|
8987
|
+
model: model.id
|
|
8988
|
+
});
|
|
8989
|
+
return context(model, call, []);
|
|
8990
|
+
}
|
|
8991
|
+
function noVideoTools(adapter, model) {
|
|
8992
|
+
return new ModelKitError({
|
|
8993
|
+
code: "unsupported_option",
|
|
8994
|
+
message: `${adapter.id} has no video tools`,
|
|
8995
|
+
model: model.id
|
|
8996
|
+
});
|
|
8997
|
+
}
|
|
8480
8998
|
async function emit(event) {
|
|
8481
8999
|
try {
|
|
8482
9000
|
await config.onUsage?.(event);
|
|
@@ -8832,6 +9350,34 @@ function createModelKit(config, adapters) {
|
|
|
8832
9350
|
usageProvider: provider
|
|
8833
9351
|
};
|
|
8834
9352
|
},
|
|
9353
|
+
async submitVideoTool(req, call = {}) {
|
|
9354
|
+
const { webhookUrl, ...rest } = call;
|
|
9355
|
+
const { adapter, ctx } = videoToolTarget(req.model, rest);
|
|
9356
|
+
if (!adapter.submitVideoTool) throw noVideoTools(adapter, ctx.model);
|
|
9357
|
+
return adapter.submitVideoTool(
|
|
9358
|
+
req,
|
|
9359
|
+
ctx,
|
|
9360
|
+
webhookUrl !== void 0 ? { webhookUrl } : {}
|
|
9361
|
+
);
|
|
9362
|
+
},
|
|
9363
|
+
async videoToolStatus(sub, call = {}) {
|
|
9364
|
+
const { adapter, ctx } = videoToolTarget(sub.model, call);
|
|
9365
|
+
if (!adapter.videoToolStatus) throw noVideoTools(adapter, ctx.model);
|
|
9366
|
+
return adapter.videoToolStatus(sub, ctx);
|
|
9367
|
+
},
|
|
9368
|
+
async videoToolResult(sub, call = {}) {
|
|
9369
|
+
const { webhook, ...rest } = call;
|
|
9370
|
+
const { adapter, ctx } = videoToolTarget(sub.model, rest);
|
|
9371
|
+
if (!adapter.videoToolResult) throw noVideoTools(adapter, ctx.model);
|
|
9372
|
+
const result = await adapter.videoToolResult(sub, ctx, webhook);
|
|
9373
|
+
await emit({ ...result.usage, model: ctx.model.id, unit: ctx.model.usage.unit });
|
|
9374
|
+
return result;
|
|
9375
|
+
},
|
|
9376
|
+
async cancelVideoTool(sub, call = {}) {
|
|
9377
|
+
const { adapter, ctx } = videoToolTarget(sub.model, call);
|
|
9378
|
+
if (!adapter.cancelVideoTool) throw noVideoTools(adapter, ctx.model);
|
|
9379
|
+
return adapter.cancelVideoTool(sub, ctx);
|
|
9380
|
+
},
|
|
8835
9381
|
usageProvider(modelId, call = {}) {
|
|
8836
9382
|
const entry = catalog.require(modelId);
|
|
8837
9383
|
if (entry.type !== "text") return entry.adapter;
|
|
@@ -8958,6 +9504,7 @@ var describe = (modelId) => createDefaultModelKit().describe(modelId);
|
|
|
8958
9504
|
SURFACES,
|
|
8959
9505
|
SurfaceSchema,
|
|
8960
9506
|
VIDEO_INPUT_SPEC_KEYS,
|
|
9507
|
+
VIDEO_TOOL_MODELS,
|
|
8961
9508
|
adapterServesType,
|
|
8962
9509
|
aiSdkTextAdapter,
|
|
8963
9510
|
arkAdapter,
|
|
@@ -8971,6 +9518,7 @@ var describe = (modelId) => createDefaultModelKit().describe(modelId);
|
|
|
8971
9518
|
describeThrown,
|
|
8972
9519
|
experimental_generateImage,
|
|
8973
9520
|
falAdapter,
|
|
9521
|
+
falWebhookBodySchema,
|
|
8974
9522
|
fileCatalogCache,
|
|
8975
9523
|
generateAudio,
|
|
8976
9524
|
generateImage,
|
|
@@ -8995,6 +9543,7 @@ var describe = (modelId) => createDefaultModelKit().describe(modelId);
|
|
|
8995
9543
|
normalizeExposure,
|
|
8996
9544
|
openaiImageAdapter,
|
|
8997
9545
|
passthroughTextModel,
|
|
9546
|
+
planVideoTool,
|
|
8998
9547
|
pollUntil,
|
|
8999
9548
|
prepareMediaPart,
|
|
9000
9549
|
primeCatalog,
|
|
@@ -9002,6 +9551,7 @@ var describe = (modelId) => createDefaultModelKit().describe(modelId);
|
|
|
9002
9551
|
readErrorBody,
|
|
9003
9552
|
replicateAdapter,
|
|
9004
9553
|
resetLiveCatalog,
|
|
9554
|
+
resolutionTier,
|
|
9005
9555
|
resolveAudioOptions,
|
|
9006
9556
|
resolveImageOptions,
|
|
9007
9557
|
resolveKeys,
|
|
@@ -9015,6 +9565,7 @@ var describe = (modelId) => createDefaultModelKit().describe(modelId);
|
|
|
9015
9565
|
toGeneratedImage,
|
|
9016
9566
|
validateInputSpec,
|
|
9017
9567
|
videoLengthViolation,
|
|
9568
|
+
videoToolConstraints,
|
|
9018
9569
|
withRetry,
|
|
9019
9570
|
xaiVideoAdapter,
|
|
9020
9571
|
...require("ai")
|