Extract row text field resolution
This commit is contained in:
@@ -195,6 +195,10 @@ Already isolated:
|
|||||||
filtering, expression-disabled handling, per-character expression promotion,
|
filtering, expression-disabled handling, per-character expression promotion,
|
||||||
POV composition adaptation, and pose-category environment sanitizing live in
|
POV composition adaptation, and pose-category environment sanitizing live in
|
||||||
`row_prompt_axes.py`; `prompt_builder.py` keeps a public delegate wrapper.
|
`row_prompt_axes.py`; `prompt_builder.py` keeps a public delegate wrapper.
|
||||||
|
- row prompt/caption text-field resolution, prompt/caption template selection,
|
||||||
|
safe formatting, configured-cast descriptor insertion, and POV directive
|
||||||
|
insertion live in `row_rendering.py`; `prompt_builder.py` keeps public
|
||||||
|
delegate wrappers.
|
||||||
- row expression text cleanup, expression route resolution, expression
|
- row expression text cleanup, expression route resolution, expression
|
||||||
intensity weighting, character-slot/cast expression override resolution, and
|
intensity weighting, character-slot/cast expression override resolution, and
|
||||||
per-character expression picking plus action-aware character-expression
|
per-character expression picking plus action-aware character-expression
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ Core helper ownership:
|
|||||||
| `category_template_metadata.py` | Object-style item-template metadata extraction, action/position family normalization, position-key normalization, key merging, and audit validation errors. |
|
| `category_template_metadata.py` | Object-style item-template metadata extraction, action/position family normalization, position-key normalization, key merging, and audit validation errors. |
|
||||||
| `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 text-field resolution, template selection, safe formatting, default prompt templates, configured-cast descriptor insertion, and POV directive insertion. |
|
||||||
| `row_assembly.py` | Final custom-row dictionary assembly behind `CustomRowAssemblyRequest`, render-context metadata population, prompt/caption rendering delegation, row-base indexing, cast/profile/slot metadata copying, and disabled-expression cleanup. |
|
| `row_assembly.py` | Final custom-row dictionary assembly behind `CustomRowAssemblyRequest`, 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. |
|
||||||
|
|||||||
+13
-16
@@ -812,6 +812,14 @@ def _format(template: str, context: dict[str, Any]) -> str:
|
|||||||
return row_rendering_policy.format_template(template, context)
|
return row_rendering_policy.format_template(template, context)
|
||||||
|
|
||||||
|
|
||||||
|
def _row_text_fields(
|
||||||
|
category: dict[str, Any],
|
||||||
|
subcategory: dict[str, Any],
|
||||||
|
item: Any,
|
||||||
|
) -> row_rendering_policy.RowTextFields:
|
||||||
|
return row_rendering_policy.resolve_row_text_fields(category, subcategory, item)
|
||||||
|
|
||||||
|
|
||||||
def _clean_prompt_punctuation(text: str) -> str:
|
def _clean_prompt_punctuation(text: str) -> str:
|
||||||
return row_expression_policy.clean_prompt_punctuation(text)
|
return row_expression_policy.clean_prompt_punctuation(text)
|
||||||
|
|
||||||
@@ -2269,18 +2277,7 @@ def _build_custom_row(
|
|||||||
position_key = str(action_route.get("position_key") or "")
|
position_key = str(action_route.get("position_key") or "")
|
||||||
action_family = str(action_route.get("action_family") or "")
|
action_family = str(action_route.get("action_family") or "")
|
||||||
|
|
||||||
negative_prompt = str(_merged_field(category, subcategory, item, "negative_prompt", g.NEGATIVE_PROMPT))
|
text_fields = _row_text_fields(category, subcategory, item)
|
||||||
positive_suffix = str(_merged_field(category, subcategory, item, "positive_suffix", GENERIC_POSITIVE_SUFFIX))
|
|
||||||
style = str(
|
|
||||||
_merged_field(
|
|
||||||
category,
|
|
||||||
subcategory,
|
|
||||||
item,
|
|
||||||
"style",
|
|
||||||
"sexy but tasteful adult pin-up coloured-pencil comic illustration",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
item_label = str(_merged_field(category, subcategory, item, "item_label", category["name"]))
|
|
||||||
|
|
||||||
assembly_request = row_assembly_policy.CustomRowAssemblyRequest(
|
assembly_request = row_assembly_policy.CustomRowAssemblyRequest(
|
||||||
row_number=row_number,
|
row_number=row_number,
|
||||||
@@ -2295,10 +2292,10 @@ def _build_custom_row(
|
|||||||
item_axis_values=item_axis_values,
|
item_axis_values=item_axis_values,
|
||||||
item_template_metadata=item_template_metadata,
|
item_template_metadata=item_template_metadata,
|
||||||
formatter_hints=item_formatter_hints,
|
formatter_hints=item_formatter_hints,
|
||||||
item_label=item_label,
|
item_label=text_fields.item_label,
|
||||||
style=style,
|
style=text_fields.style,
|
||||||
positive_suffix=positive_suffix,
|
positive_suffix=text_fields.positive_suffix,
|
||||||
negative_prompt=negative_prompt,
|
negative_prompt=text_fields.negative_prompt,
|
||||||
scene_slug=scene_slug,
|
scene_slug=scene_slug,
|
||||||
scene=scene,
|
scene=scene,
|
||||||
pose=pose,
|
pose=pose,
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from string import Formatter
|
from string import Formatter
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
from . import category_library as category_policy
|
||||||
|
from . import generate_prompt_batches as g
|
||||||
from . import row_camera as row_camera_policy
|
from . import row_camera as row_camera_policy
|
||||||
except ImportError: # Allows local smoke tests from the repository root.
|
except ImportError: # Allows local smoke tests from the repository root.
|
||||||
|
import category_library as category_policy
|
||||||
|
import generate_prompt_batches as g
|
||||||
import row_camera as row_camera_policy
|
import row_camera as row_camera_policy
|
||||||
|
|
||||||
|
|
||||||
@@ -14,6 +19,17 @@ GENERIC_POSITIVE_SUFFIX = (
|
|||||||
"pastel skin tones, muted blues and pinks, warm sensual lighting, and tactile textured paper."
|
"pastel skin tones, muted blues and pinks, warm sensual lighting, and tactile textured paper."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
DEFAULT_STYLE = "sexy but tasteful adult pin-up coloured-pencil comic illustration"
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class RowTextFields:
|
||||||
|
negative_prompt: str
|
||||||
|
positive_suffix: str
|
||||||
|
style: str
|
||||||
|
item_label: str
|
||||||
|
|
||||||
|
|
||||||
SINGLE_TEMPLATE = (
|
SINGLE_TEMPLATE = (
|
||||||
"A {subject}: {style}, {age}, {body_phrase}, {skin}, {hair}, {eyes}. "
|
"A {subject}: {style}, {age}, {body_phrase}, {skin}, {hair}, {eyes}. "
|
||||||
"{item_label}: {item}. Scene: {scene}. Pose: {pose}. Facial expression: {expression}. "
|
"{item_label}: {item}. Scene: {scene}. Pose: {pose}. Facial expression: {expression}. "
|
||||||
@@ -56,6 +72,19 @@ def format_template(template: str, context: dict[str, Any]) -> str:
|
|||||||
return template.format_map(safe_context)
|
return template.format_map(safe_context)
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_row_text_fields(category: dict[str, Any], subcategory: dict[str, Any], item: Any) -> RowTextFields:
|
||||||
|
return RowTextFields(
|
||||||
|
negative_prompt=str(
|
||||||
|
category_policy.merged_field(category, subcategory, item, "negative_prompt", g.NEGATIVE_PROMPT)
|
||||||
|
),
|
||||||
|
positive_suffix=str(
|
||||||
|
category_policy.merged_field(category, subcategory, item, "positive_suffix", GENERIC_POSITIVE_SUFFIX)
|
||||||
|
),
|
||||||
|
style=str(category_policy.merged_field(category, subcategory, item, "style", DEFAULT_STYLE)),
|
||||||
|
item_label=str(category_policy.merged_field(category, subcategory, item, "item_label", category["name"])),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def default_prompt_template(subject_type: str) -> str:
|
def default_prompt_template(subject_type: str) -> str:
|
||||||
if subject_type in ("woman", "man"):
|
if subject_type in ("woman", "man"):
|
||||||
return SINGLE_TEMPLATE
|
return SINGLE_TEMPLATE
|
||||||
|
|||||||
@@ -1714,6 +1714,37 @@ def smoke_row_rendering_policy() -> None:
|
|||||||
row_rendering.prompt_template_for({}, {}, {}, "group") == row_rendering.GROUP_TEMPLATE,
|
row_rendering.prompt_template_for({}, {}, {}, "group") == row_rendering.GROUP_TEMPLATE,
|
||||||
"Row rendering default group template changed",
|
"Row rendering default group template changed",
|
||||||
)
|
)
|
||||||
|
category_text = {
|
||||||
|
"name": "Category Label",
|
||||||
|
"negative_prompt": "category negative",
|
||||||
|
"positive_suffix": "category suffix",
|
||||||
|
"style": "category style",
|
||||||
|
"item_label": "Category Item",
|
||||||
|
}
|
||||||
|
subcategory_text = {
|
||||||
|
"negative_prompt": "subcategory negative",
|
||||||
|
"positive_suffix": "subcategory suffix",
|
||||||
|
"style": "subcategory style",
|
||||||
|
}
|
||||||
|
item_text = {
|
||||||
|
"negative_prompt": "item negative",
|
||||||
|
"style": "item style",
|
||||||
|
}
|
||||||
|
_expect(
|
||||||
|
pb._row_text_fields(category_text, subcategory_text, item_text)
|
||||||
|
== row_rendering.resolve_row_text_fields(category_text, subcategory_text, item_text),
|
||||||
|
"Prompt builder row text field wrapper should delegate to row_rendering",
|
||||||
|
)
|
||||||
|
text_fields = row_rendering.resolve_row_text_fields(category_text, subcategory_text, item_text)
|
||||||
|
_expect(text_fields.negative_prompt == "item negative", "Row text fields did not prefer item negative prompt")
|
||||||
|
_expect(text_fields.positive_suffix == "subcategory suffix", "Row text fields did not prefer subcategory suffix")
|
||||||
|
_expect(text_fields.style == "item style", "Row text fields did not prefer item style")
|
||||||
|
_expect(text_fields.item_label == "Category Item", "Row text fields did not fall back to category item label")
|
||||||
|
default_text_fields = row_rendering.resolve_row_text_fields({"name": "Default Category"}, {}, {})
|
||||||
|
_expect(default_text_fields.negative_prompt, "Row text fields lost default negative prompt")
|
||||||
|
_expect(default_text_fields.positive_suffix == row_rendering.GENERIC_POSITIVE_SUFFIX, "Row text fields lost suffix default")
|
||||||
|
_expect(default_text_fields.style == row_rendering.DEFAULT_STYLE, "Row text fields lost style default")
|
||||||
|
_expect(default_text_fields.item_label == "Default Category", "Row text fields lost category-name label default")
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"trigger": Trigger,
|
"trigger": Trigger,
|
||||||
|
|||||||
Reference in New Issue
Block a user