File size: 5,764 Bytes
e9e9f83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
XERO Setup Wizard  —  initialization & dependency downloader
============================================================
Author: Michael Laurence Curzi · ZEDEC AI / 36N9 Genetics LLC · MIT (Attribution)

This package contains ONLY XERO's own code, genome, datasets, and documentation.
It deliberately bundles **no third-party library code** (PyTorch, Transformers,
the Qwen weights, etc.). This wizard *downloads* those licensed components on
demand, with your consent, so the package itself carries no third-party
copyrighted code. See NOTICE for full attributions.

Tiers
-----
  core      : inner core only (numpy etc.) — no GPU, no ML stack. Always offered.
  outer     : + outer-core LLM stack (torch, transformers, peft, datasets) — GPU.
  model     : + download the Qwen2.5-3B-Instruct weights (Apache-2.0).
  configure : detect hardware -> write xero_config.json (agency autoconfig).
  verify    : run the capability audit.

Usage
-----
  python3 setup_wizard.py                 # interactive
  python3 setup_wizard.py --core --configure --verify --yes
  python3 setup_wizard.py --all --yes     # core + outer + model + configure + verify
"""
from __future__ import annotations

import argparse
import os
import subprocess
import sys

ROOT = os.path.dirname(os.path.abspath(__file__))
MODULES = os.path.join(ROOT, "modules")
PY = sys.executable or "python3"


def notice() -> None:
    print("=" * 68)
    print("XERO SETUP WIZARD")
    print("=" * 68)
    print("This package bundles NO third-party library code. With your consent")
    print("this wizard downloads licensed components from their official sources:")
    print("  - Qwen2.5-3B-Instruct ........ Apache-2.0 (Alibaba Cloud)")
    print("  - torch ...................... BSD-3-Clause (Meta)")
    print("  - transformers/peft/datasets . Apache-2.0 (Hugging Face)")
    print("  - numpy ...................... BSD-3-Clause")
    print("Full attributions: see the NOTICE file. XERO's own code is MIT")
    print("(Attribution to Michael Laurence Curzi required).")
    print("=" * 68)


def ask(question: str, assume_yes: bool) -> bool:
    if assume_yes:
        print(f"{question} [auto-yes]")
        return True
    try:
        return input(f"{question} [y/N]: ").strip().lower().startswith("y")
    except EOFError:
        return False


def pip_install(*args: str) -> int:
    cmd = [PY, "-m", "pip", "install", *args]
    print("  $", " ".join(cmd))
    return subprocess.call(cmd)


def install_core(assume_yes: bool) -> None:
    if ask("Download the INNER-CORE deps (numpy etc., ~30 MB)?", assume_yes):
        pip_install("-r", os.path.join(ROOT, "requirements-core.txt"))


def install_outer(assume_yes: bool) -> None:
    if ask("Download the OUTER-CORE / training stack (torch+transformers, large)?", assume_yes):
        req = os.path.join(ROOT, "training", "requirements-train.txt")
        pip_install("-r", req)


def download_model(assume_yes: bool, model_id: str) -> None:
    if not ask(f"Download the outer-core model weights ({model_id})?", assume_yes):
        return
    try:
        from huggingface_hub import snapshot_download
    except Exception:
        print("  installing huggingface_hub ...")
        pip_install("huggingface_hub")
        from huggingface_hub import snapshot_download  # noqa
    print(f"  fetching {model_id} ...")
    snapshot_download(repo_id=model_id)
    print("  model cached.")


def configure() -> None:
    sys.path.insert(0, MODULES)
    try:
        import xero_autoconfig as ac
        if hasattr(ac, "wizard"):
            try:
                ac.wizard(interactive=False)
            except TypeError:
                ac.wizard()
        elif hasattr(ac, "recommend"):
            ac.recommend()
        print(f"  hardware-fit config written -> {os.path.join(ROOT, 'xero_config.json')}")
    except Exception as e:  # noqa: BLE001
        print(f"  (autoconfig skipped: {e})")


def verify() -> int:
    print("  running capability audit ...")
    env = dict(os.environ, PYTHONPATH=MODULES)
    return subprocess.call([PY, os.path.join(ROOT, "tests", "test_all_capabilities.py")], env=env)


def main() -> int:
    ap = argparse.ArgumentParser(description="XERO setup wizard")
    ap.add_argument("--core", action="store_true", help="install inner-core deps")
    ap.add_argument("--outer", action="store_true", help="install outer-core/training stack")
    ap.add_argument("--model", action="store_true", help="download the outer-core model")
    ap.add_argument("--model-id", default="Qwen/Qwen2.5-3B-Instruct")
    ap.add_argument("--configure", action="store_true", help="write xero_config.json")
    ap.add_argument("--verify", action="store_true", help="run the capability audit")
    ap.add_argument("--all", action="store_true", help="core + outer + model + configure + verify")
    ap.add_argument("--yes", action="store_true", help="non-interactive; assume yes")
    args = ap.parse_args()

    notice()
    interactive = not any([args.core, args.outer, args.model, args.configure, args.verify, args.all])

    if args.all or args.core or interactive:
        install_core(args.yes)
    if args.all or args.outer or (interactive):
        install_outer(args.yes)
    if args.all or args.model or (interactive):
        download_model(args.yes, args.model_id)
    if args.all or args.configure or interactive:
        configure()
    rc = 0
    if args.all or args.verify or interactive:
        rc = verify()

    print("\nSetup complete." if rc == 0 else "\nSetup finished with audit failures (see above).")
    print("Next: read docs/STATUS_AND_AUDIT.md (honest state) and docs/INDEX.md.")
    return rc


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