mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 02:05:22 -04:00
fix: report serve dependency readiness (#412)
This commit is contained in:
+132
-11
@@ -92,6 +92,115 @@ def _docker_row_status(*, on_remote, in_container, installed, default_hint):
|
||||
return DockerRowStatus(applicable=True, install_hint=default_hint)
|
||||
|
||||
|
||||
def _package_installed_from_probe(name: str, probe: dict) -> bool:
|
||||
"""Return whether an optional dependency is usable by Cookbook.
|
||||
|
||||
A Python import alone is not enough: namespace packages can be created by a
|
||||
same-named directory, and vLLM serving needs the CLI on PATH. Keep this
|
||||
aligned with the actual serve command each backend launches.
|
||||
"""
|
||||
binaries = probe.get("binaries") if isinstance(probe.get("binaries"), dict) else {}
|
||||
dists = probe.get("dists") if isinstance(probe.get("dists"), dict) else {}
|
||||
modules = probe.get("modules") if isinstance(probe.get("modules"), dict) else {}
|
||||
|
||||
if name == "vllm":
|
||||
return bool(binaries.get("vllm"))
|
||||
if name == "llama_cpp":
|
||||
return bool(binaries.get("llama-server") or dists.get("llama-cpp-python"))
|
||||
if name == "sglang":
|
||||
return bool(dists.get("sglang") or modules.get("sglang", {}).get("real_module"))
|
||||
if name == "diffusers":
|
||||
return bool(
|
||||
(dists.get("diffusers") or modules.get("diffusers", {}).get("real_module"))
|
||||
and (dists.get("torch") or modules.get("torch", {}).get("real_module"))
|
||||
)
|
||||
if name == "hf_transfer":
|
||||
return bool(dists.get("hf-transfer") or modules.get("hf_transfer", {}).get("real_module"))
|
||||
return bool(dists.get(name) or modules.get(name, {}).get("real_module"))
|
||||
|
||||
|
||||
def _package_status_note(name: str, probe: dict) -> str:
|
||||
binaries = probe.get("binaries") if isinstance(probe.get("binaries"), dict) else {}
|
||||
modules = probe.get("modules") if isinstance(probe.get("modules"), dict) else {}
|
||||
dists = probe.get("dists") if isinstance(probe.get("dists"), dict) else {}
|
||||
module = modules.get(name) if isinstance(modules.get(name), dict) else {}
|
||||
locations = module.get("locations") or []
|
||||
if name == "vllm":
|
||||
if binaries.get("vllm"):
|
||||
return f"vLLM CLI: {binaries['vllm']}"
|
||||
if module.get("found") and not dists.get("vllm"):
|
||||
loc = locations[0] if locations else module.get("origin") or "unknown path"
|
||||
return f"Python sees a vllm namespace at {loc}, but no vLLM CLI is on PATH."
|
||||
return "vLLM CLI not found on PATH."
|
||||
if name == "llama_cpp":
|
||||
parts = []
|
||||
if binaries.get("llama-server"):
|
||||
parts.append(f"native llama-server: {binaries['llama-server']}")
|
||||
if dists.get("llama-cpp-python"):
|
||||
parts.append(f"python package: llama-cpp-python {dists['llama-cpp-python']}")
|
||||
return "; ".join(parts) if parts else "No native llama-server or llama-cpp-python server package found."
|
||||
if name == "diffusers":
|
||||
if _package_installed_from_probe(name, probe):
|
||||
return f"diffusers {dists.get('diffusers', 'available')} with torch {dists.get('torch', 'available')}"
|
||||
return "Diffusers serving needs both diffusers and torch."
|
||||
if name in dists:
|
||||
return f"{name} {dists[name]}"
|
||||
return ""
|
||||
|
||||
|
||||
def _package_probe_script(names: list[str]) -> str:
|
||||
names_lit = ",".join(repr(n) for n in names)
|
||||
return f"""
|
||||
import importlib.util
|
||||
import importlib.metadata as md
|
||||
import json
|
||||
import shutil
|
||||
|
||||
names=[{names_lit}]
|
||||
dist_names={{
|
||||
'vllm':['vllm'],
|
||||
'llama_cpp':['llama-cpp-python'],
|
||||
'sglang':['sglang'],
|
||||
'diffusers':['diffusers','torch'],
|
||||
'hf_transfer':['hf-transfer','hf_transfer'],
|
||||
}}
|
||||
bin_names={{
|
||||
'vllm':['vllm'],
|
||||
'llama_cpp':['llama-server'],
|
||||
}}
|
||||
|
||||
def mod_status(n):
|
||||
spec = importlib.util.find_spec(n)
|
||||
loader = getattr(spec, 'loader', None) if spec else None
|
||||
return {{
|
||||
'found': bool(spec),
|
||||
'origin': getattr(spec, 'origin', None) if spec else None,
|
||||
'loader': type(loader).__name__ if loader else None,
|
||||
'locations': list(getattr(spec, 'submodule_search_locations', []) or []),
|
||||
'real_module': bool(spec and loader),
|
||||
}}
|
||||
|
||||
def dist_status(ds):
|
||||
out = {{}}
|
||||
for d in ds:
|
||||
try:
|
||||
out[d] = md.version(d)
|
||||
except Exception:
|
||||
pass
|
||||
return out
|
||||
|
||||
def probe(n):
|
||||
mods = {{n: mod_status(n)}}
|
||||
if n == 'diffusers':
|
||||
mods['torch'] = mod_status('torch')
|
||||
dists = dist_status(dist_names.get(n, [n]))
|
||||
bins = {{b: shutil.which(b) for b in bin_names.get(n, [])}}
|
||||
return {{'modules': mods, 'dists': dists, 'binaries': bins}}
|
||||
|
||||
print(json.dumps({{n: probe(n) for n in names}}))
|
||||
"""
|
||||
|
||||
|
||||
def _find_line_break(buf):
|
||||
"""Find next line terminator in buffer. Returns (index, separator_length) or (-1, 0)."""
|
||||
ni = buf.find(b"\n")
|
||||
@@ -646,7 +755,7 @@ def setup_shell_routes() -> APIRouter:
|
||||
never reflected because the check only ever looked at the local host.
|
||||
"""
|
||||
_require_admin(request)
|
||||
import importlib, shlex, json as _json
|
||||
import importlib, importlib.metadata as importlib_metadata, shlex, json as _json
|
||||
port_arg = ""
|
||||
if ssh_port and str(ssh_port).strip() not in ("", "22"):
|
||||
_port = str(ssh_port).strip()
|
||||
@@ -672,18 +781,12 @@ def setup_shell_routes() -> APIRouter:
|
||||
# Remote check: for remote-target packages, probe the selected server's
|
||||
# venv over SSH so a remote `pip install` actually reflects here.
|
||||
remote_status: dict = {}
|
||||
remote_details: dict = {}
|
||||
remote_names = [p["name"] for p in packages if p.get("target") == "remote" and p.get("kind") != "system"]
|
||||
remote_system_names = [p["name"] for p in packages if p.get("target") == "remote" and p.get("kind") == "system"]
|
||||
if host and remote_names:
|
||||
try:
|
||||
names_lit = ",".join(repr(n) for n in remote_names)
|
||||
py = (
|
||||
"import importlib.util,json,shutil;"
|
||||
f"names=[{names_lit}];"
|
||||
"status={n:(importlib.util.find_spec(n) is not None) for n in names};"
|
||||
"status['llama_cpp']=status.get('llama_cpp',False) or shutil.which('llama-server') is not None;"
|
||||
"print(json.dumps(status))"
|
||||
)
|
||||
py = _package_probe_script(remote_names)
|
||||
src = ""
|
||||
if venv:
|
||||
act = venv if venv.endswith("/bin/activate") else venv.rstrip("/") + "/bin/activate"
|
||||
@@ -705,7 +808,12 @@ def setup_shell_routes() -> APIRouter:
|
||||
for line in reversed(txt.splitlines()):
|
||||
line = line.strip()
|
||||
if line.startswith("{"):
|
||||
remote_status = _json.loads(line)
|
||||
remote_details = _json.loads(line)
|
||||
remote_status = {
|
||||
name: _package_installed_from_probe(name, probe)
|
||||
for name, probe in remote_details.items()
|
||||
if isinstance(probe, dict)
|
||||
}
|
||||
break
|
||||
except Exception:
|
||||
remote_status = {}
|
||||
@@ -736,16 +844,29 @@ def setup_shell_routes() -> APIRouter:
|
||||
on_remote = bool(host and pkg.get("target") == "remote")
|
||||
if on_remote:
|
||||
pkg["installed"] = bool(remote_status.get(pkg["name"], False))
|
||||
probe = remote_details.get(pkg["name"])
|
||||
if isinstance(probe, dict):
|
||||
pkg["details"] = probe
|
||||
note = _package_status_note(pkg["name"], probe)
|
||||
if note:
|
||||
pkg["status_note"] = note
|
||||
elif pkg.get("kind") == "system":
|
||||
pkg["installed"] = shutil.which(pkg["name"]) is not None
|
||||
elif pkg["name"] == "llama_cpp" and shutil.which("llama-server"):
|
||||
pkg["installed"] = True
|
||||
pkg["status_note"] = f"native llama-server: {shutil.which('llama-server')}"
|
||||
else:
|
||||
try:
|
||||
importlib.import_module(pkg["name"])
|
||||
pkg["installed"] = True
|
||||
if pkg["name"] == "vllm":
|
||||
pkg["installed"] = shutil.which("vllm") is not None
|
||||
else:
|
||||
importlib_metadata.version(pkg["name"].replace("_", "-"))
|
||||
pkg["installed"] = True
|
||||
except ImportError:
|
||||
pkg["installed"] = False
|
||||
except importlib_metadata.PackageNotFoundError:
|
||||
pkg["installed"] = False
|
||||
|
||||
if pkg["name"] == "docker":
|
||||
status = _docker_row_status(
|
||||
|
||||
Reference in New Issue
Block a user