Shrug Accumulator
Per-graph memory for loops that need to remember things
- joined
- picked
- count
ComfyUI loops are annoyingly stateless. You run a VLM node in a loop twenty times and each iteration starts fresh - there's no built-in place to say "remember all the captions so far, then hand me the combined result at the end." Shrug Accumulator is that memory. It's a graph-scoped string accumulator: append items during a loop, then read them back joined together, pick one out by index, or wipe the slate clean. It's one of the pack's pure utilities - no server, no connection, just state.
It's the kind of node you don't appreciate until the first time you want to collect every VLM response in a loop and summarize them in one call, or buffer a bunch of candidate prompts and pick the best after scoring. Then it's exactly the missing piece.
How it works
The state lives in a class-level dictionary keyed by the node's unique_id, which means each instance you drop into a graph gets its own private list. Two copies of the node in the same workflow don't share anything. The mode combo picks the operation:
append- pushtextonto this node's list.reset- clear the list.read- don't touch the list; just return it joined.pick- return the item atindex.
The three outputs are always computed: joined (the list joined with delimiter, default a newline), picked (the item at index, empty if out of range or you're not in pick mode), and count (how many items are buffered).
Here's the trap that gets everyone: state is never evicted. The dict persists across workflow runs. If you don't reset at the start of a loop, the previous run's items are still in there and your "one summary" suddenly includes last run's captions. The pack's own docs say it straight: rely on mode=reset between runs. The idiom is a reset accumulator feeding into a loop, with the loop's body appending, and the joined output read after the loop finishes.
Inputs that matter
mode- the operation, described above.text(optional) - whatappendpushes. Ignored in other modes.index(optional, default 0) - which itempickreturns.delimiter(default\n) - the join separator forjoined.
How to install
Standard pack install. ComfyUI Manager → search Shrug-Prompter → Install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/fblissjr/shrug-prompter
Dependencies are already in any modern ComfyUI (httpx, orjson, pillow, torch, numpy); nothing heavy, nothing to download. A current ComfyUI build is required (V3 extension API).
Common issues
- The list keeps growing across runs. That's the no-eviction behavior. Add a
resetpass before your loop. pickedis always empty. You're not inpickmode, orindexis out of range. Note the guard: it returns empty rather than erroring, so an empty string is the silent symptom.- "Read mode returned nothing."
readonly echoes what's buffered. If nothing has been appended in this run and the state was never persisted from a prior run (or was reset), it's empty - which is correct, not broken.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| mode | COMBO | append | 4 options: append, reset, read, pick |
| delimiter | STRING | — | |
| textopt | STRING | — | |
| indexopt | INT | 0 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| joined | STRING | — |
| picked | STRING | — |
| count | INT | — |