hermes-agent/plugins/memory
Shannon Sands 8bbd77f368 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).
2026-07-28 22:40:33 -07:00
..
byterover fix: add explicit UTF-8 encoding to all subprocess text=True calls (#53428) 2026-07-24 11:45:57 -07:00
hindsight fix(gemini): sweep hardcoded Gemini default models to gemini-3.6-flash (#32360) 2026-07-28 18:17:56 -07:00
holographic fix(memory): preserve genuine pre-delimiter content in merged compaction rows 2026-07-22 06:59:14 -07:00
honcho fix: route memory-provider dep installs through lazy_deps durable target 2026-07-28 22:40:33 -07:00
mem0 fix: route memory-provider dep installs through lazy_deps durable target 2026-07-28 22:40:33 -07:00
openviking fix(openviking): cool down failed refreshes and publish conn identity atomically 2026-07-24 13:00:53 +05:30
retaindb fix(memory): guard local uploads against credential reads 2026-07-05 03:14:49 -07:00
supermemory fix(supermemory): complete self-hosted endpoint routing 2026-07-20 00:40:40 -07:00
__init__.py fix(windows): sweep remaining bare read_text/write_text sites + linter rule 2026-07-24 17:10:39 -07:00
config_schema.py revert(memory): drop the provider actions extension point 2026-07-10 15:41:52 -04:00
query_rewrite.py fix(honcho): enforce recall latency and budget contracts 2026-07-16 12:48:48 -07:00