Three coordinated changes to the WP_* node family. 1. New WP_SeedList node Emits a list of N derived seeds for a downstream loop (is_output_list). Three independent override toggles (override_seed / override_count / override_strategy) each mirror the wired Loop's base_seed / count / strategy. Connecting loop_config auto-flips override_count + override_strategy ON so the natural intent of wiring in a loop gets the defaults right; override_seed stays explicit opt-in. All emitted seeds are masked to 50 bits via the new MAX_SAFE_SEED constant in engine.seed_derive so values sit inside ComfyUI's frontend randomize range and copy-paste reproduces identically in a standalone sampler. 2. Context Loop type split + downstream Context seed widget lock Split WP_CONTEXT_LOOP_CONFIG (wire payload) from a new WP_CONTEXT_LOOP_WIDGET (DOM-widget-only TYPE). Loop's own widget mounts on the widget type; the wire type has no factory so consumers like WP_SeedList render their loop_config socket as a plain input instead of being hidden by a fallback-undefined widget. New graph walker hasUpstreamLoopOverridingSeed: WP_Context's widget glue greys out the local seed stock widget when an upstream Loop has override_seed ON, so users read "this value is dead while the Loop drives it" without inspecting the Loop config separately. 3. wp_ prefix sweep + tooltips across every WP_* node input Custom DOM widget input names now carry the wp_ prefix so canvas socket labels read as branded WP widgets: modules -> wp_modules, rows -> wp_rows, viewer -> wp_viewer, cleaner -> wp_cleaner, context_loop_config -> wp_context_loop_config. Every stock input across the node family gets a tooltip describing what it does and when to wire it from another node. Tests + comfy_api stub updated. CLAUDE.md notes the wp_ convention for future custom widgets. Bundle size budget bumped 388 -> 395 KB to fit the SeedList Vue chunk (~4.9 KB net gzip) + override lock UI; entry stays at ~4 KB gzipped.
78 lines
2.8 KiB
Python
78 lines
2.8 KiB
Python
"""WP_VarToFloat — reads a named $var from PipelineContext, emits a FLOAT.
|
|
|
|
Parsing rule: Nth signed-float substring match from the var's value
|
|
(``-?\\d+(?:\\.\\d+)?(?:[eE][-+]?\\d+)?``). Integers match too, so
|
|
``"1920"`` yields ``1920.0``. Fallback path identical to WPVarToInt.
|
|
"""
|
|
|
|
from comfy_api.latest import io # pyright: ignore[reportMissingImports]
|
|
|
|
from engine.converters import lookup_var, parse_float
|
|
from wp_nodes.types import PipelineContext, VarPickerInput
|
|
|
|
|
|
class WPVarToFloat(io.ComfyNode):
|
|
"""PipelineContext $var → FLOAT."""
|
|
|
|
@classmethod
|
|
def define_schema(cls):
|
|
return io.Schema(
|
|
node_id="WP_VarToFloat",
|
|
display_name="WP Var → Float",
|
|
category="wildcard-pipeline",
|
|
inputs=[
|
|
PipelineContext.Input(
|
|
"context",
|
|
tooltip=(
|
|
"The resolved $variable context from any upstream "
|
|
"WP Context / Loop / Injector chain. Required — "
|
|
"without it the node has no variables to read."
|
|
),
|
|
),
|
|
VarPickerInput.Input("wp_var_name", socketless=True),
|
|
io.Int.Input(
|
|
"index",
|
|
default=0,
|
|
min=0,
|
|
max=999,
|
|
tooltip=(
|
|
"Which number in the value to extract when multiple "
|
|
"are present (0 = first)."
|
|
),
|
|
),
|
|
io.Float.Input(
|
|
"default",
|
|
default=0.0,
|
|
min=-1.0e38,
|
|
max=1.0e38,
|
|
step=0.01,
|
|
tooltip=(
|
|
"Value to use when the variable is missing or the "
|
|
"index is out of range. The node never errors — it "
|
|
"falls back to this."
|
|
),
|
|
),
|
|
],
|
|
outputs=[io.Float.Output("value")],
|
|
not_idempotent=False,
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, context, wp_var_name, index, default):
|
|
text = lookup_var(context, wp_var_name)
|
|
value = parse_float(text, index, default)
|
|
a = parse_float(text, index, 0.0)
|
|
b = parse_float(text, index, 1.0)
|
|
matched = a == b
|
|
# See WP_VarToInt for the `wp_varpicker_*` UI-payload rationale
|
|
# — engine-resolved source + parsed output feeds the widget's
|
|
# "last execute" strip so wildcard-template vars show the truth.
|
|
return io.NodeOutput(
|
|
value,
|
|
ui={
|
|
"wp_varpicker_source": [text],
|
|
"wp_varpicker_parsed": [str(value) if matched else None],
|
|
"wp_varpicker_default": [str(default)],
|
|
},
|
|
)
|