KoO Workflow Preset Manager
A Preset Library That Lives Inside Your Workflow File
You have one graph: a sampler you like at 28 steps and CFG 4.5, a refine pass, two LoRA strengths, a detailer at 0.35, a tile upscale at 0.4. You also have four other combinations of those numbers you like, and nowhere to put them. So you keep five near-identical workflow files, or notes on the second monitor.
KoOWorkflowPresetManager is the third option. It's a node with no inputs and no outputs whose entire job is to snapshot the widget values of the nodes you've selected, store them under a name, and write them back later. Same category as the rgthree quality-of-life nodes - it makes a graph you're actively working in more liveable, without generating anything.
It really is frontend-only
Worth saying up front, because it changes how you use it. The Python class is a no-op: no input types, no return types, a function returning an empty tuple. All the behavior is in the pack's bundled JavaScript. That's why it can't break your queue - and why it does nothing at all when you fire the workflow through the API or run it headless. Applying a preset changes the actual widget values in the graph, and those values are what gets saved and queued. The preset was never "active" at run time.
Capture, identity, apply
Capture. Box-select the nodes you care about, type a name, hit capture. The node skips itself and other preset managers, skips buttons and anything marked non-serializing, and records a {name, index, type, value} entry per widget. Values that aren't plain JSON - curves, tensors, exotic custom widget types - get skipped with a console warning instead of corrupting the preset. With nothing selected, nothing happens, which is the most common complaint and not a bug.
Identity. Each captured node is stamped with a koo_preset_uid property, a UUID stored on the node inside the workflow. Apply looks nodes up by UID rather than node ID or title, so renaming "KSampler" to "Base pass" doesn't orphan your presets. Duplicate UIDs from copy/paste get repaired, with a console warning.
Apply. For each saved widget it finds the target by name, falls back to positional index if the name is gone, sets the value, then calls the widget callback and the node's widget-change hook, so custom nodes that redraw on change actually redraw. Then it prints a status line: values changed, nodes found, nodes missing.
That status doubles as a sanity check: it compares the live graph against the selected preset and reports MATCH or something like "6 values differ | 1 node missing". Select your preset before a run and you know whether you're reproducing the settings you think you are. Update re-snapshots every captured node that still exists.
Presets live in the manager node's saved properties, which means they live inside the workflow JSON: copy the file and they come along, open a fresh workflow and the manager starts empty.
Inputs and outputs
None of either - an empty input schema and an empty return list. Everything you touch is canvas: a name field, a preset dropdown, Capture / Apply / Update / Delete, a status readout, and a theme panel offering Light, Dark and Spicy.
Install
Manager, searching koo-nodes-pack (publisher KoO.Ai; registry availability depends on moderation approval). Manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/kevintronchin-blip/koo-nodes-pack
Restart ComfyUI and hard-refresh the browser - the frontend is a static JS file from the pack's web directory, and a stale cache gives you a node with no controls. No extra dependencies.
Where it goes wrong
"No nodes selected." Capture reads the selection, not the whole graph. Select first, then name and capture.
"Already exists – use Update." Preset names are keys, not a list you append to. Refresh with Update, or give the variant a new name.
Presets that apply to nothing. Delete a node and apply reports it missing and skips it. If you replaced a KSampler with a different sampler class, the UID is gone and there's nothing to write into. Recapture.
Widgets that come back wrong. Renamed widgets fall back to positional matching, so a node whose widget order shifted can get values in the wrong slots. Recapture after a reshuffle.
Nodes 2.0. The README is explicit that this pack's custom canvas interfaces need the Legacy / LiteGraph renderer, and that Nodes 2.0 skips node-level drawing and mouse hooks. A node that draws its own buttons renders as an empty box. Switch the renderer back and it stops being your problem.
The verdict: not a replacement for workflow variants when structure changes, since it stores widget values only. For "same graph, five seasoning levels" it's the cleanest thing I've used, and it lives in the file instead of a spreadsheet.
Inputs (0)
No inputs
Outputs (0)
No outputs