chore(i18n): refresh id translations
This commit is contained in:
parent
84ad3b85d6
commit
e865b7a21f
@ -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
|
||||
|
||||
612
docs/id/concepts/active-memory.md
Normal file
612
docs/id/concepts/active-memory.md
Normal 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)
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
@ -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`.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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 **18800–18899** 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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user