Centralize softcore pair wording
This commit is contained in:
@@ -462,7 +462,7 @@ cleanup.
|
|||||||
|
|
||||||
When connected to `SxCP Insta/OF Prompt Pair` metadata, the naturalizer emits a
|
When connected to `SxCP Insta/OF Prompt Pair` metadata, the naturalizer emits a
|
||||||
single combined natural caption with the shared descriptor plus separate
|
single combined natural caption with the shared descriptor plus separate
|
||||||
softcore and hardcore version descriptions. It uses the final selected
|
softcore and hardcore side descriptions. It uses the final selected
|
||||||
expression and composition from the generated rows, including any expression
|
expression and composition from the generated rows, including any expression
|
||||||
pool and intensity settings.
|
pool and intensity settings.
|
||||||
Set `target=softcore` or `target=hardcore` to emit only one side of the pair for
|
Set `target=softcore` or `target=hardcore` to emit only one side of the pair for
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ class CaptionMetadataRouteDependencies:
|
|||||||
natural_cast_descriptor_text: Callable[[str], str]
|
natural_cast_descriptor_text: Callable[[str], str]
|
||||||
cast_labels: Callable[[str], list[str]]
|
cast_labels: Callable[[str], list[str]]
|
||||||
natural_label_text: Callable[[Any, list[str]], str]
|
natural_label_text: Callable[[Any, list[str]], str]
|
||||||
|
softcore_caption_setup_phrase: Callable[..., str]
|
||||||
metadata_to_prose: Callable[..., tuple[str, str]]
|
metadata_to_prose: Callable[..., tuple[str, str]]
|
||||||
|
|
||||||
|
|
||||||
@@ -352,10 +353,12 @@ def insta_of_pair_from_row_result(
|
|||||||
if cast_descriptor_text and not same_soft_cast:
|
if cast_descriptor_text and not same_soft_cast:
|
||||||
parts.append(deps.natural_cast_descriptor_text(cast_descriptor_text))
|
parts.append(deps.natural_cast_descriptor_text(cast_descriptor_text))
|
||||||
if same_soft_cast and include_soft:
|
if same_soft_cast and include_soft:
|
||||||
if target == "auto":
|
parts.append(
|
||||||
parts.append("The softcore version keeps the same adult cast present together in a non-explicit teaser setup")
|
deps.softcore_caption_setup_phrase(
|
||||||
else:
|
same_cast=True,
|
||||||
parts.append("The same adult cast is present together in a non-explicit teaser setup")
|
target_auto=target == "auto",
|
||||||
|
)
|
||||||
|
)
|
||||||
partner_styling = row.get("softcore_partner_styling")
|
partner_styling = row.get("softcore_partner_styling")
|
||||||
if isinstance(partner_styling, dict):
|
if isinstance(partner_styling, dict):
|
||||||
outfits = partner_styling.get("outfits")
|
outfits = partner_styling.get("outfits")
|
||||||
@@ -368,9 +371,9 @@ def insta_of_pair_from_row_result(
|
|||||||
if pose:
|
if pose:
|
||||||
parts.append(f"The shared softcore cast pose is {pose}")
|
parts.append(f"The shared softcore cast pose is {pose}")
|
||||||
if soft_text:
|
if soft_text:
|
||||||
parts.append(f"Softcore version: {soft_text}" if target == "auto" else soft_text)
|
parts.append(f"Softcore side: {soft_text}" if target == "auto" else soft_text)
|
||||||
if hard_text:
|
if hard_text:
|
||||||
parts.append(f"Hardcore version: {hard_text}" if target == "auto" else hard_text)
|
parts.append(f"Hardcore side: {hard_text}" if target == "auto" else hard_text)
|
||||||
if not parts:
|
if not parts:
|
||||||
return None
|
return None
|
||||||
return CaptionMetadataRoute(deps.join_sentences(parts), "metadata(insta_of_pair)")
|
return CaptionMetadataRoute(deps.join_sentences(parts), "metadata(insta_of_pair)")
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ try:
|
|||||||
from . import formatter_input as input_policy
|
from . import formatter_input as input_policy
|
||||||
from . import krea_cast as cast_policy
|
from . import krea_cast as cast_policy
|
||||||
from . import route_metadata as route_metadata_policy
|
from . import route_metadata as route_metadata_policy
|
||||||
|
from . import softcore_text_policy
|
||||||
except ImportError: # Allows local smoke tests with `python -c`.
|
except ImportError: # Allows local smoke tests with `python -c`.
|
||||||
import caption_metadata_routes
|
import caption_metadata_routes
|
||||||
import caption_policy
|
import caption_policy
|
||||||
import formatter_input as input_policy
|
import formatter_input as input_policy
|
||||||
import krea_cast as cast_policy
|
import krea_cast as cast_policy
|
||||||
import route_metadata as route_metadata_policy
|
import route_metadata as route_metadata_policy
|
||||||
|
import softcore_text_policy
|
||||||
|
|
||||||
|
|
||||||
OLD_TRIGGER = caption_policy.OLD_TRIGGER
|
OLD_TRIGGER = caption_policy.OLD_TRIGGER
|
||||||
@@ -300,5 +302,6 @@ def metadata_route_dependencies(
|
|||||||
natural_cast_descriptor_text=natural_cast_descriptor_text,
|
natural_cast_descriptor_text=natural_cast_descriptor_text,
|
||||||
cast_labels=cast_labels,
|
cast_labels=cast_labels,
|
||||||
natural_label_text=natural_label_text,
|
natural_label_text=natural_label_text,
|
||||||
|
softcore_caption_setup_phrase=softcore_text_policy.softcore_caption_setup_phrase,
|
||||||
metadata_to_prose=metadata_to_prose,
|
metadata_to_prose=metadata_to_prose,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -336,6 +336,9 @@ Already isolated:
|
|||||||
prose, descriptor-entry assembly, shared descriptors, cast-label cleanup,
|
prose, descriptor-entry assembly, shared descriptors, cast-label cleanup,
|
||||||
same-cast softcore descriptor text, partner styling, platform and level
|
same-cast softcore descriptor text, partner styling, platform and level
|
||||||
labels, softcore cast presence text, and hard cast summary text.
|
labels, softcore cast presence text, and hard cast summary text.
|
||||||
|
- shared softcore pair prose for solo/same-cast/POV presence, caption side
|
||||||
|
wording, and creator-shot teaser directives lives in
|
||||||
|
`softcore_text_policy.py`; pair, Krea, and caption routes delegate to it.
|
||||||
- pair-level camera routing lives in `pair_camera.py` behind
|
- pair-level camera routing lives in `pair_camera.py` behind
|
||||||
`InstaPairCameraRoute`, including soft/hard camera config selection,
|
`InstaPairCameraRoute`, including soft/hard camera config selection,
|
||||||
same-as-softcore mode, camera-detail override, same-room hard scene
|
same-as-softcore mode, camera-detail override, same-room hard scene
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ Core helper ownership:
|
|||||||
| `pair_builder.py` | Insta/OF pair route sequencing behind `InstaPairBuildRequest` and `InstaPairBuildDependencies`, including option/filter/seed/cast parsing handoff, soft/hard row, cast, camera, clothing, and final output adapter orchestration. |
|
| `pair_builder.py` | Insta/OF pair route sequencing behind `InstaPairBuildRequest` and `InstaPairBuildDependencies`, including option/filter/seed/cast parsing handoff, soft/hard row, cast, camera, clothing, and final output adapter orchestration. |
|
||||||
| `pair_rows.py` | Insta/OF soft/hard row creation behind `InstaPairRowsRoute`, softcore expression override resolution, Woman A slot context application, soft outfit/pose overrides, POV row fields, and legacy dict compatibility. |
|
| `pair_rows.py` | Insta/OF soft/hard row creation behind `InstaPairRowsRoute`, softcore expression override resolution, Woman A slot context application, soft outfit/pose overrides, POV row fields, and legacy dict compatibility. |
|
||||||
| `pair_cast.py` | Insta/OF descriptor prose, descriptor-entry assembly, shared descriptors, cast-label cleanup, same-cast softcore descriptor text, partner styling selection, cast-summary wording, platform/level labels, softcore cast presence text, and hard cast summary text. |
|
| `pair_cast.py` | Insta/OF descriptor prose, descriptor-entry assembly, shared descriptors, cast-label cleanup, same-cast softcore descriptor text, partner styling selection, cast-summary wording, platform/level labels, softcore cast presence text, and hard cast summary text. |
|
||||||
|
| `softcore_text_policy.py` | Shared softcore pair prose for solo/same-cast/POV cast presence, caption side setup wording, and creator-shot teaser style directives. |
|
||||||
| `pair_camera.py` | Insta/OF soft/hard camera route resolution behind `InstaPairCameraRoute`, same-as-softcore camera mode, camera-detail override, camera-aware composition mutation, POV camera suppression, synchronized row/root camera metadata, and legacy dict compatibility. |
|
| `pair_camera.py` | Insta/OF soft/hard camera route resolution behind `InstaPairCameraRoute`, same-as-softcore camera mode, camera-detail override, camera-aware composition mutation, POV camera suppression, synchronized row/root camera metadata, and legacy dict compatibility. |
|
||||||
| `pair_clothing.py` | Insta/OF clothing sentence formatting and hardcore clothing continuity behind `HardcorePairClothingRoute`, body-exposure scene cleanup, action-aware body-access flags, conflicting outfit-piece cleanup, configured/default visible-person clothing, final root clothing-state assembly, and legacy dict compatibility. |
|
| `pair_clothing.py` | Insta/OF clothing sentence formatting and hardcore clothing continuity behind `HardcorePairClothingRoute`, body-exposure scene cleanup, action-aware body-access flags, conflicting outfit-piece cleanup, configured/default visible-person clothing, final root clothing-state assembly, and legacy dict compatibility. |
|
||||||
| `pair_output.py` | Insta/OF final pair prompts, trigger preservation, negative prompts, captions, and root pair metadata assembly. |
|
| `pair_output.py` | Insta/OF final pair prompts, trigger preservation, negative prompts, captions, and root pair metadata assembly. |
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ try:
|
|||||||
from . import formatter_input as input_policy
|
from . import formatter_input as input_policy
|
||||||
from . import krea_format_route
|
from . import krea_format_route
|
||||||
from . import route_metadata as route_metadata_policy
|
from . import route_metadata as route_metadata_policy
|
||||||
|
from . import softcore_text_policy
|
||||||
from .krea_action_context import (
|
from .krea_action_context import (
|
||||||
is_close_foreplay_text as _is_close_foreplay_text,
|
is_close_foreplay_text as _is_close_foreplay_text,
|
||||||
is_outercourse_text as _is_outercourse_text,
|
is_outercourse_text as _is_outercourse_text,
|
||||||
@@ -43,6 +44,7 @@ except ImportError: # Allows local smoke tests with `python -c`.
|
|||||||
import formatter_input as input_policy
|
import formatter_input as input_policy
|
||||||
import krea_format_route
|
import krea_format_route
|
||||||
import route_metadata as route_metadata_policy
|
import route_metadata as route_metadata_policy
|
||||||
|
import softcore_text_policy
|
||||||
from krea_action_context import (
|
from krea_action_context import (
|
||||||
is_close_foreplay_text as _is_close_foreplay_text,
|
is_close_foreplay_text as _is_close_foreplay_text,
|
||||||
is_outercourse_text as _is_outercourse_text,
|
is_outercourse_text as _is_outercourse_text,
|
||||||
@@ -570,6 +572,7 @@ def _krea_pair_format_dependencies() -> krea_pair_formatter.KreaPairFormatDepend
|
|||||||
pov_camera_phrase=lambda labels: _pov_camera_phrase(labels),
|
pov_camera_phrase=lambda labels: _pov_camera_phrase(labels),
|
||||||
pov_soft_camera_phrase=lambda labels: _pov_camera_phrase(labels, softcore=True),
|
pov_soft_camera_phrase=lambda labels: _pov_camera_phrase(labels, softcore=True),
|
||||||
pov_composition_text=_pov_composition_text,
|
pov_composition_text=_pov_composition_text,
|
||||||
|
softcore_cast_presence_phrase=softcore_text_policy.softcore_cast_presence_phrase,
|
||||||
natural_clothing_state=_natural_clothing_state,
|
natural_clothing_state=_natural_clothing_state,
|
||||||
composition_phrase=_composition_phrase,
|
composition_phrase=_composition_phrase,
|
||||||
paragraph=_paragraph,
|
paragraph=_paragraph,
|
||||||
|
|||||||
+7
-11
@@ -47,6 +47,7 @@ class KreaPairFormatDependencies:
|
|||||||
pov_camera_phrase: Callable[[list[str]], str]
|
pov_camera_phrase: Callable[[list[str]], str]
|
||||||
pov_soft_camera_phrase: Callable[[list[str]], str]
|
pov_soft_camera_phrase: Callable[[list[str]], str]
|
||||||
pov_composition_text: Callable[[Any, list[str]], str]
|
pov_composition_text: Callable[[Any, list[str]], str]
|
||||||
|
softcore_cast_presence_phrase: Callable[..., str]
|
||||||
natural_clothing_state: Callable[[Any, str], str]
|
natural_clothing_state: Callable[[Any, str], str]
|
||||||
composition_phrase: Callable[..., str]
|
composition_phrase: Callable[..., str]
|
||||||
paragraph: Callable[[list[str]], str]
|
paragraph: Callable[[list[str]], str]
|
||||||
@@ -134,17 +135,12 @@ def format_insta_pair_result(request: KreaPairFormatRequest, deps: KreaPairForma
|
|||||||
hard_output_composition = deps.pov_composition_text(hard_composition, pov_labels)
|
hard_output_composition = deps.pov_composition_text(hard_composition, pov_labels)
|
||||||
same_soft_cast = options.get("softcore_cast") == "same_as_hardcore"
|
same_soft_cast = options.get("softcore_cast") == "same_as_hardcore"
|
||||||
soft_output_composition = deps.pov_composition_text(soft.get("composition"), pov_labels if same_soft_cast else [])
|
soft_output_composition = deps.pov_composition_text(soft.get("composition"), pov_labels if same_soft_cast else [])
|
||||||
if same_soft_cast and pov_labels:
|
soft_cast_presence = deps.softcore_cast_presence_phrase(
|
||||||
soft_cast_presence = (
|
same_cast=same_soft_cast,
|
||||||
"the woman is framed from the POV participant's first-person camera in a soft creator-teaser pose, "
|
pov_labels=pov_labels if same_soft_cast else [],
|
||||||
"with the POV participant kept off-camera as the viewpoint and implied by camera position or foreground cues"
|
cast_label=deps.label_join(soft_labels),
|
||||||
)
|
woman_label="the woman",
|
||||||
else:
|
)
|
||||||
soft_cast_presence = (
|
|
||||||
f"{deps.label_join(soft_labels)} share the frame in a soft creator-teaser pose"
|
|
||||||
if same_soft_cast
|
|
||||||
else "The image focuses on the woman alone"
|
|
||||||
)
|
|
||||||
partner_styling = row.get("softcore_partner_styling")
|
partner_styling = row.get("softcore_partner_styling")
|
||||||
if isinstance(partner_styling, dict):
|
if isinstance(partner_styling, dict):
|
||||||
outfits = partner_styling.get("outfits")
|
outfits = partner_styling.get("outfits")
|
||||||
|
|||||||
+8
-9
@@ -7,11 +7,13 @@ try:
|
|||||||
from . import character_profile as character_profile_policy
|
from . import character_profile as character_profile_policy
|
||||||
from . import pair_clothing
|
from . import pair_clothing
|
||||||
from . import pair_options
|
from . import pair_options
|
||||||
|
from . import softcore_text_policy
|
||||||
except ImportError: # Allows local smoke tests with top-level imports.
|
except ImportError: # Allows local smoke tests with top-level imports.
|
||||||
import cast_context as cast_context_policy
|
import cast_context as cast_context_policy
|
||||||
import character_profile as character_profile_policy
|
import character_profile as character_profile_policy
|
||||||
import pair_clothing
|
import pair_clothing
|
||||||
import pair_options
|
import pair_options
|
||||||
|
import softcore_text_policy
|
||||||
|
|
||||||
|
|
||||||
AxisRng = Callable[[dict[str, int], str, int, int], Any]
|
AxisRng = Callable[[dict[str, int], str, int, int], Any]
|
||||||
@@ -264,16 +266,13 @@ def resolve_insta_pair_cast_context(
|
|||||||
else f"soft creator-teaser setup with {cast_summary_phrase(hard_women_count, hard_men_count)}"
|
else f"soft creator-teaser setup with {cast_summary_phrase(hard_women_count, hard_men_count)}"
|
||||||
)
|
)
|
||||||
soft_cast_presence = (
|
soft_cast_presence = (
|
||||||
(
|
softcore_text_policy.softcore_cast_presence_phrase(
|
||||||
"Frame Woman A from the POV participant's first-person camera in a soft creator-teaser setup; "
|
same_cast=same_softcore_cast,
|
||||||
"keep the POV participant off-camera as the viewpoint and implied by camera perspective or foreground cues. "
|
pov_labels=pov_character_labels,
|
||||||
)
|
cast_label="Woman A and the listed partners",
|
||||||
if same_softcore_cast and pov_character_labels
|
woman_label="Woman A",
|
||||||
else (
|
|
||||||
"Place Woman A and the listed partners together in a soft creator-teaser pose. "
|
|
||||||
if same_softcore_cast
|
|
||||||
else "Keep the softcore version focused on Woman A alone. "
|
|
||||||
)
|
)
|
||||||
|
+ ". "
|
||||||
)
|
)
|
||||||
soft_cast_styling_sentence = (
|
soft_cast_styling_sentence = (
|
||||||
f"Partner softcore styling: {soft_partner_outfit_text}. Cast pose: {soft_partner_styling['pose']}. "
|
f"Partner softcore styling: {soft_partner_outfit_text}. Cast pose: {soft_partner_styling['pose']}. "
|
||||||
|
|||||||
+3
-1
@@ -4,8 +4,10 @@ from typing import Any, Callable
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from . import row_normalization as row_policy
|
from . import row_normalization as row_policy
|
||||||
|
from . import softcore_text_policy
|
||||||
except ImportError: # Allows local smoke tests with `python tools/prompt_smoke.py`.
|
except ImportError: # Allows local smoke tests with `python tools/prompt_smoke.py`.
|
||||||
import row_normalization as row_policy
|
import row_normalization as row_policy
|
||||||
|
import softcore_text_policy
|
||||||
|
|
||||||
|
|
||||||
def _labeled_expression_sentence(label: str, expression: Any) -> str:
|
def _labeled_expression_sentence(label: str, expression: Any) -> str:
|
||||||
@@ -84,7 +86,7 @@ def assemble_insta_pair_metadata(
|
|||||||
f"{_labeled_expression_sentence('Facial expression', soft_row.get('expression'))}"
|
f"{_labeled_expression_sentence('Facial expression', soft_row.get('expression'))}"
|
||||||
f"Composition: {soft_row['composition']}. "
|
f"Composition: {soft_row['composition']}. "
|
||||||
f"{soft_camera_sentence}"
|
f"{soft_camera_sentence}"
|
||||||
"Keep the softcore version seductive, creator-shot, and styled as a soft teaser. "
|
f"{softcore_text_policy.softcore_style_directive()} "
|
||||||
f"{soft_row['positive_suffix']}."
|
f"{soft_row['positive_suffix']}."
|
||||||
)
|
)
|
||||||
hard_prompt = (
|
hard_prompt = (
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
def _clean(value: Any) -> str:
|
||||||
|
return " ".join(str(value or "").strip().split())
|
||||||
|
|
||||||
|
|
||||||
|
def softcore_cast_presence_phrase(
|
||||||
|
*,
|
||||||
|
same_cast: bool,
|
||||||
|
pov_labels: list[str] | tuple[str, ...] | None = None,
|
||||||
|
cast_label: str = "",
|
||||||
|
woman_label: str = "the woman",
|
||||||
|
) -> str:
|
||||||
|
pov_labels = [str(label) for label in (pov_labels or []) if str(label).strip()]
|
||||||
|
cast_label = _clean(cast_label)
|
||||||
|
woman_label = _clean(woman_label) or "the woman"
|
||||||
|
if same_cast and pov_labels:
|
||||||
|
return (
|
||||||
|
f"{woman_label} is framed from the POV participant's first-person creator camera, "
|
||||||
|
"with the POV participant implied by camera position or foreground body cues"
|
||||||
|
)
|
||||||
|
if same_cast:
|
||||||
|
visible_cast = cast_label or "the named cast"
|
||||||
|
verb = "share" if " and " in visible_cast or "," in visible_cast else "shares"
|
||||||
|
return f"{visible_cast} {verb} a styled creator-teaser frame"
|
||||||
|
return f"solo creator frame with {woman_label} as the only visible subject"
|
||||||
|
|
||||||
|
|
||||||
|
def softcore_caption_setup_phrase(*, same_cast: bool, target_auto: bool = False) -> str:
|
||||||
|
if same_cast:
|
||||||
|
return (
|
||||||
|
"The softcore side keeps the same adult cast together in a styled creator setup"
|
||||||
|
if target_auto
|
||||||
|
else "The same adult cast shares a styled creator setup"
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
"The softcore side is a solo styled creator setup"
|
||||||
|
if target_auto
|
||||||
|
else "Solo styled creator setup"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def softcore_style_directive() -> str:
|
||||||
|
return "Use seductive creator-shot teaser styling."
|
||||||
+30
-6
@@ -145,6 +145,21 @@ def _expect_no_duplicate_comma_items(name: str, value: Any) -> None:
|
|||||||
_expect(not duplicates, f"{name} has duplicate comma items: {duplicates[:5]}")
|
_expect(not duplicates, f"{name} has duplicate comma items: {duplicates[:5]}")
|
||||||
|
|
||||||
|
|
||||||
|
def _expect_no_softcore_noise(name: str, value: Any) -> None:
|
||||||
|
text = str(value or "").lower()
|
||||||
|
noisy = (
|
||||||
|
"the image focuses",
|
||||||
|
"softcore version",
|
||||||
|
"non-explicit teaser setup",
|
||||||
|
"no sex act",
|
||||||
|
"genital contact",
|
||||||
|
"keep the softcore version",
|
||||||
|
"focused on woman a alone",
|
||||||
|
)
|
||||||
|
found = [phrase for phrase in noisy if phrase in text]
|
||||||
|
_expect(not found, f"{name} has softcore prompt noise: {found}")
|
||||||
|
|
||||||
|
|
||||||
def _trigger_count(text: str, trigger: str) -> int:
|
def _trigger_count(text: str, trigger: str) -> int:
|
||||||
return len(re.findall(rf"(?<![a-z0-9_]){re.escape(trigger)}(?![a-z0-9_])", text, flags=re.IGNORECASE))
|
return len(re.findall(rf"(?<![a-z0-9_]){re.escape(trigger)}(?![a-z0-9_])", text, flags=re.IGNORECASE))
|
||||||
|
|
||||||
@@ -3850,10 +3865,10 @@ def smoke_caption_metadata_routes() -> None:
|
|||||||
_expect(hard_route is not None, "Caption pair hardcore target did not match")
|
_expect(hard_route is not None, "Caption pair hardcore target did not match")
|
||||||
assert soft_route is not None
|
assert soft_route is not None
|
||||||
assert hard_route is not None
|
assert hard_route is not None
|
||||||
_expect("Softcore version:" not in soft_route.prose, "Caption softcore target should not keep combined pair labels")
|
_expect("Softcore side:" not in soft_route.prose, "Caption softcore target should not keep combined pair labels")
|
||||||
_expect("Hardcore version:" not in soft_route.prose, "Caption softcore target should not include hard label")
|
_expect("Hardcore side:" not in soft_route.prose, "Caption softcore target should not include hard label")
|
||||||
_expect("Softcore version:" not in hard_route.prose, "Caption hardcore target should not include soft label")
|
_expect("Softcore side:" not in hard_route.prose, "Caption hardcore target should not include soft label")
|
||||||
_expect("Hardcore version:" not in hard_route.prose, "Caption hardcore target should not keep combined pair labels")
|
_expect("Hardcore side:" not in hard_route.prose, "Caption hardcore target should not keep combined pair labels")
|
||||||
_expect(soft_route.prose != hard_route.prose, "Caption pair soft/hard targets should produce distinct prose")
|
_expect(soft_route.prose != hard_route.prose, "Caption pair soft/hard targets should produce distinct prose")
|
||||||
public_hard, public_hard_method = caption_naturalizer.naturalize_caption(
|
public_hard, public_hard_method = caption_naturalizer.naturalize_caption(
|
||||||
"",
|
"",
|
||||||
@@ -5368,6 +5383,12 @@ def smoke_insta_pair() -> None:
|
|||||||
)
|
)
|
||||||
_expect_pair(pair, "insta_pair_same_cast")
|
_expect_pair(pair, "insta_pair_same_cast")
|
||||||
_expect(pair["softcore_row"].get("scene_text") == pair["hardcore_row"].get("scene_text"), "pair scene continuity broke")
|
_expect(pair["softcore_row"].get("scene_text") == pair["hardcore_row"].get("scene_text"), "pair scene continuity broke")
|
||||||
|
_expect_no_softcore_noise("insta_pair_same_cast.softcore_prompt", pair.get("softcore_prompt"))
|
||||||
|
_expect("styled creator-teaser frame" in str(pair.get("softcore_prompt", "")).lower(), "pair softcore prompt lost clean cast-presence wording")
|
||||||
|
krea_soft = krea_formatter.format_krea2_prompt("", metadata_json=_json(pair), target="softcore")
|
||||||
|
krea_soft_prompt = _expect_text("insta_pair_same_cast.krea_soft_prompt", krea_soft.get("krea_prompt"), 40)
|
||||||
|
_expect_no_softcore_noise("insta_pair_same_cast.krea_soft_prompt", krea_soft_prompt)
|
||||||
|
_expect("styled creator-teaser frame" in krea_soft_prompt.lower(), "Krea softcore prompt lost clean same-cast wording")
|
||||||
clothing_state = _clean_key(pair.get("hardcore_clothing_state"))
|
clothing_state = _clean_key(pair.get("hardcore_clothing_state"))
|
||||||
_expect("body is fully exposed" in clothing_state, "explicit nude pair should keep body exposure state")
|
_expect("body is fully exposed" in clothing_state, "explicit nude pair should keep body exposure state")
|
||||||
_expect("teaser outfit detail" not in clothing_state, "explicit nude pair should not repeat softcore outfit detail")
|
_expect("teaser outfit detail" not in clothing_state, "explicit nude pair should not repeat softcore outfit detail")
|
||||||
@@ -6546,6 +6567,8 @@ def smoke_formatter_metadata_fixtures() -> None:
|
|||||||
krea_hard = _expect_text("fixture_external_pair.krea_hard", krea_pair.get("krea_hardcore_prompt"), 40).lower()
|
krea_hard = _expect_text("fixture_external_pair.krea_hard", krea_pair.get("krea_hardcore_prompt"), 40).lower()
|
||||||
_expect(krea_pair.get("method") == "metadata_json:krea2(insta_of_pair)", "External pair Krea route changed method")
|
_expect(krea_pair.get("method") == "metadata_json:krea2(insta_of_pair)", "External pair Krea route changed method")
|
||||||
_expect("black buttoned shirt" in krea_soft, "External pair Krea soft route lost embedded partner styling")
|
_expect("black buttoned shirt" in krea_soft, "External pair Krea soft route lost embedded partner styling")
|
||||||
|
_expect_no_softcore_noise("fixture_external_pair.krea_soft", krea_pair.get("krea_softcore_prompt"))
|
||||||
|
_expect("styled creator-teaser frame" in krea_soft, "External pair Krea soft route lost clean cast-presence wording")
|
||||||
_expect("red satin lingerie set" in krea_hard, "External pair Krea hard route lost embedded clothing state")
|
_expect("red satin lingerie set" in krea_hard, "External pair Krea hard route lost embedded clothing state")
|
||||||
_expect("row hard right-side view" in krea_hard, "External pair Krea hard route lost embedded camera directive")
|
_expect("row hard right-side view" in krea_hard, "External pair Krea hard route lost embedded camera directive")
|
||||||
_expect_no_duplicate_comma_items("fixture_external_pair.krea_negative", krea_pair.get("negative_prompt"))
|
_expect_no_duplicate_comma_items("fixture_external_pair.krea_negative", krea_pair.get("negative_prompt"))
|
||||||
@@ -6578,8 +6601,9 @@ def smoke_formatter_metadata_fixtures() -> None:
|
|||||||
_expect(method == "metadata_json:metadata(insta_of_pair)", "External pair caption route changed method")
|
_expect(method == "metadata_json:metadata(insta_of_pair)", "External pair caption route changed method")
|
||||||
_expect_trigger_once("fixture_external_pair.caption", caption, Trigger)
|
_expect_trigger_once("fixture_external_pair.caption", caption, Trigger)
|
||||||
_expect("black buttoned shirt" in caption_text, "External pair caption route lost embedded partner styling")
|
_expect("black buttoned shirt" in caption_text, "External pair caption route lost embedded partner styling")
|
||||||
_expect("softcore version" in caption_text, "External pair caption route lost softcore side")
|
_expect("softcore side" in caption_text, "External pair caption route lost softcore side")
|
||||||
_expect("hardcore version" in caption_text, "External pair caption route lost hardcore side")
|
_expect("hardcore side" in caption_text, "External pair caption route lost hardcore side")
|
||||||
|
_expect("softcore version" not in caption_text and "hardcore version" not in caption_text, "External pair caption kept version labels")
|
||||||
|
|
||||||
generated = _prompt_row(
|
generated = _prompt_row(
|
||||||
name="fixture_generated_formatter_invariants",
|
name="fixture_generated_formatter_invariants",
|
||||||
|
|||||||
Reference in New Issue
Block a user