Files
ComfyUI-Ethanfel-Prompt-Bui…/README.md
T

316 lines
10 KiB
Markdown

# ComfyUI Prompt Builder
Custom ComfyUI node for building prompts from the existing `generate_prompt_batches.py`
generator without writing image batches.
The node is registered as:
- `prompt_builder / SxCP Prompt Builder`
- `prompt_builder / SxCP Seed Control`
- `prompt_builder / SxCP Caption Naturalizer`
- `prompt_builder / SxCP Insta/OF Options`
- `prompt_builder / SxCP Insta/OF Prompt Pair`
It outputs:
- `prompt`
- `negative_prompt`
- `caption`
- `metadata_json`
- `category`
- `subcategory`
`SxCP Seed Control` outputs `seed_config`, which can be connected to the prompt
builder's optional `seed_config` input.
`SxCP Caption Naturalizer` rewrites tag-like captions or labeled prompts into
more natural language. Connect the prompt builder's `metadata_json` output to
`source_text` for the cleanest result. You can also connect `caption` or
`prompt`; in that case the node falls back to prompt-label parsing or comma-tag
cleanup.
Naturalizer controls:
- `input_hint`: `auto`, `metadata_json`, or `caption_or_prompt`.
- `detail_level`: `concise`, `balanced`, or `dense`.
- `style_policy`: `drop_style_tail` removes old fixed style tails; `keep_style_terms`
keeps style descriptions in the rewritten text.
- `trigger`: defaults to `sxcppnl7`.
- `include_trigger`: prepends the trigger as its own sentence.
It outputs:
- `natural_caption`
- `method`
`SxCP Insta/OF Prompt Pair` is a special paired-output mode. It creates one
shared primary creator descriptor, then returns both a softcore prompt and a
hardcore prompt from that same descriptor. This is useful when you want the same
person/look/scene continuity but need two different prompt strengths.
It outputs:
- `softcore_prompt`
- `hardcore_prompt`
- `softcore_negative_prompt`
- `hardcore_negative_prompt`
- `softcore_caption`
- `hardcore_caption`
- `shared_descriptor`
- `metadata_json`
`SxCP Insta/OF Options` outputs `options_json`, which can be connected to the
pair node. Defaults are set so the softcore prompt is solo while the hardcore
prompt can include partners.
Options:
- `softcore_cast`: `solo` or `same_as_hardcore`.
- `hardcore_cast`: `use_counts`, `couple`, `threesome`, or `group`.
- `hardcore_women_count` and `hardcore_men_count`: used when `hardcore_cast` is
`use_counts`. The pair mode always keeps at least one adult woman as the
primary creator so the shared descriptor remains valid.
- `softcore_level`: `social_tease`, `lingerie_tease`, `implied_nude`, or
`explicit_tease`.
- `hardcore_level`: `explicit` or `hardcore`.
- `platform_style`: `hybrid`, `instagram`, or `onlyfans`.
- `continuity`: `same_creator_same_room` keeps the scene/composition aligned;
`same_creator_new_scene` keeps the same creator descriptor but lets the
hardcore scene use its own setting.
## Built-In Categories
The node keeps the original generator controls:
- `category`: `auto_weighted`, `woman`, `man`, `couple`, `group_or_layout`, or a custom JSON category.
- `clothing`: `full` or `minimal`.
- `minimal_clothing_ratio`: `-1` disables mixing; `0.0` to `1.0` mixes minimal/full clothing.
- `ethnicity`: `any`, `asian`, `white_asian`.
- `poses`: `standard` or `evocative`.
- `standard_pose_ratio`: `-1` disables mixing; `0.0` to `1.0` mixes standard/evocative poses.
- `backside_bias`: `0.0` to `1.0`, applies to evocative single-subject poses.
- `figure`: `curvy`, `balanced`, `bombshell`.
- `no_plus_women`: excludes plus-size women.
- `no_black`: excludes Black/African-coded women from women-focused pools.
`auto_weighted` uses the original batch mix: mostly women, then men, couples, and
group/layout rows. Direct categories generate only that selected category.
## Custom Categories
Add or edit JSON files in `categories/*.json`. Each file can define new main
categories, subcategories, and optional extensions to the built-in pools. Restart
or reload ComfyUI after changing JSON so dropdown choices are rebuilt.
Included JSON categories:
- `Casual clothes`
- `Provocative erotic clothes`
- `Hardcore sexual poses`
Example:
```json
{
"version": 1,
"categories": [
{
"name": "Casual clothes",
"slug": "casual_clothes",
"subject_type": "woman",
"item_label": "Clothing",
"style": "tasteful adult fashion-editorial coloured-pencil comic illustration",
"subcategories": [
{
"name": "Streetwear",
"slug": "streetwear",
"items": [
"oversized hoodie with slim jeans and clean sneakers",
"cropped bomber jacket with cargo pants and chunky trainers"
],
"scenes": [
{
"slug": "city_crosswalk",
"prompt": "sunlit city crosswalk with storefront reflections"
}
],
"poses": [
"standing with one hand in a pocket",
"walking forward with a casual runway stride"
]
}
]
}
]
}
```
Custom categories do not need a Python generator. If no `prompt_template` is
provided, the node uses a generic composer that selects subject appearance,
scene, pose, expression, composition, and a random item from the selected
subcategory.
For large categories, prefer `item_templates` plus `item_axes` instead of writing
every final item by hand:
```json
{
"name": "Example clothes",
"subject_type": "woman",
"subcategories": [
{
"name": "Lingerie",
"item_templates": [
"{color} {fabric} {top} with {bottom} and {stockings}"
],
"item_axes": {
"color": ["black", "red", "ivory"],
"fabric": ["lace", "satin", "transparent mesh"],
"top": ["balconette bra", "open-cup bra"],
"bottom": ["matching thong", "high-cut g-string"],
"stockings": ["thigh-high stockings", "fishnet stockings"]
}
}
]
}
```
The node chooses one template, fills each placeholder from the matching axis,
then records the selected axis values in `metadata_json`.
Supported `subject_type` values:
- `single_any`
- `woman`
- `man`
- `couple`
- `group`
- `layout`
- `scene`
- `configured_cast`
`configured_cast` uses the node's `women_count` and `men_count` inputs. It adds
template fields for `{women_count}`, `{men_count}`, `{person_count}`,
`{cast_summary}`, `{scene_kind}`, and `{role_graph}`. This is intended for
categories where the same prompt generator should support couples, threesomes,
and larger groups.
`{role_graph}` is a generated choreography sentence that assigns roles to the
cast, such as who penetrates, who receives oral, and who joins from the side.
It is currently most useful for `Hardcore sexual poses`.
Subcategories, templates, and axis values can declare cast constraints:
```json
{
"name": "Threesomes",
"min_people": 3,
"item_axes": {
"act": [
{
"text": "strap-on penetration and cunnilingus",
"cast": "women_only"
},
{
"text": "male/male oral and anal contact",
"cast": "men_only"
},
{
"text": "front-and-back penetration",
"cast": "mixed"
}
]
}
}
```
Supported constraints:
- `min_women`, `max_women`
- `min_men`, `max_men`
- `min_people`, `max_people`
- `cast` or `requires`: `women_only`, `men_only`, `mixed`, `has_women`,
`has_men`, `solo`, `couple`, `threesome`, `group`
If an exact subcategory is not compatible with `women_count` and `men_count`,
the node raises a clear error instead of generating an impossible prompt.
Use the `subcategory` dropdown to select either `random` or an exact
`Main category / Subcategory` path. Exact paths override the `category` dropdown,
which is useful because ComfyUI does not provide dependent dropdowns from Python
alone.
## Seed Control
The main `seed` input is still the default master seed. Connect `SxCP Seed
Control` to `seed_config` when you want to lock or vary specific axes.
Seed values:
- `-1`: follow the main seed.
- `0` or higher: override only that axis.
Axes:
- `category_seed`: custom category selection when `custom_random` is used.
- `subcategory_seed`: random subcategory selection.
- `content_seed`: generated item content, such as outfit wording.
- `person_seed`: appearance/person selection.
- `scene_seed`: scene/environment selection.
- `pose_seed`: body pose selection. For `Hardcore sexual poses`, this also drives the generated sexual pose content.
- `role_seed`: participant choreography for `{role_graph}`. If left at `-1`, it follows `pose_seed`.
- `expression_seed`: facial expression selection.
- `composition_seed`: camera/composition selection.
Example workflow: if the person and scene are right but the pose is wrong, keep
`person_seed` and `scene_seed` fixed, then change `pose_seed`. If the cast roles
are wrong but the act wording is good, change `role_seed`. If the clothing or
sexual act wording is wrong, change `content_seed`; for pose-driven categories,
change `pose_seed`.
## Pool Extensions
Use `pool_extensions` to add new entries to built-in pools without editing
Python:
```json
{
"pool_extensions": {
"women_clothes": ["relaxed high-waist jeans with a fitted ribbed tank top"],
"men_clothes": ["clean white T-shirt with relaxed jeans and canvas sneakers"],
"poses": ["standing with a relaxed hand-on-hip pose"],
"expressions": ["easygoing half-smile"],
"scenes": [
{
"slug": "city_cafe",
"prompt": "quiet city cafe terrace with morning light and small round tables"
}
]
}
}
```
Known extension pools:
`women_clothes`, `women_clothes_minimal`, `men_clothes`, `men_clothes_minimal`,
`couple_outfits`, `couple_outfits_minimal`, `poses`, `evocative_poses`,
`backside_poses`, `expressions`, `compositions`, `props`, `figure_curvy`,
`figure_athletic`, `figure_bombshell`, `scenes`, `group_scenes`,
`layouts_full`, `layouts_minimal`, `group_compositions`, `group_ages`.
## Templates
A category, subcategory, or individual item can provide `prompt_template` and
`caption_template`. Templates can use these fields:
`{trigger}`, `{main_category}`, `{subcategory}`, `{item}`, `{item_label}`,
`{subject}`, `{subject_phrase}`, `{age}`, `{body}`, `{body_phrase}`, `{skin}`,
`{hair}`, `{eyes}`, `{figure}`, `{scene}`, `{pose}`, `{expression}`,
`{composition}`, `{style}`, `{positive_suffix}`, `{negative_prompt}`,
`{women_count}`, `{men_count}`, `{person_count}`, `{cast_summary}`,
`{scene_kind}`, `{role_graph}`.
If `prepend_trigger_to_prompt` is enabled, the node prepends the trigger to the
positive prompt. Disable it for output closer to the original script's `prompt`
field.