Always prepend the Comfy identity prefix and keep refs on every shot.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+3
-3
@@ -109,7 +109,7 @@
|
||||
</div>
|
||||
<p v-if="shotScriptMode && studioMode === 'video'" class="mb-2 text-xs text-zinc-500">
|
||||
Paste a block. Text before the first marker is shot 1. Put <span class="font-medium text-zinc-300">shot 2</span>, <span class="font-medium text-zinc-300">shot 3</span> on their own lines to queue extensions — a line like <span class="font-medium text-zinc-300">Shot Type</span> will not start a new shot. Every shot uses the duration slider.
|
||||
<span v-if="identityPrompting"> Identity boilerplate is prepended to the first shot only, then concatenated into Reference to Video.</span>
|
||||
<span v-if="identityPrompting"> The Comfy identity prefix is prepended to every shot, and the same Picture 1 / extra stills are sent with each shot.</span>
|
||||
</p>
|
||||
<p v-else-if="identityPrompting" class="mb-2 text-xs text-zinc-500">
|
||||
Write camera, action, and audio. That is the dynamic action prompt. We concatenate the <span class="font-medium text-zinc-300"><Picture 1></span> identity prefix in front of it and send the result to <span class="font-medium text-zinc-300">Reference to Video</span>, not Image to Video.
|
||||
@@ -140,7 +140,7 @@
|
||||
{{ index === 0 ? 'Initial' : `Extension ${index}` }}
|
||||
<span class="font-normal text-zinc-500"> · shot {{ shot.n }} · {{ formatClipDuration(duration) }}</span>
|
||||
</p>
|
||||
<p class="mt-1 whitespace-pre-wrap text-xs text-zinc-300">{{ shot.prompt }}</p>
|
||||
<p class="mt-1 whitespace-pre-wrap text-xs text-zinc-300">{{ identityPrompting ? buildIdentityPrompt(shot.prompt, extraIdentityPictures) : shot.prompt }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -321,7 +321,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="useIdentityRefs" class="text-xs text-zinc-500">Picture 1 is the start still. Extra stills map to Picture 2–5. Empty extra slots reuse the start still so Comfy does not error. Identity refs are not reused on queued extensions.</p>
|
||||
<p v-if="useIdentityRefs" class="text-xs text-zinc-500">Picture 1 is the start still and stays Picture 1 on every shot, including queued extensions. Extra stills map to Picture 2–5. Empty extra slots reuse the start still.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
+12
-10
@@ -309,17 +309,17 @@ async function queueMiniMax(
|
||||
|
||||
const done = watchComfyJob(job, { persist: params.persist })
|
||||
job.status = 'uploading'
|
||||
const uploading = (job.library?.chainIndex || 0) > 0
|
||||
? 'Uploading last frame to ComfyUI...'
|
||||
: 'Uploading image to ComfyUI...'
|
||||
const chainIndex = job.library?.chainIndex || 0
|
||||
const uploading = params.useIdentityRefs
|
||||
? (chainIndex > 0 ? 'Uploading identity stills for next shot...' : 'Uploading image to ComfyUI...')
|
||||
: (chainIndex > 0 ? 'Uploading last frame to ComfyUI...' : 'Uploading image to ComfyUI...')
|
||||
const queueing = (job.library?.chainIndex || 0) > 0
|
||||
? 'Queueing extension on MiniMax H3...'
|
||||
: 'Queueing MiniMax H3 job...'
|
||||
emitChainJob(job, { type: 'status', message: uploading, progress: 4 })
|
||||
const uploaded = await uploadImage(params.image, job.id)
|
||||
const referenceNames: string[] = ['', '', '', '']
|
||||
const chainIndex = job.library?.chainIndex || 0
|
||||
if (chainIndex === 0) {
|
||||
if (params.useIdentityRefs) {
|
||||
for (const [index, ref] of (params.referenceImages || []).entries()) {
|
||||
if (!ref?.data?.length) continue
|
||||
const next = await uploadImage({
|
||||
@@ -353,8 +353,8 @@ async function queueMiniMax(
|
||||
sound: params.sound,
|
||||
workflow: params.workflow,
|
||||
duration: params.duration,
|
||||
useIdentityRefs: chainIndex === 0 && params.useIdentityRefs,
|
||||
referenceImageNames: chainIndex === 0 ? referenceNames : []
|
||||
useIdentityRefs: params.useIdentityRefs,
|
||||
referenceImageNames: params.useIdentityRefs ? referenceNames : []
|
||||
})
|
||||
|
||||
const queued = await queuePrompt(graph, job.clientId)
|
||||
@@ -466,7 +466,9 @@ async function runGeneration(
|
||||
await ensureComfyReady(ready)
|
||||
await queueMiniMax(job, {
|
||||
prompt: ext.prompt,
|
||||
image: { filename: 'last_frame.png', data: frame, type: 'image/png' },
|
||||
image: params.useIdentityRefs
|
||||
? params.image
|
||||
: { filename: 'last_frame.png', data: frame, type: 'image/png' },
|
||||
width: params.width,
|
||||
height: params.height,
|
||||
steps: params.steps,
|
||||
@@ -481,8 +483,8 @@ async function runGeneration(
|
||||
persist: isLast,
|
||||
workflow: params.workflow,
|
||||
duration: ext.duration,
|
||||
useIdentityRefs: false,
|
||||
referenceImages: []
|
||||
useIdentityRefs: params.useIdentityRefs,
|
||||
referenceImages: params.useIdentityRefs ? params.referenceImages : []
|
||||
})
|
||||
|
||||
if (!isLast) {
|
||||
|
||||
@@ -13,11 +13,11 @@ export function identityBoilerplate(extraRefs: number | number[] = 0) {
|
||||
: extras.length === 1
|
||||
? ` <Picture ${extras[0]}> is a secondary reference angle for profile details.`
|
||||
: ` ${extras.map(n => `<Picture ${n}>`).join(' and ')} are secondary reference angles for profile features only.`
|
||||
return `<Picture 1> is the exact facial identity, hairstyle, body proportions and clothing of the main character. Preserve this identity with high fidelity even when the subject temporarily leaves the frame and returns.${secondary}`
|
||||
return `<Picture 1> is the primary identity anchor defining exact facial geometry, hairstyle, and body proportions.${secondary} Strictly maintain the structural proportions of <Picture 1> with high fidelity when moving.`
|
||||
}
|
||||
|
||||
export function looksLikeIdentityPrompt(text: string) {
|
||||
return /primary identity anchor|exact facial identity/i.test(String(text || ''))
|
||||
return /^<Picture 1> is the (primary identity anchor|exact facial identity)/i.test(String(text || '').trim())
|
||||
}
|
||||
|
||||
export function buildIdentityPrompt(actionPrompt: string, extraRefs: number | number[] = 0) {
|
||||
|
||||
Reference in New Issue
Block a user