@milenyumai/film-kit 2.3.2 → 2.3.4

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,136 @@
1
+ # Film-Kit Model Registry
2
+
3
+ Film-Kit model metadata is centralized in `src/lib/model-registry/*`.
4
+
5
+ The registry is TypeScript `as const` metadata, not dynamic JSON. It is the canonical source for model identity, lifecycle, preset compatibility, reference-mode compatibility, capabilities, routing role, prompt grammar key, model profile key, and storyboard adapter resolution.
6
+
7
+ Long prompt grammar, runtime profile prose, production guidance, and generated workflow text stay in the existing template, adapter, skill, and model-profile layers.
8
+
9
+ ## Discovery Summary
10
+
11
+ Phase 0 found model ids in four broad surfaces:
12
+
13
+ - Root validation and runtime selection: `src/lib/types.ts`, `src/lib/defaults.ts`, `src/lib/configure.ts`, `src/lib/cli.ts`, and `src/lib/film-kit.ts`.
14
+ - Storyboard-reference routing: `src/lib/storyboard-reference/defaults.ts`, `request-normalizer.ts`, `prompt-bundle-builder.ts`, and `adapters/*`.
15
+ - Internal preset packages: `packages/*/src/lib/*`, where model ids still appear in private preset defaults, templates, and generated runtime prose.
16
+ - Public/user-facing prose and assertions: `README.md`, `content/*`, `packages/*/content/*`, and tests.
17
+
18
+ Phase 1 moved the root runtime, CLI/config validation, `generate-storyboard --models`, storyboard-reference target validation, display-name lookup, default storyboard model list, and adapter resolution onto the registry.
19
+
20
+ Phase 2 intentionally does not import the root registry directly from `packages/*`: package `tsconfig.json` files use `rootDir: src`, and the internal package sources remain private preset implementations. Public usage is guarded through the root dispatcher and root CLI.
21
+
22
+ Remaining hardcoded model names in templates, content, and tests are prompt grammar, generated docs, explicit examples, or compatibility assertions rather than canonical validation sources.
23
+
24
+ ## Files
25
+
26
+ - `src/lib/model-registry/types.ts` defines registry metadata shapes.
27
+ - `src/lib/model-registry/registry.ts` owns the canonical model entries.
28
+ - `src/lib/model-registry/selectors.ts` exposes lookup and selector helpers.
29
+ - `src/lib/model-registry/validation.ts` owns fail-closed model validation.
30
+ - `src/lib/model-registry/index.ts` is the public registry API barrel.
31
+
32
+ ## Public API
33
+
34
+ - `getModel(id)`
35
+ - `requireModel(id)`
36
+ - `listModels()`
37
+ - `listActiveModels()`
38
+ - `listVideoModels()`
39
+ - `listImageModels()`
40
+ - `listActiveVideoModelIds()`
41
+ - `listRunnableVideoModels()`
42
+ - `listRunnableVideoModelIds()`
43
+ - `listModelsForPreset(preset)`
44
+ - `listModelsForReferenceMode(referenceMode)`
45
+ - `isKnownModelId(value)`
46
+ - `isActiveModelId(value)`
47
+ - `isDeprecatedModelId(value)`
48
+ - `isRemovedModelId(value)`
49
+ - `isVideoModelId(value)`
50
+ - `isImageModelId(value)`
51
+ - `isModelSupportedByPreset(modelId, preset)`
52
+ - `getModelAdapterKey(modelId)`
53
+ - `getModelDisplayName(modelId)`
54
+ - `getReplacementModel(modelId)`
55
+ - `assertModelAllowed(modelId, context)`
56
+ - `validateModelAllowed(modelId, context)`
57
+
58
+ ## Lifecycle Rules
59
+
60
+ - `active`: accepted normally.
61
+ - `experimental`: accepted normally, but may be surfaced as internal or preview metadata.
62
+ - `deprecated`: accepted, emits an explicit warning, and should define `replacementModelId` when possible.
63
+ - `removed`: fail-closed. Removed models must never silently fall back.
64
+
65
+ ## Adapter Routing
66
+
67
+ Storyboard-reference video prompt routing resolves through `adapterKey`.
68
+
69
+ - `veo31` -> Veo adapter
70
+ - `seedance20` -> Seedance 2.0 adapter
71
+ - `kling30` -> Kling 3.0 adapter
72
+ - `generic` -> generic adapter, allowed only when the registry entry explicitly selects it
73
+ - `none`, `gptImage2` -> not valid for video storyboard adapter routing
74
+
75
+ Unknown model strings never receive a generic fallback.
76
+
77
+ ## Adding A Video Model
78
+
79
+ 1. Add one entry in `src/lib/model-registry/registry.ts`.
80
+ 2. Choose `modalities: ["video"]`.
81
+ 3. Set `lifecycleStatus`.
82
+ 4. Set `supportedPresets`.
83
+ 5. Set `supportedReferenceModes`.
84
+ 6. Set `supportedAspects`.
85
+ 7. Add `durationRange` or `durationPolicy`.
86
+ 8. Choose an existing `adapterKey` or add a new adapter.
87
+ 9. Set `promptGrammarKey` and `modelProfileKey`.
88
+ 10. Fill `routingRole` and `capabilities`.
89
+ 11. Add registry selector/validation tests.
90
+ 12. Add storyboard adapter routing tests when the model can generate video prompts.
91
+ 13. Update docs/examples only if the model should be publicly visible.
92
+
93
+ Ideal new-video-model diff:
94
+
95
+ - one registry entry
96
+ - one adapter only if no existing adapter fits
97
+ - focused tests
98
+ - docs update when public
99
+
100
+ ## Adding An Image Model
101
+
102
+ 1. Add one registry entry with `modalities: ["image"]`.
103
+ 2. Do not add it to video-only CLI or storyboard video target validation.
104
+ 3. Pick image-aware `supportedPresets`.
105
+ 4. Use `adapterKey: "gptImage2"` only for GPT Image 2 behavior; use `none` or a future image adapter key otherwise.
106
+ 5. Add tests proving it appears in image selectors and not in video selectors.
107
+
108
+ Image models must not widen video model types or `generate-storyboard --models`.
109
+
110
+ ## Deprecating A Model
111
+
112
+ 1. Change `lifecycleStatus` to `deprecated`.
113
+ 2. Add `deprecationMessage`.
114
+ 3. Add `replacementModelId` when there is a direct replacement.
115
+ 4. Keep compatibility metadata only for paths that still work.
116
+ 5. Add tests proving validation emits a warning.
117
+
118
+ Do not silently rewrite deprecated model ids unless a dedicated migration test covers that behavior.
119
+
120
+ ## Removing A Model
121
+
122
+ 1. Change `lifecycleStatus` to `removed`.
123
+ 2. Keep the id in the registry so validation can fail with a clear message.
124
+ 3. Add `deprecationMessage` and `replacementModelId` when possible.
125
+ 4. Clear runtime compatibility if the model must not be routed.
126
+ 5. Add tests proving `assertModelAllowed` fails closed.
127
+
128
+ Removed models must not fall back to active models or generic adapters.
129
+
130
+ ## Phase Boundaries
131
+
132
+ Phase 1 connects the root runtime, CLI/config validation, and storyboard-reference adapter routing to the registry.
133
+
134
+ Phase 2 keeps internal preset packages private. Package source builds use `rootDir: src`, so direct imports from root `src/lib/model-registry` would break package builds or create circular product coupling. Root `configureFilmKit()` and CLI validation are the canonical guardrails for public usage. Internal package prompt/template prose can continue to contain model names as generated runtime content.
135
+
136
+ Phase 3 is this maintenance documentation plus README linkage.
package/README.md CHANGED
@@ -70,6 +70,8 @@ Storyboard-reference prompt generation is also available when you have a charact
70
70
 
71
71
  ## Model Support
72
72
 
73
+ Canonical model metadata lives in `src/lib/model-registry/*`; see [MODEL_REGISTRY.md](./MODEL_REGISTRY.md) for the add/update/deprecate/remove checklist. Public model selection still happens at init time through the root package and CLI.
74
+
73
75
  ### `veo31`
74
76
 
75
77
  - Default single, multi, and studio model
@@ -484,6 +486,25 @@ Public root exports:
484
486
  - `FILM_KIT_CONFIG_FILE`
485
487
  - `FILM_KIT_PRESETS`
486
488
  - `LEGACY_CONFIG_FILES`
489
+ - `getModel(id)`
490
+ - `requireModel(id)`
491
+ - `listModels()`
492
+ - `listActiveModels()`
493
+ - `listVideoModels()`
494
+ - `listImageModels()`
495
+ - `listModelsForPreset(preset)`
496
+ - `listModelsForReferenceMode(referenceMode)`
497
+ - `isKnownModelId(value)`
498
+ - `isActiveModelId(value)`
499
+ - `isDeprecatedModelId(value)`
500
+ - `isRemovedModelId(value)`
501
+ - `isVideoModelId(value)`
502
+ - `isImageModelId(value)`
503
+ - `isModelSupportedByPreset(modelId, preset)`
504
+ - `getModelAdapterKey(modelId)`
505
+ - `getReplacementModel(modelId)`
506
+ - `assertModelAllowed(id, context)`
507
+ - `validateModelAllowed(id, context)`
487
508
  - `FilmKitPreset`
488
509
  - `SupportedModel`
489
510
  - `SupportedPlatform`
@@ -558,10 +579,7 @@ These subpackages are marked `private: true` and are bundled as internal sources
558
579
  Maintainer release checklist:
559
580
 
560
581
  ```bash
561
- npm run typecheck
562
- npm test
563
- npm run build
564
- npm pack --json --dry-run
582
+ npm run release:check
565
583
  ```
566
584
 
567
585
  Publish the single public package:
@@ -572,6 +590,12 @@ npm whoami
572
590
  npm publish --access public
573
591
  ```
574
592
 
593
+ If the account has npm two-factor authentication enabled for publish, include the current one-time password from the authenticator app:
594
+
595
+ ```bash
596
+ npm publish --access public --otp=123456
597
+ ```
598
+
575
599
  Optional validation before publish:
576
600
 
577
601
  ```bash
package/build/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { configureFilmKit, detectFilmKitPreset, FILM_KIT_CONFIG_FILE, FILM_KIT_PRESETS, LEGACY_CONFIG_FILES } from "./lib/film-kit.js";
2
2
  export { configureAgents } from "./lib/configure.js";
3
3
  export { buildStoryboardReferencePromptBundles, normalizeVideoPromptRequest, renderShotMarkdown, writeStoryboardReferenceOutputs } from "./lib/storyboard-reference/index.js";
4
+ export { assertModelAllowed, getModel, getModelAdapterKey, getModelDisplayName, getReplacementModel, isActiveModelId, isDeprecatedModelId, isImageModelId, isKnownModelId, isModelSupportedByPreset, isRemovedModelId, isVideoModelId, listActiveModels, listActiveVideoModelIds, listImageModels, listModels, listModelsForPreset, listModelsForReferenceMode, listRunnableVideoModelIds, listRunnableVideoModels, listVideoModels, requireModel, validateModelAllowed } from "./lib/model-registry/index.js";
4
5
  export type { AgentConfigOptions, ConfigureFilmKitResult, ConfigureResult, FilmKitConfigFile, FilmKitConfigOptions, FilmKitPreset, GptImageFormat, GptImageQuality, GptImageSize, HybridAspectRatio, KlingPreset, NanoBananaImageSize, ReferenceMode, StoryboardReferenceConfig, SupportedModel, SupportedPlatform } from "./lib/types.js";
6
+ export type { ActiveModelId, AudioModelId, DeprecatedModelId, ImageModelId, KnownModelId, ModelAdapterKey, ModelAllowedContext, ModelAllowedResult, ModelCapabilities, ModelLifecycleStatus, ModelModality, ModelRegistryEntry, MultimodalModelId, RemovedModelId, VideoModelId } from "./lib/model-registry/index.js";
5
7
  export type { CharacterReferenceSheetPrompt, ModelPromptOutput, ModelRouteMetadata, PromptBundle, ProviderAssetMappingEntry, ProviderFileLimitReport, ProviderReferenceTokenPolicy, ReferenceAsset, ReferenceAssetRequirement, SeedanceContinuityMode, ShotHandoffNote, StoryboardImagePrompt, StoryboardPhaseBudget, StoryboardReferenceBuildResult, StoryboardReferencePolicy, StoryboardReferenceWriteResult, VideoPromptRequest } from "./lib/storyboard-reference/index.js";
package/build/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { configureFilmKit, detectFilmKitPreset, FILM_KIT_CONFIG_FILE, FILM_KIT_PRESETS, LEGACY_CONFIG_FILES } from "./lib/film-kit.js";
2
2
  export { configureAgents } from "./lib/configure.js";
3
3
  export { buildStoryboardReferencePromptBundles, normalizeVideoPromptRequest, renderShotMarkdown, writeStoryboardReferenceOutputs } from "./lib/storyboard-reference/index.js";
4
+ export { assertModelAllowed, getModel, getModelAdapterKey, getModelDisplayName, getReplacementModel, isActiveModelId, isDeprecatedModelId, isImageModelId, isKnownModelId, isModelSupportedByPreset, isRemovedModelId, isVideoModelId, listActiveModels, listActiveVideoModelIds, listImageModels, listModels, listModelsForPreset, listModelsForReferenceMode, listRunnableVideoModelIds, listRunnableVideoModels, listVideoModels, requireModel, validateModelAllowed } from "./lib/model-registry/index.js";
package/build/lib/cli.js CHANGED
@@ -2,7 +2,7 @@ import { FILM_KIT_CONFIG_FILE, FILM_KIT_PRESETS, detectFilmKitPreset, isFilmKitP
2
2
  import { readFile } from "node:fs/promises";
3
3
  import { resolve } from "node:path";
4
4
  import { exists } from "./fs.js";
5
- const SUPPORTED_MODELS = ["veo31", "kling-3.0", "seedance-2.0"];
5
+ import { listActiveVideoModelIds, validateModelAllowed } from "./model-registry/index.js";
6
6
  const SUPPORTED_KLING_PRESETS = ["ultra-realism", "balanced", "custom"];
7
7
  const SUPPORTED_ASPECTS = ["16:9", "9:16", "1:1"];
8
8
  const SUPPORTED_REFERENCE_MODES = ["start-end", "storyboard-reference", "hybrid"];
@@ -87,6 +87,9 @@ const PRESET_ALLOWED_FLAGS = {
87
87
  ])
88
88
  };
89
89
  const COMMON_FLAGS = new Set(["--preset", "--output-dir", "--scenario-hint", "--scenario", "--overwrite", "-f"]);
90
+ function supportedVideoModelText() {
91
+ return listActiveVideoModelIds().join(", ");
92
+ }
90
93
  function parseIntegerFlag(raw, flag) {
91
94
  const value = Number.parseInt(raw, 10);
92
95
  if (!Number.isInteger(value) || value <= 0) {
@@ -181,10 +184,10 @@ function parseKnownFlags(args) {
181
184
  options.platforms = parsePlatforms(nextValue);
182
185
  break;
183
186
  case "--model":
184
- if (!SUPPORTED_MODELS.includes(nextValue)) {
185
- throw new Error(`Invalid --model value: ${nextValue}. Supported: ${SUPPORTED_MODELS.join(", ")}`);
186
- }
187
- options.model = nextValue;
187
+ options.model = validateModelAllowed(nextValue, {
188
+ requiredModalities: ["video"],
189
+ usage: "--model"
190
+ }).model.id;
188
191
  break;
189
192
  case "--kling-preset":
190
193
  if (!SUPPORTED_KLING_PRESETS.includes(nextValue)) {
@@ -293,9 +296,11 @@ function parseModels(raw) {
293
296
  throw new Error("Invalid --models value. Expected at least one supported model.");
294
297
  }
295
298
  for (const model of models) {
296
- if (!SUPPORTED_MODELS.includes(model)) {
297
- throw new Error(`Invalid --models value: ${model}. Supported: ${SUPPORTED_MODELS.join(", ")}`);
298
- }
299
+ validateModelAllowed(model, {
300
+ requiredModalities: ["video"],
301
+ referenceMode: "storyboard-reference",
302
+ usage: "--models"
303
+ });
299
304
  }
300
305
  return models;
301
306
  }
@@ -414,7 +419,7 @@ async function parseGenerateStoryboardCommand(args, rootDir) {
414
419
  break;
415
420
  }
416
421
  }
417
- if (!brief) {
422
+ if (!brief?.trim()) {
418
423
  throw new Error("generate-storyboard requires --brief.");
419
424
  }
420
425
  if (characterRefs.length === 0) {
@@ -472,6 +477,17 @@ export async function parseCliCommand(args, rootDir = process.cwd()) {
472
477
  `You can also commit ${FILM_KIT_CONFIG_FILE} and rerun init.`);
473
478
  }
474
479
  validatePresetFlags(preset, providedFlags);
480
+ if (options.model) {
481
+ const validationContext = {
482
+ preset,
483
+ requiredModalities: ["video"],
484
+ usage: "--model"
485
+ };
486
+ if (options.referenceMode !== undefined) {
487
+ validationContext.referenceMode = options.referenceMode;
488
+ }
489
+ validateModelAllowed(options.model, validationContext);
490
+ }
475
491
  return {
476
492
  command: "init",
477
493
  options: {
@@ -518,7 +534,7 @@ generate-storyboard flags:
518
534
  --character-ref Character identity reference image path or URL (repeatable or comma-separated)
519
535
  --storyboard-ref Optional storyboard guide image path or URL (repeatable or comma-separated)
520
536
  --brief Inline brief text or a path to a brief file
521
- --models Comma-separated models: veo31,seedance-2.0,kling-3.0
537
+ --models Comma-separated models: ${supportedVideoModelText()}
522
538
  --duration Duration in seconds per generated shot
523
539
  --aspect 16:9|9:16|1:1
524
540
  --output-dir Output root (default: ./outputs)
@@ -3,6 +3,7 @@ import { fileURLToPath } from "node:url";
3
3
  import { readdir, readFile, rm } from "node:fs/promises";
4
4
  import { exists, readJsonIfExists, writeText } from "./fs.js";
5
5
  import { resolveOptions } from "./defaults.js";
6
+ import { getModelDisplayName as getRegistryModelDisplayName } from "./model-registry/index.js";
6
7
  import { buildProjectFiles } from "./templates.js";
7
8
  const __filename = fileURLToPath(import.meta.url);
8
9
  const __dirname = dirname(__filename);
@@ -549,13 +550,6 @@ description: Storyboard-reference prompt structure for GPT Image 2 character she
549
550
  Do not emit main-shot \`ILK FRAME\`, \`İLK FRAME\`, \`SON FRAME\`, \`SHOTNN_START\`, \`SHOTNN_END\`, or exact first-frame reuse instructions in storyboard-reference mode.
550
551
  `;
551
552
  }
552
- function getModelDisplayName(model) {
553
- if (model === "kling-3.0")
554
- return "Kling 3.0";
555
- if (model === "seedance-2.0")
556
- return "Seedance 2.0";
557
- return "Google Flow + Veo 3.1";
558
- }
559
553
  function getKlingPresetDisplay(model, klingPreset) {
560
554
  return model === "kling-3.0" ? klingPreset : "n/a (Kling-only)";
561
555
  }
@@ -622,7 +616,7 @@ export async function configureAgents(options = {}) {
622
616
  scenarioHint: resolved.scenarioHint,
623
617
  model: resolved.model,
624
618
  klingPreset: getKlingPresetDisplay(resolved.model, resolved.klingPreset),
625
- modelDisplayName: getModelDisplayName(resolved.model),
619
+ modelDisplayName: getRegistryModelDisplayName(resolved.model),
626
620
  referenceMode: resolved.referenceMode,
627
621
  storyboardReferenceActive,
628
622
  maxStoryboardPhases: resolved.storyboardReferenceMode.maxStoryboardPhases
@@ -1,3 +1,4 @@
1
+ import { validateModelAllowed } from "./model-registry/index.js";
1
2
  const ALL_PLATFORMS = ["cursor", "claude", "copilot", "antigravity", "codex"];
2
3
  const DEFAULT_MODEL = "veo31";
3
4
  const DEFAULT_KLING_PRESET = "ultra-realism";
@@ -31,12 +32,21 @@ export function normalizeStoryboardReferenceConfig(input, referenceMode) {
31
32
  export function resolveOptions(input) {
32
33
  const warnings = [];
33
34
  const model = input.model ?? DEFAULT_MODEL;
35
+ const modelValidationContext = {
36
+ requiredModalities: ["video"],
37
+ usage: "runtime"
38
+ };
39
+ if (input.referenceMode !== undefined) {
40
+ modelValidationContext.referenceMode = input.referenceMode;
41
+ }
42
+ const modelValidation = validateModelAllowed(model, modelValidationContext);
34
43
  const klingPreset = input.klingPreset ?? DEFAULT_KLING_PRESET;
35
44
  const referenceMode = input.referenceMode ?? DEFAULT_REFERENCE_MODE;
36
45
  const storyboardReferenceMode = normalizeStoryboardReferenceConfig(input.storyboardReferenceMode, referenceMode);
37
46
  if (!input.model) {
38
47
  warnings.push("Model not specified. Falling back to veo31. In the next major release, --model will be required.");
39
48
  }
49
+ warnings.push(...modelValidation.warnings);
40
50
  if (referenceMode === "storyboard-reference" && !storyboardReferenceMode.enabled) {
41
51
  warnings.push("referenceMode is storyboard-reference, but storyboardReferenceMode.enabled is false.");
42
52
  }
@@ -3,6 +3,7 @@ import { fileURLToPath } from "node:url";
3
3
  import { configureAgents } from "./configure.js";
4
4
  import { resolveOptions } from "./defaults.js";
5
5
  import { exists, readJsonIfExists, writeText } from "./fs.js";
6
+ import { validateModelAllowed } from "./model-registry/index.js";
6
7
  export const FILM_KIT_CONFIG_FILE = "film-kit.config.json";
7
8
  export const FILM_KIT_PRESETS = [
8
9
  "single",
@@ -370,6 +371,20 @@ export async function configureFilmKit(options = {}) {
370
371
  assignDefined(merged, options);
371
372
  merged.rootDir = rootDir;
372
373
  merged.preset = preset;
374
+ const rootValidationWarnings = [];
375
+ const mergedModel = readString(merged.model);
376
+ if (mergedModel) {
377
+ const validationContext = {
378
+ preset,
379
+ requiredModalities: ["video"],
380
+ usage: "film-kit.config.json model"
381
+ };
382
+ const mergedReferenceMode = readString(merged.referenceMode);
383
+ if (mergedReferenceMode !== undefined) {
384
+ validationContext.referenceMode = mergedReferenceMode;
385
+ }
386
+ rootValidationWarnings.push(...validateModelAllowed(mergedModel, validationContext).warnings);
387
+ }
373
388
  const runtime = await loadPresetRuntime(preset);
374
389
  const resolved = runtime.resolve(pickPresetOptions(preset, merged));
375
390
  if (resolved.referenceMode === undefined && merged.referenceMode !== undefined) {
@@ -382,7 +397,7 @@ export async function configureFilmKit(options = {}) {
382
397
  const result = await runtime.configure(configureOptions);
383
398
  const configPath = join(rootDir, FILM_KIT_CONFIG_FILE);
384
399
  await writeText(configPath, `${JSON.stringify(buildFilmKitConfigFile(preset, resolved), null, 2)}\n`);
385
- const warnings = [...result.warnings];
400
+ const warnings = [...rootValidationWarnings, ...result.warnings];
386
401
  if (legacyMatch) {
387
402
  warnings.push(`Migrated legacy config '${legacyMatch.filename}' to '${FILM_KIT_CONFIG_FILE}'.`);
388
403
  }
@@ -0,0 +1,4 @@
1
+ export { MODEL_REGISTRY, type ActiveModelId, type AudioModelId, type DeprecatedModelId, type ImageModelId, type KnownModelId, type MultimodalModelId, type RemovedModelId, type VideoModelId } from "./registry.js";
2
+ export { getModel, getModelAdapterKey, getModelDisplayName, getReplacementModel, isActiveModelId, isDeprecatedModelId, isImageModelId, isKnownModelId, isModelSupportedByPreset, isRemovedModelId, isVideoModelId, listActiveModels, listActiveVideoModelIds, listImageModels, listModels, listModelsForPreset, listModelsForReferenceMode, listRunnableVideoModelIds, listRunnableVideoModels, listVideoModels, requireModel } from "./selectors.js";
3
+ export { assertModelAllowed, validateModelAllowed } from "./validation.js";
4
+ export type { ModelAdapterKey, ModelAllowedContext, ModelAllowedResult, ModelCapabilities, ModelDurationRange, ModelLifecycleStatus, ModelModality, ModelProfileKey, ModelRegistryAspectRatio, ModelRegistryEntry, ModelRegistryPreset, ModelRegistryReferenceMode, ModelRoutingRole, PromptGrammarKey } from "./types.js";
@@ -0,0 +1,3 @@
1
+ export { MODEL_REGISTRY } from "./registry.js";
2
+ export { getModel, getModelAdapterKey, getModelDisplayName, getReplacementModel, isActiveModelId, isDeprecatedModelId, isImageModelId, isKnownModelId, isModelSupportedByPreset, isRemovedModelId, isVideoModelId, listActiveModels, listActiveVideoModelIds, listImageModels, listModels, listModelsForPreset, listModelsForReferenceMode, listRunnableVideoModelIds, listRunnableVideoModels, listVideoModels, requireModel } from "./selectors.js";
3
+ export { assertModelAllowed, validateModelAllowed } from "./validation.js";
@@ -0,0 +1,220 @@
1
+ import type { ModelRegistryEntry } from "./types.js";
2
+ export declare const MODEL_REGISTRY: {
3
+ readonly veo31: {
4
+ readonly id: "veo31";
5
+ readonly displayName: "Google Flow + Veo 3.1";
6
+ readonly provider: "google";
7
+ readonly modalities: readonly ["video"];
8
+ readonly lifecycleStatus: "active";
9
+ readonly supportedPresets: readonly ["single", "multi", "studio"];
10
+ readonly supportedReferenceModes: readonly ["start-end", "storyboard-reference"];
11
+ readonly supportedAspects: readonly ["16:9", "9:16", "1:1"];
12
+ readonly durationRange: {
13
+ readonly minSeconds: 4;
14
+ readonly maxSeconds: 8;
15
+ };
16
+ readonly durationPolicy: "Default Film-Kit Veo runtime duration is 8 seconds.";
17
+ readonly adapterKey: "veo31";
18
+ readonly promptGrammarKey: "veo31";
19
+ readonly modelProfileKey: "veo31";
20
+ readonly routingRole: "primary-video";
21
+ readonly capabilities: {
22
+ readonly characterReference: true;
23
+ readonly storyboardReference: true;
24
+ readonly audioPlan: true;
25
+ readonly dialogue: true;
26
+ readonly startEndFrames: true;
27
+ readonly customStoryboardPhases: true;
28
+ readonly maxStoryboardPhases: 4;
29
+ };
30
+ readonly docsVisibility: "public";
31
+ };
32
+ readonly "seedance-2.0": {
33
+ readonly id: "seedance-2.0";
34
+ readonly displayName: "Seedance 2.0";
35
+ readonly provider: "bytedance";
36
+ readonly modalities: readonly ["video"];
37
+ readonly lifecycleStatus: "active";
38
+ readonly supportedPresets: readonly ["single", "multi", "studio"];
39
+ readonly supportedReferenceModes: readonly ["start-end", "storyboard-reference"];
40
+ readonly supportedAspects: readonly ["16:9", "9:16", "1:1"];
41
+ readonly durationRange: {
42
+ readonly minSeconds: 4;
43
+ readonly maxSeconds: 15;
44
+ };
45
+ readonly durationPolicy: "Seedance storyboard-reference policy uses 4-15 second shots.";
46
+ readonly adapterKey: "seedance20";
47
+ readonly promptGrammarKey: "seedance20";
48
+ readonly modelProfileKey: "seedance20";
49
+ readonly routingRole: "storyboard-video";
50
+ readonly capabilities: {
51
+ readonly characterReference: true;
52
+ readonly storyboardReference: true;
53
+ readonly multipleImageReferences: true;
54
+ readonly audioPlan: true;
55
+ readonly dialogue: true;
56
+ readonly customStoryboardPhases: true;
57
+ readonly maxStoryboardPhases: 4;
58
+ readonly maxReferenceImages: 9;
59
+ readonly maxReferenceVideos: 3;
60
+ readonly maxReferenceAudio: 3;
61
+ readonly maxReferenceFiles: 12;
62
+ };
63
+ readonly docsVisibility: "public";
64
+ };
65
+ readonly "kling-3.0": {
66
+ readonly id: "kling-3.0";
67
+ readonly displayName: "Kling 3.0";
68
+ readonly provider: "kuaishou";
69
+ readonly modalities: readonly ["video"];
70
+ readonly lifecycleStatus: "active";
71
+ readonly supportedPresets: readonly ["single", "multi", "hybrid", "hybrid-smart", "gpt-image-smart", "studio"];
72
+ readonly supportedReferenceModes: readonly ["start-end", "storyboard-reference", "hybrid"];
73
+ readonly supportedAspects: readonly ["16:9", "9:16", "1:1"];
74
+ readonly durationRange: {
75
+ readonly minSeconds: 5;
76
+ readonly maxSeconds: 15;
77
+ };
78
+ readonly durationPolicy: "Kling 3.0 supports Film-Kit start/end and smart-routed video generation.";
79
+ readonly adapterKey: "kling30";
80
+ readonly promptGrammarKey: "kling30";
81
+ readonly modelProfileKey: "kling30";
82
+ readonly routingRole: "primary-video";
83
+ readonly capabilities: {
84
+ readonly characterReference: true;
85
+ readonly storyboardReference: true;
86
+ readonly audioPlan: true;
87
+ readonly startEndFrames: true;
88
+ readonly customStoryboardPhases: true;
89
+ readonly maxStoryboardPhases: 4;
90
+ };
91
+ readonly docsVisibility: "public";
92
+ };
93
+ readonly "gpt-image-2": {
94
+ readonly id: "gpt-image-2";
95
+ readonly displayName: "GPT Image 2";
96
+ readonly provider: "openai";
97
+ readonly modalities: readonly ["image"];
98
+ readonly lifecycleStatus: "active";
99
+ readonly supportedPresets: readonly ["hybrid", "hybrid-smart", "gpt-image-smart", "studio"];
100
+ readonly supportedReferenceModes: readonly ["start-end", "storyboard-reference", "hybrid"];
101
+ readonly supportedAspects: readonly ["16:9", "9:16", "1:1"];
102
+ readonly durationPolicy: "Still-image model; video duration is not applicable.";
103
+ readonly adapterKey: "gptImage2";
104
+ readonly promptGrammarKey: "gptImage2";
105
+ readonly modelProfileKey: "gptImage2";
106
+ readonly routingRole: "image-reference";
107
+ readonly capabilities: {
108
+ readonly characterReference: true;
109
+ readonly storyboardReference: true;
110
+ };
111
+ readonly docsVisibility: "public";
112
+ };
113
+ readonly "gemini-3-pro-image-preview": {
114
+ readonly id: "gemini-3-pro-image-preview";
115
+ readonly displayName: "Gemini 3 Pro Image Preview";
116
+ readonly provider: "google";
117
+ readonly modalities: readonly ["image"];
118
+ readonly lifecycleStatus: "experimental";
119
+ readonly supportedPresets: readonly ["hybrid", "hybrid-smart"];
120
+ readonly supportedReferenceModes: readonly ["start-end", "storyboard-reference", "hybrid"];
121
+ readonly supportedAspects: readonly ["16:9", "9:16", "1:1"];
122
+ readonly durationPolicy: "Still-image model used by internal hybrid presets; video duration is not applicable.";
123
+ readonly adapterKey: "none";
124
+ readonly promptGrammarKey: "generic";
125
+ readonly modelProfileKey: "generic";
126
+ readonly routingRole: "image-reference";
127
+ readonly capabilities: {
128
+ readonly characterReference: true;
129
+ readonly storyboardReference: true;
130
+ };
131
+ readonly docsVisibility: "internal";
132
+ };
133
+ readonly "smart-dialogue-router": {
134
+ readonly id: "smart-dialogue-router";
135
+ readonly displayName: "Smart Dialogue Router";
136
+ readonly provider: "film-kit";
137
+ readonly modalities: readonly ["multimodal"];
138
+ readonly lifecycleStatus: "active";
139
+ readonly supportedPresets: readonly ["hybrid-smart", "gpt-image-smart"];
140
+ readonly supportedReferenceModes: readonly ["start-end", "storyboard-reference", "hybrid"];
141
+ readonly supportedAspects: readonly ["16:9", "9:16", "1:1"];
142
+ readonly durationPolicy: "Internal routing policy; routes dialogue/lip-sync to Veo and non-dialogue shots to Kling.";
143
+ readonly adapterKey: "none";
144
+ readonly promptGrammarKey: "generic";
145
+ readonly modelProfileKey: "generic";
146
+ readonly routingRole: "smart-router";
147
+ readonly capabilities: {
148
+ readonly smartRouting: true;
149
+ readonly audioPlan: true;
150
+ readonly dialogue: true;
151
+ };
152
+ readonly docsVisibility: "internal";
153
+ };
154
+ readonly veo2: {
155
+ readonly id: "veo2";
156
+ readonly displayName: "Veo 2";
157
+ readonly provider: "google";
158
+ readonly modalities: readonly ["video"];
159
+ readonly lifecycleStatus: "deprecated";
160
+ readonly supportedPresets: readonly ["single", "multi", "studio"];
161
+ readonly supportedReferenceModes: readonly ["start-end", "storyboard-reference"];
162
+ readonly supportedAspects: readonly ["16:9", "9:16", "1:1"];
163
+ readonly durationRange: {
164
+ readonly minSeconds: 4;
165
+ readonly maxSeconds: 8;
166
+ };
167
+ readonly durationPolicy: "Deprecated legacy video model kept only for migration warnings.";
168
+ readonly adapterKey: "generic";
169
+ readonly promptGrammarKey: "generic";
170
+ readonly modelProfileKey: "generic";
171
+ readonly routingRole: "legacy-video";
172
+ readonly capabilities: {
173
+ readonly characterReference: true;
174
+ readonly storyboardReference: true;
175
+ readonly audioPlan: true;
176
+ readonly dialogue: true;
177
+ readonly startEndFrames: true;
178
+ readonly customStoryboardPhases: true;
179
+ readonly maxStoryboardPhases: 4;
180
+ };
181
+ readonly deprecationMessage: "veo2 is deprecated. Use veo31 for current Film-Kit video generation.";
182
+ readonly replacementModelId: "veo31";
183
+ readonly docsVisibility: "hidden";
184
+ };
185
+ readonly "kling-2.0": {
186
+ readonly id: "kling-2.0";
187
+ readonly displayName: "Kling 2.0";
188
+ readonly provider: "kuaishou";
189
+ readonly modalities: readonly ["video"];
190
+ readonly lifecycleStatus: "removed";
191
+ readonly supportedPresets: readonly [];
192
+ readonly supportedReferenceModes: readonly [];
193
+ readonly supportedAspects: readonly ["16:9", "9:16", "1:1"];
194
+ readonly durationPolicy: "Removed legacy model. Do not route generation here.";
195
+ readonly adapterKey: "none";
196
+ readonly promptGrammarKey: "generic";
197
+ readonly modelProfileKey: "generic";
198
+ readonly routingRole: "removed";
199
+ readonly capabilities: {};
200
+ readonly deprecationMessage: "kling-2.0 has been removed from Film-Kit. Use kling-3.0 instead.";
201
+ readonly replacementModelId: "kling-3.0";
202
+ readonly docsVisibility: "hidden";
203
+ };
204
+ };
205
+ export type KnownModelId = keyof typeof MODEL_REGISTRY;
206
+ type RegistryEntry<K extends KnownModelId = KnownModelId> = typeof MODEL_REGISTRY[K];
207
+ type ModelIdWithLifecycle<Status extends ModelRegistryEntry["lifecycleStatus"]> = {
208
+ [K in KnownModelId]: RegistryEntry<K>["lifecycleStatus"] extends Status ? K : never;
209
+ }[KnownModelId];
210
+ type ModelIdWithModality<Modality extends ModelRegistryEntry["modalities"][number]> = {
211
+ [K in KnownModelId]: Modality extends RegistryEntry<K>["modalities"][number] ? K : never;
212
+ }[KnownModelId];
213
+ export type ActiveModelId = ModelIdWithLifecycle<"active" | "experimental">;
214
+ export type DeprecatedModelId = ModelIdWithLifecycle<"deprecated">;
215
+ export type RemovedModelId = ModelIdWithLifecycle<"removed">;
216
+ export type VideoModelId = ModelIdWithModality<"video">;
217
+ export type ImageModelId = ModelIdWithModality<"image">;
218
+ export type AudioModelId = ModelIdWithModality<"audio">;
219
+ export type MultimodalModelId = ModelIdWithModality<"multimodal">;
220
+ export {};