Gateway
Protokol Gateway
Gateway WS protocol adalah satu control plane + transport node untuk OpenClaw. Semua klien (CLI, UI web, aplikasi macOS, node iOS/Android, node headless) terhubung melalui WebSocket dan mendeklarasikan peran + cakupan mereka saat handshake.
Transport
- WebSocket, frame teks dengan payload JSON.
- Frame pertama harus berupa permintaan
connect. - Frame sebelum koneksi dibatasi hingga 64 KiB. Setelah handshake berhasil, klien
harus mengikuti batas
hello-ok.policy.maxPayloaddanhello-ok.policy.maxBufferedBytes. Dengan diagnostik diaktifkan, frame masuk yang terlalu besar dan buffer keluar yang lambat memancarkan eventpayload.largesebelum gateway menutup atau menjatuhkan frame yang terdampak. Event ini menyimpan ukuran, batas, surface, dan kode alasan yang aman. Event ini tidak menyimpan isi pesan, isi lampiran, isi frame mentah, token, cookie, atau nilai rahasia.
Handshake (connect)
Gateway → Klien (tantangan sebelum koneksi):
{
"type": "event",
"event": "connect.challenge",
"payload": { "nonce": "…", "ts": 1737264000000 }
}
Klien → Gateway:
{
"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 → Klien:
{
"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
}
}
}
Saat Gateway masih menyelesaikan startup sidecar, permintaan connect dapat
mengembalikan error UNAVAILABLE yang dapat dicoba ulang dengan details.reason diatur ke
"startup-sidecars" dan retryAfterMs. Klien harus mencoba ulang respons itu
dalam keseluruhan anggaran koneksi mereka, alih-alih menampilkannya sebagai kegagalan
handshake terminal.
server, features, snapshot, dan policy semuanya diwajibkan oleh skema
(src/gateway/protocol/schema/frames.ts). auth juga diwajibkan dan melaporkan
peran/cakupan yang dinegosiasikan. pluginSurfaceUrls bersifat opsional dan memetakan nama surface
Plugin, seperti canvas, ke URL yang dihosting dengan cakupan.
URL surface Plugin bercakupan dapat kedaluwarsa. Node dapat memanggil
node.pluginSurface.refresh dengan { "surface": "canvas" } untuk menerima entri baru
di pluginSurfaceUrls. Refaktor Plugin Canvas eksperimental tidak
mendukung jalur kompatibilitas canvasHostUrl, canvasCapability, atau
node.canvas.capability.refresh yang sudah tidak digunakan; klien native dan
gateway saat ini harus menggunakan surface Plugin.
Saat tidak ada token perangkat yang diterbitkan, hello-ok.auth melaporkan izin yang dinegosiasikan
tanpa field token:
{
"auth": {
"role": "operator",
"scopes": ["operator.read", "operator.write"]
}
}
Klien backend same-process tepercaya (client.id: "gateway-client",
client.mode: "backend") dapat menghilangkan device pada koneksi loopback langsung saat
mereka diautentikasi dengan token/kata sandi gateway bersama. Jalur ini dicadangkan
untuk RPC control-plane internal dan mencegah baseline pairing CLI/perangkat yang basi
memblokir pekerjaan backend lokal seperti pembaruan sesi subagen. Klien jarak jauh,
klien origin browser, klien node, serta klien token perangkat/identitas perangkat eksplisit
tetap menggunakan pemeriksaan pairing dan peningkatan cakupan normal.
Saat token perangkat diterbitkan, hello-ok juga menyertakan:
{
"auth": {
"deviceToken": "…",
"role": "operator",
"scopes": ["operator.read", "operator.write"]
}
}
Selama handoff bootstrap tepercaya, hello-ok.auth juga dapat menyertakan entri
peran terbatas tambahan di deviceTokens:
{
"auth": {
"deviceToken": "…",
"role": "node",
"scopes": [],
"deviceTokens": [
{
"deviceToken": "…",
"role": "operator",
"scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]
}
]
}
}
Untuk alur bootstrap node/operator bawaan, token node utama tetap
scopes: [] dan token operator apa pun yang diserahkan tetap dibatasi pada allowlist operator
bootstrap (operator.approvals, operator.read,
operator.talk.secrets, operator.write). Pemeriksaan cakupan bootstrap tetap
berprefiks peran: entri operator hanya memenuhi permintaan operator, dan peran non-operator
tetap membutuhkan cakupan di bawah prefiks perannya sendiri.
Contoh Node
{
"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": "…"
}
}
}
Pembingkaian
- Permintaan:
{type:"req", id, method, params} - Respons:
{type:"res", id, ok, payload|error} - Event:
{type:"event", event, payload, seq?, stateVersion?}
Metode dengan efek samping memerlukan kunci idempotensi (lihat skema).
Peran + cakupan
Untuk model cakupan operator lengkap, pemeriksaan saat persetujuan, dan semantik rahasia bersama, lihat Cakupan operator.
Peran
operator= klien control plane (CLI/UI/otomasi).node= host kapabilitas (camera/screen/canvas/system.run).
Cakupan (operator)
Cakupan umum:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config dengan includeSecrets: true memerlukan operator.talk.secrets
(atau operator.admin).
Metode RPC Gateway yang didaftarkan Plugin dapat meminta cakupan operatornya sendiri, tetapi
prefiks admin inti yang dicadangkan (config.*, exec.approvals.*, wizard.*,
update.*) selalu diresolve ke operator.admin.
Cakupan metode hanyalah gerbang pertama. Beberapa perintah slash yang dijangkau melalui
chat.send menerapkan pemeriksaan tingkat perintah yang lebih ketat di atasnya. Misalnya, penulisan
/config set dan /config unset persisten memerlukan operator.admin.
node.pair.approve juga memiliki pemeriksaan cakupan tambahan saat persetujuan di atas
cakupan metode dasar:
- permintaan tanpa perintah:
operator.pairing - permintaan dengan perintah node non-exec:
operator.pairing+operator.write - permintaan yang menyertakan
system.run,system.run.prepare, atausystem.which:operator.pairing+operator.admin
Caps/perintah/izin (node)
Node mendeklarasikan klaim kapabilitas saat koneksi:
caps: kategori kapabilitas tingkat tinggi seperticamera,canvas,screen,location,voice, dantalk.commands: allowlist perintah untuk invoke.permissions: toggle granular (mis.screen.record,camera.capture).
Gateway memperlakukan ini sebagai klaim dan memberlakukan allowlist sisi server.
Presence
system-presencemengembalikan entri yang dikunci berdasarkan identitas perangkat.- Entri presence menyertakan
deviceId,roles, danscopesagar UI dapat menampilkan satu baris per perangkat bahkan saat perangkat terhubung sebagai operator dan node sekaligus. node.listmenyertakan field opsionallastSeenAtMsdanlastSeenReason. Node yang terhubung melaporkan waktu koneksi mereka saat ini sebagailastSeenAtMsdengan alasanconnect; node yang sudah dipairing juga dapat melaporkan presence latar belakang yang tahan lama saat event node tepercaya memperbarui metadata pairing mereka.
Event alive latar belakang Node
Node dapat memanggil node.event dengan event: "node.presence.alive" untuk mencatat bahwa node yang sudah dipairing
hidup selama wake latar belakang tanpa menandainya terhubung.
{
"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 adalah enum tertutup: background, silent_push, bg_app_refresh,
significant_location, manual, atau connect. String trigger yang tidak dikenal dinormalisasi ke
background oleh gateway sebelum persistensi. Event ini hanya tahan lama untuk sesi perangkat node
yang terautentikasi; sesi tanpa perangkat atau belum dipairing mengembalikan handled: false.
Gateway yang berhasil mengembalikan hasil terstruktur:
{
"ok": true,
"event": "node.presence.alive",
"handled": true,
"reason": "persisted"
}
Gateway lama mungkin masih mengembalikan { "ok": true } untuk node.event; klien harus memperlakukannya sebagai
RPC yang diakui, bukan sebagai persistensi presence yang tahan lama.
Pencakupan event broadcast
Event broadcast WebSocket yang didorong server diberi gerbang cakupan agar sesi bercakupan pairing atau khusus node tidak menerima konten sesi secara pasif.
- Frame chat, agen, dan hasil tool (termasuk event
agentyang distream dan hasil pemanggilan tool) memerlukan setidaknyaoperator.read. Sesi tanpaoperator.readmelewati frame ini sepenuhnya. - Broadcast
plugin.*yang didefinisikan Plugin digerbangkan keoperator.writeatauoperator.admin, bergantung pada cara Plugin mendaftarkannya. - Event status dan transport (
heartbeat,presence,tick, siklus hidup connect/disconnect, dll.) tetap tidak dibatasi agar kesehatan transport tetap dapat diamati oleh setiap sesi yang terautentikasi. - Keluarga event broadcast yang tidak dikenal diberi gerbang cakupan secara default (fail-closed) kecuali handler terdaftar secara eksplisit melonggarkannya.
Setiap koneksi klien mempertahankan nomor urutan per kliennya sendiri sehingga broadcast mempertahankan pengurutan monotonik pada socket tersebut bahkan saat klien yang berbeda melihat subset berbeda yang difilter berdasarkan cakupan dari stream event.
Keluarga metode RPC umum
Surface WS publik lebih luas daripada contoh handshake/auth di atas. Ini
bukan dump yang dihasilkan — hello-ok.features.methods adalah daftar discovery
konservatif yang dibangun dari src/gateway/server-methods-list.ts ditambah ekspor metode
Plugin/channel yang dimuat. Perlakukan ini sebagai discovery fitur, bukan enumerasi lengkap
dari src/gateway/server-methods/*.ts.
Sistem dan identitas
healthmengembalikan snapshot kesehatan gateway yang di-cache atau baru diprobe.diagnostics.stabilitymengembalikan perekam stabilitas diagnostik terbatas terbaru. Ini menyimpan metadata operasional seperti nama event, hitungan, ukuran byte, pembacaan memori, status antrean/sesi, nama channel/Plugin, dan id sesi. Ini tidak menyimpan teks chat, body webhook, output tool, body permintaan atau respons mentah, token, cookie, atau nilai rahasia. Cakupan baca operator diperlukan.statusmengembalikan ringkasan gateway bergaya/status; field sensitif hanya disertakan untuk klien operator bercakupan admin.gateway.identity.getmengembalikan identitas perangkat gateway yang digunakan oleh alur relay dan pairing.system-presencemengembalikan snapshot presence saat ini untuk perangkat operator/node yang terhubung.system-eventmenambahkan event sistem dan dapat memperbarui/menyiarkan konteks presence.last-heartbeatmengembalikan event heartbeat terakhir yang dipersisten.set-heartbeatsmengaktifkan atau menonaktifkan pemrosesan heartbeat pada gateway.
Model dan penggunaan
models.listmengembalikan katalog model yang diizinkan runtime. Berikan{ "view": "configured" }untuk model terkonfigurasi berukuran pemilih (agents.defaults.modelsterlebih dahulu, lalumodels.providers.*.models), atau{ "view": "all" }untuk katalog lengkap.usage.statusmengembalikan ringkasan jendela penggunaan provider/kuota tersisa.usage.costmengembalikan ringkasan penggunaan biaya teragregasi untuk rentang tanggal.doctor.memory.statusmengembalikan kesiapan memori vektor / embedding cache untuk workspace agen default aktif. Berikan{ "probe": true }atau{ "deep": true }hanya ketika pemanggil secara eksplisit menginginkan ping provider embedding langsung.doctor.memory.remHarnessmengembalikan pratinjau harness REM yang terbatas dan hanya baca untuk klien control-plane jarak jauh. Ini dapat menyertakan path workspace, cuplikan memori, markdown berlandasan yang dirender, dan kandidat promosi mendalam, sehingga pemanggil memerlukanoperator.read.sessions.usagemengembalikan ringkasan penggunaan per sesi.sessions.usage.timeseriesmengembalikan penggunaan deret waktu untuk satu sesi.sessions.usage.logsmengembalikan entri log penggunaan untuk satu sesi.
Channel dan pembantu login
channels.statusmengembalikan ringkasan status channel/plugin bawaan + terbundel.channels.logoutmengeluarkan channel/akun tertentu jika channel mendukung logout.web.login.startmemulai alur login QR/web untuk provider channel web berkemampuan QR saat ini.web.login.waitmenunggu alur login QR/web tersebut selesai dan memulai channel jika berhasil.push.testmengirim push APNs uji ke node iOS terdaftar.voicewake.getmengembalikan pemicu wake-word yang tersimpan.voicewake.setmemperbarui pemicu wake-word dan menyiarkan perubahan.
Perpesanan dan log
sendadalah RPC pengiriman keluar langsung untuk pengiriman yang ditargetkan ke channel/akun/thread di luar runner chat.logs.tailmengembalikan tail log file Gateway yang dikonfigurasi dengan kontrol cursor/limit dan byte maksimum.
Talk dan TTS
talk.catalogmengembalikan katalog provider Talk hanya baca untuk ucapan, transkripsi streaming, dan suara realtime. Ini mencakup ID provider, label, status terkonfigurasi, ID model/suara yang diekspos, mode kanonis, transport, strategi brain, serta flag audio/kapabilitas realtime tanpa mengembalikan rahasia provider atau mengubah config global.talk.configmengembalikan payload config Talk efektif;includeSecretsmemerlukanoperator.talk.secrets(atauoperator.admin).talk.session.createmembuat sesi Talk milik Gateway untukrealtime/gateway-relay,transcription/gateway-relay, ataustt-tts/managed-room.brain: "direct-tools"memerlukanoperator.admin.talk.session.joinmemvalidasi token sesi managed-room, memancarkan eventsession.readyatausession.replacedsesuai kebutuhan, dan mengembalikan metadata room/sesi beserta event Talk terbaru tanpa token plaintext atau hash token tersimpan.talk.session.appendAudiomenambahkan audio input PCM base64 ke sesi relay realtime dan transkripsi milik Gateway.talk.session.startTurn,talk.session.endTurn, dantalk.session.cancelTurnmenggerakkan siklus hidup turn managed-room dengan penolakan turn usang sebelum state dibersihkan.talk.session.cancelOutputmenghentikan output audio asisten, terutama untuk interupsi berpagar VAD dalam sesi relay Gateway.talk.session.submitToolResultmenyelesaikan panggilan tool provider yang dipancarkan oleh sesi relay realtime milik Gateway.talk.session.closemenutup sesi relay, transkripsi, atau managed-room milik Gateway dan memancarkan event Talk terminal.talk.modemenetapkan/menyiarkan state mode Talk saat ini untuk klien WebChat/Control UI.talk.client.createmembuat sesi provider realtime milik klien menggunakanwebrtcatauprovider-websocketsementara Gateway memiliki config, kredensial, instruksi, dan kebijakan tool.talk.client.toolCallmemungkinkan transport realtime milik klien meneruskan panggilan tool provider ke kebijakan Gateway. Tool pertama yang didukung adalahopenclaw_agent_consult; klien menerima ID run dan menunggu event siklus hidup chat normal sebelum mengirimkan hasil tool spesifik provider.talk.eventadalah satu-satunya channel event Talk untuk realtime, transkripsi, STT/TTS, managed-room, telephony, dan adaptor meeting.talk.speakmenyintesis ucapan melalui provider ucapan Talk aktif.tts.statusmengembalikan state TTS aktif, provider aktif, provider fallback, dan state config provider.tts.providersmengembalikan inventaris provider TTS yang terlihat.tts.enabledantts.disablemengaktifkan/menonaktifkan state preferensi TTS.tts.setProvidermemperbarui provider TTS pilihan.tts.convertmenjalankan konversi teks-ke-ucapan satu kali.
Rahasia, config, pembaruan, dan wizard
secrets.reloadmenyelesaikan ulang SecretRef aktif dan menukar state rahasia runtime hanya jika berhasil sepenuhnya.secrets.resolvemenyelesaikan penugasan rahasia target-perintah untuk set perintah/target tertentu.config.getmengembalikan snapshot dan hash config saat ini.config.setmenulis payload config yang tervalidasi.config.patchmenggabungkan pembaruan config parsial.config.applymemvalidasi + mengganti payload config lengkap.config.schemamengembalikan payload skema config live yang digunakan oleh Control UI dan tooling CLI: skema,uiHints, versi, dan metadata pembuatan, termasuk metadata skema plugin + channel ketika runtime dapat memuatnya. Skema mencakup metadata fieldtitle/descriptionyang diturunkan dari label dan teks bantuan yang sama yang digunakan UI, termasuk cabang komposisi objek bertingkat, wildcard, item array, dananyOf/oneOf/allOfketika dokumentasi field yang cocok ada.config.schema.lookupmengembalikan payload lookup berbasis path untuk satu path config: path ternormalisasi, node skema dangkal, hint yang cocok +hintPath, dan ringkasan child langsung untuk penelusuran UI/CLI. Node skema lookup mempertahankan dokumentasi yang terlihat pengguna dan field validasi umum (title,description,type,enum,const,format,pattern, batas numerik/string/array/objek, dan flag sepertiadditionalProperties,deprecated,readOnly,writeOnly). Ringkasan child mengeksposkey,pathternormalisasi,type,required,hasChildren, besertahint/hintPathyang cocok.update.runmenjalankan alur pembaruan gateway dan menjadwalkan restart hanya ketika pembaruan itu sendiri berhasil; pemanggil dengan sesi dapat menyertakancontinuationMessageagar startup melanjutkan satu turn agen lanjutan melalui antrean kelanjutan restart. Pembaruan package-manager memaksa restart pembaruan yang tidak ditunda dan tanpa cooldown setelah pertukaran paket sehingga proses Gateway lama tidak terus lazy-loading dari pohondistyang telah diganti.update.statusmengembalikan sentinel restart pembaruan cache terbaru, termasuk versi berjalan pasca-restart jika tersedia.wizard.start,wizard.next,wizard.status, danwizard.cancelmengekspos wizard onboarding melalui WS RPC.
Pembantu agen dan workspace
agents.listmengembalikan entri agen terkonfigurasi, termasuk model efektif dan metadata runtime.agents.create,agents.update, danagents.deletemengelola catatan agen dan wiring workspace.agents.files.list,agents.files.get, danagents.files.setmengelola file workspace bootstrap yang diekspos untuk agen.artifacts.list,artifacts.get, danartifacts.downloadmengekspos ringkasan artefak turunan transkrip dan unduhan untuk cakupansessionKey,runId, atautaskIdeksplisit. Kueri run dan tugas menyelesaikan sesi pemilik di sisi server dan hanya mengembalikan media transkrip dengan provenance yang cocok; sumber URL tidak aman atau lokal mengembalikan unduhan yang tidak didukung alih-alih mengambil di sisi server.environments.listdanenvironments.statusmengekspos penemuan environment lokal Gateway dan node yang hanya baca untuk klien SDK.agent.identity.getmengembalikan identitas asisten efektif untuk agen atau sesi.agent.waitmenunggu run selesai dan mengembalikan snapshot terminal jika tersedia.
Kontrol sesi
sessions.listmengembalikan indeks sesi saat ini, termasuk metadataagentRuntimeper baris ketika backend runtime agen dikonfigurasi.sessions.subscribedansessions.unsubscribemengaktifkan/menonaktifkan langganan event perubahan sesi untuk klien WS saat ini.sessions.messages.subscribedansessions.messages.unsubscribemengaktifkan/menonaktifkan langganan event transkrip/pesan untuk satu sesi.sessions.previewmengembalikan pratinjau transkrip terbatas untuk kunci sesi tertentu.sessions.describemengembalikan satu baris sesi Gateway untuk kunci sesi persis.sessions.resolvemenyelesaikan atau mengkanoniskan target sesi.sessions.createmembuat entri sesi baru.sessions.sendmengirim pesan ke sesi yang sudah ada.sessions.steeradalah varian interupsi-dan-arahkan untuk sesi aktif.sessions.abortmembatalkan pekerjaan aktif untuk sesi. Pemanggil dapat memberikankeybesertarunIdopsional, atau hanya memberikanrunIduntuk run aktif yang dapat diselesaikan Gateway ke sesi.sessions.patchmemperbarui metadata/override sesi dan melaporkan model kanonis yang terselesaikan besertaagentRuntimeefektif.sessions.reset,sessions.delete, dansessions.compactmelakukan pemeliharaan sesi.sessions.getmengembalikan baris sesi tersimpan lengkap.- Eksekusi chat tetap menggunakan
chat.history,chat.send,chat.abort, danchat.inject.chat.historydinormalisasi untuk tampilan bagi klien UI: tag direktif inline dihapus dari teks yang terlihat, payload XML panggilan tool teks biasa (termasuk<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>, dan blok panggilan tool yang terpotong) serta token kontrol model ASCII/full-width yang bocor dihapus, baris asisten token-senyap murni sepertiNO_REPLY/no_replypersis dihilangkan, dan baris yang terlalu besar dapat diganti dengan placeholder.
Pemasangan perangkat dan token perangkat
device.pair.listmengembalikan perangkat tertaut yang tertunda dan disetujui.device.pair.approve,device.pair.reject, dandevice.pair.removemengelola catatan pemasangan perangkat.device.token.rotatemerotasi token perangkat tertaut dalam batas peran yang disetujui dan cakupan pemanggil.device.token.revokemencabut token perangkat tertaut dalam batas peran yang disetujui dan cakupan pemanggil.
Pemasangan node, pemanggilan, dan pekerjaan tertunda
node.pair.request,node.pair.list,node.pair.approve,node.pair.reject,node.pair.remove, dannode.pair.verifymencakup pemasangan node dan verifikasi bootstrap.node.listdannode.describemengembalikan state node yang dikenal/terhubung.node.renamememperbarui label node tertaut.node.invokemeneruskan perintah ke node terhubung.node.invoke.resultmengembalikan hasil untuk permintaan invoke.node.eventmembawa event yang berasal dari node kembali ke gateway.node.pending.pulldannode.pending.ackadalah API antrean node terhubung.node.pending.enqueuedannode.pending.drainmengelola pekerjaan tertunda yang tahan lama untuk node offline/terputus.
Keluarga persetujuan
exec.approval.request,exec.approval.get,exec.approval.list, danexec.approval.resolvemencakup permintaan persetujuan eksekusi sekali jalan serta pencarian/pemutaran ulang persetujuan tertunda.exec.approval.waitDecisionmenunggu satu persetujuan eksekusi tertunda dan mengembalikan keputusan akhir (ataunullsaat waktu habis).exec.approvals.getdanexec.approvals.setmengelola snapshot kebijakan persetujuan eksekusi Gateway.exec.approvals.node.getdanexec.approvals.node.setmengelola kebijakan persetujuan eksekusi lokal Node melalui perintah relai Node.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecision, danplugin.approval.resolvemencakup alur persetujuan yang ditentukan Plugin.
Otomasi, Skills, dan alat
- Otomasi:
wakemenjadwalkan injeksi teks bangun segera atau pada Heartbeat berikutnya;cron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runsmengelola pekerjaan terjadwal. - Skills dan alat:
commands.list,skills.*,tools.catalog,tools.effective,tools.invoke.
Keluarga peristiwa umum
chat: pembaruan obrolan UI sepertichat.injectdan peristiwa obrolan khusus transkrip lainnya.session.messagedansession.tool: pembaruan transkrip/stream peristiwa untuk sesi yang dilanggan.sessions.changed: indeks sesi atau metadata berubah.presence: pembaruan snapshot kehadiran sistem.tick: peristiwa keepalive / liveness berkala.health: pembaruan snapshot kesehatan Gateway.heartbeat: pembaruan stream peristiwa Heartbeat.cron: peristiwa perubahan proses/job Cron.shutdown: notifikasi penghentian Gateway.node.pair.requested/node.pair.resolved: siklus hidup pemasangan Node.node.invoke.request: siaran permintaan pemanggilan Node.device.pair.requested/device.pair.resolved: siklus hidup perangkat terpasang.voicewake.changed: konfigurasi pemicu kata bangun berubah.exec.approval.requested/exec.approval.resolved: siklus hidup persetujuan eksekusi.plugin.approval.requested/plugin.approval.resolved: siklus hidup persetujuan Plugin.
Metode pembantu Node
- Node dapat memanggil
skills.binsuntuk mengambil daftar terkini executable Skills untuk pemeriksaan izinkan otomatis.
Metode pembantu operator
- Operator dapat memanggil
commands.list(operator.read) untuk mengambil inventaris perintah runtime untuk sebuah agen.agentIdbersifat opsional; hilangkan untuk membaca workspace agen default.scopemengontrol permukaan mana yang ditargetkan olehnameutama:textmengembalikan token perintah teks utama tanpa awalan/nativedan jalur defaultbothmengembalikan nama native yang sadar penyedia saat tersedia
textAliasesmembawa alias garis miring persis seperti/modeldan/m.nativeNamemembawa nama perintah native yang sadar penyedia saat ada.providerbersifat opsional dan hanya memengaruhi penamaan native plus ketersediaan perintah Plugin native.includeArgs=falsemenghilangkan metadata argumen terserialisasi dari respons.
- Operator dapat memanggil
tools.catalog(operator.read) untuk mengambil katalog alat runtime untuk sebuah agen. Respons menyertakan alat yang dikelompokkan dan metadata asal:source:coreataupluginpluginId: pemilik Plugin saatsource="plugin"optional: apakah alat Plugin bersifat opsional
- Operator dapat memanggil
tools.effective(operator.read) untuk mengambil inventaris alat yang efektif runtime untuk sebuah sesi.sessionKeywajib.- Gateway menurunkan konteks runtime tepercaya dari sesi di sisi server alih-alih menerima konteks autentikasi atau pengiriman yang disediakan pemanggil.
- Respons bersifat terbatas pada sesi dan mencerminkan apa yang dapat digunakan percakapan aktif saat ini, termasuk alat inti, Plugin, dan kanal.
- Operator dapat memanggil
tools.invoke(operator.write) untuk memanggil satu alat yang tersedia melalui jalur kebijakan Gateway yang sama dengan/tools/invoke.namewajib.args,sessionKey,agentId,confirm, danidempotencyKeybersifat opsional.- Jika
sessionKeydanagentIdsama-sama ada, agen sesi yang diselesaikan harus cocok denganagentId. - Respons adalah amplop yang menghadap SDK dengan
ok,toolName,outputopsional, dan fielderrorbertipe. Penolakan persetujuan atau kebijakan mengembalikanok:falsedalam payload alih-alih melewati pipeline kebijakan alat Gateway.
- Operator dapat memanggil
skills.status(operator.read) untuk mengambil inventaris Skills yang terlihat untuk sebuah agen.agentIdbersifat opsional; hilangkan untuk membaca workspace agen default.- Respons menyertakan kelayakan, persyaratan yang hilang, pemeriksaan config, dan opsi instalasi yang disanitasi tanpa mengekspos nilai rahasia mentah.
- Operator dapat memanggil
skills.searchdanskills.detail(operator.read) untuk metadata penemuan ClawHub. - Operator dapat memanggil
skills.install(operator.admin) dalam dua mode:- Mode ClawHub:
{ source: "clawhub", slug, version?, force? }memasang folder skill ke direktoriskills/workspace agen default. - Mode penginstal Gateway:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }menjalankan aksimetadata.openclaw.installyang dideklarasikan pada host Gateway.
- Mode ClawHub:
- Operator dapat memanggil
skills.update(operator.admin) dalam dua mode:- Mode ClawHub memperbarui satu slug terlacak atau semua instalasi ClawHub terlacak dalam workspace agen default.
- Mode config mem-patch nilai
skills.entries.<skillKey>sepertienabled,apiKey, danenv.
Tampilan models.list
models.list menerima parameter view opsional:
- Dihilangkan atau
"default": perilaku runtime saat ini. Jikaagents.defaults.modelsdikonfigurasi, respons adalah katalog yang diizinkan; jika tidak, respons adalah katalog Gateway lengkap. "configured": perilaku seukuran pemilih. Jikaagents.defaults.modelsdikonfigurasi, itu tetap menang. Jika tidak, respons menggunakan entri eksplisitmodels.providers.*.models, dengan fallback ke katalog lengkap hanya saat tidak ada baris model yang dikonfigurasi."all": katalog Gateway lengkap, melewatiagents.defaults.models. Gunakan ini untuk diagnostik dan UI penemuan, bukan pemilih model normal.
Persetujuan eksekusi
- Saat permintaan eksekusi membutuhkan persetujuan, Gateway menyiarkan
exec.approval.requested. - Klien operator menyelesaikan dengan memanggil
exec.approval.resolve(memerlukan scopeoperator.approvals). - Untuk
host=node,exec.approval.requestharus menyertakansystemRunPlan(argv/cwd/rawCommand/metadata sesi kanonis). Permintaan tanpasystemRunPlanditolak. - Setelah persetujuan, panggilan
node.invoke system.runyang diteruskan menggunakan kembalisystemRunPlankanonis tersebut sebagai konteks command/cwd/sesi otoritatif. - Jika pemanggil mengubah
command,rawCommand,cwd,agentId, atausessionKeyantara persiapan dan penerusansystem.runakhir yang disetujui, Gateway menolak proses tersebut alih-alih memercayai payload yang diubah.
Fallback pengiriman agen
- Permintaan
agentdapat menyertakandeliver=trueuntuk meminta pengiriman keluar. bestEffortDeliver=falsemempertahankan perilaku ketat: target pengiriman yang tidak terselesaikan atau hanya internal mengembalikanINVALID_REQUEST.bestEffortDeliver=truemengizinkan fallback ke eksekusi khusus sesi saat tidak ada rute eksternal yang dapat dikirim yang bisa diselesaikan (misalnya sesi internal/webchat atau config multi-kanal yang ambigu).
Pembuatan versi
PROTOCOL_VERSIONberada disrc/gateway/protocol/version.ts.- Klien mengirim
minProtocol+maxProtocol; server menolak ketidakcocokan. - Skema + model dihasilkan dari definisi TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Konstanta klien
Klien referensi di src/gateway/client.ts menggunakan default ini. Nilai
stabil di seluruh protokol v4 dan merupakan baseline yang diharapkan untuk klien pihak ketiga.
| Konstanta | Default | Sumber |
|---|---|---|
PROTOCOL_VERSION |
4 |
src/gateway/protocol/version.ts |
| Waktu habis permintaan (per RPC) | 30_000 ms |
src/gateway/client.ts (requestTimeoutMs) |
| Waktu habis praauth / challenge koneksi | 15_000 ms |
src/gateway/handshake-timeouts.ts (config/env dapat menaikkan anggaran server/klien terpasang) |
| Backoff reconnect awal | 1_000 ms |
src/gateway/client.ts (backoffMs) |
| Backoff reconnect maksimum | 30_000 ms |
src/gateway/client.ts (scheduleReconnect) |
| Clamp retry cepat setelah penutupan token perangkat | 250 ms |
src/gateway/client.ts |
Grace force-stop sebelum terminate() |
250 ms |
FORCE_STOP_TERMINATE_GRACE_MS |
Waktu habis default stopAndWait() |
1_000 ms |
STOP_AND_WAIT_TIMEOUT_MS |
Interval tick default (sebelum hello-ok) |
30_000 ms |
src/gateway/client.ts |
| Penutupan karena waktu habis tick | kode 4000 saat keheningan melebihi tickIntervalMs * 2 |
src/gateway/client.ts |
MAX_PAYLOAD_BYTES |
25 * 1024 * 1024 (25 MB) |
src/gateway/server-constants.ts |
Server mengiklankan policy.tickIntervalMs, policy.maxPayload,
dan policy.maxBufferedBytes yang efektif dalam hello-ok; klien sebaiknya menghormati nilai tersebut
alih-alih default sebelum handshake.
Auth
- Autentikasi Gateway rahasia bersama menggunakan
connect.params.auth.tokenatauconnect.params.auth.password, bergantung pada mode autentikasi yang dikonfigurasi. - Mode yang membawa identitas seperti Tailscale Serve
(
gateway.auth.allowTailscale: true) atau non-loopbackgateway.auth.mode: "trusted-proxy"memenuhi pemeriksaan autentikasi koneksi dari header permintaan, bukan dariconnect.params.auth.*. gateway.auth.mode: "none"untuk ingress privat melewati autentikasi koneksi rahasia bersama sepenuhnya; jangan mengekspos mode tersebut pada ingress publik/tidak tepercaya.- Setelah pairing, Gateway menerbitkan token perangkat yang dicakupkan ke peran
koneksi + cakupan. Token ini dikembalikan dalam
hello-ok.auth.deviceTokendan harus disimpan oleh klien untuk koneksi berikutnya. - Klien harus menyimpan
hello-ok.auth.deviceTokenutama setelah setiap koneksi yang berhasil. - Menghubungkan ulang dengan token perangkat yang tersimpan tersebut juga harus menggunakan kembali kumpulan cakupan tersetujui yang tersimpan untuk token itu. Ini mempertahankan akses baca/probe/status yang sudah diberikan dan menghindari koneksi ulang diam-diam menyusut ke cakupan implisit yang lebih sempit, hanya admin.
- Penyusunan autentikasi koneksi sisi klien (
selectConnectAuthdisrc/gateway/client.ts):auth.passwordbersifat ortogonal dan selalu diteruskan jika disetel.auth.tokendiisi menurut urutan prioritas: token bersama eksplisit terlebih dahulu, laludeviceTokeneksplisit, lalu token per perangkat tersimpan (dikunci berdasarkandeviceId+role).auth.bootstrapTokendikirim hanya ketika tidak satu pun di atas menghasilkanauth.token. Token bersama atau token perangkat apa pun yang ditemukan akan menekannya.- Promosi otomatis token perangkat tersimpan pada percobaan ulang sekali pakai
AUTH_TOKEN_MISMATCHdibatasi hanya untuk endpoint tepercaya — loopback, atauwss://dengantlsFingerprintyang dipin.wss://publik tanpa pinning tidak memenuhi syarat.
- Entri tambahan
hello-ok.auth.deviceTokensadalah token handoff bootstrap. Simpan hanya ketika koneksi menggunakan autentikasi bootstrap pada transport tepercaya sepertiwss://atau pairing loopback/lokal. - Jika klien memasok
deviceTokeneksplisit atauscopeseksplisit, kumpulan cakupan yang diminta pemanggil tersebut tetap otoritatif; cakupan yang di-cache hanya digunakan kembali ketika klien menggunakan kembali token per perangkat tersimpan. - Token perangkat dapat dirotasi/dicabut melalui
device.token.rotatedandevice.token.revoke(memerlukan cakupanoperator.pairing). device.token.rotatemengembalikan metadata rotasi. Ini menggemakan token bearer pengganti hanya untuk panggilan perangkat yang sama yang sudah terautentikasi dengan token perangkat tersebut, sehingga klien token-saja dapat menyimpan penggantinya sebelum menghubungkan ulang. Rotasi bersama/admin tidak menggemakan token bearer.- Penerbitan, rotasi, dan pencabutan token tetap dibatasi pada kumpulan peran tersetujui yang tercatat dalam entri pairing perangkat tersebut; mutasi token tidak dapat memperluas atau menargetkan peran perangkat yang tidak pernah diberikan oleh persetujuan pairing.
- Untuk sesi token perangkat yang sudah dipairing, pengelolaan perangkat bersifat tercakup sendiri kecuali
pemanggil juga memiliki
operator.admin: pemanggil non-admin hanya dapat menghapus/mencabut/merotasi entri perangkat miliknya sendiri. device.token.rotatedandevice.token.revokejuga memeriksa kumpulan cakupan token operator target terhadap cakupan sesi pemanggil saat ini. Pemanggil non-admin tidak dapat merotasi atau mencabut token operator yang lebih luas daripada yang sudah mereka miliki.- Kegagalan autentikasi menyertakan
error.details.codebeserta petunjuk pemulihan:error.details.canRetryWithDeviceToken(boolean)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- Perilaku klien untuk
AUTH_TOKEN_MISMATCH:- Klien tepercaya dapat mencoba satu percobaan ulang terbatas dengan token per perangkat yang di-cache.
- Jika percobaan ulang itu gagal, klien harus menghentikan loop koneksi ulang otomatis dan menampilkan panduan tindakan operator.
Identitas perangkat + pairing
- Node harus menyertakan identitas perangkat stabil (
device.id) yang diturunkan dari fingerprint keypair. - Gateway menerbitkan token per perangkat + peran.
- Persetujuan pairing diperlukan untuk ID perangkat baru kecuali persetujuan otomatis lokal diaktifkan.
- Persetujuan otomatis pairing berpusat pada koneksi direct local loopback.
- OpenClaw juga memiliki jalur self-connect backend/container-lokal yang sempit untuk alur helper rahasia bersama tepercaya.
- Koneksi tailnet atau LAN pada host yang sama tetap diperlakukan sebagai remote untuk pairing dan memerlukan persetujuan.
- Klien WS biasanya menyertakan identitas
deviceselamaconnect(operator + node). Satu-satunya pengecualian operator tanpa perangkat adalah jalur kepercayaan eksplisit:gateway.controlUi.allowInsecureAuth=trueuntuk kompatibilitas HTTP tidak aman khusus localhost.- autentikasi Control UI operator
gateway.auth.mode: "trusted-proxy"yang berhasil. gateway.controlUi.dangerouslyDisableDeviceAuth=true(break-glass, penurunan keamanan serius).- RPC backend
gateway-clientdirect-loopback yang diautentikasi dengan token/kata sandi Gateway bersama.
- Semua koneksi harus menandatangani nonce
connect.challengeyang disediakan server.
Diagnostik migrasi autentikasi perangkat
Untuk klien lama yang masih menggunakan perilaku penandatanganan pra-challenge, connect kini mengembalikan
kode detail DEVICE_AUTH_* di bawah error.details.code dengan error.details.reason yang stabil.
Kegagalan migrasi umum:
| Pesan | details.code | details.reason | Arti |
|---|---|---|---|
device nonce required |
DEVICE_AUTH_NONCE_REQUIRED |
device-nonce-missing |
Klien menghilangkan device.nonce (atau mengirim kosong). |
device nonce mismatch |
DEVICE_AUTH_NONCE_MISMATCH |
device-nonce-mismatch |
Klien menandatangani dengan nonce yang stale/salah. |
device signature invalid |
DEVICE_AUTH_SIGNATURE_INVALID |
device-signature |
Payload tanda tangan tidak cocok dengan payload v2. |
device signature expired |
DEVICE_AUTH_SIGNATURE_EXPIRED |
device-signature-stale |
Timestamp yang ditandatangani berada di luar skew yang diizinkan. |
device identity mismatch |
DEVICE_AUTH_DEVICE_ID_MISMATCH |
device-id-mismatch |
device.id tidak cocok dengan fingerprint kunci publik. |
device public key invalid |
DEVICE_AUTH_PUBLIC_KEY_INVALID |
device-public-key |
Format/kanonikisasi kunci publik gagal. |
Target migrasi:
- Selalu tunggu
connect.challenge. - Tanda tangani payload v2 yang menyertakan nonce server.
- Kirim nonce yang sama dalam
connect.params.device.nonce. - Payload tanda tangan yang disarankan adalah
v3, yang mengikatplatformdandeviceFamilyselain field perangkat/klien/peran/cakupan/token/nonce. - Tanda tangan legacy
v2tetap diterima untuk kompatibilitas, tetapi pinning metadata perangkat yang dipairing tetap mengontrol kebijakan perintah saat koneksi ulang.
TLS + pinning
- TLS didukung untuk koneksi WS.
- Klien secara opsional dapat melakukan pin pada fingerprint sertifikat Gateway (lihat konfigurasi
gateway.tlsplusgateway.remote.tlsFingerprintatau CLI--tls-fingerprint).
Cakupan
Protokol ini mengekspos API Gateway penuh (status, kanal, model, chat,
agen, sesi, node, persetujuan, dll.). Permukaan tepatnya ditentukan oleh
skema TypeBox di src/gateway/protocol/schema.ts.