Built a universal manager and installer for all operating systems and environments. Bumped a lot of versions of things. Still needs deep testing.

This commit is contained in:
Jaret Burkett
2026-07-27 15:10:29 -06:00
parent 7e7053fc9a
commit 1e58c9a0f0
23 changed files with 2350 additions and 146 deletions

127
manager/doctor.py Normal file
View File

@@ -0,0 +1,127 @@
"""Environment diagnostics: `python -m manager doctor`."""
import os
import shutil
import subprocess
import sys
from . import detect as detect_mod
from . import env, ffmpeg, gitops, nodejs
from .util import REPO_ROOT, clean_env, find_uv, venv_dir, venv_python
def _check(label, passed, detail=""):
if sys.stdout.isatty():
mark = "\033[32mOK\033[0m " if passed else "\033[31mFAIL\033[0m"
else:
mark = "OK " if passed else "FAIL"
print(" [%s] %-18s %s" % (mark, label, detail))
return passed
def run_doctor():
print("AI Toolkit doctor\n")
d = detect_mod.detect()
from . import gitwin
_check("os / arch", True, "%s %s" % (d["os"], d["arch"]))
git = gitwin.find_git()
_check(
"git",
git is not None,
git or "not found (manager sync installs a local copy on Windows)",
)
uv = find_uv()
_check("uv", True, uv or "not found (optional, recommended)")
if d["nvidia"]:
names = ", ".join(g["name"] for g in d["nvidia"]["gpus"])
_check(
"gpu",
True,
"%s (driver %s, CUDA %s)"
% (names, d["nvidia"]["driver"], d["nvidia"]["cuda_version"]),
)
elif d["rocm"]:
_check("gpu", True, "AMD ROCm (experimental)")
elif d["backend"] == "mps":
_check("gpu", True, "Apple Silicon (MPS)")
else:
_check("gpu", False, "no supported GPU detected")
has_venv = env.venv_exists()
_check("venv", has_venv, venv_dir() if has_venv else "not created yet")
if has_venv:
torch = env.installed_torch()
_check("torch", torch is not None, torch or "not installed")
if torch and d["backend"] == "cuda":
try:
out = subprocess.run(
[
venv_python(),
"-c",
"import torch; print(torch.cuda.is_available())",
],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
timeout=120,
env=clean_env(),
)
avail = out.stdout.decode().strip() == "True"
_check(
"torch sees gpu",
avail,
"" if avail else "torch.cuda.is_available() is False",
)
except (OSError, subprocess.TimeoutExpired):
_check("torch sees gpu", False, "could not query")
node_exe, node_major = nodejs.have_usable_node()
if node_exe:
_check("node", True, "%s (v%s)" % (node_exe, node_major))
else:
_check(
"node",
False,
"none >= %d found (manager sync installs a local copy)"
% nodejs.MIN_NODE_MAJOR,
)
if os.path.isfile(ffmpeg.ffmpeg_exe()):
# run it with the launch env so missing shared libs are caught
from . import launch
try:
out = subprocess.run(
[ffmpeg.ffmpeg_exe(), "-version"],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
timeout=30,
env=launch.build_env(),
)
works = out.returncode == 0
detail = (
out.stdout.decode().splitlines()[0]
if works
else "installed but fails to run"
)
except (OSError, subprocess.TimeoutExpired):
works, detail = False, "installed but fails to run"
_check("ffmpeg (local)", works, detail)
else:
_check("ffmpeg (local)", False, "not installed (manager sync installs it)")
try:
free_gb = shutil.disk_usage(REPO_ROOT).free / (1024**3)
_check("disk space", free_gb > 30, "%.0f GB free" % free_gb)
except OSError:
pass
branch = gitops.current_branch()
_check(
"git checkout",
True,
"%s @ %s%s"
% (branch, gitops.current_commit(), " (dirty)" if gitops.is_dirty() else ""),
)