Filter anal axis details for position compatibility

This commit is contained in:
2026-06-27 16:04:39 +02:00
parent d0f2670d9c
commit ff6195473b
6 changed files with 262 additions and 6 deletions
+127
View File
@@ -51,6 +51,7 @@ import generation_profile_config # noqa: E402
import index_switch_policy # noqa: E402
import node_tooltips # noqa: E402
import krea_cast # noqa: E402
import krea_action_details # noqa: E402
import krea_configured_cast_formatter # noqa: E402
import krea_format_route # noqa: E402
import krea_formatter # noqa: E402
@@ -1130,6 +1131,56 @@ def smoke_krea_normal_row_routes() -> None:
_expect_krea_normal_route_parity(generic, "krea_normal_generic", "metadata(generic)")
def smoke_krea_action_details_policy() -> None:
_expect(
krea_action_details.strip_redundant_position_detail(
"kneeling penis-licking position while slow tongue licking on the underside of the penis"
)
== "slow tongue licking on the underside of the penis",
"Krea action detail cleanup should remove leading position-while scaffolding",
)
_expect(
krea_action_details.strip_redundant_position_detail(
"raised edge fingering position featuring mutual masturbation with both bodies touching themselves"
)
== "mutual masturbation with both bodies touching themselves",
"Krea action detail cleanup should remove leading position-featuring scaffolding",
)
_expect(
krea_action_details.strip_redundant_position_detail(
"footjob with toes curled around the penis shaft in seated footjob position"
)
== "footjob with toes curled around the penis shaft",
"Krea action detail cleanup should remove trailing in-position scaffolding",
)
_expect(
"position while"
not in krea_action_details.dedupe_outercourse_detail(
"kneeling penis-licking position while slow tongue licking on the underside of the penis",
"the woman bends forward between the man's open thighs",
"penis licking",
{"position": "kneeling penis-licking position"},
).lower(),
"Krea outercourse detail cleanup leaked position-while scaffolding",
)
_expect(
"position featuring"
not in krea_action_details.sanitize_foreplay_detail(
"raised edge fingering position featuring mutual masturbation with both bodies touching themselves",
"the woman and man sit close facing each other",
).lower(),
"Krea foreplay/manual detail cleanup leaked position-featuring scaffolding",
)
_expect(
krea_action_details.dedupe_anchor_detail(
"side-lying anal position, one leg lifted high",
"side-lying rear-entry anal pose",
)
== "one leg lifted high",
"Krea anchored detail cleanup should remove repeated anal position prefix",
)
def smoke_krea_row_fields_policy() -> None:
row = {
"subject_type": "configured_cast",
@@ -1665,6 +1716,18 @@ def smoke_row_item_policy() -> None:
== ["soles pressing around shaft"],
"Row item outercourse texture axis should prefer footjob-compatible details",
)
anal_leg_values = [
"standing with legs braced",
"one leg lifted high",
"kneeling with thighs apart",
"knees pressed to chest",
]
_expect(
pb._anal_axis_values_for_position(anal_leg_values, "side-lying anal position", "leg_detail")
== row_item.anal_axis_values_for_position(anal_leg_values, "side-lying anal position", "leg_detail")
== ["one leg lifted high"],
"Row item anal leg-detail filtering changed for side-lying anal",
)
category = {}
subcategory = {
@@ -1693,6 +1756,33 @@ def smoke_row_item_policy() -> None:
_expect(axis_values.get("hand_detail") == "hands on hips", "Row item compose did not apply oral detail filter")
_expect(metadata.get("action_family") == "oral", "Row item compose lost template metadata")
anal_subcategory = {
"name": "Anal and double penetration",
"slug": "anal_double_penetration",
"item_templates": [
{
"template": "{anal_act} in {position}, with {leg_detail}",
"action_family": "default",
"position_family": "anal",
}
],
"item_axes": {
"position": ["side-lying anal position"],
"anal_act": ["penis entering ass"],
"leg_detail": anal_leg_values,
},
}
anal_text, _anal_name, anal_axis_values, _anal_metadata = row_item.compose_item(
random.Random(5),
{},
anal_subcategory,
"Anal and double penetration",
women_count=1,
men_count=1,
)
_expect("standing with legs braced" not in anal_text, "Row item compose leaked standing legs into side-lying anal")
_expect(anal_axis_values.get("leg_detail") == "one leg lifted high", "Row item compose did not apply anal leg-detail filter")
def smoke_row_category_route_policy() -> None:
hard_config = hardcore_position_config.parse_hardcore_position_config(_position_filter("oral_only", "oral", ["kneeling"]))
@@ -5212,6 +5302,41 @@ def smoke_krea_pair_clothing_state() -> None:
_expect("outfit racks" not in sdxl_lower and "shoe shelves" not in sdxl_lower, "SDXL pair formatter leaked unsanitized hard scene")
def smoke_krea_anal_axis_compatibility() -> None:
pair = pb.build_insta_of_pair(
row_number=1,
start_index=1,
seed=6252,
ethnicity="french_european",
figure="random",
no_plus_women=False,
no_black=False,
trigger=Trigger,
prepend_trigger_to_prompt=True,
options_json=_insta_options(hardcore_clothing_continuity="partially_removed", camera_detail="off"),
character_cast=_character_cast(),
hardcore_position_config=_action_filter(
"anal_only",
pb.build_hardcore_position_pool_json(family="anal"),
),
seed_config=pb.build_seed_lock_config_json(base_seed=6252, reroll_axis="pose", reroll_seed=6352),
)
hard_row = pair["hardcore_row"]
axis_values = hard_row.get("item_axis_values") or {}
position = str(axis_values.get("position") or "").lower()
leg_detail = str(axis_values.get("leg_detail") or "").lower()
if "side-lying" in position:
_expect("standing" not in leg_detail, "Generated side-lying anal row leaked standing leg detail")
krea = krea_formatter.format_krea2_prompt("", metadata_json=_json(pair), target="hardcore")
prompt = _expect_text("krea_anal_axis_compatibility.krea_prompt", krea.get("krea_prompt"), 60)
lower = prompt.lower()
_expect(
"side-lying rear-entry anal pose" not in lower or "stands braced" not in lower,
"Krea anal formatter mixed side-lying anchor with standing role graph",
)
_expect("side-lying anal position, standing with legs braced" not in lower, "Krea anal formatter leaked contradictory axis detail")
def smoke_insta_pair_pov() -> None:
pair = pb.build_insta_of_pair(
row_number=1,
@@ -7510,6 +7635,7 @@ SMOKE_CASES: list[tuple[str, Callable[[], None]]] = [
("builder_prompt_route_policy", smoke_builder_prompt_route_policy),
("builder_config_route_policy", smoke_builder_config_route_policy),
("krea_normal_row_routes", smoke_krea_normal_row_routes),
("krea_action_details_policy", smoke_krea_action_details_policy),
("krea_row_fields_policy", smoke_krea_row_fields_policy),
("location_config_policy", smoke_location_config_policy),
("row_location_policy", smoke_row_location_policy),
@@ -7554,6 +7680,7 @@ SMOKE_CASES: list[tuple[str, Callable[[], None]]] = [
("pair_builder_policy", smoke_pair_builder_policy),
("insta_pair_same_cast", smoke_insta_pair),
("krea_pair_clothing_state", smoke_krea_pair_clothing_state),
("krea_anal_axis_compatibility", smoke_krea_anal_axis_compatibility),
("insta_pair_pov_man", smoke_insta_pair_pov),
("insta_pair_camera_split", smoke_insta_pair_camera_split),
("pov_camera_scene", smoke_pov_camera_scene),