diff --git a/docs/WIDGET_SERIALIZATION.md b/docs/WIDGET_SERIALIZATION.md index f2cca7d0e..a1adf4290 100644 --- a/docs/WIDGET_SERIALIZATION.md +++ b/docs/WIDGET_SERIALIZATION.md @@ -4,7 +4,7 @@ Two properties named `serialize` exist at different levels of a widget object. T **`widget.serialize`** — Controls **workflow persistence**. Checked by `LGraphNode.serialize()` and `configure()` when reading/writing `widgets_values` in the workflow JSON. When `false`, the widget is skipped in both serialization and deserialization. Used for UI-only widgets (image previews, progress text, audio players). Typed as `IBaseWidget.serialize` in `src/lib/litegraph/src/types/widgets.ts`. -**`widget.options.serialize`** — Controls **prompt/API serialization**. Checked by `executionUtil.ts` when building the API payload sent to the backend. When `false`, the widget is excluded from prompt inputs. Used for client-side-only controls (`control_after_generate`, combo filter lists) that the server doesn't need. Not currently typed in `IWidgetOptions` — set at runtime via the options bag. +**`widget.options.serialize`** — Controls **prompt/API serialization**. Checked by `executionUtil.ts` when building the API payload sent to the backend. When `false`, the widget is excluded from prompt inputs. Used for client-side-only controls (`control_after_generate`, combo filter lists) that the server doesn't need. Typed as `IWidgetOptions.serialize` in `src/lib/litegraph/src/types/widgets.ts`. These correspond to the two data formats in `ComfyMetadata` embedded in output files (PNG, GLTF, WebM, AVIF, etc.): `widget.serialize` → `ComfyMetadataTags.WORKFLOW`, `widget.options.serialize` → `ComfyMetadataTags.PROMPT`. @@ -22,7 +22,7 @@ These correspond to the two data formats in `ComfyMetadata` embedded in output f - `addWidget('combo', name, value, cb, { serialize: false })` puts `serialize` into `widget.options`, **not** onto `widget` directly. These are different properties consumed by different systems. - `LGraphNode.serialize()` checks `widget.serialize === false` (line 967). It does **not** check `widget.options.serialize`. A widget with `options.serialize = false` is still included in `widgets_values`. - `LGraphNode.serialize()` only writes `widgets_values` if `this.widgets` is truthy. Nodes that create widgets dynamically (like `PrimitiveNode`) will have no `widgets_values` in serialized output if serialized before widget creation — even if `this.widgets_values` exists on the instance from a prior `configure()` call. -- `widget.options.serialize` is not typed in `IWidgetOptions`. If you add it to the type definition, update this doc. +- `widget.options.serialize` is typed as `IWidgetOptions.serialize` — both properties share the name `serialize` but live at different levels of the widget object. ## Code references diff --git a/src/lib/litegraph/src/types/widgets.ts b/src/lib/litegraph/src/types/widgets.ts index 661440c3f..372be27cc 100644 --- a/src/lib/litegraph/src/types/widgets.ts +++ b/src/lib/litegraph/src/types/widgets.ts @@ -47,6 +47,19 @@ export interface IWidgetOptions { /** Used as a temporary override for determining the asset type in vue mode*/ nodeType?: string + /** + * Whether the widget value should be included in the API prompt sent to + * the backend for execution. Checked by {@link executionUtil} when + * building the prompt payload. + * + * This is distinct from {@link IBaseWidget.serialize}, which controls + * whether the value is persisted in the workflow JSON file. + * + * @default true + * @see IBaseWidget.serialize — workflow persistence + */ + serialize?: boolean + values?: TValues /** Optional function to format values for display (e.g., hash → human-readable name) */ getOptionLabel?: (value?: string | null) => string @@ -349,8 +362,15 @@ export interface IBaseWidget< vueTrack?: () => void /** - * Whether the widget value should be serialized on node serialization. + * Whether the widget value is persisted in the workflow JSON + * (`widgets_values`). Checked by {@link LGraphNode.serialize} and + * {@link LGraphNode.configure}. + * + * This is distinct from {@link IWidgetOptions.serialize}, which controls + * whether the value is included in the API prompt sent for execution. + * * @default true + * @see IWidgetOptions.serialize — API prompt inclusion */ serialize?: boolean diff --git a/src/utils/executionUtil.ts b/src/utils/executionUtil.ts index ea3e4e539..bdb414b23 100644 --- a/src/utils/executionUtil.ts +++ b/src/utils/executionUtil.ts @@ -92,7 +92,9 @@ export const graphToPrompt = async ( const inputs: ComfyApiWorkflow[string]['inputs'] = {} const { widgets } = node - // Store all widget values + // Store all widget values in the API prompt. + // Note: widget.options.serialize controls prompt inclusion (checked here). + // widget.serialize controls workflow persistence (checked by LGraphNode). if (widgets) { for (const [i, widget] of widgets.entries()) { if (!widget.name || widget.options?.serialize === false) continue