from __future__ import annotations import re from typing import Any try: from .krea_action_positions import ( arrangement_duplicates_role, hardcore_pose_arrangement, ) from .krea_action_dispatch import resolve_hardcore_action_parts except ImportError: # Allows local smoke tests with `python -c`. from krea_action_positions import ( arrangement_duplicates_role, hardcore_pose_arrangement, ) from krea_action_dispatch import resolve_hardcore_action_parts def _clean(value: Any) -> str: text = "" if value is None else str(value) text = text.replace("\n", " ") text = re.sub(r"\s+", " ", text).strip() text = re.sub(r"\s+([,.;:])", r"\1", text) return text def _lowercase_for_inline_join(text: str) -> str: text = _clean(text) return text[:1].lower() + text[1:] if text else text def _with_indefinite_article(text: str) -> str: text = _clean(text) if not text or text.lower().startswith(("a ", "an ")): return text article = "an" if text[:1].lower() in "aeiou" else "a" return f"{article} {text}" def hardcore_action_sentence( role_graph: str, hard_item: str, composition: str = "", axis_values: Any = None, detail_density: str = "balanced", ) -> str: parts = resolve_hardcore_action_parts(role_graph, hard_item, composition, axis_values, detail_density) role_graph = parts.role_graph hard_item = parts.hard_item detail = parts.detail anchor = parts.anchor arrangement = hardcore_pose_arrangement(anchor, role_graph, hard_item, composition, axis_values) anchor_phrase = _with_indefinite_article(anchor) if anchor else "" if arrangement and anchor_phrase and not arrangement_duplicates_role(arrangement, role_graph): anchor_phrase = f"{anchor_phrase} {arrangement}" if role_graph and anchor_phrase: sentence = f"In {anchor_phrase}, {_lowercase_for_inline_join(role_graph)}" elif role_graph: sentence = role_graph elif detail and anchor_phrase: sentence = f"In {anchor_phrase}, {detail}" detail = "" else: sentence = detail or hard_item detail = "" if detail: sentence = f"{sentence}; {detail}" return sentence