@sogni-ai/sogni-intelligence-client 3.22.2 → 3.22.4

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
- ...compileStoryboardAvoidSection(project.creativeBrief.concept).map(item => `- ${item}`),
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[\s\S]{0,220}(?:\.|$)/gi)) {
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 && !constraints.includes(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, '')
@@ -5690,6 +5701,17 @@ function inferStoryboardStorySpine(text, fallbackBrief) {
5690
5701
  }
5691
5702
  return 'A coherent sequence where every scene follows from the previous beat and supports the requested final video outcome.';
5692
5703
  }
5704
+ function inferStoryboardStorySpineFromScenes(scenes) {
5705
+ const beats = scenes
5706
+ .map(scene => meaningfulStoryboardPromptField(scene.purpose
5707
+ || scene.visual
5708
+ || scene.action
5709
+ || scene.title))
5710
+ .filter(Boolean);
5711
+ if (beats.length === 0)
5712
+ return '';
5713
+ return truncateStoryboardText(uniqueStoryboardStrings(beats).join(' -> '), 260);
5714
+ }
5693
5715
  function inferStoryboardProductFeatureMap(text, scenes) {
5694
5716
  const explicitLines = text
5695
5717
  .split(/\r?\n/)
@@ -5893,11 +5915,17 @@ export function buildStoryboardProject(options) {
5893
5915
  ? scenesWithEndCardText
5894
5916
  : retimeStoryboardScenesForDialogue(scenesWithEndCardText, durationSec);
5895
5917
  const voiceLines = assignVoiceLinesToScenes(normalizedScenes, sourceText);
5918
+ const structuredSceneStorySpine = inferStoryboardStorySpineFromScenes(normalizedScenes);
5919
+ const assistantStorySpineSource = approvedScriptContext || sourceText;
5896
5920
  const storySpineFallback = approvedScriptContext
5897
- || (options.promptAuthorship === 'assistant' ? narrativeUserIntentText : cleanStoryboardNarrativeSourceText(primarySourceBrief))
5921
+ || (options.promptAuthorship === 'assistant'
5922
+ ? structuredSceneStorySpine || cleanStoryboardNarrativeSourceText(primarySourceBrief)
5923
+ : cleanStoryboardNarrativeSourceText(primarySourceBrief))
5898
5924
  || prompt
5899
5925
  || narrativeUserIntentText;
5900
- const storySpine = inferStoryboardStorySpine(allText, storySpineFallback);
5926
+ const storySpine = inferStoryboardStorySpine(options.promptAuthorship === 'assistant' && assistantStorySpineSource
5927
+ ? assistantStorySpineSource
5928
+ : allText, storySpineFallback);
5901
5929
  const productFeatureMap = inferStoryboardProductFeatureMap(allText, normalizedScenes);
5902
5930
  const beatMarkerScripts = [approvedScriptContext, sourceText];
5903
5931
  let directBeatMarkerCount = 0;
@@ -6102,13 +6130,13 @@ function compileStoryboardCriticalRequirements() {
6102
6130
  'Keep character, product, logo, and style references consistent with their assigned scenes.',
6103
6131
  ];
6104
6132
  }
6105
- function compileStoryboardAvoidSection(userIntentText) {
6133
+ function compileStoryboardAvoidConstraints(constraints) {
6106
6134
  const avoidLines = [
6107
6135
  'Avoid malformed text, misspelled brand words, inconsistent reference identities, missing scene cells, wrong timings, and mismatched board/cell aspect ratios.',
6108
6136
  '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
6137
  '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
6138
  ];
6111
- for (const constraint of extractStoryboardAvoidConstraints(userIntentText)) {
6139
+ for (const constraint of constraints) {
6112
6140
  const normalized = constraint.replace(/[.]+$/g, '').trim();
6113
6141
  avoidLines.push(/^(?:avoid|without|less|do\s+not|don't)\b/i.test(normalized)
6114
6142
  ? `${normalized}.`
@@ -6116,6 +6144,9 @@ function compileStoryboardAvoidSection(userIntentText) {
6116
6144
  }
6117
6145
  return avoidLines;
6118
6146
  }
6147
+ function compileStoryboardAvoidSection(userIntentText) {
6148
+ return compileStoryboardAvoidConstraints(extractStoryboardAvoidConstraints(userIntentText));
6149
+ }
6119
6150
  function formatStoryboardSeconds(value) {
6120
6151
  return value === null ? 'unspecified' : `${Number(value.toFixed(2))}s`;
6121
6152
  }
@@ -6157,7 +6188,10 @@ function removeStoryboardMetadataLabelsFromPromptText(value, metadataLabels) {
6157
6188
  .filter(Boolean)
6158
6189
  .sort((a, b) => b.length - a.length);
6159
6190
  for (const label of aliases) {
6160
- cleaned = cleaned.replace(new RegExp(escapeStoryboardRegExp(label), 'gi'), '');
6191
+ const escaped = escapeStoryboardRegExp(label);
6192
+ const leadingBoundary = /^[\p{L}\p{N}_]/u.test(label) ? '(?<![\\p{L}\\p{N}_])' : '';
6193
+ const trailingBoundary = /[\p{L}\p{N}_]$/u.test(label) ? '(?![\\p{L}\\p{N}_])' : '';
6194
+ cleaned = cleaned.replace(new RegExp(`${leadingBoundary}${escaped}${trailingBoundary}`, 'giu'), '');
6161
6195
  }
6162
6196
  return compactStoryboardLine(cleaned)
6163
6197
  .replace(/\s+([,.;:])/g, '$1')