Extract row assembly policy
This commit is contained in:
@@ -253,6 +253,10 @@ Already isolated:
|
|||||||
sanitation before metadata leaves generation. It also copies side-specific
|
sanitation before metadata leaves generation. It also copies side-specific
|
||||||
pair metadata, such as soft partner styling and hardcore clothing/detail
|
pair metadata, such as soft partner styling and hardcore clothing/detail
|
||||||
state, onto the embedded soft/hard rows.
|
state, onto the embedded soft/hard rows.
|
||||||
|
- final custom-row assembly now lives in `row_assembly.py`, covering render
|
||||||
|
context population, prompt/caption rendering delegation, row-base indexing,
|
||||||
|
row metadata copying, configured-cast count metadata, profile/slot metadata,
|
||||||
|
and disabled-expression cleanup.
|
||||||
|
|
||||||
### Pair / Adapter Layer
|
### Pair / Adapter Layer
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ Core helper ownership:
|
|||||||
| `row_item.py` | Row item selection, weighted item/pair choice, item-template axis filling, and oral/outercourse axis compatibility filters. |
|
| `row_item.py` | Row item selection, weighted item/pair choice, item-template axis filling, and oral/outercourse axis compatibility filters. |
|
||||||
| `row_category_route.py` | Row category/subcategory/item route resolution, hardcore position-category filtering, cast-count adjustment, pose-vs-content seed-axis choice, item metadata collection, and pose-category item sanitizing. |
|
| `row_category_route.py` | Row category/subcategory/item route resolution, hardcore position-category filtering, cast-count adjustment, pose-vs-content seed-axis choice, item metadata collection, and pose-category item sanitizing. |
|
||||||
| `row_rendering.py` | Row prompt/caption template selection, safe formatting, default prompt templates, configured-cast descriptor insertion, and POV directive insertion. |
|
| `row_rendering.py` | Row prompt/caption template selection, safe formatting, default prompt templates, configured-cast descriptor insertion, and POV directive insertion. |
|
||||||
|
| `row_assembly.py` | Final custom-row dictionary assembly, render-context metadata population, prompt/caption rendering delegation, row-base indexing, cast/profile/slot metadata copying, and disabled-expression cleanup. |
|
||||||
| `row_route_metadata.py` | Row action/position route metadata resolution, template metadata precedence, inferred position-key merging, and source action-family fallback. |
|
| `row_route_metadata.py` | Row action/position route metadata resolution, template metadata precedence, inferred position-key merging, and source action-family fallback. |
|
||||||
| `row_generation.py` | Built-in legacy row generation, auto-weighted/auto-full selection, row mode randomization, ratio clamps, and expression-intensity randomization. |
|
| `row_generation.py` | Built-in legacy row generation, auto-weighted/auto-full selection, row mode randomization, ratio clamps, and expression-intensity randomization. |
|
||||||
| `category_cast_config.py` | Category preset and cast preset schemas, category/cast config JSON builders, choice lists, and config parsers used by route nodes. |
|
| `category_cast_config.py` | Category preset and cast preset schemas, category/cast config JSON builders, choice lists, and config parsers used by route nodes. |
|
||||||
|
|||||||
+56
-120
@@ -34,6 +34,7 @@ try:
|
|||||||
from . import pair_options
|
from . import pair_options
|
||||||
from . import pov_policy
|
from . import pov_policy
|
||||||
from . import row_normalization as row_policy
|
from . import row_normalization as row_policy
|
||||||
|
from . import row_assembly as row_assembly_policy
|
||||||
from . import row_camera as row_camera_policy
|
from . import row_camera as row_camera_policy
|
||||||
from . import row_category_route as row_category_route_policy
|
from . import row_category_route as row_category_route_policy
|
||||||
from . import row_expression as row_expression_policy
|
from . import row_expression as row_expression_policy
|
||||||
@@ -82,6 +83,7 @@ except ImportError: # Allows local smoke tests with `python -c`.
|
|||||||
import pair_options
|
import pair_options
|
||||||
import pov_policy
|
import pov_policy
|
||||||
import row_normalization as row_policy
|
import row_normalization as row_policy
|
||||||
|
import row_assembly as row_assembly_policy
|
||||||
import row_camera as row_camera_policy
|
import row_camera as row_camera_policy
|
||||||
import row_category_route as row_category_route_policy
|
import row_category_route as row_category_route_policy
|
||||||
import row_expression as row_expression_policy
|
import row_expression as row_expression_policy
|
||||||
@@ -2084,6 +2086,10 @@ def _prompt_axes_route(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _assemble_custom_row(**kwargs: Any) -> dict[str, Any]:
|
||||||
|
return row_assembly_policy.assemble_custom_row(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
def _build_custom_row(
|
def _build_custom_row(
|
||||||
category_choice: str,
|
category_choice: str,
|
||||||
subcategory_choice: str,
|
subcategory_choice: str,
|
||||||
@@ -2258,130 +2264,60 @@ def _build_custom_row(
|
|||||||
)
|
)
|
||||||
item_label = str(_merged_field(category, subcategory, item, "item_label", category["name"]))
|
item_label = str(_merged_field(category, subcategory, item, "item_label", category["name"]))
|
||||||
|
|
||||||
context.update(
|
return _assemble_custom_row(
|
||||||
{
|
row_number=row_number,
|
||||||
"trigger": g.TRIGGER,
|
start_index=start_index,
|
||||||
"main_category": category["name"],
|
|
||||||
"subcategory": subcategory["name"],
|
|
||||||
"category": category["name"],
|
|
||||||
"item": item_text,
|
|
||||||
"item_name": item_name,
|
|
||||||
"item_label": item_label,
|
|
||||||
"style": style,
|
|
||||||
"scene": scene,
|
|
||||||
"scene_slug": scene_slug,
|
|
||||||
"pose": pose,
|
|
||||||
"expression": expression,
|
|
||||||
"shared_expression": shared_expression,
|
|
||||||
"character_expressions": character_expressions,
|
|
||||||
"character_expression_text": character_expression_text,
|
|
||||||
"expression_enabled": not expression_disabled,
|
|
||||||
"expression_disabled": expression_disabled,
|
|
||||||
"expression_intensity": expression_intensity,
|
|
||||||
"expression_intensity_source": expression_intensity_source,
|
|
||||||
"composition": composition,
|
|
||||||
"source_composition": source_composition,
|
|
||||||
"composition_prompt": _composition_prompt(composition),
|
|
||||||
"composition_config": parsed_composition_config if _composition_config_active(parsed_composition_config) else {},
|
|
||||||
"role_graph": role_graph,
|
|
||||||
"source_role_graph": source_role_graph,
|
|
||||||
"action_family": action_family,
|
|
||||||
"position_family": position_family,
|
|
||||||
"position_key": position_key,
|
|
||||||
"position_keys": position_keys,
|
|
||||||
"pov_character_labels": pov_character_labels,
|
|
||||||
"pov_prompt_directive": _pov_prompt_directive(pov_character_labels),
|
|
||||||
"cast_descriptors": cast_descriptor_text,
|
|
||||||
"positive_suffix": positive_suffix,
|
|
||||||
"negative_prompt": negative_prompt,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
rendered = row_rendering_policy.render_prompt_caption(
|
|
||||||
item=item,
|
|
||||||
subcategory=subcategory,
|
|
||||||
category=category,
|
category=category,
|
||||||
subject_type=subject_type,
|
subcategory=subcategory,
|
||||||
|
item=item,
|
||||||
context=context,
|
context=context,
|
||||||
|
subject_type=subject_type,
|
||||||
|
item_text=item_text,
|
||||||
|
item_name=item_name,
|
||||||
|
item_axis_values=item_axis_values,
|
||||||
|
item_template_metadata=item_template_metadata,
|
||||||
|
formatter_hints=item_formatter_hints,
|
||||||
|
item_label=item_label,
|
||||||
|
style=style,
|
||||||
|
positive_suffix=positive_suffix,
|
||||||
|
negative_prompt=negative_prompt,
|
||||||
|
scene_slug=scene_slug,
|
||||||
|
scene=scene,
|
||||||
|
pose=pose,
|
||||||
|
expression=expression,
|
||||||
|
shared_expression=shared_expression,
|
||||||
|
character_expressions=character_expressions,
|
||||||
|
character_expression_text=character_expression_text,
|
||||||
|
expression_disabled=expression_disabled,
|
||||||
|
expression_intensity=expression_intensity,
|
||||||
|
expression_intensity_source=expression_intensity_source,
|
||||||
|
composition=composition,
|
||||||
|
source_composition=source_composition,
|
||||||
|
role_graph=role_graph,
|
||||||
|
source_role_graph=source_role_graph,
|
||||||
|
action_family=action_family,
|
||||||
|
position_family=position_family,
|
||||||
|
position_key=position_key,
|
||||||
|
position_keys=position_keys,
|
||||||
|
pov_character_labels=pov_character_labels,
|
||||||
|
cast_descriptors=cast_descriptors,
|
||||||
cast_descriptor_text=cast_descriptor_text,
|
cast_descriptor_text=cast_descriptor_text,
|
||||||
pov_prompt_directive=_pov_prompt_directive(pov_character_labels) if pov_character_labels else "",
|
seed_config=seed_config,
|
||||||
|
hardcore_position_config=(
|
||||||
|
parsed_hardcore_position_config
|
||||||
|
if _hardcore_position_config_active(parsed_hardcore_position_config)
|
||||||
|
else {}
|
||||||
|
),
|
||||||
|
location_config=parsed_location_config if _location_config_active(parsed_location_config) else {},
|
||||||
|
composition_config=parsed_composition_config if _composition_config_active(parsed_composition_config) else {},
|
||||||
|
content_seed_axis=content_axis,
|
||||||
|
count_adjustment=count_adjustment,
|
||||||
|
applied_profile=applied_profile,
|
||||||
|
profile_status=profile_status,
|
||||||
|
applied_slot=applied_slot,
|
||||||
|
slot_status=slot_status,
|
||||||
|
character_slots=character_slots,
|
||||||
)
|
)
|
||||||
prompt = rendered["prompt"]
|
|
||||||
caption = rendered["caption"]
|
|
||||||
batch = max(1, ((row_number - 1) // g.BATCH_SIZE) + 1)
|
|
||||||
index = start_index + row_number - 1
|
|
||||||
row = g.row_base(index, batch, context["subject"], context["age"], context["body"], scene_slug, composition)
|
|
||||||
row.update(
|
|
||||||
{
|
|
||||||
"prompt": prompt,
|
|
||||||
"caption": caption,
|
|
||||||
"negative_prompt": negative_prompt,
|
|
||||||
"expression": expression,
|
|
||||||
"main_category": category["name"],
|
|
||||||
"subcategory": subcategory["name"],
|
|
||||||
"category_slug": category["slug"],
|
|
||||||
"subcategory_slug": subcategory["slug"],
|
|
||||||
"subject_type": subject_type,
|
|
||||||
"subject_phrase": context.get("subject_phrase", ""),
|
|
||||||
"body_phrase": context.get("body_phrase", ""),
|
|
||||||
"skin": context.get("skin", ""),
|
|
||||||
"hair": context.get("hair", ""),
|
|
||||||
"eyes": context.get("eyes", ""),
|
|
||||||
"style": style,
|
|
||||||
"item": item_text,
|
|
||||||
"item_label": item_label,
|
|
||||||
"positive_suffix": positive_suffix,
|
|
||||||
"custom_item": item_name,
|
|
||||||
"item_axis_values": item_axis_values,
|
|
||||||
"item_template_metadata": item_template_metadata,
|
|
||||||
"formatter_hints": item_formatter_hints,
|
|
||||||
"scene_text": scene,
|
|
||||||
"location_config": parsed_location_config if _location_config_active(parsed_location_config) else {},
|
|
||||||
"pose": pose,
|
|
||||||
"seed_config": seed_config,
|
|
||||||
"hardcore_position_config": (
|
|
||||||
parsed_hardcore_position_config
|
|
||||||
if _hardcore_position_config_active(parsed_hardcore_position_config)
|
|
||||||
else {}
|
|
||||||
),
|
|
||||||
"content_seed_axis": content_axis,
|
|
||||||
"role_graph": role_graph,
|
|
||||||
"source_role_graph": source_role_graph,
|
|
||||||
"action_family": action_family,
|
|
||||||
"position_family": position_family,
|
|
||||||
"position_key": position_key,
|
|
||||||
"position_keys": position_keys,
|
|
||||||
"source_composition": source_composition,
|
|
||||||
"pov_character_labels": pov_character_labels,
|
|
||||||
"pov_prompt_directive": _pov_prompt_directive(pov_character_labels),
|
|
||||||
"shared_expression": shared_expression,
|
|
||||||
"character_expressions": character_expressions,
|
|
||||||
"character_expression_text": character_expression_text,
|
|
||||||
"expression_enabled": not expression_disabled,
|
|
||||||
"expression_disabled": expression_disabled,
|
|
||||||
"cast_summary": context.get("cast_summary", ""),
|
|
||||||
"cast_descriptors": cast_descriptors,
|
|
||||||
"cast_descriptor_text": cast_descriptor_text,
|
|
||||||
"scene_kind": context.get("scene_kind", ""),
|
|
||||||
"women_count": context.get("women_count", ""),
|
|
||||||
"men_count": context.get("men_count", ""),
|
|
||||||
"person_count": context.get("person_count", ""),
|
|
||||||
"cast_count_adjustment": count_adjustment if subject_type == "configured_cast" else {},
|
|
||||||
"character_profile": applied_profile,
|
|
||||||
"character_profile_status": profile_status,
|
|
||||||
"character_slot": applied_slot,
|
|
||||||
"character_slot_status": slot_status,
|
|
||||||
"character_cast_slots": character_slots,
|
|
||||||
"expression_intensity": expression_intensity,
|
|
||||||
"expression_intensity_source": expression_intensity_source,
|
|
||||||
"source": "json_category",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if context.get("figure"):
|
|
||||||
row["figure"] = context["figure"]
|
|
||||||
if expression_disabled:
|
|
||||||
row = _disable_row_expression(row, expression_intensity_source)
|
|
||||||
return row
|
|
||||||
|
|
||||||
|
|
||||||
def build_prompt(
|
def build_prompt(
|
||||||
|
|||||||
+196
@@ -0,0 +1,196 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
try:
|
||||||
|
from . import generate_prompt_batches as g
|
||||||
|
from . import pov_policy
|
||||||
|
from . import row_camera as row_camera_policy
|
||||||
|
from . import row_expression as row_expression_policy
|
||||||
|
from . import row_rendering as row_rendering_policy
|
||||||
|
except ImportError: # Allows local smoke tests from the repository root.
|
||||||
|
import generate_prompt_batches as g
|
||||||
|
import pov_policy
|
||||||
|
import row_camera as row_camera_policy
|
||||||
|
import row_expression as row_expression_policy
|
||||||
|
import row_rendering as row_rendering_policy
|
||||||
|
|
||||||
|
|
||||||
|
def assemble_custom_row(
|
||||||
|
*,
|
||||||
|
row_number: int,
|
||||||
|
start_index: int,
|
||||||
|
category: dict[str, Any],
|
||||||
|
subcategory: dict[str, Any],
|
||||||
|
item: Any,
|
||||||
|
context: dict[str, Any],
|
||||||
|
subject_type: str,
|
||||||
|
item_text: str,
|
||||||
|
item_name: str,
|
||||||
|
item_axis_values: dict[str, Any],
|
||||||
|
item_template_metadata: dict[str, Any],
|
||||||
|
formatter_hints: dict[str, Any],
|
||||||
|
item_label: str,
|
||||||
|
style: str,
|
||||||
|
positive_suffix: str,
|
||||||
|
negative_prompt: str,
|
||||||
|
scene_slug: str,
|
||||||
|
scene: str,
|
||||||
|
pose: str,
|
||||||
|
expression: str,
|
||||||
|
shared_expression: str,
|
||||||
|
character_expressions: list[str],
|
||||||
|
character_expression_text: str,
|
||||||
|
expression_disabled: bool,
|
||||||
|
expression_intensity: float | None,
|
||||||
|
expression_intensity_source: str,
|
||||||
|
composition: str,
|
||||||
|
source_composition: str,
|
||||||
|
role_graph: str,
|
||||||
|
source_role_graph: str,
|
||||||
|
action_family: str,
|
||||||
|
position_family: str,
|
||||||
|
position_key: str,
|
||||||
|
position_keys: list[str],
|
||||||
|
pov_character_labels: list[str],
|
||||||
|
cast_descriptors: list[str],
|
||||||
|
cast_descriptor_text: str,
|
||||||
|
seed_config: dict[str, int],
|
||||||
|
hardcore_position_config: dict[str, Any] | None = None,
|
||||||
|
location_config: dict[str, Any] | None = None,
|
||||||
|
composition_config: dict[str, Any] | None = None,
|
||||||
|
content_seed_axis: str = "content",
|
||||||
|
count_adjustment: dict[str, Any] | None = None,
|
||||||
|
applied_profile: dict[str, Any] | None = None,
|
||||||
|
profile_status: str = "none",
|
||||||
|
applied_slot: dict[str, Any] | None = None,
|
||||||
|
slot_status: str = "none",
|
||||||
|
character_slots: list[dict[str, Any]] | None = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
render_context = dict(context)
|
||||||
|
pov_prompt_directive = pov_policy.pov_prompt_directive(pov_character_labels)
|
||||||
|
render_context.update(
|
||||||
|
{
|
||||||
|
"trigger": g.TRIGGER,
|
||||||
|
"main_category": category["name"],
|
||||||
|
"subcategory": subcategory["name"],
|
||||||
|
"category": category["name"],
|
||||||
|
"item": item_text,
|
||||||
|
"item_name": item_name,
|
||||||
|
"item_label": item_label,
|
||||||
|
"style": style,
|
||||||
|
"scene": scene,
|
||||||
|
"scene_slug": scene_slug,
|
||||||
|
"pose": pose,
|
||||||
|
"expression": expression,
|
||||||
|
"shared_expression": shared_expression,
|
||||||
|
"character_expressions": character_expressions,
|
||||||
|
"character_expression_text": character_expression_text,
|
||||||
|
"expression_enabled": not expression_disabled,
|
||||||
|
"expression_disabled": expression_disabled,
|
||||||
|
"expression_intensity": expression_intensity,
|
||||||
|
"expression_intensity_source": expression_intensity_source,
|
||||||
|
"composition": composition,
|
||||||
|
"source_composition": source_composition,
|
||||||
|
"composition_prompt": row_camera_policy.composition_prompt(composition),
|
||||||
|
"composition_config": composition_config or {},
|
||||||
|
"role_graph": role_graph,
|
||||||
|
"source_role_graph": source_role_graph,
|
||||||
|
"action_family": action_family,
|
||||||
|
"position_family": position_family,
|
||||||
|
"position_key": position_key,
|
||||||
|
"position_keys": position_keys,
|
||||||
|
"pov_character_labels": pov_character_labels,
|
||||||
|
"pov_prompt_directive": pov_prompt_directive,
|
||||||
|
"cast_descriptors": cast_descriptor_text,
|
||||||
|
"positive_suffix": positive_suffix,
|
||||||
|
"negative_prompt": negative_prompt,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
rendered = row_rendering_policy.render_prompt_caption(
|
||||||
|
item=item,
|
||||||
|
subcategory=subcategory,
|
||||||
|
category=category,
|
||||||
|
subject_type=subject_type,
|
||||||
|
context=render_context,
|
||||||
|
cast_descriptor_text=cast_descriptor_text,
|
||||||
|
pov_prompt_directive=pov_prompt_directive if pov_character_labels else "",
|
||||||
|
)
|
||||||
|
batch = max(1, ((row_number - 1) // g.BATCH_SIZE) + 1)
|
||||||
|
index = start_index + row_number - 1
|
||||||
|
row = g.row_base(
|
||||||
|
index,
|
||||||
|
batch,
|
||||||
|
render_context["subject"],
|
||||||
|
render_context["age"],
|
||||||
|
render_context["body"],
|
||||||
|
scene_slug,
|
||||||
|
composition,
|
||||||
|
)
|
||||||
|
row.update(
|
||||||
|
{
|
||||||
|
"prompt": rendered["prompt"],
|
||||||
|
"caption": rendered["caption"],
|
||||||
|
"negative_prompt": negative_prompt,
|
||||||
|
"expression": expression,
|
||||||
|
"main_category": category["name"],
|
||||||
|
"subcategory": subcategory["name"],
|
||||||
|
"category_slug": category["slug"],
|
||||||
|
"subcategory_slug": subcategory["slug"],
|
||||||
|
"subject_type": subject_type,
|
||||||
|
"subject_phrase": render_context.get("subject_phrase", ""),
|
||||||
|
"body_phrase": render_context.get("body_phrase", ""),
|
||||||
|
"skin": render_context.get("skin", ""),
|
||||||
|
"hair": render_context.get("hair", ""),
|
||||||
|
"eyes": render_context.get("eyes", ""),
|
||||||
|
"style": style,
|
||||||
|
"item": item_text,
|
||||||
|
"item_label": item_label,
|
||||||
|
"positive_suffix": positive_suffix,
|
||||||
|
"custom_item": item_name,
|
||||||
|
"item_axis_values": item_axis_values,
|
||||||
|
"item_template_metadata": item_template_metadata,
|
||||||
|
"formatter_hints": formatter_hints,
|
||||||
|
"scene_text": scene,
|
||||||
|
"location_config": location_config or {},
|
||||||
|
"pose": pose,
|
||||||
|
"seed_config": seed_config,
|
||||||
|
"hardcore_position_config": hardcore_position_config or {},
|
||||||
|
"content_seed_axis": content_seed_axis,
|
||||||
|
"role_graph": role_graph,
|
||||||
|
"source_role_graph": source_role_graph,
|
||||||
|
"action_family": action_family,
|
||||||
|
"position_family": position_family,
|
||||||
|
"position_key": position_key,
|
||||||
|
"position_keys": position_keys,
|
||||||
|
"source_composition": source_composition,
|
||||||
|
"pov_character_labels": pov_character_labels,
|
||||||
|
"pov_prompt_directive": pov_prompt_directive,
|
||||||
|
"shared_expression": shared_expression,
|
||||||
|
"character_expressions": character_expressions,
|
||||||
|
"character_expression_text": character_expression_text,
|
||||||
|
"expression_enabled": not expression_disabled,
|
||||||
|
"expression_disabled": expression_disabled,
|
||||||
|
"cast_summary": render_context.get("cast_summary", ""),
|
||||||
|
"cast_descriptors": cast_descriptors,
|
||||||
|
"cast_descriptor_text": cast_descriptor_text,
|
||||||
|
"scene_kind": render_context.get("scene_kind", ""),
|
||||||
|
"women_count": render_context.get("women_count", ""),
|
||||||
|
"men_count": render_context.get("men_count", ""),
|
||||||
|
"person_count": render_context.get("person_count", ""),
|
||||||
|
"cast_count_adjustment": count_adjustment if subject_type == "configured_cast" else {},
|
||||||
|
"character_profile": applied_profile or {},
|
||||||
|
"character_profile_status": profile_status,
|
||||||
|
"character_slot": applied_slot or {},
|
||||||
|
"character_slot_status": slot_status,
|
||||||
|
"character_cast_slots": character_slots or [],
|
||||||
|
"expression_intensity": expression_intensity,
|
||||||
|
"expression_intensity_source": expression_intensity_source,
|
||||||
|
"source": "json_category",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if render_context.get("figure"):
|
||||||
|
row["figure"] = render_context["figure"]
|
||||||
|
if expression_disabled:
|
||||||
|
row = row_expression_policy.disable_row_expression(row, expression_intensity_source)
|
||||||
|
return row
|
||||||
@@ -50,6 +50,7 @@ import pair_clothing # noqa: E402
|
|||||||
import prompt_builder as pb # noqa: E402
|
import prompt_builder as pb # noqa: E402
|
||||||
import pov_policy # noqa: E402
|
import pov_policy # noqa: E402
|
||||||
import row_normalization # noqa: E402
|
import row_normalization # noqa: E402
|
||||||
|
import row_assembly # noqa: E402
|
||||||
import route_metadata # noqa: E402
|
import route_metadata # noqa: E402
|
||||||
import row_camera # noqa: E402
|
import row_camera # noqa: E402
|
||||||
import row_category_route # noqa: E402
|
import row_category_route # noqa: E402
|
||||||
@@ -1687,6 +1688,99 @@ def smoke_row_rendering_policy() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def smoke_row_assembly_policy() -> None:
|
||||||
|
context = {
|
||||||
|
"subject": "configured cast",
|
||||||
|
"subject_phrase": "configured adult cast",
|
||||||
|
"age": "21+ adults",
|
||||||
|
"body": "varied adult builds",
|
||||||
|
"body_phrase": "varied adult builds",
|
||||||
|
"figure": "balanced cast",
|
||||||
|
"skin": "warm skin tones",
|
||||||
|
"hair": "dark hair",
|
||||||
|
"eyes": "brown eyes",
|
||||||
|
"cast_summary": "one woman and one man",
|
||||||
|
"scene_kind": "configured_cast",
|
||||||
|
"women_count": "1",
|
||||||
|
"men_count": "1",
|
||||||
|
"person_count": "2",
|
||||||
|
}
|
||||||
|
count_adjustment = {"requested_women_count": 1, "requested_men_count": 1}
|
||||||
|
kwargs = {
|
||||||
|
"row_number": 2,
|
||||||
|
"start_index": 10,
|
||||||
|
"category": {"name": "Axis Test", "slug": "axis_test"},
|
||||||
|
"subcategory": {
|
||||||
|
"name": "Custom Scene",
|
||||||
|
"slug": "custom_scene",
|
||||||
|
"prompt_template": "Scene: {item}. Composition: {composition_prompt}. Avoid: {negative_prompt}.",
|
||||||
|
"caption_template": "{trigger}, {item}, {scene}",
|
||||||
|
},
|
||||||
|
"item": {"text": "shared structured action"},
|
||||||
|
"context": context,
|
||||||
|
"subject_type": "configured_cast",
|
||||||
|
"item_text": "shared structured action",
|
||||||
|
"item_name": "shared_action",
|
||||||
|
"item_axis_values": {"action_family": "test_action"},
|
||||||
|
"item_template_metadata": {"position_key": "test_position"},
|
||||||
|
"formatter_hints": {"krea": ["test_hint"]},
|
||||||
|
"item_label": "Scene",
|
||||||
|
"style": "clean test style",
|
||||||
|
"positive_suffix": "clear readable composition.",
|
||||||
|
"negative_prompt": "bad anatomy",
|
||||||
|
"scene_slug": "test_room",
|
||||||
|
"scene": "warm test room",
|
||||||
|
"pose": "standing close",
|
||||||
|
"expression": "focused look",
|
||||||
|
"shared_expression": "focused look",
|
||||||
|
"character_expressions": ["Woman A has focused look"],
|
||||||
|
"character_expression_text": "Woman A has focused look",
|
||||||
|
"expression_disabled": True,
|
||||||
|
"expression_intensity": 0.7,
|
||||||
|
"expression_intensity_source": "disabled",
|
||||||
|
"composition": "centered frame",
|
||||||
|
"source_composition": "centered frame",
|
||||||
|
"role_graph": "the visible partner stays centered",
|
||||||
|
"source_role_graph": "Man A stays centered",
|
||||||
|
"action_family": "test_action",
|
||||||
|
"position_family": "standing",
|
||||||
|
"position_key": "test_position",
|
||||||
|
"position_keys": ["test_position"],
|
||||||
|
"pov_character_labels": ["Man A"],
|
||||||
|
"cast_descriptors": ["Woman A: adult woman", "Man A: adult man"],
|
||||||
|
"cast_descriptor_text": "Woman A: adult woman; Man A: adult man",
|
||||||
|
"seed_config": {"content_seed": 123},
|
||||||
|
"hardcore_position_config": {"family": "standing"},
|
||||||
|
"location_config": {"location": "test_room"},
|
||||||
|
"composition_config": {"composition": "centered"},
|
||||||
|
"content_seed_axis": "pose",
|
||||||
|
"count_adjustment": count_adjustment,
|
||||||
|
"applied_profile": {"name": "profile_a"},
|
||||||
|
"profile_status": "applied",
|
||||||
|
"applied_slot": {"label": "Woman A"},
|
||||||
|
"slot_status": "applied",
|
||||||
|
"character_slots": [{"label": "Woman A"}, {"label": "Man A"}],
|
||||||
|
}
|
||||||
|
row = row_assembly.assemble_custom_row(**kwargs)
|
||||||
|
delegated = pb._assemble_custom_row(**kwargs)
|
||||||
|
|
||||||
|
_expect(row == delegated, "Prompt builder row assembly wrapper should delegate without changing output")
|
||||||
|
_expect(row["id"] == "sxcp_0011", "Row assembly changed row indexing")
|
||||||
|
_expect(row["batch"] == "batch_001", "Row assembly changed batch calculation")
|
||||||
|
_expect(row["source"] == "json_category", "Row assembly lost source marker")
|
||||||
|
_expect(row["figure"] == "balanced cast", "Row assembly lost figure metadata")
|
||||||
|
_expect(row["formatter_hints"] == {"krea": ["test_hint"]}, "Row assembly lost formatter hints")
|
||||||
|
_expect(row["cast_count_adjustment"] == count_adjustment, "Row assembly lost configured-cast count adjustment")
|
||||||
|
_expect(row["content_seed_axis"] == "pose", "Row assembly lost content seed axis")
|
||||||
|
_expect("POV participant: Man A" in row["prompt"], "Row assembly lost POV prompt directive")
|
||||||
|
_expect("Characters: Woman A: adult woman; Man A: adult man." in row["prompt"], "Row assembly lost cast descriptor insertion")
|
||||||
|
_expect(row["caption"].endswith("Woman A: adult woman; Man A: adult man"), "Row assembly lost caption descriptor append")
|
||||||
|
_expect(row["expression"] == "", "Disabled expression should clear row expression")
|
||||||
|
_expect(row["expression_enabled"] is False, "Disabled expression should mark expression disabled")
|
||||||
|
_expect(row["expression_intensity"] is None, "Disabled expression should clear intensity")
|
||||||
|
_expect(row["expression_intensity_source"] == "disabled", "Disabled expression should preserve disabled source")
|
||||||
|
|
||||||
|
|
||||||
def smoke_formatter_input_policy() -> None:
|
def smoke_formatter_input_policy() -> None:
|
||||||
source_row = {
|
source_row = {
|
||||||
"prompt": "A simple adult portrait. Setting: quiet studio. Pose: standing calmly. Avoid: low quality.",
|
"prompt": "A simple adult portrait. Setting: quiet studio. Pose: standing calmly. Avoid: low quality.",
|
||||||
@@ -4486,6 +4580,7 @@ SMOKE_CASES: list[tuple[str, Callable[[], None]]] = [
|
|||||||
("character_profile_policy", smoke_character_profile_policy),
|
("character_profile_policy", smoke_character_profile_policy),
|
||||||
("row_normalization_policy", smoke_row_normalization_policy),
|
("row_normalization_policy", smoke_row_normalization_policy),
|
||||||
("row_rendering_policy", smoke_row_rendering_policy),
|
("row_rendering_policy", smoke_row_rendering_policy),
|
||||||
|
("row_assembly_policy", smoke_row_assembly_policy),
|
||||||
("formatter_input_policy", smoke_formatter_input_policy),
|
("formatter_input_policy", smoke_formatter_input_policy),
|
||||||
("formatter_cast_policy", smoke_formatter_cast_policy),
|
("formatter_cast_policy", smoke_formatter_cast_policy),
|
||||||
("caption_policy", smoke_caption_policy),
|
("caption_policy", smoke_caption_policy),
|
||||||
|
|||||||
Reference in New Issue
Block a user