File size: 2,631 Bytes
b04d6d2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Phase 0 (SPEC §12) — prove mapping quality before any art or UI.

Runs Agent 1 (the Deck Designer) against the open ≤32B model for several varied
themes and prints each deck as a readable archetype→concept table plus the full
JSON. Inspect by hand: do the mappings read as clever-but-right across all
themes? If not, fix the prompt/few-shots before building anything else.

Usage:
    set -a; source ~/tokens; set +a
    python -m scripts.phase0_mapping                 # default 5 themes
    python -m scripts.phase0_mapping "free jazz" "tax law"
"""
from __future__ import annotations

import json
import os
import sys
import time

from arcana.archetypes import MAJOR_ARCANA
from arcana.designer import DeckError, design_deck
from arcana.llm import get_llm

DEFAULT_THEMES = [
    "thermodynamics",            # serious / scientific
    "Lord of the Rings",         # fandom
    "the French Revolution",     # history
    "breakfast foods",           # silly
    "professional wrestling",    # pop-culture wildcard
]

OUT_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
                       "phase0_out")


def print_table(deck: dict) -> None:
    print(f"\n  style: {deck['style_suffix']}")
    for a in MAJOR_ARCANA:
        c = deck["cards"][a.number]
        print(f"  {a.roman:<5} {a.name:<18}{c['concept']}")
        print(f"        ↳ {c['justification']}")


def main(themes: list[str]) -> int:
    os.makedirs(OUT_DIR, exist_ok=True)
    llm = get_llm()
    print(f"Model: {getattr(llm, 'model', '?')}  via {getattr(llm, 'base_url', '?')}")

    failures = 0
    for theme in themes:
        print("\n" + "=" * 72)
        print(f"THEME: {theme}")
        print("=" * 72)
        t0 = time.time()
        try:
            deck = design_deck(theme, llm=llm)
        except DeckError as e:
            failures += 1
            print(f"  ✗ FAILED: {e}  ({time.time() - t0:.1f}s)")
            continue
        dt = time.time() - t0
        print_table(deck)
        slug = "".join(ch if ch.isalnum() else "_" for ch in theme.lower())[:40]
        path = os.path.join(OUT_DIR, f"{slug}.json")
        with open(path, "w") as f:
            json.dump(deck, f, indent=2, ensure_ascii=False)
        print(f"\n  ✓ 22 cards in {dt:.1f}s  →  {path}")

    print("\n" + "=" * 72)
    print(f"DONE — {len(themes) - failures}/{len(themes)} decks generated.")
    print("Inspect the tables above: do the mappings feel clever-but-right?")
    return 1 if failures else 0


if __name__ == "__main__":
    args = sys.argv[1:] or DEFAULT_THEMES
    raise SystemExit(main(args))