@shop-os/modelkit 0.13.0 → 0.15.0
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 +20 -0
- package/dist/catalog.cjs +82 -3
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +33 -2
- package/dist/catalog.d.ts +33 -2
- package/dist/catalog.js +82 -3
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +87 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -2
- package/dist/index.d.ts +33 -2
- package/dist/index.js +86 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,26 @@ header in the release PR.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.15.0] - Unreleased
|
|
13
|
+
|
|
14
|
+
Reference and source videos have a minimum frame size, checked before the provider call (ENG-3453).
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- `references.videoPixels` and `sourceVideoPixels` constraints (`{ minWidth?, minHeight? }`, `VideoPixelLimits`): the smallest frame a row takes for a reference or source video. Kits before 0.15.0 ignore them (the constraint objects are loose).
|
|
18
|
+
- `videoSizeViolation(model, { referenceVideos?, sourceVideo? })` beside `videoLengthViolation`: the first undersized video as a user-facing message ("Kling 4.0 takes reference videos at least 700 px wide; video 1 is 576 px."), from measured sizes. An unmeasured video passes.
|
|
19
|
+
- Limits from fal's schemas: `kling-4.0` reference videos and `kling-4.0-edit` source 700 px, `kling-o3-edit` source 720 px, `kling-3.0-motion-control-*` motion clip 340 px (width and height each). The stored `model_catalog` rows need the same values (pro-admin) for runtime checks to see them.
|
|
20
|
+
|
|
21
|
+
## [0.14.0] - Unreleased
|
|
22
|
+
|
|
23
|
+
Video Depth Anything on fal, as a Creative Studio video tool.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- Video-tool kind `depth`: a depth map of the source clip at its frame rate and length, H.264, billed per source second at the output tier. `planVideoTool` needs the source's measured frame rate when the row has `maxOutputFrames` (fal keeps the source rate and drops frames past the limit), refuses a clip past it, and shrinks the frame to `maxOutputShortEdge`.
|
|
27
|
+
- `depth-anything-video` (Video Depth Anything) video-tool row on the fal adapter (`fal-ai/depth-anything-video`), listed on `cowork`, sources up to 100 s. The adapter always sends `model: "VDA-Small"` and `colormap: "grayscale"` (Small is the only Apache-2.0 size; fal defaults to the CC-BY-NC Large). fal caps the output at a 1080 px short edge and 2400 frames and bills $0.04 per second. The `credit_pricing_video` rows ship in the consumer bump.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
- `submitFalVideoTool` sends `output_format` only for `hdr` rows; a tool kind with no fields of its own gets none.
|
|
31
|
+
|
|
12
32
|
## [0.13.0] - Unreleased
|
|
13
33
|
|
|
14
34
|
The fal and Luma keys have one env name each; every provider key now has exactly one name.
|
package/dist/catalog.cjs
CHANGED
|
@@ -79,6 +79,7 @@ __export(catalog_entry_exports, {
|
|
|
79
79
|
sortCatalogRows: () => sortCatalogRows,
|
|
80
80
|
takesTargetAspectRatio: () => takesTargetAspectRatio,
|
|
81
81
|
videoLengthViolation: () => videoLengthViolation,
|
|
82
|
+
videoSizeViolation: () => videoSizeViolation,
|
|
82
83
|
videoToolConstraints: () => videoToolConstraints
|
|
83
84
|
});
|
|
84
85
|
module.exports = __toCommonJS(catalog_entry_exports);
|
|
@@ -5167,6 +5168,7 @@ function klingMotionControl(tier) {
|
|
|
5167
5168
|
videos: 1,
|
|
5168
5169
|
audios: 0,
|
|
5169
5170
|
videoSeconds: { min: 3, max: 30.05 },
|
|
5171
|
+
videoPixels: { minWidth: 340, minHeight: 340 },
|
|
5170
5172
|
min: { images: 1, videos: 1 }
|
|
5171
5173
|
},
|
|
5172
5174
|
requires: ["references"],
|
|
@@ -5233,6 +5235,7 @@ var VIDEO_FAMILY_MODELS = [
|
|
|
5233
5235
|
references: { ...NO_REFERENCES, images: 4 },
|
|
5234
5236
|
requires: ["sourceVideo"],
|
|
5235
5237
|
sourceVideoSeconds: { min: 3, max: 15.05 },
|
|
5238
|
+
sourceVideoPixels: { minWidth: 720, minHeight: 720 },
|
|
5236
5239
|
// generateAudio keeps (true) or drops (false) the source soundtrack.
|
|
5237
5240
|
supports: ["generateAudio"],
|
|
5238
5241
|
prompt: KLING_PROMPT,
|
|
@@ -5273,7 +5276,8 @@ var VIDEO_FAMILY_MODELS = [
|
|
|
5273
5276
|
...NO_REFERENCES,
|
|
5274
5277
|
images: 10,
|
|
5275
5278
|
videos: 5,
|
|
5276
|
-
videoSeconds: { min: 3, max: 30.05, total: 30 }
|
|
5279
|
+
videoSeconds: { min: 3, max: 30.05, total: 30 },
|
|
5280
|
+
videoPixels: { minWidth: 700, minHeight: 700 }
|
|
5277
5281
|
},
|
|
5278
5282
|
supports: ["lastFrame"],
|
|
5279
5283
|
prompt: KLING_V4_PROMPT,
|
|
@@ -5307,6 +5311,7 @@ var VIDEO_FAMILY_MODELS = [
|
|
|
5307
5311
|
references: { ...NO_REFERENCES, images: 10 },
|
|
5308
5312
|
requires: ["sourceVideo"],
|
|
5309
5313
|
sourceVideoSeconds: { min: 3, max: 30.05 },
|
|
5314
|
+
sourceVideoPixels: { minWidth: 700, minHeight: 700 },
|
|
5310
5315
|
supports: [],
|
|
5311
5316
|
prompt: KLING_V4_PROMPT,
|
|
5312
5317
|
audio: KLING_V4_AUDIO
|
|
@@ -6643,6 +6648,33 @@ var VIDEO_TOOL_MODELS = [
|
|
|
6643
6648
|
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."
|
|
6644
6649
|
}
|
|
6645
6650
|
},
|
|
6651
|
+
{
|
|
6652
|
+
// https://fal.ai/models/fal-ai/depth-anything-video/api: greyscale depth (white = near)
|
|
6653
|
+
// at the source's frame rate, short edge capped at 1080 px (a 2160x3840 source came
|
|
6654
|
+
// back 1080x1920), at most 2400 frames; one fal price of $0.04 per second for every
|
|
6655
|
+
// model size. The adapter always sends VDA-Small, the only Apache-2.0 size. 100 s is
|
|
6656
|
+
// 2400 frames at 24 fps; the frame check refuses faster clips sooner.
|
|
6657
|
+
id: "depth-anything-video",
|
|
6658
|
+
aliases: [],
|
|
6659
|
+
label: "Video Depth Anything",
|
|
6660
|
+
type: "video-tool",
|
|
6661
|
+
adapter: "fal",
|
|
6662
|
+
providerModelId: "fal-ai/depth-anything-video",
|
|
6663
|
+
lifecycle: "active",
|
|
6664
|
+
exposure: ["cowork"],
|
|
6665
|
+
constraints: {
|
|
6666
|
+
supports: [],
|
|
6667
|
+
sourceVideoSeconds: { max: 100 },
|
|
6668
|
+
tool: { kind: "depth", maxOutputShortEdge: 1080, maxOutputFrames: 2400 }
|
|
6669
|
+
},
|
|
6670
|
+
defaults: {},
|
|
6671
|
+
usage: SECONDS_USAGE,
|
|
6672
|
+
pricingKind: "video_per_second",
|
|
6673
|
+
display: {
|
|
6674
|
+
provider: "depth-anything",
|
|
6675
|
+
description: "Video Depth Anything: a greyscale depth map of the clip (near is white), frame for frame, for motion and camera control."
|
|
6676
|
+
}
|
|
6677
|
+
},
|
|
6646
6678
|
{
|
|
6647
6679
|
id: "flux-video-upscale-precise",
|
|
6648
6680
|
aliases: [],
|
|
@@ -7830,6 +7862,10 @@ var VideoSecondsLimitsSchema = import_zod3.z.looseObject({
|
|
|
7830
7862
|
total: import_zod3.z.number().optional(),
|
|
7831
7863
|
editMin: import_zod3.z.number().optional()
|
|
7832
7864
|
});
|
|
7865
|
+
var VideoPixelLimitsSchema = import_zod3.z.looseObject({
|
|
7866
|
+
minWidth: import_zod3.z.number().int().positive().optional(),
|
|
7867
|
+
minHeight: import_zod3.z.number().int().positive().optional()
|
|
7868
|
+
});
|
|
7833
7869
|
var ReferenceLimitsSchema = import_zod3.z.looseObject({
|
|
7834
7870
|
images: import_zod3.z.number().optional(),
|
|
7835
7871
|
imagesWithVideo: import_zod3.z.number().optional(),
|
|
@@ -7838,6 +7874,7 @@ var ReferenceLimitsSchema = import_zod3.z.looseObject({
|
|
|
7838
7874
|
total: import_zod3.z.number().optional(),
|
|
7839
7875
|
audioOnly: import_zod3.z.boolean().optional(),
|
|
7840
7876
|
videoSeconds: VideoSecondsLimitsSchema.optional(),
|
|
7877
|
+
videoPixels: VideoPixelLimitsSchema.optional(),
|
|
7841
7878
|
audioSeconds: import_zod3.z.looseObject({
|
|
7842
7879
|
min: import_zod3.z.number().optional(),
|
|
7843
7880
|
max: import_zod3.z.number().optional(),
|
|
@@ -7866,7 +7903,7 @@ var LanguageOptionSchema = import_zod3.z.looseObject({
|
|
|
7866
7903
|
name: import_zod3.z.string().min(1)
|
|
7867
7904
|
});
|
|
7868
7905
|
var VideoToolConstraintsSchema = import_zod3.z.looseObject({
|
|
7869
|
-
kind: import_zod3.z.enum(["upscale", "interpolate", "hdr", "bg-remove", "subtitles"]),
|
|
7906
|
+
kind: import_zod3.z.enum(["upscale", "interpolate", "hdr", "bg-remove", "subtitles", "depth"]),
|
|
7870
7907
|
upscaleFactor: RangeSchema.optional(),
|
|
7871
7908
|
maxOutputLongEdge: import_zod3.z.number().positive().optional(),
|
|
7872
7909
|
prompt: import_zod3.z.boolean().optional(),
|
|
@@ -7927,6 +7964,7 @@ var ModelConstraintsSchema = import_zod3.z.looseObject({
|
|
|
7927
7964
|
}).optional(),
|
|
7928
7965
|
languages: import_zod3.z.array(LanguageOptionSchema).optional(),
|
|
7929
7966
|
outputFormats: import_zod3.z.array(import_zod3.z.string().min(1)).min(1).optional(),
|
|
7967
|
+
sourceVideoPixels: VideoPixelLimitsSchema.optional(),
|
|
7930
7968
|
sourceVideoSeconds: VideoSecondsLimitsSchema.omit({ total: true }).extend({ inReferenceTotal: import_zod3.z.boolean().optional() }).optional(),
|
|
7931
7969
|
// segmentSeconds/maxTotalSeconds stay required: a kit before 0.3.0 drops a row whose
|
|
7932
7970
|
// extension lacks them, so every extension block keeps them.
|
|
@@ -8472,7 +8510,7 @@ function subtitleProblem(label, tool, options, resolution, durationSeconds) {
|
|
|
8472
8510
|
// src/catalog/video-tools-spec.ts
|
|
8473
8511
|
var RangeSchema2 = import_zod6.z.object({ min: import_zod6.z.number(), max: import_zod6.z.number() });
|
|
8474
8512
|
var ToolSchema = import_zod6.z.object({
|
|
8475
|
-
kind: import_zod6.z.enum(["upscale", "interpolate", "hdr", "bg-remove", "subtitles"]),
|
|
8513
|
+
kind: import_zod6.z.enum(["upscale", "interpolate", "hdr", "bg-remove", "subtitles", "depth"]),
|
|
8476
8514
|
upscaleFactor: RangeSchema2.optional(),
|
|
8477
8515
|
maxOutputLongEdge: import_zod6.z.number().positive().optional(),
|
|
8478
8516
|
prompt: import_zod6.z.boolean().optional(),
|
|
@@ -8610,6 +8648,25 @@ function planVideoTool(row2, req) {
|
|
|
8610
8648
|
}
|
|
8611
8649
|
};
|
|
8612
8650
|
}
|
|
8651
|
+
if (tool.kind === "depth") {
|
|
8652
|
+
const limit = tool.maxOutputFrames;
|
|
8653
|
+
if (limit !== void 0) {
|
|
8654
|
+
if (fps === void 0) return fail("The source video's frame rate is required");
|
|
8655
|
+
if (durationSeconds * fps > limit) {
|
|
8656
|
+
return fail(`${row2.label} renders up to ${limit} frames (${seconds(limit, fps)}).`);
|
|
8657
|
+
}
|
|
8658
|
+
}
|
|
8659
|
+
const out2 = shrinkToShortEdge(width, height, tool.maxOutputShortEdge);
|
|
8660
|
+
return {
|
|
8661
|
+
ok: true,
|
|
8662
|
+
output: {
|
|
8663
|
+
...base,
|
|
8664
|
+
...out2,
|
|
8665
|
+
resolution: resolutionTier(out2.width, out2.height),
|
|
8666
|
+
format: "h264"
|
|
8667
|
+
}
|
|
8668
|
+
};
|
|
8669
|
+
}
|
|
8613
8670
|
if (tool.kind === "subtitles") {
|
|
8614
8671
|
const resolution = resolutionTier(width, height);
|
|
8615
8672
|
const problem = subtitleProblem(
|
|
@@ -9432,6 +9489,28 @@ function videoLengthViolation(model, input) {
|
|
|
9432
9489
|
return `${model.label} takes a source video of at least ${String(sourceMin)} s; this one is ${seconds2(source, sourceMin)} s.`;
|
|
9433
9490
|
return void 0;
|
|
9434
9491
|
}
|
|
9492
|
+
function undersizedSide(frame, limits) {
|
|
9493
|
+
if (!frame || !limits) return void 0;
|
|
9494
|
+
const { width, height } = frame;
|
|
9495
|
+
if (limits.minWidth !== void 0 && width !== void 0 && width > 0 && width < limits.minWidth)
|
|
9496
|
+
return { side: "wide", min: limits.minWidth, actual: width };
|
|
9497
|
+
if (limits.minHeight !== void 0 && height !== void 0 && height > 0 && height < limits.minHeight)
|
|
9498
|
+
return { side: "tall", min: limits.minHeight, actual: height };
|
|
9499
|
+
return void 0;
|
|
9500
|
+
}
|
|
9501
|
+
function videoSizeViolation(model, input) {
|
|
9502
|
+
const refLimits = model.constraints.references?.videoPixels;
|
|
9503
|
+
const refs = input.referenceVideos ?? [];
|
|
9504
|
+
for (let i = 0; i < refs.length; i++) {
|
|
9505
|
+
const under2 = undersizedSide(refs[i], refLimits);
|
|
9506
|
+
if (under2)
|
|
9507
|
+
return `${model.label} takes reference videos at least ${String(under2.min)} px ${under2.side}; video ${i + 1} is ${String(under2.actual)} px.`;
|
|
9508
|
+
}
|
|
9509
|
+
const under = undersizedSide(input.sourceVideo, model.constraints.sourceVideoPixels);
|
|
9510
|
+
if (under)
|
|
9511
|
+
return `${model.label} takes a source video at least ${String(under.min)} px ${under.side}; this one is ${String(under.actual)} px.`;
|
|
9512
|
+
return void 0;
|
|
9513
|
+
}
|
|
9435
9514
|
function resolveImageOptions(model, request, onUnsupported = "error") {
|
|
9436
9515
|
const warnings = [];
|
|
9437
9516
|
const c = model.constraints;
|