Plugin SDK reference

ภาพรวม Plugin SDK

Plugin SDK เป็นสัญญาแบบมีชนิดข้อมูลระหว่าง Plugin กับแกนหลัก หน้านี้เป็น เอกสารอ้างอิงสำหรับ สิ่งที่ต้องนำเข้า และ สิ่งที่ลงทะเบียนได้

รูปแบบการนำเข้า

ให้นำเข้าจากพาธย่อยที่เจาะจงเสมอ:

typescript
  

แต่ละพาธย่อยเป็นโมดูลขนาดเล็กที่สมบูรณ์ในตัวเอง ซึ่งช่วยให้เริ่มต้นระบบได้รวดเร็วและ ป้องกันปัญหาการขึ้นต่อกันแบบวนซ้ำ สำหรับตัวช่วยรายการเริ่มต้น/การบิลด์เฉพาะช่องทาง ควรใช้ openclaw/plugin-sdk/channel-core; เก็บ openclaw/plugin-sdk/core ไว้สำหรับ พื้นผิวแบบครอบคลุมที่กว้างกว่าและตัวช่วยที่ใช้ร่วมกัน เช่น buildChannelConfigSchema

สำหรับการกำหนดค่าช่องทาง ให้เผยแพร่ JSON Schema ที่ช่องทางเป็นเจ้าของผ่าน openclaw.plugin.json#channelConfigs พาธย่อย plugin-sdk/channel-config-schema มีไว้สำหรับองค์ประกอบพื้นฐานของสคีมาที่ใช้ร่วมกันและตัวสร้างแบบทั่วไป Plugin ที่รวมมากับ OpenClaw ใช้ plugin-sdk/bundled-channel-config-schema สำหรับสคีมาช่องทางที่รวมมา ซึ่งยังคงเก็บไว้ พาธย่อยสคีมาที่รวมมานั้นไม่ใช่รูปแบบสำหรับ Plugin ใหม่

เอกสารอ้างอิงพาธย่อย

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

รายการจุดเริ่มต้นของคอมไพเลอร์อยู่ใน scripts/lib/plugin-sdk-entrypoints.json; การส่งออกสาธารณะแบบมีชนิดข้อมูลจะไม่รวม พาธย่อยภายในที่ระบุไว้ใน scripts/lib/plugin-sdk-private-local-only-subpaths.json รายการสำหรับโปรดักชัน ในรายการนั้นยังคงมีการส่งออกรันไทม์โฮสต์เฉพาะ JavaScript สำหรับ Plugin ทางการ ที่เผยแพร่แยกต่างหาก ขณะที่รายการสำหรับการทดสอบเท่านั้นจะยังไม่ถูกส่งออก เรียกใช้ pnpm plugin-sdk:surface เพื่อตรวจสอบจำนวนการส่งออกสาธารณะ พาธย่อยสาธารณะ ที่เลิกแนะนำแล้วซึ่งเก่าพอและไม่ได้ใช้โดยโค้ดโปรดักชันของส่วนขยายที่รวมมา จะถูกติดตามใน scripts/lib/plugin-sdk-deprecated-public-subpaths.json; บาร์เรลการส่งออกซ้ำแบบกว้าง ที่เลิกแนะนำแล้วจะถูกติดตามใน scripts/lib/plugin-sdk-deprecated-barrel-subpaths.json

API การลงทะเบียน

คอลแบ็ก register(api) จะได้รับอ็อบเจ็กต์ OpenClawPluginApi ซึ่งมี เมธอดต่อไปนี้:

Plugin ที่จัดเตรียมพื้นผิวแชตทีมภายนอกสำหรับเซสชัน สามารถลงทะเบียน ผู้ให้บริการหนึ่งรายการที่ใช้ร่วมกันทั้งโปรเซส ซึ่งส่งออกโดย openclaw/plugin-sdk/session-discussion เมธอด info({ sessionKey }) ของรายการดังกล่าว รายงานว่าการสนทนาไม่พร้อมใช้งาน พร้อมเปิด หรือเปิดอยู่แล้ว open({ sessionKey }) จะสร้างหรือค้นหาการสนทนาและส่งคืน URL สำหรับฝัง และ URL ภายนอก การลงทะเบียนผู้ให้บริการรายอื่นจะแทนที่ผู้ให้บริการปัจจุบัน

การลงทะเบียนความสามารถ

เมธอด สิ่งที่ลงทะเบียน
api.registerProvider(...) การอนุมานข้อความ (LLM)
api.registerWorkerProvider(...) สัญญาเช่าวงจรชีวิตของเวิร์กเกอร์บนคลาวด์
api.registerModelCatalogProvider(...) แถวแค็ตตาล็อกโมเดลสำหรับการสร้างข้อความและสื่อ
api.registerAgentHarness(...) ตัวดำเนินการเอเจนต์แบบเนทีฟ ทดลอง (Codex, Copilot)
api.registerCliBackend(...) แบ็กเอนด์การอนุมาน CLI ภายในเครื่อง
api.registerChannel(...) ช่องทางการรับส่งข้อความ
api.registerEmbeddingProvider(...) ผู้ให้บริการเวกเตอร์ฝังตัวที่นำกลับมาใช้ใหม่ได้
api.registerSpeechProvider(...) การสังเคราะห์ข้อความเป็นเสียงพูด / STT
api.registerRealtimeTranscriptionProvider(...) การถอดเสียงแบบเรียลไทม์ชนิดสตรีมมิง
api.registerRealtimeVoiceProvider(...) เซสชันเสียงเรียลไทม์แบบสองทิศทาง
api.registerMediaUnderstandingProvider(...) การวิเคราะห์รูปภาพ/เสียง/วิดีโอ
api.registerTranscriptSourceProvider(...) แหล่งที่มาของบทถอดเสียงการประชุมแบบสดหรือนำเข้า
api.registerImageGenerationProvider(...) การสร้างรูปภาพ
api.registerMusicGenerationProvider(...) การสร้างเพลง
api.registerVideoGenerationProvider(...) การสร้างวิดีโอ
api.registerWebFetchProvider(...) ผู้ให้บริการดึงข้อมูล / เก็บข้อมูลจากเว็บ
api.registerWebSearchProvider(...) การค้นหาเว็บ
api.registerCompactionProvider(...) แบ็กเอนด์ Compaction บทถอดเสียงแบบเสียบแทนได้

ผู้ให้บริการเวิร์กเกอร์ต้องประกาศรหัสของตนใน contracts.workerProviders ด้วย แกนหลักจะบันทึกเจตนาที่คงทนก่อน provision(profile, operationId) ผู้ให้บริการจะตรวจสอบการตั้งค่าก่อนจัดสรรทรัพยากรภายนอก และโยน WorkerProviderError เมื่อปฏิเสธโปรไฟล์อย่างถาวร provision ต้องรับช่วงสัญญาเช่าเดิมเมื่อรหัสการดำเนินการเกิดซ้ำ แกนหลักจะบันทึกการตั้งค่าโปรไฟล์ที่ตรวจสอบแล้วพร้อมสัญญาเช่า และส่งสแนปช็อตนั้นให้ destroy({ leaseId, profile }) ซึ่งต้องทำซ้ำได้โดยให้ผลเดิม และ inspect({ leaseId, profile }) ซึ่งส่งคืน active, destroyed หรือ unknown ซึ่งช่วยให้ผู้ให้บริการกำหนดเส้นทางการเรียกวงจรชีวิตได้หลังจาก Gateway เริ่มใหม่หรือมีการลบโปรไฟล์ที่ตั้งชื่อไว้ ปลายทาง SSH ใช้ SecretRef สำหรับ keyRef โดยห้ามใส่ข้อมูลคีย์แบบอินไลน์ และรวม hostKey จากผลลัพธ์การจัดเตรียมที่เชื่อถือได้ในรูปแบบ algorithm base64 เท่านั้น โดยไม่มีชื่อโฮสต์หรือความคิดเห็น แกนหลักจะปักหมุด hostKey และไม่เชื่อถือคีย์จากการเชื่อมต่อครั้งแรก ผู้ให้บริการที่ออก keyRef แบบไดนามิกสามารถใช้งาน resolveSshIdentity({ leaseId, profile, keyRef }); เมื่อมีตัวแก้ไขดังกล่าว ตัวแก้ไขนั้นจะเป็นแหล่งข้อมูลอ้างอิงหลัก ส่วนผู้ให้บริการที่ไม่มีตัวแก้ไขจะใช้ตัวแก้ไขข้อมูลลับแบบทั่วไปที่กำหนดค่าไว้ ผู้ให้บริการที่มีสัญญาเช่าต่ออายุได้ยังสามารถใช้งาน renew(leaseId) ได้ด้วย inspect ต้องโยนข้อผิดพลาดเมื่อเกิดความล้มเหลวชั่วคราวหรือไม่อาจระบุได้ ให้ส่งคืน unknown เฉพาะเมื่อยืนยันได้แน่ชัดว่าไม่มีอยู่ แกนหลักจะทำเครื่องหมายเรคคอร์ดภายในเครื่องที่ใช้งานอยู่ว่าไม่มีเจ้าของ หรือถือว่าการไม่มีอยู่ดังกล่าวเป็นการรื้อถอนเสร็จสมบูรณ์หลังจากมีคำขอทำลายที่บันทึกไว้อย่างถาวร

ผู้ให้บริการเวกเตอร์ฝังตัวที่ลงทะเบียนด้วย api.registerEmbeddingProvider(...) ต้อง ถูกระบุไว้ใน contracts.embeddingProviders ในแมนิเฟสต์ของ Plugin ด้วย นี่คือ พื้นผิวเวกเตอร์ฝังตัวแบบทั่วไปสำหรับการสร้างเวกเตอร์ที่นำกลับมาใช้ใหม่ได้ การค้นหาหน่วยความจำ สามารถใช้พื้นผิวผู้ให้บริการแบบทั่วไปนี้ จุดเชื่อมรุ่นเก่า api.registerMemoryEmbeddingProvider(...) และ contracts.memoryEmbeddingProviders เป็นความเข้ากันได้ที่เลิกแนะนำแล้ว ขณะที่ ผู้ให้บริการเฉพาะหน่วยความจำที่มีอยู่กำลังย้ายระบบ

ผู้ให้บริการเฉพาะหน่วยความจำที่ยังเปิดเผย batchEmbed(...) ในรันไทม์จะยังคงใช้ สัญญาการจัดชุดต่อไฟล์ที่มีอยู่ เว้นแต่รันไทม์จะตั้งค่า sourceWideBatchEmbed: true ไว้อย่างชัดเจน การเลือกใช้นี้ช่วยให้โฮสต์หน่วยความจำส่งส่วนข้อมูลจาก ไฟล์หน่วยความจำที่มีการเปลี่ยนแปลงหลายไฟล์และแหล่งที่มาที่เปิดใช้งานในการเรียก batchEmbed(...) ครั้งเดียว ได้จนถึงขีดจำกัดชุดของโฮสต์ อะแดปเตอร์ชุดที่อัปโหลดไฟล์คำขอ JSONL ต้อง แบ่งงานของผู้ให้บริการก่อนถึงเพดานขนาดอัปโหลดและเพดานจำนวนคำขอ ผู้ให้บริการต้องส่งคืนเวกเตอร์ฝังตัวหนึ่งรายการต่อส่วนข้อมูลอินพุตในลำดับเดียวกับ batch.chunks; ไม่ต้องระบุแฟล็กนี้เมื่อผู้ให้บริการคาดหวังชุดภายในไฟล์ หรือไม่สามารถรักษาลำดับอินพุตในงานที่ครอบคลุมทั้งแหล่งที่มาและมีขนาดใหญ่กว่าได้

เครื่องมือและคำสั่ง

ใช้ defineToolPlugin สำหรับ Plugin ที่มีเฉพาะเครื่องมือแบบง่าย ซึ่งมีชื่อเครื่องมือคงที่ ใช้ api.registerTool(...) โดยตรงสำหรับ Plugin แบบผสม หรือการลงทะเบียนเครื่องมือแบบไดนามิกเต็มรูปแบบ

เมธอด สิ่งที่ลงทะเบียน
api.registerTool(tool, opts?) เครื่องมือเอเจนต์ (จำเป็นหรือ { optional: true })
api.registerCommand(def) คำสั่งแบบกำหนดเอง (ข้าม LLM)
api.registerNodeHostCommand(command) คำสั่งที่จัดการโดย openclaw node run; ข้อมูลเมตา agentTool ที่ไม่บังคับสามารถเปิดเผยคำสั่งนี้เป็นเครื่องมือที่เอเจนต์มองเห็นได้ขณะที่ Node เชื่อมต่ออยู่

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

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

ts
agentPromptGuidance: [  "คำแนะนำคำสั่งส่วนกลาง",  { text: "แสดงข้อความนี้เฉพาะในพรอมต์หลักของ OpenClaw", surfaces: ["openclaw_main"] },];

surfaces แบบมีโครงสร้างอาจมี openclaw_main, codex_app_server, cli_backend, acp_backend หรือ subagent ส่วน pi_main ยังคงเป็นนามแฝง ที่เลิกแนะนำแล้วสำหรับ openclaw_main ไม่ต้องระบุ surfaces สำหรับคำแนะนำที่ตั้งใจให้ใช้กับทุกพื้นผิว อย่า ส่งอาร์เรย์ surfaces ว่าง ระบบจะปฏิเสธเพื่อไม่ให้การสูญเสียขอบเขตโดยไม่ตั้งใจ กลายเป็นข้อความพรอมต์ส่วนกลาง

คำสั่งสำหรับนักพัฒนาของเซิร์ฟเวอร์แอป Codex แบบเนทีฟเข้มงวดกว่าพื้นผิวพรอมต์ อื่นๆ: เฉพาะคำแนะนำที่กำหนดขอบเขตเป็น codex_app_server อย่างชัดเจนเท่านั้นที่จะได้รับการเลื่อนเข้าไปใน ช่องทางที่มีลำดับความสำคัญสูงกว่านั้น คำแนะนำแบบสตริงเดิมและคำแนะนำแบบมีโครงสร้าง ที่ไม่ได้กำหนดขอบเขตจะยังคงพร้อมใช้งานกับพื้นผิวพรอมต์ที่ไม่ใช่ Codex เพื่อความเข้ากันได้

คำสั่งของโฮสต์ Node จะทำงานบนโฮสต์ Node ที่เชื่อมต่อ ไม่ใช่ภายในโปรเซส Gateway หากมี agentTool อยู่ Node จะเผยแพร่ตัวอธิบายหลังจากเชื่อมต่อ Gateway สำเร็จ โดย Gateway จะเปิดให้การทำงานของเอเจนต์ใช้ตัวอธิบายนี้ได้เฉพาะขณะที่ Node นั้นเชื่อมต่ออยู่ และเฉพาะเมื่อ command ของตัวอธิบายอยู่ในพื้นผิวคำสั่ง ที่ได้รับอนุมัติของ Node เท่านั้น ตั้งค่า agentTool.defaultPlatforms เพื่อเพิ่ม คำสั่งที่ไม่เป็นอันตรายลงในรายการอนุญาตคำสั่งเริ่มต้นของ Node มิฉะนั้นต้องกำหนด gateway.nodes.allowCommands อย่างชัดเจนหรือนโยบายการเรียกใช้ผ่าน Node agentTool.name ต้องปลอดภัยสำหรับผู้ให้บริการ: ขึ้นต้นด้วยตัวอักษร ใช้เฉพาะตัวอักษร ตัวเลข ขีดล่าง หรือขีดกลาง และมีความยาวไม่เกิน 64 อักขระ เครื่องมือ Node ที่มี MCP เป็นแบ็กเอนด์ สามารถตั้งค่าเมทาดาทา agentTool.mcp เพื่อให้พื้นผิวแค็ตตาล็อกและการค้นหาเครื่องมือแสดง ข้อมูลประจำตัวของเซิร์ฟเวอร์/เครื่องมือ MCP ระยะไกลได้ แต่การดำเนินการยังคงผ่าน คำสั่ง Node ที่ประกาศไว้

โครงสร้างพื้นฐาน

เมธอด สิ่งที่ลงทะเบียน
api.registerHook(events, handler, opts?) ฮุกเหตุการณ์
api.registerHttpRoute(params) เอนด์พอยต์ HTTP ของ Gateway
api.registerGatewayMethod(name, handler) เมธอด RPC ของ Gateway
api.registerGatewayDiscoveryService(service) ตัวประกาศการค้นหา Gateway ภายในเครื่อง
api.registerCli(registrar, opts?) คำสั่งย่อยของ CLI
api.registerNodeCliFeature(registrar, opts?) CLI ฟีเจอร์ของ Node ภายใต้ openclaw nodes
api.registerService(service) บริการเบื้องหลัง
api.registerInteractiveHandler(registration) ตัวจัดการแบบโต้ตอบ
api.registerAgentToolResultMiddleware(...) มิดเดิลแวร์ผลลัพธ์เครื่องมือขณะรัน
api.registerMemoryPromptSupplement(builder) ส่วนพรอมต์เสริมที่อยู่ใกล้เคียงหน่วยความจำ
api.registerMemoryPromptPreparation(prepare) การเตรียมแบบอะซิงโครนัสสำหรับส่วนพรอมต์ที่อยู่ใกล้เคียงหน่วยความจำ
api.registerMemoryCorpusSupplement(adapter) คลังข้อมูลเสริมสำหรับการค้นหา/อ่านหน่วยความจำ
api.registerHostedMediaResolver(resolver) ตัวแก้ไข URL สื่อที่โฮสต์ในรูปแบบเบราว์เซอร์
api.registerMcpServerConnectionResolver(...) การขนส่ง MCP ต่อผู้ร้องขอ (url/headers) สำหรับชื่อเซิร์ฟเวอร์แบบคงที่
api.registerTextTransforms(transforms) การเขียนข้อความความเข้ากันได้ของพรอมต์/ข้อความใหม่ที่ Plugin เป็นเจ้าของ
api.registerConfigMigration(migrate) การย้ายการกำหนดค่าแบบเบาที่ทำงานก่อนโหลดรันไทม์ของ Plugin
api.registerMigrationProvider(provider) ตัวนำเข้าสำหรับ openclaw migrate
api.registerAutoEnableProbe(probe) โพรบการกำหนดค่าที่สามารถเปิดใช้ Plugin นี้โดยอัตโนมัติ
api.registerReload(registration) นโยบายคำนำหน้าการกำหนดค่า restart/hot/noop สำหรับจัดการการโหลดซ้ำ
api.registerNodeHostCommand(command) ตัวจัดการคำสั่งที่เปิดให้ Node ซึ่งจับคู่แล้วใช้
api.registerNodeInvokePolicy(policy) นโยบายรายการอนุญาต/การอนุมัติสำหรับคำสั่งที่เรียกใช้ผ่าน Node
api.registerSecurityAuditCollector(collector) ตัวรวบรวมสิ่งที่ตรวจพบสำหรับ openclaw security audit

งาน Webhook หลังการตอบรับ

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

typescript
 void runDetachedWebhookWork(() => processWebhookEvent(event)).catch((error) => {  runtime.error?.(`webhook dispatch failed: ${String(error)}`);});

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

การเชื่อมต่อ MCP ที่กำหนดขอบเขตตามผู้ร้องขอ

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

ts
api.registerMcpServerConnectionResolver({  serverName: "user-email",  resolve: async (ctx) => {    // ctx.requesterSenderId is host-trusted; never invent sender identity here.    const token = await lookupUserToken(ctx.requesterSenderId);    if (!token) {      return null; // omit this server for the current run    }    return {      url: "https://mcp.example.com/email",      headers: { Authorization: `Bearer ${token}` },    };  },});

หมายเหตุเกี่ยวกับสัญญา:

  • บริบทของตัวแก้ไขมีเฉพาะข้อมูลประจำตัวของโฮสต์ที่เชื่อถือได้ (requesterSenderId, และ agentAccountId / messageChannel ที่เป็นตัวเลือก) สามารถเพิ่มฟิลด์ที่เชื่อถือได้ในอนาคต (เช่น บริบทผู้ใช้ของ cron/เอเจนต์ย่อย) แบบเพิ่มเติมได้
  • หนึ่ง Plugin เป็นเจ้าของชื่อเซิร์ฟเวอร์หนึ่งชื่อ: หาก Plugin อื่นลงทะเบียน registerMcpServerConnectionResolver ซ้ำสำหรับ serverName เดียวกัน ระบบจะปฏิเสธพร้อมการวินิจฉัยข้อผิดพลาด (การลงทะเบียนแรกชนะ) ดังนั้น ความเป็นเจ้าของการเชื่อมต่อจึงไม่ขึ้นกับลำดับการโหลด Plugin
  • ชื่อเครื่องมือได้มาจากชุดเซิร์ฟเวอร์ที่ประกาศทั้งหมด ดังนั้นการแก้ไขเพียงบางส่วน จะไม่เปลี่ยนชื่อเซิร์ฟเวอร์ที่ปลอดภัยระหว่างผู้ร้องขอหรือแต่ละรอบ Core ไม่ ตรวจสอบว่าเอนด์พอยต์ของผู้ร้องขอแต่ละรายให้สคีมาเครื่องมือเหมือนกันหรือไม่ ตัวแก้ไข ต้องชี้ผู้ร้องขอทุกรายไปยังบริการเชิงตรรกะเดียวกัน มิฉะนั้นสคีมาเครื่องมือ (และความเสถียรของแคชพรอมต์) จะแตกต่างกันตามผู้ร้องขอ
  • การทำงานที่ไม่มี requesterSenderId ที่เชื่อถือได้ (cron, เอเจนต์ย่อย, Heartbeat, Gateway สาธารณะ) จะไม่สร้างเซิร์ฟเวอร์ที่กำหนดขอบเขตตามผู้ร้องขอ ไม่มี การเชื่อมต่อสำรองแบบใช้ร่วมกัน
  • resolve ถูกจำกัดไว้ที่ 10 วินาทีต่อเซิร์ฟเวอร์ หากหมดเวลาหรือเกิดข้อยกเว้น ระบบจะละเว้น เซิร์ฟเวอร์นั้นสำหรับการทำงานครั้งนั้น โดยไม่ทำให้ MCP แบบคงที่ล้มเหลว
  • การเชื่อมต่อที่แก้ไขแล้วจะได้รับการตรวจสอบซ้ำอย่างมากที่สุดทุก 5 นาทีต่อผู้ร้องขอ: การหมุนเวียนจะสร้างการขนส่งใหม่ด้วยข้อมูลรับรองใหม่ และผลลัพธ์ null จะเพิกถอนการเชื่อมต่อ (รันไทม์ที่แคชไว้จะถูกกำจัดแม้อยู่กลางเซสชัน) ดังนั้นข้อมูลรับรองที่ถูกเพิกถอนหรือ หมุนเวียนแล้วอาจยังถูกใช้งานต่อได้สูงสุด 5 นาที
  • headers ที่แก้ไขแล้วจะไม่ถูกบันทึกลงล็อกหรือคงไว้ถาวร Core เก็บเพียงไดเจสต์แบบมีคีย์ ชั่วคราวในหน่วยความจำ (HMAC ภายในโปรเซส) เพื่อตรวจจับการหมุนเวียนข้อมูลรับรอง และ ลงทะเบียนค่าข้อมูลรับรองในส่วนหัว/URL ที่แก้ไขแล้วกับรีจิสทรีการปกปิดข้อมูล สำหรับล็อก/การจับข้อมูลดีบัก
  • เซิร์ฟเวอร์ที่กำหนดขอบเขตตามผู้ร้องขอจะไม่สร้างมุมมอง MCP App: มุมมองมีอายุยาวกว่า การทำงานที่ยืนยันตัวตนผู้ร้องขอ และขอบเขตมุมมองของ Gateway ไม่มีข้อมูลประจำตัว ของผู้ร้องขอ ดังนั้นการแสดงตัวอย่างแอปจะยังคงปิดอย่างปลอดภัยสำหรับเซิร์ฟเวอร์เหล่านี้ ผลลัพธ์เครื่องมือ ไม่ได้รับผลกระทบ
  • เซิร์ฟเวอร์แบบคงที่ที่ไม่มีตัวแก้ไขจะคงวงจรชีวิตที่กำหนดขอบเขตตามเซสชันเดิม
  • กฎการส่งมอบของฮาร์เนส: เซิร์ฟเวอร์ที่กำหนดขอบเขตตามผู้ร้องขอจะไม่เข้าสู่ การกำหนดค่าไคลเอนต์ MCP แบบเนทีฟของฮาร์เนส (เธรด Codex mcp_servers, CLI -c mcp_servers=… หรือ การฉายภาพ MCP แบบใช้ร่วมกันในเซสชันอื่นใด) แต่ฮาร์เนสจะส่งมอบเซิร์ฟเวอร์เหล่านี้เป็นเครื่องมือ ที่กำหนดขอบเขตตามการทำงานแทน:
    • ตัวรันแบบฝัง: รันไทม์ MCP ของเซสชัน + เครื่องมือบันเดิล (แบบคงที่ + แบบกำหนดขอบเขต)
    • เซิร์ฟเวอร์แอป Codex: เครื่องมือแบบไดนามิกผ่าน materializeRequesterScopedMcpToolsForHarnessRun (เฉพาะแบบกำหนดขอบเขต เซิร์ฟเวอร์แบบคงที่ยังคงอยู่บนไคลเอนต์ MCP แบบเนทีฟของ Codex)
  • ข้อกำหนด ของเครื่องมือแบบกำหนดขอบเขตจะคงที่ตลอดเซสชันหลังจากแก้ไขสำเร็จครั้งแรก ในเซสชันนั้น เพื่อให้ฮาร์เนสที่ใช้เธรดร่วมกัน (Codex) ไม่หมุนเวียนเธรดเมื่อ ผู้ส่งเปลี่ยน ก่อนมีผู้ร้องขอรายใดแก้ไขสำเร็จ จะไม่มีการประกาศข้อกำหนดแบบกำหนดขอบเขต
  • ผู้ร้องขอที่ไม่ได้ยืนยันตัวตนบนฮาร์เนสที่ใช้เธรดร่วมกันจะยังเห็นเครื่องมือแบบกำหนดขอบเขต ที่ประกาศไว้ การเรียกเครื่องมือใดเครื่องมือหนึ่งจะคืนข้อผิดพลาดเครื่องมือว่าไม่ได้เชื่อมต่ออย่างชัดเจนสำหรับ ผู้ร้องขอรายนั้น OpenClaw จะไม่ใช้ข้อมูลรับรองของผู้ร้องขอรายอื่นเป็นทางเลือกเด็ดขาด

ตัวสร้างส่วนเสริมพรอมต์หน่วยความจำได้รับบริบท agentId, agentSessionKey และ sandboxed ที่เป็นตัวเลือก การเรียก search และ get สำหรับส่วนเสริมคลังข้อมูลหน่วยความจำจะได้รับบริบท agentId และ sandboxed ที่เป็นตัวเลือก Plugin ที่มี พื้นที่จัดเก็บซึ่งเอเจนต์เป็นเจ้าของควรแก้ไขพื้นที่จัดเก็บนั้นสำหรับแต่ละการเรียก แทนที่จะ จับพาธส่วนกลางเพียงพาธเดียวระหว่างการลงทะเบียน หากจำเป็นต้องมีรหัสเอเจนต์แต่ไม่มี ในการดำเนินการแบบหลายเอเจนต์ ให้ปิดอย่างปลอดภัยแทนการเลือก เอเจนต์โดยพลการ

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

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

ฮุกโฮสต์สำหรับ Plugin เวิร์กโฟลว์

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

เมธอด สัญญาที่เมธอดเป็นเจ้าของ
api.session.state.registerSessionExtension(...) สถานะเซสชันที่ Plugin เป็นเจ้าของและเข้ากันได้กับ JSON ซึ่งฉายผ่านเซสชันของ Gateway
api.session.workflow.enqueueNextTurnInjection(...) บริบทแบบ exactly-once ที่คงทน ซึ่งแทรกเข้าไปในการทำงานรอบถัดไปของเอเจนต์สำหรับหนึ่งเซสชัน
api.registerTrustedToolPolicy(...) นโยบายเครื่องมือก่อนถึง Plugin ที่เชื่อถือได้และควบคุมด้วยไฟล์ manifest ซึ่งสามารถบล็อกหรือเขียนพารามิเตอร์เครื่องมือใหม่ได้
api.registerToolMetadata(...) เมทาดาทาการแสดงผลแค็ตตาล็อกเครื่องมือโดยไม่เปลี่ยนการทำงานของเครื่องมือ
api.registerCommand(...) คำสั่ง Plugin ที่จำกัดขอบเขต ผลลัพธ์คำสั่งสามารถตั้งค่า continueAgent: true หรือ suppressReply: true ได้ คำสั่งแบบเนทีฟของ Discord รองรับ descriptionLocalizations
api.session.controls.registerControlUiDescriptor(...) ตัวอธิบายการสนับสนุน Control UI สำหรับพื้นผิวเซสชัน เครื่องมือ การทำงาน การตั้งค่า หรือแท็บ
api.lifecycle.registerRuntimeLifecycle(...) คอลแบ็กการล้างทรัพยากรรันไทม์ที่ Plugin เป็นเจ้าของบนเส้นทางรีเซ็ต/ลบ/โหลดใหม่
api.agent.events.registerAgentEventSubscription(...) การสมัครรับเหตุการณ์ที่ผ่านการทำให้ปลอดภัยแล้วสำหรับสถานะเวิร์กโฟลว์และตัวตรวจสอบ
api.runContext.setRunContext(...) / getRunContext(...) / clearRunContext(...) สถานะชั่วคราวของ Plugin ต่อการทำงาน ซึ่งล้างเมื่อสิ้นสุดวงจรการทำงาน
api.session.workflow.registerSessionSchedulerJob(...) เมทาดาทาการล้างงานตัวกำหนดเวลาที่ Plugin เป็นเจ้าของ ไม่ได้กำหนดเวลางานหรือสร้างระเบียนงาน
api.session.workflow.sendSessionAttachment(...) การส่งไฟล์แนบผ่านโฮสต์สำหรับ Plugin ที่รวมมาเท่านั้น ไปยังเส้นทางเซสชันขาออกโดยตรงที่ใช้งานอยู่
api.session.workflow.scheduleSessionTurn(...) / unscheduleSessionTurnsByTag(...) รอบการทำงานของเซสชันตามกำหนดเวลาที่รองรับด้วย Cron สำหรับ Plugin ที่รวมมาเท่านั้น พร้อมการล้างตามแท็ก
api.session.controls.registerSessionAction(...) การดำเนินการเซสชันแบบมีชนิดข้อมูลที่ไคลเอ็นต์สามารถส่งผ่าน Gateway ได้

ตัวอธิบาย surface: "tab" จะเพิ่มแท็บแถบด้านข้างให้กับ Control UI ตัวอธิบายแท็บของ Plugin ที่ใช้งานอยู่จะถูกประกาศให้ไคลเอ็นต์แดชบอร์ดทราบในข้อความ hello ของ Gateway (controlUiTabs) ดังนั้นแท็บจะปรากฏเฉพาะเมื่อเปิดใช้งาน Plugin เท่านั้น Plugin ที่รวมมาอาจมีมุมมองแดชบอร์ดระดับเฟิร์สคลาสสำหรับแท็บของตน ส่วน Plugin อื่น สามารถตั้งค่า path เป็นเส้นทาง HTTP ของ Plugin (ดู api.registerHttpRoute(...)) ซึ่งแดชบอร์ดจะแสดงผลในเฟรมแบบแซนด์บ็อกซ์ icon เป็นคำใบ้ชื่อไอคอนแดชบอร์ด group ใช้เลือกส่วนของแถบด้านข้าง (control หรือ agent) order ใช้จัดลำดับระหว่างแท็บ Plugin และ requiredScopes ใช้ซ่อนแท็บจากการเชื่อมต่อที่ไม่มีขอบเขตผู้ดำเนินการเหล่านั้น:

สำหรับแท็บภายนอกที่ Gateway ปกป้อง ให้ลงทะเบียนตัวอธิบาย path ภายใต้ เส้นทาง HTTP auth: "gateway" ของ Plugin เดียวกัน หลังจากบูตสแตรปแบบยืนยันตัวตนแล้ว เบราว์เซอร์จะได้รับ สิทธิ์แบบ HttpOnly อายุสั้นซึ่งจำกัดขอบเขตเฉพาะ Plugin และรากของเส้นทางนั้น เพื่อให้ เฟรมแบบแซนด์บ็อกซ์โหลดได้โดยไม่ต้องคัดลอกโทเค็น bearer ของ Gateway ลงใน URL หรือ JavaScript พาเรนต์ที่ยืนยันตัวตนแล้วจะต่ออายุสิทธิ์ขณะที่แท็บภายนอก ทำงานอยู่และก่อนเมานต์แท็บหลังการนำทางหรือการกลับมาทำงานต่อของเบราว์เซอร์ นอกจากนี้ พาเรนต์ยังตรวจสอบสิทธิ์จากแซนด์บ็อกซ์แบบ opaque เดียวกันก่อนเมานต์ เพื่อให้โหมด ความเป็นส่วนตัวของเบราว์เซอร์ที่บล็อกคุกกี้ปิดการทำงานอย่างปลอดภัยโดยแสดงพาเนลที่ไม่พร้อมใช้งาน สิทธิ์ของเฟรมยอมรับเฉพาะ GET และ HEAD และจะมี operator.read เสมอ requiredScopes ควบคุมการมองเห็นแท็บแต่ไม่ขยาย สิทธิ์ของคุกกี้ การเปลี่ยนแปลงข้อมูลยังคงอยู่บนพื้นผิวพาเรนต์ที่ยืนยันตัวตนกับ Gateway อย่างชัดเจนหรือพื้นผิว bearer แท็บภายนอกต้องใช้ HTTPS/Tailscale Serve หรือ ต้นทางลูปแบ็กที่เบราว์เซอร์เชื่อถือ HTTP ธรรมดาบนโฮสต์ LAN จะแสดง ข้อผิดพลาดด้านบริบทที่ปลอดภัยแทนการเมานต์พาเนลที่ไม่สามารถยืนยันตัวตนได้ การบล็อกคุกกี้ของบุคคลที่สามทั้งหมดจะทำให้แท็บที่ Gateway ปกป้องใช้งานไม่ได้เช่นกัน เช่นเดียวกับพื้นผิว Plugin แบบเนทีฟทั้งหมด เฟรมยังคงอยู่ภายในขอบเขตความเชื่อถือของ Plugin ที่ติดตั้ง OpenClaw ไม่ถือว่า Plugin ที่ติดตั้งเป็นหลักการรักษาความปลอดภัย ของเบราว์เซอร์ที่แยกออกจากกัน สิทธิ์คุกกี้ใช้ขอบเขตชื่อโฮสต์ของเบราว์เซอร์ ไม่ใช่ขอบเขตพอร์ต อย่าโฮสต์บริการที่ไม่ไว้วางใจซึ่งกันและกันร่วมกันบนชื่อโฮสต์ของ Gateway แม้จะอยู่บน พอร์ตอื่นก็ตาม แท็บที่รองรับด้วยการยืนยันตัวตนซึ่ง Plugin จัดการจะคงพฤติกรรม iframe โดยตรงและไม่ ร้องขอหรือต้องใช้สิทธิ์ Gateway นี้

typescript
api.session.controls.registerControlUiDescriptor({  surface: "tab",  id: "logbook",  label: "บันทึกประจำวัน",  description: "วันของคุณในรูปแบบไทม์ไลน์ ซึ่งสร้างจากภาพหน้าจอ",  icon: "sun",  group: "control",  requiredScopes: ["operator.write"],});

ใช้เนมสเปซแบบจัดกลุ่มสำหรับโค้ด Plugin ใหม่:

  • api.session.state.registerSessionExtension(...)
  • api.session.workflow.enqueueNextTurnInjection(...)
  • api.session.workflow.registerSessionSchedulerJob(...)
  • api.session.workflow.sendSessionAttachment(...)
  • api.session.workflow.scheduleSessionTurn(...)
  • api.session.workflow.unscheduleSessionTurnsByTag(...)
  • api.session.controls.registerSessionAction(...)
  • api.session.controls.registerControlUiDescriptor(...)
  • api.agent.events.registerAgentEventSubscription(...)
  • api.agent.events.emitAgentEvent(...)
  • api.runContext.setRunContext(...) / getRunContext(...) / clearRunContext(...)
  • api.lifecycle.registerRuntimeLifecycle(...)

เมธอดแบบแบนที่เทียบเท่ากันยังคงใช้งานได้ในฐานะนามแฝงความเข้ากันได้ที่เลิกแนะนำ สำหรับ Plugin ที่มีอยู่ อย่าเพิ่มโค้ด Plugin ใหม่ที่เรียก api.registerSessionExtension, api.enqueueNextTurnInjection, api.registerControlUiDescriptor, api.registerRuntimeLifecycle, api.registerAgentEventSubscription, api.emitAgentEvent, api.setRunContext, api.getRunContext, api.clearRunContext, api.registerSessionSchedulerJob, api.registerSessionAction, api.sendSessionAttachment, api.scheduleSessionTurn หรือ api.unscheduleSessionTurnsByTag โดยตรง

scheduleSessionTurn(...) เป็นเครื่องมืออำนวยความสะดวกระดับเซสชันบนตัวกำหนดเวลา Cron ของ Gateway โดย Cron เป็นเจ้าของการกำหนดเวลาและสร้างระเบียนงานเบื้องหลังเมื่อ รอบการทำงานเริ่มทำงาน ส่วน Plugin SDK จำกัดเฉพาะเซสชันเป้าหมาย การตั้งชื่อที่ Plugin เป็นเจ้าของ และการล้างเท่านั้น ใช้ api.runtime.tasks.managedFlows ภายในรอบการทำงาน ตามกำหนดเวลา เมื่องานนั้นต้องใช้สถานะ Task Flow หลายขั้นตอนที่คงทน

สัญญาเหล่านี้แยกอำนาจโดยเจตนา:

  • Plugin ภายนอกสามารถเป็นเจ้าของส่วนขยายเซสชัน ตัวอธิบาย UI คำสั่ง เมทาดาทา เครื่องมือ การแทรกในรอบถัดไป และฮุกปกติ
  • นโยบายเครื่องมือที่เชื่อถือได้จะทำงานก่อนฮุก before_tool_call ทั่วไปและ ได้รับความไว้วางใจจากโฮสต์ นโยบายที่รวมมาจะทำงานก่อน ส่วนนโยบายของ Plugin ที่ติดตั้งต้อง เปิดใช้งานอย่างชัดเจนพร้อมใส่ ID ภายในไว้ใน contracts.trustedToolPolicies และจะทำงานถัดไปตามลำดับการโหลด Plugin โดย ID นโยบาย จะจำกัดขอบเขตเฉพาะ Plugin ที่ลงทะเบียน
  • ความเป็นเจ้าของคำสั่งสงวนไว้สำหรับส่วนที่รวมมาเท่านั้น Plugin ภายนอกควรใช้ ชื่อคำสั่งหรือนามแฝงของตนเอง
  • allowPromptInjection=false ปิดใช้งานฮุกที่เปลี่ยนพรอมต์ รวมถึง agent_turn_prepare, before_prompt_build, heartbeat_prompt_contribution และ enqueueNextTurnInjection

ตัวอย่างส่วนที่ใช้งานซึ่งไม่ใช่ Plan:

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

Plugin ที่รวมมาและ Plugin ที่ติดตั้งซึ่งเปิดใช้งานอย่างชัดเจนพร้อมสัญญา manifest ที่ตรงกันสามารถใช้ api.registerAgentToolResultMiddleware(...) เมื่อ ต้องเขียนผลลัพธ์เครื่องมือใหม่หลังการดำเนินการและก่อนรันไทม์ ป้อนผลลัพธ์นั้นกลับเข้าโมเดล นี่คือรอยต่อที่เป็นกลางต่อรันไทม์และเชื่อถือได้ สำหรับตัวลดเอาต์พุตแบบอะซิงโครนัส เช่น tokenjuice

Plugin ต้องประกาศ contracts.agentToolResultMiddleware สำหรับรันไทม์เป้าหมายแต่ละรายการ ตัวอย่างเช่น ["openclaw", "codex"] Plugin ที่ติดตั้งซึ่งไม่มี สัญญาดังกล่าวหรือไม่ได้เปิดใช้งานอย่างชัดเจนจะไม่สามารถลงทะเบียนมิดเดิลแวร์นี้ได้ ให้ใช้ ฮุก Plugin ปกติของ OpenClaw สำหรับงานที่ไม่ต้องใช้จังหวะผลลัพธ์เครื่องมือ ก่อนถึงโมเดล เส้นทางการลงทะเบียนแฟกทอรีส่วนขยายแบบเก่าที่ใช้ได้เฉพาะ รันเนอร์แบบฝังตัวถูกนำออกแล้ว

การลงทะเบียนการค้นพบ Gateway

api.registerGatewayDiscoveryService(...) ช่วยให้ Plugin ประกาศ Gateway ที่ใช้งานอยู่ บนการส่งข้อมูลการค้นพบภายในเครื่อง เช่น mDNS/Bonjour โดย OpenClaw จะเรียก บริการระหว่างการเริ่มต้น Gateway เมื่อเปิดใช้งานการค้นพบภายในเครื่อง ส่งพอร์ต Gateway ปัจจุบันและข้อมูลคำใบ้ TXT ที่ไม่เป็นความลับ และเรียกตัวจัดการ stop ที่ส่งคืนมาระหว่างการปิด Gateway

typescript
api.registerGatewayDiscoveryService({  id: "my-discovery",  async advertise(ctx) {    const handle = await startMyAdvertiser({      gatewayPort: ctx.gatewayPort,      tls: ctx.gatewayTlsEnabled,      displayName: ctx.machineDisplayName,    });    return { stop: () => handle.stop() };  },});

Plugin การค้นพบ Gateway ต้องไม่ถือว่าค่า TXT ที่ประกาศเป็นความลับหรือ ข้อมูลยืนยันตัวตน การค้นพบเป็นเพียงคำใบ้สำหรับการกำหนดเส้นทาง ส่วนการยืนยันตัวตนของ Gateway และการตรึง TLS ยังคงเป็นเจ้าของความเชื่อถือ

เมทาดาทาการลงทะเบียน CLI

api.registerCli(registrar, opts?) ยอมรับเมทาดาทาคำสั่งสองประเภท:

  • commands: ชื่อคำสั่งแบบชัดเจนที่ผู้ลงทะเบียนเป็นเจ้าของ
  • descriptors: ตัวอธิบายคำสั่งขณะแยกวิเคราะห์ที่ใช้สำหรับความช่วยเหลือของ CLI การกำหนดเส้นทาง และการลงทะเบียน CLI ของ Plugin แบบโหลดเมื่อจำเป็น
  • parentPath: เส้นทางคำสั่งพาเรนต์ที่เลือกได้สำหรับกลุ่มคำสั่งแบบซ้อน เช่น ["nodes"]

สำหรับคุณลักษณะที่จับคู่กับ Node ควรใช้ api.registerNodeCliFeature(registrar, opts?) ซึ่งเป็นตัวห่อขนาดเล็กรอบ api.registerCli(..., { parentPath: ["nodes"] }) และทำให้คำสั่ง เช่น openclaw nodes canvas เป็นคุณลักษณะ Node ที่ Plugin เป็นเจ้าของอย่างชัดเจน

หากต้องการให้คำสั่ง Plugin ยังคงโหลดเมื่อจำเป็นในเส้นทาง CLI รากปกติ ให้ระบุ descriptors ที่ครอบคลุมรากคำสั่งระดับบนสุดทั้งหมดซึ่งเปิดเผยโดย ผู้ลงทะเบียนนั้น

typescript
api.registerCli(  async ({ program }) => {    const { registerMatrixCli } = await import("./src/cli.js");    registerMatrixCli({ program });  },  {    descriptors: [      {        name: "matrix",        description: "Manage Matrix accounts, verification, devices, and profile state",        hasSubcommands: true,      },    ],  },);

คำสั่งที่ซ้อนกันจะได้รับคำสั่งแม่ที่ผ่านการแก้ไขแล้วเป็น program:

typescript
api.registerCli(  async ({ program }) => {    const { registerNodesCanvasCommands } = await import("./src/cli.js");    registerNodesCanvasCommands(program);  },  {    parentPath: ["nodes"],    descriptors: [      {        name: "canvas",        description: "Capture or render canvas content from a paired node",        hasSubcommands: true,      },    ],  },);

ใช้ commands เพียงอย่างเดียวเฉพาะเมื่อไม่ต้องการการลงทะเบียน CLI รากแบบ lazy เส้นทางความเข้ากันได้แบบ eager นี้ยังคงรองรับอยู่ แต่จะไม่ติดตั้ง ตัวยึดตำแหน่งที่อิง descriptor สำหรับการโหลดแบบ lazy ในเวลา parse

การลงทะเบียนแบ็กเอนด์ CLI

api.registerCliBackend(...) ช่วยให้ Plugin เป็นเจ้าของการกำหนดค่าเริ่มต้นสำหรับ แบ็กเอนด์ AI CLI ภายในเครื่อง เช่น claude-cli หรือ my-cli

  • id ของแบ็กเอนด์จะกลายเป็นคำนำหน้าผู้ให้บริการในการอ้างอิงโมเดล เช่น my-cli/gpt-5
  • config ของแบ็กเอนด์ใช้โครงสร้างเดียวกับ agents.defaults.cliBackends.<id>
  • การกำหนดค่าของผู้ใช้ยังคงมีลำดับความสำคัญสูงกว่า OpenClaw จะผสาน agents.defaults.cliBackends.<id> ทับ ค่าเริ่มต้นของ Plugin ก่อนเรียกใช้ CLI
  • ใช้ normalizeConfig เมื่อแบ็กเอนด์ต้องเขียนค่าใหม่เพื่อความเข้ากันได้หลังการผสาน (ตัวอย่างเช่น การปรับรูปแบบแฟล็กเก่าให้เป็นมาตรฐาน)
  • ใช้ resolveExecutionArgs สำหรับการเขียน argv ใหม่ในขอบเขตคำขอซึ่งเป็นส่วนหนึ่งของ รูปแบบภาษา CLI เช่น การแมประดับการคิดของ OpenClaw ไปยังแฟล็กระดับความพยายาม แบบเนทีฟ ฮุกจะได้รับ ctx.executionMode; ใช้ "side-question" เพื่อเพิ่ม แฟล็กการแยกแบบเนทีฟของแบ็กเอนด์สำหรับการเรียก /btw ชั่วคราว หากแฟล็กเหล่านั้น ปิดใช้งานเครื่องมือแบบเนทีฟได้อย่างเชื่อถือได้สำหรับ CLI ที่เปิดใช้งานตลอดเวลา ให้ประกาศ sideQuestionToolMode: "disabled" ด้วย
  • ใช้ prepareExecution สำหรับสภาพแวดล้อมการเริ่มทำงานที่แบ็กเอนด์เป็นเจ้าของ หรือบริดจ์ การยืนยันตัวตน/การกำหนดค่าชั่วคราว ctx.contextTokenBudget ของส่วนนี้คือขีดจำกัดโทเค็นที่มีผล ซึ่งเลือกไว้สำหรับการทำงาน เพื่อให้แบ็กเอนด์ที่ทำ Compaction แบบเนทีฟสามารถจัดเกณฑ์ ของตนเองให้สอดคล้องกันโดยไม่ต้องมีสาขาในแกนหลักที่เจาะจงผู้ให้บริการ
  • แบ็กเอนด์ที่สามารถปิดใช้งานเครื่องมือแบบเนทีฟทั้งหมดสำหรับการทำงานเฉพาะครั้งอาจประกาศ nativeToolMode: "selectable" การเรียกแบบจำกัดจะส่งทูเพิล ctx.toolAvailability.native ว่างพร้อมรายการอนุญาต MCP ที่แยกจากโฮสต์อย่างเคร่งครัด resolveExecutionArgs ต้องบังคับใช้ทั้งสองอย่างกับ argv สุดท้ายสำหรับการเริ่มใหม่หรือการทำงานต่อ OpenClaw จะปฏิเสธโดยค่าเริ่มต้นหากแบ็กเอนด์ไม่สามารถดำเนินการดังกล่าวได้

สำหรับคู่มือการสร้างแบบครบวงจร โปรดดู Plugin แบ็กเอนด์ CLI

สล็อตเฉพาะ

เมธอด สิ่งที่ลงทะเบียน
api.registerContextEngine(id, factory) กลไกบริบท (ใช้งานได้ครั้งละหนึ่งรายการ) คอลแบ็กวงจรชีวิตจะได้รับ runtimeSettings เมื่อโฮสต์สามารถให้ข้อมูลวินิจฉัยโมเดล/ผู้ให้บริการ/โหมดได้ ส่วนกลไกเข้มงวดรุ่นเก่าจะถูกลองอีกครั้งโดยไม่มีคีย์นั้น
api.registerMemoryCapability(capability) ความสามารถหน่วยความจำแบบรวม

อะแดปเตอร์การฝังหน่วยความจำที่เลิกใช้แล้ว

เมธอด สิ่งที่ลงทะเบียน
api.registerMemoryEmbeddingProvider(adapter) อะแดปเตอร์การฝังหน่วยความจำสำหรับ Plugin ที่ใช้งานอยู่
  • registerMemoryCapability คือ API เฉพาะสำหรับ Plugin หน่วยความจำ
  • registerMemoryCapability อาจเปิดเผย publicArtifacts.listArtifacts(...) สำหรับการส่งออกที่โฮสต์จัดการด้วย Plugin คู่หูที่แจกแจงอาร์ติแฟกต์ที่ประกาศไว้เหล่านั้น ยังคงใช้ listActiveMemoryPublicArtifacts(...) จากฟาซาด openclaw/plugin-sdk/memory-host-core ที่เก็บไว้จนกว่าจะมี API ผู้ใช้สาธารณะ ที่มุ่งเน้นโดยเฉพาะ โดยต้องไม่เข้าถึงโครงสร้างภายในส่วนตัวของ Plugin อื่น
  • MemoryFlushPlan.model สามารถตรึงรอบการ flush ไว้กับการอ้างอิง provider/model ที่แน่นอน เช่น ollama/qwen3:8b โดยไม่สืบทอดสายโซ่ fallback ที่ใช้งานอยู่
  • registerMemoryEmbeddingProvider เลิกใช้แล้ว ผู้ให้บริการการฝังรายใหม่ ควรใช้ api.registerEmbeddingProvider(...) และ contracts.embeddingProviders
  • ผู้ให้บริการเฉพาะหน่วยความจำที่มีอยู่จะยังคงทำงานต่อไปในช่วงการย้ายข้อมูล แต่การตรวจสอบ Plugin จะรายงานสิ่งนี้เป็นภาระด้านความเข้ากันได้สำหรับ Plugin ที่ไม่ได้รวมมาในชุด

เหตุการณ์และวงจรชีวิต

เมธอด สิ่งที่ทำ
api.on(hookName, handler, opts?) ฮุกวงจรชีวิตแบบมีชนิด
api.onConversationBindingResolved(handler) คอลแบ็กการเชื่อมโยงบทสนทนา

ดูตัวอย่าง ชื่อฮุกทั่วไป และความหมายของตัวป้องกันได้ที่ ฮุกของ Plugin

ความหมายของการตัดสินใจของฮุก

before_install เป็นฮุกวงจรชีวิตของรันไทม์ Plugin ไม่ใช่พื้นผิวนโยบายการติดตั้ง สำหรับผู้ปฏิบัติงาน ใช้ security.installPolicy เมื่อการตัดสินใจอนุญาต/บล็อกต้อง ครอบคลุมเส้นทางการติดตั้งหรืออัปเดตผ่าน CLI และ Gateway

  • before_tool_call: การส่งคืน { block: true } ถือเป็นจุดสิ้นสุด เมื่อแฮนด์เลอร์ใดตั้งค่านี้ แฮนด์เลอร์ที่มีลำดับความสำคัญต่ำกว่าจะถูกข้าม
  • before_tool_call: การส่งคืน { block: false } ถือว่าไม่มีการตัดสินใจ (เหมือนกับการละ block) ไม่ใช่การแทนที่
  • before_install: การส่งคืน { block: true } ถือเป็นจุดสิ้นสุด เมื่อแฮนด์เลอร์ใดตั้งค่านี้ แฮนด์เลอร์ที่มีลำดับความสำคัญต่ำกว่าจะถูกข้าม
  • before_install: การส่งคืน { block: false } ถือว่าไม่มีการตัดสินใจ (เหมือนกับการละ block) ไม่ใช่การแทนที่
  • reply_dispatch: การส่งคืน { handled: true, ... } ถือเป็นจุดสิ้นสุด เมื่อแฮนด์เลอร์ใดรับการจัดส่งแล้ว แฮนด์เลอร์ที่มีลำดับความสำคัญต่ำกว่าและเส้นทางการจัดส่งโมเดลเริ่มต้นจะถูกข้าม
  • message_sending: การส่งคืน { cancel: true } ถือเป็นจุดสิ้นสุด เมื่อแฮนด์เลอร์ใดตั้งค่านี้ แฮนด์เลอร์ที่มีลำดับความสำคัญต่ำกว่าจะถูกข้าม
  • message_sending: การส่งคืน { cancel: false } ถือว่าไม่มีการตัดสินใจ (เหมือนกับการละ cancel) ไม่ใช่การแทนที่
  • message_received: ใช้ฟิลด์ threadId แบบมีชนิดเมื่อต้องการกำหนดเส้นทางเธรด/หัวข้อขาเข้า เก็บ metadata ไว้สำหรับข้อมูลเพิ่มเติมเฉพาะช่องทาง
  • message_sending: ใช้ฟิลด์การกำหนดเส้นทาง replyToId / threadId แบบมีชนิดก่อน fallback ไปยัง metadata เฉพาะช่องทาง
  • gateway_start: ใช้ ctx.config, ctx.workspaceDir และ ctx.getCron?.() สำหรับสถานะการเริ่มต้นที่ Gateway เป็นเจ้าของ แทนการพึ่งพาฮุก gateway:startup ภายใน Cron อาจยังโหลดอยู่ ณ จุดนี้
  • cron_reconciled: สร้างการฉายภาพ Cron ภายนอกแบบสมบูรณ์ขึ้นใหม่หลังการเริ่มต้นหรือการโหลดตัวจัดกำหนดการใหม่ โดยรวม reason และสถานะ enabled ที่มีผล รวมถึง enabled: false ขณะที่ ctx.getCron?.() ส่งคืนตัวจัดกำหนดการที่ปรับให้ตรงกันอย่างแน่นอน ส่ง ctx.abortSignal เข้าไปในงานฉายภาพแบบคงทน โดยจะยกเลิกเมื่อตัวอย่างสถานะตัวจัดกำหนดการนั้นถูกแทนที่หรือ Gateway ปิด
  • cron_changed: สังเกตการเปลี่ยนแปลงวงจรชีวิต Cron ที่ Gateway เป็นเจ้าของ เหตุการณ์ scheduled และ removed เป็นคำใบ้การปรับให้ตรงกันหลังคอมมิต ไม่ใช่บันทึกเดลตาตามลำดับ event.nextRunAtMs ของเหตุการณ์ที่กำหนดเวลาไว้จะไม่มีอยู่เมื่องานไม่มีเวลาปลุกครั้งถัดไป ส่วนเหตุการณ์ที่นำออกยังคงมีตัวอย่างสถานะของงานที่ถูกลบ

ตัวจัดกำหนดการปลุกภายนอกควรหน่วงหรือรวมเหตุการณ์ cron_changed จากนั้นอ่านมุมมองแบบคงทนทั้งหมดอีกครั้งจากตัวจัดกำหนดการล่าสุดที่ cron_reconciled จับไว้ อย่านำตัวจัดกำหนดการจากบริบท cron_changed มาใช้: คำใบ้ที่แยกออกมาจากตัวจัดกำหนดการรุ่นเก่าอาจทับซ้อนกับการโหลดใหม่ในภายหลัง

ใช้ cron_reconciled เป็นตัวกระตุ้นตัวอย่างสถานะทั้งหมดสำหรับสถานะแบบคงทนที่โหลดเมื่อ Gateway เริ่มทำงานหรือเมื่อตัวจัดกำหนดการถูกแทนที่ ระบบจะไม่เล่นซ้ำสำหรับการ hot reload เฉพาะ Plugin แฮนด์เลอร์การสังเกตทำงานแบบขนาน และการจัดส่ง แบบ fire-and-forget อาจทับซ้อนกัน ดังนั้นผู้ใช้ต้องไม่พึ่งพาลำดับการเสร็จสิ้นของเหตุการณ์ ให้ OpenClaw เป็นแหล่งข้อมูลจริงสำหรับการตรวจสอบกำหนดเวลาและการดำเนินการ

สำหรับอะแดปเตอร์แบบ single-flight ที่มีการแทนที่แบบคงทน การลองใหม่/การหน่วงเวลาถอยกลับ และการ ปิดระบบอย่างเรียบร้อย โปรดดู การฉายภาพ Cron ภายนอกอย่างปลอดภัย

ฟิลด์ออบเจ็กต์ API

ฟิลด์ ชนิด คำอธิบาย
api.id string รหัส Plugin
api.name string ชื่อที่แสดง
api.version string? เวอร์ชัน Plugin (ไม่บังคับ)
api.description string? คำอธิบาย Plugin (ไม่บังคับ)
api.source string พาธต้นทางของ Plugin
api.rootDir string? ไดเรกทอรีรากของ Plugin (ไม่บังคับ)
api.config OpenClawConfig ตัวอย่างสถานะการกำหนดค่าปัจจุบัน (ตัวอย่างสถานะรันไทม์ในหน่วยความจำที่ใช้งานอยู่เมื่อพร้อมใช้งาน)
api.pluginConfig Record<string, unknown> การกำหนดค่าเฉพาะ Plugin จาก plugins.entries.<id>.config
api.runtime PluginRuntime ตัวช่วยรันไทม์
api.logger PluginLogger ตัวบันทึกแบบจำกัดขอบเขต (debug, info, warn, error)
api.registrationMode PluginRegistrationMode โหมดการโหลดปัจจุบัน; "setup-runtime" คือช่วงเริ่มต้น/ตั้งค่าแบบเบาก่อนเข้าสู่รายการแบบเต็ม
api.resolvePath(input) (string) => string แก้ไขพาธโดยอ้างอิงจากรากของ Plugin

ข้อกำหนดโมดูลภายใน

ภายใน Plugin ให้ใช้ไฟล์ barrel ภายในเครื่องสำหรับการนำเข้าภายใน:

text
my-plugin/  api.ts            # การส่งออกสาธารณะสำหรับผู้ใช้ภายนอก  runtime-api.ts    # การส่งออกรันไทม์สำหรับใช้ภายในเท่านั้น  index.ts          # จุดเริ่มต้นของ Plugin  setup-entry.ts    # จุดเริ่มต้นแบบเบาสำหรับการตั้งค่าเท่านั้น (ไม่บังคับ)

พื้นผิวสาธารณะของ Plugin แบบรวมที่โหลดผ่าน facade (api.ts, runtime-api.ts, index.ts, setup-entry.ts และไฟล์จุดเข้าใช้งานสาธารณะที่คล้ายกัน) จะเลือกใช้ สแนปช็อตการกำหนดค่ารันไทม์ที่ทำงานอยู่เมื่อ OpenClaw กำลังทำงานแล้ว หากยังไม่มี สแนปช็อตรันไทม์ ระบบจะถอยกลับไปใช้ไฟล์การกำหนดค่าที่ได้รับการแก้ไขตำแหน่งแล้วบนดิสก์ facade ของ Plugin แบบรวมที่จัดแพ็กเกจควรโหลดผ่านตัวโหลด facade ของ Plugin ของ OpenClaw การนำเข้าโดยตรงจาก dist/extensions/... จะข้ามการตรวจสอบ manifest และ runtime sidecar ซึ่งการติดตั้งแบบจัดแพ็กเกจใช้กับโค้ดที่ Plugin เป็นเจ้าของ

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

  • Anthropic: จุดเชื่อมต่อสาธารณะ api.ts / contract-api.ts สำหรับตัวช่วย beta-header ของ Claude และสตรีม service_tier
  • @openclaw/openai-provider: api.ts ส่งออกตัวสร้างผู้ให้บริการ ตัวช่วยโมเดลเริ่มต้น และตัวสร้างผู้ให้บริการแบบเรียลไทม์
  • @openclaw/openrouter-provider: api.ts ส่งออกตัวสร้างผู้ให้บริการ พร้อมตัวช่วยการเริ่มต้นใช้งาน/การกำหนดค่า

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

Was this useful?
On this page

On this page