@nodaro/shared 1.22.0 → 1.24.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 +137 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -5
- package/dist/index.d.ts +55 -5
- package/dist/index.js +136 -43
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/llm-models.test.ts +19 -0
- package/src/__tests__/video-analysis-catalog-sync.test.ts +47 -0
- package/src/__tests__/video-analysis-pricing.test.ts +6 -1
- package/src/index.ts +3 -0
- package/src/llm-models.ts +80 -6
- package/src/model-catalog.ts +41 -20
- package/src/video-analysis-pricing.ts +24 -16
- package/src/video-analysis.ts +28 -0
package/dist/index.cjs
CHANGED
|
@@ -1667,11 +1667,11 @@ var VIDEO_MODELS = {
|
|
|
1667
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: 14, note: "10-min ceiling (no duration given)" },
|
|
1671
|
+
{ identifier: "video-analysis:gemini-3-flash:60s", credits: 3 },
|
|
1672
|
+
{ identifier: "video-analysis:gemini-3-flash:180s", credits: 4 },
|
|
1673
|
+
{ identifier: "video-analysis:gemini-3-flash:360s", credits: 9 },
|
|
1674
|
+
{ identifier: "video-analysis:gemini-3-flash:600s", credits: 14, 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: 38, note: "10-min ceiling (no duration given)" },
|
|
1688
|
+
{ identifier: "video-analysis:gemini-3.6-flash:60s", credits: 7 },
|
|
1689
|
+
{ identifier: "video-analysis:gemini-3.6-flash:180s", credits: 9 },
|
|
1690
|
+
{ identifier: "video-analysis:gemini-3.6-flash:360s", credits: 23 },
|
|
1691
|
+
{ identifier: "video-analysis:gemini-3.6-flash:600s", credits: 38, 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: 49, note: "10-min ceiling (no duration given)" },
|
|
1705
|
+
{ identifier: "video-analysis:gemini-3.1-pro:60s", credits: 9 },
|
|
1706
|
+
{ identifier: "video-analysis:gemini-3.1-pro:180s", credits: 12 },
|
|
1707
|
+
{ identifier: "video-analysis:gemini-3.1-pro:360s", credits: 30 },
|
|
1708
|
+
{ identifier: "video-analysis:gemini-3.1-pro:600s", credits: 49, 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,32 @@ 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: 63, note: "10-min ceiling (no duration given)" },
|
|
1725
|
+
{ identifier: "video-analysis:mixed:60s", credits: 11 },
|
|
1726
|
+
{ identifier: "video-analysis:mixed:180s", credits: 15 },
|
|
1727
|
+
{ identifier: "video-analysis:mixed:360s", credits: 38 },
|
|
1728
|
+
{ identifier: "video-analysis:mixed:600s", credits: 63, note: "10-min ceiling" }
|
|
1729
|
+
]
|
|
1730
|
+
},
|
|
1731
|
+
// SMART — the accuracy tier, and the only one that does not rely on voting.
|
|
1732
|
+
// Every other tier runs several cheap passes and has a grader pick between them;
|
|
1733
|
+
// this one runs a single pass with reasoning and frame sampling turned all the
|
|
1734
|
+
// way up. Priced well above them because it genuinely costs more to run.
|
|
1735
|
+
"smart-video-analysis": {
|
|
1736
|
+
id: "smart-video-analysis",
|
|
1737
|
+
kind: "video",
|
|
1738
|
+
modes: ["video-analysis"],
|
|
1739
|
+
family: "Nodaro",
|
|
1740
|
+
label: "Video Analysis (Smart)",
|
|
1741
|
+
series: "Video Analysis",
|
|
1742
|
+
description: "Highest-accuracy analysis \u2014 a single deep pass that reads the footage frame by frame, finds its own shot boundaries, and identifies the cast by appearance. Best choice when the shot list will drive regeneration. Billed per duration bucket.",
|
|
1743
|
+
useCases: ["video-analysis", "shot-list", "premium", "most-accurate"],
|
|
1744
|
+
pricing: [
|
|
1745
|
+
{ identifier: "video-analysis:smart", credits: 346, note: "10-min ceiling (no duration given)" },
|
|
1746
|
+
{ identifier: "video-analysis:smart:60s", credits: 42 },
|
|
1747
|
+
{ identifier: "video-analysis:smart:180s", credits: 94 },
|
|
1748
|
+
{ identifier: "video-analysis:smart:360s", credits: 207 },
|
|
1749
|
+
{ identifier: "video-analysis:smart:600s", credits: 346, note: "10-min ceiling" }
|
|
1729
1750
|
]
|
|
1730
1751
|
}
|
|
1731
1752
|
};
|
|
@@ -4373,6 +4394,17 @@ var LLM_MODELS = [
|
|
|
4373
4394
|
// Google documents low/medium/high for 3.1 Pro — no `minimal` tier, so
|
|
4374
4395
|
// this ladder is deliberately shorter than the flash models'.
|
|
4375
4396
|
directReasoningEfforts: ["low", "medium", "high"],
|
|
4397
|
+
// NO `reasoningEfforts` (the proxied ladder) ON PURPOSE, not an omission.
|
|
4398
|
+
// That endpoint accepts `reasoning_effort: low | high` and already DEFAULTS
|
|
4399
|
+
// to "high", so leaving it unset gets its deepest setting and a ladder here
|
|
4400
|
+
// would unlock nothing. The two lanes are NOT equivalent at their maxima:
|
|
4401
|
+
// verified 2026-07-29 on identical input, the proxy's ceiling produces
|
|
4402
|
+
// roughly a quarter of the reasoning tokens that the direct lane's
|
|
4403
|
+
// `thinkingLevel: HIGH` does, and it does not expose Google's deeper tiers
|
|
4404
|
+
// at all. That difference is visible in fine-detail reading (small on-screen
|
|
4405
|
+
// text such as a name badge), which is exactly what video-analysis casts
|
|
4406
|
+
// identities from — so adding an entry here would silently move analysis to
|
|
4407
|
+
// the shallower lane. Don't. Full comparison lives with the analysis engine.
|
|
4376
4408
|
// The ONE Gemini model routed direct-first. It is the premium/low-volume
|
|
4377
4409
|
// tier (video-analysis `pro`, no LLM_FEATURE_DEFAULTS entry), so the ~4×
|
|
4378
4410
|
// list-price premium lands on the smallest call volume — and it is where
|
|
@@ -4626,6 +4658,25 @@ function effectiveReasoningEffort(modelId, requested, advanced = false) {
|
|
|
4626
4658
|
}
|
|
4627
4659
|
return best;
|
|
4628
4660
|
}
|
|
4661
|
+
var LLM_ROUTE_DEFAULTS = {
|
|
4662
|
+
"llm-chat": { temperature: 0.7, maxTokens: 8192 },
|
|
4663
|
+
"ai-writer": { temperature: 0.7, maxTokens: 8192 },
|
|
4664
|
+
"prompt-helper": { temperature: 0.7, maxTokens: 8192, structuredOutput: true },
|
|
4665
|
+
"generate-script": { maxTokens: 16384, structuredOutput: true },
|
|
4666
|
+
"qa-check": { maxTokens: 1024, structuredOutput: true },
|
|
4667
|
+
"image-critic": { maxTokens: 1024, structuredOutput: true },
|
|
4668
|
+
"image-to-text": { maxTokens: 1024 },
|
|
4669
|
+
"describe-to-picker": { structuredOutput: true },
|
|
4670
|
+
"scene-graph-ai": { temperature: 0.3, maxTokens: 4096, structuredOutput: true },
|
|
4671
|
+
"after-effects": { temperature: 0.3, maxTokens: 2048, structuredOutput: true },
|
|
4672
|
+
"lottie-overlay": { temperature: 0.3, maxTokens: 2048, structuredOutput: true },
|
|
4673
|
+
"motion-graphics": { temperature: 0.3, maxTokens: 2048, structuredOutput: true },
|
|
4674
|
+
"motion-graphics-lottie": { temperature: 0.3, maxTokens: 8192, structuredOutput: true },
|
|
4675
|
+
"3d-title": { temperature: 0.4, maxTokens: 3072, structuredOutput: true }
|
|
4676
|
+
};
|
|
4677
|
+
function llmRouteDefaults(feature) {
|
|
4678
|
+
return feature && LLM_ROUTE_DEFAULTS[feature] || {};
|
|
4679
|
+
}
|
|
4629
4680
|
function bumpTier(tier) {
|
|
4630
4681
|
if (tier === "economy") return "standard";
|
|
4631
4682
|
if (tier === "standard") return "premium";
|
|
@@ -4654,16 +4705,22 @@ function resolveLlmCreditId(feature, body) {
|
|
|
4654
4705
|
);
|
|
4655
4706
|
}
|
|
4656
4707
|
var VIDEO_ANALYSIS_LLM_MODELS = LLM_MODELS.filter((m) => getLlmModalityCaps(m.id).video && getLlmModalityCaps(m.id).audio).map((m) => m.id);
|
|
4657
|
-
var VIDEO_ANALYSIS_TIERS = { fast: "gemini-3
|
|
4708
|
+
var VIDEO_ANALYSIS_TIERS = { fast: "gemini-3-flash", pro: "gemini-3.1-pro" };
|
|
4658
4709
|
var VIDEO_ANALYSIS_LEGACY_MODELS = {
|
|
4659
|
-
// fast tier
|
|
4660
|
-
|
|
4710
|
+
// Backed the fast tier from 2026-07 until 2026-07-29, when the economy tiers
|
|
4711
|
+
// moved to the cheaper lane and the older, cheaper flash. It is now the engine
|
|
4712
|
+
// behind the `smart` tier — but `smart` is a SENTINEL that never exposes a model
|
|
4713
|
+
// id, so as far as this map is concerned it no longer backs a selectable tier and
|
|
4714
|
+
// belongs here: stored raw `llmModel` values keep resolving and keep pricing
|
|
4715
|
+
// under their own credit family.
|
|
4716
|
+
"gemini-3.6-flash": "fast"
|
|
4661
4717
|
};
|
|
4662
|
-
var VIDEO_ANALYSIS_MIXED_TIERS = ["mixed", "mixed-fast"];
|
|
4663
|
-
var VIDEO_ANALYSIS_TIER_ORDER = ["pro", "fast", "mixed", "mixed-fast"];
|
|
4718
|
+
var VIDEO_ANALYSIS_MIXED_TIERS = ["mixed", "mixed-fast", "smart"];
|
|
4719
|
+
var VIDEO_ANALYSIS_TIER_ORDER = ["smart", "pro", "fast", "mixed", "mixed-fast"];
|
|
4664
4720
|
var DEFAULT_VIDEO_ANALYSIS_TIER = "pro";
|
|
4665
4721
|
var DEFAULT_VIDEO_ANALYSIS_MODEL = VIDEO_ANALYSIS_TIERS[DEFAULT_VIDEO_ANALYSIS_TIER];
|
|
4666
4722
|
var VIDEO_ANALYSIS_TIER_LABELS = {
|
|
4723
|
+
smart: "Smart",
|
|
4667
4724
|
fast: "Fast",
|
|
4668
4725
|
pro: "Pro",
|
|
4669
4726
|
mixed: "Mixed",
|
|
@@ -12308,6 +12365,19 @@ var entitySlotSchema = zod.z.object({
|
|
|
12308
12365
|
* where this entity is clearly visible. Optional/additive: producers may
|
|
12309
12366
|
* omit it; consumers use it as an identity reference for recreation. */
|
|
12310
12367
|
refImageUrl: zod.z.string().url().optional(),
|
|
12368
|
+
/**
|
|
12369
|
+
* Why `refImageUrl` is ABSENT, when the analyzer's vision pass actively
|
|
12370
|
+
* refused every candidate frame rather than merely failing to produce one.
|
|
12371
|
+
*
|
|
12372
|
+
* Present only alongside a missing `refImageUrl`, and only for a real refusal
|
|
12373
|
+
* — never for a technical failure, so its presence always carries meaning. The
|
|
12374
|
+
* important case reads like "the shots bound to this slot show someone else —
|
|
12375
|
+
* cast as X, but on screen: Y", which is the analyzer telling you the casting
|
|
12376
|
+
* description and the footage disagree. A consumer should treat that as a
|
|
12377
|
+
* reason to review the slot before spending on regeneration, since a wrong
|
|
12378
|
+
* identity propagates into every regenerated shot.
|
|
12379
|
+
*/
|
|
12380
|
+
refRejectedReason: zod.z.string().optional(),
|
|
12311
12381
|
/** NON-default looks only; present only when at least one exists. */
|
|
12312
12382
|
variations: zod.z.array(slotVariationSchema).max(VIDEO_ANALYSIS_MAX_VARIATIONS).optional()
|
|
12313
12383
|
});
|
|
@@ -12411,7 +12481,22 @@ var videoAnalysisResultSchema = zod.z.object({
|
|
|
12411
12481
|
slotId: zod.z.string(),
|
|
12412
12482
|
variationId: zod.z.string(),
|
|
12413
12483
|
label: zod.z.string()
|
|
12414
|
-
})).optional()
|
|
12484
|
+
})).optional(),
|
|
12485
|
+
/**
|
|
12486
|
+
* Analyzer diagnostics for THIS result — things the analysis noticed about
|
|
12487
|
+
* itself that a reader should know before spending on regeneration.
|
|
12488
|
+
*
|
|
12489
|
+
* Added because there was previously no channel for them at all: the merge
|
|
12490
|
+
* layer has always produced a warnings list and the auto-cast pass has always
|
|
12491
|
+
* had findings, and every one of them died in a `console.warn` inside a worker
|
|
12492
|
+
* the user cannot see. So a run could quietly drop a duplicated line, fold a
|
|
12493
|
+
* cast look, or conclude a character is not the person their own description
|
|
12494
|
+
* names, and the result looked indistinguishable from a clean one.
|
|
12495
|
+
*
|
|
12496
|
+
* Prose, not codes, and deliberately so — these are read by a human deciding
|
|
12497
|
+
* whether to re-run, not branched on. Absent when there is nothing to report.
|
|
12498
|
+
*/
|
|
12499
|
+
warnings: zod.z.array(zod.z.string()).optional()
|
|
12415
12500
|
});
|
|
12416
12501
|
function deriveSlotRefs(visual) {
|
|
12417
12502
|
const out = [];
|
|
@@ -12510,27 +12595,35 @@ var WINDOW_OVERLAP = 5;
|
|
|
12510
12595
|
var VIDEO_ANALYSIS_WINDOW = { LEN: WINDOW_LEN, STRIDE: WINDOW_STRIDE, OVERLAP: WINDOW_OVERLAP, SINGLE_MAX: 180 };
|
|
12511
12596
|
var VIDEO_ANALYSIS_BUCKET_CREDITS = {
|
|
12512
12597
|
// Legacy fast-tier model (pre-2026-07) — kept for stored raw-id configs.
|
|
12513
|
-
"video-analysis:gemini-3-flash:60s":
|
|
12514
|
-
"video-analysis:gemini-3-flash:180s":
|
|
12515
|
-
"video-analysis:gemini-3-flash:360s":
|
|
12516
|
-
"video-analysis:gemini-3-flash:600s":
|
|
12598
|
+
"video-analysis:gemini-3-flash:60s": 3,
|
|
12599
|
+
"video-analysis:gemini-3-flash:180s": 4,
|
|
12600
|
+
"video-analysis:gemini-3-flash:360s": 9,
|
|
12601
|
+
"video-analysis:gemini-3-flash:600s": 14,
|
|
12517
12602
|
// Current fast tier — regenerated from the private formula for its backing
|
|
12518
12603
|
// model; higher than the legacy fast schedule but still ≤ pro per bucket.
|
|
12519
|
-
"video-analysis:gemini-3.6-flash:60s":
|
|
12520
|
-
"video-analysis:gemini-3.6-flash:180s":
|
|
12521
|
-
"video-analysis:gemini-3.6-flash:360s":
|
|
12522
|
-
"video-analysis:gemini-3.6-flash:600s":
|
|
12523
|
-
"video-analysis:gemini-3.1-pro:60s":
|
|
12524
|
-
"video-analysis:gemini-3.1-pro:180s":
|
|
12525
|
-
"video-analysis:gemini-3.1-pro:360s":
|
|
12526
|
-
"video-analysis:gemini-3.1-pro:600s":
|
|
12604
|
+
"video-analysis:gemini-3.6-flash:60s": 7,
|
|
12605
|
+
"video-analysis:gemini-3.6-flash:180s": 9,
|
|
12606
|
+
"video-analysis:gemini-3.6-flash:360s": 23,
|
|
12607
|
+
"video-analysis:gemini-3.6-flash:600s": 38,
|
|
12608
|
+
"video-analysis:gemini-3.1-pro:60s": 9,
|
|
12609
|
+
"video-analysis:gemini-3.1-pro:180s": 12,
|
|
12610
|
+
"video-analysis:gemini-3.1-pro:360s": 30,
|
|
12611
|
+
"video-analysis:gemini-3.1-pro:600s": 49,
|
|
12527
12612
|
// Mixed tiers (`mixed` + `mixed-fast`) share ONE credit family — they are
|
|
12528
12613
|
// variants of the same engine plan (plan internals live in the private
|
|
12529
12614
|
// analysis plugin). Admin-tunable via model_pricing like every other row.
|
|
12530
|
-
"video-analysis:mixed:60s":
|
|
12531
|
-
"video-analysis:mixed:180s":
|
|
12532
|
-
"video-analysis:mixed:360s":
|
|
12533
|
-
"video-analysis:mixed:600s":
|
|
12615
|
+
"video-analysis:mixed:60s": 11,
|
|
12616
|
+
"video-analysis:mixed:180s": 15,
|
|
12617
|
+
"video-analysis:mixed:360s": 38,
|
|
12618
|
+
"video-analysis:mixed:600s": 63,
|
|
12619
|
+
// SMART — the one native-transport plan: a single pass with reasoning and
|
|
12620
|
+
// frame sampling turned all the way up. Priced well above the economy tiers
|
|
12621
|
+
// because it genuinely costs more to run, and it is the only tier whose
|
|
12622
|
+
// accuracy was measured against a hand-counted edit list.
|
|
12623
|
+
"video-analysis:smart:60s": 42,
|
|
12624
|
+
"video-analysis:smart:180s": 94,
|
|
12625
|
+
"video-analysis:smart:360s": 207,
|
|
12626
|
+
"video-analysis:smart:600s": 346
|
|
12534
12627
|
};
|
|
12535
12628
|
function videoAnalysisCreditSegment(modelOrSentinel) {
|
|
12536
12629
|
return modelOrSentinel === "mixed-fast" ? "mixed" : modelOrSentinel;
|
|
@@ -12744,6 +12837,7 @@ exports.LLM_MODALITY_CAPS = LLM_MODALITY_CAPS;
|
|
|
12744
12837
|
exports.LLM_MODELS = LLM_MODELS;
|
|
12745
12838
|
exports.LLM_MODEL_IDS = LLM_MODEL_IDS;
|
|
12746
12839
|
exports.LLM_REASONING_EFFORTS = LLM_REASONING_EFFORTS;
|
|
12840
|
+
exports.LLM_ROUTE_DEFAULTS = LLM_ROUTE_DEFAULTS;
|
|
12747
12841
|
exports.LLM_TEXT_INPUT_MAX = LLM_TEXT_INPUT_MAX;
|
|
12748
12842
|
exports.LOCATION_ASSET_TYPES = LOCATION_ASSET_TYPES;
|
|
12749
12843
|
exports.LOCATION_ASSET_VARIANTS = LOCATION_ASSET_VARIANTS;
|
|
@@ -13152,6 +13246,7 @@ exports.jsonResultToList = jsonResultToList;
|
|
|
13152
13246
|
exports.listBoardTemplates = listBoardTemplates;
|
|
13153
13247
|
exports.listModels = listModels;
|
|
13154
13248
|
exports.listSlotSids = listSlotSids;
|
|
13249
|
+
exports.llmRouteDefaults = llmRouteDefaults;
|
|
13155
13250
|
exports.locationMentionSlug = locationMentionSlug;
|
|
13156
13251
|
exports.locationReferencePhotoKindLabel = locationReferencePhotoKindLabel;
|
|
13157
13252
|
exports.locationUsageModeLabel = locationUsageModeLabel;
|