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),
74 lines • 3.32 kB
JavaScript
// Shapes the `set_options` reply frames (the model/effort picker's acks).
//
// WHY THIS EXISTS: each `set_options` is handled in a detached async task
// (model discovery + manager.setOptions are awaited), so acks can complete —
// and arrive at the client — OUT OF ORDER, and the ack itself used to carry no
// request identity. A client with more than one attempt outstanding (e.g. a
// timed-out pick followed by a retry) could not tell which ack answered which
// request. Clients may now stamp the request with an opaque `cid`; we echo it
// verbatim on the ack, alongside `requested_model` (the id the client ASKED
// for, pre-resolution/pre-guard), so correlation is exact.
//
// WHY `cid` AND NOT `rid`: `rid` is RESERVED on the client→server direction —
// the ui-bridge consumes ANY inbound frame carrying a string `rid` as the
// reply to a canvas command (ui-bridge.ts, the `pending` map) and it never
// reaches the orchestrator's event handler. Verified live: a rid-stamped
// set_options is silently dropped. `cid` is the established client→server
// correlation field (call_tool, list_history, upload_media) and flows through
// untouched.
//
// Backward compatible in both directions:
// • a request WITHOUT `cid` produces the exact ack shape shipped before
// (no new fields except `requested_model` when a model was requested,
// which old panels ignore);
// • the error path keeps the legacy `say` frame for old clients, and ONLY
// adds an ok:false options ack when the request carried a `cid` (so old
// panels never see a failure ack they don't expect).
/** Read the optional correlation fields off a raw `set_options` event. */
export function optionsRequestMeta(event) {
return {
...(typeof event.cid === "string" && event.cid ? { cid: event.cid } : {}),
...(typeof event.model === "string" && event.model
? { requestedModel: event.model }
: {}),
};
}
/** The success ack: what was applied + exact request correlation. */
export function optionsAckFrame(applied, meta) {
return {
type: "ack",
ok: true,
kind: "options",
model: applied.model,
effort: applied.effort ?? null,
restarted: applied.restarted,
// Effort changed mid-turn → it takes effect once the current turn ends
// (we never interrupt a live reply). The client can note this.
deferred: applied.deferred,
...(meta.cid !== undefined ? { cid: meta.cid } : {}),
...(meta.requestedModel !== undefined
? { requested_model: meta.requestedModel }
: {}),
};
}
/**
* The failure ack — ONLY for cid-stamped requests (returns null otherwise, so
* legacy clients keep seeing just the `say` and never a failure ack shape they
* don't handle). Lets a correlating client resolve the exact attempt that
* failed instead of waiting out a timeout.
*/
export function optionsErrorAckFrame(message, meta) {
if (meta.cid === undefined)
return null;
return {
type: "ack",
ok: false,
kind: "options",
message,
cid: meta.cid,
...(meta.requestedModel !== undefined
? { requested_model: meta.requestedModel }
: {}),
};
}
//# sourceMappingURL=options-ack.js.map