Web interfaces

เว็บแชต

Status: UI แชต SwiftUI บน macOS/iOS สื่อสารโดยตรงกับ Gateway WebSocket

คืออะไร

  • UI แชตแบบเนทีฟสำหรับ Gateway (ไม่มีเบราว์เซอร์ฝังตัวและไม่มีเซิร์ฟเวอร์สแตติกภายในเครื่อง)
  • ใช้เซสชันและกฎการกำหนดเส้นทางเดียวกับช่องทางอื่น
  • การกำหนดเส้นทางแบบกำหนดแน่นอน: การตอบกลับจะกลับไปยัง WebChat เสมอ

เริ่มต้นอย่างรวดเร็ว

  1. เริ่ม Gateway
  2. เปิด WebChat UI (แอป macOS/iOS) หรือแท็บแชตของ Control UI
  3. ตรวจสอบให้แน่ใจว่ามีการกำหนดค่าพาธยืนยันตัวตน 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: โฮสต์/พอร์ต WebSocket
  • gateway.auth.mode, gateway.auth.token, gateway.auth.password: การยืนยันตัวตน WebSocket แบบ shared-secret
  • gateway.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.*: การจัดเก็บเซสชันและค่าเริ่มต้นของคีย์หลัก

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