Hermes v0.21.3 : votre session Desktop ne se déconnecte plus après une veille

Vous fermez le portable pour rejoindre un appel, vous revenez, et le Desktop Hermes se charge normalement — puis vous demande de vous reconnecter. Personne n’a éjecté votre compte : c’est votre propre client qui a invalidé la session. Cela arrive le plus souvent quand vous utilisez un gateway distant et le Desktop ensemble, et ça tombe toujours au moment où vous avez le moins envie de vous en occuper.
v0.21.3 (tag v2026.9.14, publié le 14 septembre 2026, surnommé « The Sign-In Patch ») existe pour cette panne. C’est aussi un canal de mise à jour pour les utilisateurs du cloud : les images Docker et Hermes Cloud se construisent à partir du tag de release le plus récent, donc une correction doit être intégrée dans un tag stable avant de pouvoir atteindre les installations qui ne lancent jamais hermes update à la main.
Pourquoi une rafale de réveil peut invalider toute une session
Commençons par les pièces. Pour l’accès distant, un client détient une paire de tokens : un access token (courte durée de vie, utilisé pour les requêtes) et un refresh token (longue durée de vie, utilisé pour obtenir de nouveaux access tokens). Pour limiter les dégâts d’une fuite, le serveur d’autorisation fait tourner le refresh token à chaque usage — l’ancienne valeur meurt immédiatement et seule la nouvelle compte. Si l’ancienne valeur est présentée une seconde fois, le serveur la lit comme un token volé, et la réponse protectrice consiste à révoquer toute la session.
Le problème, c’est qu’il existe deux chemins de refresh : la porte par cookie du gateway et la route bearer native du Desktop. Les deux détiennent le même refresh token rotatif. Quand le Desktop se réveille d’une veille, il déclenche plusieurs requêtes d’un coup — une rafale naturelle — et les deux chemins rafraîchissent presque simultanément : la même ancienne valeur est donc présentée deux fois, et la session est déconnectée par son propre client (#110061, corrige #55712).
Le correctif fusionne ces refresh : quand des requêtes concurrentes portent le même token rotatif, une seule effectue la rotation et les autres adoptent son résultat au lieu de présenter le token à nouveau. Le refresh a aussi été sorti de l’event loop, donc un provider d’identité lent ne fige plus /api/status pendant l’attente.
Côté Portal, la contrepartie (hermes-portal#1209) : un horizon d’inactivité glissant de 30 jours, plus une fenêtre de grâce de 5 minutes sur un token tourné, afin qu’une requête réellement en vol avec la valeur tout juste tournée ne soit pas lue comme une réutilisation.
La correction plus discrète : les handles writer state.db en double
La même fenêtre contient une autre correction du stockage des sessions, celle-ci cachée dans les logs. Si vous avez déjà vu un avertissement N live SessionDB handles pendant un diagnostic, il était censé signifier « plus d’un processus écrit dans cette base » — mais il se déclenchait aussi sur des topologies saines (#110934, corrige #100896 et #103339).
Le gateway, le backend du dashboard/Desktop, la surface ACP et les lecteurs CLI attachaient chacun leur propre handle writer. La règle est désormais explicite : les lecteurs s’attachent en lecture seule, et les writers en cours de processus partagent l’unique handle du registre. Moins de handles, c’est moins d’occasions pour un composant d’annuler les verrous d’un autre — exactement la classe de panne que le patch v0.21.2 a refermée avec six PR, et celle décrite dans notre article de dépannage sur state.db.
Quoi d’autre dans v0.21.3 (documenté correctement dans v0.22.0)
v0.21.3 est un tag roulant : les ~338 PR fusionnées, 1 036 commits hors merge et 2 642 fichiers modifiés depuis v0.21.2 tiennent tous dans cette fenêtre. L’essentiel est volontairement laissé aux notes de v0.22.0, donc voici la forme de ce qui arrive, par domaine :
| Domaine | Ce qui est arrivé |
|---|---|
| Contrat du gateway | Des requêtes JSON-RPC serveur→client remplacent les paires d’événements *.request / *.respond (#110521) ; un registre de « wire contracts » Pydantic génère les types TypeScript et OpenRPC (#110522, #110523) |
| Modèles et raisonnement | L’effort de raisonnement sur chaque sélecteur de modèle ; une pastille dans le composer et un contrôle d’effort par auxiliaire dans le Desktop ; connexion OpenRouter OAuth PKCE |
| MCP | Les refresh tokens OAuth liés à l’émetteur qui les a accordés ; un rappel de ré-authentification quotidien dans le Desktop |
| Médias | Décodage des images HEIF / HEIC / AVIF |
| Providers | Wan 3.0, Kling 3.0 / Kling Image v3, MiniMax H3 Max Turbo, Gemini Omni Flash 1.1 et Meta Muse dans les catalogues FAL ; la configuration des modèles pairs Honcho retravaillée |
| Plateformes | Les tableaux collés dans Slack et l’API Agent Sessions |
| Stockage et profiles | Isolation des profiles multiplexés et corrections de vivacité du gateway ; un refus d’exécuter le mode journal WAL sur des systèmes de fichiers inter-VM |
La liste bloc par bloc se trouve sur la page de release v0.21.3, et le diff de la fenêtre est sur v2026.9.11…v2026.9.14.
Ce que vous devez faire
Les installations manuelles se mettent à jour en une commande :
hermes update
Docker et les environnements hébergés se reconstruisent à partir du nouveau tag :
docker pull nousresearch/hermes-agent:v2026.9.14
Si vos sessions mouraient après le réveil du Desktop, cette mise à jour vaut la peine d’être prise en premier. Si ce n’est jamais arrivé, votre usage a simplement manqué la fenêtre concurrente — la mise à jour est tout aussi sûre.