Alur pemuatan
Saat mulai berjalan, OpenClaw secara garis besar melakukan ini:- menemukan akar Plugin kandidat
- membaca manifes bundel native atau kompatibel dan metadata paket
- menolak kandidat yang tidak aman
- menormalkan konfigurasi Plugin (
plugins.enabled,allow,deny,entries,slots,load.paths) - menentukan pengaktifan untuk setiap kandidat
- memuat modul native yang diaktifkan: modul bundel bawaan menggunakan pemuat native; sumber lokal TypeScript pihak ketiga menggunakan mekanisme cadangan darurat Jiti
- memanggil kait native
register(api)dan mengumpulkan registrasi ke registri Plugin - mengekspos registri ke permukaan perintah/waktu jalan
activate adalah alias lama untuk register — pemuat menyelesaikan mana pun yang tersedia (def.register ?? def.activate) dan memanggilnya pada titik yang sama. Semua Plugin bundel menggunakan register; pilih register untuk Plugin baru.Perilaku mengutamakan manifes
Manifes adalah sumber kebenaran bidang kontrol. OpenClaw menggunakannya untuk:- mengidentifikasi Plugin
- menemukan kanal/Skills/skema konfigurasi yang dideklarasikan atau kapabilitas bundel
- memvalidasi
plugins.entries.<id>.config - memperkaya label/placeholder Control UI
- menampilkan metadata instalasi/katalog
- mempertahankan deskriptor aktivasi dan penyiapan yang murah tanpa memuat waktu jalan Plugin
activation dan setup tetap berada di bidang kontrol.
Keduanya adalah deskriptor khusus metadata untuk perencanaan aktivasi dan
penemuan penyiapan; keduanya tidak menggantikan registrasi waktu jalan,
register(...), atau setupEntry. Konsumen aktivasi langsung pertama kini
menggunakan petunjuk perintah, kanal, dan penyedia dari manifes untuk
mempersempit pemuatan Plugin sebelum materialisasi registri yang lebih luas:
- pemuatan CLI dipersempit ke Plugin yang memiliki perintah utama yang diminta
- penyiapan kanal/resolusi Plugin dipersempit ke Plugin yang memiliki id kanal yang diminta
- penyiapan/resolusi waktu jalan penyedia eksplisit dipersempit ke Plugin yang memiliki id penyedia yang diminta
- perencanaan startup Gateway menggunakan
activation.onStartupuntuk impor startup eksplisit dan pengecualian startup; Plugin tanpa metadata startup hanya dimuat melalui pemicu aktivasi yang lebih sempit
all yang luas
tetap menurunkan kumpulan id Plugin efektif eksplisit dari konfigurasi,
perencanaan startup, kanal yang dikonfigurasi, slot, dan aturan pengaktifan
otomatis. Jika kumpulan turunan itu kosong, OpenClaw memuat registri waktu jalan
kosong alih-alih memperluas ke setiap Plugin yang dapat ditemukan.
Perencana aktivasi mengekspos API khusus id untuk pemanggil yang sudah ada dan
API rencana untuk diagnostik baru. Entri rencana melaporkan mengapa sebuah
Plugin dipilih, memisahkan petunjuk perencana activation.* eksplisit dari
cadangan kepemilikan manifes seperti providers, channels, commandAliases,
setup.providers, contracts.tools, dan kait. Pemisahan alasan itu adalah
batas kompatibilitas: metadata Plugin yang sudah ada tetap berfungsi, sementara
kode baru dapat mendeteksi petunjuk luas atau perilaku cadangan tanpa mengubah
semantik pemuatan waktu jalan.
Penemuan penyiapan kini lebih memilih id yang dimiliki deskriptor seperti
setup.providers dan setup.cliBackends untuk mempersempit Plugin kandidat
sebelum kembali ke setup-api untuk Plugin yang masih membutuhkan kait waktu
jalan pada saat penyiapan. Daftar penyiapan penyedia menggunakan
providerAuthChoices manifes, pilihan penyiapan turunan deskriptor, dan metadata
katalog instalasi tanpa memuat waktu jalan penyedia. setup.requiresRuntime: false
eksplisit adalah batas khusus deskriptor; requiresRuntime yang dihilangkan
mempertahankan cadangan setup-api lama untuk kompatibilitas. Jika lebih dari
satu Plugin yang ditemukan mengklaim id penyedia penyiapan atau backend CLI
ternormalisasi yang sama, pencarian penyiapan menolak pemilik yang ambigu
alih-alih mengandalkan urutan penemuan. Ketika waktu jalan penyiapan memang
dieksekusi, diagnostik registri melaporkan penyimpangan antara setup.providers
/ setup.cliBackends dan penyedia atau backend CLI yang didaftarkan oleh
setup-api tanpa memblokir Plugin lama.
Batas cache Plugin
OpenClaw tidak menyimpan cache hasil penemuan Plugin atau data registri manifes langsung di balik jendela berbasis jam dinding. Instalasi, penyuntingan manifes, dan perubahan jalur pemuatan harus terlihat pada pembacaan metadata eksplisit berikutnya atau pembangunan ulang snapshot berikutnya. Parser file manifes boleh menyimpan cache tanda tangan file terbatas yang dikunci oleh jalur manifes yang dibuka, inode, ukuran, dan timestamp; cache itu hanya menghindari pemarsingan ulang byte yang tidak berubah dan tidak boleh menyimpan jawaban penemuan, registri, pemilik, atau kebijakan. Jalur cepat metadata yang aman adalah kepemilikan objek eksplisit, bukan cache tersembunyi. Jalur panas startup Gateway harus meneruskanPluginMetadataSnapshot
saat ini, PluginLookUpTable turunan, atau registri manifes eksplisit melalui
rantai panggilan. Validasi konfigurasi, pengaktifan otomatis startup, bootstrap
Plugin, dan pemilihan penyedia dapat menggunakan ulang objek-objek itu selama
mereka merepresentasikan konfigurasi dan inventaris Plugin saat ini. Pencarian
penyiapan tetap merekonstruksi metadata manifes sesuai permintaan kecuali jalur
penyiapan spesifik menerima registri manifes eksplisit; pertahankan itu sebagai
cadangan jalur dingin alih-alih menambahkan cache pencarian tersembunyi. Ketika
input berubah, bangun ulang dan ganti snapshot alih-alih memutasinya atau
menyimpan salinan historis.
Tampilan atas registri Plugin aktif dan pembantu bootstrap kanal bundel harus
dihitung ulang dari registri/akar saat ini. Peta berumur pendek boleh digunakan
di dalam satu panggilan untuk menghapus duplikasi pekerjaan atau menjaga
reentri; peta tersebut tidak boleh menjadi cache metadata proses.
Untuk pemuatan Plugin, lapisan cache persisten adalah pemuatan waktu jalan.
Lapisan ini boleh menggunakan ulang status pemuat ketika kode atau artefak
terpasang benar-benar dimuat, seperti:
PluginLoaderCacheStatedan registri waktu jalan aktif yang kompatibel- cache jiti/modul dan cache pemuat permukaan publik yang digunakan untuk menghindari impor permukaan waktu jalan yang sama berulang kali
- cache sistem file untuk artefak Plugin terpasang
- peta per panggilan berumur pendek untuk normalisasi jalur atau resolusi duplikat
- hasil penemuan
- registri manifes langsung
- registri manifes yang direkonstruksi dari indeks Plugin terpasang
- pencarian pemilik penyedia, penekanan model, kebijakan penyedia, atau metadata artefak publik
- jawaban turunan manifes lainnya yang seharusnya membuat manifes yang berubah, indeks terpasang, atau jalur pemuatan terlihat pada pembacaan metadata berikutnya
Model registri
Plugin yang dimuat tidak secara langsung memutasi global inti acak. Mereka mendaftar ke registri Plugin pusat. Registri melacak:- catatan Plugin (identitas, sumber, asal, status, diagnostik)
- alat
- kait lama dan kait bertipe
- kanal
- penyedia
- handler RPC Gateway
- rute HTTP
- registrar CLI
- layanan latar belakang
- perintah yang dimiliki Plugin
- modul Plugin -> registrasi registri
- waktu jalan inti -> konsumsi registri
Callback pengikatan percakapan
Plugin yang mengikat percakapan dapat bereaksi ketika sebuah persetujuan diselesaikan. Gunakanapi.onConversationBindingResolved(...) untuk menerima callback setelah
permintaan pengikatan disetujui atau ditolak:
status:"approved"atau"denied"decision:"allow-once","allow-always", atau"deny"binding: pengikatan yang diselesaikan untuk permintaan yang disetujuirequest: ringkasan permintaan asli, petunjuk pelepasan, id pengirim, dan metadata percakapan
Kait waktu jalan penyedia
Plugin penyedia memiliki tiga lapisan:- Metadata manifes untuk pencarian murah sebelum waktu jalan:
setup.providers[].envVars, kompatibilitas usangproviderAuthEnvVars,providerAuthAliases,providerAuthChoices, danchannelEnvVars. - Kait waktu konfigurasi:
catalog(discoverylama) ditambahapplyConfigDefaults. - Kait waktu jalan: 40+ kait opsional yang mencakup autentikasi, resolusi model, pembungkusan stream, level berpikir, kebijakan replay, dan endpoint penggunaan. Lihat daftar lengkap di Urutan dan penggunaan kait.
setup.providers[].envVars ketika penyedia memiliki kredensial
berbasis env yang harus dilihat jalur autentikasi/status/pemilih-model generik
tanpa memuat waktu jalan Plugin. providerAuthEnvVars yang usang masih dibaca
oleh adapter kompatibilitas selama jendela deprekasi, dan Plugin non-bundel yang
menggunakannya menerima diagnostik manifes. Gunakan manifes
providerAuthAliases ketika satu id penyedia harus menggunakan ulang env var,
profil autentikasi, autentikasi berbasis konfigurasi, dan pilihan onboarding
kunci API milik id penyedia lain. Gunakan manifes providerAuthChoices ketika
permukaan CLI onboarding/pilihan-autentikasi harus mengetahui id pilihan
penyedia, label grup, dan pengabelan autentikasi satu-flag sederhana tanpa
memuat waktu jalan penyedia. Pertahankan envVars waktu jalan penyedia untuk
petunjuk yang menghadap operator seperti label onboarding atau variabel
penyiapan client-id/client-secret OAuth.
Gunakan manifes channelEnvVars ketika sebuah kanal memiliki autentikasi atau
penyiapan berbasis env yang harus dilihat oleh cadangan shell-env generik,
pemeriksaan konfigurasi/status, atau prompt penyiapan tanpa memuat waktu jalan
kanal.
Urutan dan penggunaan kait
Untuk Plugin model/penyedia, OpenClaw memanggil kait dalam urutan kasar ini. Kolom “Kapan digunakan” adalah panduan keputusan cepat. Field penyedia khusus kompatibilitas yang tidak lagi dipanggil OpenClaw, sepertiProviderPlugin.capabilities dan suppressBuiltInModel, sengaja tidak
dicantumkan di sini.
| # | Kait | Fungsinya | Kapan digunakan |
|---|---|---|---|
| 1 | catalog | Menerbitkan konfigurasi penyedia ke models.providers selama pembuatan models.json | Penyedia memiliki katalog atau default URL dasar |
| 2 | applyConfigDefaults | Menerapkan default konfigurasi global milik penyedia selama materialisasi konfigurasi | Default bergantung pada mode auth, env, atau semantik keluarga model penyedia |
| — | (pencarian model bawaan) | OpenClaw mencoba jalur registry/katalog normal terlebih dahulu | (bukan kait plugin) |
| 3 | normalizeModelId | Menormalkan alias ID model legacy atau pratinjau sebelum pencarian | Penyedia memiliki pembersihan alias sebelum resolusi model kanonis |
| 4 | normalizeTransport | Menormalkan api / baseUrl keluarga penyedia sebelum perakitan model generik | Penyedia memiliki pembersihan transport untuk ID penyedia kustom dalam keluarga transport yang sama |
| 5 | normalizeConfig | Menormalkan models.providers.<id> sebelum resolusi runtime/penyedia | Penyedia memerlukan pembersihan konfigurasi yang seharusnya berada di plugin; helper keluarga Google bawaan juga menopang entri konfigurasi Google yang didukung |
| 6 | applyNativeStreamingUsageCompat | Menerapkan penulisan ulang kompat native streaming-usage ke penyedia konfigurasi | Penyedia memerlukan perbaikan metadata penggunaan streaming native berbasis endpoint |
| 7 | resolveConfigApiKey | Menyelesaikan auth penanda env untuk penyedia konfigurasi sebelum pemuatan auth runtime | Penyedia mengekspos kait resolusi kunci API penanda env milik sendiri |
| 8 | resolveSyntheticAuth | Memunculkan auth lokal/self-hosted atau berbasis konfigurasi tanpa menyimpan plaintext | Penyedia dapat beroperasi dengan penanda kredensial sintetis/lokal |
| 9 | resolveExternalAuthProfiles | Melapisi profil auth eksternal milik penyedia; default persistence adalah runtime-only untuk kredensial milik CLI/aplikasi | Penyedia menggunakan kembali kredensial auth eksternal tanpa menyimpan refresh token yang disalin; deklarasikan contracts.externalAuthProviders di manifes |
| 10 | shouldDeferSyntheticProfileAuth | Menurunkan prioritas placeholder profil sintetis tersimpan di belakang auth berbasis env/konfigurasi | Penyedia menyimpan profil placeholder sintetis yang tidak boleh menang prioritas |
| 11 | resolveDynamicModel | Fallback sinkron untuk ID model milik penyedia yang belum ada di registry lokal | Penyedia menerima ID model upstream arbitrer |
| 12 | prepareDynamicModel | Pemanasan asinkron, lalu resolveDynamicModel berjalan lagi | Penyedia memerlukan metadata jaringan sebelum menyelesaikan ID yang tidak dikenal |
| 13 | normalizeResolvedModel | Penulisan ulang final sebelum runner tertanam menggunakan model yang sudah diselesaikan | Penyedia memerlukan penulisan ulang transport tetapi tetap menggunakan transport inti |
| 14 | normalizeToolSchemas | Menormalkan skema tool sebelum runner tertanam melihatnya | Penyedia memerlukan pembersihan skema keluarga transport |
| 15 | inspectToolSchemas | Memunculkan diagnostik skema milik penyedia setelah normalisasi | Penyedia menginginkan peringatan kata kunci tanpa mengajarkan aturan khusus penyedia ke inti |
| 16 | resolveReasoningOutputMode | Memilih kontrak output reasoning native vs bertag | Penyedia memerlukan reasoning/output final bertag alih-alih field native |
| 17 | prepareExtraParams | Normalisasi parameter request sebelum wrapper opsi stream generik | Penyedia memerlukan parameter request default atau pembersihan parameter per penyedia |
| 18 | createStreamFn | Sepenuhnya mengganti jalur stream normal dengan transport kustom | Penyedia memerlukan protokol wire kustom, bukan hanya wrapper |
| 20 | wrapStreamFn | Wrapper stream setelah wrapper generik diterapkan | Penyedia memerlukan wrapper kompat header/body/model request tanpa transport kustom |
| 21 | resolveTransportTurnState | Melampirkan header atau metadata transport native per giliran | Penyedia ingin transport generik mengirim identitas giliran native penyedia |
| 22 | resolveWebSocketSessionPolicy | Melampirkan header WebSocket native atau kebijakan cool-down sesi | Penyedia ingin transport WS generik menyesuaikan header sesi atau kebijakan fallback |
| 23 | formatApiKey | Pemformat profil auth: profil tersimpan menjadi string apiKey runtime | Penyedia menyimpan metadata auth tambahan dan memerlukan bentuk token runtime kustom |
| 24 | refreshOAuth | Override refresh OAuth untuk endpoint refresh kustom atau kebijakan kegagalan refresh | Penyedia tidak cocok dengan refresher OpenClaw bersama |
| 25 | buildAuthDoctorHint | Petunjuk perbaikan yang ditambahkan saat refresh OAuth gagal | Penyedia memerlukan panduan perbaikan auth milik penyedia setelah kegagalan refresh |
| 26 | matchesContextOverflowError | Pencocok overflow context-window milik penyedia | Penyedia memiliki error overflow mentah yang akan terlewat oleh heuristik generik |
| 27 | classifyFailoverReason | Klasifikasi alasan failover milik penyedia | Penyedia dapat memetakan error API/transport mentah ke rate-limit/overload/dll |
| 28 | isCacheTtlEligible | Kebijakan prompt-cache untuk penyedia proxy/backhaul | Penyedia memerlukan gating TTL cache khusus proxy |
| 29 | buildMissingAuthMessage | Pengganti pesan pemulihan auth hilang generik | Penyedia memerlukan petunjuk pemulihan auth hilang khusus penyedia |
| 30 | augmentModelCatalog | Baris katalog sintetis/final yang ditambahkan setelah discovery | Penyedia memerlukan baris forward-compat sintetis di models list dan pemilih |
| 31 | resolveThinkingProfile | Kumpulan level /think khusus model, label tampilan, dan default | Penyedia mengekspos tangga thinking kustom atau label biner untuk model terpilih |
| 32 | isBinaryThinking | Kait kompatibilitas toggle reasoning hidup/mati | Penyedia hanya mengekspos thinking biner hidup/mati |
| 33 | supportsXHighThinking | Kait kompatibilitas dukungan reasoning xhigh | Penyedia menginginkan xhigh hanya pada sebagian model |
| 34 | resolveDefaultThinkingLevel | Kait kompatibilitas level /think default | Penyedia memiliki kebijakan /think default untuk sebuah keluarga model |
| 35 | isModernModelRef | Pencocok model modern untuk filter profil live dan pemilihan smoke | Penyedia memiliki pencocokan model pilihan live/smoke |
| 36 | prepareRuntimeAuth | Menukar kredensial terkonfigurasi menjadi token/kunci runtime aktual tepat sebelum inferensi | Penyedia memerlukan pertukaran token atau kredensial request berumur pendek |
| 37 | resolveUsageAuth | Menyelesaikan kredensial penggunaan/billing untuk /usage dan permukaan status terkait | Penyedia memerlukan parsing token penggunaan/kuota kustom atau kredensial penggunaan yang berbeda |
| 38 | fetchUsageSnapshot | Mengambil dan menormalkan snapshot penggunaan/kuota khusus provider setelah auth diselesaikan | Provider memerlukan endpoint penggunaan khusus provider atau parser payload |
| 39 | createEmbeddingProvider | Membangun adapter embedding milik provider untuk memori/pencarian | Perilaku embedding memori menjadi milik Plugin provider |
| 40 | buildReplayPolicy | Mengembalikan kebijakan replay yang mengontrol penanganan transkrip untuk provider | Provider memerlukan kebijakan transkrip khusus (misalnya, penghapusan thinking-block) |
| 41 | sanitizeReplayHistory | Menulis ulang riwayat replay setelah pembersihan transkrip generik | Provider memerlukan penulisan ulang replay khusus provider di luar helper compaction bersama |
| 42 | validateReplayTurns | Validasi akhir replay-turn atau pembentukan ulang sebelum runner tertanam | Transport provider memerlukan validasi giliran yang lebih ketat setelah sanitasi generik |
| 43 | onModelSelected | Menjalankan efek samping pasca-pemilihan milik provider | Provider memerlukan telemetri atau state milik provider saat model menjadi aktif |
normalizeModelId, normalizeTransport, dan normalizeConfig pertama-tama memeriksa
Plugin penyedia yang cocok, lalu meneruskan ke Plugin penyedia lain yang mendukung hook
hingga ada yang benar-benar mengubah id model atau transport/config. Ini menjaga
shim penyedia alias/kompat tetap berfungsi tanpa mengharuskan pemanggil mengetahui
Plugin bawaan mana yang memiliki penulisan ulang tersebut. Jika tidak ada hook penyedia yang menulis ulang entri config
keluarga Google yang didukung, normalizer config Google bawaan tetap menerapkan
pembersihan kompatibilitas tersebut.
Jika penyedia membutuhkan protokol wire yang sepenuhnya khusus atau eksekutor permintaan khusus,
itu adalah kelas ekstensi yang berbeda. Hook ini ditujukan untuk perilaku penyedia
yang masih berjalan pada loop inferensi normal OpenClaw.
resolveUsageAuth memutuskan apakah OpenClaw harus memanggil fetchUsageSnapshot atau
kembali ke resolusi kredensial generik untuk permukaan penggunaan/status. Kembalikan
{ token, accountId? } ketika penyedia memiliki kredensial penggunaan, kembalikan
{ handled: true } ketika auth penggunaan milik penyedia telah menangani permintaan dan
harus menekan fallback API-key/OAuth generik, dan kembalikan null atau undefined
ketika penyedia tidak menangani auth penggunaan.
Contoh penyedia
Contoh bawaan
Plugin penyedia bawaan mengombinasikan hook di atas agar sesuai dengan kebutuhan catalog, auth, pemikiran, replay, dan penggunaan tiap vendor. Kumpulan hook otoritatif berada bersama setiap Plugin di bawahextensions/; halaman ini mengilustrasikan bentuknya, bukan
mencerminkan daftar tersebut.
Penyedia catalog pass-through
Penyedia catalog pass-through
OpenRouter, Kilocode, Z.AI, xAI mendaftarkan
catalog plus
resolveDynamicModel / prepareDynamicModel agar mereka dapat menampilkan id model
upstream sebelum catalog statis OpenClaw.Penyedia endpoint OAuth dan penggunaan
Penyedia endpoint OAuth dan penggunaan
GitHub Copilot, Gemini CLI, ChatGPT Codex, MiniMax, Xiaomi, z.ai memasangkan
prepareRuntimeAuth atau formatApiKey dengan resolveUsageAuth +
fetchUsageSnapshot untuk memiliki pertukaran token dan integrasi /usage.Keluarga pembersihan replay dan transkrip
Keluarga pembersihan replay dan transkrip
Keluarga bernama bersama (
google-gemini, passthrough-gemini,
anthropic-by-model, hybrid-anthropic-openai) memungkinkan penyedia ikut serta dalam
kebijakan transkrip melalui buildReplayPolicy, alih-alih setiap Plugin
mengimplementasikan ulang pembersihan.Penyedia khusus catalog
Penyedia khusus catalog
byteplus, cloudflare-ai-gateway, huggingface, kimi-coding, nvidia,
qianfan, synthetic, together, venice, vercel-ai-gateway, dan
volcengine hanya mendaftarkan catalog dan menggunakan loop inferensi bersama.Helper stream khusus Anthropic
Helper stream khusus Anthropic
Header beta,
/fast / serviceTier, dan context1m berada di dalam
seam publik Plugin Anthropic api.ts / contract-api.ts
(wrapAnthropicProviderStream, resolveAnthropicBetas,
resolveAnthropicFastMode, resolveAnthropicServiceTier), bukan di dalam
SDK generik.Helper runtime
Plugin dapat mengakses helper inti tertentu melaluiapi.runtime. Untuk TTS:
textToSpeechmengembalikan payload output TTS inti normal untuk permukaan file/catatan suara.- Menggunakan konfigurasi
messages.ttsinti dan pemilihan penyedia. - Mengembalikan buffer audio PCM + laju sampel. Plugin harus melakukan resample/encode untuk penyedia.
listVoicesbersifat opsional per penyedia. Gunakan untuk pemilih suara milik vendor atau alur penyiapan.- Daftar suara dapat menyertakan metadata yang lebih kaya seperti locale, gender, dan tag kepribadian untuk pemilih sadar penyedia.
- OpenAI dan ElevenLabs mendukung telephony saat ini. Microsoft tidak.
api.registerSpeechProvider(...).
- Pertahankan kebijakan TTS, fallback, dan pengiriman balasan di inti.
- Gunakan penyedia speech untuk perilaku sintesis milik vendor.
- Input Microsoft lama
edgedinormalisasi ke id penyediamicrosoft. - Model kepemilikan yang disukai berorientasi perusahaan: satu Plugin vendor dapat memiliki penyedia teks, speech, gambar, dan media masa depan saat OpenClaw menambahkan kontrak kapabilitas tersebut.
- Pertahankan orkestrasi, fallback, config, dan wiring channel di inti.
- Pertahankan perilaku vendor di Plugin penyedia.
- Ekspansi aditif harus tetap bertipe: metode opsional baru, field hasil opsional baru, kapabilitas opsional baru.
- Pembuatan video sudah mengikuti pola yang sama:
- inti memiliki kontrak kapabilitas dan helper runtime
- Plugin vendor mendaftarkan
api.registerVideoGenerationProvider(...) - Plugin fitur/channel mengonsumsi
api.runtime.videoGeneration.*
api.runtime.mediaUnderstanding.*adalah permukaan bersama yang disukai untuk pemahaman gambar/audio/video.extractStructuredWithModel(...)adalah seam yang menghadap Plugin untuk ekstraksi milik penyedia yang terbatas dan mengutamakan gambar. Sertakan setidaknya satu input gambar; input teks adalah konteks tambahan. Plugin produk memiliki route dan skemanya, sementara OpenClaw memiliki batas penyedia/runtime.- Menggunakan konfigurasi audio pemahaman-media inti (
tools.media.audio) dan urutan fallback penyedia. - Mengembalikan
{ text: undefined }ketika tidak ada output transkripsi yang dihasilkan (misalnya input dilewati/tidak didukung). api.runtime.stt.transcribeAudioFile(...)tetap sebagai alias kompatibilitas.
api.runtime.subagent:
providerdanmodeladalah override per-run opsional, bukan perubahan sesi persisten.- OpenClaw hanya menghormati field override tersebut untuk pemanggil tepercaya.
- Untuk run fallback milik Plugin, operator harus ikut serta dengan
plugins.entries.<id>.subagent.allowModelOverride: true. - Gunakan
plugins.entries.<id>.subagent.allowedModelsuntuk membatasi Plugin tepercaya ke target kanonisprovider/modeltertentu, atau"*"untuk mengizinkan target apa pun secara eksplisit. - Run subagent Plugin yang tidak tepercaya tetap berfungsi, tetapi permintaan override ditolak alih-alih diam-diam melakukan fallback.
- Sesi subagent yang dibuat Plugin ditandai dengan id Plugin pembuat. Fallback
api.runtime.subagent.deleteSession(...)hanya dapat menghapus sesi yang dimiliki tersebut; penghapusan sesi arbitrer tetap membutuhkan permintaan Gateway berscope admin.
api.registerWebSearchProvider(...).
Catatan:
- Pertahankan pemilihan penyedia, resolusi kredensial, dan semantik permintaan bersama di inti.
- Gunakan penyedia pencarian web untuk transport pencarian khusus vendor.
api.runtime.webSearch.*adalah permukaan bersama yang disukai untuk Plugin fitur/channel yang membutuhkan perilaku pencarian tanpa bergantung pada wrapper tool agent.
api.runtime.imageGeneration
generate(...): hasilkan gambar menggunakan rantai penyedia pembuatan-gambar yang dikonfigurasi.listProviders(...): cantumkan penyedia pembuatan-gambar yang tersedia dan kapabilitasnya.
Route HTTP Gateway
Plugin dapat mengekspos endpoint HTTP denganapi.registerHttpRoute(...).
path: path rute di bawah server HTTP gateway.auth: wajib. Gunakan"gateway"untuk mewajibkan autentikasi gateway normal, atau"plugin"untuk autentikasi/verifikasi webhook yang dikelola plugin.match: opsional."exact"(bawaan) atau"prefix".replaceExisting: opsional. Memungkinkan plugin yang sama mengganti pendaftaran rute miliknya yang sudah ada.handler: kembalikantrueketika rute menangani permintaan.
api.registerHttpHandler(...)telah dihapus dan akan menyebabkan kesalahan pemuatan plugin. Gunakanapi.registerHttpRoute(...)sebagai gantinya.- Rute plugin harus mendeklarasikan
authsecara eksplisit. - Konflik
path + matchyang persis ditolak kecualireplaceExisting: true, dan satu plugin tidak dapat mengganti rute plugin lain. - Rute yang bertumpang tindih dengan tingkat
authberbeda ditolak. Pertahankan rantai fallthroughexact/prefixhanya pada tingkat auth yang sama. - Rute
auth: "plugin"tidak menerima cakupan runtime operator secara otomatis. Rute ini untuk webhook/verifikasi tanda tangan yang dikelola plugin, bukan panggilan pembantu Gateway yang memiliki hak istimewa. - Rute
auth: "gateway"berjalan di dalam cakupan runtime permintaan Gateway, tetapi cakupan tersebut sengaja konservatif:- autentikasi bearer rahasia bersama (
gateway.auth.mode = "token"/"password") menjaga cakupan runtime rute plugin tetap tersemat keoperator.write, meskipun pemanggil mengirimx-openclaw-scopes - mode HTTP tepercaya yang membawa identitas (misalnya
trusted-proxyataugateway.auth.mode = "none"pada ingress privat) menghormatix-openclaw-scopeshanya ketika header tersebut hadir secara eksplisit - jika
x-openclaw-scopestidak ada pada permintaan rute plugin yang membawa identitas tersebut, cakupan runtime kembali keoperator.write
- autentikasi bearer rahasia bersama (
- Aturan praktis: jangan menganggap rute plugin dengan auth gateway sebagai permukaan admin implisit. Jika rute Anda membutuhkan perilaku khusus admin, wajibkan mode auth yang membawa identitas dan dokumentasikan kontrak header eksplisit
x-openclaw-scopes.
Path impor Plugin SDK
Gunakan subpath SDK yang sempit alih-alih barrel root monolitikopenclaw/plugin-sdk
saat menulis plugin baru. Subpath inti:
| Subpath | Tujuan |
|---|---|
openclaw/plugin-sdk/plugin-entry | Primitif pendaftaran plugin |
openclaw/plugin-sdk/channel-core | Pembantu entri/build channel |
openclaw/plugin-sdk/core | Pembantu bersama generik dan kontrak payung |
openclaw/plugin-sdk/config-schema | Skema Zod root openclaw.json (OpenClawSchema) |
channel-setup,
setup-runtime, setup-tools, channel-pairing,
channel-contract, channel-feedback, channel-inbound, channel-outbound,
command-auth, secret-input, webhook-ingress,
channel-targets, dan channel-actions. Perilaku persetujuan sebaiknya dikonsolidasikan
pada satu kontrak approvalCapability, bukan dicampur di berbagai field
plugin yang tidak terkait. Lihat Plugin channel.
Pembantu runtime dan config berada di bawah subpath *-runtime terfokus yang cocok
(approval-runtime, agent-runtime, lazy-runtime, directory-runtime,
text-runtime, runtime-store, system-event-runtime, heartbeat-runtime,
channel-activity-runtime, dll.). Utamakan config-contracts,
plugin-config-runtime, runtime-config-snapshot, dan config-mutation
alih-alih barrel kompatibilitas config-runtime yang luas.
openclaw/plugin-sdk/channel-runtime, openclaw/plugin-sdk/channel-lifecycle,
facade pembantu channel kecil, openclaw/plugin-sdk/outbound-runtime,
openclaw/plugin-sdk/outbound-send-deps, openclaw/plugin-sdk/config-runtime,
dan openclaw/plugin-sdk/infra-runtime adalah shim kompatibilitas yang tidak digunakan lagi untuk
plugin lama. Kode baru sebaiknya mengimpor primitif generik yang lebih sempit sebagai gantinya.index.js— entri plugin yang dibundelapi.js— barrel pembantu/tiperuntime-api.js— barrel khusus runtimesetup-entry.js— entri plugin setup
openclaw/plugin-sdk/*. Jangan pernah
mengimpor src/* milik paket plugin lain dari core atau dari plugin lain.
Titik masuk yang dimuat facade mengutamakan snapshot config runtime aktif ketika
ada, lalu fallback ke file config yang telah di-resolve di disk.
Subpath khusus kapabilitas seperti image-generation, media-understanding,
dan speech ada karena plugin yang dibundel menggunakannya saat ini. Subpath tersebut tidak
otomatis menjadi kontrak eksternal jangka panjang yang dibekukan — periksa halaman
referensi SDK yang relevan saat mengandalkannya.
Skema alat pesan
Plugin sebaiknya memiliki kontribusi skemadescribeMessageTool(...) khusus channel
untuk primitif non-pesan seperti reaksi, tanda baca, dan jajak pendapat.
Presentasi kirim bersama sebaiknya menggunakan kontrak MessagePresentation generik
alih-alih field tombol, komponen, blok, atau kartu native penyedia.
Lihat Presentasi Pesan untuk kontrak,
aturan fallback, pemetaan penyedia, dan checklist penulis plugin.
Plugin yang mampu mengirim mendeklarasikan apa yang dapat mereka render melalui kapabilitas pesan:
presentationuntuk blok presentasi semantik (text,context,divider,buttons,select)delivery-pinuntuk permintaan pengiriman yang disematkan
Resolusi target channel
Plugin channel sebaiknya memiliki semantik target khusus channel. Jaga host outbound bersama tetap generik dan gunakan permukaan adapter messaging untuk aturan penyedia:messaging.inferTargetChatType({ to })memutuskan apakah target yang dinormalisasi harus diperlakukan sebagaidirect,group, atauchannelsebelum lookup direktori.messaging.targetResolver.looksLikeId(raw, normalized)memberi tahu core apakah input harus langsung melewati ke resolusi mirip id alih-alih pencarian direktori.messaging.targetResolver.reservedLiteralsmencantumkan kata polos yang merupakan referensi channel/sesi untuk penyedia tersebut. Resolusi mempertahankan entri direktori yang dikonfigurasi sebelum menolak literal cadangan, lalu gagal tertutup pada lookup direktori yang luput.messaging.targetResolver.resolveTarget(...)adalah fallback plugin ketika core membutuhkan resolusi akhir milik penyedia setelah normalisasi atau setelah lookup direktori yang luput.messaging.resolveOutboundSessionRoute(...)memiliki konstruksi rute sesi khusus penyedia setelah target di-resolve.
- Gunakan
inferTargetChatTypeuntuk keputusan kategori yang sebaiknya terjadi sebelum mencari peer/grup. - Gunakan
looksLikeIduntuk pemeriksaan “perlakukan ini sebagai id target eksplisit/native”. - Gunakan
resolveTargetuntuk fallback normalisasi khusus penyedia, bukan untuk pencarian direktori yang luas. - Simpan id native penyedia seperti id chat, id thread, JID, handle, dan id room
di dalam nilai
targetatau params khusus penyedia, bukan di field SDK generik.
Direktori berbasis config
Plugin yang menurunkan entri direktori dari config sebaiknya menjaga logika tersebut di dalam plugin dan menggunakan kembali pembantu bersama dariopenclaw/plugin-sdk/directory-runtime.
Gunakan ini ketika channel membutuhkan peer/grup berbasis config seperti:
- peer DM yang digerakkan allowlist
- peta channel/grup yang dikonfigurasi
- fallback direktori statis bercakupan akun
directory-runtime hanya menangani operasi generik:
- pemfilteran kueri
- penerapan batas
- helper deduplikasi/normalisasi
- pembuatan
ChannelDirectoryEntry[]
Katalog penyedia
Plugin penyedia dapat menentukan katalog model untuk inferensi denganregisterProvider({ catalog: { run(...) { ... } } }).
catalog.run(...) mengembalikan bentuk yang sama dengan yang ditulis OpenClaw ke
models.providers:
{ provider }untuk satu entri penyedia{ providers }untuk beberapa entri penyedia
catalog saat Plugin memiliki id model spesifik penyedia, default URL
dasar, atau metadata model yang dibatasi autentikasi.
catalog.order mengontrol kapan katalog Plugin digabungkan relatif terhadap
penyedia implisit bawaan OpenClaw:
simple: penyedia API-key biasa atau berbasis envprofile: penyedia yang muncul saat profil autentikasi adapaired: penyedia yang menyintesis beberapa entri penyedia terkaitlate: lintasan terakhir, setelah penyedia implisit lainnya
api.registerModelCatalogProvider({ provider, kinds, staticCatalog, liveCatalog }). Ini adalah jalur ke depan untuk permukaan daftar/bantuan/pemilih dan
mendukung baris text, image_generation, video_generation, dan
music_generation. Plugin penyedia tetap memiliki panggilan endpoint live,
pertukaran token, dan pemetaan respons vendor; core memiliki bentuk baris umum,
label sumber, dan pemformatan bantuan alat media. Registrasi penyedia pembuatan
media menyintesis baris katalog statis secara otomatis dari defaultModel,
models, dan capabilities.
Kompatibilitas:
discoverymasih berfungsi sebagai alias lama, tetapi mengeluarkan peringatan penghentian- jika
catalogdandiscoverysama-sama terdaftar, OpenClaw menggunakancatalog augmentModelCatalogtidak lagi disarankan; penyedia bawaan sebaiknya menerbitkan baris tambahan melaluiregisterModelCatalogProvider
Inspeksi channel baca-saja
Jika Plugin Anda mendaftarkan channel, sebaiknya implementasikanplugin.config.inspectAccount(cfg, accountId) bersama resolveAccount(...).
Mengapa:
resolveAccount(...)adalah jalur runtime. Jalur ini boleh mengasumsikan kredensial sudah sepenuhnya tersedia dan dapat gagal cepat saat rahasia wajib tidak ada.- Jalur perintah baca-saja seperti
openclaw status,openclaw status --all,openclaw channels status,openclaw channels resolve, dan alur doctor/perbaikan konfigurasi tidak seharusnya perlu menyiapkan kredensial runtime hanya untuk mendeskripsikan konfigurasi.
inspectAccount(...) yang disarankan:
- Hanya kembalikan status akun deskriptif.
- Pertahankan
enableddanconfigured. - Sertakan kolom 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 kolom sumber yang sesuai) sudah cukup untuk perintah bergaya status. - Gunakan
configured_unavailablesaat kredensial dikonfigurasi melalui SecretRef tetapi tidak tersedia di jalur perintah saat ini.
Paket package
Direktori Plugin dapat menyertakanpackage.json dengan openclaw.extensions:
name/<fileBase>.
Jika Plugin Anda mengimpor dependensi npm, instal dependensi tersebut di
direktori itu agar node_modules tersedia (npm install / pnpm install).
Batasan keamanan: setiap entri openclaw.extensions harus tetap berada di dalam
direktori Plugin setelah resolusi symlink. Entri yang keluar dari direktori
package akan ditolak.
Catatan keamanan: openclaw plugins install menginstal dependensi Plugin dengan
npm install --omit=dev --ignore-scripts lokal proyek (tanpa skrip siklus hidup,
tanpa dependensi dev saat runtime), mengabaikan pengaturan npm install global yang diwarisi.
Jaga pohon dependensi Plugin tetap “JS/TS murni” dan hindari paket yang memerlukan
build postinstall.
Opsional: openclaw.setupEntry dapat menunjuk ke modul ringan khusus penyiapan.
Ketika OpenClaw memerlukan permukaan penyiapan untuk Plugin kanal yang dinonaktifkan, atau
ketika Plugin kanal diaktifkan tetapi masih belum dikonfigurasi, OpenClaw memuat setupEntry
alih-alih entri Plugin penuh. Ini membuat startup dan penyiapan lebih ringan
ketika entri Plugin utama Anda juga merangkai alat, hook, atau kode lain yang
hanya digunakan saat runtime.
Opsional: openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen
dapat mengikutsertakan Plugin kanal ke jalur setupEntry yang sama selama fase
startup pra-dengar Gateway, bahkan ketika kanal sudah dikonfigurasi.
Gunakan ini hanya ketika setupEntry sepenuhnya mencakup permukaan startup yang harus ada
sebelum Gateway mulai mendengarkan. Dalam praktiknya, ini berarti entri penyiapan
harus mendaftarkan setiap kapabilitas milik kanal yang bergantung pada startup, seperti:
- pendaftaran kanal itu sendiri
- rute HTTP apa pun yang harus tersedia sebelum Gateway mulai mendengarkan
- metode, alat, atau layanan Gateway apa pun yang harus ada selama jendela yang sama
singleAccountKeysToMovenamedAccountPromotionKeysresolveSingleAccountPromotionTarget(...)
channels.<id>.accounts.* tanpa memuat entri Plugin penuh.
Matrix adalah contoh bundel saat ini: Matrix hanya memindahkan kunci auth/bootstrap ke
akun bernama yang dipromosikan ketika akun bernama sudah ada, dan dapat mempertahankan
kunci akun default non-kanonis yang dikonfigurasi alih-alih selalu membuat
accounts.default.
Adapter patch penyiapan tersebut menjaga penemuan permukaan kontrak bundel tetap malas. Waktu
impor tetap ringan; permukaan promosi dimuat hanya saat pertama kali digunakan, alih-alih
memasuki ulang startup kanal bundel saat impor modul.
Ketika permukaan startup tersebut mencakup metode RPC Gateway, pertahankan dengan
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.
Contoh:
Metadata katalog kanal
Plugin kanal dapat mengiklankan metadata penyiapan/penemuan melaluiopenclaw.channel dan
petunjuk instal melalui openclaw.install. Ini menjaga data katalog inti tetap kosong.
Contoh:
openclaw.channel yang berguna di luar contoh minimal:
detailLabel: label sekunder untuk permukaan katalog/status yang lebih kayadocsLabel: timpa teks tautan untuk tautan docspreferOver: id Plugin/kanal berprioritas lebih rendah yang harus dikalahkan entri katalog iniselectionDocsPrefix,selectionDocsOmitLabel,selectionExtras: kontrol salinan permukaan pemilihanmarkdownCapable: menandai kanal sebagai mampu markdown untuk keputusan pemformatan keluarexposure.configured: sembunyikan kanal dari permukaan daftar kanal yang dikonfigurasi ketika disetel kefalseexposure.setup: sembunyikan kanal dari pemilih penyiapan/konfigurasi interaktif ketika disetel kefalseexposure.docs: tandai kanal sebagai internal/privat untuk permukaan navigasi docsshowConfigured/showInSetup: alias lama yang masih diterima untuk kompatibilitas; utamakanexposurequickstartAllowFrom: ikutkan kanal ke alur quickstart standarallowFromforceAccountBinding: wajibkan pengikatan akun eksplisit bahkan ketika hanya ada satu akunpreferSessionLookupForAnnounceTarget: utamakan pencarian sesi saat menyelesaikan target pengumuman
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
OPENCLAW_PLUGIN_CATALOG_PATHS (atau OPENCLAW_MPM_CATALOG_PATHS) ke
satu atau beberapa file JSON (dipisahkan koma/titik koma/PATH). Setiap file harus
berisi { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }. Parser juga menerima "packages" atau "plugins" sebagai alias lama untuk kunci "entries".
Entri katalog kanal yang dihasilkan dan entri katalog instal penyedia mengekspos
fakta sumber instal yang dinormalisasi di samping blok mentah openclaw.install. Fakta
yang dinormalisasi mengidentifikasi apakah spesifikasi npm adalah versi persis atau selektor
mengambang, apakah metadata integritas yang diharapkan tersedia, dan apakah jalur sumber
lokal juga tersedia. Ketika identitas katalog/paket diketahui, fakta yang
dinormalisasi memperingatkan jika nama paket npm yang diurai menyimpang dari identitas tersebut.
Fakta tersebut juga memperingatkan ketika defaultChoice tidak valid atau menunjuk ke sumber yang
tidak tersedia, dan ketika metadata integritas npm tersedia tanpa sumber npm yang valid.
Konsumen harus memperlakukan installSource sebagai field opsional aditif sehingga
entri buatan tangan dan shim katalog tidak harus menyintesisnya.
Ini memungkinkan onboarding dan diagnostik menjelaskan status bidang sumber tanpa
mengimpor runtime Plugin.
Entri npm eksternal resmi sebaiknya mengutamakan npmSpec persis plus
expectedIntegrity. Nama paket polos dan dist-tag masih berfungsi untuk
kompatibilitas, tetapi memunculkan peringatan bidang sumber sehingga katalog dapat bergerak
menuju instal yang dipin dan diperiksa integritasnya tanpa merusak Plugin yang ada.
Ketika onboarding menginstal dari jalur katalog lokal, onboarding mencatat entri indeks
Plugin terkelola dengan source: "path" dan sourcePath relatif workspace
bila memungkinkan. Jalur pemuatan operasional absolut tetap berada di
plugins.load.paths; catatan instal menghindari duplikasi jalur workstation lokal
ke dalam konfigurasi berumur panjang. Ini membuat instal pengembangan lokal tetap terlihat oleh
diagnostik bidang sumber tanpa menambahkan permukaan pengungkapan jalur sistem file mentah kedua.
Baris SQLite installed_plugin_index yang dipersisten adalah sumber kebenaran instal
dan dapat disegarkan tanpa memuat modul runtime Plugin.
Map installRecords miliknya tahan lama bahkan ketika manifes Plugin hilang atau
tidak valid; payload plugins miliknya adalah tampilan manifes yang dapat dibangun ulang.
Plugin mesin konteks
Plugin mesin konteks memiliki orkestrasi konteks sesi untuk ingest, perakitan, dan Compaction. Daftarkan dari Plugin Anda denganapi.registerContextEngine(id, factory), lalu pilih mesin aktif dengan
plugins.slots.contextEngine.
Gunakan ini ketika Plugin Anda perlu mengganti atau memperluas pipeline konteks
default, bukan sekadar menambahkan pencarian memori atau hook.
ctx mengekspos nilai opsional config, agentDir, dan workspaceDir
untuk inisialisasi waktu konstruksi.
assemble() dapat mengembalikan contextProjection ketika harness aktif memiliki
thread backend persisten. Hilangkan untuk proyeksi per giliran lama. Kembalikan
{ mode: "thread_bootstrap", epoch } ketika konteks yang dirakit harus
disuntikkan sekali ke thread backend dan digunakan ulang sampai epoch berubah. Ubah
epoch setelah konteks semantik mesin berubah, seperti setelah pass Compaction
milik mesin. Host dapat mempertahankan metadata panggilan alat, bentuk input,
dan hasil alat yang telah direda dalam proyeksi thread-bootstrap agar thread
backend baru mempertahankan kontinuitas alat tanpa menyalin payload mentah yang
mengandung rahasia.
Jika mesin Anda tidak memiliki algoritma Compaction, tetap implementasikan compact()
dan delegasikan secara eksplisit:
Menambahkan kapabilitas baru
Ketika Plugin memerlukan perilaku yang tidak cocok dengan API saat ini, jangan melewati sistem Plugin dengan akses privat ke dalam. Tambahkan kapabilitas yang hilang. Urutan yang direkomendasikan:- definisikan kontrak inti Tentukan perilaku bersama apa yang harus dimiliki inti: kebijakan, fallback, penggabungan konfigurasi, siklus hidup, semantik yang berhadapan dengan kanal, dan bentuk helper runtime.
- tambahkan permukaan pendaftaran/runtime Plugin bertipe
Perluas
OpenClawPluginApidan/atauapi.runtimedengan permukaan kapabilitas bertipe paling kecil yang berguna. - rangkai konsumen inti + kanal/fitur Kanal dan Plugin fitur harus mengonsumsi kapabilitas baru melalui inti, bukan dengan mengimpor implementasi vendor secara langsung.
- daftarkan implementasi vendor Plugin vendor kemudian mendaftarkan backend mereka terhadap kapabilitas tersebut.
- tambahkan cakupan kontrak Tambahkan tes agar kepemilikan dan bentuk pendaftaran tetap eksplisit seiring waktu.
Checklist kapabilitas
Ketika Anda menambahkan kapabilitas baru, implementasinya biasanya harus menyentuh permukaan berikut secara bersamaan:- tipe kontrak inti di
src/<capability>/types.ts - helper runner/runtime inti di
src/<capability>/runtime.ts - permukaan pendaftaran API Plugin di
src/plugins/types.ts - perangkaian registry Plugin di
src/plugins/registry.ts - eksposur runtime Plugin di
src/plugins/runtime/*ketika Plugin fitur/kanal perlu mengonsumsinya - helper capture/test di
src/test-utils/plugin-registration.ts - asersi kepemilikan/kontrak di
src/plugins/contracts/registry.ts - docs operator/Plugin di
docs/
Templat kapabilitas
Pola minimal:- core memiliki kontrak kapabilitas + orkestrasi
- Plugin vendor memiliki implementasi vendor
- Plugin fitur/channel menggunakan helper runtime
- pengujian kontrak menjaga kepemilikan tetap eksplisit
Terkait
- Arsitektur Plugin — model dan bentuk kapabilitas publik
- Subpath SDK Plugin
- Penyiapan SDK Plugin
- Membangun Plugin