Agent Feedback
The thumbs-up button your AI agent can actually read
- images
- feedback_json
- chosen_index
The half of the loop nobody built
Agents in ComfyUI got good fast. MCP servers like comfy-mcp will happily let Claude Code build you a graph and hit Run. What they can't do is hand you three options and find out which one you liked. The agent proposes, you judge, and the judgment evaporates - you close the tab and retype "no, more like the second one" into a chat window.
Agent Feedback is the return path. It sits in your graph, renders the candidate images as thumbnails, and gives you vote buttons, keep/change chips, a 0–5 rating, a push/pull slider and a free-text box. Then it ships all of that to whatever is listening.
What you actually interact with
The node is an output node, so it has no downstream requirement - but you do need to feed it and label it.
images(optional, IMAGE) - the candidates to show and vote on. Batch order maps to your labels, so batch index 0 is the first line oflabels.labels(multiline string) - one label per line. With three thumbnails, line 1 captions the first, and so on. Leave a line blank and it silently shifts: blank lines are dropped, so thumbnail 2 inherits line 3's name and everything after it is off by one. Name every candidate.session_idandround- the tag the agent uses to tie this batch of feedback back to the round that produced it. If you're driving this from an agent, the pack's README suggests putting anextra.agentobject in the proposed workflow; that survives your edits and saves and comes back on every run event, so the agent can match runs to its own rounds without you typing anything.rating(0–5, slider) - 0 means unrated, per the tooltip, so it's a real "no opinion" rather than a score of zero.push(−1…1, slider) - the most interesting control in the node. −1 pulls back, 0 means refine in place, +1 pushes further in the current direction. It's a single scalar that tells a model-bending or prompt-iteration loop which way to walk.direction(multiline) - free text, and the tooltip gives the canonical example: "keep the pose, change the style."votesandchips- hidden JSON widgets. The vote buttons and the keep/change chips write them; don't hand-edit them unless you enjoy debugging malformed JSON.
The chips are a fixed vocabulary of composition, subject, palette, lighting, texture, style, each cycling between keep and change. That's the fastest signal you can give an agent: "palette: change, everything else: keep."
Outputs, and where they go
There are two: feedback_json (STRING) is the whole record - labels, votes, chips, rating, push, direction, chosen index - serialized. And chosen_index (INT) is the index of the first candidate you thumbed up, or −1 if you upvoted nothing.
Careful with that "first": upvote two candidates and chosen_index reports the earlier one, not the more popular one. There's no winner-by-count logic here, so use one thumb per round.
feedback_json is worth wiring into an AgentReportSink or a save-text node if you want the critique archived. chosen_index pairs naturally with Agent Variant Switch's selected input, which makes the vote drive the branch on the next run - and note that −1 clamps up to 1, so a round where you voted nothing falls back to candidate one rather than erroring.
The node also writes its record into its own UI output, which means it lands in ComfyUI's plain /history too. Agents that only speak the core API can still read your feedback without touching this pack's endpoints.
Run it, or don't
Press Run and the record is emitted as a feedback event before anything else matters. But the node also ships a Send to agent button, and that's the one you'll use most: it posts the current votes, rating and text straight to the bridge without re-running the graph. The status line under the chips tells you whether it went, with the event id. Run-delivered records are tagged run; button-delivered ones are tagged button, so an agent can tell them apart.
Install
Nothing exotic. No Python dependencies beyond ComfyUI itself, but two version floors: ComfyUI ≥ 0.18 and frontend ≥ 1.40, because the pack is written against the newer V3 node API with autogrow inputs. The pyproject.toml deliberately doesn't pin the frontend, so installing this will never move your frontend version for you.
cd ComfyUI/custom_nodes
git clone https://github.com/abuzreq/ComfyUI-Agent-Bridge
Or search Agent Bridge in ComfyUI Manager, or comfy node install comfyui-agent-bridge. Restart ComfyUI afterwards and the nodes appear under the agent_bridge category.
Where people get burned
The UI doesn't render. Nine times out of ten this is an old frontend. The vote row and chips are injected by the pack's own web/agent_bridge.js, which assumes the V3 node surface; on an older build you get a node with hidden widgets and no buttons instead of an error message. Update ComfyUI before filing anything.
The agent can't read the events. Agent routes need the per-install token, generated on first start at ComfyUI/user/agent_bridge/token and passed as the X-Agent-Bridge-Token header. It's in a file, not the URL, so a local script reads it and a web page can't. If ComfyUI is running with --listen, treat that token like a password.
Votes vanish after renaming. Votes are keyed by label text, so renaming a candidate mid-session orphans its vote. Vote, send, and only then relabel.
Wrong session. Leave session_id empty and everything lands in the default bucket. Fine for one person poking at one graph, useless the moment you're running two experiments at once.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| labels | STRING | One label per line | |
| session_id | STRING | — | |
| round | INT | 10–100000 | — |
| rating | INT | 00–5 | How close is this to what you want? 0 = unrated |
| push | FLOAT | 0.0-1–1 | -1 pull back, 0 refine, +1 push further in the current direction |
| direction | STRING | Free text, e.g. 'keep the pose, change the style' | |
| votes | STRING | {} | Managed by the vote buttons (JSON) |
| chips | STRING | {} | Managed by the keep/change chips (JSON) |
| imagesopt | IMAGE | Candidates to show and vote on (batch order = labels) |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| feedback_json | STRING | — |
| chosen_index | INT | — |