Ir al contenido

Hooks

Los Hooks proporcionan un sistema extensible basado en eventos para automatizar acciones en respuesta a comandos y eventos del agente. Los Hooks se descubren automáticamente desde los directorios y se pueden gestionar mediante comandos de CLI, de manera similar a como funcionan las habilidades en OpenClaw.

Los Hooks son pequeños scripts que se ejecutan cuando sucede algo. Hay dos tipos:

  • Hooks (esta página): se ejecutan dentro de la Gateway cuando se activan eventos del agente, como /new, /reset, /stop o eventos del ciclo de vida.
  • Webhooks: webhooks HTTP externos que permiten a otros sistemas activar trabajo en OpenClaw. Consulte Webhook Hooks o use openclaw webhooks para comandos auxiliares de Gmail.

Los Hooks también se pueden incluir en paquetes (plugins); consulte Plugins.

Usos comunes:

  • Guardar una instantánea de la memoria cuando restablezca una sesión
  • Mantener un registro de auditoría de los comandos para solucionar problemas o cumplimiento
  • Activar una automatización de seguimiento cuando una sesión inicia o termina
  • Escribir archivos en el espacio de trabajo del agente o llamar a API externas cuando se activan eventos

Si puede escribir una pequeña función de TypeScript, puede escribir un hook. Los Hooks se descubren automáticamente y se habilitan o deshabilitan a través de la CLI.

El sistema de Hooks le permite:

  • Guardar el contexto de la sesión en la memoria cuando se emite /new
  • Registrar todos los comandos para auditoría
  • Activar automatizaciones personalizadas en eventos del ciclo de vida del agente
  • Extender el comportamiento de OpenClaw sin modificar el código central

OpenClaw incluye cuatro hooks que se descubren automáticamente:

  • 💾 session-memory: Guarda el contexto de la sesión en su espacio de trabajo del agente (por defecto ~/.openclaw/workspace/memory/) cuando emite /new
  • 📝 command-logger: Registra todos los eventos de comandos en ~/.openclaw/logs/commands.log
  • 🚀 boot-md: Ejecuta BOOT.md cuando se inicia la puerta de enlace (requiere que los hooks internos estén habilitados)
  • 😈 soul-evil: Intercambia el contenido inyectado de SOUL.md con SOUL_EVIL.md durante una ventana de purga o por casualidad aleatoria

Listar los hooks disponibles:

Ventana de terminal
openclaw hooks list

Activar un hook:

Ventana de terminal
openclaw hooks enable session-memory

Verificar el estado del hook:

Ventana de terminal
openclaw hooks check

Obtener información detallada:

Ventana de terminal
openclaw hooks info session-memory

Durante la incorporación (openclaw onboard), se le solicitará que active los hooks recomendados. El asistente descubre automáticamente los hooks elegibles y los presenta para su selección.

Los hooks se descubren automáticamente desde tres directorios (en orden de prioridad):

  1. Hooks del espacio de trabajo: <workspace>/hooks/ (por agente, mayor prioridad)
  2. Hooks gestionados: ~/.openclaw/hooks/ (instalados por el usuario, compartidos entre espacios de trabajo)
  3. Hooks incluidos: <openclaw>/dist/hooks/bundled/ (enviados con OpenClaw)

Los directorios de hooks gestionados pueden ser un único hook o un paquete de hooks (directorio de paquete).

Cada hook es un directorio que contiene:

my-hook/
├── HOOK.md # Metadata + documentation
└── handler.ts # Handler implementation

Los paquetes de hooks son paquetes estándar de npm que exportan uno o más hooks a través de openclaw.hooks en package.json. Instálelos con:

Ventana de terminal
openclaw hooks install <path-or-spec>

Ejemplo de package.json:

{
"name": "@acme/my-hooks",
"version": "0.1.0",
"openclaw": {
"hooks": ["./hooks/my-hook", "./hooks/other-hook"]
}
}

Cada entrada apunta a un directorio de hooks que contiene HOOK.md y handler.ts (o index.ts). Los paquetes de hooks pueden enviar dependencias; se instalarán en ~/.openclaw/hooks/<id>.

El archivo HOOK.md contiene metadatos en el frontmatter YAML más documentación de Markdown:

---
name: my-hook
description: "Short description of what this hook does"
homepage: https://docs.openclaw.ai/hooks#my-hook
metadata: { "openclaw": { "emoji": "🔗", "events": ["command:new"], "requires": { "bins": ["node"] } } }
---
# My Hook
Detailed documentation goes here...
## What It Does
- Listens for `/new` commands
- Performs some action
- Logs the result
## Requirements
- Node.js must be installed
## Configuration
No configuration needed.

El objeto metadata.openclaw admite:

  • emoji: Emoji de visualización para la CLI (por ejemplo, "💾")
  • events: Matriz de eventos a los que escuchar (por ejemplo, ["command:new", "command:reset"])
  • export: Exportación con nombre a utilizar (por defecto es "default")
  • homepage: URL de documentación
  • requires: Requisitos opcionales
    • bins: Binarios requeridos en PATH (por ejemplo, ["git", "node"])
    • anyBins: Al menos uno de estos binarios debe estar presente
    • env: Variables de entorno requeridas
    • config: Rutas de configuración requeridas (ej., ["workspace.dir"])
    • os: Plataformas requeridas (ej., ["darwin", "linux"])
  • always: Omitir comprobaciones de elegibilidad (booleano)
  • install: Métodos de instalación (para hooks incluidos: [{"id":"bundled","kind":"bundled"}])

El archivo handler.ts exporta una función HookHandler:

import type { HookHandler } from "../../src/hooks/hooks.js";
const myHandler: HookHandler = async (event) => {
// Only trigger on 'new' command
if (event.type !== "command" || event.action !== "new") {
return;
}
console.log(`[my-hook] New command triggered`);
console.log(` Session: ${event.sessionKey}`);
console.log(` Timestamp: ${event.timestamp.toISOString()}`);
// Your custom logic here
// Optionally send message to user
event.messages.push("✨ My hook executed!");
};
export default myHandler;

Cada evento incluye:

{
type: 'command' | 'session' | 'agent' | 'gateway',
action: string, // e.g., 'new', 'reset', 'stop'
sessionKey: string, // Session identifier
timestamp: Date, // When the event occurred
messages: string[], // Push messages here to send to user
context: {
sessionEntry?: SessionEntry,
sessionId?: string,
sessionFile?: string,
commandSource?: string, // e.g., 'whatsapp', 'telegram'
senderId?: string,
workspaceDir?: string,
bootstrapFiles?: WorkspaceBootstrapFile[],
cfg?: OpenClawConfig
}
}

Activados cuando se emiten comandos del agente:

  • command: Todos los eventos de comandos (oyente general)
  • command:new: Cuando se emite el comando /new
  • command:reset: Cuando se emite el comando /reset
  • command:stop: Cuando se emite el comando /stop
  • agent:bootstrap: Antes de que se inyecten los archivos de arranque del espacio de trabajo (los hooks pueden mutar context.bootstrapFiles)

Activados cuando se inicia la pasarela:

  • gateway:startup: Después de que los canales se inician y se cargan los hooks

Hooks de resultados de herramientas (API de complementos)

Sección titulada «Hooks de resultados de herramientas (API de complementos)»

Estos hooks no son oyentes de flujo de eventos; permiten que los complementos ajusten sincrónicamente los resultados de las herramientas antes de que OpenClaw los guarde.

  • tool_result_persist: transforma los resultados de las herramientas antes de que se escriban en la transcripción de la sesión. Debe ser síncrono; devuelve la carga útil del resultado de la herramienta actualizada o undefined para mantenerla tal cual. Consulte Bucle del agente.

Tipos de eventos planificados:

  • session:start: Cuando comienza una nueva sesión
  • session:end: Cuando termina una sesión
  • agent:error: Cuando un agente encuentra un error
  • message:sent: Cuando se envía un mensaje
  • message:received: Cuando se recibe un mensaje
  • Hooks del espacio de trabajo (<workspace>/hooks/): Por agente, mayor prioridad
  • Hooks administrados (~/.openclaw/hooks/): Compartidos entre espacios de trabajo
Ventana de terminal
mkdir -p ~/.openclaw/hooks/my-hook
cd ~/.openclaw/hooks/my-hook
---
name: my-hook
description: "Does something useful"
metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } }
---
# My Custom Hook
This hook does something useful when you issue `/new`.
import type { HookHandler } from "../../src/hooks/hooks.js";
const handler: HookHandler = async (event) => {
if (event.type !== "command" || event.action !== "new") {
return;
}
console.log("[my-hook] Running!");
// Your logic here
};
export default handler;
Ventana de terminal
# Verify hook is discovered
openclaw hooks list
# Enable it
openclaw hooks enable my-hook
# Restart your gateway process (menu bar app restart on macOS, or restart your dev process)
# Trigger the event
# Send /new via your messaging channel

Nuevo Formato de Configuración (Recomendado)

Sección titulada «Nuevo Formato de Configuración (Recomendado)»
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"session-memory": { "enabled": true },
"command-logger": { "enabled": false }
}
}
}
}

Los hooks pueden tener configuración personalizada:

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

Cargar hooks desde directorios adicionales:

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

Formato de Configuración Heredado (Todavía Soportado)

Sección titulada «Formato de Configuración Heredado (Todavía Soportado)»

El formato de configuración antiguo todavía funciona por compatibilidad hacia atrás:

{
"hooks": {
"internal": {
"enabled": true,
"handlers": [
{
"event": "command:new",
"module": "./hooks/handlers/my-handler.ts",
"export": "default"
}
]
}
}
}

Migración: Utilice el nuevo sistema basado en descubrimiento para los nuevos hooks. Los controladores heredados se cargan después de los hooks basados en directorios.

Ventana de terminal
# List all hooks
openclaw hooks list
# Show only eligible hooks
openclaw hooks list --eligible
# Verbose output (show missing requirements)
openclaw hooks list --verbose
# JSON output
openclaw hooks list --json
Ventana de terminal
# Show detailed info about a hook
openclaw hooks info session-memory
# JSON output
openclaw hooks info session-memory --json
Ventana de terminal
# Show eligibility summary
openclaw hooks check
# JSON output
openclaw hooks check --json
Ventana de terminal
# Enable a hook
openclaw hooks enable session-memory
# Disable a hook
openclaw hooks disable command-logger

Guarda el contexto de la sesión en la memoria cuando emites /new.

Eventos: command:new

Requisitos: workspace.dir debe estar configurado

Salida: <workspace>/memory/YYYY-MM-DD-slug.md (por defecto es ~/.openclaw/workspace)

Lo que hace:

  1. Utiliza la entrada de sesión previa al restablecimiento para ubicar la transcripción correcta
  2. Extrae las últimas 15 líneas de la conversación
  3. Utiliza LLM para generar un nombre de archivo descriptivo (slug)
  4. Guarda los metadatos de la sesión en un archivo de memoria con fecha

Ejemplo de salida:

# Session: 2026-01-16 14:30:00 UTC
- **Session Key**: agent:main:main
- **Session ID**: abc123def456
- **Source**: telegram

Ejemplos de nombres de archivo:

  • 2026-01-16-vendor-pitch.md
  • 2026-01-16-api-design.md
  • 2026-01-16-1430.md (marca de tiempo de respaldo si falla la generación del slug)

Habilitar:

Ventana de terminal
openclaw hooks enable session-memory

Registra todos los eventos de comandos en un archivo de auditoría centralizado.

Eventos: command

Requisitos: Ninguno

Salida: ~/.openclaw/logs/commands.log

Lo que hace:

  1. Captura detalles del evento (acción de comando, marca de tiempo, clave de sesión, ID del remitente, origen)
  2. Agrega al archivo de registro en formato JSONL
  3. Se ejecuta silenciosamente en segundo plano

Ejemplos de entradas de registro:

{"timestamp":"2026-01-16T14:30:00.000Z","action":"new","sessionKey":"agent:main:main","senderId":"+1234567890","source":"telegram"}
{"timestamp":"2026-01-16T15:45:22.000Z","action":"stop","sessionKey":"agent:main:main","senderId":"[email protected]","source":"whatsapp"}

Ver registros:

Ventana de terminal
# View recent commands
tail -n 20 ~/.openclaw/logs/commands.log
# Pretty-print with jq
cat ~/.openclaw/logs/commands.log | jq .
# Filter by action
grep '"action":"new"' ~/.openclaw/logs/commands.log | jq .

Habilitar:

Ventana de terminal
openclaw hooks enable command-logger

Intercambia el contenido inyectado de SOUL.md con SOUL_EVIL.md durante una ventana de purga o por azar.

Eventos: agent:bootstrap

Documentación: SOUL Evil Hook

Salida: No se escriben archivos; los intercambios ocurren solo en memoria.

Activar:

Ventana de terminal
openclaw hooks enable soul-evil

Configuración:

{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"soul-evil": {
"enabled": true,
"file": "SOUL_EVIL.md",
"chance": 0.1,
"purge": { "at": "21:00", "duration": "15m" }
}
}
}
}
}

Ejecuta BOOT.md cuando se inicia la puerta de enlace (después de que inicien los canales). Los hooks internos deben estar habilitados para que esto se ejecute.

Eventos: gateway:startup

Requisitos: workspace.dir debe estar configurado

Lo que hace:

  1. Lee BOOT.md de su espacio de trabajo
  2. Ejecuta las instrucciones a través del agente de ejecución (agent runner)
  3. Envía cualquier mensaje saliente solicitado a través de la herramienta de mensajes

Activar:

Ventana de terminal
openclaw hooks enable boot-md

Los hooks se ejecutan durante el procesamiento de comandos. Manténgalos ligeros:

// ✓ Good - async work, returns immediately
const handler: HookHandler = async (event) => {
void processInBackground(event); // Fire and forget
};
// ✗ Bad - blocks command processing
const handler: HookHandler = async (event) => {
await slowDatabaseQuery(event);
await evenSlowerAPICall(event);
};

Siempre envuelva las operaciones riesgosas:

const handler: HookHandler = async (event) => {
try {
await riskyOperation(event);
} catch (err) {
console.error("[my-handler] Failed:", err instanceof Error ? err.message : String(err));
// Don't throw - let other handlers run
}
};

Regrese temprano si el evento no es relevante:

const handler: HookHandler = async (event) => {
// Only handle 'new' commands
if (event.type !== "command" || event.action !== "new") {
return;
}
// Your logic here
};

Especifique eventos exactos en los metadatos cuando sea posible:

metadata: { "openclaw": { "events": ["command:new"] } } # Specific

En lugar de:

metadata: { "openclaw": { "events": ["command"] } } # General - more overhead

La puerta de enlace registra la carga de hooks al inicio:

Registered hook: session-memory -> command:new
Registered hook: command-logger -> command
Registered hook: boot-md -> gateway:startup

Listar todos los hooks descubiertos:

Ventana de terminal
openclaw hooks list --verbose

En su manejador, registre cuándo se llama:

const handler: HookHandler = async (event) => {
console.log("[my-handler] Triggered:", event.type, event.action);
// Your logic
};

Verifique por qué un hook no es elegible:

Ventana de terminal
openclaw hooks info my-hook

Busque requisitos faltantes en la salida.

Monitoree los registros de la puerta de enlace para ver la ejecución del hook:

Ventana de terminal
# macOS
./scripts/clawlog.sh -f
# Other platforms
tail -f ~/.openclaw/gateway.log

Pruebe sus manejadores de forma aislada:

import { test } from "vitest";
import { createHookEvent } from "./src/hooks/hooks.js";
import myHandler from "./hooks/my-hook/handler.js";
test("my handler works", async () => {
const event = createHookEvent("command", "new", "test-session", {
foo: "bar",
});
await myHandler(event);
// Assert side effects
});
  • src/hooks/types.ts: Definiciones de tipos
  • src/hooks/workspace.ts: Escaneo y carga de directorios
  • src/hooks/frontmatter.ts: Análisis de metadatos de HOOK.md
  • src/hooks/config.ts: Verificación de elegibilidad
  • src/hooks/hooks-status.ts: Reporte de estado
  • src/hooks/loader.ts: Cargador de módulos dinámicos
  • src/cli/hooks-cli.ts: Comandos de CLI
  • src/gateway/server-startup.ts: Carga los hooks al inicio de la puerta de enlace
  • src/auto-reply/reply/commands-core.ts: Activa eventos de comandos
Gateway startup
Scan directories (workspace → managed → bundled)
Parse HOOK.md files
Check eligibility (bins, env, config, os)
Load handlers from eligible hooks
Register handlers for events
User sends /new
Command validation
Create hook event
Trigger hook (all registered handlers)
Command processing continues
Session reset
  1. Verifique la estructura del directorio:

    Ventana de terminal
    ls -la ~/.openclaw/hooks/my-hook/
    # Should show: HOOK.md, handler.ts
  2. Verifique el formato de HOOK.md:

    Ventana de terminal
    cat ~/.openclaw/hooks/my-hook/HOOK.md
    # Should have YAML frontmatter with name and metadata
  3. Listar todos los hooks descubiertos:

    Ventana de terminal
    openclaw hooks list

Verifique los requisitos:

Ventana de terminal
openclaw hooks info my-hook

Busque elementos faltantes:

  • Binarios (verificar PATH)
  • Variables de entorno
  • Valores de configuración
  • Compatibilidad con el sistema operativo
  1. Verifique que el enlace esté habilitado:

    Ventana de terminal
    openclaw hooks list
    # Should show ✓ next to enabled hooks
  2. Reinicie su proceso de puerta de enlace para que los enlaces se recarguen.

  3. Revise los registros de la puerta de enlace en busca de errores:

    Ventana de terminal
    ./scripts/clawlog.sh | grep hook

Busque errores de TypeScript/importación:

Ventana de terminal
# Test import directly
node -e "import('./path/to/handler.ts').then(console.log)"

Desde la configuración heredada hasta el descubrimiento

Sección titulada «Desde la configuración heredada hasta el descubrimiento»

Antes:

{
"hooks": {
"internal": {
"enabled": true,
"handlers": [
{
"event": "command:new",
"module": "./hooks/handlers/my-handler.ts"
}
]
}
}
}

Después:

  1. Crear directorio de enlace:

    Ventana de terminal
    mkdir -p ~/.openclaw/hooks/my-hook
    mv ./hooks/handlers/my-handler.ts ~/.openclaw/hooks/my-hook/handler.ts
  2. Crear HOOK.md:

    ---
    name: my-hook
    description: "My custom hook"
    metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } }
    ---
    # My Hook
    Does something useful.
  3. Actualizar configuración:

    {
    "hooks": {
    "internal": {
    "enabled": true,
    "entries": {
    "my-hook": { "enabled": true }
    }
    }
    }
    }
  4. Verifique y reinicie su proceso de puerta de enlace:

    Ventana de terminal
    openclaw hooks list
    # Should show: 🎯 my-hook ✓

Beneficios de la migración:

  • Descubrimiento automático
  • Gestión por CLI
  • Verificación de elegibilidad
  • Mejor documentación
  • Estructura consistente