Extract Insta pair output assembly
This commit is contained in:
@@ -147,14 +147,11 @@ Keep here:
|
|||||||
- soft/hard row creation;
|
- soft/hard row creation;
|
||||||
- continuity policy;
|
- continuity policy;
|
||||||
- softcore cast policy;
|
- softcore cast policy;
|
||||||
- pair metadata shape.
|
|
||||||
|
|
||||||
Improve later:
|
Improve later:
|
||||||
|
|
||||||
- make a single pair metadata sanitizer that normalizes `softcore_row`,
|
|
||||||
`hardcore_row`, pair prompts, negatives, captions, and camera fields;
|
|
||||||
- split pair assembly into small functions by phase:
|
- split pair assembly into small functions by phase:
|
||||||
`build_soft_row`, `build_hard_row`, `assemble_pair_metadata`.
|
`build_soft_row`, `build_hard_row`.
|
||||||
|
|
||||||
Already isolated:
|
Already isolated:
|
||||||
|
|
||||||
@@ -166,6 +163,9 @@ Already isolated:
|
|||||||
including action-aware body-access flags, conflicting outfit-piece cleanup,
|
including action-aware body-access flags, conflicting outfit-piece cleanup,
|
||||||
default visible-men clothing, character-clothing override handling, and final
|
default visible-men clothing, character-clothing override handling, and final
|
||||||
root clothing-state assembly.
|
root clothing-state assembly.
|
||||||
|
- final pair output assembly lives in `pair_output.py`, including soft/hard
|
||||||
|
prompt strings, trigger preservation, negatives, captions, and root metadata
|
||||||
|
shape.
|
||||||
|
|
||||||
### Krea2 Formatter Path
|
### Krea2 Formatter Path
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ Core helper ownership:
|
|||||||
| `category_library.py` | JSON category loading, subcategory normalization, named scene/expression/composition pool loading, cast compatibility filtering, exact subcategory lookup, and inheritance-based pool merging. |
|
| `category_library.py` | JSON category loading, subcategory normalization, named scene/expression/composition pool loading, cast compatibility filtering, exact subcategory lookup, and inheritance-based pool merging. |
|
||||||
| `pair_camera.py` | Insta/OF soft/hard camera route resolution, same-as-softcore camera mode, camera-detail override, camera-aware composition mutation, POV camera suppression, and synchronized row/root camera metadata. |
|
| `pair_camera.py` | Insta/OF soft/hard camera route resolution, same-as-softcore camera mode, camera-detail override, camera-aware composition mutation, POV camera suppression, and synchronized row/root camera metadata. |
|
||||||
| `pair_clothing.py` | Insta/OF hardcore clothing continuity, action-aware body-access flags, conflicting outfit-piece cleanup, default visible-men clothing, and final root clothing-state assembly. |
|
| `pair_clothing.py` | Insta/OF hardcore clothing continuity, action-aware body-access flags, conflicting outfit-piece cleanup, default visible-men clothing, and final root clothing-state assembly. |
|
||||||
|
| `pair_output.py` | Insta/OF final pair prompts, trigger preservation, negative prompts, captions, and root pair metadata assembly. |
|
||||||
| `hardcore_role_graphs.py` | Source role graph construction for hardcore configured-cast rows, including POV-aware interaction geometry. |
|
| `hardcore_role_graphs.py` | Source role graph construction for hardcore configured-cast rows, including POV-aware interaction geometry. |
|
||||||
| `hardcore_role_fallback.py` | Solo, same-sex, mixed group fallback, and support-partner role graph wording for configured casts. |
|
| `hardcore_role_fallback.py` | Solo, same-sex, mixed group fallback, and support-partner role graph wording for configured casts. |
|
||||||
| `hardcore_role_interaction.py` | Foreplay, manual stimulation, body worship, clothing transition, dominant guidance, camera performance, aftercare, and group coordination role graph wording. |
|
| `hardcore_role_interaction.py` | Foreplay, manual stimulation, body worship, clothing transition, dominant guidance, camera performance, aftercare, and group coordination role graph wording. |
|
||||||
@@ -456,8 +457,8 @@ plain prompt text. When debugging, inspect these fields before editing pools.
|
|||||||
| `shared_descriptor` | Soft row descriptor | Pair formatters | Primary creator descriptor. |
|
| `shared_descriptor` | Soft row descriptor | Pair formatters | Primary creator descriptor. |
|
||||||
| `shared_cast_descriptors` | Cast descriptor builder | Pair formatters | Full cast descriptor list. |
|
| `shared_cast_descriptors` | Cast descriptor builder | Pair formatters | Full cast descriptor list. |
|
||||||
| `softcore_row`, `hardcore_row` | Pair route | Pair formatters | Full normal metadata rows for each side. |
|
| `softcore_row`, `hardcore_row` | Pair route | Pair formatters | Full normal metadata rows for each side. |
|
||||||
| `softcore_prompt`, `hardcore_prompt` | Pair assembly | Direct output/fallback | Raw pair prompts before formatter rewrite. |
|
| `softcore_prompt`, `hardcore_prompt` | `pair_output.py` | Direct output/fallback | Raw pair prompts before formatter rewrite. |
|
||||||
| `softcore_negative_prompt`, `hardcore_negative_prompt` | Pair assembly | Formatter negatives | Separate negatives for each side. |
|
| `softcore_negative_prompt`, `hardcore_negative_prompt` | `pair_output.py` | Formatter negatives | Separate negatives for each side. |
|
||||||
| `softcore_partner_styling` | `_insta_of_partner_styling` | Krea/SDXL pair branch | Partner softcore clothing and pose when same-cast softcore is enabled. |
|
| `softcore_partner_styling` | `_insta_of_partner_styling` | Krea/SDXL pair branch | Partner softcore clothing and pose when same-cast softcore is enabled. |
|
||||||
| `character_hardcore_clothing` | Character slots | Krea pair branch | Explicit per-character hardcore clothing state. |
|
| `character_hardcore_clothing` | Character slots | Krea pair branch | Explicit per-character hardcore clothing state. |
|
||||||
| `default_man_hardcore_clothing` | Pair fallback | Krea pair branch | Auto clothing for visible men without configured clothing. |
|
| `default_man_hardcore_clothing` | Pair fallback | Krea pair branch | Auto clothing for visible men without configured clothing. |
|
||||||
@@ -851,8 +852,8 @@ Use these traces to narrow a problem in one pass.
|
|||||||
1. Check whether the prompt came from pair softcore or normal category builder.
|
1. Check whether the prompt came from pair softcore or normal category builder.
|
||||||
2. In pair softcore, inspect `softcore_partner_styling`, `softcore_row.item`,
|
2. In pair softcore, inspect `softcore_partner_styling`, `softcore_row.item`,
|
||||||
`softcore_row.pose`, and options `softcore_cast`.
|
`softcore_row.pose`, and options `softcore_cast`.
|
||||||
3. If the raw soft prompt contains awkward defensive clauses, fix
|
3. If the raw soft prompt contains awkward defensive clauses, inspect
|
||||||
`build_insta_of_pair` soft prompt assembly.
|
`pair_output.py`.
|
||||||
4. If Krea adds the awkwardness, inspect `_insta_pair_to_krea`.
|
4. If Krea adds the awkwardness, inspect `_insta_pair_to_krea`.
|
||||||
|
|
||||||
### Location composition mentions irrelevant props
|
### Location composition mentions irrelevant props
|
||||||
|
|||||||
+190
@@ -0,0 +1,190 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any, Callable
|
||||||
|
|
||||||
|
try:
|
||||||
|
from .prompt_hygiene import sanitize_caption_text, sanitize_negative_text, sanitize_prompt_text
|
||||||
|
except ImportError: # Allows local smoke tests with `python tools/prompt_smoke.py`.
|
||||||
|
from prompt_hygiene import sanitize_caption_text, sanitize_negative_text, sanitize_prompt_text
|
||||||
|
|
||||||
|
|
||||||
|
def _labeled_expression_sentence(label: str, expression: Any) -> str:
|
||||||
|
expression = str(expression or "").strip()
|
||||||
|
if not expression:
|
||||||
|
return ""
|
||||||
|
return f"{label}: {expression}. "
|
||||||
|
|
||||||
|
|
||||||
|
def _prepend_trigger(prompt: str, trigger: str, enabled: bool) -> str:
|
||||||
|
trigger = trigger.strip()
|
||||||
|
if not enabled or not trigger:
|
||||||
|
return prompt
|
||||||
|
if prompt.lower().startswith(trigger.lower()):
|
||||||
|
return prompt
|
||||||
|
return f"{trigger}, {prompt}"
|
||||||
|
|
||||||
|
|
||||||
|
def _combined_negative(base: str, extra: str) -> str:
|
||||||
|
parts = [part.strip() for part in (base, extra) if part and part.strip()]
|
||||||
|
return ", ".join(parts)
|
||||||
|
|
||||||
|
|
||||||
|
def assemble_insta_pair_metadata(
|
||||||
|
*,
|
||||||
|
active_trigger: str,
|
||||||
|
prepend_trigger_to_prompt: bool,
|
||||||
|
extra_positive: str,
|
||||||
|
extra_negative: str,
|
||||||
|
soft_negative_base: str,
|
||||||
|
hard_negative_base: str,
|
||||||
|
options: dict[str, Any],
|
||||||
|
platform_style: str,
|
||||||
|
soft_descriptor_sentence: str,
|
||||||
|
soft_level: str,
|
||||||
|
soft_cast: str,
|
||||||
|
soft_cast_presence: str,
|
||||||
|
soft_cast_styling_sentence: str,
|
||||||
|
soft_row: dict[str, Any],
|
||||||
|
soft_camera_scene_sentence: str,
|
||||||
|
soft_camera_sentence: str,
|
||||||
|
hard_level: str,
|
||||||
|
hard_cast: str,
|
||||||
|
cast_descriptor_text: str,
|
||||||
|
pov_directive: str,
|
||||||
|
pov_character_labels: list[str],
|
||||||
|
hard_clothing_sentence: str,
|
||||||
|
hard_row: dict[str, Any],
|
||||||
|
hard_scene: str,
|
||||||
|
hard_camera_scene_sentence: str,
|
||||||
|
hard_composition: str,
|
||||||
|
hard_detail_directive: str,
|
||||||
|
hard_camera_sentence: str,
|
||||||
|
descriptor: str,
|
||||||
|
soft_partner_outfit_text: str,
|
||||||
|
soft_partner_styling: dict[str, Any],
|
||||||
|
soft_camera_scene_directive: str,
|
||||||
|
soft_camera_config: dict[str, Any],
|
||||||
|
soft_camera_directive: str,
|
||||||
|
hard_camera_scene_directive: str,
|
||||||
|
hard_camera_config: dict[str, Any],
|
||||||
|
hard_camera_directive: str,
|
||||||
|
camera_caption_text: Callable[[dict[str, Any]], str],
|
||||||
|
cast_descriptors: list[str],
|
||||||
|
character_hardcore_clothing_entries: list[str],
|
||||||
|
default_man_hardcore_clothing_entries: list[str],
|
||||||
|
hard_clothing_state: str,
|
||||||
|
hard_detail_density: str,
|
||||||
|
hard_women_count: int,
|
||||||
|
hard_men_count: int,
|
||||||
|
character_slots: list[dict[str, Any]],
|
||||||
|
character_slot_map: dict[str, dict[str, Any]],
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
soft_prompt = (
|
||||||
|
f"Insta/OF softcore mode: {platform_style}. "
|
||||||
|
f"{soft_descriptor_sentence}"
|
||||||
|
f"Softcore setup: {soft_level}. Cast: {soft_cast}. "
|
||||||
|
f"{soft_cast_presence}"
|
||||||
|
f"{soft_cast_styling_sentence}"
|
||||||
|
f"{soft_row['softcore_item_prompt_label']}: {soft_row['item']}. Pose: {soft_row['pose']}. Setting: {soft_row['scene_text']}. "
|
||||||
|
f"{soft_camera_scene_sentence}"
|
||||||
|
f"{_labeled_expression_sentence('Facial expression', soft_row.get('expression'))}"
|
||||||
|
f"Composition: {soft_row['composition']}. "
|
||||||
|
f"{soft_camera_sentence}"
|
||||||
|
"Keep the softcore version seductive, creator-shot, and styled as a soft teaser. "
|
||||||
|
f"{soft_row['positive_suffix']}."
|
||||||
|
)
|
||||||
|
hard_prompt = (
|
||||||
|
f"Insta/OF hardcore mode: {platform_style}. "
|
||||||
|
f"Hardcore setup: {hard_level}. Cast: {hard_cast}. "
|
||||||
|
f"Cast descriptors: {cast_descriptor_text}. "
|
||||||
|
f"{pov_directive + ' ' if pov_directive else ''}"
|
||||||
|
f"{'Keep Woman A visually central from the POV camera. ' if pov_character_labels else 'Keep Woman A visually central. '}"
|
||||||
|
f"{hard_clothing_sentence}"
|
||||||
|
f"Role graph: {hard_row['role_graph']} Sexual scene: {hard_row['item']}. "
|
||||||
|
f"Setting: {hard_scene}. "
|
||||||
|
f"{hard_camera_scene_sentence}"
|
||||||
|
f"{_labeled_expression_sentence('Facial expressions', hard_row.get('expression'))}"
|
||||||
|
f"Composition: {hard_composition}. "
|
||||||
|
f"{hard_detail_directive}"
|
||||||
|
f"{hard_camera_sentence}"
|
||||||
|
f"{hard_row['positive_suffix']}."
|
||||||
|
)
|
||||||
|
if extra_positive.strip():
|
||||||
|
soft_prompt = f"{soft_prompt.rstrip()} {extra_positive.strip()}"
|
||||||
|
hard_prompt = f"{hard_prompt.rstrip()} {extra_positive.strip()}"
|
||||||
|
|
||||||
|
soft_prompt = _prepend_trigger(soft_prompt, active_trigger, bool(prepend_trigger_to_prompt))
|
||||||
|
hard_prompt = _prepend_trigger(hard_prompt, active_trigger, bool(prepend_trigger_to_prompt))
|
||||||
|
soft_prompt = sanitize_prompt_text(soft_prompt, triggers=(active_trigger,))
|
||||||
|
hard_prompt = sanitize_prompt_text(hard_prompt, triggers=(active_trigger,))
|
||||||
|
soft_negative = sanitize_negative_text(_combined_negative(soft_negative_base, extra_negative))
|
||||||
|
hard_negative = sanitize_negative_text(_combined_negative(hard_negative_base, extra_negative))
|
||||||
|
|
||||||
|
soft_caption_parts = [
|
||||||
|
active_trigger,
|
||||||
|
"Insta/OF softcore mode",
|
||||||
|
descriptor,
|
||||||
|
soft_level,
|
||||||
|
soft_row["item"],
|
||||||
|
soft_row["pose"],
|
||||||
|
soft_partner_outfit_text,
|
||||||
|
soft_partner_styling["pose"],
|
||||||
|
soft_row["scene_text"],
|
||||||
|
soft_camera_scene_directive,
|
||||||
|
soft_row["composition"],
|
||||||
|
camera_caption_text(soft_camera_config) if soft_camera_directive else "",
|
||||||
|
]
|
||||||
|
soft_caption = sanitize_caption_text(
|
||||||
|
", ".join(str(part).strip() for part in soft_caption_parts if str(part).strip()),
|
||||||
|
triggers=(active_trigger,),
|
||||||
|
)
|
||||||
|
hard_caption_parts = [
|
||||||
|
active_trigger,
|
||||||
|
"Insta/OF hardcore mode",
|
||||||
|
"Woman A",
|
||||||
|
descriptor,
|
||||||
|
hard_cast,
|
||||||
|
hard_row["role_graph"],
|
||||||
|
hard_row["item"],
|
||||||
|
hard_scene,
|
||||||
|
hard_camera_scene_directive,
|
||||||
|
hard_composition,
|
||||||
|
camera_caption_text(hard_camera_config) if hard_camera_directive else "",
|
||||||
|
]
|
||||||
|
hard_caption = sanitize_caption_text(
|
||||||
|
", ".join(str(part).strip() for part in hard_caption_parts if str(part).strip()),
|
||||||
|
triggers=(active_trigger,),
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"mode": "Insta/OF",
|
||||||
|
"options": options,
|
||||||
|
"shared_descriptor": descriptor,
|
||||||
|
"shared_cast_descriptors": cast_descriptors,
|
||||||
|
"pov_character_labels": pov_character_labels,
|
||||||
|
"pov_prompt_directive": pov_directive,
|
||||||
|
"softcore_partner_styling": soft_partner_styling,
|
||||||
|
"character_hardcore_clothing": character_hardcore_clothing_entries,
|
||||||
|
"default_man_hardcore_clothing": default_man_hardcore_clothing_entries,
|
||||||
|
"hardcore_clothing_state": hard_clothing_state,
|
||||||
|
"hardcore_detail_density": hard_detail_density,
|
||||||
|
"hardcore_position_config": hard_row.get("hardcore_position_config", {}),
|
||||||
|
"softcore_prompt": soft_prompt,
|
||||||
|
"hardcore_prompt": hard_prompt,
|
||||||
|
"softcore_negative_prompt": soft_negative,
|
||||||
|
"hardcore_negative_prompt": hard_negative,
|
||||||
|
"softcore_caption": soft_caption,
|
||||||
|
"hardcore_caption": hard_caption,
|
||||||
|
"softcore_row": soft_row,
|
||||||
|
"hardcore_row": hard_row,
|
||||||
|
"hardcore_women_count": hard_women_count,
|
||||||
|
"hardcore_men_count": hard_men_count,
|
||||||
|
"character_cast_slots": character_slots,
|
||||||
|
"character_slot_labels": sorted(character_slot_map),
|
||||||
|
"softcore_camera_config": soft_camera_config,
|
||||||
|
"hardcore_camera_config": hard_camera_config,
|
||||||
|
"softcore_camera_directive": soft_camera_directive,
|
||||||
|
"hardcore_camera_directive": hard_camera_directive,
|
||||||
|
"softcore_camera_scene_directive": soft_camera_scene_directive,
|
||||||
|
"hardcore_camera_scene_directive": hard_camera_scene_directive,
|
||||||
|
}
|
||||||
+50
-118
@@ -27,6 +27,7 @@ try:
|
|||||||
from . import generate_prompt_batches as g
|
from . import generate_prompt_batches as g
|
||||||
from . import pair_clothing
|
from . import pair_clothing
|
||||||
from . import pair_camera
|
from . import pair_camera
|
||||||
|
from . import pair_output
|
||||||
from . import scene_camera_adapters
|
from . import scene_camera_adapters
|
||||||
from .hardcore_text_cleanup import (
|
from .hardcore_text_cleanup import (
|
||||||
sanitize_hardcore_axis_values as _sanitize_hardcore_axis_values,
|
sanitize_hardcore_axis_values as _sanitize_hardcore_axis_values,
|
||||||
@@ -58,6 +59,7 @@ except ImportError: # Allows local smoke tests with `python -c`.
|
|||||||
import generate_prompt_batches as g
|
import generate_prompt_batches as g
|
||||||
import pair_clothing
|
import pair_clothing
|
||||||
import pair_camera
|
import pair_camera
|
||||||
|
import pair_output
|
||||||
import scene_camera_adapters
|
import scene_camera_adapters
|
||||||
from hardcore_text_cleanup import (
|
from hardcore_text_cleanup import (
|
||||||
sanitize_hardcore_axis_values as _sanitize_hardcore_axis_values,
|
sanitize_hardcore_axis_values as _sanitize_hardcore_axis_values,
|
||||||
@@ -2797,13 +2799,6 @@ def _disable_row_expression(row: dict[str, Any], source: str = "disabled") -> di
|
|||||||
return row
|
return row
|
||||||
|
|
||||||
|
|
||||||
def _labeled_expression_sentence(label: str, expression: Any) -> str:
|
|
||||||
expression = str(expression or "").strip()
|
|
||||||
if not expression:
|
|
||||||
return ""
|
|
||||||
return f"{label}: {expression}. "
|
|
||||||
|
|
||||||
|
|
||||||
def _prepend_trigger(prompt: str, trigger: str, enabled: bool) -> str:
|
def _prepend_trigger(prompt: str, trigger: str, enabled: bool) -> str:
|
||||||
trigger = trigger.strip()
|
trigger = trigger.strip()
|
||||||
if not enabled or not trigger:
|
if not enabled or not trigger:
|
||||||
@@ -6959,10 +6954,6 @@ def _insta_of_partner_styling(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _insta_of_active_trigger(prompt: str, trigger: str, enabled: bool) -> str:
|
|
||||||
return _prepend_trigger(prompt, trigger, enabled)
|
|
||||||
|
|
||||||
|
|
||||||
def build_insta_of_pair(
|
def build_insta_of_pair(
|
||||||
row_number: int,
|
row_number: int,
|
||||||
start_index: int,
|
start_index: int,
|
||||||
@@ -7256,111 +7247,52 @@ def build_insta_of_pair(
|
|||||||
else f"Woman A: {descriptor}. "
|
else f"Woman A: {descriptor}. "
|
||||||
)
|
)
|
||||||
|
|
||||||
soft_prompt = (
|
return pair_output.assemble_insta_pair_metadata(
|
||||||
f"Insta/OF softcore mode: {platform_style}. "
|
active_trigger=active_trigger,
|
||||||
f"{soft_descriptor_sentence}"
|
prepend_trigger_to_prompt=bool(prepend_trigger_to_prompt),
|
||||||
f"Softcore setup: {soft_level}. Cast: {soft_cast}. "
|
extra_positive=extra_positive,
|
||||||
f"{soft_cast_presence}"
|
extra_negative=extra_negative,
|
||||||
f"{soft_cast_styling_sentence}"
|
soft_negative_base=INSTA_OF_SOFT_NEGATIVE,
|
||||||
f"{soft_row['softcore_item_prompt_label']}: {soft_row['item']}. Pose: {soft_row['pose']}. Setting: {soft_row['scene_text']}. "
|
hard_negative_base=INSTA_OF_NEGATIVE,
|
||||||
f"{soft_camera_scene_sentence}"
|
options=options,
|
||||||
f"{_labeled_expression_sentence('Facial expression', soft_row.get('expression'))}"
|
platform_style=platform_style,
|
||||||
f"Composition: {soft_row['composition']}. "
|
soft_descriptor_sentence=soft_descriptor_sentence,
|
||||||
f"{soft_camera_sentence}"
|
soft_level=soft_level,
|
||||||
"Keep the softcore version seductive, creator-shot, and styled as a soft teaser. "
|
soft_cast=soft_cast,
|
||||||
f"{soft_row['positive_suffix']}."
|
soft_cast_presence=soft_cast_presence,
|
||||||
|
soft_cast_styling_sentence=soft_cast_styling_sentence,
|
||||||
|
soft_row=soft_row,
|
||||||
|
soft_camera_scene_sentence=soft_camera_scene_sentence,
|
||||||
|
soft_camera_sentence=soft_camera_sentence,
|
||||||
|
hard_level=hard_level,
|
||||||
|
hard_cast=hard_cast,
|
||||||
|
cast_descriptor_text=cast_descriptor_text,
|
||||||
|
pov_directive=pov_directive,
|
||||||
|
pov_character_labels=pov_character_labels,
|
||||||
|
hard_clothing_sentence=hard_clothing_sentence,
|
||||||
|
hard_row=hard_row,
|
||||||
|
hard_scene=hard_scene,
|
||||||
|
hard_camera_scene_sentence=hard_camera_scene_sentence,
|
||||||
|
hard_composition=hard_composition,
|
||||||
|
hard_detail_directive=hard_detail_directive,
|
||||||
|
hard_camera_sentence=hard_camera_sentence,
|
||||||
|
descriptor=descriptor,
|
||||||
|
soft_partner_outfit_text=soft_partner_outfit_text,
|
||||||
|
soft_partner_styling=soft_partner_styling,
|
||||||
|
soft_camera_scene_directive=soft_camera_scene_directive,
|
||||||
|
soft_camera_config=soft_camera_config,
|
||||||
|
soft_camera_directive=soft_camera_directive,
|
||||||
|
hard_camera_scene_directive=hard_camera_scene_directive,
|
||||||
|
hard_camera_config=hard_camera_config,
|
||||||
|
hard_camera_directive=hard_camera_directive,
|
||||||
|
camera_caption_text=_camera_caption_text,
|
||||||
|
cast_descriptors=cast_descriptors,
|
||||||
|
character_hardcore_clothing_entries=character_hardcore_clothing_entries,
|
||||||
|
default_man_hardcore_clothing_entries=default_man_hardcore_clothing_entries,
|
||||||
|
hard_clothing_state=hard_clothing_state,
|
||||||
|
hard_detail_density=hard_detail_density,
|
||||||
|
hard_women_count=hard_women_count,
|
||||||
|
hard_men_count=hard_men_count,
|
||||||
|
character_slots=character_slots,
|
||||||
|
character_slot_map=character_slot_map,
|
||||||
)
|
)
|
||||||
hard_prompt = (
|
|
||||||
f"Insta/OF hardcore mode: {platform_style}. "
|
|
||||||
f"Hardcore setup: {hard_level}. Cast: {hard_cast}. "
|
|
||||||
f"Cast descriptors: {cast_descriptor_text}. "
|
|
||||||
f"{pov_directive + ' ' if pov_directive else ''}"
|
|
||||||
f"{'Keep Woman A visually central from the POV camera. ' if pov_character_labels else 'Keep Woman A visually central. '}"
|
|
||||||
f"{hard_clothing_sentence}"
|
|
||||||
f"Role graph: {hard_row['role_graph']} Sexual scene: {hard_row['item']}. "
|
|
||||||
f"Setting: {hard_scene}. "
|
|
||||||
f"{hard_camera_scene_sentence}"
|
|
||||||
f"{_labeled_expression_sentence('Facial expressions', hard_row.get('expression'))}"
|
|
||||||
f"Composition: {hard_composition}. "
|
|
||||||
f"{hard_detail_directive}"
|
|
||||||
f"{hard_camera_sentence}"
|
|
||||||
f"{hard_row['positive_suffix']}."
|
|
||||||
)
|
|
||||||
if extra_positive.strip():
|
|
||||||
soft_prompt = f"{soft_prompt.rstrip()} {extra_positive.strip()}"
|
|
||||||
hard_prompt = f"{hard_prompt.rstrip()} {extra_positive.strip()}"
|
|
||||||
|
|
||||||
soft_prompt = _insta_of_active_trigger(soft_prompt, active_trigger, bool(prepend_trigger_to_prompt))
|
|
||||||
hard_prompt = _insta_of_active_trigger(hard_prompt, active_trigger, bool(prepend_trigger_to_prompt))
|
|
||||||
soft_prompt = sanitize_prompt_text(soft_prompt, triggers=(active_trigger,))
|
|
||||||
hard_prompt = sanitize_prompt_text(hard_prompt, triggers=(active_trigger,))
|
|
||||||
soft_negative = sanitize_negative_text(_combined_negative(INSTA_OF_SOFT_NEGATIVE, extra_negative))
|
|
||||||
hard_negative = sanitize_negative_text(_combined_negative(INSTA_OF_NEGATIVE, extra_negative))
|
|
||||||
soft_caption_parts = [
|
|
||||||
active_trigger,
|
|
||||||
"Insta/OF softcore mode",
|
|
||||||
descriptor,
|
|
||||||
soft_level,
|
|
||||||
soft_row["item"],
|
|
||||||
soft_row["pose"],
|
|
||||||
soft_partner_outfit_text,
|
|
||||||
soft_partner_styling["pose"],
|
|
||||||
soft_row["scene_text"],
|
|
||||||
soft_camera_scene_directive,
|
|
||||||
soft_row["composition"],
|
|
||||||
_camera_caption_text(soft_camera_config) if soft_camera_directive else "",
|
|
||||||
]
|
|
||||||
soft_caption = sanitize_caption_text(
|
|
||||||
", ".join(str(part).strip() for part in soft_caption_parts if str(part).strip()),
|
|
||||||
triggers=(active_trigger,),
|
|
||||||
)
|
|
||||||
hard_caption_parts = [
|
|
||||||
active_trigger,
|
|
||||||
"Insta/OF hardcore mode",
|
|
||||||
"Woman A",
|
|
||||||
descriptor,
|
|
||||||
hard_cast,
|
|
||||||
hard_row["role_graph"],
|
|
||||||
hard_row["item"],
|
|
||||||
hard_scene,
|
|
||||||
hard_camera_scene_directive,
|
|
||||||
hard_composition,
|
|
||||||
_camera_caption_text(hard_camera_config) if hard_camera_directive else "",
|
|
||||||
]
|
|
||||||
hard_caption = sanitize_caption_text(
|
|
||||||
", ".join(str(part).strip() for part in hard_caption_parts if str(part).strip()),
|
|
||||||
triggers=(active_trigger,),
|
|
||||||
)
|
|
||||||
metadata = {
|
|
||||||
"mode": "Insta/OF",
|
|
||||||
"options": options,
|
|
||||||
"shared_descriptor": descriptor,
|
|
||||||
"shared_cast_descriptors": cast_descriptors,
|
|
||||||
"pov_character_labels": pov_character_labels,
|
|
||||||
"pov_prompt_directive": pov_directive,
|
|
||||||
"softcore_partner_styling": soft_partner_styling,
|
|
||||||
"character_hardcore_clothing": character_hardcore_clothing_entries,
|
|
||||||
"default_man_hardcore_clothing": default_man_hardcore_clothing_entries,
|
|
||||||
"hardcore_clothing_state": hard_clothing_state,
|
|
||||||
"hardcore_detail_density": hard_detail_density,
|
|
||||||
"hardcore_position_config": hard_row.get("hardcore_position_config", {}),
|
|
||||||
"softcore_prompt": soft_prompt,
|
|
||||||
"hardcore_prompt": hard_prompt,
|
|
||||||
"softcore_negative_prompt": soft_negative,
|
|
||||||
"hardcore_negative_prompt": hard_negative,
|
|
||||||
"softcore_caption": soft_caption,
|
|
||||||
"hardcore_caption": hard_caption,
|
|
||||||
"softcore_row": soft_row,
|
|
||||||
"hardcore_row": hard_row,
|
|
||||||
"hardcore_women_count": hard_women_count,
|
|
||||||
"hardcore_men_count": hard_men_count,
|
|
||||||
"character_cast_slots": character_slots,
|
|
||||||
"character_slot_labels": sorted(character_slot_map),
|
|
||||||
"softcore_camera_config": soft_camera_config,
|
|
||||||
"hardcore_camera_config": hard_camera_config,
|
|
||||||
"softcore_camera_directive": soft_camera_directive,
|
|
||||||
"hardcore_camera_directive": hard_camera_directive,
|
|
||||||
"softcore_camera_scene_directive": soft_camera_scene_directive,
|
|
||||||
"hardcore_camera_scene_directive": hard_camera_scene_directive,
|
|
||||||
}
|
|
||||||
return metadata
|
|
||||||
|
|||||||
@@ -632,6 +632,10 @@ def _expect_pair(pair: dict[str, Any], name: str) -> None:
|
|||||||
_expect_custom_row(pair.get("hardcore_row") or {}, f"{name}.hardcore_row")
|
_expect_custom_row(pair.get("hardcore_row") or {}, f"{name}.hardcore_row")
|
||||||
_expect_text(f"{name}.softcore_prompt", pair.get("softcore_prompt"), 20)
|
_expect_text(f"{name}.softcore_prompt", pair.get("softcore_prompt"), 20)
|
||||||
_expect_text(f"{name}.hardcore_prompt", pair.get("hardcore_prompt"), 20)
|
_expect_text(f"{name}.hardcore_prompt", pair.get("hardcore_prompt"), 20)
|
||||||
|
_expect_trigger_once(f"{name}.softcore_prompt", pair.get("softcore_prompt"), Trigger)
|
||||||
|
_expect_trigger_once(f"{name}.hardcore_prompt", pair.get("hardcore_prompt"), Trigger)
|
||||||
|
_expect_trigger_once(f"{name}.softcore_caption", pair.get("softcore_caption"), Trigger)
|
||||||
|
_expect_trigger_once(f"{name}.hardcore_caption", pair.get("hardcore_caption"), Trigger)
|
||||||
_expect_no_duplicate_comma_items(f"{name}.softcore_negative", pair.get("softcore_negative_prompt"))
|
_expect_no_duplicate_comma_items(f"{name}.softcore_negative", pair.get("softcore_negative_prompt"))
|
||||||
_expect_no_duplicate_comma_items(f"{name}.hardcore_negative", pair.get("hardcore_negative_prompt"))
|
_expect_no_duplicate_comma_items(f"{name}.hardcore_negative", pair.get("hardcore_negative_prompt"))
|
||||||
_expect_formatter_outputs(pair, name, target="softcore")
|
_expect_formatter_outputs(pair, name, target="softcore")
|
||||||
|
|||||||
Reference in New Issue
Block a user