| """Taste profile loading and deterministic scoring.""" |
|
|
| from __future__ import annotations |
|
|
| import json |
| import re |
| from pathlib import Path |
|
|
| from .schema import TasteProfile, TasteRefinedPrompt |
|
|
| DEFAULT_TASTE_PATH = Path(__file__).resolve().parents[2] / "assets" / "taste_profile.json" |
|
|
| FEATURE_ALIASES: dict[str, tuple[str, ...]] = { |
| "patent_leather": ("patent leather", "gloss leather", "black leather", "latex-tech"), |
| "faux_fur": ("faux fur", "fur trim", "black fur", "fur collar"), |
| "chantilly_lace": ("chantilly lace", "lace", "lace mesh", "lace threads"), |
| "crimson_hardware": ("crimson hardware", "red metal", "red buckles", "crimson buckles", "red choker"), |
| "platform_boots": ("platform boots", "platform boot", "heavy boots", "tall boots"), |
| "slavic_model": ("slavic", "high cheekbones", "pale matte skin", "intense focused eyes"), |
| "nexus_sigils": ("nexus sigil", "nexus sigils", "orchestrator glyph", "node glyph"), |
| "rain_slicked_surfaces": ("rain", "rain-slicked", "wet pavement", "neon rain"), |
| "floating_code_data_streams": ("floating code", "data streams", "code streams"), |
| } |
|
|
|
|
| def load_taste_profile(path: Path | str = DEFAULT_TASTE_PATH) -> TasteProfile: |
| data = json.loads(Path(path).read_text(encoding="utf-8")) |
| rules = data.get("enforcement_rules", {}) |
| return TasteProfile( |
| version=data.get("version", "unknown"), |
| locked_features=data.get("locked_features", {}), |
| must_include=rules.get("must_include", []), |
| should_include=rules.get("should_include", []), |
| forbidden=rules.get("forbidden", []), |
| ) |
|
|
|
|
| def _has_alias(text: str, aliases: tuple[str, ...]) -> bool: |
| lowered = text.lower() |
| return any(re.search(rf"\b{re.escape(alias)}\b", lowered) for alias in aliases) |
|
|
|
|
| def score_prompt(prompt: str) -> tuple[float, list[str], list[str]]: |
| found: list[str] = [] |
| missing: list[str] = [] |
| for feature, aliases in FEATURE_ALIASES.items(): |
| if _has_alias(prompt, aliases): |
| found.append(feature) |
| else: |
| missing.append(feature) |
|
|
| must = ["patent_leather", "crimson_hardware", "platform_boots", "slavic_model"] |
| must_hits = sum(1 for feature in must if feature in found) |
| optional_hits = len(found) - must_hits |
| score = min(0.98, 0.38 + must_hits * 0.11 + optional_hits * 0.045) |
| return round(score, 2), missing, found |
|
|
|
|
| def refine_prompt(prompt: str, adult_mode: bool = False) -> TasteRefinedPrompt: |
| additions: list[str] = [] |
| score, missing, _ = score_prompt(prompt) |
| supplement_map = { |
| "patent_leather": "rich black patent leather with visible grain and wet reflections", |
| "faux_fur": "dense black faux fur trim at collar and cuffs", |
| "chantilly_lace": "delicate Chantilly lace mesh at neckline and sleeves", |
| "crimson_hardware": "glowing crimson hardware on buckles, choker, and closures", |
| "platform_boots": "structured platform boots with polished black soles", |
| "slavic_model": "Slavic model features with high cheekbones and intense focused eyes", |
| "nexus_sigils": "subtle NEXUS sigils and orchestrator node glyphs woven into holographic streams", |
| "rain_slicked_surfaces": "rain-slicked cinematic surfaces under cyan and magenta neon", |
| "floating_code_data_streams": "floating code and iridescent data streams in the background", |
| } |
| for feature in missing: |
| if feature in supplement_map and len(additions) < 6: |
| additions.append(supplement_map[feature]) |
|
|
| mode_clause = "adult catalog remains opt-in and partitioned" if adult_mode else "public-safe presentation" |
| refined = " ".join( |
| part.strip() |
| for part in [prompt.strip(), ", ".join(additions), mode_clause, "ultra-photorealistic FLUX.2 texture detail"] |
| if part.strip() |
| ) |
| final_score, final_missing, _ = score_prompt(refined) |
| return TasteRefinedPrompt( |
| original=prompt, |
| refined=refined, |
| additions=additions, |
| score=final_score, |
| missing_features=final_missing, |
| ) |
|
|
|
|