@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 +83 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +128 -4
- package/dist/index.d.ts +128 -4
- package/dist/index.js +81 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/gemini-omni-inputs.test.ts +68 -0
- package/src/__tests__/seedance-2-inputs.test.ts +48 -0
- package/src/__tests__/veo-i2v-inputs.test.ts +58 -0
- package/src/gemini-omni-inputs.ts +73 -0
- package/src/index.ts +3 -0
- package/src/picker-wiring.ts +1 -1
- package/src/prompt-wizard-categories.ts +3 -2
- package/src/provider-prompt-doctrine.ts +2 -3
- package/src/resolve-prompt.ts +12 -1
- package/src/seedance-2-inputs.ts +10 -3
- package/src/style-presets.ts +1 -1
- package/src/surround-fill.ts +67 -0
- package/src/veo-i2v-inputs.ts +68 -0
- package/src/video-reference-resolver.ts +12 -0
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,
|
|
10602
|
-
const refAudios = cleanList(args.refAudioUrls).slice(0,
|
|
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,
|
|
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
|
|
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
|
|
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;
|