Skip to content

hermes-agent 1.3.0 — browser sidecar, external webhooks, dashboard default - #536

Merged
jacobecox merged 4 commits into
mainfrom
claude/hermes-agent-130
Sep 2, 2026
Merged

hermes-agent 1.3.0 — browser sidecar, external webhooks, dashboard default#536
jacobecox merged 4 commits into
mainfrom
claude/hermes-agent-130

Conversation

@jacobecox

Copy link
Copy Markdown
Contributor

Feature version born from two days of live testing against 1.2.1. Every feature below was measured working end to end before this PR.

What's new

  • Browser automation via a Chromium CDP sidecar (browser.enabled, default off). The Nous image ships no browser and browser tools silently fall back to web_extract; enabling this adds a pinned chromedp/headless-shell container to the workload with CDP on loopback and points the agent at it. Live-verified: real CDP navigation, no fallback — and confirmed the app container drives it with the sidecar alone (no dep install), so it carries none of the fragility that scoped WhatsApp out.
  • External webhooks (webhooks.enabled, default off). Listener on 8644, HMAC-signed. Two exposure paths: publicAccess.expose: webhooks (canonical HTTPS, recommended) and opt-in webhooks.directLoadBalancer (dedicated L4 LB — billed continuously, plain-HTTP, and it takes over the canonical endpoint; all stated in values + README). Live-verified: signed POST → 202 → agent turn on both paths; bad signature → 401.
  • dashboard.publicUrl for custom-domain deployments (MCP OAuth callbacks + asset URLs).
  • Default publicAccess.expose flipped apidashboard — the dashboard is unusable through port-forward (a documented connection-pool issue), so the template no longer pushes users there. The API stays reachable in-GVC. Admin-login-on-public-endpoint security note carried prominently.

Scoped out, deliberately

WhatsApp personal is documented as unsupported, not half-built. Upstream ships the Baileys bridge without its node_modules (dead on arrival) and writes session state off-volume under the gateway's scrubbed env. Supporting it would mean fragile first-boot scaffolding around an upstream packaging bug, for a feature that links a personal account and surfaces its QR only to a log file. It — and the other upstream root causes — go in a report to Nous instead.

Testing

Review: PASS WITH WARNINGS (0 blockers); both warnings fixed (a default-flip footgun in the expose guards, and a premature "verified" claim now qualified with how it was confirmed). Test round: 9 PASS / 0 FAIL, then the fixes above landed as test-driven commits:

  • Config seed now sets platforms.webhook.enabledhermes webhook subscribe reads the config key, not the env the listener starts from.
  • README corrected against measured reality: per-route auto-generated HMAC secrets (shared secret is opt-in); directLoadBalancer does not coexist with a public canonical HTTPS surface.

Drift gate clean on the two-container workload; all five validation arms confirmed live; render-vs-stored shows only additive API backfills.

Review diff: git diff b6021b6..HEAD -- hermes-agent/versions/1.3.0/

🤖 Generated with Claude Code

jacobecox and others added 4 commits September 2, 2026 13:28
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
….publicUrl, default expose dashboard

- browser.enabled (default off): optional chromedp/headless-shell:151.0.7922.109
  sidecar, loopback CDP :9222 seeded as browser.cdp_url. Gating test settled live —
  the sidecar alone drives real navigation (bundled browser-use plugin, no app-container
  CLI install needed). No probes/ports on the sidecar; own scratch chrome-shm.
- webhooks.enabled (default off): WEBHOOK_ENABLED/PORT(8644)/SECRET/URL; signing secret
  rides the existing prerequisite dictionary secret (secret.keys.webhookSecret). Two
  exposure paths: publicAccess.expose: webhooks (canonical HTTPS, recommended) and
  webhooks.directLoadBalancer.enabled (dedicated L4 LB, billed + plain-HTTP — stated).
- dashboard.publicUrl: overrides HERMES_DASHBOARD_PUBLIC_URL for custom domains.
- Default publicAccess.expose flipped api -> dashboard; enum + guards extended.
- WhatsApp documented unsupported (no code). Slack 25-cmd cap / empty-allowlist-fails-closed
  and Telegram-OOB findings added. README + briefing truth pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…Access.enabled

Review (PASS WITH WARNINGS) caught a footgun the default-expose flip
introduced: the expose:dashboard/webhooks coupling guards fired regardless
of publicAccess.enabled, so a PRIVATE default install that turned the
dashboard off hit a render fail for a public-endpoint choice that is
irrelevant when nothing is public. Both guards now gate on
publicAccess.enabled. Verified: private + dashboard.enabled=false renders;
every invalid PUBLIC combination still fails.

Also qualified the browser 'verified' README wording to state HOW it was
confirmed (sidecar CDP navigation in agent.log, live this build) rather than
reading as an untested claim, and fixed a nested-parens artifact.

Sidecar tag chromedp/headless-shell:151.0.7922.109 reconfirmed via
docker manifest inspect.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ct webhook docs

Test round passed 9/0 (shippable). Fixes it surfaced:

CHART: the config seed now sets platforms.webhook.enabled=true under
webhooks.enabled. The listener starts from the WEBHOOK_ENABLED env, but
'hermes webhook subscribe' (which the README tells users to run) reads the
CONFIG key instead — without seeding it the documented CLI failed. Same
mechanism as the four proven model/browser config-set seed lines.

DOCS (truth pass against measured behavior):
- Each webhook subscription carries its OWN auto-generated HMAC secret;
  the shared secret.keys.webhookSecret is opt-in via --secret "$WEBHOOK_SECRET".
  The old wording implied the global secret signed every route.
- directLoadBalancer does NOT coexist with a public canonical HTTPS surface:
  measured, enabling it flips status.canonicalEndpoint to the tcp:// direct-LB
  address. Corrected the 'coexisting' claim.
- Added the V2 timestamped-signature replay-protection note.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jacobecox
jacobecox merged commit 760e1b5 into main Sep 2, 2026
6 checks passed
@jacobecox
jacobecox deleted the claude/hermes-agent-130 branch September 2, 2026 22:27
jacobecox added a commit that referenced this pull request Sep 3, 2026
* CHANGELOG: hermes-agent 1.3.0

The 1.3.0 version (PRs #536, #537) merged without its ship-close CHANGELOG
entry. Add it: optional Chromium browser sidecar, external webhooks, the
publicAccess.expose default flip to dashboard, and dashboard.publicUrl.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* CHANGELOG: hermes-agent 1.4.0

Add the 1.4.0 line (opt-in personal WhatsApp + pre-registered cpln MCP)
above 1.3.0, on the same catalog-changelog PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant