> ## Documentation Index
> Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Konfigurasi — agen

Konfigurasi kunci berskala agen di bawah `agents.*`, `multiAgent.*`, `session.*`,
`messages.*`, dan `talk.*`. Untuk channel, alat, runtime Gateway, dan kunci
tingkat atas lainnya, lihat [Referensi konfigurasi](/id/gateway/configuration-reference).

## Bawaan agen

### `agents.defaults.workspace`

Bawaan: `OPENCLAW_WORKSPACE_DIR` saat diatur, jika tidak `~/.openclaw/workspace`.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { workspace: "~/.openclaw/workspace" } },
}
```

Nilai `agents.defaults.workspace` eksplisit lebih diprioritaskan daripada
`OPENCLAW_WORKSPACE_DIR`. Gunakan variabel lingkungan untuk mengarahkan agen bawaan
ke workspace yang di-mount saat Anda tidak ingin menulis path tersebut ke config.

### `agents.defaults.repoRoot`

Root repositori opsional yang ditampilkan di baris Runtime pada prompt sistem. Jika tidak diatur, OpenClaw mendeteksi otomatis dengan menelusuri ke atas dari workspace.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { repoRoot: "~/Projects/openclaw" } },
}
```

### `agents.defaults.skills`

Allowlist skill bawaan opsional untuk agen yang tidak mengatur
`agents.list[].skills`.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: { skills: ["github", "weather"] },
    list: [
      { id: "writer" }, // inherits github, weather
      { id: "docs", skills: ["docs-search"] }, // replaces defaults
      { id: "locked-down", skills: [] }, // no skills
    ],
  },
}
```

* Hilangkan `agents.defaults.skills` untuk skill tanpa batasan secara bawaan.
* Hilangkan `agents.list[].skills` untuk mewarisi bawaan.
* Atur `agents.list[].skills: []` untuk tanpa skill.
* Daftar `agents.list[].skills` yang tidak kosong adalah set final untuk agen tersebut; daftar itu
  tidak digabung dengan bawaan.

### `agents.defaults.skipBootstrap`

Menonaktifkan pembuatan otomatis file bootstrap workspace (`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`).

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { skipBootstrap: true } },
}
```

### `agents.defaults.skipOptionalBootstrapFiles`

Melewati pembuatan file workspace opsional tertentu sambil tetap menulis file bootstrap wajib. Nilai valid: `SOUL.md`, `USER.md`, `HEARTBEAT.md`, dan `IDENTITY.md`.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      skipOptionalBootstrapFiles: ["SOUL.md", "USER.md"],
    },
  },
}
```

### `agents.defaults.contextInjection`

Mengontrol kapan file bootstrap workspace disuntikkan ke prompt sistem. Bawaan: `"always"`.

* `"continuation-skip"`: giliran lanjutan yang aman (setelah respons asisten selesai) melewati penyuntikan ulang bootstrap workspace, sehingga mengurangi ukuran prompt. Jalankan Heartbeat dan percobaan ulang pasca-Compaction tetap membangun ulang konteks.
* `"never"`: nonaktifkan bootstrap workspace dan penyuntikan file konteks pada setiap giliran. Gunakan ini hanya untuk agen yang sepenuhnya memiliki lifecycle prompt sendiri (mesin konteks kustom, runtime native yang membangun konteks sendiri, atau workflow khusus tanpa bootstrap). Giliran Heartbeat dan pemulihan Compaction juga melewati penyuntikan.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { contextInjection: "continuation-skip" } },
}
```

Override per agen: `agents.list[].contextInjection`. Nilai yang dihilangkan mewarisi
`agents.defaults.contextInjection`.

### `agents.defaults.bootstrapMaxChars`

Jumlah karakter maksimum per file bootstrap workspace sebelum pemotongan. Bawaan: `20000`.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { bootstrapMaxChars: 20000 } },
}
```

Override per agen: `agents.list[].bootstrapMaxChars`. Nilai yang dihilangkan mewarisi
`agents.defaults.bootstrapMaxChars`.

### `agents.defaults.bootstrapTotalMaxChars`

Jumlah karakter total maksimum yang disuntikkan di seluruh file bootstrap workspace. Bawaan: `60000`.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { bootstrapTotalMaxChars: 60000 } },
}
```

Override per agen: `agents.list[].bootstrapTotalMaxChars`. Nilai yang dihilangkan
mewarisi `agents.defaults.bootstrapTotalMaxChars`.

### Override profil bootstrap per agen

Gunakan override profil bootstrap per agen saat satu agen memerlukan perilaku
penyuntikan prompt yang berbeda dari bawaan bersama. Field yang dihilangkan mewarisi dari
`agents.defaults`.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      contextInjection: "continuation-skip",
      bootstrapMaxChars: 20000,
      bootstrapTotalMaxChars: 60000,
    },
    list: [
      {
        id: "strict-worker",
        contextInjection: "always",
        bootstrapMaxChars: 50000,
        bootstrapTotalMaxChars: 300000,
      },
    ],
  },
}
```

### `agents.defaults.bootstrapPromptTruncationWarning`

Mengontrol pemberitahuan prompt sistem yang terlihat oleh agen saat konteks bootstrap dipotong.
Bawaan: `"always"`.

* `"off"`: jangan pernah menyuntikkan teks pemberitahuan pemotongan ke prompt sistem.
* `"once"`: suntikkan pemberitahuan ringkas satu kali per tanda tangan pemotongan unik.
* `"always"`: suntikkan pemberitahuan ringkas pada setiap run saat ada pemotongan (direkomendasikan).

Hitungan mentah/disuntikkan yang rinci dan field penyetelan config tetap berada di diagnostik seperti
laporan konteks/status dan log; konteks pengguna/runtime WebChat rutin hanya
mendapat pemberitahuan pemulihan ringkas.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { bootstrapPromptTruncationWarning: "always" } }, // off | once | always
}
```

### Peta kepemilikan anggaran konteks

OpenClaw memiliki beberapa anggaran prompt/konteks bervolume tinggi, dan anggaran tersebut
sengaja dipisahkan berdasarkan subsistem, bukan semuanya mengalir melalui satu
knob generik.

* `agents.defaults.bootstrapMaxChars` /
  `agents.defaults.bootstrapTotalMaxChars`:
  penyuntikan bootstrap workspace normal.
* `agents.defaults.startupContext.*`:
  prelude satu kali untuk run model reset/startup, termasuk file
  `memory/*.md` harian terbaru. Perintah chat polos `/new` dan `/reset`
  diakui tanpa memanggil model.
* `skills.limits.*`:
  daftar skills ringkas yang disuntikkan ke prompt sistem.
* `agents.defaults.contextLimits.*`:
  kutipan runtime berbatas dan blok milik runtime yang disuntikkan.
* `memory.qmd.limits.*`:
  ukuran snippet pencarian memori terindeks dan penyuntikan.

Gunakan override per agen yang sesuai hanya saat satu agen memerlukan
anggaran berbeda:

* `agents.list[].skillsLimits.maxSkillsPromptChars`
* `agents.list[].contextInjection`
* `agents.list[].bootstrapMaxChars`
* `agents.list[].bootstrapTotalMaxChars`
* `agents.list[].contextLimits.*`

#### `agents.defaults.startupContext`

Mengontrol prelude startup giliran pertama yang disuntikkan pada run model reset/startup.
Perintah chat polos `/new` dan `/reset` mengakui reset tanpa memanggil
model, sehingga tidak memuat prelude ini.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      startupContext: {
        enabled: true,
        applyOn: ["new", "reset"],
        dailyMemoryDays: 2,
        maxFileBytes: 16384,
        maxFileChars: 1200,
        maxTotalChars: 2800,
      },
    },
  },
}
```

#### `agents.defaults.contextLimits`

Bawaan bersama untuk surface konteks runtime berbatas.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      contextLimits: {
        memoryGetMaxChars: 12000,
        memoryGetDefaultLines: 120,
        postCompactionMaxChars: 1800,
      },
    },
  },
}
```

* `memoryGetMaxChars`: batas kutipan `memory_get` bawaan sebelum metadata
  pemotongan dan pemberitahuan lanjutan ditambahkan.
* `memoryGetDefaultLines`: jendela baris `memory_get` bawaan saat `lines` dihilangkan.
* `toolResultMaxChars`: batas atas hasil alat live tingkat lanjut yang digunakan untuk hasil
  persisten dan pemulihan overflow. Biarkan tidak diatur untuk batas otomatis konteks model:
  `16000` karakter di bawah 100K token, `32000` karakter pada 100K+ token, dan `64000`
  karakter pada 200K+ token. Nilai eksplisit hingga `1000000` diterima untuk
  model berkonteks panjang, tetapi batas efektif masih dibatasi sekitar 30% dari
  jendela konteks model. `openclaw doctor --deep` mencetak batas efektif,
  dan doctor hanya memperingatkan saat override eksplisit sudah usang atau tidak berpengaruh.
* `postCompactionMaxChars`: batas kutipan AGENTS.md yang digunakan selama penyuntikan
  refresh pasca-Compaction.

#### `agents.list[].contextLimits`

Override per agen untuk knob `contextLimits` bersama. Field yang dihilangkan mewarisi
dari `agents.defaults.contextLimits`.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      contextLimits: {
        memoryGetMaxChars: 12000,
      },
    },
    list: [
      {
        id: "tiny-local",
        contextLimits: {
          memoryGetMaxChars: 6000,
          toolResultMaxChars: 8000, // advanced ceiling for this agent
        },
      },
    ],
  },
}
```

#### `skills.limits.maxSkillsPromptChars`

Batas global untuk daftar skills ringkas yang disuntikkan ke prompt sistem. Ini
tidak memengaruhi pembacaan file `SKILL.md` sesuai kebutuhan.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  skills: {
    limits: {
      maxSkillsPromptChars: 18000,
    },
  },
}
```

#### `agents.list[].skillsLimits.maxSkillsPromptChars`

Override per agen untuk anggaran prompt skills.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    list: [
      {
        id: "tiny-local",
        skillsLimits: {
          maxSkillsPromptChars: 6000,
        },
      },
    ],
  },
}
```

### `agents.defaults.imageMaxDimensionPx`

Ukuran piksel maksimum untuk sisi gambar terpanjang dalam blok gambar transkrip/alat sebelum panggilan penyedia.
Bawaan: `1200`.

Nilai yang lebih rendah biasanya mengurangi penggunaan token visi dan ukuran payload permintaan untuk run yang banyak screenshot.
Nilai yang lebih tinggi mempertahankan lebih banyak detail visual.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { imageMaxDimensionPx: 1200 } },
}
```

### `agents.defaults.imageQuality`

Preferensi kompresi/detail alat gambar untuk gambar yang dimuat dari path file, URL, dan referensi media.
Bawaan: `auto`.

OpenClaw menyesuaikan tangga resize dengan model gambar yang dipilih. Misalnya, Claude Opus 4.8, OpenAI GPT-5.5, Qwen VL, dan model visi Llama 4 yang di-host dapat menggunakan gambar yang lebih besar daripada jalur visi detail tinggi lama/bawaan, sementara giliran multi-gambar dikompresi lebih agresif dalam mode `auto` untuk mengontrol biaya token dan latensi.

Nilai:

* `auto`: sesuaikan dengan batas model dan jumlah gambar.
* `efficient`: utamakan gambar yang lebih kecil untuk penggunaan token dan byte yang lebih rendah.
* `balanced`: gunakan tangga jalan tengah standar.
* `high`: pertahankan lebih banyak detail untuk screenshot, diagram, dan gambar dokumen.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { imageQuality: "auto" } },
}
```

### `agents.defaults.userTimezone`

Zona waktu untuk konteks prompt sistem (bukan stempel waktu pesan). Fallback ke zona waktu host.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { userTimezone: "America/Chicago" } },
}
```

### `agents.defaults.timeFormat`

Format waktu dalam prompt sistem. Bawaan: `auto` (preferensi OS).

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: { defaults: { timeFormat: "auto" } }, // auto | 12 | 24
}
```

### `agents.defaults.model`

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      models: {
        "anthropic/claude-opus-4-6": { alias: "opus" },
        "minimax/MiniMax-M2.7": { alias: "minimax" },
      },
      model: {
        primary: "anthropic/claude-opus-4-6",
        fallbacks: ["minimax/MiniMax-M2.7"],
      },
      imageModel: {
        primary: "openrouter/qwen/qwen-2.5-vl-72b-instruct:free",
        fallbacks: ["openrouter/google/gemini-2.0-flash-vision:free"],
      },
      imageGenerationModel: {
        primary: "openai/gpt-image-2",
        fallbacks: ["google/gemini-3.1-flash-image-preview"],
      },
      videoGenerationModel: {
        primary: "qwen/wan2.6-t2v",
        fallbacks: ["qwen/wan2.6-i2v"],
      },
      pdfModel: {
        primary: "anthropic/claude-opus-4-6",
        fallbacks: ["openai/gpt-5.4-mini"],
      },
      params: { cacheRetention: "long" }, // global default provider params
      pdfMaxBytesMb: 10,
      pdfMaxPages: 20,
      thinkingDefault: "low",
      verboseDefault: "off",
      toolProgressDetail: "explain",
      reasoningDefault: "off",
      elevatedDefault: "on",
      timeoutSeconds: 600,
      mediaMaxMb: 5,
      contextTokens: 200000,
      maxConcurrent: 3,
    },
  },
}
```

* `model`: menerima string (`"provider/model"`) atau objek (`{ primary, fallbacks }`).
  * Bentuk string hanya menetapkan model utama.
  * Bentuk objek menetapkan model utama plus model failover berurutan.
* `imageModel`: menerima string (`"provider/model"`) atau objek (`{ primary, fallbacks }`).
  * Digunakan oleh jalur alat `image` sebagai konfigurasi model vision-nya.
  * Juga digunakan sebagai perutean fallback ketika model yang dipilih/default tidak dapat menerima input gambar.
  * Utamakan ref `provider/model` eksplisit. ID polos diterima untuk kompatibilitas; jika ID polos cocok secara unik dengan entri berkemampuan gambar yang dikonfigurasi di `models.providers.*.models`, OpenClaw melengkapinya ke provider tersebut. Kecocokan terkonfigurasi yang ambigu memerlukan prefiks provider eksplisit.
* `imageGenerationModel`: menerima string (`"provider/model"`) atau objek (`{ primary, fallbacks }`).
  * Digunakan oleh kapabilitas pembuatan gambar bersama dan permukaan alat/plugin masa depan apa pun yang menghasilkan gambar.
  * Nilai umum: `google/gemini-3.1-flash-image-preview` untuk pembuatan gambar Gemini native, `fal/fal-ai/flux/dev` untuk fal, `openai/gpt-image-2` untuk OpenAI Images, atau `openai/gpt-image-1.5` untuk output PNG/WebP OpenAI berlatar transparan.
  * Jika Anda memilih provider/model secara langsung, konfigurasikan juga autentikasi provider yang cocok (misalnya `GEMINI_API_KEY` atau `GOOGLE_API_KEY` untuk `google/*`, `OPENAI_API_KEY` atau OpenAI Codex OAuth untuk `openai/gpt-image-2` / `openai/gpt-image-1.5`, `FAL_KEY` untuk `fal/*`).
  * Jika dihilangkan, `image_generate` masih dapat menyimpulkan default provider yang didukung autentikasi. Ini mencoba provider default saat ini terlebih dahulu, lalu provider pembuatan gambar terdaftar yang tersisa dalam urutan ID provider.
* `musicGenerationModel`: menerima string (`"provider/model"`) atau objek (`{ primary, fallbacks }`).
  * Digunakan oleh kapabilitas pembuatan musik bersama dan alat bawaan `music_generate`.
  * Nilai umum: `google/lyria-3-clip-preview`, `google/lyria-3-pro-preview`, atau `minimax/music-2.6`.
  * Jika dihilangkan, `music_generate` masih dapat menyimpulkan default provider yang didukung autentikasi. Ini mencoba provider default saat ini terlebih dahulu, lalu provider pembuatan musik terdaftar yang tersisa dalam urutan ID provider.
  * Jika Anda memilih provider/model secara langsung, konfigurasikan juga autentikasi/kunci API provider yang cocok.
* `videoGenerationModel`: menerima string (`"provider/model"`) atau objek (`{ primary, fallbacks }`).
  * Digunakan oleh kapabilitas pembuatan video bersama dan alat bawaan `video_generate`.
  * Nilai umum: `qwen/wan2.6-t2v`, `qwen/wan2.6-i2v`, `qwen/wan2.6-r2v`, `qwen/wan2.6-r2v-flash`, atau `qwen/wan2.7-r2v`.
  * Jika dihilangkan, `video_generate` masih dapat menyimpulkan default provider yang didukung autentikasi. Ini mencoba provider default saat ini terlebih dahulu, lalu provider pembuatan video terdaftar yang tersisa dalam urutan ID provider.
  * Jika Anda memilih provider/model secara langsung, konfigurasikan juga autentikasi/kunci API provider yang cocok.
  * Plugin pembuatan video Qwen resmi mendukung hingga 1 video output, 1 gambar input, 4 video input, durasi 10 detik, serta opsi tingkat provider `size`, `aspectRatio`, `resolution`, `audio`, dan `watermark`.
* `pdfModel`: menerima string (`"provider/model"`) atau objek (`{ primary, fallbacks }`).
  * Digunakan oleh alat `pdf` untuk perutean model.
  * Jika dihilangkan, alat PDF melakukan fallback ke `imageModel`, lalu ke model sesi/default yang telah diselesaikan.
* `pdfMaxBytesMb`: batas ukuran PDF default untuk alat `pdf` ketika `maxBytesMb` tidak diteruskan saat pemanggilan.
* `pdfMaxPages`: halaman maksimum default yang dipertimbangkan oleh mode fallback ekstraksi di alat `pdf`.
* `verboseDefault`: tingkat verbose default untuk agen. Nilai: `"off"`, `"on"`, `"full"`. Default: `"off"`.
* `toolProgressDetail`: mode detail untuk ringkasan alat `/verbose` dan baris alat draf progres. Nilai: `"explain"` (default, label manusia ringkas) atau `"raw"` (tambahkan perintah/detail mentah bila tersedia). `agents.list[].toolProgressDetail` per agen menimpa default ini.
* `reasoningDefault`: visibilitas reasoning default untuk agen. Nilai: `"off"`, `"on"`, `"stream"`. `agents.list[].reasoningDefault` per agen menimpa default ini. Default reasoning yang dikonfigurasi hanya diterapkan untuk pemilik, pengirim terotorisasi, atau konteks Gateway admin operator ketika tidak ada override reasoning per pesan atau sesi yang ditetapkan.
* `elevatedDefault`: tingkat output elevated default untuk agen. Nilai: `"off"`, `"on"`, `"ask"`, `"full"`. Default: `"on"`.
* `model.primary`: format `provider/model` (misalnya `openai/gpt-5.5` untuk akses kunci API OpenAI atau Codex OAuth). Jika Anda menghilangkan provider, OpenClaw mencoba alias terlebih dahulu, lalu kecocokan provider terkonfigurasi yang unik untuk ID model persis tersebut, dan baru setelah itu fallback ke provider default terkonfigurasi (perilaku kompatibilitas yang tidak digunakan lagi, jadi utamakan `provider/model` eksplisit). Jika provider tersebut tidak lagi mengekspos model default terkonfigurasi, OpenClaw fallback ke provider/model terkonfigurasi pertama alih-alih memunculkan default provider lama yang sudah dihapus.
* `models`: katalog model terkonfigurasi dan allowlist untuk `/model`. Setiap entri dapat menyertakan `alias` (pintasan) dan `params` (khusus provider, misalnya `temperature`, `maxTokens`, `cacheRetention`, `context1m`, `responsesServerCompaction`, `responsesCompactThreshold`, perutean `provider` OpenRouter, `chat_template_kwargs`, `extra_body`/`extraBody`).
  * Gunakan entri `provider/*` seperti `"openai/*": {}` atau `"vllm/*": {}` untuk menampilkan semua model yang ditemukan untuk provider terpilih tanpa mencantumkan setiap ID model secara manual.
  * Tambahkan `agentRuntime` ke entri `provider/*` ketika setiap model yang ditemukan secara dinamis untuk provider tersebut harus menggunakan runtime yang sama. Kebijakan runtime `provider/model` persis tetap mengalahkan wildcard.
  * Edit aman: gunakan `openclaw config set agents.defaults.models '<json>' --strict-json --merge` untuk menambahkan entri. `config set` menolak penggantian yang akan menghapus entri allowlist yang ada kecuali Anda meneruskan `--replace`.
  * Alur configure/onboarding bercakupan provider menggabungkan model provider terpilih ke dalam map ini dan mempertahankan provider tidak terkait yang sudah dikonfigurasi.
  * Untuk model OpenAI Responses langsung, Compaction sisi server diaktifkan otomatis. Gunakan `params.responsesServerCompaction: false` untuk berhenti menyuntikkan `context_management`, atau `params.responsesCompactThreshold` untuk menimpa ambang batas. Lihat [Compaction sisi server OpenAI](/id/providers/openai#server-side-compaction-responses-api).
* `params`: parameter provider default global yang diterapkan ke semua model. Diatur di `agents.defaults.params` (misalnya `{ cacheRetention: "long" }`).
* Prioritas penggabungan `params` (konfigurasi): `agents.defaults.params` (basis global) ditimpa oleh `agents.defaults.models["provider/model"].params` (per model), lalu `agents.list[].params` (ID agen yang cocok) menimpa berdasarkan kunci. Lihat [Prompt Caching](/id/reference/prompt-caching) untuk detail.
* `models.providers.openrouter.params.provider`: kebijakan perutean provider default untuk seluruh OpenRouter. OpenClaw meneruskan ini ke objek `provider` permintaan OpenRouter; `agents.defaults.models["openrouter/<model>"].params.provider` per model dan parameter agen menimpa berdasarkan kunci. Lihat [perutean provider OpenRouter](/id/providers/openrouter#advanced-configuration).
* `params.extra_body`/`params.extraBody`: JSON pass-through lanjutan yang digabungkan ke body permintaan `api: "openai-completions"` untuk proxy kompatibel OpenAI. Jika bertabrakan dengan kunci permintaan yang dihasilkan, body ekstra menang; rute completions non-native tetap menghapus `store` khusus OpenAI setelahnya.
* `params.chat_template_kwargs`: argumen chat-template kompatibel vLLM/OpenAI yang digabungkan ke body permintaan `api: "openai-completions"` tingkat atas. Untuk `vllm/nemotron-3-*` dengan thinking mati, plugin vLLM bawaan otomatis mengirim `enable_thinking: false` dan `force_nonempty_content: true`; `chat_template_kwargs` eksplisit menimpa default yang dihasilkan, dan `extra_body.chat_template_kwargs` tetap memiliki prioritas akhir. Model thinking Qwen dan Nemotron vLLM terkonfigurasi mengekspos pilihan `/think` biner (`off`, `on`) alih-alih tangga effort bertingkat.
* `compat.thinkingFormat`: gaya payload thinking kompatibel OpenAI. Gunakan `"together"` untuk `reasoning.enabled` gaya Together, `"qwen"` untuk `enable_thinking` tingkat atas gaya Qwen, atau `"qwen-chat-template"` untuk `chat_template_kwargs.enable_thinking` pada backend keluarga Qwen yang mendukung kwargs chat-template tingkat permintaan, seperti vLLM. OpenClaw memetakan thinking yang dinonaktifkan ke `false` dan thinking yang diaktifkan ke `true`, dan model Qwen vLLM terkonfigurasi mengekspos pilihan `/think` biner untuk format ini.
* `compat.supportedReasoningEfforts`: daftar effort reasoning kompatibel OpenAI per model. Sertakan `"xhigh"` untuk endpoint kustom yang benar-benar menerimanya; OpenClaw kemudian mengekspos `/think xhigh` di menu perintah, baris sesi Gateway, validasi patch sesi, validasi CLI agen, dan validasi `llm-task` untuk provider/model terkonfigurasi tersebut. Gunakan `compat.reasoningEffortMap` ketika backend menginginkan nilai khusus provider untuk level kanonis.
* `params.preserveThinking`: opt-in khusus Z.AI untuk thinking yang dipertahankan. Ketika diaktifkan dan thinking menyala, OpenClaw mengirim `thinking.clear_thinking: false` dan memutar ulang `reasoning_content` sebelumnya; lihat [thinking Z.AI dan thinking yang dipertahankan](/id/providers/zai#thinking-and-preserved-thinking).
* `localService`: manajer proses tingkat provider opsional untuk server model lokal/self-hosted. Ketika model yang dipilih milik provider tersebut, OpenClaw memeriksa `healthUrl` (atau `baseUrl + "/models"`), menjalankan `command` dengan `args` jika endpoint sedang turun, menunggu hingga `readyTimeoutMs`, lalu mengirim permintaan model. `command` harus berupa path absolut. `idleStopMs: 0` membuat proses tetap hidup hingga OpenClaw keluar; nilai positif menghentikan proses yang dijalankan OpenClaw setelah idle selama jumlah milidetik tersebut. Lihat [layanan model lokal](/id/gateway/local-model-services).
* Kebijakan runtime berada pada provider atau model, bukan pada `agents.defaults`. Gunakan `models.providers.<provider>.agentRuntime` untuk aturan seluruh provider atau `agents.defaults.models["provider/model"].agentRuntime` / `agents.list[].models["provider/model"].agentRuntime` untuk aturan khusus model. Model agen OpenAI pada provider OpenAI resmi memilih Codex secara default.
* Penulis konfigurasi yang memutasi field ini (misalnya `/models set`, `/models set-image`, dan perintah tambah/hapus fallback) menyimpan bentuk objek kanonis dan mempertahankan daftar fallback yang ada bila memungkinkan.
* `maxConcurrent`: jumlah maksimum run agen paralel lintas sesi (setiap sesi tetap diserialisasi). Default: 4.

### Kebijakan runtime

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  models: {
    providers: {
      openai: {
        agentRuntime: { id: "codex" },
      },
    },
  },
  agents: {
    defaults: {
      model: "openai/gpt-5.5",
      models: {
        "anthropic/claude-opus-4-8": {
          agentRuntime: { id: "claude-cli" },
        },
        "vllm/*": {
          agentRuntime: { id: "openclaw" },
        },
      },
    },
  },
}
```

* `id`: `"auto"`, `"openclaw"`, id harness plugin terdaftar, atau alias backend CLI yang didukung. Plugin Codex bawaan mendaftarkan `codex`; plugin Anthropic bawaan menyediakan backend CLI `claude-cli`.
* `id: "auto"` memungkinkan harness plugin terdaftar mengklaim giliran yang didukung dan menggunakan OpenClaw saat tidak ada harness yang cocok. Runtime plugin eksplisit seperti `id: "codex"` memerlukan harness tersebut dan gagal tertutup jika tidak tersedia atau gagal.
* `id: "pi"` diterima hanya sebagai alias usang untuk `openclaw` guna mempertahankan config yang sudah dirilis dari v2026.5.22 dan sebelumnya. Config baru harus menggunakan `openclaw`.
* Prioritas runtime adalah kebijakan model persis terlebih dahulu (`agents.list[].models["provider/model"]`, `agents.defaults.models["provider/model"]`, atau `models.providers.<provider>.models[]`), lalu `agents.list[]` / `agents.defaults.models["provider/*"]`, lalu kebijakan seluruh provider di `models.providers.<provider>.agentRuntime`.
* Kunci runtime seluruh agen bersifat legacy. `agents.defaults.agentRuntime`, `agents.list[].agentRuntime`, pin runtime sesi, dan `OPENCLAW_AGENT_RUNTIME` diabaikan oleh pemilihan runtime. Jalankan `openclaw doctor --fix` untuk menghapus nilai usang.
* Model agen OpenAI menggunakan harness Codex secara default; provider/model `agentRuntime.id: "codex"` tetap valid saat Anda ingin membuatnya eksplisit.
* Untuk deployment Claude CLI, pilih `model: "anthropic/claude-opus-4-8"` ditambah `agentRuntime.id: "claude-cli"` yang dicakup model. Ref model legacy `claude-cli/claude-opus-4-7` masih berfungsi untuk kompatibilitas, tetapi config baru harus menjaga pemilihan provider/model tetap kanonis dan menempatkan backend eksekusi dalam kebijakan runtime provider/model.
* Ini hanya mengontrol eksekusi giliran agen teks. Pembuatan media, vision, PDF, musik, video, dan TTS tetap menggunakan pengaturan provider/model masing-masing.

**Singkatan alias bawaan** (hanya berlaku saat model berada di `agents.defaults.models`):

| Alias               | Model                           |
| ------------------- | ------------------------------- |
| `opus`              | `anthropic/claude-opus-4-8`     |
| `sonnet`            | `anthropic/claude-sonnet-4-6`   |
| `gpt`               | `openai/gpt-5.4`                |
| `gpt-mini`          | `openai/gpt-5.4-mini`           |
| `gpt-nano`          | `openai/gpt-5.4-nano`           |
| `gemini`            | `google/gemini-3.1-pro-preview` |
| `gemini-flash`      | `google/gemini-3-flash-preview` |
| `gemini-flash-lite` | `google/gemini-3.1-flash-lite`  |

Alias yang Anda config selalu mengalahkan default.

Model Z.AI GLM-4.x otomatis mengaktifkan mode berpikir kecuali Anda menetapkan `--thinking off` atau mendefinisikan sendiri `agents.defaults.models["zai/<model>"].params.thinking`.
Model Z.AI mengaktifkan `tool_stream` secara default untuk streaming tool call. Tetapkan `agents.defaults.models["zai/<model>"].params.tool_stream` ke `false` untuk menonaktifkannya.
Anthropic Claude Opus 4.8 menjaga berpikir tetap nonaktif secara default di OpenClaw; saat berpikir adaptif diaktifkan secara eksplisit, default effort milik provider Anthropic adalah `high`. Model Claude 4.6 default ke `adaptive` saat tidak ada level berpikir eksplisit yang ditetapkan.

### `agents.defaults.cliBackends`

Backend CLI opsional untuk run fallback khusus teks (tanpa tool call). Berguna sebagai cadangan saat provider API gagal.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      cliBackends: {
        "claude-cli": {
          command: "/opt/homebrew/bin/claude",
        },
        "my-cli": {
          command: "my-cli",
          args: ["--json"],
          output: "json",
          modelArg: "--model",
          sessionArg: "--session",
          sessionMode: "existing",
          systemPromptArg: "--system",
          // Or use systemPromptFileArg when the CLI accepts a prompt file flag.
          systemPromptWhen: "first",
          imageArg: "--image",
          imageMode: "repeat",
        },
      },
    },
  },
}
```

* Backend CLI mengutamakan teks; tool selalu dinonaktifkan.
* Sesi didukung saat `sessionArg` ditetapkan.
* Pass-through gambar didukung saat `imageArg` menerima path file.
* `reseedFromRawTranscriptWhenUncompacted: true` memungkinkan backend memulihkan sesi yang aman
  tetapi sudah diinvalidasi dari ekor transkrip mentah OpenClaw yang dibatasi sebelum
  ringkasan Compaction pertama ada. Perubahan profil auth atau epoch kredensial
  tetap tidak pernah melakukan raw-reseed.

### `agents.defaults.promptOverlays`

Overlay prompt yang independen dari provider diterapkan berdasarkan keluarga model pada permukaan prompt yang dirakit OpenClaw. Id model keluarga GPT-5 menerima kontrak perilaku bersama di seluruh rute OpenClaw/provider; `personality` hanya mengontrol lapisan gaya interaksi yang ramah. Rute app-server Codex native mempertahankan instruksi dasar/model milik Codex alih-alih overlay GPT-5 OpenClaw ini, dan OpenClaw menonaktifkan personality bawaan Codex untuk thread native.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      promptOverlays: {
        gpt5: {
          personality: "friendly", // friendly | on | off
        },
      },
    },
  },
}
```

* `"friendly"` (default) dan `"on"` mengaktifkan lapisan gaya interaksi yang ramah.
* `"off"` hanya menonaktifkan lapisan ramah; kontrak perilaku GPT-5 bertag tetap aktif.
* Legacy `plugins.entries.openai.config.personality` masih dibaca saat pengaturan bersama ini belum ditetapkan.

### `agents.defaults.heartbeat`

Run Heartbeat berkala.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m", // 0m disables
        model: "openai/gpt-5.4-mini",
        includeReasoning: false,
        includeSystemPromptSection: true, // default: true; false omits the Heartbeat section from the system prompt
        lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files
        isolatedSession: false, // default: false; true runs each heartbeat in a fresh session (no conversation history)
        skipWhenBusy: false, // default: false; true also waits for this agent's subagent/nested lanes
        session: "main",
        to: "+15555550123",
        directPolicy: "allow", // allow (default) | block
        target: "none", // default: none | options: last | whatsapp | telegram | discord | ...
        prompt: "Read HEARTBEAT.md if it exists...",
        ackMaxChars: 300,
        suppressToolErrorWarnings: false,
        timeoutSeconds: 45,
      },
    },
  },
}
```

* `every`: string durasi (ms/s/m/h). Default: `30m` (auth kunci API) atau `1h` (auth OAuth). Tetapkan ke `0m` untuk menonaktifkan.
* `includeSystemPromptSection`: saat false, menghilangkan bagian Heartbeat dari prompt sistem dan melewati injeksi `HEARTBEAT.md` ke dalam konteks bootstrap. Default: `true`.
* `suppressToolErrorWarnings`: saat true, menekan payload peringatan error tool selama run Heartbeat.
* `timeoutSeconds`: waktu maksimum dalam detik yang diizinkan untuk giliran agen Heartbeat sebelum dibatalkan. Biarkan tidak ditetapkan untuk menggunakan `agents.defaults.timeoutSeconds` saat ditetapkan, jika tidak cadence Heartbeat dibatasi pada 600 detik.
* `directPolicy`: kebijakan pengiriman langsung/DM. `allow` (default) mengizinkan pengiriman target langsung. `block` menekan pengiriman target langsung dan menghasilkan `reason=dm-blocked`.
* `lightContext`: saat true, run Heartbeat menggunakan konteks bootstrap ringan dan hanya mempertahankan `HEARTBEAT.md` dari file bootstrap workspace.
* `isolatedSession`: saat true, setiap Heartbeat berjalan dalam sesi baru tanpa riwayat percakapan sebelumnya. Pola isolasi yang sama seperti cron `sessionTarget: "isolated"`. Mengurangi biaya token per Heartbeat dari \~100K menjadi \~2-5K token.
* `skipWhenBusy`: saat true, run Heartbeat ditunda pada lane sibuk tambahan agen tersebut: subagen berkunci sesi miliknya sendiri atau pekerjaan command bertingkat. Lane Cron selalu menunda Heartbeat, bahkan tanpa flag ini.
* Per agen: tetapkan `agents.list[].heartbeat`. Saat agen mana pun mendefinisikan `heartbeat`, **hanya agen tersebut** yang menjalankan Heartbeat.
* Heartbeat menjalankan giliran agen penuh — interval yang lebih pendek membakar lebih banyak token.

### `agents.defaults.compaction`

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      compaction: {
        mode: "safeguard", // default | safeguard
        provider: "my-provider", // id of a registered compaction provider plugin (optional)
        timeoutSeconds: 180,
        reserveTokensFloor: 24000,
        keepRecentTokens: 50000,
        identifierPolicy: "strict", // strict | off | custom
        identifierInstructions: "Preserve deployment IDs, ticket IDs, and host:port pairs exactly.", // used when identifierPolicy=custom
        qualityGuard: { enabled: true, maxRetries: 1 },
        midTurnPrecheck: { enabled: false }, // optional tool-loop pressure check
        postCompactionSections: ["Session Startup", "Red Lines"], // opt in to AGENTS.md section reinjection
        model: "openrouter/anthropic/claude-sonnet-4-6", // optional compaction-only model override
        truncateAfterCompaction: true, // rotate to a smaller successor JSONL after compaction
        maxActiveTranscriptBytes: "20mb", // optional preflight local compaction trigger
        notifyUser: true, // send brief notices when compaction starts and completes (default: false)
        memoryFlush: {
          enabled: true,
          model: "ollama/qwen3:8b", // optional memory-flush-only model override
          softThresholdTokens: 6000,
          systemPrompt: "Session nearing compaction. Store durable memories now.",
          prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with the exact silent token NO_REPLY if nothing to store.",
        },
      },
    },
  },
}
```

* `mode`: `default` atau `safeguard` (peringkasan berpotongan untuk riwayat panjang). Lihat [Compaction](/id/concepts/compaction).
* `provider`: id dari plugin penyedia compaction yang terdaftar. Saat disetel, `summarize()` milik penyedia dipanggil alih-alih peringkasan LLM bawaan. Kembali ke bawaan jika gagal. Menyetel penyedia memaksa `mode: "safeguard"`. Lihat [Compaction](/id/concepts/compaction).
* `timeoutSeconds`: jumlah detik maksimum yang diizinkan untuk satu operasi compaction sebelum OpenClaw membatalkannya. Default: `180`.
* `keepRecentTokens`: anggaran titik potong agen untuk mempertahankan ekor transkrip terbaru secara verbatim. `/compact` manual menghormati ini saat disetel secara eksplisit; jika tidak, compaction manual adalah checkpoint keras.
* `identifierPolicy`: `strict` (default), `off`, atau `custom`. `strict` menambahkan panduan retensi pengenal buram bawaan di awal selama peringkasan compaction.
* `identifierInstructions`: teks pelestarian pengenal kustom opsional yang digunakan saat `identifierPolicy=custom`.
* `qualityGuard`: pemeriksaan coba-ulang-saat-output-cacat untuk ringkasan safeguard. Diaktifkan secara default dalam mode safeguard; setel `enabled: false` untuk melewati audit.
* `midTurnPrecheck`: pemeriksaan tekanan tool-loop opsional. Saat `enabled: true`, OpenClaw memeriksa tekanan konteks setelah hasil tool ditambahkan dan sebelum panggilan model berikutnya. Jika konteks tidak lagi muat, upaya saat ini dibatalkan sebelum mengirim prompt dan jalur pemulihan precheck yang ada digunakan ulang untuk memotong hasil tool atau melakukan compact lalu mencoba lagi. Berfungsi dengan mode compaction `default` dan `safeguard`. Default: dinonaktifkan.
* `postCompactionSections`: nama bagian H2/H3 AGENTS.md opsional untuk disuntikkan kembali setelah compaction. Penyuntikan ulang dinonaktifkan saat tidak disetel atau disetel ke `[]`. Menyetel `["Session Startup", "Red Lines"]` secara eksplisit mengaktifkan pasangan itu dan mempertahankan fallback lama `Every Session`/`Safety`. Aktifkan ini hanya saat konteks tambahan sepadan dengan risiko menggandakan panduan proyek yang sudah ditangkap dalam ringkasan compaction.
* `model`: `provider/model-id` opsional atau alias polos dari `agents.defaults.models` hanya untuk peringkasan compaction. Alias polos diselesaikan sebelum dispatch; ID model literal yang dikonfigurasi mempertahankan prioritas saat terjadi benturan. Gunakan ini saat sesi utama harus mempertahankan satu model tetapi ringkasan compaction harus berjalan pada model lain; saat tidak disetel, compaction menggunakan model utama sesi.
* `maxActiveTranscriptBytes`: ambang byte opsional (`number` atau string seperti `"20mb"`) yang memicu compaction lokal normal sebelum run saat JSONL aktif tumbuh melewati ambang. Memerlukan `truncateAfterCompaction` agar compaction yang berhasil dapat merotasi ke transkrip penerus yang lebih kecil. Dinonaktifkan saat tidak disetel atau `0`.
* `notifyUser`: saat `true`, mengirim pemberitahuan singkat kepada pengguna saat compaction dimulai dan saat selesai (misalnya, "Memadatkan konteks..." dan "Compaction selesai"). Dinonaktifkan secara default agar compaction tetap senyap.
* `memoryFlush`: giliran agentic senyap sebelum auto-compaction untuk menyimpan memori tahan lama. Setel `model` ke penyedia/model persis seperti `ollama/qwen3:8b` saat giliran housekeeping ini harus tetap pada model lokal; override tidak mewarisi rantai fallback sesi aktif. Dilewati saat workspace bersifat read-only.

### `agents.defaults.runRetries`

Batas iterasi retry loop run luar untuk runtime agen tertanam guna mencegah loop eksekusi tak terbatas selama pemulihan kegagalan. Perhatikan bahwa pengaturan ini saat ini hanya berlaku untuk runtime agen tertanam, bukan runtime ACP atau CLI.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      runRetries: {
        base: 24,
        perProfile: 8,
        min: 32,
        max: 160,
      },
    },
    list: [
      {
        id: "main",
        runRetries: { max: 50 }, // optional per-agent overrides
      },
    ],
  },
}
```

* `base`: jumlah dasar iterasi retry run untuk loop run luar. Default: `24`.
* `perProfile`: iterasi retry run tambahan yang diberikan per kandidat profil fallback. Default: `8`.
* `min`: batas absolut minimum untuk iterasi retry run. Default: `32`.
* `max`: batas absolut maksimum untuk iterasi retry run guna mencegah eksekusi tak terkendali. Default: `160`.

### `agents.defaults.contextPruning`

Memangkas **hasil tool lama** dari konteks dalam memori sebelum dikirim ke LLM. **Tidak** mengubah riwayat sesi di disk.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      contextPruning: {
        mode: "cache-ttl", // off | cache-ttl
        ttl: "1h", // duration (ms/s/m/h), default unit: minutes
        keepLastAssistants: 3,
        softTrimRatio: 0.3,
        hardClearRatio: 0.5,
        minPrunableToolChars: 50000,
        softTrim: { maxChars: 4000, headChars: 1500, tailChars: 1500 },
        hardClear: { enabled: true, placeholder: "[Old tool result content cleared]" },
        tools: { deny: ["browser", "canvas"] },
      },
    },
  },
}
```

<Accordion title="cache-ttl mode behavior">
  * `mode: "cache-ttl"` mengaktifkan lintasan pemangkasan.
  * `ttl` mengontrol seberapa sering pemangkasan dapat berjalan lagi (setelah sentuhan cache terakhir).
  * Pemangkasan terlebih dahulu melakukan soft-trim pada hasil tool yang terlalu besar, lalu hard-clear pada hasil tool yang lebih lama jika diperlukan.
  * `softTrimRatio` dan `hardClearRatio` menerima nilai dari `0.0` hingga `1.0`; validasi konfigurasi menolak nilai di luar rentang itu.

  **Soft-trim** mempertahankan awal + akhir dan menyisipkan `...` di tengah.

  **Hard-clear** mengganti seluruh hasil tool dengan placeholder.

  Catatan:

  * Blok gambar tidak pernah dipangkas/dibersihkan.
  * Rasio berbasis karakter (perkiraan), bukan jumlah token persis.
  * Jika ada lebih sedikit dari `keepLastAssistants` pesan asisten, pemangkasan dilewati.
</Accordion>

Lihat [Pemangkasan Sesi](/id/concepts/session-pruning) untuk detail perilaku.

### Streaming blok

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      blockStreamingDefault: "off", // on | off
      blockStreamingBreak: "text_end", // text_end | message_end
      blockStreamingChunk: { minChars: 800, maxChars: 1200 },
      blockStreamingCoalesce: { idleMs: 1000 },
      humanDelay: { mode: "natural" }, // off | natural | custom (use minMs/maxMs)
    },
  },
}
```

* Channel non-Telegram memerlukan `*.blockStreaming: true` eksplisit untuk mengaktifkan balasan blok.
* Override channel: `channels.<channel>.blockStreamingCoalesce` (dan varian per akun). Signal/Slack/Discord/Google Chat menggunakan default `minChars: 1500`.
* `humanDelay`: jeda acak antarbalasan blok. `natural` = 800–2500md. Override per agen: `agents.list[].humanDelay`.

Lihat [Streaming](/id/concepts/streaming) untuk detail perilaku + pemotongan.

### Indikator pengetikan

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      typingMode: "instant", // never | instant | thinking | message
      typingIntervalSeconds: 6,
    },
  },
}
```

* Default: `instant` untuk chat langsung/mention, `message` untuk chat grup tanpa mention.
* Override per sesi: `session.typingMode`, `session.typingIntervalSeconds`.

Lihat [Indikator Pengetikan](/id/concepts/typing-indicators).

<a id="agentsdefaultssandbox" />

### `agents.defaults.sandbox`

Sandboxing opsional untuk agen tertanam. Lihat [Sandboxing](/id/gateway/sandboxing) untuk panduan lengkap.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      sandbox: {
        mode: "non-main", // off | non-main | all
        backend: "docker", // docker | ssh | openshell
        scope: "agent", // session | agent | shared
        workspaceAccess: "none", // none | ro | rw
        workspaceRoot: "~/.openclaw/sandboxes",
        docker: {
          image: "openclaw-sandbox:bookworm-slim",
          containerPrefix: "openclaw-sbx-",
          workdir: "/workspace",
          readOnlyRoot: true,
          tmpfs: ["/tmp", "/var/tmp", "/run"],
          network: "none",
          user: "1000:1000",
          capDrop: ["ALL"],
          env: { LANG: "C.UTF-8" },
          setupCommand: "apt-get update && apt-get install -y git curl jq",
          pidsLimit: 256,
          memory: "1g",
          memorySwap: "2g",
          cpus: 1,
          ulimits: {
            nofile: { soft: 1024, hard: 2048 },
            nproc: 256,
          },
          seccompProfile: "/path/to/seccomp.json",
          apparmorProfile: "openclaw-sandbox",
          dns: ["1.1.1.1", "8.8.8.8"],
          extraHosts: ["internal.service:10.0.0.5"],
          binds: ["/home/user/source:/source:rw"],
        },
        ssh: {
          target: "user@gateway-host:22",
          command: "ssh",
          workspaceRoot: "/tmp/openclaw-sandboxes",
          strictHostKeyChecking: true,
          updateHostKeys: true,
          identityFile: "~/.ssh/id_ed25519",
          certificateFile: "~/.ssh/id_ed25519-cert.pub",
          knownHostsFile: "~/.ssh/known_hosts",
          // SecretRefs / inline contents also supported:
          // identityData: { source: "env", provider: "default", id: "SSH_IDENTITY" },
          // certificateData: { source: "env", provider: "default", id: "SSH_CERTIFICATE" },
          // knownHostsData: { source: "env", provider: "default", id: "SSH_KNOWN_HOSTS" },
        },
        browser: {
          enabled: false,
          image: "openclaw-sandbox-browser:bookworm-slim",
          network: "openclaw-sandbox-browser",
          cdpPort: 9222,
          cdpSourceRange: "172.21.0.1/32",
          vncPort: 5900,
          noVncPort: 6080,
          headless: false,
          enableNoVnc: true,
          allowHostControl: false,
          autoStart: true,
          autoStartTimeoutMs: 12000,
        },
        prune: {
          idleHours: 24,
          maxAgeDays: 7,
        },
      },
    },
  },
  tools: {
    sandbox: {
      tools: {
        allow: [
          "exec",
          "process",
          "read",
          "write",
          "edit",
          "apply_patch",
          "sessions_list",
          "sessions_history",
          "sessions_send",
          "sessions_spawn",
          "session_status",
        ],
        deny: ["browser", "canvas", "nodes", "cron", "discord", "gateway"],
      },
    },
  },
}
```

<Accordion title="Sandbox details">
  **Backend:**

  * `docker`: runtime Docker lokal (default)
  * `ssh`: runtime jarak jauh generik berbasis SSH
  * `openshell`: runtime OpenShell

  Saat `backend: "openshell"` dipilih, pengaturan khusus runtime berpindah ke
  `plugins.entries.openshell.config`.

  **Konfigurasi backend SSH:**

  * `target`: target SSH dalam bentuk `user@host[:port]`
  * `command`: perintah klien SSH (default: `ssh`)
  * `workspaceRoot`: root jarak jauh absolut yang digunakan untuk workspace per cakupan
  * `identityFile` / `certificateFile` / `knownHostsFile`: file lokal yang ada yang diteruskan ke OpenSSH
  * `identityData` / `certificateData` / `knownHostsData`: konten inline atau SecretRef yang diwujudkan OpenClaw menjadi file sementara saat runtime
  * `strictHostKeyChecking` / `updateHostKeys`: knob kebijakan host-key OpenSSH

  **Prioritas autentikasi SSH:**

  * `identityData` menang atas `identityFile`
  * `certificateData` menang atas `certificateFile`
  * `knownHostsData` menang atas `knownHostsFile`
  * Nilai `*Data` berbasis SecretRef diselesaikan dari snapshot runtime secret aktif sebelum sesi sandbox dimulai

  **Perilaku backend SSH:**

  * menanamkan workspace jarak jauh satu kali setelah create atau recreate
  * lalu mempertahankan workspace SSH jarak jauh sebagai kanonis
  * merutekan `exec`, tool file, dan path media melalui SSH
  * tidak menyinkronkan perubahan jarak jauh kembali ke host secara otomatis
  * tidak mendukung container browser sandbox

  **Akses workspace:**

  * `none`: workspace sandbox per cakupan di bawah `~/.openclaw/sandboxes`
  * `ro`: workspace sandbox di `/workspace`, workspace agen dipasang read-only di `/agent`
  * `rw`: workspace agen dipasang read/write di `/workspace`

  **Cakupan:**

  * `session`: container + workspace per sesi
  * `agent`: satu container + workspace per agen (default)
  * `shared`: container dan workspace bersama (tanpa isolasi lintas sesi)

  **Konfigurasi plugin OpenShell:**

  ```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
  {
    plugins: {
      entries: {
        openshell: {
          enabled: true,
          config: {
            mode: "mirror", // mirror | remote
            from: "openclaw",
            remoteWorkspaceDir: "/sandbox",
            remoteAgentWorkspaceDir: "/agent",
            gateway: "lab", // optional
            gatewayEndpoint: "https://lab.example", // optional
            policy: "strict", // optional OpenShell policy id
            providers: ["openai"], // optional
            autoProviders: true,
            timeoutSeconds: 120,
          },
        },
      },
    },
  }
  ```

  **Mode OpenShell:**

  * `mirror`: isi remote dari lokal sebelum eksekusi, sinkronkan kembali setelah eksekusi; workspace lokal tetap menjadi kanonis
  * `remote`: isi remote sekali saat sandbox dibuat, lalu pertahankan workspace remote sebagai kanonis

  Dalam mode `remote`, edit host-lokal yang dibuat di luar OpenClaw tidak disinkronkan ke sandbox secara otomatis setelah langkah pengisian awal.
  Transport adalah SSH ke sandbox OpenShell, tetapi plugin memiliki siklus hidup sandbox dan sinkronisasi mirror opsional.

  **`setupCommand`** berjalan sekali setelah pembuatan kontainer (melalui `sh -lc`). Membutuhkan egress jaringan, root yang dapat ditulis, pengguna root.

  **Kontainer secara default menggunakan `network: "none"`** — atur ke `"bridge"` (atau jaringan bridge kustom) jika agen membutuhkan akses keluar.
  `"host"` diblokir. `"container:<id>"` diblokir secara default kecuali Anda secara eksplisit mengatur
  `sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true` (break-glass).
  Giliran app-server Codex dalam sandbox OpenClaw aktif menggunakan pengaturan egress yang sama untuk akses jaringan mode kode native mereka.

  **Lampiran masuk** ditempatkan di `media/inbound/*` dalam workspace aktif.

  **`docker.binds`** memasang direktori host tambahan; bind global dan per agen digabungkan.

  **Browser tersandbox** (`sandbox.browser.enabled`): Chromium + CDP dalam kontainer. URL noVNC disuntikkan ke prompt sistem. Tidak memerlukan `browser.enabled` di `openclaw.json`.
  Akses pengamat noVNC menggunakan autentikasi VNC secara default dan OpenClaw menerbitkan URL token berumur pendek (alih-alih mengekspos kata sandi di URL bersama).

  * `allowHostControl: false` (default) memblokir sesi tersandbox agar tidak menargetkan browser host.
  * `network` default ke `openclaw-sandbox-browser` (jaringan bridge khusus). Atur ke `bridge` hanya ketika Anda secara eksplisit menginginkan konektivitas bridge global.
  * `cdpSourceRange` secara opsional membatasi ingress CDP di tepi kontainer ke rentang CIDR (misalnya `172.21.0.1/32`).
  * `sandbox.browser.binds` memasang direktori host tambahan hanya ke kontainer browser sandbox. Saat diatur (termasuk `[]`), ini menggantikan `docker.binds` untuk kontainer browser.
  * Default peluncuran didefinisikan di `scripts/sandbox-browser-entrypoint.sh` dan disetel untuk host kontainer:
    * `--remote-debugging-address=127.0.0.1`
    * `--remote-debugging-port=<derived from OPENCLAW_BROWSER_CDP_PORT>`
    * `--user-data-dir=${HOME}/.chrome`
    * `--no-first-run`
    * `--no-default-browser-check`
    * `--disable-3d-apis`
    * `--disable-gpu`
    * `--disable-software-rasterizer`
    * `--disable-dev-shm-usage`
    * `--disable-background-networking`
    * `--disable-features=TranslateUI`
    * `--disable-breakpad`
    * `--disable-crash-reporter`
    * `--renderer-process-limit=2`
    * `--no-zygote`
    * `--metrics-recording-only`
    * `--disable-extensions` (diaktifkan secara default)
    * `--disable-3d-apis`, `--disable-software-rasterizer`, dan `--disable-gpu`
      diaktifkan secara default dan dapat dinonaktifkan dengan
      `OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` jika penggunaan WebGL/3D memerlukannya.
    * `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` mengaktifkan kembali ekstensi jika alur kerja Anda
      bergantung padanya.
    * `--renderer-process-limit=2` dapat diubah dengan
      `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N>`; atur `0` untuk menggunakan batas proses
      default Chromium.
    * ditambah `--no-sandbox` saat `noSandbox` diaktifkan.
    * Default adalah baseline image kontainer; gunakan image browser kustom dengan
      entrypoint kustom untuk mengubah default kontainer.
</Accordion>

Sandboxing browser dan `sandbox.docker.binds` hanya untuk Docker.

Bangun image (dari checkout sumber):

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
scripts/sandbox-setup.sh           # main sandbox image
scripts/sandbox-browser-setup.sh   # optional browser image
```

Untuk instalasi npm tanpa checkout sumber, lihat [Sandboxing § Image dan penyiapan](/id/gateway/sandboxing#images-and-setup) untuk perintah `docker build` inline.

### `agents.list` (penggantian per agen)

Gunakan `agents.list[].tts` untuk memberi agen penyedia TTS, suara, model,
gaya, atau mode TTS otomatisnya sendiri. Blok agen melakukan deep-merge di atas
`messages.tts`, sehingga kredensial bersama dapat tetap berada di satu tempat sementara agen individual
hanya mengganti kolom suara atau penyedia yang mereka perlukan. Penggantian agen aktif
berlaku untuk balasan lisan otomatis, `/tts audio`, `/tts status`, dan
alat agen `tts`. Lihat [Text-to-speech](/id/tools/tts#per-agent-voice-overrides)
untuk contoh penyedia dan prioritas.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    list: [
      {
        id: "main",
        default: true,
        name: "Main Agent",
        workspace: "~/.openclaw/workspace",
        agentDir: "~/.openclaw/agents/main/agent",
        model: "anthropic/claude-opus-4-6", // or { primary, fallbacks }
        thinkingDefault: "high", // per-agent thinking level override
        reasoningDefault: "on", // per-agent reasoning visibility override
        fastModeDefault: false, // per-agent fast mode override
        params: { cacheRetention: "none" }, // overrides matching defaults.models params by key
        tts: {
          providers: {
            elevenlabs: { speakerVoiceId: "EXAVITQu4vr4xnSDxMaL" },
          },
        },
        skills: ["docs-search"], // replaces agents.defaults.skills when set
        identity: {
          name: "Samantha",
          theme: "helpful sloth",
          emoji: "🦥",
          avatar: "avatars/samantha.png",
        },
        groupChat: { mentionPatterns: ["@openclaw"] },
        sandbox: { mode: "off" },
        runtime: {
          type: "acp",
          acp: {
            agent: "codex",
            backend: "acpx",
            mode: "persistent",
            cwd: "/workspace/openclaw",
          },
        },
        subagents: { allowAgents: ["*"] },
        tools: {
          profile: "coding",
          allow: ["browser"],
          deny: ["canvas"],
          elevated: { enabled: true },
        },
      },
    ],
  },
}
```

* `id`: id agen stabil (wajib).
* `default`: ketika beberapa diatur, yang pertama menang (peringatan dicatat). Jika tidak ada yang diatur, entri daftar pertama menjadi default.
* `model`: bentuk string menetapkan primary per agen yang ketat tanpa fallback model; bentuk objek `{ primary }` juga ketat kecuali Anda menambahkan `fallbacks`. Gunakan `{ primary, fallbacks: [...] }` untuk mengikutsertakan agen tersebut ke fallback, atau `{ primary, fallbacks: [] }` untuk membuat perilaku ketat eksplisit. Pekerjaan Cron yang hanya mengganti `primary` tetap mewarisi fallback default kecuali Anda mengatur `fallbacks: []`.
* `params`: parameter stream per agen yang digabungkan di atas entri model terpilih di `agents.defaults.models`. Gunakan ini untuk penggantian khusus agen seperti `cacheRetention`, `temperature`, atau `maxTokens` tanpa menduplikasi seluruh katalog model.
* `tts`: penggantian text-to-speech per agen opsional. Blok ini melakukan deep-merge di atas `messages.tts`, jadi simpan kredensial penyedia bersama dan kebijakan fallback di `messages.tts` dan atur hanya nilai khusus persona seperti penyedia, suara, model, gaya, atau mode otomatis di sini.
* `skills`: allowlist Skills per agen opsional. Jika dihilangkan, agen mewarisi `agents.defaults.skills` saat diatur; daftar eksplisit menggantikan default alih-alih menggabungkan, dan `[]` berarti tanpa skills.
* `thinkingDefault`: tingkat thinking default per agen opsional (`off | minimal | low | medium | high | xhigh | adaptive | max`). Mengganti `agents.defaults.thinkingDefault` untuk agen ini ketika tidak ada penggantian per pesan atau sesi yang diatur. Profil penyedia/model yang dipilih mengontrol nilai mana yang valid; untuk Google Gemini, `adaptive` mempertahankan thinking dinamis milik penyedia (`thinkingLevel` dihilangkan pada Gemini 3/3.1, `thinkingBudget: -1` pada Gemini 2.5).
* `reasoningDefault`: visibilitas reasoning default per agen opsional (`on | off | stream`). Mengganti `agents.defaults.reasoningDefault` untuk agen ini ketika tidak ada penggantian reasoning per pesan atau sesi yang diatur.
* `fastModeDefault`: default per agen opsional untuk mode cepat (`"auto" | true | false`). Berlaku ketika tidak ada penggantian mode cepat per pesan atau sesi yang diatur.
* `models`: katalog model/penggantian runtime per agen opsional yang diindeks oleh id lengkap `provider/model`. Gunakan `models["provider/model"].agentRuntime` untuk pengecualian runtime per agen.
* `runtime`: deskriptor runtime per agen opsional. Gunakan `type: "acp"` dengan default `runtime.acp` (`agent`, `backend`, `mode`, `cwd`) saat agen harus default ke sesi harness ACP.
* `identity.avatar`: path relatif workspace, URL `http(s)`, atau URI `data:`.
* File gambar `identity.avatar` lokal relatif workspace dibatasi hingga 2 MB. URL `http(s)` dan URI `data:` tidak diperiksa dengan batas ukuran file lokal.
* `identity` menurunkan default: `ackReaction` dari `emoji`, `mentionPatterns` dari `name`/`emoji`.
* `subagents.allowAgents`: allowlist id agen yang dikonfigurasi untuk target eksplisit `sessions_spawn.agentId` (`["*"]` = target terkonfigurasi apa pun; default: hanya agen yang sama). Sertakan id peminta saat panggilan `agentId` yang menargetkan diri sendiri harus diizinkan. Entri kedaluwarsa yang konfigurasi agennya telah dihapus ditolak oleh `sessions_spawn` dan dihilangkan dari `agents_list`; jalankan `openclaw doctor --fix` untuk membersihkannya, atau tambahkan entri minimal `agents.list[]` jika target tersebut harus tetap dapat di-spawn sambil mewarisi default.
* Penjaga pewarisan sandbox: jika sesi peminta tersandbox, `sessions_spawn` menolak target yang akan berjalan tanpa sandbox.
* `subagents.requireAgentId`: ketika true, blokir panggilan `sessions_spawn` yang menghilangkan `agentId` (memaksa pemilihan profil eksplisit; default: false).

***

## Perutean multi-agen

Jalankan beberapa agen terisolasi di dalam satu Gateway. Lihat [Multi-Agent](/id/concepts/multi-agent).

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    list: [
      { id: "home", default: true, workspace: "~/.openclaw/workspace-home" },
      { id: "work", workspace: "~/.openclaw/workspace-work" },
    ],
  },
  bindings: [
    { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
    { agentId: "work", match: { channel: "whatsapp", accountId: "biz" } },
  ],
}
```

### Kolom kecocokan binding

* `type` (opsional): `route` untuk perutean normal (tipe yang hilang default ke route), `acp` untuk binding percakapan ACP persisten.
* `match.channel` (wajib)
* `match.accountId` (opsional; `*` = akun apa pun; dihilangkan = akun default)
* `match.peer` (opsional; `{ kind: direct|group|channel, id }`)
* `match.guildId` / `match.teamId` (opsional; khusus kanal)
* `acp` (opsional; hanya untuk `type: "acp"`): `{ mode, label, cwd, backend }`

**Urutan kecocokan deterministik:**

1. `match.peer`
2. `match.guildId`
3. `match.teamId`
4. `match.accountId` (tepat, tanpa peer/guild/team)
5. `match.accountId: "*"` (seluruh kanal)
6. Agen default

Di dalam setiap tingkat, entri `bindings` pertama yang cocok menang.

Untuk entri `type: "acp"`, OpenClaw menyelesaikan berdasarkan identitas percakapan yang tepat (`match.channel` + akun + `match.peer.id`) dan tidak menggunakan urutan tingkat binding route di atas.

### Profil akses per agen

<Accordion title="Full access (no sandbox)">
  ```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
  {
    agents: {
      list: [
        {
          id: "personal",
          workspace: "~/.openclaw/workspace-personal",
          sandbox: { mode: "off" },
        },
      ],
    },
  }
  ```
</Accordion>

<Accordion title="Read-only tools + workspace">
  ```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
  {
    agents: {
      list: [
        {
          id: "family",
          workspace: "~/.openclaw/workspace-family",
          sandbox: { mode: "all", scope: "agent", workspaceAccess: "ro" },
          tools: {
            allow: [
              "read",
              "sessions_list",
              "sessions_history",
              "sessions_send",
              "sessions_spawn",
              "session_status",
            ],
            deny: ["write", "edit", "apply_patch", "exec", "process", "browser"],
          },
        },
      ],
    },
  }
  ```
</Accordion>

<Accordion title="No filesystem access (messaging only)">
  ```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
  {
    agents: {
      list: [
        {
          id: "public",
          workspace: "~/.openclaw/workspace-public",
          sandbox: { mode: "all", scope: "agent", workspaceAccess: "none" },
          tools: {
            allow: [
              "sessions_list",
              "sessions_history",
              "sessions_send",
              "sessions_spawn",
              "session_status",
              "whatsapp",
              "telegram",
              "slack",
              "discord",
              "gateway",
            ],
            deny: [
              "read",
              "write",
              "edit",
              "apply_patch",
              "exec",
              "process",
              "browser",
              "canvas",
              "nodes",
              "cron",
              "gateway",
              "image",
            ],
          },
        },
      ],
    },
  }
  ```
</Accordion>

Lihat [Sandbox & Alat Multi-Agen](/id/tools/multi-agent-sandbox-tools) untuk detail prioritas.

***

## Sesi

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  session: {
    scope: "per-sender",
    dmScope: "main", // main | per-peer | per-channel-peer | per-account-channel-peer
    identityLinks: {
      alice: ["telegram:123456789", "discord:987654321012345678"],
    },
    reset: {
      mode: "daily", // daily | idle
      atHour: 4,
      idleMinutes: 60,
    },
    resetByType: {
      thread: { mode: "daily", atHour: 4 },
      direct: { mode: "idle", idleMinutes: 240 },
      group: { mode: "idle", idleMinutes: 120 },
    },
    resetTriggers: ["/new", "/reset"],
    store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
    maintenance: {
      mode: "enforce", // enforce (default) | warn
      pruneAfter: "30d",
      maxEntries: 500,
      resetArchiveRetention: "30d", // duration or false
      maxDiskBytes: "500mb", // optional hard budget
      highWaterBytes: "400mb", // optional cleanup target
    },
    threadBindings: {
      enabled: true,
      idleHours: 24, // default inactivity auto-unfocus in hours (`0` disables)
      maxAgeHours: 0, // default hard max age in hours (`0` disables)
    },
    mainKey: "main", // legacy (runtime always uses "main")
    agentToAgent: { maxPingPongTurns: 5 },
    sendPolicy: {
      rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }],
      default: "allow",
    },
  },
}
```

<Accordion title="Session field details">
  * **`scope`**: strategi pengelompokan sesi dasar untuk konteks obrolan grup.
    * `per-sender` (default): setiap pengirim mendapatkan sesi terisolasi dalam konteks channel.
    * `global`: semua peserta dalam konteks channel berbagi satu sesi (gunakan hanya ketika konteks bersama memang dimaksudkan).
  * **`dmScope`**: cara DM dikelompokkan.
    * `main`: semua DM berbagi sesi utama.
    * `per-peer`: isolasi berdasarkan id pengirim lintas channel.
    * `per-channel-peer`: isolasi per channel + pengirim (direkomendasikan untuk kotak masuk multi-pengguna).
    * `per-account-channel-peer`: isolasi per akun + channel + pengirim (direkomendasikan untuk multi-akun).
  * **`identityLinks`**: memetakan id kanonis ke peer berprefiks penyedia untuk berbagi sesi lintas channel. Perintah dock seperti `/dock_discord` menggunakan peta yang sama untuk mengalihkan rute balasan sesi aktif ke peer channel tertaut lain; lihat [Docking channel](/id/concepts/channel-docking).
  * **`reset`**: kebijakan reset utama. `daily` mereset pada waktu lokal `atHour`; `idle` mereset setelah `idleMinutes`. Saat keduanya dikonfigurasi, yang kedaluwarsa lebih dulu menang. Kesegaran reset harian menggunakan `sessionStartedAt` pada baris sesi; kesegaran reset idle menggunakan `lastInteractionAt`. Penulisan latar belakang/peristiwa sistem seperti Heartbeat, bangun Cron, notifikasi exec, dan pembukuan Gateway dapat memperbarui `updatedAt`, tetapi tidak menjaga sesi harian/idle tetap segar.
  * **`resetByType`**: override per tipe (`direct`, `group`, `thread`). `dm` lama diterima sebagai alias untuk `direct`.
  * **`mainKey`**: kolom lama. Runtime selalu menggunakan `"main"` untuk bucket obrolan langsung utama.
  * **`agentToAgent.maxPingPongTurns`**: jumlah maksimum giliran balasan bolak-balik antar agen selama pertukaran agen-ke-agen (bilangan bulat, rentang: `0`-`20`, default: `5`). `0` menonaktifkan rantai ping-pong.
  * **`sendPolicy`**: cocokkan berdasarkan `channel`, `chatType` (`direct|group|channel`, dengan alias lama `dm`), `keyPrefix`, atau `rawKeyPrefix`. Penolakan pertama menang.
  * **`maintenance`**: kontrol pembersihan + retensi penyimpanan sesi.
    * `mode`: `enforce` menerapkan pembersihan dan merupakan default; `warn` hanya mengeluarkan peringatan.
    * `pruneAfter`: batas usia untuk entri usang (default `30d`).
    * `maxEntries`: jumlah maksimum entri dalam `sessions.json` (default `500`). Runtime menulis pembersihan batch dengan buffer high-water kecil untuk batas ukuran produksi; `openclaw sessions cleanup --enforce` langsung menerapkan batas tersebut.
    * Sesi probe model-run Gateway berumur pendek menggunakan retensi tetap `24h`, tetapi pembersihan dibatasi tekanan: pembersihan hanya menghapus baris probe model-run ketat yang usang ketika tekanan pemeliharaan/batas entri sesi tercapai. Hanya kunci probe eksplisit ketat yang cocok dengan `agent:*:explicit:model-run-<uuid>` yang memenuhi syarat; sesi langsung, grup, thread, Cron, hook, Heartbeat, ACP, dan sub-agen normal tidak mewarisi retensi 24 jam ini. Saat pembersihan model-run berjalan, pembersihan tersebut berjalan sebelum pembersihan entri usang `pruneAfter` yang lebih luas dan batas `maxEntries`.
    * `rotateBytes`: tidak digunakan lagi dan diabaikan; `openclaw doctor --fix` menghapusnya dari konfigurasi lama.
    * `resetArchiveRetention`: retensi untuk arsip transkrip `*.reset.<timestamp>`. Default ke `pruneAfter`; atur `false` untuk menonaktifkan.
    * `maxDiskBytes`: anggaran disk direktori sesi opsional. Dalam mode `warn`, ini mencatat peringatan; dalam mode `enforce`, ini menghapus artefak/sesi tertua terlebih dahulu.
    * `highWaterBytes`: target opsional setelah pembersihan anggaran. Default ke `80%` dari `maxDiskBytes`.
  * **`threadBindings`**: default global untuk fitur sesi terikat thread.
    * `enabled`: sakelar default utama (penyedia dapat meng-override; Discord menggunakan `channels.discord.threadBindings.enabled`)
    * `idleHours`: auto-unfocus default karena tidak aktif dalam jam (`0` menonaktifkan; penyedia dapat meng-override)
    * `maxAgeHours`: usia maksimum keras default dalam jam (`0` menonaktifkan; penyedia dapat meng-override)
    * `spawnSessions`: gerbang default untuk membuat sesi kerja terikat thread dari `sessions_spawn` dan spawn thread ACP. Default ke `true` saat binding thread diaktifkan; penyedia/akun dapat meng-override.
    * `defaultSpawnContext`: konteks subagen native default untuk spawn terikat thread (`"fork"` atau `"isolated"`). Default ke `"fork"`.
</Accordion>

***

## Pesan

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  messages: {
    responsePrefix: "🦞", // or "auto"
    ackReaction: "👀",
    ackReactionScope: "group-mentions", // group-mentions | group-all | direct | all
    removeAckAfterReply: false,
    queue: {
      mode: "followup", // steer | followup | collect | interrupt
      debounceMs: 500,
      cap: 20,
      drop: "summarize", // old | new | summarize
      byChannel: {
        whatsapp: "followup",
        telegram: "followup",
      },
    },
    inbound: {
      debounceMs: 2000, // 0 disables
      byChannel: {
        whatsapp: 5000,
        slack: 1500,
      },
    },
  },
}
```

### Prefiks respons

Override per channel/akun: `channels.<channel>.responsePrefix`, `channels.<channel>.accounts.<id>.responsePrefix`.

Resolusi (yang paling spesifik menang): akun → channel → global. `""` menonaktifkan dan menghentikan cascade. `"auto"` menurunkan `[{identity.name}]`.

**Variabel template:**

| Variabel          | Deskripsi                      | Contoh                      |
| ----------------- | ------------------------------ | --------------------------- |
| `{model}`         | Nama model singkat             | `claude-opus-4-6`           |
| `{modelFull}`     | Pengidentifikasi model lengkap | `anthropic/claude-opus-4-6` |
| `{provider}`      | Nama penyedia                  | `anthropic`                 |
| `{thinkingLevel}` | Tingkat berpikir saat ini      | `high`, `low`, `off`        |
| `{identity.name}` | Nama identitas agen            | (sama seperti `"auto"`)     |

Variabel tidak peka huruf besar-kecil. `{think}` adalah alias untuk `{thinkingLevel}`.

### Reaksi ack

* Default ke `identity.emoji` agen aktif, jika tidak ada `"👀"`. Atur `""` untuk menonaktifkan.
* Override per channel: `channels.<channel>.ackReaction`, `channels.<channel>.accounts.<id>.ackReaction`.
* Urutan resolusi: akun → channel → `messages.ackReaction` → fallback identitas.
* Cakupan: `group-mentions` (default), `group-all`, `direct`, `all`.
* `removeAckAfterReply`: menghapus ack setelah balasan pada channel yang mendukung reaksi seperti Slack, Discord, Signal, Telegram, WhatsApp, dan iMessage.
* `messages.statusReactions.enabled`: mengaktifkan reaksi status siklus hidup pada Slack, Discord, Signal, Telegram, dan WhatsApp.
  Pada Slack dan Discord, nilai yang tidak disetel mempertahankan reaksi status aktif saat reaksi ack aktif.
  Pada Signal, Telegram, dan WhatsApp, atur secara eksplisit ke `true` untuk mengaktifkan reaksi status siklus hidup.
* `messages.statusReactions.emojis`: meng-override kunci emoji siklus hidup:
  `queued`, `thinking`, `compacting`, `tool`, `coding`, `web`, `deploy`, `build`,
  `concierge`, `done`, `error`, `stallSoft`, dan `stallHard`.
  Telegram hanya mengizinkan kumpulan reaksi tetap, jadi emoji terkonfigurasi yang tidak didukung akan fallback
  ke varian status terdekat yang didukung untuk obrolan tersebut.

### Debounce masuk

Mengelompokkan pesan teks-saja yang cepat dari pengirim yang sama menjadi satu giliran agen. Media/lampiran langsung di-flush. Perintah kontrol melewati debouncing.

### TTS (teks-ke-ucapan)

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  messages: {
    tts: {
      auto: "always", // off | always | inbound | tagged
      mode: "final", // final | all
      provider: "elevenlabs",
      summaryModel: "openai/gpt-5.4-mini",
      modelOverrides: { enabled: true },
      maxTextLength: 4000,
      timeoutMs: 30000,
      prefsPath: "~/.openclaw/settings/tts.json",
      providers: {
        elevenlabs: {
          apiKey: "elevenlabs_api_key",
          baseUrl: "https://api.elevenlabs.io",
          speakerVoiceId: "voice_id",
          modelId: "eleven_multilingual_v2",
          seed: 42,
          applyTextNormalization: "auto",
          languageCode: "en",
          voiceSettings: {
            stability: 0.5,
            similarityBoost: 0.75,
            style: 0.0,
            useSpeakerBoost: true,
            speed: 1.0,
          },
        },
        microsoft: {
          speakerVoice: "en-US-AvaMultilingualNeural",
          lang: "en-US",
          outputFormat: "audio-24khz-48kbitrate-mono-mp3",
        },
        openai: {
          apiKey: "openai_api_key",
          baseUrl: "https://api.openai.com/v1",
          model: "gpt-4o-mini-tts",
          speakerVoice: "alloy",
        },
      },
    },
  },
}
```

* `auto` mengontrol mode auto-TTS default: `off`, `always`, `inbound`, atau `tagged`. `/tts on|off` dapat mengganti preferensi lokal, dan `/tts status` menampilkan status efektif.
* `summaryModel` mengganti `agents.defaults.model.primary` untuk ringkasan otomatis.
* `modelOverrides` diaktifkan secara default; `modelOverrides.allowProvider` default-nya `false` (ikut serta secara eksplisit).
* Kunci API menggunakan fallback ke `ELEVENLABS_API_KEY`/`XI_API_KEY` dan `OPENAI_API_KEY`.
* Penyedia ucapan bawaan dimiliki oleh plugin. Jika `plugins.allow` diatur, sertakan setiap Plugin penyedia TTS yang ingin Anda gunakan, misalnya `microsoft` untuk Edge TTS. Id penyedia lama `edge` diterima sebagai alias untuk `microsoft`.
* `providers.openai.baseUrl` mengganti endpoint OpenAI TTS. Urutan resolusinya adalah konfigurasi, lalu `OPENAI_TTS_BASE_URL`, lalu `https://api.openai.com/v1`.
* Ketika `providers.openai.baseUrl` mengarah ke endpoint non-OpenAI, OpenClaw memperlakukannya sebagai server TTS yang kompatibel dengan OpenAI dan melonggarkan validasi model/suara.

***

## Bicara

Default untuk mode Bicara (macOS/iOS/Android).

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  talk: {
    provider: "elevenlabs",
    providers: {
      elevenlabs: {
        speakerVoiceId: "elevenlabs_voice_id",
        voiceAliases: {
          Clawd: "EXAVITQu4vr4xnSDxMaL",
          Roger: "CwhRBWXzGAHq8TQ4Fs17",
        },
        modelId: "eleven_v3",
        outputFormat: "mp3_44100_128",
        apiKey: "elevenlabs_api_key",
      },
      mlx: {
        modelId: "mlx-community/Soprano-80M-bf16",
      },
      system: {},
    },
    consultThinkingLevel: "low",
    consultFastMode: true,
    speechLocale: "ru-RU",
    silenceTimeoutMs: 1500,
    interruptOnSpeech: true,
    realtime: {
      provider: "openai",
      providers: {
        openai: {
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
        },
      },
      instructions: "Speak warmly and keep answers brief.",
      mode: "realtime",
      transport: "webrtc",
      brain: "agent-consult",
    },
  },
}
```

* `talk.provider` harus cocok dengan kunci di `talk.providers` ketika beberapa penyedia Bicara dikonfigurasi.
* Kunci Bicara datar lama (`talk.voiceId`, `talk.voiceAliases`, `talk.modelId`, `talk.outputFormat`, `talk.apiKey`) hanya untuk kompatibilitas. Jalankan `openclaw doctor --fix` untuk menulis ulang konfigurasi tersimpan ke `talk.providers.<provider>`.
* Id suara menggunakan fallback ke `ELEVENLABS_VOICE_ID` atau `SAG_VOICE_ID`.
* `providers.*.apiKey` menerima string teks biasa atau objek SecretRef.
* Fallback `ELEVENLABS_API_KEY` hanya berlaku ketika tidak ada kunci API Bicara yang dikonfigurasi.
* `providers.*.voiceAliases` memungkinkan direktif Bicara menggunakan nama yang mudah dikenali.
* `providers.mlx.modelId` memilih repo Hugging Face yang digunakan oleh pembantu MLX lokal macOS. Jika dihilangkan, macOS menggunakan `mlx-community/Soprano-80M-bf16`.
* Pemutaran MLX macOS berjalan melalui pembantu bawaan `openclaw-mlx-tts` saat tersedia, atau executable di `PATH`; `OPENCLAW_MLX_TTS_BIN` mengganti jalur pembantu untuk pengembangan.
* `consultThinkingLevel` mengontrol tingkat berpikir untuk eksekusi agen OpenClaw penuh di balik panggilan Control UI Bicara waktu nyata `openclaw_agent_consult`. Biarkan tidak diatur untuk mempertahankan perilaku sesi/model normal.
* `consultFastMode` menetapkan penggantian mode cepat sekali pakai untuk konsultasi Control UI Bicara waktu nyata tanpa mengubah pengaturan mode cepat normal sesi.
* `speechLocale` menetapkan id lokal BCP 47 yang digunakan oleh pengenalan ucapan Bicara iOS/macOS. Biarkan tidak diatur untuk menggunakan default perangkat.
* `silenceTimeoutMs` mengontrol berapa lama mode Bicara menunggu setelah pengguna diam sebelum mengirim transkrip. Tidak diatur mempertahankan jendela jeda default platform (`700 ms on macOS and Android, 900 ms on iOS`).
* `realtime.instructions` menambahkan instruksi sistem yang ditujukan ke penyedia ke prompt waktu nyata bawaan OpenClaw, sehingga gaya suara dapat dikonfigurasi tanpa kehilangan panduan default `openclaw_agent_consult`.
* `realtime.consultRouting` mengontrol fallback relai Gateway ketika penyedia waktu nyata menghasilkan transkrip pengguna final tanpa `openclaw_agent_consult`: `provider-direct` mempertahankan balasan penyedia langsung, sedangkan `force-agent-consult` merutekan permintaan yang telah difinalisasi melalui OpenClaw.

***

## Terkait

* [Referensi konfigurasi](/id/gateway/configuration-reference) — semua kunci konfigurasi lainnya
* [Konfigurasi](/id/gateway/configuration) — tugas umum dan penyiapan cepat
* [Contoh konfigurasi](/id/gateway/configuration-examples)
