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 - مشاهده یا حاشیه‌نویسی چرخه‌های Compaction
  • before_reset - مشاهده رویدادهای بازنشانی نشست (/reset، بازنشانی‌های برنامه‌نویسی‌شده)

زیرعامل‌ها

  • subagent_spawning / subagent_delivery_target / subagent_spawned / subagent_ended - هماهنگ‌کردن مسیریابی زیرعامل و تحویل تکمیل

چرخه عمر

  • gateway_start / gateway_stop - شروع یا توقف سرویس‌های متعلق به Plugin همراه با Gateway
  • cron_changed - مشاهده تغییرات چرخه عمر Cron متعلق به Gateway (افزوده‌شده، به‌روزرسانی‌شده، حذف‌شده، شروع‌شده، پایان‌یافته، زمان‌بندی‌شده)
  • before_install - بررسی اسکن‌های نصب Skills یا Plugin و، در صورت نیاز، مسدودکردن

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

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

  • event.toolName
  • event.params
  • event.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 ← منسوخ‌سازی‌های فعال.

مرتبط