[x, y], yet the graph read didn’t return node sizes, so it stacked tall
nodes (a WanVideo Sampler is ~900px) on a fixed 320px pitch and they overlapped.
It could wrap a stage into a subgraph, but the subgraph’s input/output
rails stayed stranded at the old coordinates ~11,000px away from the nodes
that moved. And it never saw the result — it reasoned about a picture from a
list of numbers.
This post is the dev-log of fixing that: a handful of small primitives in the
panel and one skill that ties them into a layout algorithm — plus the moment the
agent got a camera and immediately admitted its own layout was a mess.
TL;DR. New panel tools: richerpanel_get_graph(nodepos/size, subgraphrails,groups,color/collapsed),panel_move_rail,panel_create_group/move/edit/remove,panel_set_node_color,panel_set_node_collapsed, andpanel_screenshot(returns a PNG of the canvas). Theworkflow-layoutskill turns them into a dependency-layered, overlap-free auto-layout.
Since this post was published, the graph-read tool it describes has been replaced
by
panel_query_graph (same data, token-bounded, with filtering and traversal)
and panel_graph_outline (a compact structural overview). The rest of the post
still applies.Stop laying out blind
Everything starts with the read. The oldpanel_get_graph returned ids, types,
titles, widgets, and connections — but not geometry. Two fields fixed the
overlaps:
posandsizeon every node. Now the layout packs a column with real heights:y[i+1] = y[i] + size[i].h + GAP, instead of a fixed pitch that a 600px LoRA-select node blows straight through.railswhen you’re inside a subgraph — the positions of the boundary input/output nodes the inner wires connect to.
[0, 0] cluster, and the rails don’t follow — they sit where
the nodes used to be. Reading them back showed an output rail at x = -8691
while the nodes were at x = 0. So we added the write side:
Groups vs subgraphs (and not over-doing either)
ComfyUI has two different “grouping” ideas and they’re easy to conflate:- Group boxes — the labeled, colored rectangles. They frame a region; the
nodes stay put and editable. New tools:
panel_create_group(passnode_idsto auto-wrap),panel_move_group,panel_edit_group,panel_remove_group. - Subgraphs — collapse a stage into one nested node. Powerful for big graphs, but they hide nodes and add boundary ports.
panel_set_node_color (named LiteGraph
presets — blue, purple, green, … — or hex) to color-code stages, and
panel_set_node_collapsed to minimize rarely-touched machinery to a title chip.
The camera changes everything
Then we gave the agentpanel_screenshot. It frames the whole graph (nodes +
groups), renders the canvas to a PNG, and hands it back as an image. The first
capture of a freshly “tidied” WAN Animate workflow was humbling: the three color
bands read left-to-right correctly, but the inter-stage wiring was a tangled
fan, the group boxes dwarfed their contents, and the node tint blended into the
bands. None of that was visible in the coordinates — all of it was obvious in one
glance.
That turned layout into a loop: change → screenshot → judge → adjust. Collapse
everything for a compact pipeline? The chips went too tiny and a collapsed
input’s six output wires fanned out of a single point — worse. Re-expand and
read the real sizes? The Inputs node is 597px tall because of its video
preview, which stretched its band. Each correction came from seeing, not
guessing.
The rule that mattered most
Mid-cleanup, the principle that reorganized everything came from a human, not the algorithm:Always leave the inputs and outputs exposed so the user can just jump right in.Obvious in hindsight. Collapse the loaders, encoders, and samplers into chips — but the Load Image / Load Video input and the video-combine output are the first things a person touches. They stay expanded and prominent: drop in your media, hit run, watch the result. (Bonus:
panel_promote_widget can surface the
one widget that matters — a prompt, a seed — onto the subgraph node, so it’s
editable without drilling in.) It’s now the headline rule in the skill.
It’s a skill, not a one-off
All of this lives in theworkflow-layout skill, so the agent applies the same
algorithm every time instead of improvising:
- Read
pos/size/rails/groups. - Layer nodes by longest path from a source → left-to-right columns.
- Pack each column with real heights (no overlap); order within a column to cut wire crossings.
- Per subgraph: lay out inner nodes, then move both rails to flank them.
- Group the columns into labeled bands; color-code stages.
- Expose inputs/outputs, collapse the machinery, and screenshot to verify.