Extract SDXL preset policy
This commit is contained in:
@@ -283,11 +283,11 @@ Keep here:
|
|||||||
- metadata-family tag hints from `action_family`, `position_family`, and
|
- metadata-family tag hints from `action_family`, `position_family`, and
|
||||||
`position_keys`.
|
`position_keys`.
|
||||||
- shared formatter input parsing from `formatter_input.py`.
|
- shared formatter input parsing from `formatter_input.py`.
|
||||||
|
- style presets, quality presets, default negative prompt, and action/position
|
||||||
|
family tag hints from `sdxl_presets.py`.
|
||||||
|
|
||||||
Improve later:
|
Improve later:
|
||||||
|
|
||||||
- move presets into data dictionaries or JSON so adding styles does not require
|
|
||||||
editing formatter logic;
|
|
||||||
- add formatter profiles for Pony, SDXL photo, and flat vector;
|
- add formatter profiles for Pony, SDXL photo, and flat vector;
|
||||||
- make fallback cleanup use the shared field-label inventory.
|
- make fallback cleanup use the shared field-label inventory.
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ Core helper ownership:
|
|||||||
| `prompt_hygiene.py` | Generic prompt, caption, and negative-prompt cleanup. |
|
| `prompt_hygiene.py` | Generic prompt, caption, and negative-prompt cleanup. |
|
||||||
| `row_normalization.py` | Final prompt-row and pair metadata normalization: trigger prepending, extra-positive append, negative merge/dedupe, caption-part joining, and embedded soft/hard row sanitation. |
|
| `row_normalization.py` | Final prompt-row and pair metadata normalization: trigger prepending, extra-positive append, negative merge/dedupe, caption-part joining, and embedded soft/hard row sanitation. |
|
||||||
| `formatter_input.py` | Shared formatter input parsing: text cleanup, metadata/source JSON detection, trigger-prefix stripping, `Avoid:` splitting, prompt-field extraction, and metadata row-value fallback. |
|
| `formatter_input.py` | Shared formatter input parsing: text cleanup, metadata/source JSON detection, trigger-prefix stripping, `Avoid:` splitting, prompt-field extraction, and metadata row-value fallback. |
|
||||||
|
| `sdxl_presets.py` | SDXL style presets, quality presets, default negative prompt, and metadata-family tag hints used by the SDXL formatter and node choice lists. |
|
||||||
|
|
||||||
## Node IO Map
|
## Node IO Map
|
||||||
|
|
||||||
|
|||||||
+19
-50
@@ -5,10 +5,12 @@ from typing import Any
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from . import formatter_input as input_policy
|
from . import formatter_input as input_policy
|
||||||
|
from . import sdxl_presets as sdxl_policy
|
||||||
from .hardcore_action_metadata import normalize_hardcore_action_family
|
from .hardcore_action_metadata import normalize_hardcore_action_family
|
||||||
from .prompt_hygiene import sanitize_negative_text, sanitize_tag_prompt
|
from .prompt_hygiene import sanitize_negative_text, sanitize_tag_prompt
|
||||||
except ImportError: # Allows local smoke tests with `python -c`.
|
except ImportError: # Allows local smoke tests with `python -c`.
|
||||||
import formatter_input as input_policy
|
import formatter_input as input_policy
|
||||||
|
import sdxl_presets as sdxl_policy
|
||||||
from hardcore_action_metadata import normalize_hardcore_action_family
|
from hardcore_action_metadata import normalize_hardcore_action_family
|
||||||
from prompt_hygiene import sanitize_negative_text, sanitize_tag_prompt
|
from prompt_hygiene import sanitize_negative_text, sanitize_tag_prompt
|
||||||
|
|
||||||
@@ -19,50 +21,11 @@ TRIGGER_CANDIDATES = (
|
|||||||
"mythp0rt",
|
"mythp0rt",
|
||||||
)
|
)
|
||||||
|
|
||||||
SDXL_STYLE_PRESETS = {
|
SDXL_STYLE_PRESETS = sdxl_policy.SDXL_STYLE_PRESETS
|
||||||
"flat_vector_pony": "(skindentation:1.25), (flat color:2.0), no lineart, no outline, Flat vector",
|
SDXL_QUALITY_PRESETS = sdxl_policy.SDXL_QUALITY_PRESETS
|
||||||
"flat_vector": "(flat color:2.0), no lineart, no outline, Flat vector",
|
SDXL_DEFAULT_NEGATIVE = sdxl_policy.SDXL_DEFAULT_NEGATIVE
|
||||||
"photographic": "realistic photo, detailed skin texture, depth of field",
|
SDXL_ACTION_FAMILY_TAGS = sdxl_policy.SDXL_ACTION_FAMILY_TAGS
|
||||||
"none": "",
|
SDXL_POSITION_FAMILY_TAGS = sdxl_policy.SDXL_POSITION_FAMILY_TAGS
|
||||||
}
|
|
||||||
|
|
||||||
SDXL_QUALITY_PRESETS = {
|
|
||||||
"pony_high": (
|
|
||||||
"amazing quality, ultra detailed, 8k, very detailed, high detailed texture, "
|
|
||||||
"highly detailed anatomy, best quality, newest, very aesthetic, (score_9:1.1), "
|
|
||||||
"(score_8_up:1.1), (score_7_up:1.1), masterpiece, absurdres, highres"
|
|
||||||
),
|
|
||||||
"sdxl_high": "masterpiece, best quality, amazing quality, ultra detailed, 8k, absurdres, highres",
|
|
||||||
"none": "",
|
|
||||||
}
|
|
||||||
|
|
||||||
SDXL_DEFAULT_NEGATIVE = (
|
|
||||||
"worst quality, low quality, normal quality, lowres, bad anatomy, bad hands, "
|
|
||||||
"extra fingers, missing fingers, fused fingers, deformed, disfigured, malformed body, "
|
|
||||||
"watermark, signature, text, logo, blurry, jpeg artifacts, censored, mosaic censor"
|
|
||||||
)
|
|
||||||
|
|
||||||
SDXL_ACTION_FAMILY_TAGS = {
|
|
||||||
"foreplay": ("foreplay", "body contact"),
|
|
||||||
"outercourse": ("outercourse", "non-penetrative sex"),
|
|
||||||
"oral": ("oral sex",),
|
|
||||||
"penetration": ("penetrative sex", "penetration"),
|
|
||||||
"toy_double": ("double penetration", "toy-assisted sex"),
|
|
||||||
"climax": ("climax", "semen"),
|
|
||||||
}
|
|
||||||
|
|
||||||
SDXL_POSITION_FAMILY_TAGS = {
|
|
||||||
"penetrative": ("penetrative sex",),
|
|
||||||
"foreplay": ("foreplay",),
|
|
||||||
"interaction": ("interaction",),
|
|
||||||
"manual": ("manual stimulation",),
|
|
||||||
"oral": ("oral sex",),
|
|
||||||
"outercourse": ("outercourse",),
|
|
||||||
"anal": ("anal sex",),
|
|
||||||
"climax": ("climax",),
|
|
||||||
"threesome": ("threesome",),
|
|
||||||
"group": ("group sex",),
|
|
||||||
}
|
|
||||||
|
|
||||||
PROMPT_FIELD_LABELS = (
|
PROMPT_FIELD_LABELS = (
|
||||||
"Ages",
|
"Ages",
|
||||||
@@ -88,11 +51,11 @@ PROMPT_FIELD_LABELS = (
|
|||||||
|
|
||||||
|
|
||||||
def sdxl_style_preset_choices() -> list[str]:
|
def sdxl_style_preset_choices() -> list[str]:
|
||||||
return list(SDXL_STYLE_PRESETS)
|
return sdxl_policy.sdxl_style_preset_choices()
|
||||||
|
|
||||||
|
|
||||||
def sdxl_quality_preset_choices() -> list[str]:
|
def sdxl_quality_preset_choices() -> list[str]:
|
||||||
return list(SDXL_QUALITY_PRESETS)
|
return sdxl_policy.sdxl_quality_preset_choices()
|
||||||
|
|
||||||
|
|
||||||
def _clean(value: Any) -> str:
|
def _clean(value: Any) -> str:
|
||||||
@@ -362,7 +325,10 @@ def _row_core_tags(row: dict[str, Any], nude_weight: float) -> list[str]:
|
|||||||
|
|
||||||
|
|
||||||
def _style_prefix(style_preset: str, trigger: str, prepend_trigger: bool, custom_style: str) -> str:
|
def _style_prefix(style_preset: str, trigger: str, prepend_trigger: bool, custom_style: str) -> str:
|
||||||
style = custom_style if _clean(custom_style) else SDXL_STYLE_PRESETS.get(style_preset, SDXL_STYLE_PRESETS["flat_vector_pony"])
|
style = custom_style if _clean(custom_style) else SDXL_STYLE_PRESETS.get(
|
||||||
|
style_preset,
|
||||||
|
SDXL_STYLE_PRESETS[sdxl_policy.DEFAULT_STYLE_PRESET],
|
||||||
|
)
|
||||||
trigger = _clean(trigger)
|
trigger = _clean(trigger)
|
||||||
if prepend_trigger and trigger:
|
if prepend_trigger and trigger:
|
||||||
return _combine_tags(style, trigger)
|
return _combine_tags(style, trigger)
|
||||||
@@ -370,7 +336,10 @@ def _style_prefix(style_preset: str, trigger: str, prepend_trigger: bool, custom
|
|||||||
|
|
||||||
|
|
||||||
def _quality_tail(quality_preset: str, custom_quality: str) -> str:
|
def _quality_tail(quality_preset: str, custom_quality: str) -> str:
|
||||||
return _clean(custom_quality) or SDXL_QUALITY_PRESETS.get(quality_preset, SDXL_QUALITY_PRESETS["pony_high"])
|
return _clean(custom_quality) or SDXL_QUALITY_PRESETS.get(
|
||||||
|
quality_preset,
|
||||||
|
SDXL_QUALITY_PRESETS[sdxl_policy.DEFAULT_QUALITY_PRESET],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _soft_tags(row: dict[str, Any], root: dict[str, Any], nude_weight: float) -> str:
|
def _soft_tags(row: dict[str, Any], root: dict[str, Any], nude_weight: float) -> str:
|
||||||
@@ -488,8 +457,8 @@ def format_sdxl_prompt(
|
|||||||
extra_positive: str = "",
|
extra_positive: str = "",
|
||||||
extra_negative: str = "",
|
extra_negative: str = "",
|
||||||
) -> dict[str, str]:
|
) -> dict[str, str]:
|
||||||
style_preset = style_preset if style_preset in SDXL_STYLE_PRESETS else "flat_vector_pony"
|
style_preset = sdxl_policy.normalize_style_preset(style_preset)
|
||||||
quality_preset = quality_preset if quality_preset in SDXL_QUALITY_PRESETS else "pony_high"
|
quality_preset = sdxl_policy.normalize_quality_preset(quality_preset)
|
||||||
target = target if target in ("auto", "single", "softcore", "hardcore") else "auto"
|
target = target if target in ("auto", "single", "softcore", "hardcore") else "auto"
|
||||||
nude_weight = max(0.1, min(3.0, float(nude_weight)))
|
nude_weight = max(0.1, min(3.0, float(nude_weight)))
|
||||||
row, method = _row_from_inputs(source_text, metadata_json, input_hint)
|
row, method = _row_from_inputs(source_text, metadata_json, input_hint)
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_STYLE_PRESET = "flat_vector_pony"
|
||||||
|
DEFAULT_QUALITY_PRESET = "pony_high"
|
||||||
|
|
||||||
|
SDXL_STYLE_PRESETS = {
|
||||||
|
"flat_vector_pony": "(skindentation:1.25), (flat color:2.0), no lineart, no outline, Flat vector",
|
||||||
|
"flat_vector": "(flat color:2.0), no lineart, no outline, Flat vector",
|
||||||
|
"photographic": "realistic photo, detailed skin texture, depth of field",
|
||||||
|
"none": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
SDXL_QUALITY_PRESETS = {
|
||||||
|
"pony_high": (
|
||||||
|
"amazing quality, ultra detailed, 8k, very detailed, high detailed texture, "
|
||||||
|
"highly detailed anatomy, best quality, newest, very aesthetic, (score_9:1.1), "
|
||||||
|
"(score_8_up:1.1), (score_7_up:1.1), masterpiece, absurdres, highres"
|
||||||
|
),
|
||||||
|
"sdxl_high": "masterpiece, best quality, amazing quality, ultra detailed, 8k, absurdres, highres",
|
||||||
|
"none": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
SDXL_DEFAULT_NEGATIVE = (
|
||||||
|
"worst quality, low quality, normal quality, lowres, bad anatomy, bad hands, "
|
||||||
|
"extra fingers, missing fingers, fused fingers, deformed, disfigured, malformed body, "
|
||||||
|
"watermark, signature, text, logo, blurry, jpeg artifacts, censored, mosaic censor"
|
||||||
|
)
|
||||||
|
|
||||||
|
SDXL_ACTION_FAMILY_TAGS = {
|
||||||
|
"foreplay": ("foreplay", "body contact"),
|
||||||
|
"outercourse": ("outercourse", "non-penetrative sex"),
|
||||||
|
"oral": ("oral sex",),
|
||||||
|
"penetration": ("penetrative sex", "penetration"),
|
||||||
|
"toy_double": ("double penetration", "toy-assisted sex"),
|
||||||
|
"climax": ("climax", "semen"),
|
||||||
|
}
|
||||||
|
|
||||||
|
SDXL_POSITION_FAMILY_TAGS = {
|
||||||
|
"penetrative": ("penetrative sex",),
|
||||||
|
"foreplay": ("foreplay",),
|
||||||
|
"interaction": ("interaction",),
|
||||||
|
"manual": ("manual stimulation",),
|
||||||
|
"oral": ("oral sex",),
|
||||||
|
"outercourse": ("outercourse",),
|
||||||
|
"anal": ("anal sex",),
|
||||||
|
"climax": ("climax",),
|
||||||
|
"threesome": ("threesome",),
|
||||||
|
"group": ("group sex",),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def sdxl_style_preset_choices() -> list[str]:
|
||||||
|
return list(SDXL_STYLE_PRESETS)
|
||||||
|
|
||||||
|
|
||||||
|
def sdxl_quality_preset_choices() -> list[str]:
|
||||||
|
return list(SDXL_QUALITY_PRESETS)
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_style_preset(value: str) -> str:
|
||||||
|
return value if value in SDXL_STYLE_PRESETS else DEFAULT_STYLE_PRESET
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_quality_preset(value: str) -> str:
|
||||||
|
return value if value in SDXL_QUALITY_PRESETS else DEFAULT_QUALITY_PRESET
|
||||||
@@ -38,6 +38,7 @@ import location_config # noqa: E402
|
|||||||
import prompt_builder as pb # noqa: E402
|
import prompt_builder as pb # noqa: E402
|
||||||
import row_normalization # noqa: E402
|
import row_normalization # noqa: E402
|
||||||
import sdxl_formatter # noqa: E402
|
import sdxl_formatter # noqa: E402
|
||||||
|
import sdxl_presets # noqa: E402
|
||||||
import seed_config # noqa: E402
|
import seed_config # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
@@ -899,6 +900,46 @@ def smoke_formatter_input_policy() -> None:
|
|||||||
_expect_text("formatter_input.caption", caption, 20)
|
_expect_text("formatter_input.caption", caption, 20)
|
||||||
|
|
||||||
|
|
||||||
|
def smoke_sdxl_presets_policy() -> None:
|
||||||
|
_expect(
|
||||||
|
sdxl_formatter.SDXL_STYLE_PRESETS is sdxl_presets.SDXL_STYLE_PRESETS,
|
||||||
|
"SDXL formatter style presets should delegate to sdxl_presets",
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
sdxl_formatter.SDXL_QUALITY_PRESETS is sdxl_presets.SDXL_QUALITY_PRESETS,
|
||||||
|
"SDXL formatter quality presets should delegate to sdxl_presets",
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
sdxl_formatter.SDXL_ACTION_FAMILY_TAGS is sdxl_presets.SDXL_ACTION_FAMILY_TAGS,
|
||||||
|
"SDXL formatter action-family tags should delegate to sdxl_presets",
|
||||||
|
)
|
||||||
|
_expect("flat_vector_pony" in sdxl_presets.sdxl_style_preset_choices(), "SDXL style preset choices lost default")
|
||||||
|
_expect("pony_high" in sdxl_presets.sdxl_quality_preset_choices(), "SDXL quality preset choices lost default")
|
||||||
|
_expect(sdxl_presets.normalize_style_preset("bad") == sdxl_presets.DEFAULT_STYLE_PRESET, "SDXL invalid style fallback changed")
|
||||||
|
_expect(sdxl_presets.normalize_quality_preset("bad") == sdxl_presets.DEFAULT_QUALITY_PRESET, "SDXL invalid quality fallback changed")
|
||||||
|
|
||||||
|
row = _fixture_hardcore_row(
|
||||||
|
action_family="oral",
|
||||||
|
position_family="oral",
|
||||||
|
position_key="kneeling_oral",
|
||||||
|
position_keys=["kneeling_oral"],
|
||||||
|
)
|
||||||
|
tags = sdxl_formatter._metadata_family_tags(row)
|
||||||
|
_expect("oral sex" in tags, "SDXL metadata family tags lost oral family tag")
|
||||||
|
_expect("kneeling oral" in tags, "SDXL metadata family tags lost position key tag")
|
||||||
|
formatted = sdxl_formatter.format_sdxl_prompt(
|
||||||
|
_json(row),
|
||||||
|
input_hint="auto",
|
||||||
|
style_preset="bad",
|
||||||
|
quality_preset="bad",
|
||||||
|
trigger=SdxlTrigger,
|
||||||
|
prepend_trigger=True,
|
||||||
|
)
|
||||||
|
_expect_trigger_once("sdxl_presets.formatted_prompt", formatted.get("sdxl_prompt"), SdxlTrigger)
|
||||||
|
_expect("Flat vector" in formatted.get("sdxl_prompt", ""), "SDXL invalid style did not fall back to default preset")
|
||||||
|
_expect("score_9" in formatted.get("sdxl_prompt", ""), "SDXL invalid quality did not fall back to default preset")
|
||||||
|
|
||||||
|
|
||||||
def smoke_hardcore_position_config_policy() -> None:
|
def smoke_hardcore_position_config_policy() -> None:
|
||||||
_expect(
|
_expect(
|
||||||
pb.HARDCORE_POSITION_FAMILY_CHOICES is hardcore_position_config.HARDCORE_POSITION_FAMILY_CHOICES,
|
pb.HARDCORE_POSITION_FAMILY_CHOICES is hardcore_position_config.HARDCORE_POSITION_FAMILY_CHOICES,
|
||||||
@@ -2871,6 +2912,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),
|
||||||
("formatter_input_policy", smoke_formatter_input_policy),
|
("formatter_input_policy", smoke_formatter_input_policy),
|
||||||
|
("sdxl_presets_policy", smoke_sdxl_presets_policy),
|
||||||
("hardcore_position_config_policy", smoke_hardcore_position_config_policy),
|
("hardcore_position_config_policy", smoke_hardcore_position_config_policy),
|
||||||
("category_library_route", smoke_category_library_route),
|
("category_library_route", smoke_category_library_route),
|
||||||
("hardcore_category_routes", smoke_hardcore_category_routes),
|
("hardcore_category_routes", smoke_hardcore_category_routes),
|
||||||
|
|||||||
Reference in New Issue
Block a user