File size: 2,100 Bytes
f73b724
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Idempotent engine bootstrap.

Run at Docker build time (to warm the Maia-2 weight cache) and on local
dev when you want to verify engines are wired up. Safe to re-run; does
nothing when everything is already in place.

Usage:
    python scripts/setup_engines.py
"""

from __future__ import annotations

import importlib.util
import os
import shutil
import sys


def check_stockfish() -> bool:
    path = os.environ.get("STOCKFISH_PATH") or shutil.which("stockfish")
    if not path:
        print("  [stockfish] NOT FOUND — install via apt (Linux) or download a binary and set STOCKFISH_PATH")
        return False
    print(f"  [stockfish] OK — {path}")
    return True


def check_maia2() -> bool:
    if importlib.util.find_spec("maia2") is None:
        print("  [maia2]    NOT INSTALLED — `pip install maia2`")
        return False
    cache = os.environ.get("MAIA2_CACHE_DIR")
    if cache:
        os.makedirs(cache, exist_ok=True)
        os.environ.setdefault("HF_HOME", cache)
        print(f"  [maia2]    cache at {cache}")
    try:
        from maia2 import inference, model  # type: ignore

        print("  [maia2]    loading rapid model (this may download weights)...")
        m = model.from_pretrained(type="rapid", device="cpu")
        _ = inference.prepare()
        print(f"  [maia2]    OK — {type(m).__name__} loaded")
        return True
    except Exception as exc:
        print(f"  [maia2]    FAILED at load — {type(exc).__name__}: {exc}")
        return False


def main() -> int:
    print("Metropolis Chess Club — engine setup")
    ok_sf = check_stockfish()
    ok_maia = check_maia2()
    print()
    if ok_sf and ok_maia:
        print("All engines ready.")
        return 0
    print("Some engines are unavailable — the app will still run, but gameplay will")
    print("fall back to MockEngine or the remaining real engine.")
    return 0  # Non-zero would fail Docker builds; we want builds to succeed even if
              # weights couldn't be downloaded (they'll download on first use instead).


if __name__ == "__main__":
    sys.exit(main())