@nodaro/shared 2.20.0 → 2.21.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/dist/index.cjs +458 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +368 -8
- package/dist/index.d.ts +368 -8
- package/dist/index.js +447 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/safety-retry-policy.test.ts +62 -0
- package/src/__tests__/topaz-upscale.test.ts +132 -0
- package/src/__tests__/unresolved-ref-tokens.test.ts +66 -0
- package/src/__tests__/video-analysis.test.ts +83 -0
- package/src/__tests__/video-audio-capability.test.ts +38 -4
- package/src/__tests__/video-catalog-totality.test.ts +85 -0
- package/src/__tests__/video-collapse-parity.test.ts +76 -0
- package/src/__tests__/video-ref-video-duration-limits.test.ts +69 -0
- package/src/__tests__/video-request-normalize.test.ts +239 -0
- package/src/credit-identifiers.ts +115 -8
- package/src/index.ts +23 -3
- package/src/model-catalog.ts +288 -6
- package/src/model-constants.ts +116 -4
- package/src/node-refs.ts +82 -0
- package/src/node-runtime-keys.ts +13 -0
- package/src/safety-retry-policy.ts +37 -0
- package/src/topaz-upscale.ts +163 -0
- package/src/video-analysis.ts +70 -5
package/dist/index.cjs
CHANGED
|
@@ -55,7 +55,7 @@ var MODEL_RECOMMENDATIONS = [
|
|
|
55
55
|
{ intent: "cheapest realistic image", modelIds: ["z-image", "qwen", "imagen4-fast"], note: "Z-Image is the cheapest. Qwen / Imagen4 Fast for slightly higher quality." },
|
|
56
56
|
{ intent: "highest fidelity image", modelIds: ["nano-banana-pro", "imagen4-ultra", "flux-flex"], note: "Pick by family preference; all three are premium tiers." },
|
|
57
57
|
{ intent: "image edit / restyle", modelIds: ["flux-kontext", "ideogram-remix", "seedream-5-pro-i2i"], note: "Flux Kontext preserves identity; Ideogram Remix is character-aware; Seedream 5 Pro for instruction-based edits (5 Lite is the budget option)." },
|
|
58
|
-
{ intent: "highest-resolution image
|
|
58
|
+
{ intent: "highest-resolution image", modelIds: ["topaz-image-upscale", "nano-banana-pro", "gpt-image-2"], note: "Generate at the model's top tier, then Topaz upscale 4x (Topaz's only lever is the 1x/2x/4x factor)." },
|
|
59
59
|
{ intent: "background removal / cutout", modelIds: ["recraft-remove-bg"], note: "Cheap, no prompt needed." },
|
|
60
60
|
// video
|
|
61
61
|
{ intent: "best cinematic video", modelIds: ["veo3", "kling-3.0", "seedance-2"], note: "VEO 3.1 Quality for premium narrative; Kling 3.0 for music-synced motion; Seedance 2 for reference-driven consistency." },
|
|
@@ -398,7 +398,8 @@ var IMAGE_MODELS = {
|
|
|
398
398
|
{ identifier: "gpt-image-2", credits: 15, note: "1K default" },
|
|
399
399
|
{ identifier: "gpt-image-2:2K", credits: 30, note: "2K" },
|
|
400
400
|
{ identifier: "gpt-image-2:4K", credits: 60, note: "4K" }
|
|
401
|
-
]
|
|
401
|
+
],
|
|
402
|
+
safetyFilter: { stochastic: true, fallback: "nano-banana-pro" }
|
|
402
403
|
},
|
|
403
404
|
"gpt-image-2-i2i": {
|
|
404
405
|
id: "gpt-image-2-i2i",
|
|
@@ -408,6 +409,7 @@ var IMAGE_MODELS = {
|
|
|
408
409
|
label: "GPT Image 2 (I2I)",
|
|
409
410
|
series: "GPT Image",
|
|
410
411
|
description: "Image-to-image with GPT Image 2.",
|
|
412
|
+
safetyFilter: { stochastic: true, fallback: "nano-banana-pro" },
|
|
411
413
|
useCases: ["edit", "high-res"],
|
|
412
414
|
features: ["reference-image"],
|
|
413
415
|
aspectRatios: GPT_IMAGE_2_RATIOS,
|
|
@@ -818,14 +820,15 @@ var IMAGE_MODELS = {
|
|
|
818
820
|
family: "Topaz",
|
|
819
821
|
label: "Topaz Image Upscale",
|
|
820
822
|
series: "Topaz",
|
|
821
|
-
description: "High-quality image upscale
|
|
823
|
+
description: "High-quality image upscale at 1x (enhance only), 2x or 4x. Best for production-ready output.",
|
|
822
824
|
useCases: ["upscale", "high-res", "premium"],
|
|
823
825
|
features: ["reference-image"],
|
|
824
|
-
resolutions
|
|
826
|
+
// No `resolutions`: the provider's only quality lever is `upscale_factor`
|
|
827
|
+
// (1/2/4) — see resolveTopazUpscale. The 2K/4K/8K menu this used to
|
|
828
|
+
// advertise had no provider parameter behind it.
|
|
825
829
|
pricing: [
|
|
826
|
-
{ identifier: "topaz-image-upscale", credits: 25, note: "
|
|
827
|
-
{ identifier: "topaz-image-upscale:4K", credits: 50, note: "
|
|
828
|
-
{ identifier: "topaz-image-upscale:8K", credits: 100, note: "8K" }
|
|
830
|
+
{ identifier: "topaz-image-upscale", credits: 25, note: "1x / 2x" },
|
|
831
|
+
{ identifier: "topaz-image-upscale:4K", credits: 50, note: "4x (legacy identifier)" }
|
|
829
832
|
]
|
|
830
833
|
}
|
|
831
834
|
};
|
|
@@ -856,6 +859,7 @@ var VIDEO_MODELS = {
|
|
|
856
859
|
// docs.kie.ai/market/minimax-h3/{text,image,reference}-to-video.
|
|
857
860
|
"minimax-h3": {
|
|
858
861
|
id: "minimax-h3",
|
|
862
|
+
unlistedResolutionRendersAs: "2K",
|
|
859
863
|
kind: "video",
|
|
860
864
|
modes: ["i2v", "t2v"],
|
|
861
865
|
family: "MiniMax",
|
|
@@ -1341,6 +1345,7 @@ var VIDEO_MODELS = {
|
|
|
1341
1345
|
// declared explicitly in PRICING_DEFAULT_RESOLUTION, never by array position.
|
|
1342
1346
|
"wan-3": {
|
|
1343
1347
|
id: "wan-3",
|
|
1348
|
+
unlistedResolutionRendersAs: "720p",
|
|
1344
1349
|
kind: "video",
|
|
1345
1350
|
modes: ["i2v", "t2v"],
|
|
1346
1351
|
family: "Alibaba",
|
|
@@ -1365,6 +1370,7 @@ var VIDEO_MODELS = {
|
|
|
1365
1370
|
},
|
|
1366
1371
|
"wan-3-prime": {
|
|
1367
1372
|
id: "wan-3-prime",
|
|
1373
|
+
unlistedResolutionRendersAs: "720p",
|
|
1368
1374
|
kind: "video",
|
|
1369
1375
|
modes: ["i2v", "t2v"],
|
|
1370
1376
|
family: "Alibaba",
|
|
@@ -1533,6 +1539,76 @@ var VIDEO_MODELS = {
|
|
|
1533
1539
|
{ identifier: "wan-2.7-t2v", credits: 188, note: "5s 720p default" }
|
|
1534
1540
|
]
|
|
1535
1541
|
},
|
|
1542
|
+
// Lightricks LTX 2.3 (Replicate, not KIE). Both variants run one endpoint per
|
|
1543
|
+
// variant and switch behaviour with a `task` discriminator, so t2v and i2v are
|
|
1544
|
+
// the SAME id — no VIDEO_MODE_ALIASES row. `extend` / `retake` are separate
|
|
1545
|
+
// priced ops on the same model (ids below) but are NOT listed in `modes`:
|
|
1546
|
+
// they are driven by the Extend Video / Video Retake nodes' own pickers, and
|
|
1547
|
+
// adding the mode here would duplicate LTX in those menus.
|
|
1548
|
+
// Bands are lowercase to match LTX_DURATION_TIERS' keys in credit-identifiers.ts
|
|
1549
|
+
// and QUALITY_MAP in node-default-mappings.ts.
|
|
1550
|
+
"ltx-2.3-pro": {
|
|
1551
|
+
id: "ltx-2.3-pro",
|
|
1552
|
+
kind: "video",
|
|
1553
|
+
modes: ["i2v", "t2v"],
|
|
1554
|
+
family: "Lightricks",
|
|
1555
|
+
label: "LTX 2.3 Pro",
|
|
1556
|
+
series: "LTX",
|
|
1557
|
+
description: "Lightricks LTX 2.3 Pro \u2014 text/image/audio\u2192video up to 4K, 6/8/10s, end-frame interpolation.",
|
|
1558
|
+
useCases: ["premium", "high-res", "narrative"],
|
|
1559
|
+
features: ["end-frame"],
|
|
1560
|
+
aspectRatios: ["16:9", "9:16"],
|
|
1561
|
+
resolutions: ["1080p", "2k", "4k"],
|
|
1562
|
+
durations: [6, 8, 10],
|
|
1563
|
+
pricing: [
|
|
1564
|
+
{ identifier: "ltx-2.3-pro", credits: 240, note: "default 1080p 6s" },
|
|
1565
|
+
{ identifier: "ltx-2.3-pro:1080p:6s", credits: 240 },
|
|
1566
|
+
{ identifier: "ltx-2.3-pro:1080p:8s", credits: 320 },
|
|
1567
|
+
{ identifier: "ltx-2.3-pro:1080p:10s", credits: 400 },
|
|
1568
|
+
{ identifier: "ltx-2.3-pro:2k:6s", credits: 480 },
|
|
1569
|
+
{ identifier: "ltx-2.3-pro:2k:8s", credits: 640 },
|
|
1570
|
+
{ identifier: "ltx-2.3-pro:2k:10s", credits: 800 },
|
|
1571
|
+
{ identifier: "ltx-2.3-pro:4k:6s", credits: 960 },
|
|
1572
|
+
{ identifier: "ltx-2.3-pro:4k:8s", credits: 1280 },
|
|
1573
|
+
{ identifier: "ltx-2.3-pro:4k:10s", credits: 1600 },
|
|
1574
|
+
{ identifier: "ltx-2.3-pro-extend:per-second", credits: 40, note: "extend, per second of new footage" },
|
|
1575
|
+
{ identifier: "ltx-2.3-pro-retake:per-second", credits: 40, note: "retake, per second re-rendered" }
|
|
1576
|
+
]
|
|
1577
|
+
},
|
|
1578
|
+
"ltx-2.3-fast": {
|
|
1579
|
+
id: "ltx-2.3-fast",
|
|
1580
|
+
kind: "video",
|
|
1581
|
+
modes: ["i2v", "t2v"],
|
|
1582
|
+
family: "Lightricks",
|
|
1583
|
+
label: "LTX 2.3 Fast",
|
|
1584
|
+
series: "LTX",
|
|
1585
|
+
description: "Lightricks LTX 2.3 Fast \u2014 text/image\u2192video up to 20s at 1080p (6/8/10s at 2K and 4K). No audio input, no extend.",
|
|
1586
|
+
useCases: ["long-form", "fast", "narrative"],
|
|
1587
|
+
features: ["end-frame"],
|
|
1588
|
+
aspectRatios: ["16:9", "9:16"],
|
|
1589
|
+
resolutions: ["1080p", "2k", "4k"],
|
|
1590
|
+
// Flat union across bands — 12–20s exist only at 1080p (LTX_DURATION_TIERS
|
|
1591
|
+
// in credit-identifiers.ts is the per-band authority and snaps a 2k/4k
|
|
1592
|
+
// request back onto 6/8/10s, so the reservation is always a real tier).
|
|
1593
|
+
durations: [6, 8, 10, 12, 14, 16, 18, 20],
|
|
1594
|
+
pricing: [
|
|
1595
|
+
{ identifier: "ltx-2.3-fast", credits: 180, note: "default 1080p 6s" },
|
|
1596
|
+
{ identifier: "ltx-2.3-fast:1080p:6s", credits: 180 },
|
|
1597
|
+
{ identifier: "ltx-2.3-fast:1080p:8s", credits: 240 },
|
|
1598
|
+
{ identifier: "ltx-2.3-fast:1080p:10s", credits: 300 },
|
|
1599
|
+
{ identifier: "ltx-2.3-fast:1080p:12s", credits: 360 },
|
|
1600
|
+
{ identifier: "ltx-2.3-fast:1080p:14s", credits: 420 },
|
|
1601
|
+
{ identifier: "ltx-2.3-fast:1080p:16s", credits: 480 },
|
|
1602
|
+
{ identifier: "ltx-2.3-fast:1080p:18s", credits: 540 },
|
|
1603
|
+
{ identifier: "ltx-2.3-fast:1080p:20s", credits: 600 },
|
|
1604
|
+
{ identifier: "ltx-2.3-fast:2k:6s", credits: 360 },
|
|
1605
|
+
{ identifier: "ltx-2.3-fast:2k:8s", credits: 480 },
|
|
1606
|
+
{ identifier: "ltx-2.3-fast:2k:10s", credits: 600 },
|
|
1607
|
+
{ identifier: "ltx-2.3-fast:4k:6s", credits: 720 },
|
|
1608
|
+
{ identifier: "ltx-2.3-fast:4k:8s", credits: 960 },
|
|
1609
|
+
{ identifier: "ltx-2.3-fast:4k:10s", credits: 1200 }
|
|
1610
|
+
]
|
|
1611
|
+
},
|
|
1536
1612
|
// ── HappyHorse (1.1 — ids kept version-less; repointed in place when KIE
|
|
1537
1613
|
// delisted 1.0, same param surface, so saved workflows keep working) ──
|
|
1538
1614
|
"happyhorse": {
|
|
@@ -2384,6 +2460,105 @@ function normalizeModelInput(modelId, input) {
|
|
|
2384
2460
|
}
|
|
2385
2461
|
return out;
|
|
2386
2462
|
}
|
|
2463
|
+
var PASSTHROUGH_ASPECT_TOKENS = /* @__PURE__ */ new Set(["auto", "adaptive"]);
|
|
2464
|
+
var RESOLUTION_BAND_PIXELS = {
|
|
2465
|
+
"2k": 1440,
|
|
2466
|
+
"4k": 2160,
|
|
2467
|
+
"8k": 4320
|
|
2468
|
+
};
|
|
2469
|
+
function bandPixels(token) {
|
|
2470
|
+
const t2 = token.trim().toLowerCase();
|
|
2471
|
+
if (RESOLUTION_BAND_PIXELS[t2] !== void 0) return RESOLUTION_BAND_PIXELS[t2];
|
|
2472
|
+
const m = /^(\d+)p$/.exec(t2);
|
|
2473
|
+
return m ? Number(m[1]) : void 0;
|
|
2474
|
+
}
|
|
2475
|
+
function nearestResolutionBand(token, allowed) {
|
|
2476
|
+
let highest = allowed[allowed.length - 1];
|
|
2477
|
+
let highestPx = -Infinity;
|
|
2478
|
+
for (const a of allowed) {
|
|
2479
|
+
const px = bandPixels(a);
|
|
2480
|
+
if (px !== void 0 && px > highestPx) {
|
|
2481
|
+
highestPx = px;
|
|
2482
|
+
highest = a;
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
const want = bandPixels(token);
|
|
2486
|
+
if (want === void 0) return highest;
|
|
2487
|
+
let best = highest;
|
|
2488
|
+
let bestDist = Infinity;
|
|
2489
|
+
for (const a of allowed) {
|
|
2490
|
+
const px = bandPixels(a);
|
|
2491
|
+
if (px === void 0) continue;
|
|
2492
|
+
const d = Math.abs(px - want);
|
|
2493
|
+
if (d < bestDist) {
|
|
2494
|
+
bestDist = d;
|
|
2495
|
+
best = a;
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
return best;
|
|
2499
|
+
}
|
|
2500
|
+
function nearestAspectRatio(token, allowed) {
|
|
2501
|
+
const [w, h] = token.split(":").map(Number);
|
|
2502
|
+
if (!w || !h) return void 0;
|
|
2503
|
+
const target = Math.log(w / h);
|
|
2504
|
+
let best;
|
|
2505
|
+
let bestDist = Infinity;
|
|
2506
|
+
for (const c of allowed) {
|
|
2507
|
+
const [cw, ch] = c.split(":").map(Number);
|
|
2508
|
+
if (!cw || !ch) continue;
|
|
2509
|
+
const d = Math.abs(Math.log(cw / ch) - target);
|
|
2510
|
+
if (d < bestDist) {
|
|
2511
|
+
bestDist = d;
|
|
2512
|
+
best = c;
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
return best;
|
|
2516
|
+
}
|
|
2517
|
+
function readOptionToken(value) {
|
|
2518
|
+
if (value === void 0 || value === null) return void 0;
|
|
2519
|
+
const s = (typeof value === "string" ? value : String(value)).trim();
|
|
2520
|
+
return s === "" ? void 0 : s;
|
|
2521
|
+
}
|
|
2522
|
+
function normalizeVideoRequestParams(modelId, input) {
|
|
2523
|
+
const m = MODEL_CATALOG[modelId];
|
|
2524
|
+
const aspect = readOptionToken(input.aspectRatio);
|
|
2525
|
+
const res = readOptionToken(input.resolution);
|
|
2526
|
+
const out = { aspectRatio: aspect, resolution: res, adjustments: [] };
|
|
2527
|
+
if (!m) return out;
|
|
2528
|
+
if (m.aspectRatios?.length && aspect && !PASSTHROUGH_ASPECT_TOKENS.has(aspect.toLowerCase())) {
|
|
2529
|
+
const allowed = m.aspectRatios;
|
|
2530
|
+
const exact = allowed.find((a) => a === aspect) ?? allowed.find((a) => a.toLowerCase() === aspect.toLowerCase());
|
|
2531
|
+
if (exact !== void 0) {
|
|
2532
|
+
out.aspectRatio = exact;
|
|
2533
|
+
} else {
|
|
2534
|
+
const next = nearestAspectRatio(aspect, allowed.filter((a) => !PASSTHROUGH_ASPECT_TOKENS.has(a.toLowerCase()))) ?? allowed[0];
|
|
2535
|
+
out.adjustments.push({
|
|
2536
|
+
field: "aspectRatio",
|
|
2537
|
+
from: aspect,
|
|
2538
|
+
to: next,
|
|
2539
|
+
reason: `${m.label} does not support aspect ratio "${aspect}" \u2014 using "${next}" instead. Supported: ${allowed.join(", ")}.`
|
|
2540
|
+
});
|
|
2541
|
+
out.aspectRatio = next;
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
if (m.resolutions?.length && res) {
|
|
2545
|
+
const allowed = m.resolutions;
|
|
2546
|
+
const exact = allowed.find((a) => a === res) ?? allowed.find((a) => a.toLowerCase() === res.toLowerCase());
|
|
2547
|
+
if (exact !== void 0) {
|
|
2548
|
+
out.resolution = exact;
|
|
2549
|
+
} else {
|
|
2550
|
+
const next = m.unlistedResolutionRendersAs ?? nearestResolutionBand(res, allowed);
|
|
2551
|
+
out.adjustments.push({
|
|
2552
|
+
field: "resolution",
|
|
2553
|
+
from: res,
|
|
2554
|
+
to: next,
|
|
2555
|
+
reason: `${m.label} does not support resolution "${res}" \u2014 using "${next}" instead. Supported: ${allowed.join(", ")}.`
|
|
2556
|
+
});
|
|
2557
|
+
out.resolution = next;
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
return out;
|
|
2561
|
+
}
|
|
2387
2562
|
var MODEL_VALUE_LABELS = {
|
|
2388
2563
|
// aspect ratios
|
|
2389
2564
|
"1:1": "1:1 (Square)",
|
|
@@ -2398,6 +2573,7 @@ var MODEL_VALUE_LABELS = {
|
|
|
2398
2573
|
"2K": "2K (High)",
|
|
2399
2574
|
"4K": "4K (Ultra)",
|
|
2400
2575
|
"4k": "4K",
|
|
2576
|
+
"2k": "2K",
|
|
2401
2577
|
"8K": "8K (Ultra)",
|
|
2402
2578
|
// qualities
|
|
2403
2579
|
"medium": "Medium (Balanced)",
|
|
@@ -3583,6 +3759,39 @@ var VIDEO_REF_LIMITS_BY_PROVIDER = {
|
|
|
3583
3759
|
// the user's references (the grok-imagine-video-1.5 bug). Add only with a
|
|
3584
3760
|
// verified provider path + the catalog `reference-image` feature.
|
|
3585
3761
|
};
|
|
3762
|
+
var VIDEO_REF_VIDEO_DURATION_LIMITS = {
|
|
3763
|
+
"seedance-2-5": { minSec: 2, maxSec: 30, maxTotalSec: 30 },
|
|
3764
|
+
// MiniMax Hailuo 3 — the provider states the per-clip bound in its own reject
|
|
3765
|
+
// text: "content[1].video_url: invalid param: video duration 52838 ms,
|
|
3766
|
+
// expected [2000, 15000] ms" (app-reports P4, 2 rows, the same clip retried).
|
|
3767
|
+
// The KIE reference-to-video doc adds the COMBINED cap — the same shape the
|
|
3768
|
+
// audio side already declares in SEEDANCE_2_R2V_MAX_AUDIO_SEC_BY_PROVIDER
|
|
3769
|
+
// above, whose h3 row cites the same page.
|
|
3770
|
+
"minimax-h3": { minSec: 2, maxSec: 15, maxTotalSec: 15 }
|
|
3771
|
+
};
|
|
3772
|
+
function checkRefVideoDurations(provider, durationsSec) {
|
|
3773
|
+
const limit = VIDEO_REF_VIDEO_DURATION_LIMITS[provider];
|
|
3774
|
+
if (!limit) return { ok: true };
|
|
3775
|
+
const usable = durationsSec.filter((d) => Number.isFinite(d) && d > 0);
|
|
3776
|
+
if (usable.length === 0) return { ok: true };
|
|
3777
|
+
const offender = usable.find((d) => d < limit.minSec || d > limit.maxSec);
|
|
3778
|
+
if (offender !== void 0) {
|
|
3779
|
+
return {
|
|
3780
|
+
ok: false,
|
|
3781
|
+
message: `Each reference video must be between ${limit.minSec} and ${limit.maxSec} seconds \u2014 one is ${offender.toFixed(1)}s. Trim it (a Trim Video node upstream works) and run again.`
|
|
3782
|
+
};
|
|
3783
|
+
}
|
|
3784
|
+
if (limit.maxTotalSec !== void 0) {
|
|
3785
|
+
const total = usable.reduce((a, b) => a + b, 0);
|
|
3786
|
+
if (total > limit.maxTotalSec) {
|
|
3787
|
+
return {
|
|
3788
|
+
ok: false,
|
|
3789
|
+
message: `Reference videos must not exceed ${limit.maxTotalSec} seconds in total \u2014 these add up to ${total.toFixed(1)}s. Remove one or trim them and run again.`
|
|
3790
|
+
};
|
|
3791
|
+
}
|
|
3792
|
+
}
|
|
3793
|
+
return { ok: true };
|
|
3794
|
+
}
|
|
3586
3795
|
var RESOLUTION_VIDEO_REF_PRICING = SEEDANCE_2_PROVIDERS;
|
|
3587
3796
|
var RESOLUTION_DURATION_PRICING = {
|
|
3588
3797
|
// KIE supports only 480p/720p here; 480p is the default.
|
|
@@ -3676,10 +3885,39 @@ var VIDEO_AUDIO_CAPABILITY = {
|
|
|
3676
3885
|
// and skip the lip-sync pass. `defaultOn` mirrors the KIE default so an
|
|
3677
3886
|
// intent-less request is described honestly; audio is priced into the uniform
|
|
3678
3887
|
// per-second rate, so NOT cost-affecting (no `:audio` composite).
|
|
3679
|
-
// gemini-omni-flash is deliberately ABSENT — gemini-omni-video is absent too
|
|
3680
|
-
// (mode "none"), and the siblings must not disagree.
|
|
3681
3888
|
"wan-3": { mode: "ambient", field: "audio", defaultOn: true },
|
|
3682
|
-
"wan-3-prime": { mode: "ambient", field: "audio", defaultOn: true }
|
|
3889
|
+
"wan-3-prime": { mode: "ambient", field: "audio", defaultOn: true },
|
|
3890
|
+
// Gemini Omni (both SKUs — the pro `gemini-omni-video` and the faster
|
|
3891
|
+
// `gemini-omni-flash`; one model at two speeds, so their rows are identical
|
|
3892
|
+
// and a test pins that). Settled 2026-09-03 from Google's own documentation
|
|
3893
|
+
// at https://ai.google.dev/gemini-api/docs/omni, having been unlisted — and
|
|
3894
|
+
// therefore reported as SILENT — while the catalog described both as "native
|
|
3895
|
+
// audio".
|
|
3896
|
+
//
|
|
3897
|
+
// "ambient", and alwaysOn with no toggle field, on three sentences from that
|
|
3898
|
+
// page:
|
|
3899
|
+
// - "By default the model will try to generate an appropriate audio track
|
|
3900
|
+
// for a video." Audio on every render, and the KIE input schema
|
|
3901
|
+
// (prompt / image_urls / first+last_frame_url / audio_ids / video_list /
|
|
3902
|
+
// character_ids / duration / aspect_ratio / seed / resolution — see
|
|
3903
|
+
// docs.kie.ai/market/gemini-omni-video and
|
|
3904
|
+
// docs.kie.ai/market/google/gemini-omni-flash-1-1) carries no on/off
|
|
3905
|
+
// lever, so there is nothing for applyVideoAudioToggle to write.
|
|
3906
|
+
// - NOT native_speech: "Multi-turn voice extension: Generating spoken
|
|
3907
|
+
// dialogue or speech is supported when extending previously generated
|
|
3908
|
+
// videos via multi-turn (`previous_interaction_id`)" — a field KIE's
|
|
3909
|
+
// createTask schema does not expose, so the dialogue path is unreachable
|
|
3910
|
+
// on our transport. Held to the Wan 3.0 bar: no documented dialogue
|
|
3911
|
+
// guarantee on the path we actually drive ⇒ ambient, and upgrade only on
|
|
3912
|
+
// a live probe (the kling-3.0 standard). Classifying it native_speech
|
|
3913
|
+
// would reroute the Story→Video dialogue pipeline past the lip-sync pass.
|
|
3914
|
+
// - NOT audio_driven either: "Uploading audio references is unsupported in
|
|
3915
|
+
// the current version of the API", and "any audio in a video reference is
|
|
3916
|
+
// ignored" — there is no reference-audio transport to be driven by, and
|
|
3917
|
+
// runGeminiOmni never sends `audio_ids`.
|
|
3918
|
+
// Audio is priced into the per-tier rate, so NOT cost-affecting.
|
|
3919
|
+
"gemini-omni-video": { mode: "ambient", alwaysOn: true },
|
|
3920
|
+
"gemini-omni-flash": { mode: "ambient", alwaysOn: true }
|
|
3683
3921
|
};
|
|
3684
3922
|
var VIDEO_AUDIO_NONE = { mode: "none" };
|
|
3685
3923
|
function getVideoAudioCapability(model) {
|
|
@@ -4487,6 +4725,16 @@ var LTX_DURATION_TIERS = {
|
|
|
4487
4725
|
"ltx-2.3-pro": { "1080p": [6, 8, 10], "2k": [6, 8, 10], "4k": [6, 8, 10] },
|
|
4488
4726
|
"ltx-2.3-fast": { "1080p": [6, 8, 10, 12, 14, 16, 18, 20], "2k": [6, 8, 10], "4k": [6, 8, 10] }
|
|
4489
4727
|
};
|
|
4728
|
+
function ltxPricedTier(provider, resolution, duration) {
|
|
4729
|
+
const bands = LTX_DURATION_TIERS[provider];
|
|
4730
|
+
if (!bands) return void 0;
|
|
4731
|
+
const band2 = bands[String(resolution)] ? String(resolution) : "1080p";
|
|
4732
|
+
const allowed = bands[band2];
|
|
4733
|
+
const raw = typeof duration === "string" ? parseInt(duration, 10) : duration ?? allowed[0];
|
|
4734
|
+
const want = Number.isNaN(raw) ? allowed[0] : raw;
|
|
4735
|
+
const dur = allowed.reduce((b, a) => Math.abs(a - want) < Math.abs(b - want) ? a : b);
|
|
4736
|
+
return { band: band2, duration: dur };
|
|
4737
|
+
}
|
|
4490
4738
|
function buildVideoCreditModelIdentifier(provider, duration, sound, nodeType, mode, resolution, hasVideoRef) {
|
|
4491
4739
|
let effectiveProvider = provider;
|
|
4492
4740
|
if (nodeType === "text-to-video") {
|
|
@@ -4512,14 +4760,9 @@ function buildVideoCreditModelIdentifier(provider, duration, sound, nodeType, mo
|
|
|
4512
4760
|
const d = Number.isNaN(raw) ? 8 : GEMINI_OMNI_DURATIONS.reduce((b, a) => Math.abs(a - raw) < Math.abs(b - raw) ? a : b);
|
|
4513
4761
|
return resolution === "4k" ? `${effectiveProvider}:4k:${d}` : `${effectiveProvider}:${d}`;
|
|
4514
4762
|
}
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
const allowed = bands[band2];
|
|
4519
|
-
const raw = typeof duration === "string" ? parseInt(duration, 10) : duration ?? allowed[0];
|
|
4520
|
-
const want = Number.isNaN(raw) ? allowed[0] : raw;
|
|
4521
|
-
const dur = allowed.reduce((b, a) => Math.abs(a - want) < Math.abs(b - want) ? a : b);
|
|
4522
|
-
return `${effectiveProvider}:${band2}:${dur}s`;
|
|
4763
|
+
const ltxTier = ltxPricedTier(effectiveProvider, resolution, duration);
|
|
4764
|
+
if (ltxTier) {
|
|
4765
|
+
return `${effectiveProvider}:${ltxTier.band}:${ltxTier.duration}s`;
|
|
4523
4766
|
}
|
|
4524
4767
|
if (!DURATION_PRICED_PROVIDERS.has(effectiveProvider)) {
|
|
4525
4768
|
return effectiveProvider;
|
|
@@ -4559,6 +4802,22 @@ function buildVideoCreditModelIdentifier(provider, duration, sound, nodeType, mo
|
|
|
4559
4802
|
}
|
|
4560
4803
|
return identifier;
|
|
4561
4804
|
}
|
|
4805
|
+
function pricedVideoSelection(opts) {
|
|
4806
|
+
const adjustments = [];
|
|
4807
|
+
const ltx = ltxPricedTier(opts.provider, opts.resolution, opts.duration);
|
|
4808
|
+
const resolution = opts.resolution ?? (ltx ? ltx.band : PRICING_DEFAULT_RESOLUTION[opts.provider]);
|
|
4809
|
+
if (!ltx) return { resolution, adjustments };
|
|
4810
|
+
const requested = typeof opts.duration === "string" ? parseInt(opts.duration, 10) : opts.duration;
|
|
4811
|
+
if (requested !== void 0 && !Number.isNaN(requested) && requested !== ltx.duration) {
|
|
4812
|
+
adjustments.push({
|
|
4813
|
+
field: "duration",
|
|
4814
|
+
from: requested,
|
|
4815
|
+
to: ltx.duration,
|
|
4816
|
+
reason: `LTX renders ${ltx.band} in ${ltx.duration}s steps \u2014 using ${ltx.duration}s instead of ${requested}s.`
|
|
4817
|
+
});
|
|
4818
|
+
}
|
|
4819
|
+
return { resolution, duration: ltx.duration, adjustments };
|
|
4820
|
+
}
|
|
4562
4821
|
function buildMotionCreditModelIdentifier(provider, resolution, videoDuration) {
|
|
4563
4822
|
if (provider === "wan-animate-move" || provider === "wan-animate-replace") {
|
|
4564
4823
|
if (resolution === "580p" || resolution === "720p") {
|
|
@@ -4684,6 +4943,71 @@ function extractVideoDurationFromNode(data) {
|
|
|
4684
4943
|
return void 0;
|
|
4685
4944
|
}
|
|
4686
4945
|
|
|
4946
|
+
// src/topaz-upscale.ts
|
|
4947
|
+
var TOPAZ_UPSCALE_FACTORS = ["1", "2", "4"];
|
|
4948
|
+
var TOPAZ_DEFAULT_UPSCALE_FACTOR = "2";
|
|
4949
|
+
var LEGACY_TIER_TO_FACTOR = {
|
|
4950
|
+
"2K": "2",
|
|
4951
|
+
"4K": "4",
|
|
4952
|
+
"8K": "4"
|
|
4953
|
+
};
|
|
4954
|
+
function isFactor(v) {
|
|
4955
|
+
return TOPAZ_UPSCALE_FACTORS.includes(v);
|
|
4956
|
+
}
|
|
4957
|
+
function resolveTopazUpscale(input) {
|
|
4958
|
+
const adjustments = [];
|
|
4959
|
+
const rawFactor = typeof input.upscaleFactor === "string" ? input.upscaleFactor : "";
|
|
4960
|
+
const rawTier = typeof input.targetResolution === "string" ? input.targetResolution : "";
|
|
4961
|
+
const trimmedFactor = rawFactor.trim();
|
|
4962
|
+
const normalizedTier = rawTier.trim().toUpperCase();
|
|
4963
|
+
const factorGiven = trimmedFactor.length > 0;
|
|
4964
|
+
const factorValid = factorGiven && isFactor(trimmedFactor);
|
|
4965
|
+
const tierGiven = normalizedTier.length > 0;
|
|
4966
|
+
const tierMappedFactor = tierGiven ? LEGACY_TIER_TO_FACTOR[normalizedTier] : void 0;
|
|
4967
|
+
const finalFactor = factorValid ? trimmedFactor : tierMappedFactor ?? TOPAZ_DEFAULT_UPSCALE_FACTOR;
|
|
4968
|
+
if (factorGiven && !factorValid) {
|
|
4969
|
+
adjustments.push({
|
|
4970
|
+
field: "upscaleFactor",
|
|
4971
|
+
from: rawFactor,
|
|
4972
|
+
to: finalFactor,
|
|
4973
|
+
reason: `Topaz upscale accepts a factor of 1, 2 or 4 \u2014 "${rawFactor}" was replaced with ${finalFactor}.`
|
|
4974
|
+
});
|
|
4975
|
+
}
|
|
4976
|
+
if (factorValid && tierGiven) {
|
|
4977
|
+
if (tierMappedFactor !== finalFactor) {
|
|
4978
|
+
adjustments.push({
|
|
4979
|
+
field: "targetResolution",
|
|
4980
|
+
from: rawTier,
|
|
4981
|
+
to: void 0,
|
|
4982
|
+
reason: "upscaleFactor takes precedence over the legacy targetResolution."
|
|
4983
|
+
});
|
|
4984
|
+
}
|
|
4985
|
+
} else if (!factorValid && tierGiven) {
|
|
4986
|
+
if (tierMappedFactor) {
|
|
4987
|
+
if (normalizedTier === "8K") {
|
|
4988
|
+
adjustments.push({
|
|
4989
|
+
field: "targetResolution",
|
|
4990
|
+
from: rawTier,
|
|
4991
|
+
to: finalFactor,
|
|
4992
|
+
reason: "Topaz upscale offers factors up to 4x \u2014 an 8K target renders and bills at the 4x tier."
|
|
4993
|
+
});
|
|
4994
|
+
}
|
|
4995
|
+
} else {
|
|
4996
|
+
adjustments.push({
|
|
4997
|
+
field: "targetResolution",
|
|
4998
|
+
from: rawTier,
|
|
4999
|
+
to: finalFactor,
|
|
5000
|
+
reason: `Unknown Topaz target "${rawTier}" \u2014 rendering at ${finalFactor}x.`
|
|
5001
|
+
});
|
|
5002
|
+
}
|
|
5003
|
+
}
|
|
5004
|
+
return {
|
|
5005
|
+
upscaleFactor: finalFactor,
|
|
5006
|
+
creditTier: finalFactor === "4" ? "4K" : void 0,
|
|
5007
|
+
adjustments
|
|
5008
|
+
};
|
|
5009
|
+
}
|
|
5010
|
+
|
|
4687
5011
|
// src/presentation-utils.ts
|
|
4688
5012
|
var INPUT_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
4689
5013
|
"text-prompt",
|
|
@@ -6456,6 +6780,35 @@ function resolveNodeRefs(text, labelToOutput) {
|
|
|
6456
6780
|
}
|
|
6457
6781
|
return result;
|
|
6458
6782
|
}
|
|
6783
|
+
var REF_TOKEN_NAMESPACE_PREFIXES = [
|
|
6784
|
+
"image:",
|
|
6785
|
+
"video:",
|
|
6786
|
+
"audio:",
|
|
6787
|
+
"slot:",
|
|
6788
|
+
"ref:"
|
|
6789
|
+
];
|
|
6790
|
+
function classifyRefToken(name, resolvable) {
|
|
6791
|
+
const lower = name.toLowerCase();
|
|
6792
|
+
if (name === "" || REF_TOKEN_NAMESPACE_PREFIXES.some((p) => lower.startsWith(p))) return "skip";
|
|
6793
|
+
if (RESERVED_TEMPLATE_VARS.has(name)) return "reserved";
|
|
6794
|
+
if (resolvable === null) return "unknown";
|
|
6795
|
+
return resolvable.has(canonicalVarName(name)) ? "wired" : "missing";
|
|
6796
|
+
}
|
|
6797
|
+
function unresolvedRefTokens(text, opts) {
|
|
6798
|
+
if (typeof text !== "string" || text.length === 0) return [];
|
|
6799
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6800
|
+
const out = [];
|
|
6801
|
+
for (const m of text.matchAll(NODE_REF_PATTERN)) {
|
|
6802
|
+
const { name, fallback } = parseNodeRef(m[1] ?? "");
|
|
6803
|
+
if (fallback !== null) continue;
|
|
6804
|
+
if (classifyRefToken(name, opts.resolvable) !== "missing") continue;
|
|
6805
|
+
const canon = canonicalVarName(name);
|
|
6806
|
+
if (opts.known.has(canon) || seen.has(canon)) continue;
|
|
6807
|
+
seen.add(canon);
|
|
6808
|
+
out.push(name);
|
|
6809
|
+
}
|
|
6810
|
+
return out;
|
|
6811
|
+
}
|
|
6459
6812
|
|
|
6460
6813
|
// src/filter-condition.ts
|
|
6461
6814
|
function tryParseJson(item) {
|
|
@@ -9642,6 +9995,18 @@ function togglePick(current, id, maxSelected) {
|
|
|
9642
9995
|
return [...current.slice(1), id];
|
|
9643
9996
|
}
|
|
9644
9997
|
|
|
9998
|
+
// src/safety-retry-policy.ts
|
|
9999
|
+
function safetyRetryPolicy(modelId) {
|
|
10000
|
+
const entry = getModel(modelId);
|
|
10001
|
+
const safetyFilter = entry?.safetyFilter;
|
|
10002
|
+
if (!safetyFilter?.stochastic) return { maxAttempts: 1 };
|
|
10003
|
+
const fallback = safetyFilter.fallback;
|
|
10004
|
+
if (fallback && getModel(fallback)) {
|
|
10005
|
+
return { maxAttempts: 2, fallback };
|
|
10006
|
+
}
|
|
10007
|
+
return { maxAttempts: 2 };
|
|
10008
|
+
}
|
|
10009
|
+
|
|
9645
10010
|
// src/caption-styles.ts
|
|
9646
10011
|
var STATIC_CAPTION_STYLES = ["subtitle"];
|
|
9647
10012
|
var KINETIC_CAPTION_STYLES = [
|
|
@@ -9782,6 +10147,18 @@ var EXECUTION_DATA_KEYS = /* @__PURE__ */ new Set([
|
|
|
9782
10147
|
"currentJobId",
|
|
9783
10148
|
"currentJobProgress",
|
|
9784
10149
|
"errorMessage",
|
|
10150
|
+
// Structured detail alongside errorMessage for a safety-filter block
|
|
10151
|
+
// (see `JobErrorHint` in the app's frontend/src/types/nodes.ts). Same
|
|
10152
|
+
// lifecycle as errorMessage: a RESULT the user expects to survive reload,
|
|
10153
|
+
// never user-edited config.
|
|
10154
|
+
"errorHint",
|
|
10155
|
+
// A job policy registered by the deployment held this node's result for a
|
|
10156
|
+
// human reviewer (`jobs.status = "pending_review"`). Pure run state, like
|
|
10157
|
+
// executionStatus: the node is still "running" and the flag disappears the
|
|
10158
|
+
// moment the review resolves — so it is ALSO in TRANSIENT_RUNTIME_KEYS
|
|
10159
|
+
// below. Without the transient half, a flip into review marks a passive tab
|
|
10160
|
+
// dirty and a preset captures "awaiting review".
|
|
10161
|
+
"jobAwaitingReview",
|
|
9785
10162
|
"isStreaming",
|
|
9786
10163
|
"generatedImageUrl",
|
|
9787
10164
|
"generatedVideoUrl",
|
|
@@ -9829,6 +10206,7 @@ var TRANSIENT_RUNTIME_KEYS = /* @__PURE__ */ new Set([
|
|
|
9829
10206
|
"executionStatus",
|
|
9830
10207
|
"currentJobId",
|
|
9831
10208
|
"currentJobProgress",
|
|
10209
|
+
"jobAwaitingReview",
|
|
9832
10210
|
"isStreaming",
|
|
9833
10211
|
"subWorkflowProgress",
|
|
9834
10212
|
"__listTotal",
|
|
@@ -13519,6 +13897,26 @@ var clipLookSchema = zod.z.object({
|
|
|
13519
13897
|
* insert) states the deviation in that scene's `visual`, as with `lighting`.
|
|
13520
13898
|
*/
|
|
13521
13899
|
style: zod.z.string().optional(),
|
|
13900
|
+
/**
|
|
13901
|
+
* The Style picker CATALOG ID the prose in `style` corresponds to — the
|
|
13902
|
+
* analyzer's PICK ("pixar-3d" beside "3D stylized animation"), not a second
|
|
13903
|
+
* description of it.
|
|
13904
|
+
*
|
|
13905
|
+
* Worth strictly more than the prose it accompanies: an id addresses the
|
|
13906
|
+
* catalog, so a recreation renders the same medium the product's own Style
|
|
13907
|
+
* picker would render, instead of re-interpreting a sentence. Absent when the
|
|
13908
|
+
* analyzer read a medium it could not place in the catalog — `style` then
|
|
13909
|
+
* carries the whole answer, as it always did.
|
|
13910
|
+
*
|
|
13911
|
+
* A free `string` here on purpose. The PRODUCER validates it against the
|
|
13912
|
+
* catalog (the analyzer plugin's wire schema is an enum generated from
|
|
13913
|
+
* `STYLES`, so an invented id never leaves it), while this package must not
|
|
13914
|
+
* carry the catalog itself. A closed enum here would only add a second copy
|
|
13915
|
+
* of the vocabulary to drift out of date — and, worse, would REJECT a
|
|
13916
|
+
* catalog entry newer than the installed `@nodaro/shared`, which is exactly
|
|
13917
|
+
* the analysis a consumer most wants to read.
|
|
13918
|
+
*/
|
|
13919
|
+
styleId: zod.z.string().optional(),
|
|
13522
13920
|
/** Colour grade / palette — "muted teal-and-orange, crushed blacks". */
|
|
13523
13921
|
grade: zod.z.string().optional(),
|
|
13524
13922
|
/** Camera or film FORMAT and stock — "anamorphic digital", "16mm film grain". */
|
|
@@ -13589,8 +13987,9 @@ var entitySlotSchema = zod.z.object({
|
|
|
13589
13987
|
/** NON-default looks only; present only when at least one exists. */
|
|
13590
13988
|
variations: zod.z.array(slotVariationSchema).max(VIDEO_ANALYSIS_MAX_VARIATIONS).optional()
|
|
13591
13989
|
});
|
|
13990
|
+
var VIDEO_ANALYSIS_AUDIO_MODES = ["speech", "music", "sfx", "ambience"];
|
|
13592
13991
|
var audioLayerSchema = zod.z.object({
|
|
13593
|
-
mode: zod.z.enum(
|
|
13992
|
+
mode: zod.z.enum(VIDEO_ANALYSIS_AUDIO_MODES),
|
|
13594
13993
|
content: zod.z.string().min(1),
|
|
13595
13994
|
voice: zod.z.string().optional(),
|
|
13596
13995
|
/**
|
|
@@ -13613,7 +14012,34 @@ var audioLayerSchema = zod.z.object({
|
|
|
13613
14012
|
* (doctrine §5), so attribution here would resurrect the phantom-entity
|
|
13614
14013
|
* defect that `stripOrphanSlots` exists to kill.
|
|
13615
14014
|
*/
|
|
13616
|
-
speakerSlot: zod.z.string().optional()
|
|
14015
|
+
speakerSlot: zod.z.string().optional(),
|
|
14016
|
+
/**
|
|
14017
|
+
* SPEECH ONLY — WHO says these words, by NAME.
|
|
14018
|
+
*
|
|
14019
|
+
* The second of two ways to name a speaker, and the one for documents that
|
|
14020
|
+
* have no slots: `speakerSlot` addresses an `EntitySlot` of THIS analysis by
|
|
14021
|
+
* id, while `speaker` is the plain cast name a production keys its own cast
|
|
14022
|
+
* by ("Jack Mercer"). A layer may legitimately carry both — the id for the
|
|
14023
|
+
* analysis it came from, the name for the document it is going into — and a
|
|
14024
|
+
* consumer that understands only one reads the one it understands.
|
|
14025
|
+
*
|
|
14026
|
+
* Optional, and not refined against `mode`, for the same reason
|
|
14027
|
+
* `speakerSlot` is not: the window schema is the enforced decode grammar and
|
|
14028
|
+
* must not throw away a whole roll over one mis-tagged field.
|
|
14029
|
+
*
|
|
14030
|
+
* NOT swept by `dropUnknownSpeakers`. That function is the SLOT channel's
|
|
14031
|
+
* sanitizer — it judges an id against the surviving slot list, and a name has
|
|
14032
|
+
* no id space to be unknown in. The asymmetry is deliberate and pinned by
|
|
14033
|
+
* test; whoever owns the name's vocabulary sanitizes the name.
|
|
14034
|
+
*
|
|
14035
|
+
* The residual that leaves: a layer can keep a `speaker` naming someone
|
|
14036
|
+
* `stripOrphanSlots` already pruned as a phantom, where the same claim spelled
|
|
14037
|
+
* `speakerSlot` would have been dropped — the invented-narrator defect, in the
|
|
14038
|
+
* one spelling the sweep cannot see. LATENT today, since nothing in this
|
|
14039
|
+
* repo emits `speaker`; the day the analyzer does, that sweep is what has to
|
|
14040
|
+
* grow, not this field.
|
|
14041
|
+
*/
|
|
14042
|
+
speaker: zod.z.string().optional()
|
|
13617
14043
|
});
|
|
13618
14044
|
var windowSceneBase = zod.z.object({
|
|
13619
14045
|
startSec: zod.z.number().min(0),
|
|
@@ -14453,6 +14879,7 @@ exports.REFERENCE_HANDLE_MAP = REFERENCE_HANDLE_MAP;
|
|
|
14453
14879
|
exports.REFERENCE_ROLE_PRESETS = REFERENCE_ROLE_PRESETS;
|
|
14454
14880
|
exports.REF_HANDLE_CATEGORY = REF_HANDLE_CATEGORY;
|
|
14455
14881
|
exports.REF_IMAGE_MAX_LIMITS = REF_IMAGE_MAX_LIMITS;
|
|
14882
|
+
exports.REF_TOKEN_NAMESPACE_PREFIXES = REF_TOKEN_NAMESPACE_PREFIXES;
|
|
14456
14883
|
exports.RENDERING_SPEED_SUPPORT = RENDERING_SPEED_SUPPORT;
|
|
14457
14884
|
exports.REPEATABLE_NODE_TYPES = REPEATABLE_NODE_TYPES;
|
|
14458
14885
|
exports.REPEAT_PLACEHOLDER = REPEAT_PLACEHOLDER;
|
|
@@ -14527,6 +14954,8 @@ exports.TEXT_TO_VIDEO_PROVIDERS = TEXT_TO_VIDEO_PROVIDERS;
|
|
|
14527
14954
|
exports.TIER_MAX_PIPELINE_COST_CREDITS = TIER_MAX_PIPELINE_COST_CREDITS;
|
|
14528
14955
|
exports.TIER_PIPELINE_PARALLELISM = TIER_PIPELINE_PARALLELISM;
|
|
14529
14956
|
exports.TILT_CARRIED_FRACTION = TILT_CARRIED_FRACTION;
|
|
14957
|
+
exports.TOPAZ_DEFAULT_UPSCALE_FACTOR = TOPAZ_DEFAULT_UPSCALE_FACTOR;
|
|
14958
|
+
exports.TOPAZ_UPSCALE_FACTORS = TOPAZ_UPSCALE_FACTORS;
|
|
14530
14959
|
exports.TRANSCRIBE_PROVIDERS = TRANSCRIBE_PROVIDERS;
|
|
14531
14960
|
exports.TRANSIENT_RUNTIME_KEYS = TRANSIENT_RUNTIME_KEYS;
|
|
14532
14961
|
exports.TTS_PROVIDERS = TTS_PROVIDERS;
|
|
@@ -14542,6 +14971,7 @@ exports.VEHICLES = VEHICLES;
|
|
|
14542
14971
|
exports.VEHICLE_SUBCATEGORY_LABELS = VEHICLE_SUBCATEGORY_LABELS;
|
|
14543
14972
|
exports.VEHICLE_SUBCATEGORY_ORDER = VEHICLE_SUBCATEGORY_ORDER;
|
|
14544
14973
|
exports.VEO_PROVIDERS = VEO_PROVIDERS;
|
|
14974
|
+
exports.VIDEO_ANALYSIS_AUDIO_MODES = VIDEO_ANALYSIS_AUDIO_MODES;
|
|
14545
14975
|
exports.VIDEO_ANALYSIS_BUCKET_CREDITS = VIDEO_ANALYSIS_BUCKET_CREDITS;
|
|
14546
14976
|
exports.VIDEO_ANALYSIS_CLIP_TRANSITIONS_IN = VIDEO_ANALYSIS_CLIP_TRANSITIONS_IN;
|
|
14547
14977
|
exports.VIDEO_ANALYSIS_DEFAULT_VARIATION = VIDEO_ANALYSIS_DEFAULT_VARIATION;
|
|
@@ -14586,6 +15016,7 @@ exports.VIDEO_PROMPT_MAX = VIDEO_PROMPT_MAX;
|
|
|
14586
15016
|
exports.VIDEO_PROVIDERS_REQUIRING_IMAGE = VIDEO_PROVIDERS_REQUIRING_IMAGE;
|
|
14587
15017
|
exports.VIDEO_PROVIDERS_WITHOUT_DISPATCH = VIDEO_PROVIDERS_WITHOUT_DISPATCH;
|
|
14588
15018
|
exports.VIDEO_REF_LIMITS_BY_PROVIDER = VIDEO_REF_LIMITS_BY_PROVIDER;
|
|
15019
|
+
exports.VIDEO_REF_VIDEO_DURATION_LIMITS = VIDEO_REF_VIDEO_DURATION_LIMITS;
|
|
14589
15020
|
exports.VIDEO_TO_VIDEO_PROVIDERS = VIDEO_TO_VIDEO_PROVIDERS;
|
|
14590
15021
|
exports.VIDEO_UPSCALE_PROVIDERS = VIDEO_UPSCALE_PROVIDERS;
|
|
14591
15022
|
exports.VIDEO_UTIL_PRICING = VIDEO_UTIL_PRICING;
|
|
@@ -14654,9 +15085,11 @@ exports.characterMentionSlug = characterMentionSlug;
|
|
|
14654
15085
|
exports.characterMentionableAssetArrays = characterMentionableAssetArrays;
|
|
14655
15086
|
exports.characterSheetRefItems = characterSheetRefItems;
|
|
14656
15087
|
exports.characterVariantAssetArrays = characterVariantAssetArrays;
|
|
15088
|
+
exports.checkRefVideoDurations = checkRefVideoDurations;
|
|
14657
15089
|
exports.cinematicCreditId = cinematicCreditId;
|
|
14658
15090
|
exports.clampCinematicDuration = clampCinematicDuration;
|
|
14659
15091
|
exports.clampSmartCutWindow = clampSmartCutWindow;
|
|
15092
|
+
exports.classifyRefToken = classifyRefToken;
|
|
14660
15093
|
exports.cleanOrphanedItems = cleanOrphanedItems;
|
|
14661
15094
|
exports.clearImageCriticMetadata = clearImageCriticMetadata;
|
|
14662
15095
|
exports.clearVideoCriticMetadata = clearVideoCriticMetadata;
|
|
@@ -14831,6 +15264,7 @@ exports.normalizeModelInput = normalizeModelInput;
|
|
|
14831
15264
|
exports.normalizeNodeModelParams = normalizeNodeModelParams;
|
|
14832
15265
|
exports.normalizePinterestUrl = normalizePinterestUrl;
|
|
14833
15266
|
exports.normalizeRoleSlug = normalizeRoleSlug;
|
|
15267
|
+
exports.normalizeVideoRequestParams = normalizeVideoRequestParams;
|
|
14834
15268
|
exports.normalizeWan3Resolution = normalizeWan3Resolution;
|
|
14835
15269
|
exports.orderedLlmModels = orderedLlmModels;
|
|
14836
15270
|
exports.parseAttributedDialogue = parseAttributedDialogue;
|
|
@@ -14855,6 +15289,7 @@ exports.presentTypes = presentTypes;
|
|
|
14855
15289
|
exports.presetApplyClearKeys = presetApplyClearKeys;
|
|
14856
15290
|
exports.presetDataMatches = presetDataMatches;
|
|
14857
15291
|
exports.presetEntries = presetEntries;
|
|
15292
|
+
exports.pricedVideoSelection = pricedVideoSelection;
|
|
14858
15293
|
exports.qualityOptionsByKind = qualityOptionsByKind;
|
|
14859
15294
|
exports.readPromptAffixes = readPromptAffixes;
|
|
14860
15295
|
exports.refHandleCategory = refHandleCategory;
|
|
@@ -14899,6 +15334,7 @@ exports.resolveSlideshowTransition = resolveSlideshowTransition;
|
|
|
14899
15334
|
exports.resolveSourceThroughConnectedList = resolveSourceThroughConnectedList;
|
|
14900
15335
|
exports.resolveStoredTier = resolveStoredTier;
|
|
14901
15336
|
exports.resolveSwitchXCreditId = resolveSwitchXCreditId;
|
|
15337
|
+
exports.resolveTopazUpscale = resolveTopazUpscale;
|
|
14902
15338
|
exports.resolveVideoAnalysisModel = resolveVideoAnalysisModel;
|
|
14903
15339
|
exports.resolveVideoModeForInputs = resolveVideoModeForInputs;
|
|
14904
15340
|
exports.resolveVideoProviderForMode = resolveVideoProviderForMode;
|
|
@@ -14909,6 +15345,7 @@ exports.rewriteSpeakerSlots = rewriteSpeakerSlots;
|
|
|
14909
15345
|
exports.rgbaArrayToHex = rgbaArrayToHex;
|
|
14910
15346
|
exports.roleToPhrase = roleToPhrase;
|
|
14911
15347
|
exports.runSelector = runSelector;
|
|
15348
|
+
exports.safetyRetryPolicy = safetyRetryPolicy;
|
|
14912
15349
|
exports.sanitizeRole = sanitizeRole;
|
|
14913
15350
|
exports.searchModelVariants = searchModelVariants;
|
|
14914
15351
|
exports.seedance2AudioLimitSec = seedance2AudioLimitSec;
|
|
@@ -14945,6 +15382,7 @@ exports.tryParseJson = tryParseJson;
|
|
|
14945
15382
|
exports.uiAspectRatioFill = uiAspectRatioFill;
|
|
14946
15383
|
exports.uiDurationFill = uiDurationFill;
|
|
14947
15384
|
exports.uiResolutionFill = uiResolutionFill;
|
|
15385
|
+
exports.unresolvedRefTokens = unresolvedRefTokens;
|
|
14948
15386
|
exports.unwrapUnresolvedTokens = unwrapUnresolvedTokens;
|
|
14949
15387
|
exports.usageModeDirective = usageModeDirective;
|
|
14950
15388
|
exports.usageModeIncludesName = usageModeIncludesName;
|