@shop-os/modelkit 0.3.2 → 0.3.4
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 +24 -0
- package/README.md +2 -1
- package/dist/catalog.cjs +158 -11
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +13 -1
- package/dist/catalog.d.ts +13 -1
- package/dist/catalog.js +158 -11
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +186 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -3
- package/dist/index.d.ts +20 -3
- package/dist/index.js +184 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,30 @@ header in the release PR.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.3.4] - Unreleased
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- Snapshot rows `flux-video-upscale-precise` and `flux-video-upscale-creative` (fal `blackforestlabs/flux-video-upscale`, `type: "video-tool"`, upscale 1.5x to 3x, 4K long-edge limit, 20-second source), listed on `space_builder`. They share one endpoint and differ only in fal's `creativity` mode, which fal prices differently, so pricing keys them as two models.
|
|
16
|
+
- `constraints.tool.prompt` on upscale rows and `VideoToolRequest.prompt`: a row that sets it sends a trimmed, non-empty prompt to the provider. Other rows ignore the prompt.
|
|
17
|
+
- `providerOptions.fal.input` on video-tool rows: fixed body fields sent on every call. The source, factor and prompt are set after them, so a row cannot replace those.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- `topaz-precision` and `topaz-starlight` are also listed on `space_builder`.
|
|
21
|
+
- An upscale row with no Topaz model name (`providerOptions.fal.model`) no longer gets `model` or `H264_output` in its body. Both Topaz upscale rows name a model, so their bodies are unchanged.
|
|
22
|
+
|
|
23
|
+
### Live rows to add after publish
|
|
24
|
+
Add the two FLUX rows, and add `space_builder` to the live Topaz Precision and Starlight rows, only after every app that calls them runs 0.3.4. An older kit sends `H264_output`, drops `creativity`, and so runs the precise row in creative mode.
|
|
25
|
+
|
|
26
|
+
## [0.3.3] - Unreleased
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
- `inputSpec.arrays` joins several image inputs into one provider array field, for a model that takes its start frame, end frame and storyboard frames in one list. It maps a provider field to an ordered list of canonical keys: `arrays: { images: ["firstFrame", "referenceImages", "lastFrame"] }` sends the first frame, then the reference images, then the last frame. The field is omitted when none of the inputs is set. Video rows take `firstFrame`, `referenceImages` and `lastFrame`; image rows take `references`. A key is mapped once: in `fields` or in one array. An array name must not repeat a `fields` provider name or a `static` key, and `lastFrame` in an array needs `lastFrame` in `constraints.supports`.
|
|
30
|
+
- `sourceVideo` is an `inputSpec.fields` key on video rows, so a Replicate video row can send a source clip (for example `sourceVideo: "start_video"`). The row also needs `capabilities.acceptsSourceVideo`, or the resolver drops the clip before the adapter runs.
|
|
31
|
+
- `capabilities.sourceVideoExcludesFrames`: a source video is never sent with a first frame, a last frame or reference images. `resolveVideoOptions` refuses the mix under `"error"` and drops the images with an `option_ignored` warning for each under `"coerce"`.
|
|
32
|
+
|
|
33
|
+
### Live rows to add after publish
|
|
34
|
+
Add a Replicate video row that uses `inputSpec.arrays` or maps `sourceVideo` (for example `black-forest-labs/flux-3`) only after every app that will call it runs 0.3.3. An older kit reads such a spec as invalid: the row stays in the catalog and every call to it fails. A row of this shape should set `capabilities.lastFrameRequiresFirstFrame`, because a lone end frame would be sent as the first element of the array.
|
|
35
|
+
|
|
12
36
|
## [0.3.2] - Unreleased
|
|
13
37
|
|
|
14
38
|
### Added
|
package/README.md
CHANGED
|
@@ -218,12 +218,13 @@ instead of a kit change. It is read by the Replicate and fal adapters only. `fie
|
|
|
218
218
|
`values` remaps canonical values per key, and `static` merges literal provider fields
|
|
219
219
|
last. Video rows use `VIDEO_INPUT_SPEC_KEYS` (`prompt`, `durationSeconds`,
|
|
220
220
|
`aspectRatio`, `resolution`, `firstFrame`, `lastFrame`, `seed`, `negativePrompt`,
|
|
221
|
-
`generateAudio`, `cfgScale`, `promptExpansion`, `referenceImages`); image rows use
|
|
221
|
+
`generateAudio`, `cfgScale`, `promptExpansion`, `referenceImages`, `sourceVideo`); image rows use
|
|
222
222
|
`IMAGE_INPUT_SPEC_KEYS` (`prompt`, `references`, `aspectRatio`, `size`, `outputFormat`,
|
|
223
223
|
`seed`; map `references` to the provider's array field and remap `size` and `outputFormat`
|
|
224
224
|
with `values`); audio rows use
|
|
225
225
|
`AUDIO_INPUT_SPEC_KEYS` (`prompt`, `durationSeconds`, `seed`, `negativePrompt`,
|
|
226
226
|
`references`, `sourceVideo`, `instrumental`). `aspectRatio: "adaptive"` is omitted. A fal image row has no kind and builds its whole input from the spec; the optional `editEndpoint` (fal rows only) is the fal endpoint called instead of `providerModelId` when the request has references. fal rows without an `inputSpec` keep the Muse-shaped request and Ideogram keeps its own path; an `inputSpec` on an Ideogram row replaces that path. `editEndpoint` needs a `references` entry in `fields`. `inputSpec` on fal video rows is not supported.
|
|
227
|
+
`arrays` joins several image inputs into one provider array field, in the listed order: `arrays: { images: ["firstFrame", "referenceImages", "lastFrame"] }` (video rows: `firstFrame`, `referenceImages`, `lastFrame`; image rows: `references`). A key is mapped once, in `fields` or in one array, and the field is omitted when none of its inputs is set. A row that maps `sourceVideo` also needs `capabilities.acceptsSourceVideo`; set `capabilities.sourceVideoExcludesFrames` when the provider rejects a source video next to images.
|
|
227
228
|
`validateInputSpec` is the shared contract the write schema, `dataOnlyCapable`, and
|
|
228
229
|
the Replicate mapper all check. `dataOnlyCapable(row)` reports whether such a row would
|
|
229
230
|
be served.
|
package/dist/catalog.cjs
CHANGED
|
@@ -2066,8 +2066,16 @@ var VIDEO_MODELS = [
|
|
|
2066
2066
|
|
|
2067
2067
|
// src/catalog/video-tools.ts
|
|
2068
2068
|
var TOPAZ_LOGO = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/topazlabs.png";
|
|
2069
|
+
var FLUX_LOGO = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/flux.png";
|
|
2069
2070
|
var TOPAZ_SOURCE_SECONDS = { max: 300 };
|
|
2070
|
-
var
|
|
2071
|
+
var SECONDS_USAGE = { unit: "seconds" };
|
|
2072
|
+
var FLUX_SOURCE_SECONDS = { max: 20 };
|
|
2073
|
+
var FLUX_UPSCALE_TOOL = {
|
|
2074
|
+
kind: "upscale",
|
|
2075
|
+
upscaleFactor: { min: 1.5, max: 3 },
|
|
2076
|
+
maxOutputLongEdge: 3840,
|
|
2077
|
+
prompt: true
|
|
2078
|
+
};
|
|
2071
2079
|
var VIDEO_TOOL_MODELS = [
|
|
2072
2080
|
{
|
|
2073
2081
|
id: "topaz-precision",
|
|
@@ -2077,7 +2085,7 @@ var VIDEO_TOOL_MODELS = [
|
|
|
2077
2085
|
adapter: "fal",
|
|
2078
2086
|
providerModelId: "topaz/upscale/video/precision",
|
|
2079
2087
|
lifecycle: "active",
|
|
2080
|
-
exposure: ["cowork"],
|
|
2088
|
+
exposure: ["cowork", "space_builder"],
|
|
2081
2089
|
constraints: {
|
|
2082
2090
|
supports: [],
|
|
2083
2091
|
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
@@ -2085,7 +2093,7 @@ var VIDEO_TOOL_MODELS = [
|
|
|
2085
2093
|
},
|
|
2086
2094
|
defaults: {},
|
|
2087
2095
|
providerOptions: { fal: { model: "Proteus" } },
|
|
2088
|
-
usage:
|
|
2096
|
+
usage: SECONDS_USAGE,
|
|
2089
2097
|
pricingKind: "video_per_second",
|
|
2090
2098
|
display: {
|
|
2091
2099
|
provider: "topaz",
|
|
@@ -2102,7 +2110,7 @@ var VIDEO_TOOL_MODELS = [
|
|
|
2102
2110
|
adapter: "fal",
|
|
2103
2111
|
providerModelId: "topaz/upscale/video/generative",
|
|
2104
2112
|
lifecycle: "active",
|
|
2105
|
-
exposure: ["cowork"],
|
|
2113
|
+
exposure: ["cowork", "space_builder"],
|
|
2106
2114
|
constraints: {
|
|
2107
2115
|
supports: [],
|
|
2108
2116
|
sourceVideoSeconds: TOPAZ_SOURCE_SECONDS,
|
|
@@ -2110,7 +2118,7 @@ var VIDEO_TOOL_MODELS = [
|
|
|
2110
2118
|
},
|
|
2111
2119
|
defaults: {},
|
|
2112
2120
|
providerOptions: { fal: { model: "Starlight Precise 2.6" } },
|
|
2113
|
-
usage:
|
|
2121
|
+
usage: SECONDS_USAGE,
|
|
2114
2122
|
pricingKind: "video_per_second",
|
|
2115
2123
|
display: {
|
|
2116
2124
|
provider: "topaz",
|
|
@@ -2135,7 +2143,7 @@ var VIDEO_TOOL_MODELS = [
|
|
|
2135
2143
|
},
|
|
2136
2144
|
defaults: {},
|
|
2137
2145
|
providerOptions: { fal: { model: "Apollo" } },
|
|
2138
|
-
usage:
|
|
2146
|
+
usage: SECONDS_USAGE,
|
|
2139
2147
|
pricingKind: "video_per_second",
|
|
2140
2148
|
display: {
|
|
2141
2149
|
provider: "topaz",
|
|
@@ -2158,13 +2166,63 @@ var VIDEO_TOOL_MODELS = [
|
|
|
2158
2166
|
tool: { kind: "hdr", outputFormats: ["h265", "prores"] }
|
|
2159
2167
|
},
|
|
2160
2168
|
defaults: {},
|
|
2161
|
-
usage:
|
|
2169
|
+
usage: SECONDS_USAGE,
|
|
2162
2170
|
pricingKind: "video_per_second",
|
|
2163
2171
|
display: {
|
|
2164
2172
|
provider: "topaz",
|
|
2165
2173
|
logo: TOPAZ_LOGO,
|
|
2166
2174
|
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."
|
|
2167
2175
|
}
|
|
2176
|
+
},
|
|
2177
|
+
{
|
|
2178
|
+
id: "flux-video-upscale-precise",
|
|
2179
|
+
aliases: [],
|
|
2180
|
+
label: "FLUX Upscale Precise",
|
|
2181
|
+
type: "video-tool",
|
|
2182
|
+
adapter: "fal",
|
|
2183
|
+
providerModelId: "blackforestlabs/flux-video-upscale",
|
|
2184
|
+
lifecycle: "active",
|
|
2185
|
+
exposure: ["space_builder"],
|
|
2186
|
+
constraints: {
|
|
2187
|
+
supports: [],
|
|
2188
|
+
sourceVideoSeconds: FLUX_SOURCE_SECONDS,
|
|
2189
|
+
tool: FLUX_UPSCALE_TOOL
|
|
2190
|
+
},
|
|
2191
|
+
defaults: {},
|
|
2192
|
+
providerOptions: { fal: { input: { creativity: 0 } } },
|
|
2193
|
+
usage: SECONDS_USAGE,
|
|
2194
|
+
pricingKind: "video_per_second",
|
|
2195
|
+
display: {
|
|
2196
|
+
provider: "black-forest-labs",
|
|
2197
|
+
logo: FLUX_LOGO,
|
|
2198
|
+
description: "FLUX 3 super-resolution, source-faithful: 1.5x to 3x, up to 4K, for clips up to 20 seconds.",
|
|
2199
|
+
sortOrder: 30
|
|
2200
|
+
}
|
|
2201
|
+
},
|
|
2202
|
+
{
|
|
2203
|
+
id: "flux-video-upscale-creative",
|
|
2204
|
+
aliases: [],
|
|
2205
|
+
label: "FLUX Upscale Creative",
|
|
2206
|
+
type: "video-tool",
|
|
2207
|
+
adapter: "fal",
|
|
2208
|
+
providerModelId: "blackforestlabs/flux-video-upscale",
|
|
2209
|
+
lifecycle: "active",
|
|
2210
|
+
exposure: ["space_builder"],
|
|
2211
|
+
constraints: {
|
|
2212
|
+
supports: [],
|
|
2213
|
+
sourceVideoSeconds: FLUX_SOURCE_SECONDS,
|
|
2214
|
+
tool: FLUX_UPSCALE_TOOL
|
|
2215
|
+
},
|
|
2216
|
+
defaults: {},
|
|
2217
|
+
providerOptions: { fal: { input: { creativity: 1 } } },
|
|
2218
|
+
usage: SECONDS_USAGE,
|
|
2219
|
+
pricingKind: "video_per_second",
|
|
2220
|
+
display: {
|
|
2221
|
+
provider: "black-forest-labs",
|
|
2222
|
+
logo: FLUX_LOGO,
|
|
2223
|
+
description: "FLUX 3 super-resolution that adds fine detail, optionally guided by a prompt: 1.5x to 3x, up to 4K, for clips up to 20 seconds. Costs more than Precise.",
|
|
2224
|
+
sortOrder: 40
|
|
2225
|
+
}
|
|
2168
2226
|
}
|
|
2169
2227
|
];
|
|
2170
2228
|
|
|
@@ -2303,7 +2361,8 @@ var VIDEO_INPUT_SPEC_KEYS = [
|
|
|
2303
2361
|
"generateAudio",
|
|
2304
2362
|
"cfgScale",
|
|
2305
2363
|
"promptExpansion",
|
|
2306
|
-
"referenceImages"
|
|
2364
|
+
"referenceImages",
|
|
2365
|
+
"sourceVideo"
|
|
2307
2366
|
];
|
|
2308
2367
|
var IMAGE_INPUT_SPEC_KEYS = [
|
|
2309
2368
|
"prompt",
|
|
@@ -2322,6 +2381,12 @@ var AUDIO_INPUT_SPEC_KEYS = [
|
|
|
2322
2381
|
"sourceVideo",
|
|
2323
2382
|
"instrumental"
|
|
2324
2383
|
];
|
|
2384
|
+
var ARRAY_INPUT_SPEC_KEYS = [
|
|
2385
|
+
"firstFrame",
|
|
2386
|
+
"referenceImages",
|
|
2387
|
+
"lastFrame",
|
|
2388
|
+
"references"
|
|
2389
|
+
];
|
|
2325
2390
|
var INPUT_SPEC_SUPPORTS_KEYS = [
|
|
2326
2391
|
"lastFrame",
|
|
2327
2392
|
"seed",
|
|
@@ -2335,6 +2400,7 @@ var INPUT_SPEC_SUPPORTS_KEYS = [
|
|
|
2335
2400
|
var VIDEO_KEY_SET = new Set(VIDEO_INPUT_SPEC_KEYS);
|
|
2336
2401
|
var IMAGE_KEY_SET = new Set(IMAGE_INPUT_SPEC_KEYS);
|
|
2337
2402
|
var AUDIO_KEY_SET = new Set(AUDIO_INPUT_SPEC_KEYS);
|
|
2403
|
+
var ARRAY_KEY_SET = new Set(ARRAY_INPUT_SPEC_KEYS);
|
|
2338
2404
|
var ALL_KEY_SET = /* @__PURE__ */ new Set([
|
|
2339
2405
|
...VIDEO_INPUT_SPEC_KEYS,
|
|
2340
2406
|
...IMAGE_INPUT_SPEC_KEYS,
|
|
@@ -2379,13 +2445,30 @@ var ValuesSchema = import_zod2.z.record(import_zod2.z.string(), import_zod2.z.re
|
|
|
2379
2445
|
}
|
|
2380
2446
|
});
|
|
2381
2447
|
var StaticSchema = import_zod2.z.record(import_zod2.z.string(), ProviderScalarSchema);
|
|
2448
|
+
var ArraysSchema = import_zod2.z.record(import_zod2.z.string().min(1), import_zod2.z.array(import_zod2.z.string()).min(1)).superRefine((arrays, ctx) => {
|
|
2449
|
+
for (const [name, keys] of Object.entries(arrays)) {
|
|
2450
|
+
for (const key of keys) {
|
|
2451
|
+
if (!ARRAY_KEY_SET.has(key)) {
|
|
2452
|
+
ctx.addIssue({
|
|
2453
|
+
code: "custom",
|
|
2454
|
+
path: [name],
|
|
2455
|
+
message: `inputSpec.arrays "${name}" has unknown image key "${key}"`
|
|
2456
|
+
});
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
});
|
|
2382
2461
|
var InputSpecSchema = import_zod2.z.strictObject({
|
|
2383
2462
|
fields: FieldsSchema,
|
|
2384
2463
|
values: ValuesSchema.optional(),
|
|
2385
2464
|
static: StaticSchema.optional(),
|
|
2465
|
+
arrays: ArraysSchema.optional(),
|
|
2386
2466
|
editEndpoint: import_zod2.z.string().min(1).optional()
|
|
2387
2467
|
}).superRefine((spec, ctx) => {
|
|
2388
|
-
const mappedNames = new Set(
|
|
2468
|
+
const mappedNames = /* @__PURE__ */ new Set([
|
|
2469
|
+
...Object.values(spec.fields),
|
|
2470
|
+
...Object.keys(spec.arrays ?? {})
|
|
2471
|
+
]);
|
|
2389
2472
|
for (const key of Object.keys(spec.static ?? {})) {
|
|
2390
2473
|
if (mappedNames.has(key)) {
|
|
2391
2474
|
ctx.addIssue({
|
|
@@ -2474,14 +2557,54 @@ function validateInputSpec(raw, row) {
|
|
|
2474
2557
|
});
|
|
2475
2558
|
}
|
|
2476
2559
|
}
|
|
2560
|
+
const arrayOwner = /* @__PURE__ */ new Map();
|
|
2561
|
+
for (const [name, keys] of Object.entries(spec.arrays ?? {})) {
|
|
2562
|
+
const fieldKey = seenNames.get(name);
|
|
2563
|
+
if (fieldKey !== void 0) {
|
|
2564
|
+
issues.push({
|
|
2565
|
+
path: ["arrays", name],
|
|
2566
|
+
message: `inputSpec.arrays "${name}" is also the provider field of inputSpec.fields "${fieldKey}"`
|
|
2567
|
+
});
|
|
2568
|
+
}
|
|
2569
|
+
for (const key of keys) {
|
|
2570
|
+
if (allowed !== void 0 && !allowed.has(key)) {
|
|
2571
|
+
issues.push({
|
|
2572
|
+
path: ["arrays", name],
|
|
2573
|
+
message: `inputSpec.arrays "${key}" is not supported for ${row.type} rows`
|
|
2574
|
+
});
|
|
2575
|
+
}
|
|
2576
|
+
if (key in spec.fields) {
|
|
2577
|
+
issues.push({
|
|
2578
|
+
path: ["arrays", name],
|
|
2579
|
+
message: `inputSpec.arrays "${key}" is already mapped in inputSpec.fields`
|
|
2580
|
+
});
|
|
2581
|
+
}
|
|
2582
|
+
const owner = arrayOwner.get(key);
|
|
2583
|
+
if (owner === void 0) arrayOwner.set(key, name);
|
|
2584
|
+
else {
|
|
2585
|
+
issues.push({
|
|
2586
|
+
path: ["arrays", name],
|
|
2587
|
+
message: owner === name ? `inputSpec.arrays "${name}" lists "${key}" twice` : `inputSpec.arrays "${owner}" and "${name}" both take "${key}"`
|
|
2588
|
+
});
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2477
2592
|
const supports = row.constraints.supports ?? [];
|
|
2478
2593
|
for (const key of INPUT_SPEC_SUPPORTS_KEYS) {
|
|
2479
|
-
if (
|
|
2594
|
+
if (supports.includes(key)) continue;
|
|
2595
|
+
if (key in spec.fields) {
|
|
2480
2596
|
issues.push({
|
|
2481
2597
|
path: ["fields", key],
|
|
2482
2598
|
message: `inputSpec.fields "${key}" needs "${key}" in constraints.supports`
|
|
2483
2599
|
});
|
|
2484
2600
|
}
|
|
2601
|
+
const arrayName = arrayOwner.get(key);
|
|
2602
|
+
if (arrayName !== void 0) {
|
|
2603
|
+
issues.push({
|
|
2604
|
+
path: ["arrays", arrayName],
|
|
2605
|
+
message: `inputSpec.arrays "${key}" needs "${key}" in constraints.supports`
|
|
2606
|
+
});
|
|
2607
|
+
}
|
|
2485
2608
|
}
|
|
2486
2609
|
if (issues.length > 0) return { ok: false, issues };
|
|
2487
2610
|
return { ok: true, spec };
|
|
@@ -2606,6 +2729,7 @@ var VideoToolConstraintsSchema = import_zod3.z.looseObject({
|
|
|
2606
2729
|
kind: import_zod3.z.enum(["upscale", "interpolate", "hdr"]),
|
|
2607
2730
|
upscaleFactor: RangeSchema.optional(),
|
|
2608
2731
|
maxOutputLongEdge: import_zod3.z.number().positive().optional(),
|
|
2732
|
+
prompt: import_zod3.z.boolean().optional(),
|
|
2609
2733
|
fps: RangeSchema.optional(),
|
|
2610
2734
|
outputFormats: import_zod3.z.array(import_zod3.z.enum(["h265", "prores"])).min(1).optional()
|
|
2611
2735
|
});
|
|
@@ -2703,6 +2827,7 @@ var CatalogCapabilitiesSchema = import_zod3.z.looseObject({
|
|
|
2703
2827
|
acceptsSourceVideo: import_zod3.z.boolean().optional(),
|
|
2704
2828
|
videoEdit: import_zod3.z.boolean().optional(),
|
|
2705
2829
|
framesExcludeReferences: import_zod3.z.boolean().optional(),
|
|
2830
|
+
sourceVideoExcludesFrames: import_zod3.z.boolean().optional(),
|
|
2706
2831
|
lastFrameRequiresFirstFrame: import_zod3.z.boolean().optional(),
|
|
2707
2832
|
reasoning: import_zod3.z.boolean().optional(),
|
|
2708
2833
|
vision: import_zod3.z.boolean().optional(),
|
|
@@ -3063,6 +3188,7 @@ var ToolSchema = import_zod6.z.object({
|
|
|
3063
3188
|
kind: import_zod6.z.enum(["upscale", "interpolate", "hdr"]),
|
|
3064
3189
|
upscaleFactor: RangeSchema2.optional(),
|
|
3065
3190
|
maxOutputLongEdge: import_zod6.z.number().positive().optional(),
|
|
3191
|
+
prompt: import_zod6.z.boolean().optional(),
|
|
3066
3192
|
fps: RangeSchema2.optional(),
|
|
3067
3193
|
outputFormats: import_zod6.z.array(import_zod6.z.enum(["h265", "prores"])).min(1).optional()
|
|
3068
3194
|
});
|
|
@@ -3070,11 +3196,12 @@ function videoToolConstraints(row) {
|
|
|
3070
3196
|
if (row.type !== "video-tool") return void 0;
|
|
3071
3197
|
const parsed = ToolSchema.safeParse(row.constraints.tool);
|
|
3072
3198
|
if (!parsed.success) return void 0;
|
|
3073
|
-
const { kind, upscaleFactor, maxOutputLongEdge, fps, outputFormats } = parsed.data;
|
|
3199
|
+
const { kind, upscaleFactor, maxOutputLongEdge, prompt, fps, outputFormats } = parsed.data;
|
|
3074
3200
|
return {
|
|
3075
3201
|
kind,
|
|
3076
3202
|
...upscaleFactor !== void 0 && { upscaleFactor },
|
|
3077
3203
|
...maxOutputLongEdge !== void 0 && { maxOutputLongEdge },
|
|
3204
|
+
...prompt !== void 0 && { prompt },
|
|
3078
3205
|
...fps !== void 0 && { fps },
|
|
3079
3206
|
...outputFormats !== void 0 && { outputFormats }
|
|
3080
3207
|
};
|
|
@@ -3400,6 +3527,26 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
3400
3527
|
});
|
|
3401
3528
|
delete merged.sourceVideo;
|
|
3402
3529
|
}
|
|
3530
|
+
const imageInputs = ["firstFrame", "lastFrame", "referenceImages"].filter(
|
|
3531
|
+
(field) => field === "referenceImages" ? compact(merged.referenceImages).length > 0 : merged[field] !== void 0
|
|
3532
|
+
);
|
|
3533
|
+
if (merged.sourceVideo !== void 0 && imageInputs.length > 0 && model.capabilities?.sourceVideoExcludesFrames) {
|
|
3534
|
+
if (onUnsupported === "error") {
|
|
3535
|
+
throw new ModelKitError({
|
|
3536
|
+
code: "unsupported_option",
|
|
3537
|
+
message: `${model.id} takes a source video or images, not both`,
|
|
3538
|
+
model: model.id
|
|
3539
|
+
});
|
|
3540
|
+
}
|
|
3541
|
+
for (const field of imageInputs) {
|
|
3542
|
+
warnings.push({
|
|
3543
|
+
code: "option_ignored",
|
|
3544
|
+
field,
|
|
3545
|
+
message: `${model.id} takes a source video or images, not both; ${field} dropped`
|
|
3546
|
+
});
|
|
3547
|
+
delete merged[field];
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3403
3550
|
if (merged.lastFrame !== void 0 && merged.firstFrame === void 0 && model.capabilities?.lastFrameRequiresFirstFrame) {
|
|
3404
3551
|
if (onUnsupported === "error") {
|
|
3405
3552
|
throw new ModelKitError({
|