@nodaro/prompts 1.39.0 → 1.41.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 (66) hide show
  1. package/dist/{chunk-XIWWDGT5.cjs → chunk-2EW5B7ZV.cjs} +7 -7
  2. package/dist/{chunk-XIWWDGT5.cjs.map → chunk-2EW5B7ZV.cjs.map} +1 -1
  3. package/dist/{chunk-22KZOAGL.cjs → chunk-C3NHNECH.cjs} +86 -48
  4. package/dist/chunk-C3NHNECH.cjs.map +1 -0
  5. package/dist/{chunk-XU54YJXQ.js → chunk-HQTHDTHN.js} +85 -49
  6. package/dist/chunk-HQTHDTHN.js.map +1 -0
  7. package/dist/{chunk-KUBZVWME.cjs → chunk-LXPKTI2K.cjs} +12 -5
  8. package/dist/chunk-LXPKTI2K.cjs.map +1 -0
  9. package/dist/{chunk-3INXNDV7.cjs → chunk-LZ53F5BN.cjs} +8 -8
  10. package/dist/chunk-LZ53F5BN.cjs.map +1 -0
  11. package/dist/{chunk-7XMTVYS5.js → chunk-N6VMPG5S.js} +12 -6
  12. package/dist/chunk-N6VMPG5S.js.map +1 -0
  13. package/dist/{chunk-XRLOMTBZ.js → chunk-QBUSJGV3.js} +84 -5
  14. package/dist/chunk-QBUSJGV3.js.map +1 -0
  15. package/dist/{chunk-6MPZHFIS.js → chunk-RB2F5JQF.js} +5 -5
  16. package/dist/chunk-RB2F5JQF.js.map +1 -0
  17. package/dist/{chunk-NMWKXAYA.cjs → chunk-XTOSNRWT.cjs} +84 -5
  18. package/dist/chunk-XTOSNRWT.cjs.map +1 -0
  19. package/dist/{chunk-Z3SZXWRU.js → chunk-YS6HOWMW.js} +3 -3
  20. package/dist/{chunk-Z3SZXWRU.js.map → chunk-YS6HOWMW.js.map} +1 -1
  21. package/dist/entries/assembly.cjs +30 -22
  22. package/dist/entries/assembly.d.cts +90 -34
  23. package/dist/entries/assembly.d.ts +90 -34
  24. package/dist/entries/assembly.js +1 -1
  25. package/dist/entries/doctrine.cjs +46 -46
  26. package/dist/entries/doctrine.js +1 -1
  27. package/dist/entries/presets.cjs +32 -32
  28. package/dist/entries/presets.d.cts +2 -0
  29. package/dist/entries/presets.d.ts +2 -0
  30. package/dist/entries/presets.js +2 -2
  31. package/dist/entries/prompt-fields.cjs +26 -26
  32. package/dist/entries/prompt-fields.d.cts +2 -1
  33. package/dist/entries/prompt-fields.d.ts +2 -1
  34. package/dist/entries/prompt-fields.js +2 -2
  35. package/dist/index.cjs +133 -125
  36. package/dist/index.d.cts +1 -1
  37. package/dist/index.d.ts +1 -1
  38. package/dist/index.js +5 -5
  39. package/package.json +2 -2
  40. package/src/__tests__/factory-presets-prototype-keys.test.ts +43 -0
  41. package/src/__tests__/frame-reference-slots.test.ts +43 -0
  42. package/src/__tests__/gemini-omni-inputs.test.ts +12 -10
  43. package/src/__tests__/provider-prompt-doctrine.test.ts +14 -0
  44. package/src/__tests__/veo-i2v-inputs.test.ts +16 -11
  45. package/src/entries/assembly.ts +1 -0
  46. package/src/factory-presets/index.ts +4 -1
  47. package/src/factory-presets/references.ts +2 -1
  48. package/src/frame-reference-slots.ts +92 -0
  49. package/src/gemini-omni-inputs.ts +23 -22
  50. package/src/node-prompt-fields.ts +5 -3
  51. package/src/own-entry.ts +11 -0
  52. package/src/prompt-wizard-categories.ts +6 -0
  53. package/src/provider-prompt-doctrine.ts +89 -3
  54. package/src/ref-binding.ts +28 -3
  55. package/src/resolve-prompt.ts +2 -1
  56. package/src/seedance-2-inputs.ts +15 -40
  57. package/src/veo-i2v-inputs.ts +24 -17
  58. package/src/video-reference-resolver.ts +1 -1
  59. package/dist/chunk-22KZOAGL.cjs.map +0 -1
  60. package/dist/chunk-3INXNDV7.cjs.map +0 -1
  61. package/dist/chunk-6MPZHFIS.js.map +0 -1
  62. package/dist/chunk-7XMTVYS5.js.map +0 -1
  63. package/dist/chunk-KUBZVWME.cjs.map +0 -1
  64. package/dist/chunk-NMWKXAYA.cjs.map +0 -1
  65. package/dist/chunk-XRLOMTBZ.js.map +0 -1
  66. package/dist/chunk-XU54YJXQ.js.map +0 -1
@@ -9,8 +9,8 @@ import { imageReferenceLimit, SEEDANCE_2_REF_LIMITS, VIDEO_REF_LIMITS_BY_PROVIDE
9
9
  import { resolveFrameDelivery } from '@nodaro/shared/video';
10
10
 
11
11
  // src/ref-binding.ts
12
- function identityRefsSentence(firstOrdinal, lastOrdinal) {
13
- 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.`;
12
+ function identityRefsSentence(firstOrdinal, lastOrdinal, ordinal = REF_BINDING.ordinal) {
13
+ 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.`;
14
14
  }
15
15
  var REF_BINDING = {
16
16
  image: (label, n) => `the ${label} from @image_${n}`,
@@ -20,6 +20,14 @@ var REF_BINDING = {
20
20
  ordinal: (n) => `@image_${n}`,
21
21
  frame: (n, role) => `Use @image_${n} as the ${role} (${role === "opening" ? "first" : "last"}) frame of the video.`
22
22
  };
23
+ function imageBindingFor(syntax) {
24
+ if (syntax === "@image_N") return { ordinal: REF_BINDING.ordinal, frame: REF_BINDING.frame };
25
+ const ordinal = syntax === "@image(n)" ? (n) => `@image(${n})` : (n) => `[Image ${n}]`;
26
+ return {
27
+ ordinal,
28
+ frame: (n, role) => `Use ${ordinal(n)} as the ${role} (${role === "opening" ? "first" : "last"}) frame of the video.`
29
+ };
30
+ }
23
31
  var SEEDANCE_VIDEO_EDIT_PREFIX = "edit {video:1} as follows:\n";
24
32
  function buildSeedanceVideoEditPrompt(prompt) {
25
33
  const body = (prompt ?? "").trim();
@@ -763,15 +771,50 @@ function composeVideoPromptText(userPrompt, direction, structured, opts) {
763
771
  }
764
772
  return body;
765
773
  }
774
+
775
+ // src/frame-reference-slots.ts
776
+ function placeFramesAfterReferences(args) {
777
+ const refs = (args.refImageUrls ?? []).filter((u) => typeof u === "string" && u.trim().length > 0);
778
+ const frameCount = (args.firstFrameUrl ? 1 : 0) + (args.lastFrameUrl ? 1 : 0);
779
+ const kept = refs.slice(0, Math.max(0, args.imageCap - frameCount));
780
+ const droppedRefImages = refs.length - kept.length;
781
+ const imageUrls = [...kept];
782
+ let firstFrameOrdinal = 0;
783
+ let lastFrameOrdinal = 0;
784
+ if (args.firstFrameUrl) {
785
+ imageUrls.push(args.firstFrameUrl);
786
+ firstFrameOrdinal = imageUrls.length;
787
+ }
788
+ if (args.lastFrameUrl) {
789
+ imageUrls.push(args.lastFrameUrl);
790
+ lastFrameOrdinal = imageUrls.length;
791
+ }
792
+ const syntax = args.syntax ?? "@image_N";
793
+ const binding = imageBindingFor(syntax);
794
+ const promptBindsStart = syntax === "@image_N" && promptBindsFirstFrame(args.prompt);
795
+ let frameSentence = "";
796
+ if (promptBindsStart && firstFrameOrdinal > 0 && lastFrameOrdinal === 0) ; else if (firstFrameOrdinal > 0 && lastFrameOrdinal > 0) {
797
+ frameSentence = `Use ${binding.ordinal(firstFrameOrdinal)} as the opening (first) frame and ${binding.ordinal(lastFrameOrdinal)} as the closing (last) frame of the video.`;
798
+ } else if (firstFrameOrdinal > 0) {
799
+ frameSentence = binding.frame(firstFrameOrdinal, "opening");
800
+ } else if (lastFrameOrdinal > 0) {
801
+ frameSentence = binding.frame(lastFrameOrdinal, "closing");
802
+ }
803
+ const identitySentence = args.bindIdentities && kept.length > 0 && frameCount > 0 ? identityRefsSentence(1, kept.length, binding.ordinal) : "";
804
+ const promptSuffix = [frameSentence, identitySentence].filter(Boolean).join(" ");
805
+ return { imageUrls, promptSuffix, droppedRefImages, firstFrameOrdinal, lastFrameOrdinal };
806
+ }
807
+ function promptBindsFirstFrame(prompt) {
808
+ if (!prompt) return false;
809
+ return /@image_\d+\s+as\s+the\s+(first|opening)\s*(\(first\))?\s*frame/i.test(prompt);
810
+ }
811
+
812
+ // src/seedance-2-inputs.ts
766
813
  var clean = (u) => {
767
814
  const t = u?.trim();
768
815
  return t && t.length > 0 ? t : void 0;
769
816
  };
770
817
  var cleanList = (xs) => (xs ?? []).map(clean).filter((x) => x !== void 0);
771
- function promptBindsFirstFrame(prompt) {
772
- if (!prompt) return false;
773
- return /@image_\d+\s+as\s+the\s+(first|opening)\s*(\(first\))?\s*frame/i.test(prompt);
774
- }
775
818
  function resolveSeedance2Inputs(args) {
776
819
  const limits = args.limits ?? SEEDANCE_2_REF_LIMITS;
777
820
  const firstFrameUrl = clean(args.firstFrameUrl);
@@ -787,30 +830,16 @@ function resolveSeedance2Inputs(args) {
787
830
  }
788
831
  return { mode: "first-frame", firstFrameUrl, lastFrameUrl: void 0, referenceImageUrls: [], referenceVideoUrls: [], referenceAudioUrls: [], promptSuffix: "", droppedRefImages: 0 };
789
832
  }
790
- const frameCount = (firstFrameUrl ? 1 : 0) + (lastFrameUrl ? 1 : 0);
791
- const userImageSlots = Math.max(0, limits.images - frameCount);
792
- const keptUserImages = refImages.slice(0, userImageSlots);
793
- const droppedRefImages = refImages.length - keptUserImages.length;
794
- const referenceImageUrls = [...keptUserImages];
795
- let firstOrdinal = 0;
796
- let lastOrdinal = 0;
797
- if (firstFrameUrl) {
798
- referenceImageUrls.push(firstFrameUrl);
799
- firstOrdinal = referenceImageUrls.length;
800
- }
801
- if (lastFrameUrl) {
802
- referenceImageUrls.push(lastFrameUrl);
803
- lastOrdinal = referenceImageUrls.length;
804
- }
805
- let promptSuffix = "";
806
- const suppressFrameSentence = promptBindsFirstFrame(args.prompt);
807
- if (suppressFrameSentence && firstOrdinal > 0 && lastOrdinal === 0) ; else if (firstOrdinal > 0 && lastOrdinal > 0) {
808
- promptSuffix = `Use ${REF_BINDING.ordinal(firstOrdinal)} as the opening (first) frame and ${REF_BINDING.ordinal(lastOrdinal)} as the closing (last) frame of the video.`;
809
- } else if (firstOrdinal > 0) {
810
- promptSuffix = REF_BINDING.frame(firstOrdinal, "opening");
811
- } else if (lastOrdinal > 0) {
812
- promptSuffix = REF_BINDING.frame(lastOrdinal, "closing");
813
- }
833
+ const placed = placeFramesAfterReferences({
834
+ prompt: args.prompt,
835
+ firstFrameUrl,
836
+ lastFrameUrl,
837
+ refImageUrls: refImages,
838
+ imageCap: limits.images
839
+ });
840
+ const referenceImageUrls = placed.imageUrls;
841
+ const promptSuffix = placed.promptSuffix;
842
+ const droppedRefImages = placed.droppedRefImages;
814
843
  return {
815
844
  mode: "reference",
816
845
  firstFrameUrl: void 0,
@@ -827,16 +856,18 @@ function geminiOmniInputSlots(provider) {
827
856
  return VIDEO_REF_LIMITS_BY_PROVIDER[provider ?? DEFAULT_GEMINI_OMNI_PROVIDER]?.images ?? 7;
828
857
  }
829
858
  function resolveGeminiOmniI2vInputs(args) {
830
- const refs = (args.refImageUrls ?? []).filter((u) => typeof u === "string" && u.length > 0);
831
859
  const slots = geminiOmniInputSlots(args.provider) - (args.videoConnected ? 2 : 0);
832
- const refSlots = Math.max(0, slots - 1);
833
- const kept = refs.slice(0, refSlots);
834
- const droppedRefImages = refs.length - kept.length;
835
- const imageUrls = [args.firstFrameUrl, ...kept];
836
- if (kept.length === 0) return { imageUrls, promptSuffix: "", droppedRefImages };
837
- const frameSentence = promptBindsFirstFrame(args.prompt) ? "" : REF_BINDING.frame(1, "opening");
838
- const promptSuffix = [frameSentence, identityRefsSentence(2, kept.length + 1)].filter(Boolean).join(" ");
839
- return { imageUrls, promptSuffix, droppedRefImages };
860
+ const placed = placeFramesAfterReferences({
861
+ prompt: args.prompt,
862
+ firstFrameUrl: args.firstFrameUrl,
863
+ refImageUrls: args.refImageUrls,
864
+ imageCap: Math.max(1, slots),
865
+ bindIdentities: true
866
+ });
867
+ if (placed.imageUrls.length === 1) {
868
+ return { imageUrls: placed.imageUrls, promptSuffix: "", droppedRefImages: placed.droppedRefImages };
869
+ }
870
+ return { imageUrls: placed.imageUrls, promptSuffix: placed.promptSuffix, droppedRefImages: placed.droppedRefImages };
840
871
  }
841
872
 
842
873
  // src/veo-i2v-inputs.ts
@@ -851,15 +882,20 @@ function resolveVeoI2vInputs(args) {
851
882
  droppedEndFrame: false
852
883
  };
853
884
  }
854
- const kept = refs.slice(0, VEO_INGREDIENT_SLOTS - 1);
855
- const droppedRefImages = refs.length - kept.length;
856
- const frameSentence = promptBindsFirstFrame(args.prompt) ? "" : REF_BINDING.frame(1, "opening");
885
+ const placed = placeFramesAfterReferences({
886
+ prompt: args.prompt,
887
+ firstFrameUrl: args.firstFrameUrl,
888
+ lastFrameUrl: args.endFrameUrl,
889
+ refImageUrls: refs,
890
+ imageCap: VEO_INGREDIENT_SLOTS,
891
+ bindIdentities: true
892
+ });
857
893
  return {
858
- imageUrls: [args.firstFrameUrl, ...kept],
894
+ imageUrls: placed.imageUrls,
859
895
  generationType: "REFERENCE_2_VIDEO",
860
- promptSuffix: [frameSentence, identityRefsSentence(2, kept.length + 1)].filter(Boolean).join(" "),
861
- droppedRefImages,
862
- droppedEndFrame: Boolean(args.endFrameUrl)
896
+ promptSuffix: placed.promptSuffix,
897
+ droppedRefImages: placed.droppedRefImages,
898
+ droppedEndFrame: false
863
899
  };
864
900
  }
865
901
 
@@ -927,6 +963,6 @@ function planFrameDelivery(args) {
927
963
  return { delivery: "reference", referenceImageUrls, promptSuffix: sentences.join(" ") };
928
964
  }
929
965
 
930
- export { REF_BINDING, SEEDANCE_VIDEO_EDIT_PREFIX, appendField, appendMusicMeta, assembleImageInput, assembleSunoInput, buildSeedanceVideoEditPrompt, buildSurroundFillPrompt, composeSoundHintFromConnections, composeVideoPromptText, getEffectiveSunoCustomMode, identityRefsSentence, planFrameDelivery, promptBindsFirstFrame, resolveGeminiOmniI2vInputs, resolveRefIdTokens, resolveReferenceTokens, resolveSeedance2Inputs, resolveVeoI2vInputs, resolveVideoReferenceCore, truncateForField };
931
- //# sourceMappingURL=chunk-XU54YJXQ.js.map
932
- //# sourceMappingURL=chunk-XU54YJXQ.js.map
966
+ export { REF_BINDING, SEEDANCE_VIDEO_EDIT_PREFIX, appendField, appendMusicMeta, assembleImageInput, assembleSunoInput, buildSeedanceVideoEditPrompt, buildSurroundFillPrompt, composeSoundHintFromConnections, composeVideoPromptText, getEffectiveSunoCustomMode, identityRefsSentence, imageBindingFor, placeFramesAfterReferences, planFrameDelivery, promptBindsFirstFrame, resolveGeminiOmniI2vInputs, resolveRefIdTokens, resolveReferenceTokens, resolveSeedance2Inputs, resolveVeoI2vInputs, resolveVideoReferenceCore, truncateForField };
967
+ //# sourceMappingURL=chunk-HQTHDTHN.js.map
968
+ //# sourceMappingURL=chunk-HQTHDTHN.js.map