@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 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 unchanged; new fast-tier runs use the current fast model.",
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: 3, note: "10-min ceiling (no duration given)" },
1671
- { identifier: "video-analysis:gemini-3-flash:60s", credits: 1 },
1672
- { identifier: "video-analysis:gemini-3-flash:180s", credits: 1 },
1673
- { identifier: "video-analysis:gemini-3-flash:360s", credits: 2 },
1674
- { identifier: "video-analysis:gemini-3-flash:600s", credits: 3, note: "10-min ceiling" }
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: 9, note: "10-min ceiling (no duration given)" },
1688
- { identifier: "video-analysis:gemini-3.6-flash:60s", credits: 2 },
1689
- { identifier: "video-analysis:gemini-3.6-flash:180s", credits: 2 },
1690
- { identifier: "video-analysis:gemini-3.6-flash:360s", credits: 5 },
1691
- { identifier: "video-analysis:gemini-3.6-flash:600s", credits: 9, note: "10-min ceiling" }
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: 11, note: "10-min ceiling (no duration given)" },
1705
- { identifier: "video-analysis:gemini-3.1-pro:60s", credits: 2 },
1706
- { identifier: "video-analysis:gemini-3.1-pro:180s", credits: 3 },
1707
- { identifier: "video-analysis:gemini-3.1-pro:360s", credits: 7 },
1708
- { identifier: "video-analysis:gemini-3.1-pro:600s", credits: 11, note: "10-min ceiling" }
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: 14, note: "10-min ceiling (no duration given)" },
1725
- { identifier: "video-analysis:mixed:60s", credits: 3 },
1726
- { identifier: "video-analysis:mixed:180s", credits: 4 },
1727
- { identifier: "video-analysis:mixed:360s", credits: 9 },
1728
- { identifier: "video-analysis:mixed:600s", credits: 14, note: "10-min ceiling" }
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": 1,
12315
- "video-analysis:gemini-3-flash:180s": 1,
12316
- "video-analysis:gemini-3-flash:360s": 2,
12317
- "video-analysis:gemini-3-flash:600s": 3,
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": 2,
12321
- "video-analysis:gemini-3.6-flash:180s": 2,
12322
- "video-analysis:gemini-3.6-flash:360s": 5,
12323
- "video-analysis:gemini-3.6-flash:600s": 9,
12324
- "video-analysis:gemini-3.1-pro:60s": 2,
12325
- "video-analysis:gemini-3.1-pro:180s": 3,
12326
- "video-analysis:gemini-3.1-pro:360s": 7,
12327
- "video-analysis:gemini-3.1-pro:600s": 11,
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": 3,
12332
- "video-analysis:mixed:180s": 4,
12333
- "video-analysis:mixed:360s": 9,
12334
- "video-analysis:mixed:600s": 14
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;