From ac4c50bf34e123175805860b457024d28753cfc5 Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Sat, 27 Jun 2026 14:44:05 +0200 Subject: [PATCH] Harden formatter metadata fixtures --- category_template_metadata.py | 4 +- tools/prompt_smoke.py | 127 ++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/category_template_metadata.py b/category_template_metadata.py index 8668a10..0a16b61 100644 --- a/category_template_metadata.py +++ b/category_template_metadata.py @@ -105,8 +105,10 @@ def formatter_hints_for_route(row_or_hints: Any, route: str) -> list[str]: raw_hints = row_or_hints.get("formatter_hints") or {} elif "formatter_hint" in row_or_hints: raw_hints = formatter_hints(row_or_hints) - else: + elif row_or_hints and all(normalize_formatter_route(raw_route) for raw_route in row_or_hints): raw_hints = row_or_hints + else: + return [] normalized: dict[str, list[str]] = {} if isinstance(raw_hints, dict): diff --git a/tools/prompt_smoke.py b/tools/prompt_smoke.py index 4bc3744..fe5dfbb 100644 --- a/tools/prompt_smoke.py +++ b/tools/prompt_smoke.py @@ -4040,6 +4040,16 @@ def smoke_hardcore_position_config_policy() -> None: "krea2", ) _expect(route_hints == ["shared formatter cue", "krea formatter cue"], "Formatter hint route resolver changed") + raw_route_hints = category_template_metadata.formatter_hints_for_route( + {"all": ["raw shared cue"], "caption": ["raw caption cue"]}, + "caption", + ) + _expect(raw_route_hints == ["raw shared cue", "raw caption cue"], "Raw formatter route-map resolver changed") + _expect( + category_template_metadata.formatter_hints_for_route({"caption": "row caption should not be a hint", "prompt": "row prompt"}, "caption") + == [], + "Formatter hint route resolver treated an arbitrary metadata row as route hints", + ) _expect( pb._template_action_family(template_metadata) == category_template_metadata.template_action_family(template_metadata), "Prompt builder template action policy should delegate", @@ -5818,6 +5828,123 @@ def smoke_formatter_metadata_fixtures() -> None: _expect("krea readable anchor" not in caption_text, "Caption naturalizer leaked Krea formatter hint") _expect("sdxl route tag" not in caption_text, "Caption naturalizer leaked SDXL formatter hint") + external_pair = { + "mode": "Insta/OF", + "trigger": Trigger, + "shared_descriptor": "25-year-old adult woman, slim figure, fair skin, blonde hair, blue eyes", + "shared_cast_descriptors": [ + "Woman A: 25-year-old adult woman, slim figure, fair skin, blonde hair, blue eyes", + "Man A: 40-year-old adult man, average figure, tan skin, dark hair", + ], + "options": { + "softcore_cast": "same_as_hardcore", + "continuity": "same_creator_same_room", + "softcore_level": "lingerie_tease", + "hardcore_level": "hardcore", + }, + "softcore_row": { + "prompt": f"{Trigger}, embedded soft pair prompt.", + "caption": f"{Trigger}, embedded soft pair caption.", + "negative_prompt": "bad hands, bad hands", + "subject_type": "configured_cast", + "primary_subject": "woman", + "item": "red satin lingerie set", + "softcore_item_prompt_label": "Erotic outfit", + "pose": "standing together beside a mirror", + "scene_text": "private studio room with warm light", + "composition": "mirror teaser composition", + "expression": "confident soft smile", + "softcore_partner_styling": { + "outfits": ["Man A wears a black buttoned shirt and dark trousers"], + "pose": "standing close with one hand at the waist", + }, + "camera_config": { + "camera_mode": "standard", + "custom_camera_prompt": "front-right quarter view, eye-level shot, medium shot", + }, + "camera_directive": "Camera: row soft front-right view.", + "camera_scene_directive": "Row soft mirror camera layout.", + }, + "hardcore_row": { + "prompt": f"{Trigger}, embedded hard pair prompt.", + "caption": f"{Trigger}, embedded hard pair caption.", + "negative_prompt": "low quality, low quality", + "subject_type": "configured_cast", + "primary_subject": "configured_cast", + "item": "missionary position while full-body penetrative sex", + "custom_item": "Penetrative sex", + "item_label": "Sexual pose", + "item_axis_values": { + "position": "missionary position", + "penetration_act": "full-body penetrative sex", + }, + "scene_text": "private studio room with warm light", + "composition": "front-facing full-body frame", + "source_composition": "front-facing full-body frame", + "role_graph": ( + "Woman A lies on her back with legs open around Man A's hips while Man A is above her " + "between her thighs; Man A's penis thrusts into her pussy." + ), + "source_role_graph": ( + "Woman A lies on her back with legs open around Man A's hips while Man A is above her " + "between her thighs; Man A's penis thrusts into her pussy." + ), + "expression": "focused adult expression", + "action_family": "penetration", + "position_family": "penetrative", + "position_key": "missionary", + "position_keys": ["missionary"], + "hardcore_clothing_state": "Woman A's red satin lingerie set is pushed aside at the hips", + "camera_config": { + "camera_mode": "standard", + "custom_camera_prompt": "right side view, eye-level shot, medium shot", + }, + "camera_directive": "Camera: row hard right-side view.", + "camera_scene_directive": "Row hard body-aligned camera layout.", + }, + } + external_metadata = _json(external_pair) + + krea_pair = krea_formatter.format_krea2_prompt("", metadata_json=external_metadata, target="auto") + krea_soft = _expect_text("fixture_external_pair.krea_soft", krea_pair.get("krea_softcore_prompt"), 40).lower() + krea_hard = _expect_text("fixture_external_pair.krea_hard", krea_pair.get("krea_hardcore_prompt"), 40).lower() + _expect(krea_pair.get("method") == "metadata_json:krea2(insta_of_pair)", "External pair Krea route changed method") + _expect("black buttoned shirt" in krea_soft, "External pair Krea soft route lost embedded partner styling") + _expect("red satin lingerie set" in krea_hard, "External pair Krea hard route lost embedded clothing state") + _expect("row hard right-side view" in krea_hard, "External pair Krea hard route lost embedded camera directive") + _expect_no_duplicate_comma_items("fixture_external_pair.krea_negative", krea_pair.get("negative_prompt")) + + sdxl_pair = sdxl_formatter.format_sdxl_prompt( + "", + metadata_json=external_metadata, + target="auto", + trigger=SdxlTrigger, + prepend_trigger=True, + ) + sdxl_soft = _expect_text("fixture_external_pair.sdxl_soft", sdxl_pair.get("sdxl_softcore_prompt"), 40).lower() + sdxl_hard = _expect_text("fixture_external_pair.sdxl_hard", sdxl_pair.get("sdxl_hardcore_prompt"), 40).lower() + _expect(sdxl_pair.get("method") == "metadata_json:sdxl(insta_of_pair)", "External pair SDXL route changed method") + _expect_trigger_once("fixture_external_pair.sdxl_soft", sdxl_pair.get("sdxl_softcore_prompt"), SdxlTrigger) + _expect_trigger_once("fixture_external_pair.sdxl_hard", sdxl_pair.get("sdxl_hardcore_prompt"), SdxlTrigger) + _expect("black buttoned shirt" in sdxl_soft, "External pair SDXL soft route lost embedded partner styling") + _expect("red satin lingerie set" in sdxl_hard, "External pair SDXL hard route lost embedded clothing state") + _expect("row hard right-side view" in sdxl_hard, "External pair SDXL hard route lost embedded camera directive") + _expect_no_duplicate_comma_items("fixture_external_pair.sdxl_negative", sdxl_pair.get("negative_prompt")) + + caption, method = caption_naturalizer.naturalize_caption( + "", + metadata_json=external_metadata, + target="auto", + trigger=Trigger, + include_trigger=True, + ) + caption_text = _expect_text("fixture_external_pair.caption", caption, 40).lower() + _expect(method == "metadata_json:metadata(insta_of_pair)", "External pair caption route changed method") + _expect_trigger_once("fixture_external_pair.caption", caption, Trigger) + _expect("black buttoned shirt" in caption_text, "External pair caption route lost embedded partner styling") + _expect("softcore version" in caption_text, "External pair caption route lost softcore side") + _expect("hardcore version" in caption_text, "External pair caption route lost hardcore side") + generated = _prompt_row( name="fixture_generated_formatter_invariants", category="Casual clothes",