Plugins

Membangun Plugin

Plugin memperluas OpenClaw dengan kapabilitas baru: kanal, penyedia model, ucapan, transkripsi realtime, suara realtime, pemahaman media, pembuatan gambar, pembuatan video, pengambilan web, pencarian web, alat agen, atau kombinasi apa pun.

Anda tidak perlu menambahkan Plugin Anda ke repositori OpenClaw. Publikasikan ke ClawHub dan pengguna memasang dengan openclaw plugins install clawhub:<package-name>. Spesifikasi paket polos tetap dipasang dari npm selama peralihan peluncuran.

Prasyarat

  • Node >= 22 dan manajer paket (npm atau pnpm)
  • Familiar dengan TypeScript (ESM)
  • Untuk Plugin dalam repo: repositori sudah dikloning dan pnpm install sudah selesai. Pengembangan Plugin checkout sumber hanya mendukung pnpm karena OpenClaw memuat Plugin bundel dari paket workspace extensions/*.

Jenis Plugin apa?

Untuk Plugin kanal yang tidak dijamin terpasang saat onboarding/penyiapan berjalan, gunakan createOptionalChannelSetupSurface(...) dari openclaw/plugin-sdk/channel-setup. Ini menghasilkan pasangan adaptor penyiapan + wizard yang mengiklankan persyaratan pemasangan dan gagal secara tertutup pada penulisan konfigurasi nyata hingga Plugin terpasang.

Mulai cepat: Plugin alat

Panduan ini membuat Plugin minimal yang mendaftarkan alat agen. Plugin kanal dan penyedia memiliki panduan khusus yang ditautkan di atas.

  • Buat paket dan manifes

    {
    "name": "@myorg/openclaw-my-plugin",
    "version": "1.0.0",
    "type": "module",
    "openclaw": {
      "extensions": ["./index.ts"],
      "compat": {
        "pluginApi": ">=2026.3.24-beta.2",
        "minGatewayVersion": "2026.3.24-beta.2"
      },
      "build": {
        "openclawVersion": "2026.3.24-beta.2",
        "pluginSdkVersion": "2026.3.24-beta.2"
      }
    }
    }
    
    {
    "id": "my-plugin",
    "name": "My Plugin",
    "description": "Adds a custom tool to OpenClaw",
    "contracts": {
      "tools": ["my_tool"]
    },
    "activation": {
      "onStartup": true
    },
    "configSchema": {
      "type": "object",
      "additionalProperties": false
    }
    }
    

    Setiap Plugin memerlukan manifes, bahkan tanpa konfigurasi. Alat yang didaftarkan runtime harus dicantumkan dalam contracts.tools agar OpenClaw dapat menemukan Plugin pemilik tanpa memuat runtime setiap Plugin. Plugin juga sebaiknya mendeklarasikan activation.onStartup secara sengaja. Contoh ini menetapkannya ke true. Lihat Manifes untuk skema lengkap. Cuplikan publikasi ClawHub kanonis berada di docs/snippets/plugin-publish/.

  • Tulis entry point

    // index.ts
    import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
    import { Type } from "@sinclair/typebox";
    
    export default definePluginEntry({
      id: "my-plugin",
      name: "My Plugin",
      description: "Adds a custom tool to OpenClaw",
      register(api) {
        api.registerTool({
          name: "my_tool",
          description: "Do a thing",
          parameters: Type.Object({ input: Type.String() }),
          async execute(_id, params) {
            return { content: [{ type: "text", text: `Got: ${params.input}` }] };
          },
        });
      },
    });
    

    definePluginEntry digunakan untuk Plugin non-kanal. Untuk kanal, gunakan defineChannelPluginEntry - lihat Plugin Kanal. Untuk opsi entry point lengkap, lihat Entry Point.

  • Uji dan publikasikan

    Plugin eksternal: validasi dan publikasikan dengan ClawHub, lalu pasang:

    clawhub package publish your-org/your-plugin --dry-run
    clawhub package publish your-org/your-plugin
    openclaw plugins install clawhub:@myorg/openclaw-my-plugin
    

    Spesifikasi paket polos seperti @myorg/openclaw-my-plugin dipasang dari npm selama peralihan peluncuran. Gunakan clawhub: saat Anda menginginkan resolusi ClawHub.

    Plugin dalam repo: letakkan di bawah pohon workspace Plugin bundel - ditemukan secara otomatis.

    pnpm test -- <bundled-plugin-root>/my-plugin/
    
  • Kapabilitas Plugin

    Satu Plugin dapat mendaftarkan sejumlah kapabilitas melalui objek api:

    Kapabilitas Metode pendaftaran Panduan terperinci
    Inferensi teks (LLM) api.registerProvider(...) Plugin Penyedia
    Backend inferensi CLI api.registerCliBackend(...) Backend CLI
    Kanal / perpesanan api.registerChannel(...) Plugin Kanal
    Ucapan (TTS/STT) api.registerSpeechProvider(...) Plugin Penyedia
    Transkripsi realtime api.registerRealtimeTranscriptionProvider(...) Plugin Penyedia
    Suara realtime api.registerRealtimeVoiceProvider(...) Plugin Penyedia
    Pemahaman media api.registerMediaUnderstandingProvider(...) Plugin Penyedia
    Pembuatan gambar api.registerImageGenerationProvider(...) Plugin Penyedia
    Pembuatan musik api.registerMusicGenerationProvider(...) Plugin Penyedia
    Pembuatan video api.registerVideoGenerationProvider(...) Plugin Penyedia
    Pengambilan web api.registerWebFetchProvider(...) Plugin Penyedia
    Pencarian web api.registerWebSearchProvider(...) Plugin Penyedia
    Middleware hasil alat api.registerAgentToolResultMiddleware(...) Ikhtisar SDK
    Alat agen api.registerTool(...) Di bawah
    Perintah kustom api.registerCommand(...) Entry Point
    Kait Plugin api.on(...) Kait Plugin
    Kait peristiwa internal api.registerHook(...) Entry Point
    Rute HTTP api.registerHttpRoute(...) Internal
    Subperintah CLI api.registerCli(...) Entry Point

    Untuk API pendaftaran lengkap, lihat Ikhtisar SDK.

    Plugin bundel dapat menggunakan api.registerAgentToolResultMiddleware(...) saat mereka membutuhkan penulisan ulang hasil alat secara async sebelum model melihat output. Deklarasikan runtime target dalam contracts.agentToolResultMiddleware, misalnya ["pi", "codex"]. Ini adalah seam Plugin bundel tepercaya; Plugin eksternal sebaiknya memilih kait Plugin OpenClaw biasa kecuali OpenClaw menumbuhkan kebijakan kepercayaan eksplisit untuk kapabilitas ini.

    Jika Plugin Anda mendaftarkan metode RPC gateway kustom, simpan metode tersebut pada prefiks khusus Plugin. Namespace admin inti (config.*, exec.approvals.*, wizard.*, update.*) tetap dicadangkan dan selalu diselesaikan ke operator.admin, bahkan jika Plugin meminta cakupan yang lebih sempit.

    Semantik guard kait yang perlu diingat:

    • before_tool_call: { block: true } bersifat terminal dan menghentikan handler berprioritas lebih rendah.
    • before_tool_call: { block: false } diperlakukan sebagai tanpa keputusan.
    • before_tool_call: { requireApproval: true } menjeda eksekusi agen dan meminta persetujuan pengguna melalui overlay persetujuan exec, tombol Telegram, interaksi Discord, atau perintah /approve di kanal apa pun.
    • before_install: { block: true } bersifat terminal dan menghentikan handler berprioritas lebih rendah.
    • before_install: { block: false } diperlakukan sebagai tanpa keputusan.
    • message_sending: { cancel: true } bersifat terminal dan menghentikan handler berprioritas lebih rendah.
    • message_sending: { cancel: false } diperlakukan sebagai tanpa keputusan.
    • message_received: utamakan bidang bertipe threadId saat Anda memerlukan perutean thread/topik masuk. Simpan metadata untuk tambahan khusus kanal.
    • message_sending: utamakan bidang perutean bertipe replyToId / threadId daripada kunci metadata khusus kanal.

    Perintah /approve menangani persetujuan exec dan Plugin dengan fallback terbatas: saat id persetujuan exec tidak ditemukan, OpenClaw mencoba ulang id yang sama melalui persetujuan Plugin. Penerusan persetujuan Plugin dapat dikonfigurasi secara independen melalui approvals.plugin dalam konfigurasi.

    Jika plumbing persetujuan kustom perlu mendeteksi kasus fallback terbatas yang sama, utamakan isApprovalNotFoundError dari openclaw/plugin-sdk/error-runtime daripada mencocokkan string kedaluwarsa persetujuan secara manual.

    Lihat Kait Plugin untuk contoh dan referensi kait.

    Mendaftarkan alat agen

    Alat adalah fungsi bertipe yang dapat dipanggil LLM. Alat dapat bersifat wajib (selalu tersedia) atau opsional (pilihan pengguna):

    register(api) {
      // Required tool - always available
      api.registerTool({
        name: "my_tool",
        description: "Do a thing",
        parameters: Type.Object({ input: Type.String() }),
        async execute(_id, params) {
          return { content: [{ type: "text", text: params.input }] };
        },
      });
    
      // Optional tool - user must add to allowlist
      api.registerTool(
        {
          name: "workflow_tool",
          description: "Run a workflow",
          parameters: Type.Object({ pipeline: Type.String() }),
          async execute(_id, params) {
            return { content: [{ type: "text", text: params.pipeline }] };
          },
        },
        { optional: true },
      );
    }
    

    Setiap alat yang didaftarkan dengan api.registerTool(...) juga harus dideklarasikan dalam manifes Plugin:

    {
      "contracts": {
        "tools": ["my_tool", "workflow_tool"]
      },
      "toolMetadata": {
        "workflow_tool": {
          "optional": true
        }
      }
    }
    

    OpenClaw menangkap dan menyimpan cache descriptor tervalidasi dari tool terdaftar, sehingga plugin tidak menduplikasi data description atau skema di manifest. Kontrak manifest hanya mendeklarasikan kepemilikan dan discovery; eksekusi tetap memanggil implementasi tool terdaftar yang live. Tetapkan toolMetadata.<tool>.optional: true untuk tool yang didaftarkan dengan api.registerTool(..., { optional: true }) agar OpenClaw dapat menghindari pemuatan runtime plugin tersebut sampai tool secara eksplisit dimasukkan ke allowlist.

    Pengguna mengaktifkan tool opsional dalam config:

    {
      tools: { allow: ["workflow_tool"] },
    }
    
    • Nama tool tidak boleh bentrok dengan tool core (konflik dilewati)
    • Tool dengan objek pendaftaran yang tidak valid, termasuk parameters yang hilang, dilewati dan dilaporkan dalam diagnostik plugin alih-alih menggagalkan jalannya agent
    • Gunakan optional: true untuk tool dengan efek samping atau persyaratan binary tambahan
    • Pengguna dapat mengaktifkan semua tool dari sebuah plugin dengan menambahkan id plugin ke tools.allow

    Mendaftarkan perintah CLI

    Plugin dapat menambahkan grup perintah root openclaw dengan api.registerCli. Sediakan descriptors untuk setiap root perintah tingkat atas agar OpenClaw dapat menampilkan dan merutekan perintah tanpa memuat setiap runtime plugin secara eager.

    register(api) {
      api.registerCli(
        ({ program }) => {
          const demo = program
            .command("demo-plugin")
            .description("Run demo plugin commands");
    
          demo
            .command("ping")
            .description("Check that the plugin CLI is executable")
            .action(() => {
              console.log("demo-plugin:pong");
            });
        },
        {
          descriptors: [
            {
              name: "demo-plugin",
              description: "Run demo plugin commands",
              hasSubcommands: true,
            },
          ],
        },
      );
    }
    

    Setelah install, verifikasi pendaftaran runtime dan jalankan perintah:

    openclaw plugins inspect demo-plugin --runtime --json
    openclaw demo-plugin ping
    

    Konvensi impor

    Selalu impor dari path openclaw/plugin-sdk/<subpath> yang terfokus:

    
    
    // Wrong: monolithic root (deprecated, will be removed)
    
    

    Untuk referensi subpath lengkap, lihat Ikhtisar SDK.

    Di dalam plugin Anda, gunakan file barrel lokal (api.ts, runtime-api.ts) untuk impor internal - jangan pernah mengimpor plugin Anda sendiri melalui path SDK-nya.

    Untuk provider plugin, simpan helper khusus provider dalam barrel package-root tersebut kecuali seam benar-benar generik. Contoh bundled saat ini:

    • Anthropic: wrapper stream Claude dan helper service_tier / beta
    • OpenAI: builder provider, helper model default, provider realtime
    • OpenRouter: builder provider serta helper onboarding/config

    Jika sebuah helper hanya berguna di dalam satu paket provider bundled, simpan di seam package-root tersebut alih-alih mempromosikannya ke openclaw/plugin-sdk/*.

    Beberapa seam helper openclaw/plugin-sdk/<bundled-id> yang dihasilkan masih ada untuk pemeliharaan bundled-plugin ketika memiliki penggunaan owner yang terlacak. Perlakukan itu sebagai permukaan yang dicadangkan, bukan sebagai pola default untuk plugin pihak ketiga baru.

    Checklist prapengajuan

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s package.json memiliki metadata openclaw yang benar OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Manifest openclaw.plugin.json ada dan valid OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Entry point menggunakan defineChannelPluginEntry atau definePluginEntry OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Semua impor menggunakan path plugin-sdk/<subpath> yang terfokus OPENCLAW_DOCS_MARKER:calloutClose: