Gateway

بروتوكول Gateway

بروتوكول Gateway WS هو مستوى التحكم الوحيد ووسيلة نقل العُقد في OpenClaw. يتصل عملاء المشغّل والعُقد (CLI، وواجهة الويب، وتطبيق macOS، وعُقد iOS/Android، والعُقد بلا واجهة) عبر WebSocket ويُعلنون دورًا ونطاقًا عند إجراء المصافحة.

النقل وتأطير الرسائل

  • WebSocket، إطارات نصية، وحمولات JSON.
  • يجب أن يكون الإطار الأول طلب connect.
  • يقتصر حجم الإطارات السابقة للاتصال على 64 KiB (MAX_PREAUTH_PAYLOAD_BYTES). بعد المصافحة، اتبع hello-ok.policy.maxPayload و hello-ok.policy.maxBufferedBytes. عند تفعيل التشخيصات، تُصدر الإطارات الواردة ذات الحجم الزائد والمخازن المؤقتة الصادرة البطيئة أحداث payload.large قبل أن يغلق Gateway الاتصال أو يسقط الإطار. تحمل هذه الأحداث surface، وأحجام البايتات، والحدود، ورمز سبب آمنًا، ولا تحمل مطلقًا نصوص الرسائل، أو محتويات المرفقات، أو بايتات الإطار الخام، أو الرموز المميزة، أو ملفات تعريف الارتباط، أو الأسرار.

أشكال الإطارات:

  • الطلب: {type:"req", id, method, params}
  • الاستجابة: {type:"res", id, ok, payload|error}
  • الحدث: {type:"event", event, payload, seq?, stateVersion?}

تتطلب الطرق ذات الآثار الجانبية مفاتيح ضمان عدم التكرار (راجع المخطط).

المصافحة

يرسل Gateway تحديًا سابقًا للاتصال:

json
{  "type": "event",  "event": "connect.challenge",  "payload": { "nonce": "…", "ts": 1737264000000 }}

يرد العميل باستخدام connect:

json
{  "type": "req",  "id": "…",  "method": "connect",  "params": {    "minProtocol": 4,    "maxProtocol": 4,    "client": {      "id": "cli",      "version": "1.2.3",      "platform": "macos",      "mode": "operator"    },    "role": "operator",    "scopes": ["operator.read", "operator.write"],    "caps": [],    "commands": [],    "permissions": {},    "auth": { "token": "…" },    "locale": "en-US",    "userAgent": "openclaw-cli/1.2.3",    "device": {      "id": "device_fingerprint",      "publicKey": "…",      "signature": "…",      "signedAt": 1737264000000,      "nonce": "…"    }  }}

يستجيب Gateway باستخدام hello-ok:

json
{  "type": "res",  "id": "…",  "ok": true,  "payload": {    "type": "hello-ok",    "protocol": 4,    "server": { "version": "…", "connId": "…" },    "features": { "methods": ["…"], "events": ["…"] },    "snapshot": { "…": "…" },    "auth": {      "role": "operator",      "scopes": ["operator.read", "operator.write"]    },    "policy": {      "maxPayload": 26214400,      "maxBufferedBytes": 52428800,      "tickIntervalMs": 15000    }  }}

كل من server وfeatures وsnapshot وpolicy وauth مطلوب بموجب HelloOkSchema ‏(packages/gateway-protocol/src/schema/frames.ts). يُبلغ auth عن الدور والنطاقات المتفاوض عليها حتى عند عدم إصدار رمز مميز للجهاز (بالشكل الموضح أعلاه). يُعد pluginSurfaceUrls اختياريًا، ويربط أسماء أسطح Plugin (مثل canvas) بعناوين URL مستضافة ومحددة النطاق؛ وقد تنتهي صلاحيته، لذا تستدعي العُقد node.pluginSurface.refresh باستخدام { "surface": "canvas" } للحصول على إدخال جديد. مسار canvasHostUrl / canvasCapability / node.canvas.capability.refresh المهمَل غير مدعوم؛ استخدم أسطح Plugin. يمثل appliedConfigHash الاختياري في اللقطة مراجعة إعداد المصدر التي حلّها وقت تشغيل Gateway النشط وقبلها. يمكن للعملاء مقارنته مع config.get.configRevisionHash لتحديد ما إذا كان إعداد محفوظ أحدث لا يزال يتطلب إعادة تشغيل. يظل config.get.hash مراجعة ملف الجذر الخام المستخدمة بواسطة حواجز تعارض كتابة الإعداد.

بينما لا يزال Gateway يُنهي تشغيل العمليات الجانبية عند بدء التشغيل، يمكن أن يعيد connect خطأ UNAVAILABLE قابلًا لإعادة المحاولة مع details.reason: "startup-sidecars" و retryAfterMs. أعد المحاولة ضمن ميزانية اتصالك بدلًا من اعتباره فشلًا نهائيًا في المصافحة.

عند إصدار رمز مميز للجهاز، يضيفه hello-ok.auth:

json
{  "auth": {    "deviceToken": "…",    "role": "operator",    "scopes": ["operator.read", "operator.write"]  }}

يمثل التمهيد المضمّن عبر رمز QR/رمز الإعداد مسار تسليم للأجهزة المحمولة. يعيد الاتصال الأساسي الناجح باستخدام رمز الإعداد رمزًا مميزًا أساسيًا للعقدة، إضافة إلى رمز مميز واحد محدود للمشغّل:

json
{  "auth": {    "deviceToken": "…",    "role": "node",    "scopes": [],    "deviceTokens": [      {        "deviceToken": "…",        "role": "operator",        "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]      }    ]  }}

تسليم المشغّل هذا محدود عمدًا: فهو يكفي لبدء حلقة المشغّل على الجهاز المحمول والإعداد الأصلي، بما في ذلك operator.talk.secrets لقراءة إعداد Talk، لكن من دون نطاقات تعديل الاقتران ومن دون operator.admin. يتطلب الوصول الأوسع إلى الاقتران/الإدارة اقترانًا منفصلًا معتمدًا أو تدفقًا منفصلًا للرمز المميز. لا تحفظ hello-ok.auth.deviceTokens إلا عندما جرت مصادقة التمهيد عبر وسيلة نقل موثوقة (wss:// أو اقتران الاسترجاع الحلقي/المحلي).

يمكن لعملاء الواجهة الخلفية الموثوقين ضمن العملية نفسها (client.id: "gateway-client"، client.mode: "backend") حذف device في اتصالات الاسترجاع الحلقي المباشرة عند المصادقة باستخدام الرمز المميز/كلمة المرور المشتركة لـ Gateway. هذا المسار مخصص لاستدعاءات RPC الداخلية لمستوى التحكم (مثل تحديثات جلسات الوكلاء الفرعيين)، ويتجنب منع خطوط أساس اقتران CLI/الجهاز القديمة لعمل الواجهة الخلفية المحلي. أما العملاء البعيدون، والصادرون من المتصفح، والعُقد، والعملاء الذين يستخدمون صراحةً رمزًا مميزًا للجهاز/هوية الجهاز، فلا يزالون يمرون بفحوصات الاقتران وترقية النطاق المعتادة.

دور العامل والبروتوكول المغلق

يستخدم العاملون السحابيون نقطة دخول مخصصة للاسترجاع الحلقي عبر نفق SSH الذي يملكه Gateway والمثبّت بمفتاح المضيف. وهي لا تقبل إلا هوية العامل ولا توجّه مطلقًا المصادقة العامة، أو أحداث العُقد، أو استدعاءات RPC للمشغّل، أو طرق Plugin. يتحقق connect الصارم من بيانات اعتماد قصيرة العمر مخزنة كتجزئة ومرتبطة بالبيئة، وتجزئة الحزمة، وحقبة المالك، وإصدار مجموعة RPC، وانتهاء الصلاحية، وجلسة واحدة قابلة للقيمة الخالية؛ كما يتحقق بصورة منفصلة من الإصدار الحالي ومجموعة الميزات. يعيد النجاح worker-hello-ok بالحد الأدنى؛ ويكون تفاوض الميزات مستقلًا عن إصدار البروتوكول العام. تظل الإطارات دون 64 KiB، باستثناء إطار worker.inference.start المتفاوض عليه، الذي قد يصل إلى 25 MiB. تحتوي قائمة السماح المغلقة على worker.heartbeat وworker.transcript.commit وworker.live-event وworker.inference.start و worker.inference.cancel.

تستخدم عمليات تثبيت النصوص المنسوخة تسييج حقبة المالك، وربط جلسة يملكه Gateway، وعملية مقارنة ومبادلة للورقة الأساسية، وإعادة تشغيل متينة للتسلسل؛ وينشئ Gateway معرّفات إدخال النص المنسوخ والأصل من خلال كاتب الجلسة المعتاد. يُعاد التحقق من الملكية وانتهاء الصلاحية في كل استدعاء RPC.

إمكانات العميل

يمكن لعملاء المشغّل الإعلان عن إمكانات اختيارية في connect.params.caps:

  • tool-events: يقبل أحداث دورة حياة الأدوات المنظَّمة.
  • inline-widgets: يمكنه عرض نتائج أدوات عناصر واجهة مضمّنة مستضافة.

تصف إمكانات العميل العميل المتصل، وليس التخويل. قد تعلن أدوات الوكيل عن إمكانات مطلوبة؛ ويحذف Gateway تلك الأدوات ما لم يظهر كل متطلب في caps الخاص بالعميل المصدر. لا تتضمن عمليات التشغيل الصادرة من القنوات إمكانات عميل Gateway، لذا لا تتوفر الأدوات المقيّدة بالإمكانات حتى عندما تسمح بها سياسة الأدوات صراحةً.

مثال على اتصال عقدة

json
{  "type": "req",  "id": "…",  "method": "connect",  "params": {    "minProtocol": 4,    "maxProtocol": 4,    "client": {      "id": "ios-node",      "version": "1.2.3",      "platform": "ios",      "mode": "node"    },    "role": "node",    "scopes": [],    "caps": ["camera", "canvas", "screen", "location", "voice"],    "commands": ["camera.snap", "canvas.navigate", "screen.record", "location.get"],    "permissions": { "camera.capture": true, "screen.record": false },    "auth": { "token": "…" },    "locale": "en-US",    "userAgent": "openclaw-ios/1.2.3",    "device": {      "id": "device_fingerprint",      "publicKey": "…",      "signature": "…",      "signedAt": 1737264000000,      "nonce": "…"    }  }}

تعلن العُقد عن ادعاءات الإمكانات عند الاتصال:

  • caps: فئات عالية المستوى مثل camera وcanvas وscreen، وlocation وvoice وtalk.
  • commands: قائمة السماح بالأوامر للاستدعاء.
  • permissions: مفاتيح تبديل دقيقة (مثل screen.record وcamera.capture).

يتعامل Gateway مع هذه على أنها ادعاءات ويفرض قوائم السماح من جانب الخادم.

الأدوار والنطاقات

للاطلاع على نموذج نطاق المشغّل الكامل، وفحوصات وقت الموافقة، ودلالات السر المشترك، راجع نطاقات المشغّل.

الأدوار:

  • operator: عميل مستوى التحكم (CLI/واجهة المستخدم/الأتمتة).
  • node: مضيف الإمكانات (الكاميرا/الشاشة/لوحة الرسم/system.run).
  • worker: مضيف تنفيذ سحابي على بروتوكول العامل المخصص والمغلق.

نطاقات المشغّل (src/gateway/operator-scopes.ts)، وهي المجموعة المغلقة الكاملة:

  • operator.read
  • operator.write
  • operator.admin
  • operator.approvals
  • operator.pairing
  • operator.talk.secrets

يتطلب talk.config مع includeSecrets: true وجود operator.talk.secrets (أو operator.admin). عند تضمين الأسرار، اقرأ بيانات اعتماد موفّر Talk النشط من talk.resolved.config.apiKey؛ ويظل talk.providers.<id>.apiKey بشكل المصدر، وقد يكون كائن SecretRef أو سلسلة منقّحة.

قد تطلب طرق RPC الخاصة بـ Gateway والمسجّلة بواسطة Plugin نطاق المشغّل الخاص بها، لكن بادئات النواة المحجوزة التالية تُحل دائمًا إلى operator.admin (src/shared/gateway-method-policy.ts): config.* وexec.approvals.*، وwizard.* وupdate.*.

نطاق الطريقة ليس سوى البوابة الأولى. تطبّق بعض أوامر الشرطة المائلة التي يجري الوصول إليها عبر chat.send فحوصات أكثر صرامة على مستوى الأمر: تتطلب عمليات كتابة /config set و /config unset الدائمة وجود operator.admin حتى لعملاء Gateway الذين لديهم بالفعل نطاق مشغّل أدنى.

لدى node.pair.approve فحص إضافي للنطاق وقت الموافقة، علاوة على نطاق الطريقة الأساسي (operator.pairing)، استنادًا إلى commands المعلن للطلب المعلّق (src/infra/node-pairing-authz.ts):

الأوامر المعلنة النطاقات المطلوبة
لا شيء operator.pairing
أوامر عادية operator.pairing + operator.write
يتضمن system.run أو system.run.prepare أو system.which أو browser.proxy أو fs.listDir أو system.execApprovals.get/set operator.pairing + operator.admin

الإمكانات/الأوامر/الأذونات (العقدة)

تعلن العُقد عن ادعاءات الإمكانات عند الاتصال:

  • caps: فئات إمكانات عالية المستوى مثل camera وcanvas وscreen، وlocation وvoice وtalk.
  • commands: قائمة السماح بالأوامر للاستدعاء.
  • permissions: مفاتيح تبديل دقيقة (مثل screen.record وcamera.capture).

يتعامل Gateway مع هذه على أنها ادعاءات ويفرض قوائم السماح من جانب الخادم. يمكن للعُقد المتصلة نشر واصفات اختيارية لأدوات Plugin أو MCP مرئية للوكيل باستخدام node.pluginTools.update بعد نجاح الاتصال أو إعادة الاتصال. تُعاد تشغيل مضيفات العُقد عديمة الواجهة لتطبيق تغييرات مخزون MCP التعريفية. طريقة التحديث هذه هي مسار النشر الوحيد؛ ولا تُقبل واصفات أدوات Plugin ضمن معاملات connect. يجب أن يستخدم كل واصف أداة name آمنة لمزوّد الخدمة وأن يسمّي command ضمن قائمة السماح الحالية للأوامر في العقدة. يثق Gateway في بيانات الواصف الوصفية الواردة من العقدة المقترنة، ويرشّح الواصفات الواقعة خارج نطاق الأوامر المعتمد، ويزيلها عند قطع اتصال العقدة، ويرفض محاولات المشغّل لتعديل كتالوج عقدة أخرى. عيّن gateway.nodes.pluginTools.enabled: false لتجاهل الواصفات التي تنشرها العقدة.

تنشر مضيفات العُقد المتصلة كتالوج الاستبدال الكامل للمهارات لديها باستخدام node.skills.update. طريقة دور العقدة هذه هي مسار نشر مهارات العقدة الوحيد؛ ولا تُقبل المهارات ضمن معاملات connect. يحتوي كل واصف على اسم آمن ووصف ومحتوى SKILL.md محدود. يحلّل Gateway ذلك المحتوى باستخدام محمّل المهارات المعتاد، ويدرجه في لقطات مهارات الوكيل ما دامت العقدة متصلة، ويزيله عند قطع الاتصال. عيّن gateway.nodes.skills.enabled: false لتجاهل المهارات التي تنشرها العقدة.

الحضور

  • system-presence يعيد إدخالات مفهرسة حسب هوية الجهاز، بما في ذلك deviceId وroles وscopes، لكي تتمكن واجهات المستخدم من عرض صف واحد لكل جهاز حتى عندما يتصل بصفته مشغّلًا وعقدة في آن واحد.
  • node.list يتضمن lastSeenAtMs وlastSeenReason اختياريين. تُبلغ العُقد المتصلة عن وقت الاتصال الحالي بالسبب connect؛ ويمكن للعُقد المقترنة أيضًا الإبلاغ عن حضور دائم في الخلفية عبر حدث عقدة موثوق.

يمكن لعُقد macOS الأصلية أيضًا إرسال أحداث node.presence.activity موثّقة مع مدة خمول إدخال محدودة. يشتق Gateway الطوابع الزمنية للنشاط وفق ساعته الخاصة، ويعرض أحدث جهاز Mac متصل عبر node.list و node.describe، ويبث تحديثات node.presence إلى العملاء ذوي نطاق القراءة. راجع حضور الحاسوب النشط لمعرفة سلوك الاختيار والخصوصية وسياق النموذج وتوجيه الإشعارات.

حدث بقاء العقدة حية في الخلفية

تستدعي العُقد node.event باستخدام event: "node.presence.alive" لتسجيل أن عقدة مقترنة كانت حية أثناء تنبيه في الخلفية، من دون وضع علامة عليها بأنها متصلة:

json
{  "event": "node.presence.alive",  "payloadJSON": "{\"trigger\":\"silent_push\",\"sentAtMs\":1737264000000,\"displayName\":\"هاتف iPhone الخاص بـ Peter\",\"version\":\"2026.4.28\",\"platform\":\"iOS 18.4.0\",\"deviceFamily\":\"iPhone\",\"modelIdentifier\":\"iPhone17,1\",\"pushTransport\":\"relay\"}"}

trigger هو تعداد مغلق: background وsilent_push وbg_app_refresh و significant_location وmanual وconnect. تُطبّع القيم غير المعروفة إلى background ‏(src/shared/node-presence.ts). لا يُحفظ الحدث إلا لجلسات أجهزة العُقد الموثّقة؛ أما الجلسات التي لا تتضمن جهازًا أو غير المقترنة فتعيد handled: false.

تعيد بوابات Gateway الناجحة نتيجة منظّمة:

json
{  "ok": true,  "event": "node.presence.alive",  "handled": true,  "reason": "persisted"}

قد تعيد بوابات Gateway الأقدم { "ok": true } فقط من أجل node.event؛ تعامل مع ذلك بصفته إقرارًا باستدعاء RPC، وليس حفظًا دائمًا للحضور.

تحديد نطاق أحداث البث

تخضع أحداث البث التي يدفعها الخادم لنطاقات الصلاحية، بحيث لا تتلقى الجلسات المقيّدة بنطاق الاقتران أو المخصصة للعُقد فقط محتوى الجلسة بشكل سلبي (src/gateway/server-broadcast.ts):

  • تتطلب إطارات المحادثة والوكيل ونتائج الأدوات (أحداث agent المتدفقة، وأحداث نتائج الأدوات) operator.read على الأقل. تتخطى الجلسات التي لا تملكه هذه الإطارات بالكامل.
  • تُقيّد عمليات بث plugin.* المعرّفة بواسطة Plugin افتراضيًا إلى operator.write أو operator.admin؛ وتستخدم الإدخالات الصريحة مثل plugin.approval.requested / plugin.approval.resolved operator.approvals بدلًا من ذلك.
  • تظل أحداث الحالة/النقل (heartbeat وpresence وtick ودورة حياة الاتصال/قطع الاتصال) غير مقيّدة، لكي تكون صحة النقل قابلة للرصد في كل جلسة موثّقة.
  • تُقيّد عائلات أحداث البث غير المعروفة بنطاقات الصلاحية افتراضيًا (الإغلاق عند الفشل) ما لم يُرخِها معالج مسجّل صراحةً.

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

عائلات طرق RPC

hello-ok.features.methods هي قائمة اكتشاف متحفظة مبنية من src/gateway/server-methods-list.ts إضافة إلى صادرات طرق Plugin/القناة المحمّلة — وليست تفريغًا مولّدًا لكل طريقة، وبعض الطرق (مثل push.test وweb.login.start وweb.login.wait وsessions.usage) مستبعدة عمدًا من الاكتشاف مع أنها طرق حقيقية قابلة للاستدعاء. تعامل مع هذه باعتبارها وسيلة لاكتشاف الميزات، لا تعدادًا كاملًا لـ src/gateway/server-methods/*.ts.

النظام والهوية
  • health يعيد لقطة صحة Gateway المخزنة مؤقتًا أو التي جرى فحصها حديثًا.
  • diagnostics.stability يعيد مسجّل الاستقرار التشخيصي الحديث والمحدود: أسماء الأحداث وأعدادها وأحجام البايتات وقراءات الذاكرة وحالة قوائم الانتظار/الجلسات وأسماء القنوات/Plugin ومعرّفات الجلسات. لا يتضمن نصوص المحادثات أو أجسام Webhook أو مخرجات الأدوات أو أجسام الطلبات/الاستجابات الخام أو الرموز المميزة أو ملفات تعريف الارتباط أو الأسرار. يتطلب operator.read.
  • status يعيد ملخص Gateway بنمط /status؛ ولا تظهر الحقول الحساسة إلا لعملاء المشغّل ذوي نطاق المسؤول.
  • gateway.identity.get يعيد هوية جهاز Gateway المستخدمة في تدفقات الترحيل والاقتران.
  • system-presence يعيد لقطة الحضور الحالية لأجهزة المشغّل/العقدة المتصلة.
  • system-event يلحق حدثًا بالنظام ويمكنه تحديث سياق الحضور وبثه.
  • last-heartbeat يعيد أحدث حدث Heartbeat محفوظ.
  • set-heartbeats يفعّل أو يعطّل معالجة Heartbeat على Gateway.
  • gateway.suspend.prepare ينشئ عقد إيجار قصيرًا للتعليق التعاوني فقط عندما يكون عمل Gateway المتتبّع خاملًا. يتحقق gateway.suspend.status من عقد الإيجار هذا، ويحرره gateway.suspend.resume بعد استئناف التشغيل أو إحباط عملية المضيف.
النماذج والاستخدام
  • models.list يعيد كتالوج النماذج المسموح بها في وقت التشغيل. راجع طرق عرض "models.list" أدناه.
  • usage.status يعيد ملخصات نوافذ استخدام المزوّد/الحصة المتبقية.
  • usage.cost يعيد ملخصات استخدام التكلفة المجمّعة لنطاق زمني. مرّر agentId لوكيل واحد، أو agentScope: "all" لتجميع الوكلاء المضبوطين.
  • doctor.memory.status يعيد جاهزية ذاكرة المتجهات / التضمينات المخزنة مؤقتًا لمساحة عمل الوكيل الافتراضي النشط. مرّر { "probe": true } أو { "deep": true } فقط لتنفيذ اختبار اتصال مباشر وصريح بمزوّد التضمينات. مرّر { "agentId": "agent-id" } لتقييد إحصاءات مخزن Dreaming بمساحة عمل وكيل واحدة؛ ويؤدي حذفه إلى تجميع مساحات عمل Dreaming المضبوطة.
  • doctor.memory.dreamDiary وdoctor.memory.backfillDreamDiary وdoctor.memory.resetDreamDiary وdoctor.memory.resetGroundedShortTerm وdoctor.memory.repairDreamingArtifacts وdoctor.memory.dedupeDreamDiary تقبل { "agentId": "agent-id" } اختياريًا؛ وعند حذفه، تعمل على مساحة عمل الوكيل الافتراضي المضبوطة.
  • doctor.memory.remHarness يعيد معاينة محدودة وللقراءة فقط لأداة REM للعملاء البعيدين في مستوى التحكم، بما في ذلك مسارات مساحة العمل ومقتطفات الذاكرة ونصوص Markdown المؤسَّسة المعروضة ومرشحي الترقية العميقة. يتطلب operator.read.
  • sessions.usage يعيد ملخصات الاستخدام لكل جلسة. مرّر agentId لوكيل واحد، أو agentScope: "all" لسرد الوكلاء المضبوطين معًا. تقبل طريقتا الاستخدام كلتاهما mode: "specific" مع timeZone من IANA لحدود وحاويات الأيام التقويمية المدركة للتوقيت الصيفي. يظل utcOffset مدعومًا للعملاء الأقدم وكخيار احتياطي عندما لا يتعرف وقت تشغيل Gateway على المنطقة المطلوبة.
  • sessions.usage.timeseries يعيد استخدام السلسلة الزمنية لجلسة واحدة.
  • sessions.usage.logs يعيد إدخالات سجل الاستخدام لجلسة واحدة.
القنوات ومساعدات تسجيل الدخول
  • channels.status يعيد ملخصات حالة القنوات/Plugin المدمجة والمضمّنة.
  • channels.logout يسجّل خروج قناة/حساب محدد عندما تدعم القناة ذلك.
  • web.login.start يبدأ تدفق تسجيل دخول عبر QR/الويب لمزوّد قناة الويب الحالي القادر على استخدام QR.
  • web.login.wait ينتظر اكتمال ذلك التدفق ويبدأ القناة عند النجاح.
  • push.test يرسل إشعار APNs اختباريًا إلى عقدة iOS مسجّلة.
  • voicewake.get يعيد مشغّلات كلمات التنبيه المخزنة.
  • voicewake.set يحدّث مشغّلات كلمات التنبيه ويبث التغيير.
إدارة Plugin
  • plugins.list ‏(operator.read) يعيد مخزون Plugin المثبّت إضافة إلى الاختيارات الرسمية المنتقاة محليًا والتشخيصات وما إذا كان وضع التثبيت الحالي يسمح بالتعديلات.
  • plugins.search ‏(operator.read) يبحث في عائلات Plugin البرمجية وPlugin الحزم القابلة للتثبيت من ClawHub. مرّر query غير فارغ وlimit اختياريًا من 1 إلى 100.
  • plugins.install ‏(operator.admin) يثبّت إما إدخالًا من الكتالوج الرسمي باستخدام { source: "official", pluginId } أو حزمة ClawHub باستخدام { source: "clawhub", packageName, version?, acknowledgeClawHubRisk? }. تحافظ عمليات تثبيت ClawHub على فحوص الثقة والتكامل وسياسة التثبيت الخاصة بـ Gateway. تتطلب عمليات التثبيت الناجحة إعادة تشغيل Gateway.
  • plugins.setEnabled ‏(operator.admin) يغيّر سياسة التمكين لـ Plugin واحد مثبّت باستخدام { pluginId, enabled }. تتضمن الاستجابة إدخال الكتالوج المحدّث وبيانات إعادة التشغيل الوصفية وأي تحذيرات بشأن اختيار الفتحة.
  • plugins.uninstall ‏(operator.admin) يزيل Plugin واحدًا مثبّتًا خارجيًا باستخدام { pluginId }: مراجع الإعداد وسجل التثبيت والملفات المُدارة. لا يمكن إلغاء تثبيت Plugin المضمّنة، بل يمكن تعطيلها فقط. تسرد الاستجابة إجراءات الإزالة وتتطلب دائمًا إعادة تشغيل Gateway.
المراسلة والسجلات
  • send هو RPC التسليم الصادر المباشر للإرسال الموجّه إلى قناة/حساب/سلسلة محادثة خارج مشغّل المحادثة.
  • logs.tail يعيد ذيل سجل ملفات Gateway المضبوط مع عناصر تحكم في المؤشر/الحد والحد الأقصى للبايتات.
طرفية المشغّل
  • terminal.open يبدأ PTY على المضيف لصالح agentId محدد أو الوكيل الافتراضي، ويعيد الوكيل الذي جرى حله، ودليل العمل، والصدفة، وحالة العزل.
  • terminal.input وterminal.resize وterminal.close تعمل فقط على الجلسات المملوكة للاتصال المستدعي.
  • terminal.upload يقبل ملفًا واحدًا بترميز base64 يصل حجمه إلى 16 MiB، ويضعه مؤقتًا في دليل خاص لمدة 24 ساعة على Gateway الخاص بالجلسة أو مضيف العقدة المقترنة، ويعيد المسار المطلق. يظل على المستدعي لصق ذلك المسار أو استخدامه بطريقة أخرى؛ فلا يكتب RPC أبدًا إدخالًا إلى الطرفية ولا ينفّذ أمرًا.
  • تُبث أحداث terminal.data وterminal.exit فقط إلى الاتصال الذي يملك الجلسة.
  • تُفصل الجلسات التي ينقطع اتصالها بدلًا من إنهائها: وتظل قابلة لإعادة الاتصال لمدة gateway.terminal.detachedSessionTimeoutSeconds (القيمة الافتراضية 300؛ ويعيد 0 سلوك الإنهاء عند انقطاع الاتصال)، بينما يتراكم الإخراج الحديث في مخزن مؤقت محدود على جانب الخادم.
  • terminal.list يعيد الجلسات القابلة للاتصال؛ ويعيد terminal.attach ربط جلسة نشطة أو مفصولة بالاتصال المستدعي ويعيد مخزن إعادة التشغيل المؤقت (استحواذ بأسلوب tmux — يتلقى المالك النشط السابق terminal.exit بالسبب detached)؛ ويقرأ terminal.text المخزن المؤقت كنص عادي من دون اتصال.
  • تتطلب كل طريقة طرفية operator.admin؛ ويجب أن تكون gateway.terminal.enabled مضبوطة صراحةً على true. تُرفض الوكلاء المعزولة بالكامل، ويؤدي تغيير سياسة الوكيل إلى إغلاق جلسات PTY الحالية وقيد التنفيذ، بما فيها الجلسات المفصولة.
المحادثة وتحويل النص إلى كلام
  • talk.catalog يعيد كتالوج موفّري المحادثة للقراءة فقط للكلام، والنسخ المتدفق، والصوت في الوقت الفعلي: معرّفات الموفّرين الأساسية، وأسماء السجل البديلة، والتسميات، وحالة التهيئة، ونتيجة ready اختيارية على مستوى المجموعة، ومعرّفات النماذج/الأصوات المكشوفة، والأوضاع الأساسية، ووسائط النقل، واستراتيجيات العقل، وعلامات الصوت/الإمكانات في الوقت الفعلي، من دون إعادة أسرار الموفّر أو تعديل الإعداد العام. تضبط بوابات Gateway الحالية ready بعد تطبيق اختيار الموفّر في وقت التشغيل؛ ويُعد غيابه غير متحقق منه في بوابات Gateway الأقدم.
  • talk.config يعيد حمولة إعداد المحادثة الفعلية؛ ويتطلب includeSecrets وجود operator.talk.secrets (أو operator.admin).
  • talk.session.create ينشئ جلسة محادثة مملوكة لـ Gateway من أجل realtime/gateway-relay أو transcription/gateway-relay أو stt-tts/managed-room. بالنسبة إلى stt-tts/managed-room، يجب على مستدعي operator.write الذين يمررون sessionKey تمرير spawnedBy أيضًا لإتاحة مفتاح الجلسة ضمن النطاق؛ ويتطلب إنشاء sessionKey غير المقيّد بنطاق وbrain: "direct-tools" وجود operator.admin.
  • talk.session.join يتحقق من رمز جلسة غرفة مُدارة، ويصدر session.ready أو session.replaced حسب الحاجة، ويعيد بيانات الغرفة/الجلسة الوصفية مع أحداث المحادثة الحديثة، ولا يعيد أبدًا الرمز بنص صريح أو قيمة تجزئته.
  • talk.session.appendAudio يلحق صوت إدخال PCM بترميز base64 بجلسات الترحيل والنسخ في الوقت الفعلي المملوكة لـ Gateway.
  • talk.session.startTurn وtalk.session.endTurn وtalk.session.cancelTurn تدير دورة حياة دور الغرفة المُدارة مع رفض الأدوار القديمة قبل مسح الحالة.
  • talk.session.cancelOutput يوقف إخراج صوت المساعد، أساسًا للمقاطعة الخاضعة لـ VAD في جلسات ترحيل Gateway.
  • talk.session.submitToolResult يُكمل استدعاء أداة من الموفّر صادرًا عن جلسة ترحيل في الوقت الفعلي مملوكة لـ Gateway. ينتظر الطلب أي إشارة إكمال غير متزامنة يكشفها جسر الموفّر؛ وتُبقي عمليات الإرسال الفاشلة التشغيل المرتبط نشطًا ولا تصدر حدث نتيجة أداة ناجحًا. مرّر options: { willContinue: true } لإخراج الأداة المرحلي، أو options: { suppressResponse: true } عندما يعلن جسر الموفّر دعم الكبت وينبغي ألا تبدأ النتيجة استجابة أخرى.
  • talk.session.steer يرسل تحكمًا صوتيًا في التشغيل النشط إلى جلسة محادثة مدعومة بوكيل ومملوكة لـ Gateway: { sessionId, text, mode? }، حيث تكون mode إحدى status أو steer أو cancel أو followup؛ ويُصنّف الوضع المحذوف من النص المنطوق.
  • talk.session.close يغلق جلسة ترحيل أو نسخ أو غرفة مُدارة مملوكة لـ Gateway، ويصدر أحداث المحادثة النهائية.
  • talk.mode يضبط/يبث حالة وضع المحادثة الحالية لعملاء WebChat/واجهة التحكم.
  • talk.client.create ينشئ جلسة موفّر في الوقت الفعلي مملوكة للعميل باستخدام webrtc أو provider-websocket، بينما يملك Gateway الإعداد وبيانات الاعتماد والتعليمات وسياسة الأدوات.
  • talk.client.toolCall يتيح لوسائط النقل في الوقت الفعلي المملوكة للعميل تمرير استدعاءات أدوات الموفّر إلى سياسة Gateway. الأداة الأولى المدعومة هي openclaw_agent_consult؛ ويحصل العملاء على معرّف تشغيل وينتظرون أحداث دورة حياة الدردشة المعتادة قبل إرسال نتيجة الأداة الخاصة بالموفّر.
  • talk.client.steer يرسل تحكمًا صوتيًا في التشغيل النشط لوسائط النقل في الوقت الفعلي المملوكة للعميل. يحل Gateway التشغيل المضمن النشط من sessionKey ويعيد نتيجة قبول/رفض منظّمة بدلًا من إسقاط التوجيه بصمت.
  • talk.event هي قناة أحداث المحادثة الوحيدة لمحولات الوقت الفعلي، والنسخ، وSTT/TTS، والغرف المُدارة، والاتصالات الهاتفية، والاجتماعات.
  • talk.speak يولّد الكلام عبر موفّر كلام المحادثة النشط.
  • tts.status يعيد حالة تمكين TTS، والموفّر النشط، والموفّرين الاحتياطيين، وحالة إعداد الموفّر.
  • tts.providers يعيد مخزون موفّري TTS المرئي.
  • tts.enable وtts.disable يبدّلان حالة تفضيلات TTS.
  • tts.setProvider يحدّث موفّر TTS المفضّل.
  • tts.convert يشغّل تحويلًا لمرة واحدة من النص إلى كلام.
  • tts.speak ‏(operator.write) يعالج text غير الفارغ باستخدام سلسلة موفّري TTS العامة المُعدّة، ويعيد مقطعًا كاملًا واحدًا مضمّنًا بصفته audioBase64، بالإضافة إلى provider وبيانات outputFormat وmimeType وfileExtension الوصفية الاختيارية. بخلاف tts.convert، لا يعيد مسارًا محليًا لـ Gateway؛ وبخلاف talk.speak، لا يتطلب موفّر محادثة. يعيد النص الذي يتجاوز messages.tts.maxTextLength القيمة INVALID_REQUEST؛ وتعيد حالات فشل التوليد UNAVAILABLE.
الأسرار والإعداد والتحديث والمعالج
  • secrets.reload يعيد حل SecretRefs النشطة ويستبدل حالة الأسرار في وقت التشغيل فقط عند النجاح الكامل.
  • secrets.resolve يحل تعيينات الأسرار لأهداف الأوامر لمجموعة أوامر/أهداف محددة.
  • config.get يعيد لقطة الإعداد الحالية على القرص، وhash لملف الجذر الخام، وconfigRevisionHash الذي جرى حله، وappliedConfigHash اختياريًا للمراجعة المحلولة التي قبلها وقت تشغيل Gateway النشط.
  • config.set يكتب حمولة إعداد تم التحقق من صحتها.
  • config.patch يدمج تحديث إعداد جزئيًا. يتطلب الاستبدال الإتلافي للمصفوفة إدراج المسار المتأثر في replacePaths؛ وتستخدم المصفوفات المتداخلة ضمن إدخالات المصفوفة مسارات [] مثل agents.list[].skills.
  • config.apply يتحقق من حمولة الإعداد الكاملة ويستبدلها.
  • config.schema يعيد حمولة مخطط الإعداد الحي التي تستخدمها واجهة التحكم وأدوات CLI: المخطط، وuiHints، والإصدار، وبيانات التوليد الوصفية، وبيانات مخطط Plugin والقناة الوصفية عندما يمكن تحميلها. ويتضمن بيانات title / description الوصفية من التسميات/نص المساعدة نفسها المستخدمة في واجهة المستخدم، بما في ذلك فروع تركيب الكائنات المتداخلة، وأحرف البدل، وعناصر المصفوفة، وanyOf / oneOf / allOf عند وجود وثائق مطابقة للحقل.
  • config.schema.lookup يعيد حمولة بحث مقيّدة بمسار لمسار إعداد واحد: المسار المطبع، وعقدة مخطط سطحية، والتلميح المطابق مع hintPath، وreloadKind اختياريًا، وملخصات الأبناء المباشرين للتعمق عبر واجهة المستخدم/CLI. تكون reloadKind إحدى restart أو hot أو none ‏(src/config/schema.ts)، وتحاكي مخطط إعادة تحميل إعداد Gateway للمسار المطلوب. تحتفظ عقد مخطط البحث بالوثائق الموجّهة للمستخدم وحقول التحقق الشائعة (title، وdescription، وtype، وenum، وconst، وformat، وpattern، وحدود الأرقام/السلاسل/المصفوفات/الكائنات، وadditionalProperties، وdeprecated، وreadOnly، وwriteOnly). تكشف ملخصات الأبناء key، وpath المطبّع، وtype، وrequired، وhasChildren، وreloadKind اختياريًا، بالإضافة إلى hint / hintPath المطابقين.
  • update.run يشغّل تدفق تحديث Gateway ويجدول إعادة التشغيل فقط إذا نجح التحديث؛ ويمكن للمستدعين الذين لديهم جلسة تضمين continuationMessage كي يستأنف بدء التشغيل دور وكيل متابعة واحدًا عبر قائمة انتظار متابعة إعادة التشغيل. تستخدم تحديثات مدير الحزم وتحديثات نسخة git الخاضعة للإشراف من مستوى التحكم تسليمًا منفصلًا إلى خدمة مُدارة بدلًا من استبدال شجرة الحزمة أو تعديل مخرجات نسخة العمل/البناء داخل Gateway النشط. يعيد التسليم الذي بدأ ok: true مع result.reason: "managed-service-handoff-started" وhandoff.status: "started"؛ وتعيد عمليات التسليم غير المتاحة أو الفاشلة ok: false مع managed-service-handoff-unavailable أو managed-service-handoff-failed، بالإضافة إلى handoff.command عندما يلزم تحديث يدوي عبر الصدفة. تعني «غير متاح» أن OpenClaw يفتقر إلى حد آمن للمشرف أو هوية خدمة دائمة، مثل OPENCLAW_SYSTEMD_UNIT في systemd. أثناء تسليم بدأ بالفعل، قد يبلغ مؤشر إعادة التشغيل لفترة وجيزة عن stats.reason: "restart-health-pending"؛ وتُؤخر المتابعة حتى يتحقق CLI من Gateway المعاد تشغيله ويكتب مؤشر ok النهائي.
  • update.status يحدّث أحدث مؤشر لإعادة تشغيل التحديث ويعيده، بما في ذلك الإصدار الجاري بعد إعادة التشغيل عند توفره.
  • wizard.start وwizard.next وwizard.status وwizard.cancel تكشف معالج الإعداد الأولي عبر WS RPC.
مساعدات الوكيل ومساحة العمل
  • agents.list يعيد إدخالات الوكلاء المهيأة، بما فيها بيانات النموذج وبيئة التشغيل الفعلية.
  • agents.create وagents.update وagents.delete تدير سجلات الوكلاء وربط مساحة العمل.
  • agents.files.list وagents.files.get وagents.files.set تدير ملفات مساحة عمل التمهيد المتاحة للوكيل.
  • audit.activity.list يعيد سجل النشاط ذي الإصدارات والمقتصر على البيانات الوصفية؛ ويظل audit.list هو RPC الآمن من حيث التوافق للتشغيل/الأداة.
  • agents.workspace.list وagents.workspace.get ‏(operator.read) يتيحان تصفحًا للقراءة فقط ومقسّمًا إلى صفحات لدليل مساحة عمل الوكيل، للعملاء ضمن نطاق المشغّل الموثوق الموضح في نطاقات المشغّل. لا تقبل الطلبات إلا المسارات النسبية إلى مساحة العمل؛ وتظل عمليات القراءة محصورة في جذر مساحة العمل بعد حل مساره الحقيقي (مع رفض محاولات الإفلات عبر الروابط الرمزية والروابط الصلبة)، ومقيدة بالحجم، ومقتصرة على نص UTF-8 وأنواع الصور الشائعة (base64). لا تكشف الاستجابات مسار مساحة العمل على المضيف. لا توجد عمليات كتابة في نطاق الأسماء هذا.
  • tasks.list وtasks.get وtasks.cancel تتيح سجل مهام Gateway لعملاء SDK والمشغّل. راجع واجهات RPC لسجل المهام أدناه.
  • artifacts.list وartifacts.get وartifacts.download تتيح ملخصات العناصر المستمدة من السجل النصي وتنزيلاتها ضمن نطاق صريح من نوع sessionKey أو runId أو taskId. تستخرج استعلامات التشغيل والمهام الجلسة المالكة على جانب الخادم، ولا تعيد إلا وسائط السجل النصي ذات المصدر المطابق؛ وتعيد مصادر URL غير الآمنة أو المحلية تنزيلات غير مدعومة بدلًا من جلبها على جانب الخادم.
  • environments.list وenvironments.status تحافظان على اكتشاف بيئة Gateway المحلية وبيئة Node. تضيف عُقد العمل السحابية المهيأة والسجلات الدائمة التي تركتها ملفات التعريف السابقة بيانات worker الوصفية مع providerId وleaseId الاختياري وstate وageMs وidleMs الاختياري وattachedSessionIds. حالات دورة حياة عقدة العمل هي requested وprovisioning وbootstrapping وready وattached وidle وdraining وdestroying وdestroyed وfailed وorphaned.
  • environments.create ‏({ profileId, idempotencyKey }) يوفّر عقدة عمل من ملف تعريف موفّر مهيأ في Plugin؛ وتعيد المحاولات بالمفتاح نفسه استخدام العملية الدائمة. ويطلب environments.destroy ‏({ environmentId }) إزالة متكررة آمنة لبيئة عقدة عمل دائمة. يتطلب كلاهما operator.admin، وهما عمليتا كتابة في مستوى التحكم، ويعيدان بنية ملخص البيئة نفسها المستخدمة في استجابات الحالة.
  • agent.identity.get يعيد هوية المساعد الفعلية لوكيل أو جلسة.
  • agent.wait ينتظر انتهاء تشغيل ويعيد اللقطة النهائية عند توفرها.
التحكم في الجلسة
  • sessions.list يعيد فهرس الجلسات الحالي، بما في ذلك بيانات agentRuntime الوصفية لكل صف عند تهيئة واجهة خلفية لبيئة تشغيل الوكيل. وعند تمكين توزيع عُقد العمل السحابية أو وجود حالة استرداد دائمة، تتضمن صفوف الجلسات أيضًا حالة placement مغلقة (local أو requested أو provisioning أو syncing أو starting أو active أو draining أو reconciling أو reclaimed أو failed) بالإضافة إلى حقول البيئة أو حقبة المالك أو مساحة العمل أو الحزمة أو مؤشر ACK أو الاسترداد الخاصة بالحالة.
  • sessions.subscribe وsessions.unsubscribe تبدّلان اشتراكات أحداث تغييرات الجلسة لعميل WS الحالي.
  • sessions.messages.subscribe وsessions.messages.unsubscribe تبدّلان اشتراكات أحداث السجل النصي/الرسائل لجلسة واحدة. مرّر includeApprovals: true لتلقي أحداث دورة حياة session.approval المنقّحة أيضًا، وذلك للموافقات التي يتضمن جمهورها المحفوظ تلك الجلسة تحديدًا والتي يصرّح ربط المراجع فيها للعميل المشترك. تتضمن استجابة الاشتراك حينئذٍ قائمة approvalReplay معلّقة ومحدودة؛ وتكون موثوقة عندما تكون truncated بالقيمة false. يكون الاشتراك الاختياري خاصًا بكل استدعاء اشتراك وليس دائمًا: تؤدي إعادة الاشتراك في الجلسة نفسها دون includeApprovals: true إلى إزالة اشتراك موافقات قائم. بالإضافة إلى صلاحية قراءة الجلسة العادية، يتطلب هذا الاشتراك الاختياري operator.admin، أو operator.approvals على جهاز مقترن.
  • sessions.preview يعيد معاينات محدودة للسجل النصي لمفاتيح جلسات محددة.
  • sessions.describe يعيد صف جلسة واحدًا من Gateway لمفتاح جلسة مطابق تمامًا.
  • sessions.resolve يستخرج هدف جلسة أو يحوّله إلى صيغته القياسية.
  • sessions.create ينشئ إدخال جلسة جديدًا. تحفظ قيمتا model وthinkingLevel الاختياريتان تجاوزات النموذج والاستدلال الأولية ذريًا. يوفّر worktree: true شجرة عمل مُدارة؛ ويحدّد worktreeBaseRef/worktreeName الاختياريان المرجع الأساسي واسم الفرع، ويربط execNode ‏(operator.admin) تنفيذ الجلسة بمضيف Node. تُعاد شجرة العمل المنشأة في النتيجة وتُحفظ في صف الجلسة (worktree: { id, branch, repoRoot }). عندما يُنشأ الإدخال لكن يُرفض chat.send الأولي المتداخل، تتضمن النتيجة الناجحة runStarted: false وrunError؛ ويمكن للعملاء الاحتفاظ بالموجّه وإعادة المحاولة باستخدام مفتاح الجلسة المُعاد.
  • sessions.dispatch ‏(operator.admin) ينقل جلسة OpenClaw محلية قائمة ذات شجرة عمل مُدارة تملكها الجلسة إلى ملف تعريف مهيأ لعقدة عمل سحابية. مرّر { key, profileId, agentId? }. لا تكون الطريقة موجودة عند عدم تهيئة أي ملف تعريف لعقدة العمل، وتغلق قبول الأدوار المحلية قبل تصريف العمل النشط، ولا تعود إلا بعد أن يصل التوزيع إلى ملكية عقدة العمل active. الإرسال أحادي الاتجاه؛ ولا يشمل RPC هذا السحب من عقدة العمل إلى البيئة المحلية.
  • sessions.groups.list وsessions.groups.put وsessions.groups.rename وsessions.groups.delete تدير دليل مجموعات الجلسات المخصصة الذي يملكه Gateway (الأسماء + ترتيب العرض). تظل العضوية في حقل category لكل جلسة؛ ويؤدي تغيير الاسم والحذف إلى تحديث الجلسات الأعضاء على جانب الخادم.
  • sessions.send يرسل رسالة إلى جلسة قائمة.
  • sessions.steer هو البديل الذي يقاطع جلسة نشطة ويوجّهها.
  • sessions.abort يجهض العمل النشط لجلسة. مرّر key مع runId الاختياري، أو runId وحده لعمليات التشغيل النشطة التي يستطيع Gateway ربطها بجلسة.
  • sessions.patch يحدّث بيانات الجلسة الوصفية/تجاوزاتها ويبلّغ عن النموذج القياسي المستخرج بالإضافة إلى agentRuntime الفعلي.
  • sessions.reset وsessions.delete وsessions.compact تنفّذ صيانة الجلسة.
  • sessions.get يعيد صف الجلسة المحفوظ كاملًا.
  • لا يزال تنفيذ الدردشة يستخدم chat.history وchat.send وchat.abort وchat.inject. يُطبّع chat.history لأغراض العرض لعملاء واجهة المستخدم: تُزال وسوم التوجيه المضمّنة من النص المرئي، وتُزال حمولات XML النصية العادية لاستدعاءات الأدوات (<tool_call>...</tool_call> و<function_call>...</function_call> و<tool_calls>...</tool_calls> و<function_calls>...</function_calls> وكتل استدعاء الأدوات المبتورة) ورموز تحكم النموذج المسرّبة بصيغة ASCII/العرض الكامل، وتُحذف صفوف المساعد التي لا تحتوي إلا على رمز صامت (المطابق تمامًا لـ NO_REPLY / no_reply) ويمكن استبدال الصفوف كبيرة الحجم بعناصر نائبة.
  • chat.message.get هو قارئ الرسالة الكاملة المحدود والإضافي لإدخال مرئي واحد في السجل النصي. مرّر sessionKey وagentId الاختياري عندما يكون اختيار الجلسة ضمن نطاق الوكيل، ومعرّف السجل النصي messageId الذي سبق إظهاره عبر chat.history؛ ويعيد Gateway الإسقاط نفسه المطبّع للعرض من دون حد البتر الخاص بالسجل المختصر، ما دام الإدخال المحفوظ متاحًا وغير كبير الحجم.
  • chat.toolTitles يعيد عناوين قصيرة لأغراض استدعاءات الأدوات المعروضة في واجهة التحكم (على دفعات، بحد أقصى 24 عنصرًا مع مدخلات محدودة). تُفعّل الميزة اختياريًا عبر gateway.controlUi.toolTitles (معطّلة افتراضيًا)؛ وتجيب بوابات Gateway المعطّلة عن { titles: {}, disabled: true } من دون استدعاء للنموذج كي يتوقف العملاء عن الطلب. عند تمكينها، تستخدم العناوين توجيه نموذج الأدوات المساعدة القياسي: إما utilityModel مهيأ صراحةً (وهو قرار للمشغّل قد يرسل، مثل جميع مهام الأدوات المساعدة، محتوى مهمة محدودًا إلى الموفّر المختار)، وإلا فالنموذج الصغير الافتراضي المعلن لموفّر الجلسة، بحيث لا تظهر وجهة خروج جديدة ضمنيًا؛ ويؤدي utilityModel الفارغ إلى تعطيلها بالكامل. لا تعود العناوين أبدًا إلى النموذج الأساسي. تُخزّن النتائج مؤقتًا في قاعدة بيانات الحالة الخاصة بكل وكيل، بمفتاح يتكون من اسم الأداة + المدخلات، لذلك لا تعيد المشاهدات المتكررة احتساب تكلفة الاستدعاءات نفسها.
  • chat.send يقبل fastMode: "auto" لدور واحد لاستخدام الوضع السريع لاستدعاءات النموذج التي تبدأ قبل حد الإيقاف التلقائي، ثم بدء محاولات إعادة لاحقة أو استدعاءات احتياطية أو نتائج أدوات أو استدعاءات متابعة من دون الوضع السريع. القيمة الافتراضية للحد هي 60 ثانية (DEFAULT_FAST_MODE_AUTO_ON_SECONDS) ويمكن تهيئتها لكل نموذج باستخدام agents.defaults.models["<provider>/<model>"].params.fastAutoOnSeconds. يمكن لمستدعٍ من نوع chat.send تمرير fastAutoOnSeconds لدور واحد لتجاوز الحد لذلك الطلب. مرّر queueMode ‏(steer أو followup أو collect أو interrupt) لتجاوز وضع قائمة الانتظار المحفوظ لهذا الطلب فقط؛ وتستخدم إجراءات التوجيه الصريحة في واجهة التحكم queueMode: "steer".
إقران الأجهزة ورموزها المميزة
  • device.pair.list يعيد الأجهزة المقترنة المعلّقة والموافق عليها.
  • device.pair.setupCode ينشئ رمز إعداد للهاتف المحمول، وعنوان URL لبيانات رمز QR بصيغة PNG افتراضيًا. يتطلب operator.admin ويُحذف عمدًا من الاكتشاف المُعلن. تتضمن النتيجة setupCode وqrDataUrl الاختياري وgatewayUrl والتسمية غير السرية auth وurlSource.
  • device.pair.approve وdevice.pair.reject وdevice.pair.remove تدير سجلات إقران الأجهزة.
  • device.pair.rename يعيّن تسمية للمشغّل ({ deviceId, label }) تُفضّل على اسم العرض الذي يبلّغ عنه العميل، وتستمر بعد إصلاح الجهاز أو إعادة الموافقة عليه.
  • device.token.rotate يدوّر الرمز المميز لجهاز مقترن ضمن حدود دوره المعتمد ونطاق المستدعي.
  • device.token.revoke يلغي الرمز المميز لجهاز مقترن ضمن حدود دوره المعتمد ونطاق المستدعي.

يتضمن رمز الإعداد بيانات اعتماد تمهيدية قصيرة العمر. يجب ألا يسجّلها العملاء أو يحتفظوا بها بعد انتهاء تدفق الإقران.

إقران Node والاستدعاء والعمل المعلّق
  • node.pair.list وnode.pair.approve وnode.pair.reject وnode.pair.remove تغطي الموافقات على إمكانات Node. أُزيلت node.pair.request وnode.pair.verify في 2026.7 مع مخزن إقران Node المستقل؛ وينشئ Gateway الطلبات المعلّقة أثناء اتصالات Node.
  • node.list وnode.describe تعيدان حالة Node المعروفة/المتصلة.
  • node.rename تحدّث تسمية Node مقترنة.
  • node.invoke تمرّر أمرًا إلى Node متصلة.
  • node.invoke.result تعيد نتيجة طلب استدعاء.
  • mcp.tools.call.v1 هي أمر مضيف Node غير المزود بواجهة رسومية لاستدعاء أداة MCP محلية في Node تم تكوينها. تُنقل عبر node.invoke، وتتطلب من Node التصريح بالأمر، وتظل خاضعة لموافقة الإقران وgateway.nodes.denyCommands.
  • node.event تنقل الأحداث الصادرة من Node إلى Gateway.
  • node.pluginTools.update هي مسار النشر الوحيد لاستبدال واصفات أدوات Plugin/MCP المرئية للوكيل في Node المتصلة؛ ولا تحملها معاملات connect.
  • node.pending.pull وnode.pending.ack هما واجهتا API لطابور Node المتصلة.
  • node.pending.enqueue وnode.pending.drain تديران العمل المعلّق الدائم لعُقد Node غير المتصلة بالشبكة/المنفصلة.
عائلات الموافقات
  • approval.get وapproval.resolve هما طريقتا الموافقة الدائمتان غير المقيّدتين بنوع (النطاق operator.approvals). تعيد approval.get إسقاطًا منقحًا معلّقًا أو نهائيًا محتفظًا به مع urlPath ثابت؛ وتقبل approval.resolve معرّف الموافقة الأساسي وkind صريحًا وقرارًا، وتطبّق حسم أسبقية الإجابة الأولى، وتعيد دائمًا النتيجة الأساسية المسجّلة.
  • exec.approval.request وexec.approval.get وexec.approval.list وexec.approval.resolve تغطي طلبات موافقة التنفيذ لمرة واحدة، إضافة إلى البحث عن الموافقات المعلّقة وإعادة تشغيلها. وهي محوّلات عند حدود البروتوكول فوق سجل الموافقات الدائم نفسه.
  • exec.approval.waitDecision تنتظر موافقة تنفيذ معلّقة واحدة وتعيد القرار النهائي (أو null عند انتهاء المهلة).
  • exec.approvals.get وexec.approvals.set تديران لقطات سياسة موافقة التنفيذ في Gateway.
  • exec.approvals.node.get وexec.approvals.node.set تديران سياسة موافقة التنفيذ المحلية في Node عبر أوامر ترحيل Node.
  • plugin.approval.request وplugin.approval.list وplugin.approval.waitDecision وplugin.approval.resolve تغطي تدفقات الموافقة التي يعرّفها Plugin.
الأتمتة وSkills والأدوات
  • الأتمتة: تجدول wake حقن نص إيقاظ فوري أو عند Heartbeat التالية؛ وتدير cron.get وcron.list وcron.status وcron.add وcron.update وcron.remove وcron.run وcron.runs العمل المجدول.
  • cron.run تظل RPC بأسلوب الإضافة إلى الطابور لعمليات التشغيل اليدوية. ينبغي للعملاء الذين يحتاجون إلى دلالات الاكتمال قراءة runId المُعاد واستقصاء cron.runs.
  • cron.runs تقبل مرشح runId اختياريًا غير فارغ حتى يتمكن العملاء من تتبع تشغيل يدوي واحد موضوع في الطابور دون التسابق مع إدخالات السجل الأخرى للمهمة نفسها.
  • Skills والأدوات: commands.list وskills.* وtools.catalog وtools.effective وtools.invoke. راجع طرائق مساعدة المشغّل أدناه.

عائلات الأحداث الشائعة

  • chat: تحديثات دردشة واجهة المستخدم مثل chat.inject وغيرها من أحداث الدردشة الخاصة بالنص المسجّل فقط. في البروتوكول v4، تحمل حمولات الفروقات deltaText؛ وتظل message اللقطة التراكمية للمساعد. تضبط الاستبدالات التي ليست بادئة replace=true وتستخدم deltaText كنص بديل.
  • session.message وsession.operation وsession.tool: تحديثات النص المسجّل وعملية الجلسة الجارية وتدفق الأحداث لجلسة مشترَك فيها.
  • session.approval: الحقيقة المنقحة للموافقات المعلّقة والنهائية لمشترك في الجلسة الدقيقة اختار الاشتراك صراحةً. تستخدم الموافقات الفرعية جمهور السلف المحفوظ؛ ولا تعدّل الأحداث النصوص المسجّلة ولا توقظ الوكلاء أبدًا.
  • sessions.changed: تغيّر فهرس الجلسة أو بياناتها الوصفية.
  • presence: تحديثات لقطة حضور النظام.
  • tick: حدث دوري لإبقاء الاتصال/إثبات النشاط.
  • health: تحديث لقطة صحة Gateway.
  • heartbeat: تحديث تدفق أحداث Heartbeat.
  • cron: حدث تغيير تشغيل/مهمة Cron.
  • shutdown: إشعار إيقاف تشغيل Gateway.
  • node.pair.requested / node.pair.resolved: دورة حياة إقران Node.
  • node.invoke.request: بث طلب استدعاء Node.
  • device.pair.requested / device.pair.resolved: دورة حياة الجهاز المقترن.
  • voicewake.changed: تغيّر تكوين مشغّل كلمة الإيقاظ.
  • exec.approval.requested / exec.approval.resolved: دورة حياة موافقة التنفيذ.
  • plugin.approval.requested / plugin.approval.resolved: دورة حياة موافقة Plugin.

طرائق مساعدة Node

يمكن لعُقد Node استدعاء skills.bins لجلب القائمة الحالية لملفات Skills التنفيذية من أجل عمليات التحقق من السماح التلقائي.

RPC لدفتر التدقيق

تمنح audit.activity.list عملاء المشغّلين عرضًا ثابتًا مرتبًا من الأحدث إلى الأقدم للبيانات الوصفية لدورة حياة تشغيل الوكيل وإجراء الأداة والرسالة المشترَك فيها اختياريًا. وتتطلب operator.read. تستبعد الاستعلامات السجلات الأقدم من 30 يومًا، ويقتصر دفتر SQLite المشترك على 100,000 سجل. تُحذف الصفوف المنتهية الصلاحية أثناء بدء تشغيل Gateway والصيانة كل ساعة وعمليات الكتابة اللاحقة. راجع سجل التدقيق لمعرفة نموذج البيانات ودلالات الخصوصية.

  • المعاملات: agentId أو sessionKey أو runId مطابق تمامًا اختياري؛ وkind اختياري ("agent_run" أو "tool_action" أو "message")؛ وstatus اختياري ("started" أو "succeeded" أو "failed" أو "cancelled" أو "timed_out" أو "blocked" أو "unknown")؛ وdirection للرسالة اختياري ("inbound" أو "outbound") وchannel مطابق تمامًا؛ وحدود after / before الشاملة الاختيارية بالميلي ثانية وفق Unix؛ وlimit اختياري من 1 إلى 500؛ و cursor نصي اختياري من الصفحة السابقة.
  • النتيجة: { "events": AuditActivityEventV1[], "nextCursor"?: string }.

يتضمن اتحاد نتائج V1 المسمّى مخططات منفصلة لتشغيل الوكيل وإجراء الأداة والرسالة الواردة والرسالة الصادرة. مميّز eventType هو على الترتيب agent_run أو tool_action أو inbound_message أو outbound_message؛ ويظل kind وdirection للرسالة متاحين للتصفية والعرض. لكل حدث schemaVersion: 1 صحيح. تستخدم مراجع هوية الرسالة تنسيق hmac-sha256:v1:<32 hex key id>:<64 hex digest> المطابق تمامًا؛ ويستخدم معرّف جهة فاعلة مرسلة عبر القناة التنسيق نفسه.

تتطلب جميع المتغيرات eventType وschemaVersion وeventId وsequence وsourceSequence وoccurredAt وkind وaction وstatus وactor وredaction. حقول المتغيرات هي:

eventType الحقول المطلوبة الحقول الاختيارية
agent_run agentId، runId؛ kind: "agent_run" sessionKey، sessionId، errorCode
tool_action agentId، runId؛ kind: "tool_action" sessionKey، sessionId، toolCallId، toolName، errorCode
inbound_message direction: "inbound"، channel، conversationKind، outcome agentId، runId، durationMs، resultCount، مراجع الهوية، reasonCode، errorCode
outbound_message direction: "outbound"، channel، conversationKind، outcome agentId، runId، durationMs، resultCount، مراجع الهوية، reasonCode، deliveryKind، failureStage، errorCode

تعدادات الرسائل المغلقة هي:

  • conversationKind: ‏direct أو group أو channel أو unknown.
  • outcome الوارد: completed أو skipped أو failed؛ وreasonCode اختياري: duplicate أو reply_operation_active أو reply_operation_aborted أو fast_abort أو plugin_bound_handled أو plugin_bound_unavailable أو plugin_bound_declined أو plugin_bound_error أو before_dispatch_handled أو acp_dispatch_completed أو acp_dispatch_failed أو acp_dispatch_empty أو acp_dispatch_aborted.
  • outcome الصادر: sent أو suppressed أو failed أو unknown؛ وreasonCode اختياري: cancelled_by_message_sending_hook أو cancelled_by_reply_payload_sending_hook أو empty_after_message_sending_hook أو empty_after_reply_payload_sending_hook أو no_visible_payload. يكون المحوّل الذي لا يعيد هوية للمنصة هو unknown، لأنه لا يمكن نفي الأثر الجانبي الخارجي.
  • deliveryKind: ‏text أو media أو other؛ وfailureStage: ‏platform_send أو queue أو unknown.

الحقول النهائية مترابطة، وليست اختيارية كلٌ على حدة:

المتغير التعيين النهائي
تشغيل الوكيل لا يحتوي started على errorCode؛ وتتطلب كل حالة انتهاء غير ناجحة رمز run_* المطابق لها.
إجراء الأداة لا يحتوي started والحالة الناجحة على errorCode؛ وتتطلب كل حالة انتهاء أخرى رمز tool_* المطابق لها.
الرسالة الواردة ناجحة = completed؛ محظورة = skipped؛ فاشلة = failed إضافة إلى message_processing_failed. عند وجود reasonCode، يجب أن تنتمي إلى تلك العائلة النهائية.
الرسالة الصادرة ناجحة = sent؛ محظورة = suppressed إضافة إلى reasonCode؛ فاشلة = failed إضافة إلى errorCode وfailureStage؛ غير معروفة = unknown إضافة إلى failureStage.

يتضمن كل حدث نشاط معرّف حدث ثابتًا، وتسلسلًا رتيبًا للسجل، وتسلسل حدث المصدر، وطابعًا زمنيًا، والجهة الفاعلة، والإجراء، والحالة، والعدد الصحيح schemaVersion: 1، وredaction: "metadata_only". تتطلب سجلات التشغيل والأدوات بيانات منشأ الوكيل والتشغيل، وقد تتضمن بيانات منشأ الجلسة. قد تتضمن سجلات الرسائل معرّفات الوكيل والتشغيل، لكنها لا تتضمن عمدًا مطلقًا sessionKey أو sessionId؛ ولذلك لا ينطبق مرشح الاستعلام sessionKey إلا على صفوف التشغيل والأدوات. قد تتضمن أحداث الأدوات معرّف استدعاء الأداة واسم الأداة.

تستخدم سجلات الرسائل message.inbound.processed أو message.outbound.finished، وتضيف الاتجاه، والقناة، ونوع المحادثة، والنتيجة الموحّدة، ونوع التسليم الاختياري، ومرحلة الفشل، والمدة، وعدد النتائج، ورمز السبب، والأسماء المستعارة ذات المفاتيح والمحلية للتثبيت للحساب/المحادثة/الرسالة/الهدف. تساعد هذه الأسماء المستعارة في الربط، لكنها لا تحقق إخفاء الهوية: إذ تحتوي قاعدة بيانات الحالة على مفتاحها، بينما لا تتضمنه صادرات RPC وCLI. لا يخزّن السجل المطالبات، أو نصوص الرسائل، أو وسائط الأدوات، أو نتائج الأدوات، أو مخرجات الأوامر، أو نصوص الأخطاء الخام. تظل قيم sessionKey للتشغيل/الأداة بيانات وصفية خامًا للربط، ويمكن أن تتضمن معرّفات حسابات المنصة أو النظراء؛ وتحذف سجلات الرسائل مفاتيح الجلسات.

بالنسبة إلى الصفوف الواردة، يقيس durationMs الإرسال الأساسي حتى حالته النهائية، ويحصي resultCount حمولات الأدوات والكتل والردود النهائية الموضوعة في قائمة الانتظار. وبالنسبة إلى الصفوف الصادرة، يمتد durationMs من تولّي مسؤولية التسليم حتى الإقرار، أو قائمة الرسائل المتعذرة، أو التسوية (بما في ذلك وقت الانتظار في قائمة الانتظار)، ويحصي resultCount عمليات الإرسال الفعلية المحددة إلى المنصة. يصف deliveryKind، عند وجوده، الحمولة الفعلية بعد الخطافات والعرض؛ وتحذفه الصفوف المحجوبة أو الملتبسة بسبب الأعطال.

تشمل تغطية الرسائل الحالية الرسائل الواردة المقبولة التي تصل إلى الإرسال الأساسي، بما في ذلك نتائج التكرار/النهاية الأساسية. وتكتب تغطية الصادر صفًا نهائيًا واحدًا لكل حمولة رد منطقية أصلية تصل إلى التسليم المشترك الدائم؛ ويُجمّع التقسيم والتوزيع المتشعب للمحوّل في resultCount. لا تُسجّل عمليات الإرسال القابلة لإعادة المحاولة أو الملتبسة الموضوعة في قائمة الانتظار إلا بعد الإقرار، أو إدراجها في قائمة الرسائل المتعذرة، أو التسوية. لا تشمل التغطية حتى الآن المسارات المحلية للـPlugin ومسارات الإرسال المباشر التي تتجاوز تلك الحدود المشتركة. تعمل قائمة انتظار العامل المحدودة بأفضل جهد وقد تُسقط السجلات عند الفشل أو التشبع، لذا لا تمثل هذه الواجهة أرشيف امتثال كاملًا بلا فقد.

يكون التسجيل مفعّلًا افتراضيًا وتتحكم فيه audit.enabled. ويُتحكم في تسجيل الرسائل بشكل منفصل بواسطة audit.messages، وتكون قيمته الافتراضية "off". عند تعطيل التسجيل، يواصل audit.activity.list تقديم السجلات المكتوبة سابقًا حتى انتهاء صلاحيتها.

تظل مخططات الطلب والنتيجة وAuditEvent المشحونة لـaudit.list دون تغيير، ولا تعيد إلا سجلات تشغيل الوكيل وإجراءات الأدوات. ينبغي لعملاء المشغّل الجدد استدعاء audit.activity.list عندما يعلن Gateway دعمه. قد تُبلغ بوابات Gateway الأقدم إما عن unknown method: audit.activity.list أو، لأن التخويل كان يسبق البحث عن الطريقة في الإصدارات المشحونة، عن missing scope: operator.admin لطلب ذي نطاق قراءة. لا تتعامل مع الحالة الأخيرة على أنها غياب للطريقة إلا عندما لا تكون الطريقة مُعلنة. ويمكن للعميل حينها إعادة محاولة audit.list فقط عندما لا تتطلب مرشحاته دعم نوع الرسالة، أو الاتجاه، أو القناة.

استخدم openclaw audit للاستعلامات النصية وصادرات JSON المحدودة.

استدعاءات RPC لسجل المهام

يفحص عملاء المشغّل سجلات مهام Gateway في الخلفية ويلغونها عبر استدعاءات RPC لسجل المهام (packages/gateway-protocol/src/schema/tasks.ts). تعيد هذه ملخصات منقّحة للمهام، لا حالة وقت التشغيل الخام.

  • tasks.list يتطلب operator.read.
    • المعاملات: status اختياري ("queued"، أو "running"، أو "completed"، أو "failed"، أو "cancelled"، أو "timed_out") أو مصفوفة من تلك الحالات، وagentId اختياري، وsessionKey اختياري، وlimit اختياري من 1 إلى 500، والسلسلة النصية cursor اختيارية.
    • النتيجة: { "tasks": TaskSummary[], "nextCursor"?: string }.
  • tasks.get يتطلب operator.read.
    • المعاملات: { "taskId": string }.
    • النتيجة: { "task": TaskSummary }.
    • تُعيد معرّفات المهام المفقودة صيغة خطأ عدم العثور الخاصة بـGateway.
  • tasks.cancel يتطلب operator.write.
    • المعاملات: { "taskId": string, "reason"?: string }.
    • النتيجة: { "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }.
    • يُبلغ found عما إذا كان السجل يحتوي على مهمة مطابقة. ويُبلغ cancelled عما إذا كان وقت التشغيل قد قبل الإلغاء أو سجّله.

يتضمن TaskSummary كلًا من id وstatus، وبيانات وصفية اختيارية: kind، وruntime، وtitle، وagentId، وsessionKey، وchildSessionKey، وownerKey، وrunId، وtaskId، وflowId، وparentTaskId، وsourceId، والطوابع الزمنية، والتقدم، والملخص النهائي، ونص الخطأ المنقّح. يحدد agentId الوكيل الذي ينفّذ المهمة؛ ويحفظ sessionKey وownerKey سياق مقدم الطلب والتحكم.

طرق مساعدة المشغّل

  • يجلب commands.list ‏(operator.read) قائمة أوامر وقت التشغيل لوكيل.
    • agentId اختياري؛ احذفه لقراءة مساحة عمل الوكيل الافتراضي.
    • يتحكم scope في الواجهة التي يستهدفها name الأساسي: يعيد text رمز الأمر النصي الأساسي من دون / البادئة؛ ويعيد native ومسار both الافتراضي أسماء أصلية مدركة لمزوّد الخدمة عند توفرها.
    • يحمل textAliases أسماء مستعارة دقيقة ذات شرطة مائلة، مثل /model و/m.
    • يحمل nativeName اسم الأمر الأصلي المدرك لمزوّد الخدمة عند وجوده.
    • provider اختياري، ولا يؤثر إلا في التسمية الأصلية وتوفر أوامر Plugin الأصلية.
    • يحذف includeArgs=false البيانات الوصفية المتسلسلة للوسائط من الاستجابة.
  • يجلب tools.catalog ‏(operator.read) كتالوج أدوات وقت التشغيل لوكيل. تتضمن الاستجابة أدوات مجمّعة وبيانات وصفية للمنشأ:
    • source: ‏core أو plugin
    • pluginId: مالك Plugin عندما يكون source="plugin"
    • optional: ما إذا كانت أداة Plugin اختيارية
  • يجلب tools.effective ‏(operator.read) قائمة الأدوات الفعلية في وقت التشغيل لجلسة.
    • sessionKey مطلوب.
    • يشتق Gateway سياق وقت التشغيل الموثوق من الجلسة على جانب الخادم بدلًا من قبول سياق المصادقة أو التسليم المقدم من المستدعي.
    • الاستجابة عبارة عن إسقاط مشتق من الخادم ومحدد بنطاق الجلسة للقائمة النشطة، بما يشمل أدوات النواة وPlugin والقناة وخادم MCP المكتشفة بالفعل.
    • tools.effective للقراءة فقط بالنسبة إلى MCP: قد يسقط كتالوج MCP لجلسة دافئة عبر سياسة الأدوات النهائية، لكنه لا ينشئ أوقات تشغيل MCP، ولا يربط وسائل النقل، ولا يصدر tools/list. وإذا لم يوجد كتالوج دافئ مطابق، فقد تتضمن الاستجابة إشعارًا مثل mcp-not-yet-connected، أو mcp-not-yet-listed، أو mcp-stale-catalog.
    • تستخدم إدخالات الأدوات الفعلية source="core"، أو source="plugin"، أو source="channel"، أو source="mcp".
  • يستدعي tools.invoke ‏(operator.write) أداة متاحة واحدة عبر مسار سياسة Gateway نفسه الذي يستخدمه /tools/invoke.
    • name مطلوب. أما args، وsessionKey، وagentId، وconfirm، وidempotencyKey فهي اختيارية.
    • إذا وُجد كل من sessionKey وagentId، فيجب أن يطابق وكيل الجلسة الذي جرى حله agentId.
    • تتطلب أغلفة النواة المخصصة للمالك فقط، مثل cron وgateway وnodes، هوية المالك/المسؤول (operator.admin) رغم أن tools.invoke نفسه هو operator.write.
    • الاستجابة عبارة عن غلاف موجّه إلى SDK، ويحتوي على ok وtoolName وoutput الاختياري وحقول error محددة الأنواع. تعيد حالات الرفض الناتجة عن الموافقة أو السياسة ok:false داخل الحمولة بدلًا من تجاوز مسار سياسة أدوات Gateway.
  • يجلب skills.status ‏(operator.read) قائمة Skills المرئية لوكيل.
    • agentId اختياري؛ احذفه لقراءة مساحة عمل الوكيل الافتراضي.
    • تتضمن الاستجابة الأهلية، والمتطلبات المفقودة، وفحوصات الإعداد، وخيارات التثبيت المنقّحة من دون كشف قيم الأسرار الخام.
  • يعيد skills.search وskills.detail ‏(operator.read) بيانات اكتشاف ClawHub الوصفية.
  • يُجهّز skills.upload.begin وskills.upload.chunk وskills.upload.commit ‏(operator.admin) أرشيف Skill خاصًا قبل تثبيته. هذا مسار تحميل منفصل للمسؤول ومخصص للعملاء الموثوقين، وليس مسار تثبيت Skill المعتاد في ClawHub، ويكون معطلًا افتراضيًا ما لم يُمكّن skills.install.allowUploadedArchives.
    • ينشئ skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? }) تحميلًا مرتبطًا بذلك الاسم المختصر وقيمة الفرض.
    • يُلحق skills.upload.chunk({ uploadId, offset, dataBase64 }) البايتات عند الإزاحة الدقيقة بعد فك ترميزها.
    • يتحقق skills.upload.commit({ uploadId, sha256? }) من الحجم النهائي و SHA-256. لا يؤدي الاعتماد إلا إلى إنهاء التحميل؛ ولا يثبّت Skill.
    • أرشيفات Skills المحمّلة هي أرشيفات zip تحتوي على جذر SKILL.md. ولا يحدد اسم الدليل الداخلي للأرشيف هدف التثبيت مطلقًا.
  • يتضمن skills.install ‏(operator.admin) ثلاثة أوضاع:
    • وضع ClawHub: يثبّت { source: "clawhub", slug, version?, force? } مجلد Skill في دليل skills/ لمساحة عمل الوكيل الافتراضي.
    • وضع التحميل: يثبّت { source: "upload", uploadId, slug, force?, sha256?, timeoutMs? } تحميلًا معتمدًا في دليل skills/<slug> لمساحة عمل الوكيل الافتراضي. يجب أن يطابق الاسم المختصر وقيمة الفرض طلب skills.upload.begin الأصلي. يُرفض ما لم يُمكّن skills.install.allowUploadedArchives؛ ولا يؤثر هذا الإعداد في عمليات تثبيت ClawHub.
    • وضع مثبّت Gateway: يشغّل { name, installId, timeoutMs? } إجراء metadata.openclaw.install معلنًا على مضيف Gateway. قد يظل العملاء الأقدم يرسلون dangerouslyForceUnsafeInstall؛ هذا الحقل مهمل، ولا يُقبل إلا للتوافق مع البروتوكول، ويُتجاهل. استخدم security.installPolicy لقرارات التثبيت المملوكة للمشغّل.
  • يتضمن skills.update ‏(operator.admin) وضعين:
    • يحدّث وضع ClawHub اسمًا مختصرًا متتبعًا واحدًا أو جميع عمليات تثبيت ClawHub المتتبعة في مساحة عمل الوكيل الافتراضي.
    • يعدّل وضع الإعداد قيم skills.entries.<skillKey> مثل enabled، وapiKey، وenv.

عروض models.list

يقبل models.list معامل view اختياريًا (src/agents/model-catalog-visibility.ts):

  • محذوف أو "default": إذا جرى تكوين agents.defaults.models، فتكون الاستجابة هي الكتالوج المسموح به، بما في ذلك النماذج المكتشفة ديناميكيًا لإدخالات provider/*. وإلا فتكون الاستجابة هي كتالوج Gateway الكامل.
  • "configured": سلوك بحجم أداة الاختيار. إذا جرى تكوين agents.defaults.models، فإنه يظل ذا الأولوية، بما في ذلك الاكتشاف المحدد النطاق بحسب المزوّد لإدخالات provider/*. من دون قائمة سماح، تستخدم الاستجابة إدخالات models.providers.<provider>.models الصريحة، ولا تعود إلى الكتالوج الكامل إلا عند عدم وجود صفوف نماذج مكوّنة.
  • "provider-config": مخزون models.providers.*.models من إعداد المصدر، مستقل عن قوائم السماح لأداة الاختيار. تتضمن الصفوف إمكانات النماذج العامة والتوافر المدرك للمسار، لكنها تحذف نقاط نهاية المزوّد ومواد المصادقة وتكوين طلبات وقت التشغيل.
  • "all": كتالوج Gateway الكامل، مع تجاوز agents.defaults.models. استخدمه لواجهات مستخدم التشخيص/الاكتشاف، وليس لأدوات اختيار النماذج العادية.

موافقات التنفيذ

  • عندما يتطلب طلب تنفيذ موافقة، يبث Gateway exec.approval.requested.
  • تحسم عملاء المشغّل الطلب باستدعاء exec.approval.resolve (يتطلب operator.approvals).
  • بالنسبة إلى host=node، يجب أن يتضمن exec.approval.request القيمة systemRunPlan (بيانات argv/cwd/rawCommand/الجلسة الوصفية القياسية). تُرفض الطلبات التي لا تحتوي على systemRunPlan.
  • بعد الموافقة، تعيد استدعاءات node.invoke system.run المُمرَّرة استخدام systemRunPlan القياسي نفسه بوصفه سياق الأمر/مجلد العمل الحالي/الجلسة المعتمد.
  • إذا عدّل مستدعٍ command أو rawCommand أو cwd أو agentId أو sessionKey بين التحضير والتمرير النهائي المعتمد لـ system.run، يرفض Gateway التشغيل بدلًا من الوثوق بالحمولة المعدّلة.

الإجراء الاحتياطي لتسليم الوكيل

  • يمكن أن تتضمن طلبات agent القيمة deliver=true لطلب التسليم الصادر.
  • يحافظ bestEffortDeliver=false (القيمة الافتراضية) على السلوك الصارم: تعيد أهداف التسليم غير المحسومة أو الداخلية فقط INVALID_REQUEST.
  • يسمح bestEffortDeliver=true بالعودة إلى التنفيذ ضمن الجلسة فقط عندما يتعذر تحديد مسار خارجي قابل للتسليم (مثل جلسات المحادثة الداخلية/عبر الويب أو تكوينات القنوات المتعددة الملتبسة).
  • قد تتضمن نتائج agent النهائية القيمة result.deliveryStatus عند طلب التسليم، باستخدام حالات sent وsuppressed وpartial_failed و failed نفسها الموثقة في openclaw agent --json --deliver.

تعيين الإصدارات

  • توجد PROTOCOL_VERSION وMIN_CLIENT_PROTOCOL_VERSION وMIN_NODE_PROTOCOL_VERSION وMIN_PROBE_PROTOCOL_VERSION في packages/gateway-protocol/src/version.ts.
  • يرسل العملاء minProtocol + maxProtocol. يجب أن يتضمن عملاء المشغّل وواجهة المستخدم البروتوكول الحالي ضمن هذا النطاق؛ ويعمل العملاء والخوادم الحالية بالبروتوكول v4.
  • يجوز للعملاء المصادق عليهم الذين لديهم كل من role: "node" وclient.mode: "node" استخدام بروتوكول Node السابق مباشرةً N-1 (حاليًا v3). تستخدم مجسّات إعادة التشغيل الخفيفة نافذة N-1 نفسها. لا تتغير مصادقة الجهاز والإقران والنطاقات وسياسة الأوامر وموافقات التنفيذ بفعل نافذة التوافق هذه. تُحجب إمكانات Node والأوامر المملوكة لـ Plugin حتى ترقية Node إلى البروتوكول الحالي، لأن أسطحها المستضافة ليست جزءًا من عقد N-1.
  • تُولَّد المخططات والنماذج من تعريفات TypeBox:
    • pnpm protocol:gen
    • pnpm protocol:gen:swift
    • pnpm protocol:check

ثوابت العميل

يوجد تنفيذ العميل المرجعي في packages/gateway-client/src/ (يغلّفه OpenClaw عبر واجهة src/gateway/client.ts الرقيقة). تظل هذه القيم الافتراضية مستقرة عبر البروتوكول v4، وهي خط الأساس المتوقع لعملاء الجهات الخارجية.

الثابت القيمة الافتراضية المصدر
PROTOCOL_VERSION 4 packages/gateway-protocol/src/version.ts
MIN_CLIENT_PROTOCOL_VERSION 4 packages/gateway-protocol/src/version.ts
MIN_NODE_PROTOCOL_VERSION 3 packages/gateway-protocol/src/version.ts
MIN_PROBE_PROTOCOL_VERSION 3 packages/gateway-protocol/src/version.ts
مهلة الطلب (لكل RPC) 30_000 مللي ثانية packages/gateway-client/src/client.ts (requestTimeoutMs)
مهلة ما قبل المصادقة / تحدي الاتصال 15_000 مللي ثانية packages/gateway-client/src/timeouts.ts (يمكن لمتغير البيئة OPENCLAW_HANDSHAKE_TIMEOUT_MS زيادة ميزانية الخادم/العميل المقترن)
التراجع الأولي لإعادة الاتصال 1_000 مللي ثانية packages/gateway-client/src/client.ts (GATEWAY_RECONNECT_POLICY)
أقصى تراجع لإعادة الاتصال 30_000 مللي ثانية packages/gateway-client/src/client.ts (GATEWAY_RECONNECT_POLICY)
تقييد إعادة المحاولة السريعة بعد إغلاق رمز الجهاز 250 مللي ثانية packages/gateway-client/src/client.ts
مهلة الإيقاف الإجباري قبل terminate() 250 مللي ثانية FORCE_STOP_TERMINATE_GRACE_MS
مهلة stopAndWait() الافتراضية 1_000 مللي ثانية STOP_AND_WAIT_TIMEOUT_MS
الفاصل الافتراضي للنبضات (قبل hello-ok) 30_000 مللي ثانية packages/gateway-client/src/client.ts
الإغلاق عند انتهاء مهلة النبضة الرمز 4000 عندما يتجاوز الصمت tickIntervalMs * 2 packages/gateway-client/src/client.ts
MAX_PAYLOAD_BYTES 25 * 1024 * 1024 (25 MB) src/gateway/server-constants.ts

يعلن الخادم قيم policy.tickIntervalMs وpolicy.maxPayload وpolicy.maxBufferedBytes الفعلية في hello-ok؛ وينبغي للعملاء الالتزام بهذه القيم بدلًا من القيم الافتراضية السابقة للمصافحة.

يتيح العميل المرجعي للطلبات المحدودة امتلاك مهلتها النهائية المكوّنة عندما يكون لكل طلب معلّق مهلة. يُبقي طلب expectFinal من دون timeoutMs محدودة، أو أي طلب يتضمن timeoutMs: null، أو مزيج من الطلبات المحدودة وغير المحدودة، مراقب النبضات نشطًا. إذا ظلت الأحداث الواردة والاستجابات صامتة بعد حد مهلة النبضات، يغلق العميل المقبس بالرمز 4000، ويرفض كل طلب معلّق، ثم يعيد الاتصال. ولا يعيد تشغيل الطلبات المرفوضة بعد إعادة الاتصال.

المصادقة

  • تستخدم مصادقة Gateway بالسر المشترك connect.params.auth.token أو connect.params.auth.password، حسب gateway.auth.mode المُهيأ ("none" | "token" | "password" | "trusted-proxy").
  • تستوفي الأوضاع الحاملة للهوية، مثل Tailscale Serve ‏(gateway.auth.allowTailscale: true) أو gateway.auth.mode: "trusted-proxy" غير ذي الاسترجاع المحلي، فحص مصادقة الاتصال من ترويسات الطلب بدلاً من connect.params.auth.*.
  • يتخطى gateway.auth.mode: "none" ذو الدخول الخاص مصادقة الاتصال بالسر المشترك بالكامل؛ لا تكشف هذا الوضع عبر دخول عام أو غير موثوق.
  • بعد الاقتران، يصدر Gateway رمز جهاز مقيّدًا بدور الاتصال ونطاقاته، ويُعاد في hello-ok.auth.deviceToken. ينبغي للعملاء الاحتفاظ به بعد أي اتصال ناجح.
  • ينبغي أيضًا عند إعادة الاتصال باستخدام رمز الجهاز المخزّن إعادة استخدام مجموعة النطاقات المعتمدة المخزّنة لذلك الرمز. يحافظ ذلك على صلاحيات القراءة والفحص والحالة الممنوحة سابقًا، ويتجنب حصر عمليات إعادة الاتصال ضمنيًا ودون تنبيه في نطاق أضيق مخصص للمسؤول فقط.
  • تجميع مصادقة الاتصال من جانب العميل (selectConnectAuth في packages/gateway-client/src/client.ts):
    • يُعد auth.password مستقلاً ويُمرر دائمًا عند تعيينه.
    • تُملأ auth.token وفق ترتيب الأولوية: رمز مشترك صريح أولاً، ثم deviceToken صريح، ثم رمز مخزّن خاص بكل جهاز (مفهرس بواسطة deviceId + role).
    • لا تُرسل auth.bootstrapToken إلا عندما لا يحسم أي مما سبق auth.token. يؤدي وجود رمز مشترك أو أي رمز جهاز محسوم إلى منع إرسالها.
    • تقتصر الترقية التلقائية لرمز جهاز مخزّن عند إعادة المحاولة لمرة واحدة باستخدام AUTH_TOKEN_MISMATCH على نقاط النهاية الموثوقة فقط: الاسترجاع المحلي، أو wss:// مع tlsFingerprint مثبت. لا يتأهل wss:// العام من دون تثبيت.
  • يعيد تمهيد رمز الإعداد المضمّن hello-ok.auth.deviceToken الخاص بالعقدة الأساسية، إضافة إلى رمز مشغّل محدود في hello-ok.auth.deviceTokens لتسليم موثوق إلى جهاز محمول. يتضمن رمز المشغّل operator.talk.secrets لقراءة إعدادات Talk الأصلية، لكنه يستثني نطاقات تعديل الاقتران وoperator.admin.
  • أثناء انتظار تمهيد رمز إعداد غير أساسي للموافقة، تتضمن تفاصيل PAIRING_REQUIRED كلاً من recommendedNextStep: "wait_then_retry"، وretryable: true، وpauseReconnect: false. واصل إعادة الاتصال باستخدام رمز التمهيد نفسه حتى تتم الموافقة على الطلب أو يصبح الرمز غير صالح.
  • لا تحتفظ بـ hello-ok.auth.deviceTokens إلا عندما يستخدم الاتصال مصادقة التمهيد عبر وسيلة نقل موثوقة مثل wss:// أو الاقتران عبر الاسترجاع المحلي/المحلي.
  • إذا قدّم العميل deviceToken صريحًا أو scopes صريحًا، فتبقى مجموعة النطاقات التي طلبها المستدعي هي المرجع؛ ولا يُعاد استخدام النطاقات المخزّنة مؤقتًا إلا عندما يعيد العميل استخدام رمز الجهاز المخزّن.
  • يمكن تدوير رموز الأجهزة أو إبطالها عبر device.token.rotate و device.token.revoke (يتطلب operator.pairing). يتطلب تدوير أو إبطال رمز عقدة أو أي دور آخر غير المشغّل أيضًا operator.admin.
  • تعيد device.token.rotate بيانات التدوير الوصفية. ولا تُعيد رمز الحامل البديل إلا للاستدعاءات الصادرة من الجهاز نفسه والمصادق عليها بالفعل باستخدام رمز ذلك الجهاز، حتى يتمكن العملاء الذين يعتمدون على الرمز فقط من الاحتفاظ بالرمز البديل قبل إعادة الاتصال. لا تعيد عمليات التدوير المشتركة أو الإدارية رمز الحامل.
  • يظل إصدار الرموز وتدويرها وإبطالها مقيّدًا بمجموعة الأدوار المعتمدة المسجلة في إدخال اقتران ذلك الجهاز؛ ولا يمكن لتعديل الرمز توسيع دور جهاز أو استهداف دور لم تمنحه موافقة الاقتران قط.
  • بالنسبة إلى جلسات رموز الأجهزة المقترنة، تقتصر إدارة الجهاز على الذات ما لم يكن لدى المستدعي أيضًا operator.admin: لا يستطيع المستدعون غير المسؤولين إدارة سوى رمز المشغّل لإدخال أجهزتهم. وتقتصر إدارة رموز العقد والأدوار الأخرى غير المشغّل على المسؤول فقط، حتى لجهاز المستدعي نفسه.
  • تتحقق device.token.rotate وdevice.token.revoke أيضًا من مجموعة نطاقات رمز المشغّل المستهدف مقابل نطاقات جلسة المستدعي الحالية. لا يستطيع المستدعون غير المسؤولين تدوير أو إبطال رمز مشغّل أوسع من الرمز الذي لديهم بالفعل.
  • تتضمن إخفاقات المصادقة error.details.code إضافة إلى تلميحات الاسترداد:
    • error.details.canRetryWithDeviceToken (قيمة منطقية)
    • error.details.recommendedNextStep: أحد القيم retry_with_device_token، وupdate_auth_configuration، وupdate_auth_credentials، وwait_then_retry، وreview_auth_configuration (packages/gateway-protocol/src/connect-error-details.ts).
  • سلوك العميل عند AUTH_TOKEN_MISMATCH:
    • يجوز للعملاء الموثوقين محاولة إعادة واحدة محدودة باستخدام رمز مخزّن مؤقتًا خاص بكل جهاز.
    • إذا فشلت إعادة المحاولة، فأوقف حلقات إعادة الاتصال التلقائية وأظهر إرشادات الإجراء المطلوب من المشغّل.
  • تعني AUTH_SCOPE_MISMATCH أن رمز الجهاز قد تم التعرف عليه، لكنه لا يغطي الدور أو النطاقات المطلوبة. لا تعرض هذا باعتباره رمزًا غير صالح؛ اطلب من المشغّل إعادة الاقتران أو الموافقة على عقد النطاقات الأضيق أو الأوسع.

هوية الجهاز والاقتران

  • ينبغي للعقد تضمين هوية جهاز ثابتة (device.id) مشتقة من بصمة زوج مفاتيح.
  • تصدر بوابات Gateway رموزًا لكل جهاز ودور.
  • تلزم موافقات الاقتران لمعرّفات الأجهزة الجديدة ما لم تكن الموافقة التلقائية المحلية مفعّلة.
  • تتركز الموافقة التلقائية على الاقتران حول الاتصالات المحلية المباشرة عبر الاسترجاع المحلي.
  • يتضمن OpenClaw أيضًا مسار اتصال ذاتي ضيقًا محليًا بالنسبة إلى الواجهة الخلفية/الحاوية لتدفقات المساعد الموثوقة التي تستخدم السر المشترك.
  • تظل الاتصالات من المضيف نفسه عبر الشبكة الخاصة أو LAN تُعامل على أنها بعيدة لأغراض الاقتران وتتطلب الموافقة.
  • تتضمن عملاء WS عادةً هوية device أثناء connect (المشغّل + العقدة). والاستثناءات الوحيدة للمشغّل من دون جهاز هي مسارات الثقة الصريحة:
    • gateway.controlUi.allowInsecureAuth=true للتوافق مع HTTP غير الآمن والمقتصر على المضيف المحلي.
    • مصادقة ناجحة لواجهة Control UI الخاصة بالمشغّل عبر gateway.auth.mode: "trusted-proxy".
    • gateway.controlUi.dangerouslyDisableDeviceAuth=true (ملاذ أخير، خفض شديد للأمان).
    • استدعاءات RPC المباشرة عبر الاسترجاع المحلي لواجهة gateway-client الخلفية على مسار المساعد الداخلي المحجوز.
  • يترتب على حذف هوية الجهاز عواقب تخص النطاقات. عندما يُسمح باتصال مشغّل من دون جهاز عبر مسار ثقة صريح، يظل OpenClaw يمسح النطاقات المعلنة ذاتيًا إلى مجموعة فارغة ما لم يكن لذلك المسار استثناء مسمى للاحتفاظ بالنطاقات. عندئذ تفشل الأساليب المقيّدة بالنطاقات مع missing scope.
  • يُعد gateway.controlUi.dangerouslyDisableDeviceAuth=true مسارًا لواجهة Control UI للاحتفاظ بالنطاقات في حالات الملاذ الأخير. ولا يمنح نطاقات إلى عملاء WebSocket مخصصين عشوائيين على هيئة واجهة خلفية أو CLI.
  • يحتفظ مسار مساعد الواجهة الخلفية المحجوز والمباشر عبر الاسترجاع المحلي gateway-client بالنطاقات فقط لاستدعاءات RPC الداخلية والمحلية لمستوى التحكم؛ ولا تحصل معرّفات الواجهات الخلفية المخصصة على هذا الاستثناء.
  • يجب على جميع الاتصالات توقيع قيمة nonce ‏connect.challenge التي يوفرها الخادم.

تشخيصات ترحيل مصادقة الجهاز

بالنسبة إلى العملاء القدامى الذين لا يزالون يستخدمون سلوك التوقيع السابق لآلية التحدي، تعيد connect رموز تفاصيل DEVICE_AUTH_* ضمن error.details.code مع error.details.reason ثابت.

إخفاقات الترحيل الشائعة:

الرسالة details.code details.reason المعنى
device nonce required DEVICE_AUTH_NONCE_REQUIRED device-nonce-missing حذف العميل device.nonce (أو أرسل قيمة فارغة).
device nonce mismatch DEVICE_AUTH_NONCE_MISMATCH device-nonce-mismatch وقّع العميل باستخدام nonce قديمة أو خاطئة.
device signature invalid DEVICE_AUTH_SIGNATURE_INVALID device-signature لا تطابق حمولة التوقيع حمولة v2.
device signature expired DEVICE_AUTH_SIGNATURE_EXPIRED device-signature-stale يقع الطابع الزمني الموقّع خارج الانحراف المسموح.
device identity mismatch DEVICE_AUTH_DEVICE_ID_MISMATCH device-id-mismatch لا يطابق device.id بصمة المفتاح العام.
device public key invalid DEVICE_AUTH_PUBLIC_KEY_INVALID device-public-key فشل تنسيق المفتاح العام أو توحيده إلى الصيغة القياسية.

هدف الترحيل:

  • انتظر دائمًا connect.challenge.
  • وقّع حمولة v2 التي تتضمن nonce الخاصة بالخادم.
  • أرسل nonce نفسها في connect.params.device.nonce.
  • حمولة التوقيع المفضلة هي v3 (buildDeviceAuthPayloadV3 في packages/gateway-client/src/device-auth.ts)، التي تربط platform وdeviceFamily إضافة إلى حقول الجهاز والعميل والدور والنطاقات والرمز وnonce.
  • تظل توقيعات v2 القديمة مقبولة للتوافق، لكن تثبيت البيانات الوصفية للجهاز المقترن يظل يتحكم في سياسة الأوامر عند إعادة الاتصال.

TLS والتثبيت

  • يُدعم TLS لاتصالات WS (إعداد gateway.tls).
  • يمكن للعملاء اختياريًا تثبيت بصمة شهادة Gateway عبر gateway.remote.tlsFingerprint أو --tls-fingerprint في CLI.

النطاق

يتيح هذا البروتوكول واجهة Gateway API الكاملة: الحالة، والقنوات، والنماذج، والمحادثة، والوكيل، والجلسات، والعقد، والموافقات، وغير ذلك. ويُحدد السطح الدقيق بواسطة مخططات TypeBox المُعاد تصديرها من packages/gateway-protocol/src/schema.ts.

ذو صلة

Was this useful?
On this page

On this page