diff --git a/sdxl_tag_policy.py b/sdxl_tag_policy.py index f2f572d..636810e 100644 --- a/sdxl_tag_policy.py +++ b/sdxl_tag_policy.py @@ -64,6 +64,7 @@ def split_tag_text(text: Any) -> list[str]: flags=re.IGNORECASE, ) text = re.sub(r"(? list[str]: return [] +def _sdxl_character_pair_fragment_issues(name: str, sdxl_prompt: str) -> list[str]: + if re.search(r"\b(?:woman,\s*man|man,\s*woman)\s+are\b", sdxl_prompt, flags=re.IGNORECASE): + return [f"{name}.sdxl_prompt: broken_character_pair_tag"] + return [] + + def _trace_dict(formatter_name: str, payload: dict[str, Any]) -> tuple[dict[str, Any], str]: trace_text = str(payload.get("route_trace_json") or "") if not trace_text: @@ -727,6 +733,7 @@ def _formatter_issues( issues.extend(_sdxl_composition_tag_issues(name, sdxl_prompt)) issues.extend(_sdxl_expression_label_issues(name, sdxl_prompt)) issues.extend(_sdxl_hyphen_fragment_issues(name, sdxl_prompt)) + issues.extend(_sdxl_character_pair_fragment_issues(name, sdxl_prompt)) for label, value in ( (f"{name}.krea_negative", krea.get("negative_prompt")), diff --git a/tools/prompt_smoke.py b/tools/prompt_smoke.py index 06ec3ae..f0e5ad3 100644 --- a/tools/prompt_smoke.py +++ b/tools/prompt_smoke.py @@ -4680,6 +4680,9 @@ def smoke_sdxl_tag_policy() -> None: _expect("front-and-back penetration" in hyphenated_tags, "SDXL tag splitter broke hyphenated and compound") _expect("front-" not in hyphenated_tags and "-back penetration" not in hyphenated_tags, "SDXL tag splitter emitted broken hyphen fragments") _expect("hands on hips" in hyphenated_tags, "SDXL tag splitter stopped splitting non-hyphenated with connector") + subject_pair_tags = sdxl_tag_policy.split_tag_text("Woman A, Man A are mid-transition with hands on hips") + _expect("woman and man are mid-transition" in subject_pair_tags, "SDXL tag splitter broke paired character clause") + _expect("woman" not in subject_pair_tags and "man are mid-transition" not in subject_pair_tags, "SDXL tag splitter emitted broken paired character fragments") _expect( sdxl_formatter._camera_tags(row) == sdxl_tag_policy.camera_tags(row), "SDXL formatter camera helper should delegate to sdxl_tag_policy",