chore(i18n): refresh id translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-10 09:24:45 +00:00
parent 84ad3b85d6
commit e865b7a21f
11 changed files with 3354 additions and 1959 deletions

View File

@ -1,60 +1,56 @@
---
read_when:
- Memeriksa pekerjaan latar belakang yang sedang berlangsung atau baru saja selesai
- Men-debug kegagalan pengiriman untuk eksekusi agen yang dilepas
- Memahami bagaimana eksekusi latar belakang terkait dengan sesi, cron, dan heartbeat
summary: Pelacakan tugas latar belakang untuk eksekusi ACP, subagen, pekerjaan cron terisolasi, dan operasi CLI
- Men-debug kegagalan pengiriman untuk proses agen terlepas
- Memahami bagaimana proses latar belakang terkait dengan sesi, cron, dan heartbeat
summary: Pelacakan tugas latar belakang untuk proses ACP, subagen, tugas cron terisolasi, dan operasi CLI
title: Tugas Latar Belakang
x-i18n:
generated_at: "2026-04-06T03:06:42Z"
generated_at: "2026-04-10T09:13:14Z"
model: gpt-5.4
provider: openai
source_hash: 2f56c1ac23237907a090c69c920c09578a2f56f5d8bf750c7f2136c603c8a8ff
source_hash: d7b5ba41f1025e0089986342ce85698bc62f676439c3ccf03f3ed146beb1b1ac
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**:
eksekusi ACP, pemunculan subagen, eksekusi pekerjaan cron terisolasi, dan operasi yang dimulai dari CLI.
proses ACP, pemanggilan subagen, eksekusi tugas cron terisolasi, dan operasi yang dimulai oleh CLI.
Tugas **tidak** menggantikan sesi, pekerjaan cron, atau heartbeat — tugas adalah **buku catatan aktivitas** yang merekam pekerjaan terlepas apa yang terjadi, kapan terjadinya, dan apakah berhasil.
Tugas **tidak** menggantikan sesi, tugas cron, atau heartbeat — tugas adalah **buku aktivitas** yang mencatat pekerjaan terlepas apa yang terjadi, kapan, dan apakah pekerjaan tersebut berhasil.
<Note>
Tidak setiap eksekusi 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 proses agen membuat tugas. Giliran heartbeat dan chat interaktif normal tidak membuat tugas. Semua eksekusi cron, pemanggilan ACP, pemanggilan subagen, dan perintah agen CLI membuat tugas.
</Note>
## Ringkasan singkat
## Ringkasnya
- 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.
- ACP, subagen, semua tugas 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 tersebut; tugas CLI berbasis chat tetap aktif hanya selama konteks eksekusi pemiliknya masih aktif.
- Penyelesaian didorong oleh push: pekerjaan terlepas dapat memberi tahu secara langsung atau membangunkan
sesi/heartbeat peminta saat selesai, jadi loop polling status
biasanya bukan pola yang tepat.
- Eksekusi cron terisolasi dan penyelesaian subagen melakukan pembersihan best-effort atas tab/proses browser yang dilacak untuk sesi turunannya sebelum pencatatan pembersihan akhir.
- Pengiriman cron terisolasi menekan balasan induk sementara yang sudah usang saat
pekerjaan subagen turunan masih dikuras, dan lebih memilih keluaran turunan final
jika keluaran itu tiba sebelum pengiriman.
- Notifikasi penyelesaian dikirim langsung ke channel atau diantrikan untuk heartbeat berikutnya.
- Tugas cron tetap aktif selama runtime cron masih memiliki tugas tersebut; tugas CLI berbasis chat tetap aktif hanya selama konteks proses pemiliknya masih aktif.
- Penyelesaian bersifat didorong-push: pekerjaan terlepas dapat memberi tahu secara langsung atau membangunkan sesi/heartbeat peminta saat selesai, sehingga loop polling status biasanya bukan pendekatan yang tepat.
- Proses cron terisolasi dan penyelesaian subagen sebisa mungkin membersihkan tab/proses browser yang terlacak untuk sesi turunannya sebelum pembukuan pembersihan akhir.
- Pengiriman cron terisolasi menekan balasan induk sementara yang sudah basi saat pekerjaan subagen turunan masih dikuras, dan lebih memilih output turunan final ketika output itu tiba sebelum pengiriman.
- Notifikasi penyelesaian dikirim langsung ke saluran atau dimasukkan ke antrean untuk heartbeat berikutnya.
- `openclaw tasks list` menampilkan semua tugas; `openclaw tasks audit` menampilkan masalah.
- Catatan terminal disimpan selama 7 hari, lalu dipangkas secara otomatis.
## Mulai cepat
```bash
# Daftar semua tugas (terbaru lebih dulu)
# Daftar semua tugas (terbaru terlebih dahulu)
openclaw tasks list
# Filter berdasarkan runtime atau status
openclaw tasks list --runtime acp
openclaw tasks list --status running
# Tampilkan detail untuk tugas tertentu (berdasarkan ID, ID eksekusi, atau kunci sesi)
# Tampilkan detail untuk tugas tertentu (berdasarkan ID, ID run, atau kunci sesi)
openclaw tasks show <lookup>
# Batalkan tugas yang sedang berjalan (menghentikan sesi anak)
@ -80,19 +76,19 @@ openclaw tasks flow cancel <lookup>
| Sumber | Jenis runtime | Kapan catatan tugas dibuat | Kebijakan notifikasi default |
| ---------------------- | ------------- | ---------------------------------------------------- | ---------------------------- |
| Eksekusi latar belakang ACP | `acp` | Memunculkan sesi ACP anak | `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` |
| Operasi CLI | `cli` | Perintah `openclaw agent` yang berjalan melalui gateway | `silent` |
| Pekerjaan media agen | `cli` | Eksekusi `video_generate` berbasis sesi | `silent` |
| Proses latar belakang ACP | `acp` | Memunculkan sesi ACP anak | `done_only` |
| Orkestrasi subagen | `subagent` | Memunculkan 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` |
| Tugas media agen | `cli` | Proses `video_generate` berbasis sesi | `silent` |
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 di sesi mereka sendiri.
Tugas cron sesi utama menggunakan kebijakan notifikasi `silent` secara default — tugas tersebut membuat catatan untuk pelacakan tetapi tidak menghasilkan notifikasi. Tugas cron terisolasi juga default ke `silent` tetapi lebih terlihat karena berjalan dalam sesi mereka sendiri.
Eksekusi `video_generate` berbasis sesi juga menggunakan kebijakan notifikasi `silent`. Eksekusi 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 asinkron `music_generate` dan `video_generate` akan mencoba pengiriman channel langsung terlebih dahulu sebelum kembali ke jalur wake sesi peminta.
Proses `video_generate` berbasis sesi juga menggunakan kebijakan notifikasi `silent`. Proses ini 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` akan mencoba pengiriman saluran langsung terlebih dahulu sebelum kembali ke jalur wake sesi peminta.
Selama tugas `video_generate` berbasis sesi masih aktif, tool juga bertindak sebagai guardrail: pemanggilan `video_generate` berulang di sesi yang sama akan mengembalikan status tugas aktif alih-alih memulai generasi serentak kedua. Gunakan `action: "status"` saat Anda menginginkan pencarian kemajuan/status yang eksplisit dari sisi agen.
Saat tugas `video_generate` berbasis sesi masih aktif, tool tersebut juga bertindak sebagai guardrail: pemanggilan `video_generate` berulang dalam sesi yang sama akan mengembalikan status tugas aktif alih-alih memulai generasi serentak kedua. Gunakan `action: "status"` jika Anda menginginkan pencarian progres/status eksplisit dari sisi agen.
**Yang tidak membuat tugas:**
**Apa yang tidak membuat tugas:**
- Giliran heartbeat — sesi utama; lihat [Heartbeat](/id/gateway/heartbeat)
- Giliran chat interaktif normal
@ -104,7 +100,7 @@ Selama tugas `video_generate` berbasis sesi masih aktif, tool juga bertindak seb
stateDiagram-v2
[*] --> queued
queued --> running : agen mulai
running --> succeeded : selesai dengan sukses
running --> succeeded : selesai dengan baik
running --> failed : error
running --> timed_out : batas waktu terlampaui
running --> cancelled : operator membatalkan
@ -112,52 +108,50 @@ stateDiagram-v2
running --> lost : sesi hilang > 5 menit
```
| Status | Artinya |
| ----------- | ------------------------------------------------------------------------ |
| `queued` | Dibuat, menunggu agen mulai |
| `running` | Giliran agen sedang dieksekusi secara aktif |
| `succeeded` | Berhasil diselesaikan |
| `failed` | Selesai dengan error |
| `timed_out` | Melebihi batas waktu yang dikonfigurasi |
| `cancelled` | Dihentikan oleh operator melalui `openclaw tasks cancel` |
| `lost` | Runtime kehilangan status dukungan otoritatif setelah masa tenggang 5 menit |
| Status | Artinya |
| ----------- | -------------------------------------------------------------------------- |
| `queued` | Dibuat, menunggu agen mulai |
| `running` | Giliran agen sedang aktif dieksekusi |
| `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 — saat eksekusi agen terkait berakhir, status tugas diperbarui agar sesuai.
Transisi terjadi secara otomatis — ketika proses agen terkait berakhir, status tugas diperbarui agar sesuai.
`lost` sadar runtime:
`lost` bergantung pada runtime:
- 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 pekerjaan sebagai aktif.
- Tugas CLI: tugas sesi anak terisolasi menggunakan sesi anak; tugas CLI berbasis chat menggunakan konteks eksekusi aktif sebagai gantinya, sehingga baris sesi channel/grup/langsung yang tertinggal tidak membuatnya tetap aktif.
- Tugas cron: runtime cron tidak lagi melacak tugas tersebut sebagai aktif.
- Tugas CLI: tugas sesi anak terisolasi menggunakan sesi anak; tugas CLI berbasis chat menggunakan konteks proses langsung sebagai gantinya, sehingga baris sesi saluran/grup/langsung yang masih tersisa tidak membuatnya tetap aktif.
## Pengiriman dan notifikasi
Saat sebuah tugas mencapai status terminal, OpenClaw memberi tahu Anda. Ada dua jalur pengiriman:
Ketika sebuah tugas mencapai status terminal, OpenClaw memberi tahu Anda. Ada dua jalur pengiriman:
**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 langsung** — jika tugas memiliki target saluran (`requesterOrigin`), pesan penyelesaian dikirim langsung ke saluran tersebut (Telegram, Discord, Slack, dan sebagainya). 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 antrean sesi** — jika pengiriman langsung gagal atau tidak ada origin yang ditetapkan, pembaruan diantrikan sebagai peristiwa sistem di sesi peminta dan akan muncul pada heartbeat berikutnya.
**Pengiriman yang dimasukkan ke antrean sesi** — jika pengiriman langsung gagal atau tidak ada origin yang ditetapkan, pembaruan dimasukkan ke antrean sebagai event sistem dalam sesi peminta dan muncul pada heartbeat berikutnya.
<Tip>
Penyelesaian tugas memicu wake heartbeat segera agar Anda melihat hasilnya dengan cepat — Anda tidak perlu menunggu tick heartbeat terjadwal berikutnya.
Penyelesaian tugas memicu wake heartbeat segera sehingga Anda melihat hasilnya dengan cepat — Anda tidak perlu menunggu tick heartbeat terjadwal berikutnya.
</Tip>
Itu berarti 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 yang 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 ketika Anda memerlukan debugging, intervensi, atau audit eksplisit.
### Kebijakan notifikasi
Kontrol seberapa banyak yang Anda dengar tentang setiap tugas:
Kendalikan seberapa banyak yang Anda dengar tentang setiap tugas:
| Kebijakan | Yang dikirim |
| ------------------------ | ---------------------------------------------------------------------- |
| `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 |
| Kebijakan | Apa yang dikirimkan |
| --------------------- | -------------------------------------------------------------------------- |
| `done_only` (default) | Hanya status terminal (succeeded, failed, dll.) — **ini adalah default** |
| `state_changes` | Setiap transisi status dan pembaruan progres |
| `silent` | Tidak ada sama sekali |
Ubah kebijakan saat sebuah tugas sedang berjalan:
Ubah kebijakan saat tugas sedang berjalan:
```bash
openclaw tasks notify <lookup> state_changes
@ -171,7 +165,7 @@ openclaw tasks notify <lookup> state_changes
openclaw tasks list [--runtime <acp|subagent|cron|cli>] [--status <status>] [--json]
```
Kolom keluaran: ID Tugas, Jenis, Status, Pengiriman, ID Eksekusi, Sesi Anak, Ringkasan.
Kolom output: ID Tugas, Jenis, Status, Pengiriman, ID Run, Sesi Anak, Ringkasan.
### `tasks show`
@ -179,7 +173,7 @@ Kolom keluaran: ID Tugas, Jenis, Status, Pengiriman, ID Eksekusi, Sesi Anak, Rin
openclaw tasks show <lookup>
```
Token lookup menerima ID tugas, ID eksekusi, atau kunci sesi. 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`
@ -187,7 +181,7 @@ Token lookup menerima ID tugas, ID eksekusi, atau kunci sesi. Menampilkan catata
openclaw tasks cancel <lookup>
```
Untuk tugas ACP dan subagen, ini menghentikan sesi anak. Status bertransisi ke `cancelled` dan notifikasi pengiriman dikirim.
Untuk tugas ACP dan subagen, ini menghentikan sesi anak. Untuk tugas yang dilacak CLI, pembatalan dicatat di registri tugas (tidak ada handle runtime anak terpisah). Status bertransisi menjadi `cancelled` dan notifikasi pengiriman dikirim bila berlaku.
### `tasks notify`
@ -201,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` saat masalah terdeteksi.
Menampilkan masalah operasional. Temuan juga muncul di `openclaw status` ketika masalah terdeteksi.
| Temuan | Keparahan | Pemicu |
| ------------------------- | --------- | ----------------------------------------------------- |
| `stale_queued` | warn | Berada di antrean selama lebih dari 10 menit |
| `stale_running` | error | Berjalan selama lebih dari 30 menit |
| `lost` | error | Kepemilikan tugas berbasis 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 selesai sebelum mulai) |
| Temuan | Tingkat keparahan | Pemicu |
| ------------------------- | ----------------- | --------------------------------------------------- |
| `stale_queued` | warn | Berada di antrean selama lebih dari 10 menit |
| `stale_running` | error | Berjalan selama lebih dari 30 menit |
| `lost` | error | Kepemilikan tugas berbasis runtime menghilang |
| `delivery_failed` | warn | Pengiriman gagal dan kebijakan notifikasi bukan `silent` |
| `missing_cleanup` | warn | Tugas terminal tanpa stempel waktu cleanup |
| `inconsistent_timestamps` | warn | Pelanggaran linimasa (misalnya selesai sebelum mulai) |
### `tasks maintenance`
@ -219,23 +213,21 @@ openclaw tasks maintenance [--json]
openclaw tasks maintenance --apply [--json]
```
Gunakan ini untuk mempratinjau atau menerapkan rekonsiliasi, pemberian cap pembersihan, dan pemangkasan untuk
tugas dan status Task Flow.
Gunakan ini untuk mempratinjau atau menerapkan rekonsiliasi, pemberian stempel cleanup, dan pemangkasan untuk tugas serta status Task Flow.
Rekonsiliasi sadar runtime:
Rekonsiliasi bergantung pada runtime:
- Tugas ACP/subagen memeriksa sesi anak pendukungnya.
- Tugas cron memeriksa apakah runtime cron masih memiliki pekerjaan tersebut.
- Tugas CLI berbasis chat memeriksa konteks eksekusi aktif milik pemilik, bukan hanya baris sesi chat.
- Tugas cron memeriksa apakah runtime cron masih memiliki tugas tersebut.
- Tugas CLI berbasis chat memeriksa konteks proses langsung pemilik, bukan hanya baris sesi chat.
Pembersihan penyelesaian juga sadar runtime:
Cleanup penyelesaian juga bergantung pada runtime:
- Penyelesaian subagen melakukan penutupan best-effort tab/proses browser yang dilacak untuk sesi anak sebelum pembersihan pengumuman dilanjutkan.
- Penyelesaian cron terisolasi melakukan penutupan best-effort tab/proses browser yang dilacak untuk sesi cron sebelum eksekusi 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, akan kembali ke teks tool/toolResult terbaru yang sudah disanitasi, dan eksekusi panggilan tool yang hanya timeout dapat diringkas menjadi ringkasan kemajuan parsial singkat.
- Kegagalan pembersihan tidak menyamarkan hasil tugas yang sebenarnya.
- Penyelesaian subagen sebisa mungkin menutup tab/proses browser yang terlacak untuk sesi anak sebelum cleanup pengumuman berlanjut.
- Penyelesaian cron terisolasi sebisa mungkin menutup tab/proses browser yang terlacak untuk sesi cron sebelum proses benar-benar dibongkar.
- Pengiriman cron terisolasi menunggu tindak lanjut subagen turunan bila diperlukan dan menekan teks pengakuan induk yang sudah basi alih-alih mengumumkannya.
- Pengiriman penyelesaian subagen lebih memilih teks asisten terlihat terbaru; jika kosong, ia kembali ke teks tool/toolResult terbaru yang sudah disanitasi, dan proses khusus pemanggilan tool yang hanya timeout dapat dipadatkan menjadi ringkasan progres parsial singkat.
- Kegagalan cleanup tidak menutupi hasil tugas yang sebenarnya.
### `tasks flow list|show|cancel`
@ -245,18 +237,15 @@ openclaw tasks flow show <lookup> [--json]
openclaw tasks flow cancel <lookup>
```
Gunakan ini ketika Task Flow pengorkestrasi adalah hal yang Anda pedulikan
alih-alih satu catatan tugas latar belakang individual.
Gunakan ini ketika Task Flow pengorkestrasi adalah hal yang Anda pedulikan daripada satu catatan tugas latar belakang individual.
## Papan tugas chat (`/tasks`)
Gunakan `/tasks` di sesi chat mana pun untuk melihat tugas latar belakang yang tertaut ke sesi tersebut. Papan menampilkan
tugas aktif dan yang baru selesai beserta runtime, status, waktu, serta detail kemajuan atau error.
Gunakan `/tasks` di sesi chat mana pun untuk melihat tugas latar belakang yang ditautkan ke sesi tersebut. Papan ini menampilkan tugas aktif dan yang baru selesai beserta runtime, status, waktu, dan detail progres atau error.
Saat sesi saat ini tidak memiliki tugas tertaut yang terlihat, `/tasks` akan kembali ke jumlah tugas lokal agen
agar Anda tetap mendapatkan ringkasan tanpa membocorkan detail sesi lain.
Ketika sesi saat ini tidak memiliki tugas tertaut yang terlihat, `/tasks` kembali ke jumlah tugas lokal agen sehingga Anda tetap mendapatkan gambaran umum tanpa membocorkan detail sesi lain.
Untuk buku catatan operator lengkap, gunakan CLI: `openclaw tasks list`.
Untuk buku aktivitas operator lengkap, gunakan CLI: `openclaw tasks list`.
## Integrasi status (tekanan tugas)
@ -266,35 +255,35 @@ Untuk buku catatan operator lengkap, gunakan CLI: `openclaw tasks list`.
Tasks: 3 queued · 2 running · 1 issues
```
Ringkasan melaporkan:
Ringkasan tersebut melaporkan:
- **active** — jumlah `queued` + `running`
- **failures** — jumlah `failed` + `timed_out` + `lost`
- **byRuntime** — perincian berdasarkan `acp`, `subagent`, `cron`, `cli`
Baik `/status` maupun tool `session_status` menggunakan snapshot tugas yang sadar pembersihan: tugas aktif lebih
diprioritaskan, baris selesai yang sudah usang disembunyikan, dan kegagalan terbaru hanya ditampilkan saat tidak ada pekerjaan aktif
yang tersisa. Ini menjaga kartu status tetap berfokus pada hal yang penting saat ini.
Baik `/status` maupun tool `session_status` menggunakan snapshot tugas yang sadar-cleanup: tugas aktif
diprioritaskan, baris selesai yang sudah basi disembunyikan, dan kegagalan terbaru hanya ditampilkan saat tidak ada pekerjaan aktif
yang tersisa. Ini menjaga kartu status tetap fokus pada hal yang penting saat ini.
## Penyimpanan dan pemeliharaan
### Tempat tugas disimpan
Catatan tugas disimpan di SQLite pada:
Catatan tugas disimpan secara persisten di SQLite pada:
```
$OPENCLAW_STATE_DIR/tasks/runs.sqlite
```
Registry dimuat ke memori saat gateway dimulai dan menyinkronkan penulisan ke SQLite untuk ketahanan lintas restart.
Registri dimuat ke memori saat gateway dimulai dan menyinkronkan penulisan ke SQLite agar tetap tahan lama setelah restart.
### Pemeliharaan otomatis
Sebuah sweeper berjalan setiap **60 detik** dan menangani tiga hal:
1. **Rekonsiliasi** — memeriksa apakah tugas aktif masih memiliki dukungan runtime otoritatif. Tugas ACP/subagen menggunakan status sesi anak, tugas cron menggunakan kepemilikan pekerjaan aktif, dan tugas CLI berbasis chat menggunakan konteks eksekusi aktif milik pemilik. Jika status dukungan itu hilang selama lebih dari 5 menit, tugas ditandai sebagai `lost`.
2. **Pemberian cap pembersihan** — menetapkan cap waktu `cleanupAfter` pada tugas terminal (`endedAt + 7 days`).
3. **Pemangkasan** — menghapus catatan yang melewati tanggal `cleanupAfter`.
1. **Rekonsiliasi** — memeriksa apakah tugas aktif masih memiliki status pendukung runtime yang otoritatif. Tugas ACP/subagen menggunakan status sesi anak, tugas cron menggunakan kepemilikan tugas aktif, dan tugas CLI berbasis chat menggunakan konteks proses pemilik. Jika status pendukung tersebut hilang selama lebih dari 5 menit, tugas ditandai sebagai `lost`.
2. **Pemberian stempel cleanup** — menetapkan stempel waktu `cleanupAfter` pada tugas terminal (`endedAt + 7 hari`).
3. **Pemangkasan** — menghapus catatan yang telah melewati tanggal `cleanupAfter`.
**Retensi**: catatan tugas terminal disimpan selama **7 hari**, lalu dipangkas secara otomatis. Tidak perlu konfigurasi.
@ -304,32 +293,32 @@ Sebuah sweeper berjalan setiap **60 detik** dan menangani tiga hal:
[Task Flow](/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 [Task Flow](/id/automation/taskflow) untuk detail.
### Tugas dan cron
**Definisi** pekerjaan cron berada di `~/.openclaw/cron/jobs.json`. **Setiap** eksekusi cron membuat catatan tugas — baik sesi utama maupun terisolasi. Tugas cron sesi utama default ke kebijakan notifikasi `silent` sehingga melacak tanpa menghasilkan notifikasi.
Sebuah **definisi** tugas cron berada di `~/.openclaw/cron/jobs.json`. **Setiap** eksekusi cron membuat catatan tugas — baik sesi utama maupun terisolasi. Tugas cron sesi utama default ke kebijakan notifikasi `silent` sehingga tetap terlacak tanpa menghasilkan notifikasi.
Lihat [Cron Jobs](/id/automation/cron-jobs).
Lihat [Tugas Cron](/id/automation/cron-jobs).
### Tugas dan heartbeat
Eksekusi heartbeat adalah giliran sesi utama — mereka tidak membuat catatan tugas. Saat sebuah tugas selesai, tugas itu dapat memicu wake heartbeat agar Anda melihat hasilnya dengan cepat.
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.
Lihat [Heartbeat](/id/gateway/heartbeat).
### Tugas dan sesi
Sebuah tugas dapat mereferensikan `childSessionKey` (tempat pekerjaan berjalan) dan `requesterSessionKey` (siapa yang memulainya). Sesi adalah konteks percakapan; tugas adalah pelacakan aktivitas di atasnya.
Sebuah tugas dapat mereferensikan `childSessionKey` (tempat pekerjaan berjalan) dan `requesterSessionKey` (siapa yang memulainya). Sesi adalah konteks percakapan; tugas adalah pelacakan aktivitas di atas konteks tersebut.
### Tugas dan eksekusi agen
### Tugas dan proses agen
`runId` sebuah tugas terhubung ke eksekusi agen yang melakukan pekerjaan. Peristiwa siklus hidup agen (mulai, selesai, error) secara otomatis memperbarui status tugas — Anda tidak perlu mengelola siklus hidup secara manual.
`runId` sebuah tugas terhubung ke proses agen yang melakukan pekerjaan. Event 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 otomasi secara ringkas
- [Task Flow](/id/automation/taskflow) — orkestrasi alur di atas tugas
- [Scheduled Tasks](/id/automation/cron-jobs) — penjadwalan pekerjaan latar belakang
- [Otomasi & Tugas](/id/automation) — semua mekanisme otomasi secara sekilas
- [Task Flow](/id/automation/taskflow) — orkestrasi flow di atas tugas
- [Tugas Terjadwal](/id/automation/cron-jobs) — penjadwalan pekerjaan latar belakang
- [Heartbeat](/id/gateway/heartbeat) — giliran sesi utama berkala
- [CLI: Tasks](/cli/index#tasks) — referensi perintah CLI
- [CLI: Tugas](/cli/index#tasks) — referensi perintah CLI

View File

@ -0,0 +1,612 @@
---
read_when:
- Anda ingin memahami untuk apa memori aktif digunakan
- Anda ingin mengaktifkan memori aktif untuk agen percakapan
- Anda ingin menyesuaikan perilaku memori aktif tanpa mengaktifkannya di mana-mana
summary: Sub-agen memori pemblokir milik plugin yang menyuntikkan memori yang relevan ke dalam sesi chat interaktif
title: Memori Aktif
x-i18n:
generated_at: "2026-04-10T09:13:15Z"
model: gpt-5.4
provider: openai
source_hash: 6a51437df4ae4d9d57764601dfcfcdadb269e2895bf49dc82b9f496c1b3cb341
source_path: concepts/active-memory.md
workflow: 15
---
# Memori Aktif
Memori aktif adalah sub-agen memori pemblokir opsional milik plugin yang berjalan
sebelum balasan utama untuk sesi percakapan yang memenuhi syarat.
Fitur ini ada karena sebagian besar sistem memori mampu tetapi reaktif. Mereka bergantung pada
agen utama untuk memutuskan kapan mencari memori, atau pada pengguna untuk mengatakan hal-hal
seperti "ingat ini" atau "cari memori." Pada saat itu, momen ketika memori akan
membuat balasan terasa alami sudah terlewat.
Memori aktif memberi sistem satu kesempatan terbatas untuk memunculkan memori yang relevan
sebelum balasan utama dibuat.
## Tempelkan Ini Ke Dalam Agen Anda
Tempelkan ini ke dalam agen Anda jika Anda ingin mengaktifkan Memori Aktif dengan
pengaturan mandiri dan aman sebagai default:
```json5
{
plugins: {
entries: {
"active-memory": {
enabled: true,
config: {
enabled: true,
agents: ["main"],
allowedChatTypes: ["direct"],
modelFallbackPolicy: "default-remote",
queryMode: "recent",
promptStyle: "balanced",
timeoutMs: 15000,
maxSummaryChars: 220,
persistTranscripts: false,
logging: true,
},
},
},
},
}
```
Ini mengaktifkan plugin untuk agen `main`, membuatnya tetap terbatas pada sesi
bergaya pesan langsung secara default, memungkinkannya mewarisi model sesi saat ini terlebih dahulu, dan
tetap mengizinkan fallback jarak jauh bawaan jika tidak ada model eksplisit atau turunan yang tersedia.
Setelah itu, mulai ulang gateway:
```bash
node scripts/run-node.mjs gateway --profile dev
```
Untuk memeriksanya secara langsung dalam percakapan:
```text
/verbose on
```
## Aktifkan memori aktif
Pengaturan yang paling aman adalah:
1. aktifkan plugin
2. targetkan satu agen percakapan
3. biarkan logging tetap aktif hanya saat menyesuaikan
Mulai dengan ini di `openclaw.json`:
```json5
{
plugins: {
entries: {
"active-memory": {
enabled: true,
config: {
agents: ["main"],
allowedChatTypes: ["direct"],
modelFallbackPolicy: "default-remote",
queryMode: "recent",
promptStyle: "balanced",
timeoutMs: 15000,
maxSummaryChars: 220,
persistTranscripts: false,
logging: true,
},
},
},
},
}
```
Lalu mulai ulang gateway:
```bash
node scripts/run-node.mjs gateway --profile dev
```
Artinya:
- `plugins.entries.active-memory.enabled: true` mengaktifkan plugin
- `config.agents: ["main"]` hanya mengikutsertakan agen `main` ke dalam memori aktif
- `config.allowedChatTypes: ["direct"]` membuat memori aktif tetap aktif hanya untuk sesi bergaya pesan langsung secara default
- jika `config.model` tidak disetel, memori aktif mewarisi model sesi saat ini terlebih dahulu
- `config.modelFallbackPolicy: "default-remote"` mempertahankan fallback jarak jauh bawaan sebagai default saat tidak ada model eksplisit atau turunan yang tersedia
- `config.promptStyle: "balanced"` menggunakan gaya prompt default serba guna untuk mode `recent`
- memori aktif tetap hanya berjalan pada sesi chat interaktif persisten yang memenuhi syarat
## Cara melihatnya
Memori aktif menyuntikkan konteks sistem tersembunyi untuk model. Fitur ini tidak mengekspos
tag mentah `<active_memory_plugin>...</active_memory_plugin>` kepada klien.
## Toggle sesi
Gunakan perintah plugin saat Anda ingin menjeda atau melanjutkan memori aktif untuk
sesi chat saat ini tanpa mengedit konfigurasi:
```text
/active-memory status
/active-memory off
/active-memory on
```
Ini berlaku pada cakupan sesi. Ini tidak mengubah
`plugins.entries.active-memory.enabled`, penargetan agen, atau konfigurasi
global lainnya.
Jika Anda ingin perintah tersebut menulis konfigurasi dan menjeda atau melanjutkan memori aktif untuk
semua sesi, gunakan bentuk global eksplisit:
```text
/active-memory status --global
/active-memory off --global
/active-memory on --global
```
Bentuk global menulis `plugins.entries.active-memory.config.enabled`. Bentuk ini membiarkan
`plugins.entries.active-memory.enabled` tetap aktif agar perintah tetap tersedia untuk
mengaktifkan kembali memori aktif nanti.
Jika Anda ingin melihat apa yang dilakukan memori aktif dalam sesi langsung, aktifkan mode verbose
untuk sesi tersebut:
```text
/verbose on
```
Dengan verbose diaktifkan, OpenClaw dapat menampilkan:
- baris status memori aktif seperti `Active Memory: ok 842ms recent 34 chars`
- ringkasan debug yang mudah dibaca seperti `Active Memory Debug: Lemon pepper wings with blue cheese.`
Baris-baris tersebut berasal dari pass memori aktif yang sama yang memberi makan konteks
sistem tersembunyi, tetapi diformat untuk manusia alih-alih mengekspos markup prompt mentah.
Secara default, transkrip sub-agen memori pemblokir bersifat sementara dan dihapus
setelah proses selesai.
Contoh alur:
```text
/verbose on
what wings should i order?
```
Bentuk balasan yang diharapkan terlihat:
```text
...normal assistant reply...
🧩 Active Memory: ok 842ms recent 34 chars
🔎 Active Memory Debug: Lemon pepper wings with blue cheese.
```
## Kapan fitur ini berjalan
Memori aktif menggunakan dua gerbang:
1. **Opt-in konfigurasi**
Plugin harus diaktifkan, dan id agen saat ini harus muncul di
`plugins.entries.active-memory.config.agents`.
2. **Kelayakan runtime yang ketat**
Bahkan saat diaktifkan dan ditargetkan, memori aktif hanya berjalan untuk
sesi chat interaktif persisten yang memenuhi syarat.
Aturan sebenarnya adalah:
```text
plugin enabled
+
agent id targeted
+
allowed chat type
+
eligible interactive persistent chat session
=
active memory runs
```
Jika salah satu dari ini gagal, memori aktif tidak berjalan.
## Jenis sesi
`config.allowedChatTypes` mengontrol jenis percakapan mana yang boleh menjalankan Memori
Aktif sama sekali.
Default-nya adalah:
```json5
allowedChatTypes: ["direct"]
```
Artinya Memori Aktif berjalan secara default dalam sesi bergaya pesan langsung, tetapi
tidak dalam sesi grup atau kanal kecuali Anda secara eksplisit mengikutsertakannya.
Contoh:
```json5
allowedChatTypes: ["direct"]
```
```json5
allowedChatTypes: ["direct", "group"]
```
```json5
allowedChatTypes: ["direct", "group", "channel"]
```
## Di mana fitur ini berjalan
Memori aktif adalah fitur pengayaan percakapan, bukan fitur inferensi
di seluruh platform.
| Surface | Menjalankan memori aktif? |
| ------------------------------------------------------------------- | ------------------------------------------------------ |
| Sesi persisten Control UI / chat web | Ya, jika plugin diaktifkan dan agen ditargetkan |
| Sesi kanal interaktif lain pada jalur chat persisten yang sama | Ya, jika plugin diaktifkan dan agen ditargetkan |
| Proses sekali jalan headless | Tidak |
| Proses heartbeat/latar belakang | Tidak |
| Jalur internal `agent-command` generik | Tidak |
| Eksekusi sub-agen/helper internal | Tidak |
## Mengapa menggunakannya
Gunakan memori aktif ketika:
- sesi bersifat persisten dan menghadap pengguna
- agen memiliki memori jangka panjang yang bermakna untuk dicari
- kontinuitas dan personalisasi lebih penting daripada determinisme prompt mentah
Fitur ini bekerja sangat baik untuk:
- preferensi yang stabil
- kebiasaan yang berulang
- konteks pengguna jangka panjang yang seharusnya muncul secara alami
Fitur ini kurang cocok untuk:
- otomasi
- worker internal
- tugas API sekali jalan
- tempat di mana personalisasi tersembunyi akan terasa mengejutkan
## Cara kerjanya
Bentuk runtime-nya adalah:
```mermaid
flowchart LR
U["User Message"] --> Q["Build Memory Query"]
Q --> R["Active Memory Blocking Memory Sub-Agent"]
R -->|NONE or empty| M["Main Reply"]
R -->|relevant summary| I["Append Hidden active_memory_plugin System Context"]
I --> M["Main Reply"]
```
Sub-agen memori pemblokir hanya dapat menggunakan:
- `memory_search`
- `memory_get`
Jika koneksinya lemah, sub-agen harus mengembalikan `NONE`.
## Mode kueri
`config.queryMode` mengontrol seberapa banyak percakapan yang dilihat oleh sub-agen memori pemblokir.
## Gaya prompt
`config.promptStyle` mengontrol seberapa agresif atau ketat sub-agen memori pemblokir
saat memutuskan apakah akan mengembalikan memori.
Gaya yang tersedia:
- `balanced`: default serba guna untuk mode `recent`
- `strict`: paling tidak agresif; terbaik saat Anda ingin sangat sedikit kebocoran dari konteks di sekitar
- `contextual`: paling ramah kontinuitas; terbaik saat riwayat percakapan harus lebih diperhatikan
- `recall-heavy`: lebih bersedia memunculkan memori pada kecocokan yang lebih lemah tetapi masih masuk akal
- `precision-heavy`: secara agresif lebih memilih `NONE` kecuali kecocokannya jelas
- `preference-only`: dioptimalkan untuk favorit, kebiasaan, rutinitas, selera, dan fakta pribadi yang berulang
Pemetaan default saat `config.promptStyle` tidak disetel:
```text
message -> strict
recent -> balanced
full -> contextual
```
Jika Anda menyetel `config.promptStyle` secara eksplisit, override tersebut yang berlaku.
Contoh:
```json5
promptStyle: "preference-only"
```
## Kebijakan fallback model
Jika `config.model` tidak disetel, Memori Aktif mencoba menyelesaikan model dalam urutan ini:
```text
explicit plugin model
-> current session model
-> agent primary model
-> optional built-in remote fallback
```
`config.modelFallbackPolicy` mengontrol langkah terakhir.
Default:
```json5
modelFallbackPolicy: "default-remote"
```
Opsi lainnya:
```json5
modelFallbackPolicy: "resolved-only"
```
Gunakan `resolved-only` jika Anda ingin Memori Aktif melewati recall alih-alih melakukan
fallback ke default jarak jauh bawaan saat tidak ada model eksplisit atau turunan
yang tersedia.
## Jalur keluar lanjutan
Opsi-opsi ini sengaja tidak menjadi bagian dari pengaturan yang direkomendasikan.
`config.thinking` dapat menimpa level thinking sub-agen memori pemblokir:
```json5
thinking: "medium"
```
Default:
```json5
thinking: "off"
```
Jangan aktifkan ini secara default. Memori Aktif berjalan di jalur balasan, jadi waktu
thinking tambahan secara langsung meningkatkan latensi yang terlihat oleh pengguna.
`config.promptAppend` menambahkan instruksi operator tambahan setelah prompt default Memori
Aktif dan sebelum konteks percakapan:
```json5
promptAppend: "Prefer stable long-term preferences over one-off events."
```
`config.promptOverride` menggantikan prompt default Memori Aktif. OpenClaw
tetap menambahkan konteks percakapan setelahnya:
```json5
promptOverride: "You are a memory search agent. Return NONE or one compact user fact."
```
Kustomisasi prompt tidak direkomendasikan kecuali Anda memang sengaja menguji
kontrak recall yang berbeda. Prompt default disetel untuk mengembalikan `NONE`
atau konteks fakta pengguna yang ringkas untuk model utama.
### `message`
Hanya pesan pengguna terbaru yang dikirim.
```text
Latest user message only
```
Gunakan ini ketika:
- Anda menginginkan perilaku tercepat
- Anda menginginkan bias terkuat terhadap recall preferensi yang stabil
- giliran tindak lanjut tidak memerlukan konteks percakapan
Timeout yang direkomendasikan:
- mulai sekitar `3000` hingga `5000` md
### `recent`
Pesan pengguna terbaru plus sedikit ekor percakapan terbaru dikirim.
```text
Recent conversation tail:
user: ...
assistant: ...
user: ...
Latest user message:
...
```
Gunakan ini ketika:
- Anda menginginkan keseimbangan yang lebih baik antara kecepatan dan landasan percakapan
- pertanyaan tindak lanjut sering bergantung pada beberapa giliran terakhir
Timeout yang direkomendasikan:
- mulai sekitar `15000` md
### `full`
Percakapan lengkap dikirim ke sub-agen memori pemblokir.
```text
Full conversation context:
user: ...
assistant: ...
user: ...
...
```
Gunakan ini ketika:
- kualitas recall terkuat lebih penting daripada latensi
- percakapan berisi penyiapan penting yang jauh di belakang dalam utas
Timeout yang direkomendasikan:
- tingkatkan secara signifikan dibandingkan `message` atau `recent`
- mulai sekitar `15000` md atau lebih tinggi tergantung ukuran utas
Secara umum, timeout harus meningkat seiring ukuran konteks:
```text
message < recent < full
```
## Persistensi transkrip
Proses sub-agen memori pemblokir Memori Aktif membuat transkrip `session.jsonl` nyata
selama panggilan sub-agen memori pemblokir.
Secara default, transkrip tersebut bersifat sementara:
- ditulis ke direktori sementara
- hanya digunakan untuk proses sub-agen memori pemblokir
- langsung dihapus setelah proses selesai
Jika Anda ingin menyimpan transkrip sub-agen memori pemblokir tersebut di disk untuk debugging atau
pemeriksaan, aktifkan persistensi secara eksplisit:
```json5
{
plugins: {
entries: {
"active-memory": {
enabled: true,
config: {
agents: ["main"],
persistTranscripts: true,
transcriptDir: "active-memory",
},
},
},
},
}
```
Saat diaktifkan, memori aktif menyimpan transkrip di direktori terpisah di bawah
folder sesi agen target, bukan di jalur transkrip percakapan pengguna utama.
Tata letak default secara konseptual adalah:
```text
agents/<agent>/sessions/active-memory/<blocking-memory-sub-agent-session-id>.jsonl
```
Anda dapat mengubah subdirektori relatif dengan `config.transcriptDir`.
Gunakan ini dengan hati-hati:
- transkrip sub-agen memori pemblokir dapat cepat menumpuk pada sesi yang sibuk
- mode kueri `full` dapat menduplikasi banyak konteks percakapan
- transkrip ini berisi konteks prompt tersembunyi dan memori yang dipanggil kembali
## Konfigurasi
Semua konfigurasi memori aktif berada di bawah:
```text
plugins.entries.active-memory
```
Bidang yang paling penting adalah:
| Key | Type | Arti |
| --------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `enabled` | `boolean` | Mengaktifkan plugin itu sendiri |
| `config.agents` | `string[]` | Id agen yang dapat menggunakan memori aktif |
| `config.model` | `string` | Referensi model sub-agen memori pemblokir opsional; jika tidak disetel, memori aktif menggunakan model sesi saat ini |
| `config.queryMode` | `"message" \| "recent" \| "full"` | Mengontrol seberapa banyak percakapan yang dilihat sub-agen memori pemblokir |
| `config.promptStyle` | `"balanced" \| "strict" \| "contextual" \| "recall-heavy" \| "precision-heavy" \| "preference-only"` | Mengontrol seberapa agresif atau ketat sub-agen memori pemblokir saat memutuskan apakah akan mengembalikan memori |
| `config.thinking` | `"off" \| "minimal" \| "low" \| "medium" \| "high" \| "xhigh" \| "adaptive"` | Override thinking lanjutan untuk sub-agen memori pemblokir; default `off` untuk kecepatan |
| `config.promptOverride` | `string` | Penggantian prompt penuh lanjutan; tidak direkomendasikan untuk penggunaan normal |
| `config.promptAppend` | `string` | Instruksi tambahan lanjutan yang ditambahkan ke prompt default atau prompt yang dioverride |
| `config.timeoutMs` | `number` | Timeout keras untuk sub-agen memori pemblokir |
| `config.maxSummaryChars` | `number` | Jumlah total karakter maksimum yang diizinkan dalam ringkasan active-memory |
| `config.logging` | `boolean` | Mengeluarkan log memori aktif saat penyesuaian |
| `config.persistTranscripts` | `boolean` | Menyimpan transkrip sub-agen memori pemblokir di disk alih-alih menghapus file sementara |
| `config.transcriptDir` | `string` | Direktori relatif transkrip sub-agen memori pemblokir di bawah folder sesi agen |
Bidang penyesuaian yang berguna:
| Key | Type | Arti |
| ----------------------------- | -------- | ------------------------------------------------------------- |
| `config.maxSummaryChars` | `number` | Jumlah total karakter maksimum yang diizinkan dalam ringkasan active-memory |
| `config.recentUserTurns` | `number` | Giliran pengguna sebelumnya yang disertakan saat `queryMode` adalah `recent` |
| `config.recentAssistantTurns` | `number` | Giliran asisten sebelumnya yang disertakan saat `queryMode` adalah `recent` |
| `config.recentUserChars` | `number` | Karakter maksimum per giliran pengguna terbaru |
| `config.recentAssistantChars` | `number` | Karakter maksimum per giliran asisten terbaru |
| `config.cacheTtlMs` | `number` | Penggunaan ulang cache untuk kueri identik yang berulang |
## Pengaturan yang direkomendasikan
Mulailah dengan `recent`.
```json5
{
plugins: {
entries: {
"active-memory": {
enabled: true,
config: {
agents: ["main"],
queryMode: "recent",
promptStyle: "balanced",
timeoutMs: 15000,
maxSummaryChars: 220,
logging: true,
},
},
},
},
}
```
Jika Anda ingin memeriksa perilaku langsung saat menyesuaikan, gunakan `/verbose on` di
sesi tersebut alih-alih mencari perintah debug active-memory terpisah.
Lalu beralih ke:
- `message` jika Anda menginginkan latensi yang lebih rendah
- `full` jika Anda memutuskan bahwa konteks tambahan sepadan dengan sub-agen memori pemblokir yang lebih lambat
## Debugging
Jika memori aktif tidak muncul di tempat yang Anda harapkan:
1. Pastikan plugin diaktifkan di bawah `plugins.entries.active-memory.enabled`.
2. Pastikan id agen saat ini tercantum dalam `config.agents`.
3. Pastikan Anda menguji melalui sesi chat interaktif persisten.
4. Aktifkan `config.logging: true` dan pantau log gateway.
5. Verifikasi bahwa pencarian memori itu sendiri berfungsi dengan `openclaw memory status --deep`.
Jika hasil memori berisik, perketat:
- `maxSummaryChars`
Jika memori aktif terlalu lambat:
- turunkan `queryMode`
- turunkan `timeoutMs`
- kurangi jumlah giliran terbaru
- kurangi batas karakter per giliran
## Halaman terkait
- [Pencarian Memori](/id/concepts/memory-search)
- [Referensi konfigurasi memori](/id/reference/memory-config)
- [Penyiapan Plugin SDK](/id/plugins/sdk-setup)

View File

@ -1,26 +1,26 @@
---
read_when:
- Anda memerlukan panduan langkah demi langkah yang tepat tentang loop agen atau peristiwa siklus hidup
summary: Siklus hidup loop agen, aliran, dan semantik penantian
summary: Siklus hidup loop agen, aliran, dan semantik menunggu
title: Loop Agen
x-i18n:
generated_at: "2026-04-09T01:27:55Z"
generated_at: "2026-04-10T09:13:13Z"
model: gpt-5.4
provider: openai
source_hash: 32d3a73df8dabf449211a6183a70dcfd2a9b6f584dc76d0c4c9147582b2ca6a1
source_hash: b6831a5b11e9100e49f650feca51ab44a2bef242ce1b5db2766d0b3b5c5ba729
source_path: concepts/agent-loop.md
workflow: 15
---
# Loop Agen (OpenClaw)
Loop agentik adalah keseluruhan proses “nyata” agen: intake → perakitan konteks → inferensi model →
Loop agentik adalah keseluruhan proses “nyata” saat agen berjalan: penerimaan → perakitan konteks → inferensi model →
eksekusi alat → balasan streaming → persistensi. Ini adalah jalur otoritatif yang mengubah pesan
menjadi tindakan dan balasan akhir, sambil menjaga status sesi tetap konsisten.
Di OpenClaw, loop adalah satu proses tunggal yang diserialkan per sesi yang memancarkan peristiwa siklus hidup dan stream
saat model berpikir, memanggil alat, dan melakukan streaming output. Dokumen ini menjelaskan bagaimana loop autentik tersebut
dirangkai dari ujung ke ujung.
Di OpenClaw, sebuah loop adalah satu proses tunggal yang diserialkan per sesi yang mengirimkan peristiwa siklus hidup dan stream
saat model berpikir, memanggil alat, dan melakukan streaming output. Dokumen ini menjelaskan bagaimana loop autentik itu
dirangkai secara menyeluruh dari awal hingga akhir.
## Titik masuk
@ -29,45 +29,45 @@ dirangkai dari ujung ke ujung.
## Cara kerjanya (tingkat tinggi)
1. RPC `agent` memvalidasi parameter, menyelesaikan sesi (sessionKey/sessionId), menyimpan metadata sesi, dan segera mengembalikan `{ runId, acceptedAt }`.
1. RPC `agent` memvalidasi parameter, menyelesaikan sesi (sessionKey/sessionId), menyimpan metadata sesi, dan langsung mengembalikan `{ runId, acceptedAt }`.
2. `agentCommand` menjalankan agen:
- menyelesaikan default model + thinking/verbose
- memuat snapshot Skills
- memanggil `runEmbeddedPiAgent` (runtime pi-agent-core)
- memancarkan **akhir/error siklus hidup** jika loop tersemat tidak memancarkan salah satunya
- mengirim **lifecycle end/error** jika loop tersemat tidak mengirimkannya
3. `runEmbeddedPiAgent`:
- menserialkan proses melalui antrean per sesi + global
- menyelesaikan model + profil auth dan membangun sesi pi
- menyelesaikan profil model + autentikasi dan membangun sesi pi
- berlangganan ke peristiwa pi dan melakukan streaming delta asisten/alat
- menegakkan batas waktu -> membatalkan proses jika terlampaui
- menerapkan timeout -> membatalkan proses jika terlampaui
- mengembalikan payload + metadata penggunaan
4. `subscribeEmbeddedPiSession` menjembatani peristiwa pi-agent-core ke stream `agent` OpenClaw:
- peristiwa alat => `stream: "tool"`
- delta asisten => `stream: "assistant"`
- peristiwa siklus hidup => `stream: "lifecycle"` (`phase: "start" | "end" | "error"`)
5. `agent.wait` menggunakan `waitForAgentRun`:
- menunggu **akhir/error siklus hidup** untuk `runId`
- menunggu **lifecycle end/error** untuk `runId`
- mengembalikan `{ status: ok|error|timeout, startedAt, endedAt, error? }`
## Antrean + konkurensi
- Proses diserialkan per kunci sesi (jalur sesi) dan secara opsional melalui jalur global.
- Proses diserialkan per kunci sesi (lajur sesi) dan secara opsional melalui lajur global.
- Ini mencegah race pada alat/sesi dan menjaga riwayat sesi tetap konsisten.
- Kanal pesan dapat memilih mode antrean (collect/steer/followup) yang masuk ke sistem jalur ini.
Lihat [Antrean Perintah](/id/concepts/queue).
- Channel pesan dapat memilih mode antrean (collect/steer/followup) yang masuk ke sistem lajur ini.
Lihat [Command Queue](/id/concepts/queue).
## Persiapan sesi + workspace
- Workspace diselesaikan dan dibuat; proses tersandbox dapat dialihkan ke root workspace sandbox.
- Skills dimuat (atau digunakan kembali dari snapshot) dan disuntikkan ke env dan prompt.
- Workspace diselesaikan dan dibuat; proses yang disandbox dapat dialihkan ke root workspace sandbox.
- Skills dimuat (atau digunakan ulang dari snapshot) dan disuntikkan ke env dan prompt.
- File bootstrap/konteks diselesaikan dan disuntikkan ke laporan system prompt.
- Kunci tulis sesi diperoleh; `SessionManager` dibuka dan disiapkan sebelum streaming.
- Kunci tulis sesi diambil; `SessionManager` dibuka dan disiapkan sebelum streaming.
## Perakitan prompt + system prompt
- System prompt dibangun dari prompt dasar OpenClaw, prompt Skills, konteks bootstrap, dan override per proses.
- Batas khusus model dan token cadangan compaction diterapkan.
- Lihat [System prompt](/id/concepts/system-prompt) untuk apa yang dilihat model.
- Batas khusus model dan token cadangan untuk pemadatan diterapkan.
- Lihat [System prompt](/id/concepts/system-prompt) untuk mengetahui apa yang dilihat model.
## Titik hook (tempat Anda dapat mencegat)
@ -78,7 +78,7 @@ OpenClaw memiliki dua sistem hook:
### Hook internal (hook Gateway)
- **`agent:bootstrap`**: berjalan saat membangun file bootstrap sebelum system prompt difinalkan.
- **`agent:bootstrap`**: berjalan saat membangun file bootstrap sebelum system prompt difinalisasi.
Gunakan ini untuk menambah/menghapus file konteks bootstrap.
- **Hook perintah**: `/new`, `/reset`, `/stop`, dan peristiwa perintah lainnya (lihat dokumen Hooks).
@ -86,91 +86,91 @@ Lihat [Hooks](/id/automation/hooks) untuk penyiapan dan contoh.
### Hook plugin (siklus hidup agen + gateway)
Hook ini berjalan di dalam loop agen atau pipeline gateway:
Ini berjalan di dalam loop agen atau pipeline gateway:
- **`before_model_resolve`**: berjalan pra-sesi (tanpa `messages`) untuk mengganti provider/model secara deterministik sebelum resolusi model.
- **`before_prompt_build`**: berjalan setelah sesi dimuat (dengan `messages`) untuk menyuntikkan `prependContext`, `systemPrompt`, `prependSystemContext`, atau `appendSystemContext` sebelum prompt dikirim. Gunakan `prependContext` untuk teks dinamis per giliran dan field konteks sistem untuk panduan stabil yang seharusnya berada di ruang system prompt.
- **`before_agent_start`**: hook kompatibilitas lama yang dapat berjalan pada salah satu fase; gunakan hook eksplisit di atas jika memungkinkan.
- **`before_agent_reply`**: berjalan setelah tindakan inline dan sebelum pemanggilan LLM, memungkinkan plugin mengklaim giliran dan mengembalikan balasan sintetis atau membisukan giliran sepenuhnya.
- **`before_model_resolve`**: berjalan sebelum sesi (tanpa `messages`) untuk menimpa provider/model secara deterministik sebelum resolusi model.
- **`before_prompt_build`**: berjalan setelah sesi dimuat (dengan `messages`) untuk menyuntikkan `prependContext`, `systemPrompt`, `prependSystemContext`, atau `appendSystemContext` sebelum prompt dikirimkan. Gunakan `prependContext` untuk teks dinamis per giliran dan field system-context untuk panduan stabil yang harus berada dalam ruang system prompt.
- **`before_agent_start`**: hook kompatibilitas lama yang dapat berjalan di salah satu fase; lebih baik gunakan hook eksplisit di atas.
- **`before_agent_reply`**: berjalan setelah tindakan inline dan sebelum pemanggilan LLM, memungkinkan plugin mengambil alih giliran dan mengembalikan balasan sintetis atau membungkam giliran sepenuhnya.
- **`agent_end`**: memeriksa daftar pesan akhir dan metadata proses setelah selesai.
- **`before_compaction` / `after_compaction`**: mengamati atau memberi anotasi pada siklus compaction.
- **`before_compaction` / `after_compaction`**: mengamati atau memberi anotasi pada siklus pemadatan.
- **`before_tool_call` / `after_tool_call`**: mencegat parameter/hasil alat.
- **`before_install`**: memeriksa temuan pemindaian bawaan dan secara opsional memblokir instalasi skill atau plugin.
- **`tool_result_persist`**: secara sinkron mengubah hasil alat sebelum ditulis ke transkrip sesi.
- **`tool_result_persist`**: secara sinkron mentransformasi hasil alat sebelum ditulis ke transkrip sesi.
- **`message_received` / `message_sending` / `message_sent`**: hook pesan masuk + keluar.
- **`session_start` / `session_end`**: batas siklus hidup sesi.
- **`gateway_start` / `gateway_stop`**: peristiwa siklus hidup gateway.
Aturan keputusan hook untuk pengaman keluar/alat:
Aturan keputusan hook untuk guard keluar/alat:
- `before_tool_call`: `{ block: true }` bersifat terminal dan menghentikan handler prioritas lebih rendah.
- `before_tool_call`: `{ block: true }` bersifat terminal dan menghentikan handler berprioritas lebih rendah.
- `before_tool_call`: `{ block: false }` adalah no-op dan tidak menghapus blok sebelumnya.
- `before_install`: `{ block: true }` bersifat terminal dan menghentikan handler prioritas lebih rendah.
- `before_install`: `{ block: true }` bersifat terminal dan menghentikan handler berprioritas lebih rendah.
- `before_install`: `{ block: false }` adalah no-op dan tidak menghapus blok sebelumnya.
- `message_sending`: `{ cancel: true }` bersifat terminal dan menghentikan handler prioritas lebih rendah.
- `message_sending`: `{ cancel: false }` adalah no-op dan tidak menghapus cancel sebelumnya.
- `message_sending`: `{ cancel: true }` bersifat terminal dan menghentikan handler berprioritas lebih rendah.
- `message_sending`: `{ cancel: false }` adalah no-op dan tidak menghapus pembatalan sebelumnya.
Lihat [Hook plugin](/id/plugins/architecture#provider-runtime-hooks) untuk API hook dan detail pendaftaran.
Lihat [Plugin hooks](/id/plugins/architecture#provider-runtime-hooks) untuk API hook dan detail pendaftaran.
## Streaming + balasan parsial
- Delta asisten di-stream dari pi-agent-core dan dipancarkan sebagai peristiwa `assistant`.
- Streaming blok dapat memancarkan balasan parsial pada `text_end` atau `message_end`.
- Streaming reasoning dapat dipancarkan sebagai stream terpisah atau sebagai balasan blok.
- Delta asisten di-stream dari pi-agent-core dan dikirim sebagai peristiwa `assistant`.
- Streaming blok dapat mengirim balasan parsial baik pada `text_end` maupun `message_end`.
- Streaming reasoning dapat dikirim sebagai stream terpisah atau sebagai balasan blok.
- Lihat [Streaming](/id/concepts/streaming) untuk perilaku chunking dan balasan blok.
## Eksekusi alat + alat pesan
## Eksekusi alat + alat perpesanan
- Peristiwa mulai/pembaruan/akhir alat dipancarkan pada stream `tool`.
- Hasil alat disanitasi untuk ukuran dan payload gambar sebelum dicatat/dipancarkan.
- Pengiriman alat pesan dilacak untuk menekan konfirmasi asisten duplikat.
- Peristiwa mulai/pembaruan/selesai alat dikirim di stream `tool`.
- Hasil alat disanitasi untuk ukuran dan payload gambar sebelum dicatat/dikirim.
- Pengiriman alat perpesanan dilacak untuk menekan konfirmasi asisten yang duplikat.
## Pembentukan balasan + penekanan
- Payload akhir dirakit dari:
- teks asisten (dan reasoning opsional)
- ringkasan alat inline (saat verbose + diizinkan)
- teks error asisten saat model mengalami error
- Token senyap yang tepat `NO_REPLY` / `no_reply` difilter dari payload
keluar.
- Duplikat alat pesan dihapus dari daftar payload akhir.
- Jika tidak ada payload yang dapat dirender yang tersisa dan alat mengalami error, balasan error alat fallback dipancarkan
(kecuali alat pesan sudah mengirim balasan yang terlihat oleh pengguna).
- teks kesalahan asisten saat model mengalami error
- Token hening yang persis `NO_REPLY` / `no_reply` disaring dari
payload keluar.
- Duplikat alat perpesanan dihapus dari daftar payload akhir.
- Jika tidak ada payload yang dapat dirender dan alat mengalami error, balasan fallback kesalahan alat akan dikirim
(kecuali alat perpesanan sudah mengirim balasan yang terlihat oleh pengguna).
## Compaction + percobaan ulang
## Pemadatan + percobaan ulang
- Auto-compaction memancarkan peristiwa stream `compaction` dan dapat memicu percobaan ulang.
- Pemadatan otomatis mengirim peristiwa stream `compaction` dan dapat memicu percobaan ulang.
- Saat percobaan ulang, buffer dalam memori dan ringkasan alat direset untuk menghindari output duplikat.
- Lihat [Compaction](/id/concepts/compaction) untuk pipeline compaction.
- Lihat [Compaction](/id/concepts/compaction) untuk pipeline pemadatan.
## Stream peristiwa (saat ini)
- `lifecycle`: dipancarkan oleh `subscribeEmbeddedPiSession` (dan sebagai fallback oleh `agentCommand`)
- `lifecycle`: dikirim oleh `subscribeEmbeddedPiSession` (dan sebagai fallback oleh `agentCommand`)
- `assistant`: delta streaming dari pi-agent-core
- `tool`: peristiwa alat streaming dari pi-agent-core
## Penanganan kanal chat
## Penanganan channel chat
- Delta asisten dibuffer ke dalam pesan chat `delta`.
- Chat `final` dipancarkan pada **akhir/error siklus hidup**.
- Delta asisten dibuffer menjadi pesan chat `delta`.
- Chat `final` dikirim pada **lifecycle end/error**.
## Batas waktu
## Timeout
- Default `agent.wait`: 30 detik (hanya penantian). Parameter `timeoutMs` menimpa.
- Runtime agen: default `agents.defaults.timeoutSeconds` adalah 172800 dtk (48 jam); ditegakkan dalam timer abort `runEmbeddedPiAgent`.
- Batas waktu idle LLM: `agents.defaults.llm.idleTimeoutSeconds` membatalkan permintaan model saat tidak ada potongan respons yang tiba sebelum jendela idle berakhir. Tetapkan ini secara eksplisit untuk model lokal lambat atau provider reasoning/pemanggilan alat; tetapkan ke 0 untuk menonaktifkan. Jika tidak ditetapkan, OpenClaw menggunakan `agents.defaults.timeoutSeconds` jika dikonfigurasi, atau 60 dtk jika tidak. Proses yang dipicu cron tanpa batas waktu LLM atau agen eksplisit menonaktifkan watchdog idle dan bergantung pada batas waktu luar cron.
- Default `agent.wait`: 30 dtk (hanya penantian). Parameter `timeoutMs` menimpa nilai ini.
- Runtime agen: default `agents.defaults.timeoutSeconds` adalah 172800 dtk (48 jam); diterapkan di timer pembatalan `runEmbeddedPiAgent`.
- Timeout idle LLM: `agents.defaults.llm.idleTimeoutSeconds` membatalkan permintaan model ketika tidak ada chunk respons yang datang sebelum jendela idle berakhir. Atur secara eksplisit untuk model lokal yang lambat atau provider reasoning/pemanggilan alat; atur ke 0 untuk menonaktifkan. Jika tidak diatur, OpenClaw menggunakan `agents.defaults.timeoutSeconds` bila dikonfigurasi, atau 120 dtk bila tidak. Proses yang dipicu cron tanpa timeout LLM atau agen eksplisit menonaktifkan watchdog idle dan mengandalkan timeout luar cron.
## Tempat proses bisa berakhir lebih awal
## Tempat proses dapat berakhir lebih awal
- Batas waktu agen (abort)
- Timeout agen (abort)
- AbortSignal (batal)
- Gateway terputus atau batas waktu RPC
- Batas waktu `agent.wait` (hanya penantian, tidak menghentikan agen)
- Gateway terputus atau timeout RPC
- Timeout `agent.wait` (hanya penantian, tidak menghentikan agen)
## Terkait
- [Tools](/id/tools) — alat agen yang tersedia
- [Hooks](/id/automation/hooks) — skrip berbasis peristiwa yang dipicu oleh peristiwa siklus hidup agen
- [Compaction](/id/concepts/compaction) — cara percakapan panjang diringkas
- [Compaction](/id/concepts/compaction) — bagaimana percakapan panjang diringkas
- [Exec Approvals](/id/tools/exec-approvals) — gerbang persetujuan untuk perintah shell
- [Thinking](/id/tools/thinking) — konfigurasi tingkat thinking/reasoning

View File

@ -1,29 +1,26 @@
---
read_when:
- Anda ingin memahami cara kerja memory_search
- Anda ingin memilih provider embedding
- Anda ingin memahami cara kerja `memory_search`
- Anda ingin memilih penyedia embedding
- Anda ingin menyetel kualitas pencarian
summary: Cara pencarian memori menemukan catatan yang relevan menggunakan embeddings dan pengambilan hibrida
summary: Bagaimana pencarian memori menemukan catatan yang relevan menggunakan embeddings dan pengambilan hibrida
title: Pencarian Memori
x-i18n:
generated_at: "2026-04-06T03:06:29Z"
generated_at: "2026-04-10T09:13:13Z"
model: gpt-5.4
provider: openai
source_hash: b6541cd702bff41f9a468dad75ea438b70c44db7c65a4b793cbacaf9e583c7e9
source_hash: ca0237f4f1ee69dcbfb12e6e9527a53e368c0bf9b429e506831d4af2f3a3ac6f
source_path: concepts/memory-search.md
workflow: 15
---
# Pencarian Memori
`memory_search` menemukan catatan yang relevan dari file memori Anda, bahkan saat
susunan katanya berbeda dari teks aslinya. Fitur ini bekerja dengan mengindeks memori ke dalam
potongan-potongan kecil dan mencarinya menggunakan embedding, kata kunci, atau keduanya.
`memory_search` menemukan catatan yang relevan dari file memori Anda, bahkan ketika susunan katanya berbeda dari teks aslinya. Fitur ini bekerja dengan mengindeks memori ke dalam potongan-potongan kecil dan mencarinya menggunakan embedding, kata kunci, atau keduanya.
## Mulai cepat
Jika Anda telah mengonfigurasi kunci API OpenAI, Gemini, Voyage, atau Mistral, pencarian memori
akan bekerja secara otomatis. Untuk menetapkan provider secara eksplisit:
Jika Anda memiliki kunci API OpenAI, Gemini, Voyage, atau Mistral yang sudah dikonfigurasi, pencarian memori akan bekerja secara otomatis. Untuk menetapkan penyedia secara eksplisit:
```json5
{
@ -37,18 +34,17 @@ akan bekerja secara otomatis. Untuk menetapkan provider secara eksplisit:
}
```
Untuk embedding lokal tanpa kunci API, gunakan `provider: "local"` (memerlukan
node-llama-cpp).
Untuk embedding lokal tanpa kunci API, gunakan `provider: "local"` (memerlukan `node-llama-cpp`).
## Provider yang didukung
## Penyedia yang didukung
| Provider | ID | Memerlukan kunci API | Catatan |
| Penyedia | ID | Memerlukan kunci API | Catatan |
| -------- | --------- | -------------------- | --------------------------------------------------- |
| OpenAI | `openai` | Ya | Terdeteksi otomatis, cepat |
| Gemini | `gemini` | Ya | Mendukung pengindeksan gambar/audio |
| Voyage | `voyage` | Ya | Terdeteksi otomatis |
| Mistral | `mistral` | Ya | Terdeteksi otomatis |
| Bedrock | `bedrock` | Tidak | Terdeteksi otomatis saat rantai kredensial AWS terselesaikan |
| Bedrock | `bedrock` | Tidak | Terdeteksi otomatis saat rantai kredensial AWS terurai |
| Ollama | `ollama` | Tidak | Lokal, harus ditetapkan secara eksplisit |
| Local | `local` | Tidak | Model GGUF, unduhan ~0.6 GB |
@ -67,36 +63,29 @@ flowchart LR
M --> R["Top Results"]
```
- **Pencarian vektor** menemukan catatan dengan makna yang serupa ("gateway host" cocok dengan
"mesin yang menjalankan OpenClaw").
- **Pencarian kata kunci BM25** menemukan kecocokan yang persis (ID, string error, config
key).
- **Pencarian vektor** menemukan catatan dengan makna yang serupa ("gateway host" cocok dengan "mesin yang menjalankan OpenClaw").
- **Pencarian kata kunci BM25** menemukan kecocokan persis (ID, string kesalahan, kunci konfigurasi).
Jika hanya satu jalur yang tersedia (tanpa embedding atau tanpa FTS), jalur lainnya akan berjalan sendiri.
Jika hanya satu jalur yang tersedia (tidak ada embedding atau tidak ada FTS), jalur lainnya akan berjalan sendiri.
## Meningkatkan kualitas pencarian
Dua fitur opsional membantu saat Anda memiliki riwayat catatan yang besar:
Dua fitur opsional membantu ketika Anda memiliki riwayat catatan yang besar:
### Peluruhan temporal
Catatan lama secara bertahap kehilangan bobot peringkat sehingga informasi terbaru muncul lebih dulu.
Dengan half-life default 30 hari, skor catatan dari bulan lalu menjadi 50% dari
bobot aslinya. File evergreen seperti `MEMORY.md` tidak pernah mengalami peluruhan.
Catatan lama secara bertahap kehilangan bobot peringkat sehingga informasi terbaru muncul lebih dulu. Dengan half-life bawaan 30 hari, skor catatan dari bulan lalu menjadi 50% dari bobot aslinya. File permanen seperti `MEMORY.md` tidak pernah dikenai peluruhan.
<Tip>
Aktifkan peluruhan temporal jika agen Anda memiliki catatan harian selama berbulan-bulan dan informasi usang
terus berada di atas konteks terbaru.
Aktifkan peluruhan temporal jika agen Anda memiliki catatan harian selama berbulan-bulan dan informasi usang terus mendapat peringkat lebih tinggi daripada konteks terbaru.
</Tip>
### MMR (keragaman)
Mengurangi hasil yang redundan. Jika lima catatan semuanya menyebut config router yang sama, MMR
memastikan hasil teratas mencakup topik yang berbeda alih-alih berulang.
Mengurangi hasil yang berulang. Jika lima catatan semuanya menyebut konfigurasi router yang sama, MMR memastikan hasil teratas mencakup topik yang berbeda alih-alih mengulang hal yang sama.
<Tip>
Aktifkan MMR jika `memory_search` terus mengembalikan cuplikan yang hampir duplikat dari
catatan harian yang berbeda.
Aktifkan MMR jika `memory_search` terus mengembalikan cuplikan yang hampir duplikat dari catatan harian yang berbeda.
</Tip>
### Aktifkan keduanya
@ -120,30 +109,22 @@ catatan harian yang berbeda.
## Memori multimodal
Dengan Gemini Embedding 2, Anda dapat mengindeks gambar dan file audio bersama
Markdown. Query pencarian tetap berupa teks, tetapi akan dicocokkan dengan konten visual dan audio.
Lihat [referensi konfigurasi memori](/id/reference/memory-config) untuk
penyiapannya.
Dengan Gemini Embedding 2, Anda dapat mengindeks file gambar dan audio bersama Markdown. Kuery pencarian tetap berupa teks, tetapi akan dicocokkan dengan konten visual dan audio. Lihat [referensi konfigurasi Memori](/id/reference/memory-config) untuk penyiapan.
## Pencarian memori sesi
Anda dapat secara opsional mengindeks transkrip sesi agar `memory_search` dapat mengingat
percakapan sebelumnya. Fitur ini bersifat opt-in melalui
`memorySearch.experimental.sessionMemory`. Lihat
[referensi konfigurasi](/id/reference/memory-config) untuk detailnya.
Anda dapat secara opsional mengindeks transkrip sesi sehingga `memory_search` dapat mengingat percakapan sebelumnya. Ini bersifat opt-in melalui `memorySearch.experimental.sessionMemory`. Lihat [referensi konfigurasi](/id/reference/memory-config) untuk detailnya.
## Pemecahan masalah
**Tidak ada hasil?** Jalankan `openclaw memory status` untuk memeriksa indeks. Jika kosong, jalankan
`openclaw memory index --force`.
**Tidak ada hasil?** Jalankan `openclaw memory status` untuk memeriksa indeks. Jika kosong, jalankan `openclaw memory index --force`.
**Hanya cocok dengan kata kunci?** Provider embedding Anda mungkin belum dikonfigurasi. Periksa
`openclaw memory status --deep`.
**Hanya kecocokan kata kunci?** Penyedia embedding Anda mungkin belum dikonfigurasi. Periksa `openclaw memory status --deep`.
**Teks CJK tidak ditemukan?** Bangun ulang indeks FTS dengan
`openclaw memory index --force`.
**Teks CJK tidak ditemukan?** Bangun ulang indeks FTS dengan `openclaw memory index --force`.
## Bacaan lanjutan
- [Memori Aktif](/id/concepts/active-memory) -- memori sub-agen untuk sesi obrolan interaktif
- [Memori](/id/concepts/memory) -- tata letak file, backend, alat
- [Referensi konfigurasi memori](/id/reference/memory-config) -- semua opsi konfigurasi
- [Referensi konfigurasi Memori](/id/reference/memory-config) -- semua opsi konfigurasi

View File

@ -2,36 +2,32 @@
read_when:
- Memperluas qa-lab atau qa-channel
- Menambahkan skenario QA yang didukung repo
- Membangun otomatisasi QA dengan realisme lebih tinggi di sekitar dasbor Gateway
summary: Bentuk otomatisasi QA privat untuk qa-lab, qa-channel, skenario ber-seed, dan laporan protokol
- Membangun otomatisasi QA dengan realisme lebih tinggi di sekitar dashboard Gateway
summary: Bentuk otomatisasi QA privat untuk qa-lab, qa-channel, skenario yang di-seed, dan laporan protokol
title: Otomatisasi QA E2E
x-i18n:
generated_at: "2026-04-09T01:27:42Z"
generated_at: "2026-04-10T09:13:12Z"
model: gpt-5.4
provider: openai
source_hash: c922607d67e0f3a2489ac82bc9f510f7294ced039c1014c15b676d826441d833
source_hash: 357d6698304ff7a8c4aa8a7be97f684d50f72b524740050aa761ac0ee68266de
source_path: concepts/qa-e2e-automation.md
workflow: 15
---
# Otomatisasi QA E2E
Stack QA privat dimaksudkan untuk menguji OpenClaw dengan cara yang lebih realistis,
berbentuk kanal, dibandingkan yang dapat dicapai oleh satu unit test.
Stack QA privat dimaksudkan untuk menguji OpenClaw dengan cara yang lebih realistis dan berbentuk channel dibandingkan yang bisa dicapai oleh satu unit test.
Komponen saat ini:
- `extensions/qa-channel`: kanal pesan sintetis dengan permukaan DM, channel, thread,
reaction, edit, dan delete.
- `extensions/qa-lab`: UI debugger dan bus QA untuk mengamati transkrip,
menyuntikkan pesan masuk, dan mengekspor laporan Markdown.
- `qa/`: aset seed yang didukung repo untuk tugas kickoff dan skenario QA
dasar.
- `extensions/qa-channel`: channel pesan sintetis dengan permukaan DM, channel, thread, reaction, edit, dan delete.
- `extensions/qa-lab`: UI debugger dan bus QA untuk mengamati transkrip, menyuntikkan pesan masuk, dan mengekspor laporan Markdown.
- `qa/`: aset seed yang didukung repo untuk tugas kickoff dan skenario QA dasar.
Alur operator QA saat ini adalah situs QA dua panel:
- Kiri: dasbor Gateway (Control UI) dengan agen.
- Kanan: QA Lab, yang menampilkan transkrip bergaya Slack dan rencana skenario.
- Kiri: dashboard Gateway (Control UI) dengan agen.
- Kanan: QA Lab, menampilkan transkrip bergaya Slack dan rencana skenario.
Jalankan dengan:
@ -39,13 +35,9 @@ Jalankan dengan:
pnpm qa:lab:up
```
Perintah itu membangun situs QA, memulai lane gateway berbasis Docker, dan menampilkan
halaman QA Lab tempat operator atau loop otomatisasi dapat memberi agen misi QA,
mengamati perilaku kanal nyata, dan mencatat apa yang berhasil, gagal, atau
tetap terblokir.
Perintah itu membangun situs QA, memulai lane gateway berbasis Docker, dan mengekspos halaman QA Lab tempat operator atau loop otomatisasi dapat memberi agen sebuah misi QA, mengamati perilaku channel nyata, dan mencatat apa yang berhasil, gagal, atau tetap terblokir.
Untuk iterasi UI QA Lab yang lebih cepat tanpa membangun ulang image Docker setiap kali,
mulai stack dengan bundle QA Lab yang di-bind-mount:
Untuk iterasi UI QA Lab yang lebih cepat tanpa membangun ulang image Docker setiap kali, mulai stack dengan bundle QA Lab yang di-bind-mount:
```bash
pnpm openclaw qa docker-build-image
@ -54,9 +46,17 @@ pnpm qa:lab:up:fast
pnpm qa:lab:watch
```
`qa:lab:up:fast` menjaga layanan Docker tetap berjalan pada image yang sudah dibangun sebelumnya dan melakukan bind-mount
`extensions/qa-lab/web/dist` ke dalam container `qa-lab`. `qa:lab:watch`
membangun ulang bundle itu saat ada perubahan, dan browser memuat ulang otomatis saat hash aset QA Lab berubah.
`qa:lab:up:fast` menjaga layanan Docker tetap berjalan pada image yang sudah dibangun sebelumnya dan melakukan bind-mount `extensions/qa-lab/web/dist` ke dalam container `qa-lab`. `qa:lab:watch` membangun ulang bundle tersebut saat ada perubahan, dan browser akan memuat ulang otomatis ketika hash aset QA Lab berubah.
Untuk lane VM Linux sekali pakai tanpa membawa Docker ke dalam jalur QA, jalankan:
```bash
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
```
Ini akan mem-boot guest Multipass baru, menginstal dependensi, membangun OpenClaw di dalam guest, menjalankan `qa suite`, lalu menyalin laporan dan ringkasan QA normal kembali ke `.artifacts/qa-e2e/...` pada host.
Perintah ini menggunakan kembali perilaku pemilihan skenario yang sama seperti `qa suite` pada host.
Live run meneruskan input autentikasi QA yang didukung dan praktis untuk guest: kunci penyedia berbasis env, path konfigurasi penyedia live QA, dan `CODEX_HOME` jika ada. Pertahankan `--output-dir` di bawah root repo agar guest dapat menulis kembali melalui workspace yang di-mount.
## Seed yang didukung repo
@ -65,17 +65,16 @@ Aset seed berada di `qa/`:
- `qa/scenarios/index.md`
- `qa/scenarios/*.md`
Ini sengaja disimpan di git agar rencana QA terlihat oleh manusia maupun
agen. Daftar dasar harus tetap cukup luas untuk mencakup:
Ini sengaja disimpan di git agar rencana QA terlihat oleh manusia maupun agen. Daftar dasar harus tetap cukup luas untuk mencakup:
- chat DM dan channel
- perilaku thread
- siklus hidup aksi pesan
- callback cron
- recall memori
- pergantian model
- peralihan model
- handoff subagen
- pembacaan repo dan pembacaan dokumen
- pembacaan repo dan dokumen
- satu tugas build kecil seperti Lobster Invaders
## Pelaporan
@ -88,8 +87,7 @@ Laporan tersebut harus menjawab:
- Apa yang tetap terblokir
- Skenario tindak lanjut apa yang layak ditambahkan
Untuk pemeriksaan karakter dan gaya, jalankan skenario yang sama di beberapa ref model live
dan tulis laporan Markdown yang dinilai:
Untuk pemeriksaan karakter dan gaya, jalankan skenario yang sama pada beberapa ref model live dan tulis laporan Markdown yang dinilai:
```bash
pnpm openclaw qa character-eval \
@ -108,36 +106,19 @@ pnpm openclaw qa character-eval \
--judge-concurrency 16
```
Perintah ini menjalankan child process gateway QA lokal, bukan Docker. Skenario evaluasi karakter
harus menetapkan persona melalui `SOUL.md`, lalu menjalankan giliran pengguna biasa
seperti chat, bantuan workspace, dan tugas file kecil. Model kandidat
tidak boleh diberi tahu bahwa model tersebut sedang dievaluasi. Perintah ini mempertahankan setiap
transkrip lengkap, mencatat statistik dasar run, lalu meminta model penilai dalam mode cepat dengan
penalaran `xhigh` untuk memberi peringkat pada run berdasarkan kealamian, vibe, dan humor.
Gunakan `--blind-judge-models` saat membandingkan provider: prompt penilai tetap menerima
setiap transkrip dan status run, tetapi ref kandidat diganti dengan label netral
seperti `candidate-01`; laporan memetakan kembali peringkat ke ref sebenarnya setelah
parsing.
Run kandidat secara default menggunakan thinking `high`, dengan `xhigh` untuk model OpenAI yang
mendukungnya. Ganti kandidat tertentu secara inline dengan
`--model provider/model,thinking=<level>`. `--thinking <level>` tetap menetapkan
fallback global, dan bentuk lama `--model-thinking <provider/model=level>` tetap
dipertahankan untuk kompatibilitas.
Ref kandidat OpenAI secara default menggunakan mode cepat agar pemrosesan prioritas dipakai jika
provider mendukungnya. Tambahkan `,fast`, `,no-fast`, atau `,fast=false` secara inline ketika
satu kandidat atau penilai memerlukan override. Berikan `--fast` hanya jika Anda ingin
memaksa mode cepat aktif untuk setiap model kandidat. Durasi kandidat dan penilai
dicatat dalam laporan untuk analisis benchmark, tetapi prompt penilai secara eksplisit menyatakan
agar tidak memberi peringkat berdasarkan kecepatan.
Run model kandidat dan penilai keduanya secara default menggunakan concurrency 16. Turunkan
`--concurrency` atau `--judge-concurrency` ketika batas provider atau tekanan gateway lokal
membuat run terlalu bising.
Perintah ini menjalankan child process gateway QA lokal, bukan Docker. Skenario evaluasi karakter harus menetapkan persona melalui `SOUL.md`, lalu menjalankan giliran pengguna biasa seperti chat, bantuan workspace, dan tugas file kecil. Model kandidat tidak boleh diberi tahu bahwa model tersebut sedang dievaluasi. Perintah ini mempertahankan setiap transkrip lengkap, mencatat statistik run dasar, lalu meminta model juri dalam mode fast dengan penalaran `xhigh` untuk memberi peringkat run berdasarkan kealamian, vibe, dan humor.
Gunakan `--blind-judge-models` saat membandingkan penyedia: prompt juri tetap menerima setiap transkrip dan status run, tetapi ref kandidat diganti dengan label netral seperti `candidate-01`; laporan memetakan kembali peringkat ke ref asli setelah parsing.
Run kandidat secara default menggunakan thinking `high`, dengan `xhigh` untuk model OpenAI yang mendukungnya. Override kandidat tertentu secara inline dengan
`--model provider/model,thinking=<level>`. `--thinking <level>` tetap menetapkan fallback global, dan format lama `--model-thinking <provider/model=level>` tetap dipertahankan demi kompatibilitas.
Ref kandidat OpenAI secara default menggunakan mode fast agar pemrosesan prioritas dipakai di tempat yang didukung oleh penyedia. Tambahkan `,fast`, `,no-fast`, atau `,fast=false` secara inline ketika satu kandidat atau juri memerlukan override. Gunakan `--fast` hanya saat Anda ingin memaksa mode fast aktif untuk setiap model kandidat. Durasi kandidat dan juri dicatat dalam laporan untuk analisis benchmark, tetapi prompt juri secara eksplisit menyatakan agar tidak memberi peringkat berdasarkan kecepatan.
Run model kandidat dan juri sama-sama secara default menggunakan konkurensi 16. Turunkan
`--concurrency` atau `--judge-concurrency` ketika batas penyedia atau tekanan gateway lokal membuat sebuah run terlalu bising.
Saat tidak ada kandidat `--model` yang diberikan, evaluasi karakter secara default menggunakan
`openai/gpt-5.4`, `openai/gpt-5.2`, `openai/gpt-5`, `anthropic/claude-opus-4-6`,
`anthropic/claude-sonnet-4-6`, `zai/glm-5.1`,
`moonshot/kimi-k2.5`, dan
`google/gemini-3.1-pro-preview` saat tidak ada `--model` yang diberikan.
Saat tidak ada `--judge-model` yang diberikan, penilai secara default menggunakan
`google/gemini-3.1-pro-preview` ketika tidak ada `--model` yang diberikan.
Saat tidak ada `--judge-model` yang diberikan, juri default-nya adalah
`openai/gpt-5.4,thinking=xhigh,fast` dan
`anthropic/claude-opus-4-6,thinking=high`.

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +1,29 @@
---
read_when:
- Menerapkan atau memperbarui klien gateway WS
- Mengimplementasikan atau memperbarui klien WS gateway
- Men-debug ketidakcocokan protokol atau kegagalan koneksi
- Membuat ulang skema/model protokol
summary: 'Protokol WebSocket Gateway: handshake, frame, pembuatan versi'
title: Gateway Protocol
title: Protokol Gateway
x-i18n:
generated_at: "2026-04-08T02:15:59Z"
generated_at: "2026-04-10T09:13:11Z"
model: gpt-5.4
provider: openai
source_hash: 8635e3ac1dd311dbd3a770b088868aa1495a8d53b3ebc1eae0dfda3b2bf4694a
source_hash: 83c820c46d4803d571c770468fd6782619eaa1dca253e156e8087dec735c127f
source_path: gateway/protocol.md
workflow: 15
---
# Gateway protocol (WebSocket)
# Protokol Gateway (WebSocket)
Protokol Gateway WS adalah **bidang kontrol tunggal + transport node** untuk
OpenClaw. Semua klien (CLI, UI web, aplikasi macOS, node iOS/Android, node
headless) terhubung melalui WebSocket dan mendeklarasikan **role** + **scope**
mereka saat handshake.
Protokol WS Gateway adalah **bidang kendali tunggal + transport node** untuk
OpenClaw. Semua klien (CLI, UI web, app macOS, node iOS/Android, node headless)
terhubung melalui WebSocket dan mendeklarasikan **peran** + **cakupan** mereka
saat waktu handshake.
## Transport
- WebSocket, frame teks dengan payload JSON.
- WebSocket, frame teks dengan muatan JSON.
- Frame pertama **harus** berupa permintaan `connect`.
## Handshake (connect)
@ -84,7 +84,7 @@ Gateway → Klien:
}
```
Saat token perangkat diterbitkan, `hello-ok` juga menyertakan:
Saat token perangkat diterbitkan, `hello-ok` juga mencakup:
```json
{
@ -97,7 +97,7 @@ Saat token perangkat diterbitkan, `hello-ok` juga menyertakan:
```
Selama handoff bootstrap tepercaya, `hello-ok.auth` juga dapat menyertakan entri
role tambahan yang dibatasi dalam `deviceTokens`:
peran terbatas tambahan dalam `deviceTokens`:
```json
{
@ -117,11 +117,11 @@ role tambahan yang dibatasi dalam `deviceTokens`:
```
Untuk alur bootstrap node/operator bawaan, token node utama tetap
`scopes: []` dan token operator hasil handoff tetap dibatasi ke allowlist
`scopes: []` dan token operator yang di-handoff tetap dibatasi ke allowlist
operator bootstrap (`operator.approvals`, `operator.read`,
`operator.talk.secrets`, `operator.write`). Pemeriksaan scope bootstrap tetap
berprefiks role: entri operator hanya memenuhi permintaan operator, dan role
non-operator tetap memerlukan scope di bawah prefiks role mereka sendiri.
`operator.talk.secrets`, `operator.write`). Pemeriksaan cakupan bootstrap tetap
berawalan peran: entri operator hanya memenuhi permintaan operator, dan peran
non-operator tetap memerlukan cakupan di bawah awalan peran mereka sendiri.
### Contoh node
@ -162,20 +162,20 @@ non-operator tetap memerlukan scope di bawah prefiks role mereka sendiri.
- **Permintaan**: `{type:"req", id, method, params}`
- **Respons**: `{type:"res", id, ok, payload|error}`
- **Event**: `{type:"event", event, payload, seq?, stateVersion?}`
- **Peristiwa**: `{type:"event", event, payload, seq?, stateVersion?}`
Metode yang memiliki efek samping memerlukan **kunci idempoten** (lihat skema).
Metode yang memiliki efek samping memerlukan **kunci idempotensi** (lihat skema).
## Roles + scopes
## Peran + cakupan
### Roles
### Peran
- `operator` = klien bidang kontrol (CLI/UI/otomatisasi).
- `operator` = klien bidang kendali (CLI/UI/otomasi).
- `node` = host kapabilitas (camera/screen/canvas/system.run).
### Scopes (operator)
### Cakupan (operator)
Scope umum:
Cakupan umum:
- `operator.read`
- `operator.write`
@ -187,135 +187,136 @@ Scope umum:
`talk.config` dengan `includeSecrets: true` memerlukan `operator.talk.secrets`
(atau `operator.admin`).
Metode RPC gateway yang didaftarkan plugin dapat meminta scope operatornya
sendiri, tetapi prefiks admin inti yang dicadangkan (`config.*`, `exec.approvals.*`, `wizard.*`,
`update.*`) selalu dipetakan ke `operator.admin`.
Metode RPC gateway yang didaftarkan plugin dapat meminta cakupan operatornya
sendiri, tetapi awalan admin inti yang dicadangkan (`config.*`,
`exec.approvals.*`, `wizard.*`, `update.*`) selalu diselesaikan ke
`operator.admin`.
Scope metode hanyalah gerbang pertama. Beberapa slash command yang dicapai melalui
`chat.send` menerapkan pemeriksaan tingkat perintah yang lebih ketat di atasnya. Misalnya, penulisan
persisten `/config set` dan `/config unset` memerlukan `operator.admin`.
Cakupan metode hanyalah gerbang pertama. Beberapa slash command yang dicapai
melalui `chat.send` menerapkan pemeriksaan tingkat perintah yang lebih ketat di
atasnya. Misalnya, penulisan persisten `/config set` dan `/config unset`
memerlukan `operator.admin`.
`node.pair.approve` juga memiliki pemeriksaan scope tambahan pada saat persetujuan di atas
scope metode dasarnya:
`node.pair.approve` juga memiliki pemeriksaan cakupan saat persetujuan tambahan
di atas cakupan metode dasar:
- permintaan tanpa command: `operator.pairing`
- permintaan dengan command node non-exec: `operator.pairing` + `operator.write`
- permintaan tanpa perintah: `operator.pairing`
- permintaan dengan perintah node non-exec: `operator.pairing` + `operator.write`
- permintaan yang menyertakan `system.run`, `system.run.prepare`, atau `system.which`:
`operator.pairing` + `operator.admin`
### Caps/commands/permissions (node)
Node mendeklarasikan klaim kapabilitas saat connect:
Node mendeklarasikan klaim kapabilitas saat waktu connect:
- `caps`: kategori kapabilitas tingkat tinggi.
- `commands`: allowlist command untuk invoke.
- `permissions`: toggle granular (mis. `screen.record`, `camera.capture`).
- `commands`: allowlist perintah untuk invoke.
- `permissions`: toggle terperinci (misalnya `screen.record`, `camera.capture`).
Gateway memperlakukan ini sebagai **klaim** dan menegakkan allowlist di sisi server.
Gateway memperlakukan ini sebagai **klaim** dan menegakkan allowlist sisi server.
## Presence
## Kehadiran
- `system-presence` mengembalikan entri yang dikunci berdasarkan identitas perangkat.
- Entri presence menyertakan `deviceId`, `roles`, dan `scopes` agar UI dapat menampilkan satu baris per perangkat
bahkan ketika perangkat tersebut terhubung sebagai **operator** dan **node** sekaligus.
- `system-presence` mengembalikan entri yang dikunci oleh identitas perangkat.
- Entri kehadiran mencakup `deviceId`, `roles`, dan `scopes` sehingga UI dapat menampilkan satu baris per perangkat
bahkan saat perangkat terhubung sebagai **operator** dan **node**.
## Keluarga metode RPC umum
Halaman ini bukan dump lengkap yang dihasilkan, tetapi permukaan WS publik lebih luas
daripada contoh handshake/auth di atas. Ini adalah keluarga metode utama yang saat ini
diekspos oleh Gateway.
Halaman ini bukan dump penuh yang dihasilkan, tetapi permukaan WS publik lebih
luas daripada contoh handshake/auth di atas. Ini adalah keluarga metode utama
yang saat ini diekspos Gateway.
`hello-ok.features.methods` adalah daftar penemuan yang konservatif yang dibangun dari
`src/gateway/server-methods-list.ts` plus ekspor metode plugin/channel yang dimuat.
Perlakukan ini sebagai penemuan fitur, bukan sebagai dump yang dihasilkan dari setiap helper yang dapat dipanggil
yang diimplementasikan dalam `src/gateway/server-methods/*.ts`.
`hello-ok.features.methods` adalah daftar penemuan konservatif yang dibangun dari
`src/gateway/server-methods-list.ts` ditambah ekspor metode plugin/channel yang dimuat.
Perlakukan ini sebagai penemuan fitur, bukan sebagai dump yang dihasilkan dari setiap helper
yang dapat dipanggil yang diimplementasikan dalam `src/gateway/server-methods/*.ts`.
### Sistem dan identitas
- `health` mengembalikan snapshot kesehatan gateway yang di-cache atau baru diprobe.
- `status` mengembalikan ringkasan gateway bergaya `/status`; field sensitif hanya
disertakan untuk klien operator dengan scope admin.
- `status` mengembalikan ringkasan gateway gaya `/status`; field sensitif hanya
disertakan untuk klien operator bercakupan admin.
- `gateway.identity.get` mengembalikan identitas perangkat gateway yang digunakan oleh alur relay dan
pairing.
- `system-presence` mengembalikan snapshot presence saat ini untuk perangkat
- `system-presence` mengembalikan snapshot kehadiran saat ini untuk perangkat
operator/node yang terhubung.
- `system-event` menambahkan event sistem dan dapat memperbarui/menyiarkan konteks
presence.
- `last-heartbeat` mengembalikan event heartbeat persist terbaru.
- `set-heartbeats` mengaktifkan/menonaktifkan pemrosesan heartbeat di gateway.
- `system-event` menambahkan peristiwa sistem dan dapat memperbarui/menyiarkan konteks
kehadiran.
- `last-heartbeat` mengembalikan peristiwa heartbeat persisten terbaru.
- `set-heartbeats` mengaktifkan atau menonaktifkan pemrosesan heartbeat pada gateway.
### Model dan penggunaan
- `models.list` mengembalikan katalog model yang diizinkan saat runtime.
- `usage.status` mengembalikan ringkasan jendela penggunaan provider/kuota tersisa.
- `usage.cost` mengembalikan ringkasan penggunaan biaya teragregasi untuk rentang tanggal.
- `models.list` mengembalikan katalog model yang diizinkan runtime.
- `usage.status` mengembalikan ringkasan jendela penggunaan/kuota tersisa provider.
- `usage.cost` mengembalikan ringkasan penggunaan biaya agregat untuk suatu rentang tanggal.
- `doctor.memory.status` mengembalikan kesiapan vector-memory / embedding untuk
workspace agen default aktif.
- `sessions.usage` mengembalikan ringkasan penggunaan per sesi.
- `sessions.usage.timeseries` mengembalikan penggunaan deret waktu untuk satu sesi.
- `sessions.usage.timeseries` mengembalikan timeseries penggunaan untuk satu sesi.
- `sessions.usage.logs` mengembalikan entri log penggunaan untuk satu sesi.
### Channel dan helper login
- `channels.status` mengembalikan ringkasan status channel/plugin bawaan + bundled.
- `channels.logout` melakukan logout dari channel/akun tertentu jika channel tersebut
- `channels.status` mengembalikan ringkasan status channel/plugin bawaan + bundel.
- `channels.logout` melakukan logout pada channel/akun tertentu jika channel
mendukung logout.
- `web.login.start` memulai alur login QR/web untuk provider channel web yang mendukung QR saat ini.
- `web.login.wait` menunggu alur login QR/web tersebut selesai dan memulai
- `web.login.start` memulai alur login QR/web untuk provider channel web
saat ini yang mendukung QR.
- `web.login.wait` menunggu hingga alur login QR/web tersebut selesai dan memulai
channel jika berhasil.
- `push.test` mengirim push APNs uji ke node iOS yang terdaftar.
- `voicewake.get` mengembalikan pemicu wake word yang tersimpan.
- `voicewake.set` memperbarui pemicu wake word dan menyiarkan perubahan.
- `voicewake.get` mengembalikan pemicu wake-word yang tersimpan.
- `voicewake.set` memperbarui pemicu wake-word dan menyiarkan perubahannya.
### Pesan dan log
### Perpesanan dan log
- `send` adalah RPC pengiriman keluar langsung untuk
pengiriman yang ditargetkan ke channel/akun/thread di luar runner chat.
- `logs.tail` mengembalikan tail file log gateway yang dikonfigurasi dengan kontrol cursor/limit dan
byte maksimum.
- `send` adalah RPC pengiriman keluar langsung untuk pengiriman yang ditargetkan ke
channel/akun/thread di luar chat runner.
- `logs.tail` mengembalikan tail log file gateway yang dikonfigurasi dengan cursor/limit dan
kontrol byte maksimum.
### Talk dan TTS
- `talk.config` mengembalikan payload konfigurasi Talk yang efektif; `includeSecrets`
- `talk.config` mengembalikan muatan konfigurasi Talk yang efektif; `includeSecrets`
memerlukan `operator.talk.secrets` (atau `operator.admin`).
- `talk.mode` menetapkan/menyiarkan status mode Talk saat ini untuk klien
WebChat/Control UI.
- `talk.speak` mensintesis ucapan melalui provider speech Talk yang aktif.
- `tts.status` mengembalikan status TTS diaktifkan, provider aktif, provider fallback,
- `talk.speak` mensintesis ucapan melalui provider ucapan Talk yang aktif.
- `tts.status` mengembalikan status TTS aktif, provider aktif, provider fallback,
dan status konfigurasi provider.
- `tts.providers` mengembalikan inventaris provider TTS yang terlihat.
- `tts.enable` dan `tts.disable` mengaktifkan/menonaktifkan status preferensi TTS.
- `tts.enable` dan `tts.disable` mengaktifkan atau menonaktifkan status preferensi TTS.
- `tts.setProvider` memperbarui provider TTS pilihan.
- `tts.convert` menjalankan konversi text-to-speech sekali jalan.
- `tts.convert` menjalankan konversi teks-ke-ucapan sekali jalan.
### Secrets, config, update, dan wizard
- `secrets.reload` me-resolve ulang SecretRef aktif dan menukar status secret runtime
hanya jika seluruh proses berhasil.
- `secrets.resolve` me-resolve penetapan secret target-command untuk
set command/target tertentu.
- `config.get` mengembalikan snapshot dan hash konfigurasi saat ini.
- `config.set` menulis payload konfigurasi yang tervalidasi.
- `config.patch` menggabungkan pembaruan konfigurasi parsial.
- `config.apply` memvalidasi + mengganti seluruh payload konfigurasi.
- `config.schema` mengembalikan payload skema konfigurasi live yang digunakan oleh Control UI dan
alat CLI: skema, `uiHints`, versi, dan metadata generasi, termasuk
metadata skema plugin + channel saat runtime dapat memuatnya. Skema tersebut
menyertakan metadata field `title` / `description` yang diturunkan dari label yang sama
dan teks bantuan yang digunakan oleh UI, termasuk object bersarang, wildcard, array-item,
dan cabang komposisi `anyOf` / `oneOf` / `allOf` saat dokumentasi field yang cocok
tersedia.
- `config.schema.lookup` mengembalikan payload lookup dengan cakupan path untuk satu path konfigurasi:
path yang dinormalisasi, node skema dangkal, hint + `hintPath` yang cocok, dan
hanya jika sepenuhnya berhasil.
- `secrets.resolve` me-resolve penetapan secret target-perintah untuk set perintah/target tertentu.
- `config.get` mengembalikan snapshot config dan hash saat ini.
- `config.set` menulis muatan config yang tervalidasi.
- `config.patch` menggabungkan pembaruan config parsial.
- `config.apply` memvalidasi + mengganti seluruh muatan config.
- `config.schema` mengembalikan muatan skema config live yang digunakan oleh Control UI dan
tooling CLI: skema, `uiHints`, versi, dan metadata generasi, termasuk
metadata skema plugin + channel saat runtime dapat memuatnya. Skema
mencakup metadata field `title` / `description` yang diturunkan dari label yang sama
dan teks bantuan yang digunakan oleh UI, termasuk object bertingkat, wildcard,
item array, dan cabang komposisi `anyOf` / `oneOf` / `allOf` saat dokumentasi field yang cocok tersedia.
- `config.schema.lookup` mengembalikan muatan lookup berbatas jalur untuk satu config
path: jalur ternormalisasi, node skema dangkal, hint + `hintPath` yang cocok, dan
ringkasan child langsung untuk drill-down UI/CLI.
- Node skema lookup mempertahankan dokumentasi yang menghadap pengguna dan field validasi umum:
`title`, `description`, `type`, `enum`, `const`, `format`, `pattern`,
batas numerik/string/array/object, dan flag boolean seperti
`additionalProperties`, `deprecated`, `readOnly`, `writeOnly`.
- Ringkasan child mengekspos `key`, `path` yang dinormalisasi, `type`, `required`,
`hasChildren`, serta `hint` / `hintPath` yang cocok.
- `update.run` menjalankan alur pembaruan gateway dan menjadwalkan restart hanya ketika
pembaruannya sendiri berhasil.
- Ringkasan child mengekspos `key`, `path` ternormalisasi, `type`, `required`,
`hasChildren`, ditambah `hint` / `hintPath` yang cocok.
- `update.run` menjalankan alur pembaruan gateway dan menjadwalkan restart hanya saat
pembaruan itu sendiri berhasil.
- `wizard.start`, `wizard.next`, `wizard.status`, dan `wizard.cancel` mengekspos
wizard onboarding melalui WS RPC.
@ -324,105 +325,108 @@ yang diimplementasikan dalam `src/gateway/server-methods/*.ts`.
#### Helper agen dan workspace
- `agents.list` mengembalikan entri agen yang dikonfigurasi.
- `agents.create`, `agents.update`, dan `agents.delete` mengelola rekaman agen dan
- `agents.create`, `agents.update`, dan `agents.delete` mengelola catatan agen dan
wiring workspace.
- `agents.files.list`, `agents.files.get`, dan `agents.files.set` mengelola
file workspace bootstrap yang diekspos untuk agen.
- `agent.identity.get` mengembalikan identitas asisten efektif untuk agen atau
file workspace bootstrap yang diekspos untuk sebuah agen.
- `agent.identity.get` mengembalikan identitas asisten yang efektif untuk agen atau
sesi.
- `agent.wait` menunggu sebuah run selesai dan mengembalikan snapshot terminal jika
- `agent.wait` menunggu hingga suatu run selesai dan mengembalikan snapshot terminal saat
tersedia.
#### Kontrol sesi
- `sessions.list` mengembalikan indeks sesi saat ini.
- `sessions.subscribe` dan `sessions.unsubscribe` mengaktifkan/menonaktifkan
langganan event perubahan sesi untuk klien WS saat ini.
- `sessions.messages.subscribe` dan `sessions.messages.unsubscribe` mengaktifkan/menonaktifkan
langganan event transkrip/pesan untuk satu sesi.
- `sessions.preview` mengembalikan pratinjau transkrip berbatas untuk key sesi tertentu.
- `sessions.subscribe` dan `sessions.unsubscribe` mengaktifkan atau menonaktifkan langganan peristiwa perubahan sesi
untuk klien WS saat ini.
- `sessions.messages.subscribe` dan `sessions.messages.unsubscribe` mengaktifkan atau menonaktifkan
langganan peristiwa transkrip/pesan untuk satu sesi.
- `sessions.preview` mengembalikan pratinjau transkrip terbatas untuk kunci
sesi tertentu.
- `sessions.resolve` me-resolve atau mengkanonisasi target sesi.
- `sessions.create` membuat entri sesi baru.
- `sessions.send` mengirim pesan ke sesi yang sudah ada.
- `sessions.steer` adalah varian interrupt-and-steer untuk sesi aktif.
- `sessions.steer` adalah varian interupsi-dan-arahkan untuk sesi aktif.
- `sessions.abort` membatalkan pekerjaan aktif untuk sebuah sesi.
- `sessions.patch` memperbarui metadata/override sesi.
- `sessions.reset`, `sessions.delete`, dan `sessions.compact` melakukan pemeliharaan sesi.
- `sessions.reset`, `sessions.delete`, dan `sessions.compact` melakukan
pemeliharaan sesi.
- `sessions.get` mengembalikan baris sesi tersimpan lengkap.
- eksekusi chat tetap menggunakan `chat.history`, `chat.send`, `chat.abort`, dan
`chat.inject`.
- `chat.history` dinormalisasi untuk tampilan klien UI: tag direktif inline dihapus dari teks
yang terlihat, payload XML pemanggilan tool teks biasa (termasuk
- `chat.history` dinormalisasi untuk tampilan bagi klien UI: tag direktif inline
dihapus dari teks yang terlihat, muatan XML tool-call teks biasa (termasuk
`<tool_call>...</tool_call>`, `<function_call>...</function_call>`,
`<tool_calls>...</tool_calls>`, `<function_calls>...</function_calls>`, dan
blok pemanggilan tool yang terpotong) serta token kontrol model ASCII/full-width yang bocor
dihapus, baris asisten token senyap murni seperti `NO_REPLY` /
`no_reply` yang persis sama dihilangkan, dan baris yang terlalu besar dapat diganti dengan placeholder.
blok tool-call yang terpotong) serta token kontrol model ASCII/full-width yang
bocor dihapus, baris asisten token-senyap murni seperti `NO_REPLY` /
`no_reply` yang persis sama dihilangkan, dan baris yang terlalu besar dapat
diganti dengan placeholder.
#### Pairing perangkat dan token perangkat
- `device.pair.list` mengembalikan perangkat yang dipairing dan menunggu persetujuan.
- `device.pair.list` mengembalikan perangkat yang di-pairing yang tertunda dan disetujui.
- `device.pair.approve`, `device.pair.reject`, dan `device.pair.remove` mengelola
rekaman pairing perangkat.
- `device.token.rotate` merotasi token perangkat yang dipairing dalam batas role
dan scope yang telah disetujui.
- `device.token.revoke` mencabut token perangkat yang dipairing.
catatan pairing perangkat.
- `device.token.rotate` merotasi token perangkat yang di-pairing dalam batas peran
dan cakupan yang disetujui.
- `device.token.revoke` mencabut token perangkat yang di-pairing.
#### Pairing node, invoke, dan pekerjaan tertunda
- `node.pair.request`, `node.pair.list`, `node.pair.approve`,
`node.pair.reject`, dan `node.pair.verify` mencakup pairing node dan
verifikasi bootstrap.
- `node.list` dan `node.describe` mengembalikan status node yang diketahui/terhubung.
- `node.rename` memperbarui label node yang dipairing.
- `node.invoke` meneruskan sebuah command ke node yang terhubung.
`node.pair.reject`, dan `node.pair.verify` mencakup pairing node dan verifikasi
bootstrap.
- `node.list` dan `node.describe` mengembalikan status node yang dikenal/terhubung.
- `node.rename` memperbarui label node yang di-pairing.
- `node.invoke` meneruskan perintah ke node yang terhubung.
- `node.invoke.result` mengembalikan hasil untuk permintaan invoke.
- `node.event` membawa event yang berasal dari node kembali ke gateway.
- `node.canvas.capability.refresh` menyegarkan token kapabilitas canvas yang dibatasi scope.
- `node.pending.pull` dan `node.pending.ack` adalah API antrean node terhubung.
- `node.pending.enqueue` dan `node.pending.drain` mengelola pekerjaan tertunda yang persisten
untuk node offline/terputus.
- `node.event` membawa peristiwa yang berasal dari node kembali ke gateway.
- `node.canvas.capability.refresh` me-refresh token kapabilitas canvas yang dibatasi cakupan.
- `node.pending.pull` dan `node.pending.ack` adalah API antrean node-terhubung.
- `node.pending.enqueue` dan `node.pending.drain` mengelola pekerjaan tertunda yang tahan lama
untuk node offline/tidak terhubung.
#### Keluarga persetujuan
- `exec.approval.request`, `exec.approval.get`, `exec.approval.list`, dan
`exec.approval.resolve` mencakup permintaan persetujuan exec sekali jalan plus
lookup/replay persetujuan yang tertunda.
- `exec.approval.waitDecision` menunggu satu persetujuan exec yang tertunda dan mengembalikan
keputusan akhir (atau `null` jika timeout).
- `exec.approvals.get` dan `exec.approvals.set` mengelola snapshot kebijakan persetujuan exec
gateway.
- `exec.approvals.node.get` dan `exec.approvals.node.set` mengelola
kebijakan persetujuan exec lokal node melalui command relay node.
`exec.approval.resolve` mencakup permintaan persetujuan exec sekali pakai plus
lookup/replay persetujuan tertunda.
- `exec.approval.waitDecision` menunggu satu persetujuan exec tertunda dan mengembalikan
keputusan final (atau `null` saat timeout).
- `exec.approvals.get` dan `exec.approvals.set` mengelola snapshot kebijakan
persetujuan exec gateway.
- `exec.approvals.node.get` dan `exec.approvals.node.set` mengelola kebijakan exec lokal-node
melalui perintah relay node.
- `plugin.approval.request`, `plugin.approval.list`,
`plugin.approval.waitDecision`, dan `plugin.approval.resolve` mencakup
alur persetujuan yang didefinisikan plugin.
#### Keluarga utama lainnya
- automation:
- `wake` menjadwalkan injeksi teks wake segera atau pada heartbeat berikutnya
- otomasi:
- `wake` menjadwalkan injeksi teks bangun segera atau pada heartbeat berikutnya
- `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove`,
`cron.run`, `cron.runs`
- skills/tools: `skills.*`, `tools.catalog`, `tools.effective`
- skills/tools: `commands.list`, `skills.*`, `tools.catalog`, `tools.effective`
### Keluarga event umum
### Keluarga peristiwa umum
- `chat`: pembaruan chat UI seperti `chat.inject` dan event chat khusus transkrip
- `chat`: pembaruan chat UI seperti `chat.inject` dan peristiwa chat khusus transkrip
lainnya.
- `session.message` dan `session.tool`: pembaruan transkrip/aliran event untuk sesi
- `session.message` dan `session.tool`: pembaruan transkrip/aliran-peristiwa untuk sesi
yang dilanggani.
- `sessions.changed`: indeks sesi atau metadata telah berubah.
- `presence`: pembaruan snapshot presence sistem.
- `tick`: event keepalive / liveness periodik.
- `sessions.changed`: indeks sesi atau metadata berubah.
- `presence`: pembaruan snapshot kehadiran sistem.
- `tick`: peristiwa keepalive / liveness berkala.
- `health`: pembaruan snapshot kesehatan gateway.
- `heartbeat`: pembaruan aliran event heartbeat.
- `cron`: event perubahan run/job cron.
- `heartbeat`: pembaruan aliran peristiwa heartbeat.
- `cron`: peristiwa perubahan run/pekerjaan cron.
- `shutdown`: notifikasi shutdown gateway.
- `node.pair.requested` / `node.pair.resolved`: siklus hidup pairing node.
- `node.invoke.request`: siaran permintaan invoke node.
- `device.pair.requested` / `device.pair.resolved`: siklus hidup perangkat yang dipairing.
- `voicewake.changed`: konfigurasi pemicu wake word berubah.
- `device.pair.requested` / `device.pair.resolved`: siklus hidup perangkat yang di-pairing.
- `voicewake.changed`: konfigurasi pemicu wake-word berubah.
- `exec.approval.requested` / `exec.approval.resolved`: siklus hidup
persetujuan exec.
- `plugin.approval.requested` / `plugin.approval.resolved`: siklus hidup persetujuan plugin.
@ -434,29 +438,40 @@ yang diimplementasikan dalam `src/gateway/server-methods/*.ts`.
### Metode helper operator
- Operator dapat memanggil `tools.catalog` (`operator.read`) untuk mengambil katalog tool runtime untuk sebuah
agen. Respons mencakup tool yang dikelompokkan dan metadata asal:
- Operator dapat memanggil `commands.list` (`operator.read`) untuk mengambil inventaris perintah runtime bagi sebuah agen.
- `agentId` bersifat opsional; hilangkan untuk membaca workspace agen default.
- `scope` mengontrol permukaan mana yang dituju oleh `name` utama:
- `text` mengembalikan token perintah teks utama tanpa awalan `/`
- `native` dan jalur default `both` mengembalikan nama native yang sadar-provider
jika tersedia
- `textAliases` membawa alias slash persis seperti `/model` dan `/m`.
- `nativeName` membawa nama perintah native yang sadar-provider jika ada.
- `provider` bersifat opsional dan hanya memengaruhi penamaan native plus
ketersediaan perintah plugin native.
- `includeArgs=false` menghilangkan metadata argumen yang diserialisasi dari respons.
- Operator dapat memanggil `tools.catalog` (`operator.read`) untuk mengambil katalog tool runtime bagi sebuah
agen. Respons mencakup tool yang dikelompokkan dan metadata provenance:
- `source`: `core` atau `plugin`
- `pluginId`: pemilik plugin ketika `source="plugin"`
- `pluginId`: pemilik plugin saat `source="plugin"`
- `optional`: apakah tool plugin bersifat opsional
- Operator dapat memanggil `tools.effective` (`operator.read`) untuk mengambil inventaris tool efektif runtime
untuk sebuah sesi.
- Operator dapat memanggil `tools.effective` (`operator.read`) untuk mengambil inventaris tool efektif-runtime
bagi sebuah sesi.
- `sessionKey` wajib diisi.
- Gateway menurunkan konteks runtime tepercaya dari sesi di sisi server alih-alih menerima
auth atau konteks pengiriman yang disuplai pemanggil.
auth atau konteks pengiriman yang disediakan pemanggil.
- Respons dibatasi pada sesi dan mencerminkan apa yang dapat digunakan percakapan aktif saat ini,
termasuk tool core, plugin, dan channel.
- Operator dapat memanggil `skills.status` (`operator.read`) untuk mengambil inventaris
skill yang terlihat untuk sebuah agen.
skill yang terlihat bagi sebuah agen.
- `agentId` bersifat opsional; hilangkan untuk membaca workspace agen default.
- Respons mencakup kelayakan, persyaratan yang belum terpenuhi, pemeriksaan konfigurasi, dan
- Respons mencakup kelayakan, persyaratan yang hilang, pemeriksaan config, dan
opsi instalasi yang telah disanitasi tanpa mengekspos nilai secret mentah.
- Operator dapat memanggil `skills.search` dan `skills.detail` (`operator.read`) untuk
metadata penemuan ClawHub.
- Operator dapat memanggil `skills.install` (`operator.admin`) dalam dua mode:
- Mode ClawHub: `{ source: "clawhub", slug, version?, force? }` menginstal
folder skill ke direktori `skills/` workspace agen default.
- Mode penginstal gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }`
- Mode installer gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }`
menjalankan aksi `metadata.openclaw.install` yang dideklarasikan pada host gateway.
- Operator dapat memanggil `skills.update` (`operator.admin`) dalam dua mode:
- Mode ClawHub memperbarui satu slug yang dilacak atau semua instalasi ClawHub yang dilacak di
@ -467,19 +482,19 @@ yang diimplementasikan dalam `src/gateway/server-methods/*.ts`.
## Persetujuan exec
- Saat permintaan exec memerlukan persetujuan, gateway menyiarkan `exec.approval.requested`.
- Klien operator menyelesaikannya dengan memanggil `exec.approval.resolve` (memerlukan scope `operator.approvals`).
- Untuk `host=node`, `exec.approval.request` harus menyertakan `systemRunPlan` (`argv`/`cwd`/`rawCommand`/metadata sesi yang kanonis). Permintaan yang tidak memiliki `systemRunPlan` akan ditolak.
- Klien operator menyelesaikannya dengan memanggil `exec.approval.resolve` (memerlukan cakupan `operator.approvals`).
- Untuk `host=node`, `exec.approval.request` harus menyertakan `systemRunPlan` (metadata `argv`/`cwd`/`rawCommand`/sesi kanonis). Permintaan yang tidak memiliki `systemRunPlan` akan ditolak.
- Setelah disetujui, panggilan `node.invoke system.run` yang diteruskan menggunakan kembali
`systemRunPlan` kanonis tersebut sebagai konteks command/cwd/sesi yang otoritatif.
`systemRunPlan` kanonis tersebut sebagai konteks perintah/cwd/sesi yang otoritatif.
- Jika pemanggil mengubah `command`, `rawCommand`, `cwd`, `agentId`, atau
`sessionKey` antara tahap prepare dan penerusan `system.run` akhir yang telah disetujui, gateway
menolak eksekusi alih-alih mempercayai payload yang telah diubah.
`sessionKey` antara prepare dan penerusan `system.run` final yang telah disetujui,
gateway menolak run tersebut alih-alih memercayai muatan yang telah diubah.
## Fallback pengiriman agen
- Permintaan `agent` dapat menyertakan `deliver=true` untuk meminta pengiriman keluar.
- `bestEffortDeliver=false` mempertahankan perilaku ketat: target pengiriman yang tidak terselesaikan atau hanya-internal mengembalikan `INVALID_REQUEST`.
- `bestEffortDeliver=true` memungkinkan fallback ke eksekusi khusus sesi ketika tidak ada rute pengiriman eksternal yang dapat di-resolve (misalnya sesi internal/webchat atau konfigurasi multi-channel yang ambigu).
- `bestEffortDeliver=false` mempertahankan perilaku ketat: target pengiriman yang tidak ter-resolve atau hanya-internal mengembalikan `INVALID_REQUEST`.
- `bestEffortDeliver=true` memungkinkan fallback ke eksekusi khusus-sesi saat tidak ada rute pengiriman eksternal yang dapat di-resolve (misalnya sesi internal/webchat atau config multi-channel yang ambigu).
## Pembuatan versi
@ -492,67 +507,67 @@ yang diimplementasikan dalam `src/gateway/server-methods/*.ts`.
## Auth
- Auth gateway dengan shared-secret menggunakan `connect.params.auth.token` atau
- Auth gateway shared-secret menggunakan `connect.params.auth.token` atau
`connect.params.auth.password`, tergantung pada mode auth yang dikonfigurasi.
- Mode yang membawa identitas seperti Tailscale Serve
(`gateway.auth.allowTailscale: true`) atau
`gateway.auth.mode: "trusted-proxy"` non-loopback memenuhi pemeriksaan auth connect dari
header permintaan alih-alih `connect.params.auth.*`.
- Ingress privat `gateway.auth.mode: "none"` sepenuhnya melewati auth connect shared-secret;
jangan ekspos mode tersebut pada ingress publik/tidak tepercaya.
- Setelah pairing, Gateway menerbitkan **token perangkat** yang dibatasi ke role + scope
koneksi. Token ini dikembalikan dalam `hello-ok.auth.deviceToken` dan harus
dipersist oleh klien untuk koneksi berikutnya.
- Klien harus mempersist `hello-ok.auth.deviceToken` utama setelah setiap
koneksi berhasil.
- Saat menyambung ulang dengan token perangkat **tersimpan** tersebut, klien juga harus menggunakan kembali
set scope yang telah disetujui dan tersimpan untuk token tersebut. Ini mempertahankan akses
baca/probe/status yang telah diberikan dan menghindari penyempitan diam-diam saat reconnect menjadi
scope implisit admin-only yang lebih sempit.
- Precedensi auth connect normal adalah token/password shared eksplisit terlebih dahulu, lalu
`deviceToken` eksplisit, lalu token per-perangkat yang tersimpan, lalu token bootstrap.
- Entri tambahan `hello-ok.auth.deviceTokens` adalah token handoff bootstrap.
Persist token tersebut hanya jika connect menggunakan auth bootstrap pada transport tepercaya
seperti `wss://` atau pairing loopback/lokal.
- Jika klien memberikan `deviceToken` **eksplisit** atau `scopes` eksplisit, set scope
yang diminta pemanggil tersebut tetap menjadi otoritas; scope yang di-cache hanya
digunakan kembali ketika klien menggunakan kembali token per-perangkat yang tersimpan.
jangan mengekspos mode tersebut pada ingress publik/tidak tepercaya.
- Setelah pairing, Gateway menerbitkan **token perangkat** yang dibatasi pada
peran + cakupan koneksi. Token ini dikembalikan dalam `hello-ok.auth.deviceToken` dan
harus disimpan oleh klien untuk connect berikutnya.
- Klien harus menyimpan `hello-ok.auth.deviceToken` utama setelah setiap
connect yang berhasil.
- Menghubungkan ulang dengan token perangkat **tersimpan** tersebut juga harus menggunakan kembali set cakupan
yang telah disetujui dan tersimpan untuk token itu. Ini mempertahankan akses baca/probe/status
yang sudah diberikan dan menghindari koneksi ulang diam-diam menyusut ke
cakupan implisit khusus-admin yang lebih sempit.
- Prioritas auth connect normal adalah token/password shared eksplisit terlebih dahulu, lalu
`deviceToken` eksplisit, lalu token per-perangkat tersimpan, lalu token bootstrap.
- Entri `hello-ok.auth.deviceTokens` tambahan adalah token handoff bootstrap.
Simpan token ini hanya saat connect menggunakan auth bootstrap pada transport tepercaya
seperti `wss://` atau loopback/pairing lokal.
- Jika klien memberikan `deviceToken` **eksplisit** atau `scopes` eksplisit, set cakupan
yang diminta pemanggil tersebut tetap otoritatif; cakupan yang di-cache hanya
digunakan kembali saat klien menggunakan kembali token per-perangkat tersimpan.
- Token perangkat dapat dirotasi/dicabut melalui `device.token.rotate` dan
`device.token.revoke` (memerlukan scope `operator.pairing`).
- Penerbitan/rotasi token tetap dibatasi ke set role yang disetujui dan dicatat dalam
`device.token.revoke` (memerlukan cakupan `operator.pairing`).
- Penerbitan/rotasi token tetap dibatasi pada set peran yang disetujui dan dicatat dalam
entri pairing perangkat tersebut; merotasi token tidak dapat memperluas perangkat ke
role yang tidak pernah diberikan oleh persetujuan pairing.
- Untuk sesi token perangkat yang dipairing, pengelolaan perangkat dibatasi pada dirinya sendiri kecuali
pemanggil juga memiliki `operator.admin`: pemanggil non-admin hanya dapat
menghapus/mencabut/merotasi entri perangkat **mereka sendiri**.
- `device.token.rotate` juga memeriksa set scope operator yang diminta terhadap
scope sesi saat ini milik pemanggil. Pemanggil non-admin tidak dapat merotasi token ke
set scope operator yang lebih luas daripada yang sudah mereka miliki.
- Kegagalan auth menyertakan `error.details.code` beserta petunjuk pemulihan:
peran yang tidak pernah diberikan oleh persetujuan pairing.
- Untuk sesi token perangkat yang di-pairing, pengelolaan perangkat dibatasi pada diri sendiri kecuali
pemanggil juga memiliki `operator.admin`: pemanggil non-admin hanya dapat menghapus/mencabut/merotasi
entri perangkat **milik mereka sendiri**.
- `device.token.rotate` juga memeriksa set cakupan operator yang diminta terhadap
cakupan sesi pemanggil saat ini. Pemanggil non-admin tidak dapat merotasi token ke
set cakupan operator yang lebih luas daripada yang sudah mereka miliki.
- Kegagalan auth mencakup `error.details.code` plus petunjuk pemulihan:
- `error.details.canRetryWithDeviceToken` (boolean)
- `error.details.recommendedNextStep` (`retry_with_device_token`, `update_auth_configuration`, `update_auth_credentials`, `wait_then_retry`, `review_auth_configuration`)
- Perilaku klien untuk `AUTH_TOKEN_MISMATCH`:
- Klien tepercaya dapat mencoba satu retry terbatas dengan token per-perangkat yang di-cache.
- Jika retry itu gagal, klien harus menghentikan loop reconnect otomatis dan menampilkan panduan tindakan operator.
- Klien tepercaya dapat mencoba satu kali retry terbatas dengan token per-perangkat yang di-cache.
- Jika retry tersebut gagal, klien harus menghentikan loop reconnect otomatis dan menampilkan panduan tindakan operator.
## Identitas perangkat + pairing
- Node harus menyertakan identitas perangkat yang stabil (`device.id`) yang diturunkan dari
- Node harus menyertakan identitas perangkat stabil (`device.id`) yang diturunkan dari
fingerprint keypair.
- Gateway menerbitkan token per perangkat + role.
- Persetujuan pairing diperlukan untuk ID perangkat baru kecuali persetujuan otomatis lokal
- Gateway menerbitkan token per perangkat + peran.
- Persetujuan pairing diperlukan untuk ID perangkat baru kecuali auto-approval lokal
diaktifkan.
- Persetujuan otomatis pairing berpusat pada koneksi local loopback langsung.
- Auto-approval pairing berpusat pada koneksi local loopback langsung.
- OpenClaw juga memiliki jalur self-connect backend/container-local yang sempit untuk
alur helper shared-secret tepercaya.
- Koneksi tailnet atau LAN pada host yang sama tetap diperlakukan sebagai koneksi jarak jauh untuk pairing dan
- Koneksi tailnet host yang sama atau LAN tetap diperlakukan sebagai koneksi jarak jauh untuk pairing dan
memerlukan persetujuan.
- Semua klien WS harus menyertakan identitas `device` selama `connect` (operator + node).
Control UI hanya dapat menghilangkannya dalam mode berikut:
Control UI dapat menghilangkannya hanya dalam mode berikut:
- `gateway.controlUi.allowInsecureAuth=true` untuk kompatibilitas HTTP tidak aman khusus localhost.
- auth operator Control UI `gateway.auth.mode: "trusted-proxy"` yang berhasil.
- `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (break-glass, penurunan keamanan yang berat).
- Semua koneksi harus menandatangani nonce `connect.challenge` yang diberikan server.
- `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (break-glass, penurunan keamanan berat).
- Semua koneksi harus menandatangani nonce `connect.challenge` yang disediakan server.
### Diagnostik migrasi auth perangkat
@ -561,33 +576,33 @@ kode detail `DEVICE_AUTH_*` di bawah `error.details.code` dengan `error.details.
Kegagalan migrasi umum:
| Pesan | details.code | details.reason | Arti |
| ------------------------- | -------------------------------- | ------------------------ | -------------------------------------------------- |
| `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | Klien tidak menyertakan `device.nonce` (atau mengirim kosong). |
| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | Klien menandatangani dengan nonce yang kedaluwarsa/salah. |
| `device signature invalid`| `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | Payload tanda tangan tidak cocok dengan payload v2. |
| `device signature expired`| `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | Stempel waktu yang ditandatangani berada di luar skew yang diizinkan. |
| `device identity mismatch`| `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` tidak cocok dengan fingerprint kunci publik. |
| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | Format/kanonisasi kunci publik gagal. |
| Pesan | details.code | details.reason | Arti |
| --------------------------- | -------------------------------- | ------------------------ | -------------------------------------------------- |
| `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | Klien tidak menyertakan `device.nonce` (atau mengirim kosong). |
| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | Klien menandatangani dengan nonce yang basi/salah. |
| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | Muatan signature tidak cocok dengan muatan v2. |
| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | Tanda waktu yang ditandatangani berada di luar skew yang diizinkan. |
| `device identity mismatch` | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` tidak cocok dengan fingerprint public key. |
| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | Format/kanonisasi public key gagal. |
Target migrasi:
- Selalu tunggu `connect.challenge`.
- Tanda tangani payload v2 yang menyertakan nonce server.
- Tanda tangani muatan v2 yang menyertakan nonce server.
- Kirim nonce yang sama dalam `connect.params.device.nonce`.
- Payload tanda tangan yang disukai adalah `v3`, yang mengikat `platform` dan `deviceFamily`
- Muatan signature yang disarankan adalah `v3`, yang mengikat `platform` dan `deviceFamily`
selain field device/client/role/scopes/token/nonce.
- Tanda tangan `v2` lama tetap diterima untuk kompatibilitas, tetapi pinning metadata
paired-device tetap mengendalikan kebijakan command saat reconnect.
- Signature `v2` lama tetap diterima untuk kompatibilitas, tetapi pinning metadata
paired-device tetap mengontrol kebijakan perintah saat reconnect.
## TLS + pinning
- TLS didukung untuk koneksi WS.
- Klien dapat secara opsional mem-pin fingerprint sertifikat gateway (lihat konfigurasi `gateway.tls`
plus `gateway.remote.tlsFingerprint` atau CLI `--tls-fingerprint`).
- Klien dapat secara opsional melakukan pinning fingerprint sertifikat gateway (lihat config `gateway.tls`
serta `gateway.remote.tlsFingerprint` atau CLI `--tls-fingerprint`).
## Cakupan
Protokol ini mengekspos **API gateway lengkap** (status, channels, models, chat,
agent, sessions, nodes, approvals, dll.). Permukaan yang tepat didefinisikan oleh
skema TypeBox dalam `src/gateway/protocol/schema.ts`.
Protokol ini mengekspos **API gateway lengkap** (status, channel, model, chat,
agen, sesi, node, persetujuan, dll.). Permukaan persisnya didefinisikan oleh
skema TypeBox di `src/gateway/protocol/schema.ts`.

View File

@ -2,38 +2,40 @@
read_when:
- Menjalankan pengujian secara lokal atau di CI
- Menambahkan regresi untuk bug model/provider
- Men-debug perilaku gateway + agent
summary: 'Kit pengujian: suite unit/e2e/live, runner Docker, dan cakupan tiap pengujian'
- Men-debug perilaku gateway + agen
summary: 'Kit pengujian: suite unit/e2e/live, runner Docker, dan cakupan masing-masing pengujian'
title: Pengujian
x-i18n:
generated_at: "2026-04-09T01:30:28Z"
generated_at: "2026-04-10T09:13:17Z"
model: gpt-5.4
provider: openai
source_hash: 01117f41d8b171a4f1da11ed78486ee700e70ae70af54eb6060c57baf64ab21b
source_hash: 21b78e59a5189f4e8e6e1b490d350f4735c0395da31d21fc5d10b825313026b4
source_path: help/testing.md
workflow: 15
---
# Pengujian
OpenClaw memiliki tiga suite Vitest (unit/integrasi, e2e, live) dan sekumpulan kecil runner Docker.
OpenClaw memiliki tiga suite Vitest (unit/integrasi, e2e, live) dan sejumlah kecil runner Docker.
Dokumen ini adalah panduan “cara kami melakukan pengujian”:
Dokumen ini adalah panduan “bagaimana kami menguji”:
- Apa yang dicakup oleh setiap suite (dan apa yang sengaja _tidak_ dicakup)
- Apa yang dicakup setiap suite (dan apa yang sengaja _tidak_ dicakup)
- Perintah mana yang dijalankan untuk alur kerja umum (lokal, sebelum push, debugging)
- Cara live test menemukan kredensial dan memilih model/provider
- Bagaimana pengujian live menemukan kredensial dan memilih model/provider
- Cara menambahkan regresi untuk masalah model/provider di dunia nyata
## Mulai cepat
Hampir setiap hari:
Di sebagian besar hari:
- Gate penuh (diharapkan sebelum push): `pnpm build && pnpm check && pnpm test`
- Eksekusi full-suite lokal yang lebih cepat pada mesin yang lega: `pnpm test:max`
- Menjalankan suite penuh lokal yang lebih cepat di mesin yang lega: `pnpm test:max`
- Loop watch Vitest langsung: `pnpm test:watch`
- Penargetan file langsung kini juga merutekan path extension/channel: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts`
- Penargetan file langsung sekarang juga merutekan path extension/channel: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts`
- Utamakan menjalankan pengujian yang ditargetkan terlebih dahulu saat Anda sedang mengiterasi satu kegagalan.
- Situs QA berbasis Docker: `pnpm qa:lab:up`
- Lane QA berbasis VM Linux: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline`
Saat Anda menyentuh pengujian atau ingin keyakinan tambahan:
@ -42,85 +44,105 @@ Saat Anda menyentuh pengujian atau ingin keyakinan tambahan:
Saat men-debug provider/model nyata (memerlukan kredensial nyata):
- Suite live (probe model + tool/image gateway): `pnpm test:live`
- Suite live (probe model + gateway tool/image): `pnpm test:live`
- Targetkan satu file live secara senyap: `pnpm test:live -- src/agents/models.profiles.live.test.ts`
Tip: ketika Anda hanya memerlukan satu kasus gagal, sebaiknya persempit live test melalui env var allowlist yang dijelaskan di bawah.
Tip: jika Anda hanya membutuhkan satu kasus yang gagal, persempit pengujian live melalui env var allowlist yang dijelaskan di bawah.
## Runner khusus QA
Perintah-perintah ini berada di samping suite pengujian utama saat Anda membutuhkan realisme QA-lab:
- `pnpm openclaw qa suite`
- Menjalankan skenario QA berbasis repo langsung di host.
- `pnpm openclaw qa suite --runner multipass`
- Menjalankan suite QA yang sama di dalam VM Linux Multipass sekali pakai.
- Mempertahankan perilaku pemilihan skenario yang sama seperti `qa suite` di host.
- Menggunakan ulang flag pemilihan provider/model yang sama seperti `qa suite`.
- Untuk run live, meneruskan input autentikasi QA yang didukung dan praktis untuk guest:
kunci provider berbasis env, path konfigurasi provider live QA, dan `CODEX_HOME`
bila ada.
- Direktori output harus tetap berada di bawah root repo agar guest dapat menulis kembali melalui
workspace yang di-mount.
- Menulis laporan + ringkasan QA normal serta log Multipass di bawah
`.artifacts/qa-e2e/...`.
- `pnpm qa:lab:up`
- Memulai situs QA berbasis Docker untuk pekerjaan QA bergaya operator.
## Suite pengujian (apa yang berjalan di mana)
Anggap suite-suite ini sebagai “realisme yang semakin meningkat” (dan flakiness/biaya yang juga meningkat):
Bayangkan suite-suite ini sebagai “realisme yang meningkat” (dan flakiness/biaya yang meningkat):
### Unit / integrasi (default)
- Perintah: `pnpm test`
- Konfigurasi: sepuluh eksekusi shard berurutan (`vitest.full-*.config.ts`) di atas project Vitest terlingkup yang ada
- Config: sepuluh run shard berurutan (`vitest.full-*.config.ts`) di atas project Vitest terlingkup yang sudah ada
- File: inventaris core/unit di bawah `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts`, dan pengujian node `ui` yang di-whitelist yang dicakup oleh `vitest.unit.config.ts`
- Cakupan:
- Pengujian unit murni
- Pengujian integrasi in-process (auth gateway, routing, tooling, parsing, config)
- Regresi deterministik untuk bug yang sudah diketahui
- Pengujian integrasi in-process (autentikasi gateway, routing, tooling, parsing, config)
- Regresi deterministik untuk bug yang diketahui
- Ekspektasi:
- Berjalan di CI
- Tidak memerlukan key nyata
- Tidak memerlukan kunci nyata
- Harus cepat dan stabil
- Catatan project:
- `pnpm test` tanpa target kini menjalankan sebelas konfigurasi shard yang lebih kecil (`core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) alih-alih satu proses root-project native yang sangat besar. Ini mengurangi puncak RSS pada mesin yang sibuk dan mencegah pekerjaan auto-reply/extension mengganggu suite lain yang tidak terkait.
- `pnpm test --watch` tetap menggunakan graf project `vitest.config.ts` root native, karena loop watch multi-shard tidak praktis.
- `pnpm test`, `pnpm test:watch`, dan `pnpm test:perf:imports` merutekan target file/direktori eksplisit melalui lane terlingkup terlebih dahulu, sehingga `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` tidak perlu membayar biaya startup penuh root project.
- `pnpm test:changed` memperluas path git yang berubah ke lane terlingkup yang sama saat diff hanya menyentuh file source/test yang dapat dirutekan; edit config/setup tetap fallback ke rerun root-project yang luas.
- `pnpm test` tanpa target sekarang menjalankan sebelas config shard yang lebih kecil (`core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) alih-alih satu proses root-project native yang sangat besar. Ini mengurangi puncak RSS pada mesin yang sibuk dan mencegah pekerjaan auto-reply/extension membuat suite lain kelaparan sumber daya.
- `pnpm test --watch` tetap menggunakan graf project root native `vitest.config.ts`, karena loop watch multi-shard tidak praktis.
- `pnpm test`, `pnpm test:watch`, dan `pnpm test:perf:imports` merutekan target file/direktori eksplisit melalui lane yang terlingkup terlebih dahulu, sehingga `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` tidak perlu membayar biaya startup penuh root project.
- `pnpm test:changed` memperluas path git yang berubah ke lane terlingkup yang sama ketika diff hanya menyentuh file source/pengujian yang dapat dirutekan; edit config/setup tetap fallback ke rerun root-project yang luas.
- Pengujian `plugin-sdk` dan `commands` tertentu juga dirutekan melalui lane ringan khusus yang melewati `test/setup-openclaw-runtime.ts`; file stateful/runtime-heavy tetap berada di lane yang ada.
- File source helper `plugin-sdk` dan `commands` tertentu juga memetakan eksekusi mode-changed ke pengujian saudara eksplisit di lane ringan tersebut, sehingga edit helper tidak memicu rerun suite berat penuh untuk direktori itu.
- `auto-reply` sekarang memiliki tiga bucket khusus: helper core tingkat atas, pengujian integrasi `reply.*` tingkat atas, dan subtree `src/auto-reply/reply/**`. Ini menjaga pekerjaan harness reply terberat tetap terpisah dari pengujian status/chunk/token yang murah.
- File source helper `plugin-sdk` dan `commands` tertentu juga memetakan run mode changed ke pengujian sibling eksplisit di lane ringan itu, sehingga edit helper menghindari rerun seluruh suite berat untuk direktori tersebut.
- `auto-reply` kini memiliki tiga bucket khusus: helper core level atas, pengujian integrasi `reply.*` level atas, dan subtree `src/auto-reply/reply/**`. Ini menjaga pekerjaan harness reply terberat tetap terpisah dari pengujian status/chunk/token yang murah.
- Catatan embedded runner:
- Saat Anda mengubah input penemuan message-tool atau konteks runtime compaction,
pertahankan kedua tingkat cakupan.
- Tambahkan regresi helper yang terfokus untuk batas routing/normalisasi murni.
- Jaga juga suite integrasi embedded runner tetap sehat:
- Juga pertahankan suite integrasi embedded runner tetap sehat:
`src/agents/pi-embedded-runner/compact.hooks.test.ts`,
`src/agents/pi-embedded-runner/run.overflow-compaction.test.ts`, dan
`src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`.
- Suite-suite tersebut memverifikasi bahwa id terlingkup dan perilaku compaction tetap mengalir
- Suite-suite tersebut memverifikasi bahwa id yang dicakup dan perilaku compaction tetap mengalir
melalui path `run.ts` / `compact.ts` yang nyata; pengujian helper saja bukan
pengganti yang memadai untuk path integrasi tersebut.
- Catatan pool:
- Konfigurasi dasar Vitest sekarang menggunakan `threads` secara default.
- Konfigurasi Vitest bersama juga menetapkan `isolate: false` dan menggunakan runner non-isolated di seluruh konfigurasi root project, e2e, dan live.
- Lane UI root mempertahankan setup dan optimizer `jsdom`, tetapi sekarang juga berjalan pada runner non-isolated bersama.
- Setiap shard `pnpm test` mewarisi default `threads` + `isolate: false` yang sama dari konfigurasi Vitest bersama.
- Launcher bersama `scripts/run-vitest.mjs` sekarang juga menambahkan `--no-maglev` untuk proses Node anak Vitest secara default guna mengurangi churn kompilasi V8 selama eksekusi lokal besar. Tetapkan `OPENCLAW_VITEST_ENABLE_MAGLEV=1` jika Anda perlu membandingkan dengan perilaku V8 bawaan.
- Config dasar Vitest sekarang menggunakan `threads` secara default.
- Config Vitest bersama juga menetapkan `isolate: false` dan menggunakan runner non-isolated di seluruh root project, config e2e, dan live.
- Lane UI root mempertahankan setup dan optimizer `jsdom`, tetapi sekarang juga berjalan di runner non-isolated bersama.
- Setiap shard `pnpm test` mewarisi default `threads` + `isolate: false` yang sama dari config Vitest bersama.
- Launcher bersama `scripts/run-vitest.mjs` sekarang juga menambahkan `--no-maglev` untuk proses child Node Vitest secara default guna mengurangi churn kompilasi V8 selama run lokal besar. Tetapkan `OPENCLAW_VITEST_ENABLE_MAGLEV=1` jika Anda perlu membandingkan dengan perilaku V8 bawaan.
- Catatan iterasi lokal cepat:
- `pnpm test:changed` merutekan melalui lane terlingkup saat path yang berubah dipetakan dengan bersih ke suite yang lebih kecil.
- `pnpm test:changed` merutekan melalui lane terlingkup ketika path yang berubah terpetakan dengan bersih ke suite yang lebih kecil.
- `pnpm test:max` dan `pnpm test:changed:max` mempertahankan perilaku routing yang sama, hanya dengan batas worker yang lebih tinggi.
- Auto-scaling worker lokal kini sengaja lebih konservatif dan juga mundur saat load average host sudah tinggi, sehingga beberapa eksekusi Vitest bersamaan menimbulkan dampak yang lebih kecil secara default.
- Konfigurasi dasar Vitest menandai file projects/config sebagai `forceRerunTriggers` agar rerun mode-changed tetap benar saat wiring pengujian berubah.
- Konfigurasi mempertahankan `OPENCLAW_VITEST_FS_MODULE_CACHE` tetap aktif pada host yang didukung; tetapkan `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path` jika Anda ingin satu lokasi cache eksplisit untuk profiling langsung.
- Auto-scaling worker lokal kini memang sengaja lebih konservatif dan juga mengurangi skala ketika load average host sudah tinggi, sehingga beberapa run Vitest bersamaan secara default menimbulkan dampak yang lebih kecil.
- Config dasar Vitest menandai file project/config sebagai `forceRerunTriggers` agar rerun mode changed tetap benar saat wiring pengujian berubah.
- Config mempertahankan `OPENCLAW_VITEST_FS_MODULE_CACHE` tetap aktif pada host yang didukung; tetapkan `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path` jika Anda ingin satu lokasi cache eksplisit untuk profiling langsung.
- Catatan debug performa:
- `pnpm test:perf:imports` mengaktifkan pelaporan durasi impor Vitest beserta keluaran rincian impor.
- `pnpm test:perf:imports` mengaktifkan pelaporan durasi import Vitest beserta output rincian import.
- `pnpm test:perf:imports:changed` membatasi tampilan profiling yang sama ke file yang berubah sejak `origin/main`.
- `pnpm test:perf:changed:bench -- --ref <git-ref>` membandingkan `test:changed` yang dirutekan dengan path root-project native untuk diff yang telah di-commit tersebut dan mencetak wall time beserta max RSS macOS.
- `pnpm test:perf:changed:bench -- --worktree` melakukan benchmark pada tree kotor saat ini dengan merutekan daftar file yang berubah melalui `scripts/test-projects.mjs` dan konfigurasi Vitest root.
- `pnpm test:perf:changed:bench -- --ref <git-ref>` membandingkan `test:changed` yang dirutekan dengan path root-project native untuk diff yang di-commit itu dan mencetak wall time plus max RSS macOS.
- `pnpm test:perf:changed:bench -- --worktree` melakukan benchmark pada tree kotor saat ini dengan merutekan daftar file yang berubah melalui `scripts/test-projects.mjs` dan config root Vitest.
- `pnpm test:perf:profile:main` menulis profil CPU main-thread untuk overhead startup dan transform Vitest/Vite.
- `pnpm test:perf:profile:runner` menulis profil CPU+heap runner untuk suite unit dengan paralelisme file dinonaktifkan.
### E2E (smoke gateway)
- Perintah: `pnpm test:e2e`
- Konfigurasi: `vitest.e2e.config.ts`
- Config: `vitest.e2e.config.ts`
- File: `src/**/*.e2e.test.ts`, `test/**/*.e2e.test.ts`
- Default runtime:
- Menggunakan Vitest `threads` dengan `isolate: false`, konsisten dengan bagian repo lainnya.
- Menggunakan Vitest `threads` dengan `isolate: false`, selaras dengan bagian repo lainnya.
- Menggunakan worker adaptif (CI: hingga 2, lokal: 1 secara default).
- Berjalan dalam mode senyap secara default untuk mengurangi overhead I/O konsol.
- Override yang berguna:
- `OPENCLAW_E2E_WORKERS=<n>` untuk memaksa jumlah worker (dibatasi hingga 16).
- `OPENCLAW_E2E_VERBOSE=1` untuk mengaktifkan kembali keluaran konsol verbose.
- `OPENCLAW_E2E_WORKERS=<n>` untuk memaksakan jumlah worker (dibatasi hingga 16).
- `OPENCLAW_E2E_VERBOSE=1` untuk mengaktifkan kembali output konsol verbose.
- Cakupan:
- Perilaku end-to-end gateway multi-instance
- Surface WebSocket/HTTP, pairing node, dan jaringan yang lebih berat
- Permukaan WebSocket/HTTP, pairing node, dan jaringan yang lebih berat
- Ekspektasi:
- Berjalan di CI (saat diaktifkan dalam pipeline)
- Tidak memerlukan key nyata
- Tidak memerlukan kunci nyata
- Lebih banyak bagian bergerak dibanding pengujian unit (bisa lebih lambat)
### E2E: smoke backend OpenShell
@ -128,39 +150,39 @@ Anggap suite-suite ini sebagai “realisme yang semakin meningkat” (dan flakin
- Perintah: `pnpm test:e2e:openshell`
- File: `test/openshell-sandbox.e2e.test.ts`
- Cakupan:
- Memulai gateway OpenShell terisolasi pada host melalui Docker
- Memulai gateway OpenShell terisolasi di host melalui Docker
- Membuat sandbox dari Dockerfile lokal sementara
- Menjalankan backend OpenShell OpenClaw melalui `sandbox ssh-config` + eksekusi SSH yang nyata
- Memverifikasi perilaku filesystem remote-canonical melalui bridge fs sandbox
- Menjalankan backend OpenShell milik OpenClaw melalui `sandbox ssh-config` nyata + eksekusi SSH
- Memverifikasi perilaku filesystem kanonis-remote melalui bridge fs sandbox
- Ekspektasi:
- Hanya opt-in; bukan bagian dari eksekusi default `pnpm test:e2e`
- Memerlukan CLI `openshell` lokal plus daemon Docker yang berfungsi
- Menggunakan `HOME` / `XDG_CONFIG_HOME` yang terisolasi, lalu menghancurkan gateway dan sandbox pengujian
- Hanya opt-in; bukan bagian dari run default `pnpm test:e2e`
- Memerlukan CLI `openshell` lokal serta daemon Docker yang berfungsi
- Menggunakan `HOME` / `XDG_CONFIG_HOME` terisolasi, lalu menghancurkan gateway dan sandbox pengujian
- Override yang berguna:
- `OPENCLAW_E2E_OPENSHELL=1` untuk mengaktifkan pengujian saat menjalankan suite e2e yang lebih luas secara manual
- `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` untuk menunjuk ke biner CLI non-default atau skrip wrapper
- `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` untuk mengarah ke binary CLI non-default atau wrapper script
### Live (provider nyata + model nyata)
- Perintah: `pnpm test:live`
- Konfigurasi: `vitest.live.config.ts`
- Config: `vitest.live.config.ts`
- File: `src/**/*.live.test.ts`
- Default: **diaktifkan** oleh `pnpm test:live` (menetapkan `OPENCLAW_LIVE_TEST=1`)
- Default: **aktif** oleh `pnpm test:live` (menetapkan `OPENCLAW_LIVE_TEST=1`)
- Cakupan:
- “Apakah provider/model ini benar-benar bekerja _hari ini_ dengan kredensial nyata?”
- Menangkap perubahan format provider, keanehan tool-calling, masalah auth, dan perilaku rate limit
- “Apakah provider/model ini benar-benar berfungsi _hari ini_ dengan kredensial nyata?”
- Menangkap perubahan format provider, keanehan tool-calling, masalah autentikasi, dan perilaku rate limit
- Ekspektasi:
- Memang tidak stabil untuk CI (jaringan nyata, kebijakan provider nyata, kuota, outage)
- Menghabiskan biaya / menggunakan rate limit
- Sebaiknya menjalankan subset yang dipersempit, bukan “semuanya”
- Live run melakukan source `~/.profile` untuk mengambil API key yang belum ada.
- Secara default, live run tetap mengisolasi `HOME` dan menyalin materi config/auth ke home pengujian sementara agar fixture unit tidak dapat mengubah `~/.openclaw` asli Anda.
- Tetapkan `OPENCLAW_LIVE_USE_REAL_HOME=1` hanya saat Anda memang ingin live test menggunakan direktori home asli Anda.
- `pnpm test:live` kini default ke mode yang lebih senyap: tetap mempertahankan keluaran progres `[live] ...`, tetapi menekan notifikasi `~/.profile` tambahan dan membisukan log bootstrap gateway/chatter Bonjour. Tetapkan `OPENCLAW_LIVE_TEST_QUIET=0` jika Anda ingin log startup penuh kembali.
- Rotasi API key (spesifik provider): tetapkan `*_API_KEYS` dengan format koma/titik koma atau `*_API_KEY_1`, `*_API_KEY_2` (misalnya `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) atau override per-live melalui `OPENCLAW_LIVE_*_KEY`; pengujian akan mencoba ulang saat mendapat respons rate limit.
- Keluaran progres/heartbeat:
- Suite live sekarang mengeluarkan baris progres ke stderr sehingga pemanggilan provider yang lama tetap tampak aktif meskipun capture konsol Vitest senyap.
- `vitest.live.config.ts` menonaktifkan intersepsi konsol Vitest sehingga baris progres provider/gateway mengalir segera selama live run.
- Secara desain tidak stabil untuk CI (jaringan nyata, kebijakan provider nyata, kuota, gangguan)
- Berbiaya / memakai rate limit
- Lebih baik menjalankan subset yang dipersempit daripada “semuanya”
- Run live memuat `~/.profile` untuk mengambil API key yang belum ada.
- Secara default, run live tetap mengisolasi `HOME` dan menyalin materi config/auth ke home pengujian sementara agar fixture unit tidak dapat mengubah `~/.openclaw` Anda yang nyata.
- Tetapkan `OPENCLAW_LIVE_USE_REAL_HOME=1` hanya ketika Anda memang sengaja memerlukan pengujian live menggunakan direktori home nyata Anda.
- `pnpm test:live` kini default ke mode yang lebih senyap: tetap mempertahankan output progres `[live] ...`, tetapi menekan notifikasi `~/.profile` tambahan dan membisukan log bootstrap gateway/chatter Bonjour. Tetapkan `OPENCLAW_LIVE_TEST_QUIET=0` jika Anda ingin log startup lengkap kembali.
- Rotasi API key (khusus provider): tetapkan `*_API_KEYS` dengan format koma/titik koma atau `*_API_KEY_1`, `*_API_KEY_2` (misalnya `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) atau override per-live via `OPENCLAW_LIVE_*_KEY`; pengujian akan mencoba ulang pada respons rate limit.
- Output progres/heartbeat:
- Suite live kini mengirim baris progres ke stderr sehingga panggilan provider yang panjang terlihat aktif bahkan saat penangkapan konsol Vitest dalam mode senyap.
- `vitest.live.config.ts` menonaktifkan intersepsi konsol Vitest agar baris progres provider/gateway mengalir segera selama run live.
- Atur heartbeat direct-model dengan `OPENCLAW_LIVE_HEARTBEAT_MS`.
- Atur heartbeat gateway/probe dengan `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`.
@ -170,18 +192,18 @@ Gunakan tabel keputusan ini:
- Mengedit logika/pengujian: jalankan `pnpm test` (dan `pnpm test:coverage` jika Anda mengubah banyak hal)
- Menyentuh jaringan gateway / protokol WS / pairing: tambahkan `pnpm test:e2e`
- Men-debug “bot saya down” / kegagalan spesifik provider / tool calling: jalankan `pnpm test:live` yang dipersempit
- Men-debug “bot saya down” / kegagalan khusus provider / tool calling: jalankan `pnpm test:live` yang dipersempit
## Live: sweep kapabilitas node Android
## Live: sapuan kapabilitas node Android
- Pengujian: `src/gateway/android-node.capabilities.live.test.ts`
- Skrip: `pnpm android:test:integration`
- Tujuan: memanggil **setiap perintah yang saat ini diiklankan** oleh node Android yang terhubung dan memverifikasi perilaku kontrak perintah.
- Cakupan:
- Setup manual dengan prasyarat (suite ini tidak memasang/menjalankan/mem-pair aplikasi).
- Setup manual/prasyarat (suite ini tidak menginstal/menjalankan/memasangkan aplikasi).
- Validasi gateway `node.invoke` per perintah untuk node Android yang dipilih.
- Pra-setup yang diperlukan:
- Aplikasi Android sudah terhubung + ter-pair ke gateway.
- Aplikasi Android sudah terhubung + dipasangkan ke gateway.
- Aplikasi tetap berada di foreground.
- Izin/persetujuan capture diberikan untuk kapabilitas yang Anda harapkan lolos.
- Override target opsional:
@ -189,99 +211,99 @@ Gunakan tabel keputusan ini:
- `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`.
- Detail setup Android lengkap: [Android App](/id/platforms/android)
## Live: smoke model (key profil)
## Live: smoke model (kunci profil)
Live test dibagi menjadi dua lapisan agar kita dapat mengisolasi kegagalan:
Pengujian live dibagi menjadi dua lapisan agar kami dapat mengisolasi kegagalan:
- “Direct model” memberi tahu kita apakah provider/model dapat menjawab sama sekali dengan key yang diberikan.
- “Gateway smoke” memberi tahu kita apakah seluruh pipeline gateway+agent bekerja untuk model itu (session, history, tools, kebijakan sandbox, dan sebagainya).
- “Model langsung” memberi tahu kita apakah provider/model dapat merespons sama sekali dengan kunci yang diberikan.
- “Smoke gateway” memberi tahu kita apakah pipeline gateway+agen penuh bekerja untuk model tersebut (sesi, riwayat, tools, kebijakan sandbox, dll.).
### Lapisan 1: Penyelesaian direct model (tanpa gateway)
### Lapisan 1: Penyelesaian model langsung (tanpa gateway)
- Pengujian: `src/agents/models.profiles.live.test.ts`
- Tujuan:
- Mengenumerasi model yang ditemukan
- Menggunakan `getApiKeyForModel` untuk memilih model yang Anda miliki kredensialnya
- Menjalankan penyelesaian kecil per model (dan regresi terarah bila perlu)
- Menjalankan penyelesaian kecil per model (dan regresi tertarget bila diperlukan)
- Cara mengaktifkan:
- `pnpm test:live` (atau `OPENCLAW_LIVE_TEST=1` jika memanggil Vitest secara langsung)
- Tetapkan `OPENCLAW_LIVE_MODELS=modern` (atau `all`, alias untuk modern) agar suite ini benar-benar berjalan; jika tidak, suite ini akan di-skip agar `pnpm test:live` tetap fokus pada gateway smoke
- `pnpm test:live` (atau `OPENCLAW_LIVE_TEST=1` jika menjalankan Vitest secara langsung)
- Tetapkan `OPENCLAW_LIVE_MODELS=modern` (atau `all`, alias untuk modern) agar suite ini benar-benar berjalan; jika tidak, suite ini dilewati agar `pnpm test:live` tetap berfokus pada smoke gateway
- Cara memilih model:
- `OPENCLAW_LIVE_MODELS=modern` untuk menjalankan allowlist modern (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
- `OPENCLAW_LIVE_MODELS=all` adalah alias untuk allowlist modern
- atau `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."` (allowlist dipisahkan koma)
- Sweep modern/all default ke batas kurasi dengan sinyal tinggi; tetapkan `OPENCLAW_LIVE_MAX_MODELS=0` untuk sweep modern lengkap atau angka positif untuk batas yang lebih kecil.
- Sapuan modern/all secara default memakai batas kurasi dengan sinyal tinggi; tetapkan `OPENCLAW_LIVE_MAX_MODELS=0` untuk sapuan modern yang lengkap atau angka positif untuk batas yang lebih kecil.
- Cara memilih provider:
- `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"` (allowlist dipisahkan koma)
- Dari mana key berasal:
- Default: profile store dan fallback env
- Tetapkan `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk memaksa hanya **profile store**
- Dari mana kunci berasal:
- Secara default: penyimpanan profil dan fallback env
- Tetapkan `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk mewajibkan **penyimpanan profil** saja
- Mengapa ini ada:
- Memisahkan “API provider rusak / key tidak valid” dari “pipeline agent gateway rusak”
- Memisahkan “API provider rusak / kunci tidak valid” dari “pipeline agen gateway rusak”
- Menampung regresi kecil yang terisolasi (contoh: replay reasoning OpenAI Responses/Codex Responses + alur tool-call)
### Lapisan 2: Gateway + smoke dev agent (apa yang sebenarnya dilakukan "@openclaw")
### Lapisan 2: smoke gateway + agen dev (apa yang sebenarnya dilakukan "@openclaw")
- Pengujian: `src/gateway/gateway-models.profiles.live.test.ts`
- Tujuan:
- Menjalankan gateway in-process
- Membuat/menambal session `agent:dev:*` (override model per eksekusi)
- Mengiterasi model-dengan-key dan memverifikasi:
- respons “bermakna” (tanpa tools)
- pemanggilan tool nyata berfungsi (probe read)
- probe tool tambahan opsional (probe exec+read)
- Menyalakan gateway in-process
- Membuat/menambal sesi `agent:dev:*` (override model per run)
- Mengiterasi model-dengan-kunci dan memverifikasi:
- respons yang “bermakna” (tanpa tools)
- satu pemanggilan tool nyata berfungsi (probe read)
- probe tool ekstra opsional (probe exec+read)
- path regresi OpenAI (hanya tool-call → tindak lanjut) tetap berfungsi
- Detail probe (agar Anda dapat menjelaskan kegagalan dengan cepat):
- probe `read`: pengujian menulis file nonce di workspace lalu meminta agent `read` file tersebut dan mengembalikan nonce.
- probe `exec+read`: pengujian meminta agent menulis nonce ke file sementara via `exec`, lalu `read` kembali.
- probe gambar: pengujian melampirkan PNG yang dihasilkan (kucing + kode acak) dan mengharapkan model mengembalikan `cat <CODE>`.
- Detail probe (agar Anda bisa menjelaskan kegagalan dengan cepat):
- probe `read`: pengujian menulis file nonce di workspace dan meminta agen untuk `read` file itu lalu mengembalikan nonce tersebut.
- probe `exec+read`: pengujian meminta agen untuk menulis nonce ke file sementara melalui `exec`, lalu `read` kembali.
- probe image: pengujian melampirkan PNG yang dihasilkan (kucing + kode acak) dan mengharapkan model mengembalikan `cat <CODE>`.
- Referensi implementasi: `src/gateway/gateway-models.profiles.live.test.ts` dan `src/gateway/live-image-probe.ts`.
- Cara mengaktifkan:
- `pnpm test:live` (atau `OPENCLAW_LIVE_TEST=1` jika memanggil Vitest secara langsung)
- `pnpm test:live` (atau `OPENCLAW_LIVE_TEST=1` jika menjalankan Vitest secara langsung)
- Cara memilih model:
- Default: allowlist modern (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
- `OPENCLAW_LIVE_GATEWAY_MODELS=all` adalah alias untuk allowlist modern
- Atau tetapkan `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"` (atau daftar dipisahkan koma) untuk mempersempit
- Sweep gateway modern/all default ke batas kurasi dengan sinyal tinggi; tetapkan `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` untuk sweep modern lengkap atau angka positif untuk batas yang lebih kecil.
- Sapuan gateway modern/all secara default memakai batas kurasi dengan sinyal tinggi; tetapkan `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` untuk sapuan modern yang lengkap atau angka positif untuk batas yang lebih kecil.
- Cara memilih provider (hindari “semua OpenRouter”):
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"` (allowlist dipisahkan koma)
- Probe tool + gambar selalu aktif di live test ini:
- Probe tool + image selalu aktif dalam pengujian live ini:
- probe `read` + probe `exec+read` (stress tool)
- probe gambar berjalan saat model mengiklankan dukungan input gambar
- probe image berjalan saat model mengiklankan dukungan input image
- Alur (tingkat tinggi):
- Pengujian menghasilkan PNG kecil dengan “CAT” + kode acak (`src/gateway/live-image-probe.ts`)
- Mengirimkannya melalui `agent` `attachments: [{ mimeType: "image/png", content: "<base64>" }]`
- Gateway mem-parsing attachment menjadi `images[]` (`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`)
- Embedded agent meneruskan pesan pengguna multimodal ke model
- Asersi: balasan berisi `cat` + kode tersebut (toleransi OCR: kesalahan kecil diperbolehkan)
- Gateway mem-parsing lampiran ke dalam `images[]` (`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`)
- Agen embedded meneruskan pesan pengguna multimodal ke model
- Verifikasi: balasan berisi `cat` + kode tersebut (toleransi OCR: kesalahan kecil diperbolehkan)
Tip: untuk melihat apa yang bisa Anda uji pada mesin Anda (dan id `provider/model` yang tepat), jalankan:
Tip: untuk melihat apa yang bisa Anda uji di mesin Anda (dan id `provider/model` yang tepat), jalankan:
```bash
openclaw models list
openclaw models list --json
```
## Live: smoke backend CLI (Claude, Codex, Gemini, atau CLI lokal lain)
## Live: smoke backend CLI (Claude, Codex, Gemini, atau CLI lokal lainnya)
- Pengujian: `src/gateway/gateway-cli-backend.live.test.ts`
- Tujuan: memvalidasi pipeline Gateway + agent menggunakan backend CLI lokal, tanpa menyentuh config default Anda.
- Default smoke spesifik backend berada bersama definisi `cli-backend.ts` milik extension yang bersangkutan.
- Tujuan: memvalidasi pipeline Gateway + agen menggunakan backend CLI lokal, tanpa menyentuh config default Anda.
- Default smoke khusus backend berada di definisi `cli-backend.ts` milik extension pemiliknya.
- Aktifkan:
- `pnpm test:live` (atau `OPENCLAW_LIVE_TEST=1` jika memanggil Vitest secara langsung)
- `pnpm test:live` (atau `OPENCLAW_LIVE_TEST=1` jika menjalankan Vitest secara langsung)
- `OPENCLAW_LIVE_CLI_BACKEND=1`
- Default:
- Provider/model default: `claude-cli/claude-sonnet-4-6`
- Perilaku command/args/image berasal dari metadata plugin backend CLI yang memilikinya.
- Perilaku perintah/arg/image berasal dari metadata plugin backend CLI pemiliknya.
- Override (opsional):
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4"`
- `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"`
- `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'`
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` untuk mengirim attachment gambar nyata (path disuntikkan ke prompt).
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` untuk meneruskan path file gambar sebagai argumen CLI alih-alih injeksi prompt.
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (atau `"list"`) untuk mengendalikan cara argumen gambar diteruskan saat `IMAGE_ARG` ditetapkan.
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` untuk mengirim lampiran image nyata (path disisipkan ke prompt).
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` untuk meneruskan path file image sebagai arg CLI alih-alih menyisipkannya ke prompt.
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (atau `"list"`) untuk mengontrol cara arg image diteruskan saat `IMAGE_ARG` ditetapkan.
- `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` untuk mengirim giliran kedua dan memvalidasi alur resume.
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` untuk menonaktifkan probe kontinuitas satu session default Claude Sonnet -> Opus (tetapkan ke `1` untuk memaksanya aktif saat model yang dipilih mendukung target switch).
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` untuk menonaktifkan probe kontinuitas sesi yang default dari Claude Sonnet -> Opus pada sesi yang sama (tetapkan ke `1` untuk memaksanya aktif saat model yang dipilih mendukung target switch).
Contoh:
@ -297,7 +319,7 @@ Resep Docker:
pnpm test:docker:live-cli-backend
```
Resep Docker penyedia tunggal:
Resep Docker single-provider:
```bash
pnpm test:docker:live-cli-backend:claude
@ -308,26 +330,26 @@ pnpm test:docker:live-cli-backend:gemini
Catatan:
- Runner Docker berada di `scripts/test-live-cli-backend-docker.sh`.
- Runner ini menjalankan smoke CLI-backend live di dalam image Docker repo sebagai pengguna non-root `node`.
- Runner ini me-resolve metadata smoke CLI dari extension yang memilikinya, lalu memasang paket CLI Linux yang sesuai (`@anthropic-ai/claude-code`, `@openai/codex`, atau `@google/gemini-cli`) ke prefix writable yang di-cache di `OPENCLAW_DOCKER_CLI_TOOLS_DIR` (default: `~/.cache/openclaw/docker-cli-tools`).
- Smoke CLI-backend live sekarang menjalankan alur end-to-end yang sama untuk Claude, Codex, dan Gemini: giliran teks, giliran klasifikasi gambar, lalu pemanggilan tool MCP `cron` yang diverifikasi melalui CLI gateway.
- Smoke default Claude juga menambal session dari Sonnet ke Opus dan memverifikasi session yang dilanjutkan masih mengingat catatan sebelumnya.
- Runner ini menjalankan smoke backend CLI live di dalam image Docker repo sebagai pengguna non-root `node`.
- Runner ini me-resolve metadata smoke CLI dari extension pemiliknya, lalu memasang paket CLI Linux yang sesuai (`@anthropic-ai/claude-code`, `@openai/codex`, atau `@google/gemini-cli`) ke prefix writable yang di-cache di `OPENCLAW_DOCKER_CLI_TOOLS_DIR` (default: `~/.cache/openclaw/docker-cli-tools`).
- Smoke backend CLI live sekarang menjalankan alur end-to-end yang sama untuk Claude, Codex, dan Gemini: giliran teks, giliran klasifikasi image, lalu pemanggilan tool MCP `cron` yang diverifikasi melalui CLI gateway.
- Smoke default Claude juga menambal sesi dari Sonnet ke Opus dan memverifikasi bahwa sesi yang dilanjutkan masih mengingat catatan sebelumnya.
## Live: smoke bind ACP (`/acp spawn ... --bind here`)
- Pengujian: `src/gateway/gateway-acp-bind.live.test.ts`
- Tujuan: memvalidasi alur bind percakapan ACP nyata dengan agent ACP live:
- Tujuan: memvalidasi alur bind percakapan ACP nyata dengan agen ACP live:
- kirim `/acp spawn <agent> --bind here`
- bind percakapan message-channel sintetis di tempat
- kirim tindak lanjut normal pada percakapan yang sama
- verifikasi tindak lanjut masuk ke transkrip session ACP yang terikat
- bind percakapan saluran pesan sintetis di tempat
- kirim tindak lanjut normal pada percakapan yang sama itu
- verifikasi bahwa tindak lanjut masuk ke transkrip sesi ACP yang terikat
- Aktifkan:
- `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts`
- `OPENCLAW_LIVE_ACP_BIND=1`
- Default:
- Agent ACP di Docker: `claude,codex,gemini`
- Agent ACP untuk `pnpm test:live ...` langsung: `claude`
- Channel sintetis: konteks percakapan bergaya Slack DM
- Agen ACP di Docker: `claude,codex,gemini`
- Agen ACP untuk `pnpm test:live ...` langsung: `claude`
- Saluran sintetis: konteks percakapan gaya DM Slack
- Backend ACP: `acpx`
- Override:
- `OPENCLAW_LIVE_ACP_BIND_AGENT=claude`
@ -336,8 +358,8 @@ Catatan:
- `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini`
- `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@<version>'`
- Catatan:
- Lane ini menggunakan surface gateway `chat.send` dengan field originating-route sintetis khusus admin agar pengujian dapat melampirkan konteks message-channel tanpa berpura-pura melakukan pengiriman eksternal.
- Saat `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` tidak ditetapkan, pengujian ini menggunakan registry agent bawaan plugin `acpx` embedded untuk agent harness ACP yang dipilih.
- Lane ini menggunakan permukaan gateway `chat.send` dengan field originating-route sintetis khusus admin sehingga pengujian dapat melampirkan konteks saluran pesan tanpa berpura-pura mengirim secara eksternal.
- Saat `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` tidak ditetapkan, pengujian menggunakan registry agen bawaan plugin `acpx` embedded untuk agen harness ACP yang dipilih.
Contoh:
@ -353,7 +375,7 @@ Resep Docker:
pnpm test:docker:live-acp-bind
```
Resep Docker agen tunggal:
Resep Docker single-agent:
```bash
pnpm test:docker:live-acp-bind:claude
@ -364,19 +386,19 @@ pnpm test:docker:live-acp-bind:gemini
Catatan Docker:
- Runner Docker berada di `scripts/test-live-acp-bind-docker.sh`.
- Secara default, runner ini menjalankan smoke bind ACP terhadap semua agent CLI live yang didukung secara berurutan: `claude`, `codex`, lalu `gemini`.
- Secara default, runner ini menjalankan smoke bind ACP terhadap semua agen CLI live yang didukung secara berurutan: `claude`, `codex`, lalu `gemini`.
- Gunakan `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=codex`, atau `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` untuk mempersempit matriks.
- Runner ini melakukan source `~/.profile`, men-stage materi auth CLI yang sesuai ke container, memasang `acpx` ke prefix npm yang writable, lalu memasang CLI live yang diminta (`@anthropic-ai/claude-code`, `@openai/codex`, atau `@google/gemini-cli`) jika belum ada.
- Di dalam Docker, runner menetapkan `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx` agar acpx mempertahankan env var provider dari profile yang telah di-source tetap tersedia untuk CLI harness anak.
- Runner ini memuat `~/.profile`, menyiapkan materi autentikasi CLI yang sesuai ke dalam container, memasang `acpx` ke prefix npm writable, lalu memasang CLI live yang diminta (`@anthropic-ai/claude-code`, `@openai/codex`, atau `@google/gemini-cli`) jika belum ada.
- Di dalam Docker, runner menetapkan `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx` agar acpx tetap menyediakan env var provider dari profile yang dimuat untuk CLI harness child.
### Resep live yang direkomendasikan
Allowlist yang sempit dan eksplisit paling cepat dan paling sedikit flakey:
Allowlist yang sempit dan eksplisit adalah yang tercepat dan paling tidak flaky:
- Satu model, direct (tanpa gateway):
- Satu model, langsung (tanpa gateway):
- `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts`
- Satu model, gateway smoke:
- Satu model, smoke gateway:
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- Tool calling di beberapa provider:
@ -389,19 +411,19 @@ Allowlist yang sempit dan eksplisit paling cepat dan paling sedikit flakey:
Catatan:
- `google/...` menggunakan Gemini API (API key).
- `google-antigravity/...` menggunakan bridge OAuth Antigravity (endpoint agent bergaya Cloud Code Assist).
- `google-gemini-cli/...` menggunakan CLI Gemini lokal di mesin Anda (auth dan keanehan tooling terpisah).
- `google-antigravity/...` menggunakan bridge OAuth Antigravity (endpoint agen bergaya Cloud Code Assist).
- `google-gemini-cli/...` menggunakan Gemini CLI lokal di mesin Anda (autentikasi + keanehan tooling terpisah).
- Gemini API vs Gemini CLI:
- API: OpenClaw memanggil Gemini API yang di-host Google melalui HTTP (API key / auth profil); inilah yang biasanya dimaksud kebanyakan pengguna dengan “Gemini”.
- CLI: OpenClaw melakukan shell out ke biner `gemini` lokal; ini memiliki auth sendiri dan dapat berperilaku berbeda (streaming/dukungan tool/perbedaan versi).
- API: OpenClaw memanggil Gemini API yang di-host Google melalui HTTP (API key / autentikasi profil); inilah yang dimaksud sebagian besar pengguna saat menyebut “Gemini”.
- CLI: OpenClaw melakukan shell out ke binary `gemini` lokal; ini memiliki autentikasi sendiri dan dapat berperilaku berbeda (streaming/dukungan tool/perbedaan versi).
## Live: matriks model (apa yang kami cakup)
Tidak ada “daftar model CI” yang tetap (live bersifat opt-in), tetapi ini adalah model-model **yang direkomendasikan** untuk dicakup secara rutin di mesin pengembang dengan key.
Tidak ada “daftar model CI” yang tetap (live bersifat opt-in), tetapi ini adalah model-model yang **direkomendasikan** untuk dicakup secara rutin di mesin pengembang dengan kunci.
### Set smoke modern (tool calling + gambar)
### Set smoke modern (tool calling + image)
Ini adalah eksekusi “model umum” yang kami harapkan tetap berfungsi:
Ini adalah run “model umum” yang kami harapkan tetap berfungsi:
- OpenAI (non-Codex): `openai/gpt-5.4` (opsional: `openai/gpt-5.4-mini`)
- OpenAI Codex: `openai-codex/gpt-5.4`
@ -411,7 +433,7 @@ Ini adalah eksekusi “model umum” yang kami harapkan tetap berfungsi:
- Z.AI (GLM): `zai/glm-4.7`
- MiniMax: `minimax/MiniMax-M2.7`
Jalankan gateway smoke dengan tools + gambar:
Jalankan smoke gateway dengan tools + image:
`OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,openai-codex/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
### Baseline: tool calling (Read + Exec opsional)
@ -427,41 +449,41 @@ Pilih setidaknya satu per keluarga provider:
Cakupan tambahan opsional (bagus untuk dimiliki):
- xAI: `xai/grok-4` (atau versi terbaru yang tersedia)
- Mistral: `mistral/`… (pilih satu model yang mampu menggunakan tools dan Anda aktifkan)
- Mistral: `mistral/`… (pilih satu model yang mampu menangani “tools” dan telah Anda aktifkan)
- Cerebras: `cerebras/`… (jika Anda memiliki akses)
- LM Studio: `lmstudio/`… (lokal; tool calling bergantung pada mode API)
### Vision: pengiriman gambar (attachment → pesan multimodal)
### Vision: pengiriman image (lampiran → pesan multimodal)
Sertakan setidaknya satu model yang mendukung gambar di `OPENCLAW_LIVE_GATEWAY_MODELS` (Claude/Gemini/varian OpenAI yang mendukung vision, dan sebagainya) untuk menjalankan probe gambar.
Sertakan setidaknya satu model yang mendukung image dalam `OPENCLAW_LIVE_GATEWAY_MODELS` (varian Claude/Gemini/OpenAI yang mendukung vision, dll.) untuk menjalankan probe image.
### Agregator / gateway alternatif
### Aggregator / gateway alternatif
Jika Anda mengaktifkan key, kami juga mendukung pengujian melalui:
Jika Anda mengaktifkan kunci, kami juga mendukung pengujian melalui:
- OpenRouter: `openrouter/...` (ratusan model; gunakan `openclaw models scan` untuk menemukan kandidat yang mendukung tool+gambar)
- OpenCode: `opencode/...` untuk Zen dan `opencode-go/...` untuk Go (auth melalui `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY`)
- OpenRouter: `openrouter/...` (ratusan model; gunakan `openclaw models scan` untuk menemukan kandidat yang mendukung tool+image)
- OpenCode: `opencode/...` untuk Zen dan `opencode-go/...` untuk Go (autentikasi melalui `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY`)
Provider lain yang dapat Anda sertakan dalam matriks live (jika Anda memiliki kredensial/config):
Lebih banyak provider yang dapat Anda sertakan dalam matriks live (jika Anda memiliki kredensial/config):
- Built-in: `openai`, `openai-codex`, `anthropic`, `google`, `google-vertex`, `google-antigravity`, `google-gemini-cli`, `zai`, `openrouter`, `opencode`, `opencode-go`, `xai`, `groq`, `cerebras`, `mistral`, `github-copilot`
- Melalui `models.providers` (endpoint kustom): `minimax` (cloud/API), plus proxy apa pun yang kompatibel dengan OpenAI/Anthropic (LM Studio, vLLM, LiteLLM, dll.)
- Via `models.providers` (endpoint kustom): `minimax` (cloud/API), ditambah proxy yang kompatibel dengan OpenAI/Anthropic (LM Studio, vLLM, LiteLLM, dll.)
Tip: jangan mencoba meng-hardcode “semua model” di dokumentasi. Daftar otoritatif adalah apa pun yang dikembalikan `discoverModels(...)` di mesin Anda + key apa pun yang tersedia.
Tip: jangan mencoba melakukan hardcode “semua model” di dokumen. Daftar otoritatif adalah apa pun yang dikembalikan `discoverModels(...)` di mesin Anda + kunci apa pun yang tersedia.
## Kredensial (jangan pernah di-commit)
## Kredensial (jangan pernah commit)
Live test menemukan kredensial dengan cara yang sama seperti CLI. Implikasi praktisnya:
Pengujian live menemukan kredensial dengan cara yang sama seperti CLI. Implikasi praktisnya:
- Jika CLI berfungsi, live test seharusnya menemukan key yang sama.
- Jika live test mengatakan “tidak ada kredensial”, debug dengan cara yang sama seperti Anda men-debug `openclaw models list` / pemilihan model.
- Jika CLI berfungsi, pengujian live seharusnya menemukan kunci yang sama.
- Jika pengujian live mengatakan “tidak ada kredensial”, debug dengan cara yang sama seperti Anda men-debug `openclaw models list` / pemilihan model.
- Profil auth per-agent: `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` (inilah yang dimaksud dengan “profile keys” di live test)
- Profil autentikasi per agen: `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` (inilah yang dimaksud “kunci profil” dalam pengujian live)
- Config: `~/.openclaw/openclaw.json` (atau `OPENCLAW_CONFIG_PATH`)
- Direktori status lama: `~/.openclaw/credentials/` (disalin ke home live yang di-stage jika ada, tetapi bukan penyimpanan utama profile-key)
- Eksekusi lokal live secara default menyalin config aktif, file `auth-profiles.json` per-agent, `credentials/` lama, dan direktori auth CLI eksternal yang didukung ke home pengujian sementara; home live yang di-stage melewati `workspace/` dan `sandboxes/`, dan override path `agents.*.workspace` / `agentDir` dihapus agar probe tidak menyentuh workspace host asli Anda.
- Direktori state lama: `~/.openclaw/credentials/` (disalin ke home live yang dipersiapkan saat ada, tetapi bukan penyimpanan utama kunci profil)
- Run live lokal menyalin config aktif, file `auth-profiles.json` per agen, `credentials/` lama, dan direktori autentikasi CLI eksternal yang didukung ke home pengujian sementara secara default; home live yang dipersiapkan melewati `workspace/` dan `sandboxes/`, dan override path `agents.*.workspace` / `agentDir` dihapus agar probe tidak menyentuh workspace host nyata Anda.
Jika Anda ingin mengandalkan key env (misalnya diekspor di `~/.profile`), jalankan pengujian lokal setelah `source ~/.profile`, atau gunakan runner Docker di bawah (runner tersebut dapat me-mount `~/.profile` ke container).
Jika Anda ingin mengandalkan kunci env (misalnya diekspor di `~/.profile` Anda), jalankan pengujian lokal setelah `source ~/.profile`, atau gunakan runner Docker di bawah (runner tersebut dapat me-mount `~/.profile` ke dalam container).
## Live Deepgram (transkripsi audio)
@ -480,20 +502,20 @@ Jika Anda ingin mengandalkan key env (misalnya diekspor di `~/.profile`), jalank
- Aktifkan: `OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts`
- Cakupan:
- Menjalankan path image, video, dan `music_generate` comfy bawaan
- Melewati setiap kapabilitas kecuali `models.providers.comfy.<capability>` dikonfigurasi
- Berguna setelah mengubah pengiriman workflow comfy, polling, download, atau registrasi plugin
- Melewati tiap kapabilitas kecuali `models.providers.comfy.<capability>` telah dikonfigurasi
- Berguna setelah mengubah pengiriman workflow comfy, polling, unduhan, atau registrasi plugin
## Live pembuatan gambar
## Live pembuatan image
- Pengujian: `src/image-generation/runtime.live.test.ts`
- Perintah: `pnpm test:live src/image-generation/runtime.live.test.ts`
- Harness: `pnpm test:live:media image`
- Cakupan:
- Mengenumerasi setiap plugin provider image-generation yang terdaftar
- Memuat env var provider yang hilang dari login shell Anda (`~/.profile`) sebelum melakukan probe
- Secara default menggunakan API key live/env lebih dahulu daripada profil auth yang disimpan, sehingga key pengujian lama di `auth-profiles.json` tidak menutupi kredensial shell asli
- Melewati provider yang tidak memiliki auth/profil/model yang dapat digunakan
- Menjalankan varian image-generation bawaan melalui kapabilitas runtime bersama:
- Mengenumerasi setiap plugin provider pembuatan image yang terdaftar
- Memuat env var provider yang belum ada dari login shell Anda (`~/.profile`) sebelum probing
- Secara default menggunakan API key live/env lebih dahulu daripada profil autentikasi yang tersimpan, agar kunci pengujian usang di `auth-profiles.json` tidak menutupi kredensial shell nyata
- Melewati provider yang tidak memiliki autentikasi/profil/model yang dapat digunakan
- Menjalankan varian stock pembuatan image melalui kapabilitas runtime bersama:
- `google:flash-generate`
- `google:pro-generate`
- `google:pro-edit`
@ -505,8 +527,8 @@ Jika Anda ingin mengandalkan key env (misalnya diekspor di `~/.profile`), jalank
- `OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google"`
- `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-1,google/gemini-3.1-flash-image-preview"`
- `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit"`
- Perilaku auth opsional:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk memaksa auth profile-store dan mengabaikan override khusus env
- Perilaku autentikasi opsional:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk memaksa autentikasi dari penyimpanan profil dan mengabaikan override yang hanya berasal dari env
## Live pembuatan musik
@ -514,23 +536,23 @@ Jika Anda ingin mengandalkan key env (misalnya diekspor di `~/.profile`), jalank
- Aktifkan: `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts`
- Harness: `pnpm test:live:media music`
- Cakupan:
- Menjalankan path provider music-generation bawaan bersama
- Menjalankan path provider pembuatan musik bawaan bersama
- Saat ini mencakup Google dan MiniMax
- Memuat env var provider dari login shell Anda (`~/.profile`) sebelum melakukan probe
- Secara default menggunakan API key live/env lebih dahulu daripada profil auth yang disimpan, sehingga key pengujian lama di `auth-profiles.json` tidak menutupi kredensial shell asli
- Melewati provider yang tidak memiliki auth/profil/model yang dapat digunakan
- Menjalankan kedua mode runtime yang dideklarasikan jika tersedia:
- `generate` dengan input prompt saja
- Memuat env var provider dari login shell Anda (`~/.profile`) sebelum probing
- Secara default menggunakan API key live/env lebih dahulu daripada profil autentikasi yang tersimpan, agar kunci pengujian usang di `auth-profiles.json` tidak menutupi kredensial shell nyata
- Melewati provider yang tidak memiliki autentikasi/profil/model yang dapat digunakan
- Menjalankan kedua mode runtime yang dideklarasikan saat tersedia:
- `generate` dengan input hanya prompt
- `edit` saat provider mendeklarasikan `capabilities.edit.enabled`
- Cakupan current shared-lane:
- Cakupan shared-lane saat ini:
- `google`: `generate`, `edit`
- `minimax`: `generate`
- `comfy`: file live Comfy terpisah, bukan sweep bersama ini
- `comfy`: file live Comfy terpisah, bukan sapuan bersama ini
- Penyempitan opsional:
- `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"`
- `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"`
- Perilaku auth opsional:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk memaksa auth profile-store dan mengabaikan override khusus env
- Perilaku autentikasi opsional:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk memaksa autentikasi dari penyimpanan profil dan mengabaikan override yang hanya berasal dari env
## Live pembuatan video
@ -538,39 +560,39 @@ Jika Anda ingin mengandalkan key env (misalnya diekspor di `~/.profile`), jalank
- Aktifkan: `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts`
- Harness: `pnpm test:live:media video`
- Cakupan:
- Menjalankan path provider video-generation bawaan bersama
- Memuat env var provider dari login shell Anda (`~/.profile`) sebelum melakukan probe
- Secara default menggunakan API key live/env lebih dahulu daripada profil auth yang disimpan, sehingga key pengujian lama di `auth-profiles.json` tidak menutupi kredensial shell asli
- Melewati provider yang tidak memiliki auth/profil/model yang dapat digunakan
- Menjalankan kedua mode runtime yang dideklarasikan jika tersedia:
- `generate` dengan input prompt saja
- `imageToVideo` saat provider mendeklarasikan `capabilities.imageToVideo.enabled` dan provider/model yang dipilih menerima input gambar lokal berbasis buffer dalam sweep bersama
- `videoToVideo` saat provider mendeklarasikan `capabilities.videoToVideo.enabled` dan provider/model yang dipilih menerima input video lokal berbasis buffer dalam sweep bersama
- Provider `imageToVideo` yang saat ini dideklarasikan tetapi di-skip dalam sweep bersama:
- `vydra` karena `veo3` bawaan hanya mendukung teks dan `kling` bawaan memerlukan URL gambar jarak jauh
- Cakupan Vydra spesifik provider:
- Menjalankan path provider pembuatan video bawaan bersama
- Memuat env var provider dari login shell Anda (`~/.profile`) sebelum probing
- Secara default menggunakan API key live/env lebih dahulu daripada profil autentikasi yang tersimpan, agar kunci pengujian usang di `auth-profiles.json` tidak menutupi kredensial shell nyata
- Melewati provider yang tidak memiliki autentikasi/profil/model yang dapat digunakan
- Menjalankan kedua mode runtime yang dideklarasikan saat tersedia:
- `generate` dengan input hanya prompt
- `imageToVideo` saat provider mendeklarasikan `capabilities.imageToVideo.enabled` dan provider/model yang dipilih menerima input image lokal berbasis buffer dalam sapuan bersama
- `videoToVideo` saat provider mendeklarasikan `capabilities.videoToVideo.enabled` dan provider/model yang dipilih menerima input video lokal berbasis buffer dalam sapuan bersama
- Provider `imageToVideo` yang saat ini dideklarasikan tetapi dilewati dalam sapuan bersama:
- `vydra` karena `veo3` bawaan hanya mendukung teks dan `kling` bawaan memerlukan URL image jarak jauh
- Cakupan Vydra khusus provider:
- `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts`
- file itu menjalankan lane text-to-video `veo3` plus lane `kling` yang secara default menggunakan fixture URL gambar jarak jauh
- file tersebut menjalankan `veo3` text-to-video serta lane `kling` yang secara default menggunakan fixture URL image jarak jauh
- Cakupan live `videoToVideo` saat ini:
- `runway` hanya saat model yang dipilih adalah `runway/gen4_aleph`
- Provider `videoToVideo` yang saat ini dideklarasikan tetapi di-skip dalam sweep bersama:
- Provider `videoToVideo` yang saat ini dideklarasikan tetapi dilewati dalam sapuan bersama:
- `alibaba`, `qwen`, `xai` karena path tersebut saat ini memerlukan URL referensi `http(s)` / MP4 jarak jauh
- `google` karena lane Gemini/Veo bersama saat ini menggunakan input lokal berbasis buffer dan path itu tidak diterima dalam sweep bersama
- `openai` karena lane bersama saat ini tidak memiliki jaminan akses video inpaint/remix spesifik org
- `google` karena lane Gemini/Veo bersama saat ini menggunakan input lokal berbasis buffer dan path itu tidak diterima dalam sapuan bersama
- `openai` karena lane bersama saat ini tidak memiliki jaminan akses video inpaint/remix spesifik organisasi
- Penyempitan opsional:
- `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"`
- `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"`
- Perilaku auth opsional:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk memaksa auth profile-store dan mengabaikan override khusus env
- Perilaku autentikasi opsional:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk memaksa autentikasi dari penyimpanan profil dan mengabaikan override yang hanya berasal dari env
## Harness live media
- Perintah: `pnpm test:live:media`
- Tujuan:
- Menjalankan suite live gambar, musik, dan video bersama melalui satu entrypoint native repo
- Memuat otomatis env var provider yang hilang dari `~/.profile`
- Secara default mempersempit otomatis setiap suite ke provider yang saat ini memiliki auth yang dapat digunakan
- Menggunakan kembali `scripts/test-live.mjs`, sehingga perilaku heartbeat dan quiet-mode tetap konsisten
- Menjalankan suite live image, music, dan video bersama melalui entrypoint native repo tunggal
- Memuat otomatis env var provider yang belum ada dari `~/.profile`
- Secara default mempersempit otomatis tiap suite ke provider yang saat ini memiliki autentikasi yang dapat digunakan
- Menggunakan ulang `scripts/test-live.mjs`, sehingga perilaku heartbeat dan mode senyap tetap konsisten
- Contoh:
- `pnpm test:live:media`
- `pnpm test:live:media image video --providers openai,google,minimax`
@ -579,138 +601,138 @@ Jika Anda ingin mengandalkan key env (misalnya diekspor di `~/.profile`), jalank
## Runner Docker (opsional untuk pemeriksaan "berfungsi di Linux")
Runner Docker ini terbagi menjadi dua kelompok:
Runner Docker ini terbagi ke dalam dua kelompok:
- Runner live-model: `test:docker:live-models` dan `test:docker:live-gateway` hanya menjalankan file live profile-key yang cocok di dalam image Docker repo (`src/agents/models.profiles.live.test.ts` dan `src/gateway/gateway-models.profiles.live.test.ts`), dengan me-mount direktori config dan workspace lokal Anda (serta melakukan source `~/.profile` jika di-mount). Entrypoint lokal yang sesuai adalah `test:live:models-profiles` dan `test:live:gateway-profiles`.
- Runner live Docker secara default menggunakan batas smoke yang lebih kecil agar sweep Docker penuh tetap praktis:
`test:docker:live-models` default ke `OPENCLAW_LIVE_MAX_MODELS=12`, dan
`test:docker:live-gateway` default ke `OPENCLAW_LIVE_GATEWAY_SMOKE=1`,
- Runner live-model: `test:docker:live-models` dan `test:docker:live-gateway` hanya menjalankan file live kunci-profil yang cocok di dalam image Docker repo (`src/agents/models.profiles.live.test.ts` dan `src/gateway/gateway-models.profiles.live.test.ts`), dengan me-mount direktori config dan workspace lokal Anda (serta memuat `~/.profile` jika di-mount). Entrypoint lokal yang cocok adalah `test:live:models-profiles` dan `test:live:gateway-profiles`.
- Runner live Docker secara default memakai batas smoke yang lebih kecil agar sapuan Docker penuh tetap praktis:
`test:docker:live-models` secara default menetapkan `OPENCLAW_LIVE_MAX_MODELS=12`, dan
`test:docker:live-gateway` secara default menetapkan `OPENCLAW_LIVE_GATEWAY_SMOKE=1`,
`OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`,
`OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000`, dan
`OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Override env var tersebut saat Anda
memang ingin pemindaian lengkap yang lebih besar.
- `test:docker:all` membangun image live Docker sekali melalui `test:docker:live-build`, lalu menggunakannya kembali untuk dua lane live Docker tersebut.
- Runner smoke container: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:gateway-network`, `test:docker:mcp-channels`, dan `test:docker:plugins` mem-boot satu atau lebih container nyata dan memverifikasi path integrasi tingkat lebih tinggi.
- `test:docker:all` membangun image Docker live satu kali melalui `test:docker:live-build`, lalu menggunakannya kembali untuk dua lane Docker live tersebut.
- Runner smoke container: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:gateway-network`, `test:docker:mcp-channels`, dan `test:docker:plugins` menyalakan satu atau lebih container nyata dan memverifikasi path integrasi tingkat lebih tinggi.
Runner Docker live-model juga me-mount hanya home auth CLI yang diperlukan (atau semua yang didukung saat eksekusi tidak dipersempit), lalu menyalinnya ke home container sebelum eksekusi agar OAuth CLI eksternal dapat menyegarkan token tanpa mengubah penyimpanan auth host:
Runner Docker live-model juga melakukan bind-mount hanya pada home autentikasi CLI yang diperlukan (atau semuanya yang didukung saat run tidak dipersempit), lalu menyalinnya ke home container sebelum run agar OAuth CLI eksternal dapat menyegarkan token tanpa mengubah penyimpanan autentikasi host:
- Model direct: `pnpm test:docker:live-models` (skrip: `scripts/test-live-models-docker.sh`)
- Model langsung: `pnpm test:docker:live-models` (skrip: `scripts/test-live-models-docker.sh`)
- Smoke bind ACP: `pnpm test:docker:live-acp-bind` (skrip: `scripts/test-live-acp-bind-docker.sh`)
- Smoke backend CLI: `pnpm test:docker:live-cli-backend` (skrip: `scripts/test-live-cli-backend-docker.sh`)
- Gateway + dev agent: `pnpm test:docker:live-gateway` (skrip: `scripts/test-live-gateway-models-docker.sh`)
- Gateway + agen dev: `pnpm test:docker:live-gateway` (skrip: `scripts/test-live-gateway-models-docker.sh`)
- Smoke live Open WebUI: `pnpm test:docker:openwebui` (skrip: `scripts/e2e/openwebui-docker.sh`)
- Wizard onboarding (TTY, scaffolding penuh): `pnpm test:docker:onboard` (skrip: `scripts/e2e/onboard-docker.sh`)
- Jaringan gateway (dua container, auth + health WS): `pnpm test:docker:gateway-network` (skrip: `scripts/e2e/gateway-network-docker.sh`)
- Bridge channel MCP (Gateway seed + bridge stdio + smoke raw Claude notification-frame): `pnpm test:docker:mcp-channels` (skrip: `scripts/e2e/mcp-channels-docker.sh`)
- Plugins (smoke instalasi + alias `/plugin` + semantik restart Claude-bundle): `pnpm test:docker:plugins` (skrip: `scripts/e2e/plugins-docker.sh`)
- Jaringan gateway (dua container, autentikasi WS + health): `pnpm test:docker:gateway-network` (skrip: `scripts/e2e/gateway-network-docker.sh`)
- Bridge channel MCP (Gateway berisi seed + bridge stdio + smoke notification-frame Claude mentah): `pnpm test:docker:mcp-channels` (skrip: `scripts/e2e/mcp-channels-docker.sh`)
- Plugin (smoke install + alias `/plugin` + semantik restart bundle Claude): `pnpm test:docker:plugins` (skrip: `scripts/e2e/plugins-docker.sh`)
Runner Docker live-model juga me-mount checkout saat ini sebagai read-only dan
men-stage-nya ke workdir sementara di dalam container. Ini menjaga image runtime
tetap ramping sambil tetap menjalankan Vitest terhadap source/config lokal Anda secara persis.
Langkah staging melewati cache lokal besar dan output build aplikasi seperti
`.pnpm-store`, `.worktrees`, `__openclaw_vitest__`, serta
direktori output `.build` lokal aplikasi atau Gradle sehingga Docker live run tidak
menghabiskan waktu beberapa menit untuk menyalin artefak spesifik mesin.
Runner ini juga menetapkan `OPENCLAW_SKIP_CHANNELS=1` sehingga probe live gateway tidak memulai
Runner Docker live-model juga melakukan bind-mount checkout saat ini dalam mode read-only dan
menyiapkannya ke workdir sementara di dalam container. Ini menjaga image runtime
tetap ramping sambil tetap menjalankan Vitest terhadap source/config lokal Anda yang tepat.
Langkah staging melewati cache besar yang hanya lokal dan output build aplikasi seperti
`.pnpm-store`, `.worktrees`, `__openclaw_vitest__`, dan direktori output `.build` lokal aplikasi atau
Gradle sehingga run live Docker tidak menghabiskan waktu beberapa menit untuk menyalin
artefak spesifik mesin.
Runner tersebut juga menetapkan `OPENCLAW_SKIP_CHANNELS=1` agar probe live gateway tidak memulai
worker channel Telegram/Discord/dll. nyata di dalam container.
`test:docker:live-models` tetap menjalankan `pnpm test:live`, jadi teruskan juga
`OPENCLAW_LIVE_GATEWAY_*` saat Anda perlu mempersempit atau mengecualikan cakupan
live gateway dari lane Docker tersebut.
`OPENCLAW_LIVE_GATEWAY_*` saat Anda perlu mempersempit atau mengecualikan cakupan live
gateway dari lane Docker tersebut.
`test:docker:openwebui` adalah smoke kompatibilitas tingkat lebih tinggi: runner ini memulai
container gateway OpenClaw dengan endpoint HTTP yang kompatibel dengan OpenAI diaktifkan,
memulai container Open WebUI yang dipatok terhadap gateway tersebut, melakukan sign in melalui
memulai container Open WebUI yang dipin terhadap gateway itu, masuk melalui
Open WebUI, memverifikasi `/api/models` mengekspos `openclaw/default`, lalu mengirim
permintaan chat nyata melalui proxy `/api/chat/completions` milik Open WebUI.
Eksekusi pertama bisa terasa lebih lambat karena Docker mungkin perlu menarik image
Open WebUI dan Open WebUI mungkin perlu menyelesaikan setup cold-start-nya sendiri.
Lane ini mengharapkan key model live yang dapat digunakan, dan `OPENCLAW_PROFILE_FILE`
(`~/.profile` secara default) adalah cara utama untuk menyediakannya dalam eksekusi berbasis Docker.
Eksekusi yang berhasil mencetak payload JSON kecil seperti `{ "ok": true, "model":
Run pertama bisa terasa lebih lambat karena Docker mungkin perlu menarik image
Open WebUI dan Open WebUI mungkin perlu menyelesaikan setup cold-start miliknya.
Lane ini mengharapkan kunci model live yang dapat digunakan, dan `OPENCLAW_PROFILE_FILE`
(`~/.profile` secara default) adalah cara utama untuk menyediakannya dalam run yang di-Docker-kan.
Run yang berhasil mencetak payload JSON kecil seperti `{ "ok": true, "model":
"openclaw/default", ... }`.
`test:docker:mcp-channels` sengaja dibuat deterministik dan tidak memerlukan
akun Telegram, Discord, atau iMessage nyata. Runner ini mem-boot Gateway seed
container, memulai container kedua yang memunculkan `openclaw mcp serve`, lalu
memverifikasi penemuan percakapan yang dirutekan, pembacaan transkrip, metadata attachment,
perilaku antrean event live, routing pengiriman keluar, serta notifikasi channel +
izin bergaya Claude melalui bridge MCP stdio yang nyata. Pemeriksaan notifikasi
memeriksa frame MCP stdio mentah secara langsung sehingga smoke memvalidasi apa yang
sebenarnya dipancarkan bridge, bukan hanya apa yang kebetulan diekspos oleh SDK klien tertentu.
akun Telegram, Discord, atau iMessage nyata. Runner ini menyalakan container Gateway
yang sudah diberi seed, memulai container kedua yang menjalankan `openclaw mcp serve`, lalu
memverifikasi penemuan percakapan yang dirutekan, pembacaan transkrip, metadata lampiran,
perilaku antrean event live, routing pengiriman keluar, serta notifikasi saluran +
izin bergaya Claude melalui bridge MCP stdio nyata. Pemeriksaan notifikasi
menginspeksi frame MCP stdio mentah secara langsung sehingga smoke ini memvalidasi apa yang
benar-benar dipancarkan oleh bridge, bukan hanya apa yang kebetulan ditampilkan oleh SDK klien tertentu.
Smoke thread bahasa alami ACP manual (bukan CI):
Smoke thread bahasa natural ACP manual (bukan CI):
- `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...`
- Pertahankan skrip ini untuk alur kerja regresi/debug. Skrip ini mungkin diperlukan lagi untuk validasi routing thread ACP, jadi jangan dihapus.
- Simpan skrip ini untuk alur kerja regresi/debug. Ini mungkin akan dibutuhkan lagi untuk validasi routing thread ACP, jadi jangan dihapus.
Env var yang berguna:
- `OPENCLAW_CONFIG_DIR=...` (default: `~/.openclaw`) di-mount ke `/home/node/.openclaw`
- `OPENCLAW_WORKSPACE_DIR=...` (default: `~/.openclaw/workspace`) di-mount ke `/home/node/.openclaw/workspace`
- `OPENCLAW_PROFILE_FILE=...` (default: `~/.profile`) di-mount ke `/home/node/.profile` dan di-source sebelum menjalankan pengujian
- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (default: `~/.cache/openclaw/docker-cli-tools`) di-mount ke `/home/node/.npm-global` untuk instalasi CLI yang di-cache di dalam Docker
- Direktori/file auth CLI eksternal di bawah `$HOME` di-mount sebagai read-only di bawah `/host-auth...`, lalu disalin ke `/home/node/...` sebelum pengujian dimulai
- `OPENCLAW_PROFILE_FILE=...` (default: `~/.profile`) di-mount ke `/home/node/.profile` dan dimuat sebelum menjalankan pengujian
- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (default: `~/.cache/openclaw/docker-cli-tools`) di-mount ke `/home/node/.npm-global` untuk instalasi CLI cache di dalam Docker
- Direktori/file autentikasi CLI eksternal di bawah `$HOME` di-mount sebagai read-only di bawah `/host-auth...`, lalu disalin ke `/home/node/...` sebelum pengujian dimulai
- Direktori default: `.minimax`
- File default: `~/.codex/auth.json`, `~/.codex/config.toml`, `.claude.json`, `~/.claude/.credentials.json`, `~/.claude/settings.json`, `~/.claude/settings.local.json`
- Eksekusi provider yang dipersempit hanya me-mount direktori/file yang diperlukan yang diinferensikan dari `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS`
- Run provider yang dipersempit hanya me-mount direktori/file yang diperlukan yang diinferensikan dari `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS`
- Override manual dengan `OPENCLAW_DOCKER_AUTH_DIRS=all`, `OPENCLAW_DOCKER_AUTH_DIRS=none`, atau daftar dipisahkan koma seperti `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex`
- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` untuk mempersempit eksekusi
- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` untuk mempersempit run
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` untuk memfilter provider di dalam container
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk memastikan kredensial berasal dari profile store (bukan env)
- `OPENCLAW_OPENWEBUI_MODEL=...` untuk memilih model yang diekspos gateway untuk smoke Open WebUI
- `OPENCLAW_OPENWEBUI_PROMPT=...` untuk mengganti prompt pemeriksaan nonce yang digunakan oleh smoke Open WebUI
- `OPENWEBUI_IMAGE=...` untuk mengganti tag image Open WebUI yang dipatok
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` untuk memastikan kredensial berasal dari penyimpanan profil (bukan env)
- `OPENCLAW_OPENWEBUI_MODEL=...` untuk memilih model yang diekspos oleh gateway untuk smoke Open WebUI
- `OPENCLAW_OPENWEBUI_PROMPT=...` untuk mengoverride prompt pemeriksaan nonce yang digunakan oleh smoke Open WebUI
- `OPENWEBUI_IMAGE=...` untuk mengoverride tag image Open WebUI yang dipin
## Pemeriksaan dokumentasi
## Pemeriksaan kewarasan docs
Jalankan pemeriksaan dokumen setelah mengedit dokumen: `pnpm check:docs`.
Jalankan validasi anchor Mintlify penuh saat Anda juga memerlukan pemeriksaan heading di dalam halaman: `pnpm docs:check-links:anchors`.
Jalankan pemeriksaan docs setelah mengedit docs: `pnpm check:docs`.
Jalankan validasi anchor Mintlify penuh saat Anda juga memerlukan pemeriksaan heading dalam halaman: `pnpm docs:check-links:anchors`.
## Regresi offline (aman untuk CI)
Ini adalah regresi “pipeline nyata” tanpa provider nyata:
- Tool calling gateway (mock OpenAI, gateway + loop agent nyata): `src/gateway/gateway.test.ts` (kasus: "runs a mock OpenAI tool call end-to-end via gateway agent loop")
- Tool calling gateway (mock OpenAI, gateway nyata + loop agen): `src/gateway/gateway.test.ts` (kasus: "runs a mock OpenAI tool call end-to-end via gateway agent loop")
- Wizard gateway (WS `wizard.start`/`wizard.next`, menulis config + auth dipaksakan): `src/gateway/gateway.test.ts` (kasus: "runs wizard over ws and writes auth token config")
## Evals keandalan agent (Skills)
## Eval reliabilitas agen (Skills)
Kami sudah memiliki beberapa pengujian aman untuk CI yang berperilaku seperti “evals keandalan agent”:
Kami sudah memiliki beberapa pengujian aman-CI yang berperilaku seperti “eval reliabilitas agen”:
- Mock tool-calling melalui gateway + loop agent nyata (`src/gateway/gateway.test.ts`).
- Alur wizard end-to-end yang memvalidasi wiring session dan efek config (`src/gateway/gateway.test.ts`).
- Mock tool-calling melalui gateway nyata + loop agen (`src/gateway/gateway.test.ts`).
- Alur wizard end-to-end yang memvalidasi wiring sesi dan efek config (`src/gateway/gateway.test.ts`).
Yang masih kurang untuk Skills (lihat [Skills](/id/tools/skills)):
- **Pengambilan keputusan:** saat Skills dicantumkan dalam prompt, apakah agent memilih skill yang tepat (atau menghindari yang tidak relevan)?
- **Kepatuhan:** apakah agent membaca `SKILL.md` sebelum digunakan dan mengikuti langkah/argumen yang diwajibkan?
- **Kontrak alur kerja:** skenario multi-giliran yang menegaskan urutan tool, carryover riwayat session, dan batas sandbox.
- **Pengambilan keputusan:** saat Skills dicantumkan dalam prompt, apakah agen memilih skill yang tepat (atau menghindari yang tidak relevan)?
- **Kepatuhan:** apakah agen membaca `SKILL.md` sebelum digunakan dan mengikuti langkah/arg yang diwajibkan?
- **Kontrak alur kerja:** skenario multi-giliran yang memverifikasi urutan tool, pembawaan riwayat sesi, dan batas sandbox.
Evals di masa mendatang sebaiknya tetap deterministik terlebih dahulu:
Eval di masa mendatang sebaiknya tetap deterministik terlebih dahulu:
- Runner skenario menggunakan provider mock untuk menegaskan pemanggilan tool + urutan, pembacaan file skill, dan wiring session.
- Suite kecil skenario yang berfokus pada skill (gunakan vs hindari, gating, prompt injection).
- Evals live opsional (opt-in, dibatasi env) hanya setelah suite aman untuk CI tersedia.
- Runner skenario yang menggunakan mock provider untuk memverifikasi pemanggilan tool + urutannya, pembacaan file skill, dan wiring sesi.
- Suite kecil skenario yang berfokus pada skill (gunakan vs hindari, gating, injeksi prompt).
- Eval live opsional (opt-in, dibatasi env) hanya setelah suite aman-CI tersedia.
## Contract tests (bentuk plugin dan channel)
## Pengujian kontrak (bentuk plugin dan channel)
Contract tests memverifikasi bahwa setiap plugin dan channel yang terdaftar mematuhi
kontrak antarmukanya. Contract tests mengiterasi semua plugin yang ditemukan dan menjalankan
serangkaian asersi bentuk dan perilaku. Lane unit default `pnpm test` sengaja
melewati file seam bersama dan smoke ini; jalankan perintah contract secara eksplisit
saat Anda menyentuh surface channel atau provider bersama.
Pengujian kontrak memverifikasi bahwa setiap plugin dan channel yang terdaftar sesuai dengan
kontrak interface-nya. Pengujian ini mengiterasi semua plugin yang ditemukan dan menjalankan rangkaian
verifikasi bentuk dan perilaku. Lane unit default `pnpm test` sengaja
melewati file seam bersama dan smoke ini; jalankan perintah kontrak secara eksplisit
saat Anda menyentuh permukaan channel atau provider bersama.
### Perintah
- Semua contract: `pnpm test:contracts`
- Hanya contract channel: `pnpm test:contracts:channels`
- Hanya contract provider: `pnpm test:contracts:plugins`
- Semua kontrak: `pnpm test:contracts`
- Hanya kontrak channel: `pnpm test:contracts:channels`
- Hanya kontrak provider: `pnpm test:contracts:plugins`
### Contract channel
### Kontrak channel
Terletak di `src/channels/plugins/contracts/*.contract.test.ts`:
- **plugin** - Bentuk plugin dasar (id, nama, kapabilitas)
- **setup** - Kontrak wizard setup
- **session-binding** - Perilaku pengikatan session
- **session-binding** - Perilaku pengikatan sesi
- **outbound-payload** - Struktur payload pesan
- **inbound** - Penanganan pesan masuk
- **actions** - Handler aksi channel
@ -718,43 +740,43 @@ Terletak di `src/channels/plugins/contracts/*.contract.test.ts`:
- **directory** - API direktori/roster
- **group-policy** - Penegakan kebijakan grup
### Contract status provider
### Kontrak status provider
Terletak di `src/plugins/contracts/*.contract.test.ts`.
- **status** - Probe status channel
- **registry** - Bentuk registry plugin
### Contract provider
### Kontrak provider
Terletak di `src/plugins/contracts/*.contract.test.ts`:
- **auth** - Kontrak alur auth
- **auth-choice** - Pilihan/seleksi auth
- **auth** - Kontrak alur autentikasi
- **auth-choice** - Pilihan/seleksi autentikasi
- **catalog** - API katalog model
- **discovery** - Penemuan plugin
- **loader** - Pemuatan plugin
- **runtime** - Runtime provider
- **shape** - Bentuk/antarmuka plugin
- **shape** - Bentuk/interface plugin
- **wizard** - Wizard setup
### Kapan menjalankannya
### Kapan dijalankan
- Setelah mengubah ekspor atau subpath plugin-sdk
- Setelah menambahkan atau memodifikasi channel atau plugin provider
- Setelah merefaktor registrasi atau penemuan plugin
- Setelah mengubah export atau subpath plugin-sdk
- Setelah menambahkan atau memodifikasi plugin channel atau provider
- Setelah melakukan refaktor registrasi atau penemuan plugin
Contract tests berjalan di CI dan tidak memerlukan API key nyata.
Pengujian kontrak berjalan di CI dan tidak memerlukan API key nyata.
## Menambahkan regresi (panduan)
Saat Anda memperbaiki masalah provider/model yang ditemukan secara live:
Saat Anda memperbaiki masalah provider/model yang ditemukan dalam live:
- Tambahkan regresi yang aman untuk CI jika memungkinkan (mock/stub provider, atau tangkap transformasi bentuk permintaan yang tepat)
- Jika secara inheren hanya bisa live (rate limit, kebijakan auth), pertahankan live test tetap sempit dan opt-in melalui env var
- Sebaiknya targetkan lapisan terkecil yang menangkap bug:
- bug konversi/replay permintaan provider → direct models test
- bug pipeline gateway session/history/tool → gateway live smoke atau pengujian mock gateway yang aman untuk CI
- Tambahkan regresi aman-CI jika memungkinkan (mock/stub provider, atau tangkap transformasi bentuk permintaan yang tepat)
- Jika sifatnya memang hanya live (rate limit, kebijakan autentikasi), buat pengujian live tetap sempit dan opt-in melalui env var
- Utamakan menargetkan lapisan terkecil yang menangkap bug:
- bug konversi/replay permintaan provider → pengujian model langsung
- bug pipeline sesi/riwayat/tool gateway → smoke live gateway atau pengujian mock gateway yang aman-CI
- Guardrail traversal SecretRef:
- `src/secrets/exec-secret-ref-id-parity.test.ts` menurunkan satu target sampel per kelas SecretRef dari metadata registry (`listSecretTargetRegistryEntries()`), lalu menegaskan id exec traversal-segment ditolak.
- Jika Anda menambahkan keluarga target SecretRef `includeInPlan` baru di `src/secrets/target-registry-data.ts`, perbarui `classifyTargetClass` dalam pengujian itu. Pengujian ini sengaja gagal pada id target yang tidak terklasifikasi sehingga kelas baru tidak bisa dilewati secara diam-diam.
- `src/secrets/exec-secret-ref-id-parity.test.ts` menurunkan satu target contoh per kelas SecretRef dari metadata registry (`listSecretTargetRegistryEntries()`), lalu memverifikasi id exec segmen traversal ditolak.
- Jika Anda menambahkan keluarga target SecretRef `includeInPlan` baru di `src/secrets/target-registry-data.ts`, perbarui `classifyTargetClass` dalam pengujian tersebut. Pengujian ini sengaja gagal pada id target yang tidak terklasifikasi agar kelas baru tidak dapat dilewati secara diam-diam.

View File

@ -1,85 +1,91 @@
---
read_when:
- Anda ingin mengonfigurasi provider pencarian memory atau model embedding
- Anda ingin mengonfigurasi penyedia pencarian memori atau model embedding
- Anda ingin menyiapkan backend QMD
- Anda ingin menyetel pencarian hybrid, MMR, atau temporal decay
- Anda ingin mengaktifkan pengindeksan memory multimodal
summary: Semua pengaturan konfigurasi untuk pencarian memory, provider embedding, QMD, pencarian hybrid, dan pengindeksan multimodal
title: Referensi konfigurasi memory
- Anda ingin menyetel pencarian hibrida, MMR, atau peluruhan temporal
- Anda ingin mengaktifkan pengindeksan memori multimodal
summary: Semua opsi konfigurasi untuk pencarian memori, penyedia embedding, QMD, pencarian hibrida, dan pengindeksan multimodal
title: Referensi konfigurasi Memori
x-i18n:
generated_at: "2026-04-06T03:11:36Z"
generated_at: "2026-04-10T09:13:33Z"
model: gpt-5.4
provider: openai
source_hash: 0de0b85125443584f4e575cf673ca8d9bd12ecd849d73c537f4a17545afa93fd
source_hash: 5f9076bdfad95b87bd70625821bf401326f8eaeb53842b70823881419dbe43cb
source_path: reference/memory-config.md
workflow: 15
---
# Referensi konfigurasi memory
# Referensi konfigurasi Memori
Halaman ini mencantumkan setiap pengaturan konfigurasi untuk pencarian memory OpenClaw. Untuk
ikhtisar konseptual, lihat:
Halaman ini mencantumkan setiap opsi konfigurasi untuk pencarian memori OpenClaw. Untuk gambaran konseptual, lihat:
- [Ikhtisar Memory](/id/concepts/memory) -- cara kerja memory
- [Builtin Engine](/id/concepts/memory-builtin) -- backend SQLite default
- [QMD Engine](/id/concepts/memory-qmd) -- sidecar local-first
- [Memory Search](/id/concepts/memory-search) -- pipeline pencarian dan penyetelan
- [Ikhtisar Memori](/id/concepts/memory) -- cara kerja memori
- [Mesin Bawaan](/id/concepts/memory-builtin) -- backend SQLite bawaan
- [Mesin QMD](/id/concepts/memory-qmd) -- sidecar yang mengutamakan lokal
- [Pencarian Memori](/id/concepts/memory-search) -- alur pencarian dan penyetelan
- [Memori Aktif](/id/concepts/active-memory) -- mengaktifkan sub-agen memori untuk sesi interaktif
Semua pengaturan pencarian memory berada di bawah `agents.defaults.memorySearch` di
`openclaw.json` kecuali jika disebutkan lain.
Semua pengaturan pencarian memori berada di bawah `agents.defaults.memorySearch` dalam `openclaw.json` kecuali dinyatakan lain.
Jika Anda mencari toggle fitur **memori aktif** dan konfigurasi sub-agen, itu berada di bawah `plugins.entries.active-memory`, bukan `memorySearch`.
Memori aktif menggunakan model dua gerbang:
1. plugin harus diaktifkan dan menargetkan id agen saat ini
2. permintaan harus berupa sesi obrolan persisten interaktif yang memenuhi syarat
Lihat [Memori Aktif](/id/concepts/active-memory) untuk model aktivasi, konfigurasi yang dimiliki plugin, persistensi transkrip, dan pola rollout yang aman.
---
## Pemilihan provider
## Pemilihan penyedia
| Key | Type | Default | Deskripsi |
| ---------- | --------- | ---------------- | --------------------------------------------------------------------------------------------- |
| `provider` | `string` | terdeteksi otomatis | ID adapter embedding: `openai`, `gemini`, `voyage`, `mistral`, `bedrock`, `ollama`, `local` |
| `model` | `string` | default provider | Nama model embedding |
| `fallback` | `string` | `"none"` | ID adapter fallback saat yang utama gagal |
| `enabled` | `boolean` | `true` | Mengaktifkan atau menonaktifkan pencarian memory |
| Kunci | Tipe | Default | Deskripsi |
| ---------- | --------- | ---------------- | ------------------------------------------------------------------------------------------- |
| `provider` | `string` | terdeteksi otomatis | ID adaptor embedding: `openai`, `gemini`, `voyage`, `mistral`, `bedrock`, `ollama`, `local` |
| `model` | `string` | default penyedia | Nama model embedding |
| `fallback` | `string` | `"none"` | ID adaptor fallback saat adaptor utama gagal |
| `enabled` | `boolean` | `true` | Mengaktifkan atau menonaktifkan pencarian memori |
### Urutan deteksi otomatis
Saat `provider` tidak diatur, OpenClaw memilih yang pertama tersedia:
Ketika `provider` tidak ditetapkan, OpenClaw memilih yang pertama tersedia:
1. `local` -- jika `memorySearch.local.modelPath` dikonfigurasi dan file ada.
2. `openai` -- jika key OpenAI dapat diresolusikan.
3. `gemini` -- jika key Gemini dapat diresolusikan.
4. `voyage` -- jika key Voyage dapat diresolusikan.
5. `mistral` -- jika key Mistral dapat diresolusikan.
6. `bedrock` -- jika rantai kredensial AWS SDK dapat diresolusikan (instance role, access key, profile, SSO, web identity, atau shared config).
2. `openai` -- jika kunci OpenAI dapat diurai.
3. `gemini` -- jika kunci Gemini dapat diurai.
4. `voyage` -- jika kunci Voyage dapat diurai.
5. `mistral` -- jika kunci Mistral dapat diurai.
6. `bedrock` -- jika rantai kredensial AWS SDK terurai (instance role, access key, profile, SSO, web identity, atau shared config).
`ollama` didukung tetapi tidak terdeteksi otomatis (atur secara eksplisit).
`ollama` didukung tetapi tidak dideteksi otomatis (tetapkan secara eksplisit).
### Resolusi API key
### Resolusi kunci API
Embedding remote memerlukan API key. Bedrock menggunakan rantai kredensial default AWS SDK
sebagai gantinya (instance role, SSO, access key).
Embedding jarak jauh memerlukan kunci API. Bedrock menggunakan rantai kredensial default AWS SDK sebagai gantinya (instance role, SSO, access key).
| Provider | Env var | Key config |
| -------- | ------------------------------ | --------------------------------- |
| OpenAI | `OPENAI_API_KEY` | `models.providers.openai.apiKey` |
| Gemini | `GEMINI_API_KEY` | `models.providers.google.apiKey` |
| Voyage | `VOYAGE_API_KEY` | `models.providers.voyage.apiKey` |
| Mistral | `MISTRAL_API_KEY` | `models.providers.mistral.apiKey` |
| Bedrock | rantai kredensial AWS | Tidak memerlukan API key |
| Ollama | `OLLAMA_API_KEY` (placeholder) | -- |
| Penyedia | Variabel env | Kunci konfigurasi |
| -------- | ----------------------------- | -------------------------------- |
| OpenAI | `OPENAI_API_KEY` | `models.providers.openai.apiKey` |
| Gemini | `GEMINI_API_KEY` | `models.providers.google.apiKey` |
| Voyage | `VOYAGE_API_KEY` | `models.providers.voyage.apiKey` |
| Mistral | `MISTRAL_API_KEY` | `models.providers.mistral.apiKey` |
| Bedrock | rantai kredensial AWS | Tidak memerlukan kunci API |
| Ollama | `OLLAMA_API_KEY` (placeholder) | -- |
OAuth Codex hanya mencakup chat/completions dan tidak memenuhi permintaan
embedding.
Codex OAuth hanya mencakup chat/completions dan tidak memenuhi permintaan embedding.
---
## Konfigurasi endpoint remote
## Konfigurasi endpoint jarak jauh
Untuk endpoint kustom yang kompatibel dengan OpenAI atau meng-override default provider:
Untuk endpoint kustom yang kompatibel dengan OpenAI atau mengganti default penyedia:
| Key | Type | Deskripsi |
| ---------------- | -------- | -------------------------------------------------- |
| `remote.baseUrl` | `string` | URL dasar API kustom |
| `remote.apiKey` | `string` | Override API key |
| `remote.headers` | `object` | Header HTTP tambahan (digabungkan dengan default provider) |
| Kunci | Tipe | Deskripsi |
| ---------------- | -------- | ----------------------------------------------- |
| `remote.baseUrl` | `string` | URL basis API kustom |
| `remote.apiKey` | `string` | Mengganti kunci API |
| `remote.headers` | `object` | Header HTTP tambahan (digabung dengan default penyedia) |
```json5
{
@ -102,22 +108,22 @@ Untuk endpoint kustom yang kompatibel dengan OpenAI atau meng-override default p
## Konfigurasi khusus Gemini
| Key | Type | Default | Deskripsi |
| Kunci | Tipe | Default | Deskripsi |
| ---------------------- | -------- | ---------------------- | ----------------------------------------- |
| `model` | `string` | `gemini-embedding-001` | Juga mendukung `gemini-embedding-2-preview` |
| `outputDimensionality` | `number` | `3072` | Untuk Embedding 2: 768, 1536, atau 3072 |
<Warning>
Mengubah model atau `outputDimensionality` memicu reindex penuh otomatis.
Mengubah model atau `outputDimensionality` memicu pengindeksan ulang penuh secara otomatis.
</Warning>
---
## Konfigurasi embedding Bedrock
Bedrock menggunakan rantai kredensial default AWS SDK -- tidak memerlukan API key.
Jika OpenClaw berjalan di EC2 dengan instance role yang mengaktifkan Bedrock, cukup atur
provider dan model:
Bedrock menggunakan rantai kredensial default AWS SDK -- tidak memerlukan kunci API.
Jika OpenClaw berjalan di EC2 dengan instance role yang mendukung Bedrock, cukup tetapkan
penyedia dan model:
```json5
{
@ -132,43 +138,41 @@ provider dan model:
}
```
| Key | Type | Default | Deskripsi |
| ---------------------- | -------- | ------------------------------ | ------------------------------ |
| Kunci | Tipe | Default | Deskripsi |
| ---------------------- | -------- | ------------------------------ | ---------------------------- |
| `model` | `string` | `amazon.titan-embed-text-v2:0` | ID model embedding Bedrock apa pun |
| `outputDimensionality` | `number` | default model | Untuk Titan V2: 256, 512, atau 1024 |
### Model yang didukung
Model berikut didukung (dengan deteksi family dan default
dimension):
Model berikut didukung (dengan deteksi keluarga dan default dimensi):
| Model ID | Provider | Dims Default | Dims yang Dapat Dikonfigurasi |
| ------------------------------------------ | ---------- | ------------ | ----------------------------- |
| `amazon.titan-embed-text-v2:0` | Amazon | 1024 | 256, 512, 1024 |
| `amazon.titan-embed-text-v1` | Amazon | 1536 | -- |
| `amazon.titan-embed-g1-text-02` | Amazon | 1536 | -- |
| `amazon.titan-embed-image-v1` | Amazon | 1024 | -- |
| `amazon.nova-2-multimodal-embeddings-v1:0` | Amazon | 1024 | 256, 384, 1024, 3072 |
| `cohere.embed-english-v3` | Cohere | 1024 | -- |
| `cohere.embed-multilingual-v3` | Cohere | 1024 | -- |
| `cohere.embed-v4:0` | Cohere | 1536 | 256-1536 |
| `twelvelabs.marengo-embed-3-0-v1:0` | TwelveLabs | 512 | -- |
| `twelvelabs.marengo-embed-2-7-v1:0` | TwelveLabs | 1024 | -- |
| ID Model | Penyedia | Default Dim | Dim yang dapat dikonfigurasi |
| ------------------------------------------ | ---------- | ----------- | ---------------------------- |
| `amazon.titan-embed-text-v2:0` | Amazon | 1024 | 256, 512, 1024 |
| `amazon.titan-embed-text-v1` | Amazon | 1536 | -- |
| `amazon.titan-embed-g1-text-02` | Amazon | 1536 | -- |
| `amazon.titan-embed-image-v1` | Amazon | 1024 | -- |
| `amazon.nova-2-multimodal-embeddings-v1:0` | Amazon | 1024 | 256, 384, 1024, 3072 |
| `cohere.embed-english-v3` | Cohere | 1024 | -- |
| `cohere.embed-multilingual-v3` | Cohere | 1024 | -- |
| `cohere.embed-v4:0` | Cohere | 1536 | 256-1536 |
| `twelvelabs.marengo-embed-3-0-v1:0` | TwelveLabs | 512 | -- |
| `twelvelabs.marengo-embed-2-7-v1:0` | TwelveLabs | 1024 | -- |
Varian dengan sufiks throughput (misalnya, `amazon.titan-embed-text-v1:2:8k`) mewarisi
konfigurasi model dasar.
Varian dengan sufiks throughput (misalnya, `amazon.titan-embed-text-v1:2:8k`) mewarisi konfigurasi model dasar.
### Autentikasi
Auth Bedrock menggunakan urutan resolusi kredensial AWS SDK standar:
Autentikasi Bedrock menggunakan urutan resolusi kredensial AWS SDK standar:
1. Environment variable (`AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`)
1. Variabel lingkungan (`AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`)
2. Cache token SSO
3. Kredensial token web identity
4. File shared credentials dan config
4. File kredensial dan konfigurasi bersama
5. Kredensial metadata ECS atau EC2
Region diresolusikan dari `AWS_REGION`, `AWS_DEFAULT_REGION`, `baseUrl` provider
Region diurai dari `AWS_REGION`, `AWS_DEFAULT_REGION`, `baseUrl` penyedia
`amazon-bedrock`, atau default ke `us-east-1`.
### Izin IAM
@ -183,7 +187,7 @@ Role atau pengguna IAM memerlukan:
}
```
Untuk hak istimewa minimum, cakup `InvokeModel` ke model tertentu:
Untuk hak akses minimum, batasi `InvokeModel` ke model tertentu:
```
arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0
@ -193,42 +197,42 @@ arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0
## Konfigurasi embedding lokal
| Key | Type | Default | Deskripsi |
| --------------------- | -------- | ---------------------- | ---------------------------- |
| `local.modelPath` | `string` | terunduh otomatis | Path ke file model GGUF |
| Kunci | Tipe | Default | Deskripsi |
| --------------------- | -------- | ---------------------- | ------------------------------ |
| `local.modelPath` | `string` | terunduh otomatis | Jalur ke file model GGUF |
| `local.modelCacheDir` | `string` | default node-llama-cpp | Direktori cache untuk model yang diunduh |
Model default: `embeddinggemma-300m-qat-Q8_0.gguf` (~0,6 GB, terunduh otomatis).
Model default: `embeddinggemma-300m-qat-Q8_0.gguf` (~0.6 GB, diunduh otomatis).
Memerlukan build native: `pnpm approve-builds` lalu `pnpm rebuild node-llama-cpp`.
---
## Konfigurasi pencarian hybrid
## Konfigurasi pencarian hibrida
Semua di bawah `memorySearch.query.hybrid`:
Semua berada di bawah `memorySearch.query.hybrid`:
| Key | Type | Default | Deskripsi |
| --------------------- | --------- | ------- | ---------------------------------- |
| `enabled` | `boolean` | `true` | Aktifkan pencarian hybrid BM25 + vector |
| `vectorWeight` | `number` | `0.7` | Bobot untuk skor vector (0-1) |
| `textWeight` | `number` | `0.3` | Bobot untuk skor BM25 (0-1) |
| `candidateMultiplier` | `number` | `4` | Pengali ukuran kumpulan kandidat |
| Kunci | Tipe | Default | Deskripsi |
| --------------------- | --------- | ------- | ----------------------------------- |
| `enabled` | `boolean` | `true` | Aktifkan pencarian hibrida BM25 + vektor |
| `vectorWeight` | `number` | `0.7` | Bobot untuk skor vektor (0-1) |
| `textWeight` | `number` | `0.3` | Bobot untuk skor BM25 (0-1) |
| `candidateMultiplier` | `number` | `4` | Pengali ukuran kumpulan kandidat |
### MMR (keragaman)
| Key | Type | Default | Deskripsi |
| ------------- | --------- | ------- | --------------------------------------- |
| `mmr.enabled` | `boolean` | `false` | Aktifkan re-ranking MMR |
| Kunci | Tipe | Default | Deskripsi |
| ------------- | --------- | ------- | ------------------------------------- |
| `mmr.enabled` | `boolean` | `false` | Aktifkan pemeringkatan ulang MMR |
| `mmr.lambda` | `number` | `0.7` | 0 = keragaman maksimum, 1 = relevansi maksimum |
### Temporal decay (kekinian)
### Peluruhan temporal (keterkinian)
| Key | Type | Default | Deskripsi |
| Kunci | Tipe | Default | Deskripsi |
| ---------------------------- | --------- | ------- | ---------------------------- |
| `temporalDecay.enabled` | `boolean` | `false` | Aktifkan peningkatan kekinian |
| `temporalDecay.enabled` | `boolean` | `false` | Aktifkan dorongan keterkinian |
| `temporalDecay.halfLifeDays` | `number` | `30` | Skor menjadi setengah setiap N hari |
File evergreen (`MEMORY.md`, file tanpa tanggal di `memory/`) tidak pernah dikenai decay.
File permanen (`MEMORY.md`, file non-tanggal di `memory/`) tidak pernah dikenai peluruhan.
### Contoh lengkap
@ -253,9 +257,9 @@ File evergreen (`MEMORY.md`, file tanpa tanggal di `memory/`) tidak pernah diken
---
## Path memory tambahan
## Jalur memori tambahan
| Key | Type | Deskripsi |
| Kunci | Tipe | Deskripsi |
| ------------ | ---------- | --------------------------------------- |
| `extraPaths` | `string[]` | Direktori atau file tambahan untuk diindeks |
@ -271,33 +275,32 @@ File evergreen (`MEMORY.md`, file tanpa tanggal di `memory/`) tidak pernah diken
}
```
Path dapat berupa absolut atau relatif terhadap workspace. Direktori dipindai
Jalur dapat berupa absolut atau relatif terhadap workspace. Direktori dipindai
secara rekursif untuk file `.md`. Penanganan symlink bergantung pada backend aktif:
builtin engine mengabaikan symlink, sedangkan QMD mengikuti perilaku scanner QMD
mesin bawaan mengabaikan symlink, sedangkan QMD mengikuti perilaku pemindai QMD
yang mendasarinya.
Untuk pencarian transkrip lintas agen dengan cakupan agen, gunakan
Untuk pencarian transkrip lintas agen yang dicakup per agen, gunakan
`agents.list[].memorySearch.qmd.extraCollections` alih-alih `memory.qmd.paths`.
Koleksi tambahan tersebut mengikuti bentuk `{ path, name, pattern? }` yang sama, tetapi
digabungkan per agen dan dapat mempertahankan nama bersama yang eksplisit saat path
digabung per agen dan dapat mempertahankan nama bersama yang eksplisit ketika jalurnya
mengarah ke luar workspace saat ini.
Jika path terselesaikan yang sama muncul di `memory.qmd.paths` dan
`memorySearch.qmd.extraCollections`, QMD mempertahankan entri pertama dan melewati
duplikatnya.
Jika jalur hasil resolusi yang sama muncul di `memory.qmd.paths` dan
`memorySearch.qmd.extraCollections`, QMD mempertahankan entri pertama dan melewati duplikat.
---
## Memory multimodal (Gemini)
## Memori multimodal (Gemini)
Indeks gambar dan audio bersama Markdown menggunakan Gemini Embedding 2:
| Key | Type | Default | Deskripsi |
| ------------------------- | ---------- | ---------- | ------------------------------------- |
| `multimodal.enabled` | `boolean` | `false` | Aktifkan pengindeksan multimodal |
| Kunci | Tipe | Default | Deskripsi |
| ------------------------- | ---------- | ---------- | --------------------------------------- |
| `multimodal.enabled` | `boolean` | `false` | Aktifkan pengindeksan multimodal |
| `multimodal.modalities` | `string[]` | -- | `["image"]`, `["audio"]`, atau `["all"]` |
| `multimodal.maxFileBytes` | `number` | `10000000` | Ukuran file maksimum untuk pengindeksan |
Hanya berlaku untuk file di `extraPaths`. Root memory default tetap hanya Markdown.
Hanya berlaku untuk file di `extraPaths`. Root memori default tetap hanya Markdown.
Memerlukan `gemini-embedding-2-preview`. `fallback` harus `"none"`.
Format yang didukung: `.jpg`, `.jpeg`, `.png`, `.webp`, `.gif`, `.heic`, `.heif`
@ -307,117 +310,117 @@ Format yang didukung: `.jpg`, `.jpeg`, `.png`, `.webp`, `.gif`, `.heic`, `.heif`
## Cache embedding
| Key | Type | Default | Deskripsi |
| ------------------ | --------- | ------- | --------------------------------- |
| `cache.enabled` | `boolean` | `false` | Cache embedding chunk di SQLite |
| `cache.maxEntries` | `number` | `50000` | Embedding yang di-cache maksimum |
| Kunci | Tipe | Default | Deskripsi |
| ------------------ | --------- | ------- | ----------------------------- |
| `cache.enabled` | `boolean` | `false` | Cache embedding potongan di SQLite |
| `cache.maxEntries` | `number` | `50000` | Jumlah maksimum embedding yang di-cache |
Mencegah embedding ulang teks yang tidak berubah selama reindex atau pembaruan transkrip.
Mencegah embedding ulang pada teks yang tidak berubah selama pengindeksan ulang atau pembaruan transkrip.
---
## Batch indexing
## Pengindeksan batch
| Key | Type | Default | Deskripsi |
| ----------------------------- | --------- | ------- | -------------------------- |
| Kunci | Tipe | Default | Deskripsi |
| ----------------------------- | --------- | ------- | ---------------------------- |
| `remote.batch.enabled` | `boolean` | `false` | Aktifkan API embedding batch |
| `remote.batch.concurrency` | `number` | `2` | Job batch paralel |
| `remote.batch.wait` | `boolean` | `true` | Tunggu penyelesaian batch |
| `remote.batch.pollIntervalMs` | `number` | -- | Interval polling |
| `remote.batch.timeoutMinutes` | `number` | -- | Timeout batch |
| `remote.batch.concurrency` | `number` | `2` | Pekerjaan batch paralel |
| `remote.batch.wait` | `boolean` | `true` | Tunggu penyelesaian batch |
| `remote.batch.pollIntervalMs` | `number` | -- | Interval polling |
| `remote.batch.timeoutMinutes` | `number` | -- | Batas waktu batch |
Tersedia untuk `openai`, `gemini`, dan `voyage`. Batch OpenAI biasanya
paling cepat dan paling murah untuk backfill besar.
paling cepat dan paling murah untuk backfill berukuran besar.
---
## Pencarian memory sesi (eksperimental)
## Pencarian memori sesi (eksperimental)
Indeks transkrip sesi dan tampilkan melalui `memory_search`:
| Key | Type | Default | Deskripsi |
| ----------------------------- | ---------- | ------------ | --------------------------------------- |
| `experimental.sessionMemory` | `boolean` | `false` | Aktifkan pengindeksan sesi |
| Kunci | Tipe | Default | Deskripsi |
| ----------------------------- | ---------- | ------------ | -------------------------------------- |
| `experimental.sessionMemory` | `boolean` | `false` | Aktifkan pengindeksan sesi |
| `sources` | `string[]` | `["memory"]` | Tambahkan `"sessions"` untuk menyertakan transkrip |
| `sync.sessions.deltaBytes` | `number` | `100000` | Ambang byte untuk reindex |
| `sync.sessions.deltaMessages` | `number` | `50` | Ambang pesan untuk reindex |
| `sync.sessions.deltaBytes` | `number` | `100000` | Ambang byte untuk pengindeksan ulang |
| `sync.sessions.deltaMessages` | `number` | `50` | Ambang pesan untuk pengindeksan ulang |
Pengindeksan sesi bersifat opt-in dan berjalan secara asynchronous. Hasil dapat sedikit
usang. Log sesi berada di disk, jadi perlakukan akses filesystem sebagai batas
Pengindeksan sesi bersifat opt-in dan berjalan secara asinkron. Hasilnya dapat sedikit
tidak mutakhir. Log sesi berada di disk, jadi perlakukan akses filesystem sebagai batas
kepercayaan.
---
## Akselerasi vector SQLite (sqlite-vec)
## Akselerasi vektor SQLite (sqlite-vec)
| Key | Type | Default | Deskripsi |
| ---------------------------- | --------- | ------- | -------------------------------- |
| `store.vector.enabled` | `boolean` | `true` | Gunakan sqlite-vec untuk query vector |
| `store.vector.extensionPath` | `string` | bundled | Override path sqlite-vec |
| Kunci | Tipe | Default | Deskripsi |
| ---------------------------- | --------- | ------- | ---------------------------------- |
| `store.vector.enabled` | `boolean` | `true` | Gunakan sqlite-vec untuk kueri vektor |
| `store.vector.extensionPath` | `string` | bundled | Ganti jalur sqlite-vec |
Saat sqlite-vec tidak tersedia, OpenClaw otomatis fallback ke cosine
similarity dalam proses.
Ketika sqlite-vec tidak tersedia, OpenClaw secara otomatis beralih ke
similaritas kosinus dalam proses.
---
## Penyimpanan indeks
| Key | Type | Default | Deskripsi |
| --------------------- | -------- | ------------------------------------- | ------------------------------------------ |
| `store.path` | `string` | `~/.openclaw/memory/{agentId}.sqlite` | Lokasi indeks (mendukung token `{agentId}`) |
| `store.fts.tokenizer` | `string` | `unicode61` | Tokenizer FTS5 (`unicode61` atau `trigram`) |
| Kunci | Tipe | Default | Deskripsi |
| ------------------- | -------- | ------------------------------------- | ------------------------------------------- |
| `store.path` | `string` | `~/.openclaw/memory/{agentId}.sqlite` | Lokasi indeks (mendukung token `{agentId}`) |
| `store.fts.tokenizer` | `string` | `unicode61` | Tokenizer FTS5 (`unicode61` atau `trigram`) |
---
## Konfigurasi backend QMD
Atur `memory.backend = "qmd"` untuk mengaktifkan. Semua pengaturan QMD berada di bawah
Tetapkan `memory.backend = "qmd"` untuk mengaktifkan. Semua pengaturan QMD berada di bawah
`memory.qmd`:
| Key | Type | Default | Deskripsi |
| Kunci | Tipe | Default | Deskripsi |
| ------------------------ | --------- | -------- | ------------------------------------------ |
| `command` | `string` | `qmd` | Path executable QMD |
| `command` | `string` | `qmd` | Jalur executable QMD |
| `searchMode` | `string` | `search` | Perintah pencarian: `search`, `vsearch`, `query` |
| `includeDefaultMemory` | `boolean` | `true` | Indeks otomatis `MEMORY.md` + `memory/**/*.md` |
| `paths[]` | `array` | -- | Path tambahan: `{ name, path, pattern? }` |
| `paths[]` | `array` | -- | Jalur tambahan: `{ name, path, pattern? }` |
| `sessions.enabled` | `boolean` | `false` | Indeks transkrip sesi |
| `sessions.retentionDays` | `number` | -- | Retensi transkrip |
| `sessions.exportDir` | `string` | -- | Direktori ekspor |
OpenClaw mengutamakan bentuk query koleksi dan MCP QMD saat ini, tetapi tetap
menjaga rilis QMD yang lebih lama agar tetap berfungsi dengan fallback ke flag koleksi
`--mask` lama dan nama tool MCP lama saat diperlukan.
OpenClaw lebih memilih bentuk kueri koleksi QMD dan MCP saat ini, tetapi tetap
mendukung rilis QMD yang lebih lama dengan beralih ke flag koleksi `--mask` lama
dan nama tool MCP lama saat diperlukan.
Override model QMD tetap berada di sisi QMD, bukan config OpenClaw. Jika Anda perlu
meng-override model QMD secara global, atur environment variable seperti
`QMD_EMBED_MODEL`, `QMD_RERANK_MODEL`, dan `QMD_GENERATE_MODEL` di environment runtime
Override model QMD tetap berada di sisi QMD, bukan di konfigurasi OpenClaw. Jika Anda perlu
mengganti model QMD secara global, tetapkan variabel lingkungan seperti
`QMD_EMBED_MODEL`, `QMD_RERANK_MODEL`, dan `QMD_GENERATE_MODEL` di lingkungan runtime
gateway.
### Jadwal pembaruan
| Key | Type | Default | Deskripsi |
| ------------------------- | --------- | ------- | ------------------------------------ |
| `update.interval` | `string` | `5m` | Interval refresh |
| `update.debounceMs` | `number` | `15000` | Debounce perubahan file |
| `update.onBoot` | `boolean` | `true` | Refresh saat startup |
| `update.waitForBootSync` | `boolean` | `false` | Blok startup hingga refresh selesai |
| `update.embedInterval` | `string` | -- | Cadence embedding terpisah |
| `update.commandTimeoutMs` | `number` | -- | Timeout untuk perintah QMD |
| `update.updateTimeoutMs` | `number` | -- | Timeout untuk operasi pembaruan QMD |
| `update.embedTimeoutMs` | `number` | -- | Timeout untuk operasi embedding QMD |
| Kunci | Tipe | Default | Deskripsi |
| ------------------------- | --------- | ------- | -------------------------------------- |
| `update.interval` | `string` | `5m` | Interval penyegaran |
| `update.debounceMs` | `number` | `15000` | Debounce perubahan file |
| `update.onBoot` | `boolean` | `true` | Segarkan saat startup |
| `update.waitForBootSync` | `boolean` | `false` | Blokir startup sampai penyegaran selesai |
| `update.embedInterval` | `string` | -- | Cadence embedding terpisah |
| `update.commandTimeoutMs` | `number` | -- | Batas waktu untuk perintah QMD |
| `update.updateTimeoutMs` | `number` | -- | Batas waktu untuk operasi update QMD |
| `update.embedTimeoutMs` | `number` | -- | Batas waktu untuk operasi embedding QMD |
### Batas
| Key | Type | Default | Deskripsi |
| ------------------------- | -------- | ------- | ---------------------------- |
| `limits.maxResults` | `number` | `6` | Hasil pencarian maksimum |
| `limits.maxSnippetChars` | `number` | -- | Batasi panjang snippet |
| `limits.maxInjectedChars` | `number` | -- | Batasi total karakter yang disuntikkan |
| `limits.timeoutMs` | `number` | `4000` | Timeout pencarian |
| Kunci | Tipe | Default | Deskripsi |
| ------------------------- | -------- | ------- | ------------------------------ |
| `limits.maxResults` | `number` | `6` | Jumlah maksimum hasil pencarian |
| `limits.maxSnippetChars` | `number` | -- | Batasi panjang cuplikan |
| `limits.maxInjectedChars` | `number` | -- | Batasi total karakter yang disisipkan |
| `limits.timeoutMs` | `number` | `4000` | Batas waktu pencarian |
### Cakupan
Mengontrol sesi mana yang dapat menerima hasil pencarian QMD. Skema sama dengan
Mengontrol sesi mana yang dapat menerima hasil pencarian QMD. Skemanya sama seperti
[`session.sendPolicy`](/id/gateway/configuration-reference#session):
```json5
@ -433,18 +436,18 @@ Mengontrol sesi mana yang dapat menerima hasil pencarian QMD. Skema sama dengan
}
```
Default-nya hanya DM. `match.keyPrefix` mencocokkan session key yang dinormalisasi;
`match.rawKeyPrefix` mencocokkan key mentah termasuk `agent:<id>:`.
Default-nya hanya DM. `match.keyPrefix` cocok dengan kunci sesi yang dinormalisasi;
`match.rawKeyPrefix` cocok dengan kunci mentah termasuk `agent:<id>:`.
### Sitasi
`memory.citations` berlaku untuk semua backend:
| Value | Perilaku |
| ---------------- | ----------------------------------------------------- |
| `auto` (default) | Sertakan footer `Source: <path#line>` dalam snippet |
| `on` | Selalu sertakan footer |
| `off` | Hilangkan footer (path tetap diteruskan ke agen secara internal) |
| Nilai | Perilaku |
| ---------------- | --------------------------------------------------- |
| `auto` (default) | Sertakan footer `Source: <path#line>` dalam cuplikan |
| `on` | Selalu sertakan footer |
| `off` | Hilangkan footer (jalur tetap diteruskan ke agen secara internal) |
### Contoh QMD lengkap
@ -477,13 +480,13 @@ bukan di bawah `agents.defaults.memorySearch`.
Dreaming berjalan sebagai satu sweep terjadwal dan menggunakan fase internal light/deep/REM sebagai
detail implementasi.
Untuk perilaku konseptual dan perintah slash, lihat [Dreaming](/concepts/dreaming).
Untuk perilaku konseptual dan slash command, lihat [Dreaming](/id/concepts/dreaming).
### Pengaturan pengguna
| Key | Type | Default | Deskripsi |
| ----------- | --------- | ----------- | ------------------------------------------------ |
| `enabled` | `boolean` | `false` | Mengaktifkan atau menonaktifkan dreaming sepenuhnya |
| Kunci | Tipe | Default | Deskripsi |
| ----------- | --------- | ----------- | ---------------------------------------------- |
| `enabled` | `boolean` | `false` | Aktifkan atau nonaktifkan dreaming sepenuhnya |
| `frequency` | `string` | `0 3 * * *` | Cadence cron opsional untuk sweep dreaming penuh |
### Contoh
@ -507,6 +510,6 @@ Untuk perilaku konseptual dan perintah slash, lihat [Dreaming](/concepts/dreamin
Catatan:
- Dreaming menulis machine state ke `memory/.dreams/`.
- Dreaming menulis status mesin ke `memory/.dreams/`.
- Dreaming menulis output naratif yang dapat dibaca manusia ke `DREAMS.md` (atau `dreams.md` yang sudah ada).
- Kebijakan dan ambang fase light/deep/REM adalah perilaku internal, bukan config yang ditujukan untuk pengguna.
- Kebijakan dan ambang fase light/deep/REM adalah perilaku internal, bukan konfigurasi yang menghadap pengguna.

View File

@ -2,40 +2,38 @@
read_when:
- Menambahkan otomatisasi browser yang dikendalikan agen
- Men-debug mengapa openclaw mengganggu Chrome Anda sendiri
- Mengimplementasikan pengaturan + siklus hidup browser di aplikasi macOS
summary: Layanan kontrol browser terintegrasi + perintah tindakan
- Menerapkan pengaturan + siklus hidup browser di app macOS
summary: Layanan kontrol browser terintegrasi + perintah aksi
title: Browser (dikelola OpenClaw)
x-i18n:
generated_at: "2026-04-05T14:08:47Z"
generated_at: "2026-04-10T09:13:41Z"
model: gpt-5.4
provider: openai
source_hash: a41162efd397ea918469e16aa67e554bcbb517b3112df1d3e7927539b6a0926a
source_hash: cd3424f62178bbf25923b8bc8e4d9f70e330f35428d01fe153574e5fa45d7604
source_path: tools/browser.md
workflow: 15
---
# Browser (dikelola openclaw)
OpenClaw dapat menjalankan **profil Chrome/Brave/Edge/Chromium khusus** yang dikendalikan agen.
Profil ini terisolasi dari browser pribadi Anda dan dikelola melalui layanan kontrol
lokal kecil di dalam Gateway (hanya loopback).
OpenClaw dapat menjalankan **profil Chrome/Brave/Edge/Chromium khusus** yang dikendalikan oleh agen.
Profil ini terisolasi dari browser pribadi Anda dan dikelola melalui layanan kontrol lokal kecil di dalam Gateway (hanya loopback).
Tampilan pemula:
- Anggap ini sebagai **browser terpisah, khusus agen**.
- Anggap ini sebagai **browser terpisah yang hanya untuk agen**.
- Profil `openclaw` **tidak** menyentuh profil browser pribadi Anda.
- Agen dapat **membuka tab, membaca halaman, mengeklik, dan mengetik** di jalur yang aman.
- Profil bawaan `user` terhubung ke sesi Chrome asli Anda yang sudah login melalui Chrome MCP.
- Agen dapat **membuka tab, membaca halaman, mengklik, dan mengetik** di lane yang aman.
- Profil bawaan `user` terhubung ke sesi Chrome asli Anda yang sedang login melalui Chrome MCP.
## Yang Anda dapatkan
- Profil browser terpisah bernama **openclaw** (aksen oranye secara default).
- Kontrol tab deterministik (daftar/buka/fokus/tutup).
- Tindakan agen (klik/ketik/seret/pilih), snapshot, tangkapan layar, PDF.
- Kontrol tab yang deterministik (list/open/focus/close).
- Aksi agen (click/type/drag/select), snapshot, screenshot, PDF.
- Dukungan multi-profil opsional (`openclaw`, `work`, `remote`, ...).
Browser ini **bukan** browser harian Anda. Ini adalah permukaan yang aman dan terisolasi untuk
otomatisasi dan verifikasi agen.
Browser ini **bukan** browser harian Anda. Ini adalah permukaan yang aman dan terisolasi untuk otomatisasi dan verifikasi agen.
## Mulai cepat
@ -46,17 +44,13 @@ openclaw browser --browser-profile openclaw open https://example.com
openclaw browser --browser-profile openclaw snapshot
```
Jika Anda mendapatkan “Browser disabled”, aktifkan di config (lihat di bawah) dan mulai ulang
Gateway.
Jika Anda mendapatkan “Browser dinonaktifkan”, aktifkan di konfigurasi (lihat di bawah) lalu mulai ulang Gateway.
Jika `openclaw browser` sama sekali tidak ada, atau agen mengatakan tool browser
tidak tersedia, lompat ke [Perintah atau tool browser hilang](/tools/browser#missing-browser-command-or-tool).
Jika `openclaw browser` sama sekali tidak ada, atau agen mengatakan tool browser tidak tersedia, langsung ke [Perintah atau tool browser hilang](/id/tools/browser#missing-browser-command-or-tool).
## Kontrol plugin
Tool `browser` default sekarang adalah plugin bawaan yang dikirim dalam keadaan aktif secara
default. Artinya Anda dapat menonaktifkan atau menggantinya tanpa menghapus seluruh
sistem plugin OpenClaw:
Tool `browser` default sekarang adalah plugin bawaan yang dikirim dalam keadaan aktif secara default. Artinya, Anda dapat menonaktifkan atau menggantinya tanpa menghapus sisa sistem plugin OpenClaw:
```json5
{
@ -70,31 +64,22 @@ sistem plugin OpenClaw:
}
```
Nonaktifkan plugin bawaan sebelum memasang plugin lain yang menyediakan
nama tool `browser` yang sama. Pengalaman browser default memerlukan keduanya:
Nonaktifkan plugin bawaan sebelum memasang plugin lain yang menyediakan nama tool `browser` yang sama. Pengalaman browser default membutuhkan keduanya:
- `plugins.entries.browser.enabled` tidak dinonaktifkan
- `browser.enabled=true`
Jika Anda hanya mematikan plugin, CLI browser bawaan (`openclaw browser`),
metode gateway (`browser.request`), tool agen, dan layanan kontrol browser
default semuanya hilang bersama-sama. Config `browser.*` Anda tetap utuh agar dapat digunakan kembali oleh plugin pengganti.
Jika Anda hanya mematikan plugin, CLI browser bawaan (`openclaw browser`), metode gateway (`browser.request`), tool agen, dan layanan kontrol browser default semuanya akan hilang bersama-sama. Konfigurasi `browser.*` Anda tetap utuh agar dapat digunakan ulang oleh plugin pengganti.
Plugin browser bawaan juga sekarang memiliki implementasi runtime browser.
Core hanya menyimpan helper Plugin SDK bersama ditambah compatibility re-exports untuk
jalur impor internal lama. Dalam praktiknya, menghapus atau mengganti paket plugin browser
menghapus set fitur browser alih-alih menyisakan runtime kedua milik core.
Plugin browser bawaan sekarang juga memiliki implementasi runtime browser. Core hanya menyimpan helper Plugin SDK bersama ditambah compatibility re-export untuk path impor internal lama. Dalam praktiknya, menghapus atau mengganti paket plugin browser akan menghapus kumpulan fitur browser, alih-alih meninggalkan runtime kedua yang dimiliki core.
Perubahan config browser tetap memerlukan restart Gateway agar plugin bawaan
dapat mendaftarkan ulang layanan browsernya dengan pengaturan baru.
Perubahan konfigurasi browser tetap memerlukan restart Gateway agar plugin bawaan dapat mendaftarkan ulang layanan browser-nya dengan pengaturan baru.
## Perintah atau tool browser hilang
Jika `openclaw browser` tiba-tiba menjadi perintah yang tidak dikenal setelah upgrade, atau
agen melaporkan bahwa tool browser hilang, penyebab yang paling umum adalah
daftar `plugins.allow` yang ketat dan tidak menyertakan `browser`.
Jika `openclaw browser` tiba-tiba menjadi perintah yang tidak dikenal setelah upgrade, atau agen melaporkan bahwa tool browser hilang, penyebab paling umum adalah daftar `plugins.allow` yang terlalu ketat dan tidak menyertakan `browser`.
Contoh config yang rusak:
Contoh konfigurasi yang rusak:
```json5
{
@ -119,7 +104,7 @@ Catatan penting:
- `browser.enabled=true` saja tidak cukup ketika `plugins.allow` disetel.
- `plugins.entries.browser.enabled=true` saja juga tidak cukup ketika `plugins.allow` disetel.
- `tools.alsoAllow: ["browser"]` **tidak** memuat plugin browser bawaan. Itu hanya menyesuaikan kebijakan tool setelah plugin sudah dimuat.
- Jika Anda tidak memerlukan allowlist plugin yang ketat, menghapus `plugins.allow` juga memulihkan perilaku browser bawaan default.
- Jika Anda tidak memerlukan allowlist plugin yang ketat, menghapus `plugins.allow` juga akan memulihkan perilaku browser bawaan default.
Gejala umum:
@ -130,34 +115,33 @@ Gejala umum:
## Profil: `openclaw` vs `user`
- `openclaw`: browser terkelola dan terisolasi (tidak memerlukan extension).
- `user`: profil attach Chrome MCP bawaan untuk sesi **Chrome asli Anda yang sudah login**.
- `user`: profil attach Chrome MCP bawaan untuk sesi **Chrome asli Anda yang sedang login**.
Untuk pemanggilan tool browser agen:
Untuk panggilan tool browser agen:
- Default: gunakan browser `openclaw` yang terisolasi.
- Pilih `profile="user"` saat sesi login yang sudah ada penting dan pengguna
sedang berada di depan komputer untuk mengeklik/menyetujui prompt attach.
- Pilih `profile="user"` saat sesi login yang sudah ada penting dan pengguna berada di depan komputer untuk klik/menyetujui prompt attach apa pun.
- `profile` adalah override eksplisit saat Anda menginginkan mode browser tertentu.
Setel `browser.defaultProfile: "openclaw"` jika Anda ingin mode terkelola sebagai default.
Setel `browser.defaultProfile: "openclaw"` jika Anda ingin mode terkelola secara default.
## Konfigurasi
Pengaturan browser ada di `~/.openclaw/openclaw.json`.
Pengaturan browser berada di `~/.openclaw/openclaw.json`.
```json5
{
browser: {
enabled: true, // default: true
ssrfPolicy: {
dangerouslyAllowPrivateNetwork: true, // default mode jaringan tepercaya
dangerouslyAllowPrivateNetwork: true, // mode jaringan tepercaya default
// allowPrivateNetwork: true, // alias lama
// hostnameAllowlist: ["*.example.com", "example.com"],
// allowedHostnames: ["localhost"],
},
// cdpUrl: "http://127.0.0.1:18792", // override profil tunggal lama
remoteCdpTimeoutMs: 1500, // timeout HTTP CDP jarak jauh (md)
remoteCdpHandshakeTimeoutMs: 3000, // timeout handshake WebSocket CDP jarak jauh (md)
// cdpUrl: "http://127.0.0.1:18792", // override lama profil tunggal
remoteCdpTimeoutMs: 1500, // timeout HTTP CDP jarak jauh (ms)
remoteCdpHandshakeTimeoutMs: 3000, // timeout handshake WebSocket CDP jarak jauh (ms)
defaultProfile: "openclaw",
color: "#FF4500",
headless: false,
@ -186,32 +170,32 @@ Pengaturan browser ada di `~/.openclaw/openclaw.json`.
Catatan:
- Layanan kontrol browser melakukan bind ke loopback pada port yang diturunkan dari `gateway.port`
- Layanan kontrol browser bind ke loopback pada port yang diturunkan dari `gateway.port`
(default: `18791`, yaitu gateway + 2).
- Jika Anda mengoverride port Gateway (`gateway.port` atau `OPENCLAW_GATEWAY_PORT`),
port browser turunannya bergeser agar tetap berada dalam “keluarga” yang sama.
- `cdpUrl` default ke port CDP lokal yang dikelola saat tidak disetel.
- `remoteCdpTimeoutMs` berlaku untuk pemeriksaan keterjangkauan CDP jarak jauh (bukan loopback).
- Jika Anda meng-override port Gateway (`gateway.port` atau `OPENCLAW_GATEWAY_PORT`),
port browser turunan akan bergeser agar tetap berada dalam “keluarga” yang sama.
- `cdpUrl` secara default menggunakan port CDP lokal terkelola saat tidak disetel.
- `remoteCdpTimeoutMs` berlaku untuk pemeriksaan keterjangkauan CDP jarak jauh (non-loopback).
- `remoteCdpHandshakeTimeoutMs` berlaku untuk pemeriksaan keterjangkauan WebSocket CDP jarak jauh.
- Navigasi browser/buka-tab dilindungi SSRF sebelum navigasi dan diperiksa ulang sebisanya pada URL `http(s)` final setelah navigasi.
- Dalam mode SSRF ketat, penemuan/probe endpoint CDP jarak jauh (`cdpUrl`, termasuk lookup `/json/version`) juga diperiksa.
- `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` default ke `true` (model jaringan tepercaya). Setel ke `false` untuk penelusuran ketat hanya publik.
- `browser.ssrfPolicy.allowPrivateNetwork` tetap didukung sebagai alias lama untuk kompatibilitas.
- `attachOnly: true` berarti “jangan pernah meluncurkan browser lokal; hanya attach jika browser sudah berjalan.”
- `color` + `color` per profil memberi warna pada UI browser sehingga Anda dapat melihat profil mana yang aktif.
- Navigasi/open-tab browser dilindungi SSRF sebelum navigasi dan diperiksa ulang sebisanya pada URL `http(s)` final setelah navigasi.
- Dalam mode SSRF ketat, discovery/probe endpoint CDP jarak jauh (`cdpUrl`, termasuk lookup `/json/version`) juga diperiksa.
- `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` secara default bernilai `true` (model jaringan tepercaya). Setel ke `false` untuk penelusuran ketat hanya publik.
- `browser.ssrfPolicy.allowPrivateNetwork` tetap didukung sebagai alias lama demi kompatibilitas.
- `attachOnly: true` berarti “jangan pernah meluncurkan browser lokal; hanya attach jika browser tersebut sudah berjalan.”
- `color` + `color` per profil memberi tint pada UI browser agar Anda bisa melihat profil mana yang aktif.
- Profil default adalah `openclaw` (browser mandiri yang dikelola OpenClaw). Gunakan `defaultProfile: "user"` untuk memilih browser pengguna yang sudah login.
- Urutan deteksi otomatis: browser default sistem jika berbasis Chromium; jika tidak maka Chrome → Brave → Edge → Chromium → Chrome Canary.
- Profil `openclaw` lokal mengalokasikan otomatis `cdpPort`/`cdpUrl` — setel itu hanya untuk CDP jarak jauh.
- Urutan auto-detect: browser default sistem jika berbasis Chromium; jika tidak maka Chrome → Brave → Edge → Chromium → Chrome Canary.
- Profil `openclaw` lokal akan menetapkan `cdpPort`/`cdpUrl` secara otomatis — setel itu hanya untuk CDP jarak jauh.
- `driver: "existing-session"` menggunakan Chrome DevTools MCP alih-alih CDP mentah. Jangan
setel `cdpUrl` untuk driver itu.
- Setel `browser.profiles.<name>.userDataDir` saat profil existing-session
setel `cdpUrl` untuk driver tersebut.
- Setel `browser.profiles.<name>.userDataDir` ketika profil existing-session
harus attach ke profil pengguna Chromium non-default seperti Brave atau Edge.
## Gunakan Brave (atau browser berbasis Chromium lainnya)
## Gunakan Brave (atau browser berbasis Chromium lain)
Jika browser **default sistem** Anda berbasis Chromium (Chrome/Brave/Edge/dll),
OpenClaw menggunakannya secara otomatis. Setel `browser.executablePath` untuk mengoverride
deteksi otomatis:
OpenClaw akan menggunakannya secara otomatis. Setel `browser.executablePath` untuk meng-override
auto-detect:
Contoh CLI:
@ -245,49 +229,49 @@ openclaw config set browser.executablePath "/usr/bin/google-chrome"
## Kontrol lokal vs jarak jauh
- **Kontrol lokal (default):** Gateway memulai layanan kontrol loopback dan dapat meluncurkan browser lokal.
- **Kontrol jarak jauh (host node):** jalankan host node pada mesin yang memiliki browser; Gateway memproksikan tindakan browser ke host itu.
- **Kontrol jarak jauh (host node):** jalankan host node pada mesin yang memiliki browser; Gateway akan memproksikan aksi browser ke sana.
- **CDP jarak jauh:** setel `browser.profiles.<name>.cdpUrl` (atau `browser.cdpUrl`) untuk
attach ke browser berbasis Chromium jarak jauh. Dalam hal ini, OpenClaw tidak akan meluncurkan browser lokal.
attach ke browser berbasis Chromium jarak jauh. Dalam kasus ini, OpenClaw tidak akan meluncurkan browser lokal.
Perilaku penghentian berbeda menurut mode profil:
- profil terkelola lokal: `openclaw browser stop` menghentikan proses browser yang
diluncurkan OpenClaw
diluncurkan oleh OpenClaw
- profil attach-only dan CDP jarak jauh: `openclaw browser stop` menutup sesi
kontrol aktif dan melepas override emulasi Playwright/CDP (viewport,
skema warna, locale, timezone, mode offline, dan status serupa), meskipun
kontrol aktif dan melepaskan override emulasi Playwright/CDP (viewport,
color scheme, locale, timezone, offline mode, dan status serupa), meskipun
tidak ada proses browser yang diluncurkan oleh OpenClaw
URL CDP jarak jauh dapat menyertakan autentikasi:
URL CDP jarak jauh dapat menyertakan auth:
- Token query (misalnya, `https://provider.example?token=<token>`)
- Autentikasi HTTP Basic (misalnya, `https://user:pass@provider.example`)
- HTTP Basic auth (misalnya, `https://user:pass@provider.example`)
OpenClaw mempertahankan autentikasi saat memanggil endpoint `/json/*` dan saat terhubung
ke CDP WebSocket. Pilih env var atau secrets manager untuk
token alih-alih meng-commit-nya ke file config.
OpenClaw mempertahankan auth saat memanggil endpoint `/json/*` dan saat terhubung
ke WebSocket CDP. Pilih environment variable atau secrets manager untuk
token alih-alih meng-commit-nya ke file konfigurasi.
## Proksi browser node (default tanpa config)
## Proksi browser node (default tanpa konfigurasi)
Jika Anda menjalankan **host node** di mesin yang memiliki browser Anda, OpenClaw dapat
secara otomatis merutekan panggilan tool browser ke node tersebut tanpa config browser tambahan.
Jika Anda menjalankan **host node** pada mesin yang memiliki browser Anda, OpenClaw dapat
secara otomatis merutekan panggilan tool browser ke node tersebut tanpa konfigurasi browser tambahan.
Ini adalah jalur default untuk gateway jarak jauh.
Catatan:
- Host node mengekspos server kontrol browser lokalnya melalui **proxy command**.
- Profil berasal dari config `browser.profiles` milik node sendiri (sama seperti lokal).
- `nodeHost.browserProxy.allowProfiles` bersifat opsional. Biarkan kosong untuk perilaku lama/default: semua profil yang dikonfigurasi tetap dapat dijangkau melalui proksi, termasuk rute buat/hapus profil.
- Jika Anda menyetel `nodeHost.browserProxy.allowProfiles`, OpenClaw memperlakukannya sebagai batas least-privilege: hanya profil dalam allowlist yang dapat ditargetkan, dan rute buat/hapus profil persisten diblokir pada permukaan proksi.
- Profil berasal dari konfigurasi `browser.profiles` milik node itu sendiri (sama seperti lokal).
- `nodeHost.browserProxy.allowProfiles` bersifat opsional. Biarkan kosong untuk perilaku lama/default: semua profil yang dikonfigurasi tetap dapat dijangkau melalui proksi, termasuk route create/delete profil.
- Jika Anda menyetel `nodeHost.browserProxy.allowProfiles`, OpenClaw memperlakukannya sebagai batas least-privilege: hanya profil dalam allowlist yang dapat ditargetkan, dan route create/delete profil persisten diblokir pada permukaan proksi.
- Nonaktifkan jika Anda tidak menginginkannya:
- Pada node: `nodeHost.browserProxy.enabled=false`
- Pada gateway: `gateway.nodes.browser.mode="off"`
## Browserless (CDP jarak jauh terhosting)
## Browserless (CDP jarak jauh ter-host)
[Browserless](https://browserless.io) adalah layanan Chromium terhosting yang mengekspos
[Browserless](https://browserless.io) adalah layanan Chromium ter-host yang mengekspos
URL koneksi CDP melalui HTTPS dan WebSocket. OpenClaw dapat menggunakan keduanya, tetapi
untuk profil browser jarak jauh opsi paling sederhana adalah URL WebSocket langsung
untuk profil browser jarak jauh, opsi paling sederhana adalah URL WebSocket langsung
dari dokumentasi koneksi Browserless.
Contoh:
@ -312,29 +296,29 @@ Contoh:
Catatan:
- Ganti `<BROWSERLESS_API_KEY>` dengan token Browserless asli Anda.
- Pilih endpoint region yang sesuai dengan akun Browserless Anda (lihat dokumentasinya).
- Pilih endpoint region yang sesuai dengan akun Browserless Anda (lihat dokumen mereka).
- Jika Browserless memberi Anda base URL HTTPS, Anda dapat mengubahnya menjadi
`wss://` untuk koneksi CDP langsung atau tetap menggunakan URL HTTPS dan biarkan OpenClaw
`wss://` untuk koneksi CDP langsung atau tetap menggunakan URL HTTPS dan membiarkan OpenClaw
menemukan `/json/version`.
## Penyedia CDP WebSocket langsung
Beberapa layanan browser terhosting mengekspos endpoint **WebSocket langsung** alih-alih
penemuan CDP berbasis HTTP standar (`/json/version`). OpenClaw mendukung keduanya:
Beberapa layanan browser ter-host mengekspos endpoint **WebSocket langsung** alih-alih
discovery CDP berbasis HTTP standar (`/json/version`). OpenClaw mendukung keduanya:
- **Endpoint HTTP(S)** — OpenClaw memanggil `/json/version` untuk menemukan
URL debugger WebSocket, lalu terhubung.
- **Endpoint WebSocket** (`ws://` / `wss://`) — OpenClaw terhubung langsung,
- **Endpoint WebSocket** (`ws://` / `wss://`) — OpenClaw terhubung secara langsung,
melewati `/json/version`. Gunakan ini untuk layanan seperti
[Browserless](https://browserless.io),
[Browserbase](https://www.browserbase.com), atau penyedia mana pun yang memberi Anda
[Browserbase](https://www.browserbase.com), atau penyedia apa pun yang memberi Anda
URL WebSocket.
### Browserbase
[Browserbase](https://www.browserbase.com) adalah platform cloud untuk menjalankan
browser headless dengan penyelesaian CAPTCHA bawaan, mode stealth, dan proxy
residensial.
browser headless dengan pemecahan CAPTCHA bawaan, mode stealth, dan
proxy residensial.
```json5
{
@ -357,49 +341,49 @@ Catatan:
- [Daftar](https://www.browserbase.com/sign-up) dan salin **API Key**
Anda dari [dashboard Overview](https://www.browserbase.com/overview).
- Ganti `<BROWSERBASE_API_KEY>` dengan kunci API Browserbase asli Anda.
- Browserbase otomatis membuat sesi browser saat koneksi WebSocket dibuka, jadi
tidak perlu langkah pembuatan sesi manual.
- Tingkat gratis mengizinkan satu sesi bersamaan dan satu jam browser per bulan.
- Ganti `<BROWSERBASE_API_KEY>` dengan API key Browserbase asli Anda.
- Browserbase otomatis membuat sesi browser saat koneksi WebSocket terjadi, jadi tidak
diperlukan langkah pembuatan sesi manual.
- Tier gratis mengizinkan satu sesi bersamaan dan satu jam browser per bulan.
Lihat [pricing](https://www.browserbase.com/pricing) untuk batas paket berbayar.
- Lihat [dokumentasi Browserbase](https://docs.browserbase.com) untuk referensi API lengkap,
panduan SDK, dan contoh integrasi.
- Lihat [dokumen Browserbase](https://docs.browserbase.com) untuk referensi API
lengkap, panduan SDK, dan contoh integrasi.
## Keamanan
Gagasan utama:
Konsep utama:
- Kontrol browser hanya loopback; akses mengalir melalui autentikasi Gateway atau pairing node.
- API HTTP browser loopback mandiri menggunakan **autentikasi shared-secret saja**:
autentikasi bearer token gateway, `x-openclaw-password`, atau HTTP Basic auth dengan
- Kontrol browser hanya loopback; akses mengalir melalui auth Gateway atau pairing node.
- API HTTP browser loopback mandiri menggunakan **hanya auth shared-secret**:
auth bearer token gateway, `x-openclaw-password`, atau HTTP Basic auth dengan
password gateway yang dikonfigurasi.
- Header identitas Tailscale Serve dan `gateway.auth.mode: "trusted-proxy"` **tidak**
mengautentikasi API browser loopback mandiri ini.
- Jika kontrol browser diaktifkan dan tidak ada autentikasi shared-secret yang dikonfigurasi, OpenClaw
otomatis membuat `gateway.auth.token` saat startup dan menyimpannya ke config.
- OpenClaw **tidak** otomatis membuat token itu saat `gateway.auth.mode` sudah
- Jika kontrol browser diaktifkan dan tidak ada auth shared-secret yang dikonfigurasi, OpenClaw
otomatis membuat `gateway.auth.token` saat startup dan menyimpannya ke konfigurasi.
- OpenClaw **tidak** otomatis membuat token itu ketika `gateway.auth.mode` sudah
`password`, `none`, atau `trusted-proxy`.
- Simpan Gateway dan host node apa pun di jaringan pribadi (Tailscale); hindari eksposur publik.
- Perlakukan URL/token CDP jarak jauh sebagai rahasia; pilih env var atau secrets manager.
- Simpan Gateway dan semua host node di jaringan privat (Tailscale); hindari eksposur publik.
- Perlakukan URL/token CDP jarak jauh sebagai rahasia; pilih env vars atau secrets manager.
Tips CDP jarak jauh:
- Pilih endpoint terenkripsi (HTTPS atau WSS) dan token berumur pendek jika memungkinkan.
- Hindari menyematkan token berumur panjang langsung di file config.
- Hindari menyematkan token berumur panjang langsung di file konfigurasi.
## Profil (multi-browser)
OpenClaw mendukung beberapa profil bernama (routing config). Profil dapat berupa:
OpenClaw mendukung beberapa profil bernama (konfigurasi routing). Profil dapat berupa:
- **dikelola openclaw**: instance browser berbasis Chromium khusus dengan direktori data pengguna + port CDP sendiri
- **dikelola openclaw**: instance browser berbasis Chromium khusus dengan user data directory + port CDP miliknya sendiri
- **jarak jauh**: URL CDP eksplisit (browser berbasis Chromium yang berjalan di tempat lain)
- **sesi yang ada**: profil Chrome Anda yang ada melalui koneksi otomatis Chrome DevTools MCP
- **sesi yang ada**: profil Chrome Anda yang sudah ada melalui auto-connect Chrome DevTools MCP
Default:
- Profil `openclaw` dibuat otomatis jika belum ada.
- Profil `user` bersifat bawaan untuk attach existing-session Chrome MCP.
- Profil existing-session selain `user` bersifat opt-in; buat dengan `--driver existing-session`.
- Profil `user` bawaan tersedia untuk attach existing-session Chrome MCP.
- Profil existing-session bersifat opt-in di luar `user`; buat dengan `--driver existing-session`.
- Port CDP lokal dialokasikan dari **1880018899** secara default.
- Menghapus profil memindahkan direktori data lokalnya ke Trash.
@ -411,7 +395,7 @@ OpenClaw juga dapat attach ke profil browser berbasis Chromium yang sedang berja
server Chrome DevTools MCP resmi. Ini menggunakan kembali tab dan status login
yang sudah terbuka di profil browser tersebut.
Latar belakang resmi dan referensi penyiapan:
Referensi latar belakang dan penyiapan resmi:
- [Chrome for Developers: Use Chrome DevTools MCP with your browser session](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session)
- [Chrome DevTools MCP README](https://github.com/ChromeDevTools/chrome-devtools-mcp)
@ -425,7 +409,7 @@ nama, warna, atau direktori data browser yang berbeda.
Perilaku default:
- Profil `user` bawaan menggunakan koneksi otomatis Chrome MCP, yang menargetkan
- Profil `user` bawaan menggunakan auto-connect Chrome MCP, yang menargetkan
profil Google Chrome lokal default.
Gunakan `userDataDir` untuk Brave, Edge, Chromium, atau profil Chrome non-default:
@ -445,7 +429,7 @@ Gunakan `userDataDir` untuk Brave, Edge, Chromium, atau profil Chrome non-defaul
}
```
Lalu di browser yang sesuai:
Lalu pada browser yang sesuai:
1. Buka halaman inspect browser tersebut untuk remote debugging.
2. Aktifkan remote debugging.
@ -457,7 +441,7 @@ Halaman inspect yang umum:
- Brave: `brave://inspect/#remote-debugging`
- Edge: `edge://inspect/#remote-debugging`
Smoke test attach langsung:
Smoke test attach live:
```bash
openclaw browser --browser-profile user start
@ -466,49 +450,50 @@ openclaw browser --browser-profile user tabs
openclaw browser --browser-profile user snapshot --format ai
```
Tanda keberhasilan:
Ciri keberhasilan:
- `status` menampilkan `driver: existing-session`
- `status` menampilkan `transport: chrome-mcp`
- `status` menampilkan `running: true`
- `tabs` menampilkan daftar tab browser Anda yang sudah terbuka
- `tabs` menampilkan tab browser Anda yang sudah terbuka
- `snapshot` mengembalikan ref dari tab live yang dipilih
Yang perlu diperiksa jika attach tidak berfungsi:
Yang perlu diperiksa jika attach tidak berhasil:
- browser berbasis Chromium target versinya `144+`
- remote debugging diaktifkan di halaman inspect browser itu
- remote debugging diaktifkan di halaman inspect browser tersebut
- browser menampilkan prompt persetujuan attach dan Anda menerimanya
- `openclaw doctor` memigrasikan config browser berbasis extension lama dan memeriksa bahwa
Chrome terpasang secara lokal untuk profil koneksi otomatis default, tetapi tidak dapat
- `openclaw doctor` memigrasikan konfigurasi browser lama berbasis extension dan memeriksa bahwa
Chrome terinstal secara lokal untuk profil auto-connect default, tetapi tidak dapat
mengaktifkan remote debugging di sisi browser untuk Anda
Penggunaan agen:
- Gunakan `profile="user"` saat Anda memerlukan status browser pengguna yang sudah login.
- Jika Anda menggunakan profil existing-session kustom, teruskan nama profil eksplisit tersebut.
- Pilih mode ini hanya saat pengguna sedang berada di depan komputer untuk menyetujui
prompt attach.
- Gunakan `profile="user"` saat Anda membutuhkan status browser pengguna yang sedang login.
- Jika Anda menggunakan profil existing-session kustom, berikan nama profil eksplisit tersebut.
- Pilih mode ini hanya saat pengguna berada di depan komputer untuk menyetujui prompt
attach.
- Gateway atau host node dapat menjalankan `npx chrome-devtools-mcp@latest --autoConnect`
Catatan:
- Jalur ini berisiko lebih tinggi daripada profil `openclaw` yang terisolasi karena dapat
bertindak di dalam sesi browser Anda yang sudah login.
- Jalur ini berisiko lebih tinggi dibanding profil `openclaw` yang terisolasi karena dapat
bertindak di dalam sesi browser Anda yang sedang login.
- OpenClaw tidak meluncurkan browser untuk driver ini; OpenClaw hanya attach ke
sesi yang sudah ada.
- OpenClaw menggunakan alur `--autoConnect` Chrome DevTools MCP resmi di sini. Jika
`userDataDir` disetel, OpenClaw meneruskannya untuk menargetkan direktori data pengguna
Chromium eksplisit tersebut.
- Tangkapan layar existing-session mendukung tangkapan halaman dan tangkapan elemen `--ref`
`userDataDir` disetel, OpenClaw meneruskannya untuk menargetkan secara eksplisit
direktori data pengguna Chromium tersebut.
- Screenshot existing-session mendukung pengambilan halaman dan pengambilan elemen `--ref`
dari snapshot, tetapi tidak mendukung selector CSS `--element`.
- Tangkapan layar halaman existing-session berfungsi tanpa Playwright melalui Chrome MCP.
Tangkapan layar elemen berbasis ref (`--ref`) juga berfungsi di sana, tetapi `--full-page`
- Screenshot halaman existing-session berfungsi tanpa Playwright melalui Chrome MCP.
Screenshot elemen berbasis ref (`--ref`) juga berfungsi di sana, tetapi `--full-page`
tidak dapat digabungkan dengan `--ref` atau `--element`.
- Tindakan existing-session masih lebih terbatas daripada jalur browser terkelola:
- Aksi existing-session masih lebih terbatas dibanding jalur browser
terkelola:
- `click`, `type`, `hover`, `scrollIntoView`, `drag`, dan `select` memerlukan
ref snapshot alih-alih selector CSS
- `click` hanya untuk tombol kiri (tanpa override tombol atau modifier)
- `click` hanya tombol kiri (tanpa override tombol atau modifier)
- `type` tidak mendukung `slowly=true`; gunakan `fill` atau `press`
- `press` tidak mendukung `delayMs`
- `hover`, `scrollIntoView`, `drag`, `select`, `fill`, dan `evaluate` tidak
@ -519,19 +504,20 @@ Catatan:
- Hook upload existing-session memerlukan `ref` atau `inputRef`, mendukung satu file
dalam satu waktu, dan tidak mendukung penargetan CSS `element`.
- Hook dialog existing-session tidak mendukung override timeout.
- Beberapa fitur masih memerlukan jalur browser terkelola, termasuk tindakan batch,
ekspor PDF, intersepsi download, dan `responsebody`.
- Existing-session bersifat lokal terhadap host. Jika Chrome berada di mesin lain atau namespace jaringan lain, gunakan CDP jarak jauh atau host node.
- Beberapa fitur masih memerlukan jalur browser terkelola, termasuk batch
action, ekspor PDF, intersepsi download, dan `responsebody`.
- Existing-session bersifat host-local. Jika Chrome berada di mesin lain atau
namespace jaringan yang berbeda, gunakan CDP jarak jauh atau host node.
## Jaminan isolasi
- **Direktori data pengguna khusus**: tidak pernah menyentuh profil browser pribadi Anda.
- **Port khusus**: menghindari `9222` untuk mencegah bentrokan dengan alur kerja dev.
- **User data dir khusus**: tidak pernah menyentuh profil browser pribadi Anda.
- **Port khusus**: menghindari `9222` untuk mencegah benturan dengan alur kerja dev.
- **Kontrol tab deterministik**: targetkan tab berdasarkan `targetId`, bukan “tab terakhir”.
## Pemilihan browser
Saat meluncurkan secara lokal, OpenClaw memilih yang pertama tersedia:
Saat diluncurkan secara lokal, OpenClaw memilih yang pertama tersedia:
1. Chrome
2. Brave
@ -539,7 +525,7 @@ Saat meluncurkan secara lokal, OpenClaw memilih yang pertama tersedia:
4. Chromium
5. Chrome Canary
Anda dapat mengoverride dengan `browser.executablePath`.
Anda dapat meng-override dengan `browser.executablePath`.
Platform:
@ -547,14 +533,14 @@ Platform:
- Linux: mencari `google-chrome`, `brave`, `microsoft-edge`, `chromium`, dll.
- Windows: memeriksa lokasi instalasi umum.
## API Kontrol (opsional)
## API kontrol (opsional)
Hanya untuk integrasi lokal, Gateway mengekspos API HTTP loopback kecil:
- Status/start/stop: `GET /`, `POST /start`, `POST /stop`
- Tab: `GET /tabs`, `POST /tabs/open`, `POST /tabs/focus`, `DELETE /tabs/:targetId`
- Snapshot/tangkapan layar: `GET /snapshot`, `POST /screenshot`
- Tindakan: `POST /navigate`, `POST /act`
- Snapshot/screenshot: `GET /snapshot`, `POST /screenshot`
- Aksi: `POST /navigate`, `POST /act`
- Hook: `POST /hooks/file-chooser`, `POST /hooks/dialog`
- Download: `POST /download`, `POST /wait/download`
- Debugging: `GET /console`, `POST /pdf`
@ -566,48 +552,66 @@ Hanya untuk integrasi lokal, Gateway mengekspos API HTTP loopback kecil:
Semua endpoint menerima `?profile=<name>`.
Jika autentikasi gateway shared-secret dikonfigurasi, rute HTTP browser juga memerlukan autentikasi:
Jika auth gateway shared-secret dikonfigurasi, route HTTP browser juga memerlukan auth:
- `Authorization: Bearer <gateway token>`
- `x-openclaw-password: <gateway password>` atau HTTP Basic auth dengan password tersebut
Catatan:
- API browser loopback mandiri ini **tidak** menggunakan header trusted-proxy atau
identitas Tailscale Serve.
- Jika `gateway.auth.mode` adalah `none` atau `trusted-proxy`, rute browser loopback ini
tidak mewarisi mode pembawa identitas tersebut; tetap pertahankan hanya loopback.
- API browser loopback mandiri ini **tidak** menggunakan trusted-proxy atau
header identitas Tailscale Serve.
- Jika `gateway.auth.mode` adalah `none` atau `trusted-proxy`, route browser loopback
ini tidak mewarisi mode pembawa identitas tersebut; tetap batasi hanya loopback.
### Persyaratan Playwright
### Kontrak error `/act`
Beberapa fitur (navigate/act/snapshot AI/role snapshot, tangkapan layar elemen,
PDF) memerlukan Playwright. Jika Playwright tidak terpasang, endpoint tersebut mengembalikan
error 501 yang jelas.
`POST /act` menggunakan respons error terstruktur untuk validasi level route dan
kegagalan kebijakan:
Yang tetap berfungsi tanpa Playwright:
```json
{ "error": "<message>", "code": "ACT_*" }
```
Nilai `code` saat ini:
- `ACT_KIND_REQUIRED` (HTTP 400): `kind` hilang atau tidak dikenali.
- `ACT_INVALID_REQUEST` (HTTP 400): payload aksi gagal normalisasi atau validasi.
- `ACT_SELECTOR_UNSUPPORTED` (HTTP 400): `selector` digunakan dengan jenis aksi yang tidak didukung.
- `ACT_EVALUATE_DISABLED` (HTTP 403): `evaluate` (atau `wait --fn`) dinonaktifkan oleh konfigurasi.
- `ACT_TARGET_ID_MISMATCH` (HTTP 403): `targetId` level teratas atau dalam batch bertentangan dengan target permintaan.
- `ACT_EXISTING_SESSION_UNSUPPORTED` (HTTP 501): aksi tidak didukung untuk profil existing-session.
Kegagalan runtime lainnya masih dapat mengembalikan `{ "error": "<message>" }` tanpa
field `code`.
### Kebutuhan Playwright
Beberapa fitur (navigate/act/AI snapshot/role snapshot, screenshot elemen,
PDF) memerlukan Playwright. Jika Playwright tidak terinstal, endpoint tersebut mengembalikan error 501 yang jelas.
Yang masih berfungsi tanpa Playwright:
- Snapshot ARIA
- Tangkapan layar halaman untuk browser `openclaw` terkelola saat tersedia
WebSocket CDP per tab
- Tangkapan layar halaman untuk profil `existing-session` / Chrome MCP
- Tangkapan layar existing-session berbasis ref (`--ref`) dari output snapshot
- Screenshot halaman untuk browser `openclaw` terkelola ketika tersedia WebSocket
CDP per tab
- Screenshot halaman untuk profil `existing-session` / Chrome MCP
- Screenshot existing-session berbasis ref (`--ref`) dari output snapshot
Yang masih memerlukan Playwright:
- `navigate`
- `act`
- Snapshot AI / role snapshot
- Tangkapan layar elemen selector CSS (`--element`)
- Ekspor PDF browser penuh
- AI snapshot / role snapshot
- Screenshot elemen selector CSS (`--element`)
- ekspor PDF browser penuh
Tangkapan layar elemen juga menolak `--full-page`; rute mengembalikan `fullPage is
Screenshot elemen juga menolak `--full-page`; route mengembalikan `fullPage is
not supported for element screenshots`.
Jika Anda melihat `Playwright is not available in this gateway build`, instal paket
Playwright penuh (bukan `playwright-core`) dan mulai ulang gateway, atau instal ulang
OpenClaw dengan dukungan browser.
Jika Anda melihat `Playwright is not available in this gateway build`, instal paket Playwright lengkap (bukan `playwright-core`) lalu mulai ulang gateway, atau instal ulang OpenClaw dengan dukungan browser.
#### Instalasi Playwright di Docker
#### Instal Playwright di Docker
Jika Gateway Anda berjalan di Docker, hindari `npx playwright` (konflik override npm).
Gunakan CLI bawaan sebagai gantinya:
@ -617,7 +621,7 @@ docker compose run --rm openclaw-cli \
node /app/node_modules/playwright-core/cli.js install chromium
```
Untuk mempertahankan download browser, setel `PLAYWRIGHT_BROWSERS_PATH` (misalnya,
Untuk mempertahankan unduhan browser, setel `PLAYWRIGHT_BROWSERS_PATH` (misalnya,
`/home/node/.cache/ms-playwright`) dan pastikan `/home/node` dipertahankan melalui
`OPENCLAW_HOME_VOLUME` atau bind mount. Lihat [Docker](/id/install/docker).
@ -626,12 +630,12 @@ Untuk mempertahankan download browser, setel `PLAYWRIGHT_BROWSERS_PATH` (misalny
Alur tingkat tinggi:
- Sebuah **server kontrol** kecil menerima permintaan HTTP.
- Server ini terhubung ke browser berbasis Chromium (Chrome/Brave/Edge/Chromium) melalui **CDP**.
- Untuk tindakan lanjutan (klik/ketik/snapshot/PDF), server ini menggunakan **Playwright** di atas
- Server itu terhubung ke browser berbasis Chromium (Chrome/Brave/Edge/Chromium) melalui **CDP**.
- Untuk aksi lanjutan (click/type/snapshot/PDF), server itu menggunakan **Playwright** di atas
CDP.
- Saat Playwright tidak tersedia, hanya operasi non-Playwright yang tersedia.
Desain ini menjaga agen tetap pada antarmuka yang stabil dan deterministik sambil memungkinkan
Desain ini menjaga agen tetap berada pada antarmuka yang stabil dan deterministik sambil memungkinkan
Anda menukar browser dan profil lokal/jarak jauh.
## Referensi cepat CLI
@ -639,7 +643,7 @@ Anda menukar browser dan profil lokal/jarak jauh.
Semua perintah menerima `--browser-profile <name>` untuk menargetkan profil tertentu.
Semua perintah juga menerima `--json` untuk output yang dapat dibaca mesin (payload stabil).
Dasar:
Dasar-dasar:
- `openclaw browser status`
- `openclaw browser start`
@ -670,16 +674,16 @@ Inspeksi:
Catatan siklus hidup:
- Untuk profil attach-only dan CDP jarak jauh, `openclaw browser stop` tetap
merupakan perintah pembersihan yang tepat setelah pengujian. Ini menutup sesi kontrol aktif dan
membersihkan override emulasi sementara alih-alih mematikan browser
dasarnya.
- Untuk profil attach-only dan CDP jarak jauh, `openclaw browser stop` tetap merupakan
perintah pembersihan yang tepat setelah pengujian. Perintah ini menutup sesi kontrol aktif dan
menghapus override emulasi sementara alih-alih mematikan browser
yang mendasarinya.
- `openclaw browser errors --clear`
- `openclaw browser requests --filter api --clear`
- `openclaw browser pdf`
- `openclaw browser responsebody "**/api" --max-chars 5000`
Tindakan:
Aksi:
- `openclaw browser navigate https://example.com`
- `openclaw browser resize 1280 720`
@ -724,25 +728,25 @@ Status:
Catatan:
- `upload` dan `dialog` adalah panggilan **arming**; jalankan keduanya sebelum klik/tekan
- `upload` dan `dialog` adalah panggilan **arming**; jalankan keduanya sebelum click/press
yang memicu chooser/dialog.
- Jalur output download dan trace dibatasi ke root temp OpenClaw:
- Path output download dan trace dibatasi ke root temp OpenClaw:
- trace: `/tmp/openclaw` (fallback: `${os.tmpdir()}/openclaw`)
- download: `/tmp/openclaw/downloads` (fallback: `${os.tmpdir()}/openclaw/downloads`)
- Jalur upload dibatasi ke root upload temp OpenClaw:
- unduhan: `/tmp/openclaw/downloads` (fallback: `${os.tmpdir()}/openclaw/downloads`)
- Path upload dibatasi ke root upload temp OpenClaw:
- upload: `/tmp/openclaw/uploads` (fallback: `${os.tmpdir()}/openclaw/uploads`)
- `upload` juga dapat menyetel input file secara langsung melalui `--input-ref` atau `--element`.
- `upload` juga dapat mengatur input file secara langsung melalui `--input-ref` atau `--element`.
- `snapshot`:
- `--format ai` (default saat Playwright terpasang): mengembalikan snapshot AI dengan ref numerik (`aria-ref="<n>"`).
- `--format aria`: mengembalikan pohon aksesibilitas (tanpa ref; hanya untuk inspeksi).
- `--efficient` (atau `--mode efficient`): preset role snapshot ringkas (interactive + compact + depth + maxChars lebih rendah).
- Default config (hanya tool/CLI): setel `browser.snapshotDefaults.mode: "efficient"` untuk menggunakan snapshot efisien saat pemanggil tidak meneruskan mode (lihat [Konfigurasi gateway](/id/gateway/configuration-reference#browser)).
- Opsi role snapshot (`--interactive`, `--compact`, `--depth`, `--selector`) memaksa role-based snapshot dengan ref seperti `ref=e12`.
- `--frame "<iframe selector>"` membatasi role snapshot ke iframe (berpasangan dengan role ref seperti `e12`).
- `--interactive` menghasilkan daftar datar elemen interaktif yang mudah dipilih (terbaik untuk mendorong tindakan).
- `--labels` menambahkan tangkapan layar khusus viewport dengan label ref yang dioverlay (mencetak `MEDIA:<path>`).
- `click`/`type`/dll memerlukan `ref` dari `snapshot` (baik numerik `12` maupun role ref `e12`).
Selector CSS sengaja tidak didukung untuk tindakan.
- `--format ai` (default saat Playwright terinstal): mengembalikan snapshot AI dengan ref numerik (`aria-ref="<n>"`).
- `--format aria`: mengembalikan accessibility tree (tanpa ref; hanya untuk inspeksi).
- `--efficient` (atau `--mode efficient`): preset snapshot role ringkas (interactive + compact + depth + maxChars lebih rendah).
- Default konfigurasi (hanya tool/CLI): setel `browser.snapshotDefaults.mode: "efficient"` untuk menggunakan snapshot efisien saat pemanggil tidak memberikan mode (lihat [Konfigurasi Gateway](/id/gateway/configuration-reference#browser)).
- Opsi snapshot role (`--interactive`, `--compact`, `--depth`, `--selector`) memaksa snapshot berbasis role dengan ref seperti `ref=e12`.
- `--frame "<iframe selector>"` membatasi snapshot role ke sebuah iframe (dipasangkan dengan ref role seperti `e12`).
- `--interactive` menghasilkan daftar datar elemen interaktif yang mudah dipilih (terbaik untuk menjalankan aksi).
- `--labels` menambahkan screenshot hanya viewport dengan label ref yang dioverlay (mencetak `MEDIA:<path>`).
- `click`/`type`/dll memerlukan `ref` dari `snapshot` (baik numerik `12` maupun ref role `e12`).
Selector CSS sengaja tidak didukung untuk aksi.
## Snapshot dan ref
@ -750,31 +754,31 @@ OpenClaw mendukung dua gaya “snapshot”:
- **Snapshot AI (ref numerik)**: `openclaw browser snapshot` (default; `--format ai`)
- Output: snapshot teks yang menyertakan ref numerik.
- Tindakan: `openclaw browser click 12`, `openclaw browser type 23 "hello"`.
- Secara internal, ref diresolusikan melalui `aria-ref` milik Playwright.
- Aksi: `openclaw browser click 12`, `openclaw browser type 23 "hello"`.
- Secara internal, ref diselesaikan melalui `aria-ref` milik Playwright.
- **Role snapshot (role ref seperti `e12`)**: `openclaw browser snapshot --interactive` (atau `--compact`, `--depth`, `--selector`, `--frame`)
- Output: daftar/pohon berbasis role dengan `[ref=e12]` (dan opsional `[nth=1]`).
- Tindakan: `openclaw browser click e12`, `openclaw browser highlight e12`.
- Secara internal, ref diresolusikan melalui `getByRole(...)` (ditambah `nth()` untuk duplikat).
- Tambahkan `--labels` untuk menyertakan tangkapan layar viewport dengan label `e12` yang dioverlay.
- **Snapshot role (ref role seperti `e12`)**: `openclaw browser snapshot --interactive` (atau `--compact`, `--depth`, `--selector`, `--frame`)
- Output: daftar/tree berbasis role dengan `[ref=e12]` (dan opsional `[nth=1]`).
- Aksi: `openclaw browser click e12`, `openclaw browser highlight e12`.
- Secara internal, ref diselesaikan melalui `getByRole(...)` (ditambah `nth()` untuk duplikasi).
- Tambahkan `--labels` untuk menyertakan screenshot viewport dengan label `e12` yang dioverlay.
Perilaku ref:
- Ref **tidak stabil antar navigasi**; jika sesuatu gagal, jalankan ulang `snapshot` dan gunakan ref baru.
- Jika role snapshot diambil dengan `--frame`, role ref dibatasi ke iframe tersebut sampai role snapshot berikutnya.
- Jika snapshot role diambil dengan `--frame`, ref role dibatasi ke iframe tersebut sampai snapshot role berikutnya.
## Peningkatan `wait`
## Penguat wait
Anda dapat menunggu lebih dari sekadar waktu/teks:
- Tunggu URL (glob didukung oleh Playwright):
- Menunggu URL (glob didukung oleh Playwright):
- `openclaw browser wait --url "**/dash"`
- Tunggu status load:
- Menunggu status load:
- `openclaw browser wait --load networkidle`
- Tunggu predikat JS:
- Menunggu predikat JS:
- `openclaw browser wait --fn "window.ready===true"`
- Tunggu selector menjadi terlihat:
- Menunggu selector menjadi terlihat:
- `openclaw browser wait "#main"`
Ini dapat digabungkan:
@ -789,11 +793,11 @@ openclaw browser wait "#main" \
## Alur kerja debugging
Saat tindakan gagal (misalnya “not visible”, “strict mode violation”, “covered”):
Saat sebuah aksi gagal (misalnya “not visible”, “strict mode violation”, “covered”):
1. `openclaw browser snapshot --interactive`
2. Gunakan `click <ref>` / `type <ref>` (pilih role ref dalam mode interactive)
3. Jika masih gagal: `openclaw browser highlight <ref>` untuk melihat apa yang ditargetkan Playwright
2. Gunakan `click <ref>` / `type <ref>` (pilih ref role dalam mode interaktif)
3. Jika masih gagal: `openclaw browser highlight <ref>` untuk melihat target Playwright
4. Jika halaman berperilaku aneh:
- `openclaw browser errors --clear`
- `openclaw browser requests --filter api --clear`
@ -804,7 +808,7 @@ Saat tindakan gagal (misalnya “not visible”, “strict mode violation”,
## Output JSON
`--json` ditujukan untuk skrip dan tool terstruktur.
`--json` ditujukan untuk scripting dan tooling terstruktur.
Contoh:
@ -815,33 +819,33 @@ openclaw browser requests --filter api --json
openclaw browser cookies --json
```
Role snapshot dalam JSON menyertakan `refs` plus blok `stats` kecil (lines/chars/refs/interactive) agar tool dapat menalar ukuran dan kepadatan payload.
Snapshot role dalam JSON menyertakan `refs` plus blok `stats` kecil (lines/chars/refs/interactive) sehingga tool dapat memahami ukuran dan kepadatan payload.
## Kenop status dan environment
## Knob status dan lingkungan
Ini berguna untuk alur kerja “buat situs berperilaku seperti X”:
- Cookie: `cookies`, `cookies set`, `cookies clear`
- Cookies: `cookies`, `cookies set`, `cookies clear`
- Storage: `storage local|session get|set|clear`
- Offline: `set offline on|off`
- Header: `set headers --headers-json '{"X-Debug":"1"}'` (legacy `set headers --json '{"X-Debug":"1"}'` tetap didukung)
- HTTP basic auth: `set credentials user pass` (atau `--clear`)
- Header: `set headers --headers-json '{"X-Debug":"1"}'` (format lama `set headers --json '{"X-Debug":"1"}'` tetap didukung)
- HTTP Basic auth: `set credentials user pass` (atau `--clear`)
- Geolokasi: `set geo <lat> <lon> --origin "https://example.com"` (atau `--clear`)
- Media: `set media dark|light|no-preference|none`
- Timezone / locale: `set timezone ...`, `set locale ...`
- Device / viewport:
- `set device "iPhone 14"` (preset perangkat Playwright)
- `set device "iPhone 14"` (preset device Playwright)
- `set viewport 1280 720`
## Keamanan & privasi
- Profil browser openclaw dapat berisi sesi yang sudah login; perlakukan sebagai sesuatu yang sensitif.
- Profil browser openclaw dapat berisi sesi yang sedang login; perlakukan sebagai sesuatu yang sensitif.
- `browser act kind=evaluate` / `openclaw browser evaluate` dan `wait --fn`
mengeksekusi JavaScript arbitrer dalam konteks halaman. Prompt injection dapat
mengarahkan ini. Nonaktifkan dengan `browser.evaluateEnabled=false` jika Anda tidak membutuhkannya.
- Untuk login dan catatan anti-bot (X/Twitter, dll.), lihat [Login browser + posting X/Twitter](/tools/browser-login).
- Simpan Gateway/host node tetap privat (hanya loopback atau tailnet).
- Endpoint CDP jarak jauh sangat kuat; tunnel dan lindungi endpoint tersebut.
mengeksekusi JavaScript arbitrer dalam konteks halaman. Prompt injection dapat mengarahkan
ini. Nonaktifkan dengan `browser.evaluateEnabled=false` jika Anda tidak membutuhkannya.
- Untuk login dan catatan anti-bot (X/Twitter, dll.), lihat [Login browser + posting X/Twitter](/id/tools/browser-login).
- Jaga Gateway/host node tetap privat (hanya loopback atau tailnet).
- Endpoint CDP jarak jauh sangat kuat; tunnel-kan dan lindungi endpoint tersebut.
Contoh mode ketat (blokir tujuan privat/internal secara default):
@ -851,7 +855,7 @@ Contoh mode ketat (blokir tujuan privat/internal secara default):
ssrfPolicy: {
dangerouslyAllowPrivateNetwork: false,
hostnameAllowlist: ["*.example.com", "example.com"],
allowedHostnames: ["localhost"], // exact allow opsional
allowedHostnames: ["localhost"], // izin exact opsional
},
},
}
@ -860,12 +864,12 @@ Contoh mode ketat (blokir tujuan privat/internal secara default):
## Pemecahan masalah
Untuk masalah khusus Linux (terutama snap Chromium), lihat
[Pemecahan masalah browser](/tools/browser-linux-troubleshooting).
[Pemecahan masalah browser](/id/tools/browser-linux-troubleshooting).
Untuk penyiapan host-terpisah WSL2 Gateway + Chrome Windows, lihat
[Pemecahan masalah WSL2 + Windows + CDP Chrome jarak jauh](/tools/browser-wsl2-windows-remote-cdp-troubleshooting).
Untuk pengaturan host-terpisah WSL2 Gateway + Windows Chrome, lihat
[Pemecahan masalah WSL2 + Windows + Chrome CDP jarak jauh](/id/tools/browser-wsl2-windows-remote-cdp-troubleshooting).
## Tool agen + cara kerja kontrol
## Tool agen + cara kontrol bekerja
Agen mendapatkan **satu tool** untuk otomatisasi browser:
@ -873,20 +877,20 @@ Agen mendapatkan **satu tool** untuk otomatisasi browser:
Pemetaan kerjanya:
- `browser snapshot` mengembalikan pohon UI yang stabil (AI atau ARIA).
- `browser act` menggunakan ID `ref` dari snapshot untuk klik/ketik/seret/pilih.
- `browser snapshot` mengembalikan tree UI yang stabil (AI atau ARIA).
- `browser act` menggunakan ID `ref` dari snapshot untuk click/type/drag/select.
- `browser screenshot` menangkap piksel (halaman penuh atau elemen).
- `browser` menerima:
- `profile` untuk memilih profil browser bernama (openclaw, chrome, atau CDP jarak jauh).
- `target` (`sandbox` | `host` | `node`) untuk memilih tempat browser berada.
- Dalam sesi sandboxed, `target: "host"` memerlukan `agents.defaults.sandbox.browser.allowHostControl=true`.
- Jika `target` dihilangkan: sesi sandboxed default ke `sandbox`, sesi non-sandbox default ke `host`.
- Jika node yang mendukung browser terhubung, tool dapat otomatis diarahkan ke node itu kecuali Anda mengunci `target="host"` atau `target="node"`.
- `target` (`sandbox` | `host` | `node`) untuk memilih lokasi browser berada.
- Dalam sesi sandbox, `target: "host"` memerlukan `agents.defaults.sandbox.browser.allowHostControl=true`.
- Jika `target` dihilangkan: sesi sandbox secara default menggunakan `sandbox`, sesi non-sandbox secara default menggunakan `host`.
- Jika node yang mendukung browser terhubung, tool dapat merutekan otomatis ke node itu kecuali Anda menetapkan `target="host"` atau `target="node"`.
Ini menjaga agen tetap deterministik dan menghindari selector yang rapuh.
## Terkait
- [Ikhtisar Tools](/tools) — semua tool agen yang tersedia
- [Sandboxing](/id/gateway/sandboxing) — kontrol browser dalam environment sandboxed
- [Keamanan](/id/gateway/security) — risiko kontrol browser dan hardening
- [Ikhtisar Tools](/id/tools) — semua tool agen yang tersedia
- [Sandboxing](/id/gateway/sandboxing) — kontrol browser di lingkungan sandbox
- [Security](/id/gateway/security) — risiko kontrol browser dan hardening

View File

@ -1,61 +1,66 @@
---
read_when:
- Mengonfigurasi persetujuan exec atau allowlist
- Mengimplementasikan UX persetujuan exec di aplikasi macOS
- Meninjau prompt escape sandbox dan implikasinya
summary: Persetujuan exec, allowlist, dan prompt escape sandbox
- Menerapkan UX persetujuan exec di aplikasi macOS
- Meninjau prompt pelarian sandbox dan implikasinya
summary: Persetujuan exec, allowlist, dan prompt pelarian sandbox
title: Persetujuan Exec
x-i18n:
generated_at: "2026-04-08T02:19:03Z"
generated_at: "2026-04-10T09:13:54Z"
model: gpt-5.4
provider: openai
source_hash: 6041929185bab051ad873cc4822288cb7d6f0470e19e7ae7a16b70f76dfc2cd9
source_hash: 5f4a2e2f1f3c13a1d1926c9de0720513ea8a74d1ca571dbe74b188d8c560c14c
source_path: tools/exec-approvals.md
workflow: 15
---
# Persetujuan exec
Persetujuan exec adalah **guardrail aplikasi pendamping / host node** untuk memungkinkan agen yang disandbox menjalankan
perintah pada host nyata (`gateway` atau `node`). Anggap ini seperti interlock keselamatan:
perintah diizinkan hanya ketika kebijakan + allowlist + (opsional) persetujuan pengguna semuanya setuju.
Persetujuan exec adalah **tambahan** terhadap kebijakan tool dan gating elevated (kecuali elevated disetel ke `full`, yang melewati persetujuan).
Kebijakan efektif adalah yang **lebih ketat** dari default `tools.exec.*` dan approvals; jika field approvals dihilangkan, nilai `tools.exec` yang digunakan.
Persetujuan exec adalah **guardrail aplikasi pendamping / host node** untuk mengizinkan agen yang disandbox menjalankan
perintah di host nyata (`gateway` atau `node`). Anggap ini seperti interlock keselamatan:
perintah diizinkan hanya jika kebijakan + allowlist + (opsional) persetujuan pengguna semuanya menyetujui.
Persetujuan exec adalah **tambahan** di atas kebijakan alat dan gating elevated (kecuali elevated disetel ke `full`, yang melewati persetujuan).
Kebijakan efektif adalah yang **lebih ketat** dari default `tools.exec.*` dan approvals; jika sebuah field approvals dihilangkan, nilai `tools.exec` yang digunakan.
Host exec juga menggunakan status approvals lokal pada mesin tersebut. Nilai host-local
`ask: "always"` di `~/.openclaw/exec-approvals.json` akan terus memunculkan prompt meskipun
default sesi atau config meminta `ask: "on-miss"`.
`ask: "always"` di `~/.openclaw/exec-approvals.json` akan tetap memunculkan prompt meskipun
default sesi atau konfigurasi meminta `ask: "on-miss"`.
Gunakan `openclaw approvals get`, `openclaw approvals get --gateway`, atau
`openclaw approvals get --node <id|name|ip>` untuk memeriksa kebijakan yang diminta,
sumber kebijakan host, dan hasil efektifnya.
sumber kebijakan host, dan hasil efektif.
Untuk mesin lokal, `openclaw exec-policy show` menampilkan tampilan gabungan yang sama dan
`openclaw exec-policy set|preset` dapat menyinkronkan kebijakan yang diminta secara lokal dengan
file approvals host lokal dalam satu langkah. Ketika sebuah cakupan lokal meminta `host=node`,
`openclaw exec-policy show` melaporkan cakupan itu sebagai dikelola node saat runtime alih-alih
berpura-pura bahwa file approvals lokal adalah sumber kebenaran yang efektif.
Jika UI aplikasi pendamping **tidak tersedia**, setiap permintaan yang memerlukan prompt akan
diselesaikan oleh **fallback ask** (default: deny).
diselesaikan oleh **ask fallback** (default: deny).
Klien persetujuan chat native juga dapat mengekspos affordance khusus channel pada
pesan persetujuan yang tertunda. Misalnya, Matrix dapat menanam shortcut reaction pada
prompt persetujuan (`✅` izinkan sekali, `❌` tolak, dan `♾️` selalu izinkan saat tersedia)
sambil tetap menyediakan perintah `/approve ...` di pesan sebagai fallback.
pesan persetujuan yang tertunda. Misalnya, Matrix dapat menyiapkan pintasan reaction pada
prompt persetujuan (`✅` izinkan sekali, `❌` tolak, dan `♾️` izinkan selalu bila tersedia)
sambil tetap menyisakan perintah `/approve ...` dalam pesan sebagai fallback.
## Di mana ini berlaku
## Tempat ini berlaku
Persetujuan exec diberlakukan secara lokal pada host eksekusi:
Persetujuan exec diterapkan secara lokal pada host eksekusi:
- **host gateway** → proses `openclaw` pada mesin gateway
- **host node** → runner node (aplikasi pendamping macOS atau host node headless)
Catatan model kepercayaan:
- Pemanggil yang diautentikasi gateway adalah operator tepercaya untuk Gateway tersebut.
- Node yang dipasangkan memperluas kapabilitas operator tepercaya itu ke host node.
- Pemanggil yang diautentikasi Gateway adalah operator tepercaya untuk Gateway tersebut.
- Node yang dipasangkan memperluas kemampuan operator tepercaya itu ke host node.
- Persetujuan exec mengurangi risiko eksekusi yang tidak disengaja, tetapi bukan batas autentikasi per pengguna.
- Eksekusi host node yang disetujui mengikat konteks eksekusi kanonis: cwd kanonis, argv yang persis, env
binding ketika ada, dan path executable yang dipin bila berlaku.
- Untuk shell script dan invokasi file interpreter/runtime langsung, OpenClaw juga mencoba mengikat
satu operand file lokal konkret. Jika file yang terikat itu berubah setelah persetujuan tetapi sebelum eksekusi,
eksekusi ditolak alih-alih menjalankan konten yang sudah bergeser.
- File binding ini sengaja bersifat best-effort, bukan model semantik lengkap untuk setiap
- Proses host-node yang disetujui mengikat konteks eksekusi kanonis: cwd kanonis, argv yang tepat, pengikatan env
bila ada, dan path executable yang dipin bila berlaku.
- Untuk skrip shell dan pemanggilan file interpreter/runtime langsung, OpenClaw juga mencoba mengikat
satu operand file lokal konkret. Jika file yang diikat itu berubah setelah persetujuan tetapi sebelum eksekusi,
proses ditolak alih-alih mengeksekusi konten yang berubah.
- Pengikatan file ini sengaja bersifat best-effort, bukan model semantik lengkap dari setiap
jalur loader interpreter/runtime. Jika mode persetujuan tidak dapat mengidentifikasi tepat satu
file lokal konkret untuk diikat, mode ini menolak membuat eksekusi berbasis persetujuan alih-alih berpura-pura memberikan cakupan penuh.
file lokal konkret untuk diikat, ia menolak membuat proses yang didukung persetujuan alih-alih berpura-pura cakupannya penuh.
Pemisahan macOS:
@ -64,11 +69,11 @@ Pemisahan macOS:
## Pengaturan dan penyimpanan
Approvals berada dalam file JSON lokal pada host eksekusi:
Approvals disimpan dalam file JSON lokal pada host eksekusi:
`~/.openclaw/exec-approvals.json`
Contoh schema:
Contoh skema:
```json
{
@ -107,10 +112,10 @@ Contoh schema:
Jika Anda ingin host exec berjalan tanpa prompt persetujuan, Anda harus membuka **kedua** lapisan kebijakan:
- kebijakan exec yang diminta di config OpenClaw (`tools.exec.*`)
- kebijakan exec yang diminta dalam konfigurasi OpenClaw (`tools.exec.*`)
- kebijakan approvals lokal host di `~/.openclaw/exec-approvals.json`
Ini sekarang merupakan perilaku host default kecuali Anda mengencangkannya secara eksplisit:
Sekarang ini adalah perilaku host default kecuali Anda memperketatnya secara eksplisit:
- `tools.exec.security`: `full` pada `gateway`/`node`
- `tools.exec.ask`: `off`
@ -118,15 +123,15 @@ Ini sekarang merupakan perilaku host default kecuali Anda mengencangkannya secar
Perbedaan penting:
- `tools.exec.host=auto` memilih lokasi eksekusi: sandbox jika tersedia, jika tidak gateway.
- YOLO memilih cara host exec disetujui: `security=full` plus `ask=off`.
- Dalam mode YOLO, OpenClaw tidak menambahkan gate persetujuan heuristik obfuscation perintah terpisah di atas kebijakan host exec yang dikonfigurasi.
- `auto` tidak menjadikan perutean gateway sebagai override gratis dari sesi yang disandbox. Permintaan `host=node` per panggilan diizinkan dari `auto`, dan `host=gateway` hanya diizinkan dari `auto` ketika tidak ada runtime sandbox yang aktif. Jika Anda ingin default non-auto yang stabil, setel `tools.exec.host` atau gunakan `/exec host=...` secara eksplisit.
- `tools.exec.host=auto` memilih tempat exec berjalan: sandbox bila tersedia, jika tidak gateway.
- YOLO memilih bagaimana host exec disetujui: `security=full` plus `ask=off`.
- Dalam mode YOLO, OpenClaw tidak menambahkan gerbang persetujuan pengaburan perintah heuristik yang terpisah di atas kebijakan host exec yang dikonfigurasi.
- `auto` tidak membuat perutean gateway menjadi override bebas dari sesi yang disandbox. Permintaan per panggilan `host=node` diizinkan dari `auto`, dan `host=gateway` hanya diizinkan dari `auto` ketika tidak ada runtime sandbox yang aktif. Jika Anda ingin default non-auto yang stabil, setel `tools.exec.host` atau gunakan `/exec host=...` secara eksplisit.
Jika Anda ingin penyiapan yang lebih konservatif, kencangkan salah satu lapisan kembali ke `allowlist` / `on-miss`
atau `deny`.
Penyiapan host gateway persisten "jangan pernah prompt":
Penyiapan host-gateway persisten "jangan pernah prompt":
```bash
openclaw config set tools.exec.host gateway
@ -150,6 +155,21 @@ openclaw approvals set --stdin <<'EOF'
EOF
```
Pintasan lokal untuk kebijakan host-gateway yang sama pada mesin saat ini:
```bash
openclaw exec-policy preset yolo
```
Pintasan lokal itu memperbarui keduanya:
- `tools.exec.host/security/ask` lokal
- default `~/.openclaw/exec-approvals.json` lokal
Ini sengaja hanya lokal. Jika Anda perlu mengubah approvals host-gateway atau host-node
secara remote, tetap gunakan `openclaw approvals set --gateway` atau
`openclaw approvals set --node <id|name|ip>`.
Untuk host node, terapkan file approvals yang sama pada node tersebut:
```bash
@ -165,14 +185,20 @@ openclaw approvals set --node <id|name|ip> --stdin <<'EOF'
EOF
```
Shortcut khusus sesi:
Batasan penting yang hanya berlaku lokal:
- `openclaw exec-policy` tidak menyinkronkan approvals node
- `openclaw exec-policy set --host node` ditolak
- persetujuan exec node diambil dari node saat runtime, jadi pembaruan yang menargetkan node harus menggunakan `openclaw approvals --node ...`
Pintasan sesi saja:
- `/exec security=full ask=off` hanya mengubah sesi saat ini.
- `/elevated full` adalah shortcut break-glass yang juga melewati persetujuan exec untuk sesi tersebut.
- `/elevated full` adalah pintasan break-glass yang juga melewati persetujuan exec untuk sesi itu.
Jika file approvals host tetap lebih ketat daripada config, kebijakan host yang lebih ketat tetap menang.
## Tombol kebijakan
## Kenop kebijakan
### Security (`exec.security`)
@ -182,14 +208,14 @@ Jika file approvals host tetap lebih ketat daripada config, kebijakan host yang
### Ask (`exec.ask`)
- **off**: jangan pernah memunculkan prompt.
- **on-miss**: munculkan prompt hanya ketika allowlist tidak cocok.
- **always**: munculkan prompt pada setiap perintah.
- **off**: jangan pernah prompt.
- **on-miss**: prompt hanya ketika allowlist tidak cocok.
- **always**: prompt pada setiap perintah.
- kepercayaan tahan lama `allow-always` tidak menekan prompt ketika mode ask efektif adalah `always`
### Ask fallback (`askFallback`)
Jika prompt diperlukan tetapi tidak ada UI yang dapat dijangkau, fallback menentukan:
Jika sebuah prompt diperlukan tetapi tidak ada UI yang dapat dijangkau, fallback menentukan:
- **deny**: blokir.
- **allowlist**: izinkan hanya jika allowlist cocok.
@ -197,7 +223,7 @@ Jika prompt diperlukan tetapi tidak ada UI yang dapat dijangkau, fallback menent
### Hardening eval interpreter inline (`tools.exec.strictInlineEval`)
Ketika `tools.exec.strictInlineEval=true`, OpenClaw memperlakukan bentuk eval kode inline sebagai hanya-bisa-dengan-persetujuan meskipun binary interpreter itu sendiri ada di allowlist.
Ketika `tools.exec.strictInlineEval=true`, OpenClaw memperlakukan bentuk eval kode inline sebagai hanya-bisa-dengan-persetujuan bahkan jika biner interpreter itu sendiri ada di allowlist.
Contoh:
@ -209,18 +235,18 @@ Contoh:
- `lua -e`
- `osascript -e`
Ini adalah pertahanan berlapis untuk loader interpreter yang tidak terpetakan dengan rapi ke satu operand file stabil. Dalam mode ketat:
Ini adalah defense-in-depth untuk loader interpreter yang tidak dipetakan dengan rapi ke satu operand file yang stabil. Dalam mode ketat:
- perintah-perintah ini tetap memerlukan persetujuan eksplisit;
- perintah ini tetap memerlukan persetujuan eksplisit;
- `allow-always` tidak otomatis mempertahankan entri allowlist baru untuk perintah tersebut.
## Allowlist (per agen)
Allowlist bersifat **per agen**. Jika ada beberapa agen, ganti agen yang sedang
Anda edit di aplikasi macOS. Pattern adalah **pencocokan glob case-insensitive**.
Pattern harus diselesaikan ke **path binary** (entri basename-only diabaikan).
Entri `agents.default` lama dimigrasikan ke `agents.main` saat dimuat.
Rantai shell seperti `echo ok && pwd` tetap memerlukan setiap segmen tingkat atas memenuhi aturan allowlist.
Allowlist bersifat **per agen**. Jika ada beberapa agen, pindahkan agen yang sedang Anda
edit di aplikasi macOS. Pola adalah **kecocokan glob tidak peka huruf besar-kecil**.
Pola harus diselesaikan menjadi **path biner** (entri yang hanya berupa basename diabaikan).
Entri lama `agents.default` dimigrasikan ke `agents.main` saat dimuat.
Rantai shell seperti `echo ok && pwd` tetap mengharuskan setiap segmen tingkat atas memenuhi aturan allowlist.
Contoh:
@ -231,42 +257,42 @@ Contoh:
Setiap entri allowlist melacak:
- **id** UUID stabil yang digunakan untuk identitas UI (opsional)
- **last used** timestamp
- **last used command**
- **last resolved path**
- **terakhir digunakan** timestamp
- **perintah terakhir digunakan**
- **path terakhir yang diselesaikan**
## Auto-allow Skills CLI
## Mengizinkan otomatis CLI skill
Ketika **Auto-allow Skills CLI** diaktifkan, executable yang dirujuk oleh Skills yang dikenal
diperlakukan seolah ada di allowlist pada node (node macOS atau host node headless). Fitur ini menggunakan
`skills.bins` melalui Gateway RPC untuk mengambil daftar bin skill. Nonaktifkan ini jika Anda ingin allowlist manual yang ketat.
Saat **Auto-allow skill CLIs** diaktifkan, executable yang dirujuk oleh Skills yang diketahui
diperlakukan sebagai ada di allowlist pada node (node macOS atau host node headless). Ini menggunakan
`skills.bins` melalui Gateway RPC untuk mengambil daftar bin skill. Nonaktifkan ini jika Anda menginginkan allowlist manual yang ketat.
Catatan kepercayaan penting:
- Ini adalah **allowlist kemudahan implisit**, terpisah dari entri allowlist path manual.
- Fitur ini ditujukan untuk lingkungan operator tepercaya di mana Gateway dan node berada dalam batas kepercayaan yang sama.
- Jika Anda memerlukan kepercayaan eksplisit yang ketat, biarkan `autoAllowSkills: false` dan gunakan hanya entri allowlist path manual.
- Ini dimaksudkan untuk lingkungan operator tepercaya tempat Gateway dan node berada dalam batas kepercayaan yang sama.
- Jika Anda memerlukan kepercayaan eksplisit yang ketat, pertahankan `autoAllowSkills: false` dan gunakan hanya entri allowlist path manual.
## Safe bins (stdin-only)
## Safe bins (khusus stdin)
`tools.exec.safeBins` mendefinisikan daftar kecil binary **stdin-only** (misalnya `cut`)
`tools.exec.safeBins` mendefinisikan daftar kecil biner **khusus stdin** (misalnya `cut`)
yang dapat berjalan dalam mode allowlist **tanpa** entri allowlist eksplisit. Safe bins menolak
arg file positional dan token mirip path, sehingga hanya dapat beroperasi pada stream masuk.
Perlakukan ini sebagai jalur cepat sempit untuk filter stream, bukan daftar kepercayaan umum.
**Jangan** tambahkan binary interpreter atau runtime (misalnya `python3`, `node`, `ruby`, `bash`, `sh`, `zsh`) ke `safeBins`.
Jika suatu perintah dapat mengevaluasi kode, menjalankan subperintah, atau membaca file secara desain, gunakan entri allowlist eksplisit dan biarkan prompt persetujuan tetap aktif.
Safe bin kustom harus mendefinisikan profil eksplisit di `tools.exec.safeBinProfiles.<bin>`.
argumen file posisional dan token mirip path, sehingga hanya dapat beroperasi pada stream masuk.
Anggap ini sebagai jalur cepat sempit untuk filter stream, bukan daftar kepercayaan umum.
**Jangan** tambahkan biner interpreter atau runtime (misalnya `python3`, `node`, `ruby`, `bash`, `sh`, `zsh`) ke `safeBins`.
Jika sebuah perintah dapat mengevaluasi kode, mengeksekusi subperintah, atau membaca file secara desain, pilih entri allowlist eksplisit dan biarkan prompt persetujuan tetap aktif.
Safe bins kustom harus mendefinisikan profil eksplisit di `tools.exec.safeBinProfiles.<bin>`.
Validasi bersifat deterministik hanya dari bentuk argv (tanpa pemeriksaan keberadaan filesystem host), yang
mencegah perilaku oracle keberadaan file dari perbedaan allow/deny.
Opsi berorientasi file ditolak untuk safe bin default (misalnya `sort -o`, `sort --output`,
Opsi yang berorientasi file ditolak untuk safe bins default (misalnya `sort -o`, `sort --output`,
`sort --files0-from`, `sort --compress-program`, `sort --random-source`,
`sort --temporary-directory`/`-T`, `wc --files0-from`, `jq -f/--from-file`,
`grep -f/--file`).
Safe bins juga menegakkan kebijakan flag per-binary yang eksplisit untuk opsi yang merusak perilaku stdin-only
(misalnya `sort -o/--output/--compress-program` dan flag rekursif grep).
Opsi panjang divalidasi fail-closed dalam mode safe-bin: flag yang tidak dikenal dan singkatan
ambigu ditolak.
Flag yang ditolak oleh profil safe-bin:
Safe bins juga menegakkan kebijakan flag per biner yang eksplisit untuk opsi yang merusak perilaku
khusus stdin (misalnya `sort -o/--output/--compress-program` dan flag rekursif grep).
Opsi panjang divalidasi fail-closed dalam mode safe-bin: flag yang tidak dikenal dan
singkatan ambigu ditolak.
Flag yang ditolak menurut profil safe-bin:
[//]: # "SAFE_BIN_DENIED_FLAGS:START"
@ -278,33 +304,33 @@ Flag yang ditolak oleh profil safe-bin:
[//]: # "SAFE_BIN_DENIED_FLAGS:END"
Safe bins juga memaksa token argv diperlakukan sebagai **teks literal** pada waktu eksekusi (tanpa globbing
dan tanpa ekspansi `$VARS`) untuk segmen stdin-only, sehingga pola seperti `*` atau `$HOME/...` tidak dapat
dan tanpa ekspansi `$VARS`) untuk segmen khusus stdin, sehingga pola seperti `*` atau `$HOME/...` tidak bisa
digunakan untuk menyelundupkan pembacaan file.
Safe bins juga harus diselesaikan dari direktori binary tepercaya (default sistem plus opsi
`tools.exec.safeBinTrustedDirs`). Entri `PATH` tidak pernah otomatis dipercaya.
Direktori safe-bin tepercaya default sengaja dibuat minimal: `/bin`, `/usr/bin`.
Safe bins juga harus diselesaikan dari direktori biner tepercaya (default sistem ditambah
`tools.exec.safeBinTrustedDirs` opsional). Entri `PATH` tidak pernah otomatis dipercaya.
Direktori safe-bin tepercaya bawaan sengaja dibuat minimal: `/bin`, `/usr/bin`.
Jika executable safe-bin Anda berada di path package-manager/pengguna (misalnya
`/opt/homebrew/bin`, `/usr/local/bin`, `/opt/local/bin`, `/snap/bin`), tambahkan secara eksplisit
ke `tools.exec.safeBinTrustedDirs`.
Rantai shell dan redirection tidak otomatis diizinkan dalam mode allowlist.
Rantai shell (`&&`, `||`, `;`) diizinkan ketika setiap segmen tingkat atas memenuhi allowlist
(termasuk safe bins atau auto-allow skill). Redirection tetap tidak didukung dalam mode allowlist.
Substitusi perintah (`$()` / backticks) ditolak selama parsing allowlist, termasuk di dalam
tanda kutip ganda; gunakan tanda kutip tunggal jika Anda memerlukan teks `$()` literal.
(termasuk safe bins atau skill auto-allow). Redirection tetap tidak didukung dalam mode allowlist.
Substitusi perintah (`$()` / backtick) ditolak selama parsing allowlist, termasuk di dalam
tanda kutip ganda; gunakan tanda kutip tunggal jika Anda membutuhkan teks literal `$()`.
Pada approvals aplikasi pendamping macOS, teks shell mentah yang berisi sintaks kontrol atau ekspansi shell
(`&&`, `||`, `;`, `|`, `` ` ``, `$`, `<`, `>`, `(`, `)`) diperlakukan sebagai allowlist miss kecuali
binary shell itu sendiri ada di allowlist.
Untuk wrapper shell (`bash|sh|zsh ... -c/-lc`), override env dengan cakupan permintaan dikurangi menjadi
allowlist kecil yang eksplisit (`TERM`, `LANG`, `LC_*`, `COLORTERM`, `NO_COLOR`, `FORCE_COLOR`).
Untuk keputusan allow-always dalam mode allowlist, wrapper dispatch yang dikenal
(`env`, `nice`, `nohup`, `stdbuf`, `timeout`) mempertahankan path executable bagian dalam alih-alih
path wrapper. Multiplexer shell (`busybox`, `toybox`) juga dibuka untuk applet shell (`sh`, `ash`,
dll.) sehingga executable bagian dalam dipertahankan alih-alih binary multiplexer. Jika wrapper atau
multiplexer tidak dapat dibuka dengan aman, tidak ada entri allowlist yang dipertahankan secara otomatis.
Jika Anda memasukkan interpreter seperti `python3` atau `node` ke allowlist, gunakan `tools.exec.strictInlineEval=true` agar eval inline tetap memerlukan persetujuan eksplisit. Dalam mode ketat, `allow-always` tetap dapat mempertahankan invokasi interpreter/script yang aman, tetapi carrier inline-eval tidak dipertahankan secara otomatis.
biner shell itu sendiri ada di allowlist.
Untuk wrapper shell (`bash|sh|zsh ... -c/-lc`), override env dalam cakupan permintaan dikurangi menjadi
allowlist eksplisit kecil (`TERM`, `LANG`, `LC_*`, `COLORTERM`, `NO_COLOR`, `FORCE_COLOR`).
Untuk keputusan allow-always dalam mode allowlist, wrapper dispatch yang diketahui
(`env`, `nice`, `nohup`, `stdbuf`, `timeout`) menyimpan path executable bagian dalam alih-alih
path wrapper. Shell multiplexer (`busybox`, `toybox`) juga di-unwrapped untuk applet shell (`sh`, `ash`,
dll.) sehingga executable bagian dalam disimpan alih-alih biner multiplexer. Jika sebuah wrapper atau
multiplexer tidak dapat di-unwrapped dengan aman, tidak ada entri allowlist yang disimpan secara otomatis.
Jika Anda memasukkan interpreter seperti `python3` atau `node` ke allowlist, sebaiknya gunakan `tools.exec.strictInlineEval=true` agar eval inline tetap memerlukan persetujuan eksplisit. Dalam mode ketat, `allow-always` tetap dapat menyimpan pemanggilan interpreter/skrip yang aman, tetapi carrier inline-eval tidak disimpan secara otomatis.
Safe bin default:
Safe bins bawaan:
[//]: # "SAFE_BIN_DEFAULTS:START"
@ -312,96 +338,98 @@ Safe bin default:
[//]: # "SAFE_BIN_DEFAULTS:END"
`grep` dan `sort` tidak ada dalam daftar default. Jika Anda memilih ikut serta, pertahankan entri allowlist eksplisit untuk
alur non-stdin keduanya.
Untuk `grep` dalam mode safe-bin, berikan pola dengan `-e`/`--regexp`; bentuk pola positional
ditolak agar operand file tidak dapat diselundupkan sebagai positional yang ambigu.
`grep` dan `sort` tidak termasuk dalam daftar bawaan. Jika Anda memilih untuk mengaktifkannya, pertahankan entri allowlist eksplisit untuk
alur kerja non-stdin keduanya.
Untuk `grep` dalam mode safe-bin, berikan pola dengan `-e`/`--regexp`; bentuk pola posisional
ditolak agar operand file tidak bisa diselundupkan sebagai posisional yang ambigu.
### Safe bins versus allowlist
| Topik | `tools.exec.safeBins` | Allowlist (`exec-approvals.json`) |
| Topik | `tools.exec.safeBins` | Allowlist (`exec-approvals.json`) |
| ---------------- | ------------------------------------------------------ | ------------------------------------------------------------ |
| Tujuan | Auto-allow filter stdin sempit | Secara eksplisit mempercayai executable tertentu |
| Jenis pencocokan | Nama executable + kebijakan argv safe-bin | Pola glob path executable yang diselesaikan |
| Cakupan argumen | Dibatasi oleh profil safe-bin dan aturan token literal | Hanya pencocokan path; argumen selain itu menjadi tanggung jawab Anda |
| Contoh umum | `head`, `tail`, `tr`, `wc` | `jq`, `python3`, `node`, `ffmpeg`, CLI kustom |
| Penggunaan terbaik | Transformasi teks berisiko rendah dalam pipeline | Tool apa pun dengan perilaku atau efek samping yang lebih luas |
| Tujuan | Mengizinkan otomatis filter stdin sempit | Secara eksplisit mempercayai executable tertentu |
| Jenis kecocokan | Nama executable + kebijakan argv safe-bin | Pola glob path executable yang diselesaikan |
| Cakupan argumen | Dibatasi oleh profil safe-bin dan aturan token literal | Hanya kecocokan path; argumen selain itu menjadi tanggung jawab Anda |
| Contoh umum | `head`, `tail`, `tr`, `wc` | `jq`, `python3`, `node`, `ffmpeg`, CLI kustom |
| Penggunaan terbaik | Transformasi teks berisiko rendah dalam pipeline | Alat apa pun dengan perilaku atau efek samping yang lebih luas |
Lokasi konfigurasi:
- `safeBins` berasal dari config (`tools.exec.safeBins` atau per-agen `agents.list[].tools.exec.safeBins`).
- `safeBinTrustedDirs` berasal dari config (`tools.exec.safeBinTrustedDirs` atau per-agen `agents.list[].tools.exec.safeBinTrustedDirs`).
- `safeBinProfiles` berasal dari config (`tools.exec.safeBinProfiles` atau per-agen `agents.list[].tools.exec.safeBinProfiles`). Key per-agen menimpa key global.
- `safeBins` berasal dari config (`tools.exec.safeBins` atau per-agent `agents.list[].tools.exec.safeBins`).
- `safeBinTrustedDirs` berasal dari config (`tools.exec.safeBinTrustedDirs` atau per-agent `agents.list[].tools.exec.safeBinTrustedDirs`).
- `safeBinProfiles` berasal dari config (`tools.exec.safeBinProfiles` atau per-agent `agents.list[].tools.exec.safeBinProfiles`). Kunci profil per-agent menimpa kunci global.
- entri allowlist berada di `~/.openclaw/exec-approvals.json` lokal host di bawah `agents.<id>.allowlist` (atau melalui Control UI / `openclaw approvals allowlist ...`).
- `openclaw security audit` memperingatkan dengan `tools.exec.safe_bins_interpreter_unprofiled` ketika bin interpreter/runtime muncul di `safeBins` tanpa profil eksplisit.
- `openclaw doctor --fix` dapat membuat scaffold entri `safeBinProfiles.<bin>` kustom yang hilang sebagai `{}` (tinjau dan kencangkan setelahnya). Bin interpreter/runtime tidak dibuat scaffold secara otomatis.
- `openclaw security audit` memberi peringatan dengan `tools.exec.safe_bins_interpreter_unprofiled` ketika bin interpreter/runtime muncul di `safeBins` tanpa profil eksplisit.
- `openclaw doctor --fix` dapat membuatkan entri `safeBinProfiles.<bin>` kustom yang hilang sebagai `{}` (tinjau dan perketat setelahnya). Bin interpreter/runtime tidak dibuatkan otomatis.
Contoh profil kustom:
__OC_I18N_900004__
Jika Anda secara eksplisit memasukkan `jq` ke `safeBins`, OpenClaw tetap menolak builtin `env` dalam mode safe-bin
agar `jq -n env` tidak dapat membuang environment proses host tanpa path allowlist eksplisit
__OC_I18N_900005__
Jika Anda secara eksplisit memilih `jq` ke dalam `safeBins`, OpenClaw tetap menolak builtin `env` dalam mode safe-bin
sehingga `jq -n env` tidak dapat membuang environment proses host tanpa path allowlist eksplisit
atau prompt persetujuan.
## Pengeditan Control UI
Gunakan kartu **Control UI → Nodes → Exec approvals** untuk mengedit default, override per agen,
dan allowlist. Pilih scope (Defaults atau agen), ubah kebijakan,
tambahkan/hapus pattern allowlist, lalu **Save**. UI menampilkan metadata **last used**
per pattern agar daftar tetap rapi.
Gunakan kartu **Control UI → Nodes → Exec approvals** untuk mengedit default, override
per-agent, dan allowlist. Pilih cakupan (Defaults atau agen), sesuaikan kebijakan,
tambah/hapus pola allowlist, lalu **Save**. UI menampilkan metadata **terakhir digunakan**
per pola sehingga Anda dapat menjaga daftar tetap rapi.
Pemilih target memilih **Gateway** (approvals lokal) atau **Node**. Node
harus mengiklankan `system.execApprovals.get/set` (aplikasi macOS atau host node headless).
Jika suatu node belum mengiklankan exec approvals, edit
Jika sebuah node belum mengiklankan exec approvals, edit
`~/.openclaw/exec-approvals.json` lokalnya secara langsung.
CLI: `openclaw approvals` mendukung pengeditan gateway atau node (lihat [Approvals CLI](/cli/approvals)).
## Alur persetujuan
Ketika prompt diperlukan, gateway menyiarkan `exec.approval.requested` ke klien operator.
Ketika sebuah prompt diperlukan, gateway menyiarkan `exec.approval.requested` ke klien operator.
Control UI dan aplikasi macOS menyelesaikannya melalui `exec.approval.resolve`, lalu gateway meneruskan
permintaan yang disetujui ke host node.
Untuk `host=node`, permintaan persetujuan menyertakan payload `systemRunPlan` kanonis. Gateway menggunakan
rencana itu sebagai konteks otoritatif untuk perintah/cwd/sesi saat meneruskan permintaan `system.run`
rencana itu sebagai konteks perintah/cwd/sesi yang otoritatif saat meneruskan permintaan `system.run`
yang disetujui.
Ini penting untuk latensi persetujuan async:
Itu penting untuk latensi persetujuan asinkron:
- jalur exec node menyiapkan satu rencana kanonis di awal
- catatan persetujuan menyimpan rencana itu dan metadata binding-nya
- setelah disetujui, panggilan `system.run` akhir yang diteruskan menggunakan kembali rencana yang disimpan
alih-alih mempercayai edit pemanggil yang datang belakangan
- catatan persetujuan menyimpan rencana itu dan metadata pengikatannya
- setelah disetujui, pemanggilan `system.run` akhir yang diteruskan menggunakan kembali rencana yang tersimpan
alih-alih mempercayai edit pemanggil yang dilakukan belakangan
- jika pemanggil mengubah `command`, `rawCommand`, `cwd`, `agentId`, atau
`sessionKey` setelah permintaan persetujuan dibuat, gateway menolak
eksekusi yang diteruskan sebagai ketidakcocokan persetujuan
proses yang diteruskan sebagai ketidakcocokan persetujuan
## Perintah interpreter/runtime
Eksekusi interpreter/runtime berbasis persetujuan sengaja bersifat konservatif:
Proses interpreter/runtime yang didukung persetujuan sengaja dibuat konservatif:
- Konteks argv/cwd/env yang persis selalu diikat.
- Bentuk shell script langsung dan file runtime langsung diikat secara best-effort ke satu snapshot file lokal konkret.
- Bentuk wrapper package-manager umum yang tetap diselesaikan ke satu file lokal langsung (misalnya
`pnpm exec`, `pnpm node`, `npm exec`, `npx`) dibuka sebelum binding.
- Konteks argv/cwd/env yang tepat selalu diikat.
- Bentuk skrip shell langsung dan file runtime langsung diikat secara best-effort ke satu snapshot
file lokal konkret.
- Bentuk wrapper package-manager umum yang tetap diselesaikan menjadi satu file lokal langsung (misalnya
`pnpm exec`, `pnpm node`, `npm exec`, `npx`) di-unwrapped sebelum pengikatan.
- Jika OpenClaw tidak dapat mengidentifikasi tepat satu file lokal konkret untuk perintah interpreter/runtime
(misalnya package script, bentuk eval, rantai loader khusus runtime, atau bentuk multi-file ambigu),
eksekusi berbasis persetujuan ditolak alih-alih mengklaim cakupan semantik yang sebenarnya tidak ada.
- Untuk alur kerja tersebut, gunakan sandboxing, batas host terpisah, atau alur trusted
allowlist/full eksplisit di mana operator menerima semantik runtime yang lebih luas.
(misalnya skrip package, bentuk eval, rantai loader khusus runtime, atau bentuk multi-file yang ambigu),
eksekusi yang didukung persetujuan ditolak alih-alih mengklaim cakupan semantik yang sebenarnya tidak
dimilikinya.
- Untuk alur kerja tersebut, pilih sandboxing, batas host terpisah, atau alur allowlist/full tepercaya
yang eksplisit ketika operator menerima semantik runtime yang lebih luas.
Ketika persetujuan diperlukan, tool exec segera mengembalikan approval id. Gunakan id itu untuk
mengaitkan event sistem berikutnya (`Exec finished` / `Exec denied`). Jika tidak ada keputusan yang datang sebelum
timeout, permintaan diperlakukan sebagai approval timeout dan ditampilkan sebagai alasan penolakan.
Ketika persetujuan diperlukan, alat exec langsung mengembalikan ID persetujuan. Gunakan ID itu untuk
mengorelasikan peristiwa sistem berikutnya (`Exec finished` / `Exec denied`). Jika tidak ada keputusan yang datang sebelum
timeout, permintaan diperlakukan sebagai timeout persetujuan dan ditampilkan sebagai alasan penolakan.
### Perilaku pengiriman tindak lanjut
### Perilaku pengiriman followup
Setelah exec async yang disetujui selesai, OpenClaw mengirim giliran `agent` tindak lanjut ke sesi yang sama.
Setelah exec asinkron yang disetujui selesai, OpenClaw mengirim giliran `agent` followup ke sesi yang sama.
- Jika ada target pengiriman eksternal yang valid (channel yang dapat dikirim plus target `to`), pengiriman tindak lanjut menggunakan channel itu.
- Dalam alur khusus webchat atau sesi internal tanpa target eksternal, pengiriman tindak lanjut tetap hanya sesi (`deliver: false`).
- Jika ada target pengiriman eksternal yang valid (channel dapat dikirim plus target `to`), pengiriman followup menggunakan channel itu.
- Dalam alur khusus webchat atau sesi internal tanpa target eksternal, pengiriman followup tetap khusus sesi (`deliver: false`).
- Jika pemanggil secara eksplisit meminta pengiriman eksternal ketat tanpa channel eksternal yang dapat diselesaikan, permintaan gagal dengan `INVALID_REQUEST`.
- Jika `bestEffortDeliver` diaktifkan dan tidak ada channel eksternal yang dapat diselesaikan, pengiriman diturunkan menjadi hanya sesi alih-alih gagal.
- Jika `bestEffortDeliver` diaktifkan dan tidak ada channel eksternal yang dapat diselesaikan, pengiriman diturunkan menjadi khusus sesi alih-alih gagal.
Dialog konfirmasi mencakup:
@ -409,48 +437,47 @@ Dialog konfirmasi mencakup:
- cwd
- ID agen
- path executable yang diselesaikan
- host + metadata kebijakan
- metadata host + kebijakan
Aksi:
Tindakan:
- **Allow once** → jalankan sekarang
- **Always allow** → tambahkan ke allowlist + jalankan
- **Deny** → blokir
## Penerusan persetujuan ke chat channel
## Penerusan persetujuan ke channel chat
Anda dapat meneruskan prompt persetujuan exec ke chat channel mana pun (termasuk plugin channel) dan menyetujuinya
Anda dapat meneruskan prompt persetujuan exec ke channel chat mana pun (termasuk channel plugin) dan menyetujuinya
dengan `/approve`. Ini menggunakan pipeline pengiriman keluar normal.
Config:
__OC_I18N_900005__
Balas di chat:
__OC_I18N_900006__
Balas di chat:
__OC_I18N_900007__
Perintah `/approve` menangani persetujuan exec dan persetujuan plugin. Jika ID tidak cocok dengan persetujuan exec yang tertunda, perintah ini otomatis memeriksa persetujuan plugin sebagai gantinya.
### Penerusan persetujuan plugin
Penerusan persetujuan plugin menggunakan pipeline pengiriman yang sama seperti persetujuan exec tetapi memiliki
config independen sendiri di bawah `approvals.plugin`. Mengaktifkan atau menonaktifkan salah satunya tidak memengaruhi yang lain.
__OC_I18N_900007__
Penerusan persetujuan plugin menggunakan pipeline pengiriman yang sama dengan persetujuan exec tetapi memiliki
config independennya sendiri di bawah `approvals.plugin`. Mengaktifkan atau menonaktifkan salah satunya tidak memengaruhi yang lain.
__OC_I18N_900008__
Bentuk config identik dengan `approvals.exec`: `enabled`, `mode`, `agentFilter`,
`sessionFilter`, dan `targets` bekerja dengan cara yang sama.
Channel yang mendukung balasan interaktif bersama merender tombol persetujuan yang sama untuk persetujuan exec dan
Channel yang mendukung balasan interaktif bersama menampilkan tombol persetujuan yang sama untuk persetujuan exec maupun
plugin. Channel tanpa UI interaktif bersama akan fallback ke teks biasa dengan instruksi `/approve`.
### Persetujuan di chat yang sama pada channel mana pun
### Persetujuan chat yang sama di channel mana pun
Ketika permintaan persetujuan exec atau plugin berasal dari permukaan chat yang dapat dikirim, chat yang sama
kini dapat menyetujuinya dengan `/approve` secara default. Ini berlaku untuk channel seperti Slack, Matrix, dan
Microsoft Teams selain alur Web UI dan UI terminal yang sudah ada.
sekarang dapat menyetujuinya dengan `/approve` secara default. Ini berlaku untuk channel seperti Slack, Matrix, dan
Microsoft Teams selain alur Web UI dan terminal UI yang sudah ada.
Jalur perintah teks bersama ini menggunakan model auth channel normal untuk percakapan tersebut. Jika
chat asal sudah dapat mengirim perintah dan menerima balasan, permintaan persetujuan tidak lagi memerlukan
adapter pengiriman native terpisah hanya agar dapat tetap tertunda.
Jalur perintah teks bersama ini menggunakan model autentikasi channel normal untuk percakapan tersebut. Jika chat
asal sudah dapat mengirim perintah dan menerima balasan, permintaan persetujuan tidak lagi memerlukan adaptor pengiriman native terpisah hanya agar tetap tertunda.
Discord dan Telegram juga mendukung `/approve` di chat yang sama, tetapi channel tersebut tetap menggunakan
daftar approver yang telah diselesaikan untuk otorisasi meskipun pengiriman persetujuan native dinonaktifkan.
daftar approver yang telah diselesaikan untuk otorisasi bahkan ketika pengiriman persetujuan native dinonaktifkan.
Untuk Telegram dan klien persetujuan native lain yang memanggil Gateway secara langsung,
fallback ini sengaja dibatasi pada kegagalan "approval not found". Penolakan/error
@ -459,63 +486,63 @@ persetujuan exec yang nyata tidak diam-diam dicoba ulang sebagai persetujuan plu
### Pengiriman persetujuan native
Beberapa channel juga dapat bertindak sebagai klien persetujuan native. Klien native menambahkan DM approver, fanout chat asal,
dan UX persetujuan interaktif khusus channel di atas alur `/approve` chat-sama bersama.
dan UX persetujuan interaktif khusus channel di atas alur `/approve` chat yang sama bersama.
Ketika kartu/tombol persetujuan native tersedia, UI native tersebut menjadi jalur
utama yang dihadapi agen. Agen tidak seharusnya juga menggemakan perintah chat biasa
`/approve` duplikat kecuali hasil tool menyatakan persetujuan chat tidak tersedia atau
Ketika kartu/tombol persetujuan native tersedia, UI native tersebut menjadi jalur utama
yang dihadapi agen. Agen tidak boleh juga menggemakan perintah chat plain
`/approve` yang duplikat kecuali hasil alat menyatakan persetujuan chat tidak tersedia atau
persetujuan manual adalah satu-satunya jalur yang tersisa.
Model generik:
- kebijakan host exec tetap memutuskan apakah persetujuan exec diperlukan
- kebijakan host exec tetap menentukan apakah persetujuan exec diperlukan
- `approvals.exec` mengontrol penerusan prompt persetujuan ke tujuan chat lain
- `channels.<channel>.execApprovals` mengontrol apakah channel tersebut bertindak sebagai klien persetujuan native
Klien persetujuan native secara otomatis mengaktifkan pengiriman DM-first ketika semua kondisi berikut terpenuhi:
- channel mendukung pengiriman persetujuan native
- approver dapat diselesaikan dari `execApprovals.approvers` eksplisit atau sumber fallback terdokumentasi
milik channel tersebut
- approver dapat diselesaikan dari `execApprovals.approvers` yang eksplisit atau dari sumber fallback terdokumentasi channel tersebut
- `channels.<channel>.execApprovals.enabled` tidak disetel atau bernilai `"auto"`
Setel `enabled: false` untuk menonaktifkan klien persetujuan native secara eksplisit. Setel `enabled: true` untuk memaksanya
aktif ketika approver dapat diselesaikan. Pengiriman chat asal publik tetap eksplisit melalui
aktif ketika approver berhasil diselesaikan. Pengiriman public origin-chat tetap harus diatur secara eksplisit melalui
`channels.<channel>.execApprovals.target`.
FAQ: [Mengapa ada dua config persetujuan exec untuk persetujuan chat?](/help/faq#why-are-there-two-exec-approval-configs-for-chat-approvals)
FAQ: [Mengapa ada dua konfigurasi persetujuan exec untuk persetujuan chat?](/help/faq#why-are-there-two-exec-approval-configs-for-chat-approvals)
- Discord: `channels.discord.execApprovals.*`
- Slack: `channels.slack.execApprovals.*`
- Telegram: `channels.telegram.execApprovals.*`
Klien persetujuan native ini menambahkan perutean DM dan fanout channel opsional di atas alur
`/approve` chat-sama bersama dan tombol persetujuan bersama.
`/approve` chat yang sama bersama dan tombol persetujuan bersama.
Perilaku bersama:
- Slack, Matrix, Microsoft Teams, dan chat serupa yang dapat dikirim menggunakan model auth channel normal
untuk `/approve` chat-sama
- Slack, Matrix, Microsoft Teams, dan chat lain yang dapat dikirim menggunakan model autentikasi channel normal
untuk `/approve` di chat yang sama
- ketika klien persetujuan native aktif otomatis, target pengiriman native default adalah DM approver
- untuk Discord dan Telegram, hanya approver yang telah diselesaikan yang dapat menyetujui atau menolak
- approver Discord dapat eksplisit (`execApprovals.approvers`) atau disimpulkan dari `commands.ownerAllowFrom`
- approver Telegram dapat eksplisit (`execApprovals.approvers`) atau disimpulkan dari config owner yang ada (`allowFrom`, plus `defaultTo` direct-message bila didukung)
- approver Slack dapat eksplisit (`execApprovals.approvers`) atau disimpulkan dari `commands.ownerAllowFrom`
- tombol native Slack mempertahankan jenis approval id, sehingga ID `plugin:` dapat menyelesaikan persetujuan plugin
- untuk Discord dan Telegram, hanya approver yang berhasil diselesaikan yang dapat menyetujui atau menolak
- approver Discord dapat bersifat eksplisit (`execApprovals.approvers`) atau diinferensikan dari `commands.ownerAllowFrom`
- approver Telegram dapat bersifat eksplisit (`execApprovals.approvers`) atau diinferensikan dari konfigurasi owner yang ada (`allowFrom`, ditambah direct-message `defaultTo` bila didukung)
- approver Slack dapat bersifat eksplisit (`execApprovals.approvers`) atau diinferensikan dari `commands.ownerAllowFrom`
- tombol native Slack mempertahankan jenis approval ID, sehingga ID `plugin:` dapat menyelesaikan persetujuan plugin
tanpa lapisan fallback lokal Slack kedua
- perutean DM/channel native Matrix dan shortcut reaction menangani persetujuan exec dan plugin;
- perutean DM/channel native Matrix dan pintasan reaction menangani persetujuan exec maupun plugin;
otorisasi plugin tetap berasal dari `channels.matrix.dm.allowFrom`
- peminta tidak harus menjadi approver
- chat asal dapat menyetujui secara langsung dengan `/approve` ketika chat tersebut sudah mendukung perintah dan balasan
- tombol persetujuan native Discord merutekan berdasarkan jenis approval id: ID `plugin:` langsung menuju
- chat asal dapat menyetujui langsung dengan `/approve` ketika chat itu sudah mendukung perintah dan balasan
- tombol persetujuan native Discord merutekan berdasarkan jenis approval ID: ID `plugin:` langsung menuju
persetujuan plugin, selebihnya menuju persetujuan exec
- tombol persetujuan native Telegram mengikuti fallback exec-ke-plugin terbatas yang sama seperti `/approve`
- ketika `target` native mengaktifkan pengiriman chat asal, prompt persetujuan menyertakan teks perintah
- persetujuan exec tertunda kedaluwarsa setelah 30 menit secara default
- jika tidak ada UI operator atau klien persetujuan yang dikonfigurasi yang dapat menerima permintaan, prompt akan fallback ke `askFallback`
- ketika `target` native mengaktifkan pengiriman origin-chat, prompt persetujuan menyertakan teks perintah
- persetujuan exec yang tertunda kedaluwarsa setelah 30 menit secara default
- jika tidak ada UI operator atau klien persetujuan terkonfigurasi yang dapat menerima permintaan, prompt akan fallback ke `askFallback`
Telegram default-nya ke DM approver (`target: "dm"`). Anda dapat beralih ke `channel` atau `both` ketika Anda
ingin prompt persetujuan muncul di chat/topik Telegram asal juga. Untuk topik forum Telegram, OpenClaw mempertahankan topik untuk prompt persetujuan dan tindak lanjut pasca-persetujuan.
Telegram default ke DM approver (`target: "dm"`). Anda dapat beralih ke `channel` atau `both` saat
ingin prompt persetujuan juga muncul di chat/topik Telegram asal. Untuk topik forum Telegram,
OpenClaw mempertahankan topik tersebut untuk prompt persetujuan dan follow-up pasca-persetujuan.
Lihat:
@ -523,50 +550,51 @@ Lihat:
- [Telegram](/channels/telegram)
### Alur IPC macOS
__OC_I18N_900008__
__OC_I18N_900009__
Catatan keamanan:
- Mode Unix socket `0600`, token disimpan di `exec-approvals.json`.
- Pemeriksaan peer dengan UID yang sama.
- Challenge/response (nonce + token HMAC + hash permintaan) + TTL pendek.
## Event sistem
## Peristiwa sistem
Siklus hidup exec ditampilkan sebagai pesan sistem:
- `Exec running` (hanya jika perintah melewati ambang pemberitahuan running)
- `Exec running` (hanya jika perintah melebihi ambang notifikasi berjalan)
- `Exec finished`
- `Exec denied`
Pesan ini diposting ke sesi agen setelah node melaporkan event tersebut.
Persetujuan exec host gateway memunculkan event siklus hidup yang sama ketika perintah selesai (dan opsional ketika berjalan lebih lama dari ambang).
Exec yang digating persetujuan menggunakan kembali approval id sebagai `runId` dalam pesan ini untuk korelasi yang mudah.
Pesan-pesan ini diposting ke sesi agen setelah node melaporkan peristiwanya.
Persetujuan exec host-gateway mengirim peristiwa siklus hidup yang sama ketika perintah selesai (dan secara opsional ketika berjalan lebih lama dari ambang batas).
Exec yang digating dengan persetujuan menggunakan kembali approval ID sebagai `runId` dalam pesan-pesan ini agar mudah dikorelasikan.
## Perilaku persetujuan yang ditolak
Ketika persetujuan exec async ditolak, OpenClaw mencegah agen menggunakan kembali
output dari eksekusi sebelumnya untuk perintah yang sama di dalam sesi. Alasan penolakan
Ketika persetujuan exec asinkron ditolak, OpenClaw mencegah agen menggunakan kembali
output dari proses sebelumnya dari perintah yang sama dalam sesi. Alasan penolakan
diteruskan dengan panduan eksplisit bahwa tidak ada output perintah yang tersedia, yang menghentikan
agen dari mengklaim ada output baru atau mengulangi perintah yang ditolak dengan hasil basi dari eksekusi berhasil sebelumnya.
agen dari mengklaim ada output baru atau mengulangi perintah yang ditolak dengan
hasil lama dari proses sukses sebelumnya.
## Implikasi
- **full** sangat kuat; gunakan allowlist bila memungkinkan.
- **full** sangat kuat; pilih allowlist bila memungkinkan.
- **ask** membuat Anda tetap terlibat sambil tetap memungkinkan persetujuan cepat.
- Allowlist per agen mencegah persetujuan satu agen bocor ke agen lain.
- Persetujuan hanya berlaku untuk permintaan host exec dari **pengirim yang diautentikasi**. Pengirim yang tidak diautentikasi tidak dapat mengeluarkan `/exec`.
- `/exec security=full` adalah kemudahan tingkat sesi untuk operator yang diautentikasi dan secara desain melewati persetujuan.
Untuk memblokir penuh host exec, setel security approvals ke `deny` atau tolak tool `exec` melalui kebijakan tool.
- Persetujuan hanya berlaku untuk permintaan host exec dari **pengirim yang berwenang**. Pengirim yang tidak berwenang tidak dapat mengeluarkan `/exec`.
- `/exec security=full` adalah kemudahan tingkat sesi untuk operator yang berwenang dan secara desain melewati persetujuan.
Untuk memblokir host exec sepenuhnya, setel security approvals ke `deny` atau tolak alat `exec` melalui kebijakan alat.
Terkait:
- [Tool exec](/id/tools/exec)
- [Mode elevated](/id/tools/elevated)
- [Exec tool](/id/tools/exec)
- [Elevated mode](/id/tools/elevated)
- [Skills](/id/tools/skills)
## Terkait
- [Exec](/id/tools/exec) — tool eksekusi perintah shell
- [Exec](/id/tools/exec) — alat eksekusi perintah shell
- [Sandboxing](/id/gateway/sandboxing) — mode sandbox dan akses workspace
- [Security](/id/gateway/security) — model keamanan dan hardening
- [Sandbox vs Tool Policy vs Elevated](/id/gateway/sandbox-vs-tool-policy-vs-elevated) — kapan menggunakan masing-masing