@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.
- package/MODEL_REGISTRY.md +136 -0
- package/README.md +28 -4
- package/build/index.d.ts +2 -0
- package/build/index.js +1 -0
- package/build/lib/cli.js +26 -10
- package/build/lib/configure.js +2 -8
- package/build/lib/defaults.js +10 -0
- package/build/lib/film-kit.js +16 -1
- package/build/lib/model-registry/index.d.ts +4 -0
- package/build/lib/model-registry/index.js +3 -0
- package/build/lib/model-registry/registry.d.ts +220 -0
- package/build/lib/model-registry/registry.js +191 -0
- package/build/lib/model-registry/selectors.d.ts +23 -0
- package/build/lib/model-registry/selectors.js +80 -0
- package/build/lib/model-registry/types.d.ts +59 -0
- package/build/lib/model-registry/types.js +1 -0
- package/build/lib/model-registry/validation.d.ts +3 -0
- package/build/lib/model-registry/validation.js +42 -0
- package/build/lib/storyboard-reference/adapters/base.js +2 -5
- package/build/lib/storyboard-reference/defaults.js +2 -1
- package/build/lib/storyboard-reference/output-writer.js +33 -0
- package/build/lib/storyboard-reference/prompt-bundle-builder.js +35 -3
- package/build/lib/storyboard-reference/request-normalizer.js +6 -4
- package/build/lib/storyboard-reference/validators.js +22 -7
- package/build/lib/storyboard-reference/visual-world-builder.js +1 -1
- package/build/lib/types.d.ts +2 -1
- package/package.json +3 -1
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
|
|
297
|
-
|
|
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:
|
|
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)
|
package/build/lib/configure.js
CHANGED
|
@@ -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:
|
|
619
|
+
modelDisplayName: getRegistryModelDisplayName(resolved.model),
|
|
626
620
|
referenceMode: resolved.referenceMode,
|
|
627
621
|
storyboardReferenceActive,
|
|
628
622
|
maxStoryboardPhases: resolved.storyboardReferenceMode.maxStoryboardPhases
|
package/build/lib/defaults.js
CHANGED
|
@@ -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
|
}
|
package/build/lib/film-kit.js
CHANGED
|
@@ -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 {};
|