Expand camera route smoke coverage
This commit is contained in:
@@ -241,8 +241,10 @@ Near-term:
|
|||||||
- Add final prose hygiene already done through `prompt_hygiene.py`.
|
- Add final prose hygiene already done through `prompt_hygiene.py`.
|
||||||
- Add smoke coverage through `tools/prompt_smoke.py` for metadata-driven Krea2
|
- Add smoke coverage through `tools/prompt_smoke.py` for metadata-driven Krea2
|
||||||
formatting across built-in rows, hardcore rows, same-cast pairs, and POV
|
formatting across built-in rows, hardcore rows, same-cast pairs, and POV
|
||||||
pairs. Expand it next for close foreplay, POV penetration, and camera-scene
|
pairs.
|
||||||
preservation.
|
- Cover camera-scene preservation through `tools/prompt_smoke.py` for single
|
||||||
|
rows, split soft/hard pair cameras, and POV camera-scene routing. Expand it
|
||||||
|
next for close foreplay and POV penetration.
|
||||||
|
|
||||||
Medium-term:
|
Medium-term:
|
||||||
|
|
||||||
@@ -300,8 +302,8 @@ Medium-term:
|
|||||||
|
|
||||||
## Recommended Next Passes
|
## Recommended Next Passes
|
||||||
|
|
||||||
1. Expand `tools/prompt_smoke.py` with camera-scene, explicit nude, and
|
1. Expand `tools/prompt_smoke.py` with close foreplay, POV penetration, and
|
||||||
different-camera pair fixtures.
|
location-theme fixtures.
|
||||||
2. Split Krea action/POV/clothing helpers into separate modules.
|
2. Split Krea action/POV/clothing helpers into separate modules.
|
||||||
3. Add category JSON pool reference validation to `tools/prompt_map_audit.py`.
|
3. Add category JSON pool reference validation to `tools/prompt_map_audit.py`.
|
||||||
4. Extract scene-camera adapters from `prompt_builder.py`.
|
4. Extract scene-camera adapters from `prompt_builder.py`.
|
||||||
|
|||||||
@@ -675,6 +675,11 @@ pair metadata through the core Python APIs, then verifies:
|
|||||||
- negative prompts do not duplicate comma-list items;
|
- negative prompts do not duplicate comma-list items;
|
||||||
- same-room Insta/OF continuity keeps prompt text and `hardcore_row.scene_text`
|
- same-room Insta/OF continuity keeps prompt text and `hardcore_row.scene_text`
|
||||||
synchronized;
|
synchronized;
|
||||||
|
- camera-aware coworking scene text survives single-row Krea formatting;
|
||||||
|
- softcore and hardcore pair rows can carry different camera configs without
|
||||||
|
collapsing to the same camera phrase;
|
||||||
|
- POV camera-scene directives suppress normal third-person camera text while
|
||||||
|
preserving first-person spatial layout;
|
||||||
- expression-disabled rows do not fall back to generated expression text.
|
- expression-disabled rows do not fall back to generated expression text.
|
||||||
|
|
||||||
## Editing Cheatsheet
|
## Editing Cheatsheet
|
||||||
|
|||||||
@@ -179,6 +179,44 @@ def _action_filter(focus: str) -> str:
|
|||||||
return pb.build_hardcore_action_filter_json(focus=focus, **kwargs)
|
return pb.build_hardcore_action_filter_json(focus=focus, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def _coworking_location_config() -> str:
|
||||||
|
return pb.build_location_pool_json(
|
||||||
|
enabled=True,
|
||||||
|
combine_mode="replace",
|
||||||
|
preset="custom_only",
|
||||||
|
custom_locations=(
|
||||||
|
"coworking_smoke: coworking lounge with tall windows, warm desks, "
|
||||||
|
"laptop tables, glass partition seams, repeated desk rows, plants, "
|
||||||
|
"and soft shared-office depth"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _orbit_camera(
|
||||||
|
*,
|
||||||
|
horizontal_angle: int,
|
||||||
|
vertical_angle: int,
|
||||||
|
zoom: float,
|
||||||
|
subject_focus: str = "auto",
|
||||||
|
camera_detail: str = "compact",
|
||||||
|
) -> str:
|
||||||
|
return pb.build_camera_orbit_config_json(
|
||||||
|
enabled=True,
|
||||||
|
camera_mode="standard",
|
||||||
|
horizontal_angle=horizontal_angle,
|
||||||
|
vertical_angle=vertical_angle,
|
||||||
|
zoom=zoom,
|
||||||
|
framing="from_zoom",
|
||||||
|
subject_focus=subject_focus,
|
||||||
|
lens="auto",
|
||||||
|
orientation="auto",
|
||||||
|
phone_visibility="auto",
|
||||||
|
priority="strong",
|
||||||
|
camera_detail=camera_detail,
|
||||||
|
include_degrees=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _prompt_row(
|
def _prompt_row(
|
||||||
*,
|
*,
|
||||||
name: str,
|
name: str,
|
||||||
@@ -189,6 +227,9 @@ def _prompt_row(
|
|||||||
women_count: int = 1,
|
women_count: int = 1,
|
||||||
men_count: int = 1,
|
men_count: int = 1,
|
||||||
hardcore_position_config: str = "",
|
hardcore_position_config: str = "",
|
||||||
|
camera_config: str | dict[str, Any] | None = "",
|
||||||
|
location_config: str | dict[str, Any] | None = "",
|
||||||
|
composition_config: str | dict[str, Any] | None = "",
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
row = pb.build_prompt(
|
row = pb.build_prompt(
|
||||||
category=category,
|
category=category,
|
||||||
@@ -215,6 +256,9 @@ def _prompt_row(
|
|||||||
expression_enabled=True,
|
expression_enabled=True,
|
||||||
expression_intensity=0.6,
|
expression_intensity=0.6,
|
||||||
hardcore_position_config=hardcore_position_config,
|
hardcore_position_config=hardcore_position_config,
|
||||||
|
camera_config=camera_config,
|
||||||
|
location_config=location_config,
|
||||||
|
composition_config=composition_config,
|
||||||
)
|
)
|
||||||
_expect_row_base(row, name)
|
_expect_row_base(row, name)
|
||||||
return row
|
return row
|
||||||
@@ -227,6 +271,34 @@ def smoke_builtin_single() -> None:
|
|||||||
_expect_formatter_outputs(row, "builtin_single_woman", target="single")
|
_expect_formatter_outputs(row, "builtin_single_woman", target="single")
|
||||||
|
|
||||||
|
|
||||||
|
def smoke_camera_scene_single() -> None:
|
||||||
|
row = _prompt_row(
|
||||||
|
name="camera_scene_single",
|
||||||
|
category="woman",
|
||||||
|
subcategory="random",
|
||||||
|
seed=1051,
|
||||||
|
men_count=0,
|
||||||
|
camera_config=_orbit_camera(
|
||||||
|
horizontal_angle=45,
|
||||||
|
vertical_angle=-30,
|
||||||
|
zoom=5.0,
|
||||||
|
subject_focus="environment",
|
||||||
|
),
|
||||||
|
location_config=_coworking_location_config(),
|
||||||
|
)
|
||||||
|
scene_directive = _expect_text("camera_scene_single.camera_scene_directive", row.get("camera_scene_directive"), 40)
|
||||||
|
camera_directive = _expect_text("camera_scene_single.camera_directive", row.get("camera_directive"), 20)
|
||||||
|
_expect("Coworking camera layout" in scene_directive, "single camera-scene adapter did not identify coworking layout")
|
||||||
|
_expect("front-right quarter view" in scene_directive, "single camera scene missed orbit direction")
|
||||||
|
_expect("low-angle shot" in scene_directive, "single camera scene missed orbit elevation")
|
||||||
|
_expect("45-degree front-right quarter view" in camera_directive, "single camera directive missed custom orbit prompt")
|
||||||
|
krea = krea_formatter.format_krea2_prompt("", metadata_json=_json(row), target="single")
|
||||||
|
prompt = krea.get("krea_prompt") or ""
|
||||||
|
_expect("Coworking camera layout" in prompt, "Krea single prompt lost camera-scene directive")
|
||||||
|
_expect("45-degree front-right quarter view" in prompt, "Krea single prompt lost camera directive")
|
||||||
|
_expect_formatter_outputs(row, "camera_scene_single", target="single")
|
||||||
|
|
||||||
|
|
||||||
def smoke_hardcore_category_routes() -> None:
|
def smoke_hardcore_category_routes() -> None:
|
||||||
cast = _character_cast()
|
cast = _character_cast()
|
||||||
cases = [
|
cases = [
|
||||||
@@ -303,6 +375,9 @@ 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")
|
||||||
|
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("teaser outfit detail" not in clothing_state, "explicit nude pair should not repeat softcore outfit detail")
|
||||||
|
|
||||||
|
|
||||||
def smoke_insta_pair_pov() -> None:
|
def smoke_insta_pair_pov() -> None:
|
||||||
@@ -330,6 +405,92 @@ def smoke_insta_pair_pov() -> None:
|
|||||||
_expect("viewer" in prompt.lower(), "POV Krea prompt should mention viewer perspective")
|
_expect("viewer" in prompt.lower(), "POV Krea prompt should mention viewer perspective")
|
||||||
|
|
||||||
|
|
||||||
|
def smoke_insta_pair_camera_split() -> None:
|
||||||
|
soft_camera = _orbit_camera(
|
||||||
|
horizontal_angle=45,
|
||||||
|
vertical_angle=-30,
|
||||||
|
zoom=5.0,
|
||||||
|
subject_focus="environment",
|
||||||
|
)
|
||||||
|
hard_camera = _orbit_camera(
|
||||||
|
horizontal_angle=135,
|
||||||
|
vertical_angle=30,
|
||||||
|
zoom=8.0,
|
||||||
|
subject_focus="action",
|
||||||
|
)
|
||||||
|
pair = pb.build_insta_of_pair(
|
||||||
|
row_number=1,
|
||||||
|
start_index=1,
|
||||||
|
seed=2251,
|
||||||
|
ethnicity="any",
|
||||||
|
figure="random",
|
||||||
|
no_plus_women=False,
|
||||||
|
no_black=False,
|
||||||
|
trigger=Trigger,
|
||||||
|
prepend_trigger_to_prompt=True,
|
||||||
|
options_json=_insta_options(
|
||||||
|
softcore_camera_mode="from_camera_config",
|
||||||
|
hardcore_camera_mode="from_camera_config",
|
||||||
|
camera_detail="compact",
|
||||||
|
),
|
||||||
|
character_cast=_character_cast(),
|
||||||
|
hardcore_position_config=_action_filter("penetration_only"),
|
||||||
|
location_config=_coworking_location_config(),
|
||||||
|
softcore_camera_config=soft_camera,
|
||||||
|
hardcore_camera_config=hard_camera,
|
||||||
|
)
|
||||||
|
_expect_pair(pair, "insta_pair_camera_split")
|
||||||
|
soft_scene = _expect_text("insta_pair_camera_split.soft_camera_scene", pair.get("softcore_camera_scene_directive"), 40)
|
||||||
|
hard_scene = _expect_text("insta_pair_camera_split.hard_camera_scene", pair.get("hardcore_camera_scene_directive"), 40)
|
||||||
|
_expect("front-right quarter view" in soft_scene, "soft camera scene missed soft orbit direction")
|
||||||
|
_expect("back-right quarter view" in hard_scene, "hard camera scene missed hard orbit direction")
|
||||||
|
_expect("low-angle shot" in soft_scene, "soft camera scene missed soft elevation")
|
||||||
|
_expect("elevated shot" in hard_scene, "hard camera scene missed hard elevation")
|
||||||
|
_expect("front-right quarter view" in str(pair.get("softcore_camera_directive")), "soft pair camera directive was not preserved")
|
||||||
|
_expect("back-right quarter view" in str(pair.get("hardcore_camera_directive")), "hard pair camera directive was not preserved")
|
||||||
|
krea = krea_formatter.format_krea2_prompt("", metadata_json=_json(pair), target="auto")
|
||||||
|
_expect("front-right quarter view" in (krea.get("krea_softcore_prompt") or ""), "Krea soft pair lost soft camera geometry")
|
||||||
|
_expect("back-right quarter view" in (krea.get("krea_hardcore_prompt") or ""), "Krea hard pair lost hard camera geometry")
|
||||||
|
|
||||||
|
|
||||||
|
def smoke_pov_camera_scene() -> None:
|
||||||
|
pair = pb.build_insta_of_pair(
|
||||||
|
row_number=1,
|
||||||
|
start_index=1,
|
||||||
|
seed=2261,
|
||||||
|
ethnicity="any",
|
||||||
|
figure="random",
|
||||||
|
no_plus_women=False,
|
||||||
|
no_black=False,
|
||||||
|
trigger=Trigger,
|
||||||
|
prepend_trigger_to_prompt=True,
|
||||||
|
options_json=_insta_options(
|
||||||
|
softcore_camera_mode="from_camera_config",
|
||||||
|
hardcore_camera_mode="from_camera_config",
|
||||||
|
camera_detail="compact",
|
||||||
|
),
|
||||||
|
character_cast=_character_cast(pov_man=True),
|
||||||
|
hardcore_position_config=_action_filter("oral_only"),
|
||||||
|
location_config=_coworking_location_config(),
|
||||||
|
hardcore_camera_config=_orbit_camera(
|
||||||
|
horizontal_angle=135,
|
||||||
|
vertical_angle=30,
|
||||||
|
zoom=8.0,
|
||||||
|
subject_focus="action",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
_expect_pair(pair, "pov_camera_scene")
|
||||||
|
hard_row = pair.get("hardcore_row") or {}
|
||||||
|
_expect(not hard_row.get("camera_directive"), "POV hard row should suppress normal camera directive")
|
||||||
|
scene_directive = _expect_text("pov_camera_scene.hard_camera_scene", hard_row.get("camera_scene_directive"), 40)
|
||||||
|
_expect("from POV" in scene_directive, "POV camera scene should be marked as first-person")
|
||||||
|
_expect("not in the lower foreground" in scene_directive, "POV camera scene should keep location anchors out of lower foreground")
|
||||||
|
krea = krea_formatter.format_krea2_prompt("", metadata_json=_json(pair), target="hardcore")
|
||||||
|
prompt = krea.get("krea_prompt") or ""
|
||||||
|
_expect("from POV" in prompt, "Krea POV prompt lost camera-scene directive")
|
||||||
|
_expect("Camera:" not in prompt, "Krea POV prompt should not emit normal third-person camera directive")
|
||||||
|
|
||||||
|
|
||||||
def smoke_no_expression_fallback() -> None:
|
def smoke_no_expression_fallback() -> None:
|
||||||
cast = pb.build_character_slot_json(
|
cast = pb.build_character_slot_json(
|
||||||
subject_type="woman",
|
subject_type="woman",
|
||||||
@@ -358,9 +519,12 @@ def smoke_no_expression_fallback() -> None:
|
|||||||
|
|
||||||
SMOKE_CASES: list[tuple[str, Callable[[], None]]] = [
|
SMOKE_CASES: list[tuple[str, Callable[[], None]]] = [
|
||||||
("builtin_single_woman", smoke_builtin_single),
|
("builtin_single_woman", smoke_builtin_single),
|
||||||
|
("camera_scene_single", smoke_camera_scene_single),
|
||||||
("hardcore_category_routes", smoke_hardcore_category_routes),
|
("hardcore_category_routes", smoke_hardcore_category_routes),
|
||||||
("insta_pair_same_cast", smoke_insta_pair),
|
("insta_pair_same_cast", smoke_insta_pair),
|
||||||
("insta_pair_pov_man", smoke_insta_pair_pov),
|
("insta_pair_pov_man", smoke_insta_pair_pov),
|
||||||
|
("insta_pair_camera_split", smoke_insta_pair_camera_split),
|
||||||
|
("pov_camera_scene", smoke_pov_camera_scene),
|
||||||
("expression_disabled", smoke_no_expression_fallback),
|
("expression_disabled", smoke_no_expression_fallback),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user