Skip to content

fix(honcho): harden self-hosted setup paths#35170

Merged
kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:salvage/honcho-selfhost-33954
May 30, 2026
Merged

fix(honcho): harden self-hosted setup paths#35170
kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:salvage/honcho-selfhost-33954

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

Salvage of #33954 (Erosika / Plastic Labs) onto current main. Authorship preserved (commit authored by Erosika <eri@plasticlabs.ai>). The original branch was CONFLICTING — the only conflict was tests/test_packaging_metadata.py, where the PR's pytest.importorskip("setuptools") is now redundant with #34851 (which declared setuptools in the dev extra), so that one-file change was dropped.

Self-hosted Honcho setup had four sharp edges, each tied to an open issue:

Plus gateway cache-correctness (#33382):

  • skip honcho.json parsing in gateway cache-busting when Honcho is not the active memory provider; memoize by honcho.json mtime when it is active (removes per-message disk I/O for non-Honcho users)
  • bust the gateway agent cache on memory.provider change (the provider value gates whether honcho.json is parsed, but wasn't itself a cache-busting key)

And a fresh-install ergonomics fix:

  • add a hermes memory setup <provider> one-liner. The per-provider hermes <provider> subcommand only registers once that provider is active, so on a fresh install hermes honcho setup doesn't exist yet (argparse rejects invalid choice: 'honcho'). hermes memory setup is always available and now takes an optional positional routing to the same wizard.

Closes #20688.
Closes #29885.
Closes #26459.
Closes #30246.
Closes #33382.
Closes #32244.

Core-file touches (justified)

This is a memory-plugin PR that touches a few core files; each is justified:

  • utils.py — generic mode= arg on the shared atomic_json_write (one helper change vs. four per-provider copies).
  • gateway/run.py — the from plugins.memory.honcho.client import ... import already exists on main; this PR doesn't add a new core→plugin dependency, it improves the existing one (gates the read behind provider == "honcho", memoizes by mtime, adds memory.provider cache key).
  • hermes_cli/main.py / memory_setup.py — generic optional positional on memory setup, provider-agnostic.
  • hermes_cli/profiles.py — dot→underscore host-key migration with legacy fallback.

Test plan

scripts/run_tests.sh tests/honcho_plugin/ tests/test_honcho_client_config.py \
  tests/gateway/test_agent_cache.py tests/hermes_cli/test_profiles.py \
  tests/hermes_cli/test_memory_setup_provider_arg.py \
  tests/plugins/memory/test_hindsight_provider.py tests/plugins/memory/test_mem0_v2.py \
  tests/plugins/memory/test_supermemory_provider.py

Result: 672 passed, 0 failed. New cache-busting behavior is explicitly tested (skip-when-not-honcho, read-only-when-honcho, memory.provider busts signature, mtime memoization). tests/hermes_cli/test_memory_setup_provider_arg.py adds 4 tests for the new routing.

E2E verified with real imports + isolated HERMES_HOME: 0600 perms on write and preserved on rewrite; profile_host_key dot-sanitization; _host_block legacy dot-form fallback; /vN stripping across loopback/Tailscale/LAN/cloud/no-version/mid-path-version; gateway cache-busting gate.

ruff + ty clean on changed files.

Credit

Supersedes #33954, #20720, #30180, #32244, #33535, and the self-hosted/safe-host-key portion of #26478.

Self-hosted Honcho setup had four sharp edges:

- local/cloud URLs ending in /vN double-prefixed by the SDK (/v3/v3/... 404)
- authenticated local servers had no setup prompt for a JWT/bearer token
- profile-derived host keys could be dot-containing workspace IDs Honcho rejects
- memory-provider config files with API keys written world-readable per umask

This keeps existing behavior but makes those paths safer:

- strip a trailing /vN version segment from any configured baseUrl before SDK
  init (the SDK's route builders always prepend their own version prefix);
  auth-skipping stays loopback-only
- add an optional local JWT/bearer prompt in honcho setup, stored under
  hosts.<host>.apiKey
- derive new profile host keys with underscores, still reading legacy
  hermes.<profile> blocks
- write memory-provider config files atomically with 0600 via a shared
  utils.atomic_json_write(mode=) arg (honcho/hindsight/mem0/supermemory)
- skip honcho.json parsing in gateway cache-busting unless Honcho is the active
  memory provider; memoize by honcho.json mtime when active
- bust the gateway agent cache on memory.provider change
- add a hermes memory setup <provider> one-liner so fresh installs can configure
  a named provider without the picker (the per-provider hermes <provider>
  subcommand only registers once that provider is active)

Closes NousResearch#20688, NousResearch#29885, NousResearch#26459, NousResearch#30246, NousResearch#33382, NousResearch#32244.

Co-authored-by: BROCCOLO1D
@kshitijk4poor kshitijk4poor enabled auto-merge (rebase) May 30, 2026 05:28
@kshitijk4poor kshitijk4poor merged commit 827ce60 into NousResearch:main May 30, 2026
23 checks passed
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins comp/gateway Gateway runner, session dispatch, delivery type/security Security vulnerability or hardening labels May 30, 2026
@alt-glitch alt-glitch removed the type/bug Something isn't working label May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have type/security Security vulnerability or hardening

Projects

None yet

3 participants