chore(i18n): refresh id translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-21 19:22:42 +00:00
parent 63afff7fc6
commit 1f7f087f5e
9 changed files with 970 additions and 955 deletions

View File

@ -1,44 +1,44 @@
---
read_when:
- Memeriksa pekerjaan latar belakang yang sedang berlangsung atau yang baru saja selesai
- Men-debug kegagalan pengiriman untuk proses agen yang berjalan terpisah
- Memahami bagaimana proses latar belakang terkait dengan sesi, Cron, dan Heartbeat
summary: Pelacakan tugas latar belakang untuk proses ACP, subagen, pekerjaan Cron terisolasi, dan operasi CLI
- Memeriksa pekerjaan latar belakang yang sedang berlangsung atau baru saja selesai
- Men-debug kegagalan pengiriman untuk run agen yang terlepas
- Memahami bagaimana run latar belakang terkait dengan sesi, Cron, dan Heartbeat
summary: Pelacakan tugas latar belakang untuk run ACP, subagen, tugas Cron terisolasi, dan operasi CLI
title: Tugas Latar Belakang
x-i18n:
generated_at: "2026-04-21T09:16:05Z"
generated_at: "2026-04-21T19:20:54Z"
model: gpt-5.4
provider: openai
source_hash: ba5511b1c421bdf505fc7d34f09e453ac44e85213fcb0f082078fa957aa91fe7
source_hash: a4cd666b3eaffde8df0b5e1533eb337e44a0824824af6f8a240f18a89f71b402
source_path: automation/tasks.md
workflow: 15
---
# Tugas Latar Belakang
> **Mencari penjadwalan?** Lihat [Automation & Tasks](/id/automation) untuk memilih mekanisme yang tepat. Halaman ini membahas **pelacakan** pekerjaan latar belakang, bukan penjadwalannya.
> **Mencari penjadwalan?** Lihat [Otomasi & Tugas](/id/automation) untuk memilih mekanisme yang tepat. Halaman ini membahas **pelacakan** pekerjaan latar belakang, bukan penjadwalannya.
Tugas latar belakang melacak pekerjaan yang berjalan **di luar sesi percakapan utama Anda**:
proses ACP, pemunculan subagen, eksekusi pekerjaan Cron terisolasi, dan operasi yang dimulai dari CLI.
run ACP, spawn subagen, eksekusi tugas Cron terisolasi, dan operasi yang dimulai dari CLI.
Tugas **tidak** menggantikan sesi, pekerjaan Cron, atau Heartbeat — tugas adalah **buku catatan aktivitas** yang mencatat pekerjaan terpisah apa yang terjadi, kapan terjadinya, dan apakah berhasil.
Tugas **tidak** menggantikan sesi, tugas Cron, atau Heartbeat — tugas adalah **ledger aktivitas** yang mencatat pekerjaan terlepas apa yang terjadi, kapan terjadi, dan apakah berhasil.
<Note>
Tidak setiap proses agen membuat tugas. Giliran Heartbeat dan chat interaktif normal tidak membuatnya. Semua eksekusi Cron, pemunculan ACP, pemunculan subagen, dan perintah agen CLI membuat tugas.
Tidak setiap run agen membuat tugas. Putaran Heartbeat dan chat interaktif normal tidak membuat tugas. Semua eksekusi Cron, spawn ACP, spawn subagen, dan perintah agen CLI membuat tugas.
</Note>
## Ringkasannya
## Ringkasan Singkat
- Tugas adalah **catatan**, bukan penjadwal — Cron dan Heartbeat menentukan _kapan_ pekerjaan berjalan, tugas melacak _apa yang terjadi_.
- ACP, subagen, semua pekerjaan Cron, dan operasi CLI membuat tugas. Giliran Heartbeat tidak.
- Setiap tugas bergerak melalui `queued → running → terminal` (succeeded, failed, timed_out, cancelled, atau lost).
- Tugas Cron tetap aktif selama runtime Cron masih memiliki pekerjaan itu; tugas CLI berbasis chat tetap aktif hanya selama konteks proses pemiliknya masih aktif.
- Penyelesaian bersifat didorong push: pekerjaan terpisah dapat memberi tahu secara langsung atau membangunkan sesi/Heartbeat peminta saat selesai, sehingga loop polling status biasanya bukan pola yang tepat.
- Proses Cron terisolasi dan penyelesaian subagen melakukan pembersihan best-effort pada tab/proses browser yang dilacak untuk sesi turunannya sebelum pencatatan pembersihan akhir.
- Pengiriman Cron terisolasi menekan balasan perantara induk yang usang saat pekerjaan subagen turunan masih dikuras, dan lebih memilih keluaran turunan final jika itu tiba sebelum pengiriman.
- Notifikasi penyelesaian dikirim langsung ke channel atau diantrikan untuk Heartbeat berikutnya.
- Tugas adalah **catatan**, bukan penjadwal — Cron dan Heartbeat menentukan _kapan_ pekerjaan dijalankan, tugas melacak _apa yang terjadi_.
- ACP, subagen, semua tugas Cron, dan operasi CLI membuat tugas. Putaran Heartbeat tidak.
- Setiap tugas bergerak melalui `queued → running → terminal` (`succeeded`, `failed`, `timed_out`, `cancelled`, atau `lost`).
- Tugas Cron tetap aktif selama runtime Cron masih memiliki tugas tersebut; tugas CLI yang didukung chat tetap aktif hanya selama konteks run pemiliknya masih aktif.
- Penyelesaian bersifat push-driven: pekerjaan terlepas dapat memberi tahu secara langsung atau membangunkan sesi/Heartbeat peminta saat selesai, jadi loop polling status biasanya bukan pola yang tepat.
- Run Cron terisolasi dan penyelesaian subagen melakukan pembersihan best-effort pada tab/proses browser yang dilacak untuk sesi turunannya sebelum pembukuan pembersihan akhir.
- Pengiriman Cron terisolasi menekan balasan induk sementara yang sudah usang saat pekerjaan subagen turunan masih dikuras, dan lebih memilih output turunan final jika itu tiba sebelum pengiriman.
- Notifikasi penyelesaian dikirim langsung ke channel atau diantrekan untuk Heartbeat berikutnya.
- `openclaw tasks list` menampilkan semua tugas; `openclaw tasks audit` menampilkan masalah.
- Catatan terminal disimpan selama 7 hari, lalu dipangkas secara otomatis.
- Catatan terminal disimpan selama 7 hari, lalu otomatis dipangkas.
## Mulai cepat
@ -50,10 +50,10 @@ openclaw tasks list
openclaw tasks list --runtime acp
openclaw tasks list --status running
# Tampilkan detail untuk tugas tertentu (berdasarkan ID, run ID, atau session key)
# Tampilkan detail untuk tugas tertentu (berdasarkan ID, ID run, atau kunci sesi)
openclaw tasks show <lookup>
# Batalkan tugas yang sedang berjalan (menghentikan child session)
# Batalkan tugas yang sedang berjalan (menghentikan sesi anak)
openclaw tasks cancel <lookup>
# Ubah kebijakan notifikasi untuk sebuah tugas
@ -76,22 +76,22 @@ openclaw tasks flow cancel <lookup>
| Sumber | Jenis runtime | Kapan catatan tugas dibuat | Kebijakan notifikasi default |
| ---------------------- | ------------- | ---------------------------------------------------- | ---------------------------- |
| Proses latar belakang ACP | `acp` | Memunculkan child session ACP | `done_only` |
| Orkestrasi subagen | `subagent` | Memunculkan subagen melalui `sessions_spawn` | `done_only` |
| Pekerjaan Cron (semua jenis) | `cron` | Setiap eksekusi Cron (sesi utama dan terisolasi) | `silent` |
| Run latar belakang ACP | `acp` | Saat men-spawn sesi ACP anak | `done_only` |
| Orkestrasi subagen | `subagent` | Saat men-spawn subagen melalui `sessions_spawn` | `done_only` |
| Tugas Cron (semua jenis) | `cron` | Setiap eksekusi Cron (sesi utama dan terisolasi) | `silent` |
| Operasi CLI | `cli` | Perintah `openclaw agent` yang berjalan melalui Gateway | `silent` |
| Pekerjaan media agen | `cli` | Proses `video_generate` berbasis sesi | `silent` |
| Tugas media agen | `cli` | Run `video_generate` yang didukung sesi | `silent` |
Tugas Cron sesi utama menggunakan kebijakan notifikasi `silent` secara default — tugas ini membuat catatan untuk pelacakan tetapi tidak menghasilkan notifikasi. Tugas Cron terisolasi juga default ke `silent` tetapi lebih terlihat karena berjalan dalam sesinya sendiri.
Tugas Cron sesi utama menggunakan kebijakan notifikasi `silent` secara default — mereka membuat catatan untuk pelacakan tetapi tidak menghasilkan notifikasi. Tugas Cron terisolasi juga default ke `silent` tetapi lebih terlihat karena berjalan dalam sesi mereka sendiri.
Proses `video_generate` berbasis sesi juga menggunakan kebijakan notifikasi `silent`. Proses ini tetap membuat catatan tugas, tetapi penyelesaian dikembalikan ke sesi agen asal sebagai wake internal agar agen dapat menulis pesan lanjutan dan melampirkan video yang sudah selesai sendiri. Jika Anda memilih `tools.media.asyncCompletion.directSend`, penyelesaian async `music_generate` dan `video_generate` akan mencoba pengiriman channel langsung terlebih dahulu sebelum kembali ke jalur wake sesi peminta.
Run `video_generate` yang didukung sesi juga menggunakan kebijakan notifikasi `silent`. Run tersebut tetap membuat catatan tugas, tetapi penyelesaiannya dikembalikan ke sesi agen asal sebagai wake internal agar agen dapat menulis pesan tindak lanjut dan melampirkan video yang selesai sendiri. Jika Anda memilih `tools.media.asyncCompletion.directSend`, penyelesaian async `music_generate` dan `video_generate` mencoba pengiriman channel langsung terlebih dahulu sebelum kembali ke jalur wake sesi peminta.
Selama tugas `video_generate` berbasis sesi masih aktif, tool ini juga berfungsi sebagai guardrail: pemanggilan `video_generate` berulang dalam sesi yang sama akan mengembalikan status tugas aktif alih-alih memulai generasi kedua yang berjalan bersamaan. Gunakan `action: "status"` ketika Anda ingin pencarian progres/status eksplisit dari sisi agen.
Saat sebuah tugas `video_generate` yang didukung sesi masih aktif, tool ini juga bertindak sebagai guardrail: panggilan `video_generate` berulang dalam sesi yang sama akan mengembalikan status tugas aktif alih-alih memulai generasi serentak kedua. Gunakan `action: "status"` jika Anda ingin pencarian kemajuan/status yang eksplisit dari sisi agen.
**Apa yang tidak membuat tugas:**
**Yang tidak membuat tugas:**
- Giliran Heartbeat — sesi utama; lihat [Heartbeat](/id/gateway/heartbeat)
- Giliran chat interaktif normal
- Putaran Heartbeat — sesi utama; lihat [Heartbeat](/id/gateway/heartbeat)
- Putaran chat interaktif normal
- Respons `/command` langsung
## Siklus hidup tugas
@ -100,7 +100,7 @@ Selama tugas `video_generate` berbasis sesi masih aktif, tool ini juga berfungsi
stateDiagram-v2
[*] --> queued
queued --> running : agen mulai
running --> succeeded : selesai ok
running --> succeeded : selesai dengan baik
running --> failed : error
running --> timed_out : batas waktu terlampaui
running --> cancelled : operator membatalkan
@ -108,48 +108,48 @@ stateDiagram-v2
running --> lost : sesi hilang > 5 menit
```
| Status | Artinya |
| ----------- | -------------------------------------------------------------------------- |
| `queued` | Dibuat, menunggu agen mulai |
| `running` | Giliran agen sedang dieksekusi secara aktif |
| `succeeded` | Selesai dengan sukses |
| `failed` | Selesai dengan error |
| `timed_out` | Melebihi batas waktu yang dikonfigurasi |
| `cancelled` | Dihentikan oleh operator melalui `openclaw tasks cancel` |
| `lost` | Runtime kehilangan status backing otoritatif setelah masa tenggang 5 menit |
| Status | Artinya |
| ----------- | ------------------------------------------------------------------------ |
| `queued` | Dibuat, menunggu agen mulai |
| `running` | Putaran agen sedang dieksekusi secara aktif |
| `succeeded` | Selesai dengan sukses |
| `failed` | Selesai dengan error |
| `timed_out` | Melebihi batas waktu yang dikonfigurasi |
| `cancelled` | Dihentikan oleh operator melalui `openclaw tasks cancel` |
| `lost` | Runtime kehilangan status pendukung otoritatif setelah masa tenggang 5 menit |
Transisi terjadi secara otomatis — ketika proses agen terkait berakhir, status tugas diperbarui agar sesuai.
Transisi terjadi secara otomatis — saat run agen terkait berakhir, status tugas diperbarui agar sesuai.
`lost` bersifat sadar runtime:
`lost` bersifat runtime-aware:
- Tugas ACP: metadata child session ACP backing menghilang.
- Tugas subagen: child session backing menghilang dari penyimpanan agen target.
- Tugas Cron: runtime Cron tidak lagi melacak pekerjaan itu sebagai aktif.
- Tugas CLI: tugas child-session terisolasi menggunakan child session; tugas CLI berbasis chat menggunakan konteks proses live sebagai gantinya, sehingga baris sesi channel/grup/langsung yang masih tersisa tidak membuatnya tetap aktif.
- Tugas ACP: metadata sesi anak ACP pendukung menghilang.
- Tugas subagen: sesi anak pendukung menghilang dari penyimpanan agen target.
- Tugas Cron: runtime Cron tidak lagi melacak tugas sebagai aktif.
- Tugas CLI: tugas sesi anak terisolasi menggunakan sesi anak; tugas CLI yang didukung chat menggunakan konteks run aktif sebagai gantinya, jadi baris sesi channel/grup/langsung yang tersisa tidak membuatnya tetap hidup.
## Pengiriman dan notifikasi
Ketika sebuah tugas mencapai status terminal, OpenClaw memberi tahu Anda. Ada dua jalur pengiriman:
Saat sebuah tugas mencapai status terminal, OpenClaw memberi tahu Anda. Ada dua jalur pengiriman:
**Pengiriman langsung** — jika tugas memiliki target channel (`requesterOrigin`), pesan penyelesaian dikirim langsung ke channel tersebut (Telegram, Discord, Slack, dll.). Untuk penyelesaian subagen, OpenClaw juga mempertahankan perutean thread/topik terikat saat tersedia dan dapat mengisi `to` / akun yang hilang dari rute tersimpan sesi peminta (`lastChannel` / `lastTo` / `lastAccountId`) sebelum menyerah pada pengiriman langsung.
**Pengiriman langsung** — jika tugas memiliki target channel (`requesterOrigin`), pesan penyelesaian langsung dikirim ke channel tersebut (Telegram, Discord, Slack, dll.). Untuk penyelesaian subagen, OpenClaw juga mempertahankan perutean thread/topik yang terikat bila tersedia dan dapat mengisi `to` / akun yang hilang dari rute tersimpan sesi peminta (`lastChannel` / `lastTo` / `lastAccountId`) sebelum menyerah pada pengiriman langsung.
**Pengiriman melalui antrean sesi** — jika pengiriman langsung gagal atau tidak ada origin yang ditetapkan, pembaruan diantrikan sebagai peristiwa sistem di sesi peminta dan muncul pada Heartbeat berikutnya.
**Pengiriman yang diantrekan ke sesi** — jika pengiriman langsung gagal atau tidak ada origin yang ditetapkan, pembaruan diantrekan sebagai peristiwa sistem dalam sesi peminta dan muncul pada Heartbeat berikutnya.
<Tip>
Penyelesaian tugas memicu wake Heartbeat segera agar Anda cepat melihat hasilnya — Anda tidak perlu menunggu tick Heartbeat terjadwal berikutnya.
</Tip>
Artinya, alur kerja yang umum bersifat berbasis push: mulai pekerjaan terpisah sekali, lalu biarkan runtime membangunkan atau memberi tahu Anda saat selesai. Poll status tugas hanya ketika Anda memerlukan debugging, intervensi, atau audit eksplisit.
Artinya, alur kerja yang umum bersifat berbasis push: mulai pekerjaan terlepas sekali, lalu biarkan runtime membangunkan atau memberi tahu Anda saat selesai. Poll status tugas hanya saat Anda memerlukan debugging, intervensi, atau audit eksplisit.
### Kebijakan notifikasi
Kendalikan seberapa banyak Anda menerima kabar tentang setiap tugas:
Kendalikan seberapa banyak yang Anda dengar tentang setiap tugas:
| Kebijakan | Yang dikirimkan |
| --------------------- | ------------------------------------------------------------------------ |
| `done_only` (default) | Hanya status terminal (succeeded, failed, dll.) — **ini default-nya** |
| `state_changes` | Setiap transisi status dan pembaruan progres |
| `silent` | Tidak ada sama sekali |
| Kebijakan | Apa yang dikirimkan |
| -------------------- | ------------------------------------------------------------------------ |
| `done_only` (default) | Hanya status terminal (`succeeded`, `failed`, dll.) — **ini adalah default** |
| `state_changes` | Setiap transisi status dan pembaruan kemajuan |
| `silent` | Tidak ada sama sekali |
Ubah kebijakan saat tugas sedang berjalan:
@ -165,7 +165,7 @@ openclaw tasks notify <lookup> state_changes
openclaw tasks list [--runtime <acp|subagent|cron|cli>] [--status <status>] [--json]
```
Kolom keluaran: Task ID, Kind, Status, Delivery, Run ID, Child Session, Summary.
Kolom output: ID Tugas, Jenis, Status, Pengiriman, ID Run, Sesi Anak, Ringkasan.
### `tasks show`
@ -173,7 +173,7 @@ Kolom keluaran: Task ID, Kind, Status, Delivery, Run ID, Child Session, Summary.
openclaw tasks show <lookup>
```
Token lookup menerima task ID, run ID, atau session key. Menampilkan catatan lengkap termasuk waktu, status pengiriman, error, dan ringkasan terminal.
Token lookup menerima ID tugas, ID run, atau kunci sesi. Menampilkan catatan lengkap termasuk waktu, status pengiriman, error, dan ringkasan terminal.
### `tasks cancel`
@ -181,7 +181,7 @@ Token lookup menerima task ID, run ID, atau session key. Menampilkan catatan len
openclaw tasks cancel <lookup>
```
Untuk tugas ACP dan subagen, ini menghentikan child session. Untuk tugas yang dilacak CLI, pembatalan dicatat di registri tugas (tidak ada handle runtime anak terpisah). Status bertransisi ke `cancelled` dan notifikasi pengiriman dikirim jika berlaku.
Untuk tugas ACP dan subagen, ini menghentikan sesi anak. Untuk tugas yang dilacak CLI, pembatalan dicatat dalam registry tugas (tidak ada handle runtime anak yang terpisah). Status bertransisi ke `cancelled` dan notifikasi pengiriman dikirim jika berlaku.
### `tasks notify`
@ -195,16 +195,16 @@ openclaw tasks notify <lookup> <done_only|state_changes|silent>
openclaw tasks audit [--json]
```
Menampilkan masalah operasional. Temuan juga muncul di `openclaw status` ketika masalah terdeteksi.
Menampilkan masalah operasional. Temuan juga muncul di `openclaw status` saat masalah terdeteksi.
| Temuan | Tingkat keparahan | Pemicu |
| ------------------------- | ----------------- | ----------------------------------------------------- |
| `stale_queued` | warn | Berada di antrean lebih dari 10 menit |
| `stale_running` | error | Berjalan lebih dari 30 menit |
| `lost` | error | Kepemilikan tugas berbasis runtime menghilang |
| Temuan | Tingkat keparahan | Pemicu |
| ------------------------- | ----------------- | ------------------------------------------------------ |
| `stale_queued` | warn | Dalam antrean lebih dari 10 menit |
| `stale_running` | error | Berjalan lebih dari 30 menit |
| `lost` | error | Kepemilikan tugas yang didukung runtime menghilang |
| `delivery_failed` | warn | Pengiriman gagal dan kebijakan notifikasi bukan `silent` |
| `missing_cleanup` | warn | Tugas terminal tanpa cap waktu pembersihan |
| `inconsistent_timestamps` | warn | Pelanggaran linimasa (misalnya berakhir sebelum dimulai) |
| `missing_cleanup` | warn | Tugas terminal tanpa stempel waktu pembersihan |
| `inconsistent_timestamps` | warn | Pelanggaran linimasa (misalnya selesai sebelum dimulai) |
### `tasks maintenance`
@ -213,20 +213,20 @@ openclaw tasks maintenance [--json]
openclaw tasks maintenance --apply [--json]
```
Gunakan ini untuk mempratinjau atau menerapkan rekonsiliasi, pencap-waktu pembersihan, dan pemangkasan untuk status tugas dan Task Flow.
Gunakan ini untuk mempratinjau atau menerapkan rekonsiliasi, penandaan pembersihan, dan pemangkasan untuk tugas dan status TaskFlow.
Rekonsiliasi bersifat sadar runtime:
Rekonsiliasi bersifat runtime-aware:
- Tugas ACP/subagen memeriksa child session backing mereka.
- Tugas Cron memeriksa apakah runtime Cron masih memiliki pekerjaan tersebut.
- Tugas CLI berbasis chat memeriksa konteks proses live pemiliknya, bukan hanya baris sesi chat.
- Tugas ACP/subagen memeriksa sesi anak pendukungnya.
- Tugas Cron memeriksa apakah runtime Cron masih memiliki tugas tersebut.
- Tugas CLI yang didukung chat memeriksa konteks run aktif pemiliknya, bukan hanya baris sesi chat.
Pembersihan penyelesaian juga bersifat sadar runtime:
Pembersihan penyelesaian juga bersifat runtime-aware:
- Penyelesaian subagen melakukan best-effort menutup tab/proses browser yang dilacak untuk child session sebelum pembersihan pengumuman berlanjut.
- Penyelesaian Cron terisolasi melakukan best-effort menutup tab/proses browser yang dilacak untuk sesi Cron sebelum proses dibongkar sepenuhnya.
- Pengiriman Cron terisolasi menunggu tindak lanjut subagen turunan bila diperlukan dan menekan teks pengakuan induk yang usang alih-alih mengumumkannya.
- Pengiriman penyelesaian subagen lebih memilih teks asisten terlihat terbaru; jika itu kosong maka kembali ke teks tool/toolResult terbaru yang sudah disanitasi, dan proses tool-call yang hanya timeout dapat diringkas menjadi ringkasan progres parsial singkat.
- Penyelesaian subagen melakukan penutupan best-effort pada tab/proses browser yang dilacak untuk sesi anak sebelum pembersihan pengumuman berlanjut.
- Penyelesaian Cron terisolasi melakukan penutupan best-effort pada tab/proses browser yang dilacak untuk sesi Cron sebelum run sepenuhnya dibongkar.
- Pengiriman Cron terisolasi menunggu tindak lanjut subagen turunan bila diperlukan dan menekan teks pengakuan induk yang sudah usang alih-alih mengumumkannya.
- Pengiriman penyelesaian subagen lebih memilih teks asisten terlihat terbaru; jika kosong, pengiriman kembali ke teks tool/toolResult terbaru yang sudah disanitasi, dan run pemanggilan tool yang hanya timeout dapat diringkas menjadi ringkasan kemajuan parsial singkat. Run gagal terminal mengumumkan status kegagalan tanpa memutar ulang teks balasan yang ditangkap.
- Kegagalan pembersihan tidak menutupi hasil tugas yang sebenarnya.
### `tasks flow list|show|cancel`
@ -237,17 +237,16 @@ openclaw tasks flow show <lookup> [--json]
openclaw tasks flow cancel <lookup>
```
Gunakan ini ketika TaskFlow pengorkestrasi adalah hal yang Anda pedulikan, bukan satu catatan tugas latar belakang individual.
Gunakan ini saat TaskFlow pengorkestrasi adalah hal yang Anda pedulikan, bukan satu catatan tugas latar belakang individual.
## Papan tugas chat (`/tasks`)
Gunakan `/tasks` di sesi chat mana pun untuk melihat tugas latar belakang yang terkait dengan sesi itu. Papan menampilkan
tugas yang aktif dan yang baru selesai dengan runtime, status, waktu, serta detail progres atau error.
Gunakan `/tasks` dalam sesi chat mana pun untuk melihat tugas latar belakang yang terhubung ke sesi itu. Papan menampilkan tugas aktif dan yang baru selesai dengan runtime, status, waktu, serta detail kemajuan atau error.
Ketika sesi saat ini tidak memiliki tugas tertaut yang terlihat, `/tasks` kembali ke jumlah tugas lokal agen
Saat sesi saat ini tidak memiliki tugas tertaut yang terlihat, `/tasks` akan kembali ke hitungan tugas lokal agen
agar Anda tetap mendapatkan gambaran umum tanpa membocorkan detail sesi lain.
Untuk buku catatan operator lengkap, gunakan CLI: `openclaw tasks list`.
Untuk ledger operator lengkap, gunakan CLI: `openclaw tasks list`.
## Integrasi status (tekanan tugas)
@ -261,66 +260,66 @@ Ringkasan tersebut melaporkan:
- **active** — jumlah `queued` + `running`
- **failures** — jumlah `failed` + `timed_out` + `lost`
- **byRuntime** — rincian berdasarkan `acp`, `subagent`, `cron`, `cli`
- **byRuntime** — rincian menurut `acp`, `subagent`, `cron`, `cli`
Baik `/status` maupun tool `session_status` menggunakan snapshot tugas yang sadar pembersihan: tugas aktif
Baik `/status` maupun tool `session_status` menggunakan snapshot tugas yang sadar-pembersihan: tugas aktif
diprioritaskan, baris selesai yang usang disembunyikan, dan kegagalan terbaru hanya ditampilkan saat tidak ada pekerjaan aktif
yang tersisa. Ini menjaga kartu status tetap berfokus pada yang penting saat ini.
yang tersisa. Ini menjaga kartu status tetap fokus pada hal yang penting saat ini.
## Penyimpanan dan pemeliharaan
### Di mana tugas disimpan
### Tempat tugas disimpan
Catatan tugas disimpan di SQLite pada:
Catatan tugas disimpan persisten di SQLite pada:
```
$OPENCLAW_STATE_DIR/tasks/runs.sqlite
```
Registri dimuat ke memori saat Gateway dimulai dan menyinkronkan penulisan ke SQLite agar tetap tahan terhadap restart.
Registry dimuat ke memori saat Gateway dimulai dan menyinkronkan penulisan ke SQLite agar tetap tahan terhadap restart.
### Pemeliharaan otomatis
Sebuah sweeper berjalan setiap **60 detik** dan menangani tiga hal:
1. **Rekonsiliasi** — memeriksa apakah tugas aktif masih memiliki backing runtime yang otoritatif. Tugas ACP/subagen menggunakan status child session, tugas Cron menggunakan kepemilikan pekerjaan aktif, dan tugas CLI berbasis chat menggunakan konteks proses pemilik. Jika status backing itu hilang selama lebih dari 5 menit, tugas ditandai sebagai `lost`.
2. **Pencap-waktu pembersihan** — menetapkan cap waktu `cleanupAfter` pada tugas terminal (`endedAt + 7 days`).
3. **Pemangkasan** — menghapus catatan yang telah melewati tanggal `cleanupAfter`.
1. **Rekonsiliasi** — memeriksa apakah tugas aktif masih memiliki dukungan runtime otoritatif. Tugas ACP/subagen menggunakan status sesi anak, tugas Cron menggunakan kepemilikan tugas aktif, dan tugas CLI yang didukung chat menggunakan konteks run pemiliknya. Jika status pendukung itu hilang selama lebih dari 5 menit, tugas ditandai sebagai `lost`.
2. **Penandaan pembersihan** — menetapkan stempel waktu `cleanupAfter` pada tugas terminal (`endedAt + 7 hari`).
3. **Pemangkasan** — menghapus catatan yang sudah melewati tanggal `cleanupAfter` mereka.
**Retensi**: catatan tugas terminal disimpan selama **7 hari**, lalu dipangkas secara otomatis. Tidak perlu konfigurasi.
**Retensi**: catatan tugas terminal disimpan selama **7 hari**, lalu otomatis dipangkas. Tidak perlu konfigurasi.
## Hubungan tugas dengan sistem lain
## Bagaimana tugas berhubungan dengan sistem lain
### Tugas dan Task Flow
### Tugas dan TaskFlow
[Task Flow](/id/automation/taskflow) adalah lapisan orkestrasi flow di atas tugas latar belakang. Satu flow dapat mengoordinasikan beberapa tugas selama masa hidupnya dengan mode sinkronisasi terkelola atau tercermin. Gunakan `openclaw tasks` untuk memeriksa catatan tugas individual dan `openclaw tasks flow` untuk memeriksa flow pengorkestrasinya.
[TaskFlow](/id/automation/taskflow) adalah lapisan orkestrasi alur di atas tugas latar belakang. Satu flow dapat mengoordinasikan beberapa tugas selama masa hidupnya menggunakan mode sinkronisasi terkelola atau tercermin. Gunakan `openclaw tasks` untuk memeriksa catatan tugas individual dan `openclaw tasks flow` untuk memeriksa flow pengorkestrasi.
Lihat [Task Flow](/id/automation/taskflow) untuk detailnya.
Lihat [TaskFlow](/id/automation/taskflow) untuk detailnya.
### Tugas dan Cron
Sebuah **definisi** pekerjaan Cron berada di `~/.openclaw/cron/jobs.json`; status eksekusi runtime berada di sebelahnya dalam `~/.openclaw/cron/jobs-state.json`. **Setiap** eksekusi Cron membuat catatan tugas — baik sesi utama maupun terisolasi. Tugas Cron sesi utama menggunakan kebijakan notifikasi `silent` secara default agar tetap terlacak tanpa menghasilkan notifikasi.
Sebuah **definisi** tugas Cron disimpan di `~/.openclaw/cron/jobs.json`; status eksekusi runtime disimpan di sebelahnya dalam `~/.openclaw/cron/jobs-state.json`. **Setiap** eksekusi Cron membuat catatan tugas — baik sesi utama maupun terisolasi. Tugas Cron sesi utama default ke kebijakan notifikasi `silent` sehingga dapat dilacak tanpa menghasilkan notifikasi.
Lihat [Cron Jobs](/id/automation/cron-jobs).
Lihat [Tugas Cron](/id/automation/cron-jobs).
### Tugas dan Heartbeat
Proses Heartbeat adalah giliran sesi utama — proses ini tidak membuat catatan tugas. Saat sebuah tugas selesai, tugas itu dapat memicu wake Heartbeat agar Anda segera melihat hasilnya.
Run Heartbeat adalah putaran sesi utama — run tersebut tidak membuat catatan tugas. Saat sebuah tugas selesai, tugas itu dapat memicu wake Heartbeat agar Anda segera melihat hasilnya.
Lihat [Heartbeat](/id/gateway/heartbeat).
### Tugas dan sesi
Sebuah tugas dapat merujuk ke `childSessionKey` (tempat pekerjaan berjalan) dan `requesterSessionKey` (siapa yang memulainya). Sesi adalah konteks percakapan; tugas adalah pelacakan aktivitas di atasnya.
Sebuah tugas dapat merujuk `childSessionKey` (tempat pekerjaan dijalankan) dan `requesterSessionKey` (siapa yang memulainya). Sesi adalah konteks percakapan; tugas adalah pelacakan aktivitas di atas konteks tersebut.
### Tugas dan proses agen
### Tugas dan run agen
`runId` sebuah tugas terhubung ke proses agen yang mengerjakan tugas tersebut. Peristiwa siklus hidup agen (mulai, selesai, error) secara otomatis memperbarui status tugas — Anda tidak perlu mengelola siklus hidupnya secara manual.
`runId` sebuah tugas terhubung ke run agen yang melakukan pekerjaan. Peristiwa siklus hidup agen (mulai, selesai, error) secara otomatis memperbarui status tugas — Anda tidak perlu mengelola siklus hidupnya secara manual.
## Terkait
- [Automation & Tasks](/id/automation) — semua mekanisme otomatisasi secara ringkas
- [Task Flow](/id/automation/taskflow) — orkestrasi flow di atas tugas
- [Scheduled Tasks](/id/automation/cron-jobs) — penjadwalan pekerjaan latar belakang
- [Heartbeat](/id/gateway/heartbeat) — giliran sesi utama periodik
- [Otomasi & Tugas](/id/automation) — semua mekanisme otomasi dalam satu ringkasan
- [TaskFlow](/id/automation/taskflow) — orkestrasi alur di atas tugas
- [Tugas Terjadwal](/id/automation/cron-jobs) — menjadwalkan pekerjaan latar belakang
- [Heartbeat](/id/gateway/heartbeat) — putaran sesi utama berkala
- [CLI: Tasks](/cli/index#tasks) — referensi perintah CLI

View File

@ -1,30 +1,30 @@
---
read_when:
- Menyiapkan Synology Chat dengan OpenClaw
- Men-debug perutean webhook Synology Chat
summary: Penyiapan webhook Synology Chat dan konfigurasi OpenClaw
- Men-debug routing Webhook Synology Chat
summary: Penyiapan Webhook Synology Chat dan konfigurasi OpenClaw
title: Synology Chat
x-i18n:
generated_at: "2026-04-05T13:44:08Z"
generated_at: "2026-04-21T19:20:46Z"
model: gpt-5.4
provider: openai
source_hash: ddb25fc6b53f896f15f43b4936d69ea071a29a91838a5b662819377271e89d81
source_hash: 7288e2aa873ee1a1f57861d839cfb44ff324e3d40a7f36da07c6ba43cbe1e6e6
source_path: channels/synology-chat.md
workflow: 15
---
# Synology Chat
Status: channel pesan langsung plugin bawaan yang menggunakan webhook Synology Chat.
Plugin ini menerima pesan masuk dari webhook keluar Synology Chat dan mengirim balasan
melalui webhook masuk Synology Chat.
Status: plugin bawaan saluran pesan langsung yang menggunakan Webhook Synology Chat.
Plugin ini menerima pesan masuk dari outgoing webhook Synology Chat dan mengirim balasan
melalui incoming webhook Synology Chat.
## Plugin bawaan
Synology Chat tersedia sebagai plugin bawaan dalam rilis OpenClaw saat ini, jadi build
paket normal tidak memerlukan instalasi terpisah.
Synology Chat tersedia sebagai plugin bawaan di rilis OpenClaw saat ini, jadi build
terpaket normal tidak memerlukan instalasi terpisah.
Jika Anda menggunakan build lama atau instalasi kustom yang tidak menyertakan Synology Chat,
Jika Anda menggunakan build yang lebih lama atau instalasi kustom yang tidak menyertakan Synology Chat,
instal secara manual:
Instal dari checkout lokal:
@ -33,36 +33,36 @@ Instal dari checkout lokal:
openclaw plugins install ./path/to/local/synology-chat-plugin
```
Detail: [Plugins](/tools/plugin)
Detail: [Plugins](/id/tools/plugin)
## Penyiapan cepat
1. Pastikan plugin Synology Chat tersedia.
- Rilis OpenClaw paket saat ini sudah menyertakan plugin ini.
- Instalasi lama/kustom dapat menambahkannya secara manual dari checkout sumber dengan perintah di atas.
- `openclaw onboard` sekarang menampilkan Synology Chat dalam daftar penyiapan channel yang sama seperti `openclaw channels add`.
- Rilis OpenClaw terpaket saat ini sudah menyertakannya.
- Instalasi lama/kustom dapat menambahkannya secara manual dari source checkout dengan perintah di atas.
- `openclaw onboard` sekarang menampilkan Synology Chat dalam daftar penyiapan saluran yang sama seperti `openclaw channels add`.
- Penyiapan non-interaktif: `openclaw channels add --channel synology-chat --token <token> --url <incoming-webhook-url>`
2. Di integrasi Synology Chat:
- Buat webhook masuk dan salin URL-nya.
- Buat webhook keluar dengan token rahasia Anda.
3. Arahkan URL webhook keluar ke gateway OpenClaw Anda:
- Buat incoming webhook dan salin URL-nya.
- Buat outgoing webhook dengan token rahasia Anda.
3. Arahkan URL outgoing webhook ke gateway OpenClaw Anda:
- `https://gateway-host/webhook/synology` secara default.
- Atau `channels.synology-chat.webhookPath` kustom Anda.
4. Selesaikan penyiapan di OpenClaw.
- Terpandu: `openclaw onboard`
- Langsung: `openclaw channels add --channel synology-chat --token <token> --url <incoming-webhook-url>`
5. Mulai ulang gateway dan kirim DM ke bot Synology Chat.
5. Mulai ulang gateway lalu kirim DM ke bot Synology Chat.
Detail autentikasi webhook:
Detail autentikasi Webhook:
- OpenClaw menerima token webhook keluar dari `body.token`, lalu
- OpenClaw menerima token outgoing webhook dari `body.token`, lalu
`?token=...`, lalu header.
- Bentuk header yang diterima:
- Format header yang diterima:
- `x-synology-token`
- `x-webhook-token`
- `x-openclaw-token`
- `Authorization: Bearer <token>`
- Token yang kosong atau tidak ada akan gagal secara fail-closed.
- Token kosong atau tidak ada akan gagal tertutup.
Konfigurasi minimal:
@ -85,7 +85,7 @@ Konfigurasi minimal:
## Variabel lingkungan
Untuk akun default, Anda dapat menggunakan variabel lingkungan:
Untuk akun default, Anda dapat menggunakan variabel env:
- `SYNOLOGY_CHAT_TOKEN`
- `SYNOLOGY_CHAT_INCOMING_URL`
@ -94,16 +94,16 @@ Untuk akun default, Anda dapat menggunakan variabel lingkungan:
- `SYNOLOGY_RATE_LIMIT`
- `OPENCLAW_BOT_NAME`
Nilai konfigurasi menimpa variabel lingkungan.
Nilai konfigurasi menimpa variabel env.
## Kebijakan DM dan kontrol akses
- `dmPolicy: "allowlist"` adalah default yang direkomendasikan.
- `allowedUserIds` menerima daftar (atau string yang dipisahkan koma) ID pengguna Synology.
- `allowedUserIds` menerima daftar (atau string dipisahkan koma) ID pengguna Synology.
- Dalam mode `allowlist`, daftar `allowedUserIds` yang kosong dianggap sebagai salah konfigurasi dan rute webhook tidak akan dimulai (gunakan `dmPolicy: "open"` untuk mengizinkan semua).
- `dmPolicy: "open"` mengizinkan pengirim mana pun.
- `dmPolicy: "disabled"` memblokir DM.
- Binding penerima balasan tetap menggunakan `user_id` numerik yang stabil secara default. `channels.synology-chat.dangerouslyAllowNameMatching: true` adalah mode kompatibilitas darurat yang mengaktifkan kembali pencocokan username/nickname yang dapat berubah untuk pengiriman balasan.
- Pengikatan penerima balasan tetap menggunakan `user_id` numerik yang stabil secara default. `channels.synology-chat.dangerouslyAllowNameMatching: true` adalah mode kompatibilitas darurat yang mengaktifkan kembali pencarian username/nama panggilan yang dapat berubah untuk pengiriman balasan.
- Persetujuan pairing berfungsi dengan:
- `openclaw pairing list synology-chat`
- `openclaw pairing approve synology-chat <CODE>`
@ -120,18 +120,19 @@ openclaw message send --channel synology-chat --target synology-chat:123456 --te
```
Pengiriman media didukung melalui pengiriman file berbasis URL.
URL file keluar harus menggunakan `http` atau `https`, dan target jaringan privat atau yang diblokir akan ditolak sebelum OpenClaw meneruskan URL ke webhook NAS.
## Multi-akun
Beberapa akun Synology Chat didukung di bawah `channels.synology-chat.accounts`.
Setiap akun dapat menimpa token, URL masuk, path webhook, kebijakan DM, dan batasan.
Setiap akun dapat menimpa token, URL masuk, jalur webhook, kebijakan DM, dan batas.
Sesi pesan langsung diisolasi per akun dan pengguna, sehingga `user_id` numerik yang sama
pada dua akun Synology yang berbeda tidak berbagi status transkrip.
Berikan setiap akun aktif `webhookPath` yang berbeda. OpenClaw sekarang menolak path persis yang duplikat
dan menolak memulai akun bernama yang hanya mewarisi satu path webhook bersama dalam penyiapan multi-akun.
Jika Anda sengaja memerlukan pewarisan lama untuk akun bernama, atur
Berikan `webhookPath` yang berbeda untuk setiap akun yang diaktifkan. OpenClaw sekarang menolak path persis yang duplikat
dan menolak memulai akun bernama yang hanya mewarisi jalur webhook bersama dalam penyiapan multi-akun.
Jika Anda memang memerlukan pewarisan lama untuk akun bernama, setel
`dangerouslyAllowInheritedWebhookPath: true` pada akun tersebut atau di `channels.synology-chat`,
tetapi path persis yang duplikat tetap ditolak secara fail-closed. Lebih baik gunakan path eksplisit per akun.
tetapi path persis yang duplikat tetap ditolak dengan fail-closed. Gunakan path eksplisit per akun.
```json5
{
@ -159,34 +160,34 @@ tetapi path persis yang duplikat tetap ditolak secara fail-closed. Lebih baik gu
## Catatan keamanan
- Jaga kerahasiaan `token` dan rotasi jika bocor.
- Pertahankan `allowInsecureSsl: false` kecuali Anda secara eksplisit memercayai sertifikat NAS lokal self-signed.
- Permintaan webhook masuk diverifikasi token dan dibatasi lajunya per pengirim.
- Biarkan `allowInsecureSsl: false` kecuali Anda secara eksplisit memercayai sertifikat NAS lokal self-signed.
- Permintaan webhook masuk diverifikasi tokennya dan dibatasi lajunya per pengirim.
- Pemeriksaan token tidak valid menggunakan perbandingan rahasia waktu konstan dan fail-closed.
- Gunakan `dmPolicy: "allowlist"` untuk produksi.
- Biarkan `dangerouslyAllowNameMatching` nonaktif kecuali Anda benar-benar memerlukan pengiriman balasan berbasis username lama.
- Biarkan `dangerouslyAllowInheritedWebhookPath` nonaktif kecuali Anda secara eksplisit menerima risiko perutean path bersama dalam penyiapan multi-akun.
- Biarkan `dangerouslyAllowNameMatching` nonaktif kecuali Anda secara eksplisit memerlukan pengiriman balasan lama berbasis username.
- Biarkan `dangerouslyAllowInheritedWebhookPath` nonaktif kecuali Anda secara eksplisit menerima risiko routing jalur bersama dalam penyiapan multi-akun.
## Pemecahan masalah
- `Missing required fields (token, user_id, text)`:
- payload webhook keluar tidak memiliki salah satu field wajib
- payload outgoing webhook tidak memiliki salah satu field wajib
- jika Synology mengirim token di header, pastikan gateway/proxy mempertahankan header tersebut
- `Invalid token`:
- rahasia webhook keluar tidak cocok dengan `channels.synology-chat.token`
- permintaan mengenai akun/path webhook yang salah
- rahasia outgoing webhook tidak cocok dengan `channels.synology-chat.token`
- permintaan mengarah ke akun/jalur webhook yang salah
- reverse proxy menghapus header token sebelum permintaan mencapai OpenClaw
- `Rate limit exceeded`:
- terlalu banyak percobaan token tidak valid dari sumber yang sama dapat mengunci sementara sumber tersebut
- pengirim yang terautentikasi juga memiliki batas laju pesan terpisah per pengguna
- `Allowlist is empty. Configure allowedUserIds or use dmPolicy=open.`:
- `dmPolicy="allowlist"` aktif tetapi tidak ada pengguna yang dikonfigurasi
- `dmPolicy="allowlist"` diaktifkan tetapi tidak ada pengguna yang dikonfigurasi
- `User not authorized`:
- `user_id` numerik pengirim tidak ada dalam `allowedUserIds`
- `user_id` numerik pengirim tidak ada di `allowedUserIds`
## Terkait
- [Ikhtisar Channel](/channels) — semua channel yang didukung
- [Pairing](/channels/pairing) — autentikasi DM dan alur pairing
- [Grup](/channels/groups) — perilaku chat grup dan penyaringan mention
- [Perutean Channel](/channels/channel-routing) — perutean sesi untuk pesan
- [Keamanan](/gateway/security) — model akses dan hardening
- [Ikhtisar Saluran](/id/channels) — semua saluran yang didukung
- [Pairing](/id/channels/pairing) — autentikasi DM dan alur pairing
- [Grup](/id/channels/groups) — perilaku obrolan grup dan pembatasan mention
- [Routing Saluran](/id/channels/channel-routing) — routing sesi untuk pesan
- [Keamanan](/id/gateway/security) — model akses dan hardening

View File

@ -1,87 +1,87 @@
---
read_when:
- Anda perlu memahami mengapa suatu job CI dijalankan atau tidak dijalankan
- Anda perlu memahami mengapa sebuah pekerjaan CI dijalankan atau tidak dijalankan
- Anda sedang men-debug pemeriksaan GitHub Actions yang gagal
summary: Grafik job CI, gerbang cakupan, dan padanan perintah lokal
summary: Grafik pekerjaan CI, gerbang cakupan, dan padanan perintah lokal
title: Pipeline CI
x-i18n:
generated_at: "2026-04-21T09:16:51Z"
generated_at: "2026-04-21T19:20:45Z"
model: gpt-5.4
provider: openai
source_hash: 88a98d777fd61be1603417b71779aaf42a24d602b2437ad549f0075f22494cec
source_hash: 4d01a178402976cdf7c3c864695e8a12d3f7d1d069a77ea1b02a8aef2a3497f7
source_path: ci.md
workflow: 15
---
# Pipeline CI
CI berjalan pada setiap push ke `main` dan setiap pull request. CI menggunakan cakupan cerdas untuk melewati job mahal ketika hanya area yang tidak terkait yang berubah.
CI berjalan pada setiap push ke `main` dan setiap pull request. CI menggunakan cakupan cerdas untuk melewati pekerjaan mahal ketika hanya area yang tidak terkait yang berubah.
## Ringkasan job
## Gambaran Umum Pekerjaan
| Job | Tujuan | Kapan dijalankan |
| -------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `preflight` | Mendeteksi perubahan khusus docs, cakupan yang berubah, extension yang berubah, dan membangun manifes CI | Selalu pada push dan PR non-draf |
| `security-scm-fast` | Deteksi private key dan audit workflow melalui `zizmor` | Selalu pada push dan PR non-draf |
| `security-dependency-audit` | Audit lockfile produksi tanpa dependensi terhadap advisory npm | Selalu pada push dan PR non-draf |
| `security-fast` | Agregat wajib untuk job keamanan cepat | Selalu pada push dan PR non-draf |
| `build-artifacts` | Membangun `dist/` dan UI Control sekali, mengunggah artifact yang dapat digunakan ulang untuk job hilir | Perubahan yang relevan dengan Node |
| `checks-fast-core` | Lane kebenaran Linux cepat seperti pemeriksaan bundled/plugin-contract/protocol | Perubahan yang relevan dengan Node |
| `checks-fast-contracts-channels` | Pemeriksaan kontrak channel yang di-shard dengan hasil pemeriksaan agregat yang stabil | Perubahan yang relevan dengan Node |
| `checks-node-extensions` | Shard pengujian Plugin bundled penuh di seluruh rangkaian extension | Perubahan yang relevan dengan Node |
| `checks-node-core-test` | Shard pengujian Node inti, tidak termasuk lane channel, bundled, contract, dan extension | Perubahan yang relevan dengan Node |
| `extension-fast` | Pengujian terfokus hanya untuk plugin bundled yang berubah | Saat perubahan extension terdeteksi |
| `check` | Padanan gerbang lokal utama yang di-shard: tipe produksi, lint, guard, tipe test, dan smoke ketat | Perubahan yang relevan dengan Node |
| `check-additional` | Guard arsitektur, boundary, permukaan extension, package-boundary, dan shard gateway-watch | Perubahan yang relevan dengan Node |
| `build-smoke` | Pengujian smoke CLI hasil build dan smoke memori startup | Perubahan yang relevan dengan Node |
| `checks` | Lane Linux Node yang tersisa: pengujian channel dan kompatibilitas Node 22 khusus push | Perubahan yang relevan dengan Node |
| `check-docs` | Format docs, lint, dan pemeriksaan tautan rusak | Docs berubah |
| `skills-python` | Ruff + pytest untuk Skills berbasis Python | Perubahan yang relevan dengan skill Python |
| `checks-windows` | Lane pengujian khusus Windows | Perubahan yang relevan dengan Windows |
| `macos-node` | Lane pengujian TypeScript macOS menggunakan artifact build bersama | Perubahan yang relevan dengan macOS |
| `macos-swift` | Lint, build, dan pengujian Swift untuk aplikasi macOS | Perubahan yang relevan dengan macOS |
| `android` | Matriks build dan pengujian Android | Perubahan yang relevan dengan Android |
| Pekerjaan | Tujuan | Kapan dijalankan |
| -------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------- |
| `preflight` | Mendeteksi perubahan khusus docs, cakupan yang berubah, extension yang berubah, dan membangun manifes CI | Selalu pada push dan PR non-draf |
| `security-scm-fast` | Deteksi private key dan audit workflow melalui `zizmor` | Selalu pada push dan PR non-draf |
| `security-dependency-audit` | Audit lockfile produksi bebas dependensi terhadap advisory npm | Selalu pada push dan PR non-draf |
| `security-fast` | Agregat wajib untuk pekerjaan keamanan cepat | Selalu pada push dan PR non-draf |
| `build-artifacts` | Membangun `dist/` dan UI Control sekali, lalu mengunggah artifact yang dapat digunakan ulang untuk pekerjaan hilir | Perubahan yang relevan dengan Node |
| `checks-fast-core` | Lane koreksi Linux cepat seperti pemeriksaan bundled/plugin-contract/protocol | Perubahan yang relevan dengan Node |
| `checks-fast-contracts-channels` | Pemeriksaan kontrak channel yang di-shard dengan hasil pemeriksaan agregat yang stabil | Perubahan yang relevan dengan Node |
| `checks-node-extensions` | Shard pengujian Plugin bawaan penuh di seluruh suite extension | Perubahan yang relevan dengan Node |
| `checks-node-core-test` | Shard pengujian core Node, tidak termasuk lane channel, bundled, kontrak, dan extension | Perubahan yang relevan dengan Node |
| `extension-fast` | Pengujian terfokus hanya untuk Plugin bawaan yang berubah | Saat perubahan extension terdeteksi |
| `check` | Padanan gerbang lokal utama yang di-shard: tipe produksi, lint, guard, tipe pengujian, dan smoke ketat | Perubahan yang relevan dengan Node |
| `check-additional` | Guard arsitektur, boundary, permukaan extension, package-boundary, dan shard gateway-watch | Perubahan yang relevan dengan Node |
| `build-smoke` | Pengujian smoke CLI hasil build dan smoke memori saat startup | Perubahan yang relevan dengan Node |
| `checks` | Lane Linux Node yang tersisa: pengujian channel dan kompatibilitas Node 22 khusus push | Perubahan yang relevan dengan Node |
| `check-docs` | Pemeriksaan format docs, lint, dan tautan rusak | Docs berubah |
| `skills-python` | Ruff + pytest untuk Skills berbasis Python | Perubahan yang relevan dengan skill Python |
| `checks-windows` | Lane pengujian khusus Windows | Perubahan yang relevan dengan Windows |
| `macos-node` | Lane pengujian TypeScript macOS menggunakan artifact build bersama | Perubahan yang relevan dengan macOS |
| `macos-swift` | Lint, build, dan pengujian Swift untuk aplikasi macOS | Perubahan yang relevan dengan macOS |
| `android` | Matriks build dan pengujian Android | Perubahan yang relevan dengan Android |
## Urutan fail-fast
## Urutan Gagal Cepat
Job diurutkan agar pemeriksaan murah gagal lebih dulu sebelum job mahal berjalan:
Pekerjaan diurutkan agar pemeriksaan murah gagal lebih dulu sebelum pekerjaan mahal berjalan:
1. `preflight` menentukan lane mana yang ada sama sekali. Logika `docs-scope` dan `changed-scope` adalah langkah di dalam job ini, bukan job terpisah.
2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs`, dan `skills-python` gagal cepat tanpa menunggu artifact yang lebih berat dan job matriks platform.
3. `build-artifacts` berjalan tumpang tindih dengan lane Linux cepat sehingga konsumen hilir dapat mulai segera setelah build bersama siap.
1. `preflight` menentukan lane mana yang ada sama sekali. Logika `docs-scope` dan `changed-scope` adalah langkah di dalam pekerjaan ini, bukan pekerjaan terpisah.
2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs`, dan `skills-python` gagal cepat tanpa menunggu artifact yang lebih berat dan pekerjaan matriks platform.
3. `build-artifacts` berjalan tumpang tindih dengan lane Linux cepat agar konsumen hilir bisa mulai segera setelah build bersama siap.
4. Lane platform dan runtime yang lebih berat kemudian menyebar setelah itu: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, `extension-fast`, `checks`, `checks-windows`, `macos-node`, `macos-swift`, dan `android`.
Logika cakupan berada di `scripts/ci-changed-scope.mjs` dan dicakup oleh unit test di `src/scripts/ci-changed-scope.test.ts`.
Workflow `install-smoke` yang terpisah menggunakan ulang skrip cakupan yang sama melalui job `preflight` miliknya sendiri. Workflow ini menghitung `run_install_smoke` dari sinyal changed-smoke yang lebih sempit, sehingga smoke Docker/install hanya berjalan untuk perubahan yang relevan dengan instalasi, packaging, dan container.
Workflow `install-smoke` yang terpisah menggunakan kembali skrip cakupan yang sama melalui pekerjaan `preflight` miliknya sendiri. Workflow ini menghitung `run_install_smoke` dari sinyal changed-smoke yang lebih sempit, sehingga smoke Docker/install hanya berjalan untuk perubahan yang relevan dengan install, packaging, dan container.
Logika changed-lane lokal berada di `scripts/changed-lanes.mjs` dan dijalankan oleh `scripts/check-changed.mjs`. Gerbang lokal itu lebih ketat terhadap boundary arsitektur dibanding cakupan platform CI yang luas: perubahan produksi inti menjalankan typecheck prod inti plus test inti, perubahan khusus test inti hanya menjalankan typecheck/test inti, perubahan produksi extension menjalankan typecheck prod extension plus test extension, dan perubahan khusus test extension hanya menjalankan typecheck/test extension. Perubahan Plugin SDK publik atau plugin-contract diperluas ke validasi extension karena extension bergantung pada kontrak inti tersebut. Perubahan root/config yang tidak dikenal gagal aman ke semua lane.
Logika changed-lane lokal berada di `scripts/changed-lanes.mjs` dan dijalankan oleh `scripts/check-changed.mjs`. Gerbang lokal tersebut lebih ketat terhadap boundary arsitektur dibanding cakupan platform CI yang luas: perubahan produksi core menjalankan typecheck produksi core plus pengujian core, perubahan khusus pengujian core hanya menjalankan typecheck/pengujian core test, perubahan produksi extension menjalankan typecheck produksi extension plus pengujian extension, dan perubahan khusus pengujian extension hanya menjalankan typecheck/pengujian extension test. Perubahan Plugin SDK publik atau plugin-contract memperluas validasi ke extension karena extension bergantung pada kontrak core tersebut. Perubahan root/config yang tidak dikenal akan fail-safe ke semua lane.
Pada push, matriks `checks` menambahkan lane `compat-node22` yang khusus push. Pada pull request, lane itu dilewati dan matriks tetap berfokus pada lane test/channel normal.
Pada push, matriks `checks` menambahkan lane `compat-node22` yang khusus push. Pada pull request, lane itu dilewati dan matriks tetap berfokus pada lane pengujian/channel normal.
Keluarga test Node yang paling lambat dibagi menjadi shard include-file agar setiap job tetap kecil: kontrak channel membagi cakupan registry dan inti menjadi masing-masing delapan shard berbobot, test perintah balasan auto-reply dibagi menjadi empat shard include-pattern, dan grup prefix balasan auto-reply besar lainnya dibagi menjadi masing-masing dua shard. `check-additional` juga memisahkan kerja compile/canary package-boundary dari kerja gateway/arsitektur topologi runtime.
Keluarga pengujian Node yang paling lambat dipecah menjadi shard include-file agar setiap pekerjaan tetap kecil: kontrak channel membagi cakupan registry dan core menjadi masing-masing delapan shard berbobot, pengujian perintah balasan auto-reply dipecah menjadi empat shard pola-include, dan kelompok prefix balasan auto-reply besar lainnya dipecah menjadi masing-masing dua shard. `check-additional` juga memisahkan pekerjaan compile/canary package-boundary dari pekerjaan gateway/architecture topologi runtime.
GitHub dapat menandai job yang tergantikan sebagai `cancelled` ketika push yang lebih baru masuk ke PR atau ref `main` yang sama. Perlakukan ini sebagai noise CI kecuali run terbaru untuk ref yang sama juga gagal. Pemeriksaan shard agregat secara eksplisit menyebut kasus pembatalan ini sehingga lebih mudah dibedakan dari kegagalan test.
GitHub dapat menandai pekerjaan yang tergantikan sebagai `cancelled` ketika push yang lebih baru masuk ke PR atau ref `main` yang sama. Anggap itu sebagai noise CI kecuali run terbaru untuk ref yang sama juga gagal. Pemeriksaan agregat shard secara eksplisit menandai kasus pembatalan ini agar lebih mudah dibedakan dari kegagalan pengujian.
## Runner
| Runner | Job |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `blacksmith-16vcpu-ubuntu-2404` | `preflight`, `security-scm-fast`, `security-dependency-audit`, `security-fast`, `build-artifacts`, pemeriksaan Linux, pemeriksaan docs, skill Python, `android` |
| `blacksmith-32vcpu-windows-2025` | `checks-windows` |
| `macos-latest` | `macos-node`, `macos-swift` |
| Runner | Pekerjaan |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `blacksmith-16vcpu-ubuntu-2404` | `preflight`, `security-scm-fast`, `security-dependency-audit`, `security-fast`, `build-artifacts`, pemeriksaan Linux, pemeriksaan docs, Skills Python, `android` |
| `blacksmith-32vcpu-windows-2025` | `checks-windows` |
| `blacksmith-12vcpu-macos-latest` | `macos-node`, `macos-swift` pada `openclaw/openclaw`; fork akan kembali menggunakan `macos-latest` |
## Padanan lokal
## Padanan Lokal
```bash
pnpm changed:lanes # periksa pengklasifikasi changed-lane lokal untuk origin/main...HEAD
pnpm check:changed # gerbang lokal cerdas: typecheck/lint/test yang berubah menurut lane boundary
pnpm check:changed # gerbang lokal cerdas: typecheck/lint/pengujian yang berubah berdasarkan lane boundary
pnpm check # gerbang lokal cepat: tsgo produksi + lint ter-shard + guard cepat paralel
pnpm check:test-types
pnpm check:timed # gerbang yang sama dengan timing per tahap
pnpm build:strict-smoke
pnpm check:architecture
pnpm test:gateway:watch-regression
pnpm test # test vitest
pnpm test # pengujian vitest
pnpm test:channels
pnpm test:contracts:channels
pnpm check:docs # format docs + lint + tautan rusak

View File

@ -1,129 +1,145 @@
---
read_when:
- Menjalankan lebih dari satu Gateway pada mesin yang sama
- Anda memerlukan konfigurasi/status/port yang terisolasi untuk setiap Gateway
- Anda memerlukan config/state/port yang terisolasi untuk setiap Gateway
summary: Menjalankan beberapa Gateway OpenClaw pada satu host (isolasi, port, dan profil)
title: Beberapa Gateway
x-i18n:
generated_at: "2026-04-21T17:45:37Z"
generated_at: "2026-04-21T19:20:46Z"
model: gpt-5.4
provider: openai
source_hash: 8c3fcb921bc6596040e9249467964bd9dcd40ea7c16e958bb378247b0f994a7b
source_hash: 36796da339d5baea1704a7f42530030ea6ef4fa4bde43452ffec946b917ed4a3
source_path: gateway/multiple-gateways.md
workflow: 15
---
# Beberapa Gateway (host yang sama)
Sebagian besar penyiapan sebaiknya menggunakan satu Gateway karena satu Gateway dapat menangani beberapa koneksi perpesanan dan agen. Jika Anda memerlukan isolasi atau redundansi yang lebih kuat (misalnya, bot penyelamat), jalankan Gateway terpisah dengan profil/port yang terisolasi.
Sebagian besar penyiapan sebaiknya menggunakan satu Gateway karena satu Gateway dapat menangani beberapa koneksi pesan dan agent. Jika Anda memerlukan isolasi atau redundansi yang lebih kuat (misalnya, bot pemulihan), jalankan Gateway terpisah dengan profil/port yang terisolasi.
## Daftar periksa isolasi (wajib)
## Penyiapan Paling Direkomendasikan
- `OPENCLAW_CONFIG_PATH` — file konfigurasi per instance
- `OPENCLAW_STATE_DIR` — sesi, kredensial, cache per instance
- `agents.defaults.workspace` — root workspace per instance
- `gateway.port` (atau `--port`) — unik per instance
- Port turunan (browser/canvas) tidak boleh tumpang tindih
Bagi sebagian besar pengguna, penyiapan bot pemulihan yang paling sederhana adalah:
Jika ini dibagikan, Anda akan mengalami race konfigurasi dan konflik port.
- pertahankan bot utama pada profil default
- jalankan bot pemulihan pada `--profile rescue`
- gunakan bot Telegram yang sepenuhnya terpisah untuk akun pemulihan
- pertahankan bot pemulihan pada base port yang berbeda seperti `19789`
## Disarankan: gunakan profil default untuk utama, profil bernama untuk penyelamat
Ini menjaga bot pemulihan tetap terisolasi dari bot utama sehingga bot tersebut dapat men-debug atau menerapkan perubahan config jika bot utama tidak aktif. Sisakan setidaknya 20 port di antara base port agar port browser/canvas/CDP turunan tidak pernah bertabrakan.
Profil secara otomatis mencakup `OPENCLAW_STATE_DIR` + `OPENCLAW_CONFIG_PATH` dan menambahkan sufiks pada nama layanan. Untuk sebagian besar penyiapan bot penyelamat, pertahankan bot utama pada profil default dan berikan hanya bot penyelamat profil bernama seperti `rescue`.
## Mulai Cepat Bot Pemulihan
Gunakan ini sebagai jalur default kecuali Anda memiliki alasan kuat untuk melakukan hal lain:
```bash
# Bot pemulihan (bot Telegram terpisah, profil terpisah, port 19789)
openclaw --profile rescue onboard
openclaw --profile rescue gateway install --port 19789
```
Jika bot utama Anda sudah berjalan, biasanya hanya itu yang Anda perlukan.
Selama `openclaw --profile rescue onboard`:
- gunakan token bot Telegram yang terpisah
- pertahankan profil `rescue`
- gunakan base port setidaknya 20 lebih tinggi daripada bot utama
- terima workspace pemulihan default kecuali Anda sudah mengelolanya sendiri
Jika onboarding sudah memasang layanan pemulihan untuk Anda, `gateway install` terakhir tidak diperlukan.
## Mengapa Ini Berfungsi
Bot pemulihan tetap independen karena memiliki:
- profile/config sendiri
- direktori state sendiri
- workspace sendiri
- base port sendiri (beserta port turunannya)
- token bot Telegram sendiri
Untuk sebagian besar penyiapan, gunakan bot Telegram yang sepenuhnya terpisah untuk profil pemulihan:
- mudah dibatasi hanya untuk operator
- token dan identitas bot terpisah
- independen dari instalasi channel/app bot utama
- jalur pemulihan berbasis DM yang sederhana ketika bot utama bermasalah
## Apa yang Diubah oleh `--profile rescue onboard`
`openclaw --profile rescue onboard` menggunakan alur onboarding normal, tetapi menulis semuanya ke dalam profil terpisah.
Dalam praktiknya, itu berarti bot pemulihan mendapatkan:
- file config sendiri
- direktori state sendiri
- workspace sendiri (secara default `~/.openclaw/workspace-rescue`)
- nama layanan terkelola sendiri
Prompt-nya selain itu sama seperti onboarding normal.
## Penyiapan Multi-Gateway Umum
Tata letak bot pemulihan di atas adalah default termudah, tetapi pola isolasi yang sama juga berlaku untuk pasangan atau kelompok Gateway apa pun pada satu host.
Untuk penyiapan yang lebih umum, beri setiap Gateway tambahan profil bernama sendiri dan base port sendiri:
```bash
# utama (profil default)
openclaw setup
openclaw gateway --port 18789
# penyelamat
openclaw --profile rescue setup
openclaw --profile rescue gateway --port 19001
# gateway tambahan
openclaw --profile ops setup
openclaw --profile ops gateway --port 19789
```
Layanan:
Jika Anda ingin kedua Gateway menggunakan profil bernama, itu juga bisa:
```bash
openclaw --profile main setup
openclaw --profile main gateway --port 18789
openclaw --profile ops setup
openclaw --profile ops gateway --port 19789
```
Layanan mengikuti pola yang sama:
```bash
openclaw gateway install
openclaw --profile rescue gateway install
openclaw --profile ops gateway install --port 19789
```
Jika Anda ingin kedua Gateway menggunakan profil bernama, itu juga berfungsi, tetapi tidak wajib.
Gunakan mulai cepat bot pemulihan saat Anda menginginkan jalur operator cadangan. Gunakan pola profil umum saat Anda menginginkan beberapa Gateway jangka panjang untuk channel, tenant, workspace, atau peran operasional yang berbeda.
## Panduan bot penyelamat
## Daftar Periksa Isolasi
Penyiapan yang disarankan:
Pertahankan hal-hal ini unik untuk setiap instance Gateway:
- pertahankan bot utama pada profil default
- jalankan bot penyelamat pada `--profile rescue`
- gunakan bot Telegram yang benar-benar terpisah untuk akun penyelamat
- pertahankan bot penyelamat pada port dasar yang berbeda seperti `19001`
- `OPENCLAW_CONFIG_PATH` — file config per instance
- `OPENCLAW_STATE_DIR` — sesi, kredensial, cache per instance
- `agents.defaults.workspace` — root workspace per instance
- `gateway.port` (atau `--port`) — unik per instance
- port browser/canvas/CDP turunan
Ini menjaga bot penyelamat tetap terisolasi dari bot utama sehingga ia dapat melakukan debug atau menerapkan perubahan konfigurasi jika bot utama tidak aktif. Sisakan setidaknya 20 port di antara port dasar agar port turunan browser/canvas/CDP tidak pernah bertabrakan.
### Channel/akun penyelamat yang disarankan
Untuk sebagian besar penyiapan, gunakan bot Telegram yang benar-benar terpisah untuk profil penyelamat.
Mengapa Telegram:
- mudah dibatasi hanya untuk operator
- token dan identitas bot terpisah
- independen dari instalasi channel/aplikasi bot utama
- jalur pemulihan berbasis DM yang sederhana saat bot utama rusak
Bagian yang penting adalah kemandirian penuh: akun bot terpisah, kredensial terpisah, profil OpenClaw terpisah, workspace terpisah, dan port terpisah.
### Alur instalasi yang disarankan
Gunakan ini sebagai penyiapan default kecuali Anda memiliki alasan kuat untuk melakukan hal lain:
```bash
# Bot utama (profil default, port 18789)
openclaw onboard
openclaw gateway install
# Bot penyelamat (bot Telegram terpisah, profil terpisah, port 19001)
openclaw --profile rescue onboard
openclaw --profile rescue gateway install
```
Selama `openclaw --profile rescue onboard`:
- gunakan token bot Telegram yang terpisah
- pertahankan profil `rescue`
- gunakan port dasar yang setidaknya 20 lebih tinggi daripada bot utama
- terima workspace penyelamat default kecuali Anda sudah mengelolanya sendiri
Jika onboarding sudah memasang layanan penyelamat untuk Anda, `gateway install` terakhir tidak diperlukan.
### Apa yang diubah oleh onboarding
`openclaw --profile rescue onboard` menggunakan alur onboarding normal, tetapi menulis semuanya ke dalam profil terpisah.
Dalam praktiknya, itu berarti bot penyelamat mendapatkan miliknya sendiri:
- file konfigurasi
- direktori status
- workspace (secara default `~/.openclaw/workspace-rescue`)
- nama layanan terkelola
Selain itu, prompt-nya sama seperti onboarding normal.
Jika hal-hal ini dibagikan, Anda akan mengalami race config dan konflik port.
## Pemetaan port (turunan)
Port dasar = `gateway.port` (atau `OPENCLAW_GATEWAY_PORT` / `--port`).
Base port = `gateway.port` (atau `OPENCLAW_GATEWAY_PORT` / `--port`).
- port layanan kontrol browser = dasar + 2 (hanya loopback)
- port layanan kontrol browser = base + 2 (hanya loopback)
- host canvas disajikan pada server HTTP Gateway (port yang sama dengan `gateway.port`)
- port CDP profil browser dialokasikan otomatis dari `browser.controlPort + 9 .. + 108`
Jika Anda menimpa salah satu dari ini di konfigurasi atau env, Anda harus menjaganya tetap unik per instance.
Jika Anda menimpa salah satu dari ini di config atau env, Anda harus menjaganya tetap unik per instance.
## Catatan browser/CDP (jebakan umum)
- **Jangan** sematkan `browser.cdpUrl` ke nilai yang sama pada beberapa instance.
- Setiap instance memerlukan port kontrol browser dan rentang CDP-nya sendiri (diturunkan dari port gateway-nya).
- Setiap instance memerlukan port kontrol browser dan rentang CDP sendiri (diturunkan dari port gateway-nya).
- Jika Anda memerlukan port CDP eksplisit, atur `browser.profiles.<name>.cdpPort` per instance.
- Chrome jarak jauh: gunakan `browser.profiles.<name>.cdpUrl` (per profil, per instance).
@ -136,7 +152,7 @@ openclaw gateway --port 18789
OPENCLAW_CONFIG_PATH=~/.openclaw/rescue.json \
OPENCLAW_STATE_DIR=~/.openclaw-rescue \
openclaw gateway --port 19001
openclaw gateway --port 19789
```
## Pemeriksaan cepat
@ -153,4 +169,4 @@ openclaw --profile rescue browser status
Interpretasi:
- `gateway status --deep` membantu mendeteksi layanan launchd/systemd/schtasks usang dari instalasi yang lebih lama.
- Teks peringatan `gateway probe` seperti `multiple reachable gateways detected` hanya diharapkan ketika Anda memang sengaja menjalankan lebih dari satu gateway terisolasi.
- teks peringatan `gateway probe` seperti `multiple reachable gateways detected` hanya diharapkan ketika Anda memang sengaja menjalankan lebih dari satu gateway yang terisolasi.

View File

@ -1,74 +1,80 @@
---
read_when:
- Anda sedang membangun Plugin OpenClaw
- Anda perlu mengirimkan skema config Plugin atau men-debug error validasi Plugin
summary: Manifest Plugin + persyaratan skema JSON (validasi config ketat)
- Anda sedang membangun plugin OpenClaw
- Anda perlu merilis skema config plugin atau men-debug error validasi plugin
summary: Persyaratan manifest Plugin + skema JSON (validasi config yang ketat)
title: Manifest Plugin
x-i18n:
generated_at: "2026-04-19T01:11:10Z"
generated_at: "2026-04-21T19:20:47Z"
model: gpt-5.4
provider: openai
source_hash: 2dfc00759108ddee7bfcda8c42acf7f2d47451676447ba3caf8b5950f8a1c181
source_hash: 304c08035724dfb1ce6349972729b621aafc00880d4d259db78c22b86e9056ba
source_path: plugins/manifest.md
workflow: 15
---
# Manifest Plugin (`openclaw.plugin.json`)
Halaman ini hanya untuk **manifest Plugin OpenClaw native**.
Halaman ini hanya untuk **manifest plugin OpenClaw native**.
Untuk tata letak bundle yang kompatibel, lihat [Bundle Plugin](/id/plugins/bundles).
Untuk tata letak bundle yang kompatibel, lihat [Bundle plugin](/id/plugins/bundles).
Format bundle yang kompatibel menggunakan file manifest yang berbeda:
- Bundle Codex: `.codex-plugin/plugin.json`
- Bundle Claude: `.claude-plugin/plugin.json` atau tata letak komponen Claude
default tanpa manifest
bawaan tanpa manifest
- Bundle Cursor: `.cursor-plugin/plugin.json`
OpenClaw juga mendeteksi otomatis tata letak bundle tersebut, tetapi tidak divalidasi
terhadap skema `openclaw.plugin.json` yang dijelaskan di sini.
Untuk bundle yang kompatibel, OpenClaw saat ini membaca metadata bundle beserta root
skill yang dideklarasikan, root perintah Claude, default `settings.json` bundle
Claude, default LSP bundle Claude, dan paket hook yang didukung saat tata letaknya
sesuai dengan ekspektasi runtime OpenClaw.
skill yang dideklarasikan, root perintah Claude, default `settings.json` bundle Claude,
default LSP bundle Claude, dan hook pack yang didukung saat tata letaknya sesuai
dengan ekspektasi runtime OpenClaw.
Setiap Plugin OpenClaw native **harus** menyertakan file `openclaw.plugin.json` di
Setiap plugin OpenClaw native **harus** menyertakan file `openclaw.plugin.json` di
**root plugin**. OpenClaw menggunakan manifest ini untuk memvalidasi konfigurasi
**tanpa mengeksekusi kode plugin**. Manifest yang hilang atau tidak valid diperlakukan
sebagai error plugin dan memblokir validasi config.
**tanpa mengeksekusi kode plugin**. Manifest yang hilang atau tidak valid diperlakukan sebagai
error plugin dan memblokir validasi config.
Lihat panduan lengkap sistem plugin: [Plugin](/id/tools/plugin).
Untuk model kapabilitas native dan panduan kompatibilitas eksternal saat ini:
[Model kapabilitas](/id/plugins/architecture#public-capability-model).
## Apa fungsi file ini
## Fungsi file ini
`openclaw.plugin.json` adalah metadata yang dibaca OpenClaw sebelum memuat kode
plugin Anda.
`openclaw.plugin.json` adalah metadata yang dibaca OpenClaw sebelum memuat
kode plugin Anda.
Gunakan file ini untuk:
Gunakan untuk:
- identitas plugin
- validasi config
- metadata autentikasi dan onboarding yang harus tersedia tanpa mem-boot runtime plugin
- petunjuk aktivasi ringan yang dapat diperiksa oleh permukaan control-plane sebelum runtime dimuat
- deskriptor setup ringan yang dapat diperiksa oleh permukaan setup/onboarding sebelum runtime dimuat
- metadata alias dan auto-enable yang harus diselesaikan sebelum runtime plugin dimuat
- metadata kepemilikan keluarga model singkat yang harus mengaktifkan plugin secara otomatis sebelum runtime dimuat
- snapshot kepemilikan kapabilitas statis yang digunakan untuk wiring kompatibilitas bundle dan cakupan kontrak
- metadata QA runner ringan yang dapat diperiksa host bersama `openclaw qa` sebelum runtime plugin dimuat
- metadata config khusus channel yang harus digabungkan ke permukaan katalog dan validasi tanpa memuat runtime
- metadata auth dan onboarding yang harus tersedia tanpa mem-boot runtime plugin
- petunjuk aktivasi murah yang dapat diperiksa oleh surface control-plane sebelum runtime
dimuat
- deskriptor setup murah yang dapat diperiksa oleh surface setup/onboarding sebelum
runtime dimuat
- metadata alias dan auto-enable yang harus di-resolve sebelum runtime plugin dimuat
- metadata kepemilikan keluarga model bentuk ringkas yang harus mengaktifkan plugin
secara otomatis sebelum runtime dimuat
- snapshot kepemilikan kapabilitas statis yang digunakan untuk wiring compat bawaan dan
cakupan kontrak
- metadata runner QA murah yang dapat diperiksa host bersama `openclaw qa`
sebelum runtime plugin dimuat
- metadata config khusus channel yang harus digabungkan ke dalam surface katalog dan validasi
tanpa memuat runtime
- petunjuk UI config
Jangan gunakan file ini untuk:
Jangan gunakan untuk:
- mendaftarkan perilaku runtime
- mendeklarasikan entrypoint kode
- metadata instalasi npm
Semua itu harus ditempatkan di kode plugin Anda dan `package.json`.
Hal-hal tersebut termasuk dalam kode plugin Anda dan `package.json`.
## Contoh minimal
@ -89,7 +95,7 @@ Semua itu harus ditempatkan di kode plugin Anda dan `package.json`.
{
"id": "openrouter",
"name": "OpenRouter",
"description": "OpenRouter provider plugin",
"description": "Plugin provider OpenRouter",
"version": "1.0.0",
"providers": ["openrouter"],
"modelSupport": {
@ -117,19 +123,19 @@ Semua itu harus ditempatkan di kode plugin Anda dan `package.json`.
"provider": "openrouter",
"method": "api-key",
"choiceId": "openrouter-api-key",
"choiceLabel": "OpenRouter API key",
"choiceLabel": "Kunci API OpenRouter",
"groupId": "openrouter",
"groupLabel": "OpenRouter",
"optionKey": "openrouterApiKey",
"cliFlag": "--openrouter-api-key",
"cliOption": "--openrouter-api-key <key>",
"cliDescription": "OpenRouter API key",
"cliDescription": "Kunci API OpenRouter",
"onboardingScopes": ["text-inference"]
}
],
"uiHints": {
"apiKey": {
"label": "API key",
"label": "Kunci API",
"placeholder": "sk-or-v1-...",
"sensitive": true
}
@ -150,65 +156,65 @@ Semua itu harus ditempatkan di kode plugin Anda dan `package.json`.
| Field | Wajib | Tipe | Artinya |
| ----------------------------------- | -------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id` | Ya | `string` | ID Plugin kanonis. Ini adalah ID yang digunakan dalam `plugins.entries.<id>`. |
| `configSchema` | Ya | `object` | JSON Schema inline untuk config Plugin ini. |
| `enabledByDefault` | Tidak | `true` | Menandai Plugin bundle sebagai aktif secara default. Hilangkan field ini, atau tetapkan nilai apa pun selain `true`, agar Plugin tetap nonaktif secara default. |
| `legacyPluginIds` | Tidak | `string[]` | ID lama yang dinormalisasi ke ID Plugin kanonis ini. |
| `autoEnableWhenConfiguredProviders` | Tidak | `string[]` | ID provider yang harus mengaktifkan Plugin ini secara otomatis saat auth, config, atau referensi model menyebutkannya. |
| `kind` | Tidak | `"memory"` \| `"context-engine"` | Mendeklarasikan jenis Plugin eksklusif yang digunakan oleh `plugins.slots.*`. |
| `channels` | Tidak | `string[]` | ID channel yang dimiliki oleh Plugin ini. Digunakan untuk discovery dan validasi config. |
| `providers` | Tidak | `string[]` | ID provider yang dimiliki oleh Plugin ini. |
| `modelSupport` | Tidak | `object` | Metadata singkat keluarga model milik manifest yang digunakan untuk memuat otomatis Plugin sebelum runtime. |
| `providerEndpoints` | Tidak | `object[]` | Metadata host/baseUrl endpoint milik manifest untuk rute provider yang harus diklasifikasikan oleh core sebelum runtime provider dimuat. |
| `cliBackends` | Tidak | `string[]` | ID backend inferensi CLI yang dimiliki oleh Plugin ini. Digunakan untuk aktivasi otomatis saat startup dari referensi config eksplisit. |
| `syntheticAuthRefs` | Tidak | `string[]` | Referensi provider atau backend CLI yang hook auth sintetis milik Plugin-nya harus diperiksa selama discovery model cold path sebelum runtime dimuat. |
| `nonSecretAuthMarkers` | Tidak | `string[]` | Nilai placeholder API key milik Plugin bundle yang merepresentasikan status kredensial lokal, OAuth, atau ambient yang bukan rahasia. |
| `commandAliases` | Tidak | `object[]` | Nama perintah yang dimiliki oleh Plugin ini yang harus menghasilkan diagnostik config dan CLI yang sadar-Plugin sebelum runtime dimuat. |
| `id` | Ya | `string` | ID plugin kanonis. Ini adalah ID yang digunakan di `plugins.entries.<id>`. |
| `configSchema` | Ya | `object` | JSON Schema inline untuk config plugin ini. |
| `enabledByDefault` | Tidak | `true` | Menandai plugin bawaan sebagai aktif secara default. Hilangkan field ini, atau tetapkan nilai apa pun selain `true`, agar plugin tetap nonaktif secara default. |
| `legacyPluginIds` | Tidak | `string[]` | ID lama yang dinormalisasi ke ID plugin kanonis ini. |
| `autoEnableWhenConfiguredProviders` | Tidak | `string[]` | ID provider yang harus mengaktifkan plugin ini secara otomatis saat auth, config, atau referensi model menyebutkannya. |
| `kind` | Tidak | `"memory"` \| `"context-engine"` | Mendeklarasikan jenis plugin eksklusif yang digunakan oleh `plugins.slots.*`. |
| `channels` | Tidak | `string[]` | ID channel yang dimiliki plugin ini. Digunakan untuk discovery dan validasi config. |
| `providers` | Tidak | `string[]` | ID provider yang dimiliki plugin ini. |
| `modelSupport` | Tidak | `object` | Metadata bentuk ringkas keluarga model milik manifest yang digunakan untuk memuat plugin secara otomatis sebelum runtime. |
| `providerEndpoints` | Tidak | `object[]` | Metadata host/baseUrl endpoint milik manifest untuk rute provider yang harus diklasifikasikan core sebelum runtime provider dimuat. |
| `cliBackends` | Tidak | `string[]` | ID backend inferensi CLI yang dimiliki plugin ini. Digunakan untuk auto-activation saat startup dari referensi config eksplisit. |
| `syntheticAuthRefs` | Tidak | `string[]` | Referensi provider atau backend CLI yang hook auth sintetis milik pluginnya harus diperiksa selama discovery model cold sebelum runtime dimuat. |
| `nonSecretAuthMarkers` | Tidak | `string[]` | Nilai placeholder kunci API milik plugin bawaan yang merepresentasikan state kredensial lokal, OAuth, atau ambient yang bukan rahasia. |
| `commandAliases` | Tidak | `object[]` | Nama perintah yang dimiliki plugin ini yang harus menghasilkan diagnostik config dan CLI yang sadar-plugin sebelum runtime dimuat. |
| `providerAuthEnvVars` | Tidak | `Record<string, string[]>` | Metadata env auth provider ringan yang dapat diperiksa OpenClaw tanpa memuat kode plugin. |
| `providerAuthAliases` | Tidak | `Record<string, string>` | ID provider yang harus menggunakan ulang ID provider lain untuk pencarian auth, misalnya provider coding yang berbagi API key provider dasar dan profil auth yang sama. |
| `channelEnvVars` | Tidak | `Record<string, string[]>` | Metadata env channel ringan yang dapat diperiksa OpenClaw tanpa memuat kode plugin. Gunakan ini untuk permukaan setup atau auth channel berbasis env yang perlu dilihat helper startup/config generik. |
| `providerAuthAliases` | Tidak | `Record<string, string>` | ID provider yang harus menggunakan kembali ID provider lain untuk lookup auth, misalnya provider coding yang berbagi kunci API provider dasar dan profil auth yang sama. |
| `channelEnvVars` | Tidak | `Record<string, string[]>` | Metadata env channel ringan yang dapat diperiksa OpenClaw tanpa memuat kode plugin. Gunakan ini untuk surface setup atau auth channel berbasis env yang harus terlihat oleh helper startup/config generik. |
| `providerAuthChoices` | Tidak | `object[]` | Metadata pilihan auth ringan untuk picker onboarding, resolusi provider pilihan, dan wiring flag CLI sederhana. |
| `activation` | Tidak | `object` | Petunjuk aktivasi ringan untuk pemuatan yang dipicu oleh provider, perintah, channel, rute, dan kapabilitas. Hanya metadata; runtime plugin tetap memiliki perilaku sebenarnya. |
| `setup` | Tidak | `object` | Deskriptor setup/onboarding ringan yang dapat diperiksa oleh permukaan discovery dan setup tanpa memuat runtime plugin. |
| `qaRunners` | Tidak | `object[]` | Deskriptor QA runner ringan yang digunakan oleh host bersama `openclaw qa` sebelum runtime plugin dimuat. |
| `contracts` | Tidak | `object` | Snapshot kapabilitas bundle statis untuk kepemilikan speech, transkripsi realtime, voice realtime, media-understanding, image-generation, music-generation, video-generation, web-fetch, web search, dan tool. |
| `channelConfigs` | Tidak | `Record<string, object>` | Metadata config channel milik manifest yang digabungkan ke permukaan discovery dan validasi sebelum runtime dimuat. |
| `skills` | Tidak | `string[]` | Direktori Skills yang akan dimuat, relatif terhadap root plugin. |
| `name` | Tidak | `string` | Nama Plugin yang dapat dibaca manusia. |
| `description` | Tidak | `string` | Ringkasan singkat yang ditampilkan di permukaan plugin. |
| `version` | Tidak | `string` | Versi Plugin informasional. |
| `activation` | Tidak | `object` | Petunjuk aktivasi ringan untuk pemuatan yang dipicu provider, perintah, channel, rute, dan kapabilitas. Hanya metadata; runtime plugin tetap memiliki perilaku sebenarnya. |
| `setup` | Tidak | `object` | Deskriptor setup/onboarding ringan yang dapat diperiksa surface discovery dan setup tanpa memuat runtime plugin. |
| `qaRunners` | Tidak | `object[]` | Deskriptor runner QA ringan yang digunakan oleh host bersama `openclaw qa` sebelum runtime plugin dimuat. |
| `contracts` | Tidak | `object` | Snapshot kapabilitas bawaan statis untuk kepemilikan speech, transkripsi realtime, suara realtime, media-understanding, image-generation, music-generation, video-generation, web-fetch, web search, dan tool. |
| `channelConfigs` | Tidak | `Record<string, object>` | Metadata config channel milik manifest yang digabungkan ke surface discovery dan validasi sebelum runtime dimuat. |
| `skills` | Tidak | `string[]` | Direktori Skills yang akan dimuat, relatif terhadap root plugin. |
| `name` | Tidak | `string` | Nama plugin yang dapat dibaca manusia. |
| `description` | Tidak | `string` | Ringkasan singkat yang ditampilkan di surface plugin. |
| `version` | Tidak | `string` | Versi plugin untuk informasi. |
| `uiHints` | Tidak | `Record<string, object>` | Label UI, placeholder, dan petunjuk sensitivitas untuk field config. |
## Referensi `providerAuthChoices`
Setiap entri `providerAuthChoices` menjelaskan satu pilihan onboarding atau auth.
OpenClaw membaca ini sebelum runtime provider dimuat.
OpenClaw membacanya sebelum runtime provider dimuat.
| Field | Wajib | Tipe | Artinya |
| --------------------- | -------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `provider` | Ya | `string` | ID provider tempat pilihan ini berada. |
| `method` | Ya | `string` | ID metode auth yang akan digunakan untuk dispatch. |
| `choiceId` | Ya | `string` | ID pilihan auth stabil yang digunakan oleh alur onboarding dan CLI. |
| `choiceLabel` | Tidak | `string` | Label untuk pengguna. Jika dihilangkan, OpenClaw akan menggunakan `choiceId`. |
| `method` | Ya | `string` | ID metode auth untuk dispatch. |
| `choiceId` | Ya | `string` | ID auth-choice stabil yang digunakan oleh alur onboarding dan CLI. |
| `choiceLabel` | Tidak | `string` | Label yang ditampilkan ke pengguna. Jika dihilangkan, OpenClaw akan menggunakan `choiceId`. |
| `choiceHint` | Tidak | `string` | Teks bantuan singkat untuk picker. |
| `assistantPriority` | Tidak | `number` | Nilai yang lebih rendah diurutkan lebih awal dalam picker interaktif yang digerakkan asisten. |
| `assistantVisibility` | Tidak | `"visible"` \| `"manual-only"` | Sembunyikan pilihan dari picker asisten sambil tetap mengizinkan pemilihan CLI manual. |
| `assistantVisibility` | Tidak | `"visible"` \| `"manual-only"` | Sembunyikan pilihan ini dari picker asisten sambil tetap mengizinkan pemilihan CLI manual. |
| `deprecatedChoiceIds` | Tidak | `string[]` | ID pilihan lama yang harus mengarahkan pengguna ke pilihan pengganti ini. |
| `groupId` | Tidak | `string` | ID grup opsional untuk mengelompokkan pilihan yang terkait. |
| `groupLabel` | Tidak | `string` | Label untuk pengguna bagi grup tersebut. |
| `groupId` | Tidak | `string` | ID grup opsional untuk mengelompokkan pilihan terkait. |
| `groupLabel` | Tidak | `string` | Label yang ditampilkan ke pengguna untuk grup tersebut. |
| `groupHint` | Tidak | `string` | Teks bantuan singkat untuk grup tersebut. |
| `optionKey` | Tidak | `string` | Kunci opsi internal untuk alur auth sederhana dengan satu flag. |
| `cliFlag` | Tidak | `string` | Nama flag CLI, seperti `--openrouter-api-key`. |
| `cliOption` | Tidak | `string` | Bentuk opsi CLI lengkap, seperti `--openrouter-api-key <key>`. |
| `cliDescription` | Tidak | `string` | Deskripsi yang digunakan dalam bantuan CLI. |
| `onboardingScopes` | Tidak | `Array<"text-inference" \| "image-generation">` | Permukaan onboarding tempat pilihan ini harus muncul. Jika dihilangkan, default-nya adalah `["text-inference"]`. |
| `onboardingScopes` | Tidak | `Array<"text-inference" \| "image-generation">` | Surface onboarding tempat pilihan ini harus muncul. Jika dihilangkan, default-nya adalah `["text-inference"]`. |
## Referensi `commandAliases`
Gunakan `commandAliases` saat sebuah Plugin memiliki nama perintah runtime yang
mungkin keliru dimasukkan pengguna ke `plugins.allow` atau coba dijalankan
sebagai perintah CLI root. OpenClaw menggunakan metadata ini untuk diagnostik
tanpa mengimpor kode runtime plugin.
Gunakan `commandAliases` saat sebuah plugin memiliki nama perintah runtime yang
mungkin keliru dimasukkan pengguna ke `plugins.allow` atau coba dijalankan sebagai
perintah CLI root. OpenClaw menggunakan metadata ini untuk diagnostik tanpa mengimpor
kode runtime plugin.
```json
{
@ -222,46 +228,45 @@ tanpa mengimpor kode runtime plugin.
}
```
| Field | Wajib | Tipe | Artinya |
| ------------ | -------- | ----------------- | ------------------------------------------------------------------------- |
| `name` | Ya | `string` | Nama perintah yang dimiliki oleh Plugin ini. |
| `kind` | Tidak | `"runtime-slash"` | Menandai alias sebagai perintah slash chat, bukan perintah CLI root. |
| `cliCommand` | Tidak | `string` | Perintah CLI root terkait yang disarankan untuk operasi CLI, jika ada. |
| Field | Wajib | Tipe | Artinya |
| ------------ | -------- | ----------------- | ------------------------------------------------------------------------ |
| `name` | Ya | `string` | Nama perintah yang dimiliki plugin ini. |
| `kind` | Tidak | `"runtime-slash"` | Menandai alias sebagai perintah slash chat, bukan perintah CLI root. |
| `cliCommand` | Tidak | `string` | Perintah CLI root terkait yang disarankan untuk operasi CLI, jika ada. |
## Referensi `activation`
Gunakan `activation` saat Plugin dapat mendeklarasikan secara ringan peristiwa
control-plane mana yang seharusnya mengaktifkannya nanti.
Gunakan `activation` saat plugin dapat secara ringan mendeklarasikan peristiwa control-plane mana
yang seharusnya mengaktifkannya nanti.
## Referensi `qaRunners`
Gunakan `qaRunners` saat sebuah Plugin menyediakan satu atau lebih transport runner
di bawah root bersama `openclaw qa`. Jaga metadata ini tetap ringan dan statis;
runtime plugin tetap memiliki registrasi CLI sebenarnya melalui permukaan
`runtime-api.ts` yang ringan dan mengekspor `qaRunnerCliRegistrations`.
Gunakan `qaRunners` saat sebuah plugin menyumbangkan satu atau lebih runner transport di bawah
root bersama `openclaw qa`. Pertahankan metadata ini tetap ringan dan statis; runtime plugin
tetap memiliki registrasi CLI yang sebenarnya melalui surface `runtime-api.ts`
ringan yang mengekspor `qaRunnerCliRegistrations`.
```json
{
"qaRunners": [
{
"commandName": "matrix",
"description": "Jalankan lane QA live Matrix berbasis Docker terhadap homeserver disposable"
"description": "Menjalankan lane QA live Matrix berbasis Docker terhadap homeserver sekali pakai"
}
]
}
```
| Field | Wajib | Tipe | Artinya |
| ------------- | -------- | -------- | -------------------------------------------------------------------- |
| `commandName` | Ya | `string` | Subperintah yang dipasang di bawah `openclaw qa`, misalnya `matrix`. |
| `description` | Tidak | `string` | Teks bantuan cadangan yang digunakan saat host bersama memerlukan perintah stub. |
| Field | Wajib | Tipe | Artinya |
| ------------- | -------- | -------- | --------------------------------------------------------------------- |
| `commandName` | Ya | `string` | Subperintah yang dipasang di bawah `openclaw qa`, misalnya `matrix`. |
| `description` | Tidak | `string` | Teks bantuan fallback yang digunakan saat host bersama memerlukan perintah stub. |
Blok ini hanya metadata. Blok ini tidak mendaftarkan perilaku runtime, dan
tidak menggantikan `register(...)`, `setupEntry`, atau entrypoint runtime/plugin
lainnya. Konsumen saat ini menggunakannya sebagai petunjuk penyempitan sebelum
pemuatan plugin yang lebih luas, jadi metadata activation yang hilang biasanya
hanya berdampak pada performa; seharusnya tidak mengubah correctness selama fallback
kepemilikan manifest lama masih ada.
Blok ini hanya metadata. Ini tidak mendaftarkan perilaku runtime, dan tidak
menggantikan `register(...)`, `setupEntry`, atau entrypoint runtime/plugin lainnya.
Konsumen saat ini menggunakannya sebagai petunjuk penyempitan sebelum pemuatan plugin yang lebih luas, jadi
metadata activation yang hilang biasanya hanya berdampak pada performa; ini seharusnya tidak
mengubah kebenaran selama fallback kepemilikan manifest lama masih ada.
```json
{
@ -277,26 +282,26 @@ kepemilikan manifest lama masih ada.
| Field | Wajib | Tipe | Artinya |
| ---------------- | -------- | ---------------------------------------------------- | ------------------------------------------------------------------- |
| `onProviders` | Tidak | `string[]` | ID provider yang harus mengaktifkan Plugin ini saat diminta. |
| `onCommands` | Tidak | `string[]` | ID perintah yang harus mengaktifkan Plugin ini. |
| `onChannels` | Tidak | `string[]` | ID channel yang harus mengaktifkan Plugin ini. |
| `onRoutes` | Tidak | `string[]` | Jenis rute yang harus mengaktifkan Plugin ini. |
| `onCapabilities` | Tidak | `Array<"provider" \| "channel" \| "tool" \| "hook">` | Petunjuk kapabilitas luas yang digunakan oleh perencanaan aktivasi control-plane. |
| `onProviders` | Tidak | `string[]` | ID provider yang harus mengaktifkan plugin ini saat diminta. |
| `onCommands` | Tidak | `string[]` | ID perintah yang harus mengaktifkan plugin ini. |
| `onChannels` | Tidak | `string[]` | ID channel yang harus mengaktifkan plugin ini. |
| `onRoutes` | Tidak | `string[]` | Jenis rute yang harus mengaktifkan plugin ini. |
| `onCapabilities` | Tidak | `Array<"provider" \| "channel" \| "tool" \| "hook">` | Petunjuk kapabilitas luas yang digunakan oleh perencanaan activation control-plane. |
Konsumen live saat ini:
- perencanaan CLI yang dipicu perintah melakukan fallback ke
`commandAliases[].cliCommand` atau `commandAliases[].name` lama
- perencanaan setup/channel yang dipicu channel melakukan fallback ke kepemilikan
`channels[]` lama saat metadata aktivasi channel eksplisit tidak ada
- perencanaan setup/runtime yang dipicu provider melakukan fallback ke kepemilikan
`providers[]` lama dan `cliBackends[]` tingkat atas saat metadata aktivasi provider
eksplisit tidak ada
- perencanaan CLI yang dipicu perintah kembali menggunakan fallback
`commandAliases[].cliCommand` lama atau `commandAliases[].name`
- perencanaan setup/channel yang dipicu channel kembali menggunakan fallback
kepemilikan `channels[]` lama saat metadata activation channel eksplisit tidak ada
- perencanaan setup/runtime yang dipicu provider kembali menggunakan fallback
kepemilikan `providers[]` lama dan `cliBackends[]` tingkat atas saat metadata provider
activation eksplisit tidak ada
## Referensi `setup`
Gunakan `setup` saat permukaan setup dan onboarding memerlukan metadata milik Plugin
yang ringan sebelum runtime dimuat.
Gunakan `setup` saat surface setup dan onboarding membutuhkan metadata milik plugin yang ringan
sebelum runtime dimuat.
```json
{
@ -315,37 +320,37 @@ yang ringan sebelum runtime dimuat.
}
```
`cliBackends` tingkat atas tetap valid dan terus menjelaskan backend inferensi
CLI. `setup.cliBackends` adalah permukaan deskriptor khusus setup untuk alur
`cliBackends` tingkat atas tetap valid dan terus menjelaskan backend inferensi CLI.
`setup.cliBackends` adalah surface deskriptor khusus setup untuk alur
control-plane/setup yang harus tetap hanya berupa metadata.
Jika ada, `setup.providers` dan `setup.cliBackends` adalah permukaan lookup
berbasis deskriptor yang diutamakan untuk discovery setup. Jika deskriptor hanya
mempersempit kandidat Plugin dan setup masih membutuhkan hook runtime waktu-setup
yang lebih kaya, tetapkan `requiresRuntime: true` dan pertahankan `setup-api`
sebagai jalur eksekusi fallback.
Saat ada, `setup.providers` dan `setup.cliBackends` adalah surface lookup yang diprioritaskan
dan berbasis deskriptor untuk discovery setup. Jika deskriptor hanya
mempersempit plugin kandidat dan setup masih membutuhkan hook runtime yang lebih kaya pada waktu setup,
tetapkan `requiresRuntime: true` dan tetap gunakan `setup-api` sebagai
jalur eksekusi fallback.
Karena lookup setup dapat mengeksekusi kode `setup-api` milik Plugin, nilai
`setup.providers[].id` dan `setup.cliBackends[]` yang telah dinormalisasi harus
tetap unik di seluruh Plugin yang ditemukan. Kepemilikan ambigu akan gagal
tertutup alih-alih memilih pemenang berdasarkan urutan discovery.
Karena lookup setup dapat mengeksekusi kode `setup-api` milik plugin, nilai
`setup.providers[].id` dan `setup.cliBackends[]` yang dinormalisasi harus tetap unik di seluruh
plugin yang ditemukan. Kepemilikan yang ambigu gagal secara tertutup alih-alih memilih
pemenang berdasarkan urutan discovery.
### Referensi `setup.providers`
| Field | Wajib | Tipe | Artinya |
| ------------- | -------- | ---------- | ---------------------------------------------------------------------------------- |
| `id` | Ya | `string` | ID provider yang diekspos selama setup atau onboarding. Jaga agar ID ternormalisasi tetap unik secara global. |
| `authMethods` | Tidak | `string[]` | ID metode setup/auth yang didukung provider ini tanpa memuat runtime penuh. |
| `envVars` | Tidak | `string[]` | Env var yang dapat diperiksa oleh permukaan setup/status generik sebelum runtime plugin dimuat. |
| Field | Wajib | Tipe | Artinya |
| ------------- | -------- | ---------- | ------------------------------------------------------------------------------------ |
| `id` | Ya | `string` | ID provider yang diekspos selama setup atau onboarding. Pertahankan ID yang dinormalisasi tetap unik secara global. |
| `authMethods` | Tidak | `string[]` | ID metode setup/auth yang didukung provider ini tanpa memuat runtime penuh. |
| `envVars` | Tidak | `string[]` | Variabel env yang dapat diperiksa surface setup/status generik sebelum runtime plugin dimuat. |
### Field `setup`
| Field | Wajib | Tipe | Artinya |
| ------------------ | -------- | ---------- | --------------------------------------------------------------------------------------------------- |
| `providers` | Tidak | `object[]` | Deskriptor setup provider yang diekspos selama setup dan onboarding. |
| `cliBackends` | Tidak | `string[]` | ID backend waktu-setup yang digunakan untuk lookup setup berbasis deskriptor. Jaga agar ID ternormalisasi tetap unik secara global. |
| `configMigrations` | Tidak | `string[]` | ID migrasi config yang dimiliki oleh permukaan setup Plugin ini. |
| `requiresRuntime` | Tidak | `boolean` | Apakah setup masih memerlukan eksekusi `setup-api` setelah lookup deskriptor. |
| Field | Wajib | Tipe | Artinya |
| ------------------ | -------- | ---------- | -------------------------------------------------------------------------------------------- |
| `providers` | Tidak | `object[]` | Deskriptor setup provider yang diekspos selama setup dan onboarding. |
| `cliBackends` | Tidak | `string[]` | ID backend waktu setup yang digunakan untuk lookup setup berbasis deskriptor. Pertahankan ID yang dinormalisasi tetap unik secara global. |
| `configMigrations` | Tidak | `string[]` | ID migrasi config yang dimiliki oleh surface setup plugin ini. |
| `requiresRuntime` | Tidak | `boolean` | Apakah setup masih memerlukan eksekusi `setup-api` setelah lookup deskriptor. |
## Referensi `uiHints`
@ -355,7 +360,7 @@ tertutup alih-alih memilih pemenang berdasarkan urutan discovery.
{
"uiHints": {
"apiKey": {
"label": "API key",
"label": "Kunci API",
"help": "Digunakan untuk permintaan OpenRouter",
"placeholder": "sk-or-v1-...",
"sensitive": true
@ -366,14 +371,14 @@ tertutup alih-alih memilih pemenang berdasarkan urutan discovery.
Setiap petunjuk field dapat mencakup:
| Field | Tipe | Artinya |
| ------------- | ---------- | ---------------------------------------- |
| `label` | `string` | Label field untuk pengguna. |
| `help` | `string` | Teks bantuan singkat. |
| `tags` | `string[]` | Tag UI opsional. |
| `advanced` | `boolean` | Menandai field sebagai lanjutan. |
| Field | Tipe | Artinya |
| ------------- | ---------- | --------------------------------------- |
| `label` | `string` | Label field yang ditampilkan ke pengguna. |
| `help` | `string` | Teks bantuan singkat. |
| `tags` | `string[]` | Tag UI opsional. |
| `advanced` | `boolean` | Menandai field sebagai lanjutan. |
| `sensitive` | `boolean` | Menandai field sebagai rahasia atau sensitif. |
| `placeholder` | `string` | Teks placeholder untuk input formulir. |
| `placeholder` | `string` | Teks placeholder untuk input formulir. |
## Referensi `contracts`
@ -398,22 +403,22 @@ dibaca OpenClaw tanpa mengimpor runtime plugin.
Setiap daftar bersifat opsional:
| Field | Tipe | Artinya |
| -------------------------------- | ---------- | ------------------------------------------------------------ |
| `speechProviders` | `string[]` | ID provider speech yang dimiliki oleh Plugin ini. |
| `realtimeTranscriptionProviders` | `string[]` | ID provider transkripsi realtime yang dimiliki oleh Plugin ini. |
| `realtimeVoiceProviders` | `string[]` | ID provider voice realtime yang dimiliki oleh Plugin ini. |
| `mediaUnderstandingProviders` | `string[]` | ID provider media-understanding yang dimiliki oleh Plugin ini. |
| `imageGenerationProviders` | `string[]` | ID provider image-generation yang dimiliki oleh Plugin ini. |
| `videoGenerationProviders` | `string[]` | ID provider video-generation yang dimiliki oleh Plugin ini. |
| `webFetchProviders` | `string[]` | ID provider web-fetch yang dimiliki oleh Plugin ini. |
| `webSearchProviders` | `string[]` | ID provider web search yang dimiliki oleh Plugin ini. |
| `tools` | `string[]` | Nama tool agent yang dimiliki oleh Plugin ini untuk pemeriksaan kontrak bundle. |
| Field | Tipe | Artinya |
| -------------------------------- | ---------- | -------------------------------------------------------------- |
| `speechProviders` | `string[]` | ID provider speech yang dimiliki plugin ini. |
| `realtimeTranscriptionProviders` | `string[]` | ID provider transkripsi realtime yang dimiliki plugin ini. |
| `realtimeVoiceProviders` | `string[]` | ID provider suara realtime yang dimiliki plugin ini. |
| `mediaUnderstandingProviders` | `string[]` | ID provider media-understanding yang dimiliki plugin ini. |
| `imageGenerationProviders` | `string[]` | ID provider image-generation yang dimiliki plugin ini. |
| `videoGenerationProviders` | `string[]` | ID provider video-generation yang dimiliki plugin ini. |
| `webFetchProviders` | `string[]` | ID provider web-fetch yang dimiliki plugin ini. |
| `webSearchProviders` | `string[]` | ID provider web search yang dimiliki plugin ini. |
| `tools` | `string[]` | Nama tool agent yang dimiliki plugin ini untuk pemeriksaan kontrak bawaan. |
## Referensi `channelConfigs`
Gunakan `channelConfigs` saat sebuah Plugin channel memerlukan metadata config
ringan sebelum runtime dimuat.
Gunakan `channelConfigs` saat sebuah plugin channel membutuhkan metadata config yang ringan sebelum
runtime dimuat.
```json
{
@ -428,7 +433,7 @@ ringan sebelum runtime dimuat.
},
"uiHints": {
"homeserverUrl": {
"label": "Homeserver URL",
"label": "URL Homeserver",
"placeholder": "https://matrix.example.com"
}
},
@ -442,18 +447,18 @@ ringan sebelum runtime dimuat.
Setiap entri channel dapat mencakup:
| Field | Tipe | Artinya |
| ------------- | ------------------------ | ---------------------------------------------------------------------------------------- |
| Field | Tipe | Artinya |
| ------------- | ------------------------ | ------------------------------------------------------------------------------------------- |
| `schema` | `object` | JSON Schema untuk `channels.<id>`. Wajib untuk setiap entri config channel yang dideklarasikan. |
| `uiHints` | `Record<string, object>` | Label UI/placeholder/petunjuk sensitif opsional untuk bagian config channel tersebut. |
| `label` | `string` | Label channel yang digabungkan ke permukaan picker dan inspect saat metadata runtime belum siap. |
| `description` | `string` | Deskripsi channel singkat untuk permukaan inspect dan katalog. |
| `preferOver` | `string[]` | ID Plugin lama atau berprioritas lebih rendah yang harus dikalahkan channel ini dalam permukaan pemilihan. |
| `uiHints` | `Record<string, object>` | Label UI/placeholder/petunjuk sensitif opsional untuk bagian config channel tersebut. |
| `label` | `string` | Label channel yang digabungkan ke surface picker dan inspect saat metadata runtime belum siap. |
| `description` | `string` | Deskripsi channel singkat untuk surface inspect dan katalog. |
| `preferOver` | `string[]` | ID plugin lama atau prioritas lebih rendah yang harus dikalahkan channel ini di surface pemilihan. |
## Referensi `modelSupport`
Gunakan `modelSupport` saat OpenClaw harus menyimpulkan Plugin provider Anda dari
ID model singkat seperti `gpt-5.4` atau `claude-sonnet-4.6` sebelum runtime plugin
Gunakan `modelSupport` saat OpenClaw harus menyimpulkan plugin provider Anda dari
ID model bentuk ringkas seperti `gpt-5.4` atau `claude-sonnet-4.6` sebelum runtime plugin
dimuat.
```json
@ -465,21 +470,22 @@ dimuat.
}
```
OpenClaw menerapkan prioritas berikut:
OpenClaw menerapkan prioritas ini:
- referensi `provider/model` eksplisit menggunakan metadata manifest `providers` yang memilikinya
- `modelPatterns` mengalahkan `modelPrefixes`
- jika satu Plugin non-bundle dan satu Plugin bundle sama-sama cocok, Plugin non-bundle yang menang
- jika satu plugin non-bawaan dan satu plugin bawaan sama-sama cocok, plugin non-bawaan
menang
- ambiguitas yang tersisa diabaikan sampai pengguna atau config menentukan provider
Field:
| Field | Tipe | Artinya |
| --------------- | ---------- | ------------------------------------------------------------------------------ |
| `modelPrefixes` | `string[]` | Prefiks yang dicocokkan dengan `startsWith` terhadap ID model singkat. |
| `modelPatterns` | `string[]` | Sumber regex yang dicocokkan terhadap ID model singkat setelah suffix profil dihapus. |
| Field | Tipe | Artinya |
| --------------- | ---------- | -------------------------------------------------------------------------------- |
| `modelPrefixes` | `string[]` | Prefiks yang dicocokkan dengan `startsWith` terhadap ID model bentuk ringkas. |
| `modelPatterns` | `string[]` | Sumber regex yang dicocokkan terhadap ID model bentuk ringkas setelah penghapusan sufiks profil. |
Kunci kapabilitas tingkat atas lama sudah deprecated. Gunakan `openclaw doctor --fix` untuk
Kunci kapabilitas lama tingkat atas sudah deprecated. Gunakan `openclaw doctor --fix` untuk
memindahkan `speechProviders`, `realtimeTranscriptionProviders`,
`realtimeVoiceProviders`, `mediaUnderstandingProviders`,
`imageGenerationProviders`, `videoGenerationProviders`,
@ -491,49 +497,54 @@ kepemilikan kapabilitas.
Kedua file ini memiliki fungsi yang berbeda:
| File | Gunakan untuk |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `openclaw.plugin.json` | Discovery, validasi config, metadata pilihan auth, dan petunjuk UI yang harus ada sebelum kode plugin dijalankan |
| File | Gunakan untuk |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `openclaw.plugin.json` | Discovery, validasi config, metadata auth-choice, dan petunjuk UI yang harus ada sebelum kode plugin berjalan |
| `package.json` | Metadata npm, instalasi dependensi, dan blok `openclaw` yang digunakan untuk entrypoint, gating instalasi, setup, atau metadata katalog |
Jika Anda ragu metadata tertentu harus ditempatkan di mana, gunakan aturan ini:
Jika Anda ragu metadata tertentu harus diletakkan di mana, gunakan aturan ini:
- jika OpenClaw harus mengetahuinya sebelum memuat kode plugin, letakkan di `openclaw.plugin.json`
- jika itu terkait packaging, file entry, atau perilaku instalasi npm, letakkan di `package.json`
### Field `package.json` yang memengaruhi discovery
Sebagian metadata plugin pra-runtime sengaja ditempatkan di `package.json` di bawah
blok `openclaw`, bukan `openclaw.plugin.json`.
Beberapa metadata plugin pra-runtime sengaja berada di `package.json` di bawah blok
`openclaw`, bukan di `openclaw.plugin.json`.
Contoh penting:
| Field | Artinya |
| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `openclaw.extensions` | Mendeklarasikan entrypoint Plugin native. |
| `openclaw.setupEntry` | Entrypoint ringan khusus setup yang digunakan selama onboarding dan startup channel tertunda. |
| `openclaw.channel` | Metadata katalog channel ringan seperti label, path docs, alias, dan copy pemilihan. |
| `openclaw.channel.configuredState` | Metadata checker configured-state ringan yang dapat menjawab "apakah setup hanya-env sudah ada?" tanpa memuat runtime channel penuh. |
| `openclaw.channel.persistedAuthState` | Metadata checker auth tersimpan ringan yang dapat menjawab "apakah sudah ada yang login?" tanpa memuat runtime channel penuh. |
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | Petunjuk install/update untuk Plugin bundle dan Plugin yang dipublikasikan secara eksternal. |
| `openclaw.install.defaultChoice` | Jalur instalasi yang diutamakan saat beberapa sumber instalasi tersedia. |
| `openclaw.install.minHostVersion` | Versi host OpenClaw minimum yang didukung, menggunakan batas bawah semver seperti `>=2026.3.22`. |
| `openclaw.install.allowInvalidConfigRecovery` | Mengizinkan jalur pemulihan reinstall Plugin bundle yang sempit saat config tidak valid. |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | Memungkinkan permukaan channel khusus setup dimuat sebelum Plugin channel penuh saat startup. |
| Field | Artinya |
| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `openclaw.extensions` | Mendeklarasikan entrypoint plugin native. |
| `openclaw.setupEntry` | Entrypoint ringan khusus setup yang digunakan selama onboarding, startup channel yang ditunda, dan discovery status channel/SecretRef baca-saja. |
| `openclaw.channel` | Metadata katalog channel ringan seperti label, path docs, alias, dan copy pemilihan. |
| `openclaw.channel.configuredState` | Metadata pemeriksa configured-state ringan yang dapat menjawab "apakah setup khusus env sudah ada?" tanpa memuat runtime channel penuh. |
| `openclaw.channel.persistedAuthState` | Metadata pemeriksa auth tersimpan ringan yang dapat menjawab "apakah sudah ada yang login?" tanpa memuat runtime channel penuh. |
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | Petunjuk instalasi/update untuk plugin bawaan dan plugin yang dipublikasikan secara eksternal. |
| `openclaw.install.defaultChoice` | Jalur instalasi yang dipilih saat beberapa sumber instalasi tersedia. |
| `openclaw.install.minHostVersion` | Versi host OpenClaw minimum yang didukung, menggunakan batas bawah semver seperti `>=2026.3.22`. |
| `openclaw.install.allowInvalidConfigRecovery` | Mengizinkan jalur pemulihan reinstall plugin bawaan yang sempit saat config tidak valid. |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | Memungkinkan surface channel khusus setup dimuat sebelum plugin channel penuh selama startup. |
`openclaw.install.minHostVersion` ditegakkan selama instalasi dan pemuatan registry
manifest. Nilai yang tidak valid ditolak; nilai yang valid tetapi lebih baru akan
melewati Plugin pada host yang lebih lama.
`openclaw.install.minHostVersion` diberlakukan selama instalasi dan pemuatan registry
manifest. Nilai yang tidak valid ditolak; nilai yang valid tetapi lebih baru akan melewati
plugin pada host yang lebih lama.
`openclaw.install.allowInvalidConfigRecovery` sengaja dibuat sempit. Ini tidak
membuat config rusak secara arbitrer menjadi dapat diinstal. Saat ini, ini hanya
memungkinkan alur instalasi memulihkan kegagalan upgrade Plugin bundle usang tertentu,
seperti path Plugin bundle yang hilang atau entri `channels.<id>` usang untuk Plugin
bundle yang sama. Error config yang tidak terkait tetap memblokir instalasi dan
mengarahkan operator ke `openclaw doctor --fix`.
Plugin channel harus menyediakan `openclaw.setupEntry` saat status, daftar channel,
atau pemindaian SecretRef perlu mengidentifikasi akun yang terkonfigurasi tanpa memuat
runtime penuh. Entri setup harus mengekspos metadata channel beserta adaptor config,
status, dan secret yang aman untuk setup; pertahankan network client, listener Gateway, dan
runtime transport di entrypoint extension utama.
`openclaw.channel.persistedAuthState` adalah metadata package untuk modul checker
kecil:
`openclaw.install.allowInvalidConfigRecovery` sengaja dibuat sempit. Ini
tidak membuat config rusak sembarang menjadi dapat diinstal. Saat ini ini hanya
memungkinkan alur instalasi memulihkan dari kegagalan upgrade plugin bawaan lama tertentu, seperti
path plugin bawaan yang hilang atau entri `channels.<id>` lama untuk plugin bawaan
yang sama tersebut. Error config yang tidak terkait tetap memblokir instalasi dan mengarahkan
operator ke `openclaw doctor --fix`.
`openclaw.channel.persistedAuthState` adalah metadata package untuk modul pemeriksa kecil:
```json
{
@ -549,12 +560,13 @@ kecil:
}
```
Gunakan ini saat alur setup, doctor, atau configured-state memerlukan probe auth ya/tidak
yang ringan sebelum Plugin channel penuh dimuat. Export target harus berupa fungsi kecil
yang hanya membaca state tersimpan; jangan arahkan melalui barrel runtime channel penuh.
Gunakan ini saat alur setup, doctor, atau configured-state memerlukan probe auth
ya/tidak yang ringan sebelum plugin channel penuh dimuat. Export target harus berupa
fungsi kecil yang hanya membaca state tersimpan; jangan arahkan melalui barrel runtime
channel penuh.
`openclaw.channel.configuredState` mengikuti bentuk yang sama untuk pemeriksaan configured
khusus-env yang ringan:
khusus env yang ringan:
```json
{
@ -571,69 +583,69 @@ khusus-env yang ringan:
```
Gunakan ini saat sebuah channel dapat menjawab configured-state dari env atau input kecil
non-runtime lainnya. Jika pemeriksaan membutuhkan resolusi config penuh atau runtime
channel sebenarnya, pertahankan logika tersebut di hook plugin `config.hasConfiguredState`.
non-runtime lainnya. Jika pemeriksaan memerlukan resolusi config penuh atau runtime channel
sebenarnya, simpan logika tersebut di hook plugin `config.hasConfiguredState`.
## Persyaratan JSON Schema
- **Setiap Plugin harus menyertakan JSON Schema**, bahkan jika tidak menerima config.
- Skema kosong dapat diterima (misalnya, `{ "type": "object", "additionalProperties": false }`).
- Skema divalidasi pada saat baca/tulis config, bukan saat runtime.
- **Setiap plugin harus menyertakan JSON Schema**, meskipun tidak menerima config.
- Schema kosong dapat diterima (misalnya, `{ "type": "object", "additionalProperties": false }`).
- Schema divalidasi saat baca/tulis config, bukan saat runtime.
## Perilaku validasi
- Kunci `channels.*` yang tidak dikenal adalah **error**, kecuali ID channel tersebut dideklarasikan oleh
manifest plugin.
- `plugins.entries.<id>`, `plugins.allow`, `plugins.deny`, dan `plugins.slots.*`
harus mereferensikan ID Plugin yang **dapat ditemukan**. ID yang tidak dikenal adalah **error**.
- Jika sebuah Plugin terinstal tetapi memiliki manifest atau skema yang rusak atau hilang,
validasi gagal dan Doctor melaporkan error Plugin tersebut.
- Jika config Plugin ada tetapi Plugin tersebut **dinonaktifkan**, config tetap disimpan dan
**peringatan** akan ditampilkan di Doctor + log.
harus merujuk ke ID plugin yang **dapat ditemukan**. ID yang tidak dikenal adalah **error**.
- Jika sebuah plugin terinstal tetapi memiliki manifest atau schema yang rusak atau hilang,
validasi gagal dan Doctor melaporkan error plugin tersebut.
- Jika config plugin ada tetapi plugin **nonaktif**, config dipertahankan dan
**peringatan** ditampilkan di Doctor + log.
Lihat [Referensi konfigurasi](/id/gateway/configuration) untuk skema `plugins.*` lengkap.
Lihat [Referensi config](/id/gateway/configuration) untuk skema lengkap `plugins.*`.
## Catatan
- Manifest ini **wajib untuk Plugin OpenClaw native**, termasuk pemuatan dari filesystem lokal.
- Runtime tetap memuat modul plugin secara terpisah; manifest hanya digunakan untuk
- Manifest **wajib untuk plugin OpenClaw native**, termasuk pemuatan dari filesystem lokal.
- Runtime tetap memuat modul plugin secara terpisah; manifest hanya untuk
discovery + validasi.
- Manifest native di-parse dengan JSON5, jadi komentar, trailing comma, dan
key tanpa tanda kutip diterima selama nilai akhirnya tetap berupa object.
- Hanya field manifest yang terdokumentasi yang dibaca oleh manifest loader. Hindari menambahkan
key tingkat atas kustom di sini.
- Manifest native di-parse dengan JSON5, jadi komentar, koma di akhir, dan
kunci tanpa tanda kutip diterima selama nilai akhirnya tetap berupa object.
- Hanya field manifest yang terdokumentasi yang dibaca oleh loader manifest. Hindari menambahkan
kunci tingkat atas kustom di sini.
- `providerAuthEnvVars` adalah jalur metadata ringan untuk probe auth, validasi
penanda env, dan permukaan auth provider serupa yang tidak seharusnya mem-boot runtime
plugin hanya untuk memeriksa nama env.
- `providerAuthAliases` memungkinkan varian provider menggunakan ulang env var auth
provider lain, profil auth, auth berbasis config, dan pilihan onboarding API key
tanpa melakukan hardcode hubungan tersebut di core.
- `providerEndpoints` memungkinkan Plugin provider memiliki metadata pencocokan
host/baseUrl endpoint sederhana. Gunakan hanya untuk kelas endpoint yang sudah
didukung core; plugin tetap memiliki perilaku runtime.
- `syntheticAuthRefs` adalah jalur metadata ringan untuk hook auth sintetis milik provider
yang harus terlihat oleh discovery model cold path sebelum registry runtime ada. Cantumkan
hanya referensi yang runtime provider atau backend CLI-nya benar-benar mengimplementasikan
`resolveSyntheticAuth`.
- `nonSecretAuthMarkers` adalah jalur metadata ringan untuk placeholder API key
milik Plugin bundle seperti penanda kredensial lokal, OAuth, atau ambient.
Core memperlakukan ini sebagai non-secret untuk tampilan auth dan audit secret tanpa
melakukan hardcode pada provider pemiliknya.
- `channelEnvVars` adalah jalur metadata ringan untuk fallback shell-env, prompt
setup, dan permukaan channel serupa yang tidak seharusnya mem-boot runtime plugin
penanda env, dan surface auth provider serupa yang tidak seharusnya mem-boot runtime plugin
hanya untuk memeriksa nama env.
- `providerAuthChoices` adalah jalur metadata ringan untuk picker pilihan auth,
resolusi `--auth-choice`, pemetaan provider pilihan, dan registrasi flag CLI onboarding
sederhana sebelum runtime provider dimuat. Untuk metadata wizard runtime yang
memerlukan kode provider, lihat
- `providerAuthAliases` memungkinkan varian provider menggunakan kembali auth
env vars, profil auth, auth berbasis config, dan pilihan onboarding kunci API milik provider lain
tanpa meng-hardcode relasi tersebut di core.
- `providerEndpoints` memungkinkan plugin provider memiliki metadata pencocokan
host/baseUrl endpoint sederhana. Gunakan hanya untuk kelas endpoint yang sudah didukung core;
plugin tetap memiliki perilaku runtime.
- `syntheticAuthRefs` adalah jalur metadata ringan untuk hook auth sintetis milik provider
yang harus terlihat oleh discovery model cold sebelum registry runtime
ada. Hanya daftarkan referensi yang provider runtime atau backend CLI-nya benar-benar
mengimplementasikan `resolveSyntheticAuth`.
- `nonSecretAuthMarkers` adalah jalur metadata ringan untuk placeholder kunci API
milik plugin bawaan seperti penanda kredensial lokal, OAuth, atau ambient.
Core memperlakukan ini sebagai non-rahasia untuk tampilan auth dan audit secret tanpa
meng-hardcode provider pemilik.
- `channelEnvVars` adalah jalur metadata ringan untuk fallback shell-env, prompt setup,
dan surface channel serupa yang tidak seharusnya mem-boot runtime plugin
hanya untuk memeriksa nama env.
- `providerAuthChoices` adalah jalur metadata ringan untuk picker auth-choice,
resolusi `--auth-choice`, pemetaan provider pilihan, dan registrasi flag CLI
onboarding sederhana sebelum runtime provider dimuat. Untuk metadata wizard runtime
yang memerlukan kode provider, lihat
[Hook runtime provider](/id/plugins/architecture#provider-runtime-hooks).
- Jenis Plugin eksklusif dipilih melalui `plugins.slots.*`.
- Jenis plugin eksklusif dipilih melalui `plugins.slots.*`.
- `kind: "memory"` dipilih oleh `plugins.slots.memory`.
- `kind: "context-engine"` dipilih oleh `plugins.slots.contextEngine`
(default: `legacy` bawaan).
- `channels`, `providers`, `cliBackends`, dan `skills` dapat dihilangkan saat sebuah
Plugin tidak memerlukannya.
- Jika Plugin Anda bergantung pada modul native, dokumentasikan langkah build dan setiap
plugin tidak membutuhkannya.
- Jika plugin Anda bergantung pada modul native, dokumentasikan langkah build dan semua
persyaratan allowlist package manager (misalnya, pnpm `allow-build-scripts`
- `pnpm rebuild <package>`).
@ -641,4 +653,4 @@ Lihat [Referensi konfigurasi](/id/gateway/configuration) untuk skema `plugins.*`
- [Membangun Plugin](/id/plugins/building-plugins) — memulai dengan plugin
- [Arsitektur Plugin](/id/plugins/architecture) — arsitektur internal
- [Ikhtisar SDK](/id/plugins/sdk-overview) — referensi SDK Plugin
- [Ringkasan SDK](/id/plugins/sdk-overview) — referensi SDK Plugin

View File

@ -1,113 +1,113 @@
---
read_when:
- Anda sedang membangun plugin channel pesan baru
- Anda ingin menghubungkan OpenClaw ke platform pesan
- Anda sedang membangun plugin channel perpesanan baru
- Anda ingin menghubungkan OpenClaw ke platform perpesanan
- Anda perlu memahami permukaan adaptor ChannelPlugin
sidebarTitle: Channel Plugins
summary: Panduan langkah demi langkah untuk membangun plugin channel pesan untuk OpenClaw
summary: Panduan langkah demi langkah untuk membangun plugin channel perpesanan untuk OpenClaw
title: Membangun Plugin Channel
x-i18n:
generated_at: "2026-04-21T09:20:59Z"
generated_at: "2026-04-21T19:20:47Z"
model: gpt-5.4
provider: openai
source_hash: 569394aeefa0231ae3157a13406f91c97fe7eeff2b62df0d35a893f1ad4d5d05
source_hash: 35cae55c13b69f2219bd2f9bd3ee2f7d8c4075bd87f0be11c35a0fddb070fe1e
source_path: plugins/sdk-channel-plugins.md
workflow: 15
---
# Membangun Plugin Channel
Panduan ini memandu Anda membangun plugin channel yang menghubungkan OpenClaw ke
platform pesan. Pada akhirnya Anda akan memiliki channel yang berfungsi dengan keamanan DM,
pairing, reply threading, dan pesan keluar.
Panduan ini memandu Anda membangun plugin channel yang menghubungkan OpenClaw ke platform
perpesanan. Pada akhirnya Anda akan memiliki channel yang berfungsi dengan keamanan DM,
pairing, threading balasan, dan pengiriman pesan keluar.
<Info>
Jika Anda belum pernah membangun plugin OpenClaw sebelumnya, baca
[Memulai](/id/plugins/building-plugins) terlebih dahulu untuk struktur paket
dasar dan penyiapan manifes.
dasar dan penyiapan manifest.
</Info>
## Cara kerja plugin channel
Plugin channel tidak memerlukan tool send/edit/react mereka sendiri. OpenClaw menjaga satu
tool `message` bersama di inti. Plugin Anda memiliki:
Plugin channel tidak memerlukan tool send/edit/react mereka sendiri. OpenClaw menyimpan satu
tool `message` bersama di core. Plugin Anda memiliki:
- **Config** — resolusi akun dan wizard penyiapan
- **Security** — kebijakan DM dan allowlist
- **Pairing** — alur persetujuan DM
- **Session grammar** — bagaimana id percakapan khusus provider dipetakan ke chat dasar, id thread, dan fallback parent
- **Tata bahasa sesi** — bagaimana id percakapan khusus penyedia dipetakan ke chat dasar, id thread, dan fallback induk
- **Outbound** — mengirim teks, media, dan polling ke platform
- **Threading** — bagaimana balasan di-thread
Inti memiliki tool message bersama, prompt wiring, bentuk luar session-key,
Core memiliki tool pesan bersama, pengkabelan prompt, bentuk kunci sesi luar,
pencatatan `:thread:` generik, dan dispatch.
Jika channel Anda menambahkan param message-tool yang membawa sumber media, tampilkan
nama param tersebut melalui `describeMessageTool(...).mediaSourceParams`. Inti menggunakan
daftar eksplisit itu untuk normalisasi path sandbox dan kebijakan akses media keluar,
sehingga plugin tidak memerlukan kasus khusus shared-core untuk
param avatar, lampiran, atau gambar sampul yang khusus provider.
Sebaiknya kembalikan map berindeks action seperti
`{ "set-profile": ["avatarUrl", "avatarPath"] }` agar action yang tidak terkait tidak
mewarisi argumen media milik action lain. Array datar tetap berfungsi untuk param yang
sengaja dibagikan di setiap action yang diekspos.
nama param tersebut melalui `describeMessageTool(...).mediaSourceParams`. Core menggunakan
daftar eksplisit itu untuk normalisasi path sandbox dan kebijakan akses-media keluar,
jadi plugin tidak memerlukan kasus khusus shared-core untuk param avatar, lampiran,
atau gambar sampul yang khusus penyedia.
Sebaiknya kembalikan map yang diberi kunci tindakan seperti
`{ "set-profile": ["avatarUrl", "avatarPath"] }` agar tindakan yang tidak terkait tidak
mewarisi argumen media dari tindakan lain. Array datar tetap berfungsi untuk param yang
memang sengaja dibagikan di setiap tindakan yang diekspos.
Jika platform Anda menyimpan cakupan tambahan di dalam id percakapan, simpan parsing itu
di plugin dengan `messaging.resolveSessionConversation(...)`. Itu adalah hook kanonis
Jika platform Anda menyimpan cakupan tambahan di dalam id percakapan, simpan parsing
itu di plugin dengan `messaging.resolveSessionConversation(...)`. Itu adalah hook kanonis
untuk memetakan `rawId` ke id percakapan dasar, id thread opsional,
`baseConversationId` eksplisit, dan `parentConversationCandidates`.
`baseConversationId` eksplisit, dan `parentConversationCandidates` apa pun.
Saat Anda mengembalikan `parentConversationCandidates`, pertahankan urutannya dari
parent yang paling sempit ke percakapan parent/dasar yang paling luas.
induk yang paling sempit ke percakapan induk/dasar yang paling luas.
Plugin bawaan yang memerlukan parsing yang sama sebelum registri channel aktif
juga dapat mengekspos file tingkat atas `session-key-api.ts` dengan ekspor
`resolveSessionConversation(...)` yang cocok. Inti menggunakan permukaan yang aman untuk bootstrap itu
hanya ketika registri plugin runtime belum tersedia.
Plugin bundel yang memerlukan parsing yang sama sebelum registry channel aktif
juga dapat mengekspos file `session-key-api.ts` tingkat atas dengan
ekspor `resolveSessionConversation(...)` yang sesuai. Core menggunakan surface yang aman saat bootstrap
itu hanya ketika registry plugin runtime belum tersedia.
`messaging.resolveParentConversationCandidates(...)` tetap tersedia sebagai
fallback kompatibilitas lama ketika plugin hanya memerlukan fallback parent di atas
id generik/raw. Jika kedua hook ada, inti menggunakan
`messaging.resolveParentConversationCandidates(...)` tetap tersedia sebagai fallback kompatibilitas lama
ketika plugin hanya memerlukan fallback induk di atas id generik/raw.
Jika kedua hook ada, core menggunakan
`resolveSessionConversation(...).parentConversationCandidates` terlebih dahulu dan hanya
fallback ke `resolveParentConversationCandidates(...)` ketika hook kanonis
mengabaikannya.
kembali ke `resolveParentConversationCandidates(...)` ketika hook kanonis
menghilangkannya.
## Persetujuan dan capability channel
## Persetujuan dan kapabilitas channel
Sebagian besar plugin channel tidak memerlukan kode khusus persetujuan.
- Inti memiliki `/approve` chat yang sama, payload tombol persetujuan bersama, dan pengiriman fallback generik.
- Sebaiknya gunakan satu objek `approvalCapability` pada plugin channel ketika channel memerlukan perilaku khusus persetujuan.
- `ChannelPlugin.approvals` dihapus. Letakkan fakta pengiriman/native/render/auth persetujuan di `approvalCapability`.
- `plugin.auth` hanya untuk login/logout; inti tidak lagi membaca hook auth persetujuan dari objek itu.
- `approvalCapability.authorizeActorAction` dan `approvalCapability.getActionAvailabilityState` adalah seam auth persetujuan kanonis.
- Core memiliki `/approve` chat yang sama, payload tombol persetujuan bersama, dan pengiriman fallback generik.
- Pilih satu objek `approvalCapability` pada plugin channel saat channel memerlukan perilaku khusus persetujuan.
- `ChannelPlugin.approvals` dihapus. Tempatkan fakta pengiriman/presentasi/render/auth persetujuan di `approvalCapability`.
- `plugin.auth` hanya untuk login/logout; core tidak lagi membaca hook auth persetujuan dari objek itu.
- `approvalCapability.authorizeActorAction` dan `approvalCapability.getActionAvailabilityState` adalah seam auth-persetujuan kanonis.
- Gunakan `approvalCapability.getActionAvailabilityState` untuk ketersediaan auth persetujuan chat yang sama.
- Jika channel Anda mengekspos persetujuan exec native, gunakan `approvalCapability.getExecInitiatingSurfaceState` untuk status initiating-surface/native-client ketika berbeda dari auth persetujuan chat yang sama. Inti menggunakan hook khusus exec itu untuk membedakan `enabled` vs `disabled`, memutuskan apakah channel pemicu mendukung persetujuan exec native, dan menyertakan channel itu dalam panduan fallback native-client. `createApproverRestrictedNativeApprovalCapability(...)` mengisi ini untuk kasus umum.
- Jika channel Anda mengekspos persetujuan exec native, gunakan `approvalCapability.getExecInitiatingSurfaceState` untuk status initiating-surface/native-client saat berbeda dari auth persetujuan chat yang sama. Core menggunakan hook khusus exec itu untuk membedakan `enabled` vs `disabled`, memutuskan apakah channel pemula mendukung persetujuan exec native, dan menyertakan channel itu dalam panduan fallback native-client. `createApproverRestrictedNativeApprovalCapability(...)` mengisi ini untuk kasus umum.
- Gunakan `outbound.shouldSuppressLocalPayloadPrompt` atau `outbound.beforeDeliverPayload` untuk perilaku siklus hidup payload khusus channel seperti menyembunyikan prompt persetujuan lokal duplikat atau mengirim indikator mengetik sebelum pengiriman.
- Gunakan `approvalCapability.delivery` hanya untuk routing persetujuan native atau penekanan fallback.
- Gunakan `approvalCapability.nativeRuntime` untuk fakta persetujuan native milik channel. Jaga agar tetap lazy pada entrypoint channel yang panas dengan `createLazyChannelApprovalNativeRuntimeAdapter(...)`, yang dapat mengimpor modul runtime Anda sesuai kebutuhan sambil tetap membiarkan inti merakit siklus hidup persetujuan.
- Gunakan `approvalCapability.delivery` hanya untuk perutean persetujuan native atau penekanan fallback.
- Gunakan `approvalCapability.nativeRuntime` untuk fakta persetujuan native yang dimiliki channel. Buat tetap lazy pada entrypoint channel yang hot dengan `createLazyChannelApprovalNativeRuntimeAdapter(...)`, yang dapat mengimpor modul runtime Anda saat diminta sambil tetap memungkinkan core menyusun siklus hidup persetujuan.
- Gunakan `approvalCapability.render` hanya ketika channel benar-benar memerlukan payload persetujuan kustom alih-alih renderer bersama.
- Gunakan `approvalCapability.describeExecApprovalSetup` ketika channel ingin balasan jalur nonaktif menjelaskan knob config tepat yang dibutuhkan untuk mengaktifkan persetujuan exec native. Hook menerima `{ channel, channelLabel, accountId }`; channel akun bernama harus merender path bercakupan akun seperti `channels.<channel>.accounts.<id>.execApprovals.*` alih-alih default tingkat atas.
- Jika channel dapat menyimpulkan identitas DM mirip pemilik yang stabil dari config yang ada, gunakan `createResolvedApproverActionAuthAdapter` dari `openclaw/plugin-sdk/approval-runtime` untuk membatasi `/approve` chat yang sama tanpa menambahkan logika inti khusus persetujuan.
- Jika channel memerlukan pengiriman persetujuan native, jaga agar kode channel tetap fokus pada normalisasi target plus fakta transport/presentasi. Gunakan `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver`, dan `createApproverRestrictedNativeApprovalCapability` dari `openclaw/plugin-sdk/approval-runtime`. Letakkan fakta khusus channel di balik `approvalCapability.nativeRuntime`, idealnya melalui `createChannelApprovalNativeRuntimeAdapter(...)` atau `createLazyChannelApprovalNativeRuntimeAdapter(...)`, sehingga inti dapat merakit handler dan memiliki pemfilteran request, routing, dedupe, kedaluwarsa, langganan gateway, dan pemberitahuan routed-elsewhere. `nativeRuntime` dibagi menjadi beberapa seam yang lebih kecil:
- `availability` — apakah akun dikonfigurasi dan apakah request harus ditangani
- `presentation`memetakan view model persetujuan bersama ke payload native pending/resolved/expired atau action final
- `transport`menyiapkan target plus mengirim/memperbarui/menghapus pesan persetujuan native
- Gunakan `approvalCapability.describeExecApprovalSetup` ketika channel ingin balasan jalur-disabled menjelaskan knob config yang tepat yang diperlukan untuk mengaktifkan persetujuan exec native. Hook menerima `{ channel, channelLabel, accountId }`; channel akun-bernama harus merender path bercakupan akun seperti `channels.<channel>.accounts.<id>.execApprovals.*` alih-alih default tingkat atas.
- Jika channel dapat menyimpulkan identitas DM mirip-pemilik yang stabil dari config yang ada, gunakan `createResolvedApproverActionAuthAdapter` dari `openclaw/plugin-sdk/approval-runtime` untuk membatasi `/approve` chat yang sama tanpa menambahkan logika khusus persetujuan ke core.
- Jika channel memerlukan pengiriman persetujuan native, tetap fokuskan kode channel pada normalisasi target plus fakta transport/presentasi. Gunakan `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver`, dan `createApproverRestrictedNativeApprovalCapability` dari `openclaw/plugin-sdk/approval-runtime`. Letakkan fakta khusus channel di balik `approvalCapability.nativeRuntime`, idealnya melalui `createChannelApprovalNativeRuntimeAdapter(...)` atau `createLazyChannelApprovalNativeRuntimeAdapter(...)`, agar core dapat menyusun handler dan memiliki pemfilteran permintaan, perutean, dedupe, kedaluwarsa, subscription gateway, dan pemberitahuan dialihkan-ke-tempat-lain. `nativeRuntime` dibagi menjadi beberapa seam yang lebih kecil:
- `availability` — apakah akun dikonfigurasi dan apakah permintaan harus ditangani
- `presentation`petakan model tampilan persetujuan bersama ke payload native pending/resolved/expired atau tindakan akhir
- `transport`siapkan target plus kirim/perbarui/hapus pesan persetujuan native
- `interactions` — hook bind/unbind/clear-action opsional untuk tombol atau reaksi native
- `observe` — hook diagnostik pengiriman opsional
- Jika channel memerlukan objek milik runtime seperti klien, token, aplikasi Bolt, atau penerima webhook, daftarkan objek itu melalui `openclaw/plugin-sdk/channel-runtime-context`. Registri runtime-context generik memungkinkan inti melakukan bootstrap handler berbasis capability dari status startup channel tanpa menambahkan glue wrapper khusus persetujuan.
- Gunakan `createChannelApprovalHandler` atau `createChannelNativeApprovalRuntime` tingkat lebih rendah hanya ketika seam berbasis capability belum cukup ekspresif.
- Channel persetujuan native harus merutekan `accountId` dan `approvalKind` melalui helper tersebut. `accountId` menjaga kebijakan persetujuan multi-akun tetap bercakupan ke akun bot yang benar, dan `approvalKind` menjaga perilaku persetujuan exec vs plugin tetap tersedia bagi channel tanpa cabang hardcoded di inti.
- Inti kini juga memiliki pemberitahuan pengalihan persetujuan. Plugin channel tidak boleh mengirim pesan tindak lanjut mereka sendiri seperti "persetujuan dikirim ke DM / channel lain" dari `createChannelNativeApprovalRuntime`; sebaliknya, tampilkan routing DM origin + approver yang akurat melalui helper capability persetujuan bersama dan biarkan inti mengagregasi pengiriman aktual sebelum memposting pemberitahuan kembali ke chat pemicu.
- Pertahankan jenis id persetujuan yang dikirim dari awal sampai akhir. Klien native tidak boleh
menebak atau menulis ulang routing persetujuan exec vs plugin dari status lokal channel.
- Jenis persetujuan yang berbeda dapat dengan sengaja mengekspos permukaan native yang berbeda.
Contoh bawaan saat ini:
- Slack menjaga routing persetujuan native tetap tersedia untuk id exec maupun plugin.
- Matrix menjaga routing DM/channel native dan UX reaksi yang sama untuk persetujuan exec
- Jika channel memerlukan objek milik runtime seperti client, token, aplikasi Bolt, atau penerima Webhook, daftarkan melalui `openclaw/plugin-sdk/channel-runtime-context`. Registry runtime-context generik memungkinkan core melakukan bootstrap handler yang digerakkan oleh kapabilitas dari status startup channel tanpa menambahkan glue wrapper khusus persetujuan.
- Gunakan `createChannelApprovalHandler` atau `createChannelNativeApprovalRuntime` tingkat lebih rendah hanya ketika seam yang digerakkan kapabilitas belum cukup ekspresif.
- Channel persetujuan native harus merutekan `accountId` dan `approvalKind` melalui helper tersebut. `accountId` menjaga kebijakan persetujuan multi-akun tetap dicakup ke akun bot yang tepat, dan `approvalKind` menjaga perilaku persetujuan exec vs plugin tetap tersedia bagi channel tanpa cabang yang di-hardcode di core.
- Core sekarang juga memiliki pemberitahuan reroute persetujuan. Plugin channel tidak boleh mengirim pesan tindak lanjut mereka sendiri "persetujuan dikirim ke DM / channel lain" dari `createChannelNativeApprovalRuntime`; sebagai gantinya, tampilkan perutean asal + DM approver yang akurat melalui helper kapabilitas persetujuan bersama dan biarkan core mengagregasi pengiriman aktual sebelum memposting pemberitahuan kembali ke chat pemula.
- Pertahankan jenis id persetujuan yang dikirim dari ujung ke ujung. Client native tidak boleh
menebak atau menulis ulang perutean persetujuan exec vs plugin dari status lokal channel.
- Berbagai jenis persetujuan dapat dengan sengaja mengekspos surface native yang berbeda.
Contoh bundel saat ini:
- Slack menjaga perutean persetujuan native tetap tersedia untuk id exec dan plugin.
- Matrix menjaga perutean DM/channel native dan UX reaksi yang sama untuk persetujuan exec
dan plugin, sambil tetap memungkinkan auth berbeda menurut jenis persetujuan.
- `createApproverRestrictedNativeApprovalAdapter` masih ada sebagai wrapper kompatibilitas, tetapi kode baru sebaiknya menggunakan builder capability dan mengekspos `approvalCapability` pada plugin.
- `createApproverRestrictedNativeApprovalAdapter` masih ada sebagai wrapper kompatibilitas, tetapi kode baru sebaiknya memilih builder kapabilitas dan mengekspos `approvalCapability` pada plugin.
Untuk entrypoint channel yang panas, sebaiknya gunakan subpath runtime yang lebih sempit ketika Anda hanya
Untuk entrypoint channel yang hot, pilih subpath runtime yang lebih sempit saat Anda hanya
memerlukan satu bagian dari keluarga itu:
- `openclaw/plugin-sdk/approval-auth-runtime`
@ -120,29 +120,35 @@ memerlukan satu bagian dari keluarga itu:
- `openclaw/plugin-sdk/approval-reply-runtime`
- `openclaw/plugin-sdk/channel-runtime-context`
Demikian juga, sebaiknya gunakan `openclaw/plugin-sdk/setup-runtime`,
Demikian juga, pilih `openclaw/plugin-sdk/setup-runtime`,
`openclaw/plugin-sdk/setup-adapter-runtime`,
`openclaw/plugin-sdk/reply-runtime`,
`openclaw/plugin-sdk/reply-dispatch-runtime`,
`openclaw/plugin-sdk/reply-reference`, dan
`openclaw/plugin-sdk/reply-chunking` ketika Anda tidak memerlukan
permukaan umbrella yang lebih luas.
`openclaw/plugin-sdk/reply-chunking` saat Anda tidak memerlukan surface payung
yang lebih luas.
Khusus untuk setup:
- `openclaw/plugin-sdk/setup-runtime` mencakup helper setup yang aman untuk runtime:
adapter patch setup yang aman diimpor (`createPatchedAccountSetupAdapter`,
adaptor patch setup yang aman untuk impor (`createPatchedAccountSetupAdapter`,
`createEnvPatchedAccountSetupAdapter`,
`createSetupInputPresenceValidator`), output lookup-note,
`createSetupInputPresenceValidator`), output catatan lookup,
`promptResolvedAllowFrom`, `splitSetupEntries`, dan builder
setup-proxy terdelegasi
setup-proxy yang didelegasikan
- `openclaw/plugin-sdk/setup-adapter-runtime` adalah
seam adapter sempit yang sadar env untuk `createEnvPatchedAccountSetupAdapter`
- `openclaw/plugin-sdk/channel-setup` mencakup builder setup opsional-install ditambah beberapa primitif yang aman untuk setup:
seam adaptor sadar-env yang sempit untuk `createEnvPatchedAccountSetupAdapter`
- `openclaw/plugin-sdk/channel-setup` mencakup builder setup instalasi-opsional
ditambah beberapa primitif yang aman untuk setup:
`createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`,
Jika channel Anda mendukung setup atau auth berbasis env dan alur startup/config generik
harus mengetahui nama env tersebut sebelum runtime dimuat, deklarasikan nama itu dalam manifes plugin dengan `channelEnvVars`. Simpan `envVars` runtime channel atau konstanta lokal untuk salinan yang ditujukan kepada operator saja.
perlu mengetahui nama env tersebut sebelum runtime dimuat, deklarasikan di
manifest plugin dengan `channelEnvVars`. Simpan `envVars` runtime channel atau konstanta lokal
untuk salinan yang ditujukan kepada operator saja.
Jika channel Anda dapat muncul di `status`, `channels list`, `channels status`, atau pemindaian SecretRef sebelum runtime plugin dimulai, tambahkan `openclaw.setupEntry` di `package.json`. Entrypoint itu harus aman untuk diimpor dalam path perintah read-only dan harus mengembalikan metadata channel, adaptor config yang aman untuk setup, adaptor status, dan metadata target secret channel yang diperlukan untuk ringkasan tersebut. Jangan memulai client, listener, atau runtime transport dari entri setup.
`createOptionalChannelSetupWizard`, `DEFAULT_ACCOUNT_ID`,
`createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, dan
`splitSetupEntries`
@ -151,11 +157,10 @@ harus mengetahui nama env tersebut sebelum runtime dimuat, deklarasikan nama itu
helper setup/config bersama yang lebih berat seperti
`moveSingleAccountChannelSectionToDefaultAccount(...)`
Jika channel Anda hanya ingin mengiklankan "instal plugin ini dulu" di permukaan setup,
sebaiknya gunakan `createOptionalChannelSetupSurface(...)`. Adapter/wizard yang dihasilkan gagal tertutup pada penulisan config dan finalisasi, dan menggunakan ulang pesan install-required yang sama di seluruh validasi, finalisasi, dan salinan tautan docs.
Jika channel Anda hanya ingin mengiklankan "instal plugin ini terlebih dahulu" di
surface setup, pilih `createOptionalChannelSetupSurface(...)`. Adapter/wizard yang dihasilkan gagal tertutup pada penulisan config dan finalisasi, dan menggunakan kembali pesan install-required yang sama di validasi, finalize, dan salinan tautan docs.
Untuk jalur channel panas lainnya, sebaiknya gunakan helper sempit alih-alih
permukaan lama yang lebih luas:
Untuk path channel hot lainnya, pilih helper yang sempit daripada surface lama yang lebih luas:
- `openclaw/plugin-sdk/account-core`,
`openclaw/plugin-sdk/account-id`,
@ -163,27 +168,31 @@ permukaan lama yang lebih luas:
`openclaw/plugin-sdk/account-helpers` untuk config multi-akun dan
fallback akun default
- `openclaw/plugin-sdk/inbound-envelope` dan
`openclaw/plugin-sdk/inbound-reply-dispatch` untuk wiring route/envelope inbound dan
record-and-dispatch
`openclaw/plugin-sdk/inbound-reply-dispatch` untuk route/envelope inbound dan
pengkabelan record-and-dispatch
- `openclaw/plugin-sdk/messaging-targets` untuk parsing/pencocokan target
- `openclaw/plugin-sdk/outbound-media` dan
`openclaw/plugin-sdk/outbound-runtime` untuk pemuatan media plus delegasi identitas/kirim keluar dan perencanaan payload
`openclaw/plugin-sdk/outbound-runtime` untuk pemuatan media plus
delegasi identitas/pengiriman outbound dan perencanaan payload
- `openclaw/plugin-sdk/thread-bindings-runtime` untuk siklus hidup thread-binding
dan pendaftaran adapter
- `openclaw/plugin-sdk/agent-media-payload` hanya ketika tata letak field payload agen/media lama masih diperlukan
- `openclaw/plugin-sdk/telegram-command-config` untuk normalisasi custom-command Telegram, validasi duplikat/konflik, dan kontrak config perintah yang stabil sebagai fallback
dan pendaftaran adaptor
- `openclaw/plugin-sdk/agent-media-payload` hanya ketika tata letak field payload
agent/media lama masih diperlukan
- `openclaw/plugin-sdk/telegram-command-config` untuk normalisasi
custom-command Telegram, validasi duplikat/konflik, dan kontrak config
command yang stabil untuk fallback
Channel khusus auth biasanya dapat berhenti pada jalur default: inti menangani persetujuan dan plugin hanya mengekspos capability outbound/auth. Channel persetujuan native seperti Matrix, Slack, Telegram, dan transport chat kustom harus menggunakan helper native bersama alih-alih membuat siklus hidup persetujuan mereka sendiri.
Channel yang hanya auth biasanya dapat berhenti di path default: core menangani persetujuan dan plugin hanya mengekspos kapabilitas outbound/auth. Channel persetujuan native seperti Matrix, Slack, Telegram, dan transport chat kustom sebaiknya menggunakan helper native bersama alih-alih membuat siklus hidup persetujuan sendiri.
## Kebijakan mention inbound
Pertahankan penanganan mention inbound tetap terpisah dalam dua lapisan:
Pertahankan penanganan mention inbound terbagi dalam dua lapisan:
- pengumpulan bukti milik plugin
- pengumpulan bukti yang dimiliki plugin
- evaluasi kebijakan bersama
Gunakan `openclaw/plugin-sdk/channel-mention-gating` untuk keputusan kebijakan mention.
Gunakan `openclaw/plugin-sdk/channel-inbound` hanya ketika Anda memerlukan barrel helper inbound
Gunakan `openclaw/plugin-sdk/channel-inbound` hanya ketika Anda memerlukan helper inbound
yang lebih luas.
Cocok untuk logika lokal plugin:
@ -191,7 +200,7 @@ Cocok untuk logika lokal plugin:
- deteksi balasan-ke-bot
- deteksi kutipan-bot
- pemeriksaan partisipasi thread
- pengecualian pesan layanan/sistem
- pengecualian service/system-message
- cache native platform yang diperlukan untuk membuktikan partisipasi bot
Cocok untuk helper bersama:
@ -199,14 +208,14 @@ Cocok untuk helper bersama:
- `requireMention`
- hasil mention eksplisit
- allowlist mention implisit
- bypass perintah
- keputusan skip final
- bypass command
- keputusan akhir untuk skip
Alur yang disarankan:
1. Hitung fakta mention lokal.
2. Oper fakta tersebut ke `resolveInboundMentionDecision({ facts, policy })`.
3. Gunakan `decision.effectiveWasMentioned`, `decision.shouldBypassMention`, dan `decision.shouldSkip` di gerbang inbound Anda.
2. Teruskan fakta tersebut ke `resolveInboundMentionDecision({ facts, policy })`.
3. Gunakan `decision.effectiveWasMentioned`, `decision.shouldBypassMention`, dan `decision.shouldSkip` di gate inbound Anda.
```typescript
import {
@ -246,7 +255,7 @@ if (decision.shouldSkip) return;
```
`api.runtime.channel.mentions` mengekspos helper mention bersama yang sama untuk
plugin channel bawaan yang sudah bergantung pada injeksi runtime:
plugin channel bundel yang sudah bergantung pada injeksi runtime:
- `buildMentionRegexes`
- `matchesMentionPatterns`
@ -256,19 +265,20 @@ plugin channel bawaan yang sudah bergantung pada injeksi runtime:
Jika Anda hanya memerlukan `implicitMentionKindWhen` dan
`resolveInboundMentionDecision`, impor dari
`openclaw/plugin-sdk/channel-mention-gating` untuk menghindari memuat helper runtime inbound lain yang tidak terkait.
`openclaw/plugin-sdk/channel-mention-gating` untuk menghindari memuat helper runtime
inbound yang tidak terkait.
Helper lama `resolveMentionGating*` tetap ada di
`openclaw/plugin-sdk/channel-inbound` hanya sebagai ekspor kompatibilitas. Kode baru
Helper `resolveMentionGating*` yang lebih lama tetap ada di
`openclaw/plugin-sdk/channel-inbound` sebagai ekspor kompatibilitas saja. Kode baru
sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
## Panduan langkah demi langkah
<Steps>
<a id="step-1-package-and-manifest"></a>
<Step title="Paket dan manifes">
<Step title="Paket dan manifest">
Buat file plugin standar. Field `channel` di `package.json` adalah
yang menjadikan ini plugin channel. Untuk permukaan metadata paket lengkap,
yang menjadikan ini plugin channel. Untuk surface metadata paket lengkap,
lihat [Penyiapan dan Config Plugin](/id/plugins/sdk-setup#openclaw-channel):
<CodeGroup>
@ -283,7 +293,7 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
"channel": {
"id": "acme-chat",
"label": "Acme Chat",
"blurb": "Hubungkan OpenClaw ke Acme Chat."
"blurb": "Connect OpenClaw to Acme Chat."
}
}
}
@ -295,7 +305,7 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
"kind": "channel",
"channels": ["acme-chat"],
"name": "Acme Chat",
"description": "Plugin channel Acme Chat",
"description": "Acme Chat channel plugin",
"configSchema": {
"type": "object",
"additionalProperties": false,
@ -319,7 +329,7 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
</Step>
<Step title="Bangun objek plugin channel">
Antarmuka `ChannelPlugin` memiliki banyak permukaan adaptor opsional. Mulailah dengan
Antarmuka `ChannelPlugin` memiliki banyak surface adaptor opsional. Mulailah dengan
yang minimum — `id` dan `setup` — lalu tambahkan adaptor sesuai kebutuhan.
Buat `src/channel.ts`:
@ -330,7 +340,7 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
createChannelPluginBase,
} from "openclaw/plugin-sdk/channel-core";
import type { OpenClawConfig } from "openclaw/plugin-sdk/channel-core";
import { acmeChatApi } from "./client.js"; // klien API platform Anda
import { acmeChatApi } from "./client.js"; // your platform API client
type ResolvedAccount = {
accountId: string | null;
@ -371,7 +381,7 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
},
}),
// Keamanan DM: siapa yang dapat mengirim pesan ke bot
// DM security: who can message the bot
security: {
dm: {
channelKey: "acme-chat",
@ -381,21 +391,21 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
},
},
// Pairing: alur persetujuan untuk kontak DM baru
// Pairing: approval flow for new DM contacts
pairing: {
text: {
idLabel: "username Acme Chat",
message: "Kirim kode ini untuk memverifikasi identitas Anda:",
idLabel: "Acme Chat username",
message: "Send this code to verify your identity:",
notify: async ({ target, code }) => {
await acmeChatApi.sendDm(target, `Pairing code: ${code}`);
},
},
},
// Threading: bagaimana balasan dikirim
// Threading: how replies are delivered
threading: { topLevelReplyToMode: "reply" },
// Outbound: kirim pesan ke platform
// Outbound: send messages to the platform
outbound: {
attachedResults: {
sendText: async (params) => {
@ -419,7 +429,7 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
Alih-alih mengimplementasikan antarmuka adaptor tingkat rendah secara manual, Anda meneruskan
opsi deklaratif dan builder akan menyusunnya:
| Option | What it wires |
| Option | Yang dihubungkan |
| --- | --- |
| `security.dm` | Resolver keamanan DM bercakupan dari field config |
| `pairing.text` | Alur pairing DM berbasis teks dengan pertukaran kode |
@ -442,20 +452,20 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
export default defineChannelPluginEntry({
id: "acme-chat",
name: "Acme Chat",
description: "Plugin channel Acme Chat",
description: "Acme Chat channel plugin",
plugin: acmeChatPlugin,
registerCliMetadata(api) {
api.registerCli(
({ program }) => {
program
.command("acme-chat")
.description("Manajemen Acme Chat");
.description("Acme Chat management");
},
{
descriptors: [
{
name: "acme-chat",
description: "Manajemen Acme Chat",
description: "Acme Chat management",
hasSubcommands: false,
},
],
@ -468,15 +478,15 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
});
```
Letakkan descriptor CLI milik channel di `registerCliMetadata(...)` agar OpenClaw
Letakkan descriptor CLI yang dimiliki channel di `registerCliMetadata(...)` agar OpenClaw
dapat menampilkannya di bantuan root tanpa mengaktifkan runtime channel penuh,
sementara muatan penuh normal tetap mengambil descriptor yang sama untuk pendaftaran
perintah nyata. Pertahankan `registerFull(...)` untuk pekerjaan yang hanya runtime.
Jika `registerFull(...)` mendaftarkan metode gateway RPC, gunakan
prefix khusus plugin. Namespace admin inti (`config.*`,
sementara pemuatan penuh normal tetap mengambil descriptor yang sama untuk pendaftaran
command yang sebenarnya. Pertahankan `registerFull(...)` untuk pekerjaan yang hanya runtime.
Jika `registerFull(...)` mendaftarkan metode RPC Gateway, gunakan
prefix khusus plugin. Namespace admin core (`config.*`,
`exec.approvals.*`, `wizard.*`, `update.*`) tetap dicadangkan dan selalu
di-resolve ke `operator.admin`.
`defineChannelPluginEntry` menangani pemisahan mode registrasi secara otomatis. Lihat
`defineChannelPluginEntry` menangani pemisahan mode pendaftaran secara otomatis. Lihat
[Entry Points](/id/plugins/sdk-entrypoints#definechannelpluginentry) untuk semua
opsi.
@ -492,33 +502,33 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
export default defineSetupPluginEntry(acmeChatPlugin);
```
OpenClaw memuat ini alih-alih entri penuh saat channel dinonaktifkan
atau belum dikonfigurasi. Ini menghindari menarik kode runtime berat selama alur setup.
Lihat [Setup dan Config](/id/plugins/sdk-setup#setup-entry) untuk detail.
OpenClaw memuat ini alih-alih entri penuh ketika channel dinonaktifkan
atau belum dikonfigurasi. Ini menghindari penarikan kode runtime yang berat selama alur setup.
Lihat [Setup and Config](/id/plugins/sdk-setup#setup-entry) untuk detail.
Channel workspace bawaan yang memisahkan ekspor aman-setup ke modul sidecar
Channel workspace bundel yang memisahkan ekspor aman-setup ke modul sidecar
dapat menggunakan `defineBundledChannelSetupEntry(...)` dari
`openclaw/plugin-sdk/channel-entry-contract` ketika juga memerlukan
setter runtime eksplisit saat setup.
setter runtime waktu-setup yang eksplisit.
</Step>
<Step title="Tangani pesan inbound">
Plugin Anda perlu menerima pesan dari platform dan meneruskannya ke
OpenClaw. Pola yang umum adalah webhook yang memverifikasi request dan
mendispatch-nya melalui handler inbound channel Anda:
OpenClaw. Pola yang umum adalah Webhook yang memverifikasi permintaan dan
mengirimkannya melalui handler inbound channel Anda:
```typescript
registerFull(api) {
api.registerHttpRoute({
path: "/acme-chat/webhook",
auth: "plugin", // auth dikelola plugin (verifikasi signature sendiri)
auth: "plugin", // plugin-managed auth (verify signatures yourself)
handler: async (req, res) => {
const event = parseWebhookPayload(req);
// Handler inbound Anda mendispatch pesan ke OpenClaw.
// Wiring tepatnya bergantung pada SDK platform Anda
// lihat contoh nyata di paket plugin Microsoft Teams atau Google Chat bawaan.
// Your inbound handler dispatches the message to OpenClaw.
// The exact wiring depends on your platform SDK
// see a real example in the bundled Microsoft Teams or Google Chat plugin package.
await handleAcmeChatInbound(api, event);
res.statusCode = 200;
@ -531,7 +541,7 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
<Note>
Penanganan pesan inbound bersifat khusus channel. Setiap plugin channel memiliki
pipeline inbound-nya sendiri. Lihat plugin channel bawaan
pipeline inbound-nya sendiri. Lihat plugin channel bundel
(misalnya paket plugin Microsoft Teams atau Google Chat) untuk pola nyata.
</Note>
@ -539,14 +549,14 @@ sebaiknya menggunakan `resolveInboundMentionDecision({ facts, policy })`.
<a id="step-6-test"></a>
<Step title="Uji">
Tulis test yang diletakkan berdampingan di `src/channel.test.ts`:
Tulis pengujian colocated di `src/channel.test.ts`:
```typescript src/channel.test.ts
import { describe, it, expect } from "vitest";
import { acmeChatPlugin } from "./channel.js";
describe("plugin acme-chat", () => {
it("me-resolve akun dari config", () => {
describe("acme-chat plugin", () => {
it("resolves account from config", () => {
const cfg = {
channels: {
"acme-chat": { token: "test-token", allowFrom: ["user1"] },
@ -556,7 +566,7 @@ Tulis test yang diletakkan berdampingan di `src/channel.test.ts`:
expect(account.token).toBe("test-token");
});
it("memeriksa akun tanpa mematerialisasikan secret", () => {
it("inspects account without materializing secrets", () => {
const cfg = {
channels: { "acme-chat": { token: "test-token" } },
} as any;
@ -565,7 +575,7 @@ Tulis test yang diletakkan berdampingan di `src/channel.test.ts`:
expect(result.tokenStatus).toBe("available");
});
it("melaporkan config yang hilang", () => {
it("reports missing config", () => {
const cfg = { channels: {} } as any;
const result = acmeChatPlugin.setup!.inspectAccount!(cfg, undefined);
expect(result.configured).toBe(false);
@ -577,7 +587,7 @@ Tulis test yang diletakkan berdampingan di `src/channel.test.ts`:
pnpm test -- <bundled-plugin-root>/acme-chat/
```
Untuk helper test bersama, lihat [Testing](/id/plugins/sdk-testing).
Untuk helper pengujian bersama, lihat [Testing](/id/plugins/sdk-testing).
</Step>
</Steps>
@ -586,17 +596,17 @@ Tulis test yang diletakkan berdampingan di `src/channel.test.ts`:
```
<bundled-plugin-root>/acme-chat/
├── package.json # metadata openclaw.channel
├── openclaw.plugin.json # Manifes dengan skema config
├── package.json # openclaw.channel metadata
├── openclaw.plugin.json # Manifest with config schema
├── index.ts # defineChannelPluginEntry
├── setup-entry.ts # defineSetupPluginEntry
├── api.ts # Ekspor publik (opsional)
├── runtime-api.ts # Ekspor runtime internal (opsional)
├── api.ts # Public exports (optional)
├── runtime-api.ts # Internal runtime exports (optional)
└── src/
├── channel.ts # ChannelPlugin melalui createChatChannelPlugin
├── channel.test.ts # Test
├── client.ts # Klien API platform
└── runtime.ts # Penyimpanan runtime (jika diperlukan)
├── channel.ts # ChannelPlugin via createChatChannelPlugin
├── channel.test.ts # Tests
├── client.ts # Platform API client
└── runtime.ts # Runtime store (if needed)
```
## Topik lanjutan
@ -605,27 +615,27 @@ Tulis test yang diletakkan berdampingan di `src/channel.test.ts`:
<Card title="Opsi threading" icon="git-branch" href="/id/plugins/sdk-entrypoints#registration-mode">
Mode balasan tetap, bercakupan akun, atau kustom
</Card>
<Card title="Integrasi tool message" icon="puzzle" href="/id/plugins/architecture#channel-plugins-and-the-shared-message-tool">
describeMessageTool dan penemuan action
<Card title="Integrasi tool pesan" icon="puzzle" href="/id/plugins/architecture#channel-plugins-and-the-shared-message-tool">
describeMessageTool dan penemuan tindakan
</Card>
<Card title="Resolusi target" icon="crosshair" href="/id/plugins/architecture#channel-target-resolution">
inferTargetChatType, looksLikeId, resolveTarget
</Card>
<Card title="Helper runtime" icon="settings" href="/id/plugins/sdk-runtime">
TTS, STT, media, subagen melalui api.runtime
TTS, STT, media, subagent melalui api.runtime
</Card>
</CardGroup>
<Note>
Beberapa seam helper bawaan masih ada untuk pemeliharaan plugin bawaan dan
kompatibilitas. Itu bukan pola yang disarankan untuk plugin channel baru;
sebaiknya gunakan subpath channel/setup/reply/runtime generik dari permukaan SDK
umum kecuali Anda memang memelihara keluarga plugin bawaan itu secara langsung.
Beberapa seam helper bundel masih ada untuk pemeliharaan plugin bundel dan
kompatibilitas. Itu bukan pola yang direkomendasikan untuk plugin channel baru;
pilih subpath channel/setup/reply/runtime generik dari surface SDK umum
kecuali Anda memang memelihara keluarga plugin bundel tersebut secara langsung.
</Note>
## Langkah berikutnya
- [Plugin Provider](/id/plugins/sdk-provider-plugins) — jika plugin Anda juga menyediakan model
- [Ringkasan SDK](/id/plugins/sdk-overview) — referensi impor subpath lengkap
- [SDK Testing](/id/plugins/sdk-testing) — utilitas test dan test kontrak
- [Manifes Plugin](/id/plugins/manifest) — skema manifes lengkap
- [Ikhtisar SDK](/id/plugins/sdk-overview) — referensi impor subpath lengkap
- [Pengujian SDK](/id/plugins/sdk-testing) — utilitas pengujian dan uji kontrak
- [Manifest Plugin](/id/plugins/manifest) — skema manifest lengkap

View File

@ -1,31 +1,27 @@
---
read_when:
- Anda ingin menggunakan GitHub Copilot sebagai provider model
- Anda ingin menggunakan GitHub Copilot sebagai penyedia model
- Anda memerlukan alur `openclaw models auth login-github-copilot`
summary: Masuk ke GitHub Copilot dari OpenClaw menggunakan device flow
summary: Masuk ke GitHub Copilot dari OpenClaw menggunakan alur perangkat
title: GitHub Copilot
x-i18n:
generated_at: "2026-04-21T09:22:49Z"
generated_at: "2026-04-21T19:20:47Z"
model: gpt-5.4
provider: openai
source_hash: f7faafbd3bdcd8886e75fb0d40c3eec66355df3fca6160ebbbb9a0018b7839fe
source_hash: b5169839322f64b24b194302b61c5bad67c6cb6595989f9a1ef65867d8b68659
source_path: providers/github-copilot.md
workflow: 15
---
# GitHub Copilot
GitHub Copilot adalah asisten coding AI dari GitHub. Ini menyediakan akses ke model
Copilot untuk akun dan paket GitHub Anda. OpenClaw dapat menggunakan Copilot sebagai provider model
dengan dua cara berbeda.
GitHub Copilot adalah asisten coding AI dari GitHub. Ini menyediakan akses ke model Copilot untuk akun dan paket GitHub Anda. OpenClaw dapat menggunakan Copilot sebagai penyedia model dengan dua cara yang berbeda.
## Dua cara menggunakan Copilot di OpenClaw
## Dua cara untuk menggunakan Copilot di OpenClaw
<Tabs>
<Tab title="Provider bawaan (github-copilot)">
Gunakan alur login perangkat native untuk memperoleh token GitHub, lalu menukarnya dengan
token API Copilot saat OpenClaw berjalan. Ini adalah jalur **default** dan paling sederhana
karena tidak memerlukan VS Code.
<Tab title="Built-in provider (github-copilot)">
Gunakan alur login perangkat bawaan untuk mendapatkan token GitHub, lalu menukarkannya dengan token API Copilot saat OpenClaw berjalan. Ini adalah jalur **default** dan paling sederhana karena tidak memerlukan VS Code.
<Steps>
<Step title="Jalankan perintah login">
@ -33,12 +29,11 @@ dengan dua cara berbeda.
openclaw models auth login-github-copilot
```
Anda akan diminta mengunjungi URL dan memasukkan kode satu kali. Biarkan
terminal tetap terbuka sampai selesai.
Anda akan diminta untuk mengunjungi URL dan memasukkan kode sekali pakai. Biarkan terminal tetap terbuka sampai selesai.
</Step>
<Step title="Setel model default">
<Step title="Tetapkan model default">
```bash
openclaw models set github-copilot/claude-opus-4.6
openclaw models set github-copilot/claude-opus-4.7
```
Atau di config:
@ -46,7 +41,7 @@ dengan dua cara berbeda.
```json5
{
agents: {
defaults: { model: { primary: "github-copilot/claude-opus-4.6" } },
defaults: { model: { primary: "github-copilot/claude-opus-4.7" } },
},
}
```
@ -55,13 +50,11 @@ dengan dua cara berbeda.
</Tab>
<Tab title="Plugin Copilot Proxy (copilot-proxy)">
Gunakan extension VS Code **Copilot Proxy** sebagai bridge lokal. OpenClaw berbicara ke
endpoint `/v1` milik proxy dan menggunakan daftar model yang Anda konfigurasikan di sana.
<Tab title="Copilot Proxy plugin (copilot-proxy)">
Gunakan ekstensi VS Code **Copilot Proxy** sebagai jembatan lokal. OpenClaw berkomunikasi dengan endpoint `/v1` milik proxy dan menggunakan daftar model yang Anda konfigurasi di sana.
<Note>
Pilih ini saat Anda sudah menjalankan Copilot Proxy di VS Code atau perlu merutekan
melaluinya. Anda harus mengaktifkan Plugin dan menjaga extension VS Code tetap berjalan.
Pilih ini jika Anda sudah menjalankan Copilot Proxy di VS Code atau perlu merutekan melalui itu. Anda harus mengaktifkan Plugin dan menjaga ekstensi VS Code tetap berjalan.
</Note>
</Tab>
@ -69,77 +62,62 @@ dengan dua cara berbeda.
## Flag opsional
| Flag | Deskripsi |
| --------------- | --------------------------------------------------- |
| `--yes` | Lewati prompt konfirmasi |
| `--set-default` | Terapkan juga model default yang direkomendasikan provider |
| Flag | Deskripsi |
| --------------- | ------------------------------------------------- |
| `--yes` | Lewati prompt konfirmasi |
| `--set-default` | Juga terapkan model default yang direkomendasikan penyedia |
```bash
# Lewati konfirmasi
openclaw models auth login-github-copilot --yes
# Login dan setel model default dalam satu langkah
# Login dan tetapkan model default dalam satu langkah
openclaw models auth login --provider github-copilot --method device --set-default
```
<AccordionGroup>
<Accordion title="TTY interaktif diperlukan">
Alur login perangkat memerlukan TTY interaktif. Jalankan langsung di
terminal, bukan dalam skrip non-interaktif atau pipeline CI.
Alur login perangkat memerlukan TTY interaktif. Jalankan langsung di terminal, bukan dalam skrip non-interaktif atau pipeline CI.
</Accordion>
<Accordion title="Ketersediaan model bergantung pada paket Anda">
Ketersediaan model Copilot bergantung pada paket GitHub Anda. Jika suatu model
ditolak, coba ID lain (misalnya `github-copilot/gpt-4.1`).
Ketersediaan model Copilot bergantung pada paket GitHub Anda. Jika suatu model ditolak, coba ID lain (misalnya `github-copilot/gpt-4.1`).
</Accordion>
<Accordion title="Pemilihan transport">
ID model Claude secara otomatis menggunakan transport Anthropic Messages. GPT,
model o-series, dan Gemini tetap menggunakan transport OpenAI Responses. OpenClaw
memilih transport yang benar berdasarkan ref model.
ID model Claude menggunakan transport Anthropic Messages secara otomatis. Model GPT, o-series, dan Gemini tetap menggunakan transport OpenAI Responses. OpenClaw memilih transport yang benar berdasarkan ref model.
</Accordion>
<Accordion title="Urutan prioritas resolusi variabel environment">
OpenClaw me-resolve auth Copilot dari variabel environment dalam
urutan prioritas berikut:
<Accordion title="Urutan resolusi variabel lingkungan">
OpenClaw menyelesaikan auth Copilot dari variabel lingkungan dalam urutan prioritas berikut:
| Priority | Variable | Notes |
| -------- | --------------------- | -------------------------------- |
| 1 | `COPILOT_GITHUB_TOKEN` | Prioritas tertinggi, khusus Copilot |
| 2 | `GH_TOKEN` | Token GitHub CLI (fallback) |
| 3 | `GITHUB_TOKEN` | Token GitHub standar (terendah) |
| Prioritas | Variabel | Catatan |
| --------- | --------------------- | ------------------------------- |
| 1 | `COPILOT_GITHUB_TOKEN` | Prioritas tertinggi, khusus Copilot |
| 2 | `GH_TOKEN` | Token GitHub CLI (fallback) |
| 3 | `GITHUB_TOKEN` | Token GitHub standar (terendah) |
Saat beberapa variabel diatur, OpenClaw menggunakan yang berprioritas tertinggi.
Alur login perangkat (`openclaw models auth login-github-copilot`) menyimpan
tokennya di auth profile store dan didahulukan daripada semua variabel
environment.
Saat beberapa variabel ditetapkan, OpenClaw menggunakan yang berprioritas tertinggi. Alur login perangkat (`openclaw models auth login-github-copilot`) menyimpan tokennya di penyimpanan profil auth dan didahulukan daripada semua variabel lingkungan.
</Accordion>
<Accordion title="Penyimpanan token">
Login menyimpan token GitHub di auth profile store dan menukarnya
dengan token API Copilot saat OpenClaw berjalan. Anda tidak perlu mengelola
token secara manual.
Login menyimpan token GitHub di penyimpanan profil auth dan menukarkannya dengan token API Copilot saat OpenClaw berjalan. Anda tidak perlu mengelola token secara manual.
</Accordion>
</AccordionGroup>
<Warning>
Memerlukan TTY interaktif. Jalankan perintah login langsung di terminal, bukan
di dalam skrip headless atau job CI.
Memerlukan TTY interaktif. Jalankan perintah login langsung di terminal, bukan di dalam skrip headless atau job CI.
</Warning>
## Embedding pencarian memori
GitHub Copilot juga dapat berfungsi sebagai provider embedding untuk
[pencarian memori](/id/concepts/memory-search). Jika Anda memiliki langganan Copilot dan
sudah login, OpenClaw dapat menggunakannya untuk embedding tanpa API key terpisah.
GitHub Copilot juga dapat berfungsi sebagai penyedia embedding untuk
[pencarian memori](/id/concepts/memory-search). Jika Anda memiliki langganan Copilot dan sudah login, OpenClaw dapat menggunakannya untuk embedding tanpa API key terpisah.
### Deteksi otomatis
Saat `memorySearch.provider` adalah `"auto"` (default), GitHub Copilot dicoba
pada prioritas 15 -- setelah embedding lokal tetapi sebelum OpenAI dan provider
berbayar lainnya. Jika token GitHub tersedia, OpenClaw menemukan model
embedding yang tersedia dari API Copilot dan memilih yang terbaik secara otomatis.
Saat `memorySearch.provider` adalah `"auto"` (default), GitHub Copilot dicoba pada prioritas 15 -- setelah embedding lokal tetapi sebelum OpenAI dan penyedia berbayar lainnya. Jika token GitHub tersedia, OpenClaw menemukan model embedding yang tersedia dari API Copilot dan memilih yang terbaik secara otomatis.
### Config eksplisit
@ -149,7 +127,7 @@ embedding yang tersedia dari API Copilot dan memilih yang terbaik secara otomati
defaults: {
memorySearch: {
provider: "github-copilot",
// Opsional: override model yang ditemukan otomatis
// Opsional: timpa model yang ditemukan secara otomatis
model: "text-embedding-3-small",
},
},
@ -159,22 +137,21 @@ embedding yang tersedia dari API Copilot dan memilih yang terbaik secara otomati
### Cara kerjanya
1. OpenClaw me-resolve token GitHub Anda (dari env var atau auth profile).
2. Menukarnya dengan token API Copilot berumur pendek.
3. Mengkueri endpoint `/models` Copilot untuk menemukan model embedding yang tersedia.
1. OpenClaw menyelesaikan token GitHub Anda (dari variabel lingkungan atau profil auth).
2. Menukarkannya dengan token API Copilot berumur pendek.
3. Mengueri endpoint Copilot `/models` untuk menemukan model embedding yang tersedia.
4. Memilih model terbaik (mengutamakan `text-embedding-3-small`).
5. Mengirim permintaan embedding ke endpoint `/embeddings` Copilot.
5. Mengirim permintaan embedding ke endpoint Copilot `/embeddings`.
Ketersediaan model bergantung pada paket GitHub Anda. Jika tidak ada model embedding
yang tersedia, OpenClaw melewati Copilot dan mencoba provider berikutnya.
Ketersediaan model bergantung pada paket GitHub Anda. Jika tidak ada model embedding yang tersedia, OpenClaw melewati Copilot dan mencoba penyedia berikutnya.
## Terkait
<CardGroup cols={2}>
<Card title="Pemilihan model" href="/id/concepts/model-providers" icon="layers">
Memilih provider, ref model, dan perilaku failover.
Memilih penyedia, ref model, dan perilaku failover.
</Card>
<Card title="OAuth and auth" href="/id/gateway/authentication" icon="key">
<Card title="OAuth dan auth" href="/id/gateway/authentication" icon="key">
Detail auth dan aturan penggunaan ulang kredensial.
</Card>
</CardGroup>

View File

@ -1,26 +1,26 @@
---
read_when:
- Anda menginginkan pekerjaan latar belakang/paralel melalui agen
- Anda sedang mengubah sessions_spawn atau kebijakan tool sub-agen
- Anda sedang mengimplementasikan atau memecahkan masalah sesi subagen yang terikat thread
summary: 'Sub-agen: men-spawn eksekusi agen terisolasi yang mengumumkan hasil kembali ke chat peminta'
title: Sub-Agen
- Anda ingin pekerjaan latar belakang/paralel melalui agen
- Anda sedang mengubah kebijakan alat `sessions_spawn` atau sub-agent
- Anda sedang mengimplementasikan atau memecahkan masalah sesi subagent yang terikat ke thread
summary: 'Sub-agent: menjalankan agen terisolasi yang mengumumkan hasil kembali ke chat peminta'
title: Sub-Agent
x-i18n:
generated_at: "2026-04-05T14:09:53Z"
generated_at: "2026-04-21T19:20:52Z"
model: gpt-5.4
provider: openai
source_hash: 9df7cc35a3069ce4eb9c92a95df3ce5365a00a3fae92ff73def75461b58fec3f
source_hash: 218913f0db88d40e1b5fdb0201b8d23e7af23df572c86ff4be2637cb62498281
source_path: tools/subagents.md
workflow: 15
---
# Sub-agen
# Sub-agent
Sub-agen adalah eksekusi agen latar belakang yang di-spawn dari eksekusi agen yang sudah ada. Mereka berjalan dalam sesi mereka sendiri (`agent:<agentId>:subagent:<uuid>`) dan, saat selesai, **mengumumkan** hasilnya kembali ke channel chat peminta. Setiap eksekusi sub-agen dilacak sebagai [tugas latar belakang](/id/automation/tasks).
Sub-agent adalah eksekusi agen latar belakang yang di-spawn dari eksekusi agen yang sudah ada. Mereka berjalan dalam sesi mereka sendiri (`agent:<agentId>:subagent:<uuid>`) dan, ketika selesai, **mengumumkan** hasilnya kembali ke channel chat peminta. Setiap eksekusi sub-agent dilacak sebagai [tugas latar belakang](/id/automation/tasks).
## Slash command
## Perintah slash
Gunakan `/subagents` untuk memeriksa atau mengendalikan eksekusi sub-agen untuk **sesi saat ini**:
Gunakan `/subagents` untuk memeriksa atau mengontrol eksekusi sub-agent untuk **sesi saat ini**:
- `/subagents list`
- `/subagents kill <id|#|all>`
@ -30,9 +30,9 @@ Gunakan `/subagents` untuk memeriksa atau mengendalikan eksekusi sub-agen untuk
- `/subagents steer <id|#> <message>`
- `/subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]`
Kontrol binding thread:
Kontrol pengikatan thread:
Perintah ini bekerja pada channel yang mendukung binding thread persisten. Lihat **Channel yang mendukung thread** di bawah.
Perintah ini berfungsi pada channel yang mendukung pengikatan thread persisten. Lihat **Channel yang mendukung thread** di bawah.
- `/focus <subagent-label|session-key|session-id|session-label>`
- `/unfocus`
@ -40,129 +40,129 @@ Perintah ini bekerja pada channel yang mendukung binding thread persisten. Lihat
- `/session idle <duration|off>`
- `/session max-age <duration|off>`
`/subagents info` menampilkan metadata eksekusi (status, timestamp, session id, path transkrip, cleanup).
`/subagents info` menampilkan metadata eksekusi (status, cap waktu, id sesi, path transkrip, pembersihan).
Gunakan `sessions_history` untuk tampilan recall yang dibatasi dan difilter demi keamanan; periksa
path transkrip di disk saat Anda memerlukan transkrip mentah lengkap.
### Perilaku spawn
`/subagents spawn` memulai sub-agen latar belakang sebagai perintah pengguna, bukan relay internal, dan mengirim satu pembaruan penyelesaian final kembali ke chat peminta saat eksekusi selesai.
`/subagents spawn` memulai sub-agent latar belakang sebagai perintah pengguna, bukan relay internal, dan mengirim satu pembaruan penyelesaian final kembali ke chat peminta saat eksekusi selesai.
- Perintah spawn bersifat non-blocking; perintah ini langsung mengembalikan run id.
- Saat selesai, sub-agen mengumumkan ringkasan/pesan hasil kembali ke channel chat peminta.
- Pengiriman penyelesaian berbasis push. Setelah di-spawn, jangan polling `/subagents list`,
`sessions_list`, atau `sessions_history` dalam loop hanya untuk menunggu
selesai; periksa status hanya bila diperlukan untuk debugging atau intervensi.
- Saat selesai, OpenClaw berupaya sebaik mungkin menutup tab/proses browser yang dilacak yang dibuka oleh sesi sub-agen tersebut sebelum alur cleanup announce berlanjut.
- Perintah spawn bersifat non-blocking; perintah ini langsung mengembalikan id eksekusi.
- Saat selesai, sub-agent mengumumkan pesan ringkasan/hasil kembali ke channel chat peminta.
- Pengiriman penyelesaian berbasis push. Setelah di-spawn, jangan melakukan polling `/subagents list`,
`sessions_list`, atau `sessions_history` dalam loop hanya untuk menunggu penyelesaian;
periksa status hanya sesuai kebutuhan untuk debugging atau intervensi.
- Saat selesai, OpenClaw melakukan best-effort untuk menutup tab/proses browser yang dilacak yang dibuka oleh sesi sub-agent tersebut sebelum alur pembersihan pengumuman berlanjut.
- Untuk spawn manual, pengiriman bersifat tangguh:
- OpenClaw mencoba pengiriman `agent` langsung terlebih dahulu dengan key idempotensi yang stabil.
- Jika pengiriman langsung gagal, OpenClaw fallback ke routing antrean.
- Jika routing antrean masih tidak tersedia, announce dicoba ulang dengan exponential backoff singkat sebelum akhirnya menyerah.
- Pengiriman penyelesaian mempertahankan rute peminta yang telah diresolusikan:
- rute penyelesaian yang terikat thread atau percakapan menang bila tersedia
- jika asal penyelesaian hanya menyediakan channel, OpenClaw mengisi target/akun yang hilang dari rute terresolusikan sesi peminta (`lastChannel` / `lastTo` / `lastAccountId`) sehingga pengiriman langsung tetap berfungsi
- Handoff penyelesaian ke sesi peminta adalah konteks internal yang dihasilkan runtime (bukan teks buatan pengguna) dan mencakup:
- `Result` (teks balasan `assistant` terbaru yang terlihat, atau jika tidak ada, teks tool/toolResult terbaru yang sudah disanitasi)
- OpenClaw mencoba pengiriman `agent` langsung terlebih dahulu dengan kunci idempoten yang stabil.
- Jika pengiriman langsung gagal, OpenClaw beralih ke perutean antrean.
- Jika perutean antrean masih tidak tersedia, pengumuman dicoba lagi dengan exponential backoff singkat sebelum akhirnya menyerah.
- Pengiriman penyelesaian mempertahankan rute peminta yang telah diselesaikan:
- rute penyelesaian yang terikat thread atau terikat percakapan diprioritaskan saat tersedia
- jika asal penyelesaian hanya menyediakan channel, OpenClaw mengisi target/akun yang hilang dari rute terselesaikan sesi peminta (`lastChannel` / `lastTo` / `lastAccountId`) agar pengiriman langsung tetap berfungsi
- Handoff penyelesaian ke sesi peminta adalah konteks internal yang dibuat saat runtime (bukan teks buatan pengguna) dan mencakup:
- `Result` (teks balasan `assistant` terlihat terbaru, atau jika tidak ada, teks tool/toolResult terbaru yang telah disanitasi; eksekusi gagal terminal tidak menggunakan ulang teks balasan yang tertangkap)
- `Status` (`completed successfully` / `failed` / `timed out` / `unknown`)
- statistik runtime/token yang ringkas
- instruksi pengiriman yang memberi tahu agen peminta untuk menulis ulang dalam suara asisten normal (bukan meneruskan metadata internal mentah)
- `--model` dan `--thinking` meng-override default untuk eksekusi spesifik tersebut.
- statistik runtime/token ringkas
- instruksi pengiriman yang memberitahu agen peminta untuk menulis ulang dengan suara assistant normal (bukan meneruskan metadata internal mentah)
- `--model` dan `--thinking` menimpa default untuk eksekusi spesifik tersebut.
- Gunakan `info`/`log` untuk memeriksa detail dan output setelah selesai.
- `/subagents spawn` adalah mode sekali jalan (`mode: "run"`). Untuk sesi persisten yang terikat thread, gunakan `sessions_spawn` dengan `thread: true` dan `mode: "session"`.
- Untuk sesi harness ACP (Codex, Claude Code, Gemini CLI), gunakan `sessions_spawn` dengan `runtime: "acp"` dan lihat [Agen ACP](/tools/acp-agents).
- Untuk sesi harness ACP (Codex, Claude Code, Gemini CLI), gunakan `sessions_spawn` dengan `runtime: "acp"` dan lihat [ACP Agents](/id/tools/acp-agents).
Tujuan utama:
- Memparalelkan pekerjaan "riset / tugas panjang / tool lambat" tanpa memblokir eksekusi utama.
- Menjaga sub-agen tetap terisolasi secara default (pemisahan sesi + sandboxing opsional).
- Menjaga permukaan tool sulit disalahgunakan: sub-agen **tidak** mendapatkan session tool secara default.
- Menjaga sub-agent tetap terisolasi secara default (pemisahan sesi + sandboxing opsional).
- Menjaga permukaan tool tetap sulit disalahgunakan: sub-agent secara default **tidak** mendapatkan tool sesi.
- Mendukung kedalaman nesting yang dapat dikonfigurasi untuk pola orkestrator.
Catatan biaya: setiap sub-agen memiliki **konteks dan penggunaan tokennya sendiri**. Untuk tugas
yang berat atau berulang, setel model yang lebih murah untuk sub-agen dan pertahankan agen utama Anda pada model berkualitas lebih tinggi.
Catatan biaya: setiap sub-agent memiliki konteks dan penggunaan tokennya **sendiri**. Untuk tugas berat atau berulang,
atur model yang lebih murah untuk sub-agent dan pertahankan agen utama Anda pada model berkualitas lebih tinggi.
Anda dapat mengonfigurasi ini melalui `agents.defaults.subagents.model` atau override per agen.
## Tool
Gunakan `sessions_spawn`:
- Memulai eksekusi sub-agen (`deliver: false`, lane global: `subagent`)
- Lalu menjalankan langkah announce dan memposting balasan announce ke channel chat peminta
- Model default: mewarisi pemanggil kecuali Anda menyetel `agents.defaults.subagents.model` (atau per agen `agents.list[].subagents.model`); `sessions_spawn.model` eksplisit tetap menang.
- Thinking default: mewarisi pemanggil kecuali Anda menyetel `agents.defaults.subagents.thinking` (atau per agen `agents.list[].subagents.thinking`); `sessions_spawn.thinking` eksplisit tetap menang.
- Timeout eksekusi default: jika `sessions_spawn.runTimeoutSeconds` dihilangkan, OpenClaw menggunakan `agents.defaults.subagents.runTimeoutSeconds` bila disetel; jika tidak, fallback ke `0` (tanpa timeout).
- Memulai eksekusi sub-agent (`deliver: false`, lane global: `subagent`)
- Lalu menjalankan langkah pengumuman dan memposting balasan pengumuman ke channel chat peminta
- Model default: mewarisi pemanggil kecuali Anda menetapkan `agents.defaults.subagents.model` (atau `agents.list[].subagents.model` per agen); `sessions_spawn.model` yang eksplisit tetap diprioritaskan.
- Thinking default: mewarisi pemanggil kecuali Anda menetapkan `agents.defaults.subagents.thinking` (atau `agents.list[].subagents.thinking` per agen); `sessions_spawn.thinking` yang eksplisit tetap diprioritaskan.
- Timeout eksekusi default: jika `sessions_spawn.runTimeoutSeconds` dihilangkan, OpenClaw menggunakan `agents.defaults.subagents.runTimeoutSeconds` jika ditetapkan; jika tidak, OpenClaw menggunakan `0` (tanpa timeout).
Parameter tool:
- `task` (wajib)
- `label?` (opsional)
- `agentId?` (opsional; spawn di bawah agent id lain jika diizinkan)
- `model?` (opsional; meng-override model sub-agen; nilai yang tidak valid dilewati dan sub-agen berjalan pada model default dengan peringatan di hasil tool)
- `thinking?` (opsional; meng-override level thinking untuk eksekusi sub-agen)
- `runTimeoutSeconds?` (default ke `agents.defaults.subagents.runTimeoutSeconds` bila disetel, jika tidak `0`; saat disetel, eksekusi sub-agen dibatalkan setelah N detik)
- `thread?` (default `false`; saat `true`, meminta binding thread channel untuk sesi sub-agen ini)
- `agentId?` (opsional; spawn di bawah id agen lain jika diizinkan)
- `model?` (opsional; menimpa model sub-agent; nilai tidak valid dilewati dan sub-agent berjalan pada model default dengan peringatan di hasil tool)
- `thinking?` (opsional; menimpa level thinking untuk eksekusi sub-agent)
- `runTimeoutSeconds?` (default ke `agents.defaults.subagents.runTimeoutSeconds` jika ditetapkan, jika tidak `0`; bila ditetapkan, eksekusi sub-agent dihentikan setelah N detik)
- `thread?` (default `false`; saat `true`, meminta pengikatan thread channel untuk sesi sub-agent ini)
- `mode?` (`run|session`)
- default adalah `run`
- jika `thread: true` dan `mode` dihilangkan, default menjadi `session`
- `mode: "session"` memerlukan `thread: true`
- `cleanup?` (`delete|keep`, default `keep`)
- `sandbox?` (`inherit|require`, default `inherit`; `require` menolak spawn kecuali runtime child target berada dalam sandbox)
- `sandbox?` (`inherit|require`, default `inherit`; `require` menolak spawn kecuali runtime child target disandbox)
- `sessions_spawn` **tidak** menerima parameter pengiriman channel (`target`, `channel`, `to`, `threadId`, `replyTo`, `transport`). Untuk pengiriman, gunakan `message`/`sessions_send` dari eksekusi yang di-spawn.
## Sesi terikat thread
Saat binding thread diaktifkan untuk sebuah channel, sub-agen dapat tetap terikat ke thread sehingga pesan pengguna lanjutan di thread tersebut terus dirutekan ke sesi sub-agen yang sama.
Ketika pengikatan thread diaktifkan untuk suatu channel, sub-agent dapat tetap terikat ke thread sehingga pesan pengguna lanjutan di thread tersebut terus dirutekan ke sesi sub-agent yang sama.
### Channel yang mendukung thread
- Discord (saat ini satu-satunya channel yang didukung): mendukung sesi subagen persisten yang terikat thread (`sessions_spawn` dengan `thread: true`), kontrol thread manual (`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`), dan key adapter `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.idleHours`, `channels.discord.threadBindings.maxAgeHours`, serta `channels.discord.threadBindings.spawnSubagentSessions`.
- Discord (saat ini satu-satunya channel yang didukung): mendukung sesi subagent persisten yang terikat thread (`sessions_spawn` dengan `thread: true`), kontrol thread manual (`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`), dan kunci adaptor `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.idleHours`, `channels.discord.threadBindings.maxAgeHours`, dan `channels.discord.threadBindings.spawnSubagentSessions`.
Alur cepat:
Alur singkat:
1. Spawn dengan `sessions_spawn` menggunakan `thread: true` (dan opsional `mode: "session"`).
2. OpenClaw membuat atau mengikat thread ke target sesi tersebut di channel aktif.
3. Balasan dan pesan lanjutan di thread itu dirutekan ke sesi yang terikat.
4. Gunakan `/session idle` untuk memeriksa/memperbarui auto-unfocus karena tidak aktif dan `/session max-age` untuk mengendalikan batas keras.
5. Gunakan `/unfocus` untuk melepas ikatan secara manual.
3. Balasan dan pesan lanjutan di thread tersebut dirutekan ke sesi yang terikat.
4. Gunakan `/session idle` untuk memeriksa/memperbarui auto-unfocus karena tidak aktif dan `/session max-age` untuk mengontrol batas keras.
5. Gunakan `/unfocus` untuk melepas secara manual.
Kontrol manual:
- `/focus <target>` mengikat thread saat ini (atau membuatnya) ke target sub-agen/sesi.
- `/unfocus` menghapus binding untuk thread terikat saat ini.
- `/agents` menampilkan daftar eksekusi aktif dan status binding (`thread:<id>` atau `unbound`).
- `/session idle` dan `/session max-age` hanya berfungsi untuk thread terikat yang sedang difokuskan.
- `/focus <target>` mengikat thread saat ini (atau membuat thread) ke target sub-agent/sesi.
- `/unfocus` menghapus pengikatan untuk thread saat ini yang sedang terikat.
- `/agents` menampilkan daftar eksekusi aktif dan status pengikatan (`thread:<id>` atau `unbound`).
- `/session idle` dan `/session max-age` hanya berfungsi untuk thread terikat yang sedang fokus.
Sakelar config:
Sakelar konfigurasi:
- Default global: `session.threadBindings.enabled`, `session.threadBindings.idleHours`, `session.threadBindings.maxAgeHours`
- Override channel dan key spawn auto-bind bersifat spesifik adapter. Lihat **Channel yang mendukung thread** di atas.
- Override channel dan kunci auto-bind spawn bersifat spesifik adaptor. Lihat **Channel yang mendukung thread** di atas.
Lihat [Referensi Konfigurasi](/id/gateway/configuration-reference) dan [Slash commands](/tools/slash-commands) untuk detail adapter saat ini.
Lihat [Configuration Reference](/id/gateway/configuration-reference) dan [Slash commands](/id/tools/slash-commands) untuk detail adaptor saat ini.
Allowlist:
Daftar izin:
- `agents.list[].subagents.allowAgents`: daftar agent id yang dapat ditargetkan melalui `agentId` (`["*"]` untuk mengizinkan semua). Default: hanya agen peminta.
- `agents.defaults.subagents.allowAgents`: allowlist agen target default yang digunakan saat agen peminta tidak menetapkan `subagents.allowAgents` sendiri.
- Pelindung pewarisan sandbox: jika sesi peminta berada dalam sandbox, `sessions_spawn` menolak target yang akan berjalan tanpa sandbox.
- `agents.defaults.subagents.requireAgentId` / `agents.list[].subagents.requireAgentId`: saat true, blokir panggilan `sessions_spawn` yang menghilangkan `agentId` (memaksa pemilihan profil eksplisit). Default: false.
- `agents.list[].subagents.allowAgents`: daftar id agen yang dapat ditargetkan melalui `agentId` (`["*"]` untuk mengizinkan semua). Default: hanya agen peminta.
- `agents.defaults.subagents.allowAgents`: daftar izin agen target default yang digunakan saat agen peminta tidak menetapkan `subagents.allowAgents` miliknya sendiri.
- Guard pewarisan sandbox: jika sesi peminta disandbox, `sessions_spawn` menolak target yang akan berjalan tanpa sandbox.
- `agents.defaults.subagents.requireAgentId` / `agents.list[].subagents.requireAgentId`: saat true, memblokir pemanggilan `sessions_spawn` yang menghilangkan `agentId` (memaksa pemilihan profil eksplisit). Default: false.
Discovery:
- Gunakan `agents_list` untuk melihat agent id mana yang saat ini diizinkan untuk `sessions_spawn`.
- Gunakan `agents_list` untuk melihat id agen mana yang saat ini diizinkan untuk `sessions_spawn`.
Auto-archive:
- Sesi sub-agen diarsipkan secara otomatis setelah `agents.defaults.subagents.archiveAfterMinutes` (default: 60).
- Pengarsipan menggunakan `sessions.delete` dan mengganti nama transkrip menjadi `*.deleted.<timestamp>` (folder yang sama).
- `cleanup: "delete"` mengarsipkan segera setelah announce (tetap menyimpan transkrip melalui rename).
- Auto-archive bersifat best-effort; timer yang tertunda hilang jika gateway restart.
- `runTimeoutSeconds` **tidak** melakukan auto-archive; ini hanya menghentikan eksekusi. Sesi tetap ada sampai auto-archive.
- Auto-archive berlaku sama untuk sesi kedalaman 1 dan kedalaman 2.
- Cleanup browser terpisah dari cleanup archive: tab/proses browser yang dilacak ditutup sebaik mungkin saat eksekusi selesai, meskipun catatan transkrip/sesi tetap disimpan.
- Sesi sub-agent diarsipkan secara otomatis setelah `agents.defaults.subagents.archiveAfterMinutes` (default: 60).
- Arsip menggunakan `sessions.delete` dan mengganti nama transkrip menjadi `*.deleted.<timestamp>` (folder yang sama).
- `cleanup: "delete"` langsung mengarsipkan setelah pengumuman (tetap mempertahankan transkrip melalui penggantian nama).
- Auto-archive bersifat best-effort; timer yang tertunda hilang jika Gateway dimulai ulang.
- `runTimeoutSeconds` **tidak** melakukan auto-archive; opsi ini hanya menghentikan eksekusi. Sesi tetap ada hingga auto-archive.
- Auto-archive berlaku sama untuk sesi depth-1 dan depth-2.
- Pembersihan browser terpisah dari pembersihan arsip: tab/proses browser yang dilacak ditutup secara best-effort saat eksekusi selesai, bahkan jika catatan transkrip/sesi tetap disimpan.
## Sub-agen bertingkat
## Nested Sub-Agent
Secara default, sub-agen tidak dapat men-spawn sub-agen mereka sendiri (`maxSpawnDepth: 1`). Anda dapat mengaktifkan satu tingkat nesting dengan menetapkan `maxSpawnDepth: 2`, yang memungkinkan **pola orkestrator**: main → sub-agen orkestrator → sub-sub-agen pekerja.
Secara default, sub-agent tidak dapat melakukan spawn sub-agent mereka sendiri (`maxSpawnDepth: 1`). Anda dapat mengaktifkan satu level nesting dengan menetapkan `maxSpawnDepth: 2`, yang mengizinkan **pola orkestrator**: utama → sub-agent orkestrator → sub-sub-agent pekerja.
### Cara mengaktifkan
@ -171,8 +171,8 @@ Secara default, sub-agen tidak dapat men-spawn sub-agen mereka sendiri (`maxSpaw
agents: {
defaults: {
subagents: {
maxSpawnDepth: 2, // izinkan sub-agen men-spawn child (default: 1)
maxChildrenPerAgent: 5, // child aktif maksimum per sesi agen (default: 5)
maxSpawnDepth: 2, // izinkan sub-agent melakukan spawn child (default: 1)
maxChildrenPerAgent: 5, // maksimum child aktif per sesi agen (default: 5)
maxConcurrent: 8, // batas lane konkurensi global (default: 8)
runTimeoutSeconds: 900, // timeout default untuk sessions_spawn saat dihilangkan (0 = tanpa timeout)
},
@ -181,116 +181,116 @@ Secara default, sub-agen tidak dapat men-spawn sub-agen mereka sendiri (`maxSpaw
}
```
### Tingkat kedalaman
### Level kedalaman
| Kedalaman | Bentuk session key | Peran | Bisa spawn? |
| --------- | -------------------------------------------- | --------------------------------------------- | ------------------------------ |
| 0 | `agent:<id>:main` | Agen utama | Selalu |
| 1 | `agent:<id>:subagent:<uuid>` | Sub-agen (orkestrator bila depth 2 diizinkan) | Hanya jika `maxSpawnDepth >= 2` |
| 2 | `agent:<id>:subagent:<uuid>:subagent:<uuid>` | Sub-sub-agen (pekerja leaf) | Tidak pernah |
| Depth | Bentuk kunci sesi | Peran | Dapat spawn? |
| ----- | -------------------------------------------- | --------------------------------------------- | --------------------------- |
| 0 | `agent:<id>:main` | Agen utama | Selalu |
| 1 | `agent:<id>:subagent:<uuid>` | Sub-agent (orkestrator saat depth 2 diizinkan) | Hanya jika `maxSpawnDepth >= 2` |
| 2 | `agent:<id>:subagent:<uuid>:subagent:<uuid>` | Sub-sub-agent (pekerja leaf) | Tidak pernah |
### Rantai announce
### Rantai pengumuman
Hasil mengalir kembali ke atas rantai:
1. Pekerja kedalaman 2 selesai → announce ke induknya (orkestrator kedalaman 1)
2. Orkestrator kedalaman 1 menerima announce, menyintesis hasil, selesai → announce ke main
3. Agen utama menerima announce dan mengirimkannya ke pengguna
1. Pekerja depth-2 selesai → mengumumkan ke parent-nya (orkestrator depth-1)
2. Orkestrator depth-1 menerima pengumuman, menyintesis hasil, selesai → mengumumkan ke utama
3. Agen utama menerima pengumuman dan mengirimkannya ke pengguna
Setiap tingkat hanya melihat announce dari child langsungnya.
Setiap level hanya melihat pengumuman dari child langsungnya.
Panduan operasional:
- Mulai pekerjaan child sekali dan tunggu event penyelesaian alih-alih membangun loop polling
di sekitar `sessions_list`, `sessions_history`, `/subagents list`, atau
- Mulai pekerjaan child sekali lalu tunggu peristiwa penyelesaian alih-alih membangun loop
polling di sekitar `sessions_list`, `sessions_history`, `/subagents list`, atau
perintah `exec` sleep.
- Jika event penyelesaian child tiba setelah Anda уже mengirim jawaban final,
tindak lanjut yang benar adalah token diam persis `NO_REPLY` / `no_reply`.
- Jika peristiwa penyelesaian child tiba setelah Anda sudah mengirim jawaban final,
tindak lanjut yang benar adalah token senyap persis `NO_REPLY` / `no_reply`.
### Kebijakan tool berdasarkan kedalaman
### Kebijakan tool berdasarkan depth
- Role dan cakupan kontrol ditulis ke metadata sesi saat spawn. Ini mencegah session key datar atau sesi yang dipulihkan secara tidak sengaja mendapatkan kembali hak istimewa orkestrator.
- **Kedalaman 1 (orkestrator, saat `maxSpawnDepth >= 2`)**: Mendapat `sessions_spawn`, `subagents`, `sessions_list`, `sessions_history` sehingga dapat mengelola child-nya. Session/system tool lain tetap ditolak.
- **Kedalaman 1 (leaf, saat `maxSpawnDepth == 1`)**: Tidak ada session tool (perilaku default saat ini).
- **Kedalaman 2 (pekerja leaf)**: Tidak ada session tool — `sessions_spawn` selalu ditolak pada kedalaman 2. Tidak dapat men-spawn child lebih lanjut.
- Peran dan cakupan kontrol ditulis ke metadata sesi saat waktu spawn. Ini mencegah kunci sesi datar atau yang dipulihkan secara tidak sengaja mendapatkan kembali hak istimewa orkestrator.
- **Depth 1 (orkestrator, saat `maxSpawnDepth >= 2`)**: Mendapat `sessions_spawn`, `subagents`, `sessions_list`, `sessions_history` sehingga dapat mengelola child-nya. Tool sesi/sistem lainnya tetap ditolak.
- **Depth 1 (leaf, saat `maxSpawnDepth == 1`)**: Tidak ada tool sesi (perilaku default saat ini).
- **Depth 2 (pekerja leaf)**: Tidak ada tool sesi — `sessions_spawn` selalu ditolak pada depth 2. Tidak dapat melakukan spawn child lebih lanjut.
### Batas spawn per agen
Setiap sesi agen (di kedalaman berapa pun) dapat memiliki paling banyak `maxChildrenPerAgent` (default: 5) child aktif sekaligus. Ini mencegah fan-out tak terkendali dari satu orkestrator.
Setiap sesi agen (pada depth apa pun) dapat memiliki paling banyak `maxChildrenPerAgent` (default: 5) child aktif pada saat yang sama. Ini mencegah fan-out tak terkendali dari satu orkestrator.
### Cascade stop
### Penghentian berantai
Menghentikan orkestrator kedalaman 1 secara otomatis juga menghentikan semua child kedalaman 2 miliknya:
Menghentikan orkestrator depth-1 secara otomatis juga menghentikan semua child depth-2 miliknya:
- `/stop` di chat utama menghentikan semua agen kedalaman 1 dan mencascadekan ke child kedalaman 2 mereka.
- `/subagents kill <id>` menghentikan sub-agen tertentu dan mencascadekan ke child-nya.
- `/subagents kill all` menghentikan semua sub-agen untuk peminta dan mencascadekan.
- `/stop` di chat utama menghentikan semua agen depth-1 dan berantai ke child depth-2 mereka.
- `/subagents kill <id>` menghentikan sub-agent tertentu dan berantai ke child-nya.
- `/subagents kill all` menghentikan semua sub-agent untuk peminta dan berantai.
## Autentikasi
Auth sub-agen diresolusikan berdasarkan **agent id**, bukan berdasarkan tipe sesi:
Autentikasi sub-agent diselesaikan berdasarkan **id agen**, bukan berdasarkan jenis sesi:
- Session key sub-agen adalah `agent:<agentId>:subagent:<uuid>`.
- Penyimpanan auth dimuat dari `agentDir` milik agen tersebut.
- Profil auth agen utama digabungkan sebagai **fallback**; profil agen meng-override profil main jika terjadi konflik.
- Kunci sesi sub-agent adalah `agent:<agentId>:subagent:<uuid>`.
- Penyimpanan auth dimuat dari `agentDir` agen tersebut.
- Profil auth agen utama digabungkan sebagai **fallback**; profil agen menimpa profil utama saat terjadi konflik.
Catatan: penggabungan ini bersifat aditif, sehingga profil main selalu tersedia sebagai fallback. Auth yang sepenuhnya terisolasi per agen belum didukung.
Catatan: penggabungan bersifat aditif, jadi profil utama selalu tersedia sebagai fallback. Auth yang sepenuhnya terisolasi per agen belum didukung.
## Announce
## Pengumuman
Sub-agen melapor kembali melalui langkah announce:
Sub-agent melaporkan kembali melalui langkah pengumuman:
- Langkah announce berjalan di dalam sesi sub-agen (bukan sesi peminta).
- Jika sub-agen membalas tepat `ANNOUNCE_SKIP`, tidak ada yang diposting.
- Jika teks asisten terbaru adalah token diam persis `NO_REPLY` / `no_reply`,
output announce ditekan meskipun sebelumnya ada progres yang terlihat.
- Jika tidak, pengiriman bergantung pada kedalaman peminta:
- sesi peminta tingkat atas menggunakan panggilan `agent` lanjutan dengan pengiriman eksternal (`deliver=true`)
- sesi subagen peminta bertingkat menerima injeksi lanjutan internal (`deliver=false`) sehingga orkestrator dapat menyintesis hasil child di dalam sesi
- jika sesi subagen peminta bertingkat sudah hilang, OpenClaw fallback ke peminta sesi tersebut bila tersedia
- Untuk sesi peminta tingkat atas, pengiriman langsung mode penyelesaian pertama-tama meresolusikan rute percakapan/thread terikat dan hook override, lalu mengisi field target channel yang hilang dari rute tersimpan milik sesi peminta. Ini menjaga penyelesaian tetap pada chat/topik yang benar bahkan ketika asal penyelesaian hanya mengidentifikasi channel.
- Agregasi penyelesaian child dibatasi pada eksekusi peminta saat ini ketika membangun temuan penyelesaian bertingkat, mencegah output child basi dari eksekusi sebelumnya bocor ke announce saat ini.
- Balasan announce mempertahankan routing thread/topik bila tersedia pada adapter channel.
- Konteks announce dinormalisasi menjadi blok event internal yang stabil:
- Langkah pengumuman berjalan di dalam sesi sub-agent (bukan sesi peminta).
- Jika sub-agent membalas tepat `ANNOUNCE_SKIP`, tidak ada yang diposting.
- Jika teks assistant terbaru adalah token senyap persis `NO_REPLY` / `no_reply`,
output pengumuman disembunyikan meskipun sebelumnya ada progres yang terlihat.
- Jika tidak, pengiriman bergantung pada depth peminta:
- sesi peminta level teratas menggunakan panggilan `agent` tindak lanjut dengan pengiriman eksternal (`deliver=true`)
- sesi subagent peminta bertingkat menerima injeksi tindak lanjut internal (`deliver=false`) agar orkestrator dapat menyintesis hasil child di dalam sesi
- jika sesi subagent peminta bertingkat sudah tidak ada, OpenClaw beralih ke peminta sesi tersebut jika tersedia
- Untuk sesi peminta level teratas, pengiriman langsung mode penyelesaian pertama-tama menyelesaikan rute percakapan/thread terikat dan hook override, lalu mengisi field target channel yang hilang dari rute tersimpan sesi peminta. Ini menjaga penyelesaian tetap pada chat/topik yang benar bahkan saat asal penyelesaian hanya mengidentifikasi channel.
- Agregasi penyelesaian child dibatasi ke eksekusi peminta saat ini saat membangun temuan penyelesaian bertingkat, mencegah output child dari eksekusi lama yang sudah usang bocor ke pengumuman saat ini.
- Balasan pengumuman mempertahankan perutean thread/topik saat tersedia pada adaptor channel.
- Konteks pengumuman dinormalisasi menjadi blok peristiwa internal yang stabil:
- sumber (`subagent` atau `cron`)
- child session key/id
- tipe announce + label tugas
- baris status yang diturunkan dari sinyal hasil runtime (`success`, `error`, `timeout`, atau `unknown`)
- konten hasil yang dipilih dari teks asisten terbaru yang terlihat, atau jika tidak ada, teks tool/toolResult terbaru yang sudah disanitasi
- instruksi lanjutan yang menjelaskan kapan harus membalas vs. tetap diam
- kunci/id sesi child
- jenis pengumuman + label tugas
- baris status yang diturunkan dari hasil runtime (`success`, `error`, `timeout`, atau `unknown`)
- konten hasil yang dipilih dari teks assistant terlihat terbaru, atau jika tidak ada, teks tool/toolResult terbaru yang telah disanitasi; eksekusi gagal terminal melaporkan status gagal tanpa memutar ulang teks balasan yang tertangkap
- instruksi tindak lanjut yang menjelaskan kapan harus membalas vs. tetap diam
- `Status` tidak disimpulkan dari output model; status berasal dari sinyal hasil runtime.
- Saat timeout, jika child hanya sempat melalui tool call, announce dapat merangkum riwayat itu menjadi ringkasan progres parsial yang singkat alih-alih memutar ulang output tool mentah.
- Saat timeout, jika child hanya sempat menyelesaikan panggilan tool, pengumuman dapat meringkas riwayat itu menjadi ringkasan progres parsial singkat alih-alih memutar ulang output tool mentah.
Payload announce menyertakan baris statistik di bagian akhir (bahkan saat dibungkus):
Payload pengumuman menyertakan baris statistik di akhir (bahkan saat dibungkus):
- Runtime (misalnya, `runtime 5m12s`)
- Penggunaan token (input/output/total)
- Perkiraan biaya saat harga model dikonfigurasi (`models.providers.*.models[].cost`)
- `sessionKey`, `sessionId`, dan path transkrip (sehingga agen utama dapat mengambil riwayat melalui `sessions_history` atau memeriksa file di disk)
- Metadata internal dimaksudkan hanya untuk orkestrasi; balasan yang menghadap pengguna harus ditulis ulang dalam suara asisten yang normal.
- Estimasi biaya saat harga model dikonfigurasi (`models.providers.*.models[].cost`)
- `sessionKey`, `sessionId`, dan path transkrip (agar agen utama dapat mengambil riwayat melalui `sessions_history` atau memeriksa file di disk)
- Metadata internal dimaksudkan hanya untuk orkestrasi; balasan yang menghadap pengguna harus ditulis ulang dengan suara assistant normal.
`sessions_history` adalah jalur orkestrasi yang lebih aman:
- recall asisten dinormalisasi terlebih dahulu:
- recall assistant dinormalisasi terlebih dahulu:
- tag thinking dihapus
- blok scaffolding `<relevant-memories>` / `<relevant_memories>` dihapus
- blok payload XML tool-call teks biasa seperti `<tool_call>...</tool_call>`,
- blok payload XML panggilan tool teks biasa seperti `<tool_call>...</tool_call>`,
`<function_call>...</function_call>`, `<tool_calls>...</tool_calls>`, dan
`<function_calls>...</function_calls>` dihapus, termasuk payload terpotong
yang tidak pernah tertutup dengan benar
- scaffolding tool-call/result yang diturunkan dan penanda konteks historis dihapus
- scaffolding tool-call/result yang diturunkan levelnya dan penanda konteks historis dihapus
- token kontrol model yang bocor seperti `<|assistant|>`, token ASCII
`<|...|>` lainnya, dan varian lebar penuh `<...>` dihapus
- XML tool-call MiniMax yang malformed dihapus
`<|...|>` lainnya, dan varian full-width `<...>` dihapus
- XML panggilan tool MiniMax yang malformed dihapus
- teks mirip kredensial/token disunting
- blok panjang dapat dipotong
- riwayat yang sangat besar dapat membuang baris lama atau mengganti baris yang terlalu besar dengan
- riwayat yang sangat besar dapat menghapus baris lama atau mengganti baris yang terlalu besar dengan
`[sessions_history omitted: message too large]`
- inspeksi transkrip mentah di disk adalah fallback saat Anda memerlukan transkrip lengkap byte demi byte
- pemeriksaan transkrip mentah di disk adalah fallback saat Anda memerlukan transkrip lengkap byte demi byte
## Kebijakan Tool (tool sub-agen)
## Kebijakan Tool (tool sub-agent)
Secara default, sub-agen mendapatkan **semua tool kecuali session tool** dan system tool:
Secara default, sub-agent mendapatkan **semua tool kecuali tool sesi** dan tool sistem:
- `sessions_list`
- `sessions_history`
@ -300,9 +300,9 @@ Secara default, sub-agen mendapatkan **semua tool kecuali session tool** dan sys
`sessions_history` tetap merupakan tampilan recall yang dibatasi dan disanitasi di sini juga; ini bukan
dump transkrip mentah.
Saat `maxSpawnDepth >= 2`, sub-agen orkestrator kedalaman 1 juga menerima `sessions_spawn`, `subagents`, `sessions_list`, dan `sessions_history` sehingga mereka dapat mengelola child mereka.
Saat `maxSpawnDepth >= 2`, sub-agent orkestrator depth-1 juga menerima `sessions_spawn`, `subagents`, `sessions_list`, dan `sessions_history` sehingga mereka dapat mengelola child mereka.
Override melalui config:
Override melalui konfigurasi:
```json5
{
@ -316,9 +316,9 @@ Override melalui config:
tools: {
subagents: {
tools: {
// deny menang
// deny diprioritaskan
deny: ["gateway", "cron"],
// jika allow disetel, menjadi hanya-allow (deny tetap menang)
// jika allow ditetapkan, menjadi hanya-allow (deny tetap diprioritaskan)
// allow: ["read", "exec", "process"]
},
},
@ -328,21 +328,21 @@ Override melalui config:
## Konkurensi
Sub-agen menggunakan lane antrean khusus di dalam proses:
Sub-agent menggunakan lane antrean in-process khusus:
- Nama lane: `subagent`
- Konkurensi: `agents.defaults.subagents.maxConcurrent` (default `8`)
## Menghentikan
## Penghentian
- Mengirim `/stop` di chat peminta membatalkan sesi peminta dan menghentikan eksekusi sub-agen aktif yang di-spawn darinya, termasuk cascade ke child bertingkat.
- `/subagents kill <id>` menghentikan sub-agen tertentu dan mencascadekan ke child-nya.
- Mengirim `/stop` di chat peminta membatalkan sesi peminta dan menghentikan semua eksekusi sub-agent aktif yang di-spawn darinya, berantai ke child bertingkat.
- `/subagents kill <id>` menghentikan sub-agent tertentu dan berantai ke child-nya.
## Batasan
## Keterbatasan
- Announce sub-agen bersifat **best-effort**. Jika gateway restart, pekerjaan "announce back" yang tertunda akan hilang.
- Sub-agen tetap berbagi sumber daya proses gateway yang sama; perlakukan `maxConcurrent` sebagai katup pengaman.
- `sessions_spawn` selalu non-blocking: langsung mengembalikan `{ status: "accepted", runId, childSessionKey }`.
- Konteks sub-agen hanya menyuntikkan `AGENTS.md` + `TOOLS.md` (tanpa `SOUL.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, atau `BOOTSTRAP.md`).
- Kedalaman nesting maksimum adalah 5 (rentang `maxSpawnDepth`: 15). Kedalaman 2 direkomendasikan untuk sebagian besar kasus penggunaan.
- Pengumuman sub-agent bersifat **best-effort**. Jika gateway dimulai ulang, pekerjaan "mengumumkan kembali" yang tertunda akan hilang.
- Sub-agent tetap berbagi sumber daya proses gateway yang sama; perlakukan `maxConcurrent` sebagai katup pengaman.
- `sessions_spawn` selalu non-blocking: mengembalikan `{ status: "accepted", runId, childSessionKey }` segera.
- Konteks sub-agent hanya menyuntikkan `AGENTS.md` + `TOOLS.md` (tanpa `SOUL.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, atau `BOOTSTRAP.md`).
- Kedalaman nesting maksimum adalah 5 (rentang `maxSpawnDepth`: 15). Depth 2 direkomendasikan untuk sebagian besar kasus penggunaan.
- `maxChildrenPerAgent` membatasi child aktif per sesi (default: 5, rentang: 120).

View File

@ -1,110 +1,110 @@
---
read_when:
- Menyesuaikan parsing atau default direktif thinking, mode cepat, atau verbose
summary: Sintaks direktif untuk `/think`, `/fast`, `/verbose`, `/trace`, dan visibilitas reasoning
title: Level Thinking
summary: Sintaks direktif untuk /think, /fast, /verbose, /trace, dan visibilitas penalaran
title: Tingkat Berpikir
x-i18n:
generated_at: "2026-04-21T09:25:11Z"
generated_at: "2026-04-21T19:21:08Z"
model: gpt-5.4
provider: openai
source_hash: 1b0217f6e5a5cb3400090f31ad5271ca61848a40f77d3f942851e7c2f2352886
source_hash: c77f6f1318c428bbd21725ea5f32f8088506a10cbbf5b5cbca5973c72a5a81f9
source_path: tools/thinking.md
workflow: 15
---
# Level Thinking (direktif `/think`)
# Tingkat Berpikir (direktif `/think`)
## Fungsinya
## Apa fungsinya
- Direktif inline di isi pesan masuk mana pun: `/t <level>`, `/think:<level>`, atau `/thinking <level>`.
- Direktif inline dalam isi masuk apa pun: `/t <level>`, `/think:<level>`, atau `/thinking <level>`.
- Level (alias): `off | minimal | low | medium | high | xhigh | adaptive | max`
- minimal → “think”
- low → “think hard”
- medium → “think harder”
- high → “ultrathink” (anggaran maksimum)
- xhigh → “ultrathink+” (usaha GPT-5.2 + model Codex dan Anthropic Claude Opus 4.7)
- adaptive → thinking adaptif yang dikelola provider (didukung untuk Claude 4.6 di Anthropic/Bedrock dan Anthropic Claude Opus 4.7)
- max → reasoning maksimum dari provider (saat ini Anthropic Claude Opus 4.7)
- xhigh → “ultrathink+” (upaya GPT-5.2 + model Codex dan Anthropic Claude Opus 4.7)
- adaptive → pemikiran adaptif yang dikelola provider (didukung untuk Claude 4.6 pada Anthropic/Bedrock dan Anthropic Claude Opus 4.7)
- max → penalaran maksimum provider (saat ini Anthropic Claude Opus 4.7)
- `x-high`, `x_high`, `extra-high`, `extra high`, dan `extra_high` dipetakan ke `xhigh`.
- `highest` dipetakan ke `high`.
- Catatan provider:
- Menu dan pemilih thinking digerakkan oleh profil provider. Plugin provider mendeklarasikan himpunan level yang tepat untuk model yang dipilih, termasuk label seperti `on` biner.
- `adaptive`, `xhigh`, dan `max` hanya diiklankan untuk profil provider/model yang mendukungnya. Direktif yang diketik untuk level yang tidak didukung akan ditolak dengan opsi valid model tersebut.
- Level tak didukung yang sudah tersimpan, termasuk nilai `max` lama setelah berpindah model, dipetakan ulang ke level terbesar yang didukung untuk model yang dipilih.
- Model Anthropic Claude 4.6 default ke `adaptive` saat tidak ada level thinking eksplisit yang diatur.
- Anthropic Claude Opus 4.7 tidak default ke thinking adaptif. Default effort API-nya tetap dimiliki provider kecuali Anda secara eksplisit menetapkan level thinking.
- Anthropic Claude Opus 4.7 memetakan `/think xhigh` ke thinking adaptif plus `output_config.effort: "xhigh"`, karena `/think` adalah direktif thinking dan `xhigh` adalah pengaturan effort Opus 4.7.
- Anthropic Claude Opus 4.7 juga mengekspos `/think max`; ini dipetakan ke jalur effort maksimum milik provider yang sama.
- Model GPT OpenAI memetakan `/think` melalui dukungan effort Responses API yang spesifik model. `/think off` mengirim `reasoning.effort: "none"` hanya ketika model target mendukungnya; jika tidak, OpenClaw menghilangkan payload reasoning nonaktif alih-alih mengirim nilai yang tidak didukung.
- MiniMax (`minimax/*`) pada jalur streaming yang kompatibel dengan Anthropic default ke `thinking: { type: "disabled" }` kecuali Anda secara eksplisit menetapkan thinking di parameter model atau parameter permintaan. Ini menghindari delta `reasoning_content` yang bocor dari format stream Anthropic non-native milik MiniMax.
- Menu dan pemilih thinking digerakkan oleh profil provider. Plugin provider mendeklarasikan kumpulan level yang tepat untuk model yang dipilih, termasuk label seperti `on` biner.
- `adaptive`, `xhigh`, dan `max` hanya diiklankan untuk profil provider/model yang mendukungnya. Direktif yang diketik untuk level yang tidak didukung ditolak dengan opsi valid untuk model tersebut.
- Level tersimpan yang sudah ada tetapi tidak didukung dipetakan ulang menurut peringkat profil provider. `adaptive` kembali ke `medium` pada model non-adaptif, sedangkan `xhigh` dan `max` kembali ke level non-off terbesar yang didukung untuk model yang dipilih.
- Model Anthropic Claude 4.6 default ke `adaptive` saat tidak ada level thinking eksplisit yang ditetapkan.
- Anthropic Claude Opus 4.7 tidak default ke adaptive thinking. Default upaya API-nya tetap dimiliki provider kecuali Anda secara eksplisit menetapkan level thinking.
- Anthropic Claude Opus 4.7 memetakan `/think xhigh` ke adaptive thinking ditambah `output_config.effort: "xhigh"`, karena `/think` adalah direktif thinking dan `xhigh` adalah pengaturan upaya Opus 4.7.
- Anthropic Claude Opus 4.7 juga mengekspos `/think max`; itu dipetakan ke jalur upaya maksimum milik provider yang sama.
- Model OpenAI GPT memetakan `/think` melalui dukungan upaya Responses API spesifik model. `/think off` mengirim `reasoning.effort: "none"` hanya ketika model target mendukungnya; jika tidak, OpenClaw menghilangkan payload penalaran nonaktif alih-alih mengirim nilai yang tidak didukung.
- MiniMax (`minimax/*`) pada jalur streaming kompatibel Anthropic default ke `thinking: { type: "disabled" }` kecuali Anda secara eksplisit menetapkan thinking dalam parameter model atau parameter permintaan. Ini menghindari delta `reasoning_content` yang bocor dari format stream Anthropic non-native milik MiniMax.
- Z.AI (`zai/*`) hanya mendukung thinking biner (`on`/`off`). Level apa pun selain `off` diperlakukan sebagai `on` (dipetakan ke `low`).
- Moonshot (`moonshot/*`) memetakan `/think off` ke `thinking: { type: "disabled" }` dan level apa pun selain `off` ke `thinking: { type: "enabled" }`. Saat thinking diaktifkan, Moonshot hanya menerima `tool_choice` `auto|none`; OpenClaw menormalkan nilai yang tidak kompatibel ke `auto`.
## Urutan resolusi
1. Direktif inline pada pesan (hanya berlaku untuk pesan itu).
2. Override sesi (diatur dengan mengirim pesan yang hanya berisi direktif).
3. Default per agen (`agents.list[].thinkingDefault` dalam konfigurasi).
4. Default global (`agents.defaults.thinkingDefault` dalam konfigurasi).
5. Fallback: default yang dideklarasikan provider jika tersedia, `low` untuk model katalog lain yang ditandai mendukung reasoning, `off` jika tidak.
1. Direktif inline pada pesan (hanya berlaku untuk pesan tersebut).
2. Override sesi (ditetapkan dengan mengirim pesan yang hanya berisi direktif).
3. Default per-agent (`agents.list[].thinkingDefault` dalam config).
4. Default global (`agents.defaults.thinkingDefault` dalam config).
5. Fallback: default yang dideklarasikan provider jika tersedia, `low` untuk model katalog lain yang ditandai mampu bernalar, atau `off` jika tidak.
## Menetapkan default sesi
- Kirim pesan yang **hanya** berisi direktif tersebut (spasi diperbolehkan), misalnya `/think:medium` atau `/t high`.
- Ini akan menetap untuk sesi saat ini (default-nya per pengirim); dibersihkan dengan `/think:off` atau reset idle sesi.
- Balasan konfirmasi dikirim (`Thinking level set to high.` / `Thinking disabled.`). Jika level tidak valid (misalnya `/thinking big`), perintah ditolak dengan petunjuk dan status sesi dibiarkan tidak berubah.
- Ini akan melekat untuk sesi saat ini (default-nya per-pengirim); dibersihkan dengan `/think:off` atau reset idle sesi.
- Balasan konfirmasi dikirim (`Thinking level set to high.` / `Thinking disabled.`). Jika level tidak valid (misalnya `/thinking big`), perintah ditolak dengan petunjuk dan state sesi dibiarkan tidak berubah.
- Kirim `/think` (atau `/think:`) tanpa argumen untuk melihat level thinking saat ini.
## Penerapan per agen
## Penerapan oleh agent
- **Pi tertanam**: level yang terselesaikan diteruskan ke runtime agen Pi dalam proses.
- **Pi tersemat**: level yang dihasilkan diteruskan ke runtime agent Pi in-process.
## Mode cepat (`/fast`)
- Level: `on|off`.
- Pesan yang hanya berisi direktif mengubah override mode cepat sesi dan membalas `Fast mode enabled.` / `Fast mode disabled.`.
- Kirim `/fast` (atau `/fast status`) tanpa mode untuk melihat status mode cepat efektif saat ini.
- OpenClaw menyelesaikan mode cepat dalam urutan berikut:
- Pesan yang hanya berisi direktif mengalihkan override mode cepat sesi dan membalas `Fast mode enabled.` / `Fast mode disabled.`.
- Kirim `/fast` (atau `/fast status`) tanpa mode untuk melihat state mode cepat efektif saat ini.
- OpenClaw menyelesaikan mode cepat dalam urutan ini:
1. `/fast on|off` inline/hanya-direktif
2. Override sesi
3. Default per agen (`agents.list[].fastModeDefault`)
4. Konfigurasi per model: `agents.defaults.models["<provider>/<model>"].params.fastMode`
3. Default per-agent (`agents.list[].fastModeDefault`)
4. Config per-model: `agents.defaults.models["<provider>/<model>"].params.fastMode`
5. Fallback: `off`
- Untuk `openai/*`, mode cepat dipetakan ke pemrosesan prioritas OpenAI dengan mengirim `service_tier=priority` pada permintaan Responses yang didukung.
- Untuk `openai-codex/*`, mode cepat mengirim flag `service_tier=priority` yang sama pada Codex Responses. OpenClaw mempertahankan satu toggle `/fast` bersama di kedua jalur auth.
- Untuk permintaan `anthropic/*` publik langsung, termasuk lalu lintas terautentikasi OAuth yang dikirim ke `api.anthropic.com`, mode cepat dipetakan ke tier layanan Anthropic: `/fast on` menetapkan `service_tier=auto`, `/fast off` menetapkan `service_tier=standard_only`.
- Untuk `minimax/*` pada jalur yang kompatibel dengan Anthropic, `/fast on` (atau `params.fastMode: true`) menulis ulang `MiniMax-M2.7` menjadi `MiniMax-M2.7-highspeed`.
- Parameter model `serviceTier` / `service_tier` Anthropic yang eksplisit meng-override default mode cepat ketika keduanya diatur. OpenClaw tetap melewati injeksi tier layanan Anthropic untuk base URL proxy non-Anthropic.
- Untuk permintaan publik langsung `anthropic/*`, termasuk trafik terautentikasi OAuth yang dikirim ke `api.anthropic.com`, mode cepat dipetakan ke service tier Anthropic: `/fast on` menetapkan `service_tier=auto`, `/fast off` menetapkan `service_tier=standard_only`.
- Untuk `minimax/*` pada jalur kompatibel Anthropic, `/fast on` (atau `params.fastMode: true`) menulis ulang `MiniMax-M2.7` menjadi `MiniMax-M2.7-highspeed`.
- Parameter model Anthropic `serviceTier` / `service_tier` yang eksplisit menggantikan default mode cepat saat keduanya ditetapkan. OpenClaw tetap melewati penyuntikan service tier Anthropic untuk base URL proxy non-Anthropic.
## Direktif verbose (`/verbose` atau `/v`)
- Level: `on` (minimal) | `full` | `off` (default).
- Pesan yang hanya berisi direktif mengubah verbose sesi dan membalas `Verbose logging enabled.` / `Verbose logging disabled.`; level yang tidak valid mengembalikan petunjuk tanpa mengubah status.
- `/verbose off` menyimpan override sesi eksplisit; hapus melalui UI Sessions dengan memilih `inherit`.
- Direktif inline hanya memengaruhi pesan itu; default sesi/global berlaku untuk kasus lainnya.
- Pesan yang hanya berisi direktif mengalihkan verbose sesi dan membalas `Verbose logging enabled.` / `Verbose logging disabled.`; level yang tidak valid mengembalikan petunjuk tanpa mengubah state.
- `/verbose off` menyimpan override sesi eksplisit; hapus lewat UI Sessions dengan memilih `inherit`.
- Direktif inline hanya memengaruhi pesan itu; default sesi/global berlaku selain itu.
- Kirim `/verbose` (atau `/verbose:`) tanpa argumen untuk melihat level verbose saat ini.
- Saat verbose aktif, agen yang mengeluarkan hasil tool terstruktur (Pi, agen JSON lain) mengirim balik setiap pemanggilan tool sebagai pesan metadata-only terpisah, diawali dengan `<emoji> <tool-name>: <arg>` bila tersedia (jalur/perintah). Ringkasan tool ini dikirim segera saat setiap tool dimulai (bubble terpisah), bukan sebagai delta streaming.
- Saat verbose aktif, agent yang mengeluarkan hasil tool terstruktur (Pi, agent JSON lain) mengirim kembali setiap pemanggilan tool sebagai pesan khusus metadata tersendiri, diawali dengan `<emoji> <tool-name>: <arg>` bila tersedia (path/perintah). Ringkasan tool ini dikirim segera saat setiap tool dimulai (bubble terpisah), bukan sebagai delta streaming.
- Ringkasan kegagalan tool tetap terlihat dalam mode normal, tetapi sufiks detail error mentah disembunyikan kecuali verbose adalah `on` atau `full`.
- Saat verbose adalah `full`, keluaran tool juga diteruskan setelah selesai (bubble terpisah, dipotong ke panjang aman). Jika Anda mengubah `/verbose on|full|off` saat suatu proses sedang berjalan, bubble tool berikutnya akan mengikuti pengaturan baru.
- Saat verbose adalah `full`, output tool juga diteruskan setelah selesai (bubble terpisah, dipotong ke panjang yang aman). Jika Anda mengalihkan `/verbose on|full|off` saat run masih berlangsung, bubble tool berikutnya akan mengikuti pengaturan baru.
## Direktif trace Plugin (`/trace`)
## Direktif jejak Plugin (`/trace`)
- Level: `on` | `off` (default).
- Pesan yang hanya berisi direktif mengubah keluaran trace Plugin sesi dan membalas `Plugin trace enabled.` / `Plugin trace disabled.`.
- Direktif inline hanya memengaruhi pesan itu; default sesi/global berlaku untuk kasus lainnya.
- Kirim `/trace` (atau `/trace:`) tanpa argumen untuk melihat level trace saat ini.
- `/trace` lebih sempit daripada `/verbose`: ini hanya mengekspos baris trace/debug milik Plugin seperti ringkasan debug Active Memory.
- Baris trace dapat muncul di `/status` dan sebagai pesan diagnostik lanjutan setelah balasan asisten normal.
- Pesan yang hanya berisi direktif mengalihkan output jejak Plugin sesi dan membalas `Plugin trace enabled.` / `Plugin trace disabled.`.
- Direktif inline hanya memengaruhi pesan itu; default sesi/global berlaku selain itu.
- Kirim `/trace` (atau `/trace:`) tanpa argumen untuk melihat level jejak saat ini.
- `/trace` lebih sempit daripada `/verbose`: ini hanya mengekspos baris jejak/debug milik Plugin seperti ringkasan debug Active Memory.
- Baris jejak dapat muncul di `/status` dan sebagai pesan diagnostik lanjutan setelah balasan assistant normal.
## Visibilitas reasoning (`/reasoning`)
## Visibilitas penalaran (`/reasoning`)
- Level: `on|off|stream`.
- Pesan yang hanya berisi direktif mengubah apakah blok thinking ditampilkan dalam balasan.
- Saat diaktifkan, reasoning dikirim sebagai **pesan terpisah** yang diawali `Reasoning:`.
- `stream` (khusus Telegram): men-stream reasoning ke bubble draf Telegram saat balasan sedang dihasilkan, lalu mengirim jawaban final tanpa reasoning.
- Pesan yang hanya berisi direktif mengalihkan apakah blok thinking ditampilkan dalam balasan.
- Saat diaktifkan, penalaran dikirim sebagai **pesan terpisah** yang diawali dengan `Reasoning:`.
- `stream` (khusus Telegram): melakukan stream penalaran ke bubble draf Telegram saat balasan sedang dibuat, lalu mengirim jawaban akhir tanpa penalaran.
- Alias: `/reason`.
- Kirim `/reasoning` (atau `/reasoning:`) tanpa argumen untuk melihat level reasoning saat ini.
- Urutan resolusi: direktif inline, lalu override sesi, lalu default per agen (`agents.list[].reasoningDefault`), lalu fallback (`off`).
- Kirim `/reasoning` (atau `/reasoning:`) tanpa argumen untuk melihat level penalaran saat ini.
- Urutan resolusi: direktif inline, lalu override sesi, lalu default per-agent (`agents.list[].reasoningDefault`), lalu fallback (`off`).
## Terkait
@ -112,20 +112,20 @@ x-i18n:
## Heartbeat
- Isi probe Heartbeat adalah prompt Heartbeat yang dikonfigurasi (default: `Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`). Direktif inline dalam pesan Heartbeat berlaku seperti biasa (tetapi hindari mengubah default sesi dari Heartbeat).
- Pengiriman Heartbeat default ke payload final saja. Untuk juga mengirim pesan `Reasoning:` terpisah (jika tersedia), setel `agents.defaults.heartbeat.includeReasoning: true` atau `agents.list[].heartbeat.includeReasoning: true` per agen.
- Isi probe Heartbeat adalah prompt heartbeat yang dikonfigurasi (default: `Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`). Direktif inline dalam pesan heartbeat berlaku seperti biasa (tetapi hindari mengubah default sesi dari heartbeat).
- Pengiriman Heartbeat default-nya hanya payload akhir. Untuk juga mengirim pesan `Reasoning:` terpisah (saat tersedia), tetapkan `agents.defaults.heartbeat.includeReasoning: true` atau per-agent `agents.list[].heartbeat.includeReasoning: true`.
## UI chat web
- Pemilih thinking chat web mencerminkan level tersimpan sesi dari penyimpanan/config sesi masuk saat halaman dimuat.
- Memilih level lain langsung menulis override sesi melalui `sessions.patch`; ini tidak menunggu pengiriman berikutnya dan bukan override `thinkingOnce` sekali pakai.
- Opsi pertama selalu `Default (<resolved level>)`, di mana default yang terselesaikan berasal dari profil thinking provider model sesi aktif.
- Pemilih menggunakan `thinkingOptions` yang dikembalikan oleh baris sesi Gateway. UI browser tidak menyimpan daftar regex provider sendiri; Plugin memiliki himpunan level khusus model.
- Memilih level lain langsung menulis override sesi melalui `sessions.patch`; ini tidak menunggu pengiriman berikutnya dan bukan override satu kali `thinkingOnce`.
- Opsi pertama selalu `Default (<resolved level>)`, di mana default teresolusi berasal dari profil thinking provider model sesi aktif.
- Pemilih menggunakan `thinkingOptions` yang dikembalikan oleh baris sesi gateway. UI browser tidak menyimpan daftar regex provider sendiri; Plugin memiliki kumpulan level spesifik model.
- `/think:<level>` tetap berfungsi dan memperbarui level sesi tersimpan yang sama, sehingga direktif chat dan pemilih tetap sinkron.
## Profil provider
- Plugin provider dapat mengekspos `resolveThinkingProfile(ctx)` untuk mendefinisikan level dan default model yang didukung.
- Plugin provider dapat mengekspos `resolveThinkingProfile(ctx)` untuk mendefinisikan level yang didukung model dan default-nya.
- Setiap level profil memiliki `id` kanonis tersimpan (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `adaptive`, atau `max`) dan dapat menyertakan `label` tampilan. Provider biner menggunakan `{ id: "low", label: "on" }`.
- Hook legacy yang dipublikasikan (`supportsXHighThinking`, `isBinaryThinking`, dan `resolveDefaultThinkingLevel`) tetap ada sebagai adaptor kompatibilitas, tetapi himpunan level kustom baru sebaiknya menggunakan `resolveThinkingProfile`.
- Baris Gateway mengekspos `thinkingOptions` dan `thinkingDefault` sehingga klien ACP/chat merender profil yang sama dengan yang digunakan validasi runtime.
- Hook legacy yang dipublikasikan (`supportsXHighThinking`, `isBinaryThinking`, dan `resolveDefaultThinkingLevel`) tetap ada sebagai adaptor kompatibilitas, tetapi kumpulan level kustom baru sebaiknya menggunakan `resolveThinkingProfile`.
- Baris Gateway mengekspos `thinkingOptions` dan `thinkingDefault` agar klien ACP/chat merender profil yang sama dengan yang digunakan validasi runtime.