UNPKG

comfyui-mcp

Version:

Local-first, agent-native control plane for ComfyUI — MCP server + autonomous sidebar agent that drives your live graph in natural language on ANY LLM: Claude/ChatGPT/Gemini on your subscription (no API key), free local models via Ollama (fully offline),

73 lines • 3.51 kB
// Which panel-agent backends share THIS machine's GPU with ComfyUI while a // render runs — the single locality determination behind the VRAM handoff in // orchestrator/index.ts (free the local model's VRAM where the server has an // unload surface, HOLD chats until the render finishes, then warm back). // // "Local" = the backend's server answers on a LOOPBACK URL: same machine, // same GPU. A remote host (e.g. COMFYUI_MCP_LLAMACPP_HOST=http://gpu-box:8080/v1) // is someone else's VRAM and must NOT be gated — holding those chats would // stall work for a contention that doesn't exist. /** Loopback-URL locality test (127.0.0.1 / localhost / [::1], any port, with * or without a path suffix like /v1). ONE regex for every backend in the * handoff so the locality rule can't drift between providers. */ export function isLoopbackServerUrl(host) { return /^https?:\/\/(127\.0\.0\.1|localhost|\[::1\])(:|\/|$)/i.test(host); } /** True when the llama.cpp server (llama-server, or llama-swap in front of it) * is local — its model holds VRAM on the GPU ComfyUI renders on. */ export function isLocalLlamacpp(host) { return isLoopbackServerUrl(host); } /** True when `backend`'s LLM shares the GPU ComfyUI renders on, so its chats * are HELD while a render runs (and its model unloaded where the server has * an unload surface). Any other backend — claude/codex/gemini/custom/… — * never touches local VRAM. */ export function backendSharesRenderGpu(backend, local) { switch (backend) { case "ollama": return local.ollama; case "lmstudio": return local.lmstudio; case "llamacpp": return local.llamacpp; default: return false; } } /** Is the render-time VRAM handoff on? Default on; opt out with * COMFYUI_MCP_PAUSE_LOCAL_ON_GEN=0 — the neutral name now that the handoff * covers three backends. The legacy COMFYUI_MCP_OLLAMA_PAUSE_ON_GEN=0 is * still honored when the new name is unset. */ export function pauseLocalOnGenEnabled(env = process.env) { return (env.COMFYUI_MCP_PAUSE_LOCAL_ON_GEN ?? env.COMFYUI_MCP_OLLAMA_PAUSE_ON_GEN) !== "0"; } /** * ONE hold notice per render, per recipient — not one per held message (#2290). * * The hold itself is announced at the moment a chat is withheld, but a person who types * three lines in a row during one render triggers that code path three times, and three * identical "a render is running" bubbles read worse than the silence they replaced. This * tracks which recipients have already been told about the render currently in flight. * * Scoped to the RECIPIENT (the tab the notice is pushed to), not to the shared conversation: * a second tab that sends its own message during the same render has been told nothing yet, * and "I've queued your message" is only true for whoever sent one. * * `reset()` marks a hold-episode boundary — the render ended (or a new one began), so the * next held message is a new wait and announces again. */ export class RenderHoldNotice { told = new Set(); /** True exactly once per recipient per hold episode: this caller should announce. */ claim(recipient) { if (this.told.has(recipient)) return false; this.told.add(recipient); return true; } /** A new hold episode starts (or the current one ended) — everyone is untold again. */ reset() { this.told.clear(); } } //# sourceMappingURL=local-vram.js.map