Align outercourse action routing

This commit is contained in:
2026-06-27 16:15:27 +02:00
parent ff6195473b
commit 002c3b79d4
10 changed files with 393 additions and 67 deletions
+38 -17
View File
@@ -8,10 +8,12 @@ try:
from . import category_library as category_policy
from . import category_template_metadata as template_policy
from . import generate_prompt_batches as g
from . import outercourse_action_policy as outercourse_policy
except ImportError: # Allows local smoke tests with top-level imports.
import category_library as category_policy
import category_template_metadata as template_policy
import generate_prompt_batches as g
import outercourse_action_policy as outercourse_policy
class SafeFormatDict(dict):
@@ -182,8 +184,8 @@ def oral_axis_values_for_context(values: list[Any], position: str, oral_act: str
def outercourse_acts_for_position(values: list[Any], position: str) -> list[Any]:
position_text = str(position or "").lower()
if not position_text:
action_kind = outercourse_policy.infer_outercourse_action_kind(position)
if action_kind == outercourse_policy.OUTERCOURSE_GENERIC:
return values
def act_text(value: Any) -> str:
@@ -193,22 +195,22 @@ def outercourse_acts_for_position(values: list[Any], position: str) -> list[Any]
matches = [value for value in values if predicate(act_text(value))]
return matches or values
if any(term in position_text for term in ("boobjob", "titjob", "breast-sex", "breast sex")):
if action_kind == outercourse_policy.OUTERCOURSE_BOOBJOB:
return filtered(lambda text: any(term in text for term in ("boobjob", "titjob", "breast sex", "breasts")))
if any(term in position_text for term in ("testicle", "balls")):
if action_kind == outercourse_policy.OUTERCOURSE_TESTICLE:
return filtered(lambda text: any(term in text for term in ("testicle", "balls")))
if "penis-licking" in position_text or "penis licking" in position_text:
if action_kind == outercourse_policy.OUTERCOURSE_PENIS_LICKING:
return filtered(lambda text: "licking" in text or "tongue" in text)
if "handjob" in position_text or "hand job" in position_text:
if action_kind == outercourse_policy.OUTERCOURSE_HANDJOB:
return filtered(lambda text: any(term in text for term in ("handjob", "hand job", "hand wrapped", "two-handed")))
if "footjob" in position_text:
if action_kind == outercourse_policy.OUTERCOURSE_FOOTJOB:
return filtered(lambda text: any(term in text for term in ("footjob", "feet", "soles", "toes")))
return values
def outercourse_axis_values_for_position(values: list[Any], position: str, axis_name: str) -> list[Any]:
position_text = str(position or "").lower()
if not position_text:
action_kind = outercourse_policy.infer_outercourse_action_kind(position)
if action_kind == outercourse_policy.OUTERCOURSE_GENERIC:
return values
axis_name = str(axis_name or "").lower()
if axis_name not in {"contact_detail", "hand_detail", "texture_detail", "visibility", "body_contact"}:
@@ -224,15 +226,25 @@ def outercourse_axis_values_for_position(values: list[Any], position: str, axis_
if any(term in value_text(value) for term in terms)
and not any(term in value_text(value) for term in excluded_terms)
]
return matches or values
if matches:
return matches
if excluded_terms:
non_excluded = [
value
for value in values
if not any(term in value_text(value) for term in excluded_terms)
]
if non_excluded:
return non_excluded
return values
if any(term in position_text for term in ("boobjob", "titjob", "breast-sex", "breast sex")):
if action_kind == outercourse_policy.OUTERCOURSE_BOOBJOB:
by_axis = {
"contact_detail": ("compressed", "glans", "breast", "breasts", "soft tissue", "skin visibly"),
"hand_detail": ("breast", "breasts", "fingers"),
"texture_detail": ("compression", "soft flesh", "skin", "flesh", "asymmetry"),
"visibility": ("breast", "breasts", "glans", "shaft"),
"body_contact": ("torso", "body angled", "shoulders", "hips"),
"body_contact": ("torso", "body angle", "body angled", "shoulders", "hips"),
}
excluded_by_axis = {
"contact_detail": ("hand wrapped", "fingers and palm", "soles", "toes", "balls", "tongue"),
@@ -245,7 +257,7 @@ def outercourse_axis_values_for_position(values: list[Any], position: str, axis_
by_axis.get(axis_name, ("breast", "breasts", "shaft")),
excluded_by_axis.get(axis_name, ()),
)
if any(term in position_text for term in ("testicle", "balls")):
if action_kind == outercourse_policy.OUTERCOURSE_TESTICLE:
by_axis = {
"contact_detail": ("balls", "lips", "tongue", "wet"),
"hand_detail": ("balls", "base", "thigh"),
@@ -254,7 +266,7 @@ def outercourse_axis_values_for_position(values: list[Any], position: str, axis_
"body_contact": ("torso", "shoulders", "head tucked", "base of the penis", "knees", "thigh"),
}
return filtered(by_axis.get(axis_name, ("balls", "mouth", "tongue")))
if "penis-licking" in position_text or "penis licking" in position_text:
if action_kind == outercourse_policy.OUTERCOURSE_PENIS_LICKING:
by_axis = {
"contact_detail": ("tongue", "lips", "glans", "shaft", "wet"),
"hand_detail": ("base", "penis", "thigh"),
@@ -263,7 +275,7 @@ def outercourse_axis_values_for_position(values: list[Any], position: str, axis_
"body_contact": ("head low", "face directly", "torso", "pelvis", "base of the penis", "hips", "body angled"),
}
return filtered(by_axis.get(axis_name, ("tongue", "glans", "shaft")))
if "handjob" in position_text or "hand job" in position_text:
if action_kind == outercourse_policy.OUTERCOURSE_HANDJOB:
by_axis = {
"contact_detail": ("hand", "fingers", "palm", "shaft", "glans"),
"hand_detail": ("hand", "hands", "shaft", "penis"),
@@ -271,8 +283,17 @@ def outercourse_axis_values_for_position(values: list[Any], position: str, axis_
"visibility": ("hand", "penis", "shaft", "glans"),
"body_contact": ("hips", "knees", "body angle"),
}
return filtered(by_axis.get(axis_name, ("hand", "penis", "shaft")))
if "footjob" in position_text:
excluded_by_axis = {
"contact_detail": ("balls", "soles", "toes", "breast", "breasts", "tongue"),
"hand_detail": ("balls", "thigh", "ankles", "breast", "breasts"),
"texture_detail": ("toes", "soles", "tongue", "breast", "breasts"),
"visibility": ("balls", "feet", "soles", "breast", "mouth"),
}
return filtered(
by_axis.get(axis_name, ("hand", "penis", "shaft")),
excluded_by_axis.get(axis_name, ()),
)
if action_kind == outercourse_policy.OUTERCOURSE_FOOTJOB:
by_axis = {
"contact_detail": ("soles", "toes"),
"hand_detail": ("ankles", "thighs"),