Gateway
پروتکل Gateway
پروتکل Gateway WS، صفحهٔ کنترل واحد + انتقال Node برای OpenClaw است. همهٔ کلاینتها (CLI، رابط کاربری وب، برنامهٔ macOS، Nodeهای iOS/Android، Nodeهای بدون سر) از طریق WebSocket متصل میشوند و در زمان دستدهی، نقش + دامنهٔ خود را اعلام میکنند.
انتقال
- WebSocket، فریمهای متنی با payloadهای JSON.
- نخستین فریم باید یک درخواست
connectباشد. - فریمهای پیش از اتصال به 64 KiB محدود میشوند. پس از یک دستدهی موفق، کلاینتها
باید از محدودیتهای
hello-ok.policy.maxPayloadوhello-ok.policy.maxBufferedBytesپیروی کنند. با فعال بودن عیبیابی، فریمهای ورودی بیشازحد بزرگ و بافرهای خروجی کند، پیش از آنکه gateway فریم متأثر را ببندد یا حذف کند، رویدادهایpayload.largeمنتشر میکنند. این رویدادها اندازهها، محدودیتها، سطحها، و کدهای دلیل امن را نگه میدارند. آنها بدنهٔ پیام، محتوای پیوست، بدنهٔ خام فریم، توکنها، کوکیها، یا مقادیر محرمانه را نگه نمیدارند.
دستدهی (connect)
Gateway → کلاینت (چالش پیش از اتصال):
{ "type": "event", "event": "connect.challenge", "payload": { "nonce": "…", "ts": 1737264000000 }}کلاینت → Gateway:
{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "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 → کلاینت:
{ "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 } }}در حالی که Gateway هنوز در حال کامل کردن sidecarهای راهاندازی است، درخواست connect میتواند
یک خطای قابل تلاش دوبارهٔ UNAVAILABLE برگرداند که details.reason آن روی
"startup-sidecars" و retryAfterMs تنظیم شده است. کلاینتها باید آن پاسخ را
در چارچوب بودجهٔ کلی اتصال خود دوباره تلاش کنند، نه اینکه آن را بهعنوان شکست نهایی
دستدهی نمایش دهند.
server، features، snapshot، و policy همگی توسط schema
(src/gateway/protocol/schema/frames.ts) الزامی هستند. auth نیز الزامی است و
نقش/دامنههای مذاکرهشده را گزارش میکند. pluginSurfaceUrls اختیاری است و نامهای
سطح Plugin، مانند canvas، را به URLهای میزبانیشدهٔ دارای دامنه نگاشت میکند.
URLهای سطح Plugin دارای دامنه ممکن است منقضی شوند. Nodeها میتوانند
node.pluginSurface.refresh را با { "surface": "canvas" } فراخوانی کنند تا یک
ورودی تازه در pluginSurfaceUrls دریافت کنند. بازسازی آزمایشی Canvas plugin از مسیر
سازگاری منسوخشدهٔ canvasHostUrl، canvasCapability، یا
node.canvas.capability.refresh پشتیبانی نمیکند؛ کلاینتهای بومی و gatewayهای فعلی
باید از سطحهای Plugin استفاده کنند.
وقتی هیچ توکن دستگاهی صادر نمیشود، hello-ok.auth مجوزهای مذاکرهشده را بدون
فیلدهای توکن گزارش میکند:
{ "auth": { "role": "operator", "scopes": ["operator.read", "operator.write"] }}کلاینتهای backend مورداعتمادِ همان فرایند (client.id: "gateway-client"،
client.mode: "backend") میتوانند در اتصالهای مستقیم loopback، وقتی با توکن/گذرواژهٔ
مشترک gateway احراز هویت میکنند، device را حذف کنند. این مسیر برای RPCهای داخلی
صفحهٔ کنترل رزرو شده است و baselineهای قدیمی جفتسازی CLI/دستگاه را از مسدود کردن
کار backend محلی، مانند بهروزرسانیهای نشست subagent، بازمیدارد. کلاینتهای راهدور،
کلاینتهای با خاستگاه مرورگر، کلاینتهای Node، و کلاینتهای صریحِ دارای توکن دستگاه/هویت دستگاه
همچنان از بررسیهای عادی جفتسازی و ارتقای دامنه استفاده میکنند.
وقتی یک توکن دستگاه صادر میشود، hello-ok همچنین شامل این موارد است:
{ "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] }}در طول واگذاری bootstrap مورداعتماد، hello-ok.auth همچنین ممکن است شامل ورودیهای
نقش محدودشدهٔ اضافی در deviceTokens باشد:
{ "auth": { "deviceToken": "…", "role": "node", "scopes": [], "deviceTokens": [ { "deviceToken": "…", "role": "operator", "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"] } ] }}برای جریان bootstrap داخلی Node/operator، توکن اصلی Node بهصورت
scopes: [] باقی میماند و هر توکن operator واگذارشده به allowlist اپراتور bootstrap
(operator.approvals، operator.read،
operator.talk.secrets، operator.write) محدود میماند. بررسیهای دامنهٔ bootstrap
همچنان با پیشوند نقش میمانند: ورودیهای operator فقط درخواستهای operator را برآورده
میکنند، و نقشهای غیر-operator همچنان به دامنههایی زیر پیشوند نقش خود نیاز دارند.
نمونهٔ Node
{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "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": "…" } }}فریمبندی
- درخواست:
{type:"req", id, method, params} - پاسخ:
{type:"res", id, ok, payload|error} - رویداد:
{type:"event", event, payload, seq?, stateVersion?}
متدهای دارای اثر جانبی به کلیدهای idempotency نیاز دارند (schema را ببینید).
نقشها + دامنهها
برای مدل کامل دامنهٔ operator، بررسیهای زمان تأیید، و معنای shared-secret، دامنههای Operator را ببینید.
نقشها
operator= کلاینت صفحهٔ کنترل (CLI/UI/خودکارسازی).node= میزبان قابلیت (camera/screen/canvas/system.run).
دامنهها (operator)
دامنههای رایج:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config با includeSecrets: true به operator.talk.secrets
(یا operator.admin) نیاز دارد.
متدهای RPC gateway ثبتشده توسط Plugin ممکن است دامنهٔ operator خودشان را درخواست کنند، اما
پیشوندهای admin هستهٔ رزروشده (config.*، exec.approvals.*، wizard.*،
update.*) همیشه به operator.admin resolve میشوند.
دامنهٔ متد فقط نخستین gate است. برخی دستورهای slash که از طریق
chat.send میرسند، بررسیهای سختگیرانهتر در سطح دستور را نیز اعمال میکنند. برای مثال، نوشتنهای ماندگار
/config set و /config unset به operator.admin نیاز دارند.
node.pair.approve همچنین علاوه بر دامنهٔ پایهٔ متد، یک بررسی دامنهٔ اضافی در زمان تأیید دارد:
- درخواستهای بدون دستور:
operator.pairing - درخواستهایی با دستورهای Node غیر-exec:
operator.pairing+operator.write - درخواستهایی که شامل
system.run،system.run.prepare، یاsystem.whichهستند:operator.pairing+operator.admin
Caps/commands/permissions (node)
Nodeها در زمان اتصال ادعاهای قابلیت را اعلام میکنند:
caps: دستههای قابلیت سطح بالا مانندcamera،canvas،screen،location،voice، وtalk.commands: allowlist دستور برای invoke.permissions: toggleهای جزئی (مثلاًscreen.record،camera.capture).
Gateway با این موارد بهعنوان ادعا رفتار میکند و allowlistهای سمت سرور را اعمال میکند.
Presence
system-presenceورودیهایی با کلید هویت دستگاه برمیگرداند.- ورودیهای Presence شامل
deviceId،roles، وscopesهستند تا UIها بتوانند برای هر دستگاه یک ردیف واحد نشان دهند حتی وقتی هم بهعنوان operator و هم node متصل میشود. node.listشامل فیلدهای اختیاریlastSeenAtMsوlastSeenReasonاست. Nodeهای متصل زمان اتصال فعلی خود را بهعنوانlastSeenAtMsبا دلیلconnectگزارش میکنند؛ Nodeهای جفتشده همچنین میتوانند وقتی یک رویداد Node مورداعتماد metadata جفتسازی آنها را بهروزرسانی میکند، presence پسزمینهٔ پایدار گزارش کنند.
رویداد زنده بودن پسزمینهٔ Node
Nodeها میتوانند node.event را با event: "node.presence.alive" فراخوانی کنند تا ثبت کنند که یک Node جفتشده
در طول wake پسزمینه زنده بوده است، بدون اینکه آن را متصل علامتگذاری کنند.
{ "event": "node.presence.alive", "payloadJSON": "{\"trigger\":\"silent_push\",\"sentAtMs\":1737264000000,\"displayName\":\"Peter's iPhone\",\"version\":\"2026.4.28\",\"platform\":\"iOS 18.4.0\",\"deviceFamily\":\"iPhone\",\"modelIdentifier\":\"iPhone17,1\",\"pushTransport\":\"relay\"}"}trigger یک enum بسته است: background، silent_push، bg_app_refresh،
significant_location، manual، یا connect. رشتههای trigger ناشناخته پیش از persistence
توسط gateway به background نرمالسازی میشوند. این رویداد فقط برای نشستهای دستگاه Node احرازشده
پایدار است؛ نشستهای بدون دستگاه یا جفتنشده handled: false برمیگردانند.
gatewayهای موفق یک نتیجهٔ ساختاریافته برمیگردانند:
{ "ok": true, "event": "node.presence.alive", "handled": true, "reason": "persisted"}gatewayهای قدیمیتر ممکن است همچنان { "ok": true } را برای node.event برگردانند؛ کلاینتها باید آن را
یک RPC تأییدشده تلقی کنند، نه persistence پایدار presence.
دامنهبندی رویدادهای broadcast
رویدادهای broadcast WebSocket که از سرور push میشوند با دامنه gate میشوند تا نشستهای دارای دامنهٔ pairing یا فقط-Node، محتوای نشست را بهصورت منفعلانه دریافت نکنند.
- فریمهای chat، agent، و نتیجهٔ ابزار (شامل رویدادهای streamشدهٔ
agentو نتایج فراخوانی ابزار) حداقل بهoperator.readنیاز دارند. نشستهای بدونoperator.readاین فریمها را کاملاً رد میکنند. - broadcastهای
plugin.*تعریفشده توسط Plugin بسته به اینکه Plugin آنها را چگونه ثبت کرده باشد، بهoperator.writeیاoperator.adminمحدود میشوند. - رویدادهای وضعیت و انتقال (
heartbeat،presence،tick، چرخهٔ عمر اتصال/قطع اتصال، و غیره) بدون محدودیت میمانند تا سلامت انتقال برای هر نشست احرازشده قابل مشاهده بماند. - خانوادههای ناشناختهٔ رویداد broadcast بهصورت پیشفرض با دامنه gate میشوند (fail-closed)، مگر اینکه یک handler ثبتشده صراحتاً آنها را آزادتر کند.
هر اتصال کلاینت شمارهٔ sequence مختص خود را نگه میدارد تا broadcastها ترتیب یکنواخت را روی آن socket حفظ کنند، حتی وقتی کلاینتهای مختلف زیرمجموعههای متفاوتِ فیلترشده بر اساس دامنه از جریان رویداد را میبینند.
خانوادههای رایج متد RPC
سطح عمومی WS گستردهتر از نمونههای handshake/auth بالا است. این
یک dump تولیدشده نیست — hello-ok.features.methods یک فهرست discovery محافظهکارانه است
که از src/gateway/server-methods-list.ts بهعلاوهٔ exportهای متد Plugin/channel بارگذاریشده ساخته میشود.
با آن بهعنوان feature discovery رفتار کنید، نه یک فهرست کامل از
src/gateway/server-methods/*.ts.
سیستم و هویت
healthsnapshot سلامت gateway را که cache شده یا تازه probe شده است برمیگرداند.diagnostics.stabilityضبطکنندهٔ stability تشخیصی محدود اخیر را برمیگرداند. این مورد metadata عملیاتی مانند نام رویدادها، تعدادها، اندازههای بایت، خوانشهای حافظه، وضعیت queue/session، نامهای channel/plugin، و شناسههای session را نگه میدارد. متن chat، بدنههای webhook، خروجیهای ابزار، بدنههای خام درخواست یا پاسخ، توکنها، کوکیها، یا مقادیر محرمانه را نگه نمیدارد. دامنهٔ خواندن Operator لازم است.statusخلاصهٔ gateway به سبک/statusرا برمیگرداند؛ فیلدهای حساس فقط برای کلاینتهای operator دارای دامنهٔ admin گنجانده میشوند.gateway.identity.getهویت دستگاه gateway را که توسط جریانهای relay و pairing استفاده میشود برمیگرداند.system-presencesnapshot فعلی presence برای دستگاههای operator/node متصل را برمیگرداند.system-eventیک رویداد system اضافه میکند و میتواند زمینهٔ presence را بهروزرسانی/broadcast کند.last-heartbeatتازهترین رویداد heartbeat پایدارشده را برمیگرداند.set-heartbeatsپردازش heartbeat را روی gateway روشن/خاموش میکند.
مدلها و استفاده
models.listفهرست مدلهای مجاز در زمان اجرا را برمیگرداند. برای مدلهای پیکربندیشده در اندازه انتخابگر (agents.defaults.modelsابتدا، سپسmodels.providers.*.models) مقدار{ "view": "configured" }را ارسال کنید، یا برای فهرست کامل مقدار{ "view": "all" }را ارسال کنید.usage.statusپنجرههای استفاده ارائهدهنده/خلاصههای سهمیه باقیمانده را برمیگرداند.usage.costخلاصههای تجمیعشده هزینه استفاده را برای یک بازه تاریخی برمیگرداند.doctor.memory.statusآمادگی حافظه برداری / embedding ذخیرهشده در کش را برای فضای کاری عامل پیشفرض فعال برمیگرداند. فقط زمانی{ "probe": true }یا{ "deep": true }را ارسال کنید که فراخواننده صراحتا یک ping زنده به ارائهدهنده embedding میخواهد.doctor.memory.remHarnessیک پیشنمایش محدود و فقطخواندنی از ابزار REM را برای کلاینتهای control-plane راهدور برمیگرداند. این میتواند مسیرهای فضای کاری، قطعههای حافظه، markdown زمینهمند رندرشده، و نامزدهای ارتقای عمیق را شامل شود، بنابراین فراخوانندهها بهoperator.readنیاز دارند.sessions.usageخلاصههای استفاده بهازای هر نشست را برمیگرداند.sessions.usage.timeseriesاستفاده سری زمانی را برای یک نشست برمیگرداند.sessions.usage.logsورودیهای گزارش استفاده را برای یک نشست برمیگرداند.
کانالها و راهنماهای ورود
channels.statusخلاصههای وضعیت کانال/Plugin داخلی + همراه را برمیگرداند.channels.logoutاز یک کانال/حساب مشخص، در جایی که کانال از خروج پشتیبانی میکند، خارج میشود.web.login.startجریان ورود QR/web را برای ارائهدهنده کانال وب فعلی که قابلیت QR دارد آغاز میکند.web.login.waitمنتظر تکمیل همان جریان ورود QR/web میماند و در صورت موفقیت کانال را شروع میکند.push.testیک اعلان آزمایشی APNs را به یک Node ثبتشده iOS میفرستد.voicewake.getمحرکهای ذخیرهشده واژه بیدارباش را برمیگرداند.voicewake.setمحرکهای واژه بیدارباش را بهروزرسانی میکند و تغییر را پخش میکند.
پیامرسانی و گزارشها
sendفراخوانی RPC مستقیم تحویل خروجی برای ارسالهای هدفگیریشده بر اساس کانال/حساب/رشته در خارج از اجراکننده چت است.logs.tailانتهای گزارش فایل پیکربندیشده Gateway را همراه با کنترلهای cursor/limit و حداکثر بایت برمیگرداند.
Talk و TTS
talk.catalogفهرست فقطخواندنی ارائهدهنده Talk را برای گفتار، رونویسی جریانی، و صدای realtime برمیگرداند. این شامل شناسههای ارائهدهنده، برچسبها، وضعیت پیکربندیشده، شناسههای مدل/صداهای در معرض، حالتهای کانونی، انتقالها، راهبردهای مغز، و پرچمهای صوتی/قابلیتی realtime است، بدون اینکه اسرار ارائهدهنده را برگرداند یا پیکربندی سراسری را تغییر دهد.talk.configبار داده پیکربندی موثر Talk را برمیگرداند؛includeSecretsبهoperator.talk.secrets(یاoperator.admin) نیاز دارد.talk.session.createیک نشست Talk تحت مالکیت Gateway برایrealtime/gateway-relay،transcription/gateway-relay، یاstt-tts/managed-roomایجاد میکند.brain: "direct-tools"بهoperator.adminنیاز دارد.talk.session.joinتوکن نشست managed-room را اعتبارسنجی میکند، رویدادهایsession.readyیاsession.replacedرا در صورت نیاز منتشر میکند، و فراداده اتاق/نشست بههمراه رویدادهای اخیر Talk را بدون توکن متن ساده یا هش توکن ذخیرهشده برمیگرداند.talk.session.appendAudioصدای ورودی PCM با base64 را به نشستهای realtime relay و رونویسی تحت مالکیت Gateway اضافه میکند.talk.session.startTurn،talk.session.endTurn، وtalk.session.cancelTurnچرخه عمر نوبت managed-room را با رد نوبتهای کهنه پیش از پاک شدن وضعیت هدایت میکنند.talk.session.cancelOutputخروجی صوتی دستیار را متوقف میکند، عمدتا برای مداخله کاربر مبتنی بر VAD در نشستهای Gateway relay.talk.session.submitToolResultفراخوانی ابزار ارائهدهنده را که توسط یک نشست realtime relay تحت مالکیت Gateway منتشر شده کامل میکند. برای خروجی موقت ابزار وقتی نتیجه نهایی بعدا میآید،options: { willContinue: true }را ارسال کنید، یا وقتی نتیجه ابزار باید فراخوانی ارائهدهنده را بدون آغاز پاسخ realtime دیگری از دستیار برآورده کند،options: { suppressResponse: true }را ارسال کنید.talk.session.closeیک نشست relay، رونویسی، یا managed-room تحت مالکیت Gateway را میبندد و رویدادهای پایانی Talk را منتشر میکند.talk.modeوضعیت حالت فعلی Talk را برای کلاینتهای WebChat/Control UI تنظیم/پخش میکند.talk.client.createیک نشست ارائهدهنده realtime تحت مالکیت کلاینت با استفاده ازwebrtcیاprovider-websocketایجاد میکند، در حالی که Gateway مالک پیکربندی، اعتبارنامهها، دستورالعملها، و سیاست ابزار است.talk.client.toolCallبه انتقالهای realtime تحت مالکیت کلاینت اجازه میدهد فراخوانیهای ابزار ارائهدهنده را به سیاست Gateway فوروارد کنند. اولین ابزار پشتیبانیشدهopenclaw_agent_consultاست؛ کلاینتها یک شناسه اجرا دریافت میکنند و پیش از ارسال نتیجه ابزار ویژه ارائهدهنده، منتظر رویدادهای معمول چرخه عمر چت میمانند.talk.eventکانال رویداد واحد Talk برای realtime، رونویسی، STT/TTS، managed-room، تلفن، و آداپتورهای جلسه است.talk.speakگفتار را از طریق ارائهدهنده گفتار فعال Talk تولید میکند.tts.statusوضعیت فعال بودن TTS، ارائهدهنده فعال، ارائهدهندگان fallback، و وضعیت پیکربندی ارائهدهنده را برمیگرداند.tts.providersفهرست ارائهدهندگان قابلمشاهده TTS را برمیگرداند.tts.enableوtts.disableوضعیت ترجیحات TTS را تغییر میدهند.tts.setProviderارائهدهنده ترجیحی TTS را بهروزرسانی میکند.tts.convertتبدیل یکباره متن به گفتار را اجرا میکند.
اسرار، پیکربندی، بهروزرسانی، و ویزارد
secrets.reloadSecretRefهای فعال را دوباره resolve میکند و وضعیت سری زمان اجرا را فقط در صورت موفقیت کامل جایگزین میکند.secrets.resolveتخصیصهای سری هدففرمان را برای یک مجموعه فرمان/هدف مشخص resolve میکند.config.getsnapshot و هش پیکربندی فعلی را برمیگرداند.config.setیک بار داده پیکربندی اعتبارسنجیشده را مینویسد.config.patchیک بهروزرسانی جزئی پیکربندی را ادغام میکند.config.applyکل بار داده پیکربندی را اعتبارسنجی + جایگزین میکند.config.schemaبار داده schema زنده پیکربندی را که توسط ابزارهای Control UI و CLI استفاده میشود برمیگرداند: schema،uiHints، نسخه، و فراداده تولید، از جمله فراداده schema مربوط به Plugin + کانال وقتی زمان اجرا بتواند آن را بارگیری کند. schema شامل فراداده فیلدهایtitle/descriptionاست که از همان برچسبها و متن راهنمای استفادهشده توسط UI استخراج شدهاند، از جمله شاخههای ترکیب شیء تودرتو، wildcard، آیتم آرایه، وanyOf/oneOf/allOfوقتی مستندات فیلد منطبق وجود دارد.config.schema.lookupیک بار داده lookup محدود به مسیر را برای یک مسیر پیکربندی برمیگرداند: مسیر نرمالشده، یک گره schema کمعمق، hint منطبق +hintPath، و خلاصههای فرزند بلافصل برای drill-down در UI/CLI. گرههای schema مربوط به lookup مستندات روبهکاربر و فیلدهای رایج اعتبارسنجی (title،description،type،enum،const،format،pattern، کرانهای عددی/رشتهای/آرایهای/شیء، و پرچمهایی مانندadditionalProperties،deprecated،readOnly،writeOnly) را نگه میدارند. خلاصههای فرزندkey،pathنرمالشده،type،required،hasChildren، بههمراهhint/hintPathمنطبق را آشکار میکنند.update.runجریان بهروزرسانی Gateway را اجرا میکند و فقط وقتی خود بهروزرسانی موفق شده باشد یک راهاندازی مجدد زمانبندی میکند؛ فراخوانندههایی که نشست دارند میتوانندcontinuationMessageرا شامل کنند تا هنگام شروع، یک نوبت پیگیری عامل از طریق صف ادامه پس از راهاندازی مجدد از سر گرفته شود. بهروزرسانیهای مدیر بسته پس از جایگزینی بسته، یک راهاندازی مجدد بهروزرسانی غیربهتعویقافتاده و بدون cooldown را اجباری میکنند تا فرایند Gateway قدیمی از یک درختdistجایگزینشده به بارگذاری تنبل ادامه ندهد.update.statusآخرین sentinel ذخیرهشده در کش مربوط به راهاندازی مجدد بهروزرسانی را برمیگرداند، از جمله نسخه در حال اجرا پس از راهاندازی مجدد، وقتی در دسترس باشد.wizard.start،wizard.next،wizard.status، وwizard.cancelویزارد onboarding را از طریق WS RPC در معرض میگذارند.
راهنماهای عامل و فضای کاری
agents.listورودیهای عامل پیکربندیشده را، از جمله مدل موثر و فراداده زمان اجرا، برمیگرداند.agents.create،agents.update، وagents.deleteرکوردهای عامل و اتصال فضای کاری را مدیریت میکنند.agents.files.list،agents.files.get، وagents.files.setفایلهای فضای کاری bootstrap را که برای یک عامل در معرض قرار گرفتهاند مدیریت میکنند.tasks.list،tasks.get، وtasks.cancelدفتر وظایف Gateway را برای کلاینتهای SDK و اپراتور در معرض میگذارند.artifacts.list،artifacts.get، وartifacts.downloadخلاصهها و دانلودهای artifact استخراجشده از transcript را برای دامنه صریحsessionKey،runId، یاtaskIdدر معرض میگذارند. پرسوجوهای اجرا و وظیفه، نشست مالک را سمت سرور resolve میکنند و فقط رسانه transcript با provenance منطبق را برمیگردانند؛ منابع URL ناامن یا محلی بهجای واکشی سمت سرور، دانلودهای پشتیبانینشده برمیگردانند.environments.listوenvironments.statusکشف فقطخواندنی محیطهای محلی Gateway و Node را برای کلاینتهای SDK در معرض میگذارند.agent.identity.getهویت موثر دستیار را برای یک عامل یا نشست برمیگرداند.agent.waitمنتظر پایان یک اجرا میماند و در صورت دسترس بودن، snapshot پایانی را برمیگرداند.
کنترل نشست
sessions.listفهرست نشست فعلی را برمیگرداند، از جمله فرادادهagentRuntimeبهازای هر ردیف وقتی backend زمان اجرای عامل پیکربندی شده باشد.sessions.subscribeوsessions.unsubscribeاشتراکهای رویداد تغییر نشست را برای کلاینت WS فعلی تغییر میدهند.sessions.messages.subscribeوsessions.messages.unsubscribeاشتراکهای رویداد transcript/پیام را برای یک نشست تغییر میدهند.sessions.previewپیشنمایشهای محدود transcript را برای کلیدهای نشست مشخص برمیگرداند.sessions.describeیک ردیف نشست Gateway را برای یک کلید نشست دقیق برمیگرداند.sessions.resolveیک هدف نشست را resolve یا canonicalize میکند.sessions.createیک ورودی نشست جدید ایجاد میکند.sessions.sendیک پیام را به یک نشست موجود میفرستد.sessions.steerگونه interrupt-and-steer برای یک نشست فعال است.sessions.abortکار فعال را برای یک نشست لغو میکند. فراخواننده میتواندkeyبههمراهrunIdاختیاری را ارسال کند، یا برای اجراهای فعالی که Gateway میتواند به یک نشست resolve کند، فقطrunIdرا ارسال کند.sessions.patchفراداده/overrideهای نشست را بهروزرسانی میکند و مدل canonical resolveشده بههمراهagentRuntimeموثر را گزارش میدهد.sessions.reset،sessions.delete، وsessions.compactنگهداری نشست را انجام میدهند.sessions.getکل ردیف نشست ذخیرهشده را برمیگرداند.- اجرای چت همچنان از
chat.history،chat.send،chat.abort، وchat.injectاستفاده میکند.chat.historyبرای کلاینتهای UI بهصورت نرمالشده برای نمایش است: تگهای directive درونخطی از متن قابلمشاهده حذف میشوند، بارهای XML متن ساده فراخوانی ابزار (از جمله<tool_call>...</tool_call>،<function_call>...</function_call>،<tool_calls>...</tool_calls>،<function_calls>...</function_calls>، و بلوکهای کوتاهشده فراخوانی ابزار) و توکنهای کنترلی مدل ASCII/تمامعرضِ نشتکرده حذف میشوند، ردیفهای دستیار با توکن کاملا خاموش مانندNO_REPLY/no_replyدقیق حذف میشوند، و ردیفهای بیشازحد بزرگ میتوانند با placeholderها جایگزین شوند.
جفتسازی دستگاه و توکنهای دستگاه
device.pair.listدستگاههای جفتشده در انتظار و تاییدشده را برمیگرداند.device.pair.approve،device.pair.reject، وdevice.pair.removeرکوردهای جفتسازی دستگاه را مدیریت میکنند.device.token.rotateیک توکن دستگاه جفتشده را در محدوده نقش تاییدشده و دامنه فراخواننده آن چرخش میدهد.device.token.revokeیک توکن دستگاه جفتشده را در محدوده نقش تاییدشده و دامنه فراخواننده آن لغو میکند.
جفتسازی Node، فراخوانی، و کار در انتظار
node.pair.request،node.pair.list،node.pair.approve،node.pair.reject،node.pair.remove، وnode.pair.verifyجفتسازی Node و اعتبارسنجی bootstrap را پوشش میدهند.node.listوnode.describeوضعیت Nodeهای شناختهشده/متصل را برمیگردانند.node.renameبرچسب یک Node جفتشده را بهروزرسانی میکند.node.invokeیک فرمان را به یک Node متصل فوروارد میکند.node.invoke.resultنتیجه یک درخواست invoke را برمیگرداند.node.eventرویدادهای منشأگرفته از Node را به Gateway بازمیگرداند.node.pending.pullوnode.pending.ackAPIهای صف Node متصل هستند.node.pending.enqueueوnode.pending.drainکار در انتظار پایدار را برای Nodeهای آفلاین/قطعشده مدیریت میکنند.
خانوادههای تأیید
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 را از طریق فرمانهای relay 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کارهای زمانبندیشده را مدیریت میکنند. - Skills و ابزارها:
commands.list،skills.*،tools.catalog،tools.effective،tools.invoke.
خانوادههای رویداد رایج
chat: بهروزرسانیهای چت UI مانندchat.injectو سایر رویدادهای چت فقط مخصوص رونوشت.session.messageوsession.tool: بهروزرسانیهای رونوشت/جریان رویداد برای یک نشست مشترکشده.sessions.changed: نمایه نشست یا فراداده تغییر کرده است.presence: بهروزرسانیهای اسنپشات حضور سیستم.tick: رویداد دورهای keepalive / زندهبودن.health: بهروزرسانی اسنپشات سلامت Gateway.heartbeat: بهروزرسانی جریان رویداد Heartbeat.cron: رویداد تغییر اجرای cron/کار.shutdown: اعلان خاموشسازی Gateway.node.pair.requested/node.pair.resolved: چرخه عمر جفتسازی Node.node.invoke.request: پخش درخواست invoke در Node.device.pair.requested/device.pair.resolved: چرخه عمر دستگاه جفتشده.voicewake.changed: پیکربندی محرک واژه بیدارباش تغییر کرده است.exec.approval.requested/exec.approval.resolved: چرخه عمر تأیید اجرا.plugin.approval.requested/plugin.approval.resolved: چرخه عمر تأیید plugin.
متدهای کمکی Node
- Nodeها میتوانند برای واکشی فهرست فعلی فایلهای اجرایی skill
جهت بررسیهای auto-allow،
skills.binsرا فراخوانی کنند.
RPCهای دفتر کل وظایف
کلاینتهای عملگر میتوانند رکوردهای وظایف پسزمینه Gateway را از طریق RPCهای دفتر کل وظایف بررسی و لغو کنند. این متدها خلاصههای پاکسازیشده وظایف را برمیگردانند، نه وضعیت خام زمان اجرا را.
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 }. - شناسههای وظیفه ناموجود، قالب خطای not-found 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، زمانمُهرها، پیشرفت،
خلاصه پایانی، و متن خطای پاکسازیشده است.
متدهای کمکی عملگر
- عملگرها میتوانند برای واکشی موجودی فرمانهای زمان اجرا برای یک agent،
commands.list(operator.read) را فراخوانی کنند.agentIdاختیاری است؛ برای خواندن فضای کاری agent پیشفرض، آن را حذف کنید.scopeکنترل میکند کهnameاصلی کدام سطح را هدف بگیرد:textتوکن فرمان متنی اصلی را بدون/ابتدایی برمیگرداندnativeو مسیر پیشفرضbothدر صورت موجود بودن، نامهای native آگاه از provider را برمیگردانند
textAliasesنامهای مستعار دقیق slash مانند/modelو/mرا حمل میکند.nativeNameدر صورت وجود، نام فرمان native آگاه از provider را حمل میکند.providerاختیاری است و فقط بر نامگذاری native بهعلاوه دسترسپذیری فرمان plugin native اثر میگذارد.includeArgs=falseفراداده آرگومان سریالشده را از پاسخ حذف میکند.
- عملگرها میتوانند برای واکشی کاتالوگ ابزار زمان اجرا برای یک
agent،
tools.catalog(operator.read) را فراخوانی کنند. پاسخ شامل ابزارهای گروهبندیشده و فراداده منشأ است:source:coreیاpluginpluginId: مالک plugin وقتیsource="plugin"optional: اینکه آیا ابزار plugin اختیاری است یا نه
- عملگرها میتوانند برای واکشی موجودی ابزار مؤثر در زمان اجرا
برای یک نشست،
tools.effective(operator.read) را فراخوانی کنند.sessionKeyالزامی است.- Gateway بهجای پذیرش احراز هویت یا زمینه تحویل ارائهشده توسط فراخواننده، زمینه زمان اجرای قابل اعتماد را از نشست در سمت سرور استخراج میکند.
- پاسخ محدود به نشست است و نشان میدهد گفتوگوی فعال همین حالا از چه چیزهایی میتواند استفاده کند، شامل ابزارهای core، plugin، و channel.
- عملگرها میتوانند برای فراخوانی یک ابزار در دسترس از طریق
همان مسیر سیاست Gateway مانند
/tools/invoke،tools.invoke(operator.write) را فراخوانی کنند.nameالزامی است.args،sessionKey،agentId،confirm، وidempotencyKeyاختیاری هستند.- اگر هر دو
sessionKeyوagentIdحاضر باشند، agent نشست resolveشده باید باagentIdمطابقت داشته باشد. - پاسخ یک envelope رو به SDK با فیلدهای
ok،toolName،outputاختیاری، وerrorهای تایپشده است. ردهای تأیید یا سیاست، بهجای دور زدن پایپلاین سیاست ابزار Gateway، در payload مقدارok:falseبرمیگردانند.
- عملگرها میتوانند برای واکشی موجودی skill قابل مشاهده
برای یک agent،
skills.status(operator.read) را فراخوانی کنند.agentIdاختیاری است؛ برای خواندن فضای کاری agent پیشفرض، آن را حذف کنید.- پاسخ شامل واجدشرایطبودن، نیازمندیهای مفقود، بررسیهای پیکربندی، و گزینههای نصب پاکسازیشده بدون افشای مقادیر خام secret است.
- عملگرها میتوانند برای فراداده کشف ClawHub،
skills.searchوskills.detail(operator.read) را فراخوانی کنند. - عملگرها میتوانند برای stage کردن یک آرشیو skill خصوصی
پیش از نصب آن،
skills.upload.begin،skills.upload.chunk، وskills.upload.commit(operator.admin) را فراخوانی کنند. این یک مسیر upload مدیریتی جداگانه برای کلاینتهای مورد اعتماد است، نه جریان عادی نصب skill از ClawHub، و بهصورت پیشفرض غیرفعال است مگر اینکهskills.install.allowUploadedArchivesفعال باشد.skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? })یک upload وابسته به همان slug و مقدار force ایجاد میکند.skills.upload.chunk({ uploadId, offset, dataBase64 })بایتها را در offset دقیق decodeشده اضافه میکند.skills.upload.commit({ uploadId, sha256? })اندازه نهایی و SHA-256 را تأیید میکند. commit فقط upload را نهایی میکند؛ skill را نصب نمیکند.- آرشیوهای skill uploadشده، آرشیوهای zip حاوی ریشه
SKILL.mdهستند. نام دایرکتوری داخلی آرشیو هرگز هدف نصب را انتخاب نمیکند.
- عملگرها میتوانند
skills.install(operator.admin) را در سه حالت فراخوانی کنند:- حالت ClawHub:
{ source: "clawhub", slug, version?, force? }یک پوشه skill را در دایرکتوریskills/فضای کاری agent پیشفرض نصب میکند. - حالت upload:
{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? }یک upload commitشده را در دایرکتوریskills/<slug>فضای کاری agent پیشفرض نصب میکند. مقدار slug و force باید با درخواست اصلیskills.upload.beginمطابقت داشته باشد. این حالت رد میشود مگر اینکهskills.install.allowUploadedArchivesفعال باشد. این تنظیم بر نصبهای ClawHub اثر نمیگذارد. - حالت نصبکننده Gateway:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }یک اقدام اعلامشدهmetadata.openclaw.installرا روی میزبان Gateway اجرا میکند.
- حالت ClawHub:
- عملگرها میتوانند
skills.update(operator.admin) را در دو حالت فراخوانی کنند:- حالت ClawHub یک slug رهگیریشده یا همه نصبهای رهگیریشده ClawHub را در فضای کاری agent پیشفرض بهروزرسانی میکند.
- حالت پیکربندی مقادیر
skills.entries.<skillKey>مانندenabled،apiKey، وenvرا patch میکند.
نماهای models.list
models.list یک پارامتر view اختیاری میپذیرد:
- حذفشده یا
"default": رفتار فعلی زمان اجرا. اگرagents.defaults.modelsپیکربندی شده باشد، پاسخ همان کاتالوگ مجاز است، شامل مدلهای کشفشده پویا برای ورودیهایprovider/*. در غیر این صورت، پاسخ کاتالوگ کامل Gateway است. "configured": رفتار در اندازه picker. اگرagents.defaults.modelsپیکربندی شده باشد، همچنان اولویت دارد، شامل کشف محدود به provider برای ورودیهایprovider/*. بدون allowlist، پاسخ از ورودیهای صریحmodels.providers.*.modelsاستفاده میکند و فقط وقتی هیچ ردیف مدل پیکربندیشدهای وجود نداشته باشد، به کاتالوگ کامل برمیگردد."all": کاتالوگ کامل Gateway، با دور زدنagents.defaults.models. از این برای عیبیابی و UIهای کشف استفاده کنید، نه pickerهای عادی مدل.
تأییدهای اجرا
- وقتی یک درخواست exec به تأیید نیاز داشته باشد، Gateway رویداد
exec.approval.requestedرا پخش میکند. - کلاینتهای عملگر با فراخوانی
exec.approval.resolveآن را resolve میکنند (به scopeoperator.approvalsنیاز دارد). - برای
host=node،exec.approval.requestباید شاملsystemRunPlanباشد (argv/cwd/rawCommand/فراداده نشست canonical). درخواستهای بدونsystemRunPlanرد میشوند. - پس از تأیید، فراخوانیهای forwardشده
node.invoke system.runهمانsystemRunPlancanonical را بهعنوان زمینه معتبر command/cwd/session دوباره استفاده میکنند. - اگر یک فراخواننده
command،rawCommand،cwd،agentId، یاsessionKeyرا بین آمادهسازی و forward نهاییsystem.runتأییدشده تغییر دهد، Gateway بهجای اعتماد به payload تغییریافته، اجرا را رد میکند.
fallback تحویل agent
- درخواستهای
agentمیتوانند برای درخواست تحویل خروجی،deliver=trueرا شامل شوند. bestEffortDeliver=falseرفتار سختگیرانه را حفظ میکند: هدفهای تحویل resolveنشده یا فقط داخلی،INVALID_REQUESTبرمیگردانند.bestEffortDeliver=trueوقتی هیچ مسیر قابل تحویل خارجی قابل resolve نباشد، fallback به اجرای فقط نشست را اجازه میدهد (برای مثال نشستهای internal/webchat یا پیکربندیهای چندکاناله مبهم).- نتایج نهایی
agentممکن است وقتی تحویل درخواست شده باشد،result.deliveryStatusرا شامل شوند و از همان وضعیتهایsent،suppressed،partial_failed، وfailedاستفاده کنند که برایopenclaw agent --json --deliverمستند شدهاند.
نسخهبندی
PROTOCOL_VERSIONدرsrc/gateway/protocol/version.tsقرار دارد.- کلاینتها
minProtocol+maxProtocolرا ارسال میکنند؛ سرور بازههایی را که پروتکل فعلی آن را شامل نشوند رد میکند. کلاینتهای native از کران پایین v3 استفاده میکنند تا کلاینتهای افزایشی v4 همچنان بتوانند به gatewayهای v3 برسند. - اسکیماها + مدلها از تعاریف TypeBox تولید میشوند:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
ثابتهای کلاینت
کلاینت مرجع در src/gateway/client.ts از این پیشفرضها استفاده میکند. مقادیر در
protocol v4 پایدارند و baseline مورد انتظار برای کلاینتهای شخص ثالث هستند.
| ثابت | پیشفرض | منبع |
|---|---|---|
PROTOCOL_VERSION |
4 |
src/gateway/protocol/version.ts |
MIN_CLIENT_PROTOCOL_VERSION |
3 |
src/gateway/protocol/version.ts |
| مهلت درخواست (برای هر RPC) | 30_000 میلیثانیه |
src/gateway/client.ts (requestTimeoutMs) |
| مهلت Preauth / connect-challenge | 15_000 میلیثانیه |
src/gateway/handshake-timeouts.ts (config/env میتواند بودجهٔ جفتشدهٔ سرور/کلاینت را افزایش دهد) |
| backoff اولیهٔ اتصال مجدد | 1_000 میلیثانیه |
src/gateway/client.ts (backoffMs) |
| حداکثر backoff اتصال مجدد | 30_000 میلیثانیه |
src/gateway/client.ts (scheduleReconnect) |
| محدودسازی fast-retry پس از بستن device-token | 250 میلیثانیه |
src/gateway/client.ts |
مهلت force-stop پیش از terminate() |
250 میلیثانیه |
FORCE_STOP_TERMINATE_GRACE_MS |
مهلت پیشفرض stopAndWait() |
1_000 میلیثانیه |
STOP_AND_WAIT_TIMEOUT_MS |
فاصلهٔ tick پیشفرض (پیش از hello-ok) |
30_000 میلیثانیه |
src/gateway/client.ts |
| بستن بهدلیل tick-timeout | کد 4000 وقتی سکوت از tickIntervalMs * 2 بیشتر شود |
src/gateway/client.ts |
MAX_PAYLOAD_BYTES |
25 * 1024 * 1024 (25 مگابایت) |
src/gateway/server-constants.ts |
سرور مقادیر مؤثر policy.tickIntervalMs، policy.maxPayload،
و policy.maxBufferedBytes را در hello-ok اعلام میکند؛ کلاینتها باید بهجای پیشفرضهای پیش از handshake، همان مقادیر را رعایت کنند.
احراز هویت
- احراز هویت Gateway با shared-secret، بسته به حالت احراز هویت پیکربندیشده، از
connect.params.auth.tokenیاconnect.params.auth.passwordاستفاده میکند. - حالتهای دارای هویت مانند Tailscale Serve
(
gateway.auth.allowTailscale: true) یاgateway.auth.mode: "trusted-proxy"غیر local loopback، بررسی احراز هویت connect را از headerهای درخواست برآورده میکنند، نه ازconnect.params.auth.*. - حالت private-ingress با
gateway.auth.mode: "none"احراز هویت connect با shared-secret را کاملاً رد میکند؛ این حالت را روی ورودی عمومی/نامطمئن در معرض دسترس قرار ندهید. - پس از pairing، Gateway یک device token صادر میکند که به role + scopes اتصال
محدود است. این مقدار در
hello-ok.auth.deviceTokenبرگردانده میشود و باید برای اتصالهای آینده توسط کلاینت پایدار ذخیره شود. - کلاینتها باید پس از هر connect موفق،
hello-ok.auth.deviceTokenاصلی را پایدار ذخیره کنند. - اتصال مجدد با آن device token ذخیرهشده باید مجموعه scope تأییدشدهٔ ذخیرهشده برای همان token را نیز دوباره استفاده کند. این کار دسترسی read/probe/status را که قبلاً اعطا شده حفظ میکند و مانع از آن میشود که اتصالهای مجدد بیصدا به scope ضمنی محدودترِ فقط admin فروبریزد.
- مونتاژ احراز هویت connect در سمت کلاینت (
selectConnectAuthدرsrc/gateway/client.ts):auth.passwordمستقل است و همیشه وقتی تنظیم شده باشد ارسال میشود.auth.tokenبه ترتیب اولویت پر میشود: ابتدا shared token صریح، سپسdeviceTokenصریح، سپس token ذخیرهشدهٔ per-device (کلیدشده باdeviceId+role).auth.bootstrapTokenفقط وقتی فرستاده میشود که هیچیک از موارد بالا به یکauth.tokenمنجر نشده باشد. shared token یا هر device token حلشدهای آن را سرکوب میکند.- ارتقای خودکار device token ذخیرهشده در retry تکمرحلهای
AUTH_TOKEN_MISMATCHفقط برای endpointهای مورد اعتماد مجاز است — loopback، یاwss://باtlsFingerprintپینشده.wss://عمومی بدون پینکردن واجد شرایط نیست.
- ورودیهای اضافی
hello-ok.auth.deviceTokens، tokenهای تحویل bootstrap هستند. فقط وقتی آنها را پایدار ذخیره کنید که connect از احراز هویت bootstrap روی transport مورد اعتماد مانندwss://یا pairing از نوع loopback/local استفاده کرده باشد. - اگر کلاینت یک
deviceTokenصریح یاscopesصریح ارائه کند، آن مجموعه scope درخواستشده توسط فراخواننده همچنان مرجع است؛ scopeهای کششده فقط وقتی دوباره استفاده میشوند که کلاینت در حال استفادهٔ دوباره از token ذخیرهشدهٔ per-device باشد. - device tokenها را میتوان از طریق
device.token.rotateوdevice.token.revokeچرخاند/لغو کرد (نیازمند scopeoperator.pairing). device.token.rotateفرادادهٔ چرخش را برمیگرداند. token bearer جایگزین را فقط برای فراخوانیهای same-device که از قبل با همان device token احراز هویت شدهاند بازتاب میدهد، تا کلاینتهای token-only بتوانند جایگزین خود را پیش از اتصال مجدد پایدار ذخیره کنند. چرخشهای shared/admin، bearer token را بازتاب نمیدهند.- صدور، چرخش، و لغو token به مجموعه role تأییدشدهای محدود میماند که در ورودی pairing همان دستگاه ثبت شده است؛ تغییر token نمیتواند role دستگاهی را گسترش دهد یا هدف بگیرد که تأیید pairing هرگز اعطا نکرده است.
- برای sessionهای token دستگاه paired، مدیریت دستگاه self-scoped است مگر اینکه
فراخواننده
operator.adminنیز داشته باشد: فراخوانندگان غیر admin فقط میتوانند ورودی دستگاه خودشان را حذف/لغو/rotate کنند. device.token.rotateوdevice.token.revokeهمچنین مجموعه scope token اپراتور هدف را در برابر scopeهای session فعلی فراخواننده بررسی میکنند. فراخوانندگان غیر admin نمیتوانند token اپراتوری گستردهتر از آنچه خودشان دارند rotate یا revoke کنند.- شکستهای احراز هویت شامل
error.details.codeبههمراه راهنماییهای بازیابی هستند:error.details.canRetryWithDeviceToken(boolean)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- رفتار کلاینت برای
AUTH_TOKEN_MISMATCH:- کلاینتهای مورد اعتماد میتوانند یک retry محدود با token کششدهٔ per-device انجام دهند.
- اگر آن retry شکست خورد، کلاینتها باید حلقههای اتصال مجدد خودکار را متوقف کنند و راهنمای اقدام اپراتور را نمایش دهند.
AUTH_SCOPE_MISMATCHیعنی device token شناسایی شده، اما role/scopes درخواستشده را پوشش نمیدهد. کلاینتها نباید این را بهعنوان token بد نشان دهند؛ از اپراتور بخواهید دوباره pair کند یا قرارداد scope محدودتر/گستردهتر را تأیید کند.
هویت دستگاه + pairing
- Nodeها باید یک هویت دستگاه پایدار (
device.id) داشته باشند که از اثرانگشت keypair مشتق شده است. - Gatewayها token را بهازای هر دستگاه + role صادر میکنند.
- تأییدهای pairing برای شناسههای دستگاه جدید لازم است، مگر اینکه auto-approval محلی فعال باشد.
- auto-approval برای pairing حول اتصالهای مستقیم local loopback متمرکز است.
- OpenClaw همچنین یک مسیر self-connect محدودِ backend/container-local برای جریانهای کمکی shared-secret مورد اعتماد دارد.
- اتصالهای same-host tailnet یا LAN همچنان برای pairing بهعنوان remote در نظر گرفته میشوند و نیازمند تأیید هستند.
- کلاینتهای WS معمولاً هویت
deviceرا هنگامconnectشامل میکنند (operator + node). تنها استثناهای اپراتور بدون دستگاه، مسیرهای اعتماد صریح هستند:gateway.controlUi.allowInsecureAuth=trueبرای سازگاری HTTP ناامن فقط روی localhost.- احراز هویت موفق operator Control UI با
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(break-glass، کاهش شدید امنیت).- RPCهای backend مستقیم از نوع loopback با
gateway-clientکه با token/password مشترک Gateway احراز هویت شدهاند.
- همهٔ اتصالها باید nonce مربوط به
connect.challengeارائهشده توسط سرور را امضا کنند.
عیبیابی مهاجرت احراز هویت دستگاه
برای کلاینتهای قدیمی که هنوز از رفتار امضای پیش از 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 |
payload امضا با payload v2 تطابق ندارد. |
device signature expired |
DEVICE_AUTH_SIGNATURE_EXPIRED |
device-signature-stale |
timestamp امضاشده بیرون از skew مجاز است. |
device identity mismatch |
DEVICE_AUTH_DEVICE_ID_MISMATCH |
device-id-mismatch |
device.id با اثرانگشت public key مطابقت ندارد. |
device public key invalid |
DEVICE_AUTH_PUBLIC_KEY_INVALID |
device-public-key |
قالب/canonicalization مربوط به public key شکست خورده است. |
هدف مهاجرت:
- همیشه منتظر
connect.challengeبمانید. - payload نسخه v2 را که شامل nonce سرور است امضا کنید.
- همان nonce را در
connect.params.device.nonceارسال کنید. - payload امضای ترجیحی
v3است که افزون بر فیلدهای device/client/role/scopes/token/nonce،platformوdeviceFamilyرا نیز bind میکند. - امضاهای قدیمی
v2برای سازگاری همچنان پذیرفته میشوند، اما pinning فرادادهٔ paired-device همچنان سیاست command را در اتصال مجدد کنترل میکند.
TLS + pinning
- TLS برای اتصالهای WS پشتیبانی میشود.
- کلاینتها میتوانند بهصورت اختیاری اثرانگشت گواهی Gateway را pin کنند (به config
gateway.tlsبههمراهgateway.remote.tlsFingerprintیا CLI--tls-fingerprintمراجعه کنید).
دامنه
این protocol API کامل Gateway را در معرض دسترس قرار میدهد (status، channels، models، chat،
agent، sessions، nodes، approvals، و غیره). سطح دقیق توسط schemaهای TypeBox در
src/gateway/protocol/schema.ts تعریف شده است.