v0.20.4

Hermes Agent v0.20.4


Overview

v0.20.4 — The Glass Release. Released August 18, 2026. ~74 merged PRs · ~146 commits · ~265 files changed (+21,697 / −2,217) since v0.20.3.

A day after the Resilience Patch came the window nobody asked for and everybody wanted: the desktop finally stops fighting you. The headline is Glass — a macOS translucency mode that blurs the window without bleaching the text — and around it lands a permanently tabbed SESSIONS|BOTS sidebar, a bot roster you can finally tidy up (hide, unhide, disband), Bot Mode group chats that no longer lose long-running turns, an advisory NVIDIA SkillEvaluator scan on every skill install, cron media-send hardening (configurable timeout, manual-run attachments that survive), SessionDB contention fixes that un-break wedged gateways, a hermes update that tells the truth about parked branches, and native Kanban notifications.

This is a patch release, so the official notes are brief and the full curated documentation ships with v0.21.0. This page covers the most valuable parts of the window.


Highlights

1. Desktop Glass — translucency you can read through (macOS)

Window translucency used to map to native window opacity, which fades the whole window — text included — so anyone with a busy wallpaper effectively had to pin it at 0. Glass gives the lever a second interpretation on macOS: the window stays opaque at the native level, and instead the renderer’s field surfaces thin over the vibrancy material every chat window already carries. You get a matte blur while text, cards, popovers, and the composer keep full contrast (#88744).

Once Glass is on, three controls shape it:

  • Intensity — the same lever, running the full range. At the top the tint is gone entirely: bare, untinted blur, with text and cards still opaque.
  • Frost — Deep / Soft / Bright / Glare. macOS exposes no blur-radius knob, so the vibrancy material is the frost control.
  • Area — whole window, or sidebar only (the Finder shape: glass rail, opaque content column).

Adjusting any of them peeks: the settings overlay covers the very effect its slider controls, so holding the slider ghosts the overlay and the live window becomes the preview. Fresh macOS profiles now start with Glass pre-selected — intensity still defaults to 0, so nothing visibly changes until you move the lever, and profiles that deliberately tuned clear stay clear. Windows and Linux see exactly the row they see today (#88956).

2. The SESSIONS | BOTS sidebar is a tab strip — and bots can be hidden

The desktop’s left sidebar now always boots with SESSIONS | BOTS as side-by-side tabs in one zone. The Bots pane carries an enforced dock invariant: at every boot’s first adoption pass, any stacked Sessions-over-Bots layout is re-homed as a center tab — that layout must never survive an update again (#88872).

The roster is tidier too: right-click a bot row → Hide Bot removes it from the roster and the Active-now strip (without touching @mentions, group membership, or open chats), and a header eye toggle — rendered only while at least one bot is hidden — reveals hidden bots dimmed, with right-click → Unhide Bot. The hidden state syncs across machines through profile.yaml ui_meta (#88800).

3. Bot Mode group chats stop losing long-running turns

A group-chat member turn used to carry a fixed 3-minute deadline; a turn that outlived it returned null, which the round-robin loop treats as a pass — so a reply that finished at minute 7 had nowhere to go. Now the deadline extends while the member’s session visibly reports inflight/running, bounded by a 20-minute hard cap, and a turn that still times out records a stranded baseline that gets harvested back into the room at the next turn boundary — late, never lost, surviving window reloads (#88885). Around it: group-chat messages render Markdown (#88553), cross-machine group routing survives connection switches (#88921), a bot can sit in several group chats at once (#88980), group chats are first-class Discord-style rows opening in the main window (#88738), and they can finally be disbanded from the GUI (#88659).

4. NVIDIA SkillEvaluator: an advisory second opinion on skill installs

hermes skills install now runs NVIDIA SkillEvaluator Tier 1 (PII, unicode smuggling, script lint) as an advisory scan on every hub install — findings are shown with file:line before the install confirmation, and the install always continues. It is deliberately warn-only: the upstream PII scanner has known false-positive classes (SSH syntax like [email protected], documentation example emails, op:// secret-manager references), so findings inform your decision rather than gate it. Secrets-class findings (private keys, cloud keys, tokens, credentialed connection strings) render red with an explicit review warning. The scan is optional — without the skillevaluator binary it degrades to a silent no-op — and can be disabled with skills.tier1_advisory: false (#88573).

5. Cron media-send hardening

Three cron delivery gaps closed in this window:

  • Configurable timeout: media attachment sends had a fixed 30-second window that large exports (long TTS audio, big PDFs) blew through, logging a failure with nothing after the colon. The timeout is now HERMES_CRON_MEDIA_SEND_TIMEOUTcron.media_send_timeout_seconds300s default, and timeouts always record a non-empty failure reason (#88787).
  • Manual runs no longer drop attachments: hermes cron run <job-id> could deliver a job’s text while silently dropping its PDF/image attachments and still report success — the standalone sender reported upload failures only in warnings, which nothing read. Attachment failures are now visible in the run status on both delivery lanes (#88631).
  • Missed fires are visible: when the hosted fire path can’t reach the gateway, the job gets a durable last_fire_error stamp surfaced in cronjob list, hermes cron list, and the dashboard — cleared on the next successful run (#88555).

6. SessionDB stops blocking the event loop

An enterprise fleet hit a gateway that could not come back up: an unclean shutdown racing a second instance made every restart block inside the v25 schema migration on the event-loop thread, the loop-liveness watchdog fired exit 75, and the supervisor restarted straight back into the same state. SessionDB (schema init + migration against a contended state.db) is never constructed on the event-loop thread anymore: on a cache miss it starts a one-shot background bootstrap and waits up to 250ms — a healthy init finishes inside the window, a contended one degrades to None (every caller already handles it) with the loop stalled far below the watchdog’s probe timeout (#88753).

7. hermes update tells the truth about parked branches

On a source checkout parked on a feature branch, hermes update used to stash, sync, print ✓ Code updated! — and leave the checkout on the stale branch with none of main’s new code. It now auto-switches back to main when the parked branch is provably safe to leave (clean tree + fully merged), warns loudly and marks the code update SKIPPED when it is not, and the summary lines carry the actual branch + HEAD short-sha so drift is visible at a glance:

✓ Update complete! [main @ 30fcf9580]

(#88928)

8. Kanban tasks ping you natively

Desktop now raises a native OS notification when a Kanban task completes, hits a blocker, or fails — the full terminal event set (completed, blocked, gave_up, crashed, timed_out, block_loop_detected) with per-kind severity, so a worker stalling on a blocker while you’re in another app no longer dies silently. Gated by Settings ▸ Notifications ▸ Plugin notifications (#88765).

Improvements

  • Project-skill scan quarantine + non-interactive trust inheritance (security): project skills are now scan-quarantined against injection at load time, and non-interactive surfaces (cron/API/ACP) inherit the human’s per-repo trust decision instead of prompting or auto-trusting — completing the remaining skill items of the project-local skills epic (#88643).
  • One-shot turns persist: hermes chat -Q / -q one-shot turns now persist into the resumed session — bot-to-bot Bot Chat messaging included (#88763).
  • Bot Mode group chat rooms show profile pictures (#88746); hidden CLI-born Bot Mode sessions stay out of the global Sessions sidebar (#88677).
  • Desktop Gateways settings page: Gateway + Connections unify into one machine-level page (#88735, #88812); one roster row per bot even when a backend registers under two addresses (#88828).
  • Providers: Muse Spark 1.2 added to the OpenRouter curated picker (#88600), and api.meta.ai routes through the Responses API for prompt caching (#88601).

Fixes

  • SessionDB event-loop-thread stall (see Highlight 6); virtual-model alias leak closed at write, read, and recovery-cache (#88761); multiplex sessions now stored in the owning profile’s state.db, not root (#88734).
  • Windows bot/profile delete no longer fails with WinError 32 — memory is released before the directory remove (#88727).
  • OpenAI adapter tolerates sparse response objects; relay unwraps lazy completed streams and uses canonical managed operation names (#85581, #85579, #85582).
  • Desktop: no phantom local default on remote-gateway desktops (#88554); deleted profiles stop reconnecting and mid-switch 404s are no longer treated as session deletion (#88638, #88699); the Bots pane always opens the pinned canonical Bot Chat (#88690).

Upgrade

hermes update

After upgrading, run hermes doctor to verify the install and restart the gateway (hermes gateway) so platform changes take effect. macOS users: the Glass mode shows up in Appearance ▸ Window Translucency once the desktop app refreshes.

← Hermes Agent Changelog