Add a wildcard (any-type) optional 'signal' input to Agent Receive. Wiring any
upstream output into it creates a dependency edge so ComfyUI runs that node
first — e.g. force an Agent Emit (send the prompt) to fire before Receive starts
waiting. The value is ignored; presence is what orders execution.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
push.py and console_relay.py take --ip (default 127.0.0.1) and --port (9188),
building http://<ip>:<port>/mcp; --url still overrides. console_relay.sh takes
the IP as its first arg (./console_relay.sh 192.168.1.12) or prompts for it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every emit/pull/push/receive now logs to the ComfyUI console with channel,
text preview, image path, and seed. comfy_push validates the sender's input and
emits clear '⚠ SENDER PROBLEM' warnings (also returned to the agent) when an
image_path doesn't exist on the host, a wrong type is passed, or the message is
empty. Agent Receive logs each step and, instead of crashing on a bad/missing
image path, logs exactly what the sender got wrong and falls back to a blank
image. Helps diagnose 'error when receiving' caused by the sender.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the single-slot inbox/outbox with FIFO deques: every emit and push is
kept and delivered oldest-first, exactly once. comfy_pull and Agent Receive now
dequeue the oldest item (empty when drained) instead of overwriting/replaying the
latest. keep_last now holds the last *delivered* message (store.peek returns
last_out). list_channels reports in_pending/out_pending depths. Docs + tests
updated for FIFO ordering.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a seed lane alongside text/image: Agent Emit gains an optional seed input
(graph -> agent), Agent Receive gains a seed output (agent -> graph, 0 if none),
and comfy_pull/comfy_push carry it. Wire a KSampler seed into Emit to tell the
agent, or have the agent comfy_push(seed=...) to drive the next generation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The blocking receive sat in a single cond.wait() and never checked ComfyUI's
interrupt flag, so Cancel didn't stop it. receive() now takes a should_abort
callback and waits in short slices; the node passes ComfyUI's
throw_exception_if_processing_interrupted so hitting Cancel breaks out promptly
(no-op outside ComfyUI). Covered by an abort test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
keep_last: on timeout, re-output the last message (via new store.peek, which
reads the outbox without consuming) instead of blanking - holds the display
steady between messages in Auto Queue.
stop_on_timeout: on timeout, send an 'agent-bridge-stop-autoqueue' event; a new
web/ JS extension toggles ComfyUI's Auto Queue off so the loop halts when the
stream goes quiet (best-effort across frontend versions). Registers WEB_DIRECTORY.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ComfyUI can import the store module under two identities (one for the nodes, one
for the in-process MCP server), giving each its own class-level singleton. Result:
an agent's comfy_push went to one store while the node-side Agent Receive read the
other, so messages never crossed (the reported 'no text' / 30s timeouts). Stash
the singleton on builtins so it's one instance per process regardless of import
path. Reproduced with a dual-module-identity test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ComfyUI caches a node's output unless its inputs change. Agent Receive's inputs
(channel, wait_seconds) are constant, so re-queuing served a stale cached result
instead of the agent's newly pushed message. Add IS_CHANGED returning NaN so the
node is always dirty and re-polls the channel on every queue.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A missing 'mcp' package made the whole custom_node load fail with
ModuleNotFoundError. Now the Agent Emit/Receive nodes register regardless and the
bridge prints an actionable install hint (with ComfyUI's python path) instead of
crashing. Use __package__ to pick relative vs sys.path import so a broad except
no longer masks a missing-dependency error. Adds a no-mcp load test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ComfyUI execs __init__.py as a package without the node dir on sys.path, so the
absolute 'from src...' imports raised ModuleNotFoundError: No module named
'src.nodes'. Switch internal modules to package-relative imports and import them
relatively in __init__ (with a sys.path fallback for standalone/test use, so no
generic 'src' leaks onto sys.path to collide with other custom nodes). Adds a
regression test that loads the package the way ComfyUI does.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Zero-config images for remote/Docker: default COMFY_BRIDGE_TMP to ComfyUI's
output dir (output/agent_bridge via folder_paths), which is typically a shared
same-path mount, so comfy_pull/comfy_push paths resolve on both sides. For
containers that mount that folder at a different internal path, add
COMFY_BRIDGE_TMP_PUBLIC: comfy_pull advertises the agent-visible path and
comfy_push translates it back.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a host bind env var (mirrors the port var) plus a README section on
running ComfyUI in Docker: bind 0.0.0.0, publish the port, point the agent at
the server IP, and handle images via a shared folder with matching paths.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Lead the section with the Codex plugin install (codex plugin marketplace
add + codex plugin add), which auto-registers the comfy MCP server, then
the simpler 'codex mcp add comfy --url ...', keep the stdio shim fallback,
and the Claude Code HTTP command. Commands match what was verified on
codex-cli 0.142.3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Package the repo as a folder-installable Codex plugin (verified on
codex-cli 0.142.3):
- .agents/plugins/marketplace.json: marketplace 'comfyui-agents' listing
the repo root itself as the plugin (source.path '.'), policy
authentication ON_USE so the local no-auth HTTP server installs without
an OAuth prompt.
- .codex-plugin/plugin.json: plugin 'comfyui-agents', skills ./skills/,
mcpServers ./.codex-plugin/mcp.json (string-file form, matching the
real OpenAI connector plugins).
- .codex-plugin/mcp.json: declares the 'comfy' HTTP MCP server at
http://127.0.0.1:9188/mcp via {type: http}; Codex registers it as a
streamable_http transport.
- skills/comfyui-bridge/SKILL.md: concise skill teaching the named-channel
model, the five tools, and the core push/run/pull loop.
Verified: codex plugin marketplace add . -> codex plugin add
comfyui-agents@comfyui-agents -> codex mcp get comfy reports the URL.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
README: add a Codex section with both connection methods (HTTP url entry
and the stdio shim), matching the schema codex 0.142.3 writes; note that
AgentReceive's wait_seconds blocks a ComfyUI worker; add COMFY_BRIDGE_TMP_TTL
to the env-vars table. Design doc: add a decisions-log line recording that
the MCP server ships on a separate daemon-thread side port (9188, /mcp).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a comment clarifying the run_workflow history poll returns as soon as
any output node appears, and that the design's upgrade path is the ComfyUI
websocket `executed` event.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Switch store.py and workflows.py to the PEP 604 X | None syntax and drop
the now-unused `from typing import Optional`. Pure refactor; no behavior
change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Image.fromarray(arr) infers RGB from the (H,W,3) array shape; the explicit
mode="RGB" is deprecated in Pillow and slated for removal in 13. Clears the
three Pillow DeprecationWarnings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
save_tensor_png now reaps img_*.png files older than COMFY_BRIDGE_TMP_TTL
(env, default 3600s) after each write, so .comfy_bridge_tmp/ no longer
grows forever. Robust to races (ignores FileNotFoundError/OSError) and
never deletes the file just written.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the honest stub with a working stdio<->streamable-HTTP MCP proxy:
connect upstream to COMFY_BRIDGE_URL as an HTTP MCP client, then run a
low-level stdio MCP server whose list_tools/call_tool forward to the
upstream session. Exits non-zero with a clear stderr message on connection
failure. Adds a real end-to-end round-trip test (boots the in-process
bridge on a free port, spawns the shim, drives it via a stdio MCP client).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>