Building plugins

قلاب‌های Plugin

قلاب‌های Plugin نقاط توسعهٔ درون‌پردازه‌ای برای Pluginهای OpenClaw هستند: اجرای عامل‌ها، فراخوانی ابزارها، جریان پیام، چرخهٔ عمر نشست، مسیریابی زیرعامل، نصب‌ها یا راه‌اندازی Gateway را بررسی یا تغییر می‌دهند.

برای واکنش یک اسکریپت کوچک HOOK.md نصب‌شده توسط اپراتور به رویدادهای فرمان و Gateway مانند /new، /reset، /stop، agent:bootstrap یا gateway:startup، در عوض از قلاب‌های داخلی استفاده کنید.

شروع سریع

قلاب‌های دارای نوع را با api.on(...) از ورودی Plugin ثبت کنید:

typescript
 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: "اجرای جست‌وجوی وب",            description: `اجازه به عبارت جست‌وجو: ${String(event.params.query ?? "")}`,            severity: "info",            timeoutMs: 60_000,          },        };      },      { priority: 50 },    );  },});

رسیدگی‌کننده‌هایی که می‌توانند تصمیم یا تغییر برگردانند، به‌ترتیب نزولی priority و به‌صورت متوالی اجرا می‌شوند؛ رسیدگی‌کننده‌های دارای اولویت یکسان، ترتیب ثبت را حفظ می‌کنند. رسیدگی‌کننده‌های صرفاً مشاهده‌ای به‌صورت موازی اجرا می‌شوند و ارسال‌های مشاهده‌ای بدون انتظار ممکن است با رویدادهای بعدی هم‌پوشانی داشته باشند. از اولویت برای مرتب‌سازی اثرات جانبی مشاهده استفاده نکنید.

api.on(name, handler, opts?) این گزینه‌ها را می‌پذیرد:

گزینه اثر
priority ترتیب؛ مقدار بالاتر زودتر اجرا می‌شود.
timeoutMs بودجهٔ انتظار برای هر قلاب. پس از پایان آن، OpenClaw دیگر منتظر آن رسیدگی‌کننده نمی‌ماند و ادامه می‌دهد. این کار رسیدگی‌کننده یا اثرات جانبی آن را لغو نمی‌کند. برای استفاده از مهلت پیش‌فرض اجراکننده برای هر قلاب، آن را حذف کنید.

اپراتورها می‌توانند بودجه‌های قلاب را بدون وصله‌کردن کد Plugin تنظیم کنند:

json
{  "plugins": {    "entries": {      "my-plugin": {        "hooks": {          "timeoutMs": 30000,          "timeouts": {            "before_prompt_build": 90000,            "agent_end": 60000          }        }      }    }  }}

hooks.timeouts.<hookName> بر hooks.timeoutMs اولویت دارد و آن نیز بر مقدار api.on(..., { timeoutMs }) نوشته‌شده توسط Plugin اولویت دارد. هر مقدار باید یک عدد صحیح مثبت تا 600000 ms باشد. برای قلاب‌هایی که کندبودنشان مشخص است، بازنویسی مختص هر قلاب را ترجیح دهید تا یک Plugin در همه‌جا بودجهٔ طولانی‌تری دریافت نکند.

Promise رسیدگی‌کننده‌ای که مهلتش تمام شده است همچنان به اجرا ادامه می‌دهد، زیرا فراخوان‌های قلاب سیگنال لغو دریافت نمی‌کنند. ارسال قلاب می‌تواند پذیرش Gateway خود را آزاد کند، درحالی‌که کار آن Plugin هنوز در حال انجام است. Pluginهایی که مالک کارهای طولانی‌مدت هستند باید چرخهٔ عمر لغو و خاموش‌سازی خود را فراهم کنند.

قلاب‌های تغییردهندهٔ خروجی message_sending و reply_payload_sending برای هر رسیدگی‌کننده از پیش‌فرض 15 ثانیه‌ای استفاده می‌کنند. اگر مهلت یکی تمام شود، OpenClaw خطای Plugin را ثبت می‌کند و با آخرین بار داده ادامه می‌دهد تا مسیر تحویل سریالی بتواند تسویه شود. برای Pluginهایی که عمداً پیش از تحویل کار کندتری انجام می‌دهند، بودجهٔ بیشتری برای هر قلاب تنظیم کنید.

Pluginهای کانالی که از createReplyDispatcher استفاده می‌کنند نیز می‌توانند با beforeDeliverOptions: { timeoutMs }، یا هنگام افزودن کار با dispatcher.appendBeforeDeliver(handler, { timeoutMs })، بودجهٔ مثبت بیشتری برای هر مرحله اعلام کنند. بدون بودجهٔ اعلام‌شده توسط مالک، این فراخوان‌ها از همان پیش‌فرض 15 ثانیه‌ای استفاده می‌کنند تا یک فراخوان متوقف‌شده نتواند مسیر تحویل سریالی را در اختیار نگه دارد.

هر قلاب event.context.pluginConfig، یعنی پیکربندی حل‌شده برای 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 خروجی ارائه‌دهنده، میزان استفاده و contextTokenBudget حل‌شده در صورت موجودبودن

ابزارها

قلاب هدف
before_tool_call بازنویسی پارامترهای ابزار، مسدودکردن اجرا یا نیاز به تأیید
after_tool_call مشاهدهٔ نتایج ابزار، خطاها و مدت‌زمان
resolve_exec_env افزودن متغیرهای محیطی متعلق به Plugin به exec
tool_result_persist بازنویسی پیام دستیار تولیدشده از نتیجهٔ ابزار
before_message_write بررسی یا مسدودکردن نوشتن پیام در حال انجام (نادر)

پیام‌ها و تحویل

قلاب هدف
inbound_claim دراختیارگرفتن پیام ورودی پیش از مسیریابی عامل (پاسخ‌های مصنوعی)
channel_pairing_requested مشاهدهٔ درخواست‌های جفت‌سازی پیام خصوصی تازه ایجادشده
message_received مشاهدهٔ محتوای ورودی، فرستنده، رشته و فراداده
message_sending بازنویسی محتوای خروجی یا لغو تحویل
reply_payload_sending تغییر یا لغو بارهای پاسخ نرمال‌شده پیش از تحویل
message_sent مشاهدهٔ موفقیت یا شکست تحویل خروجی
before_dispatch بررسی یا بازنویسی ارسال خروجی پیش از واگذاری به کانال
reply_dispatch مشارکت در خط لولهٔ نهایی ارسال پاسخ

نشست‌ها و Compaction

قلاب هدف
session_start / session_end ردیابی مرزهای چرخهٔ عمر نشست. reason یکی از new، reset، idle، daily، compaction، deleted، shutdown، restart یا unknown است. shutdown/restart هنگام توقف یا راه‌اندازی مجدد فرایند با نشست‌های فعال، از نهایی‌ساز خاموش‌سازی Gateway اجرا می‌شوند تا Pluginها (حافظه، مخازن رونوشت) بتوانند ردیف‌های سرگردان را نهایی کنند، به‌جای اینکه آن‌ها را بین راه‌اندازی‌های مجدد باز بگذارند. نهایی‌ساز محدود است تا یک Plugin کند نتواند SIGTERM/SIGINT را مسدود کند.
before_compaction / after_compaction مشاهده یا حاشیه‌نویسی چرخه‌های Compaction
before_reset مشاهدهٔ رویدادهای بازنشانی نشست (/reset، بازنشانی‌های برنامه‌نویسی‌شده)

زیرعامل‌ها

  • subagent_spawned / subagent_ended - راه‌اندازی و تکمیل زیرعامل را مشاهده می‌کند.
  • subagent_delivery_target - قلاب سازگاری برای تحویل تکمیل، هنگامی که هیچ اتصال نشست هسته‌ای نمی‌تواند مسیری را تصویر کند.
  • subagent_spawning - قلاب سازگاری منسوخ‌شده. اکنون هسته، اتصال‌های زیرعامل thread: true را پیش از فعال‌شدن subagent_spawned، از طریق سازگارکننده‌های اتصال نشست کانال آماده می‌کند.
  • subagent_spawned هنگامی که OpenClaw مدل بومی نشست فرزند را پیش از راه‌اندازی تعیین کرده باشد، شامل resolvedModel و resolvedProvider است.
  • subagent_ended شامل targetSessionKey (هویت - مطابق با subagent_spawned.childSessionKeytargetKind ("subagent" یا "acp"reason، مقدار اختیاری outcome ("ok"، "error"، "timeout"، "killed"، "reset" یا "deleted")، مقدار اختیاری error، runId، endedAt، accountId و sendFarewell است. این داده شامل agentId یا childSessionKey نیست؛ برای تطبیق آن با رویداد subagent_spawned متناظر، از targetSessionKey استفاده کنید.

چرخه حیات

قلاب هدف
gateway_start / gateway_stop آغاز یا توقف سرویس‌های تحت مالکیت Plugin همراه با Gateway
deactivate نام مستعار سازگاری منسوخ‌شده برای gateway_stop؛ در Pluginهای جدید از gateway_stop استفاده کنید
cron_reconciled تطبیق با وضعیت کامل Cron متعلق به Gateway پس از راه‌اندازی یا بارگذاری مجدد
cron_changed مشاهده تغییرات چرخه حیات Cron متعلق به Gateway (افزوده‌شده، به‌روزشده، حذف‌شده، آغازشده، پایان‌یافته، زمان‌بندی‌شده)
before_install بازرسی محتوای آماده‌شده برای نصب Skill یا Plugin از یک زمان‌اجرای Plugin بارگذاری‌شده

درخواست‌های جفت‌سازی کانال

هنگامی که یک Plugin باید پس از ایجاد درخواست جفت‌سازی در انتظار توسط فرستنده پیام خصوصی جفت‌نشده، به یک اپراتور اطلاع دهد یا رکورد ممیزی ثبت کند، از channel_pairing_requested استفاده کنید. قلاب هنگام ایجاد درخواست فراخوانی می‌شود؛ تحویل پاسخ جفت‌سازی از طریق کانال به‌دلیل کندی یا خرابی کنترل‌کننده‌های قلاب به تأخیر نمی‌افتد.

typescript
api.on("channel_pairing_requested", async (event) => {  await notifyOperator({    text: `درخواست جفت‌سازی جدید ${event.channel} از ${event.senderId}: ${event.code}`,  });});

این قلاب فقط برای مشاهده است. پاسخ جفت‌سازی را تأیید، رد، سرکوب یا بازنویسی نمی‌کند. بار داده شامل کانال، accountId اختیاری، senderId محدود به کانال، code جفت‌سازی و فراداده کانال است. کد جفت‌سازی را به‌عنوان یک اعتبارنامه تأیید یک‌بارمصرف و فعال در نظر بگیرید و آن را فقط به یک مقصد اپراتور مورداعتماد تحویل دهید. metadata را متن هویتی نامطمئنِ ارائه‌شده توسط فرستنده در نظر بگیرید. این قلاب شامل بدنه یا رسانه پیام ورودی نیست.

قلاب‌های اشکال‌زدایی زمان اجرا

برای تغییر ارائه‌دهنده یا مدل در یک نوبت عامل از before_model_resolve استفاده کنید؛ این قلاب پیش از تعیین مدل اجرا می‌شود. llm_output فقط پس از آن اجرا می‌شود که یک تلاش مدل خروجی دستیار تولید کند.

برای اثبات مدل مؤثر نشست، ثبت‌های زمان اجرا را بررسی کنید، سپس از openclaw sessions یا سطوح نشست/وضعیت Gateway استفاده کنید. برای اشکال‌زدایی بارهای داده ارائه‌دهنده، Gateway را با --raw-stream و --raw-stream-path <path> راه‌اندازی کنید تا رویدادهای خام جریان مدل در یک فایل jsonl نوشته شوند.

سیاست فراخوانی ابزار

before_tool_call موارد زیر را دریافت می‌کند:

  • event.toolName
  • event.params
  • event.toolKind و event.toolInputKind اختیاری، تمایزدهنده‌های تحت اختیار میزبان برای ابزارهایی که عمداً نام مشترک دارند؛ برای مثال، فراخوانی‌های بیرونی exec در حالت کد از toolKind: "code_mode_exec" استفاده می‌کنند و هنگامی که زبان ورودی مشخص باشد، شامل toolInputKind: "javascript" | "typescript" هستند
  • event.derivedPaths اختیاری، راهنمای مسیر مقصد با تلاش معقول و مشتق‌شده از میزبان برای پوش‌های ابزار شناخته‌شده مانند apply_patch؛ این مسیرها ممکن است ناقص باشند یا دامنه آنچه ابزار واقعاً تغییر می‌دهد را بیش از حد تخمین بزنند (برای مثال، در ورودی‌های ناقص یا بدساخت)
  • event.runId اختیاری
  • event.toolCallId اختیاری
  • فیلدهای زمینه مانند ctx.agentId، ctx.sessionKey، ctx.sessionId، ctx.runId، ctx.toolKind، ctx.toolInputKind و ctx.trace تشخیصی

می‌تواند مقدار زیر را بازگرداند:

typescript
type BeforeToolCallResult = {  params?: Record<string, unknown>;  block?: boolean;  blockReason?: string;  requireApproval?: {    title: string;    description: string;    severity?: "info" | "warning" | "critical";    timeoutMs?: number;    /** @deprecated تأییدهای حل‌نشده همیشه رد می‌شوند. */    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 را هر دو تأیید کند. در رله‌های بومی PreToolUse در حالت گزارش app-server مربوط به Codex، این کار به درخواست تأیید متناظر app-server واگذار می‌شود؛ به زمان‌اجرای مهار Codex مراجعه کنید.
  • یک block: true با اولویت پایین‌تر، پس از درخواست تأیید توسط قلابی با اولویت بالاتر، همچنان می‌تواند مسدود کند.
  • onResolution تصمیم نهایی را دریافت می‌کند: allow-once، allow-always، deny، timeout یا cancelled.

برای مسیریابی تأیید، رفتار تصمیم و زمان استفاده از requireApproval به‌جای ابزارهای اختیاری یا تأییدهای exec، به درخواست‌های مجوز Plugin مراجعه کنید.

Pluginهایی که به سیاست در سطح میزبان نیاز دارند، می‌توانند سیاست‌های ابزار مورداعتماد را با api.registerTrustedToolPolicy(...) ثبت کنند. این سیاست‌ها پیش از قلاب‌های معمولی before_tool_call و پیش از تصمیم‌های عادی قلاب اجرا می‌شوند. سیاست‌های مورداعتماد همراه نخست اجرا می‌شوند؛ سیاست‌های مورداعتماد Pluginهای نصب‌شده، سپس به‌ترتیب بارگذاری Plugin اجرا می‌شوند؛ قلاب‌های معمولی before_tool_call پس از آن‌ها اجرا می‌شوند. Pluginهای همراه، مسیر موجود سیاست مورداعتماد را حفظ می‌کنند. Pluginهای نصب‌شده باید به‌صراحت فعال شوند و هر شناسه سیاست را در contracts.trustedToolPolicies اعلام کنند؛ شناسه‌های اعلام‌نشده پیش از ثبت رد می‌شوند. شناسه‌های سیاست به Plugin ثبت‌کننده محدودند، بنابراین Pluginهای مختلف می‌توانند از شناسه محلی یکسانی دوباره استفاده کنند. از این سطح فقط برای دروازه‌های مورداعتماد میزبان، مانند سیاست فضای کاری، اعمال بودجه یا ایمنی گردش‌کارهای رزروشده استفاده کنید.

قلاب محیط exec

resolve_exec_env به Pluginها اجازه می‌دهد پیش از اجرای فرمان، متغیرهای محیطی را به فراخوانی‌های ابزار exec اضافه کنند. این قلاب موارد زیر را دریافت می‌کند:

  • event.sessionKey
  • event.toolName، که در حال حاضر همیشه "exec" است
  • event.host، یکی از "gateway"، "sandbox" یا "node"
  • فیلدهای زمینه مانند ctx.agentId، ctx.sessionKey، ctx.messageProvider و ctx.channelId

یک Record<string, string> برای ادغام در محیط exec بازگردانید. کنترل‌کننده‌ها به‌ترتیب اولویت اجرا می‌شوند؛ نتایج بعدی برای کلید یکسان، نتایج قبلی را بازنویسی می‌کنند.

خروجی قلاب پیش از ادغام، با سیاست کلید محیط exec میزبان پالایش می‌شود. PATH همیشه حذف می‌شود (تعیین فرمان و بررسی‌های safe-bin به آن وابسته‌اند). کلیدهای نامعتبر و کلیدهای خطرناک بازنویسی میزبان، مانند LD_*، DYLD_*، NODE_OPTIONS، متغیرهای پراکسی (HTTP_PROXY، HTTPS_PROXY، ALL_PROXY، NO_PROXY) و متغیرهای بازنویسی TLS (NODE_TLS_REJECT_UNAUTHORIZED، SSL_CERT_FILE و موارد مشابه) حذف می‌شوند. محیط پالایش‌شده Plugin در فراداده تأیید/ممیزی Gateway گنجانده و به درخواست‌های اجرای میزبان Node ارسال می‌شود.

ماندگاری نتیجه ابزار

نتایج ابزار می‌توانند شامل details ساختاریافته برای رندر رابط کاربری، تشخیص، مسیریابی رسانه یا فراداده تحت مالکیت 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 هنگامی که OpenClaw بتواند اجرای فعال را شناسایی کند، شامل event.runId هستند؛ همان مقدار در ctx.runId نیز وجود دارد. اجراهای ناشی از Cron همچنین ctx.jobId (شناسه کار Cron مبدأ) را در زمینه نوبت عامل نمایان می‌کنند تا قلاب‌ها بتوانند معیارها، عوارض جانبی یا وضعیت را به یک کار زمان‌بندی‌شده مشخص محدود کنند. ctx.jobId بخشی از زمینه ابزار before_tool_call نیست.

برای اجراهایی که از کانال آغاز می‌شوند، ctx.channel و ctx.messageProvider سطح ارائه‌دهنده مانند discord یا telegram را مشخص می‌کنند، درحالی‌که ctx.channelId شناسه مقصد مکالمه است، زمانی که OpenClaw بتواند آن را از کلید نشست یا فراداده تحویل استخراج کند.

وقتی هویت فرستنده در دسترس باشد، زمینه‌های هوک عامل همچنین شامل موارد زیر هستند:

  • ctx.senderId - شناسه فرستنده در محدوده کانال (برای مثال، Feishu open_id، شناسه کاربر Discord). زمانی مقداردهی می‌شود که اجرا از پیام کاربری با فراداده شناخته‌شده فرستنده آغاز شده باشد.
  • ctx.chatId - شناسه مکالمه بومیِ انتقال (برای مثال، Feishu chat_id، Telegram chat_id). زمانی مقداردهی می‌شود که کانال مبدأ یک شناسه مکالمه بومی ارائه کند.
  • ctx.channelContext.sender.id - همان شناسه فرستنده در ctx.senderId، درون یک شیء متعلق به کانال که Pluginها می‌توانند آن را با فیلدهای مختص کانال گسترش دهند.
  • ctx.channelContext.chat.id - همان شناسه مکالمه در ctx.chatId، درون یک شیء متعلق به کانال که Pluginها می‌توانند آن را با فیلدهای مختص کانال گسترش دهند.

هسته فقط فیلدهای تودرتوی id را تعریف می‌کند. Pluginهای کانال که فراداده غنی‌تر فرستنده یا گفت‌وگو را از طریق یاریگر ورودی عبور می‌دهند، می‌توانند PluginHookChannelSenderContext یا PluginHookChannelChatContext را از openclaw/plugin-sdk/channel-inbound گسترش دهند:

ts
declare module "openclaw/plugin-sdk/channel-inbound" {  interface PluginHookChannelSenderContext {    unionId?: string;    userId?: string;  }}

Pluginهای کانال آن فیلدها را از طریق یاریگر SDK ورودی عبور می‌دهند:

ts
buildChannelInboundEventContext({  // ...  channelContext: {    sender: { id: senderOpenId, unionId, userId },    chat: { id: chatId },  },});

این فیلدها اختیاری هستند و برای اجراهایی با مبدأ سیستمی (heartbeat، cron، exec-event) وجود ندارند.

ctx.senderExternalId به‌عنوان فیلد منسوخ‌شده سازگاری منبع برای Pluginهای قدیمی باقی می‌ماند. هسته آن را مقداردهی نمی‌کند؛ هویت‌های جدید فرستنده مختص کانال باید از طریق گسترش ماژول زیر ctx.channelContext.sender قرار گیرند.

agent_end یک هوک مشاهده است. مسیرهای Gateway و هارنس ماندگار، آن را پس از نوبت به‌صورت اجرا و فراموش اجرا می‌کنند، درحالی‌که مسیرهای کوتاه‌عمر و تک‌اجرای CLI پیش از پاک‌سازی فرایند منتظر Promise هوک می‌مانند تا Pluginهای مورد اعتماد بتوانند داده‌های مشاهده‌پذیری پایانه را تخلیه کنند یا وضعیت را ثبت کنند. اجراکننده هوک یک مهلت زمانی 30 ثانیه‌ای اعمال می‌کند تا یک Plugin قفل‌شده یا نقطه پایانی تعبیه نتواند Promise هوک را برای همیشه در حالت انتظار باقی بگذارد. پایان مهلت ثبت می‌شود و OpenClaw ادامه می‌دهد؛ این وضعیت کار شبکه‌ای متعلق به Plugin را لغو نمی‌کند، مگر اینکه خود Plugin نیز از سیگنال لغو اختصاصی‌اش استفاده کند.

از model_call_started و model_call_ended برای تله‌متری فراخوانی ارائه‌دهنده استفاده کنید که نباید پرامپت‌های خام، تاریخچه، پاسخ‌ها، سرآیندها، بدنه درخواست‌ها یا شناسه‌های درخواست ارائه‌دهنده را دریافت کند. این هوک‌ها شامل فراداده پایدار مانند runId، callId، provider، model، موارد اختیاری api/transport، مقادیر پایانی durationMs/outcome و upstreamRequestIdHash هستند، زمانی که OpenClaw بتواند یک هش کران‌دار از شناسه درخواست ارائه‌دهنده استخراج کند. وقتی زمان اجرا فراداده پنجره زمینه را تفکیک کرده باشد، رویداد و زمینه هوک همچنین شامل contextTokenBudget، یعنی بودجه مؤثر توکن پس از سقف‌های مدل/پیکربندی/عامل، و نیز contextWindowSource و contextWindowReferenceTokens در صورت اعمال سقفی پایین‌تر خواهند بود.

before_agent_finalize فقط زمانی اجرا می‌شود که یک هارنس در آستانه پذیرش پاسخ نهایی طبیعی دستیار باشد. این مسیر لغو /stop نیست و هنگام لغو یک نوبت توسط کاربر اجرا نمی‌شود. برای درخواست یک گذر دیگر مدل از هارنس پیش از نهایی‌سازی، { action: "revise", reason } را بازگردانید؛ برای اجبار نهایی‌سازی، { action: "finalize", reason? } را بازگردانید؛ یا برای ادامه، نتیجه‌ای ارائه نکنید. کنترل‌کننده‌ها به‌طور پیش‌فرض بودجه 15s دارند؛ در صورت پایان مهلت، OpenClaw شکست را ثبت می‌کند و با پاسخ نهایی اولیه ادامه می‌دهد. هوک‌های بومی Stop در Codex به این هوک در قالب تصمیم‌های before_agent_finalize در OpenClaw منتقل می‌شوند.

هنگام بازگرداندن action: "revise"، Pluginها می‌توانند فراداده retry را اضافه کنند تا گذر اضافی مدل کران‌دار و در برابر بازپخش ایمن باشد:

typescript
type BeforeAgentFinalizeRetry = {  instruction: string;  idempotencyKey?: string;  maxAttempts?: number;};

instruction به دلیل بازبینی ارسال‌شده به هارنس افزوده می‌شود. idempotencyKey به میزبان امکان می‌دهد تلاش‌های مجدد برای درخواست یکسان Plugin را در میان تصمیم‌های نهایی‌سازی هم‌ارز بشمارد و maxAttempts تعداد گذرهای اضافی مجاز میزبان را پیش از ادامه با پاسخ نهایی طبیعی محدود می‌کند.

Pluginهای غیرباندل‌شده‌ای که به هوک‌های خام مکالمه (before_model_resolve، before_agent_reply، llm_input، llm_output، before_agent_finalize، agent_end یا before_agent_run) نیاز دارند، باید این مقدار را تنظیم کنند:

json
{  "plugins": {    "entries": {      "my-plugin": {        "hooks": {          "allowConversationAccess": true        }      }    }  }}

هوک‌های تغییردهنده پرامپت و تزریق‌های ماندگار نوبت بعد را می‌توان برای هر Plugin با plugins.entries.<id>.hooks.allowPromptInjection=false غیرفعال کرد.

افزونه‌های نشست و تزریق‌های نوبت بعد

Pluginهای گردش‌کار می‌توانند وضعیت کوچک و سازگار با JSON نشست را با api.session.state.registerSessionExtension(...) ماندگار کنند و آن را از طریق متد sessions.pluginPatch در Gateway به‌روزرسانی کنند. ردیف‌های نشست، وضعیت افزونه ثبت‌شده را از طریق pluginExtensions ارائه می‌کنند و به Control UI و سایر کلاینت‌ها اجازه می‌دهند وضعیت متعلق به Plugin را بدون آگاهی از جزئیات داخلی Plugin رندر کنند. api.registerSessionExtension(...) همچنان کار می‌کند، اما به‌نفع فضای نام api.session.state منسوخ شده است.

وقتی یک Plugin به زمینه‌ای ماندگار نیاز دارد که دقیقاً یک‌بار به نوبت بعدی مدل برسد، از api.session.workflow.enqueueNextTurnInjection(...) استفاده کنید (api.enqueueNextTurnInjection(...) سطح‌بالا یک نام مستعار منسوخ‌شده با همان رفتار است). OpenClaw تزریق‌های صف‌شده را پیش از هوک‌های پرامپت تخلیه می‌کند، تزریق‌های منقضی را کنار می‌گذارد و برای هر Plugin بر اساس idempotencyKey تکراری‌ها را حذف می‌کند. این نقطه اتصال مناسب برای ازسرگیری تأییدها، خلاصه‌های خط‌مشی، تغییرات پایشگر پس‌زمینه و ادامه فرمان‌هایی است که باید در نوبت بعدی برای مدل قابل مشاهده باشند، اما نباید به متن دائمی پرامپت سیستم تبدیل شوند.

معناشناسی پاک‌سازی بخشی از قرارداد است. فراخوان‌های بازگشتی پاک‌سازی افزونه نشست و چرخه عمر زمان اجرا، reset، delete، disable یا restart را دریافت می‌کنند. میزبان برای بازنشانی/حذف/غیرفعال‌سازی، وضعیت ماندگار افزونه نشست و تزریق‌های در انتظار نوبت بعد متعلق به Plugin را حذف می‌کند؛ راه‌اندازی مجدد وضعیت ماندگار نشست را نگه می‌دارد، درحالی‌که فراخوان‌های بازگشتی پاک‌سازی به Pluginها امکان می‌دهند کارهای زمان‌بند، زمینه اجرا و دیگر منابع خارج از مسیر اصلی مربوط به نسل قبلی زمان اجرا را آزاد کنند.

هوک‌های پیام

از هوک‌های پیام برای مسیریابی و خط‌مشی تحویل در سطح کانال استفاده کنید:

  • message_received: محتوای ورودی، فرستنده، threadId، messageId، senderId، هم‌بستگی اختیاری اجرا/نشست و فراداده را مشاهده می‌کند.
  • message_sending: ‏content را بازنویسی می‌کند یا { cancel: true } را بازمی‌گرداند.
  • reply_payload_sending: اشیای نرمال‌شده ReplyPayload (از جمله presentation، delivery، ارجاع‌های رسانه و متن) را بازنویسی می‌کند یا { cancel: true } را بازمی‌گرداند.
  • message_sent: موفقیت یا شکست نهایی را مشاهده می‌کند.

برای پاسخ‌های TTS صرفاً صوتی، content ممکن است شامل رونوشت گفتاری پنهان باشد، حتی زمانی که بار کانال هیچ متن/زیرنویس قابل مشاهده‌ای ندارد. بازنویسی آن content فقط رونوشت قابل مشاهده برای هوک را به‌روزرسانی می‌کند؛ این مقدار به‌عنوان زیرنویس رسانه رندر نمی‌شود.

رویدادهای reply_payload_sending ممکن است شامل usageState باشند؛ تصویری لحظه‌ای و با بهترین تلاش از مدل/مصرف/زمینه برای هر نوبت. تحویل ماندگار، بازپخش بازیابی‌شده و پاسخ‌های فاقد هم‌بستگی دقیق اجرا آن را ارائه نمی‌کنند.

زمینه‌های هوک پیام در صورت دسترس‌پذیری، فیلدهای هم‌بستگی پایدار زیر را ارائه می‌کنند: ctx.sessionKey، ctx.runId، ctx.messageId، ctx.senderId، ctx.trace، ctx.traceId، ctx.spanId، ctx.parentSpanId و ctx.callDepth. زمینه‌های ورودی و before_dispatch همچنین زمانی که کانال داده پیام نقل‌قول‌شده و فیلترشده بر اساس قابلیت مشاهده داشته باشد، فراداده پاسخ را ارائه می‌کنند: replyToId، replyToIdFull، replyToBody، replyToSender و replyToIsQuote. پیش از خواندن فراداده قدیمی، این فیلدهای سطح‌اول را ترجیح دهید.

پیش از استفاده از فراداده مختص کانال، فیلدهای نوع‌دار threadId و replyToId را ترجیح دهید.

قواعد تصمیم‌گیری:

  • message_sending همراه با cancel: true پایانی است.
  • message_sending همراه با cancel: false به‌عنوان بدون تصمیم در نظر گرفته می‌شود.
  • content بازنویسی‌شده به هوک‌های با اولویت پایین‌تر ادامه می‌یابد، مگر اینکه هوکی بعدی تحویل را لغو کند.
  • reply_payload_sending پس از نرمال‌سازی بار و پیش از تحویل کانال اجرا می‌شود، از جمله برای پاسخ‌هایی که به کانال مبدأ بازگردانده می‌شوند. کنترل‌کننده‌ها به‌ترتیب اجرا می‌شوند و هر کنترل‌کننده آخرین بار تولیدشده توسط کنترل‌کننده‌های با اولویت بالاتر را می‌بیند.
  • بارهای reply_payload_sending نشانگرهای اعتماد زمان اجرا مانند trustedLocalMedia را ارائه نمی‌کنند؛ Pluginها می‌توانند شکل بار را ویرایش کنند، اما نمی‌توانند به رسانه محلی اعتماد اعطا کنند.
  • message_sending می‌تواند همراه با لغو، cancelReason و metadata کران‌دار را بازگرداند. APIهای جدید چرخه عمر پیام، این وضعیت را به‌صورت نتیجه تحویل سرکوب‌شده با دلیل cancelled_by_message_sending_hook ارائه می‌کنند؛ تحویل مستقیم قدیمی برای سازگاری همچنان آرایه نتیجه خالی بازمی‌گرداند.
  • message_sent فقط برای مشاهده است. شکست کنترل‌کننده‌ها ثبت می‌شود و نتیجه تحویل را تغییر نمی‌دهد.

هوک‌های نصب

از security.installPolicy برای تصمیم‌های مجاز/مسدودسازی متعلق به اپراتور استفاده کنید. آن خط‌مشی از پیکربندی OpenClaw اجرا می‌شود، مسیرهای نصب و به‌روزرسانی CLI را پوشش می‌دهد و در صورت فعال‌بودن اما دردسترس‌نبودن، به‌صورت بسته شکست می‌خورد.

before_install یک هوک چرخه عمر زمان اجرای Plugin است. این هوک فقط پس از security.installPolicy در همان فرایند OpenClaw اجرا می‌شود که هوک‌های Plugin از قبل در آن بارگذاری شده‌اند، مانند جریان‌های نصب مبتنی بر Gateway. این هوک برای مشاهدات، هشدارها و بررسی‌های سازگاری متعلق به Plugin مفید است، اما مرز امنیتی اصلی سازمان یا میزبان برای نصب‌ها نیست. فیلد builtinScan برای سازگاری در بار رویداد باقی می‌ماند، اما OpenClaw دیگر مسدودسازی داخلی کد خطرناک هنگام نصب را اجرا نمی‌کند؛ بنابراین این فیلد یک نتیجه خالی ok است. برای توقف نصب در آن فرایند، یافته‌های اضافی یا { block: true, blockReason } را بازگردانید.

block: true پایانی است. block: false به‌عنوان بدون تصمیم در نظر گرفته می‌شود. شکست کنترل‌کننده‌ها نصب را به‌صورت بسته مسدود می‌کند.

چرخه عمر Gateway

از gateway_start برای شروع سرویس‌های عمومی Plugin و از gateway_stop برای پاک‌سازی منابع بلندمدت استفاده کنید. ممکن است زمان‌بند Cron هنگام اجرای gateway_start همچنان در حال بارگذاری باشد؛ بنابراین از آن به‌عنوان سیگنال مبنا برای یک تصویرسازی خارجی Cron استفاده نکنید.

برای سرویس‌های زمان اجرای متعلق به Plugin به هوک داخلی gateway:startup متکی نباشید.

cron_reconciled پس از آن فعال می‌شود که زمان‌بند Cron در Gateway و ناظران هنگام خروج آن، وضعیت ماندگار خود را تطبیق داده باشند. این هوک هم برای راه‌اندازی اولیه و هم برای جایگزینی زمان‌بند هنگام بارگذاری مجدد پیکربندی فعال می‌شود. رویداد، reason (startup یا reload) و وضعیت مؤثر enabled را گزارش می‌کند. Cron غیرفعال نیز همچنان با enabled: false رویداد منتشر می‌کند و به یک تصویرسازی خارجی امکان می‌دهد بیدارباش‌های منسوخ را پاک کند. برای اشاره به نمونه دقیق زمان‌بندی که تطبیق را تکمیل کرده است، از ctx.getCron?.() استفاده کنید؛ بارگذاری مجدد بعدی آن فراخوان بازگشتی را به هدف دیگری هدایت نمی‌کند. ctx.abortSignal مالک همان تصویر لحظه‌ای زمان‌بند است. Gateway به‌محض آماده‌شدن زمان‌بندی جدیدتر یا آغاز خاموش‌شدن، آن را لغو می‌کند. آن را از همه عوارض جانبی ماندگار عبور دهید و پس از لغوشدن، تصویر لحظه‌ای را نپذیرید. این یک سیگنال چرخه عمر زمان‌بند است، نه سیگنال فعال‌سازی Plugin: بارگذاری مجدد داغِ صرفاً Plugin آن را دوباره اجرا نمی‌کند. یک مصرف‌کننده تازه‌فعال‌شده، نخستین مبنای خود را هنگام جایگزینی بعدی زمان‌بند یا شروع Gateway دریافت می‌کند.

مانند سایر هوک‌های مشاهده، فراخوان‌های بازگشتی gateway_start و cron_reconciled می‌توانند هم‌پوشانی داشته باشند. اگر هر دو کنترل‌کننده مقداردهی اولیه مشترکی برای Plugin دارند، به‌جای وابستگی به ترتیب فراخوان‌های بازگشتی، آن‌ها را با یک Promise آمادگی محلیِ Plugin هماهنگ کنید.

cron_changed برای رویدادهای چرخه‌عمر Cron تحت مالکیت Gateway فعال می‌شود و محموله‌ای از نوع مشخص دارد که دلایل added، updated، removed، started، finished، و scheduled را پوشش می‌دهد. این رویداد یک عکس فوری PluginHookGatewayCronJob (شامل state.nextRunAtMs، state.lastRunStatus و state.lastError در صورت وجود) به‌همراه یک PluginHookGatewayCronDeliveryStatus از not-requested | delivered | not-delivered | unknown حمل می‌کند. رویدادهای حذف پس از ثبت نهایی رخ می‌دهند: آن‌ها تنها پس از موفقیت حذف ماندگار فعال می‌شوند و همچنان عکس فوری کار حذف‌شده را حمل می‌کنند تا زمان‌بندهای خارجی بتوانند وضعیت را تطبیق دهند.

یک رویداد scheduled پس از ثبت نهایی رخ می‌دهد: تنها پس از آن فعال می‌شود که یک نوشتن ماندگار موفق، nextRunAtMs مؤثر یک کار موجود را تغییر دهد؛ رویداد صریح چرخه‌عمر added، updated یا removed آن کار مستثنا است. مقدار سطح‌بالای event.nextRunAtMs بیدارباش بعدی ثبت‌شده است؛ در صورت نبود آن، کار بیدارباش بعدی ندارد. این رویدادها را راهنمای تطبیق در نظر بگیرید، نه یک گزارش مرتب‌شده از تغییرات. از آن‌ها به‌عنوان راهنماهایی قابل‌ادغام برای بازخوانی زمان‌بندی استفاده کنید که آخرین‌بار توسط cron_reconciled ثبت شده است؛ زمان‌بند را از یک زمینه cron_changed نپذیرید. OpenClaw را منبع حقیقت برای بررسی موعدها و اجرا نگه دارید.

برون‌نمایی امن Cron خارجی

به‌جای ارسال تغییرات رویداد Cron، یک عکس فوری کامل از بیدارباش‌ها را برون‌نمایی کنید. عملیات replaceAll در آداپتور خارجی باید اتمی و تکرارپذیر باشد و تنها پس از آن پایان یابد که میزبان عکس فوری را به‌صورت ماندگار پذیرفته باشد. همچنین باید سیگنال لغو ارائه‌شده را رعایت کند: اگر سیگنال پیش از پذیرش ماندگار لغو شود، آداپتور نباید آن عکس فوری را بپذیرد.

این الگو تنها یک کارگر با آخرین وضعیت را در حال اجرا نگه می‌دارد. فقط cron_reconciled یک نمونه زمان‌بند را می‌پذیرد؛ cron_changed صرفاً از آن کارگر می‌خواهد نمونه معتبر را دوباره بخواند، بنابراین یک راهنمای دیرهنگام نمی‌تواند زمان‌بندی قدیمی‌تر را بازیابی کند. یک بازبینی جدیدتر، تلاش فعال میزبان را پیش از آنکه بتواند عکس فوری کهنه‌ای را بپذیرد لغو می‌کند.

typescript
  type ExternalWake = { jobId: string; runAtMs: number }; type ExternalWakeHost = {  replaceAll(wakes: readonly ExternalWake[], options: { signal: AbortSignal }): Promise<void>;  close(): Promise<void>;}; type CronReader = {  list(options: { includeDisabled: true }): Promise<    Array<{      id: string;      enabled?: boolean;      state?: { nextRunAtMs?: number };    }>  >;}; export function registerCronProjection(api: OpenClawPluginApi, host: ExternalWakeHost) {  const lifecycle = new AbortController();  let cron: CronReader | undefined;  let enabled = false;  let hasBaseline = false;  let reconciliationSignal: AbortSignal | undefined;  let requestedRevision = 0;  let appliedRevision = 0;  let worker = Promise.resolve();  let activeAttempt: AbortController | undefined;   const projectLatest = async () => {    let retryMs = 1_000;     while (!lifecycle.signal.aborted && appliedRevision < requestedRevision) {      const ownerSignal = reconciliationSignal;      if (!ownerSignal || ownerSignal.aborted) {        return;      }      const targetRevision = requestedRevision;      const attempt = new AbortController();      const signal = AbortSignal.any([lifecycle.signal, ownerSignal, attempt.signal]);      activeAttempt = attempt;       try {        const jobs = enabled && cron ? await cron.list({ includeDisabled: true }) : [];        if (signal.aborted || targetRevision !== requestedRevision) {          continue;        }        const wakes = jobs          .flatMap((job): ExternalWake[] => {            const runAtMs = job.enabled === false ? undefined : job.state?.nextRunAtMs;            return runAtMs === undefined ? [] : [{ jobId: job.id, runAtMs }];          })          .sort((a, b) => a.runAtMs - b.runAtMs || a.jobId.localeCompare(b.jobId));         await host.replaceAll(wakes, { signal });        if (signal.aborted || targetRevision !== requestedRevision) {          continue;        }        appliedRevision = targetRevision;        retryMs = 1_000;      } catch {        if (lifecycle.signal.aborted || ownerSignal.aborted) {          return;        }        if (attempt.signal.aborted) {          continue;        }        api.logger.warn(`external cron projection failed; retrying in ${retryMs}ms`);        try {          await sleep(retryMs, undefined, { signal });        } catch {          if (lifecycle.signal.aborted) {            return;          }          if (attempt.signal.aborted) {            continue;          }        }        retryMs = Math.min(retryMs * 2, 30_000);      } finally {        if (activeAttempt === attempt) {          activeAttempt = undefined;        }      }    }  };   const requestProjection = () => {    const targetRevision = ++requestedRevision;    activeAttempt?.abort();    worker = worker.then(async () => {      if (!lifecycle.signal.aborted && appliedRevision < targetRevision) {        await projectLatest();      }    });    return worker;  };   api.on("cron_reconciled", (event, ctx) => {    const reconciledCron = ctx.getCron?.();    if (event.enabled && !reconciledCron) {      api.logger.warn("cron reconciliation did not expose a scheduler");      return;    }    cron = reconciledCron;    enabled = event.enabled;    hasBaseline = true;    reconciliationSignal = ctx.abortSignal;    return requestProjection();  });   api.on("cron_changed", () => {    if (hasBaseline) {      return requestProjection();    }  });   api.on("gateway_stop", async () => {    lifecycle.abort();    await worker;    await host.close();  });}

وقتی cron_reconciled مقدار enabled: false را گزارش می‌کند، همان مسیر replaceAll([]) را فراخوانی کرده و بیدارباش‌های خارجی کهنه را پاک می‌کند. تلاش مجدد/عقب‌نشینی در این مثال محلیِ فرایند است و خرابی‌های آداپتور زمان اجرا را موقتی در نظر می‌گیرد؛ پیکربندی‌های غیرقابل‌تلاش‌مجدد را پیش از ثبت اعتبارسنجی کنید. OpenClaw برای اثرات هوک Plugin صندوق خروجی فراهم نمی‌کند. اگر فرایند پیش از پذیرش ماندگار خارج شود، شروع بعدی Gateway یک عکس فوری معتبر جدید cron_reconciled منتشر می‌کند. gateway_stop کار در حال اجرای میزبان را لغو می‌کند، منتظر پایان کارگر می‌ماند، سپس آداپتور را می‌بندد.

منسوخ‌سازی‌های پیش رو

چند سطح مرتبط با هوک منسوخ شده‌اند، اما همچنان پشتیبانی می‌شوند. پیش از نسخه اصلی بعدی مهاجرت کنید:

  • پاکت‌های متن ساده کانال در هندلرهای inbound_claim و message_received. به‌جای تجزیه متن مسطح پاکت، BodyForAgent و بلوک‌های ساختاریافته زمینه کاربر را بخوانید. بنگرید به پاکت‌های متن ساده کانال ← BodyForAgent.
  • before_agent_start برای سازگاری باقی می‌ماند. Pluginهای جدید باید به‌جای مرحله ترکیبی از before_model_resolve و before_prompt_build استفاده کنند.
  • subagent_spawning برای سازگاری با Pluginهای قدیمی‌تر باقی می‌ماند، اما Pluginهای جدید نباید مسیریابی رشته را از آن بازگردانند. هسته اتصال‌های زیرعامل thread: true را از طریق آداپتورهای اتصال نشست کانال پیش از فعال‌شدن subagent_spawned آماده می‌کند.
  • deactivate تا پس از 2026-08-16 به‌عنوان نام مستعار منسوخ‌شده سازگاری پاک‌سازی باقی می‌ماند. Pluginهای جدید باید از gateway_stop استفاده کنند.
  • onResolution در before_tool_call اکنون به‌جای یک string آزاد از اجتماع نوع‌دار PluginApprovalResolution (allow-once / allow-always / deny / timeout / cancelled) استفاده می‌کند.
  • api.registerSessionExtension / api.enqueueNextTurnInjection به‌عنوان نام‌های مستعار سازگاری سطح‌بالا باقی می‌مانند. Pluginهای جدید باید از api.session.state.registerSessionExtension(...) و api.session.workflow.enqueueNextTurnInjection(...) استفاده کنند.

برای فهرست کامل — ثبت قابلیت حافظه، نمایه تفکر ارائه‌دهنده، ارائه‌دهندگان احراز هویت خارجی، انواع کشف ارائه‌دهنده، دسترسی‌دهنده‌های زمان اجرای وظیفه و تغییر نام command-authcommand-status — بنگرید به مهاجرت SDK افزونه ← منسوخ‌سازی‌های فعال.

مرتبط

Was this useful?
On this page

On this page