# 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. Secret yang Diperlukan Secret yang tidak diset dan ditandai **Ya** akan dibuat otomatis pada proses pertama (`JWT_SECRET`, `API_KEY_SECRET`) dan disimpan ke `server.env` di direktori data — setel secara eksplisit saat direktori tersebut bersifat ephemeral. Pengecualiannya adalah `OMNIROUTE_WS_BRIDGE_SECRET`: nilainya tidak disimpan ke `server.env` — entrypoint server menghasilkan nilai sementara per boot yang hanya dapat digunakan oleh bridge dalam proses, sehingga klien bridge eksternal perlu menyetelnya secara eksplisit. | Variabel | Wajib | Default | File Sumber | Deskripsi | | ---------------------------- | ----------------- | ------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `JWT_SECRET` | **Ya** | _(tidak ada)_ | `src/lib/auth` | Menandatangani/memverifikasi semua cookie sesi dashboard (JWT). Buat dengan `openssl rand -base64 48`. | | `API_KEY_SECRET` | **Ya** | _(tidak ada)_ | `src/lib/db/apiKeys.ts` | Kunci enkripsi AES untuk nilai API key saat disimpan di SQLite. Buat dengan `openssl rand -hex 32`. | | `INITIAL_PASSWORD` | Tidak | _(tidak diset)_ | `src/lib/auth/managementPassword.ts` | Menetapkan kata sandi dashboard saat startup selama belum ada yang tersimpan; diabaikan setelah kata sandi tersimpan. Instalasi npm dan sumber menyalin `.env.example` ke `.env`, sehingga mereka memulai dengan placeholder yang diketahui publik `CHANGEME`: ganti sebelum boot pertama, atau setel `INITIAL_PASSWORD=` (kosong) di `.env` tersebut untuk membuat kata sandi di wizard onboarding pada kunjungan pertama, seperti halnya nilai yang tidak diset (default image Docker). Ubah kata sandi yang tersimpan di Dashboard → Settings → Security, atau jalankan `omniroute reset-password` (`node bin/reset-password.mjs` di checkout sumber) dengan `DATA_DIR` disetel ke direktori data server. | | `OMNIROUTE_WS_BRIDGE_SECRET` | **Ya** (produksi) | _(tidak diset)_ | `src/app/api/internal/codex-responses-ws/route.ts` | Secret bersama untuk bridge WebSocket Codex Responses internal. Mengautentikasi permintaan bridge antara relay WS Electron/browser dan OmniRoute. ⚠️ **WAJIB di produksi — jika tidak diset, semua permintaan bridge WS ditolak.** Buat dengan `openssl rand -base64 32`. | | `OMNIROUTE_SW_BUILD_ID` | Tidak | _(git SHA)_ | `next.config.mjs`, `scripts/build/assembleStandalone.mjs` | Id cache-busting service worker eksplisit untuk shell PWA (#11779); pertama dalam rantai resolusi. | | `SOURCE_VERSION` | Tidak | _(tidak diset)_ | `next.config.mjs`, `scripts/build/assembleStandalone.mjs` | Kedua dalam rantai — disetel oleh builder PaaS (mis. gaya 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 git SHA. | | `OMNIROUTE_PEER_STAMP_TOKEN` | Tidak (otomatis) | _(otomatis setiap boot)_ | `src/server/authz/policies/management.ts` | Secret per proses yang membuktikan bahwa stamp IP peer tepercaya berasal dari server HTTP OmniRoute sendiri (`scripts/dev/peer-stamp.mjs`). Middleware authz mempercayai lokalitas permintaan (gating loopback/LAN untuk rute LOCAL_ONLY) hanya ketika stamp membawa token ini. Dibuat otomatis setiap boot — biarkan tidak diset; hanya pin jika untuk setup multi-proses yang harus berbagi stamp. | | `OMNIROUTE_TRUSTED_PROXIES` | Tidak | _(tidak diset)_ | `scripts/dev/peer-stamp.mjs` | Daftar IP atau rentang CIDR yang dipisahkan koma dari reverse proxy yang `X-Forwarded-For` / `X-Real-IP`-nya boleh dipercaya oleh daftar allow/deny IP, selain loopback, alamat jaringan privat, dan edge Cloudflare, yang selalu dipercaya. Diperlukan hanya untuk proxy pada alamat publik lain; jika tidak, alamat proxy itu sendiri yang menjadi penilaian filter. Throttle per klien relay (`/api/v1/relay/chat/completions`) menggunakan alamat klien teresolusi yang sama, bukan hanya header forwarding. | ### Perintah Pembuatan ```bash # Hasilkan keempat secret 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` berisi secret asli ke kontrol versi. `.gitignore` sudah mengecualikan `.env`, tetapi verifikasi sebelum melakukan push. --- ## 2. Penyimpanan & Database OmniRoute menggunakan **SQLite** (via `better-sqlite3`) untuk semua persistensi. Variabel-variabel ini mengontrol lokasi data, enkripsi, dan siklus hidup. | Variabel | Default | File Sumber | Deskripsi | | ------------------------------------------ | ----------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `DATA_DIR` | `~/.omniroute/` | `src/lib/db/core.ts` | Direktori root untuk SQLite DB, backup, dan file data. Ganti untuk volume Docker atau path kustom. | | `OMNIROUTE_ALLOW_DEFAULT_DATA_DIR` | _(tidak disetel)_ | `src/lib/dataPaths.ts` | Jalan keluar untuk pelindung DATA_DIR test/eval (#10428). Test dan probe eval/print Node (`-e`/`--eval`/`-p`/`--print`, termasuk bentuk `--eval=`/`--print=`) tanpa `DATA_DIR` dialihkan ke direktori temp sekali pakai sehingga tidak dapat membuka database operator yang sebenarnya; setel ke `1` untuk kembali menggunakan direktori asli. | | `OMNIROUTE_BUILD_SHA` | _(tidak disetel)_ | `src/lib/monitoring/buildSha.ts` | Git SHA dari artefak yang sedang berjalan. Ditetapkan oleh `npm run build:release`; dapat diinjeksikan dalam container 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 provenance pack-artifact untuk memeriksa build SHA (#10427). | | `OMNIROUTE_ALLOW_CANARY_BUILD` | _(tidak disetel)_ | `scripts/build/buildProvenance.ts` | Setel ke `1` untuk mengizinkan pengemasan build yang SHA-nya tidak berada di jalur rilis, mencatatnya sebagai canary yang disengaja alih-alih menggagalkan gerbang (#10427). | | `OMNIROUTE_SMOKE_API_KEY` | _(tidak disetel)_ | `scripts/ops/deploy-canary.mjs` | API key untuk probe smoke canary-deploy, dikirim sebagai `Authorization: Bearer` pada `/v1/chat/completions`. Hanya digunakan oleh skrip deploy (#10429), tidak pernah oleh server. Tidak terkait dengan variabel `OMNIROUTE_SMOKE_*` dari harness smoke CLI opt-in (`RUN_CLI_SMOKE=1`, `OMNIROUTE_SMOKE_BASE_URL/MODEL/API_KEY_ENV/TARGETS/TIMEOUT_MS` di `tests/integration/upstream-cli-smoke.int.test.ts`) — lihat [Integrasi CLI → Penyapuan 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 build worker yang di-spawn sehingga lapisan DB mengembalikan stub no-op alih-alih memuat addon native better-sqlite3 (yang membatalkan 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 prebuild dependensi native opsional untuk tree vendored yang tidak umum. Ini tidak membuat dependensi yang hilang menjadi dapat dibangun; gunakan hanya ketika dependensi native disediakan secara 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 PromptQL executor di disk (`/promptql-thread-sessions.json`); jika kedua variabel tidak disetel, cache hanya tetap berada di memori (tidak dipersistensikan antar restart). | | `OMNIROUTE_PLUGINS_DIR` | _(tidak disetel)_ | `src/lib/plugins/scanner.ts` | Direktori yang dibaca **runtime plugin scanner** — dan root tempat plugin manager menginstal — menggantikan default yang diturunkan dari home (#11827). Arahkan ke plugin tree yang di-bind-mount di Docker/K8s alih-alih memindahkan HOME hanya untuk merelokasi path pemindaian (HOME juga mengatur setiap perilaku relatif-home lainnya). Tidak disetel = `~/.omniroute/plugins`, atau `/tmp/.omniroute/plugins` ketika proses tidak mengekspor home sama sekali — non-discovery senyap yang dihilangkan oleh variabel ini. Direktori yang di-resolve dicatat sekali saat startup sebagai `scanner.dir_resolved` beserta input yang menang. Hanya sisi server: plugin perintah CLI memiliki `OMNIROUTE_PLUGIN_PATH` sendiri (bagian 9). | | `STORAGE_ENCRYPTION_KEY` | _(kosong = dinonaktifkan)_ | `src/lib/db/encryption.ts` | Kunci AES untuk enkripsi penuh database SQLite saat tersimpan (at rest). 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 nilainya saat melakukan rotasi kunci untuk mendukung dekripsi cadangan lama. | | `DISABLE_SQLITE_AUTO_BACKUP` | `false` | `src/lib/db/backup.ts` | Ketika `true`, melewati pencadangan file SQLite rutin/pra-tulis (penyimpanan/penghapusan harga models.dev, penulisan pengaturan). Pencadangan manual dan pra-pemulihan tetap berjalan. Ini **tidak** menonaktifkan snapshot keamanan durabel yang wajib dari migration runner ataupun perlindungan migrasi massal untuk DB persisten yang sudah ada. Pencadangan non-manual dibatasi maksimal sekali per 60 menit. Dasbor **Pengaturan → Penyimpanan** dapat menonaktifkan pencadangan otomatis rutin secara independen. | | `OMNIROUTE_SQLITE_SLOW_MS` | _(tidak diatur/nonaktif)_ | `src/lib/db/adapters/slowDiagnostics.ts` | Milidetik; nilai di bawah 1 atau non-numerik tetap nonaktif; peringatan maksimal sekali per 10 detik; baris log hanya berisi driver, operation, dan elapsedMs. | | `OMNIROUTE_CRYPT_KEY` | _(tidak diatur)_ | `src/lib/db/encryption.ts` | **Alias lawas** untuk `STORAGE_ENCRYPTION_KEY`. Diterima sebagai cadangan ketika variabel utama tidak ada. | | `OMNIROUTE_API_KEY_BASE64` | _(tidak diatur)_ | `src/lib/db/encryption.ts` | **Alias lawas** (bentuk berenkode Base64) yang diterima sebagai cadangan. Didekode secara otomatis sebelum digunakan. | | `OMNIROUTE_DB_HEALTHCHECK_INTERVAL_MS` | _(tidak diatur)_ | `src/lib/db/core.ts` | Menimpa interval healthcheck SQLite berkala (ms). Jika tidak diatur, nilai default diturunkan dari `NODE_ENV`. | | `OMNIROUTE_WAL_TRUNCATE_INTERVAL_MS` | _(dihapus)_ | `src/lib/db/walMaintenance.ts` | **Dihapus.** `wal_checkpoint(TRUNCATE)` live berkala dapat membatalkan pemetaan wal-index bersama dan membuat proses crash dengan SIGBUS (#13973), sehingga penjadwalnya tidak lagi ada. Variabel ini inert: nilai positif mencatat peringatan deprecasi satu kali, sedangkan `0` atau tidak diatur tetap diam. WAL dikelola oleh checkpoint PASSIVE (di bawah) dan dipangkas oleh checkpoint saat shutdown. | | `OMNIROUTE_WAL_PASSIVE_INTERVAL_MS` | `300000` (5m) | `src/lib/db/walMaintenance.ts` | Menimpa interval `wal_checkpoint(PASSIVE)` yang sering dijalankan (ms). Menjaga frame WAL yang tertunda tetap kecil sehingga checkpoint tetap cepat dan file WAL tetap terbatas di antara pemangkasan saat shutdown. `0` menonaktifkan. | | `OMNIROUTE_WAL_GUARD_MAX_MB` | `256` | `src/lib/db/walMaintenance.ts` | Ketika tick PASSIVE menemukan file WAL melebihi ukuran ini, jalankan `wal_checkpoint(RESTART)` sehingga WAL dimulai dari awal tanpa menulis ulang wal-index yang terpetakan. Checkpoint mode truncate secara live telah dihapus (lihat baris `OMNIROUTE_WAL_TRUNCATE_INTERVAL_MS`). | | `OMNIROUTE_PRESSURE_SELF_RESTART` | `false` | `open-sse/utils/resourcePressure.ts` | Atur ke `1`/`true`/`yes`/`on` untuk mengakhiri proses setelah tekanan sumber daya kritis bertahan selama `OMNIROUTE_PRESSURE_SELF_RESTART_AFTER_MS`, membiarkan supervisor (systemd `Restart=always`, kebijakan restart Docker) menghidupkan kembali proses yang bersih alih-alih terus melayani 503 tanpa batas. | | `OMNIROUTE_PRESSURE_SELF_RESTART_AFTER_MS` | `120000` (2m) | `open-sse/utils/resourcePressure.ts` | Berapa lama tekanan kritis harus bertahan sebelum pengakhiran untuk self-restart dipicu. | | `OMNIROUTE_PRESSURE_PSI_DISABLED` | `false` | `open-sse/utils/resourcePressurePolicy.ts` | Atur ke `1`/`true`/`yes`/`on` untuk mengabaikan `/proc/pressure/memory` tingkat host (`psi_some` / `psi_full`) ketika noisy neighbor memicu 503 sementara proses ini baik-baik saja (#13124). Perlindungan heap Cgroup dan V8 tetap aktif. PSI juga berhenti dihitung sebagai bukti throttle kernel untuk `cgroup_high`: total cgroup di atas `memory.high` kemudian berubah menjadi kritis hanya saat terjadi kenaikan `high`/`max` pada `memory.events`. Tanpa `memory.events`, rasio mentah tetap dipertahankan. | | `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 adapter fallback WASM `sql.js`. Terdeteksi otomatis melalui dependensi paket dan tata letak kandidat jika tidak diatur. | | `OMNIROUTE_BATCH_RETENTION_DAYS` | `30` | `src/lib/db/cleanup.ts` | Jumlah hari checkpoint job Batch API berstatus terminal (completed/failed/cancelled/expired), file input/output/error yang direferensikan, dan barisnya disimpan oleh proses pembersihan otomatis sebelum dihapus. Hanya berlaku setelah `BATCH_AND_FILE_AUTO_CLEANUP_ENABLED` diaktifkan; sesuai dengan jendela retensi output Batch API milik OpenAI sendiri. Tidak memengaruhi rute `DELETE /api/v1/batches/delete-completed` yang dipicu operator, yang memang secara desain tetap tanpa syarat (tanpa filter usia). | | `BATCH_AND_FILE_AUTO_CLEANUP_ENABLED` | `false` | `src/lib/db/cleanup.ts` | Jika `true`, proses pembersihan otomatis akan menghapus job Batch API berstatus terminal (beserta checkpoint-nya) yang telah melewati `OMNIROUTE_BATCH_RETENTION_DAYS`, dan mengosongkan konten BLOB dari file yang diunggah yang telah melewati `expires_at`-nya sendiri. Nonaktif secara default: setiap instalasi yang ada menyimpan data ini persis seperti sebelumnya sampai seorang operator memilih untuk ikut serta. Juga merupakan feature flag yang dapat diedit melalui dashboard — 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 melewati healthcheck DB sepenuhnya 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 healthcheck DB aktif, bahkan ketika biasanya akan dilewati (misalnya, tugas berumur pendek). | | `OMNIROUTE_SKIP_POSTINSTALL` | `0` | `scripts/postinstall.mjs` | Atur ke `1` untuk melewati warm-up runtime native selama `npm install`. Berguna pada instalasi CI/headless di mana sqlite sudah ter-build. | | `OMNIROUTE_MIGRATIONS_DIR` | _(deteksi otomatis)_ | `src/lib/db/migrationRunner.ts` | Menimpa direktori yang dipindai oleh migration runner. Berguna saat menyertakan migrasi yang dibundel dalam build kustom. | | `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 (mis. `ee=/opt/app/enterprise/db/migrations`). File yang ditemukan di sana dicatat sebagai `-`, sehingga distribusi yang menyertakan migrasinya sendiri tidak akan pernah bertabrakan dengan slot numerik upstream. Entri yang salah format, namespace yang tidak valid, atau direktori yang hilang akan memunculkan error saat startup alih-alih diam-diam melewati skema. | | `OMNIROUTE_MAX_PENDING_MIGRATIONS` | `50` | `src/lib/db/migrationRunner.ts` | Ambang batas keamanan untuk migrasi tertunda dalam jumlah besar (#3416). Startup dibatalkan jika ada lebih dari jumlah migrasi ini yang tertunda pada DB yang sudah ada (melindungi dari tabel pelacakan yang terhapus). Naikkan nilainya untuk memulihkan backup yang lebih lama; atur ke `0` untuk menonaktifkan pemeriksaan. | | `OMNIROUTE_INSTALL_UPGRADE_WORKDIR` | _(`/.install-upgrade`)_ | `scripts/check/check-install-upgrade.mjs` | Direktori kerja untuk release gate `check:install-upgrade`. Direktori ini membutuhkan sekitar 12 GB (dua pohon instalasi ~3 GB ditambah tarball), sehingga tidak boleh dijalankan pada tmpfs kecil — pada self-hosted runner, `/tmp` adalah tmpfs berbasis RAM 12 GB dan gate tersebut menghabiskannya, sehingga paket menjadi terpotong. | | `OMNIROUTE_SPEND_FLUSH_INTERVAL_MS` | _(default di kode)_ | `src/lib/spend/batchWriter.ts` | Interval flush (ms) untuk writer spend/cost yang dibatch. Nilai lebih rendah mengurangi penggabungan penulisan; nilai lebih tinggi mengurangi kontensi DB. | | `OMNIROUTE_SPEND_MAX_BUFFER_SIZE` | _(default di kode)_ | `src/lib/spend/batchWriter.ts` | Maksimum entri spend yang di-buffer sebelum flush paksa. Naikkan pada deployment dengan QPS tinggi; turunkan ketika memori yang terbatas lebih diutamakan. | | `OMNIROUTE_PROXY_FETCH_DEBUG` | _(tidak diatur)_ | `open-sse/utils/proxyFetch.ts` | Atur ke `"true"` untuk memancarkan log debug `[ProxyFetch]` pada jalur relay Vercel. Nonaktif secara default untuk menghindari kebocoran petunjuk routing. | | `OMNIROUTE_PROXY_CORE_BINARY_PATH` | _(tidak diatur)_ | `src/lib/proxySubscription/coreConfig/sync.ts` | Path absolut dari binary proxy core lokal (sebuah file bernama `sing-box`) yang memeriksa konfigurasi core yang dihasilkan sebelum menggantikan file yang diadopsi. Jika tidak diatur, hanya menulis `.generated` di samping file yang diadopsi. Khusus lingkungan host: tidak pernah disimpan di database maupun diterima melalui API manajemen, karena binary tersebut dieksekusi. | | `OMNIROUTE_PROXY_CORE_RELOAD_COMMAND` | _(tidak diatur)_ | `src/lib/proxySubscription/coreConfig/reload.ts` | Cara proxy core lokal melakukan reload setelah penggantian konfigurasi yang terverifikasi: array argumen JSON yang dijalankan tanpa shell, atau tepat `external` ketika pengamat eksternal yang menerapkan file tersebut. Tidak pernah disimpan di database maupun diekspos melalui API. | | `PROXY_LOG_INCLUDE_IPS` | `false` | `src/lib/proxyLogger.ts` | Atur ke `"true"` atau `"1"` untuk menyertakan IP klien/egress dan prefiks akun pada baris log proses verbose `[ProxyEgress]`. 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` | Jalur eksplisit yang diperiksa oleh health check kontainer. Jika tidak diatur, pemeriksaan menurunkannya dari `OMNIROUTE_BASE_PATH`; mengaturnya akan kembali menggunakan endpoint pemantauan mendalam. | | `OMNIROUTE_DEBUG_COMPLETION` | _(tidak diatur)_ | `bin/cli/commands/completion.mjs` | Atur ke nilai apa pun yang tidak kosong untuk memancarkan diagnostik `[omniroute completion]` dari jalur cache pelengkapan shell CLI (baca/segarkan/tulis). Nonaktif secara default — cache tersebut gagal secara diam-diam sehingga cache yang hilang/rusak tidak pernah merusak pelengkapan tab. | | `BATCH_RETRY_DURATION_MS` | `86400000` (24h) | `open-sse/services/batchProcessor.ts` | Jendela percobaan ulang maksimum untuk item batch individual (ms). Item yang melebihi durasi ini ditandai 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` (1h) | `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 untuk menghindari badai rate-limit. | > [!IMPORTANT] > Sebelum mengubah database persisten yang ada, runner migrasi mempublikasikan snapshot > lengkap yang dialamatkan berdasarkan konten (content-addressed) di bawah `DATA_DIR/db_backups/`. > Publikasi memerlukan sistem file yang mendukung hard link satu-sistem-file tanpa menimpa > plus sinkronisasi file yang tahan lama. Host POSIX juga memerlukan sinkronisasi direktori; > di Windows, Node dapat menolak handle direktori, sehingga OmniRoute mengosongkan (flush) > file yang dipublikasikan dan memperlakukan sinkronisasi entri direktori sebagai best effort. > Jika `DATA_DIR` yang ter-mount tidak dapat memberikan jaminan tersebut, startup gagal > dalam keadaan tertutup (fail-closed) sebelum menerapkan migrasi. Pindahkan `DATA_DIR` > ke volume dengan primitif tersebut; jangan gunakan > `DISABLE_SQLITE_AUTO_BACKUP` untuk melewati perlindungan migrasi. ### Skenario | Skenario | Konfigurasi | | ----------------------------- | --------------------------------------------------------------------------------------------- | | **Pengembangan lokal** | Biarkan semua default. DB berada di `~/.omniroute/omniroute.db`. | | **Docker** | `DATA_DIR=/data` + mount volume di `/data`. | | **Terenkripsi saat disimpan** | Atur `STORAGE_ENCRYPTION_KEY` + simpan cadangan kuncinya! Kehilangan kunci = kehilangan data. | | **CI/Testing** | `DATA_DIR=/tmp/omniroute-test` — bersifat sementara, tidak perlu enkripsi. | --- ## 3. Jaringan & Port | Variabel | Default | File Sumber | Deskripsi | | ------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `PORT` | `20128` | `src/lib/runtime/ports.ts` | Port utama untuk UI Dashboard dan endpoint API (mode port tunggal). | | `OMNIROUTE_BASE_PATH` | _(kosong = root)_ | `next.config.mjs`, `scripts/docker/ensure-docker-base-path.mjs` | Subpath URL untuk menyajikan OmniRoute di balik reverse proxy (mengatur `basePath` Next.js; pengalihan auth memperhatikan basePath). Misalnya `/omniroute`. Di Docker, nilai ini tertanam saat `docker build` (`ARG OMNIROUTE_BASE_PATH`); image root pre-built dapat menerapkan nilai runtime berbeda satu kali saat kontainer dimulai sebelum Next.js berjalan. Atur `NEXT_PUBLIC_BASE_URL` ke origin publik termasuk subpath yang sama. | | `NEXT_PUBLIC_OMNIROUTE_BASE_PATH` | _(kosong = root)_ | `src/shared/hooks/useDisplayBaseUrl.ts` | Cerminan `OMNIROUTE_BASE_PATH` yang terlihat di browser, disisipkan saat build sehingga tampilan endpoint dashboard menampilkan `https://host/omniroute/v1` alih-alih `https://host/v1`. Kembali ke `OMNIROUTE_BASE_PATH` jika tidak diatur. Lakukan build ulang setelah mengubahnya (`basePath` Next bersifat build-time). | | `DASHBOARD_ALLOW_EMBED` | _(tidak diatur = tidak pernah dapat di-frame)_ | `next.config.mjs`, `scripts/build/dashboardEmbed.mjs` | Penyematan iframe opt-in untuk halaman HTML. Jika tidak diatur, setiap route mengirimkan `frame-ancestors 'none'` + `X-Frame-Options: DENY`. Atur ke `vscode` untuk menyajikan halaman (dashboard, login, docs, landing) 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 mempertahankan header ketat dalam kedua kasus. Hanya `vscode` yang dikenali — `1`/`true` tidak mengaktifkannya. Build-time: lakukan build ulang setelah mengubahnya (`docker build --build-arg DASHBOARD_ALLOW_EMBED=vscode` untuk image; mengaturnya pada instalasi prebuilt 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 Dashboard pada port terpisah ini. | | `OMNI_MAX_CONCURRENT_CONNECTIONS` | `0` _(dinonaktifkan)_ | `src/sse/utils/backpressure.ts` | Membatasi koneksi chat bersamaan yang sedang berjalan; permintaan yang melebihi batas menerima `503` dengan `Retry-After`. Bilangan bulat positif mengaktifkan perlindungan; tidak diatur/`0` menonaktifkannya. | | `OMNIROUTE_INSTANCE_ID` | _(tidak diatur)_ | `src/shared/resilience/peerRouting.ts` | ID yang stabil dan unik untuk gateway ini saat merangkai instance OmniRoute. Mengaktifkan pemeriksaan peer-loop masuk. Karakter yang diizinkan: huruf, angka, `.`, `_`, `:`, dan `-`; maksimum 64 karakter. | | `OMNIROUTE_PEER_URLS` | _(belum diatur)_ | `src/shared/resilience/peerRouting.ts`, `open-sse/executors/base.ts` | URL dasar OmniRoute yang dipisahkan koma yang boleh menerima `X-OmniRoute-Peer-Trace`. Hanya URL upstream yang secara eksplisit masuk daftar izin yang menerima metadata peer; semua provider lain tidak tersentuh. | | `OMNIROUTE_PEER_MAX_HOPS` | `4` | `src/shared/resilience/peerRouting.ts` | Jumlah maksimum instance OmniRoute yang telah dikunjungi sebelumnya yang diterima pada request berantai (`1`-`32`). Instance yang berulang atau budget yang habis akan mengembalikan HTTP `508 Loop Detected`. | | `PROD_DASHBOARD_PORT` | `20130` | `docker-compose.prod.yml` | Port yang dipublikasikan di sisi host untuk Dashboard dalam mode produksi Docker. | | `PROD_API_PORT` | `20131` | `docker-compose.prod.yml` | Port yang dipublikasikan di sisi host untuk API dalam mode produksi Docker. | | `OMNIROUTE_PORT` | _(belum diatur)_ | `src/lib/runtime/ports.ts` | Diprioritaskan di atas `PORT` saat berjalan di dalam Electron atau wrapper lainnya. | | `LIVE_WS_PORT` | `20129` | `src/server/ws/liveServer.ts` | Port untuk server monitoring live WebSocket real-time. | | `LIVE_WS_HOST` | `127.0.0.1` | `src/server/ws/liveServer.ts` | Alamat bind untuk server WebSocket live. Atur ke `0.0.0.0` untuk mengekspos di LAN (konfigurasikan juga `LIVE_WS_ALLOWED_ORIGINS`). Koneksi diautentikasi dengan cookie sesi dashboard atau API key Bearer yang memiliki scope manajemen (`manage`/`admin`). | | `LIVE_WS_ALLOWED_ORIGINS` | _(belum diatur)_ | `src/server/ws/liveServer.ts` | Origin tambahan yang dipisahkan koma yang diizinkan membuka WebSocket live. Origin dashboard loopback sudah diizinkan secara default. | | `LIVE_WS_ALLOWED_HOSTS` | _(belum diatur)_ | `src/server/ws/liveServerAllowList.ts` | Hostname tambahan yang dipisahkan koma yang diizinkan untuk origin WebSocket live. Berbeda dengan `LIVE_WS_ALLOWED_ORIGINS` (URL origin lengkap), hanya mencocokkan bagian host — berguna untuk pengaturan LAN/Tailscale. | | `NEXT_PUBLIC_LIVE_WS_PUBLIC_URL` | _(belum diatur)_ | `src/hooks/useLiveDashboard.ts` | URL publik untuk WebSocket dashboard live (sisi browser). Atur saat menempatkan server WS di belakang reverse proxy atau Cloudflare Tunnel (mis. `wss://ws.my-ai.com/live-ws`); browser akan terhubung ke sana alih-alih `ws://hostname:20132`. Bagian pathname juga digunakan sebagai path upgrade 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 real-time (aktif secara default, terikat loopback). Saklar CI/harness yang menonaktifkan skrip helper WebSocket live mandiri. | | `RELAY_IP_PER_MINUTE` | `30` | `src/app/api/v1/relay/chat/completions/route.ts` | Batas laju relay per-(token, IP), request/menit. In-memory, per instance. `0` atau nilai negatif menonaktifkan gerbang dimensi IP (batas DB per-token tetap berlaku). | | `NODE_ENV` | `production` | Next.js core | Mengontrol verbositas logging, caching, paparan detail error, dan optimasi 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). Setel ke `0` untuk kembali ke webpack di Windows, saat mengalami inkompatibilitas native binding / bundler-compat, **atau pada mesin dengan RAM terbatas** — build produksi Turbopack pada lini versi Next.js ini (16.2.x) diketahui di upstream mencapai puncak penggunaan memori yang jauh lebih tinggi daripada webpack pada grafik modul yang besar (perbaikan memory-eviction Turbopack di Next 16.3 belum stabil); fallback webpack memiliki puncak yang jauh lebih rendah. Lihat #6409. **Build image Docker secara default menggunakan `0` (webpack)**: `Dockerfile` mendeklarasikan `ARG OMNIROUTE_USE_TURBOPACK=0` sehingga `docker build .` biasa (Railway dan host one-click lainnya, self-hoster ad-hoc) tidak mengalami OOM-kill pada builder dengan batas memori; berikan `--build-arg OMNIROUTE_USE_TURBOPACK=1` untuk mem-build image dengan Turbopack. Lihat `docs/guides/DOCKER_GUIDE.md` → Sumber daya waktu build. | | `OMNIROUTE_SKIP_DB_HEALTHCHECK` | _(belum disetel)_ | `src/lib/db/core.ts` / `src/lib/db/healthCheck.ts` | Setel ke `1` untuk melewati pemeriksaan kesehatan integritas SQLite saat startup. Berguna untuk boot yang lebih cepat pada database besar. | | `NOTIFY_SOCKET` | _(belum disetel)_ | systemd (protokol sd_notify) | Disetel 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. Tidak pernah disetel oleh pengguna. | | `OMNIROUTE_DISABLE_SD_NOTIFY` | _(belum disetel)_ | `scripts/dev/systemd-notify.mjs` | Setel ke `1` untuk menonaktifkan systemd sd_notify (Type=notify / WatchdogSec=) bahkan saat berjalan di bawah unit systemd. Notifier tetap no-op di luar systemd. | | `CREDENTIAL_HEALTH_CHECK_INTERVAL` | `3600000` | `open-sse/config/constants.ts` / `src/lib/credentialHealth/scheduler.ts` | Interval (ms) untuk penjadwal pemeriksaan kesehatan kredensial latar belakang. Minimum: 10000 (10s). | | `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` | Setel ke `1` atau `true` untuk menonaktifkan pengujian berkala latar belakang terhadap koneksi provider. Provider pencarian (SEARCH_VALIDATOR_CONFIGS di `src/lib/providers/validation/searchProviders.ts`, mis. `tavily-search`) selalu dikecualikan dari sweep — "validasi" mereka adalah kueri upstream berbayar yang sesungguhnya, sehingga mereka tidak pernah diperiksa kesehatannya dengan timer (#9970). | | `DEEP_HEALTH_CHECK_ENABLED` | `0` | `src/app/api/monitoring/health/route.ts` | Setel ke `1` untuk mengizinkan pemanggil terautentikasi meminta `/api/monitoring/health?deep=1`, yang mengambil sampel permukaan completions satu kali per TTL. Pemanggil anonim tidak pernah memicu probe. | | `OMNIROUTE_EVENT_LOOP_STALL_THRESHOLD_MS` | `5000` | `src/lib/healthzLag.ts` | Ambang stall (ms) untuk perekam event-loop saat boot: freeze yang lebih lama dari nilai ini mencatat satu baris `event loop stalled` saat melanjutkan, beserta jumlah memori dan in-flight, dan menaikkan penghitung/maksimum `eventLoopStall` di `/api/monitoring/health`. Setel ke `0` untuk menonaktifkan; nilai yang tidak dapat dibaca atau negatif akan kembali ke `5000`. | | `HOST` | `0.0.0.0` | `scripts/dev/run-next.mjs` | Alamat bind untuk server dev/start Next.js. Menimpa default `0.0.0.0` ketika disetel. | | `HOSTNAME` | `127.0.0.1` | `scripts/dev/run-next-playwright.mjs` | Alamat bind yang digunakan oleh runner Playwright saat meluncurkan Next.js. Secara bawaan `127.0.0.1` untuk pengujian hermetis. **Jangan gunakan untuk `omniroute serve`** — gunakan `OMNIROUTE_SERVER_HOST` sebagai gantinya (shell POSIX secara otomatis mengatur `HOSTNAME` ke nama mesin; `.env` tidak dapat menimpanya). | | `OMNIROUTE_SERVER_HOST` | `0.0.0.0` | `bin/cli/commands/serve.mjs` | Alamat bind untuk `omniroute serve`. Menghindari konflik dengan variabel `HOSTNAME` milik shell POSIX (selalu diatur ke nama mesin oleh bash/zsh). Kembali ke `0.0.0.0` jika tidak diatur. (#6194) | ### Mode Port ``` ┌─────────────────────────── Single Port (default) ──────────────────────────┐ │ PORT=20128 │ │ → Dashboard: http://localhost:20128 │ │ → API: http://localhost:20128/v1/chat/completions │ └─────────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────── Split Ports ─────────────────────────────────────┐ │ DASHBOARD_PORT=20128 │ │ API_PORT=20129 │ │ API_HOST=0.0.0.0 │ │ → Dashboard: http://localhost:20128 │ │ → API: http://0.0.0.0:20129/v1/chat/completions │ │ Use case: Expose API to LAN while restricting Dashboard to localhost. │ └─────────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────── Docker Production ──────────────────────────────┐ │ PROD_DASHBOARD_PORT=443 PROD_API_PORT=8443 │ │ → Maps container ports to host ports in docker-compose.prod.yml. │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## 4. Keamanan & Autentikasi | Variabel | Default | Berkas Sumber | Deskripsi | | ------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `MACHINE_ID_SALT` | `endpoint-proxy-salt` | `src/lib/auth` | Salt yang dikombinasikan dengan pengenal perangkat keras untuk sidik jari mesin. Ubah per-deployment untuk isolasi. | | `OMNIROUTE_CLI_SALT` | _(tidak diatur = salt acak per-instalasi yang disimpan di `/cli-token-salt.json`)_ | `src/lib/machineToken.ts` | Salt HMAC untuk memperoleh token autentikasi CLI lokal. Mengatur nilai ini akan merotasi semua token CLI pada mesin dan selalu diprioritaskan di atas salt yang tersimpan. Lihat `docs/security/CLI_TOKEN.md`. | | `AUTH_COOKIE_SECURE` | `false` | `src/lib/auth` | Mengatur flag `Secure` pada cookie sesi. **Harus bernilai `true`** saat berjalan di balik HTTPS. | | `REQUIRE_API_KEY` | `false` | Middleware API | Ketika `true`, semua permintaan proxy `/v1/*` harus menyertakan API key yang valid. **Flag ini tidak membatasi `GET /v1/models`**, yang justru mengikuti postur login dashboard (`requireAuthForModels`) — jadi respons `401` dari `/v1/models` TIDAK berarti inferensi terlindungi. Lihat `docs/security/INFERENCE_AUTH_POSTURE.md` (#13695). | | `ALLOW_API_KEY_REVEAL` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Mengizinkan pengungkapan nilai API key lengkap di UI Dashboard. Dapat dikonfigurasi dari Feature Flags Dashboard; berisiko keamanan pada instance bersama. | | `NO_LOG_API_KEY_IDS` | _(kosong)_ | `src/lib/compliance/index.ts` | ID API key yang dipisahkan koma yang melewati pencatatan permintaan (kepatuhan GDPR). | | `DEFAULT_RATE_LIMIT_PER_DAY` | _(tidak diatur = tanpa batas)_ | `src/shared/utils/apiKeyPolicy.ts` | Anggaran permintaan per-hari cadangan yang diterapkan pada API key yang kolom `rate_limits`-nya null. Tidak diatur atau kosong: tidak ada batas implisit (#2289, #11017). `0` sama saja (tanpa batas). Bilangan bulat positif N mengaktifkan N/hari, 5N/minggu, 20N/bulan. Nilai tidak valid yang tidak kosong akan kembali ke jendela lama 1000/hari, 5000/minggu, 20000/bulan. | | `MAX_BODY_SIZE_BYTES` | `10485760` (10 MB) | `src/shared/middleware/bodySizeGuard.ts` | Ukuran body permintaan maksimum 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 berada pada atau di atas ambang ini akan mengambil lease admisi heavyweight atomik lokal-proses sebelum parsing JSON (jalur BYTE, termasuk `POST /v1/responses`). Mekanisme pelolosan headroom sehat [#10437](https://github.com/diegosouzapw/OmniRoute/pull/10437) yang sama seperti pada structure-heavy; tetap dibatasi oleh `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` / [#10110](https://github.com/diegosouzapw/OmniRoute/issues/10110) sehingga [#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 keras rute chat yang diberlakukan terhadap byte yang dibaca selama ingesti terbatas, termasuk permintaan dengan `Content-Length` yang hilang, tidak valid, atau tidak jujur; kelebihan menerima `413`. | | `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` | _(tidak diatur — tanpa batas jumlah permintaan)_ | `src/shared/middleware/chatBodyAdmission.ts` | **#503-fanout:** batas JUMLAH permintaan lawas ini kini hanya berlaku ketika diatur secara eksplisit. Jika dibiarkan tidak diatur (bawaan), admisi chat kelas berat justru dikendalikan oleh `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` — anggaran BYTE yang diturunkan secara otomatis, diukur dari batas memori riil proses dalam **satu proses** (satu heap V8). Dua `/v1/responses` ~750 ribu token yang tumpang tindih menggagalkan heap ~12 Gi (#7849) — ini peringatan **anggaran memori**, bukan batas maksimum produk keras sebesar 2. Proses yang sehat (heap di bawah rasio shed) DAPAT menerima lebih banyak `/v1/responses` panjang secara bersamaan melalui `OMNIROUTE_CHAT_ADMISSION_HEALTHY_HEADROOM`. Puluhan klien SSE panjang (40–50) adalah heap + `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` / #10110, bukan "maks 2". Menaikkan nilai ini secara membabi buta untuk "memakai host" akan mengembalikan #7849. Gandakan **heap** dengan **N `DATA_DIR` yang independen** (#11024); jangan pernah `replicas>1` pada satu berkas SQLite. | | `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` | _(diturunkan otomatis)_ | `src/shared/middleware/admissionBudget.ts` | **#503-fanout:** penggantian (override) untuk anggaran byte ingesti yang diturunkan otomatis (25% dari batas memori V8/cgroup yang lebih ketat dibagi amplifikasi transien 8x). Nilai turunan maupun eksplisit dikunci (clamp) ke rentang 8 MiB–2 GiB. Body yang lebih besar dari anggaran efektif langsung gagal dengan `413 body_exceeds_budget`; pertikaian antar body yang masing-masing masih dapat dilayani tetap berupa `503` yang dapat dicoba ulang. 40–50 klien SSE panjang bersamaan adalah anggaran ini + heap, bukan "maks 2" yang keras. 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 shed tekanan heap (`heapUsed / heap_size_limit`) untuk admisi kelas berat BYTE dan STRUCTURE (#10183, #10268, #10437). Permintaan kelas berat bersamaan yang melampaui `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` hanya di-shed dengan `503` yang dapat dicoba ulang ketika heap JUGA berada pada atau di atas rasio ini; pada heap yang sehat, permintaan justru diterima melalui healthy-headroom. | | `OMNIROUTE_CHAT_ADMISSION_HEALTHY_HEADROOM` | `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` (bawaan `1`) | `src/shared/middleware/chatBodyAdmission.ts` | Kapasitas tambahan terbatas untuk jalur cepat heap-sehat (#10437) pada **keduanya**, STRUCTURE dan BYTE (`admitChatRequest`, termasuk body ≥ `OMNIROUTE_CHAT_LARGE_BODY_BYTES`). Tanpa batas ini, setiap permintaan yang sibuk-namun-heap-sehat melewati admisi tanpa plafon. Setelah sekian banyak lease bersamaan aktif melalui jalur heap-sehat, permintaan sibuk berikutnya jatuh ke jalur bounded-wait/shed yang SAMA dengan yang digunakan saat tekanan heap nyata. `0` menonaktifkan bypass sepenuhnya. | | `OMNIROUTE_CHAT_HEAVY_MESSAGE_COUNT` | `200` | `src/shared/middleware/chatBodyAdmission.ts` | Jumlah pesan yang mengklasifikasikan permintaan chat sebagai kelas berat bahkan ketika body-nya berada di bawah ambang byte. | | `OMNIROUTE_CHAT_HEAVY_TOOL_COUNT` | `64` | `src/shared/middleware/chatBodyAdmission.ts` | Jumlah tool yang mengklasifikasikan permintaan chat sebagai kelas berat bahkan ketika body-nya berada di bawah ambang byte. | | `OMNIROUTE_CHAT_HEAVY_ESTIMATED_TOKENS` | `32000` | `src/shared/middleware/chatBodyAdmission.ts` | Estimasi token berdasarkan ukuran string yang konservatif untuk mengklasifikasikan permintaan sebagai kelas berat; ini adalah proksi biaya admisi, bukan tokenisasi penagihan penyedia. | | `OMNIROUTE_CHAT_HARD_MAX_MESSAGES` | `0` (dinonaktifkan) | `src/shared/middleware/chatBodyAdmission.ts` | Batas riwayat chat opsional yang bersifat opt-in. Dinonaktifkan secara bawaan: jumlah pesan adalah kebijakan deployment, bukan properti universal suatu permintaan, dan pembatasan di sini menolak percakapan dengan `413` terminal sebelum pipeline kompresi sempat membuatnya dapat dilayani. Pertumbuhan heap dibatasi oleh `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` dan shed tekanan heap. Atur nilai positif pada deployment dengan memori terbatas yang memerlukan plafon keras; kelebihan kemudian menerima `413` compact-required terstruktur. | | `OMNIROUTE_MAX_NONSTREAMING_RESPONSE_BYTES` | `67108864` (64 MB) | `open-sse/handlers/chatCore/nonStreamingResponseBody.ts` | Batas keras untuk respons upstream non-streaming yang di-buffer sepenuhnya ke memori. Melewati batas ini, pembaca upstream dibatalkan dan permintaan gagal dengan cepat, alih-alih menumbuhkan string tanpa batas hingga heap habis. | | `OMNIROUTE_FORWARDING_HEADER_BUDGET_BYTES` | `768` | `open-sse/handlers/chatCore/responseHeaders.ts` | Byte maksimum pada wire yang diteruskan dari header respons upstream. Saat anggaran terlampaui, header prioritas rendah (mis., `x-codex-*` kustom, `x-oai-request-id`) dibuang agar tetap dalam batas header reverse-proxy yang umum. Atur lebih tinggi untuk meneruskan lebih banyak metadata upstream dengan konsekuensi ukuran header respons yang lebih besar. | | `CORS_ORIGIN` | _(belum diatur)_ | `src/server/cors/origins.ts` | Daftar izin CORS origin tunggal lawas. Utamakan `CORS_ALLOWED_ORIGINS` untuk deployment baru. CORS hanya untuk klien API browser lintas-origin; penulisan dashboard terautentikasi menggunakan permintaan same-origin ditambah perlindungan CSRF terikat sesi. | | `CORS_ALLOWED_ORIGINS` | _(belum diatur)_ | `src/server/cors/origins.ts` | Daftar izin CORS yang dipisahkan koma. Tidak ada wildcard yang dikirim kecuali `CORS_ALLOW_ALL=true` dikonfigurasi secara eksplisit. | | `CORS_ALLOW_ALL` | `false` | `src/server/cors/origins.ts` | Jalan darurat khusus pengembangan untuk meng-echo `Origin` browser apa pun. Jangan aktifkan pada deployment bersama atau produksi. | | `OUTBOUND_SSRF_GUARD_ENABLED` | `true` | `src/shared/network/outboundUrlGuardPolicy.ts` | Alias lawas. Toggle dashboard-nya (override DB) dibaca sebelum nilai environment ini; `false`, `0`, `no`, atau `off` di salah satunya mematikan pemeriksaan host sebagaimana `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS=true`, bahkan ketika toggle dashboard flag tersebut tersimpan mati; nilai lain menyerahkan penjagaan ke dua flag di bawah. | | `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS` | `false` | `src/shared/network/outboundUrlGuardPolicy.ts` | Mematikan pemeriksaan host penjaga URL outbound, termasuk blokir cloud-metadata (seluruh 169.254.0.0/16, metadata.google.internal), pada jalur provider yang mengikuti mode penjaga: validasi URL, penemuan model, base URL node provider (termasuk node rerank jarak jauh), dan pengujian fallback proxy, di antara jalur outbound terkait provider lainnya seperti pengambilan gambar/media jarak jauh. Juga mengizinkan target webhook privat, kecuali endpoint cloud-metadata/link-local, yang tetap diblokir meskipun flag ini aktif. Permintaan chat yang dikirim melalui `BaseExecutor.execute()` tetap menjalankan pemeriksaan cloud-metadata-nya. Provider lokal berfungsi dengan pengaturan default: `OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` (default `true`) sudah mengizinkan URL lokal dan LAN pada jalur validasi, penemuan, dan node provider; pengujian fallback proxy dan target webhook privat hanya memeriksa flag ini dan memblokir host lokal/LAN selama flag ini mati. Menimpa `OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS=false`. Nilai yang disimpan dari toggle dashboard didahulukan atas variabel ini. | | `OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` | `true` | `src/shared/network/outboundUrlGuardPolicy.ts` | Mengizinkan URL provider pada alamat lokal/privat (127.0.0.1, localhost, LAN, rentang privat) untuk validasi provider, penemuan model, chat, dan jalur outbound terkait provider lainnya yang diatur mode penjaga. **Default `true`** (mengutamakan lokal): penjaga kemudian memblokir endpoint cloud-metadata — seluruh 169.254.0.0/16 ditambah hostname metadata yang dikenal (metadata.google.internal, metadata.goog, IMDS Alibaba/Azure/Oracle, fd00:ec2::254). Atur `false` untuk mode khusus publik, yang juga memblokir host privat dan loopback. Penjaga memeriksa hostname atau literal IP sebagaimana tertulis, sebelum pencarian DNS apa pun; dalam mode khusus publik, pembungkus safe-fetch juga me-resolve hostname dan menolak jawaban privat apa pun. `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS=true` mematikan pemeriksaan ini pada jalur yang tercantum di barisnya. Provider lokal bawaan, seperti LM Studio, Ollama, vLLM, Llamafile, dan Triton, melewati semua pemeriksaan host untuk validasi kunci dan chat. Nilai yang disimpan dari toggle dashboard didahulukan atas variabel ini. (#5066) | | `AUDIO_REMOTE_PROVIDER_NODES` | `false` | `src/app/api/v1/_shared/audioProviderNodes.ts` | Mengizinkan rute `/v1/audio/*` (transkripsi, ucapan, terjemahan) menggunakan node provider kompatibel OpenAI yang dihosting di luar localhost. Mati 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` | Mengizinkan `POST /v1/rerank` (dan langkah rerank loopback mesin memori) menggunakan node provider kompatibel OpenAI yang dihosting di luar localhost — mesin LAN atau peer Tailscale yang menjalankan TEI, Infinity, vLLM, dll. Mati 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. Base URL node jarak jauh juga harus lulus kebijakan URL outbound provider (`OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` / `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS`). | | `OMNIROUTE_LOCAL_PROVIDER_NODE_HOSTS` | _(kosong)_ | `src/shared/network/localNodeHosts.ts` | Hostname (dipisahkan koma atau spasi) yang diperlakukan routing provider-node sebagai lokal — biasanya nama layanan Docker/Compose dari reranker, TEI, atau sidecar audio pada jaringan Docker milik OmniRoute sendiri (`http://reranker:8080/v1`), sehingga node tidak memerlukan IP container yang di-hardcode. Host yang tercantum memenuhi syarat untuk `/v1/rerank`, `/v1/audio/*` dan health check lokal tanpa mengaktifkan `RERANK_REMOTE_PROVIDER_NODES` / `AUDIO_REMOTE_PROVIDER_NODES` untuk setiap node remote, dan dipanggil secara langsung — tidak pernah melalui `HTTP(S)_PROXY` atau proxy pinned milik koneksi. Host tersebut tetap mengirimkan API key koneksi. Hanya nama single-label dan nama `.internal`/`.local` yang diterima; FQDN publik, literal IP, dan nama cloud-metadata diabaikan dengan peringatan. (#14635) | | `OMNIROUTE_OIDC_DISABLE_PASSWORD_LOGIN` | `false` | `src/app/api/auth/login/route.ts` | Ketika OIDC diaktifkan, nonaktifkan login kata sandi sehingga pengguna hanya dapat mengautentikasi melalui OIDC Single Sign-On. Alias tanpa awalan `OIDC_DISABLE_PASSWORD_LOGIN` juga diterima; Feature Flag Dashboard dengan key yang sama lebih diprioritaskan. (#10889) | | `OIDC_DISABLE_PASSWORD_LOGIN` | `false` | `src/app/api/auth/login/route.ts` | Alias tanpa awalan dari `OMNIROUTE_OIDC_DISABLE_PASSWORD_LOGIN` (#10889). | ### Checklist Hardening ```bash # Minimum keamanan produksi: AUTH_COOKIE_SECURE=true # Memerlukan HTTPS REQUIRE_API_KEY=true # Autentikasi semua panggilan proxy ALLOW_API_KEY_REVEAL=false # Jangan pernah mengekspos key 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 Tool & Routing | Variabel | Default | File Sumber | Deskripsi | | ----------------------------------------------------------- | -------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `TOOL_POLICY_MODE` | `disabled` | `src/lib/toolPolicy.ts` | Mengontrol akses tool/function-calling LLM. `allowlist` = hanya tool yang terdaftar, `denylist` = semua kecuali yang terdaftar, `disabled` = tanpa pembatasan. | | `OMNIROUTE_PAYLOAD_RULES_PATH` | `./config/payloadRules.json` | `open-sse/services/payloadRules.ts` | Path ke file JSON aturan manipulasi payload (penyesuaian upstream per-model/protokol). | | `OMNIROUTE_PAYLOAD_RULES_RELOAD_MS` | `5000` | `open-sse/services/payloadRules.ts` | Interval muat ulang (ms) untuk hot-reload file aturan payload. Minimum `1000`. | | `OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS` | `false` | `open-sse/services/model.ts` | Opt-in: rutekan ID model `claude-*` tanpa prefix dari klien Claude Code melalui akun OAuth Claude Code alih-alih mengharuskan prefix provider. Prefix provider eksplisit tetap diprioritaskan. Juga dapat dikonfigurasi melalui toggle dashboard di halaman provider Claude. | | `OMNIROUTE_REDACT_THINKING` | `true` | `open-sse/executors/base/redactThinkingBeta.ts` | Atur `false` untuk menghentikan OmniRoute menambahkan sendiri beta Anthropic `redact-thinking-2026-02-12` (blok thinking kosong yang hanya berisi signature). Permintaan dengan `thinking.display: "summarized"` tetap melewatkannya; beta redact yang dinegosiasikan klien atau opt-in `requestDefaults.redactThinking` yang kompatibel dengan CC tetap mempertahankannya. Permintaan OAuth Claude mempertahankan beta tersebut (karena merupakan bagian dari fingerprint OAuth Claude Code) kecuali feature flag `CLAUDE_OAUTH_SUMMARIZED_THINKING_UNREDACTED` yang secara default nonaktif diaktifkan. | | `BARE_MODEL_DEFAULT_OVERRIDE_LEGACY` | `false` | `open-sse/services/model.ts` | Perilaku lawas `resolveBareModelToConnectionDefault` (#4825): mengganti nama model apa pun tanpa prefix dengan `defaultModel` milik koneksi yang dipilih. Nonaktif secara default, hanya `auto` atau model kosong yang diganti; mencatat satu peringatan per pasangan saat aktif. | | `COMBO_CONCURRENCY_PER_MODEL` | `3` | `open-sse/services/comboConfig.ts` | Batas konkurensi per-model untuk combo round-robin (#9100). Semaphore combo round-robin sebelumnya dibatasi secara permanen pada 3 permintaan konkuren per model tanpa opsi override, sehingga lalu lintas dengan konkurensi lebih tinggi terserialisasi di balik batas tersebut. Divalidasi hingga `>= 1`, dibatasi hingga `<= 32`. | | `DISABLE_CONTEXT_WINDOW_CHECKS` | `false` | `open-sse/handlers/chatCore.ts` | Opt-in berbahaya yang melewati pemeriksaan context-window / max-input-token lokal OmniRoute untuk permintaan model tunggal langsung. Provider upstream tetap memberlakukan batas aktual mereka; kompresi prompt dan batas output-token model itu sendiri tetap aktif. Prioritas efektif adalah override Feature Flags DB > environment variable > default; tidak perlu restart. | | `OMNIROUTE_SELF_HOSTED_PROVIDERS` | _(tidak diatur)_ | `open-sse/services/selfHostedEntry.ts` | Dokumen YAML inline `providers:` (RIC-738, D4). Saat diatur (dengan atau tanpa blok `strategy:`), `/v1/chat/completions` dialihkan ke entri terpadu self-hosted yang kompatibel dengan OpenAI alih-alih pipeline cloud. Tidak diatur (default): route langsung diteruskan ke pipeline cloud yang ada. Lihat `docs/routing/SELF_HOSTED_OPENAI_ENTRY.md`. | | `OMNIROUTE_SELF_HOSTED_PROVIDERS_FILE` | _(tidak diatur)_ | `open-sse/services/selfHostedEntry.ts` | Path ke file YAML yang berisi dokumen `providers:` yang sama seperti `OMNIROUTE_SELF_HOSTED_PROVIDERS`, untuk deployment yang lebih memilih file daripada env var inline. Salah satu dari keduanya mengaktifkan entri self-hosted. | | `OMNIROUTE_SELF_HOSTED_API_KEY` | _(tidak diatur — route terbuka)_ | `open-sse/services/selfHostedEntry.ts` | API key bersama opsional untuk entri self-hosted terpadu (scaffold D5, dicadangkan untuk sistem kuota per-key). Saat diatur, permintaan harus menyertakan `Authorization: Bearer `. Tidak diatur: route terbuka, sesuai pola provider lokal self-hosted yang ada (deployment loopback/jaringan tepercaya). | | `OMNIROUTE_SELF_HOSTED_STRATEGY` | _(tidak diatur)_ | `open-sse/services/routingStrategies.ts` | Dokumen YAML inline `strategy:` untuk mesin routing deterministik (M2/RIC-740, D3) — daftar hitam/daftar putih, pemutus cooldown, prioritas biaya, sadar latensi, rantai fallback. Menimpa blok inline `strategy:` yang bersarang di dalam `OMNIROUTE_SELF_HOSTED_PROVIDERS`, per kunci. Lihat `docs/routing/DETERMINISTIC_ROUTING.md`. | | `OMNIROUTE_SELF_HOSTED_STRATEGY_FILE` | _(tidak diatur)_ | `open-sse/services/routingStrategies.ts` | Jalur ke file YAML yang memuat dokumen `strategy:` yang sama seperti `OMNIROUTE_SELF_HOSTED_STRATEGY`, untuk deployment yang lebih memilih file daripada variabel env inline. | | `OMNIROUTE_DISABLE_CONVERSATION_TRACKING` | _(tidak diatur)_ | `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 routing tidak berubah dan catatan yang sudah ada tidak dihapus. Untuk deployment yang tidak menggunakan tampilan percakapan dasbor dan ingin tabel turn berhenti bertambah. | | `OMNIROUTE_NADIR_API_KEY` | _(tidak diatur)_ | `open-sse/services/autoCombo/nadirStrategy.ts` | Kunci API untuk strategi router auto-combo `nadir` yang bersifat opt-in, digunakan saat `config.nadir.apiKey` milik combo tidak diatur. Opsional: panggilan tanpa kunci masuk ke tier anonim Nadir, yang dibatasi lajunya per IP sehingga tidak dapat digunakan di balik gateway bersama. Sensitif; utamakan field per-combo saat combo menggunakan akun yang berbeda. | | `OMNIROUTE_NADIR_BASE_URL` | `https://api.getnadir.com` | `open-sse/services/autoCombo/nadirStrategy.ts` | Origin dasar dari API keputusan Nadir, digunakan saat `config.nadir.baseUrl` milik combo tidak diatur. Hanya diperlukan untuk Nadir self-hosted, yang menjaga prompt head tetap berada di dalam jaringan Anda sendiri. Akhiran `/v1` ditoleransi dan dihilangkan. | | `OMNIROUTE_API_KEY_WEEKLY_WINDOW` | `provider` | `src/lib/usage/apiKeyUsageLimits.ts` | Jendela mingguan untuk batas penggunaan USD per kunci API (penegakan request, `GET /api/keys/{id}/usage-limits`, `@@om-usage`). `provider`: minggu berakhir pada reset mingguan paling awal di antara koneksi upstream yang dapat dijangkau kunci tersebut, atau berupa 7 hari bergulir bila tidak ada yang diketahui. `calendar`: minggu lokal dari Senin 00:00 hingga Senin 00:00 berikutnya, identik untuk setiap kunci. `calendar` direkomendasikan saat satu pool akun upstream dipakai bersama oleh banyak kunci yang masing-masing memiliki anggaran sendiri. Nilai yang tidak valid kembali ke `provider`. | | `OMNIROUTE_API_KEY_WEEKLY_WINDOW_TIMEZONE` | _(zona waktu proses)_ | `src/lib/usage/apiKeyUsageLimits.ts` | Zona waktu IANA (misalnya `Asia/Shanghai`) yang menentukan Senin 00:00 untuk jendela mingguan `calendar`. Tidak diatur atau tidak valid: zona waktu proses OmniRoute (`TZ` dari host atau container, yang sering tidak diatur, yaitu Coordinated Universal Time, pada image container). Diabaikan dalam mode `provider`. | | `OMNIROUTE_MAX_TOOLS_LIMIT` | `128` | `open-sse/config/constants.ts` | Jumlah maksimum default tools yang diizinkan dalam satu request (default OpenAI). Hanya bilangan bulat positif; nilai yang tidak diatur atau tidak valid tetap memakai `128`. Provider dengan batas yang diketahui/proaktif (`grok-cli` 200, `nvidia` 1536) tetap menerapkan batasnya sendiri — ini hanya menggeser batas atas default. | | `OMNIROUTE_PROMPT_EMULATE_TOOLS` | _(aktif)_ | `open-sse/executors/syntxChat.ts` | Pemanggilan tool emulasi-prompt SYNTX.ai: tidak diatur atau `1`/`true`/`on`/`yes` menyuntikkan katalog tool lokal ke dalam prompt; nilai lainnya (mis. `0`) melewatkan penyuntikan tersebut. | --- ## 7. URL & Sinkronisasi Cloud | Variabel | Default | File Sumber | Deskripsi | | ------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `BASE_URL` | `http://localhost:20128` | `src/lib/cloudSync.ts` | URL sisi server yang digunakan oleh pekerjaan sinkronisasi internal untuk memanggil `/api/sync/cloud`. Pertahankan sebagai URL loopback/container meskipun aplikasi diproksikan secara publik. | | `CLOUD_URL` | _(kosong)_ | `src/lib/cloudSync.ts` | URL endpoint relay 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 secara fisik mengecualikan modul istimewa 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` | Rahasia bersama yang digunakan untuk memverifikasi tanda tangan HMAC-SHA256 dari respons Cloud Sync. | | `OMNIROUTE_CLOUD_SYNC_SECRETS` | `false` | `src/lib/cloudSync.ts` | Atur ke `true` untuk mengizinkan endpoint Cloud Sync menimpa kredensial lokal. Default-nya adalah `false`. | | `OMNIROUTE_CLOUD_SYNC_ENFORCE_SIGNATURE` | `false` | `src/lib/cloudSync.ts` | Atur ke `true` untuk menolak respons Cloud Sync yang tidak ditandatangani ketika tidak ada rahasia lokal yang dikonfigurasi (#13679). Tanda tangan yang tersedia selalu diverifikasi — dan selalu ditolak ketika `OMNIROUTE_CLOUD_SYNC_SECRET` tidak ditetapkan — terlepas dari flag ini. Default berubah menjadi wajib diterapkan di v3.9. | | `OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP` | `false` | `src/app/api/providers/zed/import/route.ts` | Atur ke `true` untuk kembali menggunakan perilaku satu langkah "impor semuanya" dari v3.8.5 tanpa konfirmasi pengguna. | | `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | OAuth, Dasbor, sinkronisasi | URL yang menghadap publik untuk redirect_uri OAuth, 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 disetel)_ | `src/shared/services/cloudSyncScheduler.ts` | Fallback lama untuk `NEXT_PUBLIC_BASE_URL`. | | `NEXT_PUBLIC_PORT` | _(tidak disetel — fallback ke `PORT`)_ | `src/shared/hooks/useDisplayBaseUrl.ts` | Port fallback sisi klien untuk URL tampilan ketika origin tidak diketahui (SSR/pengujian); dibaca sebelum `PORT`. | | `OMNIROUTE_PUBLIC_BASE_URL` | _(tidak disetel)_ | Resolver origin publik, URL gambar | Origin OmniRoute yang diakses browser dengan prioritas tertinggi, digunakan untuk pembuatan URL publik dan validasi origin browser non-dashboard. Setel 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 disetel)_ | `open-sse/config/providerPluginManifestUrl.ts` | URL absolut manifes plugin penyedia yang diumumkan kepada klien sidecar. Jika tidak disetel, 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. Setel ke `https` di belakang proksi publik yang mengakhiri TLS ketika `OMNIROUTE_PROVIDER_MANIFEST_URL` eksplisit tidak disetel. | | `OMNIROUTE_TRUST_PROXY` | _(tidak disetel)_ | `src/server/origin/publicOrigin.ts` | Mode kepercayaan opsional untuk header origin publik yang diteruskan. Tidak disetel = jangan percayai `Forwarded` / `X-Forwarded-*` untuk keputusan keamanan. `true` / `loopback` hanya memercayai host/proto yang diteruskan dari proksi loopback yang diberi token. `private` / `lan` juga memercayai peer proksi LAN privat, serta memungkinkan bridge `API_PORT` mempertahankan `X-Forwarded-For` milik peer tersebut. Utamakan `NEXT_PUBLIC_BASE_URL` eksplisit dalam produksi. | | `KIE_CALLBACK_URL` | _(tidak disetel)_ | `open-sse/utils/kieTask.ts` | URL callback publik untuk pekerjaan kie.ai asinkron. Override dengan prioritas tertinggi sebelum `OMNIROUTE_KIE_CALLBACK_URL` dan `OMNIROUTE_PUBLIC_URL`. | | `OMNIROUTE_KIE_CALLBACK_URL` | _(tidak disetel)_ | `open-sse/utils/kieTask.ts` | Penulisan alternatif untuk `KIE_CALLBACK_URL`. Digunakan sebagai fallback ketika variabel utama tidak disetel. | | `OMNIROUTE_PUBLIC_URL` | _(tidak disetel)_ | `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 lain. | | `OMNIROUTE_CROF_USAGE_URL` | `https://crof.ai/usage_api/` | `open-sse/services/usage.ts` | Endpoint pencarian kuota CrofAI yang digunakan oleh halaman Usage. Override untuk relay / fixture pengujian. | | `OMNIROUTE_CLINEPASS_USAGE_URL` | `https://api.cline.bot/api/v1/users/me/plan/usage-limits` | `open-sse/services/usage/clinepass.ts` | Endpoint kuota 5 jam / mingguan / bulanan ClinePass yang digunakan oleh halaman Usage. Override 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 Usage. Override untuk relay / fixture pengujian. | | `OPENCODE_SYNTHESIZE_CLI_HEADERS` | `true` | `open-sse/executors/opencode.ts` | Sintesis header identitas OpenCode CLI (User-Agent, x-opencode-client/project, UUID permintaan/sesi) pada permintaan upstream opencode-go/zen yang tidak dikirim oleh klien, agar 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 ketika `OPENCODE_SYNTHESIZE_CLI_HEADERS` aktif dan tidak ada penggantian `_USER_AGENT` per penyedia yang ditetapkan. Hanya diterapkan pada eksekutor opencode. Pada permintaan tanpa kunci yang dibatasi oleh upstream, nilai terkonfigurasi yang tidak memuat `opencode/= 1.17>` akan diganti dengan nilai default ini, bukan ditolak. | | `OMNIROUTE_FORWARD_ATTRIBUTION` | `1` (aktif) | `open-sse/utils/opencodeHeaders.ts` | Teruskan header atribusi aplikasi klien (`x-session-id`, `x-title`, `http-referer`) ke penyedia upstream, sehingga permintaan yang dimulai di dalam harness yang tercantum mempertahankan identitasnya saat melewati router (gate penerbit OpenRouter bergantung pada header ini). `0`/`false`/`no`/`off` mempertahankan identitas registri/operator dan menghapus nilai yang diberikan klien. Header khusus yang dikonfigurasi operator selalu lebih diprioritaskan daripada nilai klien. | | `OPENCODE_CLIENT` | `desktop` | `open-sse/executors/opencode.ts` | Nilai untuk header `x-opencode-client` yang disintesis ketika `OPENCODE_SYNTHESIZE_CLI_HEADERS` aktif. | | `OPENCODE_PROJECT` | `global` | `open-sse/executors/opencode.ts` | Nilai untuk header `x-opencode-project` yang disintesis ketika `OPENCODE_SYNTHESIZE_CLI_HEADERS` aktif. | | `OMNIROUTE_EGRESS_IP_LOCK_PROVIDERS` | _(tidak ditetapkan)_ | `open-sse/config/providerErrorRules.ts` | Kumpulan efektif penyedia yang kegagalan upstream-nya dikelompokkan berdasarkan IP egress (satu 429 menonaktifkan sementara setiap koneksi terkait yang berbagi IP tersebut). Jika tidak ditetapkan, digunakan default tingkat gratis `opencode,opencode-go,opencode-cli`; `none`/`off`/`false`/`0` menonaktifkan kaskade sepenuhnya; daftar yang dipisahkan koma menggantikan kumpulan tersebut. Paket berbayar dikelompokkan berdasarkan akun di upstream dan dapat menonaktifkannya dengan aman (#9611). | | `OMNIROUTE_EGRESS_QUOTA_ROTATION_PROVIDERS` | _(tidak ditetapkan)_ | `open-sse/config/providerErrorRules.ts` | Cakupan rotasi egress untuk penolakan kuota. Jika tidak ditetapkan, anggota pool disisihkan saat menerima 429 hanya untuk kelompok berbasis IP di atas; `all` memperluas penulisan tersebut ke setiap penyedia, sehingga batas laju yang diterima melalui suatu anggota membuat pemilihan berikutnya menggunakan egress lain. Nilai apa pun selain `all` akan diabaikan. Memerlukan `PROXY_SKIP_RECENTLY_FAILED` (aktif secara default). Penyimpanan menggunakan alamat egress sebagai kunci, bukan (penyedia, alamat), sehingga 429 yang diperluas akan menonaktifkan sementara anggota tersebut untuk setiap penyedia hingga periodenya berakhir (5 menit, meningkat dua kali lipat menjadi 15). Dibaca pada setiap hasil respons, sehingga perubahan berlaku tanpa memulai ulang. | | `OPENCODE_FREE_TIER_REQUEST_CONTRACT` | _(tidak ditetapkan)_ | `open-sse/executors/opencodeFreeTierContract.ts` | Tetapkan ke `off` untuk berhenti menyesuaikan 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 ditetapkan)_ | `open-sse/executors/opencodeFreeTierContract.ts` | Nama alat yang dipisahkan koma untuk dideklarasikan pada permintaan OpenCode tanpa kunci yang tidak menyertakan alat, ketika belum ada yang diamati untuk model tersebut. Nilai kosong akan menggunakan satu placeholder yang diinstruksikan agar tidak dipanggil oleh model. 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. Ganti untuk relay / fixture pengujian. | | `OMNIROUTE_OLLAMA_CLOUD_BALANCE_URL` | `https://ollama.com/api/balance` | `open-sse/services/ollamaCloudBalance.ts` | Endpoint saldo upstream Ollama Cloud yang terdokumentasi (`GET https://ollama.com/api/balance`, `Authorization: Bearer `). Dibaca satu kali saat modul dimuat. Digunakan terlebih dahulu untuk kuota Ollama Cloud ketika koneksi memiliki kunci API; pengambil data berbasis cookie dari halaman pengaturan tetap digunakan sebagai fallback. Ganti untuk relay / fixture pengujian. | | `OLLAMA_USAGE_COOKIE` | _(tidak ditetapkan)_ | `open-sse/services/usage.ts` | Cookie `__Secure-session` Ollama Cloud yang digunakan untuk mengambil data kuota dari halaman pengaturan. Sensitif; sebaiknya gunakan kolom Dashboard per koneksi ketika beberapa akun dikonfigurasi. | | `OLLAMA_CLOUD_USAGE_COOKIE` | _(tidak ditetapkan)_ | `open-sse/services/usage.ts` | Variabel lingkungan alternatif untuk cookie `__Secure-session` Ollama Cloud. Sensitif; sebaiknya gunakan kolom Dashboard per koneksi ketika 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; utamakan kolom Dashboard per koneksi ketika 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 balik reverse proxy (nginx, Caddy), tetapkan `NEXT_PUBLIC_BASE_URL` ke URL publik stabil Anda (misalnya, `https://omniroute.example.com`) ketika 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 tugas antarpeladen. Jangan gunakan `Origin` peramban atau nama host publik untuk pengambilan mandiri internal yang menyertakan kredensial. > > Penulisan dashboard terautentikasi tidak memerlukan URL dasar publik statis: dashboard mengirim permintaan tidak aman dengan origin yang sama beserta token CSRF yang terikat pada sesi. OmniRoute tetap memusatkan validasi origin publik untuk integrasi peramban 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 token yang menandainya sebagai tepercaya. Jangan gunakan pengaturan CORS untuk memperbaiki permintaan dashboard dengan origin yang sama; CORS hanya untuk klien peramban lintas origin. --- ## 8. Proksi Outbound Arahkan panggilan penyedia LLM upstream melalui proksi HTTP atau SOCKS5 untuk kontrol egress, geo-routing, atau penyamaran IP. `OMNIROUTE_UPSTREAM_HTTP2_ENABLED` secara default bernilai `true`. Atur ke `false`, `0`, `no`, atau `off` untuk memaksa HTTP/1.1 pada dispatcher Undici di `open-sse/utils/proxyDispatcher.ts` dan `open-sse/utils/proxyFetch.ts`: egress langsung, proksi HTTP(S)/SOCKS, relay, dan percobaan ulang fresh-socket-nya. Ini mempertahankan verifikasi sertifikat TLS, autentikasi proksi, batas koneksi, dan pengaturan keep-alive. Mulai ulang OmniRoute setelah mengubahnya karena dispatcher disimpan dalam cache dan agen relay dibuat saat startup. Sakelar ini tidak mengontrol TLS fingerprinting wreq atau transport khusus penyedia. | Variabel | Default | File Sumber | Deskripsi | | ---------------------------------------- | ---------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ENABLE_SOCKS5_PROXY` | `true` | `open-sse/executors` | Aktifkan agen proxy SOCKS5 untuk panggilan upstream. Nonaktifkan dengan `false`. | | `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` | `true` | Sisi klien | Pengetahuan sisi klien tentang ketersediaan SOCKS5. | | `PROXY_SKIP_RECENTLY_FAILED` | `true` | `src/shared/utils/featureFlags.ts` | Flag fitur yang aktif secara default (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); override DB dasbor menang). Pool proxy dan rotasi per akun berhenti melayani kembali anggota yang baru saja gagal (probe TCP ditolak, atau 429 melaluinya) untuk periode yang berlipat ganda pada setiap pengulangan, hingga batas maksimum. `false` mengembalikan pemilihan biasa. | | `SELECTOR_CONTROL_ALLOWLIST` | _(belum diatur)_ | `src/lib/proxySubscription/selectorGuard.ts` | Daftar izin untuk target kontrol selektor local-core di luar loopback (host atau IP yang dipisah koma/spasi, `*` membuka LAN/privat tetapi tidak pernah metadata/link-local). Loopback melalui http/https diizinkan secara default. Nilai DB dasbor menang atas variabel ini ketika diatur dan tidak kosong. | | `PROXY_QUOTA_429_BASE_MS` | `300000` | `open-sse/utils/proxyRefusalMemory.ts` | Periode dasar (ms) pengesampingan 429, berlipat ganda pada setiap pengulangan. Dibaca sekali saat startup. Dibatasi pada `1000..3600000`; di luar rentang atau tidak dapat dibaca akan kembali ke default dengan peringatan. | | `PROXY_QUOTA_429_MAX_MS` | `900000` | `open-sse/utils/proxyRefusalMemory.ts` | Batas atas (ms) pengesampingan 429. Dibaca sekali saat startup. Dibatasi pada `1000..3600000`; di luar rentang atau tidak dapat dibaca akan kembali ke default dengan peringatan. Ketika batas atas lebih rendah dari dasar, nilainya kembali ke default. Menurunkan batas atas juga memperpendek pelupaan streak: entri dibersihkan `2 x max` setelah kedaluwarsa. | | `PROXY_POOL_SHARED_EGRESS_ORDER` | `false` | `src/shared/utils/featureFlags.ts` | Flag fitur opt-in (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); override DB dasbor menang). Untuk provider yang kuotanya dikelompokkan berdasarkan alamat egress, beri peringkat anggota pool yang berbagi alamat egress teramati milik anggota yang baru saja ditolak tepat di bawah anggota yang sehat. Hanya memengaruhi urutan, tidak pernah dikecualikan. Memerlukan `PROXY_SKIP_RECENTLY_FAILED`, yang menghasilkan sinyal penolakan yang dibacanya. | | `PROXY_WEBHOOK_REBOUND_MS` | `300000` | `src/lib/proxyEvents/proxyTransitionBridge.ts` | Jendela rebound (ms) yang membatasi peringatan webhook `proxy.set_aside` berulang per anggota pool sehingga serentetan penolakan hanya mengirim satu event. Dibaca pada setiap emit. Dibatasi pada `1000..3600000`; di luar rentang atau tidak dapat dibaca akan kembali ke default secara diam-diam. | | `HTTP_PROXY` | _(belum diatur)_ | Standar Node.js | Proxy HTTP untuk panggilan upstream. | | `HTTPS_PROXY` | _(belum diatur)_ | Standar Node.js | Proxy HTTPS untuk panggilan upstream. | | `ALL_PROXY` | _(belum diatur)_ | Standar Node.js | Proxy universal (mendukung `socks5://`). | | `OMNIROUTE_PROXY_ECHO_URL` | _(tidak diatur)_ | `src/lib/proxyEchoTarget.ts` | Menetapkan target echo-IP yang digunakan oleh probe egress proxy 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 | Daftar hostname/IP yang dipisahkan koma untuk melewati proxy. | | `OMNIROUTE_PROXY_DISPATCHER_CONNECTIONS` | `32` | `open-sse/utils/proxyDispatcher.ts` | Jumlah maksimum soket bersamaan per dispatcher proxy HTTP/SOCKS yang di-cache. Stream SSE berumur panjang seperti Codex `/v1/responses` membutuhkan lebih dari satu koneksi ketika beberapa permintaan berbagi proxy tingkat akun yang sama. Nilai di atas `256` akan dibatasi. | | `SOCKS_HANDSHAKE_TIMEOUT_MS` | `10000` | `open-sse/utils/socksConnectorWithFamily.ts` | Batas waktu handshake SOCKS5 (connect) dalam ms. Naikkan ketika satu host gateway residensial terkena konkurensi tinggi (mis. 100 permintaan simultan) — handshake sebenarnya dapat melebihi 10 detik pada pool yang jenuh meskipun proxy dapat dijangkau, yang jika tidak akan muncul sebagai `[Proxy Fast-Fail] Proxy unreachable` palsu. Dibatasi pada `120000`. | | `PROXY_FAIL_OPEN` | `false` | `src/sse/handlers/chatHelpers.ts` | Ketika `false` (default), permintaan yang proxy yang ditugaskan gagal di-resolve akan **ditolak (fail-closed)** alih-alih beralih ke koneksi langsung — mencegah kebocoran IP asli. Atur `true` untuk mengembalikan fallback DIRECT lama. | | `ENABLE_TLS_FINGERPRINT` | `false` | `open-sse/executors` | Memalsukan fingerprint TLS menggunakan wreq-js (meniru Chrome 124). Menangkal pemblokiran JA3/JA4. | | `TLS_FINGERPRINT_PROVIDERS` | _(tidak diatur)_ | `open-sse/utils/proxyFetch.ts` | Daftar allowlist provider yang dipisahkan koma untuk routing TLS ber-proxy baru (`open-sse/utils/proxyFetch.ts`). TLS langsung mempertahankan perilaku lamanya ketika tidak diatur; hanya provider-provider ini yang dirutekan melalui jembatan fingerprint Chrome 124. Groq (`api.groq.com`) dikecualikan bahkan ketika allowlist tidak diatur, karena JA3 Chrome memicu Cloudflare 1010 sementara undici native dapat mencapai API. | | `OMNIROUTE_TURNSTILE_IGNORE_TLS_ERRORS` | `false` | `open-sse/services/claudeTurnstileSolver.ts` | Mengizinkan konteks browser Playwright Claude Turnstile untuk mengabaikan error sertifikat HTTPS. | ### Skenario | Skenario | Konfigurasi | | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **SOCKS5 melalui tunnel SSH** | `ALL_PROXY=socks5://127.0.0.1:7890`, `ENABLE_SOCKS5_PROXY=true` | | **Proxy HTTP korporat** | `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` (sudah termasuk) | | **Egress dikontrol / tanpa akses langsung** | Biarkan `PROXY_FAIL_OPEN=false` (default). Permintaan gagal total ketika proxy tidak tersedia alih-alih bocor melalui koneksi langsung. | | **Lama / dev — izinkan fallback langsung** | `PROXY_FAIL_OPEN=true`. Mengembalikan perilaku pra-hardening: koneksi langsung digunakan ketika resolusi proxy gagal. | > **Catatan (bypass validasi NVIDIA — #3226):** Endpoint validasi kunci API NVIDIA > macet ketika dirutekan melalui fetch proxy global/TLS yang di-patch (dispatcher undici → 504). > `src/lib/providers/validation.ts::directHttpsRequest()` secara sengaja melewati > patch proxy untuk satu panggilan validasi tersebut menggunakan `safeOutboundFetch({ bypassProxyPatch: true })`. > Ini adalah pengecualian terdokumentasi dengan cakupan terbatas — **tidak** memengaruhi egress chat/penggunaan. > Bypass ini dikunci cakupannya oleh `tests/unit/proxy-bypass-scope-guard-3226.test.ts`. --- ## 9. Integrasi Alat CLI Mengontrol cara OmniRoute menemukan dan meluncurkan sidecar CLI (Claude Code, Codex, dll.). | Variabel | Default | Berkas 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 penemuan biner CLI (dipisahkan titik dua). | | `CLI_CONFIG_HOME` | _(tidak diatur)_ | `src/shared/services/cliRuntime.ts` | Menimpa direktori home untuk membaca konfigurasi CLI (`~/.claude`, `~/.codex`). Harus berupa path absolut dan berada di dalam home proses — **atau**, di dalam kontainer, path yang di-bind-mount (begitulah cara kerja `/host-home`). Nilai lainnya akan kembali ke direktori home. | | `CLI_ALLOW_CONFIG_WRITES` | `true` | `src/shared/services/cliRuntime.ts` | Mengizinkan OmniRoute menulis berkas konfigurasi CLI (pembaruan token, data sesi). Atur ke `false` agar setiap penulisan konfigurasi CLI gagal dengan error eksplisit "writes disabled". | | `CLI_CLAUDE_BIN` | `claude` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Claude CLI. | | `CLI_CODEX_BIN` | `codex` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Codex CLI. | | `CLI_DROID_BIN` | `droid` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Droid CLI. | | `CLI_OPENCLAW_BIN` | `openclaw` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner OpenClaw CLI. | | `CLI_CURSOR_BIN` | `agent`, lalu `cursor` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner agen Cursor. Tanpa ini, deteksi mencoba `agent` terlebih dahulu lalu kembali ke `cursor`. | | `CLI_CLINE_BIN` | `cline` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Cline CLI. | | `CLI_5DIVE_BIN` | `5dive` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner 5dive CLI. | | `CLI_5DIVE_STATE_DIR` | `/var/lib/5dive` | `src/shared/services/cliRuntime.ts` | Direktori state sistem milik 5dive (profil autentikasi milik root); mencerminkan default STATE_DIR milik 5dive sendiri. | | `CLI_CONTINUE_BIN` | `cn` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Continue CLI. | | `CLI_QODER_BIN` | `qodercli` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Qoder CLI. | | `CLI_QWEN_BIN` | `qwen` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Qwen Code CLI. | | `CLI_AIDER_BIN` | `aider` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Aider CLI. | | `CLI_GOOSE_BIN` | `goose` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Goose CLI. | | `CLI_GEMINI_BIN` | `gemini` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Google Gemini CLI — hanya untuk deteksi/health check sisi server; `omniroute run gemini` me-resolve biner `gemini` dari PATH sistem. | | `CLI_KILO_BIN` | `kilocode` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner Kilo Code CLI. | | `CLI_OPENCODE_BIN` | `opencode` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner OpenCode CLI. | | `CLI_HERMES_BIN` | `hermes` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary Hermes. Digunakan bersama oleh kedua entri katalog (`hermes` dan `hermes-agent`). | | `CLI_FORGE_BIN` | `forge` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary CLI ForgeCode. | | `CLI_JCODE_BIN` | `jcode` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary CLI jcode. | | `CLI_DEEPSEEK_TUI_BIN` | `deepseek-tui` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary TUI DeepSeek. | | `CLI_CODEWHALE_BIN` | `codewhale` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary CLI CodeWhale. | | `CLI_SMELT_BIN` | `smelt` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary CLI Smelt. | | `CLI_PI_BIN` | `pi` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary Pi (pi-coding-agent). | | `CLI_CRUSH_BIN` | `crush` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary CLI Crush. | | `CLI_OMP_BIN` | `omp` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary agen Oh My Pi (`omp`). | | `CLI_LETTA_BIN` | `letta` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary CLI Letta. | | `CLI_PRIME_AGENT_BIN` | `prime-agent` | `src/shared/services/cliRuntime.ts` | Path kustom ke binary Prime Agent (Prime Intellect). | | `CLI_WINDSURF_BIN` | _(tidak ada)_ | `src/shared/services/cliRuntime.ts` | Path kustom ke binary Windsurf. Windsurf dikirimkan **tanpa perintah default** — deteksi binary tetap dinonaktifkan sampai variabel ini diatur. | | `CLI_DEVIN_BIN` | `devin` | `open-sse/executors/devin-cli.ts` | Path kustom ke binary 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. Override harus menggunakan format `x.y.z`; nilai yang tidak valid akan kembali ke default yang terverifikasi. | | `DEVIN_DESKTOP_EXTENSION_VERSION` | `1.48.2` | `open-sse/executors/devin-desktop.ts` | `extension_version` Codeium/language-server bawaan, berbeda dari `ide_version` Desktop. Override harus menggunakan format `x.y.z`; nilai yang tidak valid menggunakan default bawaan. | | `CLI_DEVIN_AGENTIC_BIN` | `devin` | `open-sse/executors/devin-cli-agentic.ts` | Override CLI Devin khusus bridge agentic. Eksekutor hanya menerima upstream ACP stdio lokal. | | `DEVIN_AGENTIC_HOME` | _(wajib)_ | `open-sse/executors/devin-cli-agentic.ts` | Home terisolasi absolut untuk subproses Devin agentic; path bridge yang diterima adalah `/home/bridge` dan path `.sandbox` lokal-tugas (di Windows, `C:\...\.sandbox\...`). | | `DEVIN_AGENTIC_ACP_TIMEOUT_MS` | `120000` | `open-sse/executors/devin-cli-agentic.ts` | Durasi maksimum satu turn 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 Claude Code utama untuk bridge terisolasi. Harness live menggantikan contoh 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` | Override opsional untuk API manajemen seat Codeium yang digunakan oleh kuota Devin CLI (`GetUserStatus`). | | `AUGGIE_BIN` | `auggie` | `open-sse/executors/auggie.ts` | Override path absolut untuk binary CLI Augment (Auggie) yang digunakan oleh provider `auggie` lokal. Kembali ke `CLI_AUGGIE_BIN`, lalu pencarian PATH. | | `CLI_AUGGIE_BIN` | `auggie` | `open-sse/executors/auggie.ts` | Override alias untuk path binary CLI Augment (Auggie) (diperiksa setelah `AUGGIE_BIN`). | | `ZCODE_BIN` | `zcode` | `open-sse/executors/zcode.ts` | Binary yang digunakan untuk klien stdio provider `zcode` lokal. Kembali ke `zcode` di PATH. | | `ZCODE_ARGS` | — | `open-sse/executors/zcode.ts` | Array JSON (≤16 string) berisi argumen tambahan yang diteruskan ke binary `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` | Override untuk id provider yang dikirim ke app-server. | | `ZCODE_SERVER_RUNTIME_ROOT` | `~/.zcode/server` | `open-sse/executors/zcode.ts` | Root runtime app-server ZCode (tempat `node` dan `zcode-server.cjs` yang dibundel 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) satu giliran ZCode sebelum supervisor menghentikannya karena timeout. | | `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 home Hermes Agent tempat OmniRoute membaca/menulis konfigurasi Hermes CLI. Sesuai dengan env var yang diatur oleh installer PowerShell Hermes di Windows (`%LOCALAPPDATA%\hermes`). | ### Sinkronisasi Otomatis Profil CLI Flag fitur ini bersifat opt-in dan nonaktif secara default. Flag ini juga dapat diaktifkan dari dashboard CLI Code. | Variabel | Default | File Sumber | Deskripsi | | ------------------------------------- | ------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OMNIROUTE_AUTO_SYNC_CODEX_PROFILES` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Setelah sinkronisasi model provider, secara otomatis menulis ulang file profil `~/.codex/*.config.toml` dari katalog live. Memerlukan `CLI_ALLOW_CONFIG_WRITES`; tidak pernah mengubah konfigurasi Codex aktif/default, auth, pengaturan Codex-lb, atau pilihan provider. | | `OMNIROUTE_AUTO_SYNC_CLAUDE_PROFILES` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Setelah sinkronisasi model provider, secara otomatis menulis ulang file profil Claude Code `~/.claude/profiles//settings.json` dari katalog live. Memerlukan `CLI_ALLOW_CONFIG_WRITES`; tidak pernah mengubah konfigurasi Claude aktif/default, auth, atau pilihan provider. | ### Contoh Docker ```bash # Mount binary host ke dalam container dan beri tahu OmniRoute di mana lokasinya: 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 path tersebut benar-benar di-bind-mount dari host — pasangkan dengan mount seperti `~/.codex:/host-home/.codex:rw` (lihat profil `host` di `docker-compose.yml`). Path yang tidak berada di dalam home pengguna container maupun bind mount akan diabaikan, karena penulisan di sana akan dibuang saat container dibuat ulang. Image berjalan 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` | Paksa deteksi container aktif (`1`/`true`) atau nonaktif (`0`/`false`). Hanya diperlukan pada runtime yang terlewat oleh deteksi otomatis. | | `OMNIROUTE_ALLOW_CONTAINER_CONFIG_WRITE` | `false` | `src/shared/services/cliRuntime.ts` | Tetap izinkan penulisan konfigurasi CLI-tool ke path container yang tidak di-mount. Padanan CLI-nya adalah `--allow-container-write`. | | `DOCKER_UPDATE_TRIGGER_FILE` | tidak disetel | `src/lib/system/autoUpdate.ts` | Khusus image Docker: dashboard **Update Now** menulis permintaan JSON ke file ini (harus berada di dalam `DATA_DIR`) agar watcher di sisi host melakukan pull dan membuat ulang container. Lihat [Panduan Docker](../guides/DOCKER_GUIDE.md#dashboard-updates-in-docker). | ### Helper Biner CLI (`omniroute`) Variabel-variabel ini menyetel perilaku biner CLI `omniroute` itu sendiri (bukan deteksi sidecar di atas). | Variabel | Default | File Sumber | Deskripsi | | ------------------------------------- | --------------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OMNIROUTE_LANG` | _(sistem)_ | `bin/cli/i18n.mjs` | Paksa bahasa output CLI. Locale BCP-47 (mis. `en`, `pt-BR`). Menimpa variabel env locale sistem (LC_ALL, LC_MESSAGES). | | `OMNIROUTE_SHOW_LOG` | _(tidak disetel)_ | `bin/cli/runtime/processSupervisor.mjs` | Setel ke `1` untuk meneruskan stdout/stderr server ke terminal dalam mode supervised. Setara dengan flag `--log` pada `omniroute serve`. | | `OMNIROUTE_CLI_TOKEN` | _(tidak disetel)_ | `bin/cli/api.mjs` | Token autentikasi mesin yang disuntikkan sebagai header `x-omniroute-cli-token`. Dibuat otomatis di task 8.12. | | `GEMINI_CLI_HOME` | _(tidak disetel)_ | `bin/cli/commands/setup-gemini.mjs` | Root home Gemini yang persisten; eksekusi one-shot menggunakan home sementara yang terisolasi. | | `OMNIROUTE_CHILD_SIGNAL_TIMEOUT_MS` | `5000` | `bin/cli/commands/run.mjs` | Masa tenggang dalam milidetik sebelum mematikan paksa child CLI yang telah diberi sinyal. | | `OMNIROUTE_CLI_SKIP_DEFAULT_DATA_ENV` | _(tidak disetel)_ | `bin/omniroute.mjs` | Setel ke 1 dengan DATA_DIR eksplisit untuk melewati file environment direktori data pengguna default. | | `OMNIROUTE_SYNC_TOKEN` | _(tidak disetel)_ | `bin/cli/commands/sync.mjs` | Token sinkronisasi untuk `omniroute sync bundle` (`GET /api/sync/bundle` hanya menerima token sinkronisasi, bukan API key). Setara dengan `--token`. | | `OMNIROUTE_HTTP_TIMEOUT_MS` | `30000` | `bin/cli/api.mjs` | Timeout HTTP per percobaan (ms) untuk permintaan CLI → server. | | `OMNIROUTE_READY_TIMEOUT_MS` | `60000` | `bin/cli/utils/pid.mjs` | Waktu maksimum (ms) CLI menunggu endpoint health server sebelum mencetak peringatan timeout. Berguna untuk cold start yang lambat (mis. Windows). Dapat juga disetel melalui `--ready-timeout`. | | `OMNIROUTE_VERBOSE` | `0` | `bin/cli/api.mjs` | Setel ke `1` untuk mencetak diagnostik retry/backoff ke stderr selama perintah CLI. | | `OMNIROUTE_PLUGIN_PATH` | _(tidak disetel)_ | `bin/cli/plugins.mjs` | Direktori kustom untuk penemuan plugin CLI (paket `omniroute-cmd-*`). Default-nya `~/.omniroute/plugins/` jika tidak disetel. Khusus CLI — tidak pernah sampai ke pemindai plugin sisi server, yang ditunjuk oleh `OMNIROUTE_PLUGINS_DIR` (bagian 2). | | `OMNIROUTE_NO_UPDATE_NOTIFIER` | _(tidak disetel)_ | `bin/omniroute.mjs` | Sembunyikan notifikasi pembaruan CLI saat proses keluar jika disetel ke nilai non-kosong apa pun. Notifikasi tetap dinonaktifkan secara independen di CI, mode quiet, dan mode output non-teks. | | `OMNIROUTE_DOCTOR_LIVENESS_URL` | _(diturunkan)_ | `bin/cli/commands/doctor.mjs` | URL liveness yang diperiksa oleh `omniroute doctor`. Opsi programatik `livenessUrl` lebih diutamakan; jika tidak, nilai ini digunakan apa adanya. Jika tidak disetel, CLI menurunkan endpoint `/api/health/degradation` dari dashboard lokal. | | `OMNIROUTE_PROVIDER_CATALOG_PATH` | `src/shared/constants/providers/` | `bin/cli/provider-catalog.mjs` | Path katalog provider yang digunakan oleh perintah provider CLI. Opsi programatik `catalogPath` lebih diutamakan. Path absolut digunakan apa adanya; path relatif di-resolve dari root proyek. Jika tidak disetel, CLI menggunakan direktori konstanta provider, dengan file lawas `providers.ts` sebagai fallback. | | `OMNIROUTE_PROVIDER_TEST_MODEL` | _(default provider)_ | `bin/cli/provider-test.mjs` | Model fallback global untuk uji koneksi provider CLI. Urutan prioritasnya: model koneksi yang dikonfigurasi, override model khusus provider, nilai ini, lalu model uji bawaan provider. | --- ## 10. Integrasi Agen Internal & MCP | Variabel | Default | Berkas Sumber | Deskripsi | | ----------------------------------------------- | --------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OMNIROUTE_BASE_URL` | auto-detect | `open-sse/mcp-server/server.ts` | URL eksplisit agar alat MCP/A2A dapat menjangkau OmniRoute. Menimpa deteksi otomatis localhost. | | `OMNIROUTE_API_KEY` | _(tidak diatur)_ | Modul MCP/A2A | Kunci API untuk panggilan alat MCP internal dan skill A2A. | | `OMNIROUTE_API_KEY_ID` | _(tidak diatur)_ | `open-sse/mcp-server/audit.ts` | ID kunci untuk atribusi log audit MCP. | | `ROUTER_API_KEY` | _(tidak diatur)_ | Legacy | Alias legacy untuk `OMNIROUTE_API_KEY`. | | `OMNIROUTE_A2A_HISTORY_RETENTION_DAYS` | `30` | `src/lib/a2a/taskManager.ts` | Jumlah hari riwayat tugas A2A yang disimpan di basis data lokal sebelum pembersihan harian menghapus baris. Jika tidak diatur, non-numerik, atau `<= 0`, kembali ke `30`. | | `OMNIROUTE_A2A_MEMORY_HITS` | `1` | `src/lib/a2a/taskExecution.ts` | Kill-switch untuk fitur observabilitas memory-hits A2A. Atur ke `0` untuk melewati pencarian recall memori suatu tugas sepenuhnya; nilai lain apa pun (termasuk tidak diatur) tetap mengaktifkannya. | | `OMNIROUTE_ISSUE_AGENT_ENABLED` | `false` | `src/app/api/issue-agent/runs/route.ts` | Mengaktifkan endpoint recorded-triage Issue Agent offline/lokal. Biarkan dinonaktifkan kecuali Anda secara eksplisit menjalankan alur kerja recorded-triage lokal. | | `OMNIROUTE_ISSUE_AGENT_TIMEOUT_MS` | _(tidak diatur)_ | `src/lib/issueAgent/execution.ts` | Timeout (ms) untuk satu kali run recorded-triage Issue Agent. Dibatasi hingga maksimum internal; kembali ke default bawaan jika tidak diatur atau tidak valid. | | `OMNIROUTE_CONTEXT` | _(konteks aktif)_ | `bin/cli/program.mjs`, `bin/cli/api.mjs` | Konteks/profil mode-remote CLI untuk perintah `omniroute`; menimpa konteks aktif di penyimpanan konteks lokal. Setara dengan `--context `. | | `OMNIROUTE_CONTEXT_KEYCHAIN_DISABLED` | `0` | `bin/cli/contexts.mjs` | Menonaktifkan backend keychain OS `keytar` opsional untuk kredensial konteks CLI. Saat diaktifkan, kredensial tetap berada di `config.json` mode `0600` dan CLI mengeluarkan peringatan fallback satu kali; ditujukan untuk operasi headless/kontainer yang disengaja. | | `OMNIROUTE_MCP_ENFORCE_SCOPES` | `false` | `open-sse/mcp-server/server.ts` | Menerapkan kontrol akses berbasis scope pada panggilan alat MCP. | | `OMNIROUTE_MCP_SCOPES` | _(semua)_ | `open-sse/mcp-server/server.ts` | Scope 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 membuat serialisasi manifes. Nilai pengaktifan: `1`, `true`, `on`. | | `OMNIROUTE_MCP_DESCRIPTION_COMPRESSION` | `rtk` | `open-sse/mcp-server/descriptionCompressor.ts` | Algoritme/profil kompresi. Nilai penonaktifan: `0`, `false`, `off`. | | `OMNIROUTE_MCP_FETCH_TIMEOUT_MS` | `10000` | `open-sse/mcp-server/fetchTimeout.ts` | Batas waktu pembatalan (ms) untuk pembacaan manajemen internal MCP-server (health, resilience, combos, kuota, penggunaan). | | `OMNIROUTE_MCP_UPSTREAM_TIMEOUT_MS` | `60000` | `open-sse/mcp-server/fetchTimeout.ts` | Anggaran pembatalan (ms) untuk hop MCP yang menunggu provider (`route_request`, `web_search`, `web_fetch`). | | `OMNIROUTE_CORPUS_CACHE_SIZE` | `5` | `src/lib/localCorpus/configured.ts` | Jumlah maksimum instance indeks korpus lokal yang di-cache di memori (LRU, satu per direktori root yang diindeks). Dibatasi minimum `1`. | | `MODEL_SYNC_INTERVAL_HOURS` | `6` | `src/shared/services/modelSyncScheduler.ts` | Interval sinkronisasi katalog model dalam jam. | | `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | `src/lib/usage/providerLimits.ts` | Interval polling rate-limit dan kuota provider. | | `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 membanjiri upstream. `0` untuk memilih keluar (konkuren). | | `OMNIROUTE_QUOTA_FETCH_MIN_INTERVAL_MS` | `250` | `open-sse/services/quotaFetchThrottle.ts` | Interval minimum (ms) antara pengambilan kuota upstream berturut-turut pada jalur preflight/monitor per-permintaan; memberi jarak pada panggilan jaringan konkuren sehingga banyak akun pada satu IP tidak membanjiri upstream. Terhubung ke pengambil kuota Codex (`/wham/usage`), DeepSeek, Bailian (kedua situs pengambilan), OpenCode, dan Crof (#6009, #6911). Jalur dispatch generik `usage.ts::getUsageForProvider` (github/glm/minimax/nanogpt/xai/dll.) belum tercakup — dilacak secara terpisah. Cache hit tidak terpengaruh. `0` menonaktifkan; dibatasi `0..60000`. | | `OMNIROUTE_QUOTA_FETCH_JITTER_MS` | `120` | `open-sse/services/quotaFetchThrottle.ts` | Jarak acak tambahan per-permintaan (ms), diambil sampelnya pada setiap pengambilan kuota upstream yang dipesan. Default 120; dibatasi `0..60000`; `0` hanya menghilangkan jitter. Atur `OMNIROUTE_QUOTA_FETCH_MIN_INTERVAL_MS=0` untuk menonaktifkan seluruh throttle. Jitter tidak menjamin pencegahan pemblokiran upstream. | | `PROVIDER_LIMITS_POST_USAGE_REFRESH_DELAY_MS` | `5000` | `src/lib/usage/providerLimits.ts` | Penundaan (ms) sebelum menyegarkan batas provider setelah peristiwa penggunaan nyata, memberi waktu bagi API kuota upstream untuk mencatat konsumsi. | | `OMNIROUTE_LOGIN_BROWSER_PATH` | deteksi otomatis | `open-sse/services/adobeFireflyBrowserLogin.ts` | Path absolut ke executable Chrome atau Edge sistem yang digunakan untuk login Adobe Firefly interaktif dan perpanjangan off-screen. | | `ADOBE_FIREFLY_BROWSER_REFRESH` | diaktifkan | `open-sse/services/adobeFireflySession.ts` | Menjaga state IMS dan browser-risk tetap segar dengan sesi CDP Chrome lingkup-akun. Atur ke `0` untuk menonaktifkan perpanjangan browser. | | `ADOBE_FIREFLY_SESSION_DISK` | diaktifkan | `open-sse/services/adobeFireflySession.ts` | Menyimpan sesi Adobe yang diperbaiki di bawah `DATA_DIR` di seluruh restart proses. Atur ke `0` untuk menjaga sesi hanya di memori. | | `ADOBE_FIREFLY_MIN_SUBMIT_GAP_MS` | `12000` | `open-sse/services/adobeFireflySession.ts` | Jarak minimum dalam milidetik antara pengiriman generate Adobe Firefly; `0` menonaktifkan jarak. | | `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 408 Adobe yang transien; digabungkan dengan jarak pengiriman dalam maksimal lima percobaan. | | `OMNIROUTE_DISABLE_BACKGROUND_SERVICES` | `false` | `src/instrumentation-node.ts` | Menonaktifkan semua layanan latar belakang (sinkronisasi, harga, penyegaran model). Berguna untuk CI/test. | | `OMNIROUTE_HEADLESS` | _(belum diatur)_ | `src/lib/system/headless.ts` | Boot khusus mesin-proxy: melewati subsistem opsional, `/dashboard` → 404. Sama dengan `omniroute serve --headless`. Lihat [HEADLESS.md](../guides/HEADLESS.md). | | `OMNIROUTE_ENABLE_RUNTIME_BACKGROUND_TASKS` | _(tidak diatur)_ | `src/lib/config/runtimeSettings.ts` | Paksa tugas latar belakang aktif dalam deteksi pengujian otomatis. Atur `1` untuk menimpa heuristik pengujian. | | `OMNIROUTE_BUDGET_RESET_JOB_INTERVAL_MS` | `600000` | `src/lib/jobs/budgetResetJob.ts` | Interval pemeriksaan reset 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 `rate_limited_until` sementaranya telah berakhir, di luar jalur panas permintaan. Batas bawah `5000`. | | `OMNIROUTE_DISABLE_CONNECTION_RECOVERY` | `false` | `src/lib/quota/connectionRecovery.ts` | Nonaktifkan penjadwal pemulihan cooldown koneksi proaktif (pemulihan malas di `getProviderCredentials` tetap berlaku). | | `OMNIROUTE_REASONING_CACHE_CLEANUP_INTERVAL_MS` | `1800000` | `src/lib/jobs/reasoningCacheCleanupJob.ts` | Interval pembersihan cache reasoning (ms). Batas bawah `60000`. | | `OMNIROUTE_REASONING_MIN_BUDGET` | _tidak diatur_ (dinonaktifkan) | `open-sse/services/reasoningTokenBuffer.ts` | Batas bawah opt-in untuk anggaran output model berpikir: `max_tokens` pemanggil dalam `[256, floor)` dinaikkan ke batas bawah (dibatasi oleh batas output model). Tidak diatur = anggaran klien tidak pernah diperbesar (#9507). | | `OMNIROUTE_REASONING_EFFORT_PROBE_PROVIDERS` | _tidak diatur_ (dinonaktifkan) | `open-sse/services/learnedReasoningEffortCaps.ts` | Opt-in, id provider yang dipisahkan koma (atau `*`): ketika error 400/422 `reasoning_effort` tidak menyebutkan set yang diterima, coba ulang sekali satu tingkat lebih rendah (tidak pernah di bawah `low`) dan pelajari tingkat tersebut hanya jika probe dijawab (#14895). | | `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. Utamakan `*/5 * * * *` saat mengekspor body. | | `OMNIROUTE_LOG_EXPORT_RUN_TIMEOUT_MS` | `900000` | `src/lib/logExport/childRunner.ts` | Timeout wall-clock child per tujuan dalam milidetik. Timeout mencatat kegagalan dan mematikan proses tanpa memajukan batch yang belum diakui. Nilai tidak valid/non-positif/non-integer menggunakan default. | | `OMNIROUTE_LOG_EXPORT_CHILD_MAX_OLD_SPACE_MB` | `1024` | `src/lib/logExport/childRunner.ts` | Batas old-space V8 child ekspor Node dalam MB (bukan total RSS). Default menyisakan ruang untuk 500 baris artefak yang dibatasi beserta body; batch yang terlalu besar mungkin tetap menghabiskan heap child. Kegagalan menyarankan menurunkan ukuran batch atau menaikkan batas ini. Nilai tidak valid/non-positif/non-integer menggunakan default. Ekspor Bun kembali ke in-process tanpa batas ini. | | `OMNIROUTE_CONFIG_HOT_RELOAD_MS` | `5000` | `src/lib/config/hotReload.ts` | Interval polling (ms) untuk hot-reload konfigurasi. Lebih rendah dari `1000` ditolak. | | `OMNIROUTE_DISABLE_REDIS_AUTH_CACHE` | _(diaktifkan)_ | `src/lib/db/apiKeys.ts` | Atur `1` untuk melewati cache autentikasi API-key berbasis Redis (memaksa pembacaan DB). | | `OMNIROUTE_RTK_TRUST_PROJECT_FILTERS` | `0` | `open-sse/services/compression/engines/rtk/filterLoader.ts` | Percayai aturan filter proyek RTK yang dikelola pengguna tanpa pemeriksaan tanda tangan ketat. | | `OMNIROUTE_LITE_MAX_TOOL_LENGTH` | `2000` | `open-sse/services/compression/lite.ts` | Batas karakter untuk pemotongan hasil alat proaktif Lite ketika `lite.maxToolLength` tidak diatur. Rentang 256–1000000. Pengaturan dashboard menang atas env ini. | | `OMNI_COMPRESSION_WORKERS` | `2` | `open-sse/services/compression/compressionWorkerPool.ts` | 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` | Timeout per tugas dalam milidetik. Worker yang timeout dihentikan dan permintaan gagal secara terbuka (fail-open) tanpa perubahan. | | `OMNI_COMPRESSION_WORKER_IDLE_MS` | `60000` | `open-sse/services/compression/compressionWorkerPool.ts` | Masa hidup idle dalam milidetik sebelum worker kompresi yang tidak digunakan dihentikan. | | `OMNI_COMPRESSION_WORKER_MAX_OLD_MB` | `1024` | `open-sse/services/compression/compressionWorkerPool.ts` | Batas heap old-generation V8 dalam MB untuk setiap worker kompresi, semua mode (batas bawah `128`). Job yang melebihinya gagal secara fail-open (tidak dikompresi) alih-alih memperbesar heap gateway. | | `COMPRESSION_PIPELINE_BREAKER_ENABLED` | `false` | `open-sse/services/compression/pipelineEngineBreaker.ts` | Sakelar master circuit-breaker per-engine untuk pipeline bertumpuk T02. **Opt-in (default mati)** — saat aktif, engine yang berulang kali melempar error di berbagai permintaan akan dilewati (fail-open) selama masa cooldown; mati = perilaku lawas yang identik per byte. | | `COMPRESSION_PIPELINE_BREAKER_THRESHOLD` | `3` | `open-sse/services/compression/pipelineEngineBreaker.ts` | Jumlah kegagalan lintas-permintaan berturut-turut sebelum breaker sebuah engine terbuka. | | `COMPRESSION_PIPELINE_BREAKER_COOLDOWN_MS` | `30000` | `open-sse/services/compression/pipelineEngineBreaker.ts` | Durasi dalam milidetik engine yang terbuka tetap dilewati sebelum probe half-open. | | `COMPRESSION_CCR_RETRIEVAL_RAMP_FACTOR` | `2` | `open-sse/services/compression/engines/ccr/index.ts` | Ramp umpan-balik pengambilan CCR T08/H8: setiap pengambilan sebelumnya atas blok tersimpan menaikkan `minChars` efektifnya secara linear (konten yang sering diambil semakin sedikit dikompresi; `>=3` pengambilan = tidak pernah dikompresi). `1` menonaktifkan ramp (hanya skip biner pada ambang batas). | | `COMPRESSION_CCR_DURABLE_STORE` | `true` | `open-sse/services/compression/engines/ccr/index.ts` | Penyimpanan blok tahan lama CCR (#9061). Mencadangkan penyimpanan dalam memori dengan SQLite sehingga blok tetap bertahan dari pengeluaran LRU, TTL, restart, atau pengambilan yang mendarat di instance lain. Atur `false` untuk menyimpan blok hanya di memori. Blok di atas 512KB dan runtime cloud tetap hanya-di-memori bagaimanapun juga. | | `COMPRESSION_PREFIX_FREEZE_ENABLED` | `false` | `open-sse/services/compression/prefixFreeze.ts` | Sakelar master pembekuan prefix berbasis pengamatan penggunaan T08/H5. **Opt-in (default mati)** — saat aktif, system prompt yang teramati `>=` ambang batas diperlakukan sebagai prefix stabil yang dapat di-cache dan dilindungi dari kompresi bahkan untuk provider yang terlewat oleh heuristik cache statis (freeze hanya _melindungi_, tidak pernah mengubah). | | `COMPRESSION_PREFIX_FREEZE_THRESHOLD` | `3` | `open-sse/services/compression/prefixFreeze.ts` | Jumlah pengamatan terhadap system prompt sebelum ia diperlakukan sebagai prefix stabil yang dibekukan. | | `OMNIROUTE_BOOTSTRAPPED` | `false` | `src/app/(dashboard)/dashboard/page.tsx` | Diatur `true` oleh skrip bootstrap setelah penyiapan awal. Mengontrol visibilitas wizard penyiapan. | | `OMNIROUTE_ALLOW_BODY_PROJECT_OVERRIDE` | `0` | `open-sse/executors/antigravity.ts` | Pintu darurat: izinkan body permintaan menimpa field proyek Antigravity. | | `ANTIGRAVITY_CREDITS` | `off` | `open-sse/services/antigravityCredits.ts` | Kebijakan kredit Google One AI: `off` tidak pernah menyuntikkan kredit, `retry` menyuntikkan sekali setelah kuota 429 yang memenuhi syarat, dan `always` menyuntikkan pada permintaan pertama. | | `ANTIGRAVITY_ALLOW_SIGNATURE_BYPASS` | `0` | `open-sse/translator/request/openai-to-gemini.ts` | Izinkan translator permintaan Antigravity melewati validasi tanda tangan permintaan CLI yang ketat saat upstream menolak tanda tangan asli (mode debug/CLI-usang). Nilai non-nol mengaktifkan bypass. | | `AGY_TOKEN_FILE` | `~/.gemini/antigravity-cli/antigravity-oauth-token` | `src/app/api/providers/agy-auth/apply-local/route.ts` | Menimpa path file token Antigravity CLI (agy) untuk impor login lokal deteksi otomatis. | ### Jembatan OAuth CLI (Internal) | Variabel | Default | File Sumber | Deskripsi | | ------------------- | ---------------- | ------------------------------- | --------------------------------------------- | | `OMNIROUTE_SERVER` | deteksi otomatis | `src/lib/oauth/config/index.ts` | URL server untuk jembatan auth CLI↔OmniRoute. | | `OMNIROUTE_TOKEN` | _(belum diatur)_ | `src/lib/oauth/config/index.ts` | Token auth untuk jembatan CLI. | | `OMNIROUTE_USER_ID` | `cli` | `src/lib/oauth/config/index.ts` | ID pengguna untuk sesi jembatan CLI. | | `SERVER_URL` | _(belum diatur)_ | `src/lib/oauth/config/index.ts` | Alias lawas untuk `OMNIROUTE_SERVER`. | | `CLI_TOKEN` | _(belum diatur)_ | `src/lib/oauth/config/index.ts` | Alias lawas untuk `OMNIROUTE_TOKEN`. | | `CLI_USER_ID` | _(belum diatur)_ | `src/lib/oauth/config/index.ts` | Alias lawas untuk `OMNIROUTE_USER_ID`. | --- ## 11. Kredensial Penyedia OAuth Kredensial bawaan untuk **pengembangan localhost**. Untuk deployment jarak jauh, daftarkan kredensial Anda sendiri di konsol developer masing-masing penyedia. | Variable | Provider | Notes | | ------------------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `CLAUDE_OAUTH_CLIENT_ID` | Claude Code (Anthropic) | Klien publik — tidak memerlukan secret. | | `CLAUDE_CODE_REDIRECT_URI` | Claude Code | Menimpa redirect URI. Default: `https://platform.claude.com/oauth/code/callback` | | `CODEX_OAUTH_CLIENT_ID` | Codex / OpenAI | Klien publik. | | `GEMINI_OAUTH_CLIENT_ID` | Gemini (Google) | Memerlukan `_SECRET` yang sesuai. | | `GEMINI_OAUTH_CLIENT_SECRET` | Gemini (Google) | — | | `KIMI_CODING_OAUTH_CLIENT_ID` | Kimi Coding (Moonshot) | Klien publik. | | `MUSE_CODE_OAUTH_CLIENT_ID` | Muse Code (Meta) | Opsional, untuk menimpa client id device-flow publik Muse CLI. Biarkan kosong untuk menggunakan klien publik bawaan. | | `ANTIGRAVITY_OAUTH_CLIENT_ID` | Antigravity (Google) | Memerlukan `_SECRET` yang sesuai. | | `ANTIGRAVITY_OAUTH_CLIENT_SECRET` | Antigravity (Google) | — | | `GITHUB_OAUTH_CLIENT_ID` | GitHub Copilot | Klien publik. | | `GHE_COPILOT_OAUTH_CLIENT_ID` | GHE Copilot | Opsional, untuk menimpa OAuth client id GitHub Enterprise Copilot. Kembali ke default publik `GITHUB_OAUTH_CLIENT_ID` jika tidak diatur. | | `COPILOT_INTEGRATION_ID` | GitHub Copilot | Opsional, untuk menimpa integration ID klien GitHub Copilot yang dikirim pada header `Copilot-Integration-Id` dan `Editor-Plugin-Version`. Default-nya `copilot-developer-cli`. | | `WINDSURF_API_KEY` | Windsurf / Devin (v3.8) | API key cadangan 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) | Path kustom ke binary Devin CLI (`devin`). Diresolusi oleh `open-sse/executors/devin-cli.ts`. | | `GITLAB_DUO_OAUTH_CLIENT_ID` | GitLab Duo (v3.8) | OAuth client ID untuk GitLab Duo. Daftarkan aplikasi di `https://gitlab.com/-/profile/applications` dengan redirect URI `/callback` dan scope `api, read_user, openid, profile, email`. Kembali ke `GITLAB_OAUTH_CLIENT_ID` jika tidak diatur. | | `GITLAB_DUO_OAUTH_CLIENT_SECRET` | GitLab Duo (v3.8) | OAuth client secret untuk GitLab Duo. Opsional — alur PKCE tidak memerlukan secret. Kembali ke `GITLAB_OAUTH_CLIENT_SECRET` jika tidak diatur. | | `GITLAB_DUO_BASE_URL` | GitLab Duo (v3.8) | Menimpa base URL GitLab (GitLab self-hosted). Default-nya `https://gitlab.com`. Kembali ke `GITLAB_BASE_URL` jika tidak diatur. | | `GITLAB_BASE_URL` | GitLab Duo (v3.8) | Fallback lawas untuk `GITLAB_DUO_BASE_URL`. Digunakan ketika varian `_DUO_` tidak diatur. | | `GITLAB_OAUTH_CLIENT_ID` | GitLab Duo (v3.8) | Fallback lawas untuk `GITLAB_DUO_OAUTH_CLIENT_ID` yang dikonsumsi oleh `src/lib/oauth/constants/oauth.ts`. | | `GITLAB_OAUTH_CLIENT_SECRET` | GitLab Duo (v3.8) | Fallback lawas untuk `GITLAB_DUO_OAUTH_CLIENT_SECRET` yang dikonsumsi oleh `src/lib/oauth/constants/oauth.ts`. | | `QODER_OAUTH_CLIENT_SECRET` | Qoder | — | | `QODER_OAUTH_AUTHORIZE_URL` | Qoder | Atur untuk mengaktifkan OAuth Qoder. | | `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 workspace 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). | | `QODER_CLI_MAX_CONCURRENCY` | Qoder | Jumlah maksimal proses qodercli yang berjalan bersamaan (spawn print atau prompt ACP); permintaan tambahan mengantre secara FIFO. Tidak diatur (default) = tanpa batas. | | `QODER_CLI_QUEUE_TIMEOUT_MS` | Qoder | Berapa lama permintaan Qoder menunggu slot qodercli (hanya jika batas diatur) sebelum gagal dengan 429 `qodercli_busy` + `Retry-After`. Default `120000`. | | `QODER_CLI_TRANSPORT` | Qoder | `print` (default) menjalankan `qodercli --print` per permintaan; `acp` mempertahankan satu proses `qodercli --acp` persisten per PAT. | | `QODER_CLI_ACP_IDLE_TIMEOUT_MS` | Qoder | Transport ACP: hentikan proses qodercli persisten setelah waktu idle selama ini. Default `600000`. | | `QODER_CLI_ACP_STARTUP_TIMEOUT_MS` | Qoder | Transport ACP: batas waktu bagi qodercli untuk menjawab `initialize` ACP. Default `60000`. | | `QODER_CLI_ACP_MAX_SESSIONS_PER_PROCESS` | Qoder | Transport ACP: daur ulang proses qodercli persisten setelah sejumlah sesi ini. Default `500`. | | `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 beralih ke UUID acak. Lihat issue #2252. | | `VISION_BRIDGE_BASE_URL` | Vision Bridge guardrail | Base URL yang kompatibel dengan OpenAI untuk panggilan vision-bridge non-Anthropic. Secara default menggunakan env URL OpenAI lama atau api.openai.com. Arahkan ke self-loop `/v1` milik OmniRoute atau endpoint mana pun yang kompatibel dengan OpenAI (Gemini OpenAI-compat, OpenRouter). Issue #2232. Ketika URL tersebut adalah `/v1` milik OmniRoute sendiri, sub-permintaan describe mengirimkan `x-omniroute-admission-bypass: internal` dan mengautentikasi dengan kredensial self-loop yang diperoleh (sentinel `sk_omniroute` dalam mode lokal, atau `OMNIROUTE_API_KEY` / `ROUTER_API_KEY` — #1350) sehingga deployment dengan `REQUIRE_API_KEY=true` berfungsi. | | `VISION_BRIDGE_API_KEY` | Vision Bridge guardrail | Kunci API untuk URL di atas. Menggantikan env var OpenAI / Google per penyedia untuk panggilan vision-bridge non-Anthropic. Model Anthropic tetap menggunakan jalur kunci Anthropic khususnya. Issue #2232. | | `OMNIROUTE_VISION_BRIDGE_NEGATIVE_CACHE_MS` | Vision Bridge guardrail | Berapa lama hasil routing "tidak ada kandidat yang dapat digunakan" disimpan 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`. | > [!WARNING] > > 1. Buka [Google Cloud Console → Kredensial](https://console.cloud.google.com/apis/credentials) > 2. Buat OAuth 2.0 Client ID (tipe: "Aplikasi web") > 3. Tambahkan URL server Anda sebagai URI pengalihan yang diizinkan > 4. Ganti nilai kredensial di `.env`. --- ## 12. Penggantian User-Agent Provider Ganti header `User-Agent` yang dikirim ke setiap provider upstream. Ini di-resolve secara dinamis saat runtime oleh kelas dasar executor: ``` 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.280 (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 tool harness pihak ketiga apa adanya ke Anthropic pada kedua jalur yang menuju Anthropic (OAuth native dan CLIProxyAPI). Secara default, executor meng-alias nama tool non-Claude-Code secara deterministik (pemetaan kanonik Claude Code jika tersedia, jika tidak PascalCase) dan membalikkannya pada respons melalui `_toolNameMap`, sehingga harness dengan tool snake_case tidak ditolak sebagai klien pihak ketiga yang terfingerprint. Hanya untuk keperluan debugging. | | `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 independen dari string UA lengkap | | `GROK_CLI_CLIENT_VERSION` | `1.0.41` | Ganti `x-grok-client-version` untuk inference, sinkronisasi model, dan OAuth device-code, sekaligus User-Agent Grok CLI default untuk inference dan sinkronisasi model. Menerima SemVer dengan metadata prerelease/build opsional, hingga 128 karakter setelah pemangkasan spasi di awal dan akhir. Nilai yang tidak diatur, kosong, tidak valid, atau mengandung baris baru akan menggunakan pin bawaan. Penggantian User-Agent inference lengkap yang sudah ada tetap diprioritaskan. | | `CLAUDE_CODE_CLIENT_VERSION` | `2.1.280` | Ganti versi Claude Code yang diiklankan secara independen dari `CLAUDE_USER_AGENT`. Anthropic membatasi sebagian model berdasarkan nilai ini (#12417). | | `CLAUDE_CODE_CLIENT_BUILD_REVISION` | `1e2` | Ganti akhiran 3 karakter yang ditambahkan OmniRoute ke `cc_version=` pada blok billing Claude. Naikkan bersamaan dengan `CLAUDE_CODE_CLIENT_VERSION` — hanya mem-pin versi akan mengiklankan pasangan `version.revision` yang tidak pernah dikeluarkan oleh biner asli mana pun. | | `GITHUB_COPILOT_CLI_VERSION` | `1.0.91` | Ganti versi Copilot CLI yang diiklankan secara independen 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` device-code sosial Kiro (id publik) | | `KIRO_VERIFY_FULL_CRC` | `false` | Opt-in: validasi CRC pesan penuh per-frame pada event stream Kiro (untuk debug stream yang korup) | | `KIRO_CREDIT_PRICE_USD` | `0.02` | USD per kredit Kiro; mengonversi kredit `meteringEvent` menjadi biaya per-permintaan yang tepat | | `KIRO_REQUIRE_CREDITS` | `false` | Gagalkan respons Kiro yang tidak melaporkan metering kredit, alih-alih mencatatnya sebagai tidak ditagih | | `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 provider **mana pun** menggunakan pola `{PROVIDER_ID}_USER_AGENT`. Executor secara dinamis membangun nama env var 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 dalam **milidetik**. Resolusi terpusat di `src/shared/utils/runtimeTimeouts.ts`. ### Hierarki Timeout ``` REQUEST_TIMEOUT_MS (override global) ├─→ FETCH_TIMEOUT_MS (panggilan provider upstream, default: 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, default: 10000) │ ├── RESPONSES_FIRST_BYTE_TIMEOUT_MS (independen, default: 15000) │ ├── OPENCODE_RESPONSES_HEADERS_WAIT_MS (independen, default: 0 = nonaktif, disarankan: 30000) │ ├── OPENCODE_RESPONSES_HEADERS_WAIT_MAX_ROTATIONS (independen, default: 2) │ ├── FETCH_CONNECT_TIMEOUT_MS (independen, default: 30000) │ └── FETCH_KEEPALIVE_TIMEOUT_MS (independen, default: 4000) ├─→ STREAM_IDLE_TIMEOUT_MS (mewarisi dari REQUEST_TIMEOUT_MS, default: 600000) ├─→ STREAM_ACTIVE_TIMEOUT_MS (independen, default: 1260000; 0 menonaktifkan) ├─→ STREAM_READINESS_TIMEOUT_MS (mewarisi dari REQUEST_TIMEOUT_MS, default: 80000) ├─→ STREAM_READINESS_MAX_TIMEOUT_MS (membatasi perpanjangan kesiapan adaptif, default: 180000) └─→ API_BRIDGE_PROXY_TIMEOUT_MS (mewarisi dari REQUEST_TIMEOUT_MS, default: 30000) ├─→ API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS (turunan, default: 300000) ├── API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS (default: 60000) ├── API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS (default: 5000) └── API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS (default: 0 = dinonaktifkan) ``` | Variabel | Default | Deskripsi | | ----------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `REQUEST_TIMEOUT_MS` | _(belum diatur)_ | Shortcut global — menimpa default `FETCH_TIMEOUT_MS` dan `STREAM_IDLE_TIMEOUT_MS`. | | `FETCH_TIMEOUT_MS` | `600000` | Timeout total permintaan HTTP untuk panggilan provider upstream. | | `STREAM_IDLE_TIMEOUT_MS` | `600000` | Jeda hening maksimum antara byte mentah upstream sebelum membatalkan. Model extended-thinking jarang berhenti >90 detik. | | `STREAM_ACTIVE_TIMEOUT_MS` | `1260000` | Masa hidup total maksimum stream SSE aktif; tidak pernah direset saat ada byte upstream dan independen dari `REQUEST_TIMEOUT_MS`. Diturunkan dari `timeoutMs` per-model terbesar di registry (1200000, Codex) ditambah margin 60000, sehingga model yang diizinkan berjalan dengan anggaran penuhnya tidak pernah dimatikan di tengah jawaban. Atur ke `0` untuk menonaktifkan. | | `OMNIROUTE_SSE_COMMENTS` | _(dinonaktifkan)_ | Apakah OmniRoute boleh mengirimkan baris komentar SSE `:` (mis. heartbeat `: keepalive` dan trailer metadata `x-omniroute-*`). Dinonaktifkan secara default (#10524) karena klien ketat yang kompatibel dengan OpenAI melakukan JSON.parse pada setiap baris SSE dan crash pada komentar `:`; heartbeat `data:` tidak terpengaruh. Atur `on`/`true`/`1`/`yes` untuk mengaktifkan kembali. Digunakan oleh `open-sse/utils/sseHeartbeat.ts`. | | `SSE_COALESCE_MS` | `0` (nonaktif) | Opt-in: menggabungkan event `content_block_delta` Claude yang berurutan (indeks blok dan tipe delta yang sama) yang dikirim ke klien Claude, dengan flush setidaknya setiap N ms. Lossless; `signature_delta` dan event batas tidak pernah digabungkan. Berlaku untuk setiap tipe delta kecuali variabel per-tipe di bawah diatur. Digunakan oleh `open-sse/utils/sseDeltaCoalesce.ts`. | | `SSE_COALESCE_THINKING_MS` | `0` (nonaktif) | Override per-tipe dari `SSE_COALESCE_MS` untuk `thinking_delta`. | | `SSE_COALESCE_TEXT_MS` | `0` (nonaktif) | Override per-tipe dari `SSE_COALESCE_MS` untuk `text_delta`. | | `SSE_COALESCE_INPUT_JSON_MS` | `0` (nonaktif) | Override per-tipe dari `SSE_COALESCE_MS` untuk `input_json_delta`. | | `SSE_FRAME_COALESCE_MS` | `0` (nonaktif) | Opt-in: mengelompokkan frame SSE yang diteruskan dalam N ms menjadi satu penulisan ke klien. Frame pertama dan frame terminal (`[DONE]`, `message_stop`, `error`, `response.completed`/`failed`/`incomplete`) tidak pernah ditunda; dengan batching aktif, ITL mengukur jeda antar batch. Digunakan oleh `open-sse/utils/sseOutputSink.ts`. | | `SSE_STALL_WATCHDOG` | `timer` | Implementasi watchdog byte-stall untuk respons streaming. `timer` memasang ulang satu timer per chunk upstream (menyala tepat pada anggaran stall); `interval` mempertahankan satu pemeriksaan per stream dengan periode `clamp(budget/4, 1s, 5s)`, sehingga stall menyala dalam anggaran + periode. Digunakan oleh `open-sse/utils/streamStallWatchdog.ts`. | | `STREAM_READINESS_TIMEOUT_MS` | `80000` | Waktu untuk menerima event SSE non-ping pertama. Mewarisi `REQUEST_TIMEOUT_MS` jika diatur. | | `STREAM_READINESS_MAX_TIMEOUT_MS` | `180000` | Jendela readiness event pertama adaptif maksimum untuk permintaan streaming yang besar, padat tool, atau reasoning tinggi. | | `OMNIROUTE_AGENT_GOAL_POLICY_ENABLED` | `true` | Kill-switch untuk heuristik `/goal`. Atur `false`/`0`/`off` untuk menonaktifkan deteksi sepenuhnya — timeout readiness dan pemulihan stream tidak pernah ditingkatkan oleh body/header permintaan, mengurangi amplifikasi timeout yang dikendalikan klien. | | `OMNIROUTE_AGENT_GOAL_READINESS_MAX_TIMEOUT_MS` | `600000` | Jendela readiness event pertama maksimum untuk run agen `/goal` yang terdeteksi atau permintaan yang dipaksakan dengan `x-omniroute-agent-goal`. | | `OMNIROUTE_AGENT_GOAL_STREAM_RECOVERY` | `true` | Mengaktifkan pemulihan stream dini secara otomatis untuk run agen `/goal` yang terdeteksi. Atur `false`/`0`/`off` untuk menonaktifkan opt-in khusus goal. Ini hanya dapat MENAMBAHKAN pemulihan di atas default operator — tidak pernah menimpa opt-out eksplisit dari `STREAM_RECOVERY_ENABLED`/pengaturan DB. | | `OMNIROUTE_CODEX_DROP_NONSTANDARD_EVENTS` | `true` | Menghapus event SSE `codex.*` non-standar (mis. `codex.rate_limits`) yang merusak `responses.stream()` OpenAI SDK dengan 502. Default AKTIF (#11014). Atur `0`/`false`/`no`/`off` untuk meneruskannya. | | `OMNIROUTE_CODEX_APPSERVER_WS` | _(belum diatur)_ | Transport app-server Codex opt-in. Endpoint WebSocket (`ws://`/`wss://`) dari sidecar `codex app-server` lokal. Jika diatur bersama dengan token, permintaan Codex dirutekan melalui JSON-RPC ke sidecar alih-alih HTTP Responses API. Juga dapat diatur per-koneksi melalui `providerSpecificData.codexAppServerUrl`. Digunakan oleh `open-sse/executors/codex/appServerConfig.ts`. | | `OMNIROUTE_CODEX_APPSERVER_WS_TOKEN` | _(belum diatur)_ | Token capability/bearer inline yang diberikan ke app-server. Override per-koneksi: `providerSpecificData.codexAppServerToken`. | | `OMNIROUTE_CODEX_APPSERVER_WS_TOKEN_FILE` | _(tidak diatur)_ | Jalur ke file yang menyimpan token capability app-server (dari `codex app-server --ws-token-file`). Digunakan ketika `OMNIROUTE_CODEX_APPSERVER_WS_TOKEN` tidak diatur. Override per-koneksi: `providerSpecificData.codexAppServerTokenFile`. | | `OMNIROUTE_CODEX_APPSERVER_CWD` | `/tmp` | Direktori kerja tempat turn app-server dijalankan. Override per-koneksi: `providerSpecificData.codexAppServerCwd`. | | `OMNIROUTE_CODEX_APPSERVER_APPROVAL` | _(tidak diatur)_ | Kebijakan persetujuan yang diteruskan ke turn app-server (mis. `never`, `on-request`). Override per-koneksi: `providerSpecificData.codexAppServerApprovalPolicy`. | | `OMNIROUTE_CODEX_APPSERVER_SANDBOX` | _(tidak diatur)_ | Kebijakan sandbox yang diteruskan ke turn app-server (mis. `read-only`, `workspace-write`, `danger-full-access`). Jika tidak diatur, executor secara default menggunakan `workspace-write` (diperketat; sebelumnya `danger-full-access`). Override per-koneksi: `providerSpecificData.codexAppServerSandbox`. | | `OMNIROUTE_CODEX_APPSERVER_AUTO_APPROVE` | `false` | Menyetujui secara otomatis prompt persetujuan milik app-server sendiri (eksekusi perintah/file/izin pada host). Nonaktif secara default — prompt ditolak secara otomatis; pemanggilan tool harness tidak terpengaruh (mereka melewati passthrough `item/tool/call` yang terpisah). Menerima `true`/`1`/`yes`. Override per-koneksi: `providerSpecificData.codexAppServerAutoApprove`. | | `FETCH_HEADERS_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Waktu untuk menerima header respons. | | `OMNIROUTE_FETCH_START_TIMEOUT_CAP_MS` | `110000` | Waktu tunggu maksimum untuk header respons pada permintaan streaming (ms). `0` menonaktifkan batas ini; `fetchStartTimeoutCapMs` provider yang eksplisit didahulukan. | | `OMNIROUTE_DIRECT_HEADERS_TIMEOUT_MS` | `30000` (30s) | Waktu tunggu maksimum awal respons (ms) untuk setiap percobaan langsung tanpa proxy. Timeout mencoba ulang sekali pada socket baru; atur `0` untuk menonaktifkan batas dan mempertahankan perilaku sebelumnya. | | `OMNIROUTE_LOCAL_DIRECT_HEADERS_TIMEOUT_MS` | `300000` (5 menit) | Batas bawah awal respons (ms) untuk percobaan langsung tanpa proxy yang host targetnya privat/LAN/loopback (misalnya `localhost`, `host.docker.internal`, `192.168.x.x`), sehingga cold start Ollama native tidak terpotong oleh default 30s di atas. Berfungsi sebagai batas bawah: waktu tunggu efektif adalah nilai yang lebih besar antara nilai ini dan `OMNIROUTE_DIRECT_HEADERS_TIMEOUT_MS`; `0` atau nilai tidak valid menghapus batas bawah lokal. Host remote tidak terpengaruh. | | `OMNIROUTE_DIRECT_RESPONSE_RETRY_TIMEOUT_MS` | `600000` (10 menit) | Batas atas (ms) untuk percobaan ULANG pada socket baru setelah timeout awal respons pada percobaan pooled di atas (#13703). Hanya berlaku ketika pemanggil telah melampirkan sinyal deadline-nya sendiri (kaskade koneksi/model/provider/`FETCH_TIMEOUT_MS` yang teresolusi); sinyal tersebut adalah batas sebenarnya dan aktif lebih dulu di jalur yang dimaksudkan, sehingga ini merupakan pengaman cadangan yang longgar, bukan batas tetap — tanpanya, percobaan ulang menggunakan kembali jendela `OMNIROUTE_DIRECT_HEADERS_TIMEOUT_MS` pendek yang identik dengan percobaan pooled dan menghasilkan 504 pada model reasoning sehat dengan TTFB lambat. Tidak pernah diperbolehkan di bawah batas bawah tetap di atas; ketika pemanggil tidak memberikan sinyal deadline sama sekali, percobaan ulang mempertahankan batas bawah tetap tanpa perubahan. | | `FETCH_BODY_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Waktu untuk menerima seluruh body respons. | | `FETCH_CONNECT_TIMEOUT_MS` | `30000` | Timeout pembentukan koneksi TCP. | | `FETCH_KEEPALIVE_TIMEOUT_MS` | `4000` | Timeout idle socket keep-alive. | | `TLS_CLIENT_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Timeout proxy fingerprint TLS (wreq-js). | | `TLS_FIRST_BYTE_WATCHDOG_MS` | `10000` | Membatasi time-to-first-byte khusus pada body transport fingerprint-TLS wreq-js; `TLS_CLIENT_TIMEOUT_MS` saja tidak dapat menangkap body yang macet karena ia selesai segera setelah header tiba (#12656). Timeout membatalkan pembaca wreq dan kembali ke dispatcher langsung/proxy; `0` menonaktifkan watchdog. | | `RESPONSES_FIRST_BYTE_TIMEOUT_MS` | `15000` | Hanya executor OpenCode, dan hanya saat feature flag `OPENCODE_RESPONSES_STALL_ROTATION` aktif (default nonaktif): membatasi waktu tunggu byte body pertama dari balasan Responses yang di-stream setelah headernya (#13484). Stream Responses dibuka dengan `response.created`, sehingga keheningan melewati jendela ini adalah kemacetan: akun didinginkan dan permintaan berotasi ke akun berikutnya sekali; kemacetan kedua gagal dengan cepat. `0` menonaktifkan pengaman bahkan dengan flag aktif. | | `OPENCODE_RESPONSES_HEADERS_WAIT_MS` | `0` (= nonaktif) | Hanya executor OpenCode: membatasi waktu tunggu header respons upstream pada panggilan Responses yang di-stream ketika akun lain masih tersedia — permintaan yang mengantre berhenti menunggu dan berpindah alih-alih menahan seluruh jendela header. Hanya panggilan Responses yang di-stream yang terpengaruh (stream Responses dibuka dengan `response.created`, sehingga keheningan di sana adalah antrean, bukan generasi); chat completions dan panggilan non-stream tidak tersentuh, dan jendela ini hanya memperpendek batas atas fetch-start efektif, tidak pernah memperpanjangnya. Nilai yang disarankan saat mengaktifkan: `30000`. `0` menonaktifkan. | | `OPENCODE_RESPONSES_HEADERS_WAIT_MAX_ROTATIONS` | `2` | Hanya executor OpenCode: berapa kali per permintaan batas tunggu-header di atas boleh berpindah ke akun berikutnya. Akun terakhir yang tersisa selalu mempertahankan jendela header penuh. | | `OPENCODE_PARK_AND_RESUME` | `false` | Hanya executor OpenCode: parkir permintaan dengan heartbeat setelah 429 transien berulang (atau penanda pool-strain yang baru), lalu putar ulang satu leg terbatas hingga 3 akun berurutan alih-alih menyebar ke seluruh fleet (#13924). Nonaktif secara default: setiap 429 berotasi ke akun berikutnya persis seperti sebelumnya. | | `OPENCODE_PARK_REPLAY_SERVE_SETASIDE` | `false` | Hanya executor OpenCode: ketika setiap akun siap-cooldown dalam leg replay park-and-resume disisihkan oleh memori penolakan-proxy, tetap layani mereka alih-alih tidak memutar ulang apa pun (#14851, tindak lanjut dari #14750). Nonaktif secara default: leg replay kosong dalam kasus tersebut, seperti sebelum #14750. | | `STREAM_READINESS_STALL_RETRY` | `false` | Hanya chat streaming: ketika body upstream pertama macet sebelum menghasilkan event yang dapat digunakan, lakukan satu upaya kedua terbatas melalui jalur routing yang sama dengan anggaran kesiapan yang sama dan tanpa penalti akun. Nonaktif secara default: body pertama yang macet menggagalkan permintaan tanpa percobaan ulang. | | `OPENCODE_POOL_RESELECT` | `false` | Hanya executor OpenCode: setelah 429 dari provider ber-bucket egress pada akun tanpa proxy dalam konteks pool ambient, minta connection pool anggota lain untuk upaya berikutnya alih-alih mencoba ulang alamat egress yang sama. Mengurutkan, tidak pernah mengecualikan: pool yang habis mempertahankan perilaku saat ini. Nonaktif secara default: setiap 429 berotasi ke akun berikutnya persis seperti sebelumnya. | | `OPENCODE_POOL_STRAIN_MARKER_PATH` | _(tidak disetel)_ | Hanya executor OpenCode: timpa path penanda pool-strain yang dibaca sebelum parkir (`{since, reason, ttl_s}`, default `/tmp/opencode-pool-strain.json`, #13924). Penanda baru memarkir tanpa menghitung ulang; tidak ada atau usang akan kembali ke penghitung burst. | | `API_BRIDGE_PROXY_TIMEOUT_MS` | `30000` | Timeout hop proxy untuk permintaan bridge `/v1`. | | `FIRECRAWL_BASE_URL` | `https://api.firecrawl.dev` | Arahkan executor web-fetch Firecrawl ke instance self-hosted (API key opsional di luar cloud). | | `FIRECRAWL_TIMEOUT_MS` | `30000` | Timeout per permintaan untuk executor web-fetch Firecrawl. | | `TAVILY_BASE_URL` | _(tidak disetel)_ | Base URL untuk pengambil kuota `/usage` Tavily (Provider Limits); diabaikan ketika menunjuk ke `api.tavily.com`. Jika tidak disetel, kembali ke base URL koneksi. | | `API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS` | `300000` | Timeout permintaan server keseluruhan untuk bridge. | | `API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS` | `60000` | Waktu untuk mengirim header respons melalui bridge. | | `API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS` | `5000` | Timeout idle keep-alive bridge. | | `API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS` | `0` | Timeout socket mentah (0 = dinonaktifkan). | | `SHUTDOWN_TIMEOUT_MS` | `30000` | Masa tenggang pada SIGTERM/SIGINT sebelum force-exit. | | `OMNIROUTE_DEFAULT_FETCH_TIMEOUT_MS` | `120000` | Fallback yang digunakan oleh `src/shared/utils/fetchTimeout.ts` ketika `FETCH_TIMEOUT_MS` tidak disetel. | | `OMNIROUTE_PROVIDER_PROBE_TIMEOUT_MS` | `8000` | Timeout (ms) untuk preset `validationRead` dan `modelsProbe` di `src/shared/network/safeOutboundFetch.ts`. Naikkan untuk endpoint lambat (Cerebras, Cloudflare AI, Groq) untuk mencegah flapping antara aktif/error di dashboard. Kembali ke 8000ms untuk nilai tidak valid (<1000) atau non-numerik. | | `OMNIROUTE_RELAY_FETCH_TIMEOUT_MS` | `25000` | Timeout fetch khusus relay di `open-sse/utils/proxyFetch.ts` (#9158). Relay yang hang harus gagal sebelum timeout klien/agen (~30s) agar pemanggil melihat kegagalan khusus relay alih-alih timeout upstream generik. Dibatasi pada `29000` sehingga selalu terpicu lebih dulu. | | `OMNIROUTE_RETRY_BACKOFF_MS` | `10` | Backoff percobaan ulang bersama untuk jalur retry-sekali direct/relay/proxy di `open-sse/utils/proxyFetch.ts` (#9158). `0` = coba ulang segera. | | `OMNIROUTE_CLAUDE_TLS_TIMEOUT_MS` | `60000` | Timeout permintaan native wreq-js (`claudeTlsClient.ts`). | | `OMNIROUTE_CLAUDE_TLS_GRACE_MS` | `10000` | Tenggang hard-deadline JS absolut yang ditambahkan di atas timeout native. | | `OMNIROUTE_PPLX_TLS_TIMEOUT_MS` | `30000` | Timeout permintaan native wreq-js (`perplexityTlsClient.ts`). | | `OMNIROUTE_PPLX_TLS_GRACE_MS` | `10000` | Tambahan tenggang hard-deadline JS absolut di atas timeout native. | | `OMNIROUTE_PPLX_SEARCH_HINT` | `0` (off) | Menambahkan "You have built-in web search. Answer questions directly using search results." ke pesan sistem pemanggil (`perplexity-web/protocol.ts`). Nonaktif secara default — Perplexity tetap melakukan pencarian, dan kalimat tersebut bocor ke dalam balasan sebagai meta-komentar bagi klien coding. Setel `1`/`true`/`yes`/`on` untuk mengaktifkan kembali. | | `OMNIROUTE_GROK_TLS_TIMEOUT_MS` | `60000` | Timeout permintaan wreq-js native (`grokTlsClient.ts`). | | `OMNIROUTE_GROK_TLS_GRACE_MS` | `10000` | Tambahan tenggang hard-deadline JS absolut di atas timeout native. | | `OMNIROUTE_NOTION_TLS_TIMEOUT_MS` | `30000` | Timeout permintaan wreq-js native (`notionTlsClient.ts`); `notion-web` menaikkannya per permintaan menjadi `180000` untuk respons yang panjang. | | `OMNIROUTE_NOTION_TLS_GRACE_MS` | `10000` | Tambahan tenggang hard-deadline JS absolut di atas timeout native. | | `OMNIROUTE_BROWSER_POOL` | `on` | Pool browser Playwright bersama untuk chat web-cookie berbasis browser (`browserPool.ts`); setel `off` untuk menonaktifkan. | | `OBSCURA_BIN` | `auto-detect` | Jalur ke binary `obscura` yang digunakan sebagai mesin utama oleh pool browser dan eksekutor Cloudflare Playground (`open-sse/services/obscura.ts`); terdeteksi otomatis dari PATH sistem jika tidak disetel. | | `OBSCURA_CDP_ENDPOINT` | _(tidak disetel)_ | Mengarah ke Obscura yang sudah berjalan (`http://host:port`) alih-alih menjalankan yang baru; modul tidak memiliki proses tersebut (`open-sse/services/obscura.ts`). | | `OBSCURA_PORT` | `random free port` | Port eksplisit untuk `obscura serve` yang dijalankan; port kosong dipilih secara otomatis jika tidak disetel (`open-sse/services/obscura.ts`). | | `WEB_COOKIE_USE_BROWSER` | `0` | Mengalihkan permintaan chat web-cookie ke 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 login browser interaktif Adobe Firefly (`adobeFireflyBrowserLogin.ts`); menimpa deteksi otomatis per-OS. | | `OMNIROUTE_STANDALONE_DIR` | _.build/ standalone output_ | Timpaan waktu-build untuk direktori output standalone yang dikonsumsi oleh langkah kolokasi pasca-build (`scripts/build/colocate-standalone.mjs`); perkakas build, bukan runtime. | Percobaan target combo mewarisi timeout permintaan upstream yang telah diresolusi (`FETCH_TIMEOUT_MS`, atau `REQUEST_TIMEOUT_MS` saat ia menyediakan default fetch). Setel `targetTimeoutMs` pada combo, default combo, atau timpaan provider hanya untuk mempercepat fallback combo; nilai di atas timeout upstream saat ini dibatasi hingga timeout upstream. `comboTimeoutMs` adalah anggaran wall-clock seluruh combo yang terpisah di seluruh target failover. Biarkan tidak disetel atau `0` untuk mempertahankan iterasi tanpa batas (penghentian hang hardcoded 10 menit di `comboPredicates.ts` tetap berlaku). Nilai positif menggantikan jaring pengaman tersebut untuk combo. Jaga `comboTimeoutMs` lebih lama dari `targetTimeoutMs` agar failover masih memiliki waktu setelah target pertama yang lambat. ### Ambang Batas Circuit Breaker Penyetelan circuit breaker tingkat provider. Nilai default mencerminkan nilai berskala yang digunakan sejak v3.6 untuk 500+ koneksi. | Variabel | Default | Berkas Sumber | Deskripsi | | ------------------------------------------------------------- | --------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OMNIROUTE_CIRCUIT_BREAKER_OAUTH_THRESHOLD` | `8` | `open-sse/config/constants.ts` | Ambang kegagalan berurutan untuk provider OAuth sebelum breaker terpicu. | | `OMNIROUTE_CIRCUIT_BREAKER_OAUTH_RESET_MS` | `60000` | `open-sse/config/constants.ts` | Jendela reset (ms) untuk breaker provider OAuth. | | `OMNIROUTE_CIRCUIT_BREAKER_API_KEY_THRESHOLD` | `12` | `open-sse/config/constants.ts` | Ambang kegagalan berurutan untuk provider API-key. | | `OMNIROUTE_CIRCUIT_BREAKER_API_KEY_RESET_MS` | `30000` | `open-sse/config/constants.ts` | Jendela reset (ms) untuk breaker provider API-key. | | `OMNIROUTE_CIRCUIT_BREAKER_LOCAL_THRESHOLD` | `2` | `open-sse/config/constants.ts` | Ambang kegagalan berurutan untuk provider lokal (Ollama, LM Studio, ...). | | `OMNIROUTE_CIRCUIT_BREAKER_LOCAL_RESET_MS` | `15000` | `open-sse/config/constants.ts` | Jendela reset (ms) untuk breaker provider lokal. | | `OMNIROUTE_PROVIDER_BREAKER_OAUTH_FAILURE_THRESHOLD` | `10` | `open-sse/config/constants.ts` | Breaker tingkat provider: kegagalan dalam jendela sebelum seluruh provider OAuth memasuki cooldown. | | `OMNIROUTE_PROVIDER_BREAKER_OAUTH_FAILURE_WINDOW_MS` | `900000` | `open-sse/config/constants.ts` | Breaker tingkat provider: jendela hitung kegagalan bergulir (ms) untuk provider OAuth. | | `OMNIROUTE_PROVIDER_BREAKER_OAUTH_COOLDOWN_MS` | `300000` | `open-sse/config/constants.ts` | Breaker tingkat provider: cooldown (ms) setelah ambang provider OAuth tercapai. | | `OMNIROUTE_PROVIDER_BREAKER_OAUTH_DEGRADATION_THRESHOLD` | `5` | `open-sse/config/constants.ts` | Provider OAuth memasuki status DEGRADED pada jumlah kegagalan ini. | | `OMNIROUTE_PROVIDER_BREAKER_OAUTH_MAX_BACKOFF_MULTIPLIER` | `8` | `open-sse/config/constants.ts` | Pengali eskalasi maksimum resetTimeout untuk provider OAuth. | | `OMNIROUTE_PROVIDER_BREAKER_OAUTH_BACKOFF_ESCALATION_COUNT` | `2` | `open-sse/config/constants.ts` | Provider OAuth dieskalasi setelah sejumlah siklus open ini. | | `OMNIROUTE_PROVIDER_BREAKER_API_KEY_FAILURE_THRESHOLD` | `15` | `open-sse/config/constants.ts` | Breaker tingkat provider: kegagalan dalam jendela sebelum seluruh provider API-key memasuki cooldown. | | `OMNIROUTE_PROVIDER_BREAKER_API_KEY_FAILURE_WINDOW_MS` | `1800000` | `open-sse/config/constants.ts` | Breaker tingkat provider: jendela hitung kegagalan bergulir (ms) untuk provider API-key. | | `OMNIROUTE_PROVIDER_BREAKER_API_KEY_COOLDOWN_MS` | `600000` | `open-sse/config/constants.ts` | Breaker tingkat provider: cooldown (ms) setelah ambang provider API-key tercapai. | | `OMNIROUTE_PROVIDER_BREAKER_API_KEY_DEGRADATION_THRESHOLD` | `7` | `open-sse/config/constants.ts` | Provider API-key memasuki status DEGRADED pada jumlah kegagalan ini. | | `OMNIROUTE_PROVIDER_BREAKER_API_KEY_MAX_BACKOFF_MULTIPLIER` | `4` | `open-sse/config/constants.ts` | Pengali eskalasi maksimum resetTimeout untuk provider API-key. | | `OMNIROUTE_PROVIDER_BREAKER_API_KEY_BACKOFF_ESCALATION_COUNT` | `3` | `open-sse/config/constants.ts` | Provider API-key dieskalasi setelah sejumlah siklus open ini. | | `OMNIROUTE_PROVIDER_BREAKER_LOCAL_FAILURE_THRESHOLD` | `2` | `open-sse/config/constants.ts` | Breaker tingkat provider: kegagalan sebelum seluruh provider lokal memasuki cooldown. | | `OMNIROUTE_PROVIDER_BREAKER_LOCAL_FAILURE_WINDOW_MS` | `300000` | `open-sse/config/constants.ts` | Breaker tingkat provider: jendela hitung kegagalan bergulir (ms) untuk provider lokal. | | `OMNIROUTE_PROVIDER_BREAKER_LOCAL_COOLDOWN_MS` | `60000` | `open-sse/config/constants.ts` | Breaker tingkat provider: cooldown (ms) setelah ambang provider lokal tercapai. | | `OMNIROUTE_API_KEY_COOLDOWN_MS` | `60000` | `open-sse/services/apiKeyRotator.ts` | Cooldown per kunci (ms) yang diterapkan oleh rotasi API-key multi-kunci ketika respons 429 dari upstream tidak membawa `Retry-After` (#14573). Nilai non-positif atau non-numerik akan kembali ke default. | | `PIN_DROP_BACKOFF_LEVEL` | `2` | `open-sse/services/combo.ts` | Kedalaman backoff di mana provider dari pin context-cache dianggap tidak sehat secara permanen dan pin dihapus untuk failover. | | `PIN_DROP_GRACE_MS` | `20000` | `open-sse/services/combo.ts` | Jendela anti-flap (ms) yang mentoleransi cooldown sementara yang singkat sebelum menghapus pin context-cache. | ### Skenario | Skenario | Konfigurasi | | ------------------------------------- | ----------------------------------------------------- | | **Pembuatan kode berdurasi panjang** | `REQUEST_TIMEOUT_MS=900000` (15 menit) | | **Membatasi total masa aktif stream** | `STREAM_ACTIVE_TIMEOUT_MS=1260000` (21 menit) | | **Fast-fail untuk API produksi** | `API_BRIDGE_PROXY_TIMEOUT_MS=10000` | | **Model extended thinking** | `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 | Nilai 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. Menerima: `50M`, `1G`, `512K`, atau byte biasa. | | `APP_LOG_RETENTION_DAYS` | `7` | Jumlah hari untuk menyimpan file log aplikasi yang dirotasi. | | `APP_LOG_MAX_FILES` | `20` | Jumlah maksimum cadangan file log yang dirotasi. | | `CALL_LOG_RETENTION_DAYS` | `7` | Jumlah hari untuk menyimpan entri log permintaan/panggilan dalam basis data. | | `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 diatur)_ | Paksa logging permintaan terperinci aktif atau nonaktif, menggantikan pengaturan dasbor. | | `MAX_PENDING_REQUEST_AGE_MS` | `3600000` (1 jam) | Usia maksimum untuk entri log permintaan aktif yatim sebelum pembersihan dalam memori. | | `CALL_LOG_PIPELINE_CAPTURE_STREAM_CHUNKS` | `false` | Simpan potongan aliran dalam artefak pipeline saat `call_log_pipeline_enabled=true`. Bersifat opsional (`true`) — nonaktif 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 dasbor/basis data tetap menyimpan detail lengkap. | | `PROXY_LOG_FIRST_CHUNK_TIMING` | `false` | Atur ke `"true"` atau `"1"` untuk mencatat `first_chunk_ms` (dari awal pengiriman hingga byte isi berguna pertama) pada baris log proxy. Membungkus setiap isi upstream dalam aliran passthrough lazy dan memperbarui baris setelah byte tiba; nonaktif secara default agar respons diteruskan tanpa perubahan. | | `APP_LOG_ROTATION_CHECK_INTERVAL_MS` | `60000` (1 mnt) | 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 yang dipertahankan dari bagian akhir saat payload log chat dipotong. | | `CHAT_LOG_MAX_DEPTH` | `6` | Kedalaman bersarang maksimum sebelum payload log chat dipotong. | | `CHAT_LOG_MAX_OBJECT_KEYS` | `80` | Jumlah maksimum kunci objek yang dipertahankan dalam payload log chat (0 = tidak terbatas). | | `CHAT_LOG_MAX_BODY_KB` | `1024` | Ukuran keseluruhan isi permintaan/respons (KB) sebelum diganti dengan ringkasan singkat alih-alih klon lengkap. Tingkatkan nilai ini jika percakapan agentik yang panjang menampilkan placeholder alih-alih pesan sebenarnya di dasbor. | | `CHAT_DEBUG_FILE` | `false` | Jika true, `serializeArtifactForStorage` melewati pemotongan berdasarkan ukuran. Hanya untuk debugging. | --- ## 17. Optimasi Memori | Variabel | Bawaan | Deskripsi | | ----------------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `OMNIROUTE_MEMORY_MB` | _otomatis_ (bare metal); **`1024` dalam image Docker** | Batas heap V8 yang **direkomendasikan** untuk Docker/standalone (MB). Jika tidak diatur, dikalibrasi secara dinamis (~35% dari RAM sistem, dibatasi ke `[512, 4096]`); `512` hanya batas bawah ketika total memori tidak dapat dibaca. Pada `run-standalone.mjs` (Docker CMD), nilai **eksplisit** ditambahkan sebagai `--max-old-space-size` dan **menang** atas flag heap NODE_OPTIONS yang bertentangan (flag terakhir V8). `omniroute serve` tetap mengutamakan heap NODE_OPTIONS yang sudah ada (#5238). Jangan mengatur keduanya ke angka yang berbeda — proses akan mencatat peringatan yang menyebutkan kedua nilai dan pemenangnya. **Image Docker resmi selalu mengatur `1024`, sehingga kalibrasi tidak pernah dijalankan di sana.** Coding-agent `/v1/responses` memerlukan `8192`–`12288` ditambah ruang kepala cgroup — lihat [Panduan Docker — RAM runtime](../guides/DOCKER_GUIDE.md#runtime-ram-for-coding-agents). | | `OMNIROUTE_RSS_PRESSURE_MB` | _otomatis_ (`max(3072, 2 × OMNIROUTE_MEMORY_MB)`; nonaktif ketika `OMNIROUTE_MEMORY_MB` tidak diatur) | `open-sse/utils/resourcePressure.ts` | Pengaman RSS proses absolut (MB) untuk memori native/eksternal yang tidak dapat dilihat oleh `heapUsed` V8; di atasnya, permintaan baru mendapatkan 503 `resource_pressure`. RSS jarang turun setelah lonjakan, jadi pasangkan dengan `OMNIROUTE_PRESSURE_SELF_RESTART`. | | `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 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` | Jumlah root korpus lokal yang mempertahankan indeks dalam memori secara bersamaan (`src/lib/localCorpus/configured.ts`). LRU: pada batas tersebut, indeks root yang paling lama tidak digunakan dikeluarkan dan dibangun ulang pada kueri berikutnya. Dibatasi minimal `1`; nilai non-numerik akan kembali ke nilai bawaan. | | `STREAM_HISTORY_MAX` | `50` | Jumlah maksimum peristiwa stream terbaru dalam buffer tampilan langsung Dashboard. | | `CONTEXT_LENGTH_DEFAULT` | _(tidak diatur)_ | Penggantian panjang konteks global (token) untuk setiap provider yang tidak memiliki variabel `CONTEXT_LENGTH_`. Jika diatur, nilai ini **menggantikan** katalog, penggantian dashboard, dan nilai registry untuk provider tersebut; jika tidak diatur, OmniRoute menggunakan rantai bawaannya, yang pilihan terakhirnya adalah `128000`. Lihat [Panjang konteks per provider](#per-provider-context-length-context_length_provider). | | `USAGE_TOKEN_BUFFER` | `100` | Ruang kepala token tambahan yang dicadangkan saat melacak kuota penggunaan. | ### Panjang konteks per provider (`CONTEXT_LENGTH_`) `open-sse/services/contextManager.ts` (`getEnvOverride()` / `resolveTokenLimit()`) juga membaca bentuk **per provider** yang namanya dibangun dari ID provider saat runtime, sehingga tidak dapat dicantumkan baris demi baris dalam tabel di atas atau di `.env.example`. **Nama.** `CONTEXT_LENGTH_`, di mana `` adalah ID provider dalam huruf besar, dengan setiap karakter di luar `A-Z` / `0-9` diganti dengan `_`. ID provider adalah yang kanonik setelah resolusi alias (bagian `provider` dari string `provider/model` setelah alias pendek diresolusi). Node kustom yang kompatibel dengan OpenAI atau Anthropic menggunakan ID node yang dihasilkan, sehingga UUID menjadi bagian dari nama variabel. Nilainya adalah bilangan bulat positif berupa jumlah token; selain itu (kosong, `0`, negatif, non-numerik) diabaikan dan resolusi berlanjut ke langkah berikutnya. | ID Provider | Nama variabel | | ----------------------------------------------------------- | -------------------------------------------------------------------------- | | agentrouter | CONTEXT_LENGTH_AGENTROUTER | | openrouter | CONTEXT_LENGTH_OPENROUTER | | openai-compatible-chat-0f8e2c1a-5b7d-4e3f-9a6c-2d1b8e4f7a90 | CONTEXT_LENGTH_OPENAI_COMPATIBLE_CHAT_0F8E2C1A_5B7D_4E3F_9A6C_2D1B8E4F7A90 | **Prioritas.** Untuk pasangan `provider/model`, langkah pertama yang menghasilkan nilai menang: 1. `CONTEXT_LENGTH_` untuk provider tersebut. 2. `CONTEXT_LENGTH_DEFAULT` (override environment global). 3. Jendela per-model: override konteks yang disimpan secara persisten (diatur di dashboard, atau disematkan secara otomatis oleh rekonsiler penemuan, lihat `CONTEXT_WINDOW_RECONCILE_INTERVAL`), jika tidak ada, nilai katalog / models.dev yang disinkronkan. 4. `defaultContextLength` dari registry provider. 5. Heuristik nama model (`claude` 200000, `gemini` 1000000, `gpt` / `o1` / `o3` / `o4` / `codex` 400000). 6. Default bawaan per-provider, lalu `128000`. Kedua langkah environment berlaku untuk **seluruh provider**: setiap model dari provider tersebut mendapatkan batas yang sama, dan keduanya menang atas override per-model di dashboard. Ketika hanya satu model dari suatu provider yang membutuhkan jendela berbeda, gunakan override per-model di dashboard. **Cakupan.** Rantai ini menggerakkan pemeriksaan jendela konteks saat permintaan (penolakan `context_length_exceeded` / "Input exceeds context window" di `open-sse/handlers/chatCore.ts`), anggaran kompresi prompt, dan batas konteks kombo. `context_length` yang diiklankan oleh `GET /v1/models` masih dapat berasal dari metadata katalog atau registry dan tidak dijamin mencerminkan override environment. **Contoh.** Provider yang modelnya menerima jendela 1.050.000 token sementara katalog melaporkan 128.000: ```dotenv CONTEXT_LENGTH_AGENTROUTER=1050000 ``` Mulai ulang server setelah mengubahnya: nilai dibaca dari environment proses server. Pada **aplikasi desktop** server berjalan sebagai proses anak dan tidak melihat variabel sistem yang diatur setelah aplikasi diluncurkan; letakkan baris tersebut di file `.env` yang dimuat aplikasi (urutan pencarian di [Panduan Electron: Pencarian file environment](../guides/ELECTRON_GUIDE.md#environment-file-lookup)), lalu keluar sepenuhnya dan luncurkan kembali aplikasi. ### Kompresi | Variabel | Bawaan | Deskripsi | | ------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------- | | `OMNIROUTE_RTK_TRUST_PROJECT_FILTERS` | tidak diatur | Percayai `.rtk/filters.json` proyek tanpa hash `.rtk/trust.json`. Gunakan hanya dalam pengembangan lokal terkontrol. | ### Mesin Memori (rencana 21) ### Biaya event-loop dari memori, skill, dan penyegaran token (#10349) OmniRoute adalah **proses Node tunggal**. Ekstraksi/pengambilan memori, injeksi skill, dan penyegaran token provider berjalan pada **event loop yang sama** dengan `GET /healthz` dan dashboard. Semuanya bukan worker thread. | Pekerjaan | Kode | Bawaan | Kontrol operator | | ------------------------------ | ---------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | Ekstraksi / pengambilan memori | `src/lib/memory/` | Dashboard **memoryEnabled** (bawaan aktif) | Matikan **Pengaturan → Memori**. Tidak ada kill switch env terpisah selain menonaktifkan fitur di pengaturan. | | Injeksi skill | `src/lib/skills/injection.ts` | Dashboard **skillsEnabled** (bawaan aktif) | Matikan **Pengaturan → Memori/Skill** (`skillsEnabled`). Kenop sandbox di bawah hanya membatasi eksekusi setelah injeksi sudah aktif. | | Penyegaran token | `src/sse/services/tokenRefresh.ts` | Aktif untuk provider OAuth/web yang terhubung | Putuskan koneksi provider atau biarkan token tetap valid; saat ini tidak ada env `TOKEN_REFRESH=0`. | Jika `/healthz` lambat pada mesin yang sepi, nonaktifkan memori + skill terlebih dahulu, lalu periksa beban katalog/kompresi (#10303, #9685). Fitur-fitur ini melakukan yield di titik `await` tetapi tetap berebut satu thread. Lapisan embedding, vector store, dan kenop 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/dim). | | `MEMORY_EMBEDDING_CACHE_MAX` | `1000` | Jumlah maksimum entri LRU yang disimpan di 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 statis potion/Model2Vec. Diunduh secara malas ke direktori cache. | | `MEMORY_STATIC_CACHE_DIR` | `/embeddings` | Direktori yang digunakan untuk menyimpan file model potion statis. Secara default berada di bawah `DATA_DIR` jika tidak diatur. | | `HF_HUB_ENDPOINT` | `https://huggingface.co` | Menimpa URL dasar Hugging Face Hub yang digunakan oleh `staticPotion.ts` (mis. endpoint mirror untuk setup air-gapped). | | `MEMORY_VEC_TOP_K` | `20` | Top-K default yang digunakan oleh pencarian vektor brute-force `sqlite-vec` di 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` | Celah pengujian/diagnostik di `getVectorStore()` (`src/lib/memory/vectorStore.ts`): bila `true`, memaksa vector store menjadi `null` (mensimulasikan lingkungan cloud/WASM tanpa `sqlite-vec`), menurunkan pengambilan memori menjadi pencarian kata kunci FTS5. Biarkan tidak diatur di produksi. | | `NOTION_API_KEY` | _(belum diatur)_ | Kunci API untuk backend Notion (digunakan oleh preset backend yang dikenal di `genericBackend.ts`). | | `NOTION_API_URL` | `https://api.notion.com/v1` | URL dasar untuk Notion API (dapat ditimpa untuk alternatif Notion self-hosted). | | `OBSIDIAN_API_KEY` | _(belum diatur)_ | Kunci API untuk backend Obsidian Vault (digunakan oleh preset backend yang dikenal di `genericBackend.ts`). | | `OBSIDIAN_API_URL` | `http://localhost:27123` | URL dasar untuk Obsidian Vault API (dapat ditimpa untuk vault jarak jauh). | | `MEMORY_TYPED_DECAY_ENABLED` | `false` | Saklar utama peluruhan memori bertipe TV6. **Opt-in (default mati)** — sweep **menghapus** memori yang meluruh. Bila mati, `access_count`/`last_accessed_at` murni telemetri dan tidak ada yang pernah dihapus. | | `MEMORY_TYPED_DECAY_EPISODIC_DAYS` | `30` | TTL (hari) setelah memori `episodic` yang tidak digunakan meluruh. `0` membuat episodic juga kebal. Tipe tahan lama (`factual`/`procedural`/`semantic`) selalu kebal. Jam peluruhan di-reset berdasarkan `last_accessed_at`. | | `MEMORY_TYPED_DECAY_ACCESS_IMMUNITY` | `3` | Memori yang disuntikkan `>=` sebanyak ini menjadi kebal terhadap peluruhan tanpa memandang tipe. `0` menonaktifkan kekebalan akses. | | `MEMORY_TYPED_DECAY_SWEEP_INTERVAL` | `0` (dinonaktifkan) | Interval (detik) untuk sweep peluruhan berkala opsional di `src/lib/memory/typedDecay.ts`. `0`/tidak diatur = tidak ada sweep berkala. Opt-in ganda: juga memerlukan `MEMORY_TYPED_DECAY_ENABLED=true`. | | `OMNIROUTE_STRICT_SYSTEM_PROVIDERS` | _(belum diatur)_ | ID provider yang dipisahkan koma (tidak peka huruf besar/kecil) yang menerima pesan `system` **hanya di indeks 0** (`src/lib/memory/injection.ts`). Untuk provider ini, penyisipan memori di tengah array yang aman-cache tidak aman dalam percakapan multi-turn, sehingga memori digabungkan/ditambahkan di awal sebagai pesan system terdepan. Defaultnya hanya `xiaomi-mimo`/`mimo`; perluas untuk endpoint kompatibel-OpenAI self-hosted (mis. Qwen3.5+/3.6) yang chat template-nya memberlakukan batasan pesan-system-tunggal-terdepan yang sama. | ### Contoh Docker RAM Rendah `128` hanya untuk dashboard. Agen coding pada heap ini akan mengalami `FATAL ERROR` saat `/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 Spesifik Provider | Variable | Default | Source File | Description | | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `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` | Menyertakan field `name` yang ramah tampilan 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 (cold-path) untuk pembangunan ulang katalog `GET /v1/models` yang digabungkan (#12627). Saat timeout, respons 200 terakhir yang valid disajikan jika tersedia. | | `OMNIROUTE_SYNCED_CATALOG_STALE_AFTER_MS` | `2592000000` (30 hari) | `src/lib/db/models/activeSyncedCatalog.ts` | Usia setelah mana daftar model tersinkron milik sebuah koneksi berhenti menjadi otoritatif untuk routing dan gagal terbuka (fail open) ke registry (#12849). Baris tanpa stempel waktu dianggap kedaluwarsa. | | `OMNIROUTE_ANALYTICS_CACHE_TTL_MS` | `60000` (60 detik) | `src/lib/usage/analyticsResponseCache.ts` | Berapa lama respons `GET /api/usage/analytics` yang lambat digunakan kembali untuk query string yang sama (#15629). `0` menonaktifkan cache. | | `OMNIROUTE_ANALYTICS_CACHE_MIN_COMPUTE_MS` | `1000` (1 detik) | `src/lib/usage/analyticsResponseCache.ts` | Hanya respons analitik yang pembangunannya memerlukan waktu setidaknya selama ini yang di-cache, sehingga instans kecil selalu melihat data terbaru. | | `OMNIROUTE_CACHE_METRICS_MIN_COMPUTE_MS` | tidak diatur (nonaktif) | `src/app/api/cache/route.ts` via `src/lib/usage/analyticsResponseCache.ts` | Opt-in (#16361). Jika diatur ke bilangan bulat non-negatif N, bagian riwayat penggunaan dari `GET /api/cache` (total prompt-cache + tren) disajikan dari cache respons analitik bersama ketika pembangunannya memerlukan setidaknya N ms, per jendela `trendHours` yang diklamp, selama `OMNIROUTE_ANALYTICS_CACHE_TTL_MS` (riwayat dapat tertinggal hingga TTL tersebut; `DELETE /api/cache` membatalkannya). Tidak diatur atau tidak valid = riwayat dibaca langsung pada setiap permintaan. | | `NANOBANANA_POLL_TIMEOUT_MS` | `120000` | `open-sse/handlers/imageGeneration.ts` | Waktu tunggu maksimum untuk job pembuatan gambar NanoBanana. | | `NANOBANANA_POLL_INTERVAL_MS` | `2500` | `open-sse/handlers/imageGeneration.ts` | Frekuensi polling job NanoBanana. | | `ADOBE_FIREFLY_SUBMIT_BASE_DELAY_MS` | `8000` | `open-sse/services/adobeFireflyUpscale.ts` | Delay dasar untuk exponential backoff percobaan ulang submit upscale Adobe Firefly. | | `AWS_REGION` | _(tidak diatur)_ | `src/lib/providers/validation.ts`, `open-sse/handlers/audioSpeech.ts` | Region yang digunakan untuk membangun endpoint AWS Bedrock (Kiro, audio). | | `AWS_DEFAULT_REGION` | _(tidak diatur)_ | `src/lib/providers/validation.ts`, `open-sse/handlers/audioSpeech.ts` | Cadangan (fallback) 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 binary Chrome desktop untuk executor Cloudflare AI Playground, digunakan ketika pemeriksaan fingerprint headless memblokir Chromium bawaan Playwright. | | `CODEBUDDY_SYSTEM_PROMPT_MAX_LEN` | ∅ (∞) — _(tidak diatur = tanpa batas panjang)_ | `open-sse/executors/codebuddy/shared.ts` | Batas panjang opsional untuk system prompt pemanggil yang dikirim ke CodeBuddy (CN dan Internasional). Secara default, hanya prompt yang membawa penanda identitas coding-agent yang diganti dengan prompt netral (filter konten Tencent menolak prompt tersebut); prompt panjang tetap dipertahankan. Bilangan bulat > 0 juga mengganti system prompt apa pun yang lebih panjang dari jumlah karakter tersebut; tidak diatur, `0`, atau nilai non-bulat menonaktifkan batas. Setiap penggantian mencatat aturan mana yang terpicu (penanda identitas atau panjang). | | `CLOUDFLARE_API_BASE` | `https://api.cloudflare.com/client/v4` | `src/app/api/settings/proxy/cloudflare-deploy/route.ts` | Menimpa (override) base REST API Cloudflare yang digunakan oleh deployer relay Workers proxy-pool (#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 pada modal "Deploy Relay" di proxy-pool. | | `NEXT_PUBLIC_CLOUDFLARE_RELAY_ENABLED` | `true` | `src/app/(dashboard)/dashboard/settings/components/proxy/ProxyPoolTab.tsx` | Setel ke `false` untuk menyembunyikan opsi relay Cloudflare Workers dari tab Proxy Pool. | | `CLOUDFLARED_BIN` | auto-detect | `src/lib/cloudflaredTunnel.ts` | Path kustom ke binary `cloudflared`. | | `CLOUDFLARED_PROTOCOL` | `http2` | `src/lib/cloudflaredTunnel.ts` | Protokol transport tunnel: `http2` (default), `quic`, atau `auto`. | | `CLOUDFLARED_CONFIG` | _(unset)_ | `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` (named tunnel) alih-alih quick tunnel sementara. | | `CLOUDFLARED_HOSTNAME` | _(from config ingress)_ | `src/lib/cloudflaredTunnel.ts` | Penimpaan untuk hostname publik named tunnel (mis. `ai.example.com`), dilaporkan sebagai `publicUrl`/`apiUrl`. Jika tidak diatur, nilainya dibaca dari hostname `ingress` pertama pada konfigurasi. | | `DENO_DEPLOY_API_BASE` | `https://api.deno.com/v2` | `src/app/api/settings/proxy/deno-deploy/route.ts` | Menimpa base REST API Deno Deploy yang digunakan oleh deployer 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 pada modal "Deploy Relay" di proxy-pool. | | `NEXT_PUBLIC_DENO_RELAY_ENABLED` | `true` | `src/app/(dashboard)/dashboard/settings/components/proxy/ProxyPoolTab.tsx` | Setel ke `false` untuk menyembunyikan opsi relay Deno Deploy dari tab Proxy Pool. | | `SEARCH_CACHE_TTL_MS` | `300000` (5 min) | `open-sse/services/searchCache.ts` | TTL untuk caching respons API pencarian (Perplexity, Brave, dll.). | | `ENABLE_CC_COMPATIBLE_PROVIDER` | `false` | `src/shared/utils/featureFlags.ts` | Menampilkan UI provider kompatibel-CC eksperimental untuk relay khusus Claude Code. | | `NINEROUTER_HOST` | `127.0.0.1` | `open-sse/executors/ninerouter.ts` | Menimpa host tempat instance 9router tertanam mendengarkan. | | `NINEROUTER_PORT` | `20130` | `open-sse/executors/ninerouter.ts` | Menimpa port tempat instance 9router tertanam mendengarkan. | | `EMBED_WS_PROXY_HOST` | `127.0.0.1` | `src/lib/services/embedWsProxy.ts` | Host bind untuk proxy WebSocket layanan tertanam (hanya loopback secara default). | | `EMBED_WS_PROXY_PORT` | `20131` | `src/lib/services/embedWsProxy.ts` | Port untuk server proxy WebSocket layanan tertanam. | | `CLIPROXYAPI_HOST` | `127.0.0.1` | `open-sse/executors/cliproxyapi.ts` | Host bridge CLIProxyAPI (integrasi legacy). | | `CLIPROXYAPI_PORT` | `5544` | `open-sse/executors/cliproxyapi.ts` | Port bridge CLIProxyAPI. | | `CLIPROXYAPI_API_KEY` | _(empty)_ | `open-sse/handlers/chatCore/cliproxyapiCredentials.ts` | Fallback key data-plane ketika pengaturan `cliproxyapi_api_key` tidak ada. | | `CLIPROXYAPI_MANAGEMENT_KEY` | _(empty)_ | `src/lib/services/cliproxyAccountHealth.ts` | Key manajemen untuk pembacaan kesehatan akun dari instance 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 mempublikasikan sidecar `cliproxyapi` (#12578). Volume datanya menyimpan kredensial OAuth/API penyedia dan image yang di-pin tidak memiliki override `api-keys` data-plane berbasis env (hanya `config.yaml` yang di-mount), sehingga `0.0.0.0` mengekspos layanan yang membawa kredensial ke seluruh LAN. | | `MUX_SERVICE_PORT` | `8322` | `src/lib/services/bootstrap.ts` | Menimpa port tempat daemon orkestrasi agen Mux (coder/mux) tersemat mendengarkan (selalu 127.0.0.1). | | `OPENWA_SERVICE_PORT` | `8323` | `src/lib/services/bootstrap.ts` | Menimpa port tempat daemon open-wa (otomatisasi WhatsApp Web) tersemat mendengarkan (selalu 127.0.0.1). | | `DARIO_HOST` | `127.0.0.1` | `open-sse/executors/dario.ts` | Host bind/connect layanan tersemat Dario (hanya loopback secara default). | | `DARIO_PORT` | `3456` | `open-sse/executors/dario.ts` | Port layanan tersemat Dario. | | `DARIO_HOST` | `127.0.0.1` | `open-sse/executors/dario.ts` | Host bind/connect layanan tersemat Dario (hanya loopback secara default). | | `DARIO_PORT` | `3456` | `open-sse/executors/dario.ts` | Port layanan tersemat Dario. | | `LOCAL_HOSTNAMES` | _(kosong)_ | `open-sse/config/providerRegistry.ts` | Hostname tambahan yang dipisahkan koma yang diperlakukan sebagai "lokal" (nama layanan Docker, dll.). | `ENABLE_CC_COMPATIBLE_PROVIDER` hanya untuk relay pihak ketiga yang menerima klien Claude Code secara eksklusif. OmniRoute menulis ulang permintaan agar relay tersebut menerimanya. Jika Anda hanya ingin menggunakan Claude Code CLI, atau Anda tidak yakin apa relay ini, biarkan tetap dinonaktifkan dan tambahkan penyedia yang kompatibel dengan Anthropic biasa sebagai gantinya. --- ## 21. Kesehatan Proxy | Variable | Default | Source File | Description | | ------------------------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `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` | Jendela waktu (jam) untuk menghitung latensi rata-rata proxy kandidat dalam strategi pool 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 probe kesehatan proxy yang gagal. Jaga nilai ini lebih pendek dari `PROXY_HEALTH_CACHE_TTL_MS` agar timeout proxy sementara di bawah konkurensi tinggi dapat mencoba ulang dengan cepat tanpa menonaktifkan fast-fail untuk proxy yang benar-benar mati. | | `PROXY_HEALTH_ENABLED` | `true` | `src/lib/proxyHealth/scheduler.ts` | Atur ke `false` untuk menonaktifkan penjadwal kesehatan proxy latar belakang yang secara berkala memeriksa proxy yang terdaftar. | | `PROXY_HEALTH_INTERVAL_MS` | `600000` | `src/lib/proxyHealth/scheduler.ts` | Interval penyisiran penjadwal kesehatan latar belakang dalam ms (minimum `60000`). | | `PROXY_HEALTH_RELAY_INTERVAL_MS` | `21600000` | `src/lib/proxyHealth/relayCadence.ts` | Interval probe dalam ms untuk proxy edge-relay (`deno`/`vercel`/`cloudflare`), yang probe-nya membangunkan isolate serverless yang dikenai biaya (minimum `60000`). | | `PROXY_HEALTH_RECOVERY_INTERVAL_MS` | `600000` | `src/lib/proxyHealth/scheduler.ts` | Interval pass pemulihan latar belakang dalam ms: seberapa sering proxy yang sebelumnya tidak sehat di-probe ulang sehingga proxy yang telah pulih kembali masuk ke rotasi tanpa restart. Nilai di bawah `60000` akan dikembalikan ke default. | | `PROXY_HEALTH_TEST_URL` | `https://httpbin.org/ip` | `src/lib/proxyHealth/probeTarget.ts` | Target probe keterjangkauan yang digunakan oleh scheduler dan endpoint `/api/settings/proxies/auto-test`. Arahkan ke URL internal/self-hosted untuk menghindari penggunaan default publik. | | `PROXY_HEALTH_TEST_CONCURRENCY` | `10` | `src/lib/proxyHealth/probeTarget.ts` | Jumlah probe yang dimulai sekaligus per batch, digunakan bersama oleh scheduler dan endpoint `/api/settings/proxies/auto-test`. Dibatasi bawah pada 1 dan dibatasi atas pada 50. | | `PROXY_HEALTH_TEST_STAGGER_MS` | `100` | `src/lib/proxyHealth/probeTarget.ts` | Jeda dalam ms antara dua keberangkatan probe di dalam satu batch. Tanpa jeda ini, seluruh batch berangkat pada saat yang sama dan IP egress bersama dapat memicu target yang memiliki pembatasan laju. Atur ke `0` untuk menonaktifkan jarak; dibatasi maksimum 5000. | | `PROXY_HEALTH_USE_PROVIDER_TARGET` | `true` | `src/lib/proxyHealth/providerProbeTarget.ts` | Atur "false" untuk berhenti melakukan probe ke host asli provider yang ditugaskan pada proxy (`GET /models`, tanpa API key) dan selalu gunakan `PROXY_HEALTH_TEST_URL` sebagai gantinya. | | `PROXY_HEALTH_AUTO_DEACTIVATE` | `false` | `src/lib/proxyHealth/statusPolicy.ts` | Ketika `false` (default), probe keterjangkauan otomatis (scheduler + tombol "Test All" pada `/api/settings/proxies/auto-test`) bersifat **read-only** dan tidak pernah menulis status proxy — hanya operator yang mengatur aktif/tidak aktif, sehingga probe yang tidak stabil tidak dapat membuat proxy yang ditugaskan terlantar (#6246). Atur `true` untuk mengembalikan perilaku test-and-set lama. | | `FLUSH_EMPTY_RETRY_ENABLED` | `false` | `src/shared/utils/featureFlags.ts` | Flag fitur opt-in (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); override DB dashboard akan menang). `true` (atau `1`, `yes`) mencoba ulang turn streaming hasil translasi yang kosong melalui jalur kredensial normal (hingga `STREAM_RECOVERY.EMPTY_TURN_RETRY_MAX` percobaan ulang) alih-alih menampilkan respons 200 kosong atau 502 dengan konten kosong. | | `EMPTY_STREAM_SIBLING_RECOVERY_ENABLED` | `false` | `src/shared/utils/featureFlags.ts` | Flag fitur opt-in (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); override DB dashboard akan menang). `true` (atau `1`, `yes`) mengaktifkan probe konten stream kosong Claude/Codex dan menggunakan retry terbatas yang sudah ada pada koneksi lain yang memenuhi syarat setelah turn `empty_content`, tanpa cooldown atau lockout model. | | `STREAM_LATE_OUTPUT_PROBE_ENABLED` | `false` | `src/shared/utils/featureFlags.ts` | Flag fitur opt-in (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); override DB dashboard akan menang). `true` (atau `1`, `yes`) terus mengambil sampel satu chunk yang diteruskan dari setiap 16 setelah 64 chunk pertama, sehingga output terlihat yang muncul terlambat tetap menandai stream sebagai telah mengeluarkan output (5xx tunggal pasca-output tetap terbatas pada request, bukan lockout khusus model). | | `PROXY_POOL_EGRESS_OBSERVATION` | `false` | `src/shared/utils/featureFlags.ts` | Flag fitur opt-in (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); override DB dashboard menang). `true` (atau `1`, `yes`) menampilkan observasi egress pool read-only di bawah proxy pool pada dashboard (IP egress berbeda, koneksi, dan jumlah terbanyak yang terlihat di balik satu IP selama 24 jam terakhir, dari log proxy). Tidak pernah digunakan untuk routing. | | `PROXY_OPERATOR_EGRESS_ENABLED` | `false` | `src/shared/utils/featureFlags.ts` | Flag fitur opt-in (lihat [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); override DB dashboard menang). `true` (atau `1`, `yes`) menerima alamat teramati bertanggal yang dikirim operator per anggota pool dan menggabungkannya dengan pembacaan jurnal untuk tampilan dan urutan pool. | | `PROXY_OPERATOR_EGRESS_WINDOW_HOURS` | `24` | `src/lib/db/proxyOperatorEgress.ts` | Jendela observasi dalam jam untuk baris egress yang dikirim operator (dibaca pada setiap pembacaan; tidak perlu restart). Dibatasi pada 1..168; nilai di luar rentang, non-numerik, atau kosong akan kembali ke 24 dengan satu peringatan di seluruh proses, tidak pernah melempar error. | | `PROXY_AUTO_REMOVE` | `false` | `src/lib/proxyHealth/scheduler.ts` | Atur `true` agar scheduler menghapus proxy secara otomatis setelah kegagalan beruntun yang berulang. | | `PROXY_AUTO_REMOVE_AFTER` | `3` | `src/lib/proxyHealth/scheduler.ts` | Jumlah kegagalan beruntun sebelum scheduler menghapus proxy secara otomatis (saat `PROXY_AUTO_REMOVE=true`). | | `PROXY_AUTO_DISABLE` | `false` | `src/lib/proxyHealth/scheduler.ts` | Atur `true` agar scheduler menonaktifkan sementara (status `dead`, tidak pernah dihapus) sebuah proxy setelah kegagalan beruntun yang berulang, alih-alih menghapusnya. Alternatif non-destruktif untuk `PROXY_AUTO_REMOVE`: proxy langsung keluar dari resolusi pool/rotasi (filter status alive yang digunakan oleh resolusi scope-pool sudah mengecualikannya) dan diaktifkan kembali secara otomatis begitu mulai lolos probe lagi. Berbagi ambang batas `PROXY_AUTO_REMOVE_AFTER`. Jika kedua flag bernilai `true`, `PROXY_AUTO_REMOVE` yang menang. | | `PROXY_HEALTH_PASSIVE_SKIP` | `false` | `src/lib/proxyHealth/scheduler.ts` | Lewati pasif opt-in: saat `true`, scheduler melewati probe langsung untuk endpoint yang lalu lintas produksi terkininya sudah membuktikannya (setidaknya satu keberhasilan dan tidak ada kegagalan proxy yang teratribusi dalam jendela, tepat satu provider yang teramati). Nonaktif secara default: setiap proxy di-probe. | | `PROXY_PASSIVE_WINDOW_MS` | `300000` | `src/lib/proxyHealth/passiveVerdict.ts` | Jendela dalam ms dari lalu lintas produksi yang dilihat oleh lewati pasif (dibatasi `60000..599999`). Lebih pendek dari interval sweep 10 menit sehingga kegagalan terkini mendominasi alih-alih terdilusi. | | `OMNIROUTE_CONTROL_PLANE_PROXY_DIRECT_FALLBACK` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Mengizinkan alur OAuth dan validasi provider untuk melewati proxy yang disematkan dan terhubung langsung saat pra-pemeriksaan keterjangkauan proxy gagal. Prioritas efektifnya adalah override DB Feature Flags > variabel env > default. | | `RATE_LIMIT_MAX_WAIT_MS` | `30000` (30 detik) | `src/lib/resilience/settings.ts` | Bujet **tunggu-antrean** default: berapa lama sebuah permintaan boleh menunggu slot provider dan berada dalam antrean sebelum ditolak, tanpa pernah mencapai upstream. Timer dihapus begitu pekerjaan mulai dieksekusi — eksekusi dibatasi secara terpisah oleh `RATE_LIMIT_EXECUTION_MAX_WAIT_MS`. Env hanya menetapkan default: `resilienceSettings.requestQueue.maxWaitMs` yang tersimpan, lalu `rateLimitOverrides.maxWaitMs` per koneksi, masing-masing menang di atasnya. | | `RATE_LIMIT_EXECUTION_MAX_WAIT_MS` | `600000` (10 menit) | `open-sse/services/rateLimitManager.ts` | Batas atas berapa lama permintaan yang diterima boleh tetap dalam eksekusi sebelum reservasi rate-limit-nya kedaluwarsa — dipisahkan dari bujet tunggu-antrean agar fetch-start yang lambat pada gateway non-inkremental tidak mengalami timeout (#12027). | | `RATE_LIMIT_MAX_QUEUE_DEPTH` | `0` (dinonaktifkan) | `open-sse/services/rateLimitManager.ts` | Batas penerimaan antrean: tolak dengan 429 `queue_full` setelah sekian banyak permintaan sudah berada dalam antrean. `0` = tanpa batas (default). | | `RATE_LIMIT_AUTO_ENABLE` | _(belum diatur)_ | `open-sse/services/rateLimitManager.ts` | Memaksa jaring pengaman rate limit auto-enable aktif/nonaktif terlepas dari pengaturan Dashboard yang tersimpan (`resilienceSettings.requestQueue.autoEnableApiKeyProviders`). Menerima `true`/`1`/`on` untuk memaksa aktif, `false`/`0`/`off` untuk memaksa nonaktif. Saat aktif (default), koneksi kunci API yang aktif secara otomatis dilindungi rate limit. Mengatur `rateLimitProtection: false` per koneksi menonaktifkan perlindungan eksplisit tetapi tidak memilih keluar dari jaring pengaman ini; mengatur env var ini ke `false` adalah mekanisme global untuk menjalankan koneksi kunci API tanpa antrean rate-limit. | | `PROVIDER_COOLDOWN_ENABLED` | _(belum diatur → nonaktif)_ | `open-sse/services/providerCooldownTracker.ts` | Pelacakan cooldown provider/koneksi lintas-permintaan global yang bersifat opt-in. NONAKTIF secara default (tumpang tindih dengan Connection Cooldown / Provider Circuit Breaker). Menerima `true`/`1`/`on` untuk mengaktifkan. | | `PROVIDER_COOLDOWN_MIN_MS` | `5000` | `open-sse/services/providerCooldownTracker.ts` | Cooldown minimum (ms) sebelum provider/koneksi yang gagal dicoba ulang. Diskalakan secara eksponensial seiring kegagalan beruntun. Hanya digunakan saat `PROVIDER_COOLDOWN_ENABLED`. | | `PROVIDER_COOLDOWN_MAX_MS` | `300000` (5 menit) | `open-sse/services/providerCooldownTracker.ts` | Batas maksimum cooldown (ms) sebelum provider/koneksi yang gagal tetap dicoba ulang. Hanya digunakan saat `PROVIDER_COOLDOWN_ENABLED`. | | `STREAM_RECOVERY_ENABLED` | _(belum diatur → nonaktif)_ | `src/lib/resilience/settings.ts` (penyemaian) → `open-sse/services/streamRecovery.ts` (logika) | **Apa:** pemulihan transparan untuk stream upstream yang terpotong (port dari free-claude-code). Menahan jendela SSE pembuka hingga `STREAM_RECOVERY.HOLDBACK_MS` (750 ms) sehingga pemutusan _pre-commit_ — yang terjadi sebelum byte apa pun mencapai klien — dibuka kembali dan dicoba ulang tanpa terlihat. **Kapan mengaktifkan:** upstream yang tidak stabil dan sering terpotong 0-byte di awal stream; biarkan NONAKTIF jika Anda tidak dapat menoleransi tambahan hingga 750 ms pada time-to-first-token di setiap stream. Menerima `true`/`1`/`on`. Menyemai pengaturan Resilience yang tersimpan; pengaturan Dashboard menang setelah diatur. | | `STREAM_RECOVERY_MIDSTREAM_ENABLED` | _(tidak disetel → nonaktif)_ | `src/lib/resilience/settings.ts` (seed) → `open-sse/services/streamRecovery.ts` (logic) | **Apa:** kelanjutan di tengah stream (Fase 4.4) — setelah pemotongan _post-commit_ (byte sudah sampai ke klien), kirim permintaan ulang dengan teks parsial sebagai prefill asisten dan jahit sufiks yang hilang. Hanya untuk stream teks biasa yang kompatibel dengan OpenAI; tidak pernah terpicu saat ada tool call yang sedang berjalan. **Kapan diaktifkan:** generasi panjang yang terpotong di tengah jawaban dan Anda menerima bagian akhir yang dipulihkan tiba sebagai satu burst, 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 output-berguna stream aktif yang bersifat opt-in. Mendeteksi stream yang terus mengirim chunk tetapi tetap berada di bawah laju output asisten yang dikonfigurasi; heartbeat, event usage, delta kosong, dan fase tool/reasoning tidak menyamar sebagai progres. Terpisah dari timeout idle dan hard-deadline. | | `STREAM_THROUGHPUT_WATCHDOG_WARMUP_MS` | `30000` | `src/lib/resilience/settings/normalize.ts` | Masa tenggang sebelum evaluasi throughput, dibatasi hingga 0–600000 ms. | | `STREAM_THROUGHPUT_WATCHDOG_WINDOW_MS` | `30000` | `src/lib/resilience/settings/normalize.ts` | Jendela bergulir output-berguna, dibatasi hingga 1000–600000 ms; satu jendela lengkap diperlukan sebelum abort. | | `STREAM_THROUGHPUT_WATCHDOG_MIN_BYTES_PER_SECOND` | `4` | `src/lib/resilience/settings/normalize.ts` | Laju byte output asisten UTF-8 minimum (proksi token konservatif), dibatasi hingga 1–1000000. | | `STREAM_THROUGHPUT_WATCHDOG_MIN_USEFUL_BYTES` | `1` | `src/lib/resilience/settings/normalize.ts` | Sampel output-berguna non-nol minimum yang dianggap terukur, dibatasi hingga 1–1000000 byte. | | `HEALTHCHECK_STAGGER_MS` | `3000` | `src/lib/tokenHealthCheck.ts` | Interval stagger (ms) antara healthcheck token provider saat startup. | | `HEALTHCHECK_JITTER_MIN_MS` | `500` | `src/lib/tokenHealthCheck.ts` | Jitter acak minimum (ms) yang ditambahkan di atas `HEALTHCHECK_STAGGER_MS` antara healthcheck token provider, untuk mencegah bursting (Issue #1220). | | `HEALTHCHECK_JITTER_MAX_MS` | `5000` | `src/lib/tokenHealthCheck.ts` | Jitter acak maksimum (ms) yang ditambahkan di atas `HEALTHCHECK_STAGGER_MS` antara healthcheck token provider, untuk mencegah bursting (Issue #1220). | | `HEALTHCHECK_BATCH_SIZE` | `20` | `src/lib/tokenHealthCheck.ts` | Ukuran batch pemeriksaan konkuren untuk sapuan healthcheck token saat startup; nilai yang lebih besar memeriksa lebih banyak koneksi secara paralel, nilai yang lebih kecil mengurangi beban burst (Issue #7875, regresi dari #7719). | | `REQUEST_RETRY` | `2` | `src/sse/services/cooldownAwareRetry.ts` | Jumlah percobaan ulang otomatis pada respons cooldown lingkup-model sebelum mengembalikan error ke klien. | | `MAX_RETRY_INTERVAL_SEC` | `30` | `src/sse/services/cooldownAwareRetry.ts` | Interval backoff maksimum (detik) di antara percobaan ulang cooldown. Dibatasi oleh nilai ini terlepas dari `Retry-After` upstream. | | `HEADROOM_URL` | `http://localhost:8787` | `src/lib/headroom/detect.ts` | URL proxy token-saver Headroom. Lifecycle dashboard (`api/headroom/*`) secara default menjalankan CLI `headroom-ai` lokal pada loopback; timpa hanya untuk mengarah ke proxy sidecar Docker eksternal. | ### Konstanta penyetelan pemulihan stream Perilaku holdback pemulihan disetel oleh konstanta hardcoded di `open-sse/config/constants.ts` (`STREAM_RECOVERY`), ditampilkan di sini sebagai referensi — mengubahnya memerlukan penyuntingan kode, bukan variabel env: - `STREAM_RECOVERY.HOLDBACK_MS = 750` — berapa lama jendela SSE pembuka ditahan sehingga pemotongan dini dapat dicoba ulang sebelum byte apa pun dikomit ke klien. - `STREAM_RECOVERY.BUFFER_MAX_BYTES = 65536` — batas keras pada jendela yang ditahan; komit (flush + passthrough) segera setelah byte sebanyak ini terkumpul, terlepas dari timer. - `STREAM_RECOVERY.EARLY_RETRY_MAX = 4` — maksimum pembukaan ulang transparan stream upstream selama holdback masih belum dikomit. > **Rate limit sliding-window per penyedia (tanpa variabel env):** _fallback_ > rate limit sliding-window per penyedia hasil porting FCC ada di kode > (`open-sse/services/providerDefaultRateLimit.ts`, terhubung melalui > `open-sse/services/rateLimitManager.ts`) tetapi dikirimkan dengan **map default kosong** > dan saat ini **tidak memiliki variabel env operator** — hanya diaktifkan melalui hook pengujian / > penyuntingan kode. Bagian ini sengaja tidak dicantumkan dalam tabel di atas. Pembatas relay > per-`(token, IP)` yang _memang_ memiliki knob 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 ber-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 ``` ### Lingkungan 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 Proksi Terbalik (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 Provider, Tunnel, Backup & Runtime Lainnya Endpoint kuota provider, tunnel jaringan (Tailscale, Ngrok, proxy debug MITM), pool egress 1Proxy, backup database, dan override kecil per fitur yang dirujuk oleh lapisan executor atau skrip. | Variable | Default | Source File | Description | | ---------------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `REDIS_URL` | `redis://localhost:6379` | `src/shared/utils/rateLimiter.ts` | String koneksi Redis untuk backend rate limiter. | | `ALIBABA_CODING_PLAN_HOST` | _(host produksi)_ | `open-sse/services/bailianQuotaFetcher.ts` | Menimpa host yang digunakan untuk mengambil kuota coding-plan Alibaba Bailian. | | `ALIBABA_CODING_PLAN_QUOTA_URL` | diturunkan dari host | `open-sse/services/bailianQuotaFetcher.ts` | Timpaan URL kuota lengkap untuk Alibaba Bailian. | | `QWEN_CLOUD_COOKIE` | _(belum diatur)_ | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Cookie sesi konsol untuk gateway kuota Token Plan pribadi Qwen Cloud / Model Studio (API key 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` di home.qwencloud.com › Billing › Subscription (F12 › Network). Sensitif dan terbatas pada sesi; sebaiknya gunakan kolom Dashboard `qwenCloudCookie` per koneksi. | | `QWEN_CLOUD_SEC_TOKEN` | _(belum diatur)_ | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Timpaan `sec_token` manual untuk gateway konsol Token Plan. Sensitif; jika tidak diatur, pengambil akan mendapatkannya dari HTML dashboard menggunakan cookie. | | `QWEN_TOKEN_PLAN_HOST` | `https://cs-data.qwencloud.com` | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Timpaan host gateway untuk pengambil kuota Token Plan pribadi (mis. `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 mendapatkan `sec_token` dari HTML yang sudah login. | | `XIAOMI_MIMO_CONSOLE_COOKIE` | _(belum diatur)_ | `open-sse/services/usage/xiaomi-mimo.ts` | Cookie sesi konsol untuk API kuota Token Plan Xiaomi MiMo (`platform.xiaomimimo.com/api/v1/tokenPlan/usage` + `tokenPlan/detail` — API key inferensi tidak dapat membacanya). Salin seluruh header permintaan `Cookie` — yang berisi `api-platform_serviceToken` dan `userId` — dari permintaan apa pun ke `platform.xiaomimimo.com` pada halaman Token Plan (F12 › Network). Sensitif dan terbatas pada sesi; sebaiknya gunakan kolom Dashboard `xiaomiMimoConsoleCookie` per koneksi. | | `XIAOMI_MIMO_MONTHLY_TOKEN_LIMIT` | `4100000000` | `open-sse/services/usage/xiaomi-mimo.ts` | Anggaran bulanan (Kredit) untuk fallback Xiaomi MiMo yang dilacak OmniRoute, digunakan saat tidak ada cookie konsol yang dikonfigurasi. Default-nya 4,1B milik tier Lite; atur ke Kredit paket (Standard 11B / Pro 38B / Max 82B). Override `providerSpecificData.monthlyTokenLimit` per koneksi lebih diprioritaskan daripada env var ini. | | `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 vision/media free-tier Alibaba Model Studio. | | `ALIBABA_FREE_TIER_MULTIMODAL_FE_PATH` | `/costing-balance/free-quota-multimodal` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Override path front-end konsol untuk mengambil kuota multimodal free-tier Alibaba Model Studio. | | `ALIBABA_FREE_TIER_AUDIO_FE_PATH` | `/costing-balance/free-quota-audio` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Override path front-end konsol untuk mengambil kuota audio free-tier Alibaba Model Studio. | | `ALIBABA_FREE_TIER_ALLOWLIST_PATH` | _(tidak diatur)_ | `open-sse/services/alibabaFreeTierAllowlist.ts` | Path opsional ke override JSON lokal untuk allowlist model teks free-tier Alibaba bawaan. Jika tidak ada, akan kembali 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 output penyelesaian saat menghitung anggaran prompt. | | `CONTEXT_KEEP_LATEST_IMAGES` | `2` | `open-sse/services/contextManager.ts` | Berapa banyak gambar inline terbaru yang dipertahankan saat memangkas gambar lama agar muat di jendela konteks (#8560). | | `MODEL_ALIAS_COMPAT_ENABLED` | aktif | `open-sse/services/model.ts` | Mengaktifkan/menonaktifkan lapisan kompatibilitas alias model lama yang digunakan oleh klien lama. | | `OMNIROUTE_EMERGENCY_FALLBACK` | aktif | `open-sse/services/emergencyFallback.ts` | Atur `false` (atau `0`) untuk menonaktifkan fallback darurat kehabisan anggaran yang mengalihkan permintaan gagal ke model gratis `nvidia`/`openai/gpt-oss-120b`. Prioritas efektifnya adalah override Feature Flags DB > env var > default; jika tidak tersedia, layanan akan kembali ke nilai env mentah. | | `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. Timpa 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 smartphone. Timpa untuk API Command Code alternatif/yang di-hosting sendiri. | | `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 `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 idle yang melewati batas ini akan ditutup untuk menghindari kebocoran terowongan half-open. | | `BRIDGE_PORT` | `20129` | `bin/antigravity-bridge.mjs` | Port tempat bridge MITM Antigravity mendengarkan. | | `ROUTER_URL` | `http://127.0.0.1:20128/v1/antigravity` | `bin/antigravity-bridge.mjs` | Endpoint router tujuan bridge meneruskan lalu lintas Antigravity. | | `CERT_DIR` | `/mitm` | `bin/antigravity-bridge.mjs` | Menimpa direktori tempat bridge membaca materi TLS-nya. Model sertifikat dipilih seperti yang dilakukan server AgentBridge: `server.crt`/`server.key` untuk instalasi leaf lawas, jika tidak maka `ca.crt`/`ca.key` (root CA, satu leaf per host yang dicegat; dipaksakan oleh `MITM_ROOT_CA_ENABLED=true`). Bridge keluar saat startup jika file untuk model yang aktif tidak ada. | | `MITM_VERBOSE` | `1` | `src/mitm/server.cjs`, `src/mitm/_internal/bypass.cjs` | Tingkat verbositas log keputusan routing: `0` membisukan, nilai lebih tinggi mencatat lebih banyak keputusan bypass/rute. | | `MITM_ROOT_CA_ENABLED` | `false` | `src/mitm/manager.ts` | Atur `true` untuk ikut serta dalam model sertifikat root-CA + leaf per host (#6684). Instalasi baru mendapatkannya secara otomatis; instalasi dengan leaf lawas yang sudah tepercaya tetap memakai sertifikat fixed-SAN lawas kecuali jika ikut serta. | | `MITM_CERT_MODE` | `legacy` | `src/mitm/manager.ts`, `src/mitm/server.cjs` | Diatur OLEH manajer MITM untuk proses proksi yang di-spawn (`root-ca` \| `legacy`) — mencerminkan keputusan migrasi sertifikat; tidak dimaksudkan untuk diatur secara manual. | | `OMNIROUTE_NO_SUDO` | `0` | `src/mitm/systemCommands.ts` | Atur `1` (truthy) untuk menghilangkan awalan `sudo` dari perintah cert-trust MITM — untuk deployment tanpa root / user-namespaced di mana operator mempercayai CA secara manual (mis. melalui mekanisme extra-CA-certs Node). | | `SKIP_ANTIGRAVITY_DNS` | _(belum diatur)_ | `src/mitm/dns/provision.ts` | Atur `true` untuk melewati provisioning entri DNS `/etc/hosts` untuk hostname proxy Antigravity sepenuhnya — untuk container yang tidak memiliki sudo/root. | | `OMNIROUTE_SKIP_DNS_WRITE` | _(belum diatur)_ | `src/mitm/dns/dnsConfig.ts` | Atur `1` untuk melewati penulisan ke file hosts saat menambahkan/menghapus entri DNS — untuk lingkungan pengujian yang di-sandbox atau read-only. | | `OMNIROUTE_SKIP_SYSTEM_TRUST` | `0` | `src/mitm/cert/install.ts`, `src/mitm/tproxy/caTrust.ts` | Pelindung khusus test/CI: atur `1` untuk menjadikan instal/uninstal trust sertifikat sebagai no-op sehingga suite tidak pernah mengubah trust store OS. Diatur secara otomatis oleh setup pengujian dan workflow CI. | | `CHANGELOG_BASE_REF` | _(otomatis)_ | `scripts/check/check-changelog-integrity.mjs` | Base ref eksplisit untuk gate anti CHANGELOG-eat (default ke branch dasar PR di CI, atau `release/v*` tertinggi). | | `FREE_PROXY_AUTO_SYNC_ENABLED` | `false` | `src/lib/freeProxyProviders/scheduler.ts` | Atur `true` untuk mengaktifkan scheduler auto-sync pool proxy gratis di latar belakang. Opt-in, nonaktif secara default. | | `FREE_PROXY_AUTO_SYNC_INTERVAL_MS` | `1800000` | `src/lib/freeProxyProviders/scheduler.ts` | Interval auto-sync dalam milidetik (default 30 menit). | | `FREE_PROXY_1PROXY_ENABLED` | `true` | `src/lib/freeProxyProviders/oneproxy.ts` | Aktifkan sumber proxy gratis 1proxy. Atur ke `false` untuk menonaktifkan. | | `FREE_PROXY_1PROXY_API_URL` | _(lihat oneproxy.ts)_ | `src/lib/freeProxyProviders/oneproxy.ts` | Override URL API 1proxy. | | `FREE_PROXY_1PROXY_MAX` | `500` | `src/lib/freeProxyProviders/oneproxy.ts` | Jumlah maksimum proxy 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 proxy gratis Proxifly. Atur ke `false` untuk menonaktifkan. | | `FREE_PROXY_PROXIFLY_QUANTITY` | `100` | `src/lib/freeProxyProviders/proxifly.ts` | Jumlah proxy yang 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 opt-in. | | `FREE_PROXY_IPLOCATE_BASE_URL` | `https://raw.githubusercontent.com/iplocate/free-proxy-list/main/protocols` | `src/lib/freeProxyProviders/iplocate.ts` | Override URL dasar daftar proxy IPLocate. | | `FREE_PROXY_WEBSHARE_ENABLED` | `true` | `src/lib/freeProxyProviders/webshare.ts` | Aktifkan sumber pool proxy Webshare. Atur ke `false` untuk menonaktifkan; juga mengharuskan `FREE_PROXY_WEBSHARE_API_KEY` diatur. | | `FREE_PROXY_WEBSHARE_API_KEY` | _(tidak ada)_ | `src/lib/freeProxyProviders/webshare.ts` | Token API akun Webshare (`Authorization: Token `). Wajib — provider tetap dinonaktifkan tanpanya. | | `FREE_PROXY_WEBSHARE_API_URL` | `https://proxy.webshare.io/api/v2/proxy/list/` | `src/lib/freeProxyProviders/webshare.ts` | Override 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` | Menampilkan/menyembunyikan tombol Deploy Vercel Relay di tab Proxy Pool. | | `VERCEL_API_BASE` | `https://api.vercel.com` | `src/app/api/settings/proxy/vercel-deploy/route.ts` | Override URL dasar Vercel API (untuk pengujian). | | `NEXT_PUBLIC_VERCEL_RELAY_DEFAULT_PROJECT` | `omniroute-relay` | `src/app/(dashboard)/…/VercelRelayModal.tsx` | Nama proyek default yang sudah terisi otomatis di modal deploy Vercel Relay. | | `TAILSCALE_BIN` | _(deteksi otomatis)_ | `src/lib/tailscaleTunnel.ts` | Jalur eksplisit ke binary `tailscale`. | | `TAILSCALED_BIN` | _(deteksi otomatis)_ | `src/lib/tailscaleTunnel.ts` | Jalur eksplisit ke binary daemon `tailscaled`. | | `TAILSCALE_AUTHKEY` | _(tidak diatur)_ | `src/lib/tailscaleTunnel.ts` | Kunci auth Tailscale pre-shared untuk `tailscale up` non-interaktif / headless (diteruskan melalui `--auth-key=`). Jika tidak diatur, login beralih ke URL autentikasi browser interaktif. | | `NGROK_AUTHTOKEN` | _(tidak diatur)_ | `src/lib/ngrokTunnel.ts` | Mengautentikasi tunnel ngrok keluar. | | `DB_BACKUP_MAX_FILES` | `20` | `src/lib/db/backup.ts` | Jumlah maksimum file backup SQLite yang dipertahankan oleh pembersihan backup manual/terjadwal. Snapshot migrasi dialamatkan berdasarkan konten dan digunakan kembali untuk keadaan DB yang identik; snapshot tersebut tidak dipangkas di dalam jendela migrasi konkuren. Menggantikan nilai yang disimpan dari Pengaturan → Retensi backup database. | | `DB_BACKUP_RETENTION_DAYS` | `0` | `src/lib/db/backup.ts` | Usia maksimum (hari) yang dipertahankan oleh pembersihan backup manual/terjadwal. `0` menonaktifkan pemangkasan berbasis usia. Snapshot migrasi tidak dipangkas di dalam jendela migrasi konkuren. Menggantikan nilai yang disimpan dari Pengaturan → Retensi backup database. | | `OMNIROUTE_BACKUP_SCHEDULE_JOB_INTERVAL_MS` | `30000` | `src/lib/jobs/backupScheduleJob.ts` | Interval tick (ms) dari job sisi server yang mengeksekusi `backup-schedule.json`. 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. Atur ke `podman` untuk topologi Podman apa pun. Karena container tidak dapat menentukan apakah engine bersifat lokal atau dijangkau melalui Podman Machine, peringatan tetap netral terhadap topologi dan mengarah ke `contrib/podman/README.md`. | | `QUOTA_STORE_DRIVER` | `sqlite` | `src/lib/quota/storeFactory.ts` | Backend penyimpanan konsumsi quota-share: `sqlite` (default) atau `redis`. | | `QUOTA_STORE_REDIS_URL` | _(tidak diatur)_ | `src/lib/quota/storeFactory.ts` | String koneksi Redis yang digunakan saat `QUOTA_STORE_DRIVER=redis` (mis. `redis://localhost:6379`). | | `QUOTA_SATURATION_THRESHOLD` | `0.5` | `src/lib/quota/enforce.ts` | Rasio saturasi pool (0..1); pada/di atas nilai ini pool memasuki mode ketat (tanpa peminjaman). | | `QUOTA_SOFT_DEPRIORITIZE_FACTOR` | `0.7` | `open-sse/services/combo.ts` | Pengali skor (0..1) yang diterapkan pada 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 pada provider yang habis (`credits_exhausted`/`rate_limited`) dalam penilaian auto-combo saat preflight quota cutoff NONAKTIF (#4540). | | `QUOTA_CONSUMPTION_RETENTION_DAYS` | `14` | `src/lib/db/quotaConsumption.ts` | Jendela retensi (hari) untuk bucket `quota_consumption` sebelum GC (`gcQuotaConsumption`). | | `QUOTA_PREFLIGHT_CUTOFF_ENABLED` | `false` | `src/lib/resilience/settings.ts` | Opt-in (default NONAKTIF): mengaktifkan hard quota cutoff auto-routing yang membuang kandidat berkuota rendah sebelum penilaian. | | `OMNIROUTE_AUTO_FREE_FALLBACK_TO_FULL_POOL` | `false` | `open-sse/services/autoCombo/virtualFactory.ts` | Opt-in (default NONAKTIF): saat filter `auto/:` tidak cocok dengan kandidat terhubung mana pun, pulihkan perilaku lawas yaitu jatuh kembali ke pool penuh (tanpa filter) alih-alih mengembalikan pool kosong. Default NONAKTIF membuat `:free` berarti "hanya tier gratis". | | `OMNIROUTE_CHAOS_MAX_PANEL` | `5` | `open-sse/services/autoCombo/virtualFactory.ts` | Batas ukuran panel (dibatasi 1–10) untuk varian broadcast `auto/*:chaos` — satu permintaan disebarkan ke maksimal sejumlah model dari beragam provider ini. | | `OMNIROUTE_CHAOS_MIN_PANEL` | _(default engine)_ | `open-sse/services/autoCombo/virtualFactory.ts` | Penyetelan ukuran panel minimum yang diteruskan ke handler broadcast chaos; jika tidak diatur, tetap menggunakan default engine. | | `OMNIROUTE_CHAOS_PANEL_TIMEOUT_MS` | _(default engine)_ | `open-sse/services/autoCombo/virtualFactory.ts` | Batas waktu keras (ms) untuk seluruh fan-out panel chaos; jika tidak diatur, tetap menggunakan default engine. | | `GROK_AUTH_PATH` | `~/.grok/auth.json` | `open-sse/services/grokQuotaFetcher.ts` | Path file `auth.json` milik Grok CLI yang digunakan untuk mengambil kuota mingguan grok-web; timpa untuk pengujian atau instalasi CLI non-standar. | | `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 request yang ditangkap dan disimpan dalam ring buffer Traffic Inspector. | | `INSPECTOR_MAX_BODY_KB` | `1024` | `src/mitm/inspector/buffer.ts` | Ukuran maksimum body request/response yang ditangkap (KB) sebelum dipotong. | | `INSPECTOR_HTTP_PROXY_PORT` | `8080` | `src/mitm/inspector/httpProxyServer.ts` | Port lokal untuk proxy HTTP Traffic Inspector. | | `INSPECTOR_HTTP_PROXY_AUTOSTART` | `false` | `src/mitm/inspector/httpProxyServer.ts` | Menjalankan proxy HTTP inspector secara otomatis saat boot. | | `INSPECTOR_LLM_HOSTS_EXTRA` | _(tidak diatur)_ | `src/lib/inspector/captureState.ts` | Hostname tambahan (dipisahkan koma) yang diperlakukan sebagai endpoint LLM untuk penangkapan. | | `INSPECTOR_MASK_SECRETS` | `true` | `src/mitm/inspector/buffer.ts` | Menyamarkan rahasia (header auth / API key) dalam traffic yang ditangkap. | | `INSPECTOR_SYSTEM_PROXY_GUARD_MINUTES` | `30` | `src/app/api/tools/traffic-inspector/capture-modes/system-proxy/route.ts` | Menit sebelum penjaga system-proxy mengembalikan pengaturan proxy OS secara otomatis. | | `INSPECTOR_INTERNAL_INGEST_TOKEN` | _(otomatis)_ | `src/app/api/tools/traffic-inspector/internal/ingest/route.ts` | Token untuk mengautentikasi ingest capture internal ke inspector. | | `PLAYGROUND_COMPARE_MAX_COLUMNS` | `4` | `src/app/(dashboard)/dashboard/playground/` | Jumlah maksimum kolom berdampingan dalam mode compare Playground. | | `PLAYGROUND_IMPROVE_PROMPT_DEFAULT_MODEL` | _(tidak diatur)_ | `src/app/(dashboard)/dashboard/playground/` | Model default untuk aksi 'improve prompt' Playground (kembali ke model aktif jika tidak diatur). | | `BIFROST_ENABLED` | `1` | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Sakelar pemutus utama untuk proxy sidecar bifrost. Saat diatur ke `0`, route mengembalikan 503 dengan header `X-Bifrost-Killswitch` dan operator dialihkan ke jalur TS. Gunakan untuk menonaktifkan sidecar tanpa redeploy (insiden router tier-1, rotasi kunci). | | `BIFROST_BASE_URL` | _(tidak diatur)_ | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Saat diatur, route proxy sidecar Bifrost meneruskan trafik `/v1/chat/completions` ke gateway Go ini alih-alih handler relay TS. Tidak diatur → 503-dengan-fallback. Garis miring di akhir (trailing slash) dihapus. | | `BIFROST_PORT` | `8080` | `src/lib/services/bootstrap.ts` | Port tempat layanan Bifrost embedded yang diawasi melakukan bind (`127.0.0.1:`) ketika OmniRoute mengelola siklus hidup sidecar Bifrost. Default `8080`. | | `LLMLINGUA_PORT` | `20135` | `src/lib/services/bootstrap.ts` | Port tempat layanan kompresi LLMLingua yang diawasi melakukan bind (`127.0.0.1:`). Default `20135`. | | `LLMLINGUA_BASE_URL` | `http://127.0.0.1:20135` | `open-sse/services/compression/engines/llmlingua/index.ts` | Base URL untuk daemon microservice kompresi HTTP LLMLingua lokal. Default `http://127.0.0.1:20135`. | | `LLMLINGUA_MODEL` | `atjsh/llmlingua-2-js-tinybert-meetingbank` | `src/lib/services/installers/llmlingua.ts` | ID model Hugging Face yang dimuat oleh sidecar LLMLingua yang diawasi (diteruskan ke env proses anak). | | `BIFROST_API_KEY` | _(tidak diatur)_ | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | API key untuk gateway Bifrost (dikirim sebagai `Authorization: Bearer ...`). Jika tidak diatur, route mengharapkan request membawa API key OmniRoute yang valid; kunci ini hanya untuk autentikasi sisi gateway. | | `BIFROST_STREAMING_ENABLED` | `true` | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Jika true, route sidecar Bifrost melakukan streaming respons kembali melalui SSE lewat gateway, bukan melalui executor 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` | Timeout per permintaan saat melakukan proxy ke gateway Bifrost (ms). Saat timeout, 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` diutamakan saat 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 saat Bifrost tidak dikonfigurasi); `auto` memilih Bifrost saat `BIFROST_BASE_URL` diatur dan `BIFROST_ENABLED` ≠ `0`, dengan fallback TS otomatis jika sidecar tidak dapat dijangkau; `bifrost` memaksa Bifrost (ketat, tanpa fallback). Auth/rate-limit/injection-guard/allowlist selalu berjalan di route Next terlebih dahulu. Respons membawa `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` diutamakan saat keduanya diatur. | | `OMNIROUTE_BIFROST_FAILURE_COOLDOWN_MS` | `5000` | `src/app/api/v1/relay/chat/completions/bifrostCooldown.ts` | Cooldown (ms) setelah hop sidecar Bifrost gagal dalam mode `auto` sebelum relay mencoba ulang sidecar; relay mengarahkan langsung ke jalur TS selama cooldown berlangsung, lalu menyelidiki kembali. `0` menonaktifkan. Hanya berlaku saat `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 standalone kemudian mengakhiri TLS pada listener yang sama (`wss://` berfungsi tanpa perubahan). Tidak diatur → HTTP biasa. Menyediakan hanya salah satu dari cert/key, atau jalur yang tidak dapat dibaca, akan mencatat peringatan dan tetap menggunakan HTTP. | | `OMNIROUTE_TLS_KEY` | _(tidak diatur)_ | `bin/cli/commands/serve.mjs` | Jalur ke private key 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 route `/api/local/*`. Jika tidak diatur atau `0`, semua route `/api/local/*` mengembalikan 503 di production. Harus `1` pada deployment non-loopback untuk mengaktifkan peluncur Redis dan starter layanan lokal 1-klik serupa. Perlindungan berlapis dengan klasifikasi route-guard `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 (mis. aplikasi desktop). Jika diatur, permintaan dari IP non-loopback harus membawa `Authorization: Bearer `. Wajib saat `OMNIROUTE_LOCAL_ENDPOINTS_ENABLED=1` pada deployment non-loopback. | | `OMNIROUTE_REDIS_CONTAINER_NAME` | `omniroute-redis` | `bin/cli/commands/redis.mjs` | Nama container untuk peluncur Redis 1-klik (`omniroute redis up`). Digunakan oleh CLI maupun GUI `RedisLauncherPanel`. | | `OMNIROUTE_REDIS_HOST_PORT` | `6379` | `bin/cli/commands/redis.mjs` | Port host untuk peluncur Redis 1-klik. Naikkan jika host sudah mengikat 6379. Port internal container tetap 6379. | | `OMNIROUTE_REDIS_BIND_HOST` | `127.0.0.1` | `bin/cli/commands/redis.mjs` | Antarmuka host tempat peluncur Redis 1-klik mempublikasikan. Peluncur menjalankan Redis TANPA kata sandi, sehingga mengikat `0.0.0.0` memberi setiap host di LAN Anda akses Redis tanpa autentikasi — hanya perluas ini jika Anda juga mengatur kata sandi pada instance tersebut sendiri. | | `REDIS_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Antarmuka host tempat docker-compose mempublikasikan sidecar Redis (#9286). Redis compose berjalan tanpa `requirepass`; container aplikasi menjangkaunya melalui jaringan compose (`redis:6379`) — port yang dipublikasikan hanya ada untuk perkakas 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 mempublikasikan port dashboard/API/live-WS milik aplikasi (#12568). Dengan `REQUIRE_API_KEY=false` yang menjadi default `.env.example`, `0.0.0.0` mengekspos proxy LLM anonim `/v1` ke seluruh LAN/WAN — hanya perluas setelah `REQUIRE_API_KEY=true` atau reverse proxy di depannya menerapkan autentikasinya sendiri. | | `QDRANT_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Antarmuka host tempat docker-compose mempublikasikan sidecar memori Qdrant (#12578). Alasan eksposur LAN-nya sama seperti `REDIS_BIND_HOST`. | | `BIFROST_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Antarmuka host tempat docker-compose mempublikasikan sidecar router Bifrost (#12578). Alasan eksposur LAN-nya sama seperti `REDIS_BIND_HOST`. | | `REDIS_KEY_PREFIX` | `omniroute:` | `src/shared/utils/rateLimiter.ts` | Prefiks namespace yang diterapkan pada setiap key Redis OmniRoute (rate limiter, cache auth, penyimpanan kuota, circuit breaker warmup). Mencegah tabrakan key ketika instance Redis dipakai bersama aplikasi lain (#11042). | | `OMNIROUTE_INTERNAL_SERVICE_TOKEN` | _(tidak diatur — mekanisme dinonaktifkan)_ | `src/lib/api/internalServiceAuth.ts` | Rahasia bersama untuk hop REST internal yang mempertahankan identitas (#9260): komponen OmniRoute yang memanggil rute OmniRoute lokal lain mengirimkannya sebagai `x-omniroute-internal-service-token` sehingga identitas pemanggil asli tetap terjaga. Dibandingkan dengan `timingSafeEqual`. | | `OMNIROUTE_INTERNAL_SERVICE_TOKEN_FILE` | _(belum diatur)_ | `src/lib/api/internalServiceAuth.ts` | Varian berkas-rahasia dari token layanan internal: jalur ke berkas yang isinya (setelah di-trim) adalah token. Hanya digunakan ketika variabel inline tidak diatur. | | `OPENROUTER_PROVIDER_STATS_ENABLED` | `true` | `src/lib/catalog/openrouterProviderStats.ts` | Perkaya daftar penyedia di dasbor dengan statistik peringkat mingguan OpenRouter (#9324). Aktif secara default; atur ke `false` untuk melewati pengambilan latar belakang sepenuhnya (non-blocking, tidak pernah 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 opt-in)_ | Hostname sidecar Qdrant ketika `--profile memory` aktif. Default mengarah ke nama layanan qdrant dalam jaringan; ganti untuk deployment eksternal. Hanya digunakan ketika `qdrantEnabled` bernilai `true` dalam kode (`src/lib/memory/vectorStore.ts:108`). | | `QDRANT_PORT` | `6333` | _(profil klaster opt-in)_ | Port REST dari sidecar Qdrant. | | `QDRANT_GRPC_PORT` | `6334` | _(profil klaster opt-in)_ | Port gRPC dari sidecar Qdrant. Digunakan oleh pustaka klien yang lebih memilih gRPC daripada REST untuk operasi streaming. | | `QDRANT_API_KEY` | _(belum diatur)_ | _(profil klaster opt-in)_ | API key opsional untuk Qdrant Cloud atau instans on-prem yang terautentikasi. Kosong → tidak ada header `api-key` yang dikirim. | | `QDRANT_COLLECTION` | `omniroute-memory` | _(profil klaster opt-in)_ | 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 opt-in)_ | Nama model embedding default yang dicatat dalam metadata koleksi Qdrant. Embedding sebenarnya dihasilkan oleh penyedia apa pun yang ditunjuk oleh field `embeddingModel` di pengaturan OmniRoute. | | `QDRANT_VECTOR_SIZE` | `1536` | _(profil klaster opt-in)_ | Dimensi vektor embedding. Harus cocok dengan model yang Anda gunakan untuk embedding (text-embedding-3-small → 1536; ada-002 → 1536; nomic-embed-text → 768). | | `QDRANT_HNSW_EF_CONSTRUCT` | `128` | _(profil klaster opt-in)_ | Akurasi HNSW saat konstruksi indeks. 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 kelas `OMNIROUTE_ROTATE_*` di bawah yang memicu fallback akun (keadaan master-off juga memblokir kelas 429/500/502 yang aktif secara default). Memungkinkan front-end pengawas (mis. aplikasi desktop VibeProxy) mencerminkan aturan rotasinya sendiri ke mesin fallback akun backend. | | `OMNIROUTE_ROTATION_RATE_LIMIT_RESET_SECONDS` | `0` | `open-sse/services/rotationConfig.ts` | Cooldown (detik) yang diterapkan pada akun yang terkena rate limit ketika upstream tidak memberikan petunjuk reset eksplisit. `0` = gunakan cooldown default mesin alih-alih override tetap. | | `OMNIROUTE_ROTATION_DISABLE_TAG_WITHOUT_RESET` | `true` | `open-sse/services/rotationConfig.ts` | Cerminan preferensi front-end "jangan tandai sebagai rate-limited tanpa waktu reset". | | `OMNIROUTE_ROTATE_ON_429` | `true` | `open-sse/services/rotationConfig.ts` | Aktivasi fallback per status untuk error `429`. Saat `false` (dan `OMNIROUTE_ROTATION_ENABLED=true`), error `429` tidak lagi memicu rotasi akun dan justru dikembalikan ke klien. | | `OMNIROUTE_ROTATE_429_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Jumlah error `429` dalam `OMNIROUTE_ROTATE_429_WINDOW_SECONDS` yang diperlukan sebelum akun dirotasi. `1` (default) merotasi segera, mempertahankan perilaku historis. | | `OMNIROUTE_ROTATE_429_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Jendela geser (detik) di mana error `429` dihitung terhadap `OMNIROUTE_ROTATE_429_THRESHOLD`. | | `OMNIROUTE_ROTATE_ON_500` | `true` | `open-sse/services/rotationConfig.ts` | Aktivasi fallback per status untuk error server `5xx` (tidak termasuk `502`, yang memiliki kelasnya sendiri). Saat `false`, error ini tidak lagi memicu rotasi akun. | | `OMNIROUTE_ROTATE_500_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Jumlah error `5xx` dalam `OMNIROUTE_ROTATE_500_WINDOW_SECONDS` yang diperlukan sebelum akun dirotasi. `1` (default) merotasi segera. | | `OMNIROUTE_ROTATE_500_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Jendela geser (detik) tempat error `5xx` dihitung terhadap `OMNIROUTE_ROTATE_500_THRESHOLD`. | | `OMNIROUTE_ROTATE_ON_502` | `true` | `open-sse/services/rotationConfig.ts` | Pengaktifan fallback per status untuk error `502` (bad gateway). Ketika `false`, error `502` tidak lagi memicu rotasi akun. | | `OMNIROUTE_ROTATE_502_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Jumlah error `502` dalam `OMNIROUTE_ROTATE_502_WINDOW_SECONDS` yang diperlukan sebelum akun dirotasi. `1` (bawaan) langsung merotasi. | | `OMNIROUTE_ROTATE_502_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Jendela geser (detik) tempat error `502` dihitung terhadap `OMNIROUTE_ROTATE_502_THRESHOLD`. | | `OMNIROUTE_ROTATE_ON_400` | `false` | `open-sse/services/rotationConfig.ts` | Opt-in (bawaan NONAKTIF): ketika `true`, error `400` biasa (bad request) juga memicu rotasi akun. Ini hanya bersifat aditif — tidak pernah memblokir perilaku mesin yang sudah ada, di mana `400` yang membawa teks rate-limit/kuota tetap melakukan fallback terlepas dari flag ini. | | `OMNIROUTE_ROTATE_400_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Jumlah error `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 geser (detik) tempat error `400` dihitung terhadap `OMNIROUTE_ROTATE_400_THRESHOLD`. | ### Penjadwal Warmup Claude Warmup berbasis cron untuk koneksi Anthropic OAuth yang ikut serta (opt-in), sehingga jendela rate-limit 5 jam dibuka oleh permintaan terjadwal yang sederhana, bukan oleh permintaan nyata yang pertama (#8848). Penjadwal nonaktif kecuali `OMNIROUTE_WARMUP_ENABLED` bernilai truthy **dan** koneksi ditandai di `settings.claudeWarmup.connections`; daftar koneksi yang kosong berarti tidak ada yang di-warmup meskipun env var aktif. | Variable | Default | Source File | Description | | ------------------------------ | --------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OMNIROUTE_WARMUP_ENABLED` | _(tidak diatur → nonaktif)_ | `src/lib/warmupScheduler.ts` | Sakelar utama untuk penjadwal warmup. Menerima `1`/`true`/`yes`/`on` (tidak peka huruf besar/kecil, spasi dipangkas). Nilai lain apa pun, atau tidak diatur, membuat penjadwal tetap nonaktif. | | `OMNIROUTE_WARMUP_CRON` | `0 7 * * *` | `src/lib/warmupScheduler.ts` | Ekspresi cron lima kolom untuk tick warmup, dievaluasi dalam `America/Los_Angeles` (zona waktu reset Anthropic) terlepas dari jam host. | | `OMNIROUTE_WARMUP_CONCURRENCY` | `3` | `src/lib/warmupScheduler.ts` | Berapa banyak koneksi yang di-warm secara paralel per tick. Dibatasi ke rentang `1`-`10`; nilai non-numerik kembali ke `3`. | | `OMNIROUTE_WARMUP_MODEL` | `claude-3-5-haiku-20241022` | `src/lib/warmupScheduler.ts` | Model yang digunakan untuk permintaan warmup. Timpa hanya jika bawaan tidak tersedia pada paket Anda; pilih model termurah yang tetap membuka jendela. | ### Sesi VNC Browser-Login & Alias Data-Dir Chromium+VNC terkontainerisasi yang digunakan untuk penangkapan kredensial browser-login interaktif (`/api/vnc-session`), ditambah alias `DATA_DIR` lawas. Semuanya opsional — bawaan VNC menargetkan image bawaan `omniroute-vnc-chromium:local` dan hanya ditimpa untuk image kontainer kustom, port, atau penyetelan siklus hidup. | Variable | Default | Source File | Description | | ------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `OMNIROUTE_VNC_IMAGE` | `omniroute-vnc-chromium:local` | `src/lib/vncSession/manifest.ts` | Tag image Docker untuk kontainer login Chromium+VNC. Build `docker/vnc-browser/chromium` atau arahkan ini ke image kustom. | | `OMNIROUTE_DOCKER_BIN` | `docker` | `src/lib/vncSession/manifest.ts` | Biner runtime kontainer yang digunakan untuk meluncurkan kontainer VNC (mis. atur ke `podman`). | | `OMNIROUTE_VNC_CONTAINER_VNC_PORT` | `3000` | `src/lib/vncSession/manifest.ts` | Port VNC/noVNC yang diekspos 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` | Jalur direktori profil Chromium di dalam kontainer. | | `OMNIROUTE_VNC_PROFILE_DIR` | `$HOME/.omniroute/browser-login-profiles` | `src/lib/vncSession/manifest.ts` | Direktori host yang menyimpan profil browser-login yang dipersistensikan. | | `OMNIROUTE_VNC_IDLE_MS` | `600000` (10 menit) | `src/lib/vncSession/manifest.ts` | Batas waktu idle (ms) sebelum sesi VNC yang tidak aktif dihentikan. | | `OMNIROUTE_VNC_MAX_MS` | `1800000` (30 menit) | `src/lib/vncSession/manifest.ts` | Batas keras (ms) pada masa hidup satu sesi VNC. | | `OMNIROUTE_VNC_MAX_SESSIONS` | `4` | `src/lib/vncSession/manifest.ts` | Jumlah maksimum sesi VNC bersamaan. | | `OMNIROUTE_VNC_READY_MS` | `45000` | `src/lib/vncSession/manifest.ts` | Batas waktu (ms) menunggu peramban dalam kontainer menjadi siap-CDP. | | `OMNIROUTE_VNC_HARVEST_MS` | `20000` | `src/lib/vncSession/manifest.ts` | Batas waktu (ms) untuk memanen sesi/cookie yang ditangkap setelah 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 kontainer. | | `OMNIROUTE_VNC_NETWORK` | `omniroute-vnc-browser-login` | `src/lib/vncSession/manifest.ts` | Jaringan Docker khusus yang diikuti kontainer login VNC (#12571) alih-alih bridge bawaan, sehingga kontainer sejajar tidak dapat menjangkau port bridge CDP-nya. | | `VIBEPROXY_DATA_DIR` | _(tidak diatur)_ | `open-sse/services/notionThreadSessions.ts` | **Alias lawas** untuk `DATA_DIR`, hanya diperiksa setelah `DATA_DIR` dan `OMNIROUTE_DATA_DIR` keduanya tidak diatur. Menemukan cache sesi web-thread 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 setiap nilai di bawah ini tidak diatur pada 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` | fallback ke `INITIAL_PASSWORD` | `scripts/dev/run-next-playwright.mjs` | Kata sandi admin yang disuntikkan ke lingkungan Playwright. | | `OMNIROUTE_DISABLE_LOCAL_HEALTHCHECK` | `true` | `scripts/dev/run-next-playwright.mjs` | Nonaktifkan polling healthcheck lokal selama proses Playwright. | | `OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK` | `true` | `scripts/dev/run-next-playwright.mjs` | Nonaktifkan loop healthcheck token OAuth selama pengujian. | | `OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS` | _(tidak diatur)_ | `src/lib/tokenHealthCheck.ts` | Provider yang dipisahkan koma dan dikecualikan dari penyapuan token-refresh proaktif (mis. `codex,openai`). Alternatif tertarget dibanding menonaktifkan healthcheck sepenuhnya — provider ber-TTL pendek tetap melakukan refresh sementara provider cascade tetap bersifat reaktif saja. | | `OMNIROUTE_HIDE_HEALTHCHECK_LOGS` | `true` | `scripts/dev/run-next-playwright.mjs` | Senyapkan noise healthcheck di stdout Playwright. | | `OMNIROUTE_PLAYWRIGHT_SKIP_BUILD` | `0` | `scripts/dev/run-next-playwright.mjs` | Lewati build produksi Next.js sebelum Playwright dimulai (optimasi CI). | | `OMNIROUTE_SKIP_UNINSTALL_HOOK` | `0` | `scripts/build/uninstall.mjs` | Lewati hook uninstall OmniRoute (digunakan 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 smoke harness Electron untuk dilayani oleh aplikasi terpaket. | | `ELECTRON_SMOKE_TIMEOUT_MS` | `45000` | `scripts/dev/smoke-electron-packaged.mjs` | Timeout total (ms) sebelum smoke harness menyerah. | | `ELECTRON_SMOKE_SETTLE_MS` | `2000` | `scripts/dev/smoke-electron-packaged.mjs` | Jendela settle (ms) setelah halaman dimuat. | | `ELECTRON_SMOKE_APP_EXECUTABLE` | _(otomatis)_ | `scripts/dev/smoke-electron-packaged.mjs` | Path eksplisit ke executable Electron terpaket. | | `ELECTRON_SMOKE_DATA_DIR` | _(direktori sementara)_ | `scripts/dev/smoke-electron-packaged.mjs` | Direktori data untuk proses smoke Electron. | | `ELECTRON_SMOKE_KEEP_DATA` | `0` | `scripts/dev/smoke-electron-packaged.mjs` | Atur `1` untuk mempertahankan direktori data smoke setelah proses berjalan. | | `ELECTRON_SMOKE_STREAM_LOGS` | `0` | `scripts/dev/smoke-electron-packaged.mjs` | Atur `1` untuk mengalirkan log Electron ke stdout selama proses berjalan. | | `ELECTRON_SMOKE_COLD_RESTART` | `0` | `scripts/dev/smoke-electron-packaged.mjs` | #7592: luncurkan ulang terhadap 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 terjemahan dokumen Digunakan oleh `scripts/i18n/run-translation.mjs` (perintah `npm run i18n:run`). Keenam variabel ini tidak diatur secara default — atur di `.env` hanya pada mesin yang seharusnya dapat menjalankan penerjemah dokumen. | Variabel | Default | File Sumber | Deskripsi | | ---------------------------------------- | ---------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OMNIROUTE_TRANSLATION_API_URL` | _(tidak diatur)_ | `scripts/i18n/run-translation.mjs` | URL dasar yang kompatibel dengan OpenAI untuk backend terjemahan. | | `OMNIROUTE_TRANSLATION_API_KEY` | _(tidak diatur)_ | `scripts/i18n/run-translation.mjs` | Token bearer untuk backend terjemahan (tidak pernah dicatat). | | `OMNIROUTE_TRANSLATION_MODEL` | _(tidak diatur)_ | `scripts/i18n/run-translation.mjs` | ID model, mis. `gpt-4o-mini` atau `cx/gpt-5.4-mini`. | | `OMNIROUTE_TRANSLATION_FALLBACK_MODELS` | _(tidak diatur)_ | `scripts/i18n/lib/translate-backend.mjs` | Rantai model opsional yang dipisahkan koma, dicoba berurutan ketika model utama gagal (kuota 429, 401/402, 5xx, timeout, jaringan); permintaan yang salah format (400/413/422) tidak dicoba ulang di tempat lain. | | `OMNIROUTE_TRANSLATION_TIMEOUT_MS` | `60000` | `scripts/i18n/run-translation.mjs` | Timeout per permintaan dalam milidetik. | | `OMNIROUTE_TRANSLATION_REASONING_EFFORT` | _(tidak diatur)_ | `scripts/i18n/lib/translate-backend.mjs` | Kontrol reasoning opsional, dikirim apa adanya ke backend saat diatur. | | `OMNIROUTE_TRANSLATION_CONCURRENCY` | `4` | `scripts/i18n/run-translation.mjs` | Permintaan terjemahan paralel saat berjalan pada beberapa file / locale. | --- ## 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 environment 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 `503` yang dapat dicoba ulang; waktu tunggu singkat yang dibatasi menserialkan lonjakan agen alih-alih `503` seketika. `0` mengembalikan penolakan langsung. | | `OMNIROUTE_CHAT_ADMISSION_MAX_QUEUED_BYTES` | `4194304` (4 MB) | `src/shared/middleware/chatBodyAdmission.ts` | Anggaran byte-antre untuk waktu tunggu penerimaan: membatasi total byte body yang dibuffer dan ditahan di seluruh proses sehingga waktu tunggu tidak dapat memperbesar heap (#4380). Waktu tunggu yang melebihi anggaran segera menerima `503` yang dapat dicoba ulang. | | `OMNIROUTE_CHAT_VIRTUAL_TTL_MS` | `60000` (60 s) | `src/shared/middleware/chatBodyAdmission.ts` | No-op usang sejak #10110: jalur penerimaan per sesi telah dihapus dan digantikan oleh satu anggaran di seluruh proses. Diterima demi kompatibilitas konfigurasi; diabaikan. | | `OMNIROUTE_CHAT_VIRTUAL_MAX_SESSIONS` | `64` | `src/shared/middleware/chatBodyAdmission.ts` | No-op usang sejak #10110: jalur penerimaan per sesi telah dihapus dan digantikan oleh satu anggaran di seluruh proses. Diterima demi kompatibilitas konfigurasi; diabaikan. | | `OMNIROUTE_CHAT_VIRTUAL_LANES` | `0` (nonaktif) | `open-sse/services/admission/runtime.ts` | Jalur penerimaan virtual runtime adaptif (#9654): saklar utama untuk gerbang adaptif per tenant (sistem 2). Berbeda dari variabel jalur per koneksi yang usang di atas (TTL_MS / MAX_SESSIONS, no-op sejak #10110). Flag fitur Dashboard dengan nama yang sama; variabel env mengalahkan penggantian dashboard; memerlukan restart. | | `OMNIROUTE_RUNNOW_TIMEOUT_MS` | `30000` | `src/app/api/jobs/[id]/run-now/route.ts` | Membatasi berapa lama panggilan run-now menunggu job yang sedang berjalan sebelum memulai run yang diantrekan. | | `ADOBE_FIREFLY_BROWSER_REFRESH` | aktif | `open-sse/services/adobeFireflySession.ts` | Menjaga status IMS dan risiko browser tetap segar melalui sesi Chrome CDP lingkup akun; atur `0` untuk menonaktifkan. | | `ADOBE_FIREFLY_SESSION_DISK` | aktif | `open-sse/services/adobeFireflySession.ts` | Menyimpan sesi Adobe yang diperbaiki di bawah `DATA_DIR`; atur `0` untuk status hanya di memori. | | `ADOBE_FIREFLY_MIN_SUBMIT_GAP_MS` | `12000` | `open-sse/services/adobeFireflySession.ts` | Jarak minimum antara pengiriman generate Adobe Firefly. | | `ADOBE_FIREFLY_BATCH_EXTRA_GAP_MS` | `15000` | `open-sse/services/adobeFireflySession.ts` | Periode tenang ekstra setelah setiap pengiriman Adobe ketiga yang berhasil. | | `ADOBE_FIREFLY_CHROME_HEADLESS` | `0` | `open-sse/services/adobeFireflyBrowserLogin.ts` | Mode true-headless 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` | Executable Chrome absolut opsional yang digunakan oleh executor berbasis browser ketika deteksi otomatis platform tidak memadai. | | `TELEGRAM_BOT_TOKEN` | _(tidak diatur)_ | `src/lib/telegram/config.ts` | Token BotFather yang mengaktifkan webhook masuk dan menandatangani `initData` Mini App. | | `TELEGRAM_WEBHOOK_SECRET` | _(tidak diatur)_ | `src/lib/telegram/config.ts` | Secret bersama yang didaftarkan melalui `setWebhook` dan diverifikasi terhadap header `X-Telegram-Bot-Api-Secret-Token` pada setiap pengiriman webhook. Diperlukan untuk jalur webhook; tidak diatur berarti 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 proxy atau server Bot API yang di-hosting 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` (aktif) | `scripts/build/optionalPackStaging.mjs` | Atur `0` untuk melewati pembuatan tarball `.tar.gz` saat men-staging paket ML/browser opsional untuk pohon standalone Electron (direktori paket dan `optional-packs.index.json` tetap dihasilkan). Digunakan oleh alur kerja rilis desktop untuk memangkas ukuran unggahan artefak. | | `GROK_SUBSCRIPTION_IMAGES_ENABLED` | `false` | `open-sse/config/imageRegistry.ts` | Mengaktifkan pendaftaran rute gambar langganan xAI; dinonaktifkan secara default sehingga jalur gambar API-key tetap tidak berubah. | | `OMNIROUTE_API_KEY_COOLDOWN_MS` | `60000` | `open-sse/services/apiKeyRotator.ts` | Cooldown per kunci dalam milidetik ketika respons `429` tidak memiliki petunjuk `Retry-After` yang dapat digunakan. | | `OMNIROUTE_ESTIMATOR_CALIBRATION` | aktif | `open-sse/services/estimatorCalibration.ts` | Atur ke `off`, `0`, atau `false` untuk menonaktifkan pencatatan dan penerapan kalibrasi estimator dalam memori. | | `NEXT_MANUAL_SIG_HANDLE` | _(internal)_ | `scripts/dev/standalone-server-ws.mjs` | Penggantian signal-handler server standalone internal; biasanya diatur dan dihapus oleh launcher, bukan dikonfigurasi oleh operator. | ### ChatGPT Web (Codex) Default global untuk browser headless dan tunnel tool keluar. Nilai koneksi yang diatur di Dashboard lebih diutamakan. | Variabel | Default | File Sumber | Deskripsi | | --------------------------------------- | ------------------------------ | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `CHATGPT_WEB_CODEX_CHROME_PATH` | _(deteksi otomatis)_ | `open-sse/executors/chatgpt-web-codex.ts` | Path Chrome/Chromium eksplisit untuk operasi npm, systemd, dan PM2. | | `CHROME_PATH` | _(deteksi otomatis)_ | `open-sse/executors/chatgpt-web-codex.ts` | Fallback bersama untuk path 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`. | | `CHATGPT_WEB_CODEX_USE_CDP_PROFILE` | _(belum diatur — nonaktif)_ | `open-sse/vendor/codex-chatgpt-web/persistent-cdp-context.ts` | Atur ke `1` (dengan endpoint CDP yang dikonfigurasi) untuk menggunakan kembali halaman ChatGPT yang sudah ada dari profil browser yang dikelola secara eksternal dan telah masuk, alih-alih konteks terisolasi per giliran; juga membatasi tab ChatGPT bersamaan maksimal 1. Nonaktif secara default. Lihat [profil CDP persisten](../guides/CHATGPT-WEB-PERSISTENT-CDP.md). | | `CDP_PROXY_TOKEN` | _(belum diatur)_ | `docker/chatgpt-web-codex-browser/cdp-proxy.mjs` | Jika diatur, setiap permintaan ke sidecar CDP proxy harus menyertakan nilai ini di header `X-Omni-Cdp-Token` (#13679). Tanpa nilai, proxy meneruskan tanpa autentikasi — dalam hal ini hanya isolasi jaringan dari jaringan Compose `chatgpt-web-codex-net` yang memberikan perlindungan. 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 ronde tool Codex lokal. | | `CHATGPT_WEB_CODEX_RUNTIME_KEY` | _(belum diatur)_ | `open-sse/executors/chatgpt-web-codex.ts` | Runtime key tunnel global; jangan pernah ditampilkan di log. | | `CHATGPT_WEB_CODEX_CONNECTOR_NAME` | `OmniRoute Codex v2` | `open-sse/executors/chatgpt-web-codex.ts` | Nama persis dari custom connector ChatGPT yang baru dibuat untuk jembatan 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` | Pada `1`, gambar diagnostik browser diambil di setiap checkpoint. | | `CODEX_CHATGPT_WEB_LAUNCHER` | _(belum diatur)_ | `open-sse/vendor/codex-chatgpt-web/config.ts` | Path absolut opsional ke binary launcher permanen. | | `CODEX_CHATGPT_WEB_BUN` | _(deteksi otomatis)_ | `open-sse/vendor/codex-chatgpt-web/config.ts` | Path absolut opsional ke binary runtime Bun. | | `CODEX_WEB_GPT_BUN` | _(belum diatur)_ | `open-sse/vendor/codex-chatgpt-web/config.ts` | Fallback legacy untuk `CODEX_CHATGPT_WEB_BUN`; setup baru menggunakan nama kanonik. | --- ## OmniConductor Bridge Konsumen SSE berumur panjang yang mencerminkan tugas-tugas hub OmniConductor ke TaskManager A2A lokal (`src/lib/conductor/`). Bersifat opt-in — bridge hanya dimulai ketika `CONDUCTOR_HUB_URL` diatur. Hanya sisi server: token hub tidak boleh pernah sampai ke browser. | Variabel | Bawaan | Berkas Sumber | Deskripsi | | ------------------------------ | ----------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `CONDUCTOR_HUB_URL` | _(kosong)_ | `src/lib/conductor/boot.ts` | URL dasar hub OmniConductor (mis. `http://127.0.0.1:7910`). Tidak diatur = bridge dinonaktifkan. | | `CONDUCTOR_HUB_TOKEN` | _(kosong)_ | `src/lib/conductor/boot.ts` | Kredensial hub untuk feed SSE — terbitkan peer berjenis `spokesperson` pada hub (`POST /v1/peers`, admin). | | `CONDUCTOR_ORCHESTRATOR_TOKEN` | _(kosong)_ | `src/lib/conductor/hubProxy.ts` | Kredensial untuk delegasi tugas A2A→hub masuk (`POST /v1/tasks`); kembali menggunakan `CONDUCTOR_HUB_TOKEN` bila tidak diatur. | | `CONDUCTOR_SPOKESPERSON_URL` | `http://127.0.0.1:7920` | `src/lib/conductor/faroProxy.ts` | URL dasar layanan spokesperson (Faro) di balik proksi chat dashboard (`/api/conductor/ask`). | ### Penjadwalan peka kuota Digunakan oleh `open-sse/services/combo.ts` dan `src/lib/quota/quotaScheduler.ts` untuk pemeriksaan anggaran token pra-permintaan. Bersifat opt-in — perilaku perutean bawaan tidak berubah bila tidak diatur. | Variabel | Bawaan | Berkas Sumber | Deskripsi | | ---------------------------------- | --------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OMNIROUTE_QUOTA_AWARE_ROUTING` | `0` | `open-sse/services/combo.ts` | Bila `1`, lewati koneksi yang anggaran token per jendelanya (`rateLimitOverrides.tpm`, tabel `provider_quota_state`) tidak mampu menanggung perkiraan biaya permintaan sebelum pengiriman. Bersifat fail-open bila tidak ada anggaran yang dikonfigurasi. | | `OMNIROUTE_ESTIMATOR_CALIBRATION` | _(aktif)_ | `open-sse/services/estimatorCalibration.ts` | Kalibrasi umpan balik untuk estimator token context-guard (#14931): EMA per (provider, model, tools yang tersedia) dari `usage.prompt_tokens` / estimasi, dibatasi pada 0.15–2.0, hanya di memori. `off`, `0` atau `false` menonaktifkan pencatatan dan penerapannya. | | `GROK_SUBSCRIPTION_IMAGES_ENABLED` | `false` | `open-sse/config/imageRegistry.ts` | Mendaftarkan rute gambar `xai-oauth` (`xao`) dan `grok-cli`. Feature flag dashboard dengan nama yang sama; override DB akan mengalahkan nilai ini. |