feat(acp): Hermes runtime discovery and durable session load#2633
feat(acp): Hermes runtime discovery and durable session load#2633joelbrilliant wants to merge 5 commits into
Conversation
Register Hermes as a known ACP runtime in Desktop and buzz-acp, with command normalisation for hermes and hermes-acp entrypoints. Persist channel→session bindings across harness restarts and restore via session/load when the agent advertises loadSession (Hermes does). History replay stays on the wire log path and is not re-published to Buzz. Add owner dogfood guide for attaching Rocky with HERMES_HOME and acp.tool_policy: profile. Signed-off-by: joelbrilliant <joelbrilliant1@gmail.com>
Include Hermes Agent in the onboarding runtime picker alongside Claude and Codex, treat it as a CLI-native ready path (no Buzz provider pick), and lock provider selection the same way as other profile-owned runtimes. Signed-off-by: joelbrilliant <joelbrilliant1@gmail.com>
Steal the strongest Hermes-specific pieces from block#2468 without the conflicting external-agent directory work: - command-specific hermes/hermes-acp --check readiness as AdapterMissing - exact python/python3 marker-owned interpreter recognition - dogfood guide fixes (BUZZ_ACP_NO_MEMORY=true, parallelism=1) - buzz-acp README Hermes section Signed-off-by: joelbrilliant <joelbrilliant1@gmail.com>
6050c14 to
12168f8
Compare
Review requestFocused Hermes path for local managed agents (not the external-agent directory work in #2468). What this adds
Dogfood (2026-07-24) Checks
Companion Happy to split or drop anything that blocks merge. External-agent / kind 10100 / relay-observer stays out of this PR on purpose so it can land cleanly. |
|
Hey Joel — I built on #2633 locally, preserving your three commits and authorship, and found one data-loss issue worth flagging before merge.
The full branch also includes optional Hermes profile selection ( Verification: focused session-store 3/3; lost-update regression passed 75 repeated runs; clippy, formatting, and diff checks green; I didn’t open a competing PR. Happy to split the session-store fix or profile slice however is easiest for you to land. |
SessionStore was process-local cache + whole-file rewrite, so two buzz-acp processes sharing the same agent command/args identity could clobber each other's channel bindings. Reload under a sibling lockfile for every get/put/remove, keep atomic writes, recover put from corrupt sidecars, and cover independent-open interleaving in regression tests. Reported and prototyped by @rungmc357 on PR block#2633. Co-authored-by: Georgio Constantinou <210088133+rungmc357@users.noreply.github.com> Co-authored-by: joelbrilliant <joelbrilliant1@gmail.com> Signed-off-by: joelbrilliant <joelbrilliant1@gmail.com>
|
Thanks - good catch. Agreed on the SessionStore lost-update: process-local cache + whole-file rewrite is unsafe when two Verification here:
I'd like to keep #2633 scoped to discovery + durable load + onboarding. Optional Hermes Credits stay as noted for #2468 / @NYTEMODEONLY and your store fix. No need for a competing PR. |
|
Thanks, that sounds right. I don’t want to open a competing PR. Happy to help get #2633 through, and I’ll hold the optional profile support for a separate follow-up after this lands. |
|
Appreciate it. Store fix is on the branch ( If you want to help while we wait, the highest-leverage things are:
Otherwise we can leave it for review as-is. Thanks again for catching the lost-update before merge. |
|
I took a second pass against I found two residual session-binding edges:
I didn’t find anything else material. |
Failed session/load used key-only remove, so process A reading X then failing load could delete process B's newer Y for the same channel. Clear bindings with remove_if_equals under the existing lock, and cover the interleaving race in regression tests. Durable store identity is command + args + channel, not HERMES_HOME. Require unique -p <profile> acp args for multi-profile managed agents and drop the HERMES_HOME-only alternative from dogfood docs until the store is namespaced. Also note long-lived ACP OAuth stay-alive ops in the Rocky dogfood guide. Reported by @rungmc357 on PR block#2633. Co-authored-by: Georgio Constantinou <210088133+rungmc357@users.noreply.github.com> Co-authored-by: joelbrilliant <joelbrilliant1@gmail.com> Signed-off-by: joelbrilliant <joelbrilliant1@gmail.com>
|
Second pass taken - both residual edges were real. 1. Failed load deleting a newer binding Landed 2. HERMES_HOME-only multi-profile collision Commit: 3c83c15 Verification:
Thanks again for the careful review. |
|
Repositioning this against #2773, now that #2656 is being closed in its favour. The overlap I flagged on #2656 was runtime registration and model-selection UX, and BYOH supersedes that half properly - a generic seam beats two harness-specific PRs, so that's the right call. What it doesn't cover is durable sessions: I had a look through #2773 and there's no That's the half this PR does, and it's independent of how a runtime gets registered. So the plan I proposed on #2656 still works with #2773 as the target instead: land BYOH, then I rebase this down to just Also worth calling out that @rungmc357's review here found two real session-binding edges (a failed restore deleting a newer binding, and a multi-profile identity collision). Both are fixed in the current head with @wpfleger96 no rush on this at all - happy to wait until BYOH is settled and then do the rebase against whatever the final seam looks like. Just sing out if you'd rather I close this and open a fresh persistence-only PR instead, either way suits. |
Summary
Clean, mergeable Hermes attachment path for Buzz Desktop +
buzz-acp:hermes/hermes-acp)hermes acp; keep directhermes-acpfallbackhermes acp --check/hermes-acp --check→ AdapterMissing when ACP deps are absent (not a fake "logged out")python/python3marker-owned process recognition (Hermes console scripts under a venv)session/loadwhen the agent advertisesloadSessiondocs/hermes-agent-rocky.mdbuzz-acpREADME Hermes sectionHermes keeps its own tools/skills/memory/config. Buzz does not inject Buzz MCP for Hermes by default.
Live dogfood (2026-07-24)
Owner-only Rocky DM on Desktop worked end-to-end after:
acp.tool_policy: profile(companion PR below)hermes, empty args,HERMES_HOME,BUZZ_ACP_NO_MEMORY=true(must be the stringtrue, not1)Relationship to other PRs
acp.tool_policy: profilefull tool surfaceStolen from #2468 without the conflicting external-agent surface: readiness probe as AdapterMissing, python/python3 interpreter recognition, operator docs patterns.
Not in this PR (intentionally): external-agent directory cards, kind
10100profile publishing, owner presentation overrides, relay observer ingestion. That can land as a follow-up once #2468 is rebased or split.Deeper native Hermes product integration (first-class Nous surface beyond ACP bridge) is best done by the Nous Research team upstream.
Test plan
cargo test -p buzz-acp --lib(595 passed)HERMES_HOME+session/loadafter restart (manual)hermesis on PATHhermeswithout ACP extra surfaces AdapterMissing (not ready)DCO
All commits carry
Signed-off-by: joelbrilliant <joelbrilliant1@gmail.com>.