---
read_when:
    - بناء Plugins OpenClaw الأصلية أو تصحيح أخطائها
    - فهم نموذج قدرات Plugin أو حدود الملكية
    - العمل على مسار تحميل Plugin أو السجل
    - تنفيذ خطافات وقت تشغيل المزوّد أو Plugins القنوات
sidebarTitle: Internals
summary: 'داخليات Plugin: نموذج القدرات، الملكية، العقود، مسار التحميل، ومساعدات وقت التشغيل'
title: آليات Plugin الداخلية
x-i18n:
    generated_at: "2026-06-27T18:00:42Z"
    model: gpt-5.5
    postprocess_version: locale-links-v1
    provider: openai
    source_hash: 0e36f77594f16d7f03e31be81a241a15fb15c0b160f22a4dce863f6da184dfe3
    source_path: plugins/architecture.md
    workflow: 16
---

هذا هو **مرجع البنية العميق** لنظام OpenClaw Plugin. للأدلة العملية، ابدأ بإحدى الصفحات المركزة أدناه.

<CardGroup cols={2}>
  <Card title="تثبيت Plugins واستخدامها" icon="plug" href="/ar/tools/plugin">
    دليل المستخدم النهائي لإضافة Plugins وتمكينها واستكشاف مشكلاتها وإصلاحها.
  </Card>
  <Card title="بناء Plugins" icon="rocket" href="/ar/plugins/building-plugins">
    درس تعليمي لأول Plugin مع أصغر ملف manifest عامل.
  </Card>
  <Card title="Plugins القنوات" icon="comments" href="/ar/plugins/sdk-channel-plugins">
    ابنِ Plugin لقناة مراسلة.
  </Card>
  <Card title="Plugins المزوّدين" icon="microchip" href="/ar/plugins/sdk-provider-plugins">
    ابنِ Plugin لمزوّد نماذج.
  </Card>
  <Card title="نظرة عامة على SDK" icon="book" href="/ar/plugins/sdk-overview">
    مرجع خريطة الاستيراد وواجهة API للتسجيل.
  </Card>
</CardGroup>

## نموذج القدرات العام

القدرات هي نموذج **Plugin الأصلي** العام داخل OpenClaw. كل Plugin أصلي في OpenClaw يسجل نفسه مقابل نوع قدرة واحد أو أكثر:

| القدرة                | طريقة التسجيل                                      | أمثلة Plugins                         |
| ---------------------- | ------------------------------------------------ | ------------------------------------ |
| استدلال النص           | `api.registerProvider(...)`                      | `openai`, `anthropic`                |
| خلفية استدلال CLI      | `api.registerCliBackend(...)`                    | `openai`, `anthropic`                |
| التضمينات              | `api.registerEmbeddingProvider(...)`             | Plugins متجهات مملوكة للمزوّد        |
| الكلام                 | `api.registerSpeechProvider(...)`                | `elevenlabs`, `microsoft`            |
| النسخ الفوري           | `api.registerRealtimeTranscriptionProvider(...)` | `openai`                             |
| الصوت الفوري           | `api.registerRealtimeVoiceProvider(...)`         | `openai`                             |
| فهم الوسائط            | `api.registerMediaUnderstandingProvider(...)`    | `openai`, `google`                   |
| مصدر النصوص المنسوخة   | `api.registerTranscriptSourceProvider(...)`      | `discord`                            |
| توليد الصور            | `api.registerImageGenerationProvider(...)`       | `openai`, `google`, `fal`, `minimax` |
| توليد الموسيقى         | `api.registerMusicGenerationProvider(...)`       | `google`, `minimax`                  |
| توليد الفيديو          | `api.registerVideoGenerationProvider(...)`       | `qwen`                               |
| جلب الويب              | `api.registerWebFetchProvider(...)`              | `firecrawl`                          |
| بحث الويب              | `api.registerWebSearchProvider(...)`             | `google`                             |
| القناة / المراسلة      | `api.registerChannel(...)`                       | `msteams`, `matrix`                  |
| اكتشاف Gateway         | `api.registerGatewayDiscoveryService(...)`       | `bonjour`                            |

<Note>
أي Plugin يسجل صفر قدرات لكنه يوفر hooks أو أدوات أو خدمات اكتشاف أو خدمات خلفية هو Plugin **قديم يعتمد على hooks فقط**. لا يزال هذا النمط مدعوما بالكامل.
</Note>

### موقف التوافق الخارجي

نموذج القدرات مدمج في النواة ويُستخدم اليوم بواسطة Plugins المضمّنة/الأصلية، لكن توافق Plugins الخارجية ما زال يحتاج معيارا أدق من "تم تصديره، إذن صار ثابتا."

| حالة Plugin                                      | الإرشاد                                                                                         |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Plugins خارجية موجودة                            | أبقِ التكاملات المعتمدة على hooks عاملة؛ هذا هو خط أساس التوافق.                                |
| Plugins مضمّنة/أصلية جديدة                       | فضّل تسجيل القدرات الصريح على الوصولات الخاصة بالمورّد أو التصاميم الجديدة المعتمدة على hooks فقط. |
| Plugins خارجية تعتمد تسجيل القدرات               | مسموح، لكن تعامل مع أسطح المساعدات الخاصة بالقدرات على أنها متغيرة ما لم تضعها الوثائق كواجهات مستقرة. |

تسجيل القدرات هو الاتجاه المقصود. تظل hooks القديمة أكثر مسار آمن بلا كسر لـ Plugins الخارجية أثناء الانتقال. مسارات المساعدات الفرعية المصدّرة ليست كلها متساوية — فضّل العقود الضيقة الموثقة على تصديرات المساعدات العرضية.

### أشكال Plugin

يصنف OpenClaw كل Plugin محمّل إلى شكل بناء على سلوك تسجيله الفعلي (وليس البيانات الوصفية الثابتة فقط):

<AccordionGroup>
  <Accordion title="plain-capability">
    يسجل نوع قدرة واحدا بالضبط (على سبيل المثال Plugin خاص بالمزوّد فقط مثل `mistral`).
  </Accordion>
  <Accordion title="hybrid-capability">
    يسجل عدة أنواع قدرات (على سبيل المثال يملك `openai` استدلال النص والكلام وفهم الوسائط وتوليد الصور).
  </Accordion>
  <Accordion title="hook-only">
    يسجل hooks فقط (typed أو مخصصة)، بلا قدرات أو أدوات أو أوامر أو خدمات.
  </Accordion>
  <Accordion title="non-capability">
    يسجل أدوات أو أوامر أو خدمات أو مسارات، لكن بلا قدرات.
  </Accordion>
</AccordionGroup>

استخدم `openclaw plugins inspect <id>` لرؤية شكل Plugin وتفصيل قدراته. راجع [مرجع CLI](/ar/cli/plugins#inspect) للتفاصيل.

### hooks القديمة

يظل hook `before_agent_start` مدعوما كمسار توافق لـ Plugins المعتمدة على hooks فقط. ما زالت Plugins قديمة مستخدمة فعليا تعتمد عليه.

الاتجاه:

- إبقاؤه عاملا
- توثيقه كقديم
- تفضيل `before_model_resolve` لأعمال تجاوز النموذج/المزوّد
- تفضيل `before_prompt_build` لأعمال تعديل الموجه
- إزالته فقط بعد انخفاض الاستخدام الحقيقي وإثبات تغطية fixtures سلامة الترحيل

### إشارات التوافق

عند تشغيل `openclaw doctor` أو `openclaw plugins inspect <id>`، قد ترى أحد هذه التصنيفات:

| الإشارة                  | المعنى                                                       |
| -------------------------- | ------------------------------------------------------------ |
| **config valid**           | يتم تحليل الإعدادات بشكل سليم ويتم حل Plugins               |
| **compatibility advisory** | يستخدم Plugin نمطا مدعوما لكنه أقدم (مثل `hook-only`)       |
| **legacy warning**         | يستخدم Plugin ‏`before_agent_start`، وهو مهمل               |
| **hard error**             | الإعدادات غير صالحة أو فشل تحميل Plugin                     |

لن يكسر `hook-only` ولا `before_agent_start`‏ Plugin لديك اليوم: `hook-only` تنبيه إرشادي، و`before_agent_start` يطلق تحذيرا فقط. تظهر هذه الإشارات أيضا في `openclaw status --all` و`openclaw plugins doctor`.

## نظرة عامة على البنية

يتكون نظام OpenClaw Plugin من أربع طبقات:

<Steps>
  <Step title="Manifest + الاكتشاف">
    يجد OpenClaw Plugins المرشحة من المسارات المضبوطة وجذور مساحة العمل وجذور Plugins العامة وPlugins المضمّنة. يقرأ الاكتشاف أولا ملفات manifest الأصلية `openclaw.plugin.json` إضافة إلى ملفات manifest للحزم المدعومة.
  </Step>
  <Step title="التمكين + التحقق">
    تقرر النواة ما إذا كان Plugin المكتشف مفعلا أو معطلا أو محظورا أو محددا لخانة حصرية مثل الذاكرة.
  </Step>
  <Step title="تحميل وقت التشغيل">
    يتم تحميل Plugins OpenClaw الأصلية داخل العملية وتسجل القدرات في سجل مركزي. يتم تحميل JavaScript المعبأ عبر `require` الأصلي؛ أما TypeScript المحلي لمصدر طرف ثالث فهو مسار Jiti الاحتياطي الطارئ. يتم تطبيع الحزم المتوافقة إلى سجلات registry من دون استيراد كود وقت التشغيل.
  </Step>
  <Step title="استهلاك الأسطح">
    يقرأ باقي OpenClaw السجل لكشف الأدوات والقنوات وإعداد المزوّدين وhooks ومسارات HTTP وأوامر CLI والخدمات.
  </Step>
</Steps>

بالنسبة إلى CLI الخاص بـ Plugin تحديدا، ينقسم اكتشاف الأمر الجذري إلى مرحلتين:

- تأتي البيانات الوصفية وقت التحليل من `registerCli(..., { descriptors: [...] })`
- يمكن أن تبقى وحدة CLI الفعلية الخاصة بـ Plugin كسولة وتسجل نفسها عند أول استدعاء

يبقي ذلك كود CLI المملوك لـ Plugin داخل Plugin مع السماح لـ OpenClaw بحجز أسماء الأوامر الجذرية قبل التحليل.

حد التصميم المهم:

- يجب أن يعمل تحقق manifest/config من **بيانات manifest/schema الوصفية** من دون تنفيذ كود Plugin
- يمكن لاكتشاف القدرات الأصلي تحميل كود إدخال Plugin موثوق لبناء لقطة registry غير مفعِّلة
- يأتي سلوك وقت التشغيل الأصلي من مسار `register(api)` في وحدة Plugin مع `api.registrationMode === "full"`

يتيح هذا الفصل لـ OpenClaw التحقق من الإعدادات وشرح Plugins المفقودة/المعطلة وبناء تلميحات UI/schema قبل تنشيط وقت التشغيل الكامل.

### لقطة بيانات Plugin الوصفية وجدول البحث

يبني بدء تشغيل Gateway لقطة `PluginMetadataSnapshot` واحدة للقطة الإعدادات الحالية. اللقطة بيانات وصفية فقط: تخزن فهرس Plugins المثبتة وسجل manifest وتشخيصات manifest وخرائط المالك ومطبّع معرّف Plugin وسجلات manifest. لا تحتفظ بوحدات Plugin المحمّلة أو SDKs المزوّدين أو محتويات الحزم أو صادرات وقت التشغيل.

يستهلك تحقق الإعدادات الواعي بـ Plugin والتمكين التلقائي عند بدء التشغيل وتمهيد Plugin في Gateway تلك اللقطة بدلا من إعادة بناء بيانات manifest/index الوصفية بشكل مستقل. يُشتق `PluginLookUpTable` من اللقطة نفسها ويضيف خطة Plugins عند بدء التشغيل لإعدادات وقت التشغيل الحالية.

بعد بدء التشغيل، يحتفظ Gateway بلقطة البيانات الوصفية الحالية كمنتج وقت تشغيل قابل للاستبدال. يمكن لاكتشاف مزوّدي وقت التشغيل المتكرر استعارة تلك اللقطة بدلا من إعادة بناء الفهرس المثبت وسجل manifest لكل تمريرة كتالوج مزوّد. تُمسح اللقطة أو تُستبدل عند إيقاف Gateway وتغييرات الإعدادات/مخزون Plugins وكتابات الفهرس المثبت؛ يعود المستدعون إلى مسار manifest/index البارد عندما لا توجد لقطة حالية متوافقة. يجب أن تشمل فحوصات التوافق جذور اكتشاف Plugins مثل `plugins.load.paths` ومساحة عمل الوكيل الافتراضية، لأن Plugins مساحة العمل جزء من نطاق البيانات الوصفية.

تحافظ اللقطة وجدول البحث على قرارات بدء التشغيل المتكررة ضمن المسار السريع:

- ملكية القناة
- بدء تشغيل القناة المؤجل
- معرّفات Plugins عند بدء التشغيل
- ملكية المزوّد وخلفية CLI
- ملكية مزوّد الإعداد والاسم المستعار للأمر ومزوّد كتالوج النماذج وعقد manifest
- التحقق من مخطط إعدادات Plugin ومخطط إعدادات القناة
- قرارات التمكين التلقائي عند بدء التشغيل

حد السلامة هو استبدال اللقطة، لا تعديلها. أعد بناء اللقطة عندما تتغير الإعدادات أو مخزون Plugins أو سجلات التثبيت أو سياسة الفهرس المستمر. لا تعاملها كسجل عالمي واسع قابل للتعديل، ولا تحتفظ بلقطات تاريخية غير محدودة. يظل تحميل Plugins في وقت التشغيل منفصلا عن لقطات البيانات الوصفية حتى لا تختبئ حالة وقت تشغيل قديمة خلف ذاكرة تخزين مؤقت للبيانات الوصفية.

قاعدة الذاكرة المؤقتة موثقة في [داخليات بنية Plugin](/ar/plugins/architecture-internals#plugin-cache-boundary): تكون بيانات manifest والاكتشاف الوصفية حديثة ما لم يحتفظ مستدع بلقطة صريحة أو جدول بحث أو سجل manifest للتدفق الحالي. ليست الذاكرات المؤقتة المخفية للبيانات الوصفية ولا TTLs المعتمدة على ساعة الحائط جزءا من تحميل Plugin. فقط ذاكرات التخزين المؤقت لمحمل وقت التشغيل والوحدات وآثار التبعيات يمكن أن تستمر بعد تحميل الكود أو الآثار المثبتة فعليا.

ما زال بعض مستدعي المسار البارد يعيدون بناء سجلات manifest مباشرة من فهرس Plugins المثبتة المستمر بدلا من تلقي `PluginLookUpTable` من Gateway. يعيد ذلك المسار الآن بناء السجل عند الطلب؛ فضّل تمرير جدول البحث الحالي أو سجل manifest صريح عبر تدفقات وقت التشغيل عندما يكون لدى المستدعي واحد بالفعل.

### تخطيط التنشيط

تخطيط التنشيط جزء من مستوى التحكم. يمكن للمستدعين طلب معرفة أي Plugins ذات صلة بأمر أو مزوّد أو قناة أو مسار أو حزمة وكيل أو قدرة ملموسة قبل تحميل سجلات وقت تشغيل أوسع.

يحافظ المخطط على توافق سلوك manifest الحالي:

- حقول `activation.*` هي تلميحات مخطِّط صريحة
- تبقى `providers` و`channels` و`commandAliases` و`setup.providers` و`contracts.tools` والخطافات بمثابة رجوع احتياطي لملكية البيان
- تبقى واجهة API الخاصة بالمخطِّط المعتمدة على المعرّفات فقط متاحة للمستدعين الحاليين
- تُبلغ واجهة API الخاصة بالخطة عن تسميات الأسباب حتى تتمكن أدوات التشخيص من التمييز بين التلميحات الصريحة والرجوع الاحتياطي للملكية

<Warning>
لا تتعامل مع `activation` كخطاف دورة حياة أو كبديل عن `register(...)`. إنها بيانات وصفية تُستخدم لتضييق التحميل. فضّل حقول الملكية عندما تصف العلاقة بالفعل؛ واستخدم `activation` فقط لتلميحات المخطِّط الإضافية.
</Warning>

### Plugins القنوات وأداة الرسائل المشتركة

لا تحتاج Plugins القنوات إلى تسجيل أداة إرسال/تعديل/تفاعل منفصلة لإجراءات المحادثة العادية. يحتفظ OpenClaw بأداة `message` مشتركة واحدة في النواة، وتملك Plugins القنوات الاكتشاف والتنفيذ الخاصين بالقناة خلفها.

الحد الحالي هو:

- تملك النواة مضيف أداة `message` المشتركة، وربط الموجه، وحفظ سجلات الجلسة/الخيط، وإرسال التنفيذ
- تملك Plugins القنوات اكتشاف الإجراءات المحددة النطاق، واكتشاف القدرات، وأي أجزاء مخطط خاصة بالقناة
- تملك Plugins القنوات قواعد محادثة الجلسة الخاصة بالمزوّد، مثل كيفية ترميز معرّفات المحادثة لمعرّفات الخيوط أو وراثتها من المحادثات الأصلية
- تنفّذ Plugins القنوات الإجراء النهائي عبر محوّل الإجراء الخاص بها

بالنسبة إلى Plugins القنوات، سطح SDK هو `ChannelMessageActionAdapter.describeMessageTool(...)`. تتيح استدعاءة الاكتشاف الموحدة هذه لـ Plugin إرجاع إجراءاته المرئية وقدراته ومساهماته في المخطط معًا حتى لا تنفصل هذه الأجزاء عن بعضها.

عندما تحمل معلمة أداة رسائل خاصة بالقناة مصدر وسائط مثل مسار محلي أو عنوان URL لوسائط بعيدة، ينبغي لـ Plugin أيضًا إرجاع `mediaSourceParams` من `describeMessageTool(...)`. تستخدم النواة هذه القائمة الصريحة لتطبيق تطبيع مسارات الصندوق الرملي وتلميحات الوصول إلى الوسائط الصادرة بدون ترميز أسماء المعلمات المملوكة لـ Plugin بشكل ثابت. فضّل الخرائط المحددة بنطاق الإجراء هناك، وليس قائمة مسطحة واحدة على مستوى القناة، حتى لا تُطبّع معلمة وسائط خاصة بالملف الشخصي على إجراءات غير مرتبطة مثل `send`.

تمرر النواة نطاق وقت التشغيل إلى خطوة الاكتشاف هذه. تشمل الحقول المهمة:

- `accountId`
- `currentChannelId`
- `currentThreadTs`
- `currentMessageId`
- `sessionKey`
- `sessionId`
- `agentId`
- `requesterSenderId` الوارد والموثوق

هذا مهم لـ Plugins الحساسة للسياق. يمكن للقناة إخفاء إجراءات الرسائل أو إظهارها بناءً على الحساب النشط، أو الغرفة/الخيط/الرسالة الحالية، أو هوية الطالب الموثوقة بدون ترميز فروع خاصة بالقناة بشكل ثابت في أداة `message` داخل النواة.

لهذا السبب تبقى تغييرات توجيه المشغّل المضمّن عملاً خاصًا بـ Plugin: يكون المشغّل مسؤولاً عن تمرير هوية المحادثة/الجلسة الحالية إلى حد اكتشاف Plugin حتى تعرض أداة `message` المشتركة السطح الصحيح المملوك للقناة للدورة الحالية.

بالنسبة إلى مساعدات التنفيذ المملوكة للقناة، ينبغي أن تحتفظ Plugins المضمّنة بوقت تشغيل التنفيذ داخل وحدات الامتداد الخاصة بها. لم تعد النواة تملك أوقات تشغيل إجراءات الرسائل الخاصة بـ Discord أو Slack أو Telegram أو WhatsApp تحت `src/agents/tools`. لا ننشر مسارات فرعية منفصلة `plugin-sdk/*-action-runtime`، وينبغي أن تستورد Plugins المضمّنة كود وقت التشغيل المحلي الخاص بها مباشرة من الوحدات المملوكة لامتدادها.

ينطبق الحد نفسه على منافذ SDK المسماة باسم المزوّد عمومًا: لا ينبغي أن تستورد النواة براميل الملاءمة الخاصة بالقنوات لـ Slack أو Discord أو Signal أو WhatsApp أو الامتدادات المشابهة. إذا احتاجت النواة إلى سلوك ما، فإما أن تستهلك برميل `api.ts` / `runtime-api.ts` الخاص بـ Plugin المضمّن نفسه، أو ترفع الحاجة إلى قدرة عامة ضيقة في SDK المشترك.

تتبع Plugins المضمّنة القاعدة نفسها. لا ينبغي لـ `runtime-api.ts` الخاص بـ Plugin مضمّن أن يعيد تصدير واجهة الواجهة ذات العلامة التجارية الخاصة به `openclaw/plugin-sdk/<plugin-id>`. تبقى هذه الواجهات ذات العلامة التجارية حشوات توافقية لـ Plugins الخارجية والمستهلكين الأقدم، لكن ينبغي أن تستخدم Plugins المضمّنة التصديرات المحلية مع مسارات SDK عامة ضيقة مثل `openclaw/plugin-sdk/channel-policy` أو `openclaw/plugin-sdk/runtime-store` أو `openclaw/plugin-sdk/webhook-ingress`. لا ينبغي أن يضيف الكود الجديد واجهات SDK خاصة بمعرّف Plugin إلا إذا كان حد التوافق لنظام خارجي قائم يتطلب ذلك.

بالنسبة إلى الاستطلاعات تحديدًا، يوجد مساران للتنفيذ:

- `outbound.sendPoll` هو خط الأساس المشترك للقنوات التي تناسب نموذج الاستطلاع المشترك
- `actions.handleAction("poll")` هو المسار المفضّل لدلالات الاستطلاع الخاصة بالقناة أو معلمات الاستطلاع الإضافية

تؤجل النواة الآن تحليل الاستطلاع المشترك إلى ما بعد رفض إرسال استطلاع Plugin للإجراء، بحيث يمكن لمعالجات الاستطلاع المملوكة لـ Plugin قبول حقول الاستطلاع الخاصة بالقناة بدون أن يحجبها محلل الاستطلاع العام أولاً.

راجع [التفاصيل الداخلية لمعمارية Plugin](/ar/plugins/architecture-internals) لتسلسل بدء التشغيل الكامل.

## نموذج ملكية القدرات

يتعامل OpenClaw مع Plugin الأصلي كحد ملكية لـ **شركة** أو **ميزة**، وليس كمجموعة عشوائية من تكاملات غير مرتبطة.

هذا يعني:

- ينبغي عادةً أن يملك Plugin الشركة كل الأسطح المواجهة لـ OpenClaw الخاصة بتلك الشركة
- ينبغي عادةً أن يملك Plugin الميزة كامل سطح الميزة الذي يقدمه
- ينبغي أن تستهلك القنوات قدرات النواة المشتركة بدلاً من إعادة تنفيذ سلوك المزوّد بشكل مخصص

<AccordionGroup>
  <Accordion title="مزوّد متعدد القدرات">
    يملك `openai` الاستدلال النصي، والكلام، والصوت الفوري، وفهم الوسائط، وتوليد الصور. يملك `google` الاستدلال النصي إضافة إلى فهم الوسائط، وتوليد الصور، والبحث على الويب. يملك `qwen` الاستدلال النصي إضافة إلى فهم الوسائط وتوليد الفيديو.
  </Accordion>
  <Accordion title="مزوّد أحادي القدرة">
    يملك `elevenlabs` و`microsoft` الكلام؛ ويملك `firecrawl` جلب الويب؛ وتملك `minimax` / `mistral` / `moonshot` / `zai` خلفيات فهم الوسائط.
  </Accordion>
  <Accordion title="Plugin ميزة">
    يملك `voice-call` نقل المكالمات، والأدوات، وCLI، والمسارات، وجسر تدفقات وسائط Twilio، لكنه يستهلك قدرات الكلام المشتركة، والنسخ الفوري، والصوت الفوري بدلاً من استيراد Plugins المزوّدين مباشرة.
  </Accordion>
</AccordionGroup>

الحالة النهائية المقصودة هي:

- يعيش OpenAI في Plugin واحد حتى إذا امتد عبر النماذج النصية، والكلام، والصور، والفيديو المستقبلي
- يمكن لمزوّد آخر أن يفعل الشيء نفسه لمنطقة سطحه الخاصة
- لا تهتم القنوات بأي Plugin مزوّد يملك المزوّد؛ فهي تستهلك عقد القدرة المشترك الذي تعرضه النواة

هذا هو التمييز الأساسي:

- **plugin** = حد الملكية
- **capability** = عقد النواة الذي يمكن لعدة Plugins تنفيذه أو استهلاكه

لذلك إذا أضاف OpenClaw مجالاً جديدًا مثل الفيديو، فالسؤال الأول ليس "أي مزوّد ينبغي أن يرمّز التعامل مع الفيديو بشكل ثابت؟" السؤال الأول هو "ما عقد قدرة الفيديو في النواة؟" بعد وجود هذا العقد، يمكن لـ Plugins المزوّدين التسجيل ضده ويمكن لـ Plugins القنوات/الميزات استهلاكه.

إذا لم تكن القدرة موجودة بعد، فعادةً ما تكون الخطوة الصحيحة هي:

<Steps>
  <Step title="تعريف القدرة">
    عرّف القدرة المفقودة في النواة.
  </Step>
  <Step title="عرضها عبر SDK">
    اعرضها عبر واجهة Plugin API/وقت التشغيل بطريقة مكتوبة الأنواع.
  </Step>
  <Step title="توصيل المستهلكين">
    صِل القنوات/الميزات بتلك القدرة.
  </Step>
  <Step title="تنفيذات المزوّدين">
    دع Plugins المزوّدين تسجل التنفيذات.
  </Step>
</Steps>

يحافظ هذا على صراحة الملكية مع تجنب سلوك في النواة يعتمد على مزوّد واحد أو مسار كود مخصص لـ Plugin واحد.

### طبقات القدرات

استخدم هذا النموذج الذهني عند تحديد مكان الكود:

<Tabs>
  <Tab title="طبقة قدرة النواة">
    التنسيق المشترك، والسياسة، والرجوع الاحتياطي، وقواعد دمج الإعدادات، ودلالات التسليم، والعقود المكتوبة الأنواع.
  </Tab>
  <Tab title="طبقة Plugin المزوّد">
    واجهات API الخاصة بالمزوّد، والمصادقة، وفهارس النماذج، وتوليف الكلام، وتوليد الصور، وخلفيات الفيديو المستقبلية، ونقاط نهاية الاستخدام.
  </Tab>
  <Tab title="طبقة Plugin القناة/الميزة">
    تكامل Slack/Discord/voice-call/etc. الذي يستهلك قدرات النواة ويعرضها على سطح.
  </Tab>
</Tabs>

على سبيل المثال، يتبع TTS هذا الشكل:

- تملك النواة سياسة TTS وقت الرد، وترتيب الرجوع الاحتياطي، والتفضيلات، وتسليم القناة
- يملك `openai` و`elevenlabs` و`microsoft` تنفيذات التوليف
- يستهلك `voice-call` مساعد وقت تشغيل TTS الهاتفي

ينبغي تفضيل هذا النمط نفسه للقدرات المستقبلية.

### مثال Plugin شركة متعدد القدرات

ينبغي أن يبدو Plugin الشركة متماسكًا من الخارج. إذا كان لدى OpenClaw عقود مشتركة للنماذج، والكلام، والنسخ الفوري، والصوت الفوري، وفهم الوسائط، وتوليد الصور، وتوليد الفيديو، وجلب الويب، والبحث على الويب، فيمكن للمزوّد أن يملك كل أسطحه في مكان واحد:

```ts
import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry";
import {
  describeImageWithModel,
  transcribeOpenAiCompatibleAudio,
} from "openclaw/plugin-sdk/media-understanding";

const plugin: OpenClawPluginDefinition = {
  id: "exampleai",
  name: "ExampleAI",
  register(api) {
    api.registerProvider({
      id: "exampleai",
      // auth/model catalog/runtime hooks
    });

    api.registerSpeechProvider({
      id: "exampleai",
      // vendor speech config — implement the SpeechProviderPlugin interface directly
    });

    api.registerMediaUnderstandingProvider({
      id: "exampleai",
      capabilities: ["image", "audio", "video"],
      async describeImage(req) {
        return describeImageWithModel({
          provider: "exampleai",
          model: req.model,
          input: req.input,
        });
      },
      async transcribeAudio(req) {
        return transcribeOpenAiCompatibleAudio({
          provider: "exampleai",
          model: req.model,
          input: req.input,
        });
      },
    });

    api.registerWebSearchProvider(
      createPluginBackedWebSearchProvider({
        id: "exampleai-search",
        // credential + fetch logic
      }),
    );
  },
};

export default plugin;
```

ما يهم ليس أسماء المساعدات الدقيقة. الشكل هو المهم:

- يملك Plugin واحد سطح المزوّد
- لا تزال النواة تملك عقود القدرات
- تستهلك القنوات وPlugins الميزات مساعدات `api.runtime.*`، وليس كود المزوّد
- يمكن لاختبارات العقد التأكد من أن Plugin سجّل القدرات التي يدّعي امتلاكها

### مثال قدرة: فهم الفيديو

يتعامل OpenClaw بالفعل مع فهم الصور/الصوت/الفيديو كقدرة مشتركة واحدة. ينطبق نموذج الملكية نفسه هناك:

<Steps>
  <Step title="النواة تعرّف العقد">
    تعرّف النواة عقد فهم الوسائط.
  </Step>
  <Step title="Plugins المزوّدين تسجل">
    تسجل Plugins المزوّدين `describeImage` و`transcribeAudio` و`describeVideo` عند الاقتضاء.
  </Step>
  <Step title="المستهلكون يستخدمون السلوك المشترك">
    تستهلك القنوات وPlugins الميزات سلوك النواة المشترك بدلاً من التوصيل مباشرة بكود المزوّد.
  </Step>
</Steps>

يتجنب ذلك تضمين افتراضات الفيديو الخاصة بمزوّد واحد في النواة. يملك Plugin سطح المزوّد؛ وتملك النواة عقد القدرة وسلوك الرجوع الاحتياطي.

يستخدم توليد الفيديو بالفعل التسلسل نفسه: تملك النواة عقد القدرة المكتوب الأنواع ومساعد وقت التشغيل، وتسجل Plugins المزوّدين تنفيذات `api.registerVideoGenerationProvider(...)` ضده.

هل تحتاج إلى قائمة طرح عملية؟ راجع [دليل إعداد القدرات](/ar/plugins/adding-capabilities).

## العقود والإنفاذ

سطح واجهة Plugin API مكتوب الأنواع ومركزي عمدًا في `OpenClawPluginApi`. يعرّف ذلك العقد نقاط التسجيل المدعومة ومساعدات وقت التشغيل التي يمكن لـ Plugin الاعتماد عليها.

لماذا هذا مهم:

- يحصل مؤلفو Plugins على معيار داخلي مستقر واحد
- يمكن للنواة رفض الملكية المكررة، مثل تسجيل Pluginين لمعرّف المزوّد نفسه
- يمكن لبدء التشغيل إظهار تشخيصات قابلة للتنفيذ للتسجيلات غير الصحيحة
- يمكن لاختبارات العقد فرض ملكية Plugins المضمّنة ومنع الانحراف الصامت

توجد طبقتان من الإنفاذ:

<AccordionGroup>
  <Accordion title="فرض تسجيل وقت التشغيل">
    يتحقق سجل Plugins من التسجيلات أثناء تحميل Plugins. أمثلة: معرّفات موفري نماذج مكررة، ومعرّفات موفري كلام مكررة، وتسجيلات مشوهة تنتج تشخيصات Plugin بدلاً من سلوك غير محدد.
  </Accordion>
  <Accordion title="اختبارات العقد">
    تُلتقط Plugins المضمنة في سجلات عقود أثناء تشغيل الاختبارات لكي يتمكن OpenClaw من تأكيد الملكية صراحة. يُستخدم هذا اليوم لموفري النماذج، وموفري الكلام، وموفري بحث الويب، وملكية التسجيل المضمنة.
  </Accordion>
</AccordionGroup>

الأثر العملي هو أن OpenClaw يعرف مسبقاً أي Plugin يملك أي سطح. يتيح ذلك للنواة والقنوات أن تتراكب بسلاسة لأن الملكية معلنة ومكتوبة النوع وقابلة للاختبار بدلاً من أن تكون ضمنية.

### ما الذي ينتمي إلى عقد

<Tabs>
  <Tab title="عقود جيدة">
    - مكتوبة النوع
    - صغيرة
    - خاصة بالقدرة
    - مملوكة للنواة
    - قابلة لإعادة الاستخدام بواسطة عدة Plugins
    - قابلة للاستهلاك بواسطة القنوات/الميزات من دون معرفة بالمورّد

  </Tab>
  <Tab title="عقود سيئة">
    - سياسة خاصة بالمورّد مخفية في النواة
    - منافذ هروب Plugin لمرة واحدة تتجاوز السجل
    - كود قناة يصل مباشرة إلى تنفيذ مورّد
    - كائنات وقت تشغيل مخصصة ليست جزءاً من `OpenClawPluginApi` أو `api.runtime`

  </Tab>
</Tabs>

عند الشك، ارفع مستوى التجريد: عرّف القدرة أولاً، ثم دع Plugins تتصل بها.

## نموذج التنفيذ

تعمل Plugins الأصلية في OpenClaw **داخل العملية** مع Gateway. ولا تعمل داخل صندوق رمل. يملك Plugin أصلي محمّل حد الثقة نفسه على مستوى العملية مثل كود النواة.

<Warning>
آثار Plugin الأصلي: يمكن لـ Plugin تسجيل أدوات، ومعالجات شبكة، وخطافات، وخدمات؛ ويمكن لخلل في Plugin أن يعطل Gateway أو يزعزع استقراره؛ كما أن Plugin أصلياً خبيثاً يعادل تنفيذ كود عشوائي داخل عملية OpenClaw.
</Warning>

تكون الحزم المتوافقة أكثر أماناً افتراضياً لأن OpenClaw يتعامل معها حالياً كحزم بيانات وصفية/محتوى. في الإصدارات الحالية، يعني ذلك غالباً Skills المضمنة.

استخدم قوائم السماح ومسارات التثبيت/التحميل الصريحة للـ Plugins غير المضمنة. تعامل مع Plugins مساحة العمل ككود وقت تطوير، لا كافتراضات إنتاج.

بالنسبة إلى أسماء حزم مساحة العمل المضمنة، أبقِ معرّف Plugin مثبتاً في اسم npm: `@openclaw/<id>` افتراضياً، أو لاحقة مكتوبة النوع ومعتمدة مثل `-provider` أو `-plugin` أو `-speech` أو `-sandbox` أو `-media-understanding` عندما تعرض الحزمة دور Plugin أضيق عمداً.

<Note>
**ملاحظة ثقة:** يثق `plugins.allow` بـ **معرّفات Plugins**، لا بمصدرها. يطغى Plugin مساحة عمل بالمعرّف نفسه مثل Plugin مضمن عمداً على النسخة المضمنة عندما يكون Plugin مساحة العمل ذلك مفعلاً/مضافاً إلى قائمة السماح. هذا طبيعي ومفيد للتطوير المحلي، واختبار التصحيحات، والإصلاحات العاجلة. تُحسم ثقة Plugin المضمن من لقطة المصدر — البيان والكود على القرص وقت التحميل — بدلاً من بيانات التثبيت الوصفية. لا يمكن لسجل تثبيت تالف أو مستبدل أن يوسّع بصمت سطح ثقة Plugin مضمن إلى ما يتجاوز ما يدعيه المصدر الفعلي.
</Note>

## حد التصدير

يصدّر OpenClaw القدرات، لا وسائل الراحة في التنفيذ.

أبقِ تسجيل القدرات عاماً. قلّص تصديرات المساعدات غير العقدية:

- مسارات فرعية لمساعدات خاصة بـ Plugin مضمن
- مسارات فرعية لتمديدات وقت التشغيل غير مقصودة كواجهة API عامة
- مساعدات تسهيل خاصة بالمورّد
- مساعدات الإعداد/التعريف الأولي التي تعد تفاصيل تنفيذ

أُحيلت المسارات الفرعية المحجوزة لمساعدات Plugins المضمنة إلى التقاعد من خريطة تصدير SDK المولدة. أبقِ المساعدات الخاصة بالمالك داخل حزمة Plugin المالكة؛ ولا ترقِّ إلا سلوك المضيف القابل لإعادة الاستخدام إلى عقود SDK عامة مثل `plugin-sdk/gateway-runtime` و`plugin-sdk/security-runtime` و`plugin-sdk/plugin-config-runtime`.

## التفاصيل الداخلية والمرجع

لخط تحميل، ونموذج السجل، وخطافات وقت تشغيل الموفر، ومسارات HTTP في Gateway، ومخططات أدوات الرسائل، وحل أهداف القنوات، وكتالوجات الموفرين، وPlugins محرك السياق، ودليل إضافة قدرة جديدة، راجع [التفاصيل الداخلية لبنية Plugin](/ar/plugins/architecture-internals).

## ذات صلة

- [بناء Plugins](/ar/plugins/building-plugins)
- [بيان Plugin](/ar/plugins/manifest)
- [إعداد SDK الخاص بـ Plugin](/ar/plugins/sdk-setup)
