Web interfaces

สถาปัตยกรรมแดชบอร์ด

วิสัยทัศน์

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

หลักการ:

  • บอร์ดเป็นอีกหน้าหนึ่งของเซสชัน ไม่ใช่ออบเจ็กต์ใหม่ ทุกเซสชัน (เธรด) มีสองหน้า ได้แก่ บันทึกบทสนทนาและบอร์ด เซสชันที่ไม่มีวิดเจ็ตปักหมุด จะเป็นแชตธรรมดา เมื่อปักหมุดวิดเจ็ตหนึ่งรายการ บอร์ดก็จะมีอยู่ บอร์ดสืบทอด ข้อมูลระบุตัวตนของเซสชัน ความเป็นเจ้าของโดยเอเจนต์ การตั้งชื่อ การปักหมุด และวงจรชีวิต ไม่มี dashboard_create ไม่มีรีจิสทรีบอร์ด และไม่มีโมเดล ACL แยกต่างหาก
  • ความเท่าเทียมของเอเจนต์ ทุกสิ่งที่ผู้ใช้ทำบนบอร์ดได้ เอเจนต์ก็ทำได้ ด้วยเครื่องมือ ได้แก่ เพิ่ม/อัปเดต/นำวิดเจ็ตออก จัดเรียงวิดเจ็ต จัดการแท็บ สลับ แท็บที่มองเห็น และเชื่อมติดหรือซ่อนแชต
  • เป็นส่วนเนทีฟ ไม่ใช่การฝัง บอร์ดเป็นคอมโพเนนต์ Lit ในเชลล์ Control UI (ใช้ระบบการออกแบบเดียวกับส่วนอื่นของแอป) เฉพาะ เนื้อหา ของวิดเจ็ตเท่านั้นที่ ถูกแยกไว้ใน iframe ไม่มีแถบ URL และไม่มีส่วนควบคุมของเบราว์เซอร์
  • พื้นผิวสำหรับเอเจนต์ขนาดเล็ก วิดเจ็ตได้รับการอ้างถึงด้วยชื่อที่คงที่และอัปเดต ณ ตำแหน่งเดิม เลย์เอาต์เป็นกริดแบบยืดหยุ่นที่จัดพื้นที่ให้กระชับโดยอัตโนมัติ เอเจนต์ระบุขนาดและ จุดยึดเท่านั้น ไม่ระบุพิกเซลหรือพิกัด
  • ใช้ความสามารถแทนความไว้วางใจ โค้ดวิดเจ็ตเป็น HTML/JS ใด ๆ ที่เอเจนต์เขียนขึ้น และทำงานในแซนด์บ็อกซ์ที่เข้มงวด การเข้าถึง (ข้อมูล Gateway การดำเนินการ เครือข่าย) มีได้เฉพาะผ่าน แมนิเฟสต์ความสามารถที่ประกาศไว้และได้รับอนุญาตจากผู้ดำเนินการ

แนวคิด

แนวคิด คำจำกัดความ
เซสชัน (เธรด) เซสชัน Gateway ที่มีอยู่ ซึ่งใช้ sessionKey ที่คงที่เป็นคีย์ และมีเอเจนต์เป็นเจ้าของ
บอร์ด หน้าวิดเจ็ตของหนึ่งเซสชัน มีอยู่ก็ต่อเมื่อเซสชันมีวิดเจ็ต/แท็บ และยังคงอยู่หลัง /new//reset (เชื่อมโยงกับ sessionKey ไม่ใช่บันทึกบทสนทนา)
แท็บ หน้าสำหรับนำเสนอของบอร์ด ซึ่งกำหนดวิดเจ็ต การจัดเรียง และสถานะการเชื่อมติดแชต (left/right/bottom/hidden) บอร์ดเริ่มต้นด้วยแท็บโดยนัยหนึ่งแท็บ
วิดเจ็ต โปรแกรม HTML/JS ที่มีชื่อและทำงานในแซนด์บ็อกซ์ ซึ่งเซสชันเป็นเจ้าของ อ้างถึงด้วย sessionKey + name และอัปเดต ณ ตำแหน่งเดิมตามชื่อ
แมนิเฟสต์ความสามารถ การประกาศขอบเขตการเข้าถึงแยกตามวิดเจ็ต ได้แก่ data (การผูกข้อมูลแบบอ่าน), actions (กริยาที่อยู่ในรายการอนุญาต), prompt (ส่งไปยังเซสชัน), net (ต้นทางที่อนุญาต)
ปักหมุด (วิดเจ็ต) การย้ายวิดเจ็ตจากบันทึกบทสนทนาไปยังบอร์ดของเซสชัน (ผ่านส่วนควบคุมสำหรับผู้ใช้หรืออาร์กิวเมนต์เครื่องมือของเอเจนต์) การเลิกปักหมุดจะนำวิดเจ็ตออกจากบอร์ด
ปักหมุด (เซสชัน) การปักหมุดเซสชันในแถบด้านข้างที่มีอยู่ เซสชันที่ปักหมุดและมีบอร์ดจะเปิดที่หน้าบอร์ด

ขั้นตอนการใช้งาน UX

  • การยกระดับ: เอเจนต์เรียก show_widget ในแชตใดก็ได้ → วิดเจ็ตแสดงแบบอินไลน์ ในบันทึกบทสนทนาเหมือนในปัจจุบันทุกประการ → เมื่อวางเมาส์เหนือจะแสดง ปักหมุดไปยังแดชบอร์ด → วิดเจ็ต ปรากฏบนบอร์ดของเซสชัน เอเจนต์สามารถส่ง pin: true เพื่อทำเช่นเดียวกัน
  • มุมมองบอร์ด: เซสชันที่มีบอร์ดจะมีตัวสลับหน้า (แชต / แดชบอร์ด) มุมมองบอร์ด = แถบแท็บ (เฉพาะเมื่อมี >1 แท็บ) + กริดแบบยืดหยุ่น + บานหน้าต่างแชตที่เชื่อมติด แชตที่เชื่อมติดสามารถปรับขนาด ย้ายตำแหน่ง (ซ้าย/ขวา/ล่าง) และยุบได้เหมือน แถบด้านข้างทุกประการ ระบบจะจดจำสถานะการเชื่อมติดแยกตามแท็บ
  • การลาก: ผู้ใช้ลากวิดเจ็ต กริดจะจัดพื้นที่ให้กระชับโดยอัตโนมัติ (วิดเจ็ตเลื่อนขึ้น และวิดเจ็ตข้างเคียง จัดเรียงใหม่) การปรับขนาดด้วยจุดจับจะยึดตามระดับขนาดที่กำหนด ไม่มีการวางตามพิกเซล — สำหรับทุกคน
  • คำเตือนการรีเซ็ต: /new / /reset ในเซสชันที่มีบอร์ดจะขอ การยืนยันใน UI เว็บ ("บริบทจะถูกรีเซ็ต แต่แดชบอร์ดยังคงอยู่") และเก็บ บอร์ดไว้
  • แถบด้านข้าง: เซสชันที่ปักหมุดจะแสดงหน้าบอร์ดเมื่อมีบอร์ด บอร์ดของเซสชันหน้าแรกคือ "แดชบอร์ดเอเจนต์" เริ่มต้น
  • การโต้ตอบ (สามระดับ ดูด้านล่าง): เหตุการณ์สถานะแบบเงียบ การส่ง พรอมป์ที่มองเห็นได้ และทริกเกอร์ระบบอัตโนมัติ

ระดับการโต้ตอบ

  1. เหตุการณ์สถานะ (ค่าเริ่มต้น) การโต้ตอบกับ UI ของวิดเจ็ตที่โมเดลควรรับรู้ แต่ไม่ควรตอบกลับ bridge.emitState({...}) จะผนวก ประกาศเซสชันแบบมีโครงสร้าง (ใช้กลไกเดียวกับประกาศกิจกรรมกลุ่ม) ระบบจะไม่ เริ่มรอบการทำงานของเอเจนต์ โมเดลจะเห็นประกาศที่สะสมไว้ในการทำงานครั้งถัดไป
  2. พรอมป์ (การสนทนาโดยชัดแจ้ง) bridge.sendPrompt(text) — ต้องมีการ กระตุ้นโดยผู้ใช้ ส่งข้อความผู้ใช้ที่มองเห็นได้เข้าสู่เซสชัน (แชตที่เชื่อมติด จะแสดงข้อความนั้น) มีการจำกัดอัตรา การส่งแต่ละครั้งต้องได้รับการยืนยันจากผู้ใช้ เว้นแต่วิดเจ็ตจะมี สิทธิ์ความสามารถ prompt
  3. ระบบอัตโนมัติ bridge.runAction(name, args) — เรียกใช้การดำเนินการที่ประกาศใน แมนิเฟสต์ ชุดกริยาเริ่มต้น ได้แก่ cron.trigger (เรียกใช้งาน Cron ที่มีอยู่ทันที) และ binding.refresh งาน Cron ทำงานอยู่แล้วในเซสชันการทำงานแบบแยกที่มองเห็นได้ และสามารถใช้โมเดลที่มีต้นทุนต่ำกว่า นี่คือเส้นทางที่ "โมเดลขนาดเล็กขับเคลื่อนวิดเจ็ต" ไม่มีเซสชันที่ซ่อนอยู่ไม่ว่าที่ใด

โมเดลวิดเจ็ตและการโฮสต์

HTML/JS ของวิดเจ็ตเขียนโดยเอเจนต์ (โดยทั่วไปผ่าน show_widget) ถูกห่อ ด้วยเชลล์เอกสารมาตรฐาน (เมตา CSP ตัวรายงานขนาด และบูตสแตรปบริดจ์) และ แสดงผลใน <iframe sandbox="allow-scripts"> (ไม่ใช้ allow-same-origin เด็ดขาด)

  • วิดเจ็ตแบบอินไลน์ (บันทึกบทสนทนา) ยังคงใช้ไปป์ไลน์เอกสารแคนวาสปัจจุบัน: เขียนไว้ใต้ไดเรกทอรีสถานะ ให้บริการโดย Gateway ล้างตามขอบเขต และไม่ต้อง อนุมัติ (เนื่องจากไม่มีความสามารถโดยโครงสร้างอยู่แล้ว — การส่งพรอมป์ต้องได้รับการยืนยันจากผู้ใช้)
  • วิดเจ็ตบอร์ด เป็นสถานะเซสชัน: ไบต์อยู่ในฐานข้อมูล SQLite ของเอเจนต์ ที่เป็นเจ้าของ (board_widgets) และให้บริการผ่านเส้นทาง Gateway หลัก (/__openclaw__/board/<agentId>/<sessionKey>/<name>/) ที่อ่านฐานข้อมูล การปักหมุดวิดเจ็ตจากบันทึกบทสนทนาจะคัดลอกไบต์ ขีดจำกัด: 256 KB ต่อวิดเจ็ต และ 48 วิดเจ็ตต่อบอร์ด
  • อัปเดต ณ ตำแหน่งเดิม: การส่งวิดเจ็ตที่มี name เดิมอีกครั้งจะแทนที่ ไบต์ เพิ่มค่า revision กระจาย board.changed และมุมมองสดจะโหลด เฉพาะ iframe นั้นใหม่
  • การตรึงไบต์: ความสามารถที่ได้รับอนุญาตจะผูกกับ sha256 ของไบต์ วิดเจ็ต การเปลี่ยนไบต์จะคงสิทธิ์ data/net/actions ไว้เฉพาะเมื่อรีวิชันใหม่ ประกาศส่วนย่อยของแมนิเฟสต์ที่ได้รับอนุญาต แมนิเฟสต์ที่ขยายขอบเขตจะ ขออนุมัติจากผู้ดำเนินการอีกครั้ง

วิดเจ็ตโฮสต์เนื้อหา ส่วนแอป MCP เป็นเนื้อหาชนิดหนึ่ง

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

  • html — เอเจนต์เขียนผ่าน show_widget โดยเก็บไบต์ไว้ในพื้นที่จัดเก็บของบอร์ด
  • mcp-app — มุมมองแอป MCP ของบุคคลที่สาม (ทรัพยากร ui:// จากเซิร์ฟเวอร์ ที่กำหนดค่าไว้) ซึ่งโฮสต์อยู่ภายในเซลล์วิดเจ็ต

แอป MCP ไม่ได้กำหนดโมเดลวิดเจ็ต แต่วิดเจ็ตได้รับความสามารถในการโฮสต์ แอปเหล่านี้ ข้อมูลระบุตัวตน ตำแหน่ง การปักหมุด สิทธิ์ และ API สำหรับผู้เขียนยังคง เป็นของ OpenClaw ดังนั้นโค้ด show_widget จึงยังสั้นเท่าปัจจุบันและไม่ จำเป็นต้องทราบว่าข้อกำหนด MCP Apps มีอยู่

โครงสร้างพื้นฐานที่ใช้ร่วมกันด้านล่าง (นี่คือจุดที่เกิดการลดความซับซ้อน):

  • โฮสต์แซนด์บ็อกซ์หนึ่งระบบ วิดเจ็ต html แสดงผลผ่านไปป์ไลน์ที่เสริมความปลอดภัยเดียวกับ ที่แอป MCP ใช้เมื่อเปิดตัว (iframe ซ้อนสองชั้นบนต้นทางแซนด์บ็อกซ์เฉพาะ CSP แยกตามวิดเจ็ตที่ประกาศไว้และถอดรหัสแบบปิดเมื่อผิดพลาด) แทนโฮสต์ iframe เฉพาะกิจระบบที่สอง พร็อกซีรับ HTML เป็นค่า ดังนั้นเนื้อหาในเครื่องจึง เป็นกรณีปกติโดยธรรมชาติ
  • โมเดลการให้สิทธิ์หนึ่งระบบ ขอบเขตการเข้าถึงของวิดเจ็ตคือรายการอนุญาตที่ได้รับสิทธิ์ ไม่ว่าจะเป็นชนิดใด: สำหรับวิดเจ็ต html คือเครื่องมือโฮสต์ ส่วนวิดเจ็ต mcp-app คือ เครื่องมือของเซิร์ฟเวอร์ที่แอปมองเห็นได้ (ผ่านกลไก allowedAppToolNames ที่มีอยู่ โดยทำให้คงทนแยกตามวิดเจ็ตแทนที่จะแยกตามรอบการสร้าง)
  • เครื่องมือโฮสต์สำหรับวิดเจ็ต html (เปิดให้ใช้ผ่านบริดจ์วิดเจ็ตและตรวจสอบ กับสิทธิ์ที่ได้รับ):
    • openclaw.prompt.send — ระดับ 2 กำหนดเส้นทางผ่านตัวเขียนข้อความที่มองเห็นได้ และต้องได้รับการยืนยันจากผู้ใช้ เว้นแต่จะได้รับอนุญาต
    • openclaw.state.emit — ประกาศเซสชันระดับ 1 (รวมรายการและจำกัดขนาด)
    • openclaw.data.read — การผูกข้อมูลแบบอ่านอย่างเดียวที่กำหนดพารามิเตอร์ได้ (ชุด RPC แบบอ่านซึ่งอยู่ในรายการอนุญาตที่มีอยู่) โดย Gateway เป็นผู้แก้ค่า
    • openclaw.cron.trigger — ระบบอัตโนมัติระดับ 3
  • net = CSP การเข้าถึงเครือข่ายใช้การประกาศ CSP แยกตามวิดเจ็ต ที่เปิดใช้งานแล้ว (connect-src ต้นทาง) วิดเจ็ตสภาพอากาศที่อัปเดตตัวเอง ดึงข้อมูล API โดยตรงจากแซนด์บ็อกซ์โดยไม่เกี่ยวข้องกับ Gateway
  • สิทธิ์ วิดเจ็ตที่ไม่ประกาศสิ่งใดจะแสดงผลทันที (ทำงานในแซนด์บ็อกซ์ default-src 'none' และการส่งพรอมป์แต่ละครั้งต้องได้รับการยืนยัน) ซึ่งมีระดับความไว้วางใจเดียวกับ วิดเจ็ตแชตแบบอินไลน์ในปัจจุบัน เครื่องมือ/ต้นทางที่ประกาศไว้จะทำให้วิดเจ็ตอยู่ใน pending บนบอร์ด: การ์ดตัวยึดจะแสดงรายการเหล่านั้นด้วยภาษาที่มนุษย์อ่านเข้าใจ พร้อม อนุญาต/ปฏิเสธ ด้วยการแตะครั้งเดียว สิทธิ์แยกตามชื่อวิดเจ็ต สำหรับวิดเจ็ต html สิทธิ์จะถูกตรึงตามไบต์ (sha256) และไบต์ที่เปลี่ยนไปจะคงสิทธิ์ไว้เฉพาะเมื่อ การประกาศมีขอบเขตแคบลง
  • ชิมสำหรับผู้เขียน ตัวห่อเอกสารจะแทรก window.openclaw.sendPrompt/emitState/read/call เป็น API ที่คงที่สำหรับผู้เขียน ไม่ว่าการขนส่งเบื้องหลังจะเป็นช่องทางของเราหรือ AppBridge ก็เป็น รายละเอียดภายในที่ผู้เขียนวิดเจ็ตจะไม่เห็น การรายงานขนาดและโทเค็นธีม ใช้บริดจ์เดียวกัน

การแสดงบันทึกบทสนทนา: การ์ดวิดเจ็ตหนึ่งใบ

การแสดงแบบอินไลน์รวมเป็นหนึ่งบนองค์ประกอบพื้นฐานของวิดเจ็ต เมื่อผลลัพธ์เครื่องมือมี UI — เอาต์พุต show_widget หรือผลลัพธ์เครื่องมือ MCP ที่มีทรัพยากรแอป — ระบบจะ สร้าง วิดเจ็ตชั่วคราวที่ตั้งชื่ออัตโนมัติ (จำกัดขอบเขตตามเซสชันและถูกล้างออก) และ บันทึกบทสนทนาจะแสดงการ์ดวิดเจ็ตใบเดียวที่แจกจ่ายตามชนิดเนื้อหา การแสดงแอป MCP อัตโนมัติยังคงเป็นไปตามที่ข้อกำหนดคาดหวังทุกประการ (โมเดลไม่ต้องทำงานเพิ่ม) เพียงแต่เบื้องล่าง เป็น วิดเจ็ต การทำเช่นนี้จะลบกรณีพิเศษ mcpApp แบบขนานในการแสดงผลแชต (การจำกัดตามพื้นผิวและการขจัดรายการซ้ำแยกต่างหาก) ทำให้ UI แบบอินไลน์ทั้งหมดมีส่วนควบคุมการปักหมุดเดียวกัน และทำให้รีจิสทรีวิดเจ็ตเป็นเส้นทางหลัก สำหรับเปิดอีกครั้ง (การสร้างคืนจากการสแกนบันทึกบทสนทนายังคงเป็นทางเลือกสำรองสำหรับประวัติ ที่ไม่เคยปักหมุด) โฮสต์แบบสแตนด์อโลนที่อ่านอย่างเดียวและใช้ตั๋วมีส่วนทับซ้อนกับบอร์ดในฐานะ พื้นผิวถาวรสำหรับเปิดอีกครั้ง — เป็นตัวเลือกสำหรับการรวมระบบที่ต้องประเมินใน T6 ไม่ใช่ ข้อสันนิษฐาน

การจัดองค์ประกอบ: v1 ใช้การวางติดกันในกริด (วิดเจ็ตส่วนควบคุมของเอเจนต์อยู่ถัดจากวิดเจ็ตแอปบน แท็บเดียวกัน) v2 เพิ่ม สล็อตแอปที่โฮสต์จัดการ — HTML ของวิดเจ็ตเอเจนต์ประกาศ บริเวณสล็อต และโฮสต์ประกอบมุมมองแอปจริงเป็นแซนด์บ็อกซ์ระดับเดียวกัน แอปจะไม่แสดงผลภายใน iframe ของเอเจนต์ เพราะการซ้อนจะทำลายข้อมูลระบุตัวตน ของบริดจ์และเปิดทางให้เกิดการซ้อนทับ/คลิกแจ็ก UI แอปที่ได้รับสิทธิ์ ดังนั้นสล็อตจึงเป็น สัญญาเลย์เอาต์ ไม่ใช่การฝัง

วิดเจ็ตจากเซิร์ฟเวอร์ (แอป MCP ที่ปักหมุด)

เมื่อใช้โฮสต์แบบรวม การปักหมุดแอป MCP ของบุคคลที่สามเป็นเพียงวิดเจ็ตที่ ดึงเนื้อหาจากเซิร์ฟเวอร์แทนการจัดเก็บ: board_widgets จะเก็บ ตัวอธิบาย (serverName, toolName, uiResourceUri, ต้นทาง toolCallId + sessionKey) แทนไบต์ HTML และบอร์ดจะออก สัญญาเช่ามุมมองใหม่เมื่อพ้น TTL 10 นาทีของรอบแชต (ดึงทรัพยากร ui:// ใหม่เมื่อข้อมูลล้าสมัย) มุมมองแอป MCP แบบอินไลน์ในแชตมีตัวเลือก ปักหมุดไปยังแดชบอร์ด เช่นเดียวกับวิดเจ็ตของเอเจนต์ มุมมองที่เปิดใหม่เป็นแบบอ่านอย่างเดียวในขณะนี้ตามการออกแบบ แอปที่ปักหมุดซึ่งควรโต้ตอบได้ต่อเนื่องจะได้รับสิทธิ์ถาวรสำหรับเครื่องมือที่แอปมองเห็นได้ของเซิร์ฟเวอร์ (แสดงรายการอนุญาตอย่างชัดเจนแก่ผู้ดำเนินการขณะปักหมุด) โดยแยกจาก รอบการออกสิทธิ์ แอปที่ปักหมุดแต่ไม่ได้รับสิทธิ์จะยังคงเป็นแบบอ่านอย่างเดียว — แต่ยังมีประโยชน์สำหรับ แดชบอร์ดแสดงผล v1 ปักหมุดไปยังบอร์ดของเซสชันต้นทาง การปักหมุดข้ามเซสชัน ต้องใช้ตัวกลางสัญญาเช่าและต้องรอก่อน ประสานงานกับ PR #109807 ที่เปิดอยู่ (ui/message การกำหนดเส้นทางคอมโพสเซอร์ การส่งต่อธีม/ขนาด)

เลย์เอาต์: กริดแบบยืดหยุ่น

12 คอลัมน์ ความสูงแถวคงที่ จัดให้กระชับอัตโนมัติ (เลื่อนขึ้นตามแรงโน้มถ่วง ดันหลบเมื่อ ลาก — ความหมายแบบ gridstack แต่พัฒนาขึ้นเอง; คณิตศาสตร์กริดยังคงบริสุทธิ์และ ไม่ขึ้นกับ DOM) สถานะเลย์เอาต์วิดเจ็ตต่อแท็บ: { name, w (1-12), h (rows) } รวมถึง ลำดับ คำศัพท์สำหรับเอเจนต์:

  • size: sm (3×3) · md (6×4) · lg (8×6) · xl (12×8) · full (แท็บวิดเจ็ตเดียว)
  • after: <widgetName> จุดยึดลำดับที่ไม่บังคับ; หากละไว้ = ต่อท้าย
  • ผู้ใช้ลาก/ปรับขนาดได้อย่างอิสระ; โมเดลลำดับ+ขนาดเดียวกันสามารถส่งไปกลับได้

โมเดลข้อมูล (DB ต่อเอเจนต์)

ตารางใหม่ใน agents/<agentId>/agent/openclaw-agent.sqlite (ต้องเพิ่มเวอร์ชันสคีมาของ DB เอเจนต์ — ต้องได้รับการอนุมัติจากผู้ดำเนินการ ก่อนรวมการเปลี่ยนแปลงนี้):

sql
CREATE TABLE board_tabs (  session_key TEXT NOT NULL,  tab_id      TEXT NOT NULL,           -- slug  title       TEXT NOT NULL,  position    INTEGER NOT NULL,  chat_dock   TEXT NOT NULL DEFAULT 'right',  -- left|right|bottom|hidden  created_by  TEXT NOT NULL,           -- 'user' | 'agent'  PRIMARY KEY (session_key, tab_id)) STRICT; CREATE TABLE board_widgets (  session_key  TEXT NOT NULL,  name         TEXT NOT NULL,          -- stable widget name  tab_id       TEXT NOT NULL,  title        TEXT,  html         BLOB NOT NULL,          -- wrapped document source  sha256       TEXT NOT NULL,  revision     INTEGER NOT NULL,  size_w       INTEGER NOT NULL,  size_h       INTEGER NOT NULL,  position     INTEGER NOT NULL,       -- order within tab (auto-compact input)  manifest     TEXT NOT NULL DEFAULT '{}',  -- capability manifest JSON  grant_state  TEXT NOT NULL DEFAULT 'none', -- none|pending|granted|rejected  granted_sha  TEXT,                   -- byte-frozen grant  created_by   TEXT NOT NULL,  created_at   INTEGER NOT NULL,  updated_at   INTEGER NOT NULL,  PRIMARY KEY (session_key, name)) STRICT;

การมีอยู่ของบอร์ด = มีแถวใดก็ตามสำหรับ sessionKey การลบเซสชันจะลบ แถวบอร์ดของเซสชันนั้น /new//reset จะไม่แตะต้องแถวเหล่านี้

พื้นผิวโปรโตคอล

RPC (ตารางเมธอดหลัก สคีมา typebox ใน gateway-protocol):

  • board.get { sessionKey } → แท็บ + เมทาดาทาวิดเจ็ต (ไม่มีไบต์) — operator.read
  • board.update { sessionKey, ops[] } — CRUD/จัดลำดับแท็บใหม่, ย้าย/ปรับขนาด/ ลบ/เลิกปักหมุดวิดเจ็ต, สถานะด็อก, โฟกัสแท็บ — operator.write
  • board.widget.put { sessionKey, name, html, manifest, placement }operator.write (เส้นทางเครื่องมือเอเจนต์และเส้นทางปักหมุด)
  • board.widget.grant { sessionKey, name, decision }operator.approvals
  • board.event { sessionKey, widget, payload } — รับเข้าเหตุการณ์สถานะระดับ 1 — operator.write

เหตุการณ์ (ใน EVENT_SCOPE_GUARDS, ขอบเขตการอ่าน):

  • board.changed { sessionKey, revision, widget? } — สถานะที่คงอยู่เปลี่ยนแปลง; UI ดึงข้อมูลใหม่ (และโหลด iframe หนึ่งรายการใหม่เมื่อมี widget)
  • board.command { sessionKey, command } — ควบคุม UI ชั่วคราว (เอเจนต์สลับ แท็บที่มองเห็นหรือสลับด็อกแชต) — รูปแบบ ui.command

ไบต์ของวิดเจ็ตให้บริการผ่านพื้นผิว HTTP ที่ผ่านการยืนยันตัวตน ไม่ใช่ซ็อกเก็ต

เครื่องมือเอเจนต์

มีเครื่องมือทั้งหมดสามรายการ (อยู่ในแกนหลัก ลงทะเบียนเสมอ; การเรนเดอร์ถูกควบคุมด้วย ความสามารถไคลเอนต์ inline-widgets เช่นเดียวกับปัจจุบัน):

  • show_widget { title, widget_code, name?, pin?, size?, tab?, after?, capabilities? } — สร้าง/อัปเดตตามชื่อ; pin วางรายการนั้นบนบอร์ด หากไม่มี name/pin จะทำงานเหมือนปัจจุบันทุกประการ (อินไลน์ ชั่วคราว)
  • dashboard { action, ... } — คำสั่งจัดการบอร์ด: read, tab_create, tab_update, tab_delete, tabs_reorder, widget_move, widget_remove, unpin, focus_tab, set_chat_dock
  • เครื่องมือ cron ที่มีอยู่ครอบคลุมระดับระบบอัตโนมัติแล้ว; ไม่ต้องมีเครื่องมือใหม่

คำอธิบายเครื่องมือสอนคำศัพท์เกี่ยวกับขนาด/จุดยึดและโมเดลระดับ เอเจนต์ จะได้รับแจ้งเหตุการณ์ระดับ 1 ของผู้ใช้ผ่านประกาศของเซสชัน เช่น [dashboard] user clicked "Refresh" on widget weather (tab main)

สิ่งที่รายการนี้เข้ามาแทนที่

  • ลบ extensions/workspaces ฟีเจอร์ทดลอง, enabledByDefault: false, ไม่เคยอยู่ในรุ่นเสถียร (ปรากฏครั้งแรกในรุ่นเบตา 2026.7.2) ไม่มี การย้ายข้อมูล; กฎ doctor จะลบ <stateDir>/workspaces/ ที่ตกค้างหากมี แนวคิดที่นำมาใช้: คณิตศาสตร์กริดบริสุทธิ์ โมเดลความปลอดภัยของบริดจ์ (การเริ่มต้นพอร์ต, การควบคุมการผูก, ขีดจำกัดอัตรา), การอนุมัติแบบตรึงไบต์
  • การโฮสต์วิดเจ็ตย้ายจาก extensions/canvas ไปยังแกนหลัก ที่เก็บเอกสารแคนวาส ตัวห่อเอกสาร การให้บริการ HTTP และเครื่องมือ show_widget จะกลายเป็นส่วนแกนหลัก (src/canvas/); Plugin จะเก็บเครื่องมือควบคุม node-canvas (canvas) และ A2UI ไว้ การประกาศ pluginSurfaceUrls["canvas"] และ เส้นทาง /__openclaw__/canvas เป็นสัญญาไคลเอนต์เนทีฟที่เผยแพร่แล้วและยังคง เสถียร เซสชัน Discord ยังคงใช้ตัวแปร show_widget ที่ Discord เป็นเจ้าของ
  • ไม่แตะต้อง WorkBoard (การผสานรวมเป็นโครงการติดตามผล)

สิ่งที่ไม่ใช่เป้าหมาย (โครงการนี้)

  • การแชร์บอร์ดหลายผู้ใช้/ACL (ในอนาคต; จะมาผ่านการแชร์เซสชัน)
  • การเรนเดอร์บอร์ดแบบเนทีฟบน macOS/iOS (จะใช้งานได้ทุกที่ที่ฝัง Control UI; เส้นทางวิดเจ็ตอินไลน์ไม่มีการเปลี่ยนแปลง)
  • วิดเจ็ตข้อมูลในตัว (การ์ดเซสชัน/การใช้งาน/cron) — บริดจ์ความสามารถร่วมกับ วิดเจ็ตที่เอเจนต์สร้างครอบคลุม v1; รีจิสทรีชนิดในตัวสามารถเพิ่มภายหลังได้
  • WorkBoard บนแดชบอร์ด

แผนการดำเนินงาน

เวิร์กทรีอิสระ สร้างด้วย Codex รีวิว+รวมตามลำดับ รวมแล้วค่อยแก้ไข

# แบรนช์ ขอบเขต ขึ้นกับ
T1 claude/dashboard-remove-workspaces ลบ Plugin เวิร์กสเปซ + UI + เอกสาร + คีย์ i18n; กฎล้างข้อมูลของ doctor
T2 claude/dashboard-canvas-core ยกระดับการโฮสต์วิดเจ็ต + show_widget ไปยังแกนหลัก; Plugin แคนวาสเก็บเครื่องมือโหนดไว้; ไม่มีการเปลี่ยนแปลงพฤติกรรม
T3 claude/dashboard-domain ตาราง DB เอเจนต์ (เพิ่มเวอร์ชันสคีมา), RPC board.* + เหตุการณ์, เครื่องมือ dashboard, อาร์กิวเมนต์ปักหมุด/ชื่อ/แมนิเฟสต์ show_widget, ประกาศระดับ 1, รีเซ็ตโดยคงบอร์ดไว้ T2
T4 claude/dashboard-ui หน้าบอร์ด + แถบแท็บ + กริดยืดหยุ่นจัดให้กระชับอัตโนมัติ + ด็อกแชต (ซ้าย/ขวา/ล่าง/ซ่อน) + ตัวเลือกปักหมุดทรานสคริปต์ + หน้าบอร์ดในแถบด้านข้าง + การยืนยันรีเซ็ต T3 (ใช้ม็อกก่อนผ่านฟิกซ์เจอร์สำหรับการพัฒนา)
T5 claude/dashboard-capabilities ที่เก็บ/ UI สำหรับสิทธิ์ + การตรึงไบต์; ย้ายวิดเจ็ต html ไปยังโฮสต์แซนด์บ็อกซ์ที่ใช้ร่วมกัน; เครื่องมือโฮสต์ (openclaw.prompt.send/state.emit/data.read/cron.trigger); CSP net; ชิมสำหรับการเขียน T3, T4
T7 claude/dashboard-mcp-apps ชนิดเนื้อหา mcp-app: ตัวเลือกปักหมุดในมุมมองแอปอินไลน์, การจัดเก็บตัวอธิบาย, การออก/รีเฟรชสัญญาเช่าใหม่, สิทธิ์เครื่องมือเซิร์ฟเวอร์แบบถาวร (ใช้โฮสต์ MCP Apps ที่เผยแพร่แล้วซ้ำ) T3, T4
T6 ปรับแต่ง E2E แบบสดบน Gateway ชั่วคราว (คีย์จริง), ภาพหน้าจอ, การแก้ไข, เขียน /web/dashboard ใหม่โดยเน้นผู้ใช้, รีวิวการเปิดใช้เป็นค่าเริ่มต้น ทั้งหมด

การตรวจสอบความถูกต้องตามกฎของรีโพ: ใช้ vitest แบบเจาะจงในเครื่อง, เกตทั้งหมดบน Crabbox/Testbox, $autoreview ก่อนรวมทุกครั้ง, การพิสูจน์แบบสดสำหรับ T6.

Was this useful?
On this page

On this page