Control UI เป็นแอปหน้าเดียว Vite + Lit ขนาดเล็กที่ Gateway ให้บริการ:Documentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
- ค่าเริ่มต้น:
http://<host>:18789/ - คำนำหน้าเสริม: ตั้งค่า
gateway.controlUi.basePath(เช่น/openclaw)
เปิดอย่างรวดเร็ว (ภายในเครื่อง)
หาก Gateway กำลังทำงานบนคอมพิวเตอร์เครื่องเดียวกัน ให้เปิด: หากหน้าเว็บโหลดไม่สำเร็จ ให้เริ่ม Gateway ก่อน:openclaw gateway
ระบบส่งข้อมูลยืนยันตัวตนระหว่างการ handshake ของ WebSocket ผ่าน:
connect.params.auth.tokenconnect.params.auth.password- ส่วนหัวข้อมูลประจำตัวของ Tailscale Serve เมื่อ
gateway.auth.allowTailscale: true - ส่วนหัวข้อมูลประจำตัวของ trusted-proxy เมื่อ
gateway.auth.mode: "trusted-proxy"
gateway.auth.mode เป็น "password"
การจับคู่อุปกรณ์ (การเชื่อมต่อครั้งแรก)
เมื่อคุณเชื่อมต่อกับ Control UI จากเบราว์เซอร์หรืออุปกรณ์ใหม่ Gateway มักจะต้องมี การอนุมัติการจับคู่แบบครั้งเดียว นี่เป็นมาตรการรักษาความปลอดภัยเพื่อป้องกันการเข้าถึงโดยไม่ได้รับอนุญาต สิ่งที่คุณจะเห็น: “disconnected (1008): pairing required” หากเบราว์เซอร์ลองจับคู่อีกครั้งพร้อมรายละเอียดการยืนยันตัวตนที่เปลี่ยนไป (role/scopes/public key) คำขอที่รอดำเนินการก่อนหน้าจะถูกแทนที่ และจะสร้างrequestId ใหม่ ให้รัน openclaw devices list อีกครั้งก่อนอนุมัติ
หากเบราว์เซอร์ถูกจับคู่อยู่แล้ว และคุณเปลี่ยนจากสิทธิ์อ่านเป็นสิทธิ์เขียน/admin ระบบจะถือว่านี่เป็นการอัปเกรดการอนุมัติ ไม่ใช่การเชื่อมต่อใหม่แบบเงียบ OpenClaw จะคงการอนุมัติเก่าไว้ บล็อกการเชื่อมต่อใหม่ที่มีสิทธิ์กว้างขึ้น และขอให้คุณอนุมัติชุด scope ใหม่อย่างชัดเจน
เมื่ออนุมัติแล้ว ระบบจะจดจำอุปกรณ์นั้น และจะไม่ต้องอนุมัติซ้ำ เว้นแต่คุณจะเพิกถอนด้วย openclaw devices revoke --device <id> --role <role> ดู Devices CLI สำหรับการหมุนเวียนและการเพิกถอนโทเค็น
- การเชื่อมต่อเบราว์เซอร์ผ่าน local loopback โดยตรง (
127.0.0.1/localhost) จะได้รับการอนุมัติอัตโนมัติ - Tailscale Serve สามารถข้ามรอบการจับคู่สำหรับเซสชันผู้ปฏิบัติงาน Control UI ได้เมื่อ
gateway.auth.allowTailscale: true, ยืนยันตัวตน Tailscale สำเร็จ และเบราว์เซอร์แสดงข้อมูลประจำตัวอุปกรณ์ของตน - การ bind กับ Tailnet โดยตรง, การเชื่อมต่อเบราว์เซอร์ผ่าน LAN และโปรไฟล์เบราว์เซอร์ที่ไม่มีข้อมูลประจำตัวอุปกรณ์ ยังต้องได้รับการอนุมัติอย่างชัดเจน
- แต่ละโปรไฟล์เบราว์เซอร์จะสร้าง ID อุปกรณ์ที่ไม่ซ้ำกัน ดังนั้นการสลับเบราว์เซอร์หรือล้างข้อมูลเบราว์เซอร์จะต้องจับคู่ใหม่
ข้อมูลประจำตัวส่วนบุคคล (เฉพาะเบราว์เซอร์)
Control UI รองรับข้อมูลประจำตัวส่วนบุคคลต่อเบราว์เซอร์ (ชื่อที่แสดงและอวตาร) ซึ่งแนบกับข้อความขาออกเพื่อระบุที่มาในเซสชันที่แชร์ ข้อมูลนี้อยู่ในพื้นที่จัดเก็บของเบราว์เซอร์ ถูกจำกัดขอบเขตไว้ที่โปรไฟล์เบราว์เซอร์ปัจจุบัน และจะไม่ซิงก์ไปยังอุปกรณ์อื่นหรือเก็บถาวรฝั่งเซิร์ฟเวอร์ นอกเหนือจาก metadata ผู้เขียนตามปกติใน transcript ของข้อความที่คุณส่งจริง การล้างข้อมูลไซต์หรือสลับเบราว์เซอร์จะรีเซ็ตค่าให้ว่าง รูปแบบเฉพาะเบราว์เซอร์เดียวกันนี้ใช้กับการแทนที่อวตารของผู้ช่วยด้วย อวตารผู้ช่วยที่อัปโหลดจะซ้อนทับข้อมูลประจำตัวที่ Gateway resolve แล้วบนเบราว์เซอร์ภายในเครื่องเท่านั้น และจะไม่ส่งวนกลับผ่านconfig.patch ฟิลด์ config ที่แชร์ชื่อ ui.assistant.avatar ยังพร้อมใช้งานสำหรับไคลเอนต์ที่ไม่ใช่ UI ซึ่งเขียนฟิลด์นี้โดยตรง (เช่น Gateway แบบสคริปต์หรือแดชบอร์ดแบบกำหนดเอง)
endpoint การตั้งค่ารันไทม์
Control UI ดึงการตั้งค่ารันไทม์จาก/__openclaw/control-ui-config.json endpoint นี้ถูกควบคุมด้วยการยืนยันตัวตน Gateway แบบเดียวกับพื้นผิว HTTP ส่วนที่เหลือ: เบราว์เซอร์ที่ไม่ได้ยืนยันตัวตนจะดึงข้อมูลไม่ได้ และการดึงข้อมูลสำเร็จต้องมีโทเค็น/รหัสผ่าน Gateway ที่ถูกต้องอยู่แล้ว, ข้อมูลประจำตัว Tailscale Serve หรือข้อมูลประจำตัว trusted-proxy
การรองรับภาษา
Control UI สามารถแปลตัวเองตาม locale ของเบราว์เซอร์ในการโหลดครั้งแรก หากต้องการเปลี่ยนในภายหลัง ให้เปิด Overview -> Gateway Access -> Language ตัวเลือก locale อยู่ในการ์ด Gateway Access ไม่ได้อยู่ใต้ Appearance- locale ที่รองรับ:
en,zh-CN,zh-TW,pt-BR,de,es,ja-JP,ko,fr,ar,it,tr,uk,id,pl,th,vi,nl,fa - คำแปลที่ไม่ใช่ภาษาอังกฤษจะถูกโหลดแบบ lazy-load ในเบราว์เซอร์
- locale ที่เลือกจะถูกบันทึกในพื้นที่จัดเก็บของเบราว์เซอร์และนำมาใช้ซ้ำในการเข้าชมครั้งถัดไป
- คีย์คำแปลที่ขาดหายจะย้อนกลับไปใช้ภาษาอังกฤษ
th) และเปอร์เซีย (fa) ยังคงถูกสร้างใน repo สำหรับเผยแพร่ แต่อาจยังไม่ปรากฏในตัวเลือกนั้นจนกว่า Mintlify จะรองรับรหัสเหล่านั้น
ธีม Appearance
แผง Appearance จะคงธีมในตัว Claw, Knot และ Dash รวมถึงช่องนำเข้า tweakcn เฉพาะเบราว์เซอร์หนึ่งช่อง หากต้องการนำเข้าธีม ให้เปิด tweakcn editor, เลือกหรือสร้างธีม, คลิก Share แล้ววางลิงก์ธีมที่คัดลอกไว้ใน Appearance ตัวนำเข้ายังรองรับ URL registry แบบhttps://tweakcn.com/r/themes/<id>, URL editor เช่น https://tweakcn.com/editor/theme?theme=amethyst-haze, พาธสัมพัทธ์ /themes/<id>, ID ธีมดิบ และชื่อธีมเริ่มต้น เช่น amethyst-haze
ธีมที่นำเข้าจะถูกเก็บไว้เฉพาะในโปรไฟล์เบราว์เซอร์ปัจจุบันเท่านั้น ธีมจะไม่ถูกเขียนลง config ของ Gateway และไม่ซิงก์ข้ามอุปกรณ์ การแทนที่ธีมที่นำเข้าจะอัปเดตช่องภายในเครื่องหนึ่งช่อง การล้างธีมจะสลับธีมที่ใช้งานกลับไปเป็น Claw หากธีมที่นำเข้าเคยถูกเลือกอยู่
สิ่งที่ทำได้ (วันนี้)
แชทและพูดคุย
แชทและพูดคุย
- แชทกับโมเดลผ่าน Gateway WS (
chat.history,chat.send,chat.abort,chat.inject) - การรีเฟรชประวัติแชทจะขอหน้าต่างล่าสุดที่จำกัดขอบเขต พร้อมเพดานข้อความต่อข้อความ เพื่อให้เซสชันขนาดใหญ่ไม่บังคับให้เบราว์เซอร์เรนเดอร์ payload transcript เต็มก่อนที่แชทจะพร้อมใช้งาน
- พูดคุยผ่านเซสชันแบบเรียลไทม์ของเบราว์เซอร์ OpenAI ใช้ WebRTC โดยตรง, Google Live ใช้โทเค็นเบราว์เซอร์แบบใช้ครั้งเดียวที่ถูกจำกัดผ่าน WebSocket และ Plugin เสียงเรียลไทม์แบบ backend-only ใช้ transport relay ของ Gateway เซสชัน provider ที่ไคลเอนต์เป็นเจ้าของเริ่มด้วย
talk.client.create; เซสชัน Gateway relay เริ่มด้วยtalk.session.createrelay จะเก็บข้อมูลรับรอง provider ไว้บน Gateway ขณะที่เบราว์เซอร์สตรีมไมโครโฟน PCM ผ่านtalk.session.appendAudioและส่งต่อการเรียก tool ของ provideropenclaw_agent_consultผ่านtalk.client.toolCallเพื่อใช้นโยบาย Gateway และโมเดล OpenClaw ที่กำหนดค่าไว้ซึ่งใหญ่กว่า - สตรีมการเรียก tool + การ์ดผลลัพธ์ tool แบบสดใน Chat (เหตุการณ์ agent)
ช่องทาง, instances, sessions, dreams
ช่องทาง, instances, sessions, dreams
- ช่องทาง: สถานะช่องทางในตัวและช่องทางจาก Plugin ที่ bundled/ภายนอก, การเข้าสู่ระบบด้วย QR และ config ต่อช่องทาง (
channels.status,web.login.*,config.patch) - การรีเฟรช probe ของช่องทางจะคง snapshot ก่อนหน้าให้มองเห็นอยู่ขณะที่การตรวจสอบ provider ที่ช้ากำลังเสร็จสิ้น และ snapshot บางส่วนจะถูกติดป้ายเมื่อ probe หรือ audit เกินงบเวลา UI
- Instances: รายการ presence + รีเฟรช (
system-presence) - Sessions: แสดงรายการเซสชัน configured-agent ตามค่าเริ่มต้น, fallback จากคีย์เซสชัน agent ที่ไม่ได้กำหนดค่าและค้างอยู่ และใช้การ override model/thinking/fast/verbose/trace/reasoning ต่อเซสชัน (
sessions.list,sessions.patch) - Dreams: สถานะ dreaming, สวิตช์ enable/disable และตัวอ่าน Dream Diary (
doctor.memory.status,doctor.memory.dreamDiary,config.patch)
Cron, skills, nodes, การอนุมัติ exec
Cron, skills, nodes, การอนุมัติ exec
- งาน Cron: list/add/edit/run/enable/disable + ประวัติการรัน (
cron.*) - Skills: สถานะ, enable/disable, ติดตั้ง, อัปเดต API key (
skills.*) - Nodes: list + caps (
node.list) - การอนุมัติ exec: แก้ไข allowlist ของ gateway หรือ node + นโยบาย ask สำหรับ
exec host=gateway/node(exec.approvals.*)
Config
Config
- ดู/แก้ไข
~/.openclaw/openclaw.json(config.get,config.set) - Apply + restart พร้อม validation (
config.apply) และปลุกเซสชันล่าสุดที่ใช้งานอยู่ - การเขียนมี guard แบบ base-hash เพื่อป้องกันการเขียนทับการแก้ไขที่เกิดขึ้นพร้อมกัน
- การเขียน (
config.set/config.apply/config.patch) จะ preflight การ resolve SecretRef ที่ active สำหรับ refs ใน payload config ที่ส่งมา; refs ที่ส่งมาและ active แต่ resolve ไม่ได้จะถูกปฏิเสธก่อนเขียน - Schema + การเรนเดอร์ฟอร์ม (
config.schema/config.schema.lookup, รวมถึงฟิลด์title/description, UI hints ที่ match, สรุป child โดยตรง, metadata เอกสารบนโหนด object/wildcard/array/composition แบบซ้อน รวมถึง schema ของ Plugin + ช่องทางเมื่อมี); Raw JSON editor พร้อมใช้งานเฉพาะเมื่อ snapshot มี raw round-trip ที่ปลอดภัย - หาก snapshot ไม่สามารถ round-trip ข้อความดิบได้อย่างปลอดภัย Control UI จะบังคับโหมด Form และปิดใช้โหมด Raw สำหรับ snapshot นั้น
- Raw JSON editor “Reset to saved” จะรักษารูปทรงที่เขียนแบบ raw ไว้ (การจัดรูปแบบ, ความคิดเห็น, layout ของ
$include) แทนการเรนเดอร์ snapshot ที่ flatten ใหม่ เพื่อให้การแก้ไขภายนอกยังอยู่รอดหลัง reset เมื่อ snapshot สามารถ round-trip ได้อย่างปลอดภัย - ค่า object แบบ Structured SecretRef จะแสดงเป็นแบบอ่านอย่างเดียวใน input ข้อความของฟอร์ม เพื่อป้องกันความเสียหายจากการแปลง object เป็น string โดยไม่ตั้งใจ
Debug, logs, update
Debug, logs, update
- Debug: snapshot ของ status/health/models + event log + การเรียก RPC แบบ manual (
status,health,models.list) - event log มีเวลาของการรีเฟรช/RPC ใน Control UI, เวลาการเรนเดอร์แชท/config ที่ช้า และรายการความตอบสนองของเบราว์เซอร์สำหรับ animation frame ที่ยาวหรืองานที่ยาว เมื่อเบราว์เซอร์เปิดเผยชนิดรายการ PerformanceObserver เหล่านั้น
- Logs: tail สดของไฟล์ log ของ gateway พร้อม filter/export (
logs.tail) - Update: รันการอัปเดต package/git + restart (
update.run) พร้อมรายงานการ restart จากนั้น pollupdate.statusหลังเชื่อมต่อใหม่เพื่อตรวจสอบเวอร์ชัน gateway ที่กำลังรันอยู่
หมายเหตุแผงงาน Cron
หมายเหตุแผงงาน Cron
- สำหรับงานแบบ isolated ค่า delivery เริ่มต้นคือประกาศสรุป คุณสามารถสลับเป็น none ได้หากต้องการรันภายในเท่านั้น
- ฟิลด์ช่องทาง/target จะปรากฏเมื่อเลือก announce
- โหมด Webhook ใช้
delivery.mode = "webhook"โดยตั้งค่าdelivery.toเป็น URL webhook HTTP(S) ที่ถูกต้อง - สำหรับงาน main-session มีโหมด delivery แบบ webhook และ none ให้ใช้
- ตัวควบคุมแก้ไขขั้นสูงประกอบด้วย delete-after-run, clear agent override, ตัวเลือก cron exact/stagger, การ override agent model/thinking และสวิตช์ best-effort delivery
- การตรวจสอบความถูกต้องของฟอร์มเป็นแบบ inline พร้อมข้อผิดพลาดระดับฟิลด์; ค่าที่ไม่ถูกต้องจะปิดใช้ปุ่มบันทึกจนกว่าจะแก้ไข
- ตั้งค่า
cron.webhookTokenเพื่อส่ง bearer token เฉพาะ หากละไว้ webhook จะถูกส่งโดยไม่มีส่วนหัว auth - fallback ที่เลิกใช้แล้ว: งาน legacy ที่จัดเก็บไว้พร้อม
notify: trueยังสามารถใช้cron.webhookได้จนกว่าจะ migrate
พฤติกรรมของ Chat
Send and history semantics
Send and history semantics
chat.sendเป็นแบบ ไม่บล็อกการทำงาน: ยืนยันรับทันทีด้วย{ runId, status: "started" }และคำตอบจะสตรีมผ่านเหตุการณ์chat- การอัปโหลดแชตรองรับรูปภาพและไฟล์ที่ไม่ใช่วิดีโอ รูปภาพจะคงเส้นทางรูปภาพดั้งเดิมไว้ ส่วนไฟล์อื่นจะถูกจัดเก็บเป็นสื่อที่จัดการแล้วและแสดงในประวัติเป็นลิงก์ไฟล์แนบ
- การส่งซ้ำด้วย
idempotencyKeyเดิมจะส่งคืน{ status: "in_flight" }ขณะกำลังทำงาน และ{ status: "ok" }หลังเสร็จสิ้น - คำตอบของ
chat.historyถูกจำกัดขนาดเพื่อความปลอดภัยของ UI เมื่อรายการถอดความมีขนาดใหญ่เกินไป Gateway อาจตัดทอนฟิลด์ข้อความยาว ๆ ละเว้นบล็อกข้อมูลเมตาขนาดใหญ่ และแทนที่ข้อความที่ใหญ่เกินด้วยตัวแทน ([chat.history omitted: message too large]) - รูปภาพจากผู้ช่วย/ที่สร้างขึ้นจะถูกเก็บถาวรเป็นการอ้างอิงสื่อที่จัดการแล้ว และส่งกลับผ่าน URL สื่อของ Gateway ที่ผ่านการยืนยันตัวตนแล้ว ดังนั้นการโหลดซ้ำจึงไม่ต้องพึ่งพาเพย์โหลดรูปภาพ base64 ดิบที่ยังคงอยู่ในคำตอบประวัติแชต
- เมื่อเรนเดอร์
chat.historyControl UI จะลบแท็กคำสั่งแบบอินไลน์ที่มีไว้เพื่อการแสดงผลเท่านั้นออกจากข้อความผู้ช่วยที่มองเห็นได้ (เช่น[[reply_to_*]]และ[[audio_as_voice]]), เพย์โหลด XML ของการเรียกเครื่องมือแบบข้อความล้วน (รวมถึง<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>และบล็อกการเรียกเครื่องมือที่ถูกตัดทอน), และโทเค็นควบคุมโมเดล ASCII/เต็มความกว้างที่รั่วไหลมา และละเว้นรายการของผู้ช่วยที่ข้อความที่มองเห็นได้ทั้งหมดเป็นเพียงโทเค็นเงียบที่ตรงกันทุกตัวอักษรNO_REPLY/no_replyหรือโทเค็นยืนยัน HeartbeatHEARTBEAT_OK - ระหว่างการส่งที่กำลังทำงานและการรีเฟรชประวัติครั้งสุดท้าย มุมมองแชตจะยังคงแสดงข้อความผู้ใช้/ผู้ช่วยแบบมองโลกในแง่ดีในเครื่องไว้ หาก
chat.historyส่งคืนสแนปช็อตที่เก่ากว่าชั่วครู่; บันทึกถอดความแบบบัญญัติจะมาแทนที่ข้อความในเครื่องเหล่านั้นเมื่อประวัติ Gateway ตามทัน - เหตุการณ์
chatสดคือสถานะการส่งมอบ ส่วนchat.historyถูกสร้างใหม่จากบันทึกถอดความเซสชันที่คงทน หลังเหตุการณ์เครื่องมือขั้นสุดท้าย Control UI จะโหลดประวัติใหม่และผสานเฉพาะส่วนท้ายแบบมองโลกในแง่ดีขนาดเล็กเท่านั้น; ขอบเขตบันทึกถอดความมีเอกสารไว้ใน WebChat chat.injectเพิ่มบันทึกของผู้ช่วยต่อท้ายบันทึกถอดความเซสชันและบรอดแคสต์เหตุการณ์chatสำหรับการอัปเดตเฉพาะ UI (ไม่มีการรันเอเจนต์ ไม่มีการส่งมอบช่องทาง)- ส่วนหัวแชตแสดงตัวกรองเอเจนต์ก่อนตัวเลือกเซสชัน และตัวเลือกเซสชันจะถูกจำกัดขอบเขตตามเอเจนต์ที่เลือก การสลับเอเจนต์จะแสดงเฉพาะเซสชันที่ผูกกับเอเจนต์นั้น และย้อนกลับไปใช้เซสชันหลักของเอเจนต์นั้นเมื่อยังไม่มีเซสชันแดชบอร์ดที่บันทึกไว้
- บนความกว้างเดสก์ท็อป ตัวควบคุมแชตจะอยู่ในแถวเดียวแบบกะทัดรัดและยุบลงขณะเลื่อนลงในบันทึกถอดความ; การเลื่อนขึ้น กลับไปด้านบน หรือไปถึงด้านล่างจะคืนค่าตัวควบคุม
- ข้อความซ้ำที่อยู่ติดกันและมีเฉพาะข้อความจะแสดงเป็นบับเบิลเดียวพร้อมป้ายจำนวน ข้อความที่มีรูปภาพ ไฟล์แนบ เอาต์พุตเครื่องมือ หรือพรีวิวแคนวาสจะไม่ถูกยุบ
- ตัวเลือกโมเดลและการคิดในส่วนหัวแชตจะแพตช์เซสชันที่ใช้งานอยู่ทันทีผ่าน
sessions.patch; สิ่งเหล่านี้เป็นการแทนที่เซสชันแบบคงอยู่ ไม่ใช่ตัวเลือกการส่งเฉพาะเทิร์นเดียว - หากคุณส่งข้อความขณะที่การเปลี่ยนตัวเลือกโมเดลสำหรับเซสชันเดียวกันยังบันทึกอยู่ ตัวเขียนข้อความจะรอให้แพตช์เซสชันนั้นเสร็จก่อนเรียก
chat.sendเพื่อให้การส่งใช้โมเดลที่เลือก - การพิมพ์
/newใน Control UI จะสร้างและสลับไปยังเซสชันแดชบอร์ดใหม่แบบเดียวกับ New Chat ยกเว้นเมื่อมีการกำหนดค่าsession.dmScope: "main"และพาเรนต์ปัจจุบันเป็นเซสชันหลักของเอเจนต์; ในกรณีนั้นจะรีเซ็ตเซสชันหลักในตำแหน่งเดิม การพิมพ์/resetจะคงการรีเซ็ตในตำแหน่งเดิมแบบชัดเจนของ Gateway สำหรับเซสชันปัจจุบัน - ตัวเลือกโมเดลแชตขอมุมมองโมเดลที่กำหนดค่าไว้ของ Gateway หากมี
agents.defaults.modelsรายการอนุญาตนั้นจะขับเคลื่อนตัวเลือก รวมถึงรายการprovider/*ที่ทำให้แคตตาล็อกที่จำกัดตามผู้ให้บริการยังคงเป็นแบบไดนามิก มิฉะนั้น ตัวเลือกจะแสดงรายการmodels.providers.*.modelsแบบชัดเจน พร้อมผู้ให้บริการที่มีการยืนยันตัวตนที่ใช้งานได้ แคตตาล็อกแบบเต็มยังคงพร้อมใช้งานผ่าน RPC ดีบักmodels.listพร้อมview: "all" - เมื่อรายงานการใช้งานเซสชัน Gateway ใหม่มีโทเค็นบริบทปัจจุบัน พื้นที่ตัวเขียนข้อความแชตจะแสดงตัวบ่งชี้การใช้งานบริบทแบบกะทัดรัด โดยจะเปลี่ยนเป็นสไตล์คำเตือนเมื่อมีแรงกดดันต่อบริบทสูง และในระดับ Compaction ที่แนะนำ จะแสดงปุ่มแบบกะทัดรัดที่รันเส้นทาง Compaction เซสชันตามปกติ สแนปช็อตโทเค็นที่ล้าสมัยจะถูกซ่อนไว้จนกว่า Gateway จะรายงานการใช้งานใหม่อีกครั้ง
Talk mode (browser realtime)
Talk mode (browser realtime)
โหมดพูดคุยใช้ผู้ให้บริการเสียงเรียลไทม์ที่ลงทะเบียนไว้ กำหนดค่า OpenAI ด้วย
talk.realtime.provider: "openai" พร้อม talk.realtime.providers.openai.apiKey, OPENAI_API_KEY หรือโปรไฟล์ OAuth openai-codex; กำหนดค่า Google ด้วย talk.realtime.provider: "google" พร้อม talk.realtime.providers.google.apiKey เบราว์เซอร์จะไม่ได้รับคีย์ API ผู้ให้บริการมาตรฐาน OpenAI ได้รับความลับไคลเอนต์ Realtime ชั่วคราวสำหรับ WebRTC Google Live ได้รับโทเค็นการยืนยันตัวตน Live API แบบจำกัดและใช้ครั้งเดียวสำหรับเซสชัน WebSocket ของเบราว์เซอร์ โดยมีคำสั่งและประกาศเครื่องมือที่ถูกล็อกไว้ในโทเค็นโดย Gateway ผู้ให้บริการที่เปิดเผยเฉพาะสะพานเรียลไทม์ฝั่งแบ็กเอนด์จะทำงานผ่านทรานสปอร์ตรีเลย์ของ Gateway ดังนั้นข้อมูลประจำตัวและซ็อกเก็ตผู้ขายจะอยู่ฝั่งเซิร์ฟเวอร์ ขณะที่เสียงจากเบราว์เซอร์เคลื่อนผ่าน RPC ของ Gateway ที่ผ่านการยืนยันตัวตน พรอมป์เซสชัน Realtime ถูกประกอบโดย Gateway; talk.client.create ไม่ยอมรับการแทนที่คำสั่งจากผู้เรียกตัวเขียนข้อความแชตมีปุ่มตัวเลือกพูดคุยถัดจากปุ่มเริ่ม/หยุดพูดคุย ตัวเลือกจะมีผลกับเซสชันพูดคุยถัดไป และสามารถแทนที่ผู้ให้บริการ ทรานสปอร์ต โมเดล เสียง ความพยายามในการให้เหตุผล เกณฑ์ VAD ระยะเวลาเงียบ และการเติมนำหน้าได้ เมื่อตัวเลือกว่าง Gateway จะใช้ค่าเริ่มต้นที่กำหนดค่าไว้เมื่อมี หรือค่าเริ่มต้นของผู้ให้บริการ การเลือกรีเลย์ Gateway จะบังคับใช้เส้นทางรีเลย์แบ็กเอนด์; การเลือก WebRTC จะคงให้เซสชันเป็นของไคลเอนต์ และล้มเหลวแทนที่จะย้อนกลับไปใช้รีเลย์อย่างเงียบ ๆ หากผู้ให้บริการไม่สามารถสร้างเซสชันเบราว์เซอร์ได้ในตัวเขียนข้อความแชต ตัวควบคุมพูดคุยคือปุ่มรูปคลื่นถัดจากปุ่มถอดคำพูดจากไมโครโฟน เมื่อการพูดคุยเริ่มต้น แถวสถานะของตัวเขียนข้อความจะแสดง Connecting Talk... จากนั้นแสดง Talk live ขณะที่เสียงเชื่อมต่ออยู่ หรือ Asking OpenClaw... ขณะการเรียกเครื่องมือเรียลไทม์กำลังปรึกษาโมเดลขนาดใหญ่กว่าที่กำหนดค่าไว้ผ่าน talk.client.toolCallการทดสอบควันแบบสดสำหรับผู้ดูแล: OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts ตรวจสอบสะพาน WebSocket แบ็กเอนด์ของ OpenAI, การแลกเปลี่ยน SDP ของ WebRTC เบราว์เซอร์ OpenAI, การตั้งค่า WebSocket เบราว์เซอร์ด้วยโทเค็นจำกัดของ Google Live และอะแดปเตอร์เบราว์เซอร์รีเลย์ Gateway พร้อมสื่อไมโครโฟนจำลอง คำสั่งจะแสดงเฉพาะสถานะผู้ให้บริการและไม่บันทึกความลับStop and abort
Stop and abort
- คลิก หยุด (เรียก
chat.abort) - ขณะที่การรันกำลังทำงาน การติดตามผลตามปกติจะเข้าคิว คลิก นำทาง บนข้อความที่เข้าคิวเพื่อฉีดการติดตามผลนั้นเข้าสู่เทิร์นที่กำลังรัน
- พิมพ์
/stop(หรือวลีหยุดแบบเดี่ยว เช่นstop,stop action,stop run,stop openclaw,please stop) เพื่อยกเลิกนอกแบนด์ chat.abortรองรับ{ sessionKey }(ไม่มีrunId) เพื่อยกเลิกการรันที่ทำงานอยู่ทั้งหมดสำหรับเซสชันนั้น
Abort partial retention
Abort partial retention
- เมื่อการรันถูกยกเลิก ข้อความผู้ช่วยบางส่วนยังสามารถแสดงใน UI ได้
- Gateway จะคงข้อความผู้ช่วยบางส่วนที่ถูกยกเลิกไว้ในประวัติบันทึกถอดความเมื่อมีเอาต์พุตที่บัฟเฟอร์ไว้
- รายการที่คงไว้มีข้อมูลเมตาการยกเลิก เพื่อให้ผู้ใช้บันทึกถอดความแยกข้อความบางส่วนจากการยกเลิกออกจากเอาต์พุตการเสร็จสมบูรณ์ตามปกติได้
การติดตั้ง PWA และ Web Push
Control UI มาพร้อมmanifest.webmanifest และ service worker ดังนั้นเบราว์เซอร์สมัยใหม่จึงติดตั้งเป็น PWA แบบสแตนด์อโลนได้ Web Push ช่วยให้ Gateway ปลุก PWA ที่ติดตั้งแล้วด้วยการแจ้งเตือนได้ แม้แท็บหรือหน้าต่างเบราว์เซอร์ไม่ได้เปิดอยู่
| พื้นผิว | สิ่งที่ทำ |
|---|---|
ui/public/manifest.webmanifest | แมนิเฟสต์ PWA เบราว์เซอร์จะเสนอ “ติดตั้งแอป” เมื่อเข้าถึงได้ |
ui/public/sw.js | service worker ที่จัดการเหตุการณ์ push และการคลิกการแจ้งเตือน |
push/vapid-keys.json (ใต้ไดเรกทอรีสถานะ OpenClaw) | คู่คีย์ VAPID ที่สร้างอัตโนมัติ ใช้ลงนามเพย์โหลด Web Push |
push/web-push-subscriptions.json | endpoint การสมัครรับข้อมูลของเบราว์เซอร์ที่คงไว้ |
OPENCLAW_VAPID_PUBLIC_KEYOPENCLAW_VAPID_PRIVATE_KEYOPENCLAW_VAPID_SUBJECT(ค่าเริ่มต้นคือmailto:openclaw@localhost)
push.web.vapidPublicKey— ดึงคีย์สาธารณะ VAPID ที่ใช้งานอยู่push.web.subscribe— ลงทะเบียนendpointพร้อมkeys.p256dh/keys.authpush.web.unsubscribe— ลบ endpoint ที่ลงทะเบียนไว้push.web.test— ส่งการแจ้งเตือนทดสอบไปยังการสมัครรับข้อมูลของผู้เรียก
Web Push เป็นอิสระจากเส้นทางรีเลย์ APNS ของ iOS (ดู การกำหนดค่า สำหรับการพุชที่มีรีเลย์รองรับ) และเมธอด
push.test ที่มีอยู่ ซึ่งมุ่งเป้าไปที่การจับคู่มือถือแบบเนทีฟเอ็มเบดที่โฮสต์
ข้อความผู้ช่วยสามารถเรนเดอร์เนื้อหาเว็บที่โฮสต์แบบอินไลน์ด้วยชอร์ตโค้ด[embed ...] นโยบาย sandbox ของ iframe ถูกควบคุมโดย gateway.controlUi.embedSandbox:
- strict
- scripts (default)
- trusted
ปิดใช้งานการเรียกใช้สคริปต์ภายในเอ็มเบดที่โฮสต์
http(s) ภายนอกแบบสมบูรณ์ยังคงถูกบล็อกโดยค่าเริ่มต้น หากคุณตั้งใจต้องการให้ [embed url="https://..."] โหลดหน้าจากบุคคลที่สาม ให้ตั้งค่า gateway.controlUi.allowExternalEmbedUrls: true
ความกว้างข้อความแชต
ข้อความแชตที่จัดกลุ่มใช้ความกว้างสูงสุดค่าเริ่มต้นที่อ่านง่าย การปรับใช้บนจอกว้างสามารถแทนที่ได้โดยไม่ต้องแพตช์ CSS ที่บันเดิลมา ด้วยการตั้งค่าgateway.controlUi.chatMessageMaxWidth:
960px หรือ 82% พร้อมนิพจน์ความกว้างที่จำกัดอย่าง min(...), max(...), clamp(...), calc(...) และ fit-content(...)
การเข้าถึง Tailnet (แนะนำ)
- Integrated Tailscale Serve (preferred)
- Bind to tailnet + token
คง Gateway ไว้บน loopback และให้ Tailscale Serve พร็อกซีด้วย HTTPS:เปิด:
https://<magicdns>/(หรือgateway.controlUi.basePathที่คุณกำหนดค่าไว้)
tailscale-user-login) ได้เมื่อ gateway.auth.allowTailscale เป็น true OpenClaw ตรวจสอบข้อมูลประจำตัวโดยแปลงที่อยู่ x-forwarded-for ด้วย tailscale whois และจับคู่กับส่วนหัว และจะยอมรับเฉพาะเมื่อคำขอเข้ามาที่ loopback พร้อมส่วนหัว x-forwarded-* ของ Tailscale เท่านั้น สำหรับเซสชันผู้ปฏิบัติงาน Control UI ที่มีข้อมูลประจำตัวอุปกรณ์ของเบราว์เซอร์ เส้นทาง Serve ที่ตรวจสอบแล้วนี้จะข้ามรอบการจับคู่อุปกรณ์ด้วยเช่นกัน ส่วนเบราว์เซอร์ที่ไม่มีอุปกรณ์และการเชื่อมต่อบทบาทโหนดยังคงทำตามการตรวจสอบอุปกรณ์ตามปกติ ตั้งค่า gateway.auth.allowTailscale: false หากคุณต้องการบังคับใช้ข้อมูลรับรอง shared-secret อย่างชัดเจนแม้กับทราฟฟิก Serve จากนั้นใช้ gateway.auth.mode: "token" หรือ "password"สำหรับเส้นทางข้อมูลประจำตัว Serve แบบ async นี้ ความพยายามยืนยันตัวตนที่ล้มเหลวสำหรับ IP ไคลเอนต์และขอบเขตการยืนยันตัวตนเดียวกันจะถูกจัดลำดับก่อนการเขียน rate-limit ดังนั้นการลองซ้ำที่ผิดพลาดพร้อมกันจากเบราว์เซอร์เดียวกันอาจแสดง retry later ในคำขอที่สอง แทนที่จะเกิด mismatch ธรรมดาสองรายการที่แข่งกันแบบขนานHTTP ที่ไม่ปลอดภัย
หากคุณเปิดแดชบอร์ดผ่าน HTTP ธรรมดา (http://<lan-ip> หรือ http://<tailscale-ip>) เบราว์เซอร์จะทำงานใน บริบทที่ไม่ปลอดภัย และบล็อก WebCrypto โดยค่าเริ่มต้น OpenClaw จะ บล็อก การเชื่อมต่อ Control UI ที่ไม่มีข้อมูลประจำตัวอุปกรณ์
ข้อยกเว้นที่บันทึกไว้:
- ความเข้ากันได้กับ HTTP ที่ไม่ปลอดภัยเฉพาะ localhost ด้วย
gateway.controlUi.allowInsecureAuth=true - การยืนยันตัวตน Control UI ของผู้ปฏิบัติงานสำเร็จผ่าน
gateway.auth.mode: "trusted-proxy" - กลไกฉุกเฉิน
gateway.controlUi.dangerouslyDisableDeviceAuth=true
https://<magicdns>/(Serve)http://127.0.0.1:18789/(บนโฮสต์ gateway)
Insecure-auth toggle behavior
Insecure-auth toggle behavior
allowInsecureAuth เป็นสวิตช์ความเข้ากันได้ในเครื่องเท่านั้น:- อนุญาตให้เซสชัน Control UI บน localhost ดำเนินต่อได้โดยไม่มีข้อมูลประจำตัวอุปกรณ์ในบริบท HTTP ที่ไม่ปลอดภัย
- ไม่ข้ามการตรวจสอบการจับคู่
- ไม่ผ่อนคลายข้อกำหนดข้อมูลประจำตัวอุปกรณ์ระยะไกล (ที่ไม่ใช่ localhost)
Break-glass only
Break-glass only
Trusted-proxy note
Trusted-proxy note
- การยืนยันตัวตน trusted-proxy ที่สำเร็จสามารถอนุญาตเซสชัน Control UI ของ ผู้ปฏิบัติงาน โดยไม่มีข้อมูลประจำตัวอุปกรณ์ได้
- สิ่งนี้ ไม่ ขยายไปถึงเซสชัน Control UI บทบาทโหนด
- reverse proxy แบบ loopback บนโฮสต์เดียวกันยังคงไม่ผ่านการยืนยันตัวตน trusted-proxy; ดู การยืนยันตัวตน trusted proxy
นโยบายความปลอดภัยของเนื้อหา
Control UI มาพร้อมนโยบายimg-src ที่เข้มงวด: อนุญาตเฉพาะแอสเซ็ต same-origin, URL data: และ URL blob: ที่สร้างในเครื่องเท่านั้น URL รูปภาพระยะไกลแบบ http(s) และแบบสัมพันธ์กับโปรโตคอลจะถูกเบราว์เซอร์ปฏิเสธและจะไม่เกิดการดึงข้อมูลผ่านเครือข่าย
ในทางปฏิบัติ หมายความว่า:
- อวาตาร์และรูปภาพที่ให้บริการใต้พาธสัมพันธ์ (เช่น
/avatars/<id>) ยังแสดงผลได้ รวมถึงเส้นทางอวาตาร์ที่ผ่านการยืนยันตัวตนซึ่ง UI ดึงมาและแปลงเป็น URLblob:ในเครื่อง - URL แบบ inline
data:image/...ยังแสดงผลได้ (มีประโยชน์สำหรับ payload ในโปรโตคอล) - URL
blob:ในเครื่องที่สร้างโดย Control UI ยังแสดงผลได้ - URL อวาตาร์ระยะไกลที่ปล่อยออกมาจาก metadata ของช่องทางจะถูกตัดออกที่ตัวช่วยอวาตาร์ของ Control UI และแทนที่ด้วยโลโก้/แบดจ์ในตัว ดังนั้นช่องทางที่ถูกเจาะหรือประสงค์ร้ายจึงไม่สามารถบังคับให้เบราว์เซอร์ของผู้ปฏิบัติงานดึงรูปภาพระยะไกลตามอำเภอใจได้
การยืนยันตัวตนเส้นทางอวาตาร์
เมื่อกำหนดค่าการยืนยันตัวตน gateway แล้ว endpoint อวาตาร์ของ Control UI ต้องใช้โทเคน gateway เดียวกับ API ส่วนอื่น:GET /avatar/<agentId>ส่งคืนรูปภาพอวาตาร์เฉพาะให้ผู้เรียกที่ผ่านการยืนยันตัวตนเท่านั้นGET /avatar/<agentId>?meta=1ส่งคืน metadata ของอวาตาร์ภายใต้กฎเดียวกัน- คำขอที่ไม่ผ่านการยืนยันตัวตนไปยังเส้นทางใดเส้นทางหนึ่งจะถูกปฏิเสธ (ตรงกับเส้นทาง assistant-media ที่อยู่ระดับเดียวกัน) สิ่งนี้ป้องกันไม่ให้เส้นทางอวาตาร์รั่วไหลข้อมูลประจำตัวเอเจนต์บนโฮสต์ที่ได้รับการป้องกันด้วยวิธีอื่น
- Control UI เองส่งต่อโทเคน gateway เป็นส่วนหัว bearer เมื่อดึงอวาตาร์ และใช้ URL blob ที่ผ่านการยืนยันตัวตนเพื่อให้รูปภาพยังแสดงในแดชบอร์ดได้
การยืนยันตัวตนเส้นทางสื่อของผู้ช่วย
เมื่อกำหนดค่าการยืนยันตัวตน gateway แล้ว ตัวอย่างสื่อโลคัลของผู้ช่วยจะใช้เส้นทางสองขั้นตอน:GET /__openclaw__/assistant-media?meta=1&source=<path>ต้องใช้การยืนยันตัวตนผู้ปฏิบัติงาน Control UI ตามปกติ เบราว์เซอร์ส่งโทเคน gateway เป็นส่วนหัว bearer เมื่อตรวจสอบความพร้อมใช้งาน- การตอบกลับ metadata ที่สำเร็จจะมี
mediaTicketอายุสั้นที่ถูกจำกัดขอบเขตกับพาธต้นทางนั้นเท่านั้น - URL รูปภาพ เสียง วิดีโอ และเอกสารที่เบราว์เซอร์แสดงผลใช้
mediaTicket=<ticket>แทนโทเคนหรือรหัสผ่าน gateway ที่ใช้งานอยู่ ตั๋วจะหมดอายุอย่างรวดเร็วและไม่สามารถอนุญาตต้นทางอื่นได้
การสร้าง UI
Gateway ให้บริการไฟล์สแตติกจากdist/control-ui สร้างไฟล์เหล่านี้ด้วย:
ws://127.0.0.1:18789)
หน้า Control UI ว่างเปล่า
หากเบราว์เซอร์โหลดแดชบอร์ดว่างและ DevTools ไม่แสดงข้อผิดพลาดที่เป็นประโยชน์ ส่วนขยายหรือ content script ช่วงต้นอาจขัดขวางไม่ให้แอปโมดูล JavaScript ประเมินผล หน้า static มีแผงกู้คืน HTML ธรรมดาที่ปรากฏเมื่อ<openclaw-app> ไม่ถูกลงทะเบียนหลังเริ่มต้น
ใช้การกระทำ ลองอีกครั้ง ของแผงหลังเปลี่ยนสภาพแวดล้อมเบราว์เซอร์ หรือโหลดใหม่ด้วยตนเองหลังตรวจสอบสิ่งเหล่านี้:
- ปิดใช้งานส่วนขยายที่แทรกเข้าไปในทุกหน้า โดยเฉพาะส่วนขยายที่มี content script แบบ
<all_urls> - ลองใช้หน้าต่างส่วนตัว โปรไฟล์เบราว์เซอร์ใหม่ หรือเบราว์เซอร์อื่น
- ให้ Gateway ทำงานต่อและตรวจสอบ URL แดชบอร์ดเดียวกันหลังเปลี่ยนเบราว์เซอร์
การดีบัก/ทดสอบ: dev server + Gateway ระยะไกล
Control UI เป็นไฟล์สแตติก เป้าหมาย WebSocket สามารถกำหนดค่าได้และอาจแตกต่างจาก origin ของ HTTP วิธีนี้สะดวกเมื่อคุณต้องการ Vite dev server ในเครื่อง แต่ Gateway ทำงานอยู่ที่อื่นNotes
Notes
gatewayUrlถูกเก็บใน localStorage หลังโหลดและถูกลบออกจาก URL- หากคุณส่ง endpoint
ws://หรือwss://แบบเต็มผ่านgatewayUrlให้ URL-encode ค่าgatewayUrlเพื่อให้เบราว์เซอร์แยกวิเคราะห์ query string ได้ถูกต้อง - ควรส่ง
tokenผ่าน URL fragment (#token=...) เมื่อเป็นไปได้ fragment จะไม่ถูกส่งไปยังเซิร์ฟเวอร์ ซึ่งหลีกเลี่ยงการรั่วไหลผ่าน request-log และ Referer พารามิเตอร์ query แบบเดิม?token=ยังคงถูกนำเข้าได้หนึ่งครั้งเพื่อความเข้ากันได้ แต่ใช้เป็น fallback เท่านั้น และจะถูกตัดออกทันทีหลัง bootstrap passwordถูกเก็บไว้ในหน่วยความจำเท่านั้น- เมื่อ
gatewayUrlถูกตั้งค่า UI จะไม่ fallback ไปใช้ข้อมูลรับรองจาก config หรือ environment ให้ระบุtoken(หรือpassword) อย่างชัดเจน การขาดข้อมูลรับรองที่ระบุอย่างชัดเจนถือเป็นข้อผิดพลาด - ใช้
wss://เมื่อ Gateway อยู่หลัง TLS (Tailscale Serve, HTTPS proxy ฯลฯ) gatewayUrlยอมรับเฉพาะในหน้าต่างระดับบนสุด (ไม่ใช่แบบฝัง) เพื่อป้องกัน clickjacking- การปรับใช้ Control UI ที่ไม่ใช่ loopback ต้องตั้งค่า
gateway.controlUi.allowedOriginsอย่างชัดเจน (origin เต็ม) ซึ่งรวมถึงการตั้งค่า dev ระยะไกล - การเริ่มต้น Gateway อาจ seed origin ในเครื่อง เช่น
http://localhost:<port>และhttp://127.0.0.1:<port>จาก bind และ port ของ runtime ที่มีผล แต่ origin ของเบราว์เซอร์ระยะไกลยังต้องมีรายการอย่างชัดเจน - อย่าใช้
gateway.controlUi.allowedOrigins: ["*"]ยกเว้นสำหรับการทดสอบในเครื่องที่ควบคุมอย่างเข้มงวด หมายถึงอนุญาต origin ของเบราว์เซอร์ใดก็ได้ ไม่ใช่ “จับคู่กับโฮสต์อะไรก็ตามที่ฉันใช้อยู่” gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=trueเปิดใช้งานโหมด fallback origin จากส่วนหัว Host แต่เป็นโหมดความปลอดภัยที่อันตราย
ที่เกี่ยวข้อง
- แดชบอร์ด — แดชบอร์ด gateway
- การตรวจสอบสถานะ — การตรวจสอบสถานะ gateway
- TUI — อินเทอร์เฟซผู้ใช้บนเทอร์มินัล
- WebChat — อินเทอร์เฟซแชทบนเบราว์เซอร์