@nodaro/prompts 1.38.0 → 1.40.0

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 (130) hide show
  1. package/dist/chunk-2EW5B7ZV.cjs +86 -0
  2. package/dist/chunk-2EW5B7ZV.cjs.map +1 -0
  3. package/dist/chunk-2P26SZX5.cjs +414 -0
  4. package/dist/chunk-2P26SZX5.cjs.map +1 -0
  5. package/dist/{chunk-7XKHDXCL.cjs → chunk-3U7X6JZN.cjs} +13 -12
  6. package/dist/chunk-3U7X6JZN.cjs.map +1 -0
  7. package/dist/chunk-4GKTOVFM.cjs +8 -0
  8. package/dist/chunk-4GKTOVFM.cjs.map +1 -0
  9. package/dist/{chunk-HRBBNODV.js → chunk-6GVFJLDL.js} +4 -3
  10. package/dist/chunk-6GVFJLDL.js.map +1 -0
  11. package/dist/{chunk-LVSH7K7R.cjs → chunk-C3NHNECH.cjs} +165 -88
  12. package/dist/chunk-C3NHNECH.cjs.map +1 -0
  13. package/dist/{chunk-CEPVQQVO.js → chunk-C46256GZ.js} +43 -5
  14. package/dist/chunk-C46256GZ.js.map +1 -0
  15. package/dist/{chunk-JKCR6WRZ.cjs → chunk-DQFQJECU.cjs} +43 -5
  16. package/dist/chunk-DQFQJECU.cjs.map +1 -0
  17. package/dist/{chunk-QDEWBBUR.js → chunk-DUXX6CBX.js} +12 -143
  18. package/dist/chunk-DUXX6CBX.js.map +1 -0
  19. package/dist/chunk-EAYEZXWT.js +388 -0
  20. package/dist/chunk-EAYEZXWT.js.map +1 -0
  21. package/dist/chunk-GILUVQQJ.js +6 -0
  22. package/dist/chunk-GILUVQQJ.js.map +1 -0
  23. package/dist/{chunk-KIYNOOPJ.js → chunk-GTDKDD7Y.js} +12 -6
  24. package/dist/chunk-GTDKDD7Y.js.map +1 -0
  25. package/dist/{chunk-QBEZMR2F.js → chunk-HQTHDTHN.js} +137 -62
  26. package/dist/chunk-HQTHDTHN.js.map +1 -0
  27. package/dist/{chunk-TLVX5PXD.cjs → chunk-IUCNJAHW.cjs} +13 -7
  28. package/dist/chunk-IUCNJAHW.cjs.map +1 -0
  29. package/dist/{chunk-ZFIXQRBZ.cjs → chunk-LXPKTI2K.cjs} +12 -83
  30. package/dist/chunk-LXPKTI2K.cjs.map +1 -0
  31. package/dist/{chunk-CVPB2N3Z.cjs → chunk-LZ53F5BN.cjs} +103 -5
  32. package/dist/chunk-LZ53F5BN.cjs.map +1 -0
  33. package/dist/{chunk-4FDNVNJE.js → chunk-N6VMPG5S.js} +12 -79
  34. package/dist/chunk-N6VMPG5S.js.map +1 -0
  35. package/dist/{chunk-LK2CZK5U.cjs → chunk-PWWM7Q3T.cjs} +7 -7
  36. package/dist/{chunk-LK2CZK5U.cjs.map → chunk-PWWM7Q3T.cjs.map} +1 -1
  37. package/dist/{chunk-N7TOWXDJ.js → chunk-QDUTMOF4.js} +3 -3
  38. package/dist/{chunk-N7TOWXDJ.js.map → chunk-QDUTMOF4.js.map} +1 -1
  39. package/dist/{chunk-NO6XHX4R.js → chunk-RB2F5JQF.js} +100 -7
  40. package/dist/chunk-RB2F5JQF.js.map +1 -0
  41. package/dist/{chunk-MENBHEAY.cjs → chunk-WRM52ZBN.cjs} +19 -161
  42. package/dist/chunk-WRM52ZBN.cjs.map +1 -0
  43. package/dist/chunk-YS6HOWMW.js +80 -0
  44. package/dist/chunk-YS6HOWMW.js.map +1 -0
  45. package/dist/entries/assembly.cjs +34 -25
  46. package/dist/entries/assembly.d.cts +121 -37
  47. package/dist/entries/assembly.d.ts +121 -37
  48. package/dist/entries/assembly.js +5 -4
  49. package/dist/entries/doctrine.cjs +46 -46
  50. package/dist/entries/doctrine.d.cts +3 -3
  51. package/dist/entries/doctrine.d.ts +3 -3
  52. package/dist/entries/doctrine.js +1 -1
  53. package/dist/entries/picker-catalogs.cjs +42 -42
  54. package/dist/entries/picker-catalogs.js +3 -3
  55. package/dist/entries/presets.cjs +49 -26
  56. package/dist/entries/presets.d.cts +53 -1
  57. package/dist/entries/presets.d.ts +53 -1
  58. package/dist/entries/presets.js +4 -1
  59. package/dist/entries/prompt-builder.cjs +135 -98
  60. package/dist/entries/prompt-builder.d.cts +22 -11
  61. package/dist/entries/prompt-builder.d.ts +22 -11
  62. package/dist/entries/prompt-builder.js +4 -3
  63. package/dist/entries/prompt-fields.cjs +41 -40
  64. package/dist/entries/prompt-fields.d.cts +2 -1
  65. package/dist/entries/prompt-fields.d.ts +2 -1
  66. package/dist/entries/prompt-fields.js +2 -1
  67. package/dist/index.cjs +339 -273
  68. package/dist/index.d.cts +4 -4
  69. package/dist/index.d.ts +4 -4
  70. package/dist/index.js +11 -9
  71. package/dist/{subject-registry-BUswuEVD.d.cts → subject-registry-CQi_CZfJ.d.cts} +78 -9
  72. package/dist/{subject-registry-D7V8PEG-.d.ts → subject-registry-DFiGx49v.d.ts} +78 -9
  73. package/package.json +2 -2
  74. package/src/__tests__/assemble-image-input-style-references.test.ts +173 -0
  75. package/src/__tests__/catalog-id-guard.test.ts +30 -0
  76. package/src/__tests__/factory-preset-previews.test.ts +123 -0
  77. package/src/__tests__/factory-preset-references.test.ts +222 -0
  78. package/src/__tests__/factory-presets-prototype-keys.test.ts +43 -0
  79. package/src/__tests__/frame-reference-slots.test.ts +43 -0
  80. package/src/__tests__/gemini-omni-inputs.test.ts +12 -10
  81. package/src/__tests__/provider-prompt-doctrine.test.ts +14 -0
  82. package/src/__tests__/user-direction-refs.test.ts +180 -0
  83. package/src/__tests__/veo-i2v-inputs.test.ts +16 -11
  84. package/src/assemble-image-input.ts +114 -13
  85. package/src/catalog-id-guard.ts +18 -2
  86. package/src/color-names.ts +192 -0
  87. package/src/direction-registry.ts +66 -5
  88. package/src/entries/assembly.ts +1 -0
  89. package/src/entries/prompt-builder.ts +2 -0
  90. package/src/factory-presets/generate-image.ts +29 -0
  91. package/src/factory-presets/index.ts +6 -1
  92. package/src/factory-presets/preview-files.generated.ts +4 -0
  93. package/src/factory-presets/previews.ts +40 -0
  94. package/src/factory-presets/references.ts +81 -0
  95. package/src/factory-presets/shared-image.ts +4 -0
  96. package/src/factory-presets/types.ts +8 -0
  97. package/src/frame-reference-slots.ts +92 -0
  98. package/src/gemini-omni-inputs.ts +23 -22
  99. package/src/image-reference-doctrine.ts +3 -3
  100. package/src/image-token-pattern.ts +13 -0
  101. package/src/node-prompt-fields.ts +5 -3
  102. package/src/own-entry.ts +11 -0
  103. package/src/prompt-builder.ts +4 -5
  104. package/src/prompt-style-section.ts +3 -3
  105. package/src/prompt-wizard-categories.ts +2 -0
  106. package/src/provider-prompt-doctrine.ts +45 -3
  107. package/src/ref-binding.ts +28 -3
  108. package/src/resolve-prompt.ts +2 -1
  109. package/src/seedance-2-inputs.ts +15 -40
  110. package/src/user-direction-refs.ts +110 -0
  111. package/src/veo-i2v-inputs.ts +24 -17
  112. package/src/video-reference-resolver.ts +1 -1
  113. package/dist/chunk-4FDNVNJE.js.map +0 -1
  114. package/dist/chunk-7XKHDXCL.cjs.map +0 -1
  115. package/dist/chunk-CEPVQQVO.js.map +0 -1
  116. package/dist/chunk-CVPB2N3Z.cjs.map +0 -1
  117. package/dist/chunk-HRBBNODV.js.map +0 -1
  118. package/dist/chunk-JKCR6WRZ.cjs.map +0 -1
  119. package/dist/chunk-KIYNOOPJ.js.map +0 -1
  120. package/dist/chunk-LVSH7K7R.cjs.map +0 -1
  121. package/dist/chunk-MENBHEAY.cjs.map +0 -1
  122. package/dist/chunk-NO6XHX4R.js.map +0 -1
  123. package/dist/chunk-QBEZMR2F.js.map +0 -1
  124. package/dist/chunk-QDEWBBUR.js.map +0 -1
  125. package/dist/chunk-TLVX5PXD.cjs.map +0 -1
  126. package/dist/chunk-UJKFHPZ7.js +0 -37
  127. package/dist/chunk-UJKFHPZ7.js.map +0 -1
  128. package/dist/chunk-W5SCZIOB.cjs +0 -43
  129. package/dist/chunk-W5SCZIOB.cjs.map +0 -1
  130. package/dist/chunk-ZFIXQRBZ.cjs.map +0 -1
@@ -1,17 +1,18 @@
1
1
  'use strict';
2
2
 
3
- var chunkMENBHEAY_cjs = require('./chunk-MENBHEAY.cjs');
3
+ var chunkWRM52ZBN_cjs = require('./chunk-WRM52ZBN.cjs');
4
4
  var chunkXUZXBY75_cjs = require('./chunk-XUZXBY75.cjs');
5
5
  var chunk2NJTFCKQ_cjs = require('./chunk-2NJTFCKQ.cjs');
6
- var chunkLK2CZK5U_cjs = require('./chunk-LK2CZK5U.cjs');
6
+ var chunkPWWM7Q3T_cjs = require('./chunk-PWWM7Q3T.cjs');
7
+ var chunk2P26SZX5_cjs = require('./chunk-2P26SZX5.cjs');
7
8
  var chunkMQEXFCNU_cjs = require('./chunk-MQEXFCNU.cjs');
8
9
  var entities = require('@nodaro/shared/entities');
9
10
  var models = require('@nodaro/shared/models');
10
11
  var video = require('@nodaro/shared/video');
11
12
 
12
13
  // src/ref-binding.ts
13
- function identityRefsSentence(firstOrdinal, lastOrdinal) {
14
- return firstOrdinal === lastOrdinal ? `${REF_BINDING.ordinal(firstOrdinal)} is an identity reference for this shot's subjects \u2014 match its subject's exact appearance; it is not a frame.` : `${REF_BINDING.ordinal(firstOrdinal)} through ${REF_BINDING.ordinal(lastOrdinal)} are identity references for this shot's subjects \u2014 match each subject's exact appearance; they are not frames.`;
14
+ function identityRefsSentence(firstOrdinal, lastOrdinal, ordinal = REF_BINDING.ordinal) {
15
+ return firstOrdinal === lastOrdinal ? `${ordinal(firstOrdinal)} is an identity reference for this shot's subjects \u2014 match its subject's exact appearance; it is not a frame.` : `${ordinal(firstOrdinal)} through ${ordinal(lastOrdinal)} are identity references for this shot's subjects \u2014 match each subject's exact appearance; they are not frames.`;
15
16
  }
16
17
  var REF_BINDING = {
17
18
  image: (label, n) => `the ${label} from @image_${n}`,
@@ -21,6 +22,14 @@ var REF_BINDING = {
21
22
  ordinal: (n) => `@image_${n}`,
22
23
  frame: (n, role) => `Use @image_${n} as the ${role} (${role === "opening" ? "first" : "last"}) frame of the video.`
23
24
  };
25
+ function imageBindingFor(syntax) {
26
+ if (syntax === "@image_N") return { ordinal: REF_BINDING.ordinal, frame: REF_BINDING.frame };
27
+ const ordinal = syntax === "@image(n)" ? (n) => `@image(${n})` : (n) => `[Image ${n}]`;
28
+ return {
29
+ ordinal,
30
+ frame: (n, role) => `Use ${ordinal(n)} as the ${role} (${role === "opening" ? "first" : "last"}) frame of the video.`
31
+ };
32
+ }
24
33
  var SEEDANCE_VIDEO_EDIT_PREFIX = "edit {video:1} as follows:\n";
25
34
  function buildSeedanceVideoEditPrompt(prompt) {
26
35
  const body = (prompt ?? "").trim();
@@ -62,11 +71,11 @@ function resolveRefIdTokens(prompt, ctx) {
62
71
  var REFERENCE_TOKEN_RE = /\{(image|video|audio):(\d+)(?::([a-zA-Z0-9_ -]+))?\}/gi;
63
72
  function resolveReferenceTokens(prompt, counts) {
64
73
  if (!prompt) return prompt;
65
- return chunkMENBHEAY_cjs.tidyReferenceTokenGaps(
74
+ return chunkWRM52ZBN_cjs.tidyReferenceTokenGaps(
66
75
  prompt.replace(REFERENCE_TOKEN_RE, (_match, rawKind, nStr, label) => {
67
76
  const kind = rawKind.toLowerCase();
68
77
  const n = parseInt(nStr, 10);
69
- if (n < 1 || n > counts[kind]) return chunkMENBHEAY_cjs.unboundReferenceTokenText(label);
78
+ if (n < 1 || n > counts[kind]) return chunkWRM52ZBN_cjs.unboundReferenceTokenText(label);
70
79
  if (label) return REF_BINDING[kind](label, n);
71
80
  return `@${kind}_${n}`;
72
81
  })
@@ -125,7 +134,7 @@ function resolveVideoCharacterMentionsHybrid(prompt, tokens, refs, offset) {
125
134
  const binding = bindingFor(m.url);
126
135
  const lock = chunk2NJTFCKQ_cjs.buildIdentityLockLine(chunk2NJTFCKQ_cjs.withForcedIdentityLock(ref, lockOverrideByUrl.get(m.url)), binding);
127
136
  if (lock) lockLines.push(lock);
128
- const overrideLine = chunkMENBHEAY_cjs.referenceDescriptionLine(binding, ref.descriptionOverride);
137
+ const overrideLine = chunkWRM52ZBN_cjs.referenceDescriptionLine(binding, ref.descriptionOverride);
129
138
  if (overrideLine) elementDirectives.push(overrideLine);
130
139
  const inject = ref.elementInjection?.trim();
131
140
  if (inject) elementDirectives.push(inject);
@@ -153,8 +162,8 @@ function resolveVideoReferenceCore(args) {
153
162
  audio: args.audioRefCount ?? 0
154
163
  });
155
164
  const describedAndCaptionLines = [
156
- ...chunkMENBHEAY_cjs.renderDescribedReferenceLines(args.describedReferences),
157
- ...chunkMENBHEAY_cjs.renderReferenceCaptionLines(args.videoCaptions, args.audioCaptions, {
165
+ ...chunkWRM52ZBN_cjs.renderDescribedReferenceLines(args.describedReferences),
166
+ ...chunkWRM52ZBN_cjs.renderReferenceCaptionLines(args.videoCaptions, args.audioCaptions, {
158
167
  video: args.videoRefCount ?? 0,
159
168
  audio: args.audioRefCount ?? 0
160
169
  })
@@ -191,7 +200,7 @@ function resolveVideoReferenceCore(args) {
191
200
  // Described references and rail captions are the ONE thing this branch can
192
201
  // still contribute: they need no seat, so a request that carries only them
193
202
  // (a story landing before any entity exists) reaches the model here.
194
- prompt: describedAndCaptionLines.length > 0 ? chunkMENBHEAY_cjs.appendReferenceLines(resolved2 ?? "", describedAndCaptionLines, args.hybridRoles === true ? "hybrid" : "legacy") : resolved2,
203
+ prompt: describedAndCaptionLines.length > 0 ? chunkWRM52ZBN_cjs.appendReferenceLines(resolved2 ?? "", describedAndCaptionLines, args.hybridRoles === true ? "hybrid" : "legacy") : resolved2,
195
204
  additionalUrls: [...leadingRefUrls]
196
205
  };
197
206
  }
@@ -212,7 +221,7 @@ function resolveVideoReferenceCore(args) {
212
221
  mentionLockLines = h.lockLines;
213
222
  mentionElementDirectives = h.elementDirectives;
214
223
  } else {
215
- resolved = mentionTokens.length > 0 ? chunkMENBHEAY_cjs.resolveCharacterMentions(promptForResolution, mentionTokens, wiredCharRefs) : { prompt: promptForResolution, additionalUrls: [], mentionedCharacterSlugs: /* @__PURE__ */ new Set() };
224
+ resolved = mentionTokens.length > 0 ? chunkWRM52ZBN_cjs.resolveCharacterMentions(promptForResolution, mentionTokens, wiredCharRefs) : { prompt: promptForResolution, additionalUrls: [], mentionedCharacterSlugs: /* @__PURE__ */ new Set() };
216
225
  }
217
226
  const fallbackUrls = [];
218
227
  const fallbackDirectiveLines = [];
@@ -249,7 +258,7 @@ function resolveVideoReferenceCore(args) {
249
258
  canonicalPhrases.push(entities.roleToPhrase(entities.resolveDefaultRole(r.defaultRole, r.defaultUsageMode, r.source), binding));
250
259
  const lock = chunk2NJTFCKQ_cjs.buildIdentityLockLine(r, binding);
251
260
  if (lock) canonicalLockLines.push(lock);
252
- const overrideLine = chunkMENBHEAY_cjs.referenceDescriptionLine(binding, r.descriptionOverride);
261
+ const overrideLine = chunkWRM52ZBN_cjs.referenceDescriptionLine(binding, r.descriptionOverride);
253
262
  if (overrideLine) canonicalElementDirectives.push(overrideLine);
254
263
  const inject = r.elementInjection?.trim();
255
264
  if (inject) canonicalElementDirectives.push(inject);
@@ -381,7 +390,7 @@ function resolveVideoReferenceCore(args) {
381
390
  const lockBlock = lockLines.length > 0 ? `${lockLines.join("\n")}
382
391
 
383
392
  ` : "";
384
- finalPrompt = `${lockBlock}${chunkMENBHEAY_cjs.insertBeforeStyleSection(finalPrompt, trailingLines)}`;
393
+ finalPrompt = `${lockBlock}${chunkWRM52ZBN_cjs.insertBeforeStyleSection(finalPrompt, trailingLines)}`;
385
394
  } else {
386
395
  const allFallbackLines = [...fallbackDirectiveLines, ...extraDirectiveLines];
387
396
  if (allFallbackLines.length > 0) {
@@ -431,7 +440,7 @@ ${finalPrompt}` : block;
431
440
  merged.push(u);
432
441
  }
433
442
  }
434
- finalPrompt = chunkMENBHEAY_cjs.appendReferenceLines(
443
+ finalPrompt = chunkWRM52ZBN_cjs.appendReferenceLines(
435
444
  finalPrompt,
436
445
  describedAndCaptionLines,
437
446
  hybrid ? "hybrid" : "legacy"
@@ -459,7 +468,7 @@ ${finalPrompt}` : block;
459
468
  });
460
469
  }
461
470
  }
462
- const reordered = chunkMENBHEAY_cjs.applyReferenceOrderToVideo(assetUrls, finalPrompt, refsForOrdering, referenceOrder, void 0, offset);
471
+ const reordered = chunkWRM52ZBN_cjs.applyReferenceOrderToVideo(assetUrls, finalPrompt, refsForOrdering, referenceOrder, void 0, offset);
463
472
  return {
464
473
  prompt: resolveReferenceTokens(reordered.prompt, tokenCounts(merged.length)),
465
474
  additionalUrls: [...leadingRefUrls, ...reordered.urls]
@@ -513,7 +522,7 @@ function composeSoundHintFromConnections(consumer, consumerType, ctx) {
513
522
  continue;
514
523
  }
515
524
  }
516
- const hint = chunkLK2CZK5U_cjs.getParameterPromptHint(src);
525
+ const hint = chunkPWWM7Q3T_cjs.getParameterPromptHint(src);
517
526
  if (hint) acceptedHints.push(hint);
518
527
  if ((consumerType === "suno-generate" || consumerType === "generate-music") && t === "voice-character" && src.data) {
519
528
  const gender = src.data.gender;
@@ -618,35 +627,78 @@ function assembleSunoInput(input) {
618
627
  ...input.persona ?? {}
619
628
  };
620
629
  }
621
-
622
- // src/assemble-image-input.ts
623
- function renderImageHintPieces(subject, direction, structured) {
630
+ function renderImageHintPieces(subject, direction, structured, directionRefs) {
624
631
  return {
625
632
  hintClauses: [
626
- ...chunkMENBHEAY_cjs.asBodyClauses(
627
- chunkMENBHEAY_cjs.renderSubjectHints(subject, {
633
+ ...chunkWRM52ZBN_cjs.asBodyClauses(
634
+ chunkWRM52ZBN_cjs.renderSubjectHints(subject, {
628
635
  surface: "image",
629
- mode: chunkMENBHEAY_cjs.SUBJECT_IMAGE_HINT_MODE_DEFAULT
636
+ mode: chunkWRM52ZBN_cjs.SUBJECT_IMAGE_HINT_MODE_DEFAULT
630
637
  })
631
638
  ),
632
- ...chunkMENBHEAY_cjs.partitionStyleClauses(direction, {
639
+ ...chunkWRM52ZBN_cjs.partitionStyleClauses(direction, {
633
640
  surface: "image",
634
- mode: chunkMENBHEAY_cjs.IMAGE_HINT_MODE_DEFAULT
641
+ mode: chunk2P26SZX5_cjs.IMAGE_HINT_MODE_DEFAULT,
642
+ ...directionRefs !== void 0 ? { refs: directionRefs } : {}
635
643
  })
636
644
  ].filter((c) => c.text.length > 0),
637
- structuredFragment: structured ? chunkMENBHEAY_cjs.renderStructuredFields(structured) : ""
645
+ structuredFragment: structured ? chunkWRM52ZBN_cjs.renderStructuredFields(structured) : ""
638
646
  };
639
647
  }
640
648
  function composePromptText(userPrompt, pieces, keptHintClauses) {
641
- return chunkMENBHEAY_cjs.composeSectionedPrompt(
649
+ return chunkWRM52ZBN_cjs.composeSectionedPrompt(
642
650
  userPrompt,
643
651
  pieces.hintClauses.slice(0, keptHintClauses),
644
652
  pieces.structuredFragment
645
653
  );
646
654
  }
647
655
  function assembleImageInput(input) {
648
- const pieces = renderImageHintPieces(input.subject, input.direction, input.structured);
649
- const assembleWith = (keptHintClauses) => chunkMENBHEAY_cjs.buildImagePromptWithOverflow({
656
+ const style = input.styleReferences;
657
+ const result = style !== void 0 && style.length > 0 ? fillStyleReferences(input, style) : assembleOnce(input);
658
+ if (input.throwOnEmpty && !result.prompt.trim()) {
659
+ throw new Error(
660
+ "No prompt \u2014 type one, bind a character, or pick a cinematography direction"
661
+ );
662
+ }
663
+ return result;
664
+ }
665
+ function fillStyleReferences(input, style) {
666
+ const base = assembleOnce(input);
667
+ const own = base.referenceImageUrls ?? [];
668
+ const seats = models.imageReferenceLimit(input.provider) - own.length;
669
+ const seen = new Set(own);
670
+ const candidates = [];
671
+ for (const s of style) {
672
+ if (typeof s.url !== "string" || s.url.length === 0 || seen.has(s.url)) continue;
673
+ seen.add(s.url);
674
+ candidates.push(s);
675
+ }
676
+ for (let k = Math.min(seats, candidates.length); k > 0; k--) {
677
+ const extras = candidates.slice(0, k).map(styleConnectedReference);
678
+ const filled = assembleOnce({
679
+ ...input,
680
+ connectedReferences: [...input.connectedReferences ?? [], ...extras]
681
+ });
682
+ const urls = filled.referenceImageUrls ?? [];
683
+ const keepsOwn = urls.length === own.length + k && own.every((url, i) => urls[i] === url) && extras.every((ref, j) => urls[own.length + j] === ref.url);
684
+ if (keepsOwn) return { ...filled, styleReferencesSent: k };
685
+ }
686
+ return { ...base, styleReferencesSent: 0 };
687
+ }
688
+ function styleConnectedReference(s, index) {
689
+ return {
690
+ id: `style-reference-${index + 1}`,
691
+ defaultName: `Style reference ${index + 1}`,
692
+ source: "manual",
693
+ url: s.url,
694
+ isExtraRef: true,
695
+ defaultRole: "style",
696
+ description: chunk2P26SZX5_cjs.styleReferenceDescription(index, s.caption)
697
+ };
698
+ }
699
+ function assembleOnce(input) {
700
+ const pieces = renderImageHintPieces(input.subject, input.direction, input.structured, input.directionRefs);
701
+ const assembleWith = (keptHintClauses) => chunkWRM52ZBN_cjs.buildImagePromptWithOverflow({
650
702
  prompt: composePromptText(input.userPrompt, pieces, keptHintClauses),
651
703
  provider: input.provider,
652
704
  ...input.connectedReferences !== void 0 ? { connectedReferences: input.connectedReferences } : {},
@@ -674,7 +726,7 @@ function assembleImageInput(input) {
674
726
  let kept = pieces.hintClauses.length;
675
727
  let fitted = assembleWith(kept);
676
728
  if (fitted.overflowChars > 0) {
677
- const costs = chunkMENBHEAY_cjs.sectionedClauseCosts(
729
+ const costs = chunkWRM52ZBN_cjs.sectionedClauseCosts(
678
730
  input.userPrompt,
679
731
  pieces.hintClauses,
680
732
  pieces.structuredFragment
@@ -686,30 +738,25 @@ function assembleImageInput(input) {
686
738
  }
687
739
  }
688
740
  const { overflowChars, ...result } = fitted;
689
- if (input.throwOnEmpty && !result.prompt.trim()) {
690
- throw new Error(
691
- "No prompt \u2014 type one, bind a character, or pick a cinematography direction"
692
- );
693
- }
694
741
  return result;
695
742
  }
696
743
 
697
744
  // src/assemble-video-input.ts
698
745
  function composeVideoPromptText(userPrompt, direction, structured, opts) {
699
746
  const hintClauses = [
700
- ...chunkMENBHEAY_cjs.asBodyClauses(
701
- chunkMENBHEAY_cjs.renderSubjectHints(opts?.subject, {
747
+ ...chunkWRM52ZBN_cjs.asBodyClauses(
748
+ chunkWRM52ZBN_cjs.renderSubjectHints(opts?.subject, {
702
749
  surface: "video",
703
- mode: opts?.subjectHintMode ?? chunkMENBHEAY_cjs.SUBJECT_VIDEO_HINT_MODE_DEFAULT
750
+ mode: opts?.subjectHintMode ?? chunkWRM52ZBN_cjs.SUBJECT_VIDEO_HINT_MODE_DEFAULT
704
751
  })
705
752
  ),
706
- ...chunkMENBHEAY_cjs.partitionStyleClauses(direction, {
753
+ ...chunkWRM52ZBN_cjs.partitionStyleClauses(direction, {
707
754
  surface: "video",
708
- mode: opts?.hintMode ?? chunkMENBHEAY_cjs.VIDEO_HINT_MODE_DEFAULT
755
+ mode: opts?.hintMode ?? chunk2P26SZX5_cjs.VIDEO_HINT_MODE_DEFAULT
709
756
  })
710
757
  ].filter((c) => c.text.length > 0);
711
- const structuredFragment = structured ? chunkMENBHEAY_cjs.renderStructuredFields(structured) : "";
712
- const composeWith = (kept2) => chunkMENBHEAY_cjs.composeSectionedPrompt(userPrompt, hintClauses.slice(0, kept2), structuredFragment);
758
+ const structuredFragment = structured ? chunkWRM52ZBN_cjs.renderStructuredFields(structured) : "";
759
+ const composeWith = (kept2) => chunkWRM52ZBN_cjs.composeSectionedPrompt(userPrompt, hintClauses.slice(0, kept2), structuredFragment);
713
760
  const cap = opts?.cap;
714
761
  if (cap === void 0) return composeWith(hintClauses.length);
715
762
  const frame = opts?.frame ?? ((body2) => body2);
@@ -717,7 +764,7 @@ function composeVideoPromptText(userPrompt, direction, structured, opts) {
717
764
  let body = composeWith(kept);
718
765
  let framedLength = frame(body)?.length ?? 0;
719
766
  if (framedLength <= cap) return body;
720
- const costs = chunkMENBHEAY_cjs.sectionedClauseCosts(userPrompt, hintClauses, structuredFragment);
767
+ const costs = chunkWRM52ZBN_cjs.sectionedClauseCosts(userPrompt, hintClauses, structuredFragment);
721
768
  const texts = hintClauses.map((c) => c.text);
722
769
  while (framedLength > cap && kept > 0) {
723
770
  kept = chunkXUZXBY75_cjs.keepableDirectionHints(texts, kept, framedLength - cap, costs);
@@ -726,15 +773,50 @@ function composeVideoPromptText(userPrompt, direction, structured, opts) {
726
773
  }
727
774
  return body;
728
775
  }
776
+
777
+ // src/frame-reference-slots.ts
778
+ function placeFramesAfterReferences(args) {
779
+ const refs = (args.refImageUrls ?? []).filter((u) => typeof u === "string" && u.trim().length > 0);
780
+ const frameCount = (args.firstFrameUrl ? 1 : 0) + (args.lastFrameUrl ? 1 : 0);
781
+ const kept = refs.slice(0, Math.max(0, args.imageCap - frameCount));
782
+ const droppedRefImages = refs.length - kept.length;
783
+ const imageUrls = [...kept];
784
+ let firstFrameOrdinal = 0;
785
+ let lastFrameOrdinal = 0;
786
+ if (args.firstFrameUrl) {
787
+ imageUrls.push(args.firstFrameUrl);
788
+ firstFrameOrdinal = imageUrls.length;
789
+ }
790
+ if (args.lastFrameUrl) {
791
+ imageUrls.push(args.lastFrameUrl);
792
+ lastFrameOrdinal = imageUrls.length;
793
+ }
794
+ const syntax = args.syntax ?? "@image_N";
795
+ const binding = imageBindingFor(syntax);
796
+ const promptBindsStart = syntax === "@image_N" && promptBindsFirstFrame(args.prompt);
797
+ let frameSentence = "";
798
+ if (promptBindsStart && firstFrameOrdinal > 0 && lastFrameOrdinal === 0) ; else if (firstFrameOrdinal > 0 && lastFrameOrdinal > 0) {
799
+ frameSentence = `Use ${binding.ordinal(firstFrameOrdinal)} as the opening (first) frame and ${binding.ordinal(lastFrameOrdinal)} as the closing (last) frame of the video.`;
800
+ } else if (firstFrameOrdinal > 0) {
801
+ frameSentence = binding.frame(firstFrameOrdinal, "opening");
802
+ } else if (lastFrameOrdinal > 0) {
803
+ frameSentence = binding.frame(lastFrameOrdinal, "closing");
804
+ }
805
+ const identitySentence = args.bindIdentities && kept.length > 0 && frameCount > 0 ? identityRefsSentence(1, kept.length, binding.ordinal) : "";
806
+ const promptSuffix = [frameSentence, identitySentence].filter(Boolean).join(" ");
807
+ return { imageUrls, promptSuffix, droppedRefImages, firstFrameOrdinal, lastFrameOrdinal };
808
+ }
809
+ function promptBindsFirstFrame(prompt) {
810
+ if (!prompt) return false;
811
+ return /@image_\d+\s+as\s+the\s+(first|opening)\s*(\(first\))?\s*frame/i.test(prompt);
812
+ }
813
+
814
+ // src/seedance-2-inputs.ts
729
815
  var clean = (u) => {
730
816
  const t = u?.trim();
731
817
  return t && t.length > 0 ? t : void 0;
732
818
  };
733
819
  var cleanList = (xs) => (xs ?? []).map(clean).filter((x) => x !== void 0);
734
- function promptBindsFirstFrame(prompt) {
735
- if (!prompt) return false;
736
- return /@image_\d+\s+as\s+the\s+(first|opening)\s*(\(first\))?\s*frame/i.test(prompt);
737
- }
738
820
  function resolveSeedance2Inputs(args) {
739
821
  const limits = args.limits ?? models.SEEDANCE_2_REF_LIMITS;
740
822
  const firstFrameUrl = clean(args.firstFrameUrl);
@@ -750,30 +832,16 @@ function resolveSeedance2Inputs(args) {
750
832
  }
751
833
  return { mode: "first-frame", firstFrameUrl, lastFrameUrl: void 0, referenceImageUrls: [], referenceVideoUrls: [], referenceAudioUrls: [], promptSuffix: "", droppedRefImages: 0 };
752
834
  }
753
- const frameCount = (firstFrameUrl ? 1 : 0) + (lastFrameUrl ? 1 : 0);
754
- const userImageSlots = Math.max(0, limits.images - frameCount);
755
- const keptUserImages = refImages.slice(0, userImageSlots);
756
- const droppedRefImages = refImages.length - keptUserImages.length;
757
- const referenceImageUrls = [...keptUserImages];
758
- let firstOrdinal = 0;
759
- let lastOrdinal = 0;
760
- if (firstFrameUrl) {
761
- referenceImageUrls.push(firstFrameUrl);
762
- firstOrdinal = referenceImageUrls.length;
763
- }
764
- if (lastFrameUrl) {
765
- referenceImageUrls.push(lastFrameUrl);
766
- lastOrdinal = referenceImageUrls.length;
767
- }
768
- let promptSuffix = "";
769
- const suppressFrameSentence = promptBindsFirstFrame(args.prompt);
770
- if (suppressFrameSentence && firstOrdinal > 0 && lastOrdinal === 0) ; else if (firstOrdinal > 0 && lastOrdinal > 0) {
771
- promptSuffix = `Use ${REF_BINDING.ordinal(firstOrdinal)} as the opening (first) frame and ${REF_BINDING.ordinal(lastOrdinal)} as the closing (last) frame of the video.`;
772
- } else if (firstOrdinal > 0) {
773
- promptSuffix = REF_BINDING.frame(firstOrdinal, "opening");
774
- } else if (lastOrdinal > 0) {
775
- promptSuffix = REF_BINDING.frame(lastOrdinal, "closing");
776
- }
835
+ const placed = placeFramesAfterReferences({
836
+ prompt: args.prompt,
837
+ firstFrameUrl,
838
+ lastFrameUrl,
839
+ refImageUrls: refImages,
840
+ imageCap: limits.images
841
+ });
842
+ const referenceImageUrls = placed.imageUrls;
843
+ const promptSuffix = placed.promptSuffix;
844
+ const droppedRefImages = placed.droppedRefImages;
777
845
  return {
778
846
  mode: "reference",
779
847
  firstFrameUrl: void 0,
@@ -790,16 +858,18 @@ function geminiOmniInputSlots(provider) {
790
858
  return models.VIDEO_REF_LIMITS_BY_PROVIDER[provider ?? DEFAULT_GEMINI_OMNI_PROVIDER]?.images ?? 7;
791
859
  }
792
860
  function resolveGeminiOmniI2vInputs(args) {
793
- const refs = (args.refImageUrls ?? []).filter((u) => typeof u === "string" && u.length > 0);
794
861
  const slots = geminiOmniInputSlots(args.provider) - (args.videoConnected ? 2 : 0);
795
- const refSlots = Math.max(0, slots - 1);
796
- const kept = refs.slice(0, refSlots);
797
- const droppedRefImages = refs.length - kept.length;
798
- const imageUrls = [args.firstFrameUrl, ...kept];
799
- if (kept.length === 0) return { imageUrls, promptSuffix: "", droppedRefImages };
800
- const frameSentence = promptBindsFirstFrame(args.prompt) ? "" : REF_BINDING.frame(1, "opening");
801
- const promptSuffix = [frameSentence, identityRefsSentence(2, kept.length + 1)].filter(Boolean).join(" ");
802
- return { imageUrls, promptSuffix, droppedRefImages };
862
+ const placed = placeFramesAfterReferences({
863
+ prompt: args.prompt,
864
+ firstFrameUrl: args.firstFrameUrl,
865
+ refImageUrls: args.refImageUrls,
866
+ imageCap: Math.max(1, slots),
867
+ bindIdentities: true
868
+ });
869
+ if (placed.imageUrls.length === 1) {
870
+ return { imageUrls: placed.imageUrls, promptSuffix: "", droppedRefImages: placed.droppedRefImages };
871
+ }
872
+ return { imageUrls: placed.imageUrls, promptSuffix: placed.promptSuffix, droppedRefImages: placed.droppedRefImages };
803
873
  }
804
874
 
805
875
  // src/veo-i2v-inputs.ts
@@ -814,15 +884,20 @@ function resolveVeoI2vInputs(args) {
814
884
  droppedEndFrame: false
815
885
  };
816
886
  }
817
- const kept = refs.slice(0, VEO_INGREDIENT_SLOTS - 1);
818
- const droppedRefImages = refs.length - kept.length;
819
- const frameSentence = promptBindsFirstFrame(args.prompt) ? "" : REF_BINDING.frame(1, "opening");
887
+ const placed = placeFramesAfterReferences({
888
+ prompt: args.prompt,
889
+ firstFrameUrl: args.firstFrameUrl,
890
+ lastFrameUrl: args.endFrameUrl,
891
+ refImageUrls: refs,
892
+ imageCap: VEO_INGREDIENT_SLOTS,
893
+ bindIdentities: true
894
+ });
820
895
  return {
821
- imageUrls: [args.firstFrameUrl, ...kept],
896
+ imageUrls: placed.imageUrls,
822
897
  generationType: "REFERENCE_2_VIDEO",
823
- promptSuffix: [frameSentence, identityRefsSentence(2, kept.length + 1)].filter(Boolean).join(" "),
824
- droppedRefImages,
825
- droppedEndFrame: Boolean(args.endFrameUrl)
898
+ promptSuffix: placed.promptSuffix,
899
+ droppedRefImages: placed.droppedRefImages,
900
+ droppedEndFrame: false
826
901
  };
827
902
  }
828
903
 
@@ -902,6 +977,8 @@ exports.composeSoundHintFromConnections = composeSoundHintFromConnections;
902
977
  exports.composeVideoPromptText = composeVideoPromptText;
903
978
  exports.getEffectiveSunoCustomMode = getEffectiveSunoCustomMode;
904
979
  exports.identityRefsSentence = identityRefsSentence;
980
+ exports.imageBindingFor = imageBindingFor;
981
+ exports.placeFramesAfterReferences = placeFramesAfterReferences;
905
982
  exports.planFrameDelivery = planFrameDelivery;
906
983
  exports.promptBindsFirstFrame = promptBindsFirstFrame;
907
984
  exports.resolveGeminiOmniI2vInputs = resolveGeminiOmniI2vInputs;
@@ -911,5 +988,5 @@ exports.resolveSeedance2Inputs = resolveSeedance2Inputs;
911
988
  exports.resolveVeoI2vInputs = resolveVeoI2vInputs;
912
989
  exports.resolveVideoReferenceCore = resolveVideoReferenceCore;
913
990
  exports.truncateForField = truncateForField;
914
- //# sourceMappingURL=chunk-LVSH7K7R.cjs.map
915
- //# sourceMappingURL=chunk-LVSH7K7R.cjs.map
991
+ //# sourceMappingURL=chunk-C3NHNECH.cjs.map
992
+ //# sourceMappingURL=chunk-C3NHNECH.cjs.map