Plugin-Hooks sind prozessinterne Erweiterungspunkte für OpenClaw-Plugins. Verwenden Sie sie, wenn ein Plugin Agent-Ausführungen, Tool-Aufrufe, Nachrichtenfluss, Sitzungslebenszyklus, Subagent-Routing, Installationen oder Gateway-Start prüfen oder ändern muss. Verwenden Sie stattdessen interne Hooks, wenn Sie ein kleines, vom Operator installiertesDocumentation 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-Skript für Befehls- und Gateway-Ereignisse wie
/new, /reset, /stop, agent:bootstrap oder gateway:startup wünschen.
Schnellstart
Registrieren Sie typisierte Plugin-Hooks mitapi.on(...) aus dem Einstiegspunkt Ihres Plugins:
priority ausgeführt. Hooks
mit gleicher Priorität behalten die Registrierungsreihenfolge bei.
api.on(name, handler, opts?) akzeptiert:
priority- Handler-Reihenfolge (höhere Werte laufen zuerst).timeoutMs- optionales Budget pro Hook. Wenn gesetzt, bricht der Hook-Runner diesen Handler nach Ablauf des Budgets ab und fährt mit dem nächsten fort, statt langsame Einrichtung oder Abrufarbeit das vom Aufrufer konfigurierte Modell-Timeout verbrauchen zu lassen. Lassen Sie es weg, um das standardmäßige Beobachtungs-/Entscheidungs-Timeout zu verwenden, das der Hook-Runner allgemein anwendet.
hooks.timeouts.<hookName> überschreibt hooks.timeoutMs, was den vom Plugin
verfassten Wert api.on(..., { timeoutMs }) überschreibt. Jeder konfigurierte
Wert muss eine positive Ganzzahl von höchstens 600000 Millisekunden sein.
Bevorzugen Sie Überschreibungen pro Hook für bekanntermaßen langsame Hooks,
damit ein Plugin nicht überall ein längeres Budget erhält.
Jeder Hook erhält event.context.pluginConfig, die aufgelöste Konfiguration für
das Plugin, das diesen Handler registriert hat. Verwenden Sie sie für Hook-Entscheidungen,
die aktuelle Plugin-Optionen benötigen; OpenClaw injiziert sie pro Handler,
ohne das gemeinsam genutzte Ereignisobjekt zu verändern, das andere Plugins sehen.
Hook-Katalog
Hooks sind nach der Oberfläche gruppiert, die sie erweitern. Namen in Fettdruck akzeptieren ein Entscheidungsergebnis (blockieren, abbrechen, überschreiben oder Genehmigung anfordern); alle anderen dienen nur der Beobachtung. Agent-Durchlaufbefore_model_resolve- Provider oder Modell überschreiben, bevor Sitzungsnachrichten geladen werdenagent_turn_prepare- eingereihte Plugin-Turn-Injektionen verbrauchen und Kontext für denselben Durchlauf vor Prompt-Hooks hinzufügenbefore_prompt_build- dynamischen Kontext oder System-Prompt-Text vor dem Modellaufruf hinzufügenbefore_agent_start- kombinierte Phase nur aus Kompatibilitätsgründen; bevorzugen Sie die zwei Hooks obenbefore_agent_run- den endgültigen Prompt und Sitzungsnachrichten vor der Modellübermittlung prüfen und die Ausführung optional blockierenbefore_agent_reply- den Modell-Durchlauf mit einer synthetischen Antwort oder Stille kurzschließenbefore_agent_finalize- die natürliche finale Antwort prüfen und einen weiteren Modelllauf anfordernagent_end- finale Nachrichten, Erfolgsstatus und Ausführungsdauer beobachtenheartbeat_prompt_contribution- Heartbeat-spezifischen Kontext für Hintergrundmonitor- und Lebenszyklus-Plugins hinzufügen
model_call_started/model_call_ended- bereinigte Metadaten zu Provider-/Modellaufrufen, Timing, Ergebnis und begrenzte Anfrage-ID-Hashes ohne Prompt- oder Antwortinhalt beobachtenllm_input- Provider-Eingabe beobachten (System-Prompt, Prompt, Verlauf)llm_output- Provider-Ausgabe beobachten
before_tool_call- Tool-Parameter umschreiben, Ausführung blockieren oder Genehmigung anfordernafter_tool_call- Tool-Ergebnisse, Fehler und Dauer beobachtentool_result_persist- die aus einem Tool-Ergebnis erzeugte Assistentennachricht umschreibenbefore_message_write- einen laufenden Nachrichtenschreibvorgang prüfen oder blockieren (selten)
inbound_claim- eine eingehende Nachricht vor dem Agent-Routing beanspruchen (synthetische Antworten)message_received- eingehenden Inhalt, Absender, Thread und Metadaten beobachtenmessage_sending- ausgehenden Inhalt umschreiben oder Zustellung abbrechenmessage_sent- erfolgreiche oder fehlgeschlagene ausgehende Zustellung beobachtenbefore_dispatch- einen ausgehenden Dispatch vor der Kanalübergabe prüfen oder umschreibenreply_dispatch- an der finalen Antwort-Dispatch-Pipeline teilnehmen
session_start/session_end- Grenzen des Sitzungslebenszyklus nachverfolgen. Derreasondes Ereignisses ist einer vonnew,reset,idle,daily,compaction,deleted,shutdown,restartoderunknown. Die Werteshutdownundrestartwerden vom Gateway-Shutdown-Finalizer ausgelöst, wenn der Prozess gestoppt oder neu gestartet wird, während Sitzungen noch aktiv sind, sodass nachgelagerte Plugins (wie Speicher- oder Transkript-Speicher) verwaiste Zeilen finalisieren können, die sonst über Neustarts hinweg offen bleiben würden. Der Finalizer ist begrenzt, sodass ein langsames Plugin SIGTERM/SIGINT nicht blockieren kann.before_compaction/after_compaction- Compaction-Zyklen beobachten oder annotierenbefore_reset- Sitzungs-Reset-Ereignisse beobachten (/reset, programmatische Resets)
subagent_spawning/subagent_delivery_target/subagent_spawned/subagent_ended- Routing und Abschlusszustellung von Subagents koordinieren
gateway_start/gateway_stop- Plugin-eigene Dienste mit dem Gateway starten oder stoppencron_changed- Gateway-eigene Cron-Lebenszyklusänderungen beobachten (hinzugefügt, aktualisiert, entfernt, gestartet, beendet, geplant)before_install- Skill- oder Plugin-Installationsscans prüfen und optional blockieren
Tool-Aufrufrichtlinie
before_tool_call erhält:
event.toolNameevent.params- optional
event.derivedPaths, mit bestmöglichen, vom Host abgeleiteten Zielpfad-Hinweisen für bekannte Tool-Umschläge wieapply_patch; sofern vorhanden, können diese Pfade unvollständig sein oder überschätzen, was das Tool tatsächlich berühren wird (zum Beispiel bei fehlerhaften oder unvollständigen Eingaben) - optional
event.runId - optional
event.toolCallId - Kontextfelder wie
ctx.agentId,ctx.sessionKey,ctx.sessionId,ctx.runId,ctx.jobId(gesetzt bei Cron-gesteuerten Ausführungen) und diagnostischesctx.trace
block: trueist terminal und überspringt Handler mit niedrigerer Priorität.block: falsewird als keine Entscheidung behandelt.paramsschreibt die Tool-Parameter für die Ausführung um.requireApprovalpausiert die Agent-Ausführung und fragt den Benutzer über Plugin-Genehmigungen. Der Befehl/approvekann sowohl Exec- als auch Plugin-Genehmigungen erteilen.- Ein
block: truemit niedrigerer Priorität kann weiterhin blockieren, nachdem ein Hook mit höherer Priorität Genehmigung angefordert hat. onResolutionerhält die aufgelöste Genehmigungsentscheidung -allow-once,allow-always,deny,timeoutodercancelled.
api.registerTrustedToolPolicy(...) registrieren. Diese laufen vor gewöhnlichen
before_tool_call-Hooks und vor Entscheidungen externer Plugins. Verwenden Sie sie nur
für hostvertrauenswürdige Prüfungen wie Workspace-Richtlinien, Budgetdurchsetzung oder
Sicherheit für reservierte Workflows. Externe Plugins sollten normale before_tool_call-Hooks
verwenden.
Persistenz von Tool-Ergebnissen
Tool-Ergebnisse können strukturiertedetails für UI-Rendering, Diagnose,
Medien-Routing oder Plugin-eigene Metadaten enthalten. Behandeln Sie details als Laufzeitmetadaten,
nicht als Prompt-Inhalt:
- OpenClaw entfernt
toolResult.detailsvor Provider-Replay und Compaction-Eingabe, sodass Metadaten nicht zu Modellkontext werden. - Persistierte Sitzungseinträge behalten nur begrenzte
details. Zu große Details werden durch eine kompakte Zusammenfassung undpersistedDetailsTruncated: trueersetzt. tool_result_persistundbefore_message_writelaufen vor der finalen Persistenzgrenze. Hooks sollten zurückgegebenedetailsdennoch klein halten und vermeiden, promptrelevanten Text nur indetailsabzulegen; platzieren Sie modellseitig sichtbare Tool-Ausgabe incontent.
Prompt- und Modell-Hooks
Verwenden Sie die phasenspezifischen Hooks für neue Plugins:before_model_resolve: erhält nur den aktuellen Prompt und Anhangsmetadaten. Geben SieproviderOverrideodermodelOverridezurück.agent_turn_prepare: erhält den aktuellen Prompt, vorbereitete Sitzungsnachrichten und alle exakt einmaligen, für diese Sitzung entnommenen eingereihten Injektionen. Geben SieprependContextoderappendContextzurück.before_prompt_build: erhält den aktuellen Prompt und Sitzungsnachrichten. Geben SieprependContext,appendContext,systemPrompt,prependSystemContextoderappendSystemContextzurück.heartbeat_prompt_contribution: läuft nur für Heartbeat-Durchläufe und gibtprependContextoderappendContextzurück. Es ist für Hintergrundmonitore vorgesehen, die den aktuellen Zustand zusammenfassen müssen, ohne benutzerinitiierte Durchläufe zu ändern.
before_agent_start bleibt aus Kompatibilitätsgründen bestehen. Bevorzugen Sie die expliziten Hooks oben,
damit Ihr Plugin nicht von einer Legacy-Kombinationsphase abhängt.
before_agent_run läuft nach der Prompt-Erstellung und vor jeder Modelleingabe,
einschließlich promptlokalem Laden von Bildern und llm_input-Beobachtung. Es erhält
die aktuelle Benutzereingabe als prompt, plus geladene Sitzungshistorie in messages
und den aktiven System-Prompt. Geben Sie { outcome: "block", reason, message? }
zurück, um die Ausführung zu stoppen, bevor das Modell den Prompt lesen kann. reason ist intern;
message ist der benutzerseitige Ersatz. Die einzigen unterstützten Ergebnisse sind
pass und block; nicht unterstützte Entscheidungsformen schlagen geschlossen fehl.
Wenn eine Ausführung blockiert wird, speichert OpenClaw nur den Ersatztext in
message.content plus nicht sensible Blockierungsmetadaten wie die ID des blockierenden Plugins
und den Zeitstempel. Der ursprüngliche Benutzertext wird weder im Transkript noch im zukünftigen
Kontext behalten. Interne Blockierungsgründe werden als sensibel behandelt und aus
Transkript-, Verlaufs-, Broadcast-, Log- und Diagnose-Payloads ausgeschlossen. Beobachtbarkeit
sollte bereinigte Felder wie Blocker-ID, Ergebnis, Zeitstempel oder eine sichere
Kategorie verwenden.
before_agent_start und agent_end enthalten event.runId, wenn OpenClaw
die aktive Ausführung identifizieren kann. Derselbe Wert ist auch unter ctx.runId verfügbar.
Cron-gesteuerte Ausführungen legen außerdem ctx.jobId offen (die ID des auslösenden Cron-Jobs),
damit Plugin-Hooks Metriken, Nebeneffekte oder Zustand auf einen bestimmten geplanten
Job begrenzen können.
Bei kanalbasierten Ausführungen ist ctx.messageProvider die Provider-Oberfläche wie
discord oder telegram, während ctx.channelId der Zielbezeichner der Konversation ist,
wenn OpenClaw ihn aus dem Sitzungsschlüssel oder Zustellungsmetadaten ableiten kann.
agent_end ist ein Beobachtungs-Hook und läuft nach dem Durchlauf fire-and-forget. Der
Hook-Runner wendet ein Timeout von 30 Sekunden an, sodass ein festhängendes Plugin oder ein Embedding-
Endpoint das Hook-Promise nicht dauerhaft offen lassen kann. Ein Timeout wird protokolliert und
OpenClaw fährt fort; Plugin-eigene Netzwerkarbeit wird dadurch nicht abgebrochen, es sei denn,
das Plugin verwendet zusätzlich sein eigenes Abort-Signal.
Verwenden Sie model_call_started und model_call_ended für Provider-Aufruf-Telemetrie,
die keine Roh-Prompts, Verläufe, Antworten, Header, Anfragekörper oder
Provider-Anfrage-IDs erhalten soll. Diese Hooks enthalten stabile Metadaten wie
runId, callId, provider, model, optional api/transport, terminale
durationMs/outcome sowie upstreamRequestIdHash, wenn OpenClaw einen
begrenzten Hash der Provider-Anfrage-ID ableiten kann.
before_agent_finalize wird nur ausgeführt, wenn ein Harness kurz davorsteht, eine natürliche
finale Assistant-Antwort zu akzeptieren. Dies ist nicht der /stop-Abbruchpfad und wird nicht
ausgeführt, wenn der Benutzer einen Turn abbricht. Geben Sie { action: "revise", reason } zurück, um
das Harness vor der Finalisierung um einen weiteren Modelldurchlauf zu bitten, { action: "finalize", reason? }, um die Finalisierung zu erzwingen, oder lassen Sie ein Ergebnis weg, um fortzufahren.
Native Codex-Stop-Hooks werden an diesen Hook als OpenClaw-
before_agent_finalize-Entscheidungen weitergegeben.
Beim Zurückgeben von action: "revise" können Plugins retry-Metadaten einschließen, um
den zusätzlichen Modelldurchlauf begrenzt und replay-sicher zu machen:
instruction wird an den Revisionsgrund angehängt, der an das Harness gesendet wird.
idempotencyKey ermöglicht dem Host, Wiederholungen für dieselbe Plugin-Anfrage über
äquivalente Finalisierungsentscheidungen hinweg zu zählen, und maxAttempts begrenzt, wie viele zusätzliche Durchläufe der
Host zulässt, bevor er mit der natürlichen finalen Antwort fortfährt.
Nicht gebündelte Plugins, die rohe Konversations-Hooks benötigen (before_model_resolve,
before_agent_reply, llm_input, llm_output, before_agent_finalize,
agent_end oder before_agent_run), müssen Folgendes setzen:
plugins.entries.<id>.hooks.allowPromptInjection=false deaktiviert werden.
Sitzungserweiterungen und Next-Turn-Injections
Workflow-Plugins können kleinen JSON-kompatiblen Sitzungsstatus mitapi.registerSessionExtension(...) dauerhaft speichern und ihn über die Gateway-
Methode sessions.pluginPatch aktualisieren. Sitzungszeilen projizieren registrierten Erweiterungsstatus
über pluginExtensions, sodass Control UI und andere Clients Plugin-eigenen Status rendern können,
ohne Plugin-Interna kennen zu müssen.
Verwenden Sie api.enqueueNextTurnInjection(...), wenn ein Plugin dauerhaften Kontext benötigt, der
genau einmal den nächsten Modell-Turn erreichen soll. OpenClaw leert eingereihte Injections vor
Prompt-Hooks, verwirft abgelaufene Injections und dedupliziert pro Plugin nach idempotencyKey.
Dies ist die richtige Schnittstelle für Genehmigungs-Fortsetzungen, Richtlinienzusammenfassungen,
Deltas von Hintergrundmonitoren und Befehlsfortsetzungen, die im nächsten Turn für das Modell sichtbar sein sollen,
aber nicht zu dauerhaftem System-Prompt-Text werden dürfen.
Bereinigungssemantik ist Teil des Vertrags. Die Bereinigung von Sitzungserweiterungen und
Bereinigungs-Callbacks des Runtime-Lebenszyklus erhalten reset, delete, disable oder
restart. Der Host entfernt den persistenten Sitzungserweiterungsstatus des besitzenden Plugins
und ausstehende Next-Turn-Injections für reset/delete/disable; restart behält
dauerhaften Sitzungsstatus bei, während Bereinigungs-Callbacks Plugins erlauben, Scheduler-
Jobs, Ausführungskontext und andere out-of-band Ressourcen der alten Runtime-
Generation freizugeben.
Nachrichten-Hooks
Verwenden Sie Nachrichten-Hooks für Routing auf Kanalebene und Zustellungsrichtlinien:message_received: eingehende Inhalte, Absender,threadId,messageId,senderId, optionale Ausführungs-/Sitzungskorrelation und Metadaten beobachten.message_sending:contentumschreiben oder{ cancel: true }zurückgeben.message_sent: finalen Erfolg oder Fehler beobachten.
content das verborgene gesprochene Transkript enthalten,
auch wenn die Kanalnutzlast keinen sichtbaren Text bzw. keine sichtbare Bildunterschrift hat. Das Umschreiben dieses
content aktualisiert nur das für Hooks sichtbare Transkript; es wird nicht als
Medienbeschriftung gerendert.
Nachrichten-Hook-Kontexte stellen stabile Korrelationsfelder bereit, sofern verfügbar:
ctx.sessionKey, ctx.runId, ctx.messageId, ctx.senderId, ctx.trace,
ctx.traceId, ctx.spanId, ctx.parentSpanId und ctx.callDepth. Bevorzugen Sie
diese erstklassigen Felder, bevor Sie Legacy-Metadaten lesen.
Bevorzugen Sie typisierte Felder threadId und replyToId, bevor Sie kanalspezifische
Metadaten verwenden.
Entscheidungsregeln:
message_sendingmitcancel: trueist terminal.message_sendingmitcancel: falsewird als keine Entscheidung behandelt.- Umgeschriebener
contentwird an Hooks mit niedrigerer Priorität weitergereicht, sofern kein späterer Hook die Zustellung abbricht. message_sendingkanncancelReasonund begrenztemetadatazusammen mit einem Abbruch zurückgeben. Neue Nachrichtenlebenszyklus-APIs stellen dies als unterdrücktes Zustellungsergebnis mit dem Grundcancelled_by_message_sending_hookbereit; Legacy-Direktzustellung gibt aus Kompatibilitätsgründen weiterhin ein leeres Ergebnisarray zurück.message_sentdient nur der Beobachtung. Handler-Fehler werden protokolliert und ändern das Zustellungsergebnis nicht.
Installations-Hooks
before_install wird nach dem integrierten Scan auf Skill- und Plugin-Installationen ausgeführt.
Geben Sie zusätzliche Befunde oder { block: true, blockReason } zurück, um die
Installation zu stoppen.
block: true ist terminal. block: false wird als keine Entscheidung behandelt.
Gateway-Lebenszyklus
Verwenden Siegateway_start für Plugin-Dienste, die Gateway-eigenen Status benötigen. Der
Kontext stellt ctx.config, ctx.workspaceDir und ctx.getCron?.() zur
Cron-Inspektion und für Aktualisierungen bereit. Verwenden Sie gateway_stop, um lang laufende
Ressourcen zu bereinigen.
Verlassen Sie sich nicht auf den internen Hook gateway:startup für Plugin-eigene Runtime-
Dienste.
cron_changed wird für Gateway-eigene Cron-Lebenszyklusereignisse mit einer typisierten
Ereignisnutzlast ausgelöst, die die Gründe added, updated, removed, started, finished
und scheduled abdeckt. Das Ereignis enthält einen PluginHookGatewayCronJob-
Snapshot (einschließlich state.nextRunAtMs, state.lastRunStatus und
state.lastError, sofern vorhanden) sowie einen PluginHookGatewayCronDeliveryStatus
von not-requested | delivered | not-delivered | unknown. Entfernte
Ereignisse enthalten weiterhin den gelöschten Job-Snapshot, damit externe Scheduler den
Status abgleichen können. Verwenden Sie ctx.getCron?.() und ctx.config aus dem Runtime-
Kontext beim Synchronisieren externer Wake-Scheduler, und behalten Sie OpenClaw als
Quelle der Wahrheit für Fälligkeitsprüfungen und Ausführung bei.
Anstehende Deprecations
Einige Hook-nahe Oberflächen sind veraltet, werden aber weiterhin unterstützt. Migrieren Sie vor dem nächsten Major-Release:- Klartext-Kanal-Envelopes in Handlern für
inbound_claimundmessage_received. Lesen Sie stattdessenBodyForAgentund die strukturierten Benutzerkontextblöcke, statt flachen Envelope-Text zu parsen. Siehe Klartext-Kanal-Envelopes → BodyForAgent. before_agent_startbleibt aus Kompatibilitätsgründen erhalten. Neue Plugins solltenbefore_model_resolveundbefore_prompt_buildstatt der kombinierten Phase verwenden.onResolutioninbefore_tool_callverwendet nun die typisiertePluginApprovalResolution-Union (allow-once/allow-always/deny/timeout/cancelled) statt eines frei formuliertenstring.
command-auth zu command-status - finden Sie unter
Plugin-SDK-Migration → Aktive Deprecations.
Verwandt
- Plugin-SDK-Migration - aktive Deprecations und Zeitplan für Entfernungen
- Plugins erstellen
- Plugin-SDK-Übersicht
- Plugin-Einstiegspunkte
- Interne Hooks
- Interne Plugin-Architektur