Start ComfyUI automatically before queueing MiniMax jobs.
Health-check /system_stats, wait if the desktop is booting or busy, and start the host instance when it is fully offline. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import http from 'node:http'
|
||||
import { execFile, spawn } from 'node:child_process'
|
||||
import { promisify } from 'node:util'
|
||||
|
||||
const execFileAsync = promisify(execFile)
|
||||
const port = Number(process.env.COMFY_CONTROL_PORT || 8199)
|
||||
const token = process.env.COMFY_CONTROL_TOKEN || ''
|
||||
const comfyHttp = (process.env.COMFY_HOST || 'http://127.0.0.1:8188').replace(/\/$/, '')
|
||||
|
||||
function json(res, status, body) {
|
||||
const payload = JSON.stringify(body)
|
||||
res.writeHead(status, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) })
|
||||
res.end(payload)
|
||||
}
|
||||
|
||||
function authorized(req) {
|
||||
if (!token) return true
|
||||
const header = String(req.headers.authorization || '')
|
||||
return header === `Bearer ${token}`
|
||||
}
|
||||
|
||||
async function httpUp() {
|
||||
try {
|
||||
const res = await fetch(`${comfyHttp}/system_stats`, { signal: AbortSignal.timeout(2500) })
|
||||
return res.ok
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function processUp() {
|
||||
try {
|
||||
const { stdout } = await execFileAsync('tasklist', ['/FO', 'CSV', '/NH'], { windowsHide: true, timeout: 4000 })
|
||||
if (/Comfy Desktop|ComfyUI/i.test(stdout)) return true
|
||||
} catch { /* ignore */ }
|
||||
try {
|
||||
const { stdout } = await execFileAsync('powershell.exe', [
|
||||
'-NoProfile', '-Command',
|
||||
"Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match 'ComfyUI\\\\main.py|ComfyUI/main.py' } | Select-Object -First 1 -ExpandProperty ProcessId"
|
||||
], { windowsHide: true, timeout: 6000 })
|
||||
return Boolean(String(stdout).trim())
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function launchCommand() {
|
||||
if (process.env.COMFY_LAUNCH_CMD) return process.env.COMFY_LAUNCH_CMD
|
||||
const local = process.env.LOCALAPPDATA || ''
|
||||
const desktop = `${local}\\Programs\\Comfy Desktop\\Comfy Desktop.exe`
|
||||
return `start "" "${desktop}"`
|
||||
}
|
||||
|
||||
function startComfy() {
|
||||
const command = launchCommand()
|
||||
const child = spawn(command, { shell: true, detached: true, stdio: 'ignore', windowsHide: true })
|
||||
child.unref()
|
||||
return { started: true, command }
|
||||
}
|
||||
|
||||
const server = http.createServer(async (req, res) => {
|
||||
if (!authorized(req)) return json(res, 401, { ok: false, error: 'unauthorized' })
|
||||
const url = new URL(req.url || '/', 'http://localhost')
|
||||
if (req.method === 'GET' && url.pathname === '/status') {
|
||||
const [httpReady, process] = await Promise.all([httpUp(), processUp()])
|
||||
return json(res, 200, { ok: true, http: httpReady, process })
|
||||
}
|
||||
if (req.method === 'POST' && url.pathname === '/start') {
|
||||
if (await httpUp()) return json(res, 200, { ok: true, started: false, already: true })
|
||||
if (await processUp()) return json(res, 200, { ok: true, started: false, booting: true })
|
||||
const launched = startComfy()
|
||||
return json(res, 200, { ok: true, ...launched })
|
||||
}
|
||||
json(res, 404, { ok: false, error: 'not found' })
|
||||
})
|
||||
|
||||
server.listen(port, '0.0.0.0', () => {
|
||||
console.log(JSON.stringify({ src: 'comfy-host-agent', event: 'listen', port, comfyHttp }))
|
||||
})
|
||||
Reference in New Issue
Block a user