メインコンテンツへスキップ
Pluginフックは、OpenClaw Plugin向けのプロセス内拡張ポイントです。エージェント実行、ツール呼び出し、メッセージフロー、セッションライフサイクル、サブエージェントのルーティング、インストール、またはGateway起動を検査または変更します。 コマンドとGatewayイベント(/new/reset/stopagent:bootstrapgateway:startupなど)に反応する、オペレーターがインストールした小さなHOOK.mdスクリプトには、代わりに内部フックを使用してください。

クイックスタート

Pluginエントリからapi.on(...)で型付きフックを登録します。
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";

export default definePluginEntry({
  id: "tool-preflight",
  name: "Tool Preflight",
  register(api) {
    api.on(
      "before_tool_call",
      async (event) => {
        if (event.toolName !== "web_search") {
          return;
        }

        return {
          requireApproval: {
            title: "Run web search",
            description: `Allow search query: ${String(event.params.query ?? "")}`,
            severity: "info",
            timeoutMs: 60_000,
            timeoutBehavior: "deny",
          },
        };
      },
      { priority: 50 },
    );
  },
});
ハンドラーはpriorityの降順で順次実行されます。同じ優先度のハンドラーは登録順を維持します。 api.on(name, handler, opts?)は次を受け付けます。
オプション効果
priority順序付け。高いほど先に実行されます。
timeoutMsフックごとの実行予算。設定すると、ランナーは構成されたモデルタイムアウトでブロックする代わりに、その予算を超えたハンドラーを中止して次へ進みます。省略するとランナーのデフォルトのフックごとのタイムアウトを使用します。
オペレーターはPluginコードにパッチを当てずにフック予算を設定できます。
{
  "plugins": {
    "entries": {
      "my-plugin": {
        "hooks": {
          "timeoutMs": 30000,
          "timeouts": {
            "before_prompt_build": 90000,
            "agent_end": 60000
          }
        }
      }
    }
  }
}
hooks.timeouts.<hookName>hooks.timeoutMsを上書きし、hooks.timeoutMsはPlugin作成者が指定したapi.on(..., { timeoutMs })値を上書きします。各値は600000 ms以下の正の整数である必要があります。既知の低速フックにはフックごとの上書きを優先し、1つのPluginがあらゆる場所で長い予算を得ないようにしてください。 各フックは、そのハンドラーを登録したPluginの解決済み構成であるevent.context.pluginConfigを受け取ります。OpenClawは、他のPluginが見る共有イベントオブジェクトを変更せずに、ハンドラーごとにこれを注入します。

フックカタログ

フックは拡張するサーフェスごとにグループ化されています。太字の名前は判断結果(ブロック、キャンセル、上書き、または承認要求)を受け付けます。それ以外は観測専用です。 エージェントターン
フック目的
before_model_resolveセッションメッセージが読み込まれる前にプロバイダーまたはモデルを上書きする
agent_turn_prepareキューに入ったPluginターン注入を消費し、プロンプトフックの前に同一ターンのコンテキストを追加する
before_prompt_buildモデル呼び出しの前に動的コンテキストまたはシステムプロンプトテキストを追加する
before_agent_start互換性専用の結合フェーズ。上記2つのフックを優先する
before_agent_runモデル送信前に最終プロンプトとセッションメッセージを検査する。実行をブロックできる
before_agent_reply合成返信または無音でモデルターンを短絡する
before_agent_finalize自然な最終回答を検査し、もう1回モデルパスを要求する
agent_end最終メッセージ、成功状態、実行時間を観測する
heartbeat_prompt_contributionバックグラウンドモニターとライフサイクルPlugin向けにHeartbeat専用コンテキストを追加する
会話観測
フック目的
model_call_started / model_call_endedサニタイズ済みのプロバイダー/モデル呼び出しメタデータ: タイミング、結果、境界付きリクエストIDハッシュ。プロンプトまたはレスポンス内容は含みません。
llm_inputプロバイダー入力: システムプロンプト、プロンプト、履歴
llm_outputプロバイダー出力、使用量、利用可能な場合は解決済みのcontextTokenBudget
ツール
フック目的
before_tool_callツールパラメーターを書き換える、実行をブロックする、または承認を要求する
after_tool_callツール結果、エラー、実行時間を観測する
resolve_exec_envPluginが所有する環境変数をexecに提供する
tool_result_persistツール結果から生成されるアシスタントメッセージを書き換える
before_message_write進行中のメッセージ書き込みを検査またはブロックする(まれ)
メッセージと配信
フック目的
inbound_claimエージェントルーティング前に受信メッセージを要求する(合成返信)
channel_pairing_requested新しく作成されたDMペアリング要求を観測する
message_received受信内容、送信者、スレッド、メタデータを観測する
message_sending送信内容を書き換える、または配信をキャンセルする
reply_payload_sending配信前に正規化済み返信ペイロードを変更またはキャンセルする
message_sent送信配信の成功または失敗を観測する
before_dispatchチャンネルへの引き渡し前に送信ディスパッチを検査または書き換える
reply_dispatch最終返信ディスパッチパイプラインに参加する
セッションとCompaction
フック目的
session_start / session_endセッションライフサイクル境界を追跡します。reasonnewresetidledailycompactiondeletedshutdownrestart、またはunknownのいずれかです。shutdown/restartは、アクティブなセッションがある状態でプロセスが停止または再起動すると、Gatewayシャットダウンファイナライザーから発火します。これにより、Plugin(メモリ、トランスクリプトストア)は再起動をまたいで開いたままにする代わりに、ゴースト行を確定できます。ファイナライザーには上限があるため、遅いPluginがSIGTERM/SIGINTをブロックできません。
before_compaction / after_compactionCompactionサイクルを観測または注釈付けする
before_resetセッションリセットイベント(/reset、プログラムによるリセット)を観測する
サブエージェント
  • subagent_spawned / subagent_ended - サブエージェントの起動と完了を観測します。
  • subagent_delivery_target - コアのセッションバインディングでルートを投影できない場合の完了配信用互換フックです。
  • subagent_spawning - 非推奨の互換フックです。現在、コアはsubagent_spawnedが発火する前に、チャンネルのセッションバインディングアダプターを通じてthread: trueサブエージェントバインディングを準備します。
  • subagent_spawnedには、OpenClawが起動前に子セッションのネイティブモデルを解決している場合、resolvedModelresolvedProviderが含まれます。
  • subagent_endedは、targetSessionKey(ID - subagent_spawned.childSessionKeyと一致)、targetKind"subagent"または"acp")、reason、任意のoutcome"ok""error""timeout""killed""reset"、または"deleted")、任意のerrorrunIdendedAtaccountIdsendFarewellを持ちます。agentIdまたはchildSessionKeyは含みません。一致するsubagent_spawnedイベントとの関連付けにはtargetSessionKeyを使用してください。
ライフサイクル
フック目的
gateway_start / gateway_stopGatewayとともにPlugin所有サービスを開始または停止する
deactivategateway_stopの非推奨互換エイリアス。新しいPluginではgateway_stopを使用する
cron_changedGateway所有のcronライフサイクル変更(追加、更新、削除、開始、終了、スケジュール)を観測する
before_install読み込まれたPluginランタイムからステージング済みSkillまたはPluginインストール素材を検査する

チャンネルペアリング要求

Pluginが、未ペアリングのDM送信者が保留中のペアリング要求を作成した後にオペレーターへ通知する、または監査記録を書き込む必要がある場合は、channel_pairing_requestedを使用します。このフックは要求が作成されたときにディスパッチされます。ペアリング返信のチャンネル配信は、遅いまたは失敗したフックハンドラーによって遅延されません。
api.on("channel_pairing_requested", async (event) => {
  await notifyOperator({
    text: `New ${event.channel} pairing request from ${event.senderId}: ${event.code}`,
  });
});
このフックは観測専用です。ペアリング返信を承認、拒否、抑制、または書き換えることはありません。ペイロードには、チャンネル、任意の accountId、チャンネルスコープの senderId、ペアリング code、チャンネルメタデータが含まれます。ペアリングコードは有効な単回使用の承認資格情報として扱い、信頼済みのオペレーター送信先にのみ届けてください。metadata は、送信者が提供した信頼できない識別テキストとして扱ってください。このフックには、受信メッセージ本文やメディアは含まれません。

デバッグランタイムフック

エージェントターンのプロバイダーまたはモデルを切り替えるには before_model_resolve を使用します。これはモデル解決の前に実行されます。llm_output は、モデル試行がアシスタント出力を生成した後にのみ実行されます。 有効なセッションモデルを証明するには、ランタイム登録を調べてから、openclaw sessions または Gateway のセッション/ステータスサーフェスを使用します。プロバイダーペイロードをデバッグするには、--raw-stream--raw-stream-path <path> を指定して Gateway を起動し、生のモデルストリームイベントを jsonl ファイルに書き込みます。

ツール呼び出しポリシー

before_tool_call は以下を受け取ります。
  • event.toolName
  • event.params
  • 任意の event.toolKindevent.toolInputKind: 意図的に名前を共有するツール向けの、ホストが権威を持つ判別子。たとえば、外側のコードモード exec 呼び出しは toolKind: "code_mode_exec" を使用し、入力言語が既知の場合は toolInputKind: "javascript" | "typescript" を含みます
  • 任意の event.derivedPaths: apply_patch などの既知のツールエンベロープに対してホストがベストエフォートで導出した対象パスのヒント。これらのパスは、ツールが実際に触れる内容に対して不完全または過大近似である場合があります(たとえば、不正な形式または部分的な入力の場合)
  • 任意の event.runId
  • 任意の event.toolCallId
  • ctx.agentIdctx.sessionKeyctx.sessionIdctx.runIdctx.toolKindctx.toolInputKind、診断用の ctx.trace などのコンテキストフィールド
以下を返せます。
type BeforeToolCallResult = {
  params?: Record<string, unknown>;
  block?: boolean;
  blockReason?: string;
  requireApproval?: {
    title: string;
    description: string;
    severity?: "info" | "warning" | "critical";
    timeoutMs?: number;
    timeoutBehavior?: "allow" | "deny";
    allowedDecisions?: Array<"allow-once" | "allow-always" | "deny">;
    pluginId?: string;
    onResolution?: (
      decision: "allow-once" | "allow-always" | "deny" | "timeout" | "cancelled",
    ) => Promise<void> | void;
  };
};
型付きライフサイクルフックのガード動作:
  • block: true は終端であり、低優先度のハンドラーをスキップします。
  • block: false は決定なしとして扱われます。
  • params は実行用のツールパラメーターを書き換えます。
  • requireApproval はエージェント実行を一時停止し、Plugin 承認を通じてユーザーに確認します。/approve は exec と Plugin 承認の両方を承認できます。Codex app-server レポートモードのネイティブ PreToolUse リレーでは、これは対応する app-server 承認リクエストに委譲されます。Codex harness runtime を参照してください。
  • 高優先度のフックが承認を要求した後でも、低優先度の block: true はブロックできます。
  • onResolution は解決済みの決定を受け取ります: allow-onceallow-alwaysdenytimeout、または cancelled
承認ルーティング、決定動作、任意ツールや exec 承認の代わりに requireApproval を使うタイミングについては、Plugin permission requests を参照してください。 ホストレベルのポリシーが必要な Plugin は、api.registerTrustedToolPolicy(...) で信頼済みツールポリシーを登録できます。これらは通常の before_tool_call フックより前、通常のフック決定より前に実行されます。バンドル済み信頼済みポリシーが最初に実行され、インストール済み Plugin の信頼済みポリシーが Plugin 読み込み順で次に実行され、通常の before_tool_call フックはその後に実行されます。バンドル済み Plugin は既存の信頼済みポリシーパスを保持します。インストール済み Plugin は明示的に有効化され、すべてのポリシー ID を contracts.trustedToolPolicies で宣言する必要があります。宣言されていない ID は登録前に拒否されます。ポリシー ID は登録元 Plugin にスコープされるため、異なる Plugin が同じローカル ID を再利用できます。この階層は、ワークスペースポリシー、予算適用、予約済みワークフローの安全性など、ホストが信頼するゲートにのみ使用してください。

Exec 環境フック

resolve_exec_env を使うと、Plugin はコマンド実行前に exec ツール呼び出しへ環境変数を提供できます。これは以下を受け取ります。
  • event.sessionKey
  • event.toolName、現在は常に "exec"
  • event.host"gateway""sandbox"、または "node" のいずれか
  • ctx.agentIdctx.sessionKeyctx.messageProviderctx.channelId などのコンテキストフィールド
exec 環境へマージするには Record<string, string> を返します。ハンドラーは優先度順に実行され、後続の結果が同じキーの先行結果を上書きします。 フック出力は、マージ前にホストの exec 環境キー ポリシーでフィルターされます。PATH は常に削除されます(コマンド解決と safe-bin チェックがこれに依存するため)。無効なキー、および LD_*DYLD_*NODE_OPTIONS、プロキシ変数(HTTP_PROXYHTTPS_PROXYALL_PROXYNO_PROXY)、TLS 上書き変数(NODE_TLS_REJECT_UNAUTHORIZEDSSL_CERT_FILE など)のような危険なホスト上書きキーは削除されます。フィルター済みの Plugin 環境は Gateway 承認/監査メタデータに含まれ、node ホスト実行リクエストへ転送されます。

ツール結果の永続化

ツール結果には、UI レンダリング、診断、メディアルーティング、または Plugin 所有メタデータ用の構造化された details を含められます。details はプロンプト内容ではなく、ランタイムメタデータとして扱ってください。
  • OpenClaw は、メタデータがモデルコンテキストにならないように、プロバイダーリプレイと Compaction 入力の前に toolResult.details を取り除きます。
  • 永続化されたセッションエントリは、制限内の details のみを保持します。大きすぎる details はコンパクトな要約と persistedDetailsTruncated: true に置き換えられます。
  • tool_result_persistbefore_message_write は最終的な永続化上限の前に実行されます。返す details は小さく保ち、プロンプトに関連するテキストを details のみに置くことは避けてください。モデルに見えるツール出力は content に入れてください。

プロンプトとモデルフック

新しい Plugin にはフェーズ固有のフックを使用してください。
  • before_model_resolve: 現在のプロンプトと添付メタデータのみを受け取ります。providerOverride または modelOverride を返します。
  • agent_turn_prepare: 現在のプロンプト、準備済みセッションメッセージ、このセッション向けに排出された正確に一度だけのキュー済み注入を受け取ります。prependContext または appendContext を返します。
  • before_prompt_build: 現在のプロンプトとセッションメッセージを受け取ります。prependContextappendContextsystemPromptprependSystemContext、または appendSystemContext を返します。
  • heartbeat_prompt_contribution: Heartbeat ターンでのみ実行され、prependContext または appendContext を返します。ユーザー起点のターンを変更せずに現在状態を要約する必要があるバックグラウンドモニター向けです。
before_agent_start は互換性のために残っています。Plugin がレガシーな結合フェーズに依存しないよう、上記の明示的なフックを優先してください。 before_agent_run は、プロンプト構築後、プロンプトローカル画像読み込みや llm_input 観測を含むモデル入力の前に実行されます。現在のユーザー入力を prompt として受け取り、読み込み済みセッション履歴を messages に、アクティブなシステムプロンプトも受け取ります。モデルがプロンプトを読む前に実行を停止するには { outcome: "block", reason, message? } を返します。reason は内部用です。message はユーザー向けの置換文です。passblock の結果のみがサポートされ、サポートされない決定形状はフェイルクローズします。 実行がブロックされると、OpenClaw は message.content の置換テキストと、ブロックした Plugin ID やタイムスタンプなどの非機密ブロックメタデータのみを保存します。元のユーザーテキストはトランスクリプトや将来のコンテキストには保持されません。内部ブロック理由は機密として扱われ、トランスクリプト、履歴、ブロードキャスト、ログ、診断ペイロードから除外されます。可観測性には、ブロッカー ID、結果、タイムスタンプ、安全なカテゴリなどのサニタイズ済みフィールドを使用してください。 before_agent_startagent_end には、OpenClaw がアクティブな実行を識別できる場合に event.runId が含まれます。同じ値は ctx.runId にもあります。Cron 駆動の実行では、フックがメトリクス、副作用、または状態を特定のスケジュール済みジョブにスコープできるように、エージェントターン コンテキストで ctx.jobId(元の Cron ジョブ ID)も公開されます。ctx.jobIdbefore_tool_call ツールコンテキストの一部ではありません。 チャンネル起点の実行では、ctx.channelctx.messageProviderdiscordtelegram などのプロバイダーサーフェスを識別し、ctx.channelId は OpenClaw がセッションキーまたは配信メタデータから導出できる場合の会話対象識別子です。 送信者識別情報が利用可能な場合、エージェントフックコンテキストには以下も含まれます。
  • ctx.senderId - チャンネルスコープの送信者 ID(例: Feishu open_id、Discord ユーザー ID)。実行が既知の送信者メタデータを持つユーザーメッセージに由来する場合に設定されます。
  • ctx.chatId - トランスポートネイティブの会話識別子(例: Feishu chat_id、Telegram chat_id)。起点チャンネルがネイティブ会話 ID を提供する場合に設定されます。
  • ctx.channelContext.sender.id - ctx.senderId と同じ送信者 ID。Plugin がチャンネル固有フィールドで拡張できるチャンネル所有オブジェクト配下にあります。
  • ctx.channelContext.chat.id - ctx.chatId と同じ会話 ID。Plugin がチャンネル固有フィールドで拡張できるチャンネル所有オブジェクト配下にあります。
コアが定義するのはネストされた id フィールドのみです。受信ヘルパー経由でより豊富な送信者またはチャットメタデータを渡すチャンネル Plugin は、openclaw/plugin-sdk/channel-inboundPluginHookChannelSenderContext または PluginHookChannelChatContext を拡張できます。
declare module "openclaw/plugin-sdk/channel-inbound" {
  interface PluginHookChannelSenderContext {
    unionId?: string;
    userId?: string;
  }
}
チャンネル Plugin は、受信 SDK ヘルパー経由でこれらのフィールドを渡します。
buildChannelInboundEventContext({
  // ...
  channelContext: {
    sender: { id: senderOpenId, unionId, userId },
    chat: { id: chatId },
  },
});
これらのフィールドは任意であり、システム起点の実行(heartbeat、cron、exec-event)では存在しません。 ctx.senderExternalId は、古い Plugin 向けの非推奨ソース互換性フィールドとして残っています。コアはこれを設定しません。新しいチャンネル固有の送信者識別情報は、モジュール拡張を通じて ctx.channelContext.sender 配下に配置してください。 agent_end は観測フックです。Gateway と永続ハーネスのパスはターン後に fire-and-forget で実行します。一方、短命な one-shot CLI パスは、信頼済み Plugin がターミナル可観測性をフラッシュしたり状態を取得したりできるように、プロセスクリーンアップ前にフック promise を待ちます。フックランナーは 30 秒のタイムアウトを適用するため、停止した Plugin や埋め込みエンドポイントによってフック promise が永久に保留されることはありません。タイムアウトはログに記録され、OpenClaw は継続します。Plugin が独自の abort signal も使用していない限り、Plugin 所有のネットワーク作業はキャンセルされません。 生のプロンプト、履歴、レスポンス、ヘッダー、リクエスト本文、またはプロバイダーリクエスト ID を受け取るべきでないプロバイダー呼び出しテレメトリには、model_call_startedmodel_call_ended を使用してください。これらのフックには、runIdcallIdprovidermodel、任意の api/transport、終端の durationMs/outcome、OpenClaw が制限付きプロバイダーリクエスト ID ハッシュを導出できる場合の upstreamRequestIdHash などの安定したメタデータが含まれます。ランタイムがコンテキストウィンドウメタデータを解決している場合、フックイベントとコンテキストには、モデル/設定/エージェント上限後の有効なトークン予算である contextTokenBudget に加えて、より低い上限が適用された場合の contextWindowSourcecontextWindowReferenceTokens も含まれます。 before_agent_finalize は、ハーネスが自然な最終アシスタント回答を受け入れようとしている場合にのみ実行されます。これは /stop のキャンセル経路ではなく、ユーザーがターンを中断した場合にも実行されません。最終化の前にもう一度モデルパスを行うようハーネスに依頼するには { action: "revise", reason } を返し、最終化を強制するには { action: "finalize", reason? } を返します。結果を省略すると続行します。Codex ネイティブの Stop hooks は、OpenClaw before_agent_finalize の判断としてこの hook に中継されます。 action: "revise" を返す場合、plugins は retry メタデータを含めて、追加のモデルパスを有界かつリプレイ安全にできます。
type BeforeAgentFinalizeRetry = {
  instruction: string;
  idempotencyKey?: string;
  maxAttempts?: number;
};
instruction は、ハーネスに送信される修正理由に追加されます。 idempotencyKey により、ホストは同じ Plugin 要求について、同等の finalize 判断をまたいで再試行回数を数えられます。また maxAttempts は、自然な最終回答で続行する前にホストが許可する追加パス数を制限します。 未バンドルの plugins が生の会話 hooks(before_model_resolvebefore_agent_replyllm_inputllm_outputbefore_agent_finalizeagent_end、または before_agent_run)を必要とする場合は、次を設定する必要があります。
{
  "plugins": {
    "entries": {
      "my-plugin": {
        "hooks": {
          "allowConversationAccess": true
        }
      }
    }
  }
}
プロンプトを変更する hooks と永続的な次ターン注入は、Plugin ごとに plugins.entries.<id>.hooks.allowPromptInjection=false で無効化できます。

セッション拡張と次ターン注入

ワークフロー plugins は、api.session.state.registerSessionExtension(...) で小さな JSON 互換のセッション状態を永続化し、Gateway sessions.pluginPatch メソッドを通じて更新できます。セッション行は登録済みの拡張状態を pluginExtensions を通じて投影するため、Control UI や他のクライアントは Plugin 内部を知ることなく、Plugin が所有するステータスをレンダリングできます。 api.registerSessionExtension(...) は引き続き動作しますが、api.session.state 名前空間の使用が推奨され、これは非推奨です。 Plugin が次のモデルターンに正確に一度だけ届く永続的なコンテキストを必要とする場合は、api.session.workflow.enqueueNextTurnInjection(...) を使用します(トップレベルの api.enqueueNextTurnInjection(...) は同じ動作を持つ非推奨のエイリアスです)。OpenClaw はプロンプト hooks の前にキュー済みの注入を排出し、期限切れの注入を破棄し、Plugin ごとに idempotencyKey で重複排除します。これは、承認再開、ポリシー要約、バックグラウンド監視の差分、コマンド継続など、次のターンでモデルに見えるべきだが永続的なシステムプロンプト文にはすべきでないものに適した境界です。 クリーンアップのセマンティクスは契約の一部です。セッション拡張クリーンアップとランタイムライフサイクルのクリーンアップコールバックは、resetdeletedisable、または restart を受け取ります。ホストは reset/delete/disable の場合、所有 Plugin の永続的なセッション拡張状態と保留中の次ターン注入を削除します。restart は永続的なセッション状態を保持しつつ、クリーンアップコールバックにより plugins が古いランタイム世代のスケジューラージョブ、実行コンテキスト、その他の帯域外リソースを解放できるようにします。

メッセージ hooks

チャンネルレベルのルーティングと配信ポリシーにはメッセージ hooks を使用します。
  • message_received: 受信コンテンツ、送信者、threadIdmessageIdsenderId、任意の実行/セッション相関、メタデータを監視します。
  • message_sending: content を書き換えるか、{ cancel: true } を返します。
  • reply_payload_sending: 正規化済みの ReplyPayload オブジェクト (presentationdelivery、メディア参照、テキストを含む)を書き換えるか、 { cancel: true } を返します。
  • message_sent: 最終的な成功または失敗を監視します。
音声のみの TTS 返信では、チャンネルペイロードに表示テキスト/キャプションがない場合でも、content に非表示の読み上げトランスクリプトが含まれることがあります。その content を書き換えると、hook から見えるトランスクリプトのみが更新されます。メディアキャプションとしてレンダリングされることはありません。 reply_payload_sending イベントには、ベストエフォートのライブなターン単位モデル/使用量/コンテキストスナップショットである usageState が含まれる場合があります。永続的な配信、復元されたリプレイ、正確な実行相関のない返信では省略されます。 メッセージ hook コンテキストは、利用可能な場合に安定した相関フィールドを公開します。 ctx.sessionKeyctx.runIdctx.messageIdctx.senderIdctx.tracectx.traceIdctx.spanIdctx.parentSpanIdctx.callDepth です。受信コンテキストと before_dispatch コンテキストは、チャンネルに可視性フィルター済みの引用メッセージデータがある場合、返信メタデータも公開します。replyToIdreplyToIdFullreplyToBodyreplyToSenderreplyToIsQuote です。従来のメタデータを読む前に、これらの第一級フィールドを優先してください。 チャンネル固有のメタデータを使う前に、型付きの threadIdreplyToId フィールドを優先してください。 判断ルール:
  • cancel: true を含む message_sending は終端です。
  • cancel: false を含む message_sending は判断なしとして扱われます。
  • 書き換えられた content は、後続の hook が配信をキャンセルしない限り、より低優先度の hooks に進みます。
  • reply_payload_sending はペイロード正規化後、チャンネル配信前に実行されます。これには発信元チャンネルへ戻る返信も含まれます。 ハンドラーは順番に実行され、各ハンドラーは高優先度ハンドラーによって生成された最新のペイロードを見ます。
  • reply_payload_sending のペイロードは、trustedLocalMedia のようなランタイム信頼マーカーを公開しません。plugins はペイロード形状を編集できますが、ローカルメディア信頼を付与することはできません。
  • message_sending は、キャンセル時に cancelReason と有界な metadata を返せます。新しいメッセージライフサイクル API は、これを理由 cancelled_by_message_sending_hook の抑制された配信結果として公開します。従来の直接配信は互換性のために空の結果配列を返し続けます。
  • message_sent は監視専用です。ハンドラーの失敗はログに記録され、配信結果は変更されません。

インストール hooks

オペレーター所有の許可/ブロック判断には security.installPolicy を使用します。そのポリシーは OpenClaw 設定から実行され、CLI のインストールおよび更新経路を対象とし、有効だが利用できない場合は fail closed します。 before_install は Plugin ランタイムライフサイクル hook です。これは security.installPolicy の後、Gateway が支援するインストールフローなど、Plugin hooks がすでに読み込まれている OpenClaw プロセス内でのみ実行されます。Plugin が所有する監視、警告、互換性チェックには有用ですが、インストールにおける主要なエンタープライズまたはホストのセキュリティ境界ではありません。builtinScan フィールドは互換性のためイベントペイロードに残っていますが、OpenClaw はインストール時の組み込み危険コードブロックを実行しなくなったため、空の ok 結果です。そのプロセス内でインストールを停止するには、追加の findings または { block: true, blockReason } を返します。 block: true は終端です。block: false は判断なしとして扱われます。ハンドラーの失敗は fail-closed でインストールをブロックします。

Gateway ライフサイクル

Gateway が所有する状態を必要とする Plugin サービスには gateway_start を使用します。コンテキストは Cron の検査と更新のために、ctx.configctx.workspaceDirctx.getCron?.() を公開します。長時間実行されるリソースをクリーンアップするには gateway_stop を使用します。 Plugin 所有のランタイムサービスで内部の gateway:startup hook に依存しないでください。 cron_changed は、Gateway が所有する Cron ライフサイクルイベントで発火し、addedupdatedremovedstartedfinishedscheduled の理由を網羅する型付きイベントペイロードを持ちます。イベントは、PluginHookGatewayCronJob スナップショット(存在する場合は state.nextRunAtMsstate.lastRunStatusstate.lastError を含む)と、not-requested | delivered | not-delivered | unknownPluginHookGatewayCronDeliveryStatus を運びます。削除イベントでも削除済みジョブのスナップショットを保持するため、外部スケジューラーは状態を調整できます。外部ウェイクスケジューラーを同期するときは、ランタイムコンテキストの ctx.getCron?.()ctx.config を使用し、期限チェックと実行については OpenClaw を信頼できる情報源として維持してください。

今後の非推奨

いくつかの hook 隣接サーフェスは非推奨ですが、まだサポートされています。次のメジャーリリース前に移行してください。
  • inbound_claim および message_received ハンドラーの 平文チャンネルエンベロープ。 フラットなエンベロープテキストを解析する代わりに、BodyForAgent と構造化されたユーザーコンテキストブロックを読んでください。 平文チャンネルエンベロープ → BodyForAgent を参照してください。
  • before_agent_start は互換性のために残っています。新しい plugins は、結合フェーズの代わりに before_model_resolvebefore_prompt_build を使用してください。
  • subagent_spawning は古い plugins との互換性のために残っていますが、新しい plugins はここからスレッドルーティングを返すべきではありません。core は subagent_spawned が発火する前に、チャンネルのセッションバインディングアダプターを通じて thread: true のサブエージェントバインディングを準備します。
  • deactivate は、2026-08-16 以降まで、非推奨のクリーンアップ互換エイリアスとして残ります。新しい plugins は gateway_stop を使用してください。
  • before_tool_callonResolution は、自由形式の string ではなく、型付きの PluginApprovalResolution union(allow-once / allow-always / deny / timeout / cancelled)を使用するようになりました。
  • api.registerSessionExtension / api.enqueueNextTurnInjection は、トップレベルの互換エイリアスとして残っています。新しい plugins は api.session.state.registerSessionExtension(...)api.session.workflow.enqueueNextTurnInjection(...) を使用してください。
完全な一覧(メモリ能力登録、プロバイダー思考プロファイル、外部認証プロバイダー、プロバイダー探索型、タスクランタイムアクセサー、command-authcommand-status の名称変更)については、 Plugin SDK 移行 → アクティブな非推奨 を参照してください。

関連