@nodaro/shared 1.4.1
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/LICENSE +202 -0
- package/README.md +32 -0
- package/dist/index.cjs +12506 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +12269 -0
- package/dist/index.d.ts +12269 -0
- package/dist/index.js +11831 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
- package/src/__tests__/__snapshots__/prompt-builder-segments.test.ts.snap +65 -0
- package/src/__tests__/ai-avatar-pricing.test.ts +321 -0
- package/src/__tests__/apply-video-negative-prompt.test.ts +76 -0
- package/src/__tests__/attach-columns.test.ts +28 -0
- package/src/__tests__/audio-crossfade-curves.test.ts +33 -0
- package/src/__tests__/build-model-menu.test.ts +58 -0
- package/src/__tests__/character-aspect-defaults.test.ts +142 -0
- package/src/__tests__/character-mention-slug.test.ts +199 -0
- package/src/__tests__/character-reference-photo-kinds.test.ts +32 -0
- package/src/__tests__/character-usage-mode.test.ts +147 -0
- package/src/__tests__/character-variant-assets.test.ts +142 -0
- package/src/__tests__/character-voice.test.ts +130 -0
- package/src/__tests__/cinematic-avatar-pricing.test.ts +119 -0
- package/src/__tests__/combine-transitions.test.ts +137 -0
- package/src/__tests__/component-types.test.ts +87 -0
- package/src/__tests__/condition-variables.test.ts +98 -0
- package/src/__tests__/credit-identifiers.test.ts +811 -0
- package/src/__tests__/default-video-provider.test.ts +63 -0
- package/src/__tests__/entity-image-handle.test.ts +43 -0
- package/src/__tests__/entity-variants.test.ts +33 -0
- package/src/__tests__/fal-lip-sync-sets.test.ts +31 -0
- package/src/__tests__/featured-entities.test.ts +33 -0
- package/src/__tests__/film-pricing.test.ts +64 -0
- package/src/__tests__/filter-condition.test.ts +285 -0
- package/src/__tests__/freecut-protocol.test.ts +35 -0
- package/src/__tests__/generate-text-items.test.ts +19 -0
- package/src/__tests__/generated-results.test.ts +50 -0
- package/src/__tests__/graph-utils.test.ts +618 -0
- package/src/__tests__/group-aggregation.test.ts +83 -0
- package/src/__tests__/i18n-locale-completeness.test.ts +156 -0
- package/src/__tests__/image-critic-node.test.ts +86 -0
- package/src/__tests__/image-mask-mode.test.ts +16 -0
- package/src/__tests__/image-ref-limit.test.ts +78 -0
- package/src/__tests__/inpaint-region.test.ts +24 -0
- package/src/__tests__/input-field-map-parity.test.ts +30 -0
- package/src/__tests__/json-evaluator.test.ts +289 -0
- package/src/__tests__/json-path.test.ts +64 -0
- package/src/__tests__/lip-sync-pricing.test.ts +142 -0
- package/src/__tests__/list-merge.test.ts +96 -0
- package/src/__tests__/list-sort.test.ts +134 -0
- package/src/__tests__/llm-models.test.ts +445 -0
- package/src/__tests__/location-mention-slug.test.ts +246 -0
- package/src/__tests__/locations-coverage-critic-schema.test.ts +92 -0
- package/src/__tests__/loop-delimiter.test.ts +39 -0
- package/src/__tests__/lottie-slots.test.ts +245 -0
- package/src/__tests__/model-catalog-flux2-resolutions.test.ts +21 -0
- package/src/__tests__/model-constants-location.test.ts +20 -0
- package/src/__tests__/model-constants.test.ts +122 -0
- package/src/__tests__/model-tree.test.ts +86 -0
- package/src/__tests__/no-internal-imports.test.ts +25 -0
- package/src/__tests__/node-default-mappings.test.ts +175 -0
- package/src/__tests__/node-mappable-fields.test.ts +7 -0
- package/src/__tests__/node-preset-export.test.ts +46 -0
- package/src/__tests__/node-preset-extract.test.ts +166 -0
- package/src/__tests__/node-refs-canonical.test.ts +54 -0
- package/src/__tests__/node-refs-combine.test.ts +54 -0
- package/src/__tests__/node-refs.test.ts +187 -0
- package/src/__tests__/node-runtime-keys.test.ts +99 -0
- package/src/__tests__/object-aspect-defaults.test.ts +59 -0
- package/src/__tests__/parameter-node-value.test.ts +137 -0
- package/src/__tests__/pinterest-url.test.ts +35 -0
- package/src/__tests__/pipeline-chat.test.ts +110 -0
- package/src/__tests__/pipeline-validation.test.ts +98 -0
- package/src/__tests__/presentation-utils.test.ts +1137 -0
- package/src/__tests__/producer-types.test.ts +47 -0
- package/src/__tests__/prompt-length-limits.test.ts +156 -0
- package/src/__tests__/provider-directive-defaults.test.ts +46 -0
- package/src/__tests__/reduce-strategy-registry.test.ts +43 -0
- package/src/__tests__/reference-board-templates.test.ts +33 -0
- package/src/__tests__/reference-roles.test.ts +36 -0
- package/src/__tests__/resolve-field-mappings.test.ts +110 -0
- package/src/__tests__/resolve-pipeline-model.test.ts +76 -0
- package/src/__tests__/scene-node-types.test.ts +80 -0
- package/src/__tests__/scraper-actors.test.ts +67 -0
- package/src/__tests__/seedance-2-catalog.test.ts +18 -0
- package/src/__tests__/seedance-2-credit-id.test.ts +23 -0
- package/src/__tests__/seedance-aspects.test.ts +52 -0
- package/src/__tests__/selector.test.ts +1151 -0
- package/src/__tests__/settled-with-limit.test.ts +214 -0
- package/src/__tests__/social-media-specs.test.ts +129 -0
- package/src/__tests__/sub-workflow-validation.test.ts +88 -0
- package/src/__tests__/switchx-pricing.test.ts +28 -0
- package/src/__tests__/to-connected-references.test.ts +153 -0
- package/src/__tests__/utilities.test.ts +541 -0
- package/src/__tests__/video-analysis-pricing.test.ts +58 -0
- package/src/__tests__/video-analysis.test.ts +63 -0
- package/src/__tests__/video-audio-capability.test.ts +204 -0
- package/src/__tests__/video-gen-providers.test.ts +28 -0
- package/src/__tests__/video-mode-aliases.test.ts +150 -0
- package/src/__tests__/video-ref-limits.test.ts +72 -0
- package/src/__tests__/video-utils.test.ts +303 -0
- package/src/__tests__/voice-changer-models.test.ts +33 -0
- package/src/__tests__/workflow-export-strip.test.ts +46 -0
- package/src/ai-avatar-pricing.ts +213 -0
- package/src/ancestor-refs.ts +48 -0
- package/src/animals.ts +231 -0
- package/src/audio-crossfade-curves.ts +73 -0
- package/src/audio-fx-presets.ts +64 -0
- package/src/avatar-payload-validators.ts +214 -0
- package/src/caption-styles.ts +31 -0
- package/src/character-aspect-defaults.ts +102 -0
- package/src/character-facets.ts +37 -0
- package/src/character-mention-slug.ts +166 -0
- package/src/character-usage-mode.ts +109 -0
- package/src/character-variant-assets.ts +121 -0
- package/src/character-voice.ts +151 -0
- package/src/cinematic-avatar-pricing.ts +111 -0
- package/src/clone-utils.ts +46 -0
- package/src/combine-transitions.ts +482 -0
- package/src/community.ts +112 -0
- package/src/component-types.ts +127 -0
- package/src/condition-variables.ts +65 -0
- package/src/credit-estimators/index.ts +15 -0
- package/src/credit-estimators/video-utils.ts +165 -0
- package/src/credit-identifiers.ts +304 -0
- package/src/entity-approval-types.ts +31 -0
- package/src/entity-aspect-defaults.ts +82 -0
- package/src/entity-asset-types.ts +296 -0
- package/src/entity-image-handle.ts +36 -0
- package/src/extra-refs.ts +139 -0
- package/src/featured-entities.ts +136 -0
- package/src/film-pricing.ts +117 -0
- package/src/filter-condition.ts +250 -0
- package/src/flux2-pricing.ts +18 -0
- package/src/freecut-protocol.ts +52 -0
- package/src/furniture.ts +167 -0
- package/src/generate-text-items.ts +15 -0
- package/src/generated-results.ts +63 -0
- package/src/group-aggregation.ts +75 -0
- package/src/hint-graph-types.ts +18 -0
- package/src/i18n/action-fx.ar.ts +89 -0
- package/src/i18n/action-fx.de.ts +89 -0
- package/src/i18n/action-fx.es.ts +89 -0
- package/src/i18n/action-fx.fr.ts +89 -0
- package/src/i18n/action-fx.he.ts +89 -0
- package/src/i18n/action-fx.hi.ts +89 -0
- package/src/i18n/action-fx.ja.ts +89 -0
- package/src/i18n/action-fx.ko.ts +89 -0
- package/src/i18n/action-fx.pt-BR.ts +89 -0
- package/src/i18n/action-fx.ru.ts +89 -0
- package/src/i18n/action-fx.zh-CN.ts +89 -0
- package/src/i18n/aesthetic.ar.ts +170 -0
- package/src/i18n/aesthetic.de.ts +48 -0
- package/src/i18n/aesthetic.es.ts +169 -0
- package/src/i18n/aesthetic.fr.ts +52 -0
- package/src/i18n/aesthetic.he.ts +169 -0
- package/src/i18n/aesthetic.hi.ts +55 -0
- package/src/i18n/aesthetic.ja.ts +165 -0
- package/src/i18n/aesthetic.ko.ts +169 -0
- package/src/i18n/aesthetic.pt-BR.ts +148 -0
- package/src/i18n/aesthetic.ru.ts +155 -0
- package/src/i18n/aesthetic.zh-CN.ts +172 -0
- package/src/i18n/animals.ar.ts +145 -0
- package/src/i18n/animals.de.ts +144 -0
- package/src/i18n/animals.es.ts +158 -0
- package/src/i18n/animals.fr.ts +144 -0
- package/src/i18n/animals.he.ts +155 -0
- package/src/i18n/animals.hi.ts +157 -0
- package/src/i18n/animals.ja.ts +159 -0
- package/src/i18n/animals.ko.ts +159 -0
- package/src/i18n/animals.pt-BR.ts +157 -0
- package/src/i18n/animals.ru.ts +155 -0
- package/src/i18n/animals.zh-CN.ts +155 -0
- package/src/i18n/atmosphere.ar.ts +49 -0
- package/src/i18n/atmosphere.de.ts +47 -0
- package/src/i18n/atmosphere.es.ts +50 -0
- package/src/i18n/atmosphere.fr.ts +47 -0
- package/src/i18n/atmosphere.he.ts +47 -0
- package/src/i18n/atmosphere.hi.ts +49 -0
- package/src/i18n/atmosphere.ja.ts +49 -0
- package/src/i18n/atmosphere.ko.ts +49 -0
- package/src/i18n/atmosphere.pt-BR.ts +49 -0
- package/src/i18n/atmosphere.ru.ts +47 -0
- package/src/i18n/atmosphere.zh-CN.ts +152 -0
- package/src/i18n/backdrop.ar.ts +53 -0
- package/src/i18n/backdrop.de.ts +46 -0
- package/src/i18n/backdrop.es.ts +54 -0
- package/src/i18n/backdrop.fr.ts +52 -0
- package/src/i18n/backdrop.he.ts +51 -0
- package/src/i18n/backdrop.hi.ts +59 -0
- package/src/i18n/backdrop.ja.ts +61 -0
- package/src/i18n/backdrop.ko.ts +59 -0
- package/src/i18n/backdrop.pt-BR.ts +59 -0
- package/src/i18n/backdrop.ru.ts +57 -0
- package/src/i18n/backdrop.zh-CN.ts +57 -0
- package/src/i18n/camera-format.ar.ts +40 -0
- package/src/i18n/camera-format.de.ts +37 -0
- package/src/i18n/camera-format.es.ts +41 -0
- package/src/i18n/camera-format.fr.ts +37 -0
- package/src/i18n/camera-format.he.ts +37 -0
- package/src/i18n/camera-format.hi.ts +42 -0
- package/src/i18n/camera-format.ja.ts +37 -0
- package/src/i18n/camera-format.ko.ts +37 -0
- package/src/i18n/camera-format.pt-BR.ts +46 -0
- package/src/i18n/camera-format.ru.ts +42 -0
- package/src/i18n/camera-format.zh-CN.ts +42 -0
- package/src/i18n/camera-motions.ar.ts +86 -0
- package/src/i18n/camera-motions.de.ts +74 -0
- package/src/i18n/camera-motions.es.ts +86 -0
- package/src/i18n/camera-motions.fr.ts +86 -0
- package/src/i18n/camera-motions.he.ts +86 -0
- package/src/i18n/camera-motions.hi.ts +99 -0
- package/src/i18n/camera-motions.ja.ts +99 -0
- package/src/i18n/camera-motions.ko.ts +99 -0
- package/src/i18n/camera-motions.pt-BR.ts +99 -0
- package/src/i18n/camera-motions.ru.ts +99 -0
- package/src/i18n/camera-motions.zh-CN.ts +99 -0
- package/src/i18n/character-fx.ar.ts +72 -0
- package/src/i18n/character-fx.de.ts +72 -0
- package/src/i18n/character-fx.es.ts +72 -0
- package/src/i18n/character-fx.fr.ts +72 -0
- package/src/i18n/character-fx.he.ts +72 -0
- package/src/i18n/character-fx.hi.ts +72 -0
- package/src/i18n/character-fx.ja.ts +72 -0
- package/src/i18n/character-fx.ko.ts +72 -0
- package/src/i18n/character-fx.pt-BR.ts +72 -0
- package/src/i18n/character-fx.ru.ts +72 -0
- package/src/i18n/character-fx.zh-CN.ts +72 -0
- package/src/i18n/color-look.ar.ts +50 -0
- package/src/i18n/color-look.de.ts +47 -0
- package/src/i18n/color-look.es.ts +50 -0
- package/src/i18n/color-look.fr.ts +50 -0
- package/src/i18n/color-look.he.ts +49 -0
- package/src/i18n/color-look.hi.ts +52 -0
- package/src/i18n/color-look.ja.ts +54 -0
- package/src/i18n/color-look.ko.ts +54 -0
- package/src/i18n/color-look.pt-BR.ts +54 -0
- package/src/i18n/color-look.ru.ts +52 -0
- package/src/i18n/color-look.zh-CN.ts +53 -0
- package/src/i18n/composition-effects.ar.ts +26 -0
- package/src/i18n/composition-effects.de.ts +25 -0
- package/src/i18n/composition-effects.es.ts +27 -0
- package/src/i18n/composition-effects.fr.ts +25 -0
- package/src/i18n/composition-effects.he.ts +25 -0
- package/src/i18n/composition-effects.hi.ts +27 -0
- package/src/i18n/composition-effects.ja.ts +27 -0
- package/src/i18n/composition-effects.ko.ts +27 -0
- package/src/i18n/composition-effects.pt-BR.ts +25 -0
- package/src/i18n/composition-effects.ru.ts +82 -0
- package/src/i18n/composition-effects.zh-CN.ts +25 -0
- package/src/i18n/era.ar.ts +37 -0
- package/src/i18n/era.de.ts +34 -0
- package/src/i18n/era.es.ts +37 -0
- package/src/i18n/era.fr.ts +37 -0
- package/src/i18n/era.he.ts +36 -0
- package/src/i18n/era.hi.ts +39 -0
- package/src/i18n/era.ja.ts +41 -0
- package/src/i18n/era.ko.ts +39 -0
- package/src/i18n/era.pt-BR.ts +41 -0
- package/src/i18n/era.ru.ts +121 -0
- package/src/i18n/era.zh-CN.ts +39 -0
- package/src/i18n/exposure-settings.ar.ts +28 -0
- package/src/i18n/exposure-settings.de.ts +26 -0
- package/src/i18n/exposure-settings.es.ts +28 -0
- package/src/i18n/exposure-settings.fr.ts +29 -0
- package/src/i18n/exposure-settings.he.ts +28 -0
- package/src/i18n/exposure-settings.hi.ts +31 -0
- package/src/i18n/exposure-settings.ja.ts +31 -0
- package/src/i18n/exposure-settings.ko.ts +31 -0
- package/src/i18n/exposure-settings.pt-BR.ts +31 -0
- package/src/i18n/exposure-settings.ru.ts +31 -0
- package/src/i18n/exposure-settings.zh-CN.ts +31 -0
- package/src/i18n/framing.ar.ts +78 -0
- package/src/i18n/framing.de.ts +73 -0
- package/src/i18n/framing.es.ts +78 -0
- package/src/i18n/framing.fr.ts +78 -0
- package/src/i18n/framing.he.ts +77 -0
- package/src/i18n/framing.hi.ts +82 -0
- package/src/i18n/framing.ja.ts +84 -0
- package/src/i18n/framing.ko.ts +82 -0
- package/src/i18n/framing.pt-BR.ts +84 -0
- package/src/i18n/framing.ru.ts +82 -0
- package/src/i18n/framing.zh-CN.ts +82 -0
- package/src/i18n/furniture.ar.ts +92 -0
- package/src/i18n/furniture.de.ts +93 -0
- package/src/i18n/furniture.es.ts +101 -0
- package/src/i18n/furniture.fr.ts +93 -0
- package/src/i18n/furniture.he.ts +101 -0
- package/src/i18n/furniture.hi.ts +101 -0
- package/src/i18n/furniture.ja.ts +101 -0
- package/src/i18n/furniture.ko.ts +101 -0
- package/src/i18n/furniture.pt-BR.ts +101 -0
- package/src/i18n/furniture.ru.ts +101 -0
- package/src/i18n/furniture.zh-CN.ts +101 -0
- package/src/i18n/held-prop.ar.ts +74 -0
- package/src/i18n/held-prop.de.ts +65 -0
- package/src/i18n/held-prop.es.ts +83 -0
- package/src/i18n/held-prop.fr.ts +74 -0
- package/src/i18n/held-prop.he.ts +73 -0
- package/src/i18n/held-prop.hi.ts +82 -0
- package/src/i18n/held-prop.ja.ts +84 -0
- package/src/i18n/held-prop.ko.ts +84 -0
- package/src/i18n/held-prop.pt-BR.ts +84 -0
- package/src/i18n/held-prop.ru.ts +82 -0
- package/src/i18n/held-prop.zh-CN.ts +82 -0
- package/src/i18n/index.ts +208 -0
- package/src/i18n/instrumentation.ar.ts +195 -0
- package/src/i18n/instrumentation.de.ts +195 -0
- package/src/i18n/instrumentation.es.ts +195 -0
- package/src/i18n/instrumentation.fr.ts +195 -0
- package/src/i18n/instrumentation.he.ts +195 -0
- package/src/i18n/instrumentation.hi.ts +195 -0
- package/src/i18n/instrumentation.ja.ts +195 -0
- package/src/i18n/instrumentation.ko.ts +195 -0
- package/src/i18n/instrumentation.pt-BR.ts +195 -0
- package/src/i18n/instrumentation.ru.ts +195 -0
- package/src/i18n/instrumentation.zh-CN.ts +195 -0
- package/src/i18n/lens.ar.ts +24 -0
- package/src/i18n/lens.de.ts +24 -0
- package/src/i18n/lens.es.ts +24 -0
- package/src/i18n/lens.fr.ts +24 -0
- package/src/i18n/lens.he.ts +24 -0
- package/src/i18n/lens.hi.ts +24 -0
- package/src/i18n/lens.ja.ts +24 -0
- package/src/i18n/lens.ko.ts +24 -0
- package/src/i18n/lens.pt-BR.ts +24 -0
- package/src/i18n/lens.ru.ts +25 -0
- package/src/i18n/lens.zh-CN.ts +24 -0
- package/src/i18n/lighting.ar.ts +86 -0
- package/src/i18n/lighting.de.ts +84 -0
- package/src/i18n/lighting.es.ts +89 -0
- package/src/i18n/lighting.fr.ts +84 -0
- package/src/i18n/lighting.he.ts +88 -0
- package/src/i18n/lighting.hi.ts +90 -0
- package/src/i18n/lighting.ja.ts +90 -0
- package/src/i18n/lighting.ko.ts +90 -0
- package/src/i18n/lighting.pt-BR.ts +90 -0
- package/src/i18n/lighting.ru.ts +88 -0
- package/src/i18n/lighting.zh-CN.ts +92 -0
- package/src/i18n/loop-subject.ar.ts +39 -0
- package/src/i18n/loop-subject.de.ts +39 -0
- package/src/i18n/loop-subject.es.ts +39 -0
- package/src/i18n/loop-subject.fr.ts +39 -0
- package/src/i18n/loop-subject.he.ts +39 -0
- package/src/i18n/loop-subject.hi.ts +39 -0
- package/src/i18n/loop-subject.ja.ts +39 -0
- package/src/i18n/loop-subject.ko.ts +39 -0
- package/src/i18n/loop-subject.pt-BR.ts +39 -0
- package/src/i18n/loop-subject.ru.ts +39 -0
- package/src/i18n/loop-subject.zh-CN.ts +39 -0
- package/src/i18n/materials.ar.ts +80 -0
- package/src/i18n/materials.de.ts +80 -0
- package/src/i18n/materials.es.ts +87 -0
- package/src/i18n/materials.fr.ts +80 -0
- package/src/i18n/materials.he.ts +86 -0
- package/src/i18n/materials.hi.ts +86 -0
- package/src/i18n/materials.ja.ts +88 -0
- package/src/i18n/materials.ko.ts +88 -0
- package/src/i18n/materials.pt-BR.ts +88 -0
- package/src/i18n/materials.ru.ts +86 -0
- package/src/i18n/materials.zh-CN.ts +86 -0
- package/src/i18n/mood.ar.ts +61 -0
- package/src/i18n/mood.de.ts +61 -0
- package/src/i18n/mood.es.ts +66 -0
- package/src/i18n/mood.fr.ts +61 -0
- package/src/i18n/mood.he.ts +64 -0
- package/src/i18n/mood.hi.ts +66 -0
- package/src/i18n/mood.ja.ts +66 -0
- package/src/i18n/mood.ko.ts +66 -0
- package/src/i18n/mood.pt-BR.ts +64 -0
- package/src/i18n/mood.ru.ts +64 -0
- package/src/i18n/mood.zh-CN.ts +64 -0
- package/src/i18n/music-genre.ar.ts +302 -0
- package/src/i18n/music-genre.de.ts +302 -0
- package/src/i18n/music-genre.es.ts +302 -0
- package/src/i18n/music-genre.fr.ts +302 -0
- package/src/i18n/music-genre.he.ts +302 -0
- package/src/i18n/music-genre.hi.ts +302 -0
- package/src/i18n/music-genre.ja.ts +302 -0
- package/src/i18n/music-genre.ko.ts +302 -0
- package/src/i18n/music-genre.pt-BR.ts +302 -0
- package/src/i18n/music-genre.ru.ts +302 -0
- package/src/i18n/music-genre.zh-CN.ts +302 -0
- package/src/i18n/music-mood.ar.ts +75 -0
- package/src/i18n/music-mood.de.ts +75 -0
- package/src/i18n/music-mood.es.ts +75 -0
- package/src/i18n/music-mood.fr.ts +75 -0
- package/src/i18n/music-mood.he.ts +75 -0
- package/src/i18n/music-mood.hi.ts +75 -0
- package/src/i18n/music-mood.ja.ts +75 -0
- package/src/i18n/music-mood.ko.ts +75 -0
- package/src/i18n/music-mood.pt-BR.ts +75 -0
- package/src/i18n/music-mood.ru.ts +75 -0
- package/src/i18n/music-mood.zh-CN.ts +75 -0
- package/src/i18n/person.ar.ts +638 -0
- package/src/i18n/person.de.ts +629 -0
- package/src/i18n/person.es.ts +645 -0
- package/src/i18n/person.fr.ts +621 -0
- package/src/i18n/person.he.ts +656 -0
- package/src/i18n/person.hi.ts +654 -0
- package/src/i18n/person.ja.ts +662 -0
- package/src/i18n/person.ko.ts +662 -0
- package/src/i18n/person.pt-BR.ts +656 -0
- package/src/i18n/person.ru.ts +656 -0
- package/src/i18n/person.zh-CN.ts +656 -0
- package/src/i18n/photo-genre.ar.ts +58 -0
- package/src/i18n/photo-genre.de.ts +52 -0
- package/src/i18n/photo-genre.es.ts +64 -0
- package/src/i18n/photo-genre.fr.ts +58 -0
- package/src/i18n/photo-genre.he.ts +62 -0
- package/src/i18n/photo-genre.hi.ts +63 -0
- package/src/i18n/photo-genre.ja.ts +65 -0
- package/src/i18n/photo-genre.ko.ts +63 -0
- package/src/i18n/photo-genre.pt-BR.ts +65 -0
- package/src/i18n/photo-genre.ru.ts +63 -0
- package/src/i18n/photo-genre.zh-CN.ts +63 -0
- package/src/i18n/photographer.ar.ts +75 -0
- package/src/i18n/photographer.de.ts +74 -0
- package/src/i18n/photographer.es.ts +77 -0
- package/src/i18n/photographer.fr.ts +77 -0
- package/src/i18n/photographer.he.ts +78 -0
- package/src/i18n/photographer.hi.ts +80 -0
- package/src/i18n/photographer.ja.ts +84 -0
- package/src/i18n/photographer.ko.ts +84 -0
- package/src/i18n/photographer.pt-BR.ts +83 -0
- package/src/i18n/photographer.ru.ts +78 -0
- package/src/i18n/photographer.zh-CN.ts +78 -0
- package/src/i18n/pose.ar.ts +95 -0
- package/src/i18n/pose.de.ts +96 -0
- package/src/i18n/pose.es.ts +104 -0
- package/src/i18n/pose.fr.ts +96 -0
- package/src/i18n/pose.he.ts +104 -0
- package/src/i18n/pose.hi.ts +104 -0
- package/src/i18n/pose.ja.ts +104 -0
- package/src/i18n/pose.ko.ts +104 -0
- package/src/i18n/pose.pt-BR.ts +104 -0
- package/src/i18n/pose.ru.ts +104 -0
- package/src/i18n/pose.zh-CN.ts +104 -0
- package/src/i18n/post-process-effects.ar.ts +25 -0
- package/src/i18n/post-process-effects.de.ts +24 -0
- package/src/i18n/post-process-effects.es.ts +26 -0
- package/src/i18n/post-process-effects.fr.ts +24 -0
- package/src/i18n/post-process-effects.he.ts +24 -0
- package/src/i18n/post-process-effects.hi.ts +26 -0
- package/src/i18n/post-process-effects.ja.ts +26 -0
- package/src/i18n/post-process-effects.ko.ts +26 -0
- package/src/i18n/post-process-effects.pt-BR.ts +24 -0
- package/src/i18n/post-process-effects.ru.ts +24 -0
- package/src/i18n/post-process-effects.zh-CN.ts +24 -0
- package/src/i18n/render-quality.ar.ts +34 -0
- package/src/i18n/render-quality.de.ts +30 -0
- package/src/i18n/render-quality.es.ts +35 -0
- package/src/i18n/render-quality.fr.ts +34 -0
- package/src/i18n/render-quality.he.ts +33 -0
- package/src/i18n/render-quality.hi.ts +39 -0
- package/src/i18n/render-quality.ja.ts +39 -0
- package/src/i18n/render-quality.ko.ts +39 -0
- package/src/i18n/render-quality.pt-BR.ts +37 -0
- package/src/i18n/render-quality.ru.ts +37 -0
- package/src/i18n/render-quality.zh-CN.ts +37 -0
- package/src/i18n/seasons.ar.ts +10 -0
- package/src/i18n/seasons.de.ts +10 -0
- package/src/i18n/seasons.es.ts +10 -0
- package/src/i18n/seasons.fr.ts +10 -0
- package/src/i18n/seasons.he.ts +10 -0
- package/src/i18n/seasons.hi.ts +10 -0
- package/src/i18n/seasons.ja.ts +10 -0
- package/src/i18n/seasons.ko.ts +10 -0
- package/src/i18n/seasons.pt-BR.ts +10 -0
- package/src/i18n/seasons.ru.ts +10 -0
- package/src/i18n/seasons.zh-CN.ts +10 -0
- package/src/i18n/setting.ar.ts +73 -0
- package/src/i18n/setting.de.ts +73 -0
- package/src/i18n/setting.es.ts +77 -0
- package/src/i18n/setting.fr.ts +73 -0
- package/src/i18n/setting.he.ts +76 -0
- package/src/i18n/setting.hi.ts +76 -0
- package/src/i18n/setting.ja.ts +78 -0
- package/src/i18n/setting.ko.ts +76 -0
- package/src/i18n/setting.pt-BR.ts +78 -0
- package/src/i18n/setting.ru.ts +76 -0
- package/src/i18n/setting.zh-CN.ts +76 -0
- package/src/i18n/style.ar.ts +55 -0
- package/src/i18n/style.de.ts +54 -0
- package/src/i18n/style.es.ts +54 -0
- package/src/i18n/style.fr.ts +54 -0
- package/src/i18n/style.he.ts +54 -0
- package/src/i18n/style.hi.ts +54 -0
- package/src/i18n/style.ja.ts +54 -0
- package/src/i18n/style.ko.ts +54 -0
- package/src/i18n/style.pt-BR.ts +56 -0
- package/src/i18n/style.ru.ts +54 -0
- package/src/i18n/style.zh-CN.ts +54 -0
- package/src/i18n/styling.ar.ts +295 -0
- package/src/i18n/styling.de.ts +285 -0
- package/src/i18n/styling.es.ts +317 -0
- package/src/i18n/styling.fr.ts +285 -0
- package/src/i18n/styling.he.ts +307 -0
- package/src/i18n/styling.hi.ts +323 -0
- package/src/i18n/styling.ja.ts +317 -0
- package/src/i18n/styling.ko.ts +311 -0
- package/src/i18n/styling.pt-BR.ts +301 -0
- package/src/i18n/styling.ru.ts +301 -0
- package/src/i18n/styling.zh-CN.ts +307 -0
- package/src/i18n/temporal.ar.ts +31 -0
- package/src/i18n/temporal.de.ts +24 -0
- package/src/i18n/temporal.es.ts +27 -0
- package/src/i18n/temporal.fr.ts +28 -0
- package/src/i18n/temporal.he.ts +31 -0
- package/src/i18n/temporal.hi.ts +31 -0
- package/src/i18n/temporal.ja.ts +31 -0
- package/src/i18n/temporal.ko.ts +31 -0
- package/src/i18n/temporal.pt-BR.ts +31 -0
- package/src/i18n/temporal.ru.ts +31 -0
- package/src/i18n/temporal.zh-CN.ts +31 -0
- package/src/i18n/transitions.ar.ts +97 -0
- package/src/i18n/transitions.de.ts +97 -0
- package/src/i18n/transitions.es.ts +97 -0
- package/src/i18n/transitions.fr.ts +97 -0
- package/src/i18n/transitions.he.ts +97 -0
- package/src/i18n/transitions.hi.ts +97 -0
- package/src/i18n/transitions.ja.ts +97 -0
- package/src/i18n/transitions.ko.ts +97 -0
- package/src/i18n/transitions.pt-BR.ts +97 -0
- package/src/i18n/transitions.ru.ts +97 -0
- package/src/i18n/transitions.zh-CN.ts +97 -0
- package/src/i18n/types.ts +158 -0
- package/src/i18n/vehicles.ar.ts +137 -0
- package/src/i18n/vehicles.de.ts +125 -0
- package/src/i18n/vehicles.es.ts +138 -0
- package/src/i18n/vehicles.fr.ts +125 -0
- package/src/i18n/vehicles.he.ts +136 -0
- package/src/i18n/vehicles.hi.ts +138 -0
- package/src/i18n/vehicles.ja.ts +138 -0
- package/src/i18n/vehicles.ko.ts +138 -0
- package/src/i18n/vehicles.pt-BR.ts +136 -0
- package/src/i18n/vehicles.ru.ts +136 -0
- package/src/i18n/vehicles.zh-CN.ts +136 -0
- package/src/i18n/voice-character.ar.ts +126 -0
- package/src/i18n/voice-character.de.ts +126 -0
- package/src/i18n/voice-character.es.ts +126 -0
- package/src/i18n/voice-character.fr.ts +126 -0
- package/src/i18n/voice-character.he.ts +126 -0
- package/src/i18n/voice-character.hi.ts +126 -0
- package/src/i18n/voice-character.ja.ts +126 -0
- package/src/i18n/voice-character.ko.ts +126 -0
- package/src/i18n/voice-character.pt-BR.ts +126 -0
- package/src/i18n/voice-character.ru.ts +126 -0
- package/src/i18n/voice-character.zh-CN.ts +126 -0
- package/src/i18n/voice-delivery.ar.ts +77 -0
- package/src/i18n/voice-delivery.de.ts +77 -0
- package/src/i18n/voice-delivery.es.ts +77 -0
- package/src/i18n/voice-delivery.fr.ts +77 -0
- package/src/i18n/voice-delivery.he.ts +77 -0
- package/src/i18n/voice-delivery.hi.ts +77 -0
- package/src/i18n/voice-delivery.ja.ts +77 -0
- package/src/i18n/voice-delivery.ko.ts +77 -0
- package/src/i18n/voice-delivery.pt-BR.ts +77 -0
- package/src/i18n/voice-delivery.ru.ts +77 -0
- package/src/i18n/voice-delivery.zh-CN.ts +77 -0
- package/src/i18n/weapons.ar.ts +115 -0
- package/src/i18n/weapons.de.ts +114 -0
- package/src/i18n/weapons.es.ts +116 -0
- package/src/i18n/weapons.fr.ts +103 -0
- package/src/i18n/weapons.he.ts +114 -0
- package/src/i18n/weapons.hi.ts +116 -0
- package/src/i18n/weapons.ja.ts +116 -0
- package/src/i18n/weapons.ko.ts +116 -0
- package/src/i18n/weapons.pt-BR.ts +114 -0
- package/src/i18n/weapons.ru.ts +114 -0
- package/src/i18n/weapons.zh-CN.ts +114 -0
- package/src/image-critic-node.ts +61 -0
- package/src/image-critic-types.ts +40 -0
- package/src/index.ts +866 -0
- package/src/inject-upstream.ts +15 -0
- package/src/inpaint-region.ts +51 -0
- package/src/json-evaluator.ts +732 -0
- package/src/json-path.ts +52 -0
- package/src/lip-sync-pricing.ts +90 -0
- package/src/list-merge.ts +40 -0
- package/src/list-sort.ts +122 -0
- package/src/list-source-resolver.ts +50 -0
- package/src/llm-models.ts +245 -0
- package/src/location-mention-slug.ts +291 -0
- package/src/location-preset-catalog-map.ts +128 -0
- package/src/loop-delimiter.ts +73 -0
- package/src/lora-routing.ts +95 -0
- package/src/lottie-overlay-catalog.ts +175 -0
- package/src/lottie-slots.ts +309 -0
- package/src/model-catalog.ts +2386 -0
- package/src/model-constants.ts +1910 -0
- package/src/model-tree.ts +120 -0
- package/src/monetization.ts +15 -0
- package/src/multi-pick.ts +42 -0
- package/src/node-default-mappings.ts +262 -0
- package/src/node-mappable-fields.ts +70 -0
- package/src/node-preset-export.ts +56 -0
- package/src/node-preset-extract.ts +147 -0
- package/src/node-refs.ts +253 -0
- package/src/node-runtime-keys.ts +117 -0
- package/src/object-aspect-defaults.ts +72 -0
- package/src/object-picker-types.ts +22 -0
- package/src/parameter-node-value.ts +284 -0
- package/src/pinterest-url.ts +28 -0
- package/src/pipeline-chat.ts +72 -0
- package/src/pipeline-defaults.ts +318 -0
- package/src/pipeline-events.ts +162 -0
- package/src/pipeline-state-types.ts +196 -0
- package/src/pipeline-types.ts +647 -0
- package/src/pipeline-validation.ts +87 -0
- package/src/presentation-types.ts +23 -0
- package/src/presentation-utils.ts +397 -0
- package/src/producer-types.ts +188 -0
- package/src/progress-curve.ts +99 -0
- package/src/provider-directive-defaults.ts +69 -0
- package/src/reduce-strategy-registry.ts +121 -0
- package/src/reference-board-templates.ts +81 -0
- package/src/reference-roles.ts +153 -0
- package/src/reference-sheet/__tests__/board-to-column.test.ts +20 -0
- package/src/reference-sheet/__tests__/catalog.test.ts +50 -0
- package/src/reference-sheet/__tests__/cost.test.ts +38 -0
- package/src/reference-sheet/__tests__/no-drift.test.ts +28 -0
- package/src/reference-sheet/__tests__/panel-plan.test.ts +61 -0
- package/src/reference-sheet/__tests__/panel-prompts.test.ts +17 -0
- package/src/reference-sheet/__tests__/plan-generation.test.ts +72 -0
- package/src/reference-sheet/__tests__/presets.test.ts +54 -0
- package/src/reference-sheet/__tests__/types.test.ts +24 -0
- package/src/reference-sheet/catalog.ts +144 -0
- package/src/reference-sheet/cost.ts +37 -0
- package/src/reference-sheet/credit-id.ts +7 -0
- package/src/reference-sheet/index.ts +8 -0
- package/src/reference-sheet/panel-plan.ts +65 -0
- package/src/reference-sheet/panel-prompts.ts +14 -0
- package/src/reference-sheet/plan-generation.ts +79 -0
- package/src/reference-sheet/presets.ts +77 -0
- package/src/reference-sheet/types.ts +92 -0
- package/src/repeat-types.ts +97 -0
- package/src/resolve-field-mappings.ts +119 -0
- package/src/route-filter.ts +80 -0
- package/src/scene-helper-types.ts +249 -0
- package/src/scene-node-types.ts +281 -0
- package/src/scraper-actors.ts +57 -0
- package/src/scraper-output-schemas.ts +25 -0
- package/src/seasons.ts +45 -0
- package/src/selector.ts +864 -0
- package/src/settled-with-limit.ts +42 -0
- package/src/shot-element.ts +43 -0
- package/src/social-media-specs.ts +121 -0
- package/src/social-post.ts +24 -0
- package/src/sub-workflow-validation.ts +78 -0
- package/src/supported-fonts.ts +40 -0
- package/src/surround.ts +113 -0
- package/src/switchx-pricing.ts +33 -0
- package/src/text-separators.ts +59 -0
- package/src/to-connected-references.ts +77 -0
- package/src/types.ts +272 -0
- package/src/variant-job-id.ts +17 -0
- package/src/vehicles.ts +213 -0
- package/src/video-analysis-pricing.ts +74 -0
- package/src/video-analysis.ts +127 -0
- package/src/video-duration.ts +25 -0
- package/src/voice-changer-models.ts +36 -0
- package/src/voice-matcher-types.ts +37 -0
- package/src/voices.ts +92 -0
- package/src/weapons.ts +190 -0
- package/src/workflow-export.ts +153 -0
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import {
|
|
3
|
+
PIPELINE_FORMATS,
|
|
4
|
+
PIPELINE_MODES,
|
|
5
|
+
PIPELINE_OUTPUT_RESOLUTIONS,
|
|
6
|
+
PIPELINE_TYPES,
|
|
7
|
+
VIDEO_CRITIC_FRAME_MODES,
|
|
8
|
+
} from "./pipeline-defaults.js"
|
|
9
|
+
import { SceneMetadataSchema } from "./scene-node-types.js"
|
|
10
|
+
|
|
11
|
+
// ─── Input schema (POST /v1/pipelines body) ───────────────────────────────────
|
|
12
|
+
|
|
13
|
+
export const StyleDirectivesSchema = z.object({
|
|
14
|
+
visualStyle: z.string().max(200).optional(),
|
|
15
|
+
colorPalette: z.string().max(200).optional(),
|
|
16
|
+
lighting: z.string().max(200).optional(),
|
|
17
|
+
cameraLanguage: z.string().max(200).optional(),
|
|
18
|
+
avoid: z.string().max(400).optional(),
|
|
19
|
+
})
|
|
20
|
+
export type StyleDirectives = z.infer<typeof StyleDirectivesSchema>
|
|
21
|
+
|
|
22
|
+
// User-configurable per-stage model overrides. Keys follow `<stage>_<kind>` so
|
|
23
|
+
// the resolver can fall back to the global `<kind>_model` field below when a
|
|
24
|
+
// stage key is absent. When neither stage nor global is set, downstream code
|
|
25
|
+
// keeps its current "LLM picks" or "hardcoded default" behavior.
|
|
26
|
+
export const PIPELINE_MODEL_STAGES = [
|
|
27
|
+
"characters_image",
|
|
28
|
+
"locations_image",
|
|
29
|
+
"objects_image",
|
|
30
|
+
"scene_keyframes_image",
|
|
31
|
+
"shots_video",
|
|
32
|
+
"script_llm",
|
|
33
|
+
] as const
|
|
34
|
+
export type PipelineModelStage = (typeof PIPELINE_MODEL_STAGES)[number]
|
|
35
|
+
const PipelineModelStageEnum = z.enum(PIPELINE_MODEL_STAGES)
|
|
36
|
+
|
|
37
|
+
// User-pinnable model identifiers. Curated allowlists — both the Zod schema
|
|
38
|
+
// AND the frontend dropdowns derive from these. Three reasons the allowlist
|
|
39
|
+
// matters even with the `model_pricing` hard-fail guard downstream:
|
|
40
|
+
// 1. Closes the unknown-ID oracle (an unknown id returns a 503 from the
|
|
41
|
+
// route, an known-but-internal id would silently 500 mid-pipeline).
|
|
42
|
+
// 2. Keeps internal-only synthetic ids (e.g. `flux-lora-character`) out of
|
|
43
|
+
// the user-pinnable surface — those should ONLY be set by the
|
|
44
|
+
// orchestrator at runtime.
|
|
45
|
+
// 3. Prevents prompt injection via raw interpolation of the override string
|
|
46
|
+
// into the Scene Director's LLM prompt — if it isn't in the enum it
|
|
47
|
+
// can't reach the prompt.
|
|
48
|
+
// Tier-restriction enforcement (free tier blocked from veo3 etc.) lives at
|
|
49
|
+
// the route level via `canAffordCredits` — see `routes/pipelines.ts`.
|
|
50
|
+
export const PIPELINE_PINNABLE_IMAGE_MODELS = [
|
|
51
|
+
"nano-banana",
|
|
52
|
+
"nano-banana-pro",
|
|
53
|
+
"nano-banana-2",
|
|
54
|
+
"flux",
|
|
55
|
+
"gpt-image",
|
|
56
|
+
"gpt-image-2",
|
|
57
|
+
] as const
|
|
58
|
+
export type PipelinePinnableImageModel = (typeof PIPELINE_PINNABLE_IMAGE_MODELS)[number]
|
|
59
|
+
|
|
60
|
+
export const PIPELINE_PINNABLE_VIDEO_MODELS = [
|
|
61
|
+
"kling-turbo",
|
|
62
|
+
"kling",
|
|
63
|
+
"kling-3.0",
|
|
64
|
+
"seedance",
|
|
65
|
+
"seedance-2",
|
|
66
|
+
"seedance-2-fast",
|
|
67
|
+
"seedance-2-mini",
|
|
68
|
+
"veo3",
|
|
69
|
+
"veo3.1",
|
|
70
|
+
"veo3_lite",
|
|
71
|
+
"minimax",
|
|
72
|
+
"hailuo-standard",
|
|
73
|
+
"wan-turbo",
|
|
74
|
+
"bytedance-lite",
|
|
75
|
+
"bytedance-pro",
|
|
76
|
+
] as const
|
|
77
|
+
export type PipelinePinnableVideoModel = (typeof PIPELINE_PINNABLE_VIDEO_MODELS)[number]
|
|
78
|
+
|
|
79
|
+
// Script LLM — Anthropic-only. The pipeline's `callLLM` is hardwired to the
|
|
80
|
+
// Anthropic SDK; picking a non-Anthropic model would 400 mid-stage and burn
|
|
81
|
+
// the upfront credit reservation. Adding GPT/Gemini support requires routing
|
|
82
|
+
// through `lib/llm-client.ts` first; until then, keep this list tight.
|
|
83
|
+
export const PIPELINE_PINNABLE_SCRIPT_LLMS = [
|
|
84
|
+
"claude-haiku-4-5",
|
|
85
|
+
"claude-sonnet-4-6",
|
|
86
|
+
"claude-opus-4-7",
|
|
87
|
+
] as const
|
|
88
|
+
export type PipelinePinnableScriptLlm = (typeof PIPELINE_PINNABLE_SCRIPT_LLMS)[number]
|
|
89
|
+
|
|
90
|
+
const ImageModelEnum = z.enum(PIPELINE_PINNABLE_IMAGE_MODELS)
|
|
91
|
+
const VideoModelEnum = z.enum(PIPELINE_PINNABLE_VIDEO_MODELS)
|
|
92
|
+
const ScriptLlmEnum = z.enum(PIPELINE_PINNABLE_SCRIPT_LLMS)
|
|
93
|
+
|
|
94
|
+
// Per-stage override map. Each stage key maps to a model id valid for its
|
|
95
|
+
// kind. Defined as a discriminated shape (instead of `Record<stage, string>`)
|
|
96
|
+
// so the type system rejects `stage_models.shots_video = "nano-banana"`.
|
|
97
|
+
const StageModelsSchema = z
|
|
98
|
+
.object({
|
|
99
|
+
characters_image: ImageModelEnum.optional(),
|
|
100
|
+
locations_image: ImageModelEnum.optional(),
|
|
101
|
+
objects_image: ImageModelEnum.optional(),
|
|
102
|
+
scene_keyframes_image: ImageModelEnum.optional(),
|
|
103
|
+
shots_video: VideoModelEnum.optional(),
|
|
104
|
+
script_llm: ScriptLlmEnum.optional(),
|
|
105
|
+
})
|
|
106
|
+
.optional()
|
|
107
|
+
|
|
108
|
+
export const PipelineConfigSchema = z.object({
|
|
109
|
+
music_enabled: z.boolean().default(true),
|
|
110
|
+
narration_enabled: z.boolean().default(true),
|
|
111
|
+
lipsync_enabled: z.boolean().default(true),
|
|
112
|
+
freecut_export_enabled: z.boolean().default(false),
|
|
113
|
+
// Phase 1C.2.1 §H — when freecut_export_enabled, choose the serialization
|
|
114
|
+
// format. JSON is the original Nodaro-flat-timeline-v1 shape; FCPXML emits
|
|
115
|
+
// an FCPXML 1.10 timeline that Final Cut Pro / DaVinci Resolve / Premiere
|
|
116
|
+
// can ingest directly. Both reuse the same in-memory timeline reduction.
|
|
117
|
+
freecut_export_format: z.enum(["json", "fcpxml"]).default("json"),
|
|
118
|
+
shot_generation_mode: z.enum(["parallel", "sequential"]).default("parallel"),
|
|
119
|
+
silent_cut_review: z.boolean().default(true),
|
|
120
|
+
// Phase 0 studio — when true, the script stage skips the critic + refine loop
|
|
121
|
+
// and pauses for the user immediately after the first draft ("critic off by
|
|
122
|
+
// default; you decide" — the user can Edit / Regenerate at the gate).
|
|
123
|
+
skip_script_critic: z.boolean().default(false),
|
|
124
|
+
// Studio — when true, the PRODUCTION stages (shot_list / scene_images) advance
|
|
125
|
+
// automatically instead of pausing for per-scene / keyframe review. The
|
|
126
|
+
// studio's control is the creative entities (script/cast/props/locations); the
|
|
127
|
+
// engine then produces the film. The final cut (post_merge) still pauses for
|
|
128
|
+
// review, and animate sub-gates (dialogue/silent-cut) still surface. Mirrors
|
|
129
|
+
// auto-mode's advance for those stages without skipping the creative gates.
|
|
130
|
+
auto_advance_production: z.boolean().default(false),
|
|
131
|
+
// Studio speed — when true, the shot-list stage does NOT auto-force sequential
|
|
132
|
+
// mode for shot continuity, so the animate stage renders all shots in parallel
|
|
133
|
+
// (~minutes vs ~an hour for a multi-shot reel). Trades continuity chaining for
|
|
134
|
+
// speed; per-shot keyframe identity still holds.
|
|
135
|
+
force_parallel_animate: z.boolean().default(false),
|
|
136
|
+
// Global model overrides — apply to every stage of the matching kind unless
|
|
137
|
+
// a more-specific entry in `stage_models` overrides it. Constrained to the
|
|
138
|
+
// pinnable allowlists above; the route handler still re-validates against
|
|
139
|
+
// tier restrictions before pipeline creation.
|
|
140
|
+
image_model: ImageModelEnum.optional(),
|
|
141
|
+
video_model: VideoModelEnum.optional(),
|
|
142
|
+
music_model: z.string().optional(),
|
|
143
|
+
script_llm: ScriptLlmEnum.optional(),
|
|
144
|
+
// Per-stage overrides. Each key is constrained to its kind's allowlist.
|
|
145
|
+
// Empty/missing key = fall back to the global field.
|
|
146
|
+
stage_models: StageModelsSchema,
|
|
147
|
+
})
|
|
148
|
+
export type PipelineConfig = z.infer<typeof PipelineConfigSchema>
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Resolve which model a given stage should use, following the precedence:
|
|
152
|
+
* 1. `config.stage_models[stage]` — user's per-stage override
|
|
153
|
+
* 2. `config.<kind>_model` (or `config.script_llm`) — user's global pick
|
|
154
|
+
* 3. `undefined` — caller falls back to its own default (LLM picks, or hardcode)
|
|
155
|
+
*
|
|
156
|
+
* Returns `undefined` (not `null`) so callers can use `??` chains cleanly.
|
|
157
|
+
*/
|
|
158
|
+
export function resolvePipelineModel(
|
|
159
|
+
config: PipelineConfig | Partial<PipelineConfig> | null | undefined,
|
|
160
|
+
stage: PipelineModelStage,
|
|
161
|
+
): string | undefined {
|
|
162
|
+
if (!config) return undefined
|
|
163
|
+
const override = config.stage_models?.[stage]
|
|
164
|
+
if (override) return override
|
|
165
|
+
if (stage === "script_llm") return config.script_llm
|
|
166
|
+
if (stage.endsWith("_video")) return config.video_model
|
|
167
|
+
if (stage.endsWith("_image")) return config.image_model
|
|
168
|
+
return undefined
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export const PipelineInputSchema = z.object({
|
|
172
|
+
pipeline_type: z.enum(PIPELINE_TYPES).default("story_to_video"),
|
|
173
|
+
workflow_id: z.string().uuid().optional(),
|
|
174
|
+
root_node_id: z.string().min(1),
|
|
175
|
+
story_prompt: z.string().min(1).max(4000),
|
|
176
|
+
target_duration_seconds: z.number().int().min(5).max(3600),
|
|
177
|
+
format: z.enum(PIPELINE_FORMATS),
|
|
178
|
+
output_resolution: z.enum(PIPELINE_OUTPUT_RESOLUTIONS).default("720p"),
|
|
179
|
+
language: z.string().min(2).max(10).default("en"),
|
|
180
|
+
mode: z.enum(PIPELINE_MODES).default("manual"),
|
|
181
|
+
// Legacy back-compat — when both `mode` and `auto_mode` present, `mode` wins.
|
|
182
|
+
auto_mode: z.boolean().optional(),
|
|
183
|
+
style_directives: StyleDirectivesSchema.optional(),
|
|
184
|
+
config: PipelineConfigSchema.partial().optional(),
|
|
185
|
+
max_cost_credits: z.number().int().positive().optional(),
|
|
186
|
+
video_critic_frame_count: z.enum(VIDEO_CRITIC_FRAME_MODES).default("first_last"),
|
|
187
|
+
})
|
|
188
|
+
export type PipelineInput = z.infer<typeof PipelineInputSchema>
|
|
189
|
+
|
|
190
|
+
// ─── Detection LLM output (LLM spec §1) ───────────────────────────────────────
|
|
191
|
+
|
|
192
|
+
export const DetectionResultSchema = z.object({
|
|
193
|
+
characters: z.array(
|
|
194
|
+
z.object({
|
|
195
|
+
key: z.string().regex(/^[a-z][a-z0-9_]{0,63}$/),
|
|
196
|
+
name: z.string(),
|
|
197
|
+
visual_description: z.string(),
|
|
198
|
+
role_hint: z.enum(["protagonist", "antagonist", "supporting", "cameo"]),
|
|
199
|
+
has_dialogue_hint: z.boolean(),
|
|
200
|
+
}),
|
|
201
|
+
),
|
|
202
|
+
objects: z.array(
|
|
203
|
+
z.object({
|
|
204
|
+
key: z.string().regex(/^[a-z][a-z0-9_]{0,63}$/),
|
|
205
|
+
name: z.string(),
|
|
206
|
+
visual_description: z.string(),
|
|
207
|
+
narrative_significance: z.string(),
|
|
208
|
+
}),
|
|
209
|
+
),
|
|
210
|
+
locations: z.array(
|
|
211
|
+
z.object({
|
|
212
|
+
key: z.string().regex(/^[a-z][a-z0-9_]{0,63}$/),
|
|
213
|
+
name: z.string(),
|
|
214
|
+
visual_description: z.string(),
|
|
215
|
+
parent_location_key: z.string().nullable(),
|
|
216
|
+
variant_kind: z
|
|
217
|
+
.enum(["main", "time_of_day", "weather", "aftermath"])
|
|
218
|
+
.nullable(),
|
|
219
|
+
}),
|
|
220
|
+
),
|
|
221
|
+
audio_intent: z.object({
|
|
222
|
+
has_narrator: z.boolean(),
|
|
223
|
+
narrator_profile_hint: z.string().nullable(),
|
|
224
|
+
dialogue_speaker_keys: z.array(z.string()),
|
|
225
|
+
music: z.object({
|
|
226
|
+
mood_hint: z.string(),
|
|
227
|
+
bpm_hint: z.number(),
|
|
228
|
+
genre_hints: z.array(z.string()),
|
|
229
|
+
}),
|
|
230
|
+
sfx_hints: z.array(z.string()),
|
|
231
|
+
}),
|
|
232
|
+
})
|
|
233
|
+
export type DetectionResult = z.infer<typeof DetectionResultSchema>
|
|
234
|
+
|
|
235
|
+
// ─── Showrunner output (LLM spec §2) ──────────────────────────────────────────
|
|
236
|
+
|
|
237
|
+
export const EMOTIONAL_BEAT = z.enum([
|
|
238
|
+
"setup",
|
|
239
|
+
"inciting",
|
|
240
|
+
"rising",
|
|
241
|
+
"tension",
|
|
242
|
+
"climax",
|
|
243
|
+
"release",
|
|
244
|
+
"denouement",
|
|
245
|
+
"reveal",
|
|
246
|
+
"shock",
|
|
247
|
+
"release_humor",
|
|
248
|
+
"reflection",
|
|
249
|
+
])
|
|
250
|
+
|
|
251
|
+
export const SceneSpecSchema = z.object({
|
|
252
|
+
scene_index: z.number().int().min(1),
|
|
253
|
+
description: z.string().max(500),
|
|
254
|
+
emotional_beat: EMOTIONAL_BEAT,
|
|
255
|
+
duration_seconds: z.number().positive(),
|
|
256
|
+
cast_keys: z.array(z.string()),
|
|
257
|
+
location_key: z.string(),
|
|
258
|
+
object_keys: z.array(z.string()),
|
|
259
|
+
dialogue: z
|
|
260
|
+
.array(
|
|
261
|
+
z.object({
|
|
262
|
+
cast_key: z.string(),
|
|
263
|
+
line: z.string().max(200),
|
|
264
|
+
}),
|
|
265
|
+
)
|
|
266
|
+
.default([]),
|
|
267
|
+
narration: z.string().nullable(),
|
|
268
|
+
continuity_from_prev: z.enum(["hard_cut", "match_last_frame", "dissolve"]),
|
|
269
|
+
shot_count_hint: z.number().int().min(1).max(8),
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
export const ShowrunnerPlanSchema = z.object({
|
|
273
|
+
title: z.string(),
|
|
274
|
+
logline: z.string().max(200),
|
|
275
|
+
target_duration_seconds: z.number().positive(),
|
|
276
|
+
format: z.enum(PIPELINE_FORMATS),
|
|
277
|
+
output_resolution: z.enum(PIPELINE_OUTPUT_RESOLUTIONS),
|
|
278
|
+
language: z.string(),
|
|
279
|
+
genre: z.enum([
|
|
280
|
+
"action",
|
|
281
|
+
"drama",
|
|
282
|
+
"thriller",
|
|
283
|
+
"comedy",
|
|
284
|
+
"horror",
|
|
285
|
+
"sci-fi",
|
|
286
|
+
"documentary",
|
|
287
|
+
]),
|
|
288
|
+
tone: z
|
|
289
|
+
.array(
|
|
290
|
+
z.enum([
|
|
291
|
+
"gritty",
|
|
292
|
+
"hopeful",
|
|
293
|
+
"tense",
|
|
294
|
+
"melancholic",
|
|
295
|
+
"playful",
|
|
296
|
+
"epic",
|
|
297
|
+
"intimate",
|
|
298
|
+
"surreal",
|
|
299
|
+
"nostalgic",
|
|
300
|
+
"urgent",
|
|
301
|
+
"dreamy",
|
|
302
|
+
"cold",
|
|
303
|
+
"warm",
|
|
304
|
+
"menacing",
|
|
305
|
+
"whimsical",
|
|
306
|
+
"somber",
|
|
307
|
+
"triumphant",
|
|
308
|
+
"eerie",
|
|
309
|
+
]),
|
|
310
|
+
)
|
|
311
|
+
.max(5),
|
|
312
|
+
cast: z
|
|
313
|
+
.array(
|
|
314
|
+
z.object({
|
|
315
|
+
key: z.string(),
|
|
316
|
+
name: z.string(),
|
|
317
|
+
role: z.enum(["protagonist", "antagonist", "supporting", "cameo"]),
|
|
318
|
+
visual_description: z.string(),
|
|
319
|
+
voice_profile: z.string(),
|
|
320
|
+
has_dialogue: z.boolean(),
|
|
321
|
+
angle_count_hint: z.number().int().min(1).max(8),
|
|
322
|
+
expression_set_hint: z
|
|
323
|
+
.array(
|
|
324
|
+
z.enum([
|
|
325
|
+
"neutral",
|
|
326
|
+
"smiling",
|
|
327
|
+
"laughing",
|
|
328
|
+
"angry",
|
|
329
|
+
"scared",
|
|
330
|
+
"determined",
|
|
331
|
+
"sad",
|
|
332
|
+
"surprised",
|
|
333
|
+
"thoughtful",
|
|
334
|
+
"crying",
|
|
335
|
+
]),
|
|
336
|
+
)
|
|
337
|
+
.max(6)
|
|
338
|
+
.default([]),
|
|
339
|
+
}),
|
|
340
|
+
)
|
|
341
|
+
.max(8),
|
|
342
|
+
locations: z
|
|
343
|
+
.array(
|
|
344
|
+
z.object({
|
|
345
|
+
key: z.string(),
|
|
346
|
+
name: z.string(),
|
|
347
|
+
visual_description: z.string(),
|
|
348
|
+
variants_needed: z.array(z.string()).default([]),
|
|
349
|
+
}),
|
|
350
|
+
)
|
|
351
|
+
.max(8),
|
|
352
|
+
objects: z
|
|
353
|
+
.array(
|
|
354
|
+
z.object({
|
|
355
|
+
key: z.string(),
|
|
356
|
+
name: z.string(),
|
|
357
|
+
visual_description: z.string(),
|
|
358
|
+
narrative_significance: z.string(),
|
|
359
|
+
}),
|
|
360
|
+
)
|
|
361
|
+
.max(10),
|
|
362
|
+
scenes: z.array(SceneSpecSchema).min(3).max(20),
|
|
363
|
+
beats: z.array(
|
|
364
|
+
z.object({
|
|
365
|
+
type: z.enum(["hook", "rising", "climax", "resolution"]),
|
|
366
|
+
scene_indices: z.array(z.number().int()),
|
|
367
|
+
}),
|
|
368
|
+
),
|
|
369
|
+
has_narrator: z.boolean(),
|
|
370
|
+
narrator_profile: z.string().nullable(),
|
|
371
|
+
/**
|
|
372
|
+
* Phase 1C.2.1 §G — optional narration_script for omniscient narrator-style
|
|
373
|
+
* formats (trailers, documentaries, retro storytelling). When present, Stage
|
|
374
|
+
* 7 sub-step 7c synthesizes a single narration audio track that spans the
|
|
375
|
+
* full pipeline duration and gets mixed over the music in the final merge
|
|
376
|
+
* (music ducks to 60% volume per spec §G5). Leave undefined for dialogue-
|
|
377
|
+
* driven scenes that don't benefit from narration.
|
|
378
|
+
*/
|
|
379
|
+
narration_script: z
|
|
380
|
+
.object({
|
|
381
|
+
text: z.string().min(20).max(4000),
|
|
382
|
+
voice_id: z.string().optional(),
|
|
383
|
+
})
|
|
384
|
+
.optional(),
|
|
385
|
+
music_plan: z.object({
|
|
386
|
+
mood: z.string(),
|
|
387
|
+
bpm_target: z.number(),
|
|
388
|
+
genre_hints: z.array(z.string()),
|
|
389
|
+
}),
|
|
390
|
+
global_style: z.object({
|
|
391
|
+
visual_style: z.string(),
|
|
392
|
+
color_palette: z.string(),
|
|
393
|
+
lighting: z.string(),
|
|
394
|
+
camera_language: z.string(),
|
|
395
|
+
}),
|
|
396
|
+
total_duration_seconds: z.number(),
|
|
397
|
+
estimated_scene_count: z.number(),
|
|
398
|
+
warnings: z.array(z.string()),
|
|
399
|
+
})
|
|
400
|
+
export type ShowrunnerPlan = z.infer<typeof ShowrunnerPlanSchema>
|
|
401
|
+
|
|
402
|
+
// ─── Critic output (LLM spec §4) ──────────────────────────────────────────────
|
|
403
|
+
|
|
404
|
+
export const CriticIssueSchema = z.object({
|
|
405
|
+
severity: z.enum(["blocking", "warning"]),
|
|
406
|
+
scene_index: z.number().int().nullable(),
|
|
407
|
+
issue_type: z.string(),
|
|
408
|
+
description: z.string(),
|
|
409
|
+
suggested_fix: z.string(),
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
export const ScriptCriticVerdictSchema = z.object({
|
|
413
|
+
verdict: z.enum(["pass", "fail"]),
|
|
414
|
+
issues: z.array(
|
|
415
|
+
CriticIssueSchema.extend({
|
|
416
|
+
issue_type: z.enum([
|
|
417
|
+
"duration",
|
|
418
|
+
"consistency",
|
|
419
|
+
"shot_count_hint",
|
|
420
|
+
"generatability",
|
|
421
|
+
"dialogue",
|
|
422
|
+
"continuity",
|
|
423
|
+
"arc",
|
|
424
|
+
]),
|
|
425
|
+
}),
|
|
426
|
+
),
|
|
427
|
+
duration_analysis: z.object({
|
|
428
|
+
target_seconds: z.number(),
|
|
429
|
+
actual_sum_seconds: z.number(),
|
|
430
|
+
deviation_percent: z.number(),
|
|
431
|
+
within_tolerance: z.boolean(),
|
|
432
|
+
}),
|
|
433
|
+
improvement_suggestions: z.array(z.string()).optional(),
|
|
434
|
+
})
|
|
435
|
+
export type ScriptCriticVerdict = z.infer<typeof ScriptCriticVerdictSchema>
|
|
436
|
+
|
|
437
|
+
export const CastCoverageCriticVerdictSchema = z.object({
|
|
438
|
+
verdict: z.enum(["pass", "fail"]),
|
|
439
|
+
issues: z.array(
|
|
440
|
+
CriticIssueSchema.extend({
|
|
441
|
+
issue_type: z.enum([
|
|
442
|
+
"orphan_cast",
|
|
443
|
+
"unresolved_ref",
|
|
444
|
+
"dialogue_load_skew",
|
|
445
|
+
"role_completeness",
|
|
446
|
+
"key_uniqueness",
|
|
447
|
+
]),
|
|
448
|
+
}),
|
|
449
|
+
),
|
|
450
|
+
dialogue_distribution: z.array(
|
|
451
|
+
z.object({
|
|
452
|
+
cast_key: z.string(),
|
|
453
|
+
line_count: z.number(),
|
|
454
|
+
share_pct: z.number(),
|
|
455
|
+
}),
|
|
456
|
+
),
|
|
457
|
+
})
|
|
458
|
+
export type CastCoverageCriticVerdict = z.infer<typeof CastCoverageCriticVerdictSchema>
|
|
459
|
+
|
|
460
|
+
export const LocationsCoverageCriticIssueSchema = CriticIssueSchema.extend({
|
|
461
|
+
issue_type: z.enum([
|
|
462
|
+
"orphan_location",
|
|
463
|
+
"unresolved_scene_location_ref",
|
|
464
|
+
"duplicate_key",
|
|
465
|
+
"name_too_similar",
|
|
466
|
+
"description_too_short",
|
|
467
|
+
"redundant_location",
|
|
468
|
+
]),
|
|
469
|
+
// `nullish()` (= `.nullable().optional()`) instead of `.optional()` —
|
|
470
|
+
// Sonnet routinely emits `"location_key": null` for issue_types like
|
|
471
|
+
// `redundant_location` that flag a structural problem without pointing
|
|
472
|
+
// at a specific key. `.optional()` only accepted `undefined`, so those
|
|
473
|
+
// emits failed Zod validation, exhausted the critic retry budget, and
|
|
474
|
+
// killed the whole Stage 1 with `locations_coverage validation failed
|
|
475
|
+
// after 2 attempts: issues.N.location_key: Expected string, received
|
|
476
|
+
// null`. Same fix already in place on `scene_index` below.
|
|
477
|
+
location_key: z.string().nullish(),
|
|
478
|
+
scene_index: z.number().int().nullish(),
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
export const LocationsCoverageCriticVerdictSchema = z.object({
|
|
482
|
+
verdict: z.enum(["pass", "fail"]),
|
|
483
|
+
issues: z.array(LocationsCoverageCriticIssueSchema),
|
|
484
|
+
})
|
|
485
|
+
export type LocationsCoverageCriticVerdict = z.infer<typeof LocationsCoverageCriticVerdictSchema>
|
|
486
|
+
|
|
487
|
+
// Phase 1D.2c-a — image-level vision critics
|
|
488
|
+
|
|
489
|
+
export const CharacterImageCriticVerdictSchema = z.object({
|
|
490
|
+
verdict: z.enum(["pass", "fail"]),
|
|
491
|
+
prompt_adherence_score: z.number().int().min(0).max(10),
|
|
492
|
+
identified_subject: z.string().min(1).max(500),
|
|
493
|
+
issues: z.array(
|
|
494
|
+
z.object({
|
|
495
|
+
severity: z.enum(["blocking", "warning"]),
|
|
496
|
+
category: z.enum([
|
|
497
|
+
"wrong_subject",
|
|
498
|
+
"wrong_attributes",
|
|
499
|
+
"visual_artifacts",
|
|
500
|
+
"style_mismatch",
|
|
501
|
+
"other",
|
|
502
|
+
]),
|
|
503
|
+
description: z.string().min(1).max(500),
|
|
504
|
+
suggested_fix: z.string().min(1).max(300),
|
|
505
|
+
}),
|
|
506
|
+
),
|
|
507
|
+
approved_summary: z.string().min(1).max(500).optional(),
|
|
508
|
+
})
|
|
509
|
+
export type CharacterImageCriticVerdict = z.infer<typeof CharacterImageCriticVerdictSchema>
|
|
510
|
+
|
|
511
|
+
export const LocationImageCriticVerdictSchema = z.object({
|
|
512
|
+
verdict: z.enum(["pass", "fail"]),
|
|
513
|
+
prompt_adherence_score: z.number().int().min(0).max(10),
|
|
514
|
+
identified_subject: z.string().min(1).max(500),
|
|
515
|
+
issues: z.array(
|
|
516
|
+
z.object({
|
|
517
|
+
severity: z.enum(["blocking", "warning"]),
|
|
518
|
+
category: z.enum([
|
|
519
|
+
"wrong_location_type",
|
|
520
|
+
"wrong_time_of_day",
|
|
521
|
+
"wrong_attributes",
|
|
522
|
+
"visual_artifacts",
|
|
523
|
+
"style_mismatch",
|
|
524
|
+
"other",
|
|
525
|
+
]),
|
|
526
|
+
description: z.string().min(1).max(500),
|
|
527
|
+
suggested_fix: z.string().min(1).max(300),
|
|
528
|
+
}),
|
|
529
|
+
),
|
|
530
|
+
approved_summary: z.string().min(1).max(500).optional(),
|
|
531
|
+
})
|
|
532
|
+
export type LocationImageCriticVerdict = z.infer<typeof LocationImageCriticVerdictSchema>
|
|
533
|
+
|
|
534
|
+
// Phase 1D.2c-b-i — Storyboard Cohesion Critic (Stage 6, warn-only)
|
|
535
|
+
|
|
536
|
+
export const StoryboardCohesionCriticVerdictSchema = z.object({
|
|
537
|
+
overall_assessment: z.enum(["coherent", "minor_issues", "incoherent"]),
|
|
538
|
+
coherence_score: z.number().int().min(0).max(10),
|
|
539
|
+
summary: z.string().min(1).max(500),
|
|
540
|
+
findings: z.array(
|
|
541
|
+
z.object({
|
|
542
|
+
severity: z.enum(["info", "warning", "blocking"]),
|
|
543
|
+
category: z.enum([
|
|
544
|
+
"character_inconsistency",
|
|
545
|
+
"location_inconsistency",
|
|
546
|
+
"lighting_mismatch",
|
|
547
|
+
"style_drift",
|
|
548
|
+
"missing_establishing_shot",
|
|
549
|
+
"plot_jump",
|
|
550
|
+
"other",
|
|
551
|
+
]),
|
|
552
|
+
affected_scenes: z.array(z.number().int().min(1)).max(20),
|
|
553
|
+
description: z.string().min(1).max(500),
|
|
554
|
+
suggested_action: z.string().min(1).max(300),
|
|
555
|
+
}),
|
|
556
|
+
).max(30),
|
|
557
|
+
})
|
|
558
|
+
export type StoryboardCohesionCriticVerdict = z.infer<typeof StoryboardCohesionCriticVerdictSchema>
|
|
559
|
+
|
|
560
|
+
// Phase 1D.2c-b-ii — Video Critic (Stage 7)
|
|
561
|
+
|
|
562
|
+
export const VideoCriticVerdictSchema = z.object({
|
|
563
|
+
verdict: z.enum(["pass", "fail"]),
|
|
564
|
+
prompt_adherence_score: z.number().int().min(0).max(10),
|
|
565
|
+
continuity_score: z.number().int().min(0).max(10).nullable(),
|
|
566
|
+
identified_action: z.string().min(1).max(500),
|
|
567
|
+
issues: z.array(
|
|
568
|
+
z.object({
|
|
569
|
+
severity: z.enum(["blocking", "warning"]),
|
|
570
|
+
category: z.enum([
|
|
571
|
+
"wrong_action",
|
|
572
|
+
"prompt_mismatch",
|
|
573
|
+
"continuity_break",
|
|
574
|
+
"visual_artifacts",
|
|
575
|
+
"motion_glitch",
|
|
576
|
+
"style_mismatch",
|
|
577
|
+
"other",
|
|
578
|
+
]),
|
|
579
|
+
description: z.string().min(1).max(500),
|
|
580
|
+
suggested_fix: z.string().min(1).max(300),
|
|
581
|
+
}),
|
|
582
|
+
).max(20),
|
|
583
|
+
approved_summary: z.string().min(1).max(500).optional(),
|
|
584
|
+
})
|
|
585
|
+
export type VideoCriticVerdict = z.infer<typeof VideoCriticVerdictSchema>
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Phase 1D.2c-b-ii — Video Critic ShotSpec sibling fields persisted by
|
|
589
|
+
* Stage 7 (scene-internal-pipeline) directly on each ShotSpec record (NOT
|
|
590
|
+
* under a nested `metadata` key). Persisting them as siblings lets the shot
|
|
591
|
+
* recovery routes update them via a JSON-Patch-style path; the shared Zod
|
|
592
|
+
* `ShotSpec` schema doesn't enumerate these because ShotSpec is an open
|
|
593
|
+
* object on the persistence path, so this interface is the single source of
|
|
594
|
+
* truth for backend + frontend consumers that need to read/write them.
|
|
595
|
+
*
|
|
596
|
+
* Persisted location:
|
|
597
|
+
* `pipeline_entities.metadata.scene_node_data.shots[N].video_critic_*`
|
|
598
|
+
*
|
|
599
|
+
* Cleared by `clearVideoCriticMetadata` (see pipeline-defaults.ts) in the
|
|
600
|
+
* retry-video-generation recovery route + the frontend Regenerate handler.
|
|
601
|
+
*/
|
|
602
|
+
export interface VideoCriticShotFields {
|
|
603
|
+
video_critic_findings?: VideoCriticVerdict["issues"]
|
|
604
|
+
video_critic_score?: number
|
|
605
|
+
video_critic_continuity_score?: number | null
|
|
606
|
+
video_critic_identified_action?: string
|
|
607
|
+
video_critic_retry_count?: number
|
|
608
|
+
video_critic_last_attempted_url?: string
|
|
609
|
+
video_critic_failed?: boolean
|
|
610
|
+
video_critic_verdict?: "pass" | "fail"
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// ─── Entity metadata (DB pipeline_entities.metadata) ──────────────────────────
|
|
614
|
+
|
|
615
|
+
export const CharacterMetadataSchema = z.object({
|
|
616
|
+
entity_type: z.literal("character"),
|
|
617
|
+
name: z.string(),
|
|
618
|
+
visual_description: z.string(),
|
|
619
|
+
role: z.enum(["protagonist", "antagonist", "supporting", "cameo"]),
|
|
620
|
+
estimated_screen_time_shots: z.number(),
|
|
621
|
+
has_dialogue: z.boolean(),
|
|
622
|
+
voice_profile: z.string().optional(),
|
|
623
|
+
angle_count: z.number().int().min(1).max(8),
|
|
624
|
+
})
|
|
625
|
+
|
|
626
|
+
export const ObjectMetadataSchema = z.object({
|
|
627
|
+
entity_type: z.literal("object"),
|
|
628
|
+
name: z.string(),
|
|
629
|
+
visual_description: z.string(),
|
|
630
|
+
narrative_significance: z.string(),
|
|
631
|
+
scenes_present: z.array(z.string()),
|
|
632
|
+
})
|
|
633
|
+
|
|
634
|
+
export const LocationMetadataSchema = z.object({
|
|
635
|
+
entity_type: z.literal("location"),
|
|
636
|
+
name: z.string(),
|
|
637
|
+
visual_description: z.string(),
|
|
638
|
+
variants_needed: z.array(z.string()),
|
|
639
|
+
})
|
|
640
|
+
|
|
641
|
+
export const EntityMetadataSchema = z.discriminatedUnion("entity_type", [
|
|
642
|
+
CharacterMetadataSchema,
|
|
643
|
+
ObjectMetadataSchema,
|
|
644
|
+
LocationMetadataSchema,
|
|
645
|
+
SceneMetadataSchema, // new in Phase 1B.2
|
|
646
|
+
])
|
|
647
|
+
export type EntityMetadata = z.infer<typeof EntityMetadataSchema>
|