@nodaro/shared 2.12.1 → 2.13.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.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Prompt pre/post text ("affixes") — the PUBLIC node-data contract.
3
+ *
4
+ * Every AI prompt node may carry two optional strings that are wrapped around
5
+ * its run-time prompt: `promptPrefix` goes before, `promptSuffix` after. Both
6
+ * support `{Node Label}` references and plain-text snippets exactly like the
7
+ * main prompt. They are settings (edited in the node's config panel, captured
8
+ * by presets, settable through workflow JSON / `inputOverrides`), never shown
9
+ * on the node face or to published-app end users.
10
+ *
11
+ * Only the KEYS + TYPE live here (what the SDK/API contract needs). The wrap
12
+ * behaviour (`applyPromptAffixes`) lives in `@nodaro/prompts` next to
13
+ * `resolvePrompt` — see the spec's IP-placement note.
14
+ */
15
+ export const PROMPT_PREFIX_KEY = "promptPrefix" as const
16
+ export const PROMPT_SUFFIX_KEY = "promptSuffix" as const
17
+
18
+ export interface PromptAffixFields {
19
+ /** Text placed BEFORE the node's prompt at run time. Supports {Node Label} refs. */
20
+ readonly promptPrefix?: string
21
+ /** Text placed AFTER the node's prompt at run time. Supports {Node Label} refs. */
22
+ readonly promptSuffix?: string
23
+ }
24
+
25
+ /** The affix pair read off node data (blank / non-string values are omitted). */
26
+ export interface PromptAffixes {
27
+ readonly prefix?: string
28
+ readonly suffix?: string
29
+ }
30
+
31
+ function nonBlank(v: unknown): string | undefined {
32
+ return typeof v === "string" && v.trim().length > 0 ? v : undefined
33
+ }
34
+
35
+ /** Read `{ prefix, suffix }` off a node's `data`. Never throws; unknown shapes → `{}`. */
36
+ export function readPromptAffixes(data: Record<string, unknown>): PromptAffixes {
37
+ const prefix = nonBlank(data[PROMPT_PREFIX_KEY])
38
+ const suffix = nonBlank(data[PROMPT_SUFFIX_KEY])
39
+ return {
40
+ ...(prefix !== undefined ? { prefix } : {}),
41
+ ...(suffix !== undefined ? { suffix } : {}),
42
+ }
43
+ }
@@ -86,39 +86,50 @@ export const VIDEO_ANALYSIS_WINDOW = { LEN: WINDOW_LEN, STRIDE: WINDOW_STRIDE, O
86
86
  //
87
87
  // Values are pasted verbatim from the plugin generator's output — never hand
88
88
  // computed. The plugin's cost test cross-checks every row, sentinels included.
89
+ // REGENERATED 2026-08-28 — recast shot-craft Stage 1: the analyser's system
90
+ // prompt grew (transition/on-screen-text doctrine + three required wire
91
+ // fields), so the plugin's system-prompt token pin moved 8_203 → 8_482 and
92
+ // 21 of 28 rows tick up by 1–4 credits (~0.1–0.3%). Output of the plugin's
93
+ // `scripts/gen-va-buckets.mjs` on `feat/va-shot-craft`, pasted verbatim.
94
+ //
95
+ // REGENERATED 2026-08-29 — recast shot-craft Stage 1.3: the analyser's system
96
+ // prompt grew again, moving the plugin's system-prompt token pin 8_482 → 8_706
97
+ // (cloud-plugins 0.209.0). 12 of 20 analysis rows and 6 of 8 audit rows tick up
98
+ // by 1–3 credits (~0.1–0.3%); the legacy `gemini-3-flash` family is unchanged.
99
+ // Output of the plugin's `scripts/gen-va-buckets.mjs`, pasted verbatim.
89
100
  export const VIDEO_ANALYSIS_BUCKET_CREDITS: Record<string, number> = {
90
101
  // Legacy fast-tier model (pre-2026-07) — kept for stored raw-id configs.
91
102
  "video-analysis:gemini-3-flash:60s": 180,
92
103
  "video-analysis:gemini-3-flash:180s": 185,
93
- "video-analysis:gemini-3-flash:360s": 514,
94
- "video-analysis:gemini-3-flash:600s": 846,
104
+ "video-analysis:gemini-3-flash:360s": 515,
105
+ "video-analysis:gemini-3-flash:600s": 847,
95
106
  // Current fast tier — regenerated from the private formula for its backing
96
107
  // model; higher than the legacy fast schedule but still ≤ pro per bucket.
97
- "video-analysis:gemini-3.6-flash:60s": 203,
108
+ "video-analysis:gemini-3.6-flash:60s": 204,
98
109
  "video-analysis:gemini-3.6-flash:180s": 218,
99
- "video-analysis:gemini-3.6-flash:360s": 598,
100
- "video-analysis:gemini-3.6-flash:600s": 986,
101
- "video-analysis:gemini-3.1-pro:60s": 215,
102
- "video-analysis:gemini-3.1-pro:180s": 231,
103
- "video-analysis:gemini-3.1-pro:360s": 636,
104
- "video-analysis:gemini-3.1-pro:600s": 1050,
110
+ "video-analysis:gemini-3.6-flash:360s": 600,
111
+ "video-analysis:gemini-3.6-flash:600s": 990,
112
+ "video-analysis:gemini-3.1-pro:60s": 216,
113
+ "video-analysis:gemini-3.1-pro:180s": 232,
114
+ "video-analysis:gemini-3.1-pro:360s": 639,
115
+ "video-analysis:gemini-3.1-pro:600s": 1053,
105
116
  // Mixed tiers (`mixed` + `mixed-fast`) share ONE credit family — they are
106
117
  // variants of the same engine plan (plan internals live in the private
107
118
  // analysis plugin). Admin-tunable via model_pricing like every other row.
108
- "video-analysis:mixed:60s": 268,
109
- "video-analysis:mixed:180s": 289,
110
- "video-analysis:mixed:360s": 724,
111
- "video-analysis:mixed:600s": 1169,
119
+ "video-analysis:mixed:60s": 269,
120
+ "video-analysis:mixed:180s": 290,
121
+ "video-analysis:mixed:360s": 727,
122
+ "video-analysis:mixed:600s": 1174,
112
123
  // SMART — the accuracy tier, and since the 2026-08-03 re-plan a multi-roll
113
124
  // plan like the others, always refined (`selectionMode` does not apply
114
125
  // here — smart always refines; it never offers a cheaper "choose" path).
115
126
  // Priced above the economy tiers because it genuinely costs more to run;
116
127
  // the only tier whose accuracy is validated against a hand-counted edit
117
128
  // list, re-validated at the current plan before this schedule shipped.
118
- "video-analysis:smart:60s": 410,
119
- "video-analysis:smart:180s": 500,
120
- "video-analysis:smart:360s": 1259,
121
- "video-analysis:smart:600s": 2064,
129
+ "video-analysis:smart:60s": 412,
130
+ "video-analysis:smart:180s": 502,
131
+ "video-analysis:smart:360s": 1264,
132
+ "video-analysis:smart:600s": 2071,
122
133
  }
123
134
 
124
135
  /**
@@ -188,14 +199,14 @@ export function videoAnalysisNumWindows(bucketSec: number): number {
188
199
  * never hand computed. The plugin's cost test cross-checks every row.
189
200
  */
190
201
  export const VIDEO_AUDIT_BUCKET_CREDITS: Record<string, number> = {
191
- "video-audit:60s": 213,
192
- "video-audit:180s": 289,
193
- "video-audit:360s": 659,
194
- "video-audit:600s": 1066,
195
- "video-audit:auto:60s": 393,
196
- "video-audit:auto:180s": 474,
197
- "video-audit:auto:360s": 1173,
198
- "video-audit:auto:600s": 1912,
202
+ "video-audit:60s": 214,
203
+ "video-audit:180s": 290,
204
+ "video-audit:360s": 661,
205
+ "video-audit:600s": 1070,
206
+ "video-audit:auto:60s": 394,
207
+ "video-audit:auto:180s": 475,
208
+ "video-audit:auto:360s": 1176,
209
+ "video-audit:auto:600s": 1917,
199
210
  }
200
211
 
201
212
  /**
@@ -84,8 +84,20 @@ export type VideoAnalysisVisualEffect = (typeof VIDEO_ANALYSIS_VISUAL_EFFECTS)[n
84
84
  * `dissolve` (a cross-fade from one image to the other) is distinct from `fade`
85
85
  * (through black or white). Collapsing both onto `fade` — as this enum did — makes
86
86
  * a recreation render the wrong edit, and the two look nothing alike.
87
+ *
88
+ * ABSENT means NOTHING ASSERTED (since v2): the analyser emits a value only
89
+ * when it can see the device; an unknown or uncertain edit is left out so the
90
+ * video model chooses. `cut` is itself an assertion (an instant change between
91
+ * two clearly different shots), never a default.
87
92
  */
88
- export const VIDEO_ANALYSIS_TRANSITIONS = ["cut", "fade", "dissolve", "wipe", "whip"] as const
93
+ export const VIDEO_ANALYSIS_TRANSITIONS = [
94
+ "cut", "fade", "dissolve", "wipe", "whip",
95
+ // v2 (2026-08-30, recast shot craft rev 1.5 Appendix F): the common edits a
96
+ // creator actually cuts with. `white-flash` / `digital-glitch` are spelled
97
+ // out because `flash` / `glitch` already name in-shot EFFECTS (the axis test
98
+ // below) — a device is the edit BETWEEN two shots, an effect is on one shot.
99
+ "zoom", "slide", "white-flash", "digital-glitch", "morph", "match", "jump",
100
+ ] as const
89
101
  export type VideoAnalysisTransition = (typeof VIDEO_ANALYSIS_TRANSITIONS)[number]
90
102
 
91
103
  /**