@nodaro/prompts 1.0.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 +105 -0
- package/README.md +27 -0
- package/dist/index.cjs +21240 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3599 -0
- package/dist/index.d.ts +3599 -0
- package/dist/index.js +20854 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
- package/src/__tests__/__snapshots__/prompt-builder-segments.test.ts.snap +65 -0
- package/src/__tests__/action-fx.test.ts +155 -0
- package/src/__tests__/apply-picker-json.test.ts +50 -0
- package/src/__tests__/assemble-image-input.test.ts +248 -0
- package/src/__tests__/assemble-suno-input.test.ts +283 -0
- package/src/__tests__/brand-tokens.test.ts +81 -0
- package/src/__tests__/build-image-prompt-element-injection.test.ts +118 -0
- package/src/__tests__/build-image-prompt-hybrid-format.test.ts +131 -0
- package/src/__tests__/build-image-prompt-mentions.test.ts +809 -0
- package/src/__tests__/build-image-prompt-reference-cap.test.ts +57 -0
- package/src/__tests__/build-image-prompt-reference-numbering.test.ts +237 -0
- package/src/__tests__/build-image-prompt-reference-order.test.ts +313 -0
- package/src/__tests__/camera-motions-from-connections.test.ts +71 -0
- package/src/__tests__/catalog-gapfill.test.ts +53 -0
- package/src/__tests__/character-convergence-image.test.ts +217 -0
- package/src/__tests__/character-default-role-image.test.ts +167 -0
- package/src/__tests__/character-default-role-video.test.ts +168 -0
- package/src/__tests__/character-default-role.test.ts +70 -0
- package/src/__tests__/character-fx.test.ts +200 -0
- package/src/__tests__/entity-prompts-location.test.ts +97 -0
- package/src/__tests__/entity-prompts.test.ts +240 -0
- package/src/__tests__/expand-extra-refs-role.test.ts +50 -0
- package/src/__tests__/factory-presets.test.ts +1045 -0
- package/src/__tests__/factory-snippets.test.ts +68 -0
- package/src/__tests__/framing-multi.test.ts +71 -0
- package/src/__tests__/framing-vantage.test.ts +39 -0
- package/src/__tests__/i18n-entry-completeness.test.ts +269 -0
- package/src/__tests__/identity-lock.test.ts +46 -0
- package/src/__tests__/instrumentation.test.ts +68 -0
- package/src/__tests__/lighting-multi.test.ts +68 -0
- package/src/__tests__/location-convergence-image.test.ts +124 -0
- package/src/__tests__/mention-lock-flag.test.ts +499 -0
- package/src/__tests__/multi-picker-spec.test.ts +71 -0
- package/src/__tests__/music-genre.test.ts +103 -0
- package/src/__tests__/music-mood.test.ts +87 -0
- package/src/__tests__/object-creature-convergence-image.test.ts +105 -0
- package/src/__tests__/parameter-prompt-hint.test.ts +270 -0
- package/src/__tests__/parameter-registry-sync.test.ts +243 -0
- package/src/__tests__/person-age.test.ts +80 -0
- package/src/__tests__/person-analyzer-invariants.test.ts +47 -0
- package/src/__tests__/person-body-axes.test.ts +67 -0
- package/src/__tests__/person-facial-geometry.test.ts +156 -0
- package/src/__tests__/person-regional-aesthetic.test.ts +161 -0
- package/src/__tests__/person-sections.test.ts +18 -0
- package/src/__tests__/picker-analyzer-registry.test.ts +108 -0
- package/src/__tests__/picker-catalogs-project.test.ts +85 -0
- package/src/__tests__/picker-catalogs.test.ts +53 -0
- package/src/__tests__/picker-limits.test.ts +20 -0
- package/src/__tests__/prompt-builder-segments.test.ts +183 -0
- package/src/__tests__/prompt-builder-structured-fields.test.ts +40 -0
- package/src/__tests__/prompt-builder.test.ts +1773 -0
- package/src/__tests__/prompt-wizard-categories.test.ts +31 -0
- package/src/__tests__/provider-prompt-doctrine.test.ts +49 -0
- package/src/__tests__/resolve-prompt-append.test.ts +58 -0
- package/src/__tests__/resolve-prompt.test.ts +44 -0
- package/src/__tests__/role-picker-shared.test.ts +208 -0
- package/src/__tests__/seedance-2-inputs.test.ts +173 -0
- package/src/__tests__/seedance-extend.test.ts +44 -0
- package/src/__tests__/sound-aggregator.test.ts +350 -0
- package/src/__tests__/style-presets.test.ts +34 -0
- package/src/__tests__/temporal-multi.test.ts +74 -0
- package/src/__tests__/transitions.test.ts +213 -0
- package/src/__tests__/video-reference-features.test.ts +41 -0
- package/src/__tests__/video-reference-leading-refs.test.ts +90 -0
- package/src/__tests__/video-reference-resolver.test.ts +233 -0
- package/src/__tests__/video-reference-roles.test.ts +96 -0
- package/src/__tests__/voice-character.test.ts +48 -0
- package/src/__tests__/voice-delivery.test.ts +41 -0
- package/src/__tests__/wardrobe.test.ts +25 -0
- package/src/action-fx.ts +255 -0
- package/src/aesthetic.ts +435 -0
- package/src/assemble-image-input.ts +236 -0
- package/src/assemble-suno-input.ts +147 -0
- package/src/atmosphere.ts +104 -0
- package/src/backdrop.ts +131 -0
- package/src/brand-tokens.ts +154 -0
- package/src/camera-format.ts +76 -0
- package/src/camera-motions.ts +615 -0
- package/src/character-fx.ts +274 -0
- package/src/color-look.ts +103 -0
- package/src/composition-effects.ts +67 -0
- package/src/entity-prompts.ts +231 -0
- package/src/era.ts +292 -0
- package/src/exposure-settings.ts +142 -0
- package/src/factory-presets/generate-image.ts +1644 -0
- package/src/factory-presets/generate-video.ts +1116 -0
- package/src/factory-presets/index.ts +46 -0
- package/src/factory-presets/lottie-overlay.ts +166 -0
- package/src/factory-presets/motion-graphics.ts +350 -0
- package/src/factory-presets/music.ts +734 -0
- package/src/factory-presets/sfx.ts +136 -0
- package/src/factory-presets/shared-image.ts +207 -0
- package/src/factory-presets/switchx.ts +65 -0
- package/src/factory-presets/text.ts +292 -0
- package/src/factory-presets/types.ts +51 -0
- package/src/factory-presets/video-edit.ts +136 -0
- package/src/factory-presets/voice.ts +172 -0
- package/src/factory-presets.ts +2 -0
- package/src/factory-snippets/catalog.ts +105 -0
- package/src/factory-snippets/index.ts +16 -0
- package/src/factory-snippets/types.ts +33 -0
- package/src/framing.ts +634 -0
- package/src/held-prop.ts +187 -0
- package/src/identity-lock.ts +213 -0
- package/src/index.ts +66 -0
- package/src/instrumentation.ts +337 -0
- package/src/lens.ts +59 -0
- package/src/lighting.ts +229 -0
- package/src/loop-subject.ts +276 -0
- package/src/materials.ts +184 -0
- package/src/mood.ts +186 -0
- package/src/music-genre.ts +662 -0
- package/src/music-mood.ts +137 -0
- package/src/object-asset-presets.ts +81 -0
- package/src/parameter-prompt-hint.ts +281 -0
- package/src/person.ts +1368 -0
- package/src/photo-genre.ts +151 -0
- package/src/photographer.ts +612 -0
- package/src/picker-analyzer-registry.ts +374 -0
- package/src/picker-catalogs.ts +858 -0
- package/src/pose.ts +246 -0
- package/src/post-process-effects.ts +94 -0
- package/src/prompt-builder-structured-fields.ts +116 -0
- package/src/prompt-builder.ts +2964 -0
- package/src/prompt-templates.ts +50 -0
- package/src/prompt-wizard-categories.ts +334 -0
- package/src/provider-prompt-doctrine.ts +85 -0
- package/src/render-quality.ts +89 -0
- package/src/resolve-prompt.ts +120 -0
- package/src/seedance-2-inputs.ts +100 -0
- package/src/setting.ts +130 -0
- package/src/sound-aggregator.ts +241 -0
- package/src/style-presets.ts +162 -0
- package/src/style.ts +99 -0
- package/src/styling.ts +585 -0
- package/src/temporal.ts +151 -0
- package/src/transitions.ts +333 -0
- package/src/video-reference-resolver.ts +823 -0
- package/src/voice-character.ts +237 -0
- package/src/voice-delivery.ts +142 -0
- package/src/wardrobe.ts +179 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,3599 @@
|
|
|
1
|
+
import { ConnectedReference, GenericNode, GenericEdge, HintNodeLike, HintGraphContext, EntityStyle, SupportedFontName, CharacterDef, IdentityMeta, SceneData, CharacterMentionTokenInfo, LocationMentionTokenInfo, UsageMode, StyleDirectives } from '@nodaro/shared';
|
|
2
|
+
export { HintEdgeLike, HintGraphContext, HintNodeLike } from '@nodaro/shared';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Identity Lock — strength control for facial likeness preservation when a
|
|
7
|
+
* Character node's reference photo is fed into downstream generation.
|
|
8
|
+
*
|
|
9
|
+
* Real prompts seen in the wild (especially on Nano-Banana-Pro and
|
|
10
|
+
* ChatGPT-Image) explicitly write `"identitylock": "priority absolute"` /
|
|
11
|
+
* `"strictvisualfidelity": true` to clamp the face to the reference. This
|
|
12
|
+
* helper produces the equivalent natural-language clause so the rest of the
|
|
13
|
+
* stack stays unchanged.
|
|
14
|
+
*
|
|
15
|
+
* Used by:
|
|
16
|
+
* - frontend DAG executor (`workflow-editor/execute-node.ts`)
|
|
17
|
+
* - backend orchestrator (`services/workflow-engine/payload-builder.ts`)
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
type IdentityLockMode = "off" | "soft" | "strict";
|
|
21
|
+
/** Default applied when a Character node was created before the field existed. */
|
|
22
|
+
declare const DEFAULT_IDENTITY_LOCK: IdentityLockMode;
|
|
23
|
+
/**
|
|
24
|
+
* Natural-language clause for each mode. Returns an empty string for "off"
|
|
25
|
+
* (or anything unrecognised) so callers can append unconditionally.
|
|
26
|
+
*/
|
|
27
|
+
declare function getIdentityLockClause(mode: IdentityLockMode | undefined): string;
|
|
28
|
+
/** Coerce arbitrary node-data field into a valid `IdentityLockMode`. */
|
|
29
|
+
declare function toIdentityLockMode(value: unknown): IdentityLockMode;
|
|
30
|
+
/**
|
|
31
|
+
* Map a Character NODE's `identityLock` mode (off/soft/strict) → the per-reference
|
|
32
|
+
* lock shape (`{ enabled, text }`) stamped onto every `ConnectedReference` derived
|
|
33
|
+
* from that node. This is what makes the node's off/soft/strict control reach
|
|
34
|
+
* hybrid output via `buildIdentityLockLine` (below):
|
|
35
|
+
* - off → { enabled: false } (no lock line)
|
|
36
|
+
* - soft → { enabled: true, text: <soft clause> } (mild "preserve likeness")
|
|
37
|
+
* - strict → { enabled: true, text: <strict clause> }(strong "match exactly")
|
|
38
|
+
* `undefined` coerces to the runtime default (`"soft"`) via `toIdentityLockMode`,
|
|
39
|
+
* so existing nodes (which never set the field) emit the mild line in hybrid. The
|
|
40
|
+
* per-mention `~lock`/`~nolock` sentinel still overrides via `withForcedIdentityLock`.
|
|
41
|
+
*/
|
|
42
|
+
declare function characterLockToRefLock(mode: IdentityLockMode | undefined): {
|
|
43
|
+
enabled: boolean;
|
|
44
|
+
text?: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated Since Fix 4 (character @-mentions revamp) the per-image
|
|
48
|
+
* identity directive in `buildImagePrompt` — via
|
|
49
|
+
* `resolveCharacterMentions` Phase 0 and the strengthened
|
|
50
|
+
* `buildIdentityDirective` for person/character labels — already folds
|
|
51
|
+
* the identity-preservation language directly into the bulleted reference
|
|
52
|
+
* section. The global trailing clause this function used to produce is
|
|
53
|
+
* now redundant for character-wired flows, and this function only ever
|
|
54
|
+
* fired for upstream Character nodes. It now returns "" unconditionally
|
|
55
|
+
* so existing callers stay safe; remove the call sites in a follow-up
|
|
56
|
+
* cleanup, then this helper, `IdentityLockMode`, and `getIdentityLockClause`
|
|
57
|
+
* can be retired.
|
|
58
|
+
*/
|
|
59
|
+
declare function collectIdentityLockClause<N extends GenericNode, E extends GenericEdge>(_nodeId: string, _nodes: readonly N[], _edges: readonly E[]): string;
|
|
60
|
+
/**
|
|
61
|
+
* Return `true` when any Character node is upstream of `nodeId` (walking
|
|
62
|
+
* through pass-through types). Used to short-circuit
|
|
63
|
+
* `collectIdentityLockClause`: with the new per-image identity directives
|
|
64
|
+
* (Fix 4) the global trailing clause is redundant for character-wired flows.
|
|
65
|
+
*
|
|
66
|
+
* Non-character wired-image refs still get the global clause.
|
|
67
|
+
*/
|
|
68
|
+
declare function hasUpstreamCharacter<N extends GenericNode, E extends GenericEdge>(nodeId: string, nodes: readonly N[], edges: readonly E[], visited?: Set<string>): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* The identity-lock line for a reference, or `null` when the lock is off.
|
|
71
|
+
* Opt-in only: a line is returned ONLY when `identityLock.enabled === true`
|
|
72
|
+
* (absent or `enabled === false` → `null`). Custom `text` wins (with `{ref}` →
|
|
73
|
+
* binding); otherwise the source's built-in wording is used.
|
|
74
|
+
*/
|
|
75
|
+
/**
|
|
76
|
+
* Apply a per-mention identity-lock OVERRIDE to `ref` — the tri-state
|
|
77
|
+
* `~lock` / `~nolock` sentinel (Unified Reference Roles, Task 4 + F4). The
|
|
78
|
+
* `lockOverride` argument is the token's parsed `lock`:
|
|
79
|
+
* - `undefined` → INHERIT: the ORIGINAL ref is returned UNCHANGED (never a
|
|
80
|
+
* copy), so a lock-less mention resolves byte-identically to before and the
|
|
81
|
+
* ref/source default governs.
|
|
82
|
+
* - `true` → FORCE ON: `identityLock.enabled = true` (any existing custom
|
|
83
|
+
* `text` is preserved) — the `~lock` sentinel.
|
|
84
|
+
* - `false` → FORCE OFF: `identityLock.enabled = false`, which
|
|
85
|
+
* `buildIdentityLockLine` renders as `null`, SUPPRESSING even a ref-level
|
|
86
|
+
* `identityLock.enabled = true` — the `~nolock` sentinel.
|
|
87
|
+
* Called by the three HYBRID mention resolvers right before
|
|
88
|
+
* `buildIdentityLockLine`. Never mutates `ref`.
|
|
89
|
+
*/
|
|
90
|
+
declare function withForcedIdentityLock(ref: ConnectedReference, lockOverride?: boolean): ConnectedReference;
|
|
91
|
+
declare function buildIdentityLockLine(ref: ConnectedReference, binding: string): string | null;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Dispatch by parameter-node type to its prompt-hint string. For camera-motion,
|
|
95
|
+
* pass `ctx` to include the composed start/end clauses; otherwise only the
|
|
96
|
+
* bare motion description is returned.
|
|
97
|
+
*/
|
|
98
|
+
declare function getParameterPromptHint(node: HintNodeLike | undefined, ctx?: HintGraphContext): string;
|
|
99
|
+
|
|
100
|
+
interface CharacterPromptInput {
|
|
101
|
+
name: string;
|
|
102
|
+
description?: string;
|
|
103
|
+
gender?: string;
|
|
104
|
+
style?: EntityStyle | string;
|
|
105
|
+
baseOutfit?: string;
|
|
106
|
+
}
|
|
107
|
+
declare function buildCharacterPrompt(input: CharacterPromptInput): string;
|
|
108
|
+
interface ObjectPromptInput {
|
|
109
|
+
name: string;
|
|
110
|
+
description?: string;
|
|
111
|
+
category?: string;
|
|
112
|
+
style?: EntityStyle | string;
|
|
113
|
+
}
|
|
114
|
+
declare function buildObjectPrompt(input: ObjectPromptInput): string;
|
|
115
|
+
interface CreaturePromptInput {
|
|
116
|
+
name: string;
|
|
117
|
+
description?: string;
|
|
118
|
+
/** Free-text species/type (e.g. "dragon", "wolf") — the creature delta vs object. */
|
|
119
|
+
species?: string;
|
|
120
|
+
category?: string;
|
|
121
|
+
style?: EntityStyle | string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Creature establishing-shot prompt. Mirrors {@link buildObjectPrompt} but leads
|
|
125
|
+
* with the free-text `species` (a dragon/wolf/etc. IS the subject) and frames the
|
|
126
|
+
* subject as a living creature rather than a product. Falls back to "creature"
|
|
127
|
+
* when no species is given so the prompt always names a subject.
|
|
128
|
+
*/
|
|
129
|
+
declare function buildCreaturePrompt(input: CreaturePromptInput): string;
|
|
130
|
+
interface LocationPromptInput {
|
|
131
|
+
name: string;
|
|
132
|
+
description?: string;
|
|
133
|
+
category?: string;
|
|
134
|
+
style?: EntityStyle | string;
|
|
135
|
+
}
|
|
136
|
+
declare function buildLocationPrompt(input: LocationPromptInput): string;
|
|
137
|
+
interface LocationRefinePromptInput {
|
|
138
|
+
/**
|
|
139
|
+
* The user's TRANSIENT edit/refine instruction (e.g. "make it night, add
|
|
140
|
+
* drifting fog"). Used only to build this one generation's prompt - it is
|
|
141
|
+
* never written back to the location row, so the stored name / description /
|
|
142
|
+
* canonical description stay untouched. This is the deliberate contrast with
|
|
143
|
+
* `LocationPromptInput.description`, which IS the persisted scene description
|
|
144
|
+
* that `buildLocationPrompt` weaves in.
|
|
145
|
+
*/
|
|
146
|
+
editPrompt: string;
|
|
147
|
+
style?: EntityStyle | string;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Build a TRANSIENT prompt from a user-supplied edit/refine instruction.
|
|
151
|
+
*
|
|
152
|
+
* Used by `POST /v1/generate-location` when the caller passes `userPrompt`
|
|
153
|
+
* (the studio's "describe changes" / sparkle Edit flow). Paired with an i2i
|
|
154
|
+
* `sourceImageUrl` the provider edits the source establishing shot toward the
|
|
155
|
+
* instruction; with no source image it reads as a from-scratch custom scene
|
|
156
|
+
* prompt. Mirrors `characters.generate`'s seed/edit-prompt path, but locations
|
|
157
|
+
* have no stored seed prompt - this output is purely transient and the route
|
|
158
|
+
* persists nothing derived from it back to the row.
|
|
159
|
+
*/
|
|
160
|
+
declare function buildLocationRefinePrompt(input: LocationRefinePromptInput): string;
|
|
161
|
+
interface FacePromptInput {
|
|
162
|
+
name: string;
|
|
163
|
+
description?: string;
|
|
164
|
+
style?: EntityStyle | string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Face prompt uses the "face-generation" template (resolved via prompt-templates.ts).
|
|
168
|
+
* Returns the template inputs so callers can call resolveTemplate + applyTemplate.
|
|
169
|
+
*/
|
|
170
|
+
declare function buildFaceTemplateInputs(input: FacePromptInput): {
|
|
171
|
+
description: string;
|
|
172
|
+
style: string;
|
|
173
|
+
};
|
|
174
|
+
interface CharacterMotionPromptInput {
|
|
175
|
+
name: string;
|
|
176
|
+
description?: string;
|
|
177
|
+
gender?: string;
|
|
178
|
+
style?: EntityStyle | string;
|
|
179
|
+
baseOutfit?: string;
|
|
180
|
+
motionPrompt: string;
|
|
181
|
+
}
|
|
182
|
+
declare function buildMotionPrompt(input: CharacterMotionPromptInput): string;
|
|
183
|
+
/**
|
|
184
|
+
* Input shape for buildLocationMotionPrompt.
|
|
185
|
+
*
|
|
186
|
+
* Mirrors CharacterMotionPromptInput's role. `canonicalDescription` is preferred
|
|
187
|
+
* (LLM-authored from the approved main image) but the helper falls back to
|
|
188
|
+
* category+name if not yet set, and to a generic placeholder if both are absent.
|
|
189
|
+
*/
|
|
190
|
+
interface LocationMotionPromptInput {
|
|
191
|
+
name: string;
|
|
192
|
+
category?: string;
|
|
193
|
+
style?: EntityStyle | string;
|
|
194
|
+
motionPrompt: string;
|
|
195
|
+
canonicalDescription?: string;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Build the prompt sent to the i2v provider for a location atmosphere clip.
|
|
199
|
+
*
|
|
200
|
+
* Note: character's analog is named `buildMotionPrompt` (historical); location
|
|
201
|
+
* uses the more specific `buildLocationMotionPrompt`.
|
|
202
|
+
*/
|
|
203
|
+
declare function buildLocationMotionPrompt(input: LocationMotionPromptInput): string;
|
|
204
|
+
/**
|
|
205
|
+
* Object asset-type enum — the kinds of variant a user can generate off an
|
|
206
|
+
* object's anchor main image. Mirrors the literal accepted by
|
|
207
|
+
* `POST /v1/generate-object-asset` (`backend/src/routes/generate-object-asset.ts`)
|
|
208
|
+
* and consumed by the MCP `generate_object` verb (kind="asset").
|
|
209
|
+
*
|
|
210
|
+
* The `motion` value is reserved for type-system exhaustiveness on the
|
|
211
|
+
* frontend; the route rejects it because motion variants flow through the
|
|
212
|
+
* dedicated `/v1/generate-object-motion` endpoint (worker-side it's a different
|
|
213
|
+
* BullMQ job type). `custom` is the free-form bucket — callers must supply
|
|
214
|
+
* `attachToColumn` explicitly since the worker can't infer it.
|
|
215
|
+
*/
|
|
216
|
+
interface ObjectMotionPromptInput {
|
|
217
|
+
name: string;
|
|
218
|
+
category?: string;
|
|
219
|
+
style?: EntityStyle | string;
|
|
220
|
+
motionPrompt: string;
|
|
221
|
+
canonicalDescription?: string;
|
|
222
|
+
seedPromptHint?: string;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Build the prompt sent to the i2v provider for an object atmosphere/motion clip.
|
|
226
|
+
*
|
|
227
|
+
* Naming note: character's analog is `buildMotionPrompt`; location uses
|
|
228
|
+
* `buildLocationMotionPrompt`; object uses `buildObjectMotionPrompt` to make
|
|
229
|
+
* the entity type explicit at call sites.
|
|
230
|
+
*
|
|
231
|
+
* The `seedPromptHint` is appended verbatim — Phase C's route layer composes
|
|
232
|
+
* wired-picker hints (Material/Animal/Vehicle/Weapon/Furniture) into this
|
|
233
|
+
* field before passing the input. Empty hint = no-op (the trailing dot still
|
|
234
|
+
* reads cleanly: "...motion. " not "...motion. .").
|
|
235
|
+
*/
|
|
236
|
+
declare function buildObjectMotionPrompt(input: ObjectMotionPromptInput): string;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Brand layer (Phase 3a). A pragmatic brand-token set — palette + fonts + logo —
|
|
240
|
+
* authored/selected ONCE and threaded through the shot-sequence pipeline as
|
|
241
|
+
* defaults. Preset palettes are adapted from HyperFrames' Apache-2.0
|
|
242
|
+
* `hyperframes-creative/frame-presets`, re-grounded on SUPPORTED_FONT_NAMES.
|
|
243
|
+
*/
|
|
244
|
+
interface BrandPalette {
|
|
245
|
+
/** Canvas background. */
|
|
246
|
+
bg: string;
|
|
247
|
+
/** Secondary surface (cards/panels). Carried for forward-compat; unconsumed in 3a. */
|
|
248
|
+
bgAlt?: string;
|
|
249
|
+
/** Primary on-bg text. */
|
|
250
|
+
text: string;
|
|
251
|
+
/** Secondary text. Carried for forward-compat; unconsumed in 3a. */
|
|
252
|
+
textMuted?: string;
|
|
253
|
+
/** Primary accent — the brand color. */
|
|
254
|
+
accent: string;
|
|
255
|
+
/** Secondary accent. Carried for forward-compat; unconsumed in 3a. */
|
|
256
|
+
accent2?: string;
|
|
257
|
+
/** Hairline/divider. Carried for forward-compat; unconsumed in 3a. */
|
|
258
|
+
line?: string;
|
|
259
|
+
}
|
|
260
|
+
type BrandCasing = "uppercase" | "lowercase" | "none";
|
|
261
|
+
interface BrandTypeSpec {
|
|
262
|
+
/** CSS font-weight. MUST be a weight loaded for the role's font (guarded in remotion). */
|
|
263
|
+
weight?: number;
|
|
264
|
+
/** absent => inherit call-site; "none" => force no transform; else force that transform. */
|
|
265
|
+
casing?: BrandCasing;
|
|
266
|
+
/** letter-spacing in em; suppressed for Arabic at render time. */
|
|
267
|
+
tracking?: number;
|
|
268
|
+
}
|
|
269
|
+
interface BrandFonts {
|
|
270
|
+
heading: SupportedFontName;
|
|
271
|
+
body: SupportedFontName;
|
|
272
|
+
headingType?: BrandTypeSpec;
|
|
273
|
+
bodyType?: BrandTypeSpec;
|
|
274
|
+
}
|
|
275
|
+
interface BrandLogo {
|
|
276
|
+
name: string;
|
|
277
|
+
tagline?: string;
|
|
278
|
+
/** Optional logo image — an https URL on an allowlisted Nodaro-CDN host (v1: URL only; obtain from the upload tools). */
|
|
279
|
+
image?: string;
|
|
280
|
+
/** Optional hex color for a rounded panel rendered behind the logo. */
|
|
281
|
+
imageBackdrop?: string;
|
|
282
|
+
}
|
|
283
|
+
interface BrandTokens {
|
|
284
|
+
palette: BrandPalette;
|
|
285
|
+
fonts: BrandFonts;
|
|
286
|
+
logo?: BrandLogo;
|
|
287
|
+
}
|
|
288
|
+
interface BrandPresetMeta {
|
|
289
|
+
id: BrandPresetId;
|
|
290
|
+
label: string;
|
|
291
|
+
mood: string;
|
|
292
|
+
description: string;
|
|
293
|
+
}
|
|
294
|
+
type BrandPresetId = "midnight-violet" | "editorial-cream" | "cobalt-corporate" | "sandstone-warm" | "poster-contrast" | "mono-slate" | "vibrant-pulse" | "pastel-calm";
|
|
295
|
+
declare const BRAND_PRESET_IDS: readonly BrandPresetId[];
|
|
296
|
+
declare const BRAND_PRESETS: Record<BrandPresetId, BrandTokens>;
|
|
297
|
+
declare const BRAND_PRESET_META: Record<BrandPresetId, BrandPresetMeta>;
|
|
298
|
+
/** Resolve a preset-name string OR an inline BrandTokens object to BrandTokens. */
|
|
299
|
+
declare function resolveBrandInput(brand: string | BrandTokens): BrandTokens;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Image prompt assembly logic shared between frontend and backend.
|
|
303
|
+
* Handles character description expansion, style appending, negative prompt routing,
|
|
304
|
+
* provider-aware prompt truncation (default 5000 chars), and reference image filtering by model support.
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
interface ResolveCharacterMentionsResult {
|
|
308
|
+
/** Prompt with @-tokens replaced by display names + "Use these characters:" directive prepended. */
|
|
309
|
+
prompt: string;
|
|
310
|
+
/** Resolved URLs from matched mention tokens, in mention order, deduped via caller responsibility. */
|
|
311
|
+
additionalUrls: string[];
|
|
312
|
+
/**
|
|
313
|
+
* Set of character slugs that had at least one resolved mention token.
|
|
314
|
+
* Callers use this to gate the per-character "no mention → canonical
|
|
315
|
+
* fallback" behavior so a wired character with no `@-mention` still gets
|
|
316
|
+
* its canonical URL attached (existing pre-mention-feature behavior).
|
|
317
|
+
*/
|
|
318
|
+
mentionedCharacterSlugs: Set<string>;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Resolve @-mention tokens in a prompt against connected references.
|
|
322
|
+
* Returns: augmented prompt (with directives prepended + tokens replaced
|
|
323
|
+
* by character display names) and the set of asset URLs to include as refs.
|
|
324
|
+
*
|
|
325
|
+
* Behavior:
|
|
326
|
+
* - Build two lookup Maps: `bySlug` for canonical entries, `byVariant` for variant entries.
|
|
327
|
+
* - Iterate tokens left-to-right so directives are emitted in mention order.
|
|
328
|
+
* - For each token, prefer the variant match when variantSlug present; fall back to canonical.
|
|
329
|
+
* - `charactersSeen` Set guards the long canonical description to appear AT MOST ONCE
|
|
330
|
+
* per character even when the character is mentioned in several tokens.
|
|
331
|
+
* - Build a `replacements` array (token + offset + replacement display name) and
|
|
332
|
+
* apply right-to-left so earlier replacements do not shift later offsets.
|
|
333
|
+
* - Prepend a "Use these characters:\n…" directive section when any directives were emitted.
|
|
334
|
+
* - Each directive bullet leads with the user-visible `Image N (Name)` index pulled
|
|
335
|
+
* directly from the typed token (e.g. `@kira:1:smile` → `Image 1 (Kira)`).
|
|
336
|
+
* This lets the user trace a literal slug in the prompt to its appearance in
|
|
337
|
+
* the final assembled identity-directive block.
|
|
338
|
+
*/
|
|
339
|
+
declare function resolveCharacterMentions(prompt: string, tokens: readonly CharacterMentionTokenInfo[], refs: readonly ConnectedReference[]): ResolveCharacterMentionsResult;
|
|
340
|
+
interface ResolveLocationMentionsResult {
|
|
341
|
+
/** Prompt with `@location:N` tokens replaced by display names + a
|
|
342
|
+
* "Use these locations:" directive prepended when at least one bullet
|
|
343
|
+
* fires. */
|
|
344
|
+
prompt: string;
|
|
345
|
+
/** Resolved URLs from matched mention tokens, in mention order. Caller
|
|
346
|
+
* is responsible for deduping against the existing URL list (the same
|
|
347
|
+
* contract as `resolveCharacterMentions.additionalUrls`). */
|
|
348
|
+
additionalUrls: string[];
|
|
349
|
+
/** Set of location slugs that had at least one resolved mention. Callers
|
|
350
|
+
* use this to gate "no mention → canonical fallback" behavior (mirrors
|
|
351
|
+
* the character flow — Phase 2 #1 attached the canonical URL via
|
|
352
|
+
* `expandWiredLocationRefs` directly, but a future fallback path may
|
|
353
|
+
* use this set to suppress the canonical URL once the user has explicitly
|
|
354
|
+
* pinned a variant via @-mention). */
|
|
355
|
+
mentionedLocationSlugs: Set<string>;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Resolve `@oldlibrary:1:weather/rain` mentions in the prompt against the
|
|
359
|
+
* pre-expanded `wired-location` ConnectedReferences (from
|
|
360
|
+
* `expandWiredLocationRefs` / `expandLocationNodeIntoRefs`). Mirrors
|
|
361
|
+
* `resolveCharacterMentions` shape:
|
|
362
|
+
*
|
|
363
|
+
* 1. Look up the matching ref by `(locationSlug, bucket, variantSlug)`.
|
|
364
|
+
* 2. Append its URL to `additionalUrls`.
|
|
365
|
+
* 3. Substitute the inline token with the location's display name (or
|
|
366
|
+
* `Image N` for "none" mode — image attached without textual bias).
|
|
367
|
+
* 4. Emit a directive bullet under "Use these locations:" header, with
|
|
368
|
+
* mode-specific verb. "none" mode suppresses the bullet (just like
|
|
369
|
+
* character "none").
|
|
370
|
+
*
|
|
371
|
+
* Per-location single-bullet rule: each location emits AT MOST ONE bullet
|
|
372
|
+
* (the first non-none mention "claims" the slot). Subsequent mentions of the
|
|
373
|
+
* same location still produce inline substitution + URL but no additional
|
|
374
|
+
* bullet, mirroring `resolveCharacterMentions.firstBulletEmittedFor`.
|
|
375
|
+
*
|
|
376
|
+
* Returns `additionalUrls` deduplication is the caller's responsibility,
|
|
377
|
+
* matching the character contract.
|
|
378
|
+
*/
|
|
379
|
+
declare function resolveLocationMentions(prompt: string, tokens: readonly LocationMentionTokenInfo[], refs: readonly ConnectedReference[]): ResolveLocationMentionsResult;
|
|
380
|
+
/**
|
|
381
|
+
* Reorder URLs by `referenceOrder` AND renumber `Image N` tokens in the
|
|
382
|
+
* prompt to match. Returns the new URL list + the rewritten prompt. When
|
|
383
|
+
* `referenceOrder` is empty / null / all-stale, the original URLs + prompt
|
|
384
|
+
* are returned unchanged (no-op contract).
|
|
385
|
+
*
|
|
386
|
+
* Renumbering rule: build an `original-pos → new-pos` map from the URL move
|
|
387
|
+
* indices, then regex-replace `Image N` substrings (word-boundary-anchored
|
|
388
|
+
* so we don't touch "Image 12" while remapping "Image 1"). Done in one pass
|
|
389
|
+
* via a callback that looks up each match in the map; unknown positions are
|
|
390
|
+
* left as-is.
|
|
391
|
+
*
|
|
392
|
+
* NB: `findCharacterMentionTokens` is already applied BEFORE this step, so
|
|
393
|
+
* any `@kira:1:smile` literals in the prompt have been replaced with display
|
|
394
|
+
* names — only positional `Image N` markers remain to be remapped.
|
|
395
|
+
*
|
|
396
|
+
* Exposed (non-export internal) — also called by video branches in
|
|
397
|
+
* payload-builder / execute-node via `applyReferenceOrderToVideo` so video
|
|
398
|
+
* prompts honor the same reorder semantics as image prompts.
|
|
399
|
+
*/
|
|
400
|
+
declare function applyReferenceOrderToVideo(urls: readonly string[], prompt: string | undefined, refs: readonly ConnectedReference[], referenceOrder: readonly string[] | undefined, sourceNodeIdById?: ReadonlyMap<string, string>,
|
|
401
|
+
/**
|
|
402
|
+
* Number of LEADING reference images (e.g. plain image-refs that precede the
|
|
403
|
+
* asset URLs in the unified `@image_N` numbering — see
|
|
404
|
+
* `resolveVideoReferenceCore`'s `leadingRefUrls`). `urls` here are the ASSET
|
|
405
|
+
* URLs only; their prompt ordinals are `ordinalOffset + 1 …`, so the renumber
|
|
406
|
+
* remap is keyed by the offset ordinal and leading ordinals (`1 … offset`)
|
|
407
|
+
* pass through untouched. Defaults to 0 → behaviour unchanged.
|
|
408
|
+
*/
|
|
409
|
+
ordinalOffset?: number): {
|
|
410
|
+
urls: string[];
|
|
411
|
+
prompt: string | undefined;
|
|
412
|
+
};
|
|
413
|
+
interface BuildImagePromptConfig {
|
|
414
|
+
/** Raw user prompt text */
|
|
415
|
+
prompt: string;
|
|
416
|
+
/** Image provider key (e.g. "nano-banana", "gpt-image") */
|
|
417
|
+
provider: string;
|
|
418
|
+
/** Style text to append (e.g. "cinematic") */
|
|
419
|
+
style?: string;
|
|
420
|
+
/** Negative prompt text */
|
|
421
|
+
negativePrompt?: string;
|
|
422
|
+
/** Character definitions selected for this node */
|
|
423
|
+
characterDefs?: CharacterDef[];
|
|
424
|
+
/** User-level prompt template overrides */
|
|
425
|
+
userTemplates?: Record<string, string>;
|
|
426
|
+
/** Flow-level prompt template overrides */
|
|
427
|
+
flowTemplates?: Record<string, string>;
|
|
428
|
+
/** Reference image URLs from direct connections, extracted refs, and character refs */
|
|
429
|
+
referenceImageUrls?: string[];
|
|
430
|
+
/** Ancestor reference image URLs (fallback when no direct refs exist) */
|
|
431
|
+
ancestorRefs?: string[];
|
|
432
|
+
/**
|
|
433
|
+
* Rich connected-reference data. When provided, supersedes `characterDefs`
|
|
434
|
+
* and `referenceImageUrls`: per-identity directives come from this list +
|
|
435
|
+
* any `{image:N:label}` mentions in the prompt, URLs come from this list
|
|
436
|
+
* in order, and tokens expand to "the {label} from image {N}".
|
|
437
|
+
*/
|
|
438
|
+
connectedReferences?: ConnectedReference[];
|
|
439
|
+
/** Per-identity (imageIndex+label) user overrides for fidelity / custom text. */
|
|
440
|
+
identityMeta?: readonly IdentityMeta[];
|
|
441
|
+
/**
|
|
442
|
+
* Reference-prompt assembly format for the `{image:N:label}` connected-
|
|
443
|
+
* reference (non-character) path. Additive + opt-in:
|
|
444
|
+
* - "legacy" (default): the "Use these references:/Compose them naturally:"
|
|
445
|
+
* wrap with numeric `Image N` directives — unchanged behavior.
|
|
446
|
+
* - "hybrid": token expansion only — every `{image:N:label}` token → "the
|
|
447
|
+
* <label> from reference image <LETTER>". NO lock snippet is auto-injected
|
|
448
|
+
* (authors prepend their own). Images-only for now; characters/objects/
|
|
449
|
+
* locations still render legacy. v1 skips `referenceOrder` renumbering.
|
|
450
|
+
*/
|
|
451
|
+
referenceFormat?: "legacy" | "hybrid";
|
|
452
|
+
/**
|
|
453
|
+
* OPTIONAL reference-lock snippet to prepend ahead of the hybrid scene. Only
|
|
454
|
+
* used when `referenceFormat === "hybrid"`. Nothing is prepended by default —
|
|
455
|
+
* authors include their own lock snippet in the prompt text. Provide this only
|
|
456
|
+
* if a caller wants to auto-prepend a lock.
|
|
457
|
+
*/
|
|
458
|
+
referenceLockSnippet?: string;
|
|
459
|
+
/**
|
|
460
|
+
* User-defined reorder of the injected reference list. Each entry is a
|
|
461
|
+
* stable tile ID using the scheme from `compute-injected-refs.ts`:
|
|
462
|
+
* - `wired:<sourceNodeId>` (a wired upstream — manual / wired-image /
|
|
463
|
+
* wired-face / wired-object / wired-location / extra-ref)
|
|
464
|
+
* - `mention:<characterSlug>:<variantSlug|canonical>` (an `@-mention`
|
|
465
|
+
* resolved to a character variant URL)
|
|
466
|
+
* - `char-canonical:<characterSlug>` (the auto-attached canonical
|
|
467
|
+
* fallback for a wired character that the user did NOT `@-mention`)
|
|
468
|
+
*
|
|
469
|
+
* Behavior: after the existing assembly produces a URL list + a prompt
|
|
470
|
+
* with `Image N` directives, the URLs are re-ordered to match this list
|
|
471
|
+
* AND every `Image N` token in the prompt is renumbered consistently
|
|
472
|
+
* (so directive bullets, the user's typed `Image N` references, and the
|
|
473
|
+
* worker `referenceImageUrls` index all agree).
|
|
474
|
+
*
|
|
475
|
+
* IDs in this array that don't match any tile are silently dropped. Tiles
|
|
476
|
+
* whose ID is NOT in this array fall to the end in their natural order.
|
|
477
|
+
* Identical fixtures on frontend + backend MUST produce identical URL
|
|
478
|
+
* lists — the helper is shared via `compute-injected-refs.ts`.
|
|
479
|
+
*
|
|
480
|
+
* Stable-ID-per-URL mapping for the post-assembly re-order is computed
|
|
481
|
+
* from `connectedReferences` + the user's prompt; passing `referenceOrder`
|
|
482
|
+
* is a no-op when `connectedReferences` is missing (legacy path).
|
|
483
|
+
*
|
|
484
|
+
* Optional, omit to keep the existing natural order.
|
|
485
|
+
*/
|
|
486
|
+
referenceOrder?: readonly string[];
|
|
487
|
+
/**
|
|
488
|
+
* Map of `connectedReferences[i].id → sourceNodeId` so wired-raw tile IDs
|
|
489
|
+
* match the upstream node IDs the consumer panel exposes. When omitted, the
|
|
490
|
+
* builder falls back to `connectedReferences[i].id` (which equals the
|
|
491
|
+
* upstream node ID for wired entries built by the existing image-configs +
|
|
492
|
+
* payload-builder flow).
|
|
493
|
+
*/
|
|
494
|
+
sourceNodeIdById?: ReadonlyMap<string, string>;
|
|
495
|
+
/**
|
|
496
|
+
* Character slugs whose canonical-fallback the user has explicitly hidden
|
|
497
|
+
* via the × button. Mention URLs for the same character still attach.
|
|
498
|
+
*/
|
|
499
|
+
suppressedCanonicalCharacterIds?: readonly string[];
|
|
500
|
+
/**
|
|
501
|
+
* Location slugs (or DB ids) whose canonical-fallback the user has hidden
|
|
502
|
+
* via the × button. Mirrors `suppressedCanonicalCharacterIds`: the upstream
|
|
503
|
+
* `wired-location` ref still attaches, but the canonical establishing-shot
|
|
504
|
+
* URL is dropped from the injected reference list.
|
|
505
|
+
*
|
|
506
|
+
* NOTE (Phase 1A): the location canonical-fallback path is wired up in a
|
|
507
|
+
* follow-up PR (`injected-reference-helpers.ts`). Until then, this
|
|
508
|
+
* parameter is accepted but inert — callers can pass it through without
|
|
509
|
+
* any behavior change. Once the canonical-fallback logic lands, the
|
|
510
|
+
* builder will filter `connectedReferences` with `source === "wired-location"`
|
|
511
|
+
* and a matching slug, exactly like the character path does.
|
|
512
|
+
*/
|
|
513
|
+
suppressedCanonicalLocationIds?: readonly string[];
|
|
514
|
+
/**
|
|
515
|
+
* When true, skip the entire mention-resolution block (character identity
|
|
516
|
+
* directives, `Image N (Kira)` bullets, additional ref URLs from
|
|
517
|
+
* `connectedReferences`) AND strip raw `@slug[:V[:variant]]` tokens from
|
|
518
|
+
* the prompt. Used by the LoRA inference path
|
|
519
|
+
* (`flux-lora-character`) — the trigger word + LoRA carries identity, so
|
|
520
|
+
* the directive bullets are redundant and the wired-character refs
|
|
521
|
+
* shouldn't be injected as `Image N`.
|
|
522
|
+
*/
|
|
523
|
+
skipCharacterMentions?: boolean;
|
|
524
|
+
}
|
|
525
|
+
interface BuildImagePromptResult {
|
|
526
|
+
/** Final assembled prompt */
|
|
527
|
+
prompt: string;
|
|
528
|
+
/** Native negative prompt (only for models that support it), undefined otherwise */
|
|
529
|
+
nativeNegativePrompt: string | undefined;
|
|
530
|
+
/** Filtered reference image URLs (only for models that support them) */
|
|
531
|
+
referenceImageUrls: string[] | undefined;
|
|
532
|
+
}
|
|
533
|
+
type PromptSegmentOrigin = "user" | "variable" | "picker" | "mention" | "style" | "negative";
|
|
534
|
+
interface PromptSegment {
|
|
535
|
+
readonly text: string;
|
|
536
|
+
readonly origin: PromptSegmentOrigin;
|
|
537
|
+
}
|
|
538
|
+
interface BuildImagePromptSegmentsResult extends BuildImagePromptResult {
|
|
539
|
+
/** Origin-tagged decomposition of `prompt`. INVARIANT (tested):
|
|
540
|
+
* segments.map(s => s.text).join("") === prompt. */
|
|
541
|
+
segments: PromptSegment[];
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Build the final image generation prompt from config.
|
|
545
|
+
* Handles character description wrapping, style appending, negative prompt routing,
|
|
546
|
+
* truncation, and reference image filtering.
|
|
547
|
+
*
|
|
548
|
+
* Thin passthrough over `buildImagePromptInternal` — byte-identical behavior,
|
|
549
|
+
* no marks captured. Use `buildImagePromptSegments` when you also need the
|
|
550
|
+
* origin-tagged decomposition.
|
|
551
|
+
*/
|
|
552
|
+
declare function buildImagePrompt(config: BuildImagePromptConfig): BuildImagePromptResult;
|
|
553
|
+
/**
|
|
554
|
+
* `buildImagePrompt` plus an origin-tagged decomposition of the assembled
|
|
555
|
+
* `prompt`. The string output (and all other fields) is byte-identical to
|
|
556
|
+
* `buildImagePrompt` — the segments are derived from assembly marks recorded
|
|
557
|
+
* during the same pass.
|
|
558
|
+
*
|
|
559
|
+
* ABSOLUTE INVARIANT (tested): `segments.map(s => s.text).join("") === prompt`.
|
|
560
|
+
* Anything the marks can't model — `{image:N}` token expansion, `referenceOrder`
|
|
561
|
+
* renumbering, mid-string Phase-0 directive splicing, truncation — breaks the
|
|
562
|
+
* join, and we collapse to a single `user` segment rather than ship a wrong
|
|
563
|
+
* decomposition. Callers pass `bodySegments` (origins user/variable/picker/…)
|
|
564
|
+
* for the body text; they survive only when the assembly didn't rewrite the
|
|
565
|
+
* body string.
|
|
566
|
+
*/
|
|
567
|
+
declare function buildImagePromptSegments(config: BuildImagePromptConfig, bodySegments?: readonly PromptSegment[]): BuildImagePromptSegmentsResult;
|
|
568
|
+
/**
|
|
569
|
+
* Replace `{image:N:label}` and `{image:N}` tokens with natural-language
|
|
570
|
+
* phrases bound to a numbered image (Image 1 / 2 / 3 …).
|
|
571
|
+
*
|
|
572
|
+
* - `{image:N:label}` → `Image {N} ({label})`
|
|
573
|
+
* - `{image:N}` → `Image {N}` (no role specified)
|
|
574
|
+
*
|
|
575
|
+
* Same parenthetical form as the directive subject so the model sees a
|
|
576
|
+
* consistent identifier in both the bulleted list and the scene description.
|
|
577
|
+
* Numeric indices match the user-typed slug format (`@kira:1:smile`).
|
|
578
|
+
*
|
|
579
|
+
* Out-of-range indices are left untouched so they're visible in the output.
|
|
580
|
+
*/
|
|
581
|
+
declare function expandImageRefTokens(prompt: string, imageCount: number): string;
|
|
582
|
+
/** Build the combined per-identity directive intro for previews.
|
|
583
|
+
* Each directive is emitted on its own line so the model (and the human
|
|
584
|
+
* reading the FinalPromptPreview) can see the structure clearly. */
|
|
585
|
+
declare function buildIdentityDirectives(prompt: string, refs: readonly ConnectedReference[], meta?: readonly IdentityMeta[], suppressedCanonicalLocationIds?: readonly string[]): string;
|
|
586
|
+
/** @deprecated Use `expandImageRefTokens` (label-aware). */
|
|
587
|
+
declare function expandImagePositionRefs(prompt: string, imageCount: number, names?: readonly string[]): string;
|
|
588
|
+
/** @deprecated Use `buildIdentityDirectives(prompt, refs, meta)`. */
|
|
589
|
+
declare function buildReferenceBlocks(refs: readonly ConnectedReference[], _meta?: readonly IdentityMeta[]): string;
|
|
590
|
+
declare const SCENE_PROMPT_MAX_LENGTH = 2000;
|
|
591
|
+
declare const SHOT_LABELS: Record<string, string>;
|
|
592
|
+
declare const ANGLE_LABELS: Record<string, string>;
|
|
593
|
+
declare const ASPECT_RATIO_LABELS: Record<string, string>;
|
|
594
|
+
declare const MOVEMENT_LABELS: Record<string, string>;
|
|
595
|
+
declare function truncateText(text: string, maxLen: number): string;
|
|
596
|
+
/**
|
|
597
|
+
* Build a rich image-generation prompt from scene node data + character
|
|
598
|
+
* definitions. Used by both the frontend DAG executor and the backend
|
|
599
|
+
* orchestrator so that scene prompts are identical regardless of
|
|
600
|
+
* execution path.
|
|
601
|
+
*/
|
|
602
|
+
declare function buildScenePrompt(data: SceneData, assets: readonly CharacterDef[], options?: {
|
|
603
|
+
forDisplay?: boolean;
|
|
604
|
+
}): string;
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Path-1 structured prompt fields → composed prompt fragment.
|
|
608
|
+
*
|
|
609
|
+
* Used by:
|
|
610
|
+
* - Nodaro's MCP server (Phase 6 v1.1) — generate_image / generate_video verbs
|
|
611
|
+
* accept these structured fields and run them through this helper before
|
|
612
|
+
* passing the composite prompt to the underlying route.
|
|
613
|
+
* - (Optional) Frontend editor — same logic so the editor and MCP produce
|
|
614
|
+
* identical prompts for the same inputs.
|
|
615
|
+
*
|
|
616
|
+
* NOTE: this is a parallel utility to `prompt-builder.ts`. The latter does
|
|
617
|
+
* image-specific composition (character/template/reference handling), while
|
|
618
|
+
* this module handles the Path-1 structured-field shape that MCP verbs accept
|
|
619
|
+
* (free-form strings under person/styling/setting/camera/lens/mood). Existing
|
|
620
|
+
* frontend `buildPersonHints` / `buildStylingHints` helpers operate on catalog
|
|
621
|
+
* IDs and are not interchangeable with this renderer.
|
|
622
|
+
*/
|
|
623
|
+
interface StructuredPromptFields {
|
|
624
|
+
person?: {
|
|
625
|
+
age?: number;
|
|
626
|
+
gender?: "man" | "woman" | "child" | "non-binary";
|
|
627
|
+
hair?: string;
|
|
628
|
+
eyes?: string;
|
|
629
|
+
expression?: string;
|
|
630
|
+
profession?: string;
|
|
631
|
+
warriorType?: string;
|
|
632
|
+
};
|
|
633
|
+
styling?: {
|
|
634
|
+
mood?: string;
|
|
635
|
+
lighting?: string;
|
|
636
|
+
aesthetic?: string;
|
|
637
|
+
colorLook?: string;
|
|
638
|
+
};
|
|
639
|
+
setting?: {
|
|
640
|
+
era?: string;
|
|
641
|
+
atmosphere?: string;
|
|
642
|
+
backdrop?: string;
|
|
643
|
+
};
|
|
644
|
+
camera?: {
|
|
645
|
+
framing?: string;
|
|
646
|
+
motion?: string;
|
|
647
|
+
format?: string;
|
|
648
|
+
};
|
|
649
|
+
lens?: {
|
|
650
|
+
focalLength?: string;
|
|
651
|
+
aperture?: string;
|
|
652
|
+
};
|
|
653
|
+
/** Standalone shorthand mood (overrides styling.mood if both are set). */
|
|
654
|
+
mood?: string;
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Render structured fields → composite prompt fragment to be appended to the
|
|
658
|
+
* user's free-text prompt. Returns "" if no fields populated.
|
|
659
|
+
*/
|
|
660
|
+
declare function renderStructuredFields(fields: StructuredPromptFields): string;
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Shared video-reference resolver CORE — the ONE pure implementation of the
|
|
664
|
+
* video-prompt `@-mention` + canonical-fallback + extras assembly that BOTH the
|
|
665
|
+
* frontend (`frontend/src/lib/video-prompt-assembly.ts`) and backend
|
|
666
|
+
* (`backend/src/services/workflow-engine/payload-builder.ts`) resolvers delegate
|
|
667
|
+
* to.
|
|
668
|
+
*
|
|
669
|
+
* Historically the FE and BE each hand-rolled a byte-for-byte copy of this logic
|
|
670
|
+
* (they had to stay in lock-step or single-node FE runs and orchestrator runs
|
|
671
|
+
* would diverge). This module is the lift-and-shift of the FRONTEND resolver's
|
|
672
|
+
* post-expansion body into one place so there is a single source of truth.
|
|
673
|
+
*
|
|
674
|
+
* Purity contract: NO FE/BE-only dependencies. The caller is responsible for the
|
|
675
|
+
* layer-specific work BEFORE calling in:
|
|
676
|
+
* - expanding wired Character upstreams into `ConnectedReference[]`
|
|
677
|
+
* (`wiredCharRefs`), and
|
|
678
|
+
* - looking up an extra-ref's character metadata by slug
|
|
679
|
+
* (`lookupCharacterBySlug` — FE: `nodes.find(...)`, BE: `buildCtx`).
|
|
680
|
+
*
|
|
681
|
+
* Behavior-preserving when first extracted (the FE resolver's post-expansion
|
|
682
|
+
* body was lifted verbatim). The ONE intended output change since is the
|
|
683
|
+
* reference-binding surface string: the per-image subject phrasing, the bullet
|
|
684
|
+
* ordinals, and the frame directive now emit `@image_N` / `@video_N` /
|
|
685
|
+
* `@audio_N` (the legacy form was `Image N`) — all routed through the single
|
|
686
|
+
* `REF_BINDING` swap-point below. The structural strings ("Use these
|
|
687
|
+
* characters:", the bullet layout, "… is the same subject as …") are otherwise
|
|
688
|
+
* unchanged.
|
|
689
|
+
*/
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* The SINGLE swap-point for the reference-binding surface-string (design D1/D7).
|
|
693
|
+
*
|
|
694
|
+
* Every place that renders an `@image_N`-style binding into a video prompt — the
|
|
695
|
+
* per-image subject phrasing, the bare ordinal in a "Use these characters" /
|
|
696
|
+
* pair-back bullet, and the opening/closing frame directive — MUST go through
|
|
697
|
+
* these five arrows. The default form is `@image_N`; if the D7 probe shows a
|
|
698
|
+
* provider prefers the legacy `Image N` form, flipping is editing ONLY these five
|
|
699
|
+
* arrows (`@image_${n}` → `Image ${n}`), nothing downstream.
|
|
700
|
+
*
|
|
701
|
+
* This IS the live swap-point: `resolveVideoReferenceCore` routes the per-image
|
|
702
|
+
* subject phrasing, the "Use these characters" / pair-back bullet ordinals, and
|
|
703
|
+
* the frame directive through these arrows, and `resolveReferenceTokens` resolves
|
|
704
|
+
* the body `{image:N}` tokens through `REF_BINDING[kind]` — so the five arrows
|
|
705
|
+
* are the ONLY emission sites for the binding surface string.
|
|
706
|
+
*/
|
|
707
|
+
declare const REF_BINDING: {
|
|
708
|
+
readonly image: (label: string, n: number) => string;
|
|
709
|
+
readonly video: (label: string, n: number) => string;
|
|
710
|
+
readonly audio: (label: string, n: number) => string;
|
|
711
|
+
/** ordinal as it appears in a "Use these characters" bullet / pair-back */
|
|
712
|
+
readonly ordinal: (n: number) => string;
|
|
713
|
+
readonly frame: (n: number, role: "opening" | "closing") => string;
|
|
714
|
+
};
|
|
715
|
+
/**
|
|
716
|
+
* Positional reference counts the editor tokens are resolved against — how many
|
|
717
|
+
* image / video / audio references are wired into the node, in worker-payload
|
|
718
|
+
* order. `{image:N:…}` is 1-based against `image`, `{video:N:…}` against `video`,
|
|
719
|
+
* etc. A token whose N exceeds its count (or whose kind has count 0) is dropped.
|
|
720
|
+
*/
|
|
721
|
+
interface ReferenceCounts {
|
|
722
|
+
image: number;
|
|
723
|
+
video: number;
|
|
724
|
+
audio: number;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Rewrite the editor's `{image:N:label}` / `{video:N:label}` / `{audio:N:label}`
|
|
728
|
+
* reference tokens into `@image_N` / `@video_N` / `@audio_N` subject bindings.
|
|
729
|
+
*
|
|
730
|
+
* The token's `N` is POSITIONAL (1-based) against the matching `counts` entry —
|
|
731
|
+
* the worker-payload order of wired references of that kind. Per match:
|
|
732
|
+
* - `N < 1` or `N > counts[kind]` (out of range / no such reference) → drop to
|
|
733
|
+
* the bare `label` (or empty if label-less). This is the legacy
|
|
734
|
+
* `stripVideoImageTokens` strip behavior: drop the token, keep the label text.
|
|
735
|
+
* - in range, label present → `REF_BINDING[kind](label, N)`
|
|
736
|
+
* (e.g. `the person from @image_2`).
|
|
737
|
+
* - in range, no label → `the subject in @${kind}_${N}` so the binding still
|
|
738
|
+
* lands even when the author didn't name the subject.
|
|
739
|
+
*
|
|
740
|
+
* Runs of 2+ HORIZONTAL whitespace (left behind by a dropped label-less token)
|
|
741
|
+
* collapse to one space, the result is trimmed, and an empty result becomes
|
|
742
|
+
* `undefined` — matching the `stripVideoImageTokens` contract so this can replace
|
|
743
|
+
* it cleanly. The collapse class is `[^\S\r\n]` (NOT `\s`) on purpose: Task 2.4
|
|
744
|
+
* applies this to the FULLY-ASSEMBLED core prompt, which carries `\n\n` block
|
|
745
|
+
* separators between the "Use these characters:" directive block and the body —
|
|
746
|
+
* a `\s{2,}` collapse would silently merge those paragraphs. Horizontal-only
|
|
747
|
+
* collapse preserves newline structure while still tidying the dropped-token gap.
|
|
748
|
+
* The `kind` is lowercased before indexing `counts`/`REF_BINDING`, so a
|
|
749
|
+
* case-variant token (`{Image:1}`) resolves to the same binding rather than
|
|
750
|
+
* mis-classifying as out-of-range.
|
|
751
|
+
*/
|
|
752
|
+
declare function resolveReferenceTokens(prompt: string | undefined, counts: ReferenceCounts): string | undefined;
|
|
753
|
+
/**
|
|
754
|
+
* A user-attached "extra reference image" row. Layer-agnostic shape of the
|
|
755
|
+
* frontend `ExtraRef` / backend extras: only the fields this core reads.
|
|
756
|
+
*/
|
|
757
|
+
interface VideoExtraRef {
|
|
758
|
+
url: string;
|
|
759
|
+
description?: string;
|
|
760
|
+
characterSlug?: string;
|
|
761
|
+
variantSlug?: string;
|
|
762
|
+
usageMode?: UsageMode;
|
|
763
|
+
/**
|
|
764
|
+
* Wired scene-composition fragment (held-prop / styling / text) for this
|
|
765
|
+
* extra — the `ConnectedReference.elementInjection` analogue. Surfaced ONLY
|
|
766
|
+
* in hybrid mode on a FIRST-SIGHT character extra, as its own trailing scene
|
|
767
|
+
* directive (mirrors the canonical/mention hybrid paths). Absent → unchanged.
|
|
768
|
+
*/
|
|
769
|
+
elementInjection?: string | null;
|
|
770
|
+
/**
|
|
771
|
+
* Optional, opt-in per-extra identity-lock (the `ConnectedReference.identityLock`
|
|
772
|
+
* analogue). Emitted ONLY in hybrid mode on a first-sight character extra, via
|
|
773
|
+
* `buildIdentityLockLine`. Default OFF (absent / `enabled === false`) → no lock.
|
|
774
|
+
* When absent, the first-sight branch falls back to the node's mapped lock
|
|
775
|
+
* from `CharacterMeta.identityLock`.
|
|
776
|
+
*/
|
|
777
|
+
identityLock?: {
|
|
778
|
+
enabled: boolean;
|
|
779
|
+
text?: string;
|
|
780
|
+
};
|
|
781
|
+
/**
|
|
782
|
+
* The `ConnectedReference.defaultRole` analogue for ROUTE-supplied extras
|
|
783
|
+
* (generate-video / text-to-video / MCP verbs), whose adapter can only feed
|
|
784
|
+
* the COALESCED `defaultUsageMode` as `usageMode` — which would otherwise
|
|
785
|
+
* trip the meta-suppression gate and permanently ignore the node default.
|
|
786
|
+
* Preferred over `CharacterMeta.defaultRole` at the first-sight role site.
|
|
787
|
+
* The expander (`expandExtraRefsToConnectedReferences`) already suppresses
|
|
788
|
+
* the source field when a true per-ref override existed, so passing it
|
|
789
|
+
* through verbatim preserves the override-wins precedence. Canvas /
|
|
790
|
+
* orchestrator extras leave this unset (they resolve via `CharacterMeta`).
|
|
791
|
+
*/
|
|
792
|
+
defaultRole?: string;
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* Character metadata resolved by the caller for an extra-ref's `characterSlug`.
|
|
796
|
+
* Mirrors the per-layer upstream lookup: FE reads `CharacterNodeData`
|
|
797
|
+
* (`characterName` / `defaultUsageMode` / `canonicalDescription`); BE reads its
|
|
798
|
+
* `buildExtraRefCharacterContextLookup` context (`displayName` →
|
|
799
|
+
* `characterName`, etc.).
|
|
800
|
+
*/
|
|
801
|
+
interface CharacterMeta {
|
|
802
|
+
characterName?: string;
|
|
803
|
+
defaultUsageMode?: UsageMode;
|
|
804
|
+
canonicalDescription?: string;
|
|
805
|
+
/** Character node's hybrid `defaultRole` — takes precedence over
|
|
806
|
+
* `defaultUsageMode` at the video extras first-sight role site (via
|
|
807
|
+
* `resolveDefaultRole`). Absent when the node never set a role. */
|
|
808
|
+
defaultRole?: string;
|
|
809
|
+
/** Character node's `identityLock`, already mapped to the per-reference lock
|
|
810
|
+
* shape (`characterLockToRefLock`). Read at the video extras first-sight lock
|
|
811
|
+
* site; a per-extra `identityLock` still wins over it. */
|
|
812
|
+
identityLock?: {
|
|
813
|
+
enabled: boolean;
|
|
814
|
+
text?: string;
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
interface ResolveVideoReferenceCoreArgs {
|
|
818
|
+
prompt: string | undefined;
|
|
819
|
+
/** Already expanded by the caller's layer-specific expander. */
|
|
820
|
+
wiredCharRefs: ConnectedReference[];
|
|
821
|
+
extraRefs?: readonly VideoExtraRef[];
|
|
822
|
+
/** Look up an extra-ref's character metadata by slug (FE: nodes.find; BE: buildCtx). */
|
|
823
|
+
lookupCharacterBySlug?: (slug: string) => CharacterMeta | undefined;
|
|
824
|
+
referenceOrder?: readonly string[];
|
|
825
|
+
suppressedCanonicalCharacterIds?: readonly string[];
|
|
826
|
+
/**
|
|
827
|
+
* Positional counts the editor numbers `{image:N}` / `{video:N}` / `{audio:N}`
|
|
828
|
+
* body tokens against — the TOTAL reference-handle count of each kind wired
|
|
829
|
+
* into the node (base reference images + mention additions), in worker-payload
|
|
830
|
+
* order. Supplied by the callers in Tasks 3.2/4.1; when omitted, `image` falls
|
|
831
|
+
* back to the core's own merged-URL count and `video`/`audio` to 0 (the core
|
|
832
|
+
* only attaches image URLs).
|
|
833
|
+
*/
|
|
834
|
+
imageRefCount?: number;
|
|
835
|
+
videoRefCount?: number;
|
|
836
|
+
audioRefCount?: number;
|
|
837
|
+
/**
|
|
838
|
+
* Plain image-reference URLs that LEAD the unified `@image_N` numbering
|
|
839
|
+
* (D5: image-refs-first). They occupy `@image_1 … @image_offset`; every
|
|
840
|
+
* character/asset directive this core emits is numbered AFTER them, and they
|
|
841
|
+
* are prepended to the returned `additionalUrls` so the worker payload order
|
|
842
|
+
* matches the ordinals. When provided, they OWN the image token count (so
|
|
843
|
+
* `imageRefCount` is ignored for the image modality); omitted → legacy
|
|
844
|
+
* behaviour (`imageRefCount ?? mergedLen`, asset URLs numbered from 1).
|
|
845
|
+
* Already deduped/reordered by the caller (e.g. `connectedRefImageOrder`).
|
|
846
|
+
*/
|
|
847
|
+
leadingRefUrls?: readonly string[];
|
|
848
|
+
/**
|
|
849
|
+
* Number of leading image-refs the CALLER owns + merges itself (so the core
|
|
850
|
+
* offsets asset directive ordinals + the `{image:N}` count by this much WITHOUT
|
|
851
|
+
* prepending any URLs to `additionalUrls`). Used by i2v, whose frame-promotion
|
|
852
|
+
* consumes the asset URLs directly and can't have leading refs spliced in.
|
|
853
|
+
* Ignored when `leadingRefUrls` is set. D5 unified-asset-references.
|
|
854
|
+
*/
|
|
855
|
+
ordinalOffset?: number;
|
|
856
|
+
/**
|
|
857
|
+
* Render character / canonical-fallback / extra-ref directives in the hybrid
|
|
858
|
+
* role-phrase form (`the {role} from @image_N`) instead of the legacy
|
|
859
|
+
* `Use these characters:` block; default false = today's behavior, unchanged.
|
|
860
|
+
* Wired in Phase B Tasks 2-3.
|
|
861
|
+
*/
|
|
862
|
+
hybridRoles?: boolean;
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Resolve `@kira:N` / `@kira:N:smile` mentions in a video-node prompt against
|
|
866
|
+
* the caller-supplied wired Character references AND apply the per-character
|
|
867
|
+
* canonical fallback for unmentioned wired characters, plus manual/extra refs.
|
|
868
|
+
*
|
|
869
|
+
* Per-character behavior contract (parity with image-side + backend):
|
|
870
|
+
* - wired-character with at least one `@-mention` → contribute ONLY the
|
|
871
|
+
* mentioned variant URLs (no canonical auto-attach), prepend the
|
|
872
|
+
* mention-derived directive block.
|
|
873
|
+
* - wired-character with NO `@-mention` → contribute the canonical URL
|
|
874
|
+
* + a strong identity directive (mode-aware via `defaultUsageMode`).
|
|
875
|
+
*
|
|
876
|
+
* Returns the mutated prompt + the asset URLs to slot into the worker payload.
|
|
877
|
+
* The caller decides where (i2v has both `imageUrl` and `referenceImageUrls`;
|
|
878
|
+
* v2v has only a single `referenceImageUrl`; t2v has `referenceImageUrls` only).
|
|
879
|
+
*/
|
|
880
|
+
declare function resolveVideoReferenceCore(args: ResolveVideoReferenceCoreArgs): {
|
|
881
|
+
prompt: string | undefined;
|
|
882
|
+
additionalUrls: string[];
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* Aggregator that walks a consumer node's `audio-style` target handle, collects
|
|
887
|
+
* incoming Sound parameter nodes, and composes a SoundComposition (text +
|
|
888
|
+
* optional structured fields + warnings) used to enrich the consumer's prompt
|
|
889
|
+
* fields. Parallel to how cinematography hints aggregate via
|
|
890
|
+
* `collectCinematographyHints` in front+back, but exposes structured-field
|
|
891
|
+
* outputs for typed targets like MiniMax (genre/mood/instrumental).
|
|
892
|
+
*
|
|
893
|
+
* Called from:
|
|
894
|
+
* - frontend: `frontend/src/lib/audio-style-hints.ts` (canvas executor)
|
|
895
|
+
* - backend: `backend/src/services/workflow-engine/payload-builder.ts`
|
|
896
|
+
*/
|
|
897
|
+
|
|
898
|
+
type SoundConsumerType = "suno-generate" | "generate-music" | "voice-design" | "voice-remix" | "text-to-audio";
|
|
899
|
+
interface SoundCompositionFields {
|
|
900
|
+
readonly genre?: string;
|
|
901
|
+
readonly mood?: string;
|
|
902
|
+
readonly instrumental?: boolean;
|
|
903
|
+
readonly voiceDescription?: string;
|
|
904
|
+
/**
|
|
905
|
+
* Suno's binary vocal-gender control. Extracted from a connected
|
|
906
|
+
* voice-character node's `gender` field when it's "male" or "female"
|
|
907
|
+
* ("androgynous" is left to prompt-only since Suno doesn't accept it).
|
|
908
|
+
* Set on suno-generate and generate-music consumers.
|
|
909
|
+
*/
|
|
910
|
+
readonly vocalGender?: "male" | "female";
|
|
911
|
+
}
|
|
912
|
+
interface SoundComposition {
|
|
913
|
+
readonly text: string;
|
|
914
|
+
readonly fields: SoundCompositionFields;
|
|
915
|
+
readonly warnings: ReadonlyArray<string>;
|
|
916
|
+
}
|
|
917
|
+
declare function composeSoundHintFromConnections(consumer: HintNodeLike, consumerType: SoundConsumerType, ctx: HintGraphContext): SoundComposition;
|
|
918
|
+
/**
|
|
919
|
+
* Append `composedText` to `userText` with ", " separator. Empty inputs
|
|
920
|
+
* are tolerated; the non-empty side is returned alone.
|
|
921
|
+
*/
|
|
922
|
+
declare function appendField(userText: string, composedText: string): string;
|
|
923
|
+
/**
|
|
924
|
+
* Truncate `composedText` so the final string `userText + ", " + composedText`
|
|
925
|
+
* fits within `maxTotalLen`. Returns "" when the budget is non-positive (user
|
|
926
|
+
* text already at limit). Cuts on word boundary when possible.
|
|
927
|
+
*/
|
|
928
|
+
declare function truncateForField(composedText: string, userText: string, maxTotalLen: number): string;
|
|
929
|
+
/**
|
|
930
|
+
* Suno Generate auto-detects custom mode when the user typed style/title/lyrics,
|
|
931
|
+
* even without explicitly toggling `customMode`. The frontend executor, backend
|
|
932
|
+
* payload-builder, and the FinalAudioPromptPreview all need to agree on the
|
|
933
|
+
* resolved value or the preview lies about which field receives the audio-style
|
|
934
|
+
* hint.
|
|
935
|
+
*
|
|
936
|
+
* Accepts an unknown-keyed record so callers in both the typed frontend
|
|
937
|
+
* (SunoGenerateData) and the loosely-typed backend (WorkflowNodeData with
|
|
938
|
+
* `[k: string]: unknown`) can hand the node `data` straight in without casts.
|
|
939
|
+
*/
|
|
940
|
+
declare function getEffectiveSunoCustomMode(data: {
|
|
941
|
+
readonly [k: string]: unknown;
|
|
942
|
+
}): boolean;
|
|
943
|
+
/**
|
|
944
|
+
* Fold a Generate Music node's genre / mood / instrumental selections into the
|
|
945
|
+
* prompt text. The music worker only reads `prompt`, so this enrichment is the
|
|
946
|
+
* ONLY channel by which those three controls reach the provider.
|
|
947
|
+
*
|
|
948
|
+
* Shared by the single-node route (`/v1/generate-music`) and the workflow
|
|
949
|
+
* orchestrator (`payload-builder.ts` `generate-music`) so a workflow / app /
|
|
950
|
+
* webhook run produces the same prompt — and the same music — as a Run-button
|
|
951
|
+
* run. Mirrors the route's original inline `[prompt, genre, mood, …].join(", ")`
|
|
952
|
+
* exactly (locked by `routes/__tests__/generate-music.test.ts`).
|
|
953
|
+
*/
|
|
954
|
+
declare function appendMusicMeta(basePrompt: string, meta: {
|
|
955
|
+
genre?: string;
|
|
956
|
+
mood?: string;
|
|
957
|
+
instrumental?: boolean;
|
|
958
|
+
}): string;
|
|
959
|
+
|
|
960
|
+
interface AssembleSunoInput {
|
|
961
|
+
/** The `suno-generate` node; `data` is ALREADY field-mapped by the caller. */
|
|
962
|
+
node: HintNodeLike;
|
|
963
|
+
/** `{ nodes, edges }` for the connected-picker audio-style fold. */
|
|
964
|
+
graph: HintGraphContext;
|
|
965
|
+
/**
|
|
966
|
+
* Caller-resolved user prompt (FE: `overridePrompt ?? inputs.prompt ??
|
|
967
|
+
* resolveTextRefs(data.prompt)`). Folded into `prompt` in non-custom mode.
|
|
968
|
+
*/
|
|
969
|
+
userPrompt: string;
|
|
970
|
+
/**
|
|
971
|
+
* Caller-resolved lyrics (divergence C — refMap-resolved by the caller, NOT
|
|
972
|
+
* read from `data.lyrics` here).
|
|
973
|
+
*/
|
|
974
|
+
lyrics?: string;
|
|
975
|
+
/** Persona fields (FE/BE `resolvePersona(...)`), spread onto the result. */
|
|
976
|
+
persona?: {
|
|
977
|
+
personaId?: string;
|
|
978
|
+
personaModel?: "voice_persona" | "style_persona";
|
|
979
|
+
};
|
|
980
|
+
/**
|
|
981
|
+
* Reject an empty prompt+hint with `throw` (divergence A). FE run passes
|
|
982
|
+
* `true`; the BE run + the preview leave it `false`.
|
|
983
|
+
*/
|
|
984
|
+
throwOnEmpty?: boolean;
|
|
985
|
+
}
|
|
986
|
+
interface AssembleSunoResult {
|
|
987
|
+
prompt: string;
|
|
988
|
+
style?: string;
|
|
989
|
+
lyrics?: string;
|
|
990
|
+
title?: string;
|
|
991
|
+
negativeStyle?: string;
|
|
992
|
+
vocalGender?: string;
|
|
993
|
+
styleWeight?: number;
|
|
994
|
+
weirdnessConstraint?: number;
|
|
995
|
+
audioWeight?: number;
|
|
996
|
+
customMode: boolean;
|
|
997
|
+
instrumental: boolean;
|
|
998
|
+
model?: string;
|
|
999
|
+
personaId?: string;
|
|
1000
|
+
personaModel?: "voice_persona" | "style_persona";
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Assemble a `suno-generate` node's inputs into the flat field set the Suno
|
|
1004
|
+
* provider receives. Byte-faithful to the FE `execute-node.ts` inline block.
|
|
1005
|
+
*/
|
|
1006
|
+
declare function assembleSunoInput(input: AssembleSunoInput): AssembleSunoResult;
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* `assembleImageInput` — the single source of truth for turning a node's
|
|
1010
|
+
* image-generation inputs (a prompt + cinematic direction + connected
|
|
1011
|
+
* references + the per-provider levers) into the flat `{ prompt,
|
|
1012
|
+
* nativeNegativePrompt, referenceImageUrls }` the `generate-image` route
|
|
1013
|
+
* expects.
|
|
1014
|
+
*
|
|
1015
|
+
* WHY THIS EXISTS (WI-1a): the same three-step assembly —
|
|
1016
|
+
* 1. compose the prompt text (fold cinematic id-hints + structured fields),
|
|
1017
|
+
* 2. call `buildImagePrompt(...)` (the pure core; the per-provider reference
|
|
1018
|
+
* gate lives INSIDE it),
|
|
1019
|
+
* 3. (optionally) reject a truly-empty FINAL prompt,
|
|
1020
|
+
* — was duplicated in THREE places kept in lockstep by hand: the frontend
|
|
1021
|
+
* `execute-node.ts` `generate-image` branch, the backend
|
|
1022
|
+
* `payload-builder.ts` `generate-image` case, and Studio's `assembly.ts`.
|
|
1023
|
+
* This wrapper collapses them into one.
|
|
1024
|
+
*
|
|
1025
|
+
* THE NO-OP CONTRACT (load-bearing — the platform-caller parity relies on it):
|
|
1026
|
+
* the two platform callers (`execute-node` / `payload-builder`) compose their
|
|
1027
|
+
* prompt from the canvas graph themselves and pass NO cinematic `direction`
|
|
1028
|
+
* ids and NO `structured` fields. In that case `composePromptText` MUST return
|
|
1029
|
+
* the caller's `userPrompt` byte-for-byte unchanged, so the wrapper degenerates
|
|
1030
|
+
* to exactly the `buildImagePrompt(...)` call those sites make today. Studio
|
|
1031
|
+
* (and the MCP route) supply `direction` / `structured` and get the id-hint
|
|
1032
|
+
* composition on top.
|
|
1033
|
+
*
|
|
1034
|
+
* THE EMPTY-CHECK FLAG (also load-bearing for parity): `execute-node` rejects a
|
|
1035
|
+
* truly-empty assembled prompt (its "type one, mention a character, or connect
|
|
1036
|
+
* a cinematography source" guard); `payload-builder` does NOT (it never threw
|
|
1037
|
+
* there). So the post-assembly throw is OPT-IN via `throwOnEmpty` — defaulting
|
|
1038
|
+
* to `false` preserves the backend's no-throw behavior. Callers that want the
|
|
1039
|
+
* guard (frontend, Studio, route) pass `throwOnEmpty: true`.
|
|
1040
|
+
*/
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Flat cinematic-direction ids the Studio framing UI (and the MCP route)
|
|
1044
|
+
* expose — all optional. Promoted here from Studio's `assembly.ts` so the
|
|
1045
|
+
* id → hint composition lives in one place. The platform callers pass none of
|
|
1046
|
+
* these (they fold their hints from the graph into `userPrompt` themselves).
|
|
1047
|
+
*/
|
|
1048
|
+
interface DirectionFields {
|
|
1049
|
+
/** Shot Type — the FRAMINGS shot-size/coverage/composition/vantage dimensions. */
|
|
1050
|
+
framingId?: string;
|
|
1051
|
+
/** Angle — the FRAMINGS angle dimension (separate pill, so it can coexist with Shot Type). */
|
|
1052
|
+
framingAngleId?: string;
|
|
1053
|
+
lightingId?: string;
|
|
1054
|
+
lensId?: string;
|
|
1055
|
+
cameraFormatId?: string;
|
|
1056
|
+
}
|
|
1057
|
+
/**
|
|
1058
|
+
* Input to `assembleImageInput`. A faithful SUPERSET of what the two platform
|
|
1059
|
+
* callers pass to `buildImagePrompt` today (so they can route through this
|
|
1060
|
+
* wrapper with byte-identical output), plus the id-based `direction` /
|
|
1061
|
+
* `structured` composition levers that Studio + the MCP route use.
|
|
1062
|
+
*/
|
|
1063
|
+
interface AssembleImageInput {
|
|
1064
|
+
/** Pre-composed (caller's graph) or raw user prompt text. */
|
|
1065
|
+
userPrompt: string;
|
|
1066
|
+
/** Image model id / provider key (the catalog enum value, e.g. "flux-2-max"). */
|
|
1067
|
+
provider: string;
|
|
1068
|
+
/**
|
|
1069
|
+
* Connected references with URLs ALREADY resolved by the caller. Become
|
|
1070
|
+
* `referenceImageUrls` + identity directives inside `buildImagePrompt`
|
|
1071
|
+
* (gated per provider there). Omit when the caller wires only raw URLs.
|
|
1072
|
+
*/
|
|
1073
|
+
connectedReferences?: ConnectedReference[];
|
|
1074
|
+
/**
|
|
1075
|
+
* Flat cinematic-direction ids → folded into the prompt as hints. Studio /
|
|
1076
|
+
* MCP-route use; the platform callers pass none (so `composePromptText` is a
|
|
1077
|
+
* no-op for them and the result is byte-identical to today).
|
|
1078
|
+
*/
|
|
1079
|
+
direction?: DirectionFields;
|
|
1080
|
+
/** Path-1 structured fields → composed fragment appended to the prompt. */
|
|
1081
|
+
structured?: StructuredPromptFields;
|
|
1082
|
+
/**
|
|
1083
|
+
* Reference image URLs from direct connections / manual uploads — ride
|
|
1084
|
+
* `buildImagePrompt`'s reference-URL channel so they pass through the SAME
|
|
1085
|
+
* per-provider reference-image gate + ordering as `connectedReferences`.
|
|
1086
|
+
* (This is `buildImagePrompt`'s `referenceImageUrls` config field, named
|
|
1087
|
+
* `extra…` here to reflect that bound entities already carry their URLs.)
|
|
1088
|
+
*/
|
|
1089
|
+
extraReferenceImageUrls?: string[];
|
|
1090
|
+
/** Negative prompt text (routed to native vs. "Avoid:" by `buildImagePrompt`). */
|
|
1091
|
+
negativePrompt?: string;
|
|
1092
|
+
/** Style text to append (e.g. "cinematic"). */
|
|
1093
|
+
style?: string;
|
|
1094
|
+
/** User-defined reorder of the injected reference list (stable tile ids). */
|
|
1095
|
+
referenceOrder?: readonly string[];
|
|
1096
|
+
/** Per-identity (imageIndex+label) user overrides for fidelity / custom text. */
|
|
1097
|
+
identityMeta?: readonly IdentityMeta[];
|
|
1098
|
+
/** Character slugs whose canonical-fallback the user explicitly hid. */
|
|
1099
|
+
suppressedCanonicalCharacterIds?: readonly string[];
|
|
1100
|
+
/** Location slugs whose canonical-fallback the user explicitly hid. */
|
|
1101
|
+
suppressedCanonicalLocationIds?: readonly string[];
|
|
1102
|
+
/**
|
|
1103
|
+
* Reference-prompt assembly format for the `{image:N:label}` path. Forwarded
|
|
1104
|
+
* verbatim to `buildImagePrompt` (default legacy). "hybrid" = images-only
|
|
1105
|
+
* reference-lock snippet + lettered inline scene.
|
|
1106
|
+
*/
|
|
1107
|
+
referenceFormat?: "legacy" | "hybrid";
|
|
1108
|
+
/** Override the hybrid reference-lock snippet (forwarded to buildImagePrompt). */
|
|
1109
|
+
referenceLockSnippet?: string;
|
|
1110
|
+
/** Character definitions selected for this node (legacy `buildImagePrompt` path). */
|
|
1111
|
+
characterDefs?: CharacterDef[];
|
|
1112
|
+
/** User-level prompt template overrides. */
|
|
1113
|
+
userTemplates?: Record<string, string>;
|
|
1114
|
+
/** Flow-level prompt template overrides. */
|
|
1115
|
+
flowTemplates?: Record<string, string>;
|
|
1116
|
+
/** Ancestor reference image URLs (fallback when no direct refs exist). */
|
|
1117
|
+
ancestorRefs?: string[];
|
|
1118
|
+
/** Map of `connectedReferences[i].id → sourceNodeId` for wired-raw tile ids. */
|
|
1119
|
+
sourceNodeIdById?: ReadonlyMap<string, string>;
|
|
1120
|
+
/**
|
|
1121
|
+
* LoRA inference path: strip `@`-mention tokens + skip the connected-reference
|
|
1122
|
+
* machinery (the trigger word + LoRA carry identity).
|
|
1123
|
+
*/
|
|
1124
|
+
skipCharacterMentions?: boolean;
|
|
1125
|
+
/**
|
|
1126
|
+
* Reject a truly-empty FINAL (post-assembly) prompt with `throw`. OFF by
|
|
1127
|
+
* default to match the backend `payload-builder`, which never threw. The
|
|
1128
|
+
* frontend / Studio / route pass `true` to keep their "type one, bind a
|
|
1129
|
+
* character, or pick a cinematography direction" guard. Checked POST-assembly
|
|
1130
|
+
* so a bound entity / `@`-mention / direction chip that filled an otherwise-
|
|
1131
|
+
* empty prompt still runs.
|
|
1132
|
+
*/
|
|
1133
|
+
throwOnEmpty?: boolean;
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Assemble a node's image-generation inputs into a `BuildImagePromptResult`
|
|
1137
|
+
* (`{ prompt, nativeNegativePrompt, referenceImageUrls }`).
|
|
1138
|
+
*
|
|
1139
|
+
* Order: (1) compose the prompt text (no-op when no direction/structured),
|
|
1140
|
+
* (2) `buildImagePrompt(...)` — exactly the call the three sites make today,
|
|
1141
|
+
* (3) optional post-assembly empty-prompt throw (gated by `throwOnEmpty`).
|
|
1142
|
+
*/
|
|
1143
|
+
declare function assembleImageInput(input: AssembleImageInput): BuildImagePromptResult;
|
|
1144
|
+
|
|
1145
|
+
type Seedance2Mode = "first-frame" | "first-last-frame" | "reference";
|
|
1146
|
+
interface Seedance2InputsArgs {
|
|
1147
|
+
firstFrameUrl?: string;
|
|
1148
|
+
lastFrameUrl?: string;
|
|
1149
|
+
refImageUrls?: readonly string[];
|
|
1150
|
+
refVideoUrls?: readonly string[];
|
|
1151
|
+
refAudioUrls?: readonly string[];
|
|
1152
|
+
}
|
|
1153
|
+
interface Seedance2InputsResult {
|
|
1154
|
+
mode: Seedance2Mode;
|
|
1155
|
+
firstFrameUrl?: string;
|
|
1156
|
+
lastFrameUrl?: string;
|
|
1157
|
+
referenceImageUrls: string[];
|
|
1158
|
+
referenceVideoUrls: string[];
|
|
1159
|
+
referenceAudioUrls: string[];
|
|
1160
|
+
promptSuffix: string;
|
|
1161
|
+
droppedRefImages: number;
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Single source of truth for how Seedance 2's three mutually-exclusive KIE input
|
|
1165
|
+
* modes are selected from connected inputs. Strict first/last-frame mode is used
|
|
1166
|
+
* only when nothing but frames is connected; any reference (image, video, OR
|
|
1167
|
+
* audio) switches to multimodal Reference mode, where the frames are appended to
|
|
1168
|
+
* reference_image_urls (after the user's own images, so their @Image ordinals do
|
|
1169
|
+
* not shift) and named in a doctrine-compliant prompt suffix.
|
|
1170
|
+
*/
|
|
1171
|
+
declare function resolveSeedance2Inputs(args: Seedance2InputsArgs): Seedance2InputsResult;
|
|
1172
|
+
|
|
1173
|
+
/**
|
|
1174
|
+
* Canonical catalog of Person / subject-appearance choices.
|
|
1175
|
+
*
|
|
1176
|
+
* Multi-dimension parameter node. Unlike Setting / Style / Camera-Motion
|
|
1177
|
+
* (single pick) or Framing (5 dims, all shot composition), Person describes
|
|
1178
|
+
* *who the subject is*. Each dimension is mutually exclusive within itself
|
|
1179
|
+
* (pick one Type, one Age, one Cheekbones, etc.) and all are independently
|
|
1180
|
+
* optional. Dimensions are grouped into six sections (PERSON_DIMENSION_SECTIONS):
|
|
1181
|
+
* Identity, Body, Face, Hair, Skin & Eyes, Features.
|
|
1182
|
+
*
|
|
1183
|
+
* The Face section carries a dedicated facial-geometry layer — cheekbones,
|
|
1184
|
+
* facial fullness, eyelid type, canthal tilt, eye spacing, eye-to-brow set,
|
|
1185
|
+
* nose tip, and split lip fullness / lip shape — so the structured pickers
|
|
1186
|
+
* (not a single "supermodel" Type token) drive the feature geometry and ratios
|
|
1187
|
+
* that actually define a face's look. Neutral options (Average / Neutral /
|
|
1188
|
+
* Standard / Natural) carry an empty promptHint, so enabling a dimension
|
|
1189
|
+
* injects nothing until a real value is picked.
|
|
1190
|
+
*
|
|
1191
|
+
* Non-empty selections from each dimension are joined as a compound hint and
|
|
1192
|
+
* injected as cinematography context into downstream image/video prompts:
|
|
1193
|
+
* "a beautiful woman, in her 30s, East Asian, slim build, long wavy hair,
|
|
1194
|
+
* brown hair, fair skin, green eyes"
|
|
1195
|
+
*
|
|
1196
|
+
* Applies to BOTH image and video consumers (a person description is not
|
|
1197
|
+
* video-specific, unlike camera-motion / temporal). Not in
|
|
1198
|
+
* STILL_IMAGE_EXCLUDE_TYPES.
|
|
1199
|
+
*
|
|
1200
|
+
* Shared between the picker UI, the standalone Person parameter node, and
|
|
1201
|
+
* the prompt-hint injection on both the frontend DAG executor and the
|
|
1202
|
+
* backend orchestrator.
|
|
1203
|
+
*/
|
|
1204
|
+
type PersonDimension = "type" | "age" | "ethnicity" | "regional-aesthetic" | "frame" | "body-mass" | "bust" | "waist" | "hips" | "silhouette" | "face-shape" | "jawline" | "cheekbones" | "facial-fullness" | "eye-shape" | "eyelid-type" | "canthal-tilt" | "eye-spacing" | "eye-set-brow" | "nose" | "nose-tip" | "lip-fullness" | "lip-shape" | "lip-state" | "hair-color" | "hair-base" | "eyebrows" | "skin-tone" | "skin-texture" | "eye-color" | "eye-state" | "facial-hair" | "distinctive-features";
|
|
1205
|
+
interface Person {
|
|
1206
|
+
readonly id: string;
|
|
1207
|
+
readonly label: string;
|
|
1208
|
+
readonly dimension: PersonDimension;
|
|
1209
|
+
readonly description: string;
|
|
1210
|
+
readonly promptHint: string;
|
|
1211
|
+
/** Optional sub-grouping within a dimension. Used by the picker to render
|
|
1212
|
+
* two-level selection (e.g. ethnicity grouped by region → specific). */
|
|
1213
|
+
readonly group?: string;
|
|
1214
|
+
/** Optional shorter label for the picker chip. When a dimension renders
|
|
1215
|
+
* with group headers (e.g. ethnicity), the group name already supplies
|
|
1216
|
+
* context — so a chip under the "Asian" header shows "East (any)"
|
|
1217
|
+
* instead of the redundant "East Asian (any)". Node cards + tooltips
|
|
1218
|
+
* keep the full `label` / `description`. */
|
|
1219
|
+
readonly shortLabel?: string;
|
|
1220
|
+
}
|
|
1221
|
+
declare const PEOPLE: ReadonlyArray<Person>;
|
|
1222
|
+
declare const PERSON_DIMENSION_ORDER: ReadonlyArray<PersonDimension>;
|
|
1223
|
+
declare const PERSON_DIMENSION_LABELS: Readonly<Record<PersonDimension, string>>;
|
|
1224
|
+
/**
|
|
1225
|
+
* Cross-dimension grouping for the compact Person picker view. The detailed
|
|
1226
|
+
* view renders one row per dimension (PERSON_DIMENSION_ORDER); the compact
|
|
1227
|
+
* view collapses those rows into these six labelled sections. This is the
|
|
1228
|
+
* machine-readable form of the section comments in PERSON_DIMENSION_ORDER —
|
|
1229
|
+
* the guard test (person-sections.test.ts) asserts it partitions every
|
|
1230
|
+
* PersonDimension exactly once, so a newly added dimension can't silently
|
|
1231
|
+
* drop out of the compact grouping.
|
|
1232
|
+
*/
|
|
1233
|
+
interface PersonDimensionSection {
|
|
1234
|
+
readonly label: string;
|
|
1235
|
+
readonly dimensions: ReadonlyArray<PersonDimension>;
|
|
1236
|
+
}
|
|
1237
|
+
declare const PERSON_DIMENSION_SECTIONS: ReadonlyArray<PersonDimensionSection>;
|
|
1238
|
+
/**
|
|
1239
|
+
* Maps each PersonDimension to the consumer data field name holding the
|
|
1240
|
+
* selected entry id. Multi-dimension model: a consumer (PersonData) may
|
|
1241
|
+
* independently set a value in each of the dimensions.
|
|
1242
|
+
*/
|
|
1243
|
+
declare const PERSON_FIELD_BY_DIMENSION: Record<PersonDimension, "type" | "age" | "ethnicity" | "regionalAesthetic" | "frame" | "bodyMass" | "bust" | "waist" | "hips" | "silhouette" | "faceShape" | "jawline" | "cheekbones" | "facialFullness" | "eyeShape" | "eyelidType" | "canthalTilt" | "eyeSpacing" | "eyeSetBrow" | "nose" | "noseTip" | "lipFullness" | "lipShape" | "lipState" | "hairColor" | "hairBase" | "eyebrows" | "skinTone" | "skinTexture" | "eyeColor" | "eyeState" | "facialHair" | "distinctiveFeature">;
|
|
1244
|
+
/** Per-dimension multi-select cap (single source of truth for the picker UI,
|
|
1245
|
+
* the image-analyzer tool schema, and the Zod validator).
|
|
1246
|
+
* - ethnicity / regional-aesthetic / hair-color / eye-color / lip-state /
|
|
1247
|
+
* eye-state / skin-texture: 2
|
|
1248
|
+
* - distinctive-features: 3
|
|
1249
|
+
* All other dims are single-select (absent → treated as 1). */
|
|
1250
|
+
declare const MAX_SELECTED_BY_DIMENSION: Partial<Record<PersonDimension, number>>;
|
|
1251
|
+
/** Selection limit for a dimension (1 when not multi-select). */
|
|
1252
|
+
declare function getPersonDimensionLimit(dimension: PersonDimension): number;
|
|
1253
|
+
/**
|
|
1254
|
+
* Shape of the per-dimension person fields. All optional — user may set
|
|
1255
|
+
* zero, one, or all ten dimensions.
|
|
1256
|
+
*/
|
|
1257
|
+
interface PersonValue {
|
|
1258
|
+
type?: string;
|
|
1259
|
+
/** Selected age preset id (e.g. `"age-30s"`). When set to the special
|
|
1260
|
+
* `"age-custom"` sentinel, the literal age in years is read from
|
|
1261
|
+
* `customAge` and the hint is generated at build time. */
|
|
1262
|
+
age?: string;
|
|
1263
|
+
/** Specific age in years. Only consulted when `age === "age-custom"`. */
|
|
1264
|
+
customAge?: number;
|
|
1265
|
+
/** Single id, or an array of up to 2 ids for mixed heritage (e.g.
|
|
1266
|
+
* ["slavic","mediterranean"] → "of mixed Slavic and Mediterranean heritage"). */
|
|
1267
|
+
ethnicity?: string | ReadonlyArray<string>;
|
|
1268
|
+
/** Regional / cultural aesthetic vibe (e.g. `"cali-beach"`, `"parisienne"`,
|
|
1269
|
+
* `"kinshasa-sape"`). Composes with ethnicity, skin tone, hair, and
|
|
1270
|
+
* styling — the dimension's promptHints are vibe-only and never hard-code
|
|
1271
|
+
* the visuals those other dimensions own. Single id or up to 2 ids for
|
|
1272
|
+
* hybrid looks (e.g. ["nyc-fashion","parisienne"]). */
|
|
1273
|
+
regionalAesthetic?: string | ReadonlyArray<string>;
|
|
1274
|
+
/** Skeletal frame width / height (petite, slim, average, broad). Independent
|
|
1275
|
+
* of body mass — "slim frame + full bust" is expressible. */
|
|
1276
|
+
frame?: string;
|
|
1277
|
+
/** Body mass / leanness (lean, average, full, heavy). Independent of frame. */
|
|
1278
|
+
bodyMass?: string;
|
|
1279
|
+
/** Bust size (small, average, full, very full) — applicable subjects. */
|
|
1280
|
+
bust?: string;
|
|
1281
|
+
/** Waist definition (defined, average, straight). */
|
|
1282
|
+
waist?: string;
|
|
1283
|
+
/** Hip width (narrow, balanced, wide). */
|
|
1284
|
+
hips?: string;
|
|
1285
|
+
/** Overall body silhouette (hourglass, rectangular, pear, inverted-triangle,
|
|
1286
|
+
* athletic). Optional — only emits when picked. */
|
|
1287
|
+
silhouette?: string;
|
|
1288
|
+
/** Face silhouette (oval, round, square, heart…). */
|
|
1289
|
+
faceShape?: string;
|
|
1290
|
+
/** Jaw shape (strong, soft, pointed, wide). */
|
|
1291
|
+
jawline?: string;
|
|
1292
|
+
/** Cheekbone projection / height (low, average, high-defined, sculpted-high, wide). */
|
|
1293
|
+
cheekbones?: string;
|
|
1294
|
+
/** Face-specific leanness, independent of body mass (gaunt, lean, average, full, round). */
|
|
1295
|
+
facialFullness?: string;
|
|
1296
|
+
/** Eye shape — anatomical shape only (almond, round, monolid, double-eyelid,
|
|
1297
|
+
* wide, narrow). Lid type, canthal tilt, spacing and brow-set are separate. */
|
|
1298
|
+
eyeShape?: string;
|
|
1299
|
+
/** Upper-eyelid trait (standard, hooded, droopy, deep-set). */
|
|
1300
|
+
eyelidType?: string;
|
|
1301
|
+
/** Canthal tilt — outer-corner angle (neutral, upturned, downturned). */
|
|
1302
|
+
canthalTilt?: string;
|
|
1303
|
+
/** Horizontal eye spacing (close-set, average, wide-set). */
|
|
1304
|
+
eyeSpacing?: string;
|
|
1305
|
+
/** Brow-to-eye distance / eye set (low-set "hunter", average, high-set "doe"). */
|
|
1306
|
+
eyeSetBrow?: string;
|
|
1307
|
+
/** Nose bridge shape (straight, aquiline, snub, broad…). */
|
|
1308
|
+
nose?: string;
|
|
1309
|
+
/** Nose tip rotation / shape (natural, refined, upturned, rounded, drooping). */
|
|
1310
|
+
noseTip?: string;
|
|
1311
|
+
/** Lip fullness (thin, medium, full, full-lower). Replaces the legacy
|
|
1312
|
+
* combined `lips` field together with `lipShape`. */
|
|
1313
|
+
lipFullness?: string;
|
|
1314
|
+
/** Lip shape (natural, cupid's bow, wide, heart, small). Replaces the legacy
|
|
1315
|
+
* combined `lips` field together with `lipFullness`. */
|
|
1316
|
+
lipShape?: string;
|
|
1317
|
+
/** @deprecated Split into `lipFullness` + `lipShape`. Retained so legacy
|
|
1318
|
+
* workflow data keeps resolving — `buildPersonHints` reads it as a fallback
|
|
1319
|
+
* and `migratePersonValue` relocates it onto the new fields. */
|
|
1320
|
+
lips?: string;
|
|
1321
|
+
/** Lip state — what the lips are doing right now (chapped, glossy,
|
|
1322
|
+
* parted, biting, pursed, bold-red…). Distinct from `lips` which is
|
|
1323
|
+
* anatomical shape. Single id or up to 2 (e.g. glossy + parted). */
|
|
1324
|
+
lipState?: string | ReadonlyArray<string>;
|
|
1325
|
+
/** Single id or up to 2 ids for two-tone / ombre / highlighted hair
|
|
1326
|
+
* (e.g. ["hair-black","hair-platinum"]). */
|
|
1327
|
+
hairColor?: string | ReadonlyArray<string>;
|
|
1328
|
+
/** Natural hair texture + length (texture×length combos). The actual cut
|
|
1329
|
+
* / styling choice (bob, wolf cut, braids…) lives in Styling.hair-cut. */
|
|
1330
|
+
hairBase?: string;
|
|
1331
|
+
eyebrows?: string;
|
|
1332
|
+
skinTone?: string;
|
|
1333
|
+
/** Skin texture (smooth, porcelain, freckled, …). Single id or up to 2
|
|
1334
|
+
* combined (e.g. porcelain + freckled, sun-kissed + dewy). */
|
|
1335
|
+
skinTexture?: string | ReadonlyArray<string>;
|
|
1336
|
+
/** Single id or up to 2 ids for heterochromia (e.g.
|
|
1337
|
+
* ["eyes-blue","eyes-green"]). */
|
|
1338
|
+
eyeColor?: string | ReadonlyArray<string>;
|
|
1339
|
+
/** Eye state — what the eyes are doing (closed, half-lidded, wide-eyed,
|
|
1340
|
+
* staring at camera, gazing away/up/down, glassy). Distinct from
|
|
1341
|
+
* `eyeShape` (anatomy) and `eyeColor`. Single id or up to 2 (e.g.
|
|
1342
|
+
* half-lidded + glassy). */
|
|
1343
|
+
eyeState?: string | ReadonlyArray<string>;
|
|
1344
|
+
facialHair?: string;
|
|
1345
|
+
/** Single id or up to 3 ids for combined features (e.g. freckles +
|
|
1346
|
+
* glasses + sleeve tattoo). */
|
|
1347
|
+
distinctiveFeature?: string | ReadonlyArray<string>;
|
|
1348
|
+
/** Free-text appended BEFORE the dimension compound. Use when you want
|
|
1349
|
+
* context/framing to come first (e.g. "wet-haired" or "covered in paint"). */
|
|
1350
|
+
preText?: string;
|
|
1351
|
+
/** Free-text appended AFTER the dimension compound. Use for extra
|
|
1352
|
+
* specifics that dimensions can't capture (e.g. "wearing a leather
|
|
1353
|
+
* jacket", "with a silver necklace"). */
|
|
1354
|
+
postText?: string;
|
|
1355
|
+
}
|
|
1356
|
+
declare function getPerson(id: string | undefined | null): Person | undefined;
|
|
1357
|
+
declare function getPersonLabel(id: string | undefined | null, fallback?: string): string;
|
|
1358
|
+
declare function getPersonPromptHint(id: string | undefined | null): string;
|
|
1359
|
+
declare const PERSON_IDS: ReadonlyArray<string>;
|
|
1360
|
+
/**
|
|
1361
|
+
* Age hint with optional custom-numeric override. When the user picks the
|
|
1362
|
+
* "age-custom" sentinel and provides a specific number, generate a phrase
|
|
1363
|
+
* tuned to the life stage (toddler / child / teen wording for the lower
|
|
1364
|
+
* ranges, plain "{N} years old" for adults). Otherwise return the catalog
|
|
1365
|
+
* entry's static promptHint.
|
|
1366
|
+
*
|
|
1367
|
+
* Custom number is clamped to a sane range and rejected if non-finite.
|
|
1368
|
+
*/
|
|
1369
|
+
declare function buildAgeHint(ageId: string | undefined | null, customAge: number | undefined | null): string;
|
|
1370
|
+
declare function buildPersonHints(data: Record<string, unknown> & PersonValue): string[];
|
|
1371
|
+
/**
|
|
1372
|
+
* Relocate legacy single-field Person values onto the post-split fields so the
|
|
1373
|
+
* picker UI shows them in their new home:
|
|
1374
|
+
*
|
|
1375
|
+
* - `eyeShape` ∈ {hooded, droopy, deep-set} → `eyelidType`
|
|
1376
|
+
* - `eyeShape` ∈ {upturned, downturned} → `canthalTilt`
|
|
1377
|
+
* - `eyeShape` ∈ {wide-set, close-set} → `eyeSpacing`
|
|
1378
|
+
* - `lips` ∈ {thin, medium, full} → `lipFullness`
|
|
1379
|
+
* - `lips` ∈ {wide, cupids-bow, small} → `lipShape`
|
|
1380
|
+
*
|
|
1381
|
+
* PROMPT OUTPUT IS UNAFFECTED either way — `getPersonPromptHint` resolves the
|
|
1382
|
+
* ids regardless of dimension and `buildPersonHints` has a `lips` fallback;
|
|
1383
|
+
* this is UI hygiene + clean re-saves only. Immutable + idempotent: returns the
|
|
1384
|
+
* same reference when nothing moves, never overwrites an already-set target,
|
|
1385
|
+
* clears the legacy source once relocated, and preserves every other key (node
|
|
1386
|
+
* data carries non-Person fields too).
|
|
1387
|
+
*/
|
|
1388
|
+
declare function migratePersonValue<T extends Record<string, unknown>>(data: T): T;
|
|
1389
|
+
|
|
1390
|
+
/**
|
|
1391
|
+
* Public, discoverable registry of the parameter-picker catalogs.
|
|
1392
|
+
*
|
|
1393
|
+
* This is the pure-data mirror of the frontend picker registry
|
|
1394
|
+
* (`frontend/src/lib/parameter-picker-registry.tsx`). It contains NO React —
|
|
1395
|
+
* just the catalog metadata + flattened options — so it can be consumed by
|
|
1396
|
+
* the backend, the public SDK, docs tooling, and the editor alike from one
|
|
1397
|
+
* source of truth.
|
|
1398
|
+
*
|
|
1399
|
+
* Two kinds of entry (mirroring the frontend):
|
|
1400
|
+
* - "single": one value field whose value is a string id chosen from a
|
|
1401
|
+
* catalog. `options` carries the full flattened catalog (id/label/
|
|
1402
|
+
* description/category/promptHint), so a consumer can render a picker or
|
|
1403
|
+
* resolve an id → prompt fragment without importing the heavy frontend
|
|
1404
|
+
* registry.
|
|
1405
|
+
* - "multi": several value fields (e.g. Framing.shotSize + .angle + …).
|
|
1406
|
+
* Structured / multi-dimensional. There is no single catalog to flatten,
|
|
1407
|
+
* so instead of top-level `options` each multi entry carries a
|
|
1408
|
+
* `dimensions` array — one self-describing entry per field
|
|
1409
|
+
* ({ field, label, options }) in `fields` order — so a consumer can render
|
|
1410
|
+
* a per-field picker or resolve any field's id → prompt fragment without
|
|
1411
|
+
* importing the heavy frontend registry.
|
|
1412
|
+
*
|
|
1413
|
+
* A drift-guard test (`frontend/src/lib/__tests__/picker-catalogs-sync.test.ts`)
|
|
1414
|
+
* asserts parity between this registry and the frontend one so the two cannot
|
|
1415
|
+
* silently diverge.
|
|
1416
|
+
*
|
|
1417
|
+
* NOTE on `promptHint` for the four Object-entity catalogs (animal / vehicle /
|
|
1418
|
+
* weapon / furniture): those catalog entries do NOT carry a `promptHint`
|
|
1419
|
+
* field — at runtime `getParameterPromptHint` synthesizes the fragment from
|
|
1420
|
+
* `label` + `description` ("featuring a golden retriever, …"). We reproduce the
|
|
1421
|
+
* exact same phrasing here so each option's `promptHint` is non-empty AND
|
|
1422
|
+
* matches what actually gets injected downstream.
|
|
1423
|
+
*/
|
|
1424
|
+
interface PickerOption {
|
|
1425
|
+
readonly id: string;
|
|
1426
|
+
readonly label: string;
|
|
1427
|
+
readonly description?: string;
|
|
1428
|
+
/** The group id (matches `categoryOrder` / `categoryLabels`). */
|
|
1429
|
+
readonly category?: string;
|
|
1430
|
+
readonly promptHint: string;
|
|
1431
|
+
/** Only present if the source catalog entry already carries a data icon/emoji/thumbnail field. */
|
|
1432
|
+
readonly icon?: string;
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* A self-describing dimension of a multi-dim picker: one value field plus the
|
|
1436
|
+
* full option list valid for that field. `dimensions[i].field` mirrors the
|
|
1437
|
+
* frontend picker's `fields[i]` exactly (same order), so a consumer can render
|
|
1438
|
+
* a per-field picker or resolve an id → prompt fragment for any dimension
|
|
1439
|
+
* without importing the heavy frontend registry.
|
|
1440
|
+
*/
|
|
1441
|
+
interface PickerDimension {
|
|
1442
|
+
/** The node-data field this dimension writes to (e.g. "shotSize"). */
|
|
1443
|
+
readonly field: string;
|
|
1444
|
+
/** Human-readable label for the dimension (e.g. "Shot Size"). */
|
|
1445
|
+
readonly label: string;
|
|
1446
|
+
/** Flattened options valid for this field. */
|
|
1447
|
+
readonly options: readonly PickerOption[];
|
|
1448
|
+
}
|
|
1449
|
+
interface PickerCatalog {
|
|
1450
|
+
readonly nodeType: string;
|
|
1451
|
+
readonly label: string;
|
|
1452
|
+
/** The i18n catalog id (mirrors the frontend entry's `catalogId`). */
|
|
1453
|
+
readonly catalogId: string;
|
|
1454
|
+
readonly kind: "single" | "multi";
|
|
1455
|
+
/** single only — the node-data field the chosen id is written to. */
|
|
1456
|
+
readonly valueField?: string;
|
|
1457
|
+
/** single only — the catalog id selected by default. */
|
|
1458
|
+
readonly defaultValue?: string;
|
|
1459
|
+
readonly categoryOrder?: readonly string[];
|
|
1460
|
+
readonly categoryLabels?: Readonly<Record<string, string>>;
|
|
1461
|
+
/** single-dim: flattened catalog options. */
|
|
1462
|
+
readonly options?: readonly PickerOption[];
|
|
1463
|
+
/** multi-dim: the dimension keys (no single catalog to flatten). */
|
|
1464
|
+
readonly fields?: readonly string[];
|
|
1465
|
+
/** multi-dim: one self-describing entry per dimension field, in `fields` order. */
|
|
1466
|
+
readonly dimensions?: readonly PickerDimension[];
|
|
1467
|
+
}
|
|
1468
|
+
declare const PICKER_CATALOGS: readonly PickerCatalog[];
|
|
1469
|
+
/** Resolve a catalog by `nodeType` first, then by `catalogId`. */
|
|
1470
|
+
declare function getPickerCatalog(nodeTypeOrCatalogId: string): PickerCatalog | undefined;
|
|
1471
|
+
declare function listPickerCatalogs(): readonly PickerCatalog[];
|
|
1472
|
+
interface PickerCatalogSummary {
|
|
1473
|
+
readonly nodeType: string;
|
|
1474
|
+
readonly label: string;
|
|
1475
|
+
readonly catalogId: string;
|
|
1476
|
+
readonly kind: "single" | "multi";
|
|
1477
|
+
/** single only. */
|
|
1478
|
+
readonly valueField?: string;
|
|
1479
|
+
/** multi only. */
|
|
1480
|
+
readonly fields?: readonly string[];
|
|
1481
|
+
/** single: options.length; multi: sum of every dimension's options. */
|
|
1482
|
+
readonly optionCount: number;
|
|
1483
|
+
}
|
|
1484
|
+
/** Lightweight directory of every picker catalog — no option payloads. */
|
|
1485
|
+
declare function summarizePickerCatalogs(): readonly PickerCatalogSummary[];
|
|
1486
|
+
type PickerCatalogDetail = "compact" | "full";
|
|
1487
|
+
interface ProjectPickerCatalogOptions {
|
|
1488
|
+
/** Default "compact" (id/label/category/icon). "full" adds description + promptHint. */
|
|
1489
|
+
readonly detail?: PickerCatalogDetail;
|
|
1490
|
+
/** single-dim: keep only options in this category. */
|
|
1491
|
+
readonly category?: string;
|
|
1492
|
+
/** multi-dim: keep only this dimension field. */
|
|
1493
|
+
readonly field?: string;
|
|
1494
|
+
}
|
|
1495
|
+
/** An option after projection — description/promptHint present only when detail="full". */
|
|
1496
|
+
interface ProjectedPickerOption {
|
|
1497
|
+
readonly id: string;
|
|
1498
|
+
readonly label: string;
|
|
1499
|
+
readonly description?: string;
|
|
1500
|
+
readonly category?: string;
|
|
1501
|
+
readonly promptHint?: string;
|
|
1502
|
+
readonly icon?: string;
|
|
1503
|
+
}
|
|
1504
|
+
interface ProjectedPickerDimension {
|
|
1505
|
+
readonly field: string;
|
|
1506
|
+
readonly label: string;
|
|
1507
|
+
readonly options: readonly ProjectedPickerOption[];
|
|
1508
|
+
}
|
|
1509
|
+
interface ProjectedPickerCatalog {
|
|
1510
|
+
readonly nodeType: string;
|
|
1511
|
+
readonly label: string;
|
|
1512
|
+
readonly catalogId: string;
|
|
1513
|
+
readonly kind: "single" | "multi";
|
|
1514
|
+
readonly valueField?: string;
|
|
1515
|
+
readonly defaultValue?: string;
|
|
1516
|
+
readonly categoryOrder?: readonly string[];
|
|
1517
|
+
readonly categoryLabels?: Readonly<Record<string, string>>;
|
|
1518
|
+
readonly options?: readonly ProjectedPickerOption[];
|
|
1519
|
+
readonly fields?: readonly string[];
|
|
1520
|
+
readonly dimensions?: readonly ProjectedPickerDimension[];
|
|
1521
|
+
readonly detail: PickerCatalogDetail;
|
|
1522
|
+
}
|
|
1523
|
+
/** Project a catalog to the wire shape: compact by default, optional category/field filter. */
|
|
1524
|
+
declare function projectPickerCatalog(c: PickerCatalog, opts?: ProjectPickerCatalogOptions): ProjectedPickerCatalog;
|
|
1525
|
+
|
|
1526
|
+
/** A catalog entry as the analyzer consumes it. Flat catalogs lack
|
|
1527
|
+
* dimension/category; discriminated catalogs carry exactly one. */
|
|
1528
|
+
interface AnalyzerEntry {
|
|
1529
|
+
readonly id: string;
|
|
1530
|
+
readonly label: string;
|
|
1531
|
+
readonly description: string;
|
|
1532
|
+
readonly dimension?: string;
|
|
1533
|
+
readonly category?: string;
|
|
1534
|
+
}
|
|
1535
|
+
type PickerApplyMode = "override" | "overwrite-detected" | "fill-empty";
|
|
1536
|
+
type ApplyCleanup = (patch: Record<string, unknown>, mode: PickerApplyMode) => void;
|
|
1537
|
+
/** Describes how to build an analyzer spec for one picker type. Three shapes:
|
|
1538
|
+
* - "discriminated": ONE catalog whose entries carry `dimension` or `category`;
|
|
1539
|
+
* `order`/`fieldByKey`/`labels` translate keys → fields/labels; `limitFn`
|
|
1540
|
+
* gives the per-key cardinality.
|
|
1541
|
+
* - "flat": a single-value catalog (lens, camera-format) → one limit-1
|
|
1542
|
+
* dimension whose key == the node-data field. */
|
|
1543
|
+
type PickerAnalyzerDescriptor = {
|
|
1544
|
+
readonly kind: "discriminated";
|
|
1545
|
+
readonly toolName: string;
|
|
1546
|
+
readonly discriminator: "dimension" | "category";
|
|
1547
|
+
readonly order: ReadonlyArray<string>;
|
|
1548
|
+
readonly fieldByKey: Readonly<Record<string, string>>;
|
|
1549
|
+
readonly labels: Readonly<Record<string, string>>;
|
|
1550
|
+
readonly entries: ReadonlyArray<AnalyzerEntry>;
|
|
1551
|
+
readonly limitFn: (key: string) => number;
|
|
1552
|
+
readonly excludedIds?: ReadonlySet<string>;
|
|
1553
|
+
readonly cleanup?: ApplyCleanup;
|
|
1554
|
+
} | {
|
|
1555
|
+
readonly kind: "flat";
|
|
1556
|
+
readonly toolName: string;
|
|
1557
|
+
readonly field: string;
|
|
1558
|
+
readonly label: string;
|
|
1559
|
+
readonly entries: ReadonlyArray<AnalyzerEntry>;
|
|
1560
|
+
};
|
|
1561
|
+
declare const PICKER_ANALYZER_REGISTRY: {
|
|
1562
|
+
person: {
|
|
1563
|
+
kind: "discriminated";
|
|
1564
|
+
toolName: string;
|
|
1565
|
+
discriminator: "dimension";
|
|
1566
|
+
order: ReadonlyArray<string>;
|
|
1567
|
+
fieldByKey: Readonly<Record<string, string>>;
|
|
1568
|
+
labels: Readonly<Record<string, string>>;
|
|
1569
|
+
entries: ReadonlyArray<AnalyzerEntry>;
|
|
1570
|
+
limitFn: (k: string) => number;
|
|
1571
|
+
excludedIds: Set<string>;
|
|
1572
|
+
cleanup: ApplyCleanup;
|
|
1573
|
+
};
|
|
1574
|
+
styling: {
|
|
1575
|
+
kind: "discriminated";
|
|
1576
|
+
toolName: string;
|
|
1577
|
+
discriminator: "dimension";
|
|
1578
|
+
order: ReadonlyArray<string>;
|
|
1579
|
+
fieldByKey: Readonly<Record<string, string>>;
|
|
1580
|
+
labels: Readonly<Record<string, string>>;
|
|
1581
|
+
entries: ReadonlyArray<AnalyzerEntry>;
|
|
1582
|
+
limitFn: (k: string) => number;
|
|
1583
|
+
};
|
|
1584
|
+
framing: {
|
|
1585
|
+
kind: "discriminated";
|
|
1586
|
+
toolName: string;
|
|
1587
|
+
discriminator: "category";
|
|
1588
|
+
order: ReadonlyArray<string>;
|
|
1589
|
+
fieldByKey: Readonly<Record<string, string>>;
|
|
1590
|
+
labels: Readonly<Record<string, string>>;
|
|
1591
|
+
entries: ReadonlyArray<AnalyzerEntry>;
|
|
1592
|
+
limitFn: (k: string) => number;
|
|
1593
|
+
};
|
|
1594
|
+
lens: {
|
|
1595
|
+
kind: "flat";
|
|
1596
|
+
toolName: string;
|
|
1597
|
+
field: string;
|
|
1598
|
+
label: string;
|
|
1599
|
+
entries: ReadonlyArray<AnalyzerEntry>;
|
|
1600
|
+
};
|
|
1601
|
+
"camera-format": {
|
|
1602
|
+
kind: "flat";
|
|
1603
|
+
toolName: string;
|
|
1604
|
+
field: string;
|
|
1605
|
+
label: string;
|
|
1606
|
+
entries: ReadonlyArray<AnalyzerEntry>;
|
|
1607
|
+
};
|
|
1608
|
+
};
|
|
1609
|
+
type PickerType = keyof typeof PICKER_ANALYZER_REGISTRY;
|
|
1610
|
+
declare const PICKER_TYPES: PickerType[];
|
|
1611
|
+
declare const ANALYZABLE_PICKER_TYPES: ReadonlySet<string>;
|
|
1612
|
+
declare function isAnalyzablePicker(t: string): t is PickerType;
|
|
1613
|
+
interface PickerDimensionSpec {
|
|
1614
|
+
/** Catalog dimension id, e.g. "hair-color". Also the JSON key in the emitted pickerJson. */
|
|
1615
|
+
readonly dimension: string;
|
|
1616
|
+
/** Target node-data field, e.g. "hairColor". */
|
|
1617
|
+
readonly field: string;
|
|
1618
|
+
/** Human label/description, for the system-prompt legend. */
|
|
1619
|
+
readonly label: string;
|
|
1620
|
+
/** 1 = single select; 2/3 = array with maxItems. */
|
|
1621
|
+
readonly limit: number;
|
|
1622
|
+
/** Allowed catalog entry ids (the forced enum). */
|
|
1623
|
+
readonly entryIds: ReadonlyArray<string>;
|
|
1624
|
+
/** id → human label/description, for the system-prompt legend. */
|
|
1625
|
+
readonly legend: ReadonlyArray<{
|
|
1626
|
+
id: string;
|
|
1627
|
+
label: string;
|
|
1628
|
+
description: string;
|
|
1629
|
+
}>;
|
|
1630
|
+
}
|
|
1631
|
+
interface PickerAnalyzerSpec {
|
|
1632
|
+
readonly pickerType: PickerType;
|
|
1633
|
+
readonly toolName: string;
|
|
1634
|
+
readonly dimensions: ReadonlyArray<PickerDimensionSpec>;
|
|
1635
|
+
readonly cleanup?: ApplyCleanup;
|
|
1636
|
+
}
|
|
1637
|
+
declare function buildPickerAnalyzerSpec(pickerType: PickerType): PickerAnalyzerSpec;
|
|
1638
|
+
/** Zod object: each dimension is an optional enum (single) or capped enum array
|
|
1639
|
+
* (multi). `.strict()` blocks unknown keys. Mirrors the field cardinality. */
|
|
1640
|
+
declare function buildPickerZodSchema(spec: PickerAnalyzerSpec): z.ZodType<Record<string, string | string[]>, z.ZodTypeDef, unknown>;
|
|
1641
|
+
interface PickerAnalyzer {
|
|
1642
|
+
readonly spec: PickerAnalyzerSpec;
|
|
1643
|
+
readonly schema: z.ZodType<Record<string, string | string[]>, z.ZodTypeDef, unknown>;
|
|
1644
|
+
readonly legend: string;
|
|
1645
|
+
}
|
|
1646
|
+
/** Memoized analyzer build: spec → Zod schema → legend, computed once per
|
|
1647
|
+
* picker type and cached at module level. The three artifacts are catalog-
|
|
1648
|
+
* derived and stable, so the per-request route handler can reuse them instead
|
|
1649
|
+
* of rebuilding all three on every analysis call. */
|
|
1650
|
+
declare function getPickerAnalyzer(pickerType: PickerType): PickerAnalyzer;
|
|
1651
|
+
declare const GAPS_SCHEMA: z.ZodDefault<z.ZodObject<{
|
|
1652
|
+
missingItems: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1653
|
+
picker: z.ZodString;
|
|
1654
|
+
dimension: z.ZodString;
|
|
1655
|
+
observed: z.ZodString;
|
|
1656
|
+
}, "strip", z.ZodTypeAny, {
|
|
1657
|
+
picker: string;
|
|
1658
|
+
dimension: string;
|
|
1659
|
+
observed: string;
|
|
1660
|
+
}, {
|
|
1661
|
+
picker: string;
|
|
1662
|
+
dimension: string;
|
|
1663
|
+
observed: string;
|
|
1664
|
+
}>, "many">>;
|
|
1665
|
+
missingCategories: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1666
|
+
picker: z.ZodString;
|
|
1667
|
+
suggestedDimension: z.ZodString;
|
|
1668
|
+
observed: z.ZodString;
|
|
1669
|
+
}, "strip", z.ZodTypeAny, {
|
|
1670
|
+
picker: string;
|
|
1671
|
+
observed: string;
|
|
1672
|
+
suggestedDimension: string;
|
|
1673
|
+
}, {
|
|
1674
|
+
picker: string;
|
|
1675
|
+
observed: string;
|
|
1676
|
+
suggestedDimension: string;
|
|
1677
|
+
}>, "many">>;
|
|
1678
|
+
}, "strip", z.ZodTypeAny, {
|
|
1679
|
+
missingItems: {
|
|
1680
|
+
picker: string;
|
|
1681
|
+
dimension: string;
|
|
1682
|
+
observed: string;
|
|
1683
|
+
}[];
|
|
1684
|
+
missingCategories: {
|
|
1685
|
+
picker: string;
|
|
1686
|
+
observed: string;
|
|
1687
|
+
suggestedDimension: string;
|
|
1688
|
+
}[];
|
|
1689
|
+
}, {
|
|
1690
|
+
missingItems?: {
|
|
1691
|
+
picker: string;
|
|
1692
|
+
dimension: string;
|
|
1693
|
+
observed: string;
|
|
1694
|
+
}[] | undefined;
|
|
1695
|
+
missingCategories?: {
|
|
1696
|
+
picker: string;
|
|
1697
|
+
observed: string;
|
|
1698
|
+
suggestedDimension: string;
|
|
1699
|
+
}[] | undefined;
|
|
1700
|
+
}>>;
|
|
1701
|
+
interface PickerGaps {
|
|
1702
|
+
readonly missingItems: ReadonlyArray<{
|
|
1703
|
+
picker: string;
|
|
1704
|
+
dimension: string;
|
|
1705
|
+
observed: string;
|
|
1706
|
+
}>;
|
|
1707
|
+
readonly missingCategories: ReadonlyArray<{
|
|
1708
|
+
picker: string;
|
|
1709
|
+
suggestedDimension: string;
|
|
1710
|
+
observed: string;
|
|
1711
|
+
}>;
|
|
1712
|
+
}
|
|
1713
|
+
interface MultiPickerAnalyzerSpec {
|
|
1714
|
+
readonly schema: z.ZodType<Record<string, unknown>, z.ZodTypeDef, unknown>;
|
|
1715
|
+
readonly toolName: string;
|
|
1716
|
+
readonly legend: string;
|
|
1717
|
+
}
|
|
1718
|
+
/** Build ONE forced-tool schema spanning the given pickers (each section
|
|
1719
|
+
* optional so an omitted picker doesn't trigger a validation retry) plus the
|
|
1720
|
+
* capped `gaps` sidecar. Memoized by the sorted picker-set key. */
|
|
1721
|
+
declare function buildMultiPickerAnalyzerSpec(types: ReadonlyArray<PickerType>): MultiPickerAnalyzerSpec;
|
|
1722
|
+
/** Human-readable legend appended to the system prompt so enum ids are meaningful. */
|
|
1723
|
+
declare function buildPickerLegend(spec: PickerAnalyzerSpec): string;
|
|
1724
|
+
/**
|
|
1725
|
+
* Produces the patch to merge into the picker node's data. Touches ONLY the
|
|
1726
|
+
* dimension fields (never label/preText/postText/maxItemsPerRow). `override`
|
|
1727
|
+
* also clears undetected dimension fields, and runs the picker's `cleanup`
|
|
1728
|
+
* (e.g. person resets customAge + clears the deprecated `lips` field).
|
|
1729
|
+
*/
|
|
1730
|
+
declare function applyPickerJson(current: Record<string, unknown>, pickerJson: Record<string, unknown>, mode: PickerApplyMode, spec: PickerAnalyzerSpec): Record<string, unknown>;
|
|
1731
|
+
/** The analyzable picker node types wired to a producer's `picker-json` output
|
|
1732
|
+
* (deduped). The ONE definition of edge-derived selection; the frontend
|
|
1733
|
+
* execute path and the backend orchestrator both call this so they can't
|
|
1734
|
+
* drift. Accepts minimal structural node/edge shapes so both layers' richer
|
|
1735
|
+
* types satisfy it. */
|
|
1736
|
+
declare function pickerFanoutTargets(producerId: string, edges: ReadonlyArray<{
|
|
1737
|
+
source: string;
|
|
1738
|
+
target: string;
|
|
1739
|
+
sourceHandle?: string | null;
|
|
1740
|
+
}>, nodes: ReadonlyArray<{
|
|
1741
|
+
id: string;
|
|
1742
|
+
type?: string;
|
|
1743
|
+
}>): PickerType[];
|
|
1744
|
+
|
|
1745
|
+
/**
|
|
1746
|
+
* Canonical catalog of Action FX choices.
|
|
1747
|
+
*
|
|
1748
|
+
* Action FX describes a discrete, dramatic, high-energy event happening in the
|
|
1749
|
+
* scene — an explosion mid-blast, a lightning bolt striking, an earthquake
|
|
1750
|
+
* fracturing the ground, a magic fireball spell, a force field shimmering.
|
|
1751
|
+
*
|
|
1752
|
+
* Distinct from:
|
|
1753
|
+
* - Atmosphere — continuous environmental state (rain, fog, smoke, dust).
|
|
1754
|
+
* - Composition Effects — how the subject itself is rendered (smoke
|
|
1755
|
+
* sculpture, exploding-particle silhouette, glitch).
|
|
1756
|
+
* - Post-Process Effects — image-grading passes (vignette, grain, halation).
|
|
1757
|
+
* - Color Look — overall color grade direction.
|
|
1758
|
+
*
|
|
1759
|
+
* Multi-pick: 1–2 ids → composite FX clause. Pure prompt text, zero credits,
|
|
1760
|
+
* zero API calls. Shared between picker UI and prompt-hint injection on
|
|
1761
|
+
* frontend DAG executor + backend orchestrator.
|
|
1762
|
+
*/
|
|
1763
|
+
type ActionFxCategory = "disaster" | "fire-blasts" | "electric" | "combat" | "sci-fi" | "magic";
|
|
1764
|
+
interface ActionFx {
|
|
1765
|
+
readonly id: string;
|
|
1766
|
+
readonly label: string;
|
|
1767
|
+
readonly category: ActionFxCategory;
|
|
1768
|
+
readonly description: string;
|
|
1769
|
+
readonly promptHint: string;
|
|
1770
|
+
}
|
|
1771
|
+
declare const ACTION_FX_CATEGORY_ORDER: ReadonlyArray<ActionFxCategory>;
|
|
1772
|
+
declare const ACTION_FX_CATEGORY_LABELS: Readonly<Record<ActionFxCategory, string>>;
|
|
1773
|
+
declare const ACTION_FX: ReadonlyArray<ActionFx>;
|
|
1774
|
+
declare const ACTION_FX_IDS: ReadonlyArray<string>;
|
|
1775
|
+
declare function getActionFx(id: string | undefined | null): ActionFx | undefined;
|
|
1776
|
+
declare function getActionFxLabel(id: string | undefined | null, fallback?: string): string;
|
|
1777
|
+
declare function getActionFxPromptHint(id: string | undefined | null): string;
|
|
1778
|
+
/**
|
|
1779
|
+
* Multi-pick: 1–2 ids → composite FX clause.
|
|
1780
|
+
*
|
|
1781
|
+
* Single id → entry's own promptHint as a single-element array.
|
|
1782
|
+
* Two ids → emit each independently and let the comma-join compose them.
|
|
1783
|
+
* Caps at 2 ids (silently drops the rest); the picker UI also enforces this
|
|
1784
|
+
* cap, but the cap here keeps the contract robust against stale workflow
|
|
1785
|
+
* data. Duplicate ids are deduplicated before the cap is applied.
|
|
1786
|
+
*/
|
|
1787
|
+
declare function buildActionFxHints(value: unknown): string[];
|
|
1788
|
+
|
|
1789
|
+
/**
|
|
1790
|
+
* Canonical catalog of Aesthetic / Microtrend choices.
|
|
1791
|
+
*
|
|
1792
|
+
* Single-pick parameter node — user picks ONE microtrend bundle that
|
|
1793
|
+
* captures wardrobe + setting + grade + mood in a single descriptor.
|
|
1794
|
+
* Microtrends are dense, model-recognised tokens (Y2K, dark academia,
|
|
1795
|
+
* cottagecore, gorpcore...) that pull a coherent visual world along with
|
|
1796
|
+
* the name. Each promptHint expands the slang into the specific wardrobe
|
|
1797
|
+
* cues, environment cues and color treatment that define the look.
|
|
1798
|
+
*
|
|
1799
|
+
* Categories:
|
|
1800
|
+
* - mainstream: high-recognition microtrends with a stable visual signature
|
|
1801
|
+
* - niche: smaller -core / -kei / -punk movements
|
|
1802
|
+
* - era: fashion eras / sensibilities (minimalism, maximalism, glam)
|
|
1803
|
+
* - mood: cultural mood-bundles (effortless cool, main-character energy)
|
|
1804
|
+
*
|
|
1805
|
+
* Shared between the picker UI, the standalone Aesthetic parameter node,
|
|
1806
|
+
* and the prompt-hint injection on both the frontend DAG executor and the
|
|
1807
|
+
* backend orchestrator.
|
|
1808
|
+
*/
|
|
1809
|
+
type AestheticCategory = "mainstream" | "niche" | "era" | "mood";
|
|
1810
|
+
interface Aesthetic {
|
|
1811
|
+
readonly id: string;
|
|
1812
|
+
readonly label: string;
|
|
1813
|
+
readonly category: AestheticCategory;
|
|
1814
|
+
readonly description: string;
|
|
1815
|
+
readonly promptHint: string;
|
|
1816
|
+
}
|
|
1817
|
+
declare const AESTHETICS: ReadonlyArray<Aesthetic>;
|
|
1818
|
+
declare function getAesthetic(id: string | undefined | null): Aesthetic | undefined;
|
|
1819
|
+
declare function getAestheticLabel(id: string | undefined | null, fallback?: string): string;
|
|
1820
|
+
declare function getAestheticPromptHint(id: string | undefined | null): string;
|
|
1821
|
+
/**
|
|
1822
|
+
* Multi-pick variant: 1-2 aesthetic ids → blended hint. Single → entry's
|
|
1823
|
+
* own promptHint. Two → "styled in a {A} + {B} aesthetic blend" with
|
|
1824
|
+
* canonical entry labels (Y2K, dark academia, etc. stay as written).
|
|
1825
|
+
*/
|
|
1826
|
+
declare function buildAestheticHints(value: unknown): string;
|
|
1827
|
+
declare const AESTHETIC_IDS: ReadonlyArray<string>;
|
|
1828
|
+
declare const AESTHETIC_CATEGORY_LABELS: Readonly<Record<AestheticCategory, string>>;
|
|
1829
|
+
declare const AESTHETIC_CATEGORY_ORDER: ReadonlyArray<AestheticCategory>;
|
|
1830
|
+
|
|
1831
|
+
/**
|
|
1832
|
+
* Canonical catalog of atmosphere / environmental effects.
|
|
1833
|
+
*
|
|
1834
|
+
* Atmosphere dimension of a shot — environmental elements in the air that
|
|
1835
|
+
* affect visibility and mood (rain, fog, god rays, particles). Independent
|
|
1836
|
+
* of lighting (color/direction of light) and color/look (post-processing
|
|
1837
|
+
* tone). A sunny scene with fog has different atmosphere than a clear sunny
|
|
1838
|
+
* scene, even with identical subject, lighting and color grade.
|
|
1839
|
+
*
|
|
1840
|
+
* Shared between the picker UI and the prompt-hint injection on both the
|
|
1841
|
+
* frontend DAG executor and the backend orchestrator.
|
|
1842
|
+
*/
|
|
1843
|
+
interface Atmosphere {
|
|
1844
|
+
readonly id: string;
|
|
1845
|
+
readonly label: string;
|
|
1846
|
+
readonly description: string;
|
|
1847
|
+
readonly promptHint: string;
|
|
1848
|
+
}
|
|
1849
|
+
declare const ATMOSPHERES: ReadonlyArray<Atmosphere>;
|
|
1850
|
+
declare function getAtmosphere(id: string | undefined | null): Atmosphere | undefined;
|
|
1851
|
+
declare function getAtmosphereLabel(id: string | undefined | null, fallback?: string): string;
|
|
1852
|
+
declare function getAtmospherePromptHint(id: string | undefined | null): string;
|
|
1853
|
+
/**
|
|
1854
|
+
* Multi-pick: 1-2 atmosphere ids → composite atmospheric clause. Single →
|
|
1855
|
+
* entry's own promptHint. Two → emit independently and join — atmospheres
|
|
1856
|
+
* are particle-effect descriptions that compose naturally
|
|
1857
|
+
* ("fog drifting in soft cool clouds, with golden god-rays cutting through").
|
|
1858
|
+
*/
|
|
1859
|
+
declare function buildAtmosphereHints(value: unknown): string[];
|
|
1860
|
+
declare const ATMOSPHERE_IDS: ReadonlyArray<string>;
|
|
1861
|
+
|
|
1862
|
+
/**
|
|
1863
|
+
* Canonical catalog of Backdrop / studio-background presets.
|
|
1864
|
+
*
|
|
1865
|
+
* Single-pick parameter node — user picks ONE backdrop describing the
|
|
1866
|
+
* controlled wall / surface / effect *immediately behind the subject*.
|
|
1867
|
+
* Distinct from Setting (which describes the location or environment a
|
|
1868
|
+
* shot takes place in). Backdrop is the studio convention behind the
|
|
1869
|
+
* subject during a portrait, fashion, beauty, e-commerce, or product
|
|
1870
|
+
* shoot — the seamless paper, painted wall, gradient sweep, or lit
|
|
1871
|
+
* effect that frames the subject.
|
|
1872
|
+
*
|
|
1873
|
+
* For full environments (cafe, forest, alley) use the Setting node.
|
|
1874
|
+
* For artistic medium use Style. For "in the air" particles use
|
|
1875
|
+
* Atmosphere. Backdrop occupies the narrow, well-defined slot of
|
|
1876
|
+
* "what wall is this person standing in front of."
|
|
1877
|
+
*
|
|
1878
|
+
* Applies to both image and video consumers (a studio backdrop carries
|
|
1879
|
+
* over to motion shoots). Not in STILL_IMAGE_EXCLUDE_TYPES.
|
|
1880
|
+
*
|
|
1881
|
+
* Shared between the picker UI, the standalone Backdrop parameter
|
|
1882
|
+
* node, and the prompt-hint injection on both the frontend DAG executor
|
|
1883
|
+
* and the backend orchestrator.
|
|
1884
|
+
*/
|
|
1885
|
+
type BackdropCategory = "solid" | "gradient" | "textured" | "fabric" | "effect" | "reflective";
|
|
1886
|
+
interface Backdrop {
|
|
1887
|
+
readonly id: string;
|
|
1888
|
+
readonly label: string;
|
|
1889
|
+
readonly category: BackdropCategory;
|
|
1890
|
+
readonly description: string;
|
|
1891
|
+
readonly promptHint: string;
|
|
1892
|
+
}
|
|
1893
|
+
declare const BACKDROPS: ReadonlyArray<Backdrop>;
|
|
1894
|
+
declare function getBackdrop(id: string | undefined | null): Backdrop | undefined;
|
|
1895
|
+
declare function getBackdropLabel(id: string | undefined | null, fallback?: string): string;
|
|
1896
|
+
declare function getBackdropPromptHint(id: string | undefined | null): string;
|
|
1897
|
+
declare const BACKDROP_IDS: ReadonlyArray<string>;
|
|
1898
|
+
declare const BACKDROP_CATEGORY_LABELS: Readonly<Record<BackdropCategory, string>>;
|
|
1899
|
+
declare const BACKDROP_CATEGORY_ORDER: ReadonlyArray<BackdropCategory>;
|
|
1900
|
+
|
|
1901
|
+
/**
|
|
1902
|
+
* Canonical catalog of camera / film-stock choices.
|
|
1903
|
+
*
|
|
1904
|
+
* Capture-medium dimension of a shot — the physical or simulated sensor / film
|
|
1905
|
+
* stock and its associated grain, color science, and aspect treatment. Independent
|
|
1906
|
+
* of optics (lens), framing (shot size + composition), and camera motion.
|
|
1907
|
+
*
|
|
1908
|
+
* Shared between the picker UI and the prompt-hint injection on both the
|
|
1909
|
+
* frontend DAG executor and the backend orchestrator.
|
|
1910
|
+
*/
|
|
1911
|
+
interface CameraFormat {
|
|
1912
|
+
readonly id: string;
|
|
1913
|
+
readonly label: string;
|
|
1914
|
+
readonly description: string;
|
|
1915
|
+
readonly promptHint: string;
|
|
1916
|
+
}
|
|
1917
|
+
declare const CAMERA_FORMATS: ReadonlyArray<CameraFormat>;
|
|
1918
|
+
declare function getCameraFormat(id: string | undefined | null): CameraFormat | undefined;
|
|
1919
|
+
declare function getCameraFormatLabel(id: string | undefined | null, fallback?: string): string;
|
|
1920
|
+
declare function getCameraFormatPromptHint(id: string | undefined | null): string;
|
|
1921
|
+
declare const CAMERA_FORMAT_IDS: ReadonlyArray<string>;
|
|
1922
|
+
|
|
1923
|
+
/**
|
|
1924
|
+
* Canonical catalog of camera motions for video / image-to-video generation.
|
|
1925
|
+
*
|
|
1926
|
+
* Shared between frontend (picker UI, prompt hint injection) and backend
|
|
1927
|
+
* (orchestrator payload builder). The `promptHint` is a natural-language
|
|
1928
|
+
* cue that gets appended to the user prompt when the node has camera
|
|
1929
|
+
* motion enabled.
|
|
1930
|
+
*/
|
|
1931
|
+
type CameraMotionCategory = "default" | "pan" | "tilt" | "zoom" | "dolly" | "truck" | "pedestal" | "roll" | "orbit" | "crane" | "tracking" | "special";
|
|
1932
|
+
interface CameraMotion {
|
|
1933
|
+
readonly id: string;
|
|
1934
|
+
readonly label: string;
|
|
1935
|
+
readonly category: CameraMotionCategory;
|
|
1936
|
+
readonly description: string;
|
|
1937
|
+
readonly promptHint: string;
|
|
1938
|
+
}
|
|
1939
|
+
declare const CAMERA_MOTIONS: ReadonlyArray<CameraMotion>;
|
|
1940
|
+
declare const CAMERA_MOTION_CATEGORY_ORDER: ReadonlyArray<CameraMotionCategory>;
|
|
1941
|
+
declare const CAMERA_MOTION_CATEGORY_LABELS: Record<CameraMotionCategory, string>;
|
|
1942
|
+
declare function getCameraMotion(id: string | undefined | null): CameraMotion | undefined;
|
|
1943
|
+
/** Human-readable label for the given motion id. Falls back to the id if unknown. */
|
|
1944
|
+
declare function getCameraMotionLabel(id: string | undefined | null, fallback?: string): string;
|
|
1945
|
+
/** Descriptive prompt hint for the given motion id. Empty string when motion is "auto" or unknown. */
|
|
1946
|
+
declare function getCameraMotionPromptHint(id: string | undefined | null): string;
|
|
1947
|
+
declare const CAMERA_MOTION_IDS: ReadonlyArray<string>;
|
|
1948
|
+
/**
|
|
1949
|
+
* Compose a structural prompt-hint sentence from a camera-motion id plus
|
|
1950
|
+
* arrays of start-state and end-state promptHints (collected by walking
|
|
1951
|
+
* the source camera-motion node's startState / endState input handles
|
|
1952
|
+
* upstream to find connected parameter nodes).
|
|
1953
|
+
*
|
|
1954
|
+
* - No connected nodes → bare motion promptHint.
|
|
1955
|
+
* - Start only → "<motion>, beginning with <start hints joined>".
|
|
1956
|
+
* - End only → "<motion>, ending with <end hints joined>".
|
|
1957
|
+
* - Both → "<motion>, beginning with <start>, ending with <end>".
|
|
1958
|
+
*
|
|
1959
|
+
* Hints within each side are joined with " and " for grammatical flow.
|
|
1960
|
+
* If multiple nodes are connected (e.g. Framing + Lighting + Tone), all
|
|
1961
|
+
* three contribute their hint to the clause.
|
|
1962
|
+
*/
|
|
1963
|
+
declare function composeCameraMotionHintFromConnections(motionId: string | undefined, startHints: ReadonlyArray<string>, endHints: ReadonlyArray<string>): string;
|
|
1964
|
+
|
|
1965
|
+
/**
|
|
1966
|
+
* Canonical catalog of character-driven effects for AI-video generation.
|
|
1967
|
+
*
|
|
1968
|
+
* Shared between frontend (picker UI, prompt hint injection) and backend
|
|
1969
|
+
* (orchestrator payload builder). The `promptHint` is a natural-language
|
|
1970
|
+
* cue that gets composed into the user prompt when a character-fx node
|
|
1971
|
+
* is connected to a video consumer.
|
|
1972
|
+
*
|
|
1973
|
+
* Every `promptHint` references "the subject" at least once — the composer
|
|
1974
|
+
* does a global regex replace of "the subject" with the target ref's
|
|
1975
|
+
* display name (character/face/object/location) when a target is wired.
|
|
1976
|
+
*
|
|
1977
|
+
* Multi-pick supported: value field accepts `string | string[]` (cap 2).
|
|
1978
|
+
* Per-id substitution: each base hint is independently rewritten BEFORE
|
|
1979
|
+
* the join, so "Aria transforms into a werewolf, and Aria opens their
|
|
1980
|
+
* mouth and exhales..." reads correctly.
|
|
1981
|
+
*
|
|
1982
|
+
* null input is treated like undefined (falsy short-circuit → returns "")
|
|
1983
|
+
*/
|
|
1984
|
+
type CharacterFxCategory = "transformation" | "power" | "body-mod" | "face-expression" | "aura-ambient";
|
|
1985
|
+
interface CharacterFx {
|
|
1986
|
+
readonly id: string;
|
|
1987
|
+
readonly label: string;
|
|
1988
|
+
readonly category: CharacterFxCategory;
|
|
1989
|
+
readonly description: string;
|
|
1990
|
+
readonly promptHint: string;
|
|
1991
|
+
}
|
|
1992
|
+
type CharacterFxPosition = "auto" | "start" | "middle" | "end" | "full";
|
|
1993
|
+
type CharacterFxDuration = "auto" | "instant" | "short" | "medium" | "long";
|
|
1994
|
+
type CharacterFxIntensity = "auto" | "subtle" | "natural" | "dynamic" | "crazy";
|
|
1995
|
+
interface CharacterFxTiming {
|
|
1996
|
+
position?: CharacterFxPosition;
|
|
1997
|
+
duration?: CharacterFxDuration;
|
|
1998
|
+
intensity?: CharacterFxIntensity;
|
|
1999
|
+
}
|
|
2000
|
+
declare const CHARACTER_FX: ReadonlyArray<CharacterFx>;
|
|
2001
|
+
declare const CHARACTER_FX_CATEGORY_ORDER: ReadonlyArray<CharacterFxCategory>;
|
|
2002
|
+
declare const CHARACTER_FX_CATEGORY_LABELS: Readonly<Record<CharacterFxCategory, string>>;
|
|
2003
|
+
declare function getCharacterFx(id: string | undefined | null): CharacterFx | undefined;
|
|
2004
|
+
declare function getCharacterFxLabel(id: string | undefined | null, fallback?: string): string;
|
|
2005
|
+
declare function getCharacterFxPromptHint(id: string | undefined | null): string;
|
|
2006
|
+
declare const CHARACTER_FX_IDS: ReadonlyArray<string>;
|
|
2007
|
+
/**
|
|
2008
|
+
* Compose a character-fx prompt-hint sentence from an effect id (or array
|
|
2009
|
+
* of 1-2 ids for multi-pick) plus target-ref display names (from upstream
|
|
2010
|
+
* character/face/object/location nodes wired to the `target` handle) plus
|
|
2011
|
+
* optional timing fields.
|
|
2012
|
+
*
|
|
2013
|
+
* Substitution: each base hint has every `"the subject"` occurrence
|
|
2014
|
+
* rewritten to the target name BEFORE the join. Empty targetHints leaves
|
|
2015
|
+
* "the subject" intact in the prompt.
|
|
2016
|
+
*/
|
|
2017
|
+
declare function composeCharacterFxHintFromConnections(effectId: string | ReadonlyArray<string> | undefined, targetHints: ReadonlyArray<string>, timing?: CharacterFxTiming): string;
|
|
2018
|
+
|
|
2019
|
+
/**
|
|
2020
|
+
* Canonical catalog of color/look choices.
|
|
2021
|
+
*
|
|
2022
|
+
* Color/look is a multi-category dimension of a shot — it covers both
|
|
2023
|
+
* stylistic color palettes (warm, cool, teal-orange, etc.) and film-stock
|
|
2024
|
+
* emulations (Kodak Portra, Cinestill 800T, bleach bypass, etc.). Independent
|
|
2025
|
+
* of optics (lens), framing, camera motion, capture medium (camera-format),
|
|
2026
|
+
* and lighting setup.
|
|
2027
|
+
*
|
|
2028
|
+
* Shared between the picker UI and the prompt-hint injection on both the
|
|
2029
|
+
* frontend DAG executor and the backend orchestrator.
|
|
2030
|
+
*/
|
|
2031
|
+
type ColorLookCategory = "palette" | "film-emulation" | "social-preset";
|
|
2032
|
+
interface ColorLook {
|
|
2033
|
+
readonly id: string;
|
|
2034
|
+
readonly label: string;
|
|
2035
|
+
readonly category: ColorLookCategory;
|
|
2036
|
+
readonly description: string;
|
|
2037
|
+
readonly promptHint: string;
|
|
2038
|
+
}
|
|
2039
|
+
declare const COLOR_LOOKS: ReadonlyArray<ColorLook>;
|
|
2040
|
+
declare const COLOR_LOOK_CATEGORY_ORDER: ReadonlyArray<ColorLookCategory>;
|
|
2041
|
+
declare const COLOR_LOOK_CATEGORY_LABELS: Record<ColorLookCategory, string>;
|
|
2042
|
+
declare function getColorLook(id: string | undefined | null): ColorLook | undefined;
|
|
2043
|
+
declare function getColorLookLabel(id: string | undefined | null, fallback?: string): string;
|
|
2044
|
+
declare function getColorLookPromptHint(id: string | undefined | null): string;
|
|
2045
|
+
declare const COLOR_LOOK_IDS: ReadonlyArray<string>;
|
|
2046
|
+
|
|
2047
|
+
/**
|
|
2048
|
+
* Canonical catalog of Composition Effects choices.
|
|
2049
|
+
*
|
|
2050
|
+
* Composition Effects describe a "compositional trick" applied to the subject
|
|
2051
|
+
* — how the subject interacts with the canvas/frame, what material it's made
|
|
2052
|
+
* of, or what compositional gimmick frames it. This is distinct from the post-
|
|
2053
|
+
* processing image grade (Post-Process Effects) and from the artistic style
|
|
2054
|
+
* (Style): an "exploding particles" composition effect can be applied to an
|
|
2055
|
+
* oil painting style or a photorealistic style equally well.
|
|
2056
|
+
*
|
|
2057
|
+
* Single-pick — only one composition trick is applied per consumer. Pure
|
|
2058
|
+
* prompt text, zero credits, zero API calls.
|
|
2059
|
+
*
|
|
2060
|
+
* Shared between picker UI and prompt-hint injection in the frontend DAG
|
|
2061
|
+
* executor and the backend orchestrator.
|
|
2062
|
+
*/
|
|
2063
|
+
interface CompositionEffect {
|
|
2064
|
+
readonly id: string;
|
|
2065
|
+
readonly label: string;
|
|
2066
|
+
readonly description: string;
|
|
2067
|
+
readonly promptHint: string;
|
|
2068
|
+
}
|
|
2069
|
+
declare const COMPOSITION_EFFECTS: ReadonlyArray<CompositionEffect>;
|
|
2070
|
+
declare function getCompositionEffect(id: string | undefined | null): CompositionEffect | undefined;
|
|
2071
|
+
declare function getCompositionEffectLabel(id: string | undefined | null, fallback?: string): string;
|
|
2072
|
+
declare function getCompositionEffectPromptHint(id: string | undefined | null): string;
|
|
2073
|
+
declare const COMPOSITION_EFFECT_IDS: ReadonlyArray<string>;
|
|
2074
|
+
|
|
2075
|
+
/**
|
|
2076
|
+
* Canonical catalog of Era / Period choices.
|
|
2077
|
+
*
|
|
2078
|
+
* Single-pick parameter node — user picks ONE historical era or speculative
|
|
2079
|
+
* period. Each promptHint bundles wardrobe + environment + photographic
|
|
2080
|
+
* treatment so the model gets a coherent world rather than a stray decade
|
|
2081
|
+
* label. Color, lighting, grain and signature props are all part of the
|
|
2082
|
+
* descriptor because period-piece looks live or die on those cues.
|
|
2083
|
+
*
|
|
2084
|
+
* Categories:
|
|
2085
|
+
* - decade-20c: 20th-century decades from 1920s flapper to 2000s tabloid
|
|
2086
|
+
* - pre-modern: pre-20th-century historical eras (medieval -> Edwardian)
|
|
2087
|
+
* - speculative: future, retrofuture, post-apocalyptic, dieselpunk etc.
|
|
2088
|
+
*
|
|
2089
|
+
* Shared between the picker UI, the standalone Era parameter node, and the
|
|
2090
|
+
* prompt-hint injection on both the frontend DAG executor and the backend
|
|
2091
|
+
* orchestrator.
|
|
2092
|
+
*/
|
|
2093
|
+
type EraCategory = "decade-20c" | "pre-modern" | "speculative";
|
|
2094
|
+
interface Era {
|
|
2095
|
+
readonly id: string;
|
|
2096
|
+
readonly label: string;
|
|
2097
|
+
readonly category: EraCategory;
|
|
2098
|
+
readonly description: string;
|
|
2099
|
+
readonly promptHint: string;
|
|
2100
|
+
}
|
|
2101
|
+
declare const ERAS: ReadonlyArray<Era>;
|
|
2102
|
+
declare function getEra(id: string | undefined | null): Era | undefined;
|
|
2103
|
+
declare function getEraLabel(id: string | undefined | null, fallback?: string): string;
|
|
2104
|
+
declare function getEraPromptHint(id: string | undefined | null): string;
|
|
2105
|
+
declare const ERA_IDS: ReadonlyArray<string>;
|
|
2106
|
+
declare const ERA_CATEGORY_LABELS: Readonly<Record<EraCategory, string>>;
|
|
2107
|
+
declare const ERA_CATEGORY_ORDER: ReadonlyArray<EraCategory>;
|
|
2108
|
+
|
|
2109
|
+
/**
|
|
2110
|
+
* Canonical catalog of Exposure Settings choices.
|
|
2111
|
+
*
|
|
2112
|
+
* Exposure Settings is a multi-category dimension covering the core photographic
|
|
2113
|
+
* triangle that controls exposure and visual character: aperture (depth of field
|
|
2114
|
+
* and subject isolation), shutter speed (motion treatment), and ISO sensitivity
|
|
2115
|
+
* (grain quality and noise). Independent of optics (lens), lighting, framing,
|
|
2116
|
+
* camera motion, and capture medium (camera-format).
|
|
2117
|
+
*
|
|
2118
|
+
* Each picked entry contributes a focused descriptive clause — the whole point
|
|
2119
|
+
* is to give the model a strong technical hint about what the photographer
|
|
2120
|
+
* "set the dial to", and the visual consequence of that choice.
|
|
2121
|
+
*
|
|
2122
|
+
* Typical applications: portraiture wide-aperture isolation, action freeze with
|
|
2123
|
+
* fast shutter, gritty high-ISO grain, light-trail long exposure, etc.
|
|
2124
|
+
*
|
|
2125
|
+
* Shared between the picker UI, the standalone Exposure Settings parameter
|
|
2126
|
+
* node, and the prompt-hint injection on both the frontend DAG executor and
|
|
2127
|
+
* the backend orchestrator.
|
|
2128
|
+
*/
|
|
2129
|
+
type ExposureCategory = "aperture" | "shutter-speed" | "iso";
|
|
2130
|
+
interface ExposureSettings {
|
|
2131
|
+
readonly id: string;
|
|
2132
|
+
readonly label: string;
|
|
2133
|
+
readonly category: ExposureCategory;
|
|
2134
|
+
readonly description: string;
|
|
2135
|
+
readonly promptHint: string;
|
|
2136
|
+
}
|
|
2137
|
+
declare const EXPOSURE_SETTINGS: ReadonlyArray<ExposureSettings>;
|
|
2138
|
+
declare const EXPOSURE_CATEGORY_ORDER: ReadonlyArray<ExposureCategory>;
|
|
2139
|
+
declare const EXPOSURE_CATEGORY_LABELS: Record<ExposureCategory, string>;
|
|
2140
|
+
declare function getExposure(id: string | undefined | null): ExposureSettings | undefined;
|
|
2141
|
+
declare function getExposureLabel(id: string | undefined | null, fallback?: string): string;
|
|
2142
|
+
declare function getExposurePromptHint(id: string | undefined | null): string;
|
|
2143
|
+
declare const EXPOSURE_IDS: ReadonlyArray<string>;
|
|
2144
|
+
/**
|
|
2145
|
+
* Maps each ExposureCategory to the consumer data field name that holds the
|
|
2146
|
+
* selected entry id for that category. Multi-category exposure: a consumer
|
|
2147
|
+
* (image/video) can independently set a value in each of the 3 dimensions.
|
|
2148
|
+
*/
|
|
2149
|
+
declare const EXPOSURE_FIELD_BY_CATEGORY: Record<ExposureCategory, "aperture" | "shutterSpeed" | "isoValue">;
|
|
2150
|
+
/**
|
|
2151
|
+
* Shape of the per-category exposure fields on ExposureSettingsData and any
|
|
2152
|
+
* consumer that opts in. All fields optional — user may set zero, one, or
|
|
2153
|
+
* all categories.
|
|
2154
|
+
*/
|
|
2155
|
+
interface ExposureValue {
|
|
2156
|
+
aperture?: string;
|
|
2157
|
+
shutterSpeed?: string;
|
|
2158
|
+
isoValue?: string;
|
|
2159
|
+
}
|
|
2160
|
+
/**
|
|
2161
|
+
* Aggregate all enabled per-category exposure prompt hints from a consumer's
|
|
2162
|
+
* data, in canonical category order (aperture, shutter-speed, iso).
|
|
2163
|
+
*/
|
|
2164
|
+
declare function buildExposureHints(data: Record<string, unknown> & {
|
|
2165
|
+
aperture?: unknown;
|
|
2166
|
+
shutterSpeed?: unknown;
|
|
2167
|
+
isoValue?: unknown;
|
|
2168
|
+
}): string[];
|
|
2169
|
+
|
|
2170
|
+
/**
|
|
2171
|
+
* Canonical catalog of framing / shot composition choices.
|
|
2172
|
+
*
|
|
2173
|
+
* Complements `camera-motions.ts`: motion is HOW the camera moves, framing is
|
|
2174
|
+
* WHAT the camera sees and from WHICH angle. They're independent dimensions
|
|
2175
|
+
* of a shot — users can pick both (e.g. "Dolly In" + "Medium Close-up").
|
|
2176
|
+
*
|
|
2177
|
+
* Shared between the picker UI and the prompt-hint injection on both the
|
|
2178
|
+
* frontend DAG executor and the backend orchestrator.
|
|
2179
|
+
*/
|
|
2180
|
+
type FramingCategory = "shot-size" | "angle" | "coverage" | "composition" | "vantage";
|
|
2181
|
+
interface Framing {
|
|
2182
|
+
readonly id: string;
|
|
2183
|
+
readonly label: string;
|
|
2184
|
+
readonly category: FramingCategory;
|
|
2185
|
+
readonly description: string;
|
|
2186
|
+
readonly promptHint: string;
|
|
2187
|
+
}
|
|
2188
|
+
declare const FRAMINGS: ReadonlyArray<Framing>;
|
|
2189
|
+
declare const FRAMING_CATEGORY_ORDER: ReadonlyArray<FramingCategory>;
|
|
2190
|
+
declare const FRAMING_CATEGORY_LABELS: Record<FramingCategory, string>;
|
|
2191
|
+
declare function getFraming(id: string | undefined | null): Framing | undefined;
|
|
2192
|
+
declare function getFramingLabel(id: string | undefined | null, fallback?: string): string;
|
|
2193
|
+
declare function getFramingPromptHint(id: string | undefined | null): string;
|
|
2194
|
+
declare const FRAMING_IDS: ReadonlyArray<string>;
|
|
2195
|
+
declare function isVantageFraming(id: string | undefined | null): boolean;
|
|
2196
|
+
/**
|
|
2197
|
+
* Maps each FramingCategory to the consumer data field name that holds the
|
|
2198
|
+
* selected entry id for that category. Multi-category framing: a consumer
|
|
2199
|
+
* (image/video) can independently set a value in each of the 5 dimensions.
|
|
2200
|
+
*/
|
|
2201
|
+
declare const FRAMING_FIELD_BY_CATEGORY: Record<FramingCategory, "shotSize" | "angle" | "coverage" | "composition" | "vantage">;
|
|
2202
|
+
/** Per-category multi-select cap. composition supports 2 picks
|
|
2203
|
+
* (rule-of-thirds + leading-lines, centered + negative-space). All other
|
|
2204
|
+
* categories single-select (absent → 1). */
|
|
2205
|
+
declare const MAX_SELECTED_BY_FRAMING_CATEGORY: Partial<Record<FramingCategory, number>>;
|
|
2206
|
+
/** Selection limit for a framing category (1 when not multi-select). */
|
|
2207
|
+
declare function getFramingCategoryLimit(category: FramingCategory): number;
|
|
2208
|
+
/**
|
|
2209
|
+
* Shape of the per-category framing fields on FramingData and all 9 consumer
|
|
2210
|
+
* data types. All fields optional — user may set zero, one, or all categories.
|
|
2211
|
+
*/
|
|
2212
|
+
interface FramingValue {
|
|
2213
|
+
shotSize?: string;
|
|
2214
|
+
angle?: string;
|
|
2215
|
+
coverage?: string;
|
|
2216
|
+
/** Composition — single id or up to 2 ids for layered compositions
|
|
2217
|
+
* (e.g. ["rule-of-thirds", "leading-lines"], ["centered", "negative-space"]). */
|
|
2218
|
+
composition?: string | ReadonlyArray<string>;
|
|
2219
|
+
vantage?: string;
|
|
2220
|
+
}
|
|
2221
|
+
/**
|
|
2222
|
+
* Aggregate all enabled per-category framing prompt hints from a consumer's
|
|
2223
|
+
* data, in canonical category order (shot-size, angle, coverage, composition,
|
|
2224
|
+
* vantage).
|
|
2225
|
+
*
|
|
2226
|
+
* Accepts a loosely typed record (the helper is shared between strongly typed
|
|
2227
|
+
* frontend node data and the backend's `Record<string, unknown>` workflow
|
|
2228
|
+
* data). Non-string values are ignored.
|
|
2229
|
+
*
|
|
2230
|
+
* @param data the consumer data record (must include optional shotSize / angle
|
|
2231
|
+
* / coverage / composition / vantage fields)
|
|
2232
|
+
* @param skipVantage when true, skip the vantage hint (used by video consumers
|
|
2233
|
+
* where camera-motion v2 already declares spatial positioning — keeps the
|
|
2234
|
+
* pre-existing conflict-resolution behavior identical).
|
|
2235
|
+
*/
|
|
2236
|
+
declare function buildFramingHints(data: Record<string, unknown> & {
|
|
2237
|
+
shotSize?: unknown;
|
|
2238
|
+
angle?: unknown;
|
|
2239
|
+
coverage?: unknown;
|
|
2240
|
+
composition?: unknown;
|
|
2241
|
+
vantage?: unknown;
|
|
2242
|
+
}, skipVantage?: boolean): string[];
|
|
2243
|
+
|
|
2244
|
+
/**
|
|
2245
|
+
* Canonical catalog of Held Prop / hand-prop presets.
|
|
2246
|
+
*
|
|
2247
|
+
* Single-pick parameter node — user picks ONE prop the subject is
|
|
2248
|
+
* actively holding or interacting with. Distinct from the Object node,
|
|
2249
|
+
* which describes a *separate* object somewhere in the scene. A held
|
|
2250
|
+
* prop is part of the subject's pose grammar — they're cradling it,
|
|
2251
|
+
* raising it, smoking it, gripping it. Each promptHint therefore
|
|
2252
|
+
* incorporates a small piece of pose / hand language so the prop reads
|
|
2253
|
+
* as actively held rather than just "near."
|
|
2254
|
+
*
|
|
2255
|
+
* There is intentional vocabulary overlap with the Weapon node (katana,
|
|
2256
|
+
* pistol) and with parts of the Material / Vehicle catalogs — Held Prop
|
|
2257
|
+
* uses the held-in-hand grammar ("holding…", "cradling…"), while the
|
|
2258
|
+
* Weapon node uses the descriptive scene grammar ("with a katana, …").
|
|
2259
|
+
*
|
|
2260
|
+
* Applies to both image and video consumers (the prop and pose carry
|
|
2261
|
+
* over to motion). Not in STILL_IMAGE_EXCLUDE_TYPES.
|
|
2262
|
+
*
|
|
2263
|
+
* Shared between the picker UI, the standalone Held Prop parameter
|
|
2264
|
+
* node, and the prompt-hint injection on both the frontend DAG executor
|
|
2265
|
+
* and the backend orchestrator.
|
|
2266
|
+
*/
|
|
2267
|
+
type HeldPropCategory = "device" | "drink" | "smoking" | "reading-writing" | "bag-accessory" | "floral-nature" | "instrument" | "companion" | "occupational";
|
|
2268
|
+
interface HeldProp {
|
|
2269
|
+
readonly id: string;
|
|
2270
|
+
readonly label: string;
|
|
2271
|
+
readonly category: HeldPropCategory;
|
|
2272
|
+
readonly description: string;
|
|
2273
|
+
readonly promptHint: string;
|
|
2274
|
+
}
|
|
2275
|
+
declare const HELD_PROPS: ReadonlyArray<HeldProp>;
|
|
2276
|
+
declare function getHeldProp(id: string | undefined | null): HeldProp | undefined;
|
|
2277
|
+
declare function getHeldPropLabel(id: string | undefined | null, fallback?: string): string;
|
|
2278
|
+
declare function getHeldPropPromptHint(id: string | undefined | null): string;
|
|
2279
|
+
/**
|
|
2280
|
+
* Multi-pick: 1-2 prop ids → composite held-prop clause. Single → entry's
|
|
2281
|
+
* own promptHint (which already starts with "holding..." / "carrying..."
|
|
2282
|
+
* grammar). Two → emit independently, joined by buildPersonHints-style
|
|
2283
|
+
* comma-join. Common combos: book + coffee, cigarette + drink, phone + bag.
|
|
2284
|
+
*/
|
|
2285
|
+
declare function buildHeldPropHints(value: unknown): string[];
|
|
2286
|
+
declare const HELD_PROP_IDS: ReadonlyArray<string>;
|
|
2287
|
+
declare const HELD_PROP_CATEGORY_LABELS: Readonly<Record<HeldPropCategory, string>>;
|
|
2288
|
+
declare const HELD_PROP_CATEGORY_ORDER: ReadonlyArray<HeldPropCategory>;
|
|
2289
|
+
|
|
2290
|
+
/**
|
|
2291
|
+
* Instrumentation catalog: instruments (multi-select) + production style +
|
|
2292
|
+
* vocal presence. Composed into "[production] [instruments-joined] with [vocalPresence]".
|
|
2293
|
+
*
|
|
2294
|
+
* `vocalPresence: "instrumental"` is the trigger that the Generate Music
|
|
2295
|
+
* (MiniMax) integration uses to flip its `instrumental: true` flag.
|
|
2296
|
+
*
|
|
2297
|
+
* INSTRUMENTS carries a `category` field used by the picker to render a
|
|
2298
|
+
* horizontal tab row mirroring Splice's instrument taxonomy
|
|
2299
|
+
* (https://splice.com/sounds/instruments) — Drums / Percussion / Keys /
|
|
2300
|
+
* Synth / Guitar / Bass / Brass / Woodwinds / Strings / World.
|
|
2301
|
+
*/
|
|
2302
|
+
type InstrumentCategory = "drums" | "percussion" | "keys" | "synth" | "guitar" | "bass" | "brass" | "woodwinds" | "strings" | "world" | "middle-eastern";
|
|
2303
|
+
declare const INSTRUMENT_CATEGORY_ORDER: ReadonlyArray<InstrumentCategory>;
|
|
2304
|
+
declare const INSTRUMENT_CATEGORY_LABELS: Readonly<Record<InstrumentCategory, string>>;
|
|
2305
|
+
interface InstrumentationEntry {
|
|
2306
|
+
readonly id: string;
|
|
2307
|
+
readonly label: string;
|
|
2308
|
+
readonly description: string;
|
|
2309
|
+
readonly promptHint: string;
|
|
2310
|
+
}
|
|
2311
|
+
interface CategorizedInstrument extends InstrumentationEntry {
|
|
2312
|
+
readonly category: InstrumentCategory;
|
|
2313
|
+
}
|
|
2314
|
+
declare const INSTRUMENTS: ReadonlyArray<CategorizedInstrument>;
|
|
2315
|
+
declare const PRODUCTION_STYLES: ReadonlyArray<InstrumentationEntry>;
|
|
2316
|
+
declare const VOCAL_PRESENCE: ReadonlyArray<InstrumentationEntry>;
|
|
2317
|
+
/** "instrumental" is mutually exclusive with any other vocal presence —
|
|
2318
|
+
* picking it while others are selected clears the others, and picking
|
|
2319
|
+
* another while "instrumental" is selected clears it. */
|
|
2320
|
+
declare const VOCAL_PRESENCE_INSTRUMENTAL_ID = "instrumental";
|
|
2321
|
+
declare const SINGING_STYLES: ReadonlyArray<InstrumentationEntry>;
|
|
2322
|
+
declare function getInstrument(id: string | undefined): CategorizedInstrument | undefined;
|
|
2323
|
+
declare function getProductionStyle(id: string | undefined): InstrumentationEntry | undefined;
|
|
2324
|
+
declare function getVocalPresence(id: string | undefined): InstrumentationEntry | undefined;
|
|
2325
|
+
declare function getSingingStyle(id: string | undefined): InstrumentationEntry | undefined;
|
|
2326
|
+
declare function buildInstrumentationHints(data: {
|
|
2327
|
+
readonly preText?: string;
|
|
2328
|
+
readonly postText?: string;
|
|
2329
|
+
readonly instruments?: ReadonlyArray<string>;
|
|
2330
|
+
readonly production?: string;
|
|
2331
|
+
readonly vocalPresence?: string | ReadonlyArray<string>;
|
|
2332
|
+
readonly singingStyle?: string | ReadonlyArray<string>;
|
|
2333
|
+
}): string;
|
|
2334
|
+
declare function isInstrumentalVocal(value: unknown): boolean;
|
|
2335
|
+
declare const INSTRUMENTATION_DEFAULT_DATA: {
|
|
2336
|
+
preText?: string;
|
|
2337
|
+
postText?: string;
|
|
2338
|
+
instruments?: ReadonlyArray<string>;
|
|
2339
|
+
production?: string;
|
|
2340
|
+
vocalPresence?: string | ReadonlyArray<string>;
|
|
2341
|
+
singingStyle?: string | ReadonlyArray<string>;
|
|
2342
|
+
};
|
|
2343
|
+
|
|
2344
|
+
/**
|
|
2345
|
+
* Canonical catalog of lens / focal length choices.
|
|
2346
|
+
*
|
|
2347
|
+
* Optics dimension of a shot — focal length and depth-of-field character. Independent
|
|
2348
|
+
* of framing (which captures shot size and composition) and camera motion (which captures
|
|
2349
|
+
* how the camera moves). A close-up at 24mm looks completely different from a close-up
|
|
2350
|
+
* at 200mm — the lens choice carries that intent.
|
|
2351
|
+
*
|
|
2352
|
+
* Shared between the picker UI and the prompt-hint injection on both the
|
|
2353
|
+
* frontend DAG executor and the backend orchestrator.
|
|
2354
|
+
*/
|
|
2355
|
+
interface Lens {
|
|
2356
|
+
readonly id: string;
|
|
2357
|
+
readonly label: string;
|
|
2358
|
+
readonly description: string;
|
|
2359
|
+
readonly promptHint: string;
|
|
2360
|
+
}
|
|
2361
|
+
declare const LENSES: ReadonlyArray<Lens>;
|
|
2362
|
+
declare function getLens(id: string | undefined | null): Lens | undefined;
|
|
2363
|
+
declare function getLensLabel(id: string | undefined | null, fallback?: string): string;
|
|
2364
|
+
declare function getLensPromptHint(id: string | undefined | null): string;
|
|
2365
|
+
declare const LENS_IDS: ReadonlyArray<string>;
|
|
2366
|
+
|
|
2367
|
+
/**
|
|
2368
|
+
* Canonical catalog of lighting choices.
|
|
2369
|
+
*
|
|
2370
|
+
* Lighting is a multi-category dimension of a shot — light comes from a
|
|
2371
|
+
* direction, has a stylistic intent (three-point, Rembrandt, low-key, etc.),
|
|
2372
|
+
* and is anchored to a time of day. Independent of optics (lens), framing,
|
|
2373
|
+
* camera motion, and capture medium (camera-format).
|
|
2374
|
+
*
|
|
2375
|
+
* Shared between the picker UI and the prompt-hint injection on both the
|
|
2376
|
+
* frontend DAG executor and the backend orchestrator.
|
|
2377
|
+
*/
|
|
2378
|
+
type LightingCategory = "time-of-day" | "style" | "direction" | "lighting-ratio" | "color-temperature";
|
|
2379
|
+
interface Lighting {
|
|
2380
|
+
readonly id: string;
|
|
2381
|
+
readonly label: string;
|
|
2382
|
+
readonly category: LightingCategory;
|
|
2383
|
+
readonly description: string;
|
|
2384
|
+
readonly promptHint: string;
|
|
2385
|
+
}
|
|
2386
|
+
declare const LIGHTINGS: ReadonlyArray<Lighting>;
|
|
2387
|
+
declare const LIGHTING_CATEGORY_ORDER: ReadonlyArray<LightingCategory>;
|
|
2388
|
+
declare const LIGHTING_CATEGORY_LABELS: Record<LightingCategory, string>;
|
|
2389
|
+
declare function getLighting(id: string | undefined | null): Lighting | undefined;
|
|
2390
|
+
declare function getLightingLabel(id: string | undefined | null, fallback?: string): string;
|
|
2391
|
+
declare function getLightingPromptHint(id: string | undefined | null): string;
|
|
2392
|
+
declare const LIGHTING_IDS: ReadonlyArray<string>;
|
|
2393
|
+
/**
|
|
2394
|
+
* Maps each LightingCategory to the consumer data field name that holds the
|
|
2395
|
+
* selected entry id for that category. Multi-category lighting: a consumer
|
|
2396
|
+
* (image/video) can independently set a value in each of the 3 dimensions.
|
|
2397
|
+
*
|
|
2398
|
+
* Field names use 'lighting' prefix where the category name is generic or
|
|
2399
|
+
* would collide with other dimensions (e.g. Temporal also has a 'direction'
|
|
2400
|
+
* category; 'style' is generic across many dims).
|
|
2401
|
+
*/
|
|
2402
|
+
declare const LIGHTING_FIELD_BY_CATEGORY: Record<LightingCategory, "timeOfDay" | "lightingStyle" | "lightingDirection" | "lightingRatio" | "colorTemperature">;
|
|
2403
|
+
/**
|
|
2404
|
+
* Shape of the per-category lighting fields on LightingData and all 9 consumer
|
|
2405
|
+
* data types. All fields optional — user may set zero, one, or all categories.
|
|
2406
|
+
*/
|
|
2407
|
+
interface LightingValue {
|
|
2408
|
+
timeOfDay?: string;
|
|
2409
|
+
/** Lighting style — single id or up to 2 ids for layered setups
|
|
2410
|
+
* (e.g. ["key", "rim"], ["soft", "hard"], ["beauty-dish", "kicker"]). */
|
|
2411
|
+
lightingStyle?: string | ReadonlyArray<string>;
|
|
2412
|
+
lightingDirection?: string;
|
|
2413
|
+
/** Lighting ratio id from LIGHTINGS (relative key-to-shadow brightness, e.g. "ratio-1-2"). */
|
|
2414
|
+
lightingRatio?: string;
|
|
2415
|
+
/** Color temperature id from LIGHTINGS (Kelvin warmth/coolness, e.g. "temp-5600k"). */
|
|
2416
|
+
colorTemperature?: string;
|
|
2417
|
+
}
|
|
2418
|
+
/**
|
|
2419
|
+
* Aggregate all enabled per-category lighting prompt hints from a consumer's
|
|
2420
|
+
* data, in canonical category order (time-of-day, style, direction).
|
|
2421
|
+
*
|
|
2422
|
+
* Accepts a loosely typed record (the helper is shared between strongly typed
|
|
2423
|
+
* frontend node data and the backend's `Record<string, unknown>` workflow
|
|
2424
|
+
* data). Non-string values are ignored.
|
|
2425
|
+
*
|
|
2426
|
+
* @param data the consumer data record (must include optional timeOfDay /
|
|
2427
|
+
* lightingStyle / lightingDirection fields)
|
|
2428
|
+
*/
|
|
2429
|
+
declare function buildLightingHints(data: Record<string, unknown> & {
|
|
2430
|
+
timeOfDay?: unknown;
|
|
2431
|
+
lightingStyle?: unknown;
|
|
2432
|
+
lightingDirection?: unknown;
|
|
2433
|
+
lightingRatio?: unknown;
|
|
2434
|
+
colorTemperature?: unknown;
|
|
2435
|
+
}): string[];
|
|
2436
|
+
|
|
2437
|
+
/**
|
|
2438
|
+
* Canonical catalog of loop-friendly subject presets ("Loop Subject").
|
|
2439
|
+
*
|
|
2440
|
+
* The Loop Subject parameter node emits one of these prompt fragments,
|
|
2441
|
+
* pre-tuned for VEO 3.1 perfect-loop generation. Each prompt is shaped to
|
|
2442
|
+
* either:
|
|
2443
|
+
* - have inherently cyclical / ambient motion the model knows from the
|
|
2444
|
+
* subject alone (clouds drift, aurora undulates, embers flicker), or
|
|
2445
|
+
* - anchor periodicity via the "fractal" / "self-similar" tokens, which
|
|
2446
|
+
* in user testing strongly biased VEO toward loop-tolerant output even
|
|
2447
|
+
* when the prompt also contained directional cues (vanishing points,
|
|
2448
|
+
* receding lines).
|
|
2449
|
+
*
|
|
2450
|
+
* These are NOT motion prompts — they describe the SCENE for the image
|
|
2451
|
+
* generator. The motion side (the perfect-loop seal phrase) is appended
|
|
2452
|
+
* separately at the i2v stage. Keeping the two concerns separated lets
|
|
2453
|
+
* users animate the same loop-friendly image with different motion intent
|
|
2454
|
+
* and lets us refine each library independently.
|
|
2455
|
+
*/
|
|
2456
|
+
type LoopSubjectCategory = "realistic" | "abstract";
|
|
2457
|
+
interface LoopSubject {
|
|
2458
|
+
readonly id: string;
|
|
2459
|
+
readonly label: string;
|
|
2460
|
+
readonly category: LoopSubjectCategory;
|
|
2461
|
+
readonly description: string;
|
|
2462
|
+
/** Drop-in prompt text for Generate Image. Wired into the prompt input
|
|
2463
|
+
* via FieldMappings, same as Setting / Motion / Mood Parameter nodes. */
|
|
2464
|
+
readonly promptHint: string;
|
|
2465
|
+
}
|
|
2466
|
+
declare const LOOP_SUBJECT_CATEGORY_ORDER: ReadonlyArray<LoopSubjectCategory>;
|
|
2467
|
+
declare const LOOP_SUBJECT_CATEGORY_LABELS: Readonly<Record<LoopSubjectCategory, string>>;
|
|
2468
|
+
declare const LOOP_SUBJECTS: ReadonlyArray<LoopSubject>;
|
|
2469
|
+
declare function getLoopSubject(id: string): LoopSubject | undefined;
|
|
2470
|
+
declare function getLoopSubjectLabel(id: string): string;
|
|
2471
|
+
declare function getLoopSubjectPromptHint(id: string): string;
|
|
2472
|
+
|
|
2473
|
+
/**
|
|
2474
|
+
* Canonical catalog of material presets ("Material").
|
|
2475
|
+
*
|
|
2476
|
+
* Material dimension — *what something is made of*. Works universally across
|
|
2477
|
+
* subjects (clothing, skin, body) and objects (furniture, vehicles, props,
|
|
2478
|
+
* surfaces). The same catalog can describe a silk dress, a chrome sculpture of
|
|
2479
|
+
* a person, a leather pillow, or a plastic train.
|
|
2480
|
+
*
|
|
2481
|
+
* Grammar: every entry's `promptHint` begins with `"made of ..."` — this reads
|
|
2482
|
+
* correctly regardless of target ("a dress made of silk", "a human made of
|
|
2483
|
+
* glass", "a pillow made of leather", "a train made of plastic").
|
|
2484
|
+
*
|
|
2485
|
+
* For clothing-specific phrasing ("wearing silk"), see the `fabric` dimension
|
|
2486
|
+
* on the Styling node. There is intentional overlap in vocabulary (leather,
|
|
2487
|
+
* silk, velvet appear in both) — Material uses the universal `"made of"`
|
|
2488
|
+
* grammar, Fabric uses the wardrobe-native `"wearing"` grammar.
|
|
2489
|
+
*
|
|
2490
|
+
* Shared between the picker UI, the standalone Material parameter node, and
|
|
2491
|
+
* the prompt-hint injection on both the frontend DAG executor and the
|
|
2492
|
+
* backend orchestrator.
|
|
2493
|
+
*/
|
|
2494
|
+
type MaterialCategory = "fabric" | "metal" | "stone" | "wood" | "glass-ceramic" | "natural" | "exotic";
|
|
2495
|
+
interface Material {
|
|
2496
|
+
readonly id: string;
|
|
2497
|
+
readonly label: string;
|
|
2498
|
+
readonly category: MaterialCategory;
|
|
2499
|
+
readonly description: string;
|
|
2500
|
+
readonly promptHint: string;
|
|
2501
|
+
}
|
|
2502
|
+
declare const MATERIALS: ReadonlyArray<Material>;
|
|
2503
|
+
declare function getMaterial(id: string | undefined | null): Material | undefined;
|
|
2504
|
+
declare function getMaterialLabel(id: string | undefined | null, fallback?: string): string;
|
|
2505
|
+
declare function getMaterialPromptHint(id: string | undefined | null): string;
|
|
2506
|
+
/**
|
|
2507
|
+
* Multi-pick: 1-2 material ids → composite material clause. Single → entry's
|
|
2508
|
+
* own promptHint. Two → "made of {A} and {B}" using lowercased entry labels.
|
|
2509
|
+
* Covers leather+brass handbag, wood+steel chair, glass+chrome lamp, etc.
|
|
2510
|
+
*/
|
|
2511
|
+
declare function buildMaterialHints(value: unknown): string;
|
|
2512
|
+
declare const MATERIAL_IDS: ReadonlyArray<string>;
|
|
2513
|
+
declare const MATERIAL_CATEGORY_LABELS: Readonly<Record<MaterialCategory, string>>;
|
|
2514
|
+
declare const MATERIAL_CATEGORY_ORDER: ReadonlyArray<MaterialCategory>;
|
|
2515
|
+
|
|
2516
|
+
/**
|
|
2517
|
+
* Canonical catalog of Mood / emotional-state choices.
|
|
2518
|
+
*
|
|
2519
|
+
* Single-pick parameter node — user picks ONE mood that describes the
|
|
2520
|
+
* subject's emotional state. The promptHint captures the natural
|
|
2521
|
+
* consequence on face + body language (a happy mood → "with a warm smile
|
|
2522
|
+
* and bright eyes", a fierce mood → "with an intense, fierce expression").
|
|
2523
|
+
*
|
|
2524
|
+
* Separate from:
|
|
2525
|
+
* - Tone (the overall content/writing tone — sarcastic, playful, formal)
|
|
2526
|
+
* - Atmosphere (what's in the air — fog, rain, dust)
|
|
2527
|
+
* - Style (artistic medium — oil painting, photorealistic)
|
|
2528
|
+
*
|
|
2529
|
+
* Applies to both image and video consumers (mood describes the subject,
|
|
2530
|
+
* not video-specific). Not in STILL_IMAGE_EXCLUDE_TYPES.
|
|
2531
|
+
*
|
|
2532
|
+
* Includes pre/post free-text fields (same pattern as Person) for
|
|
2533
|
+
* specifics the catalog can't express ("restrained grief", "crying with
|
|
2534
|
+
* relief", etc.).
|
|
2535
|
+
*
|
|
2536
|
+
* Shared between the picker UI, the standalone Mood parameter node, and
|
|
2537
|
+
* the prompt-hint injection on both the frontend DAG executor and the
|
|
2538
|
+
* backend orchestrator.
|
|
2539
|
+
*/
|
|
2540
|
+
type MoodCategory = "positive" | "negative" | "neutral" | "intense";
|
|
2541
|
+
interface Mood {
|
|
2542
|
+
readonly id: string;
|
|
2543
|
+
readonly label: string;
|
|
2544
|
+
readonly category: MoodCategory;
|
|
2545
|
+
readonly description: string;
|
|
2546
|
+
readonly promptHint: string;
|
|
2547
|
+
}
|
|
2548
|
+
declare const MOODS: ReadonlyArray<Mood>;
|
|
2549
|
+
declare function getMood(id: string | undefined | null): Mood | undefined;
|
|
2550
|
+
declare function getMoodLabel(id: string | undefined | null, fallback?: string): string;
|
|
2551
|
+
declare function getMoodPromptHint(id: string | undefined | null): string;
|
|
2552
|
+
declare const MOOD_IDS: ReadonlyArray<string>;
|
|
2553
|
+
declare const MOOD_CATEGORY_LABELS: Readonly<Record<MoodCategory, string>>;
|
|
2554
|
+
declare const MOOD_CATEGORY_ORDER: ReadonlyArray<MoodCategory>;
|
|
2555
|
+
/**
|
|
2556
|
+
* Shape of Mood parameter data. Single id OR array of up to 2 ids (mixed
|
|
2557
|
+
* mood like "smirking + aloof"). Plus optional pre/post free text.
|
|
2558
|
+
*/
|
|
2559
|
+
interface MoodValue {
|
|
2560
|
+
mood?: string | ReadonlyArray<string>;
|
|
2561
|
+
preText?: string;
|
|
2562
|
+
postText?: string;
|
|
2563
|
+
}
|
|
2564
|
+
/**
|
|
2565
|
+
* Build prompt hints from MoodData: optional pre-text, the selected mood's
|
|
2566
|
+
* hint (single or mixed), optional post-text. Returns array — caller joins
|
|
2567
|
+
* with ", ".
|
|
2568
|
+
*/
|
|
2569
|
+
declare function buildMoodHints(data: Record<string, unknown> & MoodValue): string[];
|
|
2570
|
+
|
|
2571
|
+
/**
|
|
2572
|
+
* Canonical catalog of music genres for Suno / MiniMax / Text-to-Audio
|
|
2573
|
+
* prompt composition. Shared between frontend (picker UI), backend
|
|
2574
|
+
* orchestrator (payload-builder), and frontend DAG executor.
|
|
2575
|
+
*
|
|
2576
|
+
* Each entry's `promptHint` is the natural-language fragment injected into
|
|
2577
|
+
* the consumer's style/prompt field by `composeSoundHintFromConnections`.
|
|
2578
|
+
*
|
|
2579
|
+
* Top-level genres carry a `category` field used by the picker to render a
|
|
2580
|
+
* horizontal tab row (mirrors PersonPicker.ethnicity grouping). Categories
|
|
2581
|
+
* are Splice-aligned (https://splice.com/sounds/genres) so the taxonomy
|
|
2582
|
+
* matches industry conventions.
|
|
2583
|
+
*/
|
|
2584
|
+
type MusicGenreCategory = "hip-hop-rnb" | "electronic" | "pop" | "rock-metal" | "acoustic" | "global" | "cinematic";
|
|
2585
|
+
declare const MUSIC_GENRE_CATEGORY_ORDER: ReadonlyArray<MusicGenreCategory>;
|
|
2586
|
+
declare const MUSIC_GENRE_CATEGORY_LABELS: Readonly<Record<MusicGenreCategory, string>>;
|
|
2587
|
+
interface MusicSubgenre {
|
|
2588
|
+
readonly id: string;
|
|
2589
|
+
readonly label: string;
|
|
2590
|
+
readonly promptHint: string;
|
|
2591
|
+
}
|
|
2592
|
+
interface MusicGenre {
|
|
2593
|
+
readonly id: string;
|
|
2594
|
+
readonly label: string;
|
|
2595
|
+
readonly description: string;
|
|
2596
|
+
readonly promptHint: string;
|
|
2597
|
+
readonly category: MusicGenreCategory;
|
|
2598
|
+
readonly subgenres: ReadonlyArray<MusicSubgenre>;
|
|
2599
|
+
}
|
|
2600
|
+
interface MusicEra {
|
|
2601
|
+
readonly id: string;
|
|
2602
|
+
readonly label: string;
|
|
2603
|
+
readonly description: string;
|
|
2604
|
+
readonly promptHint: string;
|
|
2605
|
+
}
|
|
2606
|
+
declare const MUSIC_GENRES: ReadonlyArray<MusicGenre>;
|
|
2607
|
+
declare const MUSIC_ERAS: ReadonlyArray<MusicEra>;
|
|
2608
|
+
declare function getMusicGenre(id: string | undefined): MusicGenre | undefined;
|
|
2609
|
+
declare function getMusicGenreLabel(id: string | undefined): string;
|
|
2610
|
+
declare function getMusicSubgenre(genreId: string | undefined, subgenreId: string | undefined): MusicSubgenre | undefined;
|
|
2611
|
+
declare function getMusicEra(id: string | undefined): MusicEra | undefined;
|
|
2612
|
+
/**
|
|
2613
|
+
* Compose hints from MusicGenreData: optional preText, structured
|
|
2614
|
+
* [era] [subgenre|genre] (or " / "-joined genres for multi), optional
|
|
2615
|
+
* postText. Returns array — caller joins with ", " (matches buildMoodHints
|
|
2616
|
+
* / buildPersonHints pattern).
|
|
2617
|
+
*
|
|
2618
|
+
* Multi-genre (genre is an array): emit each genre's hint joined with " / "
|
|
2619
|
+
* — subgenre is ignored in multi-mode (subgenre is meaningful only against
|
|
2620
|
+
* a single chosen genre).
|
|
2621
|
+
*/
|
|
2622
|
+
declare function buildMusicGenreHints(data: {
|
|
2623
|
+
readonly preText?: string;
|
|
2624
|
+
readonly postText?: string;
|
|
2625
|
+
readonly genre?: string | ReadonlyArray<string>;
|
|
2626
|
+
readonly subgenre?: string;
|
|
2627
|
+
readonly era?: string;
|
|
2628
|
+
}): string;
|
|
2629
|
+
/** Default data when a music-genre node is dropped on canvas. Empty by design — forces a deliberate pick. */
|
|
2630
|
+
declare const MUSIC_GENRE_DEFAULT_DATA: {
|
|
2631
|
+
preText?: string;
|
|
2632
|
+
postText?: string;
|
|
2633
|
+
genre?: string | ReadonlyArray<string>;
|
|
2634
|
+
subgenre?: string;
|
|
2635
|
+
era?: string;
|
|
2636
|
+
};
|
|
2637
|
+
|
|
2638
|
+
/**
|
|
2639
|
+
* Music mood catalog: energy + emotion + vibe sub-fields.
|
|
2640
|
+
* Composed by buildMusicMoodHints into "[energy] [emotion] [vibe]".
|
|
2641
|
+
*/
|
|
2642
|
+
interface MusicMoodEntry {
|
|
2643
|
+
readonly id: string;
|
|
2644
|
+
readonly label: string;
|
|
2645
|
+
readonly description: string;
|
|
2646
|
+
readonly promptHint: string;
|
|
2647
|
+
}
|
|
2648
|
+
declare const MUSIC_ENERGIES: ReadonlyArray<MusicMoodEntry>;
|
|
2649
|
+
declare const MUSIC_EMOTIONS: ReadonlyArray<MusicMoodEntry>;
|
|
2650
|
+
declare const MUSIC_VIBES: ReadonlyArray<MusicMoodEntry>;
|
|
2651
|
+
declare function getMusicEnergy(id: string | undefined): MusicMoodEntry | undefined;
|
|
2652
|
+
declare function getMusicEmotion(id: string | undefined): MusicMoodEntry | undefined;
|
|
2653
|
+
declare function getMusicVibe(id: string | undefined): MusicMoodEntry | undefined;
|
|
2654
|
+
declare function buildMusicMoodHints(data: {
|
|
2655
|
+
readonly preText?: string;
|
|
2656
|
+
readonly postText?: string;
|
|
2657
|
+
readonly energy?: string;
|
|
2658
|
+
readonly emotion?: string | ReadonlyArray<string>;
|
|
2659
|
+
readonly vibe?: string | ReadonlyArray<string>;
|
|
2660
|
+
}): string;
|
|
2661
|
+
declare const MUSIC_MOOD_DEFAULT_DATA: {
|
|
2662
|
+
preText?: string;
|
|
2663
|
+
postText?: string;
|
|
2664
|
+
energy?: string;
|
|
2665
|
+
emotion?: string | ReadonlyArray<string>;
|
|
2666
|
+
vibe?: string | ReadonlyArray<string>;
|
|
2667
|
+
};
|
|
2668
|
+
|
|
2669
|
+
/**
|
|
2670
|
+
* Canonical catalog of Photo Genre / Photographic Intent presets.
|
|
2671
|
+
*
|
|
2672
|
+
* Single-pick parameter node — user picks ONE photographic genre that
|
|
2673
|
+
* bundles a packed set of conventions: lighting, framing, wardrobe
|
|
2674
|
+
* implications, color grading, and tabloid/editorial/selfie context. A
|
|
2675
|
+
* single photo-genre selection therefore acts as a meta-preset that
|
|
2676
|
+
* pushes the downstream prompt toward a recognizable style of image.
|
|
2677
|
+
*
|
|
2678
|
+
* Distinct from:
|
|
2679
|
+
* - Style (artistic medium — oil painting, anime, photorealistic)
|
|
2680
|
+
* - Setting (where the photo takes place)
|
|
2681
|
+
* - Framing (shot size + angle composition)
|
|
2682
|
+
* - Lighting (key/rim/fill direction and quality)
|
|
2683
|
+
*
|
|
2684
|
+
* Photo Genre is the "what kind of photograph is this trying to be"
|
|
2685
|
+
* dimension — paparazzi vs corporate headshot vs gym mirror selfie vs
|
|
2686
|
+
* Vogue editorial. Each promptHint is authored to bundle the canonical
|
|
2687
|
+
* markers of that genre in one descriptive clause, so connecting just
|
|
2688
|
+
* this node moves the image squarely into that recognizable genre.
|
|
2689
|
+
*
|
|
2690
|
+
* Applies to both image and video consumers (genre conventions cover
|
|
2691
|
+
* both still and motion). Not in STILL_IMAGE_EXCLUDE_TYPES.
|
|
2692
|
+
*
|
|
2693
|
+
* Shared between the picker UI, the standalone Photo Genre parameter
|
|
2694
|
+
* node, and the prompt-hint injection on both the frontend DAG executor
|
|
2695
|
+
* and the backend orchestrator.
|
|
2696
|
+
*/
|
|
2697
|
+
type PhotoGenreCategory = "editorial" | "documentary" | "studio-formal" | "selfie" | "print-context" | "lifestyle" | "commercial";
|
|
2698
|
+
interface PhotoGenre {
|
|
2699
|
+
readonly id: string;
|
|
2700
|
+
readonly label: string;
|
|
2701
|
+
readonly category: PhotoGenreCategory;
|
|
2702
|
+
readonly description: string;
|
|
2703
|
+
readonly promptHint: string;
|
|
2704
|
+
}
|
|
2705
|
+
declare const PHOTO_GENRES: ReadonlyArray<PhotoGenre>;
|
|
2706
|
+
declare function getPhotoGenre(id: string | undefined | null): PhotoGenre | undefined;
|
|
2707
|
+
declare function getPhotoGenreLabel(id: string | undefined | null, fallback?: string): string;
|
|
2708
|
+
declare function getPhotoGenrePromptHint(id: string | undefined | null): string;
|
|
2709
|
+
declare const PHOTO_GENRE_IDS: ReadonlyArray<string>;
|
|
2710
|
+
declare const PHOTO_GENRE_CATEGORY_LABELS: Readonly<Record<PhotoGenreCategory, string>>;
|
|
2711
|
+
declare const PHOTO_GENRE_CATEGORY_ORDER: ReadonlyArray<PhotoGenreCategory>;
|
|
2712
|
+
|
|
2713
|
+
/**
|
|
2714
|
+
* Canonical catalog of Photographer / Artist Style choices.
|
|
2715
|
+
*
|
|
2716
|
+
* Single-pick parameter node — user picks ONE photographer or illustrator
|
|
2717
|
+
* whose visual signature should drive the look. Each promptHint pairs the
|
|
2718
|
+
* artist's name with a couple of distinguishing visual cues, because
|
|
2719
|
+
* generative models recognise both the name token and the descriptive
|
|
2720
|
+
* vocabulary that surrounds it. Names alone tend to be too vague.
|
|
2721
|
+
*
|
|
2722
|
+
* Categories:
|
|
2723
|
+
* - editorial: fashion / editorial photographers (dreamy painterly look)
|
|
2724
|
+
* - documentary: documentary, street, photojournalism
|
|
2725
|
+
* - cinematographer: working DPs whose work translates well to stills
|
|
2726
|
+
* - concept: digital painters, concept artists, fantasy illustrators
|
|
2727
|
+
* - illustrator: illustrators, animators, art-nouveau / classical artists
|
|
2728
|
+
*
|
|
2729
|
+
* Shared between the picker UI, the standalone Photographer parameter node,
|
|
2730
|
+
* and the prompt-hint injection on both the frontend DAG executor and the
|
|
2731
|
+
* backend orchestrator.
|
|
2732
|
+
*/
|
|
2733
|
+
type PhotographerCategory = "editorial" | "documentary" | "cinematographer" | "concept" | "illustrator";
|
|
2734
|
+
interface Photographer {
|
|
2735
|
+
readonly id: string;
|
|
2736
|
+
readonly label: string;
|
|
2737
|
+
readonly category: PhotographerCategory;
|
|
2738
|
+
readonly description: string;
|
|
2739
|
+
readonly promptHint: string;
|
|
2740
|
+
}
|
|
2741
|
+
declare const PHOTOGRAPHERS: ReadonlyArray<Photographer>;
|
|
2742
|
+
declare function getPhotographer(id: string | undefined | null): Photographer | undefined;
|
|
2743
|
+
declare function getPhotographerLabel(id: string | undefined | null, fallback?: string): string;
|
|
2744
|
+
declare function getPhotographerPromptHint(id: string | undefined | null): string;
|
|
2745
|
+
/**
|
|
2746
|
+
* Multi-pick variant: 1-2 photographer ids → blended hint. Single → entry's
|
|
2747
|
+
* own promptHint. Two → "shot in the blended language of {A} and {B}" — the
|
|
2748
|
+
* model interprets this as referencing both creators' visual signatures.
|
|
2749
|
+
*/
|
|
2750
|
+
declare function buildPhotographerHints(value: unknown): string;
|
|
2751
|
+
declare const PHOTOGRAPHER_IDS: ReadonlyArray<string>;
|
|
2752
|
+
declare const PHOTOGRAPHER_CATEGORY_LABELS: Readonly<Record<PhotographerCategory, string>>;
|
|
2753
|
+
declare const PHOTOGRAPHER_CATEGORY_ORDER: ReadonlyArray<PhotographerCategory>;
|
|
2754
|
+
|
|
2755
|
+
/**
|
|
2756
|
+
* Canonical catalog of Pose / posture + action choices.
|
|
2757
|
+
*
|
|
2758
|
+
* Single-pick parameter node — user picks ONE pose that describes the
|
|
2759
|
+
* subject's body position + action. Covers both static poses ("standing
|
|
2760
|
+
* upright") and dynamic action ("mid-stride, running").
|
|
2761
|
+
*
|
|
2762
|
+
* Separate from:
|
|
2763
|
+
* - Framing → Vantage (azimuth of camera around subject, not subject pose)
|
|
2764
|
+
* - Camera Motion (how the camera moves, not the subject)
|
|
2765
|
+
*
|
|
2766
|
+
* Applies to both image and video consumers (pose describes the subject,
|
|
2767
|
+
* not video-specific). Not in STILL_IMAGE_EXCLUDE_TYPES.
|
|
2768
|
+
*
|
|
2769
|
+
* Includes pre/post free-text fields (same pattern as Person) for
|
|
2770
|
+
* specifics the catalog can't express ("mid-fall, arms flailing", etc.).
|
|
2771
|
+
*
|
|
2772
|
+
* Shared between the picker UI, the standalone Pose parameter node, and
|
|
2773
|
+
* the prompt-hint injection on both the frontend DAG executor and the
|
|
2774
|
+
* backend orchestrator.
|
|
2775
|
+
*/
|
|
2776
|
+
type PoseCategory = "standing" | "seated" | "movement" | "action" | "resting" | "hand-position" | "body-lean" | "head-tilt" | "activity";
|
|
2777
|
+
interface Pose {
|
|
2778
|
+
readonly id: string;
|
|
2779
|
+
readonly label: string;
|
|
2780
|
+
readonly category: PoseCategory;
|
|
2781
|
+
readonly description: string;
|
|
2782
|
+
readonly promptHint: string;
|
|
2783
|
+
}
|
|
2784
|
+
declare const POSES: ReadonlyArray<Pose>;
|
|
2785
|
+
declare function getPose(id: string | undefined | null): Pose | undefined;
|
|
2786
|
+
declare function getPoseLabel(id: string | undefined | null, fallback?: string): string;
|
|
2787
|
+
declare function getPosePromptHint(id: string | undefined | null): string;
|
|
2788
|
+
declare const POSE_IDS: ReadonlyArray<string>;
|
|
2789
|
+
declare const POSE_CATEGORY_LABELS: Readonly<Record<PoseCategory, string>>;
|
|
2790
|
+
declare const POSE_CATEGORY_ORDER: ReadonlyArray<PoseCategory>;
|
|
2791
|
+
/**
|
|
2792
|
+
* Shape of Pose parameter data. Multi-dimensional: pose + optional
|
|
2793
|
+
* orthogonal sub-pickers (hand position / body lean / head tilt) + optional
|
|
2794
|
+
* pre/post free text.
|
|
2795
|
+
*/
|
|
2796
|
+
interface PoseValue {
|
|
2797
|
+
pose?: string;
|
|
2798
|
+
/** Optional hand-position pose id (orthogonal to pose). */
|
|
2799
|
+
handPosition?: string;
|
|
2800
|
+
/** Optional body-lean pose id (orthogonal to pose). */
|
|
2801
|
+
bodyLean?: string;
|
|
2802
|
+
/** Optional head-tilt pose id (orthogonal to pose). */
|
|
2803
|
+
headTilt?: string;
|
|
2804
|
+
/** Optional activity pose id — what the subject is DOING in the world
|
|
2805
|
+
* (smoking, eating, texting, driving…). Distinct from posture / movement /
|
|
2806
|
+
* action; orthogonal to the other sub-pickers. */
|
|
2807
|
+
activity?: string;
|
|
2808
|
+
preText?: string;
|
|
2809
|
+
postText?: string;
|
|
2810
|
+
}
|
|
2811
|
+
/**
|
|
2812
|
+
* Build prompt hints from PoseData: optional pre-text, the selected pose's
|
|
2813
|
+
* hint, the orthogonal hand-position / body-lean / head-tilt hints,
|
|
2814
|
+
* optional post-text. Returns array — caller joins with ", ".
|
|
2815
|
+
*/
|
|
2816
|
+
declare function buildPoseHints(data: Record<string, unknown> & PoseValue): string[];
|
|
2817
|
+
|
|
2818
|
+
/**
|
|
2819
|
+
* Canonical catalog of Post-Process Effects choices.
|
|
2820
|
+
*
|
|
2821
|
+
* Post-process effects describe an image-level grade or processing pass
|
|
2822
|
+
* applied AFTER the image is captured / rendered — vignette, grain, halation,
|
|
2823
|
+
* bloom, chromatic aberration, light leaks, scratches, soft-focus diffusion,
|
|
2824
|
+
* dodge-and-burn, etc. These are the touches a colorist or photographer
|
|
2825
|
+
* applies in the darkroom or grading suite.
|
|
2826
|
+
*
|
|
2827
|
+
* Distinct from:
|
|
2828
|
+
* - Style — the artistic medium (oil paint, watercolor, anime).
|
|
2829
|
+
* - Composition Effects — what the subject is made of or how it interacts
|
|
2830
|
+
* with the frame (smoke sculpture, exploding particles, breaking the
|
|
2831
|
+
* fourth wall).
|
|
2832
|
+
* - Color Look — overall color grade direction (teal-orange, pastel, mono).
|
|
2833
|
+
* - Atmosphere — what's in the air (fog, dust, rain).
|
|
2834
|
+
*
|
|
2835
|
+
* Single-pick — only one post-process pass is applied per consumer.
|
|
2836
|
+
*
|
|
2837
|
+
* Shared between picker UI and prompt-hint injection in the frontend DAG
|
|
2838
|
+
* executor and the backend orchestrator.
|
|
2839
|
+
*/
|
|
2840
|
+
interface PostProcessEffect {
|
|
2841
|
+
readonly id: string;
|
|
2842
|
+
readonly label: string;
|
|
2843
|
+
readonly description: string;
|
|
2844
|
+
readonly promptHint: string;
|
|
2845
|
+
}
|
|
2846
|
+
declare const POST_PROCESS_EFFECTS: ReadonlyArray<PostProcessEffect>;
|
|
2847
|
+
declare function getPostProcessEffect(id: string | undefined | null): PostProcessEffect | undefined;
|
|
2848
|
+
declare function getPostProcessEffectLabel(id: string | undefined | null, fallback?: string): string;
|
|
2849
|
+
declare function getPostProcessEffectPromptHint(id: string | undefined | null): string;
|
|
2850
|
+
/**
|
|
2851
|
+
* Multi-pick: 1-2 post-process effect ids → composite grading clause.
|
|
2852
|
+
* Common pairs: vignette + film-grain, halation + bloom, dodge-burn +
|
|
2853
|
+
* chromatic-aberration. Each entry already describes a complete grading
|
|
2854
|
+
* pass, so we emit independently and let the comma-join compose them.
|
|
2855
|
+
*/
|
|
2856
|
+
declare function buildPostProcessHints(value: unknown): string[];
|
|
2857
|
+
declare const POST_PROCESS_EFFECT_IDS: ReadonlyArray<string>;
|
|
2858
|
+
|
|
2859
|
+
/**
|
|
2860
|
+
* Canonical catalog of Render Engine / Quality presets.
|
|
2861
|
+
*
|
|
2862
|
+
* "Render Quality" is the pure technical-stamp dimension — what tool the image
|
|
2863
|
+
* appears to have been rendered through, or what quality stamp it carries.
|
|
2864
|
+
* Distinct from Style (artistic medium), Lens (optics), and Camera Format
|
|
2865
|
+
* (capture medium): a "raytracing" hint says nothing about whether the look
|
|
2866
|
+
* is anime or photorealistic; it just promises ray-traced-grade reflections,
|
|
2867
|
+
* shadows, and global illumination.
|
|
2868
|
+
*
|
|
2869
|
+
* Three loose families, each adding a different kind of authority signal:
|
|
2870
|
+
* - Engines: name a real render package (Unreal 5, Octane, Cycles…). Useful
|
|
2871
|
+
* for hyper-stylized 3D illustration or game-trailer aesthetics.
|
|
2872
|
+
* - Render-quality keywords: the technical buzzwords that lock in modern
|
|
2873
|
+
* physically-correct lighting (raytracing, PBR, GI, lumen).
|
|
2874
|
+
* - Resolution / Detail: explicit "sharp + detailed" stamps (4K/8K/16K,
|
|
2875
|
+
* "ultra-detailed").
|
|
2876
|
+
* - Style stamps: portmanteau quality markers ("masterpiece", "raw photo",
|
|
2877
|
+
* "award-winning") that providers strongly weight.
|
|
2878
|
+
*
|
|
2879
|
+
* Single-pick — only one render-quality stamp is applied per consumer. Shared
|
|
2880
|
+
* between picker UI and prompt-hint injection in the frontend DAG executor
|
|
2881
|
+
* and the backend orchestrator.
|
|
2882
|
+
*/
|
|
2883
|
+
interface RenderQuality {
|
|
2884
|
+
readonly id: string;
|
|
2885
|
+
readonly label: string;
|
|
2886
|
+
readonly description: string;
|
|
2887
|
+
readonly promptHint: string;
|
|
2888
|
+
}
|
|
2889
|
+
declare const RENDER_QUALITIES: ReadonlyArray<RenderQuality>;
|
|
2890
|
+
declare function getRenderQuality(id: string | undefined | null): RenderQuality | undefined;
|
|
2891
|
+
declare function getRenderQualityLabel(id: string | undefined | null, fallback?: string): string;
|
|
2892
|
+
declare function getRenderQualityPromptHint(id: string | undefined | null): string;
|
|
2893
|
+
declare const RENDER_QUALITY_IDS: ReadonlyArray<string>;
|
|
2894
|
+
|
|
2895
|
+
/**
|
|
2896
|
+
* Canonical catalog of place/environment presets ("Setting").
|
|
2897
|
+
*
|
|
2898
|
+
* Setting dimension of an image/video — *where* the shot takes place (coffee
|
|
2899
|
+
* shop, forest clearing, cyberpunk alley, cathedral, etc.). Orthogonal to the
|
|
2900
|
+
* other cinematography dimensions:
|
|
2901
|
+
*
|
|
2902
|
+
* - Style = artistic medium (Oil Painting, Pixar 3D, Photorealistic)
|
|
2903
|
+
* - Atmosphere = what's in the air (Fog, Rain, God rays, Dust)
|
|
2904
|
+
* - Lighting = direction / quality of light
|
|
2905
|
+
* - Setting = *where* (this file)
|
|
2906
|
+
*
|
|
2907
|
+
* Not to be confused with the Location **entity** node, which generates a
|
|
2908
|
+
* persistent reference image for a specific place via an AI provider call.
|
|
2909
|
+
* Setting is pure prompt text (zero credits, zero API calls), deterministic.
|
|
2910
|
+
*
|
|
2911
|
+
* Shared between the picker UI, the standalone Setting parameter node, and
|
|
2912
|
+
* the prompt-hint injection on both the frontend DAG executor and the
|
|
2913
|
+
* backend orchestrator.
|
|
2914
|
+
*/
|
|
2915
|
+
type SettingCategory = "indoor" | "urban" | "nature" | "fantastical";
|
|
2916
|
+
interface Setting {
|
|
2917
|
+
readonly id: string;
|
|
2918
|
+
readonly label: string;
|
|
2919
|
+
readonly category: SettingCategory;
|
|
2920
|
+
readonly description: string;
|
|
2921
|
+
readonly promptHint: string;
|
|
2922
|
+
}
|
|
2923
|
+
declare const SETTINGS: ReadonlyArray<Setting>;
|
|
2924
|
+
declare function getSetting(id: string | undefined | null): Setting | undefined;
|
|
2925
|
+
declare function getSettingLabel(id: string | undefined | null, fallback?: string): string;
|
|
2926
|
+
declare function getSettingPromptHint(id: string | undefined | null): string;
|
|
2927
|
+
declare const SETTING_IDS: ReadonlyArray<string>;
|
|
2928
|
+
declare const SETTING_CATEGORY_LABELS: Readonly<Record<SettingCategory, string>>;
|
|
2929
|
+
|
|
2930
|
+
/**
|
|
2931
|
+
* Canonical catalog of image style presets.
|
|
2932
|
+
*
|
|
2933
|
+
* Style dimension of an image/video — the overall artistic rendering or
|
|
2934
|
+
* medium (anime, oil painting, photorealistic, etc.). Independent of
|
|
2935
|
+
* lighting (direction/color of light), color/look (post-processing grade),
|
|
2936
|
+
* atmosphere (environmental effects), lens (focal length distortion), and
|
|
2937
|
+
* framing (composition). Two shots with identical lighting, lens and
|
|
2938
|
+
* framing still look radically different when one is "Oil Painting" and
|
|
2939
|
+
* the other is "Pixel Art".
|
|
2940
|
+
*
|
|
2941
|
+
* Shared between the picker UI, the standalone Style parameter node, the
|
|
2942
|
+
* inline Style dropdown in image config panels (backward-compat), and the
|
|
2943
|
+
* prompt-hint injection on both the frontend DAG executor and the backend
|
|
2944
|
+
* orchestrator.
|
|
2945
|
+
*
|
|
2946
|
+
* The `id` values are kept in sync with `IMAGE_STYLE_PRESETS` in
|
|
2947
|
+
* `frontend/src/components/editor/config-panels/model-options.ts` so the
|
|
2948
|
+
* inline dropdown and the Style node resolve to the same richer promptHint
|
|
2949
|
+
* at execution time.
|
|
2950
|
+
*/
|
|
2951
|
+
interface Style {
|
|
2952
|
+
readonly id: string;
|
|
2953
|
+
readonly label: string;
|
|
2954
|
+
readonly description: string;
|
|
2955
|
+
readonly promptHint: string;
|
|
2956
|
+
}
|
|
2957
|
+
declare const STYLES: ReadonlyArray<Style>;
|
|
2958
|
+
declare function getStyle(id: string | undefined | null): Style | undefined;
|
|
2959
|
+
declare function getStyleLabel(id: string | undefined | null, fallback?: string): string;
|
|
2960
|
+
declare function getStylePromptHint(id: string | undefined | null): string;
|
|
2961
|
+
declare const STYLE_IDS: ReadonlyArray<string>;
|
|
2962
|
+
|
|
2963
|
+
/**
|
|
2964
|
+
* Canonical catalog of Styling / beauty + wardrobe + accessories choices.
|
|
2965
|
+
*
|
|
2966
|
+
* Multi-dimension parameter node like Person and Framing:
|
|
2967
|
+
*
|
|
2968
|
+
* Beauty / Hair / Accessories
|
|
2969
|
+
* 1. makeup — Natural, glamour, smoky, goth, bold lips, editorial, dewy…
|
|
2970
|
+
* 2. hair-cut — Pixie, bob, buzz cut, pompadour, dreadlocks, braids (45 entries)
|
|
2971
|
+
* 3. hair-treatment — Babylights, balayage, ombré, highlights…
|
|
2972
|
+
* 4. hair-state — Wet, messy, windswept, voluminous, sleek, frizzy,
|
|
2973
|
+
* tousled, flowing… Hair motion / condition. Distinct
|
|
2974
|
+
* from cut (shape) and treatment (color).
|
|
2975
|
+
* 5. eyewear — Sunglasses (aviators / cat-eye / round), fashion glasses…
|
|
2976
|
+
* 6. headwear — Hats (beanie, cap, fedora…), headbands, hoods, crowns
|
|
2977
|
+
* 7. jewelry — Subtle, statement, gold, silver, layered, pearl
|
|
2978
|
+
* 8. nails — Polished, red, dark, long acrylic, French tips
|
|
2979
|
+
* 9. face-paint — Subtle, dramatic, costume, tribal markings
|
|
2980
|
+
*
|
|
2981
|
+
* Wardrobe (head-to-toe garments)
|
|
2982
|
+
* 10. outfit — Single-pick complete look (school uniform, business
|
|
2983
|
+
* suit, evening gown, scrubs, bikini, lingerie, kimono…).
|
|
2984
|
+
* Intended as an override that semantically supersedes
|
|
2985
|
+
* the per-piece selections; users are responsible for
|
|
2986
|
+
* not stacking conflicting pieces.
|
|
2987
|
+
* 11. top — Upper-body garment (t-shirt, hoodie, sweater, blouse,
|
|
2988
|
+
* crop top, bikini top, sports bra…)
|
|
2989
|
+
* 12. bottom — Lower-body garment (jeans, chinos, skirt, shorts,
|
|
2990
|
+
* leggings, sweatpants…)
|
|
2991
|
+
* 13. outerwear — Layered-over outer garment (leather jacket, blazer,
|
|
2992
|
+
* trench, puffer, cardigan, kimono robe…)
|
|
2993
|
+
* 14. legwear — Stockings / tights / socks worn between bottom and
|
|
2994
|
+
* footwear (sheer / opaque tights, fishnets, thigh-highs…)
|
|
2995
|
+
* 15. footwear — Shoes (sneakers, heels, boots, loafers, sandals…)
|
|
2996
|
+
*
|
|
2997
|
+
* Modifiers
|
|
2998
|
+
* 16. fabric — Clothing fabric (silk, leather, denim, velvet…) phrased
|
|
2999
|
+
* as "wearing X". Overlaps vocabulary with the universal
|
|
3000
|
+
* Material node in the Object category, but Fabric is
|
|
3001
|
+
* clothing-specific and scoped to the Subject workflow.
|
|
3002
|
+
* 17. wardrobe-state — How the clothes are worn (oversized, fitted, cropped,
|
|
3003
|
+
* sheer, wet, ripped, off-shoulder, tucked-in, layered,
|
|
3004
|
+
* unbuttoned…). Composes with any garment selection.
|
|
3005
|
+
*
|
|
3006
|
+
* Each dimension is mutually exclusive within itself; all are optional.
|
|
3007
|
+
* Applies to BOTH image and video consumers. Includes pre/post free-text
|
|
3008
|
+
* fields for specifics the catalog can't express.
|
|
3009
|
+
*/
|
|
3010
|
+
type StylingDimension = "makeup" | "eyewear" | "headwear" | "hair-cut" | "hair-treatment" | "hair-state" | "jewelry" | "nails" | "face-paint" | "outfit" | "top" | "bottom" | "outerwear" | "legwear" | "footwear" | "fabric" | "wardrobe-state";
|
|
3011
|
+
interface Styling {
|
|
3012
|
+
readonly id: string;
|
|
3013
|
+
readonly label: string;
|
|
3014
|
+
readonly dimension: StylingDimension;
|
|
3015
|
+
readonly description: string;
|
|
3016
|
+
readonly promptHint: string;
|
|
3017
|
+
}
|
|
3018
|
+
declare const STYLINGS: ReadonlyArray<Styling>;
|
|
3019
|
+
declare const STYLING_DIMENSION_ORDER: ReadonlyArray<StylingDimension>;
|
|
3020
|
+
declare const STYLING_DIMENSION_LABELS: Readonly<Record<StylingDimension, string>>;
|
|
3021
|
+
declare const STYLING_FIELD_BY_DIMENSION: Record<StylingDimension, "makeup" | "eyewear" | "headwear" | "hairCut" | "hairTreatment" | "hairState" | "jewelry" | "nails" | "facePaint" | "outfit" | "top" | "bottom" | "outerwear" | "legwear" | "footwear" | "fabric" | "wardrobeState">;
|
|
3022
|
+
/** Per-dimension multi-select cap — single source of truth for the picker UI,
|
|
3023
|
+
* the image-analyzer tool schema, and the Zod validator. jewelry: 3
|
|
3024
|
+
* (necklace + earrings + rings), wardrobe-state: 3 (oversized + wet + ripped),
|
|
3025
|
+
* hair-state: 2 (wet + windswept). All others single-select (absent → 1). */
|
|
3026
|
+
declare const MAX_SELECTED_BY_STYLING_DIMENSION: Partial<Record<StylingDimension, number>>;
|
|
3027
|
+
/** Selection limit for a styling dimension (1 when not multi-select). */
|
|
3028
|
+
declare function getStylingDimensionLimit(dimension: StylingDimension): number;
|
|
3029
|
+
interface StylingValue {
|
|
3030
|
+
makeup?: string;
|
|
3031
|
+
eyewear?: string;
|
|
3032
|
+
headwear?: string;
|
|
3033
|
+
/** Hair cut / styling choice — bob, wolf cut, braids, ponytail, etc.
|
|
3034
|
+
* Pairs with Person.hair-base (texture + length). */
|
|
3035
|
+
hairCut?: string;
|
|
3036
|
+
hairTreatment?: string;
|
|
3037
|
+
/** Hair state / motion / condition — wet, messy, windswept, voluminous,
|
|
3038
|
+
* sleek, frizzy, tousled, flowing… Distinct from cut (shape) and
|
|
3039
|
+
* treatment (color processing). Single id or up to 2 (e.g.
|
|
3040
|
+
* ["wet", "windswept"], ["messy", "voluminous"]). */
|
|
3041
|
+
hairState?: string | ReadonlyArray<string>;
|
|
3042
|
+
/** Jewelry. Single id or up to 3 ids for stacked jewelry
|
|
3043
|
+
* (e.g. necklace + earrings + rings). */
|
|
3044
|
+
jewelry?: string | ReadonlyArray<string>;
|
|
3045
|
+
nails?: string;
|
|
3046
|
+
facePaint?: string;
|
|
3047
|
+
/** Single-pick complete outfit archetype (school uniform, business suit,
|
|
3048
|
+
* evening gown, scrubs, bikini, lingerie, kimono…). Intended as an override
|
|
3049
|
+
* that semantically supersedes the per-piece selections. */
|
|
3050
|
+
outfit?: string;
|
|
3051
|
+
/** Upper-body garment (t-shirt, sweater, blouse, sports bra, bikini top…). */
|
|
3052
|
+
top?: string;
|
|
3053
|
+
/** Lower-body garment (jeans, chinos, skirt, shorts, leggings…). */
|
|
3054
|
+
bottom?: string;
|
|
3055
|
+
/** Layered-over outer garment (jacket, blazer, coat, cardigan…). */
|
|
3056
|
+
outerwear?: string;
|
|
3057
|
+
/** Legwear worn between bottom and footwear (tights, fishnets, stockings, socks…). */
|
|
3058
|
+
legwear?: string;
|
|
3059
|
+
/** Shoes (sneakers, heels, boots, loafers, sandals…). */
|
|
3060
|
+
footwear?: string;
|
|
3061
|
+
/** Clothing fabric / material — silk, leather, denim, etc. Phrased as
|
|
3062
|
+
* "wearing X"; overlaps in vocabulary with the universal Material node
|
|
3063
|
+
* in the Object category. */
|
|
3064
|
+
fabric?: string;
|
|
3065
|
+
/** How the clothes are worn — oversized, fitted, cropped, sheer, wet,
|
|
3066
|
+
* ripped, off-shoulder, tucked-in, layered, unbuttoned… Composes with
|
|
3067
|
+
* any garment selection. Single id or up to 3 ids for stacked
|
|
3068
|
+
* modifiers (e.g. ["oversized", "wet", "ripped"]). */
|
|
3069
|
+
wardrobeState?: string | ReadonlyArray<string>;
|
|
3070
|
+
preText?: string;
|
|
3071
|
+
postText?: string;
|
|
3072
|
+
}
|
|
3073
|
+
declare function getStyling(id: string | undefined | null): Styling | undefined;
|
|
3074
|
+
declare function getStylingLabel(id: string | undefined | null, fallback?: string): string;
|
|
3075
|
+
declare function getStylingPromptHint(id: string | undefined | null): string;
|
|
3076
|
+
declare const STYLING_IDS: ReadonlyArray<string>;
|
|
3077
|
+
declare function buildStylingHints(data: Record<string, unknown> & StylingValue): string[];
|
|
3078
|
+
|
|
3079
|
+
/**
|
|
3080
|
+
* Canonical catalog of temporal modifiers.
|
|
3081
|
+
*
|
|
3082
|
+
* Temporal is the speed / freeze / direction / shutter dimension of a video —
|
|
3083
|
+
* how time flows through the shot. Distinct from the post-process Speed Ramp
|
|
3084
|
+
* FFmpeg node (which operates on an existing rendered video); these are
|
|
3085
|
+
* prompt-time guidance hints for the generator model so it produces footage
|
|
3086
|
+
* that already embeds the temporal intent. Independent of lighting, color,
|
|
3087
|
+
* lens, camera motion, etc.
|
|
3088
|
+
*
|
|
3089
|
+
* Video-only: stills can't have motion or a speed, so image-gen consumers
|
|
3090
|
+
* don't read this field.
|
|
3091
|
+
*
|
|
3092
|
+
* Shared between the picker UI and the prompt-hint injection on both the
|
|
3093
|
+
* frontend DAG executor and the backend orchestrator.
|
|
3094
|
+
*/
|
|
3095
|
+
type TemporalCategory = "speed" | "freeze" | "direction" | "shutter";
|
|
3096
|
+
interface Temporal {
|
|
3097
|
+
readonly id: string;
|
|
3098
|
+
readonly label: string;
|
|
3099
|
+
readonly category: TemporalCategory;
|
|
3100
|
+
readonly description: string;
|
|
3101
|
+
readonly promptHint: string;
|
|
3102
|
+
}
|
|
3103
|
+
declare const TEMPORALS: ReadonlyArray<Temporal>;
|
|
3104
|
+
declare const TEMPORAL_CATEGORY_ORDER: ReadonlyArray<TemporalCategory>;
|
|
3105
|
+
declare const TEMPORAL_CATEGORY_LABELS: Record<TemporalCategory, string>;
|
|
3106
|
+
declare function getTemporal(id: string | undefined | null): Temporal | undefined;
|
|
3107
|
+
declare function getTemporalLabel(id: string | undefined | null, fallback?: string): string;
|
|
3108
|
+
declare function getTemporalPromptHint(id: string | undefined | null): string;
|
|
3109
|
+
declare const TEMPORAL_IDS: ReadonlyArray<string>;
|
|
3110
|
+
/**
|
|
3111
|
+
* Maps each TemporalCategory to the consumer data field name that holds the
|
|
3112
|
+
* selected entry id for that category. Multi-category temporal: a consumer
|
|
3113
|
+
* (video-only) can independently set a value in each of the 4 dimensions.
|
|
3114
|
+
*
|
|
3115
|
+
* Field names use 'temporal' prefix throughout to avoid collisions: 'direction'
|
|
3116
|
+
* collides with Lighting's 'direction' category; 'speed', 'shutter', and
|
|
3117
|
+
* 'freeze' are generic vocabulary.
|
|
3118
|
+
*/
|
|
3119
|
+
declare const TEMPORAL_FIELD_BY_CATEGORY: Record<TemporalCategory, "temporalSpeed" | "temporalFreeze" | "temporalDirection" | "temporalShutter">;
|
|
3120
|
+
/**
|
|
3121
|
+
* Shape of the per-category temporal fields on TemporalData and the 5 video
|
|
3122
|
+
* consumer data types. All fields optional — user may set zero, one, or all
|
|
3123
|
+
* categories.
|
|
3124
|
+
*/
|
|
3125
|
+
interface TemporalValue {
|
|
3126
|
+
temporalSpeed?: string;
|
|
3127
|
+
temporalFreeze?: string;
|
|
3128
|
+
temporalDirection?: string;
|
|
3129
|
+
temporalShutter?: string;
|
|
3130
|
+
}
|
|
3131
|
+
/**
|
|
3132
|
+
* Aggregate all enabled per-category temporal prompt hints from a consumer's
|
|
3133
|
+
* data, in canonical category order (speed, freeze, direction, shutter).
|
|
3134
|
+
*
|
|
3135
|
+
* Accepts a loosely typed record (the helper is shared between strongly typed
|
|
3136
|
+
* frontend node data and the backend's `Record<string, unknown>` workflow
|
|
3137
|
+
* data). Non-string values are ignored.
|
|
3138
|
+
*
|
|
3139
|
+
* @param data the consumer data record (must include optional temporalSpeed /
|
|
3140
|
+
* temporalFreeze / temporalDirection / temporalShutter fields)
|
|
3141
|
+
*/
|
|
3142
|
+
declare function buildTemporalHints(data: Record<string, unknown> & {
|
|
3143
|
+
temporalSpeed?: unknown;
|
|
3144
|
+
temporalFreeze?: unknown;
|
|
3145
|
+
temporalDirection?: unknown;
|
|
3146
|
+
temporalShutter?: unknown;
|
|
3147
|
+
}): string[];
|
|
3148
|
+
|
|
3149
|
+
/**
|
|
3150
|
+
* Canonical catalog of cinematic transitions for AI-video generation.
|
|
3151
|
+
*
|
|
3152
|
+
* Shared between frontend (picker UI, prompt hint injection) and backend
|
|
3153
|
+
* (orchestrator payload builder). The `promptHint` is a natural-language
|
|
3154
|
+
* cue that gets composed into the user prompt when a transition node is
|
|
3155
|
+
* connected to a video consumer.
|
|
3156
|
+
*
|
|
3157
|
+
* Multi-pick supported: value field accepts `string | string[]` (cap 2).
|
|
3158
|
+
* Graph-aware: `startState` / `endState` input handles accept upstream
|
|
3159
|
+
* parameter nodes whose hints are folded into the composed clause as
|
|
3160
|
+
* "starting from <X>, ending at <Y>".
|
|
3161
|
+
*/
|
|
3162
|
+
type TransitionCategory = "standard" | "time" | "element" | "morph" | "portal" | "physics" | "light" | "glitch";
|
|
3163
|
+
interface Transition {
|
|
3164
|
+
readonly id: string;
|
|
3165
|
+
readonly label: string;
|
|
3166
|
+
readonly category: TransitionCategory;
|
|
3167
|
+
readonly description: string;
|
|
3168
|
+
readonly promptHint: string;
|
|
3169
|
+
}
|
|
3170
|
+
type TransitionPosition = "auto" | "start" | "middle" | "end" | "full";
|
|
3171
|
+
type TransitionDuration = "auto" | "instant" | "short" | "medium" | "long";
|
|
3172
|
+
type TransitionIntensity = "auto" | "subtle" | "natural" | "dynamic" | "crazy";
|
|
3173
|
+
interface TransitionTiming {
|
|
3174
|
+
position?: TransitionPosition;
|
|
3175
|
+
duration?: TransitionDuration;
|
|
3176
|
+
intensity?: TransitionIntensity;
|
|
3177
|
+
}
|
|
3178
|
+
declare const TRANSITIONS: ReadonlyArray<Transition>;
|
|
3179
|
+
declare const TRANSITION_CATEGORY_ORDER: ReadonlyArray<TransitionCategory>;
|
|
3180
|
+
declare const TRANSITION_CATEGORY_LABELS: Readonly<Record<TransitionCategory, string>>;
|
|
3181
|
+
declare function getTransition(id: string | undefined | null): Transition | undefined;
|
|
3182
|
+
declare function getTransitionLabel(id: string | undefined | null, fallback?: string): string;
|
|
3183
|
+
declare function getTransitionPromptHint(id: string | undefined | null): string;
|
|
3184
|
+
declare const TRANSITION_IDS: ReadonlyArray<string>;
|
|
3185
|
+
/**
|
|
3186
|
+
* Compose a structural prompt-hint sentence from a transition id (or array
|
|
3187
|
+
* of 1-2 ids for multi-pick) plus optional start-state/end-state hints
|
|
3188
|
+
* (collected by walking the source node's startState / endState input
|
|
3189
|
+
* handle edges upstream) and optional timing fields.
|
|
3190
|
+
*
|
|
3191
|
+
* Behavior:
|
|
3192
|
+
* - 0 hints (no transition, empty array, or all-empty hints) → ""
|
|
3193
|
+
* - n base hints joined with ", and "
|
|
3194
|
+
* - Timing/start/end clauses apply ONCE at the outer layer, not per-id
|
|
3195
|
+
* - null input is treated like undefined (falsy short-circuit → returns "")
|
|
3196
|
+
*/
|
|
3197
|
+
declare function composeTransitionHintFromConnections(transitionId: string | ReadonlyArray<string> | undefined, startHints: ReadonlyArray<string>, endHints: ReadonlyArray<string>, timing?: TransitionTiming): string;
|
|
3198
|
+
|
|
3199
|
+
/**
|
|
3200
|
+
* Voice-character catalog: age + gender + language + accent + timbre. Feeds
|
|
3201
|
+
* Voice Design's voiceDescription field via the Sound aggregator.
|
|
3202
|
+
*
|
|
3203
|
+
* `language` is multi-pick (up to 3) for codeswitching / multilingual
|
|
3204
|
+
* voice work. Distinct from `accent` — accent is HOW it sounds, language
|
|
3205
|
+
* is WHAT'S being spoken.
|
|
3206
|
+
*/
|
|
3207
|
+
interface VoiceCharacterEntry {
|
|
3208
|
+
readonly id: string;
|
|
3209
|
+
readonly label: string;
|
|
3210
|
+
readonly description: string;
|
|
3211
|
+
readonly promptHint: string;
|
|
3212
|
+
}
|
|
3213
|
+
declare const VOICE_AGES: ReadonlyArray<VoiceCharacterEntry>;
|
|
3214
|
+
declare const VOICE_GENDERS: ReadonlyArray<VoiceCharacterEntry>;
|
|
3215
|
+
declare const VOICE_LANGUAGES: ReadonlyArray<VoiceCharacterEntry>;
|
|
3216
|
+
declare const VOICE_ACCENTS: ReadonlyArray<VoiceCharacterEntry>;
|
|
3217
|
+
declare const VOICE_TIMBRES: ReadonlyArray<VoiceCharacterEntry>;
|
|
3218
|
+
declare function getVoiceAge(id: string | undefined): VoiceCharacterEntry | undefined;
|
|
3219
|
+
declare function getVoiceGender(id: string | undefined): VoiceCharacterEntry | undefined;
|
|
3220
|
+
declare function getVoiceLanguage(id: string | undefined): VoiceCharacterEntry | undefined;
|
|
3221
|
+
declare function getVoiceAccent(id: string | undefined): VoiceCharacterEntry | undefined;
|
|
3222
|
+
declare function getVoiceTimbre(id: string | undefined): VoiceCharacterEntry | undefined;
|
|
3223
|
+
/**
|
|
3224
|
+
* Compose a natural-language voice character clause.
|
|
3225
|
+
* Examples (depending on which sub-fields are set):
|
|
3226
|
+
* { age, gender, timbre, accent } → "middle-aged male voice with warm timbre and British RP accent"
|
|
3227
|
+
* { timbre } → "warm timbre"
|
|
3228
|
+
* { accent } → "British RP accent"
|
|
3229
|
+
* { age, gender } → "middle-aged male voice"
|
|
3230
|
+
* { language: ["english","spanish"] } → "English / Spanish voice"
|
|
3231
|
+
* { } → ""
|
|
3232
|
+
*
|
|
3233
|
+
* `language` is multi-pick — multiple languages emit "English / Spanish"
|
|
3234
|
+
* for codeswitching / multilingual voices.
|
|
3235
|
+
*/
|
|
3236
|
+
declare function buildVoiceCharacterHints(data: {
|
|
3237
|
+
readonly preText?: string;
|
|
3238
|
+
readonly postText?: string;
|
|
3239
|
+
readonly age?: string;
|
|
3240
|
+
readonly gender?: string;
|
|
3241
|
+
readonly language?: string | ReadonlyArray<string>;
|
|
3242
|
+
readonly accent?: string;
|
|
3243
|
+
readonly timbre?: string;
|
|
3244
|
+
}): string;
|
|
3245
|
+
declare const VOICE_CHARACTER_DEFAULT_DATA: {
|
|
3246
|
+
preText?: string;
|
|
3247
|
+
postText?: string;
|
|
3248
|
+
age?: string;
|
|
3249
|
+
gender?: string;
|
|
3250
|
+
language?: string | ReadonlyArray<string>;
|
|
3251
|
+
accent?: string;
|
|
3252
|
+
timbre?: string;
|
|
3253
|
+
};
|
|
3254
|
+
|
|
3255
|
+
/**
|
|
3256
|
+
* Voice-delivery catalog: pace + emotion + archetype. Feeds
|
|
3257
|
+
* Voice Design's voiceDescription via the Sound aggregator.
|
|
3258
|
+
*/
|
|
3259
|
+
interface VoiceDeliveryEntry {
|
|
3260
|
+
readonly id: string;
|
|
3261
|
+
readonly label: string;
|
|
3262
|
+
readonly description: string;
|
|
3263
|
+
readonly promptHint: string;
|
|
3264
|
+
}
|
|
3265
|
+
declare const VOICE_PACES: ReadonlyArray<VoiceDeliveryEntry>;
|
|
3266
|
+
declare const VOICE_EMOTIONS: ReadonlyArray<VoiceDeliveryEntry>;
|
|
3267
|
+
declare const VOICE_ARCHETYPES: ReadonlyArray<VoiceDeliveryEntry>;
|
|
3268
|
+
declare function getVoicePace(id: string | undefined): VoiceDeliveryEntry | undefined;
|
|
3269
|
+
declare function getVoiceEmotion(id: string | undefined): VoiceDeliveryEntry | undefined;
|
|
3270
|
+
declare function getVoiceArchetype(id: string | undefined): VoiceDeliveryEntry | undefined;
|
|
3271
|
+
/**
|
|
3272
|
+
* Compose a delivery clause.
|
|
3273
|
+
* Examples:
|
|
3274
|
+
* { pace, archetype, emotion } → "measured documentary-narrator-style delivery, reassuring tone"
|
|
3275
|
+
* { archetype } → "documentary-narrator-style delivery"
|
|
3276
|
+
* { emotion } → "reassuring tone"
|
|
3277
|
+
* { pace } → "measured pace"
|
|
3278
|
+
*/
|
|
3279
|
+
declare function buildVoiceDeliveryHints(data: {
|
|
3280
|
+
readonly preText?: string;
|
|
3281
|
+
readonly postText?: string;
|
|
3282
|
+
readonly pace?: string;
|
|
3283
|
+
readonly emotion?: string;
|
|
3284
|
+
readonly archetype?: string;
|
|
3285
|
+
}): string;
|
|
3286
|
+
declare const VOICE_DELIVERY_DEFAULT_DATA: {
|
|
3287
|
+
preText?: string;
|
|
3288
|
+
postText?: string;
|
|
3289
|
+
pace?: string;
|
|
3290
|
+
emotion?: string;
|
|
3291
|
+
archetype?: string;
|
|
3292
|
+
};
|
|
3293
|
+
|
|
3294
|
+
type WardrobeDimension = "archetype" | "top" | "bottom" | "outerwear" | "footwear" | "headwear" | "accessories" | "color-palette" | "material" | "era";
|
|
3295
|
+
interface WardrobeEntry {
|
|
3296
|
+
readonly id: string;
|
|
3297
|
+
readonly label: string;
|
|
3298
|
+
readonly dimension: WardrobeDimension;
|
|
3299
|
+
readonly promptHint: string;
|
|
3300
|
+
}
|
|
3301
|
+
interface WardrobeValue {
|
|
3302
|
+
archetype?: string;
|
|
3303
|
+
top?: string;
|
|
3304
|
+
bottom?: string;
|
|
3305
|
+
outerwear?: string;
|
|
3306
|
+
footwear?: string;
|
|
3307
|
+
headwear?: string | ReadonlyArray<string>;
|
|
3308
|
+
accessories?: string | ReadonlyArray<string>;
|
|
3309
|
+
colorPalette?: string;
|
|
3310
|
+
material?: string;
|
|
3311
|
+
era?: string;
|
|
3312
|
+
}
|
|
3313
|
+
declare const WARDROBE_DIMENSION_ORDER: ReadonlyArray<WardrobeDimension>;
|
|
3314
|
+
declare const WARDROBE_CATEGORY_LABELS: Readonly<Record<WardrobeDimension, string>>;
|
|
3315
|
+
declare const WARDROBE_FIELD_BY_DIMENSION: Record<WardrobeDimension, keyof WardrobeValue>;
|
|
3316
|
+
declare const WARDROBE: ReadonlyArray<WardrobeEntry>;
|
|
3317
|
+
declare function getWardrobeEntry(id: string | undefined | null): WardrobeEntry | undefined;
|
|
3318
|
+
declare function getWardrobePromptHint(id: string | undefined | null): string;
|
|
3319
|
+
declare function getWardrobeEntriesByDimension(dim: WardrobeDimension): WardrobeEntry[];
|
|
3320
|
+
declare function buildWardrobeHints(value: Record<string, unknown> & WardrobeValue): string[];
|
|
3321
|
+
|
|
3322
|
+
/**
|
|
3323
|
+
* Default prompt templates and template resolution/application functions.
|
|
3324
|
+
* Shared between frontend and backend.
|
|
3325
|
+
*/
|
|
3326
|
+
declare const DEFAULT_TEMPLATES: Record<string, string>;
|
|
3327
|
+
/**
|
|
3328
|
+
* Resolve a template by key, checking flow-level overrides, then user overrides,
|
|
3329
|
+
* then the system defaults.
|
|
3330
|
+
*/
|
|
3331
|
+
declare function resolveTemplate(key: string, userTemplates?: Record<string, string>, flowTemplates?: Record<string, string>): string;
|
|
3332
|
+
/**
|
|
3333
|
+
* Replace `{varName}` placeholders in a template string with values from vars.
|
|
3334
|
+
*/
|
|
3335
|
+
declare function applyTemplate(template: string, vars: Record<string, string>): string;
|
|
3336
|
+
|
|
3337
|
+
/**
|
|
3338
|
+
* Per-provider prompting doctrine — the single source of truth for "how to
|
|
3339
|
+
* prompt model family X well". Consumed by:
|
|
3340
|
+
* 1. backend/src/prompts/prompt-wizard-system.ts (enhance/generate system prompts)
|
|
3341
|
+
* 2. backend/scripts/gen-skills (provider-prompting block in video node skills)
|
|
3342
|
+
* 3. backend/src/lib/mcp/tools/models.ts (list_models promptTips)
|
|
3343
|
+
* 4. compact recipes in MCP tool descriptions point here via get_node_skill
|
|
3344
|
+
*
|
|
3345
|
+
* Sources, in precedence order (conflicts resolve top-down):
|
|
3346
|
+
* - Official BytePlus ModelArk "Dreamina Seedance 2.0 series prompt guide"
|
|
3347
|
+
* https://docs.byteplus.com/en/docs/ModelArk/2222480
|
|
3348
|
+
* - Official launch post https://seed.bytedance.com/en/blog/official-launch-of-seedance-2-0
|
|
3349
|
+
* - KIE API docs https://docs.kie.ai/market/bytedance/seedance-2
|
|
3350
|
+
*/
|
|
3351
|
+
interface ProviderPromptDoctrine {
|
|
3352
|
+
/** MODEL_CATALOG ids this doctrine covers. */
|
|
3353
|
+
readonly providers: readonly string[];
|
|
3354
|
+
/** Human heading for skill docs, e.g. "Seedance 2.0 (seedance-2, seedance-2-fast)". */
|
|
3355
|
+
readonly heading: string;
|
|
3356
|
+
/** Short bullets for compact surfaces (list_models promptTips). ≤220 chars each. */
|
|
3357
|
+
readonly tips: readonly string[];
|
|
3358
|
+
/** Full markdown doctrine for system prompts and generated skill docs. */
|
|
3359
|
+
readonly doctrine: string;
|
|
3360
|
+
}
|
|
3361
|
+
declare const PROVIDER_PROMPT_DOCTRINES: readonly ProviderPromptDoctrine[];
|
|
3362
|
+
/** Full doctrine for a provider id, or undefined when none exists. */
|
|
3363
|
+
declare function getPromptDoctrine(providerId: string): ProviderPromptDoctrine | undefined;
|
|
3364
|
+
/** Compact tips for a provider id ([] when none) — used by list_models. */
|
|
3365
|
+
declare function getPromptTips(providerId: string): readonly string[];
|
|
3366
|
+
|
|
3367
|
+
/**
|
|
3368
|
+
* Prompt Wizard — shared types, category definitions, and provider capabilities.
|
|
3369
|
+
*
|
|
3370
|
+
* Used by the backend (system prompt building) and frontend (type-checking, UI).
|
|
3371
|
+
*/
|
|
3372
|
+
interface WizardCategory {
|
|
3373
|
+
readonly key: string;
|
|
3374
|
+
readonly label: string;
|
|
3375
|
+
readonly optional?: boolean;
|
|
3376
|
+
}
|
|
3377
|
+
interface WizardQuestion {
|
|
3378
|
+
category: string;
|
|
3379
|
+
label: string;
|
|
3380
|
+
options: WizardOption[];
|
|
3381
|
+
selected: string | string[] | null;
|
|
3382
|
+
allowCustom: boolean;
|
|
3383
|
+
multi?: boolean;
|
|
3384
|
+
}
|
|
3385
|
+
interface WizardOption {
|
|
3386
|
+
value: string;
|
|
3387
|
+
label: string;
|
|
3388
|
+
description?: string;
|
|
3389
|
+
}
|
|
3390
|
+
interface WizardSelection {
|
|
3391
|
+
category: string;
|
|
3392
|
+
value: string;
|
|
3393
|
+
isCustom: boolean;
|
|
3394
|
+
}
|
|
3395
|
+
interface RecommendedModel {
|
|
3396
|
+
provider: string;
|
|
3397
|
+
field: string;
|
|
3398
|
+
label: string;
|
|
3399
|
+
reason: string;
|
|
3400
|
+
}
|
|
3401
|
+
interface WizardNodeContext {
|
|
3402
|
+
connectedInputTypes?: string[];
|
|
3403
|
+
referenceImageCount?: number;
|
|
3404
|
+
referenceImageUrls?: string[];
|
|
3405
|
+
hasSourceVideo?: boolean;
|
|
3406
|
+
}
|
|
3407
|
+
interface ModelChange {
|
|
3408
|
+
field: string;
|
|
3409
|
+
value: string;
|
|
3410
|
+
}
|
|
3411
|
+
declare const IMAGE_WIZARD_CATEGORIES: readonly WizardCategory[];
|
|
3412
|
+
declare const VIDEO_WIZARD_CATEGORIES: readonly WizardCategory[];
|
|
3413
|
+
declare const MUSIC_WIZARD_CATEGORIES: readonly WizardCategory[];
|
|
3414
|
+
declare const AUDIO_WIZARD_CATEGORIES: readonly WizardCategory[];
|
|
3415
|
+
declare const TEXT_WIZARD_CATEGORIES: readonly WizardCategory[];
|
|
3416
|
+
declare const LLM_CHAT_WIZARD_CATEGORIES: readonly WizardCategory[];
|
|
3417
|
+
declare function getCategoriesForNodeType(nodeType: string): readonly WizardCategory[] | undefined;
|
|
3418
|
+
/** Node types that support the wizard (excludes edit-image, text-to-speech, lip-sync) */
|
|
3419
|
+
declare function isWizardSupported(nodeType: string): boolean;
|
|
3420
|
+
declare const PROVIDER_CAPABILITIES: Record<string, Record<string, string>>;
|
|
3421
|
+
/** Reference image role options (for multi-select) */
|
|
3422
|
+
declare const REFERENCE_IMAGE_ROLES: readonly WizardOption[];
|
|
3423
|
+
|
|
3424
|
+
interface ResolvePromptArgs {
|
|
3425
|
+
override?: string;
|
|
3426
|
+
typed?: ReadonlyArray<string | undefined>;
|
|
3427
|
+
wired?: string;
|
|
3428
|
+
refMap: ReadonlyMap<string, string>;
|
|
3429
|
+
/** Opt-in (generate-image / generate-video only): APPEND the wired
|
|
3430
|
+
* (connected-prompt) value to the TYPED base instead of treating wired as a
|
|
3431
|
+
* fallback, so a connected prompt auto-injects alongside the typed prompt. An
|
|
3432
|
+
* `override` (list fan-out item) still fully replaces — no wired append.
|
|
3433
|
+
* Off/undefined = exact legacy precedence (override > typed > wired) for every
|
|
3434
|
+
* other node type. */
|
|
3435
|
+
appendWired?: boolean;
|
|
3436
|
+
}
|
|
3437
|
+
/** SINGLE SOURCE OF TRUTH for prompt precedence across both DAG engines:
|
|
3438
|
+
* override (list fan-out) > first present typed candidate > wired > "".
|
|
3439
|
+
* "present" = non-empty after trim. {Label} refs are resolved on the chosen
|
|
3440
|
+
* branch via the shared resolveNodeRefs. With `appendWired`, the chosen base
|
|
3441
|
+
* AND the wired value are both emitted (joined ". "). */
|
|
3442
|
+
declare function resolvePrompt({ override, typed, wired, refMap, appendWired }: ResolvePromptArgs): string;
|
|
3443
|
+
/** Compose a final NEGATIVE prompt from a TYPED base + a WIRED (connected
|
|
3444
|
+
* negative-handle) value: both are emitted, joined ". " (mirrors `appendWired`
|
|
3445
|
+
* for the positive prompt). Pure join — the caller resolves `{label}` refs on
|
|
3446
|
+
* the typed value first, and the wired value is already a resolved output that
|
|
3447
|
+
* the input-resolver has filtered (referenced / Inject-Negative-off dropped).
|
|
3448
|
+
* Generate-image / generate-video only; empty parts are dropped. */
|
|
3449
|
+
declare function composeNegative(typed?: string, wired?: string): string;
|
|
3450
|
+
/** Ordered typed-candidate fields per node type — the precedence source of
|
|
3451
|
+
* truth (NOT NODE_MAPPABLE_FIELDS, which is field-mapping eligibility, omits
|
|
3452
|
+
* video-retake, and orders llm-chat wrong). */
|
|
3453
|
+
declare const NODE_PROMPT_CANDIDATE_FIELDS: Readonly<Record<string, readonly string[]>>;
|
|
3454
|
+
interface ComputeNodePromptArgs {
|
|
3455
|
+
override?: string;
|
|
3456
|
+
wired?: string;
|
|
3457
|
+
refMap: ReadonlyMap<string, string>;
|
|
3458
|
+
/** See ResolvePromptArgs.appendWired — generate-image / generate-video only. */
|
|
3459
|
+
appendWired?: boolean;
|
|
3460
|
+
}
|
|
3461
|
+
/** Resolve a single-prompt node's final prompt (typed-primary). Both engines
|
|
3462
|
+
* call this so field-selection + precedence are structurally identical. */
|
|
3463
|
+
declare function computeNodePrompt(nodeType: string, data: Record<string, unknown>, { override, wired, refMap, appendWired }: ComputeNodePromptArgs): string;
|
|
3464
|
+
interface LlmChatFieldArgs {
|
|
3465
|
+
override?: string;
|
|
3466
|
+
wiredUserInput?: string;
|
|
3467
|
+
wiredSystemPrompt?: string;
|
|
3468
|
+
refMap: ReadonlyMap<string, string>;
|
|
3469
|
+
}
|
|
3470
|
+
/** llm-chat resolves TWO independent fields. override applies to userInput only. */
|
|
3471
|
+
declare function computeLlmChatFields(data: Record<string, unknown>, { override, wiredUserInput, wiredSystemPrompt, refMap }: LlmChatFieldArgs): {
|
|
3472
|
+
userInput: string;
|
|
3473
|
+
systemPrompt: string;
|
|
3474
|
+
};
|
|
3475
|
+
|
|
3476
|
+
interface FactoryPreset {
|
|
3477
|
+
/** Stable slug "<nodeType>/<kebab-name>" — used as a React key and in exports. */
|
|
3478
|
+
readonly id: string;
|
|
3479
|
+
readonly name: string;
|
|
3480
|
+
readonly description?: string;
|
|
3481
|
+
/** Optional folder/section label this preset is grouped under in the picker.
|
|
3482
|
+
* Presets sharing a `group` render together; "variants of one idea" (e.g. the
|
|
3483
|
+
* character-sheet family) are simply siblings in the same group. */
|
|
3484
|
+
readonly group?: string;
|
|
3485
|
+
/** How the group renders: a collapsible "folder" (default) or a flat "section"
|
|
3486
|
+
* label. Taken from the first preset that opens the group. */
|
|
3487
|
+
readonly groupKind?: "folder" | "section";
|
|
3488
|
+
/** Capture-shaped config (no label / fieldMappings / runtime keys). */
|
|
3489
|
+
readonly data: Readonly<Record<string, unknown>>;
|
|
3490
|
+
}
|
|
3491
|
+
/** A render-ready bucket of factory presets sharing one `group` (or the leading
|
|
3492
|
+
* ungrouped bucket, `group: null`). Produced by {@link groupFactoryPresets}. */
|
|
3493
|
+
interface FactoryPresetGroup<T> {
|
|
3494
|
+
/** Stable key for React + collapse state ("__root__" for the ungrouped bucket). */
|
|
3495
|
+
readonly key: string;
|
|
3496
|
+
/** Group label, or null for the ungrouped bucket. */
|
|
3497
|
+
readonly group: string | null;
|
|
3498
|
+
readonly groupKind: "folder" | "section";
|
|
3499
|
+
readonly presets: T[];
|
|
3500
|
+
}
|
|
3501
|
+
/**
|
|
3502
|
+
* Bucket an ordered list of presets by their `group` field for rendering. Groups
|
|
3503
|
+
* appear in first-appearance order; presets keep their array order within a
|
|
3504
|
+
* group; ungrouped presets collect into a single leading `null` bucket. Pure and
|
|
3505
|
+
* UI-agnostic (operates on anything carrying `group`/`groupKind`) so the config
|
|
3506
|
+
* panel dropdown reuses it and it stays unit-testable.
|
|
3507
|
+
*/
|
|
3508
|
+
declare function groupFactoryPresets<T extends {
|
|
3509
|
+
group?: string;
|
|
3510
|
+
groupKind?: "folder" | "section";
|
|
3511
|
+
}>(presets: readonly T[]): FactoryPresetGroup<T>[];
|
|
3512
|
+
|
|
3513
|
+
/** System/factory presets shipped with the app. Assembled here in the original
|
|
3514
|
+
* single-file key order; each value lives in its per-domain module. */
|
|
3515
|
+
declare const FACTORY_PRESETS: Readonly<Record<string, readonly FactoryPreset[]>>;
|
|
3516
|
+
declare function getFactoryPresets(nodeType: string): readonly FactoryPreset[];
|
|
3517
|
+
|
|
3518
|
+
/**
|
|
3519
|
+
* Style Gallery presets (north-star §6 ①).
|
|
3520
|
+
*
|
|
3521
|
+
* Each preset is a named "look" the user picks at Start. Picking one sets the
|
|
3522
|
+
* pipeline's `style_directives`, which the Showrunner folds into the plan's
|
|
3523
|
+
* `global_style` — and from there it propagates into every entity reference
|
|
3524
|
+
* sheet, scene keyframe, and shot prompt, plus the image/location critics. So
|
|
3525
|
+
* the whole film stays visually consistent in the chosen style.
|
|
3526
|
+
*
|
|
3527
|
+
* The catalog is intentionally style/genre-agnostic (not just "cinematic"):
|
|
3528
|
+
* films, explainers, animated ads, kids' content, education. A per-shot style
|
|
3529
|
+
* override lives in the Focus composer (follow-up).
|
|
3530
|
+
*
|
|
3531
|
+
* `swatch` is a CSS gradient used as a lightweight thumbnail until real sample
|
|
3532
|
+
* images ship — it gives each look a recognizable visual without bundling
|
|
3533
|
+
* assets.
|
|
3534
|
+
*/
|
|
3535
|
+
interface StylePreset {
|
|
3536
|
+
/** Stable id stored on the pipeline (do not rename — breaks recall). */
|
|
3537
|
+
id: string;
|
|
3538
|
+
label: string;
|
|
3539
|
+
/** One-line description shown under the label. */
|
|
3540
|
+
description: string;
|
|
3541
|
+
/** CSS `background` value for the card's thumbnail swatch. */
|
|
3542
|
+
swatch: string;
|
|
3543
|
+
/** Conditioning fed to the Showrunner → plan.global_style → all generation. */
|
|
3544
|
+
directives: StyleDirectives;
|
|
3545
|
+
}
|
|
3546
|
+
declare const STYLE_PRESETS: readonly StylePreset[];
|
|
3547
|
+
/** Resolve a preset by id. Returns undefined for the "Auto" / unknown case. */
|
|
3548
|
+
declare function getStylePreset(id: string | undefined): StylePreset | undefined;
|
|
3549
|
+
|
|
3550
|
+
/** Angle preset → prompt fragment (slotted into "<name>, <fragment>. <base>"). */
|
|
3551
|
+
declare const OBJECT_ANGLE_PROMPTS: Record<string, string>;
|
|
3552
|
+
/** Material preset → prompt fragment. */
|
|
3553
|
+
declare const OBJECT_MATERIAL_PROMPTS: Record<string, string>;
|
|
3554
|
+
/** Variation preset → prompt fragment. */
|
|
3555
|
+
declare const OBJECT_VARIATION_PROMPTS: Record<string, string>;
|
|
3556
|
+
declare const OBJECT_ANGLE_PRESETS: readonly string[];
|
|
3557
|
+
declare const OBJECT_MATERIAL_PRESETS: readonly string[];
|
|
3558
|
+
declare const OBJECT_VARIATION_PRESETS: readonly string[];
|
|
3559
|
+
type ObjectPresetAssetType = "angles" | "materials" | "variations";
|
|
3560
|
+
/** Preset key lists per asset type — backend VARIANTS validation reads this. */
|
|
3561
|
+
declare const OBJECT_ASSET_PRESETS: Record<ObjectPresetAssetType, readonly string[]>;
|
|
3562
|
+
/** Prompt-fragment maps per asset type — backend buildVariantPrompt reads this. */
|
|
3563
|
+
declare const OBJECT_ASSET_PROMPTS: Record<ObjectPresetAssetType, Record<string, string>>;
|
|
3564
|
+
|
|
3565
|
+
/** Which prompt field a snippet belongs to. Negative-target snippets only
|
|
3566
|
+
* surface in negative-prompt fields, and are bare comma lists by convention
|
|
3567
|
+
* (per Google's Veo guidance, a negative FIELD must name the unwanted thing,
|
|
3568
|
+
* never "no X"). */
|
|
3569
|
+
type SnippetTarget = "prompt" | "negative";
|
|
3570
|
+
/** Node modality a snippet applies to. A node declares its modality once in
|
|
3571
|
+
* the frontend's NODE_PROMPT_FIELDS; the menu shows snippets whose `media`
|
|
3572
|
+
* contains it. */
|
|
3573
|
+
type SnippetMedia = "image" | "video" | "audio" | "text";
|
|
3574
|
+
declare const SNIPPET_MEDIA_VALUES: readonly SnippetMedia[];
|
|
3575
|
+
interface FactorySnippet {
|
|
3576
|
+
/** Stable kebab slug, e.g. "identity-lock". Unique across the catalog. */
|
|
3577
|
+
readonly id: string;
|
|
3578
|
+
readonly name: string;
|
|
3579
|
+
/** One-liner shown in the menu and matched by search. */
|
|
3580
|
+
readonly description?: string;
|
|
3581
|
+
/** The exact fragment inserted into the prompt. Single line; never contains
|
|
3582
|
+
* `{`, `}`, or `@` (guard-tested) so it can never form a mention/variable
|
|
3583
|
+
* token in the editor. */
|
|
3584
|
+
readonly text: string;
|
|
3585
|
+
readonly target: SnippetTarget;
|
|
3586
|
+
readonly media: readonly SnippetMedia[];
|
|
3587
|
+
/** Menu group AND the pill-swap sibling pool (swap lists same-category). */
|
|
3588
|
+
readonly category: string;
|
|
3589
|
+
}
|
|
3590
|
+
|
|
3591
|
+
/** Factory snippet catalog (v1: image + video; audio/text follow later).
|
|
3592
|
+
* Order within a category = menu order = pill quick-cycle order. */
|
|
3593
|
+
|
|
3594
|
+
declare const FACTORY_SNIPPETS: readonly FactorySnippet[];
|
|
3595
|
+
|
|
3596
|
+
/** Factory snippets for one field: target match + media membership. */
|
|
3597
|
+
declare function getFactorySnippets(target: SnippetTarget, media: SnippetMedia): readonly FactorySnippet[];
|
|
3598
|
+
|
|
3599
|
+
export { ACTION_FX, ACTION_FX_CATEGORY_LABELS, ACTION_FX_CATEGORY_ORDER, ACTION_FX_IDS, AESTHETICS, AESTHETIC_CATEGORY_LABELS, AESTHETIC_CATEGORY_ORDER, AESTHETIC_IDS, ANALYZABLE_PICKER_TYPES, ANGLE_LABELS, ASPECT_RATIO_LABELS, ATMOSPHERES, ATMOSPHERE_IDS, AUDIO_WIZARD_CATEGORIES, type ActionFx, type ActionFxCategory, type Aesthetic, type AestheticCategory, type AssembleImageInput, type AssembleSunoInput, type AssembleSunoResult, type Atmosphere, BACKDROPS, BACKDROP_CATEGORY_LABELS, BACKDROP_CATEGORY_ORDER, BACKDROP_IDS, BRAND_PRESETS, BRAND_PRESET_IDS, BRAND_PRESET_META, type Backdrop, type BackdropCategory, type BrandCasing, type BrandFonts, type BrandLogo, type BrandPalette, type BrandPresetId, type BrandPresetMeta, type BrandTokens, type BrandTypeSpec, type BuildImagePromptConfig, type BuildImagePromptResult, type BuildImagePromptSegmentsResult, CAMERA_FORMATS, CAMERA_FORMAT_IDS, CAMERA_MOTIONS, CAMERA_MOTION_CATEGORY_LABELS, CAMERA_MOTION_CATEGORY_ORDER, CAMERA_MOTION_IDS, CHARACTER_FX, CHARACTER_FX_CATEGORY_LABELS, CHARACTER_FX_CATEGORY_ORDER, CHARACTER_FX_IDS, COLOR_LOOKS, COLOR_LOOK_CATEGORY_LABELS, COLOR_LOOK_CATEGORY_ORDER, COLOR_LOOK_IDS, COMPOSITION_EFFECTS, COMPOSITION_EFFECT_IDS, type CameraFormat, type CameraMotion, type CameraMotionCategory, type CategorizedInstrument, type CharacterFx, type CharacterFxCategory, type CharacterFxDuration, type CharacterFxIntensity, type CharacterFxPosition, type CharacterFxTiming, type CharacterMeta, type CharacterMotionPromptInput, type CharacterPromptInput, type ColorLook, type ColorLookCategory, type CompositionEffect, type ComputeNodePromptArgs, type CreaturePromptInput, DEFAULT_IDENTITY_LOCK, DEFAULT_TEMPLATES, type DirectionFields, ERAS, ERA_CATEGORY_LABELS, ERA_CATEGORY_ORDER, ERA_IDS, EXPOSURE_CATEGORY_LABELS, EXPOSURE_CATEGORY_ORDER, EXPOSURE_FIELD_BY_CATEGORY, EXPOSURE_IDS, EXPOSURE_SETTINGS, type Era, type EraCategory, type ExposureCategory, type ExposureSettings, type ExposureValue, FACTORY_PRESETS, FACTORY_SNIPPETS, FRAMINGS, FRAMING_CATEGORY_LABELS, FRAMING_CATEGORY_ORDER, FRAMING_FIELD_BY_CATEGORY, FRAMING_IDS, type FacePromptInput, type FactoryPreset, type FactoryPresetGroup, type FactorySnippet, type Framing, type FramingCategory, type FramingValue, GAPS_SCHEMA, HELD_PROPS, HELD_PROP_CATEGORY_LABELS, HELD_PROP_CATEGORY_ORDER, HELD_PROP_IDS, type HeldProp, type HeldPropCategory, IMAGE_WIZARD_CATEGORIES, INSTRUMENTATION_DEFAULT_DATA, INSTRUMENTS, INSTRUMENT_CATEGORY_LABELS, INSTRUMENT_CATEGORY_ORDER, type IdentityLockMode, type InstrumentCategory, type InstrumentationEntry, LENSES, LENS_IDS, LIGHTINGS, LIGHTING_CATEGORY_LABELS, LIGHTING_CATEGORY_ORDER, LIGHTING_FIELD_BY_CATEGORY, LIGHTING_IDS, LLM_CHAT_WIZARD_CATEGORIES, LOOP_SUBJECTS, LOOP_SUBJECT_CATEGORY_LABELS, LOOP_SUBJECT_CATEGORY_ORDER, type Lens, type Lighting, type LightingCategory, type LightingValue, type LlmChatFieldArgs, type LocationMotionPromptInput, type LocationPromptInput, type LocationRefinePromptInput, type LoopSubject, type LoopSubjectCategory, MATERIALS, MATERIAL_CATEGORY_LABELS, MATERIAL_CATEGORY_ORDER, MATERIAL_IDS, MAX_SELECTED_BY_DIMENSION, MAX_SELECTED_BY_FRAMING_CATEGORY, MAX_SELECTED_BY_STYLING_DIMENSION, MOODS, MOOD_CATEGORY_LABELS, MOOD_CATEGORY_ORDER, MOOD_IDS, MOVEMENT_LABELS, MUSIC_EMOTIONS, MUSIC_ENERGIES, MUSIC_ERAS, MUSIC_GENRES, MUSIC_GENRE_CATEGORY_LABELS, MUSIC_GENRE_CATEGORY_ORDER, MUSIC_GENRE_DEFAULT_DATA, MUSIC_MOOD_DEFAULT_DATA, MUSIC_VIBES, MUSIC_WIZARD_CATEGORIES, type Material, type MaterialCategory, type ModelChange, type Mood, type MoodCategory, type MoodValue, type MultiPickerAnalyzerSpec, type MusicEra, type MusicGenre, type MusicGenreCategory, type MusicMoodEntry, type MusicSubgenre, NODE_PROMPT_CANDIDATE_FIELDS, OBJECT_ANGLE_PRESETS, OBJECT_ANGLE_PROMPTS, OBJECT_ASSET_PRESETS, OBJECT_ASSET_PROMPTS, OBJECT_MATERIAL_PRESETS, OBJECT_MATERIAL_PROMPTS, OBJECT_VARIATION_PRESETS, OBJECT_VARIATION_PROMPTS, type ObjectMotionPromptInput, type ObjectPresetAssetType, type ObjectPromptInput, PEOPLE, PERSON_DIMENSION_LABELS, PERSON_DIMENSION_ORDER, PERSON_DIMENSION_SECTIONS, PERSON_FIELD_BY_DIMENSION, PERSON_IDS, PHOTOGRAPHERS, PHOTOGRAPHER_CATEGORY_LABELS, PHOTOGRAPHER_CATEGORY_ORDER, PHOTOGRAPHER_IDS, PHOTO_GENRES, PHOTO_GENRE_CATEGORY_LABELS, PHOTO_GENRE_CATEGORY_ORDER, PHOTO_GENRE_IDS, PICKER_ANALYZER_REGISTRY, PICKER_CATALOGS, PICKER_TYPES, POSES, POSE_CATEGORY_LABELS, POSE_CATEGORY_ORDER, POSE_IDS, POST_PROCESS_EFFECTS, POST_PROCESS_EFFECT_IDS, PRODUCTION_STYLES, PROVIDER_CAPABILITIES, PROVIDER_PROMPT_DOCTRINES, type Person, type PersonDimension, type PersonDimensionSection, type PersonValue, type PhotoGenre, type PhotoGenreCategory, type Photographer, type PhotographerCategory, type PickerAnalyzer, type PickerAnalyzerDescriptor, type PickerAnalyzerSpec, type PickerApplyMode, type PickerCatalog, type PickerCatalogDetail, type PickerCatalogSummary, type PickerDimension, type PickerDimensionSpec, type PickerGaps, type PickerOption, type PickerType, type Pose, type PoseCategory, type PoseValue, type PostProcessEffect, type ProjectPickerCatalogOptions, type ProjectedPickerCatalog, type ProjectedPickerDimension, type ProjectedPickerOption, type PromptSegment, type PromptSegmentOrigin, type ProviderPromptDoctrine, REFERENCE_IMAGE_ROLES, REF_BINDING, RENDER_QUALITIES, RENDER_QUALITY_IDS, type RecommendedModel, type ReferenceCounts, type RenderQuality, type ResolveCharacterMentionsResult, type ResolveLocationMentionsResult, type ResolvePromptArgs, type ResolveVideoReferenceCoreArgs, SCENE_PROMPT_MAX_LENGTH, SETTINGS, SETTING_CATEGORY_LABELS, SETTING_IDS, SHOT_LABELS, SINGING_STYLES, SNIPPET_MEDIA_VALUES, STYLES, STYLE_IDS, STYLE_PRESETS, STYLINGS, STYLING_DIMENSION_LABELS, STYLING_DIMENSION_ORDER, STYLING_FIELD_BY_DIMENSION, STYLING_IDS, type Seedance2InputsArgs, type Seedance2InputsResult, type Seedance2Mode, type Setting, type SettingCategory, type SnippetMedia, type SnippetTarget, type SoundComposition, type SoundCompositionFields, type SoundConsumerType, type StructuredPromptFields, type Style, type StylePreset, type Styling, type StylingDimension, type StylingValue, TEMPORALS, TEMPORAL_CATEGORY_LABELS, TEMPORAL_CATEGORY_ORDER, TEMPORAL_FIELD_BY_CATEGORY, TEMPORAL_IDS, TEXT_WIZARD_CATEGORIES, TRANSITIONS, TRANSITION_CATEGORY_LABELS, TRANSITION_CATEGORY_ORDER, TRANSITION_IDS, type Temporal, type TemporalCategory, type TemporalValue, type Transition, type TransitionCategory, type TransitionDuration, type TransitionIntensity, type TransitionPosition, type TransitionTiming, VIDEO_WIZARD_CATEGORIES, VOCAL_PRESENCE, VOCAL_PRESENCE_INSTRUMENTAL_ID, VOICE_ACCENTS, VOICE_AGES, VOICE_ARCHETYPES, VOICE_CHARACTER_DEFAULT_DATA, VOICE_DELIVERY_DEFAULT_DATA, VOICE_EMOTIONS, VOICE_GENDERS, VOICE_LANGUAGES, VOICE_PACES, VOICE_TIMBRES, type VideoExtraRef, type VoiceCharacterEntry, type VoiceDeliveryEntry, WARDROBE, WARDROBE_CATEGORY_LABELS, WARDROBE_DIMENSION_ORDER, WARDROBE_FIELD_BY_DIMENSION, type WardrobeDimension, type WardrobeEntry, type WardrobeValue, type WizardCategory, type WizardNodeContext, type WizardOption, type WizardQuestion, type WizardSelection, appendField, appendMusicMeta, applyPickerJson, applyReferenceOrderToVideo, applyTemplate, assembleImageInput, assembleSunoInput, buildActionFxHints, buildAestheticHints, buildAgeHint, buildAtmosphereHints, buildCharacterPrompt, buildCreaturePrompt, buildExposureHints, buildFaceTemplateInputs, buildFramingHints, buildHeldPropHints, buildIdentityDirectives, buildIdentityLockLine, buildImagePrompt, buildImagePromptSegments, buildInstrumentationHints, buildLightingHints, buildLocationMotionPrompt, buildLocationPrompt, buildLocationRefinePrompt, buildMaterialHints, buildMoodHints, buildMotionPrompt, buildMultiPickerAnalyzerSpec, buildMusicGenreHints, buildMusicMoodHints, buildObjectMotionPrompt, buildObjectPrompt, buildPersonHints, buildPhotographerHints, buildPickerAnalyzerSpec, buildPickerLegend, buildPickerZodSchema, buildPoseHints, buildPostProcessHints, buildReferenceBlocks, buildScenePrompt, buildStylingHints, buildTemporalHints, buildVoiceCharacterHints, buildVoiceDeliveryHints, buildWardrobeHints, characterLockToRefLock, collectIdentityLockClause, composeCameraMotionHintFromConnections, composeCharacterFxHintFromConnections, composeNegative, composeSoundHintFromConnections, composeTransitionHintFromConnections, computeLlmChatFields, computeNodePrompt, expandImagePositionRefs, expandImageRefTokens, getActionFx, getActionFxLabel, getActionFxPromptHint, getAesthetic, getAestheticLabel, getAestheticPromptHint, getAtmosphere, getAtmosphereLabel, getAtmospherePromptHint, getBackdrop, getBackdropLabel, getBackdropPromptHint, getCameraFormat, getCameraFormatLabel, getCameraFormatPromptHint, getCameraMotion, getCameraMotionLabel, getCameraMotionPromptHint, getCategoriesForNodeType, getCharacterFx, getCharacterFxLabel, getCharacterFxPromptHint, getColorLook, getColorLookLabel, getColorLookPromptHint, getCompositionEffect, getCompositionEffectLabel, getCompositionEffectPromptHint, getEffectiveSunoCustomMode, getEra, getEraLabel, getEraPromptHint, getExposure, getExposureLabel, getExposurePromptHint, getFactoryPresets, getFactorySnippets, getFraming, getFramingCategoryLimit, getFramingLabel, getFramingPromptHint, getHeldProp, getHeldPropLabel, getHeldPropPromptHint, getIdentityLockClause, getInstrument, getLens, getLensLabel, getLensPromptHint, getLighting, getLightingLabel, getLightingPromptHint, getLoopSubject, getLoopSubjectLabel, getLoopSubjectPromptHint, getMaterial, getMaterialLabel, getMaterialPromptHint, getMood, getMoodLabel, getMoodPromptHint, getMusicEmotion, getMusicEnergy, getMusicEra, getMusicGenre, getMusicGenreLabel, getMusicSubgenre, getMusicVibe, getParameterPromptHint, getPerson, getPersonDimensionLimit, getPersonLabel, getPersonPromptHint, getPhotoGenre, getPhotoGenreLabel, getPhotoGenrePromptHint, getPhotographer, getPhotographerLabel, getPhotographerPromptHint, getPickerAnalyzer, getPickerCatalog, getPose, getPoseLabel, getPosePromptHint, getPostProcessEffect, getPostProcessEffectLabel, getPostProcessEffectPromptHint, getProductionStyle, getPromptDoctrine, getPromptTips, getRenderQuality, getRenderQualityLabel, getRenderQualityPromptHint, getSetting, getSettingLabel, getSettingPromptHint, getSingingStyle, getStyle, getStyleLabel, getStylePreset, getStylePromptHint, getStyling, getStylingDimensionLimit, getStylingLabel, getStylingPromptHint, getTemporal, getTemporalLabel, getTemporalPromptHint, getTransition, getTransitionLabel, getTransitionPromptHint, getVocalPresence, getVoiceAccent, getVoiceAge, getVoiceArchetype, getVoiceEmotion, getVoiceGender, getVoiceLanguage, getVoicePace, getVoiceTimbre, getWardrobeEntriesByDimension, getWardrobeEntry, getWardrobePromptHint, groupFactoryPresets, hasUpstreamCharacter, isAnalyzablePicker, isInstrumentalVocal, isVantageFraming, isWizardSupported, listPickerCatalogs, migratePersonValue, pickerFanoutTargets, projectPickerCatalog, renderStructuredFields, resolveBrandInput, resolveCharacterMentions, resolveLocationMentions, resolvePrompt, resolveReferenceTokens, resolveSeedance2Inputs, resolveTemplate, resolveVideoReferenceCore, summarizePickerCatalogs, toIdentityLockMode, truncateForField, truncateText, withForcedIdentityLock };
|