@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.
Files changed (42) hide show
  1. package/dist/contracts/data/promptContracts.d.ts.map +1 -1
  2. package/dist/contracts/data/promptContracts.js +23 -0
  3. package/dist/contracts/data/promptContracts.js.map +1 -1
  4. package/dist/contracts/videoComposition.d.ts.map +1 -1
  5. package/dist/contracts/videoComposition.js +15 -1
  6. package/dist/contracts/videoComposition.js.map +1 -1
  7. package/dist/public-skill-runtime/index.d.ts.map +1 -1
  8. package/dist/public-skill-runtime/index.js +85 -29
  9. package/dist/public-skill-runtime/index.js.map +1 -1
  10. package/dist/tools/definitions/animate-photo/definition.d.ts.map +1 -1
  11. package/dist/tools/definitions/animate-photo/definition.js +6 -4
  12. package/dist/tools/definitions/animate-photo/definition.js.map +1 -1
  13. package/dist/tools/definitions/generate-video/definition.d.ts.map +1 -1
  14. package/dist/tools/definitions/generate-video/definition.js +3 -1
  15. package/dist/tools/definitions/generate-video/definition.js.map +1 -1
  16. package/dist/tools/definitions/sound-to-video/definition.d.ts.map +1 -1
  17. package/dist/tools/definitions/sound-to-video/definition.js +2 -0
  18. package/dist/tools/definitions/sound-to-video/definition.js.map +1 -1
  19. package/dist/tools/definitions/video-to-video/definition.d.ts.map +1 -1
  20. package/dist/tools/definitions/video-to-video/definition.js +3 -1
  21. package/dist/tools/definitions/video-to-video/definition.js.map +1 -1
  22. package/dist/tools/shared/seedancePolicyErrors.d.ts +14 -1
  23. package/dist/tools/shared/seedancePolicyErrors.d.ts.map +1 -1
  24. package/dist/tools/shared/seedancePolicyErrors.js +35 -2
  25. package/dist/tools/shared/seedancePolicyErrors.js.map +1 -1
  26. package/dist-esm/contracts/data/promptContracts.js +23 -0
  27. package/dist-esm/contracts/data/promptContracts.js.map +1 -1
  28. package/dist-esm/contracts/videoComposition.js +15 -1
  29. package/dist-esm/contracts/videoComposition.js.map +1 -1
  30. package/dist-esm/public-skill-runtime/index.js +85 -29
  31. package/dist-esm/public-skill-runtime/index.js.map +1 -1
  32. package/dist-esm/tools/definitions/animate-photo/definition.js +6 -4
  33. package/dist-esm/tools/definitions/animate-photo/definition.js.map +1 -1
  34. package/dist-esm/tools/definitions/generate-video/definition.js +3 -1
  35. package/dist-esm/tools/definitions/generate-video/definition.js.map +1 -1
  36. package/dist-esm/tools/definitions/sound-to-video/definition.js +2 -0
  37. package/dist-esm/tools/definitions/sound-to-video/definition.js.map +1 -1
  38. package/dist-esm/tools/definitions/video-to-video/definition.js +3 -1
  39. package/dist-esm/tools/definitions/video-to-video/definition.js.map +1 -1
  40. package/dist-esm/tools/shared/seedancePolicyErrors.js +34 -1
  41. package/dist-esm/tools/shared/seedancePolicyErrors.js.map +1 -1
  42. package/package.json +1 -1
@@ -2817,17 +2817,20 @@ function inferExplicitStoryboardTargetVideoAspectRatio(text) {
2817
2817
  }
2818
2818
  return null;
2819
2819
  }
2820
- function inferStoryboardTargetVideoAspectRatio(text, boardAspectRatio) {
2821
- const explicitTarget = inferExplicitStoryboardTargetVideoAspectRatio(text);
2822
- if (explicitTarget)
2823
- return explicitTarget;
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 cellAspectRatio = normalizeAspectRatio(layoutContract.storyboardCellAspectRatio)
3075
- ?? fallback.cellAspectRatio;
3076
- const targetVideoAspectRatio = normalizeAspectRatio(layoutContract.targetVideoAspectRatio)
3077
- ?? cellAspectRatio
3078
- ?? fallback.targetVideoAspectRatio;
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 inferredTargetVideoAspectRatio = explicitTargetVideoAspectRatio
3129
- ?? inferStoryboardTargetVideoAspectRatio(userIntentText, provisionalBoardAspectRatio);
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 || cells.length <= headers.length)
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.some(section => extractStoryboardTiming(`${section.heading}\n${section.body}`) !== null);
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
- if (!scenes.every(scene => scene.startSec !== null && scene.endSec !== null && scene.durationSec !== null && scene.durationSec > 0)) {
5235
- return scenes;
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 = scenes.some((scene, index) => (scene.durationSec ?? 0) + rules.toleranceSec < minimumDurations[index]);
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 originalDurations = scenes.map(scene => scene.durationSec ?? 0);
5255
- const weightTotal = originalDurations.reduce((sum, duration) => sum + Math.max(0.01, duration), 0);
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 (/^(?:storyboard|video|production|reference|timecoded|beat\s+\d|scene\s+\d|format|duration|aspect|does this|please confirm)\b/i.test(candidate)) {
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 GPT Image 2 storyboard board. 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.`,
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: ${project.creativeBrief.visualQualityBar}`,
6717
+ `Visual style: ${visualStyle}`,
6662
6718
  toneProgression ? `Tone progression: ${toneProgression}` : '',
6663
6719
  musicArc ? `Music arc: ${musicArc}` : '',
6664
6720
  '',