Web interfaces

ส่วนติดต่อผู้ใช้สำหรับควบคุม

Control UI เป็นแอปหน้าเดียวขนาดเล็กแบบ Vite + Lit ที่ Gateway ให้บริการ:

  • ค่าเริ่มต้น: http://<host>:18789/
  • คำนำหน้าเพิ่มเติม: ตั้งค่า gateway.controlUi.basePath (เช่น /openclaw)

แอปนี้สื่อสาร โดยตรงกับ Gateway WebSocket บนพอร์ตเดียวกัน

เปิดอย่างรวดเร็ว (ภายในเครื่อง)

หาก Gateway กำลังทำงานบนคอมพิวเตอร์เครื่องเดียวกัน ให้เปิด:

หากหน้าโหลดไม่สำเร็จ ให้เริ่ม Gateway ก่อน: openclaw gateway

ระบบส่งการยืนยันตัวตนระหว่างการจับมือ WebSocket ผ่าน:

  • connect.params.auth.token
  • connect.params.auth.password
  • ส่วนหัวตัวตน Tailscale Serve เมื่อ gateway.auth.allowTailscale: true
  • ส่วนหัวตัวตน trusted-proxy เมื่อ gateway.auth.mode: "trusted-proxy"

แผงการตั้งค่าแดชบอร์ดเก็บโทเค็นไว้สำหรับเซสชันแท็บเบราว์เซอร์ปัจจุบันและ URL ของ Gateway ที่เลือกไว้; รหัสผ่านจะไม่ถูกคงไว้ โดยปกติการเริ่มต้นใช้งานจะสร้างโทเค็น Gateway สำหรับการยืนยันตัวตนแบบความลับร่วมในการเชื่อมต่อครั้งแรก แต่การยืนยันตัวตนด้วยรหัสผ่านก็ใช้ได้เช่นกันเมื่อ gateway.auth.mode เป็น "password"

การจับคู่อุปกรณ์ (การเชื่อมต่อครั้งแรก)

เมื่อคุณเชื่อมต่อกับ Control UI จากเบราว์เซอร์หรืออุปกรณ์ใหม่ Gateway มักจะต้องใช้ การอนุมัติการจับคู่แบบครั้งเดียว นี่เป็นมาตรการรักษาความปลอดภัยเพื่อป้องกันการเข้าถึงโดยไม่ได้รับอนุญาต

สิ่งที่คุณจะเห็น: "disconnected (1008): pairing required"

  • แสดงรายการคำขอที่รอดำเนินการ

    bash
    openclaw devices list
  • อนุมัติด้วย ID คำขอ

    bash
    openclaw devices approve <requestId>
  • หากเบราว์เซอร์ลองจับคู่อีกครั้งด้วยรายละเอียดการยืนยันตัวตนที่เปลี่ยนไป (บทบาท/ขอบเขต/กุญแจสาธารณะ) คำขอที่รอดำเนินการก่อนหน้าจะถูกแทนที่ และจะสร้าง requestId ใหม่ ให้รัน openclaw devices list อีกครั้งก่อนอนุมัติ

    หากเบราว์เซอร์จับคู่แล้ว และคุณเปลี่ยนจากสิทธิ์อ่านเป็นสิทธิ์เขียน/ผู้ดูแลระบบ ระบบจะถือว่านี่เป็นการอัปเกรดการอนุมัติ ไม่ใช่การเชื่อมต่อใหม่แบบเงียบ OpenClaw จะคงการอนุมัติเดิมไว้ บล็อกการเชื่อมต่อใหม่ที่มีสิทธิ์กว้างขึ้น และขอให้คุณอนุมัติชุดขอบเขตใหม่อย่างชัดเจน

    เมื่ออนุมัติแล้ว อุปกรณ์จะถูกจดจำและจะไม่ต้องอนุมัติซ้ำ เว้นแต่คุณจะเพิกถอนด้วย openclaw devices revoke --device <id> --role <role> ดู CLI อุปกรณ์ สำหรับการหมุนเวียนและการเพิกถอนโทเค็น

    เอเจนต์ Paperclip ที่เชื่อมต่อผ่านอะแดปเตอร์ openclaw_gateway ใช้ขั้นตอนการอนุมัติครั้งแรกแบบเดียวกัน หลังจากพยายามเชื่อมต่อครั้งแรก ให้รัน openclaw devices approve --latest เพื่อดูตัวอย่างคำขอที่รอดำเนินการ จากนั้นรันคำสั่ง openclaw devices approve <requestId> ที่พิมพ์ออกมาอีกครั้งเพื่ออนุมัติ ส่งค่า --url และ --token อย่างชัดเจนสำหรับ Gateway ระยะไกล เพื่อให้การอนุมัติคงที่หลังรีสตาร์ต ให้กำหนดค่า adapterConfig.devicePrivateKeyPem แบบถาวรใน Paperclip แทนการปล่อยให้สร้างตัวตนอุปกรณ์ชั่วคราวใหม่ในแต่ละรัน

    จับคู่อุปกรณ์มือถือ

    ผู้ดูแลระบบที่จับคู่แล้วสามารถสร้าง QR การเชื่อมต่อ iOS/Android ได้โดยไม่ต้อง เปิดเทอร์มินัล:

  • เปิดการจับคู่มือถือ

    เลือก โหนด จากนั้นคลิก จับคู่อุปกรณ์มือถือ ในการ์ด อุปกรณ์

  • เชื่อมต่อโทรศัพท์

    ในแอปมือถือ OpenClaw ให้เปิด การตั้งค่าGateway แล้วสแกนรหัส QR คุณสามารถคัดลอกและวางรหัสตั้งค่าแทนได้

  • ยืนยันการเชื่อมต่อ

    แอป iOS/Android อย่างเป็นทางการจะเชื่อมต่อโดยอัตโนมัติ หาก อุปกรณ์ แสดง คำขอที่รอดำเนินการ ให้ตรวจสอบบทบาทและขอบเขตก่อนอนุมัติ

  • การสร้างรหัสตั้งค่าต้องใช้ operator.admin; ปุ่มจะถูกปิดใช้งานสำหรับ เซสชันที่ไม่มีสิทธิ์นี้ รหัสตั้งค่ามีข้อมูลรับรองเริ่มต้นที่มีอายุสั้น ดังนั้นให้ปฏิบัติกับ QR และรหัสที่คัดลอกเหมือนรหัสผ่านระหว่างที่ยังใช้ได้ สำหรับการจับคู่ระยะไกล Gateway ต้องแก้เป็น wss:// ได้ (ตัวอย่างเช่น ผ่าน Tailscale Serve/Funnel); ws:// แบบธรรมดาถูกจำกัดไว้ที่ที่อยู่ loopback และ LAN ส่วนตัว ดู การจับคู่ สำหรับ รายละเอียดความปลอดภัยและตัวเลือกสำรองทั้งหมด

    ตัวตนส่วนบุคคล (ภายในเบราว์เซอร์)

    Control UI รองรับตัวตนส่วนบุคคลต่อเบราว์เซอร์ (ชื่อที่แสดงและอวาตาร์) ที่แนบกับข้อความขาออกเพื่อระบุผู้ส่งในเซสชันที่ใช้ร่วมกัน ตัวตนนี้อยู่ในพื้นที่จัดเก็บของเบราว์เซอร์ จำกัดอยู่กับโปรไฟล์เบราว์เซอร์ปัจจุบัน และจะไม่ซิงค์ไปยังอุปกรณ์อื่นหรือคงไว้ฝั่งเซิร์ฟเวอร์นอกเหนือจากเมทาดาทาผู้เขียนทรานสคริปต์ตามปกติบนข้อความที่คุณส่งจริง การล้างข้อมูลไซต์หรือสลับเบราว์เซอร์จะรีเซ็ตให้ว่างเปล่า

    รูปแบบภายในเบราว์เซอร์แบบเดียวกันใช้กับการแทนที่อวาตาร์ผู้ช่วยด้วย อวาตาร์ผู้ช่วยที่อัปโหลดจะซ้อนทับตัวตนที่ Gateway แก้ได้เฉพาะในเบราว์เซอร์ภายในเครื่อง และจะไม่ส่งกลับไปกลับมาผ่าน config.patch ฟิลด์การกำหนดค่าที่ใช้ร่วมกัน ui.assistant.avatar ยังคงพร้อมใช้งานสำหรับไคลเอนต์ที่ไม่ใช่ UI ซึ่งเขียนฟิลด์นี้โดยตรง (เช่น Gateway แบบสคริปต์หรือแดชบอร์ดแบบกำหนดเอง)

    ปลายทางการกำหนดค่ารันไทม์

    Control UI ดึงการตั้งค่ารันไทม์จาก /control-ui-config.json ซึ่งแก้แบบสัมพันธ์กับเส้นทางฐาน Control UI ของ Gateway (ตัวอย่างเช่น /__openclaw__/control-ui-config.json เมื่อ UI ถูกให้บริการภายใต้ /__openclaw__/) ปลายทางนี้ถูกควบคุมด้วยการยืนยันตัวตน Gateway แบบเดียวกับพื้นผิว HTTP ส่วนที่เหลือ: เบราว์เซอร์ที่ไม่ได้ยืนยันตัวตนไม่สามารถดึงข้อมูลได้ และการดึงข้อมูลที่สำเร็จต้องมีโทเค็น/รหัสผ่าน Gateway ที่ยังใช้ได้อยู่แล้ว ตัวตน Tailscale Serve หรือ ตัวตน trusted-proxy

    การรองรับภาษา

    Control UI สามารถแปลภาษาตัวเองในการโหลดครั้งแรกตามโลเคลของเบราว์เซอร์ของคุณ หากต้องการแทนที่ในภายหลัง ให้เปิด ภาพรวม -> การเข้าถึง Gateway -> ภาษา ตัวเลือกโลเคลอยู่ในการ์ดการเข้าถึง Gateway ไม่ได้อยู่ภายใต้ลักษณะที่ปรากฏ

    • โลเคลที่รองรับ: en, zh-CN, zh-TW, pt-BR, de, es, ja-JP, ko, fr, ar, it, tr, uk, id, pl, th, vi, nl, fa
    • การแปลที่ไม่ใช่ภาษาอังกฤษจะถูกโหลดแบบ lazy ในเบราว์เซอร์
    • โลเคลที่เลือกจะถูกบันทึกในพื้นที่จัดเก็บของเบราว์เซอร์และใช้ซ้ำในการเข้าชมครั้งถัดไป
    • คีย์คำแปลที่หายไปจะถอยกลับไปใช้ภาษาอังกฤษ

    การแปลเอกสารถูกสร้างสำหรับชุดโลเคลที่ไม่ใช่ภาษาอังกฤษชุดเดียวกัน แต่ตัวเลือกภาษา Mintlify ในตัวของไซต์เอกสารถูกจำกัดไว้ที่รหัสโลเคลที่ Mintlify ยอมรับ เอกสารภาษาไทย (th) และเปอร์เซีย (fa) ยังคงถูกสร้างในรีโพเผยแพร่; เอกสารเหล่านี้อาจไม่ปรากฏในตัวเลือกนั้นจนกว่า Mintlify จะรองรับรหัสเหล่านั้น

    ธีมลักษณะที่ปรากฏ

    แผงลักษณะที่ปรากฏเก็บธีม Claw, Knot และ Dash ในตัวไว้ รวมถึงช่องนำเข้า tweakcn ภายในเบราว์เซอร์หนึ่งช่อง หากต้องการนำเข้าธีม ให้เปิด ตัวแก้ไข tweakcn เลือกหรือสร้างธีม คลิก แชร์ แล้ววางลิงก์ธีมที่คัดลอกไว้ลงในลักษณะที่ปรากฏ ตัวนำเข้ายังยอมรับ URL รีจิสทรี https://tweakcn.com/r/themes/<id>, URL ตัวแก้ไขอย่าง https://tweakcn.com/editor/theme?theme=amethyst-haze, เส้นทางสัมพัทธ์ /themes/<id>, ID ธีมดิบ และชื่อธีมเริ่มต้น เช่น amethyst-haze

    ลักษณะที่ปรากฏยังมีการตั้งค่าขนาดข้อความภายในเบราว์เซอร์ การตั้งค่านี้ถูกจัดเก็บร่วมกับค่ากำหนด Control UI ที่เหลือ ใช้กับข้อความแชต ข้อความตัวเขียน การ์ดเครื่องมือ และแถบด้านข้างของแชต และคงช่องป้อนข้อความไว้อย่างน้อย 16px เพื่อให้ Safari บนมือถือไม่ซูมอัตโนมัติเมื่อโฟกัส

    ธีมที่นำเข้าจะถูกจัดเก็บเฉพาะในโปรไฟล์เบราว์เซอร์ปัจจุบันเท่านั้น ธีมเหล่านี้จะไม่ถูกเขียนลงในการกำหนดค่า Gateway และจะไม่ซิงค์ข้ามอุปกรณ์ การแทนที่ธีมที่นำเข้าจะอัปเดตช่องภายในเครื่องช่องเดียว; การล้างธีมจะสลับธีมที่ใช้งานกลับไปเป็น Claw หากธีมที่นำเข้าถูกเลือกอยู่

    สิ่งที่ทำได้ (ตอนนี้)

    แชตและพูดคุย
    • แชตกับโมเดลผ่าน Gateway WS (chat.history, chat.send, chat.abort, chat.inject)
    • การรีเฟรชประวัติแชตจะขอหน้าต่างล่าสุดแบบมีขอบเขตพร้อมเพดานข้อความต่อข้อความ เพื่อให้เซสชันขนาดใหญ่ไม่บังคับให้เบราว์เซอร์เรนเดอร์เพย์โหลดทรานสคริปต์เต็มก่อนที่แชตจะใช้งานได้
    • พูดคุยผ่านเซสชันเรียลไทม์ของเบราว์เซอร์ OpenAI ใช้ WebRTC โดยตรง, Google Live ใช้โทเค็นเบราว์เซอร์แบบใช้ครั้งเดียวที่ถูกจำกัดผ่าน WebSocket และ Plugin เสียงเรียลไทม์แบบแบ็กเอนด์เท่านั้นใช้ทรานสปอร์ตรีเลย์ของ Gateway เซสชันผู้ให้บริการที่ไคลเอนต์เป็นเจ้าของเริ่มด้วย talk.client.create; เซสชันรีเลย์ Gateway เริ่มด้วย talk.session.create รีเลย์จะเก็บข้อมูลรับรองผู้ให้บริการไว้บน Gateway ขณะที่เบราว์เซอร์สตรีม PCM จากไมโครโฟนผ่าน talk.session.appendAudio, ส่งต่อการเรียกเครื่องมือผู้ให้บริการ openclaw_agent_consult ผ่าน talk.client.toolCall สำหรับนโยบาย Gateway และโมเดล OpenClaw ที่กำหนดค่าไว้ขนาดใหญ่กว่า และกำหนดเส้นทางการควบคุมเสียงของรันที่ทำงานอยู่ผ่าน talk.client.steer หรือ talk.session.steer
    • สตรีมการเรียกเครื่องมือ + การ์ดเอาต์พุตเครื่องมือสดในแชต (เหตุการณ์เอเจนต์)
    • แท็บกิจกรรมพร้อมสรุปกิจกรรมเครื่องมือสดจากการส่ง session.tool / เหตุการณ์เครื่องมือที่มีอยู่ ซึ่งอยู่ภายในเบราว์เซอร์และให้ความสำคัญกับการปกปิดข้อมูลก่อน
    ช่องทาง อินสแตนซ์ เซสชัน ความฝัน
    • ช่องทาง: สถานะช่องทาง Plugin ในตัว รวมถึงที่บันเดิล/ภายนอก, การเข้าสู่ระบบด้วย QR และการกำหนดค่าต่อช่องทาง (channels.status, web.login.*, config.patch)
    • การรีเฟรชการตรวจสอบช่องทางจะคงสแนปช็อตก่อนหน้าให้มองเห็นได้ขณะการตรวจสอบผู้ให้บริการที่ช้าดำเนินการเสร็จ และสแนปช็อตบางส่วนจะถูกติดป้ายเมื่อการตรวจสอบหรือการตรวจประเมินเกินงบเวลา UI
    • อินสแตนซ์: รายการสถานะพร้อมใช้งาน + รีเฟรช (system-presence)
    • เซสชัน: แสดงรายการเซสชันเอเจนต์ที่กำหนดค่าไว้เป็นค่าเริ่มต้น ปักหมุดเซสชันที่ใช้บ่อย เปลี่ยนชื่อ เก็บถาวรหรือกู้คืนเซสชันที่ไม่ใช้งาน ถอยกลับจากคีย์เซสชันเอเจนต์ที่ไม่ได้กำหนดค่าซึ่งเก่าเกินไป และใช้การแทนที่โมเดล/การคิด/เร็ว/ละเอียด/ติดตาม/การให้เหตุผลต่อเซสชัน (sessions.list, sessions.patch) เซสชันที่ปักหมุดจะเรียงเหนือเซสชันล่าสุดที่ไม่ได้ปักหมุด; เซสชันที่เก็บถาวรอยู่ในมุมมองที่เก็บถาวรของหน้าเซสชันและคงทรานสคริปต์ไว้
    • ความฝัน: สถานะ Dreaming, สวิตช์เปิด/ปิด และตัวอ่านไดอารีความฝัน (doctor.memory.status, doctor.memory.dreamDiary, config.patch)
    Cron, Skills, โหนด, การอนุมัติ exec
    • งาน Cron: แสดงรายการ/เพิ่ม/แก้ไข/รัน/เปิดใช้งาน/ปิดใช้งาน + ประวัติการรัน (cron.*)
    • Skills: สถานะ เปิดใช้งาน/ปิดใช้งาน ติดตั้ง อัปเดตคีย์ API (skills.*)
    • โหนด: แสดงรายการ + ความสามารถ (node.list), สร้างรหัสตั้งค่ามือถือ และอนุมัติการจับคู่อุปกรณ์ (device.pair.*)
    • การอนุมัติ exec: แก้ไขรายการอนุญาตของ Gateway หรือโหนด + นโยบายการถามสำหรับ exec host=gateway/node (exec.approvals.*)
    Config
    • ดู/แก้ไข ~/.openclaw/openclaw.json (config.get, config.set)
    • MCP มีหน้าการตั้งค่าเฉพาะสำหรับเซิร์ฟเวอร์ที่กำหนดค่าไว้ การเปิดใช้งาน สรุป OAuth/ตัวกรอง/การทำงานแบบขนาน คำสั่งผู้ปฏิบัติงานทั่วไป และตัวแก้ไขการกำหนดค่า mcp แบบจำกัดขอบเขต
    • นำไปใช้ + รีสตาร์ตพร้อมการตรวจสอบ (config.apply) และปลุกเซสชันที่ใช้งานล่าสุด
    • การเขียนมีตัวป้องกัน base-hash เพื่อป้องกันการเขียนทับการแก้ไขพร้อมกัน
    • การเขียน (config.set/config.apply/config.patch) จะตรวจสอบล่วงหน้าการแก้ค่า SecretRef ที่ใช้งานอยู่สำหรับ refs ในเพย์โหลดการกำหนดค่าที่ส่งมา; refs ที่ส่งมาซึ่งใช้งานอยู่แต่แก้ค่าไม่ได้จะถูกปฏิเสธก่อนเขียน
    • การบันทึกฟอร์มจะทิ้งตัวแทนค่าที่ถูกปกปิดซึ่งล้าสมัยและไม่สามารถกู้คืนจากการกำหนดค่าที่บันทึกไว้ได้ พร้อมคงค่าที่ถูกปกปิดซึ่งยังจับคู่กับ secret ที่บันทึกไว้
    • Schema + การเรนเดอร์ฟอร์ม (config.schema / config.schema.lookup รวมถึงฟิลด์ title / description, คำใบ้ UI ที่ตรงกัน, สรุปลูกโดยตรง, เมตาดาต้าเอกสารบนโหนด object/wildcard/array/composition ที่ซ้อนกัน รวมถึง schema ของ Plugin + ช่องทางเมื่อมี); ตัวแก้ไข Raw JSON จะใช้ได้เฉพาะเมื่อ snapshot มี raw round-trip ที่ปลอดภัย
    • หาก snapshot ไม่สามารถ round-trip ข้อความ raw ได้อย่างปลอดภัย Control UI จะบังคับใช้โหมดฟอร์มและปิดใช้งานโหมด Raw สำหรับ snapshot นั้น
    • ตัวแก้ไข Raw JSON "รีเซ็ตเป็นค่าที่บันทึกไว้" จะคงรูปทรงที่เขียนแบบ raw ไว้ (การจัดรูปแบบ, ความคิดเห็น, เลย์เอาต์ $include) แทนการเรนเดอร์ snapshot แบบแบนใหม่ ดังนั้นการแก้ไขภายนอกจะรอดจากการรีเซ็ตเมื่อ snapshot สามารถ round-trip ได้อย่างปลอดภัย
    • ค่า object SecretRef แบบมีโครงสร้างจะแสดงเป็นอ่านอย่างเดียวในอินพุตข้อความของฟอร์ม เพื่อป้องกันความเสียหายจากการแปลง object เป็น string โดยไม่ตั้งใจ
    Debug, logs, update
    • ดีบัก: snapshot สถานะ/สุขภาพ/โมเดล + บันทึกเหตุการณ์ + การเรียก RPC ด้วยตนเอง (status, health, models.list)
    • บันทึกเหตุการณ์รวมเวลา refresh/RPC ของ Control UI, เวลาเรนเดอร์ chat/config ที่ช้า และรายการการตอบสนองของเบราว์เซอร์สำหรับเฟรมแอนิเมชันยาวหรืองานยาวเมื่อเบราว์เซอร์เปิดเผยชนิดรายการ PerformanceObserver เหล่านั้น
    • บันทึก: tail แบบสดของบันทึกไฟล์ Gateway พร้อมตัวกรอง/ส่งออก (logs.tail)
    • อัปเดต: รันการอัปเดตแพ็กเกจ/git + รีสตาร์ต (update.run) พร้อมรายงานการรีสตาร์ต จากนั้น poll update.status หลังเชื่อมต่อใหม่เพื่อตรวจสอบเวอร์ชัน Gateway ที่กำลังทำงาน
    Cron jobs panel notes
    • สำหรับงานแบบแยกเดี่ยว การส่งมอบมีค่าเริ่มต้นเป็นประกาศสรุป คุณสามารถเปลี่ยนเป็นไม่มีได้หากต้องการให้รันเฉพาะภายใน
    • ฟิลด์ช่องทาง/เป้าหมายจะแสดงเมื่อเลือกประกาศ
    • โหมด Webhook ใช้ delivery.mode = "webhook" โดยตั้ง delivery.to เป็น URL webhook HTTP(S) ที่ถูกต้อง
    • สำหรับงานเซสชันหลัก โหมดการส่งมอบ webhook และไม่มีจะพร้อมใช้งาน
    • ตัวควบคุมการแก้ไขขั้นสูงรวมถึงลบหลังรัน, ล้างการ override agent, ตัวเลือก cron exact/stagger, การ override โมเดล/thinking ของ agent และสวิตช์การส่งมอบแบบ best-effort
    • การตรวจสอบฟอร์มเป็นแบบ inline พร้อมข้อผิดพลาดระดับฟิลด์; ค่าที่ไม่ถูกต้องจะปิดใช้งานปุ่มบันทึกจนกว่าจะแก้ไข
    • ตั้ง cron.webhookToken เพื่อส่ง bearer token เฉพาะ หากละไว้ webhook จะถูกส่งโดยไม่มีส่วนหัว auth
    • fallback ที่เลิกใช้แล้ว: รัน openclaw doctor --fix เพื่อย้ายงาน legacy ที่จัดเก็บไว้พร้อม notify: true จาก cron.webhook ไปเป็น webhook ต่อรายการงานอย่างชัดเจนหรือการส่งมอบเมื่อเสร็จสิ้น

    หน้า MCP

    หน้า MCP เฉพาะเป็นมุมมองผู้ปฏิบัติงานสำหรับเซิร์ฟเวอร์ MCP ที่ OpenClaw จัดการภายใต้ mcp.servers หน้านี้ไม่ได้เริ่ม transport ของ MCP ด้วยตัวเอง; ใช้เพื่อตรวจสอบและแก้ไขการกำหนดค่าที่บันทึกไว้ จากนั้นใช้ openclaw mcp doctor --probe เมื่อคุณต้องการหลักฐานเซิร์ฟเวอร์แบบสด

    เวิร์กโฟลว์ทั่วไป:

    1. เปิด MCP จากแถบด้านข้าง
    2. ตรวจสอบการ์ดสรุปสำหรับจำนวนเซิร์ฟเวอร์ทั้งหมด เปิดใช้งาน OAuth และมีตัวกรอง
    3. ตรวจสอบแต่ละแถวเซิร์ฟเวอร์สำหรับ transport, การเปิดใช้งาน, auth, ตัวกรอง, timeout และคำใบ้คำสั่ง
    4. สลับการเปิดใช้งานเมื่อเซิร์ฟเวอร์ควรยังคงถูกกำหนดค่าไว้แต่ไม่เข้าร่วมการค้นพบ runtime
    5. แก้ไขส่วนการกำหนดค่า mcp แบบจำกัดขอบเขตสำหรับนิยามเซิร์ฟเวอร์, ส่วนหัว, พาธ TLS/mTLS, เมตาดาต้า OAuth, ตัวกรองเครื่องมือ และเมตาดาต้าการฉายภาพของ Codex
    6. ใช้ บันทึก สำหรับการเขียนการกำหนดค่า หรือ บันทึกและเผยแพร่ เมื่อ Gateway ที่กำลังทำงานควรนำการกำหนดค่าที่เปลี่ยนแปลงไปใช้
    7. รัน openclaw mcp status --verbose, openclaw mcp doctor --probe หรือ openclaw mcp reload จากเทอร์มินัลเมื่อกระบวนการที่แก้ไขต้องการ diagnostics แบบคงที่, หลักฐานแบบสด หรือการทิ้ง cached-runtime

    หน้านี้ปกปิดค่าคล้าย URL ที่มีข้อมูลประจำตัวก่อนเรนเดอร์ และใส่เครื่องหมายคำพูดให้ชื่อเซิร์ฟเวอร์ใน snippet คำสั่งเพื่อให้คำสั่งที่คัดลอกยังทำงานกับช่องว่างหรืออักขระพิเศษของ shell ได้ เอกสารอ้างอิง CLI และการกำหนดค่าฉบับเต็มอยู่ใน MCP

    แท็บกิจกรรม

    แท็บกิจกรรมเป็นตัวสังเกตแบบชั่วคราวเฉพาะเบราว์เซอร์สำหรับกิจกรรมเครื่องมือแบบสด ซึ่งได้มาจากสตรีมเหตุการณ์ Gateway session.tool / เครื่องมือเดียวกับที่ขับเคลื่อนการ์ดเครื่องมือของ Chat; แท็บนี้ไม่ได้เพิ่มตระกูลเหตุการณ์ Gateway, endpoint, ที่จัดเก็บกิจกรรมถาวร, ฟีด metrics หรือสตรีมตัวสังเกตภายนอกอีกชุดหนึ่ง

    รายการกิจกรรมจะเก็บเฉพาะสรุปที่ล้างข้อมูลแล้วและตัวอย่าง output ที่ถูกปกปิดและตัดทอน ค่าอาร์กิวเมนต์ของเครื่องมือจะไม่ถูกจัดเก็บในสถานะกิจกรรม; UI แสดงว่าอาร์กิวเมนต์ถูกซ่อนไว้และบันทึกเฉพาะจำนวนฟิลด์อาร์กิวเมนต์ รายการในหน่วยความจำติดตามแท็บเบราว์เซอร์ปัจจุบัน อยู่รอดจากการนำทางภายใน Control UI และรีเซ็ตเมื่อโหลดหน้าใหม่ สลับเซสชัน หรือกด ล้าง

    พฤติกรรม Chat

    Send and history semantics
    • chat.send เป็นแบบ ไม่บล็อก: ตอบรับทันทีด้วย { runId, status: "started" } และสตรีมคำตอบผ่านเหตุการณ์ chat ไคลเอนต์ Control UI ที่เชื่อถือได้อาจได้รับเมตาดาต้าเวลา ACK เพิ่มเติมสำหรับ diagnostics ภายในเครื่องด้วย
    • การอัปโหลด Chat รองรับรูปภาพและไฟล์ที่ไม่ใช่วิดีโอ รูปภาพจะคงพาธรูปภาพดั้งเดิม; ไฟล์อื่นจะถูกจัดเก็บเป็นสื่อที่จัดการและแสดงในประวัติเป็นลิงก์แนบ
    • การส่งซ้ำด้วย idempotencyKey เดิมจะคืน { status: "in_flight" } ระหว่างที่กำลังทำงาน และ { status: "ok" } หลังเสร็จสิ้น
    • คำตอบ chat.history ถูกจำกัดขนาดเพื่อความปลอดภัยของ UI เมื่อรายการ transcript ใหญ่เกินไป Gateway อาจตัดทอนฟิลด์ข้อความยาว ละเว้นบล็อกเมตาดาต้าหนัก และแทนที่ข้อความที่ใหญ่เกินด้วยตัวแทน ([chat.history omitted: message too large])
    • เมื่อข้อความผู้ช่วยที่มองเห็นได้ถูกตัดทอนใน chat.history ตัวอ่านด้านข้างสามารถดึงรายการ transcript แบบ display-normalized ฉบับเต็มตามต้องการผ่าน chat.message.get ด้วย sessionKey, agentId ที่ใช้งานอยู่เมื่อจำเป็น และ messageId ของ transcript หาก Gateway ยังไม่สามารถคืนข้อมูลเพิ่มได้ ตัวอ่านจะแสดงสถานะไม่พร้อมใช้งานอย่างชัดเจนแทนการแสดงตัวอย่างที่ถูกตัดทอนซ้ำอย่างเงียบ ๆ
    • รูปภาพที่ผู้ช่วย/ระบบสร้างขึ้นจะถูกคงอยู่เป็น managed media references และให้บริการกลับผ่าน URL สื่อ Gateway ที่ยืนยันตัวตนแล้ว ดังนั้นการโหลดใหม่จึงไม่ขึ้นกับเพย์โหลดรูปภาพ base64 ดิบที่ยังอยู่ในคำตอบประวัติ Chat
    • เมื่อเรนเดอร์ chat.history Control UI จะลบแท็กคำสั่ง inline ที่ใช้แสดงผลเท่านั้นออกจากข้อความผู้ช่วยที่มองเห็นได้ (เช่น [[reply_to_*]] และ [[audio_as_voice]]), เพย์โหลด XML การเรียกเครื่องมือแบบข้อความล้วน (รวมถึง <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, <function_calls>...</function_calls> และบล็อกการเรียกเครื่องมือที่ถูกตัดทอน), และโทเค็นควบคุมโมเดล ASCII/full-width ที่รั่วไหล และละเว้นรายการผู้ช่วยที่ข้อความที่มองเห็นได้ทั้งหมดเป็นเพียง silent token ที่ตรงเป๊ะ NO_REPLY / no_reply หรือโทเค็นตอบรับ Heartbeat HEARTBEAT_OK
    • ระหว่างการส่งที่ใช้งานอยู่และการ refresh ประวัติครั้งสุดท้าย มุมมอง Chat จะคงข้อความผู้ใช้/ผู้ช่วยแบบ optimistic ภายในเครื่องให้มองเห็นได้หาก chat.history คืน snapshot ที่เก่ากว่าชั่วครู่; transcript canonical จะแทนที่ข้อความภายในเครื่องเหล่านั้นเมื่อประวัติ Gateway ตามทัน
    • เหตุการณ์ chat แบบสดคือสถานะการส่งมอบ ขณะที่ chat.history ถูกสร้างใหม่จาก transcript เซสชันถาวร หลังเหตุการณ์ tool-final Control UI จะโหลดประวัติใหม่และ merge เฉพาะส่วนท้ายแบบ optimistic ขนาดเล็ก; ขอบเขต transcript อธิบายไว้ใน WebChat
    • chat.inject เพิ่มโน้ตผู้ช่วยต่อท้าย transcript เซสชันและ broadcast เหตุการณ์ chat สำหรับการอัปเดตเฉพาะ UI (ไม่มี agent run, ไม่มีการส่งมอบช่องทาง)
    • แถบด้านข้างแสดงเซสชันล่าสุดพร้อมการกระทำเซสชันใหม่ ลิงก์เซสชันทั้งหมด และปุ่มค้นหาเซสชันที่เปิดตัวเลือกเซสชันแบบเต็ม (จำกัดขอบเขตตาม agent ที่เลือก พร้อมการค้นหาและ pagination) การสลับ agent จะแสดงเฉพาะเซสชันที่ผูกกับ agent นั้น และ fallback ไปยังเซสชันหลักของ agent นั้นเมื่อยังไม่มีเซสชัน dashboard ที่บันทึกไว้
    • แต่ละแถวในตัวเลือกเซสชันสามารถเปลี่ยนชื่อ ปักหมุด หรือ archive เซสชันได้ run ที่ใช้งานอยู่และเซสชันหลักของ agent ไม่สามารถ archive ได้ การ archive เซสชันที่เลือกอยู่ในปัจจุบันจะสลับ Chat กลับไปยังเซสชันหลักของ agent นั้น
    • บนความกว้างระดับเดสก์ท็อป ตัวควบคุม Chat จะอยู่ในแถวกะทัดรัดแถวเดียวและยุบขณะเลื่อนลง transcript; การเลื่อนขึ้น กลับไปด้านบน หรือไปถึงด้านล่างจะคืนตัวควบคุม
    • ข้อความข้อความล้วนที่ซ้ำกันต่อเนื่องจะเรนเดอร์เป็น bubble เดียวพร้อม badge จำนวน ข้อความที่มีรูปภาพ ไฟล์แนบ output เครื่องมือ หรือ canvas preview จะไม่ถูกยุบ
    • ตัวเลือกโมเดลและ thinking ในส่วนหัว Chat จะ patch เซสชันที่ใช้งานอยู่ทันทีผ่าน sessions.patch; สิ่งเหล่านี้เป็นการ override เซสชันแบบถาวร ไม่ใช่ตัวเลือกส่งสำหรับรอบเดียวเท่านั้น
    • หากคุณส่งข้อความขณะที่การเปลี่ยนตัวเลือกโมเดลสำหรับเซสชันเดียวกันยังบันทึกอยู่ composer จะรอ session patch นั้นก่อนเรียก chat.send เพื่อให้การส่งใช้โมเดลที่เลือก
    • การพิมพ์ /new ใน Control UI จะสร้างและสลับไปยังเซสชัน dashboard ใหม่แบบเดียวกับ New Chat ยกเว้นเมื่อกำหนดค่า session.dmScope: "main" และ parent ปัจจุบันเป็นเซสชันหลักของ agent; ในกรณีนั้นจะรีเซ็ตเซสชันหลักในที่เดิม การพิมพ์ /reset จะคงการรีเซ็ตในที่เดิมอย่างชัดเจนของ Gateway สำหรับเซสชันปัจจุบัน
    • ตัวเลือกโมเดลของ Chat ขอ model view ที่กำหนดค่าไว้ของ Gateway หากมี agents.defaults.models allowlist นั้นจะขับเคลื่อนตัวเลือก รวมถึงรายการ provider/* ที่ทำให้ catalog แบบจำกัดขอบเขต provider เป็นแบบไดนามิก มิฉะนั้นตัวเลือกจะแสดงรายการ models.providers.*.models ที่ชัดเจนพร้อม provider ที่มี auth ใช้งานได้ catalog ฉบับเต็มยังพร้อมใช้งานผ่าน RPC ดีบัก models.list ด้วย view: "all"
    • เมื่อรายงานการใช้งานเซสชัน Gateway ใหม่มี context tokens ปัจจุบัน แถบเครื่องมือ composer ของ Chat จะแสดงวงแหวนการใช้งาน context ขนาดเล็กพร้อมเปอร์เซ็นต์ที่ใช้; รายละเอียด token ฉบับเต็มอยู่ใน tooltip วงแหวนจะเปลี่ยนเป็นสไตล์คำเตือนเมื่อ context กดดันสูง และที่ระดับ Compaction ที่แนะนำ จะแสดงปุ่มกะทัดรัดที่รันเส้นทาง Compaction เซสชันปกติ snapshot token ที่ล้าสมัยจะถูกซ่อนไว้จนกว่า Gateway จะรายงานการใช้งานใหม่อีกครั้ง
    Talk mode (browser realtime)

    โหมดพูดใช้ผู้ให้บริการเสียง realtime ที่ลงทะเบียนไว้ กำหนดค่า OpenAI ด้วย talk.realtime.provider: "openai" พร้อมโปรไฟล์ auth แบบคีย์ API openai, talk.realtime.providers.openai.apiKey หรือ OPENAI_API_KEY; โปรไฟล์ OAuth ของ OpenAI ไม่ได้กำหนดค่าเสียง Realtime กำหนดค่า Google ด้วย talk.realtime.provider: "google" พร้อม talk.realtime.providers.google.apiKey เบราว์เซอร์จะไม่เคยได้รับคีย์ API ของ provider มาตรฐาน OpenAI ได้รับ secret ไคลเอนต์ Realtime แบบชั่วคราวสำหรับ WebRTC Google Live ได้รับ token auth Live API แบบจำกัดและใช้ครั้งเดียวสำหรับเซสชัน WebSocket ของเบราว์เซอร์ พร้อมคำสั่งและการประกาศเครื่องมือที่ถูกล็อกไว้ใน token โดย Gateway provider ที่เปิดเผยเฉพาะ backend realtime bridge จะทำงานผ่าน transport relay ของ Gateway ดังนั้นข้อมูลประจำตัวและ socket ของ vendor จะอยู่ฝั่งเซิร์ฟเวอร์ ขณะที่เสียงของเบราว์เซอร์ย้ายผ่าน RPC ของ Gateway ที่ยืนยันตัวตนแล้ว prompt ของเซสชัน Realtime ประกอบโดย Gateway; talk.client.create ไม่ยอมรับการ override คำสั่งที่ caller ระบุ

    ตัวเขียนข้อความแชทมีปุ่มตัวเลือกการพูดคุยอยู่ถัดจากปุ่มเริ่ม/หยุดการพูดคุย ตัวเลือกเหล่านี้มีผลกับเซสชันการพูดคุยถัดไป และสามารถแทนที่ผู้ให้บริการ, การรับส่ง, โมเดล, เสียง, ระดับความพยายามในการให้เหตุผล, เกณฑ์ VAD, ระยะเวลาความเงียบ และระยะ padding ของคำนำหน้าได้ เมื่อตัวเลือกว่าง Gateway จะใช้ค่าเริ่มต้นที่กำหนดค่าไว้เมื่อมี หรือใช้ค่าเริ่มต้นของผู้ให้บริการ การเลือก Gateway relay จะบังคับใช้เส้นทาง relay ของแบ็กเอนด์ ส่วนการเลือก WebRTC จะคงให้เซสชันเป็นของไคลเอนต์ และจะล้มเหลวแทนการถอยกลับไปใช้ relay แบบเงียบ ๆ หากผู้ให้บริการไม่สามารถสร้างเซสชันเบราว์เซอร์ได้

    ในตัวเขียนข้อความแชท ตัวควบคุมการพูดคุยคือปุ่มรูปคลื่นที่อยู่ถัดจากปุ่มบันทึกเสียงตามคำบอกด้วยไมโครโฟน เมื่อการพูดคุยเริ่มขึ้น แถวสถานะของตัวเขียนข้อความจะแสดง 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 relay พร้อมสื่อไมโครโฟนจำลอง คำสั่งนี้พิมพ์เฉพาะสถานะผู้ให้บริการและไม่บันทึกความลับ

    หยุดและยกเลิก
    • คลิก หยุด (เรียก chat.abort)
    • ขณะที่การรันทำงานอยู่ การติดตามผลปกติจะเข้าคิว คลิก นำทาง บนข้อความที่เข้าคิวเพื่อแทรกการติดตามผลนั้นเข้าไปในเทิร์นที่กำลังรันอยู่
    • พิมพ์ /stop (หรือวลี abort แบบเดี่ยว เช่น stop, stop action, stop run, stop openclaw, please stop) เพื่อยกเลิกนอกแบนด์
    • chat.abort รองรับ { sessionKey } (ไม่มี runId) เพื่อยกเลิกการรันที่ทำงานอยู่ทั้งหมดสำหรับเซสชันนั้น
    การเก็บส่วนบางส่วนหลัง abort
    • เมื่อการรันถูก abort ข้อความบางส่วนของผู้ช่วยยังสามารถแสดงใน UI ได้
    • Gateway จะคงข้อความผู้ช่วยบางส่วนที่ถูก abort ไว้ในประวัติ transcript เมื่อมีเอาต์พุตที่บัฟเฟอร์ไว้
    • รายการที่คงไว้มีเมทาดาทา abort เพื่อให้ผู้บริโภค transcript แยกส่วนบางส่วนจาก abort ออกจากเอาต์พุตการเสร็จสิ้นปกติได้

    การติดตั้ง PWA และ web push

    Control UI มาพร้อม manifest.webmanifest และ service worker ดังนั้นเบราว์เซอร์สมัยใหม่จึงติดตั้งเป็น PWA แบบสแตนด์อโลนได้ Web Push ช่วยให้ Gateway ปลุก PWA ที่ติดตั้งไว้ด้วยการแจ้งเตือนได้ แม้เมื่อแท็บหรือหน้าต่างเบราว์เซอร์ไม่ได้เปิดอยู่

    หากหน้าแสดง Protocol mismatch ทันทีหลังจากอัปเดต OpenClaw ให้เปิดแดชบอร์ดใหม่ด้วย openclaw dashboard แล้ว hard-refresh หน้า หากยังล้มเหลว ให้ล้างข้อมูลไซต์สำหรับ origin ของแดชบอร์ด หรือทดสอบในหน้าต่างเบราว์เซอร์ส่วนตัว แท็บเก่าหรือแคช service worker ของเบราว์เซอร์อาจยังคงรันบันเดิล Control UI ก่อนอัปเดตกับ Gateway ที่ใหม่กว่า

    พื้นผิว สิ่งที่ทำ
    ui/public/manifest.webmanifest manifest ของ PWA เบราว์เซอร์จะเสนอ "ติดตั้งแอป" เมื่อเข้าถึงได้
    ui/public/sw.js service worker ที่จัดการเหตุการณ์ push และการคลิกการแจ้งเตือน
    push/vapid-keys.json (ภายใต้ไดเรกทอรีสถานะของ OpenClaw) คู่กุญแจ VAPID ที่สร้างอัตโนมัติซึ่งใช้ลงนาม payload ของ Web Push
    push/web-push-subscriptions.json endpoint การสมัครรับข้อมูลของเบราว์เซอร์ที่คงไว้

    แทนที่คู่กุญแจ VAPID ผ่าน env vars บนโปรเซส Gateway เมื่อคุณต้องการตรึงกุญแจ (สำหรับการปรับใช้หลายโฮสต์, การหมุนเวียนความลับ หรือการทดสอบ):

    • OPENCLAW_VAPID_PUBLIC_KEY
    • OPENCLAW_VAPID_PRIVATE_KEY
    • OPENCLAW_VAPID_SUBJECT (ค่าเริ่มต้นเป็น https://openclaw.ai)

    Control UI ใช้วิธีของ Gateway ที่จำกัดด้วย scope เหล่านี้เพื่อลงทะเบียนและทดสอบการสมัครรับข้อมูลของเบราว์เซอร์:

    • push.web.vapidPublicKey — ดึงคีย์สาธารณะ VAPID ที่ใช้งานอยู่
    • push.web.subscribe — ลงทะเบียน endpoint พร้อม keys.p256dh/keys.auth
    • push.web.unsubscribe — ลบ endpoint ที่ลงทะเบียนไว้
    • push.web.test — ส่งการแจ้งเตือนทดสอบไปยังการสมัครรับข้อมูลของผู้เรียก

    embed ที่โฮสต์ไว้

    ข้อความผู้ช่วยสามารถเรนเดอร์เนื้อหาเว็บที่โฮสต์ไว้แบบอินไลน์ด้วย shortcode [embed ...] นโยบาย sandbox ของ iframe ถูกควบคุมโดย gateway.controlUi.embedSandbox:

    strict

    ปิดใช้งานการรันสคริปต์ภายใน embed ที่โฮสต์ไว้

    scripts (default)

    อนุญาต embed แบบโต้ตอบได้โดยยังคงแยก origin ไว้ ค่านี้เป็นค่าเริ่มต้นและมักเพียงพอสำหรับเกม/วิดเจ็ตเบราว์เซอร์แบบครบในตัว

    trusted

    เพิ่ม allow-same-origin บน allow-scripts สำหรับเอกสาร same-site ที่ตั้งใจต้องการสิทธิ์ที่แข็งแรงกว่า

    ตัวอย่าง:

    json5
    {  gateway: {    controlUi: {      embedSandbox: "scripts",    },  },}

    URL embed ภายนอกแบบ absolute http(s) จะยังถูกบล็อกตามค่าเริ่มต้น หากคุณตั้งใจให้ [embed url="https://..."] โหลดหน้าของบุคคลที่สาม ให้ตั้งค่า gateway.controlUi.allowExternalEmbedUrls: true

    ความกว้างของข้อความแชท

    ข้อความแชทที่จัดกลุ่มใช้ max-width เริ่มต้นที่อ่านง่าย การปรับใช้บนจอกว้างสามารถแทนที่ได้โดยไม่ต้องแพตช์ CSS ที่บันเดิลไว้ ด้วยการตั้งค่า gateway.controlUi.chatMessageMaxWidth:

    json5
    {  gateway: {    controlUi: {      chatMessageMaxWidth: "min(1280px, 82%)",    },  },}

    ค่านี้ถูกตรวจสอบก่อนถึงเบราว์เซอร์ ค่าที่รองรับรวมถึงความยาวและเปอร์เซ็นต์แบบธรรมดา เช่น 960px หรือ 82% รวมถึงนิพจน์ความกว้างแบบมีข้อจำกัด min(...), max(...), clamp(...), calc(...) และ fit-content(...)

    การเข้าถึง tailnet (แนะนำ)

    Tailscale Serve แบบผสานรวม (แนะนำ)

    คง Gateway ไว้บน loopback และให้ Tailscale Serve ทำพร็อกซีด้วย HTTPS:

    bash
    openclaw gateway --tailscale serve

    เปิด:

    • https://<magicdns>/ (หรือ gateway.controlUi.basePath ที่คุณกำหนดค่าไว้)

    ตามค่าเริ่มต้น คำขอ Control UI/WebSocket Serve สามารถรับรองความถูกต้องผ่าน header ระบุตัวตน Tailscale (tailscale-user-login) เมื่อ gateway.auth.allowTailscale เป็น true OpenClaw ตรวจสอบตัวตนด้วยการ resolve ที่อยู่ x-forwarded-for ด้วย tailscale whois แล้วจับคู่กับ header และยอมรับเฉพาะเมื่อคำขอเข้าถึง loopback พร้อม header x-forwarded-* ของ Tailscale สำหรับเซสชันผู้ปฏิบัติการ Control UI ที่มีตัวตนอุปกรณ์เบราว์เซอร์ เส้นทาง Serve ที่ตรวจสอบแล้วนี้ยังข้ามรอบการจับคู่อุปกรณ์ด้วย ส่วนเบราว์เซอร์ที่ไม่มีอุปกรณ์และการเชื่อมต่อบทบาท node ยังคงใช้การตรวจสอบอุปกรณ์ปกติ ตั้งค่า gateway.auth.allowTailscale: false หากคุณต้องการบังคับใช้ข้อมูลรับรอง shared-secret อย่างชัดเจนแม้กับทราฟฟิก Serve จากนั้นใช้ gateway.auth.mode: "token" หรือ "password"

    สำหรับเส้นทางตัวตน Serve แบบ async นั้น ความพยายาม auth ที่ล้มเหลวสำหรับ IP ไคลเอนต์และ scope auth เดียวกันจะถูกจัดลำดับก่อนเขียน rate-limit ดังนั้นการลองใหม่ที่ผิดพลาดพร้อมกันจากเบราว์เซอร์เดียวกันอาจแสดง retry later ในคำขอที่สอง แทนที่จะเกิด mismatch ธรรมดาสองรายการที่แข่งกันแบบขนาน

    Bind ไปยัง tailnet + token

    bash
    openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"

    จากนั้นเปิด:

    • http://<tailscale-ip>:18789/ (หรือ gateway.controlUi.basePath ที่คุณกำหนดค่าไว้)

    วาง shared secret ที่ตรงกันลงในการตั้งค่า UI (ส่งเป็น connect.params.auth.token หรือ connect.params.auth.password)

    HTTP ที่ไม่ปลอดภัย

    หากคุณเปิดแดชบอร์ดผ่าน HTTP ธรรมดา (http://<lan-ip> หรือ http://<tailscale-ip>) เบราว์เซอร์จะรันใน บริบทที่ไม่ปลอดภัย และบล็อก WebCrypto ตามค่าเริ่มต้น OpenClaw บล็อก การเชื่อมต่อ Control UI ที่ไม่มีตัวตนอุปกรณ์

    ข้อยกเว้นที่มีเอกสาร:

    • ความเข้ากันได้ของ HTTP ที่ไม่ปลอดภัยเฉพาะ localhost ด้วย gateway.controlUi.allowInsecureAuth=true
    • auth ของ Control UI ผู้ปฏิบัติการที่สำเร็จผ่าน gateway.auth.mode: "trusted-proxy"
    • ตัวเลือกฉุกเฉิน gateway.controlUi.dangerouslyDisableDeviceAuth=true

    วิธีแก้ที่แนะนำ: ใช้ HTTPS (Tailscale Serve) หรือเปิด UI ในเครื่อง:

    • https://<magicdns>/ (Serve)
    • http://127.0.0.1:18789/ (บนโฮสต์ gateway)
    พฤติกรรม toggle ของ insecure-auth
    json5
    {  gateway: {    controlUi: { allowInsecureAuth: true },    bind: "tailnet",    auth: { mode: "token", token: "replace-me" },  },}

    allowInsecureAuth เป็น toggle ความเข้ากันได้เฉพาะ local เท่านั้น:

    • อนุญาตให้เซสชัน Control UI ของ localhost ดำเนินต่อได้โดยไม่มีตัวตนอุปกรณ์ในบริบท HTTP ที่ไม่ปลอดภัย
    • ไม่ข้ามการตรวจสอบการจับคู่
    • ไม่ผ่อนคลายข้อกำหนดตัวตนอุปกรณ์ระยะไกล (ไม่ใช่ localhost)
    เฉพาะกรณีฉุกเฉิน
    json5
    {  gateway: {    controlUi: { dangerouslyDisableDeviceAuth: true },    bind: "tailnet",    auth: { mode: "token", token: "replace-me" },  },}
    หมายเหตุ trusted-proxy
    • auth แบบ trusted-proxy ที่สำเร็จสามารถรับเซสชัน Control UI ของ ผู้ปฏิบัติการ โดยไม่มีตัวตนอุปกรณ์ได้
    • สิ่งนี้ ไม่ ขยายไปยังเซสชัน Control UI บทบาท node
    • reverse proxy local loopback บนโฮสต์เดียวกันยังไม่ผ่าน auth แบบ trusted-proxy; ดู auth แบบ trusted proxy

    ดู Tailscale สำหรับคำแนะนำการตั้งค่า HTTPS

    นโยบายความปลอดภัยของเนื้อหา

    Control UI มาพร้อมนโยบาย img-src ที่เข้มงวด: อนุญาตเฉพาะ asset แบบ same-origin, URL data: และ URL blob: ที่สร้างขึ้นในเครื่องเท่านั้น URL รูปภาพระยะไกลแบบ http(s) และแบบ relative ต่อ protocol จะถูกเบราว์เซอร์ปฏิเสธและไม่เกิดการ fetch เครือข่าย

    ความหมายในทางปฏิบัติ:

    • Avatar และรูปภาพที่ให้บริการภายใต้ path แบบ relative (เช่น /avatars/<id>) ยังเรนเดอร์ได้ รวมถึง route avatar ที่ผ่านการรับรองความถูกต้องซึ่ง UI fetch แล้วแปลงเป็น URL blob: ในเครื่อง
    • URL data:image/... แบบอินไลน์ยังเรนเดอร์ได้ (มีประโยชน์สำหรับ payload ภายในโปรโตคอล)
    • URL blob: ในเครื่องที่ Control UI สร้างยังเรนเดอร์ได้
    • URL avatar ระยะไกลที่ channel metadata ปล่อยออกมาจะถูกตัดออกที่ helper avatar ของ Control UI และแทนที่ด้วยโลโก้/ป้ายในตัว ดังนั้น channel ที่ถูกยึดหรือเป็นอันตรายจึงไม่สามารถบังคับให้เบราว์เซอร์ผู้ปฏิบัติการ fetch รูปภาพระยะไกลตามอำเภอใจได้

    คุณไม่จำเป็นต้องเปลี่ยนอะไรเพื่อให้ได้พฤติกรรมนี้ — เปิดใช้อยู่เสมอและกำหนดค่าไม่ได้

    auth ของ route avatar

    เมื่อกำหนดค่า auth ของ gateway แล้ว endpoint avatar ของ Control UI ต้องใช้ token ของ gateway เดียวกับส่วนที่เหลือของ API:

    • GET /avatar/<agentId> คืนรูปภาพ avatar เฉพาะให้ผู้เรียกที่ผ่านการรับรองความถูกต้องเท่านั้น GET /avatar/<agentId>?meta=1 คืนเมทาดาทา avatar ภายใต้กฎเดียวกัน
    • คำขอที่ไม่ผ่านการรับรองความถูกต้องไปยัง route ใด route หนึ่งจะถูกปฏิเสธ (ตรงกับ route assistant-media ที่เป็นพี่น้องกัน) สิ่งนี้ป้องกันไม่ให้ route avatar รั่วไหลตัวตน agent บนโฮสต์ที่ได้รับการปกป้องอยู่แล้ว
    • Control UI เองส่งต่อ token ของ gateway เป็น bearer header เมื่อ fetch avatar และใช้ URL blob ที่ผ่านการรับรองความถูกต้องเพื่อให้รูปภาพยังเรนเดอร์ในแดชบอร์ดได้

    หากคุณปิดใช้งานการยืนยันตัวตนของ Gateway (ไม่แนะนำบนโฮสต์ที่ใช้ร่วมกัน) เส้นทาง avatar จะกลายเป็นแบบไม่ต้องยืนยันตัวตนเช่นกัน สอดคล้องกับส่วนอื่นของ Gateway

    การยืนยันตัวตนของเส้นทางสื่อของ Assistant

    เมื่อกำหนดค่าการยืนยันตัวตนของ Gateway แล้ว ตัวอย่างสื่อภายในเครื่องของ assistant จะใช้เส้นทางสองขั้นตอน:

    • GET /__openclaw__/assistant-media?meta=1&source=<path> ต้องใช้การยืนยันตัวตนผู้ปฏิบัติงาน Control UI ตามปกติ เบราว์เซอร์ส่งโทเค็น Gateway เป็น bearer header เมื่อตรวจสอบความพร้อมใช้งาน
    • การตอบกลับ metadata ที่สำเร็จจะมี mediaTicket อายุสั้นซึ่งจำกัดขอบเขตไว้กับเส้นทาง source นั้นโดยตรง
    • URL ของรูปภาพ เสียง วิดีโอ และเอกสารที่แสดงผลในเบราว์เซอร์จะใช้ mediaTicket=<ticket> แทนโทเค็นหรือรหัสผ่าน Gateway ที่ใช้งานอยู่ ตั๋วจะหมดอายุอย่างรวดเร็วและไม่สามารถอนุญาต source อื่นได้

    วิธีนี้ทำให้การแสดงผลสื่อตามปกติยังเข้ากันได้กับองค์ประกอบสื่อแบบเนทีฟของเบราว์เซอร์ โดยไม่ใส่ข้อมูลประจำตัว Gateway ที่นำกลับมาใช้ซ้ำได้ไว้ใน URL สื่อที่มองเห็นได้

    การสร้าง UI

    Gateway ให้บริการไฟล์ static จาก dist/control-ui สร้างไฟล์เหล่านี้ด้วย:

    bash
    pnpm ui:build

    base แบบ absolute ที่เป็นตัวเลือก (เมื่อคุณต้องการ URL asset แบบคงที่):

    bash
    OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build

    สำหรับการพัฒนาภายในเครื่อง (dev server แยกต่างหาก):

    bash
    pnpm ui:dev

    จากนั้นชี้ UI ไปยัง URL ของ Gateway WS ของคุณ (เช่น ws://127.0.0.1:18789)

    หน้า Control UI ว่างเปล่า

    หากเบราว์เซอร์โหลด dashboard ว่างเปล่าและ DevTools ไม่แสดงข้อผิดพลาดที่เป็นประโยชน์ extension หรือ content script ที่ทำงานช่วงต้นอาจทำให้แอปโมดูล JavaScript ไม่ได้ประเมินผล หน้า static มีแผงกู้คืน HTML แบบเรียบง่ายซึ่งจะแสดงขึ้นเมื่อ <openclaw-app> ไม่ได้ลงทะเบียนหลังจากเริ่มต้น

    ใช้การกระทำ ลองอีกครั้ง ของแผงหลังจากเปลี่ยนสภาพแวดล้อมของเบราว์เซอร์ หรือโหลดใหม่ด้วยตนเองหลังจากตรวจสอบรายการเหล่านี้:

    • ปิดใช้งาน extension ที่แทรกเข้าไปในทุกหน้า โดยเฉพาะ extension ที่มี content script แบบ <all_urls>
    • ลองใช้หน้าต่างส่วนตัว โปรไฟล์เบราว์เซอร์ใหม่สะอาด หรือเบราว์เซอร์อื่น
    • ให้ Gateway ทำงานต่อไปและตรวจสอบ URL dashboard เดิมหลังจากเปลี่ยนเบราว์เซอร์

    การดีบัก/ทดสอบ: dev server + Gateway ระยะไกล

    Control UI เป็นไฟล์ static; เป้าหมาย WebSocket กำหนดค่าได้และอาจแตกต่างจาก HTTP origin ได้ วิธีนี้มีประโยชน์เมื่อคุณต้องการใช้ Vite dev server ภายในเครื่อง แต่ Gateway ทำงานอยู่ที่อื่น

  • เริ่ม UI dev server

    bash
    pnpm ui:dev
  • เปิดด้วย gatewayUrl

    text
    http://localhost:5173/?gatewayUrl=ws%3A%2F%2F<gateway-host>%3A18789

    การยืนยันตัวตนครั้งเดียวแบบตัวเลือก (หากจำเป็น):

    text
    http://localhost:5173/?gatewayUrl=wss%3A%2F%2F<gateway-host>%3A18789#token=<gateway-token>
  • หมายเหตุ
    • gatewayUrl จะถูกเก็บไว้ใน localStorage หลังจากโหลดและถูกลบออกจาก URL
    • หากคุณส่ง endpoint ws:// หรือ wss:// แบบเต็มผ่าน gatewayUrl ให้ URL-encode ค่า gatewayUrl เพื่อให้เบราว์เซอร์แยกวิเคราะห์ query string ได้อย่างถูกต้อง
    • ควรส่ง token ผ่าน fragment ของ URL (#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 แบบเต็ม) การโหลด LAN/Tailnet ส่วนตัวแบบ same-origin จาก loopback, RFC1918/link-local, .local, .ts.net หรือโฮสต์ Tailscale CGNAT จะยอมรับได้โดยไม่ต้องเปิดใช้ Host-header fallback
    • การเริ่มต้น Gateway อาจ seed origin ภายในเครื่อง เช่น http://localhost:<port> และ http://127.0.0.1:<port> จาก bind และ port ของ runtime ที่มีผล แต่ origin ของเบราว์เซอร์ระยะไกลยังต้องมีรายการที่ระบุอย่างชัดเจน
    • ห้ามใช้ gateway.controlUi.allowedOrigins: ["*"] ยกเว้นสำหรับการทดสอบภายในเครื่องที่ควบคุมอย่างเข้มงวด หมายถึงอนุญาต browser origin ใดก็ได้ ไม่ใช่ "จับคู่กับ host ใดก็ตามที่ฉันใช้อยู่"
    • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true เปิดใช้โหมด Host-header origin fallback แต่เป็นโหมดความปลอดภัยที่อันตราย

    ตัวอย่าง:

    json5
    {  gateway: {    controlUi: {      allowedOrigins: ["http://localhost:5173"],    },  },}

    รายละเอียดการตั้งค่าการเข้าถึงระยะไกล: การเข้าถึงระยะไกล

    ที่เกี่ยวข้อง

    • Dashboard — dashboard ของ Gateway
    • Health Checks — การเฝ้าระวังสุขภาพของ Gateway
    • TUI — อินเทอร์เฟซผู้ใช้ผ่านเทอร์มินัล
    • WebChat — อินเทอร์เฟซแชตบนเบราว์เซอร์
    Was this useful?
    On this page

    On this page