Improve hardcore prompt wording QA

This commit is contained in:
2026-06-25 15:07:42 +02:00
parent 9c86151b89
commit 186f225778
3 changed files with 257 additions and 40 deletions
+109 -15
View File
@@ -292,9 +292,24 @@ def _natural_label_text(text: Any, labels: list[str]) -> str:
text = re.sub(r"\bWoman A\b", "the woman", text)
elif labels == ["Man A"]:
text = re.sub(r"\bMan A\b", "the man", text)
text = re.sub(
r"(^|[.!?]\s+)(the woman|the man)\b",
lambda match: match.group(1) + match.group(2).capitalize(),
text,
flags=re.IGNORECASE,
)
return text
def _lowercase_for_inline_join(text: str) -> str:
return re.sub(
r"^(The woman|The man|The viewer|The named adults)\b",
lambda match: match.group(1).lower(),
_clean(text),
flags=re.IGNORECASE,
)
def _cast_prose(
text: str,
central_label: str = "Woman A",
@@ -446,10 +461,40 @@ def _pov_hardcore_pose_sentence(
action_lower = action_text.lower()
if not context:
context = action_lower
def sentence(base: str) -> str:
details = ""
if ";" in action_text:
details = _pov_clean_detail(action_text.split(";", 1)[1], f"{context} {base}", detail_density)
return f"{base}; {details}" if details else base
if _is_outercourse_text(context, action_lower):
if any(term in context for term in ("boobjob", "titjob", "breast sex", "breast-sex")):
return sentence(
"POV breast-sex position: the viewer reclines with his hips in the foreground while the woman kneels between his thighs; "
"her hands press both breasts around the viewer's penis with the glans near her mouth"
)
if any(term in context for term in ("testicle", "balls licking", "balls-licking", "balls and mouth")):
return sentence(
"POV testicle-sucking position: the viewer reclines with thighs open while the woman kneels low between his legs; "
"her mouth and tongue stay at the viewer's balls with his penis visible above her face"
)
if any(term in context for term in ("penis licking", "penis-licking", "tongue along", "tongue licking")):
return sentence(
"POV penis-licking position: the viewer's hips and penis are in the foreground while the woman kneels close; "
"her tongue moves along the shaft and glans with her hands steadying the base"
)
if any(term in context for term in ("footjob", "soles", "toes curled", "feet stroking")):
return sentence(
"POV footjob position: the viewer reclines with his penis in the foreground while the woman faces him; "
"her soles wrap around the shaft and stroke it with the contact point centered"
)
return sentence(
"POV non-penetrative outercourse position: the viewer's hips stay in the foreground while the woman keeps the visible contact point centered"
)
penetrative_tokens = (
"penetrat",
"thrust",
"penis",
"anal",
"cowgirl",
"missionary",
@@ -472,12 +517,6 @@ def _pov_hardcore_pose_sentence(
contact = _pov_contact_clause(action, role_graph, hard_item, axis_values, context)
def sentence(base: str) -> str:
details = ""
if ";" in action_text:
details = _pov_clean_detail(action_text.split(";", 1)[1], f"{context} {base}", detail_density)
return f"{base}; {details}" if details else base
if "reverse cowgirl" in context:
return sentence(
"POV reverse cowgirl position: the viewer lies on his back while the woman straddles his hips facing away; "
@@ -644,11 +683,31 @@ def _sanitize_scene_text_for_cast(text: Any, labels: list[str]) -> str:
return text
def _natural_clothing_state(text: Any) -> str:
def _clothing_access_phrase(action_text: Any) -> str:
text = _clean(action_text).lower()
if any(term in text for term in ("cumshot", "ejaculat", "semen", "cum on", "cum across", "post-orgasm", "aftermath")):
return "leaving the body exposed for visible semen and aftermath"
if any(term in text for term in ("boobjob", "titjob", "breast sex", "footjob", "testicle", "balls", "penis licking", "non-penetrative")):
return "leaving the contact point unobstructed"
if any(term in text for term in ("oral", "blowjob", "fellatio", "mouth", "tongue")):
return "leaving the oral contact unobstructed"
if any(term in text for term in ("penetrat", "thrust", "penis entering", "vaginal", "anal")):
return "leaving the penetration point unobstructed"
return "leaving skin and body contact readable"
def _natural_clothing_state(text: Any, action_text: Any = "") -> str:
text = _clean(text)
if not text:
return ""
text = re.sub(r"^Clothing state:\s*", "", text, flags=re.IGNORECASE)
if re.search(r";\s*(?=(?:Woman|Man) [A-Z]\b)", text):
parts = [
_natural_clothing_state(part, action_text).rstrip(".")
for part in re.split(r";\s*(?=(?:Woman|Man) [A-Z]\b)", text)
if _clean(part)
]
return ". ".join(part for part in parts if part)
body_exposure = re.match(r"^Body exposure:\s*(.*?)\.?$", text, flags=re.IGNORECASE)
if body_exposure:
return _clean(body_exposure.group(1)).rstrip(".")
@@ -672,9 +731,9 @@ def _natural_clothing_state(text: Any) -> str:
if "nude-adjacent" in state:
return f"{owner.capitalize()}'s body is partly exposed"
if "partially removed" in state or "pushed aside" in state:
return f"{owner.capitalize()}'s {outfit} is pushed aside and partly removed, exposing the sexual contact clearly"
return f"{owner.capitalize()}'s {outfit} is pushed aside or partly removed where needed, {_clothing_access_phrase(action_text)}"
if "keeps" in state:
return f"{owner.capitalize()} keeps the {outfit} on while the sexual contact stays visible"
return f"{owner.capitalize()} keeps the {outfit} on while {_clothing_access_phrase(action_text)}"
text = re.sub(r";\s*(?:softcore visual reference|teaser outfit detail):\s*", ". Visual clothing state: ", text, flags=re.IGNORECASE)
text = text.replace("softcore outfit", "outfit")
text = text.replace("teaser outfit", "outfit")
@@ -715,6 +774,31 @@ def _position_context_text(role_graph: str, hard_item: str, composition: str = "
)
def _is_outercourse_text(*parts: Any) -> bool:
text = " ".join(_clean(part).lower() for part in parts if _clean(part))
return any(
term in text
for term in (
"outercourse",
"non-penetrative",
"boobjob",
"titjob",
"breast sex",
"breast-sex",
"testicle",
"balls licking",
"balls-licking",
"penis licking",
"penis-licking",
"tongue along",
"footjob",
"soles",
"toes curled",
"feet stroking",
)
)
def _is_toy_assisted_double_text(*parts: Any) -> bool:
text = " ".join(_clean(part).lower() for part in parts if _clean(part))
if "toy" not in text:
@@ -758,6 +842,16 @@ def _hardcore_pose_anchor(role_graph: str, hard_item: str, composition: str = ""
position_text = _clean(axis_values.get("position", "")).lower()
if not text:
return ""
if _is_outercourse_text(role_graph, hard_item, composition, _axis_values_text(axis_values)):
if any(term in text for term in ("boobjob", "titjob", "breast sex", "breast-sex")):
return "breast-sex outercourse pose"
if any(term in text for term in ("testicle", "balls licking", "balls-licking", "balls and mouth")):
return "testicle-sucking outercourse pose"
if any(term in text for term in ("penis licking", "penis-licking", "tongue along", "tongue licking")):
return "penis-licking outercourse pose"
if any(term in text for term in ("footjob", "soles", "toes curled", "feet stroking")):
return "footjob outercourse pose"
return "non-penetrative outercourse pose"
if _is_toy_assisted_double_text(role_graph, hard_item, composition, _axis_values_text(axis_values)):
if "face-down ass-up" in text or "face-down" in text:
return "toy-assisted face-down rear-entry double-penetration pose"
@@ -887,7 +981,7 @@ def _hardcore_pose_anchor(role_graph: str, hard_item: str, composition: str = ""
return "three-body explicit sex pose"
if "group" in text or "orgy" in text:
return "multi-body explicit sex pose"
if "penetrat" in text or "thrust" in text:
if re.search(r"(?<!non-)penetrat|thrust", text):
return "hip-aligned penetrative sex pose"
return ""
@@ -1085,7 +1179,7 @@ def _hardcore_pose_arrangement(anchor: str, role_graph: str, hard_item: str, com
return "with all three adult bodies clearly placed around the central subject"
if "group" in text or "orgy" in text:
return "with each adult body readable in the shared sex act"
if "penetrat" in text or "thrust" in text:
if re.search(r"(?<!non-)penetrat|thrust", text):
return "with hips aligned and legs open around the contact point"
return ""
@@ -1158,7 +1252,7 @@ def _hardcore_item_detail(hard_item: str) -> str:
r"face-sitting cunnilingus",
r"pussy licking with thighs spread",
r"oral sex with tongue and fingers",
r"mouth on genitals with explicit contact",
r"oral contact with mouth on the visible genitals",
r"sixty-nine oral sex",
)
act_pattern = "|".join(act_patterns)
@@ -1621,7 +1715,7 @@ def _hardcore_action_sentence(
if arrangement and anchor_phrase and not _arrangement_duplicates_role(arrangement, role_graph):
anchor_phrase = f"{anchor_phrase} {arrangement}"
if role_graph and anchor_phrase:
sentence = f"In {anchor_phrase}, {role_graph}"
sentence = f"In {anchor_phrase}, {_lowercase_for_inline_join(role_graph)}"
elif role_graph:
sentence = role_graph
elif detail and anchor_phrase:
@@ -2063,7 +2157,7 @@ def _insta_pair_to_krea(row: dict[str, Any], detail_level: str, style_mode: str)
hard_action,
_pov_camera_phrase(pov_labels),
_natural_label_text(
_filter_pov_labeled_clauses(_natural_clothing_state(row.get("hardcore_clothing_state")), pov_labels),
_filter_pov_labeled_clauses(_natural_clothing_state(row.get("hardcore_clothing_state"), hard_action), pov_labels),
hard_labels,
),
hard_cast_prose,