@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
|
@@ -2817,17 +2817,20 @@ function inferExplicitStoryboardTargetVideoAspectRatio(text) {
|
|
|
2817
2817
|
}
|
|
2818
2818
|
return null;
|
|
2819
2819
|
}
|
|
2820
|
-
function
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2820
|
+
function inferStoryboardTargetVideoAspect(text, boardAspectRatio, explicitTargetVideoAspectRatio = inferExplicitStoryboardTargetVideoAspectRatio(text)) {
|
|
2821
|
+
if (explicitTargetVideoAspectRatio) {
|
|
2822
|
+
return { aspectRatio: explicitTargetVideoAspectRatio, source: 'explicit_ratio' };
|
|
2823
|
+
}
|
|
2824
2824
|
if (/\b(?:portrait|vertical|9\s*:\s*16)\b/i.test(text) || textMentionsPortraitSocialFormat(text)) {
|
|
2825
|
-
return '9:16';
|
|
2825
|
+
return { aspectRatio: '9:16', source: 'orientation_cue' };
|
|
2826
2826
|
}
|
|
2827
2827
|
if (/\b(?:landscape|horizontal|widescreen|16\s*:\s*9|youtube)\b/i.test(text)) {
|
|
2828
|
-
return '16:9';
|
|
2828
|
+
return { aspectRatio: '16:9', source: 'orientation_cue' };
|
|
2829
2829
|
}
|
|
2830
|
-
return boardAspectRatio;
|
|
2830
|
+
return { aspectRatio: boardAspectRatio, source: 'board_fallback' };
|
|
2831
|
+
}
|
|
2832
|
+
function inferStoryboardTargetVideoAspectRatio(text, boardAspectRatio) {
|
|
2833
|
+
return inferStoryboardTargetVideoAspect(text, boardAspectRatio).aspectRatio;
|
|
2831
2834
|
}
|
|
2832
2835
|
function inferStoryboardCellAspectRatio(text, targetVideoAspectRatio) {
|
|
2833
2836
|
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);
|
|
@@ -3057,7 +3060,7 @@ function normalizeStoryboardBoardDimensions(value) {
|
|
|
3057
3060
|
function storyboardPlanningSourceFromContract(contract) {
|
|
3058
3061
|
return contract?.layout?.source ?? contract?.source ?? 'fallback_text';
|
|
3059
3062
|
}
|
|
3060
|
-
function applyStoryboardPlanningLayoutContract(fallback, contract, frameCount, userDefinedCanvas) {
|
|
3063
|
+
function applyStoryboardPlanningLayoutContract(fallback, contract, frameCount, userDefinedCanvas, userDefinedTargetVideoAspect) {
|
|
3061
3064
|
const layoutContract = contract?.layout;
|
|
3062
3065
|
if (!layoutContract)
|
|
3063
3066
|
return fallback;
|
|
@@ -3071,11 +3074,14 @@ function applyStoryboardPlanningLayoutContract(fallback, contract, frameCount, u
|
|
|
3071
3074
|
const boardAspectRatio = contractOwnsCanvas
|
|
3072
3075
|
? normalizeAspectRatio(layoutContract.storyboardCanvasAspectRatio) ?? fallback.boardAspectRatio
|
|
3073
3076
|
: fallback.boardAspectRatio;
|
|
3074
|
-
const
|
|
3075
|
-
|
|
3076
|
-
const
|
|
3077
|
-
?? cellAspectRatio
|
|
3078
|
-
|
|
3077
|
+
const contractOwnsVideoGeometry = !userDefinedTargetVideoAspect
|
|
3078
|
+
|| layoutSource === 'user_schema';
|
|
3079
|
+
const cellAspectRatio = contractOwnsVideoGeometry
|
|
3080
|
+
? normalizeAspectRatio(layoutContract.storyboardCellAspectRatio) ?? fallback.cellAspectRatio
|
|
3081
|
+
: fallback.cellAspectRatio;
|
|
3082
|
+
const targetVideoAspectRatio = contractOwnsVideoGeometry
|
|
3083
|
+
? normalizeAspectRatio(layoutContract.targetVideoAspectRatio) ?? cellAspectRatio ?? fallback.targetVideoAspectRatio
|
|
3084
|
+
: fallback.targetVideoAspectRatio;
|
|
3079
3085
|
const layout = describeStoryboardLayout(boardAspectRatio, cellAspectRatio, frameCount);
|
|
3080
3086
|
const contractBoardDimensions = contractOwnsCanvas
|
|
3081
3087
|
? normalizeStoryboardBoardDimensions(layoutContract.boardDimensions)
|
|
@@ -3125,8 +3131,9 @@ export function inferStoryboardLayoutSpec(userIntentText, frameCount, planningCo
|
|
|
3125
3131
|
const provisionalBoardAspectRatio = userDefinedCanvas
|
|
3126
3132
|
? inferStoryboardBoardAspectRatio(userIntentText)
|
|
3127
3133
|
: '16:9';
|
|
3128
|
-
const
|
|
3129
|
-
|
|
3134
|
+
const inferredTargetVideoAspect = inferStoryboardTargetVideoAspect(userIntentText, provisionalBoardAspectRatio, explicitTargetVideoAspectRatio);
|
|
3135
|
+
const inferredTargetVideoAspectRatio = inferredTargetVideoAspect.aspectRatio;
|
|
3136
|
+
const userDefinedTargetVideoAspect = inferredTargetVideoAspect.source !== 'board_fallback';
|
|
3130
3137
|
const cellAspectRatio = inferStoryboardCellAspectRatio(userIntentText, inferredTargetVideoAspectRatio);
|
|
3131
3138
|
const targetVideoAspectRatio = explicitTargetVideoAspectRatio ?? cellAspectRatio;
|
|
3132
3139
|
const balancedGrid = userDefinedCanvas
|
|
@@ -3145,7 +3152,7 @@ export function inferStoryboardLayoutSpec(userIntentText, frameCount, planningCo
|
|
|
3145
3152
|
? {}
|
|
3146
3153
|
: { boardDimensions: balancedGrid?.boardDimensions ?? GPT_IMAGE_STORYBOARD_DEFAULTS.storyboardLandscape.aspectRatio }),
|
|
3147
3154
|
};
|
|
3148
|
-
return applyStoryboardPlanningLayoutContract(fallback, planningContract, frameCount, userDefinedCanvas);
|
|
3155
|
+
return applyStoryboardPlanningLayoutContract(fallback, planningContract, frameCount, userDefinedCanvas, userDefinedTargetVideoAspect);
|
|
3149
3156
|
}
|
|
3150
3157
|
function clampStoryboardDefaultFrameCount(value) {
|
|
3151
3158
|
return Math.max(STORYBOARD_DEFAULT_MIN_FRAMES, Math.min(STORYBOARD_DEFAULT_MAX_FRAMES, Math.round(value)));
|
|
@@ -4275,8 +4282,42 @@ function storyboardTableRowLooksLikeCountedBeat(cells, headers) {
|
|
|
4275
4282
|
const candidate = compactStoryboardLine(cells[Math.max(0, headerIndex)] || cells[0] || '');
|
|
4276
4283
|
return /^(?:beat|scene|shot|panel|frame)?\s*(?:#\s*)?0?\d{1,2}\b/i.test(candidate);
|
|
4277
4284
|
}
|
|
4285
|
+
function storyboardTableCellLooksLikeCameraCue(cell) {
|
|
4286
|
+
const compact = compactStoryboardLine(cell);
|
|
4287
|
+
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);
|
|
4288
|
+
}
|
|
4289
|
+
function storyboardTableCellLooksLikeTransitionCue(cell) {
|
|
4290
|
+
const compact = compactStoryboardLine(cell);
|
|
4291
|
+
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);
|
|
4292
|
+
}
|
|
4278
4293
|
function normalizeStoryboardTableCellsToHeaders(cells, headers) {
|
|
4279
|
-
if (!headers
|
|
4294
|
+
if (!headers)
|
|
4295
|
+
return cells;
|
|
4296
|
+
if (cells.length === headers.length - 1) {
|
|
4297
|
+
const purposeHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:purpose|story\s*beat|story\s*purpose|beat\s*name|beat\s*title|narrative|name|title)\b/i);
|
|
4298
|
+
const visualHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:visual|frame|shot|image|action)\b/i);
|
|
4299
|
+
const transitionHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:transition|edit|cut|fade|dissolve|wipe)\b/i);
|
|
4300
|
+
const purposeCell = compactStoryboardLine(cells[purposeHeaderIndex] || '');
|
|
4301
|
+
const shiftedCameraCell = cells[visualHeaderIndex] || '';
|
|
4302
|
+
const shiftedTransitionCell = transitionHeaderIndex >= 0
|
|
4303
|
+
? cells[transitionHeaderIndex - 1] || ''
|
|
4304
|
+
: '';
|
|
4305
|
+
const shiftedColumnsLookLikeFoldedPurposeVisual = transitionHeaderIndex >= 0
|
|
4306
|
+
? storyboardTableCellLooksLikeTransitionCue(shiftedTransitionCell)
|
|
4307
|
+
: storyboardTableCellLooksLikeCameraCue(shiftedCameraCell);
|
|
4308
|
+
if (purposeHeaderIndex >= 0
|
|
4309
|
+
&& visualHeaderIndex === purposeHeaderIndex + 1
|
|
4310
|
+
&& visualHeaderIndex < cells.length
|
|
4311
|
+
&& purposeCell.length >= 20
|
|
4312
|
+
&& shiftedColumnsLookLikeFoldedPurposeVisual) {
|
|
4313
|
+
return [
|
|
4314
|
+
...cells.slice(0, visualHeaderIndex),
|
|
4315
|
+
cells[purposeHeaderIndex],
|
|
4316
|
+
...cells.slice(visualHeaderIndex),
|
|
4317
|
+
];
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4320
|
+
if (cells.length <= headers.length)
|
|
4280
4321
|
return cells;
|
|
4281
4322
|
const overflow = cells.length - headers.length;
|
|
4282
4323
|
const combinedAudioDialogueIndex = headers.findIndex(header => /\baudio\b/i.test(header)
|
|
@@ -4370,10 +4411,11 @@ function splitStoryboardTableSections(text) {
|
|
|
4370
4411
|
const cameraHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:camera|motion|fx|effect|lighting|style|look)\b/i);
|
|
4371
4412
|
const dialogueHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:dialogue|vo|v\.o\.|voiceover|speech|narration)\b/i);
|
|
4372
4413
|
const soundHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:audio|sfx|sound|foley|music)\b/i);
|
|
4414
|
+
const transitionHeaderIndex = storyboardTableHeaderIndex(headers, /\b(?:transition|edit|cut|fade|dissolve|wipe)\b/i);
|
|
4373
4415
|
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);
|
|
4374
4416
|
const beatHeaderIndex = headers
|
|
4375
4417
|
? headers.findIndex(header => /\b(?:beat|scene|shot|panel|frame)\b/i.test(header)
|
|
4376
|
-
&& !/\b(?:visual|action|camera|audio|dialogue|vo|sfx)\b/i.test(header))
|
|
4418
|
+
&& !/\b(?:visual|action|camera|audio|dialogue|vo|sfx|transition)\b/i.test(header))
|
|
4377
4419
|
: -1;
|
|
4378
4420
|
const purposeHeaderIndex = headers
|
|
4379
4421
|
? headers.findIndex(header => /\b(?:purpose|story\s*beat|story\s*purpose|beat\s*name|beat\s*title|narrative|name|title)\b/i.test(header)
|
|
@@ -4404,6 +4446,9 @@ function splitStoryboardTableSections(text) {
|
|
|
4404
4446
|
const soundCell = soundHeaderIndex >= 0
|
|
4405
4447
|
? storyboardTableCellWithFieldBreaks(cells[soundHeaderIndex] || '')
|
|
4406
4448
|
: '';
|
|
4449
|
+
const transitionCell = transitionHeaderIndex >= 0
|
|
4450
|
+
? storyboardTableCellWithFieldBreaks(cells[transitionHeaderIndex] || '')
|
|
4451
|
+
: '';
|
|
4407
4452
|
const visibleTextCell = visibleTextHeaderIndex >= 0
|
|
4408
4453
|
? storyboardTableCellWithFieldBreaks(cells[visibleTextHeaderIndex] || '')
|
|
4409
4454
|
: '';
|
|
@@ -4445,6 +4490,8 @@ function splitStoryboardTableSections(text) {
|
|
|
4445
4490
|
|| (visibleTextHeaderIndex >= 0 ? compactStoryboardLine(visibleTextCell) : ''));
|
|
4446
4491
|
const audio = extractStoryboardField(audioCell, ['Audio/SFX', 'Audio', 'SFX', 'FX', 'Foley', 'Sound', 'Sounds'])
|
|
4447
4492
|
|| storyboardTableCellWithoutDialogue(soundCell || audioCell, dialogue);
|
|
4493
|
+
const transition = extractStoryboardField(transitionCell, ['Transition', 'Transition out', 'Transition-out', 'Edit'])
|
|
4494
|
+
|| (transitionHeaderIndex >= 0 ? compactStoryboardLine(transitionCell) : '');
|
|
4448
4495
|
const number = sections.length + 1;
|
|
4449
4496
|
const beatLabel = beatHeaderIndex >= 0 && beatHeaderIndex !== timingCellIndex
|
|
4450
4497
|
? compactStoryboardLine(cells[beatHeaderIndex])
|
|
@@ -4457,6 +4504,7 @@ function splitStoryboardTableSections(text) {
|
|
|
4457
4504
|
&& purposeHeaderIndex !== soundHeaderIndex
|
|
4458
4505
|
&& purposeHeaderIndex !== cameraHeaderIndex
|
|
4459
4506
|
&& purposeHeaderIndex !== visibleTextHeaderIndex
|
|
4507
|
+
&& purposeHeaderIndex !== transitionHeaderIndex
|
|
4460
4508
|
? compactStoryboardLine(cells[purposeHeaderIndex])
|
|
4461
4509
|
: '';
|
|
4462
4510
|
const beatTitleSource = purposeLabel && !/^\d{1,2}$/.test(purposeLabel)
|
|
@@ -4476,6 +4524,7 @@ function splitStoryboardTableSections(text) {
|
|
|
4476
4524
|
dialogue ? `Dialogue/VO: ${dialogue}` : '',
|
|
4477
4525
|
visibleText ? `Visible text: ${visibleText}` : '',
|
|
4478
4526
|
audio ? `Audio/SFX: ${audio}` : '',
|
|
4527
|
+
transition ? `Transition: ${transition}` : '',
|
|
4479
4528
|
].filter(Boolean).join('\n'),
|
|
4480
4529
|
});
|
|
4481
4530
|
}
|
|
@@ -4714,7 +4763,7 @@ function synthesizeStoryboardSectionsFromPlainNarration(sourceText, frameCount,
|
|
|
4714
4763
|
}
|
|
4715
4764
|
function storyboardSectionsHavePreservableExplicitTiming(sections) {
|
|
4716
4765
|
return sections.length > 1
|
|
4717
|
-
&& sections.
|
|
4766
|
+
&& sections.every(section => extractStoryboardTiming(`${section.heading}\n${section.body}`) !== null);
|
|
4718
4767
|
}
|
|
4719
4768
|
function canonicalStoryboardScriptContext(text) {
|
|
4720
4769
|
const trimmed = String(text || '').trim();
|
|
@@ -5231,11 +5280,16 @@ function minimumStoryboardSceneDurationForDialogue(scene, rules, wordsPerSecondM
|
|
|
5231
5280
|
function retimeStoryboardScenesForDialogue(scenes, targetDurationSec, rules = DEFAULT_STORYBOARD_TIMING_RULES) {
|
|
5232
5281
|
if (targetDurationSec === null || scenes.length === 0)
|
|
5233
5282
|
return scenes;
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5283
|
+
const hasCompletePositiveTiming = scenes.every(scene => scene.startSec !== null
|
|
5284
|
+
&& scene.endSec !== null
|
|
5285
|
+
&& scene.durationSec !== null
|
|
5286
|
+
&& scene.durationSec > 0);
|
|
5287
|
+
const sourceDurations = scenes.map(scene => (scene.durationSec !== null && scene.durationSec > 0
|
|
5288
|
+
? scene.durationSec
|
|
5289
|
+
: targetDurationSec / scenes.length));
|
|
5237
5290
|
const minimumDurations = scenes.map(scene => minimumStoryboardSceneDurationForDialogue(scene, rules));
|
|
5238
|
-
const needsRetiming =
|
|
5291
|
+
const needsRetiming = !hasCompletePositiveTiming
|
|
5292
|
+
|| scenes.some((scene, index) => (scene.durationSec ?? 0) + rules.toleranceSec < minimumDurations[index]);
|
|
5239
5293
|
if (!needsRetiming)
|
|
5240
5294
|
return scenes;
|
|
5241
5295
|
let requiredDurations = minimumDurations;
|
|
@@ -5251,9 +5305,8 @@ function retimeStoryboardScenesForDialogue(scenes, targetDurationSec, rules = DE
|
|
|
5251
5305
|
if (minimumTotal > targetDurationSec + rules.toleranceSec)
|
|
5252
5306
|
return scenes;
|
|
5253
5307
|
const extraDuration = Math.max(0, targetDurationSec - minimumTotal);
|
|
5254
|
-
const
|
|
5255
|
-
const
|
|
5256
|
-
const unroundedDurations = requiredDurations.map((minimum, index) => (minimum + (extraDuration * Math.max(0.01, originalDurations[index]) / weightTotal)));
|
|
5308
|
+
const weightTotal = sourceDurations.reduce((sum, duration) => sum + Math.max(0.01, duration), 0);
|
|
5309
|
+
const unroundedDurations = requiredDurations.map((minimum, index) => (minimum + (extraDuration * Math.max(0.01, sourceDurations[index]) / weightTotal)));
|
|
5257
5310
|
const timelineStartSec = scenes[0].startSec ?? 0;
|
|
5258
5311
|
const timelineEndSec = Math.round((timelineStartSec + targetDurationSec) * 100) / 100;
|
|
5259
5312
|
let cursor = timelineStartSec;
|
|
@@ -5354,7 +5407,9 @@ function inferStoryboardStorySpineFromHeading(text) {
|
|
|
5354
5407
|
const collected = [];
|
|
5355
5408
|
for (let cursor = index + 1; cursor < lines.length && collected.length < 4; cursor += 1) {
|
|
5356
5409
|
const candidate = lines[cursor];
|
|
5357
|
-
if (
|
|
5410
|
+
if (/^\|/.test(candidate)
|
|
5411
|
+
|| storyboardMarkdownTableSeparatorLine(candidate)
|
|
5412
|
+
|| /^(?:storyboard|video|production|reference|timecoded|beat\s+\d|scene\s+\d|format|duration|aspect|does this|please confirm)\b/i.test(candidate)) {
|
|
5358
5413
|
break;
|
|
5359
5414
|
}
|
|
5360
5415
|
const cleaned = cleanStoryboardStorySpine(candidate);
|
|
@@ -6643,6 +6698,7 @@ export function compileSeedanceStoryboardPromptFromProject(project, options = {}
|
|
|
6643
6698
|
: 'All scene numbers, timecodes, labels, and production notes remain metadata only and must not appear in the video.';
|
|
6644
6699
|
const toneProgression = project.creativeBrief.toneProgression.join(' -> ');
|
|
6645
6700
|
const musicArc = project.scenes.map(scene => scene.music).filter(Boolean).join(' -> ');
|
|
6701
|
+
const visualStyle = project.creativeBrief.visualQualityBar.replace(/\bstoryboard\s+sheet\b/gi, 'cinematic video');
|
|
6646
6702
|
return [
|
|
6647
6703
|
'PROJECT:',
|
|
6648
6704
|
`Title: ${project.title}`,
|
|
@@ -6651,14 +6707,14 @@ export function compileSeedanceStoryboardPromptFromProject(project, options = {}
|
|
|
6651
6707
|
`Story spine: ${storySpine}`,
|
|
6652
6708
|
'',
|
|
6653
6709
|
'INPUT ASSETS:',
|
|
6654
|
-
`${storyboardImageTag}: approved
|
|
6710
|
+
`${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.`,
|
|
6655
6711
|
'',
|
|
6656
6712
|
'GLOBAL VIDEO INSTRUCTIONS:',
|
|
6657
6713
|
`Render one continuous cinematic video in ${aspectRatio}. Follow the storyboard scene order, timing ranges, transitions, and audio plan.`,
|
|
6658
6714
|
'Use the storyboard as the controlling source for shot order and intent while converting each panel into full-screen motion.',
|
|
6659
6715
|
visibleTextInstruction,
|
|
6660
6716
|
metadataLabels.length > 0 ? `Do not render these metadata labels as video text: ${metadataLabels.join('; ')}.` : '',
|
|
6661
|
-
`Visual style: ${
|
|
6717
|
+
`Visual style: ${visualStyle}`,
|
|
6662
6718
|
toneProgression ? `Tone progression: ${toneProgression}` : '',
|
|
6663
6719
|
musicArc ? `Music arc: ${musicArc}` : '',
|
|
6664
6720
|
'',
|