@nodaro/prompts 1.7.0 → 1.7.3

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/index.cjs CHANGED
@@ -10017,6 +10017,9 @@ function renderLens(l) {
10017
10017
  if (l.aperture) bits.push(`f/${l.aperture}`);
10018
10018
  return bits.length > 0 ? `Lens: ${bits.join(", ")}.` : "";
10019
10019
  }
10020
+ function identityRefsSentence(firstOrdinal, lastOrdinal) {
10021
+ 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.`;
10022
+ }
10020
10023
  var REF_BINDING = {
10021
10024
  image: (label, n) => `the ${label} from @image_${n}`,
10022
10025
  video: (label, n) => `the ${label} from @video_${n}`,
@@ -10595,11 +10598,12 @@ function promptBindsFirstFrame(prompt) {
10595
10598
  return /@image_\d+\s+as\s+the\s+(first|opening)\s*(\(first\))?\s*frame/i.test(prompt);
10596
10599
  }
10597
10600
  function resolveSeedance2Inputs(args) {
10601
+ const limits = args.limits ?? shared.SEEDANCE_2_REF_LIMITS;
10598
10602
  const firstFrameUrl = clean(args.firstFrameUrl);
10599
10603
  const lastFrameUrl = clean(args.lastFrameUrl);
10600
10604
  const refImages = cleanList(args.refImageUrls);
10601
- const refVideos = cleanList(args.refVideoUrls).slice(0, shared.SEEDANCE_2_REF_LIMITS.videos);
10602
- const refAudios = cleanList(args.refAudioUrls).slice(0, shared.SEEDANCE_2_REF_LIMITS.audio);
10605
+ const refVideos = cleanList(args.refVideoUrls).slice(0, limits.videos);
10606
+ const refAudios = cleanList(args.refAudioUrls).slice(0, limits.audio);
10603
10607
  const hasAnyReference = refImages.length > 0 || refVideos.length > 0 || refAudios.length > 0;
10604
10608
  const canUseStrictMode = !hasAnyReference && (Boolean(firstFrameUrl) || !lastFrameUrl);
10605
10609
  if (canUseStrictMode) {
@@ -10609,7 +10613,7 @@ function resolveSeedance2Inputs(args) {
10609
10613
  return { mode: "first-frame", firstFrameUrl, lastFrameUrl: void 0, referenceImageUrls: [], referenceVideoUrls: [], referenceAudioUrls: [], promptSuffix: "", droppedRefImages: 0 };
10610
10614
  }
10611
10615
  const frameCount = (firstFrameUrl ? 1 : 0) + (lastFrameUrl ? 1 : 0);
10612
- const userImageSlots = Math.max(0, shared.SEEDANCE_2_REF_LIMITS.images - frameCount);
10616
+ const userImageSlots = Math.max(0, limits.images - frameCount);
10613
10617
  const keptUserImages = refImages.slice(0, userImageSlots);
10614
10618
  const droppedRefImages = refImages.length - keptUserImages.length;
10615
10619
  const referenceImageUrls = [...keptUserImages];
@@ -10643,6 +10647,43 @@ function resolveSeedance2Inputs(args) {
10643
10647
  droppedRefImages
10644
10648
  };
10645
10649
  }
10650
+ var GEMINI_OMNI_INPUT_SLOTS = shared.VIDEO_REF_LIMITS_BY_PROVIDER["gemini-omni-video"]?.images ?? 7;
10651
+ function resolveGeminiOmniI2vInputs(args) {
10652
+ const refs = (args.refImageUrls ?? []).filter((u) => typeof u === "string" && u.length > 0);
10653
+ const slots = GEMINI_OMNI_INPUT_SLOTS - (args.videoConnected ? 2 : 0);
10654
+ const refSlots = Math.max(0, slots - 1);
10655
+ const kept = refs.slice(0, refSlots);
10656
+ const droppedRefImages = refs.length - kept.length;
10657
+ const imageUrls = [args.firstFrameUrl, ...kept];
10658
+ if (kept.length === 0) return { imageUrls, promptSuffix: "", droppedRefImages };
10659
+ const frameSentence = promptBindsFirstFrame(args.prompt) ? "" : REF_BINDING.frame(1, "opening");
10660
+ const promptSuffix = [frameSentence, identityRefsSentence(2, kept.length + 1)].filter(Boolean).join(" ");
10661
+ return { imageUrls, promptSuffix, droppedRefImages };
10662
+ }
10663
+
10664
+ // src/veo-i2v-inputs.ts
10665
+ var VEO_INGREDIENT_SLOTS = 3;
10666
+ function resolveVeoI2vInputs(args) {
10667
+ const refs = (args.refImageUrls ?? []).filter((u) => typeof u === "string" && u.length > 0);
10668
+ if (refs.length === 0) {
10669
+ return {
10670
+ imageUrls: args.endFrameUrl ? [args.firstFrameUrl, args.endFrameUrl] : [args.firstFrameUrl],
10671
+ promptSuffix: "",
10672
+ droppedRefImages: 0,
10673
+ droppedEndFrame: false
10674
+ };
10675
+ }
10676
+ const kept = refs.slice(0, VEO_INGREDIENT_SLOTS - 1);
10677
+ const droppedRefImages = refs.length - kept.length;
10678
+ const frameSentence = promptBindsFirstFrame(args.prompt) ? "" : REF_BINDING.frame(1, "opening");
10679
+ return {
10680
+ imageUrls: [args.firstFrameUrl, ...kept],
10681
+ generationType: "REFERENCE_2_VIDEO",
10682
+ promptSuffix: [frameSentence, identityRefsSentence(2, kept.length + 1)].filter(Boolean).join(" "),
10683
+ droppedRefImages,
10684
+ droppedEndFrame: Boolean(args.endFrameUrl)
10685
+ };
10686
+ }
10646
10687
  function toOptions(arr, categoryField) {
10647
10688
  return arr.map((e) => {
10648
10689
  const opt = {
@@ -26224,7 +26265,7 @@ precise subject \u2192 action details \u2192 scene/environment \u2192 lighting &
26224
26265
  **Generation differences (seedance-2-5 vs the 2.0 SKUs)**
26225
26266
  - A single 2.5 shot runs to 30s, where every 2.0 SKU stops at 15s. Plan a complete 4-6 shot beat inside ONE generation instead of splitting it into two clips and stitching \u2014 no seam to hide, and continuity holds because it never leaves the model.
26226
26267
  - 2.5 also takes far more reference material (30 images / 10 videos / 10 audio vs 9/3/3). Treat that as room for COVERAGE \u2014 more distinct characters, locations and props in one shot \u2014 not as licence to pile refs onto one identity. The "ONE headshot + ONE full-body, 4-5 assets total" rule above still produces the best likeness on 2.5.
26227
- - 2.5 renders at 480p/720p only: there is no 1080p or 4K tier, so route a job that needs one to seedance-2 (which has both) or upscale afterwards.
26268
+ - 2.5 renders at 480p/720p/1080p (1080p since 2026-08-17): there is no 4K tier, so route a job that needs 4K to seedance-2 (which has it) or upscale afterwards.
26228
26269
  - With a start frame, 2.5 always derives the output aspect from that frame \u2014 an explicit aspect ratio is rejected outright, so compose the frame at the ratio you want.
26229
26270
 
26230
26271
  **References (when reference media is attached)**
@@ -26249,8 +26290,7 @@ precise subject \u2192 action details \u2192 scene/environment \u2192 lighting &
26249
26290
  - More than 4 referenced people gets unstable: group people into composite images of \u22644 first (image generation), then reference those composites.
26250
26291
  - Repeated extension degrades quality: prefer high-definition reference assets and avoid stacking many continuations.
26251
26292
 
26252
- **Auto-path formula (community-sourced enrichment \u2014 apiyi.com Seedance 2.0 prompt guide,
26253
- higgsfield.ai 4K breakdown; captured 2026-08-09)**
26293
+ **Auto-path formula (community-sourced enrichment; captured 2026-08-09)**
26254
26294
  - Six steps IN ORDER, 60-100 words total (longer measurably degrades): Subject \u2192 Action \u2192 Environment \u2192 Camera \u2192 Style \u2192 Constraints.
26255
26295
  - ONE primary camera instruction per shot. Compound moves chain with "then": "camera slow tracking then subtle rise" \u2014 never two competing verbs. The 8 reliable camera types: push-in, pull-out, pan, tracking, orbit/arc, aerial, handheld, locked-off.
26256
26296
  - SEPARATE camera movement from subject movement \u2014 the single biggest quality lever: "The dancer spins slowly. Camera holds fixed framing." \u2014 never "spinning camera around a dancing person".
@@ -26643,6 +26683,7 @@ var PROVIDER_CAPABILITIES = {
26643
26683
  "gpt-image": "Creative concepts, illustration, variable quality tiers",
26644
26684
  "gpt-image-2": "Latest GPT Image \u2014 sharp text, photorealism, 1K/2K/4K resolution",
26645
26685
  "grok": "General purpose, good text understanding",
26686
+ "grok-2": "Grok Imagine 2 \u2014 expressive, high-contrast, stylized output",
26646
26687
  "imagen4": "Google's latest, strong photorealism and text rendering",
26647
26688
  "imagen4-fast": "Faster Imagen 4 variant",
26648
26689
  "imagen4-ultra": "Highest quality Imagen 4",
@@ -26719,7 +26760,7 @@ var PROVIDER_CAPABILITIES = {
26719
26760
  "seedance-2": "Seedance 2.0 \u2014 multimodal refs (9 images / 3 videos / 3 audio), native multi-track audio, multi-shot storytelling, 4-15s",
26720
26761
  "seedance-2-fast": "Seedance 2.0 Fast \u2014 same multimodal + audio capabilities, cheaper and quicker",
26721
26762
  "seedance-2-mini": "Seedance 2.0 Mini \u2014 same multimodal + audio capabilities, budget tier, 480p/720p, 4-15s",
26722
- "seedance-2-5": "Seedance 2.5 \u2014 up to 30s in ONE shot (no stitching), wider multimodal refs (30 images / 10 videos / 10 audio), native audio, 480p/720p",
26763
+ "seedance-2-5": "Seedance 2.5 \u2014 up to 30s in ONE shot (no stitching), wider multimodal refs (30 images / 10 videos / 10 audio), native audio, 480p/720p/1080p",
26723
26764
  "minimax-h3": "MiniMax Hailuo 3 \u2014 premium multimodal refs (9 images / 3 videos / 3 audio), always-on audio, 2K or 768P, 4-15s per-second pricing",
26724
26765
  "wan": "Versatile, good for animations and transformations",
26725
26766
  "wan-turbo": "Faster Wan generation",
@@ -26747,7 +26788,7 @@ var PROVIDER_CAPABILITIES = {
26747
26788
  "seedance-2": "Seedance 2.0 \u2014 start/end frame + multimodal refs, native audio, 4-15s",
26748
26789
  "seedance-2-fast": "Seedance 2.0 Fast \u2014 same capabilities, cheaper and quicker",
26749
26790
  "seedance-2-mini": "Seedance 2.0 Mini \u2014 same capabilities, budget tier, 480p/720p",
26750
- "seedance-2-5": "Seedance 2.5 \u2014 start/end frame + wide multimodal refs, native audio, up to 30s, 480p/720p",
26791
+ "seedance-2-5": "Seedance 2.5 \u2014 start/end frame + wide multimodal refs, native audio, up to 30s, 480p/720p/1080p",
26751
26792
  "minimax-h3": "MiniMax Hailuo 3 \u2014 first/last frame + multimodal refs, always-on audio, 2K or 768P, 4-15s",
26752
26793
  "hailuo-2.3-pro": "Premium Hailuo animation",
26753
26794
  "hailuo-2.3": "Standard Hailuo animation",
@@ -26860,7 +26901,7 @@ var NODE_PROMPT_CANDIDATE_FIELDS = {
26860
26901
  function computeNodePrompt(nodeType, data, { override, wired, refMap, appendWired }) {
26861
26902
  let typed;
26862
26903
  if (nodeType === "text-to-speech") {
26863
- typed = data.textSource === "direct" ? [data.directText] : [];
26904
+ typed = data.textSource === "direct" || !present(wired) ? [data.directText] : [];
26864
26905
  } else {
26865
26906
  const fields = NODE_PROMPT_CANDIDATE_FIELDS[nodeType] ?? ["prompt"];
26866
26907
  typed = fields.map((f) => data[f]);
@@ -32075,6 +32116,35 @@ function getPickerWiring(nodeType) {
32075
32116
  return WIRING_MAP.get(nodeType);
32076
32117
  }
32077
32118
 
32119
+ // src/surround-fill.ts
32120
+ var EDGE = {
32121
+ right: { carried: "left", painted: "right" },
32122
+ left: { carried: "right", painted: "left" },
32123
+ up: { carried: "bottom", painted: "top" },
32124
+ down: { carried: "top", painted: "bottom" }
32125
+ };
32126
+ var TILT_SUBJECT = {
32127
+ up: {
32128
+ word: "up",
32129
+ subject: "the open sky directly overhead \u2014 sky, clouds, or (for an interior) the canopy or ceiling",
32130
+ where: "overhead"
32131
+ },
32132
+ down: {
32133
+ word: "down",
32134
+ subject: "the ground directly below \u2014 terrain, floor, or water surface",
32135
+ where: "below"
32136
+ }
32137
+ };
32138
+ function buildSurroundFillPrompt(direction, userPrompt) {
32139
+ const scene = userPrompt && userPrompt.trim() ? `${userPrompt.trim()}. ` : "";
32140
+ const { carried, painted } = EDGE[direction];
32141
+ if (direction === "up" || direction === "down") {
32142
+ const t = TILT_SUBJECT[direction];
32143
+ return `${scene}This is a camera tilted straight ${t.word} from the same scene. The ${carried} strip holds real, finished pixels from the edge of the horizon view; the ${painted} region is flat gray and MUST be painted as ${t.subject}. Render what is genuinely ${t.where} \u2014 do NOT repeat, mirror, or continue the landscape, and do NOT draw a horizon line or distant scenery in the painted region. CRITICAL: keep the ${carried} strip unchanged and match the scene's EXACT lighting, time of day, white balance, and color grade \u2014 the same light as the ${carried} strip; no golden hour, no sunset, no warm relight, no cinematic regrade. Blend smoothly into the ${carried} strip with no visible seam. No people, no text, no labels, no watermarks.`;
32144
+ }
32145
+ return `${scene}This is a partial frame: the ${carried} portion contains real, finished pixels and the ${painted} portion is flat gray that MUST be painted in. Paint ONLY the ${painted} gray region as a natural, seamless continuation of the ${carried} portion \u2014 same scene, same perspective, continuing the horizon, geometry, and content across the boundary with no break. Keep the ${carried} portion completely unchanged. CRITICAL: do NOT change the lighting, exposure, white balance, or time of day. Match the ${carried} portion's EXACT light, color temperature, and contrast across the whole frame \u2014 if it is flat overcast daylight, keep flat overcast daylight. No golden hour, no sunset, no warm relight, no cinematic regrade. The seam between the ${carried} and ${painted} portions must be invisible. No people, no text, no labels, no watermarks.`;
32146
+ }
32147
+
32078
32148
  exports.ACTION_FX = ACTION_FX;
32079
32149
  exports.ACTION_FX_CATEGORY_LABELS = ACTION_FX_CATEGORY_LABELS;
32080
32150
  exports.ACTION_FX_CATEGORY_ORDER = ACTION_FX_CATEGORY_ORDER;
@@ -32307,6 +32377,7 @@ exports.buildPostProcessHints = buildPostProcessHints;
32307
32377
  exports.buildReferenceBlocks = buildReferenceBlocks;
32308
32378
  exports.buildScenePrompt = buildScenePrompt;
32309
32379
  exports.buildStylingHints = buildStylingHints;
32380
+ exports.buildSurroundFillPrompt = buildSurroundFillPrompt;
32310
32381
  exports.buildTemporalHints = buildTemporalHints;
32311
32382
  exports.buildVoiceCharacterHints = buildVoiceCharacterHints;
32312
32383
  exports.buildVoiceDeliveryHints = buildVoiceDeliveryHints;
@@ -32449,6 +32520,7 @@ exports.getWardrobeEntry = getWardrobeEntry;
32449
32520
  exports.getWardrobePromptHint = getWardrobePromptHint;
32450
32521
  exports.groupFactoryPresets = groupFactoryPresets;
32451
32522
  exports.hasUpstreamCharacter = hasUpstreamCharacter;
32523
+ exports.identityRefsSentence = identityRefsSentence;
32452
32524
  exports.isAnalyzablePicker = isAnalyzablePicker;
32453
32525
  exports.isInstrumentalVocal = isInstrumentalVocal;
32454
32526
  exports.isVantageFraming = isVantageFraming;
@@ -32462,11 +32534,13 @@ exports.referenceRulesBlock = referenceRulesBlock;
32462
32534
  exports.renderStructuredFields = renderStructuredFields;
32463
32535
  exports.resolveBrandInput = resolveBrandInput;
32464
32536
  exports.resolveCharacterMentions = resolveCharacterMentions;
32537
+ exports.resolveGeminiOmniI2vInputs = resolveGeminiOmniI2vInputs;
32465
32538
  exports.resolveLocationMentions = resolveLocationMentions;
32466
32539
  exports.resolvePrompt = resolvePrompt;
32467
32540
  exports.resolveReferenceTokens = resolveReferenceTokens;
32468
32541
  exports.resolveSeedance2Inputs = resolveSeedance2Inputs;
32469
32542
  exports.resolveTemplate = resolveTemplate;
32543
+ exports.resolveVeoI2vInputs = resolveVeoI2vInputs;
32470
32544
  exports.resolveVideoReferenceCore = resolveVideoReferenceCore;
32471
32545
  exports.summarizePickerCatalogs = summarizePickerCatalogs;
32472
32546
  exports.toIdentityLockMode = toIdentityLockMode;