Internal Plugin
Ini adalah referensi arsitektur mendalam. Untuk panduan praktis, lihat:
- Instal dan gunakan plugin — panduan pengguna
- Memulai — tutorial plugin pertama
- Plugin Channel — bangun channel perpesanan
- Plugin Provider — bangun provider model
- Ikhtisar SDK — peta impor dan API registrasi
Model kapabilitas publik
Kapabilitas adalah model plugin native publik di dalam OpenClaw. Setiap plugin native OpenClaw mendaftar terhadap satu atau lebih tipe kapabilitas:| Capability | Registration method | Example plugins |
|---|---|---|
| Inferensi teks | api.registerProvider(...) | openai, anthropic |
| Backend inferensi CLI | api.registerCliBackend(...) | openai, anthropic |
| Ucapan | api.registerSpeechProvider(...) | elevenlabs, microsoft |
| Transkripsi realtime | api.registerRealtimeTranscriptionProvider(...) | openai |
| Suara realtime | api.registerRealtimeVoiceProvider(...) | openai |
| Pemahaman media | api.registerMediaUnderstandingProvider(...) | openai, google |
| Pembuatan gambar | api.registerImageGenerationProvider(...) | openai, google, fal, minimax |
| Pembuatan video | api.registerVideoGenerationProvider(...) | qwen |
| Pengambilan web | api.registerWebFetchProvider(...) | firecrawl |
| Pencarian web | api.registerWebSearchProvider(...) | google |
| Channel / perpesanan | api.registerChannel(...) | msteams, matrix |
Sikap kompatibilitas eksternal
Model kapabilitas sudah ada di core dan digunakan oleh plugin bundled/native hari ini, tetapi kompatibilitas plugin eksternal masih membutuhkan standar yang lebih ketat daripada “ini diekspor, jadi ini dibekukan.” Panduan saat ini:- plugin eksternal yang sudah ada: pertahankan integrasi berbasis hook agar tetap berfungsi; anggap ini sebagai baseline kompatibilitas
- plugin bundled/native baru: lebih pilih registrasi kapabilitas eksplisit daripada reach-in spesifik vendor atau desain hook-only baru
- plugin eksternal yang mengadopsi registrasi kapabilitas: diizinkan, tetapi perlakukan surface helper spesifik kapabilitas sebagai sesuatu yang masih berkembang kecuali dokumen secara eksplisit menandai suatu kontrak sebagai stabil
- API registrasi kapabilitas adalah arah yang dituju
- hook legacy tetap menjadi jalur paling aman tanpa kerusakan bagi plugin eksternal selama transisi
- subpath helper yang diekspor tidak semuanya setara; pilih kontrak terdokumentasi yang sempit, bukan ekspor helper insidental
Bentuk plugin
OpenClaw mengklasifikasikan setiap plugin yang dimuat ke dalam sebuah bentuk berdasarkan perilaku registrasi aktualnya (bukan hanya metadata statis):- plain-capability — mendaftarkan tepat satu tipe kapabilitas (misalnya
plugin provider saja seperti
mistral) - hybrid-capability — mendaftarkan beberapa tipe kapabilitas (misalnya
openaimemiliki inferensi teks, ucapan, pemahaman media, dan pembuatan gambar) - hook-only — hanya mendaftarkan hook (typed atau custom), tanpa kapabilitas, tool, command, atau layanan
- non-capability — mendaftarkan tool, command, layanan, atau route tetapi tidak memiliki kapabilitas
openclaw plugins inspect <id> untuk melihat bentuk plugin dan rincian
kapabilitasnya. Lihat referensi CLI untuk detail.
Hook legacy
Hookbefore_agent_start tetap didukung sebagai jalur kompatibilitas untuk
plugin hook-only. Plugin legacy di dunia nyata masih bergantung padanya.
Arah:
- tetap pertahankan agar berfungsi
- dokumentasikan sebagai legacy
- pilih
before_model_resolveuntuk pekerjaan override model/provider - pilih
before_prompt_builduntuk pekerjaan mutasi prompt - hapus hanya setelah penggunaan nyata menurun dan cakupan fixture membuktikan keamanan migrasi
Sinyal kompatibilitas
Saat Anda menjalankanopenclaw doctor atau openclaw plugins inspect <id>,
Anda mungkin melihat salah satu label berikut:
| Signal | Meaning |
|---|---|
| config valid | Konfigurasi diparse dengan baik dan plugin ter-resolve |
| compatibility advisory | Plugin menggunakan pola lama-yang-masih-didukung (mis. hook-only) |
| legacy warning | Plugin menggunakan before_agent_start, yang sudah deprecated |
| hard error | Konfigurasi tidak valid atau plugin gagal dimuat |
hook-only maupun before_agent_start tidak akan merusak plugin Anda saat ini —
hook-only bersifat advisory, dan before_agent_start hanya memicu peringatan. Sinyal-sinyal ini juga muncul di openclaw status --all dan openclaw plugins doctor.
Ikhtisar arsitektur
Sistem plugin OpenClaw memiliki empat lapisan:- Manifest + discovery
OpenClaw menemukan kandidat plugin dari path yang dikonfigurasi, root workspace,
root extension global, dan extension bundled. Discovery membaca manifest native
openclaw.plugin.jsonserta manifest bundle yang didukung terlebih dahulu. - Enablement + validasi Core memutuskan apakah plugin yang ditemukan diaktifkan, dinonaktifkan, diblokir, atau dipilih untuk slot eksklusif seperti memory.
- Pemuatan runtime Plugin native OpenClaw dimuat in-process melalui jiti dan mendaftarkan kapabilitas ke registry pusat. Bundle yang kompatibel dinormalisasi menjadi record registry tanpa mengimpor kode runtime.
- Konsumsi surface Bagian lain dari OpenClaw membaca registry untuk mengekspos tool, channel, setup provider, hook, route HTTP, command CLI, dan layanan.
- metadata waktu parse berasal dari
registerCli(..., { descriptors: [...] }) - modul CLI plugin yang sebenarnya bisa tetap lazy dan mendaftar pada pemanggilan pertama
- discovery + validasi config harus bekerja dari metadata manifest/schema tanpa mengeksekusi kode plugin
- perilaku runtime native berasal dari path
register(api)modul plugin
Plugin channel dan tool pesan bersama
Plugin channel tidak perlu mendaftarkan tool kirim/edit/reaksi terpisah untuk aksi chat normal. OpenClaw mempertahankan satu toolmessage bersama di core,
dan plugin channel memiliki discovery serta eksekusi spesifik channel di baliknya.
Batas saat ini adalah:
- core memiliki host tool
messagebersama, wiring prompt, pencatatan sesi/thread, dan dispatch eksekusi - plugin channel memiliki scoped action discovery, capability discovery, serta fragmen schema spesifik channel
- plugin channel memiliki tata bahasa percakapan sesi spesifik provider, seperti bagaimana id percakapan mengenkode id thread atau mewarisi dari percakapan induk
- plugin channel mengeksekusi aksi akhir melalui adapter action mereka
ChannelMessageActionAdapter.describeMessageTool(...). Panggilan discovery yang
terpadu itu memungkinkan plugin mengembalikan aksi yang terlihat, kapabilitas,
dan kontribusi schema secara bersamaan agar bagian-bagian itu tidak saling drift.
Core meneruskan scope runtime ke langkah discovery tersebut. Field penting meliputi:
accountIdcurrentChannelIdcurrentThreadTscurrentMessageIdsessionKeysessionIdagentIdrequesterSenderIdinbound tepercaya
message core.
Inilah alasan perubahan routing embedded-runner masih merupakan pekerjaan plugin:
runner bertanggung jawab meneruskan identitas chat/sesi saat ini ke batas
discovery plugin agar tool message bersama mengekspos surface milik channel
yang benar untuk giliran saat ini.
Untuk helper eksekusi milik channel, plugin bundled sebaiknya menyimpan runtime
eksekusi di dalam modul extension mereka sendiri. Core tidak lagi memiliki runtime
message-action Discord, Slack, Telegram, atau WhatsApp di bawah src/agents/tools.
Kami tidak mempublikasikan subpath plugin-sdk/*-action-runtime terpisah, dan plugin bundled
sebaiknya mengimpor kode runtime lokal mereka sendiri langsung dari modul
milik extension mereka.
Batas yang sama berlaku untuk seam SDK bernama provider secara umum: core tidak
boleh mengimpor convenience barrel spesifik channel untuk Slack, Discord, Signal,
WhatsApp, atau extension serupa. Jika core memerlukan suatu perilaku, konsumsi
barrel api.ts / runtime-api.ts milik plugin bundled itu sendiri atau promosikan kebutuhan
tersebut menjadi kapabilitas generik yang sempit di SDK bersama.
Khusus untuk poll, ada dua jalur eksekusi:
outbound.sendPolladalah baseline bersama untuk channel yang cocok dengan model poll umumactions.handleAction("poll")adalah jalur yang disukai untuk semantik poll spesifik channel atau parameter poll tambahan
Model kepemilikan kapabilitas
OpenClaw memperlakukan plugin native sebagai batas kepemilikan untuk sebuah company atau sebuah fitur, bukan sebagai kumpulan integrasi yang tidak terkait. Artinya:- plugin company biasanya sebaiknya memiliki semua surface OpenClaw yang menghadap company tersebut
- plugin fitur biasanya sebaiknya memiliki seluruh surface fitur yang diperkenalkannya
- channel sebaiknya mengonsumsi kapabilitas core bersama alih-alih mengimplementasikan ulang perilaku provider secara ad hoc
- plugin bundled
openaimemiliki perilaku model-provider OpenAI dan perilaku OpenAI speech + realtime-voice + media-understanding + image-generation - plugin bundled
elevenlabsmemiliki perilaku speech ElevenLabs - plugin bundled
microsoftmemiliki perilaku speech Microsoft - plugin bundled
googlememiliki perilaku model-provider Google plus perilaku Google media-understanding + image-generation + web-search - plugin bundled
firecrawlmemiliki perilaku web-fetch Firecrawl - plugin bundled
minimax,mistral,moonshot, danzaimemiliki backend media-understanding mereka - plugin
voice-calladalah plugin fitur: plugin ini memiliki transport panggilan, tool, CLI, route, dan jembatan media-stream Twilio, tetapi mengonsumsi kapabilitas speech bersama plus realtime-transcription dan realtime-voice alih-alih mengimpor plugin vendor secara langsung
- OpenAI berada dalam satu plugin meskipun mencakup model teks, speech, gambar, dan video di masa mendatang
- vendor lain dapat melakukan hal yang sama untuk surface area miliknya sendiri
- channel tidak peduli plugin vendor mana yang memiliki provider; mereka mengonsumsi kontrak kapabilitas bersama yang diekspos oleh core
- plugin = batas kepemilikan
- capability = kontrak core yang dapat diimplementasikan atau dikonsumsi oleh beberapa plugin
- definisikan kapabilitas yang hilang di core
- ekspos melalui API/runtime plugin secara typed
- hubungkan channel/fitur terhadap kapabilitas itu
- biarkan plugin vendor mendaftarkan implementasi
Pelapisan kapabilitas
Gunakan model mental ini saat memutuskan di mana kode harus ditempatkan:- lapisan kapabilitas core: orkestrasi bersama, kebijakan, fallback, aturan penggabungan config, semantik pengiriman, dan kontrak typed
- lapisan plugin vendor: API spesifik vendor, auth, katalog model, sintesis speech, pembuatan gambar, backend video di masa mendatang, endpoint usage
- lapisan plugin channel/fitur: integrasi Slack/Discord/voice-call/dll. yang mengonsumsi kapabilitas core dan menyajikannya pada suatu surface
- core memiliki kebijakan TTS saat balasan, urutan fallback, preferensi, dan pengiriman channel
openai,elevenlabs, danmicrosoftmemiliki implementasi sintesisvoice-callmengonsumsi helper runtime TTS telephony
Contoh plugin company multi-kapabilitas
Sebuah plugin company harus terasa kohesif dari luar. Jika OpenClaw memiliki kontrak bersama untuk model, speech, transkripsi realtime, suara realtime, pemahaman media, pembuatan gambar, pembuatan video, pengambilan web, dan pencarian web, seorang vendor dapat memiliki semua surface miliknya di satu tempat:- satu plugin memiliki surface vendor
- core tetap memiliki kontrak kapabilitas
- channel dan plugin fitur mengonsumsi helper
api.runtime.*, bukan kode vendor - pengujian kontrak dapat menegaskan bahwa plugin mendaftarkan kapabilitas yang diklaim dimilikinya
Contoh kapabilitas: pemahaman video
OpenClaw sudah memperlakukan pemahaman gambar/audio/video sebagai satu kapabilitas bersama. Model kepemilikan yang sama berlaku di sana:- core mendefinisikan kontrak media-understanding
- plugin vendor mendaftarkan
describeImage,transcribeAudio, dandescribeVideosesuai kebutuhan - channel dan plugin fitur mengonsumsi perilaku core bersama alih-alih terhubung langsung ke kode vendor
api.registerVideoGenerationProvider(...) terhadapnya.
Butuh daftar periksa rollout yang konkret? Lihat
Capability Cookbook.
Kontrak dan penegakan
Surface API plugin sengaja dibuat typed dan dipusatkan diOpenClawPluginApi. Kontrak itu mendefinisikan titik registrasi yang didukung
dan helper runtime yang dapat diandalkan oleh sebuah plugin.
Mengapa ini penting:
- penulis plugin mendapatkan satu standar internal yang stabil
- core dapat menolak kepemilikan ganda seperti dua plugin yang mendaftarkan provider id yang sama
- startup dapat memunculkan diagnostik yang dapat ditindaklanjuti untuk registrasi yang malformed
- pengujian kontrak dapat menegakkan kepemilikan plugin bundled dan mencegah drift diam-diam
- penegakan registrasi runtime Registry plugin memvalidasi registrasi saat plugin dimuat. Contoh: provider id duplikat, speech provider id duplikat, dan registrasi yang malformed menghasilkan diagnostik plugin alih-alih perilaku tak terdefinisi.
- pengujian kontrak Plugin bundled ditangkap dalam registry kontrak selama pengujian berjalan sehingga OpenClaw dapat menegaskan kepemilikan secara eksplisit. Saat ini ini digunakan untuk model provider, speech provider, web search provider, dan kepemilikan registrasi bundled.
Apa yang termasuk dalam kontrak
Kontrak plugin yang baik adalah:- typed
- kecil
- spesifik kapabilitas
- dimiliki oleh core
- dapat digunakan ulang oleh beberapa plugin
- dapat dikonsumsi oleh channel/fitur tanpa pengetahuan vendor
- kebijakan spesifik vendor yang disembunyikan di core
- escape hatch plugin satu kali yang melewati registry
- kode channel yang menjangkau langsung ke implementasi vendor
- objek runtime ad hoc yang bukan bagian dari
OpenClawPluginApiatauapi.runtime
Model eksekusi
Plugin native OpenClaw berjalan in-process bersama Gateway. Mereka tidak di-sandbox. Plugin native yang dimuat memiliki batas kepercayaan tingkat proses yang sama dengan kode core. Implikasinya:- plugin native dapat mendaftarkan tool, network handler, hook, dan layanan
- bug pada plugin native dapat membuat gateway crash atau tidak stabil
- plugin native yang berbahaya setara dengan eksekusi kode arbitrer di dalam proses OpenClaw
@openclaw/<id> secara default, atau suffix typed yang disetujui seperti
-provider, -plugin, -speech, -sandbox, atau -media-understanding ketika
package dengan sengaja mengekspos peran plugin yang lebih sempit.
Catatan kepercayaan penting:
plugins.allowmempercayai plugin id, bukan provenance sumber.- Plugin workspace dengan id yang sama seperti plugin bundled sengaja membayangi salinan bundled ketika plugin workspace tersebut diaktifkan/di-allowlist.
- Ini normal dan berguna untuk pengembangan lokal, pengujian patch, dan hotfix.
Batas ekspor
OpenClaw mengekspor kapabilitas, bukan convenience implementasi. Pertahankan registrasi kapabilitas tetap publik. Pangkas ekspor helper non-kontrak:- subpath helper spesifik plugin bundled
- subpath plumbing runtime yang tidak dimaksudkan sebagai API publik
- helper convenience spesifik vendor
- helper setup/onboarding yang merupakan detail implementasi
plugin-sdk/feishu, plugin-sdk/feishu-setup, plugin-sdk/zalo,
plugin-sdk/zalo-setup, dan beberapa seam plugin-sdk/matrix*. Perlakukan ini sebagai
ekspor detail implementasi yang dicadangkan, bukan sebagai pola SDK yang direkomendasikan untuk
plugin pihak ketiga baru.
Pipeline pemuatan
Saat startup, OpenClaw kira-kira melakukan ini:- menemukan root plugin kandidat
- membaca manifest native atau bundle kompatibel serta metadata package
- menolak kandidat yang tidak aman
- menormalisasi config plugin (
plugins.enabled,allow,deny,entries,slots,load.paths) - memutuskan enablement untuk setiap kandidat
- memuat modul native yang diaktifkan melalui jiti
- memanggil hook native
register(api)(atauactivate(api)— alias legacy) dan mengumpulkan registrasi ke dalam registry plugin - mengekspos registry ke surface command/runtime
activate adalah alias legacy untuk register — loader meresolve mana pun yang ada (def.register ?? def.activate) dan memanggilnya pada titik yang sama. Semua plugin bundled menggunakan register; pilih register untuk plugin baru.Perilaku manifest-first
Manifest adalah sumber kebenaran control-plane. OpenClaw menggunakannya untuk:- mengidentifikasi plugin
- menemukan deklarasi channel/skills/schema config atau kapabilitas bundle
- memvalidasi
plugins.entries.<id>.config - menambah label/placeholder UI Control
- menampilkan metadata instalasi/katalog
Apa yang di-cache oleh loader
OpenClaw menyimpan cache in-process jangka pendek untuk:- hasil discovery
- data registry manifest
- registry plugin yang dimuat
- Setel
OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1atauOPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1untuk menonaktifkan cache ini. - Sesuaikan jendela cache dengan
OPENCLAW_PLUGIN_DISCOVERY_CACHE_MSdanOPENCLAW_PLUGIN_MANIFEST_CACHE_MS.
Model registry
Plugin yang dimuat tidak langsung memodifikasi global core acak. Mereka mendaftar ke sebuah registry plugin pusat. Registry melacak:- record plugin (identitas, sumber, origin, status, diagnostik)
- tool
- hook legacy dan hook typed
- channel
- provider
- handler RPC gateway
- route HTTP
- registrar CLI
- layanan latar belakang
- command milik plugin
- modul plugin -> registrasi registry
- runtime core -> konsumsi registry
Callback pengikatan percakapan
Plugin yang mengikat percakapan dapat bereaksi saat sebuah persetujuan diselesaikan. Gunakanapi.onConversationBindingResolved(...) untuk menerima callback setelah permintaan bind
disetujui atau ditolak:
status:"approved"atau"denied"decision:"allow-once","allow-always", atau"deny"binding: binding yang ter-resolve untuk permintaan yang disetujuirequest: ringkasan permintaan asli, petunjuk detach, sender id, dan metadata percakapan
Hook runtime provider
Plugin provider sekarang memiliki dua lapisan:- metadata manifest:
providerAuthEnvVarsuntuk lookup auth env murah sebelum runtime dimuat, plusproviderAuthChoicesuntuk label onboarding/pilihan auth murah dan metadata flag CLI sebelum runtime dimuat - hook waktu konfigurasi:
catalog/ legacydiscoveryplusapplyConfigDefaults - hook runtime:
normalizeModelId,normalizeTransport,normalizeConfig,applyNativeStreamingUsageCompat,resolveConfigApiKey,resolveSyntheticAuth,shouldDeferSyntheticProfileAuth,resolveDynamicModel,prepareDynamicModel,normalizeResolvedModel,contributeResolvedModelCompat,capabilities,normalizeToolSchemas,inspectToolSchemas,resolveReasoningOutputMode,prepareExtraParams,createStreamFn,wrapStreamFn,resolveTransportTurnState,resolveWebSocketSessionPolicy,formatApiKey,refreshOAuth,buildAuthDoctorHint,matchesContextOverflowError,classifyFailoverReason,isCacheTtlEligible,buildMissingAuthMessage,suppressBuiltInModel,augmentModelCatalog,isBinaryThinking,supportsXHighThinking,resolveDefaultThinkingLevel,isModernModelRef,prepareRuntimeAuth,resolveUsageAuth,fetchUsageSnapshot,createEmbeddingProvider,buildReplayPolicy,sanitizeReplayHistory,validateReplayTurns,onModelSelected
providerAuthEnvVars saat provider memiliki kredensial berbasis env
yang harus terlihat oleh jalur auth/status/model-picker generik tanpa memuat runtime plugin.
Gunakan manifest providerAuthChoices saat surface CLI onboarding/pilihan auth
perlu mengetahui choice id provider, label grup, dan wiring auth satu-flag sederhana
tanpa memuat runtime provider. Pertahankan runtime provider envVars untuk petunjuk
yang menghadap operator seperti label onboarding atau variabel setup
OAuth client-id/client-secret.
Urutan hook dan penggunaan
Untuk plugin model/provider, OpenClaw memanggil hook dalam urutan kasar berikut. Kolom “When to use” adalah panduan keputusan cepat.| # | Hook | What it does | When to use |
|---|---|---|---|
| 1 | catalog | Mempublikasikan config provider ke models.providers selama generasi models.json | Provider memiliki katalog atau default base URL |
| 2 | applyConfigDefaults | Menerapkan default config global milik provider selama materialisasi config | Default bergantung pada mode auth, env, atau semantik keluarga model provider |
| — | (pencarian model bawaan) | OpenClaw mencoba jalur registry/katalog normal terlebih dahulu | (bukan hook plugin) |
| 3 | normalizeModelId | Menormalisasi alias model-id legacy atau preview sebelum lookup | Provider memiliki pembersihan alias sebelum resolusi model kanonis |
| 4 | normalizeTransport | Menormalisasi api / baseUrl keluarga provider sebelum perakitan model generik | Provider memiliki pembersihan transport untuk provider id kustom dalam keluarga transport yang sama |
| 5 | normalizeConfig | Menormalisasi models.providers.<id> sebelum resolusi runtime/provider | Provider memerlukan pembersihan config yang seharusnya berada bersama plugin; helper keluarga Google bundled juga menjadi backstop untuk entri config Google yang didukung |
| 6 | applyNativeStreamingUsageCompat | Menerapkan penulisan ulang kompatibilitas streaming-usage native ke provider config | Provider memerlukan perbaikan metadata native streaming usage berbasis endpoint |
| 7 | resolveConfigApiKey | Meresolve auth penanda env untuk provider config sebelum pemuatan auth runtime | Provider memiliki resolusi API key penanda env milik provider; amazon-bedrock juga memiliki resolver penanda env AWS bawaan di sini |
| 8 | resolveSyntheticAuth | Menampilkan auth lokal/self-hosted atau berbasis config tanpa mempersistenkan plaintext | Provider dapat beroperasi dengan penanda kredensial sintetis/lokal |
| 9 | shouldDeferSyntheticProfileAuth | Menurunkan prioritas placeholder profil sintetis yang tersimpan di bawah auth berbasis env/config | Provider menyimpan profil placeholder sintetis yang seharusnya tidak menang dalam prioritas |
| 10 | resolveDynamicModel | Fallback sinkron untuk model id milik provider yang belum ada di registry lokal | Provider menerima model id upstream arbitrer |
| 11 | prepareDynamicModel | Warm-up async, lalu resolveDynamicModel dijalankan lagi | Provider memerlukan metadata jaringan sebelum meresolve id yang tidak dikenal |
| 12 | normalizeResolvedModel | Penulisan ulang akhir sebelum embedded runner menggunakan model yang ter-resolve | Provider memerlukan penulisan ulang transport tetapi masih menggunakan transport core |
| 13 | contributeResolvedModelCompat | Menyumbangkan flag kompatibilitas untuk model vendor di balik transport kompatibel lain | Provider mengenali modelnya sendiri pada transport proxy tanpa mengambil alih provider |
| 14 | capabilities | Metadata transkrip/tooling milik provider yang digunakan oleh logika core bersama | Provider memerlukan keunikan transkrip/keluarga provider |
| 15 | normalizeToolSchemas | Menormalisasi schema tool sebelum embedded runner melihatnya | Provider memerlukan pembersihan schema keluarga transport |
| 16 | inspectToolSchemas | Menampilkan diagnostik schema milik provider setelah normalisasi | Provider ingin peringatan keyword tanpa mengajarkan aturan spesifik provider ke core |
| 17 | resolveReasoningOutputMode | Memilih kontrak keluaran reasoning native vs bertag | Provider memerlukan reasoning/final output bertag alih-alih field native |
| 18 | prepareExtraParams | Normalisasi parameter request sebelum wrapper opsi stream generik | Provider memerlukan parameter request default atau pembersihan parameter per-provider |
| 19 | createStreamFn | Sepenuhnya mengganti jalur stream normal dengan transport kustom | Provider memerlukan wire protocol kustom, bukan sekadar wrapper |
| 20 | wrapStreamFn | Wrapper stream setelah wrapper generik diterapkan | Provider memerlukan wrapper header/body/model kompatibilitas request tanpa transport kustom |
| 21 | resolveTransportTurnState | Melampirkan header atau metadata transport per-turn native | Provider ingin transport generik mengirim identitas turn native provider |
| 22 | resolveWebSocketSessionPolicy | Melampirkan header WebSocket native atau kebijakan cool-down sesi | Provider ingin transport WS generik menyetel header sesi atau kebijakan fallback |
| 23 | formatApiKey | Formatter profil auth: profil tersimpan menjadi string apiKey runtime | Provider menyimpan metadata auth tambahan dan memerlukan bentuk token runtime kustom |
| 24 | refreshOAuth | Override refresh OAuth untuk endpoint refresh kustom atau kebijakan kegagalan refresh | Provider tidak cocok dengan refresher pi-ai bersama |
| 25 | buildAuthDoctorHint | Petunjuk perbaikan yang ditambahkan saat refresh OAuth gagal | Provider memerlukan panduan perbaikan auth milik provider setelah kegagalan refresh |
| 26 | matchesContextOverflowError | Matcher overflow context-window milik provider | Provider memiliki error overflow mentah yang tidak terdeteksi oleh heuristik generik |
| 27 | classifyFailoverReason | Klasifikasi alasan failover milik provider | Provider dapat memetakan error API/transport mentah ke rate-limit/overload/dll |
| 28 | isCacheTtlEligible | Kebijakan prompt-cache untuk provider proxy/backhaul | Provider memerlukan gating TTL cache spesifik proxy |
| 29 | buildMissingAuthMessage | Pengganti untuk pesan pemulihan missing-auth generik | Provider memerlukan petunjuk pemulihan missing-auth spesifik provider |
| 30 | suppressBuiltInModel | Penekanan model upstream usang plus petunjuk error opsional yang menghadap pengguna | Provider perlu menyembunyikan baris upstream usang atau menggantinya dengan petunjuk vendor |
| 31 | augmentModelCatalog | Baris katalog sintetis/akhir ditambahkan setelah discovery | Provider memerlukan baris forward-compat sintetis di models list dan picker |
| 32 | isBinaryThinking | Toggle reasoning on/off untuk provider binary-thinking | Provider hanya mengekspos binary thinking on/off |
| 33 | supportsXHighThinking | Dukungan reasoning xhigh untuk model terpilih | Provider ingin xhigh hanya pada subset model |
| 34 | resolveDefaultThinkingLevel | Level /think default untuk keluarga model tertentu | Provider memiliki kebijakan /think default untuk keluarga model |
| 35 | isModernModelRef | Matcher model-modern untuk filter profil live dan pemilihan smoke | Provider memiliki pencocokan model pilihan live/smoke |
| 36 | prepareRuntimeAuth | Menukar kredensial yang dikonfigurasi menjadi token/key runtime aktual tepat sebelum inferensi | Provider memerlukan pertukaran token atau kredensial request berumur pendek |
| 37 | resolveUsageAuth | Meresolve kredensial usage/billing untuk /usage dan surface status terkait | Provider memerlukan parsing token usage/kuota kustom atau kredensial usage yang berbeda |
| 38 | fetchUsageSnapshot | Mengambil dan menormalisasi snapshot usage/kuota spesifik provider setelah auth di-resolve | Provider memerlukan endpoint usage atau parser payload spesifik provider |
| 39 | createEmbeddingProvider | Membangun adapter embedding milik provider untuk memory/search | Perilaku embedding memory seharusnya berada bersama plugin provider |
| 40 | buildReplayPolicy | Mengembalikan kebijakan replay yang mengendalikan penanganan transkrip untuk provider | Provider memerlukan kebijakan transkrip kustom (misalnya penghapusan blok thinking) |
| 41 | sanitizeReplayHistory | Menulis ulang riwayat replay setelah pembersihan transkrip generik | Provider memerlukan penulisan ulang replay spesifik provider di luar helper pemadatan bersama |
| 42 | validateReplayTurns | Validasi atau pembentukan ulang replay-turn akhir sebelum embedded runner | Transport provider memerlukan validasi turn yang lebih ketat setelah sanitasi generik |
| 43 | onModelSelected | Menjalankan efek samping pasca-pemilihan milik provider | Provider memerlukan telemetri atau state milik provider saat sebuah model menjadi aktif |
normalizeModelId, normalizeTransport, dan normalizeConfig terlebih dahulu
memeriksa plugin provider yang cocok, lalu fallback ke plugin provider lain yang
mampu menggunakan hook sampai salah satunya benar-benar mengubah model id atau
transport/config. Ini menjaga shim provider alias/kompatibilitas tetap berfungsi
tanpa mengharuskan pemanggil mengetahui plugin bundled mana yang memiliki penulisan ulang tersebut. Jika tidak ada hook provider yang menulis ulang entri config keluarga
Google yang didukung, normalizer config Google bundled tetap menerapkan pembersihan kompatibilitas itu.
Jika provider memerlukan wire protocol yang sepenuhnya kustom atau executor request
kustom, itu adalah kelas extension yang berbeda. Hook-hook ini ditujukan untuk
perilaku provider yang tetap berjalan pada loop inferensi normal OpenClaw.
Contoh provider
Contoh bawaan
- Anthropic menggunakan
resolveDynamicModel,capabilities,buildAuthDoctorHint,resolveUsageAuth,fetchUsageSnapshot,isCacheTtlEligible,resolveDefaultThinkingLevel,applyConfigDefaults,isModernModelRef, danwrapStreamFnkarena memiliki forward-compat Claude 4.6, petunjuk keluarga provider, panduan perbaikan auth, integrasi endpoint usage, eligibility prompt-cache, default config yang sadar auth, kebijakan thinking default/adaptif Claude, serta pembentukan stream spesifik Anthropic untuk beta header,/fast/serviceTier, dancontext1m. - Helper stream spesifik Claude milik Anthropic untuk saat ini tetap berada di
seam
api.ts/contract-api.tspublik milik plugin bundled itu sendiri. Surface package itu mengeksporwrapAnthropicProviderStream,resolveAnthropicBetas,resolveAnthropicFastMode,resolveAnthropicServiceTier, dan builder wrapper Anthropic tingkat rendah alih-alih memperlebar SDK generik di sekitar aturan beta-header satu provider. - OpenAI menggunakan
resolveDynamicModel,normalizeResolvedModel, dancapabilitiesplusbuildMissingAuthMessage,suppressBuiltInModel,augmentModelCatalog,supportsXHighThinking, danisModernModelRefkarena memiliki forward-compat GPT-5.4, normalisasi langsung OpenAIopenai-completions->openai-responses, petunjuk auth yang sadar Codex, penekanan Spark, baris daftar OpenAI sintetis, dan kebijakan thinking / live-model GPT-5; keluarga streamopenai-responses-defaultsmemiliki wrapper OpenAI Responses native bersama untuk header atribusi,/fast/serviceTier, text verbosity, native Codex web search, pembentukan payload reasoning-compat, dan manajemen konteks Responses. - OpenRouter menggunakan
catalogplusresolveDynamicModeldanprepareDynamicModelkarena provider bersifat pass-through dan mungkin mengekspos model id baru sebelum katalog statis OpenClaw diperbarui; provider ini juga menggunakancapabilities,wrapStreamFn, danisCacheTtlEligibleagar header request spesifik provider, metadata routing, patch reasoning, dan kebijakan prompt-cache tetap berada di luar core. Kebijakan replay-nya berasal dari keluargapassthrough-gemini, sedangkan keluarga streamopenrouter-thinkingmemiliki injection reasoning proxy dan skip untuk model yang tidak didukung /auto. - GitHub Copilot menggunakan
catalog,auth,resolveDynamicModel, dancapabilitiesplusprepareRuntimeAuthdanfetchUsageSnapshotkarena memerlukan device login milik provider, perilaku fallback model, keunikan transkrip Claude, pertukaran token GitHub -> token Copilot, dan endpoint usage milik provider. - OpenAI Codex menggunakan
catalog,resolveDynamicModel,normalizeResolvedModel,refreshOAuth, danaugmentModelCatalogplusprepareExtraParams,resolveUsageAuth, danfetchUsageSnapshotkarena masih berjalan di transport OpenAI core tetapi memiliki normalisasi transport/base URL, kebijakan fallback refresh OAuth, pilihan transport default, baris katalog Codex sintetis, dan integrasi endpoint usage ChatGPT; provider ini berbagi keluarga streamopenai-responses-defaultsyang sama dengan OpenAI langsung. - Google AI Studio dan Gemini CLI OAuth menggunakan
resolveDynamicModel,buildReplayPolicy,sanitizeReplayHistory,resolveReasoningOutputMode,wrapStreamFn, danisModernModelRefkarena keluarga replaygoogle-geminimemiliki fallback forward-compat Gemini 3.1, validasi replay Gemini native, sanitasi replay bootstrap, mode keluaran reasoning bertag, dan pencocokan modern-model, sedangkan keluarga streamgoogle-thinkingmemiliki normalisasi payload thinking Gemini; Gemini CLI OAuth juga menggunakanformatApiKey,resolveUsageAuth, danfetchUsageSnapshotuntuk pemformatan token, parsing token, dan wiring endpoint kuota. - Anthropic Vertex menggunakan
buildReplayPolicymelalui keluarga replayanthropic-by-modelsehingga pembersihan replay spesifik Claude tetap terbatas pada id Claude alih-alih setiap transportanthropic-messages. - Amazon Bedrock menggunakan
buildReplayPolicy,matchesContextOverflowError,classifyFailoverReason, danresolveDefaultThinkingLevelkarena memiliki klasifikasi error throttle/not-ready/context-overflow spesifik Bedrock untuk trafik Anthropic-on-Bedrock; kebijakan replay-nya tetap berbagi guardanthropic-by-modelkhusus Claude yang sama. - OpenRouter, Kilocode, Opencode, dan Opencode Go menggunakan
buildReplayPolicymelalui keluarga replaypassthrough-geminikarena mereka mem-proxy model Gemini melalui transport yang kompatibel dengan OpenAI dan memerlukan sanitasi thought-signature Gemini tanpa validasi replay Gemini native atau penulisan ulang bootstrap. - MiniMax menggunakan
buildReplayPolicymelalui keluarga replayhybrid-anthropic-openaikarena satu provider memiliki semantik pesan Anthropic dan kompatibel OpenAI sekaligus; provider ini mempertahankan penghapusan thinking-block khusus Claude di sisi Anthropic sambil mengoverride mode keluaran reasoning kembali ke native, dan keluarga streamminimax-fast-modememiliki penulisan ulang model fast-mode pada jalur stream bersama. - Moonshot menggunakan
catalogpluswrapStreamFnkarena masih menggunakan transport OpenAI bersama tetapi memerlukan normalisasi payload thinking milik provider; keluarga streammoonshot-thinkingmemetakan config plus status/thinkke payload binary thinking native-nya. - Kilocode menggunakan
catalog,capabilities,wrapStreamFn, danisCacheTtlEligiblekarena memerlukan header request milik provider, normalisasi payload reasoning, petunjuk transkrip Gemini, dan gating cache-TTL Anthropic; keluarga streamkilocode-thinkingmempertahankan injection thinking Kilo pada jalur stream proxy bersama sambil melewatikilo/autodan model id proxy lain yang tidak mendukung payload reasoning eksplisit. - Z.AI menggunakan
resolveDynamicModel,prepareExtraParams,wrapStreamFn,isCacheTtlEligible,isBinaryThinking,isModernModelRef,resolveUsageAuth, danfetchUsageSnapshotkarena memiliki fallback GLM-5, defaulttool_stream, UX binary thinking, pencocokan modern-model, serta auth usage + pengambilan kuota; keluarga streamtool-stream-default-onmenjaga wrappertool_streamdefault-on tetap di luar glue tulisan tangan per-provider. - xAI menggunakan
normalizeResolvedModel,normalizeTransport,contributeResolvedModelCompat,prepareExtraParams,wrapStreamFn,resolveSyntheticAuth,resolveDynamicModel, danisModernModelRefkarena memiliki normalisasi transport xAI Responses native, penulisan ulang alias Grok fast-mode, defaulttool_stream, pembersihan strict-tool / reasoning-payload, penggunaan ulang auth fallback untuk tool milik plugin, resolusi model Grok forward-compat, dan patch kompatibilitas milik provider seperti profil tool-schema xAI, unsupported schema keywords, nativeweb_search, dan decoding argumen tool-call entitas HTML. - Mistral, OpenCode Zen, dan OpenCode Go hanya menggunakan
capabilitiesuntuk menjaga keunikan transkrip/tooling tetap di luar core. - Provider bundled katalog-saja seperti
byteplus,cloudflare-ai-gateway,huggingface,kimi-coding,nvidia,qianfan,synthetic,together,venice,vercel-ai-gateway, danvolcenginemenggunakancatalogsaja. - Qwen menggunakan
cataloguntuk provider teksnya plus registrasi media-understanding dan video-generation bersama untuk surface multimodalnya. - MiniMax dan Xiaomi menggunakan
catalogplus usage hooks karena perilaku/usagemereka dimiliki plugin meskipun inferensi masih berjalan melalui transport bersama.
Helper runtime
Plugin dapat mengakses helper core tertentu melaluiapi.runtime. Untuk TTS:
textToSpeechmengembalikan payload keluaran TTS core normal untuk surface file/voice-note.- Menggunakan konfigurasi core
messages.ttsdan pemilihan provider. - Mengembalikan buffer audio PCM + sample rate. Plugin harus melakukan resample/encode untuk provider.
listVoicesbersifat opsional per provider. Gunakan untuk voice picker atau alur setup milik vendor.- Daftar suara dapat menyertakan metadata yang lebih kaya seperti locale, gender, dan tag kepribadian untuk picker yang sadar provider.
- OpenAI dan ElevenLabs mendukung telephony saat ini. Microsoft tidak.
api.registerSpeechProvider(...).
- Pertahankan kebijakan TTS, fallback, dan pengiriman balasan di core.
- Gunakan speech provider untuk perilaku sintesis milik vendor.
- Input
edgelegacy Microsoft dinormalisasi menjadi provider idmicrosoft. - Model kepemilikan yang disukai berorientasi pada company: satu plugin vendor dapat memiliki provider teks, speech, gambar, dan media di masa depan saat OpenClaw menambahkan kontrak kapabilitas tersebut.
- Pertahankan orkestrasi, fallback, config, dan wiring channel di core.
- Pertahankan perilaku vendor di plugin provider.
- Ekspansi aditif harus tetap typed: metode opsional baru, field hasil opsional baru, kapabilitas opsional baru.
- Pembuatan video sudah mengikuti pola yang sama:
- core memiliki kontrak kapabilitas dan helper runtime
- plugin vendor mendaftarkan
api.registerVideoGenerationProvider(...) - plugin fitur/channel mengonsumsi
api.runtime.videoGeneration.*
api.runtime.mediaUnderstanding.*adalah surface bersama yang disukai untuk pemahaman gambar/audio/video.- Menggunakan konfigurasi audio media-understanding core (
tools.media.audio) dan urutan fallback provider. - Mengembalikan
{ text: undefined }ketika tidak ada keluaran transkripsi yang dihasilkan (misalnya input dilewati/tidak didukung). api.runtime.stt.transcribeAudioFile(...)tetap tersedia sebagai alias kompatibilitas.
api.runtime.subagent:
providerdanmodeladalah override per-eksekusi opsional, bukan perubahan sesi persisten.- OpenClaw hanya menghormati field override tersebut untuk pemanggil tepercaya.
- Untuk eksekusi fallback milik plugin, operator harus memilih opt-in dengan
plugins.entries.<id>.subagent.allowModelOverride: true. - Gunakan
plugins.entries.<id>.subagent.allowedModelsuntuk membatasi plugin tepercaya ke target kanonisprovider/modeltertentu, atau"*"untuk secara eksplisit mengizinkan target apa pun. - Eksekusi subagent plugin tak tepercaya tetap berfungsi, tetapi permintaan override ditolak alih-alih diam-diam fallback.
api.registerWebSearchProvider(...).
Catatan:
- Pertahankan pemilihan provider, resolusi kredensial, dan semantik request bersama di core.
- Gunakan web-search provider untuk transport pencarian spesifik vendor.
api.runtime.webSearch.*adalah surface bersama yang disukai untuk plugin fitur/channel yang memerlukan perilaku pencarian tanpa bergantung pada wrapper tool agen.
api.runtime.imageGeneration
generate(...): buat gambar menggunakan rantai provider image-generation yang dikonfigurasi.listProviders(...): daftar provider image-generation yang tersedia dan kapabilitasnya.
Route HTTP Gateway
Plugin dapat mengekspos endpoint HTTP denganapi.registerHttpRoute(...).
path: path route di bawah server HTTP gateway.auth: wajib. Gunakan"gateway"untuk mewajibkan auth gateway normal, atau"plugin"untuk auth/verifikasi webhook yang dikelola plugin.match: opsional."exact"(default) atau"prefix".replaceExisting: opsional. Memungkinkan plugin yang sama mengganti registrasi route miliknya yang sudah ada.handler: kembalikantrueketika route menangani request.
api.registerHttpHandler(...)telah dihapus dan akan menyebabkan error pemuatan plugin. Gunakanapi.registerHttpRoute(...)sebagai gantinya.- Route plugin harus menyatakan
authsecara eksplisit. - Konflik
path + matchexact ditolak kecualireplaceExisting: true, dan satu plugin tidak dapat mengganti route plugin lain. - Route yang tumpang tindih dengan level
authberbeda akan ditolak. Pertahankan rantai fallthroughexact/prefixhanya pada level auth yang sama. - Route
auth: "plugin"tidak menerima scope runtime operator secara otomatis. Route ini ditujukan untuk webhook/verifikasi signature yang dikelola plugin, bukan panggilan helper Gateway yang memiliki privilese. - Route
auth: "gateway"berjalan di dalam runtime scope request Gateway, tetapi scope itu sengaja konservatif:- shared-secret bearer auth (
gateway.auth.mode = "token"/"password") mempertahankan scope runtime route plugin padaoperator.write, bahkan jika pemanggil mengirimx-openclaw-scopes - mode HTTP tepercaya yang membawa identitas (misalnya
trusted-proxyataugateway.auth.mode = "none"pada ingress privat) menghormatix-openclaw-scopeshanya ketika header itu secara eksplisit ada - jika
x-openclaw-scopestidak ada pada request route plugin yang membawa identitas tersebut, scope runtime fallback keoperator.write
- shared-secret bearer auth (
- Aturan praktis: jangan berasumsi bahwa route plugin dengan auth gateway adalah surface admin implisit. Jika route Anda memerlukan perilaku admin-only, wajibkan mode auth yang membawa identitas dan dokumentasikan kontrak header
x-openclaw-scopesyang eksplisit.
Path impor Plugin SDK
Gunakan subpath SDK alih-alih impor monolitikopenclaw/plugin-sdk saat
menulis plugin:
openclaw/plugin-sdk/plugin-entryuntuk primitif registrasi plugin.openclaw/plugin-sdk/coreuntuk kontrak umum bersama yang menghadap plugin.openclaw/plugin-sdk/config-schemauntuk ekspor skema Zod rootopenclaw.json(OpenClawSchema).- Primitif channel stabil seperti
openclaw/plugin-sdk/channel-setup,openclaw/plugin-sdk/setup-runtime,openclaw/plugin-sdk/setup-adapter-runtime,openclaw/plugin-sdk/setup-tools,openclaw/plugin-sdk/channel-pairing,openclaw/plugin-sdk/channel-contract,openclaw/plugin-sdk/channel-feedback,openclaw/plugin-sdk/channel-inbound,openclaw/plugin-sdk/channel-lifecycle,openclaw/plugin-sdk/channel-reply-pipeline,openclaw/plugin-sdk/command-auth,openclaw/plugin-sdk/secret-input, danopenclaw/plugin-sdk/webhook-ingressuntuk wiring setup/auth/reply/webhook bersama.channel-inboundadalah rumah bersama untuk debounce, pencocokan mention, pemformatan envelope, dan helper konteks envelope inbound.channel-setupadalah seam setup opsional-install yang sempit.setup-runtimeadalah surface setup yang aman untuk runtime yang digunakan olehsetupEntry/ startup yang ditunda, termasuk adapter patch setup yang aman untuk impor.setup-adapter-runtimeadalah seam adapter setup akun yang sadar env.setup-toolsadalah seam helper kecil untuk CLI/arsip/dokumen (formatCliCommand,detectBinary,extractArchive,resolveBrewExecutable,formatDocsLink,CONFIG_DIR). - Subpath domain seperti
openclaw/plugin-sdk/channel-config-helpers,openclaw/plugin-sdk/allow-from,openclaw/plugin-sdk/channel-config-schema,openclaw/plugin-sdk/telegram-command-config,openclaw/plugin-sdk/channel-policy,openclaw/plugin-sdk/approval-runtime,openclaw/plugin-sdk/config-runtime,openclaw/plugin-sdk/infra-runtime,openclaw/plugin-sdk/agent-runtime,openclaw/plugin-sdk/lazy-runtime,openclaw/plugin-sdk/reply-history,openclaw/plugin-sdk/routing,openclaw/plugin-sdk/status-helpers,openclaw/plugin-sdk/text-runtime,openclaw/plugin-sdk/runtime-store, danopenclaw/plugin-sdk/directory-runtimeuntuk helper runtime/config bersama.telegram-command-configadalah seam publik sempit untuk normalisasi/validasi custom command Telegram dan tetap tersedia meskipun surface kontrak Telegram bundled sementara tidak tersedia.text-runtimeadalah seam bersama untuk teks/markdown/logging, termasuk penghilangan teks yang terlihat oleh asisten, helper render/chunking markdown, helper redaksi, helper directive-tag, dan utilitas safe-text. - Seam channel spesifik persetujuan sebaiknya memilih satu kontrak
approvalCapabilitypada plugin. Core kemudian membaca auth persetujuan, pengiriman, render, dan perilaku native-routing melalui satu kapabilitas itu alih-alih mencampur perilaku persetujuan ke field plugin yang tidak terkait. openclaw/plugin-sdk/channel-runtimesudah deprecated dan hanya tersisa sebagai shim kompatibilitas untuk plugin lama. Kode baru sebaiknya mengimpor primitif generik yang lebih sempit sebagai gantinya, dan kode repo tidak boleh menambah impor baru terhadap shim tersebut.- Internal extension bundled tetap privat. Plugin eksternal sebaiknya hanya menggunakan
subpath
openclaw/plugin-sdk/*. Kode core/test OpenClaw dapat menggunakan entry point publik repo di bawah root package plugin sepertiindex.js,api.js,runtime-api.js,setup-entry.js, dan file yang cakupannya sempit sepertilogin-qr-api.js. Jangan pernah mengimporsrc/*package plugin dari core atau dari extension lain. - Pembagian entry point repo:
<plugin-package-root>/api.jsadalah barrel helper/types,<plugin-package-root>/runtime-api.jsadalah barrel runtime-only,<plugin-package-root>/index.jsadalah entry plugin bundled, dan<plugin-package-root>/setup-entry.jsadalah entry plugin setup. - Contoh provider bundled saat ini:
- Anthropic menggunakan
api.js/contract-api.jsuntuk helper stream Claude sepertiwrapAnthropicProviderStream, helper beta-header, dan parsingservice_tier. - OpenAI menggunakan
api.jsuntuk builder provider, helper model default, dan builder provider realtime. - OpenRouter menggunakan
api.jsuntuk builder provider plus helper onboarding/config, sedangkanregister.runtime.jsmasih dapat mengekspor ulang helper generikplugin-sdk/provider-streamuntuk penggunaan lokal repo.
- Anthropic menggunakan
- Entry point publik yang dimuat melalui facade lebih memilih snapshot config runtime aktif ketika ada, lalu fallback ke file config ter-resolve di disk ketika OpenClaw belum melayani snapshot runtime.
- Primitif generik bersama tetap menjadi kontrak SDK publik yang disukai. Sebagian kecil
seam helper bermerek channel bundled yang dicadangkan untuk kompatibilitas masih ada.
Perlakukan itu sebagai seam pemeliharaan/kompatibilitas bundled, bukan target impor pihak ketiga baru;
kontrak lintas-channel baru tetap sebaiknya berada pada subpath generik
plugin-sdk/*atau barrel plugin-localapi.js/runtime-api.js.
- Hindari barrel root
openclaw/plugin-sdkuntuk kode baru. - Lebih pilih primitif stabil yang sempit terlebih dahulu. Subpath setup/pairing/reply/
feedback/contract/inbound/threading/command/secret-input/webhook/infra/
allowlist/status/message-tool yang lebih baru adalah kontrak yang dituju untuk pekerjaan plugin bundled dan eksternal baru.
Parsing/pencocokan target berada pada
openclaw/plugin-sdk/channel-targets. Gate action pesan dan helper message-id reaksi berada padaopenclaw/plugin-sdk/channel-actions. - Barrel helper spesifik extension bundled tidak stabil secara default. Jika sebuah
helper hanya diperlukan oleh extension bundled, simpan di balik seam lokal
api.jsatauruntime-api.jsmilik extension itu alih-alih mempromosikannya keopenclaw/plugin-sdk/<extension>. - Seam helper bersama yang baru sebaiknya generik, bukan bermerek channel. Parsing target bersama
berada pada
openclaw/plugin-sdk/channel-targets; internal spesifik channel tetap berada di balik seam lokalapi.jsatauruntime-api.jsmilik plugin. - Subpath spesifik kapabilitas seperti
image-generation,media-understanding, danspeechada karena plugin bundled/native menggunakannya hari ini. Keberadaannya tidak dengan sendirinya berarti setiap helper yang diekspor adalah kontrak eksternal jangka panjang yang dibekukan.
Skema tool pesan
Plugin sebaiknya memiliki kontribusi schemadescribeMessageTool(...) spesifik channel.
Pertahankan field spesifik provider di plugin, bukan di core bersama.
Untuk fragmen schema portabel bersama, gunakan ulang helper generik yang diekspor melalui
openclaw/plugin-sdk/channel-actions:
createMessageToolButtonsSchema()untuk payload gaya grid tombolcreateMessageToolCardSchema()untuk payload kartu terstruktur
Resolusi target channel
Plugin channel sebaiknya memiliki semantik target spesifik channel. Pertahankan host outbound bersama tetap generik dan gunakan surface adapter perpesanan untuk aturan provider:messaging.inferTargetChatType({ to })memutuskan apakah target yang dinormalisasi harus diperlakukan sebagaidirect,group, atauchannelsebelum lookup direktori.messaging.targetResolver.looksLikeId(raw, normalized)memberi tahu core apakah sebuah input harus langsung menuju resolusi yang mirip id alih-alih pencarian direktori.messaging.targetResolver.resolveTarget(...)adalah fallback plugin ketika core memerlukan resolusi akhir milik provider setelah normalisasi atau setelah direktori tidak menemukan hasil.messaging.resolveOutboundSessionRoute(...)memiliki konstruksi route sesi spesifik provider setelah target ter-resolve.
- Gunakan
inferTargetChatTypeuntuk keputusan kategori yang harus terjadi sebelum pencarian peer/group. - Gunakan
looksLikeIduntuk pemeriksaan “perlakukan ini sebagai id target eksplisit/native”. - Gunakan
resolveTargetuntuk fallback normalisasi spesifik provider, bukan untuk pencarian direktori luas. - Simpan id native provider seperti chat id, thread id, JID, handle, dan room
id di dalam nilai
targetatau parameter spesifik provider, bukan di field SDK generik.
Direktori berbasis config
Plugin yang menurunkan entri direktori dari config harus menyimpan logika itu di plugin dan menggunakan ulang helper bersama dariopenclaw/plugin-sdk/directory-runtime.
Gunakan ini saat sebuah channel memerlukan peer/group berbasis config seperti:
- peer DM berbasis allowlist
- peta channel/group yang dikonfigurasi
- fallback direktori statis dengan scope akun
directory-runtime hanya menangani operasi generik:
- filtering query
- penerapan limit
- helper deduping/normalisasi
- membangun
ChannelDirectoryEntry[]
Katalog provider
Plugin provider dapat mendefinisikan katalog model untuk inferensi denganregisterProvider({ catalog: { run(...) { ... } } }).
catalog.run(...) mengembalikan bentuk yang sama yang ditulis OpenClaw ke dalam
models.providers:
{ provider }untuk satu entri provider{ providers }untuk beberapa entri provider
catalog ketika plugin memiliki model id spesifik provider, default base URL,
atau metadata model yang bergantung pada auth.
catalog.order mengontrol kapan katalog plugin digabung relatif terhadap provider
implisit bawaan OpenClaw:
simple: provider berbasis API key atau env biasaprofile: provider yang muncul ketika profil auth adapaired: provider yang mensintesis beberapa entri provider terkaitlate: pass terakhir, setelah provider implisit lain
discoverytetap berfungsi sebagai alias legacy- jika
catalogdandiscoverysama-sama didaftarkan, OpenClaw menggunakancatalog
Inspeksi channel baca-saja
Jika plugin Anda mendaftarkan channel, pilih implementasiplugin.config.inspectAccount(cfg, accountId) di samping resolveAccount(...).
Mengapa:
resolveAccount(...)adalah jalur runtime. Jalur ini boleh mengasumsikan kredensial sudah sepenuhnya termaterialisasi dan dapat gagal cepat saat secret yang diperlukan tidak ada.- Jalur command baca-saja seperti
openclaw status,openclaw status --all,openclaw channels status,openclaw channels resolve, dan alur doctor/perbaikan config seharusnya tidak perlu mematerialisasi kredensial runtime hanya untuk mendeskripsikan konfigurasi.
inspectAccount(...) yang direkomendasikan:
- Kembalikan hanya status akun yang deskriptif.
- Pertahankan
enableddanconfigured. - Sertakan field sumber/status kredensial bila relevan, seperti:
tokenSource,tokenStatusbotTokenSource,botTokenStatusappTokenSource,appTokenStatussigningSecretSource,signingSecretStatus
- Anda tidak perlu mengembalikan nilai token mentah hanya untuk melaporkan
ketersediaan baca-saja. Mengembalikan
tokenStatus: "available"(dan field sumber yang cocok) sudah cukup untuk command bergaya status. - Gunakan
configured_unavailableketika sebuah kredensial dikonfigurasi melalui SecretRef tetapi tidak tersedia pada jalur command saat ini.
Package pack
Direktori plugin dapat menyertakanpackage.json dengan openclaw.extensions:
name/<fileBase>.
Jika plugin Anda mengimpor dependency npm, instal dependency tersebut di direktori itu agar
node_modules tersedia (npm install / pnpm install).
Guardrail keamanan: setiap entry openclaw.extensions harus tetap berada di dalam direktori plugin
setelah resolusi symlink. Entry yang keluar dari direktori package akan
ditolak.
Catatan keamanan: openclaw plugins install menginstal dependency plugin dengan
npm install --omit=dev --ignore-scripts (tanpa lifecycle script, tanpa dependency dev saat runtime). Pertahankan pohon dependency plugin tetap “pure JS/TS” dan hindari package yang memerlukan build postinstall.
Opsional: openclaw.setupEntry dapat menunjuk ke modul setup-only yang ringan.
Saat OpenClaw memerlukan surface setup untuk plugin channel yang dinonaktifkan, atau
saat plugin channel diaktifkan tetapi masih belum terkonfigurasi, OpenClaw memuat setupEntry
alih-alih entry plugin penuh. Ini membuat startup dan setup lebih ringan
ketika entry plugin utama Anda juga me-wiring tool, hook, atau kode
runtime-only lainnya.
Opsional: openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen
dapat memilih sebuah plugin channel untuk menggunakan jalur setupEntry yang sama selama
fase startup pre-listen gateway, bahkan ketika channel sudah dikonfigurasi.
Gunakan ini hanya ketika setupEntry sepenuhnya mencakup surface startup yang harus ada
sebelum gateway mulai mendengarkan. Dalam praktiknya, itu berarti entry setup
harus mendaftarkan setiap kapabilitas milik channel yang dibutuhkan startup, seperti:
- registrasi channel itu sendiri
- setiap route HTTP yang harus tersedia sebelum gateway mulai mendengarkan
- setiap method gateway, tool, atau layanan yang harus ada selama jendela yang sama
singleAccountKeysToMovenamedAccountPromotionKeysresolveSingleAccountPromotionTarget(...)
channels.<id>.accounts.* tanpa memuat entry plugin penuh.
Matrix adalah contoh bundled saat ini: plugin ini hanya memindahkan key auth/bootstrap ke
akun promoted bernama saat akun bernama sudah ada, dan dapat mempertahankan
key default-account non-kanonis yang sudah dikonfigurasi alih-alih selalu membuat
accounts.default.
Adapter patch setup tersebut menjaga discovery contract-surface bundled tetap lazy. Waktu impor tetap ringan; surface promosi hanya dimuat saat pertama kali digunakan alih-alih
masuk kembali ke startup channel bundled pada saat impor modul.
Saat surface startup tersebut mencakup method RPC gateway, simpan pada
prefix spesifik plugin. Namespace admin core (config.*,
exec.approvals.*, wizard.*, update.*) tetap dicadangkan dan selalu ter-resolve
ke operator.admin, bahkan jika plugin meminta scope yang lebih sempit.
Contoh:
Metadata katalog channel
Plugin channel dapat mengiklankan metadata setup/discovery melaluiopenclaw.channel dan
petunjuk instalasi melalui openclaw.install. Ini menjaga data katalog core bebas data keras.
Contoh:
openclaw.channel yang berguna di luar contoh minimal:
detailLabel: label sekunder untuk surface katalog/status yang lebih kayadocsLabel: override teks tautan untuk tautan dokumenpreferOver: id plugin/channel prioritas lebih rendah yang seharusnya dikalahkan oleh entri katalog iniselectionDocsPrefix,selectionDocsOmitLabel,selectionExtras: kontrol salinan surface pemilihanmarkdownCapable: menandai channel sebagai mampu markdown untuk keputusan pemformatan outboundshowConfigured: sembunyikan channel dari surface daftar channel terkonfigurasi ketika disetel kefalsequickstartAllowFrom: memilih channel ini untuk alurallowFromquickstart standarforceAccountBinding: wajibkan pengikatan akun eksplisit bahkan ketika hanya ada satu akunpreferSessionLookupForAnnounceTarget: pilih lookup sesi saat meresolve target announce
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
OPENCLAW_PLUGIN_CATALOG_PATHS (atau OPENCLAW_MPM_CATALOG_PATHS) ke
satu atau lebih file JSON (dipisahkan dengan koma/titik koma/PATH). Setiap file harus
berisi { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }. Parser juga menerima "packages" atau "plugins" sebagai alias legacy untuk key "entries".
Plugin context engine
Plugin context engine memiliki orkestrasi konteks sesi untuk ingest, assembly, dan compaction. Daftarkan dari plugin Anda denganapi.registerContextEngine(id, factory), lalu pilih engine aktif dengan
plugins.slots.contextEngine.
Gunakan ini saat plugin Anda perlu mengganti atau memperluas pipeline konteks default
alih-alih hanya menambahkan pencarian memory atau hook.
compact()
dan delegasikan secara eksplisit:
Menambahkan kapabilitas baru
Ketika sebuah plugin memerlukan perilaku yang tidak cocok dengan API saat ini, jangan melewati sistem plugin dengan reach-in privat. Tambahkan kapabilitas yang hilang. Urutan yang direkomendasikan:- definisikan kontrak core Putuskan perilaku bersama apa yang seharusnya dimiliki core: kebijakan, fallback, penggabungan config, lifecycle, semantik yang menghadap channel, dan bentuk helper runtime.
- tambahkan surface registrasi/runtime plugin yang typed
Perluas
OpenClawPluginApidan/atauapi.runtimedengan surface kapabilitas typed paling kecil yang berguna. - hubungkan konsumen core + channel/fitur Channel dan plugin fitur sebaiknya mengonsumsi kapabilitas baru melalui core, bukan dengan mengimpor implementasi vendor secara langsung.
- daftarkan implementasi vendor Plugin vendor kemudian mendaftarkan backend mereka terhadap kapabilitas tersebut.
- tambahkan cakupan kontrak Tambahkan pengujian agar kepemilikan dan bentuk registrasi tetap eksplisit seiring waktu.
Daftar periksa kapabilitas
Ketika Anda menambahkan kapabilitas baru, implementasi biasanya harus menyentuh surface-surface ini secara bersama:- tipe kontrak core di
src/<capability>/types.ts - helper runner/runtime core di
src/<capability>/runtime.ts - surface registrasi API plugin di
src/plugins/types.ts - wiring registry plugin di
src/plugins/registry.ts - eksposur runtime plugin di
src/plugins/runtime/*ketika plugin fitur/channel perlu mengonsumsinya - helper capture/test di
src/test-utils/plugin-registration.ts - asersi kepemilikan/kontrak di
src/plugins/contracts/registry.ts - dokumen operator/plugin di
docs/
Template kapabilitas
Pola minimal:- core memiliki kontrak kapabilitas + orkestrasi
- plugin vendor memiliki implementasi vendor
- plugin fitur/channel mengonsumsi helper runtime
- pengujian kontrak menjaga kepemilikan tetap eksplisit