واجهة التحكم (المتصفح)
واجهة التحكم هي تطبيق صفحة واحدة صغير مبني باستخدام Vite + Lit وتقوم Gateway بتقديمه:- الافتراضي:
http://<host>:18789/ - بادئة اختيارية: اضبط
gateway.controlUi.basePath(مثل/openclaw)
فتح سريع (محلي)
إذا كانت Gateway تعمل على الجهاز نفسه، فافتح: إذا فشل تحميل الصفحة، فابدأ Gateway أولًا:openclaw gateway.
يتم توفير المصادقة أثناء مصافحة WebSocket عبر:
connect.params.auth.tokenconnect.params.auth.password- ترويسات هوية Tailscale Serve عندما يكون
gateway.auth.allowTailscale: true - ترويسات هوية trusted-proxy عندما يكون
gateway.auth.mode: "trusted-proxy"
gateway.auth.mode هو "password".
إقران الجهاز (الاتصال الأول)
عندما تتصل بواجهة التحكم من متصفح أو جهاز جديد، فإن Gateway تتطلب موافقة إقران لمرة واحدة — حتى إذا كنت على Tailnet نفسها معgateway.auth.allowTailscale: true. وهذا إجراء أمني لمنع
الوصول غير المصرح به.
ما الذي ستراه: “disconnected (1008): pairing required”
للموافقة على الجهاز:
requestId جديد.
أعد تشغيل openclaw devices list قبل الموافقة.
بعد الموافقة، يتم تذكر الجهاز ولن يتطلب إعادة الموافقة إلا
إذا ألغيتَه باستخدام openclaw devices revoke --device <id> --role <role>. راجع
CLI الأجهزة لمعرفة تدوير الرموز المميزة والإلغاء.
ملاحظات:
- تتم الموافقة تلقائيًا على اتصالات المتصفح المحلية المباشرة عبر local loopback (
127.0.0.1/localhost). - ما تزال اتصالات المتصفح عبر Tailnet وLAN تتطلب موافقة صريحة، حتى عندما تأتي من الجهاز نفسه.
- ينشئ كل ملف تعريف متصفح معرّف جهاز فريدًا، لذا فإن تغيير المتصفحات أو مسح بيانات المتصفح سيتطلب إعادة الإقران.
دعم اللغة
يمكن لواجهة التحكم أن توطّن نفسها عند أول تحميل استنادًا إلى لغة متصفحك، ويمكنك تجاوز ذلك لاحقًا من منتقي اللغة في بطاقة الوصول.- اللغات المدعومة:
enوzh-CNوzh-TWوpt-BRوdeوes - يتم تحميل الترجمات غير الإنجليزية بشكل كسول في المتصفح.
- تُحفَظ اللغة المحددة في تخزين المتصفح وتُعاد إعادة استخدامها في الزيارات المستقبلية.
- تعود مفاتيح الترجمة المفقودة إلى الإنجليزية.
ما الذي يمكنها فعله (اليوم)
- الدردشة مع النموذج عبر Gateway WS (
chat.history,chat.send,chat.abort,chat.inject) - بث استدعاءات الأدوات + بطاقات مخرجات الأدوات الحية في الدردشة (أحداث الوكيل)
- القنوات: حالة القنوات المضمّنة بالإضافة إلى قنوات الإضافات المضمّنة/الخارجية، وتسجيل الدخول عبر QR، وإعدادات كل قناة (
channels.status,web.login.*,config.patch) - المثيلات: قائمة التواجد + التحديث (
system-presence) - الجلسات: سرد + تجاوزات لكل جلسة للنموذج/التفكير/الوضع السريع/الوضع المطوّل/الاستدلال (
sessions.list,sessions.patch) - مهام Cron: سرد/إضافة/تعديل/تشغيل/تمكين/تعطيل + سجل التشغيل (
cron.*) - Skills: الحالة، والتمكين/التعطيل، والتثبيت، وتحديثات مفاتيح API (
skills.*) - العُقد: سرد + الإمكانات (
node.list) - موافقات التنفيذ: تعديل قوائم السماح الخاصة بـ gateway أو العقد + سياسة ask لـ
exec host=gateway/node(exec.approvals.*) - الإعدادات: عرض/تعديل
~/.openclaw/openclaw.json(config.get,config.set) - الإعدادات: تطبيق + إعادة تشغيل مع التحقق (
config.apply) وتنشيط آخر جلسة نشطة - تتضمن عمليات كتابة الإعدادات حارس base-hash لمنع الكتابة فوق التعديلات المتزامنة
- تُجري عمليات كتابة الإعدادات (
config.set/config.apply/config.patch) أيضًا فحصًا مسبقًا لحل SecretRef النشط للمراجع الموجودة في حمولة الإعدادات المقدمة؛ وتُرفض المراجع النشطة غير المحلولة في الحمولة المقدمة قبل الكتابة - مخطط الإعدادات + عرض النموذج (
config.schema/config.schema.lookup, بما في ذلكtitle/descriptionللحقل، وتلميحات UI المطابقة، وملخصات العناصر التابعة المباشرة، وبيانات الوثائق الوصفية في عُقد الكائنات/البطاقات العامة/المصفوفات/التركيبات المتداخلة، بالإضافة إلى مخططات الإضافات + القنوات عند توفرها)؛ ولا يكون محرر Raw JSON متاحًا إلا عندما تمتلك اللقطة رحلة ذهاب وإياب خام آمنة - إذا تعذر على لقطة ما إجراء رحلة ذهاب وإياب آمنة للنص الخام، فإن واجهة التحكم تفرض وضع النموذج وتعطّل وضع Raw لتلك اللقطة
- تُعرَض قيم كائنات SecretRef المنظمة للقراءة فقط في حقول نص النموذج لمنع الإفساد العرضي الناتج عن تحويل الكائن إلى سلسلة
- التصحيح: لقطات الحالة/الصحة/النماذج + سجل الأحداث + استدعاءات RPC اليدوية (
status,health,models.list) - السجلات: تتبع حي لسجلات ملفات gateway مع التصفية/التصدير (
logs.tail) - التحديث: تشغيل تحديث حزمة/git + إعادة تشغيل (
update.run) مع تقرير إعادة تشغيل
- بالنسبة إلى المهام المعزولة، يكون التسليم افتراضيًا إلى ملخص إعلان. ويمكنك التبديل إلى عدم التسليم إذا كنت تريد تشغيلات داخلية فقط.
- تظهر حقول القناة/الهدف عند تحديد الإعلان.
- يستخدم وضع Webhook
delivery.mode = "webhook"مع تعيينdelivery.toإلى عنوان URL صالح لـ webhook من نوع HTTP(S). - بالنسبة إلى مهام الجلسة الرئيسية، يتوفر وضعا التسليم webhook وعدم التسليم.
- تتضمن عناصر التحكم المتقدمة في التعديل الحذف بعد التشغيل، ومسح تجاوز الوكيل، وخيارات Cron الدقيقة/المتدرجة، وتجاوزات نموذج الوكيل/التفكير، وتبديلات التسليم بأفضل جهد.
- يكون التحقق من صحة النموذج مضمنًا مع أخطاء على مستوى الحقل؛ وتعطّل القيم غير الصالحة زر الحفظ حتى يتم إصلاحها.
- اضبط
cron.webhookTokenلإرسال رمز bearer مخصص؛ وإذا حُذف فسيتم إرسال webhook من دون ترويسة مصادقة. - التراجع القديم: ما تزال المهام القديمة المخزنة مع
notify: trueقادرة على استخدامcron.webhookإلى أن تتم هجرتها.
سلوك الدردشة
chat.sendغير حاجب: فهو يقرّ فورًا بـ{ runId, status: "started" }ويتم بث الاستجابة عبر أحداثchat.- تعيد إعادة الإرسال بالمفتاح نفسه
idempotencyKeyالقيمة{ status: "in_flight" }أثناء التشغيل، و{ status: "ok" }بعد الاكتمال. - تكون استجابات
chat.historyمحدودة الحجم حفاظًا على أمان UI. وعندما تكون إدخالات النص المسجل كبيرة جدًا، قد تقوم Gateway باقتطاع الحقول النصية الطويلة، وحذف كتل البيانات الوصفية الثقيلة، واستبدال الرسائل كبيرة الحجم بعنصر نائب ([chat.history omitted: message too large]). - يقوم
chat.historyأيضًا بإزالة علامات التوجيه المضمنة الخاصة بالعرض فقط من النص المرئي للمساعد (مثل[[reply_to_*]]و[[audio_as_voice]])، وحمولات XML النصية العادية لاستدعاءات الأدوات (بما في ذلك<tool_call>...</tool_call>و<function_call>...</function_call>و<tool_calls>...</tool_calls>و<function_calls>...</function_calls>وكتل استدعاء الأدوات المقتطعة)، ورموز التحكم في النموذج المسرّبة بصيغة ASCII/العرض الكامل، ويحذف إدخالات المساعد التي يكون نصها المرئي بالكامل هو الرمز الصامت الدقيقNO_REPLY/no_reply. - يقوم
chat.injectبإلحاق ملاحظة مساعد بالنص المسجل للجلسة ويبث حدثchatلتحديثات UI فقط (من دون تشغيل وكيل، ومن دون تسليم إلى القناة). - تقوم منتقيات النموذج والتفكير في رأس الدردشة بتعديل الجلسة النشطة فورًا عبر
sessions.patch؛ وهي تجاوزات دائمة للجلسة، وليست خيارات إرسال لدور واحد فقط. - الإيقاف:
- انقر Stop (يستدعي
chat.abort) - اكتب
/stop(أو عبارات الإلغاء المستقلة مثلstopأوstop actionأوstop runأوstop openclawأوplease stop) للإلغاء خارج النطاق - يدعم
chat.abortالقيمة{ sessionKey }(من دونrunId) لإلغاء جميع التشغيلات النشطة لتلك الجلسة
- انقر Stop (يستدعي
- الاحتفاظ الجزئي عند الإلغاء:
- عند إلغاء تشغيل، قد يظل النص الجزئي للمساعد ظاهرًا في UI
- تحتفظ Gateway بالنص الجزئي الملغى للمساعد في سجل النصوص عندما يوجد خرج مخزن مؤقتًا
- تتضمن الإدخالات المحتفَظ بها بيانات وصفية للإلغاء حتى يتمكن مستهلكو النصوص المسجلة من تمييز الأجزاء الملغاة عن مخرجات الإكمال العادية
وصول Tailnet (موصى به)
Tailscale Serve المدمج (المفضل)
أبقِ Gateway على loopback ودع Tailscale Serve يمرّرها عبر HTTPS:https://<magicdns>/(أوgateway.controlUi.basePathالمهيأ لديك)
tailscale-user-login) عندما يكون gateway.auth.allowTailscale هو true. ويقوم OpenClaw
بالتحقق من الهوية عبر حل عنوان x-forwarded-for باستخدام
tailscale whois ومطابقته مع الترويسة، ولا يقبل هذه الترويسات إلا عندما
يضرب الطلب loopback مع ترويسات x-forwarded-* الخاصة بـ Tailscale. اضبط
gateway.auth.allowTailscale: false إذا كنت تريد فرض بيانات اعتماد صريحة تعتمد على السر المشترك
حتى مع حركة Serve. ثم استخدم gateway.auth.mode: "token" أو
"password".
وبالنسبة إلى مسار هوية Serve غير المتزامن هذا، تتم سلسلة محاولات المصادقة الفاشلة من عنوان IP العميل نفسه
ونطاق المصادقة نفسه قبل كتابات تحديد المعدل. ولذلك يمكن أن يظهر
retry later في الطلب الثاني من إعادة المحاولة السيئة المتزامنة من المتصفح نفسه
بدلًا من سباق فشلَي تطابق عاديين بالتوازي.
تفترض مصادقة Serve من دون رمز أن مضيف gateway موثوق. وإذا كان من الممكن
أن تعمل شيفرة محلية غير موثوقة على ذلك المضيف، فاشترط مصادقة token/password.
الربط بـ tailnet + token
http://<tailscale-ip>:18789/(أوgateway.controlUi.basePathالمهيأ لديك)
connect.params.auth.token أو connect.params.auth.password).
HTTP غير الآمن
إذا فتحت لوحة المعلومات عبر HTTP عادي (http://<lan-ip> أو http://<tailscale-ip>)،
فسيعمل المتصفح في سياق غير آمن ويحظر WebCrypto. وافتراضيًا،
يقوم OpenClaw بحظر اتصالات واجهة التحكم من دون هوية جهاز.
الاستثناءات الموثقة:
- توافق HTTP غير الآمن الخاص بـ localhost فقط مع
gateway.controlUi.allowInsecureAuth=true - نجاح مصادقة المشغّل في واجهة التحكم عبر
gateway.auth.mode: "trusted-proxy" - وضع الطوارئ
gateway.controlUi.dangerouslyDisableDeviceAuth=true
https://<magicdns>/(Serve)http://127.0.0.1:18789/(على مضيف gateway)
allowInsecureAuth مجرد تبديل توافق محلي:
- يسمح لجلسات واجهة التحكم على localhost بالمتابعة من دون هوية جهاز في سياقات HTTP غير الآمنة.
- لا يتجاوز فحوصات الإقران.
- لا يرخّي متطلبات هوية الجهاز البعيدة (غير localhost).
dangerouslyDisableDeviceAuth بتعطيل فحوصات هوية جهاز واجهة التحكم وهو
تخفيض أمني خطير جدًا. أعده سريعًا بعد استخدام الطوارئ.
ملاحظة trusted-proxy:
- يمكن لمصادقة trusted-proxy الناجحة أن تسمح بجلسات واجهة تحكم للمشغّل من دون هوية جهاز
- وهذا لا يمتد إلى جلسات واجهة التحكم ذات دور العقدة
- وما تزال الوكلاءات العكسية loopback الموجودة على المضيف نفسه لا تستوفي مصادقة trusted-proxy؛ راجع Trusted Proxy Auth
بناء UI
تقدّم Gateway ملفات ثابتة منdist/control-ui. ابنِها باستخدام:
ws://127.0.0.1:18789).
التصحيح/الاختبار: خادم تطوير + Gateway بعيد
واجهة التحكم عبارة عن ملفات ثابتة؛ وهدف WebSocket قابل للتهيئة ويمكن أن يكون مختلفًا عن أصل HTTP. وهذا مفيد عندما تريد خادم تطوير Vite محليًا لكن Gateway تعمل في مكان آخر.- ابدأ خادم تطوير UI:
pnpm ui:dev - افتح عنوان URL مثل:
- يتم تخزين
gatewayUrlفي localStorage بعد التحميل وإزالته من عنوان URL. - يجب تمرير
tokenعبر جزء URL (#token=...) كلما أمكن. لا تُرسل الأجزاء إلى الخادم، ما يتجنب تسربها في سجلات الطلبات وReferer. وما تزال معلمات الاستعلام القديمة?token=تُستورد مرة واحدة من أجل التوافق، لكن كخيار رجوع فقط، وتُزال مباشرةً بعد الإقلاع. - يُحتفَظ بـ
passwordفي الذاكرة فقط. - عندما يكون
gatewayUrlمضبوطًا، لا يعود UI إلى بيانات الاعتماد الموجودة في الإعدادات أو البيئة. قدّمtoken(أوpassword) صراحةً. ويُعد غياب بيانات اعتماد صريحة خطأ. - استخدم
wss://عندما تكون Gateway خلف TLS (Tailscale Serve أو وكيل HTTPS أو ما شابه). - لا يُقبل
gatewayUrlإلا في نافذة من المستوى الأعلى (غير مضمنة) لمنع clickjacking. - يجب أن تضبط عمليات نشر واجهة التحكم غير loopback قيمة
gateway.controlUi.allowedOriginsصراحةً (كأصول كاملة). ويشمل ذلك إعدادات التطوير البعيد. - لا تستخدم
gateway.controlUi.allowedOrigins: ["*"]إلا للاختبار المحلي المحكوم بإحكام. فهي تعني السماح لأي أصل متصفح، لا “مطابقة أي مضيف أستخدمه”. - يفعّل
gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=trueوضع الرجوع إلى الأصل عبر Host-header، لكنه وضع أمني خطير.
ذو صلة
- لوحة المعلومات — لوحة معلومات gateway
- WebChat — واجهة دردشة معتمدة على المتصفح
- TUI — واجهة مستخدم طرفية
- فحوصات الصحة — مراقبة صحة gateway