mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix: route memory-provider dep installs through lazy_deps durable target
Installing a memory provider (Honcho, mem0, hindsight, ...) from the dashboard Plugins page failed on hosted deployments with a permission error: the setup endpoint shelled out to `uv pip install --python sys.executable`, which targets the sealed read-only venv under /opt/hermes (immutable hosted image, NS-579/#49113). The correct mechanism already exists: tools/lazy_deps.py redirects installs to the writable durable target on the data volume (HERMES_LAZY_INSTALL_TARGET=/opt/data/lazy-packages) when the venv is sealed (HERMES_DISABLE_LAZY_INSTALLS=1), appends the target to the END of sys.path (core venv always wins collisions), and constrains shared deps to core-venv versions. The dashboard installer simply never used it. Fix: - tools/lazy_deps.py: new public install_specs() — installs arbitrary manifest-declared pip specs through the same environment routing as ensure(): venv-scoped by default, durable-target on sealed images, refused with an actionable reason when gated off (config kill switch or sealed venv without a target — never surfaces raw EROFS/EACCES). Specs are validated with _spec_is_safe(); post-install it invalidates import/metadata caches so availability rechecks in the same process see the new packages without a restart. Never raises. - hermes_cli/web_server.py: _install_memory_provider_pip_dependencies now calls install_specs() instead of building its own uv/pip subprocess. Blocked installs surface the gate reason in the setup results; the response's status block reflects post-install availability (stale 'missing deps' state clears immediately). - hermes_cli/memory_setup.py, plugins/memory/honcho/cli.py, plugins/memory/mem0/_setup.py: CLI setup wizards routed through install_specs() too — same sealed-venv failure mode, same fix. No hosted setup path writes to /opt/hermes anymore; provider discovery and installation now use the same environment (sys.path activation is shared with the lazy-install bootstrap in hermes_bootstrap). Tests: - tests/tools/test_lazy_deps.py: TestInstallSpecs — gating matrix (sealed+no-target blocked with immutable-deployment reason, config kill switch, sealed+target proceeds), spec-safety rejection before any subprocess, venv-scoped vs --target command display, failure stderr passthrough, never-raises contract. - tests/hermes_cli/test_web_server.py: setup endpoint routes pip through lazy_deps (regression guard asserts no direct 'pip install' subprocess), blocked-reason surfacing, same-response availability recheck clears stale missing state. Fixes NS-605 (Plain T-1111).
This commit is contained in:
parent
2796fca8c9
commit
8bbd77f368
7 changed files with 416 additions and 25 deletions
|
|
@ -516,12 +516,17 @@ def _ensure_sdk_installed() -> bool:
|
|||
return False
|
||||
|
||||
print(" Installing honcho-ai...", flush=True)
|
||||
from hermes_cli.tools_config import _pip_install
|
||||
# Environment-aware install: sealed hosted venvs redirect to the durable
|
||||
# data-volume target instead of writing to /opt/hermes (NS-605).
|
||||
from tools.lazy_deps import install_specs
|
||||
|
||||
result = _pip_install(["honcho-ai==2.2.0"])
|
||||
if result.returncode == 0:
|
||||
result = install_specs(["honcho-ai==2.2.0"])
|
||||
if result.ok:
|
||||
print(" Installed.\n")
|
||||
return True
|
||||
elif result.blocked:
|
||||
print(f" Cannot install: {result.reason}\n")
|
||||
return False
|
||||
else:
|
||||
print(f" Install failed:\n{(result.stderr or '').strip()}")
|
||||
print(" Run manually: uv pip install 'honcho-ai==2.2.0'\n")
|
||||
|
|
|
|||
|
|
@ -863,11 +863,17 @@ def _install_provider_deps(llm_id: str, embedder_id: str, vector_id: str) -> Non
|
|||
for dep in sorted(deps):
|
||||
try:
|
||||
print(f" Installing {dep}...")
|
||||
subprocess.run(
|
||||
["uv", "pip", "install", "--python", sys.executable, dep],
|
||||
capture_output=True, timeout=60,
|
||||
)
|
||||
print(f" ✓ Installed {dep}")
|
||||
# Environment-aware install: sealed hosted venvs redirect to the
|
||||
# durable data-volume target instead of /opt/hermes (NS-605).
|
||||
from tools.lazy_deps import install_specs
|
||||
|
||||
outcome = install_specs([dep], timeout=60)
|
||||
if outcome.ok:
|
||||
print(f" ✓ Installed {dep}")
|
||||
elif outcome.blocked:
|
||||
print(f" Warning: cannot install {dep}: {outcome.reason}")
|
||||
else:
|
||||
print(f" Warning: Could not install {dep}. Install manually: uv pip install {dep}")
|
||||
except Exception:
|
||||
print(f" Warning: Could not install {dep}. Install manually: uv pip install {dep}")
|
||||
if deps:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue