Add Image v2 as a sibling of Image edit, with separate Klein graphs.
Keep the v1 Image tab on its dual-branch template. The host agent follows Desktop's live port so Coolify stays on :8198. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,36 +23,73 @@ function authorized(req) {
|
||||
return header === `Bearer ${token}`
|
||||
}
|
||||
|
||||
function candidatePorts() {
|
||||
const ports = new Set([8188, 8189])
|
||||
try {
|
||||
const url = new URL(defaultHttp.includes('://') ? defaultHttp : `http://${defaultHttp}`)
|
||||
if (url.port) ports.add(Number(url.port))
|
||||
} catch { /* ignore */ }
|
||||
function lockPorts() {
|
||||
const ports = []
|
||||
try {
|
||||
const dir = join(process.env.APPDATA || '', 'Comfy Desktop', 'port-locks')
|
||||
for (const name of readdirSync(dir)) {
|
||||
const match = name.match(/^port-(\d+)\.json$/)
|
||||
if (match) ports.add(Number(match[1]))
|
||||
if (match) ports.push(Number(match[1]))
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
return [...ports]
|
||||
return ports
|
||||
}
|
||||
|
||||
async function probe(portNum) {
|
||||
function candidatePorts() {
|
||||
const skip = new Set([port, proxyPort])
|
||||
const ordered = []
|
||||
const seen = new Set()
|
||||
const add = (value) => {
|
||||
const next = Number(value)
|
||||
if (!Number.isInteger(next) || next < 1 || next > 65535) return
|
||||
if (skip.has(next) || seen.has(next)) return
|
||||
seen.add(next)
|
||||
ordered.push(next)
|
||||
}
|
||||
for (const next of lockPorts()) add(next)
|
||||
try {
|
||||
const url = new URL(defaultHttp.includes('://') ? defaultHttp : `http://${defaultHttp}`)
|
||||
if (url.port) add(url.port)
|
||||
} catch { /* ignore */ }
|
||||
for (let next = 8188; next <= 8210; next++) add(next)
|
||||
return ordered
|
||||
}
|
||||
|
||||
async function probeStats(portNum) {
|
||||
try {
|
||||
const res = await fetch(`http://127.0.0.1:${portNum}/system_stats`, { signal: AbortSignal.timeout(2500) })
|
||||
return res.ok
|
||||
if (!res.ok) return null
|
||||
const stats = await res.json()
|
||||
if (!stats?.system) return null
|
||||
return stats
|
||||
} catch {
|
||||
return false
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function advertisedPort(stats) {
|
||||
const argv = stats?.system?.argv
|
||||
if (!Array.isArray(argv)) return 0
|
||||
const index = argv.findIndex(item => String(item) === '--port')
|
||||
if (index >= 0) return Number(argv[index + 1]) || 0
|
||||
const flag = argv.find(item => /^--port=\d+$/.test(String(item)))
|
||||
if (flag) return Number(String(flag).split('=')[1]) || 0
|
||||
return 0
|
||||
}
|
||||
|
||||
async function findHealthyPort() {
|
||||
const found = []
|
||||
for (const next of candidatePorts()) {
|
||||
if (await probe(next)) return next
|
||||
const stats = await probeStats(next)
|
||||
if (!stats) continue
|
||||
found.push({ port: next, advertised: advertisedPort(stats) })
|
||||
}
|
||||
return 0
|
||||
const native = found.find(item => item.advertised && item.advertised === item.port)
|
||||
if (native) return native.port
|
||||
for (const item of found) {
|
||||
if (item.advertised && found.some(other => other.port === item.advertised)) return item.advertised
|
||||
}
|
||||
return found[0]?.port || 0
|
||||
}
|
||||
|
||||
let proxyServer = null
|
||||
@@ -60,12 +97,11 @@ let proxyTarget = 0
|
||||
|
||||
function ensureProxy(targetPort) {
|
||||
if (!targetPort) return
|
||||
if (proxyServer && proxyTarget === targetPort) return
|
||||
proxyTarget = targetPort
|
||||
if (proxyServer) {
|
||||
try { proxyServer.close() } catch { /* ignore */ }
|
||||
proxyServer = null
|
||||
if (proxyTarget !== targetPort) {
|
||||
proxyTarget = targetPort
|
||||
console.log(JSON.stringify({ src: 'comfy-host-agent', event: 'proxy-target', listen: proxyPort, target: proxyTarget }))
|
||||
}
|
||||
if (proxyServer) return
|
||||
proxyServer = net.createServer((client) => {
|
||||
const upstream = net.connect(proxyTarget, '127.0.0.1')
|
||||
const fail = () => {
|
||||
@@ -85,6 +121,12 @@ function ensureProxy(targetPort) {
|
||||
})
|
||||
}
|
||||
|
||||
async function syncProxy() {
|
||||
const healthyPort = await findHealthyPort()
|
||||
if (healthyPort) ensureProxy(healthyPort)
|
||||
return healthyPort
|
||||
}
|
||||
|
||||
async function processUp() {
|
||||
try {
|
||||
const { stdout } = await execFileAsync('tasklist', ['/FO', 'CSV', '/NH'], { windowsHide: true, timeout: 4000 })
|
||||
@@ -231,8 +273,7 @@ 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 [healthyPort, process] = await Promise.all([findHealthyPort(), processUp()])
|
||||
if (healthyPort) ensureProxy(healthyPort)
|
||||
const [healthyPort, process] = await Promise.all([syncProxy(), processUp()])
|
||||
return json(res, 200, {
|
||||
ok: true,
|
||||
http: Boolean(healthyPort),
|
||||
@@ -242,9 +283,8 @@ const server = http.createServer(async (req, res) => {
|
||||
})
|
||||
}
|
||||
if (req.method === 'POST' && url.pathname === '/start') {
|
||||
const healthyPort = await findHealthyPort()
|
||||
const healthyPort = await syncProxy()
|
||||
if (healthyPort) {
|
||||
ensureProxy(healthyPort)
|
||||
return json(res, 200, { ok: true, started: false, already: true, port: healthyPort, proxyPort })
|
||||
}
|
||||
const launched = startComfy()
|
||||
@@ -258,8 +298,7 @@ const server = http.createServer(async (req, res) => {
|
||||
})
|
||||
|
||||
server.listen(port, '0.0.0.0', async () => {
|
||||
const healthyPort = await findHealthyPort()
|
||||
if (healthyPort) ensureProxy(healthyPort)
|
||||
const healthyPort = await syncProxy()
|
||||
console.log(JSON.stringify({
|
||||
src: 'comfy-host-agent',
|
||||
event: 'listen',
|
||||
@@ -268,4 +307,7 @@ server.listen(port, '0.0.0.0', async () => {
|
||||
comfyPort: healthyPort || null,
|
||||
candidates: candidatePorts()
|
||||
}))
|
||||
setInterval(() => {
|
||||
syncProxy().catch(() => {})
|
||||
}, 3000)
|
||||
})
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cd /d "%~dp0.."
|
||||
node "%~dp0comfy-host-agent.mjs"
|
||||
Reference in New Issue
Block a user