Tools

โหมดโค้ด

โหมดโค้ดเป็นฟีเจอร์รันไทม์เอเจนต์ OpenClaw แบบทดลองที่ต้องเลือกเปิดใช้ เมื่อ เปิดใช้แล้ว โมเดลจะไม่เห็นสคีมาของเครื่องมือที่เปิดใช้ทั้งหมดอีกต่อไป แต่จะเห็น exec, wait และเครื่องมือแบบ direct-only ใดๆ ที่ผลลัพธ์แบบมีโครงสร้างไม่สามารถส่งผ่าน บริดจ์ guest ที่รองรับเฉพาะ JSON ได้ โมเดลจะเขียนโปรแกรม JavaScript หรือ TypeScript ขนาดเล็กเพื่อค้นหา ดูคำอธิบาย และเรียกใช้แค็ตตาล็อกเครื่องมือที่ซ่อนอยู่

หน้านี้อธิบายโหมดโค้ดของ OpenClaw ไม่ใช่ Codex Code Mode ฟีเจอร์ทั้งสอง ใช้ชื่อเดียวกันและชื่อเครื่องมือควบคุมเดียวกัน (exec, wait) แต่เป็น การใช้งานที่แยกจากกัน:

  • Codex Code Mode ทำงานภายในระบบควบคุมการเขียนโค้ดของ Codex เครื่องมือ exec ของมันเป็น เครื่องมือไวยากรณ์แบบอิสระ: โมเดลเขียนซอร์ส JavaScript ดิบ (อาจ นำหน้าด้วยบรรทัด pragma // @exec: {...} สำหรับตัวเลือกการดำเนินการ) ซึ่งจะถูกดำเนินการ ในรันไทม์ V8 Code Mode ภายในโปรเซสของ Codex
  • โหมดโค้ดของ OpenClaw ทำงานในรันไทม์เอเจนต์ OpenClaw ทั่วไป และจะ ปิดอยู่เว้นแต่จะกำหนดค่า tools.codeMode.enabled: true เครื่องมือ exec รับเพย์โหลด JSON { code, language } ซึ่งดำเนินการในเวิร์กเกอร์ QuickJS-WASI

ทั้งสองเป็นพื้นผิวการดำเนินการ JavaScript ไม่ใช่พื้นผิวคำสั่งเชลล์ ให้ถือว่าเป็น ฟีเจอร์อิสระที่มีการใช้งานแตกต่างกัน ซึ่งบังเอิญเปิดเผยเครื่องมือ exec/wait ที่มีชื่อเหมือนกัน

การทำงาน

  • รายการเครื่องมือที่โมเดลมองเห็นจะกลายเป็น exec, wait รวมถึงเครื่องมือแบบ direct-only ใดๆ เช่น computer หรือตัวโหลด image สำหรับวิชันแบบเนทีฟ ซึ่งผลลัพธ์รูปภาพ ไม่สามารถส่งผ่านบริดจ์ guest ได้
  • exec ประเมิน JavaScript หรือ TypeScript ที่โมเดลสร้างขึ้นในเธรดเวิร์กเกอร์ QuickJS-WASI ที่แยกออกจากกัน
  • เครื่องมือที่เปิดใช้และมีสิทธิ์อยู่ในแค็ตตาล็อกทุกเครื่องมือ (แกนหลัก OpenClaw, Plugin, MCP, ไคลเอนต์) จะถูกซ่อนจากการเป็น เครื่องมือเดี่ยวที่โมเดลมองเห็น และเปิดเผยภายในโปรแกรม guest ผ่าน ALL_TOOLS และ tools
  • คำอธิบาย exec มีดัชนีด่วนแบบจำกัดของรหัสแค็ตตาล็อก OpenClaw/Plugin ที่ตรงกัน คำใบ้อินพุตแบบย่อ และคำใบ้เอาต์พุตที่ประกาศแบบย่อเมื่อ เครื่องมือที่เชื่อถือได้มีสคีมาเอาต์พุต โดยจะละคำอธิบาย สคีมาแบบเต็ม รายการ MCP และรายการที่เกินขีดจำกัดไว้ การค้นหาแค็ตตาล็อกฝั่ง guest ยังคงเป็นทางเลือกสำรอง
  • โค้ด guest ค้นหาแค็ตตาล็อกที่ซ่อนอยู่ ดูคำอธิบายสคีมาของเครื่องมือ และเรียกใช้ เครื่องมือผ่านเส้นทางการดำเนินการเดียวกับที่ใช้ในการทำงานปกติของเอเจนต์ (นโยบาย การอนุมัติ ฮุก และเทเลเมทรียังคงมีผลทั้งหมด)
  • เครื่องมือ MCP จะถูกจัดกลุ่มภายใต้เนมสเปซ MCP; ในโหมดโค้ด วิธีนี้เป็น วิธีเดียวที่รองรับสำหรับเรียกใช้เครื่องมือเหล่านั้น
  • wait ดำเนินการรันโหมดโค้ดที่ระงับไว้ต่อ เมื่อการเรียกเครื่องมือแบบซ้อนยัง รอดำเนินการอยู่

โหมดโค้ดเปลี่ยนเฉพาะพื้นผิวการประสานงานที่โมเดลมองเห็นเท่านั้น โดยไม่ แทนที่เครื่องมือ เครื่องมือของ Plugin เครื่องมือ MCP การยืนยันตัวตน นโยบายการอนุมัติ พฤติกรรมของช่องทาง หรือการเลือกโมเดล

เหตุผลที่ควรใช้

  • พื้นผิวพรอมป์ที่เล็กลง: ผู้ให้บริการได้รับเครื่องมือควบคุมสองรายการ ดัชนีเครื่องมือเนทีฟ แบบจำกัด และเฉพาะเครื่องมือโดยตรงไม่กี่รายการที่จำเป็น แทนสคีมาเครื่องมือแบบเต็ม หลายสิบหรือหลายร้อยรายการ
  • การประสานงานที่ดีขึ้น: โมเดลสามารถใช้ลูป การรวม การแปลงขนาดเล็ก ตรรกะแบบมีเงื่อนไข และการเรียกเครื่องมือแบบซ้อนพร้อมกันภายในเซลล์โค้ดเดียว
  • ลดจำนวนรอบการรับส่งกับโมเดล: สัญญาเอาต์พุตที่ประกาศไว้ช่วยให้โมเดลเรียกและ แปลงผลลัพธ์ของเครื่องมือใน exec เดียวได้ ส่วนเอาต์พุตที่ไม่รู้จักจะยังคงส่งค่าดิบก่อน
  • ไม่ขึ้นกับผู้ให้บริการ: ใช้งานได้กับเครื่องมือ OpenClaw, Plugin, MCP และไคลเอนต์ โดยไม่ พึ่งพาการดำเนินการโค้ดแบบเนทีฟของผู้ให้บริการ
  • ล้มเหลวแบบปิด: หากเปิดใช้โหมดโค้ดแต่รันไทม์ QuickJS-WASI ไม่พร้อมใช้งาน การรันจะล้มเหลวแทนที่จะถอยกลับไปเปิดเผยเครื่องมือโดยตรง ในวงกว้างอย่างเงียบๆ

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

คงการเปิดเผยเครื่องมือโดยตรงไว้สำหรับแค็ตตาล็อกขนาดเล็กหรือโมเดลที่ไม่สามารถ เขียนโปรแกรมสั้นๆ ได้อย่างเชื่อถือได้ ใช้ การค้นหาเครื่องมือ เมื่อต้องการ แค็ตตาล็อกแบบกะทัดรัด แต่ต้องการตัวควบคุมค้นหา/ดูคำอธิบาย/เรียกใช้แบบมีโครงสร้าง แทน guest QuickJS-WASI

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

เปิดใช้โหมดโค้ด

json5
{  tools: {    codeMode: {      enabled: true,    },  },}

รูปแบบย่อ:

json5
{  tools: {    codeMode: true,  },}

โหมดโค้ดจะยังคงปิดเมื่อไม่ระบุ tools.codeMode, เป็น false หรือเป็นออบเจ็กต์ ที่ไม่มี enabled: true

หากใช้เอเจนต์แบบแซนด์บ็อกซ์ร่วมกับเซิร์ฟเวอร์ MCP ที่กำหนดค่าไว้ ให้อนุญาต Plugin MCP ที่รวมมาให้ในนโยบายเครื่องมือของแซนด์บ็อกซ์ด้วย เช่น tools.sandbox.tools.alsoAllow: ["bundle-mcp"] ดู การกำหนดค่า - เครื่องมือและผู้ให้บริการแบบกำหนดเอง

กำหนดขีดจำกัดอย่างชัดเจนเพื่อให้ข้อจำกัดรัดกุมยิ่งขึ้น:

json5
{  tools: {    codeMode: {      enabled: true,      timeoutMs: 10000,      memoryLimitBytes: 67108864,      maxOutputBytes: 65536,      maxSnapshotBytes: 10485760,      maxPendingToolCalls: 16,      snapshotTtlSeconds: 900,      searchDefaultLimit: 8,      maxSearchLimit: 50,    },  },}

สิ่งที่โมเดลทำ

สำหรับเครื่องมือที่มีเอาต์พุตประกาศไว้ เช่น Array<{ id: string; paid: boolean; tons: number }> โปรแกรม guest โปรแกรมเดียวสามารถ เลือก เรียกใช้ และแปลงเครื่องมือนั้นได้:

javascript
const [shipmentTool] = await tools.search("list shipments");const shipments = await tools.callValue(shipmentTool.id, {});return shipments.filter((shipment) => !shipment.paid && shipment.tons > 10);

เมื่อบรรทัดดัชนีด่วนลงท้ายด้วย -> ? จะไม่ทราบรูปร่างเอาต์พุต exec ครั้งแรก ต้องส่งคืน await tools.callValue(...) โดยไม่เปลี่ยนแปลง ส่วน exec ในภายหลังสามารถ แปลงค่าที่สังเกตได้ วิธีนี้ต้องใช้รอบโมเดลเพิ่มอีกหนึ่งรอบ แต่ป้องกันไม่ให้ โมเดลคาดเดาชื่อฟิลด์

ตรวจสอบพื้นผิวที่ใช้งานอยู่

เพื่อยืนยันรูปร่างเพย์โหลดของโมเดลระหว่างการดีบัก ให้รัน Gateway พร้อม การบันทึกล็อกแบบเจาะจง:

bash
OPENCLAW_DEBUG_CODE_MODE=1 \OPENCLAW_DEBUG_MODEL_TRANSPORT=1 \OPENCLAW_DEBUG_MODEL_PAYLOAD=tools \openclaw gateway

เมื่อโหมดโค้ดทำงาน ชื่อเครื่องมือที่โมเดลมองเห็นในล็อกควรเป็น exec และ wait สำหรับเพย์โหลดผู้ให้บริการฉบับเต็มที่ปกปิดข้อมูลแล้ว ให้เพิ่ม OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted สำหรับเซสชันดีบักช่วงสั้นๆ

ใช้ Swarm สำหรับการกระจายงานไปยังเอเจนต์

Swarm เพิ่มโกลบอล guest agents.run(), phase() และ log() สำหรับประสานงานซับเอเจนต์พร้อมกันจากสคริปต์โหมดโค้ด เปิดใช้ทั้ง tools.codeMode และ tools.swarm แล้วใช้โฟลว์ควบคุม JavaScript ปกติสำหรับ การกระจายงาน เกตการตัดสินใจ และการรวบรวมแบบมีโครงสร้าง Swarm เป็นเกตแบบเลือกเปิดใช้ ที่แยกต่างหาก การเปิดใช้โหมดโค้ดเพียงอย่างเดียวจะไม่เปิดเผย API agents.*

ภาพรวมเชิงเทคนิค

ส่วนที่เหลือของหน้านี้กล่าวถึงสัญญารันไทม์และรายละเอียดการใช้งาน สำหรับผู้ดูแล ผู้เขียน Plugin ที่กำลังดีบักการเปิดเผยเครื่องมือ และผู้ปฏิบัติงาน ที่กำลังตรวจสอบการนำไปใช้งานที่มีความเสี่ยงสูง

สถานะรันไทม์

รันไทม์ quickjs-wasi
สถานะเริ่มต้น ปิดใช้งาน
ความเสถียร พื้นผิว OpenClaw แบบทดลอง (Codex Code Mode เป็นพื้นผิวระบบควบคุม Codex ที่เสถียรและแยกต่างหาก)
พื้นผิวเป้าหมาย การรันเอเจนต์ OpenClaw ทั่วไป
แนวทางด้านความปลอดภัย ถือว่าโค้ดของโมเดลเป็นอันตราย
คำมั่นต่อผู้ใช้ การเปิดใช้โหมดโค้ดจะไม่ถอยกลับไปเปิดเผยเครื่องมือโดยตรงในวงกว้างอย่างเงียบๆ

ขอบเขต

โหมดโค้ดเป็นเจ้าของรูปร่างการประสานงานที่โมเดลมองเห็นสำหรับการรันที่เตรียมไว้ โดย ไม่ได้เป็นเจ้าของการเลือกโมเดล พฤติกรรมของช่องทาง การยืนยันตัวตน นโยบายเครื่องมือ หรือการใช้งาน เครื่องมือ

อยู่ในขอบเขต: คำนิยามเครื่องมือควบคุม/โดยตรงที่โมเดลมองเห็น การสร้างแค็ตตาล็อกเครื่องมือ ที่ซ่อนอยู่ การดำเนินการ guest ของ JavaScript/TypeScript รันไทม์เวิร์กเกอร์ QuickJS-WASI คอลแบ็กโฮสต์สำหรับค้นหา/ดูคำอธิบาย/เรียกใช้ สถานะที่ดำเนินการต่อได้สำหรับ โปรแกรม guest ที่ระงับ ขีดจำกัดเอาต์พุต/เวลาหมด/หน่วยความจำ/การเรียกที่รอดำเนินการ/สแนปช็อต และการฉายข้อมูลเทเลเมทรี/วิถีการทำงานสำหรับการเรียกเครื่องมือแบบซ้อน

อยู่นอกขอบเขต: การดำเนินการโค้ดระยะไกลแบบเนทีฟของผู้ให้บริการ ความหมายของการดำเนินการ เชลล์ การเปลี่ยนการอนุญาตเครื่องมือที่มีอยู่ สคริปต์ที่ผู้ใช้เขียนและจัดเก็บถาวร การเข้าถึงตัวจัดการแพ็กเกจ/ไฟล์/เครือข่าย/โมดูลในโค้ด guest และการนำส่วนภายในของ Codex Code Mode มาใช้โดยตรง

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

คำศัพท์

  • โหมดโค้ด: โหมดรันไทม์ OpenClaw ที่ซ่อนเครื่องมือโมเดลซึ่งเข้ากันได้กับแค็ตตาล็อก และเปิดเผย exec, wait รวมถึงเครื่องมือแบบ direct-only ที่จำเป็น
  • รันไทม์ guest: VM JavaScript ของ QuickJS-WASI ที่ประเมินโค้ดของโมเดล
  • บริดจ์โฮสต์: พื้นผิวคอลแบ็กที่แคบและเข้ากันได้กับ JSON จากโค้ด guest กลับเข้าสู่ OpenClaw
  • แค็ตตาล็อก: รายการเครื่องมือที่มีผลในขอบเขตการรัน หลังการแก้ไข นโยบายเครื่องมือ Plugin, MCP และเครื่องมือไคลเอนต์ตามปกติ
  • การเรียกเครื่องมือแบบซ้อน: การเรียกเครื่องมือจากโค้ด guest ผ่านบริดจ์ โฮสต์
  • สแนปช็อต: สถานะ VM QuickJS-WASI ที่ซีเรียลไลซ์และบันทึกไว้ เพื่อให้ wait สามารถดำเนินการ รันโหมดโค้ดที่ระงับไว้ต่อได้

การกำหนดค่า

tools.codeMode.enabled เป็นเกตการเปิดใช้งาน การตั้งค่าฟิลด์อื่นจะไม่ เปิดใช้ฟีเจอร์นี้ด้วยตัวเอง

ฟิลด์ ค่าเริ่มต้น ข้อจำกัด
enabled false บูลีน; เฉพาะ true เท่านั้นที่เปิดใช้โหมดโค้ด
runtime "quickjs-wasi" ค่าที่รองรับเพียงค่าเดียว
mode "only" เปิดเผยเครื่องมือควบคุม/โดยตรง และจัดรายการที่เหลือไว้ในแค็ตตาล็อก
languages ["javascript", "typescript"] เซตย่อยใดๆ ของทั้งสองรายการ
timeoutMs 10000 100-60000
memoryLimitBytes 67108864 1048576-1073741824
maxOutputBytes 65536 1024-10485760
maxSnapshotBytes 10485760 1024-268435456
maxPendingToolCalls 16 1-128
snapshotTtlSeconds 900 1-86400
searchDefaultLimit 8 จำกัดไว้ที่ maxSearchLimit
maxSearchLimit 50 1-50

หากเปิดใช้โหมดโค้ดแต่ไม่สามารถโหลด QuickJS-WASI ได้ OpenClaw จะล้มเหลวแบบปิด สำหรับการรันนั้น โดยจะไม่เปิดเผยเครื่องมือปกติเป็นทางเลือกสำรองอย่างเงียบๆ

การเปิดใช้งาน

โหมดโค้ดจะได้รับการประเมินหลังจากทราบนโยบายเครื่องมือที่มีผลแล้ว และก่อน ประกอบคำขอสุดท้ายสำหรับโมเดล:

  1. ระบุเอเจนต์ โมเดล ผู้ให้บริการ แซนด์บ็อกซ์ ช่องทาง ผู้ส่ง และนโยบาย การรัน
  2. สร้างรายการเครื่องมือ OpenClaw ที่มีผล โดยเพิ่มเครื่องมือ Plugin, MCP และ ไคลเอนต์ที่เข้าเกณฑ์
  3. ใช้นโยบายอนุญาต/ปฏิเสธ
  4. หาก tools.codeMode.enabled เป็น false ให้เปิดเผยเครื่องมือตามปกติต่อไป
  5. หากเปิดใช้งานและมีเครื่องมือที่ทำงานสำหรับการรัน ให้คงเครื่องมือ direct-only ที่จำเป็นไว้ และลงทะเบียนเครื่องมือที่มีผลซึ่งเข้าเกณฑ์แค็ตตาล็อกทุกรายการในแค็ตตาล็อก โหมดโค้ด
  6. นำเครื่องมือที่ลงแค็ตตาล็อกแล้วออกจากรายการที่โมเดลมองเห็น และเพิ่ม exec กับ wait ควบคู่กับเครื่องมือ direct-only ที่คงไว้

การรันที่ตั้งใจไม่ให้มีเครื่องมือ (การเรียกโมเดลดิบ, disableTools: true หรือรายการ tools.allow ที่ว่าง) จะไม่เปิดใช้งานพื้นผิวโหมดโค้ด แม้ จะกำหนดค่า tools.codeMode.enabled: true ไว้ โหมดโค้ดและการค้นหาเครื่องมือของ OpenClaw ใช้ร่วมกันไม่ได้ในการรันเดียว หากโหมดโค้ดเปิดใช้งาน Compaction ของการค้นหาเครื่องมือ จะไม่ทำงาน

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

เครื่องมือที่โมเดลมองเห็น

เมื่อโหมดโค้ดทำงาน โมเดลจะเห็น exec, wait และเครื่องมือ direct-only ที่จำเป็น เครื่องมืออื่นทุกตัวที่เปิดใช้งานจะถูกซ่อนจากรายการเครื่องมือ ที่แสดงต่อโมเดล และลงทะเบียนในแค็ตตาล็อกโหมดโค้ด

ใช้ exec สำหรับการประสานงานเครื่องมือ การรวมข้อมูล ลูป การเรียกซ้อนแบบขนาน และการแปลงข้อมูลแบบมีโครงสร้าง ใช้ wait เฉพาะเมื่อ exec ส่งคืนผลลัพธ์ waiting ที่ดำเนินการต่อได้

exec

exec เริ่มเซลล์โหมดโค้ดและส่งคืนผลลัพธ์หนึ่งรายการ โค้ดอินพุตสร้างโดยโมเดล และต้องถือว่าเป็นอันตราย

อินพุต:

typescript
type CodeModeExecInput = {  code?: string;  command?: string;  language?: "javascript" | "typescript";};

กฎ:

  • ต้องมีค่าอย่างใดอย่างหนึ่งระหว่าง code หรือ command
  • code คือฟิลด์ที่แสดงต่อโมเดลตามเอกสาร
  • ยอมรับ command เป็นนามแฝงที่เข้ากันได้กับ exec สำหรับนโยบาย hook และ การเขียนใหม่ที่เชื่อถือได้ (เครื่องมือ shell exec ปกติของ OpenClaw ก็ใช้ฟิลด์ command เช่นกัน) เมื่อมีทั้งสองค่า ค่าต้องตรงกัน
  • language มีค่าเริ่มต้นเป็น "javascript"; สคีมาเปิดเผยเป็น string enum แบบแบน ("javascript" | "typescript") ไม่ใช่ยูเนียน oneOf/anyOf เนื่องจากผู้ให้บริการบางรายปฏิเสธรูปแบบเหล่านั้น
  • หาก language เป็น "typescript" OpenClaw จะทรานสไพล์ก่อนประเมินผล
  • exec ปฏิเสธ import, require, dynamic import และรูปแบบ module-loader
  • exec จะไม่เปิดเผยการติดตั้งใช้งาน shell exec ปกติแบบเรียกซ้ำ
  • เหตุการณ์ hook exec ของโหมดโค้ดชั้นนอกมี toolKind: "code_mode_exec" และ toolInputKind: "javascript" | "typescript" (เมื่อทราบ) เพื่อให้นโยบายสามารถ แยกเซลล์โหมดโค้ดออกจากการเรียก exec แบบ shell ซึ่งใช้ ชื่อเครื่องมือเดียวกัน

ผลลัพธ์:

typescript
type CodeModeResult = CodeModeCompletedResult | CodeModeWaitingResult | CodeModeFailedResult; type CodeModeCompletedResult = {  status: "completed";  value: unknown;  output?: CodeModeOutput[];  telemetry: CodeModeTelemetry;}; type CodeModeWaitingResult = {  status: "waiting";  runId: string;  reason: "pending_tools" | "yield";  pendingToolCalls?: CodeModePendingToolCall[];  output?: CodeModeOutput[];  telemetry: CodeModeTelemetry;}; type CodeModeFailedResult = {  status: "failed";  error: string;  code?: CodeModeErrorCode;  output?: CodeModeOutput[];  telemetry: CodeModeTelemetry;};

exec ส่งคืน waiting เมื่อเกสต์พักการทำงานพร้อมสถานะที่ดำเนินการต่อได้ ซึ่งยัง ต้องการการดำเนินการต่อที่โมเดลมองเห็น เช่น yield_control(...) แบบชัดแจ้ง หรือ การเรียกเครื่องมือบริดจ์ที่ยังไม่เสร็จสิ้นภายในกำหนดเวลาของ exec ผลลัพธ์ จะมี runId สำหรับ wait การเรียกเครื่องมือบริดจ์ ได้แก่ tools.search/describe/ call และการเรียกเนมสเปซ รวมถึงการเรียกเนมสเปซ MCP จะถูกระบายอัตโนมัติ ภายในสายเรียก exec/wait เดียวกัน ตราบใดที่ดำเนินการเสร็จภายในกำหนดเวลา ดังนั้น บล็อกโค้ดขนาดกะทัดรัดที่รอเครื่องมือหลายตัวจึงทำงานจนเสร็จในการผลัดเดียวของโมเดล แทนที่จะบังคับให้เรียกเครื่องมือโมเดลหนึ่งครั้งต่อ await การรันที่ปลอดภัยต่อการรีสตาร์ตจะไม่ ระบายอัตโนมัติ งานที่ค้างอยู่ยังคงผ่านการตรวจสอบที่ปลอดภัยต่อการเล่นซ้ำ

exec ส่งคืน completed เฉพาะเมื่อ VM ของเกสต์ไม่มีงานค้างอยู่และ ค่าสุดท้ายเข้ากันได้กับ JSON หลังจากอะแดปเตอร์เอาต์พุตของ OpenClaw ทำงานแล้ว

wait

wait ดำเนินการต่อ VM โหมดโค้ดที่พักการทำงานไว้

อินพุต:

typescript
type CodeModeWaitInput = {  runId: string;};

เอาต์พุตเป็นยูเนียน CodeModeResult เดียวกับที่ exec ส่งคืน

wait มีอยู่เนื่องจากเครื่องมือ OpenClaw ที่ซ้อนกันอาจทำงานช้า โต้ตอบได้ ถูกควบคุมด้วยการอนุมัติ หรือสตรีมการอัปเดตบางส่วน โมเดลไม่ควรต้องเปิด การเรียก exec ที่ยาวไว้ขณะที่โฮสต์รอการทำงานภายนอก

QuickJS-WASI snapshot/restore คือกลไกการดำเนินการต่อ:

  1. exec ประเมินโค้ดจนเสร็จสิ้น ล้มเหลว หรือพักการทำงาน
  2. เมื่อพักการทำงาน OpenClaw จะสร้างสแนปช็อตของ QuickJS VM และบันทึกงาน ของโฮสต์ที่ค้างอยู่
  3. เมื่องานที่ค้างอยู่เสร็จสิ้น wait จะกู้คืนสแนปช็อต VM และ ลงทะเบียน callback ของโฮสต์อีกครั้งด้วยชื่อที่คงที่
  4. OpenClaw ส่งผลลัพธ์ของเครื่องมือที่ซ้อนกันเข้าสู่ VM ที่กู้คืนแล้ว และระบาย งานที่ค้างอยู่ของ QuickJS
  5. wait ส่งคืน completed, failed หรือผลลัพธ์ waiting อื่น

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

wait ล้มเหลว (ในรูปผลลัพธ์ failed) เมื่อ:

  • ไม่รู้จัก runId หรือสแนปช็อตหมดอายุแล้ว
  • ผู้เรียกไม่ได้อยู่ในขอบเขตการรัน/เซสชันเดียวกับการรันที่พักไว้
  • มี wait กำลังทำงานอยู่แล้วสำหรับ runId นั้น
  • การกู้คืน QuickJS-WASI ล้มเหลว
  • การดำเนินการต่อจะเกิน maxOutputBytes หรือ maxSnapshotBytes

API รันไทม์ของเกสต์

typescript
declare const ALL_TOOLS: ToolCatalogEntry[];declare const tools: ToolCatalog;declare const MCP: Record<string, unknown>;declare const namespaces: Record<string, unknown>; declare function text(value: unknown): void;declare function json(value: unknown): void;declare function yield_control(reason?: string): Promise<void>;

ALL_TOOLS คือเมทาดาทาขนาดกะทัดรัดสำหรับแค็ตตาล็อกที่มีขอบเขตเฉพาะการรัน โดยค่าเริ่มต้น จะไม่มีสคีมาเต็ม คำอธิบาย exec ที่โมเดลมองเห็นยังรวมถึง ชุดย่อยแบบจำกัดและกำหนดได้แน่นอนของ id ที่ตรงกันจาก OpenClaw/Plugin คำใบ้อินพุต แบบกะทัดรัด และคำใบ้เอาต์พุตที่ประกาศและเชื่อถือได้ คำอธิบายจะยังถูกเลื่อนการโหลดไว้ เพื่อไม่ให้ ข้อความแค็ตตาล็อกที่เป็นอันตรายชักนำโมเดล เมื่อดัชนีนั้นไม่มีเครื่องมือรายการหนึ่ง ให้อ่าน ALL_TOOLS หรือเรียก tools.search(...) ภายในโปรแกรมเกสต์

ลูกศรในแต่ละบรรทัดของดัชนีด่วนอธิบายค่า tools.callValue(...) -> Array<{ id: string }> คือคำใบ้เอาต์พุตที่ประกาศ ส่วน -> ? หมายถึงไม่ทราบเอาต์พุต เอาต์พุตที่ไม่ทราบจะเน้นค่าดิบก่อน: ส่งคืนค่าโดยไม่เปลี่ยนแปลง สังเกตค่านั้น แล้วจึง กรองหรือแมปใน exec ภายหลังแทนการเดาชื่อฟิลด์ หลักการนี้ยัง ใช้เมื่อการอ่านเอาต์พุตที่ประกาศไว้ส่งต่อไปยังการเรียก -> ? ขั้นสุดท้าย: ให้ส่งคืน ค่าดิบของการเรียกนั้นโดยไม่ห่อด้วยรูปแบบคำตอบที่ร้องขอ

typescript
type ToolCatalogEntry = {  id: string;  name: string;  label?: string;  description: string;  source: "openclaw" | "mcp" | "client";  sourceName?: string;  input: string;  output?: string;};

input คือลายเซ็นรูปแบบ TypeScript แบบจำกัดสำหรับกรณีทั่วไป ใช้ tools.describe(...) เมื่อยังต้องการสคีมาเต็มที่ตรงกัน รายการ MCP ระยะไกล และไคลเอนต์ใช้ input: "unknown" เพื่อให้สคีมาที่ไม่น่าเชื่อถือยังคง ถูกเลื่อนการโหลดจนถึง describe ส่วน output จะมีเฉพาะคำใบ้แบบกะทัดรัดที่สมบูรณ์ซึ่งได้มาจาก outputSchema ของแกนหลัก OpenClaw หรือ Plugin ที่เชื่อถือได้ การอ้างสคีมาเอาต์พุตจาก MCP และไคลเอนต์จะไม่ถูกยกระดับ เป็นคำใบ้แค็ตตาล็อกที่เชื่อถือได้นี้

เครื่องมือ Plugin ใช้ source: "openclaw" โดยตั้งค่า sourceName เป็น id ของ Plugin เจ้าของ โดยไม่มีค่าแหล่งที่มา "plugin" แยกต่างหาก source: "mcp" ใช้เฉพาะกับรายการ MCP ในเมทาดาทา sourceName/mcp (และถูกกรองออก จาก ALL_TOOLS/tools.* โปรดดูด้านล่าง)

สคีมาเต็มจะโหลดเมื่อร้องขอเท่านั้น:

typescript
type ToolCatalogEntryWithSchema = ToolCatalogEntry & {  parameters: unknown;  outputSchema?: unknown;};

ตัวช่วยแค็ตตาล็อก:

typescript
type ToolCatalog = {  search(query: string, options?: { limit?: number }): Promise&lt;ToolCatalogEntry[]&gt;;  describe(id: string): Promise&lt;ToolCatalogEntryWithSchema&gt;;  callValue(id: string, input?: unknown): Promise<unknown>;  call(id: string, input?: unknown): Promise<unknown>;  [safeToolName: string]: unknown;};

ฟังก์ชันเครื่องมือเพื่อความสะดวกจะติดตั้งเฉพาะชื่อที่ปลอดภัยและไม่กำกวม:

typescript
const files = await tools.search("read local file");const fileRead = await tools.describe(files[0].id);const content = await tools.callValue(fileRead.id, { path: "README.md" }); // หากแค็ตตาล็อกที่ซ่อนอยู่มีรายการ `web_search` ที่ไม่กำกวม:const hits = await tools.web_search({ query: "OpenClaw code mode" });

tools.callValue(...) ส่งคืนค่า JSON details ของเครื่องมือปกติโดยตรง tools.call(...) จะรักษาเอนเวโลป { tool, result } แบบดิบไว้สำหรับผู้เรียก ที่ต้องการบล็อกเนื้อหาหรือเมทาดาทาผลลัพธ์อื่น

สัญญาเอาต์พุตที่ประกาศ

เครื่องมือ OpenClaw สามารถประกาศ outputSchema สำหรับค่าแบบมีโครงสร้างที่ใส่ไว้ใน AgentToolResult.details ซึ่งมีประโยชน์สำหรับโหมดโค้ดและการค้นหาเครื่องมือ แต่ ไม่ใช่สคีมาการตอบกลับเครื่องมือแบบเนทีฟของผู้ให้บริการ และไม่เปลี่ยนการเปิดเผยเครื่องมือ โดยตรง

สำหรับเครื่องมือที่สร้างด้วย defineToolPlugin ให้ประกาศสคีมาไว้ข้าง parameters:

typescript
  const Shipment = Type.Object(  {    id: Type.String(),    paid: Type.Boolean(),    tons: Type.Number(),  },  { additionalProperties: false },); export default defineToolPlugin({  id: "shipping",  name: "Shipping",  description: "Shipment tools.",  tools: (tool) => [    tool({      name: "shipping_list",      description: "List shipments.",      parameters: Type.Object({}),      outputSchema: Type.Array(Shipment),      execute: async () => loadShipments(),    }),  ],});

สำหรับ api.registerTool(...) หรือเครื่องมือจาก factory ให้ใส่พร็อพเพอร์ตี outputSchema เดียวกันบนออบเจ็กต์ AnyAgentTool ที่ส่งคืน

สัญญาในตัวปัจจุบันประกอบด้วย agents_list, apply_patch, conversations_list, conversations_send, conversations_turn, edit, openclaw, read, screen, sessions_history, sessions_list, sessions_search, sessions_send, session_status, spawn_task, terminal, web_fetch และ web_search การส่งผ่านโดยตรงอย่างแม่นยำสามารถนำสคีมาของโปรโตคอลเจ้าของกลับมาใช้แทน การทำสัญญาสำหรับโมเดลเท่านั้นซ้ำได้ ตัวอย่างเช่น เครื่องมือการสนทนาเปิดเผย สคีมาผลลัพธ์ Gateway เดียวกับที่ใช้โดย conversations.list, conversations.send และ conversations.turn; web_fetch เป็นเจ้าของสคีมา เฉพาะเครื่องมือซึ่งคำใบ้เปิดเผยเมทาดาทาที่เสถียร ข้อความ สถานะแคช และเมทาดาทา การล้นแบบซ้อน; web_search ประกาศยูเนียนผลลัพธ์/คำตอบ/ข้อผิดพลาด/ข้อมูลดิบ ที่ผ่านการทำให้เป็นมาตรฐานอย่างแม่นยำเป็นคำใบ้ดัชนีด่วนที่สมบูรณ์ สัญญาระบบไฟล์ส่งคืน ผลลัพธ์แบบมีโครงสร้างสำหรับข้อความที่อ่าน รูปภาพ การตัดทอน และตัวเลือกไม่พบไฟล์; สถานะการเปลี่ยนแปลงจากการแก้ไขอย่างชัดเจนพร้อมข้อมูล diff/patch; และข้อมูลสรุปพาธ ของ apply-patch เมื่อดัชนีด่วนประกาศฟิลด์ เซลล์เดียวสามารถรวมการค้นหาและการส่งมอบ โดยไม่ต้องใช้รอบตรวจสอบแยกต่างหาก:

javascript
const listed = await tools.conversations_list({ query: "บอตบิลด์" });const target = listed.conversations.find((item) => item.label === "บอตบิลด์");if (!target) throw new Error("ไม่พบการสนทนา");return await tools.conversations_send({  conversationRef: target.conversationRef,  message: "บิลด์เสร็จสิ้นแล้ว",});

การเรียกแบบซ้อนยังคงใช้นโยบายเครื่องมือ ฮุก และการอนุมัติตามปกติ หากสัญญาฉบับเต็ม มีความแม่นยำแต่ใหญ่เกินไปสำหรับดัชนีด่วนที่มีขอบเขต สัญญานั้นยังคงเข้าถึงได้ผ่าน tools.describe(...) และลูกศรยังคงเป็น -> ?

กฎของสัญญาเข้มงวดดังนี้:

  • อธิบายค่า details ที่เข้ากันได้กับ JSON อย่างแม่นยำ ไม่ใช่บล็อก content ที่เรนเดอร์แล้วหรือเอนเวโลปของผู้ให้บริการ
  • รวมตัวแปรผลลัพธ์สำเร็จหรือข้อผิดพลาดทุกแบบที่ไม่โยนข้อยกเว้น ละเว้น outputSchema เมื่อ เครื่องมือไม่มีผลลัพธ์แบบมีโครงสร้างที่เสถียร
  • ปิดเลเยอร์ออบเจ็กต์ด้วย { additionalProperties: false } เพื่อให้ได้ คำใบ้ดัชนีด่วนที่สมบูรณ์ สคีมาที่เปิด ใหญ่เกินไป หรือไม่สมบูรณ์ในลักษณะอื่น ยังคงเข้าถึงได้ผ่าน tools.describe(...) แต่ไม่เปิดใช้การใช้ฟิลด์ในรอบเดียว
  • OpenClaw คอมไพล์สคีมาก่อนเรียกใช้เครื่องมือ จากนั้นตรวจสอบ details สุดท้ายหลังจากฮุกเครื่องมือตามปกติและก่อนการเรียกแค็ตตาล็อกส่งคืน สคีมาที่ไม่ถูกต้องไม่สามารถเรียกใช้เครื่องมือได้; หากข้อมูลไม่ตรงกัน การทำงานจะล้มเหลว โดยไม่พิมพ์ค่า
  • คำใบ้แบบกะทัดรัดมีลักษณะกำหนดแน่นอนและมีขอบเขต tools.describe(...) เปิดเผย สคีมาที่เชื่อถือได้ฉบับเต็มเมื่อคำใบ้แบบกะทัดรัดไม่เพียงพอ
  • โค้ด Plugin ที่ติดตั้งเป็นโค้ดภายในที่เชื่อถือได้อยู่แล้ว เมทาดาทาจาก MCP ระยะไกล และไคลเอนต์ยังคงไม่น่าเชื่อถือและไม่สามารถเลือกใช้คำใบ้ดัชนีด่วนเหล่านี้ได้

ดูรายละเอียดการสร้าง Plugin ที่ Plugin เครื่องมือ

รายการแค็ตตาล็อก MCP ไม่สามารถเรียกผ่าน tools.callValue(...), tools.call(...) หรือฟังก์ชันอำนวยความสะดวกในโหมดโค้ดได้; รายการเหล่านี้เปิดเผย ผ่านเนมสเปซ MCP ที่สร้างขึ้นเท่านั้น ไฟล์ประกาศรูปแบบ TypeScript เข้าถึงได้ผ่านพื้นผิวไฟล์เสมือนแบบอ่านอย่างเดียว API เพื่อให้เอเจนต์ ตรวจสอบลายเซ็น MCP ได้โดยไม่เพิ่มสคีมา MCP ลงในพรอมต์:

typescript
const files = await API.list("mcp");const githubApi = await API.read("mcp/github.d.ts"); const issue = await MCP.github.createIssue({  owner: "openclaw",  repo: "openclaw",  title: "ตรวจสอบบันทึก Gateway",}); const snapshot = await MCP.chromeDevtools.takeSnapshot({ output: "markdown" });const resource = await MCP.docs.resources.read({ uri: "memo://one" });const prompt = await MCP.docs.prompts.get({  name: "brief",  arguments: { topic: "release" },});

API.read("mcp/<server>.d.ts") ส่งคืนประกาศแบบกะทัดรัดที่อนุมานจาก เมทาดาทาเครื่องมือ MCP:

typescript
type McpToolResult = {  content?: unknown[];  structuredContent?: unknown;  isError?: boolean;  [key: string]: unknown;}; declare namespace MCP.github {  /** ส่งคืนส่วนหัว API รูปแบบ TypeScript นี้ */  function $api(toolName?: string, options?: { schema?: boolean }): Promise&lt;McpApiHeader&gt;;   /**   * สร้าง issue ใน GitHub   * @param owner เจ้าของรีโพซิทอรี   * @param repo ชื่อรีโพซิทอรี   * @param title ชื่อ issue   */  function createIssue(input: {    owner: string;    repo: string;    title: string;    body?: string;  }): Promise&lt;McpToolResult&gt;;}

ไฟล์ประกาศเป็นไฟล์เสมือน ไม่ได้เขียนไว้ใต้ไดเรกทอรีเวิร์กสเปซหรือสถานะ สำหรับการเรียก exec ในโหมดโค้ดแต่ละครั้ง OpenClaw จะสร้างแค็ตตาล็อก เครื่องมือตามขอบเขตการรัน เก็บรายการ MCP ที่มองเห็นได้ เรนเดอร์ mcp/index.d.ts พร้อม mcp/<server>.d.ts หนึ่งรายการต่อเซิร์ฟเวอร์ที่มองเห็นได้ และแทรกตารางขนาดเล็ก แบบอ่านอย่างเดียวนี้ลงในเวิร์กเกอร์ QuickJS โค้ดเกสต์มองเห็นเฉพาะออบเจ็กต์ API: API.list(prefix?) ส่งคืนเมทาดาทาไฟล์ และ API.read(path) ส่งคืนเนื้อหาประกาศที่เลือก พาธที่ไม่รู้จักและเซกเมนต์ ./.. จะถูกปฏิเสธ

วิธีนี้กันสคีมา MCP ขนาดใหญ่ออกจากพรอมต์ของโมเดล: เอเจนต์เรียนรู้ว่า API เสมือนมีอยู่จากคำอธิบายเครื่องมือ exec อ่านเฉพาะไฟล์ประกาศ ที่จำเป็น จากนั้นเรียก MCP.<server>.<tool>() ด้วยอาร์กิวเมนต์ออบเจ็กต์หนึ่งรายการ MCP.<server>.$api() ยังคงใช้เป็นทางเลือกสำรองแบบอินไลน์สำหรับ การตอบกลับสคีมาของเครื่องมือเดียวภายในโปรแกรมได้

รันไทม์เกสต์ไม่เคยมองเห็นออบเจ็กต์ของโฮสต์โดยตรง อินพุตและเอาต์พุตข้าม บริดจ์ในรูปค่าที่เข้ากันได้กับ JSON พร้อมขีดจำกัดขนาดที่ชัดเจน

เนมสเปซภายใน

เนมสเปซภายในมอบ API โดเมนแบบกระชับให้โหมดโค้ดโดยไม่เพิ่มเครื่องมือ ที่โมเดลมองเห็น อินทิเกรชันที่โหลดเดอร์เป็นเจ้าของจะลงทะเบียนเนมสเปซ เช่น Issues หรือ Calendar; จากนั้นโค้ดเกสต์จะเรียกเนมสเปซนั้น ภายในโปรแกรม QuickJS ขณะที่โมเดลยังคงเห็นพื้นผิวควบคุม/โดยตรงแบบกะทัดรัด

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

โค้ดเกสต์ใช้ได้ทั้งโกลบอลโดยตรงหรือแมป namespaces:

javascript
const open = await Issues.list({ state: "open" });const alsoOpen = await namespaces.Issues.list({ state: "open" });return { count: open.length, alsoCount: alsoOpen.length };

วงจรชีวิตของรีจิสทรี

รีจิสทรีเนมสเปซอยู่ภายในโปรเซสและใช้ ID เนมสเปซเป็นคีย์:

  1. โหลดเดอร์ที่เชื่อถือได้เรียก registerCodeModeNamespaceForPlugin(pluginId, registration)
  2. โหมดโค้ดสร้าง ToolSearchRuntime ที่ซ่อนไว้สำหรับการรันและอ่าน แค็ตตาล็อกตามขอบเขตการรันของรายการนั้น
  3. createCodeModeNamespaceRuntime(ctx, catalog) เก็บเฉพาะการลงทะเบียน ที่ requiredToolNames ทั้งหมดมองเห็นได้และเป็นของ pluginId เดียวกัน
  4. แต่ละเนมสเปซที่มองเห็นได้เรียก createScope(ctx) สำหรับการรันปัจจุบัน โดยรับบริบทการรัน เช่น agentId, sessionKey, sessionId, runId, การกำหนดค่า และสถานะยกเลิก
  5. ข้อมูลขอบเขตถูกทำซีเรียลไลซ์เป็นตัวอธิบายแบบธรรมดาและแทรกลงใน QuickJS เป็นโกลบอลโดยตรงและ namespaces.<globalName>
  6. การเรียกของเกสต์หยุดรอผ่านบริดจ์เวิร์กเกอร์ แก้ไขพาธเนมสเปซ บนโฮสต์ แมปการเรียกไปยังเครื่องมือแค็ตตาล็อกที่ประกาศและ Plugin เป็นเจ้าของ แล้วเรียกใช้เครื่องมือนั้นผ่าน ToolSearchRuntime.callExactId
  7. การเรียกบริดจ์เนมสเปซที่พร้อมจะถูกระบายโดยอัตโนมัติภายในการเรียก exec/wait ที่ใช้งานอยู่; หากงานเนมสเปซยังค้างอยู่เมื่อหมดเวลา หรือเกสต์ยอมคืนการทำงานอย่างชัดเจน wait จะดำเนินรันไทม์เนมสเปซเดิม ต่อในภายหลัง
  8. การย้อนกลับหรือถอนการติดตั้ง Plugin จะเรียก clearCodeModeNamespacesForPlugin(pluginId) เพื่อไม่ให้โกลบอลที่ล้าสมัย คงอยู่หลังการโหลด Plugin ล้มเหลว

การเรียกเนมสเปซคือการเรียกเครื่องมือแค็ตตาล็อก โดยใช้นโยบาย ฮุก การอนุมัติ การจัดการการยกเลิก เทเลเมทรี การฉายทรานสคริปต์ และพฤติกรรม หยุดรอ/ดำเนินการต่อแบบเดียวกับ tools.call(...)

รูปแบบการลงทะเบียน

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

typescript
   createCodeModeNamespaceTool,  registerCodeModeNamespaceForPlugin,} from "../agents/code-mode-namespaces.js"; const pluginId = "github"; registerCodeModeNamespaceForPlugin(pluginId, {  id: "github-issues",  globalName: "Issues",  description: "ตัวช่วย GitHub issue สำหรับรีโพซิทอรีปัจจุบัน",  requiredToolNames: ["github_list_issues", "github_update_issue"],  prompt: "ใช้ Issues.list(params) และ Issues.update(number, patch)",  createScope: (ctx) => ({    repository: ctx.config,    list: createCodeModeNamespaceTool("github_list_issues", ([params]) => params ?? {}),    update: createCodeModeNamespaceTool("github_update_issue", ([number, patch]) => ({      number,      patch,    })),  }),});

createCodeModeNamespaceTool(toolName, inputMapper) ทำเครื่องหมายสมาชิกขอบเขตเป็น ฟังก์ชันเนมสเปซที่เรียกใช้ได้ inputMapper ซึ่งเป็นตัวเลือกจะรับอาร์กิวเมนต์ ของเกสต์และส่งคืนออบเจ็กต์อินพุตสำหรับเครื่องมือแค็ตตาล็อกเบื้องหลัง; หากไม่มี จะใช้อาร์กิวเมนต์แรกของเกสต์ หรือใช้ {} เมื่อไม่ได้ระบุ

ฟังก์ชันโฮสต์ดิบจะถูกปฏิเสธก่อนโค้ดเกสต์ทำงาน:

typescript
createScope: () => ({  // ไม่ถูกต้อง: การทำเช่นนี้ข้ามวงจรชีวิตของเครื่องมือแค็ตตาล็อกและจะถูกปฏิเสธ  list: async () => githubClient.listIssues(),});

ความเป็นเจ้าของและการมองเห็น

ความเป็นเจ้าของเนมสเปซผูกกับ pluginId ของผู้เรียกลงทะเบียน requiredToolNames เป็นทั้งด่านควบคุมการมองเห็นและการตรวจสอบความเป็นเจ้าของ:

  • เครื่องมือที่จำเป็นทุกชิ้นต้องมีอยู่ในแค็ตตาล็อกของการรัน
  • เครื่องมือที่จำเป็นทุกชิ้นต้องมี sourceName === pluginId
  • เนมสเปซจะถูกซ่อนเมื่อเครื่องมือที่จำเป็นรายการใดขาดหายไปหรือเป็นของ Plugin อื่น
  • แต่ละพาธที่เรียกใช้ได้สามารถกำหนดเป้าหมายได้เฉพาะเครื่องมือที่ระบุชื่อไว้ใน requiredToolNames

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

ตัวอย่างเช่น เนมสเปซ GitHub ควรอยู่หลัง Plugin ที่ GitHub เป็นเจ้าของ ซึ่งเป็นเจ้าของ การยืนยันตัวตน GitHub, ไคลเอนต์ REST/GraphQL, ขีดจำกัดอัตรา, การอนุมัติการเขียน และการทดสอบ โหมดโค้ดของแกนหลักไม่ควรฝัง API เฉพาะ GitHub, การจัดการโทเค็น หรือนโยบายผู้ให้บริการ

กฎการทำซีเรียลไลซ์ขอบเขต

createScope(ctx) อาจส่งคืนออบเจ็กต์ธรรมดาที่มีค่าซึ่งเข้ากันได้กับ JSON, อาร์เรย์ ออบเจ็กต์แบบซ้อน และมาร์กเกอร์การเรียก createCodeModeNamespaceTool(...) ออบเจ็กต์โฮสต์จะไม่เข้าสู่ QuickJS โดยตรง

ตัวทำซีเรียลไลซ์จะปฏิเสธ:

  • ฟังก์ชันดิบ
  • กราฟออบเจ็กต์แบบวนรอบ
  • เซกเมนต์พาธที่ไม่ปลอดภัย: __proto__, constructor, prototype, คีย์ว่าง หรือคีย์ที่มีตัวคั่นพาธภายใน
  • ค่า globalName ที่ไม่ใช่ตัวระบุ JavaScript
  • การชนกันของ globalName กับโกลบอลในตัวของโหมดโค้ด เช่น tools, namespaces, text, json, yield_control, MCP, API, ALL_TOOLS หรือ __openclaw*

ค่าที่ไม่สามารถทำซีเรียลไลซ์เป็น JSON ได้จะถูกแปลงเป็นค่าทางเลือกที่ปลอดภัยต่อ JSON ก่อนข้ามบริดจ์ ข้อมูลไบนารี แฮนเดิล ซ็อกเก็ต ไคลเอนต์ และอินสแตนซ์คลาส ควรอยู่หลังเครื่องมือแค็ตตาล็อกทั่วไป

พรอมต์

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

typescript
{  description: "ตัวช่วยสำหรับบริการผลิตนิยาย",  prompt:    "ใช้ Fictions.riskAudit(), Fictions.promoteIfReady(id, status) และ Fictions.unpaidOver(amount)",}

กำหนดให้พรอมต์กล่าวถึงสัญญาของเนมสเปซ ไม่ใช่การตั้งค่าการยืนยันตัวตน ประวัติการติดตั้งใช้งาน หรือพฤติกรรมของ Plugin ที่ไม่เกี่ยวข้อง

การล้างข้อมูล

เนมสเปซเป็นการลงทะเบียนภายในโปรเซส ให้ลบออกเมื่อ Plugin เจ้าของ ถูกปิดใช้งาน ถอนการติดตั้ง หรือย้อนกลับ:

typescript
clearCodeModeNamespacesForPlugin(pluginId);

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

รายการตรวจสอบการทดสอบ

การเปลี่ยนแปลงเนมสเปซควรครอบคลุมขอบเขตความปลอดภัยและพฤติกรรมของเกสต์:

  • ข้อความพรอมต์ของเนมสเปซปรากฏเฉพาะเมื่อมองเห็นเครื่องมือเบื้องหลัง
  • เครื่องมือชื่อเดียวกันจาก sourceName อื่นต้องไม่เปิดเผยเนมสเปซ
  • ฟังก์ชันขอบเขตดิบถูกปฏิเสธ
  • รหัสเนมสเปซปลอมและพาธปลอมถูกปฏิเสธ
  • พาธที่เรียกได้ต้องไม่กำหนดเป้าหมายไปยังเครื่องมือที่ไม่ได้ประกาศ
  • ออบเจ็กต์ซ้อนและการอ้างอิงร่วมถูกทำให้เป็นอนุกรมอย่างถูกต้อง
  • การเรียกเนมสเปซทำงานผ่านเครื่องมือในแค็ตตาล็อกและส่งคืนรายละเอียดที่ปลอดภัยสำหรับ JSON
  • โค้ดเกสต์สามารถดักจับความล้มเหลวได้
  • การเรียกเนมสเปซที่ถูกระงับดำเนินต่อผ่าน wait
  • การย้อนกลับ Plugin ล้างการลงทะเบียนเนมสเปซของเจ้าของ

เนมสเปซช่วยเสริมแค็ตตาล็อก tools.search/tools.call แบบทั่วไป: ใช้ แค็ตตาล็อกสำหรับเครื่องมือ OpenClaw, Plugin และไคลเอนต์ที่เปิดใช้งานโดยพลการ ใช้ MCP สำหรับเครื่องมือ MCP และใช้เนมสเปซอื่นสำหรับ API โดเมนที่มีเอกสารกำกับและ Plugin เป็นเจ้าของ เมื่อโค้ดที่กระชับเชื่อถือได้มากกว่าการค้นหาสคีมาซ้ำๆ

API เอาต์พุต

  • text(value) เพิ่มเอาต์พุตที่มนุษย์อ่านได้ต่อท้ายอาร์เรย์ output
  • json(value) เพิ่มรายการเอาต์พุตแบบมีโครงสร้างต่อท้ายหลังจาก ทำให้เป็นอนุกรมที่เข้ากันได้กับ JSON
  • ค่าสุดท้ายที่โค้ดเกสต์ส่งคืนจะกลายเป็น value ในผลลัพธ์ completed
typescript
type CodeModeOutput = { type: "text"; text: string } | { type: "json"; value: unknown };

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

แค็ตตาล็อกเครื่องมือ

แค็ตตาล็อกที่ซ่อนไว้ประกอบด้วยเครื่องมือหลังการกรองตามนโยบายที่มีผล ตามลำดับ ดังนี้: เครื่องมือหลักของ OpenClaw, เครื่องมือ Plugin ที่รวมมาให้, เครื่องมือ Plugin ภายนอก, เครื่องมือ MCP แล้วจึงเป็นเครื่องมือที่ไคลเอนต์จัดเตรียมให้สำหรับการรันปัจจุบัน

รหัสแค็ตตาล็อกมีความเสถียรภายในการรันหนึ่งครั้งและกำหนดได้แน่นอนสำหรับ ชุดเครื่องมือที่เทียบเท่ากันเมื่อเป็นไปได้ รูปแบบจริง:

text
<source>:<owner>:<tool-name>

โดย <source> คือ openclaw, mcp หรือ client (เครื่องมือ Plugin ใช้ openclaw โดยมีรหัส Plugin เป็น <owner> ส่วนเครื่องมือหลักใช้ openclaw:core:*) ตัวอย่าง:

text
openclaw:core:messageopenclaw:browser:browser_requestmcp:github:create_issueclient:app:select_file

แค็ตตาล็อกละเว้นเครื่องมือควบคุมโหมดโค้ด (exec, wait, tool_search_code, tool_search, tool_describe, tool_call) และเครื่องมือที่เรียกโดยตรงเท่านั้น ตัวควบคุม ต้องไม่เรียกซ้ำผ่านแค็ตตาล็อก ส่วนเครื่องมือที่เรียกโดยตรงเท่านั้นยังคงมองเห็นได้โดยโมเดล เนื่องจากผลลัพธ์แบบมีโครงสร้างไม่สามารถข้ามบริดจ์ QuickJS ได้

รายการ MCP ยังคงอยู่ในแค็ตตาล็อกที่มีขอบเขตระดับการรัน เพื่อให้นโยบาย การอนุมัติ ฮุก เทเลเมทรี การฉายทรานสคริปต์ และรหัสเครื่องมือที่แน่นอนยังคงใช้ร่วมกับ การเรียกใช้เครื่องมือตามปกติ มุมมองสำหรับเกสต์ ALL_TOOLS, tools.search(...), tools.describe(...), tools.callValue(...) และ tools.call(...) จะละเว้นรายการ MCP เนมสเปซ MCP.<server>.<tool>({ ...input }) ที่สร้างขึ้นจะแก้กลับไปยัง รหัสแค็ตตาล็อกที่แน่นอนและส่งต่อผ่านพาธตัวดำเนินการเดียวกัน

การทำงานร่วมกับการค้นหาเครื่องมือ

โหมดโค้ดใช้แทนพื้นผิวโมเดลการค้นหาเครื่องมือของ OpenClaw สำหรับการรันที่ เปิดใช้งานโหมดนี้

เมื่อ tools.codeMode.enabled เป็น true และโหมดโค้ดทำงาน:

  • OpenClaw จะไม่เปิดเผย tool_search_code, tool_search, tool_describe หรือ tool_call เป็นเครื่องมือที่โมเดลมองเห็นได้
  • แนวคิดการจัดทำแค็ตตาล็อกเดียวกันย้ายเข้าไปอยู่ภายในรันไทม์ของเกสต์
  • รันไทม์ของเกสต์ได้รับเมทาดาทา ALL_TOOLS แบบกระชับและตัวช่วยค้นหา/อธิบาย/ เรียกใช้สำหรับเครื่องมือที่ไม่ใช่ MCP
  • การเรียก MCP ใช้เนมสเปซ MCP ที่สร้างขึ้นและส่วนหัว $api() ของเนมสเปซนั้น แทน tools.call(...)
  • การเรียกซ้อนส่งต่อผ่านพาธตัวดำเนินการ OpenClaw เดียวกับที่การค้นหา เครื่องมือใช้

ดู การค้นหาเครื่องมือ สำหรับบริดจ์แค็ตตาล็อกแบบกระชับของ OpenClaw ซึ่งโหมดโค้ดใช้แทนในการรันที่เปิดใช้งาน

ชื่อเครื่องมือและการชนกัน

เครื่องมือ exec ที่โมเดลมองเห็นได้คือเครื่องมือโหมดโค้ด หากเปิดใช้งานเครื่องมือเชลล์ exec ตามปกติของ OpenClaw เครื่องมือนี้จะถูกซ่อนจากโมเดลและจัดเข้าแค็ตตาล็อกเหมือน เครื่องมืออื่นๆ

ภายในรันไทม์ของเกสต์:

  • tools.call("openclaw:core:exec", input) สามารถเรียกเครื่องมือเชลล์ exec ได้หาก นโยบายอนุญาต
  • tools.exec(...) จะถูกติดตั้งเฉพาะเมื่อรายการเชลล์ exec ในแค็ตตาล็อกมี ชื่อที่ปลอดภัยและไม่กำกวม
  • เครื่องมือโหมดโค้ด exec จะไม่สามารถเรียกซ้ำผ่าน tools ได้

หากเครื่องมือสองรายการถูกปรับให้เป็นชื่ออำนวยความสะดวกที่ปลอดภัยชื่อเดียวกัน OpenClaw จะละเว้น ฟังก์ชันอำนวยความสะดวกและกำหนดให้ใช้ tools.call(id, input)

การเรียกใช้เครื่องมือซ้อน

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

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

อนุญาตการเรียกซ้อนแบบขนานได้สูงสุด maxPendingToolCalls

วงจรชีวิตการรันและสแนปช็อต

การรันโหมดโค้ดแต่ละครั้งถูกติดตามในแมปภายในโปรเซสโดยใช้ runId เป็นคีย์ (ไม่ บันทึกลงดิสก์หรือฐานข้อมูล) exec/wait ส่งคืนสถานะผลลัพธ์หนึ่งในสามแบบ: completed, waiting หรือ failed

  • ผลลัพธ์ waiting เก็บสแนปช็อต QuickJS คำขอบริดจ์ที่รอดำเนินการ และ เมทาดาทาขอบเขต (รหัสการรันของเอเจนต์ รหัส/คีย์เซสชัน) ไว้จนกว่า wait จะดำเนินต่อหรือ หมดอายุ
  • การหมดอายุ เซสชันผิด การรันผิด และค่า runId ที่ไม่รู้จัก/กำลังดำเนินต่อแล้ว จะไม่สร้างสถานะสิ้นสุดที่แยกต่างหาก แต่จะแสดงเป็น ผลลัพธ์ failed (code: "invalid_input") พร้อมข้อความ เช่น code mode run is unavailable or expired. หรือ code mode run belongs to a different session.
  • สแนปช็อตของการรันจะถูกลบออกจากแมปทันทีที่สิ้นสุดเป็น completed หรือ failed หรือถูกทิ้งเมื่อ Gateway ปิดตัว (ไม่มีสิ่งใด คงอยู่หลังการรีสตาร์ต เนื่องจากเป็นสถานะรันไทม์ชั่วคราว)
  • สำหรับงานแบบอ่านอย่างเดียว exec สามารถตั้งค่า restartSafe: true จากนั้น OpenClaw จะปฏิเสธ การเรียกแค็ตตาล็อกและเนมสเปซ Plugin ที่มีผลข้างเคียงก่อนดำเนินการ และ ทำเครื่องหมายผลลัพธ์ที่ถูกระงับว่าปลอดภัยสำหรับการเล่นซ้ำ หากการรีสตาร์ตขัดจังหวะ wait, การกู้คืนหลังรีสตาร์ต จะสร้างเทิร์นขึ้นใหม่จาก ทรานสคริปต์ แทนการกู้คืนสแนปช็อตภายในโปรเซส ตัวเทิร์นการกู้คืนเอง ยังคงจำกัดเฉพาะเครื่องมือหลักแบบอ่านอย่างเดียวที่ผ่านการตรวจสอบและเครื่องมือ Plugin ที่ระบุอย่างชัดเจนว่าปลอดภัยสำหรับการเล่นซ้ำ
  • OpenClaw จำกัดจำนวนการรันที่ถูกระงับพร้อมกันต่อโปรเซสไว้ที่ (64) และ ปฏิเสธการระงับใหม่ที่เกินขีดจำกัดดังกล่าวด้วย too many suspended code mode runs.

พื้นที่จัดเก็บสแนปช็อตถูกจำกัดด้วย maxSnapshotBytes ต่อการรัน ขีดจำกัดการรัน ที่ถูกระงับต่อโปรเซสข้างต้น และ snapshotTtlSeconds

รันไทม์ QuickJS-WASI

OpenClaw โหลด quickjs-wasi เป็นการขึ้นต่อกันโดยตรงในแพ็กเกจเจ้าของ โดย ไม่พึ่งพาสำเนาแบบส่งผ่านที่ติดตั้งไว้สำหรับการขึ้นต่อกันที่ไม่เกี่ยวข้อง

ความรับผิดชอบของรันไทม์: คอมไพล์/โหลดโมดูล WebAssembly ของ QuickJS-WASI สร้าง VM แยกหนึ่งรายการต่อการรันหรือการดำเนินต่อของโหมดโค้ด ลงทะเบียนคอลแบ็กโฮสต์ ด้วยชื่อที่เสถียร ตั้งค่าขีดจำกัดหน่วยความจำและการขัดจังหวะ ประเมิน JavaScript ระบาย งานที่รอดำเนินการ ทำสแนปช็อตสถานะ VM ที่ถูกระงับ กู้คืนสแนปช็อตสำหรับ wait และกำจัดแฮนเดิล VM กับสแนปช็อตหลังจากสถานะสิ้นสุด

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

TypeScript

การรองรับ TypeScript เป็นเพียงการแปลงซอร์ส: อินพุตที่ยอมรับคือสตริงโค้ด TypeScript หนึ่งรายการ เอาต์พุตคือสตริง JavaScript ที่ QuickJS-WASI ประเมินผล ไม่มีการตรวจสอบชนิด ไม่มีการแก้ไขโมดูล และไม่มี import/require การวินิจฉัยจะถูกส่งคืนเป็นผลลัพธ์ failed

คอมไพเลอร์ TypeScript จะโหลดแบบล่าช้าเฉพาะเซลล์ TypeScript เท่านั้น เซลล์ JavaScript ธรรมดาและโหมดโค้ดที่ปิดใช้งานจะไม่โหลดคอมไพเลอร์

ขอบเขตความปลอดภัย

โค้ดของโมเดลถือว่าเป็นภัยคุกคาม รันไทม์ใช้การป้องกันหลายชั้น:

  • รัน QuickJS-WASI นอกลูปเหตุการณ์หลัก ในเธรดผู้ปฏิบัติงาน
  • โหลด quickjs-wasi เป็นการขึ้นต่อกันโดยตรง ไม่ผ่าน Codex หรือ แพ็กเกจแบบส่งผ่าน
  • ไม่มีระบบไฟล์ เครือข่าย โปรเซสย่อย การนำเข้าโมดูล ตัวแปรสภาพแวดล้อม หรือออบเจ็กต์โกลบอลของโฮสต์ภายในเกสต์
  • ใช้ขีดจำกัดหน่วยความจำและการขัดจังหวะของ QuickJS ร่วมกับการหมดเวลา ตามเวลาจริงของโปรเซสแม่
  • บังคับใช้ขีดจำกัดเอาต์พุต สแนปช็อต บันทึก และการเรียกที่รอดำเนินการ
  • ทำให้ค่าบริดจ์ของโฮสต์เป็นอนุกรมผ่านอะแดปเตอร์ JSON ที่จำกัด
  • แปลงข้อผิดพลาดของโฮสต์เป็นข้อผิดพลาดธรรมดาของเกสต์ โดยไม่ส่งออบเจ็กต์จากขอบเขตโฮสต์
  • ทิ้งสแนปช็อตเมื่อหมดเวลา ถูกยกเลิก เซสชันสิ้นสุด หรือหมดอายุ
  • ปฏิเสธการเข้าถึงแบบเรียกซ้ำไปยัง exec, wait และเครื่องมือควบคุมการค้นหาเครื่องมือ
  • ป้องกันไม่ให้การชนกันของชื่ออำนวยความสะดวกบดบังตัวช่วยแค็ตตาล็อก

แซนด์บ็อกซ์เป็นชั้นความปลอดภัยหนึ่งชั้น ผู้ดำเนินการอาจยังต้องใช้ การเสริมความแข็งแกร่งระดับระบบปฏิบัติการสำหรับการติดตั้งใช้งานที่มีความเสี่ยงสูง

รหัสข้อผิดพลาด

typescript
type CodeModeErrorCode =  | "invalid_input"  | "runtime_unavailable"  | "timeout"  | "output_limit_exceeded"  | "snapshot_limit_exceeded"  | "internal_error";

invalid_input ครอบคลุมอาร์กิวเมนต์ exec/wait ที่ไม่ถูกต้อง ภาษาที่ปิดใช้งาน การเข้าถึงโมดูลที่ถูกปฏิเสธ ความล้มเหลวในการแปลง TypeScript ค่า runId ที่ไม่รู้จัก/หมดอายุ/อยู่นอกขอบเขต และการรันที่ถูกระงับมากเกินไป runtime_unavailable ครอบคลุมผู้ปฏิบัติงาน QuickJS ที่เริ่มทำงานไม่สำเร็จหรือออกด้วยสถานะไม่เป็นศูนย์

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

เทเลเมทรี

ฟิลด์ telemetry ของแต่ละผลลัพธ์รายงาน: ขนาดแค็ตตาล็อกที่ซ่อนอยู่และการแจกแจง ตามแหล่งที่มา (จำนวน openclaw/mcp/client) จำนวนการค้นหา/อธิบาย/เรียกใช้ สะสมสำหรับแค็ตตาล็อกของการรัน และชื่อเครื่องมือที่โมเดลมองเห็นได้ (exec, wait และเครื่องมือที่เรียกโดยตรงเท่านั้นซึ่งเก็บไว้)

เทเลเมทรีต้องไม่มีข้อมูลลับ ค่าสภาพแวดล้อมดิบ หรืออินพุตเครื่องมือที่ไม่ได้ปกปิด นอกเหนือจากนโยบายเส้นทางที่มีอยู่ของ OpenClaw

การแก้จุดบกพร่อง

ใช้การบันทึกการขนส่งของโมเดลแบบเจาะจง เมื่อโหมดโค้ดทำงานแตกต่างจาก การรันเครื่องมือตามปกติ:

bash
OPENCLAW_DEBUG_CODE_MODE=1 \OPENCLAW_DEBUG_MODEL_TRANSPORT=1 \OPENCLAW_DEBUG_MODEL_PAYLOAD=tools \OPENCLAW_DEBUG_SSE=events \openclaw gateway

สำหรับการดีบักรูปแบบ payload ให้ใช้ OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted คำสั่งนี้จะบันทึกสแนปช็อต JSON ของคำขอโมเดลที่ผ่านการปกปิดข้อมูลและจำกัดขนาดไว้แล้ว ให้ใช้เฉพาะ ระหว่างการดีบักเท่านั้น เนื่องจากพรอมป์และข้อความในสารยังอาจปรากฏอยู่

สำหรับการดีบักสตรีม ให้ใช้ OPENCLAW_DEBUG_SSE=peek เพื่อบันทึกเหตุการณ์ SSE 5 รายการแรก ที่ผ่านการปกปิดข้อมูลแล้ว Code mode จะปฏิเสธการทำงานเช่นกัน หาก payload สุดท้ายของผู้ให้บริการ ไม่มี exec จำนวนหนึ่งรายการ, wait จำนวนหนึ่งรายการ และมีเฉพาะเครื่องมือ แบบ direct-only ที่ได้รับอนุมัติ หลังจากพื้นผิว Code mode เปิดใช้งานแล้ว

โครงสร้างการใช้งาน

  • สัญญาการกำหนดค่า: tools.codeMode
  • ตัวสร้างแค็ตตาล็อก: แปลงเครื่องมือที่มีผลเป็นรายการแบบย่อและแมป id
  • อะแดปเตอร์พื้นผิวโมเดล: แทนที่เครื่องมือที่มองเห็นได้ด้วยเครื่องมือควบคุม/เครื่องมือโดยตรง
  • อะแดปเตอร์รันไทม์ QuickJS-WASI: โหลด ประเมิน สร้างสแนปช็อต กู้คืน และกำจัด
  • ตัวควบคุม worker: การหมดเวลา การยกเลิก และการแยกความขัดข้อง
  • อะแดปเตอร์บริดจ์: คอลแบ็กโฮสต์ที่ปลอดภัยสำหรับ JSON และการส่งมอบผลลัพธ์
  • อะแดปเตอร์แปลง TypeScript
  • ที่เก็บสแนปช็อต: TTL ขีดจำกัดขนาด และการกำหนดขอบเขตตามรอบการทำงาน/เซสชัน
  • การฉายวิถีสำหรับการเรียกเครื่องมือแบบซ้อน
  • ตัวนับเทเลเมทรีและการวินิจฉัย

การใช้งานนี้นำแนวคิดแค็ตตาล็อกและตัวดำเนินการจาก Tool Search มาใช้ซ้ำ แต่ ไม่ได้ใช้ลูก node:vm เป็นแซนด์บ็อกซ์

รายการตรวจสอบการตรวจสอบความถูกต้อง

ความครอบคลุมของ Code mode ควรพิสูจน์ว่า:

  • การกำหนดค่าที่ปิดใช้งานจะไม่เปลี่ยนการเปิดเผยเครื่องมือที่มีอยู่
  • การกำหนดค่าแบบออบเจ็กต์ที่ไม่มี enabled: true จะยังคงปิดใช้งาน Code mode
  • การกำหนดค่าที่เปิดใช้งานจะเปิดเผย exec, wait และเฉพาะเครื่องมือ direct-only ที่จำเป็น ให้แก่โมเดลเมื่อเครื่องมือทำงานอยู่ในรอบการทำงาน
  • รอบการทำงานแบบดิบที่ไม่มีเครื่องมือ, disableTools และรายการอนุญาตที่ว่างเปล่า จะไม่ทริกเกอร์ การบังคับใช้ payload ของ Code mode
  • เครื่องมือที่มีผลซึ่งไม่ใช่ MCP และมีสิทธิ์อยู่ในแค็ตตาล็อกทั้งหมดจะปรากฏใน ALL_TOOLS
  • เครื่องมือ direct-only จะยังคงมองเห็นได้สำหรับโมเดลและไม่ปรากฏใน ALL_TOOLS
  • เครื่องมือที่ถูกปฏิเสธจะไม่ปรากฏใน ALL_TOOLS
  • tools.search, tools.describe, tools.callValue และ tools.call ใช้งานกับเครื่องมือ OpenClaw ได้
  • API.list("mcp") และ API.read("mcp/<server>.d.ts") เปิดเผย การประกาศ MCP ในรูปแบบ TypeScript โดยไม่มีการเรียกบริดจ์/เครื่องมือ
  • เนมสเปซ MCP $api() ยังคงพร้อมใช้งานเป็นทางเลือกสำรองแบบอินไลน์สำหรับสคีมา
  • การเรียกเนมสเปซ MCP ใช้งานได้กับเครื่องมือ MCP ที่มองเห็นได้โดยใช้อินพุตออบเจ็กต์หนึ่งรายการ ขณะที่ ไม่มีรายการแค็ตตาล็อก MCP โดยตรงใน tools.*
  • เครื่องมือควบคุมของ Tool Search ถูกซ่อนจากทั้งพื้นผิวโมเดลและ แค็ตตาล็อกที่ซ่อนอยู่
  • การเรียกแบบซ้อนจะรักษาพฤติกรรมการอนุมัติและฮุกไว้
  • เชลล์ exec ถูกซ่อนจากโมเดล แต่เรียกได้ด้วย id ของแค็ตตาล็อกเมื่อ ได้รับอนุญาต
  • Code mode แบบเรียกซ้ำ exec และ wait ไม่สามารถเรียกจากโค้ด guest ได้
  • อินพุต TypeScript ถูกแปลงและประเมินโดยไม่โหลด TypeScript ใน เส้นทางที่ปิดใช้งานหรือเส้นทาง JavaScript-only
  • การเข้าถึง import, require, ระบบไฟล์ เครือข่าย และสภาพแวดล้อมจะล้มเหลว
  • ลูปไม่สิ้นสุดจะหมดเวลาและไม่สามารถบล็อก Gateway ได้
  • ความล้มเหลวจากขีดจำกัดหน่วยความจำจะยุติ VM ของ guest
  • มีการบังคับใช้ขีดจำกัดเอาต์พุตและสแนปช็อตกับการเรียกที่เสร็จสมบูรณ์และถูกพักไว้
  • wait ดำเนินการต่อจากสแนปช็อตที่ถูกพักไว้และส่งคืนค่าสุดท้าย
  • ค่า runId ที่หมดอายุ ถูกยกเลิก อยู่ผิดเซสชัน และไม่รู้จักจะล้มเหลว
  • การเล่นทรานสคริปต์ซ้ำและการคงอยู่จะรักษาการเรียกควบคุมของ Code mode
  • ทรานสคริปต์และเทเลเมทรีแสดงการเรียกเครื่องมือแบบซ้อนอย่างชัดเจน

แผนการทดสอบ E2E

เรียกใช้รายการเหล่านี้เป็นการทดสอบการผสานรวมหรือการทดสอบตั้งแต่ต้นจนจบเมื่อเปลี่ยนรันไทม์:

  1. เริ่ม Gateway ด้วย tools.codeMode.enabled: false
  2. ส่งรอบการทำงานของเอเจนต์พร้อมชุดเครื่องมือโดยตรงขนาดเล็ก
  3. ยืนยันว่าเครื่องมือที่โมเดลมองเห็นไม่มีการเปลี่ยนแปลง
  4. เริ่มระบบใหม่ด้วย tools.codeMode.enabled: true
  5. ส่งรอบการทำงานของเอเจนต์พร้อมเครื่องมือทดสอบ OpenClaw, Plugin, MCP และไคลเอ็นต์
  6. ยืนยันว่ารายการเครื่องมือที่โมเดลมองเห็นคือ exec, wait และมีเฉพาะเครื่องมือ direct-only ที่กำหนดค่าไว้
  7. ใน exec ให้อ่าน ALL_TOOLS และยืนยันว่าเครื่องมือทดสอบที่มีผลและมีสิทธิ์อยู่ในแค็ตตาล็อก ปรากฏอยู่ ขณะที่ไม่มีเครื่องมือ direct-only
  8. ใน exec ให้เรียกเครื่องมือ OpenClaw/Plugin/ไคลเอ็นต์ผ่าน tools.search, tools.describe และ tools.callValue (หรือ tools.call แบบดิบ)
  9. ใน exec ให้เรียก API.list("mcp") และ API.read("mcp/<server>.d.ts") และ ยืนยันว่าไฟล์การประกาศอธิบายเครื่องมือ MCP ที่มองเห็นได้
  10. ใน exec ให้เรียกเครื่องมือ MCP ผ่าน MCP.<server>.<tool>({ ...input }) และ ยืนยันว่าไม่มีรายการแค็ตตาล็อก MCP โดยตรงใน ALL_TOOLS และ tools.*
  11. ยืนยันว่าเครื่องมือที่ถูกปฏิเสธไม่มีอยู่และไม่สามารถเรียกด้วย id ที่คาดเดาได้
  12. เริ่มการเรียกเครื่องมือแบบซ้อนที่เสร็จสิ้นหลังจาก exec ส่งคืน waiting
  13. เรียก wait และยืนยันว่า VM ที่กู้คืนได้รับผลลัพธ์จากเครื่องมือ
  14. ยืนยันว่าคำตอบสุดท้ายมีเอาต์พุตที่สร้างขึ้นหลังการกู้คืน
  15. ยืนยันว่าการหมดเวลา การยกเลิก และการหมดอายุของสแนปช็อตจะล้างสถานะรันไทม์
  16. ส่งออกวิถีและยืนยันว่าการเรียกแบบซ้อนมองเห็นได้ภายใต้การเรียก Code mode ระดับแม่

การเปลี่ยนแปลงเฉพาะเอกสารในหน้านี้ยังคงควรเรียกใช้ pnpm check:docs

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

Was this useful?
On this page

On this page