Name outputs from the input, engine, and LoRA keys instead of aigen_0001. Image-edit presets now store prompts, and aspect fill pads stills without stretching.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-08-30 16:24:49 -05:00
co-authored by Cursor
parent 4d411f83d4
commit 0e1222d035
23 changed files with 668 additions and 93 deletions
+34 -7
View File
@@ -7,6 +7,7 @@ import { ensureComfyLoraNames, persistLoraFields } from '~/server/utils/loras'
import { imageDimensions } from '~/server/utils/resolution'
import { emitChainJob } from '~/server/utils/watch'
import { saveStill } from '~/server/utils/library'
import { comfyJobPrefix } from '~/utils/outputNames'
import { parseImageV2Engine, type ImageV2Engine, type ImageV2Mode, type ImageV2Task } from '~/utils/imageV2'
import type { EditImageFile } from '~/server/utils/imageChain'
@@ -31,6 +32,7 @@ export type EditV2RunParams = {
width?: number
height?: number
turbo?: boolean
aspect?: string
sourceStillId?: string
referenceStillId?: string
loraStack?: import('~/utils/loras').LoraStackItem[]
@@ -77,7 +79,31 @@ export async function runEditV2(job: Job, params: EditV2RunParams) {
: params.mode === 'compose' ? 'Uploading stills A and B to Beast...' : 'Uploading still A to Beast...',
progress: generate ? 12 : 8
})
const uploaded = generate || !params.image ? null : await uploadImage(params.image, job.id)
const { applyImageFill } = await import('~/server/utils/imagePad')
const { composeFillPrompt } = await import('~/utils/imageAspect')
let image = params.image
let mask = params.mask
let prompt = params.prompt
let padded = false
if (!generate && image) {
const filled = await applyImageFill({
image,
mask: params.mode === 'refine' ? mask : null,
aspect: params.aspect || 'auto'
})
image = filled.image
if (filled.mask) mask = filled.mask
padded = filled.padded
prompt = composeFillPrompt(prompt, padded)
if (padded) {
emitChainJob(job, {
type: 'status',
message: `Filling to ${filled.aspect} without stretching...`,
progress: 7
})
}
}
const uploaded = generate || !image ? null : await uploadImage(image, job.id)
const uploadedRef = generate || params.mode === 'refine'
? null
: params.reference
@@ -86,10 +112,10 @@ export async function runEditV2(job: Job, params: EditV2RunParams) {
filename: `ref_${params.reference.filename || 'image_b.png'}`
}, job.id)
: null
const uploadedMask = !generate && params.mode === 'refine' && params.mask
const uploadedMask = !generate && params.mode === 'refine' && mask
? await uploadImage({
...params.mask,
filename: `mask_${params.mask.filename || 'refine-mask.png'}`
...mask,
filename: `mask_${mask.filename || 'refine-mask.png'}`
}, job.id)
: null
if (job.status === 'cancelled') throw new Error('Job interrupted.')
@@ -112,7 +138,7 @@ export async function runEditV2(job: Job, params: EditV2RunParams) {
mode: params.mode,
engine,
task: params.task,
prompt: params.prompt,
prompt,
negative: params.negative,
imageAName: uploaded?.name,
imageBName: uploadedRef?.name,
@@ -129,7 +155,7 @@ export async function runEditV2(job: Job, params: EditV2RunParams) {
width: params.width,
height: params.height,
turbo: params.turbo === true,
filenamePrefix: `aigen_v2_${job.id.slice(0, 8)}`,
filenamePrefix: comfyJobPrefix(job.id),
kreaUnetName: krea?.unet,
kreaClipName: krea?.clip,
kreaVaeName: krea?.vae,
@@ -174,7 +200,7 @@ export async function runEditV2(job: Job, params: EditV2RunParams) {
const still = await saveStill({
ownerKey: library.ownerKey,
folderId: library.folderId,
filename: output.filename,
filename: library.name ? `${library.name}.png` : output.filename,
data: buffer,
width: size?.width || 0,
height: size?.height || 0,
@@ -199,6 +225,7 @@ export async function runEditV2(job: Job, params: EditV2RunParams) {
strength: params.mode === 'generate' ? undefined : params.strength,
width: params.mode === 'generate' ? params.width : undefined,
height: params.mode === 'generate' ? params.height : undefined,
aspect: params.aspect || 'auto',
seed: params.seed,
sourceStillId: params.sourceStillId || library.stillId,
referenceStillId: params.referenceStillId,