Date: 2026-02-22
Proposed
PrimitiveNode creates widgets dynamically on connection. When copied, the clone has no this.widgets, so LGraphNode.serialize() drops widgets_values from the clipboard data. This causes secondary widget values (e.g., control_after_generate) to be lost on paste. See WIDGET_SERIALIZATION.md for the full mechanism.
Override serialize() to fall back to this.widgets_values (set during configure()) when the base implementation omits it due to missing this.widgets.
- Pro: No change to connection lifecycle semantics. Lowest risk.
- Pro: Doesn't affect workflow save/load (which already works via
onAfterGraphConfigured). - Con: Doesn't address the deeper design issue — primitives are still empty on copy.
On copy, the primitive is a clone of the configured instance (with widgets intact). On disconnect or paste without connections, it returns to empty state.
- Pro: Copy→serialize captures
widgets_valuescorrectly. Matches OOP expectations. - Pro: Secondary widget state survives round-trips without special-casing.
- Con:
input.widget[CONFIG]allows extensions to make PrimitiveNode create a different widget than the target. Widget config is derived at connection time, not stored, so cloning the configured state may not be faithful. - Con: Deserialization ordering —
configure()runs before links are restored. PrimitiveNode needs links to know what widgets to create.onAfterGraphConfigured()handles this for workflow load, but copy/paste uses a different code path. - Con: Higher risk of regressions in extension compatibility.
Primitives act as a synchronization mechanism — no own state, just a projection of the target widget's resolved value.
- Pro: Cleanest conceptual model. Eliminates state duplication.
- Con: Primitives can connect to multiple targets. Projection with multiple targets is ambiguous.
- Con: Major architectural change with broad impact.
Pending. Option A is the most pragmatic first step. Option B can be revisited after Option A ships and stabilizes.