Aller au contenu

Hooks

Les Hooks sont de petits scripts qui s’exécutent lorsque quelque chose se produit à l’intérieur du Gateway. Ils peuvent être découverts à partir de répertoires et inspectés avec openclaw hooks. Le Gateway ne charge les hooks internes qu’après avoir activé les hooks ou configuré au moins une entrée de hook, un pack de hooks, un gestionnaire hérité ou un répertoire de hooks supplémentaire.

Il existe deux types de hooks dans OpenClaw :

  • Hooks internes (cette page) : s’exécutent à l’intérieur du Gateway lorsque des événements d’agent se déclenchent, comme /new, /reset, /stop, ou des événements de cycle de vie.
  • Webhooks : points de terminaison HTTP externes qui permettent à d’autres systèmes de déclencher des travaux dans OpenClaw. Voir Webhooks.

Les hooks peuvent également être regroupés dans des plugins. openclaw hooks list montre à la fois les hooks autonomes et les hooks gérés par des plugins.

Fenêtre de terminal
# List available hooks
openclaw hooks list
# Enable a hook
openclaw hooks enable session-memory
# Check hook status
openclaw hooks check
# Get detailed information
openclaw hooks info session-memory
EventWhen it fires
command:newcommande /new émise
command:resetcommande /reset émise
command:stopcommande /stop émise
commandTout événement de commande (écouteur général)
session:compact:beforeAvant que la compaction ne résume l’historique
session:compact:afterAprès la fin de la compaction
session:patchLorsque les propriétés de session sont modifiées
agent:bootstrapAvant l’injection des fichiers d’amorçage de l’espace de travail
gateway:startupAprès le démarrage des canaux et le chargement des hooks
gateway:shutdownLorsque l’arrêt de la passerelle commence
gateway:pre-restartAvant un redémarrage prévu de la passerelle
message:receivedMessage entrant de n’importe quel canal
message:transcribedAprès la fin de la transcription audio
message:preprocessedAprès la fin ou l’ignorance du prétraitement des médias et des liens
message:sentMessage sortant délivré

Chaque hook est un répertoire contenant deux fichiers :

my-hook/
├── HOOK.md # Metadata + documentation
└── handler.ts # Handler implementation
---
name: my-hook
description: "Short description of what this hook does"
metadata: { "openclaw": { "emoji": "🔗", "events": ["command:new"], "requires": { "bins": ["node"] } } }
---
# My Hook
Detailed documentation goes here.

Champs de métadonnées (metadata.openclaw) :

FieldDescription
emojiAfficher l’emoji pour la CLI
eventsTableau des événements à écouter
exportExport nommé à utiliser (par défaut "default")
osPlateformes requises (par ex., ["darwin", "linux"])
requiresChemins bins, anyBins, env ou config requis
alwaysContourner les vérifications d’éligibilité (booléen)
installMéthodes d’installation
const handler = async (event) => {
if (event.type !== "command" || event.action !== "new") {
return;
}
console.log(`[my-hook] New command triggered`);
// Your logic here
// Optionally send message to user
event.messages.push("Hook executed!");
};
export default handler;

Chaque événement comprend : type, action, sessionKey, timestamp, messages (push pour envoyer à l’utilisateur) et context (données spécifiques à l’événement). Les contextes de hook des plugins d’agent et d’outil peuvent également inclure trace, un contexte de trace de diagnostic compatible W3C en lecture seule que les plugins peuvent transmettre aux journaux structurés pour la corrélation OTEL.

Événements de commande (command:new, command:reset) : context.sessionEntry, context.previousSessionEntry, context.commandSource, context.workspaceDir, context.cfg.

Événements de message (message:received) : context.from, context.content, context.channelId, context.metadata (données spécifiques au fournisseur incluant senderId, senderName, guildId). context.content préfère un corps de commande non vide pour les messages de type commande, puis revient au corps entrant brut et au corps générique ; il n’inclut pas l’enrichissement réservé à l’agent tel que l’historique des fils ou les résumés de liens.

Événements de message (message:sent) : context.to, context.content, context.success, context.channelId.

Événements de message (message:transcribed) : context.transcript, context.from, context.channelId, context.mediaPath.

Événements de message (message:preprocessed) : context.bodyForAgent (corps final enrichi), context.from, context.channelId.

Événements d’amorçage (agent:bootstrap) : context.bootstrapFiles (tableau modifiable), context.agentId.

Événements de correctif de session (session:patch) : context.sessionEntry, context.patch (uniquement les champs modifiés), context.cfg. Seuls les clients privilégiés peuvent déclencher des événements de correctif.

Événements de compactage : session:compact:before inclut messageCount, tokenCount. session:compact:after ajoute compactedCount, summaryLength, tokensBefore, tokensAfter.

command:stop observe l’utilisateur émettant /stop ; il s’agit du cycle de vie d’annulation/de commande, et non d’une porte de finalisation de l’agent. Les plugins qui doivent inspecter une réponse finale naturelle et demander à l’agent de faire un autre passage doivent plutôt utiliser le hook de plugin typé before_agent_finalize. Voir Plugin hooks.

Événements de cycle de vie du Gateway : gateway:shutdown inclut reason et restartExpectedMs et se déclenche lorsque l’arrêt de la passerelle commence. gateway:pre-restart inclut le même contexte mais se déclenche uniquement lorsque l’arrêt fait partie d’un redémarrage attendu et qu’une valeur finie restartExpectedMs est fournie. Pendant l’arrêt, chaque attente de hook de cycle de vie est de type « meilleur effort » et bornée, de sorte que l’arrêt se poursuit si un gestionnaire stagne. Le budget d’attente par défaut est de 5 secondes pour gateway:shutdown et de 10 secondes pour gateway:pre-restart.

Utilisez gateway:pre-restart pour de courtes notifications de redémarrage tant que les canaux sont encore disponibles :

import { execFile } from "node:child_process";
import { promisify } from "node:util";
const execFileAsync = promisify(execFile);
export default async function handler(event) {
if (event.type !== "gateway" || event.action !== "pre-restart") {
return;
}
const restartInSeconds = Math.ceil(event.context.restartExpectedMs / 1000);
await execFileAsync("openclaw", ["system", "event", "--mode", "now", "--text", `Gateway restarting in ~${restartInSeconds}s (${event.context.reason}). Checkpoint now.`]);
}

Entre l’événement gateway:shutdown (ou gateway:pre-restart) et le reste de la séquence d’arrêt, la Gateway déclenche également un hook de plugin typé session_end pour chaque session qui était encore active lorsque le processus s’est arrêté. Le reason de l’événement est shutdown pour un arrêt SIGTERM/SIGINT simple et restart lorsque la fermeture a été planifiée dans le cadre d’un redémarrage prévu. Ce drainage est limité, de sorte qu’un gestionnaire session_end lent ne peut pas bloquer la sortie du processus, et les sessions qui ont déjà été finalisées via replace / reset / delete / compaction sont ignorées pour éviter les déclenchements doubles.

Les hooks sont découverts à partir de ces répertoires, par ordre de priorité de remplacement croissante :

  1. Hooks intégrés : fournis avec OpenClaw
  2. Hooks de plugin : hooks groupés dans les plugins installés
  3. Hooks gérés : ~/.openclaw/hooks/ (installés par l’utilisateur, partagés entre les espaces de travail). Les répertoires supplémentaires de hooks.internal.load.extraDirs partagent cette priorité.
  4. Hooks de l’espace de travail : <workspace>/hooks/ (par agent, désactivés par défaut jusqu’à ce qu’ils soient explicitement activés)

Les hooks de l’espace de travail peuvent ajouter de nouveaux noms de hooks mais ne peuvent pas remplacer les hooks intégrés, gérés ou fournis par le plugin portant le même nom.

La Gateway ignore la découverte de hooks internes au démarrage jusqu’à ce que les hooks internes soient configurés. Activez un hook intégré ou géré avec openclaw hooks enable <name>, installez un pack de hooks ou définissez hooks.internal.enabled=true pour opter. Lorsque vous activez un hook nommé, la Gateway ne charge que le gestionnaire de ce hook ; hooks.internal.enabled=true, les répertoires de hooks supplémentaires et les gestionnaires hérités optent pour une découverte large.

Les packs de hooks sont des packages npm qui exportent des hooks via openclaw.hooks dans package.json. Installez avec :

Fenêtre de terminal
openclaw plugins install <path-or-spec>

Les spécifications Npm sont limitées au registre (nom du package + version exacte facultative ou dist-tag). Les spécifications Git/URL/fichier et les plages semver sont rejetées.

HookÉvénementsCe qu’il fait
session-memorycommand:new, command:resetEnregistre le contexte de la session dans <workspace>/memory/
bootstrap-extra-filesagent:bootstrapInjecte des fichiers d’amorçage supplémentaires à partir de motifs glob
command-loggercommandEnregistre toutes les commandes dans ~/.openclaw/logs/commands.log
compaction-notifiersession:compact:before, session:compact:afterEnvoie des avis de chat visibles lorsque la compaction de session commence/se termine
boot-mdgateway:startupExécute BOOT.md lorsque la passerelle démarre

Activer n’importe quel hook intégré :

Fenêtre de terminal
openclaw hooks enable <hook-name>

Extrait les 15 derniers messages utilisateur/assistant et les enregistre dans <workspace>/memory/YYYY-MM-DD-HHMM.md en utilisant la date locale de l’hôte. La capture de mémoire s’exécute en arrière-plan, de sorte que les accusés de réception /new et /reset ne sont pas retardés par les lectures de transcription ou la génération optionnelle de slugs. Définissez hooks.internal.entries.session-memory.llmSlug: true pour générer des slugs de noms de fichiers descriptifs avec le model configuré. Nécessite workspace.dir d’être configuré.

{
"hooks": {
"internal": {
"entries": {
"bootstrap-extra-files": {
"enabled": true,
"paths": ["packages/*/AGENTS.md", "packages/*/TOOLS.md"]
}
}
}
}
}

Les chemins sont résolus par rapport à l’espace de travail. Seuls les noms de base d’amorçage reconnus sont chargés (AGENTS.md, SOUL.md, TOOLS.md, IDENTITY.md, USER.md, HEARTBEAT.md, BOOTSTRAP.md, MEMORY.md).

Enregistre chaque commande slash dans ~/.openclaw/logs/commands.log.

Envoie de courts messages d’état dans la conversation en cours lorsque OpenClaw commence et termine la compactage de la transcription de session. Cela rend les tours longs moins confus sur les interfaces de chat car l’utilisateur peut voir que l’assistant résume le contexte et continuera après la compactage.

Exécute BOOT.md depuis l’espace de travail actif lorsque la passerelle démarre.

Les plugins peuvent enregistrer des hooks typés via le Plugin SDK pour une intégration plus approfondie : intercepter les appels d’outils, modifier les invites, contrôler le flux des messages, et plus encore. Utilisez les hooks de plugin lorsque vous avez besoin de before_tool_call, before_agent_reply, before_install, ou d’autres hooks de cycle de vie en cours de processus.

Pour la référence complète des hooks de plugin, consultez Plugin hooks.

{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"session-memory": { "enabled": true },
"command-logger": { "enabled": false }
}
}
}
}

Variables d’environnement par hook :

{
"hooks": {
"internal": {
"entries": {
"my-hook": {
"enabled": true,
"env": { "MY_CUSTOM_VAR": "value" }
}
}
}
}
}

Répertoires de hooks supplémentaires :

{
"hooks": {
"internal": {
"load": {
"extraDirs": ["/path/to/more/hooks"]
}
}
}
}

Fenêtre de terminal
# List all hooks (add --eligible, --verbose, or --json)
openclaw hooks list
# Show detailed info about a hook
openclaw hooks info <hook-name>
# Show eligibility summary
openclaw hooks check
# Enable/disable
openclaw hooks enable <hook-name>
openclaw hooks disable <hook-name>
  • Gardez les gestionnaires rapides. Les hooks s’exécutent pendant le traitement des commandes. Effectuez les tâches lourdes de façon asynchrone avec void processInBackground(event).
  • Gérez les erreurs avec élégance. Enveloppez les opérations risquées dans des blocs try/catch ; ne lancez pas d’exceptions pour permettre aux autres gestionnaires de s’exécuter.
  • Filtrez les événements tôt. Retournez immédiatement si le type/action de l’événement n’est pas pertinent.
  • Utilisez des clés d’événement spécifiques. Préférez "events": ["command:new"] à "events": ["command"] pour réduire la charge.
Fenêtre de terminal
# Verify directory structure
ls -la ~/.openclaw/hooks/my-hook/
# Should show: HOOK.md, handler.ts
# List all discovered hooks
openclaw hooks list
Fenêtre de terminal
openclaw hooks info my-hook

Vérifiez la présence de binaires manquants (PATH), de variables d’environnement, de valeurs de configuration ou de compatibilité OS.

  1. Vérifiez que le hook est activé : openclaw hooks list
  2. Redémarrez votre processus passerelle pour que les hooks se rechargent.
  3. Consultez les journaux de la passerelle : ./scripts/clawlog.sh | grep hook