Building plugins
Plugin alat
defineToolPlugin membangun plugin yang hanya menambahkan alat yang dapat dipanggil agen: tanpa
saluran, penyedia model, hook, layanan, atau backend penyiapan. Fungsi ini menghasilkan
metadata manifes yang diperlukan OpenClaw untuk menemukan alat tanpa memuat kode
runtime plugin.
Untuk plugin penyedia, saluran, hook, layanan, atau plugin dengan kemampuan campuran, mulailah dengan Membangun plugin, Plugin Saluran, atau Plugin Penyedia.
Persyaratan
- Node 22.19+, Node 23.11+, atau Node 24+.
- Keluaran paket TypeScript ESM.
typeboxdidependencies(bukan hanyadevDependencies- plugin yang dihasilkan mengimpornya saat runtime).openclaw >=2026.5.17, versi pertama yang mengeksporopenclaw/plugin-sdk/tool-plugin.- Root paket yang menyertakan
dist/,openclaw.plugin.json, danpackage.json.
Mulai cepat
openclaw plugins init stock-quotes --name "Stock Quotes"cd stock-quotesnpm installnpm run plugin:buildnpm run plugin:validatenpm testplugins init membuat kerangka:
| Berkas | Tujuan |
|---|---|
src/index.ts |
Entri defineToolPlugin dengan satu alat echo |
src/index.test.ts |
Pengujian metadata yang memeriksa daftar alat |
tsconfig.json |
Keluaran TypeScript NodeNext ke dist/ |
vitest.config.ts |
Konfigurasi Vitest untuk src/**/*.test.ts |
package.json |
Skrip, dependensi runtime, openclaw.extensions: ["./dist/index.js"] |
openclaw.plugin.json |
Metadata manifes yang dihasilkan untuk alat awal |
npm run plugin:build menjalankan npm run build (tsc), lalu
openclaw plugins build --entry ./dist/index.js. npm run plugin:validate
membangun ulang dan menjalankan openclaw plugins validate --entry ./dist/index.js.
Validasi yang berhasil menampilkan:
Plugin stock-quotes is valid.Opsi openclaw plugins init <id>:
| Flag | Bawaan | Efek |
|---|---|---|
--directory <path> |
<id> |
Direktori keluaran |
--name <name> |
<id> dalam format judul |
Nama tampilan |
--type <type> |
tool |
Jenis kerangka: tool atau provider |
--force |
nonaktif | Timpa direktori keluaran yang sudah ada |
Menulis alat
defineToolPlugin menerima identitas plugin, skema konfigurasi opsional, dan
daftar alat statis. Jenis parameter dan konfigurasi disimpulkan dari
skema TypeBox.
export default defineToolPlugin({ id: "stock-quotes", name: "Stock Quotes", description: "Fetch stock quote snapshots.", configSchema: Type.Object({ apiKey: Type.Optional(Type.String({ description: "Quote API key." })), baseUrl: Type.Optional(Type.String({ description: "Quote API base URL." })), }), tools: (tool) => [ tool({ name: "stock_quote", label: "Stock Quote", description: "Fetch a stock quote snapshot.", parameters: Type.Object({ symbol: Type.String({ description: "Ticker symbol, for example OPEN." }), }), async execute({ symbol }, config, context) { context.signal?.throwIfAborted(); return { symbol: symbol.toUpperCase(), configured: Boolean(config.apiKey), baseUrl: config.baseUrl ?? "https://api.example.com", }; }, }), ],});Nama alat adalah API yang stabil. Pilih nama yang unik, menggunakan huruf kecil, dan cukup spesifik untuk menghindari benturan dengan alat inti atau plugin lain.
Alat opsional dan alat pabrik
Tetapkan optional: true ketika pengguna harus secara eksplisit memasukkan alat ke daftar izin sebelum
alat dikirim ke model. openclaw plugins build menulis entri manifes
toolMetadata.<tool>.optional yang sesuai, sehingga OpenClaw dapat mengetahui bahwa
alat tersebut opsional tanpa memuat kode runtime plugin.
tool({ name: "workflow_run", description: "Run an external workflow.", parameters: Type.Object({ goal: Type.String() }), optional: true, execute: ({ goal }) => ({ queued: true, goal }),});Gunakan factory ketika alat memerlukan konteks alat runtime sebelum dapat
dibuat—untuk tidak mengikutsertakannya dalam proses tertentu, memeriksa status sandbox, atau mengikat
pembantu runtime. Metadata tetap statis meskipun alat konkretnya dibuat
saat runtime.
tool({ name: "local_workflow", description: "Run a local workflow outside sandboxed sessions.", parameters: Type.Object({ goal: Type.String() }), optional: true, factory({ api, toolContext }) { if (toolContext.sandboxed) { return null; } return createLocalWorkflowTool(api); },});Pabrik tetap mendeklarasikan nama alat tetap di awal. Gunakan definePluginEntry
secara langsung ketika plugin menghitung nama alat secara dinamis atau menggabungkan alat
dengan hook, layanan, penyedia, atau perintah.
Nilai kembalian
defineToolPlugin membungkus nilai kembalian biasa ke dalam format hasil alat
OpenClaw:
- Kembalikan string ketika model harus melihat teks persis tersebut.
- Kembalikan nilai yang kompatibel dengan JSON ketika Anda ingin model melihat JSON yang diformat
dan OpenClaw menyimpan nilai aslinya di
details.
tool({ name: "echo_text", description: "Echo input text.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => input,});tool({ name: "echo_json", description: "Echo input as structured JSON.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => ({ input, length: input.length }),});Gunakan alat pabrik ketika Anda memerlukan AgentToolResult khusus atau ingin menggunakan kembali
implementasi api.registerTool yang sudah ada.
Konfigurasi
configSchema bersifat opsional. Hilangkan properti ini dan OpenClaw akan menerapkan skema objek kosong
yang ketat; manifes yang dihasilkan tetap menyertakan configSchema.
export default defineToolPlugin({ id: "no-config-tools", name: "No Config Tools", description: "Adds tools that do not need configuration.", tools: () => [],});Dengan configSchema, argumen kedua execute diberi tipe berdasarkan skema tersebut:
const configSchema = Type.Object({ apiKey: Type.String(),}); export default defineToolPlugin({ id: "configured-tools", name: "Configured Tools", description: "Adds configured tools.", configSchema, tools: (tool) => [ tool({ name: "configured_ping", description: "Check whether configuration is available.", parameters: Type.Object({}), execute: (_params, config) => ({ hasKey: config.apiKey.length > 0 }), }), ],});OpenClaw membaca konfigurasi plugin dari entri plugin dalam konfigurasi Gateway. Jangan menanamkan rahasia langsung dalam contoh kode sumber atau dokumentasi; gunakan konfigurasi, variabel lingkungan, atau SecretRefs sesuai model keamanan plugin.
Metadata yang dihasilkan
OpenClaw harus membaca manifes plugin sebelum mengimpor kode runtime plugin.
defineToolPlugin menyediakan metadata statis untuk keperluan ini, dan
openclaw plugins build menuliskannya ke dalam paket. Jalankan ulang generator setelah
mengubah id, nama, deskripsi, skema konfigurasi, aktivasi, atau nama alat
plugin:
npm run buildopenclaw plugins build --entry ./dist/index.jsManifes yang dihasilkan untuk plugin dengan satu alat:
{ "id": "stock-quotes", "name": "Stock Quotes", "description": "Fetch stock quote snapshots.", "version": "0.1.0", "configSchema": { "type": "object", "additionalProperties": false, "properties": {} }, "activation": { "onStartup": true }, "contracts": { "tools": ["stock_quote"] }}contracts.tools adalah kontrak penemuan yang penting: kontrak ini memberi tahu OpenClaw
plugin mana yang memiliki setiap alat tanpa memuat runtime setiap plugin yang terpasang. Manifes
yang usang dapat menyebabkan alat tidak ditemukan, atau kesalahan pendaftaran
dikaitkan dengan plugin yang salah.
Metadata paket
openclaw plugins build juga menyelaraskan package.json dengan entri runtime
yang dipilih:
{ "type": "module", "files": ["dist", "openclaw.plugin.json", "README.md"], "dependencies": { "typebox": "^1.1.38" }, "peerDependencies": { "openclaw": ">=2026.5.17" }, "openclaw": { "extensions": ["./dist/index.js"] }}Sertakan JavaScript hasil pembangunan (./dist/index.js), bukan entri sumber TypeScript.
Entri sumber hanya berfungsi untuk pengembangan lokal dalam ruang kerja.
Memvalidasi di CI
plugins build --check gagal tanpa menulis ulang berkas ketika metadata yang dihasilkan
sudah usang:
npm run buildopenclaw plugins build --entry ./dist/index.js --checkopenclaw plugins validate --entry ./dist/index.jsnpm testplugins validate memeriksa bahwa:
openclaw.plugin.jsontersedia dan lolos pemuat manifes normal.- Entri saat ini mengekspor metadata
defineToolPlugin. - Bidang manifes yang dihasilkan cocok dengan metadata entri.
contracts.toolscocok dengan nama alat yang dideklarasikan.package.jsonmengarahkanopenclaw.extensionske entri runtime yang dipilih.
Memasang dan memeriksa secara lokal
Dari checkout OpenClaw terpisah atau CLI yang sudah terpasang, pasang jalur paket:
openclaw plugins install ./stock-quotesopenclaw plugins inspect stock-quotes --runtimeUntuk pengujian asap paket, kemas terlebih dahulu lalu pasang tarball:
npm packopenclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgzopenclaw plugins inspect stock-quotes --runtime --jsonSetelah memasang, mulai ulang atau muat ulang Gateway dan minta agen menggunakan alat tersebut. Jika alat tidak terlihat, periksa runtime plugin dan katalog alat efektif sebelum mengubah kode (lihat Pemecahan masalah).
Menerbitkan
Terbitkan melalui ClawHub setelah paket siap. clawhub package publish
menerima sumber: folder lokal, repositori GitHub (owner/repo[@ref]), atau
URL tarball.
clawhub package publish ./stock-quotes --dry-runclawhub package publish ./stock-quotesPasang dengan pelacak ClawHub eksplisit:
openclaw plugins install clawhub:your-org/stock-quotesSpesifikasi paket npm tanpa awalan tetap dipasang dari npm selama transisi peluncuran, tetapi ClawHub adalah sarana penemuan dan distribusi yang diutamakan untuk plugin OpenClaw. Lihat Penerbitan ClawHub untuk cakupan pemilik dan tinjauan rilis.
Pemecahan masalah
plugin entry not found: ./dist/index.js
Berkas entri yang dipilih tidak tersedia. Jalankan npm run build, lalu jalankan kembali
openclaw plugins build --entry ./dist/index.js atau
openclaw plugins validate --entry ./dist/index.js.
plugin entry does not expose defineToolPlugin metadata
Entri tidak mengekspor nilai yang dibuat oleh defineToolPlugin. Pastikan
ekspor bawaan modul adalah hasil defineToolPlugin(...), atau berikan
entri yang benar dengan --entry.
openclaw.plugin.json generated metadata is stale
Manifes tidak lagi cocok dengan metadata entri. Jalankan:
npm run buildopenclaw plugins build --entry ./dist/index.jsCommit perubahan openclaw.plugin.json dan package.json.
package.json openclaw.extensions must include ./dist/index.js
Metadata paket mengarah ke entri runtime lain. Jalankan
openclaw plugins build --entry ./dist/index.js agar generator menyelaraskan
metadata paket dengan entri yang ingin Anda sertakan.
Cannot find package 'typebox'
Plugin hasil pembangunan mengimpor typebox saat runtime. Pertahankan paket tersebut di dependencies,
pasang ulang, bangun ulang, dan jalankan kembali validasi.
Alat tidak muncul setelah pemasangan
Periksa hal berikut secara berurutan:
openclaw plugins inspect <plugin-id> --runtimeopenclaw plugins validate --root <plugin-root> --entry ./dist/index.jsopenclaw.plugin.jsonmemilikicontracts.toolsdengan nama alat yang diharapkan.package.jsonmemilikiopenclaw.extensions: ["./dist/index.js"].- Gateway telah dimulai ulang atau dimuat ulang setelah menginstal plugin.