Hermes Agent

Hermes extends A2A streaming while tightening delivery recovery

Hermes proposes client-side streaming A2A calls with capability-gated fallback, per-peer headers and a corrected Discord recovery cursor. The three records turn transport negotiation, peer identity and replay position into explicit delivery contracts.

← Back to homeOriginal source ↗

NousResearch/hermes-agent PR #86369 is the inspected primary source: “feat(a2a): client-side SendStreamingMessage with card-gated fallback.” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- NousResearch/hermes-agent PR #86369 was created 2026-08-14T21:27:09Z and was open at inspection; its title is “feat(a2a): client-side SendStreamingMessage with card-gated fallback.” - NousResearch/hermes-agent PR #86322 was created 2026-08-14T20:24:22Z and was open at inspection; its title is “feat(a2a): support custom per-peer headers and send User-Agent.” - NousResearch/hermes-agent PR #86547 was created 2026-08-15T00:05:45Z and was open at inspection; its title is “feat(discord): recovery cursor correctness (omniscience R3).” - The repository reported 230646 stars, 32256 open issues, default branch main, and last push 2026-08-15T00:39:36Z. - The latest tagged-release baseline checked was v2026.8.13 published 2026-08-13T20:37:37Z.

What changed

NousResearch/hermes-agent PR #86369 reports: Summary _send_task() checks the peer's agent card (already fetched for the RPC URL) for capabilities.streaming When promote, it issues SendStreamingMessage and reads the SSE response: interim task/statusUpdate frames and keepalive comments keep bytes flowing, so proxies with idle timeouts no longer kill long-running turns Reply text is collected from artifactUpdate frames (prioritized) or the terminal statusUpdate, matching the existing message/send extraction order Falls back to the existing blocking message/send path when the card is unavailable, doesn't promote streaming, or the stream fails at transport level Why A2A peers behind reverse proxies with idle timeouts — Cloudflare's ~100s 524 is the canonical case — are unusable for long tasks today: the client POSTs message/send, the peer works past the proxy's timeout, and the connection dies with a 524 while the task may still complete server-side. The A2A v1.0 message/stream binding already exists on the server side (SSE with 5s keepalives); this wires the client to use it when available. Includes the per-peer custom headers change from #86322 (first commit), since reaching streaming peers behind header-auth proxies needs both. This PR is stacked; if #86322 merges first, only the later commits here are novel. Adversarial review pass (fixes 1-5) An independent adversarial review of the initial implementation surfaced five defects; all fixed

NousResearch/hermes-agent PR #86322 reports: Summary _resolve_peer() passes through a headers dict from the peer config entry _send_task() merges per-peer headers into every request alongside auth headers _http_get_json() / _http_post_json() send a Hermes-A2A/1.0 User-Agent Why A2A peers fronted by header-authenticating proxies (e.g. Cloudflare Access with service tokens: CF-Access-Client-Id / CF-Access-Client-Secret) are unreachable today — only bearer/basic auth headers are sent. Per-peer custom headers make any header-auth proxy work with zero code changes, and a real User-Agent keeps proxies/WAFs from rejecting the default Python UA. Config example Test plan [x] Live-tested against a Hermes peer behind Cloudflare Access (service token policy): card fetch + task submit succeed with headers configured, 403 without [x] Existing bearer-auth peer (no custom headers) unaffected [ ] Unit tests for header merge precedence Summary by CodeRabbit **New Features** Added support for custom HTTP headers in peer configuration. Custom headers are now included in discovery and task requests. **Improvements** Added the Hermes-A2A/1.0 User-Agent header to HTTP requests.

NousResearch/hermes-agent PR #86547 reports: Discord Omniscience R3** (Part of #79564, Fixes #86539): recovery cursor correctness. 21/21 tests pass. New module only.

Why it matters

A streaming transport is only useful if peers can negotiate it safely and a reconnect does not repeat or skip messages. Headers and cursors are part of delivery identity, not decoration. 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-15. The tagged-release baseline was v2026.8.13 published 2026-08-13T20:37:37Z. 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/86369. Supporting records are https://github.com/NousResearch/hermes-agent/pull/86322 and https://github.com/NousResearch/hermes-agent/pull/86547. 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

Bind the selected A2A method, peer headers and recovery cursor into one receipt, then test fallback and reconnect against duplicate and missing delivery. 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.