Extract row subject route policy

This commit is contained in:
2026-06-27 09:49:50 +02:00
parent d31d513ec3
commit f7164480df
5 changed files with 268 additions and 51 deletions
+57 -45
View File
@@ -43,6 +43,7 @@ try:
from . import row_pools as row_pool_policy
from . import row_rendering as row_rendering_policy
from . import row_route_metadata as row_route_policy
from . import row_subject_route as row_subject_route_policy
from . import seed_config as seed_policy
from . import subject_context as subject_context_policy
from .hardcore_text_cleanup import (
@@ -89,6 +90,7 @@ except ImportError: # Allows local smoke tests with `python -c`.
import row_pools as row_pool_policy
import row_rendering as row_rendering_policy
import row_route_metadata as row_route_policy
import row_subject_route as row_subject_route_policy
import seed_config as seed_policy
import subject_context as subject_context_policy
from hardcore_text_cleanup import (
@@ -1960,6 +1962,37 @@ def _subject_context(
)
def _subject_route(
*,
subject_type: str,
seed_config: dict[str, int],
seed: int,
row_number: int,
ethnicity: str,
figure: str,
no_plus_women: bool,
no_black: bool,
women_count: int,
men_count: int,
character_profile: str | dict[str, Any] | None = None,
character_cast: str | dict[str, Any] | list[Any] | None = None,
) -> dict[str, Any]:
return row_subject_route_policy.resolve_subject_route(
subject_type=subject_type,
seed_config=seed_config,
seed=seed,
row_number=row_number,
ethnicity=ethnicity,
figure=figure,
no_plus_women=no_plus_women,
no_black=no_black,
women_count=women_count,
men_count=men_count,
character_profile=character_profile,
character_cast=character_cast,
)
def _scene_pool(
category: dict[str, Any],
subcategory: dict[str, Any],
@@ -2020,7 +2053,6 @@ def _build_custom_row(
location_config: str | dict[str, Any] | None = None,
composition_config: str | dict[str, Any] | None = None,
) -> dict[str, Any]:
person_rng = _axis_rng(seed_config, "person", seed, row_number)
scene_rng = _axis_rng(seed_config, "scene", seed, row_number)
pose_rng = _axis_rng(seed_config, "pose", seed, row_number)
role_rng = _axis_rng(seed_config, "role", seed, row_number)
@@ -2054,41 +2086,35 @@ def _build_custom_row(
item_formatter_hints = dict(category_route.get("formatter_hints") or {})
is_pose_category = bool(category_route.get("is_pose_category"))
subject_type = str(_merged_field(category, subcategory, item, "subject_type", "single_any"))
context = _subject_context(person_rng, subject_type, ethnicity, figure, no_plus_women, no_black, women_count, men_count)
character_slots = _parse_character_cast(character_cast)
character_slot_map = _character_slot_label_map(character_slots)
applied_slot: dict[str, Any] = {}
slot_status = "none"
if context.get("subject_type") in ("woman", "man"):
slot_label = "Woman A" if context["subject_type"] == "woman" else "Man A"
if slot_label in character_slot_map:
context, applied_slot = _character_context_for_label(
slot_label,
character_slot_map,
person_rng,
ethnicity,
figure,
no_plus_women,
no_black,
)
slot_status = f"applied:{slot_label}"
applied_profile, profile_status = {}, "skipped_character_slot"
else:
context, applied_profile, profile_status = _apply_character_profile_to_context(context, character_profile)
else:
context, applied_profile, profile_status = _apply_character_profile_to_context(context, character_profile)
subject_type = context["subject_type"]
pov_character_labels = (
_pov_character_labels(character_slot_map, men_count)
if subject_type == "configured_cast"
else []
subject_route = _subject_route(
subject_type=subject_type,
seed_config=seed_config,
seed=seed,
row_number=row_number,
ethnicity=ethnicity,
figure=figure,
no_plus_women=no_plus_women,
no_black=no_black,
women_count=women_count,
men_count=men_count,
character_profile=character_profile,
character_cast=character_cast,
)
context = dict(subject_route["context"])
subject_type = str(subject_route.get("subject_type") or context.get("subject_type") or subject_type)
character_slots = list(subject_route.get("character_slots") or [])
character_slot_map = dict(subject_route.get("character_slot_map") or {})
applied_slot = dict(subject_route.get("applied_slot") or {})
slot_status = str(subject_route.get("character_slot_status") or "none")
applied_profile = dict(subject_route.get("applied_profile") or {})
profile_status = str(subject_route.get("character_profile_status") or "none")
pov_character_labels = list(subject_route.get("pov_character_labels") or [])
cast_descriptors = list(subject_route.get("cast_descriptors") or [])
cast_descriptor_text = str(subject_route.get("cast_descriptor_text") or "")
source_role_graph = build_hardcore_role_graph(role_rng, subcategory, context, item_axis_values, pov_character_labels)
if is_pose_category:
source_role_graph = _sanitize_hardcore_environment_anchors(source_role_graph)
role_graph = _pov_role_graph_prompt(source_role_graph, pov_character_labels)
cast_descriptors: list[str] = []
cast_descriptor_text = ""
expression_intensity_source = expression_intensity_source or "input"
expression_disabled = not bool(expression_enabled)
if expression_disabled:
@@ -2113,20 +2139,6 @@ def _build_custom_row(
)
if expression_intensity is None:
expression_disabled = True
if subject_type == "configured_cast" and character_slots:
cast_descriptors, _descriptor_slots = _cast_descriptor_entries(
seed_config,
seed,
row_number,
ethnicity,
figure,
no_plus_women,
no_black,
women_count,
men_count,
character_slots,
)
cast_descriptor_text = _insta_of_prompt_cast_descriptors("; ".join(cast_descriptors))
scene_slug, scene = _choose_pair(
scene_rng,