diff --git a/docs/ar/channels/msteams.md b/docs/ar/channels/msteams.md index b4c16f0f5..cc989fd84 100644 --- a/docs/ar/channels/msteams.md +++ b/docs/ar/channels/msteams.md @@ -1,56 +1,56 @@ --- read_when: - العمل على ميزات قناة Microsoft Teams -summary: حالة دعم بوت Microsoft Teams وإمكاناته وإعداده +summary: حالة دعم بوت Microsoft Teams، والإمكانات، والإعدادات title: Microsoft Teams x-i18n: - generated_at: "2026-04-05T12:37:11Z" + generated_at: "2026-04-12T00:18:53Z" model: gpt-5.4 provider: openai - source_hash: 99fc6e136893ec65dc85d3bc0c0d92134069a2f3b8cb4fcf66c14674399b3eaf + source_hash: 3e6841a618fb030e4c2029b3652d45dedd516392e2ae17309ff46b93648ffb79 source_path: channels/msteams.md workflow: 15 --- # Microsoft Teams -> "اتركوا كل أمل، يا من تدخلون هنا." +> "تخلَّوا عن كل أمل، يا من تدخلون هنا." -تم التحديث: 2026-01-21 +تم التحديث: 2026-03-25 -الحالة: النص + مرفقات الرسائل المباشرة مدعومان؛ ويتطلب إرسال الملفات في القنوات/المجموعات `sharePointSiteId` + أذونات Graph (راجع [إرسال الملفات في الدردشات الجماعية](#sending-files-in-group-chats)). تُرسل الاستطلاعات عبر Adaptive Cards. وتعرض إجراءات الرسائل الإجراء الصريح `upload-file` لعمليات الإرسال التي تبدأ بالملف. +الحالة: النص + مرفقات الرسائل المباشرة مدعومان؛ يتطلب إرسال الملفات في القنوات/المجموعات `sharePointSiteId` + أذونات Graph (راجع [إرسال الملفات في الدردشات الجماعية](#sending-files-in-group-chats)). تُرسَل الاستطلاعات عبر Adaptive Cards. تعرض إجراءات الرسائل `upload-file` بشكل صريح لعمليات الإرسال التي تبدأ بالملفات. -## المكون الإضافي المضمّن +## المكون الإضافي المضمَّن -يأتي Microsoft Teams كمكون إضافي مضمّن في إصدارات OpenClaw الحالية، لذلك لا يلزم +يأتي Microsoft Teams كمكون إضافي مضمَّن في إصدارات OpenClaw الحالية، لذا لا يلزم أي تثبيت منفصل في البنية المعبأة العادية. -إذا كنت تستخدم إصدارًا أقدم أو تثبيتًا مخصصًا يستبعد Teams المضمّن، +إذا كنت تستخدم إصدارًا أقدم أو تثبيتًا مخصصًا لا يتضمن Teams المضمَّن، فقم بتثبيته يدويًا: ```bash openclaw plugins install @openclaw/msteams ``` -نسخة checkout محلية (عند التشغيل من مستودع git): +نسخة محلية (عند التشغيل من مستودع git): ```bash openclaw plugins install ./path/to/local/msteams-plugin ``` -التفاصيل: [Plugins](/tools/plugin) +التفاصيل: [المكونات الإضافية](/ar/tools/plugin) -## إعداد سريع (للمبتدئين) +## الإعداد السريع (للمبتدئين) -1. تأكد من أن المكون الإضافي لـ Microsoft Teams متاح. +1. تأكد من أن المكون الإضافي Microsoft Teams متاح. - إصدارات OpenClaw المعبأة الحالية تتضمنه بالفعل. - - يمكن للإصدارات/التثبيتات الأقدم أو المخصصة إضافته يدويًا بالأوامر أعلاه. -2. أنشئ **Azure Bot** ‏(App ID + client secret + tenant ID). + - يمكن لعمليات التثبيت الأقدم/المخصصة إضافته يدويًا باستخدام الأوامر أعلاه. +2. أنشئ **Azure Bot** (معرّف التطبيق + سر العميل + معرّف المستأجر). 3. اضبط OpenClaw باستخدام بيانات الاعتماد هذه. -4. اكشف `/api/messages` ‏(المنفذ 3978 افتراضيًا) عبر URL عام أو نفق. -5. ثبّت حزمة تطبيق Teams وابدأ gateway. +4. عرّض `/api/messages` (المنفذ 3978 افتراضيًا) عبر عنوان URL عام أو نفق. +5. ثبّت حزمة تطبيق Teams وابدأ البوابة. -الحد الأدنى من الإعداد: +الإعدادات الدنيا (سر العميل): ```json5 { @@ -66,19 +66,21 @@ openclaw plugins install ./path/to/local/msteams-plugin } ``` -ملاحظة: تُحظر الدردشات الجماعية افتراضيًا (`channels.msteams.groupPolicy: "allowlist"`). للسماح بالردود في المجموعات، اضبط `channels.msteams.groupAllowFrom` (أو استخدم `groupPolicy: "open"` للسماح لأي عضو، مع تقييد الإشارات). +بالنسبة لعمليات النشر الإنتاجية، فكّر في استخدام [المصادقة الاتحادية](#federated-authentication-certificate--managed-identity) (شهادة أو هوية مُدارة) بدلًا من أسرار العميل. + +ملاحظة: يتم حظر الدردشات الجماعية افتراضيًا (`channels.msteams.groupPolicy: "allowlist"`). للسماح بالردود الجماعية، اضبط `channels.msteams.groupAllowFrom` (أو استخدم `groupPolicy: "open"` للسماح لأي عضو، مع اشتراط الإشارة). ## الأهداف -- التحدث إلى OpenClaw عبر الرسائل المباشرة في Teams أو الدردشات الجماعية أو القنوات. -- إبقاء التوجيه حتميًا: تعود الردود دائمًا إلى القناة التي وصلت منها. -- الاعتماد افتراضيًا على سلوك آمن للقناة (الإشارات مطلوبة ما لم يتم تكوين خلاف ذلك). +- التحدث إلى OpenClaw عبر رسائل Teams المباشرة أو الدردشات الجماعية أو القنوات. +- الحفاظ على توجيه حتمي: تعود الردود دائمًا إلى القناة التي وصلت منها. +- اعتماد سلوك آمن للقنوات افتراضيًا (الإشارات مطلوبة ما لم يتم ضبط خلاف ذلك). -## عمليات كتابة الإعداد +## كتابات الإعدادات -يُسمح افتراضيًا لـ Microsoft Teams بكتابة تحديثات الإعداد الناتجة عن `/config set|unset` (يتطلب `commands.config: true`). +افتراضيًا، يُسمح لـ Microsoft Teams بكتابة تحديثات الإعدادات التي يتم تشغيلها بواسطة `/config set|unset` (يتطلب `commands.config: true`). -عطّل ذلك باستخدام: +للتعطيل: ```json5 { @@ -88,18 +90,18 @@ openclaw plugins install ./path/to/local/msteams-plugin ## التحكم في الوصول (الرسائل المباشرة + المجموعات) -**الوصول عبر الرسائل المباشرة** +**الوصول إلى الرسائل المباشرة** - الافتراضي: `channels.msteams.dmPolicy = "pairing"`. يتم تجاهل المرسلين غير المعروفين حتى تتم الموافقة عليهم. - يجب أن يستخدم `channels.msteams.allowFrom` معرّفات كائنات AAD الثابتة. -- أسماء UPN/العرض قابلة للتغيير؛ والمطابقة المباشرة معطلة افتراضيًا ولا تُفعّل إلا باستخدام `channels.msteams.dangerouslyAllowNameMatching: true`. -- يمكن للمعالج تحويل الأسماء إلى معرّفات عبر Microsoft Graph عندما تسمح بيانات الاعتماد بذلك. +- أسماء UPN/العرض قابلة للتغيير؛ والمطابقة المباشرة معطلة افتراضيًا ولا تُفعّل إلا مع `channels.msteams.dangerouslyAllowNameMatching: true`. +- يمكن للمعالج حلّ الأسماء إلى معرّفات عبر Microsoft Graph عندما تسمح بيانات الاعتماد بذلك. **الوصول إلى المجموعات** -- الافتراضي: `channels.msteams.groupPolicy = "allowlist"` (محظور ما لم تضف `groupAllowFrom`). استخدم `channels.defaults.groupPolicy` لتجاوز القيمة الافتراضية عند عدم ضبطها. -- يتحكم `channels.msteams.groupAllowFrom` في المرسلين الذين يمكنهم التشغيل في الدردشات/القنوات الجماعية (ويعود إلى `channels.msteams.allowFrom` عند الحاجة). -- اضبط `groupPolicy: "open"` للسماح لأي عضو (مع بقاء تقييد الإشارات افتراضيًا). +- الافتراضي: `channels.msteams.groupPolicy = "allowlist"` (محظور ما لم تضف `groupAllowFrom`). استخدم `channels.defaults.groupPolicy` لتجاوز القيمة الافتراضية عند عدم الضبط. +- يتحكم `channels.msteams.groupAllowFrom` في المرسلين الذين يمكنهم التفعيل في الدردشات الجماعية/القنوات (مع الرجوع إلى `channels.msteams.allowFrom`). +- اضبط `groupPolicy: "open"` للسماح لأي عضو (ولا يزال مقيدًا بالإشارة افتراضيًا). - لعدم السماح **بأي قنوات**، اضبط `channels.msteams.groupPolicy: "disabled"`. مثال: @@ -115,14 +117,14 @@ openclaw plugins install ./path/to/local/msteams-plugin } ``` -**Teams + قائمة سماح القنوات** +**Teams + قائمة السماح للقنوات** -- حدّد نطاق الردود في المجموعات/القنوات عبر إدراج الفرق والقنوات ضمن `channels.msteams.teams`. +- حدّد نطاق الردود في المجموعات/القنوات عبر إدراج الفرق والقنوات تحت `channels.msteams.teams`. - يجب أن تستخدم المفاتيح معرّفات الفرق الثابتة ومعرّفات محادثات القنوات. -- عندما يكون `groupPolicy="allowlist"` وتوجد قائمة سماح للفرق، لا تُقبل إلا الفرق/القنوات المُدرجة (مع تقييد الإشارات). +- عندما يكون `groupPolicy="allowlist"` وتوجد قائمة سماح للفرق، يتم قبول الفرق/القنوات المدرجة فقط (مع اشتراط الإشارة). - يقبل معالج الإعداد إدخالات `Team/Channel` ويخزنها لك. -- عند بدء التشغيل، يحل OpenClaw أسماء الفرق/القنوات وأسماء المستخدمين في قوائم السماح إلى معرّفات (عندما تسمح أذونات Graph بذلك) - ويسجل هذا الربط؛ وتُحتفظ بأسماء الفرق/القنوات غير المحلولة كما أُدخلت ولكن يتم تجاهلها للتوجيه افتراضيًا ما لم يكن `channels.msteams.dangerouslyAllowNameMatching: true` مفعّلًا. +- عند بدء التشغيل، يحل OpenClaw أسماء الفرق/القنوات وأسماء المستخدمين في قائمة السماح إلى معرّفات (عندما تسمح أذونات Graph بذلك) + ويسجل التعيين؛ وتُحتفظ بأسماء الفرق/القنوات غير المحلولة كما كُتبت لكن يتم تجاهلها في التوجيه افتراضيًا ما لم يتم تفعيل `channels.msteams.dangerouslyAllowNameMatching: true`. مثال: @@ -145,49 +147,49 @@ openclaw plugins install ./path/to/local/msteams-plugin ## كيف يعمل -1. تأكد من أن المكون الإضافي لـ Microsoft Teams متاح. +1. تأكد من أن المكون الإضافي Microsoft Teams متاح. - إصدارات OpenClaw المعبأة الحالية تتضمنه بالفعل. - - يمكن للإصدارات/التثبيتات الأقدم أو المخصصة إضافته يدويًا بالأوامر أعلاه. -2. أنشئ **Azure Bot** ‏(App ID + secret + tenant ID). + - يمكن لعمليات التثبيت الأقدم/المخصصة إضافته يدويًا باستخدام الأوامر أعلاه. +2. أنشئ **Azure Bot** (معرّف التطبيق + السر + معرّف المستأجر). 3. أنشئ **حزمة تطبيق Teams** تشير إلى البوت وتتضمن أذونات RSC أدناه. -4. ارفع/ثبّت تطبيق Teams داخل فريق (أو نطاق شخصي للرسائل المباشرة). -5. اضبط `msteams` في `~/.openclaw/openclaw.json` (أو متغيرات البيئة) وابدأ gateway. -6. يستمع gateway إلى حركة webhook الخاصة بـ Bot Framework على `/api/messages` افتراضيًا. +4. ارفع/ثبّت تطبيق Teams داخل فريق (أو في النطاق الشخصي للرسائل المباشرة). +5. اضبط `msteams` في `~/.openclaw/openclaw.json` (أو متغيرات البيئة) وابدأ البوابة. +6. تستمع البوابة افتراضيًا إلى حركة مرور Webhook الخاصة بـ Bot Framework على `/api/messages`. ## إعداد Azure Bot (المتطلبات المسبقة) -قبل إعداد OpenClaw، تحتاج إلى إنشاء مورد Azure Bot. +قبل ضبط OpenClaw، تحتاج إلى إنشاء مورد Azure Bot. ### الخطوة 1: إنشاء Azure Bot 1. انتقل إلى [Create Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot) 2. املأ علامة التبويب **Basics**: - | الحقل | القيمة | - | ------------------ | --------------------------------------------------------- | - | **Bot handle** | اسم البوت الخاص بك، مثل `openclaw-msteams` (يجب أن يكون فريدًا) | - | **Subscription** | اختر اشتراك Azure الخاص بك | - | **Resource group** | أنشئ مجموعة جديدة أو استخدم مجموعة موجودة | - | **Pricing tier** | **Free** للتطوير/الاختبار | - | **Type of App** | **Single Tenant** (موصى به - راجع الملاحظة أدناه) | - | **Creation type** | **Create new Microsoft App ID** | + | الحقل | القيمة | + | ------------------ | -------------------------------------------------------- | + | **اسم البوت** | اسم البوت الخاص بك، مثل `openclaw-msteams` (يجب أن يكون فريدًا) | + | **الاشتراك** | اختر اشتراك Azure الخاص بك | + | **مجموعة الموارد** | أنشئ مجموعة جديدة أو استخدم مجموعة موجودة | + | **فئة التسعير** | **مجاني** للتطوير/الاختبار | + | **نوع التطبيق** | **Single Tenant** (موصى به - راجع الملاحظة أدناه) | + | **نوع الإنشاء** | **Create new Microsoft App ID** | -> **إشعار إيقاف:** تم إيقاف إنشاء البوتات الجديدة متعددة المستأجرين بعد 2025-07-31. استخدم **Single Tenant** للبوتات الجديدة. +> **إشعار إهمال:** تم إهمال إنشاء بوتات جديدة متعددة المستأجرين بعد 2025-07-31. استخدم **Single Tenant** للبوتات الجديدة. -3. انقر **Review + create** → **Create** (انتظر نحو دقيقة إلى دقيقتين) +3. انقر **Review + create** → **Create** (انتظر حوالي 1-2 دقيقة) ### الخطوة 2: الحصول على بيانات الاعتماد 1. انتقل إلى مورد Azure Bot الخاص بك → **Configuration** -2. انسخ **Microsoft App ID** → هذا هو `appId` الخاص بك +2. انسخ **Microsoft App ID** → هذا هو `appId` 3. انقر **Manage Password** → انتقل إلى App Registration -4. ضمن **Certificates & secrets** → **New client secret** → انسخ **Value** → هذا هو `appPassword` الخاص بك -5. انتقل إلى **Overview** → انسخ **Directory (tenant) ID** → هذا هو `tenantId` الخاص بك +4. ضمن **Certificates & secrets** → **New client secret** → انسخ **Value** → هذا هو `appPassword` +5. انتقل إلى **Overview** → انسخ **Directory (tenant) ID** → هذا هو `tenantId` ### الخطوة 3: إعداد نقطة نهاية المراسلة 1. في Azure Bot → **Configuration** -2. اضبط **Messaging endpoint** على webhook URL الخاص بك: +2. اضبط **Messaging endpoint** على عنوان URL الخاص بـ webhook: - الإنتاج: `https://your-domain.com/api/messages` - التطوير المحلي: استخدم نفقًا (راجع [التطوير المحلي](#local-development-tunneling) أدناه) @@ -197,74 +199,216 @@ openclaw plugins install ./path/to/local/msteams-plugin 2. انقر **Microsoft Teams** → Configure → Save 3. اقبل شروط الخدمة +## المصادقة الاتحادية (الشهادة + الهوية المُدارة) + +> أُضيف في 2026.3.24 + +بالنسبة لعمليات النشر الإنتاجية، يدعم OpenClaw **المصادقة الاتحادية** كبديل أكثر أمانًا لأسرار العميل. تتوفر طريقتان: + +### الخيار أ: المصادقة المستندة إلى الشهادة + +استخدم شهادة PEM مسجلة في تسجيل تطبيق Entra ID الخاص بك. + +**الإعداد:** + +1. أنشئ شهادة أو احصل عليها (بتنسيق PEM مع المفتاح الخاص). +2. في Entra ID → App Registration → **Certificates & secrets** → **Certificates** → ارفع الشهادة العامة. + +**الإعدادات:** + +```json5 +{ + channels: { + msteams: { + enabled: true, + appId: "", + tenantId: "", + authType: "federated", + certificatePath: "/path/to/cert.pem", + webhook: { port: 3978, path: "/api/messages" }, + }, + }, +} +``` + +**متغيرات البيئة:** + +- `MSTEAMS_AUTH_TYPE=federated` +- `MSTEAMS_CERTIFICATE_PATH=/path/to/cert.pem` + +### الخيار ب: Azure Managed Identity + +استخدم Azure Managed Identity للمصادقة دون كلمة مرور. وهذا مثالي لعمليات النشر على بنية Azure التحتية (AKS، App Service، Azure VMs) حيث تتوفر هوية مُدارة. + +**كيف يعمل:** + +1. يحتوي الـ pod/VM الخاص بالبوت على هوية مُدارة (مخصصة من النظام أو من المستخدم). +2. يربط **اعتماد هوية اتحادية** الهوية المُدارة بتسجيل تطبيق Entra ID. +3. في وقت التشغيل، يستخدم OpenClaw `@azure/identity` للحصول على الرموز المميزة من نقطة نهاية Azure IMDS (`169.254.169.254`). +4. يتم تمرير الرمز المميز إلى Teams SDK لمصادقة البوت. + +**المتطلبات المسبقة:** + +- بنية Azure تحتية مع تفعيل الهوية المُدارة (AKS workload identity أو App Service أو VM) +- إنشاء اعتماد هوية اتحادية في تسجيل تطبيق Entra ID +- وصول شبكي إلى IMDS (`169.254.169.254:80`) من الـ pod/VM + +**الإعدادات (هوية مُدارة مخصصة من النظام):** + +```json5 +{ + channels: { + msteams: { + enabled: true, + appId: "", + tenantId: "", + authType: "federated", + useManagedIdentity: true, + webhook: { port: 3978, path: "/api/messages" }, + }, + }, +} +``` + +**الإعدادات (هوية مُدارة مخصصة من المستخدم):** + +```json5 +{ + channels: { + msteams: { + enabled: true, + appId: "", + tenantId: "", + authType: "federated", + useManagedIdentity: true, + managedIdentityClientId: "", + webhook: { port: 3978, path: "/api/messages" }, + }, + }, +} +``` + +**متغيرات البيئة:** + +- `MSTEAMS_AUTH_TYPE=federated` +- `MSTEAMS_USE_MANAGED_IDENTITY=true` +- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=` (فقط للهوية المخصصة من المستخدم) + +### إعداد AKS Workload Identity + +لعمليات نشر AKS التي تستخدم workload identity: + +1. **فعّل workload identity** في عنقود AKS الخاص بك. +2. **أنشئ اعتماد هوية اتحادية** في تسجيل تطبيق Entra ID: + + ```bash + az ad app federated-credential create --id --parameters '{ + "name": "my-bot-workload-identity", + "issuer": "", + "subject": "system:serviceaccount::", + "audiences": ["api://AzureADTokenExchange"] + }' + ``` + +3. **أضف تعليقًا توضيحيًا إلى حساب خدمة Kubernetes** باستخدام معرّف عميل التطبيق: + + ```yaml + apiVersion: v1 + kind: ServiceAccount + metadata: + name: my-bot-sa + annotations: + azure.workload.identity/client-id: "" + ``` + +4. **أضف تسمية إلى الـ pod** لحقن workload identity: + + ```yaml + metadata: + labels: + azure.workload.identity/use: "true" + ``` + +5. **تأكد من الوصول الشبكي** إلى IMDS (`169.254.169.254`) — إذا كنت تستخدم NetworkPolicy، فأضف قاعدة خروج تسمح بحركة المرور إلى `169.254.169.254/32` على المنفذ 80. + +### مقارنة أنواع المصادقة + +| الطريقة | الإعدادات | المزايا | العيوب | +| -------------------- | ---------------------------------------------- | ---------------------------------- | ------------------------------------- | +| **سر العميل** | `appPassword` | إعداد بسيط | يتطلب تدوير الأسرار، وأقل أمانًا | +| **الشهادة** | `authType: "federated"` + `certificatePath` | لا يوجد سر مشترك عبر الشبكة | عبء إدارة الشهادات | +| **Managed Identity** | `authType: "federated"` + `useManagedIdentity` | بدون كلمة مرور، ولا توجد أسرار لإدارتها | يتطلب بنية Azure التحتية | + +**السلوك الافتراضي:** عندما لا يتم ضبط `authType`، يستخدم OpenClaw افتراضيًا مصادقة سر العميل. تستمر الإعدادات الحالية في العمل دون تغييرات. + ## التطوير المحلي (الأنفاق) -لا يستطيع Teams الوصول إلى `localhost`. استخدم نفقًا للتطوير المحلي: +لا يمكن لـ Teams الوصول إلى `localhost`. استخدم نفقًا للتطوير المحلي: -**الخيار A: ngrok** +**الخيار أ: ngrok** ```bash ngrok http 3978 -# انسخ URL الذي يبدأ بـ https، مثل https://abc123.ngrok.io +# انسخ عنوان URL الخاص بـ https، مثل https://abc123.ngrok.io # اضبط نقطة نهاية المراسلة على: https://abc123.ngrok.io/api/messages ``` -**الخيار B: Tailscale Funnel** +**الخيار ب: Tailscale Funnel** ```bash tailscale funnel 3978 -# استخدم URL الخاص بـ Tailscale funnel كنقطة نهاية للمراسلة +# استخدم عنوان URL الخاص بـ Tailscale funnel كنقطة نهاية للمراسلة ``` ## Teams Developer Portal (بديل) -بدلًا من إنشاء manifest ZIP يدويًا، يمكنك استخدام [Teams Developer Portal](https://dev.teams.microsoft.com/apps): +بدلًا من إنشاء ملف manifest ZIP يدويًا، يمكنك استخدام [Teams Developer Portal](https://dev.teams.microsoft.com/apps): 1. انقر **+ New app** -2. املأ المعلومات الأساسية (الاسم، الوصف، معلومات المطور) +2. املأ المعلومات الأساسية (الاسم، الوصف، معلومات المطوّر) 3. انتقل إلى **App features** → **Bot** -4. اختر **Enter a bot ID manually** والصق Azure Bot App ID -5. فعّل النطاقات: **Personal** و**Team** و**Group Chat** +4. اختر **Enter a bot ID manually** والصق Azure Bot App ID الخاص بك +5. حدّد النطاقات: **Personal** و**Team** و**Group Chat** 6. انقر **Distribute** → **Download app package** 7. في Teams: **Apps** → **Manage your apps** → **Upload a custom app** → اختر ملف ZIP -غالبًا ما يكون هذا أسهل من تعديل ملفات manifest JSON يدويًا. +غالبًا ما يكون هذا أسهل من تعديل ملفات JSON manifest يدويًا. ## اختبار البوت -**الخيار A: Azure Web Chat (تحقق من webhook أولًا)** +**الخيار أ: Azure Web Chat (تحقق من webhook أولًا)** 1. في Azure Portal → مورد Azure Bot الخاص بك → **Test in Web Chat** 2. أرسل رسالة - يجب أن ترى ردًا -3. وهذا يؤكد أن نقطة نهاية webhook تعمل قبل إعداد Teams +3. يؤكد هذا أن نقطة نهاية webhook تعمل قبل إعداد Teams -**الخيار B: Teams (بعد تثبيت التطبيق)** +**الخيار ب: Teams (بعد تثبيت التطبيق)** 1. ثبّت تطبيق Teams (تحميل جانبي أو كتالوج المؤسسة) 2. اعثر على البوت في Teams وأرسل رسالة مباشرة -3. تحقق من سجلات gateway لرؤية النشاط الوارد +3. تحقّق من سجلات البوابة لرؤية النشاط الوارد ## الإعداد (الحد الأدنى للنص فقط) -1. **تأكد من أن المكون الإضافي لـ Microsoft Teams متاح** +1. **تأكد من أن المكون الإضافي Microsoft Teams متاح** - إصدارات OpenClaw المعبأة الحالية تتضمنه بالفعل. - - يمكن للإصدارات/التثبيتات الأقدم أو المخصصة إضافته يدويًا: + - يمكن لعمليات التثبيت الأقدم/المخصصة إضافته يدويًا: - من npm: `openclaw plugins install @openclaw/msteams` - - من نسخة checkout محلية: `openclaw plugins install ./path/to/local/msteams-plugin` + - من نسخة محلية: `openclaw plugins install ./path/to/local/msteams-plugin` 2. **تسجيل البوت** - - أنشئ Azure Bot (راجع أعلاه) ودوّن: + - أنشئ Azure Bot (راجع أعلاه) وسجّل: - App ID - - Client secret ‏(App password) - - Tenant ID ‏(single-tenant) + - سر العميل (App password) + - Tenant ID (مستأجر واحد) 3. **manifest تطبيق Teams** - - أضف إدخال `bot` حيث `botId = `. - - النطاقات: `personal`, `team`, `groupChat`. - - `supportsFiles: true` ‏(مطلوب لمعالجة الملفات في النطاق الشخصي). + - أضف إدخال `bot` مع `botId = `. + - النطاقات: `personal` و`team` و`groupChat`. + - `supportsFiles: true` (مطلوب للتعامل مع الملفات في النطاق الشخصي). - أضف أذونات RSC (أدناه). - - أنشئ الأيقونات: `outline.png` ‏(32x32) و`color.png` ‏(192x192). - - اضغط الملفات الثلاثة معًا في zip: ‏`manifest.json`, `outline.png`, `color.png`. + - أنشئ الأيقونات: `outline.png` (32x32) و`color.png` (192x192). + - اضغط الملفات الثلاثة معًا في ملف Zip: `manifest.json` و`outline.png` و`color.png`. 4. **اضبط OpenClaw** @@ -286,53 +430,58 @@ tailscale funnel 3978 - `MSTEAMS_APP_ID` - `MSTEAMS_APP_PASSWORD` - `MSTEAMS_TENANT_ID` + - `MSTEAMS_AUTH_TYPE` (اختياري: `"secret"` أو `"federated"`) + - `MSTEAMS_CERTIFICATE_PATH` (مصادقة اتحادية + شهادة) + - `MSTEAMS_CERTIFICATE_THUMBPRINT` (اختياري، غير مطلوب للمصادقة) + - `MSTEAMS_USE_MANAGED_IDENTITY` (مصادقة اتحادية + هوية مُدارة) + - `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID` (لهوية MI المخصصة من المستخدم فقط) 5. **نقطة نهاية البوت** - اضبط Azure Bot Messaging Endpoint على: - - `https://:3978/api/messages` ‏(أو المسار/المنفذ الذي اخترته). + - `https://:3978/api/messages` (أو المسار/المنفذ الذي اخترته). -6. **شغّل gateway** - - تبدأ قناة Teams تلقائيًا عندما يكون المكون الإضافي المضمّن أو المثبّت يدويًا متاحًا وتوجد إعدادات `msteams` مع بيانات الاعتماد. +6. **شغّل البوابة** + - تبدأ قناة Teams تلقائيًا عندما يكون المكون الإضافي المضمَّن أو المثبَّت يدويًا متاحًا وتكون إعدادات `msteams` موجودة مع بيانات الاعتماد. ## إجراء معلومات العضو -يعرض OpenClaw إجراء `member-info` مدعومًا من Graph لـ Microsoft Teams حتى تتمكن الوكلاء وعمليات الأتمتة من حل تفاصيل أعضاء القناة (اسم العرض والبريد الإلكتروني والدور) مباشرةً من Microsoft Graph. +يوفّر OpenClaw إجراء `member-info` مدعومًا من Graph لـ Microsoft Teams بحيث يمكن للوكلاء وعمليات الأتمتة حلّ تفاصيل أعضاء القناة (الاسم المعروض، البريد الإلكتروني، الدور) مباشرةً من Microsoft Graph. المتطلبات: -- إذن RSC ‏`Member.Read.Group` (موجود بالفعل في manifest الموصى به) -- لعمليات البحث عبر الفرق: إذن تطبيق Graph ‏`User.Read.All` مع موافقة المسؤول +- إذن RSC `Member.Read.Group` (موجود بالفعل في manifest الموصى به) +- لعمليات البحث عبر الفرق: إذن تطبيق Graph `User.Read.All` مع موافقة المسؤول -يخضع الإجراء لـ `channels.msteams.actions.memberInfo` (الافتراضي: مفعّل عند توفر بيانات اعتماد Graph). +يتم التحكم في هذا الإجراء بواسطة `channels.msteams.actions.memberInfo` (الافتراضي: مفعّل عندما تكون بيانات اعتماد Graph متاحة). ## سياق السجل -- يتحكم `channels.msteams.historyLimit` في عدد رسائل القناة/المجموعة الأخيرة التي تُغلَّف داخل الموجّه. -- يعود إلى `messages.groupChat.historyLimit`. اضبطه إلى `0` للتعطيل (الافتراضي 50). -- يُرشّح سجل السلسلة الذي يتم جلبه بواسطة قوائم سماح المرسلين (`allowFrom` / `groupAllowFrom`)، لذا فإن تهيئة سياق السلسلة تتضمن فقط الرسائل من المرسلين المسموح لهم. -- يتم تمرير سياق المرفقات المقتبسة (`ReplyTo*` المشتق من HTML الرد في Teams) حاليًا كما تم استلامه. -- بمعنى آخر، تتحكم قوائم السماح في من يمكنه تشغيل الوكيل؛ ولا تُرشّح اليوم إلا بعض مسارات السياق التكميلي المحددة. -- يمكن تقييد سجل الرسائل المباشرة عبر `channels.msteams.dmHistoryLimit` (أدوار المستخدم). والتجاوزات لكل مستخدم: `channels.msteams.dms[""].historyLimit`. +- يتحكم `channels.msteams.historyLimit` في عدد رسائل القناة/المجموعة الحديثة التي يتم تضمينها في الموجّه. +- يعود إلى `messages.groupChat.historyLimit`. اضبطه على `0` للتعطيل (الافتراضي 50). +- تتم تصفية سجل سلسلة الرسائل الذي يتم جلبه وفقًا لقوائم السماح للمرسلين (`allowFrom` / `groupAllowFrom`)، لذا فإن تهيئة سياق السلسلة لا تتضمن إلا الرسائل من المرسلين المسموح بهم. +- يتم تمرير سياق المرفقات المقتبسة (`ReplyTo*` المشتق من HTML الرد في Teams) كما تم استلامه حاليًا. +- بعبارة أخرى، تتحكم قوائم السماح في من يمكنه تشغيل الوكيل؛ ويتم اليوم تصفية مسارات سياق إضافية محددة فقط. +- يمكن تقييد سجل الرسائل المباشرة عبر `channels.msteams.dmHistoryLimit` (أدوار المستخدم). وتوجد تجاوزات لكل مستخدم عبر: `channels.msteams.dms[""].historyLimit`. ## أذونات Teams RSC الحالية (Manifest) -هذه هي أذونات **resourceSpecific** الحالية في manifest تطبيق Teams لدينا. وهي لا تنطبق إلا داخل الفريق/الدردشة التي ثُبّت فيها التطبيق. +هذه هي **resourceSpecific permissions** الحالية في manifest تطبيق Teams لدينا. وهي تنطبق فقط داخل الفريق/الدردشة المثبَّت فيها التطبيق. **للقنوات (نطاق الفريق):** -- `ChannelMessage.Read.Group` ‏(Application) - تلقي جميع رسائل القناة بدون @mention -- `ChannelMessage.Send.Group` ‏(Application) -- `Member.Read.Group` ‏(Application) -- `Owner.Read.Group` ‏(Application) -- `ChannelSettings.Read.Group` ‏(Application) -- `TeamMember.Read.Group` ‏(Application) -- `TeamSettings.Read.Group` ‏(Application) +- `ChannelMessage.Read.Group` (Application) - تلقي كل رسائل القناة بدون @mention +- `ChannelMessage.Send.Group` (Application) +- `Member.Read.Group` (Application) +- `Owner.Read.Group` (Application) +- `ChannelSettings.Read.Group` (Application) +- `TeamMember.Read.Group` (Application) +- `TeamSettings.Read.Group` (Application) **للدردشات الجماعية:** -- `ChatMessage.Read.Chat` ‏(Application) - تلقي جميع رسائل الدردشة الجماعية بدون @mention +- `ChatMessage.Read.Chat` (Application) - تلقي كل رسائل الدردشة الجماعية بدون @mention -## مثال على Teams Manifest (منقّح) +## مثال على Teams Manifest (مع تنقيح البيانات) مثال أدنى صالح مع الحقول المطلوبة. استبدل المعرّفات وعناوين URL. @@ -382,148 +531,153 @@ tailscale funnel 3978 } ``` -### ملاحظات manifest المهمة (حقول لا غنى عنها) +### تحذيرات manifest (حقول أساسية مطلوبة) -- يجب أن يطابق `bots[].botId` **تمامًا** Azure Bot App ID. -- يجب أن يطابق `webApplicationInfo.id` **تمامًا** Azure Bot App ID. -- يجب أن يتضمن `bots[].scopes` الأسطح التي تخطط لاستخدامها (`personal`, `team`, `groupChat`). -- يتطلب `bots[].supportsFiles: true` لمعالجة الملفات في النطاق الشخصي. +- يجب أن يطابق `bots[].botId` **بالضرورة** Azure Bot App ID. +- يجب أن يطابق `webApplicationInfo.id` **بالضرورة** Azure Bot App ID. +- يجب أن يتضمن `bots[].scopes` الأسطح التي تخطط لاستخدامها (`personal` و`team` و`groupChat`). +- `bots[].supportsFiles: true` مطلوب للتعامل مع الملفات في النطاق الشخصي. - يجب أن يتضمن `authorization.permissions.resourceSpecific` أذونات قراءة/إرسال القنوات إذا كنت تريد حركة مرور القنوات. ### تحديث تطبيق موجود -لتحديث تطبيق Teams مثبّت بالفعل (مثلًا لإضافة أذونات RSC): +لتحديث تطبيق Teams مثبت بالفعل (على سبيل المثال، لإضافة أذونات RSC): 1. حدّث `manifest.json` بالإعدادات الجديدة -2. **زد الحقل `version`** ‏(مثلًا `1.0.0` → `1.1.0`) -3. **أعد ضغط** manifest مع الأيقونات (`manifest.json`, `outline.png`, `color.png`) +2. **زد حقل `version`** (مثلًا `1.0.0` → `1.1.0`) +3. **أعِد ضغط** manifest مع الأيقونات (`manifest.json` و`outline.png` و`color.png`) 4. ارفع ملف zip الجديد: - - **الخيار A (Teams Admin Center):** Teams Admin Center → Teams apps → Manage apps → اعثر على تطبيقك → Upload new version - - **الخيار B (Sideload):** في Teams → Apps → Manage your apps → Upload a custom app -5. **لقنوات الفرق:** أعد تثبيت التطبيق في كل فريق حتى تدخل الأذونات الجديدة حيز التنفيذ -6. **أغلق Teams تمامًا ثم أعد تشغيله** (وليس مجرد إغلاق النافذة) لمسح بيانات تعريف التطبيق المخزنة مؤقتًا + - **الخيار أ (Teams Admin Center):** Teams Admin Center → Teams apps → Manage apps → اعثر على تطبيقك → Upload new version + - **الخيار ب (التحميل الجانبي):** في Teams → Apps → Manage your apps → Upload a custom app +5. **لقنوات الفريق:** أعد تثبيت التطبيق في كل فريق حتى تصبح الأذونات الجديدة فعّالة +6. **أغلق Teams تمامًا وأعد تشغيله** (وليس مجرد إغلاق النافذة) لمسح بيانات تعريف التطبيق المخزنة مؤقتًا ## الإمكانات: RSC فقط مقابل Graph -### مع **Teams RSC فقط** (التطبيق مثبت، من دون أذونات Microsoft Graph API) +### مع **Teams RSC فقط** (التطبيق مثبت، بدون أذونات Microsoft Graph API) يعمل: -- قراءة محتوى **النص** لرسائل القنوات. -- إرسال محتوى **نص** رسائل القنوات. +- قراءة محتوى **النص** في رسائل القنوات. +- إرسال محتوى **نصي** إلى القنوات. - استقبال مرفقات الملفات في **النطاق الشخصي (DM)**. لا يعمل: -- **الصور أو محتويات الملفات** في القنوات/المجموعات (تتضمن الحمولة مجرد HTML stub). -- تنزيل المرفقات المخزنة في SharePoint/OneDrive. -- قراءة سجل الرسائل (فيما يتجاوز حدث webhook المباشر). +- **صور أو محتويات ملفات** القنوات/المجموعات (تتضمن الحمولة فقط HTML placeholder). +- تنزيل المرفقات المخزّنة في SharePoint/OneDrive. +- قراءة سجل الرسائل (إلى ما بعد حدث webhook المباشر). ### مع **Teams RSC + أذونات تطبيق Microsoft Graph** يضيف: -- تنزيل المحتويات المستضافة (الصور الملصقة داخل الرسائل). +- تنزيل المحتويات المستضافة (الصور الملصقة في الرسائل). - تنزيل مرفقات الملفات المخزنة في SharePoint/OneDrive. - قراءة سجل رسائل القنوات/الدردشات عبر Graph. ### RSC مقابل Graph API -| الإمكانية | أذونات RSC | Graph API | -| ----------------------- | --------------------- | ------------------------------------ | -| **الرسائل الآنية** | نعم (عبر webhook) | لا (استطلاع فقط) | -| **الرسائل التاريخية** | لا | نعم (يمكن الاستعلام عن السجل) | -| **تعقيد الإعداد** | manifest التطبيق فقط | يتطلب موافقة المسؤول + تدفق token | -| **يعمل دون اتصال** | لا (يجب أن يكون قيد التشغيل) | نعم (يمكن الاستعلام في أي وقت) | +| الإمكانية | أذونات RSC | Graph API | +| ----------------------- | -------------------- | ----------------------------------- | +| **الرسائل الفورية** | نعم (عبر webhook) | لا (استقصاء فقط) | +| **الرسائل التاريخية** | لا | نعم (يمكن الاستعلام عن السجل) | +| **تعقيد الإعداد** | manifest التطبيق فقط | يتطلب موافقة المسؤول + تدفق الرموز | +| **يعمل دون اتصال** | لا (يجب أن يكون قيد التشغيل) | نعم (يمكن الاستعلام في أي وقت) | -**الخلاصة:** يستخدم RSC للاستماع الآني؛ ويُستخدم Graph API للوصول إلى السجل التاريخي. وللحاق بالرسائل الفائتة أثناء عدم الاتصال، تحتاج إلى Graph API مع `ChannelMessage.Read.All` ‏(يتطلب موافقة المسؤول). +**الخلاصة:** تُستخدم RSC للاستماع الفوري؛ ويُستخدم Graph API للوصول إلى السجل. إذا كنت تريد تعويض الرسائل الفائتة أثناء عدم الاتصال، فأنت تحتاج إلى Graph API مع `ChannelMessage.Read.All` (يتطلب موافقة المسؤول). -## الوسائط + السجل المفعّلان عبر Graph (مطلوبان للقنوات) +## الوسائط + السجل مع تفعيل Graph (مطلوب للقنوات) -إذا كنت تحتاج إلى الصور/الملفات في **القنوات** أو تريد جلب **سجل الرسائل**، فيجب تفعيل أذونات Microsoft Graph ومنح موافقة المسؤول. +إذا كنت تحتاج إلى صور/ملفات في **القنوات** أو تريد جلب **سجل الرسائل**، فيجب عليك تفعيل أذونات Microsoft Graph ومنح موافقة المسؤول. -1. في Entra ID ‏(Azure AD) **App Registration**، أضف أذونات **Application** لـ Microsoft Graph: - - `ChannelMessage.Read.All` ‏(مرفقات القنوات + السجل) - - `Chat.Read.All` أو `ChatMessage.Read.All` ‏(للدردشات الجماعية) +1. في **App Registration** ضمن Entra ID (Azure AD)، أضف **Application permissions** لـ Microsoft Graph: + - `ChannelMessage.Read.All` (مرفقات القنوات + السجل) + - `Chat.Read.All` أو `ChatMessage.Read.All` (الدردشات الجماعية) 2. **امنح موافقة المسؤول** للمستأجر. -3. زِد **إصدار manifest** لتطبيق Teams، وأعد رفعه، و**أعد تثبيت التطبيق في Teams**. -4. **أغلق Teams تمامًا ثم أعد تشغيله** لمسح بيانات تعريف التطبيق المخزنة مؤقتًا. +3. ارفع **إصدار manifest** لتطبيق Teams، ثم أعد رفعه، و**أعد تثبيت التطبيق في Teams**. +4. **أغلق Teams تمامًا وأعد تشغيله** لمسح بيانات تعريف التطبيق المخزنة مؤقتًا. -**إذن إضافي لإشارات المستخدمين:** تعمل إشارات @ للمستخدمين مباشرةً للمستخدمين الموجودين في المحادثة. ولكن إذا أردت البحث ديناميكيًا عن مستخدمين والإشارة إليهم وهم **ليسوا في المحادثة الحالية**، فأضف إذن `User.Read.All` ‏(Application) وامنح موافقة المسؤول. +**إذن إضافي لإشارات المستخدمين:** تعمل إشارات المستخدم @mentions مباشرةً للمستخدمين الموجودين في المحادثة. ولكن إذا كنت تريد البحث ديناميكيًا عن مستخدمين والإشارة إليهم وهم **ليسوا في المحادثة الحالية**، فأضف إذن التطبيق `User.Read.All` وامنح موافقة المسؤول. ## القيود المعروفة ### مهلات webhook -يسلّم Teams الرسائل عبر HTTP webhook. وإذا استغرقت المعالجة وقتًا طويلًا جدًا (مثل بطء استجابات LLM)، فقد ترى: +يُسلِّم Teams الرسائل عبر HTTP webhook. إذا استغرقت المعالجة وقتًا طويلًا جدًا (مثل استجابات LLM البطيئة)، فقد ترى: -- مهلات gateway -- إعادة Teams محاولة إرسال الرسالة (مما يسبب التكرار) +- مهلات البوابة +- إعادة Teams لمحاولة إرسال الرسالة (مما يسبب تكرارات) - إسقاط الردود -يتعامل OpenClaw مع ذلك عبر إعادة الاستجابة بسرعة وإرسال الردود بشكل استباقي، ولكن قد تستمر المشكلات مع الاستجابات البطيئة جدًا. +يعالج OpenClaw ذلك عبر الإرجاع السريع وإرسال الردود بشكل استباقي، لكن الاستجابات البطيئة جدًا قد تظل تسبب مشكلات. ### التنسيق -Markdown في Teams أكثر محدودية من Slack أو Discord: +تنسيق Markdown في Teams أكثر محدودية من Slack أو Discord: - يعمل التنسيق الأساسي: **غامق** و_مائل_ و`code` والروابط -- قد لا تُعرض Markdown المعقدة (الجداول والقوائم المتداخلة) بشكل صحيح -- تُدعم Adaptive Cards للاستطلاعات وإرسال البطاقات العامة (راجع أدناه) +- قد لا يتم عرض Markdown المعقد (الجداول، القوائم المتداخلة) بشكل صحيح +- يتم دعم Adaptive Cards للاستطلاعات وعمليات إرسال البطاقات العامة (راجع أدناه) -## الإعداد +## الإعدادات الإعدادات الأساسية (راجع `/gateway/configuration` لأنماط القنوات المشتركة): - `channels.msteams.enabled`: تفعيل/تعطيل القناة. -- `channels.msteams.appId`, `channels.msteams.appPassword`, `channels.msteams.tenantId`: بيانات اعتماد البوت. -- `channels.msteams.webhook.port` ‏(الافتراضي `3978`) -- `channels.msteams.webhook.path` ‏(الافتراضي `/api/messages`) -- `channels.msteams.dmPolicy`: ‏`pairing | allowlist | open | disabled` ‏(الافتراضي: pairing) -- `channels.msteams.allowFrom`: قائمة السماح للرسائل المباشرة (يوصى بمعرّفات كائنات AAD). يحل المعالج الأسماء إلى معرّفات أثناء الإعداد عندما يكون وصول Graph متاحًا. +- `channels.msteams.appId` و`channels.msteams.appPassword` و`channels.msteams.tenantId`: بيانات اعتماد البوت. +- `channels.msteams.webhook.port` (الافتراضي `3978`) +- `channels.msteams.webhook.path` (الافتراضي `/api/messages`) +- `channels.msteams.dmPolicy`: `pairing | allowlist | open | disabled` (الافتراضي: pairing) +- `channels.msteams.allowFrom`: قائمة السماح للرسائل المباشرة (يُنصح باستخدام معرّفات كائنات AAD). يحلّ المعالج الأسماء إلى معرّفات أثناء الإعداد عندما يكون وصول Graph متاحًا. - `channels.msteams.dangerouslyAllowNameMatching`: مفتاح طوارئ لإعادة تفعيل مطابقة UPN/أسماء العرض القابلة للتغيير والتوجيه المباشر بأسماء الفرق/القنوات. - `channels.msteams.textChunkLimit`: حجم تقسيم النص الصادر. -- `channels.msteams.chunkMode`: ‏`length` ‏(الافتراضي) أو `newline` للتقسيم على الأسطر الفارغة (حدود الفقرات) قبل التقسيم حسب الطول. -- `channels.msteams.mediaAllowHosts`: قائمة السماح لمضيفي المرفقات الواردة (الافتراضي نطاقات Microsoft/Teams). -- `channels.msteams.mediaAuthAllowHosts`: قائمة السماح لإرفاق رؤوس Authorization عند إعادة محاولة الوسائط (الافتراضي مضيفو Graph + Bot Framework). -- `channels.msteams.requireMention`: طلب @mention في القنوات/المجموعات (الافتراضي true). -- `channels.msteams.replyStyle`: ‏`thread | top-level` ‏(راجع [نمط الرد](#reply-style-threads-vs-posts)). +- `channels.msteams.chunkMode`: `length` (الافتراضي) أو `newline` للتقسيم على الأسطر الفارغة (حدود الفقرات) قبل التقسيم حسب الطول. +- `channels.msteams.mediaAllowHosts`: قائمة السماح لمضيفي المرفقات الواردة (الافتراضي: نطاقات Microsoft/Teams). +- `channels.msteams.mediaAuthAllowHosts`: قائمة السماح لإرفاق ترويسات Authorization عند إعادة محاولة الوسائط (الافتراضي: مضيفو Graph + Bot Framework). +- `channels.msteams.requireMention`: اشتراط @mention في القنوات/المجموعات (الافتراضي true). +- `channels.msteams.replyStyle`: `thread | top-level` (راجع [نمط الرد](#reply-style-threads-vs-posts)). - `channels.msteams.teams..replyStyle`: تجاوز لكل فريق. - `channels.msteams.teams..requireMention`: تجاوز لكل فريق. -- `channels.msteams.teams..tools`: تجاوزات سياسة الأدوات الافتراضية لكل فريق (`allow`/`deny`/`alsoAllow`) تُستخدم عندما يكون تجاوز القناة مفقودًا. -- `channels.msteams.teams..toolsBySender`: تجاوزات سياسة الأدوات الافتراضية لكل فريق ولكل مرسل (الرمز الشامل `"*"` مدعوم). +- `channels.msteams.teams..tools`: تجاوزات سياسة الأدوات الافتراضية لكل فريق (`allow`/`deny`/`alsoAllow`) تُستخدم عند غياب تجاوز على مستوى القناة. +- `channels.msteams.teams..toolsBySender`: تجاوزات سياسة الأدوات الافتراضية لكل مرسل داخل الفريق (`"*"` wildcard مدعوم). - `channels.msteams.teams..channels..replyStyle`: تجاوز لكل قناة. - `channels.msteams.teams..channels..requireMention`: تجاوز لكل قناة. - `channels.msteams.teams..channels..tools`: تجاوزات سياسة الأدوات لكل قناة (`allow`/`deny`/`alsoAllow`). -- `channels.msteams.teams..channels..toolsBySender`: تجاوزات سياسة الأدوات لكل قناة ولكل مرسل (الرمز الشامل `"*"` مدعوم). +- `channels.msteams.teams..channels..toolsBySender`: تجاوزات سياسة الأدوات لكل مرسل داخل القناة (`"*"` wildcard مدعوم). - يجب أن تستخدم مفاتيح `toolsBySender` بادئات صريحة: - `id:`, `e164:`, `username:`, `name:` (أما المفاتيح القديمة غير المسبوقة فما تزال تُطابق `id:` فقط). -- `channels.msteams.actions.memberInfo`: تفعيل أو تعطيل إجراء معلومات العضو المدعوم من Graph (الافتراضي: مفعّل عند توفر بيانات اعتماد Graph). -- `channels.msteams.sharePointSiteId`: معرّف موقع SharePoint لرفع الملفات في الدردشات/القنوات الجماعية (راجع [إرسال الملفات في الدردشات الجماعية](#sending-files-in-group-chats)). + `id:` و`e164:` و`username:` و`name:` (المفاتيح القديمة غير المسبوقة لا تزال تُطابق `id:` فقط). +- `channels.msteams.actions.memberInfo`: تفعيل أو تعطيل إجراء معلومات العضو المدعوم من Graph (الافتراضي: مفعّل عندما تكون بيانات اعتماد Graph متاحة). +- `channels.msteams.authType`: نوع المصادقة — `"secret"` (الافتراضي) أو `"federated"`. +- `channels.msteams.certificatePath`: مسار ملف شهادة PEM (مصادقة اتحادية + شهادة). +- `channels.msteams.certificateThumbprint`: بصمة الشهادة (اختياري، غير مطلوب للمصادقة). +- `channels.msteams.useManagedIdentity`: تفعيل مصادقة الهوية المُدارة (في وضع federated). +- `channels.msteams.managedIdentityClientId`: معرّف العميل للهوية المُدارة المخصصة من المستخدم. +- `channels.msteams.sharePointSiteId`: معرّف موقع SharePoint لرفع الملفات في الدردشات الجماعية/القنوات (راجع [إرسال الملفات في الدردشات الجماعية](#sending-files-in-group-chats)). ## التوجيه والجلسات -- تتبع مفاتيح الجلسات صيغة الوكيل القياسية (راجع [/concepts/session](/concepts/session)): +- تتبع مفاتيح الجلسات تنسيق الوكيل القياسي (راجع [/concepts/session](/ar/concepts/session)): - تشترك الرسائل المباشرة في الجلسة الرئيسية (`agent::`). - تستخدم رسائل القنوات/المجموعات معرّف المحادثة: - `agent::msteams:channel:` - `agent::msteams:group:` -## نمط الرد: Threads مقابل Posts +## نمط الرد: سلاسل الرسائل مقابل المنشورات -قدّم Teams مؤخرًا نمطي واجهة مستخدم للقنوات فوق نموذج البيانات الأساسي نفسه: +قدّم Teams مؤخرًا نمطين لواجهة القنوات فوق نموذج البيانات الأساسي نفسه: -| النمط | الوصف | `replyStyle` الموصى به | -| ------------------------ | -------------------------------------------------------- | ---------------------- | -| **Posts** ‏(الكلاسيكي) | تظهر الرسائل كبطاقات مع ردود مترابطة تحتها | `thread` ‏(الافتراضي) | -| **Threads** ‏(على نمط Slack) | تتدفق الرسائل خطيًا، بشكل أقرب إلى Slack | `top-level` | +| النمط | الوصف | `replyStyle` الموصى به | +| ------------------------ | --------------------------------------------------------- | ------------------------ | +| **Posts** (الكلاسيكي) | تظهر الرسائل كبطاقات مع ردود مترابطة أسفلها | `thread` (الافتراضي) | +| **Threads** (على نمط Slack) | تتدفق الرسائل بشكل خطي، بصورة أقرب إلى Slack | `top-level` | -**المشكلة:** لا تعرض Teams API نمط واجهة المستخدم الذي تستخدمه القناة. إذا استخدمت `replyStyle` خاطئًا: +**المشكلة:** لا تكشف Teams API عن نمط الواجهة الذي تستخدمه القناة. إذا استخدمت `replyStyle` غير المناسب: - `thread` في قناة بنمط Threads → تظهر الردود متداخلة بشكل غير ملائم -- `top-level` في قناة بنمط Posts → تظهر الردود كمنشورات مستقلة على المستوى الأعلى بدلًا من أن تكون داخل السلسلة +- `top-level` في قناة بنمط Posts → تظهر الردود كمنشورات مستقلة على المستوى الأعلى بدلًا من داخل السلسلة -**الحل:** اضبط `replyStyle` لكل قناة بحسب إعداد القناة: +**الحل:** اضبط `replyStyle` لكل قناة وفقًا لطريقة إعداد القناة: ```json5 { @@ -549,39 +703,39 @@ Markdown في Teams أكثر محدودية من Slack أو Discord: **القيود الحالية:** - **الرسائل المباشرة:** تعمل الصور ومرفقات الملفات عبر Teams bot file APIs. -- **القنوات/المجموعات:** تعيش المرفقات في تخزين M365 ‏(SharePoint/OneDrive). لا تتضمن حمولة webhook إلا HTML stub، وليس بايتات الملف الفعلية. **أذونات Graph API مطلوبة** لتنزيل مرفقات القنوات. -- لعمليات الإرسال الصريحة التي تبدأ بالملف، استخدم `action=upload-file` مع `media` / `filePath` / `path`؛ وتصبح `message` الاختيارية هي النص/التعليق المصاحب، بينما يتجاوز `filename` الاسم المرفوع. +- **القنوات/المجموعات:** تعيش المرفقات في تخزين M365 (SharePoint/OneDrive). تتضمن حمولة webhook فقط HTML placeholder، وليس بايتات الملف الفعلية. **أذونات Graph API مطلوبة** لتنزيل مرفقات القنوات. +- لعمليات الإرسال الصريحة التي تبدأ بملف، استخدم `action=upload-file` مع `media` / `filePath` / `path`؛ ويصبح `message` الاختياري النص/التعليق المرافق، بينما يتجاوز `filename` الاسم المرفوع. -من دون أذونات Graph، ستُستقبل رسائل القنوات التي تحتوي على صور كنص فقط (ولا يمكن للبوت الوصول إلى محتوى الصورة). -وبشكل افتراضي، ينزّل OpenClaw الوسائط فقط من أسماء مضيفي Microsoft/Teams. ويمكنك تجاوز ذلك عبر `channels.msteams.mediaAllowHosts` ‏(استخدم `["*"]` للسماح بأي مضيف). -ولا تُرفق رؤوس Authorization إلا للمضيفين المدرجين في `channels.msteams.mediaAuthAllowHosts` ‏(الافتراضي مضيفو Graph + Bot Framework). أبقِ هذه القائمة صارمة (وتجنب اللواحق متعددة المستأجرين). +من دون أذونات Graph، ستُستقبل رسائل القنوات التي تحتوي على صور كنص فقط (ولا يكون محتوى الصورة متاحًا للبوت). +افتراضيًا، ينزّل OpenClaw الوسائط فقط من أسماء مضيفي Microsoft/Teams. ويمكنك تجاوز ذلك عبر `channels.msteams.mediaAllowHosts` (استخدم `["*"]` للسماح بأي مضيف). +تُرفق ترويسات Authorization فقط للمضيفين الموجودين في `channels.msteams.mediaAuthAllowHosts` (الافتراضي: مضيفو Graph + Bot Framework). أبقِ هذه القائمة صارمة (وتجنب suffixes متعددة المستأجرين). ## إرسال الملفات في الدردشات الجماعية -يمكن للبوتات إرسال الملفات في الرسائل المباشرة باستخدام تدفق FileConsentCard ‏(مدمج). لكن **إرسال الملفات في الدردشات/القنوات الجماعية** يتطلب إعدادًا إضافيًا: +يمكن للبوتات إرسال الملفات في الرسائل المباشرة باستخدام تدفق FileConsentCard (مدمج). لكن **إرسال الملفات في الدردشات الجماعية/القنوات** يتطلب إعدادًا إضافيًا: -| السياق | كيفية إرسال الملفات | الإعداد المطلوب | -| ------------------------ | ----------------------------------------- | ----------------------------------------------- | -| **الرسائل المباشرة** | FileConsentCard → يقبل المستخدم → يرفع البوت | يعمل مباشرةً | -| **الدردشات/القنوات الجماعية** | رفع إلى SharePoint → رابط مشاركة | يتطلب `sharePointSiteId` + أذونات Graph | -| **الصور (أي سياق)** | مضمنة داخل الرسالة بترميز Base64 | تعمل مباشرةً | +| السياق | كيفية إرسال الملفات | الإعداد المطلوب | +| ------------------------ | -------------------------------------------- | ----------------------------------------------- | +| **الرسائل المباشرة** | FileConsentCard → يقبل المستخدم → يرفع البوت | يعمل مباشرةً | +| **الدردشات الجماعية/القنوات** | رفع إلى SharePoint → مشاركة الرابط | يتطلب `sharePointSiteId` + أذونات Graph | +| **الصور (أي سياق)** | Base64 مضمّن inline | يعمل مباشرةً | ### لماذا تحتاج الدردشات الجماعية إلى SharePoint -لا تمتلك البوتات محرك OneDrive شخصيًا (ونقطة نهاية Graph API ‏`/me/drive` لا تعمل لهويات التطبيقات). ولإرسال الملفات في الدردشات/القنوات الجماعية، يرفع البوت الملف إلى **موقع SharePoint** وينشئ رابط مشاركة. +لا تمتلك البوتات محرك OneDrive شخصيًا (لا تعمل نقطة نهاية Graph API ‏`/me/drive` مع هويات التطبيقات). لإرسال الملفات في الدردشات الجماعية/القنوات، يرفع البوت الملف إلى **موقع SharePoint** وينشئ رابط مشاركة. ### الإعداد -1. **أضف أذونات Graph API** في Entra ID ‏(Azure AD) → App Registration: - - `Sites.ReadWrite.All` ‏(Application) - رفع الملفات إلى SharePoint - - `Chat.Read.All` ‏(Application) - اختياري، يفعّل روابط المشاركة لكل مستخدم +1. **أضف أذونات Graph API** في Entra ID (Azure AD) → App Registration: + - `Sites.ReadWrite.All` (Application) - رفع الملفات إلى SharePoint + - `Chat.Read.All` (Application) - اختياري، يفعّل روابط مشاركة لكل مستخدم 2. **امنح موافقة المسؤول** للمستأجر. 3. **احصل على معرّف موقع SharePoint الخاص بك:** ```bash - # عبر Graph Explorer أو curl باستخدام token صالح: + # عبر Graph Explorer أو curl مع رمز صالح: curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" @@ -598,7 +752,7 @@ Markdown في Teams أكثر محدودية من Slack أو Discord: { channels: { msteams: { - // ... إعداد آخر ... + // ... other config ... sharePointSiteId: "contoso.sharepoint.com,guid1,guid2", }, }, @@ -607,40 +761,40 @@ Markdown في Teams أكثر محدودية من Slack أو Discord: ### سلوك المشاركة -| الإذن | سلوك المشاركة | -| ---------------------------------------- | ---------------------------------------------------------- | -| `Sites.ReadWrite.All` فقط | رابط مشاركة على مستوى المؤسسة (يمكن لأي شخص في المؤسسة الوصول) | -| `Sites.ReadWrite.All` + `Chat.Read.All` | رابط مشاركة لكل مستخدم (يمكن فقط لأعضاء الدردشة الوصول) | +| الإذن | سلوك المشاركة | +| --------------------------------------- | --------------------------------------------------------- | +| `Sites.ReadWrite.All` فقط | رابط مشاركة على مستوى المؤسسة (يمكن لأي شخص في المؤسسة الوصول) | +| `Sites.ReadWrite.All` + `Chat.Read.All` | رابط مشاركة لكل مستخدم (يمكن فقط لأعضاء الدردشة الوصول) | تكون المشاركة لكل مستخدم أكثر أمانًا لأن المشاركين في الدردشة فقط يمكنهم الوصول إلى الملف. وإذا كان إذن `Chat.Read.All` مفقودًا، يعود البوت إلى المشاركة على مستوى المؤسسة. ### سلوك الرجوع الاحتياطي -| السيناريو | النتيجة | -| ------------------------------------------------- | --------------------------------------------------- | -| دردشة جماعية + ملف + تم إعداد `sharePointSiteId` | رفع إلى SharePoint وإرسال رابط مشاركة | -| دردشة جماعية + ملف + لا يوجد `sharePointSiteId` | محاولة رفع إلى OneDrive ‏(قد تفشل) وإرسال نص فقط | -| دردشة شخصية + ملف | تدفق FileConsentCard ‏(يعمل بدون SharePoint) | -| أي سياق + صورة | مضمنة داخل الرسالة بترميز Base64 ‏(تعمل بدون SharePoint) | +| السيناريو | النتيجة | +| ------------------------------------------------- | -------------------------------------------------- | +| دردشة جماعية + ملف + تم ضبط `sharePointSiteId` | الرفع إلى SharePoint، ثم إرسال رابط مشاركة | +| دردشة جماعية + ملف + لا يوجد `sharePointSiteId` | محاولة رفع إلى OneDrive (قد تفشل)، ثم إرسال نص فقط | +| دردشة شخصية + ملف | تدفق FileConsentCard (يعمل بدون SharePoint) | +| أي سياق + صورة | Base64 مضمّن inline (يعمل بدون SharePoint) | ### موقع تخزين الملفات -تُخزَّن الملفات المرفوعة في مجلد `/OpenClawShared/` داخل مكتبة المستندات الافتراضية لموقع SharePoint المُعد. +تُخزَّن الملفات المرفوعة في مجلد `/OpenClawShared/` داخل مكتبة المستندات الافتراضية لموقع SharePoint المضبوط. ## الاستطلاعات (Adaptive Cards) -يرسل OpenClaw استطلاعات Teams على شكل Adaptive Cards ‏(لا توجد Teams poll API أصلية). +يرسل OpenClaw استطلاعات Teams كبطاقات Adaptive Cards (لا توجد Teams poll API أصلية). - CLI: `openclaw message poll --channel msteams --target conversation: ...` -- تُسجَّل الأصوات بواسطة gateway في `~/.openclaw/msteams-polls.json`. -- يجب أن يبقى gateway متصلًا لتسجيل الأصوات. -- لا تنشر الاستطلاعات تلقائيًا ملخصات النتائج بعدُ (افحص ملف التخزين إذا لزم الأمر). +- تُسجَّل الأصوات بواسطة البوابة في `~/.openclaw/msteams-polls.json`. +- يجب أن تظل البوابة متصلة لتسجيل الأصوات. +- لا تنشر الاستطلاعات ملخصات النتائج تلقائيًا حتى الآن (افحص ملف التخزين إذا لزم الأمر). ## Adaptive Cards (عامة) -أرسل أي JSON خاص بـ Adaptive Card إلى مستخدمي Teams أو المحادثات باستخدام أداة `message` أو CLI. +أرسل أي JSON من نوع Adaptive Card إلى مستخدمي Teams أو المحادثات باستخدام أداة `message` أو CLI. -تقبل المعلمة `card` كائن JSON خاص بـ Adaptive Card. وعند توفير `card` يصبح نص الرسالة اختياريًا. +تقبل المعلمة `card` كائن JSON لـ Adaptive Card. وعند توفير `card`، يصبح نص الرسالة اختياريًا. **أداة الوكيل:** @@ -665,18 +819,18 @@ openclaw message send --channel msteams \ --card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}' ``` -راجع [Adaptive Cards documentation](https://adaptivecards.io/) للحصول على مخطط البطاقات والأمثلة. ولتفاصيل تنسيق الأهداف، راجع [تنسيقات الأهداف](#target-formats) أدناه. +راجع [وثائق Adaptive Cards](https://adaptivecards.io/) للحصول على مخطط البطاقات والأمثلة. ولمعرفة تفاصيل تنسيق الوجهة، راجع [تنسيقات الوجهة](#target-formats) أدناه. -## تنسيقات الأهداف +## تنسيقات الوجهة -تستخدم أهداف MSTeams بادئات للتمييز بين المستخدمين والمحادثات: +تستخدم وجهات MSTeams بادئات للتمييز بين المستخدمين والمحادثات: -| نوع الهدف | التنسيق | المثال | -| ---------------------- | -------------------------------- | --------------------------------------------------- | -| مستخدم (حسب المعرّف) | `user:` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` | -| مستخدم (حسب الاسم) | `user:` | `user:John Smith` ‏(يتطلب Graph API) | -| مجموعة/قناة | `conversation:` | `conversation:19:abc123...@thread.tacv2` | -| مجموعة/قناة (خام) | `` | `19:abc123...@thread.tacv2` ‏(إذا كان يتضمن `@thread`) | +| نوع الوجهة | التنسيق | المثال | +| ------------------- | -------------------------------- | --------------------------------------------------- | +| مستخدم (حسب المعرّف) | `user:` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` | +| مستخدم (حسب الاسم) | `user:` | `user:John Smith` (يتطلب Graph API) | +| مجموعة/قناة | `conversation:` | `conversation:19:abc123...@thread.tacv2` | +| مجموعة/قناة (خام) | `` | `19:abc123...@thread.tacv2` (إذا كان يحتوي على `@thread`) | **أمثلة CLI:** @@ -684,7 +838,7 @@ openclaw message send --channel msteams \ # الإرسال إلى مستخدم حسب المعرّف openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello" -# الإرسال إلى مستخدم حسب اسم العرض (يُفعّل بحث Graph API) +# الإرسال إلى مستخدم حسب اسم العرض (يؤدي إلى بحث عبر Graph API) openclaw message send --channel msteams --target "user:John Smith" --message "Hello" # الإرسال إلى دردشة جماعية أو قناة @@ -695,7 +849,7 @@ openclaw message send --channel msteams --target "conversation:19:abc...@thread. --card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}' ``` -**أمثلة أداة الوكيل:** +**أمثلة أدوات الوكيل:** ```json5 { @@ -719,79 +873,79 @@ openclaw message send --channel msteams --target "conversation:19:abc...@thread. } ``` -ملاحظة: من دون البادئة `user:`، تُفسَّر الأسماء افتراضيًا على أنها حل لمجموعة/فريق. استخدم دائمًا `user:` عند استهداف أشخاص باسم العرض. +ملاحظة: بدون البادئة `user:`، تُوجَّه الأسماء افتراضيًا إلى حلّ المجموعة/الفريق. استخدم دائمًا `user:` عند استهداف الأشخاص باسم العرض. ## المراسلة الاستباقية -- لا يمكن إرسال الرسائل الاستباقية إلا **بعد** أن يتفاعل المستخدم، لأننا نخزن مراجع المحادثات في تلك اللحظة. -- راجع `/gateway/configuration` لمعرفة `dmPolicy` وتقييد قائمة السماح. +- لا تكون الرسائل الاستباقية ممكنة إلا **بعد** أن يتفاعل المستخدم، لأننا نخزن مراجع المحادثة عند تلك النقطة. +- راجع `/gateway/configuration` لمعرفة إعدادات `dmPolicy` وتقييد قائمة السماح. ## معرّفات الفريق والقناة (مشكلة شائعة) -إن معلمة الاستعلام `groupId` في عناوين URL الخاصة بـ Teams **ليست** معرّف الفريق المستخدم في الإعداد. استخرج المعرّفات من مسار URL بدلًا من ذلك: +ليست معلمة الاستعلام `groupId` في عناوين URL الخاصة بـ Teams هي معرّف الفريق المستخدم للإعداد. استخرج المعرّفات من مسار URL بدلًا من ذلك: -**URL الفريق:** +**عنوان URL للفريق:** ``` https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=... └────────────────────────────┘ - معرّف الفريق (نفّذ URL-decode لهذا) + معرّف الفريق (فك ترميز URL لهذا) ``` -**URL القناة:** +**عنوان URL للقناة:** ``` https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=... └─────────────────────────┘ - معرّف القناة (نفّذ URL-decode لهذا) + معرّف القناة (فك ترميز URL لهذا) ``` **للإعداد:** -- معرّف الفريق = مقطع المسار بعد `/team/` ‏(بعد URL-decoded، مثل `19:Bk4j...@thread.tacv2`) -- معرّف القناة = مقطع المسار بعد `/channel/` ‏(بعد URL-decoded) +- معرّف الفريق = مقطع المسار بعد `/team/` (بعد فك ترميز URL، مثل `19:Bk4j...@thread.tacv2`) +- معرّف القناة = مقطع المسار بعد `/channel/` (بعد فك ترميز URL) - **تجاهل** معلمة الاستعلام `groupId` ## القنوات الخاصة -تملك البوتات دعمًا محدودًا في القنوات الخاصة: +تتمتع البوتات بدعم محدود في القنوات الخاصة: -| الميزة | القنوات القياسية | القنوات الخاصة | -| ---------------------------- | ------------------ | --------------------- | -| تثبيت البوت | نعم | محدود | -| الرسائل الآنية (webhook) | نعم | قد لا تعمل | -| أذونات RSC | نعم | قد تتصرف بشكل مختلف | -| @mentions | نعم | إذا كان البوت متاحًا | -| سجل Graph API | نعم | نعم (مع الأذونات) | +| الميزة | القنوات القياسية | القنوات الخاصة | +| ---------------------------- | ----------------- | ---------------------- | +| تثبيت البوت | نعم | محدود | +| الرسائل الفورية (webhook) | نعم | قد لا تعمل | +| أذونات RSC | نعم | قد تتصرف بشكل مختلف | +| @mentions | نعم | إذا كان البوت متاحًا | +| سجل Graph API | نعم | نعم (مع الأذونات) | -**حلول بديلة إذا لم تعمل القنوات الخاصة:** +**الحلول البديلة إذا لم تعمل القنوات الخاصة:** 1. استخدم القنوات القياسية لتفاعلات البوت 2. استخدم الرسائل المباشرة - يمكن للمستخدمين دائمًا مراسلة البوت مباشرةً -3. استخدم Graph API للوصول إلى السجل التاريخي (يتطلب `ChannelMessage.Read.All`) +3. استخدم Graph API للوصول إلى السجل (يتطلب `ChannelMessage.Read.All`) ## استكشاف الأخطاء وإصلاحها -### مشكلات شائعة +### المشكلات الشائعة -- **الصور لا تظهر في القنوات:** أذونات Graph أو موافقة المسؤول مفقودة. أعد تثبيت تطبيق Teams وأغلق Teams تمامًا ثم أعد فتحه. -- **لا توجد ردود في القناة:** الإشارات مطلوبة افتراضيًا؛ اضبط `channels.msteams.requireMention=false` أو قم بالإعداد لكل فريق/قناة. -- **عدم تطابق الإصدار (ما يزال Teams يعرض manifest قديمًا):** أزل التطبيق ثم أعد إضافته وأغلق Teams تمامًا لتحديثه. -- **401 Unauthorized من webhook:** هذا متوقع عند الاختبار اليدوي من دون Azure JWT - ويعني أن نقطة النهاية قابلة للوصول لكن المصادقة فشلت. استخدم Azure Web Chat للاختبار بشكل صحيح. +- **الصور لا تظهر في القنوات:** أذونات Graph أو موافقة المسؤول مفقودة. أعد تثبيت تطبيق Teams وأغلق Teams تمامًا/أعد فتحه. +- **لا توجد ردود في القناة:** الإشارات مطلوبة افتراضيًا؛ اضبط `channels.msteams.requireMention=false` أو قم بالضبط لكل فريق/قناة. +- **عدم تطابق الإصدار (لا يزال Teams يعرض manifest القديم):** أزل التطبيق ثم أضفه من جديد وأغلق Teams تمامًا لتحديثه. +- **401 Unauthorized من webhook:** هذا متوقع عند الاختبار اليدوي بدون Azure JWT - وهذا يعني أن نقطة النهاية قابلة للوصول لكن المصادقة فشلت. استخدم Azure Web Chat للاختبار بشكل صحيح. ### أخطاء رفع manifest - **"Icon file cannot be empty":** يشير manifest إلى ملفات أيقونات حجمها 0 بايت. أنشئ أيقونات PNG صالحة (`outline.png` بحجم 32x32 و`color.png` بحجم 192x192). -- **"webApplicationInfo.Id already in use":** لا يزال التطبيق مثبتًا في فريق/دردشة أخرى. اعثر عليه وأزل تثبيته أولًا، أو انتظر 5-10 دقائق لانتشار التغيير. -- **"Something went wrong" on upload:** ارفع عبر [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com) بدلًا من ذلك، وافتح أدوات المطور في المتصفح (F12) → علامة Network، ثم تحقق من جسم الاستجابة لرؤية الخطأ الفعلي. -- **فشل التحميل الجانبي:** جرّب "Upload an app to your org's app catalog" بدلًا من "Upload a custom app" - فهذا يتجاوز غالبًا قيود التحميل الجانبي. +- **"webApplicationInfo.Id already in use":** التطبيق لا يزال مثبتًا في فريق/دردشة أخرى. ابحث عنه وأزِل تثبيته أولًا، أو انتظر 5-10 دقائق لانتشار التغييرات. +- **"Something went wrong" عند الرفع:** ارفع عبر [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com) بدلًا من ذلك، وافتح أدوات المطور في المتصفح (F12) → علامة تبويب Network، وتحقق من نص الاستجابة لمعرفة الخطأ الفعلي. +- **فشل التحميل الجانبي:** جرّب "Upload an app to your org's app catalog" بدلًا من "Upload a custom app" - فهذا غالبًا ما يتجاوز قيود التحميل الجانبي. ### أذونات RSC لا تعمل -1. تحقق من أن `webApplicationInfo.id` يطابق App ID الخاص بالبوت تمامًا +1. تحقّق من أن `webApplicationInfo.id` يطابق App ID الخاص بالبوت تمامًا 2. أعد رفع التطبيق وأعد تثبيته في الفريق/الدردشة -3. تحقق مما إذا كان مسؤول المؤسسة قد حظر أذونات RSC -4. تأكد من أنك تستخدم النطاق الصحيح: `ChannelMessage.Read.Group` للفرق، و`ChatMessage.Read.Chat` للدردشات الجماعية +3. تحقّق مما إذا كان مسؤول المؤسسة قد حظر أذونات RSC +4. أكّد أنك تستخدم النطاق الصحيح: `ChannelMessage.Read.Group` للفرق، و`ChatMessage.Read.Chat` للدردشات الجماعية ## المراجع @@ -800,13 +954,13 @@ https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?gr - [Teams app manifest schema](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema) - [Receive channel messages with RSC](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc) - [RSC permissions reference](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent) -- [Teams bot file handling](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4) ‏(القناة/المجموعة تتطلب Graph) +- [Teams bot file handling](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4) (القنوات/المجموعات تتطلب Graph) - [Proactive messaging](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages) ## ذو صلة -- [نظرة عامة على القنوات](/channels) — جميع القنوات المدعومة -- [الإقران](/channels/pairing) — مصادقة الرسائل المباشرة وتدفق الإقران -- [المجموعات](/channels/groups) — سلوك الدردشة الجماعية وتقييد الإشارات -- [توجيه القنوات](/channels/channel-routing) — توجيه الجلسات للرسائل -- [الأمان](/gateway/security) — نموذج الوصول والتقوية +- [نظرة عامة على القنوات](/ar/channels) — جميع القنوات المدعومة +- [الاقتران](/ar/channels/pairing) — مصادقة الرسائل المباشرة وتدفق الاقتران +- [المجموعات](/ar/channels/groups) — سلوك الدردشة الجماعية وتقييد الإشارات +- [توجيه القنوات](/ar/channels/channel-routing) — توجيه الجلسات للرسائل +- [الأمان](/ar/gateway/security) — نموذج الوصول والتحصين diff --git a/docs/ar/plugins/sdk-agent-harness.md b/docs/ar/plugins/sdk-agent-harness.md index d1410b9ec..36ed7eb25 100644 --- a/docs/ar/plugins/sdk-agent-harness.md +++ b/docs/ar/plugins/sdk-agent-harness.md @@ -1,51 +1,57 @@ --- read_when: - - أنت تغيّر وقت تشغيل الوكيل المضمّن أو سجل الـ harness - - أنت تسجّل agent harness من plugin مضمّنة أو موثوقة - - أنت بحاجة إلى فهم كيفية ارتباط plugin ‏Codex بموفري النماذج + - أنت تغيّر وقت تشغيل الوكيل المضمّن أو سجل Harness الخاص به + - أنت تسجّل Harness وكيل من مكوّن إضافي مضمّن أو موثوق به + - تحتاج إلى فهم كيفية ارتباط مكوّن Codex الإضافي بموفري النماذج sidebarTitle: Agent Harness -summary: سطح SDK تجريبي لـ plugins التي تستبدل منفّذ الوكيل المضمّن منخفض المستوى -title: Agent Harness Plugins +summary: سطح SDK تجريبي للمكوّنات الإضافية التي تستبدل منفّذ الوكيل المضمّن منخفض المستوى +title: مكوّنات Harness الإضافية للوكيل x-i18n: - generated_at: "2026-04-11T02:46:23Z" + generated_at: "2026-04-12T00:18:56Z" model: gpt-5.4 provider: openai - source_hash: 43c1f2c087230398b0162ed98449f239c8db1e822e51c7dcd40c54fa6c3374e1 + source_hash: 62b88fd24ce8b600179db27e16e8d764a2cd7a14e5c5df76374c33121aa5e365 source_path: plugins/sdk-agent-harness.md workflow: 15 --- -# Agent Harness Plugins +# مكوّنات Agent Harness الإضافية -إن **agent harness** هو المنفّذ منخفض المستوى لدورة وكيل OpenClaw واحدة تم إعدادها مسبقًا. وهو ليس موفر نماذج، ولا قناة، ولا سجل أدوات. +يُعد **agent harness** المنفّذ منخفض المستوى لدورة واحدة مُحضّرة لوكيل OpenClaw. +وهو ليس موفر نماذج، وليس قناة، وليس سجل أدوات. -استخدم هذا السطح فقط مع plugins الأصلية المضمّنة أو الموثوقة. لا يزال هذا العقد تجريبيًا لأن أنواع المعاملات تعكس عمدًا المنفّذ المضمّن الحالي. +استخدم هذا السطح فقط للمكوّنات الإضافية الأصلية المضمّنة أو الموثوق بها. لا يزال +هذا التعاقد تجريبيًا لأن أنواع المعاملات تعكس عمدًا المنفّذ المضمّن الحالي. ## متى تستخدم harness -سجّل agent harness عندما تكون لعائلة النماذج بيئة جلسات أصلية خاصة بها ويكون نقل الموفر العادي في OpenClaw تجريدًا غير مناسب. +سجّل agent harness عندما تكون لعائلة نماذج ما بيئة جلسات أصلية خاصة بها +ويكون نقل موفر OpenClaw العادي تجريدًا غير مناسب. أمثلة: -- خادم وكيل برمجة أصلي يملك سلاسل الرسائل والضغط +- خادم coding-agent أصلي يملك سلاسل التنفيذ والضغط - CLI أو daemon محلي يجب أن يبث أحداث الخطة/الاستدلال/الأدوات الأصلية -- بيئة تشغيل نموذج تحتاج إلى معرّف استئناف خاص بها بالإضافة إلى نسخة السجل النصي للجلسة في OpenClaw +- بيئة تشغيل نموذج تحتاج إلى معرّف استئناف خاص بها بالإضافة إلى + نص جلسة OpenClaw -**لا** تسجّل harness فقط لإضافة API جديدة لـ LLM. بالنسبة إلى واجهات API النماذج العادية عبر HTTP أو WebSocket، أنشئ [provider plugin](/ar/plugins/sdk-provider-plugins). +**لا** تسجّل harness لمجرد إضافة واجهة API جديدة لـ LLM. بالنسبة لواجهات +HTTP أو WebSocket العادية للنماذج، أنشئ [مكوّن provider إضافي](/ar/plugins/sdk-provider-plugins). -## ما الذي يبقى ضمن مسؤولية core +## ما الذي لا يزال core يملكه قبل اختيار harness، يكون OpenClaw قد حدّد بالفعل: - الموفر والنموذج -- حالة مصادقة وقت التشغيل -- مستوى الاستدلال وميزانية السياق -- ملف السجل النصي/الجلسة في OpenClaw +- حالة المصادقة في وقت التشغيل +- مستوى التفكير وميزانية السياق +- ملف النص/جلسة OpenClaw - مساحة العمل وsandbox وسياسة الأدوات -- استدعاءات ردود القنوات واستدعاءات البث -- سياسة النموذج الاحتياطي والتبديل المباشر للنموذج +- عمليات رد القناة وعمليات البث +- سياسة الرجوع إلى نموذج بديل والتبديل بين النماذج الحية -هذا الفصل مقصود. تعمل harness على محاولة تم إعدادها مسبقًا؛ فهي لا تختار الموفرين، ولا تستبدل تسليم القنوات، ولا تبدّل النماذج بصمت. +هذا التقسيم مقصود. يقوم harness بتشغيل محاولة مُحضّرة؛ ولا يختار +الموفرين، ولا يستبدل تسليم القنوات، ولا يبدّل النماذج بصمت. ## تسجيل harness @@ -66,9 +72,9 @@ const myHarness: AgentHarness = { }, async runAttempt(params) { - // ابدأ سلسلة الرسائل الأصلية أو استأنفها. - // استخدم params.prompt وparams.tools وparams.images وparams.onPartialReply، - // وparams.onAgentEvent، وغيرها من حقول المحاولة المُعدّة مسبقًا. + // Start or resume your native thread. + // Use params.prompt, params.tools, params.images, params.onPartialReply, + // params.onAgentEvent, and the other prepared attempt fields. return await runMyNativeTurn(params); }, }; @@ -76,7 +82,7 @@ const myHarness: AgentHarness = { export default definePluginEntry({ id: "my-native-agent", name: "My Native Agent", - description: "يشغّل النماذج المحددة عبر daemon وكيل أصلي.", + description: "Runs selected models through a native agent daemon.", register(api) { api.registerAgentHarness(myHarness); }, @@ -87,42 +93,82 @@ export default definePluginEntry({ يختار OpenClaw harness بعد تحديد الموفر/النموذج: -1. يفرض `OPENCLAW_AGENT_RUNTIME=` harness مسجّلة بالمعرّف نفسه. -2. يفرض `OPENCLAW_AGENT_RUNTIME=pi` استخدام harness ‏PI المضمّنة. -3. يطلب `OPENCLAW_AGENT_RUNTIME=auto` من الـ harnesses المسجّلة ما إذا كانت تدعم الموفر/النموذج المحدد. -4. إذا لم تتطابق أي harness مسجّلة، يستخدم OpenClaw ‏PI ما لم يكن الرجوع الاحتياطي إلى PI معطّلًا. +1. يفرض `OPENCLAW_AGENT_RUNTIME=` استخدام harness مسجّل بهذا المعرّف. +2. يفرض `OPENCLAW_AGENT_RUNTIME=pi` استخدام harness المدمج PI. +3. يطلب `OPENCLAW_AGENT_RUNTIME=auto` من الـ harnesses المسجّلة ما إذا كانت تدعم + الموفر/النموذج الذي تم تحديده. +4. إذا لم يطابق أي harness مسجّل، يستخدم OpenClaw PI ما لم يكن الرجوع إلى PI + معطّلًا. -تظهر إخفاقات plugin harness المفروضة كإخفاقات تشغيل. في وضع `auto`، قد يرجع OpenClaw إلى PI عندما تفشل plugin harness المحددة قبل أن تنتج الدورة أي آثار جانبية. اضبط `OPENCLAW_AGENT_HARNESS_FALLBACK=none` أو `embeddedHarness.fallback: "none"` لجعل هذا الرجوع الاحتياطي إخفاقًا صريحًا بدلًا من ذلك. +تظهر أعطال harness الخاص بالمكوّن الإضافي المفروض كأعطال تشغيل. في وضع `auto`، +قد يرجع OpenClaw إلى PI عندما يفشل harness المحدد من المكوّن الإضافي قبل أن +تنتج الدورة آثارًا جانبية. عيّن `OPENCLAW_AGENT_HARNESS_FALLBACK=none` أو +`embeddedHarness.fallback: "none"` لجعل هذا الرجوع فشلًا صارمًا بدلًا من ذلك. -تسجّل plugin ‏Codex المضمّنة `codex` بوصفه معرّف harness الخاص بها. ويتعامل core مع ذلك على أنه معرّف plugin harness عادي؛ ويجب أن تبقى الأسماء المستعارة الخاصة بـ Codex داخل plugin أو إعدادات المشغّل، لا في محدد وقت التشغيل المشترك. +يسجّل مكوّن Codex الإضافي المضمّن `codex` كمعرّف harness له. ويتعامل core مع ذلك +باعتباره معرّف harness عاديًا لمكوّن إضافي؛ أما الأسماء المستعارة الخاصة بـ Codex +فينبغي أن تكون ضمن المكوّن الإضافي أو إعدادات المشغّل، لا في محدد وقت التشغيل المشترك. -## إقران الموفر مع harness +## إقران provider مع harness -ينبغي لمعظم الـ harnesses أيضًا تسجيل موفر. يجعل الموفر مراجع النماذج، وحالة المصادقة، والبيانات الوصفية للنموذج، واختيار `/model` مرئية لبقية OpenClaw. ثم تطالب harness بهذا الموفر في `supports(...)`. +ينبغي لمعظم الـ harnesses أيضًا تسجيل provider. يجعل provider مراجع النماذج، +وحالة المصادقة، وبيانات النموذج الوصفية، واختيار `/model` مرئية لباقي OpenClaw. +ثم يطالب harness بهذا الموفر في `supports(...)`. -تتبع plugin ‏Codex المضمّنة هذا النمط: +يتبع مكوّن Codex الإضافي المضمّن هذا النمط: -- معرّف الموفر: `codex` -- مراجع النماذج للمستخدم: `codex/gpt-5.4` و`codex/gpt-5.2` أو أي نموذج آخر يعيده خادم تطبيق Codex +- معرّف provider: `codex` +- مراجع النماذج للمستخدم: `codex/gpt-5.4` و`codex/gpt-5.2` أو نموذج آخر يعيده + خادم تطبيق Codex - معرّف harness: `codex` -- المصادقة: توفر موفر اصطناعي، لأن harness ‏Codex تملك تسجيل الدخول/الجلسة الأصلية لـ Codex -- طلب خادم التطبيق: يرسل OpenClaw معرّف النموذج المجرد إلى Codex ويجعل harness تتحدث مع بروتوكول خادم التطبيق الأصلي +- المصادقة: إتاحة موفر تركيبية، لأن Codex harness يملك تسجيل الدخول/الجلسة الأصلية لـ Codex +- طلب خادم التطبيق: يرسل OpenClaw معرّف النموذج المجرد إلى Codex ويترك + لـ harness التحدث مع بروتوكول خادم التطبيق الأصلي -إن plugin ‏Codex إضافة تكميلية. تظل مراجع `openai/gpt-*` العادية مراجع لموفر OpenAI وتواصل استخدام مسار موفر OpenClaw العادي. اختر `codex/gpt-*` عندما تريد مصادقة مُدارة من Codex، واكتشاف نماذج Codex، وسلاسل رسائل أصلية، وتنفيذ خادم تطبيق Codex. يمكن لـ `/model` التبديل بين نماذج Codex التي يعيدها خادم تطبيق Codex دون الحاجة إلى بيانات اعتماد موفر OpenAI. +مكوّن Codex الإضافي ذو طبيعة إضافية. تظل مراجع `openai/gpt-*` العادية +مراجع لموفر OpenAI وتستمر في استخدام مسار موفر OpenClaw العادي. اختر `codex/gpt-*` +عندما تريد مصادقة مُدارة بواسطة Codex، واكتشاف نماذج Codex، وسلاسل تنفيذ أصلية، +وتنفيذ خادم تطبيق Codex. يمكن لـ `/model` التبديل بين نماذج Codex التي يعيدها +خادم تطبيق Codex من دون الحاجة إلى بيانات اعتماد موفر OpenAI. لإعدادات المشغّل، وأمثلة بادئات النماذج، وإعدادات Codex فقط، راجع [Codex Harness](/ar/plugins/codex-harness). -يتطلب OpenClaw إصدار خادم تطبيق Codex `0.118.0` أو أحدث. تتحقق plugin ‏Codex من مصافحة تهيئة خادم التطبيق وتمنع الخوادم الأقدم أو غير ذات الإصدار حتى لا يعمل OpenClaw إلا مع سطح البروتوكول الذي تم اختباره معه. +يتطلب OpenClaw إصدار Codex app-server `0.118.0` أو أحدث. يتحقق مكوّن Codex +الإضافي من مصافحة التهيئة مع app-server ويحظر الخوادم الأقدم أو غير المرقمة +حتى لا يعمل OpenClaw إلا على سطح البروتوكول الذي جرى اختباره معه. -## تعطيل الرجوع الاحتياطي إلى PI +### وضع Codex harness الأصلي -افتراضيًا، يشغّل OpenClaw الوكلاء المضمّنين مع `agents.defaults.embeddedHarness` -مضبوطة على `{ runtime: "auto", fallback: "pi" }`. في وضع `auto`، يمكن لـ plugin harnesses المسجّلة المطالبة بزوج موفر/نموذج مطابق. إذا لم يتطابق أي منها، أو إذا فشلت plugin harness مختارة تلقائيًا قبل إنتاج مخرجات، يرجع OpenClaw إلى PI. +يُعد `codex` harness المضمّن وضع Codex الأصلي لدورات وكلاء OpenClaw المضمّنة. +فعّل مكوّن `codex` الإضافي المضمّن أولًا، وأدرج `codex` في +`plugins.allow` إذا كان إعدادك يستخدم قائمة سماح مقيّدة. وهو يختلف عن +`openai-codex/*`: -اضبط `fallback: "none"` عندما تحتاج إلى إثبات أن plugin harness هي بيئة التشغيل الوحيدة المستخدمة. يعطّل هذا الرجوع الاحتياطي التلقائي إلى PI؛ لكنه لا يمنع `runtime: "pi"` الصريح أو `OPENCLAW_AGENT_RUNTIME=pi`. +- يستخدم `openai-codex/*` OAuth الخاص بـ ChatGPT/Codex عبر مسار موفر OpenClaw العادي. +- يستخدم `codex/*` موفر Codex المضمّن ويوجّه الدورة عبر Codex + app-server. -لتشغيلات مضمّنة خاصة بـ Codex فقط: +عند تشغيل هذا الوضع، يملك Codex معرّف سلسلة التنفيذ الأصلية، وسلوك الاستئناف، +والضغط، وتنفيذ app-server. ولا يزال OpenClaw يملك قناة الدردشة، +ومرآة النص الظاهرة، وسياسة الأدوات، والموافقات، وتسليم الوسائط، واختيار +الجلسة. استخدم `embeddedHarness.runtime: "codex"` مع +`embeddedHarness.fallback: "none"` عندما تحتاج إلى إثبات أن مسار Codex +app-server مستخدم وأن الرجوع إلى PI لا يخفي harness أصليًا معطّلًا. + +## تعطيل الرجوع إلى PI + +بشكل افتراضي، يشغّل OpenClaw الوكلاء المضمّنين مع تعيين `agents.defaults.embeddedHarness` +إلى `{ runtime: "auto", fallback: "pi" }`. في وضع `auto`، يمكن لـ harnesses +المسجّلة من المكوّنات الإضافية المطالبة بزوج موفر/نموذج. إذا لم يطابق أي منها، +أو إذا فشل harness لمكوّن إضافي تم اختياره تلقائيًا قبل إنتاج أي مخرجات، +يرجع OpenClaw إلى PI. + +عيّن `fallback: "none"` عندما تحتاج إلى إثبات أن harness الخاص بالمكوّن الإضافي +هو وقت التشغيل الوحيد الجاري استخدامه. يؤدي ذلك إلى تعطيل الرجوع التلقائي إلى PI؛ +لكنه لا يمنع `runtime: "pi"` الصريح أو `OPENCLAW_AGENT_RUNTIME=pi`. + +لتشغيلات مضمّنة خاصة بـ Codex: ```json { @@ -138,7 +184,9 @@ export default definePluginEntry({ } ``` -إذا كنت تريد أن تطالب أي plugin harness مسجّلة بالنماذج المطابقة لكنك لا تريد أبدًا أن يرجع OpenClaw بصمت إلى PI، فأبقِ `runtime: "auto"` وعطّل الرجوع الاحتياطي: +إذا كنت تريد أن تطالب أي harness مسجّل من المكوّنات الإضافية بالنماذج المطابقة ولكنك +لا تريد أبدًا أن يرجع OpenClaw بصمت إلى PI، فأبقِ `runtime: "auto"` وعطّل +الرجوع: ```json { @@ -153,7 +201,7 @@ export default definePluginEntry({ } ``` -تستخدم التجاوزات الخاصة بكل وكيل البنية نفسها: +تستخدم عمليات التجاوز لكل وكيل الشكل نفسه: ```json { @@ -178,8 +226,9 @@ export default definePluginEntry({ } ``` -لا يزال `OPENCLAW_AGENT_RUNTIME` يتجاوز وقت التشغيل المضبوط. استخدم -`OPENCLAW_AGENT_HARNESS_FALLBACK=none` لتعطيل الرجوع الاحتياطي إلى PI من البيئة. +لا يزال `OPENCLAW_AGENT_RUNTIME` يتجاوز وقت التشغيل المكوَّن. استخدم +`OPENCLAW_AGENT_HARNESS_FALLBACK=none` لتعطيل الرجوع إلى PI من +البيئة. ```bash OPENCLAW_AGENT_RUNTIME=codex \ @@ -187,39 +236,53 @@ OPENCLAW_AGENT_HARNESS_FALLBACK=none \ openclaw gateway run ``` -مع تعطيل الرجوع الاحتياطي، تفشل الجلسة مبكرًا عندما لا تكون harness المطلوبة مسجّلة، أو لا تدعم الموفر/النموذج المحدد، أو تفشل قبل إنتاج آثار جانبية للدورة. وهذا مقصود في عمليات النشر الخاصة بـ Codex فقط وفي الاختبارات المباشرة التي يجب أن تثبت أن مسار خادم تطبيق Codex مستخدم فعلًا. +مع تعطيل الرجوع، تفشل الجلسة مبكرًا عندما لا يكون harness المطلوب +مسجّلًا، أو لا يدعم الموفر/النموذج الذي تم تحديده، أو يفشل قبل +إنتاج آثار جانبية للدورة. وهذا مقصود لعمليات النشر الخاصة بـ Codex فقط +ولاختبارات live التي يجب أن تثبت أن مسار Codex app-server قيد الاستخدام فعلًا. -يتحكم هذا الإعداد فقط في agent harness المضمّنة. وهو لا يعطّل توجيه النماذج الخاص بالموفر للصور أو الفيديو أو الموسيقى أو TTS أو PDF أو غيرها. +يتحكم هذا الإعداد فقط في embedded agent harness. ولا يعطّل +توجيه النماذج الخاص بالموفر للصور أو الفيديو أو الموسيقى أو TTS أو PDF أو غيرها. -## الجلسات الأصلية ونسخة السجل النصي +## الجلسات الأصلية ومرآة النص -قد تحتفظ harness بمعرّف جلسة أصلي أو معرّف سلسلة رسائل أو رمز استئناف من جهة daemon. أبقِ هذا الربط مرتبطًا صراحةً بجلسة OpenClaw، واستمر في عكس مخرجات المساعد/الأداة المرئية للمستخدم إلى السجل النصي في OpenClaw. +قد يحتفظ harness بمعرّف جلسة أصلي، أو معرّف سلسلة تنفيذ، أو رمز استئناف +على جانب daemon. أبقِ هذا الارتباط مقترنًا صراحةً بجلسة OpenClaw، واستمر +في عكس مخرجات المساعد/الأداة الظاهرة للمستخدم إلى نص OpenClaw. -يبقى السجل النصي في OpenClaw طبقة التوافق من أجل: +يبقى نص OpenClaw طبقة التوافق من أجل: -- سجل الجلسة المرئي للقنوات -- البحث في السجل النصي وفهرسته -- التبديل مجددًا إلى harness ‏PI المضمّنة في دورة لاحقة +- سجل الجلسة الظاهر في القناة +- البحث في النص وفهرسته +- العودة إلى harness المدمج PI في دورة لاحقة - السلوك العام لـ `/new` و`/reset` وحذف الجلسة -إذا كانت harness تخزّن ربط sidecar، فنفّذ `reset(...)` حتى يتمكن OpenClaw من مسحه عند إعادة تعيين جلسة OpenClaw المالكة. +إذا كان harness يخزن ارتباطًا جانبيًا، فنفّذ `reset(...)` حتى يتمكن OpenClaw من +مسحه عند إعادة تعيين جلسة OpenClaw المالكة له. ## نتائج الأدوات والوسائط -ينشئ core قائمة أدوات OpenClaw ويمررها إلى المحاولة المُعدّة مسبقًا. عندما تنفّذ harness استدعاء أداة ديناميكيًا، فأعد نتيجة الأداة عبر بنية نتيجة harness بدلًا من إرسال وسائط القناة بنفسك. +يبني core قائمة أدوات OpenClaw ويمررها إلى المحاولة المُحضّرة. +عندما ينفّذ harness استدعاء أداة ديناميكيًا، أعد نتيجة الأداة عبر +صيغة نتيجة harness بدلًا من إرسال وسائط القناة بنفسك. -هذا يُبقي مخرجات النص والصورة والفيديو والموسيقى وTTS والموافقات وأدوات المراسلة على مسار التسليم نفسه مثل التشغيلات المعتمدة على PI. +يحافظ ذلك على مخرجات النص والصورة والفيديو والموسيقى وTTS والموافقة وأدوات المراسلة +ضمن مسار التسليم نفسه كما في التشغيلات المدعومة بـ PI. ## القيود الحالية -- مسار الاستيراد العام عامّ، لكن بعض الأسماء المستعارة لأنواع المحاولة/النتيجة ما تزال تحمل أسماء `Pi` للتوافق. -- تثبيت harness من طرف ثالث ما يزال تجريبيًا. فضّل provider plugins إلى أن تحتاج إلى بيئة جلسات أصلية. -- التبديل بين الـ harnesses مدعوم عبر الدورات. لا تبدّل الـ harnesses في منتصف الدورة بعد بدء الأدوات الأصلية أو الموافقات أو نص المساعد أو إرسال الرسائل. +- مسار الاستيراد العام عام، لكن بعض الأسماء المستعارة لأنواع المحاولة/النتيجة لا تزال + تحمل أسماء `Pi` من أجل التوافق. +- تثبيت harnesses الخارجية تجريبي. فضّل مكوّنات provider الإضافية + إلى أن تحتاج إلى بيئة جلسات أصلية. +- التبديل بين harnesses مدعوم عبر الدورات. لا تبدّل بين harnesses في + منتصف الدورة بعد بدء الأدوات الأصلية أو الموافقات أو نص المساعد أو إرسال + الرسائل. ## ذو صلة - [نظرة عامة على SDK](/ar/plugins/sdk-overview) - [مساعدات وقت التشغيل](/ar/plugins/sdk-runtime) -- [Provider Plugins](/ar/plugins/sdk-provider-plugins) +- [مكوّنات Provider الإضافية](/ar/plugins/sdk-provider-plugins) - [Codex Harness](/ar/plugins/codex-harness) - [موفرو النماذج](/ar/concepts/model-providers) diff --git a/docs/ar/providers/openai.md b/docs/ar/providers/openai.md index 0598eecd3..b421412a1 100644 --- a/docs/ar/providers/openai.md +++ b/docs/ar/providers/openai.md @@ -1,51 +1,51 @@ --- read_when: - تريد استخدام نماذج OpenAI في OpenClaw - - تريد استخدام مصادقة اشتراك Codex بدلًا من مفاتيح API + - تريد مصادقة اشتراك Codex بدلًا من مفاتيح API + - تحتاج إلى سلوك تنفيذ أكثر صرامة لوكيل GPT-5 summary: استخدم OpenAI عبر مفاتيح API أو اشتراك Codex في OpenClaw title: OpenAI x-i18n: - generated_at: "2026-04-07T07:22:43Z" + generated_at: "2026-04-12T00:18:54Z" model: gpt-5.4 provider: openai - source_hash: 6a2ce1ce5f085fe55ec50b8d20359180b9002c9730820cd5b0e011c3bf807b64 + source_hash: 7aa06fba9ac901e663685a6b26443a2f6aeb6ec3589d939522dc87cbb43497b4 source_path: providers/openai.md workflow: 15 --- # OpenAI -توفّر OpenAI واجهات API للمطورين لنماذج GPT. يدعم Codex **تسجيل الدخول إلى ChatGPT** للوصول -عبر الاشتراك أو **تسجيل الدخول بمفتاح API** للوصول القائم على الاستخدام. يتطلب Codex cloud تسجيل الدخول إلى ChatGPT. -وتدعم OpenAI صراحةً استخدام OAuth الخاص بالاشتراك في الأدوات/سير العمل الخارجية مثل OpenClaw. +توفّر OpenAI واجهات API للمطورين لنماذج GPT. يدعم Codex **تسجيل الدخول عبر ChatGPT** للوصول عبر الاشتراك أو **تسجيل الدخول عبر مفتاح API** للوصول القائم على الاستخدام. يتطلب Codex cloud تسجيل الدخول عبر ChatGPT. +تدعم OpenAI صراحةً استخدام OAuth للاشتراك في الأدوات/سير العمل الخارجية مثل OpenClaw. ## نمط التفاعل الافتراضي -يمكن لـ OpenClaw إضافة تراكب توجيه صغير خاص بـ OpenAI لكل من تشغيلات `openai/*` و -`openai-codex/*`. وبشكل افتراضي، يبقي هذا التراكب المساعد ودودًا، -وتعاونيًا، ومقتضبًا، ومباشرًا، وأكثر تعبيرًا عاطفيًا قليلًا -من دون أن يستبدل توجيه نظام OpenClaw الأساسي. كما يسمح التراكب الودود أيضًا -باستخدام الرموز التعبيرية أحيانًا عندما يكون ذلك مناسبًا بشكل طبيعي، مع الحفاظ -على اقتضاب المخرجات عمومًا. +يمكن لـ OpenClaw إضافة طبقة تراكب صغيرة خاصة بـ OpenAI إلى الموجّه لكل من تشغيلات `openai/*` و +`openai-codex/*`. افتراضيًا، تُبقي طبقة التراكب المساعد ودودًا، +ومتعاونًا، وموجزًا، ومباشرًا، وأكثر تعبيرًا عاطفيًا قليلًا +من دون استبدال موجّه نظام OpenClaw الأساسي. كما تسمح طبقة التراكب الودية +باستخدام الرمز التعبيري أحيانًا عندما يكون مناسبًا بشكل طبيعي، مع الإبقاء على +الإخراج العام موجزًا. -مفتاح الإعدادات: +مفتاح الإعداد: `plugins.entries.openai.config.personality` القيم المسموح بها: -- `"friendly"`: الافتراضي؛ يفعّل التراكب الخاص بـ OpenAI. -- `"on"`: اسم مستعار لـ `"friendly"`. -- `"off"`: يعطّل التراكب ويستخدم توجيه OpenClaw الأساسي فقط. +- `"friendly"`: الافتراضي؛ يفعّل طبقة التراكب الخاصة بـ OpenAI. +- `"on"`: اسم بديل لـ `"friendly"`. +- `"off"`: يعطّل طبقة التراكب ويستخدم موجّه OpenClaw الأساسي فقط. النطاق: - ينطبق على نماذج `openai/*`. - ينطبق على نماذج `openai-codex/*`. -- لا يؤثر في الموفّرين الآخرين. +- لا يؤثر في مزوّدين آخرين. -هذا السلوك مفعّل افتراضيًا. احتفظ بـ `"friendly"` صراحةً إذا كنت تريد أن -يستمر ذلك رغم تقلبات الإعدادات المحلية مستقبلًا: +هذا السلوك مفعّل افتراضيًا. أبقِ `"friendly"` مضبوطًا صراحةً إذا كنت تريد أن +يستمر هذا الإعداد رغم أي تغييرات محلية مستقبلية في الإعدادات: ```json5 { @@ -61,9 +61,9 @@ x-i18n: } ``` -### تعطيل تراكب توجيه OpenAI +### تعطيل طبقة موجّه OpenAI -إذا أردت توجيه OpenClaw الأساسي غير المعدّل، فاضبط التراكب على `"off"`: +إذا كنت تريد موجّه OpenClaw الأساسي غير المعدّل، فاضبط طبقة التراكب على `"off"`: ```json5 { @@ -79,35 +79,35 @@ x-i18n: } ``` -يمكنك أيضًا ضبطه مباشرةً باستخدام config CLI: +يمكنك أيضًا ضبطه مباشرةً باستخدام CLI الخاص بالإعدادات: ```bash openclaw config set plugins.entries.openai.config.personality off ``` -يقوم OpenClaw بتسوية هذا الإعداد دون حساسية لحالة الأحرف وقت التشغيل، لذا فإن قيمًا مثل -`"Off"` ستعطّل التراكب الودود أيضًا. +يُطبّع OpenClaw هذا الإعداد أثناء التشغيل بدون حساسية لحالة الأحرف، لذا فإن قيمًا مثل +`"Off"` ستعطّل أيضًا طبقة التراكب الودية. -## الخيار A: مفتاح OpenAI API (OpenAI Platform) +## الخيار A: مفتاح OpenAI API ‏(OpenAI Platform) **الأفضل لـ:** الوصول المباشر إلى API والفوترة القائمة على الاستخدام. احصل على مفتاح API من لوحة تحكم OpenAI. ملخص المسار: -- `openai/gpt-5.4` = مسار OpenAI Platform API مباشر -- يتطلب `OPENAI_API_KEY` (أو إعداد موفّر OpenAI مكافئ) -- في OpenClaw، يتم توجيه تسجيل الدخول إلى ChatGPT/Codex عبر `openai-codex/*` وليس `openai/*` +- `openai/gpt-5.4` = مسار API مباشر إلى OpenAI Platform +- يتطلب `OPENAI_API_KEY` (أو إعداد مزوّد OpenAI مكافئ) +- في OpenClaw، يُوجَّه تسجيل الدخول عبر ChatGPT/Codex من خلال `openai-codex/*` وليس `openai/*` ### إعداد CLI ```bash openclaw onboard --auth-choice openai-api-key -# أو بدون تفاعل +# أو بشكل غير تفاعلي openclaw onboard --openai-api-key "$OPENAI_API_KEY" ``` -### مقتطف إعدادات +### مقتطف إعداد ```json5 { @@ -116,28 +116,28 @@ openclaw onboard --openai-api-key "$OPENAI_API_KEY" } ``` -تسرد وثائق نماذج API الحالية من OpenAI النموذجين `gpt-5.4` و`gpt-5.4-pro` للاستخدام المباشر -مع OpenAI API. ويقوم OpenClaw بتمرير كليهما عبر مسار `openai/*` الخاص بـ Responses. -ويتعمّد OpenClaw إخفاء السطر القديم `openai/gpt-5.3-codex-spark`، -لأن استدعاءات OpenAI API المباشرة ترفضه في حركة المرور الحية. +تسرد مستندات نماذج API الحالية من OpenAI النموذجين `gpt-5.4` و `gpt-5.4-pro` للاستخدام المباشر عبر +OpenAI API. يمرّر OpenClaw كليهما عبر مسار `openai/*` Responses. +ويتعمد OpenClaw إخفاء الصف القديم `openai/gpt-5.3-codex-spark`، +لأن استدعاءات OpenAI API المباشرة ترفضه في الحركة الحية. -لا يعرض OpenClaw **`openai/gpt-5.3-codex-spark`** على مسار OpenAI -API المباشر. لا يزال `pi-ai` يوفّر سطرًا مضمّنًا لذلك النموذج، لكن طلبات OpenAI API الحية -ترفضه حاليًا. ويُتعامل مع Spark على أنه خاص بـ Codex فقط في OpenClaw. +لا يوفّر OpenClaw النموذج `openai/gpt-5.3-codex-spark` على مسار OpenAI +API المباشر. لا يزال `pi-ai` يوفّر صفًا مدمجًا لهذا النموذج، لكن طلبات OpenAI API الحية +ترفضه حاليًا. ويُعامل Spark على أنه خاص بـ Codex فقط في OpenClaw. -## توليد الصور +## إنشاء الصور -يسجل plugin `openai` المضمن أيضًا توليد الصور عبر الأداة المشتركة +يسجّل المكوّن الإضافي المضمّن `openai` أيضًا إنشاء الصور عبر الأداة المشتركة `image_generate`. - نموذج الصور الافتراضي: `openai/gpt-image-1` -- التوليد: حتى 4 صور لكل طلب -- وضع التعديل: مفعّل، حتى 5 صور مرجعية +- الإنشاء: حتى 4 صور لكل طلب +- وضع التحرير: مفعّل، حتى 5 صور مرجعية - يدعم `size` -- ملاحظة حالية خاصة بـ OpenAI: لا يمرّر OpenClaw حاليًا تجاوزات `aspectRatio` أو +- الملاحظة الحالية الخاصة بـ OpenAI: لا يمرّر OpenClaw حاليًا تجاوزات `aspectRatio` أو `resolution` إلى OpenAI Images API -لاستخدام OpenAI كموفّر الصور الافتراضي: +لاستخدام OpenAI كمزوّد الصور الافتراضي: ```json5 { @@ -151,23 +151,23 @@ API المباشر. لا يزال `pi-ai` يوفّر سطرًا مضمّنًا } ``` -راجع [توليد الصور](/ar/tools/image-generation) لمعلمات الأداة -المشتركة، واختيار الموفّر، وسلوك التحويل الاحتياطي. +راجع [إنشاء الصور](/ar/tools/image-generation) لمعلمات +الأداة المشتركة، واختيار المزوّد، وسلوك التبديل الاحتياطي. -## توليد الفيديو +## إنشاء الفيديو -يسجل plugin `openai` المضمن أيضًا توليد الفيديو عبر الأداة المشتركة +يسجّل المكوّن الإضافي المضمّن `openai` أيضًا إنشاء الفيديو عبر الأداة المشتركة `video_generate`. - نموذج الفيديو الافتراضي: `openai/sora-2` -- الأوضاع: من نص إلى فيديو، ومن صورة إلى فيديو، وتدفقات مرجعية/تحرير لفيديو واحد -- الحدود الحالية: صورة واحدة أو مرجع فيديو واحد -- ملاحظة حالية خاصة بـ OpenAI: يمرّر OpenClaw حاليًا فقط تجاوزات `size` - لتوليد الفيديو الأصلي في OpenAI. أما التجاوزات الاختيارية غير المدعومة - مثل `aspectRatio` و`resolution` و`audio` و`watermark` فيتم تجاهلها - والإبلاغ عنها كتحذير أداة. +- الأوضاع: نص إلى فيديو، وصورة إلى فيديو، وتدفّقات مرجعية/تحرير لفيديو واحد +- الحدود الحالية: صورة واحدة أو إدخال مرجعي لفيديو واحد +- الملاحظة الحالية الخاصة بـ OpenAI: يمرّر OpenClaw حاليًا فقط تجاوزات `size` + لإنشاء الفيديو الأصلي من OpenAI. أمّا التجاوزات الاختيارية غير المدعومة + مثل `aspectRatio` و `resolution` و `audio` و `watermark` فيتم تجاهلها + ويُبلّغ عنها كتحذير من الأداة. -لاستخدام OpenAI كموفّر الفيديو الافتراضي: +لاستخدام OpenAI كمزوّد الفيديو الافتراضي: ```json5 { @@ -181,19 +181,19 @@ API المباشر. لا يزال `pi-ai` يوفّر سطرًا مضمّنًا } ``` -راجع [توليد الفيديو](/ar/tools/video-generation) لمعلمات الأداة -المشتركة، واختيار الموفّر، وسلوك التحويل الاحتياطي. +راجع [إنشاء الفيديو](/ar/tools/video-generation) لمعلمات +الأداة المشتركة، واختيار المزوّد، وسلوك التبديل الاحتياطي. -## الخيار B: اشتراك OpenAI Code (Codex) +## الخيار B: اشتراك OpenAI Code ‏(Codex) **الأفضل لـ:** استخدام وصول اشتراك ChatGPT/Codex بدلًا من مفتاح API. -يتطلب Codex cloud تسجيل الدخول إلى ChatGPT، بينما تدعم Codex CLI تسجيل الدخول عبر ChatGPT أو مفتاح API. +يتطلب Codex cloud تسجيل الدخول عبر ChatGPT، بينما يدعم Codex CLI تسجيل الدخول عبر ChatGPT أو مفتاح API. ملخص المسار: -- `openai-codex/gpt-5.4` = مسار ChatGPT/Codex OAuth -- يستخدم تسجيل الدخول إلى ChatGPT/Codex، وليس مفتاح OpenAI Platform API مباشرًا -- قد تختلف الحدود من جهة الموفّر لـ `openai-codex/*` عن تجربة ChatGPT على الويب/التطبيق +- `openai-codex/gpt-5.4` = مسار OAuth لـ ChatGPT/Codex +- يستخدم تسجيل الدخول عبر ChatGPT/Codex، وليس مفتاح OpenAI Platform API مباشرًا +- قد تختلف الحدود على جهة المزوّد لـ `openai-codex/*` عن تجربة ChatGPT على الويب/التطبيق ### إعداد CLI ‏(Codex OAuth) @@ -201,11 +201,11 @@ API المباشر. لا يزال `pi-ai` يوفّر سطرًا مضمّنًا # شغّل Codex OAuth في المعالج openclaw onboard --auth-choice openai-codex -# أو شغّل OAuth مباشرة +# أو شغّل OAuth مباشرةً openclaw models auth login --provider openai-codex ``` -### مقتطف إعدادات (اشتراك Codex) +### مقتطف إعداد (اشتراك Codex) ```json5 { @@ -213,44 +213,44 @@ openclaw models auth login --provider openai-codex } ``` -تسرد وثائق Codex الحالية من OpenAI النموذج `gpt-5.4` باعتباره نموذج Codex الحالي. ويقوم OpenClaw -بربطه إلى `openai-codex/gpt-5.4` لاستخدام ChatGPT/Codex OAuth. +تسرد مستندات Codex الحالية من OpenAI النموذج `gpt-5.4` على أنه نموذج Codex الحالي. ويقوم OpenClaw +بربطه مع `openai-codex/gpt-5.4` لاستخدام OAuth عبر ChatGPT/Codex. -هذا المسار منفصل عمدًا عن `openai/gpt-5.4`. إذا أردت -مسار OpenAI Platform API المباشر، فاستخدم `openai/*` مع مفتاح API. وإذا أردت -تسجيل الدخول إلى ChatGPT/Codex، فاستخدم `openai-codex/*`. +هذا المسار منفصل عمدًا عن `openai/gpt-5.4`. إذا كنت تريد +المسار المباشر لـ OpenAI Platform API، فاستخدم `openai/*` مع مفتاح API. وإذا كنت تريد +تسجيل الدخول عبر ChatGPT/Codex، فاستخدم `openai-codex/*`. -إذا أعاد onboarding استخدام تسجيل دخول موجود مسبقًا في Codex CLI، فستظل بيانات الاعتماد تلك -مُدارة بواسطة Codex CLI. وعند انتهاء الصلاحية، يعيد OpenClaw قراءة مصدر Codex الخارجي -أولًا، وعندما يتمكن الموفّر من تحديثه، يكتب بيانات الاعتماد المحدّثة -مرة أخرى إلى تخزين Codex بدلًا من أخذ الملكية في نسخة منفصلة خاصة بـ OpenClaw فقط. +إذا أعادت عملية الإعداد الأولى استخدام تسجيل دخول موجود إلى Codex CLI، فستظل بيانات الاعتماد +تُدار بواسطة Codex CLI. وعند انتهاء صلاحيتها، يعيد OpenClaw قراءة مصدر Codex الخارجي +أولًا، وعندما يستطيع المزوّد تحديثها، يكتب بيانات الاعتماد المحدّثة +من جديد إلى تخزين Codex بدلًا من تولّي إدارتها في نسخة منفصلة خاصة بـ OpenClaw فقط. إذا كان حساب Codex الخاص بك مخوّلًا لاستخدام Codex Spark، فإن OpenClaw يدعم أيضًا: - `openai-codex/gpt-5.3-codex-spark` -يتعامل OpenClaw مع Codex Spark على أنه خاص بـ Codex فقط. وهو لا يعرض مسار -مباشرًا بمفتاح API من نوع `openai/gpt-5.3-codex-spark`. +يعامل OpenClaw Codex Spark على أنه خاص بـ Codex فقط. ولا يوفّر مسار +`openai/gpt-5.3-codex-spark` مباشرًا يعتمد على مفتاح API. -كما يحتفظ OpenClaw أيضًا بـ `openai-codex/gpt-5.3-codex-spark` عندما -يكتشفه `pi-ai`. ويجب التعامل معه على أنه تجريبي ومعتمد على الاستحقاق: إذ إن Codex Spark -منفصل عن GPT-5.4 `/fast`، كما أن توفره يعتمد على حساب Codex / -ChatGPT المسجّل دخوله. +كما يحافظ OpenClaw على `openai-codex/gpt-5.3-codex-spark` عندما +يكتشفه `pi-ai`. ويجب التعامل معه على أنه يعتمد على الأهلية وتجريبي: إذ إن Codex Spark +منفصل عن GPT-5.4 `/fast`، ويعتمد توفره على حساب Codex / ChatGPT +المسجّل الدخول به. -### حد نافذة سياق Codex +### حد نافذة السياق في Codex -يتعامل OpenClaw مع بيانات نموذج Codex الوصفية وحد وقت تشغيل السياق على أنهما +يعامل OpenClaw بيانات نموذج Codex الوصفية وحد وقت التشغيل للسياق على أنهما قيمتان منفصلتان. بالنسبة إلى `openai-codex/gpt-5.4`: - `contextWindow` الأصلي: `1050000` -- الحد الافتراضي لوقت التشغيل `contextTokens`: `272000` +- حد `contextTokens` الافتراضي في وقت التشغيل: `272000` -يحافظ ذلك على صحة بيانات النموذج الوصفية مع الإبقاء على نافذة -وقت التشغيل الافتراضية الأصغر، التي تتمتع عمليًا بخصائص أفضل من حيث الكمون والجودة. +يحافظ ذلك على صحة بيانات النموذج الوصفية مع الإبقاء على نافذة التشغيل الافتراضية الأصغر +التي تتمتع عمليًا بخصائص أفضل من حيث زمن الاستجابة والجودة. -إذا أردت حدًا فعليًا مختلفًا، فاضبط `models.providers..models[].contextTokens`: +إذا كنت تريد حدًا فعليًا مختلفًا، فاضبط `models.providers..models[].contextTokens`: ```json5 { @@ -269,47 +269,44 @@ ChatGPT المسجّل دخوله. } ``` -استخدم `contextWindow` فقط عندما تقوم بتعريف أو تجاوز بيانات النموذج الأصلية -الوصفية. واستخدم `contextTokens` عندما تريد تقييد ميزانية السياق وقت التشغيل. +استخدم `contextWindow` فقط عندما تعلن أو تتجاوز بيانات النموذج +الوصفية الأصلية. واستخدم `contextTokens` عندما تريد تقييد ميزانية السياق في وقت التشغيل. ### النقل الافتراضي -يستخدم OpenClaw `pi-ai` لبث النموذج. ولكل من `openai/*` و -`openai-codex/*`، يكون النقل الافتراضي هو `"auto"` (WebSocket أولًا، ثم -التحويل الاحتياطي إلى SSE). +يستخدم OpenClaw ‏`pi-ai` لبث النماذج. ولكل من `openai/*` و +`openai-codex/*`، يكون النقل الافتراضي هو `"auto"` ‏(WebSocket أولًا، ثم الرجوع إلى SSE). -في وضع `"auto"`، يعيد OpenClaw أيضًا محاولة واحدة عند حدوث فشل مبكر قابل لإعادة المحاولة في WebSocket -قبل أن يتحول احتياطيًا إلى SSE. أما وضع `"websocket"` المفروض فلا يزال يُظهر أخطاء النقل -مباشرةً بدلًا من إخفائها وراء التحويل الاحتياطي. +في وضع `"auto"`، يعيد OpenClaw أيضًا المحاولة مرة واحدة عند حدوث فشل مبكر قابل لإعادة المحاولة في WebSocket +قبل أن يرجع إلى SSE. أمّا الوضع الإجباري `"websocket"` فيُظهر أخطاء النقل مباشرةً بدلًا من إخفائها خلف الرجوع الاحتياطي. -بعد فشل WebSocket عند الاتصال أو في الدور المبكر في وضع `"auto"`، يعلّم OpenClaw -مسار WebSocket الخاص بتلك الجلسة على أنه متدهور لمدة تقارب 60 ثانية، ويرسل -الأدوار اللاحقة عبر SSE خلال فترة التهدئة بدلًا من التنقل العنيف بين -وسائل النقل. +بعد فشل WebSocket عند الاتصال أو في بداية الدور ضمن وضع `"auto"`، يضع OpenClaw +مسار WebSocket الخاص بتلك الجلسة في حالة متدهورة لمدة تقارب 60 ثانية ويرسل +الأدوار اللاحقة عبر SSE أثناء فترة التهدئة بدلًا من التقلّب بين +أنماط النقل. -بالنسبة إلى نقاط نهاية OpenAI الأصلية (`openai/*` و`openai-codex/*` وAzure -OpenAI Responses)، يرفق OpenClaw أيضًا حالة مستقرة لهوية الجلسة والدور -بالطلبات حتى تظل إعادة المحاولة وإعادة الاتصال والتحويل الاحتياطي إلى SSE منسجمة مع -هوية المحادثة نفسها. ويتضمن ذلك على مسارات عائلة OpenAI الأصلية رؤوس هوية طلب مستقرة للجلسة/الدور بالإضافة إلى بيانات نقل وصفية مطابقة. +وبالنسبة إلى نقاط النهاية الأصلية من عائلة OpenAI ‏(`openai/*` و `openai-codex/*` و Azure +OpenAI Responses)، يرفق OpenClaw أيضًا حالة هوية مستقرة للجلسة والدور +بالطلبات بحيث تظل إعادة المحاولة، وإعادة الاتصال، والرجوع إلى SSE متسقة مع +هوية المحادثة نفسها. وعلى مسارات عائلة OpenAI الأصلية، يتضمن ذلك رؤوس هوية مستقرة لطلب الجلسة/الدور بالإضافة إلى بيانات نقل وصفية مطابقة. -كما يطبع OpenClaw أيضًا عدادات استخدام OpenAI عبر متغيرات النقل المختلفة قبل -أن تصل إلى واجهات الجلسة/الحالة. فقد يبلّغ مرور Native OpenAI/Codex Responses -عن الاستخدام بصيغة `input_tokens` / `output_tokens` أو -`prompt_tokens` / `completion_tokens`؛ ويتعامل OpenClaw معها على أنها عدادات -الإدخال والإخراج نفسها بالنسبة إلى `/status` و`/usage` وسجلات الجلسات. وعندما يحذف -مرور WebSocket الأصلي `total_tokens` (أو يبلّغ عنه بقيمة `0`)، يعود OpenClaw إلى -إجمالي الإدخال + الإخراج المُطبّع حتى تظل عروض الجلسة/الحالة مليئة بالبيانات. +كما يطبّع OpenClaw عدّادات استخدام OpenAI عبر تنويعات النقل قبل +أن تصل إلى واجهات الجلسة/الحالة. فقد تُبلّغ حركة OpenAI/Codex Responses الأصلية عن الاستخدام بصيغتي +`input_tokens` / `output_tokens` أو +`prompt_tokens` / `completion_tokens`؛ ويعامل OpenClaw هذه الصيغ على أنها عدّادات الإدخال +والإخراج نفسها بالنسبة إلى `/status` و `/usage` وسجلات الجلسات. وعندما تُسقط حركة +WebSocket الأصلية `total_tokens` (أو تُبلّغ عنه على أنه `0`)، يعتمد OpenClaw على إجمالي الإدخال + الإخراج المطبع حتى تبقى عروض الجلسة/الحالة مملوءة. يمكنك ضبط `agents.defaults.models..params.transport`: - `"sse"`: فرض SSE - `"websocket"`: فرض WebSocket -- `"auto"`: جرّب WebSocket، ثم تحوّل احتياطيًا إلى SSE +- `"auto"`: جرّب WebSocket ثم ارجع إلى SSE -بالنسبة إلى `openai/*` (Responses API)، يفعّل OpenClaw أيضًا الإحماء عبر WebSocket -افتراضيًا (`openaiWsWarmup: true`) عند استخدام نقل WebSocket. +وبالنسبة إلى `openai/*` ‏(Responses API)، يفعّل OpenClaw أيضًا الإحماء عبر WebSocket افتراضيًا +(`openaiWsWarmup: true`) عند استخدام نقل WebSocket. -وثائق OpenAI ذات الصلة: +مستندات OpenAI ذات الصلة: - [Realtime API with WebSocket](https://platform.openai.com/docs/guides/realtime-websocket) - [Streaming API responses (SSE)](https://platform.openai.com/docs/guides/streaming-responses) @@ -331,10 +328,10 @@ OpenAI Responses)، يرفق OpenClaw أيضًا حالة مستقرة لهوي } ``` -### إحماء OpenAI WebSocket +### إحماء WebSocket في OpenAI -تصف وثائق OpenAI الإحماء بأنه اختياري. ويقوم OpenClaw بتفعيله افتراضيًا لـ -`openai/*` لتقليل كمون الدور الأول عند استخدام نقل WebSocket. +تصف مستندات OpenAI الإحماء على أنه اختياري. ويقوم OpenClaw بتفعيله افتراضيًا لـ +`openai/*` لتقليل زمن الاستجابة في أول دور عند استخدام نقل WebSocket. ### تعطيل الإحماء @@ -372,11 +369,11 @@ OpenAI Responses)، يرفق OpenClaw أيضًا حالة مستقرة لهوي } ``` -### OpenAI وCodex والمعالجة ذات الأولوية +### المعالجة ذات الأولوية في OpenAI وCodex -تعرض API الخاصة بـ OpenAI المعالجة ذات الأولوية عبر `service_tier=priority`. في +يكشف API الخاص بـ OpenAI عن المعالجة ذات الأولوية عبر `service_tier=priority`. في OpenClaw، اضبط `agents.defaults.models["/"].params.serviceTier` -لتمرير هذا الحقل في نقاط نهاية Native OpenAI/Codex Responses. +لتمرير هذا الحقل في نقاط النهاية الأصلية لـ OpenAI/Codex Responses. ```json5 { @@ -399,38 +396,38 @@ OpenClaw، اضبط `agents.defaults.models["/"].params.service } ``` -القيم المدعومة هي `auto` و`default` و`flex` و`priority`. +القيم المدعومة هي `auto` و `default` و `flex` و `priority`. -يمرّر OpenClaw `params.serviceTier` إلى كل من طلبات Responses المباشرة `openai/*` -وطلبات Codex Responses من نوع `openai-codex/*` عندما تشير تلك النماذج -إلى نقاط نهاية Native OpenAI/Codex. +يمرّر OpenClaw ‏`params.serviceTier` إلى كل من طلبات `openai/*` المباشرة عبر Responses +وطلبات `openai-codex/*` عبر Codex Responses عندما تشير تلك النماذج +إلى نقاط النهاية الأصلية لـ OpenAI/Codex. سلوك مهم: - يجب أن يستهدف `openai/*` المباشر `api.openai.com` - يجب أن يستهدف `openai-codex/*` ‏`chatgpt.com/backend-api` -- إذا قمت بتوجيه أي من الموفّرين عبر base URL آخر أو proxy، فإن OpenClaw يترك `service_tier` من دون تعديل +- إذا وجّهت أيًا من المزوّدين عبر عنوان URL أساسي آخر أو وكيل، يترك OpenClaw قيمة `service_tier` كما هي -### وضع OpenAI السريع +### الوضع السريع في OpenAI -يعرض OpenClaw مفتاح تبديل مشترك للوضع السريع لكل من جلسات `openai/*` و +يوفّر OpenClaw مفتاح تبديل مشتركًا للوضع السريع لكل من جلسات `openai/*` و `openai-codex/*`: -- Chat/UI: ‏`/fast status|on|off` -- Config: ‏`agents.defaults.models["/"].params.fastMode` +- المحادثة/واجهة المستخدم: `/fast status|on|off` +- الإعداد: `agents.defaults.models["/"].params.fastMode` -عندما يكون الوضع السريع مفعّلًا، يربطه OpenClaw بمعالجة OpenAI ذات الأولوية: +عند تفعيل الوضع السريع، يربطه OpenClaw بالمعالجة ذات الأولوية في OpenAI: -- ترسل استدعاءات Responses المباشرة من `openai/*` إلى `api.openai.com` القيمة `service_tier = "priority"` -- وترسل استدعاءات Responses من `openai-codex/*` إلى `chatgpt.com/backend-api` أيضًا القيمة `service_tier = "priority"` -- يتم الحفاظ على قيم `service_tier` الموجودة في الحمولة +- ترسل استدعاءات `openai/*` المباشرة عبر Responses إلى `api.openai.com` القيمة `service_tier = "priority"` +- كما ترسل استدعاءات `openai-codex/*` عبر Responses إلى `chatgpt.com/backend-api` القيمة `service_tier = "priority"` +- يتم الحفاظ على قيم `service_tier` الموجودة أصلًا في الحمولة - لا يعيد الوضع السريع كتابة `reasoning` أو `text.verbosity` -وبالنسبة إلى GPT 5.4 تحديدًا، فإن الإعداد الأكثر شيوعًا هو: +بالنسبة إلى GPT 5.4 تحديدًا، فإن الإعداد الأكثر شيوعًا هو: -- إرسال `/fast on` في جلسة تستخدم `openai/gpt-5.4` أو `openai-codex/gpt-5.4` +- إرسال `/fast on` داخل جلسة تستخدم `openai/gpt-5.4` أو `openai-codex/gpt-5.4` - أو ضبط `agents.defaults.models["openai/gpt-5.4"].params.fastMode = true` -- وإذا كنت تستخدم Codex OAuth أيضًا، فاضبط `agents.defaults.models["openai-codex/gpt-5.4"].params.fastMode = true` أيضًا +- وإذا كنت تستخدم أيضًا Codex OAuth، فاضبط `agents.defaults.models["openai-codex/gpt-5.4"].params.fastMode = true` أيضًا مثال: @@ -455,49 +452,76 @@ OpenClaw، اضبط `agents.defaults.models["/"].params.service } ``` -تتغلب تجاوزات الجلسة على config. وتؤدي إزالة تجاوز الجلسة في واجهة Sessions -إلى إعادة الجلسة إلى القيمة الافتراضية المضبوطة. +تتغلب تجاوزات الجلسة على الإعدادات. ويؤدي مسح تجاوز الجلسة في واجهة Sessions +إلى إعادة الجلسة إلى الإعداد الافتراضي المضبوط. -### مسارات Native OpenAI مقابل المسارات المتوافقة مع OpenAI +### مسارات OpenAI الأصلية مقابل المسارات المتوافقة مع OpenAI -يتعامل OpenClaw مع نقاط النهاية المباشرة لـ OpenAI وCodex وAzure OpenAI بشكل مختلف -عن الوكلاء العامين المتوافقين مع OpenAI من نوع `/v1`: +يعامل OpenClaw نقاط النهاية المباشرة لـ OpenAI وCodex وAzure OpenAI بشكل مختلف +عن وكلاء `/v1` العامة المتوافقة مع OpenAI: -- تحافظ المسارات الأصلية `openai/*` و`openai-codex/*` ومسارات Azure OpenAI على - `reasoning: { effort: "none" }` كما هو عندما تعطل reasoning صراحةً -- تجعل مسارات عائلة OpenAI الأصلية مخططات الأدوات في الوضع الصارم افتراضيًا -- لا تُرفق رؤوس الإسناد المخفية الخاصة بـ OpenClaw (`originator` و`version` و - `User-Agent`) إلا على مضيفي OpenAI الأصليين المؤكدين - (`api.openai.com`) ومضيفي Codex الأصليين (`chatgpt.com/backend-api`) -- تحتفظ مسارات Native OpenAI/Codex بتشكيل الطلبات الخاص بـ OpenAI فقط مثل - `service_tier`، و`store` الخاصة بـ Responses، والحمولات المتوافقة مع OpenAI reasoning، - وتلميحات cache الخاصة بالتوجيه -- تحتفظ المسارات المتوافقة مع OpenAI على نمط proxy بسلوك التوافق الأكثر مرونة، ولا - تفرض مخططات أدوات صارمة، أو تشكيل طلبات خاص بالأصل، أو رؤوس +- تحتفظ المسارات الأصلية `openai/*` و`openai-codex/*` ومسارات Azure OpenAI بالقيمة + `reasoning: { effort: "none" }` كما هي عندما تعطل الاستدلال صراحةً +- تضبط مسارات عائلة OpenAI الأصلية مخططات الأدوات على الوضع الصارم افتراضيًا +- لا تُرفق رؤوس إسناد OpenClaw المخفية (`originator` و`version` و + `User-Agent`) إلا على مضيفات OpenAI الأصلية المتحقق منها + (`api.openai.com`) ومضيفات Codex الأصلية (`chatgpt.com/backend-api`) +- تحتفظ مسارات OpenAI/Codex الأصلية بتشكيل الطلبات الخاص بـ OpenAI مثل + `service_tier` و`store` في Responses وحمولات توافق الاستدلال الخاصة بـ OpenAI و + تلميحات cache الموجّه +- تحتفظ المسارات المتوافقة مع OpenAI على نمط الوكيل بسلوك التوافق الأكثر مرونة ولا + تفرض مخططات أدوات صارمة أو تشكيل طلبات خاصًا بالمسارات الأصلية أو رؤوس إسناد OpenAI/Codex المخفية -يبقى Azure OpenAI ضمن فئة التوجيه الأصلي بالنسبة إلى سلوك النقل والتوافق، -لكنه لا يتلقى رؤوس الإسناد المخفية الخاصة بـ OpenAI/Codex. +يبقى Azure OpenAI ضمن فئة المسارات الأصلية من حيث سلوك النقل والتوافق، +لكنه لا يتلقى رؤوس إسناد OpenAI/Codex المخفية. -يحافظ هذا على السلوك الحالي لـ Native OpenAI Responses من دون فرض طبقات -التوافق القديمة الخاصة بـ OpenAI على الواجهات الخلفية `/v1` التابعة لجهات خارجية. +يحافظ هذا على السلوك الحالي الأصلي لـ OpenAI Responses من دون فرض +طبقات التوافق الأقدم الخاصة بـ OpenAI-compatible على الواجهات الخلفية الخارجية `/v1`. + +### وضع GPT الصارم الوكيلي + +بالنسبة إلى تشغيلات GPT-5-family عبر `openai/*` و`openai-codex/*`، يمكن لـ OpenClaw استخدام +عقد تنفيذ Pi مضمّن أكثر صرامة: + +```json5 +{ + agents: { + defaults: { + embeddedPi: { + executionContract: "strict-agentic", + }, + }, + }, +} +``` + +مع `strict-agentic`، لم يعد OpenClaw يتعامل مع دور مساعد يقتصر على الخطة +على أنه تقدم ناجح عندما يكون هناك إجراء أداة ملموس متاح. بل يعيد محاولة +الدور مع توجيه للتنفيذ الفوري، ويفعّل تلقائيًا أداة `update_plan` المنظمة للأعمال +الجوهرية، ويعرض حالة تعطّل صريحة إذا واصل النموذج +التخطيط من دون تنفيذ. + +هذا الوضع محصور في تشغيلات GPT-5-family عبر OpenAI وOpenAI Codex. أما المزوّدون الآخرون +وعائلات النماذج الأقدم فيحتفظون بسلوك Pi المضمّن الافتراضي ما لم تختر +تفعيل إعدادات تشغيل أخرى لهم. ### الضغط من جهة الخادم في OpenAI Responses -بالنسبة إلى نماذج OpenAI Responses المباشرة (`openai/*` التي تستخدم `api: "openai-responses"` مع -`baseUrl` على `api.openai.com`)، يقوم OpenClaw الآن بتفعيل تلميحات حمولة -الضغط من جهة خادم OpenAI تلقائيًا: +بالنسبة إلى نماذج OpenAI Responses المباشرة (`openai/*` باستخدام `api: "openai-responses"` مع +`baseUrl` على `api.openai.com`)، يفعّل OpenClaw الآن تلقائيًا تلميحات حمولة +الضغط من جهة خادم OpenAI: -- يفرض `store: true` (إلا إذا ضبط توافق النموذج `supportsStore: false`) -- ويحقن `context_management: [{ type: "compaction", compact_threshold: ... }]` +- يفرض `store: true` (ما لم يضبط توافق النموذج `supportsStore: false`) +- يحقن `context_management: [{ type: "compaction", compact_threshold: ... }]` -افتراضيًا، تكون قيمة `compact_threshold` هي `70%` من `contextWindow` الخاص بالنموذج (أو `80000` +افتراضيًا، تكون قيمة `compact_threshold` مساوية لـ `70%` من `contextWindow` الخاص بالنموذج (أو `80000` عند عدم توفره). ### تفعيل الضغط من جهة الخادم صراحةً -استخدم هذا عندما تريد فرض حقن `context_management` على -نماذج Responses المتوافقة (مثل Azure OpenAI Responses): +استخدم هذا عندما تريد فرض حقن `context_management` في نماذج +Responses المتوافقة (مثل Azure OpenAI Responses): ```json5 { @@ -515,7 +539,7 @@ OpenClaw، اضبط `agents.defaults.models["/"].params.service } ``` -### التفعيل مع عتبة مخصصة +### التفعيل مع حد مخصص ```json5 { @@ -552,7 +576,7 @@ OpenClaw، اضبط `agents.defaults.models["/"].params.service } ``` -لا يتحكم `responsesServerCompaction` إلا في حقن `context_management`. +يتحكم `responsesServerCompaction` فقط في حقن `context_management`. ولا تزال نماذج OpenAI Responses المباشرة تفرض `store: true` ما لم يضبط التوافق `supportsStore: false`.