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
เริ่มต้นใช้งานอย่างรวดเร็ว
เปิดใช้โหมดโค้ด
{ tools: { codeMode: { enabled: true, }, },}รูปแบบย่อ:
{ tools: { codeMode: true, },}โหมดโค้ดจะยังคงปิดเมื่อไม่ระบุ tools.codeMode, เป็น false หรือเป็นออบเจ็กต์
ที่ไม่มี enabled: true
หากใช้เอเจนต์แบบแซนด์บ็อกซ์ร่วมกับเซิร์ฟเวอร์ MCP ที่กำหนดค่าไว้ ให้อนุญาต
Plugin MCP ที่รวมมาให้ในนโยบายเครื่องมือของแซนด์บ็อกซ์ด้วย เช่น
tools.sandbox.tools.alsoAllow: ["bundle-mcp"] ดู
การกำหนดค่า - เครื่องมือและผู้ให้บริการแบบกำหนดเอง
กำหนดขีดจำกัดอย่างชัดเจนเพื่อให้ข้อจำกัดรัดกุมยิ่งขึ้น:
{ 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 โปรแกรมเดียวสามารถ
เลือก เรียกใช้ และแปลงเครื่องมือนั้นได้:
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 พร้อม การบันทึกล็อกแบบเจาะจง:
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 จะล้มเหลวแบบปิด สำหรับการรันนั้น โดยจะไม่เปิดเผยเครื่องมือปกติเป็นทางเลือกสำรองอย่างเงียบๆ
การเปิดใช้งาน
โหมดโค้ดจะได้รับการประเมินหลังจากทราบนโยบายเครื่องมือที่มีผลแล้ว และก่อน ประกอบคำขอสุดท้ายสำหรับโมเดล:
- ระบุเอเจนต์ โมเดล ผู้ให้บริการ แซนด์บ็อกซ์ ช่องทาง ผู้ส่ง และนโยบาย การรัน
- สร้างรายการเครื่องมือ OpenClaw ที่มีผล โดยเพิ่มเครื่องมือ Plugin, MCP และ ไคลเอนต์ที่เข้าเกณฑ์
- ใช้นโยบายอนุญาต/ปฏิเสธ
- หาก
tools.codeMode.enabledเป็น false ให้เปิดเผยเครื่องมือตามปกติต่อไป - หากเปิดใช้งานและมีเครื่องมือที่ทำงานสำหรับการรัน ให้คงเครื่องมือ direct-only ที่จำเป็นไว้ และลงทะเบียนเครื่องมือที่มีผลซึ่งเข้าเกณฑ์แค็ตตาล็อกทุกรายการในแค็ตตาล็อก โหมดโค้ด
- นำเครื่องมือที่ลงแค็ตตาล็อกแล้วออกจากรายการที่โมเดลมองเห็น และเพิ่ม
execกับwaitควบคู่กับเครื่องมือ direct-only ที่คงไว้
การรันที่ตั้งใจไม่ให้มีเครื่องมือ (การเรียกโมเดลดิบ, disableTools: true
หรือรายการ tools.allow ที่ว่าง) จะไม่เปิดใช้งานพื้นผิวโหมดโค้ด แม้
จะกำหนดค่า tools.codeMode.enabled: true ไว้ โหมดโค้ดและการค้นหาเครื่องมือของ OpenClaw
ใช้ร่วมกันไม่ได้ในการรันเดียว หากโหมดโค้ดเปิดใช้งาน Compaction ของการค้นหาเครื่องมือ
จะไม่ทำงาน
แค็ตตาล็อกโหมดโค้ดมีขอบเขตเฉพาะการรัน และต้องไม่ทำให้เครื่องมือจาก เอเจนต์ เซสชัน ผู้ส่ง หรือการรันอื่นรั่วไหลเข้ามา
เครื่องมือที่โมเดลมองเห็น
เมื่อโหมดโค้ดทำงาน โมเดลจะเห็น exec, wait และเครื่องมือ
direct-only ที่จำเป็น เครื่องมืออื่นทุกตัวที่เปิดใช้งานจะถูกซ่อนจากรายการเครื่องมือ
ที่แสดงต่อโมเดล และลงทะเบียนในแค็ตตาล็อกโหมดโค้ด
ใช้ exec สำหรับการประสานงานเครื่องมือ การรวมข้อมูล ลูป การเรียกซ้อนแบบขนาน
และการแปลงข้อมูลแบบมีโครงสร้าง ใช้ wait เฉพาะเมื่อ exec ส่งคืนผลลัพธ์
waiting ที่ดำเนินการต่อได้
exec
exec เริ่มเซลล์โหมดโค้ดและส่งคืนผลลัพธ์หนึ่งรายการ โค้ดอินพุตสร้างโดยโมเดล
และต้องถือว่าเป็นอันตราย
อินพุต:
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-loaderexecจะไม่เปิดเผยการติดตั้งใช้งาน shellexecปกติแบบเรียกซ้ำ- เหตุการณ์ hook
execของโหมดโค้ดชั้นนอกมีtoolKind: "code_mode_exec"และtoolInputKind: "javascript" | "typescript"(เมื่อทราบ) เพื่อให้นโยบายสามารถ แยกเซลล์โหมดโค้ดออกจากการเรียกexecแบบ shell ซึ่งใช้ ชื่อเครื่องมือเดียวกัน
ผลลัพธ์:
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 โหมดโค้ดที่พักการทำงานไว้
อินพุต:
type CodeModeWaitInput = { runId: string;};เอาต์พุตเป็นยูเนียน CodeModeResult เดียวกับที่ exec ส่งคืน
wait มีอยู่เนื่องจากเครื่องมือ OpenClaw ที่ซ้อนกันอาจทำงานช้า โต้ตอบได้
ถูกควบคุมด้วยการอนุมัติ หรือสตรีมการอัปเดตบางส่วน โมเดลไม่ควรต้องเปิด
การเรียก exec ที่ยาวไว้ขณะที่โฮสต์รอการทำงานภายนอก
QuickJS-WASI snapshot/restore คือกลไกการดำเนินการต่อ:
execประเมินโค้ดจนเสร็จสิ้น ล้มเหลว หรือพักการทำงาน- เมื่อพักการทำงาน OpenClaw จะสร้างสแนปช็อตของ QuickJS VM และบันทึกงาน ของโฮสต์ที่ค้างอยู่
- เมื่องานที่ค้างอยู่เสร็จสิ้น
waitจะกู้คืนสแนปช็อต VM และ ลงทะเบียน callback ของโฮสต์อีกครั้งด้วยชื่อที่คงที่ - OpenClaw ส่งผลลัพธ์ของเครื่องมือที่ซ้อนกันเข้าสู่ VM ที่กู้คืนแล้ว และระบาย งานที่ค้างอยู่ของ QuickJS
waitส่งคืนcompleted,failedหรือผลลัพธ์waitingอื่น
สแนปช็อตเป็นสถานะรันไทม์ ไม่ใช่อาร์ติแฟกต์ของผู้ใช้ โดยอยู่เฉพาะใน แมปภายในโปรเซส (ไม่มีการเขียนฐานข้อมูลหรือดิสก์) มีการจำกัดขนาด หมดอายุได้ และมี ขอบเขตเฉพาะการรันและเซสชันที่สร้างสแนปช็อตนั้น
wait ล้มเหลว (ในรูปผลลัพธ์ failed) เมื่อ:
- ไม่รู้จัก
runIdหรือสแนปช็อตหมดอายุแล้ว - ผู้เรียกไม่ได้อยู่ในขอบเขตการรัน/เซสชันเดียวกับการรันที่พักไว้
- มี
waitกำลังทำงานอยู่แล้วสำหรับrunIdนั้น - การกู้คืน QuickJS-WASI ล้มเหลว
- การดำเนินการต่อจะเกิน
maxOutputBytesหรือmaxSnapshotBytes
API รันไทม์ของเกสต์
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 ภายหลังแทนการเดาชื่อฟิลด์ หลักการนี้ยัง
ใช้เมื่อการอ่านเอาต์พุตที่ประกาศไว้ส่งต่อไปยังการเรียก -> ? ขั้นสุดท้าย: ให้ส่งคืน
ค่าดิบของการเรียกนั้นโดยไม่ห่อด้วยรูปแบบคำตอบที่ร้องขอ
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.* โปรดดูด้านล่าง)
สคีมาเต็มจะโหลดเมื่อร้องขอเท่านั้น:
type ToolCatalogEntryWithSchema = ToolCatalogEntry & { parameters: unknown; outputSchema?: unknown;};ตัวช่วยแค็ตตาล็อก:
type ToolCatalog = { search(query: string, options?: { limit?: number }): Promise<ToolCatalogEntry[]>; describe(id: string): Promise<ToolCatalogEntryWithSchema>; callValue(id: string, input?: unknown): Promise<unknown>; call(id: string, input?: unknown): Promise<unknown>; [safeToolName: string]: unknown;};ฟังก์ชันเครื่องมือเพื่อความสะดวกจะติดตั้งเฉพาะชื่อที่ปลอดภัยและไม่กำกวม:
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:
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 เมื่อดัชนีด่วนประกาศฟิลด์ เซลล์เดียวสามารถรวมการค้นหาและการส่งมอบ
โดยไม่ต้องใช้รอบตรวจสอบแยกต่างหาก:
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 ลงในพรอมต์:
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:
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<McpApiHeader>; /** * สร้าง issue ใน GitHub * @param owner เจ้าของรีโพซิทอรี * @param repo ชื่อรีโพซิทอรี * @param title ชื่อ issue */ function createIssue(input: { owner: string; repo: string; title: string; body?: string; }): Promise<McpToolResult>;}ไฟล์ประกาศเป็นไฟล์เสมือน ไม่ได้เขียนไว้ใต้ไดเรกทอรีเวิร์กสเปซหรือสถานะ
สำหรับการเรียก 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:
const open = await Issues.list({ state: "open" });const alsoOpen = await namespaces.Issues.list({ state: "open" });return { count: open.length, alsoCount: alsoOpen.length };วงจรชีวิตของรีจิสทรี
รีจิสทรีเนมสเปซอยู่ภายในโปรเซสและใช้ ID เนมสเปซเป็นคีย์:
- โหลดเดอร์ที่เชื่อถือได้เรียก
registerCodeModeNamespaceForPlugin(pluginId, registration) - โหมดโค้ดสร้าง
ToolSearchRuntimeที่ซ่อนไว้สำหรับการรันและอ่าน แค็ตตาล็อกตามขอบเขตการรันของรายการนั้น createCodeModeNamespaceRuntime(ctx, catalog)เก็บเฉพาะการลงทะเบียน ที่requiredToolNamesทั้งหมดมองเห็นได้และเป็นของpluginIdเดียวกัน- แต่ละเนมสเปซที่มองเห็นได้เรียก
createScope(ctx)สำหรับการรันปัจจุบัน โดยรับบริบทการรัน เช่นagentId,sessionKey,sessionId,runId, การกำหนดค่า และสถานะยกเลิก - ข้อมูลขอบเขตถูกทำซีเรียลไลซ์เป็นตัวอธิบายแบบธรรมดาและแทรกลงใน QuickJS
เป็นโกลบอลโดยตรงและ
namespaces.<globalName> - การเรียกของเกสต์หยุดรอผ่านบริดจ์เวิร์กเกอร์ แก้ไขพาธเนมสเปซ
บนโฮสต์ แมปการเรียกไปยังเครื่องมือแค็ตตาล็อกที่ประกาศและ Plugin เป็นเจ้าของ
แล้วเรียกใช้เครื่องมือนั้นผ่าน
ToolSearchRuntime.callExactId - การเรียกบริดจ์เนมสเปซที่พร้อมจะถูกระบายโดยอัตโนมัติภายในการเรียก
exec/waitที่ใช้งานอยู่; หากงานเนมสเปซยังค้างอยู่เมื่อหมดเวลา หรือเกสต์ยอมคืนการทำงานอย่างชัดเจนwaitจะดำเนินรันไทม์เนมสเปซเดิม ต่อในภายหลัง - การย้อนกลับหรือถอนการติดตั้ง Plugin จะเรียก
clearCodeModeNamespacesForPlugin(pluginId)เพื่อไม่ให้โกลบอลที่ล้าสมัย คงอยู่หลังการโหลด Plugin ล้มเหลว
การเรียกเนมสเปซคือการเรียกเครื่องมือแค็ตตาล็อก โดยใช้นโยบาย ฮุก
การอนุมัติ การจัดการการยกเลิก เทเลเมทรี การฉายทรานสคริปต์ และพฤติกรรม
หยุดรอ/ดำเนินการต่อแบบเดียวกับ tools.call(...)
รูปแบบการลงทะเบียน
ลงทะเบียนเนมสเปซจากอินทิเกรชันที่เป็นเจ้าของเครื่องมือเบื้องหลัง จำกัดขอบเขต ให้เล็กและเปิดเผยเฉพาะกริยาของโดเมนที่แมปกับเครื่องมือแค็ตตาล็อกที่ประกาศไว้
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 ซึ่งเป็นตัวเลือกจะรับอาร์กิวเมนต์
ของเกสต์และส่งคืนออบเจ็กต์อินพุตสำหรับเครื่องมือแค็ตตาล็อกเบื้องหลัง; หากไม่มี
จะใช้อาร์กิวเมนต์แรกของเกสต์ หรือใช้ {} เมื่อไม่ได้ระบุ
ฟังก์ชันโฮสต์ดิบจะถูกปฏิเสธก่อนโค้ดเกสต์ทำงาน:
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 ที่โมเดลมองเห็นเฉพาะเมื่อเนมสเปซมองเห็นได้สำหรับการรันนั้น ใช้
สิ่งเหล่านี้เพื่อสอนพื้นผิวที่มีประโยชน์ขนาดเล็กที่สุด:
{ description: "ตัวช่วยสำหรับบริการผลิตนิยาย", prompt: "ใช้ Fictions.riskAudit(), Fictions.promoteIfReady(id, status) และ Fictions.unpaidOver(amount)",}กำหนดให้พรอมต์กล่าวถึงสัญญาของเนมสเปซ ไม่ใช่การตั้งค่าการยืนยันตัวตน ประวัติการติดตั้งใช้งาน หรือพฤติกรรมของ Plugin ที่ไม่เกี่ยวข้อง
การล้างข้อมูล
เนมสเปซเป็นการลงทะเบียนภายในโปรเซส ให้ลบออกเมื่อ Plugin เจ้าของ ถูกปิดใช้งาน ถอนการติดตั้ง หรือย้อนกลับ:
clearCodeModeNamespacesForPlugin(pluginId);การล้างข้อมูลโหมดโค้ดเป็นหน้าที่ของ Plugin ให้ล้างการลงทะเบียนเนมสเปซของ Plugin
เมื่อวงจรชีวิตสิ้นสุดลง แทนที่จะเก็บแฮนเดิลสำหรับรื้อถอนแยกตามเนมสเปซ
การทดสอบสามารถเรียก clearCodeModeNamespacesForTest() เพื่อหลีกเลี่ยงการรั่วไหลของ
การลงทะเบียนระหว่างกรณีทดสอบ
รายการตรวจสอบการทดสอบ
การเปลี่ยนแปลงเนมสเปซควรครอบคลุมขอบเขตความปลอดภัยและพฤติกรรมของเกสต์:
- ข้อความพรอมต์ของเนมสเปซปรากฏเฉพาะเมื่อมองเห็นเครื่องมือเบื้องหลัง
- เครื่องมือชื่อเดียวกันจาก
sourceNameอื่นต้องไม่เปิดเผยเนมสเปซ - ฟังก์ชันขอบเขตดิบถูกปฏิเสธ
- รหัสเนมสเปซปลอมและพาธปลอมถูกปฏิเสธ
- พาธที่เรียกได้ต้องไม่กำหนดเป้าหมายไปยังเครื่องมือที่ไม่ได้ประกาศ
- ออบเจ็กต์ซ้อนและการอ้างอิงร่วมถูกทำให้เป็นอนุกรมอย่างถูกต้อง
- การเรียกเนมสเปซทำงานผ่านเครื่องมือในแค็ตตาล็อกและส่งคืนรายละเอียดที่ปลอดภัยสำหรับ JSON
- โค้ดเกสต์สามารถดักจับความล้มเหลวได้
- การเรียกเนมสเปซที่ถูกระงับดำเนินต่อผ่าน
wait - การย้อนกลับ Plugin ล้างการลงทะเบียนเนมสเปซของเจ้าของ
เนมสเปซช่วยเสริมแค็ตตาล็อก tools.search/tools.call แบบทั่วไป: ใช้
แค็ตตาล็อกสำหรับเครื่องมือ OpenClaw, Plugin และไคลเอนต์ที่เปิดใช้งานโดยพลการ ใช้ MCP
สำหรับเครื่องมือ MCP และใช้เนมสเปซอื่นสำหรับ API โดเมนที่มีเอกสารกำกับและ Plugin เป็นเจ้าของ
เมื่อโค้ดที่กระชับเชื่อถือได้มากกว่าการค้นหาสคีมาซ้ำๆ
API เอาต์พุต
text(value)เพิ่มเอาต์พุตที่มนุษย์อ่านได้ต่อท้ายอาร์เรย์outputjson(value)เพิ่มรายการเอาต์พุตแบบมีโครงสร้างต่อท้ายหลังจาก ทำให้เป็นอนุกรมที่เข้ากันได้กับ JSON- ค่าสุดท้ายที่โค้ดเกสต์ส่งคืนจะกลายเป็น
valueในผลลัพธ์completed
type CodeModeOutput = { type: "text"; text: string } | { type: "json"; value: unknown };กฎ: ลำดับเอาต์พุตตรงกับลำดับการเรียกของเกสต์ เอาต์พุตถูกจำกัดด้วย
maxOutputBytes ค่าที่ทำให้เป็นอนุกรมไม่ได้จะถูกแปลงเป็นสตริงธรรมดาหรือ
ข้อผิดพลาด ไม่รองรับค่าไบนารี รูปภาพและไฟล์ส่งผ่าน
เครื่องมือ OpenClaw ตามปกติ ไม่ใช่ผ่านบริดจ์โหมดโค้ด
แค็ตตาล็อกเครื่องมือ
แค็ตตาล็อกที่ซ่อนไว้ประกอบด้วยเครื่องมือหลังการกรองตามนโยบายที่มีผล ตามลำดับ ดังนี้: เครื่องมือหลักของ OpenClaw, เครื่องมือ Plugin ที่รวมมาให้, เครื่องมือ Plugin ภายนอก, เครื่องมือ MCP แล้วจึงเป็นเครื่องมือที่ไคลเอนต์จัดเตรียมให้สำหรับการรันปัจจุบัน
รหัสแค็ตตาล็อกมีความเสถียรภายในการรันหนึ่งครั้งและกำหนดได้แน่นอนสำหรับ ชุดเครื่องมือที่เทียบเท่ากันเมื่อเป็นไปได้ รูปแบบจริง:
<source>:<owner>:<tool-name>โดย <source> คือ openclaw, mcp หรือ client (เครื่องมือ Plugin ใช้
openclaw โดยมีรหัส Plugin เป็น <owner> ส่วนเครื่องมือหลักใช้ openclaw:core:*)
ตัวอย่าง:
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และเครื่องมือควบคุมการค้นหาเครื่องมือ - ป้องกันไม่ให้การชนกันของชื่ออำนวยความสะดวกบดบังตัวช่วยแค็ตตาล็อก
แซนด์บ็อกซ์เป็นชั้นความปลอดภัยหนึ่งชั้น ผู้ดำเนินการอาจยังต้องใช้ การเสริมความแข็งแกร่งระดับระบบปฏิบัติการสำหรับการติดตั้งใช้งานที่มีความเสี่ยงสูง
รหัสข้อผิดพลาด
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
การแก้จุดบกพร่อง
ใช้การบันทึกการขนส่งของโมเดลแบบเจาะจง เมื่อโหมดโค้ดทำงานแตกต่างจาก การรันเครื่องมือตามปกติ:
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
เรียกใช้รายการเหล่านี้เป็นการทดสอบการผสานรวมหรือการทดสอบตั้งแต่ต้นจนจบเมื่อเปลี่ยนรันไทม์:
- เริ่ม Gateway ด้วย
tools.codeMode.enabled: false - ส่งรอบการทำงานของเอเจนต์พร้อมชุดเครื่องมือโดยตรงขนาดเล็ก
- ยืนยันว่าเครื่องมือที่โมเดลมองเห็นไม่มีการเปลี่ยนแปลง
- เริ่มระบบใหม่ด้วย
tools.codeMode.enabled: true - ส่งรอบการทำงานของเอเจนต์พร้อมเครื่องมือทดสอบ OpenClaw, Plugin, MCP และไคลเอ็นต์
- ยืนยันว่ารายการเครื่องมือที่โมเดลมองเห็นคือ
exec,waitและมีเฉพาะเครื่องมือ direct-only ที่กำหนดค่าไว้ - ใน
execให้อ่านALL_TOOLSและยืนยันว่าเครื่องมือทดสอบที่มีผลและมีสิทธิ์อยู่ในแค็ตตาล็อก ปรากฏอยู่ ขณะที่ไม่มีเครื่องมือ direct-only - ใน
execให้เรียกเครื่องมือ OpenClaw/Plugin/ไคลเอ็นต์ผ่านtools.search,tools.describeและtools.callValue(หรือtools.callแบบดิบ) - ใน
execให้เรียกAPI.list("mcp")และAPI.read("mcp/<server>.d.ts")และ ยืนยันว่าไฟล์การประกาศอธิบายเครื่องมือ MCP ที่มองเห็นได้ - ใน
execให้เรียกเครื่องมือ MCP ผ่านMCP.<server>.<tool>({ ...input })และ ยืนยันว่าไม่มีรายการแค็ตตาล็อก MCP โดยตรงในALL_TOOLSและtools.* - ยืนยันว่าเครื่องมือที่ถูกปฏิเสธไม่มีอยู่และไม่สามารถเรียกด้วย id ที่คาดเดาได้
- เริ่มการเรียกเครื่องมือแบบซ้อนที่เสร็จสิ้นหลังจาก
execส่งคืนwaiting - เรียก
waitและยืนยันว่า VM ที่กู้คืนได้รับผลลัพธ์จากเครื่องมือ - ยืนยันว่าคำตอบสุดท้ายมีเอาต์พุตที่สร้างขึ้นหลังการกู้คืน
- ยืนยันว่าการหมดเวลา การยกเลิก และการหมดอายุของสแนปช็อตจะล้างสถานะรันไทม์
- ส่งออกวิถีและยืนยันว่าการเรียกแบบซ้อนมองเห็นได้ภายใต้การเรียก Code mode ระดับแม่
การเปลี่ยนแปลงเฉพาะเอกสารในหน้านี้ยังคงควรเรียกใช้ pnpm check:docs
ที่เกี่ยวข้อง
- Swarm สำหรับการประสานเอเจนต์แบบกระจายงานจากสคริปต์ Code Mode
- Tool Search
- รันไทม์ของเอเจนต์
- เครื่องมือ Exec
- การเรียกใช้โค้ด