Browse by topic

Hermes yesterday, October 28, 2026: replies, redirects and cron runs that landed in the wrong place

What landed on Hermes Agent main on October 28, 2026: old conversations kept off the chat after /new, web_extract re-checking redirects, cron test runs that keep the scheduled one and first sessions that no longer stall.

Title card from the Hermes yesterday motion recap: white capitals over a black arcade maze with blue pixel walls, peach dots and a yellow chomper, reading things landed in the wrong place, main put them back.

Things kept turning up in the wrong place. After /new in a Telegram chat, what you typed into the old conversation from the Desktop was answered in the chat, web_extract followed redirects into sites you had blocked, and test-firing a cron job used up its real run. 258 commits landed; here are the 10 that matter.

1. After /new, the old conversation stays yours in the apps and out of the chat

Before: when a messaging chat moved to another conversation (/new, /resume, /branch, a handoff, the context-exhaustion auto-reset or a fresh session), a prompt you sent to the old conversation from the Desktop, the Webapp or the mobile app ran in the chat’s new conversation, and its reply was posted to the chat. Reminders and background commands started there answered in the chat too, and after a gateway restart the app refused to continue the old conversation at all. After: the app’s prompts, Stop and controls act on the old conversation alone, and nothing it produces reaches the chat: replies, reminders, subscriptions and background results land in the old conversation. The chat keeps getting only its new conversation’s replies, and /resume of the old one on the chat brings them back there. Limits: a model or /yolo override picked in the app after the chat moved on is not kept, and tool approvals in such a turn were not tested live.

Pull request: Old conversation after /new.

2. web_extract checks where a page really ended up

Before: when a page redirected, web_extract checked your website blocklist and the private-address guard only against the URL you asked for, so a redirect into a blocked site was served, and a cached redirect kept serving its target after you blocked it. On most providers a target’s own 403, 404 or 429 came back as a successful extraction with no error, so the agent could not tell blocked from blank, the error page was cached as the content, and the keyless ring read a site’s 429 as vendor throttling and moved on to the next vendor. After: every extract provider, the keyless rescue ring included, re-checks the final URL against the blocklist and the private-address guard, refused pages are never cached, and a cache hit re-checks the page’s final URL. Target errors read HTTP 403 from origin (the body is kept), and an origin error never walks the keyless ring. Limits: cache entries written before the update keep the old check until they expire, and a vendor that follows a redirect but reports only the requested URL leaves nothing to check.

Pull requests: Redirects re-checked, Target errors reported.

3. Test-firing a cron job no longer uses up its scheduled run

Before: a manual run (cronjob run, hermes cron run, the dashboard or Webapp Run button) counted as the job’s scheduled run: test-firing an in 30m one-shot completed it, so the real run never happened, and a recurring job with repeat.times lost one of its runs. A run-now that arrived while a manual run was in flight was dropped, and the manual run’s completion notice said Model: ? and API calls: 0. After: a manual run is an extra fire. The one-shot keeps its slot and fires on time, a repeat budget keeps all its runs, a queued run-now survives, and the notice shows the model and API calls the run actually recorded. A run-now when the slot is already due still counts as that scheduled run, so it does not fire twice.

Pull requests: Extra fire, Real model and API calls in the notice.

4. A slow network no longer stalls your first session

Before: on a fresh home with no caches, the first new session waited for the model registry and model-metadata downloads inside the request, and their timeouts only covered each socket read, so a connection trickling a byte every couple of seconds or a hung DNS lookup held it up: no reply in 240 s in the PR’s tests, and 100 s with stalled DNS. After: each of those downloads has a 15 s total limit and falls back to the cache it has (an empty one on a fresh home), so the same tests answered in 0.9 to 30.5 s. On a normal network nothing changes: the full registry still downloads and is cached.

Pull request: Slow network, first session.

5. No more blank pages after hermes update

Before: a dashboard tab left open across hermes update went blank the next time you opened a page it had not loaded yet, because the rebuild deleted the old page files, and it stayed blank until you reloaded by hand. In the Desktop and the Webapp, a single stylesheet or script request that failed at boot left a blank page with nothing to click. After: the dashboard reloads once into the new build (at most once every 5 minutes per tab, so a truly broken build cannot loop), and a failed Desktop or Webapp boot shows a notice with a Reload button, in the Hermes wordmark and your theme colours. It never reloads on its own.

Pull requests: Dashboard reloads into the new build, Reload notice on a failed boot.

6. Discord approval buttons last as long as the approval

Before: Discord command-approval buttons stopped working after Discord’s own view timeout even when approvals.timeout was longer, approvals.discord_prompt_timeout was capped at 900 s, and a card answered elsewhere (a text /approve, a timeout, /stop) kept live-looking buttons. After: the buttons follow the request’s timeout, the configured Discord prompt timeouts are honoured above 900 s, and every card is retired with how it ended once the request settles, whatever path settled it. A stale click only answers the person who clicked, and the approval id no longer travels in the platform metadata that the relay forwarded to its external connector.

Pull request: Discord approvals.

7. Kanban workers survive a dropped connection

Before: when a Kanban worker’s socket to its gateway dropped mid-turn, the worker exited, the turn ended and the card was booked crashed, losing the work done. A worker lost during its handshake could leave its card stuck on running (49 minutes in the report), because every reclaim path waited for the long-lived gateway to exit. After: a lost socket, an owner restart or a draining owner resumes the same attempt on a new connection, giving up only after 180 s of owner silence, and a lost worker’s card is booked on the next dispatcher tick after the grace period, with an error that names the loss. Limit: a graceful gateway restart still interrupts the turn; the worker now reads that result instead of failing.

Pull requests: Socket drop resumes the attempt, Lost worker’s card booked.

8. The Webapp is you, with one Group Chat list

Before: a signed-in Webapp tab counted as a second user, so the Desktop and the Webapp each saw only their own Group Chats, and a Desktop on its own local backend (hermes serve or hermes dashboard) kept yet another list. Group Chat files did not work on that backend, and a room stopped after 10 replies however many members it had. After: a signed-in Webapp tab acts as the machine owner, the same identity the native Desktop uses, so chats and Group Chats are shared with the Desktop and the TUI. A standalone backend passes Group Chat calls to the running gateway and hands its existing rooms over once (deleted rooms stay deleted), and sends, member replies and file attachments work on handed rooms. The room limits are config keys now, hosted_rooms.discussion.max_messages (default 10) and max_rounds (default 3), read when the service starts. In review: a fix so a first bot delivery stops renaming an older Bot Chat.

Pull requests: Webapp is the machine owner, One Group Chat list, Handed rooms take Sends, File attach on the local backend, Files on both routes, room limits as config, Bot Chat rename fix, in review.

9. Fleets can manage config centrally (opt-in)

Before: every agent read each profile’s config.yaml from its own disk. After: with HERMES_CONFIG_BACKEND=remote in the environment or .env, an agent (Hermes Cloud or an on-prem fleet) fetches each profile’s config from a central config service, polls it every 5 minutes, and sends hermes config set, model switches and dashboard edits as compare-and-swap writes. Admins set values and locks at global, tenant, group, owner, agent or profile level, and the agent cannot change a locked key. If the service is unreachable at boot the agent exits instead of running on defaults, secret-shaped keys accept only ${VAR} references, and config edit, backups, profile clone, profile rename and snapshot restore are refused in this mode. Nothing changes unless you set the variable: the file stays the default. Heads-up: an open PR reports that a Hermes Cloud agent in this mode hangs at boot on its first remote read, and fixes it; it is still in review.

Pull requests: Backend, Cloud boot hang fix, in review.

10. 1 new plugin in the catalog: long-term memory

1 new community entry: Severian is a local-first long-term memory provider, with an append-only store in SQLite or PostgreSQL with pgvector, hybrid keyword and vector search with a re-ranker, memories that cite the observations they came from, and a note when two returned memories disagree. It works offline by default. Heads-up: it stores every conversation turn, by default in one SQLite database under the Hermes root shared by all profiles (rows scoped per profile), and its opt-in embeddings download a model from Hugging Face on first use. Catalog entries do not wait for a release: they reach installs through the published catalog.

Meanwhile, in the engine room

Dozens of fixes landed yesterday that most users never see, and the Webapp and the Desktop took most of them: Group Chats, plugins, sign-in and shortcuts.

  • Manual /compress on a gateway session (CLI, TUI, Desktop, ACP) silently used the built-in compressor even when a plugin context engine was configured; it now runs through the configured engine and refuses a summary that would grow the conversation (pull request)
  • On Browser Use cloud, a screenshot of a hidden tab hung for 60 s and failed; it now brings the tab to the front and returns in under a second, and on a local browser your own tab is left alone (pull request)
  • Installs where Teams or Google Chat were never set up logged a no valid toolsets warning to errors.log, and new installs no longer get those config rows; a real typo in such a row still warns (pull request)
  • On a Webapp exposed on the network, a signed-out request to /api/status showed profile names, the install id and memory and disk figures, and confirmed whether a profile name existed; it now gets only liveness and the sign-in details (pull request)

If you noticed none of this, it worked.

All on main, ships in the next release; the new catalog entry already reaches installs through the published catalog (Desktop app changes reach the Microsoft Store app with the release and the .exe and .dmg app with its next bundled release). Latest stable: v0.22.5.

Watch the recap

The 56-second motion recap, made with Remotion, is on X.

Was this configuration guide helpful?

If you have questions, encountered issues during setup, or want to discuss networking and security, connect or reach out on LinkedIn.

Connect on LinkedIn