Plugins
هوکهای Plugin
هوکهای Plugin نقاط گسترش درونفرایندی برای Pluginهای OpenClaw هستند. زمانی از آنها استفاده کنید که یک Plugin نیاز دارد اجرای عاملها، فراخوانی ابزارها، جریان پیام، چرخه عمر نشست، مسیریابی زیرعامل، نصبها، یا راهاندازی Gateway را بررسی یا تغییر دهد.
وقتی یک اسکریپت کوچک HOOK.md نصبشده توسط اپراتور برای رویدادهای فرمان و Gateway مانند
/new، /reset، /stop، agent:bootstrap، یا gateway:startup میخواهید،
بهجای آن از هوکهای داخلی استفاده کنید.
شروع سریع
هوکهای تایپشده Plugin را با api.on(...) از ورودی Plugin خود ثبت کنید:
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 را بازنویسی میکند، و آن نیز مقدار
نوشتهشده توسط Plugin در api.on(..., { timeoutMs }) را بازنویسی میکند. هر مقدار پیکربندیشده باید
یک عدد صحیح مثبت و حداکثر برابر با 600000 میلیثانیه باشد. برای هوکهای کند شناختهشده، بازنویسیهای مخصوص هر هوک را ترجیح دهید
تا یک Plugin در همهجا بودجه طولانیتری نگیرد.
هر هوک event.context.pluginConfig را دریافت میکند؛ یعنی پیکربندی حلشده برای
Pluginی که آن گرداننده را ثبت کرده است. از آن برای تصمیمهای هوکی استفاده کنید که به
گزینههای فعلی Plugin نیاز دارند؛ OpenClaw آن را برای هر گرداننده تزریق میکند، بدون اینکه
شیء رویداد مشترک دیدهشده توسط دیگر Pluginها را تغییر دهد.
کاتالوگ هوکها
هوکها بر اساس سطحی که گسترش میدهند گروهبندی شدهاند. نامهای پررنگ یک نتیجه تصمیم را میپذیرند (مسدودسازی، لغو، بازنویسی، یا درخواست تأیید)؛ سایر موارد فقط برای مشاهده هستند.
نوبت عامل
before_model_resolve- بازنویسی ارائهدهنده یا مدل پیش از بارگذاری پیامهای نشستagent_turn_prepare- مصرف تزریقهای نوبت Plugin در صف و افزودن زمینه همان نوبت پیش از هوکهای پرامپتbefore_prompt_build- افزودن زمینه پویا یا متن پرامپت سیستمی پیش از فراخوانی مدلbefore_agent_start- فاز ترکیبی فقط برای سازگاری؛ دو هوک بالا را ترجیح دهیدbefore_agent_run- بررسی پرامپت نهایی و پیامهای نشست پیش از ارسال به مدل و، در صورت نیاز، مسدودکردن اجراbefore_agent_reply- کوتاهکردن نوبت مدل با یک پاسخ مصنوعی یا سکوتbefore_agent_finalize- بررسی پاسخ نهایی طبیعی و درخواست یک گذر دیگر مدلagent_end- مشاهده پیامهای نهایی، وضعیت موفقیت، و مدت اجراheartbeat_prompt_contribution- افزودن زمینه فقط مخصوص Heartbeat برای Pluginهای پایش پسزمینه و چرخه عمر
مشاهده مکالمه
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- مشارکت در خط لوله نهایی ارسال پاسخ
نشستها و Compaction
session_start/session_end- ردیابی مرزهای چرخه عمر نشستbefore_compaction/after_compaction- مشاهده یا حاشیهنویسی چرخههای Compactionbefore_reset- مشاهده رویدادهای بازنشانی نشست (/reset، بازنشانیهای برنامهنویسیشده)
زیرعاملها
subagent_spawning/subagent_delivery_target/subagent_spawned/subagent_ended- هماهنگکردن مسیریابی زیرعامل و تحویل تکمیل
چرخه عمر
gateway_start/gateway_stop- شروع یا توقف سرویسهای متعلق به Plugin همراه با Gatewaycron_changed- مشاهده تغییرات چرخه عمر Cron متعلق به Gateway (افزودهشده، بهروزرسانیشده، حذفشده، شروعشده، پایانیافته، زمانبندیشده)before_install- بررسی اسکنهای نصب Skills یا Plugin و، در صورت نیاز، مسدودکردن
سیاست فراخوانی ابزار
before_tool_call موارد زیر را دریافت میکند:
event.toolNameevent.paramsevent.runIdاختیاریevent.toolCallIdاختیاری- فیلدهای زمینه مانند
ctx.agentId،ctx.sessionKey،ctx.sessionId،ctx.runId،ctx.jobId(روی اجراهای هدایتشده با Cron تنظیم میشود)، و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";
pluginId?: string;
onResolution?: (
decision: "allow-once" | "allow-always" | "deny" | "timeout" | "cancelled",
) => Promise<void> | void;
};
};
قواعد:
block: trueپایانی است و گردانندههای با اولویت پایینتر را رد میکند.block: falseبهعنوان نبود تصمیم در نظر گرفته میشود.paramsپارامترهای ابزار را برای اجرا بازنویسی میکند.requireApprovalاجرای عامل را متوقف میکند و از کاربر از طریق تأییدهای Plugin درخواست میگیرد. فرمان/approveمیتواند هم تأییدهای exec و هم تأییدهای Plugin را تأیید کند.- یک
block: trueبا اولویت پایینتر همچنان میتواند پس از درخواست تأیید توسط یک هوک با اولویت بالاتر مسدود کند. onResolutionتصمیم تأیید حلشده را دریافت میکند -allow-once،allow-always،deny،timeout، یاcancelled.
Pluginهای همراه که به سیاست سطح میزبان نیاز دارند میتوانند سیاستهای ابزار مورد اعتماد را
با api.registerTrustedToolPolicy(...) ثبت کنند. اینها پیش از هوکهای معمولی
before_tool_call و پیش از تصمیمهای Plugin خارجی اجرا میشوند. فقط برای
دروازههای مورد اعتماد میزبان مانند سیاست فضای کاری، اعمال بودجه، یا
ایمنی جریانکاری رزروشده از آنها استفاده کنید. Pluginهای خارجی باید از هوکهای معمول
before_tool_call استفاده کنند.
ماندگارسازی نتیجه ابزار
نتایج ابزار میتوانند شامل details ساختاریافته برای رندر UI، تشخیصها،
مسیریابی رسانه، یا فراداده متعلق به Plugin باشند. با details بهعنوان فراداده زمان اجرا برخورد کنید،
نه محتوای پرامپت:
- OpenClaw پیش از بازپخش ارائهدهنده و ورودی Compaction،
toolResult.detailsرا حذف میکند تا فراداده به زمینه مدل تبدیل نشود. - ورودیهای نشست ماندگارشده فقط
detailsمحدود را نگه میدارند. جزئیات بیشازحد بزرگ با یک خلاصه فشرده وpersistedDetailsTruncated: trueجایگزین میشوند. tool_result_persistوbefore_message_writeپیش از سقف نهایی ماندگارسازی اجرا میشوند. هوکها همچنان بایدdetailsبرگشتی را کوچک نگه دارند و از قرار دادن متن مرتبط با پرامپت فقط درdetailsپرهیز کنند؛ خروجی ابزار قابل مشاهده برای مدل را درcontentبگذارید.
هوکهای پرامپت و مدل
برای Pluginهای جدید از هوکهای مخصوص هر فاز استفاده کنید:
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 برای سازگاری باقی میماند. هوکهای صریح بالا را ترجیح دهید
تا Plugin شما به یک فاز ترکیبی قدیمی وابسته نباشد.
before_agent_run پس از ساخت پرامپت و پیش از هر ورودی مدل اجرا میشود،
از جمله بارگذاری تصویر محلی پرامپت و مشاهده llm_input. این هوک
ورودی فعلی کاربر را بهعنوان prompt، بهعلاوه تاریخچه نشست بارگذاریشده در messages
و پرامپت سیستمی فعال دریافت میکند. برای توقف اجرا پیش از اینکه مدل بتواند پرامپت را بخواند،
{ outcome: "block", reason, message? } را برگردانید. reason داخلی است؛
message جایگزین روبهروی کاربر است. تنها نتایج پشتیبانیشده
pass و block هستند؛ شکلهای تصمیم پشتیبانینشده بسته شکست میخورند.
وقتی یک اجرا مسدود میشود، OpenClaw فقط متن جایگزین را در
message.content بههمراه فراداده مسدودسازی غیرحساس مانند شناسه Plugin مسدودکننده
و مهر زمانی ذخیره میکند. متن اصلی کاربر در رونویس یا زمینه آینده نگه داشته نمیشود.
دلایل مسدودسازی داخلی حساس در نظر گرفته میشوند و از بارهای رونویس،
تاریخچه، پخش، لاگ، و تشخیص حذف میشوند. مشاهدهپذیری باید از فیلدهای پاکسازیشده
مانند شناسه مسدودکننده، نتیجه، مهر زمانی، یا یک دستهبندی امن استفاده کند.
before_agent_start و agent_end زمانی event.runId را شامل میشوند که OpenClaw بتواند
اجرای فعال را شناسایی کند. همان مقدار روی ctx.runId نیز در دسترس است.
اجراهای هدایتشده با Cron همچنین ctx.jobId (شناسه کار Cron مبدأ) را آشکار میکنند تا
هوکهای Plugin بتوانند معیارها، اثرات جانبی، یا وضعیت را به یک کار زمانبندیشده مشخص محدود کنند.
برای اجراهای منشأگرفته از کانال، ctx.messageProvider سطح ارائهدهنده مانند
discord یا telegram است، درحالیکه ctx.channelId شناسه هدف مکالمه است
وقتی OpenClaw بتواند آن را از کلید نشست یا فراداده تحویل استخراج کند.
agent_end یک هوک مشاهده است و پس از نوبت بهصورت fire-and-forget اجرا میشود. اجراکننده
هوک یک زمانسنج 30 ثانیهای اعمال میکند تا یک Plugin گیرکرده یا نقطه پایانی embedding
نتواند promise هوک را برای همیشه در حالت معلق رها کند. timeout ثبت میشود و
OpenClaw ادامه میدهد؛ مگر اینکه خود Plugin نیز از سیگنال abort خود استفاده کند،
کار شبکهای متعلق به Plugin را لغو نمیکند.
برای دورسنجی فراخوانی ارائهدهنده که نباید پرامپتهای خام، تاریخچه، پاسخها، سربرگها، بدنههای درخواست،
یا شناسههای درخواست ارائهدهنده را دریافت کند، از model_call_started و model_call_ended استفاده کنید.
این هوکها شامل فراداده پایدار مانند
runId، callId، provider، model، api/transport اختیاری، مقدار پایانی
durationMs/outcome، و upstreamRequestIdHash هستند، وقتی OpenClaw بتواند یک
هش محدود شناسه درخواست ارائهدهنده را استخراج کند.
before_agent_finalize فقط زمانی اجرا میشود که یک harness در آستانه پذیرش یک
پاسخ نهایی طبیعی دستیار باشد. این مسیر لغو /stop نیست و زمانی که
کاربر یک نوبت را abort میکند اجرا نمیشود. برای درخواست یک گذر دیگر مدل از
harness پیش از نهاییسازی، { action: "revise", reason } را برگردانید؛ برای اجبار به نهاییسازی،
{ action: "finalize", reason? } را برگردانید؛ یا برای ادامه، نتیجهای برنگردانید.
هوکهای بومی Stop در Codex بهعنوان تصمیمهای
before_agent_finalize در OpenClaw به این هوک منتقل میشوند.
هنگام برگرداندن action: "revise"، Pluginها میتوانند فراداده retry را اضافه کنند تا
گذر اضافی مدل محدود و ایمن برای بازپخش باشد:
type BeforeAgentFinalizeRetry = {
instruction: string;
idempotencyKey?: string;
maxAttempts?: number;
};
instruction به دلیل بازبینیای که به هارنس ارسال میشود افزوده میشود.
idempotencyKey به میزبان اجازه میدهد تلاشهای دوباره برای همان درخواست Plugin را در تصمیمهای finalize معادل بشمارد، و maxAttempts محدود میکند میزبان پیش از ادامه دادن با پاسخ نهایی طبیعی، چند گذر اضافه را مجاز بداند.
Pluginهای غیرباندلشدهای که به قلابهای خام مکالمه (before_model_resolve,
before_agent_reply, llm_input, llm_output, before_agent_finalize,
agent_end، یا before_agent_run) نیاز دارند باید تنظیم کنند:
{
"plugins": {
"entries": {
"my-plugin": {
"hooks": {
"allowConversationAccess": true
}
}
}
}
}
قلابهایی که پرامپت را تغییر میدهند و تزریقهای پایدار نوبت بعدی را میتوان برای هر Plugin با plugins.entries.<id>.hooks.allowPromptInjection=false غیرفعال کرد.
افزونههای نشست و تزریقهای نوبت بعدی
Pluginهای گردش کار میتوانند وضعیت نشست کوچکِ سازگار با JSON را با api.registerSessionExtension(...) پایدار کنند و آن را از طریق متد sessions.pluginPatch در Gateway بهروزرسانی کنند. ردیفهای نشست، وضعیت افزونه ثبتشده را از طریق pluginExtensions نمایش میدهند و به Control UI و کلاینتهای دیگر اجازه میدهند وضعیت متعلق به Plugin را بدون دانستن جزئیات داخلی Plugin رندر کنند.
وقتی یک Plugin نیاز دارد زمینه پایدار دقیقاً یکبار به نوبت بعدی مدل برسد، از api.enqueueNextTurnInjection(...) استفاده کنید. OpenClaw تزریقهای صفشده را پیش از قلابهای پرامپت تخلیه میکند، تزریقهای منقضیشده را حذف میکند، و بر اساس idempotencyKey برای هر Plugin موارد تکراری را حذف میکند. این درز مناسب برای ازسرگیریهای تأیید، خلاصههای خطمشی، دلتاهای پایش پسزمینه، و ادامههای فرمانی است که باید در نوبت بعدی برای مدل قابل مشاهده باشند اما نباید به متن دائمی پرامپت سیستم تبدیل شوند.
معناشناسی پاکسازی بخشی از قرارداد است. پاکسازی افزونه نشست و کالبکهای پاکسازی چرخه عمر زمان اجرا reset، delete، disable، یا restart دریافت میکنند. میزبان وضعیت افزونه نشست پایدار متعلق به Plugin و تزریقهای در انتظار نوبت بعدی را برای reset/delete/disable حذف میکند؛ restart وضعیت نشست پایدار را نگه میدارد، در حالی که کالبکهای پاکسازی به Pluginها اجازه میدهند کارهای زمانبند، زمینه اجرا، و منابع خارج از باند دیگر را برای نسل قدیمی زمان اجرا آزاد کنند.
قلابهای پیام
از قلابهای پیام برای مسیریابی سطح کانال و خطمشی تحویل استفاده کنید:
message_received: محتوای ورودی، فرستنده،threadId،messageId،senderId، همبستگی اختیاری اجرا/نشست، و فراداده را مشاهده کنید.message_sending:contentرا بازنویسی کنید یا{ cancel: true }برگردانید.message_sent: موفقیت یا شکست نهایی را مشاهده کنید.
برای پاسخهای TTS فقط صوتی، content ممکن است حتی وقتی بار کانال متن/کپشن قابل مشاهده ندارد، رونوشت گفتاری پنهان را در خود داشته باشد. بازنویسی آن content فقط رونوشت قابل مشاهده برای قلاب را بهروزرسانی میکند؛ بهعنوان کپشن رسانه رندر نمیشود.
زمینههای قلاب پیام وقتی در دسترس باشند فیلدهای همبستگی پایدار را آشکار میکنند:
ctx.sessionKey، ctx.runId، ctx.messageId، ctx.senderId، ctx.trace،
ctx.traceId، ctx.spanId، ctx.parentSpanId، و ctx.callDepth. پیش از خواندن فراداده قدیمی، این فیلدهای درجهاول را ترجیح دهید.
پیش از استفاده از فراداده ویژه کانال، فیلدهای تایپشده threadId و replyToId را ترجیح دهید.
قواعد تصمیمگیری:
message_sendingباcancel: trueنهایی است.message_sendingباcancel: falseبهعنوان نبود تصمیم در نظر گرفته میشود.contentبازنویسیشده به قلابهای با اولویت پایینتر ادامه میدهد مگر اینکه قلابی بعدی تحویل را لغو کند.
قلابهای نصب
before_install پس از اسکن داخلی برای نصبهای Skills و Plugin اجرا میشود. یافتههای اضافی یا { block: true, blockReason } را برگردانید تا نصب متوقف شود.
block: true نهایی است. block: false بهعنوان نبود تصمیم در نظر گرفته میشود.
چرخه عمر Gateway
برای سرویسهای Plugin که به وضعیت متعلق به Gateway نیاز دارند، از gateway_start استفاده کنید. زمینه ctx.config، ctx.workspaceDir، و ctx.getCron?.() را برای بازرسی و بهروزرسانیهای cron آشکار میکند. برای پاکسازی منابع بلندمدت از gateway_stop استفاده کنید.
برای سرویسهای زمان اجرای متعلق به Plugin به قلاب داخلی gateway:startup تکیه نکنید.
cron_changed برای رویدادهای چرخه عمر cron متعلق به gateway با بار رویداد تایپشدهای اجرا میشود که دلیلهای added، updated، removed، started، finished، و scheduled را پوشش میدهد. رویداد یک اسنپشات PluginHookGatewayCronJob (شامل state.nextRunAtMs، state.lastRunStatus، و state.lastError در صورت وجود) بههمراه یک PluginHookGatewayCronDeliveryStatus از not-requested | delivered | not-delivered | unknown حمل میکند. رویدادهای حذفشده همچنان اسنپشات کار حذفشده را حمل میکنند تا زمانبندهای خارجی بتوانند وضعیت را همگام کنند. هنگام همگامسازی زمانبندهای بیدارباش خارجی، از ctx.getCron?.() و ctx.config از زمینه زمان اجرا استفاده کنید، و OpenClaw را منبع حقیقت برای بررسیهای موعد و اجرا نگه دارید.
منسوخسازیهای پیشرو
چند سطح مجاور قلاب منسوخ شدهاند اما هنوز پشتیبانی میشوند. پیش از انتشار اصلی بعدی مهاجرت کنید:
- پاکتهای کانال متن ساده در هندلرهای
inbound_claimوmessage_received. بهجای پارس کردن متن تخت پاکت،BodyForAgentو بلوکهای ساختیافته زمینه کاربر را بخوانید. ببینید پاکتهای کانال متن ساده ← BodyForAgent. before_agent_startبرای سازگاری باقی میماند. Pluginهای جدید باید بهجای فاز ترکیبی، ازbefore_model_resolveوbefore_prompt_buildاستفاده کنند.onResolutionدرbefore_tool_callاکنون بهجایstringآزاد، از union تایپشدهPluginApprovalResolution(allow-once/allow-always/deny/timeout/cancelled) استفاده میکند.
برای فهرست کامل - ثبت قابلیت حافظه، پروفایل تفکر ارائهدهنده، ارائهدهندگان احراز هویت خارجی، انواع کشف ارائهدهنده، دسترسیدهندههای زمان اجرای وظیفه، و تغییر نام command-auth به command-status - ببینید
مهاجرت SDK Plugin ← منسوخسازیهای فعال.
مرتبط
- مهاجرت SDK Plugin - منسوخسازیهای فعال و جدول زمانی حذف
- ساخت Pluginها
- نمای کلی SDK Plugin
- نقاط ورود Plugin
- قلابهای داخلی
- جزئیات داخلی معماری Plugin