Hermes Agent v0.20.3
Overview
v0.20.3 — The Resilience Patch. Erschienen am 16. August 2026. Seit v0.20.2 ~125 gemergte PRs · ~250 Commits · ~461 geänderte Dateien (+42.613 / −1.641).
Einen Tag nach dem Connections Patch beantwortet dieses Release eine leisere Frage: Was passiert, wenn deine Automation still und heimlich stehen bleibt und niemand etwas davon mitbekommt? Der cron-Scheduler übersteht jetzt eine erschöpfte Dateideskriptor-Tabelle, gleicht veraltete Claims gegen das Executions-Ledger ab, bewaffnet festgeklemmte wiederkehrende Jobs neu und holt versäumte Ausführungen externer Provider nach – während last_fire_error jede verpasste Ausführung in der CLI, im Dashboard und in der Tool-Ausgabe des Agents selbst sichtbar macht. Darum herum: die MCP-2.x-SDK-Migration mit Unterstützung für das zustandslose Protokoll von 2026-07-28, CommandCode als Provider erster Klasse, das von Copilot CLI inspirierte /worktree und das sichere /rollback, die gehärtete Runtime-Ownership für Python-Subprozesse sowie Fixes gegen Datenverluste beim Session-Handoff.
Da es sich um ein Patch-Release handelt, fallen die offiziellen Notizen knapp aus – die vollständige kuratierte Dokumentation erscheint mit v0.21.0. Diese Seite deckt die wertvollsten Teile dieses Zeitfensters ab.
Highlights
1. Der cron-Scheduler heilt sich selbst
Drei stille Stillstand-Modi, die Jobs früher stundenlang lahmlegten – während alles „gesund aussah“ – heilen sich jetzt selbst:
- EMFILE (Dateideskriptor-Erschöpfung):
tick()verschluckte früher jedenOSErrorals „eine andere Instanz hält das Lock“, sodass eine fd-Erschöpfung an der Lock-Datei als erfolgreicher Tick verbucht wurde und danach nie wieder ein Job lief. Der errno beim Lock-Erwerb wird jetzt klassifiziert: Nur echte Konkurrenz wird still übersprungen, echte Fehler schlagen als fehlgeschlagener Tick durch, und der Ticker versucht best effort, Dateideskriptoren zurückzugewinnen (gc.collect()+ Anheben des weichen nofile-Limits), mit exponentiellem Backoff und einem Maximum von 15 Minuten (#88335, basierend auf #87796 von @webtecnica). - Veraltete In-Flight-Claims: Ein ausgelaufener Claim, der jünger als das Altersfenster (2×Interval, 30 Minuten) war, klemmte einen wiederkehrenden Job fest, bis jemand von außen eingriff. Der Sweep gleicht jetzt gegen das dauerhafte Executions-Ledger ab: Belegt die Terminalzeile des Laufs, dass er beendet wurde, wird der Claim zwangsweise freigegeben – mit einer Schutzlogik, damit ein frischer Claim nie mit dem abgeschlossenen Ergebnis des vorherigen Laufs verwechselt wird (#88343, basierend auf #87259).
- Festgeklemmter persistierter Fehlerzustand: Ein wiederkehrender Job mit
last_status=errorund einem in der Zukunft parkendennext_run_atwar für jeden Sweep unsichtbar und überlebte Gateway-Neustarts. Er bewaffnet sich jetzt automatisch beim nächsten Tick neu – und das Re-Arming respektiert die Zulässigkeit des Zeitplans, sodass eine Nur-Wochentage-Cron-Expression niemals an einem Samstag feuert (#88339, basierend auf #87261).
2. Verpasste Ausführungen sind sichtbar – und werden nachgeholt
Der Live-Vorfall vom 14. August 2026 (vier verpasste Nachtläufe in Folge, ohne jede Spur außer einer Logzeile) hat zwei dauerhafte Fixes hervorgebracht. Erstens: Wenn der gehostete Fire-Pfad das Gateway nicht erreichen kann, bekommt der Job einen last_fire_error-Stempel, der in cronjob list, hermes cron list (rote Zeile ⚠ Missed scheduled fire:) und im Dashboard auftaucht; ein erfolgreicher Lauf löscht ihn wieder, sodass der Stempel immer den aktuellen Zustand beschreibt (#88555). Zweitens: Externe cron-Provider (Chronos / gehostetes Managed Cron) unterstützen jetzt das Nachholen versäumter Ausführungen: Kommt ein Fire nie an und sind die Retries erschöpft, erkennt das Gateway den überfälligen Job und führt ihn nach einer Gnadenfrist lokal aus – cron.misfire_grace_minutes (Standard 10, ≤0 deaktiviert). Der Ausfall kostet Minuten statt eines still verlorenen Tages (#88563).
3. MCP: SDK 2.x + das zustandslose Protokoll von 2026-07-28
Hermes ist auf das MCP-2.x-SDK migriert (#88180) und spricht das zustandslose Protokoll von 2026-07-28 jetzt durchgängig end-to-end (#88299). Server ohne initialize-Handshake verbinden sich sofort über einen einzigen _negotiate_session()-Choke-Point an allen vier Transport-Aufrufstellen (stdio, SSE, neues HTTP, altes HTTP). Der protocol-Schlüssel pro Server: auto (Standard) versucht zuerst den alten Handshake und fällt auf server/discover zurück, wenn der Server ihn ablehnt – null zusätzliche Roundtrips für die bestehende Flotte; stateless probiert zuerst discover; legacy deaktiviert den Fallback. SEP-2549-ttlMs/cacheScope-Hinweise aus tools/list werden mit TTL-Ablauf in den Schema-Cache übernommen, und die OAuth-Registrierung folgt der neuen Spezifikation (natives application_type, RFC-9207-iss-Validierung).
4. Neue Provider: CommandCode (und Muse Spark auf main)
CommandCode (commandcode.ai) ist jetzt ein Provider erster Klasse – die Profile commandcode (OpenAI Chat Completions) und commandcode-anthropic (Anthropic Messages, Bearer-Auth) teilen sich einen COMMANDCODE_API_KEY und decken die Pläne GOAT/Pro/Max/Provider ab (rund 30+ offene und geschlossene Modelle, Live-Discovery über den öffentlichen Endpunkt /provider/v1/models) (#88308, gerettet aus #32909). Auf main (nach dem Tag) gesellt sich die Meta Model API (Muse Spark) als eingebautes Plugin dazu: --provider meta-ai funktioniert out of the box mit MODEL_API_KEY (Aliasse META_API_KEY/META_MODEL_API_KEY, Override über META_BASE_URL) und einem Katalog aus muse-spark-1.2 / muse-spark-1.2-contributor (#88565).
5. /worktree und sicheres /rollback – Agent-Änderungen, die man zurücknehmen kann
In diesem Zeitfenster landen zwei von Copilot CLI inspirierte Befehle. /worktree new [name] erstellt mitten in der Session einen isolierten git-Worktree (.worktrees/ im Repository, Branch auf Basis der frisch geholten Remote-Spitze, worktree_sync wird beachtet) und leitet die Terminal- und Datei-Tools der Session dorthin um – ohne Neustart; /worktree zeigt den aktiven Tree und /worktree list listet alle auf, mit derselben Exit-Aufräumlogik wie hermes -w (ungepushte Bäume bleiben erhalten). /rollback setzt jetzt standardmäßig auf sichere Wiederherstellung: Ein projektweites Ledger der vom Agent geschriebenen Änderungen (sha256 jedes gelandeten write_file/patch) erlaubt es, nur das zurückzurollen, was der Agent geändert hat, vom Agent erstellte Dateien zu löschen und deine Hand-Edits zu erhalten; --all/--force stellt alles wieder her, übersprungene Dateien werden mit einem Hinweis gemeldet.
6. Python-Subprozess-Runtime-Ownership
execute_code und Co. besitzen jetzt ihre Python-Subprozess-Umgebung: PYTHONHOME/PYTHONPATH werden aus der verwalteten Runtime zusammengesetzt statt verunreinigt von der Eltern-Shell geerbt. Das schließt eine ganze Klasse von „funktioniert in meinem Terminal, bricht im Agent“-Überraschungen und härtet die Grenze gegenüber unvertrautem Code.
7. Fixes für Datenverluste beim Session-Handoff
Zwei von Nutzern gemeldete Datenverlust-Bugs sind behoben (#88244). Eine CLI→Gateway-Race nach /handoff telegram konnte die Session-Zeile finalisieren, die das Gateway gerade aktiv beschrieb – das gesamte Handoff-Bein verschwand daraufhin aus dem Verlauf und aus session_search; die CLI verfolgt jetzt übergebene Session-IDs und überspringt die Cleanup-Finalisierung. Außerdem wird eine korrupte state.db, die alle Nachrichten blockierte, jetzt an die Oberfläche geholt: Das Gateway sendet Wiederherstellungs-Hinweise (inklusive hermes doctor --fix und sqlite3 .recover) an die Home-Kanäle, statt den Fehler in Logs zu vergraben.
Verbesserungen
- Sicherheits-Scan bei Plugin-Installation und -Update (inspiriert von Claude-Cowork): Installationen werden vor der Aktivierung auf verdächtige Inhalte gescannt.
- UTF-16-Textdateien werden durch Transkodierung nach UTF-8 gelesen (Port aus MoonshotAI/kimi-code#2647); Gemini-3-Tool-Call-IDs bleiben über Adapter-Umschreibungen hinweg erhalten (Port aus earendil-works/pi#7494).
- Git-Worktree-Selbstheilung: Ein fehlgeschlagener oder abgelaufener
hermes -w-Worktree-Aufruf räumt hinter sich auf (Teilverzeichnis, LOCKED-Admin-Eintrag, verwaister Branch), und der Start-Wartungslauf repackt, wenn die Packs ausufern – die 39 Packs (638 MB) aus dem August-Vorfall wurden zu 2 (287 MB), und die Worktree-Erstellung fiel von einem 30-Sekunden-Timeout auf 0,5 Sekunden (#88306). - Cua-Driver-0.20-Runtime-Verträge: Computer-Use prüft einen installierten Driver bei Update und Laufzeit und repariert ihn automatisch, wenn er den Runtime-Vertrag nicht erfüllt (#87646-Familie).
- Desktop: DiffusionCanvas-Rendering ist begrenzt (Pause-Policy, 15-fps-Budget, Instanz-Obergrenze), die Pixel-Ei-Animation im Leerlauf schläft, Bot-Mode-Gruppenchats rendern Markdown, und Remote-Gateway-Desktops zeigen keinen Phantom-Local-Default mehr (#88564, #88406, #88553, #88554).
- Delegate: Die uncommittete Arbeit eines Subagents bleibt erhalten, wenn die Git-Inspektion fehlschlägt, und Eltern werden informiert, wenn ein Worktree ungeprüft erhalten blieb.
Fixes
/handoff-CLI→Gateway-Race, die das Handoff-Bein verlor (#88234); state.db-Korruption wird jetzt mit Wiederherstellungs-Hinweisen gemeldet (#88235).- Matrix: Leere nackte Dateinamen in
m.audio/m.file/m.video-Bodies werden bereinigt; Telegram bevorzugt IPv4-API-Adressen und loggt den erstgewählten Sticker als info. - Cron:
run_claimwird bei Dispatch-Fehlern für Einmal-Jobs entfernt; Drift-Korrekturen werden auf nutzereigene Pins gelenkt. - Kompression: Eine abgebrochene Rotation bläht das übergeordnete Element, das sie nicht veröffentlichen konnte, nicht mehr auf.
- Desktop: Die Pre-Start-Settle-Sperre kann den Composer nicht mehr verriegeln; ein wiederhergestellter bzw. bearbeiteter Arm hält den Composer nutzbar.
Upgrade
hermes update
Nach dem Upgrade hermes doctor ausführen, um die Installation zu prüfen, und das Gateway neu starten (hermes gateway), damit Plattformänderungen greifen. Wenn du einen externen cron-Provider nutzt, wirf einmal einen Blick auf hermes cron list, um sicherzugehen, dass last_fire_error nichts Offenes anzeigt.