Web interfaces
เว็บแชต
Status: UI แชต SwiftUI บน macOS/iOS สื่อสารโดยตรงกับ Gateway WebSocket
คืออะไร
- UI แชตแบบเนทีฟสำหรับ Gateway (ไม่มีเบราว์เซอร์ฝังตัวและไม่มีเซิร์ฟเวอร์สแตติกภายในเครื่อง)
- ใช้เซสชันและกฎการกำหนดเส้นทางเดียวกับช่องทางอื่น
- การกำหนดเส้นทางแบบกำหนดแน่นอน: การตอบกลับจะกลับไปยัง WebChat เสมอ
เริ่มต้นอย่างรวดเร็ว
- เริ่ม Gateway
- เปิด WebChat UI (แอป macOS/iOS) หรือแท็บแชตของ Control UI
- ตรวจสอบให้แน่ใจว่ามีการกำหนดค่าพาธยืนยันตัวตน Gateway ที่ถูกต้อง (ค่าเริ่มต้นคือ shared-secret, แม้บน loopback)
วิธีทำงาน (พฤติกรรม)
- UI เชื่อมต่อกับ Gateway WebSocket และใช้
chat.history,chat.sendและchat.inject chat.historyถูกจำกัดขอบเขตเพื่อความเสถียร: Gateway อาจตัดฟิลด์ข้อความยาว ละเว้นเมทาดาทาหนัก และแทนที่รายการที่มีขนาดเกินด้วย[chat.history omitted: message too large]chat.historyติดตามสาขาทรานสคริปต์ที่ใช้งานอยู่สำหรับไฟล์เซสชันแบบ append-only สมัยใหม่ ดังนั้นสาขา rewrite ที่ถูกละทิ้งและสำเนาพรอมป์ที่ถูกแทนที่จะไม่ถูกแสดงใน WebChat- รายการ Compaction แสดงเป็นตัวแบ่งประวัติที่ถูกย่ออย่างชัดเจน ตัวแบ่งอธิบายว่าเทิร์นก่อนหน้าถูกเก็บรักษาไว้ในเช็คพอยต์ และลิงก์ไปยังตัวควบคุมเช็คพอยต์ของ Sessions ซึ่งผู้ปฏิบัติงานสามารถแตกสาขาหรือกู้คืนมุมมองก่อน Compaction ได้เมื่อสิทธิ์อนุญาต
- Control UI จดจำ Gateway
sessionIdเบื้องหลังที่ส่งกลับโดยchat.historyและรวมค่าไว้ในการเรียกchat.sendต่อเนื่อง ดังนั้นการเชื่อมต่อใหม่และการรีเฟรชหน้าจะดำเนินบทสนทนาที่จัดเก็บไว้เดิมต่อ เว้นแต่ผู้ใช้จะเริ่มหรือรีเซ็ตเซสชัน - Control UI รวมการส่งที่กำลังดำเนินอยู่ซ้ำสำหรับเซสชัน ข้อความ และไฟล์แนบเดียวกันก่อนสร้าง id การรัน
chat.sendใหม่; Gateway ยังคงลดคำขอซ้ำที่ใช้คีย์ idempotency เดียวกัน - ไฟล์เริ่มต้นของเวิร์กสเปซและคำสั่ง
BOOTSTRAP.mdที่รอดำเนินการจะถูกส่งผ่าน Project Context ในพรอมป์ระบบของเอเจนต์ ไม่ได้คัดลอกเข้าไปในข้อความผู้ใช้ WebChat การตัด bootstrap เพิ่มเพียงประกาศกู้คืนแบบกระชับในพรอมป์ระบบ; จำนวนโดยละเอียดและปุ่มปรับแต่งการกำหนดค่ายังคงอยู่บนพื้นผิววินิจฉัย chat.historyยังถูกปรับให้เป็นมาตรฐานสำหรับการแสดงผลด้วย: บริบท OpenClaw เฉพาะรันไทม์, ตัวห่อ envelope ขาเข้า, แท็กคำสั่งการส่งมอบแบบอินไลน์ เช่น[[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 ที่รั่วไหล จะถูกลบออกจากข้อความที่มองเห็นได้, และรายการผู้ช่วยที่ข้อความที่มองเห็นได้ทั้งหมดเป็นเพียงโทเค็นเงียบที่ตรงเป๊ะNO_REPLY/no_replyจะถูกละเว้น- เพย์โหลดตอบกลับที่ถูกทำเครื่องหมายเป็นการให้เหตุผล (
isReasoning: true) จะถูกตัดออกจากเนื้อหาผู้ช่วยของ WebChat, ข้อความ replay ทรานสคริปต์ และบล็อกเนื้อหาเสียง ดังนั้นเพย์โหลดที่เป็นการคิดเท่านั้นจะไม่ปรากฏเป็นข้อความผู้ช่วยที่มองเห็นได้หรือเสียงที่เล่นได้ chat.injectเพิ่มบันทึกผู้ช่วยต่อท้ายทรานสคริปต์โดยตรงและกระจายไปยัง UI (ไม่มีการรันเอเจนต์)- การรันที่ถูกยกเลิกสามารถคงเอาต์พุตผู้ช่วยบางส่วนให้มองเห็นได้ใน UI
- Gateway เก็บข้อความผู้ช่วยบางส่วนที่ถูกยกเลิกไว้ในประวัติทรานสคริปต์เมื่อมีเอาต์พุตในบัฟเฟอร์ และทำเครื่องหมายรายการเหล่านั้นด้วยเมทาดาทาการยกเลิก
- ประวัติจะถูกดึงจาก Gateway เสมอ (ไม่มีการเฝ้าดูไฟล์ภายในเครื่อง)
- หากเข้าถึง Gateway ไม่ได้ WebChat จะเป็นแบบอ่านอย่างเดียว
ทรานสคริปต์และโมเดลการส่งมอบ
WebChat มีพาธข้อมูลแยกกันสองพาธ:
- ไฟล์ JSONL ของเซสชันคือทรานสคริปต์โมเดล/รันไทม์แบบถาวร สำหรับการรันเอเจนต์ปกติ Pi จะเก็บข้อความ
user,assistantและtoolResultที่โมเดลมองเห็นได้ผ่านตัวจัดการเซสชันของตน WebChat ไม่เขียนข้อความการส่งมอบ สถานะ หรือข้อความช่วยเหลือใดๆ เข้าไปในทรานสคริปต์นั้นโดยพลการ - เหตุการณ์ Gateway
ReplyPayloadคือภาพฉายการส่งมอบสด เหตุการณ์เหล่านี้สามารถถูกปรับให้เป็นมาตรฐานสำหรับการแสดง WebChat/ช่องทาง, การสตรีมบล็อก, แท็กคำสั่ง, การฝังสื่อ, แฟล็ก TTS/เสียง และพฤติกรรม fallback ของ UI เหตุการณ์เหล่านี้ไม่ใช่บันทึกเซสชันหลักโดยตัวมันเอง - WebChat ฉีดรายการทรานสคริปต์ผู้ช่วยเฉพาะเมื่อ Gateway เป็นเจ้าของข้อความที่แสดงนอกเทิร์นผู้ช่วย Pi ปกติ:
chat.inject, คำตอบคำสั่งที่ไม่ใช่เอเจนต์, เอาต์พุตบางส่วนที่ถูกยกเลิก และส่วนเสริมทรานสคริปต์สื่อที่ WebChat จัดการ chat.historyอ่านทรานสคริปต์เซสชันที่จัดเก็บไว้และใช้ภาพฉายการแสดงผลของ WebChat หากข้อความผู้ช่วยสดปรากฏระหว่างการรันแต่หายไปหลังโหลดประวัติใหม่ ให้ตรวจสอบก่อนว่า JSONL ดิบมีข้อความผู้ช่วยหรือไม่ จากนั้นตรวจสอบว่าโปรเจกชันchat.historyลบข้อความนั้นออกหรือไม่ แล้วจึงตรวจสอบว่าการรวม optimistic-tail ของ Control UI แทนที่สถานะการส่งมอบภายในเครื่องด้วยสแนปช็อตที่คงอยู่หรือไม่
คำตอบสุดท้ายของการรันเอเจนต์ปกติควรคงอยู่ถาวรเพราะ Pi เขียน message_end ของผู้ช่วย fallback ใดๆ ที่สะท้อนเพย์โหลดสุดท้ายที่ส่งมอบเข้าไปในทรานสคริปต์ต้องหลีกเลี่ยงการทำซ้ำเทิร์นผู้ช่วยที่ Pi เขียนไว้แล้วก่อน
แผงเครื่องมือเอเจนต์ของ Control UI
- แผง Tools ของ Control UI
/agentsมีสองมุมมองแยกกัน:- พร้อมใช้งานตอนนี้ ใช้
tools.effective(sessionKey=...)และแสดงสิ่งที่เซสชันปัจจุบัน ใช้งานได้จริงในรันไทม์ รวมถึงเครื่องมือหลัก, Plugin และเครื่องมือที่ช่องทางเป็นเจ้าของ - การกำหนดค่าเครื่องมือ ใช้
tools.catalogและยังคงเน้นที่โปรไฟล์ การ override และ ความหมายของแคตตาล็อก
- พร้อมใช้งานตอนนี้ ใช้
- ความพร้อมใช้งานในรันไทม์ถูกกำหนดขอบเขตตามเซสชัน การสลับเซสชันบนเอเจนต์เดียวกันสามารถเปลี่ยนรายการ พร้อมใช้งานตอนนี้ ได้
- ตัวแก้ไขการกำหนดค่าไม่ได้บ่งบอกถึงความพร้อมใช้งานในรันไทม์; การเข้าถึงที่มีผลยังคงเป็นไปตามลำดับความสำคัญของนโยบาย
(
allow/deny, override ต่อเอเจนต์และต่อผู้ให้บริการ/ช่องทาง)
การใช้งานระยะไกล
- โหมดระยะไกล tunneling Gateway WebSocket ผ่าน SSH/Tailscale
- คุณไม่จำเป็นต้องรันเซิร์ฟเวอร์ WebChat แยกต่างหาก
อ้างอิงการกำหนดค่า (WebChat)
การกำหนดค่าแบบเต็ม: การกำหนดค่า
ตัวเลือก WebChat:
gateway.webchat.chatHistoryMaxChars: จำนวนอักขระสูงสุดสำหรับฟิลด์ข้อความในคำตอบchat.historyเมื่อรายการทรานสคริปต์เกินขีดจำกัดนี้ Gateway จะตัดฟิลด์ข้อความยาวและอาจแทนที่ข้อความที่มีขนาดเกินด้วย placeholder ลูกค้ายังสามารถส่งmaxCharsต่อคำขอเพื่อ override ค่าเริ่มต้นนี้สำหรับการเรียกchat.historyครั้งเดียวได้
ตัวเลือกส่วนกลางที่เกี่ยวข้อง:
gateway.port,gateway.bind: โฮสต์/พอร์ต WebSocketgateway.auth.mode,gateway.auth.token,gateway.auth.password: การยืนยันตัวตน WebSocket แบบ shared-secretgateway.auth.allowTailscale: แท็บแชต Control UI ในเบราว์เซอร์สามารถใช้ส่วนหัวตัวตน Tailscale Serve ได้เมื่อเปิดใช้งานgateway.auth.mode: "trusted-proxy": การยืนยันตัวตน reverse-proxy สำหรับลูกค้าเบราว์เซอร์ที่อยู่หลังแหล่งพร็อกซี ที่ไม่ใช่ loopback และรับรู้ตัวตน (ดู Trusted Proxy Auth)gateway.remote.url,gateway.remote.token,gateway.remote.password: เป้าหมาย Gateway ระยะไกลsession.*: การจัดเก็บเซสชันและค่าเริ่มต้นของคีย์หลัก