fix: distinguish external cookbook runtimes (#1188)

This commit is contained in:
spooky
2026-06-03 00:20:00 +10:00
committed by GitHub
parent 6b7dd4ea28
commit f667667da3
3 changed files with 82 additions and 6 deletions

View File

@@ -118,6 +118,7 @@ def _running_in_container(dockerenv_path="/.dockerenv", cgroup_path="/proc/1/cgr
DockerRowStatus = namedtuple("DockerRowStatus", ["applicable", "install_hint"])
PackageUpdateStatus = namedtuple("PackageUpdateStatus", ["available", "note"])
def _docker_row_status(*, on_remote, in_container, installed, default_hint):
@@ -180,7 +181,10 @@ def _package_status_note(name: str, probe: dict) -> str:
locations = module.get("locations") or []
if name == "vllm":
if binaries.get("vllm"):
return f"vLLM CLI: {binaries['vllm']}"
parts = [f"vLLM CLI: {binaries['vllm']}"]
if dists.get("vllm"):
parts.append(f"python package: vllm {dists['vllm']}")
return "; ".join(parts)
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."
@@ -201,6 +205,35 @@ def _package_status_note(name: str, probe: dict) -> str:
return ""
def _package_pip_update_status(pkg: dict, probe: dict | None = None) -> PackageUpdateStatus:
"""Return whether the Dependencies UI should offer a generic pip update.
"Installed" means Cookbook can use the dependency. It does not always mean
the dependency is a Python package that Cookbook should update with pip:
native llama-server can come from a package manager/source build, and a CLI
may be on PATH without matching Python package metadata.
"""
if pkg.get("kind") == "system" or not pkg.get("pip"):
return PackageUpdateStatus(False, "Update this system dependency outside Odysseus.")
name = pkg.get("name")
binaries = probe.get("binaries") if isinstance(probe, dict) and isinstance(probe.get("binaries"), dict) else {}
dists = probe.get("dists") if isinstance(probe, dict) and isinstance(probe.get("dists"), dict) else {}
if name == "llama_cpp" and binaries.get("llama-server"):
return PackageUpdateStatus(
False,
"Using native llama-server on PATH; update it with its package manager or source checkout.",
)
if name == "vllm" and binaries.get("vllm") and not dists.get("vllm"):
return PackageUpdateStatus(
False,
"Using a vLLM CLI on PATH without Python package metadata; update it outside Odysseus.",
)
return PackageUpdateStatus(True, "Update uses pip in the selected Python environment.")
def _prepend_user_install_bins_to_path() -> None:
"""Make pip --user console scripts visible to dependency probes.
@@ -944,6 +977,7 @@ def setup_shell_routes() -> APIRouter:
for pkg in packages:
on_remote = bool(host and pkg.get("target") == "remote")
probe = None
if on_remote:
pkg["installed"] = bool(remote_status.get(pkg["name"], False))
probe = remote_details.get(pkg["name"])
@@ -957,12 +991,23 @@ def setup_shell_routes() -> APIRouter:
elif pkg["name"] == "llama_cpp" and shutil.which("llama-server"):
pkg["installed"] = True
pkg["status_note"] = f"native llama-server: {shutil.which('llama-server')}"
probe = {"binaries": {"llama-server": shutil.which("llama-server")}, "dists": {}}
elif pkg["name"] == "vllm":
_vllm_cli = shutil.which("vllm")
pkg["installed"] = _vllm_cli is not None
if pkg["installed"]:
try:
_vllm_version = importlib_metadata.version(_pip_dist_name(pkg))
except importlib_metadata.PackageNotFoundError:
_vllm_version = None
probe = {
"binaries": {"vllm": _vllm_cli},
"dists": {"vllm": _vllm_version} if _vllm_version else {},
}
pkg["status_note"] = _package_status_note("vllm", probe)
else:
try:
importlib.import_module(pkg["name"])
if pkg["name"] == "vllm":
pkg["installed"] = shutil.which("vllm") is not None
else:
importlib_metadata.version(_pip_dist_name(pkg))
pkg["installed"] = True
except ImportError:
@@ -970,6 +1015,12 @@ def setup_shell_routes() -> APIRouter:
except importlib_metadata.PackageNotFoundError:
pkg["installed"] = False
if pkg.get("installed"):
update_status = _package_pip_update_status(pkg, probe)
pkg["pip_update_available"] = update_status.available
if update_status.note:
pkg["update_note"] = update_status.note
if pkg["name"] == "docker":
status = _docker_row_status(
on_remote=on_remote,

View File

@@ -618,6 +618,10 @@ async function _fetchDependencies() {
const _statusTag = (pkg, isLocal, isSystemDep, winBlocked) => {
if (winBlocked) return `<span class="cookbook-dep-tag cookbook-dep-na">N/A</span>`;
if (pkg.installed && isSystemDep) return `<span class="cookbook-dep-tag cookbook-dep-installed" title="Found on selected server">Installed</span>`;
if (pkg.installed && pkg.pip_update_available === false) {
const tip = esc(pkg.update_note || pkg.status_note || 'Found externally; update outside Odysseus.');
return `<span class="cookbook-dep-tag cookbook-dep-installed" title="${tip}">Installed</span>`;
}
if (pkg.installed) return `<button class="cookbook-dep-tag cookbook-dep-installed cookbook-dep-installed-btn" title="Installed — click for actions"><span class="cookbook-dep-installed-label">Installed</span><span class="cookbook-dep-caret">&#9662;</span></button>`;
if (isSystemDep) {
const depTip = esc(pkg.install_hint || 'Install this OS package on the selected server.');
@@ -632,11 +636,13 @@ async function _fetchDependencies() {
const isSystemDep = pkg.kind === 'system';
const winBlocked = !isLocal && _isWindows() && _winUnsupported.has(pkg.name);
const note = pkg.status_note ? `<div class="memory-item-meta" style="font-size:10px;opacity:0.65;margin-top:3px;">${esc(pkg.status_note)}</div>` : '';
const updateNote = pkg.installed && pkg.pip_update_available === false && pkg.update_note ? `<div class="memory-item-meta" style="font-size:10px;opacity:0.55;margin-top:3px;">${esc(pkg.update_note)}</div>` : '';
return `<div class="cookbook-dep-row${winBlocked ? ' cookbook-dep-blocked' : ''}" data-pkg-name="${esc(pkg.name)}" data-dep-pip="${esc(pkg.pip || '')}" data-dep-target="${isLocal ? 'local' : 'remote'}" data-dep-kind="${esc(pkg.kind || 'python')}">`
+ `<div class="cookbook-dep-info">`
+ `<div class="memory-item-title">${esc(pkg.name)}</div>`
+ `<div class="memory-item-meta" style="font-size:10px;opacity:0.5;margin-top:2px;">${esc(pkg.desc)}</div>`
+ note
+ updateNote
+ `</div>`
+ `<span class="cookbook-dep-tag cookbook-dep-cat">${esc(pkg.category)}</span>`
+ _statusTag(pkg, isLocal, isSystemDep, winBlocked)

View File

@@ -15,6 +15,7 @@ from routes.shell_routes import (
_running_in_container,
_docker_row_status,
_package_installed_from_probe,
_package_pip_update_status,
_package_probe_script,
_package_status_note,
_prepend_user_install_bins_to_path,
@@ -224,6 +225,21 @@ class TestPackageProbeStatus:
}
assert _package_installed_from_probe("vllm", probe) is True
assert "python package: vllm 0.8.5" in _package_status_note("vllm", probe)
assert _package_pip_update_status({"name": "vllm", "pip": "vllm"}, probe).available is True
def test_vllm_cli_without_dist_is_external_for_update(self):
probe = {
"modules": {"vllm": {"found": False, "real_module": False}},
"dists": {},
"binaries": {"vllm": "/opt/vllm/bin/vllm"},
}
status = _package_pip_update_status({"name": "vllm", "pip": "vllm"}, probe)
assert _package_installed_from_probe("vllm", probe) is True
assert status.available is False
assert "outside Odysseus" in status.note
def test_llama_cpp_is_installed_when_native_llama_server_exists(self):
probe = {
@@ -234,6 +250,9 @@ class TestPackageProbeStatus:
assert _package_installed_from_probe("llama_cpp", probe) is True
assert "native llama-server" in _package_status_note("llama_cpp", probe)
status = _package_pip_update_status({"name": "llama_cpp", "pip": "llama-cpp-python[server]"}, probe)
assert status.available is False
assert "package manager or source checkout" in status.note
def test_diffusers_requires_torch_too(self):
missing_torch = {