@nodaro/shared 1.19.0 → 1.21.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/dist/index.cjs +79 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +78 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/video-analysis.test.ts +69 -1
- package/src/model-catalog.ts +21 -21
- package/src/video-analysis-pricing.ts +16 -16
- package/src/video-analysis.ts +65 -0
package/dist/index.cjs
CHANGED
|
@@ -1664,14 +1664,14 @@ var VIDEO_MODELS = {
|
|
|
1664
1664
|
family: "Nodaro",
|
|
1665
1665
|
label: "Video Analysis (Fast \u2014 legacy)",
|
|
1666
1666
|
series: "Video Analysis",
|
|
1667
|
-
description: "Legacy fast-tier analysis model (pre-2026-07). Kept so stored raw-model configs keep running and pricing
|
|
1667
|
+
description: "Legacy fast-tier analysis model (pre-2026-07). Kept so stored raw-model configs keep running and keep pricing under their own identifier; new fast-tier runs use the current fast model.",
|
|
1668
1668
|
useCases: ["video-analysis", "shot-list", "fast"],
|
|
1669
1669
|
pricing: [
|
|
1670
|
-
{ identifier: "video-analysis:gemini-3-flash", credits:
|
|
1671
|
-
{ identifier: "video-analysis:gemini-3-flash:60s", credits:
|
|
1672
|
-
{ identifier: "video-analysis:gemini-3-flash:180s", credits:
|
|
1673
|
-
{ identifier: "video-analysis:gemini-3-flash:360s", credits:
|
|
1674
|
-
{ identifier: "video-analysis:gemini-3-flash:600s", credits:
|
|
1670
|
+
{ identifier: "video-analysis:gemini-3-flash", credits: 9, note: "10-min ceiling (no duration given)" },
|
|
1671
|
+
{ identifier: "video-analysis:gemini-3-flash:60s", credits: 2 },
|
|
1672
|
+
{ identifier: "video-analysis:gemini-3-flash:180s", credits: 3 },
|
|
1673
|
+
{ identifier: "video-analysis:gemini-3-flash:360s", credits: 6 },
|
|
1674
|
+
{ identifier: "video-analysis:gemini-3-flash:600s", credits: 9, note: "10-min ceiling" }
|
|
1675
1675
|
]
|
|
1676
1676
|
},
|
|
1677
1677
|
"gemini-3.6-flash-video-analysis": {
|
|
@@ -1684,11 +1684,11 @@ var VIDEO_MODELS = {
|
|
|
1684
1684
|
description: "Analyze a video into a structured shot list (scenes, camera, audio) \u2014 fast, economy tier. Billed per duration bucket.",
|
|
1685
1685
|
useCases: ["video-analysis", "shot-list", "fast"],
|
|
1686
1686
|
pricing: [
|
|
1687
|
-
{ identifier: "video-analysis:gemini-3.6-flash", credits:
|
|
1688
|
-
{ identifier: "video-analysis:gemini-3.6-flash:60s", credits:
|
|
1689
|
-
{ identifier: "video-analysis:gemini-3.6-flash:180s", credits:
|
|
1690
|
-
{ identifier: "video-analysis:gemini-3.6-flash:360s", credits:
|
|
1691
|
-
{ identifier: "video-analysis:gemini-3.6-flash:600s", credits:
|
|
1687
|
+
{ identifier: "video-analysis:gemini-3.6-flash", credits: 25, note: "10-min ceiling (no duration given)" },
|
|
1688
|
+
{ identifier: "video-analysis:gemini-3.6-flash:60s", credits: 5 },
|
|
1689
|
+
{ identifier: "video-analysis:gemini-3.6-flash:180s", credits: 6 },
|
|
1690
|
+
{ identifier: "video-analysis:gemini-3.6-flash:360s", credits: 15 },
|
|
1691
|
+
{ identifier: "video-analysis:gemini-3.6-flash:600s", credits: 25, note: "10-min ceiling" }
|
|
1692
1692
|
]
|
|
1693
1693
|
},
|
|
1694
1694
|
"gemini-3.1-pro-video-analysis": {
|
|
@@ -1701,11 +1701,11 @@ var VIDEO_MODELS = {
|
|
|
1701
1701
|
description: "Analyze a video into a structured shot list (scenes, camera, audio) \u2014 higher-fidelity, default tier. Billed per duration bucket.",
|
|
1702
1702
|
useCases: ["video-analysis", "shot-list", "cinematic"],
|
|
1703
1703
|
pricing: [
|
|
1704
|
-
{ identifier: "video-analysis:gemini-3.1-pro", credits:
|
|
1705
|
-
{ identifier: "video-analysis:gemini-3.1-pro:60s", credits:
|
|
1706
|
-
{ identifier: "video-analysis:gemini-3.1-pro:180s", credits:
|
|
1707
|
-
{ identifier: "video-analysis:gemini-3.1-pro:360s", credits:
|
|
1708
|
-
{ identifier: "video-analysis:gemini-3.1-pro:600s", credits:
|
|
1704
|
+
{ identifier: "video-analysis:gemini-3.1-pro", credits: 33, note: "10-min ceiling (no duration given)" },
|
|
1705
|
+
{ identifier: "video-analysis:gemini-3.1-pro:60s", credits: 6 },
|
|
1706
|
+
{ identifier: "video-analysis:gemini-3.1-pro:180s", credits: 8 },
|
|
1707
|
+
{ identifier: "video-analysis:gemini-3.1-pro:360s", credits: 20 },
|
|
1708
|
+
{ identifier: "video-analysis:gemini-3.1-pro:600s", credits: 33, note: "10-min ceiling" }
|
|
1709
1709
|
]
|
|
1710
1710
|
},
|
|
1711
1711
|
// Both mixed tiers are variants of the same advanced multi-engine analysis
|
|
@@ -1721,11 +1721,11 @@ var VIDEO_MODELS = {
|
|
|
1721
1721
|
description: "Our most advanced analysis tier \u2014 multiple analysis engines combined into one result for maximum completeness and accuracy. Billed per duration bucket.",
|
|
1722
1722
|
useCases: ["video-analysis", "shot-list", "premium", "most-complete"],
|
|
1723
1723
|
pricing: [
|
|
1724
|
-
{ identifier: "video-analysis:mixed", credits:
|
|
1725
|
-
{ identifier: "video-analysis:mixed:60s", credits:
|
|
1726
|
-
{ identifier: "video-analysis:mixed:180s", credits:
|
|
1727
|
-
{ identifier: "video-analysis:mixed:360s", credits:
|
|
1728
|
-
{ identifier: "video-analysis:mixed:600s", credits:
|
|
1724
|
+
{ identifier: "video-analysis:mixed", credits: 57, note: "10-min ceiling (no duration given)" },
|
|
1725
|
+
{ identifier: "video-analysis:mixed:60s", credits: 10 },
|
|
1726
|
+
{ identifier: "video-analysis:mixed:180s", credits: 13 },
|
|
1727
|
+
{ identifier: "video-analysis:mixed:360s", credits: 35 },
|
|
1728
|
+
{ identifier: "video-analysis:mixed:600s", credits: 57, note: "10-min ceiling" }
|
|
1729
1729
|
]
|
|
1730
1730
|
}
|
|
1731
1731
|
};
|
|
@@ -12189,7 +12189,28 @@ var entitySlotSchema = zod.z.object({
|
|
|
12189
12189
|
var audioLayerSchema = zod.z.object({
|
|
12190
12190
|
mode: zod.z.enum(["speech", "music", "sfx"]),
|
|
12191
12191
|
content: zod.z.string().min(1),
|
|
12192
|
-
voice: zod.z.string().optional()
|
|
12192
|
+
voice: zod.z.string().optional(),
|
|
12193
|
+
/**
|
|
12194
|
+
* SPEECH ONLY — `slotId` of the on-screen speaker saying these words.
|
|
12195
|
+
*
|
|
12196
|
+
* `voice` casts a voice ("male, proud triumphant shouting"); this says WHO it
|
|
12197
|
+
* belongs to, so a recreation can route the line to the right character
|
|
12198
|
+
* instead of guessing. Usually one person speaks per scene and the guess is
|
|
12199
|
+
* right, which is exactly why the cases with two speakers over one cut fail
|
|
12200
|
+
* silently without this field.
|
|
12201
|
+
*
|
|
12202
|
+
* Optional by design and deliberately NOT refined against `mode` here: the
|
|
12203
|
+
* window schema is the enforced decode grammar, and rejecting a whole roll
|
|
12204
|
+
* because the model tagged a music layer would be a hair-trigger failure. A
|
|
12205
|
+
* speaker on a non-speech layer, or one naming a slot that no longer exists,
|
|
12206
|
+
* is stripped structurally by `dropUnknownSpeakers` — the same
|
|
12207
|
+
* unwrap/drop/sweep philosophy the slot-token and binding channels use.
|
|
12208
|
+
*
|
|
12209
|
+
* An unseen narrator gets NO speaker: a voice with no body is never a slot
|
|
12210
|
+
* (doctrine §5), so attribution here would resurrect the phantom-entity
|
|
12211
|
+
* defect that `stripOrphanSlots` exists to kill.
|
|
12212
|
+
*/
|
|
12213
|
+
speakerSlot: zod.z.string().optional()
|
|
12193
12214
|
});
|
|
12194
12215
|
var windowSceneBase = zod.z.object({
|
|
12195
12216
|
startSec: zod.z.number().min(0),
|
|
@@ -12278,6 +12299,24 @@ function dropUnknownBindings(sv, validBySlot) {
|
|
|
12278
12299
|
}
|
|
12279
12300
|
return { kept: Object.keys(kept).length > 0 ? kept : void 0, dropped };
|
|
12280
12301
|
}
|
|
12302
|
+
function rewriteSpeakerSlots(audio, slotRenames) {
|
|
12303
|
+
if (!audio.some((a) => a.speakerSlot !== void 0 && slotRenames[a.speakerSlot])) return audio;
|
|
12304
|
+
return audio.map((a) => {
|
|
12305
|
+
const to = a.speakerSlot !== void 0 ? slotRenames[a.speakerSlot] : void 0;
|
|
12306
|
+
return to ? { ...a, speakerSlot: to } : a;
|
|
12307
|
+
});
|
|
12308
|
+
}
|
|
12309
|
+
function dropUnknownSpeakers(audio, validSlotIds) {
|
|
12310
|
+
const dropped = [];
|
|
12311
|
+
const out = audio.map((a) => {
|
|
12312
|
+
if (a.speakerSlot === void 0) return a;
|
|
12313
|
+
if (a.mode === "speech" && validSlotIds.has(a.speakerSlot)) return a;
|
|
12314
|
+
dropped.push(a.speakerSlot);
|
|
12315
|
+
const { speakerSlot: _drop, ...rest } = a;
|
|
12316
|
+
return rest;
|
|
12317
|
+
});
|
|
12318
|
+
return { audio: dropped.length > 0 ? out : audio, dropped };
|
|
12319
|
+
}
|
|
12281
12320
|
function renderAnalyzedScene(scene, slots, castMap) {
|
|
12282
12321
|
const byId = new Map(slots.map((s) => [s.slotId, s]));
|
|
12283
12322
|
return scene.visual.replace(SLOT_TOKEN_RE, (_whole, id) => castMap?.[id] ?? byId.get(id)?.description ?? id);
|
|
@@ -12311,27 +12350,27 @@ var WINDOW_OVERLAP = 5;
|
|
|
12311
12350
|
var VIDEO_ANALYSIS_WINDOW = { LEN: WINDOW_LEN, STRIDE: WINDOW_STRIDE, OVERLAP: WINDOW_OVERLAP, SINGLE_MAX: 180 };
|
|
12312
12351
|
var VIDEO_ANALYSIS_BUCKET_CREDITS = {
|
|
12313
12352
|
// Legacy fast-tier model (pre-2026-07) — kept for stored raw-id configs.
|
|
12314
|
-
"video-analysis:gemini-3-flash:60s":
|
|
12315
|
-
"video-analysis:gemini-3-flash:180s":
|
|
12316
|
-
"video-analysis:gemini-3-flash:360s":
|
|
12317
|
-
"video-analysis:gemini-3-flash:600s":
|
|
12353
|
+
"video-analysis:gemini-3-flash:60s": 2,
|
|
12354
|
+
"video-analysis:gemini-3-flash:180s": 3,
|
|
12355
|
+
"video-analysis:gemini-3-flash:360s": 6,
|
|
12356
|
+
"video-analysis:gemini-3-flash:600s": 9,
|
|
12318
12357
|
// Current fast tier — regenerated from the private formula for its backing
|
|
12319
12358
|
// model; higher than the legacy fast schedule but still ≤ pro per bucket.
|
|
12320
|
-
"video-analysis:gemini-3.6-flash:60s":
|
|
12321
|
-
"video-analysis:gemini-3.6-flash:180s":
|
|
12322
|
-
"video-analysis:gemini-3.6-flash:360s":
|
|
12323
|
-
"video-analysis:gemini-3.6-flash:600s":
|
|
12324
|
-
"video-analysis:gemini-3.1-pro:60s":
|
|
12325
|
-
"video-analysis:gemini-3.1-pro:180s":
|
|
12326
|
-
"video-analysis:gemini-3.1-pro:360s":
|
|
12327
|
-
"video-analysis:gemini-3.1-pro:600s":
|
|
12359
|
+
"video-analysis:gemini-3.6-flash:60s": 5,
|
|
12360
|
+
"video-analysis:gemini-3.6-flash:180s": 6,
|
|
12361
|
+
"video-analysis:gemini-3.6-flash:360s": 15,
|
|
12362
|
+
"video-analysis:gemini-3.6-flash:600s": 25,
|
|
12363
|
+
"video-analysis:gemini-3.1-pro:60s": 6,
|
|
12364
|
+
"video-analysis:gemini-3.1-pro:180s": 8,
|
|
12365
|
+
"video-analysis:gemini-3.1-pro:360s": 20,
|
|
12366
|
+
"video-analysis:gemini-3.1-pro:600s": 33,
|
|
12328
12367
|
// Mixed tiers (`mixed` + `mixed-fast`) share ONE credit family — they are
|
|
12329
12368
|
// variants of the same engine plan (plan internals live in the private
|
|
12330
12369
|
// analysis plugin). Admin-tunable via model_pricing like every other row.
|
|
12331
|
-
"video-analysis:mixed:60s":
|
|
12332
|
-
"video-analysis:mixed:180s":
|
|
12333
|
-
"video-analysis:mixed:360s":
|
|
12334
|
-
"video-analysis:mixed:600s":
|
|
12370
|
+
"video-analysis:mixed:60s": 10,
|
|
12371
|
+
"video-analysis:mixed:180s": 13,
|
|
12372
|
+
"video-analysis:mixed:360s": 35,
|
|
12373
|
+
"video-analysis:mixed:600s": 57
|
|
12335
12374
|
};
|
|
12336
12375
|
function videoAnalysisCreditSegment(modelOrSentinel) {
|
|
12337
12376
|
return modelOrSentinel === "mixed-fast" ? "mixed" : modelOrSentinel;
|
|
@@ -12839,6 +12878,7 @@ exports.describeEdgeBehavior = describeEdgeBehavior;
|
|
|
12839
12878
|
exports.describeMaskRegion = describeMaskRegion;
|
|
12840
12879
|
exports.describeSlotControl = describeSlotControl;
|
|
12841
12880
|
exports.dropUnknownBindings = dropUnknownBindings;
|
|
12881
|
+
exports.dropUnknownSpeakers = dropUnknownSpeakers;
|
|
12842
12882
|
exports.durationsByMode = durationsByMode;
|
|
12843
12883
|
exports.effectiveReasoningEffort = effectiveReasoningEffort;
|
|
12844
12884
|
exports.encodeProviderItem = encodeProviderItem;
|
|
@@ -13022,6 +13062,7 @@ exports.resolveVideoProviderForMode = resolveVideoProviderForMode;
|
|
|
13022
13062
|
exports.resolveXfadeName = resolveXfadeName;
|
|
13023
13063
|
exports.rewriteSceneBindings = rewriteSceneBindings;
|
|
13024
13064
|
exports.rewriteSlotTokens = rewriteSlotTokens;
|
|
13065
|
+
exports.rewriteSpeakerSlots = rewriteSpeakerSlots;
|
|
13025
13066
|
exports.rgbaArrayToHex = rgbaArrayToHex;
|
|
13026
13067
|
exports.roleToPhrase = roleToPhrase;
|
|
13027
13068
|
exports.runSelector = runSelector;
|