From comfyui-plugin
ComfyUI predicate/boolean nodes: compare, AND/OR/XOR/NOT, ternary, null/empty/type probes, ExecutionBlocker. Use when forming the boolean that drives a workflow switch or blocker.
How this skill is triggered — by the user, by Claude, or both
Slash command
/comfyui-plugin:comfy-conditionalsThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Predicates → boolean → branch. *How the decision is formed*, not where
Predicates → boolean → branch. How the decision is formed, not where the signal goes after.
Four packs contribute predicate primitives. The split:
| Pack | Primary niche |
|---|---|
comfyui-easy-use | easy ifElse, easy compare, easy blocker, and the easy is* probes — the broadest, most-used predicate kit |
comfyui-impact-pack | ImpactCompare + ImpactConditionalBranch (lazy) + ImpactIfNone + ImpactConditionalStopIteration (Impact-iterator loop control) |
comfyui_essentials | SimpleCondition (ternary), SimpleComparison (typed, epsilon-aware), SimpleMathCondition (boolean from math) |
comfyui-logicutils | Bit-banging + regex-on-strings logic gates: AContainsB, bitwise And/Or/Xor/Not/Shift, generic Invert |
| Use this skill when... | Use instead when... |
|---|---|
| Forming the boolean/predicate that drives a switch or blocker in a workflow | Routing the signal after the decision is made -> comfy-flow-control |
| Comparing values, combining booleans, detecting null/empty | Computing a numeric (non-boolean) value -> comfy-math-strings |
custom_nodes/comfyui-easy-use/py/nodes/logic.py — ifElse, compare, blocker, is* probescustom_nodes/comfyui-impact-pack/modules/impact/special_samplers.py — ImpactCompare, ImpactConditionalBranchcustom_nodes/comfyui_essentials/misc.py — SimpleMath / SimpleCondition / SimpleComparisoncustom_nodes/comfyui-logicutils/logic_gates.py — logic gate nodes| Need | Best node | Why |
|---|---|---|
Compare two ANY values, any op (==, !=, <, >, <=, >=) | easy compare | Multi-op switcher widget, no type lock |
| Compare two INT/FLOAT, return BOOLEAN | ImpactCompare | Op picker (a=b, a<>b, a>b, a<b, a>=b, a<=b, tt/ff constants) |
| Compare two FLOAT with epsilon tolerance | SimpleComparison (essentials) | Floats are unsafe under == — epsilon-aware |
| Compare a string against a regex / substring | LogicGateCompareString / AContainsB (logicutils) | The only regex-on-string predicate available |
Quick math → boolean (e.g. (a+b) > c) | SimpleMathCondition | Computes the expression and returns BOOLEAN in one node |
| Detect null / unwired input | easy isNone or ImpactIfNone | Returns BOOLEAN + passes value through |
| Detect empty mask (all zeros) | easy isMaskEmpty | Specifically tests MASK type |
| Detect SDXL vs SD1 model | easy isSDXL | Probes CLIP / pipe and identifies arch |
| Detect file path exists on disk | easy isFileExist | For input-validation gates |
ImpactConditionalBranch.cond is BOOLEAN. Don't feed it:
SimpleMathCondition output → that's FLOAT (0.0 / 1.0) — convert via comparator firsteasy compare output → that IS BOOLEAN, fineLogicGateCompare output → BOOLEAN, fineImpactCompare (a > 0) or convertWhen in doubt, route through easy compare and pick the comparison operator that yields the boolean you want.
For combining multiple predicates into one branch input:
| Operator | Node |
|---|---|
| AND / OR / XOR | ImpactLogicalOperators (op picker) |
| NOT | ImpactNeg |
| Bit-wise AND / OR / XOR / NOT / shift | logicutils LogicGateBitwiseAnd etc. (work on INT, not BOOLEAN) |
| Generic invert (works on any truthy/falsy) | LogicGateInvertBasic |
isMaskEmpty(face_mask) ──┐
▼
ImpactNeg (NOT) ──┐
▼
ImpactLogicalOperators (AND) ──→ ImpactConditionalBranch
▲
isFileExist(reference.png) ────────┘
This combination says: "face mask is non-empty AND reference image exists on disk → run the detailer branch".
| Node | Behavior |
|---|---|
easy ifElse | BOOLEAN selector, on_true / on_false inputs; only the chosen one is evaluated upstream |
ImpactConditionalBranch | BOOLEAN cond; lazy tt_value / ff_value inputs |
ImpactConditionalBranchSelMode | Same, but selection happens at execution time rather than prompt-queue time — needed when cond depends on something computed earlier in the same queue |
These are predicate-side nodes that ALSO act as switches — they
form the boolean and route in one step. If your predicate is simple
(one comparison) and the branches are large (samplers, models),
ImpactConditionalBranch is the cleanest single-node solution.
If the predicate is complex (multi-criteria), form it explicitly in
this skill's primitives, then pass the resulting BOOLEAN to a switch
from comfy-flow-control.
SimpleCondition (essentials) — given condition, returns value_if_true
or value_if_false. Both inputs are computed (eager), so it's a value
picker, not an execution gate. Use it for selecting between two
constants or already-computed scalars; never for selecting between
sampler chains.
easy blocker is the canonical "kill this path" node. Behavior:
continue BOOLEAN.continue=True: pass the value through unchanged.continue=False: returns an ExecutionBlocker sentinel.The sentinel propagates downstream: any node that receives an
ExecutionBlocker on any input is silently skipped (its
execute() is never called). The skip cascades through the rest of
the graph downstream of the blocker.
LoadImage ── easy compare (size > 1024) ─┐
▼
LoadImage ──────────────► easy blocker ───► ResizeImage ─► KSampler ─► SaveImage
▲ continue
When the loaded image is smaller than 1024px, the blocker fires; ResizeImage / KSampler / SaveImage are all skipped without errors.
comfy-flow-control
gotchas. The blocker fires, but a Preview Bridge tee downstream
reports nothing visibly, and fails to propagate the abort. Use
FastPreview (kjnodes) downstream of a blocker if you need
visual confirmation.easy showAnything on the BOOLEAN that drives the
blocker to confirm at queue time.| Probe | Returns BOOLEAN when |
|---|---|
easy isNone | Input is None / unwired / a placeholder |
ImpactIfNone | Same, plus passes the non-None value through (combines probe + pass-through) |
easy isMaskEmpty | All mask pixels are zero (no positive area) |
easy isFileExist | Filesystem path resolves to a real file |
easy isSDXL | The CLIP / pipe / model identifies as SDXL architecture |
Use cases:
isMaskEmpty(face_mask) → blocker to skip
detailer when no face is found.isFileExist(ref_path) → switch between
"use reference" and "no reference" branches.isSDXL(pipe) → switch sampler configuration.comfyui-logicutils is the sole source for:
LogicGateCompareString (also
registered as AContainsB). Pass a regex pattern in b, a string
in a, get BOOLEAN.LogicGateInvertBasic — generic invert that handles any
truthy/falsy input (more lenient than ImpactNeg, which expects
strict BOOLEAN).ImpactConditionalStopIteration — only useful inside an Impact
detector→detailer iterator loop. Takes a BOOLEAN; when True, halts
the iterator's next round. The iterator must support stop signals
(detector-pipeline variants do; non-iterating Impact paths ignore it).
LoadImage ──► BBoxDetector ──► IMAGE/MASK output
│
▼
easy isMaskEmpty ──► (BOOLEAN)
│
▼ (invert: empty → skip)
ImpactNeg
│
▼
┌───────► easy blocker ◄────── (the image+mask payload)
│ continue
▼
(downstream FaceDetailer chain, silently skipped on empty)
isMaskEmpty → True when no face found → ImpactNeg flips it → False
→ blocker fires → FaceDetailer + SaveImage chain is skipped without
error.
"Run the high-quality upscale path only if the image is large AND the reference exists AND we're not in SDXL mode":
GetImageSize&Count(image) ──► width ──► easy compare (> 1024) ──┐ (BOOL)
│
easy isFileExist(ref_path) ──► (BOOL) ───────────────────────────┤
│
easy isSDXL(pipe) ──► ImpactNeg (NOT SDXL) ──► (BOOL) ───────────┤
▼
ImpactLogicalOperators (AND of 3)
│
▼
ImpactConditionalBranch
tt = upscale chain
ff = passthrough
Three independent predicates combined with AND. The downstream branch is fully lazy: when any predicate is False, none of the upscale chain runs.
Useful for caching: if an output file already exists, skip regeneration.
easy isFileExist("output/cached_step1.png") ──► (BOOL)
│
▼
ImpactConditionalBranch
tt = LoadImage from cache
ff = run full pipeline + SaveImage
easy compare with == on FLOATs is a
trap. Use SimpleComparison (epsilon-aware) or easy compare with
< / > instead. 1.0 + 2.0 == 3.0 is True, but 0.1 + 0.2 == 0.3
is False.ComfyExecutionBlocker: lazy nodes
(easy ifElse, ImpactConditionalBranch) won't evaluate the
unselected branch, but they pass through whatever node-graph value
the selected branch produces — including an ExecutionBlocker
sentinel. If both branches can emit blockers, plan the merge
carefully.SimpleMathCondition returns FLOAT (1.0 / 0.0), not BOOLEAN.
Pass through ImpactCompare (> 0.5) before feeding a switch that
wants BOOLEAN.easy isNone on a pipe: pipes (PIPE_LINE) are tuples — isNone
returns False on an empty pipe (the tuple exists, just with None
fields). To detect missing pipe content, unpack with pipeOut and
probe individual fields.AContainsB is regex, not substring: special characters need
escaping. To do a plain substring check, escape with \Q...\E or
use Python regex-special escapes manually.comfy-flow-control — once the boolean is formed, this skill points
at the switches that consume it (typed switches, ExecutionBlocker
propagation, broadcast routing).comfy-math-strings — math primitives that feed comparisons
(constants, sliders, SimpleMath expressions, GetImageSize&Count
outputs).comfy-debug-preview — ShowAnything / ShowText for inspecting
the BOOLEAN being passed to a branch at queue time.comfy-flow-control.comfy-math-strings.npx claudepluginhub laurigates/claude-plugins --plugin comfyui-pluginComfyUI routing nodes: typed switches, index switches, broadcast (Anything Everywhere), pipe/context bundles, for/while loops, ExecutionBlocker gates. Use when wiring where a signal routes in a workflow.
Explains ComfyUI node execution lifecycle: caching via fingerprint_inputs/IS_CHANGED, input validation with validate_inputs, lazy status checks, topological execution order. Use for debugging, caching control, validation, flow understanding.
Defines canonical Pi Flow node config and run condition standards, covering lifecycle, hooks, gates, profiles, and syntax for editing existing workflows.