v2.2.0: Prompt Builder nodes, wildcard review tool, docs refresh

- Add Wildcard Prompt Composer and Wildcard Character Composer builder nodes (core/builder, web/prompt_builder.js, builders/, vp wildcard lists)

- Add browser-based wildcard review tool (tools/wildcard_review) with manifest-based undo

- Add wildcard catalog/curation, surreal compiler/lint/scene, profile token budget

- README: document all 18 nodes, bump to v2.2.0, fix stale node/platform lists; CHANGELOG 2.2.0

- Rewrite NODE_COMPARISON for 18 nodes; fix QUICKSTART (dead test_setup.py ref, menu path) and QUICK_REFERENCE node list

- gitignore review manifests and CLAUDE.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Eric Hiss
2026-10-28 20:36:44 -07:00
co-authored by Copilot
parent df90d119b4
commit 373ea8bda3
81 changed files with 15705 additions and 588 deletions
+145 -304
View File
@@ -1,343 +1,184 @@
# Node Comparison Guide - Which Node Should I Use?
All 18 nodes live under **Add Node → Eric Prompt Enhancers**. This guide groups them by job and
helps you pick. For full per-node descriptions see README.md → "The Nodes".
## Quick Decision Tree
```
Do you have an IMAGE or just TEXT?
What do you want to do?
├─ TEXT → Text-to-Video nodes
├─ Expand a short idea into a full prompt (with an LLM)
│ │
│ ├─ Want SIMPLE presets?
│ │ └─ Use: AI Video Prompt Expander (Standard)
│ ├─ For VIDEO, from TEXT
│ │ ├─ Simple, preset-driven → Video Prompt Expander
│ │ └─ Precise camera/lighting → Video Prompt Expander (Advanced)
│ │
│ └─ Want DETAILED controls?
│ └─ Use: AI Video Prompt Expander (Advanced)
│ ├─ For VIDEO, from an IMAGE → Image-to-Video Prompt Expander
│ │
│ ├─ For an IMAGE, from an IMAGE → Image-to-Image Prompt Expander
│ │
│ ├─ For an IMAGE, from TEXT → Text-to-Image Prompt Enhancer
│ │
│ └─ For Alice text-to-video → Alice T2V Prompt Refiner
│
└─ IMAGE → Image-based nodes
│
├─ Want to ANIMATE it (video)?
│ └─ Use: Image-to-Video Prompt Expander
│
└─ Want to TRANSFORM it (image)?
└─ Use: Image-to-Image Prompt Expander
├─ Take a FINISHED prompt and format it for a specific model
│ ├─ Any of 60+ platform profiles → Platform Prompt Rewriter
│ └─ Ideogram 4 (structured JSON) → Ideogram 4 Magic Prompt
│
├─ Work with WILDCARDS / add variation
│ ├─ Resolve wildcard syntax → Wildcard Processor
│ ├─ Nudge picks to neighbours → Semantic Variation
│ ├─ Did the key idea survive? → Concept Survival Check
│ └─ One surreal anomaly → Surreal Premise
│
├─ BUILD a prompt with buttons (no typed syntax)
│ ├─ Whole prompt, section by section → Wildcard Prompt Composer
│ └─ A reusable character → Wildcard Character Composer
│
└─ Keep a LIBRARY of prompts
├─ Save one → Save Prompt to DB
├─ Find one → Search Prompt DB
├─ Bulk-import many → Import Prompts to DB
└─ Fetch one / random → Browse / Random Prompt DB
```
## Complete Node Comparison
| Feature | Standard | Advanced | Image-to-Video | Image-to-Image |
|---------|----------|----------|----------------|----------------|
| **Input** | Text only | Text only | Image + Motion | Image + Changes |
| **Output** | Video prompts | Video prompts | Video prompts | Image prompts |
| **Presets** | ✅ | ✅ | ✅ | ❌ (Platform-based) |
| **Wildcards** | ✅ | ✅ | ✅ | ✅ |
| **Random Mode** | ✅ | ✅ (respects controls) | ✅ | ❌ |
| **Aesthetic Controls** | Basic | Full | Medium | Full (image-focused) |
| **Vision Model** | ❌ | ❌ | ✅ | ✅ |
| **Platform Awareness** | ❌ | ❌ | ❌ | ✅ (6 platforms) |
| **Best For** | Quick video prompts | Precise video control | Animating images | Transforming images |
## Detailed Comparison
### 1. AI Video Prompt Expander (Standard)
**When to use:**
- ✅ Quick video prompt generation
- ✅ Preset-based workflows
- ✅ Don't need fine control
- ✅ Text-to-video generation
**Example:**
```
Input: "A {animal} in a {location}"
Preset: cinematic
Tier: enhanced
Output: Detailed video prompt with cinematic style
```
**Pros:**
- Simple, fast
- Good presets
- Wildcard support
- Random mode
**Cons:**
- Less control
- No vision model
- No platform optimization
---
### 2. AI Video Prompt Expander (Advanced)
## 1. LLM expanders & enhancers
**When to use:**
- ✅ Need precise aesthetic control
- ✅ Specific camera/lighting requirements
- ✅ Professional video workflows
- ✅ Text-to-video with details
These turn a short idea (and optionally a reference image) into a full prompt with a local LLM.
**Example:**
```
Input: "detective in office"
Shot Size: medium close-up
Camera Angle: low angle
Lighting: edge lighting
Preset: noir
Output: Precise video prompt with all specifications
```
| Node | Input | Output | Vision | Platform-aware |
|------|-------|--------|--------|----------------|
| **Video Prompt Expander** | Text | Video prompt | ❌ | video `target_model` |
| **Video Prompt Expander (Advanced)** | Text (+ optional image) | Video prompt | ✅ (optional) | video `target_model` |
| **Image-to-Video Prompt Expander** | Image + motion | Video prompt | ✅ | video `target_model` |
| **Image-to-Image Prompt Expander** | Image + changes | Image prompt | ✅ | ✅ 6 platforms |
| **Text-to-Image Prompt Enhancer** | Text (+ 1-2 ref images) | Image prompt | ✅ (optional) | ✅ 8 platforms |
| **Alice T2V Prompt Refiner** | Text and/or images | Alice T2V prompt | ✅ (optional) | Alice |
**Pros:**
- Full control
- All Wan 2.2 options
- Respects dropdowns in random mode
- Wildcard support
### Video Prompt Expander
Simple, fast video prompts. Style presets, five `expansion_tier` levels (auto/basic/enhanced/advanced/
cinematic), up to 3 variations. **Use when** you want a quick video prompt from a short idea.
**Cons:**
- More complex
- No vision model
- No platform optimization
### Video Prompt Expander (Advanced)
Granular video control: operation modes (`expand_from_idea`, `refine_existing`, `modify_style`,
`add_details`), Concise/Moderate/Detailed/Exhaustive detail, 50+ camera/lighting/visual dropdowns, and an
optional reference image (Qwen3-VL). **Use when** you need specific cinematography or want to refine an
existing prompt.
### Image-to-Video Prompt Expander
A vision model describes your image, then motion and camera are added. **Use when** you're animating an
existing image.
### Image-to-Image Prompt Expander
Platform-aware image-to-image prompts (6 platforms: flux, sd_xl, wan22, hunyuan_image, qwen_image,
qwen_image_edit) with vision analysis of the source. **Use when** you're transforming or editing an image.
### Text-to-Image Prompt Enhancer
Multi-platform image prompts (8 platforms incl. Flux, SDXL, Pony, Illustrious, Chroma, Qwen Image/Edit, Wan
Image), 22 genre styles, optional reference images, emphasis `(keyword:1.5)` and alternation `{a|b|c}`.
**Use when** you're generating a still image from text.
### Alice T2V Prompt Refiner
Refines rough text and/or reference images into structured Alice text-to-video prompts. **Use when** you're
targeting Alice.
---
### 3. Image-to-Video Prompt Expander
## 2. Platform output
**When to use:**
- ✅ Animating existing images
- ✅ Image-to-video workflows
- ✅ Want AI to describe image
- ✅ Focus on motion/camera
Format an already-written prompt for a specific model.
**Example:**
```
Image: portrait.jpg
Motion: "slowly turns and smiles"
Camera: push in
Output: Video prompt preserving image + adding motion
```
### Platform Prompt Rewriter
Rewrites a finished prompt for any of 60+ platform profiles, in that model's exact format (including
structured ones: MiniMax H3 fields, FLUX.2 / Ideogram JSON, edit instructions), and keeps it inside the
text encoder's token limit so trigger words aren't dropped. **Use when** you already have a prompt and want
it tuned for a particular model. Outputs: prompt, negative_prompt, report, system_prompt.
**Pros:**
- Vision model describes image
- Focus on motion
- Camera controls
- Preset support
**Cons:**
- Needs vision model
- Video-only (not for img2img)
- No platform optimization
### Ideogram 4 Magic Prompt
Builds an Ideogram 4 "magic prompt" (structured JSON + high-level line) with a recommended canvas size.
**Use when** you're generating with Ideogram 4.
---
### 4. Image-to-Image Prompt Expander (NEW!)
## 3. Wildcards & variation
**When to use:**
- ✅ Transforming/editing images
- ✅ Image-to-image workflows
- ✅ Platform-specific needs (Flux, SDXL, etc.)
- ✅ Style transfer, lighting changes
### Wildcard Processor
Resolves wildcard syntax (`__name__`, `{a|b|c}`, weights, ranges, variables, `__objects[metal AND handheld]__`)
read from `models/wildcards`. **Use when** you want wildcard expansion without an LLM.
**Example:**
```
Image: photo.jpg
Change: "make it oil painting"
Platform: flux
Art Style: oil painting
Output: Flux-optimized prompt for artistic transformation
```
### Semantic Variation
Moves each random wildcard pick to a semantic neighbour, along named direction axes. **Use when** you want
controlled variety across runs.
**Pros:**
- Platform-aware (6 platforms!)
- Vision model
- Art/style controls
- Optimized per model
### Concept Survival Check
Measures whether the key concepts (a surreal anomaly, exact LoRA triggers, ...) survived the LLM rewrite.
**Use when** you need to confirm something important wasn't paraphrased away. Outputs: report, all_survived,
missing, carried_by_json.
**Cons:**
- Needs vision model
- Image-only (not for video)
- No presets (uses platforms)
### Surreal Premise
Turns an ordinary scene into one anomaly stated as plain physical fact, with an instruction block that
protects it through the rewrite. Its `llm_instructions` plug into any enhancer's `wildcard_instructions`.
**Use when** you want a grounded surreal premise. See SURREAL_GUIDE.md.
---
## Use Case Examples
## 4. Prompt builders (click, don't type)
### Use Case 1: Quick Video from Text
### Wildcard Prompt Composer
Builds a whole prompt section by section with clickable pills instead of typed wildcard syntax, in the
chosen platform's section order. Lock a section to hold it while re-rolling, drag to reorder, save as a
template. **Use when** you want to assemble a prompt visually. See PROMPT_BUILDER_GUIDE.md.
**Goal:** Fast video prompt
**Node:** AI Video Prompt Expander (Standard)
```
Input: "robot in neon city"
Preset: cinematic
Tier: enhanced
```
### Use Case 2: Precise Video Control
**Goal:** Specific cinematography
**Node:** AI Video Prompt Expander (Advanced)
```
Input: "spaceship flying"
Shot: wide shot
Camera: tracking shot
Lighting: rim lighting
Lens: wide-angle
```
### Use Case 3: Animate Portrait
**Goal:** Make image move
**Node:** Image-to-Video Prompt Expander
```
Image: portrait.jpg
Motion: "turns head and smiles"
Camera: dolly in
For: Hunyuan Video, CogVideoX
```
### Use Case 4: Flux Style Transfer
**Goal:** Photo to painting
**Node:** Image-to-Image Prompt Expander
```
Image: photo.jpg
Change: "impressionist painting"
Platform: flux
Art Style: oil painting
For: FLUX.1-dev
```
### Use Case 5: SDXL Enhancement
**Goal:** Enhance with SDXL
**Node:** Image-to-Image Prompt Expander
```
Image: low_res.jpg
Change: "enhance quality, add details"
Platform: sd_xl
Detail: highly detailed
For: SDXL
```
### Use Case 6: Qwen Quick Edit
**Goal:** Fast specific edit
**Node:** Image-to-Image Prompt Expander
```
Image: portrait.jpg
Change: "change background to beach"
Platform: qwen_image_edit
For: Qwen Edit Model
```
## Feature Availability
### Wildcards
✅ All nodes support wildcards!
```
"A {animal:cat|dog|fox} {action:running|flying}"
```
### Random Mode
✅ Standard: Full random
✅ Advanced: Respects dropdowns
✅ Img2Vid: Available
❌ Img2Img: Uses platforms instead
### Vision Model
❌ Standard: No
❌ Advanced: No
✅ Img2Vid: Yes
✅ Img2Img: Yes
### Platform Optimization
❌ Standard: No
❌ Advanced: No (Wan 2.2 focus)
❌ Img2Vid: No (video focus)
✅ Img2Img: Yes! (6 platforms)
## Workflow Recommendations
### Video Generation Workflow
**Option 1: Simple**
```
[Standard Node] → [Video Gen Model]
```
**Option 2: Advanced**
```
[Advanced Node] → [Video Gen Model]
```
**Option 3: From Image**
```
[Load Image] → [Img2Vid Node] → [Video Gen Model]
```
### Image Generation Workflow
**From Image:**
```
[Load Image] → [Img2Img Node] → [Image Gen Model]
```
**Platform-Specific:**
```
For Flux: [Img2Img] (platform: flux) → [Flux Model]
For SDXL: [Img2Img] (platform: sd_xl) → [SDXL Model]
For Qwen: [Img2Img] (platform: qwen_image) → [Qwen Model]
```
## Common Questions
### Q: Which node for best video prompts?
**A:**
- Quick: Standard
- Precise: Advanced
- From image: Img2Vid
### Q: Which node for Flux img2img?
**A:** Image-to-Image with platform: flux
### Q: Can I use vision model with video nodes?
**A:** Only Img2Vid and Img2Img have vision support
### Q: Which supports wildcards?
**A:** All 4 nodes!
### Q: Which respects my aesthetic dropdowns in random mode?
**A:** Advanced node (video)
### Q: Which optimizes for my image model?
**A:** Image-to-Image (6 platforms!)
## Summary
**Choose based on:**
| Your Task | Use This Node |
|-----------|---------------|
| Text → Video prompt (quick) | Standard |
| Text → Video prompt (precise) | Advanced |
| Image → Video prompt | Image-to-Video |
| Image → Image prompt (Flux) | Image-to-Image (flux) |
| Image → Image prompt (SDXL) | Image-to-Image (sd_xl) |
| Image → Image prompt (Qwen) | Image-to-Image (qwen) |
| Image → Quick edit | Image-to-Image (qwen_edit) |
**All nodes support:**
- ✅ Wildcards
- ✅ LM Studio / Ollama
- ✅ Multiple variations
- ✅ File saving
- ✅ Keyword injection
**Special features:**
- Vision model: Img2Vid, Img2Img only
- Platform optimization: Img2Img only
- Full aesthetic control: Advanced, Img2Img
- Random mode: Standard, Advanced, Img2Vid
### Wildcard Character Composer
The same node limited to the Subject section, for a character you reuse across prompts or branches.
---
**Pick the right tool for your workflow!**
## 5. Prompt database
All nodes work together - use Standard for quick video prompts, Img2Img for Flux transformations, etc.
| Node | Does |
|------|------|
| **Save Prompt to DB** | Saves a prompt (+ optional negative) to the local SQLite DB; passes the prompt through unchanged |
| **Search Prompt DB** | Finds the top match by keyword, category, platform, rating, tags or favourites |
| **Import Prompts to DB** | Bulk-imports prompts from `.txt` / `.csv` / other files |
| **Browse / Random Prompt DB** | Fetches a prompt by ID, or a random/filtered one by seed |
**Use when** you want to build and reuse a personal library of prompts.
---
## Feature availability (expanders)
| | Standard | Advanced | Img2Vid | Img2Img | Txt2Img |
|---|---|---|---|---|---|
| **Presets** | ✅ | ✅ | ✅ | ❌ (platforms) | ❌ (genres) |
| **Wildcards** | ✅ | ✅ | ✅ | ✅ | ✅ |
| **Vision model** | ❌ | optional | ✅ | ✅ | optional |
| **Platform optimization** | video target | video target | video target | ✅ 6 | ✅ 8 |
| **Random mode** | ✅ | ✅ (respects controls) | ✅ | ❌ | ✅ |
---
## Common questions
**Q: Quick video prompt?** Video Prompt Expander. **Precise?** Advanced. **From an image?** Image-to-Video.
**Q: I already have a prompt — how do I format it for my model?** Platform Prompt Rewriter (60+ profiles).
**Q: Which nodes support wildcards?** All the expanders, plus the dedicated Wildcard Processor and the
Composer builders.
**Q: Which use a vision model?** Image-to-Video and Image-to-Image always; Advanced and Text-to-Image
optionally.
**Q: How do I build a prompt without typing wildcard syntax?** Wildcard Prompt Composer (whole prompt) or
Wildcard Character Composer (one character).
**Q: Where do I keep prompts I like?** The four Prompt Database nodes.
---
**Pick the right tool for your workflow — the nodes are designed to chain together.**
+297
View File
@@ -0,0 +1,297 @@
# Wildcard Composer Guide
Builder nodes write a prompt section by section, with buttons instead of typed wildcard syntax.
- **Wildcard Prompt Composer** holds every section in one node: Format, Subject, Action, Setting,
Light & atmosphere, Composition, Camera and Style & finish (plus Text when you add it), shown in
the order the chosen platform wants them. Most of the time this is the only builder node you need.
- **Wildcard Character Composer** is the same node limited to the Subject section (with Pose from Action), for
a character you want to reuse across several Wildcard Prompt Composers or branches.
A Subject phrase, for example:
```text
a [Age] [Occupation] in typical uniform, with dark wrinkled skin, a [Face] and [Hair color] hair
lit by glowing fiery red light, with a [Expression] expression
```
The words are yours; each `[Pill]` is a wildcard. One roll reads: *"a middle-aged adult professor in
typical uniform, with dark wrinkled skin, a gaunt face and cinnamon brown hair lit by glowing fiery
red light, with a thoughtful expression."*
## The panel
**Section strip** (top): the platform's section order, read from the `structure` line of the
platform profile you pick in `platform` (Krea 2: subject with its actions, then setting, light,
medium, framing; FLUX.2: subject, action, style, setting, lighting, technical). Click a section to
work on it; it turns amber. Sections with something in them have a solid outline. `+ Subject` adds
Subject 2 (3, ...), placed right after Subject so each person keeps their own attributes, which is
what Krea 2 asks for. `+ Text` adds the optional Text section (words shown in the picture).
**Your own section order**: drag a section chip onto another to reorder. The node then builds and
joins its sections in that order (saved with the node and its templates) whatever the platform;
**Platform order** goes back to the platform's. The sections and why: dev/PROMPT_TAXONOMY_SPEC.md.
**Prompt frame**: every section of the prompt, one line each, in platform order. Every gap between
pills is a text box; type there. The amber gap is the insert point: click a gap (in any section) to
move it there. Typed text may use wildcard syntax too (`{red|blue}`, `__name__`). A word doubled
across a pill (`auburn hair` + typed `hair`) is written once. Each line has two switches:
- **Lock** keeps that section's picks while the seed moves, so you can hold a character and re-roll
only the setting (the section is held at the seed it last rolled with; click again to release).
- **LLM fills** asks the Platform Prompt Rewriter to write the section when you leave it empty
("a setting that suits the subject"). It needs `llm_instructions` connected to the rewriter's
`wildcard_instructions`. A section you have written in is used as written.
**Moving wildcards**: drag a pill to a gap (in its own section or another one) to move it there;
drop it on another pill to put it just before that one. The text on either side of where it was
closes up, as when a pill is removed. Clicking a pill opens its list and makes the gap right after
it the insert point, so the next slot button adds a wildcard just after the one you selected.
To add one at the very start, click the small gap before the first pill.
**Slot buttons**: the buttons for the active section (Setting shows Location, Interior, Era,
Weather...), under headings for the Subject (Person, Face & hair, Clothing, Accessories). A button
appears only when your library has at least one list for it, so another user's panel shows fewer
or more buttons depending on their packs; hover a button to see how many lists back it.
**Subject type** (the menu on Subject lines): Person, Animal, Creature, Object, Vehicle or Food
shows that type's buttons (an Animal subject isn't offered Makeup); *Any type* shows them all.
*Scene only* means no subject at all (a landscape, an empty plate for a composite, a storyboard
background): the Subject line is left out of the prompt and the rewriter is told not to add one.
**Arrange** (next to *+ Button*): drag a button onto another button to put it there, onto a group
heading to move it under that heading, or onto a section chip to move it to that section; *hide*
takes it off the palette (Arrange still shows it, to bring it back). The layout is saved in
`builders_user/button_layout.yaml` and applies to every node; **Reset layout** returns to the
shipped one. The shipped `builders/prompt.yaml` is never changed.
**Any · Woman · Man** (on Subject lines, for people): which lists the buttons use for that subject. Lists
named for the other gender are left out and lists named for this one come first (lists named for
neither follow). Switching moves the pills that are still on Random to the best list for the new
choice; pills with picks keep their list. Subject 2 has its own switch. Click one to insert a pill at the amber gap. Its list is the best match in your
library (see *Where the lists come from*); change it in the list viewer.
**One row per pill** of the active section:
| control | what it does | syntax written |
|---|---|---|
| Random | any entry | `__list__` |
| Fixed | always your first pick, or your own text | `{1$$value}` |
| Subset | random among your picks | `{a\|b\|c}` |
| Exclude | random, never your picks | `__list!{a\|b}__` |
| − n + | that many different entries, joined with "and" | `{2$$ and $$…}` |
| Meaning | the LLM polish may reword it, keeping the meaning | (default) |
| Exact | kept word for word (names, LoRA triggers) | `=` marker |
| Loose | inspiration; the LLM may drop it | `?` marker |
The row also shows what the pill rolled for the current seed.
**List viewer** (click a pill or its row). Long lists load 300 entries at a time as you scroll.
Lists rated above off join the source menu at that level, marked with it (`suggestive ·`, `explicit ·`). The
viewer's *NSFW level* menu rates the list, and every rated entry has its own small menu (auto = its words);
entries the node's `nsfw` level leaves out are greyed. Both save to `_catalog_user.yaml`. choose the source list (every list in your library
that matches the slot; lists with identical content are shown once, and each is labelled short,
medium or long by its median entry length), search it, tick entries, then *Fix to first pick*,
*Use picks as subset* or *Exclude picks*. Rate while you look: the stars rate the list (starred lists
come first for that slot everywhere), *Hide list* takes it out of every slot and bare name, and
*drop* on an entry means it is never picked again from that list. All three are saved in
`_catalog_user.yaml` next to the lists, so they apply to every node, not just this one. *Or fix to your own value* sets any text, for example an
exact age such as "7-year-old" or "42-year-old".
**Preview**: exactly what the node outputs for the seed on the node (the same code runs both).
*Re-roll* moves the seed on by one.
## Outputs and chaining
| output | use |
|---|---|
| `sections` | every section filled so far. Connect to the next builder's `sections` input. |
| `text` | all sections as one prompt in the platform's order. Use as is, or connect to a Platform Prompt Rewriter's `idea` for LLM polish. |
| `llm_instructions` | which picks were random and how to keep them. Connect to the rewriter's `wildcard_instructions` so Exact picks survive the rewrite. |
| `template` | the prompt as unresolved wildcard syntax, to save or to let another node roll it. |
| `report` | the picks and any warnings. |
Usually: **Wildcard Prompt Composer** → **Platform Prompt Rewriter** (`idea` ← `text`,
`wildcard_instructions` ← `llm_instructions`).
Chaining is for reuse: one **Wildcard Character Composer** feeding the `sections` input of several
Wildcard Prompt Composers gives the same character in different scenes. A section both nodes fill is joined, the
upstream one first.
### With the LoRA Suggester (Krea2)
| from | to |
|---|---|
| Composer `text` | Platform Prompt Rewriter `idea` |
| Composer `llm_instructions` | Rewriter `wildcard_instructions` |
| Composer `sections` | LoRA Suggester `sections` |
| Rewriter `prompt` | LoRA Suggester `text` |
| LoRA Suggester `prompt_with_triggers` | the Krea2 text encoder |
| LoRA Suggester `suggestions` | Eric Krea2 Multi-LoRA Stack `suggestions` |
The Suggester picks LoRAs from the Composer's separate sections (style and format feed the style role, setting the
environment role, and so on), so the rewriter's prose cannot blur that choice; the trigger words are added after the
rewrite, so the LLM never sees them. The Composer's `nsfw` level travels with `sections` and caps the Suggester too.
Rewriter settings for this: platform **Krea 2**, `official_prompt` **off** (Krea's own prompt expands short prompts;
off uses the profile's rules: keep every subject, add nothing, polish a detailed prompt rather than inflate it,
60-150 words), temperature about 0.5. `extra_instructions` like "name the medium and style in the first sentence"
keeps the style words where Krea2's 512-token limit cannot cut them. The Krea2 Magic Prompt node is a short-prompt
expander: after a Composer it rewrites the picks and pushes the style words to the end.
For variety across a batch, put wildcards in the Style and Format sections (a medium, a movement, a rendering), not
only in the subject: the Suggester's `variety` only reshuffles LoRAs that score close to each other, while a different
style phrase picks a different family of LoRAs. "LLM fills" on the Style section leaves the Suggester nothing to read.
**Sliders.** Slider LoRAs (age, waist, shot size, saturation ...) are not scored like other LoRAs: the Suggester reads
the prompt for phrases that ask for a place on a slider's axis ("wasp waist", "a very old fisherman", "extreme
close-up") and sets that slider to a signed weight. Everyday style words ("detailed", "dark", "comic") are kept below
the firing line so they do not dial anything. The phrases live in the LoRA Catalog tool's `axes.yaml` and
`axes_ladders.yaml`; what every file is, and how to add phrases, calibrate a slider with your own weights or add an
axis: **SLIDERS_AND_AXES.md** in the LoRA Catalog folder. Node widgets: `slider_max`, `slider_range` (used when a
slider's card has no believable range), `slider_min_strength` (1 any cue, 2 the default, 3 only strong asks).
**exclude / pin boxes.** Whole words, one entry per line or comma separated. Plain words match a LoRA's name or file
name; `folder:<words>`, `role:<role>` and `axis:<axis>` (exclude only, except `axis:` pins) widen it. A pin uses one
LoRA, the best match, and may carry a weight: `waist slider=-8`, `axis:age=+3`. The node's tooltips have the full
list, and the report says what each entry matched.
## Where the lists come from
`builders/prompt.yaml` defines the sections and every slot button; `builders/character.yaml`
extends it and keeps the subject and action buttons. A slot finds its lists by name: a list belongs to a slot when its
leaf name (last path segment, lower case, pack prefixes such as `cops_wc_` removed) fully matches one
of the slot's `match` patterns. Your stars rank first, then earlier patterns, then the catalog's
quality score (booru-tag lists rank below prose), then bigger lists; hidden lists are left out. The
viewer's source menu shows each list's stars, size, length or `tags`, and quality (`q85`). Lists
with `lora` in the key are never offered. Lists rated above the node's `nsfw` level (by folder, content, or
words in the key: see the Wildcard guide, NSFW levels) are not offered; the others are marked with their level.
A slot can also take `folders` (regexes searched in the folder part of the key: every list in a
matching folder counts, after `match`) and `search` (words that must all be in the key, see below).
The Name button uses `folders` for packs such as a name megalist whose lists are called
`black - female`.
When a list's own name says nothing a button knows (`basemodel/eye-color/brown`,
`loom/10-lighting/female/soft`), its nearest meaningful folder name is matched instead: generic
folders (`female`, `general`, `v2` ...) are looked past, leading numbers dropped, the pack folder
never used, and only one level up (further up, folders tend to name a whole scene).
## Prompt line (your prompt files)
**+ Prompt** adds a Prompt line; drag its chip like any other line, and put a Setting, Format, a second
Subject or anything else around it. Its button, **Browse prompts.**, opens your prompt files (`_prompts`,
see the Wildcard guide) folder by folder: click a file to read its first prompts, **Use** inserts it,
**Use the whole folder** inserts a pill that draws from every file in that folder. The search box finds
files by name in every folder. Click the pill afterwards to see all its prompts, search them, pick, fix,
exclude or drop some, exactly as with any list; **Browse prompts.** in that window swaps the file. The
Prompt line feeds every role of the LoRA Suggester. A whole prompt often names its own place or style, so
an added Setting can contradict it; the Platform Prompt Rewriter after the Composer smooths that out.
## More lists
**More lists…**, the last button of every palette, shows the usable lists no button above offers:
word, phrase and tag lists with 3+ entries (whole prompts and templates stay with Find). Each gets
a section from the catalog's reading of its content, or from words in its path, and a group from
the path word it shares with the most other lists (Makeup, Creature, Food ...). Click a group, then
a list to insert it; ☆ saves one list as a button, **☆ Button for all N lists** saves the group.
Lists with identical content are shown once.
## Find, and your own buttons
The **Find** box next to the section heading searches every list: first lists whose key has all your
words, then (when the catalog is built) lists whose entries match. Click a result to insert that
list at the amber gap; the pill is labelled with the list's name. The Woman / Man switch of the
section filters Find too.
Save what you find as a button, under **My buttons** at the top of the section's palette:
* **☆ Button** on a result (or in a pill's list viewer): a button for that one list.
* **☆ Button for "words"** at the foot of the results, or **+ Button**: a category button. It
offers every list whose key has all the words, folders included, now and as you add packs.
A word of 4+ letters may sit inside a longer one (`names` finds `peoplenamemegalist`), a plural
`s` is optional, and gender words (`female`, `men`, ...) follow the list's gender, so `male` does
not find female lists. The editor shows how many lists match while you type.
Buttons are saved in `builders_user/my_buttons.yaml` (plain YAML, safe to edit by hand) and are
shared by every builder node whose parts show that section; ✎ on a button edits or deletes it.
A button of yours whose lists are all rated above off is hidden while `nsfw` is off.
```yaml
buttons:
- id: my_black_names
label: Black names
section: subject
lists: [blackamericanfemalefirstnames_v10/black_female_names]
- id: my_famous_buildings
label: Famous buildings
section: setting
search: famous buildings
```
To change a slot, add slots or pin your favourite lists, copy `prompt.yaml` to `builders_user/`
(same `id` replaces the shipped one) and edit it. Slots are grouped by the section whose buttons
show them; the package's own curated lists (light/setups, camera/lenses, art/mediums, ...) are
pinned first:
```yaml
- section: subject
slots:
- id: hair_color
label: Hair color
match: ['hair_?colou?rs?']
avoid: ['fantasy']
lists: ['my_pack/hair_colors_curated'] # pinned first
```
A new YAML file with a new `id` defines a new builder; it needs a node class (one line in
`prompt_builder_node.py`).
## Merging lists
Most packs share one core vocabulary and add their own tail (in one library, "black" was in 13 of
26 hair colour lists). **Merge lists…** in a pill's list viewer folds every list behind that button
into one:
* Near-identical entries become one row: case, hyphens, weights and the button's own words are
ignored, so "Black hair", "black" and "black-haired" fold for Hair color. The most common
spelling is shown; hover a row for the lists it came from and the other spellings.
* Rows are sorted by how many lists have them (`×13`); entries in 3+ lists are highlighted. Show
only entries in 2+ / 3+ / 5+ lists, or only short, medium or long ones; what is shown (and ticked)
is what gets saved.
* Click a row to leave it out. **Untick shown** / **Tick shown** work on what the search box finds,
so "untick everything with 'glowing'" is two steps.
* Untick source lists at the top to leave them out of the merge.
* **Save list** writes `mine/<button>/<name>.txt` in the wildcard folder most of the sources come
from, with a header naming them. Lists in `mine/<button>/` come first on that button, and the pill
switches to the new list. **Hide the source lists** hides them from every button (Hide list in the
viewer brings one back).
Your merged lists are for you: the header keeps the sources, since their licences are unknown.
## Templates
The bar at the top of the node saves everything on it as a named template and loads it back on
any composer node:
* **Save as…** asks for a name and writes `builders_user/templates/<name>.json`: every section's
text and pills (list, mode, picks or exclusions, count, keep), Subject 2, 3 …, the Woman / Man
choices, LLM fills and the platform. Locks are not saved, so a template always loads free to re-roll.
* **Load template…** replaces what is on the node. **Undo load** puts back what was there.
Sections the node doesn't have (Setting on the Character Composer, say) are left out, and the
bar says so.
* **Update** saves the node over the template it was loaded from; **Delete** removes that template.
* A pill whose list isn't in this library (a template from another machine) shows red **missing**;
open it and pick another source list.
Templates are plain JSON, one file each, so they can be copied, shared or kept in git.
## Ages
The Age slot uses whatever age lists you have, with nothing removed, and any exact age can be typed
as a Fixed value. The only content rule in the wildcard engine is the content filter (on by default,
`"content_filter": false` in config.json turns it off) that drops a single list entry pairing
minor-related and sexual terms, and checks the assembled prompt for a minor term next to an
explicit sexual term (nudity alone does not count). A failing roll is re-rolled; typed text that
fails is blanked, with the reason in the report. It does not touch age lists or ordinary depictions
of people of any age. `violence_filter` (off by default) is separate: see the Wildcard guide.
+10 -12
View File
@@ -27,12 +27,12 @@ Use this if you want the image-to-video or image-to-image nodes to caption image
4. Set `vision_model_name` to the repo or local path (append `@4bit`/`@8bit` if desired)
5. Use the `vision_endpoint` field for optional overrides like `quant=4bit;attn=sdpa`
## Step 2: Verify Installation
## Step 2: Verify Your LLM Backend
1. Open terminal in the video_prompter directory
2. Run: `python test_setup.py`
3. Choose your LLM backend and test connection
4. You should see "✅ ALL TESTS COMPLETED"
1. Confirm your server responds in a browser:
- LM Studio: http://localhost:1234/v1
- Ollama: http://localhost:11434
2. Make sure a model is loaded (LM Studio) or pulled (Ollama) and the server is running.
## Step 3: Restart ComfyUI
@@ -43,7 +43,7 @@ Use this if you want the image-to-video or image-to-image nodes to caption image
## Step 4: Add Node to Workflow
1. Right-click in ComfyUI → Add Node
2. Navigate to: **video → prompting → AI Video Prompt Expander**
2. Navigate to: **Eric Prompt Enhancers → Video Prompt Expander**
3. The node will appear with all inputs ready
## Step 5: Basic Usage
@@ -187,17 +187,15 @@ Once you have basic expansion working:
- **Full Documentation**: See README.md
- **Configuration Guide**: See CONFIGURATION.md
- **Presets Reference**: See presets.py
- **Test Your Setup**: Run test_setup.py
## Getting Help
If something isn't working:
1. Run `python test_setup.py` - it will identify issues
2. Check the **status** output - it shows errors clearly
3. Review your LLM backend connection
4. Check ComfyUI console for error messages
5. Verify model is loaded and endpoint is correct
1. Check the **status** output - it shows errors clearly
2. Review your LLM backend connection
3. Check ComfyUI console for error messages
4. Verify model is loaded and endpoint is correct
## Success!
+25 -2
View File
@@ -6,12 +6,35 @@ After restarting ComfyUI, all nodes appear under:
**Add Node → Eric Prompt Enhancers**
You'll find 5 nodes:
You'll find **18 nodes**, grouped below (see README.md → "The Nodes" for full descriptions):
**LLM expanders & enhancers**
1. Video Prompt Expander
2. Video Prompt Expander (Advanced)
3. Image-to-Video Prompt Expander
4. Image-to-Image Prompt Expander
5. Text-to-Image Prompt Enhancer ⭐ NEW
5. Text-to-Image Prompt Enhancer
6. Alice T2V Prompt Refiner
**Platform output**
7. Platform Prompt Rewriter
8. Ideogram 4 Magic Prompt
**Wildcards & variation**
9. Wildcard Processor
10. Semantic Variation
11. Concept Survival Check
12. Surreal Premise
**Prompt builders**
13. Wildcard Prompt Composer
14. Wildcard Character Composer
**Prompt database**
15. Save Prompt to DB
16. Search Prompt DB
17. Import Prompts to DB
18. Browse / Random Prompt DB
---
+117 -15
View File
@@ -38,39 +38,93 @@ strangeness is the hour, the emptiness, the stillness, the process, and a story
| double reading | Dali | Two things with the same silhouette, one form that is honestly both |
| working machine | Varo | Mechanism + feedstock + product, joined by a causal chain that looks functional |
| archive composite | Uelsmann, Maar | Fragments from YOUR iconography file and prompt database, never from stock |
| found strange | Atget, Crewdson | No anomaly: hour, emptiness, stillness, a light without a source, a trace |
| found strange | Atget, Crewdson | No anomaly: ONE hour and ONE condition - emptiness, stillness, light or a trace |
| process estrangement | Man Ray, Miller | An ordinary subject and one photographic process |
The operations table from the plan (displacement, scale violation, hybridization, material substitution, physics
The operations table from the plan (displacement, scale violation, hybridization, material substitution, behaviour
transfer, physics
negation, inversion, double image, animation / petrification, absence, metaphysical space, literalized language,
multiplication, and for video a temporal one) is the critic's vocabulary for describing a result.
multiplication, causal reversal, autonomy, taxonomy error, and for video a temporal one) is the critic's
vocabulary for describing a result. The last three come from the transformation atlas in the *Surrealism Field
Manual*: the consequence present without its cause; the shadow, reflection or garment that acts while the thing
that casts it does not; and the object left physically untouched but catalogued as a specimen of the wrong
kingdom. Autonomy is allowed as a second operation, because a shadow behaving on its own echoes an object-level
anomaly rather than competing with it.
### A premise is a picture, not an inventory
`found_strange` originally joined its hour to two independently drawn conditions. Measured over 300 seeds that
gave four and a half unrelated facts per premise — the generator itself producing the prompt soup the method
exists to avoid — and in 33% of draws it paired a daylight hour with a condition that only reads in darkness
("noon with hardly a shadow" and "only one light in the whole scene is on"). Handed two facts that cannot both
be true, the LLM critic would look for the relation joining them and invent one, and nothing downstream could
recover: in the run that exposed this, a telephone receiver became the only light source in a garden at noon.
It now draws ONE hour and ONE condition, and the entries carry a light tag (`dark` / `bright` on the hour,
`needs_dark` on the conditions that are invisible in daylight) so an incompatible pair cannot be drawn at all.
Two hours by three groups also gives the critic six genuinely different candidates where a forced mode used to
yield two near-copies, which matters because the critic's whole job is to reject most of what it is given.
Contradictions measured after the change: none in 300 seeds.
### The law
An operation says what is violated. The **law** says what governs the violation: what may change, what may not,
and how the change behaves. Without one the picture reads as random, and a second anomaly reads as a second idea
instead of an echo - the commonest failure in generated surrealism, and the one the field manual is most
insistent about. Every operation carries its own law, so the law always governs the premise that was actually
chosen; the node's `law` input overrides it and is never touched. The eight charges carry laws of their own -
grief makes what the missing person touched heavier, desire makes what is wanted larger - but these are offered
to the LLM critic as a *suggestion* only, because an emotion does not know which anomaly was picked. The law
reaches the instruction block under its own heading, with the standing order to show the rule in effect, never
state it, and remove anything that does not obey it.
The critic exists twice. The **code critic** is seeded, offline and instant: it filters cliches and explanations
and chooses by score. The **LLM critic** is one call: it names the subject, lists its ordinary attributes, keeps
or rejects each candidate with a reason (an affinity that cannot be said in one short clause is rejected),
carries out the procedure modes, and writes the premise, a restatement, a Magritte-style title that names a
problem and never describes the picture, and counter-terms for the negative prompt. If its answer is unusable
the code critic's choice stands and the `why` output says so.
and chooses by score. It cannot check that a second operation obeys the first one's law, and says so in `why`.
The output is a **brief**: the idea with the premise appended as plain physical fact, and an instruction block
that travels through the `wildcard_instructions` input every enhancer already has. The block tells the
The LLM path is now staged. The first call inventories the **ordinary scene**: stable entity ids, visible
attributes, ordinary physical properties, relationships, affordances, subject action, setting, light and
viewpoint. It does not invent an anomaly. The **LLM critic** is the second call. It names the subject, keeps or rejects each
candidate with a reason (an affinity that cannot be said in one short clause is rejected), carries out the
procedure modes, writes the law that fits the premise it chose, and then does the field manual's own critique
step: it scores its draft premise on seven rubric dimensions from 0 to 4 - reality anchor, rupture, psychic
pressure, transformation rule, formal unity, ambiguity, residual power - names the lowest-scoring one, and
rewrites the premise with that one repair applied. The scores, the weakest dimension and the repair are printed
in `why`, so the judgement can be judged. It also picks one of five named title strategies (sideways
association, false classification, temporal clue, ordinary phrase, poetic friction); "Dream", "Untitled" and
anything containing "surreal" are refused. If its answer is unusable the code critic's choice stands and the
`why` output says so; a missing or malformed part - no scores, no repair, an over-long or placeholder law - is
dropped rather than guessed at, and the rest of the verdict is still used.
The critic also returns a structured render plan: target, replacement/material/borrowed behaviour, properties to
preserve, positive visual evidence, likely ordinary interpretations to reject, composition, and a
`preserved_scene` from which replaced entities and properties have already been removed.
An operation-specific compiler turns that plan into the node's **text** output. It never prepends the untouched
idea: doing that restored replaced objects because the platform rewriter is required to keep every noun the user
named. Removed entity descriptions and their head nouns are hard validation failures. Context clauses that name
one are dropped; if the anomaly itself names one or uses substitution grammar, compilation is refused and the
unchanged idea is returned with an explicit error in `why`.
The instruction block travels through the `wildcard_instructions` input every enhancer already has. The block tells the
enhancer's LLM to state the anomaly early as fact, restate it once in other words, keep everything else
rigorously ordinary, render in the chosen register, serve the chosen charge, and never use the ban-list. Its
rigorously ordinary, render in the chosen register, serve the chosen charge, add no further symbolic objects
(every extra noun competes with the premise, which is how a prompt becomes soup), and never use the ban-list. Its
`Concepts` heading is the one the Concept Survival Check parses, so whether the anomaly survived the rewrite
can be measured.
## Using it
**Surreal Premise node** (`Eric Prompt Enhancers`). Connect `text` to an enhancer's prompt and `llm_instructions`
to its `wildcard_instructions`. `why` shows every candidate, the critic's judgements and the reasoning. `title`
and `negative_additions` are extras.
to its `wildcard_instructions`. `why` shows every candidate, the critic's judgements, the rubric scores and the
reasoning. `title`, `negative_additions` and `law` are extras.
Controls: `mode` and `operation` (auto, or force one), `count` (1 or 2, never more; a second operation is always
atmosphere-level so both read as one event), `strangeness` (shifts which modes and operations are drawn),
`register` (deadpan photographic by default: a photograph argues with its own impossibility), `charge` (the
emotional source the anomaly serves; an anomaly with no stake reads as a gimmick), `critic` (llm or code),
`seed`, `medium` (video adds anomalies in time), an optional `embedder` (partners far from the idea in meaning
score higher), and `use_archive`.
score higher), `use_archive`, and `law` (leave blank and the chosen operation's law is used; type one and it is
used verbatim, for instance *only patterned fabric can cross the boundary between a body and a wall*).
**The old `surreal` preset** on the three video nodes and `genre_style = surreal` on the Text-to-Image node now
route through the engine with the code critic, seeded like the node's wildcards, so each variation gets its own
@@ -81,7 +135,8 @@ it with your own recurring objects, places and motifs. The engine draws from it
mode needs it. Magritte's bowler hat, apple and curtain were a small private vocabulary recombined for decades;
that is what makes a body of work recognisable instead of averaging toward everyone's.
**Lists** in `wildcards/surreal/` (physics, absences, idioms, processes, temporal, found_strange, machines) are
**Lists** in `wildcards/surreal/` (physics, absences, idioms, processes, temporal, autonomy, reversals,
found_strange, machines, motifs) are
ordinary wildcards too: `__surreal/physics__`. Entries are conditions laid on the user's own scene and say
`THE SUBJECT` for its main subject.
@@ -95,6 +150,53 @@ making placements relative to the subject), it sometimes rewrites rather than ke
candidate number (now detected), and its own premises can contradict themselves. A 24B or larger model is the
one to use for the critic.
## Phase 1: writing for the image model (2026-10-01)
The 2026-09-21 run showed the idea surviving the rewrite and the picture still coming back ordinary. Three causes,
and what changed (spec: `dev/SURREAL_RENDER_SPEC.md`):
1. **Substitution grammar.** "Where the teacup should be there are boots instead" gives a text encoder a teacup AND
boots; it keeps nouns and loses the counterfactual. Every candidate now carries a `render` - the result as the
camera sees it - and the replaced object goes on a `suppress` list the rewriter is told never to name.
`core/strategies/surreal/lint.py` rejects should be / would be / instead of the / in place of / as if / treats
it as, and attitudes with no pixels (nobody notices, unnoticed, remains unaware or unfazed), in generator
output and in the critic's `render`. On the Platform Rewriter's output, attitude clauses are removed and
substitution grammar or a named suppressed object is reported as a warning.
2. **The anomaly was outvoted.** The block now puts the anomaly FIRST, large in the frame, gives it at least a third
of the words, asks for a second visible consequence instead of a paraphrase, and drops camera boilerplate
unless the register needs it.
3. **Conceptual but invisible.** The rubric gains `visibility` (unmistakable in a thumbnail at a glance), and the
critic is told that deadpan is not the same as small.
**Two-stage.** The node has two new outputs, `scene_prompt` and `edit_instruction`, and a `staging` widget (all
appended at the end). Generate the ordinary picture from `scene_prompt`, then apply `edit_instruction` with an
edit model (Qwen-Image-Edit, Flux 2 edit, Kontext, Qwen-Image 2.1 i2i). The edit is filled whenever the
operation can be done as one edit (displacement, scale, hybridization, material, inversion, petrification,
multiplication; the LLM critic also writes edits for others when it can). `two_stage` restricts the automatic
choice to those operations.
### Structured compiler stages (2026-10-18)
1. **Ordinary inventory.** Record the scene before intervention; no surreal invention is allowed.
2. **Generator and critic.** Choose one operation and produce a transformation law plus a structured render plan.
3. **Operation compiler.** Compile only the final transformed scene, anomaly first, with required physical proof
and no removed entity. Displacement, material substitution, scale violation and behaviour transfer have
dedicated compilers; the other operations use the shared positive-fact compiler until their own grammar is
refined from live results.
4. **Platform verbalizer.** The existing enhancer receives the compiled scene and the structured plan. It may
express that plan in the target model's dialect but may not reinterpret it.
`behavior_transfer` covers cases such as an ocean that remains seawater but forms a stable lifted fold like heavy
fabric. The critic must preserve evidence of the original identity, add evidence of the borrowed behaviour, keep
the surface connected to its scene, and reject the likely normal readings (a handful of water, a splash, or a
literal textile prop).
Two live runs with Mistral Small 3.2 24B as critic and rewriter (`dev/logs/try_surreal_live_p1*.log`): in the first,
8 of 9 premises led with a visible physical fact (the ninth fell back to the code critic) and 7 of 9 came with an
edit instruction; in the second, after fixing the survival check, 9 of 9 survived the rewrite. The survival check
had keyed the judge's verdicts on the exact concept text and lost them whenever the judge echoed a concept slightly
differently, reporting '[none]' for anomalies that were plainly in the prompt.
## The test protocol for the two-operation limit
In the plan doc: ten subjects, one platform, counts 1, 2 and an uncapped control, four seeds each, scored blind
+147
View File
@@ -18,6 +18,118 @@ define the same name (the first folder wins, your pack replaces the shipped list
`python_embeded\python.exe custom_nodes\video_prompter\dev\scan_wildcard_packs.py` reports on
everything found: unreadable files, names defined twice, references to packs you do not have.
### Special folders inside a pack folder
```text
_nsfw/<pack>/... NSFW lists, rated explicit. Only a node whose nsfw is explicit uses them; there
they answer to their name without the _nsfw/ prefix. _nsfw/suggestive/<pack>/ and
_nsfw/nudity/<pack>/ rate a folder lower (see NSFW levels).
_generated/... lists written by the tools themselves. Always searched.
_prompts/<pack>/... whole prompts, one per line (see Prompt files). Answer only to prompts/... names.
_anything_else/ any other top-level folder starting with "_" is ignored
(_duplicates, _quarantine, _cleanup, ...).
```
Lists whose own name rates them (`nsfw_poses.txt`, `sex_act.txt`, a YAML key `clothes/nsfw`, `lingerie.txt`)
are gated by level wherever they sit (see NSFW levels). `__MACOSX`, `.git` and `._` fork files are always skipped.
Entries that pair minor-related and sexual terms are removed at load time in every folder, whatever
the nsfw level says. The same test runs on each finished prompt, where terms from different picks meet,
with explicit sexual terms only (nudity words alone do not count there): a roll that fails is
re-rolled with derived seeds when the picks caused it, and blanked with the reason in the report (or,
for an LLM's rewrite, in the console) when the typed text did or no re-roll passes. It is a plain
word match (no LLM, no VRAM), on by default; `config.json` -> `"wildcards": {"content_filter": false}`
turns both checks off. `<lora:...>` tags inside entries are removed at load time
(`config.json` -> `"wildcards": {"strip_lora": false}` keeps them).
### Renamed and dumped lists
The wildcard review (tools/wildcard_review) can rename a list you keep: a `.txt` is renamed in its folder, a key inside a
YAML / JSON file is written out as its own `.txt` (the old key hidden, the pack file untouched). The old name keeps
working: `_catalog_user.yaml` gets `aliases: {old name: new name}`, so saved workflows and templates still find it.
Its "Move dumped files" step moves dumped files to `_dumped/` (same paths; skipped like every other `_` folder).
Both write a manifest; `python tools/wildcard_review/server.py --undo <manifest>` puts things back. A list's `slot:`
in `_catalog_user.yaml` may name several Composer buttons (a list of ids).
### Prompt files (_prompts)
Lists whose entries are whole prompts live in `_prompts/`, keeping their pack and theme folders
(`dev/move_prompt_lists.py` moved them there; `--undo <manifest>` puts them back). They are their own area:
```text
__prompts/<pack>/<theme>/<file>__ one prompt from that file
__prompts/<pack>/<theme>/*__ one prompt from any file in that folder (and its subfolders)
__prompts/<pack>/<theme>__ the same: a folder name stands for everything in it
```
Nothing else reaches them: a bare name (`__forest__`), an ordinary glob (`__*/forest__`), the Composer's
buttons, More lists, Find and the catalog only ever see the normal lists, so a whole prompt can't land in a
Setting or Style pill. A YAML or JSON file under `_prompts/` is named with its folder in front
(`_prompts/pack/x.yaml` with key `mood/rain` -> `prompts/pack/mood/rain`); a file that is only a list (a JSON
array) is named after the file. `_prompts/_nsfw/...` is rated like `_nsfw/` and answers to `prompts/...`.
Stars, hide, drop and entry ratings work as for any list (saved under the `prompts/...` name).
### NSFW levels
Every node that resolves wildcards has an `nsfw` setting, the same levels as the LoRA cards and the LoRA Suggester:
| Setting | A run uses |
|---|---|
| off (default) | SFW only: no suggestive, nude or explicit lists or entries |
| suggestive | also lingerie, bikinis, underwear, "sexy", "seductive", cleavage ... |
| nudity | also nude, naked, topless, nipples ... |
| explicit | everything, including lists under `_nsfw/` |
off is its own category: to get suggestive content, set suggestive. Lists and entries are rated by a word match
(no LLM, no VRAM), and you can correct any rating:
- **A list** is rated by its folder (`_nsfw/` = explicit; `_nsfw/suggestive/` and `_nsfw/nudity/` rate a folder
lower; the level folder is not part of the name, so `_nsfw/nudity/pack/poses` answers to `__pack/poses__`), by its
name below the pack folder (`lingerie`, `underwear`, `bikini` -> suggestive; `nude`, `naked`, `topless` -> nudity;
`nsfw`, `sex`, `porn`, `fetish` -> explicit), or by the catalog finding explicit content. A list above the run's
level does not exist for lookups, globs, tag queries or slot buttons.
- **An entry** is rated by its words, so an SFW list can still hold a few suggestive entries and an off run leaves
just those out. Words that mean something else are exempt ("Garter Snake", "Naked Mole Rat", "nude pumps",
"a bottomless pit", "summa cum laude").
- **A reference** whose list, or every entry in it, is above the run's level is dropped from the prompt (like the
violence filter) and the report says `nsfw filter (off): __lingerie__ dropped ...`.
- **Your corrections** go in `_catalog_user.yaml` (see the Catalog section): `nsfw: <level>` on a list, `ratings:` on
single entries, or a top-level `ratings:` for an entry in every list. The Composer's list viewer writes both: the
*NSFW level* menu by the stars, and a small menu on every rated entry. Entries the node's level leaves out are
shown greyed.
The Wildcard Composer passes its level on in `sections`; the LoRA Suggester uses the lowest of what the prompt asks
for, its own `nsfw` setting and the Composer's level. `dev/nsfw_levels_dryrun.py` rates your whole library without
changing anything (report in `dev/logs/nsfw_levels_dryrun.md`, every rated entry in `dev/logs/nsfw_entry_ratings.csv`).
### Violence filter
Every node with `nsfw` also has `violence_filter`, right after it:
| Setting | Held back |
|---|---|
| off (default) | nothing |
| no gore | blood and gore, torture, mutilation, dismemberment, corpses |
| no gore or violent acts | also murder, massacre, execution, stabbing, strangling, suicide / self-harm |
| no violence or weapons | also guns, swords, knives, bombs, battle, war |
It works on wildcard picks: entries whose words fall in the chosen tier (or a lower one) are
skipped, and lists whose name says it (`gore`, `torture`, `violence`, `weapons`, `guns` ...) are
hidden, in the Composer's buttons too. A reference whose entries are all held back is dropped from
the prompt (`a knight holding __weapons__` -> `a knight holding`). Text you type is left as is.
Whatever either filter did (a re-roll, a blocked prompt, a dropped reference) is listed first in the
node's report, one `FILTER: ...` line each. A word match, no model; titles
and names that contain the words ("Corpse Bride") are held back with them.
### Which list a bare name means
`__pose__` is exact first. Inside a pack's own list, a reference resolves in that pack first, so a
template written as `__wildcards/quality__` finds its own pack's `wildcards/quality`. Otherwise
`__pose__` finds lists named `pose` in subfolders; when several packs have one, ONE pack is used
(the highest-priority folder, then the shortest path) and the report names the others. Lists of
different packs are never mixed by accident. To pool on purpose, write `__**/pose__`.
`config.json` -> `"wildcards": {"pool_mode": "legacy"}` restores the old pool-everything lookup.
## Syntax
```text
@@ -27,6 +139,7 @@ __painters__ depth-agnostic: finds style/painters if no top-
__materials__ a folder name stands for everything inside it (same as __materials/**__)
__camera/**__ any list under a folder
__colors*__ glob on the name
__expression!{furious|sad}__ any entry except these (case-insensitive; markers go first: __=name!{a}__)
{red|green|blue} variant: one of these
{3::common|1::rare} weights
@@ -74,6 +187,37 @@ Verbatim picks are checked in the LLM's answer and added back if it dropped them
`wildcard_llm_block` toggle on each node turns the block off, in which case the LLM only sees the
resolved text.
## The catalog and your curation
The first time a node uses wildcards, a background thread indexes every list into
`_catalog.sqlite` in each wildcard folder (the package's own lists index into `cache/catalogs/`).
Later starts only look at files that changed. For each list it records what kind of list it is
(single items, phrases, full prompts, templates, booru tags), a quality score (clean, short, varied
entries score high; quality boilerplate, weight syntax, broken characters and tiny lists score low),
lists with identical content in other packs, and NSFW found by content: a list full of explicit
words is rated explicit, like one under `_nsfw/`, wherever it sits.
Your own judgement goes in `_catalog_user.yaml` next to the lists. The Wildcard Prompt Composer's list viewer
writes it (stars, Hide list, drop an entry); you can also edit it by hand:
```yaml
lists:
"mrweazsfwildcardssfw_v30glamour/hair_colors":
stars: 5 # ranks it first for slot buttons and ambiguous names
"cushyswildcard_v6/pose":
hidden: true # never used by a bare name, a glob or a slot; __its/exact/name__ still works
"thepromptbuilder_v21ponyillustrious/face_expression":
drop: [Sarcasm, Smug] # these entries are never picked
"some_pack/camera":
nsfw: off # the list's NSFW level, overrides folder / name / content (off | suggestive | nudity | explicit)
ratings: {lace boyshorts: off} # one entry's level in this list (overrides its words)
ratings: # an entry's level in every list
Naked Mole Rat: off
```
When a bare `__name__` matches lists in several packs, the pack with your stars (else the best
quality score) is used. Turn the whole thing off with `"wildcards": {"catalog": false}` in config.json.
## Seeds
`wildcard_seed` on every enhancer: `-1` rolls fresh picks on every run, `0` or more is reproducible
@@ -103,6 +247,9 @@ axis bites on a given list.
shows the phrase in the rewritten prompt that carries it and a similarity score, and for verbatim
picks whether the exact words are there. `all_survived` can gate a retry.
**Wildcard Character Composer** (and later Scene / Style builders) writes a prompt section with slot buttons
instead of typed syntax; see [PROMPT_BUILDER_GUIDE.md](PROMPT_BUILDER_GUIDE.md).
Resolving upstream: when a Wildcard Processor or Semantic Variation node does the picking, connect
its `text` to the enhancer's prompt and its `llm_instructions` to the enhancer's
`wildcard_instructions` input. The enhancer then treats those picks exactly like its own.