مسار التحميل
عند بدء التشغيل، ينفّذ OpenClaw تقريبًا ما يلي:- اكتشاف جذور Plugin المرشحة
- قراءة بيانات manifest للحزم الأصلية أو المتوافقة وبيانات package الوصفية
- رفض المرشحين غير الآمنين
- تطبيع إعدادات Plugin (
plugins.enabled,allow,deny,entries,slots,load.paths) - تحديد حالة التمكين لكل مرشح
- تحميل الوحدات الأصلية الممكّنة: تستخدم الوحدات المجمّعة المبنية مُحمّلًا أصليًا؛ وتستخدم Plugins الأصلية غير المبنية
jiti - استدعاء خطافات
register(api)الأصلية وجمع التسجيلات داخل سجل Plugin - إتاحة السجل لأسطح الأوامر/وقت التشغيل
activate هو اسم بديل قديم لـ register — يحلّ المُحمّل أيهما موجود (def.register ?? def.activate) ويستدعيه في النقطة نفسها. تستخدم جميع Plugins المجمّعة register; ويفضّل استخدام register في Plugins الجديدة.سلوك manifest أولًا
يُعد manifest مصدر الحقيقة لمستوى التحكم. ويستخدمه OpenClaw من أجل:- تحديد Plugin
- اكتشاف القنوات/Skills/مخطط الإعدادات المصرّح بها أو قدرات الحزمة
- التحقق من
plugins.entries.<id>.config - تعزيز التسميات/العناصر النائبة في واجهة Control
- عرض بيانات التثبيت/الفهرس الوصفية
- الحفاظ على واصفات تفعيل وإعداد منخفضة الكلفة دون تحميل وقت تشغيل Plugin
activation وsetup في manifest ضمن مستوى التحكم.
وهما واصفات وصفية فقط لتخطيط التفعيل واكتشاف الإعداد؛
ولا تستبدلان التسجيل في وقت التشغيل، أو register(...)، أو setupEntry.
ويستخدم أول مستهلكي التفعيل الفعليين الآن تلميحات الأوامر والقنوات والمزوّدات في manifest
لتضييق تحميل Plugin قبل إنشاء السجل الأوسع:
- يضيّق تحميل CLI إلى Plugins التي تملك الأمر الأساسي المطلوب
- يضيّق إعداد القناة/تحليل Plugin إلى Plugins التي تملك معرّف القناة المطلوب
- يضيّق تحليل الإعداد/وقت التشغيل الصريح للمزوّد إلى Plugins التي تملك معرّف المزوّد المطلوب
activation.* عن الرجوع الاحتياطي لملكية manifest
مثل providers وchannels وcommandAliases وsetup.providers
وcontracts.tools والخطافات. ويُعد هذا الفصل في الأسباب حدّ التوافق:
إذ تستمر بيانات Plugin الوصفية الحالية في العمل، بينما يمكن للشيفرة الجديدة اكتشاف التلميحات الواسعة
أو سلوك الرجوع الاحتياطي دون تغيير دلالات التحميل في وقت التشغيل.
يفضّل اكتشاف الإعداد الآن المعرّفات المملوكة للواصفات مثل setup.providers و
setup.cliBackends لتضييق Plugins المرشحة قبل الرجوع إلى
setup-api بالنسبة إلى Plugins التي ما تزال تحتاج إلى خطافات وقت تشغيل أثناء الإعداد. وإذا ادّعى
أكثر من Plugin مكتشَف واحد ملكية معرّف موحّد لمزوّد إعداد أو واجهة CLI خلفية،
فإن البحث عن الإعداد يرفض المالك الملتبس بدلًا من الاعتماد على ترتيب الاكتشاف.
ما الذي يخزّنه المُحمّل مؤقتًا
يحتفظ OpenClaw بذاكرات مؤقتة قصيرة داخل العملية من أجل:- نتائج الاكتشاف
- بيانات سجل manifest
- سجلات Plugins المحمّلة
- اضبط
OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1أوOPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1لتعطيل هذه الذواكر المؤقتة. - اضبط نوافذ الذاكرة المؤقتة باستخدام
OPENCLAW_PLUGIN_DISCOVERY_CACHE_MSوOPENCLAW_PLUGIN_MANIFEST_CACHE_MS.
نموذج السجل
لا تقوم Plugins المحمّلة بتعديل متغيرات أساسية عشوائية في النواة مباشرةً. بل تسجّل في سجل Plugin مركزي. يتتبّع السجل ما يلي:- سجلات Plugin (الهوية، والمصدر، والمنشأ، والحالة، والتشخيصات)
- الأدوات
- الخطافات القديمة والخطافات المكتوبة
- القنوات
- المزوّدات
- معالجات Gateway RPC
- مسارات HTTP
- مسجّلات CLI
- الخدمات الخلفية
- الأوامر المملوكة لـ Plugin
- وحدة Plugin -> التسجيل في السجل
- وقت التشغيل الأساسي -> استهلاك السجل
استدعاءات ربط المحادثة
يمكن لـ Plugins التي تربط محادثةً أن تتفاعل عند حسم الموافقة. استخدمapi.onConversationBindingResolved(...) لتلقي استدعاء بعد الموافقة على
طلب ربط أو رفضه:
status:"approved"أو"denied"decision:"allow-once"أو"allow-always"أو"deny"binding: الربط المحسوم للطلبات الموافق عليهاrequest: ملخص الطلب الأصلي، وتلميح الفصل، ومعرّف المرسل، و بيانات المحادثة الوصفية
خطافات وقت تشغيل المزوّد
تتكون Plugins المزوّد من ثلاث طبقات:- بيانات manifest الوصفية لبحث منخفض الكلفة قبل وقت التشغيل:
providerAuthEnvVars, وproviderAuthAliases, وproviderAuthChoices, وchannelEnvVars. - خطافات وقت الإعداد:
catalog(الاسم القديمdiscovery) بالإضافة إلىapplyConfigDefaults. - خطافات وقت التشغيل: أكثر من 40 خطافًا اختياريًا تغطي المصادقة، وتحليل النموذج، وتغليف البث، ومستويات التفكير، وسياسة الإعادة، ونقاط نهاية الاستخدام. راجع القائمة الكاملة ضمن ترتيب الخطافات واستخدامها.
providerAuthEnvVars في manifest عندما يملك المزوّد بيانات اعتماد معتمدة على env
يجب أن تراها مسارات المصادقة/الحالة/منتقي النماذج العامة دون تحميل وقت تشغيل Plugin.
واستخدم providerAuthAliases في manifest عندما يجب على معرّف مزوّد ما إعادة استخدام
متغيرات env الخاصة بمزوّد آخر، وملفات تعريف المصادقة، والمصادقة المعتمدة على الإعدادات، وخيار
التهيئة باستخدام مفتاح API. واستخدم providerAuthChoices في manifest عندما ينبغي لأسطح
CLI الخاصة بالإعداد/اختيار المصادقة أن تعرف معرّف خيار المزوّد، وتسميات المجموعات،
وتهيئة المصادقة البسيطة بعلم واحد من دون تحميل وقت تشغيل المزوّد. وأبقِ
envVars الخاصة بوقت تشغيل المزوّد لتلميحات موجّهة للمشغّل مثل تسميات الإعداد أو
متغيرات إعداد OAuth مثل client-id/client-secret.
استخدم channelEnvVars في manifest عندما تكون لدى القناة مصادقة أو إعداد يعتمد على env
يجب أن تراه آليات الرجوع العامة إلى shell-env، أو فحوصات config/status، أو مطالبات الإعداد
من دون تحميل وقت تشغيل القناة.
ترتيب الخطافات واستخدامها
بالنسبة إلى Plugins النموذج/المزوّد، يستدعي OpenClaw الخطافات بهذا الترتيب التقريبي. ويُعد العمود “متى تستخدمه” دليل القرار السريع.| # | الخطاف | ما الذي يفعله | متى تستخدمه |
|---|---|---|---|
| 1 | catalog | ينشر إعدادات المزوّد داخل models.providers أثناء توليد models.json | عندما يملك المزوّد فهرسًا أو إعدادات افتراضية أساسية لـ URL |
| 2 | applyConfigDefaults | يطبّق الإعدادات الافتراضية العامة المملوكة للمزوّد أثناء إنشاء الإعدادات | عندما تعتمد الإعدادات الافتراضية على نمط المصادقة أو env أو دلالات عائلة نماذج المزوّد |
| — | (بحث النموذج المضمّن) | يحاول OpenClaw أولًا المسار العادي للسجل/الفهرس | (ليس خطاف Plugin) |
| 3 | normalizeModelId | يطبّع الأسماء البديلة القديمة أو التجريبية لمعرّف النموذج قبل البحث | عندما يملك المزوّد تنظيف الأسماء البديلة قبل التحليل القياسي لمعرّف النموذج |
| 4 | normalizeTransport | يطبّع api / baseUrl الخاص بعائلة المزوّد قبل التجميع العام للنموذج | عندما يملك المزوّد تنظيف طبقة النقل لمعرّفات مزوّد مخصّصة ضمن عائلة النقل نفسها |
| 5 | normalizeConfig | يطبّع models.providers.<id> قبل تحليل وقت التشغيل/المزوّد | عندما يحتاج المزوّد إلى تنظيف الإعدادات بطريقة يجب أن تبقى مع Plugin؛ كما تدعم أدوات Google-family المجمّعة أيضًا إدخالات إعدادات Google المدعومة |
| 6 | applyNativeStreamingUsageCompat | يطبّق تعديلات التوافق الخاصة باستخدام البث الأصلي على مزوّدات الإعدادات | عندما يحتاج المزوّد إلى إصلاحات لبيانات وصفية لاستخدام البث الأصلي تعتمد على نقطة النهاية |
| 7 | resolveConfigApiKey | يحلّ مصادقة env-marker لمزوّدات الإعدادات قبل تحميل مصادقة وقت التشغيل | عندما يملك المزوّد تحليلًا مملوكًا له لمفتاح API عبر env-marker؛ كما يملك amazon-bedrock أيضًا محلّل AWS env-marker مضمّنًا هنا |
| 8 | resolveSyntheticAuth | يعرض مصادقة محلية/مستضافة ذاتيًا أو معتمدة على الإعدادات دون حفظ نص عادي | عندما يستطيع المزوّد العمل باستخدام واسم اعتماد اصطناعي/محلي |
| 9 | resolveExternalAuthProfiles | يضيف تراكبًا لملفات تعريف المصادقة الخارجية المملوكة للمزوّد؛ والقيمة الافتراضية لـ persistence هي runtime-only لبيانات الاعتماد المملوكة لـ CLI/التطبيق | عندما يعيد المزوّد استخدام بيانات اعتماد مصادقة خارجية من دون حفظ رموز تحديث منسوخة؛ صرّح عن contracts.externalAuthProviders في manifest |
| 10 | shouldDeferSyntheticProfileAuth | يخفض أولوية العناصر النائبة المخزّنة لملفات التعريف الاصطناعية لصالح المصادقة المعتمدة على env/الإعدادات | عندما يخزّن المزوّد ملفات تعريف اصطناعية نائبة يجب ألا تتقدّم في الأولوية |
| 11 | resolveDynamicModel | مزامنة رجوعية لمعرّفات النماذج المملوكة للمزوّد غير الموجودة بعد في السجل المحلي | عندما يقبل المزوّد معرّفات نماذج علوية اعتباطية |
| 12 | prepareDynamicModel | تهيئة غير متزامنة، ثم يُشغَّل resolveDynamicModel مرة أخرى | عندما يحتاج المزوّد إلى بيانات وصفية من الشبكة قبل تحليل المعرّفات غير المعروفة |
| 13 | normalizeResolvedModel | إعادة كتابة نهائية قبل أن يستخدم المنفّذ المضمّن النموذج المحلَّل | عندما يحتاج المزوّد إلى إعادة كتابة لطبقة النقل مع الاستمرار في استخدام طبقة نقل أساسية |
| 14 | contributeResolvedModelCompat | يضيف أعلام توافق لنماذج المورّد الموجودة خلف طبقة نقل متوافقة أخرى | عندما يتعرّف المزوّد على نماذجه الخاصة في طبقات نقل وسيطة من دون أن يتولى المزوّد نفسه |
| 15 | capabilities | بيانات وصفية للنصوص/الأدوات مملوكة للمزوّد وتستخدمها منطق النواة المشتركة | عندما يحتاج المزوّد إلى خصائص خاصة بالنصوص أو بعائلة المزوّد |
| 16 | normalizeToolSchemas | يطبّع مخططات الأدوات قبل أن يراها المنفّذ المضمّن | عندما يحتاج المزوّد إلى تنظيف مخططات خاص بعائلة النقل |
| 17 | inspectToolSchemas | يعرض تشخيصات المخططات المملوكة للمزوّد بعد التطبيع | عندما يريد المزوّد تحذيرات للكلمات المفتاحية من دون تعليم النواة قواعد خاصة بالمزوّد |
| 18 | resolveReasoningOutputMode | يختار عقد مخرجات الاستدلال الأصلي مقابل الموسوم | عندما يحتاج المزوّد إلى مخرجات استدلال/نهائية موسومة بدلًا من الحقول الأصلية |
| 19 | prepareExtraParams | تطبيع بارامترات الطلب قبل أغلفة خيارات البث العامة | عندما يحتاج المزوّد إلى بارامترات طلب افتراضية أو تنظيف بارامترات خاص بكل مزوّد |
| 20 | createStreamFn | يستبدل مسار البث العادي بالكامل بطبقة نقل مخصّصة | عندما يحتاج المزوّد إلى بروتوكول نقل مخصّص بالكامل، وليس مجرد غلاف |
| 21 | wrapStreamFn | غلاف للبث بعد تطبيق الأغلفة العامة | عندما يحتاج المزوّد إلى أغلفة توافق لرؤوس/جسم/نموذج الطلب من دون طبقة نقل مخصّصة |
| 22 | resolveTransportTurnState | يرفق رؤوسًا أو بيانات وصفية أصلية خاصة بكل دورة نقل | عندما يريد المزوّد من طبقات النقل العامة إرسال هوية دورة أصلية خاصة بالمزوّد |
| 23 | resolveWebSocketSessionPolicy | يرفق رؤوس WebSocket أصلية أو سياسة تهدئة للجلسة | عندما يريد المزوّد من طبقات WS العامة ضبط رؤوس الجلسة أو سياسة الرجوع الاحتياطي |
| 24 | formatApiKey | منسّق ملف تعريف المصادقة: يتحول ملف التعريف المخزّن إلى سلسلة apiKey الخاصة بوقت التشغيل | عندما يخزّن المزوّد بيانات مصادقة وصفية إضافية ويحتاج إلى شكل مخصص لرمز وقت التشغيل |
| 25 | refreshOAuth | تجاوز لتحديث OAuth لنقاط نهاية تحديث مخصّصة أو سياسة فشل التحديث | عندما لا يتوافق المزوّد مع محدّثات pi-ai المشتركة |
| 26 | buildAuthDoctorHint | تلميح إصلاح يُضاف عند فشل تحديث OAuth | عندما يحتاج المزوّد إلى إرشاد إصلاح مصادقة مملوك له بعد فشل التحديث |
| 27 | matchesContextOverflowError | مطابقة مملوكة للمزوّد لخطأ تجاوز نافذة السياق | عندما يملك المزوّد أخطاء تجاوز خام قد تفوّتها الاستدلالات العامة |
| 28 | classifyFailoverReason | تصنيف مملوك للمزوّد لسبب التبديل الاحتياطي | عندما يستطيع المزوّد ربط أخطاء API/النقل الخام بأسباب مثل حد المعدل/الحمولة الزائدة/إلخ |
| 29 | isCacheTtlEligible | سياسة Prompt-cache لمزوّدات proxy/backhaul | عندما يحتاج المزوّد إلى تقييد TTL خاص بالـ proxy |
| 30 | buildMissingAuthMessage | بديل لرسالة استعادة المصادقة المفقودة العامة | عندما يحتاج المزوّد إلى تلميح استعادة خاص بالمزوّد للمصادقة المفقودة |
| 31 | suppressBuiltInModel | إخفاء النماذج العلوية القديمة مع تلميح خطأ اختياري موجّه للمستخدم | عندما يحتاج المزوّد إلى إخفاء صفوف علوية قديمة أو استبدالها بتلميح خاص بالمورّد |
| 32 | augmentModelCatalog | صفوف فهرس اصطناعية/نهائية تُضاف بعد الاكتشاف | عندما يحتاج المزوّد إلى صفوف توافق أمامي اصطناعية في models list وأدوات الاختيار |
| 33 | resolveThinkingProfile | يحدد مستوى /think الخاص بالنموذج، وتسميات العرض، والقيمة الافتراضية | عندما يوفّر المزوّد سلم تفكير مخصصًا أو تسمية ثنائية للنماذج المحددة |
| 34 | isBinaryThinking | خطاف توافق لتبديل الاستدلال تشغيل/إيقاف | عندما يوفّر المزوّد تفكيرًا ثنائيًا تشغيل/إيقاف فقط |
| 35 | supportsXHighThinking | خطاف توافق لدعم الاستدلال xhigh | عندما يريد المزوّد تفعيل xhigh فقط لمجموعة فرعية من النماذج |
| 36 | resolveDefaultThinkingLevel | خطاف توافق لمستوى /think الافتراضي | عندما يملك المزوّد سياسة /think الافتراضية لعائلة نماذج |
| 37 | isModernModelRef | مطابِق النماذج الحديثة لمرشحات الملفات التعريفية الحية واختيار smoke | عندما يملك المزوّد مطابقة النموذج المفضل للاختبارات الحية/smoke |
| 38 | prepareRuntimeAuth | يستبدل بيانات اعتماد مُعدّة مسبقًا بالرمز/المفتاح الفعلي لوقت التشغيل مباشرة قبل الاستدلال | عندما يحتاج المزوّد إلى تبادل رمز أو بيانات اعتماد طلب قصيرة العمر |
| 39 | resolveUsageAuth | يحل بيانات اعتماد الاستخدام/الفوترة الخاصة بـ /usage والأسطح المرتبطة بالحالة | عندما يحتاج المزوّد إلى تحليل مخصص لرمز الاستخدام/الحصة أو إلى بيانات اعتماد استخدام مختلفة |
| 40 | fetchUsageSnapshot | يجلب ويطبّع لقطات الاستخدام/الحصة الخاصة بالمزوّد بعد حلّ المصادقة | عندما يحتاج المزوّد إلى نقطة نهاية استخدام خاصة به أو إلى محلّل حمولة |
| 41 | createEmbeddingProvider | يبني مُهايئ embeddings مملوكًا للمزوّد للذاكرة/البحث | عندما يكون سلوك embeddings الخاص بالذاكرة تابعًا لـ Plugin المزوّد |
| 42 | buildReplayPolicy | يعيد سياسة replay تتحكم في معالجة النصوص الخاصة بالمزوّد | عندما يحتاج المزوّد إلى سياسة نصوص مخصصة (مثل إزالة كتل التفكير) |
| 43 | sanitizeReplayHistory | يعيد كتابة سجل replay بعد التنظيف العام للنصوص | عندما يحتاج المزوّد إلى إعادة كتابة replay خاصة به تتجاوز أدوات Compaction المشتركة |
| 44 | validateReplayTurns | التحقق النهائي من دورات replay أو إعادة تشكيلها قبل المنفّذ المضمّن | عندما تحتاج طبقة نقل المزوّد إلى تحقق أكثر صرامة من الدورات بعد التنقية العامة |
| 45 | onModelSelected | ينفّذ آثارًا جانبية لاحقة للاختيار مملوكة للمزوّد | عندما يحتاج المزوّد إلى telemetry أو حالة مملوكة له عند تفعيل نموذج ما |
normalizeModelId وnormalizeTransport وnormalizeConfig أولًا من
Plugin المزوّد المطابق، ثم ينتقل إلى Plugins المزوّد الأخرى القادرة على استخدام الخطافات
إلى أن يغيّر أحدها فعليًا معرّف النموذج أو النقل/الإعدادات. ويحافظ ذلك على
عمل طبقات alias/compat الوسيطة للمزوّد من دون مطالبة المستدعي بمعرفة أي Plugin
مجمّع يملك إعادة الكتابة. وإذا لم يُعِد أي خطاف مزوّد كتابة
إدخال إعدادات مدعوم من Google-family، فسيظل مطبّع إعدادات Google المجمّع يطبّق
تنظيف التوافق هذا.
إذا كان المزوّد يحتاج إلى بروتوكول نقل مخصص بالكامل أو منفّذ طلبات مخصص،
فهذه فئة مختلفة من الامتداد. هذه الخطافات مخصّصة لسلوك المزوّد الذي
يستمر في العمل ضمن حلقة الاستدلال العادية في OpenClaw.
مثال على مزوّد
أمثلة مضمّنة
تجمع Plugins المزوّد المجمّعة بين الخطافات أعلاه لتلبية احتياجات كل مورّد في الفهرس، والمصادقة، والتفكير، وreplay، والاستخدام. وتوجد مجموعة الخطافات المعتمدة مع كل Plugin ضمنextensions/; وتعرض هذه الصفحة الأشكال بدلًا من
عكس القائمة كما هي.
مزوّدات فهرس تمريري
مزوّدات فهرس تمريري
تسجّل OpenRouter وKilocode وZ.AI وxAI
catalog بالإضافة إلى
resolveDynamicModel / prepareDynamicModel حتى تتمكن من إظهار معرّفات
النماذج العلوية قبل الفهرس الثابت في OpenClaw.مزوّدات OAuth ونقطة نهاية الاستخدام
مزوّدات OAuth ونقطة نهاية الاستخدام
تقرن GitHub Copilot وGemini CLI وChatGPT Codex وMiniMax وXiaomi وz.ai
prepareRuntimeAuth أو formatApiKey مع resolveUsageAuth +
fetchUsageSnapshot لتتولى تبادل الرموز والتكامل مع /usage.عائلات replay وتنظيف النصوص
عائلات replay وتنظيف النصوص
تتيح العائلات المسماة المشتركة (
google-gemini وpassthrough-gemini
وanthropic-by-model وhybrid-anthropic-openai) للمزوّدات الاشتراك في
سياسة النصوص عبر buildReplayPolicy بدلًا من إعادة تنفيذ التنظيف في
كل Plugin.مزوّدات تعتمد على الفهرس فقط
مزوّدات تعتمد على الفهرس فقط
تسجّل
byteplus وcloudflare-ai-gateway وhuggingface وkimi-coding وnvidia
وqianfan وsynthetic وtogether وvenice وvercel-ai-gateway و
volcengine فقط catalog وتعتمد على حلقة الاستدلال المشتركة.أدوات بث خاصة بـ Anthropic
أدوات بث خاصة بـ Anthropic
توجد رؤوس Beta، و
/fast / serviceTier، وcontext1m داخل
واجهة api.ts / contract-api.ts العامة الخاصة بـ Plugin Anthropic
(wrapAnthropicProviderStream وresolveAnthropicBetas
وresolveAnthropicFastMode وresolveAnthropicServiceTier) بدلًا من
SDK العامة.أدوات وقت التشغيل
يمكن لـ Plugins الوصول إلى أدوات أساسية محددة عبرapi.runtime. بالنسبة إلى TTS:
- يعيد
textToSpeechحمولة خرج TTS الأساسية العادية لأسطح الملفات/الملاحظات الصوتية. - يستخدم إعداد
messages.ttsالأساسي واختيار المزوّد. - يعيد مخزن PCM صوتيًا + معدل العيّنة. ويجب على Plugins إعادة أخذ العينات/الترميز للمزوّدات.
listVoicesاختياري لكل مزوّد. استخدمه لمنتقيات الأصوات أو تدفقات الإعداد المملوكة للمورّد.- يمكن أن تتضمن قوائم الأصوات بيانات وصفية أغنى مثل اللغة المحلية، والجنس، ووسوم الشخصية لمنتقيات تراعي المزوّد.
- يدعم OpenAI وElevenLabs الاتصال الهاتفي اليوم. أما Microsoft فلا يدعمه.
api.registerSpeechProvider(...).
- أبقِ سياسة TTS، والرجوع الاحتياطي، وتسليم الردود داخل النواة.
- استخدم مزوّدي الكلام لسلوك التوليف المملوك للمورّد.
- يُطبَّع الإدخال القديم
edgeالخاص بـ Microsoft إلى معرّف المزوّدmicrosoft. - نموذج الملكية المفضّل موجّه نحو الشركة: يمكن لـ Plugin واحد خاص بالمورّد أن يملك مزوّدي النص، والكلام، والصورة، ووسائط مستقبلية أخرى كلما أضاف OpenClaw عقود القدرات تلك.
- أبقِ التنسيق، والرجوع الاحتياطي، والإعدادات، وربط القنوات داخل النواة.
- أبقِ سلوك المورّد داخل Plugin المزوّد.
- يجب أن يظل التوسع الإضافي مكتوبًا: أساليب اختيارية جديدة، وحقول نتائج اختيارية جديدة، وقدرات اختيارية جديدة.
- يتبع توليد الفيديو النمط نفسه بالفعل:
- تملك النواة عقد القدرة وأداة وقت التشغيل
- تسجّل Plugins المورّد
api.registerVideoGenerationProvider(...) - تستهلك Plugins الميزة/القناة
api.runtime.videoGeneration.*
- يُعد
api.runtime.mediaUnderstanding.*السطح المشترك المفضّل لفهم الصورة/الصوت/الفيديو. - يستخدم إعداد الصوت الأساسي لفهم الوسائط (
tools.media.audio) وترتيب الرجوع الاحتياطي للمزوّد. - يعيد
{ text: undefined }عندما لا يُنتَج أي خرج نسخ (مثلًا إذا كان الإدخال متخطًى/غير مدعوم). - يبقى
api.runtime.stt.transcribeAudioFile(...)اسمًا بديلًا للتوافق.
api.runtime.subagent:
providerوmodelهما تجاوزان اختياريان لكل تشغيل، وليسا تغييرات جلسة دائمة.- لا يطبّق OpenClaw حقول التجاوز هذه إلا للمستدعين الموثوقين.
- بالنسبة إلى عمليات الرجوع الاحتياطي المملوكة لـ Plugin، يجب على المشغّلين تفعيل ذلك صراحةً عبر
plugins.entries.<id>.subagent.allowModelOverride: true. - استخدم
plugins.entries.<id>.subagent.allowedModelsلتقييد Plugins الموثوقة بأهدافprovider/modelالقياسية المحددة، أو"*"للسماح الصريح بأي هدف. - تظل عمليات Subagent الخاصة بـ Plugins غير الموثوقة تعمل، لكن تُرفض طلبات التجاوز بدلًا من الرجوع الاحتياطي بصمت.
api.registerWebSearchProvider(...).
ملاحظات:
- أبقِ اختيار المزوّد، وتحليل بيانات الاعتماد، ودلالات الطلبات المشتركة داخل النواة.
- استخدم مزوّدي البحث على الويب لطبقات النقل الخاصة بالمورّد.
- يُعد
api.runtime.webSearch.*السطح المشترك المفضّل لPlugins الميزات/القنوات التي تحتاج إلى سلوك بحث من دون الاعتماد على غلاف أداة الوكيل.
api.runtime.imageGeneration
generate(...): يولّد صورة باستخدام سلسلة مزوّد توليد الصور المهيّأة.listProviders(...): يسرد مزوّدي توليد الصور المتاحين وقدراتهم.
مسارات HTTP الخاصة بـ Gateway
يمكن لـ Plugins كشف نقاط نهاية HTTP باستخدامapi.registerHttpRoute(...).
path: مسار route ضمن خادم HTTP الخاص بـ Gateway.auth: مطلوب. استخدم"gateway"لطلب مصادقة Gateway العادية، أو"plugin"للمصادقة/التحقق من Webhook الذي يديره Plugin.match: اختياري."exact"(الافتراضي) أو"prefix".replaceExisting: اختياري. يسمح لـ Plugin نفسه باستبدال تسجيل مساره الحالي.handler: أعِدtrueعندما يكون المسار قد عالج الطلب.
- أُزيل
api.registerHttpHandler(...)وسيسبب خطأ في تحميل Plugin. استخدمapi.registerHttpRoute(...)بدلًا منه. - يجب على مسارات Plugin التصريح عن
authصراحةً. - تُرفض تعارضات
path + matchالمتطابقة ما لم يكنreplaceExisting: true، ولا يمكن لـ Plugin واحد استبدال مسار Plugin آخر. - تُرفض المسارات المتداخلة ذات مستويات
authالمختلفة. أبقِ سلاسل التمريرexact/prefixضمن مستوى المصادقة نفسه فقط. - لا تتلقى مسارات
auth: "plugin"نطاقات وقت تشغيل المشغّل تلقائيًا. فهي مخصّصة لـ Webhooks/التحقق من التوقيع الذي يديره Plugin، وليست لاستدعاءات Gateway المساعدة ذات الامتيازات. - تعمل مسارات
auth: "gateway"داخل نطاق وقت تشغيل طلب Gateway، لكن هذا النطاق متحفظ عمدًا:- تبقي مصادقة bearer بالمفتاح السري المشترك (
gateway.auth.mode = "token"/"password") نطاقات وقت تشغيل مسار Plugin مثبتة عندoperator.write، حتى لو أرسل المستدعيx-openclaw-scopes - أوضاع HTTP الموثوقة الحاملة للهوية (مثل
trusted-proxyأوgateway.auth.mode = "none"على مدخل خاص) لا تكرّمx-openclaw-scopesإلا عندما يكون الرأس موجودًا صراحةً - إذا كان
x-openclaw-scopesغائبًا في طلبات مسار Plugin الحاملة للهوية تلك، يعود نطاق وقت التشغيل إلىoperator.write
- تبقي مصادقة bearer بالمفتاح السري المشترك (
- القاعدة العملية: لا تفترض أن مسار Plugin ذي مصادقة gateway هو سطح إدارة ضمني. إذا كان مسارك يحتاج إلى سلوك مخصص للمشرف فقط، فاشترط وضع مصادقة حاملًا للهوية ووثّق عقد الرأس
x-openclaw-scopesالصريح.
مسارات استيراد Plugin SDK
استخدم المسارات الفرعية الضيقة في SDK بدلًا من البرميل الجذري الأحاديopenclaw/plugin-sdk
عند تأليف Plugins جديدة. المسارات الفرعية الأساسية:
| المسار الفرعي | الغرض |
|---|---|
openclaw/plugin-sdk/plugin-entry | بدائيات تسجيل Plugin |
openclaw/plugin-sdk/channel-core | أدوات إدخال/بناء القنوات |
openclaw/plugin-sdk/core | أدوات مشتركة عامة والعقد المظلّي |
openclaw/plugin-sdk/config-schema | مخطط Zod الجذري لـ openclaw.json (OpenClawSchema) |
channel-setup,
وsetup-runtime, وsetup-adapter-runtime, وsetup-tools, وchannel-pairing,
وchannel-contract, وchannel-feedback, وchannel-inbound, وchannel-lifecycle,
وchannel-reply-pipeline, وcommand-auth, وsecret-input, وwebhook-ingress,
وchannel-targets, وchannel-actions. يجب أن يوحَّد سلوك الموافقة
حول عقد approvalCapability واحد بدلًا من المزج عبر حقول Plugin
غير المرتبطة. راجع Plugins القنوات.
توجد أدوات وقت التشغيل والإعدادات ضمن مسارات فرعية مطابقة من نوع *-runtime
(approval-runtime, وconfig-runtime, وinfra-runtime, وagent-runtime,
وlazy-runtime, وdirectory-runtime, وtext-runtime, وruntime-store، وغيرها).
openclaw/plugin-sdk/channel-runtime مهمل — وهو طبقة توافقية لـ
Plugins الأقدم. يجب أن تستورد الشيفرة الجديدة بدائيات عامة أضيق بدلًا من ذلك.index.js— إدخال Plugin المجمّعapi.js— برميل الأدوات/الأنواعruntime-api.js— برميل خاص بوقت التشغيل فقطsetup-entry.js— إدخال Plugin الإعداد
openclaw/plugin-sdk/* الفرعية. لا
تستورد أبدًا src/* من حزمة Plugin أخرى من النواة أو من Plugin آخر.
وتفضّل نقاط الدخول المحمّلة عبر الواجهة لقطة إعدادات وقت التشغيل النشطة عندما
تكون موجودة، ثم تعود إلى ملف الإعدادات المحلول على القرص.
توجد مسارات فرعية خاصة بالقدرات مثل image-generation وmedia-understanding
وspeech لأن Plugins المجمّعة تستخدمها اليوم. وهي ليست تلقائيًا عقودًا خارجية
ثابتة طويلة الأمد — راجع صفحة مرجع SDK ذات الصلة عند الاعتماد عليها.
مخططات أدوات الرسائل
يجب أن تملك Plugins مساهمات مخططdescribeMessageTool(...) الخاصة بالقنوات
للوحدات غير الرسائلية مثل التفاعلات، وعلامات القراءة، والاستطلاعات.
ويجب أن يستخدم عرض الإرسال المشترك عقد MessagePresentation العام
بدلًا من حقول الأزرار أو المكونات أو الكتل أو البطاقات الأصلية الخاصة بالمزوّد.
راجع Message Presentation لمعرفة العقد،
وقواعد الرجوع الاحتياطي، وربط المزوّد، وقائمة التحقق الخاصة بمؤلف Plugin.
تصرّح Plugins القادرة على الإرسال بما يمكنها عرضه من خلال قدرات الرسائل:
presentationلكتل العرض الدلالية (text,context,divider,buttons,select)delivery-pinلطلبات التسليم المثبّت
تحليل أهداف القنوات
يجب أن تملك Plugins القنوات دلالات الأهداف الخاصة بالقناة. أبقِ المضيف الصادر المشترك عامًا، واستخدم سطح مُهايئ المراسلة لقواعد المزوّد:- يحدد
messaging.inferTargetChatType({ to })ما إذا كان الهدف الموحّد يجب التعامل معه كـdirectأوgroupأوchannelقبل البحث في الدليل. - يوضح
messaging.targetResolver.looksLikeId(raw, normalized)للنواة ما إذا كان الإدخال يجب أن يتجاوز مباشرة إلى التحليل الشبيه بالمعرّف بدلًا من البحث في الدليل. - يمثّل
messaging.targetResolver.resolveTarget(...)رجوع Plugin الاحتياطي عندما تحتاج النواة إلى تحليل نهائي مملوك للمزوّد بعد التطبيع أو بعد فشل البحث في الدليل. - يملك
messaging.resolveOutboundSessionRoute(...)إنشاء مسار الجلسة الخاص بالمزوّد بعد تحليل الهدف.
- استخدم
inferTargetChatTypeلقرارات التصنيف التي يجب أن تحدث قبل البحث عن الأقران/المجموعات. - استخدم
looksLikeIdلفحوصات “تعامل مع هذا على أنه معرّف هدف صريح/أصلي”. - استخدم
resolveTargetلرجوع التطبيع الاحتياطي الخاص بالمزوّد، وليس للبحث الواسع في الدليل. - أبقِ المعرّفات الأصلية الخاصة بالمزوّد مثل معرّفات الدردشة، ومعرّفات السلاسل، وJIDs،
والمقابض، ومعرّفات الغرف داخل قيم
targetأو البارامترات الخاصة بالمزوّد، لا في حقول SDK العامة.
الأدلة المعتمدة على الإعدادات
يجب أن تبقي Plugins التي تشتق إدخالات الدليل من الإعدادات هذا المنطق داخل Plugin وأن تعيد استخدام الأدوات المشتركة منopenclaw/plugin-sdk/directory-runtime.
استخدم هذا عندما تحتاج قناة إلى أقران/مجموعات معتمدة على الإعدادات مثل:
- أقران DM المعتمدين على allowlist
- خرائط القنوات/المجموعات المهيّأة
- بدائل دليل ثابتة ضمن نطاق الحساب
directory-runtime إلا مع العمليات العامة:
- تصفية الاستعلام
- تطبيق الحد
- أدوات إزالة التكرار/التطبيع
- بناء
ChannelDirectoryEntry[]
فهارس المزوّدين
يمكن لـ Plugins المزوّدين تعريف فهارس نماذج للاستدلال باستخدامregisterProvider({ catalog: { run(...) { ... } } }).
يعيد catalog.run(...) الشكل نفسه الذي يكتبه OpenClaw داخل
models.providers:
{ provider }لإدخال مزوّد واحد{ providers }لعدة إدخالات مزوّدين
catalog عندما يملك Plugin معرّفات نماذج خاصة بالمزوّد، أو
إعدادات base URL الافتراضية، أو بيانات وصفية للنماذج مقيدة بالمصادقة.
يتحكم catalog.order في وقت دمج فهرس Plugin مقارنةً بمزوّدي OpenClaw
الضمنيين المضمّنين:
simple: مزوّدات تعتمد على مفتاح API عادي أو على envprofile: مزوّدات تظهر عندما توجد ملفات تعريف المصادقةpaired: مزوّدات تُنشئ عدة إدخالات مزوّد مترابطةlate: التمريرة الأخيرة، بعد بقية المزوّدين الضمنيين
- ما يزال
discoveryيعمل كاسم بديل قديم - إذا سُجّل كل من
catalogوdiscovery، يستخدم OpenClawcatalog
فحص القنوات للقراءة فقط
إذا كان Plugin الخاص بك يسجّل قناة، ففضّل تنفيذplugin.config.inspectAccount(cfg, accountId) إلى جانب resolveAccount(...).
السبب:
resolveAccount(...)هو مسار وقت التشغيل. ويُسمح له بافتراض أن بيانات الاعتماد قد جرى تجسيدها بالكامل، ويمكنه الفشل سريعًا عند غياب الأسرار المطلوبة.- لا ينبغي لمسارات الأوامر للقراءة فقط مثل
openclaw status، وopenclaw status --all، وopenclaw channels status، وopenclaw channels resolve، وعمليات doctor/config repair أن تحتاج إلى تجسيد بيانات اعتماد وقت التشغيل لمجرد وصف الإعدادات.
inspectAccount(...):
- أعِد فقط حالة حساب وصفية.
- حافظ على
enabledوconfigured. - ضمّن حقول مصدر/حالة بيانات الاعتماد عند الاقتضاء، مثل:
tokenSource,tokenStatusbotTokenSource,botTokenStatusappTokenSource,appTokenStatussigningSecretSource,signingSecretStatus
- لا تحتاج إلى إعادة قيم الرموز الخام فقط للإبلاغ عن
الإتاحة في القراءة فقط. يكفي إرجاع
tokenStatus: "available"(وحقل المصدر المطابق) لأوامر نمط الحالة. - استخدم
configured_unavailableعندما تكون بيانات الاعتماد مهيأة عبر SecretRef لكن غير متاحة في مسار الأمر الحالي.
حِزم الحزم
قد يتضمن دليل Plugin ملفpackage.json يحوي openclaw.extensions:
name/<fileBase>.
إذا كان Plugin الخاص بك يستورد تبعيات npm، فثبّتها في هذا الدليل حتى
يصبح node_modules متاحًا (npm install / pnpm install).
حاجز أمان: يجب أن يبقى كل إدخال في openclaw.extensions داخل دليل Plugin
بعد تحليل الروابط الرمزية. وتُرفض الإدخالات التي تخرج من دليل الحزمة.
ملاحظة أمنية: يثبّت openclaw plugins install تبعيات Plugin باستخدام
npm install --omit=dev --ignore-scripts (من دون نصوص دورة حياة، ومن دون تبعيات تطوير في وقت التشغيل). حافظ على أشجار تبعيات Plugin
“JavaScript/TypeScript خالصة” وتجنب الحزم التي تتطلب بناء postinstall.
اختياري: يمكن أن يشير openclaw.setupEntry إلى وحدة خفيفة مخصّصة للإعداد فقط.
عندما يحتاج OpenClaw إلى أسطح إعداد لقناة Plugin معطلة، أو
عندما تكون قناة Plugin مفعّلة ولكنها غير مهيأة بعد، فإنه يحمّل setupEntry
بدلًا من إدخال Plugin الكامل. وهذا يُبقي بدء التشغيل والإعداد أخف
عندما يكون إدخال Plugin الرئيسي لديك يربط أيضًا أدوات أو خطافات أو
شيفرة أخرى خاصة بوقت التشغيل فقط.
اختياري: يمكن أن يفعّل openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen
لقناة Plugin مسار setupEntry نفسه أثناء
مرحلة بدء التشغيل قبل الاستماع في Gateway، حتى عندما تكون القناة مهيأة بالفعل.
استخدم هذا فقط عندما يغطي setupEntry بالكامل سطح بدء التشغيل الذي يجب أن يوجد
قبل أن يبدأ Gateway في الاستماع. وعمليًا، يعني ذلك أن إدخال الإعداد
يجب أن يسجّل كل قدرة مملوكة للقناة يعتمد عليها بدء التشغيل، مثل:
- تسجيل القناة نفسه
- أي مسارات HTTP يجب أن تكون متاحة قبل أن يبدأ Gateway في الاستماع
- أي أساليب Gateway أو أدوات أو خدمات يجب أن توجد خلال تلك النافذة نفسها
singleAccountKeysToMovenamedAccountPromotionKeysresolveSingleAccountPromotionTarget(...)
channels.<id>.accounts.* من دون تحميل إدخال Plugin الكامل.
وتُعد Matrix المثال المجمّع الحالي: فهي تنقل فقط مفاتيح المصادقة/التمهيد
إلى حساب مُرقّى مسمّى عندما تكون الحسابات المسمّاة موجودة بالفعل، ويمكنها
الحفاظ على مفتاح حساب افتراضي غير قياسي مهيأ بدلًا من إنشاء
accounts.default دائمًا.
تُبقي مُهايئات التصحيح الخاصة بالإعداد هذه اكتشاف أسطح العقود المجمّعة كسولًا.
ويبقى وقت الاستيراد خفيفًا؛ ويُحمَّل سطح الترقية فقط عند أول استخدام بدلًا من
إعادة الدخول إلى بدء تشغيل القناة المجمّعة عند استيراد الوحدة.
عندما تتضمن أسطح بدء التشغيل هذه أساليب Gateway RPC، فأبقها ضمن
بادئة خاصة بـ Plugin. وتظل مساحات أسماء الإدارة الأساسية (config.*,
وexec.approvals.*, وwizard.*, وupdate.*) محجوزة وتُحل دائمًا إلى
operator.admin، حتى إذا طلب Plugin نطاقًا أضيق.
مثال:
البيانات الوصفية لفهرس القنوات
يمكن لـ Plugins القنوات الإعلان عن بيانات وصفية خاصة بالإعداد/الاكتشاف عبرopenclaw.channel و
تلميحات التثبيت عبر openclaw.install. وهذا يُبقي بيانات فهرس النواة خالية من البيانات.
مثال:
openclaw.channel المفيدة إلى جانب المثال الأدنى:
detailLabel: تسمية ثانوية لأسطح الفهرس/الحالة الأكثر ثراءًdocsLabel: تجاوز نص الرابط الخاص برابط الوثائقpreferOver: معرّفات Plugin/قنوات ذات أولوية أقل يجب أن يتفوق عليها إدخال الفهرس هذاselectionDocsPrefix,selectionDocsOmitLabel,selectionExtras: عناصر تحكم نصية خاصة بسطح الاختيارmarkdownCapable: يعلّم القناة على أنها قادرة على استخدام Markdown لقرارات التنسيق الصادرexposure.configured: إخفاء القناة من أسطح سرد القنوات المهيأة عند ضبطه علىfalseexposure.setup: إخفاء القناة من منتقيات الإعداد/التهيئة التفاعلية عند ضبطه علىfalseexposure.docs: تعليم القناة على أنها داخلية/خاصة لأسطح التنقل في الوثائقshowConfigured/showInSetup: أسماء بديلة قديمة ما تزال مقبولة للتوافق؛ ويفضّل استخدامexposurequickstartAllowFrom: يضم القناة إلى تدفقallowFromالقياسي في البدء السريعforceAccountBinding: يفرض ربط حساب صريحًا حتى عند وجود حساب واحد فقطpreferSessionLookupForAnnounceTarget: يفضّل البحث عن الجلسة عند تحليل أهداف الإعلان
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
OPENCLAW_PLUGIN_CATALOG_PATHS (أو OPENCLAW_MPM_CATALOG_PATHS) إلى
ملف JSON واحد أو أكثر (مفصولة بفواصل/فواصل منقوطة/محدِّد PATH). يجب أن يحتوي كل ملف
على { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }. ويقبل المحلّل أيضًا
"packages" أو "plugins" كأسماء بديلة قديمة للمفتاح "entries".
تكشف إدخالات فهرس القنوات المُولّدة وإدخالات فهرس تثبيت المزوّدين
حقائق مطبّعة لمصدر التثبيت إلى جانب كتلة openclaw.install الخام. وتحدّد
الحقائق المطبّعة ما إذا كان npm spec إصدارًا مطابقًا تمامًا أو محددًا عائمًا،
وما إذا كانت بيانات السلامة المتوقعة موجودة، وما إذا كان مسار مصدر محلي
متاحًا أيضًا. ويجب على المستهلكين التعامل مع installSource باعتباره
حقلًا اختياريًا إضافيًا حتى لا تضطر الإدخالات الأقدم المبنية يدويًا وطبقات التوافق
إلى توليده. ويتيح ذلك لعمليات الإعداد والتشخيصات شرح
حالة مستوى المصدر من دون استيراد وقت تشغيل Plugin.
يجب أن تفضّل إدخالات npm الخارجية الرسمية npmSpec مطابقًا تمامًا بالإضافة إلى
expectedIntegrity. ولا تزال أسماء الحزم المجردة وdist-tags تعمل
للتوافق، لكنها تُظهر تحذيرات على مستوى المصدر بحيث يمكن للفهرس أن يتجه
نحو تثبيتات مثبتة ومتحقق من سلامتها دون كسر Plugins الحالية.
وعند التثبيت أثناء الإعداد من مسار فهرس محلي، يُسجَّل
إدخال plugins.installs مع source: "path" وsourcePath
نسبي لمساحة العمل عندما يكون ذلك ممكنًا. ويبقى مسار التحميل التشغيلي المطلق في
plugins.load.paths; ويتجنب سجل التثبيت تكرار مسارات محطة العمل المحلية
داخل إعدادات طويلة الأمد. ويحافظ ذلك على ظهور تثبيتات التطوير المحلية في
تشخيصات مستوى المصدر من دون إضافة سطح كشف ثانٍ خام لمسار نظام الملفات.
Plugins لمحرك السياق
تملك Plugins محرك السياق تنسيق سياق الجلسة لعمليات الإدخال، والتجميع، وCompaction. سجّلها من Plugin الخاص بك باستخدامapi.registerContextEngine(id, factory)، ثم اختر المحرك النشط عبر
plugins.slots.contextEngine.
استخدم هذا عندما يحتاج Plugin الخاص بك إلى استبدال مسار السياق الافتراضي
أو توسيعه بدلًا من مجرد إضافة بحث في الذاكرة أو خطافات.
compact()
منفذة وفوّضها صراحةً:
إضافة قدرة جديدة
عندما يحتاج Plugin إلى سلوك لا يلائم API الحالية، فلا تتجاوز نظام Plugin عبر وصول خاص داخلي. أضف القدرة الناقصة. التسلسل الموصى به:- تعريف العقد الأساسي حدّد السلوك المشترك الذي ينبغي أن تملكه النواة: السياسة، والرجوع الاحتياطي، ودمج الإعدادات، ودورة الحياة، والدلالات المواجهة للقنوات، وشكل أداة وقت التشغيل.
- إضافة أسطح تسجيل/وقت تشغيل مكتوبة لـ Plugin
وسّع
OpenClawPluginApiو/أوapi.runtimeبأصغر سطح قدرة مكتوب ومفيد. - ربط النواة + مستهلكي القنوات/الميزات يجب أن تستهلك القنوات وPlugins الميزات القدرة الجديدة من خلال النواة، لا عبر استيراد تنفيذ خاص بمورّد مباشرة.
- تسجيل تنفيذات المورّدين بعد ذلك تسجّل Plugins المورّدين الواجهات الخلفية الخاصة بها مقابل القدرة.
- إضافة تغطية للعقد أضف اختبارات حتى تبقى الملكية وشكل التسجيل واضحين مع مرور الوقت.
قائمة التحقق للقدرات
عندما تضيف قدرة جديدة، يجب عادةً أن يلمس التنفيذ هذه الأسطح معًا:- أنواع العقد الأساسية في
src/<capability>/types.ts - المشغّل/أداة وقت التشغيل الأساسية في
src/<capability>/runtime.ts - سطح تسجيل Plugin API في
src/plugins/types.ts - ربط سجل Plugin في
src/plugins/registry.ts - كشف وقت تشغيل Plugin في
src/plugins/runtime/*عندما تحتاج Plugins الميزات/القنوات إلى استهلاكه - أدوات الالتقاط/الاختبار في
src/test-utils/plugin-registration.ts - تأكيدات الملكية/العقد في
src/plugins/contracts/registry.ts - وثائق المشغّل/Plugin في
docs/
قالب القدرة
النمط الأدنى:- تملك النواة عقد القدرة + التنسيق
- تملك Plugins المورّدين التنفيذات الخاصة بالمورّد
- تستهلك Plugins الميزات/القنوات أدوات وقت التشغيل
- تُبقي اختبارات العقد الملكية واضحة
ذو صلة
- معمارية Plugin — نموذج القدرات العام والأشكال
- المسارات الفرعية لـ Plugin SDK
- إعداد Plugin SDK
- بناء Plugins