Hermes Agent

Hermes fixes three ways failure can look like success

Hermes patches `/stop` under named profiles, failed delegation status for non-retryable client errors, and Desktop recovery when a cloud agent returns 502, 503 or 504 during boot.

← Back to homeOriginal source ↗

NousResearch/hermes-agent PR #91939 is the inspected primary source: “fix(gateway): /stop leaves sibling thread runs alive under a named profile.” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- NousResearch/hermes-agent PR #91939 was created 2026-08-22T00:35:03Z and was open at inspection; its title is “fix(gateway): /stop leaves sibling thread runs alive under a named profile.” - NousResearch/hermes-agent PR #91940 was created 2026-08-22T00:35:34Z and was open at inspection; its title is “fix(delegate): report failed status for non-retryable subagent client errors (#82599).” - NousResearch/hermes-agent PR #91921 was created 2026-08-22T00:00:06Z and was open at inspection; its title is “feat(desktop): cloud-agent-down boot failures get actionable recovery (#85335, salvage #85373).” - The repository reported 233997 stars, 34386 open issues, default branch main, and last push 2026-08-22T00:31:15Z. - The latest tagged-release baseline checked was v2026.8.19 published 2026-08-21T12:16:39Z.

What changed

NousResearch/hermes-agent PR #91939 reports: What _sibling_thread_run_keys (used by /stop to find other participants' runs in a shared thread under thread_sessions_per_user=True) built its match prefix from a hardcoded agent:main. _session_key_namespace puts a named profile in that exact slot (agent:coder:...), so under any profile other than the default the prefix matched nothing: /stop silently reported no sibling runs and left them running. Only the default profile ever worked. Fix Derive the namespace from the caller's own key instead of hardcoding main. Siblings share the caller's namespace by definition, so this also keeps profiles isolated — a /stop in one profile must not reach another profile's runs in the same thread. Default-profile keys build the byte-identical prefix as before. Test plan tests/gateway/test_stop_thread_sibling.py: added the named-profile case (fails without this change), a profile-isolation case, a near-miss thread id guard (thr11 vs thr1), and an explicit default-profile-unchanged guard..venv/Scripts/python.exe -m pytest tests/gateway/test_stop_thread_sibling.py -q — 5 passed. Platforms tested Windows (dev box). No platform-specific code paths touched.

NousResearch/hermes-agent PR #91940 reports: Fixes #82599 Root cause A child that aborted on a non-retryable client error (HTTP 401, billing wall, content-policy block) returns the error string as inal_response with ailed=True from un_conversation() — but _run_single_child() derived delegation status purely from summary non-emptiness. The error string qualified as "usable output", so every batch reported status=completed while the delegation was silently broken (xit_reason=max_iterations, runcated=true on a one-call task). Fix ools/delegate_tool.py::_run_single_child now checks esult["failed"] first: those aborts report status="failed" / xit_reason="error" (same vocabulary as the existing timeout/exception entries). completed=False alone is deliberately NOT treated as failure — iteration-budget-exhausted children still return genuine summaries and stay completed+truncated (documented intended behavior). Single, batch and background paths share this derivation point, so one fix covers all shapes; async queue copies status verbatim downstream. Verification New behavior-contract tests in ests/tools/test_delegate.py: non-retryable client error → failed status; budget-exhausted-with-summary → stays completed. scripts/run_tests.sh tests/tools/test_delegate.py → 71 passed; 8 sibling delegate/async-delegation files → 118 passed.

NousResearch/hermes-agent PR #91921 reports: Summary A Nous Cloud agent returning 502/503/504 at boot no longer looks like a frozen app — the boot-failure overlay says the cloud instance is down and offers real recovery actions: Check Portal status · Use local gateway · Retry · Get help on Discord. Salvages #85373 by @andrexibiza (fixes #85335). Root cause: both boot boundaries (OAuth WS-ticket mint + readiness polling) collapsed server-side faults into the generic "backend did not become ready", and the renderer boot-looped with no guidance for an instance the user can't restart. Changes electron/backend-health.ts (@andrexibiza): isServerSideHttpError (structured statusCode-first, legacy "503:" prefix fallback), isNousCloudAgentUrl (*.agents.nousresearch.com), and one shared makeNousCloudBackendDownError factory used at BOTH boot boundaries; 401/403 stay on the reauth path, 500 keeps polling. electron/connection-config.ts (@andrexibiza): gatewayTicketFailure preserves the integer statusCode through the ticket-error wrapper so Cloud classification survives. electron/main.ts: boot progress carries isCloudBackendDown + statusCode; conflict with main's newer host-key-change latch resolved in favor of both. boot-failure-overlay.tsx: cloud-down branch renders Portal/Discord as dedicated action buttons (follow-up commit — URLs live in code, localized hints can't drift them), plus Use local gateway / Retry / Gateway settings; Repair (local-only) correctly dropped. i18n: en/ja/zh/zh-hant/ar for the cloud-down copy + the two new button labels. Validation | Check | Result | |---|---| | boot-failure-overlay.test.tsx (4 tests, incl. cloud-down button contract) | pass | | electron vitest project (backend-health

Why it matters

All three defects erase failure identity: work continues after stop, a client error becomes completed output, or a dead cloud backend looks like a frozen app. The operator test is whether the system remains bounded and its receipts still describe the action after failure, retry or restart.

Current

The primary record was open when captured on 2026-08-22. The tagged-release baseline was v2026.8.19 published 2026-08-21T12:16:39Z. Repository metadata, full source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/NousResearch/hermes-agent/pull/91939. Supporting records are https://github.com/NousResearch/hermes-agent/pull/91940 and https://github.com/NousResearch/hermes-agent/pull/91921. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Preserve namespace, failure class and recovery action in the terminal receipt, then verify that stop, delegation and boot overlays agree with runtime state. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.