Tighten YuE lyrics validation and Comfy music workflow wiring.

Require section tags before queueing YuE and keep the ACE/YuE path changes that were already in progress.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-03 20:32:41 -05:00
co-authored by Cursor
parent 47f14d7be2
commit 17d4d4ffdc
8 changed files with 114 additions and 29 deletions
+64 -15
View File
@@ -390,6 +390,35 @@ async function tryRecover() {
}
}
async function attachLiveMusic(opts: {
studioId?: string
liveId: string
message?: string
progress?: number
}) {
const liveId = String(opts.liveId || '').trim()
if (!liveId) return
if (opts.studioId) studioJobId.value = opts.studioId
liveMusicId.value = opts.studioId || liveMusicId.value || liveId
queued.value = false
busy.value = true
settled = false
if (typeof opts.progress === 'number') progress.value = opts.progress
if (opts.message) status.value = opts.message
else if (!status.value || /waiting for a generate|waiting in the job queue|waiting for gpu/i.test(status.value)) {
status.value = selectedEngine.value === 'yue'
? 'YuE running on Comfy — Stage A can take 10–20+ minutes'
: 'Generating…'
}
if (jobId.value !== liveId) {
jobId.value = liveId
listen(liveId)
}
if (!recoverPoll) {
recoverPoll = setInterval(() => { void tryRecover() }, 8000)
}
}
async function refreshStudioQueue() {
const data = await $fetch<{
jobs?: Array<{
@@ -405,6 +434,23 @@ async function refreshStudioQueue() {
const musicRow = rows.find(job => job.kind === 'music' && (job.status === 'waiting' || job.status === 'running' || job.status === 'held'))
liveMusicId.value = musicRow?.id || ''
queueCount.value = data.waitingCount || rows.filter(job => job.status === 'waiting').length
if (musicRow?.status === 'running' && musicRow.liveJobId) {
await attachLiveMusic({
studioId: musicRow.id,
liveId: musicRow.liveJobId
})
} else if (musicRow && (musicRow.status === 'waiting' || (musicRow.status === 'held' && !musicRow.liveJobId))) {
studioJobId.value = musicRow.id
queued.value = true
busy.value = true
status.value = musicRow.status === 'held'
? 'Paused in the job queue'
: (selectedEngine.value === 'yue'
? 'Waiting for GPU… YuE is heavy; do not spam Generate'
: 'Waiting in the job queue…')
}
if (!studioJobId.value) return
const row = rows.find(job => job.id === studioJobId.value)
if (!row) {
@@ -429,16 +475,7 @@ async function refreshStudioQueue() {
return
}
if (row.status === 'running' && row.liveJobId) {
queued.value = false
if (!jobId.value || jobId.value !== row.liveJobId) {
jobId.value = row.liveJobId
listen(row.liveJobId)
}
if (/waiting/i.test(status.value)) {
status.value = selectedEngine.value === 'yue'
? 'YuE running on Comfy — Stage A can take 10–20+ minutes'
: 'Generating…'
}
await attachLiveMusic({ studioId: row.id, liveId: row.liveJobId })
}
if (row.status === 'error') {
queued.value = false
@@ -449,13 +486,24 @@ async function refreshStudioQueue() {
return
}
if (row.liveJobId && row.liveJobId !== jobId.value) {
queued.value = false
jobId.value = row.liveJobId
status.value = status.value || 'Generating…'
listen(row.liveJobId)
await attachLiveMusic({ studioId: row.id, liveId: row.liveJobId })
}
}
async function resumeActiveMusic() {
const active = await $fetch<{
music?: { jobId?: string; message?: string; progress?: number; status?: string }
} | null>('/api/generate/active').catch(() => null)
const liveId = active?.music?.jobId
if (!liveId) return
if (active?.music?.status === 'error' || active?.music?.status === 'complete') return
await attachLiveMusic({
liveId,
message: active?.music?.message,
progress: typeof active?.music?.progress === 'number' ? active.music.progress : undefined
})
}
function applyEvent(payload: Record<string, any>) {
if (payload.message) status.value = payload.message
if (typeof payload.progress === 'number') progress.value = payload.progress
@@ -660,6 +708,7 @@ onMounted(async () => {
await loadLibrary()
await loadMusicPresets()
applyIncomingMusic()
await resumeActiveMusic()
await refreshStudioQueue()
stopQueuePoll()
queuePoll = setInterval(() => { void refreshStudioQueue() }, 8000)
@@ -670,7 +719,7 @@ onMounted(async () => {
status.value = 'Loaded from library'
return
}
if (!audioUrl.value) {
if (!audioUrl.value && !busy.value) {
try {
const recovered = await $fetch<Record<string, any>>('/api/generate/recover', { method: 'POST', body: {} })
if (recovered?.trackId && /recovered/i.test(String(recovered.message || ''))) {