本文へ移動
cccskills
無料GitHub で公開日本語紹介

agent-runtime-hooks

エージェント実行中の各段階をフックで監視し、ツール呼び出しの模擬・制御や人の承認、圧縮、サブエージェント処理に介入する仕組みを扱います。

原文原文の説明を見る

Use for agent lifecycle hooks, tool mocks, intervention, sub-agent calls and context compression.

lobehub/lobehubスター 83,506(GitHub 83,506 + cccskills 0)

実行スコア 未検証

インストール方法を見る

こんなときに便利

  • エージェントの実行状況を記録したいとき
  • ツール結果をテスト用に模擬したいとき
  • Webhookでツール実行を許可・拒否したいとき
  • 承認やサブエージェントの流れを追いたいとき

日本語での紹介

できること

エージェントの実行ライフサイクルにフックを登録し、各段階のイベントを扱う方法を説明します。ステップ開始・完了、ツール実行前後やエラー、人による承認、コンテキスト圧縮、サブエージェントの呼び出し、最終状態などを対象にできます。ローカルハンドラーではツール結果を模擬し、Webhookではイベント通知や設定に応じた許可・拒否の判断を扱います。イベントに含まれる実行ID、ツール情報、結果などのコンテキストや、Webhookのペイロードと配信エラーの挙動も示します。

こんなときに便利

エージェント実行の観測や運用時の介入を組み込みたい開発者、ツールの結果を検証用に差し替えたい場合に向いています。承認やサブエージェントを含む処理の流れを追う用途にも使えます。

使い方の例

  • 「ツール実行前に許可を確認するWebhookフックを設定して」
  • 「このエージェントのステップとエラーを記録するフックを追加して」
  • 「テスト時にツールの結果をローカルで模擬して」

注意点

Webhookの設定や動作には配信先URLが必要です。ヘッダーに環境変数を使う場合は許可リストを指定し、秘密情報は保存時に展開しません。Webhookのみで登録したフックはプロセス再起動後に関数ハンドラーを復元できません。

この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。

資料チェック

SKILL.md の記述から、注意が要る操作と導入の前提を AI が確認しました。点数は実際に動かした結果(実行検証)だけで付けています。

安全面送信・削除・コマンド実行などの扱いが明示されているか
B一部不足Webhookで実行を許可・拒否できますが、失敗時設定など説明が分散しています。
導入のしやすさ必要なツールや API キーが少ないか、書かれているか
B一部不足Webhook用の送信先URLや環境変数許可リストが必要と明記されています。

点数には入れていません。 2026年10月26日 時点で AI(OpenAI Codex)が判定しました。目安なので、入れる前に原文も確認してください。

評価が違うと思ったら、見直しを依頼する

どの項目が、なぜ違うと思うかを書いてください。ログインは不要です。内容を SKILL.md と照らし合わせて評価を作り直し、この欄に反映します。

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

含まれるファイル(1)

  • SKILL.md15.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Agent Runtime Hooks

Register lifecycle hooks through execAgent({ hooks }). HookDispatcher stores them per operation and dispatches them in registration order.

Hook Types

16 hook types across 5 categories:

execAgent({ hooks })
  │
  ├─ beforeStep ──────────── Before each step executes
  │     │
  │     ├─ [call_llm]        LLM inference
  │     │
  │     ├─ [call_tool]
  │     │     ├─ beforeToolCall ── Before tool executes (supports mocking)
  │     │     ├─ (tool execution)
  │     │     ├─ afterToolCall ─── After tool completes (optional result control)
  │     │     └─ onToolCallError ─ Tool threw an exception
  │     │
  │     ├─ [request_human_approve]
  │     │     ├─ beforeHumanIntervention ── Before agent pauses
  │     │     ├─ afterHumanIntervention ─── After approve/reject + resume
  │     │     └─ onStopByHumanIntervention ── User rejected, agent halted
  │     │
  │     ├─ [compress_context]
  │     │     ├─ beforeCompact ──── Before compression starts
  │     │     ├─ afterCompact ───── After compression completes
  │     │     └─ onCompactError ─── Compression failed
  │     │
  │     ├─ [callAgent] (via execSubAgentTask)
  │     │     ├─ beforeCallAgent ── Before sub-agent starts
  │     │     ├─ afterCallAgent ─── After creation/start returns
  │     │     └─ onCallAgentError ── Sub-agent failed
  │     │
  │     └─ afterStep ──────────── After step completes
  │
  ├─ (next step...)
  │
  ├─ onComplete ───────────── Operation reaches terminal state
  └─ onError ──────────────── Error during execution

Key Files

FileRole
packages/agent-runtime/src/types/hooks.tsEvent types and required/optional fields
apps/server/src/services/agentRuntime/hooks/types.tsRegistration and webhook types
apps/server/src/services/agentRuntime/hooks/HookDispatcher.tsRegistration, dispatch, local mocks, HTTP/QStash delivery
apps/server/src/services/agentRuntime/hooks/webhookPayload.tsEvent projection and email enrichment
apps/server/src/modules/AgentRuntime/adapters/toolCallHookContext.tsShared tool-event context builder
apps/server/src/modules/AgentRuntime/adapters/ServerToolTransport.tsTool notifications and execution results
apps/server/src/modules/AgentRuntime/RuntimeExecutors.tsTool, compression and human-intervention execution
apps/server/src/services/agentRuntime/AgentRuntimeService/ (executeStep/, intervention.ts)Step events and human-intervention continuation
apps/server/src/services/agentRuntime/CompletionLifecycle/index.tsTerminal events
apps/server/src/services/aiAgent/subAgentRuns.tsSub-agent events

Registration

const hooks: AgentHook[] = [
  {
    id: 'observe-step',
    type: 'afterStep',
    handler: async (event) => {
      console.log(event.operationId, event.stepIndex);
    },
  },
];
await aiAgentService.execAgent({ agentId, prompt, hooks });

Completion cleans up registrations through hookDispatcher.unregister(operationId).

Webhook Hooks

Webhook-only hooks deliver in both local and queue modes. For hooks with both handler and webhook, local dispatch calls the handler; queue dispatch uses the serialized webhook. Only webhook configuration is persisted, so functions are unavailable after a process restart.

const hook: AgentHook = {
  id: 'tool-notification',
  type: 'afterToolCall',
  matcher: '^fs/readFile$',
  webhook: {
    url: 'https://example.com/hooks',
    delivery: 'fetch',
    timeout: 5, // seconds; default 30
    headers: { Authorization: 'Bearer ${HOOK_TOKEN}' },
    allowedEnvVars: ['HOOK_TOKEN'],
  },
};
  • matcher is a regex against ${identifier}/${apiName}, supported only on tool events. Omitted, empty, or * matches all tools.
  • Header environment templates resolve only at send time from allowedEnvVars; persist templates, never resolved secrets.
  • Notifications ignore response content and may return HTTP 204.
  • beforeToolCall with responseHandling: 'toolCall' awaits an optional HTTP decision before tool execution. Return HTTP 2xx JSON with { "decision": "allow" } or { "decision": "deny", "reason": "禁止执行该操作" } to intervene. The type is { decision: 'allow' } | { decision: 'deny'; reason?: string }; a deny with an omitted or empty reason uses Blocked by beforeToolCall hook.. Denials preserve the reason in the tool result/card with classification hook_denied.
  • afterToolCall also accepts responseHandling: 'toolCall'. It synchronously checks the full request/result before archival and model consumption; deny replaces the original result with the receiver's optional reason in both content and blocked state. A deny with an omitted or empty reason uses Blocked by afterToolCall hook., following the same Blocked by ${type} hook. rule as beforeToolCall. The reason enters model context and the tool card, as with beforeToolCall. It does not undo tool side effects, retries, or charges. See the result-control contract for deferred completions and runtime boundaries.
  • Environment response modes are ignore (default notifications) and toolCall (optional decisions for both before and after). Only subscribed events are enabled. Replace removed toolResult/toolCallAndResult values with toolCall; use the events list to select after-only checking. Existing after responses with a valid decision now control results.
  • HTTP 204, empty successful bodies, invalid JSON, and JSON without a top-level decision (including arrays, scalars, null, or only the old nested hookSpecificOutput) are notification responses, even with onError: 'block'. Continue checking subsequent hooks; do not treat a notification as permission to skip later policies. Explicit invalid decisions, non-2xx status, oversized bodies, invalid UTF-8, network failures, and timeouts follow onError: 'continue' | 'block' (default continue); blocking uses hook_control_error as the tool-result content and reason for both before and after hooks. Cancellation never grants permission.
  • Extra response fields are allowed and discarded. Only decision and a deny's optional string reason are consumed; updatedInput/additionalContext do not change tool arguments or conversation context.
  • Configuration: packages/types/src/agentHook.ts; response parsing: packages/types/src/agentHookResponse.ts; HTTP delivery: apps/server/src/services/agentRuntime/hooks/httpWebhook.ts.

Hook configuration lifetime

  • Environment hooks (AGENT_HOOK_WEBHOOK_*) always come from the executing worker's current environment, including after human approval and deferred completion. Never persist their configuration or restore a previous environment's hooks.
  • Code-supplied webhook hooks (execAgent({ hooks })) retain the existing per-operation serialization and persistence. Recover these caller hooks from the runtime snapshot or durable operation record; preserve environment-variable templates without expanding secrets into storage.
  • Evaluate each operation's recovered caller hooks in order, then evaluate current environment hooks once in the final round. Do not deduplicate caller hook IDs across operations. Environment-only hooks do not require durable operation storage. Removing an environment hook stops it from controlling subsequent results; when no matching result control remains, allow the result. Do not freeze a previous environment policy across an approval or restart.
  • Deferred completion publishes into its empty placeholder once; duplicate callbacks retain that first final result, including a denial. Propagate caller-policy storage errors rather than treating failed reads as an empty hook list. Do not extend default allow to configured-hook delivery failures: those follow onError.
  • Cover environment removal/addition across approval and snapshot expiry, publication without review markers, and continued enforcement of persisted caller hooks in regression tests.

Publish after the result hook

  • Await result control before archival, message content/state writes, streaming, and model consumption. Persist the allowed result or the sanitized denial directly; do not add toolResultControl pending/allowed/blocked metadata or hide raw output through history projections.
  • Human approval sources claim the decision and retain the answer in their private resolution/outbox. MessageModel.resolveHumanApproval defaults to claim-only; only the runtime calls it with publishResult: true after result control. Stop/rejection receipts can publish directly because they contain no executed tool output.
  • Recover original caller hooks through the existing intervention operation identity or deferred callback's parent operation. Keep the in-memory hook verdict separate from tool-owned state; a tool returning type: 'blocked' is not a hook verdict.
  • Every deferred backfill, including a member that fails to start, follows the same hook-before-write order. Use the existing empty placeholder to arbitrate duplicate final writes; do not introduce a replacement review state machine.
  • When a thread has a sub-agent or group-member completion bridge, that bridge exclusively publishes its tool result. Thread lifecycle hooks update thread metadata only; never prefill the tool message with an ungated summary, including after approval recovery.
  • Cover an answer held while a hook runs, atomic publication and rollback, duplicate callbacks after policy removal, and partial member startup failure. History readers should need no result-review logic.

Events

EventTiming and payload
beforeStepBefore a step; AgentHookEvent
afterStepAfter a step; content, tool calls/results and usage totals
onCompleteTerminal state; reason such as done, error, interrupted, max_steps or cost_limit
onErrorOperation error; errorMessage, errorDetail and available error metadata
beforeToolCallBefore tool execution; shared tool context and local mock() callback
afterToolCallAfter tool execution; structured result and mocked
onToolCallErrorTool execution throws; shared tool context and error
beforeHumanInterventionBefore approval; pendingTools, operationId, stepIndex
afterHumanInterventionApproval decision and continuation; action, optional toolCallId and rejectionReason
onStopByHumanInterventionHuman rejection stops the run; optional toolCallId and rejectionReason
beforeCompactBefore compression; messageCount, tokenCount, stepIndex
afterCompactAfter compression; groupId, messagesBefore, messagesAfter, summary
onCompactErrorCompression error; error, tokenCount, stepIndex
beforeCallAgentBefore sub-agent creation; agentId, instruction
afterCallAgentCreation/start returns; agentId, subOperationId, success, optional threadId
onCallAgentErrorSub-agent call fails; agentId, error

CallAgent events dispatch on the parent operation identified by parentOperationId. An isolated child supplies threadId; shared group members use the shared conversation. Child completion is reported by the child's onComplete event.

Tool Context

Use buildToolCallHookContext() for the three tool events.

  • Required fields: native toolCallId, assistantMessageId, identifier, apiName, effective args, callIndex, stepIndex, operationId and executor.
  • Optional associations come from the run context: agent, topic, session, thread, group, task, workspace, document, source/tool message and parent operation IDs.
  • userId uses runtime.userId ?? origin.userId.
  • toolSource identifies the tool's origin; executor identifies the server/client dispatch route. executionTarget and activeDeviceId describe the run's execution plan and device selection.
  • afterToolCall.result carries content, success, optional executionTime and error/state data such as state.type: 'blocked'. mocked marks results supplied by a local hook.

Sandbox and MCP tools use the same event path. Filter with identifier, apiName or toolSource.

Local Mocking

dispatchBeforeToolCall() exposes event.mock(result). The first accepted mock wins and short-circuits the remaining mock handlers. The method returns { isMocked: true, result } for a mock, or null to continue execution.

event.mock({ content: '{"items":[]}', success: true });

Tool observation payloads use BeforeToolCallObservationEvent; the callback belongs to the in-memory handler event. dispatchBeforeToolCall() does not deliver webhooks.

Webhook Payloads

createWebhookPayloadBuilder() selects eventFields, adds hookId/hookType, then merges webhook.body. The body determines the final value of overlapping fields. Tool-result notification payloads use redactResultForEvents() to trim raw skill Work data; controls receive the full result. Work registration retains the full in-process result. finalState is available to local handlers; serialized payloads carry the event's data fields.

When email is selected, the builder resolves userEmail from the final effective userId, replacing supplied email values. Email-only projections use the event ID. An explicit invalid ID, missing email or lookup error leaves email omitted.

Email queries share a per-dispatcher cache of up to 1,000 users for five minutes. Query timeouts belong to the database layer. The builder's optional fourth { signal } argument lets a waiter cancel independently; cancellation returns undefined so the caller can stop delivery. Fetch and QStash use the enriched payload.

Delivery Errors

Dispatch awaits each handler or webhook. Ordinary errors are logged and dispatch continues. Webhooks with fallback: 'none' accumulate a CriticalHookDeliveryError, which is thrown after sibling hooks have run. QStash delivery defaults to a fetch fallback; use fallback: 'none' for QStash-signed endpoints.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

acceptance

無料概要あり

実際の製品を操作して、利用者が確認できる動作証拠を集め、検証計画に沿った受け入れレポートとして公開するスキルです。

  • 変更後の製品動作を実地で検証したいとき
  • 画面キャプチャなどの証拠を集めたいとき
  • 検証計画とレポートを作成したいとき
lobehub/lobehub8.4万2026年10月26日 更新

add-model-provider

無料概要あり

LobeHubにAIモデルプロバイダーを追加し、実行時連携からモデル表示、設定、ブランド表記、文書化、動作確認まで進めるスキルです。

  • 新しいAIモデルプロバイダーを追加したいとき
  • プロバイダーの設定手順や説明文を更新したいとき
  • 既存プロバイダーへのモデル追加要件を見極めたいとき
lobehub/lobehub8.4万2026年10月26日 更新

add-setting-env

無料概要あり

ユーザー設定の初期値をサーバー側の環境変数で切り替えるため、型定義や設定の組み立て、ユーザーストアへの反映、環境変数の例と説明書きを追加する手順です。

  • 設定の初期値を環境変数で変えたいとき
  • 設定項目をサーバー設定に追加したいとき
  • 環境変数の例と説明を更新したいとき
lobehub/lobehub8.4万2026年10月26日 更新

agent-signal

無料概要あり

イベントを起点にエージェントのバックグラウンド処理を組み立て、ソース・シグナル・アクション・ポリシーの役割分担や非同期連携を実装するためのスキルです。

  • イベント起点の処理を追加したいとき
  • バックグラウンド処理を非同期化したいとき
  • 重複実行を防ぐ仕組みを整えたいとき
lobehub/lobehub8.4万2026年10月26日 更新

agent-testing-bot

無料概要あり

DiscordやSlackなどの実際のチャットアプリでボットにメッセージを送り、応答を画面で確認する受け入れテストを行うスキルです。

  • 実際のDiscordでボット応答を確かめたいとき
  • SlackやTelegramの会話経路をテストしたいとき
  • macOSアプリ上の操作結果を画面で記録したいとき
lobehub/lobehub8.4万2026年10月26日 更新

agent-tracing

無料概要あり

エージェントの実行記録を操作IDから調べ、失敗したツール呼び出し、入出力、LLMに渡した文脈を確認して原因を追えるようにします。

  • 失敗したツール呼び出しを調べたいとき
  • LLMに渡された文脈を確認したいとき
  • 操作ごとのツールと結果を追いたいとき
lobehub/lobehub8.4万2026年10月26日 更新

lobehub のスキルをすべて見る

このスキルの問題を報告する