@sogni-ai/sogni-intelligence-client 3.22.3 → 3.22.5
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.
|
@@ -798,7 +798,7 @@ function compileStoryboardImagePromptFromProject(project) {
|
|
|
798
798
|
project.endCard.logoUsage ? `Logo usage: ${project.endCard.logoUsage}` : '',
|
|
799
799
|
'',
|
|
800
800
|
'NEGATIVE / AVOID:',
|
|
801
|
-
...
|
|
801
|
+
...compileStoryboardAvoidConstraints(project.creativeBrief.mustAvoid).map(item => `- ${item}`),
|
|
802
802
|
].join('\n');
|
|
803
803
|
}
|
|
804
804
|
function scenePromptText(scene) {
|
|
@@ -3847,13 +3847,24 @@ function compileStoryboardReferenceSection(project) {
|
|
|
3847
3847
|
}
|
|
3848
3848
|
function extractStoryboardAvoidConstraints(text) {
|
|
3849
3849
|
const constraints = [];
|
|
3850
|
-
for (const match of text.matchAll(/\b(?:avoid|do not include|don't include|without|less)\b[
|
|
3850
|
+
for (const match of text.matchAll(/\b(?:avoid|do not include|don't include|without|less)\b(?:(?!\b(?:avoid|do not include|don't include|without|less)\b)[^.!?\n]){0,220}/gi)) {
|
|
3851
3851
|
const value = normalizeStoryboardAvoidConstraint(match[0]);
|
|
3852
|
-
if (value
|
|
3852
|
+
if (value
|
|
3853
|
+
&& !storyboardAvoidConstraintIsWorkflowControl(value)
|
|
3854
|
+
&& !constraints.includes(value)) {
|
|
3853
3855
|
constraints.push(value);
|
|
3856
|
+
}
|
|
3854
3857
|
}
|
|
3855
3858
|
return constraints;
|
|
3856
3859
|
}
|
|
3860
|
+
function storyboardAvoidConstraintIsWorkflowControl(value) {
|
|
3861
|
+
const interaction = /\b(?:approval|confirmation|review|feedback|permission|user\s+input|user\s+response)\b/i;
|
|
3862
|
+
if (!interaction.test(value))
|
|
3863
|
+
return false;
|
|
3864
|
+
const processAction = /\b(?:ask(?:ing)?|await(?:ing)?|wait(?:ing)?|pause|pausing|stop(?:ping)?|hold(?:ing)?|seek(?:ing)?|request(?:ing)?|require|requiring|check(?:ing)?|confirm(?:ing)?|approve|approving)\b/i;
|
|
3865
|
+
const workflowBoundary = /\b(?:workflow|stage|step|phase|round|generation|render|between|before|after|proceed|continu(?:e|ing))\b/i;
|
|
3866
|
+
return processAction.test(value) || workflowBoundary.test(value);
|
|
3867
|
+
}
|
|
3857
3868
|
function normalizeStoryboardAvoidConstraint(value) {
|
|
3858
3869
|
const cleaned = compactStoryboardLine(stripStoryboardMarkup(value))
|
|
3859
3870
|
.replace(/^[*\-_\s]+|[*\-_\s]+$/g, '')
|
|
@@ -5679,10 +5690,11 @@ function inferStoryboardStorySpineFromHeading(text) {
|
|
|
5679
5690
|
}
|
|
5680
5691
|
function inferStoryboardStorySpine(text, fallbackBrief) {
|
|
5681
5692
|
const explicit = cleanStoryboardStorySpine(text.match(/\b(?:story\s+spine|narrative\s+spine|throughline|story\s+arc|creative\s+intent)\s*:\s*([^\n]{1,360})/i)?.[1] || '');
|
|
5682
|
-
|
|
5693
|
+
const generatedFallbackPrefix = 'One continuous progression from the source brief:';
|
|
5694
|
+
if (explicit && !explicit.startsWith(generatedFallbackPrefix))
|
|
5683
5695
|
return explicit;
|
|
5684
5696
|
const fromHeading = inferStoryboardStorySpineFromHeading(text);
|
|
5685
|
-
if (fromHeading)
|
|
5697
|
+
if (fromHeading && !fromHeading.startsWith(generatedFallbackPrefix))
|
|
5686
5698
|
return fromHeading;
|
|
5687
5699
|
const compactFallback = sanitizeStoryboardExternalAudioReferences(truncateStoryboardText(cleanStoryboardNarrativeSourceText(fallbackBrief || text), 260));
|
|
5688
5700
|
if (compactFallback) {
|
|
@@ -5690,6 +5702,17 @@ function inferStoryboardStorySpine(text, fallbackBrief) {
|
|
|
5690
5702
|
}
|
|
5691
5703
|
return 'A coherent sequence where every scene follows from the previous beat and supports the requested final video outcome.';
|
|
5692
5704
|
}
|
|
5705
|
+
function inferStoryboardStorySpineFromScenes(scenes) {
|
|
5706
|
+
const beats = scenes
|
|
5707
|
+
.map(scene => meaningfulStoryboardPromptField(scene.purpose
|
|
5708
|
+
|| scene.visual
|
|
5709
|
+
|| scene.action
|
|
5710
|
+
|| scene.title))
|
|
5711
|
+
.filter(Boolean);
|
|
5712
|
+
if (beats.length === 0)
|
|
5713
|
+
return '';
|
|
5714
|
+
return truncateStoryboardText(uniqueStoryboardStrings(beats).join(' -> '), 260);
|
|
5715
|
+
}
|
|
5693
5716
|
function inferStoryboardProductFeatureMap(text, scenes) {
|
|
5694
5717
|
const explicitLines = text
|
|
5695
5718
|
.split(/\r?\n/)
|
|
@@ -5893,11 +5916,22 @@ export function buildStoryboardProject(options) {
|
|
|
5893
5916
|
? scenesWithEndCardText
|
|
5894
5917
|
: retimeStoryboardScenesForDialogue(scenesWithEndCardText, durationSec);
|
|
5895
5918
|
const voiceLines = assignVoiceLinesToScenes(normalizedScenes, sourceText);
|
|
5896
|
-
const
|
|
5897
|
-
|
|
5919
|
+
const authoredStorySpineSections = approvedSections.length > 0
|
|
5920
|
+
? approvedSections
|
|
5921
|
+
: sourceSections;
|
|
5922
|
+
const authoredStorySpineScenes = authoredStorySpineSections.map(section => buildSceneFromSection(section, references, null, storyboardScenePlanningContractForIndex(options.planningContract, section.number)));
|
|
5923
|
+
const structuredSceneStorySpine = inferStoryboardStorySpineFromScenes(authoredStorySpineScenes.length > 0 ? authoredStorySpineScenes : normalizedScenes);
|
|
5924
|
+
const assistantStorySpineSource = approvedScriptContext || sourceText;
|
|
5925
|
+
const storySpineFallback = (options.promptAuthorship === 'assistant'
|
|
5926
|
+
? structuredSceneStorySpine
|
|
5927
|
+
|| cleanStoryboardNarrativeSourceText(primarySourceBrief)
|
|
5928
|
+
|| approvedScriptContext
|
|
5929
|
+
: approvedScriptContext || cleanStoryboardNarrativeSourceText(primarySourceBrief))
|
|
5898
5930
|
|| prompt
|
|
5899
5931
|
|| narrativeUserIntentText;
|
|
5900
|
-
const storySpine = inferStoryboardStorySpine(
|
|
5932
|
+
const storySpine = inferStoryboardStorySpine(options.promptAuthorship === 'assistant' && assistantStorySpineSource
|
|
5933
|
+
? assistantStorySpineSource
|
|
5934
|
+
: allText, storySpineFallback);
|
|
5901
5935
|
const productFeatureMap = inferStoryboardProductFeatureMap(allText, normalizedScenes);
|
|
5902
5936
|
const beatMarkerScripts = [approvedScriptContext, sourceText];
|
|
5903
5937
|
let directBeatMarkerCount = 0;
|
|
@@ -6102,13 +6136,13 @@ function compileStoryboardCriticalRequirements() {
|
|
|
6102
6136
|
'Keep character, product, logo, and style references consistent with their assigned scenes.',
|
|
6103
6137
|
];
|
|
6104
6138
|
}
|
|
6105
|
-
function
|
|
6139
|
+
function compileStoryboardAvoidConstraints(constraints) {
|
|
6106
6140
|
const avoidLines = [
|
|
6107
6141
|
'Avoid malformed text, misspelled brand words, inconsistent reference identities, missing scene cells, wrong timings, and mismatched board/cell aspect ratios.',
|
|
6108
6142
|
'Avoid scene numbers, timing badges, timecodes, production tables, Dialogue/VO labels, Audio/SFX labels, or other production notes overlaid inside the video frame artwork.',
|
|
6109
6143
|
'Avoid in-frame comic-book SFX/action text such as Whoosh!, Impact!, Boom!, Thud!, Slash!, Crack!, or Pop!; keep those words in the production notes only.',
|
|
6110
6144
|
];
|
|
6111
|
-
for (const constraint of
|
|
6145
|
+
for (const constraint of constraints) {
|
|
6112
6146
|
const normalized = constraint.replace(/[.]+$/g, '').trim();
|
|
6113
6147
|
avoidLines.push(/^(?:avoid|without|less|do\s+not|don't)\b/i.test(normalized)
|
|
6114
6148
|
? `${normalized}.`
|
|
@@ -6116,6 +6150,9 @@ function compileStoryboardAvoidSection(userIntentText) {
|
|
|
6116
6150
|
}
|
|
6117
6151
|
return avoidLines;
|
|
6118
6152
|
}
|
|
6153
|
+
function compileStoryboardAvoidSection(userIntentText) {
|
|
6154
|
+
return compileStoryboardAvoidConstraints(extractStoryboardAvoidConstraints(userIntentText));
|
|
6155
|
+
}
|
|
6119
6156
|
function formatStoryboardSeconds(value) {
|
|
6120
6157
|
return value === null ? 'unspecified' : `${Number(value.toFixed(2))}s`;
|
|
6121
6158
|
}
|
|
@@ -6157,7 +6194,10 @@ function removeStoryboardMetadataLabelsFromPromptText(value, metadataLabels) {
|
|
|
6157
6194
|
.filter(Boolean)
|
|
6158
6195
|
.sort((a, b) => b.length - a.length);
|
|
6159
6196
|
for (const label of aliases) {
|
|
6160
|
-
|
|
6197
|
+
const escaped = escapeStoryboardRegExp(label);
|
|
6198
|
+
const leadingBoundary = /^[\p{L}\p{N}_]/u.test(label) ? '(?<![\\p{L}\\p{N}_])' : '';
|
|
6199
|
+
const trailingBoundary = /[\p{L}\p{N}_]$/u.test(label) ? '(?![\\p{L}\\p{N}_])' : '';
|
|
6200
|
+
cleaned = cleaned.replace(new RegExp(`${leadingBoundary}${escaped}${trailingBoundary}`, 'giu'), '');
|
|
6161
6201
|
}
|
|
6162
6202
|
return compactStoryboardLine(cleaned)
|
|
6163
6203
|
.replace(/\s+([,.;:])/g, '$1')
|