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

19 KiB

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

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

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

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

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.

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.