@shop-os/modelkit 0.7.7 → 0.7.10
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 +18 -0
- package/dist/catalog.cjs +26 -21
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.js +26 -21
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +112 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +112 -51
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5267,8 +5267,10 @@ var RAY_RESOLUTIONS = ["360p", "720p", "1080p"];
|
|
|
5267
5267
|
var RAY_PROMPT = { referenceSyntax: "numbered", maxChars: 6e3 };
|
|
5268
5268
|
var LUMA_VIDEO_MODELS = [
|
|
5269
5269
|
{
|
|
5270
|
-
// https://docs.agents.lumalabs.ai: type "video" with a
|
|
5271
|
-
// firstFrame and lastFrame ride as start_frame and end_frame.
|
|
5270
|
+
// https://docs.agents.lumalabs.ai: type "video" with a 5 s or 10 s duration;
|
|
5271
|
+
// firstFrame and lastFrame ride as start_frame and end_frame. Luma bills a
|
|
5272
|
+
// 10 s clip at 3x the 5 s price; pro-backend prices it that way, so this row
|
|
5273
|
+
// must not offer 10 s before that pricing is deployed (ENG-3324).
|
|
5272
5274
|
id: "ray-3.2",
|
|
5273
5275
|
aliases: [],
|
|
5274
5276
|
label: "Ray 3.2",
|
|
@@ -5280,7 +5282,7 @@ var LUMA_VIDEO_MODELS = [
|
|
|
5280
5282
|
constraints: {
|
|
5281
5283
|
aspectRatios: ["adaptive", ...RAY_RATIOS],
|
|
5282
5284
|
resolutions: [...RAY_RESOLUTIONS],
|
|
5283
|
-
durations: [5],
|
|
5285
|
+
durations: [5, 10],
|
|
5284
5286
|
supports: ["lastFrame"],
|
|
5285
5287
|
prompt: { ...RAY_PROMPT },
|
|
5286
5288
|
audio: "never"
|
|
@@ -5290,7 +5292,7 @@ var LUMA_VIDEO_MODELS = [
|
|
|
5290
5292
|
pricingKind: "video_per_second",
|
|
5291
5293
|
display: {
|
|
5292
5294
|
provider: "luma",
|
|
5293
|
-
description: "Luma Ray 3.2 text- and image-to-video with optional first and last frames, 5-second clips at up to 1080p.",
|
|
5295
|
+
description: "Luma Ray 3.2 text- and image-to-video with optional first and last frames, 5- or 10-second clips at up to 1080p.",
|
|
5294
5296
|
logo: LUMA_LOGO2
|
|
5295
5297
|
},
|
|
5296
5298
|
capabilities: {}
|
|
@@ -5800,38 +5802,38 @@ var VIDEO_MODELS = [
|
|
|
5800
5802
|
capabilities: { ...FRAMES_EXCLUDE_REFERENCES }
|
|
5801
5803
|
},
|
|
5802
5804
|
{
|
|
5803
|
-
// mode standard/pro/4k selects 720p/1080p/4K
|
|
5804
|
-
//
|
|
5805
|
-
//
|
|
5806
|
-
//
|
|
5805
|
+
// fal Kling O3 (adapters/fal-kling-omni.ts): mode standard/pro/4k selects 720p/1080p/4K
|
|
5806
|
+
// in the endpoint path. Moved off Replicate kwaivgi/kling-v3-omni-video, which fal sells
|
|
5807
|
+
// at half the price; the id and inputs stay. The Replicate mapper stays for deployed
|
|
5808
|
+
// model_catalog rows not yet switched. Frames and reference images share fal's cap of 7.
|
|
5809
|
+
// Reference video, multi-shot and keep-sound were never wired, so stay off.
|
|
5807
5810
|
id: "kling-v3-omni-video",
|
|
5808
5811
|
aliases: ["kwaivgi/kling-v3-omni-video", "kling-v3-omni"],
|
|
5809
5812
|
label: "Kling V3 Omni",
|
|
5810
5813
|
type: "video",
|
|
5811
|
-
adapter: "
|
|
5812
|
-
providerModelId: "
|
|
5814
|
+
adapter: "fal",
|
|
5815
|
+
providerModelId: "fal-ai/kling-video/o3",
|
|
5813
5816
|
lifecycle: "active",
|
|
5814
5817
|
exposure: ["cowork", "space_builder"],
|
|
5815
5818
|
constraints: {
|
|
5816
5819
|
aspectRatios: [...KLING_OMNI_RATIOS],
|
|
5817
5820
|
resolutions: ["720p", "1080p", "4k"],
|
|
5818
5821
|
durations: { min: 3, max: 15 },
|
|
5819
|
-
references: { images: 7,
|
|
5822
|
+
references: { images: 7, videos: 0, audios: 0 },
|
|
5820
5823
|
supports: ["generateAudio", "lastFrame"],
|
|
5821
5824
|
prompt: KLING_PROMPT2,
|
|
5822
5825
|
audio: "optional"
|
|
5823
5826
|
},
|
|
5824
5827
|
defaults: { durationSeconds: 5, aspectRatio: "16:9", generateAudio: true, mode: "pro" },
|
|
5825
|
-
usage: {
|
|
5828
|
+
usage: { ...VIDEO_USAGE3 },
|
|
5826
5829
|
pricingKind: "video_per_second",
|
|
5827
5830
|
display: {
|
|
5828
5831
|
provider: "kuaishou",
|
|
5829
5832
|
logo: "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/kling-color.png",
|
|
5830
|
-
description: "Kuaishou Kling Video 3.0 Omni
|
|
5833
|
+
description: "Kuaishou Kling Video 3.0 Omni generation from text, start/end images and up to 7 reference images, with optional native audio; up to 15 seconds at up to 4K."
|
|
5831
5834
|
}
|
|
5832
|
-
//
|
|
5833
|
-
//
|
|
5834
|
-
// the adapter sends as start_image.
|
|
5835
|
+
// No lastFrameRequiresFirstFrame: fal image-to-video needs a start frame, so the adapter
|
|
5836
|
+
// sends a lone end frame as the start frame, as the Replicate model took it.
|
|
5835
5837
|
},
|
|
5836
5838
|
{
|
|
5837
5839
|
id: "minimax-h3",
|
|
@@ -9446,11 +9448,11 @@ function toolInput(ctx, req, output) {
|
|
|
9446
9448
|
}
|
|
9447
9449
|
var EXR_DEFAULT_PROMPT = "The same video in high dynamic range, with unchanged content, motion, framing and timing.";
|
|
9448
9450
|
async function submitFalVideoTool(req, ctx, opts) {
|
|
9449
|
-
const
|
|
9450
|
-
if (!
|
|
9451
|
+
const plan4 = planVideoTool(ctx.model, req);
|
|
9452
|
+
if (!plan4.ok) {
|
|
9451
9453
|
throw new ModelKitError({
|
|
9452
9454
|
code: "unsupported_option",
|
|
9453
|
-
message:
|
|
9455
|
+
message: plan4.error,
|
|
9454
9456
|
provider: "fal",
|
|
9455
9457
|
model: ctx.model.id,
|
|
9456
9458
|
retryable: false
|
|
@@ -9458,7 +9460,7 @@ async function submitFalVideoTool(req, ctx, opts) {
|
|
|
9458
9460
|
}
|
|
9459
9461
|
const target = new URL(`${FAL_QUEUE_ORIGIN}/${ctx.model.providerModelId}`);
|
|
9460
9462
|
if (opts.webhookUrl !== void 0) target.searchParams.set("fal_webhook", opts.webhookUrl);
|
|
9461
|
-
const res = await queueFetch(ctx, target.toString(), "POST", toolInput(ctx, req,
|
|
9463
|
+
const res = await queueFetch(ctx, target.toString(), "POST", toolInput(ctx, req, plan4.output));
|
|
9462
9464
|
const parsed = submitResponseSchema.safeParse(await readJson(ctx, res));
|
|
9463
9465
|
if (!parsed.success) {
|
|
9464
9466
|
throw new ModelKitError({
|
|
@@ -9476,7 +9478,7 @@ async function submitFalVideoTool(req, ctx, opts) {
|
|
|
9476
9478
|
statusUrl: parsed.data.status_url,
|
|
9477
9479
|
responseUrl: parsed.data.response_url,
|
|
9478
9480
|
cancelUrl: parsed.data.cancel_url,
|
|
9479
|
-
output:
|
|
9481
|
+
output: plan4.output
|
|
9480
9482
|
};
|
|
9481
9483
|
}
|
|
9482
9484
|
async function falVideoToolStatus(sub, ctx) {
|
|
@@ -10165,14 +10167,14 @@ function planFalImage(req, providerModelId, model) {
|
|
|
10165
10167
|
const exact = falExactSize(spec, req);
|
|
10166
10168
|
const call = { label: spec.label, req, refs, edit: edit2, ...exact !== void 0 && { exact } };
|
|
10167
10169
|
const built = family.build(call, model);
|
|
10168
|
-
const
|
|
10170
|
+
const plan4 = {
|
|
10169
10171
|
endpoint: edit2 && family.editEndpoint !== void 0 ? family.editEndpoint : id,
|
|
10170
10172
|
input: built.input,
|
|
10171
10173
|
output: family.output ?? "images"
|
|
10172
10174
|
};
|
|
10173
|
-
if (built.imageQuality !== void 0)
|
|
10174
|
-
if (built.imageSize !== void 0)
|
|
10175
|
-
return
|
|
10175
|
+
if (built.imageQuality !== void 0) plan4.imageQuality = built.imageQuality;
|
|
10176
|
+
if (built.imageSize !== void 0) plan4.imageSize = built.imageSize;
|
|
10177
|
+
return plan4;
|
|
10176
10178
|
}
|
|
10177
10179
|
var FalFileSchema = import_zod14.z.object({ url: import_zod14.z.string(), content_type: import_zod14.z.string().nullish() });
|
|
10178
10180
|
var ImagesPayloadSchema = import_zod14.z.object({ images: import_zod14.z.array(FalFileSchema) });
|
|
@@ -10194,18 +10196,18 @@ async function downloadFalFile(ctx, file) {
|
|
|
10194
10196
|
const mime = res.headers.get("content-type") ?? file.content_type ?? "";
|
|
10195
10197
|
return { bytes: new Uint8Array(await res.arrayBuffer()), mime };
|
|
10196
10198
|
}
|
|
10197
|
-
function filesOf(payload,
|
|
10198
|
-
if (
|
|
10199
|
+
function filesOf(payload, plan4) {
|
|
10200
|
+
if (plan4.output === "image") {
|
|
10199
10201
|
const parsed2 = ImagePayloadSchema.safeParse(payload);
|
|
10200
10202
|
return parsed2.success ? [parsed2.data.image] : [];
|
|
10201
10203
|
}
|
|
10202
10204
|
const parsed = ImagesPayloadSchema.safeParse(payload);
|
|
10203
10205
|
return parsed.success ? parsed.data.images : [];
|
|
10204
10206
|
}
|
|
10205
|
-
async function collectFalPlanImages(payload,
|
|
10206
|
-
const files = filesOf(payload,
|
|
10207
|
+
async function collectFalPlanImages(payload, plan4, ctx, req) {
|
|
10208
|
+
const files = filesOf(payload, plan4);
|
|
10207
10209
|
if (files.length === 0) {
|
|
10208
|
-
throw fail2(ctx.model.id, `fal ${
|
|
10210
|
+
throw fail2(ctx.model.id, `fal ${plan4.endpoint} returned no image`, "provider_rejected");
|
|
10209
10211
|
}
|
|
10210
10212
|
const images = await Promise.all(
|
|
10211
10213
|
files.map(async (file) => {
|
|
@@ -10220,18 +10222,18 @@ async function collectFalPlanImages(payload, plan3, ctx, req) {
|
|
|
10220
10222
|
unit: "images",
|
|
10221
10223
|
quantity: images.length
|
|
10222
10224
|
};
|
|
10223
|
-
const billedSize =
|
|
10225
|
+
const billedSize = plan4.imageSize ?? req.size;
|
|
10224
10226
|
if (billedSize !== void 0 && ctx.model.type === "image") usage3.imageSize = billedSize;
|
|
10225
|
-
if (
|
|
10227
|
+
if (plan4.imageQuality !== void 0) usage3.imageQuality = plan4.imageQuality;
|
|
10226
10228
|
const result = { images, usage: usage3, raw: payload };
|
|
10227
10229
|
const remote = files.find((f) => !f.url.startsWith("data:"));
|
|
10228
10230
|
if (remote !== void 0) result.outputUrl = remote.url;
|
|
10229
10231
|
return result;
|
|
10230
10232
|
}
|
|
10231
10233
|
async function generateFalFamilyImage(req, ctx, run) {
|
|
10232
|
-
const
|
|
10233
|
-
const payload = await run(
|
|
10234
|
-
return collectFalPlanImages(payload,
|
|
10234
|
+
const plan4 = planFalImage(req, ctx.model.providerModelId, ctx.model.id);
|
|
10235
|
+
const payload = await run(plan4.endpoint, plan4.input);
|
|
10236
|
+
return collectFalPlanImages(payload, plan4, ctx, req);
|
|
10235
10237
|
}
|
|
10236
10238
|
|
|
10237
10239
|
// src/adapters/fal-mask.ts
|
|
@@ -11329,10 +11331,50 @@ var KLING_TIERS = [
|
|
|
11329
11331
|
{ mode: "pro", resolution: "1080p" },
|
|
11330
11332
|
{ mode: "4k", resolution: "4k" }
|
|
11331
11333
|
];
|
|
11334
|
+
var KLING_O3_OMNI = "fal-ai/kling-video/o3";
|
|
11332
11335
|
function klingTier(req) {
|
|
11333
11336
|
return KLING_TIERS.find((tier) => tier.resolution === req.resolution) ?? KLING_TIERS.find((tier) => tier.mode === req.mode) ?? KLING_TIERS[0];
|
|
11334
11337
|
}
|
|
11335
11338
|
|
|
11339
|
+
// src/adapters/fal-kling-omni.ts
|
|
11340
|
+
function plan(req, ctx) {
|
|
11341
|
+
const tier = klingTier(req);
|
|
11342
|
+
const duration = wholeSeconds(req, ctx);
|
|
11343
|
+
const input = {
|
|
11344
|
+
prompt: req.prompt.trim(),
|
|
11345
|
+
duration: String(duration),
|
|
11346
|
+
generate_audio: req.generateAudio ?? true
|
|
11347
|
+
};
|
|
11348
|
+
const start = req.firstFrame ?? req.lastFrame;
|
|
11349
|
+
const end = req.firstFrame ? req.lastFrame : void 0;
|
|
11350
|
+
const images = urls(req.referenceImages);
|
|
11351
|
+
let task;
|
|
11352
|
+
if (images.length > 0) {
|
|
11353
|
+
task = "reference-to-video";
|
|
11354
|
+
input["image_urls"] = images;
|
|
11355
|
+
if (start) input["start_image_url"] = refToUrl(start);
|
|
11356
|
+
if (end) input["end_image_url"] = refToUrl(end);
|
|
11357
|
+
} else if (start) {
|
|
11358
|
+
task = "image-to-video";
|
|
11359
|
+
input["image_url"] = refToUrl(start);
|
|
11360
|
+
if (end) input["end_image_url"] = refToUrl(end);
|
|
11361
|
+
} else {
|
|
11362
|
+
task = "text-to-video";
|
|
11363
|
+
}
|
|
11364
|
+
const ratio = concreteRatio(req);
|
|
11365
|
+
if (ratio !== void 0 && start === void 0) input["aspect_ratio"] = ratio;
|
|
11366
|
+
return {
|
|
11367
|
+
endpoint: `${KLING_O3_OMNI}/${tier.mode}/${task}`,
|
|
11368
|
+
input,
|
|
11369
|
+
resolution: tier.resolution,
|
|
11370
|
+
seconds: requestedSeconds(duration)
|
|
11371
|
+
};
|
|
11372
|
+
}
|
|
11373
|
+
var klingOmniFamily = {
|
|
11374
|
+
ids: /* @__PURE__ */ new Set([KLING_O3_OMNI]),
|
|
11375
|
+
plan
|
|
11376
|
+
};
|
|
11377
|
+
|
|
11336
11378
|
// src/resolve-video-rules.ts
|
|
11337
11379
|
var MOTION_PRO2 = "fal-ai/kling-video/v3/pro/motion-control";
|
|
11338
11380
|
var MOTION_STANDARD2 = "fal-ai/kling-video/v3/standard/motion-control";
|
|
@@ -11477,6 +11519,7 @@ var RULES = /* @__PURE__ */ new Map([
|
|
|
11477
11519
|
[MOTION_PRO2, motionControl2],
|
|
11478
11520
|
[MOTION_STANDARD2, motionControl2],
|
|
11479
11521
|
[O3_REFERENCE2, o3Reference2],
|
|
11522
|
+
[KLING_O3_OMNI, o3Reference2],
|
|
11480
11523
|
[O3_EDIT2, (req) => needsSource(req) ?? needsPrompt(req)],
|
|
11481
11524
|
[H3_TURBO, h3Turbo],
|
|
11482
11525
|
[MINIMAX_H3_INSERT, h3Insert],
|
|
@@ -11506,13 +11549,14 @@ function h3EndFrameRatioWarning(model, ratio) {
|
|
|
11506
11549
|
message: `${model.id} follows the end frame's aspect ratio`
|
|
11507
11550
|
};
|
|
11508
11551
|
}
|
|
11509
|
-
function
|
|
11552
|
+
function takesKlingMode(model) {
|
|
11553
|
+
if (model.adapter === "fal") return model.providerModelId.toLowerCase() === KLING_O3_OMNI;
|
|
11510
11554
|
if (model.adapter !== "replicate") return false;
|
|
11511
11555
|
const kind = videoKind(model.providerModelId);
|
|
11512
11556
|
return kind === "kling" || kind === "kling-omni";
|
|
11513
11557
|
}
|
|
11514
|
-
function
|
|
11515
|
-
if (
|
|
11558
|
+
function fillKlingModeResolution(model, req) {
|
|
11559
|
+
if (takesKlingMode(model) && req.resolution === void 0) {
|
|
11516
11560
|
req.resolution = klingTier(req).resolution;
|
|
11517
11561
|
}
|
|
11518
11562
|
}
|
|
@@ -11651,7 +11695,7 @@ var minimaxH3MaxFamily = {
|
|
|
11651
11695
|
|
|
11652
11696
|
// src/adapters/fal-omnihuman.ts
|
|
11653
11697
|
var OMNIHUMAN_V22 = "bytedance/omnihuman/v2";
|
|
11654
|
-
function
|
|
11698
|
+
function plan2(req, ctx) {
|
|
11655
11699
|
const [image] = req.referenceImages ?? [];
|
|
11656
11700
|
const [audio] = req.referenceAudios ?? [];
|
|
11657
11701
|
if (image === void 0 || audio === void 0) {
|
|
@@ -11662,14 +11706,14 @@ function plan(req, ctx) {
|
|
|
11662
11706
|
return { endpoint: OMNIHUMAN_V22, input, seconds: inputLengthSeconds(req, audio) };
|
|
11663
11707
|
}
|
|
11664
11708
|
var OMNIHUMAN_MODEL_IDS = /* @__PURE__ */ new Set([OMNIHUMAN_V22]);
|
|
11665
|
-
var omnihumanFamily = { ids: OMNIHUMAN_MODEL_IDS, plan };
|
|
11709
|
+
var omnihumanFamily = { ids: OMNIHUMAN_MODEL_IDS, plan: plan2 };
|
|
11666
11710
|
|
|
11667
11711
|
// src/adapters/fal-vidu.ts
|
|
11668
11712
|
var FAMILY2 = "fal-ai/vidu/q4";
|
|
11669
11713
|
function viduTier(resolution) {
|
|
11670
11714
|
return resolution === "2k" || resolution === "4k" ? upperTier(resolution) : resolution;
|
|
11671
11715
|
}
|
|
11672
|
-
function
|
|
11716
|
+
function plan3(req, ctx) {
|
|
11673
11717
|
const images = urls(req.referenceImages);
|
|
11674
11718
|
const audios = urls(req.referenceAudios);
|
|
11675
11719
|
const duration = wholeSeconds(req, ctx);
|
|
@@ -11696,11 +11740,12 @@ function plan2(req, ctx) {
|
|
|
11696
11740
|
return { endpoint, input, resolution, seconds: requestedSeconds(duration) };
|
|
11697
11741
|
}
|
|
11698
11742
|
var VIDU_MODEL_IDS = /* @__PURE__ */ new Set([FAMILY2]);
|
|
11699
|
-
var viduFamily = { ids: VIDU_MODEL_IDS, plan:
|
|
11743
|
+
var viduFamily = { ids: VIDU_MODEL_IDS, plan: plan3 };
|
|
11700
11744
|
|
|
11701
11745
|
// src/adapters/fal-video-families.ts
|
|
11702
11746
|
var FAMILIES2 = [
|
|
11703
11747
|
klingV3Family,
|
|
11748
|
+
klingOmniFamily,
|
|
11704
11749
|
minimaxH3MaxFamily,
|
|
11705
11750
|
happyHorseFamily,
|
|
11706
11751
|
viduFamily,
|
|
@@ -12177,7 +12222,7 @@ function extractVideoUrl(result, endpoint, model) {
|
|
|
12177
12222
|
}
|
|
12178
12223
|
async function generateFalVideo(req, ctx, deps) {
|
|
12179
12224
|
const providerModelId = ctx.model.providerModelId;
|
|
12180
|
-
const
|
|
12225
|
+
const plan4 = planFalFamilyVideo(req, ctx);
|
|
12181
12226
|
const start = (endpoint2, input, usageOf2) => startFalVideoJob(
|
|
12182
12227
|
ctx,
|
|
12183
12228
|
() => falClientOf(ctx, deps),
|
|
@@ -12185,7 +12230,7 @@ async function generateFalVideo(req, ctx, deps) {
|
|
|
12185
12230
|
input,
|
|
12186
12231
|
videoFileDecoder(ctx, req, endpoint2, usageOf2)
|
|
12187
12232
|
);
|
|
12188
|
-
if (
|
|
12233
|
+
if (plan4 !== void 0) return start(plan4.endpoint, plan4.input, planUsage(ctx, plan4));
|
|
12189
12234
|
if (isKling(providerModelId)) return start(KLING_O1_ENDPOINT, klingO1Input(req));
|
|
12190
12235
|
if (isWan(providerModelId)) {
|
|
12191
12236
|
const { endpoint: endpoint2, input } = wanVideo(req, providerModelId.toLowerCase());
|
|
@@ -12235,9 +12280,9 @@ function videoFileDecoder(ctx, req, endpoint, usageOf2) {
|
|
|
12235
12280
|
raw: payload
|
|
12236
12281
|
});
|
|
12237
12282
|
}
|
|
12238
|
-
function planUsage(ctx,
|
|
12283
|
+
function planUsage(ctx, plan4) {
|
|
12239
12284
|
return (payload) => {
|
|
12240
|
-
const seconds3 =
|
|
12285
|
+
const seconds3 = plan4.seconds(payload);
|
|
12241
12286
|
return {
|
|
12242
12287
|
model: ctx.model.id,
|
|
12243
12288
|
provider: "fal",
|
|
@@ -12245,7 +12290,7 @@ function planUsage(ctx, plan3) {
|
|
|
12245
12290
|
unit: "seconds",
|
|
12246
12291
|
quantity: seconds3,
|
|
12247
12292
|
durationSeconds: seconds3,
|
|
12248
|
-
...
|
|
12293
|
+
...plan4.resolution !== void 0 && { resolution: plan4.resolution }
|
|
12249
12294
|
};
|
|
12250
12295
|
};
|
|
12251
12296
|
}
|
|
@@ -14268,6 +14313,21 @@ function imageUsage2(ctx) {
|
|
|
14268
14313
|
};
|
|
14269
14314
|
}
|
|
14270
14315
|
var GENERATE_SECONDS = 5;
|
|
14316
|
+
var GENERATE_LENGTHS = [5, 10];
|
|
14317
|
+
function generateSeconds(req) {
|
|
14318
|
+
return req.durationSeconds ?? GENERATE_SECONDS;
|
|
14319
|
+
}
|
|
14320
|
+
function checkGenerateSeconds(req, ctx) {
|
|
14321
|
+
const seconds3 = generateSeconds(req);
|
|
14322
|
+
if (GENERATE_LENGTHS.includes(seconds3)) return;
|
|
14323
|
+
throw new ModelKitError({
|
|
14324
|
+
code: "unsupported_option",
|
|
14325
|
+
message: `${ctx.model.id} renders ${GENERATE_LENGTHS.join(" or ")} s clips, not ${seconds3} s`,
|
|
14326
|
+
provider: "luma",
|
|
14327
|
+
model: ctx.model.id,
|
|
14328
|
+
retryable: false
|
|
14329
|
+
});
|
|
14330
|
+
}
|
|
14271
14331
|
var MAX_PLAUSIBLE_SECONDS = 60;
|
|
14272
14332
|
function editedSeconds(req, bytes) {
|
|
14273
14333
|
const measured = mp4DurationSeconds(bytes);
|
|
@@ -14333,7 +14393,7 @@ function videoBody(req, ctx, mode) {
|
|
|
14333
14393
|
prompt,
|
|
14334
14394
|
video: {
|
|
14335
14395
|
...req.resolution !== void 0 && { resolution: req.resolution },
|
|
14336
|
-
duration:
|
|
14396
|
+
duration: `${generateSeconds(req)}s`,
|
|
14337
14397
|
...req.firstFrame !== void 0 && { start_frame: imageRef(req.firstFrame) },
|
|
14338
14398
|
...req.lastFrame !== void 0 && { end_frame: imageRef(req.lastFrame) }
|
|
14339
14399
|
}
|
|
@@ -14442,7 +14502,7 @@ function lumaVideoJob(ctx, req, mode, id) {
|
|
|
14442
14502
|
if (mode === "generate") {
|
|
14443
14503
|
const result2 = {
|
|
14444
14504
|
video: { url, expiresAt: new Date(Date.now() + OUTPUT_URL_TTL_MS) },
|
|
14445
|
-
usage: videoUsage4(jobCtx, req, mode,
|
|
14505
|
+
usage: videoUsage4(jobCtx, req, mode, generateSeconds(req)),
|
|
14446
14506
|
raw: { id }
|
|
14447
14507
|
};
|
|
14448
14508
|
return result2;
|
|
@@ -14470,6 +14530,7 @@ async function generateLumaVideo(req, ctx) {
|
|
|
14470
14530
|
});
|
|
14471
14531
|
}
|
|
14472
14532
|
const mode = lumaVideoMode(ctx);
|
|
14533
|
+
if (mode === "generate") checkGenerateSeconds(req, ctx);
|
|
14473
14534
|
const created = await submitGeneration(ctx, videoBody(req, ctx, mode));
|
|
14474
14535
|
return lumaVideoJob(ctx, req, mode, created.id);
|
|
14475
14536
|
}
|
|
@@ -16681,10 +16742,10 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
16681
16742
|
warnings
|
|
16682
16743
|
);
|
|
16683
16744
|
if (aspectRatio !== void 0) merged.aspectRatio = aspectRatio;
|
|
16684
|
-
|
|
16745
|
+
fillKlingModeResolution(model, merged);
|
|
16685
16746
|
const resolution = resolveVideoResolution(merged.resolution, model, onUnsupported, warnings);
|
|
16686
16747
|
if (resolution !== void 0) merged.resolution = resolution;
|
|
16687
|
-
if (
|
|
16748
|
+
if (takesKlingMode(model)) delete merged.mode;
|
|
16688
16749
|
const duration = resolveDuration(
|
|
16689
16750
|
merged.durationSeconds,
|
|
16690
16751
|
c.durations,
|