Хуки Plugin є внутрішньопроцесними точками розширення для плагінів OpenClaw. Використовуйте їх, коли плагіну потрібно перевіряти або змінювати запуски агента, виклики інструментів, потік повідомлень, життєвий цикл сесії, маршрутизацію субагентів, встановлення або запуск Gateway. Натомість використовуйте внутрішні хуки, коли вам потрібен невеликий встановлений оператором скриптDocumentation 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 для подій команд і Gateway, як-от
/new, /reset, /stop, agent:bootstrap або gateway:startup.
Швидкий старт
Зареєструйте типізовані хуки плагіна за допомогоюapi.on(...) з точки входу вашого плагіна:
priority. Хуки з однаковим пріоритетом
зберігають порядок реєстрації.
api.on(name, handler, opts?) приймає:
priority- порядок обробників (вищий виконується першим).timeoutMs- необов’язковий бюджет для окремого хука. Якщо його задано, виконавець хуків перериває цей обробник після завершення бюджету й переходить до наступного, замість того щоб дозволити повільному налаштуванню або відновленню даних використати налаштований для викликача тайм-аут моделі. Не вказуйте його, щоб використати стандартний тайм-аут спостереження/рішення, який виконавець хуків застосовує загально.
hooks.timeouts.<hookName> перевизначає hooks.timeoutMs, який перевизначає
задане автором плагіна значення api.on(..., { timeoutMs }). Кожне налаштоване значення має
бути додатним цілим числом не більше ніж 600000 мілісекунд. Надавайте перевагу перевизначенням
для окремих хуків, якщо відомо, що вони повільні, щоб один плагін не отримував довший бюджет
усюди.
Кожен хук отримує event.context.pluginConfig, розв’язану конфігурацію для
плагіна, який зареєстрував цей обробник. Використовуйте її для рішень хука, яким потрібні
поточні параметри плагіна; OpenClaw впроваджує її для кожного обробника, не змінюючи
спільний об’єкт події, який бачать інші плагіни.
Каталог хуків
Хуки згруповано за поверхнею, яку вони розширюють. Назви, виділені жирним, приймають результат рішення (заблокувати, скасувати, перевизначити або вимагати схвалення); усі інші призначені лише для спостереження. Хід агентаbefore_model_resolve- перевизначити провайдера або модель до завантаження повідомлень сесіїagent_turn_prepare- спожити поставлені в чергу ін’єкції ходу плагіна й додати контекст того самого ходу перед хуками запитуbefore_prompt_build- додати динамічний контекст або текст системного запиту перед викликом моделіbefore_agent_start- комбінована фаза лише для сумісності; надавайте перевагу двом хукам вищеbefore_agent_run- перевірити фінальний запит і повідомлення сесії перед надсиланням моделі та за потреби заблокувати запускbefore_agent_reply- перервати хід моделі синтетичною відповіддю або тишеюbefore_agent_finalize- перевірити природну фінальну відповідь і запросити ще один прохід моделіagent_end- спостерігати фінальні повідомлення, стан успіху та тривалість запускуheartbeat_prompt_contribution- додати контекст лише для Heartbeat для фонових моніторів і плагінів життєвого циклу
model_call_started/model_call_ended- спостерігати санітизовані метадані виклику провайдера/моделі, час, результат і обмежені хеші ідентифікаторів запитів без вмісту запиту чи відповідіllm_input- спостерігати вхідні дані провайдера (системний запит, запит, історія)llm_output- спостерігати вихідні дані провайдера
before_tool_call- переписати параметри інструмента, заблокувати виконання або вимагати схваленняafter_tool_call- спостерігати результати інструмента, помилки й тривалістьtool_result_persist- переписати повідомлення асистента, створене з результату інструментаbefore_message_write- перевірити або заблокувати запис повідомлення, що виконується (рідко)
inbound_claim- перехопити вхідне повідомлення перед маршрутизацією агента (синтетичні відповіді)message_received- спостерігати вхідний вміст, відправника, гілку та метаданіmessage_sending- переписати вихідний вміст або скасувати доставленняmessage_sent- спостерігати успішне або невдале доставлення вихідного повідомленняbefore_dispatch- перевірити або переписати вихідне відправлення перед передаванням каналуreply_dispatch- брати участь у фінальному конвеєрі відправлення відповіді
session_start/session_end- відстежувати межі життєвого циклу сесії.reasonподії є одним ізnew,reset,idle,daily,compaction,deleted,shutdown,restartабоunknown. Значенняshutdownіrestartспрацьовують із фіналізатора завершення роботи Gateway, коли процес зупиняється або перезапускається, поки сесії ще активні, щоб нижчі плагіни (наприклад, сховища пам’яті або транскриптів) могли фіналізувати привидні рядки, які інакше залишилися б у відкритому стані після перезапусків. Фіналізатор обмежений, тому повільний плагін не може заблокувати SIGTERM/SIGINT.before_compaction/after_compaction- спостерігати або анотувати цикли Compactionbefore_reset- спостерігати події скидання сесії (/reset, програмні скидання)
subagent_spawning/subagent_delivery_target/subagent_spawned/subagent_ended- координувати маршрутизацію субагентів і доставлення завершення
gateway_start/gateway_stop- запускати або зупиняти сервіси, що належать плагіну, разом із Gatewaycron_changed- спостерігати зміни життєвого циклу Cron, що належать Gateway (додано, оновлено, видалено, запущено, завершено, заплановано)before_install- перевірити сканування встановлення навички або плагіна та за потреби заблокувати
Політика викликів інструментів
before_tool_call отримує:
event.toolNameevent.params- необов’язкове
event.derivedPaths, що містить найкращі можливі підказки цільових шляхів, отримані від хоста, для добре відомих оболонок інструментів, як-отapply_patch; коли вони присутні, ці шляхи можуть бути неповними або можуть надмірно приблизно описувати те, чого інструмент фактично торкнеться (наприклад, із некоректними або частковими вхідними даними) - необов’язкове
event.runId - необов’язкове
event.toolCallId - поля контексту, як-от
ctx.agentId,ctx.sessionKey,ctx.sessionId,ctx.runId,ctx.jobId(задається для запусків, керованих Cron), і діагностичнеctx.trace
block: trueє термінальним і пропускає обробники з нижчим пріоритетом.block: falseтрактується як відсутність рішення.paramsпереписує параметри інструмента для виконання.requireApprovalпризупиняє запуск агента й запитує користувача через схвалення плагінів. Команда/approveможе схвалювати як exec, так і схвалення плагінів.block: trueз нижчим пріоритетом усе ще може заблокувати після того, як хук із вищим пріоритетом запросив схвалення.onResolutionотримує розв’язане рішення схвалення -allow-once,allow-always,deny,timeoutабоcancelled.
api.registerTrustedToolPolicy(...). Вони виконуються перед звичайними
хуками before_tool_call і перед рішеннями зовнішніх плагінів. Використовуйте їх лише
для довірених хосту шлюзів, як-от політика робочого простору, контроль бюджету або
безпека зарезервованого робочого процесу. Зовнішні плагіни мають використовувати звичайні
хуки before_tool_call.
Збереження результатів інструментів
Результати інструментів можуть містити структурованіdetails для рендерингу UI, діагностики,
маршрутизації медіа або метаданих, що належать плагіну. Розглядайте details як метадані виконання,
а не як вміст запиту:
- OpenClaw вилучає
toolResult.detailsперед повторним відтворенням у провайдера та вхідними даними Compaction, щоб метадані не ставали контекстом моделі. - Збережені записи сесії залишають лише обмежені
details. Надмірно великі деталі замінюються компактним підсумком іpersistedDetailsTruncated: true. tool_result_persistіbefore_message_writeвиконуються перед фінальним обмеженням збереження. Хуки все одно мають тримати поверненіdetailsмалими й уникати розміщення тексту, релевантного для запиту, лише вdetails; розміщуйте видимий для моделі вихід інструмента вcontent.
Хуки запитів і моделі
Використовуйте фазоспецифічні хуки для нових плагінів:before_model_resolve: отримує лише поточний запит і метадані вкладень. ПовертаєproviderOverrideабоmodelOverride.agent_turn_prepare: отримує поточний запит, підготовлені повідомлення сесії та будь-які одноразові поставлені в чергу ін’єкції, вилучені для цієї сесії. ПовертаєprependContextабоappendContext.before_prompt_build: отримує поточний запит і повідомлення сесії. ПовертаєprependContext,appendContext,systemPrompt,prependSystemContextабоappendSystemContext.heartbeat_prompt_contribution: виконується лише для ходів Heartbeat і повертаєprependContextабоappendContext. Він призначений для фонових моніторів, яким потрібно підсумовувати поточний стан, не змінюючи ходи, ініційовані користувачем.
before_agent_start залишається для сумісності. Надавайте перевагу явним хукам вище,
щоб ваш плагін не залежав від застарілої комбінованої фази.
before_agent_run виконується після побудови запиту й перед будь-якими вхідними даними моделі,
зокрема завантаженням локальних для запиту зображень і спостереженням llm_input. Він отримує
поточний користувацький ввід як prompt, а також завантажену історію сесії в messages
і активний системний запит. Поверніть { outcome: "block", reason, message? },
щоб зупинити запуск до того, як модель зможе прочитати запит. reason є внутрішнім;
message є заміною, видимою користувачу. Єдині підтримувані результати -
pass і block; непідтримувані форми рішень завершуються закрито.
Коли запуск заблоковано, OpenClaw зберігає лише текст заміни в
message.content плюс нечутливі метадані блокування, як-от ідентифікатор плагіна, що блокує,
і мітку часу. Оригінальний текст користувача не зберігається в транскрипті або майбутньому
контексті. Внутрішні причини блокування вважаються чутливими й виключаються з
транскрипта, історії, трансляції, журналу та діагностичних корисних навантажень. Для спостережуваності
слід використовувати санітизовані поля, як-от ідентифікатор блокувальника, результат, мітка часу або безпечна
категорія.
before_agent_start і agent_end містять event.runId, коли OpenClaw може
ідентифікувати активний запуск. Те саме значення також доступне в ctx.runId.
Запуски, керовані Cron, також надають ctx.jobId (ідентифікатор вихідного завдання Cron), щоб
хуки плагінів могли прив’язувати метрики, побічні ефекти або стан до конкретного запланованого
завдання.
Для запусків, що походять із каналу, ctx.messageProvider є поверхнею провайдера, як-от
discord або telegram, тоді як ctx.channelId є цільовим ідентифікатором розмови,
коли OpenClaw може вивести його з ключа сесії або метаданих доставлення.
agent_end є хуком спостереження й виконується за принципом fire-and-forget після ходу. Виконавець
хуків застосовує тайм-аут 30 секунд, щоб завислий плагін або кінцева точка вбудовування
не могли залишити проміс хука в очікуванні назавжди. Тайм-аут записується в журнал, і
OpenClaw продовжує роботу; він не скасовує мережеву роботу, що належить плагіну, якщо
плагін також не використовує власний сигнал переривання.
Використовуйте model_call_started і model_call_ended для телеметрії викликів провайдера, яка не повинна отримувати сирі prompts, історію, відповіді, заголовки, тіла запитів або ідентифікатори запитів провайдера. Ці хуки містять стабільні метадані, як-от runId, callId, provider, model, необов’язкові api/transport, кінцеві durationMs/outcome і upstreamRequestIdHash, коли OpenClaw може вивести обмежений hash ідентифікатора запиту провайдера.
before_agent_finalize запускається лише тоді, коли harness ось-ось прийме природну фінальну відповідь assistant. Це не шлях скасування /stop, і він не запускається, коли користувач перериває turn. Поверніть { action: "revise", reason }, щоб попросити harness виконати ще один прохід моделі перед фіналізацією, { action: "finalize", reason? }, щоб примусово виконати фіналізацію, або не повертайте результат, щоб продовжити. Нативні хуки Codex Stop передаються в цей хук як рішення OpenClaw before_agent_finalize.
Коли повертається action: "revise", plugins можуть включити метадані retry, щоб зробити додатковий прохід моделі обмеженим і безпечним для повторного відтворення:
instruction додається до причини ревізії, надісланої до harness.
idempotencyKey дає хосту змогу рахувати повторні спроби для того самого запиту plugin у межах еквівалентних рішень фіналізації, а maxAttempts обмежує кількість додаткових проходів, які хост дозволить перед продовженням із природною фінальною відповіддю.
Non-bundled plugins, яким потрібні хуки сирої розмови (before_model_resolve,
before_agent_reply, llm_input, llm_output, before_agent_finalize,
agent_end або before_agent_run), мають задати:
plugins.entries.<id>.hooks.allowPromptInjection=false.
Розширення сесії та ін’єкції наступного turn
Workflow plugins можуть зберігати невеликий JSON-сумісний стан сесії за допомогоюapi.registerSessionExtension(...) і оновлювати його через метод Gateway sessions.pluginPatch. Рядки сесій проєктують зареєстрований стан розширення через pluginExtensions, даючи Control UI та іншим клієнтам змогу відображати статус, яким володіє plugin, без знання внутрішньої реалізації plugin.
Використовуйте api.enqueueNextTurnInjection(...), коли plugin потрібен тривалий контекст, який має потрапити в наступний turn моделі рівно один раз. OpenClaw вичерпує поставлені в чергу ін’єкції перед prompt-хуками, відкидає прострочені ін’єкції та дедуплікує за idempotencyKey для кожного plugin. Це правильний seam для відновлень після схвалення, підсумків політик, дельт фонового монітора та продовжень команд, які мають бути видимі моделі на наступному turn, але не повинні ставати постійним текстом system prompt.
Семантика очищення є частиною контракту. Колбеки очищення розширень сесії та очищення життєвого циклу runtime отримують reset, delete, disable або restart. Хост видаляє persistent стан розширення сесії plugin-власника та pending ін’єкції наступного turn для reset/delete/disable; restart зберігає тривалий стан сесії, тоді як колбеки очищення дають plugins змогу звільнити завдання планувальника, контекст виконання та інші позасмугові ресурси для старої генерації runtime.
Хуки повідомлень
Використовуйте хуки повідомлень для routing на рівні каналу та політики доставлення:message_received: спостерігає вхідний вміст, відправника,threadId,messageId,senderId, необов’язкову кореляцію run/session і метадані.message_sending: переписуєcontentабо повертає{ cancel: true }.message_sent: спостерігає фінальний успіх або помилку.
content може містити прихований озвучений transcript, навіть коли payload каналу не має видимого тексту/підпису. Переписування цього content оновлює лише transcript, видимий хуку; він не рендериться як media caption.
Контексти хуків повідомлень надають стабільні поля кореляції, коли вони доступні:
ctx.sessionKey, ctx.runId, ctx.messageId, ctx.senderId, ctx.trace,
ctx.traceId, ctx.spanId, ctx.parentSpanId і ctx.callDepth. Надавайте перевагу цим first-class полям перед читанням legacy metadata.
Надавайте перевагу typed полям threadId і replyToId перед використанням metadata, специфічних для каналу.
Правила ухвалення рішень:
message_sendingзcancel: trueє terminal.message_sendingзcancel: falseвважається відсутністю рішення.- Переписаний
contentпродовжує передаватися хукам нижчого пріоритету, якщо пізніший хук не скасує доставлення. message_sendingможе повернутиcancelReasonі обмеженіmetadataразом зі скасуванням. Нові API життєвого циклу повідомлень показують це як suppressed результат доставлення з причиноюcancelled_by_message_sending_hook; legacy direct delivery і надалі повертає порожній масив результатів для сумісності.message_sentпризначений лише для спостереження. Помилки handler логуються й не змінюють результат доставлення.
Хуки встановлення
before_install запускається після вбудованого сканування для встановлень skill і plugin. Поверніть додаткові знахідки або { block: true, blockReason }, щоб зупинити встановлення.
block: true є terminal. block: false вважається відсутністю рішення.
Життєвий цикл Gateway
Використовуйтеgateway_start для сервісів plugin, яким потрібен стан, що належить Gateway. Контекст надає ctx.config, ctx.workspaceDir і ctx.getCron?.() для перевірки й оновлень cron. Використовуйте gateway_stop, щоб очистити довготривалі ресурси.
Не покладайтеся на внутрішній хук gateway:startup для runtime-сервісів, якими володіє plugin.
cron_changed спрацьовує для подій життєвого циклу cron, якими володіє gateway, з typed payload події, що охоплює причини added, updated, removed, started, finished і scheduled. Подія несе snapshot PluginHookGatewayCronJob (включно з state.nextRunAtMs, state.lastRunStatus і state.lastError, коли вони наявні) плюс PluginHookGatewayCronDeliveryStatus зі значенням not-requested | delivered | not-delivered | unknown. Події видалення все одно несуть snapshot видаленого завдання, щоб зовнішні планувальники могли узгодити стан. Використовуйте ctx.getCron?.() і ctx.config з runtime-контексту під час синхронізації зовнішніх wake schedulers, і тримайте OpenClaw як джерело істини для перевірок due та виконання.
Майбутні припинення підтримки
Кілька поверхонь, суміжних із хуками, deprecated, але все ще підтримуються. Мігруйте до наступного major release:- Plaintext channel envelopes у handler
inbound_claimіmessage_received. ЧитайтеBodyForAgentі структуровані блоки user-context замість parsing flat envelope text. Див. Plaintext channel envelopes → BodyForAgent. before_agent_startзберігається для сумісності. Нові plugins мають використовуватиbefore_model_resolveіbefore_prompt_buildзамість combined phase.onResolutionуbefore_tool_callтепер використовує typed unionPluginApprovalResolution(allow-once/allow-always/deny/timeout/cancelled) замість free-formstring.
command-auth → command-status - див.
Міграція Plugin SDK → Активні припинення підтримки.
Пов’язане
- Міграція Plugin SDK - активні припинення підтримки та графік видалення
- Створення plugins
- Огляд Plugin SDK
- Точки входу Plugin
- Внутрішні хуки
- Внутрішня архітектура Plugin