Os ganchos de Plugin são pontos de extensão em processo para Plugins do OpenClaw. Use-os quando um Plugin precisar inspecionar ou alterar execuções de agentes, chamadas de ferramentas, fluxo de mensagens, ciclo de vida de sessão, roteamento de subagentes, instalações ou inicialização do Gateway. Use ganchos internos em vez disso quando quiser um pequeno scriptDocumentation Index
Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
HOOK.md instalado pelo operador para eventos de comando e Gateway, como
/new, /reset, /stop, agent:bootstrap ou gateway:startup.
Início rápido
Registre ganchos de Plugin tipados comapi.on(...) a partir da entrada do seu Plugin:
priority decrescente. Ganchos com a mesma prioridade
mantêm a ordem de registro.
api.on(name, handler, opts?) aceita:
priority- ordenação dos manipuladores (valores mais altos são executados primeiro).timeoutMs- orçamento opcional por gancho. Quando definido, o executor de ganchos aborta esse manipulador após o orçamento transcorrer e continua com o próximo, em vez de permitir que configuração lenta ou trabalho de recuperação consuma o tempo limite de modelo configurado pelo chamador. Omita para usar o tempo limite padrão de observação/decisão que o executor de ganchos aplica genericamente.
hooks.timeouts.<hookName> substitui hooks.timeoutMs, que substitui o valor
api.on(..., { timeoutMs }) criado pelo autor do Plugin. Cada valor configurado deve
ser um inteiro positivo não maior que 600000 milissegundos. Prefira substituições por gancho
para ganchos conhecidos por serem lentos, para que um Plugin não receba um orçamento maior
em todos os lugares.
Cada gancho recebe event.context.pluginConfig, a configuração resolvida para o
Plugin que registrou esse manipulador. Use-a para decisões de gancho que precisam das
opções atuais do Plugin; o OpenClaw a injeta por manipulador sem mutar o
objeto de evento compartilhado visto por outros Plugins.
Catálogo de ganchos
Os ganchos são agrupados pela superfície que estendem. Nomes em negrito aceitam um resultado de decisão (bloquear, cancelar, substituir ou exigir aprovação); todos os outros são apenas de observação. Turno do agentebefore_model_resolve- substitui provedor ou modelo antes que as mensagens de sessão sejam carregadasagent_turn_prepare- consome injeções de turno de Plugin enfileiradas e adiciona contexto no mesmo turno antes dos ganchos de promptbefore_prompt_build- adiciona contexto dinâmico ou texto de prompt do sistema antes da chamada ao modelobefore_agent_start- fase combinada apenas para compatibilidade; prefira os dois ganchos acimabefore_agent_run- inspeciona o prompt final e as mensagens de sessão antes do envio ao modelo e, opcionalmente, bloqueia a execuçãobefore_agent_reply- interrompe o turno do modelo com uma resposta sintética ou silênciobefore_agent_finalize- inspeciona a resposta final natural e solicita mais uma passagem do modeloagent_end- observa mensagens finais, estado de sucesso e duração da execuçãoheartbeat_prompt_contribution- adiciona contexto somente de Heartbeat para monitor em segundo plano e Plugins de ciclo de vida
model_call_started/model_call_ended- observa metadados sanitizados de chamada de provedor/modelo, temporização, resultado e hashes limitados de ID de solicitação sem conteúdo de prompt ou respostallm_input- observa a entrada do provedor (prompt do sistema, prompt, histórico)llm_output- observa a saída do provedor
before_tool_call- reescreve parâmetros de ferramenta, bloqueia a execução ou exige aprovaçãoafter_tool_call- observa resultados de ferramenta, erros e duraçãotool_result_persist- reescreve a mensagem do assistente produzida a partir de um resultado de ferramentabefore_message_write- inspeciona ou bloqueia uma escrita de mensagem em andamento (raro)
inbound_claim- reivindica uma mensagem de entrada antes do roteamento do agente (respostas sintéticas)message_received- observa conteúdo de entrada, remetente, thread e metadadosmessage_sending- reescreve conteúdo de saída ou cancela a entregamessage_sent- observa sucesso ou falha de entrega de saídabefore_dispatch- inspeciona ou reescreve um despacho de saída antes da transferência ao canalreply_dispatch- participa do pipeline final de despacho de resposta
session_start/session_end- rastreia limites do ciclo de vida da sessão. Oreasondo evento é um denew,reset,idle,daily,compaction,deleted,shutdown,restartouunknown. Os valoresshutdownerestartdisparam a partir do finalizador de desligamento do Gateway quando o processo é parado ou reiniciado enquanto sessões ainda estão ativas, para que Plugins downstream (como memória ou armazenamentos de transcrições) possam finalizar linhas fantasma que, de outra forma, permaneceriam em estado aberto entre reinicializações. O finalizador é limitado para que um Plugin lento não possa bloquear SIGTERM/SIGINT.before_compaction/after_compaction- observa ou anota ciclos de Compactionbefore_reset- observa eventos de redefinição de sessão (/reset, redefinições programáticas)
subagent_spawning/subagent_delivery_target/subagent_spawned/subagent_ended- coordena roteamento de subagentes e entrega de conclusão
gateway_start/gateway_stop- inicia ou para serviços pertencentes ao Plugin com o Gatewaycron_changed- observa alterações de ciclo de vida de Cron pertencente ao Gateway (adicionado, atualizado, removido, iniciado, concluído, agendado)before_install- inspeciona varreduras de instalação de skill ou Plugin e, opcionalmente, bloqueia
Política de chamada de ferramenta
before_tool_call recebe:
event.toolNameevent.paramsevent.derivedPathsopcional, contendo dicas de caminho de destino derivadas do host em regime de melhor esforço para envelopes de ferramentas conhecidos, comoapply_patch; quando presentes, esses caminhos podem estar incompletos ou podem superestimar o que a ferramenta realmente tocará (por exemplo, com entradas malformadas ou parciais)event.runIdopcionalevent.toolCallIdopcional- campos de contexto como
ctx.agentId,ctx.sessionKey,ctx.sessionId,ctx.runId,ctx.jobId(definido em execuções acionadas por Cron) ectx.tracede diagnóstico
block: trueé terminal e pula manipuladores de prioridade mais baixa.block: falseé tratado como ausência de decisão.paramsreescreve os parâmetros da ferramenta para execução.requireApprovalpausa a execução do agente e pergunta ao usuário por meio de aprovações de Plugin. O comando/approvepode aprovar aprovações de exec e de Plugin.- Um
block: truede prioridade mais baixa ainda pode bloquear depois que um gancho de prioridade mais alta solicitou aprovação. onResolutionrecebe a decisão de aprovação resolvida -allow-once,allow-always,deny,timeoutoucancelled.
api.registerTrustedToolPolicy(...). Elas são executadas antes dos ganchos
before_tool_call comuns e antes de decisões de Plugins externos. Use-as somente
para barreiras confiáveis pelo host, como política de espaço de trabalho, aplicação de orçamento ou
segurança de fluxos de trabalho reservados. Plugins externos devem usar ganchos before_tool_call
normais.
Persistência de resultado de ferramenta
Resultados de ferramenta podem incluirdetails estruturados para renderização da UI, diagnósticos,
roteamento de mídia ou metadados pertencentes ao Plugin. Trate details como metadados de runtime,
não como conteúdo de prompt:
- O OpenClaw remove
toolResult.detailsantes de repetição pelo provedor e entrada de Compaction para que metadados não se tornem contexto do modelo. - Entradas de sessão persistidas mantêm apenas
detailslimitados. Detalhes grandes demais são substituídos por um resumo compacto epersistedDetailsTruncated: true. tool_result_persistebefore_message_writesão executados antes do limite final de persistência. Ganchos ainda devem manter osdetailsretornados pequenos e evitar colocar texto relevante para prompt apenas emdetails; coloque a saída de ferramenta visível ao modelo emcontent.
Ganchos de prompt e modelo
Use os ganchos específicos de fase para novos Plugins:before_model_resolve: recebe apenas o prompt atual e metadados de anexos. RetorneproviderOverrideoumodelOverride.agent_turn_prepare: recebe o prompt atual, mensagens de sessão preparadas e quaisquer injeções enfileiradas exatamente uma vez drenadas para esta sessão. RetorneprependContextouappendContext.before_prompt_build: recebe o prompt atual e mensagens de sessão. RetorneprependContext,appendContext,systemPrompt,prependSystemContextouappendSystemContext.heartbeat_prompt_contribution: é executado somente para turnos de Heartbeat e retornaprependContextouappendContext. Ele é destinado a monitores em segundo plano que precisam resumir o estado atual sem alterar turnos iniciados pelo usuário.
before_agent_start permanece para compatibilidade. Prefira os ganchos explícitos acima
para que seu Plugin não dependa de uma fase combinada legada.
before_agent_run é executado após a construção do prompt e antes de qualquer entrada do modelo,
incluindo carregamento de imagens locais ao prompt e observação de llm_input. Ele recebe
a entrada atual do usuário como prompt, além do histórico de sessão carregado em messages
e o prompt do sistema ativo. Retorne { outcome: "block", reason, message? }
para parar a execução antes que o modelo possa ler o prompt. reason é interno;
message é a substituição exibida ao usuário. Os únicos resultados suportados são
pass e block; formatos de decisão não suportados falham fechados.
Quando uma execução é bloqueada, o OpenClaw armazena apenas o texto de substituição em
message.content, além de metadados de bloqueio não sensíveis, como o ID do Plugin bloqueador
e o timestamp. O texto original do usuário não é retido na transcrição nem no contexto futuro.
Motivos internos de bloqueio são tratados como sensíveis e excluídos de
transcrição, histórico, broadcast, log e cargas de diagnóstico. A observabilidade
deve usar campos sanitizados, como ID do bloqueador, resultado, timestamp ou uma categoria
segura.
before_agent_start e agent_end incluem event.runId quando o OpenClaw consegue
identificar a execução ativa. O mesmo valor também fica disponível em ctx.runId.
Execuções acionadas por Cron também expõem ctx.jobId (o ID do job de Cron de origem) para que
ganchos de Plugin possam delimitar métricas, efeitos colaterais ou estado a um job agendado
específico.
Para execuções originadas por canal, ctx.messageProvider é a superfície de provedor, como
discord ou telegram, enquanto ctx.channelId é o identificador do alvo da conversa
quando o OpenClaw consegue derivá-lo da chave de sessão ou dos metadados de entrega.
agent_end é um gancho de observação e é executado fire-and-forget após o turno. O
executor de ganchos aplica um tempo limite de 30 segundos para que um Plugin travado ou endpoint
de embedding não possa deixar a promessa do gancho pendente para sempre. Um tempo limite é registrado e
o OpenClaw continua; ele não cancela trabalho de rede pertencente ao Plugin, a menos que o
Plugin também use seu próprio sinal de abortamento.
Use model_call_started e model_call_ended para telemetria de chamadas de provedor
que não deve receber prompts brutos, histórico, respostas, cabeçalhos, corpos de
requisição ou IDs de requisição do provedor. Esses hooks incluem metadados estáveis, como
runId, callId, provider, model, api/transport opcionais,
durationMs/outcome terminais e upstreamRequestIdHash quando o OpenClaw consegue derivar um
hash limitado do ID de requisição do provedor.
before_agent_finalize é executado somente quando um harness está prestes a aceitar uma resposta
final natural do assistente. Ele não é o caminho de cancelamento /stop e não é
executado quando o usuário aborta um turno. Retorne { action: "revise", reason } para pedir
ao harness mais uma passagem de modelo antes da finalização, { action: "finalize", reason? } para forçar a finalização, ou omita um resultado para continuar.
Hooks nativos Stop do Codex são retransmitidos para este hook como decisões
before_agent_finalize do OpenClaw.
Ao retornar action: "revise", plugins podem incluir metadados retry para tornar
a passagem extra do modelo limitada e segura para repetição:
instruction é acrescentada ao motivo de revisão enviado ao harness.
idempotencyKey permite que o host conte novas tentativas para a mesma solicitação de plugin em
decisões de finalização equivalentes, e maxAttempts limita quantas passagens extras o
host permitirá antes de continuar com a resposta final natural.
Plugins não empacotados que precisam de hooks de conversa bruta (before_model_resolve,
before_agent_reply, llm_input, llm_output, before_agent_finalize,
agent_end ou before_agent_run) devem definir:
plugins.entries.<id>.hooks.allowPromptInjection=false.
Extensões de sessão e injeções para o próximo turno
Plugins de fluxo de trabalho podem persistir pequenos estados de sessão compatíveis com JSON usandoapi.registerSessionExtension(...) e atualizá-los por meio do método
sessions.pluginPatch do Gateway. Linhas de sessão projetam o estado de extensão registrado
por meio de pluginExtensions, permitindo que a UI de Controle e outros clientes renderizem
status de propriedade do plugin sem conhecer os detalhes internos do plugin.
Use api.enqueueNextTurnInjection(...) quando um plugin precisar que contexto durável
chegue ao próximo turno do modelo exatamente uma vez. O OpenClaw drena injeções enfileiradas antes
dos hooks de prompt, descarta injeções expiradas e deduplica por idempotencyKey
por plugin. Este é o ponto de integração correto para retomadas de aprovação, resumos de política,
deltas de monitoramento em segundo plano e continuações de comando que devem ficar visíveis para
o modelo no próximo turno, mas não devem se tornar texto permanente do prompt do sistema.
As semânticas de limpeza fazem parte do contrato. A limpeza de extensões de sessão e os callbacks
de limpeza do ciclo de vida do runtime recebem reset, delete, disable ou
restart. O host remove o estado persistente de extensão de sessão do plugin proprietário
e as injeções pendentes para o próximo turno em reset/delete/disable; restart mantém
o estado durável da sessão enquanto os callbacks de limpeza permitem que plugins liberem trabalhos
do agendador, contexto de execução e outros recursos fora de banda da geração antiga do runtime.
Hooks de mensagem
Use hooks de mensagem para roteamento e política de entrega no nível do canal:message_received: observa conteúdo de entrada, remetente,threadId,messageId,senderId, correlação opcional de execução/sessão e metadados.message_sending: reescrevecontentou retorna{ cancel: true }.message_sent: observa sucesso ou falha final.
content pode conter a transcrição falada oculta
mesmo quando o payload do canal não tiver texto/legenda visível. Reescrever esse
content atualiza somente a transcrição visível ao hook; ela não é renderizada como uma
legenda de mídia.
Contextos de hook de mensagem expõem campos de correlação estáveis quando disponíveis:
ctx.sessionKey, ctx.runId, ctx.messageId, ctx.senderId, ctx.trace,
ctx.traceId, ctx.spanId, ctx.parentSpanId e ctx.callDepth. Prefira
esses campos de primeira classe antes de ler metadados legados.
Prefira os campos tipados threadId e replyToId antes de usar metadados
específicos do canal.
Regras de decisão:
message_sendingcomcancel: trueé terminal.message_sendingcomcancel: falseé tratado como nenhuma decisão.contentreescrito continua para hooks de prioridade menor, a menos que um hook posterior cancele a entrega.message_sendingpode retornarcancelReasonemetadatalimitados com um cancelamento. Novas APIs de ciclo de vida de mensagem expõem isso como um resultado de entrega suprimida com o motivocancelled_by_message_sending_hook; a entrega direta legada continua retornando um array de resultados vazio por compatibilidade.message_senté somente observação. Falhas de handler são registradas e não alteram o resultado da entrega.
Hooks de instalação
before_install é executado após a varredura integrada de instalações de Skills e plugins.
Retorne descobertas adicionais ou { block: true, blockReason } para interromper a
instalação.
block: true é terminal. block: false é tratado como nenhuma decisão.
Ciclo de vida do Gateway
Usegateway_start para serviços de plugin que precisam de estado pertencente ao Gateway. O
contexto expõe ctx.config, ctx.workspaceDir e ctx.getCron?.() para
inspeção e atualizações de cron. Use gateway_stop para limpar recursos
de longa duração.
Não dependa do hook interno gateway:startup para serviços de runtime
pertencentes ao plugin.
cron_changed dispara para eventos de ciclo de vida de cron pertencentes ao gateway, com um
payload de evento tipado cobrindo os motivos added, updated, removed, started, finished
e scheduled. O evento carrega um snapshot PluginHookGatewayCronJob
(incluindo state.nextRunAtMs, state.lastRunStatus e
state.lastError quando presentes), além de um PluginHookGatewayCronDeliveryStatus
de not-requested | delivered | not-delivered | unknown. Eventos removidos
ainda carregam o snapshot do trabalho excluído para que agendadores externos possam
reconciliar o estado. Use ctx.getCron?.() e ctx.config do contexto de runtime
ao sincronizar agendadores externos de ativação, e mantenha o OpenClaw como a
fonte da verdade para verificações de vencimento e execução.
Próximas descontinuações
Algumas superfícies adjacentes a hooks estão obsoletas, mas ainda têm suporte. Migre antes da próxima versão principal:- Envelopes de canal em texto simples em handlers
inbound_claimemessage_received. LeiaBodyForAgente os blocos estruturados de contexto do usuário em vez de analisar texto de envelope plano. Consulte Envelopes de canal em texto simples → BodyForAgent. before_agent_startpermanece por compatibilidade. Novos plugins devem usarbefore_model_resolveebefore_prompt_buildem vez da fase combinada.onResolutionembefore_tool_callagora usa a união tipadaPluginApprovalResolution(allow-once/allow-always/deny/timeout/cancelled) em vez de umastringde formato livre.
command-auth → command-status - consulte
Migração do Plugin SDK → Descontinuações ativas.
Relacionados
- Migração do Plugin SDK - descontinuações ativas e cronograma de remoção
- Como criar plugins
- Visão geral do Plugin SDK
- Pontos de entrada de plugin
- Hooks internos
- Detalhes internos da arquitetura de plugins