File size: 4,071 Bytes
cac0037
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
"""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,
    )