chore(i18n): refresh id translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-16 09:16:43 +00:00
parent 40eb955644
commit 0f8bd7fe3d
5 changed files with 874 additions and 531 deletions

View File

@ -3,34 +3,34 @@ read_when:
- Anda ingin memahami untuk apa Active Memory digunakan
- Anda ingin mengaktifkan Active Memory untuk agen percakapan
- Anda ingin menyesuaikan perilaku Active Memory tanpa mengaktifkannya di semua tempat
summary: Sub-agen memori pemblokiran milik Plugin yang menyuntikkan memori yang relevan ke dalam sesi obrolan interaktif
summary: Sub-agen memori pemblokiran milik Plugin yang menyuntikkan memori yang relevan ke dalam sesi chat interaktif
title: Active Memory
x-i18n:
generated_at: "2026-04-14T02:08:42Z"
generated_at: "2026-04-16T09:14:37Z"
model: gpt-5.4
provider: openai
source_hash: b151e9eded7fc5c37e00da72d95b24c1dc94be22e855c8875f850538392b0637
source_hash: ab36c5fea1578348cc2258ea3b344cc7bdc814f337d659cdb790512b3ea45473
source_path: concepts/active-memory.md
workflow: 15
---
# Active Memory
Active Memory adalah sub-agen memori pemblokiran opsional milik Plugin yang berjalan
Active memory adalah sub-agen memori pemblokiran opsional milik Plugin yang berjalan
sebelum balasan utama untuk sesi percakapan yang memenuhi syarat.
Ini ada karena sebagian besar sistem memori mampu tetapi reaktif. Sistem tersebut bergantung pada
agen utama untuk memutuskan kapan harus 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 lewat.
agen utama untuk memutuskan kapan harus menelusuri memori, atau pada pengguna untuk mengatakan hal-hal
seperti "ingat ini" atau "telusuri memori." Saat itu terjadi, momen ketika memori
seharusnya membuat balasan terasa alami sudah terlewat.
Active Memory memberi sistem satu kesempatan yang dibatasi untuk memunculkan memori yang relevan
Active memory memberi sistem satu kesempatan terbatas untuk memunculkan memori yang relevan
sebelum balasan utama dibuat.
## Tempelkan Ini ke Agen Anda
## Tempelkan Ini Ke Dalam Agen Anda
Tempelkan ini ke agen Anda jika Anda ingin mengaktifkan Active Memory dengan
pengaturan yang mandiri dan aman secara default:
Tempelkan ini ke dalam agen Anda jika Anda ingin mengaktifkan Active Memory dengan
pengaturan mandiri yang aman secara default:
```json5
{
@ -56,7 +56,7 @@ pengaturan yang mandiri dan aman secara default:
}
```
Ini mengaktifkan plugin untuk agen `main`, membatasinya ke sesi
Ini menyalakan Plugin untuk agen `main`, menjaganya tetap terbatas pada sesi
bergaya pesan langsung secara default, memungkinkannya mewarisi model sesi saat ini terlebih dahulu, dan
menggunakan model fallback yang dikonfigurasi hanya jika tidak ada model eksplisit atau turunan yang tersedia.
@ -77,7 +77,7 @@ Untuk memeriksanya secara langsung dalam percakapan:
Pengaturan yang paling aman adalah:
1. aktifkan plugin
1. aktifkan Plugin
2. targetkan satu agen percakapan
3. biarkan logging tetap aktif hanya saat penyesuaian
@ -112,26 +112,111 @@ Lalu mulai ulang Gateway:
openclaw gateway
```
Arti dari ini:
Artinya:
- `plugins.entries.active-memory.enabled: true` mengaktifkan plugin
- `plugins.entries.active-memory.enabled: true` menyalakan Plugin
- `config.agents: ["main"]` hanya mengikutsertakan agen `main` ke active memory
- `config.allowedChatTypes: ["direct"]` membuat active memory tetap aktif hanya untuk sesi bergaya pesan langsung secara default
- jika `config.model` tidak diatur, active memory mewarisi model sesi saat ini terlebih dahulu
- jika `config.model` tidak disetel, active memory mewarisi model sesi saat ini terlebih dahulu
- `config.modelFallback` secara opsional menyediakan provider/model fallback Anda sendiri untuk recall
- `config.promptStyle: "balanced"` menggunakan gaya prompt tujuan umum default untuk mode `recent`
- active memory tetap hanya berjalan pada sesi obrolan persisten interaktif yang memenuhi syarat
- `config.promptStyle: "balanced"` menggunakan gaya prompt umum default untuk mode `recent`
- active memory tetap hanya berjalan pada sesi chat persisten interaktif yang memenuhi syarat
## Rekomendasi kecepatan
Pengaturan paling sederhana adalah membiarkan `config.model` tidak disetel dan membiarkan Active Memory menggunakan
model yang sama yang sudah Anda gunakan untuk balasan normal. Itu adalah default paling aman
karena mengikuti preferensi provider, autentikasi, dan model yang sudah ada.
Jika Anda ingin Active Memory terasa lebih cepat, gunakan model inferensi khusus
alih-alih meminjam model chat utama.
Contoh pengaturan provider cepat:
```json5
models: {
providers: {
cerebras: {
baseUrl: "https://api.cerebras.ai/v1",
apiKey: "${CEREBRAS_API_KEY}",
api: "openai-completions",
models: [{ id: "gpt-oss-120b", name: "GPT OSS 120B (Cerebras)" }],
},
},
},
plugins: {
entries: {
"active-memory": {
enabled: true,
config: {
model: "cerebras/gpt-oss-120b",
},
},
},
}
```
Opsi model cepat yang layak dipertimbangkan:
- `cerebras/gpt-oss-120b` untuk model recall khusus yang cepat dengan permukaan tool yang sempit
- model sesi normal Anda, dengan membiarkan `config.model` tidak disetel
- model fallback berlatensi rendah seperti `google/gemini-3-flash` saat Anda menginginkan model recall terpisah tanpa mengubah model chat utama Anda
Mengapa Cerebras merupakan opsi berorientasi kecepatan yang kuat untuk Active Memory:
- permukaan tool Active Memory sempit: hanya memanggil `memory_search` dan `memory_get`
- kualitas recall penting, tetapi latensi lebih penting daripada pada jalur jawaban utama
- provider cepat khusus menghindari keterikatan latensi recall memori pada provider chat utama Anda
Jika Anda tidak menginginkan model terpisah yang dioptimalkan untuk kecepatan, biarkan `config.model` tidak disetel
dan biarkan Active Memory mewarisi model sesi saat ini.
### Pengaturan Cerebras
Tambahkan entri provider seperti ini:
```json5
models: {
providers: {
cerebras: {
baseUrl: "https://api.cerebras.ai/v1",
apiKey: "${CEREBRAS_API_KEY}",
api: "openai-completions",
models: [{ id: "gpt-oss-120b", name: "GPT OSS 120B (Cerebras)" }],
},
},
}
```
Lalu arahkan Active Memory ke sana:
```json5
plugins: {
entries: {
"active-memory": {
enabled: true,
config: {
model: "cerebras/gpt-oss-120b",
},
},
},
}
```
Catatan:
- pastikan API key Cerebras benar-benar memiliki akses model untuk model yang Anda pilih, karena visibilitas `/v1/models` saja tidak menjamin akses `chat/completions`
## Cara melihatnya
Active memory menyuntikkan awalan prompt tersembunyi yang tidak tepercaya untuk model. Active memory
tidak mengekspos tag mentah `<active_memory_plugin>...</active_memory_plugin>` di
Active memory menyuntikkan awalan prompt tidak tepercaya tersembunyi untuk model. Fitur ini
tidak mengekspos tag mentah `<active_memory_plugin>...</active_memory_plugin>` dalam
balasan normal yang terlihat oleh klien.
## Toggle sesi
## Tombol sesi
Gunakan perintah plugin ketika Anda ingin menjeda atau melanjutkan active memory untuk
sesi obrolan saat ini tanpa mengedit konfigurasi:
Gunakan perintah Plugin saat Anda ingin menjeda atau melanjutkan active memory untuk
sesi chat saat ini tanpa mengedit konfigurasi:
```text
/active-memory status
@ -139,11 +224,11 @@ sesi obrolan saat ini tanpa mengedit konfigurasi:
/active-memory on
```
Ini berskala sesi. Ini tidak mengubah
`plugins.entries.active-memory.enabled`, penargetan agen, atau konfigurasi
global lainnya.
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 active memory untuk
Jika Anda ingin perintah menulis konfigurasi dan menjeda atau melanjutkan active memory untuk
semua sesi, gunakan bentuk global yang eksplisit:
```text
@ -157,7 +242,7 @@ Bentuk global menulis `plugins.entries.active-memory.config.enabled`. Bentuk ini
mengaktifkan kembali active memory nanti.
Jika Anda ingin melihat apa yang dilakukan active memory dalam sesi langsung, aktifkan
toggle sesi yang sesuai dengan output yang Anda inginkan:
tombol sesi yang sesuai dengan keluaran yang Anda inginkan:
```text
/verbose on
@ -169,10 +254,10 @@ Dengan itu diaktifkan, OpenClaw dapat menampilkan:
- baris status active memory seperti `Active Memory: status=ok elapsed=842ms query=recent summary=34 chars` saat `/verbose on`
- ringkasan debug yang mudah dibaca seperti `Active Memory Debug: Lemon pepper wings with blue cheese.` saat `/trace on`
Baris-baris tersebut berasal dari pass active memory yang sama yang memberi awalan
prompt tersembunyi, tetapi diformat untuk manusia alih-alih mengekspos markup prompt mentah.
Baris-baris itu dikirim sebagai pesan diagnostik lanjutan setelah balasan normal
asisten sehingga klien channel seperti Telegram tidak menampilkan gelembung diagnostik terpisah
Baris-baris tersebut berasal dari pass active memory yang sama yang memberi masukan pada
awalan prompt tersembunyi, tetapi diformat untuk manusia alih-alih mengekspos markup prompt mentah.
Baris-baris tersebut dikirim sebagai pesan diagnostik lanjutan setelah balasan normal
asisten sehingga klien saluran seperti Telegram tidak menampilkan gelembung diagnostik terpisah
sebelum balasan.
Jika Anda juga mengaktifkan `/trace raw`, blok `Model Input (User Role)` yang ditelusuri akan
@ -193,57 +278,58 @@ Contoh alur:
```text
/verbose on
/trace on
sayap apa yang sebaiknya saya pesan?
what wings should i order?
```
Bentuk balasan terlihat yang diharapkan:
Bentuk balasan yang diharapkan terlihat:
```text
...balasan asisten normal...
...normal assistant reply...
🧩 Active Memory: status=ok elapsed=842ms query=recent summary=34 chars
🔎 Active Memory Debug: Lemon pepper wings with blue cheese.
```
## Kapan dijalankan
## Kapan berjalan
Active memory menggunakan dua gerbang:
1. **Opt-in konfigurasi**
Plugin harus diaktifkan, dan id agen saat ini harus muncul di
Plugin harus diaktifkan, dan ID agen saat ini harus muncul di
`plugins.entries.active-memory.config.agents`.
2. **Kelayakan runtime yang ketat**
Bahkan ketika diaktifkan dan ditargetkan, active memory hanya berjalan untuk sesi obrolan persisten interaktif yang memenuhi syarat.
Bahkan ketika diaktifkan dan ditargetkan, active memory hanya berjalan untuk
sesi chat persisten interaktif yang memenuhi syarat.
Aturan sebenarnya adalah:
```text
plugin diaktifkan
plugin enabled
+
id agen ditargetkan
agent id targeted
+
jenis obrolan diizinkan
allowed chat type
+
sesi obrolan persisten interaktif yang memenuhi syarat
eligible interactive persistent chat session
=
active memory berjalan
active memory runs
```
Jika salah satu gagal, active memory tidak berjalan.
## Jenis sesi
`config.allowedChatTypes` mengontrol jenis percakapan apa saja yang boleh menjalankan Active
`config.allowedChatTypes` mengontrol jenis percakapan mana yang boleh menjalankan Active
Memory sama sekali.
Nilai default-nya adalah:
Default-nya adalah:
```json5
allowedChatTypes: ["direct"]
```
Itu berarti Active Memory berjalan secara default dalam sesi bergaya pesan langsung, tetapi
tidak dalam sesi grup atau channel kecuali Anda secara eksplisit mengikutsertakannya.
Artinya Active Memory berjalan secara default dalam sesi bergaya pesan langsung, tetapi
tidak dalam sesi grup atau saluran kecuali Anda secara eksplisit mengikutsertakannya.
Contoh:
@ -259,38 +345,38 @@ allowedChatTypes: ["direct", "group"]
allowedChatTypes: ["direct", "group", "channel"]
```
## Di mana dijalankan
## Di mana berjalan
Active memory adalah fitur pengayaan percakapan, bukan fitur inferensi
seluruh platform.
| Surface | Menjalankan active memory? |
| ------------------------------------------------------------------- | ------------------------------------------------------- |
| Sesi persisten UI kontrol / web chat | Ya, jika plugin diaktifkan dan agen ditargetkan |
| Sesi channel interaktif lain pada jalur obrolan persisten yang sama | Ya, jika plugin diaktifkan dan agen ditargetkan |
| Control UI / sesi persisten web chat | Ya, jika Plugin diaktifkan dan agen ditargetkan |
| Sesi saluran interaktif lain pada jalur chat persisten yang sama | Ya, jika Plugin diaktifkan dan agen ditargetkan |
| Proses headless sekali jalan | Tidak |
| Proses Heartbeat/latar belakang | Tidak |
| Jalur `agent-command` internal generik | Tidak |
| Jalur internal `agent-command` generik | Tidak |
| Eksekusi sub-agen/helper internal | Tidak |
## Mengapa menggunakannya
Gunakan active memory ketika:
Gunakan active memory saat:
- sesi bersifat persisten dan menghadap pengguna
- agen memiliki memori jangka panjang yang bermakna untuk dicari
- kesinambungan dan personalisasi lebih penting daripada determinisme prompt mentah
- sesi bersifat persisten dan berhadapan dengan pengguna
- agen memiliki memori jangka panjang yang bermakna untuk ditelusuri
- kontinuitas dan personalisasi lebih penting daripada determinisme prompt mentah
Active memory bekerja sangat baik terutama untuk:
Fitur ini bekerja sangat baik untuk:
- preferensi yang stabil
- kebiasaan yang berulang
- konteks pengguna jangka panjang yang seharusnya muncul secara alami
Active memory kurang cocok untuk:
Fitur ini kurang cocok untuk:
- otomatisasi
- pekerja internal
- worker internal
- tugas API sekali jalan
- tempat di mana personalisasi tersembunyi akan terasa mengejutkan
@ -312,11 +398,11 @@ Sub-agen memori pemblokiran hanya dapat menggunakan:
- `memory_search`
- `memory_get`
Jika koneksinya lemah, sub-agen tersebut harus mengembalikan `NONE`.
Jika koneksinya lemah, sub-agen harus mengembalikan `NONE`.
## Mode kueri
`config.queryMode` mengontrol seberapa banyak percakapan yang dilihat sub-agen memori pemblokiran.
`config.queryMode` mengontrol seberapa banyak percakapan yang dilihat oleh sub-agen memori pemblokiran.
## Gaya prompt
@ -325,14 +411,14 @@ saat memutuskan apakah akan mengembalikan memori.
Gaya yang tersedia:
- `balanced`: default tujuan umum untuk mode `recent`
- `strict`: paling tidak antusias; terbaik saat Anda ingin sangat sedikit kebocoran dari konteks sekitar
- `contextual`: paling ramah terhadap kesinambungan; terbaik saat riwayat percakapan harus lebih diperhitungkan
- `balanced`: default serbaguna untuk mode `recent`
- `strict`: paling tidak antusias; terbaik saat Anda menginginkan sangat sedikit pengaruh dari konteks terdekat
- `contextual`: paling ramah kontinuitas; terbaik saat riwayat percakapan harus lebih diperhitungkan
- `recall-heavy`: lebih bersedia memunculkan memori pada kecocokan yang lebih lemah tetapi masih masuk akal
- `precision-heavy`: sangat memilih `NONE` kecuali kecocokannya jelas
- `preference-only`: dioptimalkan untuk favorit, kebiasaan, rutinitas, selera, dan fakta pribadi yang berulang
Pemetaan default saat `config.promptStyle` tidak diatur:
Pemetaan default saat `config.promptStyle` tidak disetel:
```text
message -> strict
@ -340,7 +426,7 @@ recent -> balanced
full -> contextual
```
Jika Anda mengatur `config.promptStyle` secara eksplisit, override tersebut yang berlaku.
Jika Anda menyetel `config.promptStyle` secara eksplisit, override itu yang berlaku.
Contoh:
@ -350,16 +436,16 @@ promptStyle: "preference-only"
## Kebijakan fallback model
Jika `config.model` tidak diatur, Active Memory mencoba menyelesaikan model dalam urutan ini:
Jika `config.model` tidak disetel, Active Memory mencoba menyelesaikan model dalam urutan ini:
```text
model plugin eksplisit
-> model sesi saat ini
-> model utama agen
-> model fallback yang dikonfigurasi secara opsional
explicit plugin model
-> current session model
-> agent primary model
-> optional configured fallback model
```
`config.modelFallback` mengontrol langkah fallback yang dikonfigurasi.
`config.modelFallback` mengontrol langkah fallback terkonfigurasi.
Fallback kustom opsional:
@ -367,17 +453,17 @@ Fallback kustom opsional:
modelFallback: "google/gemini-3-flash"
```
Jika tidak ada model eksplisit, turunan, atau fallback yang dikonfigurasi yang dapat diselesaikan, Active Memory
Jika tidak ada model eksplisit, turunan, atau fallback terkonfigurasi yang berhasil diselesaikan, Active Memory
melewati recall untuk giliran tersebut.
`config.modelFallbackPolicy` dipertahankan hanya sebagai field kompatibilitas usang
untuk konfigurasi lama. Field ini tidak lagi mengubah perilaku runtime.
`config.modelFallbackPolicy` dipertahankan hanya sebagai field kompatibilitas
usang untuk konfigurasi lama. Field ini tidak lagi mengubah perilaku runtime.
## Escape hatch lanjutan
## Opsi lanjutan untuk situasi khusus
Opsi-opsi ini sengaja tidak menjadi bagian dari pengaturan yang direkomendasikan.
Opsi ini sengaja tidak menjadi bagian dari pengaturan yang direkomendasikan.
`config.thinking` dapat mengganti tingkat thinking sub-agen memori pemblokiran:
`config.thinking` dapat menimpa tingkat thinking sub-agen memori pemblokiran:
```json5
thinking: "medium"
@ -392,21 +478,21 @@ thinking: "off"
Jangan aktifkan ini secara default. Active Memory berjalan di jalur balasan, jadi waktu
thinking tambahan secara langsung meningkatkan latensi yang terlihat oleh pengguna.
`config.promptAppend` menambahkan instruksi operator tambahan setelah prompt Active
Memory default dan sebelum konteks percakapan:
`config.promptAppend` menambahkan instruksi operator tambahan setelah prompt default Active
Memory dan sebelum konteks percakapan:
```json5
promptAppend: "Utamakan preferensi jangka panjang yang stabil daripada peristiwa sekali jalan."
promptAppend: "Prefer stable long-term preferences over one-off events."
```
`config.promptOverride` menggantikan prompt Active Memory default. OpenClaw
`config.promptOverride` menggantikan prompt default Active Memory. OpenClaw
tetap menambahkan konteks percakapan setelahnya:
```json5
promptOverride: "Anda adalah agen pencarian memori. Kembalikan NONE atau satu fakta pengguna yang ringkas."
promptOverride: "You are a memory search agent. Return NONE or one compact user fact."
```
Kustomisasi prompt tidak direkomendasikan kecuali Anda memang sengaja menguji
Kustomisasi prompt tidak direkomendasikan kecuali Anda memang sedang menguji
kontrak recall yang berbeda. Prompt default disetel untuk mengembalikan `NONE`
atau konteks fakta pengguna yang ringkas untuk model utama.
@ -415,48 +501,48 @@ atau konteks fakta pengguna yang ringkas untuk model utama.
Hanya pesan pengguna terbaru yang dikirim.
```text
Hanya pesan pengguna terbaru
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
- giliran lanjutan tidak memerlukan konteks percakapan
Timeout yang direkomendasikan:
- mulai sekitar `3000` hingga `5000` ms
- mulai dari sekitar `3000` hingga `5000` ms
### `recent`
Pesan pengguna terbaru ditambah sedikit ekor percakapan terbaru dikirim.
Pesan pengguna terbaru ditambah ekor percakapan terbaru yang kecil akan dikirim.
```text
Ekor percakapan terbaru:
Recent conversation tail:
user: ...
assistant: ...
user: ...
Pesan pengguna terbaru:
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
- Anda menginginkan keseimbangan yang lebih baik antara kecepatan dan pijakan percakapan
- pertanyaan lanjutan sering bergantung pada beberapa giliran terakhir
Timeout yang direkomendasikan:
- mulai sekitar `15000` ms
- mulai dari sekitar `15000` ms
### `full`
Percakapan lengkap dikirim ke sub-agen memori pemblokiran.
Seluruh percakapan dikirim ke sub-agen memori pemblokiran.
```text
Konteks percakapan lengkap:
Full conversation context:
user: ...
assistant: ...
user: ...
@ -466,14 +552,14 @@ user: ...
Gunakan ini ketika:
- kualitas recall terkuat lebih penting daripada latensi
- percakapan berisi pengaturan penting yang berada jauh di belakang dalam thread
- percakapan berisi pengaturan penting jauh di belakang dalam utas
Timeout yang direkomendasikan:
- tingkatkan secara signifikan dibandingkan dengan `message` atau `recent`
- mulai sekitar `15000` ms atau lebih tinggi, bergantung pada ukuran thread
- tingkatkan secara signifikan dibandingkan `message` atau `recent`
- mulai dari sekitar `15000` ms atau lebih tinggi tergantung ukuran utas
Secara umum, timeout harus meningkat seiring ukuran konteks:
Secara umum, timeout sebaiknya meningkat seiring ukuran konteks:
```text
message < recent < full
@ -481,17 +567,17 @@ message < recent < full
## Persistensi transkrip
Proses sub-agen memori pemblokiran Active Memory membuat transkrip `session.jsonl`
nyata selama pemanggilan sub-agen memori pemblokiran.
Proses sub-agen memori pemblokiran Active memory membuat transkrip `session.jsonl` nyata
selama pemanggilan sub-agen memori pemblokiran.
Secara default, transkrip tersebut bersifat sementara:
- ditulis ke direktori temp
- digunakan hanya untuk proses sub-agen memori pemblokiran
- ditulis ke direktori sementara
- hanya digunakan untuk proses sub-agen memori pemblokiran
- dihapus segera setelah proses selesai
Jika Anda ingin menyimpan transkrip sub-agen memori pemblokiran tersebut di disk untuk debugging atau
inspeksi, aktifkan persistensi secara eksplisit:
pemeriksaan, aktifkan persistensi secara eksplisit:
```json5
{
@ -510,7 +596,7 @@ inspeksi, aktifkan persistensi secara eksplisit:
}
```
Saat diaktifkan, active memory menyimpan transkrip di direktori terpisah di bawah
Saat diaktifkan, active memory menyimpan transkrip dalam direktori terpisah di bawah
folder sesi agen target, bukan di jalur transkrip percakapan pengguna utama.
Secara konseptual, tata letak default adalah:
@ -523,8 +609,8 @@ Anda dapat mengubah subdirektori relatif dengan `config.transcriptDir`.
Gunakan ini dengan hati-hati:
- transkrip sub-agen memori pemblokiran dapat cepat menumpuk pada sesi yang sibuk
- mode kueri `full` dapat menggandakan banyak konteks percakapan
- transkrip sub-agen memori pemblokiran dapat menumpuk dengan cepat pada sesi yang sibuk
- mode kueri `full` dapat menduplikasi banyak konteks percakapan
- transkrip ini berisi konteks prompt tersembunyi dan memori yang di-recall
## Konfigurasi
@ -537,32 +623,32 @@ plugins.entries.active-memory
Field yang paling penting adalah:
| Key | Type | Arti |
| --------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `enabled` | `boolean` | Mengaktifkan plugin itu sendiri |
| `config.agents` | `string[]` | Id agen yang dapat menggunakan active memory |
| `config.model` | `string` | Ref model sub-agen memori pemblokiran opsional; jika tidak diatur, active memory menggunakan model sesi saat ini |
| `config.queryMode` | `"message" \| "recent" \| "full"` | Mengontrol seberapa banyak percakapan yang dilihat sub-agen memori pemblokiran |
| Key | Type | Arti |
| --------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `enabled` | `boolean` | Mengaktifkan Plugin itu sendiri |
| `config.agents` | `string[]` | ID agen yang dapat menggunakan active memory |
| `config.model` | `string` | Ref model sub-agen memori pemblokiran opsional; jika tidak disetel, active memory menggunakan model sesi saat ini |
| `config.queryMode` | `"message" \| "recent" \| "full"` | Mengontrol seberapa banyak percakapan yang dilihat sub-agen memori pemblokiran |
| `config.promptStyle` | `"balanced" \| "strict" \| "contextual" \| "recall-heavy" \| "precision-heavy" \| "preference-only"` | Mengontrol seberapa antusias atau ketat sub-agen memori pemblokiran saat memutuskan apakah akan mengembalikan memori |
| `config.thinking` | `"off" \| "minimal" \| "low" \| "medium" \| "high" \| "xhigh" \| "adaptive"` | Override thinking lanjutan untuk sub-agen memori pemblokiran; 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 yang dioverride |
| `config.timeoutMs` | `number` | Timeout keras untuk sub-agen memori pemblokiran |
| `config.maxSummaryChars` | `number` | Total karakter maksimum yang diizinkan dalam ringkasan active-memory |
| `config.logging` | `boolean` | Menghasilkan log active memory saat penyesuaian |
| `config.persistTranscripts` | `boolean` | Menyimpan transkrip sub-agen memori pemblokiran di disk alih-alih menghapus file temp |
| `config.transcriptDir` | `string` | Direktori transkrip sub-agen memori pemblokiran relatif di bawah folder sesi agen |
| `config.thinking` | `"off" \| "minimal" \| "low" \| "medium" \| "high" \| "xhigh" \| "adaptive"` | Override thinking lanjutan untuk sub-agen memori pemblokiran; default `off` demi 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 yang dioverride |
| `config.timeoutMs` | `number` | Timeout keras untuk sub-agen memori pemblokiran |
| `config.maxSummaryChars` | `number` | Jumlah total karakter maksimum yang diizinkan dalam ringkasan active-memory |
| `config.logging` | `boolean` | Menghasilkan log active memory selama penyesuaian |
| `config.persistTranscripts` | `boolean` | Menyimpan transkrip sub-agen memori pemblokiran di disk alih-alih menghapus file sementara |
| `config.transcriptDir` | `string` | Direktori transkrip sub-agen memori pemblokiran relatif di bawah folder sesi agen |
Field penyesuaian yang berguna:
| Key | Type | Arti |
| ----------------------------- | -------- | ------------------------------------------------------------- |
| `config.maxSummaryChars` | `number` | Total karakter maksimum yang diizinkan dalam ringkasan active-memory |
| 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` | Maks karakter per giliran pengguna terbaru |
| `config.recentAssistantChars` | `number` | Maks karakter per giliran asisten terbaru |
| `config.cacheTtlMs` | `number` | Penggunaan ulang cache untuk kueri identik yang berulang |
| `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 berulang |
## Pengaturan yang direkomendasikan
@ -588,12 +674,12 @@ Mulailah dengan `recent`.
}
```
Jika Anda ingin memeriksa perilaku langsung saat melakukan penyesuaian, gunakan `/verbose on` untuk
baris status normal dan `/trace on` untuk ringkasan debug active-memory alih-alih
mencari perintah debug active-memory terpisah. Di channel obrolan, baris diagnostik tersebut
dikirim setelah balasan asisten utama, bukan sebelumnya.
Jika Anda ingin memeriksa perilaku langsung saat penyesuaian, gunakan `/verbose on` untuk
baris status normal dan `/trace on` untuk ringkasan debug active-memory
alih-alih mencari perintah debug active-memory terpisah. Di saluran chat, baris
diagnostik tersebut dikirim setelah balasan utama asisten, bukan sebelumnya.
Lalu beralih ke:
Lalu pindah ke:
- `message` jika Anda menginginkan latensi yang lebih rendah
- `full` jika Anda memutuskan konteks tambahan sepadan dengan sub-agen memori pemblokiran yang lebih lambat
@ -602,13 +688,13 @@ Lalu beralih ke:
Jika active memory tidak muncul di tempat yang Anda harapkan:
1. Konfirmasikan plugin diaktifkan di `plugins.entries.active-memory.enabled`.
2. Konfirmasikan id agen saat ini tercantum di `config.agents`.
3. Konfirmasikan Anda menguji melalui sesi obrolan persisten interaktif.
1. Pastikan Plugin diaktifkan di `plugins.entries.active-memory.enabled`.
2. Pastikan ID agen saat ini tercantum di `config.agents`.
3. Pastikan Anda menguji melalui sesi chat persisten interaktif.
4. Aktifkan `config.logging: true` dan pantau log Gateway.
5. Verifikasi bahwa pencarian memori itu sendiri berfungsi dengan `openclaw memory status --deep`.
5. Verifikasi bahwa penelusuran memori itu sendiri berfungsi dengan `openclaw memory status --deep`.
Jika hasil memori terlalu berisik, perketat:
Jika hasil memori terlalu bising, perketat:
- `maxSummaryChars`
@ -621,60 +707,60 @@ Jika active memory terlalu lambat:
## Masalah umum
### Provider embedding berubah secara tidak terduga
### Provider embedding berubah tanpa diduga
Active Memory menggunakan pipeline `memory_search` normal di bawah
`agents.defaults.memorySearch`. Itu berarti penyiapan provider embedding hanya menjadi
persyaratan ketika pengaturan `memorySearch` Anda memerlukan embedding untuk perilaku
`agents.defaults.memorySearch`. Artinya, pengaturan provider embedding hanya menjadi
persyaratan saat pengaturan `memorySearch` Anda memerlukan embedding untuk perilaku
yang Anda inginkan.
Dalam praktiknya:
- penyiapan provider eksplisit **diperlukan** jika Anda menginginkan provider yang tidak
dideteksi otomatis, seperti `ollama`
- penyiapan provider eksplisit **diperlukan** jika deteksi otomatis tidak dapat menyelesaikan
provider embedding yang dapat digunakan untuk lingkungan Anda
- penyiapan provider eksplisit **sangat direkomendasikan** jika Anda menginginkan
pemilihan provider yang deterministik alih-alih "yang pertama tersedia menang"
- penyiapan provider eksplisit biasanya **tidak diperlukan** jika deteksi otomatis sudah
- pengaturan provider eksplisit **diperlukan** jika Anda menginginkan provider yang tidak
terdeteksi otomatis, seperti `ollama`
- pengaturan provider eksplisit **diperlukan** jika deteksi otomatis tidak berhasil
menyelesaikan provider embedding yang dapat digunakan untuk lingkungan Anda
- pengaturan provider eksplisit **sangat direkomendasikan** jika Anda menginginkan
pemilihan provider yang deterministik alih-alih "yang tersedia pertama menang"
- pengaturan provider eksplisit biasanya **tidak diperlukan** jika deteksi otomatis sudah
menyelesaikan provider yang Anda inginkan dan provider tersebut stabil dalam deployment Anda
Jika `memorySearch.provider` tidak diatur, OpenClaw mendeteksi otomatis provider
Jika `memorySearch.provider` tidak disetel, OpenClaw mendeteksi otomatis provider
embedding pertama yang tersedia.
Ini bisa membingungkan dalam deployment nyata:
Hal itu dapat membingungkan dalam deployment nyata:
- API key yang baru tersedia dapat mengubah provider mana yang digunakan pencarian memori
- satu perintah atau surface diagnostik dapat membuat provider yang dipilih terlihat
berbeda dari jalur yang sebenarnya Anda gunakan selama sinkronisasi memori langsung atau
bootstrap pencarian
- provider yang di-host dapat gagal dengan error kuota atau rate-limit yang baru terlihat
setelah Active Memory mulai mengeluarkan pencarian recall sebelum setiap balasan
- API key yang baru tersedia dapat mengubah provider mana yang digunakan penelusuran memori
- satu perintah atau permukaan diagnostik mungkin membuat provider yang dipilih tampak
berbeda dari jalur yang benar-benar Anda gunakan selama sinkronisasi memori langsung atau
bootstrap penelusuran
- provider ter-host dapat gagal dengan error kuota atau rate limit yang baru terlihat
setelah Active Memory mulai mengeluarkan kueri recall sebelum setiap balasan
Active Memory tetap dapat berjalan tanpa embedding ketika `memory_search` dapat beroperasi
dalam mode degradasi hanya leksikal, yang biasanya terjadi ketika tidak ada provider
Active Memory tetap dapat berjalan tanpa embedding saat `memory_search` dapat beroperasi
dalam mode degradasi leksikal saja, yang biasanya terjadi saat tidak ada provider
embedding yang dapat diselesaikan.
Jangan berasumsi fallback yang sama berlaku pada kegagalan runtime provider seperti kehabisan kuota,
rate limit, error jaringan/provider, atau model lokal/jarak jauh yang hilang setelah suatu provider
sudah dipilih.
Jangan berasumsi fallback yang sama berlaku pada kegagalan runtime provider seperti
kuota habis, rate limit, error jaringan/provider, atau model lokal/jarak jauh yang hilang
setelah provider sudah dipilih.
Dalam praktiknya:
- jika tidak ada provider embedding yang dapat diselesaikan, `memory_search` dapat terdegradasi menjadi
pengambilan hanya leksikal
- jika suatu provider embedding dapat diselesaikan lalu gagal saat runtime, OpenClaw saat ini
- jika tidak ada provider embedding yang dapat diselesaikan, `memory_search` dapat turun menjadi
pengambilan leksikal saja
- jika provider embedding berhasil diselesaikan lalu gagal saat runtime, OpenClaw saat ini
tidak menjamin fallback leksikal untuk permintaan tersebut
- jika Anda memerlukan pemilihan provider yang deterministik, pin
`agents.defaults.memorySearch.provider`
- jika Anda memerlukan failover provider pada error runtime, konfigurasikan
- jika Anda memerlukan failover provider saat terjadi error runtime, konfigurasikan
`agents.defaults.memorySearch.fallback` secara eksplisit
Jika Anda bergantung pada recall berbasis embedding, pengindeksan multimodal, atau provider
lokal/jarak jauh tertentu, pin provider tersebut secara eksplisit alih-alih mengandalkan
lokal/jarak jauh tertentu, pin provider secara eksplisit alih-alih mengandalkan
deteksi otomatis.
Contoh pinning umum:
Contoh pinning yang umum:
OpenAI:
@ -721,8 +807,8 @@ Ollama:
}
```
Jika Anda mengharapkan failover provider pada error runtime seperti kehabisan kuota,
pinning provider saja tidak cukup. Konfigurasikan juga fallback eksplisit:
Jika Anda mengharapkan failover provider pada error runtime seperti
kuota habis, pinning provider saja tidak cukup. Konfigurasikan fallback eksplisit juga:
```json5
{
@ -739,29 +825,30 @@ pinning provider saja tidak cukup. Konfigurasikan juga fallback eksplisit:
### Debugging masalah provider
Jika Active Memory lambat, kosong, atau tampak berpindah provider secara tidak terduga:
Jika Active Memory lambat, kosong, atau tampak berpindah provider tanpa diduga:
- pantau log Gateway saat mereproduksi masalah; cari baris seperti
`active-memory: ... start|done`, `memory sync failed (search-bootstrap)`, atau
error embedding khusus provider
- aktifkan `/trace on` untuk memunculkan ringkasan debug Active Memory milik Plugin di
error embedding spesifik provider
- aktifkan `/trace on` untuk menampilkan ringkasan debug Active Memory milik Plugin di
sesi
- aktifkan `/verbose on` jika Anda juga menginginkan baris status normal `🧩 Active Memory: ...`
- aktifkan `/verbose on` jika Anda juga ingin baris status normal `🧩 Active Memory: ...`
setelah setiap balasan
- jalankan `openclaw memory status --deep` untuk memeriksa backend pencarian memori saat ini
- jalankan `openclaw memory status --deep` untuk memeriksa backend penelusuran memori saat ini
dan kesehatan indeks
- periksa `agents.defaults.memorySearch.provider` dan auth/config terkait untuk memastikan
- periksa `agents.defaults.memorySearch.provider` serta autentikasi/konfigurasi terkait untuk memastikan
provider yang Anda harapkan benar-benar yang dapat diselesaikan saat runtime
- jika Anda menggunakan `ollama`, verifikasi model embedding yang dikonfigurasi telah terinstal, misalnya `ollama list`
- jika Anda menggunakan `ollama`, verifikasi bahwa model embedding yang dikonfigurasi telah terinstal, misalnya dengan
`ollama list`
Contoh alur debugging:
```text
1. Mulai Gateway dan pantau log-nya
2. Di sesi obrolan, jalankan /trace on
3. Kirim satu pesan yang seharusnya memicu Active Memory
4. Bandingkan baris debug yang terlihat di obrolan dengan baris log Gateway
5. Jika pilihan provider ambigu, pin `agents.defaults.memorySearch.provider` secara eksplisit
1. Start the gateway and watch its logs
2. In the chat session, run /trace on
3. Send one message that should trigger Active Memory
4. Compare the chat-visible debug line with the gateway log lines
5. If provider choice is ambiguous, pin agents.defaults.memorySearch.provider explicitly
```
Contoh:

View File

@ -1,29 +1,29 @@
---
read_when:
- Mengimplementasikan atau memperbarui klien WS gateway
- 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: Protokol Gateway
x-i18n:
generated_at: "2026-04-10T09:13:11Z"
generated_at: "2026-04-16T09:14:38Z"
model: gpt-5.4
provider: openai
source_hash: 83c820c46d4803d571c770468fd6782619eaa1dca253e156e8087dec735c127f
source_hash: 683e61ebe993a2d739bc34860060b0e3eda36b5c57267a2bcc03d177ec612fb3
source_path: gateway/protocol.md
workflow: 15
---
# Protokol Gateway (WebSocket)
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.
Protokol WS Gateway 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 **peran** + **cakupan**
mereka saat handshake.
## Transport
- WebSocket, frame teks dengan muatan JSON.
- WebSocket, frame teks dengan payload JSON.
- Frame pertama **harus** berupa permintaan `connect`.
## Handshake (connect)
@ -80,11 +80,25 @@ Gateway → Klien:
"type": "res",
"id": "…",
"ok": true,
"payload": { "type": "hello-ok", "protocol": 3, "policy": { "tickIntervalMs": 15000 } }
"payload": {
"type": "hello-ok",
"protocol": 3,
"server": { "version": "…", "connId": "…" },
"features": { "methods": ["…"], "events": ["…"] },
"snapshot": { "…": "…" },
"policy": {
"maxPayload": 26214400,
"maxBufferedBytes": 52428800,
"tickIntervalMs": 15000
}
}
}
```
Saat token perangkat diterbitkan, `hello-ok` juga mencakup:
`server`, `features`, `snapshot`, dan `policy` semuanya wajib menurut skema
(`src/gateway/protocol/schema/frames.ts`). `auth` dan `canvasHostUrl` bersifat opsional.
Saat token perangkat diterbitkan, `hello-ok` juga menyertakan:
```json
{
@ -97,7 +111,7 @@ Saat token perangkat diterbitkan, `hello-ok` juga mencakup:
```
Selama handoff bootstrap tepercaya, `hello-ok.auth` juga dapat menyertakan entri
peran terbatas tambahan dalam `deviceTokens`:
peran tambahan yang dibatasi dalam `deviceTokens`:
```json
{
@ -121,7 +135,7 @@ Untuk alur bootstrap node/operator bawaan, token node utama tetap
operator bootstrap (`operator.approvals`, `operator.read`,
`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.
non-operator tetap memerlukan cakupan di bawah awalan perannya sendiri.
### Contoh node
@ -160,17 +174,17 @@ non-operator tetap memerlukan cakupan di bawah awalan peran mereka sendiri.
## Framing
- **Permintaan**: `{type:"req", id, method, params}`
- **Respons**: `{type:"res", id, ok, payload|error}`
- **Peristiwa**: `{type:"event", event, payload, seq?, stateVersion?}`
- **Request**: `{type:"req", id, method, params}`
- **Response**: `{type:"res", id, ok, payload|error}`
- **Event**: `{type:"event", event, payload, seq?, stateVersion?}`
Metode yang memiliki efek samping memerlukan **kunci idempotensi** (lihat skema).
Method yang memiliki efek samping memerlukan **idempotency keys** (lihat skema).
## Peran + cakupan
### Peran
- `operator` = klien bidang kendali (CLI/UI/otomasi).
- `operator` = klien bidang kontrol (CLI/UI/otomasi).
- `node` = host kapabilitas (camera/screen/canvas/system.run).
### Cakupan (operator)
@ -187,18 +201,17 @@ Cakupan umum:
`talk.config` dengan `includeSecrets: true` memerlukan `operator.talk.secrets`
(atau `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`.
Method RPC Gateway yang didaftarkan Plugin dapat meminta cakupan operatornya
sendiri, tetapi awalan admin inti yang dicadangkan (`config.*`, `exec.approvals.*`, `wizard.*`,
`update.*`) selalu di-resolve menjadi `operator.admin`.
Cakupan metode hanyalah gerbang pertama. Beberapa slash command yang dicapai
Cakupan method 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 cakupan saat persetujuan tambahan
di atas cakupan metode dasar:
di atas cakupan method dasar:
- permintaan tanpa perintah: `operator.pairing`
- permintaan dengan perintah node non-exec: `operator.pairing` + `operator.write`
@ -211,111 +224,113 @@ Node mendeklarasikan klaim kapabilitas saat waktu connect:
- `caps`: kategori kapabilitas tingkat tinggi.
- `commands`: allowlist perintah untuk invoke.
- `permissions`: toggle terperinci (misalnya `screen.record`, `camera.capture`).
- `permissions`: toggle granular (misalnya `screen.record`, `camera.capture`).
Gateway memperlakukan ini sebagai **klaim** dan menegakkan allowlist sisi server.
Gateway memperlakukan ini sebagai **klaim** dan menegakkan allowlist di sisi server.
## Kehadiran
- `system-presence` mengembalikan entri yang dikunci oleh identitas perangkat.
- `system-presence` mengembalikan entri yang dikunci berdasarkan 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**.
bahkan ketika perangkat terhubung sebagai **operator** dan **node** sekaligus.
## Keluarga metode RPC umum
## Keluarga method RPC umum
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.
luas daripada contoh handshake/auth di atas. Ini adalah keluarga method utama
yang diekspos Gateway saat ini.
`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`.
`src/gateway/server-methods-list.ts` ditambah ekspor method 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 gaya `/status`; field sensitif hanya
disertakan untuk klien operator bercakupan admin.
disertakan untuk klien operator dengan cakupan admin.
- `gateway.identity.get` mengembalikan identitas perangkat gateway yang digunakan oleh alur relay dan
pairing.
- `system-presence` mengembalikan snapshot kehadiran saat ini untuk perangkat
operator/node yang terhubung.
- `system-event` menambahkan peristiwa sistem dan dapat memperbarui/menyiarkan konteks
- `system-event` menambahkan event sistem dan dapat memperbarui/menyiarkan konteks
kehadiran.
- `last-heartbeat` mengembalikan peristiwa heartbeat persisten terbaru.
- `set-heartbeats` mengaktifkan atau menonaktifkan pemrosesan heartbeat pada gateway.
- `last-heartbeat` mengembalikan event Heartbeat persisten terbaru.
- `set-heartbeats` mengaktifkan atau menonaktifkan pemrosesan Heartbeat di gateway.
### Model dan penggunaan
- `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.
- `models.list` mengembalikan katalog model yang diizinkan saat runtime.
- `usage.status` mengembalikan ringkasan jendela penggunaan provider/kuota tersisa.
- `usage.cost` mengembalikan ringkasan penggunaan biaya agregat untuk 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 timeseries penggunaan untuk satu sesi.
- `sessions.usage.timeseries` mengembalikan penggunaan deret waktu 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 + bundel.
- `channels.logout` melakukan logout pada channel/akun tertentu jika channel
- `channels.status` mengembalikan ringkasan status channel/plugin bawaan + bundled.
- `channels.logout` melakukan logout untuk channel/akun tertentu ketika channel
mendukung logout.
- `web.login.start` memulai alur login QR/web untuk provider channel web
saat ini yang mendukung QR.
berkemampuan QR saat ini.
- `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 perubahannya.
- `voicewake.get` mengembalikan trigger wake-word yang tersimpan.
- `voicewake.set` memperbarui trigger wake-word dan menyiarkan perubahannya.
### Perpesanan dan log
### Pesan dan log
- `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.
- `logs.tail` mengembalikan tail file log gateway yang dikonfigurasi dengan kontrol cursor/limit dan
max-byte.
### Talk dan TTS
- `talk.config` mengembalikan muatan konfigurasi Talk yang efektif; `includeSecrets`
- `talk.config` mengembalikan payload 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 ucapan Talk yang aktif.
- `tts.status` mengembalikan status TTS aktif, provider aktif, provider fallback,
- `talk.speak` mensintesis ucapan melalui provider speech Talk yang aktif.
- `tts.status` mengembalikan status TTS aktif/nonaktif, provider aktif, provider fallback,
dan status konfigurasi provider.
- `tts.providers` mengembalikan inventaris provider TTS yang terlihat.
- `tts.enable` dan `tts.disable` mengaktifkan atau menonaktifkan status preferensi TTS.
- `tts.setProvider` memperbarui provider TTS pilihan.
- `tts.convert` menjalankan konversi teks-ke-ucapan sekali jalan.
- `tts.convert` menjalankan konversi text-to-speech sekali jalan.
### Secrets, config, update, dan wizard
### Secret, config, update, dan wizard
- `secrets.reload` me-resolve ulang SecretRef aktif dan menukar status secret runtime
hanya jika sepenuhnya berhasil.
- `secrets.resolve` me-resolve penetapan secret target-perintah untuk set perintah/target tertentu.
hanya jika seluruh proses berhasil.
- `secrets.resolve` me-resolve penetapan secret yang ditargetkan perintah untuk
set perintah/target tertentu.
- `config.get` mengembalikan snapshot config dan hash saat ini.
- `config.set` menulis muatan config yang tervalidasi.
- `config.set` menulis payload 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
- `config.apply` memvalidasi + mengganti seluruh payload config.
- `config.schema` mengembalikan payload 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
metadata skema plugin + channel ketika runtime dapat memuatnya. Skema ini
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
dan teks bantuan yang digunakan oleh UI, termasuk object bertingkat, wildcard, array-item,
dan cabang komposisi `anyOf` / `oneOf` / `allOf` ketika dokumentasi field
yang cocok tersedia.
- `config.schema.lookup` mengembalikan payload lookup berbatas path untuk satu
path config: path yang dinormalisasi, node skema dangkal, hint yang cocok + `hintPath`, dan
ringkasan child langsung untuk drill-down UI/CLI.
- Node skema lookup mempertahankan dokumentasi yang menghadap pengguna dan field validasi umum:
- Node skema lookup mempertahankan dokumentasi yang berhadapan dengan 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` ternormalisasi, `type`, `required`,
`hasChildren`, ditambah `hint` / `hintPath` yang cocok.
- `update.run` menjalankan alur pembaruan gateway dan menjadwalkan restart hanya saat
- 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
pembaruan itu sendiri berhasil.
- `wizard.start`, `wizard.next`, `wizard.status`, dan `wizard.cancel` mengekspos
wizard onboarding melalui WS RPC.
@ -325,29 +340,29 @@ yang dapat dipanggil yang diimplementasikan dalam `src/gateway/server-methods/*.
#### Helper agen dan workspace
- `agents.list` mengembalikan entri agen yang dikonfigurasi.
- `agents.create`, `agents.update`, dan `agents.delete` mengelola catatan agen dan
- `agents.create`, `agents.update`, dan `agents.delete` mengelola record agen dan
wiring workspace.
- `agents.files.list`, `agents.files.get`, dan `agents.files.set` mengelola
file workspace bootstrap yang diekspos untuk sebuah agen.
- `agent.identity.get` mengembalikan identitas asisten yang efektif untuk agen atau
- `agents.files.list`, `agents.files.get`, dan `agents.files.set` mengelola file
workspace bootstrap yang diekspos untuk sebuah agen.
- `agent.identity.get` mengembalikan identitas asisten efektif untuk sebuah agen atau
sesi.
- `agent.wait` menunggu hingga suatu run selesai dan mengembalikan snapshot terminal saat
- `agent.wait` menunggu hingga sebuah run selesai dan mengembalikan snapshot terminal ketika
tersedia.
#### Kontrol sesi
- `sessions.list` mengembalikan indeks sesi saat ini.
- `sessions.subscribe` dan `sessions.unsubscribe` mengaktifkan atau menonaktifkan langganan peristiwa perubahan sesi
- `sessions.subscribe` dan `sessions.unsubscribe` mengaktifkan atau menonaktifkan langganan event 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
langganan event transkrip/pesan untuk satu sesi.
- `sessions.preview` mengembalikan pratinjau transkrip yang dibatasi 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 interupsi-dan-arahkan untuk sesi aktif.
- `sessions.abort` membatalkan pekerjaan aktif untuk sebuah sesi.
- `sessions.send` mengirim pesan ke dalam sesi yang sudah ada.
- `sessions.steer` adalah varian interrupt-and-steer untuk sesi yang aktif.
- `sessions.abort` membatalkan pekerjaan aktif untuk suatu sesi.
- `sessions.patch` memperbarui metadata/override sesi.
- `sessions.reset`, `sessions.delete`, dan `sessions.compact` melakukan
pemeliharaan sesi.
@ -355,122 +370,123 @@ yang dapat dipanggil yang diimplementasikan dalam `src/gateway/server-methods/*.
- eksekusi chat tetap menggunakan `chat.history`, `chat.send`, `chat.abort`, dan
`chat.inject`.
- `chat.history` dinormalisasi untuk tampilan bagi klien UI: tag direktif inline
dihapus dari teks yang terlihat, muatan XML tool-call teks biasa (termasuk
dihapus dari teks yang terlihat, payload XML panggilan tool teks biasa (termasuk
`<tool_call>...</tool_call>`, `<function_call>...</function_call>`,
`<tool_calls>...</tool_calls>`, `<function_calls>...</function_calls>`, dan
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.
blok panggilan tool yang dipotong) 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 di-pairing yang tertunda dan disetujui.
- `device.pair.list` mengembalikan perangkat berpasangan yang tertunda dan yang disetujui.
- `device.pair.approve`, `device.pair.reject`, dan `device.pair.remove` mengelola
catatan pairing perangkat.
- `device.token.rotate` merotasi token perangkat yang di-pairing dalam batas peran
record pairing perangkat.
- `device.token.rotate` memutar token perangkat yang telah dipasangkan dalam batas peran
dan cakupan yang disetujui.
- `device.token.revoke` mencabut token perangkat yang di-pairing.
- `device.token.revoke` mencabut token perangkat yang telah dipasangkan.
#### 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 dikenal/terhubung.
- `node.rename` memperbarui label node yang di-pairing.
- `node.list` dan `node.describe` mengembalikan status node yang diketahui/terhubung.
- `node.rename` memperbarui label node yang telah dipasangkan.
- `node.invoke` meneruskan perintah ke node yang terhubung.
- `node.invoke.result` mengembalikan hasil untuk permintaan invoke.
- `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.event` membawa event yang berasal dari node kembali ke gateway.
- `node.canvas.capability.refresh` menyegarkan token kapabilitas canvas yang dibatasi cakupan.
- `node.pending.pull` dan `node.pending.ack` adalah API antrean node yang terhubung.
- `node.pending.enqueue` dan `node.pending.drain` mengelola pekerjaan tertunda yang tahan lama
untuk node offline/tidak terhubung.
untuk node yang offline/terputus.
#### Keluarga persetujuan
#### Keluarga approval
- `exec.approval.request`, `exec.approval.get`, `exec.approval.list`, dan
`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.
`exec.approval.resolve` mencakup permintaan approval exec sekali jalan plus
lookup/replay approval yang tertunda.
- `exec.approval.waitDecision` menunggu satu approval exec yang tertunda dan mengembalikan
keputusan akhir (atau `null` saat timeout).
- `exec.approvals.get` dan `exec.approvals.set` mengelola snapshot kebijakan approval exec
gateway.
- `exec.approvals.node.get` dan `exec.approvals.node.set` mengelola kebijakan approval 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.
alur approval yang didefinisikan Plugin.
#### Keluarga utama lainnya
- otomasi:
- `wake` menjadwalkan injeksi teks bangun segera atau pada heartbeat berikutnya
- `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: `commands.list`, `skills.*`, `tools.catalog`, `tools.effective`
### Keluarga peristiwa umum
### Keluarga event umum
- `chat`: pembaruan chat UI seperti `chat.inject` dan peristiwa chat khusus transkrip
- `chat`: pembaruan chat UI seperti `chat.inject` dan event chat khusus transkrip
lainnya.
- `session.message` dan `session.tool`: pembaruan transkrip/aliran-peristiwa untuk sesi
- `session.message` dan `session.tool`: pembaruan transkrip/aliran event untuk sesi
yang dilanggani.
- `sessions.changed`: indeks sesi atau metadata berubah.
- `presence`: pembaruan snapshot kehadiran sistem.
- `tick`: peristiwa keepalive / liveness berkala.
- `tick`: event keepalive / liveness periodik.
- `health`: pembaruan snapshot kesehatan gateway.
- `heartbeat`: pembaruan aliran peristiwa heartbeat.
- `cron`: peristiwa perubahan run/pekerjaan cron.
- `heartbeat`: pembaruan aliran event Heartbeat.
- `cron`: event perubahan job/run 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 di-pairing.
- `voicewake.changed`: konfigurasi pemicu wake-word berubah.
- `device.pair.requested` / `device.pair.resolved`: siklus hidup perangkat yang dipasangkan.
- `voicewake.changed`: config trigger wake-word berubah.
- `exec.approval.requested` / `exec.approval.resolved`: siklus hidup
persetujuan exec.
- `plugin.approval.requested` / `plugin.approval.resolved`: siklus hidup persetujuan plugin.
approval exec.
- `plugin.approval.requested` / `plugin.approval.resolved`: siklus hidup
approval plugin.
### Metode helper node
### Method helper node
- Node dapat memanggil `skills.bins` untuk mengambil daftar executable skill saat ini
untuk pemeriksaan auto-allow.
### Metode helper operator
### Method helper operator
- Operator dapat memanggil `commands.list` (`operator.read`) untuk mengambil inventaris perintah runtime bagi sebuah agen.
- 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:
- `scope` mengontrol permukaan yang dituju `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:
- `provider` bersifat opsional dan hanya memengaruhi penamaan native plus ketersediaan perintah
Plugin native.
- `includeArgs=false` menghilangkan metadata argumen terserialisasi dari respons.
- Operator dapat memanggil `tools.catalog` (`operator.read`) untuk mengambil katalog tool runtime untuk sebuah
agen. Responsnya mencakup tool yang dikelompokkan dan metadata asal:
- `source`: `core` atau `plugin`
- `pluginId`: pemilik plugin saat `source="plugin"`
- `pluginId`: pemilik plugin ketika `source="plugin"`
- `optional`: apakah tool plugin bersifat opsional
- Operator dapat memanggil `tools.effective` (`operator.read`) untuk mengambil inventaris tool efektif-runtime
bagi sebuah sesi.
- `sessionKey` wajib diisi.
untuk suatu sesi.
- `sessionKey` wajib.
- Gateway menurunkan konteks runtime tepercaya dari sesi di sisi server alih-alih menerima
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.
auth atau konteks pengiriman yang disuplai pemanggil.
- Responsnya dibatasi per sesi dan mencerminkan apa yang dapat digunakan percakapan aktif saat ini,
termasuk core, plugin, dan tool channel.
- Operator dapat memanggil `skills.status` (`operator.read`) untuk mengambil inventaris
skill yang terlihat bagi sebuah agen.
Skills yang terlihat untuk sebuah agen.
- `agentId` bersifat opsional; hilangkan untuk membaca workspace agen default.
- 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.
- Responsnya mencakup kelayakan, persyaratan yang hilang, pemeriksaan config, dan
opsi instalasi yang 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 ClawHub: `{ source: "clawhub", slug, version?, force? }` memasang folder
skill ke direktori `skills/` workspace agen default.
- 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:
@ -479,95 +495,128 @@ yang dapat dipanggil yang diimplementasikan dalam `src/gateway/server-methods/*.
- Mode config mem-patch nilai `skills.entries.<skillKey>` seperti `enabled`,
`apiKey`, dan `env`.
## Persetujuan exec
## Approval exec
- Saat permintaan exec memerlukan persetujuan, gateway menyiarkan `exec.approval.requested`.
- Saat permintaan exec memerlukan approval, gateway menyiarkan `exec.approval.requested`.
- 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
- Untuk `host=node`, `exec.approval.request` harus menyertakan `systemRunPlan` (`argv`/`cwd`/`rawCommand`/metadata sesi kanonis). Permintaan yang tidak memiliki `systemRunPlan` akan ditolak.
- Setelah approval, panggilan `node.invoke system.run` yang diteruskan menggunakan kembali
`systemRunPlan` kanonis tersebut sebagai konteks perintah/cwd/sesi yang otoritatif.
- Jika pemanggil mengubah `command`, `rawCommand`, `cwd`, `agentId`, atau
`sessionKey` antara prepare dan penerusan `system.run` final yang telah disetujui,
gateway menolak run tersebut alih-alih memercayai muatan yang telah diubah.
- Jika pemanggil memodifikasi `command`, `rawCommand`, `cwd`, `agentId`, atau
`sessionKey` antara prepare dan penerusan `system.run` final yang disetujui, maka
gateway menolak eksekusi tersebut alih-alih mempercayai payload yang telah dimodifikasi.
## Fallback pengiriman agen
- Permintaan `agent` dapat menyertakan `deliver=true` untuk meminta pengiriman keluar.
- `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).
- `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 diselesaikan (misalnya sesi internal/webchat atau config multi-channel yang ambigu).
## Pembuatan versi
- `PROTOCOL_VERSION` berada di `src/gateway/protocol/schema.ts`.
- `PROTOCOL_VERSION` berada di `src/gateway/protocol/schema/protocol-schemas.ts`.
- Klien mengirim `minProtocol` + `maxProtocol`; server menolak ketidakcocokan.
- Skema + model dihasilkan dari definisi TypeBox:
- `pnpm protocol:gen`
- `pnpm protocol:gen:swift`
- `pnpm protocol:check`
### Konstanta klien
Klien referensi di `src/gateway/client.ts` menggunakan default berikut. Nilai-nilai ini
stabil di seluruh protokol v3 dan merupakan baseline yang diharapkan untuk klien pihak ketiga.
| Constant | Default | Source |
| ----------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------- |
| `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` |
| Timeout permintaan (per RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) |
| Timeout preauth / connect-challenge | `10_000` ms | `src/gateway/handshake-timeouts.ts` (clamp `250``10_000`) |
| Backoff reconnect awal | `1_000` ms | `src/gateway/client.ts` (`backoffMs`) |
| Backoff reconnect maksimum | `30_000` ms | `src/gateway/client.ts` (`scheduleReconnect`) |
| Clamp percobaan ulang cepat setelah device-token close | `250` ms | `src/gateway/client.ts` |
| Masa tenggang force-stop sebelum `terminate()` | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` |
| Timeout default `stopAndWait()` | `1_000` ms | `STOP_AND_WAIT_TIMEOUT_MS` |
| Interval tick default (pra `hello-ok`) | `30_000` ms | `src/gateway/client.ts` |
| Penutupan karena timeout tick | kode `4000` ketika senyap melebihi `tickIntervalMs * 2` | `src/gateway/client.ts` |
| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 MB) | `src/gateway/server-constants.ts` |
Server mengiklankan `policy.tickIntervalMs`, `policy.maxPayload`,
dan `policy.maxBufferedBytes` efektif dalam `hello-ok`; klien harus mematuhi nilai tersebut
alih-alih default pra-handshake.
## Auth
- Auth gateway shared-secret menggunakan `connect.params.auth.token` atau
`connect.params.auth.password`, tergantung pada mode auth yang dikonfigurasi.
`connect.params.auth.password`, bergantung 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 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.
(`gateway.auth.allowTailscale: true`) atau `gateway.auth.mode: "trusted-proxy"`
non-loopback memenuhi pemeriksaan auth connect dari header permintaan, bukan dari
`connect.params.auth.*`.
- `gateway.auth.mode: "none"` untuk private-ingress melewati auth connect shared-secret
sepenuhnya; 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 koneksi 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
koneksi berhasil.
- Saat menyambung kembali dengan token perangkat **tersimpan** tersebut, klien juga harus menggunakan kembali
set cakupan tersimpan yang telah disetujui untuk token tersebut. Ini mempertahankan akses
baca/probe/status yang sudah diberikan dan menghindari reconnect yang diam-diam menyusut ke
cakupan implisit khusus admin yang lebih sempit.
- Perakitan auth connect sisi klien (`selectConnectAuth` di
`src/gateway/client.ts`):
- `auth.password` bersifat ortogonal dan selalu diteruskan ketika disetel.
- `auth.token` diisi berdasarkan urutan prioritas: shared token eksplisit terlebih dahulu,
lalu `deviceToken` eksplisit, lalu token per-perangkat yang tersimpan (dikunci berdasarkan
`deviceId` + `role`).
- `auth.bootstrapToken` hanya dikirim ketika tidak satu pun dari hal di atas me-resolve
sebuah `auth.token`. Shared token atau token perangkat apa pun yang ter-resolve akan menekannya.
- Auto-promotion token perangkat tersimpan pada percobaan ulang sekali jalan
`AUTH_TOKEN_MISMATCH` dibatasi hanya untuk **endpoint tepercaya**
loopback, atau `wss://` dengan `tlsFingerprint` yang dipin. `wss://` publik
tanpa pinning tidak memenuhi syarat.
- Entri tambahan `hello-ok.auth.deviceTokens` adalah token handoff bootstrap.
Simpan token tersebut hanya ketika 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
- Jika klien menyuplai `deviceToken` **eksplisit** atau `scopes` eksplisit, maka
set cakupan yang diminta pemanggil tersebut tetap otoritatif; cakupan cache hanya
digunakan kembali ketika klien menggunakan ulang token per-perangkat yang tersimpan.
- Token perangkat dapat diputar/dicabut melalui `device.token.rotate` dan
`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
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**.
- Penerbitan/rotasi token tetap dibatasi pada set peran yang disetujui dan tercatat dalam
entri pairing perangkat tersebut; memutar token tidak dapat memperluas perangkat ke
peran yang tidak pernah diberikan oleh approval pairing.
- Untuk sesi token perangkat berpasangan, pengelolaan perangkat dibatasi untuk dirinya sendiri kecuali
pemanggil juga memiliki `operator.admin`: pemanggil non-admin hanya dapat
menghapus/mencabut/memutar entri perangkat **miliknya 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
cakupan sesi saat ini milik pemanggil. Pemanggil non-admin tidak dapat memutar token ke
set cakupan operator yang lebih luas daripada yang sudah mereka miliki.
- Kegagalan auth mencakup `error.details.code` plus petunjuk pemulihan:
- Kegagalan auth menyertakan `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 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.
- Klien tepercaya dapat mencoba satu percobaan ulang terbatas dengan token per-perangkat yang di-cache.
- Jika percobaan ulang itu gagal, klien harus menghentikan loop reconnect otomatis dan menampilkan panduan tindakan operator.
## Identitas perangkat + pairing
- Node harus menyertakan identitas perangkat stabil (`device.id`) yang diturunkan dari
- Node harus menyertakan identitas perangkat yang stabil (`device.id`) yang diturunkan dari
fingerprint keypair.
- Gateway menerbitkan token per perangkat + peran.
- Persetujuan pairing diperlukan untuk ID perangkat baru kecuali auto-approval lokal
- Approval pairing diperlukan untuk ID perangkat baru kecuali auto-approval lokal
diaktifkan.
- Auto-approval pairing berpusat pada koneksi local loopback langsung.
- Auto-approval pairing berpusat pada koneksi loopback lokal langsung.
- OpenClaw juga memiliki jalur self-connect backend/container-local yang sempit untuk
alur helper shared-secret tepercaya.
- Koneksi tailnet host yang sama atau LAN tetap diperlakukan sebagai koneksi jarak jauh untuk pairing dan
memerlukan persetujuan.
- Koneksi tailnet atau LAN pada host yang sama tetap diperlakukan sebagai koneksi jarak jauh untuk pairing dan
memerlukan approval.
- Semua klien WS harus menyertakan identitas `device` selama `connect` (operator + node).
Control UI dapat menghilangkannya hanya dalam mode berikut:
Control UI hanya dapat mengabaikannya 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 berat).
- Semua koneksi harus menandatangani nonce `connect.challenge` yang disediakan server.
- auth operator `gateway.auth.mode: "trusted-proxy"` Control UI yang berhasil.
- `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (break-glass, penurunan keamanan yang parah).
- Semua koneksi harus menandatangani nonce `connect.challenge` yang diberikan server.
### Diagnostik migrasi auth perangkat
@ -576,33 +625,33 @@ kode detail `DEVICE_AUTH_*` di bawah `error.details.code` dengan `error.details.
Kegagalan migrasi umum:
| Pesan | details.code | details.reason | Arti |
| Message | details.code | details.reason | Meaning |
| --------------------------- | -------------------------------- | ------------------------ | -------------------------------------------------- |
| `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. |
| `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | Klien mengabaikan `device.nonce` (atau mengirim kosong). |
| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | Klien menandatangani dengan nonce yang stale/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. |
Target migrasi:
- Selalu tunggu `connect.challenge`.
- Tanda tangani muatan v2 yang menyertakan nonce server.
- Kirim nonce yang sama dalam `connect.params.device.nonce`.
- Muatan signature yang disarankan adalah `v3`, yang mengikat `platform` dan `deviceFamily`
selain field device/client/role/scopes/token/nonce.
- Signature `v2` lama tetap diterima untuk kompatibilitas, tetapi pinning metadata
paired-device tetap mengontrol kebijakan perintah saat reconnect.
- Tandatangani payload v2 yang menyertakan nonce server.
- Kirim nonce yang sama di `connect.params.device.nonce`.
- Payload tanda tangan yang disukai adalah `v3`, yang mengikat `platform` dan `deviceFamily`
selain field perangkat/klien/peran/cakupan/token/nonce.
- Tanda tangan `v2` lama tetap diterima untuk kompatibilitas, tetapi pinning metadata
perangkat berpasangan tetap mengontrol kebijakan perintah saat reconnect.
## TLS + pinning
- TLS didukung untuk koneksi WS.
- Klien dapat secara opsional melakukan pinning fingerprint sertifikat gateway (lihat config `gateway.tls`
serta `gateway.remote.tlsFingerprint` atau CLI `--tls-fingerprint`).
- Klien dapat secara opsional mem-pin fingerprint sertifikat gateway (lihat config `gateway.tls`
plus `gateway.remote.tlsFingerprint` atau CLI `--tls-fingerprint`).
## Cakupan
Protokol ini mengekspos **API gateway lengkap** (status, channel, model, chat,
agen, sesi, node, persetujuan, dll.). Permukaan persisnya didefinisikan oleh
agent, sesi, node, approval, dll.). Permukaan persisnya didefinisikan oleh
skema TypeBox di `src/gateway/protocol/schema.ts`.

View File

@ -1,14 +1,14 @@
---
read_when:
- Anda ingin menggunakan model Google Gemini dengan OpenClaw
- Anda memerlukan alur auth API key atau OAuth
summary: Penyiapan Google Gemini (API key + OAuth, pembuatan gambar, pemahaman media, pencarian web)
- Anda memerlukan kunci API atau alur autentikasi OAuth
summary: Penyiapan Google Gemini (kunci API + OAuth, pembuatan gambar, pemahaman media, TTS, pencarian web)
title: Google (Gemini)
x-i18n:
generated_at: "2026-04-12T23:30:55Z"
generated_at: "2026-04-16T09:14:37Z"
model: gpt-5.4
provider: openai
source_hash: 64b848add89061b208a5d6b19d206c433cace5216a0ca4b63d56496aecbde452
source_hash: ec2d62855f5e80efda758aad71bcaa95c38b1e41761fa1100d47a06c62881419
source_path: providers/google.md
workflow: 15
---
@ -16,7 +16,7 @@ x-i18n:
# Google (Gemini)
Plugin Google menyediakan akses ke model Gemini melalui Google AI Studio, serta
pembuatan gambar, pemahaman media (gambar/audio/video), dan pencarian web melalui
pembuatan gambar, pemahaman media (gambar/audio/video), text-to-speech, dan pencarian web melalui
Gemini Grounding.
- Provider: `google`
@ -26,10 +26,10 @@ Gemini Grounding.
## Memulai
Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
Pilih metode autentikasi yang Anda inginkan dan ikuti langkah-langkah penyiapan.
<Tabs>
<Tab title="API key">
<Tab title="Kunci API">
**Terbaik untuk:** akses API Gemini standar melalui Google AI Studio.
<Steps>
@ -38,7 +38,7 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
openclaw onboard --auth-choice gemini-api-key
```
Atau berikan key secara langsung:
Atau berikan kunci secara langsung:
```bash
openclaw onboard --non-interactive \
@ -47,7 +47,7 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
--gemini-api-key "$GEMINI_API_KEY"
```
</Step>
<Step title="Setel model default">
<Step title="Tetapkan model default">
```json5
{
agents: {
@ -58,7 +58,7 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
}
```
</Step>
<Step title="Verifikasi model tersedia">
<Step title="Verifikasi bahwa model tersedia">
```bash
openclaw models list --provider google
```
@ -66,13 +66,13 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
</Steps>
<Tip>
Variabel environment `GEMINI_API_KEY` dan `GOOGLE_API_KEY` sama-sama didukung. Gunakan salah satu yang sudah Anda konfigurasikan.
Variabel lingkungan `GEMINI_API_KEY` dan `GOOGLE_API_KEY` keduanya didukung. Gunakan mana saja yang sudah Anda konfigurasi.
</Tip>
</Tab>
<Tab title="Gemini CLI (OAuth)">
**Terbaik untuk:** menggunakan kembali login Gemini CLI yang sudah ada melalui PKCE OAuth alih-alih API key terpisah.
**Terbaik untuk:** menggunakan kembali login Gemini CLI yang sudah ada melalui PKCE OAuth alih-alih kunci API terpisah.
<Warning>
Provider `google-gemini-cli` adalah integrasi tidak resmi. Beberapa pengguna
@ -81,7 +81,7 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
<Steps>
<Step title="Instal Gemini CLI">
Perintah `gemini` lokal harus tersedia di `PATH`.
Perintah lokal `gemini` harus tersedia di `PATH`.
```bash
# Homebrew
@ -91,15 +91,15 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
npm install -g @google/gemini-cli
```
OpenClaw mendukung instalasi Homebrew maupun instalasi npm global, termasuk
tata letak Windows/npm yang umum.
OpenClaw mendukung instalasi Homebrew dan instalasi npm global, termasuk
tata letak umum Windows/npm.
</Step>
<Step title="Masuk melalui OAuth">
```bash
openclaw models auth login --provider google-gemini-cli --set-default
```
</Step>
<Step title="Verifikasi model tersedia">
<Step title="Verifikasi bahwa model tersedia">
```bash
openclaw models list --provider google-gemini-cli
```
@ -109,7 +109,7 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
- Model default: `google-gemini-cli/gemini-3-flash-preview`
- Alias: `gemini-cli`
**Variabel environment:**
**Variabel lingkungan:**
- `OPENCLAW_GEMINI_OAUTH_CLIENT_ID`
- `OPENCLAW_GEMINI_OAUTH_CLIENT_SECRET`
@ -117,17 +117,17 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
(Atau varian `GEMINI_CLI_*`.)
<Note>
Jika permintaan OAuth Gemini CLI gagal setelah login, setel `GOOGLE_CLOUD_PROJECT` atau
`GOOGLE_CLOUD_PROJECT_ID` pada host gateway lalu coba lagi.
Jika permintaan OAuth Gemini CLI gagal setelah login, tetapkan `GOOGLE_CLOUD_PROJECT` atau
`GOOGLE_CLOUD_PROJECT_ID` pada host Gateway lalu coba lagi.
</Note>
<Note>
Jika login gagal sebelum alur browser dimulai, pastikan perintah `gemini` lokal
Jika login gagal sebelum alur browser dimulai, pastikan perintah lokal `gemini`
terinstal dan ada di `PATH`.
</Note>
Provider `google-gemini-cli` yang khusus OAuth adalah
surface inferensi teks yang terpisah. Pembuatan gambar, pemahaman media, dan Gemini Grounding tetap berada pada
Provider `google-gemini-cli` yang hanya mendukung OAuth adalah
surface inferensi teks terpisah. Pembuatan gambar, pemahaman media, dan Gemini Grounding tetap berada pada
id provider `google`.
</Tab>
@ -135,11 +135,12 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
## Kemampuan
| Capability | Supported |
| Kemampuan | Didukung |
| ---------------------- | ----------------- |
| Chat completions | Ya |
| Penyelesaian chat | Ya |
| Pembuatan gambar | Ya |
| Pembuatan musik | Ya |
| Text-to-speech | Ya |
| Pemahaman gambar | Ya |
| Transkripsi audio | Ya |
| Pemahaman video | Ya |
@ -149,8 +150,8 @@ Pilih metode auth yang Anda inginkan dan ikuti langkah penyiapannya.
<Tip>
Model Gemma 4 (misalnya `gemma-4-26b-a4b-it`) mendukung mode thinking. OpenClaw
menulis ulang `thinkingBudget` ke `thinkingLevel` Google yang didukung untuk Gemma 4.
Menyetel thinking ke `off` mempertahankan thinking nonaktif alih-alih memetakannya ke
menulis ulang `thinkingBudget` menjadi `thinkingLevel` Google yang didukung untuk Gemma 4.
Menetapkan thinking ke `off` akan mempertahankan thinking dalam keadaan nonaktif alih-alih memetakannya ke
`MINIMAL`.
</Tip>
@ -160,8 +161,8 @@ Provider pembuatan gambar `google` bawaan secara default menggunakan
`google/gemini-3.1-flash-image-preview`.
- Juga mendukung `google/gemini-3-pro-image-preview`
- Generate: hingga 4 gambar per permintaan
- Mode edit: aktif, hingga 5 gambar input
- Hasilkan: hingga 4 gambar per permintaan
- Mode edit: diaktifkan, hingga 5 gambar masukan
- Kontrol geometri: `size`, `aspectRatio`, dan `resolution`
Untuk menggunakan Google sebagai provider gambar default:
@ -179,12 +180,12 @@ Untuk menggunakan Google sebagai provider gambar default:
```
<Note>
Lihat [Image Generation](/id/tools/image-generation) untuk parameter tool bersama, pemilihan provider, dan perilaku failover.
Lihat [Pembuatan Gambar](/id/tools/image-generation) untuk parameter alat bersama, pemilihan provider, dan perilaku failover.
</Note>
## Pembuatan video
Plugin `google` bawaan juga mendaftarkan pembuatan video melalui tool bersama
Plugin `google` bawaan juga mendaftarkan pembuatan video melalui alat bersama
`video_generate`.
- Model video default: `google/veo-3.1-fast-generate-preview`
@ -207,20 +208,20 @@ Untuk menggunakan Google sebagai provider video default:
```
<Note>
Lihat [Video Generation](/id/tools/video-generation) untuk parameter tool bersama, pemilihan provider, dan perilaku failover.
Lihat [Pembuatan Video](/id/tools/video-generation) untuk parameter alat bersama, pemilihan provider, dan perilaku failover.
</Note>
## Pembuatan musik
Plugin `google` bawaan juga mendaftarkan pembuatan musik melalui tool bersama
Plugin `google` bawaan juga mendaftarkan pembuatan musik melalui alat bersama
`music_generate`.
- Model musik default: `google/lyria-3-clip-preview`
- Juga mendukung `google/lyria-3-pro-preview`
- Kontrol prompt: `lyrics` dan `instrumental`
- Format output: `mp3` secara default, ditambah `wav` pada `google/lyria-3-pro-preview`
- Input referensi: hingga 10 gambar
- Eksekusi berbasis sesi dilepas melalui alur task/status bersama, termasuk `action: "status"`
- Format keluaran: `mp3` secara default, ditambah `wav` pada `google/lyria-3-pro-preview`
- Masukan referensi: hingga 10 gambar
- Proses berbasis sesi dilepas melalui alur tugas/status bersama, termasuk `action: "status"`
Untuk menggunakan Google sebagai provider musik default:
@ -237,21 +238,65 @@ Untuk menggunakan Google sebagai provider musik default:
```
<Note>
Lihat [Music Generation](/id/tools/music-generation) untuk parameter tool bersama, pemilihan provider, dan perilaku failover.
Lihat [Pembuatan Musik](/id/tools/music-generation) untuk parameter alat bersama, pemilihan provider, dan perilaku failover.
</Note>
## Text-to-speech
Provider ucapan `google` bawaan menggunakan jalur TTS Google Gemini API dengan
`gemini-3.1-flash-tts-preview`.
- Suara default: `Kore`
- Auth: `messages.tts.providers.google.apiKey`, `models.providers.google.apiKey`, `GEMINI_API_KEY`, atau `GOOGLE_API_KEY`
- Keluaran: WAV untuk lampiran TTS biasa, PCM untuk Talk/teleponi
- Keluaran catatan suara native: tidak didukung pada jalur Gemini API ini karena API mengembalikan PCM, bukan Opus
Untuk menggunakan Google sebagai provider TTS default:
```json5
{
messages: {
tts: {
auto: "always",
provider: "google",
providers: {
google: {
model: "gemini-3.1-flash-tts-preview",
voiceName: "Kore",
},
},
},
},
}
```
Gemini API TTS menerima tag audio ekspresif dalam tanda kurung siku di dalam teks, seperti
`[whispers]` atau `[laughs]`. Agar tag tidak muncul di balasan chat yang terlihat sambil
tetap mengirimkannya ke TTS, letakkan tag tersebut di dalam blok `[[tts:text]]...[[/tts:text]]`:
```text
Berikut adalah teks balasan yang bersih.
[[tts:text]][whispers] Berikut adalah versi yang diucapkan.[[/tts:text]]
```
<Note>
Kunci API Google Cloud Console yang dibatasi untuk Gemini API valid untuk
provider ini. Ini bukan jalur Cloud Text-to-Speech API yang terpisah.
</Note>
## Konfigurasi lanjutan
<AccordionGroup>
<Accordion title="Reuse cache Gemini langsung">
Untuk eksekusi API Gemini langsung (`api: "google-generative-ai"`), OpenClaw
<Accordion title="Penggunaan ulang cache Gemini langsung">
Untuk proses Gemini API langsung (`api: "google-generative-ai"`), OpenClaw
meneruskan handle `cachedContent` yang dikonfigurasi ke permintaan Gemini.
- Konfigurasikan parameter per-model atau global dengan
- Konfigurasikan parameter per model atau global dengan
`cachedContent` atau `cached_content` lama
- Jika keduanya ada, `cachedContent` yang diprioritaskan
- Nilai contoh: `cachedContents/prebuilt-context`
- Penggunaan cache-hit Gemini dinormalisasi ke `cacheRead` OpenClaw dari
- Contoh nilai: `cachedContents/prebuilt-context`
- Penggunaan cache-hit Gemini dinormalisasi menjadi `cacheRead` OpenClaw dari
`cachedContentTokenCount` upstream
```json5
@ -274,17 +319,17 @@ Lihat [Music Generation](/id/tools/music-generation) untuk parameter tool bersam
<Accordion title="Catatan penggunaan JSON Gemini CLI">
Saat menggunakan provider OAuth `google-gemini-cli`, OpenClaw menormalisasi
output JSON CLI sebagai berikut:
keluaran JSON CLI sebagai berikut:
- Teks balasan berasal dari field JSON `response` milik CLI.
- Penggunaan fallback ke `stats` saat CLI membiarkan `usage` kosong.
- `stats.cached` dinormalisasi ke `cacheRead` OpenClaw.
- Jika `stats.input` tidak ada, OpenClaw menurunkan token input dari
- Teks balasan berasal dari field `response` pada JSON CLI.
- Penggunaan akan menggunakan `stats` jika CLI membiarkan `usage` kosong.
- `stats.cached` dinormalisasi menjadi `cacheRead` OpenClaw.
- Jika `stats.input` tidak ada, OpenClaw menurunkan token masukan dari
`stats.input_tokens - stats.cached`.
</Accordion>
<Accordion title="Environment dan penyiapan daemon">
<Accordion title="Penyiapan lingkungan dan daemon">
Jika Gateway berjalan sebagai daemon (launchd/systemd), pastikan `GEMINI_API_KEY`
tersedia untuk proses tersebut (misalnya, di `~/.openclaw/.env` atau melalui
`env.shellEnv`).
@ -295,15 +340,15 @@ Lihat [Music Generation](/id/tools/music-generation) untuk parameter tool bersam
<CardGroup cols={2}>
<Card title="Pemilihan model" href="/id/concepts/model-providers" icon="layers">
Memilih provider, ref model, dan perilaku failover.
Memilih provider, referensi model, dan perilaku failover.
</Card>
<Card title="Pembuatan gambar" href="/id/tools/image-generation" icon="image">
Parameter tool gambar bersama dan pemilihan provider.
Parameter alat gambar bersama dan pemilihan provider.
</Card>
<Card title="Pembuatan video" href="/id/tools/video-generation" icon="video">
Parameter tool video bersama dan pemilihan provider.
Parameter alat video bersama dan pemilihan provider.
</Card>
<Card title="Pembuatan musik" href="/id/tools/music-generation" icon="music">
Parameter tool musik bersama dan pemilihan provider.
Parameter alat musik bersama dan pemilihan provider.
</Card>
</CardGroup>

View File

@ -0,0 +1,132 @@
---
x-i18n:
generated_at: "2026-04-16T09:14:29Z"
model: gpt-5.4
provider: openai
source_hash: 95e56c5411204363676f002059c942201503e2359515d1a4b409882cc2e04920
source_path: refactor/async-exec-duplicate-completion-investigation.md
workflow: 15
---
# Investigasi Penyelesaian Duplikat Async Exec
## Cakupan
- Sesi: `agent:main:telegram:group:-1003774691294:topic:1`
- Gejala: completion async exec yang sama untuk session/run `keen-nexus` tercatat dua kali di LCM sebagai giliran pengguna.
- Tujuan: mengidentifikasi apakah ini kemungkinan besar merupakan injeksi sesi duplikat atau sekadar retry pengiriman outbound biasa.
## Kesimpulan
Kemungkinan besar ini adalah **injeksi sesi duplikat**, bukan retry pengiriman outbound murni.
Celah sisi gateway yang paling kuat ada di **jalur penyelesaian exec node**:
1. Penyelesaian exec di sisi node memancarkan `exec.finished` dengan `runId` lengkap.
2. Gateway `server-node-events` mengubahnya menjadi system event dan meminta heartbeat.
3. Heartbeat run menyuntikkan blok system event yang telah dikuras ke dalam prompt agen.
4. Embedded runner menyimpan prompt tersebut sebagai giliran pengguna baru dalam transkrip sesi.
Jika `exec.finished` yang sama mencapai gateway dua kali untuk `runId` yang sama karena alasan apa pun (replay, duplikat saat reconnect, resend dari upstream, producer terduplikasi), OpenClaw saat ini **tidak memiliki pemeriksaan idempotensi yang dikunci oleh `runId`/`contextKey`** pada jalur ini. Salinan kedua akan menjadi pesan pengguna kedua dengan konten yang sama.
## Jalur Kode yang Tepat
### 1. Produser: event penyelesaian exec node
- `src/node-host/invoke.ts:340-360`
- `sendExecFinishedEvent(...)` memancarkan `node.event` dengan event `exec.finished`.
- Payload mencakup `sessionKey` dan `runId` lengkap.
### 2. Ingesti event gateway
- `src/gateway/server-node-events.ts:574-640`
- Menangani `exec.finished`.
- Membangun teks:
- `Exec finished (node=..., id=<runId>, code ...)`
- Mengantrikannya melalui:
- `enqueueSystemEvent(text, { sessionKey, contextKey: runId ? \`exec:${runId}\` : "exec", trusted: false })`
- Segera meminta wake:
- `requestHeartbeatNow(scopedHeartbeatWakeOptions(sessionKey, { reason: "exec-event" }))`
### 3. Kelemahan dedupe system event
- `src/infra/system-events.ts:90-115`
- `enqueueSystemEvent(...)` hanya menekan **teks duplikat yang berurutan**:
- `if (entry.lastText === cleaned) return false`
- Ia menyimpan `contextKey`, tetapi **tidak** menggunakan `contextKey` untuk idempotensi.
- Setelah drain, penekanan duplikat di-reset.
Artinya, `exec.finished` yang direplay dengan `runId` yang sama bisa diterima lagi nanti, walaupun kode sudah memiliki kandidat idempotensi yang stabil (`exec:<runId>`).
### 4. Penanganan wake bukan pengganda utama
- `src/infra/heartbeat-wake.ts:79-117`
- Wake digabungkan berdasarkan `(agentId, sessionKey)`.
- Permintaan wake duplikat untuk target yang sama runtuh menjadi satu entri wake tertunda.
Ini membuat **penanganan wake duplikat saja** menjadi penjelasan yang lebih lemah daripada ingesti event duplikat.
### 5. Heartbeat mengonsumsi event dan mengubahnya menjadi input prompt
- `src/infra/heartbeat-runner.ts:535-574`
- Preflight mengintip system event tertunda dan mengklasifikasikan run exec-event.
- `src/auto-reply/reply/session-system-events.ts:86-90`
- `drainFormattedSystemEvents(...)` menguras antrean untuk sesi tersebut.
- `src/auto-reply/reply/get-reply-run.ts:400-427`
- Blok system event yang telah dikuras didahulukan ke badan prompt agen.
### 6. Titik injeksi transkrip
- `src/agents/pi-embedded-runner/run/attempt.ts:2000-2017`
- `activeSession.prompt(effectivePrompt)` mengirim prompt lengkap ke sesi PI embedded.
- Itulah titik ketika prompt turunan completion menjadi giliran pengguna yang tersimpan.
Jadi begitu system event yang sama dibangun ulang ke dalam prompt dua kali, pesan pengguna LCM duplikat memang diharapkan.
## Mengapa retry pengiriman outbound biasa lebih kecil kemungkinannya
Ada jalur kegagalan outbound yang nyata di heartbeat runner:
- `src/infra/heartbeat-runner.ts:1194-1242`
- Balasan dibuat lebih dulu.
- Pengiriman outbound terjadi kemudian melalui `deliverOutboundPayloads(...)`.
- Kegagalan di sana mengembalikan `{ status: "failed" }`.
Namun, untuk entri antrean system event yang sama, ini saja **tidak cukup** untuk menjelaskan giliran pengguna duplikat:
- `src/auto-reply/reply/session-system-events.ts:86-90`
- Antrean system event sudah dikuras sebelum pengiriman outbound.
Jadi retry kirim kanal dengan sendirinya tidak akan membuat ulang event antrean yang sama secara persis. Itu bisa menjelaskan pengiriman eksternal yang hilang/gagal, tetapi tidak dengan sendirinya menjelaskan pesan pengguna sesi identik kedua.
## Kemungkinan sekunder dengan keyakinan lebih rendah
Ada loop retry full-run di runner agen:
- `src/auto-reply/reply/agent-runner-execution.ts:741-1473`
- Kegagalan transien tertentu dapat me-retry seluruh run dan mengirim ulang `commandBody` yang sama.
Ini dapat menggandakan prompt pengguna yang tersimpan **dalam eksekusi balasan yang sama** jika prompt sudah ditambahkan sebelum kondisi retry terpicu.
Saya menempatkannya lebih rendah daripada ingest `exec.finished` duplikat karena:
- jeda yang diamati sekitar 51 detik, yang terlihat lebih seperti giliran/wake kedua daripada retry dalam proses;
- laporan sudah menyebut kegagalan pengiriman pesan berulang, yang lebih mengarah ke giliran terpisah yang terjadi kemudian daripada retry model/runtime yang langsung.
## Hipotesis Akar Masalah
Hipotesis dengan keyakinan tertinggi:
- Completion `keen-nexus` datang melalui **jalur event exec node**.
- `exec.finished` yang sama dikirim ke `server-node-events` dua kali.
- Gateway menerima keduanya karena `enqueueSystemEvent(...)` tidak melakukan dedupe berdasarkan `contextKey` / `runId`.
- Setiap event yang diterima memicu heartbeat dan disuntikkan sebagai giliran pengguna ke transkrip PI.
## Usulan Perbaikan Bedah Kecil
Jika perbaikan diinginkan, perubahan kecil dengan nilai tinggi adalah:
- buat idempotensi exec/system-event menghormati `contextKey` untuk horizon singkat, setidaknya untuk pengulangan `(sessionKey, contextKey, text)` yang persis;
- atau tambahkan dedupe khusus di `server-node-events` untuk `exec.finished` yang dikunci oleh `(sessionKey, runId, jenis event)`.
Itu akan langsung memblokir duplikat `exec.finished` yang direplay sebelum berubah menjadi giliran sesi.

View File

@ -1,56 +1,55 @@
---
read_when:
- Mengaktifkan text-to-speech untuk balasan
- Mengonfigurasi provider atau batas TTS
- Menggunakan perintah `/tts`
- Mengonfigurasi penyedia TTS atau batasan
- Menggunakan perintah /tts
summary: Text-to-speech (TTS) untuk balasan keluar
title: Text-to-Speech
x-i18n:
generated_at: "2026-04-12T23:33:41Z"
generated_at: "2026-04-16T09:14:37Z"
model: gpt-5.4
provider: openai
source_hash: ad79a6be34879347dc73fdab1bd219823cd7c6aa8504e3e4c73e1a0554c837c5
source_hash: de7c1dc8831c1ba307596afd48cb4d36f844724887a13b17e35f41ef5174a86f
source_path: tools/tts.md
workflow: 15
---
# Text-to-speech (TTS)
OpenClaw dapat mengubah balasan keluar menjadi audio menggunakan ElevenLabs, Microsoft, MiniMax, atau OpenAI.
OpenClaw dapat mengonversi balasan keluar menjadi audio menggunakan ElevenLabs, Google Gemini, Microsoft, MiniMax, atau OpenAI.
Fitur ini berfungsi di mana pun OpenClaw dapat mengirim audio.
## Layanan yang didukung
- **ElevenLabs** (provider utama atau fallback)
- **Microsoft** (provider utama atau fallback; implementasi bawaan saat ini menggunakan `node-edge-tts`)
- **MiniMax** (provider utama atau fallback; menggunakan API T2A v2)
- **OpenAI** (provider utama atau fallback; juga digunakan untuk ringkasan)
- **ElevenLabs** (penyedia utama atau cadangan)
- **Google Gemini** (penyedia utama atau cadangan; menggunakan Gemini API TTS)
- **Microsoft** (penyedia utama atau cadangan; implementasi bawaan saat ini menggunakan `node-edge-tts`)
- **MiniMax** (penyedia utama atau cadangan; menggunakan API T2A v2)
- **OpenAI** (penyedia utama atau cadangan; juga digunakan untuk ringkasan)
### Catatan speech Microsoft
Provider speech Microsoft bawaan saat ini menggunakan layanan TTS neural online Microsoft Edge melalui library `node-edge-tts`. Ini adalah layanan hosted (bukan
lokal), menggunakan endpoint Microsoft, dan tidak memerlukan API key.
`node-edge-tts` mengekspos opsi konfigurasi speech dan format output, tetapi
tidak semua opsi didukung oleh layanan tersebut. Input directive dan config lama yang
menggunakan `edge` tetap berfungsi dan dinormalisasi ke `microsoft`.
Penyedia speech Microsoft bawaan saat ini menggunakan layanan neural TTS online Microsoft Edge melalui library `node-edge-tts`. Ini adalah layanan yang di-hosting (bukan lokal), menggunakan endpoint Microsoft, dan tidak memerlukan API key.
`node-edge-tts` mengekspos opsi konfigurasi speech dan format output, tetapi tidak semua opsi didukung oleh layanan tersebut. Konfigurasi lama dan input directive yang menggunakan `edge` masih berfungsi dan dinormalisasi menjadi `microsoft`.
Karena jalur ini adalah layanan web publik tanpa SLA atau kuota yang dipublikasikan,
anggap ini sebagai best-effort. Jika Anda memerlukan batas dan dukungan yang terjamin, gunakan OpenAI
anggap ini sebagai upaya terbaik. Jika Anda memerlukan batas yang terjamin dan dukungan, gunakan OpenAI
atau ElevenLabs.
## Key opsional
## Kunci opsional
Jika Anda ingin OpenAI, ElevenLabs, atau MiniMax:
Jika Anda ingin menggunakan OpenAI, ElevenLabs, Google Gemini, atau MiniMax:
- `ELEVENLABS_API_KEY` (atau `XI_API_KEY`)
- `GEMINI_API_KEY` (atau `GOOGLE_API_KEY`)
- `MINIMAX_API_KEY`
- `OPENAI_API_KEY`
Speech Microsoft **tidak** memerlukan API key.
Jika beberapa provider dikonfigurasi, provider yang dipilih digunakan terlebih dahulu dan yang lainnya menjadi opsi fallback.
Jika beberapa penyedia dikonfigurasi, penyedia yang dipilih akan digunakan terlebih dahulu dan yang lainnya menjadi opsi cadangan.
Ringkasan otomatis menggunakan `summaryModel` yang dikonfigurasi (atau `agents.defaults.model.primary`),
jadi provider tersebut juga harus diautentikasi jika Anda mengaktifkan ringkasan.
jadi penyedia tersebut juga harus diautentikasi jika Anda mengaktifkan ringkasan.
## Tautan layanan
@ -64,18 +63,18 @@ jadi provider tersebut juga harus diautentikasi jika Anda mengaktifkan ringkasan
## Apakah ini diaktifkan secara default?
Tidak. AutoTTS **nonaktif** secara default. Aktifkan di config dengan
Tidak. AutoTTS **nonaktif** secara default. Aktifkan di konfigurasi dengan
`messages.tts.auto` atau secara lokal dengan `/tts on`.
Saat `messages.tts.provider` tidak disetel, OpenClaw memilih provider
speech pertama yang dikonfigurasi sesuai urutan auto-select registri.
Saat `messages.tts.provider` tidak disetel, OpenClaw memilih penyedia
speech pertama dalam urutan pemilihan otomatis registry.
## Config
## Konfigurasi
Config TTS berada di bawah `messages.tts` di `openclaw.json`.
Konfigurasi TTS berada di bawah `messages.tts` dalam `openclaw.json`.
Skema lengkap ada di [Konfigurasi Gateway](/id/gateway/configuration).
### Config minimal (aktifkan + provider)
### Konfigurasi minimal (aktifkan + penyedia)
```json5
{
@ -88,7 +87,7 @@ Skema lengkap ada di [Konfigurasi Gateway](/id/gateway/configuration).
}
```
### OpenAI utama dengan fallback ElevenLabs
### OpenAI utama dengan cadangan ElevenLabs
```json5
{
@ -176,7 +175,33 @@ Skema lengkap ada di [Konfigurasi Gateway](/id/gateway/configuration).
}
```
### Nonaktifkan speech Microsoft
### Google Gemini utama
```json5
{
messages: {
tts: {
auto: "always",
provider: "google",
providers: {
google: {
apiKey: "gemini_api_key",
model: "gemini-3.1-flash-tts-preview",
voiceName: "Kore",
},
},
},
},
}
```
Google Gemini TTS menggunakan jalur API key Gemini. API key Google Cloud Console
yang dibatasi untuk Gemini API valid di sini, dan ini adalah jenis key yang sama
yang digunakan oleh penyedia pembuatan gambar Google bawaan. Urutan resolusinya adalah
`messages.tts.providers.google.apiKey` -> `models.providers.google.apiKey` ->
`GEMINI_API_KEY` -> `GOOGLE_API_KEY`.
### Menonaktifkan speech Microsoft
```json5
{
@ -192,7 +217,7 @@ Skema lengkap ada di [Konfigurasi Gateway](/id/gateway/configuration).
}
```
### Batas kustom + path prefs
### Batas khusus + jalur prefs
```json5
{
@ -219,7 +244,7 @@ Skema lengkap ada di [Konfigurasi Gateway](/id/gateway/configuration).
}
```
### Nonaktifkan ringkasan otomatis untuk balasan panjang
### Menonaktifkan ringkasan otomatis untuk balasan panjang
```json5
{
@ -243,57 +268,61 @@ Lalu jalankan:
- `inbound` hanya mengirim audio setelah pesan suara masuk.
- `tagged` hanya mengirim audio saat balasan menyertakan directive `[[tts:key=value]]` atau blok `[[tts:text]]...[[/tts:text]]`.
- `enabled`: toggle lama (doctor memigrasikan ini ke `auto`).
- `mode`: `"final"` (default) atau `"all"` (termasuk balasan alat/blok).
- `provider`: id provider speech seperti `"elevenlabs"`, `"microsoft"`, `"minimax"`, atau `"openai"` (fallback otomatis).
- Jika `provider` **tidak disetel**, OpenClaw menggunakan provider speech pertama yang dikonfigurasi sesuai urutan auto-select registri.
- `provider: "edge"` lama tetap berfungsi dan dinormalisasi ke `microsoft`.
- `mode`: `"final"` (default) atau `"all"` (termasuk balasan tool/blok).
- `provider`: id penyedia speech seperti `"elevenlabs"`, `"google"`, `"microsoft"`, `"minimax"`, atau `"openai"` (cadangan bersifat otomatis).
- Jika `provider` **tidak disetel**, OpenClaw menggunakan penyedia speech pertama yang dikonfigurasi dalam urutan pemilihan otomatis registry.
- `provider: "edge"` lama masih berfungsi dan dinormalisasi menjadi `microsoft`.
- `summaryModel`: model murah opsional untuk ringkasan otomatis; default ke `agents.defaults.model.primary`.
- Menerima `provider/model` atau alias model yang dikonfigurasi.
- `modelOverrides`: izinkan model memancarkan directive TTS (aktif secara default).
- `allowProvider` default ke `false` (peralihan provider bersifat opt-in).
- `providers.<id>`: pengaturan milik provider yang dikunci dengan id provider speech.
- Blok provider langsung lama (`messages.tts.openai`, `messages.tts.elevenlabs`, `messages.tts.microsoft`, `messages.tts.edge`) dimigrasikan otomatis ke `messages.tts.providers.<id>` saat dimuat.
- `maxTextLength`: batas keras untuk input TTS (karakter). `/tts audio` gagal jika terlampaui.
- `timeoutMs`: timeout permintaan (md).
- `prefsPath`: timpa path JSON prefs lokal (provider/batas/ringkasan).
- Nilai `apiKey` fallback ke env var (`ELEVENLABS_API_KEY`/`XI_API_KEY`, `MINIMAX_API_KEY`, `OPENAI_API_KEY`).
- `providers.elevenlabs.baseUrl`: timpa base URL API ElevenLabs.
- `providers.openai.baseUrl`: timpa endpoint OpenAI TTS.
- `modelOverrides`: izinkan model mengeluarkan directive TTS (aktif secara default).
- `allowProvider` default ke `false` (peralihan penyedia bersifat opt-in).
- `providers.<id>`: pengaturan milik penyedia yang dikunci dengan id penyedia speech.
- Blok penyedia langsung lama (`messages.tts.openai`, `messages.tts.elevenlabs`, `messages.tts.microsoft`, `messages.tts.edge`) dimigrasikan otomatis ke `messages.tts.providers.<id>` saat dimuat.
- `maxTextLength`: batas keras untuk input TTS (karakter). `/tts audio` gagal jika melebihi batas.
- `timeoutMs`: batas waktu permintaan (ms).
- `prefsPath`: ganti jalur JSON prefs lokal (penyedia/batas/ringkasan).
- Nilai `apiKey` menggunakan fallback ke env vars (`ELEVENLABS_API_KEY`/`XI_API_KEY`, `GEMINI_API_KEY`/`GOOGLE_API_KEY`, `MINIMAX_API_KEY`, `OPENAI_API_KEY`).
- `providers.elevenlabs.baseUrl`: ganti base URL API ElevenLabs.
- `providers.openai.baseUrl`: ganti endpoint OpenAI TTS.
- Urutan resolusi: `messages.tts.providers.openai.baseUrl` -> `OPENAI_TTS_BASE_URL` -> `https://api.openai.com/v1`
- Nilai non-default diperlakukan sebagai endpoint TTS yang kompatibel dengan OpenAI, sehingga nama model dan suara kustom diterima.
- Nilai non-default diperlakukan sebagai endpoint TTS yang kompatibel dengan OpenAI, sehingga nama model dan voice khusus diterima.
- `providers.elevenlabs.voiceSettings`:
- `stability`, `similarityBoost`, `style`: `0..1`
- `useSpeakerBoost`: `true|false`
- `speed`: `0.5..2.0` (1.0 = normal)
- `providers.elevenlabs.applyTextNormalization`: `auto|on|off`
- `providers.elevenlabs.languageCode`: ISO 639-1 2 huruf (misalnya `en`, `de`)
- `providers.elevenlabs.seed`: integer `0..4294967295` (determinisme best-effort)
- `providers.minimax.baseUrl`: timpa base URL API MiniMax (default `https://api.minimax.io`, env: `MINIMAX_API_HOST`).
- `providers.elevenlabs.languageCode`: ISO 639-1 2 huruf (mis. `en`, `de`)
- `providers.elevenlabs.seed`: bilangan bulat `0..4294967295` (determinisme upaya terbaik)
- `providers.minimax.baseUrl`: ganti base URL API MiniMax (default `https://api.minimax.io`, env: `MINIMAX_API_HOST`).
- `providers.minimax.model`: model TTS (default `speech-2.8-hd`, env: `MINIMAX_TTS_MODEL`).
- `providers.minimax.voiceId`: pengenal suara (default `English_expressive_narrator`, env: `MINIMAX_TTS_VOICE_ID`).
- `providers.minimax.voiceId`: pengenal voice (default `English_expressive_narrator`, env: `MINIMAX_TTS_VOICE_ID`).
- `providers.minimax.speed`: kecepatan pemutaran `0.5..2.0` (default 1.0).
- `providers.minimax.vol`: volume `(0, 10]` (default 1.0; harus lebih besar dari 0).
- `providers.minimax.pitch`: pergeseran pitch `-12..12` (default 0).
- `providers.google.model`: model TTS Gemini (default `gemini-3.1-flash-tts-preview`).
- `providers.google.voiceName`: nama voice bawaan Gemini (default `Kore`; `voice` juga diterima).
- `providers.google.baseUrl`: ganti base URL API Gemini. Hanya `https://generativelanguage.googleapis.com` yang diterima.
- Jika `messages.tts.providers.google.apiKey` dihilangkan, TTS dapat menggunakan kembali `models.providers.google.apiKey` sebelum fallback ke env.
- `providers.microsoft.enabled`: izinkan penggunaan speech Microsoft (default `true`; tanpa API key).
- `providers.microsoft.voice`: nama suara neural Microsoft (misalnya `en-US-MichelleNeural`).
- `providers.microsoft.lang`: kode bahasa (misalnya `en-US`).
- `providers.microsoft.outputFormat`: format output Microsoft (misalnya `audio-24khz-48kbitrate-mono-mp3`).
- `providers.microsoft.voice`: nama voice neural Microsoft (mis. `en-US-MichelleNeural`).
- `providers.microsoft.lang`: kode bahasa (mis. `en-US`).
- `providers.microsoft.outputFormat`: format output Microsoft (mis. `audio-24khz-48kbitrate-mono-mp3`).
- Lihat format output Microsoft Speech untuk nilai yang valid; tidak semua format didukung oleh transport bawaan berbasis Edge.
- `providers.microsoft.rate` / `providers.microsoft.pitch` / `providers.microsoft.volume`: string persen (misalnya `+10%`, `-5%`).
- `providers.microsoft.saveSubtitles`: tulis subtitle JSON di samping berkas audio.
- `providers.microsoft.rate` / `providers.microsoft.pitch` / `providers.microsoft.volume`: string persentase (mis. `+10%`, `-5%`).
- `providers.microsoft.saveSubtitles`: tulis subtitle JSON di samping file audio.
- `providers.microsoft.proxy`: URL proxy untuk permintaan speech Microsoft.
- `providers.microsoft.timeoutMs`: override timeout permintaan (md).
- `providers.microsoft.timeoutMs`: ganti batas waktu permintaan (ms).
- `edge.*`: alias lama untuk pengaturan Microsoft yang sama.
## Override yang digerakkan model (aktif secara default)
## Override berbasis model (aktif secara default)
Secara default, model **dapat** memancarkan directive TTS untuk satu balasan.
Saat `messages.tts.auto` adalah `tagged`, directive ini wajib untuk memicu audio.
Secara default, model **dapat** mengeluarkan directive TTS untuk satu balasan.
Saat `messages.tts.auto` adalah `tagged`, directive ini diperlukan untuk memicu audio.
Saat diaktifkan, model dapat memancarkan directive `[[tts:...]]` untuk menimpa suara
untuk satu balasan, ditambah blok `[[tts:text]]...[[/tts:text]]` opsional untuk
menyediakan tag ekspresif (tawa, isyarat bernyanyi, dll.) yang seharusnya hanya muncul
di audio.
Saat diaktifkan, model dapat mengeluarkan directive `[[tts:...]]` untuk mengganti voice
untuk satu balasan, ditambah blok opsional `[[tts:text]]...[[/tts:text]]` untuk
memberikan tag ekspresif (tawa, isyarat bernyanyi, dll.) yang seharusnya hanya muncul dalam
audio.
Directive `provider=...` diabaikan kecuali `modelOverrides.allowProvider: true`.
@ -306,11 +335,11 @@ Ini dia.
[[tts:text]](tertawa) Bacakan lagunya sekali lagi.[[/tts:text]]
```
Key directive yang tersedia (saat diaktifkan):
Kunci directive yang tersedia (saat diaktifkan):
- `provider` (id provider speech yang terdaftar, misalnya `openai`, `elevenlabs`, `minimax`, atau `microsoft`; memerlukan `allowProvider: true`)
- `voice` (suara OpenAI) atau `voiceId` (ElevenLabs / MiniMax)
- `model` (model TTS OpenAI, id model ElevenLabs, atau model MiniMax)
- `provider` (id penyedia speech terdaftar, misalnya `openai`, `elevenlabs`, `google`, `minimax`, atau `microsoft`; memerlukan `allowProvider: true`)
- `voice` (voice OpenAI), `voiceName` / `voice_name` / `google_voice` (voice Google), atau `voiceId` (ElevenLabs / MiniMax)
- `model` (model TTS OpenAI, id model ElevenLabs, atau model MiniMax) atau `google_model` (model TTS Google)
- `stability`, `similarityBoost`, `style`, `speed`, `useSpeakerBoost`
- `vol` / `volume` (volume MiniMax, 0-10)
- `pitch` (pitch MiniMax, -12 hingga 12)
@ -332,7 +361,7 @@ Nonaktifkan semua override model:
}
```
Allowlist opsional (aktifkan peralihan provider sambil menjaga knob lain tetap dapat dikonfigurasi):
Allowlist opsional (aktifkan peralihan penyedia sambil tetap menjaga knob lain dapat dikonfigurasi):
```json5
{
@ -350,8 +379,8 @@ Allowlist opsional (aktifkan peralihan provider sambil menjaga knob lain tetap d
## Preferensi per pengguna
Perintah slash menulis override lokal ke `prefsPath` (default:
`~/.openclaw/settings/tts.json`, timpa dengan `OPENCLAW_TTS_PREFS` atau
Slash command menulis override lokal ke `prefsPath` (default:
`~/.openclaw/settings/tts.json`, ganti dengan `OPENCLAW_TTS_PREFS` atau
`messages.tts.prefsPath`).
Field yang disimpan:
@ -361,23 +390,24 @@ Field yang disimpan:
- `maxLength` (ambang ringkasan; default 1500 karakter)
- `summarize` (default `true`)
Field ini menimpa `messages.tts.*` untuk host tersebut.
Ini menimpa `messages.tts.*` untuk host tersebut.
## Format output (tetap)
- **Feishu / Matrix / Telegram / WhatsApp**: pesan suara Opus (`opus_48000_64` dari ElevenLabs, `opus` dari OpenAI).
- 48kHz / 64kbps adalah kompromi yang baik untuk pesan suara.
- **Channel lain**: MP3 (`mp3_44100_128` dari ElevenLabs, `mp3` dari OpenAI).
- **Saluran lain**: MP3 (`mp3_44100_128` dari ElevenLabs, `mp3` dari OpenAI).
- 44.1kHz / 128kbps adalah keseimbangan default untuk kejernihan ucapan.
- **MiniMax**: MP3 (model `speech-2.8-hd`, sample rate 32kHz). Format catatan suara tidak didukung secara native; gunakan OpenAI atau ElevenLabs untuk pesan suara Opus yang terjamin.
- **Google Gemini**: Gemini API TTS mengembalikan PCM 24kHz mentah. OpenClaw membungkusnya sebagai WAV untuk lampiran audio dan mengembalikan PCM secara langsung untuk Talk/telephony. Format catatan suara Opus native tidak didukung oleh jalur ini.
- **Microsoft**: menggunakan `microsoft.outputFormat` (default `audio-24khz-48kbitrate-mono-mp3`).
- Transport bawaan menerima `outputFormat`, tetapi tidak semua format tersedia dari layanan.
- Transport bawaan menerima `outputFormat`, tetapi tidak semua format tersedia dari layanan tersebut.
- Nilai format output mengikuti format output Microsoft Speech (termasuk Ogg/WebM Opus).
- `sendVoice` Telegram menerima OGG/MP3/M4A; gunakan OpenAI/ElevenLabs jika Anda memerlukan
- Telegram `sendVoice` menerima OGG/MP3/M4A; gunakan OpenAI/ElevenLabs jika Anda memerlukan
pesan suara Opus yang terjamin.
- Jika format output Microsoft yang dikonfigurasi gagal, OpenClaw mencoba ulang dengan MP3.
- Jika format output Microsoft yang dikonfigurasi gagal, OpenClaw akan mencoba lagi dengan MP3.
Format output OpenAI/ElevenLabs bersifat tetap per channel (lihat di atas).
Format output OpenAI/ElevenLabs tetap per saluran (lihat di atas).
## Perilaku auto-TTS
@ -385,7 +415,7 @@ Saat diaktifkan, OpenClaw:
- melewati TTS jika balasan sudah berisi media atau directive `MEDIA:`.
- melewati balasan yang sangat pendek (< 10 karakter).
- merangkum balasan panjang saat diaktifkan menggunakan `agents.defaults.model.primary` (atau `summaryModel`).
- meringkas balasan panjang saat diaktifkan menggunakan `agents.defaults.model.primary` (atau `summaryModel`).
- melampirkan audio yang dihasilkan ke balasan.
Jika balasan melebihi `maxLength` dan ringkasan nonaktif (atau tidak ada API key untuk
@ -397,19 +427,19 @@ dilewati dan balasan teks normal dikirim.
```
Balasan -> TTS diaktifkan?
tidak -> kirim teks
ya -> ada media / MEDIA: / pendek?
ya -> kirim teks
tidak -> panjang > batas?
tidak -> TTS -> lampirkan audio
ya -> ringkasan diaktifkan?
tidak -> kirim teks
ya -> ringkas (summaryModel atau agents.defaults.model.primary)
ya -> ada media / MEDIA: / pendek?
ya -> kirim teks
tidak -> panjang > batas?
tidak -> TTS -> lampirkan audio
ya -> ringkasan diaktifkan?
tidak -> kirim teks
ya -> ringkas (summaryModel atau agents.defaults.model.primary)
-> TTS -> lampirkan audio
```
## Penggunaan perintah slash
## Penggunaan slash command
Ada satu perintah: `/tts`.
Hanya ada satu perintah: `/tts`.
Lihat [Slash commands](/id/tools/slash-commands) untuk detail pengaktifannya.
Catatan Discord: `/tts` adalah perintah bawaan Discord, jadi OpenClaw mendaftarkan
@ -427,24 +457,24 @@ Catatan Discord: `/tts` adalah perintah bawaan Discord, jadi OpenClaw mendaftark
Catatan:
- Perintah memerlukan pengirim yang berwenang (aturan allowlist/owner tetap berlaku).
- Perintah memerlukan pengirim yang diotorisasi (aturan allowlist/owner tetap berlaku).
- `commands.text` atau pendaftaran perintah native harus diaktifkan.
- Config `messages.tts.auto` menerima `off|always|inbound|tagged`.
- `/tts on` menulis preferensi TTS lokal ke `always`; `/tts off` menulisnya ke `off`.
- Gunakan config jika Anda menginginkan default `inbound` atau `tagged`.
- `limit` dan `summary` disimpan di prefs lokal, bukan config utama.
- Konfigurasi `messages.tts.auto` menerima `off|always|inbound|tagged`.
- `/tts on` menulis preferensi TTS lokal menjadi `always`; `/tts off` menulisnya menjadi `off`.
- Gunakan konfigurasi jika Anda menginginkan default `inbound` atau `tagged`.
- `limit` dan `summary` disimpan di prefs lokal, bukan konfigurasi utama.
- `/tts audio` menghasilkan balasan audio sekali pakai (tidak mengaktifkan TTS).
- `/tts status` menyertakan visibilitas fallback untuk percobaan terbaru:
- `/tts status` mencakup visibilitas fallback untuk percobaan terbaru:
- fallback berhasil: `Fallback: <primary> -> <used>` plus `Attempts: ...`
- kegagalan: `Error: ...` plus `Attempts: ...`
- diagnostik rinci: `Attempt details: provider:outcome(reasonCode) latency`
- Kegagalan API OpenAI dan ElevenLabs kini menyertakan detail galat provider yang telah di-parse dan request id (saat dikembalikan oleh provider), yang ditampilkan dalam galat/log TTS.
- gagal: `Error: ...` plus `Attempts: ...`
- diagnostik terperinci: `Attempt details: provider:outcome(reasonCode) latency`
- Kegagalan API OpenAI dan ElevenLabs sekarang menyertakan detail error penyedia yang sudah diurai dan request id (saat dikembalikan oleh penyedia), yang ditampilkan dalam error/log TTS.
## Alat agen
## Tool agen
Alat `tts` mengubah teks menjadi ucapan dan mengembalikan lampiran audio untuk
pengiriman balasan. Saat channel adalah Feishu, Matrix, Telegram, atau WhatsApp,
audio dikirim sebagai pesan suara, bukan sebagai lampiran berkas.
Tool `tts` mengonversi teks menjadi ucapan dan mengembalikan lampiran audio untuk
pengiriman balasan. Saat salurannya adalah Feishu, Matrix, Telegram, atau WhatsApp,
audio dikirim sebagai pesan suara, bukan lampiran file.
## Gateway RPC