Hermes : les plugins et leurs hooks
1. Quoi ? — Définition et contexte
Section intitulée « 1. Quoi ? — Définition et contexte »Les skills sont du texte : elles orientent le modèle. Les plugins sont du code Python : ils s’exécutent, qu’importe ce que le modèle décide.
Un plugin s’enregistre sur des hooks du cycle de vie de Hermes et peut, selon le hook, observer un événement, réécrire un message avant traitement, ou exposer de nouveaux outils à l’agent.
Les quatre plugins actifs
Section intitulée « Les quatre plugins actifs »| Plugin | Version | Apport | Auteur |
|---|---|---|---|
telegram-voice-transcriptor | 1.1.0 | Hook pre_gateway_dispatch | Sur mesure |
telegram-message-editor | 1.0.0 | Outil telegram_status_message | Sur mesure |
codex-usage-alert | 1.0.0 | Hook post_api_request | Sur mesure |
mnemosyne | 0.4.0 | 20 outils + 3 hooks | Tiers (Abdias J) |
Les hooks utilisés
Section intitulée « Les hooks utilisés »| Hook | Moment | Peut faire |
|---|---|---|
pre_gateway_dispatch | Message reçu, avant traitement | Réécrire ou rediriger l’événement |
pre_llm_call | Avant l’appel au modèle | Injecter du contexte dans le prompt |
on_session_start | Ouverture de session | Charger un état initial |
post_tool_call | Après un appel d’outil | Observer, capturer |
post_api_request | Après un appel LLM abouti | Observer, déclencher un effet de bord |
2. Pourquoi ? — Enjeux et motivations
Section intitulée « 2. Pourquoi ? — Enjeux et motivations »Pourquoi des plugins user plutôt qu’un patch du cœur ?
Section intitulée « Pourquoi des plugins user plutôt qu’un patch du cœur ? »L’arbre applicatif /opt/hermes appartient à l’image. Une modification y survit jusqu’à la prochaine mise à jour — et disparaît alors sans bruit, ce qui est la pire des fins pour une personnalisation.
Les plugins user vivent dans /opt/data/plugins/, c’est-à-dire dans le bind mount. Ils survivent aux docker compose up --force-recreate comme aux mises à jour d’image, et partent dans le backup quotidien.
C’est la même règle que le mode wrapper de Mnemosyne : tout ce qui doit durer vit dans le volume, jamais dans l’image.
Plugin ou outil MCP ?
Section intitulée « Plugin ou outil MCP ? »Les deux ajoutent des capacités, mais pas au même endroit ni au même prix.
| Outil MCP N8N | Plugin | |
|---|---|---|
| Où | Un node dans un workflow | Du Python dans le conteneur |
| Accès | Ce que N8N peut atteindre | Le runtime de Hermes lui-même |
| Modification | Éditer le workflow, redémarrer le conteneur | Éditer le fichier, redémarrer le conteneur |
| Peut réagir à un événement | Non — seulement être appelé | Oui, via les hooks |
La ligne de partage est simple : une action métier devient un outil MCP ; un comportement qui doit se déclencher sans que l’agent le décide devient un plugin.
3. Comment ? — Mise en œuvre technique
Section intitulée « 3. Comment ? — Mise en œuvre technique »telegram-voice-transcriptor
Section intitulée « telegram-voice-transcriptor »Sur un vocal Telegram, le plugin réécrit l’événement pour y injecter le bloc de la skill transcriptor-fr-voice. Le pipeline STT préfixe ensuite le transcript en citation, et l’agent répond avec le texte français nettoyé.
Son intérêt tient moins à ce qu’il fait qu’à ce sur quoi il refuse de se déclencher.
Le hook est aussi fail-open : toute exception est journalisée en avertissement et le message part en traitement normal. Une skill cassée ou un import raté ne doit jamais avaler un message vocal.
telegram-message-editor
Section intitulée « telegram-message-editor »Ce plugin expose un outil, telegram_status_message, avec deux actions : create envoie un message et retourne son message_id, update édite ce même message en place. Plafond 4096 caractères, et par défaut la conversation courante quand l’appel vient de Telegram.
Le problème qu’il résout est un problème d’ergonomie. Un agent qui travaille plusieurs minutes sur une tâche en plusieurs étapes a le choix entre se taire — et laisser croire qu’il est bloqué — ou envoyer un message par étape, et noyer la conversation. L’édition en place donne un troisième choix : un tableau de bord unique qui se met à jour.
codex-usage-alert
Section intitulée « codex-usage-alert »Hermes partage l’abonnement ChatGPT avec CLI Ollama et les workflows N8N. Atteindre le plafond hebdomadaire ne produit aucun signal avant que le bot ne se mette à répondre par des erreurs.
Le plugin s’enregistre sur post_api_request, ne réagit qu’aux appels du provider openai-codex, et alerte quand la consommation du compte franchit un seuil (90 % par défaut).
Ses quatre garde-fous méritent d’être notés, parce qu’ils sont ce qui distingue un plugin d’observation acceptable d’un plugin qui dégrade le service :
| Garde-fou | Mise en œuvre |
|---|---|
| Non bloquant | Le hook démarre au plus un thread démon court et rend la main immédiatement |
| Charge maîtrisée | Un cooldown de 300 s évite de rappeler le backend à chaque message d’une conversation active |
| Anti-spam | Une alerte par combinaison seuil + fenêtre de quota + heure de reset, avec un historique borné à 200 clés |
| Fail-open | Toute erreur est journalisée et n’affecte jamais la réponse de Hermes |
Le principe commun : un plugin greffé sur un chemin chaud ne doit jamais être ce qui casse ou ralentit la réponse.
mnemosyne
Section intitulée « mnemosyne »Le seul plugin tiers du lot, et de loin le plus gros : 20 outils et 3 hooks (pre_llm_call, on_session_start, post_tool_call). Il est installé en mode wrapper et fait l’objet d’un article dédié.
Sa présence dans cette liste dit quelque chose du système d’extension : la mémoire longue, qui est sans doute la fonctionnalité la plus structurante de l’agent, s’installe par le même mécanisme qu’une alerte de quota.
Déploiement
Section intitulée « Déploiement »Un plugin est un répertoire avec un plugin.yaml et un __init__.py qui expose register(ctx).
def register(ctx) -> None: ctx.register_hook("post_api_request", _on_post_api_request)name: codex-usage-alertversion: 1.0.0description: "Non-blocking Telegram Home alert when OpenAI Codex account usage crosses a threshold."author: Guillaume PARRAT + Hermes Agentprovides_hooks: - post_api_requestSeul telegram-voice-transcriptor a une source versionnée dans le dépôt ; le déploiement se fait par copie puis redémarrage :
cp -r ai-stack/hermes/plugins/telegram-voice-transcriptor ai-stack/hermes/data/plugins/docker compose -f ai-stack/docker-compose.yaml restart hermesdocker exec hermes hermes plugins list # statut attendu : enabled4. Et si ? — Perspectives et limites
Section intitulée « 4. Et si ? — Perspectives et limites »Limites actuelles
Section intitulée « Limites actuelles »| Limite | Impact | Mitigation |
|---|---|---|
| Trois plugins sur quatre non versionnés | Seul le transcripteur a une source dans le dépôt ; les autres n’existent qu’en production | Sauvegarde quotidienne ; portage vers le dépôt à faire |
| Redémarrage obligatoire | Toute modification impose un restart du conteneur | Regrouper les changements |
| Pas de test automatisé | Un plugin cassé se découvre à l’usage | Le fail-open limite les dégâts à une fonctionnalité perdue |
| Hooks non versionnés côté amont | Un changement de signature amont casse un plugin | hermes plugins list après chaque mise à jour d’image |
| Pas d’isolation | Un plugin s’exécute dans le processus du gateway | Discipline : non bloquant et fail-open par défaut |
Scénarios d’évolution
Section intitulée « Scénarios d’évolution »Si les plugins doivent être versionnés :
ai-stack/hermes/plugins/existe déjà et contient le transcripteur — les trois autres suivent le même patron.- Bénéfice principal : pouvoir revenir en arrière après une mise à jour amont qui casse un hook.
Si un plugin doit devenir bloquant :
- Le cas typique serait une vraie chaîne d’approbation avant les actions sensibles, plutôt que la règle de system prompt actuelle.
- Un hook
pre_tool_callconviendrait — mais un plugin bloquant sur le chemin chaud demande un timeout et un comportement de repli explicites, sinon une panne du plugin gèle l’agent.
Si l’observabilité doit progresser :
post_api_requestetpost_tool_callsont les points naturels pour exporter des métriques.- Un plugin qui pousserait un compteur vers Prometheus donnerait à Hermes la même visibilité que le reste des stacks dans Grafana.
Pages liées
Section intitulée « Pages liées »- Hermes Agent — Le déploiement et l’activation des plugins
- Mémoire Mnemosyne — Le plus gros plugin du lot
- Skills —
hermes-user-pluginsethermes-runtime-plugins, l’outillage d’écriture - Outils MCP — L’autre façon d’ajouter une capacité
Workflows
Section intitulée « Workflows »- Codex CLI Integration — L’édition en place, version N8N
- Voice Transcription — L’autre chemin de transcription
Infrastructure
Section intitulée « Infrastructure »- Backup des bases de données — Les plugins déployés sont sauvegardés