Skip to main content
Hook は、エージェントイベントの発火時に Gateway 内で実行される小さなスクリプトです。対象には、/new/reset/stop などのコマンド、セッションの Compaction、Gateway のライフサイクル、メッセージフローがあります。Hook はディレクトリから検出され、openclaw hooks で管理されます。Gateway が内部 Hook を読み込むのは、Hook を有効にするか、Hook エントリ、Hook パック、レガシーハンドラー、追加の Hook ディレクトリのいずれかを少なくとも 1 つ設定した後だけです。 OpenClaw には 2 種類の Hook があります。
  • 内部 Hook(このページ):エージェントイベントの発火時に Gateway 内で実行されます。
  • Webhook:他のシステムから OpenClaw の処理をトリガーできる外部 HTTP エンドポイントです。Webhookを参照してください。
Hook は Plugin 内にバンドルすることもできます。openclaw hooks list には、スタンドアロン Hook と Plugin 管理の Hook(plugin:<id> と表示)の両方が表示されます。

適切なサーフェスを選ぶ

OpenClaw には、見た目は似ていても異なる問題を解決する複数の拡張サーフェスがあります。 小規模なインストール済みインテグレーションのように動作する自動化が必要な場合は、内部 Hook を使用します。ランタイムのライフサイクル制御が必要な場合は、型付き Plugin Hook を使用します。

クイックスタート

イベントの種類

Hook は、この表の特定のキー、または単独のファミリー名 (commandsessionagentgatewaymessage)をサブスクライブして、そのファミリー内のすべてのアクションを受信します。OpenClaw コアはそれ以外を発行しないため、他の名前はほぼ常に入力ミスであり、Hook は通知なしに動作しないままになります(カスタムイベントを発行する Plugin がある場合にのみ発火する可能性があります)。Hook ローダーは、そのような名前(たとえば command:nwe)について警告をログに記録し、openclaw hooks info <name> もそれらを検出するため、まったく実行されない Hook も診断できます。

Hook の作成

Hook の構造

各 Hook は、2 つのファイルを含むディレクトリです。
ハンドラーファイルには、handler.tshandler.jsindex.ts、または index.js を使用できます。

HOOK.md の形式

メタデータフィールドmetadata.openclaw):

ハンドラーの実装

各イベントには、typeactionsessionKeytimestampmessages、および context(イベント固有のデータ)が含まれます。エージェントおよびツールの Hook 用の型付き Plugin Hook コンテキストには、読み取り専用で W3C 互換の診断トレースコンテキストである trace も含まれる場合があり、Plugin は OTEL の相関付けのために構造化ログへ渡すことができます。 event.messages に追加された文字列がチャットへ返されるのは、 command:newcommand:reset(元の会話への返信としてルーティング)、 および session:compact:before / session:compact:after (Compaction のステータス通知として送信)の場合だけです。 command:stopmessage:*agent:bootstrapsession:patchgateway:* を含むその他すべてのイベントは、追加されたメッセージを無視します。

イベントコンテキストの要点

コマンドイベントcommand:newcommand:reset):context.sessionEntrycontext.previousSessionEntrycontext.commandSourcecontext.senderIdcontext.workspaceDircontext.cfg コマンドイベントcommand:stop):context.sessionEntrycontext.sessionIdcontext.commandSourcecontext.senderId メッセージイベントmessage:received):context.fromcontext.contentcontext.channelIdcontext.media(順序付けされた段階的な添付ファイル情報)、リモートメディアがまだローカルにステージングされていない場合の context.originalMediacontext.mediaStagingPending、および context.metadatasenderIdsenderNameguildId を含むプロバイダー固有のデータ)。context.content は、コマンド形式のメッセージでは空白でないコマンド本文を優先し、次に受信時の未加工本文、汎用本文の順でフォールバックします。スレッド履歴やリンク要約など、エージェント専用の拡張情報は含まれません。metadata 内のレガシーメディアエイリアスは非推奨です。 メッセージイベントmessage:sent):context.tocontext.contentcontext.successcontext.channelId、および送信に失敗した場合の context.error メッセージイベントmessage:transcribed):context.transcriptcontext.fromcontext.channelId、および context.mediacontext.mediaPathcontext.mediaType は、最初の情報に対する非推奨のエイリアスとして残されています。 メッセージイベントmessage:preprocessed):context.bodyForAgent(最終的に拡張された本文)、context.fromcontext.channelId ブートストラップイベントagent:bootstrap):context.bootstrapFiles(変更可能な配列)、context.agentId セッションパッチイベントsession:patch):context.sessionEntrycontext.patch(変更されたフィールドのみ)、context.cfg。パッチイベントをトリガーできるのは特権クライアントだけです。コンテキストはクローンであるため、ハンドラーが実際のセッションエントリを変更することはできません。 Compaction イベントsession:compact:before には messageCounttokenCount が含まれます。session:compact:after には、さらに compactedCountsummaryLengthtokensBeforetokensAfter が追加されます。 command:stop は、ユーザーによる /stop の発行を監視します。これはキャンセル/コマンドのライフサイクルであり、エージェントの最終処理を制御するゲートではありません。自然な最終回答を検査し、エージェントにもう一度処理を行わせる必要がある Plugin は、代わりに型付き Plugin Hook before_agent_finalize を使用してください。Plugin Hookを参照してください。 Gateway ライフサイクルイベントgateway:shutdown には reasonrestartExpectedMs が含まれ、Gateway のシャットダウン開始時に発火します。gateway:pre-restart には同じコンテキストが含まれますが、シャットダウンが予定された再起動の一部であり、有限の restartExpectedMs 値が指定された場合にのみ発火します。シャットダウン中の各ライフサイクル Hook の待機はベストエフォートかつ制限時間付きであり、ハンドラーが停止してもシャットダウンは続行されます。デフォルトの待機時間は、gateway:shutdown では 5 秒、gateway:pre-restart では 10 秒です。 チャンネルがまだ利用可能な間に短い再起動通知を送るには、gateway:pre-restart を使用します。
gateway:shutdown(または gateway:pre-restart)イベントと、残りのシャットダウンシーケンスの間に、Gateway はプロセス停止時にまだアクティブだった各セッションに対して、型付き session_end Plugin Hook も発火します。イベントの reason は、通常の SIGTERM/SIGINT 停止では shutdown、予定された再起動の一部として終了がスケジュールされた場合は restart です。このドレイン処理には制限時間があるため、遅い session_end ハンドラーがプロセス終了を妨げることはありません。また、置換/リセット/削除/Compaction によってすでに終了処理されたセッションは、二重発火を避けるためスキップされます。

Hook の検出

Hook は 4 つのソースから検出されます。
  1. 同梱フック: OpenClaw に同梱
  2. Plugin フック: インストール済み Plugin に同梱。同名の同梱フックを上書き可能
  3. 管理対象フック: ~/.openclaw/hooks/(ユーザーがインストールし、ワークスペース間で共有)。同梱フックと Plugin フックを上書き可能。hooks.internal.load.extraDirs で指定した追加ディレクトリにも同じ優先順位が適用されます。
  4. ワークスペースフック: <workspace>/hooks/(エージェントごと。明示的に有効化されるまでデフォルトでは無効)
ワークスペースフックは新しいフック名を追加できますが、同名の同梱フック、管理対象フック、または Plugin 提供フックを上書きすることはできません。 内部フックが設定されるまで、Gateway は起動時の内部フック検出をスキップします。openclaw hooks enable <name> で同梱フックまたは管理対象フックを有効化するか、フックパックをインストールするか、hooks.internal.enabled=true を設定してオプトインします。名前を指定してフックを有効化すると、Gateway はそのフックのハンドラーのみを読み込みます。hooks.internal.enabled=true、追加のフックディレクトリ、およびレガシーハンドラーを使用すると、広範な検出にオプトインします。

フックパック

フックパックは、package.json 内の openclaw.hooks を介してフックをエクスポートする npm パッケージです。次のコマンドでインストールします。
npm 仕様ではレジストリのみが使用できます(パッケージ名と、任意の完全一致バージョンまたは dist-tag)。Git、URL、ファイルの仕様、および semver 範囲は拒否されます。以前の openclaw hooks install および openclaw hooks update コマンドは、openclaw plugins install / openclaw plugins update の非推奨エイリアスです。

同梱フック

任意の同梱フックを有効化します。

session-memory の詳細

最後のユーザーおよびアシスタントのメッセージ(デフォルトは 15 件、hooks.internal.entries.session-memory.messages で設定可能)を抽出し、ホストのローカル日付を使用して <workspace>/memory/YYYY-MM-DD-HHMM.md に保存します。メモリのキャプチャはバックグラウンドで実行されるため、トランスクリプトの読み取りや任意のスラッグ生成によって /new および /reset の確認応答が遅延することはありません。説明的なファイル名スラッグを生成するには hooks.internal.entries.session-memory.llmSlug: true を設定します。また、任意で hooks.internal.entries.session-memory.model に、sonnet などの設定済みエイリアス、エージェントのデフォルトプロバイダー上のモデル ID、または provider/model 参照を設定できます。model を省略した場合、スラッグ生成にはエージェントのデフォルトモデルが使用され、利用できない場合はタイムスタンプスラッグにフォールバックします。workspace.dir の設定が必要です。

bootstrap-extra-files の設定

patterns および files は、paths のエイリアスとして受け入れられます。パスはワークスペースを基準に解決され、ワークスペース内に収まる必要があります。認識されるブートストラップのベース名(AGENTS.mdSOUL.mdTOOLS.mdIDENTITY.mdUSER.mdHEARTBEAT.mdBOOTSTRAP.mdMEMORY.md)のみが読み込まれます。

command-logger の詳細

すべてのスラッシュコマンドを JSON 行(タイムスタンプ、アクション、セッションキー、送信者 ID、ソース)として ~/.openclaw/logs/commands.log に記録します。

compaction-notifier の詳細

OpenClaw がセッショントランスクリプトの Compaction を開始および完了したとき、現在の会話に短いステータスメッセージを送信します。これにより、アシスタントがコンテキストを要約中であり、Compaction 後に処理を続行することがユーザーに分かるため、チャット画面で長いターンを処理する際の混乱が軽減されます。

boot-md の詳細

設定済みの各エージェントスコープについて、そのエージェントで解決されたワークスペースにファイルが存在する場合、Gateway の起動時に BOOT.md を実行します。

Plugin フック

Plugin は、より深い統合のため、Plugin SDK を介して型付きフックを登録できます。 ツール呼び出しのインターセプト、プロンプトの変更、メッセージフローの制御などが可能です。 before_tool_callbefore_agent_replybefore_install、またはその他のプロセス内ライフサイクルフックが必要な場合は、Plugin フックを使用します。 Plugin が管理する内部フックはこれとは異なります。このページで説明する 大まかなコマンド/ライフサイクルイベントシステムに参加し、openclaw hooks list では plugin:<id> として表示されます。これらは副作用やフックパックとの互換性のために使用し、 順序付きミドルウェアやポリシーゲートには使用しないでください。 Plugin フックの完全なリファレンスについては、Plugin フックを参照してください。

設定

フックごとの環境値は、プロセス環境と併せてフックの requires.env 適格性チェックを満たすために使用され、ハンドラーはフックの設定エントリからその値を読み取ることができます。
追加のフックディレクトリ:
後方互換性のため、従来の hooks.internal.handlers 配列設定形式も引き続きサポートされていますが、新しいフックでは検出ベースのシステムを使用してください。

CLI リファレンス

ベストプラクティス

  • ハンドラーを高速に保つ。 フックはコマンド処理中に実行されます。負荷の高い処理は void processInBackground(event) を使用して、完了を待たずに実行します。
  • エラーを適切に処理する。 リスクのある操作は try/catch で囲み、他のハンドラーを実行できるように例外をスローしないでください。
  • イベントを早期に絞り込む。 イベントの種類やアクションが関連しない場合は、直ちに return します。
  • 具体的なイベントキーを使用する。 オーバーヘッドを減らすため、"events": ["command"] よりも "events": ["command:new"] を優先します。

トラブルシューティング

フックが検出されない

フックが適格でない

不足しているバイナリ(PATH)、環境変数、設定値、または OS の互換性を確認してください。

フックが実行されない

  1. フックが有効になっていることを確認します: openclaw hooks list
  2. フックを再読み込みするため、Gateway プロセスを再起動します。
  3. Gateway のログを確認します: openclaw logs --follow | grep -i hook

関連項目