โปรโตคอล Gateway WS คือ control plane + การขนส่งของ Node เดียว สำหรับ OpenClaw ไคลเอนต์ทั้งหมด (CLI, UI บนเว็บ, แอป macOS, Node iOS/Android, Node แบบ headless) เชื่อมต่อผ่าน WebSocket และประกาศ บทบาท + ขอบเขต ของตนในช่วง handshakeDocumentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
การขนส่ง
- WebSocket, เฟรมข้อความพร้อม payload แบบ JSON
- เฟรมแรก ต้อง เป็นคำขอ
connect - เฟรมก่อน connect จำกัดไว้ที่ 64 KiB หลังจาก handshake สำเร็จ ไคลเอนต์
ควรทำตามขีดจำกัด
hello-ok.policy.maxPayloadและhello-ok.policy.maxBufferedBytesเมื่อเปิดใช้งาน diagnostics เฟรมขาเข้าที่มีขนาดเกินกำหนดและบัฟเฟอร์ขาออกที่ช้าจะปล่อยเหตุการณ์payload.largeก่อนที่ gateway จะปิดหรือทิ้งเฟรมที่ได้รับผลกระทบ เหตุการณ์เหล่านี้เก็บ ขนาด ขีดจำกัด surface และรหัสเหตุผลที่ปลอดภัย ไม่เก็บเนื้อหาข้อความ เนื้อหาไฟล์แนบ เนื้อหาเฟรมดิบ token, cookie หรือค่าลับ
Handshake (connect)
Gateway → ไคลเอนต์ (challenge ก่อน connect):connect อาจ
ส่งคืนข้อผิดพลาด UNAVAILABLE ที่ลองใหม่ได้ โดยตั้งค่า details.reason เป็น
"startup-sidecars" พร้อม retryAfterMs ไคลเอนต์ควรลอง response นั้นใหม่
ภายในงบประมาณการเชื่อมต่อโดยรวม แทนที่จะแสดงเป็นความล้มเหลวของ
handshake ขั้นสุดท้าย
server, features, snapshot และ policy ทั้งหมดเป็นข้อมูลที่ schema
กำหนดให้มี (src/gateway/protocol/schema/frames.ts) auth ก็จำเป็นเช่นกันและรายงาน
บทบาท/ขอบเขตที่เจรจาได้ pluginSurfaceUrls เป็นตัวเลือก และแมปชื่อ surface ของ Plugin
เช่น canvas ไปยัง URL ที่โฮสต์แบบมีขอบเขต
URL surface ของ Plugin แบบมีขอบเขตอาจหมดอายุได้ Node สามารถเรียก
node.pluginSurface.refresh ด้วย { "surface": "canvas" } เพื่อรับรายการใหม่ใน
pluginSurfaceUrls การ refactor Plugin Canvas แบบทดลองไม่รองรับเส้นทางความเข้ากันได้
canvasHostUrl, canvasCapability หรือ
node.canvas.capability.refresh ที่เลิกใช้แล้ว ไคลเอนต์ native และ
gateway ปัจจุบันต้องใช้ surface ของ Plugin
เมื่อไม่ได้ออก device token, hello-ok.auth จะรายงานสิทธิ์ที่เจรจาได้
โดยไม่มีฟิลด์ token:
client.id: "gateway-client",
client.mode: "backend") อาจละ device ได้ในการเชื่อมต่อ local loopback โดยตรงเมื่อ
ยืนยันตัวตนด้วย token/password ของ gateway ที่ใช้ร่วมกัน เส้นทางนี้สงวนไว้สำหรับ
RPC ของ control-plane ภายใน และกันไม่ให้ baseline การจับคู่ CLI/device ที่ล้าสมัย
บล็อกงาน backend ภายในเครื่อง เช่น การอัปเดต session ของ subagent ไคลเอนต์ระยะไกล
ไคลเอนต์จาก browser-origin, ไคลเอนต์ Node และไคลเอนต์ device-token/device-identity
แบบชัดเจนยังคงใช้การตรวจสอบการจับคู่และการยกระดับขอบเขตตามปกติ
เมื่อออก device token แล้ว hello-ok จะรวมสิ่งนี้ด้วย:
hello-ok.auth อาจรวมรายการบทบาทแบบมีขอบเขตเพิ่มเติม
ใน deviceTokens ด้วย:
scopes: [] และ token ของ operator ที่ส่งต่อจะยังคงจำกัดอยู่ใน allowlist ของ bootstrap
operator (operator.approvals, operator.read,
operator.talk.secrets, operator.write) การตรวจสอบขอบเขต bootstrap ยังคง
มี prefix ตามบทบาท: รายการ operator จะตอบสนองเฉพาะคำขอของ operator และบทบาทที่ไม่ใช่ operator
ยังต้องมีขอบเขตภายใต้ prefix บทบาทของตนเอง
ตัวอย่าง Node
การจัดเฟรม
- คำขอ:
{type:"req", id, method, params} - Response:
{type:"res", id, ok, payload|error} - เหตุการณ์:
{type:"event", event, payload, seq?, stateVersion?}
บทบาท + ขอบเขต
สำหรับโมเดลขอบเขตของ operator แบบเต็ม การตรวจสอบในเวลาอนุมัติ และความหมายของ shared-secret ดู ขอบเขตของ Operatorบทบาท
operator= ไคลเอนต์ control plane (CLI/UI/automation)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 ของตนเองได้ แต่
prefix ผู้ดูแลระบบหลักที่สงวนไว้ (config.*, exec.approvals.*, wizard.*,
update.*) จะ resolve เป็น operator.admin เสมอ
ขอบเขตของเมธอดเป็นเพียงด่านแรก คำสั่ง 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 ประกาศการอ้างสิทธิ์ความสามารถในเวลา connect:caps: หมวดหมู่ความสามารถระดับสูง เช่นcamera,canvas,screen,location,voiceและtalkcommands: allowlist ของคำสั่งสำหรับ invokepermissions: toggle แบบละเอียด (เช่นscreen.record,camera.capture)
Presence
system-presenceส่งคืนรายการที่ key ตามตัวตนอุปกรณ์- รายการ presence รวม
deviceId,rolesและscopesเพื่อให้ UI แสดงหนึ่งแถวต่ออุปกรณ์ได้ แม้เมื่ออุปกรณ์เชื่อมต่อเป็นทั้ง operator และ node node.listรวมฟิลด์ตัวเลือกlastSeenAtMsและlastSeenReasonNode ที่เชื่อมต่ออยู่จะรายงาน เวลาการเชื่อมต่อปัจจุบันเป็นlastSeenAtMsพร้อมเหตุผลconnect; Node ที่จับคู่แล้วสามารถรายงาน presence เบื้องหลังที่คงทนได้เช่นกันเมื่อเหตุการณ์ Node ที่เชื่อถือได้อัปเดต metadata การจับคู่ของตน
เหตุการณ์ Node background alive
Node อาจเรียกnode.event ด้วย event: "node.presence.alive" เพื่อบันทึกว่า Node ที่จับคู่แล้ว
ยัง alive ระหว่างการ wake เบื้องหลัง โดยไม่ทำเครื่องหมายว่าเชื่อมต่ออยู่
trigger เป็น enum แบบปิด: background, silent_push, bg_app_refresh,
significant_location, manual หรือ connect สตริง trigger ที่ไม่รู้จักจะถูก normalize เป็น
background โดย gateway ก่อน persistence เหตุการณ์จะคงทนเฉพาะสำหรับ session อุปกรณ์ Node
ที่ยืนยันตัวตนแล้วเท่านั้น; session ที่ไม่มีอุปกรณ์หรือไม่ได้จับคู่จะส่งคืน handled: false
gateway ที่สำเร็จจะส่งคืนผลลัพธ์แบบมีโครงสร้าง:
{ "ok": true } สำหรับ node.event; ไคลเอนต์ควรถือว่านั่นเป็น
RPC ที่ได้รับการยืนยันแล้ว ไม่ใช่ persistence ของ presence ที่คงทน
การกำหนดขอบเขตเหตุการณ์ broadcast
เหตุการณ์ broadcast ของ WebSocket ที่เซิร์ฟเวอร์ push จะถูก gate ด้วยขอบเขต เพื่อไม่ให้ session ที่จำกัดเฉพาะการจับคู่หรือเฉพาะ Node รับเนื้อหา session แบบ passively- เฟรม chat, agent และ tool-result (รวมถึงเหตุการณ์
agentแบบ streamed และผลลัพธ์ tool call) ต้องมีอย่างน้อยoperator.readSession ที่ไม่มีoperator.readจะข้ามเฟรมเหล่านี้ทั้งหมด - broadcast
plugin.*ที่ Plugin กำหนด จะถูก gate เป็นoperator.writeหรือoperator.adminขึ้นอยู่กับวิธีที่ Plugin ลงทะเบียนไว้ - เหตุการณ์สถานะและการขนส่ง (
heartbeat,presence,tick, lifecycle connect/disconnect ฯลฯ) ยังคงไม่ถูกจำกัดเพื่อให้ทุก session ที่ยืนยันตัวตนแล้วสังเกตสุขภาพของการขนส่งได้ - กลุ่มเหตุการณ์ broadcast ที่ไม่รู้จัก จะถูก gate ด้วยขอบเขตโดยค่าเริ่มต้น (fail-closed) เว้นแต่ handler ที่ลงทะเบียนไว้จะผ่อนปรนอย่างชัดเจน
กลุ่มเมธอด RPC ทั่วไป
surface 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
ระบบและตัวตน
ระบบและตัวตน
โมเดลและการใช้งาน
โมเดลและการใช้งาน
models.listส่งคืนแค็ตตาล็อกโมเดลที่รันไทม์อนุญาต ส่ง{ "view": "configured" }สำหรับโมเดลที่กำหนดค่าแล้วในขนาดพอดีกับตัวเลือก (agents.defaults.modelsก่อน แล้วตามด้วยmodels.providers.*.models) หรือ{ "view": "all" }สำหรับแค็ตตาล็อกทั้งหมดusage.statusส่งคืนหน้าต่างการใช้งานของผู้ให้บริการ/สรุปโควตาที่เหลือusage.costส่งคืนสรุปการใช้งานต้นทุนที่รวบรวมแล้วสำหรับช่วงวันที่doctor.memory.statusส่งคืนความพร้อมของ vector-memory / embedding ที่แคชไว้สำหรับพื้นที่ทำงานของเอเจนต์เริ่มต้นที่ใช้งานอยู่ ส่ง{ "probe": true }หรือ{ "deep": true }เฉพาะเมื่อผู้เรียกต้องการ ping ผู้ให้บริการ embedding แบบสดอย่างชัดเจนdoctor.memory.remHarnessส่งคืนตัวอย่าง REM harness แบบอ่านอย่างเดียวที่มีขอบเขตจำกัดสำหรับไคลเอนต์ระนาบควบคุมระยะไกล โดยอาจรวมถึงพาธพื้นที่ทำงาน ชิ้นส่วนหน่วยความจำ มาร์กดาวน์ที่ยึดโยงและเรนเดอร์แล้ว และตัวเลือกสำหรับการเลื่อนระดับเชิงลึก ดังนั้นผู้เรียกต้องมีoperator.readsessions.usageส่งคืนสรุปการใช้งานรายเซสชันsessions.usage.timeseriesส่งคืนการใช้งานแบบอนุกรมเวลาสำหรับหนึ่งเซสชันsessions.usage.logsส่งคืนรายการบันทึกการใช้งานสำหรับหนึ่งเซสชัน
ช่องทางและตัวช่วยเข้าสู่ระบบ
ช่องทางและตัวช่วยเข้าสู่ระบบ
channels.statusส่งคืนสรุปสถานะช่องทาง/Plugin ในตัว + ที่บันเดิลมาchannels.logoutออกจากระบบช่องทาง/บัญชีเฉพาะที่ช่องทางรองรับการออกจากระบบweb.login.startเริ่มโฟลว์เข้าสู่ระบบผ่าน QR/เว็บสำหรับผู้ให้บริการช่องทางเว็บปัจจุบันที่รองรับ QRweb.login.waitรอให้โฟลว์เข้าสู่ระบบผ่าน QR/เว็บนั้นเสร็จสมบูรณ์ และเริ่มช่องทางเมื่อสำเร็จpush.testส่ง APNs push ทดสอบไปยัง Node iOS ที่ลงทะเบียนไว้voicewake.getส่งคืนทริกเกอร์ wake-word ที่จัดเก็บไว้voicewake.setอัปเดตทริกเกอร์ wake-word และกระจายการเปลี่ยนแปลง
การส่งข้อความและบันทึก
การส่งข้อความและบันทึก
sendคือ RPC การส่งออกโดยตรงสำหรับการส่งที่ระบุช่องทาง/บัญชี/thread นอกตัวรันแชตlogs.tailส่งคืน tail บันทึกไฟล์ Gateway ที่กำหนดค่าไว้ พร้อมการควบคุม cursor/limit และจำนวนไบต์สูงสุด
Talk และ TTS
Talk และ TTS
talk.catalogส่งคืนแค็ตตาล็อกผู้ให้บริการ Talk แบบอ่านอย่างเดียวสำหรับเสียงพูด การถอดเสียงแบบสตรีม และเสียงแบบเรียลไทม์ โดยรวมถึงรหัสผู้ให้บริการ ป้ายกำกับ สถานะที่กำหนดค่าไว้ รหัสโมเดล/เสียงที่เปิดเผย โหมดมาตรฐาน การขนส่ง กลยุทธ์สมอง และแฟล็กเสียง/ความสามารถแบบเรียลไทม์ โดยไม่ส่งคืนความลับของผู้ให้บริการหรือเปลี่ยนแปลงค่ากำหนดส่วนกลางtalk.configส่งคืน payload ค่ากำหนด Talk ที่มีผลจริง;includeSecretsต้องใช้operator.talk.secrets(หรือoperator.admin)talk.session.createสร้างเซสชัน Talk ที่ Gateway เป็นเจ้าของสำหรับrealtime/gateway-relay,transcription/gateway-relayหรือstt-tts/managed-roombrain: "direct-tools"ต้องใช้operator.admintalk.session.joinตรวจสอบโทเค็นเซสชัน managed-room ปล่อยเหตุการณ์session.readyหรือsession.replacedตามความจำเป็น และส่งคืนเมทาดาทาห้อง/เซสชันพร้อมเหตุการณ์ Talk ล่าสุดโดยไม่มีโทเค็นข้อความธรรมดาหรือแฮชโทเค็นที่จัดเก็บไว้talk.session.appendAudioเพิ่มเสียงอินพุต PCM แบบ base64 ต่อท้ายในเซสชันรีเลย์เรียลไทม์และเซสชันถอดเสียงที่ Gateway เป็นเจ้าของtalk.session.startTurn,talk.session.endTurnและtalk.session.cancelTurnขับเคลื่อนวงจรชีวิต turn ของ managed-room พร้อมการปฏิเสธ turn ที่ค้างเก่าก่อนล้างสถานะtalk.session.cancelOutputหยุดเอาต์พุตเสียงของผู้ช่วย โดยหลักใช้สำหรับการแทรกพูดที่ควบคุมด้วย VAD ในเซสชันรีเลย์ Gatewaytalk.session.submitToolResultทำให้การเรียกเครื่องมือของผู้ให้บริการที่ปล่อยโดยเซสชันรีเลย์เรียลไทม์ที่ Gateway เป็นเจ้าของเสร็จสมบูรณ์ ส่งoptions: { willContinue: true }สำหรับเอาต์พุตเครื่องมือชั่วคราวเมื่อจะมีผลลัพธ์สุดท้ายตามมา หรือoptions: { suppressResponse: true }เมื่อผลลัพธ์เครื่องมือควรตอบสนองการเรียกของผู้ให้บริการโดยไม่เริ่มการตอบกลับผู้ช่วยแบบเรียลไทม์อีกครั้งtalk.session.closeปิดเซสชันรีเลย์ การถอดเสียง หรือ managed-room ที่ Gateway เป็นเจ้าของ และปล่อยเหตุการณ์ Talk ปลายทางtalk.modeตั้งค่า/กระจายสถานะโหมด Talk ปัจจุบันสำหรับไคลเอนต์ WebChat/Control UItalk.client.createสร้างเซสชันผู้ให้บริการเรียลไทม์ที่ไคลเอนต์เป็นเจ้าของโดยใช้webrtcหรือprovider-websocketขณะที่ Gateway เป็นเจ้าของค่ากำหนด ข้อมูลรับรอง คำสั่ง และนโยบายเครื่องมือtalk.client.toolCallให้การขนส่งเรียลไทม์ที่ไคลเอนต์เป็นเจ้าของส่งต่อการเรียกเครื่องมือของผู้ให้บริการไปยังนโยบาย Gateway เครื่องมือแรกที่รองรับคือopenclaw_agent_consult; ไคลเอนต์รับรหัสการรันและรอเหตุการณ์วงจรชีวิตแชตปกติก่อนส่งผลลัพธ์เครื่องมือเฉพาะผู้ให้บริการtalk.eventคือช่องทางเหตุการณ์ Talk เดียวสำหรับอะแดปเตอร์เรียลไทม์ การถอดเสียง STT/TTS, managed-room, โทรศัพท์ และการประชุมtalk.speakสังเคราะห์เสียงพูดผ่านผู้ให้บริการเสียงพูด Talk ที่ใช้งานอยู่tts.statusส่งคืนสถานะการเปิดใช้ TTS ผู้ให้บริการที่ใช้งานอยู่ ผู้ให้บริการสำรอง และสถานะค่ากำหนดผู้ให้บริการtts.providersส่งคืนคลังผู้ให้บริการ TTS ที่มองเห็นได้tts.enableและtts.disableสลับสถานะค่ากำหนด TTStts.setProviderอัปเดตผู้ให้บริการ TTS ที่ต้องการtts.convertรันการแปลงข้อความเป็นเสียงแบบครั้งเดียว
ความลับ ค่ากำหนด การอัปเดต และวิซาร์ด
ความลับ ค่ากำหนด การอัปเดต และวิซาร์ด
secrets.reloadแก้ไข SecretRefs ที่ใช้งานอยู่อีกครั้งและสลับสถานะความลับของรันไทม์เฉพาะเมื่อสำเร็จทั้งหมดsecrets.resolveแก้ไขการกำหนดความลับเป้าหมายคำสั่งสำหรับชุดคำสั่ง/เป้าหมายเฉพาะconfig.getส่งคืน snapshot และแฮชของค่ากำหนดปัจจุบันconfig.setเขียน payload ค่ากำหนดที่ผ่านการตรวจสอบแล้วconfig.patchผสานการอัปเดตค่ากำหนดบางส่วนconfig.applyตรวจสอบ + แทนที่ payload ค่ากำหนดทั้งหมดconfig.schemaส่งคืน payload สคีมาค่ากำหนดสดที่ใช้โดยเครื่องมือ Control UI และ CLI: สคีมา,uiHints, เวอร์ชัน และเมทาดาทาการสร้าง รวมถึงเมทาดาทาสคีมา Plugin + ช่องทางเมื่อรันไทม์โหลดได้ สคีมามีเมทาดาทาฟิลด์title/descriptionที่ได้มาจากป้ายกำกับและข้อความช่วยเหลือเดียวกับที่ UI ใช้ รวมถึงกิ่งองค์ประกอบของออบเจ็กต์ซ้อน wildcard รายการอาร์เรย์ และanyOf/oneOf/allOfเมื่อมีเอกสารฟิลด์ที่ตรงกันconfig.schema.lookupส่งคืน payload การค้นหาที่จำกัดตามพาธสำหรับพาธค่ากำหนดหนึ่งรายการ: พาธที่ทำให้เป็นมาตรฐานแล้ว โหนดสคีมาแบบตื้น hint ที่ตรงกัน +hintPathและสรุปลูกโดยตรงสำหรับการเจาะลึกใน UI/CLI โหนดสคีมาการค้นหาคงเอกสารที่ผู้ใช้เห็นและฟิลด์การตรวจสอบทั่วไป (title,description,type,enum,const,format,pattern, ขอบเขต numeric/string/array/object และแฟล็กอย่างadditionalProperties,deprecated,readOnly,writeOnly) สรุปลูกเปิดเผยkey,pathที่ทำให้เป็นมาตรฐานแล้ว,type,required,hasChildrenรวมถึงhint/hintPathที่ตรงกันupdate.runรันโฟลว์อัปเดต Gateway และกำหนดเวลาการรีสตาร์ทเฉพาะเมื่อการอัปเดตเองสำเร็จ; ผู้เรียกที่มีเซสชันสามารถใส่continuationMessageเพื่อให้ตอนเริ่มต้นระบบกลับมาดำเนิน turn ของเอเจนต์ถัดไปหนึ่งครั้งผ่านคิวการต่อเนื่องหลังรีสตาร์ท การอัปเดตผ่านตัวจัดการแพ็กเกจบังคับให้รีสตาร์ทอัปเดตแบบไม่เลื่อนเวลาและไม่มี cooldown หลังสลับแพ็กเกจ เพื่อไม่ให้กระบวนการ Gateway เก่ายังคง lazy-load จากต้นไม้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ที่ระบุอย่างชัดเจน คำค้นหารันและงานจะแก้ไขเซสชันเจ้าของฝั่งเซิร์ฟเวอร์ และส่งคืนเฉพาะสื่อ transcript ที่มีแหล่งที่มาตรงกัน; แหล่ง URL ที่ไม่ปลอดภัยหรือเป็น local จะส่งคืนการดาวน์โหลดที่ไม่รองรับแทนการ fetch ฝั่งเซิร์ฟเวอร์environments.listและenvironments.statusเปิดเผยการค้นพบสภาพแวดล้อมแบบอ่านอย่างเดียวที่เป็น Gateway-local และ Node สำหรับไคลเอนต์ SDKagent.identity.getส่งคืนอัตลักษณ์ผู้ช่วยที่มีผลจริงสำหรับเอเจนต์หรือเซสชันagent.waitรอให้การรันเสร็จสิ้นและส่งคืน snapshot ปลายทางเมื่อมี
การควบคุมเซสชัน
การควบคุมเซสชัน
sessions.listส่งคืนดัชนีเซสชันปัจจุบัน รวมถึงเมทาดาทาagentRuntimeต่อแถวเมื่อกำหนดค่าแบ็กเอนด์รันไทม์เอเจนต์ไว้sessions.subscribeและsessions.unsubscribeสลับการสมัครรับเหตุการณ์การเปลี่ยนแปลงเซสชันสำหรับไคลเอนต์ WS ปัจจุบันsessions.messages.subscribeและsessions.messages.unsubscribeสลับการสมัครรับเหตุการณ์ transcript/ข้อความสำหรับหนึ่งเซสชันsessions.previewส่งคืนตัวอย่าง transcript ที่มีขอบเขตจำกัดสำหรับคีย์เซสชันเฉพาะsessions.describeส่งคืนแถวเซสชัน Gateway หนึ่งแถวสำหรับคีย์เซสชันที่ตรงกันทุกประการsessions.resolveแก้ไขหรือทำให้เป้าหมายเซสชันเป็นมาตรฐานsessions.createสร้างรายการเซสชันใหม่sessions.sendส่งข้อความเข้าไปในเซสชันที่มีอยู่sessions.steerคือรูปแบบ interrupt-and-steer สำหรับเซสชันที่ใช้งานอยู่sessions.abortยกเลิกงานที่ใช้งานอยู่สำหรับเซสชัน ผู้เรียกอาจส่งkeyพร้อมrunIdที่เป็นทางเลือก หรือส่งเฉพาะrunIdสำหรับการรันที่ใช้งานอยู่ซึ่ง Gateway สามารถแก้ไขเป็นเซสชันได้sessions.patchอัปเดตเมทาดาทา/การ override ของเซสชัน และรายงานโมเดลมาตรฐานที่แก้ไขแล้วพร้อมagentRuntimeที่มีผลจริงsessions.reset,sessions.deleteและsessions.compactดำเนินการบำรุงรักษาเซสชันsessions.getส่งคืนแถวเซสชันที่จัดเก็บไว้ทั้งหมด- การดำเนินการแชตยังคงใช้
chat.history,chat.send,chat.abortและchat.injectchat.historyถูกปรับให้เป็นมาตรฐานสำหรับการแสดงผลแก่ไคลเอนต์ UI: แท็ก directive แบบ inline จะถูกลบออกจากข้อความที่มองเห็น, payload XML ของการเรียกเครื่องมือแบบข้อความธรรมดา (รวมถึง<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>และบล็อกการเรียกเครื่องมือที่ถูกตัดทอน) และโทเค็นควบคุมโมเดล ASCII/full-width ที่รั่วไหลจะถูกลบออก, แถวผู้ช่วยที่เป็นโทเค็นเงียบล้วน เช่นNO_REPLY/no_replyที่ตรงกันทุกประการจะถูกละไว้ และแถวที่มีขนาดใหญ่เกินไปสามารถถูกแทนที่ด้วย placeholders
การจับคู่อุปกรณ์และโทเค็นอุปกรณ์
การจับคู่อุปกรณ์และโทเค็นอุปกรณ์
device.pair.listส่งคืนอุปกรณ์ที่จับคู่แล้วที่รอดำเนินการและอนุมัติแล้วdevice.pair.approve,device.pair.rejectและdevice.pair.removeจัดการเรคคอร์ดการจับคู่อุปกรณ์device.token.rotateหมุนเวียนโทเค็นอุปกรณ์ที่จับคู่แล้วภายในขอบเขตบทบาทที่อนุมัติและขอบเขตผู้เรียกdevice.token.revokeเพิกถอนโทเค็นอุปกรณ์ที่จับคู่แล้วภายในขอบเขตบทบาทที่อนุมัติและขอบเขตผู้เรียก
การจับคู่ Node, invoke และงานที่รอดำเนินการ
การจับคู่ Node, invoke และงานที่รอดำเนินการ
node.pair.request,node.pair.list,node.pair.approve,node.pair.reject,node.pair.removeและnode.pair.verifyครอบคลุมการจับคู่ Node และการตรวจสอบ bootstrapnode.listและnode.describeส่งคืนสถานะ Node ที่รู้จัก/เชื่อมต่ออยู่node.renameอัปเดตป้ายกำกับ Node ที่จับคู่แล้วnode.invokeส่งต่อคำสั่งไปยัง Node ที่เชื่อมต่ออยู่node.invoke.resultส่งคืนผลลัพธ์สำหรับคำขอ invokenode.eventนำเหตุการณ์ที่เกิดจาก Node กลับเข้าสู่ Gatewaynode.pending.pullและnode.pending.ackคือ API คิวของ Node ที่เชื่อมต่ออยู่node.pending.enqueueและnode.pending.drainจัดการงานที่รอดำเนินการแบบคงทนสำหรับ Node ที่ออฟไลน์/ตัดการเชื่อมต่อ
กลุ่มการอนุมัติ
กลุ่มการอนุมัติ
exec.approval.request,exec.approval.get,exec.approval.listและexec.approval.resolveครอบคลุมคำขออนุมัติ exec แบบครั้งเดียว พร้อมการค้นหา/เล่นซ้ำการอนุมัติที่ค้างอยู่exec.approval.waitDecisionรอการอนุมัติ exec ที่ค้างอยู่หนึ่งรายการ และส่งคืนผลการตัดสินใจสุดท้าย (หรือnullเมื่อหมดเวลา)exec.approvals.getและexec.approvals.setจัดการสแนปชอตนโยบายการอนุมัติ exec ของ gatewayexec.approvals.node.getและexec.approvals.node.setจัดการนโยบายการอนุมัติ exec เฉพาะ Node ผ่านคำสั่ง relay ของ Nodeplugin.approval.request,plugin.approval.list,plugin.approval.waitDecisionและplugin.approval.resolveครอบคลุมโฟลว์การอนุมัติที่ Plugin กำหนด
ระบบอัตโนมัติ, Skills และเครื่องมือ
ระบบอัตโนมัติ, 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 / liveness เป็นระยะhealth: การอัปเดตสแนปชอตสถานะสุขภาพของ gatewayheartbeat: การอัปเดตสตรีมเหตุการณ์ Heartbeatcron: เหตุการณ์การเปลี่ยนแปลงงาน/การรัน Cronshutdown: การแจ้งเตือนการปิด Gatewaynode.pair.requested/node.pair.resolved: วงจรชีวิตการจับคู่ Nodenode.invoke.request: การกระจายคำขอ invoke ของ Nodedevice.pair.requested/device.pair.resolved: วงจรชีวิตอุปกรณ์ที่จับคู่voicewake.changed: ค่ากำหนดทริกเกอร์คำปลุกมีการเปลี่ยนแปลงexec.approval.requested/exec.approval.resolved: วงจรชีวิตการอนุมัติ execplugin.approval.requested/plugin.approval.resolved: วงจรชีวิตการอนุมัติ Plugin
เมธอดตัวช่วยของ Node
- Node อาจเรียก
skills.binsเพื่อดึงรายการปัจจุบันของไฟล์ปฏิบัติการ Skill สำหรับการตรวจสอบ auto-allow
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 } - id งานที่ไม่มีอยู่จะส่งคืนรูปแบบข้อผิดพลาด 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, timestamp, ความคืบหน้า,
สรุปปลายทาง และข้อความข้อผิดพลาดที่ผ่านการทำให้ปลอดภัยแล้ว
เมธอดตัวช่วยของผู้ปฏิบัติงาน
- ผู้ปฏิบัติงานอาจเรียก
commands.list(operator.read) เพื่อดึงคลังคำสั่งรันไทม์ สำหรับ agentagentIdเป็นตัวเลือก; ละไว้เพื่ออ่านพื้นที่ทำงาน agent เริ่มต้นscopeควบคุมว่าnameหลักจะกำหนดเป้าหมายพื้นผิวใด:textส่งคืนโทเคนคำสั่งข้อความหลักโดยไม่มี/นำหน้าnativeและพาธเริ่มต้นbothส่งคืนชื่อแบบ native ที่รับรู้ provider เมื่อมีให้ใช้
textAliasesมี alias เครื่องหมายทับแบบตรงตัว เช่น/modelและ/mnativeNameมีชื่อคำสั่ง native ที่รับรู้ provider เมื่อมีอยู่providerเป็นตัวเลือก และมีผลเฉพาะต่อการตั้งชื่อแบบ native รวมถึงความพร้อมใช้งานของคำสั่ง Plugin แบบ nativeincludeArgs=falseละเมทาดาทาอาร์กิวเมนต์ที่ serialize แล้วจากการตอบกลับ
- ผู้ปฏิบัติงานอาจเรียก
tools.catalog(operator.read) เพื่อดึงแค็ตตาล็อกเครื่องมือรันไทม์สำหรับ agent การตอบกลับมีเครื่องมือที่จัดกลุ่มแล้วและเมทาดาทา provenance:source:coreหรือpluginpluginId: เจ้าของ Plugin เมื่อsource="plugin"optional: เครื่องมือ Plugin เป็นตัวเลือกหรือไม่
- ผู้ปฏิบัติงานอาจเรียก
tools.effective(operator.read) เพื่อดึงคลังเครื่องมือที่มีผลในรันไทม์ สำหรับเซสชัน- ต้องระบุ
sessionKey - gateway อนุมานบริบทรันไทม์ที่เชื่อถือได้จากเซสชันฝั่งเซิร์ฟเวอร์ แทนที่จะยอมรับ บริบทการตรวจสอบสิทธิ์หรือการส่งมอบที่ผู้เรียกส่งมา
- การตอบกลับอยู่ในขอบเขตเซสชันและสะท้อนสิ่งที่บทสนทนาที่ใช้งานอยู่สามารถใช้ได้ในตอนนี้ รวมถึงเครื่องมือ core, Plugin และ channel
- ต้องระบุ
- ผู้ปฏิบัติงานอาจเรียก
tools.invoke(operator.write) เพื่อ invoke เครื่องมือที่พร้อมใช้งานหนึ่งรายการผ่าน พาธนโยบาย gateway เดียวกับ/tools/invoke- ต้องระบุ
nameส่วนargs,sessionKey,agentId,confirmและidempotencyKeyเป็นตัวเลือก - หากมีทั้ง
sessionKeyและagentIdagent ของเซสชันที่ resolve แล้วต้องตรงกับagentId - การตอบกลับเป็น envelope สำหรับ SDK ที่มี
ok,toolName,outputที่ไม่บังคับ และฟิลด์errorแบบมีชนิด การปฏิเสธจากการอนุมัติหรือนโยบายจะส่งคืนok:falseใน payload แทนที่จะ ข้าม pipeline นโยบายเครื่องมือของ gateway
- ต้องระบุ
- ผู้ปฏิบัติงานอาจเรียก
skills.status(operator.read) เพื่อดึงคลัง Skill ที่มองเห็นได้สำหรับ agentagentIdเป็นตัวเลือก; ละไว้เพื่ออ่านพื้นที่ทำงาน agent เริ่มต้น- การตอบกลับมีคุณสมบัติความพร้อมใช้งาน ข้อกำหนดที่ขาดหาย การตรวจสอบค่ากำหนด และ ตัวเลือกการติดตั้งที่ผ่านการทำให้ปลอดภัยแล้ว โดยไม่เปิดเผยค่าความลับดิบ
- ผู้ปฏิบัติงานอาจเรียก
skills.searchและskills.detail(operator.read) สำหรับ เมทาดาทาการค้นพบ ClawHub - ผู้ปฏิบัติงานอาจเรียก
skills.upload.begin,skills.upload.chunkและskills.upload.commit(operator.admin) เพื่อ stage archive Skill ส่วนตัว ก่อนติดตั้ง นี่เป็นพาธอัปโหลดสำหรับ admin แยกต่างหากสำหรับไคลเอนต์ที่เชื่อถือได้ ไม่ใช่โฟลว์ติดตั้ง Skill ของ ClawHub ตามปกติ และถูกปิดใช้งานโดยค่าเริ่มต้น เว้นแต่skills.install.allowUploadedArchivesจะเปิดใช้งานskills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? })สร้างการอัปโหลดที่ผูกกับ slug และค่า force นั้นskills.upload.chunk({ uploadId, offset, dataBase64 })ต่อท้ายไบต์ที่ offset ที่ถอดรหัสแล้วแบบตรงตัวskills.upload.commit({ uploadId, sha256? })ตรวจสอบขนาดสุดท้ายและ SHA-256 การ commit เพียงทำให้การอัปโหลดเสร็จสมบูรณ์เท่านั้น; ไม่ได้ติดตั้ง Skill- archive Skill ที่อัปโหลดเป็น archive zip ที่มีราก
SKILL.mdชื่อไดเรกทอรีภายในของ archive จะไม่เลือกเป้าหมายการติดตั้ง
- ผู้ปฏิบัติงานอาจเรียก
skills.install(operator.admin) ได้สามโหมด:- โหมด ClawHub:
{ source: "clawhub", slug, version?, force? }ติดตั้ง โฟลเดอร์ Skill ลงในไดเรกทอรีskills/ของพื้นที่ทำงาน agent เริ่มต้น - โหมดอัปโหลด:
{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? }ติดตั้งการอัปโหลดที่ commit แล้วลงในไดเรกทอรีskills/<slug>ของพื้นที่ทำงาน agent เริ่มต้น slug และค่า force ต้องตรงกับคำขอskills.upload.beginเดิม โหมดนี้จะถูกปฏิเสธ เว้นแต่skills.install.allowUploadedArchivesจะเปิดใช้งาน การตั้งค่านี้ไม่มีผลต่อ การติดตั้ง ClawHub - โหมดตัวติดตั้ง Gateway:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }รัน actionmetadata.openclaw.installที่ประกาศไว้บนโฮสต์ gateway
- โหมด ClawHub:
- ผู้ปฏิบัติงานอาจเรียก
skills.update(operator.admin) ได้สองโหมด:- โหมด ClawHub อัปเดต slug ที่ติดตามหนึ่งรายการหรือการติดตั้ง ClawHub ที่ติดตามทั้งหมดใน พื้นที่ทำงาน agent เริ่มต้น
- โหมดค่ากำหนด patch ค่า
skills.entries.<skillKey>เช่นenabled,apiKeyและenv
มุมมอง models.list
models.list รับพารามิเตอร์ view ที่ไม่บังคับ:
- ละไว้หรือ
"default": พฤติกรรมรันไทม์ปัจจุบัน หากกำหนดค่าagents.defaults.modelsไว้ การตอบกลับคือแค็ตตาล็อกที่อนุญาต รวมถึงโมเดลที่ค้นพบแบบไดนามิกสำหรับรายการprovider/*มิฉะนั้นการตอบกลับคือแค็ตตาล็อก Gateway ทั้งหมด "configured": พฤติกรรมขนาดเหมาะกับตัวเลือก หากกำหนดค่าagents.defaults.modelsไว้ ค่านั้นยังมีผลเหนือกว่า รวมถึงการค้นพบในขอบเขต provider สำหรับรายการprovider/*หากไม่มี allowlist การตอบกลับจะใช้รายการmodels.providers.*.modelsแบบชัดเจน และ fallback ไปยังแค็ตตาล็อกทั้งหมดเฉพาะเมื่อไม่มีแถวโมเดลที่กำหนดค่าไว้"all": แค็ตตาล็อก Gateway ทั้งหมด โดยข้ามagents.defaults.modelsใช้สำหรับ UI การวินิจฉัยและการค้นพบ ไม่ใช่ตัวเลือกโมเดลปกติ
การอนุมัติ exec
- เมื่อคำขอ exec ต้องการการอนุมัติ gateway จะกระจาย
exec.approval.requested - ไคลเอนต์ผู้ปฏิบัติงาน resolve โดยเรียก
exec.approval.resolve(ต้องใช้ scopeoperator.approvals) - สำหรับ
host=node,exec.approval.requestต้องมีsystemRunPlan(ข้อมูลเมทาดาทาargv/cwd/rawCommand/session แบบ canonical) คำขอที่ไม่มีsystemRunPlanจะถูกปฏิเสธ - หลังอนุมัติ การเรียก
node.invoke system.runที่ส่งต่อจะใช้systemRunPlanแบบ canonical นั้นซ้ำ เป็นบริบทคำสั่ง/cwd/session ที่มีอำนาจ - หากผู้เรียกกลายพันธุ์
command,rawCommand,cwd,agentIdหรือsessionKeyระหว่างการเตรียมและการส่งต่อsystem.runที่ได้รับอนุมัติขั้นสุดท้าย gateway จะปฏิเสธการรัน แทนที่จะเชื่อถือ payload ที่ถูกกลายพันธุ์
fallback การส่งมอบของ agent
- คำขอ
agentสามารถมีdeliver=trueเพื่อขอการส่งมอบขาออก bestEffortDeliver=falseคงพฤติกรรมเข้มงวด: เป้าหมายการส่งมอบที่ resolve ไม่ได้หรือเป็น internal-only จะส่งคืนINVALID_REQUESTbestEffortDeliver=trueอนุญาตให้ fallback ไปยังการดำเนินการเฉพาะเซสชันเมื่อไม่สามารถ resolve เส้นทางภายนอกที่ส่งมอบได้ (เช่น เซสชัน internal/webchat หรือค่ากำหนดหลาย channel ที่คลุมเครือ)- ผลลัพธ์
agentสุดท้ายอาจมีresult.deliveryStatusเมื่อมีการขอการส่งมอบ โดยใช้สถานะsent,suppressed,partial_failedและfailedเดียวกับที่บันทึกไว้สำหรับopenclaw agent --json --deliver
การกำหนดเวอร์ชัน
PROTOCOL_VERSIONอยู่ในsrc/gateway/protocol/version.ts- ไคลเอนต์ส่ง
minProtocol+maxProtocol; เซิร์ฟเวอร์ปฏิเสธช่วงที่ ไม่รวม protocol ปัจจุบันของตน ไคลเอนต์ native ใช้ขอบเขตล่าง v3 เพื่อให้ ไคลเอนต์ v4 แบบเพิ่มได้ยังคงเข้าถึง gateway v3 ได้ - Schema + model ถูกสร้างจากนิยาม 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 ms | src/gateway/client.ts (requestTimeoutMs) |
| ระยะหมดเวลา Preauth / connect-challenge | 15_000 ms | src/gateway/handshake-timeouts.ts (config/env สามารถเพิ่มงบประมาณ server/client ที่จับคู่กันได้) |
| ระยะ backoff การเชื่อมต่อใหม่เริ่มต้น | 1_000 ms | src/gateway/client.ts (backoffMs) |
| ระยะ backoff การเชื่อมต่อใหม่สูงสุด | 30_000 ms | src/gateway/client.ts (scheduleReconnect) |
| ขีดจำกัด fast-retry หลังปิด device-token | 250 ms | src/gateway/client.ts |
ระยะผ่อนผัน force-stop ก่อน terminate() | 250 ms | FORCE_STOP_TERMINATE_GRACE_MS |
ระยะหมดเวลาเริ่มต้นของ stopAndWait() | 1_000 ms | STOP_AND_WAIT_TIMEOUT_MS |
ช่วง tick เริ่มต้น (ก่อน hello-ok) | 30_000 ms | src/gateway/client.ts |
| การปิดจาก tick-timeout | code 4000 เมื่อความเงียบเกิน tickIntervalMs * 2 | src/gateway/client.ts |
MAX_PAYLOAD_BYTES | 25 * 1024 * 1024 (25 MB) | src/gateway/server-constants.ts |
policy.tickIntervalMs, policy.maxPayload,
และ policy.maxBufferedBytes ที่มีผลจริงใน hello-ok; client ควรปฏิบัติตามค่าเหล่านั้น
แทนค่าเริ่มต้นก่อน handshake
การยืนยันตัวตน
- การยืนยันตัวตน Gateway แบบ shared-secret ใช้
connect.params.auth.tokenหรือconnect.params.auth.passwordขึ้นอยู่กับโหมดการยืนยันตัวตนที่กำหนดค่าไว้ - โหมดที่มีข้อมูลระบุตัวตน เช่น Tailscale Serve
(
gateway.auth.allowTailscale: true) หรือgateway.auth.mode: "trusted-proxy"ที่ไม่ใช่ loopback จะผ่านการตรวจสอบการยืนยันตัวตนสำหรับ connect จาก request headers แทนconnect.params.auth.* gateway.auth.mode: "none"สำหรับ private-ingress จะข้ามการยืนยันตัวตนแบบ shared-secret สำหรับ connect ทั้งหมด; อย่าเปิดเผยโหมดนั้นบน ingress สาธารณะหรือไม่น่าเชื่อถือ- หลังการจับคู่ Gateway จะออก device token ที่จำกัดขอบเขตตาม
role + scopes ของการเชื่อมต่อ ค่านี้จะถูกส่งคืนใน
hello-ok.auth.deviceTokenและ client ควร เก็บไว้เพื่อใช้ในการเชื่อมต่อในอนาคต - client ควรเก็บ
hello-ok.auth.deviceTokenหลักหลังจาก connect สำเร็จทุกครั้ง - การเชื่อมต่อใหม่ด้วย device token ที่ เก็บไว้ นั้นควรใช้ชุด scope ที่อนุมัติแล้วซึ่งเก็บไว้ สำหรับ token นั้นซ้ำด้วย วิธีนี้จะรักษาสิทธิ์เข้าถึง read/probe/status ที่ได้รับอนุญาตแล้ว และหลีกเลี่ยงการย่อขอบเขตการเชื่อมต่อใหม่อย่างเงียบ ๆ เป็น scope แบบ admin-only โดยนัยที่แคบกว่า
- การประกอบการยืนยันตัวตนสำหรับ connect ฝั่ง client (
selectConnectAuthในsrc/gateway/client.ts):auth.passwordเป็นอิสระจากส่วนอื่นและจะถูกส่งต่อเสมอเมื่อมีการตั้งค่าauth.tokenถูกเติมค่าตามลำดับความสำคัญ: shared token ที่ระบุอย่างชัดเจนก่อน, จากนั้นdeviceTokenที่ระบุอย่างชัดเจน, แล้วจึงเป็น per-device token ที่เก็บไว้ (ผูกด้วยdeviceId+role)auth.bootstrapTokenจะถูกส่งเฉพาะเมื่อไม่มีรายการข้างต้นแก้เป็นauth.tokenได้ shared token หรือ device token ใด ๆ ที่แก้ได้จะระงับค่านี้- การเลื่อนขั้นอัตโนมัติของ device token ที่เก็บไว้ในการลองซ้ำแบบ one-shot
AUTH_TOKEN_MISMATCHถูกจำกัดให้ทำได้กับ endpoint ที่เชื่อถือได้เท่านั้น — loopback หรือwss://ที่มีtlsFingerprintแบบ pinnedwss://สาธารณะที่ไม่มีการ pin จะไม่เข้าเกณฑ์
- รายการ
hello-ok.auth.deviceTokensเพิ่มเติมคือ token สำหรับ bootstrap handoff เก็บรายการเหล่านี้ไว้เฉพาะเมื่อ connect ใช้ bootstrap auth บน transport ที่เชื่อถือได้ เช่นwss://หรือการจับคู่แบบ loopback/local - หาก client ระบุ
deviceTokenหรือscopesอย่าง ชัดเจน ชุด scope ที่ ผู้เรียกขอยังคงเป็นแหล่งอ้างอิงหลัก; cached scopes จะถูกนำกลับมาใช้เฉพาะ เมื่อ client กำลังใช้ per-device token ที่เก็บไว้ซ้ำ - device token สามารถหมุนเวียน/เพิกถอนได้ผ่าน
device.token.rotateและdevice.token.revoke(ต้องมี scopeoperator.pairing) device.token.rotateส่งคืน metadata การหมุนเวียน โดยจะ echo replacement bearer token เฉพาะสำหรับการเรียกจากอุปกรณ์เดียวกันที่ยืนยันตัวตนด้วย device token นั้นอยู่แล้ว เพื่อให้ client แบบ token-only สามารถเก็บ replacement ของตนก่อน เชื่อมต่อใหม่ การหมุนเวียนแบบ shared/admin จะไม่ echo bearer token- การออก token การหมุนเวียน และการเพิกถอนยังคงถูกจำกัดไว้กับชุด role ที่อนุมัติแล้ว ซึ่งบันทึกไว้ในรายการ pairing ของ device นั้น; การเปลี่ยนแปลง token ไม่สามารถขยายหรือ กำหนดเป้าหมาย role ของ device ที่การอนุมัติ pairing ไม่เคยให้ไว้
- สำหรับ paired-device token sessions การจัดการ device จะจำกัดขอบเขตกับตนเอง เว้นแต่
ผู้เรียกจะมี
operator.adminด้วย: ผู้เรียกที่ไม่ใช่ admin สามารถลบ/เพิกถอน/หมุนเวียน ได้เฉพาะรายการ device ของตนเอง เท่านั้น device.token.rotateและdevice.token.revokeยังตรวจสอบชุด scope ของ operator token เป้าหมายเทียบกับ scopes ของ session ปัจจุบันของผู้เรียก ผู้เรียกที่ไม่ใช่ admin ไม่สามารถหมุนเวียนหรือเพิกถอน operator token ที่กว้างกว่าที่ตนมีอยู่แล้ว- ความล้มเหลวในการยืนยันตัวตนมี
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)
- พฤติกรรมของ client สำหรับ
AUTH_TOKEN_MISMATCH:- client ที่เชื่อถือได้อาจลองซ้ำแบบจำกัดหนึ่งครั้งด้วย cached per-device token
- หากการลองซ้ำนั้นล้มเหลว client ควรหยุดวงวนการเชื่อมต่อใหม่อัตโนมัติและแสดงคำแนะนำการดำเนินการสำหรับ operator
AUTH_SCOPE_MISMATCHหมายความว่า device token ถูกจดจำได้แต่ไม่ครอบคลุม role/scopes ที่ขอ client ไม่ควรนำเสนอเรื่องนี้ว่าเป็น token ที่ไม่ถูกต้อง; ให้แจ้ง operator ให้จับคู่ใหม่หรืออนุมัติสัญญา scope ที่แคบกว่า/กว้างกว่า
ข้อมูลระบุตัวตนของ device + การจับคู่
- node ควรมีข้อมูลระบุตัวตนของ device ที่เสถียร (
device.id) ซึ่งได้มาจาก fingerprint ของ keypair - Gateway ออก token ต่อ device + role
- การอนุมัติการจับคู่จำเป็นสำหรับ device ID ใหม่ เว้นแต่เปิดใช้การอนุมัติอัตโนมัติแบบ local
- การอนุมัติอัตโนมัติของการจับคู่มีศูนย์กลางอยู่ที่การเชื่อมต่อ direct local loopback
- OpenClaw ยังมีเส้นทาง self-connect แบบ backend/container-local ที่จำกัดสำหรับ โฟลว์ helper แบบ shared-secret ที่เชื่อถือได้
- การเชื่อมต่อ tailnet หรือ LAN บน host เดียวกันยังคงถือว่าเป็น remote สำหรับการจับคู่และ ต้องได้รับการอนุมัติ
- โดยปกติ WS client จะใส่ข้อมูลระบุตัวตน
deviceระหว่างconnect(operator + node) ข้อยกเว้น operator ที่ไม่มี device มีเฉพาะเส้นทางความไว้วางใจที่ระบุชัดเจน:gateway.controlUi.allowInsecureAuth=trueสำหรับความเข้ากันได้กับ HTTP ที่ไม่ปลอดภัยเฉพาะ localhost- การยืนยันตัวตน Control UI ของ operator ด้วย
gateway.auth.mode: "trusted-proxy"ที่สำเร็จ gateway.controlUi.dangerouslyDisableDeviceAuth=true(break-glass, ลดระดับความปลอดภัยอย่างรุนแรง)- RPC backend
gateway-clientแบบ direct-loopback ที่ยืนยันตัวตนด้วย shared gateway token/password
- ทุกการเชื่อมต่อต้องลงนาม nonce
connect.challengeที่ server ให้มา
diagnostics การย้าย device auth
สำหรับ client รุ่นเก่าที่ยังใช้พฤติกรรมการลงนามก่อน challenge ตอนนี้connect จะส่งคืน
code รายละเอียด DEVICE_AUTH_* ใต้ error.details.code พร้อม error.details.reason ที่เสถียร
ความล้มเหลวทั่วไปในการย้าย:
| ข้อความ | details.code | details.reason | ความหมาย |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | client ละเว้น device.nonce (หรือส่งค่าว่าง) |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | client ลงนามด้วย 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 ไม่ตรงกับ fingerprint ของ public key |
device public key invalid | DEVICE_AUTH_PUBLIC_KEY_INVALID | device-public-key | รูปแบบ/canonicalization ของ public key ล้มเหลว |
- รอ
connect.challengeเสมอ - ลงนาม payload v2 ที่มี server nonce
- ส่ง nonce เดียวกันใน
connect.params.device.nonce - payload ลายเซ็นที่แนะนำคือ
v3ซึ่งผูกplatformและdeviceFamilyเพิ่มเติมจากฟิลด์ device/client/role/scopes/token/nonce - ลายเซ็น
v2รุ่นเก่ายังคงถูกยอมรับเพื่อความเข้ากันได้ แต่การ pin metadata ของ paired-device ยังคงควบคุมนโยบายคำสั่งเมื่อเชื่อมต่อใหม่
TLS + การ pin
- รองรับ TLS สำหรับการเชื่อมต่อ WS
- client อาจ pin fingerprint ของใบรับรอง Gateway ได้ตามต้องการ (ดู config
gateway.tlsรวมถึงgateway.remote.tlsFingerprintหรือ CLI--tls-fingerprint)
ขอบเขต
protocol นี้เปิดเผย API ของ Gateway แบบเต็ม (status, channels, models, chat, agent, sessions, nodes, approvals ฯลฯ) พื้นผิวที่แน่นอนถูกกำหนดโดย TypeBox schemas ในsrc/gateway/protocol/schema.ts