Promote multi-person hardcore action routing
This commit is contained in:
@@ -55,6 +55,8 @@ ACTION_FAMILY_CAPTION_LABELS = {
|
|||||||
"outercourse": "non-penetrative action",
|
"outercourse": "non-penetrative action",
|
||||||
"oral": "oral action",
|
"oral": "oral action",
|
||||||
"penetration": "penetrative action",
|
"penetration": "penetrative action",
|
||||||
|
"threesome": "three-person action",
|
||||||
|
"group": "group action",
|
||||||
"toy_double": "toy-assisted double-contact action",
|
"toy_double": "toy-assisted double-contact action",
|
||||||
"climax": "climax action",
|
"climax": "climax action",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ ACTION_MANUAL = "manual"
|
|||||||
ACTION_OUTERCOURSE = "outercourse"
|
ACTION_OUTERCOURSE = "outercourse"
|
||||||
ACTION_ORAL = "oral"
|
ACTION_ORAL = "oral"
|
||||||
ACTION_PENETRATION = "penetration"
|
ACTION_PENETRATION = "penetration"
|
||||||
|
ACTION_THREESOME = "threesome"
|
||||||
|
ACTION_GROUP = "group"
|
||||||
ACTION_TOY_DOUBLE = "toy_double"
|
ACTION_TOY_DOUBLE = "toy_double"
|
||||||
ACTION_DEFAULT = "default"
|
ACTION_DEFAULT = "default"
|
||||||
|
|
||||||
@@ -43,6 +45,8 @@ HARDCORE_ACTION_FAMILY_CHOICES = {
|
|||||||
ACTION_OUTERCOURSE,
|
ACTION_OUTERCOURSE,
|
||||||
ACTION_ORAL,
|
ACTION_ORAL,
|
||||||
ACTION_PENETRATION,
|
ACTION_PENETRATION,
|
||||||
|
ACTION_THREESOME,
|
||||||
|
ACTION_GROUP,
|
||||||
ACTION_TOY_DOUBLE,
|
ACTION_TOY_DOUBLE,
|
||||||
ACTION_DEFAULT,
|
ACTION_DEFAULT,
|
||||||
}
|
}
|
||||||
@@ -66,6 +70,16 @@ def normalize_hardcore_action_family(value: Any, default: str = "") -> str:
|
|||||||
"anal_penetration": ACTION_ANAL,
|
"anal_penetration": ACTION_ANAL,
|
||||||
"outer_course": ACTION_OUTERCOURSE,
|
"outer_course": ACTION_OUTERCOURSE,
|
||||||
"outercourse_sex": ACTION_OUTERCOURSE,
|
"outercourse_sex": ACTION_OUTERCOURSE,
|
||||||
|
"three_person": ACTION_THREESOME,
|
||||||
|
"three_person_action": ACTION_THREESOME,
|
||||||
|
"threesome": ACTION_THREESOME,
|
||||||
|
"threesomes": ACTION_THREESOME,
|
||||||
|
"threeway": ACTION_THREESOME,
|
||||||
|
"three_way": ACTION_THREESOME,
|
||||||
|
"group": ACTION_GROUP,
|
||||||
|
"group_sex": ACTION_GROUP,
|
||||||
|
"group_sex_orgy": ACTION_GROUP,
|
||||||
|
"orgy": ACTION_GROUP,
|
||||||
"manual": ACTION_MANUAL,
|
"manual": ACTION_MANUAL,
|
||||||
"manual_stimulation": ACTION_MANUAL,
|
"manual_stimulation": ACTION_MANUAL,
|
||||||
"interaction": ACTION_FOREPLAY,
|
"interaction": ACTION_FOREPLAY,
|
||||||
@@ -143,6 +157,8 @@ def source_hardcore_action_family(
|
|||||||
"manual": ACTION_MANUAL,
|
"manual": ACTION_MANUAL,
|
||||||
"oral": ACTION_ORAL,
|
"oral": ACTION_ORAL,
|
||||||
"outercourse": ACTION_OUTERCOURSE,
|
"outercourse": ACTION_OUTERCOURSE,
|
||||||
|
"threesome": ACTION_THREESOME,
|
||||||
|
"group": ACTION_GROUP,
|
||||||
"climax": ACTION_CLIMAX,
|
"climax": ACTION_CLIMAX,
|
||||||
}
|
}
|
||||||
return source_mapping.get(family, inferred)
|
return source_mapping.get(family, inferred)
|
||||||
|
|||||||
@@ -525,7 +525,8 @@ def hardcore_position_template_required(config: dict[str, Any]) -> bool:
|
|||||||
|
|
||||||
def hardcore_allowed_subcategory_slugs(config: dict[str, Any]) -> set[str]:
|
def hardcore_allowed_subcategory_slugs(config: dict[str, Any]) -> set[str]:
|
||||||
family = normalize_hardcore_position_family(config.get("family"))
|
family = normalize_hardcore_position_family(config.get("family"))
|
||||||
allowed = set(HARDCORE_POSITION_FAMILY_SUBCATEGORIES.get(family, HARDCORE_POSITION_FAMILY_SUBCATEGORIES["any"]))
|
base_allowed = set(HARDCORE_POSITION_FAMILY_SUBCATEGORIES.get(family, HARDCORE_POSITION_FAMILY_SUBCATEGORIES["any"]))
|
||||||
|
allowed = set(base_allowed)
|
||||||
if not config.get("allow_penetration", True):
|
if not config.get("allow_penetration", True):
|
||||||
allowed.difference_update({"penetrative_sex", "anal_double_penetration", "threesomes", "group_sex_orgy"})
|
allowed.difference_update({"penetrative_sex", "anal_double_penetration", "threesomes", "group_sex_orgy"})
|
||||||
if not config.get("allow_foreplay", True):
|
if not config.get("allow_foreplay", True):
|
||||||
@@ -554,7 +555,11 @@ def hardcore_allowed_subcategory_slugs(config: dict[str, Any]) -> set[str]:
|
|||||||
allowed.discard("cumshot_climax")
|
allowed.discard("cumshot_climax")
|
||||||
if not config.get("allow_double", True) and family == "anal":
|
if not config.get("allow_double", True) and family == "anal":
|
||||||
allowed.add("anal_double_penetration")
|
allowed.add("anal_double_penetration")
|
||||||
return allowed or set(HARDCORE_POSITION_FAMILY_SUBCATEGORIES["any"])
|
if allowed:
|
||||||
|
return allowed
|
||||||
|
if family != "any":
|
||||||
|
return base_allowed
|
||||||
|
return set(HARDCORE_POSITION_FAMILY_SUBCATEGORIES["any"])
|
||||||
|
|
||||||
|
|
||||||
def is_hardcore_sexual_category(category: dict[str, Any]) -> bool:
|
def is_hardcore_sexual_category(category: dict[str, Any]) -> bool:
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ SDXL_ACTION_FAMILY_TAGS = {
|
|||||||
"outercourse": ("outercourse", "non-penetrative sex"),
|
"outercourse": ("outercourse", "non-penetrative sex"),
|
||||||
"oral": ("oral sex",),
|
"oral": ("oral sex",),
|
||||||
"penetration": ("penetrative sex", "penetration"),
|
"penetration": ("penetrative sex", "penetration"),
|
||||||
|
"threesome": ("threesome",),
|
||||||
|
"group": ("group sex",),
|
||||||
"toy_double": ("double penetration", "toy-assisted sex"),
|
"toy_double": ("double penetration", "toy-assisted sex"),
|
||||||
"climax": ("climax", "semen"),
|
"climax": ("climax", "semen"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,6 +113,29 @@ def _character_cast(*, pov_man: bool = False) -> str:
|
|||||||
)["character_cast"]
|
)["character_cast"]
|
||||||
|
|
||||||
|
|
||||||
|
def _character_cast_subjects(subjects: list[str] | tuple[str, ...]) -> str:
|
||||||
|
cast = ""
|
||||||
|
counts = {"woman": 0, "man": 0}
|
||||||
|
for subject in subjects:
|
||||||
|
subject = str(subject)
|
||||||
|
counts[subject] += 1
|
||||||
|
label = chr(ord("A") + counts[subject] - 1)
|
||||||
|
cast = pb.build_character_slot_json(
|
||||||
|
subject_type=subject,
|
||||||
|
label=label,
|
||||||
|
age="25-year-old adult" if subject == "woman" else "40-year-old adult",
|
||||||
|
ethnicity="western_european",
|
||||||
|
figure="balanced",
|
||||||
|
body="slim busty" if subject == "woman" else "average",
|
||||||
|
descriptor_detail="compact",
|
||||||
|
expression_intensity=0.55,
|
||||||
|
softcore_expression_intensity=0.35,
|
||||||
|
hardcore_expression_intensity=0.75,
|
||||||
|
character_cast=cast,
|
||||||
|
)["character_cast"]
|
||||||
|
return cast
|
||||||
|
|
||||||
|
|
||||||
def _random_character_cast() -> str:
|
def _random_character_cast() -> str:
|
||||||
cast = pb.build_character_slot_json(
|
cast = pb.build_character_slot_json(
|
||||||
subject_type="woman",
|
subject_type="woman",
|
||||||
@@ -302,6 +325,30 @@ HARDCORE_ROUTE_CASES = (
|
|||||||
"caption": ("anal action",),
|
"caption": ("anal action",),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "hardcore.single.threesome",
|
||||||
|
"subcategory": "Threesomes",
|
||||||
|
"focus": "threesome_only",
|
||||||
|
"family": "threesome",
|
||||||
|
"expected_route": {"action_family": "threesome", "position_family": "threesome"},
|
||||||
|
"expected_terms": {
|
||||||
|
"krea": ("three",),
|
||||||
|
"sdxl": ("threesome",),
|
||||||
|
"caption": ("three-person action",),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hardcore.single.group",
|
||||||
|
"subcategory": "Group sex and orgy",
|
||||||
|
"focus": "group_only",
|
||||||
|
"family": "group",
|
||||||
|
"expected_route": {"action_family": "group", "position_family": "group"},
|
||||||
|
"expected_terms": {
|
||||||
|
"krea": ("group",),
|
||||||
|
"sdxl": ("group sex",),
|
||||||
|
"caption": ("group action",),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "hardcore.single.climax",
|
"name": "hardcore.single.climax",
|
||||||
"subcategory": "Cumshot and climax",
|
"subcategory": "Cumshot and climax",
|
||||||
@@ -309,7 +356,7 @@ HARDCORE_ROUTE_CASES = (
|
|||||||
"family": "climax",
|
"family": "climax",
|
||||||
"expected_route": {"action_family": "climax", "position_family": "climax"},
|
"expected_route": {"action_family": "climax", "position_family": "climax"},
|
||||||
"expected_terms": {
|
"expected_terms": {
|
||||||
"krea": ("ejaculation",),
|
"krea": ("semen",),
|
||||||
"sdxl": ("climax", "semen"),
|
"sdxl": ("climax", "semen"),
|
||||||
"caption": ("climax action",),
|
"caption": ("climax action",),
|
||||||
},
|
},
|
||||||
@@ -734,6 +781,10 @@ def _regular_single_case(seed: int) -> dict[str, Any]:
|
|||||||
|
|
||||||
|
|
||||||
def _hardcore_single_case(seed: int, subcategory: str, focus: str, family: str) -> dict[str, Any]:
|
def _hardcore_single_case(seed: int, subcategory: str, focus: str, family: str) -> dict[str, Any]:
|
||||||
|
women_count, men_count, character_cast = {
|
||||||
|
"threesome": (1, 2, _character_cast_subjects(("woman", "man", "man"))),
|
||||||
|
"group": (2, 2, _character_cast_subjects(("woman", "woman", "man", "man"))),
|
||||||
|
}.get(family, (1, 1, _character_cast()))
|
||||||
return pb.build_prompt(
|
return pb.build_prompt(
|
||||||
category="Hardcore sexual poses",
|
category="Hardcore sexual poses",
|
||||||
subcategory=subcategory,
|
subcategory=subcategory,
|
||||||
@@ -754,9 +805,9 @@ def _hardcore_single_case(seed: int, subcategory: str, focus: str, family: str)
|
|||||||
extra_positive="",
|
extra_positive="",
|
||||||
extra_negative="",
|
extra_negative="",
|
||||||
seed_config=pb.build_seed_lock_config_json(base_seed=seed),
|
seed_config=pb.build_seed_lock_config_json(base_seed=seed),
|
||||||
women_count=1,
|
women_count=women_count,
|
||||||
men_count=1,
|
men_count=men_count,
|
||||||
character_cast=_character_cast(),
|
character_cast=character_cast,
|
||||||
hardcore_position_config=_position_filter(focus, family, []),
|
hardcore_position_config=_position_filter(focus, family, []),
|
||||||
location_config=_coworking_location_config(),
|
location_config=_coworking_location_config(),
|
||||||
camera_config=_orbit_camera(horizontal_angle=35, vertical_angle=0, zoom=6.5),
|
camera_config=_orbit_camera(horizontal_angle=35, vertical_angle=0, zoom=6.5),
|
||||||
|
|||||||
+68
-1
@@ -4015,6 +4015,10 @@ def smoke_caption_policy() -> None:
|
|||||||
)
|
)
|
||||||
row = {"action_family": "oral", "position_family": ""}
|
row = {"action_family": "oral", "position_family": ""}
|
||||||
_expect(caption_policy.metadata_action_label(row) == "oral action", "Caption action-family label changed")
|
_expect(caption_policy.metadata_action_label(row) == "oral action", "Caption action-family label changed")
|
||||||
|
row = {"action_family": "threesome", "position_family": ""}
|
||||||
|
_expect(caption_policy.metadata_action_label(row) == "three-person action", "Caption threesome action-family label changed")
|
||||||
|
row = {"action_family": "group", "position_family": ""}
|
||||||
|
_expect(caption_policy.metadata_action_label(row) == "group action", "Caption group action-family label changed")
|
||||||
row = {"action_family": "oral", "position_family": "Anal"}
|
row = {"action_family": "oral", "position_family": "Anal"}
|
||||||
_expect(caption_naturalizer._metadata_action_label(row) == "anal action", "Caption position-family label priority changed")
|
_expect(caption_naturalizer._metadata_action_label(row) == "anal action", "Caption position-family label priority changed")
|
||||||
browsing_caption, browsing_method = caption_naturalizer.naturalize_caption(
|
browsing_caption, browsing_method = caption_naturalizer.naturalize_caption(
|
||||||
@@ -4913,6 +4917,14 @@ def smoke_hardcore_position_config_policy() -> None:
|
|||||||
category_template_metadata.template_action_family({"action_family": "anal sex"}) == "anal",
|
category_template_metadata.template_action_family({"action_family": "anal sex"}) == "anal",
|
||||||
"Template action-family normalizer should accept anal aliases",
|
"Template action-family normalizer should accept anal aliases",
|
||||||
)
|
)
|
||||||
|
_expect(
|
||||||
|
category_template_metadata.template_action_family({"action_family": "three way"}) == "threesome",
|
||||||
|
"Template action-family normalizer should accept threesome aliases",
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
category_template_metadata.template_action_family({"action_family": "group sex"}) == "group",
|
||||||
|
"Template action-family normalizer should accept group aliases",
|
||||||
|
)
|
||||||
_expect(
|
_expect(
|
||||||
category_template_metadata.template_position_family({"position_family": "penetration"}) == "penetrative",
|
category_template_metadata.template_position_family({"position_family": "penetration"}) == "penetrative",
|
||||||
"Template position-family normalizer should accept action-style aliases",
|
"Template position-family normalizer should accept action-style aliases",
|
||||||
@@ -4965,6 +4977,26 @@ def smoke_hardcore_position_config_policy() -> None:
|
|||||||
_expect(filtered.get("allow_penetration") is False, "Hardcore outercourse focus should disable penetration")
|
_expect(filtered.get("allow_penetration") is False, "Hardcore outercourse focus should disable penetration")
|
||||||
_expect("outercourse_sex" in hardcore_position_config.hardcore_allowed_subcategory_slugs(filtered), "Allowed subcategories lost outercourse")
|
_expect("outercourse_sex" in hardcore_position_config.hardcore_allowed_subcategory_slugs(filtered), "Allowed subcategories lost outercourse")
|
||||||
_expect("oral_sex" not in hardcore_position_config.hardcore_allowed_subcategory_slugs(filtered), "Allowed subcategories should exclude oral")
|
_expect("oral_sex" not in hardcore_position_config.hardcore_allowed_subcategory_slugs(filtered), "Allowed subcategories should exclude oral")
|
||||||
|
strict_threesome = json.loads(
|
||||||
|
pb.build_hardcore_action_filter_json(
|
||||||
|
hardcore_position_config=pb.build_hardcore_position_pool_json(family="threesome"),
|
||||||
|
focus="threesome_only",
|
||||||
|
allow_toys=False,
|
||||||
|
allow_double=False,
|
||||||
|
allow_penetration=False,
|
||||||
|
allow_foreplay=False,
|
||||||
|
allow_interaction=False,
|
||||||
|
allow_manual=False,
|
||||||
|
allow_oral=False,
|
||||||
|
allow_outercourse=False,
|
||||||
|
allow_anal=False,
|
||||||
|
allow_climax=False,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
hardcore_position_config.hardcore_allowed_subcategory_slugs(strict_threesome) == {"threesomes"},
|
||||||
|
"Specific hardcore family filter should not widen to the full pool when boolean filters empty it",
|
||||||
|
)
|
||||||
action_only = json.loads(
|
action_only = json.loads(
|
||||||
hardcore_position_config.build_hardcore_action_filter_json(
|
hardcore_position_config.build_hardcore_action_filter_json(
|
||||||
focus="outercourse_only",
|
focus="outercourse_only",
|
||||||
@@ -5062,6 +5094,14 @@ def smoke_hardcore_position_config_policy() -> None:
|
|||||||
"generic contact",
|
"generic contact",
|
||||||
)
|
)
|
||||||
_expect(source_action_family == "outercourse", "Source action-family fallback should accept hyphenated source aliases")
|
_expect(source_action_family == "outercourse", "Source action-family fallback should accept hyphenated source aliases")
|
||||||
|
_expect(
|
||||||
|
hardcore_action_metadata.source_hardcore_action_family("threesome", "", "three-body contact") == "threesome",
|
||||||
|
"Source action-family fallback should accept threesome source family",
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
hardcore_action_metadata.source_hardcore_action_family("group", "", "group sex contact") == "group",
|
||||||
|
"Source action-family fallback should accept group source family",
|
||||||
|
)
|
||||||
default_action_route = row_route_metadata.resolve_action_position_route(
|
default_action_route = row_route_metadata.resolve_action_position_route(
|
||||||
is_pose_category=True,
|
is_pose_category=True,
|
||||||
subcategory={"slug": "anal_double_penetration"},
|
subcategory={"slug": "anal_double_penetration"},
|
||||||
@@ -5550,6 +5590,31 @@ def smoke_hardcore_category_routes() -> None:
|
|||||||
_expect(sdxl_tag in (sdxl.get("sdxl_prompt") or "").lower(), f"{name} SDXL prompt did not include family tag {sdxl_tag!r}")
|
_expect(sdxl_tag in (sdxl.get("sdxl_prompt") or "").lower(), f"{name} SDXL prompt did not include family tag {sdxl_tag!r}")
|
||||||
caption, _method = caption_naturalizer.naturalize_caption("", metadata_json=_json(row), trigger=Trigger, include_trigger=True)
|
caption, _method = caption_naturalizer.naturalize_caption("", metadata_json=_json(row), trigger=Trigger, include_trigger=True)
|
||||||
_expect(caption_label in caption.lower(), f"{name} caption did not include family label {caption_label!r}")
|
_expect(caption_label in caption.lower(), f"{name} caption did not include family label {caption_label!r}")
|
||||||
|
multi_cases = [
|
||||||
|
("hardcore_threesome", "Threesomes", "threesome_only", "threesome", {"threesome", "toy_double"}, "threesome", "three-person action", 1, 2),
|
||||||
|
("hardcore_group", "Group sex and orgy", "group_only", "group", {"group", "toy_double"}, "group sex", "group action", 2, 2),
|
||||||
|
]
|
||||||
|
for index, (name, subcategory, focus, position_family, action_families, sdxl_tag, caption_label, women_count, men_count) in enumerate(multi_cases, start=1151):
|
||||||
|
subjects = ["woman"] * women_count + ["man"] * men_count
|
||||||
|
row = _prompt_row(
|
||||||
|
name=name,
|
||||||
|
category="Hardcore sexual poses",
|
||||||
|
subcategory=subcategory,
|
||||||
|
seed=index,
|
||||||
|
character_cast=_character_cast_subjects(subjects),
|
||||||
|
women_count=women_count,
|
||||||
|
men_count=men_count,
|
||||||
|
hardcore_position_config=_action_filter(focus),
|
||||||
|
)
|
||||||
|
_expect_custom_row(row, name)
|
||||||
|
_expect(row.get("subject_type") == "configured_cast", f"{name} should use configured cast")
|
||||||
|
_expect(row.get("position_family") == position_family, f"{name} position_family mismatch: {row.get('position_family')}")
|
||||||
|
_expect(row.get("action_family") in action_families, f"{name} action_family mismatch: {row.get('action_family')}")
|
||||||
|
_expect_formatter_outputs(row, name, target="single")
|
||||||
|
sdxl = sdxl_formatter.format_sdxl_prompt("", metadata_json=_json(row), target="single", trigger=SdxlTrigger, prepend_trigger=True)
|
||||||
|
_expect(sdxl_tag in (sdxl.get("sdxl_prompt") or "").lower(), f"{name} SDXL prompt did not include family tag {sdxl_tag!r}")
|
||||||
|
caption, _method = caption_naturalizer.naturalize_caption("", metadata_json=_json(row), trigger=Trigger, include_trigger=True)
|
||||||
|
_expect(caption_label in caption.lower(), f"{name} caption did not include family label {caption_label!r}")
|
||||||
annotated_row = None
|
annotated_row = None
|
||||||
for seed in range(1801, 1841):
|
for seed in range(1801, 1841):
|
||||||
row = _prompt_row(
|
row = _prompt_row(
|
||||||
@@ -7071,6 +7136,8 @@ def smoke_fallback_role_graph_routes() -> None:
|
|||||||
)
|
)
|
||||||
_expect_custom_row(row, name)
|
_expect_custom_row(row, name)
|
||||||
_expect(row.get("position_family") == family, f"{name} position_family mismatch: {row.get('position_family')}")
|
_expect(row.get("position_family") == family, f"{name} position_family mismatch: {row.get('position_family')}")
|
||||||
|
if family == "threesome":
|
||||||
|
_expect(row.get("action_family") == "threesome", f"{name} action_family should be threesome")
|
||||||
_expect(position_key in (row.get("position_keys") or []), f"{name} lost position key {position_key!r}")
|
_expect(position_key in (row.get("position_keys") or []), f"{name} lost position key {position_key!r}")
|
||||||
role_graph = _expect_text(f"{name}.source_role_graph", row.get("source_role_graph"), 30).lower()
|
role_graph = _expect_text(f"{name}.source_role_graph", row.get("source_role_graph"), 30).lower()
|
||||||
for term in role_terms:
|
for term in role_terms:
|
||||||
@@ -7844,7 +7911,7 @@ def smoke_seed_config_policy() -> None:
|
|||||||
def smoke_prompt_route_simulation_policy() -> None:
|
def smoke_prompt_route_simulation_policy() -> None:
|
||||||
report = prompt_route_simulation.run_simulation(seed=3901, include_prompts=False)
|
report = prompt_route_simulation.run_simulation(seed=3901, include_prompts=False)
|
||||||
summary = report.get("summary") or {}
|
summary = report.get("summary") or {}
|
||||||
_expect(summary.get("cases") == 11, "Prompt route simulation case count changed unexpectedly")
|
_expect(summary.get("cases") == 13, "Prompt route simulation case count changed unexpectedly")
|
||||||
_expect(summary.get("axis_checks") == 6, "Prompt route simulation lost axis check coverage")
|
_expect(summary.get("axis_checks") == 6, "Prompt route simulation lost axis check coverage")
|
||||||
_expect(summary.get("issues") == 0, f"Prompt route simulation reported issues: {report.get('issues')}")
|
_expect(summary.get("issues") == 0, f"Prompt route simulation reported issues: {report.get('issues')}")
|
||||||
cases = {case.get("name"): case for case in report.get("cases") or []}
|
cases = {case.get("name"): case for case in report.get("cases") or []}
|
||||||
|
|||||||
Reference in New Issue
Block a user