Files
ComfyUI-Ethanfel-Prompt-Bui…/docs/prompt-pool-routing-map.md
T
2026-06-26 12:03:46 +02:00

453 lines
19 KiB
Markdown

# Prompt Pool Routing Map
This document maps the roads that can lead to prompt text. It intentionally does
not duplicate every prompt phrase in the JSON pools. The useful debugging target
is usually: which node path selected which pool, which seed axis controlled it,
and whether the final wording was still raw builder text or rewritten by a
formatter.
## Mental Model
There are three layers:
1. Generation layer: selects category, subcategory, item/action, character
descriptors, scene, expression, pose, composition, and camera directives.
2. Pair/adapter layer: optionally builds a softcore/hardcore pair, applies
continuity, POV handling, camera-aware scene text, and clothing state.
3. Formatter layer: rewrites a metadata row into Krea2 prose, SDXL tags, or a
naturalized caption.
When a result is wrong, first identify which layer owns the bad text:
- Raw builder prompt already wrong: edit `prompt_builder.py` or the relevant
`categories/*.json` pool/template.
- Raw builder prompt acceptable, Krea2 output wrong: edit `krea_formatter.py`.
- Raw builder prompt acceptable, SDXL tags wrong: edit `sdxl_formatter.py`.
- Natural caption/training caption wrong: edit `caption_naturalizer.py`.
- UI/preview/loop behavior wrong: edit `__init__.py`, `loop_nodes.py`, or
`web/*.js`.
## High-Level Routes
```mermaid
flowchart TD
A[SxCP Prompt Builder] --> B[prompt_builder.build_prompt]
C[SxCP Prompt Builder From Configs] --> D[parse config nodes]
D --> B
E[SxCP Insta/OF Prompt Pair] --> F[prompt_builder.build_insta_of_pair]
F --> B
B --> R[metadata row + prompt + negative + caption]
F --> P[pair metadata: soft row + hard row]
R --> K[SxCP Krea2 Formatter]
R --> S[SxCP SDXL Formatter]
R --> N[SxCP Caption Naturalizer]
P --> K
P --> S
P --> N
```
The config nodes mostly emit JSON. The final builder nodes parse that JSON and
call the same core generation functions.
## Main Entry Points
| ComfyUI node | Python entry | What it owns |
| --- | --- | --- |
| `SxCP Prompt Builder` | `build_prompt` | Direct single prompt generation. Can use built-in categories or JSON categories. |
| `SxCP Prompt Builder From Configs` | `build_prompt_from_configs` -> `build_prompt` | Same generator, but inputs come from category/cast/profile/filter helper nodes. |
| `SxCP Insta/OF Prompt Pair` | `build_insta_of_pair` | Builds a softcore row and hardcore row with shared cast/continuity options. |
| `SxCP Krea2 Formatter` | `format_krea2_prompt` | Converts metadata rows or pair metadata into Krea2-friendly prose. |
| `SxCP SDXL Formatter` | `format_sdxl_prompt` | Converts metadata rows or pair metadata into SDXL/tag style prompts. |
| `SxCP Caption Naturalizer` | `naturalize_caption` | Converts rows into more natural sentence captions. |
## Seed Axes
Seed routing is centralized around `SEED_AXIS_SALTS`, `SEED_AXIS_ALIASES`, and
`_axis_rng` in `prompt_builder.py`.
| Axis | Controls |
| --- | --- |
| `category` | Main category selection when random/auto. |
| `subcategory` | Subcategory selection. |
| `content` | Clothing item, category item, generated outfit, many softcore outfit choices. |
| `person` | Character appearance when not fully manual. |
| `scene` | Location/scene choice. |
| `pose` | Generic pose choice, and for pose-content categories, the hardcore position/action item. |
| `role` | Role graph / action choreography for sexual pose categories. Falls back through pose aliases. |
| `expression` | Expression choice and expression intensity randomization. |
| `composition` | Composition/framing choice. |
`SxCP Global Seed`, `SxCP Seed Control`, and `SxCP Seed Locker` all feed
`seed_config`. Values below zero mean the row's main seed still drives that
axis. Fixed axis seeds allow changing only one road, for example changing
`pose`/`role` while keeping person, scene, and category stable.
## Category Sources
There are two category systems.
| Source | Files/functions | Notes |
| --- | --- | --- |
| Built-in legacy generator | `generate_prompt_batches.py`, `_build_direct_builtin_row`, `_build_auto_weighted_row` | Handles legacy `woman`, `man`, `couple`, `group_or_layout`, `auto_weighted`, and `auto_full`. |
| JSON category library | `categories/*.json`, `load_category_library`, `_build_custom_row` | Handles expandable categories such as casual clothes, erotic clothes, and hardcore sexual poses. |
JSON categories are the scalable system. Add new main categories or subcategories
there unless the behavior needs Python logic.
## JSON Category Road
```mermaid
flowchart TD
A[category/subcategory input] --> B[_find_subcategory]
B --> C[item from subcategory.items]
C --> D[_compose_item]
D --> E[item_templates + axes]
B --> F[_scene_pool]
B --> G[_expression_pool]
B --> H[_pose_pool]
B --> I[_composition_pool]
E --> J[role graph / item text / axis values]
F --> R[scene_text]
G --> R
H --> R
I --> R
J --> R[metadata row]
```
Important JSON keys:
- `categories`: main category definitions.
- `subcategories`: selectable subcategories inside a category.
- `items`: item/action entries selected by the content or pose axis.
- `item_templates`: templates with axis placeholders.
- `axes`: values used to fill `item_templates`.
- `scene_pool` / `scene_pools` or direct `scenes`: location road.
- `expression_pool` / `expression_pools` or direct `expressions`: expression road.
- `composition_pool` / `composition_pools` or direct `compositions`: framing road.
- `poses`: category-specific pose fallback.
- `prompt_template` / `caption_template`: final prompt assembly for that category.
- `inherit_scenes`, `inherit_expressions`, `inherit_compositions`: stop or allow
inheritance from category/subcategory/item levels.
- `pool_extensions`: patch legacy pools from JSON.
Current category/pool files:
| File | Main ownership |
| --- | --- |
| `categories/default_categories.json` | Casual clothes, men/couple casual variants, normal JSON categories. |
| `categories/erotic_clothes.json` | Provocative/erotic clothing categories and their scene/expression/composition pools. |
| `categories/sexual_poses.json` | Hardcore sexual pose/action categories, role graphs, explicit scene/expression/composition pools. |
| `categories/location_pools.json` | Named scene pools and location pool extensions. |
| `categories/expression_composition_pools.json` | Named expression pools and composition pools. |
## Pool Resolution
### Scene / Location
Scene text is selected by `_scene_pool`.
Resolution order:
1. `SxCP Location Pool` / `SxCP Location Theme` with `replace` overrides the
category scene pool.
2. Category/subcategory/item direct `scenes` and referenced scene pools are
merged, unless inheritance is disabled.
3. `SxCP Location Pool` with `add` appends its entries.
4. Fallback is legacy `g.SCENES` or `g.GROUP_SCENES`.
Edit targets:
- Add reusable named locations: `categories/location_pools.json`.
- Add category-specific locations: the category JSON file.
- Add quick workflow-only locations: `SxCP Location Pool` custom locations.
- Add themed location packs: `THEMATIC_LOCATION_PRESETS` in `prompt_builder.py`.
### Expression
Expression text is selected by `_expression_pool`, then filtered by
`_expression_entries_for_intensity`.
Resolution order:
1. Category/subcategory/item direct `expressions` and named expression pools.
2. Inheritance can stop at item or subcategory level.
3. Fallback is legacy `g.EXPRESSIONS`.
4. Character slots can override intensity per softcore/hardcore phase.
5. Expression can be disabled globally or per character slot.
Edit targets:
- General expression pools: `categories/expression_composition_pools.json`.
- Hardcore-specific expressions: usually `categories/sexual_poses.json` or named
hardcore expression pools.
- Character-level expression settings: slot config and `_cast_expression_intensity_override`.
- Formatter expression wording: `krea_formatter.py` or `caption_naturalizer.py`.
### Pose / Action
Generic pose text is selected by `_pose_pool`. Hardcore sexual pose categories
are different: the sexual position/action is an item/template selected by the
content route, with `content_seed_axis` set to `pose` for pose-content
categories.
Edit targets:
- Normal pose pools: legacy `g.POSES`, `g.EVOCATIVE_POSES`, or JSON `poses`.
- Hardcore positions/actions: `categories/sexual_poses.json`.
- Position filtering UI: `build_hardcore_position_pool_json`,
`build_hardcore_action_filter_json`, `_apply_hardcore_position_config_to_subcategory`.
- Krea2 action rewrite, POV position rewrite, cleanup: `krea_formatter.py`.
### Composition
Composition text is selected by `_composition_pool`.
Resolution order:
1. `SxCP Composition Pool` / `SxCP Location Theme` with `replace` overrides the
category composition pool.
2. Category/subcategory/item direct `compositions` and named composition pools
are merged.
3. `SxCP Composition Pool` with `add` appends entries.
4. Fallback is legacy `g.COMPOSITIONS` or `g.GROUP_COMPOSITIONS`.
Edit targets:
- General composition pools: `categories/expression_composition_pools.json`.
- Category-specific composition pools: relevant category JSON.
- Workflow overrides: `SxCP Composition Pool`.
- Camera-aware composition replacements: `_coworking_composition_prompt`.
## Character Route
```mermaid
flowchart TD
A[Woman/Man/Character Slot chain] --> B[character_cast JSON]
C[Profile Load] --> D[character_profile JSON]
E[Manual Details / Hair / Body / Age / Eyes / Clothing nodes] --> A
B --> F[_parse_character_cast]
F --> G[_character_slot_label_map]
G --> H[_context_from_character_slot]
H --> R[cast descriptors + slot clothing + expression settings]
D --> I[_apply_character_profile_to_context]
I --> R
```
Important behavior:
- Slot chaining labels the closest slot to the final node as `A` for that gender,
then upstream slots as `B`, `C`, and so on.
- `character_cast` is for multi-character configured casts. `character_profile`
is for reusable primary-character details.
- `SxCP Character Manual Details` and characteristic pool nodes can feed slots.
- `SxCP Character Clothing` can feed `softcore_outfit` and `hardcore_clothing`.
- A man slot can be marked as POV. POV men are omitted from visible cast
descriptors, and camera wording is adapted to first-person view.
Edit targets:
- Appearance field generation: `_context_from_character_slot`,
`_character_context_for_label`, `_cast_descriptor_entries`.
- Profile save/load: `SxCPCharacterProfileSave`,
`SxCPCharacterProfileLoad`, profile helpers in `prompt_builder.py`, and
`web/profile_buttons.js`.
- Hair/body/ethnicity list behavior: characteristic config builders in
`prompt_builder.py`.
## Insta/OF Pair Route
```mermaid
flowchart TD
O[SxCP Insta/OF Options] --> P[build_insta_of_pair]
C[character_cast] --> P
S[seed_config] --> P
L[location_config] --> P
M[composition_config] --> P
H[hardcore_position_config] --> P
P --> A[soft_row via build_prompt]
P --> B[hard_row via build_prompt]
A --> X[pair metadata]
B --> X
X --> K[Krea2/SDXL/Naturalizer]
```
Softcore row:
- Category comes from `INSTA_OF_SOFTCORE_SUBCATEGORY_BY_LEVEL`.
- Outfit comes from character slot `softcore_outfit` if present, otherwise
`INSTA_OF_SOFTCORE_OUTFITS`.
- Soft pose comes from `INSTA_OF_SOFTCORE_POSES`.
- Partner styling comes from `_insta_of_partner_styling` when softcore cast is
`same_as_hardcore`.
Hardcore row:
- Category is always `Hardcore sexual poses`.
- Cast count comes from `SxCP Insta/OF Options`.
- Position/action can be constrained by `SxCP Hardcore Position Pool` and
`SxCP Hardcore Action Filter`.
- Clothing comes from character slot hardcore clothing first, then fallback
`hardcore_clothing_continuity`.
- Men receive default hardcore clothing if visible and not configured.
- POV labels alter action, camera, composition, and visible cast descriptors.
Continuity:
- `same_creator_same_room` reuses the softcore scene for hardcore.
- `same_creator_new_scene` lets hardcore use its own scene.
- Shared cast descriptors are stored in pair metadata and consumed by formatters.
## Hardcore Position Route
`SxCP Hardcore Position Pool` and `SxCP Hardcore Action Filter` both emit
`hardcore_position_config`.
```mermaid
flowchart TD
A[Hardcore Position Pool] --> C[hardcore_position_config]
B[Hardcore Action Filter] --> C
C --> D[_filter_hardcore_categories_for_position]
C --> E[_apply_hardcore_position_config_to_subcategory]
E --> F[item_templates / axes in sexual_poses.json]
F --> G[role_graph + item + axis_values]
G --> H[Krea2 action sentence and POV rewrite]
```
What each part owns:
- `sexual_poses.json`: available positions, families, action templates, role
graph templates, and action-specific pool references.
- `prompt_builder.py`: filters which templates/axes remain available.
- `krea_formatter.py`: rewrites the selected action into model-readable prose,
including POV variants and cleanup.
If one action keeps recurring, inspect:
1. The enabled position family/action flags.
2. `weight` values in `sexual_poses.json`.
3. Whether the selected subcategory has only a small compatible set after
filtering.
4. Whether the formatter collapses several raw actions into the same final
wording.
## Camera And Scene Route
Camera config nodes:
- `SxCP Camera Control`: direct camera settings.
- `SxCP Camera Orbit Control`: orbit-like camera settings.
- `SxCP Qwen Camera Translator`: converts qwen multi-angle info into
`camera_config`.
Camera handling:
1. Camera nodes emit `camera_config`.
2. `build_prompt` calls `_apply_camera_config`.
3. `_camera_directive` creates a plain camera sentence unless disabled/off.
4. `_camera_scene_directive_for_context` can add location-aware camera text.
5. POV rows suppress the normal camera directive and use first-person camera
wording instead.
Current camera-aware scene adapter:
- Coworking/business-cafe/office scenes are detected by `_is_coworking_scene`.
- Location profile comes from `_coworking_location_profile`.
- Direction, distance, and elevation details come from `_coworking_direction_detail`,
`_coworking_distance_detail`, and `_coworking_elevation_detail`.
- Composition cleanup for coworking outfit-check wording happens in
`_coworking_composition_prompt`.
Important POV rule:
- In POV rows, location anchors must stay behind, beside, or at the frame edges.
The foreground belongs to the POV body/hands and visible partner/action.
## Formatter Routes
### Krea2
`format_krea2_prompt` chooses between three roads:
- Pair metadata: `_insta_pair_to_krea`.
- Normal metadata row: `_normal_row_to_krea`.
- Plain text fallback: `_fallback_text_to_krea`.
Key Krea2 ownership:
- Cast descriptor naturalization: `_cast_prose`, `_natural_label_text`.
- Hardcore action sentence: `_hardcore_action_sentence`.
- POV hardcore sentence: `_pov_hardcore_pose_sentence`, `_pov_action_phrase`.
- Clothing state cleanup: `_natural_clothing_state`.
- Camera scene preservation: `_camera_scene_phrase`.
### SDXL
`format_sdxl_prompt` chooses between:
- Pair metadata: `_soft_tags` and `_hard_tags`.
- Normal metadata row: `_row_core_tags`.
- Plain text fallback: `_fallback_text_to_sdxl`.
Use this route for style triggers, weighted tag style, nude weighting, and Pony /
SDXL quality/style presets.
### Naturalizer
`naturalize_caption` chooses metadata-specific renderers such as
`_configured_cast_from_row`, `_couple_from_row`, and single/group renderers.
Use this route when the row metadata is correct but the sentence-style caption is
too mechanical or unsuitable for training captions.
## Utility / Workflow Nodes
These do not own prompt pool wording, but they affect execution and review:
| Node family | Files | Purpose |
| --- | --- | --- |
| Loop nodes | `loop_nodes.py`, `web/loop_slots.js` | While/for loop execution and carry values. |
| Index switch | `loop_nodes.py`, `web/index_switch_slots.js` | Multi-input to selected output, and selected input to multi-output routing. |
| Accumulator | `loop_nodes.py`, `web/accumulator_preview.js` | Stores generated values/images during workflow execution and previews/reorders/deletes them. |
| Persistent text preview | `loop_nodes.py`, `web/preview_any_text.js` | Stores any value as text and keeps it after workflow reload. |
| SDXL bucket size | `SxCPSDXLBucketSize` in `__init__.py` | Random/fixed SDXL bucket width and height selection. |
## Editing Cheatsheet
| Symptom | First file/function to inspect |
| --- | --- |
| Wrong main category/subcategory frequency | Category node config, `load_category_library`, category JSON weights. |
| Wrong outfit/clothing item | Relevant category JSON, `INSTA_OF_SOFTCORE_OUTFITS`, `SxCP Character Clothing`. |
| Nude/clothing state confusing Krea2 | `build_insta_of_pair` clothing state helpers, then `_natural_clothing_state`. |
| Wrong location | `categories/location_pools.json`, category `scene_pool`, `_scene_pool`. |
| Location good but camera/location layout wrong | `_camera_scene_directive_for_context`, coworking adapter functions. |
| Repeated desk/anchor in POV foreground | Coworking direction/distance/elevation helpers. |
| Wrong expression intensity | Character slot expression settings, `_expression_entries_for_intensity`, expression pools. |
| Expression appears when disabled | `_disable_row_expression`, formatter expression extraction. |
| Same hardcore action repeats | Hardcore filter config, `sexual_poses.json` weights, `_apply_hardcore_position_config_to_subcategory`. |
| Raw hardcore prompt position is vague | `sexual_poses.json` item templates and role graph templates. |
| Krea2 hardcore prompt position is vague | `_hardcore_action_sentence` or `_pov_hardcore_pose_sentence`. |
| Man appears described in POV | POV labels, `_cast_prose` omit labels, `_pov_action_phrase`. |
| Camera prompt missing from Krea2 | Row `camera_directive` / `camera_scene_directive`, then Krea `_camera_phrase`. |
| Trigger missing in Krea2 fallback | `format_krea2_prompt` preserve-trigger fallback behavior. |
| SDXL tags too weak/wrong style | `sdxl_formatter.py` presets and `_row_core_tags` / `_soft_tags` / `_hard_tags`. |
| Saved profile does not match liked character | Profile save/load path and whether the saved input is row metadata or regenerated slot config. |
| Accumulator preview behavior wrong | `loop_nodes.py` accumulator methods and `web/accumulator_preview.js`. |
## Safe Edit Workflow
Before changing prompt behavior:
1. Capture one raw builder output and the formatter output.
2. Check metadata JSON for `source`, `main_category`, `subcategory`,
`content_seed_axis`, `scene_text`, `item`, `role_graph`, `source_role_graph`,
`item_axis_values`, `composition`, `camera_scene_directive`, and
`pov_character_labels`.
3. Decide whether the bug is selection, raw wording, camera adaptation, or
formatter rewrite.
4. Edit the smallest owning pool/template/function.
5. Re-run a small simulation with fixed person/scene/category seeds and only the
target axis varied.
The repo may have unrelated dirty files during interactive prompt work. Always
stage only the intended files for commits.