diff --git a/categories/krea2_pov_pose_variants.json b/categories/krea2_pov_pose_variants.json index c5eb763..20ad0e5 100644 --- a/categories/krea2_pov_pose_variants.json +++ b/categories/krea2_pov_pose_variants.json @@ -399,6 +399,8 @@ "viewer abdomen, shorts, thighs, and feet frame the lower foreground", "shaft is a short centered vertical column", "one woman kneels directly below the viewer between his feet", + "her mouth seals around the centered shaft", + "one hand wraps the base", "hair crown, forehead, shoulders, hands, and knees are visible from above", "desk legs, chair wheels, carpet texture, and floor seams act as top-down office anchors" ], diff --git a/krea_configured_cast_formatter.py b/krea_configured_cast_formatter.py index 532e491..b09954e 100644 --- a/krea_configured_cast_formatter.py +++ b/krea_configured_cast_formatter.py @@ -172,7 +172,8 @@ def format_configured_cast_result( if not cast_labels and women_count == 1 and men_count == 1: cast_labels = ["Woman A", "Man A"] cast_labels = deps.merge_labels(cast_labels, pov_labels) - expression = _filter_expression_for_krea2_variant(row, request.expression) + has_atlas_variant = _has_krea2_atlas_variant(row) + expression = "" if has_atlas_variant else _filter_expression_for_krea2_variant(row, request.expression) expression = deps.filter_pov_labeled_clauses(expression, pov_labels) expression = deps.natural_label_text(expression, cast_labels) composition = deps.sanitize_hardcore_environment_anchors(request.composition) @@ -213,7 +214,7 @@ def format_configured_cast_result( action, ) camera_scene = _filter_camera_scene_for_krea2_variant(row, request.camera_scene) - output_composition = "" if _has_krea2_atlas_variant(row) else deps.pov_composition_text(composition, pov_labels) + output_composition = "" if has_atlas_variant else deps.pov_composition_text(composition, pov_labels) parts = [ action, scene_anchor, @@ -226,7 +227,7 @@ def format_configured_cast_result( deps.expression_phrase(expression), deps.composition_phrase(output_composition, action, "The image is framed as", detail_density), camera, - request.style if request.detail_level != "concise" else "", + "" if has_atlas_variant else request.style if request.detail_level != "concise" else "", ] return KreaConfiguredCastPrompt(deps.paragraph(parts)) diff --git a/krea_pair_formatter.py b/krea_pair_formatter.py index 171113e..6d7c9cc 100644 --- a/krea_pair_formatter.py +++ b/krea_pair_formatter.py @@ -210,7 +210,8 @@ def format_insta_pair_result(request: KreaPairFormatRequest, deps: KreaPairForma hard_axis_values, hard_detail_density, ) - hard_output_composition = "" if _has_krea2_atlas_variant(hard) else deps.pov_composition_text(hard_composition, pov_labels) + hard_has_atlas_variant = _has_krea2_atlas_variant(hard) + hard_output_composition = "" if hard_has_atlas_variant else deps.pov_composition_text(hard_composition, pov_labels) 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_cast_presence = deps.softcore_cast_presence_phrase( @@ -243,7 +244,7 @@ def format_insta_pair_result(request: KreaPairFormatRequest, deps: KreaPairForma soft_labels, ) hard_expression = "" - if not deps.expression_disabled(hard): + if not deps.expression_disabled(hard) and not hard_has_atlas_variant: hard_expression_source = _filter_expression_for_krea2_variant( hard, deps.clean(hard.get("character_expression_text")) or deps.clean(hard.get("expression")), @@ -281,7 +282,9 @@ def format_insta_pair_result(request: KreaPairFormatRequest, deps: KreaPairForma hard_cast_prose, hard_action, deps.pov_camera_phrase(pov_labels), - deps.natural_label_text( + "" + if hard_has_atlas_variant + else deps.natural_label_text( deps.filter_pov_labeled_clauses(deps.natural_clothing_state(row.get("hardcore_clothing_state"), hard_action), pov_labels), hard_labels, ), @@ -290,7 +293,7 @@ def format_insta_pair_result(request: KreaPairFormatRequest, deps: KreaPairForma deps.expression_phrase(hard_expression), deps.composition_phrase(hard_output_composition, hard_action, detail_density=hard_detail_density), hard_camera, - hard_style if detail_level != "concise" else "", + "" if hard_has_atlas_variant else hard_style if detail_level != "concise" else "", ] return KreaPairPrompts( soft_prompt=deps.paragraph(soft_parts), diff --git a/krea_pov_actions.py b/krea_pov_actions.py index 5e347de..1e2d992 100644 --- a/krea_pov_actions.py +++ b/krea_pov_actions.py @@ -109,7 +109,7 @@ def _krea2_atlas_variant_sentence(axis_values: Any) -> str: variant = _selected_krea2_atlas_variant(axis_values) if not variant: return "" - cues = _unique_texts([variant.get("canonical_geometry"), *(variant.get("prompt_cues") or [])]) + cues = _unique_texts(list(variant.get("prompt_cues") or []) or [variant.get("canonical_geometry")]) return _clean("; ".join(cues)).rstrip(".") @@ -331,7 +331,7 @@ def pov_hardcore_pose_sentence( atlas_sentence = _krea2_atlas_variant_sentence(axis_values) if atlas_sentence: - return sentence(atlas_sentence) + return atlas_sentence def oral_direction() -> tuple[bool, bool]: oral_context = f"{context} {action_lower}" diff --git a/tools/prompt_smoke.py b/tools/prompt_smoke.py index de6f38c..080ff53 100644 --- a/tools/prompt_smoke.py +++ b/tools/prompt_smoke.py @@ -6847,9 +6847,34 @@ def smoke_krea2_pov_atlas_variant_prompt_routes() -> None: "framed as " not in prompt and "the image is framed as " not in prompt, f"{key} final Krea prompt kept generic composition text after atlas route: {prompt}", ) + for forbidden in ( + "pov foreground clothing cue", + "body is fully exposed", + "explicit consensual", + "use clear adult anatomy", + ): + _expect(forbidden not in prompt, f"{key} final Krea prompt kept generic formatter layer {forbidden!r}: {prompt}") atlas_geometry = " ".join([str(variant.get("canonical_geometry") or ""), *[str(cue) for cue in variant.get("prompt_cues") or []]]).lower() if any(term in atlas_geometry for term in ("top-down", "top view", "top-view", "nadir", "overhead")): _expect("eye-level shot" not in prompt, f"{key} final Krea prompt kept contradictory eye-level camera text: {prompt}") + if key == "pov_blowjob_top_down_vertical_shaft": + _expect( + prompt.count("nadir-angle standing male pov top-view oral") == 1, + f"{key} final Krea prompt repeated top-view atlas header instead of staying compact: {prompt}", + ) + for forbidden in ( + "the woman takes the viewer's penis", + "visible saliva", + "cum on", + "hands holding hips", + "eyes looking up", + ): + _expect(forbidden not in prompt, f"{key} final Krea prompt kept generic detail fragment {forbidden!r}: {prompt}") + for required in ( + "mouth seals around the centered shaft", + "one hand wraps the base", + ): + _expect(required in prompt, f"{key} final Krea prompt lost compact contact cue {required!r}: {prompt}") for avoid in variant.get("avoid_cues") or []: avoid_text = _expect_text(f"{key}.avoid_cue", avoid, 4).lower() _expect(avoid_text not in prompt, f"{key} final Krea prompt leaked avoid cue {avoid_text!r}: {prompt}")