@sogni-ai/sogni-intelligence-client 3.0.7 → 3.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts/data/promptContracts.d.ts.map +1 -1
- package/dist/contracts/data/promptContracts.js +23 -0
- package/dist/contracts/data/promptContracts.js.map +1 -1
- package/dist/contracts/videoComposition.d.ts.map +1 -1
- package/dist/contracts/videoComposition.js +15 -1
- package/dist/contracts/videoComposition.js.map +1 -1
- package/dist/public-skill-runtime/index.d.ts.map +1 -1
- package/dist/public-skill-runtime/index.js +85 -29
- package/dist/public-skill-runtime/index.js.map +1 -1
- package/dist/tools/definitions/animate-photo/definition.d.ts.map +1 -1
- package/dist/tools/definitions/animate-photo/definition.js +6 -4
- package/dist/tools/definitions/animate-photo/definition.js.map +1 -1
- package/dist/tools/definitions/generate-video/definition.d.ts.map +1 -1
- package/dist/tools/definitions/generate-video/definition.js +3 -1
- package/dist/tools/definitions/generate-video/definition.js.map +1 -1
- package/dist/tools/definitions/sound-to-video/definition.d.ts.map +1 -1
- package/dist/tools/definitions/sound-to-video/definition.js +2 -0
- package/dist/tools/definitions/sound-to-video/definition.js.map +1 -1
- package/dist/tools/definitions/video-to-video/definition.d.ts.map +1 -1
- package/dist/tools/definitions/video-to-video/definition.js +3 -1
- package/dist/tools/definitions/video-to-video/definition.js.map +1 -1
- package/dist/tools/shared/seedancePolicyErrors.d.ts +14 -1
- package/dist/tools/shared/seedancePolicyErrors.d.ts.map +1 -1
- package/dist/tools/shared/seedancePolicyErrors.js +35 -2
- package/dist/tools/shared/seedancePolicyErrors.js.map +1 -1
- package/dist-esm/contracts/data/promptContracts.js +23 -0
- package/dist-esm/contracts/data/promptContracts.js.map +1 -1
- package/dist-esm/contracts/videoComposition.js +15 -1
- package/dist-esm/contracts/videoComposition.js.map +1 -1
- package/dist-esm/public-skill-runtime/index.js +85 -29
- package/dist-esm/public-skill-runtime/index.js.map +1 -1
- package/dist-esm/tools/definitions/animate-photo/definition.js +6 -4
- package/dist-esm/tools/definitions/animate-photo/definition.js.map +1 -1
- package/dist-esm/tools/definitions/generate-video/definition.js +3 -1
- package/dist-esm/tools/definitions/generate-video/definition.js.map +1 -1
- package/dist-esm/tools/definitions/sound-to-video/definition.js +2 -0
- package/dist-esm/tools/definitions/sound-to-video/definition.js.map +1 -1
- package/dist-esm/tools/definitions/video-to-video/definition.js +3 -1
- package/dist-esm/tools/definitions/video-to-video/definition.js.map +1 -1
- package/dist-esm/tools/shared/seedancePolicyErrors.js +34 -1
- package/dist-esm/tools/shared/seedancePolicyErrors.js.map +1 -1
- package/package.json +1 -1
|
@@ -2919,17 +2919,20 @@ function inferExplicitStoryboardTargetVideoAspectRatio(text) {
|
|
|
2919
2919
|
}
|
|
2920
2920
|
return null;
|
|
2921
2921
|
}
|
|
2922
|
-
function
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2922
|
+
function inferStoryboardTargetVideoAspect(text, boardAspectRatio, explicitTargetVideoAspectRatio = inferExplicitStoryboardTargetVideoAspectRatio(text)) {
|
|
2923
|
+
if (explicitTargetVideoAspectRatio) {
|
|
2924
|
+
return { aspectRatio: explicitTargetVideoAspectRatio, source: 'explicit_ratio' };
|
|
2925
|
+
}
|
|
2926
2926
|
if (/\b(?:portrait|vertical|9\s*:\s*16)\b/i.test(text) || textMentionsPortraitSocialFormat(text)) {
|
|
2927
|
-
return '9:16';
|
|
2927
|
+
return { aspectRatio: '9:16', source: 'orientation_cue' };
|
|
2928
2928
|
}
|
|
2929
2929
|
if (/\b(?:landscape|horizontal|widescreen|16\s*:\s*9|youtube)\b/i.test(text)) {
|
|
2930
|
-
return '16:9';
|
|
2930
|
+
return { aspectRatio: '16:9', source: 'orientation_cue' };
|
|
2931
2931
|
}
|
|
2932
|
-
return boardAspectRatio;
|
|
2932
|
+
return { aspectRatio: boardAspectRatio, source: 'board_fallback' };
|
|
2933
|
+
}
|
|
2934
|
+
function inferStoryboardTargetVideoAspectRatio(text, boardAspectRatio) {
|
|
2935
|
+
return inferStoryboardTargetVideoAspect(text, boardAspectRatio).aspectRatio;
|
|
2933
2936
|
}
|
|
2934
2937
|
function inferStoryboardCellAspectRatio(text, targetVideoAspectRatio) {
|
|
2935
2938
|
const explicitCell = inferStoryboardAspectNearUnit(text, String.raw `cell|cells|frame|frames|panel|panels|still|stills|thumbnail|thumbnails|shot|shots`, /\b(?:board|canvas|image|poster|sheet|layout|story\s*board|storyboard|output|format)\b/i);
|
|
@@ -3159,7 +3162,7 @@ function normalizeStoryboardBoardDimensions(value) {
|
|
|
3159
3162
|
function storyboardPlanningSourceFromContract(contract) {
|
|
3160
3163
|
return contract?.layout?.source ?? contract?.source ?? 'fallback_text';
|
|
3161
3164
|
}
|
|
3162
|
-
function applyStoryboardPlanningLayoutContract(fallback, contract, frameCount, userDefinedCanvas) {
|
|
3165
|
+
function applyStoryboardPlanningLayoutContract(fallback, contract, frameCount, userDefinedCanvas, userDefinedTargetVideoAspect) {
|
|
3163
3166
|
const layoutContract = contract?.layout;
|
|
3164
3167
|
if (!layoutContract)
|
|
3165
3168
|
return fallback;
|
|
@@ -3173,11 +3176,14 @@ function applyStoryboardPlanningLayoutContract(fallback, contract, frameCount, u
|
|
|
3173
3176
|
const boardAspectRatio = contractOwnsCanvas
|
|
3174
3177
|
? normalizeAspectRatio(layoutContract.storyboardCanvasAspectRatio) ?? fallback.boardAspectRatio
|
|
3175
3178
|
: fallback.boardAspectRatio;
|
|
3176
|
-
const
|
|
3177
|
-
|
|
3178
|
-
const
|
|
3179
|
-
?? cellAspectRatio
|
|
3180
|
-
|
|
3179
|
+
const contractOwnsVideoGeometry = !userDefinedTargetVideoAspect
|
|
3180
|
+
|| layoutSource === 'user_schema';
|
|
3181
|
+
const cellAspectRatio = contractOwnsVideoGeometry
|
|
3182
|
+
? normalizeAspectRatio(layoutContract.storyboardCellAspectRatio) ?? fallback.cellAspectRatio
|
|
3183
|
+
: fallback.cellAspectRatio;
|
|
3184
|
+
const targetVideoAspectRatio = contractOwnsVideoGeometry
|
|
3185
|
+
? normalizeAspectRatio(layoutContract.targetVideoAspectRatio) ?? cellAspectRatio ?? fallback.targetVideoAspectRatio
|
|
3186
|
+
: fallback.targetVideoAspectRatio;
|
|
3181
3187
|
const layout = describeStoryboardLayout(boardAspectRatio, cellAspectRatio, frameCount);
|
|
3182
3188
|
const contractBoardDimensions = contractOwnsCanvas
|
|
3183
3189
|
? normalizeStoryboardBoardDimensions(layoutContract.boardDimensions)
|
|
@@ -3227,8 +3233,9 @@ function inferStoryboardLayoutSpec(userIntentText, frameCount, planningContract)
|
|
|
3227
3233
|
const provisionalBoardAspectRatio = userDefinedCanvas
|
|
3228
3234
|
? inferStoryboardBoardAspectRatio(userIntentText)
|
|
3229
3235
|
: '16:9';
|
|
3230
|
-
const
|
|
3231
|
-
|
|
3236
|
+
const inferredTargetVideoAspect = inferStoryboardTargetVideoAspect(userIntentText, provisionalBoardAspectRatio, explicitTargetVideoAspectRatio);
|
|
3237
|
+
const inferredTargetVideoAspectRatio = inferredTargetVideoAspect.aspectRatio;
|
|
3238
|
+
const userDefinedTargetVideoAspect = inferredTargetVideoAspect.source !== 'board_fallback';
|
|
3232
3239
|
const cellAspectRatio = inferStoryboardCellAspectRatio(userIntentText, inferredTargetVideoAspectRatio);
|
|
3233
3240
|
const targetVideoAspectRatio = explicitTargetVideoAspectRatio ?? cellAspectRatio;
|
|
3234
3241
|
const balancedGrid = userDefinedCanvas
|
|
@@ -3247,7 +3254,7 @@ function inferStoryboardLayoutSpec(userIntentText, frameCount, planningContract)
|
|
|
3247
3254
|
? {}
|
|
3248
3255
|
: { boardDimensions: balancedGrid?.boardDimensions ?? exports.GPT_IMAGE_STORYBOARD_DEFAULTS.storyboardLandscape.aspectRatio }),
|
|
3249
3256
|
};
|
|
3250
|
-
return applyStoryboardPlanningLayoutContract(fallback, planningContract, frameCount, userDefinedCanvas);
|
|
3257
|
+
return applyStoryboardPlanningLayoutContract(fallback, planningContract, frameCount, userDefinedCanvas, userDefinedTargetVideoAspect);
|
|
3251
3258
|
}
|
|
3252
3259
|
function clampStoryboardDefaultFrameCount(value) {
|
|
3253
3260
|
return Math.max(exports.STORYBOARD_DEFAULT_MIN_FRAMES, Math.min(exports.STORYBOARD_DEFAULT_MAX_FRAMES, Math.round(value)));
|
|
@@ -4377,8 +4384,42 @@ function storyboardTableRowLooksLikeCountedBeat(cells, headers) {
|
|
|
4377
4384
|
const candidate = compactStoryboardLine(cells[Math.max(0, headerIndex)] || cells[0] || '');
|
|
4378
4385
|
return /^(?:beat|scene|shot|panel|frame)?\s*(?:#\s*)?0?\d{1,2}\b/i.test(candidate);
|
|
4379
4386
|
}
|
|
4387
|
+
function storyboardTableCellLooksLikeCameraCue(cell) {
|
|
4388
|
+
const compact = compactStoryboardLine(cell);
|
|
4389
|
+
return /\b(?:camera|motion|shot|frame|framing|close[-\s]?up|medium|wide|macro|static|locked|hold|push(?:es)?\s+in|pull(?:s)?\s+back|pan|tilt|dolly|truck|tracking|handheld|orbit|zoom|focus|rack\s+focus|focus\s+pull|slow[-\s]?mo|timelapse)\b/i.test(compact);
|
|
4390
|
+
}
|
|
4391
|
+
function storyboardTableCellLooksLikeTransitionCue(cell) {
|
|
4392
|
+
const compact = compactStoryboardLine(cell);
|
|
4393
|
+
return /\b(?:transition|cut|hard\s+cut|smash\s+cut|match\s+cut|jump\s+cut|fade|cross[-\s]?fade|dissolve|wipe|morph|glitch|burst|snap|blend|strobe|whip[-\s]?pan)\b/i.test(compact);
|
|
4394
|
+
}
|
|
4380
4395
|
function normalizeStoryboardTableCellsToHeaders(cells, headers) {
|
|
4381
|
-
if (!headers
|
|
4396
|
+
if (!headers)
|
|
4397
|
+
return cells;
|
|
4398
|
+
if (cells.length === headers.length - 1) {
|
|
4399
|
+
const purposeHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:purpose|story\s*beat|story\s*purpose|beat\s*name|beat\s*title|narrative|name|title)\b/i);
|
|
4400
|
+
const visualHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:visual|frame|shot|image|action)\b/i);
|
|
4401
|
+
const transitionHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:transition|edit|cut|fade|dissolve|wipe)\b/i);
|
|
4402
|
+
const purposeCell = compactStoryboardLine(cells[purposeHeaderIndex] || '');
|
|
4403
|
+
const shiftedCameraCell = cells[visualHeaderIndex] || '';
|
|
4404
|
+
const shiftedTransitionCell = transitionHeaderIndex >= 0
|
|
4405
|
+
? cells[transitionHeaderIndex - 1] || ''
|
|
4406
|
+
: '';
|
|
4407
|
+
const shiftedColumnsLookLikeFoldedPurposeVisual = transitionHeaderIndex >= 0
|
|
4408
|
+
? storyboardTableCellLooksLikeTransitionCue(shiftedTransitionCell)
|
|
4409
|
+
: storyboardTableCellLooksLikeCameraCue(shiftedCameraCell);
|
|
4410
|
+
if (purposeHeaderIndex >= 0
|
|
4411
|
+
&& visualHeaderIndex === purposeHeaderIndex + 1
|
|
4412
|
+
&& visualHeaderIndex < cells.length
|
|
4413
|
+
&& purposeCell.length >= 20
|
|
4414
|
+
&& shiftedColumnsLookLikeFoldedPurposeVisual) {
|
|
4415
|
+
return [
|
|
4416
|
+
...cells.slice(0, visualHeaderIndex),
|
|
4417
|
+
cells[purposeHeaderIndex],
|
|
4418
|
+
...cells.slice(visualHeaderIndex),
|
|
4419
|
+
];
|
|
4420
|
+
}
|
|
4421
|
+
}
|
|
4422
|
+
if (cells.length <= headers.length)
|
|
4382
4423
|
return cells;
|
|
4383
4424
|
const overflow = cells.length - headers.length;
|
|
4384
4425
|
const combinedAudioDialogueIndex = headers.findIndex(header => /\baudio\b/i.test(header)
|
|
@@ -4472,10 +4513,11 @@ function splitStoryboardTableSections(text) {
|
|
|
4472
4513
|
const cameraHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:camera|motion|fx|effect|lighting|style|look)\b/i);
|
|
4473
4514
|
const dialogueHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:dialogue|vo|v\.o\.|voiceover|speech|narration)\b/i);
|
|
4474
4515
|
const soundHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:audio|sfx|sound|foley|music)\b/i);
|
|
4516
|
+
const transitionHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:transition|edit|cut|fade|dissolve|wipe)\b/i);
|
|
4475
4517
|
const visibleTextHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:visible\s+text|on[-\s]?screen\s+text|onscreen\s+text|text|copy|cta|tagline|headline|title\s+card|subtitle|caption)\b/i);
|
|
4476
4518
|
const beatHeaderIndex = headers
|
|
4477
4519
|
? headers.findIndex(header => /\b(?:beat|scene|shot|panel|frame)\b/i.test(header)
|
|
4478
|
-
&& !/\b(?:visual|action|camera|audio|dialogue|vo|sfx)\b/i.test(header))
|
|
4520
|
+
&& !/\b(?:visual|action|camera|audio|dialogue|vo|sfx|transition)\b/i.test(header))
|
|
4479
4521
|
: -1;
|
|
4480
4522
|
const purposeHeaderIndex = headers
|
|
4481
4523
|
? headers.findIndex(header => /\b(?:purpose|story\s*beat|story\s*purpose|beat\s*name|beat\s*title|narrative|name|title)\b/i.test(header)
|
|
@@ -4506,6 +4548,9 @@ function splitStoryboardTableSections(text) {
|
|
|
4506
4548
|
const soundCell = soundHeaderIndex >= 0
|
|
4507
4549
|
? storyboardTableCellWithFieldBreaks(cells[soundHeaderIndex] || '')
|
|
4508
4550
|
: '';
|
|
4551
|
+
const transitionCell = transitionHeaderIndex >= 0
|
|
4552
|
+
? storyboardTableCellWithFieldBreaks(cells[transitionHeaderIndex] || '')
|
|
4553
|
+
: '';
|
|
4509
4554
|
const visibleTextCell = visibleTextHeaderIndex >= 0
|
|
4510
4555
|
? storyboardTableCellWithFieldBreaks(cells[visibleTextHeaderIndex] || '')
|
|
4511
4556
|
: '';
|
|
@@ -4547,6 +4592,8 @@ function splitStoryboardTableSections(text) {
|
|
|
4547
4592
|
|| (visibleTextHeaderIndex >= 0 ? compactStoryboardLine(visibleTextCell) : ''));
|
|
4548
4593
|
const audio = extractStoryboardField(audioCell, ['Audio/SFX', 'Audio', 'SFX', 'FX', 'Foley', 'Sound', 'Sounds'])
|
|
4549
4594
|
|| storyboardTableCellWithoutDialogue(soundCell || audioCell, dialogue);
|
|
4595
|
+
const transition = extractStoryboardField(transitionCell, ['Transition', 'Transition out', 'Transition-out', 'Edit'])
|
|
4596
|
+
|| (transitionHeaderIndex >= 0 ? compactStoryboardLine(transitionCell) : '');
|
|
4550
4597
|
const number = sections.length + 1;
|
|
4551
4598
|
const beatLabel = beatHeaderIndex >= 0 && beatHeaderIndex !== timingCellIndex
|
|
4552
4599
|
? compactStoryboardLine(cells[beatHeaderIndex])
|
|
@@ -4559,6 +4606,7 @@ function splitStoryboardTableSections(text) {
|
|
|
4559
4606
|
&& purposeHeaderIndex !== soundHeaderIndex
|
|
4560
4607
|
&& purposeHeaderIndex !== cameraHeaderIndex
|
|
4561
4608
|
&& purposeHeaderIndex !== visibleTextHeaderIndex
|
|
4609
|
+
&& purposeHeaderIndex !== transitionHeaderIndex
|
|
4562
4610
|
? compactStoryboardLine(cells[purposeHeaderIndex])
|
|
4563
4611
|
: '';
|
|
4564
4612
|
const beatTitleSource = purposeLabel && !/^\d{1,2}$/.test(purposeLabel)
|
|
@@ -4578,6 +4626,7 @@ function splitStoryboardTableSections(text) {
|
|
|
4578
4626
|
dialogue ? `Dialogue/VO: ${dialogue}` : '',
|
|
4579
4627
|
visibleText ? `Visible text: ${visibleText}` : '',
|
|
4580
4628
|
audio ? `Audio/SFX: ${audio}` : '',
|
|
4629
|
+
transition ? `Transition: ${transition}` : '',
|
|
4581
4630
|
].filter(Boolean).join('\n'),
|
|
4582
4631
|
});
|
|
4583
4632
|
}
|
|
@@ -4816,7 +4865,7 @@ function synthesizeStoryboardSectionsFromPlainNarration(sourceText, frameCount,
|
|
|
4816
4865
|
}
|
|
4817
4866
|
function storyboardSectionsHavePreservableExplicitTiming(sections) {
|
|
4818
4867
|
return sections.length > 1
|
|
4819
|
-
&& sections.
|
|
4868
|
+
&& sections.every(section => extractStoryboardTiming(`${section.heading}\n${section.body}`) !== null);
|
|
4820
4869
|
}
|
|
4821
4870
|
function canonicalStoryboardScriptContext(text) {
|
|
4822
4871
|
const trimmed = String(text || '').trim();
|
|
@@ -5333,11 +5382,16 @@ function minimumStoryboardSceneDurationForDialogue(scene, rules, wordsPerSecondM
|
|
|
5333
5382
|
function retimeStoryboardScenesForDialogue(scenes, targetDurationSec, rules = DEFAULT_STORYBOARD_TIMING_RULES) {
|
|
5334
5383
|
if (targetDurationSec === null || scenes.length === 0)
|
|
5335
5384
|
return scenes;
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5385
|
+
const hasCompletePositiveTiming = scenes.every(scene => scene.startSec !== null
|
|
5386
|
+
&& scene.endSec !== null
|
|
5387
|
+
&& scene.durationSec !== null
|
|
5388
|
+
&& scene.durationSec > 0);
|
|
5389
|
+
const sourceDurations = scenes.map(scene => (scene.durationSec !== null && scene.durationSec > 0
|
|
5390
|
+
? scene.durationSec
|
|
5391
|
+
: targetDurationSec / scenes.length));
|
|
5339
5392
|
const minimumDurations = scenes.map(scene => minimumStoryboardSceneDurationForDialogue(scene, rules));
|
|
5340
|
-
const needsRetiming =
|
|
5393
|
+
const needsRetiming = !hasCompletePositiveTiming
|
|
5394
|
+
|| scenes.some((scene, index) => (scene.durationSec ?? 0) + rules.toleranceSec < minimumDurations[index]);
|
|
5341
5395
|
if (!needsRetiming)
|
|
5342
5396
|
return scenes;
|
|
5343
5397
|
let requiredDurations = minimumDurations;
|
|
@@ -5353,9 +5407,8 @@ function retimeStoryboardScenesForDialogue(scenes, targetDurationSec, rules = DE
|
|
|
5353
5407
|
if (minimumTotal > targetDurationSec + rules.toleranceSec)
|
|
5354
5408
|
return scenes;
|
|
5355
5409
|
const extraDuration = Math.max(0, targetDurationSec - minimumTotal);
|
|
5356
|
-
const
|
|
5357
|
-
const
|
|
5358
|
-
const unroundedDurations = requiredDurations.map((minimum, index) => (minimum + (extraDuration * Math.max(0.01, originalDurations[index]) / weightTotal)));
|
|
5410
|
+
const weightTotal = sourceDurations.reduce((sum, duration) => sum + Math.max(0.01, duration), 0);
|
|
5411
|
+
const unroundedDurations = requiredDurations.map((minimum, index) => (minimum + (extraDuration * Math.max(0.01, sourceDurations[index]) / weightTotal)));
|
|
5359
5412
|
const timelineStartSec = scenes[0].startSec ?? 0;
|
|
5360
5413
|
const timelineEndSec = Math.round((timelineStartSec + targetDurationSec) * 100) / 100;
|
|
5361
5414
|
let cursor = timelineStartSec;
|
|
@@ -5456,7 +5509,9 @@ function inferStoryboardStorySpineFromHeading(text) {
|
|
|
5456
5509
|
const collected = [];
|
|
5457
5510
|
for (let cursor = index + 1; cursor < lines.length && collected.length < 4; cursor += 1) {
|
|
5458
5511
|
const candidate = lines[cursor];
|
|
5459
|
-
if (
|
|
5512
|
+
if (/^\|/.test(candidate)
|
|
5513
|
+
|| storyboardMarkdownTableSeparatorLine(candidate)
|
|
5514
|
+
|| /^(?:storyboard|video|production|reference|timecoded|beat\s+\d|scene\s+\d|format|duration|aspect|does this|please confirm)\b/i.test(candidate)) {
|
|
5460
5515
|
break;
|
|
5461
5516
|
}
|
|
5462
5517
|
const cleaned = cleanStoryboardStorySpine(candidate);
|
|
@@ -6745,6 +6800,7 @@ function compileSeedanceStoryboardPromptFromProject(project, options = {}) {
|
|
|
6745
6800
|
: 'All scene numbers, timecodes, labels, and production notes remain metadata only and must not appear in the video.';
|
|
6746
6801
|
const toneProgression = project.creativeBrief.toneProgression.join(' -> ');
|
|
6747
6802
|
const musicArc = project.scenes.map(scene => scene.music).filter(Boolean).join(' -> ');
|
|
6803
|
+
const visualStyle = project.creativeBrief.visualQualityBar.replace(/\bstoryboard\s+sheet\b/gi, 'cinematic video');
|
|
6748
6804
|
return [
|
|
6749
6805
|
'PROJECT:',
|
|
6750
6806
|
`Title: ${project.title}`,
|
|
@@ -6753,14 +6809,14 @@ function compileSeedanceStoryboardPromptFromProject(project, options = {}) {
|
|
|
6753
6809
|
`Story spine: ${storySpine}`,
|
|
6754
6810
|
'',
|
|
6755
6811
|
'INPUT ASSETS:',
|
|
6756
|
-
`${storyboardImageTag}: approved
|
|
6812
|
+
`${storyboardImageTag}: approved storyboard reference image. Treat it as an ordered shot guide and timing reference only, not as a collage, split-screen, grid, or picture-in-picture layout to reproduce.`,
|
|
6757
6813
|
'',
|
|
6758
6814
|
'GLOBAL VIDEO INSTRUCTIONS:',
|
|
6759
6815
|
`Render one continuous cinematic video in ${aspectRatio}. Follow the storyboard scene order, timing ranges, transitions, and audio plan.`,
|
|
6760
6816
|
'Use the storyboard as the controlling source for shot order and intent while converting each panel into full-screen motion.',
|
|
6761
6817
|
visibleTextInstruction,
|
|
6762
6818
|
metadataLabels.length > 0 ? `Do not render these metadata labels as video text: ${metadataLabels.join('; ')}.` : '',
|
|
6763
|
-
`Visual style: ${
|
|
6819
|
+
`Visual style: ${visualStyle}`,
|
|
6764
6820
|
toneProgression ? `Tone progression: ${toneProgression}` : '',
|
|
6765
6821
|
musicArc ? `Music arc: ${musicArc}` : '',
|
|
6766
6822
|
'',
|