Replace Comfy YuE with standalone YuEGP profile 1

This commit is contained in:
Towsty
2026-09-07 20:24:47 -05:00
parent eeff12cdab
commit c2b6032e49
33 changed files with 976 additions and 294 deletions
+20 -5
View File
@@ -76,6 +76,7 @@ export interface StudioJobPayload {
lyrics?: string
instrumental?: boolean
lyricsStrength?: number
yueProfile?: 1 | 3
musicEngine?: import('~/utils/music').MusicEngine
}
@@ -283,6 +284,7 @@ function failZombieLiveJob(job: Job, error: string) {
function sweepStaleLiveJobs() {
const now = Date.now()
for (const job of listJobs()) {
if (job.yueGp) continue
if (job.saving) continue
if (job.status === 'queued' && !job.promptId && now - job.startedAt >= QUEUED_GRACE_MS) {
failZombieLiveJob(job, 'Job never started')
@@ -302,6 +304,7 @@ async function reapZombieLiveJobs() {
const { fetchHistory } = await import('~/server/utils/comfy')
for (const job of listJobs()) {
// Never interrupt download/stitch/library save — Comfy is idle then by design.
if (job.yueGp) continue
if (job.saving) continue
if (job.library?.chainContinuing) continue
if (job.status !== 'running' && job.status !== 'uploading' && job.status !== 'queued') continue
@@ -346,6 +349,7 @@ async function reapZombieLiveJobs() {
}
function liveJobOwnsGpu(job: Job) {
if (job.yueGp && ['running', 'queued', 'uploading'].includes(job.status)) return true
if (job.library?.stopAfterCurrent) return false
if (job.library?.chainContinuing) return true
if (job.saving) return true
@@ -365,6 +369,7 @@ function liveJobOwnsGpu(job: Job) {
*/
function clearDeadGpuClaimsForForceStart() {
for (const live of listJobs()) {
if (live.yueGp) continue
if (live.saving) continue
if (jobIsLocallySubmitting(live)) continue
if (live.status !== 'running' && live.status !== 'queued' && live.status !== 'uploading') {
@@ -586,6 +591,10 @@ export async function clearStuckStudioWork(owner: string) {
if (job.library?.ownerKey !== owner) continue
if (job.status === 'complete' || job.status === 'error' || job.status === 'cancelled') continue
liveIds.add(job.id)
if (job.yueGp) {
const { cancelYueGpJob } = await import('./yueGp')
await cancelYueGpJob(job)
}
job.status = 'cancelled'
job.error = 'Cleared by force reset'
if (job.library) {
@@ -647,6 +656,11 @@ async function stopLiveGeneration(liveJobId?: string, shotQueueId?: string) {
}
if (!liveJobId) return
const live = getJob(liveJobId)
if (live?.yueGp) {
const { cancelYueGpJob } = await import('./yueGp')
await cancelYueGpJob(live)
return
}
if (live) {
live.status = 'cancelled'
if (live.library) {
@@ -896,7 +910,7 @@ function repairStaleJobs(jobs: StudioJob[]) {
job.updatedAt = Date.now()
continue
}
if (job.status === 'error' && isTransientComfyError(job.lastError)) {
if (job.payload.musicEngine !== 'yue' && job.status === 'error' && isTransientComfyError(job.lastError)) {
job.status = 'waiting'
job.liveJobId = undefined
job.lastError = undefined
@@ -905,7 +919,7 @@ function repairStaleJobs(jobs: StudioJob[]) {
job.updatedAt = Date.now()
continue
}
if (job.status === 'held' && isTransientComfyError(job.lastError)) {
if (job.payload.musicEngine !== 'yue' && job.status === 'held' && isTransientComfyError(job.lastError)) {
job.status = 'waiting'
job.liveJobId = undefined
job.lastError = undefined
@@ -1285,7 +1299,7 @@ async function startStudioEditJob(item: StudioJob) {
height: payload.height,
steps: payload.steps,
turbo: true,
seed: payload.seed || Math.floor(Math.random() * 2_147_483_647),
seed: payload.seed ?? Math.floor(Math.random() * 2_147_483_647),
cfg: payload.cfg,
stillId: payload.stillId,
stillFilename: payload.stillFilename,
@@ -1375,12 +1389,13 @@ async function startStudioMusicJob(item: StudioJob) {
lyrics: payload.instrumental ? '' : (payload.lyrics || ''),
duration: payload.duration,
steps: payload.steps,
seed: payload.seed || Math.floor(Math.random() * 2_147_483_647),
seed: payload.seed ?? Math.floor(Math.random() * 2_147_483_647),
cfg: payload.cfg,
lyricsStrength: payload.instrumental ? 0 : (payload.lyricsStrength ?? 0.9),
instrumental: payload.instrumental === true,
folderLocked: payload.folderLocked,
engine: payload.musicEngine || 'ace-step',
yueProfile: payload.yueProfile ?? 1,
samplerName: payload.samplerName || 'euler',
scheduler: payload.scheduler || 'simple'
})
@@ -1650,7 +1665,7 @@ export async function onLiveVideoSettled(job: Job) {
return
}
const remaining = remainingStudioShots(job)
const wakeFail = job.status === 'error' && remaining > 0 && isTransientComfyError(job.error)
const wakeFail = !job.yueGp && job.status === 'error' && remaining > 0 && isTransientComfyError(job.error)
const failed = (job.status === 'error' || job.status === 'cancelled') && !wakeFail
await mutateStore(owner, (store) => {