Move pair detail density policy
This commit is contained in:
@@ -214,8 +214,9 @@ Already isolated:
|
||||
|
||||
- Insta/OF option normalization, softcore category/outfit/pose pools, partner
|
||||
outfit pools, clothing-continuity labels, negatives, and hardcore cast count
|
||||
policy live in `pair_options.py`; `prompt_builder.py` keeps public delegate
|
||||
wrappers for existing nodes and tests.
|
||||
policy, plus hardcore detail-density directive text, live in
|
||||
`pair_options.py`; `prompt_builder.py` keeps public delegate wrappers for
|
||||
existing nodes and tests.
|
||||
- soft/hard row creation lives in `pair_rows.py`, including softcore expression
|
||||
override resolution, Woman A slot context application, soft outfit/pose
|
||||
overrides, POV row fields, and hardcore row creation.
|
||||
|
||||
@@ -79,7 +79,7 @@ Core helper ownership:
|
||||
| `location_config.py` | Location/composition preset schemas, themed location packs, custom location/composition parsing, pool merge behavior, and location/composition config parsing. |
|
||||
| `row_location.py` | Built-in row location/composition config application, deterministic scene/composition choice, source metadata, and legacy prompt/caption rewrites. |
|
||||
| `hardcore_position_config.py` | Hardcore position/action-filter choices, selected-position normalization, config JSON builders/parsers, focus-policy toggles, subcategory allow-list policy, position-key detection, and category/template/axis filtering. |
|
||||
| `pair_options.py` | Insta/OF option schema/defaults, softcore category/outfit/pose pools, partner outfit pools, clothing-continuity labels, negatives, and hardcore cast count policy. |
|
||||
| `pair_options.py` | Insta/OF option schema/defaults, softcore category/outfit/pose pools, partner outfit pools, clothing-continuity labels, negatives, hardcore cast count policy, and hardcore detail-density directives. |
|
||||
| `pair_rows.py` | Insta/OF soft/hard row creation, softcore expression override resolution, Woman A slot context application, soft outfit/pose overrides, and POV row fields. |
|
||||
| `pair_camera.py` | Insta/OF soft/hard camera route resolution, same-as-softcore camera mode, camera-detail override, camera-aware composition mutation, POV camera suppression, and synchronized row/root camera metadata. |
|
||||
| `pair_clothing.py` | Insta/OF hardcore clothing continuity, action-aware body-access flags, conflicting outfit-piece cleanup, default visible-men clothing, and final root clothing-state assembly. |
|
||||
@@ -261,7 +261,7 @@ This table is the first stop when the selected content is wrong.
|
||||
| `sexual_poses.json` foreplay/interaction/manual/oral/outercourse/penetration/etc. | Hardcore action and porn-scene interaction templates, role graphs, axis values, hardcore pool references | `pose` for pose-content route, also `role`; sometimes `content` aliases matter | High because Krea2 rewrites action and POV position text |
|
||||
| `location_pools.json` | Reusable scene pools and legacy scene extensions | `scene` | Medium when a camera-aware adapter changes scene/composition wording |
|
||||
| `expression_composition_pools.json` | Reusable expressions and framing/composition pools | `expression`, `composition` | Medium because formatter may label or suppress expressions |
|
||||
| `pair_options.py` | Insta/OF option defaults, softcore level-to-category mapping, creator outfit/pose pools, partner outfit pools, negatives, and hard cast count policy | Options node plus `content`/`pose` axes inside pair route | Medium because pair route pools must remain consistent with Krea/SDXL pair formatting |
|
||||
| `pair_options.py` | Insta/OF option defaults, softcore level-to-category mapping, creator outfit/pose pools, partner outfit pools, negatives, hard cast count policy, and hardcore detail-density directives | Options node plus `content`/`pose` axes inside pair route | Medium because pair route pools must remain consistent with Krea/SDXL pair formatting |
|
||||
| `generate_prompt_batches.py` legacy pools | Built-in generator clothing, pose, expression, scene, composition lists | Main row seed plus axis config through legacy adapter | Medium because legacy prompt format is field-label heavy |
|
||||
|
||||
When adding a new pool, choose JSON when the change is pure selectable wording.
|
||||
@@ -503,7 +503,7 @@ plain prompt text. When debugging, inspect these fields before editing pools.
|
||||
| `character_hardcore_clothing` | Character slots | Krea pair branch | Explicit per-character hardcore clothing state. |
|
||||
| `default_man_hardcore_clothing` | Pair fallback | Krea pair branch | Auto clothing for visible men without configured clothing. |
|
||||
| `hardcore_clothing_state` | Pair clothing continuity | Krea/SDXL pair branch | Final hard clothing/body exposure sentence before Krea cleanup. |
|
||||
| `hardcore_detail_density` | Insta/OF options | Krea hardcore action rewrite | Controls compact/balanced/dense action detail. |
|
||||
| `hardcore_detail_density` | Insta/OF options via `pair_options.py` | Krea hardcore action rewrite | Controls compact/balanced/dense action detail directives. |
|
||||
| `softcore_camera_config`, `hardcore_camera_config` | Pair camera route | Krea/SDXL pair branch | Separate camera configs after option mode resolution. |
|
||||
| `softcore_camera_directive`, `hardcore_camera_directive` | Pair camera route | Krea pair branch | Separate plain camera sentences, suppressed for POV. |
|
||||
| `softcore_camera_scene_directive`, `hardcore_camera_scene_directive` | Scene-camera adapter | Krea/Naturalizer pair branch | Separate location-aware camera layout text. |
|
||||
|
||||
+18
-2
@@ -32,6 +32,14 @@ INSTA_OF_HARDCORE_CLOTHING_CONTINUITY = {
|
||||
"explicit_nude": "Woman A's body is fully exposed, bare skin unobstructed",
|
||||
}
|
||||
|
||||
HARDCORE_DETAIL_DENSITY_CHOICES = ["compact", "balanced", "dense"]
|
||||
|
||||
HARDCORE_DETAIL_DIRECTIVES = {
|
||||
"compact": "Use one compact position-first sexual action sentence; avoid repeated aftermath wording. ",
|
||||
"balanced": "",
|
||||
"dense": "Use dense but coherent motion, contact, and aftermath detail while keeping one readable body position. ",
|
||||
}
|
||||
|
||||
INSTA_OF_NEGATIVE = (
|
||||
"minors, childlike appearance, teen, underage, schoolgirl, non-consensual, coercion, rape, "
|
||||
"violence, injury, blood, gore, incest, bestiality, watermark, logo, readable username, social media UI"
|
||||
@@ -218,6 +226,14 @@ def character_softcore_outfit_values(source: str, custom_outfits: str = "") -> l
|
||||
return []
|
||||
|
||||
|
||||
def hardcore_detail_density_choices() -> list[str]:
|
||||
return list(HARDCORE_DETAIL_DENSITY_CHOICES)
|
||||
|
||||
|
||||
def hardcore_detail_directive(density: Any) -> str:
|
||||
return HARDCORE_DETAIL_DIRECTIVES.get(str(density or "balanced"), "")
|
||||
|
||||
|
||||
def character_hardcore_clothing_values(state: str, custom_clothing: str = "") -> list[str]:
|
||||
state = str(state or "no_change").strip()
|
||||
if state == "fully_nude":
|
||||
@@ -251,7 +267,7 @@ def build_insta_of_options_json(
|
||||
softcore_expression_enabled: bool = True,
|
||||
hardcore_expression_enabled: bool = True,
|
||||
hardcore_detail_density: str = "balanced",
|
||||
hardcore_detail_density_choices: list[str] | tuple[str, ...] = ("compact", "balanced", "dense"),
|
||||
hardcore_detail_density_choices: list[str] | tuple[str, ...] = tuple(HARDCORE_DETAIL_DENSITY_CHOICES),
|
||||
) -> str:
|
||||
hardcore_detail_density = (
|
||||
hardcore_detail_density if hardcore_detail_density in hardcore_detail_density_choices else "balanced"
|
||||
@@ -286,7 +302,7 @@ def parse_insta_of_options(
|
||||
*,
|
||||
camera_mode_choices: dict[str, str] | list[str] | tuple[str, ...],
|
||||
camera_detail_choices: list[str] | tuple[str, ...],
|
||||
hardcore_detail_density_choices: list[str] | tuple[str, ...],
|
||||
hardcore_detail_density_choices: list[str] | tuple[str, ...] = tuple(HARDCORE_DETAIL_DENSITY_CHOICES),
|
||||
) -> dict[str, Any]:
|
||||
defaults = {
|
||||
"softcore_cast": "solo",
|
||||
|
||||
+3
-7
@@ -132,7 +132,7 @@ CHARACTER_HAIR_STYLE_CHOICES = character_policy.CHARACTER_HAIR_STYLE_CHOICES
|
||||
CHARACTER_EYE_COLOR_CHOICES = character_policy.CHARACTER_EYE_COLOR_CHOICES
|
||||
|
||||
CAMERA_DETAIL_CHOICES = camera_policy.CAMERA_DETAIL_CHOICES
|
||||
HARDCORE_DETAIL_DENSITY_CHOICES = ["compact", "balanced", "dense"]
|
||||
HARDCORE_DETAIL_DENSITY_CHOICES = pair_options.HARDCORE_DETAIL_DENSITY_CHOICES
|
||||
HARDCORE_POSITION_FAMILY_CHOICES = hardcore_position_policy.HARDCORE_POSITION_FAMILY_CHOICES
|
||||
HARDCORE_POSITION_FOCUS_CHOICES = hardcore_position_policy.HARDCORE_POSITION_FOCUS_CHOICES
|
||||
HARDCORE_POSITION_KEY_CHOICES = hardcore_position_policy.HARDCORE_POSITION_KEY_CHOICES
|
||||
@@ -1244,7 +1244,7 @@ def camera_detail_choices() -> list[str]:
|
||||
|
||||
|
||||
def hardcore_detail_density_choices() -> list[str]:
|
||||
return list(HARDCORE_DETAIL_DENSITY_CHOICES)
|
||||
return pair_options.hardcore_detail_density_choices()
|
||||
|
||||
|
||||
def hardcore_position_family_choices() -> list[str]:
|
||||
@@ -4279,11 +4279,7 @@ def build_insta_of_pair(
|
||||
hard_row["source_scene_text"] = hard_row.get("source_scene_text") or hard_row.get("scene_text", "")
|
||||
hard_row["scene_text"] = hard_scene
|
||||
hard_detail_density = options["hardcore_detail_density"]
|
||||
hard_detail_directive = {
|
||||
"compact": "Use one compact position-first sexual action sentence; avoid repeated aftermath wording. ",
|
||||
"balanced": "",
|
||||
"dense": "Use dense but coherent motion, contact, and aftermath detail while keeping one readable body position. ",
|
||||
}[hard_detail_density]
|
||||
hard_detail_directive = pair_options.hardcore_detail_directive(hard_detail_density)
|
||||
pov_directive = _pov_prompt_directive(pov_character_labels)
|
||||
soft_descriptor_sentence = cast_context["soft_descriptor_sentence"]
|
||||
|
||||
|
||||
@@ -1597,6 +1597,26 @@ def smoke_pair_options_policy() -> None:
|
||||
pb.INSTA_OF_SOFTCORE_OUTFITS is pb.pair_options.INSTA_OF_SOFTCORE_OUTFITS,
|
||||
"prompt_builder should delegate Insta/OF softcore outfit policy to pair_options",
|
||||
)
|
||||
_expect(
|
||||
pb.HARDCORE_DETAIL_DENSITY_CHOICES is pb.pair_options.HARDCORE_DETAIL_DENSITY_CHOICES,
|
||||
"prompt_builder should delegate hardcore detail density choices to pair_options",
|
||||
)
|
||||
_expect(
|
||||
pb.pair_options.hardcore_detail_directive("compact").startswith("Use one compact"),
|
||||
"compact hardcore detail density should have a compact directive",
|
||||
)
|
||||
_expect(
|
||||
pb.pair_options.hardcore_detail_directive("dense").startswith("Use dense"),
|
||||
"dense hardcore detail density should have a dense directive",
|
||||
)
|
||||
_expect(
|
||||
pb.pair_options.hardcore_detail_directive("balanced") == "",
|
||||
"balanced hardcore detail density should not add a directive",
|
||||
)
|
||||
_expect(
|
||||
pb.pair_options.hardcore_detail_directive("bad") == "",
|
||||
"invalid hardcore detail density directive should be empty",
|
||||
)
|
||||
options = json.loads(
|
||||
pb.build_insta_of_options_json(
|
||||
softcore_expression_enabled="false",
|
||||
|
||||
Reference in New Issue
Block a user