@nodaro/shared 1.9.0 → 1.10.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.
@@ -10,13 +10,16 @@
10
10
  * these.
11
11
  *
12
12
  * The measured-rate constants and the $-derived `videoAnalysisBucketCredits`
13
- * formula live in `backend/src/lib/pricing/video-analysis-cost.ts` (core,
14
- * not ee/ — the MCP tool description builder needs them regardless of
15
- * edition). They were moved out of this package (published Apache-2.0 on
16
- * npm an irrevocable grant) per the 2026-07-06 public-flip IP audit, S5.
13
+ * formula that GENERATE these numbers live PRIVATELY in the
14
+ * `@nodaroai/cloud-plugins` package (`src/plugins/video-analysis/cost.ts`)
15
+ * never in this public repo. They were first moved out of this package
16
+ * (published Apache-2.0 on npm) per the 2026-07-06 public-flip IP audit S5,
17
+ * then out of the app repo entirely alongside the rest of the video-analysis
18
+ * node. A cross-check test in that private package guards this table so the
19
+ * public numbers can't silently drift from the formula.
17
20
  *
18
21
  * `VIDEO_ANALYSIS_BUCKET_CREDITS` below is the precomputed OUTPUT of that
19
- * backend formula for every (model × bucket) combination — a plain credit
22
+ * private formula for every (model × bucket) combination — a plain credit
20
23
  * lookup table, not a formula, mirroring the same wire-contract pattern
21
24
  * `VIDEO_CLIP_CREDITS` uses in `film-pricing.ts`. It is what the frontend's
22
25
  * client-side cost preview (`estimateNodeCredits` in
@@ -34,11 +37,12 @@ const WINDOW_LEN = 150, WINDOW_STRIDE = 145, WINDOW_OVERLAP = 5
34
37
  export const VIDEO_ANALYSIS_WINDOW = { LEN: WINDOW_LEN, STRIDE: WINDOW_STRIDE, OVERLAP: WINDOW_OVERLAP, SINGLE_MAX: 180 } as const
35
38
 
36
39
  /**
37
- * Precomputed credit cost per (model, bucket) — the OUTPUT of the backend's
38
- * `videoAnalysisBucketCredits` formula, not a formula itself. Regenerate by
39
- * running that function for every `VIDEO_ANALYSIS_LLM_MODELS` × duration
40
- * bucket combination whenever the underlying rate/token constants change
41
- * (backend test guards drift). Keep in sync with
40
+ * Precomputed credit cost per (model, bucket) — the OUTPUT of the private
41
+ * `videoAnalysisBucketCredits` formula (in `@nodaroai/cloud-plugins`), not a
42
+ * formula itself. Regenerate by running that function for every
43
+ * `VIDEO_ANALYSIS_LLM_MODELS` × duration bucket combination whenever the
44
+ * underlying rate/token constants change (the plugin's cost test guards drift).
45
+ * Keep in sync with
42
46
  * `docs/nodes/processing-video/video-analysis.md`.
43
47
  */
44
48
  export const VIDEO_ANALYSIS_BUCKET_CREDITS: Record<string, number> = {
@@ -34,11 +34,18 @@ export const entitySlotSchema = z.object({
34
34
  })
35
35
  export type EntitySlot = z.infer<typeof entitySlotSchema>
36
36
 
37
- const audioSchema = z.object({
38
- mode: z.enum(["speech", "music", "sfx", "silence"]),
39
- content: z.string(), // speech: verbatim quote; music/sfx: gen-ready description; silence: "" allowed
37
+ /**
38
+ * One concurrent sound layer in a scene. Real footage stacks sound (music bed
39
+ * under dialogue over ambient sfx), so a scene carries an ARRAY of these an
40
+ * empty array means genuine silence. `content`: speech = verbatim words;
41
+ * music/sfx = gen-ready description. `voice` is speech-only voice-casting.
42
+ */
43
+ const audioLayerSchema = z.object({
44
+ mode: z.enum(["speech", "music", "sfx"]),
45
+ content: z.string().min(1),
40
46
  voice: z.string().optional(),
41
47
  })
48
+ export type AudioLayer = z.infer<typeof audioLayerSchema>
42
49
 
43
50
  const windowSceneBase = z.object({
44
51
  startSec: z.number().min(0),
@@ -48,7 +55,8 @@ const windowSceneBase = z.object({
48
55
  camera: z.string(),
49
56
  visual: z.string().min(1),
50
57
  transitionOut: z.enum(["cut", "fade", "wipe", "whip"]).optional(),
51
- audio: audioSchema,
58
+ // Array of concurrent layers (music + speech + sfx together); [] = silence.
59
+ audio: z.array(audioLayerSchema),
52
60
  })
53
61
  // .strip() (default) drops model-emitted oversized/slotRefs — validator-computed only.
54
62
  const windowSceneSchema = windowSceneBase.refine((s) => s.endSec > s.startSec, { message: "endSec must be > startSec" })