Files
ComfyUI-Ethanfel-Prompt-Bui…/caption_format_route.py
T

140 lines
4.5 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Callable
try:
from . import formatter_input as input_policy
from . import formatter_route_trace as trace_policy
from . import formatter_target as target_policy
except ImportError: # pragma: no cover - plain-script smoke tests
import formatter_input as input_policy
import formatter_route_trace as trace_policy
import formatter_target as target_policy
@dataclass(frozen=True)
class CaptionFormatRequest:
source_text: str
metadata_json: str = ""
input_hint: str = "auto"
target: str = "auto"
trigger: str = ""
include_trigger: bool = True
detail_level: str = "balanced"
style_policy: str = "drop_style_tail"
caption_profile: str = "manual_controls"
@dataclass(frozen=True)
class CaptionFormatRoute:
caption: str
method: str
branch: str
input_hint: str
target: str
detail_level: str
style_policy: str
include_trigger: bool
keep_style: bool
route_trace_json: str = ""
def as_tuple(self) -> tuple[str, str]:
return self.caption, self.method
def as_trace_tuple(self) -> tuple[str, str, str]:
return self.caption, self.method, self.route_trace_json
@dataclass(frozen=True)
class CaptionFormatDependencies:
apply_caption_profile: Callable[[str, str, str, bool], tuple[str, str, bool]]
keep_style_terms: Callable[[str], bool]
row_from_inputs: Callable[[str, str, str], tuple[dict[str, Any] | None, str]]
metadata_to_prose: Callable[..., tuple[str, str]]
text_to_prose: Callable[[str, str, bool], tuple[str, str]]
with_trigger: Callable[[str, str, bool], str]
sanitize_prose_text: Callable[..., str]
def naturalize_caption_result(
request: CaptionFormatRequest,
deps: CaptionFormatDependencies,
) -> CaptionFormatRoute:
input_hint = input_policy.normalize_input_hint(request.input_hint, text_hint=input_policy.INPUT_HINT_CAPTION_OR_PROMPT)
target = target_policy.normalize_target(request.target)
detail_level, style_policy, include_trigger = deps.apply_caption_profile(
request.caption_profile,
request.detail_level,
request.style_policy,
request.include_trigger,
)
keep_style = deps.keep_style_terms(style_policy)
row, row_method = deps.row_from_inputs(request.source_text, request.metadata_json, input_hint)
if row is not None:
prose, method = deps.metadata_to_prose(row, detail_level, keep_style, target)
caption = deps.sanitize_prose_text(
deps.with_trigger(prose, request.trigger, include_trigger),
triggers=(request.trigger,),
)
full_method = f"{row_method}:{method}"
route_trace = trace_policy.route_trace_json(
formatter="caption",
branch="metadata",
method=full_method,
input_hint=input_hint,
target=target,
detail_level=detail_level,
style_policy=style_policy,
include_trigger=include_trigger,
keep_style=keep_style,
)
return CaptionFormatRoute(
caption=caption,
method=full_method,
branch="metadata",
input_hint=input_hint,
target=target,
detail_level=detail_level,
style_policy=style_policy,
include_trigger=include_trigger,
keep_style=keep_style,
route_trace_json=route_trace,
)
prose, method = deps.text_to_prose(request.source_text, detail_level, keep_style)
caption = deps.sanitize_prose_text(
deps.with_trigger(prose, request.trigger, include_trigger),
triggers=(request.trigger,),
)
route_trace = trace_policy.route_trace_json(
formatter="caption",
branch="text",
method=method,
input_hint=input_hint,
target=target,
detail_level=detail_level,
style_policy=style_policy,
include_trigger=include_trigger,
keep_style=keep_style,
)
return CaptionFormatRoute(
caption=caption,
method=method,
branch="text",
input_hint=input_hint,
target=target,
detail_level=detail_level,
style_policy=style_policy,
include_trigger=include_trigger,
keep_style=keep_style,
route_trace_json=route_trace,
)
def naturalize_caption(
request: CaptionFormatRequest,
deps: CaptionFormatDependencies,
) -> tuple[str, str]:
return naturalize_caption_result(request, deps).as_tuple()