Centralize formatter detail levels
This commit is contained in:
+5
-6
@@ -4,9 +4,11 @@ import re
|
||||
from typing import Any
|
||||
|
||||
try:
|
||||
from . import formatter_detail as detail_policy
|
||||
from . import formatter_input as input_policy
|
||||
from . import route_metadata as route_metadata_policy
|
||||
except ImportError: # Allows local smoke tests with `python tools/prompt_smoke.py`.
|
||||
import formatter_detail as detail_policy
|
||||
import formatter_input as input_policy
|
||||
import route_metadata as route_metadata_policy
|
||||
|
||||
@@ -14,7 +16,7 @@ except ImportError: # Allows local smoke tests with `python tools/prompt_smoke.
|
||||
OLD_TRIGGER = "sxcpinup_coloredpencil"
|
||||
DEFAULT_TRIGGER = "sxcppnl7"
|
||||
|
||||
DETAIL_LEVELS = ("balanced", "concise", "dense")
|
||||
DETAIL_LEVELS = detail_policy.DETAIL_LEVELS
|
||||
STYLE_POLICIES = ("drop_style_tail", "keep_style_terms")
|
||||
CAPTION_PROFILE_DEFAULT = "manual_controls"
|
||||
|
||||
@@ -72,7 +74,7 @@ POSITION_FAMILY_CAPTION_LABELS = {
|
||||
|
||||
|
||||
def normalize_detail_level(value: str) -> str:
|
||||
return value if value in DETAIL_LEVELS else "balanced"
|
||||
return detail_policy.normalize_detail_level(value)
|
||||
|
||||
|
||||
def normalize_style_policy(value: str) -> str:
|
||||
@@ -107,10 +109,7 @@ def keep_style_terms(style_policy: str) -> bool:
|
||||
|
||||
|
||||
def detail_allows(level: str, dense_only: bool = False) -> bool:
|
||||
level = normalize_detail_level((level or "balanced").strip().lower())
|
||||
if dense_only:
|
||||
return level == "dense"
|
||||
return level != "concise"
|
||||
return detail_policy.detail_allows(level, dense_only=dense_only)
|
||||
|
||||
|
||||
def strip_style_tail(text: str) -> str:
|
||||
|
||||
@@ -84,6 +84,15 @@ routes:
|
||||
It must not make formatter-style decisions. Krea prose, SDXL tags, and training
|
||||
caption sentence shape stay in their formatter modules.
|
||||
|
||||
Formatter detail-level handling now has one home:
|
||||
|
||||
- `formatter_detail.py`
|
||||
|
||||
It owns route-neutral prose detail levels, node choice lists, normalization, and
|
||||
the concise/balanced/dense inclusion gate used by Krea2 and natural-caption
|
||||
routes. It must not own route-specific style controls such as Krea photographic
|
||||
mode or caption style-tail policy.
|
||||
|
||||
Formatter target handling now has one home:
|
||||
|
||||
- `formatter_target.py`
|
||||
|
||||
@@ -126,6 +126,7 @@ Core helper ownership:
|
||||
| `krea_cast.py` | Shared formatter cast descriptor parsing, cast labels, cast prose, natural cast descriptor text, and label replacement used by Krea2 and caption routes. |
|
||||
| `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, embedded soft/hard row output and side-metadata synchronization, and embedded row sanitation. |
|
||||
| `formatter_detail.py` | Shared formatter detail-level choices, normalization, and concise/balanced/dense gates used by Krea2 and caption routes. |
|
||||
| `formatter_input.py` | Shared formatter input parsing: text cleanup, metadata/source JSON detection, trigger-prefix stripping, shared prompt field-label inventory, fallback field-label stripping, `Avoid:` splitting, prompt-field extraction, and metadata row-value fallback. |
|
||||
| `formatter_target.py` | Shared formatter target choices and normalization for `auto`, `single`, `softcore`, and `hardcore`, including pair-side selection and combined-caption inclusion policy. |
|
||||
| `node_tooltips.py` | Node input tooltip inventory, node-specific overrides, dynamic-input fallback rules, and tooltip injection installer used by `__init__.py`. |
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
DETAIL_LEVELS = ("balanced", "concise", "dense")
|
||||
DEFAULT_DETAIL_LEVEL = "balanced"
|
||||
|
||||
|
||||
def detail_level_choices() -> list[str]:
|
||||
return list(DETAIL_LEVELS)
|
||||
|
||||
|
||||
def normalize_detail_level(value: Any) -> str:
|
||||
level = str(value or "").strip().lower().replace("-", "_").replace(" ", "_")
|
||||
return level if level in DETAIL_LEVELS else DEFAULT_DETAIL_LEVEL
|
||||
|
||||
|
||||
def detail_allows(level: Any, dense_only: bool = False) -> bool:
|
||||
level = normalize_detail_level(level)
|
||||
if dense_only:
|
||||
return level == "dense"
|
||||
return level != "concise"
|
||||
@@ -4,8 +4,10 @@ from dataclasses import dataclass
|
||||
from typing import Any, Callable
|
||||
|
||||
try:
|
||||
from . import formatter_detail as detail_policy
|
||||
from . import formatter_target as target_policy
|
||||
except ImportError: # pragma: no cover - plain-script smoke tests
|
||||
import formatter_detail as detail_policy
|
||||
import formatter_target as target_policy
|
||||
|
||||
|
||||
@@ -48,7 +50,7 @@ class KreaFormatDependencies:
|
||||
|
||||
|
||||
def format_krea2_prompt_result(request: KreaFormatRequest, deps: KreaFormatDependencies) -> KreaFormatRoute:
|
||||
detail_level = request.detail_level if request.detail_level in ("concise", "balanced", "dense") else "balanced"
|
||||
detail_level = detail_policy.normalize_detail_level(request.detail_level)
|
||||
style_mode = request.style_mode if request.style_mode in ("preserve", "photographic", "minimal") else "preserve"
|
||||
target = target_policy.normalize_target(request.target)
|
||||
row, method = deps.row_from_inputs(request.source_text, request.metadata_json, request.input_hint)
|
||||
|
||||
+4
-2
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
try:
|
||||
from .caption_naturalizer import naturalize_caption
|
||||
from .caption_policy import caption_profile_choices
|
||||
from .formatter_detail import detail_level_choices
|
||||
from .formatter_input import INPUT_HINT_CAPTION_OR_PROMPT, INPUT_HINT_PROMPT, input_hint_choices
|
||||
from .formatter_target import target_choices
|
||||
from .krea_formatter import format_krea2_prompt
|
||||
@@ -15,6 +16,7 @@ try:
|
||||
except ImportError: # Allows local smoke tests from the repository root.
|
||||
from caption_naturalizer import naturalize_caption
|
||||
from caption_policy import caption_profile_choices
|
||||
from formatter_detail import detail_level_choices
|
||||
from formatter_input import INPUT_HINT_CAPTION_OR_PROMPT, INPUT_HINT_PROMPT, input_hint_choices
|
||||
from formatter_target import target_choices
|
||||
from krea_formatter import format_krea2_prompt
|
||||
@@ -34,7 +36,7 @@ class SxCPCaptionNaturalizer:
|
||||
"source_text": ("STRING", {"default": "", "multiline": True}),
|
||||
"input_hint": (input_hint_choices(text_hint=INPUT_HINT_CAPTION_OR_PROMPT), {"default": "auto"}),
|
||||
"caption_profile": (caption_profile_choices(), {"default": "manual_controls"}),
|
||||
"detail_level": (["balanced", "concise", "dense"], {"default": "balanced"}),
|
||||
"detail_level": (detail_level_choices(), {"default": "balanced"}),
|
||||
"style_policy": (["drop_style_tail", "keep_style_terms"], {"default": "drop_style_tail"}),
|
||||
"trigger": ("STRING", {"default": "sxcppnl7"}),
|
||||
"include_trigger": ("BOOLEAN", {"default": True}),
|
||||
@@ -86,7 +88,7 @@ class SxCPKrea2Formatter:
|
||||
"source_text": ("STRING", {"default": "", "multiline": True}),
|
||||
"input_hint": (input_hint_choices(text_hint=INPUT_HINT_PROMPT), {"default": "auto"}),
|
||||
"target": (target_choices(), {"default": "auto"}),
|
||||
"detail_level": (["balanced", "concise", "dense"], {"default": "balanced"}),
|
||||
"detail_level": (detail_level_choices(), {"default": "balanced"}),
|
||||
"style_mode": (["preserve", "photographic", "minimal"], {"default": "preserve"}),
|
||||
"preserve_trigger": ("BOOLEAN", {"default": False}),
|
||||
},
|
||||
|
||||
@@ -38,6 +38,7 @@ CRITICAL_ROUTE_MODULES: tuple[tuple[str, str], ...] = (
|
||||
("krea_format_route.py", "krea_format_route_policy"),
|
||||
("sdxl_format_route.py", "sdxl_format_route_policy"),
|
||||
("caption_format_route.py", "caption_format_route_policy"),
|
||||
("formatter_detail.py", "formatter_detail_policy"),
|
||||
("formatter_input.py", "formatter_input_policy"),
|
||||
("formatter_target.py", "formatter_target_policy"),
|
||||
("pair_builder.py", "pair_builder_policy"),
|
||||
|
||||
@@ -41,6 +41,7 @@ import character_slot # noqa: E402
|
||||
import category_cast_config # noqa: E402
|
||||
import category_library # noqa: E402
|
||||
import filter_config # noqa: E402
|
||||
import formatter_detail # noqa: E402
|
||||
import formatter_input # noqa: E402
|
||||
import formatter_target # noqa: E402
|
||||
import hardcore_position_config # noqa: E402
|
||||
@@ -2842,6 +2843,26 @@ def smoke_formatter_target_policy() -> None:
|
||||
_expect(not hard_pair.include_softcore and hard_pair.include_hardcore, "Pair hardcore should include only hard side")
|
||||
|
||||
|
||||
def smoke_formatter_detail_policy() -> None:
|
||||
_expect(
|
||||
formatter_detail.detail_level_choices() == ["balanced", "concise", "dense"],
|
||||
"Formatter detail choices changed",
|
||||
)
|
||||
_expect(formatter_detail.normalize_detail_level("dense") == "dense", "Formatter detail lost dense")
|
||||
_expect(formatter_detail.normalize_detail_level("BAD") == "balanced", "Formatter detail should normalize invalid values")
|
||||
_expect(formatter_detail.detail_allows("concise") is False, "Formatter detail concise gate changed")
|
||||
_expect(formatter_detail.detail_allows("dense", dense_only=True) is True, "Formatter detail dense-only gate changed")
|
||||
_expect(caption_policy.DETAIL_LEVELS is formatter_detail.DETAIL_LEVELS, "Caption detail levels should delegate")
|
||||
_expect(
|
||||
caption_policy.normalize_detail_level("bad") == formatter_detail.normalize_detail_level("bad"),
|
||||
"Caption detail normalization should delegate",
|
||||
)
|
||||
_expect(
|
||||
caption_policy.detail_allows("dense", dense_only=True) == formatter_detail.detail_allows("dense", dense_only=True),
|
||||
"Caption detail gate should delegate",
|
||||
)
|
||||
|
||||
|
||||
def smoke_krea_format_route_policy() -> None:
|
||||
row = _prompt_row(
|
||||
name="krea_format_route_single",
|
||||
@@ -6264,8 +6285,10 @@ def smoke_node_formatter_registration() -> None:
|
||||
_expect("caption_profile" in caption_inputs, "Caption Naturalizer lost caption_profile input")
|
||||
_expect("target" in caption_inputs, "Caption Naturalizer lost target input")
|
||||
_expect(caption_inputs["target"][0] == formatter_target.target_choices(), "Caption Naturalizer target choices drifted")
|
||||
_expect(caption_inputs["detail_level"][0] == formatter_detail.detail_level_choices(), "Caption Naturalizer detail choices drifted")
|
||||
_expect("tooltip" in caption_inputs["caption_profile"][1], "Caption profile tooltip injection missing")
|
||||
_expect(krea_inputs["target"][0] == formatter_target.target_choices(), "Krea2 Formatter target choices drifted")
|
||||
_expect(krea_inputs["detail_level"][0] == formatter_detail.detail_level_choices(), "Krea2 Formatter detail choices drifted")
|
||||
|
||||
krea_output = krea_node().build(
|
||||
"sxcppnl7 A woman standing by a window",
|
||||
@@ -6644,6 +6667,7 @@ SMOKE_CASES: list[tuple[str, Callable[[], None]]] = [
|
||||
("row_assembly_policy", smoke_row_assembly_policy),
|
||||
("formatter_input_policy", smoke_formatter_input_policy),
|
||||
("formatter_target_policy", smoke_formatter_target_policy),
|
||||
("formatter_detail_policy", smoke_formatter_detail_policy),
|
||||
("krea_format_route_policy", smoke_krea_format_route_policy),
|
||||
("formatter_cast_policy", smoke_formatter_cast_policy),
|
||||
("caption_policy", smoke_caption_policy),
|
||||
|
||||
Reference in New Issue
Block a user