# Environment Variables Reference (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../reference/ENVIRONMENT.md) · 🇪🇹 [am](../../../am/docs/reference/ENVIRONMENT.md) · 🇸🇦 [ar](../../../ar/docs/reference/ENVIRONMENT.md) · 🇦🇿 [az](../../../az/docs/reference/ENVIRONMENT.md) · 🇧🇬 [bg](../../../bg/docs/reference/ENVIRONMENT.md) · 🇧🇩 [bn](../../../bn/docs/reference/ENVIRONMENT.md) · 🇧🇦 [bs](../../../bs/docs/reference/ENVIRONMENT.md) · 🇨🇿 [cs](../../../cs/docs/reference/ENVIRONMENT.md) · 🇩🇰 [da](../../../da/docs/reference/ENVIRONMENT.md) · 🇩🇪 [de](../../../de/docs/reference/ENVIRONMENT.md) · 🇬🇷 [el](../../../el/docs/reference/ENVIRONMENT.md) · 🇪🇸 [es](../../../es/docs/reference/ENVIRONMENT.md) · 🇪🇪 [et](../../../et/docs/reference/ENVIRONMENT.md) · 🇮🇷 [fa](../../../fa/docs/reference/ENVIRONMENT.md) · 🇫🇮 [fi](../../../fi/docs/reference/ENVIRONMENT.md) · 🇫🇷 [fr](../../../fr/docs/reference/ENVIRONMENT.md) · 🇮🇪 [ga](../../../ga/docs/reference/ENVIRONMENT.md) · 🇮🇳 [gu](../../../gu/docs/reference/ENVIRONMENT.md) · 🇳🇬 [ha](../../../ha/docs/reference/ENVIRONMENT.md) · 🇮🇱 [he](../../../he/docs/reference/ENVIRONMENT.md) · 🇮🇳 [hi](../../../hi/docs/reference/ENVIRONMENT.md) · 🇭🇷 [hr](../../../hr/docs/reference/ENVIRONMENT.md) · 🇭🇺 [hu](../../../hu/docs/reference/ENVIRONMENT.md) · 🇦🇲 [hy](../../../hy/docs/reference/ENVIRONMENT.md) · 🇳🇬 [ig](../../../ig/docs/reference/ENVIRONMENT.md) · 🇮🇹 [it](../../../it/docs/reference/ENVIRONMENT.md) · 🇯🇵 [ja](../../../ja/docs/reference/ENVIRONMENT.md) · 🇬🇪 [ka](../../../ka/docs/reference/ENVIRONMENT.md) · 🇰🇭 [km](../../../km/docs/reference/ENVIRONMENT.md) · 🇮🇳 [kn](../../../kn/docs/reference/ENVIRONMENT.md) · 🇰🇷 [ko](../../../ko/docs/reference/ENVIRONMENT.md) · 🇱🇹 [lt](../../../lt/docs/reference/ENVIRONMENT.md) · 🇱🇻 [lv](../../../lv/docs/reference/ENVIRONMENT.md) · 🇮🇳 [ml](../../../ml/docs/reference/ENVIRONMENT.md) · 🇮🇳 [mr](../../../mr/docs/reference/ENVIRONMENT.md) · 🇲🇾 [ms](../../../ms/docs/reference/ENVIRONMENT.md) · 🇲🇹 [mt](../../../mt/docs/reference/ENVIRONMENT.md) · 🇲🇲 [my](../../../my/docs/reference/ENVIRONMENT.md) · 🇳🇵 [ne](../../../ne/docs/reference/ENVIRONMENT.md) · 🇳🇱 [nl](../../../nl/docs/reference/ENVIRONMENT.md) · 🇳🇴 [no](../../../no/docs/reference/ENVIRONMENT.md) · 🇮🇳 [or](../../../or/docs/reference/ENVIRONMENT.md) · 🇮🇳 [pa](../../../pa/docs/reference/ENVIRONMENT.md) · 🇵🇭 [phi](../../../phi/docs/reference/ENVIRONMENT.md) · 🇵🇱 [pl](../../../pl/docs/reference/ENVIRONMENT.md) · 🇵🇹 [pt](../../../pt/docs/reference/ENVIRONMENT.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/reference/ENVIRONMENT.md) · 🇷🇴 [ro](../../../ro/docs/reference/ENVIRONMENT.md) · 🇷🇺 [ru](../../../ru/docs/reference/ENVIRONMENT.md) · 🇱🇰 [si](../../../si/docs/reference/ENVIRONMENT.md) · 🇸🇰 [sk](../../../sk/docs/reference/ENVIRONMENT.md) · 🇸🇮 [sl](../../../sl/docs/reference/ENVIRONMENT.md) · 🇷🇸 [sr](../../../sr/docs/reference/ENVIRONMENT.md) · 🇸🇪 [sv](../../../sv/docs/reference/ENVIRONMENT.md) · 🇰🇪 [sw](../../../sw/docs/reference/ENVIRONMENT.md) · 🇮🇳 [ta](../../../ta/docs/reference/ENVIRONMENT.md) · 🇮🇳 [te](../../../te/docs/reference/ENVIRONMENT.md) · 🇹🇭 [th](../../../th/docs/reference/ENVIRONMENT.md) · 🇹🇷 [tr](../../../tr/docs/reference/ENVIRONMENT.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/reference/ENVIRONMENT.md) · 🇵🇰 [ur](../../../ur/docs/reference/ENVIRONMENT.md) · 🇺🇿 [uz](../../../uz/docs/reference/ENVIRONMENT.md) · 🇻🇳 [vi](../../../vi/docs/reference/ENVIRONMENT.md) · 🇳🇬 [yo](../../../yo/docs/reference/ENVIRONMENT.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/reference/ENVIRONMENT.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/reference/ENVIRONMENT.md)
---
> Referensi lengkap untuk setiap variabel lingkungan yang dikenali oleh OmniRoute.
> Untuk templat mulai cepat, lihat [`.env.example`](../../.env.example).
> [!IMPORTANT]
> Setiap variabel yang didokumentasikan di sini juga harus tercantum dalam `.env.example`, dan
> setiap variabel dalam `.env.example` harus tercantum di sini. `npm run check:env-doc-sync`
> memastikan hal ini saat commit dan di CI. Untuk mengecualikan suatu variabel secara sengaja, tambahkan variabel tersebut ke
> daftar izin di dalam `scripts/check/check-env-doc-sync.mjs`.
---
## Daftar Isi
- [1. Rahasia yang Wajib](#1-rahasia-yang-wajib)
- [2. Penyimpanan & Basis Data](#2-penyimpanan--basis-data)
- [3. Jaringan & Port](#3-jaringan--port)
- [4. Keamanan & Autentikasi](#4-keamanan--autentikasi)
- [5. Sanitasi Input & Perlindungan PII](#5-sanitasi-input--perlindungan-pii)
- [6. Kebijakan Alat & Perutean](#6-kebijakan-alat--perutean)
- [7. URL & Sinkronisasi Cloud](#7-url--sinkronisasi-cloud)
- [8. Proksi Keluar](#8-proksi-keluar)
- [9. Integrasi Alat CLI](#9-integrasi-alat-cli)
- [10. Integrasi Agen Internal & MCP](#10-integrasi-agen-internal--mcp)
- [11. Kredensial Penyedia OAuth](#11-kredensial-penyedia-oauth)
- [12. Penggantian User-Agent Penyedia](#12-penggantian-user-agent-penyedia)
- [13. Kompatibilitas Sidik Jari CLI](#13-kompatibilitas-sidik-jari-cli)
- [14. Penyedia Kunci API](#14-penyedia-kunci-api)
- [15. Pengaturan Waktu Habis](#15-pengaturan-waktu-habis)
- [16. Pencatatan](#16-pencatatan)
- [17. Pengoptimalan Memori](#17-pengoptimalan-memori)
- [18. Sinkronisasi Harga](#18-sinkronisasi-harga)
- [19. Sinkronisasi Model (Dev)](#19-sinkronisasi-model-dev)
- [20. Pengaturan Khusus Penyedia](#20-pengaturan-khusus-penyedia)
- [21. Kesehatan Proksi](#21-kesehatan-proksi)
- [22. Debugging](#22-debugging)
- [23. Integrasi GitHub](#23-integrasi-github)
- [24. Sandbox Skills (v3.8.0+)](#24-sandbox-skills-v380)
- [27. Umpan Radar (Hosting Mandiri)](#27-umpan-radar-hosting-mandiri)
- [Skenario Deployment](#skenario-deployment)
- [Audit: Variabel yang Dihapus / Tidak Digunakan](#audit-variabel-yang-dihapus--tidak-digunakan)
---
## 1. Rahasia yang Wajib
Variabel-variabel ini **harus** ditetapkan sebelum dijalankan untuk pertama kalinya. Tanpa variabel tersebut, aplikasi akan menolak untuk dimulai atau beroperasi dengan nilai default yang tidak aman.
| Variabel | Wajib | Default | File Sumber | Deskripsi |
| ---------------------------- | ----------------- | ------------------------ | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `JWT_SECRET` | **Ya** | _(tidak ada)_ | `src/lib/auth` | Menandatangani/memverifikasi semua cookie sesi dasbor (JWT). Buat dengan `openssl rand -base64 48`. |
| `API_KEY_SECRET` | **Ya** | _(tidak ada)_ | `src/lib/db/apiKeys.ts` | Kunci enkripsi AES untuk nilai kunci API yang tersimpan di SQLite. Buat dengan `openssl rand -hex 32`. |
| `INITIAL_PASSWORD` | **Ya** | `CHANGEME` | Skrip bootstrap | Menetapkan kata sandi awal dasbor admin (sesuai dengan default `.env.example` — sengaja dibuat jelas tidak aman untuk memaksa perubahan). **Ubah sebelum penggunaan pertama.** Setelah masuk, ubah melalui Dasbor → Pengaturan → Keamanan. |
| `OMNIROUTE_WS_BRIDGE_SECRET` | **Ya** (produksi) | _(tidak disetel)_ | `src/app/api/internal/codex-responses-ws/route.ts` | Rahasia bersama untuk jembatan WebSocket Codex Responses internal. Mengautentikasi permintaan jembatan antara relai WS Electron/browser dan OmniRoute. ⚠️ **WAJIB dalam produksi — jika tidak disetel, semua permintaan jembatan WS akan ditolak.** Buat dengan `openssl rand -base64 32`. |
| `OMNIROUTE_SW_BUILD_ID` | Tidak | _(SHA git)_ | `next.config.mjs`, `scripts/build/assembleStandalone.mjs` | ID eksplisit untuk membatalkan cache service worker bagi shell PWA (#11779); yang pertama dalam rantai resolusi. |
| `SOURCE_VERSION` | Tidak | _(tidak disetel)_ | `next.config.mjs`, `scripts/build/assembleStandalone.mjs` | Yang kedua dalam rantai — disetel oleh builder PaaS (misalnya bergaya Heroku) sebagai commit yang di-deploy. |
| `NEXT_PUBLIC_SW_BUILD_ID` | Tidak | _(diturunkan)_ | `src/shared/components/PwaRegister.tsx` | Nilai publik waktu build yang digunakan klien untuk mendaftarkan `/sw.js?v=…`; diturunkan dari dua nilai di atas, lalu SHA git. |
| `OMNIROUTE_PEER_STAMP_TOKEN` | Tidak (otomatis) | _(otomatis setiap boot)_ | `src/server/authz/policies/management.ts` | Rahasia per proses yang membuktikan bahwa stempel IP peer tepercaya berasal dari server HTTP milik OmniRoute sendiri (`scripts/dev/peer-stamp.mjs`). Middleware authz memercayai lokalitas permintaan (pembatasan loopback/LAN untuk rute LOCAL_ONLY) hanya jika stempel tersebut membawa token ini. Dibuat otomatis setiap kali boot — biarkan tidak disetel; tetapkan secara tetap hanya untuk konfigurasi multiproses yang harus berbagi stempel. |
### Perintah Pembuatan
```bash
# Buat keempat rahasia sekaligus:
echo "JWT_SECRET=$(openssl rand -base64 48)"
echo "API_KEY_SECRET=$(openssl rand -hex 32)"
echo "INITIAL_PASSWORD=$(openssl rand -base64 16)"
echo "OMNIROUTE_WS_BRIDGE_SECRET=$(openssl rand -base64 32)"
```
> [!CAUTION]
> Jangan pernah melakukan commit file `.env` yang berisi rahasia asli ke kontrol versi. `.gitignore` sudah mengecualikan `.env`, tetapi verifikasikan sebelum melakukan push.
---
## 2. Penyimpanan & Basis Data
OmniRoute menggunakan **SQLite** (melalui `better-sqlite3`) untuk semua persistensi. Variabel-variabel ini mengontrol lokasi, enkripsi, dan siklus hidup data.
| Variabel | Default | Berkas Sumber | Deskripsi |
| ------------------------------------------ | ----------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DATA_DIR` | _(tidak disetel)_ | `src/lib/db/core.ts` | Direktori utama untuk basis data SQLite, cadangan, dan berkas data. Timpa untuk volume Docker atau jalur khusus. |
| `OMNIROUTE_ALLOW_DEFAULT_DATA_DIR` | _(tidak disetel)_ | `src/lib/dataPaths.ts` | Mekanisme pengecualian untuk penjaga DATA_DIR pengujian/evaluasi (#10428). Pengujian dan probe evaluasi/cetak Node (`-e`/`--eval`/`-p`/`--print`, termasuk bentuk `--eval=`/`--print=`) tanpa `DATA_DIR` dialihkan ke direktori sementara sekali pakai agar tidak dapat membuka basis data asli milik operator; setel ke `1` untuk kembali menggunakan direktori asli. |
| `OMNIROUTE_BUILD_SHA` | _(tidak disetel)_ | `src/lib/monitoring/buildSha.ts` | SHA Git dari artefak yang sedang berjalan. Dicantumkan oleh `npm run build:release`; dapat diinjeksi dalam kontainer yang dikirim tanpa sentinel `dist/BUILD_SHA`. Ditampilkan sebagai `system.buildSha` pada `/api/monitoring/health`. |
| `OMNIROUTE_RELEASE_REF` | `origin/main` | `scripts/build/buildProvenance.ts` | Ref yang digunakan gerbang asal-usul artefak paket untuk memeriksa SHA build (#10427). |
| `OMNIROUTE_ALLOW_CANARY_BUILD` | _(tidak disetel)_ | `scripts/build/buildProvenance.ts` | Setel ke `1` untuk mengizinkan pengemasan build yang SHA-nya tidak berada pada jalur rilis, dengan mencatatnya sebagai canary yang disengaja alih-alih menggagalkan gerbang (#10427). |
| `OMNIROUTE_SMOKE_API_KEY` | _(tidak disetel)_ | `scripts/ops/deploy-canary.mjs` | Kunci API untuk probe smoke penerapan canary, yang dikirim sebagai `Authorization: Bearer` pada `/v1/chat/completions`. Hanya digunakan oleh skrip penerapan (#10429), tidak pernah oleh server. Tidak terkait dengan variabel `OMNIROUTE_SMOKE_*` milik rangkaian smoke CLI yang harus diaktifkan secara eksplisit (`RUN_CLI_SMOKE=1`, `OMNIROUTE_SMOKE_BASE_URL/MODEL/API_KEY_ENV/TARGETS/TIMEOUT_MS` dalam `tests/integration/upstream-cli-smoke.int.test.ts`) — lihat [Integrasi CLI → Pemeriksaan smoke nyata](../guides/CLI-INTEGRATIONS.md). |
| `OMNIROUTE_BUILDING` | _(tidak disetel)_ | `src/lib/buildPhase.ts` | Sinyal fase build (#10060): disetel ke `1` oleh `scripts/build/build-next-isolated.mjs` dan diwarisi oleh setiap worker build yang dijalankan agar lapisan basis data mengembalikan stub tanpa operasi alih-alih memuat addon native better-sqlite3 (yang menghentikan worker saat keluar). Tidak pernah disetel untuk server yang sedang berjalan. |
| `OMNIROUTE_SKIP_NATIVE_DEP_CHECK` | `0` | `scripts/check/check-native-deps.mjs` | Setel ke `1` untuk melewati pemeriksaan prabuild dependensi native opsional bagi struktur vendor yang tidak umum. Ini tidak membuat dependensi yang hilang menjadi dapat di-build; gunakan hanya ketika dependensi native disediakan melalui mekanisme terpisah. |
| `OMNIROUTE_DATA_DIR` | _(tidak disetel)_ | `open-sse/executors/promptql/threadSticky.ts` | **Alias fallback** untuk `DATA_DIR`, diperiksa hanya ketika `DATA_DIR` tidak disetel. Digunakan untuk menemukan cache sesi thread-sticky milik eksekutor PromptQL pada disk (`
/promptql-thread-sessions.json`); jika kedua variabel tidak disetel, cache hanya disimpan dalam memori (tidak dipertahankan setelah dimulai ulang). |
| `OMNIROUTE_PLUGINS_DIR` | _(tidak disetel)_ | `src/lib/plugins/scanner.ts` | Direktori yang dibaca oleh **pemindai plugin runtime** — sekaligus direktori utama tempat pengelola plugin melakukan instalasi — dengan menimpa default yang diturunkan dari direktori home (#11827). Arahkan ke struktur plugin yang dipasang melalui bind mount di Docker/K8s, alih-alih memindahkan HOME hanya untuk merelokasi jalur pemindaian (HOME juga mengatur semua perilaku lain yang relatif terhadap direktori home). Jika tidak disetel = `~/.omniroute/plugins`, atau `/tmp/.omniroute/plugins` ketika proses sama sekali tidak mengekspor home — kondisi plugin tidak terdeteksi secara diam-diam yang diatasi oleh variabel ini. Direktori yang telah di-resolve dicatat satu kali saat startup sebagai `scanner.dir_resolved`, beserta input yang dipilih. Hanya sisi server: plugin perintah CLI tetap menggunakan `OMNIROUTE_PLUGIN_PATH` miliknya sendiri (bagian 9). |
| `STORAGE_ENCRYPTION_KEY` | _(kosong = dinonaktifkan)_ | `src/lib/db/encryption.ts` | Kunci AES untuk enkripsi penuh basis data SQLite saat disimpan. Buat dengan `openssl rand -hex 32`. |
| `STORAGE_ENCRYPTION_KEY_VERSION` | `v1` | `scripts/build/bootstrap-env.mjs`, `electron/main.js` | Label versi untuk kunci enkripsi. Naikkan saat melakukan rotasi kunci agar mendukung dekripsi cadangan lama. |
| `DISABLE_SQLITE_AUTO_BACKUP` | `false` | `src/lib/db/backup.ts` | Jika `true`, lewati pencadangan rutin/sebelum penulisan berkas SQLite (penyimpanan/penghapusan harga models.dev, penulisan pengaturan). Pencadangan manual dan sebelum pemulihan tetap dijalankan. Ini **tidak** menonaktifkan snapshot keamanan persisten wajib milik pelaksana migrasi atau perlindungan migrasi massal untuk DB persisten yang sudah ada. Pencadangan nonmanual dibatasi maksimal sekali setiap 60 menit. **Pengaturan → Penyimpanan** di Dasbor dapat menonaktifkan pencadangan otomatis rutin secara terpisah. |
| `OMNIROUTE_CRYPT_KEY` | _(tidak ditetapkan)_ | `src/lib/db/encryption.ts` | **Alias lama** untuk `STORAGE_ENCRYPTION_KEY`. Diterima sebagai nilai cadangan jika variabel utama tidak tersedia. |
| `OMNIROUTE_API_KEY_BASE64` | _(tidak ditetapkan)_ | `src/lib/db/encryption.ts` | **Alias lama** (format yang dikodekan dengan Base64) yang diterima sebagai nilai cadangan. Didekodekan secara otomatis sebelum digunakan. |
| `OMNIROUTE_DB_HEALTHCHECK_INTERVAL_MS` | _(tidak ditetapkan)_ | `src/lib/db/core.ts` | Ganti interval pemeriksaan kesehatan SQLite berkala (md). Jika tidak ditetapkan, nilai default diturunkan dari `NODE_ENV`. |
| `OMNIROUTE_WAL_TRUNCATE_INTERVAL_MS` | _(dihapus)_ | `src/lib/db/walMaintenance.ts` | **Dihapus.** `wal_checkpoint(TRUNCATE)` langsung berkala dapat membuat pemetaan wal-index bersama menjadi tidak valid dan menyebabkan proses mengalami crash dengan SIGBUS (#13973), sehingga penjadwal tidak lagi tersedia. Variabel ini tidak berpengaruh: nilai positif mencatat peringatan penghentian dukungan satu kali, sedangkan `0` atau tidak ditetapkan tidak menghasilkan pesan. WAL dipelihara oleh checkpoint PASSIVE (di bawah) dan dipangkas oleh checkpoint saat penghentian. |
| `OMNIROUTE_WAL_PASSIVE_INTERVAL_MS` | `300000` (5m) | `src/lib/db/walMaintenance.ts` | Ganti interval (md) `wal_checkpoint(PASSIVE)` yang sering dijalankan. Menjaga agar frame WAL yang tertunda tetap sedikit sehingga checkpoint tetap cepat dan ukuran berkas WAL tetap terbatas di antara pemangkasan saat penghentian. `0` menonaktifkannya. |
| `OMNIROUTE_WAL_GUARD_MAX_MB` | `256` | `src/lib/db/walMaintenance.ts` | Saat siklus PASSIVE menemukan berkas WAL melebihi ukuran ini, jalankan `wal_checkpoint(RESTART)` agar WAL dimulai kembali tanpa menulis ulang wal-index yang dipetakan. Checkpoint mode pemangkasan langsung telah dihapus (lihat baris `OMNIROUTE_WAL_TRUNCATE_INTERVAL_MS`). |
| `OMNIROUTE_PRESSURE_SELF_RESTART` | `false` | `open-sse/utils/resourcePressure.ts` | Tetapkan ke `1`/`true`/`yes`/`on` untuk menghentikan proses setelah tekanan sumber daya kritis berlangsung selama `OMNIROUTE_PRESSURE_SELF_RESTART_AFTER_MS`, sehingga supervisor (systemd `Restart=always`, kebijakan mulai ulang Docker) dapat menjalankan kembali proses yang bersih alih-alih terus menyajikan respons 503 tanpa batas waktu. |
| `OMNIROUTE_PRESSURE_SELF_RESTART_AFTER_MS` | `120000` (2m) | `open-sse/utils/resourcePressure.ts` | Durasi tekanan kritis harus berlanjut sebelum penghentian untuk mulai ulang mandiri dipicu. |
| `OMNIROUTE_SQLJS_WASM_PATH` | _(deteksi otomatis)_ | `src/lib/db/adapters/sqljsAdapter.ts` | Jalur eksplisit (absolut atau relatif terhadap cwd) ke `sql-wasm.wasm` saat menggunakan adaptor fallback WASM `sql.js`. Terdeteksi otomatis melalui dependensi paket dan tata letak kandidat jika tidak ditetapkan. |
| `OMNIROUTE_BATCH_RETENTION_DAYS` | `30` | `src/lib/db/cleanup.ts` | Jumlah hari checkpoint tugas Batch API terminal (selesai/gagal/dibatalkan/kedaluwarsa), berkas input/output/galat yang dirujuk, dan barisnya disimpan oleh pembersihan otomatis sebelum dihapus. Hanya berlaku setelah `BATCH_AND_FILE_AUTO_CLEANUP_ENABLED` diaktifkan; sesuai dengan periode retensi output Batch API milik OpenAI. Tidak memengaruhi rute `DELETE /api/v1/batches/delete-completed` yang dipicu operator, yang secara sengaja tetap tanpa syarat (tanpa filter usia). |
| `BATCH_AND_FILE_AUTO_CLEANUP_ENABLED` | `false` | `src/lib/db/cleanup.ts` | Jika `true`, izinkan pembersihan otomatis menghapus tugas Batch API terminal (beserta checkpoint-nya) yang telah melewati `OMNIROUTE_BATCH_RETENTION_DAYS`, serta menghapus konten BLOB dari berkas unggahan yang telah melewati `expires_at` masing-masing. Dinonaktifkan secara default: setiap instalasi yang ada tetap menyimpan data ini persis seperti sebelumnya hingga operator memilih untuk mengaktifkannya. Juga merupakan flag fitur yang dapat diedit melalui dasbor — lihat `docs/reference/FEATURE_FLAGS.md` → Runtime. |
| `OMNIROUTE_SKIP_DB_HEALTHCHECK` | `0` | `src/lib/db/core.ts`, `src/lib/db/healthCheck.ts` | Atur ke `1` untuk sepenuhnya melewati pemeriksaan kesehatan DB saat startup. Berguna untuk tugas berumur pendek dan pengujian integrasi. |
| `OMNIROUTE_FORCE_DB_HEALTHCHECK` | `0` | `src/lib/db/core.ts` | Atur ke `1` untuk memaksa loop pemeriksaan kesehatan DB tetap aktif, bahkan ketika biasanya akan dilewati (misalnya, tugas berumur pendek). |
| `OMNIROUTE_SKIP_POSTINSTALL` | `0` | `scripts/postinstall.mjs` | Atur ke `1` untuk melewati pemanasan runtime native selama `npm install`. Berguna dalam instalasi CI/headless ketika sqlite sudah di-build. |
| `OMNIROUTE_MIGRATIONS_DIR` | _(deteksi otomatis)_ | `src/lib/db/migrationRunner.ts` | Ganti direktori yang dipindai oleh runner migrasi. Berguna saat menyertakan migrasi yang dibundel dalam build khusus. |
| `OMNIROUTE_EXTRA_MIGRATIONS_DIRS` | _(tidak diatur)_ | `src/lib/db/migrationRunner/extraDirs.ts` | Direktori migrasi tambahan sebagai entri `namespace=dir` yang dipisahkan oleh pembatas path platform (misalnya `ee=/opt/app/enterprise/db/migrations`). File yang ditemukan di sana dicatat sebagai `-`, sehingga distribusi yang menyertakan migrasinya sendiri tidak pernah bertabrakan dengan slot numerik upstream. Entri yang salah format, namespace yang tidak valid, atau direktori yang tidak ada akan memicu error saat startup, alih-alih melewati skema secara diam-diam. |
| `OMNIROUTE_MAX_PENDING_MIGRATIONS` | `50` | `src/lib/db/migrationRunner.ts` | Ambang batas keamanan untuk migrasi tertunda dalam jumlah besar (#3416). Startup dibatalkan jika lebih dari jumlah ini migrasi masih tertunda pada DB yang sudah ada (melindungi dari tabel pelacakan yang terhapus). Naikkan nilainya untuk memulihkan cadangan lama; atur ke `0` untuk menonaktifkan pemeriksaan. |
| `OMNIROUTE_INSTALL_UPGRADE_WORKDIR` | _(`/.install-upgrade`)_ | `scripts/check/check-install-upgrade.mjs` | Direktori kerja untuk gerbang rilis `check:install-upgrade`. Direktori ini membutuhkan sekitar 12 GB (dua struktur instalasi berukuran ~3 GB ditambah tarball), sehingga tidak boleh dijalankan pada tmpfs kecil — pada runner yang di-host sendiri, `/tmp` adalah tmpfs berbasis RAM sebesar 12 GB dan gerbang tersebut menghabiskan kapasitasnya, sehingga paket terpotong. |
| `OMNIROUTE_SPEND_FLUSH_INTERVAL_MS` | _(nilai default dalam kode)_ | `src/lib/spend/batchWriter.ts` | Interval flush (ms) untuk penulis pengeluaran/biaya yang diproses secara batch. Nilai yang lebih rendah mengurangi penggabungan operasi tulis; nilai yang lebih tinggi mengurangi kontensi DB. |
| `OMNIROUTE_SPEND_MAX_BUFFER_SIZE` | _(nilai default dalam kode)_ | `src/lib/spend/batchWriter.ts` | Jumlah maksimum entri pengeluaran yang di-buffer sebelum flush paksa. Naikkan pada deployment ber-QPS tinggi; turunkan ketika pembatasan memori lebih penting. |
| `OMNIROUTE_PROXY_FETCH_DEBUG` | _(tidak diatur)_ | `open-sse/utils/proxyFetch.ts` | Atur ke `"true"` untuk mengeluarkan log debug `[ProxyFetch]` pada jalur relay Vercel. Dinonaktifkan secara default untuk menghindari kebocoran petunjuk routing. |
| `PROXY_LOG_INCLUDE_IPS` | `false` | `src/lib/proxyLogger.ts` | Atur ke `"true"` atau `"1"` untuk menyertakan IP klien/egress dan prefiks akun dalam baris log proses `[ProxyEgress]` yang mendetail. Tetap DINONAKTIFKAN secara default agar log proses tidak membocorkan IP atau prefiks akun. |
| `OMNIROUTE_DEBUG` | _(tidak diatur)_ | `bin/cli/commands/quota.mjs` | Atur ke `1` untuk mencetak diagnostik waktu per permintaan (`[omniroute] GET completed in Nms`) dari perintah kuota CLI ke stderr. |
| `OMNIROUTE_HEALTHCHECK_PATH` | _(otomatis)_ | `scripts/dev/healthcheck.mjs` | Path eksplisit yang diperiksa oleh pemeriksaan kesehatan container. Jika tidak diatur, pemeriksaan akan menentukannya dari `OMNIROUTE_BASE_PATH`; mengaturnya akan mengaktifkan kembali endpoint pemantauan mendalam. |
| `OMNIROUTE_DEBUG_COMPLETION` | _(tidak diatur)_ | `bin/cli/commands/completion.mjs` | Atur ke nilai apa pun yang tidak kosong untuk mengeluarkan diagnostik `[omniroute completion]` dari path cache pelengkapan shell CLI (baca/perbarui/tulis). Dinonaktifkan secara default — kegagalan cache tersebut terjadi secara diam-diam agar cache yang hilang/rusak tidak pernah merusak pelengkapan tab. |
| `BATCH_RETRY_DURATION_MS` | `86400000` (24 jam) | `open-sse/services/batchProcessor.ts` | Jendela percobaan ulang maksimum untuk setiap item batch (ms). Item yang melampaui durasi ini ditandai sebagai gagal. |
| `BATCH_BACKOFF_BASE_MS` | `5000` | `open-sse/services/batchProcessor.ts` | Penundaan dasar (ms) untuk backoff eksponensial pada percobaan ulang item batch. |
| `BATCH_BACKOFF_MAX_MS` | `3600000` (1 jam) | `open-sse/services/batchProcessor.ts` | Batas maksimum (ms) untuk backoff eksponensial di antara percobaan ulang item batch. |
| `BATCH_MAX_CONCURRENT` | `1` | `open-sse/services/batchProcessor.ts` | Jumlah maksimum batch yang diproses secara bersamaan. Naikkan untuk meningkatkan throughput; pertahankan tetap rendah guna menghindari lonjakan pembatasan laju. |
> [!IMPORTANT]
> Sebelum mengubah database persisten yang sudah ada, runner migrasi menerbitkan snapshot lengkap
> berbasis alamat konten di bawah `DATA_DIR/db_backups/`. Publikasi memerlukan sistem berkas
> yang mendukung hard link tanpa penimpaan dalam sistem berkas yang sama serta sinkronisasi berkas
> yang tahan lama. Host POSIX juga memerlukan sinkronisasi direktori; di Windows, Node dapat menolak
> handle direktori, sehingga OmniRoute melakukan flush pada berkas yang diterbitkan dan memperlakukan
> sinkronisasi entri direktori sebagai upaya terbaik.
> Jika `DATA_DIR` yang di-mount tidak dapat memberikan jaminan tersebut, startup akan dihentikan secara
> aman sebelum menerapkan migrasi. Pindahkan `DATA_DIR` ke volume yang memiliki kemampuan tersebut;
> jangan gunakan `DISABLE_SQLITE_AUTO_BACKUP` untuk melewati pengamanan migrasi.
### Skenario
| Skenario | Konfigurasi |
| ------------------------ | ------------------------------------------------------------------------------------------ |
| **Pengembangan lokal** | Biarkan semua nilai default. DB berada di `~/.omniroute/omniroute.db`. |
| **Docker** | `DATA_DIR=/data` + mount volume di `/data`. |
| **Dienkripsi saat diam** | Atur `STORAGE_ENCRYPTION_KEY` + simpan cadangan kuncinya! Kehilangannya = kehilangan data. |
| **CI/Pengujian** | `DATA_DIR=/tmp/omniroute-test` — bersifat sementara, tidak memerlukan enkripsi. |
---
## 3. Jaringan & Port
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PORT` | `20128` | `src/lib/runtime/ports.ts` | Port utama untuk UI Dasbor dan endpoint API (mode port tunggal). |
| `OMNIROUTE_BASE_PATH` | _(kosong = root)_ | `next.config.mjs`, `scripts/docker/ensure-docker-base-path.mjs` | Subjalur URL untuk menyajikan OmniRoute di belakang reverse proxy (mengatur `basePath` Next.js; pengalihan autentikasi memperhitungkan basePath). Contoh: `/omniroute`. Di Docker, nilainya disematkan selama `docker build` (`ARG OMNIROUTE_BASE_PATH`); image root bawaan dapat menerapkan nilai runtime yang berbeda satu kali saat container dimulai sebelum Next.js berjalan. Atur `NEXT_PUBLIC_BASE_URL` ke origin publik yang menyertakan subjalur yang sama. |
| `NEXT_PUBLIC_OMNIROUTE_BASE_PATH` | _(kosong = root)_ | `src/shared/hooks/useDisplayBaseUrl.ts` | Salinan `OMNIROUTE_BASE_PATH` yang terlihat oleh browser, disisipkan saat build agar tampilan endpoint dasbor menampilkan `https://host/omniroute/v1`, bukan `https://host/v1`. Menggunakan `OMNIROUTE_BASE_PATH` sebagai fallback jika tidak diatur. Lakukan build ulang setelah mengubahnya (`basePath` Next ditentukan saat build). |
| `DASHBOARD_ALLOW_EMBED` | _(tidak diatur = tidak pernah dapat ditampilkan dalam frame)_ | `next.config.mjs`, `scripts/build/dashboardEmbed.mjs` | Pengaktifan opsional untuk menyematkan halaman HTML melalui iframe. Jika tidak diatur, setiap rute dikirim dengan `frame-ancestors 'none'` + `X-Frame-Options: DENY`. Atur ke `vscode` untuk menyajikan halaman (dasbor, login, dokumentasi, landing page) dengan `frame-ancestors 'self' vscode-webview:` dan tanpa `X-Frame-Options`, sehingga VS Code Simple Browser dapat merendernya (mode `dashboardOpen: "editor"` milik OmniCopilot). Permukaan API (`/api`, `/v1`, `/v1beta`, `/a2a`, `/healthz`, alias tingkat root) tetap menggunakan header ketat dalam kedua kondisi. Hanya `vscode` yang dikenali — `1`/`true` tidak mengaktifkannya. Saat build: lakukan build ulang setelah mengubahnya (`docker build --build-arg DASHBOARD_ALLOW_EMBED=vscode` untuk image; mengaturnya pada instalasi bawaan tidak berpengaruh). |
| `API_PORT` | _(tidak diatur)_ | `src/lib/runtime/ports.ts` | Jika diatur, menyajikan API proxy `/v1/*` pada port terpisah ini. |
| `API_HOST` | `0.0.0.0` | `src/lib/runtime/ports.ts` | Alamat bind untuk port API. |
| `DASHBOARD_PORT` | _(tidak diatur)_ | `src/lib/runtime/ports.ts` | Jika diatur, menyajikan UI Dasbor pada port terpisah ini. |
| `OMNI_MAX_CONCURRENT_CONNECTIONS` | `0` _(dinonaktifkan)_ | `src/sse/utils/backpressure.ts` | Membatasi koneksi chat aktif bersamaan yang sedang diproses; permintaan yang melampaui batas akan menerima `503` dengan `Retry-After`. Bilangan bulat positif mengaktifkan pembatas; tidak diatur/`0` akan menonaktifkannya. |
| `OMNIROUTE_INSTANCE_ID` | _(tidak diatur)_ | `src/shared/resilience/peerRouting.ts` | ID stabil dan unik untuk gateway ini saat merangkai instance OmniRoute. Mengaktifkan pemeriksaan loop peer masuk. Karakter yang diizinkan: huruf, angka, `.`, `_`, `:`, dan `-`; maksimum 64 karakter. |
| `OMNIROUTE_PEER_URLS` | _(tidak disetel)_ | `src/shared/resilience/peerRouting.ts`, `open-sse/executors/base.ts` | URL dasar OmniRoute yang dipisahkan dengan koma dan dapat menerima `X-OmniRoute-Peer-Trace`. Hanya URL upstream yang secara eksplisit masuk daftar yang diizinkan yang menerima metadata peer; semua penyedia lainnya tidak terpengaruh. |
| `OMNIROUTE_PEER_MAX_HOPS` | `4` | `src/shared/resilience/peerRouting.ts` | Jumlah maksimum instans OmniRoute yang telah dikunjungi sebelumnya dan diterima pada permintaan berantai (`1`-`32`). Instans berulang atau anggaran yang telah habis akan mengembalikan HTTP `508 Loop Detected`. |
| `PROD_DASHBOARD_PORT` | `20130` | `docker-compose.prod.yml` | Port yang dipublikasikan pada sisi host untuk Dasbor dalam mode produksi Docker. |
| `PROD_API_PORT` | `20131` | `docker-compose.prod.yml` | Port yang dipublikasikan pada sisi host untuk API dalam mode produksi Docker. |
| `OMNIROUTE_PORT` | _(tidak disetel)_ | `src/lib/runtime/ports.ts` | Diprioritaskan daripada `PORT` saat dijalankan di dalam Electron atau pembungkus lainnya. |
| `LIVE_WS_PORT` | `20129` | `src/server/ws/liveServer.ts` | Port untuk server pemantauan langsung WebSocket secara waktu nyata. |
| `LIVE_WS_HOST` | `127.0.0.1` | `src/server/ws/liveServer.ts` | Alamat pengikatan untuk server WebSocket langsung. Atur ke `0.0.0.0` agar dapat diakses melalui LAN (konfigurasikan juga `LIVE_WS_ALLOWED_ORIGINS`). |
| `LIVE_WS_ALLOWED_ORIGINS` | _(tidak disetel)_ | `src/server/ws/liveServer.ts` | Origin tambahan yang dipisahkan dengan koma dan diizinkan untuk membuka WebSocket langsung. Origin dasbor loopback telah diizinkan secara default. |
| `LIVE_WS_ALLOWED_HOSTS` | _(tidak disetel)_ | `src/server/ws/liveServerAllowList.ts` | Nama host tambahan yang dipisahkan dengan koma dan diizinkan untuk origin WebSocket langsung. Tidak seperti `LIVE_WS_ALLOWED_ORIGINS` (URL origin lengkap), variabel ini hanya mencocokkan bagian host—berguna untuk konfigurasi LAN/Tailscale. |
| `NEXT_PUBLIC_LIVE_WS_PUBLIC_URL` | _(tidak disetel)_ | `src/hooks/useLiveDashboard.ts` | URL publik untuk WebSocket dasbor langsung (sisi browser). Atur saat server WS ditempatkan di belakang proksi balik atau Cloudflare Tunnel (misalnya `wss://ws.my-ai.com/live-ws`); browser akan terhubung ke sana alih-alih ke `ws://hostname:20132`. Bagian nama jalur juga digunakan sebagai jalur peningkatan WebSocket (default: `/live-ws`). |
| `OMNIROUTE_ENABLE_LIVE_WS` | `true` | `src/server/ws/liveServer.ts` dan `scripts/start-ws-server.mjs` | Atur ke `0` atau `false` untuk menonaktifkan server WebSocket waktu nyata (diaktifkan secara default, terikat ke loopback). Opsi CI/harness yang menonaktifkan skrip pembantu WebSocket langsung mandiri. |
| `RELAY_IP_PER_MINUTE` | `30` | `src/app/api/v1/relay/chat/completions/route.ts` | Batas laju relai per (token, IP), dalam permintaan/menit. Disimpan dalam memori, per instans. `0` atau nilai negatif menonaktifkan pembatas dimensi IP (batas DB per token tetap berlaku). |
| `NODE_ENV` | `production` | Inti Next.js | Mengontrol tingkat verbositas logging, caching, pemaparan detail kesalahan, dan pengoptimalan Next.js. |
| `OMNIROUTE_USE_TURBOPACK` | `1` (Turbopack — default kode) | `package.json` / Next.js 16 | Turbopack adalah bundler default untuk `npm run dev` dan `npm run build` (build 2–3× lebih cepat berdasarkan benchmark). Atur ke `0` untuk beralih kembali ke webpack di Windows, ketika mengalami inkompatibilitas native binding/bundler, **atau pada mesin dengan RAM terbatas** — build produksi Turbopack pada lini versi Next.js ini (16.2.x) diketahui dari laporan upstream mencapai puncak penggunaan memori yang jauh lebih tinggi daripada webpack pada grafik modul besar (perbaikan eviksi memori Turbopack di Next 16.3 belum stabil); fallback webpack memiliki puncak penggunaan memori yang jauh lebih rendah. Lihat #6409. |
| `OMNIROUTE_SKIP_DB_HEALTHCHECK` | _(tidak diatur)_ | `src/lib/db/core.ts` / `src/lib/db/healthCheck.ts` | Atur ke `1` untuk melewati pemeriksaan kesehatan integritas SQLite saat startup. Berguna agar proses boot lebih cepat pada database besar. |
| `NOTIFY_SOCKET` | _(tidak diatur)_ | systemd (protokol sd_notify) | Diatur oleh systemd ketika proses berjalan di bawah unit layanan dengan integrasi sd_notify; OmniRoute membacanya (lihat `OMNIROUTE_DISABLE_SD_NOTIFY`) untuk mengirim notifikasi READY/WATCHDOG. Jangan pernah diatur oleh pengguna. |
| `OMNIROUTE_DISABLE_SD_NOTIFY` | _(tidak diatur)_ | `scripts/dev/systemd-notify.mjs` | Atur ke `1` untuk menonaktifkan sd_notify systemd (Type=notify / WatchdogSec=), bahkan ketika berjalan di bawah unit systemd. Notifier tidak melakukan apa pun di luar systemd. |
| `CREDENTIAL_HEALTH_CHECK_INTERVAL` | `300000` | `open-sse/config/constants.ts` / `src/lib/credentialHealth/scheduler.ts` | Interval (ms) untuk scheduler pemeriksaan kesehatan kredensial di latar belakang. Minimum: 10000 (10 dtk). |
| `CREDENTIAL_HEALTH_CACHE_TTL` | `300000` | `open-sse/config/constants.ts` / `src/lib/credentialHealth/cache.ts` | TTL (ms) untuk status kesehatan kredensial yang di-cache. |
| `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` | `false` | `src/lib/credentialHealth/scheduler.ts` | Atur ke `1` atau `true` untuk menonaktifkan pengujian berkala koneksi penyedia di latar belakang. Penyedia pencarian (SEARCH_VALIDATOR_CONFIGS di `src/lib/providers/validation/searchProviders.ts`, misalnya `tavily-search`) selalu dikecualikan dari pemeriksaan menyeluruh — "validasi" mereka merupakan kueri upstream aktual yang dikenai biaya, sehingga pemeriksaan kesehatannya tidak pernah dilakukan secara terjadwal (#9970). |
| `HOST` | `0.0.0.0` | `scripts/dev/run-next.mjs` | Alamat bind untuk server dev/start Next.js. Menggantikan default `0.0.0.0` jika diatur. |
| `HOSTNAME` | `127.0.0.1` | `scripts/dev/run-next-playwright.mjs` | Alamat bind yang digunakan oleh runner Playwright saat meluncurkan Next.js. Default-nya adalah `127.0.0.1` untuk pengujian hermetik. **Jangan gunakan untuk `omniroute serve`** — gunakan `OMNIROUTE_SERVER_HOST` sebagai gantinya (shell POSIX secara otomatis mengatur `HOSTNAME` ke nama mesin; `.env` tidak dapat menggantikannya). |
| `OMNIROUTE_SERVER_HOST` | `0.0.0.0` | `bin/cli/commands/serve.mjs` | Alamat bind untuk `omniroute serve`. Menghindari konflik dengan variabel `HOSTNAME` shell POSIX (selalu diatur ke nama mesin oleh bash/zsh). Beralih ke `0.0.0.0` jika tidak diatur. (#6194) |
### Mode Port
```
┌─────────────────────────── Port Tunggal (bawaan) ──────────────────────────┐
│ PORT=20128 │
│ → Dasbor: http://localhost:20128 │
│ → API: http://localhost:20128/v1/chat/completions │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────── Port Terpisah ──────────────────────────────────┐
│ DASHBOARD_PORT=20128 │
│ API_PORT=20129 │
│ API_HOST=0.0.0.0 │
│ → Dasbor: http://localhost:20128 │
│ → API: http://0.0.0.0:20129/v1/chat/completions │
│ Kasus penggunaan: Ekspos API ke LAN sambil membatasi Dasbor ke localhost. │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────── Produksi Docker ────────────────────────────────┐
│ PROD_DASHBOARD_PORT=443 PROD_API_PORT=8443 │
│ → Memetakan port kontainer ke port host di docker-compose.prod.yml. │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 4. Keamanan & Autentikasi
| Variabel | Bawaan | File Sumber | Deskripsi |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MACHINE_ID_SALT` | `endpoint-proxy-salt` | `src/lib/auth` | Salt yang digabungkan dengan pengenal perangkat keras untuk membuat sidik jari mesin. Ubah untuk setiap deployment guna memastikan isolasi. |
| `OMNIROUTE_CLI_SALT` | _(tidak ditetapkan = salt acak per instalasi yang disimpan di `/cli-token-salt.json`)_ | `src/lib/machineToken.ts` | Salt HMAC untuk memperoleh token autentikasi CLI lokal. Menetapkan nilai ini akan merotasi semua token CLI pada mesin dan selalu diprioritaskan daripada salt yang disimpan. Lihat `docs/security/CLI_TOKEN.md`. |
| `AUTH_COOKIE_SECURE` | `false` | `src/lib/auth` | Menetapkan flag `Secure` pada cookie sesi. **Harus bernilai `true`** saat dijalankan di belakang HTTPS. |
| `REQUIRE_API_KEY` | `false` | middleware API | Jika bernilai `true`, semua permintaan proksi `/v1/*` harus menyertakan kunci API yang valid. **Flag ini tidak membatasi `GET /v1/models`**, yang mengikuti postur login dasbor (`requireAuthForModels`) — sehingga respons `401` dari `/v1/models` TIDAK berarti inferensi telah dilindungi. Lihat `docs/security/INFERENCE_AUTH_POSTURE.md` (#13695). |
| `ALLOW_API_KEY_REVEAL` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Memungkinkan nilai lengkap kunci API ditampilkan di UI Dasbor. Dapat dikonfigurasi melalui Flag Fitur Dasbor; berisiko terhadap keamanan pada instans bersama. |
| `NO_LOG_API_KEY_IDS` | _(kosong)_ | `src/lib/compliance/index.ts` | ID kunci API yang dipisahkan koma dan tidak dicatat dalam log permintaan (kepatuhan GDPR). |
| `DEFAULT_RATE_LIMIT_PER_DAY` | _(tidak ditetapkan = tanpa batas)_ | `src/shared/utils/apiKeyPolicy.ts` | Anggaran permintaan cadangan per hari yang diterapkan pada kunci API dengan kolom `rate_limits` bernilai null. Tidak ditetapkan atau kosong: tidak ada batas implisit (#2289, #11017). `0` memiliki arti yang sama (tanpa batas). Bilangan bulat positif N mengaktifkan N/hari, 5N/minggu, 20N/bulan. Nilai tidak kosong dengan format yang salah akan kembali menggunakan rentang lama, yaitu 1000/hari, 5000/minggu, dan 20000/bulan. |
| `MAX_BODY_SIZE_BYTES` | `10485760` (10 MB) | `src/shared/middleware/bodySizeGuard.ts` | Ukuran maksimum body permintaan yang diizinkan. Menolak payload yang melebihi batas ini. |
| `OMNIROUTE_CHAT_LARGE_BODY_BYTES` | `262144` (256 KB) | `src/shared/middleware/chatBodyAdmission.ts` | Body permintaan aktual yang mencapai atau melampaui ambang batas ini akan memperoleh lease penerimaan beban berat atomik yang bersifat lokal bagi proses sebelum parsing JSON (jalur BYTE, termasuk `POST /v1/responses`). Menggunakan mekanisme pelepasan ketika tersedia ruang kapasitas yang sehat dari [#10437](https://github.com/diegosouzapw/OmniRoute/pull/10437) yang sama dengan permintaan berstruktur berat; tetap dibatasi oleh `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` / [#10110](https://github.com/diegosouzapw/OmniRoute/issues/10110) agar masalah [#7849](https://github.com/diegosouzapw/OmniRoute/issues/7849) tidak muncul kembali. |
| `OMNIROUTE_CHAT_HARD_MAX_BODY_BYTES` | `52428800` (50 MB) | `src/shared/middleware/chatBodyAdmission.ts` | Batas maksimum absolut rute chat yang diberlakukan terhadap byte yang dibaca selama penyerapan terbatas, termasuk permintaan dengan `Content-Length` yang tidak ada, tidak valid, atau tidak sesuai kenyataan; kelebihan akan menerima `413`. |
| `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` | _(tidak disetel — tanpa batas jumlah permintaan)_ | `src/shared/middleware/chatBodyAdmission.ts` | **#503-fanout:** batas JUMLAH permintaan lama ini sekarang hanya berlaku jika disetel secara eksplisit. Jika tidak disetel (default), penerimaan chat kelas berat akan dibatasi oleh `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` — anggaran BYTE yang diturunkan secara otomatis berdasarkan batas memori nyata proses dalam **satu proses** (satu heap V8). Dua `/v1/responses` dengan ~750 ribu token yang bertumpang tindih menyebabkan heap ~12 GiB berhenti (#7849) — ini adalah peringatan **anggaran memori**, bukan batas maksimum produk yang bersifat absolut sebesar 2. Proses yang sehat (heap di bawah rasio pelepasan) DAPAT menerima lebih banyak `/v1/responses` panjang secara bersamaan melalui `OMNIROUTE_CHAT_ADMISSION_HEALTHY_HEADROOM`. Puluhan klien SSE berumur panjang (40–50) bergantung pada heap + `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` / #10110, bukan “maksimum 2”. Menaikkan nilai ini secara membabi buta untuk “menggunakan host” akan memunculkan kembali #7849. Gandakan **heap** dengan **N `DATA_DIR` independen** (#11024); jangan pernah menggunakan `replicas>1` pada satu file SQLite. |
| `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` | _(diturunkan secara otomatis)_ | `src/shared/middleware/admissionBudget.ts` | **#503-fanout:** penggantian untuk anggaran byte penyerapan yang diturunkan secara otomatis (25% dari batas memori V8/cgroup yang lebih ketat, dibagi dengan amplifikasi sementara 8x). Nilai turunan dan eksplisit dibatasi pada 8 MiB–2 GiB. Isi yang lebih besar daripada anggaran efektif akan langsung gagal dengan `413 body_exceeds_budget`; persaingan antara isi yang masing-masing dapat dilayani tetap dapat dicoba ulang dengan `503`. Kapasitas 40–50 klien SSE berumur panjang secara bersamaan bergantung pada anggaran ini + heap, bukan batas absolut “maksimum 2”. Baca `chatAdmission.maxInflightBytes` / `budgetSource` / `pressureSeverity` di `/api/monitoring/health` sebelum melakukan penyetelan. |
| `OMNIROUTE_CHAT_ADMISSION_HEAP_SHED_RATIO` | `0.75` | `src/shared/middleware/chatBodyAdmission.ts` | Rasio pelepasan akibat tekanan heap (`heapUsed / heap_size_limit`) untuk penerimaan kelas berat BYTE dan STRUCTURE (#10183, #10268, #10437). Permintaan kelas berat konkuren yang melampaui `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` hanya dilepas dengan `503` yang dapat dicoba ulang ketika heap JUGA berada pada atau di atas rasio ini; pada heap yang sehat, permintaan tersebut diterima melalui ruang cadangan sehat. |
| `OMNIROUTE_CHAT_ADMISSION_HEALTHY_HEADROOM` | `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` (default `1`) | `src/shared/middleware/chatBodyAdmission.ts` | Kapasitas tambahan terbatas untuk jalur cepat heap sehat (#10437) pada **keduanya**, STRUCTURE dan BYTE (`admitChatRequest`, termasuk isi ≥ `OMNIROUTE_CHAT_LARGE_BODY_BYTES`). Tanpa batas ini, setiap permintaan pada kondisi sibuk namun dengan heap sehat akan melewati kontrol penerimaan tanpa batas maksimum. Setelah permintaan konkuren sebanyak ini memiliki lease aktif melalui jalur heap sehat, permintaan sibuk berikutnya akan diteruskan ke jalur tunggu terbatas/pelepasan yang SAMA dengan jalur yang digunakan ketika terjadi tekanan heap nyata. `0` menonaktifkan mekanisme bypass sepenuhnya. |
| `OMNIROUTE_CHAT_HEAVY_MESSAGE_COUNT` | `200` | `src/shared/middleware/chatBodyAdmission.ts` | Jumlah pesan yang mengklasifikasikan permintaan chat sebagai kelas berat meskipun ukuran isinya berada di bawah ambang byte. |
| `OMNIROUTE_CHAT_HEAVY_TOOL_COUNT` | `64` | `src/shared/middleware/chatBodyAdmission.ts` | Jumlah alat yang mengklasifikasikan permintaan chat sebagai kelas berat meskipun ukuran isinya berada di bawah ambang byte. |
| `OMNIROUTE_CHAT_HEAVY_ESTIMATED_TOKENS` | `32000` | `src/shared/middleware/chatBodyAdmission.ts` | Perkiraan token konservatif berdasarkan ukuran string yang mengklasifikasikan permintaan sebagai kelas berat; ini merupakan proksi biaya penerimaan, bukan tokenisasi penagihan penyedia. |
| `OMNIROUTE_CHAT_HARD_MAX_MESSAGES` | `0` (dinonaktifkan) | `src/shared/middleware/chatBodyAdmission.ts` | Batas riwayat chat opsional yang harus diaktifkan secara eksplisit. Dinonaktifkan secara default: jumlah pesan adalah kebijakan deployment, bukan properti universal suatu permintaan, dan pembatasan di sini akan menolak percakapan dengan `413` terminal sebelum pipeline kompresi dapat membuatnya dapat dilayani. Pertumbuhan heap dibatasi oleh `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` dan pelepasan akibat tekanan heap. Tetapkan nilai positif pada deployment dengan memori terbatas yang memerlukan batas maksimum absolut; kelebihan kemudian akan menerima `413` terstruktur yang mengharuskan pemadatan. |
| `OMNIROUTE_MAX_NONSTREAMING_RESPONSE_BYTES` | `67108864` (64 MB) | `open-sse/handlers/chatCore/nonStreamingResponseBody.ts` | Batas maksimum absolut untuk respons upstream non-streaming yang disangga sepenuhnya ke dalam memori. Setelah batas ini terlampaui, pembaca upstream akan dibatalkan dan permintaan akan gagal dengan cepat, alih-alih terus memperbesar string tanpa batas hingga heap habis. |
| `OMNIROUTE_FORWARDING_HEADER_BUDGET_BYTES` | `768` | `open-sse/handlers/chatCore/responseHeaders.ts` | Jumlah maksimum byte jaringan yang diteruskan dari header respons upstream. Ketika anggaran terlampaui, header berprioritas lebih rendah (misalnya, `x-codex-*`, `x-oai-request-id`) akan dihapus agar tetap berada dalam batas header reverse proxy yang umum. Tetapkan nilai yang lebih tinggi untuk meneruskan lebih banyak metadata upstream dengan konsekuensi ukuran header respons yang lebih besar. |
| `CORS_ORIGIN` | _(tidak ditetapkan)_ | `src/server/cors/origins.ts` | Daftar izin CORS satu origin versi lama. Utamakan `CORS_ALLOWED_ORIGINS` untuk deployment baru. CORS hanya ditujukan bagi klien API browser lintas origin; penulisan dashboard terautentikasi menggunakan permintaan dari origin yang sama beserta perlindungan CSRF yang terikat pada sesi. |
| `CORS_ALLOWED_ORIGINS` | _(tidak ditetapkan)_ | `src/server/cors/origins.ts` | Daftar izin CORS yang dipisahkan koma. Wildcard tidak dikirim kecuali `CORS_ALLOW_ALL=true` dikonfigurasi secara eksplisit. |
| `CORS_ALLOW_ALL` | `false` | `src/server/cors/origins.ts` | Opsi darurat khusus pengembangan untuk menggemakan setiap `Origin` browser. Jangan aktifkan pada deployment bersama atau produksi. |
| `OUTBOUND_SSRF_GUARD_ENABLED` | `true` | `src/shared/network/outboundUrlGuard.ts` | Blokir panggilan penyedia yang menargetkan rentang IP privat/loopback/link-local. Nonaktifkan hanya di lingkungan pengujian yang terisolasi. |
| `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS` | `false` | `src/shared/network/outboundUrlGuard.ts` | Izinkan URL penyedia yang mengarah ke jaringan privat/lokal (localhost, 192.168.x.x, 10.x.x.x, dll.). **DIPERLUKAN untuk penyedia yang di-host sendiri** (LM Studio, Ollama, vLLM, Llamafile, Triton, SearXNG). Ketika `false`, dashboard menolak validasi URL lokal. |
| `OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` | `true` | `src/shared/network/outboundUrlGuard.ts` | Izinkan penambahan/validasi penyedia pada alamat lokal/privat (127.0.0.1, localhost, LAN, rentang privat) — dibatasi pada jalur validasi penyedia. **Default `true`** (mengutamakan lokal); tetapkan ke `false` untuk memberlakukan pemblokiran ketat khusus alamat publik. Endpoint metadata cloud (169.254.169.254, metadata.google.internal) tetap diblokir dalam kondisi apa pun. (#5066) |
| `AUDIO_REMOTE_PROVIDER_NODES` | `false` | `src/app/api/v1/_shared/audioProviderNodes.ts` | Izinkan rute `/v1/audio/*` (transkripsi, ucapan, terjemahan) menggunakan node penyedia yang kompatibel dengan OpenAI dan di-host di luar localhost. Dinonaktifkan secara default — merutekan audio ke host jarak jauh mengubah identitas egress dan harus menjadi keputusan operator yang eksplisit. Node loopback/privat (localhost, 127.0.0.1, 172.16-31.x) selalu diizinkan dan tidak terpengaruh. (#3963) |
| `RERANK_REMOTE_PROVIDER_NODES` | `false` | `src/app/api/v1/_shared/rerankProviderNodes.ts` | Izinkan `POST /v1/rerank` (serta langkah pemeringkatan ulang loopback milik mesin memori) menggunakan node penyedia yang kompatibel dengan OpenAI dan di-host di luar localhost — perangkat LAN atau peer Tailscale yang menjalankan TEI, Infinity, vLLM, dll. Dinonaktifkan secara default — merutekan ke host jarak jauh mengubah identitas egress dan harus menjadi keputusan operator yang eksplisit. Node loopback (localhost, 127.0.0.1, 172.16-31.x) selalu diizinkan dan tidak terpengaruh. Node jarak jauh juga harus lolos kebijakan URL outbound penyedia (`OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` / `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS`); host metadata cloud tidak pernah dijadikan tujuan perutean. |
| `OMNIROUTE_OIDC_DISABLE_PASSWORD_LOGIN` | `false` | `src/app/api/auth/login/route.ts` | Ketika OIDC diaktifkan, nonaktifkan login dengan kata sandi agar pengguna hanya dapat melakukan autentikasi melalui Single Sign-On OIDC. Alias dasar `OIDC_DISABLE_PASSWORD_LOGIN` juga diterima; Dashboard Feature Flag dengan kunci yang sama memiliki prioritas lebih tinggi. (#10889) |
| `OIDC_DISABLE_PASSWORD_LOGIN` | `false` | `src/app/api/auth/login/route.ts` | Alias dasar dari `OMNIROUTE_OIDC_DISABLE_PASSWORD_LOGIN` (#10889). |
### Daftar Periksa Penguatan Keamanan
```bash
# Keamanan minimum untuk produksi:
AUTH_COOKIE_SECURE=true # Memerlukan HTTPS
REQUIRE_API_KEY=true # Autentikasi semua panggilan proxy
ALLOW_API_KEY_REVEAL=false # Jangan pernah tampilkan kunci di UI
CORS_ALLOWED_ORIGINS=https://your.domain.com
MAX_BODY_SIZE_BYTES=5242880 # Batas 5 MB
```
---
## 5. Sanitasi Input & Perlindungan PII
OmniRoute menyediakan pertahanan dua lapis: pemindaian injeksi pada sisi permintaan dan penghapusan PII pada sisi respons.
> **⚠️ Keterbatasan:** Mekanisme pengaman ini merupakan deteksi heuristik _upaya terbaik_, bukan firewall injeksi prompt atau sistem DLP PII yang lengkap. Mekanisme ini dapat menghasilkan positif palsu (prompt persona/RPG yang aman ditandai) dan negatif palsu (leetspeak, spasi, pola non-Inggris). Mekanisme ini saja tidak cukup untuk kepatuhan. Sesuaikan mode dan uji terhadap lalu lintas Anda sebelum mengandalkannya.
### Sisi Permintaan: Pengaman Injeksi Prompt
| Variabel | Bawaan | File Sumber | Deskripsi |
| --------------------------------- | ----------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `INPUT_SANITIZER_ENABLED` | `true` | `src/middleware/promptInjectionGuard.ts` | Aktifkan pemindaian pesan masuk untuk mendeteksi pola injeksi prompt. |
| `INPUT_SANITIZER_MODE` | `warn` | `src/middleware/promptInjectionGuard.ts` | Kebijakan injeksi: `warn` = hanya catat, `block` = tolak permintaan dengan 400. `redact` lama **tidak** menghapus teks injeksi; gunakan `PII_REDACTION_ENABLED` untuk penulisan ulang PII permintaan. |
| `INJECTION_GUARD_MODE` | _(tidak disetel)_ | `src/middleware/promptInjectionGuard.ts` | Alias lama untuk `INPUT_SANITIZER_MODE` — perilaku yang sama. |
| `INPUT_SANITIZER_BLOCK_THRESHOLD` | `high` | `src/shared/utils/injectionSeverity.ts` | Tingkat keparahan minimum yang ditolak oleh `MODE=block`: `high` (bawaan), `medium`, atau `low`. Pola tingkat medium hanya diamati kecuali ambang batas diturunkan. |
| `INJECTION_GUARD_BLOCK_THRESHOLD` | _(tidak disetel)_ | `src/shared/utils/injectionSeverity.ts` | Alias lama untuk `INPUT_SANITIZER_BLOCK_THRESHOLD` — perilaku yang sama. |
| `PII_REDACTION_ENABLED` | `false` | `src/lib/guardrails/piiMasker.ts` | Jika `true`, samarkan PII dalam permintaan masuk (terlepas dari mode injeksi). |
| `CREDENTIAL_REDACTION_ENABLED` | `false` | `src/lib/guardrails/credentialMasker.ts` | Samarkan pola kunci API/token rahasia yang umum dikenal dari payload permintaan/respons. Harus diaktifkan secara eksplisit; mengikuti `PII_REDACTION_ENABLED`. |
### Sisi Respons: Sanitizer PII
| Variabel | Bawaan | File Sumber | Deskripsi |
| -------------------------------- | -------- | ------------------------- | ------------------------------------------------------------------------------------- |
| `PII_RESPONSE_SANITIZATION` | `false` | `src/lib/piiSanitizer.ts` | Pindai respons LLM untuk mendeteksi PII yang bocor sebelum dikembalikan kepada klien. |
| `PII_RESPONSE_SANITIZATION_MODE` | `redact` | `src/lib/piiSanitizer.ts` | `redact` = samarkan PII, `warn` = hanya catat, `block` = hapus seluruh respons. |
### Sanitizer Konteks Rute Bertoken VS Code
| Variabel | Bawaan | File Sumber | Deskripsi |
| ----------------------------------- | ------ | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OMNIROUTE_VSCODE_SANITIZE_CONTEXT` | `1` | `src/app/api/v1/vscode/contextSanitizer.ts` | Menghapus konteks editor aktif implisit (`editorContext`, `activeEditor`, `currentFile`, `selection`, `openTabs`…) dari permintaan `/v1/vscode/[token]/*` dan menyamarkan konten file sensitif yang dilampirkan secara eksplisit. Aman secara bawaan; setel ke `0` untuk menonaktifkannya. |
### Skenario
| Skenario | Konfigurasi |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Kepatuhan perusahaan** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=block`, `PII_REDACTION_ENABLED=true`, `PII_RESPONSE_SANITIZATION=true` (injeksi diblokir + penyamaran PII permintaan/respons; setiap mode bersifat independen) |
| **Hanya pemantauan** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=warn` — mencatat tetapi tidak pernah memblokir |
| **Penggunaan pribadi** | Biarkan semuanya dinonaktifkan — tanpa overhead |
---
## 6. Kebijakan Alat & Perutean
| Variabel | Default | File Sumber | Deskripsi |
| ----------------------------------------------------------- | ----------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `TOOL_POLICY_MODE` | `disabled` | `src/lib/toolPolicy.ts` | Mengontrol akses pemanggilan alat/fungsi LLM. `allowlist` = hanya alat yang tercantum, `denylist` = semua kecuali yang tercantum, `disabled` = tanpa pembatasan. |
| `OMNIROUTE_PAYLOAD_RULES_PATH` | `./config/payloadRules.json` | `open-sse/services/payloadRules.ts` | Jalur ke file JSON aturan manipulasi payload (penyesuaian upstream per model/protokol). |
| `OMNIROUTE_PAYLOAD_RULES_RELOAD_MS` | `5000` | `open-sse/services/payloadRules.ts` | Interval pemuatan ulang (ms) untuk memuat ulang file aturan payload secara dinamis. Minimum `1000`. |
| `OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS` | `false` | `open-sse/services/model.ts` | Pilihan opsional: merutekan ID model `claude-*` tanpa prefiks dari klien Claude Code melalui akun OAuth Claude Code alih-alih mewajibkan prefiks penyedia. Prefiks penyedia eksplisit tetap diprioritaskan. Juga dapat dikonfigurasi melalui tombol alih dasbor di halaman penyedia Claude. |
| `COMBO_CONCURRENCY_PER_MODEL` | `3` | `open-sse/services/comboConfig.ts` | Batas konkurensi per model untuk kombinasi round-robin (#9100). Semaphore kombinasi round-robin sebelumnya dibatasi secara tetap hingga 3 permintaan bersamaan per model tanpa opsi penggantian, sehingga lalu lintas dengan konkurensi lebih tinggi diserialkan di belakang batas tersebut. Divalidasi ke `>= 1`, dibatasi hingga `<= 32`. |
| `DISABLE_CONTEXT_WINDOW_CHECKS` | `false` | `open-sse/handlers/chatCore.ts` | Pilihan opsional berbahaya yang melewati pemeriksaan lokal OmniRoute atas jendela konteks/token input maksimum untuk permintaan langsung ke satu model. Penyedia upstream tetap memberlakukan batas aktual mereka; kompresi prompt dan batas token output model tetap aktif. Urutan prioritas efektif adalah penggantian DB Feature Flags > variabel lingkungan > default; mulai ulang tidak diperlukan. |
| `OMNIROUTE_SELF_HOSTED_PROVIDERS` | _(tidak ditetapkan)_ | `open-sse/services/selfHostedEntry.ts` | Dokumen YAML `providers:` inline (RIC-738, D4). Saat ditetapkan (dengan atau tanpa blok `strategy:`), `/v1/chat/completions` dialihkan ke entri terpadu yang di-host sendiri dan kompatibel dengan OpenAI, bukan ke pipeline cloud. Jika tidak ditetapkan (default): rute diteruskan langsung ke pipeline cloud yang ada. Lihat `docs/routing/SELF_HOSTED_OPENAI_ENTRY.md`. |
| `OMNIROUTE_SELF_HOSTED_PROVIDERS_FILE` | _(tidak ditetapkan)_ | `open-sse/services/selfHostedEntry.ts` | Jalur ke file YAML yang berisi dokumen `providers:` yang sama dengan `OMNIROUTE_SELF_HOSTED_PROVIDERS`, untuk deployment yang lebih memilih file daripada variabel lingkungan inline. Salah satunya akan mengaktifkan entri yang di-host sendiri. |
| `OMNIROUTE_SELF_HOSTED_API_KEY` | _(tidak ditetapkan — rute terbuka)_ | `open-sse/services/selfHostedEntry.ts` | Kunci API bersama opsional untuk entri terpadu yang di-host sendiri (kerangka D5, dicadangkan untuk sistem kuota per kunci). Saat ditetapkan, permintaan harus menyertakan `Authorization: Bearer `. Jika tidak ditetapkan: rute terbuka, sesuai dengan pola penyedia lokal yang di-host sendiri saat ini (deployment loopback/jaringan tepercaya). |
| `OMNIROUTE_SELF_HOSTED_STRATEGY` | _(tidak ditetapkan)_ | `open-sse/services/routingStrategies.ts` | Dokumen YAML `strategy:` inline untuk mesin perutean deterministik (M2/RIC-740, D3) — daftar hitam/daftar putih, pemutus cooldown, prioritas biaya, sadar latensi, rantai fallback. Menggantikan blok `strategy:` inline yang disarangkan di dalam `OMNIROUTE_SELF_HOSTED_PROVIDERS`, per kunci. Lihat `docs/routing/DETERMINISTIC_ROUTING.md`. |
| `OMNIROUTE_SELF_HOSTED_STRATEGY_FILE` | _(tidak ditetapkan)_ | `open-sse/services/routingStrategies.ts` | Jalur ke file YAML yang berisi dokumen `strategy:` yang sama dengan `OMNIROUTE_SELF_HOSTED_STRATEGY`, untuk deployment yang lebih memilih file daripada variabel lingkungan inline. |
| `OMNIROUTE_DISABLE_CONVERSATION_TRACKING` | _(tidak disetel)_ | `open-sse/services/conversationTracker.ts` | Atur ke `1` untuk berhenti mengumpulkan riwayat percakapan. `resolveConversationId()` mengembalikan hasil yang tidak dilacak sebelum membaca SQLite atau mengurai riwayat pesan, dan ID sesi yang diberikan klien juga tercakup. Penanganan sesi perutean tidak berubah dan catatan yang ada tidak dihapus. Ditujukan untuk deployment yang tidak menggunakan tampilan percakapan dasbor dan ingin menghentikan pertumbuhan tabel giliran. |
---
## 7. URL & Sinkronisasi Cloud
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------------------------- | ------------------------------------------------------ | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BASE_URL` | `http://localhost:20128` | `src/lib/cloudSync.ts` | URL sisi server yang digunakan oleh tugas sinkronisasi internal untuk memanggil `/api/sync/cloud`. Pertahankan sebagai URL loopback/container meskipun aplikasi diproksi secara publik. |
| `CLOUD_URL` | _(kosong)_ | `src/lib/cloudSync.ts` | URL endpoint relai cloud (fitur premium). |
| `CLOUD_SYNC_TIMEOUT_MS` | `12000` | `src/lib/cloudSync.ts` | Batas waktu HTTP untuk permintaan sinkronisasi cloud. |
| `OMNIROUTE_BUILD_PROFILE` | `full` | Konfigurasi build Webpack | Profil waktu build (atur ke `minimal` untuk mengecualikan modul berhak istimewa secara fisik dari bundle). |
| `OMNIROUTE_STANDALONE_DIR` | _output standalone .build/_ | `scripts/build/colocate-standalone.mjs` | Penggantian waktu build untuk direktori output standalone yang digunakan oleh langkah kolokasi pasca-build. Bukan pengaturan runtime. |
| `OMNIROUTE_CLOUD_SYNC_SECRET` | _(kosong)_ | `src/lib/cloudSync.ts` | Secret bersama yang digunakan untuk memverifikasi tanda tangan HMAC-SHA256 dari respons Sinkronisasi Cloud. |
| `OMNIROUTE_CLOUD_SYNC_SECRETS` | `false` | `src/lib/cloudSync.ts` | Atur ke `true` agar endpoint Sinkronisasi Cloud dapat menimpa kredensial lokal. Default-nya adalah `false`. |
| `OMNIROUTE_CLOUD_SYNC_ENFORCE_SIGNATURE` | `false` | `src/lib/cloudSync.ts` | Atur ke `true` untuk menolak respons Sinkronisasi Cloud yang tidak ditandatangani ketika tidak ada secret lokal yang dikonfigurasi (#13679). Tanda tangan yang tersedia selalu diverifikasi — dan selalu ditolak ketika `OMNIROUTE_CLOUD_SYNC_SECRET` tidak diatur — terlepas dari flag ini. Default berubah menjadi wajib diterapkan pada v3.9. |
| `OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP` | `false` | `src/app/api/providers/zed/import/route.ts` | Atur ke `true` untuk kembali ke perilaku satu langkah "impor semuanya" v3.8.5 tanpa konfirmasi pengguna. |
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | OAuth, Dasbor, sinkronisasi | URL yang menghadap publik untuk OAuth redirect_uri, tautan Dasbor, dan URL publik yang dihasilkan. Atur ke URL publik yang stabil ketika callback OAuth atau tautan browser yang dihasilkan harus menggunakan host reverse-proxy kanonis. |
| `NEXT_PUBLIC_CLOUD_URL` | _(kosong)_ | Sisi klien | Cerminan sisi klien dari `CLOUD_URL`. |
| `NEXT_PUBLIC_APP_URL` | _(tidak diatur)_ | `src/shared/services/cloudSyncScheduler.ts` | Fallback lama untuk `NEXT_PUBLIC_BASE_URL`. |
| `NEXT_PUBLIC_PORT` | _(tidak diatur — menggunakan `PORT` sebagai fallback)_ | `src/shared/hooks/useDisplayBaseUrl.ts` | Port fallback sisi klien untuk URL tampilan saat origin tidak diketahui (SSR/pengujian); dibaca sebelum `PORT`. |
| `OMNIROUTE_PUBLIC_BASE_URL` | _(tidak diatur)_ | Resolver origin publik, URL gambar | Origin OmniRoute yang dapat diakses browser dengan prioritas tertinggi, digunakan untuk pembuatan URL publik dan validasi origin browser non-dasbor. Atur ini ketika OpenWebUI atau relay lain mengakses OmniRoute melalui URL internal, tetapi browser pengguna harus mengambil media yang dihasilkan dari LAN, tunnel, atau origin publik. **Jangan** sertakan `/v1`. |
| `OMNIROUTE_PROVIDER_MANIFEST_URL` | _(tidak diatur)_ | `open-sse/config/providerPluginManifestUrl.ts` | URL absolut manifes plugin penyedia yang diumumkan kepada klien sidecar. Jika tidak diatur, OmniRoute memperoleh `/api/v1/provider-plugin-manifest` dari origin permintaan atau HOST/PORT. |
| `OMNIROUTE_PUBLIC_PROTOCOL` | `http` | `open-sse/config/providerPluginManifestUrl.ts` | Protokol yang digunakan saat memperoleh URL manifes plugin penyedia dari HOST/PORT tanpa origin permintaan. Atur ke `https` di belakang proksi publik yang mengakhiri TLS saat `OMNIROUTE_PROVIDER_MANIFEST_URL` eksplisit tidak diatur. |
| `OMNIROUTE_TRUST_PROXY` | _(tidak diatur)_ | `src/server/origin/publicOrigin.ts` | Mode kepercayaan opsional untuk header origin publik yang diteruskan. Tidak diatur = jangan percayai `Forwarded` / `X-Forwarded-*` untuk keputusan keamanan. `true` / `loopback` memercayai host/protokol yang diteruskan hanya dari proksi loopback yang diberi token. `private` / `lan` juga memercayai peer proksi LAN privat. Sebaiknya gunakan `NEXT_PUBLIC_BASE_URL` eksplisit dalam produksi. |
| `KIE_CALLBACK_URL` | _(tidak diatur)_ | `open-sse/utils/kieTask.ts` | URL callback publik untuk tugas kie.ai asinkron. Penggantian dengan prioritas tertinggi sebelum `OMNIROUTE_KIE_CALLBACK_URL` dan `OMNIROUTE_PUBLIC_URL`. |
| `OMNIROUTE_KIE_CALLBACK_URL` | _(tidak diatur)_ | `open-sse/utils/kieTask.ts` | Penamaan alternatif untuk `KIE_CALLBACK_URL`. Digunakan sebagai fallback ketika variabel utama tidak diatur. |
| `OMNIROUTE_PUBLIC_URL` | _(tidak diatur)_ | `open-sse/utils/kieTask.ts` | Origin publik yang digunakan untuk menyusun URL callback asinkron. Fallback dengan prioritas terendah untuk callback kie.ai; juga digunakan sebagai URL publik generik untuk relay lainnya. |
| `OMNIROUTE_CROF_USAGE_URL` | `https://crof.ai/usage_api/` | `open-sse/services/usage.ts` | Endpoint pencarian kuota CrofAI yang digunakan oleh halaman Penggunaan. Ganti untuk relay / fixture pengujian. |
| `OMNIROUTE_OPENCODE_QUOTA_URL` | `https://opencode.ai/zen/go/v1/usage` | `open-sse/services/opencodeQuotaFetcher.ts` | Endpoint penggunaan resmi OpenCode Go yang diautentikasi dengan kunci API dan digunakan oleh halaman Penggunaan. Ganti untuk relay / fixture pengujian. |
| `OPENCODE_SYNTHESIZE_CLI_HEADERS` | `true` | `open-sse/executors/opencode.ts` | Buat header identitas OpenCode CLI sintetis (User-Agent, x-opencode-client/project, UUID permintaan/sesi) pada permintaan upstream opencode-go/zen yang tidak dikirim oleh klien, sehingga Cloudflare pada egress VPS menerimanya (#6210/#5997). Aktif secara default sejak #10571; nonaktifkan dengan `false`/`0`/`no`/`off`. |
| `OPENCODE_USER_AGENT` | `opencode/1.18.31` | `open-sse/utils/opencodeHeaders.ts` | User-Agent default yang digunakan saat `OPENCODE_SYNTHESIZE_CLI_HEADERS` aktif dan tidak ada penggantian `_USER_AGENT` per penyedia yang diatur. Hanya diterapkan pada eksekutor opencode. Pada permintaan tanpa kunci yang dibatasi oleh upstream, nilai terkonfigurasi yang tidak memuat `opencode/= 1.17>` akan diganti dengan default ini alih-alih ditolak. |
| `OPENCODE_CLIENT` | `desktop` | `open-sse/executors/opencode.ts` | Nilai untuk header `x-opencode-client` yang disintesis saat `OPENCODE_SYNTHESIZE_CLI_HEADERS` aktif. |
| `OPENCODE_PROJECT` | `global` | `open-sse/executors/opencode.ts` | Nilai untuk header `x-opencode-project` yang disintesis saat `OPENCODE_SYNTHESIZE_CLI_HEADERS` aktif. |
| `OPENCODE_FREE_TIER_REQUEST_CONTRACT` | _(tidak disetel)_ | `open-sse/executors/opencodeFreeTierContract.ts` | Atur ke `off` untuk menghentikan penyesuaian isi permintaan OpenCode tanpa kunci (flag streaming dan daftar alat). Header tetap diterapkan. Dibaca pada setiap permintaan, sehingga perubahan langsung berlaku. |
| `OPENCODE_FREE_TIER_PLACEHOLDER_TOOLS` | _(tidak disetel)_ | `open-sse/executors/opencodeFreeTierContract.ts` | Nama alat yang dipisahkan koma untuk dideklarasikan pada permintaan OpenCode tanpa kunci yang tidak menyertakan alat apa pun, ketika belum ada yang diamati untuk model tersebut. Jika kosong, kembali menggunakan satu placeholder yang diberi tahu kepada model agar tidak dipanggil. Maksimal 32 entri, `[A-Za-z_][A-Za-z0-9_-]{0,63}`; entri yang tidak valid akan diabaikan. |
| `OMNIROUTE_OLLAMA_CLOUD_USAGE_URL` | `https://ollama.com/settings` | `open-sse/services/usage.ts` | URL pengaturan Ollama Cloud yang digunakan untuk mengambil data kuota. Timpa untuk relay / fixture pengujian. |
| `OLLAMA_USAGE_COOKIE` | _(tidak disetel)_ | `open-sse/services/usage.ts` | Cookie `__Secure-session` Ollama Cloud yang digunakan untuk mengambil data kuota dari halaman pengaturan. Sensitif; lebih baik gunakan bidang Dashboard per koneksi saat beberapa akun dikonfigurasi. |
| `OLLAMA_CLOUD_USAGE_COOKIE` | _(tidak disetel)_ | `open-sse/services/usage.ts` | Variabel lingkungan alternatif untuk cookie `__Secure-session` Ollama Cloud. Sensitif; lebih baik gunakan bidang Dashboard per koneksi saat beberapa akun dikonfigurasi. |
| `OMNIROUTE_OLLAMA_USAGE_COOKIE` | _(tidak disetel)_ | `open-sse/services/usage.ts` | Variabel lingkungan alternatif untuk cookie `__Secure-session` Ollama Cloud yang digunakan sebelum alias yang lebih pendek. Sensitif; lebih baik gunakan bidang Dashboard per koneksi saat beberapa akun dikonfigurasi. |
| `OMNIROUTE_CODEWHISPERER_BASE_URL` | `https://codewhisperer.us-east-1.amazonaws.com` | `open-sse/services/usage.ts` | Endpoint batas penggunaan CodeWhisperer (AWS Kiro). Timpa untuk relay / fixture pengujian. |
> [!IMPORTANT]
> Saat menerapkan di belakang reverse proxy (nginx, Caddy), atur `NEXT_PUBLIC_BASE_URL` ke URL publik stabil Anda (misalnya, `https://omniroute.example.com`) jika callback OAuth atau tautan publik yang dihasilkan harus menggunakan nama host tersebut. Tanpa ini, callback OAuth dapat gagal karena redirect_uri tidak cocok dan tautan publik yang dihasilkan dapat mengarah ke origin kontainer internal.
>
> Pertahankan `BASE_URL` sebagai URL loopback/kontainer internal untuk pekerjaan antarpeladen. Jangan gunakan `Origin` browser atau nama host publik untuk pengambilan mandiri internal yang menyertakan kredensial.
>
> Penulisan dashboard yang diautentikasi tidak memerlukan URL dasar publik statis: dashboard mengirim permintaan tidak aman dengan origin yang sama menggunakan token CSRF yang terikat ke sesi. OmniRoute tetap memusatkan validasi origin publik untuk integrasi browser non-dashboard: variabel lingkungan URL publik eksplisit dipercaya terlebih dahulu; header mentah `Forwarded` / `X-Forwarded-*` diabaikan kecuali `OMNIROUTE_TRUST_PROXY` diaktifkan dan peer proxy langsung diberi penanda token sebagai tepercaya. Jangan gunakan pengaturan CORS untuk memperbaiki permintaan dashboard dengan origin yang sama; CORS hanya untuk klien browser lintas origin.
---
## 8. Proksi Keluar
Rutekan panggilan ke penyedia LLM upstream melalui proksi HTTP atau SOCKS5 untuk kontrol lalu lintas keluar, perutean geografis, atau penyamaran IP.
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------------------------- | ---------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ENABLE_SOCKS5_PROXY` | `true` | `open-sse/executors` | Aktifkan agen proksi SOCKS5 untuk panggilan upstream. Nonaktifkan dengan `false`. |
| `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` | `true` | Sisi klien | Kesadaran sisi klien terhadap ketersediaan SOCKS5. |
| `PROXY_SKIP_RECENTLY_FAILED` | `false` | `src/shared/utils/featureFlags.ts` | Flag fitur yang harus diaktifkan secara eksplisit (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); penggantian dari DB dasbor lebih diutamakan). Pool proksi dan rotasi per akun berhenti menyajikan kembali anggota yang baru saja gagal (probe TCP ditolak atau menerima 429 saat melaluinya) selama periode yang berlipat ganda pada setiap kegagalan berulang, hingga batas maksimum. `true` (atau `1`, `yes`) mengaktifkannya. |
| `HTTP_PROXY` | _(tidak diatur)_ | Standar Node.js | Proksi HTTP untuk panggilan upstream. |
| `HTTPS_PROXY` | _(tidak diatur)_ | Standar Node.js | Proksi HTTPS untuk panggilan upstream. |
| `ALL_PROXY` | _(tidak diatur)_ | Standar Node.js | Proksi universal (mendukung `socks5://`). |
| `OMNIROUTE_PROXY_ECHO_URL` | _(tidak diatur)_ | `src/lib/proxyEchoTarget.ts` | Menetapkan target gema-IP yang digunakan oleh probe lalu lintas keluar proksi ke satu URL. Jika tidak diatur, probe mencoba `api64.ipify.org`, lalu `api4.ipify.org`, agar tunnel khusus IPv4 tidak dilaporkan mati (#9694). |
| `NO_PROXY` | _(tidak diatur)_ | Standar Node.js | Nama host/IP yang dipisahkan koma untuk melewati proksi. |
| `OMNIROUTE_PROXY_DISPATCHER_CONNECTIONS` | `32` | `open-sse/utils/proxyDispatcher.ts` | Jumlah maksimum soket bersamaan per dispatcher proksi HTTP/SOCKS yang di-cache. Stream SSE berumur panjang seperti Codex `/v1/responses` memerlukan lebih dari satu koneksi ketika beberapa permintaan menggunakan proksi tingkat akun yang sama. Nilai di atas `256` dibatasi. |
| `SOCKS_HANDSHAKE_TIMEOUT_MS` | `10000` | `open-sse/utils/socksConnectorWithFamily.ts` | Batas waktu handshake (koneksi) SOCKS5 dalam ms. Naikkan ketika satu host gateway residensial menerima konkurensi tinggi (misalnya 100 permintaan secara bersamaan) — handshake yang sebenarnya dapat melebihi 10 detik saat pool jenuh meskipun proksi dapat dijangkau, yang jika tidak dilakukan akan muncul sebagai `[Proxy Fast-Fail] Proxy unreachable` palsu. Dibatasi hingga `120000`. |
| `PROXY_FAIL_OPEN` | `false` | `src/sse/handlers/chatHelpers.ts` | Jika `false` (default), permintaan yang proksi tetapan untuknya gagal di-resolve akan **ditolak (fail-closed)** alih-alih beralih kembali ke koneksi langsung — mencegah kebocoran IP asli. Atur ke `true` untuk memulihkan fallback DIRECT lama. |
| `ENABLE_TLS_FINGERPRINT` | `false` | `open-sse/executors` | Memalsukan fingerprint TLS menggunakan wreq-js (meniru Chrome 124). Mengatasi pemblokiran JA3/JA4. |
| `TLS_FINGERPRINT_PROVIDERS` | _(tidak diatur)_ | `open-sse/utils/proxyFetch.ts` | Daftar izin penyedia yang dipisahkan koma untuk perutean TLS berproksi yang baru (`open-sse/utils/proxyFetch.ts`). TLS langsung mempertahankan perilaku lamanya saat tidak diatur; hanya penyedia ini yang dirutekan melalui jembatan fingerprint Chrome-124. |
| `OMNIROUTE_TURNSTILE_IGNORE_TLS_ERRORS` | `false` | `open-sse/services/claudeTurnstileSolver.ts` | Mengizinkan konteks browser Playwright Claude Turnstile untuk mengabaikan kesalahan sertifikat HTTPS. |
### Skenario
| Skenario | Konfigurasi |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **SOCKS5 melalui tunnel SSH** | `ALL_PROXY=socks5://127.0.0.1:7890`, `ENABLE_SOCKS5_PROXY=true` |
| **Proksi HTTP perusahaan** | `HTTP_PROXY=http://proxy.corp.com:3128`, `HTTPS_PROXY=http://proxy.corp.com:3128`, `NO_PROXY=localhost,internal.corp.com` |
| **Anti-fingerprint** | `ENABLE_TLS_FINGERPRINT=true` — memerlukan `wreq-js` (disertakan) |
| **Egress terkendali / tanpa akses langsung** | Biarkan `PROXY_FAIL_OPEN=false` (default). Permintaan langsung gagal saat proksi tidak tersedia alih-alih bocor melalui koneksi langsung. |
| **Lama / pengembangan — izinkan fallback langsung** | `PROXY_FAIL_OPEN=true`. Memulihkan perilaku sebelum hardening: koneksi langsung digunakan saat resolusi proksi gagal. |
> **Catatan (bypass validasi NVIDIA — #3226):** Endpoint validasi kunci API NVIDIA
> macet saat dirutekan melalui fetch global yang telah ditambal untuk proksi/TLS (dispatcher undici → 504).
> `src/lib/providers/validation.ts::directHttpsRequest()` secara sengaja melewati
> tambalan proksi untuk satu panggilan validasi tersebut menggunakan `safeOutboundFetch({ bypassProxyPatch: true })`.
> Ini adalah pengecualian terbatas yang terdokumentasi — hal ini **tidak** memengaruhi egress chat/penggunaan.
> Cakupan bypass dikunci oleh `tests/unit/proxy-bypass-scope-guard-3226.test.ts`.
---
## 9. Integrasi Alat CLI
Mengontrol cara OmniRoute menemukan dan menjalankan sidecar CLI (Claude Code, Codex, dll.).
| Variabel | Default | File Sumber | Deskripsi |
| --------------------------------- | -------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLI_MODE` | `auto` | `src/shared/services/cliRuntime.ts` | `auto` = cari di PATH sistem; `manual` = hanya gunakan path eksplisit. |
| `CLI_EXTRA_PATHS` | _(tidak diatur)_ | `src/shared/services/cliRuntime.ts` | Entri PATH tambahan untuk menemukan biner CLI (dipisahkan dengan titik dua). |
| `CLI_CONFIG_HOME` | _(tidak diatur)_ | `src/shared/services/cliRuntime.ts` | Timpa direktori home untuk membaca konfigurasi CLI (`~/.claude`, `~/.codex`). Harus berupa path absolut dan berada di dalam home proses — **atau**, dalam container, berupa path yang di-bind mount (begitulah cara kerja `/host-home`). Selain itu, akan kembali menggunakan direktori home. |
| `CLI_ALLOW_CONFIG_WRITES` | `true` | `src/shared/services/cliRuntime.ts` | Izinkan OmniRoute menulis file konfigurasi CLI (penyegaran token, data sesi). Atur ke `false` agar setiap penulisan konfigurasi CLI gagal dengan galat eksplisit "penulisan dinonaktifkan". |
| `CLI_CLAUDE_BIN` | `claude` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Claude CLI. |
| `CLI_CODEX_BIN` | `codex` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Codex CLI. |
| `CLI_DROID_BIN` | `droid` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Droid CLI. |
| `CLI_OPENCLAW_BIN` | `openclaw` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner OpenClaw CLI. |
| `CLI_CURSOR_BIN` | `agent`, lalu `cursor` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner agen Cursor. Tanpa path tersebut, pendeteksian akan mencoba `agent` terlebih dahulu, lalu beralih ke `cursor`. |
| `CLI_CLINE_BIN` | `cline` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Cline CLI. |
| `CLI_5DIVE_BIN` | `5dive` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner 5dive CLI. |
| `CLI_5DIVE_STATE_DIR` | `/var/lib/5dive` | `src/shared/services/cliRuntime.ts` | Direktori status sistem 5dive (profil autentikasi milik root); mengikuti default STATE_DIR milik 5dive. |
| `CLI_CONTINUE_BIN` | `cn` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Continue CLI. |
| `CLI_QODER_BIN` | `qodercli` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Qoder CLI. |
| `CLI_QWEN_BIN` | `qwen` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Qwen Code CLI. |
| `CLI_AIDER_BIN` | `aider` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Aider CLI. |
| `CLI_GOOSE_BIN` | `goose` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Goose CLI. |
| `CLI_GEMINI_BIN` | `gemini` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Google Gemini CLI — hanya untuk pendeteksian/pemeriksaan kesehatan di sisi server; `omniroute run gemini` menemukan biner `gemini` dari PATH sistem. |
| `CLI_KILO_BIN` | `kilocode` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner Kilo Code CLI. |
| `CLI_OPENCODE_BIN` | `opencode` | `src/shared/services/cliRuntime.ts` | Path khusus ke biner OpenCode CLI. |
| `CLI_HERMES_BIN` | `hermes` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner Hermes. Digunakan bersama oleh kedua entri katalog (`hermes` dan `hermes-agent`). |
| `CLI_FORGE_BIN` | `forge` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner CLI ForgeCode. |
| `CLI_JCODE_BIN` | `jcode` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner CLI jcode. |
| `CLI_DEEPSEEK_TUI_BIN` | `deepseek-tui` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner TUI DeepSeek. |
| `CLI_CODEWHALE_BIN` | `codewhale` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner CLI CodeWhale. |
| `CLI_SMELT_BIN` | `smelt` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner CLI Smelt. |
| `CLI_PI_BIN` | `pi` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner Pi (pi-coding-agent). |
| `CLI_CRUSH_BIN` | `crush` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner CLI Crush. |
| `CLI_OMP_BIN` | `omp` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner agen Oh My Pi (`omp`). |
| `CLI_LETTA_BIN` | `letta` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner CLI Letta. |
| `CLI_PRIME_AGENT_BIN` | `prime-agent` | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner Prime Agent (Prime Intellect). |
| `CLI_WINDSURF_BIN` | _(tidak ada)_ | `src/shared/services/cliRuntime.ts` | Jalur khusus ke biner Windsurf. Windsurf **tidak menyediakan perintah default** — deteksi biner tetap dinonaktifkan hingga variabel ini ditetapkan. |
| `CLI_DEVIN_BIN` | `devin` | `open-sse/executors/devin-cli.ts` | Jalur khusus ke biner CLI Devin (v3.8.0). Digunakan oleh eksekutor Windsurf/Devin. |
| `DEVIN_DESKTOP_VERSION` | `3.6.27` | `open-sse/executors/devin-desktop.ts` | `ide_version` Devin Desktop. Nilai pengganti harus menggunakan format `x.y.z`; nilai yang tidak valid akan kembali ke nilai default yang telah diverifikasi. |
| `DEVIN_DESKTOP_EXTENSION_VERSION` | `1.48.2` | `open-sse/executors/devin-desktop.ts` | `extension_version` Codeium/server bahasa yang disertakan, berbeda dari `ide_version` Desktop. Nilai pengganti harus menggunakan `x.y.z`; nilai yang tidak valid akan menggunakan nilai default yang disertakan. |
| `CLI_DEVIN_AGENTIC_BIN` | `devin` | `open-sse/executors/devin-cli-agentic.ts` | Penggantian CLI Devin khusus bridge agentik. Eksekutor hanya menerima upstream stdio ACP lokal. |
| `DEVIN_AGENTIC_HOME` | _(wajib)_ | `open-sse/executors/devin-cli-agentic.ts` | Direktori home terisolasi absolut untuk subproses Devin agentik; jalur bridge yang diterima adalah `/home/bridge` dan jalur `.sandbox` lokal tugas (di Windows, `C:\...\.sandbox\...`). |
| `DEVIN_AGENTIC_ACP_TIMEOUT_MS` | `120000` | `open-sse/executors/devin-cli-agentic.ts` | Durasi maksimum satu giliran ACP Devin sebelum bridge menghentikan proses anak dan mengembalikan timeout eksplisit. |
| `DEVIN_BRIDGE_MODEL` | `devin-cli-agentic/swe-1-7` | `docker/devin-bridge/compose.yml` | Alias model utama Claude Code untuk bridge terisolasi. Harness langsung mengganti contoh tersebut dengan model yang dikembalikan oleh akun Devin saat ini. |
| `DEVIN_BRIDGE_SONNET_MODEL` | `DEVIN_BRIDGE_MODEL` | `docker/devin-bridge/compose.yml` | Alias bridge terisolasi yang digunakan saat Claude Code meminta default Sonnet-nya. |
| `DEVIN_BRIDGE_OPUS_MODEL` | `DEVIN_BRIDGE_MODEL` | `docker/devin-bridge/compose.yml` | Alias bridge terisolasi yang digunakan saat Claude Code meminta default Opus-nya. |
| `DEVIN_BRIDGE_HAIKU_MODEL` | `DEVIN_BRIDGE_MODEL` | `docker/devin-bridge/compose.yml` | Alias bridge terisolasi yang digunakan saat Claude Code meminta default Haiku-nya. |
| `DEVIN_BRIDGE_SUBAGENT_MODEL` | `DEVIN_BRIDGE_MODEL` | `docker/devin-bridge/compose.yml` | Alias bridge terisolasi yang digunakan untuk subagen Claude Code. |
| `DEVIN_SEAT_API_URL` | `https://server.codeium.com` | `open-sse/services/usage/devinCli.ts` | Penggantian opsional untuk API manajemen seat Codeium yang digunakan oleh kuota Devin CLI (`GetUserStatus`). |
| `AUGGIE_BIN` | `auggie` | `open-sse/executors/auggie.ts` | Penggantian dengan path absolut untuk biner CLI Augment (Auggie) yang digunakan oleh penyedia `auggie` lokal. Jika tidak tersedia, akan menggunakan `CLI_AUGGIE_BIN`, lalu melakukan pencarian di PATH. |
| `CLI_AUGGIE_BIN` | `auggie` | `open-sse/executors/auggie.ts` | Alias penggantian untuk path biner CLI Augment (Auggie) (diperiksa setelah `AUGGIE_BIN`). |
| `ZCODE_BIN` | `zcode` | `open-sse/executors/zcode.ts` | Biner yang digunakan untuk klien stdio milik penyedia `zcode` lokal. Jika tidak tersedia, akan menggunakan `zcode` di PATH. |
| `ZCODE_ARGS` | — | `open-sse/executors/zcode.ts` | Larik JSON (≤16 string) berisi argumen tambahan yang diteruskan ke biner `zcode` saat diluncurkan melalui `cliTools`. |
| `ZCODE_CWD` | `process.cwd()` | `open-sse/executors/zcode.ts` | Direktori kerja untuk subproses app-server ZCode. |
| `ZCODE_PROVIDER_ID` | `builtin:zai-coding-plan` | `open-sse/executors/zcode.ts` | Penggantian untuk ID penyedia yang dikirim ke app-server. |
| `ZCODE_SERVER_RUNTIME_ROOT` | `~/.zcode/server` | `open-sse/executors/zcode.ts` | Direktori root runtime app-server ZCode (tempat `node` dan `zcode-server.cjs` yang disertakan berada). |
| `ZCODE_SERVER_NODE` | `/node` | `open-sse/executors/zcode.ts` | Executable Node yang digunakan untuk menjalankan app-server ZCode. |
| `ZCODE_SERVER_ENTRY` | `/zcode-server.cjs` | `open-sse/executors/zcode.ts` | Skrip entri app-server yang digunakan untuk menjalankan server ZCode. |
| `ZCODE_STARTUP_TIMEOUT_MS` | `10000` | `open-sse/executors/zcode.ts` | Batas waktu startup (ms) sebelum peluncuran app-server ZCode dianggap gagal. |
| `ZCODE_RPC_TIMEOUT_MS` | `30000` | `open-sse/executors/zcode.ts` | Batas waktu RPC per permintaan (ms) untuk panggilan app-server ZCode. |
| `ZCODE_TURN_TIMEOUT_MS` | `120000` | `open-sse/executors/zcode.ts` | Durasi maksimum (ms) untuk satu giliran ZCode sebelum supervisor menghentikannya karena kehabisan waktu. |
| `ZCODE_POLL_INTERVAL_MS` | `250` | `open-sse/executors/zcode.ts` | Interval polling (ms) untuk penyelesaian giliran ZCode. |
| `HERMES_HOME` | `~/.hermes` | `src/lib/cli-helper/config-generator/hermesHome.ts` | Direktori utama Hermes Agent tempat OmniRoute membaca/menulis konfigurasi Hermes CLI. Sesuai dengan variabel lingkungan yang ditetapkan oleh penginstal PowerShell Hermes di Windows (`%LOCALAPPDATA%\hermes`). |
### Sinkronisasi Otomatis Profil CLI
Flag fitur ini bersifat opsional dan dinonaktifkan secara default. Flag tersebut juga dapat diaktifkan atau dinonaktifkan dari
dasbor CLI Code.
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------------- | ------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_AUTO_SYNC_CODEX_PROFILES` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Setelah sinkronisasi model penyedia, secara otomatis menulis ulang file profil `~/.codex/*.config.toml` berdasarkan katalog aktif. Memerlukan `CLI_ALLOW_CONFIG_WRITES`; tidak pernah mengubah konfigurasi Codex aktif/default, autentikasi, pengaturan Codex-lb, atau pilihan penyedia. |
| `OMNIROUTE_AUTO_SYNC_CLAUDE_PROFILES` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Setelah sinkronisasi model penyedia, secara otomatis menulis ulang file profil Claude Code `~/.claude/profiles//settings.json` berdasarkan katalog aktif. Memerlukan `CLI_ALLOW_CONFIG_WRITES`; tidak pernah mengubah konfigurasi Claude aktif/default, autentikasi, atau pilihan penyedia. |
### Contoh Docker
```bash
# Pasang biner host ke dalam kontainer dan beri tahu OmniRoute lokasi biner tersebut:
CLI_EXTRA_PATHS=/host-cli/bin
CLI_CONFIG_HOME=/host-home
CLI_ALLOW_CONFIG_WRITES=true
CLI_CLAUDE_BIN=/host-cli/bin/claude
```
`CLI_CONFIG_HOME` hanya berlaku ketika jalurnya benar-benar di-bind mount dari
host — pasangkan dengan mount seperti `~/.codex:/host-home/.codex:rw` (lihat profil
`host` di `docker-compose.yml`). Jalur yang tidak berada di dalam direktori home
pengguna container maupun merupakan bind mount akan diabaikan, karena data yang
ditulis di sana akan hilang ketika container dibuat ulang.
Image dijalankan sebagai `USER node`, sehingga `/root` yang tidak di-mount **bukan**
override yang valid.
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------------------------- | ------------ | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_CONTAINER` | _(otomatis)_ | `src/shared/utils/containerEnv.ts` | Memaksa deteksi container aktif (`1`/`true`) atau nonaktif (`0`/`false`). Hanya diperlukan pada runtime yang tidak terdeteksi oleh deteksi otomatis. |
| `OMNIROUTE_ALLOW_CONTAINER_CONFIG_WRITE` | `false` | `src/shared/services/cliRuntime.ts` | Tetap mengizinkan penulisan konfigurasi alat CLI ke jalur container yang tidak di-mount. Padanan CLI-nya adalah `--allow-container-write`. |
### Pembantu Biner CLI (`omniroute`)
Variabel-variabel ini menyesuaikan perilaku biner CLI `omniroute` itu sendiri (bukan
deteksi sidecar di atas).
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------------- | ---------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_LANG` | _(sistem)_ | `bin/cli/i18n.mjs` | Memaksa bahasa output CLI. Locale BCP-47 (misalnya `en`, `pt-BR`). Menggantikan variabel lingkungan locale sistem (LC_ALL, LC_MESSAGES). |
| `OMNIROUTE_SHOW_LOG` | _(tidak diatur)_ | `bin/cli/runtime/processSupervisor.mjs` | Atur ke `1` untuk meneruskan stdout/stderr server ke terminal dalam mode terawasi. Setara dengan flag `--log` pada `omniroute serve`. |
| `OMNIROUTE_CLI_TOKEN` | _(tidak diatur)_ | `bin/cli/api.mjs` | Token autentikasi mesin yang disisipkan sebagai header `x-omniroute-cli-token`. Dibuat secara otomatis dalam tugas 8.12. |
| `OMNIROUTE_HTTP_TIMEOUT_MS` | `30000` | `bin/cli/api.mjs` | Batas waktu HTTP per percobaan (ms) untuk permintaan CLI → server. |
| `OMNIROUTE_READY_TIMEOUT_MS` | `60000` | `bin/cli/utils/pid.mjs` | Waktu maksimum (ms) bagi CLI untuk menunggu endpoint kesehatan server sebelum mencetak peringatan batas waktu. Berguna untuk cold start yang lambat (misalnya Windows). Juga dapat diatur melalui `--ready-timeout`. |
| `OMNIROUTE_VERBOSE` | `0` | `bin/cli/api.mjs` | Atur ke `1` untuk mencetak diagnostik percobaan ulang/backoff ke stderr selama menjalankan perintah CLI. |
| `OMNIROUTE_PLUGIN_PATH` | _(tidak diatur)_ | `bin/cli/plugins.mjs` | Direktori khusus untuk penemuan plugin CLI (paket `omniroute-cmd-*`). Secara default menggunakan `~/.omniroute/plugins/` jika tidak diatur. Khusus CLI — variabel ini tidak pernah diteruskan ke pemindai plugin sisi server, yang diarahkan oleh `OMNIROUTE_PLUGINS_DIR` (bagian 2). |
---
## 10. Integrasi Agen Internal & MCP
| Variabel | Default | File Sumber | Deskripsi |
| ----------------------------------------------- | --------------------------------------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_BASE_URL` | deteksi otomatis | `open-sse/mcp-server/server.ts` | URL eksplisit yang digunakan alat MCP/A2A untuk mengakses OmniRoute. Menggantikan deteksi otomatis localhost. |
| `OMNIROUTE_API_KEY` | _(tidak ditetapkan)_ | Modul MCP/A2A | Kunci API untuk pemanggilan alat MCP internal dan skill A2A. |
| `OMNIROUTE_API_KEY_ID` | _(tidak ditetapkan)_ | `open-sse/mcp-server/audit.ts` | ID kunci untuk atribusi log audit MCP. |
| `ROUTER_API_KEY` | _(tidak ditetapkan)_ | Lama | Alias lama untuk `OMNIROUTE_API_KEY`. |
| `OMNIROUTE_A2A_HISTORY_RETENTION_DAYS` | `30` | `src/lib/a2a/taskManager.ts` | Jumlah hari riwayat tugas A2A disimpan dalam basis data lokal sebelum pembersihan harian menghapus baris. Jika tidak ditetapkan, bukan angka, atau `<= 0`, nilainya kembali ke `30`. |
| `OMNIROUTE_A2A_MEMORY_HITS` | `1` | `src/lib/a2a/taskExecution.ts` | Sakelar pemutus untuk fitur observabilitas memory-hits A2A. Atur ke `0` untuk sepenuhnya melewati pencarian pengingatan memori bagi suatu tugas; nilai lainnya (termasuk jika tidak ditetapkan) akan membuatnya tetap aktif. |
| `OMNIROUTE_ISSUE_AGENT_ENABLED` | `false` | `src/app/api/issue-agent/runs/route.ts` | Mengaktifkan endpoint triase terekam Issue Agent secara offline/lokal. Biarkan dinonaktifkan kecuali alur kerja triase terekam lokal dijalankan secara eksplisit. |
| `OMNIROUTE_ISSUE_AGENT_TIMEOUT_MS` | _(tidak ditetapkan)_ | `src/lib/issueAgent/execution.ts` | Batas waktu (ms) untuk satu kali proses triase terekam Issue Agent. Dibatasi hingga maksimum internal; kembali ke nilai default bawaan jika tidak ditetapkan atau tidak valid. |
| `OMNIROUTE_CONTEXT` | _(konteks aktif)_ | `bin/cli/program.mjs`, `bin/cli/api.mjs` | Konteks/profil mode jarak jauh CLI untuk perintah `omniroute`; menggantikan konteks aktif dalam penyimpanan konteks lokal. Setara dengan `--context `. |
| `OMNIROUTE_CONTEXT_KEYCHAIN_DISABLED` | `0` | `bin/cli/contexts.mjs` | Menonaktifkan backend rantai kunci OS `keytar` opsional untuk kredensial konteks CLI. Saat diaktifkan, kredensial tetap berada dalam `config.json` dengan mode `0600` dan CLI menampilkan peringatan fallback satu kali; ditujukan untuk pengoperasian headless/kontainer yang disengaja. |
| `OMNIROUTE_MCP_ENFORCE_SCOPES` | `false` | `open-sse/mcp-server/server.ts` | Menerapkan kontrol akses berbasis cakupan pada pemanggilan alat MCP. |
| `OMNIROUTE_MCP_SCOPES` | _(semua)_ | `open-sse/mcp-server/server.ts` | Cakupan yang dipisahkan koma: `admin`, `combos`, `health`, `models`, `routing`, `budget`, `metrics`, `pricing`, `memory`, `skills`. |
| `OMNIROUTE_MCP_COMPRESS_DESCRIPTIONS` | `false` | `open-sse/mcp-server/descriptionCompressor.ts` | Mengompresi deskripsi alat MCP sebelum melakukan serialisasi manifes. Nilai untuk mengaktifkan: `1`, `true`, `on`. |
| `OMNIROUTE_MCP_DESCRIPTION_COMPRESSION` | `rtk` | `open-sse/mcp-server/descriptionCompressor.ts` | Algoritma/profil kompresi. Nilai untuk menonaktifkan: `0`, `false`, `off`. |
| `OMNIROUTE_MCP_FETCH_TIMEOUT_MS` | `10000` | `open-sse/mcp-server/fetchTimeout.ts` | Batas waktu pembatalan (ms) untuk pembacaan manajemen internal server MCP (kesehatan, ketahanan, kombinasi, kuota, penggunaan). |
| `OMNIROUTE_MCP_UPSTREAM_TIMEOUT_MS` | `60000` | `open-sse/mcp-server/fetchTimeout.ts` | Batas waktu pembatalan (ms) untuk hop MCP yang menunggu penyedia (`route_request`, `web_search`, `web_fetch`). |
| `OMNIROUTE_CORPUS_CACHE_SIZE` | `5` | `src/lib/localCorpus/configured.ts` | Jumlah maksimum instans indeks korpus lokal yang disimpan dalam cache memori (LRU, satu per direktori akar yang diindeks). Dibatasi ke minimum `1`. |
| `MODEL_SYNC_INTERVAL_HOURS` | `24` | `src/shared/services/modelSyncScheduler.ts` | Interval sinkronisasi katalog model dalam jam. |
| `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | `src/lib/usage/providerLimits.ts` | Interval polling batas laju dan kuota penyedia. |
| `PROVIDER_LIMITS_SYNC_SPACING_MS` | `1500` | `src/lib/usage/providerLimits.ts` | Jeda (ms) antara pengambilan kuota OAuth berturut-turut dalam sinkronisasi massal; koneksi OAuth diambil satu per satu untuk menghindari lonjakan permintaan ke upstream. `0` menonaktifkan pengaturan ini (konkuren). |
| `OMNIROUTE_QUOTA_FETCH_MIN_INTERVAL_MS` | `250` | `open-sse/services/quotaFetchThrottle.ts` | Interval minimum (ms) antara pengambilan kuota upstream berturut-turut pada jalur pra-pemeriksaan/pemantauan per permintaan; memberi jeda pada panggilan jaringan konkuren agar banyak akun pada satu IP tidak menyebabkan lonjakan permintaan ke upstream. Diterapkan pada pengambil kuota Codex (`/wham/usage`), DeepSeek, Bailian (kedua lokasi pengambilan), OpenCode, dan Crof (#6009, #6911). Jalur pengiriman generik `usage.ts::getUsageForProvider` (github/glm/minimax/nanogpt/xai/dll.) belum tercakup — dilacak secara terpisah. Cache hit tidak terpengaruh. `0` menonaktifkan; dibatasi pada `0..5000`. |
| `PROVIDER_LIMITS_POST_USAGE_REFRESH_DELAY_MS` | `5000` | `src/lib/usage/providerLimits.ts` | Penundaan (ms) sebelum memperbarui batas penyedia setelah peristiwa penggunaan nyata, sehingga API kuota upstream memiliki waktu untuk mencatat konsumsi. |
| `OMNIROUTE_LOGIN_BROWSER_PATH` | deteksi otomatis | `open-sse/services/adobeFireflyBrowserLogin.ts` | Jalur absolut ke executable Chrome atau Edge sistem yang digunakan untuk proses masuk Adobe Firefly interaktif dan pembaruan di luar layar. |
| `ADOBE_FIREFLY_BROWSER_REFRESH` | diaktifkan | `open-sse/services/adobeFireflySession.ts` | Menjaga status IMS dan risiko browser tetap mutakhir dengan sesi Chrome CDP yang cakupannya dibatasi per akun. Atur ke `0` untuk menonaktifkan pembaruan browser. |
| `ADOBE_FIREFLY_SESSION_DISK` | diaktifkan | `open-sse/services/adobeFireflySession.ts` | Menyimpan sesi Adobe yang telah diperbaiki di bawah `DATA_DIR` saat proses dimulai ulang. Atur ke `0` agar sesi hanya disimpan dalam memori. |
| `ADOBE_FIREFLY_MIN_SUBMIT_GAP_MS` | `12000` | `open-sse/services/adobeFireflySession.ts` | Jeda minimum dalam milidetik antara pengiriman pembuatan Adobe Firefly; `0` menonaktifkan jeda. |
| `ADOBE_FIREFLY_BATCH_EXTRA_GAP_MS` | `15000` | `open-sse/services/adobeFireflySession.ts` | Periode tenang tambahan dalam milidetik setelah setiap pengiriman Adobe ketiga yang berhasil. |
| `ADOBE_FIREFLY_SUBMIT_BASE_DELAY_MS` | `8000` | `open-sse/services/adobeFireflyClient.ts` | Backoff dasar dalam milidetik setelah respons Adobe 408 sementara; digabungkan dengan jeda pengiriman hingga maksimum lima percobaan. |
| `OMNIROUTE_DISABLE_BACKGROUND_SERVICES` | `false` | `src/instrumentation-node.ts` | Menonaktifkan semua layanan latar belakang (sinkronisasi, penetapan harga, pembaruan model). Berguna untuk CI/pengujian. |
| `OMNIROUTE_ENABLE_RUNTIME_BACKGROUND_TASKS` | _(tidak ditetapkan)_ | `src/lib/config/runtimeSettings.ts` | Memaksa tugas latar belakang tetap aktif saat pengujian otomatis terdeteksi. Atur `1` untuk mengesampingkan heuristik pengujian. |
| `OMNIROUTE_BUDGET_RESET_JOB_INTERVAL_MS` | `600000` | `src/lib/jobs/budgetResetJob.ts` | Frekuensi pemeriksaan pengaturan ulang anggaran (ms). Batas bawah `10000`. |
| `OMNIROUTE_CONNECTION_RECOVERY_INTERVAL_MS` | `60000` | `src/lib/quota/connectionRecovery.ts` | Interval pemulihan cooldown koneksi proaktif (ms): memvalidasi ulang koneksi yang nilai sementara `rate_limited_until`-nya telah berlalu, di luar jalur utama permintaan. Batas minimum `5000`. |
| `OMNIROUTE_DISABLE_CONNECTION_RECOVERY` | `false` | `src/lib/quota/connectionRecovery.ts` | Menonaktifkan penjadwal pemulihan cooldown koneksi proaktif (pemulihan secara malas di `getProviderCredentials` tetap berlaku). |
| `OMNIROUTE_REASONING_CACHE_CLEANUP_INTERVAL_MS` | `1800000` | `src/lib/jobs/reasoningCacheCleanupJob.ts` | Interval pembersihan cache penalaran (ms). Batas minimum `60000`. |
| `OMNIROUTE_REASONING_MIN_BUDGET` | _tidak ditetapkan_ (dinonaktifkan) | `open-sse/services/reasoningTokenBuffer.ts` | Batas minimum opsional untuk anggaran keluaran model pemikiran: `max_tokens` pemanggil dalam rentang `[256, floor)` dinaikkan hingga batas minimum (dibatasi oleh batas keluaran model). Tidak ditetapkan = anggaran klien tidak pernah diperbesar (#9507). |
| `OMNIROUTE_LOG_EXPORT_CRON` | `0 * * * *` | `src/lib/jobs/logExportJob.ts` | Ekspresi cron (UTC) untuk tugas ekspor log panggilan yang menguras setiap tujuan ekspor log yang diaktifkan. |
| `OMNIROUTE_CONFIG_HOT_RELOAD_MS` | `5000` | `src/lib/config/hotReload.ts` | Interval polling (ms) untuk pemuatan ulang langsung konfigurasi. Nilai yang lebih rendah dari `1000` ditolak. |
| `OMNIROUTE_DISABLE_REDIS_AUTH_CACHE` | _(diaktifkan)_ | `src/lib/db/apiKeys.ts` | Atur ke `1` untuk melewati cache autentikasi kunci API berbasis Redis (memaksa pembacaan DB). |
| `OMNIROUTE_RTK_TRUST_PROJECT_FILTERS` | `0` | `open-sse/services/compression/engines/rtk/filterLoader.ts` | Memercayai aturan filter proyek RTK yang dikelola pengguna tanpa pemeriksaan tanda tangan yang ketat. |
| `OMNIROUTE_LITE_MAX_TOOL_LENGTH` | `2000` | `open-sse/services/compression/lite.ts` | Batas karakter untuk pemotongan proaktif hasil alat Lite ketika `lite.maxToolLength` tidak ditetapkan. Rentang 256–1000000. Pengaturan dasbor diprioritaskan dibandingkan variabel lingkungan ini. |
| `OMNI_COMPRESSION_WORKERS` | `2` | `open-sse/services/compression/compressionWorkerPool.ts` | Jumlah maksimum worker RTK/Caveman sinkron yang berjalan bersamaan; tugas berlebih menunggu secara FIFO. |
| `OMNI_COMPRESSION_WORKER_TIMEOUT_MS` | `120000` | `open-sse/services/compression/compressionWorkerPool.ts` | Batas waktu per tugas dalam milidetik. Worker yang kehabisan waktu dihentikan dan permintaan diteruskan tanpa perubahan. |
| `OMNI_COMPRESSION_WORKER_IDLE_MS` | `60000` | `open-sse/services/compression/compressionWorkerPool.ts` | Masa aktif saat menganggur dalam milidetik sebelum worker kompresi yang tidak digunakan dihentikan. |
| `COMPRESSION_PIPELINE_BREAKER_ENABLED` | `false` | `open-sse/services/compression/pipelineEngineBreaker.ts` | Sakelar utama pemutus sirkuit per mesin untuk pipeline bertumpuk T02. **Opsional (secara default nonaktif)** — ketika aktif, mesin yang berulang kali melempar pengecualian di berbagai permintaan akan dilewati (fail-open) selama periode cooldown; nonaktif = perilaku lama yang identik hingga tingkat byte. |
| `COMPRESSION_PIPELINE_BREAKER_THRESHOLD` | `3` | `open-sse/services/compression/pipelineEngineBreaker.ts` | Jumlah kegagalan berturut-turut di berbagai permintaan sebelum pemutus suatu mesin terbuka. |
| `COMPRESSION_PIPELINE_BREAKER_COOLDOWN_MS` | `30000` | `open-sse/services/compression/pipelineEngineBreaker.ts` | Durasi dalam milidetik saat mesin dengan pemutus terbuka tetap dilewati sebelum probe setengah terbuka. |
| `COMPRESSION_CCR_RETRIEVAL_RAMP_FACTOR` | `2` | `open-sse/services/compression/engines/ccr/index.ts` | Peningkatan umpan balik pengambilan CCR T08/H8: setiap pengambilan sebelumnya atas blok yang disimpan menaikkan `minChars` efektifnya secara linear (konten yang sering diambil dikompresi lebih sedikit; pengambilan `>=3` = tidak pernah dikompresi). `1` menonaktifkan peningkatan (hanya melewati secara biner pada ambang batas). |
| `COMPRESSION_CCR_DURABLE_STORE` | `true` | `open-sse/services/compression/engines/ccr/index.ts` | Penyimpanan blok persisten CCR (#9061). Mencadangkan penyimpanan dalam memori dengan SQLite agar blok tetap bertahan setelah dikeluarkan oleh LRU, melewati TTL, dimulai ulang, atau pengambilan dilakukan pada instans lain. Atur ke `false` agar blok hanya disimpan dalam memori. Blok berukuran lebih dari 512KB dan runtime cloud akan tetap hanya disimpan dalam memori. |
| `COMPRESSION_PREFIX_FREEZE_ENABLED` | `false` | `open-sse/services/compression/prefixFreeze.ts` | Sakelar utama pembekuan prefiks berdasarkan penggunaan yang diamati T08/H5. **Ikut serta (secara default nonaktif)** — saat aktif, prompt sistem yang diamati `>=` ambang batas diperlakukan sebagai prefiks stabil yang dapat di-cache dan dipertahankan dari kompresi, bahkan untuk penyedia yang tidak terdeteksi oleh heuristik cache statis (pembekuan hanya _mempertahankan_, tidak pernah mengubah). |
| `COMPRESSION_PREFIX_FREEZE_THRESHOLD` | `3` | `open-sse/services/compression/prefixFreeze.ts` | Jumlah pengamatan terhadap prompt sistem sebelum prompt tersebut diperlakukan sebagai prefiks stabil yang dibekukan. |
| `OMNIROUTE_BOOTSTRAPPED` | `false` | `src/app/(dashboard)/dashboard/page.tsx` | Diatur ke `true` oleh skrip bootstrap setelah penyiapan awal. Mengontrol visibilitas wizard penyiapan. |
| `OMNIROUTE_ALLOW_BODY_PROJECT_OVERRIDE` | `0` | `open-sse/executors/antigravity.ts` | Mekanisme darurat: izinkan isi permintaan menimpa bidang proyek Antigravity. |
| `ANTIGRAVITY_CREDITS` | `off` | `open-sse/services/antigravityCredits.ts` | Kebijakan kredit Google One AI: `off` tidak pernah menyisipkan kredit, `retry` menyisipkannya satu kali setelah respons kuota 429 yang memenuhi syarat, dan `always` menyisipkannya pada permintaan pertama. |
| `ANTIGRAVITY_ALLOW_SIGNATURE_BYPASS` | `0` | `open-sse/translator/request/openai-to-gemini.ts` | Izinkan penerjemah permintaan Antigravity melewati validasi ketat tanda tangan permintaan CLI ketika layanan upstream menolak tanda tangan asli (mode debug/CLI lawas). Nilai bukan nol mengaktifkan bypass. |
| `AGY_TOKEN_FILE` | `~/.gemini/antigravity-cli/antigravity-oauth-token` | `src/app/api/providers/agy-auth/apply-local/route.ts` | Timpa jalur file token Antigravity CLI (agy) untuk impor login lokal dengan deteksi otomatis. |
### Jembatan CLI OAuth (Internal)
| Variabel | Default | File Sumber | Deskripsi |
| ------------------- | ---------------- | ------------------------------- | ---------------------------------------------------- |
| `OMNIROUTE_SERVER` | deteksi otomatis | `src/lib/oauth/config/index.ts` | URL server untuk jembatan autentikasi CLI↔OmniRoute. |
| `OMNIROUTE_TOKEN` | _(tidak diatur)_ | `src/lib/oauth/config/index.ts` | Token autentikasi untuk jembatan CLI. |
| `OMNIROUTE_USER_ID` | `cli` | `src/lib/oauth/config/index.ts` | ID pengguna untuk sesi jembatan CLI. |
| `SERVER_URL` | _(tidak diatur)_ | `src/lib/oauth/config/index.ts` | Alias lama untuk `OMNIROUTE_SERVER`. |
| `CLI_TOKEN` | _(tidak diatur)_ | `src/lib/oauth/config/index.ts` | Alias lama untuk `OMNIROUTE_TOKEN`. |
| `CLI_USER_ID` | _(tidak diatur)_ | `src/lib/oauth/config/index.ts` | Alias lama untuk `OMNIROUTE_USER_ID`. |
---
## 11. Kredensial Penyedia OAuth
Kredensial bawaan untuk **pengembangan localhost**. Untuk deployment jarak jauh, daftarkan milik Anda sendiri di konsol pengembang setiap penyedia.
| Variabel | Penyedia | Catatan |
| ------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLAUDE_OAUTH_CLIENT_ID` | Claude Code (Anthropic) | Klien publik — tidak memerlukan secret. |
| `CLAUDE_CODE_REDIRECT_URI` | Claude Code | Timpa URI pengalihan. Default: `https://platform.claude.com/oauth/code/callback` |
| `CODEX_OAUTH_CLIENT_ID` | Codex / OpenAI | Klien publik. |
| `GEMINI_OAUTH_CLIENT_ID` | Gemini (Google) | Membutuhkan `_SECRET` yang cocok. |
| `GEMINI_OAUTH_CLIENT_SECRET` | Gemini (Google) | — |
| `KIMI_CODING_OAUTH_CLIENT_ID` | Kimi Coding (Moonshot) | Klien publik. |
| `MUSE_CODE_OAUTH_CLIENT_ID` | Muse Code (Meta) | Timpa opsional untuk ID klien alur perangkat Muse CLI publik. Biarkan tidak diatur untuk menggunakan klien publik bawaan. |
| `ANTIGRAVITY_OAUTH_CLIENT_ID` | Antigravity (Google) | Membutuhkan `_SECRET` yang cocok. |
| `ANTIGRAVITY_OAUTH_CLIENT_SECRET` | Antigravity (Google) | — |
| `GITHUB_OAUTH_CLIENT_ID` | GitHub Copilot | Klien publik. |
| `GHE_COPILOT_OAUTH_CLIENT_ID` | GHE Copilot | Timpa opsional untuk ID klien OAuth GitHub Enterprise Copilot. Kembali ke default publik `GITHUB_OAUTH_CLIENT_ID` saat tidak diatur. |
| `COPILOT_INTEGRATION_ID` | GitHub Copilot | Timpa opsional untuk ID integrasi klien GitHub Copilot yang dikirim dalam header `Copilot-Integration-Id` dan `Editor-Plugin-Version`. Defaultnya adalah `copilot-developer-cli`. |
| `WINDSURF_API_KEY` | Windsurf / Devin (v3.8) | Fallback kunci API yang digunakan oleh `open-sse/executors/devin-cli.ts` ketika tidak ada kredensial per-koneksi yang tersedia. Opsional. |
| `CLI_DEVIN_BIN` | Devin CLI (v3.8) | Jalur kustom ke biner Devin CLI (`devin`). Diselesaikan oleh `open-sse/executors/devin-cli.ts`. |
| `GITLAB_DUO_OAUTH_CLIENT_ID` | GitLab Duo (v3.8) | ID klien OAuth untuk GitLab Duo. Daftarkan aplikasi di `https://gitlab.com/-/profile/applications` dengan URI pengalihan `/callback` dan cakupan `api, read_user, openid, profile, email`. Kembali ke `GITLAB_OAUTH_CLIENT_ID`. |
| `GITLAB_DUO_OAUTH_CLIENT_SECRET` | GitLab Duo (v3.8) | Secret klien OAuth untuk GitLab Duo. Opsional — alur PKCE tidak memerlukan secret. Kembali ke `GITLAB_OAUTH_CLIENT_SECRET`. |
| `GITLAB_DUO_BASE_URL` | GitLab Duo (v3.8) | Timpa URL dasar GitLab (GitLab yang di-host sendiri). Defaultnya adalah `https://gitlab.com`. Kembali ke `GITLAB_BASE_URL`. |
| `GITLAB_BASE_URL` | GitLab Duo (v3.8) | Fallback lama untuk `GITLAB_DUO_BASE_URL`. Digunakan ketika varian `_DUO_` tidak diatur. |
| `GITLAB_OAUTH_CLIENT_ID` | GitLab Duo (v3.8) | Fallback lama untuk `GITLAB_DUO_OAUTH_CLIENT_ID` yang digunakan oleh `src/lib/oauth/constants/oauth.ts`. |
| `GITLAB_OAUTH_CLIENT_SECRET` | GitLab Duo (v3.8) | Fallback lama untuk `GITLAB_DUO_OAUTH_CLIENT_SECRET` yang digunakan oleh `src/lib/oauth/constants/oauth.ts`. |
| `QODER_OAUTH_CLIENT_SECRET` | Qoder | — |
| `QODER_OAUTH_AUTHORIZE_URL` | Qoder | Atur untuk mengaktifkan Qoder OAuth. |
| `QODER_OAUTH_TOKEN_URL` | Qoder | — |
| `QODER_OAUTH_USERINFO_URL` | Qoder | — |
| `QODER_OAUTH_CLIENT_ID` | Qoder | — |
| `QODER_PERSONAL_ACCESS_TOKEN` | Qoder | Fallback kunci API langsung (melewati OAuth). |
| `QODER_CLI_WORKSPACE` | Qoder | ID Ruang Kerja untuk Qoder CLI. |
| `OMNIROUTE_QODER_WORKSPACE` | Qoder | Alias untuk `QODER_CLI_WORKSPACE`. |
| `QODER_CLI_CONFIG_DIR` | Qoder | Timpa direktori konfigurasi Qoder CLI (sesi PAT terisolasi, menghindari penimpaan login browser). |
| `BLACKBOX_WEB_VALIDATED_TOKEN` | Blackbox Web | Token `tk` frontend untuk dikirim sebagai `validated` pada `/api/chat`. Diperlukan ketika Blackbox memberlakukan pencocokan token; jika tidak, OmniRoute akan kembali ke UUID acak. Lihat isu #2252. |
| `VISION_BRIDGE_BASE_URL` | Vision Bridge guardrail | URL dasar yang kompatibel dengan OpenAI untuk panggilan vision-bridge non-Anthropic. Defaultnya adalah env URL OpenAI lama atau api.openai.com. Arahkan ke self-loop `/v1` OmniRoute atau endpoint yang kompatibel dengan OpenAI (Gemini OpenAI-compat, OpenRouter). Isu #2232. Ketika URL adalah `/v1` milik OmniRoute sendiri, sub-permintaan deskripsi mengirimkan `x-omniroute-admission-bypass: internal` dan mengautentikasi dengan kredensial self-loop yang telah diselesaikan (`sk_omniroute` sentinel dalam mode lokal, atau `OMNIROUTE_API_KEY` / `ROUTER_API_KEY` — #1350) sehingga deployment `REQUIRE_API_KEY=true` berfungsi. |
| `VISION_BRIDGE_API_KEY` | Vision Bridge guardrail | Kunci API untuk URL di atas. Menimpa variabel lingkungan OpenAI / Google per penyedia untuk panggilan vision-bridge non-Anthropic. Model Anthropic mempertahankan jalur kunci Anthropic khusus mereka. Isu #2232. |
| `OMNIROUTE_VISION_BRIDGE_NEGATIVE_CACHE_MS` | Vision Bridge guardrail | Berapa lama hasil routing "tidak ada kandidat yang dapat digunakan" di-cache, dalam ms (default `30000`). Nilai yang tidak valid atau negatif akan kembali ke default; `0` menonaktifkan cache negatif. Sumber: `src/lib/guardrails/visionBridgeRouter.ts`. |
> [!PERINGATAN]
>
> 1. Buka [Google Cloud Console → Credentials](https://console.cloud.google.com/apis/credentials)
> 2. Buat ID Klien OAuth 2.0 (tipe: "Aplikasi web")
> 3. Tambahkan URL server Anda sebagai URI pengalihan yang diotorisasi
> 4. Ganti nilai kredensial di `.env`.
---
## 12. Penggantian User-Agent Penyedia
Ganti header `User-Agent` yang dikirim ke setiap penyedia upstream. Nilai ini ditentukan secara dinamis saat runtime oleh kelas dasar eksekutor:
```
process.env[`${PROVIDER_ID}_USER_AGENT`]
```
> **Sumber:** `open-sse/executors/base.ts` → `buildHeaders()`
| Variabel | Nilai Default | Kapan Harus Diperbarui |
| -------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `CLAUDE_USER_AGENT` | `claude-cli/2.1.258 (external, cli)` | Saat Anthropic merilis versi CLI baru |
| `CLAUDE_DISABLE_TOOL_NAME_CLOAK` | `false` | `executors/base.ts` + `executors/cliproxyapi.ts` | Atur ke `1`/`true` untuk meneruskan nama alat harness pihak ketiga apa adanya ke Anthropic pada kedua jalur yang menuju Anthropic (OAuth native dan CLIProxyAPI). Secara default, eksekutor secara deterministik membuat alias untuk nama alat non-Claude-Code (menggunakan pemetaan kanonis Claude Code jika tersedia, atau PascalCase jika tidak) dan mengembalikannya pada respons melalui `_toolNameMap`, sehingga harness dengan alat bernama snake_case tidak ditolak karena teridentifikasi sebagai klien pihak ketiga. Hanya untuk proses debug. |
| `CODEX_USER_AGENT` | `codex-cli/0.155.0 (Windows 10.0.26200; x64)` | Saat OpenAI memperbarui Codex CLI |
| `CODEX_CLIENT_VERSION` | `0.155.0` | Ganti versi klien Codex secara terpisah dari string UA lengkap |
| `CLAUDE_CODE_CLIENT_VERSION` | `2.1.258` | Ganti versi Claude Code yang diumumkan secara terpisah dari `CLAUDE_USER_AGENT`. Anthropic membatasi beberapa model berdasarkan nilai ini (#12417). |
| `GITHUB_COPILOT_CLI_VERSION` | `1.0.81-6` | Ganti versi Copilot CLI yang diumumkan secara terpisah dari `GITHUB_USER_AGENT` |
| `GITHUB_USER_AGENT` | `GitHubCopilotChat/0.54.0` | Saat GitHub Copilot Chat diperbarui |
| `ANTIGRAVITY_USER_AGENT` | `antigravity/2.0.1 darwin/arm64` | Saat Antigravity IDE diperbarui |
| `KIRO_USER_AGENT` | `AWS-SDK-JS/3.0.0 kiro-ide/1.0.0` | Saat Kiro IDE diperbarui |
| `KIRO_OAUTH_CLIENT_ID` | `kiro-cli` | Ganti `clientId` (ID publik) kode perangkat sosial Kiro |
| `KIRO_VERIFY_FULL_CRC` | `false` | Keikutsertaan opsional: validasi CRC pesan lengkap per frame pada aliran peristiwa Kiro (untuk men-debug aliran yang rusak) |
| `QODER_USER_AGENT` | `Qoder-Cli` | Saat Qoder CLI diperbarui |
| `CURSOR_USER_AGENT` | `Cursor/3.3` | Saat Cursor diperbarui |
> [!TIP]
> Anda dapat menambahkan penggantian User-Agent untuk penyedia **apa pun** menggunakan pola `{PROVIDER_ID}_USER_AGENT`. Eksekutor secara dinamis menyusun nama variabel lingkungan tersebut.
---
## 13. Kompatibilitas Sidik Jari CLI
Saat diaktifkan, OmniRoute menyusun ulang header HTTP dan kolom isi JSON agar sesuai dengan karakteristik persis alat CLI resmi. Hal ini mengurangi risiko akun ditandai sekaligus mempertahankan IP proksi Anda.
**Sumber:** `open-sse/config/cliFingerprints.ts`, `open-sse/executors/base.ts`
### Per Penyedia
| Variabel | Aktivasi | Efek |
| ------------------------ | -------- | ---------------------------------------------- |
| `CLI_COMPAT_CODEX` | `=1` | Meniru karakteristik permintaan Codex CLI |
| `CLI_COMPAT_CLAUDE` | `=1` | Meniru karakteristik permintaan Claude Code |
| `CLI_COMPAT_GITHUB` | `=1` | Meniru karakteristik permintaan GitHub Copilot |
| `CLI_COMPAT_ANTIGRAVITY` | `=1` | Meniru karakteristik permintaan Antigravity |
| `CLI_COMPAT_CURSOR` | `=1` | Meniru karakteristik permintaan Cursor |
| `CLI_COMPAT_KIMI_CODING` | `=1` | Meniru karakteristik permintaan Kimi Coding |
| `CLI_COMPAT_KILOCODE` | `=1` | Meniru karakteristik permintaan Kilo Code |
| `CLI_COMPAT_CLINE` | `=1` | Meniru karakteristik permintaan Cline |
### Global
| Variabel | Aktivasi | Efek |
| ---------------- | -------- | ---------------------------------------------------------------------- |
| `CLI_COMPAT_ALL` | `=1` | Aktifkan kompatibilitas sidik jari untuk **semua** penyedia sekaligus. |
### Penggantian identitas Kimi Coding CLI
| Variabel | Default | File Sumber | Deskripsi |
| ----------------------- | ------------------------ | ---------------------------------------- | ------------------------------------------------------------------- |
| `KIMI_CLI_VERSION` | `1.36.0` | `src/lib/oauth/providers/kimi-coding.ts` | Ganti versi Kimi CLI yang dikirim selama panggilan OAuth/API. |
| `KIMI_CODING_DEVICE_ID` | _(default yang direkam)_ | `src/lib/oauth/providers/kimi-coding.ts` | Ganti ID perangkat Kimi yang direkam dan digunakan di header klien. |
> [!NOTE]
> Fitur ini bekerja bersama penggantian User-Agent (§12). Sistem sidik jari menangani urutan header dan urutan kolom isi, sedangkan penggantian User-Agent menangani string UA tertentu. Keduanya dapat diaktifkan secara independen.
---
## 14. Penyedia Kunci API
Kunci API untuk penyedia yang menggunakan autentikasi langsung. **Penyiapan yang disarankan:** Dasbor → Penyedia → Tambahkan Kunci API.
Pengaturan melalui variabel lingkungan merupakan alternatif untuk deployment Docker atau tanpa antarmuka grafis.
Pola yang dikenali: `{PROVIDER_ID}_API_KEY`
| Variabel | Penyedia |
| ------------------ | ---------------------------------------------------- |
| `DEEPSEEK_API_KEY` | DeepSeek |
| `NVIDIA_API_KEY` | NVIDIA NIM |
| `JINA_AI_API_KEY` | Jina AI (Foundation API + fallback Reader) |
| `JINA_API_KEY` | Jina AI (alias untuk `JINA_AI_API_KEY`) |
| `GEMINI_API_KEY` | Gemini (Google AI Studio) embeddings + fallback chat |
| `GOOGLE_API_KEY` | Gemini (alias untuk `GEMINI_API_KEY`) |
> [!NOTE]
> Entri statis `${PROVIDER}_API_KEY` untuk Groq, xAI, Mistral, Perplexity, Together AI, Fireworks, Cerebras, Cohere, Nebius, dan Qianfan telah dihapus pada v3.8.0 karena runtime tidak lagi membacanya — penyedia tersebut secara eksklusif mengandalkan Dasbor / `data/provider-credentials.json` / DB terenkripsi. Lihat bagian _Audit: Variabel yang Dihapus / Tidak Digunakan_ di bagian bawah dokumen ini untuk jalur migrasi.
> [!TIP]
> Kunci yang ditetapkan melalui Dasbor disimpan secara terenkripsi di SQLite dan lebih diprioritaskan daripada variabel lingkungan.
>
> **Jina:** embeddings `jina-ai/…`, rerank, classify, segment, dan `jina-search` **tidak** menagihkan kunci lingkungan klaster ketika koneksi dasbor `jina-ai` (atau `jina-reader` bersama) tersedia — `getProviderCredentials` menggunakan strategi isi-yang-kosong-terlebih-dahulu. `JINA_AI_API_KEY` / `JINA_API_KEY` hanya digunakan ketika tidak ada kunci dasbor yang dapat digunakan. Log panggilan mencatat fallback lingkungan sebagai `connection_id=env:JINA_AI_API_KEY`. Kartu Reader (`jina-reader`, `r.jina.ai`) tidak pernah melayani `/v1/embeddings` atau `/v1/rerank`.
>
> **Gemini:** `gemini/gemini-embedding-2` (alias `google/gemini-embedding-2`) menggunakan koneksi dasbor `gemini` terlebih dahulu. `GEMINI_API_KEY` / `GOOGLE_API_KEY` hanya digunakan ketika tidak ada kunci dasbor yang dapat digunakan. Log panggilan mencatat fallback lingkungan sebagai `connection_id=env:GEMINI_API_KEY`. Lalu lintas multimodal native menggunakan `x-goog-api-key` terhadap `:embedContent` / `:batchEmbedContents` — N item `input` OpenAI menjadi N vektor.
---
## 15. Pengaturan Timeout
Semua nilai dinyatakan dalam **milidetik**. Resolusi terpusat berada di `src/shared/utils/runtimeTimeouts.ts`.
### Hierarki Timeout
```
REQUEST_TIMEOUT_MS (penggantian global)
├─→ FETCH_TIMEOUT_MS (panggilan penyedia upstream, bawaan: 600000)
│ ├─→ FETCH_HEADERS_TIMEOUT_MS (mewarisi dari FETCH_TIMEOUT_MS)
│ ├─→ FETCH_BODY_TIMEOUT_MS (mewarisi dari FETCH_TIMEOUT_MS)
│ ├─→ TLS_CLIENT_TIMEOUT_MS (mewarisi dari FETCH_TIMEOUT_MS)
│ │ └── TLS_FIRST_BYTE_WATCHDOG_MS (independen, bawaan: 10000)
│ ├── RESPONSES_FIRST_BYTE_TIMEOUT_MS (independen, bawaan: 15000)
│ ├── FETCH_CONNECT_TIMEOUT_MS (independen, bawaan: 30000)
│ └── FETCH_KEEPALIVE_TIMEOUT_MS (independen, bawaan: 4000)
├─→ STREAM_IDLE_TIMEOUT_MS (mewarisi dari REQUEST_TIMEOUT_MS, bawaan: 600000)
├─→ STREAM_ACTIVE_TIMEOUT_MS (independen, bawaan: 1260000; 0 menonaktifkan)
├─→ STREAM_READINESS_TIMEOUT_MS (mewarisi dari REQUEST_TIMEOUT_MS, bawaan: 80000)
├─→ STREAM_READINESS_MAX_TIMEOUT_MS (membatasi ekstensi kesiapan adaptif, bawaan: 180000)
└─→ API_BRIDGE_PROXY_TIMEOUT_MS (mewarisi dari REQUEST_TIMEOUT_MS, bawaan: 30000)
├─→ API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS (diturunkan, bawaan: 300000)
├── API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS (bawaan: 60000)
├── API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS (bawaan: 5000)
└── API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS (bawaan: 0 = dinonaktifkan)
```
| Variabel | Default | Deskripsi |
| ----------------------------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REQUEST_TIMEOUT_MS` | _(tidak disetel)_ | Pintasan global — mengganti default `FETCH_TIMEOUT_MS` dan `STREAM_IDLE_TIMEOUT_MS`. |
| `FETCH_TIMEOUT_MS` | `600000` | Batas waktu total permintaan HTTP untuk panggilan penyedia upstream. |
| `STREAM_IDLE_TIMEOUT_MS` | `600000` | Waktu hening maksimum antara byte mentah upstream sebelum dibatalkan. Model dengan extended-thinking jarang berhenti selama >90 detik. |
| `STREAM_ACTIVE_TIMEOUT_MS` | `1260000` | Masa aktif total maksimum stream SSE; tidak pernah direset oleh byte upstream dan tidak bergantung pada `REQUEST_TIMEOUT_MS`. Diturunkan dari nilai `timeoutMs` per model terbesar dalam registry (1200000, Codex) ditambah margin 60000, sehingga model yang diizinkan menggunakan seluruh anggaran waktunya tidak pernah dihentikan di tengah jawaban. Atur ke `0` untuk menonaktifkan. |
| `OMNIROUTE_SSE_COMMENTS` | _(dinonaktifkan)_ | Menentukan apakah OmniRoute boleh mengirimkan baris komentar SSE `:` (misalnya heartbeat `: keepalive` dan trailer metadata `x-omniroute-*`). Dinonaktifkan secara default (#10524) karena klien yang sepenuhnya kompatibel dengan OpenAI melakukan JSON.parse pada setiap baris SSE dan mengalami crash akibat komentar `:`; heartbeat `data:` tidak terpengaruh. Atur ke `on`/`true`/`1`/`yes` untuk mengaktifkannya kembali. Digunakan oleh `open-sse/utils/sseHeartbeat.ts`. |
| `STREAM_READINESS_TIMEOUT_MS` | `80000` | Waktu untuk menerima event SSE non-ping pertama. Mewarisi `REQUEST_TIMEOUT_MS` jika disetel. |
| `STREAM_READINESS_MAX_TIMEOUT_MS` | `180000` | Jendela kesiapan adaptif maksimum untuk event pertama bagi permintaan streaming yang besar, banyak menggunakan alat, atau memerlukan penalaran tinggi. |
| `OMNIROUTE_AGENT_GOAL_POLICY_ENABLED` | `true` | Kill switch untuk heuristik `/goal`. Atur ke `false`/`0`/`off` untuk menonaktifkan deteksi sepenuhnya — batas waktu kesiapan dan pemulihan stream tidak pernah ditingkatkan berdasarkan body/header permintaan, sehingga memitigasi amplifikasi batas waktu yang dikendalikan klien. |
| `OMNIROUTE_AGENT_GOAL_READINESS_MAX_TIMEOUT_MS` | `600000` | Jendela kesiapan maksimum untuk event pertama bagi proses agen `/goal` yang terdeteksi atau permintaan yang dipaksakan dengan `x-omniroute-agent-goal`. |
| `OMNIROUTE_AGENT_GOAL_STREAM_RECOVERY` | `true` | Aktifkan pemulihan stream awal secara otomatis untuk proses agen `/goal` yang terdeteksi. Atur ke `false`/`0`/`off` untuk menonaktifkan pengaktifan khusus goal. Opsi ini hanya dapat MENAMBAHKAN pemulihan di atas default operator — opsi ini tidak pernah mengesampingkan penolakan eksplisit melalui `STREAM_RECOVERY_ENABLED`/pengaturan DB. |
| `OMNIROUTE_CODEX_DROP_NONSTANDARD_EVENTS` | `true` | Hapus event SSE `codex.*` nonstandar (misalnya `codex.rate_limits`) yang menyebabkan `responses.stream()` milik OpenAI SDK gagal dengan 502. Aktif secara default (#11014). Atur ke `0`/`false`/`no`/`off` untuk meneruskannya. |
| `OMNIROUTE_CODEX_APPSERVER_WS` | _(tidak disetel)_ | Transport app-server Codex yang bersifat opsional. Endpoint WebSocket (`ws://`/`wss://`) dari sidecar `codex app-server` lokal. Jika disetel bersama token, permintaan Codex dirutekan melalui JSON-RPC ke sidecar, bukan melalui HTTP Responses API. Juga dapat disetel per koneksi melalui `providerSpecificData.codexAppServerUrl`. Digunakan oleh `open-sse/executors/codex/appServerConfig.ts`. |
| `OMNIROUTE_CODEX_APPSERVER_WS_TOKEN` | _(tidak disetel)_ | Token kapabilitas/bearer inline yang diberikan kepada app-server. Penggantian per koneksi: `providerSpecificData.codexAppServerToken`. |
| `OMNIROUTE_CODEX_APPSERVER_WS_TOKEN_FILE` | _(tidak disetel)_ | Path ke file yang berisi token kapabilitas app-server (dari `codex app-server --ws-token-file`). Digunakan ketika `OMNIROUTE_CODEX_APPSERVER_WS_TOKEN` tidak disetel. Penggantian per koneksi: `providerSpecificData.codexAppServerTokenFile`. |
| `OMNIROUTE_CODEX_APPSERVER_CWD` | `/tmp` | Direktori kerja tempat proses app-server dijalankan. Penggantian per koneksi: `providerSpecificData.codexAppServerCwd`. |
| `OMNIROUTE_CODEX_APPSERVER_APPROVAL` | _(tidak disetel)_ | Kebijakan persetujuan yang diteruskan ke proses app-server (misalnya `never`, `on-request`). Penggantian per koneksi: `providerSpecificData.codexAppServerApprovalPolicy`. |
| `OMNIROUTE_CODEX_APPSERVER_SANDBOX` | _(tidak disetel)_ | Kebijakan sandbox yang diteruskan ke proses app-server (misalnya `read-only`, `workspace-write`, `danger-full-access`). Jika tidak disetel, executor menggunakan default `workspace-write` (diperketat; sebelumnya `danger-full-access`). Penggantian per koneksi: `providerSpecificData.codexAppServerSandbox`. |
| `OMNIROUTE_CODEX_APPSERVER_AUTO_APPROVE` | `false` | Setujui secara otomatis prompt persetujuan milik app-server sendiri (eksekusi perintah/file/izin pada host). Dinonaktifkan secara default — prompt ditolak secara otomatis; pemanggilan alat harness tidak terpengaruh (pemanggilan tersebut melewati passthrough `item/tool/call` yang terpisah). Menerima `true`/`1`/`yes`. Penggantian per koneksi: `providerSpecificData.codexAppServerAutoApprove`. |
| `FETCH_HEADERS_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Waktu untuk menerima header respons. |
| `OMNIROUTE_DIRECT_HEADERS_TIMEOUT_MS` | `30000` (30 dtk) | Waktu tunggu maksimum dimulainya respons (md) untuk setiap upaya langsung tanpa proksi. Jika terjadi batas waktu, upaya akan diulang sekali pada soket baru; atur ke `0` untuk menonaktifkan batas dan mempertahankan perilaku sebelumnya. |
| `OMNIROUTE_DIRECT_RESPONSE_RETRY_TIMEOUT_MS` | `600000` (10 mnt) | Batas maksimum (md) untuk upaya RETRY dengan soket baru setelah batas waktu dimulainya respons pada upaya dengan koneksi yang dikumpulkan di atas (#13703). Hanya berlaku ketika pemanggil telah memasang sinyal tenggat waktunya sendiri (rangkaian koneksi/model/penyedia/`FETCH_TIMEOUT_MS` yang telah ditetapkan); sinyal tersebut merupakan batas sebenarnya dan akan terpicu lebih dahulu pada alur yang dimaksud, sehingga ini adalah pengaman akhir yang longgar alih-alih batas tetap — tanpanya, upaya ulang menggunakan kembali rentang pendek `OMNIROUTE_DIRECT_HEADERS_TIMEOUT_MS` yang identik dengan upaya menggunakan koneksi yang dikumpulkan dan menyebabkan model penalaran dengan TTFB lambat tetapi sehat menghasilkan 504. Tidak pernah diizinkan lebih rendah dari batas minimum tetap di atas; ketika pemanggil sama sekali tidak memberikan sinyal tenggat waktu, upaya ulang mempertahankan batas minimum tetap tanpa perubahan. |
| `FETCH_BODY_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Waktu untuk menerima keseluruhan isi respons. |
| `FETCH_CONNECT_TIMEOUT_MS` | `30000` | Batas waktu pembuatan koneksi TCP. |
| `FETCH_KEEPALIVE_TIMEOUT_MS` | `4000` | Batas waktu menganggur soket keep-alive. |
| `TLS_CLIENT_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Batas waktu proksi sidik jari TLS (wreq-js). |
| `TLS_FIRST_BYTE_WATCHDOG_MS` | `10000` | Membatasi waktu hingga byte pertama khusus pada isi dari transport sidik jari TLS wreq-js; `TLS_CLIENT_TIMEOUT_MS` saja tidak dapat mendeteksi isi yang macet karena diselesaikan segera setelah header tiba (#12656). Batas waktu akan membatalkan pembaca wreq dan beralih ke dispatcher langsung/proksi; `0` menonaktifkan pengawas. |
| `RESPONSES_FIRST_BYTE_TIMEOUT_MS` | `15000` | Hanya untuk eksekutor OpenCode, dan hanya saat flag fitur `OPENCODE_RESPONSES_STALL_ROTATION` aktif (secara default nonaktif): membatasi waktu tunggu byte isi pertama dari balasan Responses yang dialirkan setelah header-nya (#13484). Aliran Responses dibuka dengan `response.created`, sehingga tidak adanya data setelah rentang ini dianggap sebagai kemacetan: akun ditempatkan dalam masa tunggu dan permintaan dialihkan ke akun berikutnya satu kali; kemacetan kedua akan langsung gagal. `0` menonaktifkan pengaman meskipun flag aktif. |
| `OPENCODE_PARK_AND_RESUME` | `false` | Hanya untuk eksekutor OpenCode: parkir permintaan dengan heartbeat setelah 429 sementara yang berulang (atau penanda tekanan pool yang baru), lalu putar ulang satu tahap terbatas yang mencakup hingga 3 akun secara berurutan alih-alih menyebarkan permintaan ke seluruh armada (#13924). Secara default nonaktif: setiap 429 mengalihkan ke akun berikutnya persis seperti sebelumnya. |
| `OPENCODE_POOL_STRAIN_MARKER_PATH` | _(tidak diatur)_ | Hanya untuk eksekutor OpenCode: ganti path penanda tekanan pool yang dibaca sebelum pemarkiran (`{since, reason, ttl_s}`, default `/tmp/opencode-pool-strain.json`, #13924). Penanda baru akan memarkir tanpa menghitung ulang; jika tidak ada atau sudah usang, kembali menggunakan penghitung burst. |
| `API_BRIDGE_PROXY_TIMEOUT_MS` | `30000` | Batas waktu hop proksi untuk permintaan bridge `/v1`. |
| `FIRECRAWL_BASE_URL` | `https://api.firecrawl.dev` | Arahkan eksekutor pengambilan web Firecrawl ke instans yang di-host sendiri (kunci API opsional di luar cloud). |
| `FIRECRAWL_TIMEOUT_MS` | `30000` | Batas waktu per permintaan untuk eksekutor pengambilan web Firecrawl. |
| `API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS` | `300000` | Batas waktu keseluruhan permintaan server untuk bridge. |
| `API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS` | `60000` | Waktu untuk mengirim header respons melalui bridge. |
| `API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS` | `5000` | Batas waktu menganggur keep-alive bridge. |
| `API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS` | `0` | Batas waktu soket mentah (0 = dinonaktifkan). |
| `SHUTDOWN_TIMEOUT_MS` | `30000` | Masa tenggang saat SIGTERM/SIGINT sebelum keluar secara paksa. |
| `OMNIROUTE_DEFAULT_FETCH_TIMEOUT_MS` | `120000` | Nilai fallback yang digunakan oleh `src/shared/utils/fetchTimeout.ts` ketika `FETCH_TIMEOUT_MS` tidak diatur. |
| `OMNIROUTE_PROVIDER_PROBE_TIMEOUT_MS` | `8000` | Batas waktu (md) untuk preset `validationRead` dan `modelsProbe` di `src/shared/network/safeOutboundFetch.ts`. Naikkan untuk endpoint yang lambat (Cerebras, Cloudflare AI, Groq) guna mencegah status bolak-balik antara aktif/error di dasbor. Kembali ke 8000 md untuk nilai yang tidak valid (<1000) atau bukan numerik. |
| `OMNIROUTE_RELAY_FETCH_TIMEOUT_MS` | `25000` | Batas waktu fetch khusus relay di `open-sse/utils/proxyFetch.ts` (#9158). Relay yang macet harus gagal sebelum batas waktu klien/agen (~30 dtk) agar pemanggil melihat kegagalan khusus relay, bukan batas waktu upstream generik. Dibatasi maksimum `29000` agar selalu terpicu lebih dahulu. |
| `OMNIROUTE_RETRY_BACKOFF_MS` | `10` | Backoff percobaan ulang bersama untuk jalur percobaan ulang satu kali direct/relay/proxy di `open-sse/utils/proxyFetch.ts` (#9158). `0` = langsung mencoba ulang. |
| `OMNIROUTE_CLAUDE_TLS_TIMEOUT_MS` | `60000` | Batas waktu permintaan native wreq-js (`claudeTlsClient.ts`). |
| `OMNIROUTE_CLAUDE_TLS_GRACE_MS` | `10000` | Masa tenggang tenggat mutlak JS yang ditambahkan di atas batas waktu native. |
| `OMNIROUTE_PPLX_TLS_TIMEOUT_MS` | `30000` | Batas waktu permintaan native wreq-js (`perplexityTlsClient.ts`). |
| `OMNIROUTE_PPLX_TLS_GRACE_MS` | `10000` | Masa tenggang tenggat mutlak JS yang ditambahkan di atas batas waktu native. |
| `OMNIROUTE_PPLX_SEARCH_HINT` | `0` (nonaktif) | Menambahkan "Anda memiliki pencarian web bawaan. Jawab pertanyaan secara langsung menggunakan hasil pencarian." ke pesan sistem pemanggil (`perplexity-web/protocol.ts`). Nonaktif secara default — Perplexity tetap melakukan pencarian, dan kalimat tersebut bocor ke balasan sebagai komentar meta untuk klien pemrograman. Atur ke `1`/`true`/`yes`/`on` untuk memulihkannya. |
| `OMNIROUTE_GROK_TLS_TIMEOUT_MS` | `60000` | Batas waktu permintaan native wreq-js (`grokTlsClient.ts`). |
| `OMNIROUTE_GROK_TLS_GRACE_MS` | `10000` | Masa tenggang tenggat mutlak JS yang ditambahkan di atas batas waktu native. |
| `OMNIROUTE_NOTION_TLS_TIMEOUT_MS` | `30000` | Batas waktu permintaan native wreq-js (`notionTlsClient.ts`); `notion-web` menaikkannya per permintaan menjadi `180000` untuk generasi yang panjang. |
| `OMNIROUTE_NOTION_TLS_GRACE_MS` | `10000` | Masa tenggang tenggat mutlak JS yang ditambahkan di atas batas waktu native. |
| `OMNIROUTE_BROWSER_POOL` | `on` | Pool browser Playwright bersama untuk chat cookie web berbasis browser (`browserPool.ts`); atur ke `off` untuk menonaktifkannya. |
| `OBSCURA_BIN` | `auto-detect` | Jalur ke biner `obscura` yang digunakan sebagai mesin utama oleh pool browser dan eksekutor Cloudflare Playground (`open-sse/services/obscura.ts`); dideteksi secara otomatis dari PATH sistem jika tidak diatur. |
| `OBSCURA_CDP_ENDPOINT` | _(tidak diatur)_ | Arahkan ke Obscura yang sudah berjalan (`http://host:port`) alih-alih membuat proses baru; modul tidak memiliki proses tersebut (`open-sse/services/obscura.ts`). |
| `OBSCURA_PORT` | `random free port` | Port eksplisit untuk `obscura serve` yang dibuat; port kosong dipilih secara otomatis jika tidak diatur (`open-sse/services/obscura.ts`). |
| `WEB_COOKIE_USE_BROWSER` | `0` | Memilih agar permintaan chat cookie web menggunakan jalur berbasis browser (`browserBackedChat.ts`); `1` untuk mengaktifkan. |
| `KIMI_WEB_BASE_URL` | `https://www.kimi.ai` | URL dasar untuk eksekutor Kimi Web (Connect-RPC kimi.ai internasional) (`kimi-web.ts`); timpa hanya untuk endpoint mirror/proxy. |
| `KIMI_WEB_CHAT_URL` | `/apiv2/kimi.gateway.chat.v1.ChatService/Chat` | Endpoint chat lengkap untuk eksekutor Kimi Web (`kimi-web.ts`). |
| `OMNIROUTE_LOGIN_BROWSER_PATH` | _(terdeteksi otomatis)_ | Jalur ke executable Chrome/Edge sistem untuk proses masuk browser interaktif Adobe Firefly (`adobeFireflyBrowserLogin.ts`); menimpa deteksi otomatis per OS. |
| `OMNIROUTE_STANDALONE_DIR` | _output standalone .build/_ | Penimpaan waktu build untuk direktori output standalone yang digunakan oleh langkah kolokasi pasca-build (`scripts/build/colocate-standalone.mjs`); perkakas build, bukan runtime. |
Percobaan target combo mewarisi batas waktu permintaan upstream yang telah di-resolve (`FETCH_TIMEOUT_MS`, atau
`REQUEST_TIMEOUT_MS` saat variabel tersebut menyediakan nilai default fetch). Atur `targetTimeoutMs` dalam combo,
nilai default combo, atau penimpaan penyedia hanya agar fallback combo berlangsung lebih cepat; nilai di atas
batas waktu upstream saat ini dibatasi hingga batas waktu upstream.
`comboTimeoutMs` adalah anggaran waktu wall-clock terpisah untuk keseluruhan combo di semua target failover.
Biarkan tidak diatur atau atur ke `0` agar iterasi tidak terbatas tetap berlaku (penghenti kemacetan bawaan selama 10 menit di
`comboPredicates.ts` tetap berlaku). Nilai positif menggantikan
pengaman tersebut untuk combo. Pastikan `comboTimeoutMs` lebih lama daripada `targetTimeoutMs` agar failover
masih memiliki waktu setelah target pertama yang lambat.
### Ambang Batas Circuit Breaker
Penyesuaian circuit breaker tingkat penyedia. Nilai default mencerminkan nilai berskala yang digunakan sejak v3.6 untuk 500+ koneksi.
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------------------------------------- | --------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `OMNIROUTE_CIRCUIT_BREAKER_OAUTH_THRESHOLD` | `8` | `open-sse/config/constants.ts` | Ambang kegagalan berturut-turut untuk penyedia OAuth sebelum circuit breaker terpicu. |
| `OMNIROUTE_CIRCUIT_BREAKER_OAUTH_RESET_MS` | `60000` | `open-sse/config/constants.ts` | Jendela reset (md) untuk circuit breaker penyedia OAuth. |
| `OMNIROUTE_CIRCUIT_BREAKER_API_KEY_THRESHOLD` | `12` | `open-sse/config/constants.ts` | Ambang kegagalan berturut-turut untuk penyedia kunci API. |
| `OMNIROUTE_CIRCUIT_BREAKER_API_KEY_RESET_MS` | `30000` | `open-sse/config/constants.ts` | Jendela reset (md) untuk circuit breaker penyedia kunci API. |
| `OMNIROUTE_CIRCUIT_BREAKER_LOCAL_THRESHOLD` | `2` | `open-sse/config/constants.ts` | Ambang kegagalan berturut-turut untuk penyedia lokal (Ollama, LM Studio, ...). |
| `OMNIROUTE_CIRCUIT_BREAKER_LOCAL_RESET_MS` | `15000` | `open-sse/config/constants.ts` | Jendela reset (md) untuk circuit breaker penyedia lokal. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_FAILURE_THRESHOLD` | `10` | `open-sse/config/constants.ts` | Circuit breaker tingkat penyedia: jumlah kegagalan dalam jendela sebelum seluruh penyedia OAuth memasuki masa jeda. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_FAILURE_WINDOW_MS` | `900000` | `open-sse/config/constants.ts` | Circuit breaker tingkat penyedia: jendela penghitungan kegagalan bergulir (md) untuk penyedia OAuth. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_COOLDOWN_MS` | `300000` | `open-sse/config/constants.ts` | Circuit breaker tingkat penyedia: masa jeda (md) setelah ambang penyedia OAuth tercapai. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_DEGRADATION_THRESHOLD` | `5` | `open-sse/config/constants.ts` | Penyedia OAuth memasuki status DEGRADED saat mencapai jumlah kegagalan ini. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_MAX_BACKOFF_MULTIPLIER` | `8` | `open-sse/config/constants.ts` | Pengali maksimum peningkatan resetTimeout untuk penyedia OAuth. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_BACKOFF_ESCALATION_COUNT` | `2` | `open-sse/config/constants.ts` | Penyedia OAuth melakukan eskalasi setelah jumlah siklus terbuka ini. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_FAILURE_THRESHOLD` | `15` | `open-sse/config/constants.ts` | Circuit breaker tingkat penyedia: jumlah kegagalan dalam jendela sebelum seluruh penyedia kunci API memasuki masa jeda. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_FAILURE_WINDOW_MS` | `1800000` | `open-sse/config/constants.ts` | Circuit breaker tingkat penyedia: jendela penghitungan kegagalan bergulir (md) untuk penyedia kunci API. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_COOLDOWN_MS` | `600000` | `open-sse/config/constants.ts` | Circuit breaker tingkat penyedia: masa jeda (md) setelah ambang penyedia kunci API tercapai. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_DEGRADATION_THRESHOLD` | `7` | `open-sse/config/constants.ts` | Penyedia kunci API memasuki status DEGRADED saat mencapai jumlah kegagalan ini. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_MAX_BACKOFF_MULTIPLIER` | `4` | `open-sse/config/constants.ts` | Pengali maksimum peningkatan resetTimeout untuk penyedia kunci API. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_BACKOFF_ESCALATION_COUNT` | `3` | `open-sse/config/constants.ts` | Penyedia kunci API melakukan eskalasi setelah jumlah siklus terbuka ini. |
| `OMNIROUTE_PROVIDER_BREAKER_LOCAL_FAILURE_THRESHOLD` | `2` | `open-sse/config/constants.ts` | Circuit breaker tingkat penyedia: jumlah kegagalan sebelum seluruh penyedia lokal memasuki masa jeda. |
| `OMNIROUTE_PROVIDER_BREAKER_LOCAL_FAILURE_WINDOW_MS` | `300000` | `open-sse/config/constants.ts` | Circuit breaker tingkat penyedia: jendela penghitungan kegagalan bergulir (md) untuk penyedia lokal. |
| `OMNIROUTE_PROVIDER_BREAKER_LOCAL_COOLDOWN_MS` | `60000` | `open-sse/config/constants.ts` | Circuit breaker tingkat penyedia: masa jeda (md) setelah ambang penyedia lokal tercapai. |
| `PIN_DROP_BACKOFF_LEVEL` | `2` | `open-sse/services/combo.ts` | Kedalaman backoff saat penyedia milik pin cache konteks dianggap tidak sehat secara berkelanjutan dan pin tersebut dilepas untuk failover. |
| `PIN_DROP_GRACE_MS` | `20000` | `open-sse/services/combo.ts` | Jendela anti-flap (md) yang menoleransi masa jeda sementara singkat sebelum melepaskan pin cache konteks. |
### Skenario
| Skenario | Konfigurasi |
| -------------------------------------------- | ----------------------------------------------------- |
| **Pembuatan kode jangka panjang** | `REQUEST_TIMEOUT_MS=900000` (15 menit) |
| **Batasi total masa aktif stream** | `STREAM_ACTIVE_TIMEOUT_MS=1260000` (21 menit) |
| **Gagal cepat untuk API produksi** | `API_BRIDGE_PROXY_TIMEOUT_MS=10000` |
| **Model dengan pemikiran yang diperpanjang** | `STREAM_IDLE_TIMEOUT_MS=300000` (5 menit antar-chunk) |
---
## 16. Logging
Sistem logging menulis ke stdout dan file log yang dirotasi. Semua konfigurasi dibaca oleh `src/lib/logEnv.ts`.
| Variabel | Default | Deskripsi |
| ----------------------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `APP_LOG_LEVEL` | `info` | Level log minimum: `debug`, `info`, `warn`, `error`. |
| `APP_LOG_FORMAT` | `text` | Format output: `text` (mudah dibaca manusia) atau `json` (terstruktur). |
| `APP_LOG_TO_FILE` | `true` | Tulis log ke file selain ke stdout. |
| `APP_LOG_FILE_PATH` | `logs/application/app.log` | Jalur file log (relatif terhadap root proyek atau `DATA_DIR`). |
| `APP_LOG_MAX_FILE_SIZE` | `50M` | Ukuran file maksimum sebelum rotasi. Nilai yang diterima: `50M`, `1G`, `512K`, atau byte biasa. |
| `APP_LOG_RETENTION_DAYS` | `7` | Jumlah hari untuk menyimpan file log aplikasi yang telah dirotasi. |
| `APP_LOG_MAX_FILES` | `20` | Jumlah maksimum cadangan file log yang telah dirotasi. |
| `CALL_LOG_RETENTION_DAYS` | `7` | Jumlah hari untuk menyimpan entri log permintaan/panggilan dalam database. |
| `CALL_LOG_MAX_ENTRIES` | `10000` | Jumlah maksimum entri log panggilan dalam buffer memori. |
| `CALL_LOGS_TABLE_MAX_ROWS` | `100000` | Jumlah maksimum baris dalam tabel SQLite `call_logs` sebelum pemangkasan. |
| `ENABLE_REQUEST_LOGS` | _(tidak ditetapkan)_ | Paksa logging permintaan terperinci agar aktif atau nonaktif, dengan mengesampingkan pengaturan dasbor. |
| `MAX_PENDING_REQUEST_AGE_MS` | `3600000` (1 jam) | Usia maksimum entri log permintaan aktif yang tidak lagi terkait sebelum pembersihan dalam memori. |
| `CALL_LOG_PIPELINE_CAPTURE_STREAM_CHUNKS` | `false` | Simpan potongan stream dalam artefak pipeline saat `call_log_pipeline_enabled=true`. Harus diaktifkan secara eksplisit (`true`) — dinonaktifkan secara default untuk menghemat ruang disk. |
| `CALL_LOG_PIPELINE_MAX_SIZE_KB` | `512` | Ukuran maksimum artefak log panggilan pipeline dalam KB saat `call_log_pipeline_enabled=true`. |
| `PROXY_LOGS_TABLE_MAX_ROWS` | `100000` | Jumlah maksimum baris dalam tabel SQLite `proxy_logs` sebelum pemangkasan. |
| `PROXY_LOG_INCLUDE_IPS` | `false` | Sertakan IP klien/egress dan prefiks akun dalam log konsol `[ProxyEgress]`. Catatan log proxy di dasbor/database tetap menyimpan detail lengkap. |
| `APP_LOG_ROTATION_CHECK_INTERVAL_MS` | `60000` (1 menit) | Seberapa sering `src/lib/logRotation.ts` memeriksa ulang ukuran file log aktif. |
| `CHAT_LOG_TEXT_LIMIT` | `65536` | Panjang string maksimum yang dipertahankan dalam artefak log chat (default 64 KB). |
| `CHAT_LOG_ARRAY_TAIL_ITEMS` | `128` | Jumlah item array dari bagian akhir yang dipertahankan saat payload log chat dipangkas. |
| `CHAT_LOG_MAX_DEPTH` | `6` | Kedalaman penyarangan maksimum sebelum payload log chat dipangkas. |
| `CHAT_LOG_MAX_OBJECT_KEYS` | `80` | Jumlah maksimum kunci objek yang dipertahankan dalam payload log chat (0 = tanpa batas). |
| `CHAT_LOG_MAX_BODY_KB` | `1024` | Ukuran keseluruhan isi permintaan/respons (KB) sebelum diganti dengan ringkasan sederhana alih-alih salinan lengkap. Naikkan nilai ini jika percakapan agen yang panjang menampilkan placeholder alih-alih pesan sebenarnya di dasbor. |
| `CHAT_DEBUG_FILE` | `false` | Jika true, `serializeArtifactForStorage` melewati pemangkasan berdasarkan ukuran. Hanya untuk debugging. |
---
## 17. Optimasi Memori
| Variabel | Default | Deskripsi |
| ----------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_MEMORY_MB` | _otomatis_ (bare metal); **`1024` dalam image Docker** | Batas heap V8 (MB) yang **direkomendasikan** untuk Docker/standalone. Jika tidak ditetapkan, nilainya dikalibrasi secara dinamis (~35% RAM sistem, dibatasi pada `[512, 4096]`); `512` hanya menjadi batas minimum ketika total memori tidak dapat dibaca. Pada `run-standalone.mjs` (Docker CMD), nilai yang **ditentukan secara eksplisit** ditambahkan sebagai `--max-old-space-size` dan **mengalahkan** flag heap NODE_OPTIONS yang bertentangan (flag terakhir V8). `omniroute serve` tetap memprioritaskan flag heap NODE_OPTIONS yang sudah ada (#5238). Jangan tetapkan keduanya ke angka yang berbeda — proses akan mencatat peringatan yang menyebutkan kedua nilai tersebut dan nilai mana yang digunakan. **Image Docker resmi selalu menetapkan `1024`, sehingga kalibrasi tidak pernah dijalankan di sana.** Coding-agent `/v1/responses` memerlukan `8192`–`12288` ditambah ruang ekstra cgroup — lihat [Panduan Docker — RAM runtime](../guides/DOCKER_GUIDE.md#runtime-ram-for-coding-agents). |
| `PROMPT_CACHE_MAX_SIZE` | `50` | Jumlah maksimum entri prompt sistem yang disimpan dalam cache. |
| `PROMPT_CACHE_MAX_BYTES` | `2097152` (2 MB) | Ukuran total maksimum cache prompt. |
| `PROMPT_CACHE_TTL_MS` | `300000` (5 menit) | TTL entri cache prompt. |
| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Jumlah maksimum respons dengan temperature=0 yang disimpan dalam cache. |
| `SEMANTIC_CACHE_MAX_BYTES` | `4194304` (4 MB) | Ukuran total maksimum cache semantik. |
| `SEMANTIC_CACHE_TTL_MS` | `1800000` (30 menit) | TTL entri cache semantik. |
| `OMNIROUTE_CORPUS_CACHE_SIZE` | `5` | Root korpus lokal yang secara bersamaan mempertahankan indeks aktif dalam memori (`src/lib/localCorpus/configured.ts`). LRU: saat mencapai batas, indeks root yang paling lama tidak digunakan dikeluarkan dan dibangun ulang pada kueri berikutnya. Dibatasi ke nilai minimum `1`; nilai nonnumerik akan kembali ke nilai default. |
| `STREAM_HISTORY_MAX` | `50` | Jumlah maksimum peristiwa stream terbaru dalam buffer tampilan langsung Dasbor. |
| `CONTEXT_LENGTH_DEFAULT` | `128000` | Batas maksimum panjang konteks cadangan global untuk model tanpa konfigurasi eksplisit. |
| `USAGE_TOKEN_BUFFER` | `100` | Ruang ekstra token yang dicadangkan saat melacak kuota penggunaan. |
### Kompresi
| Variabel | Default | Deskripsi |
| ------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_RTK_TRUST_PROJECT_FILTERS` | tidak ditetapkan | Percayai `.rtk/filters.json` proyek tanpa hash `.rtk/trust.json`. Gunakan hanya dalam pengembangan lokal yang terkontrol. |
### Mesin Memori (rencana 21)
### Biaya event loop untuk memori, keterampilan, dan penyegaran token (#10349)
OmniRoute adalah **satu proses Node**. Ekstraksi/pengambilan memori, injeksi keterampilan, dan penyegaran token penyedia berjalan pada **event loop yang sama** dengan `GET /healthz` dan dasbor. Semua itu bukan thread pekerja.
| Pekerjaan | Kode | Default | Kontrol operator |
| ---------------------------- | ---------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Ekstraksi/pengambilan memori | `src/lib/memory/` | **memoryEnabled** di dasbor (aktif secara default) | Nonaktifkan **Settings → Memory**. Tidak ada kill switch env terpisah selain menonaktifkan fitur tersebut di pengaturan. |
| Injeksi skills | `src/lib/skills/injection.ts` | **skillsEnabled** di dasbor (aktif secara default) | Nonaktifkan **Settings → Memory/Skills** (`skillsEnabled`). Opsi sandbox di bawah hanya membatasi eksekusi setelah injeksi diaktifkan. |
| Penyegaran token | `src/sse/services/tokenRefresh.ts` | Aktif untuk penyedia OAuth/web yang terhubung | Putuskan koneksi penyedia atau biarkan token tetap valid; saat ini tidak ada env `TOKEN_REFRESH=0`. |
Jika `/healthz` lambat pada mesin yang sedang tidak sibuk, nonaktifkan memori + skills terlebih dahulu, lalu periksa beban katalog/kompresi (#10303, #9685). Fitur-fitur ini menyerahkan eksekusi pada titik `await`, tetapi tetap bersaing menggunakan satu thread.
Opsi lapisan embedding, penyimpanan vektor, dan reranking untuk subsistem memori persisten (`src/lib/memory/`).
| Variabel | Default | Deskripsi |
| ------------------------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MEMORY_EMBEDDING_CACHE_TTL_MS` | `300000` (5 menit) | TTL untuk cache embedding dalam memori (per tanda tangan sumber/model/dimensi). |
| `MEMORY_EMBEDDING_CACHE_MAX` | `1000` | Jumlah maksimum entri LRU yang dipertahankan dalam cache embedding. |
| `MEMORY_TRANSFORMERS_MODEL` | `Xenova/all-MiniLM-L6-v2` | ID repo HF untuk pipeline MiniLM lokal `@huggingface/transformers` yang bersifat opt-in (~23 MB int8, ~400 MB RAM). |
| `MEMORY_STATIC_MODEL` | `minishlab/potion-base-8M` | ID repo HF untuk embedder tabel pencarian potion/Model2Vec statis. Diunduh secara lazy ke dalam direktori cache. |
| `MEMORY_STATIC_CACHE_DIR` | `/embeddings` | Direktori yang digunakan untuk menyimpan cache file model potion statis. Secara default berada di bawah `DATA_DIR` jika tidak ditetapkan. |
| `HF_HUB_ENDPOINT` | `https://huggingface.co` | Mengganti URL dasar Hugging Face Hub yang digunakan oleh `staticPotion.ts` (misalnya endpoint mirror untuk lingkungan air-gapped). |
| `MEMORY_VEC_TOP_K` | `20` | Nilai top-K default yang digunakan oleh pencarian vektor brute-force `sqlite-vec` dalam `src/lib/memory/vectorStore.ts`. |
| `MEMORY_RRF_K` | `60` | Konstanta Reciprocal Rank Fusion `k` untuk pengambilan hibrida FTS5 + vektor (resep sqlite-vec). |
| `VECTOR_STORE_DISABLE_VEC` | `false` | Titik pengujian/diagnostik dalam `getVectorStore()` (`src/lib/memory/vectorStore.ts`): jika `true`, memaksa penyimpanan vektor menjadi `null` (menyimulasikan lingkungan cloud/WASM tanpa `sqlite-vec`), sehingga pengambilan memori menurun menjadi pencarian kata kunci FTS5. Biarkan tidak ditetapkan dalam produksi. |
| `NOTION_API_KEY` | _(tidak ditetapkan)_ | Kunci API untuk backend Notion (digunakan oleh preset backend yang dikenal dalam `genericBackend.ts`). |
| `NOTION_API_URL` | `https://api.notion.com/v1` | URL dasar untuk API Notion (dapat diganti untuk alternatif Notion yang di-host sendiri). |
| `OBSIDIAN_API_KEY` | _(tidak ditetapkan)_ | Kunci API untuk backend Obsidian Vault (digunakan oleh preset backend yang dikenal dalam `genericBackend.ts`). |
| `OBSIDIAN_API_URL` | `http://localhost:27123` | URL dasar untuk API Obsidian Vault (dapat diganti untuk vault jarak jauh). |
| `MEMORY_TYPED_DECAY_ENABLED` | `false` | Sakelar utama peluruhan memori bertipe TV6. **Opt-in (nonaktif secara default)** — sweep akan **menghapus** memori yang telah meluruh. Jika dinonaktifkan, `access_count`/`last_accessed_at` hanya merupakan telemetri dan tidak ada yang pernah dihapus. |
| `MEMORY_TYPED_DECAY_EPISODIC_DAYS` | `30` | TTL (hari) setelah memori `episodic` yang tidak digunakan akan meluruh. `0` juga membuat memori episodik kebal. Tipe tahan lama (`factual`/`procedural`/`semantic`) selalu kebal. Waktu peluruhan ditetapkan ulang berdasarkan `last_accessed_at`. |
| `MEMORY_TYPED_DECAY_ACCESS_IMMUNITY` | `3` | Memori yang telah diinjeksi sebanyak `>=` jumlah ini menjadi kebal terhadap peluruhan, apa pun tipenya. `0` menonaktifkan kekebalan berdasarkan akses. |
| `MEMORY_TYPED_DECAY_SWEEP_INTERVAL` | `0` (dinonaktifkan) | Interval (detik) untuk sweep peluruhan berkala opsional dalam `src/lib/memory/typedDecay.ts`. `0`/tidak ditetapkan = tidak ada sweep berkala. Memerlukan opt-in ganda: `MEMORY_TYPED_DECAY_ENABLED=true` juga harus ditetapkan. |
| `OMNIROUTE_STRICT_SYSTEM_PROVIDERS` | _(tidak ditetapkan)_ | ID penyedia yang dipisahkan koma (tidak peka huruf besar-kecil) yang menerima pesan `system` **hanya pada indeks 0** (`src/lib/memory/injection.ts`). Untuk penyedia ini, penyisipan memori di tengah array yang aman bagi cache tidak aman dalam percakapan multi-turn, sehingga memori digabungkan/ditambahkan di awal sebagai pesan system pertama. Secara default hanya `xiaomi-mimo`/`mimo`; perluas untuk endpoint kompatibel OpenAI yang di-host sendiri (misalnya Qwen3.5+/3.6) jika template chat-nya menerapkan batasan satu pesan system di awal yang sama. |
### Contoh Docker dengan RAM Rendah
`128` hanya untuk dasbor. Agen coding pada heap ini mengalami `FATAL ERROR` selama `/v1/responses` yang panjang. Jangan gunakan contoh ini sebagai gateway Claude/Codex/Grok.
```bash
OMNIROUTE_MEMORY_MB=128
PROMPT_CACHE_MAX_SIZE=20
PROMPT_CACHE_MAX_BYTES=524288 # 512 KB
SEMANTIC_CACHE_MAX_SIZE=25
SEMANTIC_CACHE_MAX_BYTES=1048576 # 1 MB
STREAM_HISTORY_MAX=10
```
---
## 18. Sinkronisasi Harga
Sinkronisasi otomatis data harga model dari sumber eksternal.
| Variabel | Default | File Sumber | Deskripsi |
| ----------------------- | ------------- | ------------------------ | -------------------------------------------------- |
| `PRICING_SYNC_ENABLED` | `false` | `src/lib/pricingSync.ts` | Sinkronisasi harga berkala yang bersifat opsional. |
| `PRICING_SYNC_INTERVAL` | `86400` (24h) | `src/lib/pricingSync.ts` | Interval sinkronisasi dalam detik. |
| `PRICING_SYNC_SOURCES` | `litellm` | `src/lib/pricingSync.ts` | Sumber data yang dipisahkan dengan koma. |
---
## Sinkronisasi ELO Arena
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------------- | ------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ARENA_ELO_SYNC_ENABLED` | `true` | `src/shared/constants/featureFlagDefinitions.ts` | Sinkronisasi ELO berkala untuk papan peringkat Arena AI, dapat dikonfigurasi dari Feature Flags Dasbor atau dinonaktifkan dengan `false`. |
| `MODELS_CATALOG_PREFIX_MODE` | `dual` | `src/shared/constants/featureFlagDefinitions.ts`, `src/app/api/v1/models/catalog.ts` | Bentuk prefiks yang digunakan untuk ID model dalam `GET /v1/models`. `dual` mengumumkan prefiks alias pendek dan prefiks penyedia kanonis untuk setiap model (kompatibilitas mundur — ukuran katalog menjadi kira-kira dua kali lipat); `alias` menghasilkan satu ID per model; `canonical` hanya menghasilkan prefiks ID penyedia lengkap (penyedia yang aliasnya sudah merupakan ID kanonis tetap memiliki satu entri). Klien dapat menggantinya untuk setiap permintaan dengan `?prefix=alias`. Lihat [API_REFERENCE](API_REFERENCE.md#model-id-prefixes-prefix). |
| `ARENA_ELO_SYNC_INTERVAL` | `86400` (24h) | `src/lib/arenaEloSync.ts` | Interval sinkronisasi dalam detik. |
---
## Penyedia Playground PromptQL (Tidak Resmi/Eksperimental)
Jembatan sesi GraphQL hasil rekayasa balik untuk prompt.ql.app (`src/shared/constants/providers/web-cookie.ts`). Semuanya bersifat opsional — nilai default mengarah ke endpoint playground publik; ganti hanya untuk deployment PromptQL yang di-host sendiri/alternatif.
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `PROMPTQL_GRAPHQL_ENDPOINT` | `https://data.prompt.ql.app/promptql/playground-v2-hge/v1/graphql` | `open-sse/executors/promptql.ts` | Endpoint GraphQL yang digunakan untuk operasi obrolan/sesi. |
| `PROMPTQL_CREDITS_ENDPOINT` | `https://data.pro.ql.app/v1/graphql` | `open-sse/executors/promptql.ts`, `open-sse/services/usage/promptql.ts` | Endpoint GraphQL yang digunakan untuk meminta informasi saldo/penggunaan kredit. |
| `PROMPTQL_TOKEN_REFRESH_URL` | `https://auth.pro.ql.app/ddn/project/token` | `open-sse/executors/promptql.ts` | Endpoint yang digunakan untuk penyegaran token dengan upaya terbaik. |
| `PROMPTQL_POLL_TIMEOUT_MS` | `180000` | `open-sse/executors/promptql.ts` | Waktu maksimum (ms) untuk melakukan polling `thread_events` sebelum kehabisan waktu. |
---
## Penyedia Web HyperAgent (Tidak Resmi/Eksperimental)
Jembatan sesi hasil rekayasa balik untuk hyperagent.com (`src/shared/constants/providers/web-cookie.ts`). Opsional — nilai default mengarah ke endpoint penagihan/penggunaan publik; ubah hanya untuk deployment HyperAgent yang di-host sendiri/alternatif.
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------- | --------------------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------- |
| `HYPERAGENT_USAGE_URL` | `https://hyperagent.com/api/settings/billing/usage` | `open-sse/services/usage/hyperagent.ts` | Endpoint yang digunakan untuk mengambil blok kredit penagihan/penggunaan. |
---
## Kuota Penggunaan Kilo Code
Pencarian saldo USD pribadi dan penggunaan Kilo Pass untuk penyedia Kilo Code. Opsional — nilai default mengarah ke API Kilo publik; ubah hanya untuk relai/fixture pengujian. Autentikasi menggunakan token akses OAuth yang sudah ada pada koneksi.
| Variabel | Default | File Sumber | Deskripsi |
| -------------- | --------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------ |
| `KILO_API_URL` | `https://api.kilo.ai` | `open-sse/services/usage/kilocode.ts` | URL dasar yang digunakan untuk mengambil saldo Kilo Code pribadi dan penggunaan Kilo Pass. |
---
## Penyedia Web Adobe Firefly (Tidak Resmi/Eksperimental)
Penyegaran sesi berbasis browser untuk penyedia web Adobe Firefly
(`open-sse/services/adobeFireflyBrowserLogin.ts`, `open-sse/services/adobeFireflySession.ts`,
`open-sse/services/adobeFireflyClient.ts`). Opsional — semua nilai default telah disesuaikan untuk instalasi
desktop normal.
> **Dihapus dalam #9255.** Runtime Chrome lama yang terhubung melalui CDP (adobeFireflyChromeRuntime.ts)
> digantikan oleh layanan login browser Playwright, dan opsi konfigurasinya tidak lagi tersedia. Variabel
> ADOBE_FIREFLY_CHROME_ CDP_PORT / VISIBLE / HEADED / PING / FORCE_RESTART, beserta
> ADOBE_FIREFLY_LOGIN_WAIT_MS dan ADOBE_FIREFLY_FORTER_WAIT_MS, tidak dibaca di bagian mana pun dalam
> basis kode — menetapkannya tidak akan memberikan efek apa pun.
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------------ | ---------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ADOBE_FIREFLY_CHROME_HEADLESS` | `0` | `open-sse/services/adobeFireflyBrowserLogin.ts` | Atur ke `1` untuk Chrome yang benar-benar headless (diketahui tidak berfungsi untuk pembuatan; hanya untuk debugging). |
| `ADOBE_FIREFLY_BROWSER_REFRESH` | `1` | `open-sse/services/adobeFireflySession.ts` | Pilihan untuk mengaktifkan/menonaktifkan pemanasan browser proaktif. `0` menonaktifkan pemanasan proaktif (pemulihan 408 di tengah batch tetap berlaku). |
| `ADOBE_FIREFLY_SESSION_DISK` | `1` | `open-sse/services/adobeFireflySession.ts` | Atur ke `0` untuk menonaktifkan penyimpanan sesi Adobe Firefly ke disk. |
| `ADOBE_FIREFLY_MIN_SUBMIT_GAP_MS` | _(tidak diatur)_ | `open-sse/services/adobeFireflySession.ts` | Jeda minimum (ms) yang diberlakukan di antara pengiriman berturut-turut, menggantikan nilai default bawaan. |
| `ADOBE_FIREFLY_BATCH_EXTRA_GAP_MS` | _(tidak diatur)_ | `open-sse/services/adobeFireflySession.ts` | Jeda tambahan (ms) yang ditambahkan setelah batch berhasil, menggantikan nilai default bawaan. |
| `ADOBE_FIREFLY_SUBMIT_BASE_DELAY_MS` | _(tidak diatur)_ | `open-sse/services/adobeFireflyClient.ts` | Penundaan dasar (ms) sebelum mengirimkan permintaan pembuatan, menggantikan nilai default bawaan. |
---
## 19. Sinkronisasi Model (Dev)
| Variabel | Default | File Sumber | Deskripsi |
| ----------------------------------- | ---------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `MODELS_DEV_SYNC_ENABLED` | _(tidak diatur)_ | `src/lib/modelsDevSync.ts` | Penggantian paksa untuk sinkronisasi harga models.dev. Tidak diatur = ikuti Pengaturan > AI (`modelsDevSyncEnabled`). `0`/`false`/`off`/`no` **mengalahkan DB** dan melewati sinkronisasi berkala maupun pemindaian SQL/JSON `getModelsDevPricing()` (pemulihan ketika dasbor macet pada event loop yang sama). `1`/`true`/`on`/`yes` memaksa sinkronisasi aktif. Penyimpanan/penghapusan harga tetap memanggil `backupDbFile("pre-write")`, yang tidak melakukan apa pun selama pembatasan 60 menit atau ketika `DISABLE_SQLITE_AUTO_BACKUP` berlaku. |
| `MODELS_DEV_SYNC_INTERVAL` | `86400` (24 jam) | `src/lib/modelsDevSync.ts` | Interval sinkronisasi katalog model saat pengembangan, dalam detik. |
| `CONTEXT_WINDOW_RECONCILE_INTERVAL` | `86400` (24 jam) | `src/lib/contextWindowResolver.ts` | Interval (detik) untuk rekonsiliator jendela konteks yang melakukan koreksi mandiri (5004): menetapkan jendela yang dideklarasikan penyedia dari penemuan `/models` sebagai penggantian `auto:discovery` ketika berbeda dari katalog. Atur ke `0` untuk menonaktifkannya. Menggunakan kembali data yang telah disinkronkan (tanpa pengambilan baru); tidak pernah menimpa penggantian `manual`. |
---
## 20. Pengaturan Khusus Penyedia
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OPENROUTER_CATALOG_TTL_MS` | `86400000` (24 jam) | `src/lib/catalog/openrouterCatalog.ts` | TTL cache katalog model OpenRouter. |
| `MODEL_CATALOG_INCLUDE_NAMES` | `true` | `src/shared/constants/featureFlagDefinitions.ts` | Sertakan bidang `name` yang mudah dibaca dalam respons `/v1/models`. Nonaktifkan untuk klien yang hanya mengharapkan ID. |
| `CATALOG_BUILD_TIMEOUT_MS` | `8000` (8 detik) | `src/app/api/v1/models/catalogCache.ts` | Batas waktu tunggu jalur dingin untuk pembangunan ulang katalog `GET /v1/models` yang digabungkan (#12627). Jika waktu habis, respons 200 terakhir yang valid akan disajikan jika tersedia. |
| `OMNIROUTE_SYNCED_CATALOG_STALE_AFTER_MS` | `2592000000` (30 hari) | `src/lib/db/models/activeSyncedCatalog.ts` | Jangka waktu setelah daftar model tersinkron milik suatu koneksi berhenti dianggap otoritatif untuk perutean dan beralih secara terbuka ke registri (#12849). Baris yang tidak pernah diberi stempel waktu dianggap kedaluwarsa. |
| `NANOBANANA_POLL_TIMEOUT_MS` | `120000` | `open-sse/handlers/imageGeneration.ts` | Waktu tunggu maksimum untuk tugas pembuatan gambar NanoBanana. |
| `NANOBANANA_POLL_INTERVAL_MS` | `2500` | `open-sse/handlers/imageGeneration.ts` | Frekuensi polling tugas NanoBanana. |
| `ADOBE_FIREFLY_SUBMIT_BASE_DELAY_MS` | `8000` | `open-sse/services/adobeFireflyUpscale.ts` | Penundaan dasar untuk backoff eksponensial percobaan ulang pengiriman peningkatan skala Adobe Firefly. |
| `AWS_REGION` | _(tidak diatur)_ | `src/lib/providers/validation.ts`, `open-sse/handlers/audioSpeech.ts` | Wilayah yang digunakan untuk membuat endpoint AWS Bedrock (Kiro, audio). |
| `AWS_DEFAULT_REGION` | _(tidak diatur)_ | `src/lib/providers/validation.ts`, `open-sse/handlers/audioSpeech.ts` | Nilai cadangan ketika `AWS_REGION` tidak diatur. |
| `CLOUDFLARE_ACCOUNT_ID` | _(tidak diatur)_ | `open-sse/executors/cloudflare-ai.ts` | ID akun untuk Cloudflare Workers AI. |
| `CLOUDFLARE_PLAYGROUND_CHROME_PATH` | _(tidak diatur)_ | `open-sse/executors/cloudflare-playground.ts` | Path lengkap biner Chrome desktop untuk eksekutor Cloudflare AI Playground, digunakan ketika pemeriksaan sidik jari headless memblokir Chromium bawaan Playwright. |
| `CLOUDFLARE_API_BASE` | `https://api.cloudflare.com/client/v4` | `src/app/api/settings/proxy/cloudflare-deploy/route.ts` | Ganti basis API REST Cloudflare yang digunakan oleh penyebar relai Workers kumpulan proksi (#4640 / 9router#1360). |
| `NEXT_PUBLIC_CLOUDFLARE_RELAY_DEFAULT_PROJECT` | `omniroute-relay` | `src/app/(dashboard)/dashboard/settings/components/proxy/CloudflareRelayModal.tsx` | Nama proyek worker default yang disarankan dalam modal "Deploy Relay" pada kumpulan proksi. |
| `NEXT_PUBLIC_CLOUDFLARE_RELAY_ENABLED` | `true` | `src/app/(dashboard)/dashboard/settings/components/proxy/ProxyPoolTab.tsx` | Atur ke `false` untuk menyembunyikan opsi relai Cloudflare Workers dari tab Proxy Pool. |
| `CLOUDFLARED_BIN` | deteksi otomatis | `src/lib/cloudflaredTunnel.ts` | Path khusus ke biner `cloudflared`. |
| `CLOUDFLARED_PROTOCOL` | `http2` | `src/lib/cloudflaredTunnel.ts` | Protokol transportasi tunnel: `http2` (default), `quic`, atau `auto`. |
| `CLOUDFLARED_CONFIG` | _(tidak diatur)_ | `src/lib/cloudflaredTunnel.ts` | Path ke `config.yml` cloudflared yang dikelola secara lokal (dengan `tunnel:`, `credentials-file:`, `ingress:`). Jika diatur, OmniRoute menjalankan `tunnel --config run` (tunnel bernama), bukan tunnel cepat sementara. |
| `CLOUDFLARED_HOSTNAME` | _(dari ingress konfigurasi)_ | `src/lib/cloudflaredTunnel.ts` | Penggantian untuk nama host publik tunnel bernama (misalnya `ai.example.com`), yang dilaporkan sebagai `publicUrl`/`apiUrl`. Jika tidak diatur, nilainya dibaca dari nama host `ingress` pertama dalam konfigurasi. |
| `DENO_DEPLOY_API_BASE` | `https://api.deno.com/v2` | `src/app/api/settings/proxy/deno-deploy/route.ts` | Menimpa basis REST API Deno Deploy yang digunakan oleh penerap relay proxy-pool (#4643 / 9router#1437). |
| `NEXT_PUBLIC_DENO_RELAY_DEFAULT_PROJECT` | `omniroute-deno-relay` | `src/app/(dashboard)/dashboard/settings/components/proxy/DenoRelayModal.tsx` | Nama aplikasi Deno Deploy default yang disarankan dalam modal "Deploy Relay" proxy-pool. |
| `NEXT_PUBLIC_DENO_RELAY_ENABLED` | `true` | `src/app/(dashboard)/dashboard/settings/components/proxy/ProxyPoolTab.tsx` | Atur ke `false` untuk menyembunyikan opsi relay Deno Deploy dari tab Proxy Pool. |
| `SEARCH_CACHE_TTL_MS` | `300000` (5 menit) | `open-sse/services/searchCache.ts` | TTL untuk penyimpanan cache respons API pencarian (Perplexity, Brave, dll.). |
| `ENABLE_CC_COMPATIBLE_PROVIDER` | `false` | `src/shared/utils/featureFlags.ts` | Menampilkan UI penyedia kompatibel dengan CC yang eksperimental untuk relay khusus Claude Code. |
| `NINEROUTER_HOST` | `127.0.0.1` | `open-sse/executors/ninerouter.ts` | Menimpa host tempat instans 9router tertanam mendengarkan. |
| `NINEROUTER_PORT` | `20130` | `open-sse/executors/ninerouter.ts` | Menimpa port tempat instans 9router tertanam mendengarkan. |
| `EMBED_WS_PROXY_HOST` | `127.0.0.1` | `src/lib/services/embedWsProxy.ts` | Host pengikatan untuk proksi WebSocket layanan tertanam (secara default hanya loopback). |
| `EMBED_WS_PROXY_PORT` | `20131` | `src/lib/services/embedWsProxy.ts` | Port untuk server proksi WebSocket layanan tertanam. |
| `CLIPROXYAPI_HOST` | `127.0.0.1` | `open-sse/executors/cliproxyapi.ts` | Host bridge CLIProxyAPI (integrasi lama). |
| `CLIPROXYAPI_PORT` | `5544` | `open-sse/executors/cliproxyapi.ts` | Port bridge CLIProxyAPI. |
| `CLIPROXYAPI_API_KEY` | _(kosong)_ | `open-sse/handlers/chatCore/cliproxyapiCredentials.ts` | Kunci cadangan bidang data ketika pengaturan `cliproxyapi_api_key` tidak tersedia. |
| `CLIPROXYAPI_MANAGEMENT_KEY` | _(kosong)_ | `src/lib/services/cliproxyAccountHealth.ts` | Kunci manajemen untuk membaca kesehatan akun dari instans CLIProxyAPI yang dikelola secara eksternal. |
| `CLIPROXYAPI_CONFIG_DIR` | `~/.cli-proxy-api` | `src/lib/versionManager/processManager.ts` | Direktori konfigurasi CLIProxyAPI. |
| `CLIPROXY_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Antarmuka host tempat docker-compose memublikasikan sidecar `cliproxyapi` (#12578). Volume datanya menyimpan kredensial OAuth/API penyedia dan image yang disematkan tidak memiliki penimpaan `api-keys` bidang data berbasis env (hanya `config.yaml` yang dipasang), sehingga `0.0.0.0` mengekspos layanan yang memuat kredensial ke seluruh LAN. |
| `MUX_SERVICE_PORT` | `8322` | `src/lib/services/bootstrap.ts` | Menimpa port tempat daemon orkestrasi agen Mux (coder/mux) tertanam mendengarkan (selalu 127.0.0.1). |
| `OPENWA_SERVICE_PORT` | `8323` | `src/lib/services/bootstrap.ts` | Menimpa port tempat daemon open-wa (otomatisasi WhatsApp Web) tertanam mendengarkan (selalu 127.0.0.1). |
| `DARIO_HOST` | `127.0.0.1` | `open-sse/executors/dario.ts` | Host pengikatan/koneksi layanan tertanam Dario (secara default hanya loopback). |
| `DARIO_PORT` | `3456` | `open-sse/executors/dario.ts` | Port layanan tertanam Dario. |
| `DARIO_HOST` | `127.0.0.1` | `open-sse/executors/dario.ts` | Host pengikatan/koneksi layanan tertanam Dario (secara default hanya loopback). |
| `DARIO_PORT` | `3456` | `open-sse/executors/dario.ts` | Port layanan tertanam Dario. |
| `LOCAL_HOSTNAMES` | _(kosong)_ | `open-sse/config/providerRegistry.ts` | Nama host tambahan yang dipisahkan koma dan diperlakukan sebagai "lokal" (nama layanan Docker, dll.). |
`ENABLE_CC_COMPATIBLE_PROVIDER` hanya ditujukan untuk relay pihak ketiga yang secara eksklusif menerima klien Claude Code.
OmniRoute menulis ulang permintaan agar relay tersebut dapat menerimanya. Jika Anda hanya ingin menggunakan
Claude Code CLI, atau tidak yakin dengan relay yang dimaksud, biarkan opsi ini dinonaktifkan dan tambahkan
penyedia reguler yang kompatibel dengan Anthropic sebagai gantinya.
---
## 21. Kesehatan Proxy
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PROXY_FAST_FAIL_TIMEOUT_MS` | `2000` | `src/lib/proxyHealth.ts` | Batas waktu pemeriksaan kesehatan fast-fail. |
| `PROXY_LATENCY_WINDOW_HOURS` | `3` | `src/lib/db/proxies.ts` | Rentang waktu (jam) untuk menghitung latensi rata-rata proxy kandidat dalam strategi kumpulan yang dioptimalkan untuk latensi. |
| `PROXY_HEALTH_CACHE_TTL_MS` | `30000` | `src/lib/proxyHealth.ts` | TTL cache hasil pemeriksaan kesehatan. |
| `PROXY_HEALTH_UNHEALTHY_CACHE_TTL_MS` | `2000` | `src/lib/proxyHealth.ts` | TTL cache untuk pemeriksaan kesehatan proxy yang gagal. Tetapkan agar lebih singkat daripada `PROXY_HEALTH_CACHE_TTL_MS` sehingga batas waktu proxy sementara pada konkurensi tinggi dapat dicoba ulang dengan cepat tanpa menonaktifkan fast-fail untuk proxy yang benar-benar mati. |
| `PROXY_HEALTH_ENABLED` | `true` | `src/lib/proxyHealth/scheduler.ts` | Tetapkan ke `false` untuk menonaktifkan penjadwal kesehatan proxy latar belakang yang secara berkala memeriksa proxy terdaftar. |
| `PROXY_HEALTH_INTERVAL_MS` | `600000` | `src/lib/proxyHealth/scheduler.ts` | Interval pemindaian penjadwal kesehatan latar belakang dalam milidetik (minimum `60000`). |
| `PROXY_HEALTH_RECOVERY_INTERVAL_MS` | `600000` | `src/lib/proxyHealth/scheduler.ts` | Interval proses pemulihan latar belakang dalam ms: seberapa sering proksi yang sebelumnya tidak sehat diperiksa ulang agar proksi yang telah pulih kembali ke rotasi tanpa perlu memulai ulang. Nilai di bawah `60000` akan kembali ke nilai default. |
| `PROXY_HEALTH_TEST_URL` | `https://httpbin.org/ip` | `src/lib/proxyHealth/probeTarget.ts` | Target pemeriksaan keterjangkauan yang digunakan oleh penjadwal dan endpoint `/api/settings/proxies/auto-test`. Arahkan ke URL internal/yang di-host sendiri untuk menghindari penggunaan target publik default. |
| `PROXY_HEALTH_TEST_CONCURRENCY` | `10` | `src/lib/proxyHealth/probeTarget.ts` | Jumlah pemeriksaan yang dimulai sekaligus per batch, digunakan bersama oleh penjadwal dan endpoint `/api/settings/proxies/auto-test`. Nilai minimum dibulatkan menjadi 1 dan dibatasi hingga maksimum 50. |
| `PROXY_HEALTH_TEST_STAGGER_MS` | `100` | `src/lib/proxyHealth/probeTarget.ts` | Jeda dalam ms di antara dua pemeriksaan yang dikirim dalam satu batch. Tanpa jeda ini, seluruh batch dikirim pada saat yang sama dan IP egress bersama dapat memicu pembatasan laju pada target. Atur ke `0` untuk menonaktifkan jeda; dibatasi hingga maksimum 5000. |
| `PROXY_HEALTH_USE_PROVIDER_TARGET` | `true` | `src/lib/proxyHealth/providerProbeTarget.ts` | Atur ke "false" untuk berhenti memeriksa host sebenarnya dari penyedia yang ditetapkan ke proksi (`GET /models`, tanpa kunci API) dan selalu menggunakan `PROXY_HEALTH_TEST_URL` sebagai gantinya. |
| `PROXY_HEALTH_AUTO_DEACTIVATE` | `false` | `src/lib/proxyHealth/statusPolicy.ts` | Saat `false` (default), pemeriksaan keterjangkauan otomatis (penjadwal + tombol "Test All" pada `/api/settings/proxies/auto-test`) bersifat **hanya-baca** dan tidak pernah mengubah status proksi — hanya operator yang menetapkan aktif/tidak aktif, sehingga pemeriksaan yang tidak stabil tidak membuat proksi yang telah ditetapkan menjadi tidak dapat digunakan (#6246). Atur ke `true` untuk memulihkan perilaku lama, yaitu menguji dan menetapkan status. |
| `FLUSH_EMPTY_RETRY_ENABLED` | `false` | `src/shared/utils/featureFlags.ts` | Flag fitur opsional (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); penggantian nilai melalui DB dasbor akan diprioritaskan). `true` (atau `1`, `yes`) mencoba ulang giliran streaming hasil terjemahan yang kosong melalui jalur kredensial normal (hingga `STREAM_RECOVERY.EMPTY_TURN_RETRY_MAX` kali percobaan ulang), alih-alih menampilkan respons 200 kosong atau 502 dengan konten kosong. |
| `PROXY_POOL_EGRESS_OBSERVATION` | `false` | `src/shared/utils/featureFlags.ts` | Flag fitur opsional (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); penggantian nilai melalui DB dasbor akan diprioritaskan). `true` (atau `1`, `yes`) menampilkan pengamatan egress kumpulan yang hanya-baca di bawah kumpulan proksi pada dasbor (IP egress yang berbeda, jumlah koneksi, dan jumlah terbanyak yang teramati di balik satu IP selama 24 jam terakhir, berdasarkan log proksi). Tidak pernah digunakan untuk perutean. |
| `PROXY_AUTO_REMOVE` | `false` | `src/lib/proxyHealth/scheduler.ts` | Atur ke `true` agar penjadwal menghapus proksi secara otomatis setelah kegagalan berturut-turut yang berulang. |
| `PROXY_AUTO_REMOVE_AFTER` | `3` | `src/lib/proxyHealth/scheduler.ts` | Jumlah kegagalan berturut-turut sebelum penjadwal menghapus proksi secara otomatis (ketika `PROXY_AUTO_REMOVE=true`). |
| `PROXY_AUTO_DISABLE` | `false` | `src/lib/proxyHealth/scheduler.ts` | Atur ke `true` agar penjadwal menonaktifkan proksi secara lunak (status `dead`, tidak pernah dihapus) setelah kegagalan berturut-turut yang berulang, alih-alih menghapusnya. Alternatif nondestruktif untuk `PROXY_AUTO_REMOVE`: proksi segera dikeluarkan dari resolusi kumpulan/rotasi (filter status aktif yang digunakan oleh resolusi kumpulan cakupan sudah mengecualikannya) dan diaktifkan kembali secara otomatis setelah berhasil melewati pemeriksaan lagi. Menggunakan ambang batas `PROXY_AUTO_REMOVE_AFTER` yang sama. Jika kedua flag bernilai `true`, `PROXY_AUTO_REMOVE` akan diprioritaskan. |
| `OMNIROUTE_CONTROL_PLANE_PROXY_DIRECT_FALLBACK` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Izinkan alur validasi OAuth dan penyedia melewati proksi yang disematkan dan terhubung secara langsung ketika prapemeriksaan keterjangkauan proksi gagal. Urutan prioritas yang berlaku adalah penggantian dari DB Feature Flags > variabel lingkungan > nilai default. |
| `RATE_LIMIT_MAX_WAIT_MS` | `30000` (30 dtk) | `src/lib/resilience/settings.ts` | Anggaran **waktu tunggu antrean** default: berapa lama permintaan dapat menunggu slot penyedia dan berada dalam antrean sebelum ditolak tanpa pernah mencapai upstream. Pewaktu dihapus setelah tugas mulai dijalankan — eksekusi dibatasi secara terpisah oleh `RATE_LIMIT_EXECUTION_MAX_WAIT_MS`. Variabel lingkungan hanya menetapkan nilai default: `resilienceSettings.requestQueue.maxWaitMs` yang tersimpan, lalu `rateLimitOverrides.maxWaitMs` per koneksi, masing-masing memiliki prioritas lebih tinggi. |
| `RATE_LIMIT_EXECUTION_MAX_WAIT_MS` | `600000` (10 menit) | `open-sse/services/rateLimitManager.ts` | Batas maksimum lamanya permintaan yang telah diterima dapat tetap dalam eksekusi sebelum reservasi batas lajunya kedaluwarsa — dipisahkan dari anggaran waktu tunggu antrean agar awal pengambilan yang lambat pada gateway noninkremental tidak mengalami timeout (#12027). |
| `RATE_LIMIT_MAX_QUEUE_DEPTH` | `0` (dinonaktifkan) | `open-sse/services/rateLimitManager.ts` | Batas penerimaan antrean: tolak dengan respons 429 `queue_full` setelah jumlah permintaan yang sudah berada dalam antrean mencapai nilai ini. `0` = tanpa batas (default). |
| `RATE_LIMIT_AUTO_ENABLE` | _(tidak diatur)_ | `open-sse/services/rateLimitManager.ts` | Paksa jaring pengaman batas laju aktif otomatis untuk hidup/mati terlepas dari pengaturan Dashboard yang tersimpan. Menerima `true`/`1`/`on` untuk memaksa aktif, `false`/`0`/`off` untuk memaksa nonaktif. |
| `PROVIDER_COOLDOWN_ENABLED` | _(tidak disetel → nonaktif)_ | `open-sse/services/providerCooldownTracker.ts` | Pelacakan cooldown penyedia/koneksi global lintas permintaan yang bersifat opsional. NONAKTIF secara default (tumpang tindih dengan Cooldown Koneksi / Circuit Breaker Penyedia). Menerima `true`/`1`/`on` untuk mengaktifkan. |
| `PROVIDER_COOLDOWN_MIN_MS` | `5000` | `open-sse/services/providerCooldownTracker.ts` | Cooldown minimum (md) sebelum penyedia/koneksi yang gagal dicoba kembali. Bertambah secara eksponensial seiring kegagalan berturut-turut. Hanya digunakan ketika `PROVIDER_COOLDOWN_ENABLED`. |
| `PROVIDER_COOLDOWN_MAX_MS` | `300000` (5 menit) | `open-sse/services/providerCooldownTracker.ts` | Batas cooldown maksimum (md) sebelum penyedia/koneksi yang gagal tetap dicoba kembali. Hanya digunakan ketika `PROVIDER_COOLDOWN_ENABLED`. |
| `STREAM_RECOVERY_ENABLED` | _(tidak disetel → nonaktif)_ | `src/lib/resilience/settings.ts` (nilai awal) → `open-sse/services/streamRecovery.ts` (logika) | **Apa:** pemulihan transparan untuk aliran upstream yang terpotong (port free-claude-code). Menahan jendela SSE pembuka hingga `STREAM_RECOVERY.HOLDBACK_MS` (750 md), sehingga pemutusan _pra-commit_ — yang terjadi sebelum byte apa pun sampai ke klien — dibuka kembali dan dicoba ulang tanpa terlihat. **Kapan diaktifkan:** upstream yang tidak stabil/sering terpotong pada 0 byte saat aliran dimulai; biarkan NONAKTIF jika Anda tidak dapat menoleransi tambahan waktu hingga token pertama sampai sebesar 750 md pada setiap aliran. Menerima `true`/`1`/`on`. Menginisialisasi pengaturan Ketahanan yang dipersistenkan; setelah ditetapkan, pengaturan Dasbor yang berlaku. |
| `STREAM_RECOVERY_MIDSTREAM_ENABLED` | _(tidak disetel → nonaktif)_ | `src/lib/resilience/settings.ts` (nilai awal) → `open-sse/services/streamRecovery.ts` (logika) | **Apa:** kelanjutan di tengah aliran (Fase 4.4) — setelah pemotongan _pasca-commit_ (byte telah sampai ke klien), mengirim ulang permintaan dengan teks parsial sebagai prefill asisten dan menyambungkan sufiks yang hilang. Hanya untuk aliran teks biasa yang kompatibel dengan OpenAI; tidak pernah dijalankan saat panggilan alat sedang berlangsung. **Kapan diaktifkan:** pembuatan teks panjang yang terpotong di tengah jawaban dan Anda menerima bagian akhir hasil pemulihan tiba sekaligus, bukan token demi token. Independen dari `STREAM_RECOVERY_ENABLED` (profil risiko berbeda). Menerima `true`/`1`/`on`. |
| `STREAM_THROUGHPUT_WATCHDOG_ENABLED` | _(tidak disetel → nonaktif)_ | `src/lib/resilience/settings.ts` → `open-sse/services/throughputWatchdog.ts` | Watchdog keluaran berguna untuk aliran aktif yang bersifat opsional. Mendeteksi aliran yang terus mengirim potongan tetapi tetap berada di bawah tingkat keluaran asisten yang dikonfigurasi; heartbeat, peristiwa penggunaan, delta kosong, serta fase alat/penalaran tidak disalahartikan sebagai kemajuan. Terpisah dari batas waktu idle dan tenggat waktu mutlak. |
| `STREAM_THROUGHPUT_WATCHDOG_WARMUP_MS` | `30000` | `src/lib/resilience/settings/normalize.ts` | Masa tenggang sebelum evaluasi throughput, dibatasi pada 0–600000 md. |
| `STREAM_THROUGHPUT_WATCHDOG_WINDOW_MS` | `30000` | `src/lib/resilience/settings/normalize.ts` | Jendela bergulir untuk keluaran berguna, dibatasi pada 1000–600000 md; satu jendela penuh diperlukan sebelum pembatalan. |
| `STREAM_THROUGHPUT_WATCHDOG_MIN_BYTES_PER_SECOND` | `4` | `src/lib/resilience/settings/normalize.ts` | Laju minimum byte keluaran asisten UTF-8 (proksi token konservatif), dibatasi pada 1–1000000. |
| `STREAM_THROUGHPUT_WATCHDOG_MIN_USEFUL_BYTES` | `1` | `src/lib/resilience/settings/normalize.ts` | Sampel keluaran berguna tak nol minimum yang dianggap dapat diukur, dibatasi pada 1–1000000 byte. |
| `HEALTHCHECK_STAGGER_MS` | `3000` | `src/lib/tokenHealthCheck.ts` | Interval bertahap (md) antara pemeriksaan kesehatan token penyedia saat startup. |
| `HEALTHCHECK_JITTER_MIN_MS` | `500` | `src/lib/tokenHealthCheck.ts` | Jitter acak minimum (ms) yang ditambahkan di atas `HEALTHCHECK_STAGGER_MS` di antara pemeriksaan kesehatan token penyedia, untuk mencegah lonjakan serentak (Isu #1220). |
| `HEALTHCHECK_JITTER_MAX_MS` | `5000` | `src/lib/tokenHealthCheck.ts` | Jitter acak maksimum (ms) yang ditambahkan di atas `HEALTHCHECK_STAGGER_MS` di antara pemeriksaan kesehatan token penyedia, untuk mencegah lonjakan serentak (Isu #1220). |
| `HEALTHCHECK_BATCH_SIZE` | `20` | `src/lib/tokenHealthCheck.ts` | Ukuran batch pemeriksaan bersamaan untuk penyisiran pemeriksaan kesehatan token saat proses awal; nilai yang lebih besar memeriksa lebih banyak koneksi secara paralel, sedangkan nilai yang lebih kecil mengurangi beban lonjakan (Isu #7875, regresi dari #7719). |
| `REQUEST_RETRY` | `2` | `src/sse/services/cooldownAwareRetry.ts` | Jumlah percobaan ulang otomatis pada respons masa tunggu yang tercakup dalam model sebelum mengembalikan kesalahan kepada klien. |
| `MAX_RETRY_INTERVAL_SEC` | `30` | `src/sse/services/cooldownAwareRetry.ts` | Interval backoff maksimum (detik) di antara percobaan ulang akibat masa tunggu. Dibatasi oleh nilai ini terlepas dari `Retry-After` upstream. |
| `HEADROOM_URL` | `http://localhost:8787` | `src/lib/headroom/detect.ts` | URL proksi penghemat token Headroom. Siklus hidup dasbor (`api/headroom/*`) secara default menjalankan CLI `headroom-ai` lokal pada loopback; timpa hanya untuk mengarahkannya ke proksi sidecar Docker eksternal. |
### Konstanta penyetelan pemulihan stream
Perilaku penahanan pemulihan disetel melalui konstanta yang di-hardcode dalam
`open-sse/config/constants.ts` (`STREAM_RECOVERY`), yang ditampilkan di sini sebagai referensi —
mengubahnya memerlukan pengeditan kode, bukan variabel lingkungan:
- `STREAM_RECOVERY.HOLDBACK_MS = 750` — durasi jendela SSE pembuka ditahan
agar pemotongan dini dapat dicoba ulang sebelum byte apa pun dikomit ke klien.
- `STREAM_RECOVERY.BUFFER_MAX_BYTES = 65536` — batas mutlak untuk jendela yang ditahan; lakukan komit
(flush + passthrough) segera setelah byte sebanyak ini terakumulasi, terlepas dari pewaktu.
- `STREAM_RECOVERY.EARLY_RETRY_MAX = 4` — jumlah maksimum pembukaan ulang transparan atas stream upstream
selama penahanan belum dikomit.
> **Batas laju jendela geser per penyedia (tanpa variabel lingkungan):** _fallback_
> batas laju jendela geser per penyedia yang di-porting dari FCC tersedia dalam kode
> (`open-sse/services/providerDefaultRateLimit.ts`, dihubungkan melalui
> `open-sse/services/rateLimitManager.ts`), tetapi didistribusikan dengan **peta default kosong**
> dan saat ini **tidak memiliki variabel lingkungan operator** — fitur ini hanya diaktifkan melalui hook pengujian /
> pengeditan kode. Fitur ini sengaja tidak dicantumkan dalam tabel di atas. Pembatas relay per-`(token, IP)`
> yang _memang_ memiliki parameter pengaturan adalah `RELAY_IP_PER_MINUTE` (§3 Jaringan & Port).
---
## 22. Debugging
> [!CAUTION]
> Variabel-variabel ini menghasilkan **output yang panjang** dan dapat membocorkan data sensitif. **Jangan pernah mengaktifkannya di lingkungan produksi.**
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CURSOR_DEBUG` | _(tidak disetel)_ | `open-sse/executors/cursor.ts` | Setel ke `1` untuk mengaktifkan log eksekutor Cursor yang mendetail (chunk SSE yang telah didekode, dll.). |
| `CURSOR_STREAM_DEBUG` | _(tidak disetel)_ | `open-sse/executors/cursor.ts` | Alias yang kompatibel dengan versi sebelumnya untuk `CURSOR_DEBUG`. |
| `CURSOR_DUMP_FILE` | _(tidak disetel)_ | `open-sse/executors/cursor.ts` | Path file opsional yang menerima chunk Cursor mentah yang telah didekode saat `CURSOR_DEBUG=1`. |
| `CURSOR_STREAM_TIMEOUT_MS` | `300000` | `open-sse/executors/cursor.ts` | Batas waktu inaktivitas stream (md) untuk eksekutor Cursor. |
| `CURSOR_KV_GRACE_MS` | `2000` | `open-sse/executors/cursor.ts` | Jendela tenggang (md) setelah terminator lunak composer kv_after_text ketika masih ada byte dalam buffer — memberikan waktu bagi pemanggilan alat exec_mcp di bagian akhir untuk menyelesaikan frame-nya. |
| `CURSOR_TOOL_DIRECTIVE` | diaktifkan (`!== "0"`) | `open-sse/executors/cursor.ts` | Direktif komitmen alat yang membuat composer-2.5 menerbitkan pemanggilan alat secara andal. Setel ke `0` untuk menonaktifkannya. |
| `OMNIROUTE_SYSTEM_INSTRUCTION_APPEND` | _(tidak disetel)_ | `open-sse/translator/request/claude-to-openai.ts`, `open-sse/translator/response/openai-to-claude.ts` | Teks prompt sistem yang ditentukan operator dan ditambahkan ke pesan sistem SETELAH penerjemahan (injeksi pascapenerjemahan), sehingga mencapai jalur codex/Responses dan `/v1/messages`. Juga digunakan sebagai prefiks direktif yang dihapus dari blok pembuka sistem yang digaungkan kembali. Biarkan tidak disetel untuk menonaktifkannya. |
| `OMNIROUTE_STRIP_SYSTEM_PREAMBLE` | `0` (nonaktif) | `open-sse/translator/response/openai-to-claude.ts`, `open-sse/utils/directivePreambleStripper.ts` | Setel ke `1` untuk menghapus blok pembuka prompt sistem yang digaungkan kembali dari awal stream openai→claude. Secara default nonaktif — heuristiknya dirancang mengikuti prosa bahasa Inggris dan mengubah payload respons, sehingga balasan yang secara sah diawali dengan bagian semacam itu akan kehilangan bagian tersebut. |
| `CURSOR_IMAGE_FETCH_TIMEOUT_MS` | `15000` | `open-sse/utils/cursorImages.ts` | Batas waktu pengambilan per gambar (md) untuk input visi `image_url` jarak jauh. |
| `CURSOR_STATE_DB_PATH` | _(dideteksi)_ | `open-sse/utils/cursorVersionDetector.ts` | Ganti pencarian DB status Cursor IDE yang digunakan untuk mendeteksi versi IDE. |
| `CURSOR_AGENT_CLI_VERSION` | _(deteksi / sematkan)_ | `open-sse/utils/cursorAgentCliVersion.ts` | ID build Agent CLI (`YYYY.MM.DD-`) untuk `x-cursor-client-version: cli-…` pada Agent Run. |
| `CURSOR_AGENT_BIN` | _(tidak disetel)_ | `open-sse/handlers/imageGeneration/providers/cursorAgentImage.ts` | Path ke biner Cursor Agent yang digunakan untuk pembuatan gambar. Jika tidak disetel, handler menggunakan `providerSpecificData.agentBin`, lalu PATH. |
| `CURSOR_IMG_TIMEOUT_MS` | `210000` | `open-sse/handlers/imageGeneration/providers/cursorAgentImage.ts` | Waktu aktual per gambar (md) untuk tugas gambar Cursor Agent. |
| `CURSOR_IMG_MAX_CONCURRENT` | `2` | `open-sse/handlers/imageGeneration/providers/cursorAgentImage.ts` | Batas konkurensi seat bersama untuk tugas gambar Cursor. |
| `CURSOR_IMG_MODEL` | permintaan / `auto` | `open-sse/handlers/imageGeneration/providers/cursorAgentImage.ts` | Ganti `--model` Cursor CLI untuk tugas gambar. |
| `UC_IMAGE_POLL_INTERVAL_MS` | `2000` | `open-sse/handlers/imageGeneration/providers/ucImage.ts` | Interval polling hasil pembuatan gambar UC (uncensored.com) (md). |
| `UC_IMAGE_POLL_TIMEOUT_MS` | `60000` | `open-sse/handlers/imageGeneration/providers/ucImage.ts` | Batas waktu aktual polling hasil pembuatan gambar UC (md). |
| `UC_VIDEO_POLL_INTERVAL_MS` | `3000` | `open-sse/handlers/videoGeneration/providers/ucVideo.ts` | Interval polling hasil pembuatan video UC (uncensored.com) (md). |
| `UC_VIDEO_POLL_TIMEOUT_MS` | `300000` | `open-sse/handlers/videoGeneration/providers/ucVideo.ts` | Batas waktu aktual polling hasil pembuatan video UC (md). |
| `CURSOR_DATA_DIR` | _(dideteksi)_ | `open-sse/utils/cursorAgentCliVersion.ts` | Ganti direktori data Cursor Agent CLI (`…/versions/`); variabel yang sama digunakan oleh agen resmi. |
| `CURSOR_TOKEN` | _(tidak disetel)_ | `scripts/ad-hoc/cursor-tap.cjs` | Token bearer Cursor langsung yang digunakan oleh alat bantu pengembang. |
| `OMNIROUTE_LOG_REQUEST_SHAPE` | dinonaktifkan (ikut serta melalui `"1"`) | `src/app/api/v1/chat/completions/route.ts` | Catat penanda jenis/panjang konten untuk payload chat berukuran besar saat `"1"` disetel. Secara default nonaktif untuk mengurangi derau log. |
| `DEBUG_RESPONSES_SSE_TO_JSON` | _(tidak disetel)_ | `open-sse/handlers/responseTranslator.ts` | Setel ke `true` untuk mencatat detail penerjemahan SSE→JSON Responses API. |
| `DEBUG_CLAUDE_NONSTREAM` | _(tidak disetel)_ | `open-sse/handlers/responseTranslator.ts` | Setel ke `true` untuk menampilkan chunk textContent kosong dalam jalur penerjemahan respons Claude (hanya untuk debugging). |
| `NEXT_PUBLIC_OMNIROUTE_E2E_MODE` | _(tidak disetel)_ | Harness pengujian E2E | Setel ke `true` untuk mengaktifkan mode pengujian E2E (autentikasi yang dilonggarkan, hook pengujian). |
---
## 23. Integrasi GitHub
Izinkan pengguna melaporkan masalah secara langsung dari Dashboard.
| Variabel | Default | File Sumber | Deskripsi |
| --------------------- | ---------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GITHUB_ISSUES_REPO` | _(belum diatur)_ | `src/app/api/v1/issues/report/route.ts` | Repositori dalam format `owner/repo`. |
| `GITHUB_ISSUES_TOKEN` | _(belum diatur)_ | `src/app/api/v1/issues/report/route.ts` | GitHub Personal Access Token dengan cakupan `issues:write`. |
| `GITHUB_TOKEN` | _(belum diatur)_ | triase masalah / pembantu agen cloud | Token akses GitHub generik yang digunakan sebagai cadangan untuk `GITHUB_ISSUES_TOKEN` dan digunakan oleh pembantu agen cloud di `src/lib/cloudAgent/*`. |
---
## Skenario Deployment
Untuk panduan SRE backend relay (perilaku ts/bifrost/auto, penempatan 9router vs CLIProxyAPI, dan strategi fallback throughput tinggi), lihat [Strategi Backend Relay](/docs/reference/RELAY_BACKEND_STRATEGY.md).
### Pengembangan Lokal Minimal
```bash
JWT_SECRET=$(openssl rand -base64 48)
API_KEY_SECRET=$(openssl rand -hex 32)
INITIAL_PASSWORD=dev123
PORT=20128
NODE_ENV=development
```
### Produksi Docker
```bash
JWT_SECRET=
API_KEY_SECRET=
INITIAL_PASSWORD=
STORAGE_ENCRYPTION_KEY=
DATA_DIR=/data
PORT=20128
API_PORT=20129
NODE_ENV=production
AUTH_COOKIE_SECURE=true
REQUIRE_API_KEY=true
NEXT_PUBLIC_BASE_URL=https://omniroute.example.com
BASE_URL=http://localhost:20128
OMNIROUTE_MEMORY_MB=8192
CORS_ORIGIN=https://your-frontend.example.com
```
### Terisolasi / CI
```bash
JWT_SECRET=test-jwt-secret-for-ci
API_KEY_SECRET=test-api-key-secret-for-ci
INITIAL_PASSWORD=testpass
NODE_ENV=production
OMNIROUTE_DISABLE_BACKGROUND_SERVICES=true
APP_LOG_TO_FILE=false
```
### VPS dengan Reverse Proxy (nginx + Cloudflare)
```bash
JWT_SECRET=
API_KEY_SECRET=
STORAGE_ENCRYPTION_KEY=
PORT=20128
AUTH_COOKIE_SECURE=true
REQUIRE_API_KEY=true
NEXT_PUBLIC_BASE_URL=https://omniroute.example.com
BASE_URL=http://127.0.0.1:20128
CORS_ORIGIN=https://omniroute.example.com
ENABLE_TLS_FINGERPRINT=true
CLI_COMPAT_ALL=1
```
---
## 24. Sandbox Skills (v3.8.0+)
Batas dan pengaturan keamanan yang diterapkan saat framework Skills (`src/lib/skills/`) menjalankan otomatisasi yang ditentukan pengguna dalam lingkungan sandbox.
| Variabel | Default | File Sumber | Deskripsi |
| --------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SKILLS_SANDBOX_TIMEOUT_MS` | `10000` (10 dtk) | `src/lib/skills/builtins.ts` | Batas waktu wall-clock per eksekusi untuk kode skill dalam sandbox. Batas mutlak; proses yang berlangsung lebih lama akan dihentikan. |
| `SKILLS_EXECUTION_TIMEOUT_MS` | _(menggunakan `SKILLS_SANDBOX_TIMEOUT_MS` sebagai fallback)_ | `src/lib/skills/` | Batas waktu orkestrasi skill tingkat tinggi. Atur lebih tinggi daripada `SKILLS_SANDBOX_TIMEOUT_MS` untuk memungkinkan alur kerja multi-langkah. |
| `SKILLS_MAX_FILE_BYTES` | `1048576` (1 MB) | `src/lib/skills/builtins.ts` | Jumlah byte maksimum yang dapat dibaca skill dari setiap file tunggal dalam sandbox. |
| `SKILLS_MAX_HTTP_RESPONSE_BYTES` | `256000` (250 KB) | `src/lib/skills/builtins.ts` | Jumlah byte maksimum yang diambil dari setiap respons HTTP tunggal di dalam skill. |
| `SKILLS_MAX_SANDBOX_OUTPUT_CHARS` | `100000` | `src/lib/skills/builtins.ts` | Batas mutlak jumlah karakter stdout/stderr yang dikembalikan dari pemanggilan sandbox. |
| `SKILLS_SANDBOX_NETWORK_ENABLED` | `false` | `src/lib/skills/builtins.ts` | Atur ke `1`/`true` untuk mengizinkan jaringan keluar dari dalam sandbox. Secara default **terisolasi** demi keamanan. |
| `SKILLS_ALLOWED_SANDBOX_IMAGES` | _(kosong)_ | `src/lib/skills/builtins.ts` | Daftar gambar kontainer yang dipisahkan koma dan diizinkan untuk eksekusi sandbox. Kosong berarti hanya menggunakan default bawaan. |
| `SKILLS_SANDBOX_DOCKER_IMAGE` | _(default bawaan)_ | `src/lib/skills/` | Gambar kontainer yang digunakan saat membuat sandbox berbasis Docker. Timpa untuk menyematkan gambar dasar kustom yang diperkuat. |
| `SKILLS_SANDBOX_RUNTIME` | `auto` | `src/lib/skills/sandbox.ts`, `src/lib/skills/containerProvider.ts` | Runtime kontainer untuk sandbox skill: `auto` \| `docker` \| `apple` \| `wsl` \| `orbstack` \| `podman`. `auto` memilih runtime terinstal terbaik berdasarkan OS host (Apple Container/OrbStack di macOS, WSL Container di Windows, Podman di Linux), dengan fallback ke Docker. |
> [!CAUTION]
> Mengaktifkan `SKILLS_SANDBOX_NETWORK_ENABLED=true` membuka jalur keluar dari kode skill arbitrer. Padukan dengan `OUTBOUND_SSRF_GUARD_ENABLED=true` dan kebijakan `CORS_ORIGIN`/proxy yang ketat dalam deployment bersama.
---
## 25. Kuota Penyedia, Tunnel, Cadangan & Runtime Lainnya
Endpoint kuota penyedia, tunnel jaringan (Tailscale, Ngrok, proksi debug MITM), pool egress 1Proxy, cadangan basis data, dan override kecil per fitur yang dirujuk oleh lapisan eksekutor atau skrip.
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REDIS_URL` | `redis://localhost:6379` | `src/shared/utils/rateLimiter.ts` | String koneksi Redis untuk backend pembatas laju. |
| `ALIBABA_CODING_PLAN_HOST` | _(host produksi)_ | `open-sse/services/bailianQuotaFetcher.ts` | Mengganti host yang digunakan untuk mengambil kuota paket coding Alibaba Bailian. |
| `ALIBABA_CODING_PLAN_QUOTA_URL` | diturunkan dari host | `open-sse/services/bailianQuotaFetcher.ts` | Override URL kuota lengkap untuk Alibaba Bailian. |
| `QWEN_CLOUD_COOKIE` | _(tidak diatur)_ | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Cookie sesi konsol untuk gateway kuota Token Plan pribadi Qwen Cloud / Model Studio (kunci API inferensi tidak dapat membacanya). Salin seluruh header permintaan `Cookie` — yang berisi `login_qwencloud_ticket` — dari panggilan `api.json` apa pun ke `cs-data.qwencloud.com` pada home.qwencloud.com › Billing › Subscription (F12 › Network). Bersifat sensitif dan terbatas pada sesi; utamakan kolom Dashboard `qwenCloudCookie` per koneksi. |
| `QWEN_CLOUD_SEC_TOKEN` | _(tidak diatur)_ | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Override `sec_token` manual untuk gateway konsol Token Plan. Bersifat sensitif; jika tidak diatur, pengambil akan menentukannya dari HTML dashboard menggunakan cookie. |
| `QWEN_TOKEN_PLAN_HOST` | `https://cs-data.qwencloud.com` | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Override host gateway untuk pengambil kuota Token Plan pribadi (misalnya `bailian-singapore-cs.alibabacloud.com` untuk konsol Model Studio). |
| `QWEN_TOKEN_PLAN_DASHBOARD_URL` | `https://home.qwencloud.com/` | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | URL dashboard yang digunakan untuk menentukan `sec_token` dari HTML saat pengguna telah login. |
| `ALIBABA_FREE_TIER_VISION_FE_PATH` | `/costing-balance/free-quota-image-video` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Override path front-end konsol untuk mengambil kuota gratis tingkat awal bagi fitur visi/media Alibaba Model Studio. |
| `ALIBABA_FREE_TIER_MULTIMODAL_FE_PATH` | `/costing-balance/free-quota-multimodal` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Penggantian path front-end konsol untuk mengambil kuota multimodal tingkat gratis Alibaba Model Studio. |
| `ALIBABA_FREE_TIER_AUDIO_FE_PATH` | `/costing-balance/free-quota-audio` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Penggantian path front-end konsol untuk mengambil kuota audio tingkat gratis Alibaba Model Studio. |
| `ALIBABA_FREE_TIER_ALLOWLIST_PATH` | _(tidak diatur)_ | `open-sse/services/alibabaFreeTierAllowlist.ts` | Path opsional ke penggantian JSON lokal untuk daftar izin model teks tingkat gratis Alibaba bawaan. Jika tidak tersedia, beralih ke `$DATA_DIR/alibaba-free-tier-allowlist.json`, lalu `config/alibaba-free-tier-allowlist.json`. |
| `CONTEXT_RESERVE_TOKENS` | `1024` | `open-sse/services/contextManager.ts` | Token yang dicadangkan untuk keluaran penyelesaian saat menghitung anggaran prompt. |
| `CONTEXT_KEEP_LATEST_IMAGES` | `2` | `open-sse/services/contextManager.ts` | Jumlah gambar inline terbaru yang dipertahankan saat memangkas gambar lama agar sesuai dengan jendela konteks (#8560). |
| `MODEL_ALIAS_COMPAT_ENABLED` | diaktifkan | `open-sse/services/model.ts` | Mengaktifkan atau menonaktifkan lapisan kompatibilitas alias model lama yang digunakan oleh klien versi lama. |
| `OMNIROUTE_EMERGENCY_FALLBACK` | diaktifkan | `open-sse/services/emergencyFallback.ts` | Atur ke `false` (atau `0`) untuk menonaktifkan fallback darurat saat anggaran habis yang mengalihkan permintaan gagal ke model gratis `nvidia`/`openai/gpt-oss-120b`. Urutan prioritas efektifnya adalah penggantian DB Feature Flags > variabel lingkungan > nilai default; jika tidak tersedia, layanan kembali menggunakan nilai mentah dari variabel lingkungan. |
| `COMMAND_CODE_CALLBACK_PORT` | _(tidak diatur)_ | `src/app/api/providers/command-code/auth/shared.ts` | Port lokal yang digunakan untuk callback bergaya OAuth dari helper CLI Command Code. |
| `COMMAND_CODE_VERSION` | `0.33.2` | `open-sse/executors/commandCode.ts` | Nilai yang dikirim sebagai header `x-command-code-version` ke upstream Command Code. Ganti nilainya untuk menaikkan versi CLI. |
| `COMMANDCODE_API_URL` | `https://api.commandcode.ai` | `open-sse/services/usage/command-code.ts` | URL dasar untuk upstream penggunaan/kuota Command Code yang digunakan oleh telemetri pengambil kuota ponsel pintar. Ganti nilainya untuk API Command Code yang di-host sendiri/alternatif. |
| `MITM_LOCAL_PORT` | `443` | `src/mitm/server.cjs` | Port bind lokal untuk proksi debug MITM. |
| `MITM_DISABLE_TLS_VERIFY` | `0` | `src/mitm/server.cjs` | Atur ke `1` untuk menonaktifkan verifikasi TLS upstream (khusus pengembangan). |
| `MITM_IDLE_TIMEOUT_MS` | `60000` | `src/mitm/socketTimeouts.ts`, `src/mitm/server.cjs` | Batas waktu soket idle (ms) untuk koneksi yang diproksikan; soket yang tetap idle setelah batas ini akan diputus untuk menghindari kebocoran tunnel setengah terbuka. |
| `BRIDGE_PORT` | `20129` | `bin/antigravity-bridge.mjs` | Port tempat bridge MITM Antigravity menerima koneksi. |
| `ROUTER_URL` | `http://127.0.0.1:20128/v1/antigravity` | `bin/antigravity-bridge.mjs` | Endpoint router yang menjadi tujuan penerusan lalu lintas Antigravity oleh bridge. |
| `CERT_DIR` | `~/.omniroute/mitm` | `bin/antigravity-bridge.mjs` | Direktori yang berisi `server.key`/`server.crt` untuk listener TLS bridge; bridge akan berhenti jika salah satunya tidak ada. |
| `MITM_VERBOSE` | `1` | `src/mitm/server.cjs`, `src/mitm/_internal/bypass.cjs` | Verbositas log keputusan perutean: `0` menonaktifkan log, sedangkan nilai yang lebih tinggi mencatat lebih banyak keputusan bypass/perutean. |
| `MITM_ROOT_CA_ENABLED` | `false` | `src/mitm/manager.ts` | Atur ke `true` untuk memilih menggunakan model CA root + sertifikat leaf per host (#6684). Instalasi baru menggunakannya secara otomatis; instalasi dengan sertifikat leaf lama yang sudah dipercaya akan tetap menggunakan sertifikat SAN tetap lama kecuali memilih untuk beralih. |
| `MITM_CERT_MODE` | `legacy` | `src/mitm/manager.ts`, `src/mitm/server.cjs` | Diatur OLEH pengelola MITM untuk proses proksi yang dijalankan (`root-ca` \| `legacy`) — mencerminkan keputusan migrasi sertifikat; tidak dimaksudkan untuk diatur secara manual. |
| `OMNIROUTE_NO_SUDO` | `0` | `src/mitm/systemCommands.ts` | Atur ke `1` (truthy) untuk menghapus `sudo` di awal perintah kepercayaan sertifikat MITM — untuk deployment tanpa root / dengan namespace pengguna, tempat operator memercayai CA secara manual (misalnya melalui mekanisme sertifikat CA tambahan milik Node). |
| `SKIP_ANTIGRAVITY_DNS` | _(tidak diatur)_ | `src/mitm/dns/provision.ts` | Atur ke `true` untuk sepenuhnya melewati penyediaan entri DNS `/etc/hosts` bagi nama host proksi Antigravity — untuk container tanpa akses sudo/root. |
| `OMNIROUTE_SKIP_DNS_WRITE` | _(tidak diatur)_ | `src/mitm/dns/dnsConfig.ts` | Atur ke `1` untuk melewati penulisan ke file hosts saat menambahkan/menghapus entri DNS — untuk lingkungan pengujian yang terisolasi atau hanya-baca. |
| `OMNIROUTE_SKIP_SYSTEM_TRUST` | `0` | `src/mitm/cert/install.ts`, `src/mitm/tproxy/caTrust.ts` | Pengaman khusus pengujian/CI: atur ke `1` agar pemasangan/penghapusan kepercayaan sertifikat tidak melakukan apa pun, sehingga rangkaian pengujian tidak pernah mengubah penyimpanan kepercayaan OS. Diatur secara otomatis oleh penyiapan pengujian dan alur kerja CI. |
| `CHANGELOG_BASE_REF` | _(otomatis)_ | `scripts/check/check-changelog-integrity.mjs` | Ref dasar eksplisit untuk gerbang anti-penghapusan CHANGELOG (secara default menggunakan cabang dasar PR di CI, atau `release/v*` tertinggi). |
| `FREE_PROXY_AUTO_SYNC_ENABLED` | `false` | `src/lib/freeProxyProviders/scheduler.ts` | Atur ke `true` untuk mengaktifkan penjadwal sinkronisasi otomatis kumpulan proksi gratis di latar belakang. Bersifat opsional dan dinonaktifkan secara default. |
| `FREE_PROXY_AUTO_SYNC_INTERVAL_MS` | `1800000` | `src/lib/freeProxyProviders/scheduler.ts` | Interval sinkronisasi otomatis dalam milidetik (default 30 menit). |
| `FREE_PROXY_1PROXY_ENABLED` | `true` | `src/lib/freeProxyProviders/oneproxy.ts` | Aktifkan sumber proksi gratis 1proxy. Atur ke `false` untuk menonaktifkannya. |
| `FREE_PROXY_1PROXY_API_URL` | _(lihat oneproxy.ts)_ | `src/lib/freeProxyProviders/oneproxy.ts` | Penggantian URL API 1proxy. |
| `FREE_PROXY_1PROXY_MAX` | `500` | `src/lib/freeProxyProviders/oneproxy.ts` | Jumlah maksimum proksi yang diambil per sinkronisasi dari 1proxy. |
| `FREE_PROXY_1PROXY_MIN_QUALITY` | `50` | `src/lib/freeProxyProviders/oneproxy.ts` | Ambang batas skor kualitas minimum untuk impor 1proxy. |
| `FREE_PROXY_PROXIFLY_ENABLED` | `true` | `src/lib/freeProxyProviders/proxifly.ts` | Aktifkan sumber proksi gratis Proxifly. Atur ke `false` untuk menonaktifkannya. |
| `FREE_PROXY_PROXIFLY_QUANTITY` | `100` | `src/lib/freeProxyProviders/proxifly.ts` | Jumlah proksi yang akan diambil per sinkronisasi Proxifly. |
| `FREE_PROXY_PROXIFLY_ANONYMITY` | `elite` | `src/lib/freeProxyProviders/proxifly.ts` | Filter tingkat anonimitas untuk Proxifly (`elite`, `anonymous`, `transparent`). |
| `FREE_PROXY_IPLOCATE_ENABLED` | `false` | `src/lib/freeProxyProviders/iplocate.ts` | Aktifkan sumber proxy gratis IPLocate. Hanya aktif jika diikutsertakan secara eksplisit. |
| `FREE_PROXY_IPLOCATE_BASE_URL` | `https://raw.githubusercontent.com/iplocate/free-proxy-list/main/protocols` | `src/lib/freeProxyProviders/iplocate.ts` | Penggantian URL dasar daftar proxy IPLocate. |
| `FREE_PROXY_WEBSHARE_ENABLED` | `true` | `src/lib/freeProxyProviders/webshare.ts` | Aktifkan sumber kumpulan proxy Webshare. Atur ke `false` untuk menonaktifkannya; `FREE_PROXY_WEBSHARE_API_KEY` juga harus ditetapkan. |
| `FREE_PROXY_WEBSHARE_API_KEY` | _(tidak ada)_ | `src/lib/freeProxyProviders/webshare.ts` | Token API akun Webshare (`Authorization: Token `). Wajib — penyedia tetap dinonaktifkan jika token ini tidak ditetapkan. |
| `FREE_PROXY_WEBSHARE_API_URL` | `https://proxy.webshare.io/api/v2/proxy/list/` | `src/lib/freeProxyProviders/webshare.ts` | Penggantian URL API daftar proxy Webshare. |
| `FREE_PROXY_WEBSHARE_MAX` | `500` | `src/lib/freeProxyProviders/webshare.ts` | Jumlah maksimum proxy yang diimpor per sinkronisasi Webshare. |
| `NEXT_PUBLIC_VERCEL_RELAY_ENABLED` | `true` | `src/app/(dashboard)/…/ProxyPoolTab.tsx` | Tampilkan/sembunyikan tombol Deploy Vercel Relay di tab Proxy Pool. |
| `VERCEL_API_BASE` | `https://api.vercel.com` | `src/app/api/settings/proxy/vercel-deploy/route.ts` | Penggantian URL dasar API Vercel (untuk pengujian). |
| `NEXT_PUBLIC_VERCEL_RELAY_DEFAULT_PROJECT` | `omniroute-relay` | `src/app/(dashboard)/…/VercelRelayModal.tsx` | Nama proyek default yang telah diisikan sebelumnya dalam modal deployment Vercel Relay. |
| `TAILSCALE_BIN` | _(deteksi otomatis)_ | `src/lib/tailscaleTunnel.ts` | Jalur eksplisit ke biner `tailscale`. |
| `TAILSCALED_BIN` | _(deteksi otomatis)_ | `src/lib/tailscaleTunnel.ts` | Jalur eksplisit ke biner daemon `tailscaled`. |
| `TAILSCALE_AUTHKEY` | _(tidak ditetapkan)_ | `src/lib/tailscaleTunnel.ts` | Kunci autentikasi Tailscale yang dibagikan sebelumnya untuk `tailscale up` noninteraktif / headless (diteruskan melalui `--auth-key=`). Jika tidak ditetapkan, proses masuk kembali menggunakan URL autentikasi browser interaktif. |
| `NGROK_AUTHTOKEN` | _(tidak ditetapkan)_ | `src/lib/ngrokTunnel.ts` | Mengautentikasi tunnel ngrok keluar. |
| `DB_BACKUP_MAX_FILES` | `20` | `src/lib/db/backup.ts` | Jumlah maksimum file cadangan SQLite yang dipertahankan oleh pembersihan cadangan manual/terjadwal. Snapshot migrasi diberi alamat berdasarkan konten dan digunakan kembali untuk status DB yang identik; snapshot tersebut tidak dipangkas dalam jendela migrasi bersamaan. Menggantikan nilai yang disimpan dari Pengaturan → Retensi cadangan database. |
| `DB_BACKUP_RETENTION_DAYS` | `0` | `src/lib/db/backup.ts` | Usia maksimum (hari) yang dipertahankan oleh pembersihan cadangan manual/terjadwal. `0` menonaktifkan pemangkasan berdasarkan usia. Snapshot migrasi tidak dipangkas dalam jendela migrasi bersamaan. Menggantikan nilai yang disimpan dari Pengaturan → Retensi cadangan database. |
| `OMNIROUTE_BACKUP_SCHEDULE_JOB_INTERVAL_MS` | `30000` | `src/lib/jobs/backupScheduleJob.ts` | Interval tick (ms) untuk tugas sisi server yang menjalankan `backup-schedule.json`. Nilainya harus tetap jauh di bawah granularitas cron 1 menit; nilai di bawah `5000` atau yang tidak dapat diurai akan kembali ke `30000`. |
| `CONTAINER_HOST` | `docker` | `scripts/check-permissions.sh` | Petunjuk runtime container untuk pemeriksaan izin entrypoint. Tetapkan ke `podman` untuk topologi Podman apa pun. Karena container tidak dapat menentukan apakah engine bersifat lokal atau diakses melalui Podman Machine, peringatan tetap netral terhadap topologi dan mengarahkan ke `contrib/podman/README.md`. |
| `QUOTA_STORE_DRIVER` | `sqlite` | `src/lib/quota/storeFactory.ts` | Backend penyimpanan konsumsi berbagi kuota: `sqlite` (default) atau `redis`. |
| `QUOTA_STORE_REDIS_URL` | _(tidak ditetapkan)_ | `src/lib/quota/storeFactory.ts` | String koneksi Redis yang digunakan saat `QUOTA_STORE_DRIVER=redis` (misalnya `redis://localhost:6379`). |
| `QUOTA_SATURATION_THRESHOLD` | `0.5` | `src/lib/quota/enforce.ts` | Rasio saturasi pool (0..1); saat/melampauinya, pool memasuki mode ketat (tanpa peminjaman). |
| `QUOTA_SOFT_DEPRIORITIZE_FACTOR` | `0.7` | `open-sse/services/combo.ts` | Pengali skor (0..1) yang diterapkan ke target saat kebijakan kuota lunak menurunkan prioritasnya. |
| `STATUS_SOFT_DEPRIORITIZE_FACTOR` | `0.5` | `open-sse/services/combo/autoStrategy.ts` | Pengali skor (0..1) yang diterapkan ke penyedia yang kehabisan kuota (`credits_exhausted`/`rate_limited`) dalam penilaian auto-combo saat batas kuota preflight NONAKTIF (#4540). |
| `QUOTA_CONSUMPTION_RETENTION_DAYS` | `14` | `src/lib/db/quotaConsumption.ts` | Periode retensi (hari) untuk bucket `quota_consumption` sebelum GC (`gcQuotaConsumption`). |
| `QUOTA_PREFLIGHT_CUTOFF_ENABLED` | `false` | `src/lib/resilience/settings.ts` | Fitur opsional (secara default NONAKTIF): mengaktifkan batas tegas kuota perutean otomatis yang menghapus kandidat dengan kuota rendah sebelum penilaian. |
| `OMNIROUTE_AUTO_FREE_FALLBACK_TO_FULL_POOL` | `false` | `open-sse/services/autoCombo/virtualFactory.ts` | Fitur opsional (secara default NONAKTIF): saat filter `auto/:` tidak menemukan kandidat yang terhubung, pulihkan perilaku lama dengan beralih ke seluruh pool (tanpa filter), alih-alih mengembalikan pool kosong. Pengaturan default NONAKTIF membuat `:free` berarti "hanya tingkat gratis". |
| `OMNIROUTE_CHAOS_MAX_PANEL` | `5` | `open-sse/services/autoCombo/virtualFactory.ts` | Batas ukuran panel (dibatasi ke 1–10) untuk varian siaran `auto/*:chaos` — satu permintaan disebarkan ke paling banyak sejumlah ini model dari penyedia yang beragam. |
| `OMNIROUTE_CHAOS_MIN_PANEL` | _(default mesin)_ | `open-sse/services/autoCombo/virtualFactory.ts` | Penyesuaian ukuran minimum panel yang diteruskan ke penangan siaran chaos; jika tidak ditetapkan, default mesin tetap digunakan. |
| `OMNIROUTE_CHAOS_PANEL_TIMEOUT_MS` | _(default mesin)_ | `open-sse/services/autoCombo/virtualFactory.ts` | Batas waktu tegas (ms) untuk keseluruhan fan-out panel chaos; jika tidak ditetapkan, default mesin tetap digunakan. |
| `GROK_AUTH_PATH` | `~/.grok/auth.json` | `open-sse/services/grokQuotaFetcher.ts` | Path ke `auth.json` CLI Grok yang digunakan untuk mengambil kuota mingguan grok-web; timpa untuk pengujian atau instalasi CLI nonstandar. |
| `AGENTBRIDGE_UPSTREAM_CA_CERT` | _(tidak diatur)_ | `src/mitm/manager.ts` | Sertifikat CA tambahan (PEM) yang dipercaya untuk koneksi TLS upstream AgentBridge. |
| `INSPECTOR_BUFFER_SIZE` | `1000` | `src/mitm/inspector/buffer.ts` | Jumlah maksimum permintaan yang ditangkap dan disimpan dalam ring buffer Traffic Inspector. |
| `INSPECTOR_MAX_BODY_KB` | `1024` | `src/mitm/inspector/buffer.ts` | Ukuran maksimum isi permintaan/respons yang ditangkap (KB) sebelum dipotong. |
| `INSPECTOR_HTTP_PROXY_PORT` | `8080` | `src/mitm/inspector/httpProxyServer.ts` | Port lokal untuk proksi HTTP Traffic Inspector. |
| `INSPECTOR_HTTP_PROXY_AUTOSTART` | `false` | `src/mitm/inspector/httpProxyServer.ts` | Mulai proksi HTTP inspector secara otomatis saat boot. |
| `INSPECTOR_TLS_INTERCEPT` | `false` | `src/lib/inspector/captureState.ts` | Aktifkan intersepsi TLS (MITM) untuk lalu lintas HTTPS yang ditangkap. |
| `INSPECTOR_LLM_HOSTS_EXTRA` | _(tidak diatur)_ | `src/lib/inspector/captureState.ts` | Nama host tambahan (dipisahkan dengan koma) yang diperlakukan sebagai endpoint LLM untuk penangkapan. |
| `INSPECTOR_MASK_SECRETS` | `true` | `src/mitm/inspector/buffer.ts` | Samarkan informasi rahasia (header autentikasi / kunci API) dalam lalu lintas yang ditangkap. |
| `INSPECTOR_SYSTEM_PROXY_GUARD_MINUTES` | `30` | `src/app/api/tools/traffic-inspector/capture-modes/system-proxy/route.ts` | Jumlah menit sebelum pengaman proksi sistem secara otomatis mengembalikan pengaturan proksi OS. |
| `INSPECTOR_INTERNAL_INGEST_TOKEN` | _(otomatis)_ | `src/app/api/tools/traffic-inspector/internal/ingest/route.ts` | Token untuk mengautentikasi penyerapan data tangkapan internal ke inspector. |
| `PLAYGROUND_COMPARE_MAX_COLUMNS` | `4` | `src/app/(dashboard)/dashboard/playground/` | Jumlah maksimum kolom berdampingan dalam mode perbandingan Playground. |
| `PLAYGROUND_IMPROVE_PROMPT_DEFAULT_MODEL` | _(tidak diatur)_ | `src/app/(dashboard)/dashboard/playground/` | Model default untuk tindakan 'perbaiki prompt' di Playground (kembali menggunakan model aktif jika tidak diatur). |
| `BIFROST_ENABLED` | `1` | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Sakelar penghenti utama untuk proksi sidecar Bifrost. Jika diatur ke `0`, route mengembalikan 503 dengan header `X-Bifrost-Killswitch` dan operator dialihkan ke jalur TS. Gunakan untuk menonaktifkan sidecar tanpa melakukan deployment ulang (insiden router tingkat 1, rotasi kunci). |
| `BIFROST_BASE_URL` | _(tidak diatur)_ | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Jika diatur, route proksi sidecar Bifrost meneruskan lalu lintas `/v1/chat/completions` ke gateway Go ini, bukan ke handler relay TS. Tidak diatur → 503 dengan fallback. Garis miring di akhir akan dihapus. |
| `BIFROST_PORT` | `8080` | `src/lib/services/bootstrap.ts` | Port yang digunakan layanan tersemat Bifrost yang diawasi (`127.0.0.1:`) saat OmniRoute mengelola siklus hidup sidecar Bifrost. Default-nya adalah `8080`. |
| `BIFROST_API_KEY` | _(tidak diatur)_ | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Kunci API untuk gateway Bifrost (dikirim sebagai `Authorization: Bearer ...`). Jika tidak diatur, route mengharapkan permintaan membawa kunci API OmniRoute yang valid; kunci ini hanya digunakan untuk autentikasi di sisi gateway. |
| `BIFROST_STREAMING_ENABLED` | `true` | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Jika true, route sidecar Bifrost mengalirkan kembali respons melalui SSE via gateway, bukan melalui eksekutor streaming TS. Atur ke `0` untuk memaksa respons JSON non-streaming melalui gateway. |
| `BIFROST_TIMEOUT_MS` | `30000` | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Batas waktu per permintaan saat melakukan proksi ke gateway Bifrost (ms). Jika batas waktu terlampaui, route mengembalikan jalur relay TS melalui header `X-Bifrost-Fallback`. |
| `OMNIROUTE_BIFROST_KEY` | _(tidak diatur)_ | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Alias untuk `BIFROST_API_KEY` (digunakan oleh skrip yang membaca env melalui `OMNIROUTE_*`). `BIFROST_API_KEY` diprioritaskan jika keduanya diatur. |
| `OMNIROUTE_RELAY_BACKEND` | `ts` / `auto` | `src/app/api/v1/relay/chat/completions/routingBackend.ts` | Backend relay untuk `/api/v1/relay/chat/completions`: `ts \| bifrost \| auto`. `ts` = relay TypeScript (default jika Bifrost tidak dikonfigurasi); `auto` memilih Bifrost jika `BIFROST_BASE_URL` diatur dan `BIFROST_ENABLED` ≠ `0`, dengan fallback otomatis ke TS jika sidecar tidak dapat dijangkau; `bifrost` memaksa penggunaan Bifrost (ketat, tanpa fallback). Autentikasi/pembatasan laju/perlindungan injeksi/daftar izin selalu dijalankan terlebih dahulu di route Next. Respons menyertakan `X-Routing-Backend` / `X-Routing-Fallback` / `X-Routing-Fallback-Reason`. |
| `RELAY_ROUTING_BACKEND` | _(tidak diatur)_ | `src/app/api/v1/relay/chat/completions/routingBackend.ts` | Alias yang diterima untuk `OMNIROUTE_RELAY_BACKEND` (nilai `ts \| bifrost \| auto` yang sama). `OMNIROUTE_RELAY_BACKEND` memiliki prioritas jika keduanya diatur. |
| `OMNIROUTE_BIFROST_FAILURE_COOLDOWN_MS` | `5000` | `src/app/api/v1/relay/chat/completions/bifrostCooldown.ts` | Masa jeda (ms) setelah hop sidecar Bifrost gagal dalam mode `auto` sebelum relai mencoba kembali sidecar tersebut; relai merutekan langsung ke jalur TS selama masa jeda berlangsung, lalu melakukan probe lagi. `0` menonaktifkannya. Hanya berlaku jika `OMNIROUTE_RELAY_BACKEND=auto`. |
| `OMNIROUTE_TLS_CERT` | _(tidak diatur)_ | `bin/cli/commands/serve.mjs` | Jalur ke sertifikat TLS PEM untuk menyajikan `omniroute serve` melalui HTTPS (setara dengan `--tls-cert`). Harus dipasangkan dengan `OMNIROUTE_TLS_KEY`; server mandiri kemudian mengakhiri TLS pada listener yang sama (`wss://` tetap berfungsi tanpa perubahan). Tidak diatur → HTTP biasa. Jika hanya salah satu dari sertifikat/kunci yang diberikan, atau jalurnya tidak dapat dibaca, peringatan akan dicatat dan server tetap menggunakan HTTP. |
| `OMNIROUTE_TLS_KEY` | _(tidak diatur)_ | `bin/cli/commands/serve.mjs` | Jalur ke kunci privat TLS PEM untuk HTTPS `omniroute serve` (setara dengan `--tls-key`). Harus dipasangkan dengan `OMNIROUTE_TLS_CERT`. Lihat `OMNIROUTE_TLS_CERT`. |
| `OMNIROUTE_LOCAL_ENDPOINTS_ENABLED` | `0` | `src/lib/security/localEndpoints.ts` | Sakelar utama untuk rute `/api/local/*`. Jika tidak diatur atau bernilai `0`, semua rute `/api/local/*` mengembalikan 503 dalam produksi. Harus bernilai `1` pada deployment non-loopback untuk mengaktifkan peluncur Redis dan pemulai layanan lokal sekali klik serupa. Perlindungan berlapis bersama klasifikasi penjaga rute `isLocalOnlyPath()` (`LOCAL_ONLY_API_PREFIXES` di `src/server/authz/routeGuard.ts`). |
| `OMNIROUTE_LOCAL_ENDPOINTS_TOKEN` | _(tidak diatur)_ | `src/lib/security/localEndpoints.ts` | Token bearer untuk pemanggil `/api/local/*` yang tidak berada di loopback (misalnya aplikasi desktop). Jika diatur, permintaan dari IP non-loopback harus menyertakan `Authorization: Bearer `. Wajib ketika `OMNIROUTE_LOCAL_ENDPOINTS_ENABLED=1` pada deployment non-loopback. |
| `OMNIROUTE_REDIS_CONTAINER_NAME` | `omniroute-redis` | `bin/cli/commands/redis.mjs` | Nama kontainer untuk peluncur Redis sekali klik (`omniroute redis up`). Digunakan oleh CLI dan GUI `RedisLauncherPanel`. |
| `OMNIROUTE_REDIS_HOST_PORT` | `6379` | `bin/cli/commands/redis.mjs` | Port host untuk peluncur Redis sekali klik. Ubah ke nilai yang lebih tinggi jika host sudah menggunakan port 6379. Port internal kontainer tetap 6379. |
| `OMNIROUTE_REDIS_BIND_HOST` | `127.0.0.1` | `bin/cli/commands/redis.mjs` | Antarmuka host tempat peluncur Redis sekali klik dipublikasikan. Peluncur memulai Redis TANPA kata sandi, sehingga mengikat ke `0.0.0.0` memberikan setiap host di LAN Anda akses ke Redis tanpa autentikasi — perluas cakupan ini hanya jika Anda juga menetapkan sendiri kata sandi pada instans tersebut. |
| `REDIS_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Antarmuka host tempat docker-compose memublikasikan sidecar Redis (#9286). Redis compose berjalan tanpa `requirepass`; kontainer aplikasi mengaksesnya melalui jaringan compose (`redis:6379`) — port yang dipublikasikan hanya tersedia untuk alat di sisi host. `0.0.0.0` mengekspos Redis tanpa autentikasi ke seluruh LAN. |
| `REDIS_PORT` | `6379` | `docker-compose.yml` | Port host untuk sidecar Redis compose. |
| `APP_BIND_HOST` | `127.0.0.1` | `docker-compose.yml`, `docker-compose.prod.yml` | Antarmuka host tempat docker-compose memublikasikan port dashboard/API/live-WS milik aplikasi (#12568). Dengan `REQUIRE_API_KEY=false` sebagai nilai default dalam `.env.example`, `0.0.0.0` mengekspos proksi LLM `/v1` anonim ke seluruh LAN/WAN — perluas hanya setelah `REQUIRE_API_KEY=true` atau jika proksi balik di depannya memberlakukan autentikasinya sendiri. |
| `QDRANT_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Antarmuka host tempat docker-compose memublikasikan sidecar memori Qdrant (#12578). Pertimbangan eksposur LAN-nya sama seperti `REDIS_BIND_HOST`. |
| `BIFROST_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Antarmuka host tempat docker-compose memublikasikan sidecar router Bifrost (#12578). Pertimbangan eksposur LAN-nya sama seperti `REDIS_BIND_HOST`. |
| `REDIS_KEY_PREFIX` | `omniroute:` | `src/shared/utils/rateLimiter.ts` | Prefiks namespace yang diterapkan pada setiap kunci Redis OmniRoute (pembatas laju, cache autentikasi, penyimpanan kuota, pemutus sirkuit pemanasan). Mencegah benturan kunci saat instans Redis digunakan bersama aplikasi lain (#11042). |
| `OMNIROUTE_INTERNAL_SERVICE_TOKEN` | _(tidak disetel — mekanisme dinonaktifkan)_ | `src/lib/api/internalServiceAuth.ts` | Rahasia bersama untuk lompatan REST internal yang mempertahankan identitas (#9260): komponen OmniRoute yang memanggil rute OmniRoute lokal lainnya mengirimkannya sebagai `x-omniroute-internal-service-token` sehingga identitas pemanggil asli tetap dipertahankan. Dibandingkan menggunakan `timingSafeEqual`. |
| `OMNIROUTE_INTERNAL_SERVICE_TOKEN_FILE` | _(tidak disetel)_ | `src/lib/api/internalServiceAuth.ts` | Varian file rahasia dari token layanan internal: jalur ke file yang kontennya, setelah spasi di awal dan akhir dihapus, merupakan token tersebut. Hanya diperiksa ketika variabel inline tidak disetel. |
| `OPENROUTER_PROVIDER_STATS_ENABLED` | `true` | `src/lib/catalog/openrouterProviderStats.ts` | Memperkaya daftar penyedia di dashboard dengan statistik peringkat mingguan OpenRouter (#9324). Aktif secara default; setel ke `false` untuk sepenuhnya melewati pengambilan di latar belakang (tidak memblokir dan tidak pernah berakibat fatal). |
| `OPENROUTER_PROVIDER_STATS_TTL_MS` | `86400000` (24 jam) | `src/lib/catalog/openrouterProviderStats.ts` | TTL cache untuk snapshot statistik penyedia OpenRouter, dalam milidetik. |
| `OMNIROUTE_REDIS_IMAGE` | `redis:7-alpine` | `bin/cli/commands/redis.mjs` | Image Redis yang digunakan oleh peluncur Redis 1-klik. Ganti dengan `redis:8-alpine` atau mirror registry privat sesuai kebutuhan. |
| `QDRANT_HOST` | `qdrant` | _(profil klaster opsional)_ | Nama host sidecar Qdrant saat `--profile memory` aktif. Nilai default mengarah ke nama layanan qdrant dalam jaringan; timpa untuk deployment eksternal. Hanya digunakan saat `qdrantEnabled` bernilai `true` dalam kode (`src/lib/memory/vectorStore.ts:108`). |
| `QDRANT_PORT` | `6333` | _(profil klaster opsional)_ | Port REST sidecar Qdrant. |
| `QDRANT_GRPC_PORT` | `6334` | _(profil klaster opsional)_ | Port gRPC sidecar Qdrant. Digunakan oleh pustaka klien yang lebih memilih gRPC daripada REST untuk operasi streaming. |
| `QDRANT_API_KEY` | _(tidak ditetapkan)_ | _(profil klaster opsional)_ | Kunci API opsional untuk Qdrant Cloud atau instans lokal yang diautentikasi. Kosong → tidak ada header `api-key` yang dikirim. |
| `QDRANT_COLLECTION` | `omniroute-memory` | _(profil klaster opsional)_ | Nama koleksi untuk embedding memori percakapan OmniRoute. Dibuat saat pertama kali dijalankan dengan dimensi `QDRANT_VECTOR_SIZE`. |
| `QDRANT_EMBEDDING_MODEL` | `text-embedding-3-small` | _(profil klaster opsional)_ | Nama model embedding default yang dicatat dalam metadata koleksi Qdrant. Embedding aktual dihasilkan oleh penyedia yang dirujuk oleh bidang `embeddingModel` dalam pengaturan OmniRoute. |
| `QDRANT_VECTOR_SIZE` | `1536` | _(profil klaster opsional)_ | Dimensi vektor embedding. Harus sesuai dengan model yang Anda gunakan untuk membuat embedding (text-embedding-3-small → 1536; ada-002 → 1536; nomic-embed-text → 768). |
| `QDRANT_HNSW_EF_CONSTRUCT` | `128` | _(profil klaster opsional)_ | Akurasi saat konstruksi indeks HNSW. Lebih tinggi = build lebih lambat, pencarian lebih cepat. |
| `OMNIROUTE_ROTATION_ENABLED` | `true` | `open-sse/services/rotationConfig.ts` | Sakelar utama untuk rotasi akun yang dapat dikonfigurasi operator. Saat `false`, tidak ada satu pun kelas `OMNIROUTE_ROTATE_*` di bawah ini yang memicu fallback akun (status nonaktif utama juga memblokir kelas 429/500/502 yang secara default diaktifkan). Memungkinkan frontend pengawas (misalnya aplikasi desktop VibeProxy) mencerminkan aturan rotasinya sendiri ke mesin fallback akun backend. |
| `OMNIROUTE_ROTATION_RATE_LIMIT_RESET_SECONDS` | `0` | `open-sse/services/rotationConfig.ts` | Waktu tunggu (detik) yang diterapkan pada akun yang terkena pembatasan laju saat upstream tidak memberikan petunjuk reset yang eksplisit. `0` = gunakan waktu tunggu default mesin alih-alih penggantian tetap. |
| `OMNIROUTE_ROTATION_DISABLE_TAG_WITHOUT_RESET` | `true` | `open-sse/services/rotationConfig.ts` | Cerminan preferensi front-end "jangan tandai sebagai terkena pembatasan laju tanpa waktu reset". |
| `OMNIROUTE_ROTATE_ON_429` | `true` | `open-sse/services/rotationConfig.ts` | Mengaktifkan fallback per status untuk galat `429`. Jika `false` (dan `OMNIROUTE_ROTATION_ENABLED=true`), galat `429` tidak lagi memicu rotasi akun dan sebagai gantinya dikembalikan kepada klien. |
| `OMNIROUTE_ROTATE_429_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Jumlah galat `429` dalam `OMNIROUTE_ROTATE_429_WINDOW_SECONDS` yang diperlukan sebelum akun dirotasi. `1` (bawaan) langsung merotasi akun, sehingga mempertahankan perilaku sebelumnya. |
| `OMNIROUTE_ROTATE_429_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Jendela bergulir (detik) untuk menghitung galat `429` terhadap `OMNIROUTE_ROTATE_429_THRESHOLD`. |
| `OMNIROUTE_ROTATE_ON_500` | `true` | `open-sse/services/rotationConfig.ts` | Mengaktifkan fallback per status untuk galat server `5xx` (kecuali `502`, yang memiliki kelas tersendiri). Jika `false`, galat ini tidak lagi memicu rotasi akun. |
| `OMNIROUTE_ROTATE_500_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Jumlah galat `5xx` dalam `OMNIROUTE_ROTATE_500_WINDOW_SECONDS` yang diperlukan sebelum akun dirotasi. `1` (bawaan) langsung merotasi akun. |
| `OMNIROUTE_ROTATE_500_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Jendela bergulir (detik) untuk menghitung galat `5xx` terhadap `OMNIROUTE_ROTATE_500_THRESHOLD`. |
| `OMNIROUTE_ROTATE_ON_502` | `true` | `open-sse/services/rotationConfig.ts` | Mengaktifkan fallback per status untuk galat `502` (gateway bermasalah). Jika `false`, galat `502` tidak lagi memicu rotasi akun. |
| `OMNIROUTE_ROTATE_502_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Jumlah galat `502` dalam `OMNIROUTE_ROTATE_502_WINDOW_SECONDS` yang diperlukan sebelum akun dirotasi. `1` (bawaan) langsung merotasi akun. |
| `OMNIROUTE_ROTATE_502_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Jendela bergulir (detik) untuk menghitung galat `502` terhadap `OMNIROUTE_ROTATE_502_THRESHOLD`. |
| `OMNIROUTE_ROTATE_ON_400` | `false` | `open-sse/services/rotationConfig.ts` | Opsional (default NONAKTIF): jika `true`, respons `400` biasa (permintaan tidak valid) juga memicu rotasi akun. Ini hanya bersifat menambahkan — tidak pernah menghalangi perilaku mesin yang sudah ada, yaitu respons `400` yang memuat teks batas laju/kuota tetap melakukan peralihan terlepas dari nilai flag ini. |
| `OMNIROUTE_ROTATE_400_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Jumlah kesalahan `400` dalam `OMNIROUTE_ROTATE_400_WINDOW_SECONDS` yang diperlukan sebelum akun dirotasi (hanya digunakan ketika `OMNIROUTE_ROTATE_ON_400=true`). |
| `OMNIROUTE_ROTATE_400_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Jendela bergulir (dalam detik) untuk menghitung kesalahan `400` terhadap `OMNIROUTE_ROTATE_400_THRESHOLD`. |
### Penjadwal Pemanasan Claude
Pemanasan berbasis cron untuk koneksi OAuth Anthropic yang telah diikutsertakan, sehingga jendela batas laju 5 jam dibuka oleh permintaan terjadwal sederhana, bukan oleh permintaan nyata pertama (#8848). Penjadwal tetap nonaktif kecuali `OMNIROUTE_WARMUP_ENABLED` bernilai truthy **dan** koneksi ditandai dalam `settings.claudeWarmup.connections`; daftar koneksi kosong berarti tidak ada koneksi yang dipanaskan meskipun variabel lingkungan diaktifkan.
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------ | ------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OMNIROUTE_WARMUP_ENABLED` | _(tidak ditetapkan → nonaktif)_ | `src/lib/warmupScheduler.ts` | Sakelar utama untuk penjadwal pemanasan. Menerima `1`/`true`/`yes`/`on` (tidak peka huruf besar-kecil, spasi di awal dan akhir dihapus). Nilai lain, atau jika tidak ditetapkan, membuat penjadwal tetap nonaktif. |
| `OMNIROUTE_WARMUP_CRON` | `0 7 * * *` | `src/lib/warmupScheduler.ts` | Ekspresi cron lima bidang untuk pemicu pemanasan, dievaluasi dalam `America/Los_Angeles` (zona waktu pengaturan ulang Anthropic) terlepas dari waktu host. |
| `OMNIROUTE_WARMUP_CONCURRENCY` | `3` | `src/lib/warmupScheduler.ts` | Jumlah koneksi yang dipanaskan secara paralel per pemicu. Dibatasi ke rentang `1`-`10`; nilai nonnumerik kembali ke `3`. |
| `OMNIROUTE_WARMUP_MODEL` | `claude-3-5-haiku-20241022` | `src/lib/warmupScheduler.ts` | Model yang digunakan untuk permintaan pemanasan. Ganti hanya jika model default tidak tersedia pada paket Anda; pilih model termurah yang tetap dapat membuka jendela tersebut. |
### Sesi VNC untuk Login Browser & Alias Direktori Data
Chromium+VNC dalam container yang digunakan untuk pengambilan kredensial login browser secara interaktif (`/api/vnc-session`), beserta alias lama `DATA_DIR`. Semuanya opsional — nilai default VNC menargetkan image bawaan `omniroute-vnc-chromium:local` dan hanya perlu diganti untuk image container khusus, port khusus, atau penyesuaian siklus hidup.
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_VNC_IMAGE` | `omniroute-vnc-chromium:local` | `src/lib/vncSession/manifest.ts` | Tag image Docker untuk container login Chromium+VNC. Build `docker/vnc-browser/chromium` atau arahkan variabel ini ke image kustom. |
| `OMNIROUTE_DOCKER_BIN` | `docker` | `src/lib/vncSession/manifest.ts` | Binary runtime container yang digunakan untuk menjalankan container VNC (misalnya, atur ke `podman`). |
| `OMNIROUTE_VNC_CONTAINER_VNC_PORT` | `3000` | `src/lib/vncSession/manifest.ts` | Port VNC/noVNC yang diekspos di dalam container. |
| `OMNIROUTE_VNC_CONTAINER_CDP_PORT` | `9223` | `src/lib/vncSession/manifest.ts` | Port Chrome DevTools Protocol di dalam container. |
| `OMNIROUTE_VNC_CONTAINER_PROFILE_DIR` | `/config` | `src/lib/vncSession/manifest.ts` | Path direktori profil Chromium di dalam container. |
| `OMNIROUTE_VNC_PROFILE_DIR` | `$HOME/.omniroute/browser-login-profiles` | `src/lib/vncSession/manifest.ts` | Direktori host yang menyimpan profil login browser yang dipertahankan. |
| `OMNIROUTE_VNC_IDLE_MS` | `600000` (10 mnt) | `src/lib/vncSession/manifest.ts` | Batas waktu idle (mdtk) sebelum sesi VNC yang tidak aktif dihapus. |
| `OMNIROUTE_VNC_MAX_MS` | `1800000` (30 mnt) | `src/lib/vncSession/manifest.ts` | Batas maksimum mutlak (mdtk) untuk masa aktif satu sesi VNC. |
| `OMNIROUTE_VNC_MAX_SESSIONS` | `4` | `src/lib/vncSession/manifest.ts` | Jumlah maksimum sesi VNC yang berjalan secara bersamaan. |
| `OMNIROUTE_VNC_READY_MS` | `45000` | `src/lib/vncSession/manifest.ts` | Batas waktu (mdtk) untuk menunggu browser dalam container siap digunakan melalui CDP. |
| `OMNIROUTE_VNC_HARVEST_MS` | `20000` | `src/lib/vncSession/manifest.ts` | Batas waktu (mdtk) untuk mengambil sesi/cookie yang direkam setelah proses login selesai. |
| `OMNIROUTE_VNC_CHROMIUM_ARGS` | `--remote-debugging-port=9222 --no-first-run --no-default-browser-check` | `src/lib/vncSession/manifest.ts` | Flag baris perintah tambahan yang diteruskan ke Chromium dalam container. |
| `OMNIROUTE_VNC_NETWORK` | `omniroute-vnc-browser-login` | `src/lib/vncSession/manifest.ts` | Jaringan Docker khusus yang digunakan oleh container login VNC (#12571), bukan bridge default, agar container lain tidak dapat mengakses port bridge CDP-nya. |
| `VIBEPROXY_DATA_DIR` | _(tidak diatur)_ | `open-sse/services/notionThreadSessions.ts` | **Alias lama** untuk `DATA_DIR`, yang diperiksa hanya setelah `DATA_DIR` dan `OMNIROUTE_DATA_DIR` sama-sama tidak diatur. Menentukan lokasi cache sesi thread web Notion (`/notion-web-thread-sessions.json`). |
---
## 26. Harness Pengujian & E2E
Digunakan oleh `scripts/dev/run-next-playwright.mjs`, `scripts/dev/smoke-electron-packaged.mjs`,
`scripts/dev/run-ecosystem-tests.mjs`, dan `scripts/build/uninstall.mjs`. Biarkan semua
nilai di bawah ini tidak disetel dalam deployment produksi.
| Variabel | Default | File Sumber | Deskripsi |
| -------------------------------------- | ----------------------------------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_E2E_BOOTSTRAP_MODE` | `auth` | `scripts/dev/run-next-playwright.mjs` | Mode bootstrap E2E (`auth`, `fresh`, `reuse`) untuk runner Playwright. |
| `OMNIROUTE_E2E_PASSWORD` | menggunakan `INITIAL_PASSWORD` sebagai fallback | `scripts/dev/run-next-playwright.mjs` | Kata sandi admin yang diinjeksikan ke dalam lingkungan Playwright. |
| `OMNIROUTE_DISABLE_LOCAL_HEALTHCHECK` | `true` | `scripts/dev/run-next-playwright.mjs` | Menonaktifkan polling pemeriksaan kesehatan lokal selama proses Playwright berlangsung. |
| `OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK` | `true` | `scripts/dev/run-next-playwright.mjs` | Menonaktifkan loop pemeriksaan kesehatan token OAuth selama pengujian. |
| `OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS` | _(tidak disetel)_ | `src/lib/tokenHealthCheck.ts` | Penyedia yang dipisahkan koma dan dikecualikan dari penyisiran pembaruan token proaktif (misalnya, `codex,openai`). Alternatif tertarget untuk menonaktifkan pemeriksaan kesehatan sepenuhnya—penyedia dengan TTL singkat tetap diperbarui, sedangkan penyedia berantai tetap hanya reaktif. |
| `OMNIROUTE_HIDE_HEALTHCHECK_LOGS` | `true` | `scripts/dev/run-next-playwright.mjs` | Membisukan derau pemeriksaan kesehatan di stdout Playwright. |
| `OMNIROUTE_PLAYWRIGHT_SKIP_BUILD` | `0` | `scripts/dev/run-next-playwright.mjs` | Melewati build produksi Next.js sebelum Playwright dimulai (pengoptimalan CI). |
| `OMNIROUTE_SKIP_UNINSTALL_HOOK` | `0` | `scripts/build/uninstall.mjs` | Melewati hook penghapusan instalasi OmniRoute (digunakan oleh CI agar `node_modules` tetap utuh). |
| `ECOSYSTEM_SERVER_WAIT_MS` | `180000` | `scripts/dev/run-ecosystem-tests.mjs` | Waktu tunggu (ms) hingga server menjadi sehat sebelum menjalankan pengujian ekosistem/protokol. |
| `ELECTRON_SMOKE_URL` | `http://127.0.0.1:20128/login` | `scripts/dev/smoke-electron-packaged.mjs` | URL yang diharapkan oleh harness smoke Electron untuk disajikan oleh aplikasi terpaket. |
| `ELECTRON_SMOKE_TIMEOUT_MS` | `45000` | `scripts/dev/smoke-electron-packaged.mjs` | Batas waktu total (ms) sebelum harness smoke berhenti mencoba. |
| `ELECTRON_SMOKE_SETTLE_MS` | `2000` | `scripts/dev/smoke-electron-packaged.mjs` | Jendela waktu stabilisasi (ms) setelah halaman dimuat. |
| `ELECTRON_SMOKE_APP_EXECUTABLE` | _(otomatis)_ | `scripts/dev/smoke-electron-packaged.mjs` | Path eksplisit ke file executable Electron terpaket. |
| `ELECTRON_SMOKE_DATA_DIR` | _(tmpdir)_ | `scripts/dev/smoke-electron-packaged.mjs` | Direktori data untuk proses smoke Electron. |
| `ELECTRON_SMOKE_KEEP_DATA` | `0` | `scripts/dev/smoke-electron-packaged.mjs` | Atur ke `1` untuk mempertahankan direktori data smoke setelah proses dijalankan. |
| `ELECTRON_SMOKE_STREAM_LOGS` | `0` | `scripts/dev/smoke-electron-packaged.mjs` | Atur ke `1` untuk mengalirkan log Electron ke stdout selama proses berlangsung. |
| `ELECTRON_SMOKE_COLD_RESTART` | `0` | `scripts/dev/smoke-electron-packaged.mjs` | #7592: luncurkan ulang menggunakan direktori data yang sama dan pastikan peluncuran kedua memilih driver SQLite native. |
| `CLI_DEVIN_BIN` | _(pencarian PATH)_ | `open-sse/executors/devin-cli.ts` | Timpa jalur biner Devin CLI. |
### Pipeline penerjemahan dokumentasi
Digunakan oleh `scripts/i18n/run-translation.mjs` (perintah `npm run i18n:run`).
Kelima variabel secara default tidak ditetapkan — tetapkan variabel tersebut di `.env` hanya pada mesin
yang seharusnya dapat menjalankan penerjemah dokumentasi.
| Variabel | Default | File Sumber | Deskripsi |
| ----------------------------------- | -------------------- | ---------------------------------- | ------------------------------------------------------------------------- |
| `OMNIROUTE_TRANSLATION_API_URL` | _(tidak ditetapkan)_ | `scripts/i18n/run-translation.mjs` | URL dasar yang kompatibel dengan OpenAI untuk backend penerjemahan. |
| `OMNIROUTE_TRANSLATION_API_KEY` | _(tidak ditetapkan)_ | `scripts/i18n/run-translation.mjs` | Token bearer untuk backend penerjemahan (tidak pernah dicatat dalam log). |
| `OMNIROUTE_TRANSLATION_MODEL` | _(tidak ditetapkan)_ | `scripts/i18n/run-translation.mjs` | ID model, misalnya `gpt-4o-mini` atau `cx/gpt-5.4-mini`. |
| `OMNIROUTE_TRANSLATION_TIMEOUT_MS` | `60000` | `scripts/i18n/run-translation.mjs` | Batas waktu per permintaan dalam milidetik. |
| `OMNIROUTE_TRANSLATION_CONCURRENCY` | `4` | `scripts/i18n/run-translation.mjs` | Permintaan penerjemahan paralel saat dijalankan pada beberapa file/lokal. |
---
## 27. Umpan Radar (Hosting Mandiri)
Pengaya opsional yang dikendalikan oleh flag fitur RADAR_ENABLED (dinonaktifkan secara default — sebuah flag
fitur yang diaktifkan atau dinonaktifkan melalui Settings/DB, bukan variabel lingkungan; lihat
[docs/frameworks/RADAR.md](../frameworks/RADAR.md#flag-radar_enabled-default-off)).
Empat variabel pertama di bawah ini adalah penggantian opsional untuk umpan yang di-hosting sendiri atau
hasil fork serta alur kunci pendukung. Variabel kelima, `RADAR_ADMIN_URL`, adalah tautan terpisah tanpa
nilai default ke panel operasi pribadi milik pemilik. Lihat [docs/frameworks/RADAR.md](../frameworks/RADAR.md) untuk
dokumentasi modul lengkap beserta
[urutan aktivasi menyeluruh dan penyiapan terpandu](../frameworks/RADAR.md#end-to-end-activation-and-guided-setup).
Pembaca pengumuman umum Beranda/Log Perubahan tidak dikonfigurasi melalui variabel
lingkungan dan tidak bergantung pada flag fitur RADAR_ENABLED. Pembaca ini mengakses URL `news.json`
repositori publik yang dideklarasikan dalam `src/shared/utils/releaseNotes.ts` hanya melalui
GET; ID pengabaian tetap disimpan dalam penyimpanan lokal browser.
| Variabel | Default | File Sumber | Deskripsi |
| ----------------------------- | -------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `RADAR_FEED_URL` | `https://radar.omniroute.online` | `src/lib/radar/{sync,referralsSync,offersSync,intelSync}.ts` | URL dasar yang digunakan bersama oleh umpan katalog, rujukan, penawaran pendukung, dan Intel yang ditandatangani secara terpisah. Ganti untuk mengarahkannya ke layanan yang di-hosting sendiri atau hasil fork. |
| `RADAR_FEED_PUBKEY` | _(kunci default yang disematkan)_ | `src/lib/radar/pinnedKeys.ts` | Kunci publik Ed25519 (SPKI DER base64 atau PEM) yang digunakan untuk memverifikasi tanda tangan umpan dari umpan khusus. |
| `RADAR_CONTRIBUTOR_CLAIM_URL` | `https://radar.omniroute.online/auth/github` | `src/lib/radar/links.ts` | URL yang dibuka oleh tombol dasbor "Saya seorang kontributor" (alur klaim kunci pendukung melalui OAuth GitHub). |
| `RADAR_SUPPORTER_PLANS_URL` | `https://radar.omniroute.online/planos` | `src/lib/radar/links.ts` | URL yang dibuka oleh tombol dasbor "Dukung proyek ini" (halaman pembayaran/paket). |
| `RADAR_ADMIN_URL` | _(tidak ditetapkan)_ | `src/lib/radar/links.ts` | Tautan panel operasi pribadi khusus pemilik. HTTPS diwajibkan, kecuali untuk penerusan SSH loopback HTTP; nilai yang tidak ditetapkan atau tidak valid tidak akan membuat item navigasi. |
---
## Audit: Variabel yang Dihapus / Tidak Digunakan
Variabel berikut muncul dalam versi `.env.example` sebelumnya, tetapi **tidak memiliki referensi runtime** dalam basis kode saat ini. Variabel tersebut telah dihapus:
| Variabel | Alasan |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `STORAGE_DRIVER=sqlite` | Tidak pernah dibaca oleh file sumber mana pun. SQLite adalah satu-satunya driver yang didukung — tidak perlu melakukan pemilihan. |
| `INSTANCE_NAME=omniroute` | Terdapat dalam dokumentasi/templat env lama, tetapi tidak digunakan saat runtime. Mungkin akan kembali dalam fitur multi-instans di masa mendatang. |
| `SQLITE_MAX_SIZE_MB=2048` | Tidak dirujuk dalam kode sumber. Ukuran database tidak dibatasi secara artifisial. |
| `SQLITE_CLEAN_LEGACY_FILES=true` | Tidak dirujuk dalam kode sumber. Pembersihan lama kemungkinan telah dihapus. |
| `CLI_ROO_BIN` | Tidak terdaftar di `src/shared/services/cliRuntime.ts`. |
| `CLI_KIMI_CODING_BIN` | Tidak terdaftar di `src/shared/services/cliRuntime.ts` (Kimi Coding menggunakan OAuth, bukan biner CLI). |
| `IFLOW_OAUTH_CLIENT_ID` / `IFLOW_OAUTH_CLIENT_SECRET` | Tidak dirujuk di mana pun dalam kode sumber. |
| `CEREBRAS_API_KEY` / `COHERE_API_KEY` / `FIREWORKS_API_KEY` / `GROQ_API_KEY` / `MISTRAL_API_KEY` / `NEBIUS_API_KEY` / `PERPLEXITY_API_KEY` / `TOGETHER_API_KEY` / `XAI_API_KEY` | Dihapus di v3.8.0. Runtime tidak lagi membaca variabel env ini — kredensial berasal dari Dashboard / `data/provider-credentials.json` / DB terenkripsi. |
| `CURSOR_PROTOBUF_DEBUG` | Dihapus di v3.8.0. Eksekutor Cursor menggunakan `CURSOR_DEBUG` / `CURSOR_STREAM_DEBUG` (lihat §22). |
| `CLI_COMPAT_KIRO` | Dihapus di v3.8.0. Kiro termasuk dalam `CLI_COMPAT_OMITTED_PROVIDER_IDS` — toggle-nya tidak berpengaruh. |
| `QIANFAN_API_KEY` | Dihapus bersama stub kunci API penyedia lain yang tidak digunakan di v3.8.0. |
### Koreksi Nilai Default
| Variabel | Nilai `.env.example` Lama | Default Kode Aktual | Perbaikan |
| ------------------------- | ------------------------- | ------------------- | ----------------------------------------------------------------------- |
| `APP_LOG_RETENTION_DAYS` | `90` | `7` | ✅ Nilai yang menyesatkan dihapus; `7` didokumentasikan sebagai default |
| `CALL_LOG_RETENTION_DAYS` | `90` | `7` | ✅ Nilai yang menyesatkan dihapus; `7` didokumentasikan sebagai default |
### Regenerasi konfigurasi OpenCode (tooling ad hoc)
Digunakan oleh `scripts/ad-hoc/regen-opencode-config.ts` untuk meregenerasi `opencode.json`
dengan nilai `limit.context` dan `limit.output` yang akurat, yang diambil dari instans
OmniRoute yang sedang berjalan. Tidak satu pun dari variabel ini diperlukan untuk operasi normal — skrip tersebut
hanya merupakan tooling pengembang.
| Variabel | Default | File Sumber | Deskripsi |
| ------------------ | ------------------------ | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_URL` | `http://localhost:20128` | `scripts/ad-hoc/regen-opencode-config.ts` | URL dasar instans OmniRoute yang akan dikueri untuk `/v1/models`. |
| `OMNIROUTE_KEY` | _(tidak disetel)_ | `scripts/ad-hoc/regen-opencode-config.ts` | Kunci API untuk mengautentikasi ke endpoint `/v1/models` OmniRoute. Menggunakan `OPENCODE_API_KEY` sebagai fallback jika tidak disetel. |
| `OPENCODE_API_KEY` | _(tidak disetel)_ | `scripts/ad-hoc/regen-opencode-config.ts` | Kunci API bergaya OpenCode (`sk-...`) yang ditulis ke dalam `opencode.json` yang dibuat ulang. Menggunakan `OMNIROUTE_KEY` sebagai fallback jika tidak disetel. |
### Harness evaluasi kompresi offline (alat ad hoc)
Digunakan oleh `scripts/compression-eval/index.ts`, CLI evaluasi kompresi offline.
Tidak diperlukan untuk operasi normal — hanya alat pengembang.
| Variabel | Default | File Sumber | Deskripsi |
| ---------------------------- | ------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_EVAL_CREDENTIALS` | `{}` (kosong) | `scripts/compression-eval/index.ts` | Kredensial JSON yang disediakan operator untuk penyedia yang diuji oleh CLI evaluasi kompresi offline (diuraikan dengan `JSON.parse`). Biarkan tidak disetel untuk dry run. |
### Sesi Browser VNC
Digunakan oleh `src/lib/vncSession/manifest.ts` untuk mengonfigurasi sesi Chromium headless berbasis Docker bagi penyedia otomatisasi browser. Semuanya opsional — nilai default ditampilkan di bawah.
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------------- | ------------------------------ | ------------------------------------------- | ------------------------------------------------------------------------------------- |
| `OMNIROUTE_DOCKER_BIN` | `docker` | `src/lib/vncSession/manifest.ts` | Jalur ke biner Docker yang digunakan untuk menjalankan kontainer VNC. |
| `OMNIROUTE_VNC_IMAGE` | `omniroute-vnc-chromium:local` | `src/lib/vncSession/manifest.ts` | Image Docker untuk kontainer Chromium VNC. |
| `OMNIROUTE_VNC_CHROMIUM_ARGS` | _(flag bawaan)_ | `src/lib/vncSession/manifest.ts` | Argumen CLI Chromium tambahan yang diteruskan ke browser di dalam kontainer. |
| `OMNIROUTE_VNC_CONTAINER_VNC_PORT` | `3000` | `src/lib/vncSession/manifest.ts` | Port VNC di dalam kontainer. |
| `OMNIROUTE_VNC_CONTAINER_CDP_PORT` | `9223` | `src/lib/vncSession/manifest.ts` | Port Chrome DevTools Protocol di dalam kontainer. |
| `OMNIROUTE_VNC_CONTAINER_PROFILE_DIR` | `/config` | `src/lib/vncSession/manifest.ts` | Direktori profil di dalam kontainer. |
| `OMNIROUTE_VNC_PROFILE_DIR` | _(tidak disetel)_ | `src/lib/vncSession/manifest.ts` | Direktori sisi host untuk profil browser persisten. |
| `OMNIROUTE_VNC_IDLE_MS` | `600000` | `src/lib/vncSession/manifest.ts` | Batas waktu tidak aktif (md) sebelum sesi VNC dihentikan. |
| `OMNIROUTE_VNC_MAX_MS` | `1800000` | `src/lib/vncSession/manifest.ts` | Durasi sesi maksimum (md). |
| `OMNIROUTE_VNC_MAX_SESSIONS` | `4` | `src/lib/vncSession/manifest.ts` | Jumlah maksimum sesi VNC serentak. |
| `OMNIROUTE_VNC_READY_MS` | `45000` | `src/lib/vncSession/manifest.ts` | Batas waktu kesiapan browser (md). |
| `OMNIROUTE_VNC_HARVEST_MS` | `20000` | `src/lib/vncSession/manifest.ts` | Batas waktu penghentian/pembersihan (md). |
| `OMNIROUTE_VNC_NETWORK` | `omniroute-vnc-browser-login` | `src/lib/vncSession/manifest.ts` | Jaringan Docker khusus yang diikuti kontainer (#12571), terpisah dari bridge default. |
| `VIBEPROXY_DATA_DIR` | _(tidak disetel)_ | `open-sse/services/notionThreadSessions.ts` | Direktori untuk persistensi sesi thread Notion. |
### Autentikasi layanan internal
| Variabel | Default | Deskripsi |
| --------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| `OMNIROUTE_INTERNAL_SERVICE_TOKEN` | – | Token inline untuk autentikasi antarlayanan pada bidang manajemen. |
| `OMNIROUTE_INTERNAL_SERVICE_TOKEN_FILE` | – | Jalur ke file yang berisi token layanan internal (lebih disarankan dalam kontainer; menggantikan variabel inline). |
### Statistik penyedia OpenRouter
| Variabel | Default | Deskripsi |
| ----------------------------------- | --------- | ----------------------------------------------------------------------------------------------------- |
| `OPENROUTER_PROVIDER_STATS_ENABLED` | `true` | Atur ke `false` untuk melewati pengambilan statistik per penyedia OpenRouter untuk pengayaan katalog. |
| `OPENROUTER_PROVIDER_STATS_TTL_MS` | `3600000` | TTL cache (md) untuk statistik penyedia OpenRouter yang diambil. |
### Binding Redis tertanam
| Variabel | Default | Deskripsi |
| --------------------------- | ----------- | --------------------------------------------------------------------- |
| `REDIS_BIND_HOST` | `127.0.0.1` | Alamat bind untuk layanan Redis tertanam. |
| `REDIS_PORT` | `6379` | Port untuk layanan Redis tertanam. |
| `OMNIROUTE_REDIS_BIND_HOST` | – | Penggantian dalam cakupan OmniRoute untuk alamat bind Redis tertanam. |
---
## 24. Penambahan rilis v3.8.50
Pengaturan ini diperkenalkan setelah snapshot kontrak lingkungan sebelumnya.
| Variabel | Default | File Sumber | Deskripsi |
| ------------------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_CHAT_ADMISSION_QUEUE_MS` | `2000` | `src/shared/middleware/chatBodyAdmission.ts` | Waktu tunggu maksimum untuk slot penerimaan chat kelas berat sebelum mengembalikan `503` yang dapat dicoba ulang; waktu tunggu singkat yang dibatasi akan menserialkan lonjakan permintaan agen alih-alih langsung mengembalikan `503`. Nilai `0` memulihkan penolakan langsung. |
| `OMNIROUTE_CHAT_ADMISSION_MAX_QUEUED_BYTES` | `4194304` (4 MB) | `src/shared/middleware/chatBodyAdmission.ts` | Anggaran byte dalam antrean untuk waktu tunggu penerimaan: membatasi total byte isi yang disangga dan ditahan di seluruh proses agar waktu tunggu tidak memperbesar heap (#4380). Permintaan tunggu yang melampaui anggaran langsung menerima `503` yang dapat dicoba ulang. |
| `OMNIROUTE_CHAT_VIRTUAL_TTL_MS` | `60000` (60 dtk) | `src/shared/middleware/chatBodyAdmission.ts` | Tidak digunakan lagi dan tidak melakukan apa pun sejak #10110: jalur penerimaan per sesi telah dihapus dan digantikan dengan satu anggaran untuk seluruh proses. Diterima untuk kompatibilitas konfigurasi; diabaikan. |
| `OMNIROUTE_CHAT_VIRTUAL_MAX_SESSIONS` | `64` | `src/shared/middleware/chatBodyAdmission.ts` | Tidak digunakan lagi dan tidak melakukan apa pun sejak #10110: jalur penerimaan per sesi telah dihapus dan digantikan dengan satu anggaran untuk seluruh proses. Diterima untuk kompatibilitas konfigurasi; diabaikan. |
| `OMNIROUTE_CHAT_VIRTUAL_LANES` | `0` (nonaktif) | `open-sse/services/admission/runtime.ts` | Jalur penerimaan virtual runtime adaptif (#9654): sakelar utama untuk gerbang adaptif per penyewa (sistem 2). Berbeda dari variabel jalur per koneksi yang tidak digunakan lagi di atas (TTL_MS / MAX_SESSIONS, tidak melakukan apa pun sejak #10110). Flag fitur dasbor dengan nama yang sama; variabel lingkungan lebih diprioritaskan daripada penggantian dari dasbor; memerlukan mulai ulang. |
| `OMNIROUTE_RUNNOW_TIMEOUT_MS` | `30000` | `src/app/api/jobs/[id]/run-now/route.ts` | Membatasi durasi tunggu panggilan run-now terhadap tugas yang sedang berjalan sebelum memulai eksekusi dalam antrean. |
| `ADOBE_FIREFLY_BROWSER_REFRESH` | diaktifkan | `open-sse/services/adobeFireflySession.ts` | Menjaga status IMS dan risiko browser tetap mutakhir melalui sesi Chrome CDP dengan cakupan akun; atur ke `0` untuk menonaktifkannya. |
| `ADOBE_FIREFLY_SESSION_DISK` | diaktifkan | `open-sse/services/adobeFireflySession.ts` | Menyimpan sesi Adobe yang telah diperbaiki di bawah `DATA_DIR`; atur ke `0` agar status hanya disimpan dalam memori. |
| `ADOBE_FIREFLY_MIN_SUBMIT_GAP_MS` | `12000` | `open-sse/services/adobeFireflySession.ts` | Jarak waktu minimum antara pengiriman permintaan pembuatan Adobe Firefly. |
| `ADOBE_FIREFLY_BATCH_EXTRA_GAP_MS` | `15000` | `open-sse/services/adobeFireflySession.ts` | Periode jeda tambahan setelah setiap pengiriman Adobe ketiga yang berhasil. |
| `ADOBE_FIREFLY_CHROME_HEADLESS` | `0` | `open-sse/services/adobeFireflyBrowserLogin.ts` | Mode headless murni khusus debug; Adobe colligo biasanya menolak sesi risiko yang dihasilkan. |
| `CHROME_PATH` | deteksi otomatis | `open-sse/executors/cloudflare-playground.ts`, `open-sse/executors/chatgpt-web-codex.ts` | Lokasi absolut opsional executable Chrome yang digunakan oleh eksekutor berbasis browser ketika deteksi otomatis platform tidak memadai. |
| `TELEGRAM_BOT_TOKEN` | _(belum diatur)_ | `src/lib/telegram/config.ts` | Token BotFather yang mengaktifkan webhook masuk dan menandatangani `initData` Mini App. |
| `TELEGRAM_WEBHOOK_SECRET` | _(belum diatur)_ | `src/lib/telegram/config.ts` | Rahasia bersama yang didaftarkan melalui `setWebhook` dan diverifikasi terhadap header `X-Telegram-Bot-Api-Secret-Token` pada setiap pengiriman webhook. Diperlukan untuk jalur webhook; jika tidak diatur, pengiriman webhook ditolak dengan 503. |
| `TELEGRAM_DEFAULT_MODEL` | `auto/chat` | `src/lib/telegram/chatProxy.ts` | Model yang digunakan untuk balasan chat Telegram. |
| `TELEGRAM_BOT_API_BASE` | `https://api.telegram.org` | `src/lib/telegram/config.ts` | Penggantian URL dasar Bot API untuk proksi atau server Bot API yang dihosting sendiri. |
| `TELEGRAM_WEBHOOK_TIMEOUT_MS` | `60000` | `src/lib/telegram/config.ts` | Batas waktu dalam milidetik untuk panggilan Bot API keluar. |
| `OMNIROUTE_OPTIONAL_PACK_TAR` | `1` (diaktifkan) | `scripts/build/optionalPackStaging.mjs` | Atur ke `0` untuk melewati pembuatan tarball `.tar.gz` saat menyiapkan paket ML/browser opsional untuk hierarki mandiri Electron (direktori paket dan `optional-packs.index.json` tetap dibuat). Digunakan oleh alur kerja rilis desktop untuk mengurangi ukuran unggahan artefak. |
### ChatGPT Web (Codex)
Default global untuk browser headless dan tunnel alat keluar. Nilai koneksi yang ditetapkan di dasbor lebih diprioritaskan.
| Variabel | Default | File Sumber | Deskripsi |
| --------------------------------------- | ------------------------------ | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CHATGPT_WEB_CODEX_CHROME_PATH` | _(deteksi otomatis)_ | `open-sse/executors/chatgpt-web-codex.ts` | Jalur Chrome/Chromium eksplisit untuk pengoperasian dengan npm, systemd, dan PM2. |
| `CHROME_PATH` | _(deteksi otomatis)_ | `open-sse/executors/chatgpt-web-codex.ts` | Fallback bersama untuk jalur Chrome/Chromium eksplisit. |
| `CHATGPT_WEB_CODEX_CDP_URL` | _(belum diatur)_ | `open-sse/executors/chatgpt-web-codex.ts` | Endpoint CDP internal; Docker menggunakan sidecar pada port `9223`. |
| `CDP_PROXY_TOKEN` | _(belum diatur)_ | `docker/chatgpt-web-codex-browser/cdp-proxy.mjs` | Jika diatur, setiap permintaan ke sidecar proksi CDP harus menyertakan nilai ini dalam header `X-Omni-Cdp-Token` (#13679). Tanpa nilai tersebut, proksi akan meneruskan permintaan tanpa autentikasi — dalam kondisi ini, perlindungan hanya bergantung pada isolasi jaringan Compose `chatgpt-web-codex-net`. Buat dengan `openssl rand -hex 32`. |
| `CHATGPT_WEB_CODEX_TUNNEL_ID` | _(belum diatur)_ | `open-sse/executors/chatgpt-web-codex.ts` | ID tunnel OpenAI global untuk putaran tool Codex lokal. |
| `CHATGPT_WEB_CODEX_RUNTIME_KEY` | _(belum diatur)_ | `open-sse/executors/chatgpt-web-codex.ts` | Runtime key tunnel global; jangan pernah menampilkannya dalam log. |
| `CHATGPT_WEB_CODEX_CONNECTOR_NAME` | `OmniRoute Codex v2` | `open-sse/executors/chatgpt-web-codex.ts` | Nama persis konektor kustom ChatGPT yang baru dibuat untuk bridge MCP. |
| `CODEX_CHATGPT_WEB_HOME` | `/chatgpt-web-codex` | `open-sse/vendor/codex-chatgpt-web/config.ts` | Direktori khusus untuk status browser, broker, dan tunnel. |
| `CODEX_CHATGPT_WEB_BROWSER_DIAGNOSTICS` | `0` | `open-sse/vendor/codex-chatgpt-web/adapters/chatgpt-web/browser-worker.ts` | Jika bernilai `1`, gambar diagnostik browser diambil pada setiap checkpoint. |
| `CODEX_CHATGPT_WEB_LAUNCHER` | _(belum diatur)_ | `open-sse/vendor/codex-chatgpt-web/config.ts` | Jalur absolut opsional menuju binary launcher persisten. |
| `CODEX_CHATGPT_WEB_BUN` | _(deteksi otomatis)_ | `open-sse/vendor/codex-chatgpt-web/config.ts` | Jalur absolut opsional menuju binary runtime Bun. |
| `CODEX_WEB_GPT_BUN` | _(belum diatur)_ | `open-sse/vendor/codex-chatgpt-web/config.ts` | Fallback lama untuk `CODEX_CHATGPT_WEB_BUN`; penyiapan baru menggunakan nama kanonis. |
---
## Jembatan OmniConductor
Konsumen SSE berumur panjang yang mencerminkan tugas hub OmniConductor ke dalam A2A TaskManager lokal (`src/lib/conductor/`). Bersifat opsional — jembatan hanya dimulai ketika `CONDUCTOR_HUB_URL` ditetapkan. Hanya untuk sisi server: token hub tidak boleh sampai ke browser.
| Variabel | Default | Berkas Sumber | Deskripsi |
| ------------------------------ | ----------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONDUCTOR_HUB_URL` | _(kosong)_ | `src/lib/conductor/boot.ts` | URL dasar hub OmniConductor (misalnya `http://127.0.0.1:7910`). Tidak ditetapkan = jembatan dinonaktifkan. |
| `CONDUCTOR_HUB_TOKEN` | _(kosong)_ | `src/lib/conductor/boot.ts` | Kredensial hub untuk umpan SSE — buat peer berjenis `spokesperson` di hub (`POST /v1/peers`, admin). |
| `CONDUCTOR_ORCHESTRATOR_TOKEN` | _(kosong)_ | `src/lib/conductor/hubProxy.ts` | Kredensial untuk pendelegasian tugas A2A→hub yang masuk (`POST /v1/tasks`); menggunakan `CONDUCTOR_HUB_TOKEN` sebagai cadangan jika tidak ditetapkan. |
| `CONDUCTOR_SPOKESPERSON_URL` | `http://127.0.0.1:7920` | `src/lib/conductor/faroProxy.ts` | URL dasar layanan spokesperson (Faro) di balik proksi obrolan dasbor (`/api/conductor/ask`). |
### Penjadwalan berbasis kuota
Digunakan oleh `open-sse/services/combo.ts` dan `src/lib/quota/quotaScheduler.ts` untuk pemeriksaan anggaran token pra-permintaan. Bersifat opsional — perilaku perutean default tidak berubah jika tidak ditetapkan.
| Variabel | Default | Berkas Sumber | Deskripsi |
| ------------------------------- | ------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OMNIROUTE_QUOTA_AWARE_ROUTING` | `0` | `open-sse/services/combo.ts` | Jika `1`, lewati koneksi yang anggaran token per jendelanya (`rateLimitOverrides.tpm`, tabel `provider_quota_state`) tidak dapat menanggung perkiraan biaya permintaan sebelum pengiriman. Tetap lanjutkan jika tidak ada anggaran yang dikonfigurasi. |