From 7f6bf0ffd8efd4563980fa8de4571382948f4475 Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Sat, 27 Jun 2026 22:06:37 +0200 Subject: [PATCH] Clean SDXL composition tags --- sdxl_tag_routes.py | 11 +++++++++-- tools/prompt_route_simulation.py | 8 ++++++++ tools/prompt_smoke.py | 9 +++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/sdxl_tag_routes.py b/sdxl_tag_routes.py index f5621c7..f2608af 100644 --- a/sdxl_tag_routes.py +++ b/sdxl_tag_routes.py @@ -72,6 +72,13 @@ def _pair_counts(row: dict[str, Any], root: dict[str, Any]) -> tuple[int, int]: return _descriptor_counts(root) +def _composition_tags_text(text: str) -> str: + text = re.sub(r"^vertical\s+", "", str(text or "").strip(), flags=re.IGNORECASE) + text = re.sub(r"\s+composition$", "", text, flags=re.IGNORECASE) + text = re.sub(r"\bcomposition\b", "frame", text, flags=re.IGNORECASE) + return text.strip(" ,") + + def _row_explicit_signal_text( row: dict[str, Any], *, @@ -133,7 +140,7 @@ def row_core_tags_result(request: SDXLRowTagRequest, deps: SDXLTagRouteDependenc "expression", ("Facial expressions", "Facial expression"), ) - composition = deps.row_value(row, "composition", ("Composition",)) + composition = _composition_tags_text(deps.row_value(row, "composition", ("Composition",))) for value in ( item, pose, @@ -226,7 +233,7 @@ def hard_tags_result(request: SDXLPairTagRequest, deps: SDXLTagRouteDependencies hard_role = deps.clean(row.get("source_role_graph") or row.get("role_graph")) hard_clothing = deps.clean(root.get("hardcore_clothing_state")) expression = deps.clean(row.get("character_expression_text") or row.get("expression")) - composition = deps.clean(row.get("composition")) + composition = _composition_tags_text(deps.clean(row.get("composition"))) for value in ( hard_role, hard_item, diff --git a/tools/prompt_route_simulation.py b/tools/prompt_route_simulation.py index 022fcaa..9b1d984 100644 --- a/tools/prompt_route_simulation.py +++ b/tools/prompt_route_simulation.py @@ -569,6 +569,13 @@ def _composition_label_issues(name: str, prompts: dict[str, str]) -> list[str]: return issues +def _sdxl_composition_tag_issues(name: str, sdxl_prompt: str) -> list[str]: + for tag in (part.strip() for part in sdxl_prompt.split(",")): + if re.search(r"\bcomposition$", tag, flags=re.IGNORECASE): + return [f"{name}.sdxl_prompt: composition_tag_label"] + 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: @@ -705,6 +712,7 @@ def _formatter_issues( issues.extend(_caption_expression_grammar_issues(name, caption_text)) issues.extend(_krea_grammar_issues(name, krea_prompt)) issues.extend(_composition_label_issues(name, prompts)) + issues.extend(_sdxl_composition_tag_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 12f5383..1e813f6 100644 --- a/tools/prompt_smoke.py +++ b/tools/prompt_smoke.py @@ -4806,6 +4806,15 @@ def smoke_sdxl_tag_routes() -> None: _expect("27-year-old adult" in stale_character_route_tags, "SDXL route lost structured character age") _expect("warm olive skin" in stale_character_route_tags, "SDXL route lost structured character skin") _expect("stale" not in stale_character_route_tags, "SDXL route should not parse stale prompt character labels") + composition_label_row = _fixture_hardcore_row( + composition="coworking lounge frame with tall-window depth behind them composition", + ) + composition_label_tags = sdxl_tag_routes.row_core_tags_result( + sdxl_tag_routes.SDXLRowTagRequest(composition_label_row, 1.29), + deps, + ).as_text() + _expect("tall-window depth behind them composition" not in composition_label_tags, "SDXL route kept raw composition label tag") + _expect("tall-window depth behind them" in composition_label_tags, "SDXL route lost composition detail while removing label") stale_prompt_row = _fixture_hardcore_row( prompt="stale raw prompt mentions fully nude naked pussy penis oral anal semen penetration", item="standing portrait setup",