Add LoRA stacks with per-item strengths and named video/image generation presets so setups survive reload without mixing Klein onto MiniMax. Keep LTX Pink Cherry and xAIGen LoRAs on xAIGen, and run Recommend on Beast.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-08-28 15:24:44 -05:00
co-authored by Cursor
parent 0af3cddb14
commit f8db0d626a
36 changed files with 1767 additions and 246 deletions
+8 -93
View File
@@ -187,7 +187,7 @@ async function ensureUnlocked(onStatus: StatusFn) {
onStatus({
state: 'starting',
message: 'Image ComfyUI is offline. Starting the sidecar instance...',
message: 'Image ComfyUI is offline. Starting the Beast instance...',
host,
processRunning: Boolean(remote?.process)
})
@@ -195,7 +195,7 @@ async function ensureUnlocked(onStatus: StatusFn) {
if (!started.started && started.reason === 'no-launcher') {
throw createError({
statusCode: 503,
statusMessage: 'Image ComfyUI is offline and the sidecar host agent did not start it. Confirm the agent on 192.168.77.101:8199 is running.'
statusMessage: 'Image ComfyUI is offline and the Beast host agent did not start it. Confirm COMFY_CONTROL_URL is running.'
})
}
@@ -230,111 +230,26 @@ export function ensureImageComfyReady(onStatus: StatusFn = () => undefined) {
}
let sidecarGate: Promise<unknown> = Promise.resolve()
let sidecarLastStartAt = 0
function sidecarControlSettings() {
const config = useRuntimeConfig()
return {
host: getSidecarImageHost(),
controlUrl: String(config.imageComfyControlUrl || process.env.IMAGE_COMFY_CONTROL_URL || '').replace(/\/$/, ''),
controlToken: String(config.imageComfyControlToken || process.env.IMAGE_COMFY_CONTROL_TOKEN || ''),
healthTimeoutMs: 2500,
startTimeoutMs: Number(process.env.IMAGE_COMFY_START_TIMEOUT_MS || 180_000)
}
}
async function sidecarControlRequest(path: string, method = 'GET') {
const { controlUrl, controlToken } = sidecarControlSettings()
if (!controlUrl) return null
try {
const res = await fetch(`${controlUrl}${path}`, {
method,
headers: {
Accept: 'application/json',
...(controlToken ? { Authorization: `Bearer ${controlToken}` } : {})
},
signal: AbortSignal.timeout(5000)
})
if (!res.ok) return { ok: false, status: res.status }
return await res.json() as {
ok?: boolean
http?: boolean
process?: boolean
started?: boolean
already?: boolean
}
} catch {
return null
}
}
async function startSidecarComfy() {
const now = Date.now()
if (now - sidecarLastStartAt < 15_000) {
log('sidecar-start-skipped', { reason: 'recent-start' })
return { started: false, reason: 'recent-start' as const }
}
sidecarLastStartAt = now
const remote = await sidecarControlRequest('/start', 'POST')
if (remote?.ok || remote?.started) {
log('sidecar-start-remote', {})
return { started: true, reason: 'remote' as const }
}
return { started: false, reason: 'no-launcher' as const }
}
async function ensureSidecarUnlocked(onStatus: StatusFn) {
const cfg = sidecarControlSettings()
const host = cfg.host
const host = getSidecarImageHost()
if (!host) {
throw createError({
statusCode: 503,
statusMessage: 'Sidecar Qwen VL is not configured. Set IMAGE_COMFY_HOST or IMAGE_COMFY_FALLBACK_HOST.'
statusMessage: 'Qwen VL is not configured. Set COMFY_HOST or IMAGE_COMFY_HOST to Beast.'
})
}
onStatus({ state: 'offline', message: 'Checking Sidecar Qwen VL…', host, box: 'sidecar' })
const health = await checkImageComfyHttp(cfg.healthTimeoutMs, host)
onStatus({ state: 'offline', message: 'Checking Beast Qwen VL…', host, box: 'beast' })
const health = await checkImageComfyHttp(2500, host)
if (health.ok) {
onStatus({ state: 'online', message: 'Sidecar Qwen VL online', host, box: 'sidecar' })
onStatus({ state: 'online', message: 'Beast Qwen VL online', host, box: 'beast' })
return
}
onStatus({
state: 'starting',
message: 'Sidecar is offline. Starting Qwen VL on 192.168.77.101…',
host,
box: 'sidecar'
})
const started = await startSidecarComfy()
if (!started.started && started.reason === 'no-launcher') {
throw createError({
statusCode: 503,
statusMessage: 'Sidecar is offline and the host agent did not start it. Confirm the agent on 192.168.77.101:8199 is running.'
})
}
const deadline = Date.now() + cfg.startTimeoutMs
let attempt = 0
while (Date.now() < deadline) {
attempt += 1
onStatus({
state: 'starting',
message: `Starting Sidecar Qwen VL… waiting for Comfy (${attempt})`,
host,
box: 'sidecar'
})
const next = await checkImageComfyHttp(cfg.healthTimeoutMs, host)
if (next.ok) {
onStatus({ state: 'online', message: 'Sidecar Qwen VL online', host, box: 'sidecar', processRunning: true })
return
}
await sleep(2000)
}
throw createError({
statusCode: 503,
statusMessage: 'Started Sidecar Qwen VL but it never answered. The 101 box can take a couple of minutes to load after a cold boot.'
statusMessage: `Beast ComfyUI is offline (${host}). Recommend needs Qwen VL on that instance and will not start a sidecar.`
})
}