feat: add the set_node_field op and its command - #911
claude[bot] wants to merge 2 commits into
Conversation
The vocabulary can only express a node scalar-field change as an add_node upsert, which replaces the whole node and clears its widget stamps. These cases pin what a field-addressed register must do: a standalone command, replay through apply_op, per-field LWW, a closed field allowlist, and batchability.
comfy workflow set-node-field <file> <node> <field> <value> writes one durable node field — title, mode, flags.collapsed or flags.pinned — and emits a replayable op. One LWW register per (node, field), so a title write and a flag write on one node never contend, and neither disturbs that node's widget registers. Writable fields are a closed set: everything outside it either has an op of its own or is node identity that only add_node and delete_node move. null clears a field, so a flag returns to absent the way workflow JSON round-trips it.
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
|
Evidence. Of the last 20 runs of What's actually failing — two E2E cases in
The resolver never reaches the conflict report, because it aborts earlier on a VCS URL pulled from a live third-party node pack: So these tests clone Why it can't be this PR. The diff is five files — No re-run. The drive-to-green convention is to retry an unrelated failure once, but this is not an intermittent flake — it fails deterministically on Everything else on this PR is green: Created by Claude Tag |
Requested by Christian Byrne · Slack thread
Prototype / spike — not intended to merge as-is. One of four PRs in a cross-repo prototype (comfy-multi-player, ComfyUI_frontend, this, cloud).
Before
There is no way to rename a node, mute one, collapse one or pin one through the op vocabulary. The closest thing is an
add_nodeupsert, which is a legitimate LWW replace — but of the whole node: it rewrites the node's widget values and resets its widget stamps, so a field change concurrent with aset_widgeton the same node discards that write.That is the gap ComfyUI_frontend hit trying to sync
flags.collapsed/flags.pinnedout of the canvas, and it is why the in-app agent can build a graph but cannot label one.After
title,mode,flags.collapsed,flags.pinned— exported asWRITABLE_NODE_FIELDS("node_field", node_id, field)— one LWW register per(node, field)valueofnullworkflow apply/foreachTwo collaborators can now edit two fields of one node, or a field and a widget, without contending — and
detect_conflictagrees, so V0's ask-to-merge does not raise on a pair that cannot actually clobber.Why the field list is closed
Everything outside it either has an op of its own (
widgets_valuesisset_widget's;inputs/outputsbelong toconnect) or is node identity (id,type) that onlyadd_node/delete_nodemay move.flagsas a whole is excluded too — a whole-object write would reintroduce exactly the clobber this op exists to avoid.Node ids compare as strings throughout (amendment v1.2), since the CLI takes this one straight off the command line.
Red → green
f9102catest:apply_op, per-field LWW independence, either-order convergence, idempotency, the field allowlist and batchability. All 10 fail —No such command 'set-node-field'andunknown op 'set_node_field'.75fd565feat:test_op_vocabulary_contract.pypasses, which is the point of it: the doc's frozen-kinds table,FROZEN_OPS,BATCHABLE_OPS, and both dispatch tables are pinned to agree, so thedocs/op-vocabulary-v1.mdrow in this PR is not decoration — the contract test would fail without it.ruff checkandruff format --checkclean.Cross-repo notes
comfy-multi-playerpinsdocs/op-vocabulary-v1.mdby SHA in itsupstream-pins.json, so its companion PR'sset_node_fieldneeds the pin re-established against this change once it lands. Itscheck:pinspasses today only because it cites no new section.FROZEN_OPShere and in cmp had already drifted before this PR — cmp carriesdisconnectanddefine_subgraph, this does not. Worth a separate look; not touched here.comfy workflow set-node-field, so it pins against this branch rather than waiting for a merge.Not done here
docs/op-vocabulary-v1.mdbeyond the frozen-kinds row. A real landing wants the versioned amendment prose the file's own header asks for.🤖 Generated with Claude Code
https://claude.ai/code/session_016jorVkGmycSkD6j7A6sdJV
Generated by Claude Code