-
Notifications
You must be signed in to change notification settings - Fork 2
Concepts
How the pieces fit together — the mental model behind the nodes + modules.
- The
$variablepipeline - Context chaining
- Seeds and loops
- Constraints in depth
- Internal variables
- Conflicts and warnings
- Bundles
Every module in a Context publishes one or more $variables (except constraints, which only re-weight). Later modules in the same stack — plus any downstream Context — can read those variables.
The Prompt Assembler is the consumer: its template string mentions $variables, and the engine fills them in at run time.
The token syntaxes that appear in templates, option values, and rule values:
-
$varname— substitute the value of$varnamefrom the context.$varname.Kindexes a multi-pick result (0-based, e.g.$colors.0); a bare$varnamejoins the whole list with its separator. -
{a|b|c}— inline pick from an alternation list, evaluated at render time. Weight an arm withN::value(3::cat|dog); escape a literal$/@/{as$$/@@/{{.-
Multi-pick —
{N$$sep$$a|b|c}picks N arms joined bysep;{N-M$$sep$$…}picks a random count in the N–M range. Add~for independent (with replacement — arms may repeat):{N~$$…}. The default is unique (no repeats). -
Nested arms — an inline pick's arms are resolved recursively, so they can themselves contain
$vars,@{}refs, and further{…}picks (subject to the surface gate below).
-
Multi-pick —
-
@{uuid}— reference another library module by its 8-hex uuid. Optional, combinable segments:@{uuid#name}caches a display name (shown if the row goes missing),@{uuid:filter}narrows a referenced wildcard's pool by a sub-category boolean expression (warm or cool),@{uuid!null}drops the null option. Full form:@{abcd1234#Mood:calm or intense!null}.
Not every token resolves on every surface. Each module resolves only the tokens that make sense for it; anything else is left as literal text:
| Surface |
$var read |
@{uuid} ref |
{a|b} pick |
|---|---|---|---|
| Wildcard option value | — | ✓ | ✓ |
| Combine template | ✓ | literal | ✓ |
| Derivation action value | ✓ | ✓ | ✓ |
| Derivation condition value | ✓ | — | — |
| Fixed Values value | — | — | ✓ |
| Prompt Assembler template | ✓ | literal | literal |
Wildcards are producers — they don't read $vars. The Assembler is seedless, so picks/refs in its template render verbatim. Derivation action values now resolve @{} refs (a rule can inject a nested wildcard's pick); derivation conditions stay plain comparisons.
Two WP Context nodes can be chained: the upstream one publishes its $vars, the downstream one adds new ones or overrides existing ones. Last write wins — a downstream $style replaces an upstream $style.

Upstream Context publishes Starter subject + Starter style. Downstream Context adds an Override style row (orange MOD border) plus its own Starter subject. Assembler reads the downstream's overridden $style while $subject flows through.
When to chain
- Base context + variation layers — keep a shared style/quality base in the upstream Context, branch off downstream Contexts with different subjects.
- A/B comparisons — same upstream, two different downstream Contexts, two assemblers.
- Bundle composition — drop the same base bundle into multiple downstream Contexts.
Every Context node has a seed input. At generation time each module gets its own independent random stream derived from that seed — so changing the seed re-rolls every module's pick together, but reordering modules doesn't disturb each other's results.
Any single module can flip its Lock seed runtime toggle. That module always makes the same pick regardless of the Context seed — useful for holding a background style or art direction steady while everything else varies. Locked modules are also unaffected by WP Context Loop's per-iteration variation.
Drop a WP Context Loop in front of your Context and one Generate runs the whole chain N times in a single click — each iteration with its own seed and its own fresh roll of wildcards. The Variation strategy controls how those per-iteration seeds spread:
- Hashed (default) — each iteration gets an unrelated seed derived from the base. Most variety.
-
Sequential —
base, base+1, base+2, …. Adjacent iterations feel related and drift gradually. - Stride — large prime jumps. Wide spread, deterministic.
The loop emits a list of prompts — one per iteration. Downstream samplers run once per prompt. But a standard KSampler takes a single INT seed (not a list), so every iteration is sampled with that same seed. If two iterations happen to roll the same prompt string, the sampler produces the same image for both.
Three ways to keep every output distinct:
-
Drop a WP Seed List between the loop and your sampler (cleanest). It emits a list of N seeds that pairs with the loop's prompts so each (prompt, seed) is unique. Auto-matches the loop's count + strategy when you wire
loop_config. -
Bake
$iterationinto the prompt template — it never repeats, so the prompt text is always unique. -
Wire
$iterationthrough a WP Var → Int into the sampler's seed input so each iteration also gets its own seed.
Inside each loop iteration, two $variables are available:
-
$iteration— current pass, 1-based (1, 2, 3 … up to count). Use it asframe 1 of 4 — $subject. -
$iteration_total— total runs, constant per iter.
Both are internal by default so they help downstream modules without leaking into the rendered prompt. Flip the internal toggle off in the loop config if you want them to appear.
A Constraint module is a one-shot re-weighter: it watches a source wildcard's pick, then nudges a downstream target wildcard's option weights before that target makes its own pick.
source wildcard → constraint → target wildcard is the rule. The constraint claims the first target wildcard instance downstream of itself.
If you have two $mood wildcards downstream of the constraint and want to influence both, you need two constraints (each claims one). Position in the stack controls which target each constraint claims.
- Exceptions (per-option pairs) win over matrix (sub-category × sub-category) rules when both apply to the same option.
- Use matrix for broad category nudges (feline → intense).
- Use exceptions for precise overrides (tiger → sleepy = exclude).
A wildcard option whose value contains @{uuid} references a downstream wildcard "nested" inside it. A constraint targeting that nested wildcard fires when the carrier option is picked. The wiki UI flags carriers with a ↪×N collapsed chip so you can drill into which constraints route through which option.
By default a constraint re-weights every matching target instance downstream. A per-instance Target reach selector narrows that:
- All (default) — every downstream target instance.
- First — only the first target instance after the constraint.
- Next N — the next N target instances (a count).
- Pick — only specific target rows you select (direct instances, or nested-ref carriers).
A constraint whose reach covers zero reachable targets is flagged constraint_orphan_target.
If a constraint's source or target wildcard isn't in your library — you installed the constraint without its wildcards, or deleted one — that axis is stranded: the editor shows the dead uuid and locks the matrix read-only. Reattach re-points the axis at a local wildcard (or downloads the missing one from the community); the matrix + exceptions remap onto the new wildcard's sub-categories.
When a constraint runs but its target wildcard never appears downstream (e.g. you removed the target without removing the constraint), the runtime emits a constraint_never_applied warning. Visible in WP Debug's Warnings tab.
A $variable flagged internal lives in the context (other modules read it normally) but is stripped at the Assembler boundary so it doesn't render in the prompt text.
When to use
- A
$moodthat drives a derivation but shouldn't appear literally in the prompt. - A
$weatherused by constraints as a source but irrelevant to the rendered text. - The loop's
$iteration+$iteration_total(internal by default).
Where to flip it
- Wildcard / Fixed / Combine / Derivation — each module's runtime "Hide from prompt" toggle.
- Loop iteration vars — the loop's iteration var config.
The internal flag is preserved across Context chains — once a variable is internal, every downstream Assembler skips it.
A non-blocking advisory scanner walks every WP_Context on the graph and flags potential issues before you press Generate:
-
missing_template_variable— an Assembler references a$varthat no upstream module produces. -
shadows_upstream— a module overrides an upstream$var. Often intentional; informational only. -
duplicate_variable— two modules in the same Context write the same$var. Last one wins. -
constraint_orphan_source/constraint_orphan_target— constraint's source/target uuid not in the catalog or no matching instance. -
constraint_never_applied(runtime) — constraint ran but its target never came up.

WP Context's pairing row carries an orange CONFLICT badge → WP Debug Warnings tab open showing the constraint-orphan-target message in plain English → WP Prompt Assembler resolves around the unmet constraint without aborting.
The scanner never blocks execution — it advises only. Runtime warnings appear in WP Debug after Generate; pre-run conflicts appear as dot badges on the affected module rows.
A Bundle is a frozen snapshot of one or more modules, saved into the library as a single reusable unit. Drop a bundle into any Context and the engine treats its children as if they had been placed directly in the stack.
When you save a bundle, the editor takes a snapshot of every child module's payload at that moment. Later edits to the library entries do not propagate into already-inserted bundle instances — the snapshot keeps the bundle reproducible across machines + workflow saves.
If a library module a bundle references changes after the bundle was saved, the canvas flags the bundle row with a MODIFIED chip + offers a re-snapshot action. Same goes for inner bundles (a bundle that references another bundle).
Deleting a bundle that's still referenced from another bundle / workflow fires a confirmation dialog listing every dependent so nothing breaks silently.
Home · Quick Start · Nodes · Modules · Concepts
💬 Discord · 🐛 Report an issue · 💭 Discussions · 📦 Releases
Wildcard Pipeline — weighted wildcards, chained $variable Contexts, looped batches, and a persistent module library for ComfyUI.