@sogni-ai/sogni-intelligence-client 3.0.4 → 3.0.6
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/billing/spendGate.d.ts.map +1 -1
- package/dist/billing/spendGate.js.map +1 -1
- package/dist/contracts/data/promptContracts.d.ts.map +1 -1
- package/dist/contracts/data/promptContracts.js +4 -1
- package/dist/contracts/data/promptContracts.js.map +1 -1
- package/dist/events/runEvent.d.ts.map +1 -1
- package/dist/events/runEvent.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/public-skill-runtime/index.d.ts.map +1 -1
- package/dist/public-skill-runtime/index.js +143 -6
- package/dist/public-skill-runtime/index.js.map +1 -1
- package/dist/workflows/index.d.ts +2 -2
- package/dist/workflows/index.d.ts.map +1 -1
- package/dist/workflows/index.js +13 -1
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/primitives/sanitizer.d.ts +21 -0
- package/dist/workflows/primitives/sanitizer.d.ts.map +1 -1
- package/dist/workflows/primitives/sanitizer.js +68 -3
- package/dist/workflows/primitives/sanitizer.js.map +1 -1
- package/dist-esm/billing/spendGate.js.map +1 -1
- package/dist-esm/contracts/data/promptContracts.js +4 -1
- package/dist-esm/contracts/data/promptContracts.js.map +1 -1
- package/dist-esm/events/runEvent.js.map +1 -1
- package/dist-esm/index.js +1 -1
- package/dist-esm/index.js.map +1 -1
- package/dist-esm/public-skill-runtime/index.js +143 -6
- package/dist-esm/public-skill-runtime/index.js.map +1 -1
- package/dist-esm/workflows/index.js +1 -1
- package/dist-esm/workflows/index.js.map +1 -1
- package/dist-esm/workflows/primitives/sanitizer.js +67 -2
- package/dist-esm/workflows/primitives/sanitizer.js.map +1 -1
- package/package.json +7 -1
|
@@ -4702,6 +4702,118 @@ function splitStoryboardSections(text) {
|
|
|
4702
4702
|
return inlineSections;
|
|
4703
4703
|
return sectionHeadings.length > 0 ? sectionHeadings : tableSections;
|
|
4704
4704
|
}
|
|
4705
|
+
function extractPlainNarrationScriptText(text) {
|
|
4706
|
+
const source = text.trim();
|
|
4707
|
+
if (!source)
|
|
4708
|
+
return '';
|
|
4709
|
+
const markers = Array.from(source.matchAll(/^\s*(?:#{1,6}\s*)?(?:voice[-\s]?over\s+|narration\s+)?script\s*:\s*$/gim));
|
|
4710
|
+
const marker = markers[markers.length - 1];
|
|
4711
|
+
if (!marker || marker.index === undefined)
|
|
4712
|
+
return '';
|
|
4713
|
+
const body = source.slice(marker.index + marker[0].length).trim();
|
|
4714
|
+
return body
|
|
4715
|
+
.split(/\r?\n/)
|
|
4716
|
+
.map(line => stripStoryboardMarkup(line).trim())
|
|
4717
|
+
.filter(Boolean)
|
|
4718
|
+
.join('\n\n')
|
|
4719
|
+
.trim();
|
|
4720
|
+
}
|
|
4721
|
+
function splitPlainNarrationPhrases(text) {
|
|
4722
|
+
const normalized = text
|
|
4723
|
+
.replace(/\s+/g, ' ')
|
|
4724
|
+
.trim();
|
|
4725
|
+
if (!normalized)
|
|
4726
|
+
return [];
|
|
4727
|
+
const sentenceMatches = normalized.match(/[^.!?]+[.!?]+(?:["')\]]+)?|[^.!?]+$/g) ?? [normalized];
|
|
4728
|
+
return sentenceMatches
|
|
4729
|
+
.flatMap(sentence => sentence
|
|
4730
|
+
.split(/\s*(?:;|:\s+|,\s+(?=(?:and|but|so|whether|from|across|under|while|as)\b))\s*/i)
|
|
4731
|
+
.map(part => compactStoryboardLine(part)))
|
|
4732
|
+
.filter(part => countWords(part) > 0);
|
|
4733
|
+
}
|
|
4734
|
+
function splitPhraseAtWordMidpoint(value) {
|
|
4735
|
+
const words = value.match(/\S+/g) ?? [];
|
|
4736
|
+
if (words.length < 8)
|
|
4737
|
+
return null;
|
|
4738
|
+
const midpoint = Math.floor(words.length / 2);
|
|
4739
|
+
const left = words.slice(0, midpoint).join(' ').trim();
|
|
4740
|
+
const right = words.slice(midpoint).join(' ').trim();
|
|
4741
|
+
return left && right ? [left, right] : null;
|
|
4742
|
+
}
|
|
4743
|
+
function normalizeNarrationSegmentCount(phrases, frameCount) {
|
|
4744
|
+
if (frameCount <= 0)
|
|
4745
|
+
return [];
|
|
4746
|
+
let segments = phrases.slice();
|
|
4747
|
+
while (segments.length < frameCount) {
|
|
4748
|
+
let longestIndex = -1;
|
|
4749
|
+
let longestCount = 0;
|
|
4750
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
4751
|
+
const words = countWords(segments[index]);
|
|
4752
|
+
if (words > longestCount) {
|
|
4753
|
+
longestCount = words;
|
|
4754
|
+
longestIndex = index;
|
|
4755
|
+
}
|
|
4756
|
+
}
|
|
4757
|
+
if (longestIndex < 0)
|
|
4758
|
+
break;
|
|
4759
|
+
const split = splitPhraseAtWordMidpoint(segments[longestIndex]);
|
|
4760
|
+
if (!split)
|
|
4761
|
+
break;
|
|
4762
|
+
segments.splice(longestIndex, 1, split[0], split[1]);
|
|
4763
|
+
}
|
|
4764
|
+
if (segments.length <= frameCount)
|
|
4765
|
+
return segments;
|
|
4766
|
+
const merged = [];
|
|
4767
|
+
for (let index = 0; index < frameCount; index += 1) {
|
|
4768
|
+
const start = Math.floor(index * segments.length / frameCount);
|
|
4769
|
+
const end = Math.floor((index + 1) * segments.length / frameCount);
|
|
4770
|
+
const chunk = segments.slice(start, Math.max(start + 1, end)).join(' ');
|
|
4771
|
+
if (chunk.trim())
|
|
4772
|
+
merged.push(chunk.trim());
|
|
4773
|
+
}
|
|
4774
|
+
return merged;
|
|
4775
|
+
}
|
|
4776
|
+
function titleFromNarrationSegment(segment, index) {
|
|
4777
|
+
const words = compactStoryboardLine(segment)
|
|
4778
|
+
.replace(/["'()]/g, '')
|
|
4779
|
+
.split(/\s+/)
|
|
4780
|
+
.filter(Boolean)
|
|
4781
|
+
.slice(0, 6)
|
|
4782
|
+
.join(' ');
|
|
4783
|
+
return words || `Narration Beat ${index + 1}`;
|
|
4784
|
+
}
|
|
4785
|
+
function synthesizeStoryboardSectionsFromPlainNarration(sourceText, frameCount, references) {
|
|
4786
|
+
const script = extractPlainNarrationScriptText(sourceText);
|
|
4787
|
+
if (!script || countWords(script) < 8)
|
|
4788
|
+
return [];
|
|
4789
|
+
const phrases = splitPlainNarrationPhrases(script);
|
|
4790
|
+
const segments = normalizeNarrationSegmentCount(phrases, frameCount).slice(0, frameCount);
|
|
4791
|
+
if (segments.length === 0)
|
|
4792
|
+
return [];
|
|
4793
|
+
const referenceLine = references.length > 0
|
|
4794
|
+
? `Reference usage: ${references.map(ref => `Image ${ref.index ?? references.indexOf(ref) + 1}`).join(', ')}.`
|
|
4795
|
+
: '';
|
|
4796
|
+
const cameraPresets = [
|
|
4797
|
+
'Wide establishing composition that introduces the setting, subject, or idea named in the narration.',
|
|
4798
|
+
'Medium composition focused on the active subject, action, or relationship in this beat.',
|
|
4799
|
+
'Detail insert on concrete objects, gestures, text, environment, or visual evidence named in the narration.',
|
|
4800
|
+
'Tracking or reveal-style composition that moves the story into the next idea.',
|
|
4801
|
+
];
|
|
4802
|
+
return segments.map((segment, index) => ({
|
|
4803
|
+
number: index + 1,
|
|
4804
|
+
heading: `Scene ${index + 1} - ${titleFromNarrationSegment(segment, index)}`,
|
|
4805
|
+
body: [
|
|
4806
|
+
`Purpose: Translate narration beat ${index + 1} into a concrete ordered storyboard moment.`,
|
|
4807
|
+
`Visual/Action: Create a concrete visual moment using only this narration beat and the supplied references: ${segment}`,
|
|
4808
|
+
`Camera/Motion: ${cameraPresets[index % cameraPresets.length]}`,
|
|
4809
|
+
'Lighting/Style: Match the visual style, genre, and tone implied by the user request and supplied references; keep the frame cinematic but readable as a storyboard panel.',
|
|
4810
|
+
'Transition: Maintain continuity from the previous beat through subject, setting, gesture, camera direction, color, or motion when those cues are present.',
|
|
4811
|
+
`Dialogue/VO: ${segment}`,
|
|
4812
|
+
'Audio/SFX: Use only audio cues implied by the narration or user request; otherwise keep ambience or music generic and unobtrusive.',
|
|
4813
|
+
referenceLine,
|
|
4814
|
+
].filter(Boolean).join('\n'),
|
|
4815
|
+
}));
|
|
4816
|
+
}
|
|
4705
4817
|
function storyboardSectionsHavePreservableExplicitTiming(sections) {
|
|
4706
4818
|
return sections.length > 1
|
|
4707
4819
|
&& sections.some(section => extractStoryboardTiming(`${section.heading}\n${section.body}`) !== null);
|
|
@@ -5536,8 +5648,14 @@ function buildStoryboardProject(options) {
|
|
|
5536
5648
|
: assistantDraftUndercounted || assistantApprovedDraftUndercounted
|
|
5537
5649
|
? []
|
|
5538
5650
|
: sourceSections;
|
|
5539
|
-
const
|
|
5540
|
-
|
|
5651
|
+
const selectedSectionsHaveExplicitTiming = sections.length > 0 && storyboardSectionsHavePreservableExplicitTiming(sections);
|
|
5652
|
+
const preserveAssistantExplicitTiming = options.promptAuthorship === 'assistant' && selectedSectionsHaveExplicitTiming;
|
|
5653
|
+
const synthesizedSections = sections.length === 0
|
|
5654
|
+
? synthesizeStoryboardSectionsFromPlainNarration(`${sourceText}\n\n${narrativeUserIntentText}`, options.frameCount, references)
|
|
5655
|
+
: [];
|
|
5656
|
+
const storyboardSections = sections.length > 0 ? sections : synthesizedSections;
|
|
5657
|
+
const parsedScenes = storyboardSections.length > 0
|
|
5658
|
+
? storyboardSections.map((section) => {
|
|
5541
5659
|
return buildSceneFromSection(section, references, null, storyboardScenePlanningContractForIndex(options.planningContract, section.number));
|
|
5542
5660
|
})
|
|
5543
5661
|
: [];
|
|
@@ -5547,12 +5665,17 @@ function buildStoryboardProject(options) {
|
|
|
5547
5665
|
}));
|
|
5548
5666
|
const timingNormalizedScenes = normalizeAssistantStoryboardSceneTiming(scenes, durationSec, options.promptAuthorship);
|
|
5549
5667
|
const dialogueAlignment = alignAssistantStoryboardDialogueWithUserSource(timingNormalizedScenes, userIntentText, options.promptAuthorship);
|
|
5550
|
-
const
|
|
5668
|
+
const canPreserveAssistantExplicitTiming = preserveAssistantExplicitTiming && !dialogueAlignment.shouldRetime;
|
|
5669
|
+
const dialogueTimedScenes = (!canPreserveAssistantExplicitTiming
|
|
5670
|
+
&& (options.promptAuthorship === 'assistant' || dialogueAlignment.shouldRetime))
|
|
5551
5671
|
? retimeStoryboardScenesForDialogue(dialogueAlignment.scenes, durationSec)
|
|
5552
5672
|
: dialogueAlignment.scenes;
|
|
5553
5673
|
const userConstraintSource = buildStoryboardUserConstraintSource(narrativeUserIntentText, cleanStoryboardNarrativeSourceText(primarySourceBrief), options);
|
|
5554
5674
|
const { mustIncludeText, endCardText } = storyboardRequiredTextForProject(options, userConstraintSource, dialogueTimedScenes);
|
|
5555
|
-
const
|
|
5675
|
+
const scenesWithEndCardText = applyStoryboardEndCardTextToScenes(dialogueTimedScenes, endCardText);
|
|
5676
|
+
const normalizedScenes = canPreserveAssistantExplicitTiming
|
|
5677
|
+
? scenesWithEndCardText
|
|
5678
|
+
: retimeStoryboardScenesForDialogue(scenesWithEndCardText, durationSec);
|
|
5556
5679
|
const voiceLines = assignVoiceLinesToScenes(normalizedScenes, sourceText);
|
|
5557
5680
|
const storySpineFallback = approvedScriptContext
|
|
5558
5681
|
|| (options.promptAuthorship === 'assistant' ? narrativeUserIntentText : cleanStoryboardNarrativeSourceText(primarySourceBrief))
|
|
@@ -5582,8 +5705,8 @@ function buildStoryboardProject(options) {
|
|
|
5582
5705
|
}
|
|
5583
5706
|
const recognizedSectionCount = directBeatMarkerCount > 0
|
|
5584
5707
|
? directBeatMarkerCount
|
|
5585
|
-
:
|
|
5586
|
-
?
|
|
5708
|
+
: storyboardSections.length > 0
|
|
5709
|
+
? storyboardSections.length
|
|
5587
5710
|
: Math.max(approvedSections.length, sourceSections.length);
|
|
5588
5711
|
return {
|
|
5589
5712
|
title: inferStoryboardTitle(allText),
|
|
@@ -5921,6 +6044,19 @@ function storyboardLayoutSpecFromProject(project, frameCount) {
|
|
|
5921
6044
|
...(project.boardDimensions ? { boardDimensions: project.boardDimensions } : {}),
|
|
5922
6045
|
};
|
|
5923
6046
|
}
|
|
6047
|
+
function compileStoryboardFrameGeometrySection(layout) {
|
|
6048
|
+
const cellOrientation = parseAspectRatioOrientation(layout.cellAspectRatio);
|
|
6049
|
+
if (cellOrientation === 'portrait') {
|
|
6050
|
+
return [
|
|
6051
|
+
'PORTRAIT FRAME GEOMETRY:',
|
|
6052
|
+
`Every cinematic artwork area inside a panel must remain a ${layout.cellAspectRatio} portrait video-frame rectangle matching the final video frame.`,
|
|
6053
|
+
`Inside every numbered scene slot, draw one identical upright ${layout.cellAspectRatio} video-frame rectangle whose height is visibly greater than its width.`,
|
|
6054
|
+
`Square cells violate the requested ${layout.targetVideoAspectRatio} final video format.`,
|
|
6055
|
+
'Unused grid slots must remain blank margin/notes space only; do not fill them with extra scenes, duplicate frames, or decorative artwork.',
|
|
6056
|
+
];
|
|
6057
|
+
}
|
|
6058
|
+
return [];
|
|
6059
|
+
}
|
|
5924
6060
|
function compileVideoStoryboardImagePrompt(options) {
|
|
5925
6061
|
const rawUserIntentText = options.userIntentText.trim();
|
|
5926
6062
|
const userIntentText = canonicalStoryboardScriptContext(rawUserIntentText) || rawUserIntentText;
|
|
@@ -5954,6 +6090,7 @@ function compileVideoStoryboardImagePrompt(options) {
|
|
|
5954
6090
|
`Each panel must contain one distinct ${layout.cellAspectRatio} cinematic video-frame rectangle with compact notes outside the frame.`,
|
|
5955
6091
|
'Keep scene numbers, timecodes, titles, dialogue/VO, audio notes, and production notes outside the video-frame rectangles.',
|
|
5956
6092
|
'Do not merge panels, create inset thumbnails, make panels square, or overlay storyboard metadata inside the artwork frames.',
|
|
6093
|
+
...compileStoryboardFrameGeometrySection(layout),
|
|
5957
6094
|
'',
|
|
5958
6095
|
...compileStoryboardReferenceSection(project),
|
|
5959
6096
|
'',
|