Hermes Agent v0.21.2
Aperçu
v0.21.2 — The state.db Patch Release. Publiée le 11 septembre 2026. 947 commits hors merge · 1 869 fichiers modifiés (+182 504 / −15 564) · 312 PR fusionnées · 140 contributeurs depuis v0.21.1.
v0.21.0 a réécrit la gestion des connexions du stockage de sessions, et une partie de cette réécriture a laissé le state.db fragile sur une partie des installations : un second writer pouvait annuler les verrous du premier, une base parfaitement saine pouvait être jugée corrompue, et une seule ligne défectueuse suffisait à faire tomber sessions list. v0.21.2 ferme toute cette classe de pannes. Six PR totalisent 44 issues fermées et traitent couche par couche la propriété des verrous, la récupération WAL, les chemins de lecture et le diagnostic, pour que la base fonctionne ou échoue de façon claire et précise — jamais en silence, et jamais en emportant la conversation avec elle.
Autour de cette campagne, les quatre jours qui ont suivi v0.21.1 ont aussi apporté une série de renforcements de l’isolation entre profiles, la fin de la tempête de démarrages de backends du desktop, un coffre de credentials que l’agent peut utiliser sans jamais voir un secret, un index de plugins revu et épinglé par SHA avec une page Plugins unifiée dans le Desktop, et un quota gratuit Nous avec un premier lancement guidé. Cette page parcourt la fenêtre dans cet ordre.
Points forts
1. La campagne de fiabilité de state.db : six PR, 44 issues fermées
Chacun des modes de panne ci-dessous a été reproduit, corrigé, et laissé sous garde pour que la même forme ne puisse pas revenir discrètement.
- Plus de seconds writers. Le gateway du profile écrivait l’état des salles gérées dans le state.db racine toutes les 5 secondes ; le dashboard ouvrait un handle inscriptible au démarrage ; la garde de cycle de vie de cron faisait un
open()brut contre une base vivante, ce qui suffit à annuler les verrous POSIX du gateway ; etdoctor --fixfaisait un checkpoint alors qu’un détenteur vivant existait encore. Aujourd’hui les salles gérées vivent dansshared-state.db, le dashboard ouvre d’abord en lecture seule, la garde passe par le registre des connexions gérées, etdoctor --fixrefuse tout checkpoint dont il ne peut pas prouver la sûreté (#108076). - Les bases WAL saines ne se bloquent plus. Une série de formes où une base qui fonctionnait était déclarée morte a disparu : un dentry
(deleted)sous OpenZFS,close()en course avecappend_message, un pool de lecture qui distribuait des connexions en mode journal non confirmé, unedisk I/O errortransitoire sous WSL2 qui faisait échouerget_sessiondès le premier essai, et un « state.db locked » encore diffusé alors que les verrous étaient libérés (#108082). - Un index de recherche corrompu ne tue plus le tour. Les erreurs qui ne touchaient que l’index plein texte étaient auparavant traitées comme une corruption du fichier entier et le système échouait en fail-closed. Elles sont désormais classées
fts_index: la recherche se dégrade, l’index est reconstruit plus tard, et le transcript reste intact. La même PR fait distinguer honnêtement àdoctorla corruption structurelle de la corruption d’index, ajoute une sonde d’écriture FTS qui attrape la forme d’index périmé où toutes les vérifications passent mais où chaque écriture échoue, empêche.recoverde ne pas démarrer à cause de tables shadow FTS5 orphelines, récupère les bases dont le header a été mis à zéro, et fait renvoyer un 503 au polling analytics du dashboard au lieu de 520 000 tracebacks par jour (#108130). - Une seule ligne défectueuse ne fait plus tomber
sessions list, l’export ou les insights. Un timestamp en TEXT ou une epoch à1e30faisaient planter toute la liste ; un marker JSON malformé faisait planterjson_extract; plus de 999 ids faisaient planter la suppression en masse et le prune. Désormais chaque lecteur passe parcoerce_epoch()— une mauvaise ligne s’affiche en?avec un WARNING qui nomme la session — ainsi que par des gardesjson_valid, des listes IN découpées et une hydratation par lots des exports (#108086). - Les sessions ne se lient plus à la base d’un autre profile, et ne la lisent plus. Le démarrage du backend du desktop pouvait épingler la
state.dbdu mauvais profile dans une course d’override de HERMES_HOME ;session_searchavec un ID brut scannait en silence tous les profiles et renvoyait les conversations d’autres personnes ; le guide de récupération pointait vers le mauvais fichier ; et supprimer un profile laissait des handles ouverts (WinError 32) (#108074). - Ouvrir state.db ne prend plus de verrou d’écriture quand il n’y a rien à écrire. Un processus
hermesponctuel qui s’ouvrait derrière un gateway occupé restait bloqué 4 à 20 secondes avant de signaler « database is locked ». Il prend maintenant 0,01 seconde (#108067).
Si votre state.db a déjà été endommagé par 0.21.0 ou 0.21.1, commencez ici :
hermes doctor
hermes sessions recover --inspect-only
2. Isolation entre profiles renforcée
v0.21.2 fait de la frontière entre profiles une convention qui est appliquée : les bots d’un profile secondaire n’héritent plus de l’allow-list du profile par défaut (#107616) ; les adaptateurs n’envoient plus de credentials vers l’hôte du profile par défaut (#107617) ; les serveurs MCP en stdio ne reçoivent plus les secrets du vault du profile par défaut (#107630) ; la livraison MEDIA: ne peut plus transporter le .env / auth.json / state.db d’un autre profile (#107609) ; les callbacks drive Feishu et les réponses du webhook /p/<profile>/ restent dans le profile routé (#107620, #107626) ; et un profile secondaire ne reçoit plus le bearer Nous d’un profile frère (#107611).
Au fond, la règle est simple : si un processus appartient à un profile, il ne peut ni atteindre les fichiers et secrets d’un autre profile, ni émettre de requêtes sous l’identité d’un autre.
3. La tempête de démarrages de backends du desktop est terminée
Bot Mode lançait ou composait un backend par profile au démarrage, puis à chaque tick du roster ; survoler la liste des Bots lançait un backend par ligne ; et changer de profile pouvait créer des primaries en double. La création et la réutilisation des backends suivent désormais un cycle de vie explicite, le rendu du roster n’a plus d’effet de bord, et changer de profile vous rend le même primary au lieu d’une nouvelle copie (#108069, #108107, #108118, #108134, #107969, #108112). Ce que vous remarquez, c’est qu’un démarrage à froid du desktop ne ressemble plus à un décollage de ventilateurs doublé d’un gateway débordé.
4. Un coffre de credentials dans lequel l’agent ne peut pas voir
L’agent peut désormais se connecter, payer et remplir des adresses depuis 1Password, Bitwarden ou le vault Hermes local sans jamais voir le secret ; les codes de double authentification viennent de secrets d’authenticator enregistrés, ou sont demandés dans votre propre UI (#106480, #107585). Les plugins git privés s’installent eux aussi avec des credentials enregistrés (#106981). Autrement dit, les secrets vont du vault directement vers le site ou le dépôt cible : l’agent orchestre, voit « terminé » ou « échec », et jamais le texte en clair.
5. Un catalogue de plugins et une page Plugins unique
Les plugins disposent maintenant d’un index revu et épinglé par SHA, avec CLI, CI d’admission, documentation et dashboard (#69446). Le Desktop gagne une page Plugins unique qui gère les plugins d’agent et de desktop au même endroit — installer, parcourir le catalogue et épingler sur un commit sans en sortir (#107212, #107314, #107321). Radio sort comme plugin SDK optionnel (#107072).
6. Quota gratuit Nous et premier lancement guidé
L’inférence et les connecteurs gratuits fonctionnent dès l’installation, avec une connexion en une commande (#105258, #105260), et /login fonctionne directement dans le chat (#105261) ; les outils de connecteurs (Gmail, Linear, Notion et d’autres) se trouvent via tool_search (#106842) ; et avec HERMES_GUEST_ONBOARDING=1 défini, le premier lancement devient un parcours guidé qui configure comptes, connecteurs et modèles avant la première conversation (#107697, #107958, #107985, #108211).
export HERMES_GUEST_ONBOARDING=1
Améliorations
v0.21.2 est une release corrective : les changements ci-dessous ne font pas la une, mais ils participent au même objectif — empêcher state.db de mentir.
- Ordre de reconstruction et de publication : une state.db nouvellement créée ne publie plus ses tables FTS avant de prendre le verrou de reconstruction (#106311).
- Générations WAL et sortie : les handles qui ont perdu une génération WAL ne font plus de checkpoint de frames périmés à la sortie (#106315, #106840), et une base qui ne peut pas être vérifiée reste intacte pendant l’initialisation du WAL (#106568).
- Quarantaine plutôt qu’ouverture destructrice : une base dont le header a été écrasé est mise en quarantaine avec son WAL au lieu d’être ouverte de façon destructrice (#106587), et les handles en quarantaine refusent VACUUM et FTS optimize (#106343, #106349).
Corrections
- Gateway et plateformes : une clé
display:nue dans config.yaml ne fait plus planter chaque tour (#106305) ; les derniers messages d’une voie en file refusés par la plateforme sont enregistrés et relivrés (#106316) ; un envoi WebSocket bloqué ne bloque plus tous les événements qui le suivent (#106581) ; le premier tour n’attend plus la sonde de la toolchain Python (#106556) ; avecbots_require_mentionactivé, les bots Telegram doivent être mentionnés avec @, ce qui casse le ping-pong entre bots (#106534) ; Matrix rend LaTeX (#106515) ; Signal rend les tableaux Markdown (#106538) ; les réponses WhatsApp conservent la citation sur les messages à vue unique (#106541) ; les réponses uniquement média rapportent SUCCESS sur toutes les plateformes (#106557). - Providers et routage :
/modelet le routage automatique auxiliaire ne peuvent plus facturer un provider que vous n’avez pas choisi (#107366) ; Hermes ne bascule jamais en silence vers un provider sans credentials (#107281) ; les modèles Bedrock Claude/Converse/Mantle survivent à/model, au fallback et à la récupération (#107621, #107658) ; les Bedrock Guardrails s’appliquent réellement (#107815) ; un 400 d’image lié au budget de patch dans Codex est retenté avec une image réduite (#106525) ; un provider primaire sans autorisation plus fallback n’oscillent plus (#106549) ; le raisonnement de replay refusé par Azure Foundry est classé et tronqué (#106718) ; un refresh OAuth MCP n’efface plus le refresh token (#106185) ; le client Anthropic n’envoie qu’un seul credential (#107978) ; DeepSeek V4.1 Flash rejoint les sélecteurs Nous Portal et OpenRouter (#107489) ; OpenAI et FAL prennent en charge GPT Image 2.5 (#105988) ; Opus 5 et Fable 5.1 rejoignent le sélecteur Anthropic natif (#106636). - Boucle d’agent et compaction : un callback périodique bloqué ne freine plus le refresh du lease (#106308) ; un
/steeren cours de tour est stocké comme sa propre ligne user (#106317, #106344) ; les refus pour limite de mémoire en inférence locale passent en backoff au lieu de compacter l’historique (#106307) ; un débordement de contexte après un streaming partiel clôt le tour (#106567) ; les continuations de longueur s’arrêtent quand le texte précédent a déjà rempli la fenêtre (#106571) ; la compaction n’expire plus en silence sur les retries aux (#106866) ; les clés demodel_thresholdspeuvent être qualifiées par provider (#108061) ; basculer entre Desktop et TUI ne reconstruit plus le system prompt, ce qui préserve le prompt cache (#105844) ; la CLI conserve un sidecarapi_contentpour que même une persistance précoce préserve le cache (#105842). - CLI, TUI et Desktop :
hermes -z --resumereprend bien la session (#106313) ; les touches étendues apportent Shift+lettre et Cmd+Shift+Z aux terminaux (#90674, #105493) ; les timeouts debrowser_exectuent tout l’arbre de processus (#106589) ; la vérification des mises à jour interroge l’API GitHub une fois par jour au lieu de lancer un git fetch toutes les 30 minutes (#107648) ;hermes updatedonne la vraie raison et ne reste plus bloqué sur le fetch (#108053) ; côté Desktop, la langue de l’UI survit à un redémarrage de mise à jour (#106476), les autorisations OAuth expirées disposent d’une reconnexion en un clic (#106965), le mode HUD réaffiche la conversation et rend toujours la fenêtre (#107491, #107423), le backend s’arrête quand son parent Desktop s’arrête (#107977), les mises à jour Windows ne signalent plus de faux échecs (#106175, #107183), WSLg rend sur les GPU Windows (#106528) et la configuration rapide par QR Telegram est portée depuis le dashboard (#107242). - Cron et Kanban : un « run now » hors de l’heure pleine n’annule plus la prochaine exécution planifiée (#106306) ; une exécution manuelle tuée ne bloque plus le prochain créneau de 5 minutes (#106733) ; une tâche passée de ponctuelle à récurrente continue de se déclencher (#106532) ; les tâches sans modèle épinglé utilisent le modèle capturé à leur création (#106499) ;
--clone-allne copie plus les tâches cron (#106478) ;kanban promoterefuse une tâche parente inachevée (#106550) ;kanban_request_reviewrefuse un reviewer profile inconnu (#106547). - Outils et mémoire : un serveur MCP stdio qui meurt en pleine appel ne rejoue plus l’appel d’outil (#106546) ; une revue d’arrière-plan uniquement composée de skills ne peut plus supprimer d’entrées de mémoire (#106310) ; les mémoires mem0 ne perdent plus les tours longs (#106542) ;
tool_searchne renvoie rien plutôt que cinq outils sans rapport qui partagent un mot (#106676) ; le sudo NOPASSWD distant ne demande plus d’approbation (#107939) ; les lectures RSS et Reddit ne sont plus activées par défaut (#105873). - Entretien : les sauvegardes de config.yaml sont regroupées dans un seul répertoire borné
backups/config/(#106388) ;hermes backupne conserve que les 3 zips les plus récents (#106455) ;hermes setup --resetsauvegarde la vraie config (#106453) ; la rétention dedebug sharesur le chemin de secours dpaste tombe à 1 jour (#106531).
Mise à jour
Les installations existantes se mettent à jour sur place :
hermes update
Installation neuve :
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
Les déploiements gérés doivent être mis à jour via leurs propres outils de déploiement, avec le nouveau tag.
Si le state.db a déjà été endommagé par 0.21.0 ou 0.21.1 : lancez d’abord hermes doctor — il distingue désormais correctement la corruption structurelle de la corruption d’index — et quand une reconstruction ne suffit pas, il vous indique hermes sessions recover --inspect-only (limité au profile).
Le diff complet est sur v2026.9.7…v2026.9.11.
← Hermes Agent Changelog