Move pair descriptor policy
This commit is contained in:
@@ -228,9 +228,10 @@ Already isolated:
|
|||||||
- soft/hard row creation lives in `pair_rows.py`, including softcore expression
|
- soft/hard row creation lives in `pair_rows.py`, including softcore expression
|
||||||
override resolution, Woman A slot context application, soft outfit/pose
|
override resolution, Woman A slot context application, soft outfit/pose
|
||||||
overrides, POV row fields, and hardcore row creation.
|
overrides, POV row fields, and hardcore row creation.
|
||||||
- pair-level cast/display context lives in `pair_cast.py`, including shared
|
- pair-level cast/display context lives in `pair_cast.py`, including descriptor
|
||||||
descriptors, same-cast softcore descriptor text, partner styling, platform and
|
prose, shared descriptors, cast-label cleanup, same-cast softcore descriptor
|
||||||
level labels, softcore cast presence text, and hard cast summary text.
|
text, partner styling, platform and level labels, softcore cast presence text,
|
||||||
|
and hard cast summary text.
|
||||||
- pair-level camera routing lives in `pair_camera.py`, including soft/hard
|
- pair-level camera routing lives in `pair_camera.py`, including soft/hard
|
||||||
camera config selection, same-as-softcore mode, camera-detail override,
|
camera config selection, same-as-softcore mode, camera-detail override,
|
||||||
same-room hard scene continuity, camera-aware composition mutation, POV camera
|
same-room hard scene continuity, camera-aware composition mutation, POV camera
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ Core helper ownership:
|
|||||||
| `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. |
|
| `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, hardcore cast count policy, and hardcore detail-density directives. |
|
| `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_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_cast.py` | Insta/OF shared descriptors, same-cast softcore descriptor text, partner styling selection, cast-summary wording, platform/level labels, softcore cast presence text, and hard cast summary text. |
|
| `pair_cast.py` | Insta/OF descriptor prose, shared descriptors, cast-label cleanup, same-cast softcore descriptor text, partner styling selection, cast-summary wording, platform/level labels, softcore cast presence text, and hard cast summary text. |
|
||||||
| `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_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 clothing sentence formatting, body-exposure scene cleanup, hardcore clothing continuity, action-aware body-access flags, conflicting outfit-piece cleanup, configured/default visible-person clothing, and final root clothing-state assembly. |
|
| `pair_clothing.py` | Insta/OF clothing sentence formatting, body-exposure scene cleanup, hardcore clothing continuity, action-aware body-access flags, conflicting outfit-piece cleanup, configured/default visible-person clothing, and final root clothing-state assembly. |
|
||||||
| `pair_output.py` | Insta/OF final pair prompts, trigger preservation, negative prompts, captions, and root pair metadata assembly. |
|
| `pair_output.py` | Insta/OF final pair prompts, trigger preservation, negative prompts, captions, and root pair metadata assembly. |
|
||||||
|
|||||||
+32
-4
@@ -4,15 +4,16 @@ from typing import Any, Callable
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from . import cast_context as cast_context_policy
|
from . import cast_context as cast_context_policy
|
||||||
|
from . import character_profile as character_profile_policy
|
||||||
from . import pair_clothing
|
from . import pair_clothing
|
||||||
from . import pair_options
|
from . import pair_options
|
||||||
except ImportError: # Allows local smoke tests with top-level imports.
|
except ImportError: # Allows local smoke tests with top-level imports.
|
||||||
import cast_context as cast_context_policy
|
import cast_context as cast_context_policy
|
||||||
|
import character_profile as character_profile_policy
|
||||||
import pair_clothing
|
import pair_clothing
|
||||||
import pair_options
|
import pair_options
|
||||||
|
|
||||||
|
|
||||||
DescriptorFromRow = Callable[[dict[str, Any]], str]
|
|
||||||
CastDescriptors = Callable[..., list[str]]
|
CastDescriptors = Callable[..., list[str]]
|
||||||
AxisRng = Callable[[dict[str, int], str, int, int], Any]
|
AxisRng = Callable[[dict[str, int], str, int, int], Any]
|
||||||
Choose = Callable[[Any, list[str]], str]
|
Choose = Callable[[Any, list[str]], str]
|
||||||
@@ -23,6 +24,35 @@ def cast_summary_phrase(women_count: int, men_count: int) -> str:
|
|||||||
return cast_context_policy.cast_summary_phrase(women_count, men_count)
|
return cast_context_policy.cast_summary_phrase(women_count, men_count)
|
||||||
|
|
||||||
|
|
||||||
|
def insta_descriptor_from_row(row: dict[str, Any]) -> str:
|
||||||
|
return character_profile_policy.descriptor_from_parts(
|
||||||
|
"woman",
|
||||||
|
row.get("age_band") or row.get("age"),
|
||||||
|
row.get("body_phrase"),
|
||||||
|
row.get("skin"),
|
||||||
|
row.get("hair"),
|
||||||
|
row.get("eyes"),
|
||||||
|
row.get("descriptor_detail"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def insta_descriptor_from_context(context: dict[str, Any]) -> str:
|
||||||
|
subject = str(context.get("subject") or context.get("subject_type") or "person").strip()
|
||||||
|
return character_profile_policy.descriptor_from_parts(
|
||||||
|
subject,
|
||||||
|
context.get("age"),
|
||||||
|
context.get("body_phrase"),
|
||||||
|
context.get("skin"),
|
||||||
|
context.get("hair"),
|
||||||
|
context.get("eyes"),
|
||||||
|
context.get("descriptor_detail"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def prompt_cast_descriptors(text: str) -> str:
|
||||||
|
return str(text or "").replace("Woman A / primary creator:", "Woman A:")
|
||||||
|
|
||||||
|
|
||||||
def softcore_partner_styling(
|
def softcore_partner_styling(
|
||||||
*,
|
*,
|
||||||
seed_config: dict[str, int],
|
seed_config: dict[str, int],
|
||||||
@@ -87,14 +117,12 @@ def resolve_insta_pair_cast_context(
|
|||||||
platform_styles: dict[str, str],
|
platform_styles: dict[str, str],
|
||||||
soft_levels: dict[str, str],
|
soft_levels: dict[str, str],
|
||||||
hardcore_levels: dict[str, str],
|
hardcore_levels: dict[str, str],
|
||||||
descriptor_from_row: DescriptorFromRow,
|
|
||||||
build_cast_descriptors: CastDescriptors,
|
build_cast_descriptors: CastDescriptors,
|
||||||
prompt_cast_descriptors: Callable[[str], str],
|
|
||||||
axis_rng: AxisRng,
|
axis_rng: AxisRng,
|
||||||
choose: Choose,
|
choose: Choose,
|
||||||
slot_softcore_outfit: SlotSoftcoreOutfit,
|
slot_softcore_outfit: SlotSoftcoreOutfit,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
descriptor = descriptor_from_row(soft_row)
|
descriptor = insta_descriptor_from_row(soft_row)
|
||||||
cast_descriptors = build_cast_descriptors(
|
cast_descriptors = build_cast_descriptors(
|
||||||
descriptor,
|
descriptor,
|
||||||
parsed_seed_config,
|
parsed_seed_config,
|
||||||
|
|||||||
+3
-22
@@ -3819,28 +3819,11 @@ def _insta_of_hardcore_counts(options: dict[str, Any]) -> tuple[int, int]:
|
|||||||
|
|
||||||
|
|
||||||
def _insta_of_descriptor(row: dict[str, Any]) -> str:
|
def _insta_of_descriptor(row: dict[str, Any]) -> str:
|
||||||
return _descriptor_from_parts(
|
return pair_cast.insta_descriptor_from_row(row)
|
||||||
"woman",
|
|
||||||
row.get("age_band") or row.get("age"),
|
|
||||||
row.get("body_phrase"),
|
|
||||||
row.get("skin"),
|
|
||||||
row.get("hair"),
|
|
||||||
row.get("eyes"),
|
|
||||||
row.get("descriptor_detail"),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _insta_of_descriptor_from_context(context: dict[str, Any]) -> str:
|
def _insta_of_descriptor_from_context(context: dict[str, Any]) -> str:
|
||||||
subject = str(context.get("subject") or context.get("subject_type") or "person").strip()
|
return pair_cast.insta_descriptor_from_context(context)
|
||||||
return _descriptor_from_parts(
|
|
||||||
subject,
|
|
||||||
context.get("age"),
|
|
||||||
context.get("body_phrase"),
|
|
||||||
context.get("skin"),
|
|
||||||
context.get("hair"),
|
|
||||||
context.get("eyes"),
|
|
||||||
context.get("descriptor_detail"),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _insta_of_cast_descriptors(
|
def _insta_of_cast_descriptors(
|
||||||
@@ -3873,7 +3856,7 @@ def _insta_of_cast_descriptors(
|
|||||||
|
|
||||||
|
|
||||||
def _insta_of_prompt_cast_descriptors(text: str) -> str:
|
def _insta_of_prompt_cast_descriptors(text: str) -> str:
|
||||||
return str(text or "").replace("Woman A / primary creator:", "Woman A:")
|
return pair_cast.prompt_cast_descriptors(text)
|
||||||
|
|
||||||
|
|
||||||
def _insta_of_softcore_category(level: str) -> tuple[str, str]:
|
def _insta_of_softcore_category(level: str) -> tuple[str, str]:
|
||||||
@@ -3990,9 +3973,7 @@ def build_insta_of_pair(
|
|||||||
platform_styles=INSTA_OF_PLATFORM_STYLES,
|
platform_styles=INSTA_OF_PLATFORM_STYLES,
|
||||||
soft_levels=INSTA_OF_SOFT_LEVELS,
|
soft_levels=INSTA_OF_SOFT_LEVELS,
|
||||||
hardcore_levels=INSTA_OF_HARDCORE_LEVELS,
|
hardcore_levels=INSTA_OF_HARDCORE_LEVELS,
|
||||||
descriptor_from_row=_insta_of_descriptor,
|
|
||||||
build_cast_descriptors=_insta_of_cast_descriptors,
|
build_cast_descriptors=_insta_of_cast_descriptors,
|
||||||
prompt_cast_descriptors=_insta_of_prompt_cast_descriptors,
|
|
||||||
axis_rng=_axis_rng,
|
axis_rng=_axis_rng,
|
||||||
choose=g.choose,
|
choose=g.choose,
|
||||||
slot_softcore_outfit=_slot_softcore_outfit,
|
slot_softcore_outfit=_slot_softcore_outfit,
|
||||||
|
|||||||
@@ -1710,6 +1710,28 @@ def smoke_pair_options_policy() -> None:
|
|||||||
pair_cast.cast_summary_phrase(2, 1) == "2 women, 1 man, 3 total adults",
|
pair_cast.cast_summary_phrase(2, 1) == "2 women, 1 man, 3 total adults",
|
||||||
"Pair cast summary phrase should live in pair_cast",
|
"Pair cast summary phrase should live in pair_cast",
|
||||||
)
|
)
|
||||||
|
descriptor_row = {
|
||||||
|
"age": "25-year-old adult",
|
||||||
|
"body_phrase": "curvy build",
|
||||||
|
"skin": "warm skin",
|
||||||
|
"hair": "dark hair",
|
||||||
|
"eyes": "brown eyes",
|
||||||
|
}
|
||||||
|
_expect(
|
||||||
|
pb._insta_of_descriptor(descriptor_row) == pair_cast.insta_descriptor_from_row(descriptor_row),
|
||||||
|
"Prompt builder Insta descriptor should delegate to pair_cast",
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
pair_cast.insta_descriptor_from_context(
|
||||||
|
{"subject_type": "man", "age": "40-year-old adult", "body_phrase": "stocky figure"}
|
||||||
|
)
|
||||||
|
== "40-year-old adult man, stocky figure",
|
||||||
|
"Pair cast context descriptor formatting changed",
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
pair_cast.prompt_cast_descriptors("Woman A / primary creator: descriptor") == "Woman A: descriptor",
|
||||||
|
"Pair cast prompt descriptor label cleanup changed",
|
||||||
|
)
|
||||||
partner_styling = pair_cast.softcore_partner_styling(
|
partner_styling = pair_cast.softcore_partner_styling(
|
||||||
seed_config={},
|
seed_config={},
|
||||||
seed=1,
|
seed=1,
|
||||||
|
|||||||
Reference in New Issue
Block a user