Do not mark a waiting I2V complete when the image job finishes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-08-28 17:58:28 -05:00
co-authored by Cursor
parent 382bd37a3e
commit 3ed1d6aa9d
4 changed files with 69 additions and 26 deletions
+22 -24
View File
@@ -4,7 +4,7 @@ import { getJob, listJobs, emitJob, type Job } from '~/server/utils/jobs'
import { listPendingJobs, patchPendingJob, readPendingJob, deletePendingJob } from '~/server/utils/pending'
import { getShotQueue } from '~/server/utils/shotQueue'
import { fetchLiveQueue } from '~/server/utils/comfy'
import { isLtxWorkflow, LTX_DISABLED_MESSAGE, ltxWorkflowEnabled, parseVideoWorkflow, type VideoWorkflowId } from '~/utils/videoModels'
import { isLtxWorkflow, isTextToVideo, LTX_DISABLED_MESSAGE, ltxWorkflowEnabled, parseVideoWorkflow, type VideoWorkflowId } from '~/utils/videoModels'
import { persistLoraFields } from '~/server/utils/loras'
import { resolveLoraStack } from '~/utils/loras'
@@ -484,7 +484,7 @@ export async function markStudioHeld(owner: string, id: string) {
export async function markStudioSettled(owner: string, liveJobId: string, status: 'complete' | 'error' | 'cancelled', error?: string) {
return mutate(owner, (jobs) => {
const job = jobs.find(item => item.liveJobId === liveJobId) || jobs.find(item => item.status === 'running')
const job = jobs.find(item => item.liveJobId === liveJobId)
if (!job) return null
if (job.holdForCutIn && status === 'complete') {
job.status = 'held'
@@ -750,6 +750,16 @@ export async function startStudioJob(item: StudioJob) {
payload.globalLocks,
payload.shotPermanenceRefs
)
const stillFile = payload.stillId && existsSync(stillPath(item.ownerKey, payload.stillId))
? {
filename: payload.stillFilename || 'still.png',
data: readFileSync(stillPath(item.ownerKey, payload.stillId)),
type: 'image/png'
}
: null
if (!isTextToVideo(workflow) && !stillFile) {
throw new Error('The input still is missing from the library')
}
const job = createJob()
live = job
job.kind = 'video'
@@ -840,13 +850,6 @@ export async function startStudioJob(item: StudioJob) {
await markStudioLive(item.ownerKey, item.id, job.id, job.library.queueId)
const stillFile = payload.stillId && existsSync(stillPath(item.ownerKey, payload.stillId))
? {
filename: payload.stillFilename || 'still.png',
data: readFileSync(stillPath(item.ownerKey, payload.stillId)),
type: 'image/png'
}
: null
const referenceImages: Array<{ filename: string; data: Buffer; type?: string } | null> = [null, null, null, null]
for (const [index, stillId] of (payload.referenceStillIds || []).entries()) {
if (!stillId || index >= 4) continue
@@ -914,17 +917,12 @@ export async function onLiveVideoSettled(job: Job) {
const failed = job.status === 'error' || job.status === 'cancelled'
const snapshot = readStore(owner)
const rowNow = snapshot.jobs.find(item => item.liveJobId === job.id)
|| snapshot.jobs.find(item => (
item.status === 'running'
&& Boolean(item.shotQueueId)
&& item.shotQueueId === job.library?.queueId
))
|| snapshot.jobs.find(item => (
item.status === 'running'
&& !item.shotQueueId
&& !job.library?.queueId
&& (!item.liveJobId || item.liveJobId === job.id)
))
|| (job.library?.queueId
? snapshot.jobs.find(item => (
item.status === 'running'
&& item.shotQueueId === job.library?.queueId
))
: undefined)
const userPause = !failed && rowNow?.holdForCutIn !== true && (
rowNow?.pauseAfterCurrent === true
|| rowNow?.pausedByUser === true
@@ -937,7 +935,7 @@ export async function onLiveVideoSettled(job: Job) {
}
if (userPause && remaining > 0) {
await mutateStore(owner, (store) => {
const row = store.jobs.find(item => item.liveJobId === job.id) || store.jobs.find(item => item.status === 'running')
const row = store.jobs.find(item => item.liveJobId === job.id)
if (!row) {
syncPausedFlag(store)
return
@@ -953,7 +951,7 @@ export async function onLiveVideoSettled(job: Job) {
})
} else if (cutInHold) {
await mutate(owner, (jobs) => {
const row = jobs.find(item => item.liveJobId === job.id) || jobs.find(item => item.status === 'running')
const row = jobs.find(item => item.liveJobId === job.id)
if (!row) return
row.status = 'held'
row.liveJobId = undefined
@@ -963,7 +961,7 @@ export async function onLiveVideoSettled(job: Job) {
})
} else if (userPause) {
await mutateStore(owner, (store) => {
const row = store.jobs.find(item => item.liveJobId === job.id) || store.jobs.find(item => item.status === 'running')
const row = store.jobs.find(item => item.liveJobId === job.id)
if (!row) {
syncPausedFlag(store)
return
@@ -990,7 +988,7 @@ export async function onLiveVideoSettled(job: Job) {
: 'error'
await markStudioSettled(owner, job.id, status, job.error)
}
kickStudioQueue()
await kickStudioQueue()
}
function applyLiveJobPause(live: Job | undefined, pause: boolean, restoreAutoRun?: boolean) {