Keep remaining multi-shot clips on a Queue page so prompts can be edited between shots, with process-next or overnight run-all.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { frameLength, runGeneration } from '~/server/utils/videoChain'
|
||||
import { createShotQueue, finishQueueBurst, setQueueJob } from '~/server/utils/shotQueue'
|
||||
|
||||
function isComfyBusyTimeout(error: unknown) {
|
||||
const err = error as { statusCode?: number; status?: number; data?: { code?: string }; message?: string; statusMessage?: string }
|
||||
@@ -154,6 +155,8 @@ export default defineEventHandler(async (event) => {
|
||||
job.kind = 'video'
|
||||
job.maxStep = steps
|
||||
job.hideThumbnail = hideThumbnail
|
||||
const familyId = crypto.randomUUID()
|
||||
const queueAutoRun = fields.queueAutoRun === 'true'
|
||||
job.library = {
|
||||
ownerKey,
|
||||
folderId,
|
||||
@@ -184,9 +187,42 @@ export default defineEventHandler(async (event) => {
|
||||
chainStep: 1,
|
||||
chainTotal,
|
||||
chainLabel: extensions.length ? 'Initial' : undefined,
|
||||
familyId: crypto.randomUUID(),
|
||||
familyId,
|
||||
workflow,
|
||||
useIdentityRefs
|
||||
useIdentityRefs,
|
||||
queueAutoRun: extensions.length ? queueAutoRun : false,
|
||||
queueBudget: extensions.length && queueAutoRun ? extensions.length : 0
|
||||
}
|
||||
if (extensions.length) {
|
||||
const queue = await createShotQueue({
|
||||
ownerKey,
|
||||
name: clipName,
|
||||
familyId,
|
||||
folderId,
|
||||
autoRun: queueAutoRun,
|
||||
stillId: still?.id,
|
||||
stillFilename: still?.filename,
|
||||
hideThumbnail,
|
||||
hideInput,
|
||||
aspect: fields.aspect || 'auto',
|
||||
width,
|
||||
height,
|
||||
steps,
|
||||
turbo,
|
||||
cfg,
|
||||
fps,
|
||||
samplerName,
|
||||
scheduler,
|
||||
workflow,
|
||||
sound,
|
||||
useIdentityRefs,
|
||||
referenceStillIds,
|
||||
initial: { prompt, duration: durationSeconds },
|
||||
extensions,
|
||||
jobId: job.id
|
||||
})
|
||||
job.library.queueId = queue.id
|
||||
setQueueJob(queue.id, job.id)
|
||||
}
|
||||
emitChainJob(job, { type: 'status', message: 'Checking ComfyUI...', progress: 1 })
|
||||
|
||||
@@ -242,6 +278,10 @@ export default defineEventHandler(async (event) => {
|
||||
job.status = 'deferred'
|
||||
const message = 'ComfyUI was still busy after 3 minutes. Saved this job — click it under Held jobs to restore the form.'
|
||||
emitJob(job, { type: 'deferred', draftId: draft.id, message, progress: job.progress })
|
||||
if (job.library.queueId) {
|
||||
await finishQueueBurst(job.library.ownerKey, job.library.queueId, true, 'Held because ComfyUI was busy').catch(() => null)
|
||||
setQueueJob(job.library.queueId, null)
|
||||
}
|
||||
return
|
||||
} catch {
|
||||
// fall through to a normal error if the held job could not be saved
|
||||
@@ -252,6 +292,10 @@ export default defineEventHandler(async (event) => {
|
||||
job.status = 'error'
|
||||
job.error = message
|
||||
emitJob(job, { type: 'error', error: message, message })
|
||||
if (job.library?.queueId) {
|
||||
await finishQueueBurst(job.library.ownerKey, job.library.queueId, false, message).catch(() => null)
|
||||
setQueueJob(job.library.queueId, null)
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
@@ -270,6 +314,8 @@ export default defineEventHandler(async (event) => {
|
||||
folderId,
|
||||
hideThumbnail,
|
||||
folderLocked,
|
||||
chainTotal
|
||||
chainTotal,
|
||||
queueId: job.library?.queueId,
|
||||
queuedRemaining: extensions.length
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user