Plugins
จุดเข้าใช้งานของ Plugin
ทุก Plugin ส่งออกอ็อบเจกต์ entry เริ่มต้น SDK มีตัวช่วยสามรายการสำหรับ สร้างอ็อบเจกต์เหล่านี้
สำหรับ Plugin ที่ติดตั้งแล้ว package.json ควรชี้การโหลดรันไทม์ไปยัง
JavaScript ที่บิลด์แล้วเมื่อมีให้ใช้:
{
"openclaw": {
"extensions": ["./src/index.ts"],
"runtimeExtensions": ["./dist/index.js"],
"setupEntry": "./src/setup-entry.ts",
"runtimeSetupEntry": "./dist/setup-entry.js"
}
}
extensions และ setupEntry ยังคงเป็น entry ซอร์สที่ใช้ได้สำหรับการพัฒนา
ในเวิร์กสเปซและ git checkout แนะนำให้ใช้ runtimeExtensions และ
runtimeSetupEntry เมื่อ OpenClaw โหลดแพ็กเกจที่ติดตั้งแล้ว และช่วยให้แพ็กเกจ
npm หลีกเลี่ยงการคอมไพล์ TypeScript ระหว่างรันไทม์ จำเป็นต้องระบุ entry รันไทม์
อย่างชัดเจน: runtimeSetupEntry ต้องมี setupEntry และหากไม่มีอาร์ติแฟกต์
runtimeExtensions หรือ runtimeSetupEntry การติดตั้ง/การค้นหาจะล้มเหลว
แทนที่จะถอยกลับไปใช้ซอร์สแบบเงียบ ๆ หากแพ็กเกจที่ติดตั้งแล้วประกาศเฉพาะ
entry ซอร์ส TypeScript OpenClaw จะใช้เพียร์ dist/*.js ที่บิลด์แล้วซึ่งตรงกัน
เมื่อมีอยู่ จากนั้นจึงถอยกลับไปใช้ซอร์ส TypeScript
พาธ entry ทั้งหมดต้องอยู่ภายในไดเรกทอรีแพ็กเกจของ Plugin entry รันไทม์และ
เพียร์ JavaScript ที่บิลด์แล้วซึ่งอนุมานได้ ไม่ได้ทำให้พาธซอร์ส extensions
หรือ setupEntry ที่หลุดออกนอกแพ็กเกจกลายเป็นพาธที่ใช้ได้
definePluginEntry
นำเข้า: openclaw/plugin-sdk/plugin-entry
สำหรับ Plugin ของ provider, Plugin เครื่องมือ, Plugin hook และทุกอย่างที่ ไม่ใช่ ช่องทางรับส่งข้อความ
export default definePluginEntry({
id: "my-plugin",
name: "My Plugin",
description: "Short summary",
register(api) {
api.registerProvider({
/* ... */
});
api.registerTool({
/* ... */
});
},
});
| ฟิลด์ | ประเภท | จำเป็น | ค่าเริ่มต้น |
|---|---|---|---|
id |
string |
ใช่ | - |
name |
string |
ใช่ | - |
description |
string |
ใช่ | - |
kind |
string |
ไม่ | - |
configSchema |
OpenClawPluginConfigSchema | () => OpenClawPluginConfigSchema |
ไม่ | สคีมาวัตถุว่าง |
register |
(api: OpenClawPluginApi) => void |
ใช่ | - |
idต้องตรงกับ manifestopenclaw.plugin.jsonของคุณkindใช้สำหรับสล็อตแบบเอกสิทธิ์:"memory"หรือ"context-engine"configSchemaอาจเป็นฟังก์ชันสำหรับการประเมินแบบ lazy- OpenClaw จะแก้ค่าและ memoize สคีมานั้นในการเข้าถึงครั้งแรก ดังนั้นตัวสร้างสคีมาที่แพง จะทำงานเพียงครั้งเดียว
defineChannelPluginEntry
นำเข้า: openclaw/plugin-sdk/channel-core
ห่อ definePluginEntry ด้วยการเชื่อมต่อเฉพาะช่องทาง เรียก
api.registerChannel({ plugin }) โดยอัตโนมัติ เปิดเผย seam เมทาดาทา CLI
สำหรับ root-help แบบไม่บังคับ และ gate registerFull ตามโหมดการลงทะเบียน
export default defineChannelPluginEntry({
id: "my-channel",
name: "My Channel",
description: "Short summary",
plugin: myChannelPlugin,
setRuntime: setMyRuntime,
registerCliMetadata(api) {
api.registerCli(/* ... */);
},
registerFull(api) {
api.registerGatewayMethod(/* ... */);
},
});
| ฟิลด์ | ประเภท | จำเป็น | ค่าเริ่มต้น |
|---|---|---|---|
id |
string |
ใช่ | - |
name |
string |
ใช่ | - |
description |
string |
ใช่ | - |
plugin |
ChannelPlugin |
ใช่ | - |
configSchema |
OpenClawPluginConfigSchema | () => OpenClawPluginConfigSchema |
ไม่ | สคีมาวัตถุว่าง |
setRuntime |
(runtime: PluginRuntime) => void |
ไม่ | - |
registerCliMetadata |
(api: OpenClawPluginApi) => void |
ไม่ | - |
registerFull |
(api: OpenClawPluginApi) => void |
ไม่ | - |
setRuntimeจะถูกเรียกระหว่างการลงทะเบียนเพื่อให้คุณเก็บ reference ของรันไทม์ได้ (โดยทั่วไปผ่านcreatePluginRuntimeStore) โดยจะถูกข้ามระหว่างการจับเมทาดาทา CLIregisterCliMetadataทำงานระหว่างapi.registrationMode === "cli-metadata",api.registrationMode === "discovery"และapi.registrationMode === "full"ใช้เป็นตำแหน่งมาตรฐานสำหรับตัวบรรยาย CLI ที่ช่องทางเป็นเจ้าของ เพื่อให้ root help ไม่ก่อให้เกิดการ activate, snapshot การค้นหารวมเมทาดาทาคำสั่งแบบคงที่ และ การลงทะเบียนคำสั่ง CLI ปกติยังคงเข้ากันได้กับการโหลด Plugin แบบเต็ม- การลงทะเบียนเพื่อค้นหาเป็นแบบไม่ก่อให้เกิดการ activate ไม่ใช่ import-free OpenClaw อาจ
ประเมิน entry ของ Plugin ที่เชื่อถือได้และโมดูล Plugin ช่องทางเพื่อสร้าง
snapshot ดังนั้นให้ import ระดับบนสุดไม่มี side effect และวาง socket,
client, worker และ service ไว้หลังพาธเฉพาะ
"full" registerFullทำงานเฉพาะเมื่อapi.registrationMode === "full"โดยจะถูกข้าม ระหว่างการโหลดเฉพาะการตั้งค่า- เช่นเดียวกับ
definePluginEntry,configSchemaสามารถเป็น factory แบบ lazy และ OpenClaw จะ memoize สคีมาที่แก้ค่าแล้วในการเข้าถึงครั้งแรก - สำหรับคำสั่ง CLI ระดับ root ที่ Plugin เป็นเจ้าของ แนะนำให้ใช้
api.registerCli(..., { descriptors: [...] })เมื่อคุณต้องการให้คำสั่งยังคง lazy-loaded โดยไม่หายไปจาก parse tree ของ CLI ระดับ root สำหรับ Plugin ช่องทาง แนะนำให้ลงทะเบียนตัวบรรยายเหล่านั้น จากregisterCliMetadata(...)และให้registerFull(...)เน้นงานที่ใช้เฉพาะรันไทม์ - หาก
registerFull(...)ลงทะเบียนเมธอด RPC ของ Gateway ด้วย ให้เก็บไว้ภายใต้ prefix เฉพาะ Plugin namespace ผู้ดูแลระบบหลักที่สงวนไว้ (config.*,exec.approvals.*,wizard.*,update.*) จะถูกบังคับเป็นoperator.adminเสมอ
defineSetupPluginEntry
นำเข้า: openclaw/plugin-sdk/channel-core
สำหรับไฟล์ setup-entry.ts แบบเบา คืนค่าเพียง { plugin } โดยไม่มี
การเชื่อมต่อรันไทม์หรือ CLI
export default defineSetupPluginEntry(myChannelPlugin);
OpenClaw โหลดสิ่งนี้แทน entry แบบเต็มเมื่อช่องทางถูกปิดใช้งาน, ยังไม่ได้กำหนดค่า หรือเมื่อเปิดใช้การโหลดแบบเลื่อนเวลา ดู การตั้งค่าและการกำหนดค่า เพื่อดูว่าเรื่องนี้สำคัญเมื่อใด
ในทางปฏิบัติ ให้จับคู่ defineSetupPluginEntry(...) กับกลุ่มตัวช่วยการตั้งค่าแบบแคบ:
openclaw/plugin-sdk/setup-runtimeสำหรับตัวช่วยการตั้งค่าที่ปลอดภัยต่อรันไทม์ เช่น adapter สำหรับแพตช์การตั้งค่าที่ import-safe, เอาต์พุต lookup-note,promptResolvedAllowFrom,splitSetupEntriesและ proxy การตั้งค่าแบบ delegatedopenclaw/plugin-sdk/channel-setupสำหรับพื้นผิวการตั้งค่า optional-installopenclaw/plugin-sdk/setup-toolsสำหรับตัวช่วย CLI/archive/docs ของการตั้งค่า/ติดตั้ง
เก็บ SDK หนัก ๆ, การลงทะเบียน CLI และ service รันไทม์ที่อยู่ยาวไว้ใน entry แบบเต็ม
ช่องทางในเวิร์กสเปซที่ bundled ซึ่งแยกพื้นผิวการตั้งค่าและรันไทม์สามารถใช้
defineBundledChannelSetupEntry(...) จาก
openclaw/plugin-sdk/channel-entry-contract แทนได้ contract นั้นทำให้
entry การตั้งค่าเก็บ export ของ Plugin/secret ที่ปลอดภัยต่อการตั้งค่าไว้ได้ พร้อมกับยังเปิดเผย
runtime setter:
export default defineBundledChannelSetupEntry({
importMetaUrl: import.meta.url,
plugin: {
specifier: "./channel-plugin-api.js",
exportName: "myChannelPlugin",
},
runtime: {
specifier: "./runtime-api.js",
exportName: "setMyChannelRuntime",
},
});
ใช้ contract แบบ bundled นั้นเฉพาะเมื่อ flow การตั้งค่าต้องการ runtime setter แบบเบาจริง ๆ ก่อนที่ entry ช่องทางแบบเต็มจะโหลด
โหมดการลงทะเบียน
api.registrationMode บอก Plugin ของคุณว่าถูกโหลดมาอย่างไร:
| โหมด | เมื่อใด | สิ่งที่ต้องลงทะเบียน |
|---|---|---|
"full" |
การเริ่มต้น Gateway ปกติ | ทุกอย่าง |
"discovery" |
การค้นหาความสามารถแบบอ่านอย่างเดียว | การลงทะเบียนช่องทางพร้อมตัวบรรยาย CLI แบบคงที่; โค้ด entry อาจโหลด แต่ให้ข้าม socket, worker, client และ service |
"setup-only" |
ช่องทางถูกปิดใช้งาน/ยังไม่ได้กำหนดค่า | การลงทะเบียนช่องทางเท่านั้น |
"setup-runtime" |
flow การตั้งค่าที่มีรันไทม์พร้อมใช้ | การลงทะเบียนช่องทางพร้อมเฉพาะรันไทม์แบบเบาที่จำเป็นก่อน entry แบบเต็มจะโหลด |
"cli-metadata" |
การจับ root help / เมทาดาทา CLI | ตัวบรรยาย CLI เท่านั้น |
defineChannelPluginEntry จัดการการแยกนี้โดยอัตโนมัติ หากคุณใช้
definePluginEntry โดยตรงสำหรับช่องทาง ให้ตรวจสอบโหมดด้วยตนเอง:
register(api) {
if (
api.registrationMode === "cli-metadata" ||
api.registrationMode === "discovery" ||
api.registrationMode === "full"
) {
api.registerCli(/* ... */);
if (api.registrationMode === "cli-metadata") return;
}
api.registerChannel({ plugin: myPlugin });
if (api.registrationMode !== "full") return;
// Heavy runtime-only registrations
api.registerService(/* ... */);
}
โหมด discovery สร้าง snapshot registry ที่ไม่ก่อให้เกิดการ activate แต่ยังอาจประเมิน entry ของ Plugin และอ็อบเจกต์ Plugin ช่องทาง เพื่อให้ OpenClaw สามารถลงทะเบียน ความสามารถของช่องทางและตัวบรรยาย CLI แบบคงที่ได้ ให้ถือว่าการประเมินโมดูลใน discovery เป็น สิ่งที่เชื่อถือได้แต่เบา: ห้ามมี network client, subprocess, listener, การเชื่อมต่อฐานข้อมูล, background worker, การอ่าน credential หรือ side effect รันไทม์จริงอื่น ๆ ที่ระดับบนสุด
ให้ถือว่า "setup-runtime" เป็นช่วงเวลาที่พื้นผิวเริ่มต้นเฉพาะการตั้งค่าต้อง
มีอยู่โดยไม่กลับเข้าไปยังรันไทม์ช่องทาง bundled แบบเต็ม สิ่งที่เหมาะคือ
การลงทะเบียนช่องทาง, route HTTP ที่ปลอดภัยต่อการตั้งค่า, เมธอด Gateway ที่ปลอดภัยต่อการตั้งค่า และ
ตัวช่วยการตั้งค่าแบบ delegated service เบื้องหลังที่หนัก, CLI registrar และ
bootstrap ของ provider/client SDK ยังคงควรอยู่ใน "full"
สำหรับ CLI registrar โดยเฉพาะ:
- ใช้
descriptorsเมื่อ registrar เป็นเจ้าของคำสั่งระดับ root หนึ่งคำสั่งขึ้นไป และคุณ ต้องการให้ OpenClaw lazy-load โมดูล CLI จริงเมื่อเรียกใช้ครั้งแรก - ตรวจสอบให้แน่ใจว่าตัวบรรยายเหล่านั้นครอบคลุม root คำสั่งระดับบนสุดทุกตัวที่ registrar เปิดเผย
- จำกัดชื่อคำสั่งในตัวบรรยายให้เป็นตัวอักษร ตัวเลข hyphen และ underscore โดยเริ่มต้นด้วยตัวอักษรหรือตัวเลข; OpenClaw จะปฏิเสธชื่อตัวบรรยายที่อยู่นอก รูปแบบนั้น และตัดลำดับควบคุมเทอร์มินัลออกจากคำอธิบายก่อน แสดงผล help
- ใช้
commandsอย่างเดียวเฉพาะสำหรับพาธความเข้ากันได้แบบ eager
รูปแบบของ Plugin
OpenClaw จำแนก Plugin ที่โหลดแล้วตามพฤติกรรมการลงทะเบียน:
| รูปแบบ | คำอธิบาย |
|---|---|
| plain-capability | ประเภทความสามารถเดียว (เช่น เฉพาะผู้ให้บริการ) |
| hybrid-capability | ความสามารถหลายประเภท (เช่น ผู้ให้บริการ + คำพูด) |
| hook-only | เฉพาะ hook เท่านั้น ไม่มีความสามารถ |
| non-capability | เครื่องมือ/คำสั่ง/บริการ แต่ไม่มีความสามารถ |
ใช้ openclaw plugins inspect <id> เพื่อดูรูปแบบของ Plugin
ที่เกี่ยวข้อง
- ภาพรวม SDK - API การลงทะเบียนและข้อมูลอ้างอิง subpath
- ตัวช่วย Runtime -
api.runtimeและcreatePluginRuntimeStore - การตั้งค่าและการกำหนดค่า - manifest, จุดเข้า setup, การโหลดแบบเลื่อนออกไป
- Channel Plugins - การสร้างอ็อบเจกต์
ChannelPlugin - Provider Plugins - การลงทะเบียนผู้ให้บริการและ hook