Filter incompatible SDXL route tags

This commit is contained in:
2026-06-27 18:41:17 +02:00
parent 5ca5f1b858
commit cac4fe47cd
4 changed files with 123 additions and 5 deletions
+51 -1
View File
@@ -21,6 +21,17 @@ except ImportError: # Allows local smoke tests with `python -c`.
PROMPT_FIELD_LABELS = input_policy.prompt_field_labels()
INCOMPATIBLE_ROUTE_TAGS = {
"action:penetration": ("oral sex", "outercourse", "anal sex", "manual stimulation"),
"action:oral": ("penetrative sex", "penetration", "anal sex", "outercourse"),
"action:outercourse": ("penetrative sex", "penetration", "oral sex", "anal sex", "manual stimulation"),
"position:penetrative": ("oral sex", "outercourse", "anal sex", "manual stimulation"),
"position:oral": ("penetrative sex", "penetration", "anal sex", "outercourse"),
"position:outercourse": ("penetrative sex", "penetration", "oral sex", "anal sex", "manual stimulation"),
"position:manual": ("penetrative sex", "penetration", "oral sex", "anal sex", "outercourse"),
"position:anal": ("oral sex", "outercourse", "manual stimulation"),
}
def clean(value: Any) -> str:
return input_policy.clean_text(value)
@@ -238,7 +249,33 @@ def explicit_tags(text: str, nude_weight: float) -> list[str]:
tags.append("penetration")
if "vaginal" in lower:
tags.append("pussy")
if "oral" in lower or "mouth" in lower:
oral_terms = (
"oral sex",
"oral-sex",
"blowjob",
"deepthroat",
"fellatio",
"cunnilingus",
"pussy licking",
"mouth on",
"mouth pressed",
"mouth contact",
"mouth around",
"lips wrapped",
"takes the penis in her mouth",
"takes the man's penis",
"takes the viewer's penis",
"penis in her mouth",
"tongue on pussy",
"tongue along the penis",
"tongue along the penis shaft",
"tongue touches the underside",
"licking the penis",
"testicle sucking",
"balls licking",
"balls-licking",
)
if any(token in lower for token in oral_terms):
tags.append("oral sex")
if "anal" in lower:
tags.append("anal sex")
@@ -247,6 +284,18 @@ def explicit_tags(text: str, nude_weight: float) -> list[str]:
return tags
def filter_incompatible_route_tags(tags: list[str], row: dict[str, Any]) -> list[str]:
action_family = route_metadata_policy.row_action_family(row)
position_family = route_metadata_policy.row_position_family(row)
blocked: set[str] = set()
for scope, family in (("action", action_family), ("position", position_family)):
for tag in INCOMPATIBLE_ROUTE_TAGS.get(f"{scope}:{family}", ()):
blocked.add(tag_key(tag))
if not blocked:
return tags
return [tag for tag in tags if tag_key(tag) not in blocked]
def softcore_pair_tags(row: dict[str, Any], root: dict[str, Any]) -> list[str]:
tags = ["softcore teaser", softcore_text_policy.softcore_style_tag()]
options = root.get("options") if isinstance(root.get("options"), dict) else {}
@@ -274,5 +323,6 @@ def tag_route_dependencies() -> sdxl_tag_routes.SDXLTagRouteDependencies:
axis_value_tags=axis_value_tags,
camera_tags=camera_tags,
explicit_tags=explicit_tags,
filter_incompatible_route_tags=filter_incompatible_route_tags,
softcore_pair_tags=softcore_pair_tags,
)