diff --git a/docs/i18n/id/CODE_OF_CONDUCT.md b/docs/i18n/id/CODE_OF_CONDUCT.md
index 7c95a80f5d..6219f74923 100644
--- a/docs/i18n/id/CODE_OF_CONDUCT.md
+++ b/docs/i18n/id/CODE_OF_CONDUCT.md
@@ -1,132 +1,89 @@
-# Contributor Covenant Code of Conduct (Bahasa Indonesia)
+# Kode Etik Contributor Covenant (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../CODE_OF_CONDUCT.md) · 🇸🇦 [ar](../ar/CODE_OF_CONDUCT.md) · 🇧🇬 [bg](../bg/CODE_OF_CONDUCT.md) · 🇧🇩 [bn](../bn/CODE_OF_CONDUCT.md) · 🇨🇿 [cs](../cs/CODE_OF_CONDUCT.md) · 🇩🇰 [da](../da/CODE_OF_CONDUCT.md) · 🇩🇪 [de](../de/CODE_OF_CONDUCT.md) · 🇪🇸 [es](../es/CODE_OF_CONDUCT.md) · 🇮🇷 [fa](../fa/CODE_OF_CONDUCT.md) · 🇫🇮 [fi](../fi/CODE_OF_CONDUCT.md) · 🇫🇷 [fr](../fr/CODE_OF_CONDUCT.md) · 🇮🇳 [gu](../gu/CODE_OF_CONDUCT.md) · 🇮🇱 [he](../he/CODE_OF_CONDUCT.md) · 🇮🇳 [hi](../hi/CODE_OF_CONDUCT.md) · 🇭🇺 [hu](../hu/CODE_OF_CONDUCT.md) · 🇮🇩 [id](../id/CODE_OF_CONDUCT.md) · 🇮🇹 [it](../it/CODE_OF_CONDUCT.md) · 🇯🇵 [ja](../ja/CODE_OF_CONDUCT.md) · 🇰🇷 [ko](../ko/CODE_OF_CONDUCT.md) · 🇮🇳 [mr](../mr/CODE_OF_CONDUCT.md) · 🇲🇾 [ms](../ms/CODE_OF_CONDUCT.md) · 🇳🇱 [nl](../nl/CODE_OF_CONDUCT.md) · 🇳🇴 [no](../no/CODE_OF_CONDUCT.md) · 🇵🇭 [phi](../phi/CODE_OF_CONDUCT.md) · 🇵🇱 [pl](../pl/CODE_OF_CONDUCT.md) · 🇵🇹 [pt](../pt/CODE_OF_CONDUCT.md) · 🇧🇷 [pt-BR](../pt-BR/CODE_OF_CONDUCT.md) · 🇷🇴 [ro](../ro/CODE_OF_CONDUCT.md) · 🇷🇺 [ru](../ru/CODE_OF_CONDUCT.md) · 🇸🇰 [sk](../sk/CODE_OF_CONDUCT.md) · 🇸🇪 [sv](../sv/CODE_OF_CONDUCT.md) · 🇰🇪 [sw](../sw/CODE_OF_CONDUCT.md) · 🇮🇳 [ta](../ta/CODE_OF_CONDUCT.md) · 🇮🇳 [te](../te/CODE_OF_CONDUCT.md) · 🇹🇭 [th](../th/CODE_OF_CONDUCT.md) · 🇹🇷 [tr](../tr/CODE_OF_CONDUCT.md) · 🇺🇦 [uk-UA](../uk-UA/CODE_OF_CONDUCT.md) · 🇵🇰 [ur](../ur/CODE_OF_CONDUCT.md) · 🇻🇳 [vi](../vi/CODE_OF_CONDUCT.md) · 🇨🇳 [zh-CN](../zh-CN/CODE_OF_CONDUCT.md)
---
-## Our Pledge
+## Ikrar Kami
-We as members, contributors, and leaders pledge to make participation in our
-community a harassment-free experience for everyone, regardless of age, body
-size, visible or invisible disability, ethnicity, sex characteristics, gender
-identity and expression, level of experience, education, socio-economic status,
-nationality, personal appearance, race, religion, or sexual identity
-and orientation.
+Kami sebagai anggota, kontributor, dan pemimpin berjanji untuk menjadikan partisipasi dalam komunitas kami sebagai pengalaman yang bebas dari pelecehan bagi semua orang, tanpa memandang usia, ukuran tubuh, disabilitas yang terlihat maupun tidak terlihat, etnisitas, karakteristik seks, identitas dan ekspresi gender, tingkat pengalaman, pendidikan, status sosial-ekonomi, kebangsaan, penampilan pribadi, ras, agama, atau identitas dan orientasi seksual.
-We pledge to act and interact in ways that contribute to an open, welcoming,
-diverse, inclusive, and healthy community.
+Kami berjanji untuk bertindak dan berinteraksi dengan cara yang berkontribusi pada komunitas yang terbuka, ramah, beragam, inklusif, dan sehat.
-## Our Standards
+## Standar Kami
-Examples of behavior that contributes to a positive environment for our
-community include:
+Contoh perilaku yang berkontribusi pada lingkungan yang positif bagi komunitas kami meliputi:
-- Demonstrating empathy and kindness toward other people
-- Being respectful of differing opinions, viewpoints, and experiences
-- Giving and gracefully accepting constructive feedback
-- Accepting responsibility and apologizing to those affected by our mistakes,
- and learning from the experience
-- Focusing on what is best not just for us as individuals, but for the
- overall community
+- Menunjukkan empati dan kebaikan terhadap orang lain
+- Menghormati pendapat, sudut pandang, dan pengalaman yang berbeda
+- Memberikan dan menerima umpan balik yang konstruktif dengan lapang dada
+- Menerima tanggung jawab dan meminta maaf kepada mereka yang terdampak oleh kesalahan kita, serta belajar dari pengalaman tersebut
+- Berfokus pada apa yang terbaik bukan hanya bagi kita sebagai individu, tetapi bagi komunitas secara keseluruhan
-Examples of unacceptable behavior include:
+Contoh perilaku yang tidak dapat diterima meliputi:
-- The use of sexualized language or imagery, and sexual attention or
- advances of any kind
-- Trolling, insulting or derogatory comments, and personal or political attacks
-- Public or private harassment
-- Publishing others' private information, such as a physical or email
- address, without their explicit permission
-- Other conduct which could reasonably be considered inappropriate in a
- professional setting
+- Penggunaan bahasa atau citra yang bersifat seksual, serta perhatian atau rayuan seksual dalam bentuk apa pun
+- Trolling, komentar menghina atau merendahkan, serta serangan pribadi atau politis
+- Pelecehan di ranah publik maupun privat
+- Mempublikasikan informasi pribadi orang lain, seperti alamat fisik atau email, tanpa izin eksplisit mereka
+- Perilaku lain yang secara wajar dapat dianggap tidak pantas dalam lingkungan profesional
-## Enforcement Responsibilities
+## Tanggung Jawab Penegakan
-Community leaders are responsible for clarifying and enforcing our standards of
-acceptable behavior and will take appropriate and fair corrective action in
-response to any behavior that they deem inappropriate, threatening, offensive,
-or harmful.
+Pemimpin komunitas bertanggung jawab untuk mengklarifikasi dan menegakkan standar perilaku yang dapat diterima, serta akan mengambil tindakan korektif yang tepat dan adil sebagai respons terhadap perilaku apa pun yang mereka anggap tidak pantas, mengancam, menyinggung, atau merugikan.
-Community leaders have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions that are
-not aligned to this Code of Conduct, and will communicate reasons for moderation
-decisions when appropriate.
+Pemimpin komunitas memiliki hak dan tanggung jawab untuk menghapus, mengedit, atau menolak komentar, commit, kode, suntingan wiki, isu, dan kontribusi lain yang tidak sesuai dengan Kode Etik ini, serta akan mengomunikasikan alasan keputusan moderasi bila diperlukan.
-## Scope
+## Cakupan
-This Code of Conduct applies within all community spaces, and also applies when
-an individual is officially representing the community in public spaces.
-Examples of representing our community include using an official e-mail address,
-posting via an official social media account, or acting as an appointed
-representative at an online or offline event.
+Kode Etik ini berlaku di semua ruang komunitas, dan juga berlaku ketika seseorang secara resmi mewakili komunitas di ruang publik. Contoh perwakilan komunitas kita meliputi penggunaan alamat email resmi, posting melalui akun media sosial resmi, atau bertindak sebagai perwakilan yang ditunjuk pada acara daring maupun luring.
-## Enforcement
+## Penegakan
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported to the community leaders responsible for enforcement at
+Kasus perilaku kasar, melecehkan, atau tidak dapat diterima lainnya dapat dilaporkan kepada pemimpin komunitas yang bertanggung jawab atas penegakan di
.
-All complaints will be reviewed and investigated promptly and fairly.
+Semua pengaduan akan ditinjau dan diselidiki dengan segera dan adil.
-All community leaders are obligated to respect the privacy and security of the
-reporter of any incident.
+Semua pemimpin komunitas berkewajiban untuk menghormati privasi dan keamanan pelapor dari setiap insiden.
-## Enforcement Guidelines
+## Pedoman Penegakan
-Community leaders will follow these Community Impact Guidelines in determining
-the consequences for any action they deem in violation of this Code of Conduct:
+Pemimpin komunitas akan mengikuti Pedoman Dampak Komunitas ini dalam menentukan konsekuensi atas setiap tindakan yang mereka anggap melanggar Kode Etik ini:
-### 1. Correction
+### 1. Koreksi
-**Community Impact**: Use of inappropriate language or other behavior deemed
-unprofessional or unwelcome in the community.
+**Dampak Komunitas**: Penggunaan bahasa yang tidak pantas atau perilaku lain yang dianggap tidak profesional atau tidak diinginkan dalam komunitas.
-**Consequence**: A private, written warning from community leaders, providing
-clarity around the nature of the violation and an explanation of why the
-behavior was inappropriate. A public apology may be requested.
+**Konsekuensi**: Peringatan tertulis secara privat dari pemimpin komunitas, yang memberikan kejelasan mengenai sifat pelanggaran dan penjelasan mengapa perilaku tersebut tidak pantas. Permohonan maaf secara publik mungkin diminta.
-### 2. Warning
+### 2. Peringatan
-**Community Impact**: A violation through a single incident or series
-of actions.
+**Dampak Komunitas**: Pelanggaran melalui satu insiden atau serangkaian tindakan.
-**Consequence**: A warning with consequences for continued behavior. No
-interaction with the people involved, including unsolicited interaction with
-those enforcing the Code of Conduct, for a specified period of time. This
-includes avoiding interactions in community spaces as well as external channels
-like social media. Violating these terms may lead to a temporary or
-permanent ban.
+**Konsekuensi**: Peringatan dengan konsekuensi apabila perilaku tersebut berlanjut. Tidak ada interaksi dengan pihak-pihak yang terlibat, termasuk interaksi yang tidak diminta dengan mereka yang menegakkan Kode Etik, selama jangka waktu tertentu. Hal ini mencakup penghindaran interaksi di ruang komunitas maupun di saluran eksternal seperti media sosial. Melanggar ketentuan ini dapat mengakibatkan larangan sementara atau permanen.
-### 3. Temporary Ban
+### 3. Larangan Sementara
-**Community Impact**: A serious violation of community standards, including
-sustained inappropriate behavior.
+**Dampak Komunitas**: Pelanggaran serius terhadap standar komunitas, termasuk perilaku tidak pantas yang berkelanjutan.
-**Consequence**: A temporary ban from any sort of interaction or public
-communication with the community for a specified period of time. No public or
-private interaction with the people involved, including unsolicited interaction
-with those enforcing the Code of Conduct, is allowed during this period.
-Violating these terms may lead to a permanent ban.
+**Konsekuensi**: Larangan sementara dari segala bentuk interaksi atau komunikasi publik dengan komunitas selama jangka waktu tertentu. Tidak ada interaksi publik maupun privat dengan pihak-pihak yang terlibat, termasuk interaksi yang tidak diminta dengan mereka yang menegakkan Kode Etik, yang diizinkan selama periode ini. Melanggar ketentuan ini dapat mengakibatkan larangan permanen.
-### 4. Permanent Ban
+### 4. Larangan Permanen
-**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior, harassment of an
-individual, or aggression toward or disparagement of classes of individuals.
+**Dampak Komunitas**: Menunjukkan pola pelanggaran standar komunitas, termasuk perilaku tidak pantas yang berkelanjutan, pelecehan terhadap individu, atau agresi terhadap atau penghinaan kepada golongan individu tertentu.
-**Consequence**: A permanent ban from any sort of public interaction within
-the community.
+**Konsekuensi**: Larangan permanen dari segala bentuk interaksi publik dalam komunitas.
-## Attribution
+## Atribusi
-This Code of Conduct is adapted from the [Contributor Covenant][homepage],
-version 2.0, available at
+Kode Etik ini diadaptasi dari [Contributor Covenant][homepage],
+versi 2.0, tersedia di
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
-Community Impact Guidelines were inspired by [Mozilla's code of conduct
-enforcement ladder](https://github.com/mozilla/diversity).
+Pedoman Dampak Komunitas terinspirasi dari [tangga penegakan kode etik Mozilla](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
-For answers to common questions about this code of conduct, see the FAQ at
-https://www.contributor-covenant.org/faq. Translations are available at
+Untuk jawaban atas pertanyaan umum tentang kode etik ini, lihat FAQ di
+https://www.contributor-covenant.org/faq. Terjemahan tersedia di
https://www.contributor-covenant.org/translations.
diff --git a/docs/i18n/id/CONTRIBUTING.md b/docs/i18n/id/CONTRIBUTING.md
index b1a724553a..fea9c9b7c2 100644
--- a/docs/i18n/id/CONTRIBUTING.md
+++ b/docs/i18n/id/CONTRIBUTING.md
@@ -1,22 +1,22 @@
-# Contributing to OmniRoute (Bahasa Indonesia)
+# Berkontribusi ke OmniRoute (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../CONTRIBUTING.md) · 🇸🇦 [ar](../ar/CONTRIBUTING.md) · 🇧🇬 [bg](../bg/CONTRIBUTING.md) · 🇧🇩 [bn](../bn/CONTRIBUTING.md) · 🇨🇿 [cs](../cs/CONTRIBUTING.md) · 🇩🇰 [da](../da/CONTRIBUTING.md) · 🇩🇪 [de](../de/CONTRIBUTING.md) · 🇪🇸 [es](../es/CONTRIBUTING.md) · 🇮🇷 [fa](../fa/CONTRIBUTING.md) · 🇫🇮 [fi](../fi/CONTRIBUTING.md) · 🇫🇷 [fr](../fr/CONTRIBUTING.md) · 🇮🇳 [gu](../gu/CONTRIBUTING.md) · 🇮🇱 [he](../he/CONTRIBUTING.md) · 🇮🇳 [hi](../hi/CONTRIBUTING.md) · 🇭🇺 [hu](../hu/CONTRIBUTING.md) · 🇮🇩 [id](../id/CONTRIBUTING.md) · 🇮🇹 [it](../it/CONTRIBUTING.md) · 🇯🇵 [ja](../ja/CONTRIBUTING.md) · 🇰🇷 [ko](../ko/CONTRIBUTING.md) · 🇮🇳 [mr](../mr/CONTRIBUTING.md) · 🇲🇾 [ms](../ms/CONTRIBUTING.md) · 🇳🇱 [nl](../nl/CONTRIBUTING.md) · 🇳🇴 [no](../no/CONTRIBUTING.md) · 🇵🇭 [phi](../phi/CONTRIBUTING.md) · 🇵🇱 [pl](../pl/CONTRIBUTING.md) · 🇵🇹 [pt](../pt/CONTRIBUTING.md) · 🇧🇷 [pt-BR](../pt-BR/CONTRIBUTING.md) · 🇷🇴 [ro](../ro/CONTRIBUTING.md) · 🇷🇺 [ru](../ru/CONTRIBUTING.md) · 🇸🇰 [sk](../sk/CONTRIBUTING.md) · 🇸🇪 [sv](../sv/CONTRIBUTING.md) · 🇰🇪 [sw](../sw/CONTRIBUTING.md) · 🇮🇳 [ta](../ta/CONTRIBUTING.md) · 🇮🇳 [te](../te/CONTRIBUTING.md) · 🇹🇭 [th](../th/CONTRIBUTING.md) · 🇹🇷 [tr](../tr/CONTRIBUTING.md) · 🇺🇦 [uk-UA](../uk-UA/CONTRIBUTING.md) · 🇵🇰 [ur](../ur/CONTRIBUTING.md) · 🇻🇳 [vi](../vi/CONTRIBUTING.md) · 🇨🇳 [zh-CN](../zh-CN/CONTRIBUTING.md)
---
-Thank you for your interest in contributing! This guide covers everything you need to get started.
+Terima kasih atas minat Anda untuk berkontribusi! Panduan ini mencakup semua yang perlu Anda ketahui untuk memulai.
---
-## Development Setup
+## Pengaturan Pengembangan
-### Prerequisites
+### Persyaratan
- **Node.js** >= 18 < 24 (recommended: 22 LTS)
- **npm** 10+
- **Git**
-### Clone & Install
+### Kloning & Instalasi
```bash
git clone https://github.com/diegosouzapw/OmniRoute.git
@@ -24,7 +24,7 @@ cd OmniRoute
npm install
```
-### Environment Variables
+### Variabel Lingkungan
```bash
# Create your .env from the template
@@ -35,28 +35,28 @@ echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env
```
-Key variables for development:
+Variabel-variabel utama untuk pengembangan:
-| Variable | Development Default | Description |
-| ---------------------- | ------------------------ | --------------------- |
-| `PORT` | `20128` | Server port |
-| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Base URL for frontend |
-| `JWT_SECRET` | (generate above) | JWT signing secret |
-| `INITIAL_PASSWORD` | `CHANGEME` | First login password |
-| `APP_LOG_LEVEL` | `info` | Log verbosity level |
+| Variable | Development Default | Deskripsi |
+| ---------------------- | ------------------------ | --------------------------------- |
+| `PORT` | `20128` | Port server |
+| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | URL dasar untuk frontend |
+| `JWT_SECRET` | (generate above) | Kunci penandatanganan JWT |
+| `INITIAL_PASSWORD` | `CHANGEME` | Kata sandi login pertama |
+| `APP_LOG_LEVEL` | `info` | Tingkat verbositas log |
-### Dashboard Settings
+### Pengaturan Dashboard
-The dashboard provides UI toggles for features that can also be configured via environment variables:
+Dashboard menyediakan tombol UI untuk fitur-fitur yang juga dapat dikonfigurasi melalui variabel lingkungan:
-| Setting Location | Toggle | Description |
-| ------------------- | ------------------ | ------------------------------ |
-| Settings → Advanced | Debug Mode | Enable debug request logs (UI) |
-| Settings → General | Sidebar Visibility | Show/hide sidebar sections |
+| Lokasi Pengaturan | Tombol | Deskripsi |
+| ------------------- | ------------------ | ---------------------------------------- |
+| Settings → Advanced | Debug Mode | Aktifkan log permintaan debug (UI) |
+| Settings → General | Sidebar Visibility | Tampilkan/sembunyikan bagian sidebar |
-These settings are stored in the database and persist across restarts, overriding env var defaults when set.
+Pengaturan ini disimpan di database dan tetap ada setelah restart, menggantikan nilai default variabel lingkungan jika sudah diatur.
-### Running Locally
+### Menjalankan Secara Lokal
```bash
# Development mode (hot reload)
@@ -70,16 +70,16 @@ npm run start
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
-Default URLs:
+URL default:
- **Dashboard**: `http://localhost:20128/dashboard`
- **API**: `http://localhost:20128/v1`
---
-## Git Workflow
+## Alur Kerja Git
-> ⚠️ **NEVER commit directly to `main`.** Always use feature branches.
+> ⚠️ **JANGAN PERNAH melakukan commit langsung ke `main`.** Selalu gunakan cabang fitur.
```bash
git checkout -b feat/your-feature-name
@@ -89,20 +89,20 @@ git push -u origin feat/your-feature-name
# Open a Pull Request on GitHub
```
-### Branch Naming
+### Penamaan Cabang
-| Prefix | Purpose |
-| ----------- | ------------------------- |
-| `feat/` | New features |
-| `fix/` | Bug fixes |
-| `refactor/` | Code restructuring |
-| `docs/` | Documentation changes |
-| `test/` | Test additions/fixes |
-| `chore/` | Tooling, CI, dependencies |
+| Awalan | Tujuan |
+| ----------- | ------------------------------ |
+| `feat/` | Fitur baru |
+| `fix/` | Perbaikan bug |
+| `refactor/` | Restrukturisasi kode |
+| `docs/` | Perubahan dokumentasi |
+| `test/` | Penambahan/perbaikan tes |
+| `chore/` | Perkakas, CI, dependensi |
-### Commit Messages
+### Pesan Commit
-Follow [Conventional Commits](https://www.conventionalcommits.org/):
+Ikuti [Conventional Commits](https://www.conventionalcommits.org/):
```
feat: add circuit breaker for provider calls
@@ -112,11 +112,11 @@ test: add observability unit tests
refactor(db): consolidate rate limit tables
```
-Scopes: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.
+Cakupan: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.
---
-## Running Tests
+## Menjalankan Tes
```bash
# All tests (unit + vitest + ecosystem + e2e)
@@ -146,166 +146,166 @@ npm run lint
npm run check
```
-Coverage notes:
+Catatan cakupan:
-- `npm run test:coverage` measures source coverage for the main unit test suite, excludes `tests/**`, and includes `open-sse/**`
-- Pull requests must keep the overall coverage gate at **60% or higher** for statements, lines, functions, and branches
-- If a PR changes production code in `src/`, `open-sse/`, `electron/`, or `bin/`, it must add or update automated tests in the same PR
-- `npm run coverage:report` prints the detailed file-by-file report from the latest coverage run
-- `npm run test:coverage:legacy` preserves the older metric for historical comparison
-- See `docs/ops/COVERAGE_PLAN.md` for the phased coverage improvement roadmap
+- `npm run test:coverage` mengukur cakupan kode sumber untuk rangkaian tes unit utama, mengecualikan `tests/**`, dan menyertakan `open-sse/**`
+- Pull request harus menjaga batas cakupan keseluruhan di **60% atau lebih tinggi** untuk pernyataan, baris, fungsi, dan cabang
+- Jika sebuah PR mengubah kode produksi di `src/`, `open-sse/`, `electron/`, atau `bin/`, PR tersebut harus menambahkan atau memperbarui tes otomatis dalam PR yang sama
+- `npm run coverage:report` mencetak laporan terperinci per file dari hasil cakupan terbaru
+- `npm run test:coverage:legacy` mempertahankan metrik lama untuk perbandingan historis
+- Lihat `docs/ops/COVERAGE_PLAN.md` untuk peta jalan peningkatan cakupan bertahap
-### Pull Request Requirements
+### Persyaratan Pull Request
-Before opening or merging a PR:
+Sebelum membuka atau menggabungkan sebuah PR:
-- Run `npm run test:unit`
-- Run `npm run test:coverage`
-- Ensure the coverage gate stays at **60%+** for all metrics
-- Include the changed or added test files in the PR description when production code changed
-- Check the SonarQube result on the PR when the project secrets are configured in CI
+- Jalankan `npm run test:unit`
+- Jalankan `npm run test:coverage`
+- Pastikan batas cakupan tetap di **60%+** untuk semua metrik
+- Sertakan file tes yang diubah atau ditambahkan dalam deskripsi PR ketika kode produksi berubah
+- Periksa hasil SonarQube pada PR ketika rahasia proyek dikonfigurasi di CI
-Current test status: **122 unit test files** covering:
+Status tes saat ini: **122 file tes unit** yang mencakup:
-- Provider translators and format conversion
-- Rate limiting, circuit breaker, and resilience
-- Semantic cache, idempotency, progress tracking
-- Database operations and schema (21 DB modules)
-- OAuth flows and authentication
-- API endpoint validation (Zod v4)
-- MCP server tools and scope enforcement
-- Memory and Skills systems
+- Penerjemah penyedia dan konversi format
+- Pembatasan laju, pemutus sirkuit, dan ketahanan
+- Cache semantik, idempoten, pelacakan progres
+- Operasi database dan skema (21 modul DB)
+- Alur OAuth dan autentikasi
+- Validasi endpoint API (Zod v4)
+- Alat server MCP dan penegakan cakupan
+- Sistem Memory dan Skills
---
-## Code Style
+## Gaya Kode
-- **ESLint** — Run `npm run lint` before committing
-- **Prettier** — Auto-formatted via `lint-staged` on commit (2 spaces, semicolons, double quotes, 100 char width, es5 trailing commas)
-- **TypeScript** — All `src/` code uses `.ts`/`.tsx`; `open-sse/` uses `.ts`/`.js`; document with TSDoc (`@param`, `@returns`, `@throws`)
-- **No `eval()`** — ESLint enforces `no-eval`, `no-implied-eval`, `no-new-func`
-- **Zod validation** — Use Zod v4 schemas for all API input validation
-- **Naming**: Files = camelCase/kebab-case, components = PascalCase, constants = UPPER_SNAKE
+- **ESLint** — Jalankan `npm run lint` sebelum melakukan commit
+- **Prettier** — Diformat otomatis melalui `lint-staged` saat commit (2 spasi, titik koma, tanda kutip ganda, lebar 100 karakter, koma trailing es5)
+- **TypeScript** — Semua kode `src/` menggunakan `.ts`/`.tsx`; `open-sse/` menggunakan `.ts`/`.js`; dokumentasi dengan TSDoc (`@param`, `@returns`, `@throws`)
+- **Tanpa `eval()`** — ESLint menerapkan `no-eval`, `no-implied-eval`, `no-new-func`
+- **Validasi Zod** — Gunakan skema Zod v4 untuk semua validasi input API
+- **Penamaan**: File = camelCase/kebab-case, komponen = PascalCase, konstanta = UPPER_SNAKE
---
-## Project Structure
+## Struktur Proyek
```
src/ # TypeScript (.ts / .tsx)
├── app/ # Next.js 16 App Router
-│ ├── (dashboard)/ # Dashboard pages (23 sections)
-│ ├── api/ # API routes (51 directories)
-│ └── login/ # Auth pages (.tsx)
-├── domain/ # Policy engine (policyEngine, comboResolver, costRules, etc.)
-├── lib/ # Core business logic (.ts)
-│ ├── a2a/ # Agent-to-Agent v0.3 protocol server
-│ ├── acp/ # Agent Communication Protocol registry
-│ ├── compliance/ # Compliance policy engine
-│ ├── db/ # SQLite database layer (21 modules + 16 migrations)
-│ ├── memory/ # Persistent conversational memory
-│ ├── oauth/ # OAuth providers, services, and utilities
-│ ├── skills/ # Extensible skill framework
-│ ├── usage/ # Usage tracking and cost calculation
-│ └── localDb.ts # Re-export layer only — never add logic here
-├── middleware/ # Request middleware (promptInjectionGuard)
-├── mitm/ # MITM proxy (cert, DNS, target routing)
+│ ├── (dashboard)/ # Halaman dashboard (23 bagian)
+│ ├── api/ # Rute API (51 direktori)
+│ └── login/ # Halaman autentikasi (.tsx)
+├── domain/ # Mesin kebijakan (policyEngine, comboResolver, costRules, dll.)
+├── lib/ # Logika bisnis inti (.ts)
+│ ├── a2a/ # Server protokol Agent-to-Agent v0.3
+│ ├── acp/ # Registri Agent Communication Protocol
+│ ├── compliance/ # Mesin kebijakan kepatuhan
+│ ├── db/ # Lapisan database SQLite (21 modul + 16 migrasi)
+│ ├── memory/ # Memori percakapan persisten
+│ ├── oauth/ # Penyedia, layanan, dan utilitas OAuth
+│ ├── skills/ # Kerangka skill yang dapat diperluas
+│ ├── usage/ # Pelacakan penggunaan dan kalkulasi biaya
+│ └── localDb.ts # Lapisan re-ekspor saja — jangan pernah tambahkan logika di sini
+├── middleware/ # Middleware permintaan (promptInjectionGuard)
+├── mitm/ # Proxy MITM (sertifikat, DNS, perutean target)
├── shared/
-│ ├── components/ # React components (.tsx)
-│ ├── constants/ # Provider definitions (60+), MCP scopes, routing strategies
-│ ├── utils/ # Circuit breaker, sanitizer, auth helpers
-│ └── validation/ # Zod v4 schemas
-└── sse/ # SSE proxy pipeline
+│ ├── components/ # Komponen React (.tsx)
+│ ├── constants/ # Definisi penyedia (60+), cakupan MCP, strategi perutean
+│ ├── utils/ # Pemutus sirkuit, sanitizer, pembantu autentikasi
+│ └── validation/ # Skema Zod v4
+└── sse/ # Pipeline proxy SSE
-open-sse/ # @omniroute/open-sse workspace
-├── executors/ # 14 provider-specific request executors
-├── handlers/ # 11 request handlers (chat, responses, embeddings, images, etc.)
-├── mcp-server/ # MCP server (25 tools, 3 transports, 10 scopes)
-├── services/ # 36+ services (combo, autoCombo, rateLimitManager, etc.)
-├── translator/ # Format translators (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama)
-├── transformer/ # Responses API transformer
-└── utils/ # 22 utility modules (stream, TLS, proxy, logging)
+open-sse/ # Workspace @omniroute/open-sse
+├── executors/ # 14 eksekutor permintaan khusus penyedia
+├── handlers/ # 11 penangan permintaan (chat, responses, embeddings, images, dll.)
+├── mcp-server/ # Server MCP (25 alat, 3 transport, 10 cakupan)
+├── services/ # 36+ layanan (combo, autoCombo, rateLimitManager, dll.)
+├── translator/ # Penerjemah format (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama)
+├── transformer/ # Transformer Responses API
+└── utils/ # 22 modul utilitas (stream, TLS, proxy, logging)
-electron/ # Electron desktop app (cross-platform)
+electron/ # Aplikasi desktop Electron (lintas platform)
tests/
-├── unit/ # Node.js test runner (122 test files)
-├── integration/ # Integration tests
-├── e2e/ # Playwright tests
-├── security/ # Security tests
-├── translator/ # Translator-specific tests
-└── load/ # Load tests
+├── unit/ # Runner tes Node.js (122 file tes)
+├── integration/ # Tes integrasi
+├── e2e/ # Tes Playwright
+├── security/ # Tes keamanan
+├── translator/ # Tes khusus penerjemah
+└── load/ # Tes beban
-docs/ # Documentation
-├── ARCHITECTURE.md # System architecture
-├── API_REFERENCE.md # All endpoints
-├── USER_GUIDE.md # Provider setup, CLI integration
-├── TROUBLESHOOTING.md # Common issues
-├── MCP-SERVER.md # MCP server (25 tools)
-├── A2A-SERVER.md # A2A agent protocol
-├── AUTO-COMBO.md # Auto-combo engine
-├── CLI-TOOLS.md # CLI tools integration
-├── COVERAGE_PLAN.md # Test coverage improvement plan
-├── openapi.yaml # OpenAPI specification
-└── adr/ # Architecture Decision Records
+docs/ # Dokumentasi
+├── ARCHITECTURE.md # Arsitektur sistem
+├── API_REFERENCE.md # Semua endpoint
+├── USER_GUIDE.md # Pengaturan penyedia, integrasi CLI
+├── TROUBLESHOOTING.md # Masalah umum
+├── MCP-SERVER.md # Server MCP (25 alat)
+├── A2A-SERVER.md # Protokol agen A2A
+├── AUTO-COMBO.md # Mesin auto-combo
+├── CLI-TOOLS.md # Integrasi alat CLI
+├── COVERAGE_PLAN.md # Rencana peningkatan cakupan tes
+├── openapi.yaml # Spesifikasi OpenAPI
+└── adr/ # Catatan Keputusan Arsitektur
```
---
-## Adding a New Provider
+## Menambahkan Penyedia Baru
-### Step 1: Register Provider Constants
+### Langkah 1: Daftarkan Konstanta Penyedia
-Add to `src/shared/constants/providers.ts` — Zod-validated at module load.
+Tambahkan ke `src/shared/constants/providers.ts` — divalidasi dengan Zod saat modul dimuat.
-### Step 2: Add Executor (if custom logic needed)
+### Langkah 2: Tambahkan Eksekutor (jika diperlukan logika kustom)
-Create executor in `open-sse/executors/your-provider.ts` extending the base executor.
+Buat eksekutor di `open-sse/executors/your-provider.ts` dengan memperluas eksekutor dasar.
-### Step 3: Add Translator (if non-OpenAI format)
+### Langkah 3: Tambahkan Penerjemah (jika format bukan OpenAI)
-Create request/response translators in `open-sse/translator/`.
+Buat penerjemah permintaan/respons di `open-sse/translator/`.
-### Step 4: Add OAuth Config (if OAuth-based)
+### Langkah 4: Tambahkan Konfigurasi OAuth (jika berbasis OAuth)
-Add OAuth credentials in `src/lib/oauth/constants/oauth.ts` and service in `src/lib/oauth/services/`.
+Tambahkan kredensial OAuth di `src/lib/oauth/constants/oauth.ts` dan layanan di `src/lib/oauth/services/`.
-### Step 5: Register Models
+### Langkah 5: Daftarkan Model
-Add model definitions in `open-sse/config/providerRegistry.ts`.
+Tambahkan definisi model di `open-sse/config/providerRegistry.ts`.
-### Step 6: Add Tests
+### Langkah 6: Tambahkan Tes
-Write unit tests in `tests/unit/` covering at minimum:
+Tulis tes unit di `tests/unit/` yang mencakup minimal:
-- Provider registration
-- Request/response translation
-- Error handling
+- Pendaftaran penyedia
+- Terjemahan permintaan/respons
+- Penanganan kesalahan
---
-## Pull Request Checklist
+## Daftar Periksa Pull Request
-- [ ] Tests pass (`npm test`)
-- [ ] Linting passes (`npm run lint`)
-- [ ] Build succeeds (`npm run build`)
-- [ ] TypeScript types added for new public functions and interfaces
-- [ ] No hardcoded secrets or fallback values
-- [ ] All inputs validated with Zod schemas
-- [ ] CHANGELOG updated (if user-facing change)
-- [ ] Documentation updated (if applicable)
+- [ ] Tes lulus (`npm test`)
+- [ ] Linting lulus (`npm run lint`)
+- [ ] Build berhasil (`npm run build`)
+- [ ] Tipe TypeScript ditambahkan untuk fungsi dan antarmuka publik baru
+- [ ] Tidak ada rahasia atau nilai fallback yang dikodekan secara keras
+- [ ] Semua input divalidasi dengan skema Zod
+- [ ] CHANGELOG diperbarui (jika ada perubahan yang terlihat pengguna)
+- [ ] Dokumentasi diperbarui (jika berlaku)
---
-## Releasing
+## Rilis
-Releases are managed via the `/generate-release` workflow. When a new GitHub Release is created, the package is **automatically published to npm** via GitHub Actions.
+Rilis dikelola melalui alur kerja `/generate-release`. Ketika GitHub Release baru dibuat, paket secara **otomatis diterbitkan ke npm** melalui GitHub Actions.
---
-## Getting Help
+## Mendapatkan Bantuan
-- **Architecture**: See [`docs/architecture/ARCHITECTURE.md`](docs/architecture/ARCHITECTURE.md)
-- **API Reference**: See [`docs/reference/API_REFERENCE.md`](docs/reference/API_REFERENCE.md)
-- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
-- **ADRs**: See `docs/adr/` for architectural decision records
+- **Arsitektur**: Lihat [`docs/architecture/ARCHITECTURE.md`](docs/architecture/ARCHITECTURE.md)
+- **Referensi API**: Lihat [`docs/reference/API_REFERENCE.md`](docs/reference/API_REFERENCE.md)
+- **Masalah**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
+- **ADR**: Lihat `docs/adr/` untuk catatan keputusan arsitektur
diff --git a/docs/i18n/id/GEMINI.md b/docs/i18n/id/GEMINI.md
index d9706fda42..e263e872fc 100644
--- a/docs/i18n/id/GEMINI.md
+++ b/docs/i18n/id/GEMINI.md
@@ -1,25 +1,25 @@
-# Security and Cleanliness Rules for AI Assistants (Bahasa Indonesia)
+# Aturan Keamanan dan Kebersihan untuk Asisten AI (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../GEMINI.md) · 🇸🇦 [ar](../ar/GEMINI.md) · 🇧🇬 [bg](../bg/GEMINI.md) · 🇧🇩 [bn](../bn/GEMINI.md) · 🇨🇿 [cs](../cs/GEMINI.md) · 🇩🇰 [da](../da/GEMINI.md) · 🇩🇪 [de](../de/GEMINI.md) · 🇪🇸 [es](../es/GEMINI.md) · 🇮🇷 [fa](../fa/GEMINI.md) · 🇫🇮 [fi](../fi/GEMINI.md) · 🇫🇷 [fr](../fr/GEMINI.md) · 🇮🇳 [gu](../gu/GEMINI.md) · 🇮🇱 [he](../he/GEMINI.md) · 🇮🇳 [hi](../hi/GEMINI.md) · 🇭🇺 [hu](../hu/GEMINI.md) · 🇮🇩 [id](../id/GEMINI.md) · 🇮🇹 [it](../it/GEMINI.md) · 🇯🇵 [ja](../ja/GEMINI.md) · 🇰🇷 [ko](../ko/GEMINI.md) · 🇮🇳 [mr](../mr/GEMINI.md) · 🇲🇾 [ms](../ms/GEMINI.md) · 🇳🇱 [nl](../nl/GEMINI.md) · 🇳🇴 [no](../no/GEMINI.md) · 🇵🇭 [phi](../phi/GEMINI.md) · 🇵🇱 [pl](../pl/GEMINI.md) · 🇵🇹 [pt](../pt/GEMINI.md) · 🇧🇷 [pt-BR](../pt-BR/GEMINI.md) · 🇷🇴 [ro](../ro/GEMINI.md) · 🇷🇺 [ru](../ru/GEMINI.md) · 🇸🇰 [sk](../sk/GEMINI.md) · 🇸🇪 [sv](../sv/GEMINI.md) · 🇰🇪 [sw](../sw/GEMINI.md) · 🇮🇳 [ta](../ta/GEMINI.md) · 🇮🇳 [te](../te/GEMINI.md) · 🇹🇭 [th](../th/GEMINI.md) · 🇹🇷 [tr](../tr/GEMINI.md) · 🇺🇦 [uk-UA](../uk-UA/GEMINI.md) · 🇵🇰 [ur](../ur/GEMINI.md) · 🇻🇳 [vi](../vi/GEMINI.md) · 🇨🇳 [zh-CN](../zh-CN/GEMINI.md)
---
-## 1. File Placement & Organization
+## 1. Penempatan & Organisasi File
-- **Test Files**: ALL unit tests, integration tests, ecosystem tests, or Vitest files MUST strictly be placed within the `tests/` directory (e.g., `tests/unit/`, `tests/integration/`). NEVER create test files in the project root (`/`).
-- **Scripts and Utilities**: ALL maintenance, debugging, generation, or experimental scripts (`.cjs`, `.mjs`, `.js`, `.ts`) MUST be placed strictly inside the `scripts/` directory or `scripts/scratch/` for temporary one-offs. NEVER dump loose scripts in the project root (`/`).
+- **File Tes**: SEMUA uji unit, uji integrasi, uji ekosistem, atau file Vitest HARUS ditempatkan secara ketat di dalam direktori `tests/` (mis., `tests/unit/`, `tests/integration/`). JANGAN PERNAH membuat file tes di root proyek (`/`).
+- **Skrip dan Utilitas**: SEMUA skrip pemeliharaan, debugging, pembuatan, atau eksperimental (`.cjs`, `.mjs`, `.js`, `.ts`) HARUS ditempatkan secara ketat di dalam direktori `scripts/` atau `scripts/scratch/` untuk keperluan sementara. JANGAN PERNAH membuang skrip bebas di root proyek (`/`).
-**The Project Root MUST ONLY CONTAIN:**
+**Root Proyek HANYA BOLEH BERISI:**
-- Configuration files (`vitest.config.ts`, `next.config.mjs`, `eslint.config.mjs`, etc.)
-- Dependency files (`package.json`, `package-lock.json`)
-- Documentation files (`README.md`, `CHANGELOG.md`, `AGENTS.md`)
-- CI/CD files and ignore definitions (`.gitignore`, `.dockerignore`)
+- File konfigurasi (`vitest.config.ts`, `next.config.mjs`, `eslint.config.mjs`, dll.)
+- File dependensi (`package.json`, `package-lock.json`)
+- File dokumentasi (`README.md`, `CHANGELOG.md`, `AGENTS.md`)
+- File CI/CD dan definisi pengabaian (`.gitignore`, `.dockerignore`)
-When creating _any_ validation tests or one-off logic scripts, default to using `scripts/scratch/` or the `tests/unit/` directories according to your goals. Do not pollute the `/` root context.
+Saat membuat _tes validasi_ atau skrip logika sekali pakai, default ke penggunaan `scripts/scratch/` atau direktori `tests/unit/` sesuai tujuan Anda. Jangan mencemari konteks root `/`.
-## 2. VPS Dashboard Credentials
+## 2. Kredensial Dashboard VPS
-| Environment | URL | Password |
-| ----------- | ------------------------- | -------- |
-| Local VPS | http://192.168.0.15:20128 | 123456 |
+| Lingkungan | URL | Kata Sandi |
+| ---------- | ------------------------- | ---------- |
+| VPS Lokal | http://192.168.0.15:20128 | 123456 |
diff --git a/docs/i18n/id/README.md b/docs/i18n/id/README.md
index 19247d911c..c57e14d228 100644
--- a/docs/i18n/id/README.md
+++ b/docs/i18n/id/README.md
@@ -1,14 +1,14 @@
-# 🚀 OmniRoute — The Free AI Gateway (Bahasa Indonesia)
+# 🚀 OmniRoute — Gateway AI Gratis (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../README.md) · 🇸🇦 [ar](../ar/README.md) · 🇧🇬 [bg](../bg/README.md) · 🇧🇩 [bn](../bn/README.md) · 🇨🇿 [cs](../cs/README.md) · 🇩🇰 [da](../da/README.md) · 🇩🇪 [de](../de/README.md) · 🇪🇸 [es](../es/README.md) · 🇮🇷 [fa](../fa/README.md) · 🇫🇮 [fi](../fi/README.md) · 🇫🇷 [fr](../fr/README.md) · 🇮🇳 [gu](../gu/README.md) · 🇮🇱 [he](../he/README.md) · 🇮🇳 [hi](../hi/README.md) · 🇭🇺 [hu](../hu/README.md) · 🇮🇩 [id](../id/README.md) · 🇮🇹 [it](../it/README.md) · 🇯🇵 [ja](../ja/README.md) · 🇰🇷 [ko](../ko/README.md) · 🇮🇳 [mr](../mr/README.md) · 🇲🇾 [ms](../ms/README.md) · 🇳🇱 [nl](../nl/README.md) · 🇳🇴 [no](../no/README.md) · 🇵🇭 [phi](../phi/README.md) · 🇵🇱 [pl](../pl/README.md) · 🇵🇹 [pt](../pt/README.md) · 🇧🇷 [pt-BR](../pt-BR/README.md) · 🇷🇴 [ro](../ro/README.md) · 🇷🇺 [ru](../ru/README.md) · 🇸🇰 [sk](../sk/README.md) · 🇸🇪 [sv](../sv/README.md) · 🇰🇪 [sw](../sw/README.md) · 🇮🇳 [ta](../ta/README.md) · 🇮🇳 [te](../te/README.md) · 🇹🇭 [th](../th/README.md) · 🇹🇷 [tr](../tr/README.md) · 🇺🇦 [uk-UA](../uk-UA/README.md) · 🇵🇰 [ur](../ur/README.md) · 🇻🇳 [vi](../vi/README.md) · 🇨🇳 [zh-CN](../zh-CN/README.md)
---
-### Never stop coding. Smart routing to **FREE & low-cost AI models** with automatic fallback.
+### Jangan pernah berhenti ngoding. Routing cerdas ke **model AI GRATIS & berbiaya rendah** dengan fallback otomatis.
-_Your universal API proxy — one endpoint, 100+ providers, zero downtime. Now with **MCP Server (25 tools)**, **A2A Protocol**, **Memory/Skills Systems** & **Electron Desktop App**._
+_Proxy API universal Anda — satu endpoint, 100+ penyedia, tanpa downtime. Kini dengan **MCP Server (25 alat)**, **Protokol A2A**, **Sistem Memori/Skill** & **Aplikasi Desktop Electron**._
-**Chat Completions • Embeddings • Image Generation • Video • Music • Audio • Reranking • **Web Search** • MCP Server • A2A Protocol • 100% TypeScript**
+**Chat Completions • Embeddings • Pembuatan Gambar • Video • Musik • Audio • Reranking • **Pencarian Web** • MCP Server • Protokol A2A • 100% TypeScript**
---
@@ -41,7 +41,7 @@ _Your universal API proxy — one endpoint, 100+ providers, zero downtime. Now w
[](https://omniroute.online)
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
-[🌐 Website](https://omniroute.online) • [🚀 Quick Start](#-quick-start) • [💡 Features](#-key-features) • [📖 Docs](#-documentation) • [💰 Pricing](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
+[🌐 Website](https://omniroute.online) • [🚀 Mulai Cepat](#-quick-start) • [💡 Fitur](#-key-features) • [📖 Dokumentasi](#-documentation) • [💰 Harga](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
@@ -49,7 +49,7 @@ _Your universal API proxy — one endpoint, 100+ providers, zero downtime. Now w
---
-## 🖼️ Main Dashboard
+## 🖼️ Dashboard Utama

@@ -57,12 +57,12 @@ _Your universal API proxy — one endpoint, 100+ providers, zero downtime. Now w
---
-## 📸 Dashboard Preview
+## 📸 Pratinjau Dashboard
-Click to see dashboard screenshots
+Klik untuk melihat tangkapan layar dashboard
-| Page | Screenshot |
+| Halaman | Tangkapan Layar |
| -------------- | ------------------------------------------------- |
| **Providers** |  |
| **Combos** |  |
@@ -78,9 +78,9 @@ _Your universal API proxy — one endpoint, 100+ providers, zero downtime. Now w
---
-### 🤖 Free AI Provider for your favorite coding agents
+### 🤖 Penyedia AI Gratis untuk agen coding favorit Anda
-_Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway for unlimited coding._
+_Hubungkan IDE atau alat CLI berbasis AI apa pun melalui OmniRoute — gateway API gratis untuk coding tanpa batas._
@@ -159,541 +159,541 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
-📡 All agents connect via http://localhost:20128/v1 or http://cloud.omniroute.online/v1 — one config, unlimited models and quota
+📡 Semua agen terhubung melalui http://localhost:20128/v1 atau http://cloud.omniroute.online/v1 — satu konfigurasi, model dan kuota tak terbatas
---
-## 🤔 Why OmniRoute?
+## 🤔 Mengapa OmniRoute?
-**Stop wasting money and hitting limits:**
+**Berhenti membuang uang dan terus mencapai batas:**
--
Subscription quota expires unused every month
--
Rate limits stop you mid-coding
--
Expensive APIs ($20-50/month per provider)
--
Manual switching between providers
+-
Kuota langganan kedaluwarsa tanpa digunakan setiap bulan
+-
Batas rate menghentikan Anda di tengah sesi coding
+-
API mahal ($20-50/bulan per penyedia)
+-
Perpindahan manual antar penyedia
-**OmniRoute solves this:**
+**OmniRoute mengatasi ini:**
-- ✅ **Maximize subscriptions** - Track quota, use every bit before reset
-- ✅ **Auto fallback** - Subscription → API Key → Cheap → Free, zero downtime
-- ✅ **Multi-account** - Round-robin between accounts per provider
-- ✅ **Universal** - Works with Claude Code, Codex, Gemini CLI, Cursor, Cline, OpenClaw, any CLI tool
+- ✅ **Maksimalkan langganan** - Pantau kuota, gunakan setiap bit sebelum reset
+- ✅ **Fallback otomatis** - Langganan → Kunci API → Murah → Gratis, tanpa downtime
+- ✅ **Multi-akun** - Round-robin antar akun per penyedia
+- ✅ **Universal** - Bekerja dengan Claude Code, Codex, Gemini CLI, Cursor, Cline, OpenClaw, alat CLI apa pun
---
-## 📧 Support
+## 📧 Dukungan
-> 💬 **Join our community!** [WhatsApp Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Get help, share tips, and stay updated.
+> 💬 **Bergabunglah dengan komunitas kami!** [Grup WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Dapatkan bantuan, berbagi tips, dan tetap terupdate.
- **Website**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
-- **WhatsApp**: [Community Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
-- **Contributing**: See [CONTRIBUTING.md](CONTRIBUTING.md), open a PR, or pick a `good first issue`
+- **WhatsApp**: [Grup Komunitas](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
+- **Berkontribusi**: Lihat [CONTRIBUTING.md](CONTRIBUTING.md), buka PR, atau pilih `good first issue`
-### 🐛 Reporting a Bug?
+### 🐛 Melaporkan Bug?
-When opening an issue, please run the system-info command and attach the generated file:
+Saat membuka issue, jalankan perintah system-info dan lampirkan file yang dihasilkan:
```bash
npm run system-info
```
-This generates a `system-info.txt` with your Node.js version, OmniRoute version, OS details, installed CLI tools (qoder, gemini, claude, codex, antigravity, droid, etc.), Docker/PM2 status, and system packages — everything we need to reproduce your issue quickly. Attach the file directly to your GitHub issue.
+Perintah ini menghasilkan `system-info.txt` berisi versi Node.js, versi OmniRoute, detail OS, alat CLI yang terpasang (qoder, gemini, claude, codex, antigravity, droid, dll.), status Docker/PM2, dan paket sistem — semua yang dibutuhkan untuk mereproduksi masalah Anda dengan cepat. Lampirkan file tersebut langsung ke GitHub issue Anda.
---
-## 🔄 How It Works
+## 🔄 Cara Kerjanya
```
┌─────────────┐
-│ Your CLI │ (Claude Code, Codex, Gemini CLI, OpenClaw, Cursor, Cline...)
+│ CLI Anda │ (Claude Code, Codex, Gemini CLI, OpenClaw, Cursor, Cline...)
│ Tool │
└──────┬──────┘
│ http://localhost:20128/v1
↓
┌─────────────────────────────────────────┐
-│ OmniRoute (Smart Router) │
-│ • Format translation (OpenAI ↔ Claude) │
-│ • Quota tracking + Embeddings + Images │
-│ • Auto token refresh │
+│ OmniRoute (Router Cerdas) │
+│ • Translasi format (OpenAI ↔ Claude) │
+│ • Pelacakan kuota + Embeddings + Gambar│
+│ • Refresh token otomatis │
└──────┬──────────────────────────────────┘
│
- ├─→ [Tier 1: SUBSCRIPTION] Claude Code, Codex, Gemini CLI
- │ ↓ quota exhausted
- ├─→ [Tier 2: API KEY] DeepSeek, Groq, xAI, Mistral, NVIDIA NIM, etc.
- │ ↓ budget limit
- ├─→ [Tier 3: CHEAP] GLM ($0.6/1M), MiniMax ($0.2/1M)
- │ ↓ budget limit
- └─→ [Tier 4: FREE] Qoder, Qwen, Kiro (unlimited)
+ ├─→ [Tier 1: LANGGANAN] Claude Code, Codex, Gemini CLI
+ │ ↓ kuota habis
+ ├─→ [Tier 2: KUNCI API] DeepSeek, Groq, xAI, Mistral, NVIDIA NIM, dll.
+ │ ↓ batas anggaran
+ ├─→ [Tier 3: MURAH] GLM ($0.6/1M), MiniMax ($0.2/1M)
+ │ ↓ batas anggaran
+ └─→ [Tier 4: GRATIS] Qoder, Qwen, Kiro (tidak terbatas)
-Result: Never stop coding, minimal cost
+Hasil: Tidak pernah berhenti coding, biaya minimal
```
---
-## 🎯 What OmniRoute Solves — 30 Real Pain Points & Use Cases
+## 🎯 Apa yang Diselesaikan OmniRoute — 30 Masalah Nyata & Kasus Penggunaan
-> **Every developer using AI tools faces these problems daily.** OmniRoute was built to solve them all — from cost overruns to regional blocks, from broken OAuth flows to protocol operations and enterprise observability.
+> **Setiap developer yang menggunakan alat AI menghadapi masalah ini setiap hari.** OmniRoute dibangun untuk menyelesaikannya semua — dari pembengkakan biaya hingga pemblokiran regional, dari alur OAuth yang rusak hingga operasi protokol dan observabilitas enterprise.
-💸 1. "I pay for an expensive subscription but still get interrupted by limits"
+💸 1. "Saya membayar langganan mahal tapi masih terganggu oleh batas"
-Developers pay $20–200/month for Claude Pro, Codex Pro, or GitHub Copilot. Even paying, quota has a ceiling — 5h of usage, weekly limits, or per-minute rate limits. Mid-coding session, the provider stops responding and the developer loses flow and productivity.
+Developer membayar $20–200/bulan untuk Claude Pro, Codex Pro, atau GitHub Copilot. Meski sudah membayar, kuota memiliki batas — 5 jam penggunaan, batas mingguan, atau batas rate per menit. Di tengah sesi coding, penyedia berhenti merespons dan developer kehilangan fokus dan produktivitas.
-**How OmniRoute solves it:**
+**Cara OmniRoute menyelesaikannya:**
-- **Smart 4-Tier Fallback** — If subscription quota runs out, automatically redirects to API Key → Cheap → Free with zero manual intervention
-- **Provider Limits Tracking** — Cached quota snapshots refresh on a server-side schedule (default `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES=70`) with manual refresh available in the UI
-- **Multi-Account Support** — Multiple accounts per provider with auto round-robin — when one runs out, switches to the next
-- **Custom Combos** — Customizable fallback chains with 13 balancing strategies (priority, weighted, fill-first, round-robin, P2C, random, least-used, cost-optimized, strict-random, auto, lkgp, context-optimized, **context-relay**)
-- **Structured Combo Builder** — Build combos step-by-step with explicit provider + model + account selection, including repeated providers and fixed-account targets
-- **Quota-Aware P2C** — Power-of-two account selection now factors quota headroom, backoff, recent errors, and consecutive use
-- **Codex Business Quotas** — Business/Team workspace quota monitoring directly in the dashboard
+- **Fallback 4-Tier Cerdas** — Jika kuota langganan habis, secara otomatis mengarahkan ke Kunci API → Murah → Gratis tanpa intervensi manual
+- **Pelacakan Batas Penyedia** — Snapshot kuota yang di-cache diperbarui sesuai jadwal sisi server (default `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES=70`) dengan pembaruan manual tersedia di UI
+- **Dukungan Multi-Akun** — Beberapa akun per penyedia dengan round-robin otomatis — saat satu habis, beralih ke berikutnya
+- **Combo Kustom** — Rantai fallback yang dapat dikustomisasi dengan 13 strategi penyeimbangan (priority, weighted, fill-first, round-robin, P2C, random, least-used, cost-optimized, strict-random, auto, lkgp, context-optimized, **context-relay**)
+- **Pembangun Combo Terstruktur** — Buat combo langkah demi langkah dengan pemilihan penyedia + model + akun yang eksplisit, termasuk penyedia berulang dan target akun tetap
+- **P2C Berbasis Kuota** — Pemilihan akun power-of-two kini mempertimbangkan kapasitas kuota, backoff, kesalahan terkini, dan penggunaan berturut-turut
+- **Kuota Bisnis Codex** — Pemantauan kuota workspace Business/Team langsung di dashboard
-🔌 2. "I need to use multiple providers but each has a different API"
+🔌 2. "Saya perlu menggunakan beberapa penyedia tetapi masing-masing memiliki API berbeda"
-OpenAI uses one format, Claude (Anthropic) uses another, Gemini yet another. If a dev wants to test models from different providers or fallback between them, they need to reconfigure SDKs, change endpoints, deal with incompatible formats. Custom providers (FriendLI, NIM) have non-standard model endpoints.
+OpenAI menggunakan satu format, Claude (Anthropic) menggunakan format lain, Gemini pun berbeda lagi. Jika seorang developer ingin menguji model dari penyedia berbeda atau melakukan fallback di antara mereka, mereka perlu mengonfigurasi ulang SDK, mengganti endpoint, dan menangani format yang tidak kompatibel. Penyedia kustom (FriendLI, NIM) memiliki endpoint model non-standar.
-**How OmniRoute solves it:**
+**Cara OmniRoute menyelesaikannya:**
-- **Unified Endpoint** — A single `http://localhost:20128/v1` serves as proxy for all 100+ providers
-- **Format Translation** — Automatic and transparent: OpenAI ↔ Claude ↔ Gemini ↔ Responses API
-- **Response Sanitization** — Strips non-standard fields (`x_groq`, `usage_breakdown`, `service_tier`) that break OpenAI SDK v1.83+
-- **Role Normalization** — Converts `developer` → `system` for non-OpenAI providers; `system` → `user` for GLM/ERNIE
-- **Think Tag Extraction** — Extracts `` blocks from models like DeepSeek R1 into standardized `reasoning_content`
-- **Structured Output for Gemini** — `json_schema` → `responseMimeType`/`responseSchema` automatic conversion
-- **`stream` defaults to `false`** — Aligns with OpenAI spec, avoiding unexpected SSE in Python/Rust/Go SDKs
+- **Endpoint Terpadu** — Satu `http://localhost:20128/v1` berfungsi sebagai proxy untuk semua 100+ penyedia
+- **Translasi Format** — Otomatis dan transparan: OpenAI ↔ Claude ↔ Gemini ↔ Responses API
+- **Sanitasi Respons** — Menghapus field non-standar (`x_groq`, `usage_breakdown`, `service_tier`) yang merusak OpenAI SDK v1.83+
+- **Normalisasi Peran** — Mengonversi `developer` → `system` untuk penyedia non-OpenAI; `system` → `user` untuk GLM/ERNIE
+- **Ekstraksi Tag Think** — Mengekstrak blok `` dari model seperti DeepSeek R1 ke `reasoning_content` yang terstandarisasi
+- **Output Terstruktur untuk Gemini** — Konversi otomatis `json_schema` → `responseMimeType`/`responseSchema`
+- **`stream` default ke `false`** — Selaras dengan spesifikasi OpenAI, menghindari SSE tak terduga di SDK Python/Rust/Go
-🌐 3. "My AI provider blocks my region/country"
+🌐 3. "Penyedia AI saya memblokir wilayah/negara saya"
-Providers like OpenAI/Codex block access from certain geographic regions. Users get errors like `unsupported_country_region_territory` during OAuth and API connections. This is especially frustrating for developers from developing countries.
+Penyedia seperti OpenAI/Codex memblokir akses dari wilayah geografis tertentu. Pengguna mendapat kesalahan seperti `unsupported_country_region_territory` saat OAuth dan koneksi API. Ini sangat membuat frustasi para developer dari negara berkembang.
-**How OmniRoute solves it:**
+**Cara OmniRoute menyelesaikannya:**
-- **3-Level Proxy Config** — Configurable proxy at 3 levels: global (all traffic), per-provider (one provider only), and per-connection/key
-- **Color-Coded Proxy Badges** — Visual indicators: 🟢 global proxy, 🟡 provider proxy, 🔵 connection proxy, always showing the IP
-- **OAuth Token Exchange Through Proxy** — OAuth flow also goes through the proxy, solving `unsupported_country_region_territory`
-- **Connection Tests via Proxy** — Connection tests use the configured proxy (no more direct bypass)
-- **SOCKS5 Support** — Full SOCKS5 proxy support for outbound routing
-- **TLS Fingerprint Spoofing** — Browser-like TLS fingerprint via `wreq-js` to bypass bot detection
-- **🔏 CLI Fingerprint Matching** — Reorders headers and body fields to match native CLI binary signatures, drastically reducing account flagging risk. The proxy IP is preserved — you get both stealth **and** IP masking simultaneously
+- **Konfigurasi Proxy 3-Level** — Proxy yang dapat dikonfigurasi di 3 level: global (semua lalu lintas), per-penyedia (hanya satu penyedia), dan per-koneksi/kunci
+- **Lencana Proxy Berkode Warna** — Indikator visual: 🟢 proxy global, 🟡 proxy penyedia, 🔵 proxy koneksi, selalu menampilkan IP
+- **Pertukaran Token OAuth Melalui Proxy** — Alur OAuth juga melewati proxy, menyelesaikan masalah `unsupported_country_region_territory`
+- **Uji Koneksi via Proxy** — Uji koneksi menggunakan proxy yang dikonfigurasi (tidak ada lagi bypass langsung)
+- **Dukungan SOCKS5** — Dukungan proxy SOCKS5 penuh untuk routing keluar
+- **Spoofing Sidik Jari TLS** — Sidik jari TLS seperti browser melalui `wreq-js` untuk melewati deteksi bot
+- **🔏 Pencocokan Sidik Jari CLI** — Menyusun ulang header dan field body agar sesuai dengan tanda tangan biner CLI asli, sangat mengurangi risiko pemanduan akun. IP proxy tetap dipertahankan — Anda mendapatkan kesiluman **dan** penyamaran IP secara bersamaan
-🆓 4. "I want to use AI for coding but I have no money"
+🆓 4. "Saya ingin menggunakan AI untuk coding tapi tidak punya uang"
-Not everyone can pay $20–200/month for AI subscriptions. Students, devs from emerging countries, hobbyists, and freelancers need access to quality models at zero cost.
+Tidak semua orang bisa membayar $20–200/bulan untuk langganan AI. Pelajar, developer dari negara berkembang, penghobi, dan freelancer membutuhkan akses ke model berkualitas tanpa biaya sama sekali.
-**How OmniRoute solves it:**
+**Cara OmniRoute menyelesaikannya:**
-- **Free Tier Providers Built-in** — Native support for 100% free providers: Qoder (5 unlimited models via OAuth: kimi-k2-thinking, qwen3-coder-plus, deepseek-r1, minimax-m2, kimi-k2), Qwen (4 unlimited models: qwen3-coder-plus, qwen3-coder-flash, qwen3-coder-next, vision-model), Kiro (Claude + AWS Builder ID for free), Gemini CLI (180K tokens/month free)
-- **Ollama Cloud** — Cloud-hosted Ollama models at `api.ollama.com` with free "Light usage" tier; use `ollamacloud/` prefix
-- **Free-Only Combos** — Chain `gc/gemini-3-flash → if/kimi-k2-thinking → qw/qwen3-coder-plus` = $0/month with zero downtime
-- **NVIDIA NIM Free Access** — ~40 RPM dev-forever free access to 70+ models at build.nvidia.com (transitioning from credits to pure rate limits)
-- **Cost Optimized Strategy** — Routing strategy that automatically chooses the cheapest available provider
+- **Penyedia Tier Gratis Bawaan** — Dukungan asli untuk penyedia 100% gratis: Qoder (5 model tak terbatas via OAuth: kimi-k2-thinking, qwen3-coder-plus, deepseek-r1, minimax-m2, kimi-k2), Qwen (4 model tak terbatas: qwen3-coder-plus, qwen3-coder-flash, qwen3-coder-next, vision-model), Kiro (Claude + AWS Builder ID gratis), Gemini CLI (180K token/bulan gratis)
+- **Ollama Cloud** — Model Ollama yang di-host di cloud pada `api.ollama.com` dengan tier "Light usage" gratis; gunakan prefix `ollamacloud/`
+- **Combo Hanya Gratis** — Rantai `gc/gemini-3-flash → if/kimi-k2-thinking → qw/qwen3-coder-plus` = $0/bulan tanpa downtime
+- **Akses Gratis NVIDIA NIM** — ~40 RPM akses gratis selamanya untuk 70+ model di build.nvidia.com (beralih dari kredit ke batas rate murni)
+- **Strategi Optimasi Biaya** — Strategi routing yang secara otomatis memilih penyedia termurah yang tersedia
-🔒 5. "I need to protect my AI gateway from unauthorized access"
+🔒 5. "Saya perlu melindungi gateway AI saya dari akses tidak sah"
-When exposing an AI gateway to the network (LAN, VPS, Docker), anyone with the address can consume the developer's tokens/quota. Without protection, APIs are vulnerable to misuse, prompt injection, and abuse.
+Saat mengekspos gateway AI ke jaringan (LAN, VPS, Docker), siapa pun yang memiliki alamat tersebut dapat mengonsumsi token/kuota developer. Tanpa perlindungan, API rentan terhadap penyalahgunaan, injeksi prompt, dan eksploitasi.
-**How OmniRoute solves it:**
+**Cara OmniRoute menyelesaikannya:**
-- **API Key Management** — Generation, rotation, and scoping per provider with a dedicated `/dashboard/api-manager` page
-- **Model-Level Permissions** — Restrict API keys to specific models (`openai/*`, wildcard patterns), with Allow All/Restrict toggle
-- **API Endpoint Protection** — Require a key for `/v1/models` and block specific providers from the listing
-- **Auth Guard + CSRF Protection** — All dashboard routes protected with `withAuth` middleware + CSRF tokens
-- **Rate Limiter** — Per-IP rate limiting with configurable windows
-- **IP Filtering** — Allowlist/blocklist for access control
-- **Prompt Injection Guard** — Sanitization against malicious prompt patterns
-- **AES-256-GCM Encryption** — Credentials encrypted at rest
+- **Manajemen Kunci API** — Pembuatan, rotasi, dan pembatasan lingkup per penyedia dengan halaman `/dashboard/api-manager` yang didedikasikan
+- **Izin Tingkat Model** — Batasi kunci API ke model tertentu (`openai/*`, pola wildcard), dengan toggle Izinkan Semua/Batasi
+- **Perlindungan Endpoint API** — Wajibkan kunci untuk `/v1/models` dan blokir penyedia tertentu dari daftar
+- **Auth Guard + Perlindungan CSRF** — Semua rute dashboard dilindungi dengan middleware `withAuth` + token CSRF
+- **Pembatas Rate** — Pembatasan rate per-IP dengan jendela yang dapat dikonfigurasi
+- **Penyaringan IP** — Allowlist/blocklist untuk kontrol akses
+- **Penjaga Injeksi Prompt** — Sanitasi terhadap pola prompt berbahaya
+- **Enkripsi AES-256-GCM** — Kredensial dienkripsi saat disimpan
-🛑 6. "My provider went down and I lost my coding flow"
+🛑 6. "Penyedia saya mati dan saya kehilangan alur coding"
-AI providers can become unstable, return 5xx errors, or hit temporary rate limits. If a dev depends on a single provider, they're interrupted. Without circuit breakers, repeated retries can crash the application.
+Penyedia AI bisa menjadi tidak stabil, mengembalikan kesalahan 5xx, atau mencapai batas rate sementara. Jika developer bergantung pada satu penyedia, mereka akan terganggu. Tanpa circuit breaker, percobaan ulang berulang dapat menyebabkan aplikasi crash.
-**How OmniRoute solves it:**
+**Cara OmniRoute menyelesaikannya:**
-- **Request Queue & Pacing** — Per-connection request buckets smooth bursts before they hit upstream rate caps
-- **Connection Cooldown** — A single connection cools down after retryable failures with optional upstream `Retry-After` hints and exponential backoff
-- **Provider Circuit Breaker** — The provider only trips after fallback is exhausted and the provider request still fails with provider-wide transient errors; connection-scoped `429` rate limits stay in Connection Cooldown
-- **Wait For Cooldown** — The server can wait for the earliest connection cooldown to expire and retry the same client request automatically
-- **Anti-Thundering Herd** — Mutex + semaphore protection against concurrent retry storms
-- **Combo Fallback Chains** — If the primary provider fails, automatically falls through the chain with no intervention
-- **Health Dashboard** — Uptime monitoring, provider circuit breaker states, cooldowns, cache stats, p50/p95/p99 latency
+- **Antrian & Pacing Permintaan** — Bucket permintaan per-koneksi memperhalus lonjakan sebelum mencapai batas rate upstream
+- **Pendinginan Koneksi** — Satu koneksi mendingin setelah kegagalan yang dapat dicoba ulang dengan petunjuk `Retry-After` upstream opsional dan backoff eksponensial
+- **Circuit Breaker Penyedia** — Penyedia hanya trip setelah fallback habis dan permintaan penyedia masih gagal dengan kesalahan transien seluruh penyedia; batas rate `429` yang terikat koneksi tetap di Pendinginan Koneksi
+- **Tunggu Pendinginan** — Server dapat menunggu pendinginan koneksi paling awal berakhir dan mencoba ulang permintaan klien yang sama secara otomatis
+- **Anti-Thundering Herd** — Perlindungan mutex + semaphore terhadap badai percobaan ulang bersamaan
+- **Rantai Fallback Combo** — Jika penyedia utama gagal, secara otomatis jatuh ke rantai berikutnya tanpa intervensi
+- **Dashboard Kesehatan** — Pemantauan uptime, status circuit breaker penyedia, pendinginan, statistik cache, latensi p50/p95/p99
-🔧 7. "Configuring each AI tool is tedious and repetitive"
+🔧 7. "Mengonfigurasi setiap alat AI membosankan dan berulang"
-Developers use Cursor, Claude Code, Codex CLI, OpenClaw, Gemini CLI, Kilo Code... Each tool needs a different config (API endpoint, key, model). Reconfiguring when switching providers or models is a waste of time.
+Developer menggunakan Cursor, Claude Code, Codex CLI, OpenClaw, Gemini CLI, Kilo Code... Setiap alat memerlukan konfigurasi berbeda (endpoint API, kunci, model). Mengonfigurasi ulang saat berganti penyedia atau model adalah pemborosan waktu.
-**How OmniRoute solves it:**
+**Cara OmniRoute menyelesaikannya:**
-- **CLI Tools Dashboard** — Dedicated page with one-click setup for Claude Code, Codex CLI, OpenClaw, Kilo Code, Antigravity, Cline
-- **GitHub Copilot Config Generator** — Generates `chatLanguageModels.json` for VS Code with bulk model selection
-- **Onboarding Wizard** — Guided 4-step setup for first-time users
-- **One endpoint, all models** — Configure `http://localhost:20128/v1` once, access 100+ providers
+- **Dashboard Alat CLI** — Halaman khusus dengan pengaturan satu klik untuk Claude Code, Codex CLI, OpenClaw, Kilo Code, Antigravity, Cline
+- **Generator Konfigurasi GitHub Copilot** — Menghasilkan `chatLanguageModels.json` untuk VS Code dengan pemilihan model massal
+- **Wizard Orientasi** — Pengaturan terpandu 4 langkah untuk pengguna pertama kali
+- **Satu endpoint, semua model** — Konfigurasi `http://localhost:20128/v1` sekali, akses 100+ penyedia
-🔑 8. "Managing OAuth tokens from multiple providers is hell"
+🔑 8. "Mengelola token OAuth dari beberapa penyedia adalah mimpi buruk"
-Claude Code, Codex, Gemini CLI, Copilot — all use OAuth 2.0 with expiring tokens. Developers need to re-authenticate constantly, deal with `client_secret is missing`, `redirect_uri_mismatch`, and failures on remote servers. OAuth on LAN/VPS is particularly problematic.
+Claude Code, Codex, Gemini CLI, Copilot — semua menggunakan OAuth 2.0 dengan token yang kedaluwarsa. Developer perlu mengautentikasi ulang terus-menerus, menangani `client_secret is missing`, `redirect_uri_mismatch`, dan kegagalan di server jarak jauh. OAuth di LAN/VPS sangat bermasalah.
-**How OmniRoute solves it:**
+**Cara OmniRoute menyelesaikannya:**
-- **Auto Token Refresh** — OAuth tokens refresh in background before expiration
-- **OAuth 2.0 (PKCE) Built-in** — Automatic flow for Claude Code, Codex, Gemini CLI, Copilot, Kiro, Qwen, Qoder
-- **Multi-Account OAuth** — Multiple accounts per provider via JWT/ID token extraction
-- **OAuth LAN/Remote Fix** — Private IP detection for `redirect_uri` + manual URL mode for remote servers
-- **OAuth Behind Nginx** — Uses `window.location.origin` for reverse proxy compatibility
-- **Remote OAuth Guide** — Step-by-step guide for Google Cloud credentials on VPS/Docker
+- **Refresh Token Otomatis** — Token OAuth diperbarui di latar belakang sebelum kedaluwarsa
+- **OAuth 2.0 (PKCE) Bawaan** — Alur otomatis untuk Claude Code, Codex, Gemini CLI, Copilot, Kiro, Qwen, Qoder
+- **OAuth Multi-Akun** — Beberapa akun per penyedia melalui ekstraksi token JWT/ID
+- **Perbaikan OAuth LAN/Jarak Jauh** — Deteksi IP privat untuk `redirect_uri` + mode URL manual untuk server jarak jauh
+- **OAuth di Balik Nginx** — Menggunakan `window.location.origin` untuk kompatibilitas reverse proxy
+- **Panduan OAuth Jarak Jauh** — Panduan langkah demi langkah untuk kredensial Google Cloud di VPS/Docker
-📊 9. "I don't know how much I'm spending or where"
+📊 9. "Saya tidak tahu berapa banyak yang saya belanjakan atau di mana"
-Developers use multiple paid providers but have no unified view of spending. Each provider has its own billing dashboard, but there's no consolidated view. Unexpected costs can pile up.
+Developer menggunakan beberapa penyedia berbayar tetapi tidak memiliki tampilan pengeluaran yang terpadu. Setiap penyedia memiliki dashboard penagihan sendiri, tetapi tidak ada tampilan konsolidasi. Biaya tak terduga bisa menumpuk.
-**How OmniRoute solves it:**
+**Cara OmniRoute menyelesaikannya:**
-- **Cost Analytics Dashboard** — Per-token cost tracking and budget management per provider
-- **Budget Limits per Tier** — Spending ceiling per tier that triggers automatic fallback
-- **Per-Model Pricing Configuration** — Configurable prices per model
-- **Usage Statistics Per API Key** — Request count and last-used timestamp per key
-- **Analytics Dashboard** — Stat cards, model usage chart, provider table with success rates and latency
+- **Dashboard Analitik Biaya** — Pelacakan biaya per-token dan manajemen anggaran per penyedia
+- **Batas Anggaran per Tier** — Batas pengeluaran per tier yang memicu fallback otomatis
+- **Konfigurasi Harga Per-Model** — Harga yang dapat dikonfigurasi per model
+- **Statistik Penggunaan Per Kunci API** — Jumlah permintaan dan cap waktu terakhir digunakan per kunci
+- **Dashboard Analitik** — Kartu statistik, grafik penggunaan model, tabel penyedia dengan tingkat keberhasilan dan latensi
-🐛 10. "I can't diagnose errors and problems in AI calls"
+🐛 10. "Saya tidak dapat mendiagnosis kesalahan dan masalah dalam panggilan AI"
-When a call fails, the dev doesn't know if it was a rate limit, expired token, wrong format, or provider error. Fragmented logs across different terminals. Without observability, debugging is trial-and-error.
+Saat panggilan gagal, pengembang tidak mengetahui apakah itu batas kecepatan, token kedaluwarsa, format salah, atau kesalahan penyedia. Log terfragmentasi di terminal yang berbeda. Tanpa observabilitas, debugging adalah trial-and-error.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- **Unified Logs Dashboard** — 4 tabs: Request Logs, Proxy Logs, Audit Logs, Console
-- **Console Log Viewer** — Real-time terminal-style viewer with color-coded levels, auto-scroll, search, filter
-- **SQLite Summary Logs** — Request and proxy log indexes stay queryable across restarts without loading large payload blobs into SQLite
-- **Translator Playground** — 4 debugging modes: Playground (format translation), Chat Tester (round-trip), Test Bench (batch), Live Monitor (real-time)
-- **Request Telemetry** — p50/p95/p99 latency + X-Request-Id tracing
-- **File-Based Detail Artifacts** — App logs rotate by size, retention days, and archive count; detailed request/response payloads live in `DATA_DIR/call_logs/` and rotate independently of SQLite summaries
-- **System Info Report** — `npm run system-info` generates `system-info.txt` with your full environment (Node version, OmniRoute version, OS, CLI tools, Docker/PM2 status). Attach it when reporting issues for instant triage.
+- **Dasbor Log Terpadu** — 4 tab: Log Permintaan, Log Proksi, Log Audit, Konsol
+- **Penampil Log Konsol** — Penampil gaya terminal real-time dengan level kode warna, gulir otomatis, pencarian, filter
+- **Log Ringkasan SQLite** — Indeks log permintaan dan proksi tetap dapat dikueri saat restart tanpa memuat blob payload besar ke SQLite
+- **Translator Playground** — 4 mode debugging: Playground (terjemahan format), Chat Tester (pulang pergi), Test Bench (batch), Live Monitor (real-time)
+- **Telemetri Permintaan** — latensi p50/p95/p99 + penelusuran X-Request-Id
+- **Artefak Detail Berbasis File** — Log aplikasi dirotasi berdasarkan ukuran, hari penyimpanan, dan jumlah arsip; payload permintaan/respons terperinci ada di `DATA_DIR/call_logs/` dan diputar secara independen dari ringkasan SQLite
+- **Laporan Info Sistem** — `npm run system-info` menghasilkan `system-info.txt` dengan lingkungan lengkap Anda (versi Node, versi OmniRoute, OS, alat CLI, status Docker/PM2). Lampirkan saat melaporkan masalah untuk triase instan.
-🏗️ 11. "Deploying and maintaining the gateway is complex"
+🏗️ 11. "Menyebarkan dan memelihara gateway itu rumit"
-Installing, configuring, and maintaining an AI proxy across different environments (local, VPS, Docker, cloud) is labor-intensive. Problems like hardcoded paths, `EACCES` on directories, port conflicts, and cross-platform builds add friction.
+Menginstal, mengonfigurasi, dan memelihara proksi AI di berbagai lingkungan (lokal, VPS, Docker, cloud) membutuhkan banyak tenaga. Masalah seperti jalur hardcode, `EACCES` pada direktori, konflik port, dan pembangunan lintas platform menambah gesekan.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- **npm global install** — `npm install -g omniroute && omniroute` — done
-- **Docker Multi-Platform** — AMD64 + ARM64 native (Apple Silicon, AWS Graviton, Raspberry Pi)
-- **Docker Compose Profiles** — `base` (no CLI tools) and `cli` (with Claude Code, Codex, OpenClaw)
-- **Electron Desktop App** — Native app for Windows/macOS/Linux with system tray, auto-start, offline mode
-- **Split-Port Mode** — API and Dashboard on separate ports for advanced scenarios (reverse proxy, container networking)
-- **Cloud Sync** — Config synchronization across devices via Cloudflare Workers
-- **DB Backups** — Automatic backup, restore, export and import of all settings, with `DISABLE_SQLITE_AUTO_BACKUP` for externally managed backups
+- **instal global npm** — `npm install -g omniroute && omniroute` — selesai
+- **Docker Multi-Platform** — asli AMD64 + ARM64 (Apple Silicon, AWS Graviton, Raspberry Pi)
+- **Docker Compose Profiles** — `base` (tanpa alat CLI) dan `cli` (dengan Claude Code, Codex, OpenClaw)
+- **Aplikasi Desktop Electron** — Aplikasi asli untuk Windows/macOS/Linux dengan baki sistem, mulai otomatis, mode offline
+- **Mode Port Terpisah** — API dan Dasbor pada port terpisah untuk skenario tingkat lanjut (proksi terbalik, jaringan kontainer)
+- **Cloud Sync** — Konfigurasi sinkronisasi antar perangkat melalui Cloudflare Workers
+- **DB Backups** — Pencadangan otomatis, pemulihan, ekspor dan impor semua pengaturan, dengan `DISABLE_SQLITE_AUTO_BACKUP` untuk pencadangan yang dikelola secara eksternal
-🌍 12. "The interface is English-only and my team doesn't speak English"
+🌍 12. "Antarmuka hanya berbahasa Inggris dan tim saya tidak bisa berbahasa Inggris"
-Teams in non-English-speaking countries, especially in Latin America, Asia, and Europe, struggle with English-only interfaces. Language barriers reduce adoption and increase configuration errors.
+Tim di negara-negara yang tidak berbahasa Inggris, khususnya di Amerika Latin, Asia, dan Eropa, kesulitan dengan antarmuka yang hanya berbahasa Inggris. Hambatan bahasa mengurangi adopsi dan meningkatkan kesalahan konfigurasi.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- **Dashboard i18n — 30 Languages** — All 500+ keys translated including Arabic, Bulgarian, Danish, German, Spanish, Finnish, French, Hebrew, Hindi, Hungarian, Indonesian, Italian, Japanese, Korean, Malay, Dutch, Norwegian, Polish, Portuguese (PT/BR), Romanian, Russian, Slovak, Swedish, Thai, Ukrainian, Vietnamese, Chinese, Filipino, English
-- **RTL Support** — Right-to-left support for Arabic and Hebrew
-- **Multi-Language READMEs** — 30 complete documentation translations
-- **Language Selector** — Globe icon in header for real-time switching
+- **Dasbor i18n — 30 Bahasa** — 500+ tombol diterjemahkan termasuk Arab, Bulgaria, Denmark, Jerman, Spanyol, Finlandia, Prancis, Ibrani, Hindi, Hungaria, Indonesia, Italia, Jepang, Korea, Melayu, Belanda, Norwegia, Polandia, Portugis (PT/BR), Rumania, Rusia, Slovakia, Swedia, Thailand, Ukraina, Vietnam, China, Filipina, Inggris
+- **Dukungan RTL** — Dukungan kanan ke kiri untuk bahasa Arab dan Ibrani
+- **README Multi-Bahasa** — 30 terjemahan dokumentasi lengkap
+- **Pemilih Bahasa** — Ikon bola dunia di header untuk peralihan waktu nyata
-🔄 13. "I need more than chat — I need embeddings, images, audio"
+🔄 13. "Saya memerlukan lebih dari sekedar chat — saya memerlukan embeddings, gambar, audio"
-AI isn't just chat completion. Devs need to generate images, transcribe audio, create embeddings for RAG, rerank documents, and moderate content. Each API has a different endpoint and format.
+AI bukan hanya penyelesaian obrolan. Pengembang perlu membuat gambar, mentranskripsikan audio, membuat penyematan untuk RAG, mengubah peringkat dokumen, dan memoderasi konten. Setiap API memiliki titik akhir dan format yang berbeda.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- **Embeddings** — `/v1/embeddings` with 6 providers and 9+ models
-- **Image Generation** — `/v1/images/generations` with 10 providers and 20+ models (OpenAI, xAI, Together, Fireworks, Nebius, Hyperbolic, NanoBanana, Antigravity, SD WebUI, ComfyUI)
-- **Text-to-Video** — `/v1/videos/generations` — ComfyUI (AnimateDiff, SVD) and SD WebUI
-- **Text-to-Music** — `/v1/music/generations` — ComfyUI (Stable Audio Open, MusicGen)
-- **Audio Transcription** — `/v1/audio/transcriptions` — Whisper + Nvidia NIM, HuggingFace, Qwen3
-- **Text-to-Speech** — `/v1/audio/speech` — ElevenLabs, Nvidia NIM, HuggingFace, Coqui, Tortoise, Qwen3, **Inworld**, **Cartesia**, **PlayHT**, + existing providers
-- **Moderations** — `/v1/moderations` — Content safety checks
-- **Reranking** — `/v1/rerank` — Document relevance reranking
-- **Responses API** — Full `/v1/responses` support for Codex
+- **Sematan** — `/v1/embeddings` dengan 6 penyedia dan 9+ model
+- **Pembuatan Gambar** — `/v1/images/generations` dengan 10 penyedia dan 20+ model (OpenAI, xAI, Together, Fireworks, Nebius, Hyperbolic, NanoBanana, Antigravity, SD WebUI, ComfyUI)
+- **Teks-ke-Video** — `/v1/videos/generations` — ComfyUI (AnimateDiff, SVD) dan SD WebUI
+- **Teks-ke-Musik** — `/v1/music/generations` — ComfyUI (Audio Terbuka Stabil, MusicGen)
+- **Transkripsi Audio** — `/v1/audio/transcriptions` — Whisper + Nvidia NIM, HuggingFace, Qwen3
+- **Text-to-Speech** — `/v1/audio/speech` — ElevenLabs, Nvidia NIM, HuggingFace, Coqui, Tortoise, Qwen3, **Inworld**, **Cartesia**, **PlayHT**, + penyedia yang ada
+- **Moderasi** — `/v1/moderations` — Pemeriksaan keamanan konten
+- **Pemeringkatan ulang** — `/v1/rerank` — Pemeringkatan ulang relevansi dokumen
+- **Respon API** — Dukungan penuh `/v1/responses` untuk Codex
-🧪 14. "I have no way to test and compare quality across models"
+🧪 14. "Saya tidak punya cara untuk menguji dan membandingkan kualitas antar model"
-Developers want to know which model is best for their use case — code, translation, reasoning — but comparing manually is slow. No integrated eval tools exist.
+Pengembang ingin mengetahui model mana yang terbaik untuk kasus penggunaan mereka — kode, terjemahan, penalaran — tetapi membandingkan secara manual itu lambat. Tidak ada alat evaluasi terintegrasi.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- **LLM Evaluations** — Golden set testing with 10 pre-loaded cases covering greetings, math, geography, code generation, JSON compliance, translation, markdown, safety refusal
-- **4 Match Strategies** — `exact`, `contains`, `regex`, `custom` (JS function)
-- **Translator Playground Test Bench** — Batch testing with multiple inputs and expected outputs, cross-provider comparison
-- **Chat Tester** — Full round-trip with visual response rendering
-- **Live Monitor** — Real-time stream of all requests flowing through the proxy
+- **Evaluasi LLM** — Pengujian set emas dengan 10 kasus yang dimuat sebelumnya yang mencakup salam, matematika, geografi, pembuatan kode, kepatuhan JSON, terjemahan, penurunan harga, penolakan keamanan
+- **4 Strategi Pertandingan** — `exact`, `contains`, `regex`, `custom` (fungsi JS)
+- **Bangku Tes Taman Bermain Penerjemah** — Pengujian batch dengan banyak masukan dan keluaran yang diharapkan, perbandingan lintas penyedia
+- **Penguji Obrolan** — Perjalanan bolak-balik penuh dengan rendering respons visual
+- **Monitor Langsung** — Aliran real-time dari semua permintaan yang mengalir melalui proxy
-📈 15. "I need to scale without losing performance"
+📈 15. "Saya perlu meningkatkan skala tanpa kehilangan performa"
-As request volume grows, without caching the same questions generate duplicate costs. Without idempotency, duplicate requests waste processing. Per-provider rate limits must be respected.
+Seiring bertambahnya volume permintaan, tanpa menyimpan pertanyaan yang sama akan menghasilkan biaya duplikat. Tanpa idempotensi, permintaan duplikat akan membuang-buang pemrosesan. Batasan tarif per penyedia harus dipatuhi.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- **Semantic Cache** — Two-tier cache (signature + semantic) reduces cost and latency
-- **Request Idempotency** — 5s deduplication window for identical requests
-- **Rate Limit Detection** — Per-provider RPM, min gap, and max concurrent tracking
-- **Request Queue & Pacing** — Configurable queue, pacing, and concurrency defaults in Settings → Resilience
-- **API Key Validation Cache** — 3-tier cache for production performance
-- **Health Dashboard with Telemetry** — p50/p95/p99 latency, cache stats, uptime
+- **Cache Semantik** — Cache dua tingkat (tanda tangan + semantik) mengurangi biaya dan latensi
+- **Request Idempoency** — Jendela deduplikasi 5 detik untuk permintaan yang identik
+- **Deteksi Batas Tarif** — RPM per penyedia, selisih minimum, dan pelacakan serentak maks
+- **Antrian & Kecepatan Permintaan** — Antrean, kecepatan, dan kecepatan konkurensi yang dapat dikonfigurasi secara default di Pengaturan → Ketahanan
+- **Cache Validasi Kunci API** — cache 3 tingkat untuk kinerja produksi
+- **Dasbor Kesehatan dengan Telemetri** — latensi p50/p95/p99, statistik cache, waktu aktif
-🤖 16. "I want to control model behavior globally"
+🤖 16. "Saya ingin mengontrol perilaku model secara global"
-Developers who want all responses in a specific language, with a specific tone, or want to limit reasoning tokens. Configuring this in every tool/request is impractical.
+Pengembang yang menginginkan semua respons dalam bahasa tertentu, dengan nada tertentu, atau ingin membatasi token penalaran. Mengonfigurasi ini di setiap alat/permintaan tidak praktis.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- **System Prompt Injection** — Global prompt applied to all requests
-- **Thinking Budget Validation** — Reasoning token allocation control per request (passthrough, auto, custom, adaptive)
-- **9 Routing Strategies** — Global strategies that determine how requests are distributed
-- **Wildcard Router** — `provider/*` patterns route dynamically to any provider
-- **Combo Enable/Disable Toggle** — Toggle combos directly from the dashboard
-- **Manual Combo Ordering** — Drag combo cards by handle and persist the order in SQLite
-- **Provider Toggle** — Enable/disable all connections for a provider with one click
-- **Blocked Providers** — Exclude specific providers from `/v1/models` listing
+- **Injeksi Perintah Sistem** — Perintah global diterapkan ke semua permintaan
+- **Validasi Anggaran Berpikir** — Kontrol alokasi token penalaran per permintaan (passthrough, otomatis, kustom, adaptif)
+- **9 Strategi Perutean** — Strategi global yang menentukan cara permintaan didistribusikan
+- **Wildcard Router** — pola `provider/*` merutekan secara dinamis ke penyedia mana pun
+- **Combo Aktifkan/Nonaktifkan Toggle** — Beralih kombo langsung dari dasbor
+- **Pengurutan Kombo Manual** — Seret kartu kombo berdasarkan pegangan dan pertahankan pesanan di SQLite
+- **Toggle Penyedia** — Mengaktifkan/menonaktifkan semua koneksi untuk penyedia dengan satu klik
+- **Penyedia yang Diblokir** — Kecualikan penyedia tertentu dari daftar `/v1/models`
-🧰 17. "I need MCP tools as first-class product capabilities"
+🧰 17. "Saya membutuhkan alat MCP sebagai kemampuan produk kelas satu"
Many AI gateways expose MCP only as a hidden implementation detail. Teams need a visible, manageable operation layer.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- MCP appears in the dashboard navigation and endpoint protocol tab
-- Dedicated MCP management page with process, tools, scopes, and audit
-- Built-in quick-start for `omniroute --mcp` and client onboarding
+- MCP muncul di navigasi dasbor dan tab protokol titik akhir
+- Halaman manajemen MCP khusus dengan proses, alat, cakupan, dan audit
+- Mulai cepat bawaan untuk `omniroute --mcp` dan orientasi klien
-🧠 18. "I need A2A orchestration with sync + stream task paths"
+🧠 18. "Saya memerlukan orkestrasi A2A dengan jalur tugas sinkronisasi + streaming"
-Agent workflows need both direct replies and long-running streamed execution with lifecycle control.
+Alur kerja agen memerlukan balasan langsung dan eksekusi streaming jangka panjang dengan kontrol siklus hidup.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- A2A JSON-RPC endpoint (`POST /a2a`) with `message/send` and `message/stream`
-- SSE streaming with terminal state propagation
-- Task lifecycle APIs for `tasks/get` and `tasks/cancel`
+- Titik akhir A2A JSON-RPC (`POST /a2a`) dengan `message/send` dan `message/stream`
+- Streaming SSE dengan propagasi status terminal
+- API siklus hidup tugas untuk `tasks/get` dan `tasks/cancel`
-🛰️ 19. "I need real MCP process health, not guessed status"
+🛰️ 19. "Saya membutuhkan kesehatan proses MCP yang nyata, bukan status yang dapat ditebak"
-Operational teams need to know if MCP is actually alive, not just whether an API is reachable.
+Tim operasional perlu mengetahui apakah MCP benar-benar aktif, bukan hanya apakah API dapat dijangkau.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- Runtime heartbeat file with PID, timestamps, transport, tool count, and scope mode
-- MCP status API combining heartbeat + recent activity
-- UI status cards for process/uptime/heartbeat freshness
+- File detak jantung runtime dengan PID, stempel waktu, transportasi, jumlah alat, dan mode cakupan
+- API status MCP menggabungkan detak jantung + aktivitas terkini
+- Kartu status UI untuk kesegaran proses/waktu aktif/detak jantung
-📋 20. "I need auditable MCP tool execution"
+📋 20. "Saya memerlukan eksekusi alat MCP yang dapat diaudit"
-When tools mutate config or trigger ops actions, teams need forensic traceability.
+Saat alat mengubah konfigurasi atau memicu tindakan operasi, tim memerlukan kemampuan penelusuran forensik.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- SQLite-backed audit logging for MCP tool calls
-- Filters by tool, success/failure, API key, and pagination
-- Dashboard audit table + stats endpoints for automation
+- Pencatatan audit yang didukung SQLite untuk panggilan alat MCP
+- Filter berdasarkan alat, keberhasilan/kegagalan, kunci API, dan penomoran halaman
+- Tabel audit dasbor + titik akhir statistik untuk otomatisasi
-🔐 21. "I need scoped MCP permissions per integration"
+🔐 21. "Saya memerlukan izin MCP terbatas per integrasi"
Different clients should have least-privilege access to tool categories.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- 10 granular MCP scopes for controlled tool access
-- Scope enforcement and visibility in MCP management UI
-- Safe default posture for operational tooling
+- 10 cakupan MCP granular untuk akses alat terkontrol
+- Penegakan cakupan dan visibilitas di UI manajemen MCP
+- Postur default yang aman untuk perkakas operasional
-⚙️ 22. "I need operational controls without redeploying"
+⚙️ 22. "Saya memerlukan kontrol operasional tanpa memindahkan"
-Teams need quick runtime changes during incidents or cost events.
+Tim memerlukan perubahan runtime yang cepat selama insiden atau peristiwa biaya.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- Switch combo activation directly from MCP dashboard
-- Tune queue, cooldown, breaker, and wait settings from the dedicated Resilience page
-- Review live provider breaker state from the Health dashboard
+- Beralih aktivasi kombo langsung dari dasbor MCP
+- Sesuaikan pengaturan antrean, cooldown, pemutus, dan tunggu dari halaman Ketahanan khusus
+- Tinjau status pemutus penyedia langsung dari dasbor Kesehatan
-🔄 23. "I need live A2A task lifecycle visibility and cancellation"
+🔄 23. "Saya memerlukan visibilitas dan pembatalan siklus hidup tugas A2A langsung"
Without lifecycle visibility, task incidents become hard to triage.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- Task listing/filtering by state/skill with pagination
-- Drill-down on task metadata, events, and artifacts
-- Task cancellation endpoint and UI action with confirmation
+- Daftar tugas/pemfilteran berdasarkan status/keterampilan dengan penomoran halaman
+- Telusuri metadata tugas, peristiwa, dan artefak
+- Titik akhir pembatalan tugas dan tindakan UI dengan konfirmasi
-🌊 24. "I need active stream metrics for A2A load"
+🌊 24. "Saya memerlukan metrik aliran aktif untuk memuat A2A"
-Streaming workflows require operational insight into concurrency and live connections.
+Alur kerja streaming memerlukan wawasan operasional tentang konkurensi dan koneksi langsung.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- Active stream counters integrated into A2A status
-- Last task timestamp and per-state counts
-- A2A dashboard cards for real-time ops monitoring
+- Penghitung aliran aktif terintegrasi ke dalam status A2A
+- Stempel waktu tugas terakhir dan jumlah per negara bagian
+- Kartu dasbor A2A untuk pemantauan operasi waktu nyata
-🪪 25. "I need standard agent discovery for clients"
+🪪 25. "Saya memerlukan penemuan agen standar untuk klien"
-External clients and orchestrators need machine-readable metadata for onboarding.
+Klien dan orkestra eksternal memerlukan metadata yang dapat dibaca mesin untuk orientasi.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- Agent Card exposed at `/.well-known/agent.json`
-- Capabilities and skills shown in management UI
-- A2A status API includes discovery metadata for automation
+- Kartu Agen terungkap di `/.well-known/agent.json`
+- Kemampuan dan keterampilan yang ditunjukkan dalam manajemen UI
+- API status A2A mencakup metadata penemuan untuk otomatisasi
-🧭 26. "I need protocol discoverability in the product UX"
+🧭 26. "Saya memerlukan kemampuan protokol untuk ditemukan di UX produk"
If users cannot discover protocol surfaces, adoption and support quality drop.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- Consolidated **Endpoints** page with tabs for Proxy, MCP, A2A, and API Endpoints
-- Inline service status toggles (Online/Offline) for MCP and A2A
-- Links from overview to dedicated management tabs
+- Halaman **Endpoint** terkonsolidasi dengan tab untuk Proxy, MCP, A2A, dan API Endpoints
+- Pengalih status layanan inline (Online/Offline) untuk MCP dan A2A
+- Tautan dari ikhtisar ke tab manajemen khusus
-🧪 27. "I need end-to-end protocol validation with real clients"
+🧪 27. "Saya memerlukan validasi protokol end-to-end dengan klien nyata"
Mock tests are not enough to validate protocol compatibility before release.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- E2E suite that boots app and uses real MCP SDK client transport
-- A2A client tests for discovery, send, stream, get, and cancel flows
-- Cross-check assertions against MCP audit and A2A tasks APIs
+- Suite E2E yang mem-boot aplikasi dan menggunakan transportasi klien MCP SDK yang sebenarnya
+- Klien A2A menguji penemuan, pengiriman, streaming, dapatkan, dan pembatalan aliran
+- Periksa silang pernyataan terhadap audit MCP dan API tugas A2A
-📡 28. "I need unified observability across all interfaces"
+📡 28. "Saya memerlukan observabilitas terpadu di semua antarmuka"
Splitting observability by protocol creates blind spots and longer MTTR.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- Unified dashboards/logs/analytics in one product
-- Health + audit + request telemetry across OpenAI, MCP, and A2A layers
-- Operational APIs for status and automation
+- Dasbor/log/analitik terpadu dalam satu produk
+- Kesehatan + audit + permintaan telemetri di seluruh lapisan OpenAI, MCP, dan A2A
+- API Operasional untuk status dan otomatisasi
-💼 29. "I need one runtime for proxy + tools + agent orchestration"
+💼 29. "Saya memerlukan satu runtime untuk proxy + alat + orkestrasi agen"
-Running many separate services increases operational cost and failure modes.
+Menjalankan banyak layanan terpisah akan meningkatkan biaya operasional dan mode kegagalan.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- OpenAI-compatible proxy, MCP server, and A2A server in one stack
-- Shared auth, resilience, data store, and observability
-- Consistent policy model across all interaction surfaces
+- Proksi yang kompatibel dengan OpenAI, server MCP, dan server A2A dalam satu tumpukan
+- Otentikasi bersama, ketahanan, penyimpanan data, dan kemampuan observasi
+- Model kebijakan yang konsisten di seluruh platform interaksi
-🚀 30. "I need to ship agentic workflows without glue-code sprawl"
+🚀 30. "Saya perlu mengirim workflow agentic tanpa tumpukan glue code"
-Teams lose velocity when stitching multiple ad-hoc services and scripts.
+Tim kehilangan kecepatan saat menggabungkan beberapa layanan dan skrip ad-hoc.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- Unified endpoint strategy for clients and agents
-- Built-in protocol management UIs and smoke validation paths
-- Production-ready foundations (security, logging, resilience, backup)
+- Strategi titik akhir terpadu untuk klien dan agen
+- UI manajemen protokol bawaan dan jalur validasi asap
+- Fondasi siap produksi (keamanan, logging, ketahanan, cadangan)
-📚 31. "My long sessions crash with 'context_length_exceeded' limits"
+📚 31. "Sesi panjang saya crash karena batas 'context_length_exceeded'"
-During deep debugging, long histories with tool results quickly exceed provider token windows, causing failed requests and orphaned context.
+Selama proses debug mendalam, riwayat panjang dengan hasil alat dengan cepat melampaui jendela token penyedia, menyebabkan permintaan gagal dan konteks tidak ada lagi.
-**How OmniRoute solves it:**
+**Bagaimana OmniRoute menyelesaikannya:**
-- **Proactive Context Compression** — Evaluates token budgets before the request hits upstream and proactively prunes old conversation history with a smart binary-search mechanism.
-- **Structural Integrity Guards** — Automatically tracks explicit `tool_use` definitions and ensures that if a tool input is truncated, its corresponding `tool_result` is also safely removed, preventing API validation errors.
-- **Multi-Layer Dropping** — Progressively drops system messages, regular messages, and finally enforces strict length limits without breaking conversational logic.
+- **Kompresi Konteks Proaktif** — Mengevaluasi anggaran token sebelum permintaan mencapai hulu dan secara proaktif memangkas riwayat percakapan lama dengan mekanisme pencarian biner yang cerdas.
+- **Pengaman Integritas Struktural** — Secara otomatis melacak definisi `tool_use` yang eksplisit dan memastikan bahwa jika masukan alat terpotong, `tool_result` yang terkait juga dihapus dengan aman, sehingga mencegah kesalahan validasi API.
+- **Penghapusan Multi-Lapisan** — Secara progresif menghapus pesan sistem, pesan biasa, dan akhirnya menerapkan batas panjang yang ketat tanpa merusak logika percakapan.
-### Example Playbooks (Integrated Use Cases)
+### Contoh Playbook (Kasus Penggunaan Terintegrasi)
**Playbook A: Maximize paid subscription + cheap backup**
@@ -707,7 +707,7 @@ Monthly cost: $20 + small backup spend
Outcome: higher quality, near-zero interruption
```
-**Playbook B: Zero-cost coding stack**
+**Playbook B: Tumpukan coding tanpa biaya**
```txt
Combo: "free-forever"
@@ -719,7 +719,7 @@ Monthly cost: $0
Outcome: stable free coding workflow
```
-**Playbook C: 24/7 always-on fallback chain**
+**Playbook C: Rantai fallback yang selalu aktif 24/7**
```txt
Combo: "always-on"
@@ -732,7 +732,7 @@ Combo: "always-on"
Outcome: deep fallback depth for deadline-critical workloads
```
-**Playbook D: Agent ops with MCP + A2A**
+**Playbook D: Operasi agen dengan MCP + A2A**
```txt
1) Start MCP transport (`omniroute --mcp`) for tool-driven operations
@@ -743,44 +743,44 @@ Outcome: deep fallback depth for deadline-critical workloads
---
-## 🆓 Start Free — Zero Configuration Cost
+## 🆓 Mulai Gratis — Tanpa Biaya Konfigurasi
-> Setup AI coding in minutes at **$0/month**. Connect these free accounts and use the built-in **Free Stack** combo.
+> Siapkan pengkodean AI dalam hitungan menit di **$0/bulan**. Hubungkan akun gratis ini dan gunakan kombo **Free Stack** bawaan.
| Step | Action | Providers Unlocked |
| ---- | -------------------------------------------------- | ------------------------------------------------------------------ |
| 1 | Connect **Kiro** (AWS Builder ID OAuth) | Claude Sonnet 4.5, Haiku 4.5 — **unlimited** |
| 2 | Connect **Qoder** (Google OAuth) | kimi-k2-thinking, qwen3-coder-plus, deepseek-r1... — **unlimited** |
| 3 | Connect **Qwen** (Device Code) | qwen3-coder-plus, qwen3-coder-flash... — **unlimited** |
-| 4 | Connect **Gemini CLI** (Google OAuth) | gemini-3-flash, gemini-2.5-pro — **180K/mo free** |
-| 5 | `/dashboard/combos` → **Free Stack ($0)** template | Round-robin all free providers automatically |
+| 4 | Connect **Gemini CLI** (Google OAuth) | gemini-3-flash, gemini-2.5-pro — **Gratis 180K/bln** |
+| 5 | `/dashboard/combos` → **Templat Tumpukan Gratis ($0)** | Round-robin semua penyedia gratis secara otomatis |
-**Point any IDE/CLI to:** `http://localhost:20128/v1` · API Key: `any-string` · Done.
+**Arahkan IDE/CLI apa pun ke:** `http://localhost:20128/v1` · Kunci API: `any-string` · Selesai.
-> **Optional extra coverage (also free):** Groq API key (30 RPM free), NVIDIA NIM (40 RPM free, 70+ models), Cerebras (1M tok/day), LongCat API key (50M tokens/day!), Cloudflare Workers AI (10K Neurons/day, 50+ models).
+> **Cakupan ekstra opsional (juga gratis):** Kunci API Groq (gratis 30 RPM), NVIDIA NIM (gratis 40 RPM, 70+ model), Cerebras (1 juta tok/hari), kunci API LongCat (50 juta token/hari!), Cloudflare Workers AI (10 ribu neuron/hari, 50+ model).
## Mulai Cepat
-### 1) Install and run
+### 1) Instal dan jalankan
```bash
npm install -g omniroute
omniroute
```
-> **pnpm users:** Run `pnpm approve-builds -g` after install to enable native build scripts required by `better-sqlite3` and `@swc/core`:
+> **pengguna pnpm:** Jalankan `pnpm approve-builds -g` setelah instalasi untuk mengaktifkan skrip build asli yang diperlukan oleh `better-sqlite3` dan `@swc/core`:
>
> ```bash
> pnpm install -g omniroute
-> pnpm approve-builds -g # Select all packages → approve
+> pnpm approve-builds -g # Pilih semua paket → approve
> omniroute
> ```
-Dashboard opens at `http://localhost:20128` and API base URL is `http://localhost:20128/v1`.
+Dasbor terbuka di `http://localhost:20128` dan URL dasar API adalah `http://localhost:20128/v1`.
#### Arch Linux (AUR)
-Arch Linux users can install the [AUR package](https://aur.archlinux.org/packages/omniroute-bin), which installs OmniRoute and provides a systemd user service:
+Pengguna Arch Linux dapat menginstal [AUR package](https://aur.archlinux.org/packages/omniroute-bin), yang menginstal OmniRoute dan menyediakan layanan pengguna systemd:
```bash
yay -S omniroute-bin
@@ -789,9 +789,9 @@ systemctl --user enable --now omniroute.service
| Command | Description |
| ----------------------- | ----------------------------------------------------------- |
-| `omniroute` | Start server (`PORT=20128`, API and dashboard on same port) |
+| `omniroute` | Mulai server (`PORT=20128`, API dan dasbor pada port yang sama) |
| `omniroute --port 3000` | Set canonical/API port to 3000 |
-| `omniroute --mcp` | Start MCP server (stdio transport) |
+| `omniroute --mcp` | Mulai server MCP (stdio transport) |
| `omniroute --no-open` | Don't auto-open browser |
| `omniroute --help` | Show help |
@@ -803,63 +803,63 @@ PORT=20128 DASHBOARD_PORT=20129 omniroute
# Dashboard: http://localhost:20129
```
-### 2) Uninstalling
+### 2) Menghapus Instalasi
-When you no longer need OmniRoute, we provide two quick scripts for a clean removal:
+Saat Anda tidak lagi memerlukan OmniRoute, kami menyediakan dua skrip cepat untuk penghapusan bersih:
| Command | Action |
| ------------------------ | ----------------------------------------------------------------------------------- |
-| `npm run uninstall` | Removes the system app but **keeps your DB and configurations** in `~/.omniroute`. |
-| `npm run uninstall:full` | Removes the app AND permanently **erases all configurations, keys, and databases**. |
+| `npm run uninstall` | Menghapus aplikasi sistem tetapi **menyimpan DB dan konfigurasi Anda** di `~/.omniroute`. |
+| `npm run uninstall:full` | Menghapus aplikasi DAN secara permanen **menghapus semua konfigurasi, kunci, dan database**. |
-> Note: To run these commands, navigate to the OmniRoute project folder (if you cloned it) and run them. Alternatively, if globally installed, you can simply run `npm uninstall -g omniroute`.
+> Catatan: Untuk menjalankan perintah ini, navigasikan ke folder proyek OmniRoute (jika Anda mengkloningnya) dan jalankan. Alternatifnya, jika diinstal secara global, Anda cukup menjalankan `npm uninstall -g omniroute`.
-### Long-Running Streaming Timeouts
+### Batas Waktu Streaming yang Berlangsung Lama
-For most deployments, you only need:
+Untuk sebagian besar penerapan, Anda hanya memerlukan:
| Variable | Default | Purpose |
| ------------------------ | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
-| `REQUEST_TIMEOUT_MS` | `600000` | Shared baseline for upstream response-start timeout, hidden Undici timeouts, TLS fingerprint requests, and API bridge request/proxy timeouts |
-| `STREAM_IDLE_TIMEOUT_MS` | inherits `REQUEST_TIMEOUT_MS` | Maximum gap between streaming chunks before OmniRoute aborts the SSE stream |
+| `REQUEST_TIMEOUT_MS` | `600000` | Garis dasar bersama untuk batas waktu mulai respons upstream, batas waktu Undici yang tersembunyi, permintaan sidik jari TLS, dan batas waktu permintaan/proksi jembatan API |
+| `STREAM_IDLE_TIMEOUT_MS` | inherits `REQUEST_TIMEOUT_MS` | Kesenjangan maksimum antara potongan streaming sebelum OmniRoute membatalkan aliran SSE |
-Backward compatibility is preserved: existing `FETCH_TIMEOUT_MS`, `API_BRIDGE_PROXY_TIMEOUT_MS`, and other per-layer timeout vars still work and override the shared baseline.
+Kompatibilitas mundur dipertahankan: `FETCH_TIMEOUT_MS`, `API_BRIDGE_PROXY_TIMEOUT_MS`, dan var batas waktu per lapisan lainnya yang ada masih berfungsi dan menggantikan garis dasar bersama.
-For Claude Code-compatible upstreams (`anthropic-compatible-cc-*`), OmniRoute also derives the outbound `X-Stainless-Timeout` header from the resolved fetch timeout so provider-side read timeouts stay aligned with your env configuration.
+Untuk upstream yang kompatibel dengan Kode Claude (`anthropic-compatible-cc-*`), OmniRoute juga memperoleh header `X-Stainless-Timeout` keluar dari batas waktu pengambilan yang diselesaikan sehingga batas waktu baca sisi penyedia tetap selaras dengan konfigurasi env Anda.
-For third-party Claude Code-compatible reverse proxies, OmniRoute keeps the default
-`anthropic-beta` set conservative and, when `Client Cache Control` is left on `Auto`,
-only forwards client-provided `cache_control` markers. If the request does not include
-`cache_control`, OmniRoute does not inject bridge-owned markers.
+Untuk reverse proxy pihak ketiga yang kompatibel dengan Claude Code, OmniRoute tetap menggunakan default
+`anthropic-beta` disetel konservatif dan, ketika `Client Cache Control` tersisa di `Auto`,
+hanya meneruskan penanda `cache_control` yang disediakan klien. Jika permintaan tidak menyertakan
+`cache_control`, OmniRoute tidak memasukkan penanda milik jembatan.
-Advanced overrides are available if you need finer control:
+Penggantian tingkat lanjut tersedia jika Anda memerlukan kontrol yang lebih baik:
| Variable | Default | Purpose |
| ---------------------------------------- | ------------------------------------------ | -------------------------------------------------------------------- |
-| `FETCH_TIMEOUT_MS` | inherits `REQUEST_TIMEOUT_MS` | Upstream response-start timeout used until response headers arrive |
-| `FETCH_HEADERS_TIMEOUT_MS` | inherits `FETCH_TIMEOUT_MS` | Undici time limit for receiving upstream response headers |
+| `FETCH_TIMEOUT_MS` | inherits `REQUEST_TIMEOUT_MS` | Batas waktu mulai respons hulu digunakan hingga header respons tiba |
+| `FETCH_HEADERS_TIMEOUT_MS` | inherits `FETCH_TIMEOUT_MS` | Batas waktu Undici untuk menerima header respons upstream |
| `FETCH_BODY_TIMEOUT_MS` | inherits `FETCH_TIMEOUT_MS` | Undici time limit between upstream body chunks (`0` disables it) |
| `FETCH_CONNECT_TIMEOUT_MS` | `30000` | Undici TCP connect timeout |
| `FETCH_KEEPALIVE_TIMEOUT_MS` | `4000` | Undici idle keep-alive socket timeout |
-| `TLS_CLIENT_TIMEOUT_MS` | inherits `FETCH_TIMEOUT_MS` | Timeout for TLS fingerprint requests made through `wreq-js` |
-| `API_BRIDGE_PROXY_TIMEOUT_MS` | inherits `REQUEST_TIMEOUT_MS` or `600000` | Timeout for `/v1` proxy forwarding from API port to dashboard port |
-| `API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS` | `max(API_BRIDGE_PROXY_TIMEOUT_MS, 300000)` | Incoming request timeout on the API bridge server |
-| `API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS` | `60000` | Incoming header timeout on the API bridge server |
-| `API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS` | `5000` | Keep-alive timeout on the API bridge server |
-| `API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS` | `0` | Socket inactivity timeout on the API bridge server (`0` disables it) |
+| `TLS_CLIENT_TIMEOUT_MS` | inherits `FETCH_TIMEOUT_MS` | Batas waktu untuk permintaan sidik jari TLS yang dilakukan melalui `wreq-js` |
+| `API_BRIDGE_PROXY_TIMEOUT_MS` | inherits `REQUEST_TIMEOUT_MS` or `600000` | Batas waktu untuk penerusan proxy `/v1` dari port API ke port dasbor |
+| `API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS` | `max(API_BRIDGE_PROXY_TIMEOUT_MS, 300000)` | Batas waktu permintaan masuk di server jembatan API |
+| `API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS` | `60000` | Batas waktu header masuk di server jembatan API |
+| `API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS` | `5000` | Batas waktu tetap hidup di server jembatan API|
+| `API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS` | `0` |Batas waktu ketidakaktifan soket di server jembatan API (`0` menonaktifkannya) |
-For streaming requests, `FETCH_TIMEOUT_MS` only covers connection setup / waiting for the first upstream response. Once the stream is active, OmniRoute will only abort on an actual stall (`STREAM_IDLE_TIMEOUT_MS`) or Undici body inactivity (`FETCH_BODY_TIMEOUT_MS`).
+Untuk permintaan streaming, `FETCH_TIMEOUT_MS` hanya mencakup pengaturan koneksi/menunggu respons upstream pertama. Setelah aliran aktif, OmniRoute hanya akan dibatalkan pada keadaan terhenti sebenarnya (`STREAM_IDLE_TIMEOUT_MS`) atau tubuh Undici tidak aktif (`FETCH_BODY_TIMEOUT_MS`).
-If you run OmniRoute behind Nginx, Caddy, Cloudflare, or another reverse proxy, make sure the proxy
-timeouts are also higher than your OmniRoute stream/fetch timeouts.
+Jika Anda menjalankan OmniRoute di belakang Nginx, Caddy, Cloudflare, atau proksi terbalik lainnya, pastikan proksi tersebut
+waktu tunggu juga lebih tinggi daripada waktu tunggu aliran/pengambilan OmniRoute Anda.
-### 2) Connect providers and create your API key
+### 2) Hubungkan penyedia dan buat kunci API Anda
-1. Open Dashboard → `Providers` and connect at least one provider (OAuth or API key).
-2. Open Dashboard → `Endpoints` and create an API key.
-3. (Optional) Open Dashboard → `Combos` and set your fallback chain.
+1. Buka Dasbor → `Providers` dan sambungkan setidaknya satu penyedia (OAuth atau kunci API).
+2. Buka Dasbor → `Endpoints` dan buat kunci API.
+3. (Opsional) Buka Dasbor → `Combos` dan atur rantai cadangan Anda.
-### 3) Point your coding tool to OmniRoute
+### 3) Arahkan alat pengkodean Anda ke OmniRoute
```txt
Base URL: http://localhost:20128/v1
@@ -867,22 +867,22 @@ API Key: [copy from Endpoint page]
Model: if/kimi-k2-thinking (or any provider/model prefix)
```
-Works with Claude Code, Codex CLI, Gemini CLI, Cursor, Cline, OpenClaw, OpenCode, and OpenAI-compatible SDKs.
+Bekerja dengan Claude Code, Codex CLI, Gemini CLI, Cursor, Cline, OpenClaw, OpenCode, dan SDK yang kompatibel dengan OpenAI.
-### 4) Enable and validate protocols (v2.0)
+### 4) Mengaktifkan dan memvalidasi protokol (v2.0)
-**MCP (for tool-driven operations):**
+**MCP (untuk operasi yang digerakkan oleh alat):**
```bash
omniroute --mcp
```
-Then connect your MCP client over `stdio` and test tools like:
+Kemudian sambungkan klien MCP Anda melalui `stdio` dan uji alat seperti:
- `omniroute_get_health`
- `omniroute_list_combos`
-**A2A (for agent-to-agent workflows):**
+**A2A (untuk alur kerja agen-ke-agen):**
```bash
curl http://localhost:20128/.well-known/agent.json
@@ -894,15 +894,15 @@ curl -X POST http://localhost:20128/a2a \
-d '{"jsonrpc":"2.0","id":"quickstart","method":"message/send","params":{"skill":"quota-management","messages":[{"role":"user","content":"Give me a short quota summary."}]}}'
```
-### 5) Validate everything end-to-end (recommended)
+### 5) Validasi semuanya end-to-end (direkomendasikan)
```bash
npm run test:protocols:e2e
```
-This suite validates real MCP and A2A client flows against a running app.
+Suite ini memvalidasi alur klien MCP dan A2A yang sebenarnya terhadap aplikasi yang sedang berjalan.
-### Alternative: run from source
+### Alternatif: dijalankan dari sumber
```bash
cp .env.example .env
@@ -913,7 +913,7 @@ PORT=20128 DASHBOARD_PORT=20129 NEXT_PUBLIC_BASE_URL=http://localhost:20129 npm
Void Linux (`xbps-src` template)
-For Void Linux users, you can build a native package using `xbps-src`. Save this block as `srcpkgs/omniroute/template`:
+Untuk pengguna Void Linux, Anda dapat membuat paket asli menggunakan `xbps-src`. Simpan blok ini sebagai `srcpkgs/omniroute/template`:
```bash
# Template file for 'omniroute'
@@ -1021,7 +1021,7 @@ post_install() {
## 🐳 Docker
-OmniRoute is available as a public Docker image on [Docker Hub](https://hub.docker.com/r/diegosouzapw/omniroute).
+OmniRoute tersedia sebagai image Docker publik di [Docker Hub](https://hub.docker.com/r/diegosouzapw/omniroute).
**Quick run:**
@@ -1035,7 +1035,7 @@ docker run -d \
diegosouzapw/omniroute:latest
```
-**With environment file:**
+**Dengan file lingkungan:**
```bash
# Copy and edit .env first
@@ -1051,7 +1051,7 @@ docker run -d \
diegosouzapw/omniroute:latest
```
-**Using Docker Compose:**
+**Menggunakan Docker Tulis:**
```bash
# Base profile (no CLI tools)
@@ -1061,22 +1061,22 @@ docker compose --profile base up -d
docker compose --profile cli up -d
```
-Dashboard support for Docker deployments now includes a one-click **Cloudflare Quick Tunnel** on `Dashboard → Endpoints`. The first enable downloads `cloudflared` only when needed, starts a temporary tunnel to your current `/v1` endpoint, and shows the generated `https://*.trycloudflare.com/v1` URL directly below your normal public URL.
+Dukungan dasbor untuk penerapan Docker kini mencakup **Cloudflare Quick Tunnel** sekali klik di `Dashboard → Endpoints`. Yang pertama mengaktifkan pengunduhan `cloudflared` hanya bila diperlukan, memulai terowongan sementara ke titik akhir `/v1` Anda saat ini, dan menampilkan URL `https://*.trycloudflare.com/v1` yang dihasilkan langsung di bawah URL publik normal Anda.
Notes:
-- Quick Tunnel URLs are temporary and change after every restart.
-- Quick Tunnels are not auto-restored after an OmniRoute or container restart. Re-enable them from the dashboard when needed.
-- Managed install currently supports Linux, macOS, and Windows on `x64` / `arm64`.
-- Managed Quick Tunnels default to HTTP/2 transport to avoid noisy QUIC UDP buffer warnings in constrained container environments. Set `CLOUDFLARED_PROTOCOL=quic` or `auto` if you want a different transport.
-- Docker images bundle system CA roots and pass them to managed `cloudflared`, which avoids TLS trust failures when the tunnel bootstraps inside the container.
-- SQLite runs in WAL mode. `docker stop` should be allowed to finish so OmniRoute can checkpoint the latest changes back into `storage.sqlite`.
-- The bundled Compose files already set a 40s stop grace period. If you run the image directly, keep `--stop-timeout 40` (or similar) so manual stops do not cut off shutdown cleanup.
-- Set `CLOUDFLARED_BIN=/absolute/path/to/cloudflared` if you want OmniRoute to use an existing binary instead of downloading one.
+- URL Terowongan Cepat bersifat sementara dan berubah setelah setiap restart.
+- Terowongan Cepat tidak dipulihkan secara otomatis setelah OmniRoute atau kontainer dimulai ulang. Aktifkan kembali dari dasbor bila diperlukan.
+- Penginstalan terkelola saat ini mendukung Linux, macOS, dan Windows di `x64` / `arm64`.
+- Terkelola Quick Tunnels default ke transportasi HTTP/2 untuk menghindari peringatan buffer UDP QUIC yang berisik di lingkungan kontainer yang terbatas. Setel `CLOUDFLARED_PROTOCOL=quic` atau `auto` jika Anda menginginkan transportasi lain.
+- Gambar Docker menggabungkan akar CA sistem dan meneruskannya ke `cloudflared` yang dikelola, yang menghindari kegagalan kepercayaan TLS ketika terowongan melakukan bootstrap di dalam wadah.
+- SQLite berjalan dalam mode WAL. `docker stop` harus dibiarkan selesai sehingga OmniRoute dapat memeriksa kembali perubahan terbaru ke `storage.sqlite`.
+- File Compose yang dibundel sudah menetapkan masa tenggang penghentian 40 detik. Jika Anda menjalankan image secara langsung, pertahankan `--stop-timeout 40` (atau serupa) sehingga penghentian manual tidak menghentikan pembersihan pematian.
+- Setel `CLOUDFLARED_BIN=/absolute/path/to/cloudflared` jika Anda ingin OmniRoute menggunakan biner yang sudah ada alih-alih mengunduhnya.
-**Using Docker Compose with Caddy (HTTPS Auto-TLS):**
+**Menggunakan Docker Compose dengan Caddy (HTTPS Auto-TLS):**
-OmniRoute can be securely exposed using Caddy's automatic SSL provisioning. Ensure your domain's DNS A record points to your server's IP.
+OmniRoute dapat diekspos dengan aman menggunakan penyediaan SSL otomatis Caddy. Pastikan data DNS A domain Anda mengarah ke IP server Anda.
```yaml
services:
@@ -1110,17 +1110,17 @@ volumes:
---
-## 🖥️ Desktop App — Offline & Always-On
+## 🖥️ Aplikasi Desktop — Offline & Selalu Aktif
-> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
+> 🆕 **BARU!** OmniRoute kini tersedia sebagai **aplikasi desktop asli** untuk Windows, macOS, dan Linux.
-Run OmniRoute as a standalone desktop app — no terminal, no browser, no internet required for local models. The Electron-based app includes:
+Jalankan OmniRoute sebagai aplikasi desktop mandiri — tanpa terminal, tanpa browser, tanpa internet untuk model lokal. Aplikasi berbasis Electron meliputi:
-- 🖥️ **Native Window** — Dedicated app window with system tray integration
-- 🔄 **Auto-Start** — Launch OmniRoute on system login
-- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
-- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
-- 🌐 **Offline Mode** — Works fully offline with bundled server
+- 🖥️ **Jendela Asli** — Jendela aplikasi khusus dengan integrasi baki sistem
+- 🔄 **Mulai Otomatis** — Luncurkan OmniRoute saat login sistem
+- 🔔 **Pemberitahuan Asli** — Dapatkan peringatan jika kuota habis atau masalah penyedia
+- ⚡ **Instal Sekali Klik** — NSIS (Windows), DMG (macOS), AppImage (Linux)
+- 🌐 **Mode Offline** — Bekerja sepenuhnya offline dengan server yang dibundel
### Mulai Cepat
@@ -1137,17 +1137,17 @@ npm run electron:build:linux # Linux (.AppImage)
### System Tray
-When minimized, OmniRoute lives in your system tray with quick actions:
+Saat diminimalkan, OmniRoute ada di baki sistem Anda dengan tindakan cepat:
-- Open dashboard
-- Change server port
-- Quit application
+- Buka dasbor
+- Ubah port server
+- Keluar dari aplikasi
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
-## 💰 Pricing at a Glance
+## 💰 Harga Sekilas
| Tier | Provider | Cost | Quota Reset | Best For |
| ------------------- | --------------------------- | ------------------------- | ---------------- | --------------------------------- |
@@ -1155,31 +1155,31 @@ When minimized, OmniRoute lives in your system tray with quick actions:
| | Codex (Plus/Pro) | $20-200/mo | 5h + weekly | OpenAI users |
| | Gemini CLI | **FREE** | 180K/mo + 1K/day | Everyone! |
| | GitHub Copilot | $10-19/mo | Monthly | GitHub users |
-| **🔑 API KEY** | NVIDIA NIM | **FREE** (dev forever) | ~40 RPM | 70+ open models |
+| **🔑 API KEY** | NVIDIA NIM | **GRATIS** (pengembangan selamanya) | ~40 RPM | 70+ open models |
| | Cerebras | **FREE** (1M tok/day) | 60K TPM / 30 RPM | World's fastest |
| | Groq | **FREE** (30 RPM) | 14.4K RPD | Ultra-fast Llama/Gemma |
| | DeepSeek V3.2 | $0.27/$1.10 per 1M | None | Best price/quality reasoning |
| | xAI Grok-4 Fast | **$0.20/$0.50 per 1M** 🆕 | None | Fastest + tool calling, ultralow |
-| | xAI Grok-4 (standard) | $0.20/$1.50 per 1M 🆕 | None | Reasoning flagship from xAI |
-| | Mistral | Free trial + paid | Rate limited | European AI |
-| | OpenRouter | Pay-per-use | None | 100+ models aggr. |
+| | xAI Grok-4 (standard) | $0.20/$1.50 per 1M 🆕 | None | Penalaran andalan dari xAI |
+| | Mistral | Uji coba gratis + berbayar | Rate limited | European AI |
+| | OpenRouter | Bayar per penggunaan | None | 100+ models aggr. |
| **💰 CHEAP** | GLM-5 (via Z.AI) 🆕 | $0.5/1M | Daily 10AM | 128K output, newest flagship |
| | GLM-4.7 | $0.6/1M | Daily 10AM | Budget backup |
| | MiniMax M2.5 🆕 | $0.3/1M input | 5-hour rolling | Reasoning + agentic tasks |
| | MiniMax M2.1 | $0.2/1M | 5-hour rolling | Cheapest option |
-| | Kimi K2.5 (Moonshot API) 🆕 | Pay-per-use | None | Direct Moonshot API access |
+| | Kimi K2.5 (Moonshot API) 🆕 | Bayar per penggunaan | None | Direct Moonshot API access |
| | Kimi K2 | $9/mo flat | 10M tokens/mo | Predictable cost |
| **🆓 FREE** | Qoder | **$0** | Unlimited | 5 models unlimited |
| | Qwen | **$0** | Unlimited | 4 models unlimited |
| | Kiro | **$0** | Unlimited | Claude Sonnet/Haiku (AWS Builder) |
-| | LongCat Flash-Lite 🆕 | **$0** (50M tok/day 🔥) | 1 RPS | Largest free quota on Earth |
-| | Pollinations AI 🆕 | **$0** (no key needed) | 1 req/15s | GPT-5, Claude, DeepSeek, Llama 4 |
-| | Cloudflare Workers AI 🆕 | **$0** (10K Neurons/day) | ~150 resp/day | 50+ models, global edge |
+| | LongCat Flash-Lite 🆕 | **$0** (50M tok/day 🔥) | 1 RPS | Kuota gratis terbesar di dunia |
+| | Pollinations AI 🆕 | **$0** (tidak perlu kunci) | 1 req/15s | GPT-5, Claude, DeepSeek, Llama 4 |
+| | Cloudflare Workers AI 🆕 | **$0** (10K Neurons/day) | ~150 resp/day | 50+ model, keunggulan global |
| | Scaleway AI 🆕 | **$0** (1M tokens total) | Rate limited | EU/GDPR, Qwen3 235B, Llama 70B |
-> 🆕 **New models added (Mar 2026):** Grok-4 Fast family at $0.20/$0.50/M (benchmarked at 1143ms — 30% faster than Gemini 2.5 Flash), GLM-5 via Z.AI with 128K output, MiniMax M2.5 reasoning, DeepSeek V3.2 updated pricing, Kimi K2.5 via Moonshot direct API.
+> 🆕 **Model baru ditambahkan (Mar 2026):** Keluarga Grok-4 Fast seharga $0,20/$0,50/M (dibandingkan pada 1143ms — 30% lebih cepat dibandingkan Gemini 2.5 Flash), GLM-5 melalui Z.AI dengan output 128K, penalaran MiniMax M2.5, harga DeepSeek V3.2 yang diperbarui, Kimi K2.5 melalui API langsung Moonshot.
-**💡 $0 Combo Stack — The Complete Free Setup:**
+**💡 Tumpukan Kombo $0 — Penyiapan Gratis Lengkap:**
```
# 🆓 Ultimate Free Stack 2026 — 11 Providers, $0 Forever
@@ -1196,17 +1196,17 @@ NVIDIA NIM (nvidia/) → 70+ open models — 40 RPM forever
Cerebras (cerebras/) → Llama/Qwen world-fastest — 1M tok/day
```
-**Zero cost. Never stops coding.** Configure this as one OmniRoute combo and all fallbacks happen automatically — no manual switching ever.
+**Tanpa biaya. Jangan pernah berhenti melakukan pengkodean.** Konfigurasikan ini sebagai satu kombo OmniRoute dan semua fallback terjadi secara otomatis — tidak pernah ada peralihan manual.
---
---
-## 🆓 Free Models — What You Actually Get
+## 🆓 Model Gratis — Apa yang Sebenarnya Anda Dapatkan
-> All models below are **100% free with zero credit card required**. OmniRoute auto-routes between them when one quota runs out — combine them all for an unbreakable $0 combo.
+> Semua model di bawah **100% gratis tanpa memerlukan kartu kredit**. OmniRoute melakukan rute otomatis di antara keduanya ketika satu kuota habis — gabungkan semuanya untuk kombo $0 yang tidak dapat dipecahkan.
-### 🔵 CLAUDE MODELS (via Kiro — AWS Builder ID)
+### 🔵 MODEL CLAUDE (melalui Kiro — ID AWS Builder)
| Model | Prefix | Limit | Rate Limit |
| ------------------- | ------ | ------------- | --------------------- |
@@ -1214,7 +1214,7 @@ Cerebras (cerebras/) → Llama/Qwen world-fastest — 1M tok/day
| `claude-haiku-4.5` | `kr/` | **Unlimited** | No reported daily cap |
| `claude-opus-4.6` | `kr/` | **Unlimited** | Latest Opus via Kiro |
-### 🟢 QODER MODELS (Free PAT via qodercli)
+### 🟢 MODEL QODER (PAT Gratis melalui qodercli)
| Model | Prefix | Limit | Rate Limit |
| ------------------ | ------ | ------------- | --------------- |
@@ -1224,10 +1224,10 @@ Cerebras (cerebras/) → Llama/Qwen world-fastest — 1M tok/day
| `minimax-m2.1` | `if/` | **Unlimited** | No reported cap |
| `kimi-k2` | `if/` | **Unlimited** | No reported cap |
-> Recommended connection method: **Personal Access Token + `qodercli`**. Browser OAuth is
-> experimental and disabled by default unless `QODER_OAUTH_*` environment variables are configured.
+> Metode koneksi yang disarankan: **Token Akses Pribadi + `qodercli`**. Peramban OAuth adalah
+> eksperimental dan dinonaktifkan secara default kecuali variabel lingkungan `QODER_OAUTH_*` dikonfigurasi.
-### 🟡 QWEN MODELS (Device Code Auth)
+### 🟡 MODEL QWEN (Otentikasi Kode Perangkat)
| Model | Prefix | Limit | Rate Limit |
| ------------------- | ------ | ------------- | ------------------- |
@@ -1243,15 +1243,15 @@ Cerebras (cerebras/) → Llama/Qwen world-fastest — 1M tok/day
| `gemini-3-flash-preview` | `gc/` | **180K tok/month** + 1K/day | Monthly reset |
| `gemini-2.5-pro` | `gc/` | 180K/month (shared pool) | High quality |
-### ⚫ NVIDIA NIM (Free API Key — build.nvidia.com)
+### ⚫ NVIDIA NIM (Kunci API Gratis — build.nvidia.com)
| Tier | Daily Limit | Rate Limit | Notes |
| ---------- | ------------ | ----------- | ------------------------------------------------------ |
-| Free (Dev) | No token cap | **~40 RPM** | 70+ models; transitioning to pure rate limits mid-2025 |
+| Free (Dev) | No token cap | **~40 RPM** | 70+ model; transisi ke batas tarif murni pada pertengahan tahun 2025 |
-Popular free models: `moonshotai/kimi-k2.5` (Kimi K2.5), `z-ai/glm4.7` (GLM 4.7), `deepseek-ai/deepseek-v3.2` (DeepSeek V3.2), `nvidia/llama-3.3-70b-instruct`, `deepseek/deepseek-r1`
+Model gratis populer: `moonshotai/kimi-k2.5` (Kimi K2.5), `z-ai/glm4.7` (GLM 4.7), `deepseek-ai/deepseek-v3.2` (DeepSeek V3.2), `nvidia/llama-3.3-70b-instruct`, `deepseek/deepseek-r1`
-### ⚪ CEREBRAS (Free API Key — inference.cerebras.ai)
+### ⚪ CEREBRAS (Kunci API Gratis — inference.cerebras.ai)
| Tier | Daily Limit | Rate Limit | Notes |
| ---- | ----------------- | ---------------- | ------------------------------------------- |
@@ -1259,7 +1259,7 @@ Popular free models: `moonshotai/kimi-k2.5` (Kimi K2.5), `z-ai/glm4.7` (GLM 4.7)
Available free: `llama-3.3-70b`, `llama-3.1-8b`, `deepseek-r1-distill-llama-70b`
-### 🔴 GROQ (Free API Key — console.groq.com)
+### 🔴 GROQ (Kunci API Gratis — console.groq.com)
| Tier | Daily Limit | Rate Limit | Notes |
| ---- | ------------- | ---------------- | ----------------------------------------- |
@@ -1267,19 +1267,19 @@ Available free: `llama-3.3-70b`, `llama-3.1-8b`, `deepseek-r1-distill-llama-70b`
Available free: `llama-3.3-70b-versatile`, `gemma2-9b-it`, `mixtral-8x7b`, `whisper-large-v3`
-### 🔴 LONGCAT AI (Free API Key — longcat.chat) 🆕
+### 🔴 LONGCAT AI (Kunci API Gratis — longcat.chat) 🆕
-| Model | Prefix | Daily Free Quota | Notes |
+| Model | Prefix | Kuota Gratis Harian | Notes |
| ----------------------------- | ------ | ----------------- | ----------------------- |
-| `LongCat-Flash-Lite` | `lc/` | **50M tokens** 💥 | Largest free quota ever |
+| `LongCat-Flash-Lite` | `lc/` | **50M tokens** 💥 | Kuota gratis terbesar yang pernah ada |
| `LongCat-Flash-Chat` | `lc/` | 500K tokens | Multi-turn chat |
| `LongCat-Flash-Thinking` | `lc/` | 500K tokens | Reasoning / CoT |
| `LongCat-Flash-Thinking-2601` | `lc/` | 500K tokens | Jan 2026 version |
| `LongCat-Flash-Omni-2603` | `lc/` | 500K tokens | Multimodal |
-> 100% free while in public beta. Sign up at [longcat.chat](https://longcat.chat) with email or phone. Resets daily 00:00 UTC.
+> 100% gratis saat dalam versi beta publik. Daftar di [longcat.chat](https://longcat.chat) dengan email atau telepon. Reset setiap hari pukul 00:00 UTC.
-### 🟢 POLLINATIONS AI (No API Key Required) 🆕
+### 🟢 POLLINASI AI (Tidak Perlu Kunci API) 🆕
| Model | Prefix | Rate Limit | Provider Behind |
| ---------- | ------ | ---------- | ------------------ |
@@ -1290,52 +1290,52 @@ Available free: `llama-3.3-70b-versatile`, `gemma2-9b-it`, `mixtral-8x7b`, `whis
| `llama` | `pol/` | 1 req/15s | Meta Llama 4 Scout |
| `mistral` | `pol/` | 1 req/15s | Mistral AI |
-> ✨ **Zero friction:** No signup, no API key. Add the Pollinations provider with an empty key field and it works immediately.
+> ✨ **Tanpa gesekan:** Tanpa pendaftaran, tanpa kunci API. Tambahkan penyedia Penyerbukan dengan bidang kunci kosong dan itu langsung berfungsi.
-### 🟠 CLOUDFLARE WORKERS AI (Free API Key — cloudflare.com) 🆕
+### 🟠 AI CLOUDFLARE WORKERS (Kunci API Gratis — cloudflare.com) 🆕
| Tier | Daily Neurons | Equivalent Usage | Notes |
| ---- | ------------- | --------------------------------------- | ----------------------- |
-| Free | **10,000** | ~150 LLM resp / 500s audio / 15K embeds | Global edge, 50+ models |
+| Free | **10,000** | ~150 LLM resp / 500s audio / 15K embeds | Keunggulan global, 50+ model |
-Popular free models: `@cf/meta/llama-3.3-70b-instruct`, `@cf/google/gemma-3-12b-it`, `@cf/openai/whisper-large-v3-turbo` (free audio!), `@cf/qwen/qwen2.5-coder-15b-instruct`
+Model gratis populer: `@cf/meta/llama-3.3-70b-instruct`, `@cf/google/gemma-3-12b-it`, `@cf/openai/whisper-large-v3-turbo` (audio gratis!), `@cf/qwen/qwen2.5-coder-15b-instruct`
-> Requires API Token + Account ID from [dash.cloudflare.com](https://dash.cloudflare.com). Store Account ID in provider settings.
+> Membutuhkan Token API + ID Akun dari [dash.cloudflare.com](https://dash.cloudflare.com). Simpan ID Akun di pengaturan penyedia.
-### 🟣 SCALEWAY AI (1M Free Tokens — scaleway.com) 🆕
+### 🟣 SCALEWAY AI (1 Juta Token Gratis — scaleway.com) 🆕
| Tier | Free Quota | Location | Notes |
| ---- | ------------- | ------------ | ----------------------------------- |
| Free | **1M tokens** | 🇫🇷 Paris, EU | No credit card needed within limits |
-Available free: `qwen3-235b-a22b-instruct-2507` (Qwen3 235B!), `llama-3.1-70b-instruct`, `mistral-small-3.2-24b-instruct-2506`, `deepseek-v3-0324`
+Tersedia gratis: `qwen3-235b-a22b-instruct-2507` (Qwen3 235B!), `llama-3.1-70b-instruct`, `mistral-small-3.2-24b-instruct-2506`, `deepseek-v3-0324`
-> EU/GDPR compliant. Get API key at [console.scaleway.com](https://console.scaleway.com).
+> Sesuai dengan UE/GDPR. Dapatkan kunci API di [console.scaleway.com](https://console.scaleway.com).
-> **💡 The Ultimate Free Stack (11 Providers, $0 Forever):**
+> **💡 Tumpukan Gratis Terbaik (11 Penyedia, $0 Selamanya):**
>
> ```
-> Kiro (kr/) → Claude Sonnet/Haiku UNLIMITED
-> Qoder (if/) → kimi-k2-thinking, qwen3-coder-plus, deepseek-r1 UNLIMITED
-> LongCat Lite (lc/) → LongCat-Flash-Lite — 50M tokens/day 🔥
-> Pollinations (pol/) → GPT-5, Claude, DeepSeek, Llama 4 — no key needed
-> Qwen (qw/) → qwen3-coder models UNLIMITED
-> Gemini (gemini/) → Gemini 2.5 Flash — 1,500 req/day free
-> Cloudflare AI (cf/) → 50+ models — 10K Neurons/day
-> Scaleway (scw/) → Qwen3 235B, Llama 70B — 1M free tokens (EU)
-> Groq (groq/) → Llama/Gemma — 14.4K req/day ultra-fast
-> NVIDIA NIM (nvidia/) → 70+ open models — 40 RPM forever
-> Cerebras (cerebras/) → Llama/Qwen world-fastest — 1M tok/day
+> Kiro (kr/) → Claude Sonnet/Haiku TANPA BATAS
+> Qoder (if/) → kimi-k2-thinking, qwen3-coder-plus, deepseek-r1 TANPA BATAS
+> LongCat Lite (lc/) → LongCat-Flash-Lite — 50 juta token/hari 🔥
+> Pollinations (pol/) → GPT-5, Claude, DeepSeek, Llama 4 — tidak perlu kunci
+> Qwen (qw/) → model qwen3-coder TANPA BATAS
+> Gemini (gemini/) → Gemini 2.5 Flash — 1.500 req/hari gratis
+> Cloudflare AI (cf/) → 50+ model — 10 ribu Neurons/hari
+> Scaleway (scw/) → Qwen3 235B, Llama 70B — 1 juta token gratis (EU)
+> Groq (groq/) → Llama/Gemma — 14,4 ribu req/hari, sangat cepat
+> NVIDIA NIM (nvidia/) → 70+ model terbuka — 40 RPM selamanya
+> Cerebras (cerebras/) → Llama/Qwen tercepat di dunia — 1 juta tok/hari
> ```
-## 🎙️ Free Transcription Combo
+## 🎙️ Kombo Transkripsi Gratis
-> Transcribe any audio/video for **$0** — Deepgram leads with $200 free, AssemblyAI $50 fallback, Groq Whisper as unlimited emergency backup.
+> Transkripsikan audio/video apa pun seharga **$0** — Deepgram memimpin dengan $200 gratis, penggantian AssemblyAI $50, Groq Whisper sebagai cadangan darurat tanpa batas.
| Provider | Free Credits | Best Model | Rate Limit |
| ----------------- | ---------------------- | -------------------------------------------- | ---------------------------- |
-| 🟢 **Deepgram** | **$200 free** (signup) | `nova-3` — best accuracy, 30+ languages | No RPM limit on free credits |
-| 🔵 **AssemblyAI** | **$50 free** (signup) | `universal-3-pro` — chapters, sentiment, PII | No RPM limit on free credits |
+| 🟢 **Deepgram** | **$200 free** (signup) | `nova-3` — best accuracy, 30+ languages | Tidak ada batasan RPM pada kredit gratis |
+| 🔵 **AssemblyAI** | **$50 free** (signup) | `universal-3-pro` — chapters, sentiment, PII | Tidak ada batasan RPM pada kredit gratis |
| 🔴 **Groq** | **Free forever** | `whisper-large-v3` — OpenAI Whisper | 30 RPM (rate limited) |
**Suggested combo in `/dashboard/combos`:**
@@ -1349,181 +1349,181 @@ Nodes:
[3] groq/whisper-large-v3 → free forever, emergency fallback
```
-Then in `/dashboard/media` → **Transcription** tab: upload any audio or video file → select your combo endpoint → get transcription in supported formats.
+Kemudian di tab `/dashboard/media` → **Transkripsi**: unggah file audio atau video apa pun → pilih titik akhir kombo Anda → dapatkan transkripsi dalam format yang didukung.
-## 💡 Key Features
+## 💡 Fitur Utama
-OmniRoute v3.6 is built as an operational platform, not just a relay proxy.
+OmniRoute v3.6 dibangun sebagai platform operasional, bukan hanya proxy relai.
-### 🆕 New — v3.6.x Highlights (Apr 2026)
+### 🆕 Baru — Sorotan v3.6.x (Apr 2026)
-| Feature | What It Does |
+| Feature | Apa Fungsinya |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
-| 🌐 **V1 WebSocket Bridge** | OpenAI-compatible WebSocket traffic upgraded and proxied via `/v1/ws` — full streaming over WS with session auth (API key or session cookie) |
-| 🔑 **Sync Tokens & Config Bundle** | Issue/revoke sync tokens for config sync endpoints. Config bundles versioned with ETag for bandwidth-efficient polling |
+| 🌐 **V1 WebSocket Bridge** | Lalu lintas WebSocket yang kompatibel dengan OpenAI ditingkatkan dan diproksi melalui `/v1/ws` — streaming penuh melalui WS dengan autentikasi sesi (kunci API atau cookie sesi) |
+| 🔑 **Sync Tokens & Config Bundle** | Menerbitkan/mencabut token sinkronisasi untuk titik akhir sinkronisasi konfigurasi. Paket konfigurasi diversi dengan ETag untuk polling hemat bandwidth |
| 🧠 **GLM Thinking (glmt) Preset** | GLM Thinking registered first-class: 65 536 max tokens, 24 576 thinking budget, 900s timeout, usage sync & pricing — Claude-compatible API |
-| 🔢 **Hybrid Token Counting** | Uses provider-side `/messages/count_tokens` when available; falls back to estimation — accurate usage tracking without guessing |
-| 🌱 **Model Alias Auto-Seed** | 30+ cross-proxy dialect aliases normalised at startup — no more routing mismatches |
-| 🛡️ **Safe Outbound Fetch** | All provider validation and model discovery go through a guarded fetch layer blocking private/local URLs with retry, timeout, and SSRF protection |
-| ⏳ **Wait For Cooldown** | Server-side chat retries when every candidate connection is cooling down; configurable `enabled`, `maxRetries`, and `maxRetryWaitSec` |
-| 🔍 **Runtime Env Validation** | Startup validates all env vars with Zod schemas — clear errors for missing secrets, invalid URLs, or wrong types |
-| 📋 **Compliance Audit Expansion** | Structured audit logs with pagination, request context, auth events, provider CRUD events, and SSRF-blocked validation logging |
-| 🔐 **TPS Log Metric** | Log details modal shows Tokens Per Second (TPS) — quick performance at-a-glance for every request |
-| 🗑️ **Uninstall / Full Uninstall** | `npm run uninstall` keeps data, `npm run uninstall:full` removes everything — clean removal for all install methods |
-| 🔧 **OAuth Env Repair** | One-click "Repair env" action for OAuth providers restores missing env vars and fixes broken auth state |
-| 🔒 **Graceful Electron Shutdown** | Electron `before-quit` shuts down Next.js gracefully, preventing SQLite WAL database locks on desktop close |
-| 👁️ **Model Visibility Toggle** | Per-model visibility toggle (👁 icon) with search filter and active-count badge (`N/M active`) on provider pages |
+| 🔢 **Hybrid Token Counting** | Menggunakan `/messages/count_tokens` sisi penyedia jika tersedia; kembali ke perkiraan — pelacakan penggunaan yang akurat tanpa menebak-nebak|
+|🌱 **Model Alias Benih Otomatis** | 30+ cross-proxy dialect aliases normalised at startup — no more routing mismatches |
+| 🛡️ **Safe Outbound Fetch** | Semua validasi penyedia dan penemuan model melalui lapisan pengambilan yang dilindungi yang memblokir URL pribadi/lokal dengan percobaan ulang, batas waktu, dan perlindungan SSRF |
+| ⏳ **Tunggu Masa Tenang** | Percobaan ulang obrolan sisi server ketika setiap koneksi kandidat sedang dingin; dapat dikonfigurasi `enabled`, `maxRetries`, dan `maxRetryWaitSec` |
+| 🔍 **Validasi Env Runtime** | Startup memvalidasi semua env vars dengan skema Zod - menghapus kesalahan untuk rahasia yang hilang, URL yang tidak valid, atau tipe yang salah |
+| 📋 **Compliance Audit Expansion** | Log audit terstruktur dengan penomoran halaman, konteks permintaan, peristiwa autentikasi, peristiwa CRUD penyedia, dan pencatatan validasi yang diblokir SSRF |
+| 🔐 **TPS Log Metric** | Modal detail log menunjukkan Token Per Second (TPS) — sekilas kinerja cepat untuk setiap permintaan |
+| 🗑️ **Uninstall / Full Uninstall** | `npm run uninstall` menyimpan data, `npm run uninstall:full` menghapus semuanya — penghapusan bersih untuk semua metode instalasi |
+| 🔧 **OAuth Env Repair** | Tindakan "Perbaiki env" sekali klik untuk penyedia OAuth memulihkan vars env yang hilang dan memperbaiki status autentikasi yang rusak |
+| 🔒 **Pematian Elektron yang Anggun** | Electron `before-quit` dimatikan Next.js dengan baik, mencegah penguncian database SQLite WAL pada penutupan desktop |
+| 👁️ **Pengalih Visibilitas Model** | Pengalih visibilitas per model (ikon 👁) dengan filter pencarian dan lencana jumlah aktif (`N/M active`) di halaman penyedia |
| 📧 **Email Privacy Masking** | OAuth account emails masked (`di*****@g****.com`), full address visible on hover |
-| 🔗 **Context Relay Strategy** | Combo strategy preserving session continuity via structured handoff summaries when accounts rotate mid-conversation |
-| 🛡️ **Proxy Hardening** | Token health check, API key validation, and undici dispatcher all honor proxy config |
+| 🔗 **Context Relay Strategy** | Strategi kombo menjaga kesinambungan sesi melalui ringkasan penyerahan terstruktur saat akun dirotasi di tengah percakapan |
+| 🛡️ **Proxy Hardening** | Pemeriksaan kesehatan token, validasi kunci API, dan operator undici semuanya menghormati konfigurasi proxy |
| ⚠️ **Node.js 24 Login Warning** | Login page proactively detects incompatible Node.js versions and shows a clear warning banner |
| 📎 **Gemini PDF Attachments** | PDF attachments correctly routed to Gemini via `inline_data` and generic base64 detection |
-| 🔒 **CodeQL Security Hardening** | Resolved SSRF, insecure randomness, polynomial ReDoS, and incomplete URL sanitization alerts |
+| 🔒 **Pengerasan Keamanan CodeQL** | Resolved SSRF, insecure randomness, polynomial ReDoS, and incomplete URL sanitization alerts |
-### 🆕 New — ClawRouter-Inspired Improvements (Mar 2026)
+### 🆕 Baru — Peningkatan Terinspirasi ClawRouter (Mar 2026)
-| Feature | What It Does |
+| Feature | Apa Fungsinya |
| ------------------------------------ | ------------------------------------------------------------------------------------------- |
| ⚡ **Grok-4 Fast Family** | xAI models at $0.20/$0.50/M — benchmarked 1143ms (30% faster than Gemini 2.5 Flash) |
-| 🧠 **GLM-5 via Z.AI** | 128K output context, $0.5/1M — newest flagship from the GLM family |
-| 🔮 **MiniMax M2.5** | Reasoning + agentic tasks at $0.30/1M — significant upgrade from M2.1 |
-| 🎯 **toolCalling Flag per Model** | Per-model `toolCalling: true/false` in registry — AutoCombo skips non-tool-capable models |
-| 🌍 **Multilingual Intent Detection** | PT/ZH/ES/AR keywords in AutoCombo scoring — better model selection for non-English content |
-| 📊 **Benchmark-Driven Fallbacks** | Real p95 latency from live requests feeds combo scoring — AutoCombo learns from actual data |
+| 🧠 **GLM-5 via Z.AI** | Konteks keluaran 128 ribu, $0,5/1 juta — andalan terbaru dari keluarga GLM |
+| 🔮 **MiniMax M2.5** | Penalaran + tugas agen seharga $0,30/1 juta — peningkatan signifikan dari M2.1|
+|🎯 **alat Memanggil Bendera per Model** | Per model `toolCalling: true/false` di registri — AutoCombo melewatkan model yang tidak mendukung alat |
+| 🌍 **Multilingual Intent Detection** | Kata kunci PT/ZH/ES/AR dalam penilaian AutoCombo — pemilihan model yang lebih baik untuk konten non-Inggris |
+| 📊 **Benchmark-Driven Fallbacks** | Latensi p95 nyata dari penilaian kombo umpan permintaan langsung — AutoCombo belajar dari data aktual |
| 🔁 **Request Deduplication** | Content-hash based dedup window — multi-agent safe, prevents duplicate charges |
-| 🔌 **Pluggable RouterStrategy** | Extensible `RouterStrategy` interface — add custom routing logic as plugins |
+| 🔌 **Pluggable RouterStrategy** | Antarmuka `RouterStrategy` yang dapat diperluas — tambahkan logika perutean khusus sebagai plugin |
-### 🚀 Previous v2.0.9+ — Playground, CLI Fingerprints & ACP
+### 🚀 Sebelumnya v2.0.9+ — Playground, Fingerprint CLI & ACP
-| Feature | What It Does |
+| Feature | Apa Fungsinya |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
-| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
-| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw + 9 more), process spawner, `/api/acp/agents` endpoint |
-| 🤖 **ACP Agents Dashboard** | Debug › Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool. **OpenCode** users get a "Download opencode.json" button that auto-generates a ready-to-use config with all available models. |
-| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
+| 🎮 **Model Playground** | Halaman dasbor untuk menguji model apa pun secara langsung — pemilih penyedia/model/titik akhir, Editor Monaco, streaming, batalkan, pengaturan waktu |
+| 🔏 **CLI Fingerprint Matching** | Pengurutan header/isi per penyedia agar sesuai dengan tanda tangan CLI asli — alihkan per penyedia di Pengaturan > Keamanan. **IP proxy Anda dipertahankan** |
+| 🤝 **Dukungan ACP (Protokol Klien Agen)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw + 9 more), process spawner, `/api/acp/agents` endpoint |
+| 🤖 **Dasbor Agen ACP** | Debug › Halaman agen — kisi 14 agen dengan status pemasangan, versi, formulir agen khusus untuk alat CLI apa pun. Pengguna **OpenCode** mendapatkan tombol "Unduh opencode.json" yang secara otomatis menghasilkan konfigurasi siap pakai dengan semua model yang tersedia. |
+| 🔧 **Custom Model `apiFormat` Routing** | Model khusus dengan `apiFormat: "responses"` sekarang dirutekan dengan benar ke penerjemah Responses API |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
-| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
+| 🔄 **Pembaruan Otomatis Elektron** | Aplikasi desktop memeriksa pembaruan + instal otomatis saat restart |
-### 🤖 Agent & Protocol Operations (v2.0)
+### 🤖 Operasi Agen & Protokol (v2.0)
-| Feature | What It Does |
+| Feature | Apa Fungsinya |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
-| 🔧 **MCP Server (25 tools)** | IDE/agent tools via 3 transports: stdio, SSE (`/api/mcp/sse`), Streamable HTTP (`/api/mcp/stream`). 18 core + 3 memory + 4 skill tools |
-| 🤝 **A2A Server (JSON-RPC + SSE)** | Agent-to-agent task execution with sync and streaming flows |
-| 🧭 **Consolidated Endpoints Page** | Tabbed management page with Endpoint Proxy, MCP, A2A, and API Endpoints tabs |
-| 🎚️ **Service Enable/Disable Toggles** | ON/OFF switches for MCP and A2A with settings persistence (default: OFF) |
-| 🛰️ **MCP Runtime Heartbeat** | Real process status (pid, uptime, heartbeat age, transport, scope mode) |
-| 📋 **MCP Audit Trail** | Filterable audit logs with success/failure and key attribution |
-| 🔐 **MCP Scope Enforcement** | 10 granular scope permissions for controlled tool access |
-| 📡 **A2A Task Lifecycle Management** | List/filter tasks, inspect events/artifacts, cancel running tasks |
-| 📋 **Agent Card Discovery** | `/.well-known/agent.json` for client auto-discovery |
-| 🧪 **Protocol E2E Test Harness** | Real MCP SDK + A2A client flows in `test:protocols:e2e` |
-| ⚙️ **Operational Controls** | Switch combos, tune resilience settings, and review breaker state from dedicated Health and Settings surfaces |
+| 🔧 **Server MCP (25 alat)** | IDE/agent tools via 3 transports: stdio, SSE (`/api/mcp/sse`), Streamable HTTP (`/api/mcp/stream`). 18 core + 3 memory + 4 skill tools |
+| 🤝 **Server A2A (JSON-RPC + SSE)** | Eksekusi tugas agen-ke-agen dengan alur sinkronisasi dan streaming |
+| 🧭 **Halaman Titik Akhir Konsolidasi** | Halaman manajemen bertab dengan tab Proksi Titik Akhir, MCP, A2A, dan Titik Akhir API|
+| 🎚️ **Service Enable/Disable Toggles** |Sakelar ON/OFF untuk MCP dan A2A dengan pengaturan persistensi (default: OFF) |
+| 🛰️ **Detak Jantung Waktu Proses MCP** | Real process status (pid, uptime, heartbeat age, transport, scope mode) |
+| 📋 **MCP Audit Trail** | Log audit yang dapat difilter dengan keberhasilan/kegagalan dan atribusi kunci |
+| 🔐 **MCP Scope Enforcement** | 10 izin cakupan terperinci untuk akses alat terkontrol |
+| 📡 **Manajemen Siklus Hidup Tugas A2A** | List/filter tasks, inspect events/artifacts, cancel running tasks |
+| 📋 **Agent Card Discovery** | `/.well-known/agent.json` untuk penemuan otomatis klien |
+| 🧪 **Protocol E2E Test Harness** | Klien MCP SDK + A2A asli mengalir di `test:protocols:e2e` |
+| ⚙️ **Operational Controls** | Ganti kombo, sesuaikan pengaturan ketahanan, dan tinjau status pemutus dari permukaan Kesehatan dan Pengaturan khusus |
-### 🧠 Routing & Intelligence
+### 🧠 Routing & Kecerdasan
-| Feature | What It Does |
+| Feature | Apa Fungsinya |
| ---------------------------------- | ------------------------------------------------------------------------ |
-| 🎯 **Smart 4-Tier Fallback** | Auto-route: Subscription → API Key → Cheap → Free |
-| 📊 **Real-Time Quota Tracking** | Live token count + reset countdown per provider |
-| 🔄 **Format Translation** | OpenAI ↔ Claude ↔ Gemini ↔ Responses with schema-safe conversions |
-| 👥 **Multi-Account Support** | Multiple accounts per provider with intelligent selection |
-| 🔄 **Auto Token Refresh** | OAuth tokens refresh automatically with retry |
-| 🎨 **Custom Combos** | 13 balancing strategies + fallback chain control |
-| 🔗 **Context Relay** | Session continuity handoffs when account rotation happens mid-session |
+| 🎯 **Pengembalian 4 Tingkat Cerdas** | Rute otomatis: Berlangganan → Kunci API → Murah → Gratis |
+| 📊 **Pelacakan Kuota Waktu Nyata** | Jumlah token langsung + setel ulang hitungan mundur per penyedia |
+| 🔄 **Format Translation** | OpenAI ↔ Claude ↔ Gemini ↔ Respons dengan konversi skema-aman |
+| 👥 **Dukungan Multi-Akun** | Banyak akun per penyedia dengan pilihan cerdas |
+| 🔄 **Auto Token Refresh** | Token OAuth disegarkan secara otomatis dengan percobaan ulang |
+| 🎨 **Custom Combos** | 13 strategi penyeimbangan + kontrol rantai mundur |
+| 🔗 **Context Relay** | Penyerahan kesinambungan sesi ketika rotasi akun terjadi di tengah sesi |
| 🌐 **Wildcard Router** | `provider/*` dynamic routing |
-| 🧠 **Thinking Budget Controls** | Passthrough, auto, custom, and adaptive reasoning limits |
-| 🔀 **Model Aliases** | Built-in + custom model aliasing and migration safety |
-| ⚡ **Background Degradation** | Route low-priority background tasks to cheaper models |
-| 🧪 **Task-Aware Smart Routing** | Auto-select model by content type (coding/vision/analysis/summarization) |
+| 🧠 **Thinking Budget Controls** | Batas penalaran passthrough, otomatis, kustom, dan adaptif|
+| 🔀 **Model Aliases** |Alias model khusus + bawaan dan keamanan migrasi |
+| ⚡ **Background Degradation** | Arahkan tugas latar belakang berprioritas rendah ke model yang lebih murah |
+| 🧪 **Perutean Cerdas Sadar Tugas** | Pilih model secara otomatis berdasarkan jenis konten (pengkodean/visi/analisis/ringkasan) |
| 🔄 **A2A Agent Workflows** | Deterministic FSM orchestrator for stateful multi-step agent executions |
| 🔀 **Adaptive Routing** | Dynamic strategy override based on token volume and prompt complexity |
| 🎲 **Provider Diversity** | Shannon entropy scoring balancing auto-combo traffic distribution |
| 💬 **System Prompt Injection** | Global behavior controls applied consistently |
-| 📄 **Responses API Compatibility** | Full `/v1/responses` support for Codex and advanced agentic workflows |
+| 📄 **Kompatibilitas API Respons** | Dukungan penuh `/v1/responses` untuk Codex dan alur kerja agen tingkat lanjut |
-### 🎵 Multi-Modal APIs
+### 🎵 API Multi-Modal
-| Feature | What It Does |
+| Feature | Apa Fungsinya |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| 🖼️ **Image Generation** | `/v1/images/generations` with cloud and local backends |
-| 📐 **Embeddings** | `/v1/embeddings` for search and RAG pipelines |
+| 🖼️ **Image Generation** | `/v1/images/generations` dengan cloud dan backend lokal |
+| 📐 **Embeddings** | `/v1/embeddings` untuk saluran pencarian dan RAG |
| 🎤 **Audio Transcription** | `/v1/audio/transcriptions` — 7 providers (Deepgram Nova 3, AssemblyAI, Groq Whisper, HuggingFace, ElevenLabs, OpenAI, Azure), auto-language detection, MP4/MP3/WAV support |
-| 🔊 **Text-to-Speech** | `/v1/audio/speech` — 10 providers (ElevenLabs, OpenAI, Deepgram, Cartesia, PlayHT, HuggingFace, Nvidia NIM, Inworld, Coqui, Tortoise) with correct error messages |
+| 🔊 **Text-to-Speech** | `/v1/audio/speech` — 10 penyedia (ElevenLabs, OpenAI, Deepgram, Cartesia, PlayHT, HuggingFace, Nvidia NIM, Inworld, Coqui, Tortoise) dengan pesan kesalahan yang benar |
| 🎬 **Video Generation** | `/v1/videos/generations` (ComfyUI + SD WebUI workflows) |
| 🎵 **Music Generation** | `/v1/music/generations` (ComfyUI workflows) |
| 🛡️ **Moderations** | `/v1/moderations` safety checks |
-| 🔀 **Reranking** | `/v1/rerank` for relevance scoring |
+| 🔀 **Reranking** | `/v1/rerank` untuk penilaian relevansi |
| 🔍 **Web Search** 🆕 | `/v1/search` — 5 providers (Serper, Brave, Perplexity, Exa, Tavily), 6,500+ free/month, auto-failover, cache |
-### 🛡️ Resilience, Security & Governance
+### 🛡️ Ketahanan, Keamanan & Tata Kelola
-| Feature | What It Does |
+| Feature | Apa Fungsinya |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------- |
-| 🔌 **Provider Circuit Breakers** | Provider-wide trip/recover after fallback exhaustion with configurable thresholds |
-| 🔒 **Daily Quota Lock** 🆕 | Detects exhaustion signals and locks routing for the specific model until midnight |
-| 🎯 **Endpoint-Aware Models** | Custom models declare supported endpoints + API format |
+| 🔌 **Penyedia Pemutus Arus** | Perjalanan/pemulihan di seluruh penyedia setelah kelelahan fallback dengan ambang batas yang dapat dikonfigurasi |
+| 🔒 **Kunci Kuota Harian** 🆕 | Mendeteksi sinyal kelelahan dan mengunci perutean untuk model tertentu hingga tengah malam |
+| 🎯 **Model Sadar Titik Akhir** | Model khusus mendeklarasikan titik akhir + format API yang didukung |
| 🛡️ **Anti-Thundering Herd** | Mutex + semaphore protections on retry/rate events |
-| 🧠 **Semantic + Signature Cache** | Cost/latency reduction with two cache layers |
+| 🧠 **Semantic + Signature Cache** | Pengurangan biaya/latensi dengan dua lapisan cache |
| ⚡ **Request Idempotency** | Duplicate protection window |
-| 🔒 **TLS Fingerprint Spoofing** | Browser-like TLS fingerprint — **reduces bot detection and account flagging** |
+| 🔒 **TLS Fingerprint Spoofing** | Sidik jari TLS seperti browser — **mengurangi deteksi bot dan penandaan akun**|
| 🔏 **CLI Fingerprint Matching** | Matches native CLI request signatures — **reduces ban risk while preserving proxy IP** |
-| 🌐 **IP Filtering** | Allowlist/blocklist control for exposed deployments |
-| 🚦 **Request Queue & Pacing** | Configurable per-connection request buckets for RPM, spacing, concurrency, and max wait |
+| 🌐 **IP Filtering** |Kontrol daftar yang diizinkan/daftar blokir untuk penerapan yang terbuka |
+| 🚦 **Minta Antrian & Kecepatan** | Bucket permintaan per koneksi yang dapat dikonfigurasi untuk RPM, spasi, konkurensi, dan waktu tunggu maksimal |
| 📉 **Graceful Degradation** | Multi-layer capability fallbacks protecting core gateway operations |
-| 📜 **Config Audit Trail** | Diff-based change tracking preventing operational drift with simple rollbacks |
-| ⏳ **Provider Health Sync** | Proactive token expiration monitoring triggering alerts before authorization failures |
+| 📜 **Config Audit Trail** | Pelacakan perubahan berbasis diff mencegah penyimpangan operasional dengan rollback sederhana |
+| ⏳ **Sinkronisasi Kesehatan Penyedia** | Proactive token expiration monitoring triggering alerts before authorization failures |
| ❄️ **Connection Cooldown** | Retryable 408/429/5xx failures cool down a single connection with optional upstream hints |
-| 🚪 **Auto-Disable Banned Accounts** | Permanently blocked token accounts can be disabled automatically |
-| 🔑 **API Key Management + Scoping** | Secure key issuance/rotation and model/provider controls |
-| 👁️ **Scoped API Key Reveal** 🆕 | Opt-in recovery of API keys via `ALLOW_API_KEY_REVEAL` |
-| 🛡️ **Protected `/models`** | Optional auth gating and provider hiding for model catalog |
-| 🛡️ **Safe Outbound Fetch** 🆕 | Guarded fetch for provider calls — blocks private/local URLs, retries, SSRF protection |
-| ⏳ **Wait For Cooldown** 🆕 | Auto-retry chat after connection cooldowns; configurable `enabled`, `maxRetries`, and `maxRetryWaitSec` |
-| 🔍 **Runtime Env Validation** 🆕 | Zod-based env schema validation at startup with actionable error messages |
-| 📋 **Compliance Audit v2** 🆕 | Pagination, request context, auth events, provider CRUD, and SSRF-blocked logging |
+| 🚪 **Nonaktifkan Otomatis Akun yang Diblokir** | Akun token yang diblokir secara permanen dapat dinonaktifkan secara otomatis |
+| 🔑 **Manajemen Kunci API + Pelingkupan** | Mengamankan penerbitan/rotasi kunci dan kontrol model/penyedia |
+| 👁️ **Pengungkapan Kunci API Cakupan** 🆕 | Ikut serta dalam pemulihan kunci API melalui `ALLOW_API_KEY_REVEAL` |
+| 🛡️ **Protected `/models`** | Gerbang autentikasi opsional dan penyembunyian penyedia untuk katalog model |
+| 🛡️ **Safe Outbound Fetch** 🆕 | Pengambilan yang dijaga untuk panggilan penyedia — memblokir URL pribadi/lokal, percobaan ulang, perlindungan SSRF |
+| ⏳ **Tunggu Cooldown** 🆕 | Coba ulang obrolan secara otomatis setelah cooldown koneksi; dapat dikonfigurasi `enabled`, `maxRetries`, dan `maxRetryWaitSec` |
+| 🔍 **Validasi Env Runtime** 🆕 | Zod-based env schema validation at startup with actionable error messages |
+| 📋 **Compliance Audit v2** 🆕 | Penomoran halaman, konteks permintaan, peristiwa autentikasi, CRUD penyedia, dan logging yang diblokir SSRF |
-### 📊 Observability & Analytics
+### 📊 Observabilitas & Analitik
-| Feature | What It Does |
+| Feature | Apa Fungsinya |
| -------------------------------- | ----------------------------------------------------- |
-| 📝 **Request + Proxy Logging** | Full request/response and proxy logging |
-| 📉 **Streamed Detailed Logs** | Reconstructs SSE payload streams cleanly into the UI |
-| 🏷️ **Real-Time Model Badges** 🆕 | Live model status and daily quota countdown timers |
-| 📋 **Unified Logs Dashboard** | Request, proxy, audit, and console views in one page |
-| 🔍 **Request Telemetry** | p50/p95/p99 latency and request tracing |
+| 📝 **Permintaan + Pencatatan Proksi** | Permintaan/respons penuh dan pencatatan proksi|
+| 📉 **Streamed Detailed Logs** |Merekonstruksi aliran muatan SSE dengan rapi ke dalam UI |
+| 🏷️ **Lencana Model Real-Time** 🆕 | Status model langsung dan penghitung waktu mundur kuota harian |
+| 📋 **Dasbor Log Terpadu** | Tampilan permintaan, proksi, audit, dan konsol dalam satu halaman |
+| 🔍 **Request Telemetry** | latensi p50/p95/p99 dan penelusuran permintaan |
| 🏥 **Health Dashboard** | Uptime, breaker states, lockouts, cache stats |
-| 💰 **Cost Tracking** | Budget controls and per-model pricing visibility |
-| 📈 **Analytics Visualizations** | Model/provider usage insights and trend views |
-| 🧪 **Evaluation Framework** | Golden set testing with configurable match strategies |
-| 📡 **Live Diagnostics** 🆕 | Semantic cache bypass for accurate combo live testing |
+| 💰 **Cost Tracking** | Kontrol anggaran dan visibilitas harga per model |
+| 📈 **Analytics Visualizations** | Wawasan penggunaan model/penyedia dan tampilan tren |
+| 🧪 **Evaluation Framework** | Pengujian set emas dengan strategi pencocokan yang dapat dikonfigurasi |
+| 📡 **Live Diagnostics** 🆕 | Bypass cache semantik untuk pengujian langsung kombo yang akurat |
| 🔐 **TPS Log Metric** 🆕 | Tokens Per Second badge in log details modal |
### ☁️ Deployment & Platform
-| Feature | What It Does |
+| Feature | Apa Fungsinya |
| ------------------------------ | --------------------------------------------------------------------- |
| 🌐 **Deploy Anywhere** | Localhost, VPS, Docker, Cloud environments |
-| 🚇 **Cloudflare Tunnel** 🆕 | One-click Quick Tunnel integration from the dashboard |
-| 🔑 **API Key Model Filtering** | Native /v1/models response filtered via assigned Bearer context roles |
-| ⚡ **Smart Cache Bypass** | Configurable TTL heuristics and forced refetch controls |
-| 🔄 **Backup/Restore** | Export/import and disaster recovery flows |
-| 🧙 **Onboarding Wizard** | First-run guided setup |
-| 🔧 **CLI Tools Dashboard** | One-click setup for popular coding tools |
-| 🎮 **Model Playground** | Test any provider/model/endpoint from the dashboard |
-| 🔏 **CLI Fingerprint Toggle** | Per-provider fingerprint matching in Settings > Security |
-| 🌐 **i18n (30 languages)** | Full dashboard + docs language support with RTL coverage |
-| 🧹 **Clear All Models** | One-click model list clearing in provider details |
-| 👁️ **Sidebar Controls** 🆕 | Hide components and integrations from Appearance Settings |
-| 📋 **Issue Templates** | Standardized GitHub templates for bugs and features |
-| 📂 **Custom Data Directory** | `DATA_DIR` override for storage location |
+| 🚇 **Cloudflare Tunnel** 🆕 | Integrasi Quick Tunnel sekali klik dari dasbor |
+| 🔑 **Pemfilteran Model Kunci API** | Respons asli /v1/models difilter melalui peran konteks Pembawa yang ditetapkan |
+| ⚡ **Smart Cache Bypass** | Heuristik TTL yang dapat dikonfigurasi dan kontrol pengambilan ulang paksa |
+| 🔄 **Backup/Restore** | Arus ekspor/impor dan pemulihan bencana |
+| 🧙 **Onboarding Wizard** | Penyiapan terpandu yang dijalankan pertama kali |
+| 🔧 **Dasbor Alat CLI** | Pengaturan sekali klik untuk alat pengkodean populer |
+| 🎮 **Model Playground** | Uji penyedia/model/titik akhir apa pun dari dasbor|
+| 🔏 **CLI Fingerprint Toggle** |Pencocokan sidik jari per penyedia di Pengaturan > Keamanan |
+| 🌐 **i18n (30 languages)** | Dasbor lengkap + dukungan bahasa dokumen dengan cakupan RTL |
+| 🧹 **Hapus Semua Model** | Pembersihan daftar model sekali klik di detail penyedia |
+| 👁️ **Sidebar Controls** 🆕 | Sembunyikan komponen dan integrasi dari Pengaturan Penampilan |
+| 📋 **Issue Templates** | Templat GitHub standar untuk bug dan fitur |
+| 📂 **Custom Data Directory** | `DATA_DIR` penggantian untuk lokasi penyimpanan |
| 🌐 **V1 WebSocket Bridge** 🆕 | OpenAI-compatible WebSocket traffic proxied via `/v1/ws` |
-| 🔑 **Sync Tokens & Bundle** 🆕 | Config sync tokens + versioned bundle endpoint with ETag support |
+| 🔑 **Sync Tokens & Bundle** 🆕 | Konfigurasikan token sinkronisasi + titik akhir bundel berversi dengan dukungan ETag |
-### Feature Deep Dive
+### Fitur Penyelaman Mendalam
-#### Smart fallback with practical cost control
+#### Penggantian cerdas dengan pengendalian biaya praktis
```txt
Combo: "my-coding-stack"
@@ -1533,42 +1533,42 @@ Combo: "my-coding-stack"
4. if/kimi-k2-thinking
```
-When quota, rate, or health fails, OmniRoute automatically moves to the next candidate without manual switching.
+Ketika kuota, tarif, atau kesehatan gagal, OmniRoute secara otomatis berpindah ke kandidat berikutnya tanpa peralihan manual.
-#### Protocol management that is visible and operable
+#### Manajemen protokol yang terlihat dan dapat dioperasikan
-- MCP + A2A are discoverable in UI and docs (not hidden)
-- Protocol status APIs expose live operational data (`/api/mcp/*`, `/api/a2a/*`)
-- Dashboards include actions for day-2 ops (combo toggles, breaker resets, task cancellation)
+- MCP + A2A dapat ditemukan di UI dan dokumen (tidak disembunyikan)
+- API status protokol memaparkan data operasional langsung (`/api/mcp/*`, `/api/a2a/*`)
+- Dasbor mencakup tindakan untuk operasi hari ke-2 (pengalihan kombo, pengaturan ulang pemutus, pembatalan tugas)
-#### Translator + validation workflow
+#### Workflow translator + validasi
-The Translator area includes:
+Area Penerjemah meliputi:
- **Playground**: request transformation checks
- **Chat Tester**: full request/response round-trip
- **Test Bench**: multiple cases in one run
- **Live Monitor**: real-time traffic view
-Plus protocol validation with real clients via `npm run test:protocols:e2e`.
+Ditambah validasi protokol dengan klien nyata melalui `npm run test:protocols:e2e`.
-> 📖 **[MCP Server README](open-sse/mcp-server/README.md)** — Tool reference, IDE configs, and client examples
+> 📖 **[MCP Server README](open-sse/mcp-server/README.md)** — Referensi alat, konfigurasi IDE, dan contoh klien
>
-> 📖 **[A2A Server README](src/lib/a2a/README.md)** — Skills, JSON-RPC methods, streaming, and task lifecycle
+> 📖 **[A2A Server README](src/lib/a2a/README.md)** — Keterampilan, metode JSON-RPC, streaming, dan siklus hidup tugas
-## 🧪 Evaluations (Evals)
+## 🧪 Evaluasi (Evals)
-OmniRoute includes a built-in evaluation framework to test LLM response quality against a golden set. Access it via **Analytics → Evals** in the dashboard.
+OmniRoute menyertakan kerangka evaluasi bawaan untuk menguji kualitas respons LLM terhadap rangkaian emas. Akses melalui **Analytics → Evals** di dasbor.
-### Built-in Golden Set
+### Golden Set Bawaan
-The pre-loaded "OmniRoute Golden Set" contains test cases for:
+"OmniRoute Golden Set" yang dimuat sebelumnya berisi kasus uji untuk:
-- Greetings, math, geography, code generation
-- JSON format compliance, translation, markdown generation
-- Safety refusal (harmful content), counting, boolean logic
+- Salam, matematika, geografi, pembuatan kode
+- Kepatuhan format JSON, terjemahan, pembuatan penurunan harga
+- Penolakan keamanan (konten berbahaya), penghitungan, logika boolean
-### Evaluation Strategies
+### Strategi Evaluasi
| Strategy | Description | Example |
| ---------- | ------------------------------------------------ | -------------------------------- |
@@ -1579,12 +1579,12 @@ The pre-loaded "OmniRoute Golden Set" contains test cases for:
---
-## 📖 Setup Guide
+## 📖 Panduan Setup
-### Protocol Setup (MCP + A2A)
+### Pengaturan Protokol (MCP + A2A)
-🧩 MCP Setup (Model Context Protocol)
+🧩 Penyiapan MCP (Protokol Konteks Model)
Start MCP transport in stdio mode:
@@ -1594,12 +1594,12 @@ omniroute --mcp
Recommended validation flow:
-1. Connect your MCP client over stdio.
-2. Run `omniroute_get_health`.
-3. Run `omniroute_list_combos`.
-4. Open `/dashboard/mcp` to confirm heartbeat, activity, and audit.
+1. Hubungkan klien MCP Anda melalui stdio.
+2. Jalankan `omniroute_get_health`.
+3. Jalankan `omniroute_list_combos`.
+4. Buka `/dashboard/mcp` untuk mengonfirmasi detak jantung, aktivitas, dan audit.
-Useful APIs for automation:
+API yang berguna untuk otomatisasi:
- `GET /api/mcp/status`
- `GET /api/mcp/tools`
@@ -1609,9 +1609,9 @@ Useful APIs for automation:
-🤝 A2A Setup (Agent2Agent)
+🤝 Pengaturan A2A (Agen2Agen)
-Discover the agent:
+Temukan agennya:
```bash
curl http://localhost:20128/.well-known/agent.json
@@ -1634,14 +1634,14 @@ Manage lifecycle:
Operational UI:
-- `/dashboard/a2a` for task/state/stream observability and smoke actions
+- `/dashboard/a2a` untuk observasi tugas/status/aliran dan tindakan asap
-🧪 End-to-end protocol validation
+🧪 Validasi protokol end-to-end
-Validate both protocols with real clients:
+Validasi kedua protokol dengan klien nyata:
```bash
npm run test:protocols:e2e
@@ -1649,14 +1649,14 @@ npm run test:protocols:e2e
This verifies:
-- MCP SDK client connect/list/call
-- A2A discovery/send/stream/get/cancel
-- Cross-check data in MCP audit and A2A task management APIs
+- Koneksi/daftar/panggilan klien MCP SDK
+- Penemuan A2A/kirim/aliran/dapatkan/batalkan
+- Periksa silang data dalam audit MCP dan API manajemen tugas A2A
-💳 Subscription Providers
+💳 Penyedia Berlangganan
### Claude Code (Pro/Max)
@@ -1671,7 +1671,7 @@ Models:
cc/claude-haiku-4-5-20251001
```
-**Pro Tip:** Use Opus for complex tasks, Sonnet for speed. OmniRoute tracks quota per model!
+**Kiat Pro:** Gunakan Opus untuk tugas kompleks, Soneta untuk kecepatan. OmniRoute melacak kuota per model!
### OpenAI Codex (Plus/Pro)
@@ -1685,24 +1685,24 @@ Models:
cx/gpt-5.1-codex-max
```
-#### Codex Account Limit Management (5h + Weekly)
+#### Manajemen Batas Akun Codex (5 jam + Mingguan)
-Each Codex account now has policy toggles in `Dashboard -> Providers`:
+Setiap akun Codex kini memiliki kebijakan yang dapat diubah di `Dashboard -> Providers`:
-- `5h` (ON/OFF): enforce the 5-hour window threshold policy.
-- `Weekly` (ON/OFF): enforce the weekly window threshold policy.
-- Threshold behavior: when an enabled window reaches >=90% usage, that account is skipped.
-- Rotation behavior: OmniRoute routes to the next eligible Codex account automatically.
-- Reset behavior: when the provider `resetAt` time passes, the account becomes eligible again automatically.
+- `5h` (ON/OFF): menerapkan kebijakan ambang jendela 5 jam.
+- `Weekly` (ON/OFF): menerapkan kebijakan ambang jendela mingguan.
+- Perilaku ambang batas: ketika jendela yang diaktifkan mencapai >=90% penggunaan, akun tersebut dilewati.
+- Perilaku rotasi: OmniRoute merutekan ke akun Codex berikutnya yang memenuhi syarat secara otomatis.
+- Perilaku reset: ketika waktu `resetAt` penyedia telah berlalu, akun akan memenuhi syarat lagi secara otomatis.
Scenarios:
-- `5h ON` + `Weekly ON`: account is skipped when either window reaches threshold.
-- `5h OFF` + `Weekly ON`: only weekly usage can block the account.
-- `5h ON` + `Weekly OFF`: only 5-hour usage can block the account.
-- `resetAt` passed: account re-enters rotation automatically (no manual re-enable).
+- `5h ON` + `Weekly ON`: akun dilewati ketika salah satu jendela mencapai ambang batas.
+- `5h OFF` + `Weekly ON`: hanya penggunaan mingguan yang dapat memblokir akun.
+- `5h ON` + `Weekly OFF` : hanya penggunaan 5 jam yang dapat memblokir akun.
+- `resetAt` lolos: akun masuk kembali ke rotasi secara otomatis (tidak ada pengaktifan ulang secara manual).
-### Gemini CLI (FREE 180K/month!)
+### Gemini CLI (GRATIS 180K/bulan!)
```bash
Dashboard → Providers → Connect Gemini CLI
@@ -1714,7 +1714,7 @@ Models:
gc/gemini-2.5-pro
```
-**Best Value:** Huge free tier! Use this before paid tiers.
+**Nilai Terbaik:** Tingkat gratis yang sangat besar! Gunakan ini sebelum tingkatan berbayar.
### GitHub Copilot
@@ -1732,90 +1732,90 @@ Models:
-🔑 API Key Providers
+🔑 Penyedia Kunci API
-### NVIDIA NIM (FREE developer access — 70+ models)
+### NVIDIA NIM (akses pengembang GRATIS — 70+ model)
-1. Sign up: [build.nvidia.com](https://build.nvidia.com)
-2. Get free API key (1000 inference credits included)
-3. Dashboard → Add Provider → NVIDIA NIM:
- - API Key: `nvapi-your-key`
+1. Daftar: [build.nvidia.com](https://build.nvidia.com)
+2. Dapatkan kunci API gratis (termasuk 1000 kredit inferensi)
+3. Dasbor → Tambah Penyedia → NVIDIA NIM:
+ - Kunci API: `nvapi-your-key`
-**Models:** `nvidia/llama-3.3-70b-instruct`, `nvidia/mistral-7b-instruct`, and 50+ more
+**Model:** `nvidia/llama-3.3-70b-instruct`, `nvidia/mistral-7b-instruct`, dan 50+ lainnya
-**Pro Tip:** OpenAI-compatible API — works seamlessly with OmniRoute's format translation!
+**Kiat Pro:** API yang kompatibel dengan OpenAI — bekerja secara lancar dengan terjemahan format OmniRoute!
### DeepSeek
-1. Sign up: [platform.deepseek.com](https://platform.deepseek.com)
-2. Get API key
-3. Dashboard → Add Provider → DeepSeek
+1. Daftar: [platform.deepseek.com](https://platform.deepseek.com)
+2. Dapatkan kunci API
+3. Dasbor → Tambah Penyedia → DeepSeek
**Models:** `deepseek/deepseek-chat`, `deepseek/deepseek-coder`
-### Groq (Free Tier Available!)
+### Groq (Tersedia Tingkat Gratis!)
-1. Sign up: [console.groq.com](https://console.groq.com)
-2. Get API key (free tier included)
-3. Dashboard → Add Provider → Groq
+1. Daftar: [console.groq.com](https://console.groq.com)
+2. Dapatkan kunci API (termasuk tingkat gratis)
+3. Dasbor → Tambah Penyedia → Groq
**Models:** `groq/llama-3.3-70b`, `groq/mixtral-8x7b`
**Pro Tip:** Ultra-fast inference — best for real-time coding!
-### OpenRouter (100+ Models)
+### OpenRouter (100+ Model)
-1. Sign up: [openrouter.ai](https://openrouter.ai)
-2. Get API key
-3. Dashboard → Add Provider → OpenRouter
+1. Daftar: [openrouter.ai](https://openrouter.ai)
+2. Dapatkan kunci API
+3. Dasbor → Tambah Penyedia → OpenRouter
-**Models:** Access 100+ models from all major providers through a single API key.
+**Model:** Akses 100+ model dari semua penyedia utama melalui satu kunci API.
-**Dashboard behavior:** OpenRouter models are managed from **Available Models**. Manual add, import, and auto-sync all update the same list.
+**Perilaku dasbor:** Model OpenRouter dikelola dari **Model yang Tersedia**. Penambahan manual, impor, dan sinkronisasi otomatis semuanya memperbarui daftar yang sama.
-💰 Cheap Providers (Backup)
+💰 Penyedia Murah (Cadangan)
-### GLM-4.7 (Daily reset, $0.6/1M)
+### GLM-4.7 (Reset harian, $0.6/1M)
-1. Sign up: [Zhipu AI](https://open.bigmodel.cn/)
-2. Get API key from Coding Plan
-3. Dashboard → Add API Key:
- - Provider: `glm`
- - API Key: `your-key`
+1. Daftar: [Zhipu AI](https://open.bigmodel.cn/)
+2. Dapatkan kunci API dari Coding Plan
+3. Dasbor → Tambahkan Kunci API:
+ - Penyedia: `glm`
+ - Kunci API: `your-key`
**Use:** `glm/glm-4.7`
-**Pro Tip:** Coding Plan offers 3× quota at 1/7 cost! Reset daily 10:00 AM.
+**Tips Pro:** Paket Coding menawarkan 3× kuota dengan biaya 1/7! Reset setiap hari pukul 10.00.
-### MiniMax M2.1 (5h reset, $0.20/1M)
+### MiniMax M2.1 (Reset 5 jam, $0.20/1M)
-1. Sign up: [MiniMax](https://www.minimax.io/)
-2. Get API key
-3. Dashboard → Add API Key
+1. Daftar: [MiniMax](https://www.minimax.io/)
+2. Dapatkan kunci API
+3. Dasbor → Tambahkan Kunci API
**Use:** `minimax/MiniMax-M2.1`
-**Pro Tip:** Cheapest option for long context (1M tokens)!
+**Kiat Pro:** Opsi termurah untuk konteks panjang (1 juta token)!
-### Kimi K2 ($9/month flat)
+### Kimi K2 ($9/bulan flat)
-1. Subscribe: [Moonshot AI](https://platform.moonshot.ai/)
-2. Get API key
-3. Dashboard → Add API Key
+1. Berlangganan: [Moonshot AI](https://platform.moonshot.ai/)
+2. Dapatkan kunci API
+3. Dasbor → Tambahkan Kunci API
**Use:** `kimi/kimi-latest`
-**Pro Tip:** Fixed $9/month for 10M tokens = $0.90/1M effective cost!
+**Kiat Pro:** Memperbaiki $9/bulan untuk 10 juta token = biaya efektif $0,90/1 juta!
-🆓 FREE Providers (Emergency Backup)
+🆓 Penyedia GRATIS (Cadangan Darurat)
-### Qoder (5 FREE models via OAuth)
+### Qoder (5 model GRATIS melalui OAuth)
```bash
Dashboard → Connect Qoder
@@ -1830,7 +1830,7 @@ Models:
if/deepseek-r1
```
-### Qwen (4 FREE models via Device Code)
+### Qwen (4 model GRATIS melalui Kode Perangkat)
```bash
Dashboard → Connect Qwen
@@ -1842,7 +1842,7 @@ Models:
qw/qwen3-coder-flash
```
-### Kiro (Claude FREE)
+### Kiro (Claude GRATIS)
```bash
Dashboard → Connect Kiro
@@ -1857,9 +1857,9 @@ Models:
-🎨 Create Combos
+🎨 Membuat Combo
-### Example 1: Maximize Subscription → Cheap Backup
+### Contoh 1: Maksimalkan Langganan → Cadangan Murah
```
Dashboard → Combos → Create New
@@ -1873,7 +1873,7 @@ Models:
Use in CLI: premium-coding
```
-### Example 2: Free-Only (Zero Cost)
+### Contoh 2: Gratis Saja (Tanpa Biaya)
```
Name: free-combo
@@ -1888,7 +1888,7 @@ Cost: $0 forever!
-🔧 CLI Integration
+🔧 Integrasi CLI
### Cursor IDE
@@ -1901,7 +1901,7 @@ Settings → Models → Advanced:
### Claude Code
-Use the **CLI Tools** page in the dashboard for one-click configuration, or edit `~/.claude/settings.json` manually.
+Gunakan halaman **Alat CLI** di dasbor untuk konfigurasi sekali klik, atau edit `~/.claude/settings.json` secara manual.
### Codex CLI
@@ -1914,7 +1914,7 @@ codex "your prompt"
### OpenClaw
-**Option 1 — Dashboard (recommended):**
+**Opsi 1 — Dasbor (disarankan):**
```
Dashboard → CLI Tools → OpenClaw → Select Model → Apply
@@ -1936,7 +1936,7 @@ Dashboard → CLI Tools → OpenClaw → Select Model → Apply
}
```
-> **Note:** OpenClaw only works with local OmniRoute. Use `127.0.0.1` instead of `localhost` to avoid IPv6 resolution issues.
+> **Catatan:** OpenClaw hanya berfungsi dengan OmniRoute lokal. Gunakan `127.0.0.1` alih-alih `localhost` untuk menghindari masalah resolusi IPv6.
### Cline / Continue / RooCode
@@ -1950,7 +1950,7 @@ Settings → API Configuration:
### OpenCode
-**Step 1:** Add OmniRoute as a custom provider:
+**Langkah 1:** Tambahkan OmniRoute sebagai penyedia khusus:
```bash
opencode
@@ -1958,7 +1958,7 @@ opencode
# Select "Other" → Enter ID: "omniroute" → Enter your OmniRoute API key
```
-**Step 2:** Create/edit `opencode.json` in your project root:
+**Langkah 2:** Buat/edit `opencode.json` di root proyek Anda:
```json
{
@@ -1980,14 +1980,14 @@ opencode
}
```
-**Step 3:** Select the model in OpenCode:
+**Langkah 3:** Pilih model di OpenCode:
```bash
/models
# Select any OmniRoute model from the list
```
-> **Tip:** Add any model available in your OmniRoute `/v1/models` endpoint to the `models` section. Use the format `provider/model-id` from your OmniRoute dashboard.
+> **Tips:** Tambahkan model apa pun yang tersedia di titik akhir OmniRoute `/v1/models` Anda ke bagian `models`. Gunakan format `provider/model-id` dari dasbor OmniRoute Anda.
@@ -1996,112 +1996,112 @@ opencode
## Pemecahan Masalah
-Click to expand troubleshooting guide
+Klik untuk memperluas panduan pemecahan masalah
-**"Language model did not provide messages"**
+**"Model bahasa tidak memberikan pesan"**
-- Provider quota exhausted → Check dashboard quota tracker
-- Solution: Use combo fallback or switch to cheaper tier
+- Kuota penyedia habis → Periksa dashboard pelacak kuota
+- Solusi: Gunakan combo fallback atau beralih ke tier yang lebih murah
**Rate limiting**
-- Subscription quota out → Fallback to GLM/MiniMax
-- Add combo: `cc/claude-opus-4-7 → glm/glm-4.7 → if/kimi-k2-thinking`
+- Kuota berlangganan habis → Penggantian ke GLM/MiniMax
+- Tambahkan kombo: `cc/claude-opus-4-7 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth token expired**
-- Auto-refreshed by OmniRoute
-- If issues persist: Dashboard → Provider → Reconnect
+- Disegarkan secara otomatis oleh OmniRoute
+- Jika masalah terus berlanjut: Dasbor → Penyedia → Sambungkan kembali
**High costs**
-- Check usage stats in Dashboard → Costs
-- Switch primary model to GLM/MiniMax
-- Use free tier (Gemini CLI, Qoder) for non-critical tasks
+- Periksa statistik penggunaan di Dashboard → Biaya
+- Ganti model utama ke GLM/MiniMax
+- Gunakan tingkat gratis (Gemini CLI, Qoder) untuk tugas-tugas yang tidak penting
-**Dashboard/API ports are wrong**
+**Port dasbor/API salah**
-- `PORT` is the canonical base port (and API port by default)
-- `API_PORT` overrides only OpenAI-compatible API listener
-- `DASHBOARD_PORT` overrides only dashboard/Next.js listener
-- Set `NEXT_PUBLIC_BASE_URL` to your dashboard/public URL (for OAuth callbacks)
+- `PORT` adalah port dasar kanonik (dan port API secara default)
+- `API_PORT` hanya menimpa pendengar API yang kompatibel dengan OpenAI
+- `DASHBOARD_PORT` hanya menimpa dashboard/pendengar Next.js
+- Setel `NEXT_PUBLIC_BASE_URL` ke dasbor/URL publik Anda (untuk panggilan balik OAuth)
**Cloud sync errors**
-- Verify `BASE_URL` points to your running instance
-- Verify `CLOUD_URL` points to your expected cloud endpoint
-- Keep `NEXT_PUBLIC_*` values aligned with server-side values
+- Verifikasi `BASE_URL` poin ke instance Anda yang sedang berjalan
+- Verifikasi `CLOUD_URL` poin ke titik akhir cloud yang Anda harapkan
+- Jaga agar nilai `NEXT_PUBLIC_*` selaras dengan nilai sisi server
**First login not working**
-- Check `INITIAL_PASSWORD` in `.env`
-- If unset, fallback password is `123456`
+- Periksa `INITIAL_PASSWORD` di `.env`
+- Jika tidak disetel, kata sandi cadangan adalah `123456`
-**No request logs**
+**Tidak ada log permintaan**
-- `call_logs` in SQLite stores summary metadata for the Request Logs table and analytics views
-- Detailed request/response payloads are written to `DATA_DIR/call_logs/` as one JSON artifact per request
-- Enable pipeline capture from Dashboard → Logs → Request Logs if you need detailed per-stage payloads
-- `Export Logs` reads the artifact files on demand, while `Export All` includes the `call_logs/` directory alongside `storage.sqlite`
-- Set `APP_LOG_TO_FILE=true` if you also want application console logs in `logs/application/app.log`
-- Adjust `APP_LOG_MAX_FILE_SIZE`, `APP_LOG_RETENTION_DAYS`, `APP_LOG_MAX_FILES`, and `CALL_LOG_MAX_ENTRIES` as needed
+- `call_logs` di SQLite menyimpan metadata ringkasan untuk tabel Log Permintaan dan tampilan analitik
+- Muatan permintaan/respons terperinci ditulis ke `DATA_DIR/call_logs/` sebagai satu artefak JSON per permintaan
+- Aktifkan pengambilan saluran pipa dari Dasbor → Log → Log Permintaan jika Anda memerlukan muatan per tahap yang terperinci
+- `Export Logs` membaca file artefak sesuai permintaan, sementara `Export All` menyertakan direktori `call_logs/` bersama `storage.sqlite`
+- Setel `APP_LOG_TO_FILE=true` jika Anda juga ingin log konsol aplikasi di `logs/application/app.log`
+- Sesuaikan `APP_LOG_MAX_FILE_SIZE`, `APP_LOG_RETENTION_DAYS`, `APP_LOG_MAX_FILES`, dan `CALL_LOG_MAX_ENTRIES` sesuai kebutuhan
-**Connection test shows "Invalid" for OpenAI-compatible providers**
+**Tes koneksi menunjukkan "Tidak Valid" untuk penyedia yang kompatibel dengan OpenAI**
-- Many providers don't expose a `/models` endpoint
-- OmniRoute v1.0.6+ includes fallback validation via chat completions
-- Ensure base URL includes `/v1` suffix
+- Banyak penyedia tidak mengekspos titik akhir `/models`
+- OmniRoute v1.0.6+ menyertakan validasi fallback melalui penyelesaian obrolan
+- Pastikan URL dasar menyertakan akhiran `/v1`
-### 🔐 OAuth on a Remote Server
+### 🔐 OAuth di Server Jarak Jauh
-> **⚠️ Important for users running OmniRoute on a VPS, Docker, or any remote server**
+> **⚠️ Penting bagi pengguna yang menjalankan OmniRoute di VPS, Docker, atau server jarak jauh mana pun**
-#### Why does Antigravity / Gemini CLI OAuth fail on remote servers?
+#### Mengapa OAuth Antigravity / Gemini CLI gagal di server jarak jauh?
-The **Antigravity** and **Gemini CLI** providers use **Google OAuth 2.0**. Google requires the `redirect_uri` in the OAuth flow to exactly match one of the pre-registered URIs in the app's Google Cloud Console.
+Penyedia **Antigravitasi** dan **Gemini CLI** menggunakan **Google OAuth 2.0**. Google mewajibkan `redirect_uri` dalam alur OAuth agar sama persis dengan salah satu URI yang telah didaftarkan sebelumnya di Google Cloud Console aplikasi.
-The OAuth credentials bundled in OmniRoute are registered **for `localhost` only**. When you access OmniRoute on a remote server (e.g. `https://omniroute.myserver.com`), Google rejects the authentication with:
+Kredensial OAuth yang disertakan dalam OmniRoute didaftarkan **hanya untuk `localhost`**. Saat Anda mengakses OmniRoute di server jarak jauh (misalnya `https://omniroute.myserver.com`), Google menolak autentikasi dengan:
```
Error 400: redirect_uri_mismatch
```
-#### Solution: Configure your own OAuth credentials
+#### Solusi: Konfigurasikan kredensial OAuth Anda sendiri
-You need to create an **OAuth 2.0 Client ID** in Google Cloud Console with your server's URI.
+Anda perlu membuat **ID Klien OAuth 2.0** di Google Cloud Console dengan URI server Anda.
-#### Step-by-step
+#### Langkah demi langkah
**1. Open Google Cloud Console**
Go to: [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)
-**2. Create a new OAuth 2.0 Client ID**
+**2. Buat ID Klien OAuth 2.0 baru**
-- Click **"+ Create Credentials"** → **"OAuth client ID"**
-- Application type: **"Web application"**
-- Name: anything you like (e.g. `OmniRoute Remote`)
+- Klik **"+ Buat Kredensial"** → **"ID klien OAuth"**
+- Jenis aplikasi: **"Aplikasi web"**
+- Nama: apa pun yang Anda suka (mis. `OmniRoute Remote`)
**3. Add Authorized Redirect URIs**
-In the **"Authorized redirect URIs"** field, add:
+Di kolom **"URI pengalihan resmi"**, tambahkan:
```
https://your-server.com/callback
```
-> Replace `your-server.com` with your server's domain or IP (include the port if needed, e.g. `http://45.33.32.156:20128/callback`).
+> Ganti `your-server.com` dengan domain atau IP server Anda (sertakan port jika diperlukan, misalnya `http://45.33.32.156:20128/callback`).
-**4. Save and copy the credentials**
+**4. Simpan dan salin kredensial**
-After creating, Google will show the **Client ID** and **Client Secret**.
+Setelah pembuatan, Google akan menampilkan **ID Klien** dan **Rahasia Klien**.
-**5. Set environment variables**
+**5. Tetapkan variabel lingkungan**
-In your `.env` (or Docker environment variables):
+Di `.env` Anda (atau variabel lingkungan Docker):
```bash
# For Antigravity:
@@ -2126,23 +2126,23 @@ docker restart omniroute
**7. Try connecting again**
-Dashboard → Providers → Antigravity (or Gemini CLI) → OAuth
+Dasbor → Penyedia → Antigravitasi (atau Gemini CLI) → OAuth
Google will now redirect correctly to `https://your-server.com/callback`.
---
-#### Temporary workaround (without custom credentials)
+#### Solusi sementara (tanpa kredensial kustom)
-If you don't want to set up your own credentials right now, you can still use the **manual URL flow**:
+Jika Anda tidak ingin menyiapkan kredensial Anda sendiri saat ini, Anda masih dapat menggunakan **alur URL manual**:
-1. OmniRoute opens the Google authorization URL
-2. After authorizing, Google tries to redirect to `localhost` (which fails on the remote server)
-3. **Copy the full URL** from your browser's address bar (even if the page doesn't load)
-4. Paste that URL into the field shown in the OmniRoute connection modal
-5. Click **"Connect"**
+1. OmniRoute membuka URL otorisasi Google
+2. Setelah otorisasi, Google mencoba mengalihkan ke `localhost` (yang gagal di server jauh)
+3. **Salin URL lengkap** dari bilah alamat browser Anda (meskipun halaman tidak dimuat)
+4. Tempelkan URL tersebut ke bidang yang ditampilkan di modal koneksi OmniRoute
+5. Klik **"Hubungkan"**
-> This works because the authorization code in the URL is valid regardless of whether the redirect page loaded.
+> Ini berfungsi karena kode otorisasi di URL valid terlepas dari apakah halaman pengalihan dimuat.
---
@@ -2169,11 +2169,11 @@ Você precisa criar um **OAuth 2.0 Client ID** no Google Cloud Console com a URI
Abra: [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)
-**2. Crie um novo OAuth 2.0 Client ID**
+**2. Inilah ID Klien OAuth 2.0 yang baru**
-- Clique em **"+ Create Credentials"** → **"OAuth client ID"**
-- Tipo de aplicativo: **"Web application"**
-- Nome: escolha qualquer nome (ex: `OmniRoute Remote`)
+- Klik pada **"+ Buat Kredensial"** → **"ID klien OAuth"**
+- Tip aplikasi: **"Aplikasi web"**
+- Nama: nama escolha qualquer (misal: `OmniRoute Remote`)
**3. Adicione as Authorized Redirect URIs**
@@ -2187,7 +2187,7 @@ https://seu-servidor.com/callback
**4. Salve e copie as credenciais**
-Após criar, o Google mostrará o **Client ID** e o **Client Secret**.
+Kemudian, Google menampilkan **ID Klien** dan **Rahasia Klien**.
**5. Configure as variáveis de ambiente**
@@ -2216,7 +2216,7 @@ docker restart omniroute
**7. Tente conectar novamente**
-Dashboard → Providers → Antigravity (ou Gemini CLI) → OAuth
+Dasbor → Penyedia → Antigravitasi (atau Gemini CLI) → OAuth
Agora o Google redirecionará corretamente para `https://seu-servidor.com/callback` e a autenticação funcionará.
@@ -2240,25 +2240,25 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
-## 🛠️ Tech Stack
+## 🛠️ Stack Teknologi
-Click to expand tech stack details
+Klik untuk membuka detail stack teknologi
-- **Runtime**: Node.js 18–22 LTS (⚠️ Node.js 24+ is **not supported** — `better-sqlite3` native binaries are incompatible)
-- **Language**: TypeScript 5.9 — **100% TypeScript** across `src/` and `open-sse/` (zero `any` in core modules since v2.0)
-- **Framework**: Next.js 16 + React 19 + Tailwind CSS 4
-- **Database**: better-sqlite3 (SQLite) + LowDB (JSON legacy) — domain state, proxy logs, MCP audit, routing decisions, memory, skills
-- **Schemas**: Zod (MCP tool I/O validation, API contracts)
-- **Protocols**: MCP (stdio/HTTP) + A2A v0.3 (JSON-RPC 2.0 + SSE)
-- **Streaming**: Server-Sent Events (SSE)
-- **Auth**: OAuth 2.0 (PKCE) + JWT + API Keys + MCP Scoped Authorization
-- **Testing**: Node.js test runner + Vitest (900+ tests including unit, integration, E2E)
-- **CI/CD**: GitHub Actions (auto npm publish + Docker Hub on release)
-- **Website**: [omniroute.online](https://omniroute.online)
-- **Package**: [npmjs.com/package/omniroute](https://www.npmjs.com/package/omniroute)
-- **Docker**: [hub.docker.com/r/diegosouzapw/omniroute](https://hub.docker.com/r/diegosouzapw/omniroute)
-- **Resilience**: Circuit breaker, exponential backoff, anti-thundering herd, TLS spoofing, auto-combo self-healing
+- **Runtime**: Node.js 18–22 LTS (⚠️ Node.js 24+ **tidak didukung** — `better-sqlite3` biner asli tidak kompatibel)
+- **Bahasa**: TypeScript 5.9 — **100% TypeScript** di `src/` dan `open-sse/` (nol `any` dalam modul inti sejak v2.0)
+- **Kerangka Kerja**: Next.js 16 + React 19 + Tailwind CSS 4
+- **Database**: lebih baik-sqlite3 (SQLite) + LowDB (JSON legacy) — status domain, log proksi, audit MCP, keputusan perutean, memori, keterampilan
+- **Skema**: Zod (validasi I/O alat MCP, kontrak API)
+- **Protokol**: MCP (stdio/HTTP) + A2A v0.3 (JSON-RPC 2.0 + SSE)
+- **Streaming**: Peristiwa Terkirim Server (SSE)
+- **Auth**: OAuth 2.0 (PKCE) + JWT + Kunci API + Otorisasi Cakupan MCP
+- **Pengujian**: Pelari pengujian Node.js + Vitest (900+ pengujian termasuk unit, integrasi, E2E)
+- **CI/CD**: Tindakan GitHub (publikasi npm otomatis + Docker Hub saat dirilis)
+- **Situs Web**: [omniroute.online](https://omniroute.online)
+- **Paket**: [npmjs.com/package/omniroute](https://www.npmjs.com/package/omniroute)
+- **Pekerja Pelabuhan**: [hub.docker.com/r/diegosouzapw/omniroute](https://hub.docker.com/r/diegosouzapw/omniroute)
+- **Ketahanan**: Pemutus arus, backoff eksponensial, kawanan anti-thundering, spoofing TLS, penyembuhan diri kombo otomatis
@@ -2268,66 +2268,66 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
| Document | Description |
| --------------------------------------------------------------------- | --------------------------------------------------- |
-| [User Guide](docs/guides/USER_GUIDE.md) | Providers, combos, CLI integration, deployment |
-| [API Reference](docs/reference/API_REFERENCE.md) | All endpoints with examples |
-| [MCP Server](open-sse/mcp-server/README.md) | 25 MCP tools, IDE configs, Python/TS/Go clients |
-| [A2A Server](src/lib/a2a/README.md) | JSON-RPC 2.0 protocol, skills, streaming, task mgmt |
+| [User Guide](docs/guides/USER_GUIDE.md) | Penyedia, kombo, integrasi CLI, penerapan |
+| [API Reference](docs/reference/API_REFERENCE.md) | Semua titik akhir dengan contoh |
+| [MCP Server](open-sse/mcp-server/README.md) | 25 alat MCP, konfigurasi IDE, klien Python/TS/Go |
+| [A2A Server](src/lib/a2a/README.md) | Protokol JSON-RPC 2.0, keterampilan, streaming, manajemen tugas |
| [Auto-Combo Engine](docs/routing/AUTO-COMBO.md) | 6-factor scoring, mode packs, self-healing |
-| [Context Relay](docs/features/context-relay.md) | Session handoff strategy for account rotation |
-| [Troubleshooting](docs/guides/TROUBLESHOOTING.md) | Common problems and solutions |
-| [Architecture](docs/architecture/ARCHITECTURE.md) | System architecture and internals |
+| [Context Relay](docs/features/context-relay.md) | Strategi penyerahan sesi untuk rotasi akun |
+| [Troubleshooting](docs/guides/TROUBLESHOOTING.md) | Masalah umum dan solusinya |
+| [Architecture](docs/architecture/ARCHITECTURE.md) | Arsitektur sistem dan internal|
| [Codebase Documentation](docs/architecture/CODEBASE_DOCUMENTATION.md) | Beginner-friendly codebase walkthrough |
-| [Uninstall Guide](docs/guides/UNINSTALL.md) | Clean removal for all install methods |
-| [Environment Config](docs/reference/ENVIRONMENT.md) | Complete `.env` variables and references |
-| [Contributing](CONTRIBUTING.md) | Development setup and guidelines |
+| [Uninstall Guide](docs/guides/UNINSTALL.md) |Penghapusan bersih untuk semua metode instalasi |
+| [Environment Config](docs/reference/ENVIRONMENT.md) | Lengkapi `.env` variabel dan referensi |
+| [Contributing](CONTRIBUTING.md) | Pengaturan dan pedoman pengembangan |
| [OpenAPI Spec](docs/reference/openapi.yaml) | OpenAPI 3.0 specification |
-| [Security Policy](SECURITY.md) | Vulnerability reporting and security practices |
-| [VM Deployment](docs/ops/VM_DEPLOYMENT_GUIDE.md) | Complete guide: VM + nginx + Cloudflare setup |
-| [Features Gallery](docs/guides/FEATURES.md) | Visual dashboard tour with screenshots |
+| [Security Policy](SECURITY.md) | Pelaporan kerentanan dan praktik keamanan |
+| [VM Deployment](docs/ops/VM_DEPLOYMENT_GUIDE.md) | Panduan lengkap: pengaturan VM + nginx + Cloudflare |
+| [Features Gallery](docs/guides/FEATURES.md) | Tur dasbor visual dengan tangkapan layar |
| [Release Checklist](docs/ops/RELEASE_CHECKLIST.md) | Pre-release validation steps |
---
## 🗺️ Roadmap
-OmniRoute has **218+ features planned** across multiple development phases. Here are the key areas:
+OmniRoute memiliki **218+ fitur yang direncanakan** di berbagai fase pengembangan. Berikut adalah bidang-bidang utamanya:
| Category | Planned Features | Highlights |
| ----------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------- |
-| 🧠 **Routing & Intelligence** | 25+ | Lowest-latency routing, tag-based routing, quota preflight, quota-aware P2C, step-based combo routing |
-| 🔒 **Security & Compliance** | 20+ | SSRF hardening, credential cloaking, rate-limit per endpoint, management key scoping |
-| 📊 **Observability** | 15+ | OpenTelemetry integration, real-time quota monitoring, combo target health, cost tracking per model |
-| 🔄 **Provider Integrations** | 20+ | Dynamic model registry, connection cooldowns, multi-account Codex, Copilot quota parsing |
-| ⚡ **Performance** | 15+ | Dual cache layer, prompt cache, response cache, streaming keepalive, batch API |
+| 🧠 **Routing & Intelligence** | 25+ | Perutean latensi terendah, perutean berbasis tag, preflight kuota, P2C sadar kuota, perutean kombo berbasis langkah |
+| 🔒 **Security & Compliance** | 20+ | Pengerasan SSRF, penyelubungan kredensial, batas tarif per titik akhir, pelingkupan kunci manajemen |
+| 📊 **Observability** | 15+ | Integrasi OpenTelemetry, pemantauan kuota waktu nyata, kesehatan target kombo, pelacakan biaya per model |
+| 🔄 **Provider Integrations** | 20+ | Registri model dinamis, cooldown koneksi, Codex multi-akun, penguraian kuota Salinan |
+| ⚡ **Performance** | 15+ | Lapisan cache ganda, cache cepat, cache respons, streaming keepalive, API batch|
| 🌐 **Ecosystem** | 10+ | WebSocket API, config hot-reload, distributed config store, commercial mode |
-### 🔜 Coming Soon
+### 🔜 Segera Hadir
-- 🔗 **OpenCode Integration** — Native provider support for the OpenCode AI coding IDE
-- 🔗 **TRAE Integration** — Full support for the TRAE AI development framework
-- 📦 **Batch API** — Asynchronous batch processing for bulk requests
-- 🎯 **Tag-Based Routing** — Route requests based on custom tags and metadata
-- 💰 **Lowest-Cost Strategy** — Automatically select the cheapest available provider
+- 🔗 **Integrasi OpenCode** — Dukungan penyedia asli untuk IDE pengkodean AI OpenCode
+- 🔗 **Integrasi TRAE** — Dukungan penuh untuk kerangka pengembangan AI TRAE
+- 📦 **Batch API** — Pemrosesan batch asinkron untuk permintaan massal
+- 🎯 **Perutean Berbasis Tag** — Merutekan permintaan berdasarkan tag dan metadata khusus
+- 💰 **Strategi Biaya Terendah** — Secara otomatis memilih penyedia termurah yang tersedia
-> 📝 Full feature specifications available in [`docs/new-features/`](docs/new-features/) (217 detailed specs)
+> 📝 Spesifikasi fitur lengkap tersedia di [docs/new-features/](docs/new-features/) (217 spesifikasi detail)
---
-## 👥 Contributors
+## 👥 Kontributor
[](https://github.com/diegosouzapw/OmniRoute/graphs/contributors)
-### How to Contribute
+### Cara Berkontribusi
-1. Fork the repository
-2. Create your feature branch (`git checkout -b feature/amazing-feature`)
-3. Commit your changes (`git commit -m 'Add amazing feature'`)
-4. Push to the branch (`git push origin feature/amazing-feature`)
-5. Open a Pull Request
+1. Cabangkan repositori
+2. Buat cabang fitur Anda (`git checkout -b feature/amazing-feature`)
+3. Komit perubahan Anda (`git commit -m 'Add amazing feature'`)
+4. Dorong ke cabang (`git push origin feature/amazing-feature`)
+5. Buka Permintaan Tarik
-See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
+Lihat [CONTRIBUTING.md](CONTRIBUTING.md) untuk panduan detailnya.
-### Releasing a New Version
+### Merilis Versi Baru
```bash
# Create a release — npm publish happens automatically
@@ -2336,7 +2336,7 @@ gh release create v2.0.0 --title "v2.0.0" --generate-notes
---
-## 📊 Star History
+## 📊 Riwayat Star
@@ -2356,15 +2356,15 @@ gh release create v2.0.0 --title "v2.0.0" --generate-notes
-## 🙏 Acknowledgments
+## 🙏 Ucapan Terima Kasih
-Special thanks to **[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)** — the original Go implementation that inspired this JavaScript port.
+Terima kasih khusus kepada **[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)** — implementasi Go asli yang menginspirasi port JavaScript ini.
---
## Lisensi
-MIT License - see [LICENSE](LICENSE) for details.
+Lisensi MIT - lihat [LICENSE](LICENSE) untuk detailnya.
---
diff --git a/docs/i18n/id/SECURITY.md b/docs/i18n/id/SECURITY.md
index 25a0cd526a..5bbfd79e9b 100644
--- a/docs/i18n/id/SECURITY.md
+++ b/docs/i18n/id/SECURITY.md
@@ -1,138 +1,138 @@
-# Security Policy (Bahasa Indonesia)
+# Kebijakan Keamanan (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../SECURITY.md) · 🇸🇦 [ar](../ar/SECURITY.md) · 🇧🇬 [bg](../bg/SECURITY.md) · 🇧🇩 [bn](../bn/SECURITY.md) · 🇨🇿 [cs](../cs/SECURITY.md) · 🇩🇰 [da](../da/SECURITY.md) · 🇩🇪 [de](../de/SECURITY.md) · 🇪🇸 [es](../es/SECURITY.md) · 🇮🇷 [fa](../fa/SECURITY.md) · 🇫🇮 [fi](../fi/SECURITY.md) · 🇫🇷 [fr](../fr/SECURITY.md) · 🇮🇳 [gu](../gu/SECURITY.md) · 🇮🇱 [he](../he/SECURITY.md) · 🇮🇳 [hi](../hi/SECURITY.md) · 🇭🇺 [hu](../hu/SECURITY.md) · 🇮🇩 [id](../id/SECURITY.md) · 🇮🇹 [it](../it/SECURITY.md) · 🇯🇵 [ja](../ja/SECURITY.md) · 🇰🇷 [ko](../ko/SECURITY.md) · 🇮🇳 [mr](../mr/SECURITY.md) · 🇲🇾 [ms](../ms/SECURITY.md) · 🇳🇱 [nl](../nl/SECURITY.md) · 🇳🇴 [no](../no/SECURITY.md) · 🇵🇭 [phi](../phi/SECURITY.md) · 🇵🇱 [pl](../pl/SECURITY.md) · 🇵🇹 [pt](../pt/SECURITY.md) · 🇧🇷 [pt-BR](../pt-BR/SECURITY.md) · 🇷🇴 [ro](../ro/SECURITY.md) · 🇷🇺 [ru](../ru/SECURITY.md) · 🇸🇰 [sk](../sk/SECURITY.md) · 🇸🇪 [sv](../sv/SECURITY.md) · 🇰🇪 [sw](../sw/SECURITY.md) · 🇮🇳 [ta](../ta/SECURITY.md) · 🇮🇳 [te](../te/SECURITY.md) · 🇹🇭 [th](../th/SECURITY.md) · 🇹🇷 [tr](../tr/SECURITY.md) · 🇺🇦 [uk-UA](../uk-UA/SECURITY.md) · 🇵🇰 [ur](../ur/SECURITY.md) · 🇻🇳 [vi](../vi/SECURITY.md) · 🇨🇳 [zh-CN](../zh-CN/SECURITY.md)
---
-## Reporting Vulnerabilities
+## Melaporkan Kerentanan
-If you discover a security vulnerability in OmniRoute, please report it responsibly:
+Jika Anda menemukan kerentanan keamanan di OmniRoute, harap laporkan secara bertanggung jawab:
-1. **DO NOT** open a public GitHub issue
-2. Use [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new)
-3. Include: description, reproduction steps, and potential impact
+1. **JANGAN** membuka isu GitHub yang bersifat publik
+2. Gunakan [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new)
+3. Sertakan: deskripsi, langkah-langkah reproduksi, dan potensi dampak
-## Response Timeline
+## Linimasa Respons
-| Stage | Target |
-| ------------------- | --------------------------- |
-| Acknowledgment | 48 hours |
-| Triage & Assessment | 5 business days |
-| Patch Release | 14 business days (critical) |
+| Tahap | Target |
+| ----------------------- | ------------------------------- |
+| Konfirmasi Penerimaan | 48 jam |
+| Triase & Penilaian | 5 hari kerja |
+| Rilis Patch | 14 hari kerja (kritis) |
-## Supported Versions
+## Versi yang Didukung
-| Version | Support Status |
-| ------- | -------------- |
-| 3.6.x | ✅ Active |
-| 3.5.x | ✅ Security |
-| < 3.5.0 | ❌ Unsupported |
+| Versi | Status Dukungan |
+| ------- | ------------------ |
+| 3.6.x | ✅ Aktif |
+| 3.5.x | ✅ Keamanan |
+| < 3.5.0 | ❌ Tidak Didukung |
---
-## Security Architecture
+## Arsitektur Keamanan
-OmniRoute implements a multi-layered security model:
+OmniRoute menerapkan model keamanan berlapis:
```
Request → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider
```
-### 🔐 Authentication & Authorization
+### 🔐 Autentikasi & Otorisasi
-| Feature | Implementation |
-| -------------------- | ---------------------------------------------------------- |
-| **Dashboard Login** | Password-based auth with JWT tokens (HttpOnly cookies) |
-| **API Key Auth** | HMAC-signed keys with CRC validation |
-| **OAuth 2.0 + PKCE** | Secure provider auth (Claude, Codex, Gemini, Cursor, etc.) |
-| **Token Refresh** | Automatic OAuth token refresh before expiry |
-| **Secure Cookies** | `AUTH_COOKIE_SECURE=true` for HTTPS environments |
-| **MCP Scopes** | 10 granular scopes for MCP tool access control |
+| Fitur | Implementasi |
+| -------------------- | ------------------------------------------------------------------- |
+| **Login Dashboard** | Autentikasi berbasis kata sandi dengan token JWT (cookie HttpOnly) |
+| **Autentikasi API Key** | Kunci bertanda tangan HMAC dengan validasi CRC |
+| **OAuth 2.0 + PKCE** | Autentikasi penyedia yang aman (Claude, Codex, Gemini, Cursor, dll.) |
+| **Pembaruan Token** | Pembaruan token OAuth otomatis sebelum kedaluwarsa |
+| **Cookie Aman** | `AUTH_COOKIE_SECURE=true` untuk lingkungan HTTPS |
+| **Ruang Lingkup MCP** | 10 ruang lingkup terperinci untuk kontrol akses alat MCP |
-### 🛡️ Encryption at Rest
+### 🛡️ Enkripsi Data Tersimpan
-All sensitive data stored in SQLite is encrypted using **AES-256-GCM** with scrypt key derivation:
+Semua data sensitif yang disimpan di SQLite dienkripsi menggunakan **AES-256-GCM** dengan derivasi kunci scrypt:
-- API keys, access tokens, refresh tokens, and ID tokens
-- Versioned format: `enc:v1:::`
-- Passthrough mode (plaintext) when `STORAGE_ENCRYPTION_KEY` is not set
+- Kunci API, token akses, token penyegaran, dan token ID
+- Format berversi: `enc:v1:::`
+- Mode passthrough (teks biasa) ketika `STORAGE_ENCRYPTION_KEY` tidak disetel
```bash
# Generate encryption key:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
-### 🧠 Prompt Injection Guard
+### 🧠 Penjaga Injeksi Prompt
-Middleware that detects and blocks prompt injection attacks in LLM requests:
+Middleware yang mendeteksi dan memblokir serangan injeksi prompt dalam permintaan LLM:
-| Pattern Type | Severity | Example |
-| ------------------- | -------- | ---------------------------------------------- |
-| System Override | High | "ignore all previous instructions" |
-| Role Hijack | High | "you are now DAN, you can do anything" |
-| Delimiter Injection | Medium | Encoded separators to break context boundaries |
-| DAN/Jailbreak | High | Known jailbreak prompt patterns |
-| Instruction Leak | Medium | "show me your system prompt" |
+| Jenis Pola | Tingkat Keparahan | Contoh |
+| ------------------- | ----------------- | ----------------------------------------------------------- |
+| Penimpaan Sistem | Tinggi | "ignore all previous instructions" |
+| Pembajakan Peran | Tinggi | "you are now DAN, you can do anything" |
+| Injeksi Pembatas | Sedang | Pemisah yang dikodekan untuk merusak batas konteks |
+| DAN/Jailbreak | Tinggi | Pola prompt jailbreak yang telah diketahui |
+| Kebocoran Instruksi | Sedang | "show me your system prompt" |
-Configure via dashboard (Settings → Security) or `.env`:
+Konfigurasikan melalui dashboard (Settings → Security) atau `.env`:
```env
INPUT_SANITIZER_ENABLED=true
INPUT_SANITIZER_MODE=block # warn | block | redact
```
-### 🔒 PII Redaction
+### 🔒 Redaksi PII
-Automatic detection and optional redaction of personally identifiable information:
+Deteksi otomatis dan redaksi opsional informasi yang dapat mengidentifikasi pribadi:
-| PII Type | Pattern | Replacement |
-| ------------- | --------------------- | ------------------ |
-| Email | `user@domain.com` | `[EMAIL_REDACTED]` |
-| CPF (Brazil) | `123.456.789-00` | `[CPF_REDACTED]` |
-| CNPJ (Brazil) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
-| Credit Card | `4111-1111-1111-1111` | `[CC_REDACTED]` |
-| Phone | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
-| SSN (US) | `123-45-6789` | `[SSN_REDACTED]` |
+| Jenis PII | Pola | Pengganti |
+| ---------------- | --------------------- | ------------------ |
+| Email | `user@domain.com` | `[EMAIL_REDACTED]` |
+| CPF (Brasil) | `123.456.789-00` | `[CPF_REDACTED]` |
+| CNPJ (Brasil) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
+| Kartu Kredit | `4111-1111-1111-1111` | `[CC_REDACTED]` |
+| Telepon | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
+| SSN (AS) | `123-45-6789` | `[SSN_REDACTED]` |
```env
PII_REDACTION_ENABLED=true
```
-### 🌐 Network Security
+### 🌐 Keamanan Jaringan
-| Feature | Description |
-| ------------------------ | ---------------------------------------------------------------- |
-| **CORS** | Configurable origin control (`CORS_ORIGIN` env var, default `*`) |
-| **IP Filtering** | Allowlist/blocklist IP ranges in dashboard |
-| **Rate Limiting** | Per-provider rate limits with automatic backoff |
-| **Anti-Thundering Herd** | Mutex + per-connection locking prevents cascading 502s |
-| **TLS Fingerprint** | Browser-like TLS fingerprint spoofing to reduce bot detection |
-| **CLI Fingerprint** | Per-provider header/body ordering to match native CLI signatures |
+| Fitur | Deskripsi |
+| ------------------------ | ------------------------------------------------------------------------------- |
+| **CORS** | Kontrol origin yang dapat dikonfigurasi (variabel env `CORS_ORIGIN`, default `*`) |
+| **Pemfilteran IP** | Daftar izin/blokir rentang IP di dashboard |
+| **Pembatasan Laju** | Batas laju per-penyedia dengan backoff otomatis |
+| **Anti-Thundering Herd** | Mutex + penguncian per-koneksi mencegah kegagalan 502 beruntun |
+| **Sidik Jari TLS** | Spoofing sidik jari TLS menyerupai browser untuk mengurangi deteksi bot |
+| **Sidik Jari CLI** | Pengurutan header/body per-penyedia agar sesuai tanda tangan CLI native |
-### 🔌 Resilience & Availability
+### 🔌 Ketahanan & Ketersediaan
-| Feature | Description |
-| ----------------------- | ------------------------------------------------------------------ |
-| **Circuit Breaker** | 3-state (Closed → Open → Half-Open) per provider, SQLite-persisted |
-| **Request Idempotency** | 5-second dedup window for duplicate requests |
-| **Exponential Backoff** | Automatic retry with increasing delays |
-| **Health Dashboard** | Real-time provider health monitoring |
+| Fitur | Deskripsi |
+| -------------------------- | ---------------------------------------------------------------------------- |
+| **Pemutus Sirkuit** | 3 status (Closed → Open → Half-Open) per penyedia, dipersistenkan di SQLite |
+| **Idempotansi Permintaan** | Jendela deduplikasi 5 detik untuk permintaan duplikat |
+| **Backoff Eksponensial** | Percobaan ulang otomatis dengan penundaan yang semakin meningkat |
+| **Dashboard Kesehatan** | Pemantauan kesehatan penyedia secara real-time |
-### 📋 Compliance
+### 📋 Kepatuhan
-| Feature | Description |
-| ------------------ | ----------------------------------------------------------- |
-| **Log Retention** | Automatic cleanup after `CALL_LOG_RETENTION_DAYS` |
-| **No-Log Opt-out** | Per API key `noLog` flag disables request logging |
-| **Audit Log** | Administrative actions tracked in `audit_log` table |
-| **MCP Audit** | SQLite-backed audit logging for all MCP tool calls |
-| **Zod Validation** | All API inputs validated with Zod v4 schemas at module load |
+| Fitur | Deskripsi |
+| ---------------------- | ---------------------------------------------------------------------- |
+| **Retensi Log** | Pembersihan otomatis setelah `CALL_LOG_RETENTION_DAYS` |
+| **Opt-out Tanpa Log** | Tanda `noLog` per kunci API menonaktifkan pencatatan permintaan |
+| **Log Audit** | Tindakan administratif dilacak di tabel `audit_log` |
+| **Audit MCP** | Pencatatan audit berbasis SQLite untuk semua pemanggilan alat MCP |
+| **Validasi Zod** | Semua input API divalidasi dengan skema Zod v4 saat pemuatan modul |
---
-## Required Environment Variables
+## Variabel Lingkungan yang Wajib Disetel
-All secrets must be set before starting the server. The server will **fail fast** if they are missing or weak.
+Semua rahasia harus disetel sebelum menjalankan server. Server akan **gagal cepat** jika nilainya tidak ada atau terlalu lemah.
```bash
# REQUIRED — server will not start without these:
@@ -143,17 +143,17 @@ API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
-The server actively rejects known-weak values like `changeme`, `secret`, or `password`.
+Server secara aktif menolak nilai yang diketahui lemah seperti `changeme`, `secret`, atau `password`.
---
-## Docker Security
+## Keamanan Docker
-- Use non-root user in production
-- Mount secrets as read-only volumes
-- Never copy `.env` files into Docker images
-- Use `.dockerignore` to exclude sensitive files
-- Set `AUTH_COOKIE_SECURE=true` when behind HTTPS
+- Gunakan pengguna non-root di lingkungan produksi
+- Pasang rahasia sebagai volume hanya-baca
+- Jangan pernah menyalin file `.env` ke dalam image Docker
+- Gunakan `.dockerignore` untuk mengecualikan file sensitif
+- Setel `AUTH_COOKIE_SECURE=true` saat berada di belakang HTTPS
```bash
docker run -d \
@@ -170,10 +170,10 @@ docker run -d \
---
-## Dependencies
+## Dependensi
-- Run `npm audit` regularly
-- Keep dependencies updated
-- The project uses `husky` + `lint-staged` for pre-commit checks
-- CI pipeline runs ESLint security rules on every push
-- Provider constants validated at module load via Zod (`src/shared/validation/providerSchema.ts`)
+- Jalankan `npm audit` secara berkala
+- Jaga agar dependensi tetap diperbarui
+- Proyek menggunakan `husky` + `lint-staged` untuk pemeriksaan pra-commit
+- Pipeline CI menjalankan aturan keamanan ESLint pada setiap push
+- Konstanta penyedia divalidasi saat pemuatan modul melalui Zod (`src/shared/validation/providerSchema.ts`)
diff --git a/docs/i18n/id/docs/architecture/ARCHITECTURE.md b/docs/i18n/id/docs/architecture/ARCHITECTURE.md
index 049bf956c5..3445d8f776 100644
--- a/docs/i18n/id/docs/architecture/ARCHITECTURE.md
+++ b/docs/i18n/id/docs/architecture/ARCHITECTURE.md
@@ -1,4 +1,4 @@
-# OmniRoute Architecture (Bahasa Indonesia)
+# Arsitektur OmniRoute (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/ARCHITECTURE.md) · 🇸🇦 [ar](../../ar/docs/ARCHITECTURE.md) · 🇧🇬 [bg](../../bg/docs/ARCHITECTURE.md) · 🇧🇩 [bn](../../bn/docs/ARCHITECTURE.md) · 🇨🇿 [cs](../../cs/docs/ARCHITECTURE.md) · 🇩🇰 [da](../../da/docs/ARCHITECTURE.md) · 🇩🇪 [de](../../de/docs/ARCHITECTURE.md) · 🇪🇸 [es](../../es/docs/ARCHITECTURE.md) · 🇮🇷 [fa](../../fa/docs/ARCHITECTURE.md) · 🇫🇮 [fi](../../fi/docs/ARCHITECTURE.md) · 🇫🇷 [fr](../../fr/docs/ARCHITECTURE.md) · 🇮🇳 [gu](../../gu/docs/ARCHITECTURE.md) · 🇮🇱 [he](../../he/docs/ARCHITECTURE.md) · 🇮🇳 [hi](../../hi/docs/ARCHITECTURE.md) · 🇭🇺 [hu](../../hu/docs/ARCHITECTURE.md) · 🇮🇩 [id](../../id/docs/ARCHITECTURE.md) · 🇮🇹 [it](../../it/docs/ARCHITECTURE.md) · 🇯🇵 [ja](../../ja/docs/ARCHITECTURE.md) · 🇰🇷 [ko](../../ko/docs/ARCHITECTURE.md) · 🇮🇳 [mr](../../mr/docs/ARCHITECTURE.md) · 🇲🇾 [ms](../../ms/docs/ARCHITECTURE.md) · 🇳🇱 [nl](../../nl/docs/ARCHITECTURE.md) · 🇳🇴 [no](../../no/docs/ARCHITECTURE.md) · 🇵🇭 [phi](../../phi/docs/ARCHITECTURE.md) · 🇵🇱 [pl](../../pl/docs/ARCHITECTURE.md) · 🇵🇹 [pt](../../pt/docs/ARCHITECTURE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/ARCHITECTURE.md) · 🇷🇴 [ro](../../ro/docs/ARCHITECTURE.md) · 🇷🇺 [ru](../../ru/docs/ARCHITECTURE.md) · 🇸🇰 [sk](../../sk/docs/ARCHITECTURE.md) · 🇸🇪 [sv](../../sv/docs/ARCHITECTURE.md) · 🇰🇪 [sw](../../sw/docs/ARCHITECTURE.md) · 🇮🇳 [ta](../../ta/docs/ARCHITECTURE.md) · 🇮🇳 [te](../../te/docs/ARCHITECTURE.md) · 🇹🇭 [th](../../th/docs/ARCHITECTURE.md) · 🇹🇷 [tr](../../tr/docs/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/ARCHITECTURE.md) · 🇵🇰 [ur](../../ur/docs/ARCHITECTURE.md) · 🇻🇳 [vi](../../vi/docs/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/ARCHITECTURE.md)
@@ -6,117 +6,117 @@
_Last updated: 2026-04-15_
-## Executive Summary
+## Ringkasan Eksekutif
-OmniRoute is a local AI routing gateway and dashboard built on Next.js.
-It provides a single OpenAI-compatible endpoint (`/v1/*`) and routes traffic across multiple upstream providers with translation, fallback, token refresh, and usage tracking.
+OmniRoute adalah gateway routing AI lokal dan dasbor yang dibangun di atas Next.js.
+Sistem ini menyediakan satu endpoint yang kompatibel dengan OpenAI (`/v1/*`) dan merutekan lalu lintas ke berbagai penyedia upstream dengan kemampuan translasi, fallback, pembaruan token, dan pelacakan penggunaan.
-Core capabilities:
+Kemampuan inti:
-- OpenAI-compatible API surface for CLI/tools (100+ providers, 16 executors)
-- Request/response translation across provider formats
-- Model combo fallback (multi-model sequence)
-- Structured combo steps (`provider + model + connection`) with runtime ordering by `compositeTiers`
-- Account-level fallback (multi-account per provider)
-- Quota preflight and quota-aware P2C account selection in the main chat path
-- OAuth + API-key provider connection management (13 OAuth modules)
-- Embedding generation via `/v1/embeddings` (6 providers, 9 models)
-- Image generation via `/v1/images/generations` (10+ providers, 20+ models)
-- Audio transcription via `/v1/audio/transcriptions` (7 providers)
-- Text-to-speech via `/v1/audio/speech` (10 providers)
-- Video generation via `/v1/videos/generations` (ComfyUI + SD WebUI)
-- Music generation via `/v1/music/generations` (ComfyUI)
-- Web search via `/v1/search` (5 providers)
-- Moderations via `/v1/moderations`
-- Reranking via `/v1/rerank`
-- Think tag parsing (`...`) for reasoning models
-- Response sanitization for strict OpenAI SDK compatibility
-- Role normalization (developer→system, system→user) for cross-provider compatibility
-- Structured output conversion (json_schema → Gemini responseSchema)
-- Local persistence for providers, keys, aliases, combos, settings, pricing (26 DB modules)
-- Usage/cost tracking and request logging
-- Optional cloud sync for multi-device/state sync
-- IP allowlist/blocklist for API access control
-- Thinking budget management (passthrough/auto/custom/adaptive)
-- Global system prompt injection
-- Session tracking and fingerprinting
-- Per-account enhanced rate limiting with provider-specific profiles
-- Circuit breaker pattern for provider resilience
-- Anti-thundering herd protection with mutex locking
-- Signature-based request deduplication cache
-- Domain layer: cost rules, fallback policy, lockout policy
-- Context Relay: session handoff summaries for account rotation continuity
-- Domain state persistence (SQLite write-through cache for fallbacks, budgets, lockouts, circuit breakers)
-- Policy engine for centralized request evaluation (lockout → budget → fallback)
-- Request telemetry with p50/p95/p99 latency aggregation
-- Combo target telemetry and historical combo target health via `combo_execution_key` / `combo_step_id`
-- Correlation ID (X-Request-Id) for end-to-end tracing
-- Compliance audit logging with opt-out per API key
-- Eval framework for LLM quality assurance
-- Health dashboard with real-time provider circuit breaker status
-- MCP Server (25 tools) with 3 transports (stdio/SSE/Streamable HTTP)
-- A2A Server (JSON-RPC 2.0 + SSE) with skills and task lifecycle
-- Memory system (extraction, injection, retrieval, summarization)
-- Skills system (registry, executor, sandbox, built-in skills)
-- MITM proxy with certificate management and DNS handling
-- Prompt injection guard middleware
-- ACP (Agent Communication Protocol) registry
-- Modular OAuth providers (13 individual modules under `src/lib/oauth/providers/`)
-- Uninstall/full-uninstall scripts
-- OAuth environment repair action
-- WebSocket bridge for OpenAI-compatible WS clients (`/v1/ws`)
-- Sync token management (issue/revoke, ETag-versioned config bundle download)
-- GLM Thinking (`glmt`) first-class provider preset
-- Hybrid token counting (provider-side `/messages/count_tokens` with estimation fallback)
-- Model alias auto-seeding (30+ cross-proxy dialect normalizations at startup)
-- Safe outbound fetch with SSRF guard, private URL blocking, and configurable retry
-- Cooldown-aware chat retries with configurable `requestRetry` and `maxRetryIntervalSec`
-- Runtime environment validation with Zod at startup
-- Compliance audit v2 with pagination, provider CRUD events, and SSRF-blocked validation logging
+- Antarmuka API yang kompatibel dengan OpenAI untuk CLI/tools (100+ penyedia, 16 executor)
+- Translasi permintaan/respons antar format penyedia
+- Fallback combo model (urutan multi-model)
+- Langkah combo terstruktur (`provider + model + connection`) dengan pengurutan runtime melalui `compositeTiers`
+- Fallback di tingkat akun (multi-akun per penyedia)
+- Preflight kuota dan pemilihan akun P2C yang sadar kuota pada jalur chat utama
+- Manajemen koneksi penyedia OAuth + API-key (13 modul OAuth)
+- Pembuatan embedding melalui `/v1/embeddings` (6 penyedia, 9 model)
+- Pembuatan gambar melalui `/v1/images/generations` (10+ penyedia, 20+ model)
+- Transkripsi audio melalui `/v1/audio/transcriptions` (7 penyedia)
+- Text-to-speech melalui `/v1/audio/speech` (10 penyedia)
+- Pembuatan video melalui `/v1/videos/generations` (ComfyUI + SD WebUI)
+- Pembuatan musik melalui `/v1/music/generations` (ComfyUI)
+- Pencarian web melalui `/v1/search` (5 penyedia)
+- Moderasi melalui `/v1/moderations`
+- Reranking melalui `/v1/rerank`
+- Penguraian think tag (`...`) untuk model penalaran
+- Sanitasi respons untuk kompatibilitas ketat OpenAI SDK
+- Normalisasi peran (developer→system, system→user) untuk kompatibilitas lintas penyedia
+- Konversi output terstruktur (json_schema → Gemini responseSchema)
+- Persistensi lokal untuk penyedia, kunci, alias, combo, pengaturan, harga (26 modul DB)
+- Pelacakan penggunaan/biaya dan pencatatan permintaan
+- Sinkronisasi cloud opsional untuk sinkronisasi multi-perangkat/status
+- Daftar izin/blokir IP untuk kontrol akses API
+- Manajemen anggaran berpikir (passthrough/auto/custom/adaptive)
+- Injeksi system prompt global
+- Pelacakan sesi dan fingerprinting
+- Pembatasan laju yang ditingkatkan per akun dengan profil khusus penyedia
+- Pola circuit breaker untuk ketahanan penyedia
+- Perlindungan anti-thundering herd dengan penguncian mutex
+- Cache deduplikasi permintaan berbasis tanda tangan
+- Lapisan domain: aturan biaya, kebijakan fallback, kebijakan lockout
+- Context Relay: ringkasan handoff sesi untuk kesinambungan rotasi akun
+- Persistensi status domain (cache write-through SQLite untuk fallback, anggaran, lockout, circuit breaker)
+- Mesin kebijakan untuk evaluasi permintaan terpusat (lockout → budget → fallback)
+- Telemetri permintaan dengan agregasi latensi p50/p95/p99
+- Telemetri target combo dan kesehatan target combo historis melalui `combo_execution_key` / `combo_step_id`
+- Correlation ID (X-Request-Id) untuk pelacakan end-to-end
+- Pencatatan audit kepatuhan dengan opsi keluar per API key
+- Kerangka eval untuk penjaminan kualitas LLM
+- Dasbor kesehatan dengan status circuit breaker penyedia secara real-time
+- MCP Server (25 tools) dengan 3 transport (stdio/SSE/Streamable HTTP)
+- A2A Server (JSON-RPC 2.0 + SSE) dengan skill dan siklus hidup tugas
+- Sistem memori (ekstraksi, injeksi, pengambilan, perangkuman)
+- Sistem skill (registry, executor, sandbox, skill bawaan)
+- Proxy MITM dengan manajemen sertifikat dan penanganan DNS
+- Middleware penjaga injeksi prompt
+- Registry ACP (Agent Communication Protocol)
+- Penyedia OAuth modular (13 modul individual di bawah `src/lib/oauth/providers/`)
+- Skrip uninstall/full-uninstall
+- Aksi perbaikan lingkungan OAuth
+- Jembatan WebSocket untuk klien WS yang kompatibel dengan OpenAI (`/v1/ws`)
+- Manajemen token sinkronisasi (penerbitan/pencabutan, unduhan bundel konfigurasi berversi ETag)
+- Preset penyedia utama GLM Thinking (`glmt`)
+- Penghitungan token hybrid (sisi penyedia `/messages/count_tokens` dengan fallback estimasi)
+- Penyemaian alias model otomatis (30+ normalisasi dialek lintas proxy saat startup)
+- Pengambilan outbound aman dengan penjaga SSRF, pemblokiran URL privat, dan percobaan ulang yang dapat dikonfigurasi
+- Percobaan ulang chat yang sadar cooldown dengan `requestRetry` dan `maxRetryIntervalSec` yang dapat dikonfigurasi
+- Validasi lingkungan runtime dengan Zod saat startup
+- Audit kepatuhan v2 dengan paginasi, event CRUD penyedia, dan pencatatan validasi yang diblokir SSRF
-Primary runtime model:
+Waktu proses model utama:
-- Next.js app routes under `src/app/api/*` implement both dashboard APIs and compatibility APIs
-- A shared SSE/routing core in `src/sse/*` + `open-sse/*` handles provider execution, translation, streaming, fallback, and usage
+- Route aplikasi Next.js di bawah `src/app/api/*` mengimplementasikan API dasbor dan API kompatibilitas
+- Inti SSE/routing bersama dalam `src/sse/*` + `open-sse/*` menangani eksekusi penyedia, translasi, streaming, fallback, dan penggunaan
-## Scope and Boundaries
+## Ruang Lingkup dan Batasan
-### In Scope
+### Dalam Ruang Lingkup
-- Local gateway runtime
-- Dashboard management APIs
-- Provider authentication and token refresh
-- Request translation and SSE streaming
-- Local state + usage persistence
-- Optional cloud sync orchestration
+- Runtime gateway lokal
+- API manajemen dasbor
+- Autentikasi penyedia dan pembaruan token
+- Translasi permintaan dan streaming SSE
+- Persistensi status lokal + penggunaan
+- Orkestrasi sinkronisasi cloud opsional
-### Out of Scope
+### Di Luar Ruang Lingkup
-- Cloud service implementation behind `NEXT_PUBLIC_CLOUD_URL`
-- Provider SLA/control plane outside local process
-- External CLI binaries themselves (Claude CLI, Codex CLI, etc.)
+- Implementasi layanan cloud di balik `NEXT_PUBLIC_CLOUD_URL`
+- SLA/control plane penyedia di luar proses lokal
+- Biner CLI eksternal itu sendiri (Claude CLI, Codex CLI, dll.)
-## Dashboard Surface (Current)
+## Tampilan Dasbor (Saat Ini)
-Main pages under `src/app/(dashboard)/dashboard/`:
+Halaman utama di bawah `src/app/(dashboard)/dashboard/`:
-- `/dashboard` — quick start + provider overview
-- `/dashboard/endpoint` — endpoint proxy + MCP + A2A + API endpoint tabs
-- `/dashboard/providers` — provider connections and credentials
-- `/dashboard/combos` — combo strategies, templates, step-based builder, model routing rules, manual persisted ordering
-- `/dashboard/costs` — cost aggregation and pricing visibility
-- `/dashboard/analytics` — usage analytics, evaluations, combo target health
-- `/dashboard/limits` — quota/rate controls
-- `/dashboard/cli-tools` — CLI onboarding, runtime detection, config generation
-- `/dashboard/agents` — detected ACP agents + custom agent registration
-- `/dashboard/media` — image/video/music playground
-- `/dashboard/search-tools` — search provider testing and history
-- `/dashboard/health` — uptime, circuit breakers, rate limits, quota-monitored sessions
-- `/dashboard/logs` — request/proxy/audit/console logs
-- `/dashboard/settings` — system settings tabs (general, routing, combo defaults, etc.)
-- `/dashboard/api-manager` — API key lifecycle and model permissions
+- `/dashboard` — panduan cepat + ikhtisar penyedia
+- `/dashboard/endpoint` — tab proxy endpoint + MCP + A2A + endpoint API
+- `/dashboard/providers` — koneksi penyedia dan kredensial
+- `/dashboard/combos` — strategi combo, template, pembuat berbasis langkah, aturan routing model, pengurutan persisten manual
+- `/dashboard/costs` — agregasi biaya dan visibilitas harga
+- `/dashboard/analytics` — analitik penggunaan, evaluasi, kesehatan target combo
+- `/dashboard/limits` — kontrol kuota/laju
+- `/dashboard/cli-tools` — orientasi CLI, deteksi runtime, pembuatan konfigurasi
+- `/dashboard/agents` — agen ACP yang terdeteksi + pendaftaran agen kustom
+- `/dashboard/media` — playground gambar/video/musik
+- `/dashboard/search-tools` — pengujian penyedia pencarian dan riwayat
+- `/dashboard/health` — uptime, circuit breaker, batas laju, sesi yang dipantau kuota
+- `/dashboard/logs` — log permintaan/proxy/audit/konsol
+- `/dashboard/settings` — tab pengaturan sistem (umum, routing, default combo, dll.)
+- `/dashboard/api-manager` — siklus hidup API key dan izin model
-## High-Level System Context
+## Konteks Sistem Tingkat Tinggi
```mermaid
flowchart LR
@@ -164,279 +164,279 @@ flowchart LR
DASH --> CLOUD
```
-## Core Runtime Components
+## Komponen Runtime Inti
-## 1) API and Routing Layer (Next.js App Routes)
+## 1) Lapisan API dan Routing (Next.js App Routes)
-Main directories:
+Direktori utama:
-- `src/app/api/v1/*` and `src/app/api/v1beta/*` for compatibility APIs
-- `src/app/api/*` for management/configuration APIs
-- Next rewrites in `next.config.mjs` map `/v1/*` to `/api/v1/*`
+- `src/app/api/v1/*` dan `src/app/api/v1beta/*` untuk API kompatibilitas
+- `src/app/api/*` untuk API manajemen/konfigurasi
+- Selanjutnya penulisan ulang di `next.config.mjs` peta `/v1/*` menjadi `/api/v1/*`
-Important compatibility routes:
+Route kompatibilitas penting:
- `src/app/api/v1/chat/completions/route.ts`
- `src/app/api/v1/messages/route.ts`
- `src/app/api/v1/responses/route.ts`
-- `src/app/api/v1/models/route.ts` — includes custom models with `custom: true`
-- `src/app/api/v1/embeddings/route.ts` — embedding generation (6 providers)
-- `src/app/api/v1/images/generations/route.ts` — image generation (4+ providers incl. Antigravity/Nebius)
+- `src/app/api/v1/models/route.ts` — termasuk model khusus dengan `custom: true`
+- `src/app/api/v1/embeddings/route.ts` — generasi penyematan (6 penyedia)
+- `src/app/api/v1/images/generations/route.ts` — pembuatan gambar (4+ penyedia termasuk Antigravitasi/Nebius)
- `src/app/api/v1/messages/count_tokens/route.ts`
-- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — dedicated per-provider chat
-- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — dedicated per-provider embeddings
-- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — dedicated per-provider images
+- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — obrolan khusus per penyedia
+- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — penyematan khusus per penyedia
+- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — gambar khusus per penyedia
- `src/app/api/v1beta/models/route.ts`
- `src/app/api/v1beta/models/[...path]/route.ts`
-Management domains:
+Domain manajemen:
-- Auth/settings: `src/app/api/auth/*`, `src/app/api/settings/*`
-- Providers/connections: `src/app/api/providers*`
-- Provider nodes: `src/app/api/provider-nodes*`
-- Custom models: `src/app/api/provider-models` (GET/POST/DELETE)
-- Model catalog: `src/app/api/models/route.ts` (GET)
-- Proxy config: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
+- Auth/pengaturan: `src/app/api/auth/*`, `src/app/api/settings/*`
+- Penyedia/koneksi: `src/app/api/providers*`
+- Node penyedia: `src/app/api/provider-nodes*`
+- Model kustom: `src/app/api/provider-models` (GET/POST/DELETE)
+- Katalog model: `src/app/api/models/route.ts` (GET)
+- Konfigurasi proxy: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
- OAuth: `src/app/api/oauth/*`
-- Keys/aliases/combos/pricing: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
-- Usage: `src/app/api/usage/*`
+- Kunci/alias/combo/harga: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
+- Penggunaan: `src/app/api/usage/*`
- Sync/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*`
-- CLI tooling helpers: `src/app/api/cli-tools/*`
-- IP filter: `src/app/api/settings/ip-filter` (GET/PUT)
-- Thinking budget: `src/app/api/settings/thinking-budget` (GET/PUT)
+- Pembantu alat CLI: `src/app/api/cli-tools/*`
+- Filter IP: `src/app/api/settings/ip-filter` (GET/PUT)
+- Anggaran berpikir: `src/app/api/settings/thinking-budget` (GET/PUT)
- System prompt: `src/app/api/settings/system-prompt` (GET/PUT)
-- Sessions: `src/app/api/sessions` (GET)
-- Rate limits: `src/app/api/rate-limits` (GET)
-- Resilience: `src/app/api/resilience` (GET/PATCH) — request queue, connection cooldown, provider breaker, wait-for-cooldown config
-- Resilience reset: `src/app/api/resilience/reset` (POST) — reset provider breakers
-- Cache stats: `src/app/api/cache/stats` (GET/DELETE)
-- Telemetry: `src/app/api/telemetry/summary` (GET)
-- Budget: `src/app/api/usage/budget` (GET/POST)
-- Fallback chains: `src/app/api/fallback/chains` (GET/POST/DELETE)
-- Compliance audit: `src/app/api/compliance/audit-log` (GET, with pagination + structured metadata)
-- Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
-- Policies: `src/app/api/policies` (GET/POST)
-- Sync tokens: `src/app/api/sync/tokens` (GET/POST), `src/app/api/sync/tokens/[id]` (GET/DELETE)
-- Config bundle: `src/app/api/sync/bundle` (GET, ETag-versioned snapshot of settings/providers/combos/keys)
-- WebSocket: `src/app/api/v1/ws/route.ts` — Upgrade handler for OpenAI-compatible WS clients
+- Sesi: `src/app/api/sessions` (GET)
+- Batas laju: `src/app/api/rate-limits` (GET)
+- Ketahanan: `src/app/api/resilience` (GET/PATCH) — antrean permintaan, cooldown koneksi, breaker penyedia, konfigurasi wait-for-cooldown
+- Reset ketahanan: `src/app/api/resilience/reset` (POST) — reset breaker penyedia
+- Statistik cache: `src/app/api/cache/stats` (GET/DELETE)
+- Telemetri: `src/app/api/telemetry/summary` (GET)
+- Anggaran: `src/app/api/usage/budget` (GET/POST)
+- Rantai fallback: `src/app/api/fallback/chains` (GET/POST/DELETE)
+- Audit kepatuhan: `src/app/api/compliance/audit-log` (GET, dengan paginasi + metadata terstruktur)
+- Eval: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
+- Kebijakan: `src/app/api/policies` (GET/POST)
+- Token sinkronisasi: `src/app/api/sync/tokens` (GET/POST), `src/app/api/sync/tokens/[id]` (GET/DELETE)
+- Bundel konfigurasi: `src/app/api/sync/bundle` (GET, snapshot berversi ETag dari pengaturan/penyedia/combo/kunci)
+- WebSocket: `src/app/api/v1/ws/route.ts` — handler Upgrade untuk klien WS yang kompatibel dengan OpenAI
-## 2) SSE + Translation Core
+## 2) Inti SSE + Translasi
-Main flow modules:
+Modul aliran utama:
-- Entry: `src/sse/handlers/chat.ts`
-- Core orchestration: `open-sse/handlers/chatCore.ts`
-- Provider execution adapters: `open-sse/executors/*`
-- Format detection/provider config: `open-sse/services/provider.ts`
-- Model parse/resolve: `src/sse/services/model.ts`, `open-sse/services/model.ts`
-- Account fallback logic: `open-sse/services/accountFallback.ts`
-- Translation registry: `open-sse/translator/index.ts`
-- Stream transformations: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts`
-- Usage extraction/normalization: `open-sse/utils/usageTracking.ts`
-- Think tag parser: `open-sse/utils/thinkTagParser.ts`
-- Embedding handler: `open-sse/handlers/embeddings.ts`
-- Embedding provider registry: `open-sse/config/embeddingRegistry.ts`
-- Image generation handler: `open-sse/handlers/imageGeneration.ts`
-- Image provider registry: `open-sse/config/imageRegistry.ts`
-- Response sanitization: `open-sse/handlers/responseSanitizer.ts`
-- Role normalization: `open-sse/services/roleNormalizer.ts`
+- Entri: `src/sse/handlers/chat.ts`
+- Orkestrasi inti: `open-sse/handlers/chatCore.ts`
+- Adaptor eksekusi penyedia: `open-sse/executors/*`
+- Deteksi format/konfigurasi penyedia: `open-sse/services/provider.ts`
+- Penguraian/resolusi model: `src/sse/services/model.ts`, `open-sse/services/model.ts`
+- Logika fallback akun: `open-sse/services/accountFallback.ts`
+- Registry translasi: `open-sse/translator/index.ts`
+- Transformasi stream: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts`
+- Ekstraksi/normalisasi penggunaan: `open-sse/utils/usageTracking.ts`
+- Pengurai think tag: `open-sse/utils/thinkTagParser.ts`
+- Handler embedding: `open-sse/handlers/embeddings.ts`
+- Registry penyedia embedding: `open-sse/config/embeddingRegistry.ts`
+- Handler pembuatan gambar: `open-sse/handlers/imageGeneration.ts`
+- Registry penyedia gambar: `open-sse/config/imageRegistry.ts`
+- Sanitasi respons: `open-sse/handlers/responseSanitizer.ts`
+- Normalisasi peran: `open-sse/services/roleNormalizer.ts`
-Services (business logic):
+Layanan (logika bisnis):
-- Account selection/scoring: `open-sse/services/accountSelector.ts`
-- Context lifecycle management: `open-sse/services/contextManager.ts`
-- IP filter enforcement: `open-sse/services/ipFilter.ts`
-- Session tracking: `open-sse/services/sessionManager.ts`
-- Request deduplication: `open-sse/services/signatureCache.ts`
-- System prompt injection: `open-sse/services/systemPrompt.ts`
-- Thinking budget management: `open-sse/services/thinkingBudget.ts`
-- Wildcard model routing: `open-sse/services/wildcardRouter.ts`
-- Rate limit management: `open-sse/services/rateLimitManager.ts`
+- Pemilihan/penilaian akun: `open-sse/services/accountSelector.ts`
+- Manajemen siklus hidup konteks: `open-sse/services/contextManager.ts`
+- Penegakan filter IP: `open-sse/services/ipFilter.ts`
+- Pelacakan sesi: `open-sse/services/sessionManager.ts`
+- Deduplikasi permintaan: `open-sse/services/signatureCache.ts`
+- Injeksi system prompt: `open-sse/services/systemPrompt.ts`
+- Manajemen anggaran berpikir: `open-sse/services/thinkingBudget.ts`
+- Routing model wildcard: `open-sse/services/wildcardRouter.ts`
+- Manajemen batas laju: `open-sse/services/rateLimitManager.ts`
- Circuit breaker: `open-sse/services/circuitBreaker.ts`
-- Context handoff: `open-sse/services/contextHandoff.ts` — handoff summary generation and injection for context-relay strategy
-- Codex quota fetcher: `open-sse/services/codexQuotaFetcher.ts` — fetches Codex quota for context-relay handoff decisions
-- Cooldown-aware retry: `src/sse/services/cooldownAwareRetry.ts` — per-model cooldown retries with configurable `requestRetry` / `maxRetryIntervalSec`
-- Safe outbound fetch: `src/shared/network/safeOutboundFetch.ts` — guarded provider/model fetch with SSRF guard, private-URL blocking, retry, and timeout
-- Outbound URL guard: `src/shared/network/outboundUrlGuard.ts` — validates provider URLs against private/localhost CIDR ranges
-- Provider request defaults: `open-sse/services/providerRequestDefaults.ts` — provider-level `maxTokens`, `temperature`, `thinkingBudgetTokens` defaults
-- GLM provider constants: `open-sse/config/glmProvider.ts` — shared GLM models, quota URLs, GLMT timeout/defaults
-- Antigravity upstream: `open-sse/config/antigravityUpstream.ts` — base URL and discovery path constants
-- Codex client constants: `open-sse/config/codexClient.ts` — versioned user-agent and client-version values
-- Model alias seed: `src/lib/modelAliasSeed.ts` — seeds 30+ cross-proxy dialect aliases at startup
+- Handoff konteks: `open-sse/services/contextHandoff.ts` — pembuatan dan injeksi ringkasan handoff untuk strategi context-relay
+- Pengambil kuota Codex: `open-sse/services/codexQuotaFetcher.ts` — mengambil kuota Codex untuk keputusan handoff context-relay
+- Percobaan ulang yang sadar cooldown: `src/sse/services/cooldownAwareRetry.ts` — percobaan ulang cooldown per model dengan `requestRetry` / `maxRetryIntervalSec` yang dapat dikonfigurasi
+- Pengambilan outbound aman: `src/shared/network/safeOutboundFetch.ts` — pengambilan penyedia/model yang dijaga dengan penjaga SSRF, pemblokiran URL privat, percobaan ulang, dan batas waktu
+- Penjaga URL outbound: `src/shared/network/outboundUrlGuard.ts` — memvalidasi URL penyedia terhadap rentang CIDR privat/localhost
+- Default permintaan penyedia: `open-sse/services/providerRequestDefaults.ts` — default `maxTokens`, `temperature`, `thinkingBudgetTokens` tingkat penyedia
+- Konstanta penyedia GLM: `open-sse/config/glmProvider.ts` — model GLM bersama, URL kuota, timeout/default GLMT
+- Upstream Antigravity: `open-sse/config/antigravityUpstream.ts` — konstanta base URL dan jalur discovery
+- Konstanta klien Codex: `open-sse/config/codexClient.ts` — nilai user-agent dan client-version berversi
+- Seed alias model: `src/lib/modelAliasSeed.ts` — menyemai 30+ alias dialek lintas proxy saat startup
-Domain layer modules:
+Modul lapisan domain:
-- Cost rules/budgets: `src/lib/domain/costRules.ts`
-- Fallback policy: `src/lib/domain/fallbackPolicy.ts`
-- Combo resolver: `src/lib/domain/comboResolver.ts`
-- Lockout policy: `src/lib/domain/lockoutPolicy.ts`
-- Policy engine: `src/domain/policyEngine.ts` — centralized lockout → budget → fallback evaluation
-- Error codes catalog: `src/lib/domain/errorCodes.ts`
-- Request ID: `src/lib/domain/requestId.ts`
-- Fetch timeout: `src/lib/domain/fetchTimeout.ts`
-- Request telemetry: `src/lib/domain/requestTelemetry.ts`
-- Compliance/audit: `src/lib/domain/compliance/index.ts`
-- Eval runner: `src/lib/domain/evalRunner.ts`
-- Domain state persistence: `src/lib/db/domainState.ts` — SQLite CRUD for fallback chains, budgets, cost history, lockout state, circuit breakers
+- Aturan biaya/anggaran: `src/lib/domain/costRules.ts`
+- Kebijakan fallback: `src/lib/domain/fallbackPolicy.ts`
+- Resolver combo: `src/lib/domain/comboResolver.ts`
+- Kebijakan lockout: `src/lib/domain/lockoutPolicy.ts`
+- Mesin kebijakan: `src/domain/policyEngine.ts` — evaluasi terpusat lockout → budget → fallback
+- Katalog kode kesalahan: `src/lib/domain/errorCodes.ts`
+- ID permintaan: `src/lib/domain/requestId.ts`
+- Batas waktu pengambilan: `src/lib/domain/fetchTimeout.ts`
+- Telemetri permintaan: `src/lib/domain/requestTelemetry.ts`
+- Kepatuhan/audit: `src/lib/domain/compliance/index.ts`
+- Pelari eval: `src/lib/domain/evalRunner.ts`
+- Persistensi status domain: `src/lib/db/domainState.ts` — CRUD SQLite untuk rantai fallback, anggaran, riwayat biaya, status lockout, circuit breaker
-OAuth provider modules (13 individual files under `src/lib/oauth/providers/`):
+Modul penyedia OAuth (13 file individual di bawah `src/lib/oauth/providers/`):
-- Registry index: `src/lib/oauth/providers/index.ts`
-- Individual providers: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
-- Thin wrapper: `src/lib/oauth/providers.ts` — re-exports from individual modules
+- Indeks registry: `src/lib/oauth/providers/index.ts`
+- Penyedia individual: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
+- Pembungkus tipis: `src/lib/oauth/providers.ts` — re-ekspor dari modul individual
-## 3) Persistence Layer
+## 3) Lapisan Persistensi
-Primary state DB (SQLite):
+DB status utama (SQLite):
-- Core infra: `src/lib/db/core.ts` (better-sqlite3, migrations, WAL)
-- Re-export facade: `src/lib/localDb.ts` (thin compatibility layer for callers)
-- file: `${DATA_DIR}/storage.sqlite` (or `$XDG_CONFIG_HOME/omniroute/storage.sqlite` when set, else `~/.omniroute/storage.sqlite`)
-- entities (tables + KV namespaces): providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt**
+- Infrastruktur inti: `src/lib/db/core.ts` (better-sqlite3, migrasi, WAL)
+- Fasad re-ekspor: `src/lib/localDb.ts` (lapisan kompatibilitas tipis untuk pemanggil)
+- File: `${DATA_DIR}/storage.sqlite` (atau `$XDG_CONFIG_HOME/omniroute/storage.sqlite` jika diatur, jika tidak `~/.omniroute/storage.sqlite`)
+- Entitas (tabel + namespace KV): providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt**
-Usage persistence:
+Persistensi penggunaan:
-- facade: `src/lib/usageDb.ts` (decomposed modules in `src/lib/usage/*`)
-- SQLite tables in `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs`
-- optional file artifacts remain for compatibility/debug (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `/logs/...`)
-- legacy JSON files are migrated to SQLite by startup migrations when present
+- Fasad: `src/lib/usageDb.ts` (modul terurai dalam `src/lib/usage/*`)
+- Tabel SQLite dalam `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs`
+- Artefak file opsional tetap ada untuk kompatibilitas/debug (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `/logs/...`)
+- File JSON lama dimigrasikan ke SQLite oleh migrasi startup jika ada
-Domain State DB (SQLite):
+DB Status Domain (SQLite):
-- `src/lib/db/domainState.ts` — CRUD operations for domain state
-- Tables (created in `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
-- Write-through cache pattern: in-memory Maps are authoritative at runtime; mutations are written synchronously to SQLite; state is restored from DB on cold start
+- `src/lib/db/domainState.ts` — operasi CRUD untuk status domain
+- Tabel (dibuat di `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
+- Pola cache write-through: Map dalam memori bersifat otoritatif saat runtime; mutasi ditulis secara sinkron ke SQLite; status dipulihkan dari DB saat cold start
-## 4) Auth + Security Surfaces
+## 4) Permukaan Auth + Keamanan
-- Dashboard cookie auth: `src/proxy.ts`, `src/app/api/auth/login/route.ts`
-- API key generation/verification: `src/shared/utils/apiKey.ts`
-- Provider secrets persisted in `providerConnections` entries
-- Outbound proxy support via `open-sse/utils/proxyFetch.ts` (env vars) and `open-sse/utils/networkProxy.ts` (configurable per-provider or global)
-- SSRF / outbound URL guard: `src/shared/network/outboundUrlGuard.ts` — blocks private/loopback/link-local ranges for all provider calls
-- Runtime env validation: `src/lib/env/runtimeEnv.ts` — Zod schema for all environment variables, surfaced as startup errors/warnings
-- Sync tokens: `src/lib/db/syncTokens.ts` — scoped tokens for config bundle download endpoints; backed by `sync_tokens` SQLite table (migration `024_create_sync_tokens.sql`)
-- WebSocket handshake auth: `src/lib/ws/handshake.ts` — validates WS upgrade requests via API key or session cookie
+- Auth cookie dasbor: `src/proxy.ts`, `src/app/api/auth/login/route.ts`
+- Pembuatan/verifikasi API key: `src/shared/utils/apiKey.ts`
+- Rahasia penyedia yang disimpan dalam entri `providerConnections`
+- Dukungan proxy outbound melalui `open-sse/utils/proxyFetch.ts` (env var) dan `open-sse/utils/networkProxy.ts` (dapat dikonfigurasi per penyedia atau global)
+- Penjaga SSRF/URL outbound: `src/shared/network/outboundUrlGuard.ts` — memblokir rentang privat/loopback/link-local untuk semua panggilan penyedia
+- Validasi env runtime: `src/lib/env/runtimeEnv.ts` — skema Zod untuk semua variabel lingkungan, ditampilkan sebagai kesalahan/peringatan saat startup
+- Token sinkronisasi: `src/lib/db/syncTokens.ts` — token bercakupan untuk endpoint unduhan bundel konfigurasi; didukung oleh tabel SQLite `sync_tokens` (migrasi `024_create_sync_tokens.sql`)
+- Auth handshake WebSocket: `src/lib/ws/handshake.ts` — memvalidasi permintaan upgrade WS melalui API key atau cookie sesi
-## 5) Cloud Sync
+## 5) Sinkronisasi Cloud
-- Scheduler init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`, `src/shared/services/modelSyncScheduler.ts`
-- Periodic task: `src/shared/services/cloudSyncScheduler.ts`
-- Periodic task: `src/shared/services/modelSyncScheduler.ts`
-- Control route: `src/app/api/sync/cloud/route.ts`
+- Inisialisasi penjadwal: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`, `src/shared/services/modelSyncScheduler.ts`
+- Tugas berkala: `src/shared/services/cloudSyncScheduler.ts`
+- Tugas berkala: `src/shared/services/modelSyncScheduler.ts`
+- Route kontrol: `src/app/api/sync/cloud/route.ts`
-## Request Lifecycle (`/v1/chat/completions`)
+## Siklus Hidup Permintaan (`/v1/chat/completions`)
```mermaid
sequenceDiagram
autonumber
- participant Client as CLI/SDK Client
+ participant Client as Klien CLI/SDK
participant Route as /api/v1/chat/completions
participant Chat as src/sse/handlers/chat
participant Core as open-sse/handlers/chatCore
- participant Model as Model Resolver
- participant Auth as Credential Selector
- participant Exec as Provider Executor
- participant Prov as Upstream Provider
- participant Stream as Stream Translator
+ participant Model as Resolver Model
+ participant Auth as Pemilih Kredensial
+ participant Exec as Executor Penyedia
+ participant Prov as Penyedia Upstream
+ participant Stream as Penerjemah Stream
participant Usage as usageDb
Client->>Route: POST /v1/chat/completions
Route->>Chat: handleChat(request)
- Chat->>Model: parse/resolve model or combo
+ Chat->>Model: urai/resolusi model atau combo
- alt Combo model
- Chat->>Chat: iterate combo models (handleComboChat)
+ alt Model combo
+ Chat->>Chat: iterasi model combo (handleComboChat)
end
Chat->>Auth: getProviderCredentials(provider)
- Auth-->>Chat: active account + tokens/api key
+ Auth-->>Chat: akun aktif + token/api key
Chat->>Core: handleChatCore(body, modelInfo, credentials)
- Core->>Core: detect source format
- Core->>Core: translate request to target format
+ Core->>Core: deteksi format sumber
+ Core->>Core: terjemahkan permintaan ke format target
Core->>Exec: execute(provider, transformedBody)
- Exec->>Prov: upstream API call
- Prov-->>Exec: SSE/JSON response
- Exec-->>Core: response + metadata
+ Exec->>Prov: panggilan API upstream
+ Prov-->>Exec: respons SSE/JSON
+ Exec-->>Core: respons + metadata
alt 401/403
Core->>Exec: refreshCredentials()
- Exec-->>Core: updated tokens
- Core->>Exec: retry request
+ Exec-->>Core: token yang diperbarui
+ Core->>Exec: coba ulang permintaan
end
- Core->>Stream: translate/normalize stream to client format
- Stream-->>Client: SSE chunks / JSON response
+ Core->>Stream: terjemahkan/normalisasi stream ke format klien
+ Stream-->>Client: potongan SSE / respons JSON
- Stream->>Usage: extract usage + persist history/log
+ Stream->>Usage: ekstrak penggunaan + simpan riwayat/log
```
-## Combo + Account Fallback Flow
+## Aliran Fallback Combo + Akun
```mermaid
flowchart TD
- A[Incoming model string] --> B{Is combo name?}
- B -- Yes --> C[Load combo models sequence]
- B -- No --> D[Single model path]
+ A[String model masuk] --> B{Apakah nama combo?}
+ B -- Ya --> C[Muat urutan model combo]
+ B -- Tidak --> D[Jalur model tunggal]
- C --> E[Try model N]
- E --> F[Resolve provider/model]
+ C --> E[Coba model N]
+ E --> F[Resolusi penyedia/model]
D --> F
- F --> G[Select account credentials]
- G --> H{Credentials available?}
- H -- No --> I[Return provider unavailable]
- H -- Yes --> J[Execute request]
+ F --> G[Pilih kredensial akun]
+ G --> H{Kredensial tersedia?}
+ H -- Tidak --> I[Kembalikan penyedia tidak tersedia]
+ H -- Ya --> J[Eksekusi permintaan]
- J --> K{Success?}
- K -- Yes --> L[Return response]
- K -- No --> M{Fallback-eligible error?}
+ J --> K{Berhasil?}
+ K -- Ya --> L[Kembalikan respons]
+ K -- Tidak --> M{Kesalahan layak fallback?}
- M -- No --> N[Return error]
- M -- Yes --> O[Mark account unavailable cooldown]
- O --> P{Another account for provider?}
- P -- Yes --> G
- P -- No --> Q{In combo with next model?}
- Q -- Yes --> E
- Q -- No --> R[Return all unavailable]
+ M -- Tidak --> N[Kembalikan kesalahan]
+ M -- Ya --> O[Tandai akun cooldown tidak tersedia]
+ O --> P{Ada akun lain untuk penyedia?}
+ P -- Ya --> G
+ P -- Tidak --> Q{Dalam combo dengan model berikutnya?}
+ Q -- Ya --> E
+ Q -- Tidak --> R[Kembalikan semua tidak tersedia]
```
-Fallback decisions are driven by `open-sse/services/accountFallback.ts` using status codes and error-message heuristics. Combo routing adds one extra guard: provider-scoped 400s such as upstream content-block and role-validation failures are treated as model-local failures so later combo targets can still run.
+Keputusan fallback dikendalikan oleh `open-sse/services/accountFallback.ts` menggunakan kode status dan heuristik pesan kesalahan. Routing combo menambahkan satu penjaga ekstra: 400 yang bercakupan penyedia seperti kegagalan blokir konten upstream dan validasi peran diperlakukan sebagai kegagalan lokal model sehingga target combo berikutnya masih bisa berjalan.
-## OAuth Onboarding and Token Refresh Lifecycle
+## Siklus Hidup Orientasi OAuth dan Pembaruan Token
```mermaid
sequenceDiagram
autonumber
- participant UI as Dashboard UI
+ participant UI as UI Dasbor
participant OAuth as /api/oauth/[provider]/[action]
- participant ProvAuth as Provider Auth Server
+ participant ProvAuth as Server Auth Penyedia
participant DB as localDb
participant Test as /api/providers/[id]/test
- participant Exec as Provider Executor
+ participant Exec as Executor Penyedia
- UI->>OAuth: GET authorize or device-code
- OAuth->>ProvAuth: create auth/device flow
- ProvAuth-->>OAuth: auth URL or device code payload
- OAuth-->>UI: flow data
+ UI->>OAuth: GET authorize atau device-code
+ OAuth->>ProvAuth: buat aliran auth/device
+ ProvAuth-->>OAuth: URL auth atau payload kode device
+ OAuth-->>UI: data aliran
- UI->>OAuth: POST exchange or poll
- OAuth->>ProvAuth: token exchange/poll
- ProvAuth-->>OAuth: access/refresh tokens
+ UI->>OAuth: POST exchange atau poll
+ OAuth->>ProvAuth: penukaran/polling token
+ ProvAuth-->>OAuth: token akses/penyegaran
OAuth->>DB: createProviderConnection(oauth data)
- OAuth-->>UI: success + connection id
+ OAuth-->>UI: berhasil + id koneksi
UI->>Test: POST /api/providers/[id]/test
- Test->>Exec: validate credentials / optional refresh
- Exec-->>Test: valid or refreshed token info
- Test->>DB: update status/tokens/errors
- Test-->>UI: validation result
+ Test->>Exec: validasi kredensial / penyegaran opsional
+ Exec-->>Test: info token valid atau yang diperbarui
+ Test->>DB: perbarui status/token/kesalahan
+ Test-->>UI: hasil validasi
```
-Refresh during live traffic is executed inside `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`.
+Pembaruan selama lalu lintas langsung dieksekusi di dalam `open-sse/handlers/chatCore.ts` melalui executor `refreshCredentials()`.
-## Cloud Sync Lifecycle (Enable / Sync / Disable)
+## Siklus Hidup Sinkronisasi Cloud (Aktifkan / Sinkronkan / Nonaktifkan)
```mermaid
sequenceDiagram
@@ -468,14 +468,14 @@ sequenceDiagram
Sync-->>UI: disabled
```
-Periodic sync is triggered by `CloudSyncScheduler` when cloud is enabled.
+Sinkronisasi berkala dipicu oleh `CloudSyncScheduler` saat cloud diaktifkan.
-## Data Model and Storage Map
+## Model Data dan Peta Penyimpanan
```mermaid
erDiagram
- SETTINGS ||--o{ PROVIDER_CONNECTION : controls
- PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_provider
+ SETTINGS ||--o{ PROVIDER_CONNECTION : kontrol
+ PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : penyedia_kompatibel_belakang
PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage
SETTINGS {
@@ -573,12 +573,12 @@ erDiagram
Physical storage files:
-- primary runtime DB: `${DATA_DIR}/storage.sqlite`
-- request log lines: `${DATA_DIR}/log.txt` (compat/debug artifact)
-- structured call payload archives: `${DATA_DIR}/call_logs/`
-- optional translator/request debug sessions: `/logs/...`
+- DB waktu proses utama: `${DATA_DIR}/storage.sqlite`
+- baris log permintaan: `${DATA_DIR}/log.txt` (artefak compat/debug)
+- arsip muatan panggilan terstruktur: `${DATA_DIR}/call_logs/`
+- sesi debug penerjemah/permintaan opsional: `/logs/...`
-## Deployment Topology
+## Topologi Deployment
```mermaid
flowchart LR
@@ -609,86 +609,86 @@ flowchart LR
Next --> SyncCloud
```
-## Module Mapping (Decision-Critical)
+## Pemetaan Modul (Kritis Keputusan)
-### Route and API Modules
+### Rute dan Modul API
-- `src/app/api/v1/*`, `src/app/api/v1beta/*`: compatibility APIs
-- `src/app/api/v1/providers/[provider]/*`: dedicated per-provider routes (chat, embeddings, images)
-- `src/app/api/providers*`: provider CRUD, validation, testing
-- `src/app/api/provider-nodes*`: custom compatible node management
-- `src/app/api/provider-models`: custom model management (CRUD)
-- `src/app/api/models/route.ts`: model catalog API (aliases + custom models)
-- `src/app/api/oauth/*`: OAuth/device-code flows
-- `src/app/api/keys*`: local API key lifecycle
-- `src/app/api/models/alias`: alias management
-- `src/app/api/combos*`: fallback combo management
-- `src/app/api/pricing`: pricing overrides for cost calculation
-- `src/app/api/settings/proxy`: proxy configuration (GET/PUT/DELETE)
-- `src/app/api/settings/proxy/test`: outbound proxy connectivity test (POST)
-- `src/app/api/usage/*`: usage and logs APIs
-- `src/app/api/sync/*` + `src/app/api/cloud/*`: cloud sync and cloud-facing helpers
-- `src/app/api/cli-tools/*`: local CLI config writers/checkers
-- `src/app/api/settings/ip-filter`: IP allowlist/blocklist (GET/PUT)
-- `src/app/api/settings/thinking-budget`: thinking token budget config (GET/PUT)
-- `src/app/api/settings/system-prompt`: global system prompt (GET/PUT)
-- `src/app/api/sessions`: active session listing (GET)
-- `src/app/api/rate-limits`: per-account rate limit status (GET)
-- `src/app/api/sync/tokens`: sync token CRUD (GET/POST)
-- `src/app/api/sync/tokens/[id]`: sync token get/delete (GET/DELETE)
-- `src/app/api/sync/bundle`: config bundle download (GET, ETag versioning)
-- `src/app/api/v1/ws`: WebSocket upgrade handler for OpenAI-compatible WS clients
+- `src/app/api/v1/*`, `src/app/api/v1beta/*`: API kompatibilitas
+- `src/app/api/v1/providers/[provider]/*`: rute khusus per penyedia (obrolan, penyematan, gambar)
+- `src/app/api/providers*` : penyedia CRUD, validasi, pengujian
+- `src/app/api/provider-nodes*`: manajemen node khusus yang kompatibel
+- `src/app/api/provider-models`: manajemen model khusus (CRUD)
+- `src/app/api/models/route.ts`: API katalog model (alias + model khusus)
+- `src/app/api/oauth/*`: OAuth/kode perangkat mengalir
+- `src/app/api/keys*`: siklus hidup kunci API lokal
+- `src/app/api/models/alias`: manajemen alias
+- `src/app/api/combos*`: manajemen kombo cadangan
+- `src/app/api/pricing`: penggantian harga untuk penghitungan biaya
+- `src/app/api/settings/proxy`: konfigurasi proksi (GET/PUT/DELETE)
+- `src/app/api/settings/proxy/test`: uji konektivitas proxy keluar (POST)
+- `src/app/api/usage/*`: API penggunaan dan log
+- `src/app/api/sync/*` + `src/app/api/cloud/*`: sinkronisasi cloud dan bantuan yang menghadap cloud
+- `src/app/api/cli-tools/*`: penulis/pemeriksa konfigurasi CLI lokal
+- `src/app/api/settings/ip-filter`: Daftar IP yang diizinkan/daftar blokir (GET/PUT)
+- `src/app/api/settings/thinking-budget`: konfigurasi anggaran token pemikiran (GET/PUT)
+- `src/app/api/settings/system-prompt`: perintah sistem global (GET/PUT)
+- `src/app/api/sessions`: daftar sesi aktif (GET)
+- `src/app/api/rate-limits`: status batas tarif per akun (GET)
+- `src/app/api/sync/tokens`: token sinkronisasi CRUD (GET/POST)
+- `src/app/api/sync/tokens/[id]`: dapatkan/hapus token sinkronisasi (GET/DELETE)
+- `src/app/api/sync/bundle`: pengunduhan bundel konfigurasi (GET, versi ETag)
+- `src/app/api/v1/ws`: Pengendali pemutakhiran WebSocket untuk klien WS yang kompatibel dengan OpenAI
-### Routing and Execution Core
+### Perutean dan Inti Eksekusi
-- `src/sse/handlers/chat.ts`: request parse, combo handling, account selection loop
-- `open-sse/handlers/chatCore.ts`: translation, executor dispatch, retry/refresh handling, stream setup
-- `open-sse/executors/*`: provider-specific network and format behavior
+- `src/sse/handlers/chat.ts`: penguraian permintaan, penanganan kombo, putaran pemilihan akun
+- `open-sse/handlers/chatCore.ts`: terjemahan, pengiriman eksekutor, penanganan coba lagi/segarkan, pengaturan streaming
+- `open-sse/executors/*`: perilaku jaringan dan format khusus penyedia
-### Translation Registry and Format Converters
+### Registri Terjemahan dan Pengonversi Format
-- `open-sse/translator/index.ts`: translator registry and orchestration
-- Request translators: `open-sse/translator/request/*`
-- Response translators: `open-sse/translator/response/*`
-- Format constants: `open-sse/translator/formats.ts`
+- `open-sse/translator/index.ts`: registrasi dan orkestrasi penerjemah
+- Permintaan penerjemah: `open-sse/translator/request/*`
+- Penerjemah tanggapan: `open-sse/translator/response/*`
+- Konstanta format: `open-sse/translator/formats.ts`
-### Persistence
+### Persistensi
-- `src/lib/db/*`: persistent config/state and domain persistence on SQLite
-- `src/lib/localDb.ts`: compatibility re-export for DB modules
-- `src/lib/usageDb.ts`: usage history/call logs facade on top of SQLite tables
+- `src/lib/db/*`: konfigurasi/status persisten dan persistensi domain di SQLite
+- `src/lib/localDb.ts`: ekspor ulang kompatibilitas untuk modul DB
+- `src/lib/usageDb.ts`: riwayat penggunaan/log panggilan fasad di atas tabel SQLite
-## Provider Executor Coverage (Strategy Pattern)
+## Cakupan Pelaksana Penyedia (Pola Strategi)
-Each provider has a specialized executor extending `BaseExecutor` (in `open-sse/executors/base.ts`), which provides URL building, header construction, retry with exponential backoff, credential refresh hooks, and the `execute()` orchestration method.
+Setiap penyedia memiliki pelaksana khusus yang memperluas `BaseExecutor` (dalam `open-sse/executors/base.ts`), yang menyediakan pembuatan URL, konstruksi header, percobaan ulang dengan backoff eksponensial, kait penyegaran kredensial, dan metode orkestrasi `execute()`.
| Executor | Provider(s) | Special Handling |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
-| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA, etc. | Dynamic URL/header config per provider |
+| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA, etc. | Konfigurasi URL/tajuk dinamis per penyedia |
| `AntigravityExecutor` | Google Antigravity | Custom project/session IDs, Retry-After parsing |
-| `CliProxyApiExecutor` | CLIProxyAPI-compatible providers | Custom auth and protocol handling |
-| `CloudflareAiExecutor` | Cloudflare Workers AI | Account ID injection, Neurons-based usage tracking |
+| `CliProxyApiExecutor` | Penyedia yang kompatibel dengan CLIProxyAPI | Penanganan autentikasi dan protokol khusus |
+| `CloudflareAiExecutor` | Cloudflare Workers AI | Injeksi ID Akun, pelacakan penggunaan berbasis Neuron |
| `CodexExecutor` | OpenAI Codex | Injects system instructions, forces reasoning effort |
-| `CursorExecutor` | Cursor IDE | ConnectRPC protocol, Protobuf encoding, request signing via checksum |
+| `CursorExecutor` | Cursor IDE | Protokol ConnectRPC, pengkodean Protobuf, penandatanganan permintaan melalui checksum |
| `GithubExecutor` | GitHub Copilot | Copilot token refresh, VSCode-mimicking headers |
| `GeminiCLIExecutor` | Gemini CLI | Google OAuth token refresh cycle |
-| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binary format → SSE conversion |
-| `OpenCodeExecutor` | OpenCode | AI SDK compatible provider setup |
-| `PollinationsExecutor` | Pollinations AI | No API key required, rate-limited requests |
-| `PuterExecutor` | Puter | Browser-based provider integration |
-| `QoderExecutor` | Qoder AI | PAT and OAuth support, multi-model free tier |
-| `VertexExecutor` | Google Vertex AI | Service account auth, region-based endpoints |
+| `KiroExecutor` | AWS CodeWhisperer/Kiro | Format biner AWS EventStream → konversi SSE |
+| `OpenCodeExecutor` | OpenCode | Penyiapan penyedia yang kompatibel dengan AI SDK |
+| `PollinationsExecutor` | Pollinations AI | Tidak diperlukan kunci API, permintaan dengan tarif terbatas |
+| `PuterExecutor` | Puter | Integrasi penyedia berbasis browser |
+| `QoderExecutor` | Qoder AI | Dukungan PAT dan OAuth, tingkat gratis multi-model |
+| `VertexExecutor` | Google Vertex AI | Otentikasi akun layanan, titik akhir berbasis wilayah |
-All other providers (including custom compatible nodes) use the `DefaultExecutor`.
+Semua penyedia lain (termasuk node khusus yang kompatibel) menggunakan `DefaultExecutor`.
-## Provider Compatibility Matrix
+## Matriks Kompatibilitas Penyedia
| Provider | Format | Auth | Stream | Non-Stream | Token Refresh | Usage API |
| ---------------- | ---------------- | --------------------- | ---------------- | ---------- | ------------- | ------------------ |
-| Claude | claude | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Admin only |
-| Gemini | gemini | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
+| Claude | claude | Kunci API / OAuth | ✅ | ✅ | ✅ | ⚠️ Admin only |
+| Gemini | gemini | Kunci API / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
-| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ Full quota API |
+| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ API kuota penuh |
| OpenAI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Codex | openai-responses | OAuth | ✅ forced | ❌ | ✅ | ✅ Rate limits |
| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Quota snapshots |
@@ -712,10 +712,10 @@ All other providers (including custom compatible nodes) use the `DefaultExecutor
| Cohere | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| NVIDIA NIM | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Cloudflare AI | openai | API Token + Acct ID | ✅ | ✅ | ❌ | ❌ |
-| Pollinations | openai | None (no key) | ✅ | ✅ | ❌ | ❌ |
+| Pollinations | openai | Tidak ada (tidak ada kunci) | ✅ | ✅ | ❌ | ❌ |
| Scaleway AI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| LongCat | openai | API Key | ✅ | ✅ | ❌ | ❌ |
-| Ollama Cloud | openai | API Key (optional) | ✅ | ✅ | ❌ | ❌ |
+| Ollama Cloud | openai | Kunci API (opsional)| ✅ | ✅ | ❌ | ❌ |
| HuggingFace | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Nebius | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| SiliconFlow | openai | API Key | ✅ | ✅ | ❌ | ❌ |
@@ -723,16 +723,16 @@ All other providers (including custom compatible nodes) use the `DefaultExecutor
| Vertex AI | gemini | Service Account | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
| Puter | openai | API Key | ✅ | ✅ | ❌ | ❌ |
-## Format Translation Coverage
+## Format Cakupan Terjemahan
-Detected source formats include:
+Format sumber yang terdeteksi meliputi:
- `openai`
- `openai-responses`
- `claude`
- `gemini`
-Target formats include:
+Format sasarannya meliputi:
- OpenAI chat/Responses
- Claude
@@ -740,22 +740,22 @@ Target formats include:
- Kiro
- Cursor
-Translations use **OpenAI as the hub format** — all conversions go through OpenAI as intermediate:
+Penerjemahan menggunakan **OpenAI sebagai format hub** — semua konversi melalui OpenAI sebagai perantara:
```
Source Format → OpenAI (hub) → Target Format
```
-Translations are selected dynamically based on source payload shape and provider target format.
+Terjemahan dipilih secara dinamis berdasarkan bentuk muatan sumber dan format target penyedia.
-Additional processing layers in the translation pipeline:
+Lapisan pemrosesan tambahan dalam alur terjemahan:
-- **Response sanitization** — Strips non-standard fields from OpenAI-format responses (both streaming and non-streaming) to ensure strict SDK compliance
-- **Role normalization** — Converts `developer` → `system` for non-OpenAI targets; merges `system` → `user` for models that reject the system role (GLM, ERNIE)
-- **Think tag extraction** — Parses `...` blocks from content into `reasoning_content` field
-- **Structured output** — Converts OpenAI `response_format.json_schema` to Gemini's `responseMimeType` + `responseSchema`
+- **Sanitasi respons** — Menghapus kolom non-standar dari respons format OpenAI (streaming dan non-streaming) untuk memastikan kepatuhan SDK yang ketat
+- **Normalisasi peran** — Mengonversi `developer` → `system` untuk target non-OpenAI; menggabungkan `system` → `user` untuk model yang menolak peran sistem (GLM, ERNIE)
+- **Pikirkan ekstraksi tag** — Mengurai `...` blok dari konten ke dalam bidang `reasoning_content`
+- **Output terstruktur** — Mengonversi OpenAI `response_format.json_schema` menjadi `responseMimeType` + `responseSchema` Gemini
-## Supported API Endpoints
+## Titik Akhir API yang Didukung
| Endpoint | Format | Handler |
| -------------------------------------------------- | ------------------ | ------------------------------------------------------------------- |
@@ -766,126 +766,126 @@ Additional processing layers in the translation pipeline:
| `GET /v1/embeddings` | Model listing | API route |
| `POST /v1/images/generations` | OpenAI Images | `open-sse/handlers/imageGeneration.ts` |
| `GET /v1/images/generations` | Model listing | API route |
-| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Dedicated per-provider with model validation |
-| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Dedicated per-provider with model validation |
-| `POST /v1/providers/{provider}/images/generations` | OpenAI Images | Dedicated per-provider with model validation |
+| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Per penyedia khusus dengan validasi model |
+| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Per penyedia khusus dengan validasi model |
+| `POST /v1/providers/{provider}/images/generations` | OpenAI Images | Per penyedia khusus dengan validasi model |
| `POST /v1/messages/count_tokens` | Claude Token Count | API route |
-| `GET /v1/models` | OpenAI Models list | API route (chat + embedding + image + custom models) |
-| `GET /api/models/catalog` | Catalog | All models grouped by provider + type |
+| `GET /v1/models` | Daftar Model OpenAI | Rute API (obrolan + penyematan + gambar + model khusus) |
+| `GET /api/models/catalog` | Catalog | Semua model dikelompokkan berdasarkan penyedia + jenis |
| `POST /v1beta/models/*:streamGenerateContent` | Gemini native | API route |
-| `GET/PUT/DELETE /api/settings/proxy` | Proxy Config | Network proxy configuration |
-| `POST /api/settings/proxy/test` | Proxy Connectivity | Proxy health/connectivity test endpoint |
-| `GET/POST/DELETE /api/provider-models` | Provider Models | Provider model metadata backing custom and managed available models |
+| `GET/PUT/DELETE /api/settings/proxy` | Proxy Config | Konfigurasi proksi jaringan |
+| `POST /api/settings/proxy/test` | Proxy Connectivity | Titik akhir pengujian kesehatan/konektivitas proxy |
+| `GET/POST/DELETE /api/provider-models` | Provider Models | Metadata model penyedia mendukung model kustom dan terkelola yang tersedia |
-## Bypass Handler
+## Handler Bypass
-The bypass handler (`open-sse/utils/bypassHandler.ts`) intercepts known "throwaway" requests from Claude CLI — warmup pings, title extractions, and token counts — and returns a **fake response** without consuming upstream provider tokens. This is triggered only when `User-Agent` contains `claude-cli`.
+Penangan bypass (`open-sse/utils/bypassHandler.ts`) mencegat permintaan "sekali pakai" yang diketahui dari Claude CLI — ping pemanasan, ekstraksi judul, dan jumlah token — dan mengembalikan **respons palsu** tanpa menggunakan token penyedia upstream. Ini dipicu hanya ketika `User-Agent` berisi `claude-cli`.
-## Request Logging and Artifacts
+## Minta Pencatatan dan Artefak
-The older file-based request logger (`open-sse/utils/requestLogger.ts`) is retained only for
-legacy compatibility. The current runtime contract uses:
+Pencatat permintaan berbasis file yang lebih lama (`open-sse/utils/requestLogger.ts`) dipertahankan hanya untuk
+kompatibilitas warisan. Kontrak runtime saat ini menggunakan:
-- `APP_LOG_TO_FILE=true` for application and audit logs written under `/logs/`
-- SQLite-backed call log records in `call_logs`
-- `${DATA_DIR}/call_logs/YYYY-MM-DD/...` artifacts when the call log pipeline is enabled
+- `APP_LOG_TO_FILE=true` untuk log aplikasi dan audit yang ditulis di bawah `/logs/`
+- Catatan log panggilan yang didukung SQLite di `call_logs`
+- `${DATA_DIR}/call_logs/YYYY-MM-DD/...` artefak saat pipa log panggilan diaktifkan
-## Failure Modes and Resilience
+## Mode Kegagalan dan Ketahanan
-## 1) Account/Provider Availability
+## 1) Ketersediaan Akun/Penyedia
-- connection cooldown on retryable upstream failures
-- account fallback before failing request
-- combo model fallback when current model/provider path is exhausted
+- cooldown koneksi pada kegagalan upstream yang dapat dicoba lagi
+- penggantian akun sebelum permintaan gagal
+- penggantian model kombo ketika jalur model/penyedia saat ini habis
-## 2) Token Expiry
+## 2) Kedaluwarsa Token
-- pre-check and refresh with retry for refreshable providers
-- 401/403 retry after refresh attempt in core path
+- pra-periksa dan segarkan dengan coba lagi untuk penyedia yang dapat disegarkan
+- 401/403 percobaan ulang setelah upaya penyegaran di jalur inti
-## 3) Stream Safety
+## 3) Keamanan Stream
-- disconnect-aware stream controller
-- translation stream with end-of-stream flush and `[DONE]` handling
-- usage estimation fallback when provider usage metadata is missing
+- pengontrol aliran yang sadar akan pemutusan hubungan
+- aliran terjemahan dengan flush akhir aliran dan penanganan `[DONE]`
+- penggantian estimasi penggunaan ketika metadata penggunaan penyedia tidak ada
-## 4) Cloud Sync Degradation
+## 4) Degradasi Sinkronisasi Cloud
-- sync errors are surfaced but local runtime continues
-- scheduler has retry-capable logic, but periodic execution currently calls single-attempt sync by default
+- kesalahan sinkronisasi muncul tetapi runtime lokal terus berlanjut
+- penjadwal memiliki logika yang mampu mencoba ulang, namun eksekusi berkala saat ini memanggil sinkronisasi upaya tunggal secara default
-## 5) Data Integrity
+## 5) Integritas Data
- SQLite schema migrations and auto-upgrade hooks at startup
- legacy JSON → SQLite migration compatibility path
-## 6) SSRF / Outbound URL Guard
+## 6) SSRF / Penjaga URL Outbound
-- `src/shared/network/outboundUrlGuard.ts` blocks all private/loopback/link-local target URLs before they reach provider executors
-- Provider model discovery and validation routes use `src/shared/network/safeOutboundFetch.ts` which applies the guard before every outbound request
-- Guard errors surface as `URL_GUARD_BLOCKED` with HTTP 422 and are logged to the compliance audit trail via `providerAudit.ts`
+- `src/shared/network/outboundUrlGuard.ts` memblokir semua URL target pribadi/loopback/link-lokal sebelum mencapai pelaksana penyedia
+- Rute penemuan dan validasi model penyedia menggunakan `src/shared/network/safeOutboundFetch.ts` yang menerapkan penjagaan sebelum setiap permintaan keluar
+- Kesalahan penjaga muncul sebagai `URL_GUARD_BLOCKED` dengan HTTP 422 dan dicatat ke jejak audit kepatuhan melalui `providerAudit.ts`
-## Observability and Operational Signals
+## Observabilitas dan Sinyal Operasional
-Runtime visibility sources:
+Sumber visibilitas waktu proses:
-- console logs from `src/sse/utils/logger.ts`
-- per-request usage aggregates in SQLite (`usage_history`, `call_logs`, `proxy_logs`)
-- four-stage detailed payload captures in SQLite (`request_detail_logs`) when `settings.detailed_logs_enabled=true`
-- textual request status log in `log.txt` (optional/compat)
-- optional application log files under `logs/` when `APP_LOG_TO_FILE=true`
-- optional request artifacts under `${DATA_DIR}/call_logs/` when the call log pipeline is enabled
-- dashboard usage endpoints (`/api/usage/*`) for UI consumption
+- log konsol dari `src/sse/utils/logger.ts`
+- agregat penggunaan per permintaan di SQLite (`usage_history`, `call_logs`, `proxy_logs`)
+- pengambilan muatan terperinci empat tahap dalam SQLite (`request_detail_logs`) ketika `settings.detailed_logs_enabled=true`
+- status permintaan tekstual masuk `log.txt` (opsional/sesuai)
+- file log aplikasi opsional di bawah `logs/` ketika `APP_LOG_TO_FILE=true`
+- artefak permintaan opsional di bawah `${DATA_DIR}/call_logs/` ketika saluran log panggilan diaktifkan
+- titik akhir penggunaan dasbor (`/api/usage/*`) untuk konsumsi UI
Detailed request payload capture stores up to four JSON payload stages per routed call:
-- raw request received from the client
-- translated request actually sent upstream
-- provider response reconstructed as JSON; streamed responses are compacted to the final summary plus stream metadata
-- final client response returned by OmniRoute; streamed responses are stored in the same compact summary form
+- permintaan mentah diterima dari klien
+- permintaan yang diterjemahkan sebenarnya dikirim ke hulu
+- respons penyedia direkonstruksi sebagai JSON; tanggapan yang dialirkan dipadatkan ke ringkasan akhir ditambah metadata aliran
+- respons klien akhir yang dikembalikan oleh OmniRoute; tanggapan yang dialirkan disimpan dalam bentuk ringkasan ringkas yang sama
-## Security-Sensitive Boundaries
+## Batasan yang Sensitif terhadap Keamanan
-- JWT secret (`JWT_SECRET`) secures dashboard session cookie verification/signing
-- Initial password bootstrap (`INITIAL_PASSWORD`) should be explicitly configured for first-run provisioning
-- API key HMAC secret (`API_KEY_SECRET`) secures generated local API key format
-- Provider secrets (API keys/tokens) are persisted in local DB and should be protected at filesystem level
-- Cloud sync endpoints rely on API key auth + machine id semantics
+- Rahasia JWT (`JWT_SECRET`) mengamankan verifikasi/penandatanganan cookie sesi dasbor
+- Bootstrap kata sandi awal (`INITIAL_PASSWORD`) harus dikonfigurasi secara eksplisit untuk provisi yang dijalankan pertama kali
+- Rahasia HMAC kunci API (`API_KEY_SECRET`) mengamankan format kunci API lokal yang dihasilkan
+- Rahasia penyedia (kunci/token API) disimpan di DB lokal dan harus dilindungi di tingkat sistem file
+- Titik akhir sinkronisasi cloud mengandalkan autentikasi kunci API + semantik id mesin
-## Environment and Runtime Matrix
+## Matriks Lingkungan dan Runtime
-Environment variables actively used by code:
+Variabel lingkungan yang aktif digunakan oleh kode:
-- App/auth: `JWT_SECRET`, `INITIAL_PASSWORD`
-- Storage: `DATA_DIR`
-- Compatible node behavior: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
-- Optional storage base override (Linux/macOS when `DATA_DIR` unset): `XDG_CONFIG_HOME`
-- Security hashing: `API_KEY_SECRET`, `MACHINE_ID_SALT`
-- Logging: `APP_LOG_TO_FILE`, `APP_LOG_RETENTION_DAYS`, `CALL_LOG_RETENTION_DAYS`
-- Sync/cloud URLing: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL`
-- Outbound proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` and lowercase variants
-- SOCKS5 feature flags: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
-- Platform/runtime helpers (not app-specific config): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME`
+- Aplikasi/autentikasi: `JWT_SECRET`, `INITIAL_PASSWORD`
+- Penyimpanan: `DATA_DIR`
+- Perilaku node yang kompatibel: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
+- Penggantian basis penyimpanan opsional (Linux/macOS ketika `DATA_DIR` tidak disetel): `XDG_CONFIG_HOME`
+- Pencirian keamanan: `API_KEY_SECRET`, `MACHINE_ID_SALT`
+- Pencatatan: `APP_LOG_TO_FILE`, `APP_LOG_RETENTION_DAYS`, `CALL_LOG_RETENTION_DAYS`
+- URL sinkronisasi/cloud: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL`
+- Proksi keluar: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` dan varian huruf kecil
+- Bendera fitur SOCKS5: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
+- Pembantu platform/runtime (bukan konfigurasi khusus aplikasi): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME`
-## Known Architectural Notes
+## Catatan Arsitektur yang Diketahui
-1. `usageDb` and `localDb` share the same base directory policy (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) with legacy file migration.
-2. `/api/v1/route.ts` delegates to the same unified catalog builder used by `/api/v1/models` (`src/app/api/v1/models/catalog.ts`) to avoid semantic drift.
-3. Request logger writes full headers/body when enabled; treat log directory as sensitive.
-4. Cloud behavior depends on correct `NEXT_PUBLIC_BASE_URL` and cloud endpoint reachability.
-5. The `open-sse/` directory is published as the `@omniroute/open-sse` **npm workspace package**. Source code imports it via `@omniroute/open-sse/...` (resolved by Next.js `transpilePackages`). File paths in this document still use the directory name `open-sse/` for consistency.
-6. Charts in the dashboard use **Recharts** (SVG-based) for accessible, interactive analytics visualizations (model usage bar charts, provider breakdown tables with success rates).
-7. E2E tests use **Playwright** (`tests/e2e/`), run via `npm run test:e2e`. Unit tests use **Node.js test runner** (`tests/unit/`), run via `npm run test:unit`. Source code under `src/` is **TypeScript** (`.ts`/`.tsx`); the `open-sse/` workspace remains JavaScript (`.js`).
-8. Settings page is organized into 7 tabs: General, Appearance, AI, Security, Routing, Resilience, Advanced. The Resilience page only configures request queue, connection cooldown, provider breaker, and wait-for-cooldown behavior; live breaker runtime state is shown on the Health page.
-9. **Context Relay** strategy (`context-relay`) is split across two layers: `combo.ts` decides if a handoff should be generated, `chat.ts` injects the handoff after account resolution. Handoff data lives in `context_handoffs` SQLite table. This split is intentional because only `chat.ts` knows whether the actual account changed.
-10. **Proxy enforcement** is now comprehensive: `tokenHealthCheck.ts` resolves proxy per connection, `/api/providers/validate` uses `runWithProxyContext`, and `proxyFetch.ts` uses `undici.fetch()` to maintain dispatcher compatibility on Node 22.
-11. **Node.js runtime policy detection**: `/api/settings/require-login` returns `nodeVersion` and `nodeCompatible` fields. The login page renders a warning banner when the runtime falls outside the supported secure Node.js lines.
+1. `usageDb` dan `localDb` berbagi kebijakan direktori dasar yang sama (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) dengan migrasi file lama.
+2. `/api/v1/route.ts` mendelegasikan ke pembuat katalog terpadu yang sama yang digunakan oleh `/api/v1/models` (`src/app/api/v1/models/catalog.ts`) untuk menghindari penyimpangan semantik.
+3. Pencatat permintaan menulis header/isi lengkap saat diaktifkan; memperlakukan direktori log sebagai sensitif.
+4. Perilaku cloud bergantung pada `NEXT_PUBLIC_BASE_URL` yang benar dan jangkauan titik akhir cloud.
+5. Direktori `open-sse/` diterbitkan sebagai `@omniroute/open-sse` **paket ruang kerja npm**. Kode sumber mengimpornya melalui `@omniroute/open-sse/...` (diselesaikan oleh Next.js `transpilePackages`). Jalur file dalam dokumen ini masih menggunakan nama direktori `open-sse/` untuk konsistensi.
+6. Bagan di dasbor menggunakan **Recharts** (berbasis SVG) untuk visualisasi analitik interaktif yang mudah diakses (diagram batang penggunaan model, tabel perincian penyedia dengan tingkat keberhasilan).
+7. Tes E2E menggunakan **Playwright** (`tests/e2e/`), dijalankan melalui `npm run test:e2e`. Pengujian unit menggunakan **Node.js test runner** (`tests/unit/`), dijalankan melalui `npm run test:unit`. Kode sumber di bawah `src/` adalah **TypeScript** (`.ts`/`.tsx`); ruang kerja `open-sse/` tetap JavaScript (`.js`).
+8. Halaman pengaturan disusun dalam 7 tab: Umum, Tampilan, AI, Keamanan, Perutean, Ketahanan, Lanjutan. Halaman Ketahanan hanya mengonfigurasi antrean permintaan, waktu tunggu koneksi, pemutus penyedia, dan perilaku menunggu waktu tunggu; status runtime pemutus langsung ditampilkan di halaman Kesehatan.
+9. Strategi **Relai Konteks** (`context-relay`) dibagi menjadi dua lapisan: `combo.ts` memutuskan apakah handoff harus dibuat, `chat.ts` memasukkan handoff setelah resolusi akun. Data handoff ada di tabel SQLite `context_handoffs`. Pemisahan ini disengaja karena hanya `chat.ts` yang mengetahui apakah akun sebenarnya berubah.
+10. **Penerapan proxy** kini komprehensif: `tokenHealthCheck.ts` menyelesaikan proxy per koneksi, `/api/providers/validate` menggunakan `runWithProxyContext`, dan `proxyFetch.ts` menggunakan `undici.fetch()` untuk menjaga kompatibilitas operator di Node 22.
+11. **Deteksi kebijakan runtime Node.js**: `/api/settings/require-login` mengembalikan kolom `nodeVersion` dan `nodeCompatible`. Halaman login menampilkan spanduk peringatan ketika runtime berada di luar garis aman Node.js yang didukung.
-## Operational Verification Checklist
+## Daftar Periksa Verifikasi Operasional
-- Build from source: `npm run build`
-- Build Docker image: `docker build -t omniroute .`
-- Start service and verify:
+- Bangun dari sumber: `npm run build`
+- Bangun gambar Docker: `docker build -t omniroute .`
+- Mulai layanan dan verifikasi:
- `GET /api/settings`
- `GET /api/v1/models`
-- CLI target base URL should be `http://:20128/v1` when `PORT=20128`
+- URL dasar target CLI harus `http://:20128/v1` ketika `PORT=20128`
diff --git a/docs/i18n/id/docs/architecture/CODEBASE_DOCUMENTATION.md b/docs/i18n/id/docs/architecture/CODEBASE_DOCUMENTATION.md
index 2b2ed35375..13905a0259 100644
--- a/docs/i18n/id/docs/architecture/CODEBASE_DOCUMENTATION.md
+++ b/docs/i18n/id/docs/architecture/CODEBASE_DOCUMENTATION.md
@@ -4,21 +4,21 @@
---
-> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
+> Panduan lengkap dan ramah-pemula untuk router proxy AI multi-penyedia **omniroute**.
---
-## 1. What Is omniroute?
+## 1. Apa Itu omniroute?
-omniroute is a **proxy router** that sits between AI clients (Claude CLI, Codex, Cursor IDE, etc.) and AI providers (Anthropic, Google, OpenAI, AWS, GitHub, etc.). It solves one big problem:
+omniroute adalah sebuah **router proxy** yang berada di antara klien AI (Claude CLI, Codex, Cursor IDE, dll.) dan penyedia AI (Anthropic, Google, OpenAI, AWS, GitHub, dll.). Ia memecahkan satu masalah besar:
-> **Different AI clients speak different "languages" (API formats), and different AI providers expect different "languages" too.** omniroute translates between them automatically.
+> **Klien AI yang berbeda berbicara "bahasa" yang berbeda (format API), dan penyedia AI yang berbeda pun mengharapkan "bahasa" yang berbeda pula.** omniroute menerjemahkan di antara mereka secara otomatis.
-Think of it like a universal translator at the United Nations — any delegate can speak any language, and the translator converts it for any other delegate.
+Bayangkan seperti penerjemah universal di Perserikatan Bangsa-Bangsa — delegasi mana pun dapat berbicara dalam bahasa apa pun, dan penerjemah mengubahnya untuk delegasi lainnya.
---
-## 2. Architecture Overview
+## 2. Ikhtisar Arsitektur
```mermaid
graph LR
@@ -63,82 +63,82 @@ graph LR
H -.-> G
```
-### Core Principle: Hub-and-Spoke Translation
+### Prinsip Inti: Terjemahan Hub-and-Spoke
-All format translation passes through **OpenAI format as the hub**:
+Semua terjemahan format melewati **format OpenAI sebagai hub**:
```
Client Format → [OpenAI Hub] → Provider Format (request)
Provider Format → [OpenAI Hub] → Client Format (response)
```
-This means you only need **N translators** (one per format) instead of **N²** (every pair).
+Artinya Anda hanya membutuhkan **N penerjemah** (satu per format), bukan **N²** (setiap pasangan).
---
-## 3. Project Structure
+## 3. Struktur Proyek
```
omniroute/
-├── open-sse/ ← Core proxy library (portable, framework-agnostic)
-│ ├── index.js ← Main entry point, exports everything
-│ ├── config/ ← Configuration & constants
-│ ├── executors/ ← Provider-specific request execution
-│ ├── handlers/ ← Request handling orchestration
-│ ├── services/ ← Business logic (auth, models, fallback, usage)
-│ ├── translator/ ← Format translation engine
-│ │ ├── request/ ← Request translators (8 files)
-│ │ ├── response/ ← Response translators (7 files)
-│ │ └── helpers/ ← Shared translation utilities (6 files)
-│ └── utils/ ← Utility functions
-├── src/ ← Application layer (Express/Worker runtime)
-│ ├── app/ ← Web UI, API routes, middleware
-│ ├── lib/ ← Database, auth, and shared library code
-│ ├── mitm/ ← Man-in-the-middle proxy utilities
-│ ├── models/ ← Database models
-│ ├── shared/ ← Shared utilities (wrappers around open-sse)
-│ ├── sse/ ← SSE endpoint handlers
-│ └── store/ ← State management
-├── data/ ← Runtime data (credentials, logs)
-│ └── provider-credentials.json (external credentials override, gitignored)
-└── tester/ ← Test utilities
+├── open-sse/ ← Library proxy inti (portabel, framework-agnostic)
+│ ├── index.js ← Titik masuk utama, mengekspor segalanya
+│ ├── config/ ← Konfigurasi & konstanta
+│ ├── executors/ ← Eksekusi permintaan khusus penyedia
+│ ├── handlers/ ← Orkestrasi penanganan permintaan
+│ ├── services/ ← Logika bisnis (auth, model, fallback, penggunaan)
+│ ├── translator/ ← Mesin terjemahan format
+│ │ ├── request/ ← Penerjemah permintaan (8 file)
+│ │ ├── response/ ← Penerjemah respons (7 file)
+│ │ └── helpers/ ← Utilitas terjemahan bersama (6 file)
+│ └── utils/ ← Fungsi utilitas
+├── src/ ← Lapisan aplikasi (runtime Express/Worker)
+│ ├── app/ ← Antarmuka web, rute API, middleware
+│ ├── lib/ ← Database, auth, dan kode library bersama
+│ ├── mitm/ ← Utilitas proxy man-in-the-middle
+│ ├── models/ ← Model database
+│ ├── shared/ ← Utilitas bersama (wrapper open-sse)
+│ ├── sse/ ← Handler endpoint SSE
+│ └── store/ ← Manajemen state
+├── data/ ← Data runtime (kredensial, log)
+│ └── provider-credentials.json (override kredensial eksternal, diabaikan git)
+└── tester/ ← Utilitas pengujian
```
---
-## 4. Module-by-Module Breakdown
+## 4. Rincian Modul per Modul
### 4.1 Config (`open-sse/config/`)
-The **single source of truth** for all provider configuration.
+**Satu-satunya sumber kebenaran** untuk semua konfigurasi penyedia.
-| File | Purpose |
+| File | Tujuan |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `constants.ts` | `PROVIDERS` object with base URLs, OAuth credentials (defaults), headers, and default system prompts for every provider. Also defines `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, and `SKIP_PATTERNS`. |
-| `credentialLoader.ts` | Loads external credentials from `data/provider-credentials.json` and merges them over the hardcoded defaults in `PROVIDERS`. Keeps secrets out of source control while maintaining backwards compatibility. |
-| `providerModels.ts` | Central model registry: maps provider aliases → model IDs. Functions like `getModels()`, `getProviderByAlias()`. |
-| `codexInstructions.ts` | System instructions injected into Codex requests (editing constraints, sandbox rules, approval policies). |
-| `defaultThinkingSignature.ts` | Default "thinking" signatures for Claude and Gemini models. |
-| `ollamaModels.ts` | Schema definition for local Ollama models (name, size, family, quantization). |
+| `constants.ts` | Objek `PROVIDERS` dengan URL dasar, kredensial OAuth (default), header, dan system prompt default untuk setiap penyedia. Juga mendefinisikan `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, dan `SKIP_PATTERNS`. |
+| `credentialLoader.ts` | Memuat kredensial eksternal dari `data/provider-credentials.json` dan menggabungkannya ke atas nilai default yang ter-hardcode di `PROVIDERS`. Menjaga rahasia di luar source control sambil mempertahankan kompatibilitas mundur. |
+| `providerModels.ts` | Registry model terpusat: memetakan alias penyedia → ID model. Fungsi-fungsi seperti `getModels()`, `getProviderByAlias()`. |
+| `codexInstructions.ts` | Instruksi sistem yang disuntikkan ke dalam permintaan Codex (batasan pengeditan, aturan sandbox, kebijakan persetujuan). |
+| `defaultThinkingSignature.ts` | Tanda tangan "berpikir" default untuk model Claude dan Gemini. |
+| `ollamaModels.ts` | Definisi skema untuk model Ollama lokal (nama, ukuran, keluarga, kuantisasi). |
-#### Credential Loading Flow
+#### Alur Pemuatan Kredensial
```mermaid
flowchart TD
A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"]
B --> C{"data/provider-credentials.json\nexists?"}
C -->|Yes| D["credentialLoader reads JSON"]
- C -->|No| E["Use hardcoded defaults"]
+ C -->|No| E["Gunakan default hardcode"]
D --> F{"For each provider in JSON"}
F --> G{"Provider exists\nin PROVIDERS?"}
G -->|No| H["Log warning, skip"]
- G -->|Yes| I{"Value is object?"}
+ G -->|Yes| I{"Nilai adalah objek?"}
I -->|No| J["Log warning, skip"]
I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"]
K --> F
H --> F
J --> F
- F -->|Done| L["PROVIDERS ready with\nmerged credentials"]
+ F -->|Done| L["PROVIDERS siap dengan\nkredensial yang digabungkan"]
E --> L
```
@@ -146,7 +146,7 @@ flowchart TD
### 4.2 Executors (`open-sse/executors/`)
-Executors encapsulate **provider-specific logic** using the **Strategy Pattern**. Each executor overrides base methods as needed.
+Executor merangkum **logika khusus penyedia** menggunakan **Strategy Pattern**. Setiap executor mengganti metode dasar sesuai kebutuhan.
```mermaid
classDiagram
@@ -196,32 +196,32 @@ classDiagram
BaseExecutor <|-- GithubExecutor
```
-| Executor | Provider | Key Specializations |
+| Executor | Penyedia | Spesialisasi Utama |
| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
-| `base.ts` | — | Abstract base: URL building, headers, retry logic, credential refresh |
-| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generic OAuth token refresh for standard providers |
-| `antigravity.ts` | Google Cloud Code | Project/session ID generation, multi-URL fallback, custom retry parsing from error messages ("reset after 2h7m23s") |
-| `cursor.ts` | Cursor IDE | **Most complex**: SHA-256 checksum auth, Protobuf request encoding, binary EventStream → SSE response parsing |
-| `codex.ts` | OpenAI Codex | Injects system instructions, manages thinking levels, removes unsupported parameters |
-| `gemini-cli.ts` | Google Gemini CLI | Custom URL building (`streamGenerateContent`), Google OAuth token refresh |
-| `github.ts` | GitHub Copilot | Dual token system (GitHub OAuth + Copilot token), VSCode header mimicking |
-| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binary parsing, AMZN event frames, token estimation |
-| `index.ts` | — | Factory: maps provider name → executor class, with default fallback |
+| `base.ts` | — | Basis abstrak: pembangunan URL, header, logika percobaan ulang, pembaruan kredensial |
+| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Pembaruan token OAuth generik untuk penyedia standar |
+| `antigravity.ts` | Google Cloud Code | Pembuatan ID proyek/sesi, fallback multi-URL, parsing percobaan ulang kustom dari pesan error ("reset after 2h7m23s") |
+| `cursor.ts` | Cursor IDE | **Paling kompleks**: autentikasi checksum SHA-256, encoding permintaan Protobuf, parsing binary EventStream → respons SSE |
+| `codex.ts` | OpenAI Codex | Menyuntikkan instruksi sistem, mengelola tingkat berpikir, menghapus parameter yang tidak didukung |
+| `gemini-cli.ts` | Google Gemini CLI | Pembangunan URL kustom (`streamGenerateContent`), pembaruan token OAuth Google |
+| `github.ts` | GitHub Copilot | Sistem token ganda (GitHub OAuth + token Copilot), peniruan header VSCode |
+| `kiro.ts` | AWS CodeWhisperer | Parsing binary AWS EventStream, frame event AMZN, estimasi token |
+| `index.ts` | — | Factory: memetakan nama penyedia → kelas executor, dengan fallback default |
---
### 4.3 Handlers (`open-sse/handlers/`)
-The **orchestration layer** — coordinates translation, execution, streaming, and error handling.
+**Lapisan orkestrasi** — mengoordinasikan terjemahan, eksekusi, streaming, dan penanganan error.
-| File | Purpose |
+| File | Tujuan |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `chatCore.ts` | **Central orchestrator** (~600 lines). Handles the complete request lifecycle: format detection → translation → executor dispatch → streaming/non-streaming response → token refresh → error handling → usage logging. |
-| `responsesHandler.ts` | Adapter for OpenAI's Responses API: converts Responses format → Chat Completions → sends to `chatCore` → converts SSE back to Responses format. |
-| `embeddings.ts` | Embedding generation handler: resolves embedding model → provider, dispatches to provider API, returns OpenAI-compatible embedding response. Supports 6+ providers. |
-| `imageGeneration.ts` | Image generation handler: resolves image model → provider, supports OpenAI-compatible, Gemini-image (Antigravity), and fallback (Nebius) modes. Returns base64 or URL images. |
+| `chatCore.ts` | **Orkestrator pusat** (~600 baris). Menangani siklus hidup permintaan secara lengkap: deteksi format → terjemahan → dispatch executor → respons streaming/non-streaming → pembaruan token → penanganan error → pencatatan penggunaan. |
+| `responsesHandler.ts` | Adaptor untuk Responses API OpenAI: mengonversi format Responses → Penyelesaian Obrolan → mengirim ke `chatCore` → mengonversi SSE kembali ke format Responses. |
+| `embeddings.ts` | Handler pembuatan embedding: me-resolve model embedding → penyedia, mengirim ke API penyedia, mengembalikan respons embedding yang kompatibel dengan OpenAI. Mendukung 6+ penyedia. |
+| `imageGeneration.ts` | Handler pembuatan gambar: me-resolve model gambar → penyedia, mendukung mode kompatibel-OpenAI, Gemini-image (Antigravity), dan fallback (Nebius). Mengembalikan gambar base64 atau URL. |
-#### Request Lifecycle (chatCore.ts)
+#### Siklus Hidup Permintaan (chatCore.ts)
```mermaid
sequenceDiagram
@@ -262,26 +262,26 @@ sequenceDiagram
### 4.4 Services (`open-sse/services/`)
-Business logic that supports the handlers and executors.
+Logika bisnis yang mendukung handler dan executor.
-| File | Purpose |
+| File | Tujuan |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `provider.ts` | **Format detection** (`detectFormat`): analyzes request body structure to identify Claude/OpenAI/Gemini/Antigravity/Responses formats (includes `max_tokens` heuristic for Claude). Also: URL building, header building, thinking config normalization. Supports `openai-compatible-*` and `anthropic-compatible-*` dynamic providers. |
-| `model.ts` | Model string parsing (`claude/model-name` → `{provider: "claude", model: "model-name"}`), alias resolution with collision detection, input sanitization (rejects path traversal/control chars), and model info resolution with async alias getter support. |
-| `accountFallback.ts` | Rate-limit handling: exponential backoff (1s → 2s → 4s → max 2min), account cooldown management, error classification (which errors trigger fallback vs. not). |
-| `tokenRefresh.ts` | OAuth token refresh for **every provider**: Google (Gemini, Antigravity), Claude, Codex, Qwen, Qoder, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Includes in-flight promise deduplication cache and retry with exponential backoff. |
-| `combo.ts` | **Combo models**: chains of fallback models. If model A fails with a fallback-eligible error, try model B, then C, etc. Returns actual upstream status codes. |
-| `usage.ts` | Fetches quota/usage data from provider APIs (GitHub Copilot quotas, Antigravity model quotas, Codex rate limits, Kiro usage breakdowns, Claude settings). |
-| `accountSelector.ts` | Smart account selection with scoring algorithm: considers priority, health status, round-robin position, and cooldown state to pick the optimal account for each request. |
-| `contextManager.ts` | Request context lifecycle management: creates and tracks per-request context objects with metadata (request ID, timestamps, provider info) for debugging and logging. |
-| `ipFilter.ts` | IP-based access control: supports allowlist and blocklist modes. Validates client IP against configured rules before processing API requests. |
-| `sessionManager.ts` | Session tracking with client fingerprinting: tracks active sessions using hashed client identifiers, monitors request counts, and provides session metrics. |
-| `signatureCache.ts` | Request signature-based deduplication cache: prevents duplicate requests by caching recent request signatures and returning cached responses for identical requests within a time window. |
-| `systemPrompt.ts` | Global system prompt injection: prepends or appends a configurable system prompt to all requests, with per-provider compatibility handling. |
-| `thinkingBudget.ts` | Reasoning token budget management: supports passthrough, auto (strip thinking config), custom (fixed budget), and adaptive (complexity-scaled) modes for controlling thinking/reasoning tokens. |
-| `wildcardRouter.ts` | Wildcard model pattern routing: resolves wildcard patterns (e.g., `*/claude-*`) to concrete provider/model pairs based on availability and priority. |
+| `provider.ts` | **Deteksi format** (`detectFormat`): menganalisis struktur body permintaan untuk mengidentifikasi format Claude/OpenAI/Gemini/Antigravity/Responses (mencakup heuristik `max_tokens` untuk Claude). Juga: pembangunan URL, pembangunan header, normalisasi konfigurasi berpikir. Mendukung penyedia dinamis `openai-compatible-*` dan `anthropic-compatible-*`. |
+| `model.ts` | Parsing string model (`claude/model-name` → `{provider: "claude", model: "model-name"}`), resolusi alias dengan deteksi tabrakan, sanitasi input (menolak path traversal/karakter kontrol), dan resolusi info model dengan dukungan getter alias asinkron. |
+| `accountFallback.ts` | Penanganan rate-limit: backoff eksponensial (1d → 2d → 4d → maks 2min), manajemen cooldown akun, klasifikasi error (error mana yang memicu fallback vs. tidak). |
+| `tokenRefresh.ts` | Pembaruan token OAuth untuk **setiap penyedia**: Google (Gemini, Antigravity), Claude, Codex, Qwen, Qoder, GitHub (OAuth + token ganda Copilot), Kiro (AWS SSO OIDC + Social Auth). Mencakup cache deduplikasi promise in-flight dan percobaan ulang dengan backoff eksponensial. |
+| `combo.ts` | **Model combo**: rantai model fallback. Jika model A gagal dengan error yang memenuhi syarat fallback, coba model B, lalu C, dst. Mengembalikan kode status upstream yang sebenarnya. |
+| `usage.ts` | Mengambil data kuota/penggunaan dari API penyedia (kuota GitHub Copilot, kuota model Antigravity, batas laju Codex, rincian penggunaan Kiro, pengaturan Claude). |
+| `accountSelector.ts` | Pemilihan akun cerdas dengan algoritma penilaian: mempertimbangkan prioritas, status kesehatan, posisi round-robin, dan kondisi cooldown untuk memilih akun optimal setiap permintaan. |
+| `contextManager.ts` | Manajemen siklus hidup konteks permintaan: membuat dan melacak objek konteks per-permintaan dengan metadata (ID permintaan, stempel waktu, info penyedia) untuk debugging dan pencatatan. |
+| `ipFilter.ts` | Kontrol akses berbasis IP: mendukung mode allowlist dan blocklist. Memvalidasi IP klien terhadap aturan yang dikonfigurasi sebelum memproses permintaan API. |
+| `sessionManager.ts` | Pelacakan sesi dengan fingerprinting klien: melacak sesi aktif menggunakan identifier klien yang di-hash, memantau jumlah permintaan, dan menyediakan metrik sesi. |
+| `signatureCache.ts` | Cache deduplikasi berbasis tanda tangan permintaan: mencegah permintaan duplikat dengan menyimpan cache tanda tangan permintaan terbaru dan mengembalikan respons tersimpan untuk permintaan identik dalam jendela waktu tertentu. |
+| `systemPrompt.ts` | Injeksi system prompt global: menambahkan di depan atau di belakang system prompt yang dapat dikonfigurasi ke semua permintaan, dengan penanganan kompatibilitas per-penyedia. |
+| `thinkingBudget.ts` | Manajemen anggaran token penalaran: mendukung mode passthrough, auto (hapus konfigurasi berpikir), kustom (anggaran tetap), dan adaptif (skala kompleksitas) untuk mengendalikan token berpikir/penalaran. |
+| `wildcardRouter.ts` | Routing pola model wildcard: me-resolve pola wildcard (mis., `*/claude-*`) ke pasangan penyedia/model konkret berdasarkan ketersediaan dan prioritas. |
-#### Token Refresh Deduplication
+#### Deduplikasi Pembaruan Token
```mermaid
sequenceDiagram
@@ -302,7 +302,7 @@ sequenceDiagram
Cache->>Cache: Delete cache entry
```
-#### Account Fallback State Machine
+#### Mesin Status Fallback Akun
```mermaid
stateDiagram-v2
@@ -327,7 +327,7 @@ stateDiagram-v2
}
```
-#### Combo Model Chain
+#### Model Rantai Kombo
```mermaid
flowchart LR
@@ -348,7 +348,7 @@ flowchart LR
### 4.5 Translator (`open-sse/translator/`)
-The **format translation engine** using a self-registering plugin system.
+**Mesin terjemahan format** yang menggunakan sistem plugin pendaftaran-diri.
#### Arsitektur
@@ -376,40 +376,40 @@ graph TD
end
```
-| Directory | Files | Description |
+| Direktori | File | Deskripsi |
| ------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `request/` | 8 translators | Convert request bodies between formats. Each file self-registers via `register(from, to, fn)` on import. |
-| `response/` | 7 translators | Convert streaming response chunks between formats. Handles SSE event types, thinking blocks, tool calls. |
-| `helpers/` | 6 helpers | Shared utilities: `claudeHelper` (system prompt extraction, thinking config), `geminiHelper` (parts/contents mapping), `openaiHelper` (format filtering), `toolCallHelper` (ID generation, missing response injection), `maxTokensHelper`, `responsesApiHelper`. |
-| `index.ts` | — | Translation engine: `translateRequest()`, `translateResponse()`, state management, registry. |
-| `formats.ts` | — | Format constants: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. |
+| `request/` | 8 penerjemah | Mengonversi body permintaan antar format. Setiap file mendaftar sendiri melalui `register(from, to, fn)` saat diimpor. |
+| `response/` | 7 penerjemah | Mengonversi potongan respon streaming antar format. berpartisipasi tipe acara SSE, blok berpikir, panggilan alat. |
+| `helpers/` | 6 pembantu | Utilitas bersama: `claudeHelper` (ekstraksi system prompt, konfigurasi berpikir), `geminiHelper` (pemetaan parts/contents), `openaiHelper` (pemfilteran format), `toolCallHelper` (pembuatan ID, injeksi respons yang hilang), `maxTokensHelper`, `responsesApiHelper`. |
+| `index.ts` | — | Mesin terjemahan: `translateRequest()`, `translateResponse()`, manajemen state, registry. |
+| `formats.ts` | — | Konstanta format: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. |
-#### Key Design: Self-Registering Plugins
+#### Desain Utama: Plugin Pendaftaran-Diri
```javascript
-// Each translator file calls register() on import:
+// Setiap file penerjemah memanggil register() saat diimpor:
import { register } from "../index.js";
register("claude", "openai", translateClaudeToOpenAI);
-// The index.js imports all translator files, triggering registration:
-import "./request/claude-to-openai.js"; // ← self-registers
+// index.js mengimpor semua file penerjemah, memicu pendaftaran:
+import "./request/claude-to-openai.js"; // ← mendaftar sendiri
```
---
### 4.6 Utils (`open-sse/utils/`)
-| File | Purpose |
+| File | Tujuan |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `error.ts` | Error response building (OpenAI-compatible format), upstream error parsing, Antigravity retry-time extraction from error messages, SSE error streaming. |
-| `stream.ts` | **SSE Transform Stream** — the core streaming pipeline. Two modes: `TRANSLATE` (full format translation) and `PASSTHROUGH` (normalize + extract usage). Handles chunk buffering, usage estimation, content length tracking. Per-stream encoder/decoder instances avoid shared state. |
-| `streamHelpers.ts` | Low-level SSE utilities: `parseSSELine` (whitespace-tolerant), `hasValuableContent` (filters empty chunks for OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (format-aware SSE serialization with `perf_metrics` cleanup). |
-| `usageTracking.ts` | Token usage extraction from any format (Claude/OpenAI/Gemini/Responses), estimation with separate tool/message char-per-token ratios, buffer addition (2000 tokens safety margin), format-specific field filtering, console logging with ANSI colors. |
-| `requestLogger.ts` | Legacy file-based request logging helper kept for compatibility. Current deployments should prefer `APP_LOG_TO_FILE` for application logs and the call log pipeline for persisted request artifacts. |
-| `bypassHandler.ts` | Intercepts specific patterns from Claude CLI (title extraction, warmup, count) and returns fake responses without calling any provider. Supports both streaming and non-streaming. Intentionally limited to Claude CLI scope. |
-| `networkProxy.ts` | Resolves outbound proxy URL for a given provider with precedence: provider-specific config → global config → environment variables (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Supports `NO_PROXY` exclusions. Caches config for 30s. |
+| `error.ts` | Pembangunan respons error (format kompatibel-OpenAI), parsing error upstream, ekstraksi waktu percobaan ulang Antigravity dari pesan error, streaming error SSE. |
+| `stream.ts` | **SSE Transform Stream** — inti streaming saluran pipa. Mode dua: `TRANSLATE` (terjemahan format penuh) dan `PASSTHROUGH` (normalisasi + penggunaan ekstraksi). menyertakan buffering potongan, estimasi penggunaan, pelacakan panjang konten. Encoder/decoder instance per-stream menghindari status bersama. |
+| `streamHelpers.ts` | Utilitas SSE tingkat rendah: `parseSSELine` (toleran terhadap spasi), `hasValuableContent` (menyaring potongan kosong untuk OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (serialisasi SSE yang peka format dengan pembersihan `perf_metrics`). |
+| `usageTracking.ts` | Ekstraksi penggunaan token dari format apa pun (Claude/OpenAI/Gemini/Responses), estimasi dengan rasio karakter-per-token terpisah untuk tool/pesan, penambahan buffer (margin keamanan 2000 token), pemfilteran field spesifik-format, pencatatan konsol dengan warna ANSI. |
+| `requestLogger.ts` | Pembantu pencatatan permintaan berbasis file lawas yang dipertahankan untuk kompatibilitas. Deployment saat ini sebaiknya menggunakan `APP_LOG_TO_FILE` untuk log aplikasi dan pipeline log panggilan untuk artefak permintaan yang dipersistensikan. |
+| `bypassHandler.ts` | Mengintersep pola tertentu dari Claude CLI (ekstraksi judul, pemanasan, penghitungan) dan mengembalikan respons palsu tanpa memanggil penyedia apa pun. Mendukung streaming maupun non-streaming. Sengaja dibatasi hanya untuk cakupan Claude CLI. |
+| `networkProxy.ts` | Me-resolve URL proxy keluar untuk penyedia tertentu dengan urutan prioritas: konfigurasi spesifik-penyedia → konfigurasi global → variabel lingkungan (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Mendukung pengecualian `NO_PROXY`. Menyimpan cache konfigurasi selama 30d. |
-#### SSE Streaming Pipeline
+#### SSE Streaming Saluran Pipa
```mermaid
flowchart TD
@@ -431,127 +431,127 @@ flowchart TD
style M fill:#9f9,stroke:#333
```
-#### Request Logger Session Structure
+#### Struktur Sesi Permintaan Logger
```
logs/
└── claude_gemini_claude-sonnet_20260208_143045/
- ├── 1_req_client.json ← Raw client request
- ├── 2_req_source.json ← After initial conversion
- ├── 3_req_openai.json ← OpenAI intermediate format
- ├── 4_req_target.json ← Final target format
- ├── 5_res_provider.txt ← Provider SSE chunks (streaming)
- ├── 5_res_provider.json ← Provider response (non-streaming)
- ├── 6_res_openai.txt ← OpenAI intermediate chunks
- ├── 7_res_client.txt ← Client-facing SSE chunks
- └── 6_error.json ← Error details (if any)
+ ├── 1_req_client.json ← Permintaan klien mentah
+ ├── 2_req_source.json ← Setelah konversi awal
+ ├── 3_req_openai.json ← Format perantara OpenAI
+ ├── 4_req_target.json ← Format target akhir
+ ├── 5_res_provider.txt ← Potongan SSE penyedia (streaming)
+ ├── 5_res_provider.json ← Respons penyedia (non-streaming)
+ ├── 6_res_openai.txt ← Potongan perantara OpenAI
+ ├── 7_res_client.txt ← Potongan SSE yang menghadap klien
+ └── 6_error.json ← Detail error (jika ada)
```
---
-### 4.7 Application Layer (`src/`)
+### 4.7 Lapisan Aplikasi (`src/`)
-| Directory | Purpose |
-| ------------- | ---------------------------------------------------------------------- |
-| `src/app/` | Web UI, API routes, Express middleware, OAuth callback handlers |
-| `src/lib/` | Database access (`localDb.ts`, `usageDb.ts`), authentication, shared |
-| `src/mitm/` | Man-in-the-middle proxy utilities for intercepting provider traffic |
-| `src/models/` | Database model definitions |
-| `src/shared/` | Wrappers around open-sse functions (provider, stream, error, etc.) |
-| `src/sse/` | SSE endpoint handlers that wire the open-sse library to Express routes |
-| `src/store/` | Application state management |
+| Direktori | Tujuan |
+| ------------- | ------------------------------------------------------------------------------- |
+| `src/app/` | Antarmuka web, rute API, middleware Express, handler callback OAuth |
+| `src/lib/` | Akses database (`localDb.ts`, `usageDb.ts`), autentikasi, kode bersama |
+| `src/mitm/` | Utilitas proxy man-in-the-middle untuk mengintersep lalu lintas penyedia |
+| `src/models/` | Definisi model basis data |
+| `src/shared/` | Wrapper fungsi open-sse (penyedia, stream, error, dll.) |
+| `src/sse/` | Handler endpoint SSE yang menghubungkan library open-sse ke rute Express |
+| `src/store/` | Manajemen state aplikasi |
-#### Notable API Routes
+#### Rute API Penting
-| Route | Methods | Purpose |
-| --------------------------------------------- | --------------- | ------------------------------------------------------------------------------------- |
-| `/api/provider-models` | GET/POST/DELETE | CRUD for custom models per provider |
-| `/api/models/catalog` | GET | Aggregated catalog of all models (chat, embedding, image, custom) grouped by provider |
-| `/api/settings/proxy` | GET/PUT/DELETE | Hierarchical outbound proxy configuration (`global/providers/combos/keys`) |
-| `/api/settings/proxy/test` | POST | Validates proxy connectivity and returns public IP/latency |
-| `/v1/providers/[provider]/chat/completions` | POST | Dedicated per-provider chat completions with model validation |
-| `/v1/providers/[provider]/embeddings` | POST | Dedicated per-provider embeddings with model validation |
-| `/v1/providers/[provider]/images/generations` | POST | Dedicated per-provider image generation with model validation |
-| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist management |
-| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget configuration (passthrough/auto/custom/adaptive) |
-| `/api/settings/system-prompt` | GET/PUT | Global system prompt injection for all requests |
-| `/api/sessions` | GET | Active session tracking and metrics |
-| `/api/rate-limits` | GET | Per-account rate limit status |
+| Rute | Metode | Tujuan |
+| --------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------- |
+| `/api/provider-models` | GET/POST/DELETE | CRUD untuk model kustom per penyedia |
+| `/api/models/catalog` | GET | Katalog gabungan semua model (chat, embedding, gambar, kustom) yang dikelompokkan per penyedia |
+| `/api/settings/proxy` | GET/PUT/DELETE | Konfigurasi proxy keluar hierarkis (`global/providers/combos/keys`) |
+| `/api/settings/proxy/test` | POST | Memvalidasi konektivitas proxy dan mengembalikan IP publik/latensi |
+| `/v1/providers/[provider]/chat/completions` | POST | Chat completions khusus per-penyedia dengan validasi model |
+| `/v1/providers/[provider]/embeddings` | POST | Embedding khusus per-penyedia dengan validasi model |
+| `/v1/providers/[provider]/images/generations` | POST | Pembuatan gambar khusus per-penyedia dengan validasi model |
+| `/api/settings/ip-filter` | GET/PUT | Manajemen allowlist/blocklist IP |
+| `/api/settings/thinking-budget` | GET/PUT | Konfigurasi anggaran token penalaran (passthrough/auto/custom/adaptive) |
+| `/api/settings/system-prompt` | GET/PUT | Injeksi system prompt global untuk semua permintaan |
+| `/api/sessions` | GET | Pelacakan sesi aktif dan metrik |
+| `/api/rate-limits` | GET | Status batas laju per-akun |
---
-## 5. Key Design Patterns
+## 5. Pola Desain Utama
-### 5.1 Hub-and-Spoke Translation
+### 5.1 Terjemahan Hub-and-Spoke
-All formats translate through **OpenAI format as the hub**. Adding a new provider only requires writing **one pair** of translators (to/from OpenAI), not N pairs.
+Semua format diterjemahkan melalui **format OpenAI sebagai hub**. Menambahkan penyedia baru hanya membutuhkan penulisan **satu pasang** penerjemah (ke/dari OpenAI), bukan N pasangan.
-### 5.2 Executor Strategy Pattern
+### 5.2 Strategy Pattern pada Executor
-Each provider has a dedicated executor class inheriting from `BaseExecutor`. The factory in `executors/index.ts` selects the right one at runtime.
+Setiap penyedia memiliki kelas executor khusus yang mewarisi dari `BaseExecutor`. Factory di `executors/index.ts` memilih yang tepat saat runtime.
-### 5.3 Self-Registering Plugin System
+### 5.3 Sistem Plugin Pendaftaran-Diri
-Translator modules register themselves on import via `register()`. Adding a new translator is just creating a file and importing it.
+Modul penerjemah mendaftarkan diri saat diimpor melalui `register()`. Menambahkan penerjemah baru cukup dengan membuat file dan mengimpornya.
-### 5.4 Account Fallback with Exponential Backoff
+### 5.4 Fallback Akun dengan Backoff Eksponensial
-When a provider returns 429/401/500, the system can switch to the next account, applying exponential cooldowns (1s → 2s → 4s → max 2min).
+Ketika penyedia mengembalikan 429/401/500, sistem dapat beralih ke akun berikutnya, menerapkan cooldown eksponensial (1d → 2d → 4d → maks 2min).
-### 5.5 Combo Model Chains
+### 5.5 Model Rantai Kombo
-A "combo" groups multiple `provider/model` strings. If the first fails, fallback to the next automatically.
+Sebuah "combo" mengelompokkan beberapa string `provider/model`. Jika yang pertama gagal, otomatis beralih ke berikutnya.
-### 5.6 Stateful Streaming Translation
+### 5.6 Terjemahan Streaming dengan State
-Response translation maintains state across SSE chunks (thinking block tracking, tool call accumulation, content block indexing) via the `initState()` mechanism.
+Terjemahan respons mempertahankan state di seluruh potongan SSE (pelacakan blok berpikir, akumulasi tool call, pengindeksan blok konten) melalui mekanisme `initState()`.
-### 5.7 Usage Safety Buffer
+### 5.7 Buffer Keamanan Penggunaan
-A 2000-token buffer is added to reported usage to prevent clients from hitting context window limits due to overhead from system prompts and format translation.
+Buffer 2000 token ditambahkan ke penggunaan yang dilaporkan untuk mencegah klien mencapai batas jendela konteks akibat overhead dari system prompt dan terjemahan format.
---
-## 6. Supported Formats
+## 6. Format yang Didukung
-| Format | Direction | Identifier |
+| Format | Arah | Identifier |
| ----------------------- | --------------- | ------------------ |
-| OpenAI Chat Completions | source + target | `openai` |
-| OpenAI Responses API | source + target | `openai-responses` |
-| Anthropic Claude | source + target | `claude` |
-| Google Gemini | source + target | `gemini` |
-| Google Gemini CLI | target only | `gemini-cli` |
-| Antigravity | source + target | `antigravity` |
-| AWS Kiro | target only | `kiro` |
-| Cursor | target only | `cursor` |
+| OpenAI Chat Completions | sumber + target | `openai` |
+| API Respons OpenAI | sumber + target | `openai-responses` |
+| Anthropic Claude | sumber + target | `claude` |
+| Google Gemini | sumber + target | `gemini` |
+| Google Gemini CLI | target saja | `gemini-cli` |
+| Antigravity | sumber + target | `antigravity` |
+| AWS Kiro | target saja | `kiro` |
+| Cursor | target saja | `cursor` |
---
-## 7. Supported Providers
+## 7. Penyedia yang Didukung
-| Provider | Auth Method | Executor | Key Notes |
-| ------------------------ | ---------------------- | ----------- | --------------------------------------------- |
-| Anthropic Claude | API key or OAuth | Default | Uses `x-api-key` header |
-| Google Gemini | API key or OAuth | Default | Uses `x-goog-api-key` header |
-| Google Gemini CLI | OAuth | GeminiCLI | Uses `streamGenerateContent` endpoint |
-| Antigravity | OAuth | Antigravity | Multi-URL fallback, custom retry parsing |
-| OpenAI | API key | Default | Standard Bearer auth |
-| Codex | OAuth | Codex | Injects system instructions, manages thinking |
-| GitHub Copilot | OAuth + Copilot token | Github | Dual token, VSCode header mimicking |
-| Kiro (AWS) | AWS SSO OIDC or Social | Kiro | Binary EventStream parsing |
-| Cursor IDE | Checksum auth | Cursor | Protobuf encoding, SHA-256 checksums |
-| Qwen | OAuth | Default | Standard auth |
-| Qoder | OAuth (Basic + Bearer) | Default | Dual auth header |
-| OpenRouter | API key | Default | Standard Bearer auth |
-| GLM, Kimi, MiniMax | API key | Default | Claude-compatible, use `x-api-key` |
-| `openai-compatible-*` | API key | Default | Dynamic: any OpenAI-compatible endpoint |
-| `anthropic-compatible-*` | API key | Default | Dynamic: any Claude-compatible endpoint |
+| Penyedia | Metode Autentikasi | Executor | Catatan Utama |
+| ------------------------ | ---------------------- | ----------- | ----------------------------------------------------- |
+| Anthropic Claude | Kunci API atau OAuth | Default | Menggunakan header `x-api-key` |
+| Google Gemini | Kunci API atau OAuth | Default | Menggunakan header `x-goog-api-key` |
+| Google Gemini CLI | OAuth | GeminiCLI | Menggunakan endpoint `streamGenerateContent` |
+| Antigravity | OAuth | Antigravity | Penggantian multi-URL, penguraian percobaan ulang kustom |
+| OpenAI | API key | Default | Autentikasi Bearer standar |
+| Codex | OAuth | Codex | Menyuntikkan instruksi sistem, mengelola berpikir |
+| GitHub Copilot | OAuth + token Copilot | Github | Token ganda, peniruan header VSCode |
+| Kiro (AWS) | AWS SSO OIDC atau Social | Kiro | Parsing binary EventStream |
+| Cursor IDE | Autentikasi checksum | Cursor | Encoding Protobuf, checksum SHA-256 |
+| Qwen | OAuth | Default | Autentikasi standar |
+| Qoder | OAuth (Basic + Bearer) | Default | Autentikasi header ganda|
+| OpenRouter | API key | Default | Autentikasi Bearer standar |
+| GLM, Kimi, MiniMax | API key | Default | Kompatibel-Claude, menggunakan `x-api-key` |
+| `openai-compatible-*` | API key | Default |Dinamis: endpoint kompatibel-OpenAI apa pun |
+| `anthropic-compatible-*` | API key | Default | Dinamis: endpoint kompatibel-Claude apa pun |
---
-## 8. Data Flow Summary
+## 8. Ringkasan Alur Data
-### Streaming Request
+### Permintaan Streaming
```mermaid
flowchart LR
@@ -568,7 +568,7 @@ flowchart LR
K --> L["logUsage()\nsaveRequestUsage()"]
```
-### Non-Streaming Request
+### Permintaan Non-Streaming
```mermaid
flowchart LR
@@ -579,12 +579,12 @@ flowchart LR
E --> F["Return JSON\nresponse"]
```
-### Bypass Flow (Claude CLI)
+### Alur Bypass (Claude CLI)
```mermaid
flowchart LR
A["Claude CLI request"] --> B{"Match bypass\npattern?"}
- B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"]
+ B -->|"Title/Warmup/Count"| C["Buat respons palsu\nOpenAI"]
B -->|"No match"| D["Normal flow"]
C --> E["Translate to\nsource format"]
E --> F["Return without\ncalling provider"]
diff --git a/docs/i18n/id/docs/cloudflare-zero-trust-guide.md b/docs/i18n/id/docs/cloudflare-zero-trust-guide.md
index ff8b7f34ce..5ddfa7e4c9 100644
--- a/docs/i18n/id/docs/cloudflare-zero-trust-guide.md
+++ b/docs/i18n/id/docs/cloudflare-zero-trust-guide.md
@@ -1,106 +1,106 @@
-# Guia Completo: Cloudflare Tunnel & Zero Trust (Split-Port) (Bahasa Indonesia)
+# Panduan Lengkap: Cloudflare Tunnel & Zero Trust (Split-Port) (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/cloudflare-zero-trust-guide.md) · 🇪🇸 [es](../../es/docs/cloudflare-zero-trust-guide.md) · 🇫🇷 [fr](../../fr/docs/cloudflare-zero-trust-guide.md) · 🇩🇪 [de](../../de/docs/cloudflare-zero-trust-guide.md) · 🇮🇹 [it](../../it/docs/cloudflare-zero-trust-guide.md) · 🇷🇺 [ru](../../ru/docs/cloudflare-zero-trust-guide.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/cloudflare-zero-trust-guide.md) · 🇯🇵 [ja](../../ja/docs/cloudflare-zero-trust-guide.md) · 🇰🇷 [ko](../../ko/docs/cloudflare-zero-trust-guide.md) · 🇸🇦 [ar](../../ar/docs/cloudflare-zero-trust-guide.md) · 🇮🇳 [hi](../../hi/docs/cloudflare-zero-trust-guide.md) · 🇮🇳 [in](../../in/docs/cloudflare-zero-trust-guide.md) · 🇹🇭 [th](../../th/docs/cloudflare-zero-trust-guide.md) · 🇻🇳 [vi](../../vi/docs/cloudflare-zero-trust-guide.md) · 🇮🇩 [id](../../id/docs/cloudflare-zero-trust-guide.md) · 🇲🇾 [ms](../../ms/docs/cloudflare-zero-trust-guide.md) · 🇳🇱 [nl](../../nl/docs/cloudflare-zero-trust-guide.md) · 🇵🇱 [pl](../../pl/docs/cloudflare-zero-trust-guide.md) · 🇸🇪 [sv](../../sv/docs/cloudflare-zero-trust-guide.md) · 🇳🇴 [no](../../no/docs/cloudflare-zero-trust-guide.md) · 🇩🇰 [da](../../da/docs/cloudflare-zero-trust-guide.md) · 🇫🇮 [fi](../../fi/docs/cloudflare-zero-trust-guide.md) · 🇵🇹 [pt](../../pt/docs/cloudflare-zero-trust-guide.md) · 🇷🇴 [ro](../../ro/docs/cloudflare-zero-trust-guide.md) · 🇭🇺 [hu](../../hu/docs/cloudflare-zero-trust-guide.md) · 🇧🇬 [bg](../../bg/docs/cloudflare-zero-trust-guide.md) · 🇸🇰 [sk](../../sk/docs/cloudflare-zero-trust-guide.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/cloudflare-zero-trust-guide.md) · 🇮🇱 [he](../../he/docs/cloudflare-zero-trust-guide.md) · 🇵🇭 [phi](../../phi/docs/cloudflare-zero-trust-guide.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/cloudflare-zero-trust-guide.md) · 🇨🇿 [cs](../../cs/docs/cloudflare-zero-trust-guide.md) · 🇹🇷 [tr](../../tr/docs/cloudflare-zero-trust-guide.md)
---
-Este guia documenta o padrão ouro de infraestrutura de rede para proteger o **OmniRoute** e expor sua aplicação de forma segura para a internet, **sem abrir nenhuma porta (Zero Inbound)**.
+Panduan ini mendokumentasikan standar infrastruktur jaringan terbaik untuk mengamankan **OmniRoute** dan mengekspos aplikasi Anda ke internet secara aman, **tanpa membuka satu pun port (Zero Inbound)**.
-## O que foi feito na sua VM?
+## Apa yang Telah Dilakukan pada VM Anda?
-Nós ativamos o OmniRoute em modo **Split-Port** através do PM2:
+Kami mengaktifkan OmniRoute dalam mode **Split-Port** melalui PM2:
-- **Porta \`20128\`:** Roda **apenas a API** `/v1`.
-- **Porta \`20129\`:** Roda **apenas o Dashboard** Administrativo visual.
+- **Port \`20128\`:** Menjalankan **hanya API** `/v1`.
+- **Port \`20129\`:** Menjalankan **hanya Dashboard** Administratif visual.
-Além disso, o serviço interno exige \`REQUIRE_API_KEY=true\`, o que significa que nenhum agente pode consumir os endpoints da API sem enviar um "Bearer Token" legítimo gerado na aba API Keys do Painel.
+Selain itu, layanan internal memerlukan `REQUIRE_API_KEY=true`, yang berarti tidak ada agen yang dapat menggunakan endpoint API tanpa mengirimkan "Bearer Token" yang sah yang dihasilkan dari tab API Keys di Panel.
-Isso nos permite criar duas regras completamente independentes na rede. É aqui que entra o **Cloudflare Tunnel (cloudflared)**.
+Hal ini memungkinkan kita membuat dua aturan yang sepenuhnya independen di jaringan. Di sinilah peran **Cloudflare Tunnel (cloudflared)**.
---
-## 1. Como Criar o Túnel na Cloudflare
+## 1. Cara Membuat Terowongan di Cloudflare
-O utilitário \`cloudflared\` já está instalado na sua máquina. Siga os passos na nuvem:
+Utilitas `cloudflared` sudah terpasang di mesin Anda. Ikuti langkah-langkah berikut di cloud:
-1. Acesse seu painel **Cloudflare Zero Trust** (One.dash.cloudflare.com).
-2. No menu à esquerda, vá em **Networks > Tunnels**.
-3. Clique em **Add a Tunnel**, escolha **Cloudflared** e dê o nome \`OmniRoute-VM\`.
-4. Ele vai gerar um comando na tela chamado "Install and run a connector". **Você só precisa copiar o Token (a string longa após `--token`)**.
-5. Logue via SSH na sua máquina virtual (ou Terminal do Proxmox) e execute:
+1. Akses panel **Cloudflare Zero Trust** Anda (One.dash.cloudflare.com).
+2. Di menu sebelah kiri, pergi ke **Networks > Tunnels**.
+3. Klik **Add a Tunnel**, pilih **Cloudflared**, dan beri nama `OmniRoute-VM`.
+4. Sistem akan menghasilkan perintah di layar bernama "Install and run a connector". **Anda hanya perlu menyalin Token (string panjang setelah `--token`)**.
+5. Masuk melalui SSH ke mesin virtual Anda (atau Terminal Proxmox) dan jalankan:
\`\`\`bash
- # Inicia e amarra o túnel permanentemente à sua conta
- cloudflared service install SEU_TOKEN_GIGANTE_AQUI
+ # Memulai dan mengikat terowongan secara permanen ke akun Anda
+ cloudflared service install TOKEN_PANJANG_ANDA_DI_SINI
\`\`\`
---
-## 2. Configurando o Roteamento (Public Hostnames)
+## 2. Mengonfigurasi Perutean (Public Hostnames)
-Ainda na tela do Tunnel recém-criado, vá para a aba **Public Hostnames** e adicione as **duas** rotas, aproveitando a separação que fizemos:
+Masih di layar Tunnel yang baru dibuat, buka tab **Public Hostnames** dan tambahkan **dua** rute, memanfaatkan pemisahan yang telah kita lakukan:
-### Rota 1: API Segura (Limitada)
+### Rute 1: API Aman (Terbatas)
-- **Subdomain:** \`api\`
-- **Domain:** \`seuglobal.com.br\` (escolha seu domínio real)
-- **Service Type:** \`HTTP\`
-- **URL:** \`127.0.0.1:20128\` _(Porta interna da API)_
+- **Subdomain:** `api`
+- **Domain:** `domainanda.com` (pilih domain nyata Anda)
+- **Service Type:** `HTTP`
+- **URL:** `127.0.0.1:20128` _(Port internal API)_
-### Rota 2: Painel Zero Trust (Fechado)
+### Rute 2: Panel Zero Trust (Tertutup)
-- **Subdomain:** \`omniroute\` ou \`painel\`
-- **Domain:** \`seuglobal.com.br\`
-- **Service Type:** \`HTTP\`
-- **URL:** \`127.0.0.1:20129\` _(Porta interna do App/Visual)_
+- **Subdomain:** `omniroute` atau `panel`
+- **Domain:** `domainanda.com`
+- **Service Type:** `HTTP`
+- **URL:** `127.0.0.1:20129` _(Port internal App/Visual)_
-Neste momento, a conectividade "Física" está resolvida. Agora vamos blindar de verdade.
+Pada titik ini, konektivitas "fisik" telah terselesaikan. Sekarang kita akan benar-benar mengamankannya.
---
-## 3. Blindando o Painel com Zero Trust (Access)
+## 3. Mengamankan Panel dengan Zero Trust (Access)
-Nenhuma senha local protege melhor o seu painel do que remover totalmente o acesso a ele da internet aberta.
+Tidak ada kata sandi lokal yang lebih baik dalam melindungi panel Anda selain menghapus sepenuhnya akses ke panel tersebut dari internet terbuka.
-1. No painel Zero Trust, vá em **Access > Applications > Add an application**.
-2. Selecione **Self-hosted**.
-3. Em **Application name**, coloque \`Painel OmniRoute\`.
-4. Em **Application domain**, coloque \`omniroute.seuglobal.com.br\` (O mesmo que você fez na "Rota 2").
-5. Clique em **Next**.
-6. Em **Rule action**, escolha \`Allow\`. Em nome da Rule coloque \`Admin Apenas\`.
-7. Em **Include**, no seletor de "Selector" escolha \`Emails\` e digite o seu email, por exemplo \`admin@spgeo.com.br\`.
-8. Salve (`Add application`).
+1. Di panel Zero Trust, buka **Access > Applications > Add an application**.
+2. Pilih **Self-hosted**.
+3. Di **Application name**, masukkan `Panel OmniRoute`.
+4. Di **Application domain**, masukkan `omniroute.domainanda.com` (sama dengan yang Anda buat di "Rute 2").
+5. Klik **Next**.
+6. Di **Rule action**, pilih `Allow`. Beri nama Rule `Admin Saja`.
+7. Di **Include**, pada selektor "Selector" pilih `Emails` dan masukkan email Anda, misalnya `admin@domainanda.com`.
+8. Simpan (`Add application`).
-> **O que isso fez:** Se você tentar abrir \`omniroute.seuglobal.com.br\`, não cai mais na sua aplicação OmniRoute! Cai numa tela elegante da Cloudflare pedindo para digitar seu email. Somente se você (ou o email que você botou) for digitado lá, ele recebe no Outlook/Gmail um código de 6 dígitos temporário que libera o túnel até a porta \`20129\`.
+> **Apa yang terjadi:** Jika Anda mencoba membuka `omniroute.domainanda.com`, Anda tidak akan langsung masuk ke aplikasi OmniRoute! Anda akan disambut halaman Cloudflare yang meminta Anda memasukkan email. Hanya jika email yang Anda masukkan cocok, Anda akan menerima kode sementara 6 digit melalui Outlook/Gmail yang membuka akses ke terowongan menuju port `20129`.
---
-## 4. Limitando e Protegendo a API com Rate Limit (WAF)
+## 4. Membatasi dan Melindungi API dengan Rate Limit (WAF)
-O Dashboard do Zero Trust não se aplica à rota da API (\`api.seuglobal.com.br\`), porque é um acesso programático via ferramentas automatizadas (agentes) sem navegador. Para ele, usaremos o Firewall principal (WAF) da Cloudflare.
+Dashboard Zero Trust tidak berlaku untuk rute API (`api.domainanda.com`), karena ini adalah akses terprogram melalui alat otomatis (agen) tanpa browser. Untuk ini, kita akan menggunakan Firewall utama (WAF) Cloudflare.
-1. Acesse o **Painel Normal** da Cloudflare (dash.cloudflare.com) e entre no seu Domínio.
-2. No menu esquerdo, vá em **Security > WAF > Rate limiting rules**.
-3. Clique em **Create rule**.
-4. **Name:** \`Anti-Abuso OmniRoute API\`
+1. Akses **Panel Normal** Cloudflare (dash.cloudflare.com) dan masuk ke Domain Anda.
+2. Di menu sebelah kiri, buka **Security > WAF > Rate limiting rules**.
+3. Klik **Create rule**.
+4. **Name:** `Anti-Penyalahgunaan OmniRoute API`
5. **If incoming requests match...**
- - Escolha em Field: \`Hostname\`
- - Operator: \`equals\`
- - Value: \`api.seuglobal.com.br\`
-6. Em **With the same characteristics:** Mantenha \`IP\`.
-7. Nos limites (Limit):
- - **When requests exceed:** \`50\`
- - **Period:** \`1 minute\`
-8. No final, em **Action**: \`Block\` (Bloquear) e decida se o bloqueio dura por 1 minuto ou 1 hora.
+ - Pilih di Field: `Hostname`
+ - Operator: `equals`
+ - Value: `api.domainanda.com`
+6. Di **With the same characteristics:** Pertahankan `IP`.
+7. Pada batas (Limit):
+ - **When requests exceed:** `50`
+ - **Period:** `1 minute`
+8. Di bagian bawah, pada **Action**: `Block` (Blokir) dan tentukan apakah pemblokiran berlangsung 1 menit atau 1 jam.
9. **Deploy**.
-> **O que isso fez:** Ninguém pode mandar mais de 50 requisições num período de 60 segundos na sua URL de API. Como você roda vários agentes e os consumos por trás já batem rate limit e já rastreiam tokens, isso é apenas uma medida na Borda da Internet (Edge Layer) que protege sua Instância On-Premises de cair por estresse térmico antes mesmo do tráfego descer pelo túnel.
+> **Apa yang terjadi:** Tidak ada yang dapat mengirim lebih dari 50 permintaan dalam periode 60 detik ke URL API Anda. Karena Anda menjalankan beberapa agen dan konsumsi di belakangnya sudah mencapai batas laju serta melacak token, ini hanyalah langkah pengamanan di lapisan tepi internet (Edge Layer) yang melindungi instans On-Premises Anda dari kelebihan beban bahkan sebelum trafik melewati terowongan.
---
-## Finalização
+## Penutup
-1. A sua VM **não possui nenhuma porta exposta** em `/etc/ufw`.
-2. O OmniRoute só conversa HTTPS saindo (\`cloudflared\`) e não recebendo TCP direto do mundo.
-3. Seus requets pro OpenAI são ofuscados porque configuramos eles globalmente pra passar em um Proxy SOCKS5 (A nuvem não liga pro SOCKS5 porque ela vem Inbound).
-4. Seu painel web tem 2-Factor com Email.
-5. Sua API está ratelimitada na borda pela Cloudflare e só trafega Bearer Tokens.
+1. VM Anda **tidak memiliki port yang terbuka** di `/etc/ufw`.
+2. OmniRoute hanya berkomunikasi melalui HTTPS keluar (`cloudflared`) dan tidak menerima koneksi TCP langsung dari internet.
+3. Permintaan Anda ke OpenAI disamarkan karena dikonfigurasi secara global untuk melewati Proxy SOCKS5 (cloud tidak peduli dengan SOCKS5 karena trafik datang secara Inbound).
+4. Panel web Anda memiliki autentikasi 2 faktor melalui Email.
+5. API Anda dibatasi lajunya di tepi jaringan oleh Cloudflare dan hanya menerima lalu lintas Bearer Token.
diff --git a/docs/i18n/id/docs/features/context-relay.md b/docs/i18n/id/docs/features/context-relay.md
index a00f14a26c..53ef6bb299 100644
--- a/docs/i18n/id/docs/features/context-relay.md
+++ b/docs/i18n/id/docs/features/context-relay.md
@@ -1,65 +1,65 @@
-# Context Relay (Bahasa Indonesia)
+# Context Relay
🌐 **Languages:** 🇺🇸 [English](../../../../../docs/features/context-relay.md) · 🇪🇸 [es](../../../es/docs/features/context-relay.md) · 🇫🇷 [fr](../../../fr/docs/features/context-relay.md) · 🇩🇪 [de](../../../de/docs/features/context-relay.md) · 🇮🇹 [it](../../../it/docs/features/context-relay.md) · 🇷🇺 [ru](../../../ru/docs/features/context-relay.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/features/context-relay.md) · 🇯🇵 [ja](../../../ja/docs/features/context-relay.md) · 🇰🇷 [ko](../../../ko/docs/features/context-relay.md) · 🇸🇦 [ar](../../../ar/docs/features/context-relay.md) · 🇮🇳 [hi](../../../hi/docs/features/context-relay.md) · 🇮🇳 [in](../../../in/docs/features/context-relay.md) · 🇹🇭 [th](../../../th/docs/features/context-relay.md) · 🇻🇳 [vi](../../../vi/docs/features/context-relay.md) · 🇮🇩 [id](../../../id/docs/features/context-relay.md) · 🇲🇾 [ms](../../../ms/docs/features/context-relay.md) · 🇳🇱 [nl](../../../nl/docs/features/context-relay.md) · 🇵🇱 [pl](../../../pl/docs/features/context-relay.md) · 🇸🇪 [sv](../../../sv/docs/features/context-relay.md) · 🇳🇴 [no](../../../no/docs/features/context-relay.md) · 🇩🇰 [da](../../../da/docs/features/context-relay.md) · 🇫🇮 [fi](../../../fi/docs/features/context-relay.md) · 🇵🇹 [pt](../../../pt/docs/features/context-relay.md) · 🇷🇴 [ro](../../../ro/docs/features/context-relay.md) · 🇭🇺 [hu](../../../hu/docs/features/context-relay.md) · 🇧🇬 [bg](../../../bg/docs/features/context-relay.md) · 🇸🇰 [sk](../../../sk/docs/features/context-relay.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/features/context-relay.md) · 🇮🇱 [he](../../../he/docs/features/context-relay.md) · 🇵🇭 [phi](../../../phi/docs/features/context-relay.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/features/context-relay.md) · 🇨🇿 [cs](../../../cs/docs/features/context-relay.md) · 🇹🇷 [tr](../../../tr/docs/features/context-relay.md)
---
-`context-relay` is a combo strategy that keeps session continuity when the active account
-rotates before the conversation is finished.
+`context-relay` adalah strategi combo yang menjaga kesinambungan sesi ketika akun aktif
+berputar sebelum percakapan selesai.
-The current runtime behaves like priority routing for model selection, then adds a
-handoff layer on top:
+Runtime saat ini berperilaku seperti routing prioritas untuk pemilihan model, kemudian menambahkan
+lapisan handoff di atasnya:
-- before the active account is exhausted, OmniRoute generates a compact structured summary
-- after authentication selects a different account for the same session, OmniRoute injects
- that summary as a system message into the next request
-- once the handoff is consumed successfully, it is removed from storage
+- sebelum akun aktif habis, OmniRoute menghasilkan ringkasan terstruktur yang ringkas
+- setelah autentikasi memilih akun berbeda untuk sesi yang sama, OmniRoute menyuntikkan
+ ringkasan tersebut sebagai pesan sistem ke dalam permintaan berikutnya
+- setelah handoff berhasil dikonsumsi, handoff tersebut dihapus dari penyimpanan
-## When To Use It
+## Kapan Menggunakannya
-Use `context-relay` when all of the following are true:
+Gunakan `context-relay` ketika semua kondisi berikut terpenuhi:
-- the combo is expected to rotate between multiple accounts of the same provider
-- losing short-term conversational continuity would hurt task quality
-- the provider exposes enough quota information to predict an approaching account limit
+- combo diharapkan berputar di antara beberapa akun dari penyedia yang sama
+- kehilangan kesinambungan percakapan jangka pendek akan mengurangi kualitas tugas
+- penyedia mengekspos informasi kuota yang cukup untuk memprediksi batas akun yang akan datang
-This is most useful for long-running coding or research sessions that may outlive a single
-account window.
+Ini paling berguna untuk sesi coding atau riset yang berjalan lama yang mungkin melampaui satu
+jendela akun.
-## Runtime Flow
+## Alur Runtime
-The current behavior is intentionally split across two runtime layers.
+Perilaku saat ini secara sengaja dibagi ke dalam dua lapisan runtime.
-### 0% to 84% quota used
+### 0% hingga 84% kuota terpakai
-No handoff is generated. Requests behave like normal priority routing.
+Tidak ada handoff yang dihasilkan. Permintaan berperilaku seperti routing prioritas normal.
-### 85% to 94% quota used
+### 85% hingga 94% kuota terpakai
-If the active provider is enabled in `handoffProviders`, OmniRoute generates a structured
-handoff summary in the background before the account is fully exhausted.
+Jika penyedia aktif diaktifkan di `handoffProviders`, OmniRoute menghasilkan ringkasan handoff
+terstruktur di latar belakang sebelum akun habis sepenuhnya.
-Important details:
+Detail penting:
-- the default warning threshold is `0.85`
-- the hard stop for generation is `0.95`
-- only one in-flight handoff generation is allowed per `sessionId + comboName`
-- if an active handoff already exists for that session/combo, no duplicate summary is generated
+- ambang batas peringatan default adalah `0.85`
+- batas keras untuk pembuatan adalah `0.95`
+- hanya satu pembuatan handoff yang sedang berjalan yang diizinkan per `sessionId + comboName`
+- jika handoff aktif sudah ada untuk sesi/combo tersebut, tidak ada ringkasan duplikat yang dihasilkan
-### 95% or more quota used
+### 95% atau lebih kuota terpakai
-No new handoff is generated. At this point the system is already in or near exhaustion and
-the runtime avoids scheduling another summary request.
+Tidak ada handoff baru yang dihasilkan. Pada titik ini sistem sudah berada dalam kondisi habis atau
+mendekati habis dan runtime menghindari penjadwalan permintaan ringkasan lain.
-### After account rotation
+### Setelah rotasi akun
-When the next request for the same session resolves to a different authenticated account,
-OmniRoute prepends the stored handoff as a system message. Injection happens only after the
-real account switch is known.
+Ketika permintaan berikutnya untuk sesi yang sama menghasilkan akun terautentikasi yang berbeda,
+OmniRoute menambahkan handoff yang tersimpan sebagai pesan sistem. Penyuntikan hanya terjadi setelah
+pergantian akun nyata diketahui.
-## Handoff Payload
+## Muatan Handoff
-The persisted handoff payload is stored in `context_handoffs` and includes:
+Muatan handoff yang dipersistenkan disimpan di `context_handoffs` dan mencakup:
- `sessionId`
- `comboName`
@@ -74,7 +74,7 @@ The persisted handoff payload is stored in `context_handoffs` and includes:
- `generatedAt`
- `expiresAt`
-The summary model is instructed to return a JSON object with this structure:
+Model ringkasan diperintahkan untuk mengembalikan objek JSON dengan struktur berikut:
```json
{
@@ -85,46 +85,46 @@ The summary model is instructed to return a JSON object with this structure:
}
```
-At injection time, OmniRoute converts that payload into a `` system
-message so the next account can continue with the correct local context.
+Pada saat penyuntikan, OmniRoute mengonversi muatan tersebut menjadi pesan sistem ``
+agar akun berikutnya dapat melanjutkan dengan konteks lokal yang benar.
## Konfigurasi
-`context-relay` supports these config fields:
+`context-relay` mendukung kolom konfigurasi berikut:
-- `handoffThreshold`: warning threshold for summary generation, default `0.85`
-- `handoffModel`: optional model override used only for summary generation
-- `handoffProviders`: allowlist of providers allowed to trigger handoff generation
+- `handoffThreshold`: ambang batas peringatan untuk pembuatan ringkasan, default `0.85`
+- `handoffModel`: penggantian model opsional yang hanya digunakan untuk pembuatan ringkasan
+- `handoffProviders`: daftar izin penyedia yang diperbolehkan memicu pembuatan handoff
-Global defaults can be configured in Settings, and combo-specific values can override them
-in the Combos page.
+Nilai default global dapat dikonfigurasi di Pengaturan, dan nilai spesifik combo dapat menggantikannya
+di halaman Combos.
-## Architectural Note
+## Catatan Arsitektur
-The current implementation does not use a standalone `handleContextRelayCombo` handler.
+Implementasi saat ini tidak menggunakan pengendali `handleContextRelayCombo` yang berdiri sendiri.
-Instead:
+Sebaliknya:
-- `open-sse/services/combo.ts` decides whether a successful turn should generate a handoff
-- `src/sse/handlers/chat.ts` injects the handoff only after authentication resolves the
- actual account used for the request
+- `open-sse/services/combo.ts` memutuskan apakah giliran yang berhasil harus menghasilkan handoff
+- `src/sse/handlers/chat.ts` menyuntikkan handoff hanya setelah autentikasi menyelesaikan
+ akun aktual yang digunakan untuk permintaan
-This split is intentional in the current codebase because the combo loop alone does not know
-whether the request stayed on the same account or actually switched accounts.
+Pemisahan ini disengaja dalam basis kode saat ini karena loop combo saja tidak mengetahui
+apakah permintaan tetap pada akun yang sama atau benar-benar berpindah akun.
-## Limitations
+## Keterbatasan
-- Effective runtime support is currently centered on `codex` quota rotation.
-- `handoffProviders` is already modeled as a config surface, but real handoff generation
- still depends on provider-specific quota plumbing.
-- The summary is intentionally compact and recent-history based; it is not a full transcript
- replay mechanism.
-- Handoffs are scoped by `sessionId + comboName` and expire automatically.
-- If the session does not switch accounts, the stored handoff is not injected.
+- Dukungan runtime yang efektif saat ini terpusat pada rotasi kuota `codex`.
+- `handoffProviders` sudah dimodelkan sebagai permukaan konfigurasi, tetapi pembuatan handoff
+ nyata masih bergantung pada jalur kuota spesifik penyedia.
+- Ringkasan secara sengaja dibuat ringkas dan berbasis riwayat terkini; ini bukan mekanisme
+ pemutaran ulang transkrip penuh.
+- Handoff dicakupkan oleh `sessionId + comboName` dan kedaluwarsa secara otomatis.
+- Jika sesi tidak berpindah akun, handoff yang tersimpan tidak disuntikkan.
-## Recommended Usage Pattern
+## Pola Penggunaan yang Disarankan
-- use multiple accounts from the same provider
-- keep stable `sessionId` values across the session
-- set `handoffThreshold` early enough to leave room for the background summary request
-- treat the feature as continuity assistance, not as a replacement for persistent memory
+- gunakan beberapa akun dari penyedia yang sama
+- pertahankan nilai `sessionId` yang stabil sepanjang sesi
+- atur `handoffThreshold` cukup awal untuk menyisakan ruang bagi permintaan ringkasan latar belakang
+- perlakukan fitur ini sebagai bantuan kesinambungan, bukan sebagai pengganti memori persisten
diff --git a/docs/i18n/id/docs/frameworks/A2A-SERVER.md b/docs/i18n/id/docs/frameworks/A2A-SERVER.md
index 808d40683c..7a83d8d8e4 100644
--- a/docs/i18n/id/docs/frameworks/A2A-SERVER.md
+++ b/docs/i18n/id/docs/frameworks/A2A-SERVER.md
@@ -1,38 +1,38 @@
-# OmniRoute A2A Server Documentation (Bahasa Indonesia)
+# Dokumentasi Server A2A OmniRoute (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/A2A-SERVER.md) · 🇸🇦 [ar](../../ar/docs/A2A-SERVER.md) · 🇧🇬 [bg](../../bg/docs/A2A-SERVER.md) · 🇧🇩 [bn](../../bn/docs/A2A-SERVER.md) · 🇨🇿 [cs](../../cs/docs/A2A-SERVER.md) · 🇩🇰 [da](../../da/docs/A2A-SERVER.md) · 🇩🇪 [de](../../de/docs/A2A-SERVER.md) · 🇪🇸 [es](../../es/docs/A2A-SERVER.md) · 🇮🇷 [fa](../../fa/docs/A2A-SERVER.md) · 🇫🇮 [fi](../../fi/docs/A2A-SERVER.md) · 🇫🇷 [fr](../../fr/docs/A2A-SERVER.md) · 🇮🇳 [gu](../../gu/docs/A2A-SERVER.md) · 🇮🇱 [he](../../he/docs/A2A-SERVER.md) · 🇮🇳 [hi](../../hi/docs/A2A-SERVER.md) · 🇭🇺 [hu](../../hu/docs/A2A-SERVER.md) · 🇮🇩 [id](../../id/docs/A2A-SERVER.md) · 🇮🇹 [it](../../it/docs/A2A-SERVER.md) · 🇯🇵 [ja](../../ja/docs/A2A-SERVER.md) · 🇰🇷 [ko](../../ko/docs/A2A-SERVER.md) · 🇮🇳 [mr](../../mr/docs/A2A-SERVER.md) · 🇲🇾 [ms](../../ms/docs/A2A-SERVER.md) · 🇳🇱 [nl](../../nl/docs/A2A-SERVER.md) · 🇳🇴 [no](../../no/docs/A2A-SERVER.md) · 🇵🇭 [phi](../../phi/docs/A2A-SERVER.md) · 🇵🇱 [pl](../../pl/docs/A2A-SERVER.md) · 🇵🇹 [pt](../../pt/docs/A2A-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/A2A-SERVER.md) · 🇷🇴 [ro](../../ro/docs/A2A-SERVER.md) · 🇷🇺 [ru](../../ru/docs/A2A-SERVER.md) · 🇸🇰 [sk](../../sk/docs/A2A-SERVER.md) · 🇸🇪 [sv](../../sv/docs/A2A-SERVER.md) · 🇰🇪 [sw](../../sw/docs/A2A-SERVER.md) · 🇮🇳 [ta](../../ta/docs/A2A-SERVER.md) · 🇮🇳 [te](../../te/docs/A2A-SERVER.md) · 🇹🇭 [th](../../th/docs/A2A-SERVER.md) · 🇹🇷 [tr](../../tr/docs/A2A-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/A2A-SERVER.md) · 🇵🇰 [ur](../../ur/docs/A2A-SERVER.md) · 🇻🇳 [vi](../../vi/docs/A2A-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/A2A-SERVER.md)
---
-> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent
+> Protokol Agent-to-Agent v0.3 — OmniRoute sebagai agen routing cerdas
-## Agent Discovery
+## Penemuan Agen
```bash
curl http://localhost:20128/.well-known/agent.json
```
-Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements.
+Mengembalikan Kartu Agen yang mendeskripsikan kemampuan, keterampilan, dan persyaratan autentikasi OmniRoute.
---
-## Authentication
+## Autentikasi
-All `/a2a` requests require an API key via the `Authorization` header:
+Semua permintaan `/a2a` memerlukan kunci API melalui header `Authorization`:
```
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
```
-If no API key is configured on the server, authentication is bypassed.
+Jika tidak ada kunci API yang dikonfigurasi di server, autentikasi akan dilewati.
---
-## JSON-RPC 2.0 Methods
+## Metode JSON-RPC 2.0
-### `message/send` — Synchronous Execution
+### `message/send` — Eksekusi Sinkron
-Sends a message to a skill and waits for the complete response.
+Mengirim pesan ke sebuah keterampilan dan menunggu respons lengkap.
```bash
curl -X POST http://localhost:20128/a2a \
@@ -50,7 +50,7 @@ curl -X POST http://localhost:20128/a2a \
}'
```
-**Response:**
+**Respons:**
```json
{
@@ -71,9 +71,9 @@ curl -X POST http://localhost:20128/a2a \
}
```
-### `message/stream` — SSE Streaming
+### `message/stream` — Streaming SSE
-Same as `message/send` but returns Server-Sent Events for real-time streaming.
+Sama seperti `message/send` tetapi mengembalikan Server-Sent Events untuk streaming secara real-time.
```bash
curl -N -X POST http://localhost:20128/a2a \
@@ -90,7 +90,7 @@ curl -N -X POST http://localhost:20128/a2a \
}'
```
-**SSE Events:**
+**Event SSE:**
```
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"..."}}}
@@ -100,7 +100,7 @@ data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","s
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
```
-### `tasks/get` — Query Task Status
+### `tasks/get` — Kueri Status Tugas
```bash
curl -X POST http://localhost:20128/a2a \
@@ -109,7 +109,7 @@ curl -X POST http://localhost:20128/a2a \
-d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}'
```
-### `tasks/cancel` — Cancel a Task
+### `tasks/cancel` — Batalkan Sebuah Tugas
```bash
curl -X POST http://localhost:20128/a2a \
@@ -120,16 +120,16 @@ curl -X POST http://localhost:20128/a2a \
---
-## Available Skills
+## Keterampilan yang Tersedia
-| Skill | Description |
-| :----------------- | :------------------------------------------------------------------------------------------------------------------------------ |
-| `smart-routing` | Routes prompts through OmniRoute's intelligent pipeline. Returns response with routing explanation, cost, and resilience trace. |
-| `quota-management` | Answers natural-language queries about provider quotas, suggests free combos, and provides quota rankings. |
+| Keterampilan | Deskripsi |
+| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `smart-routing` | Merutekan prompt melalui pipeline cerdas OmniRoute. Mengembalikan respons beserta penjelasan routing, biaya, dan jejak ketahanan. |
+| `quota-management` | Menjawab kueri bahasa alami tentang kuota penyedia, menyarankan combo gratis, dan memberikan peringkat kuota. |
---
-## Task Lifecycle
+## Siklus Hidup Tugas
```
submitted → working → completed
@@ -137,25 +137,25 @@ submitted → working → completed
→ cancelled
```
-- Tasks expire after 5 minutes (configurable)
-- Terminal states: `completed`, `failed`, `cancelled`
-- Event log tracks every state transition
+- Tugas kedaluwarsa setelah 5 menit (dapat dikonfigurasi)
+- Status terminal: `completed`, `failed`, `cancelled`
+- Log event melacak setiap transisi status
---
-## Error Codes
+## Kode Kesalahan
-| Code | Meaning |
-| :----- | :----------------------------- |
-| -32700 | Parse error (invalid JSON) |
-| -32600 | Invalid request / Unauthorized |
-| -32601 | Method or skill not found |
-| -32602 | Invalid params |
-| -32603 | Internal error |
+| Kode | Arti |
+| :----- | :-------------------------------------- |
+| -32700 | Kesalahan parse (JSON tidak valid) |
+| -32600 | Permintaan tidak valid / Tidak diotorisasi |
+| -32601 | Metode atau keterampilan tidak ditemukan |
+| -32602 | Parameter tidak valid |
+| -32603 | Kesalahan internal |
---
-## Integration Examples
+## Contoh Integrasi
### Python (requests)
diff --git a/docs/i18n/id/docs/frameworks/MCP-SERVER.md b/docs/i18n/id/docs/frameworks/MCP-SERVER.md
index 33b5c59578..1af2f02093 100644
--- a/docs/i18n/id/docs/frameworks/MCP-SERVER.md
+++ b/docs/i18n/id/docs/frameworks/MCP-SERVER.md
@@ -1,63 +1,63 @@
-# OmniRoute MCP Server Documentation (Bahasa Indonesia)
+# Dokumentasi Server MCP OmniRoute (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/MCP-SERVER.md) · 🇸🇦 [ar](../../ar/docs/MCP-SERVER.md) · 🇧🇬 [bg](../../bg/docs/MCP-SERVER.md) · 🇧🇩 [bn](../../bn/docs/MCP-SERVER.md) · 🇨🇿 [cs](../../cs/docs/MCP-SERVER.md) · 🇩🇰 [da](../../da/docs/MCP-SERVER.md) · 🇩🇪 [de](../../de/docs/MCP-SERVER.md) · 🇪🇸 [es](../../es/docs/MCP-SERVER.md) · 🇮🇷 [fa](../../fa/docs/MCP-SERVER.md) · 🇫🇮 [fi](../../fi/docs/MCP-SERVER.md) · 🇫🇷 [fr](../../fr/docs/MCP-SERVER.md) · 🇮🇳 [gu](../../gu/docs/MCP-SERVER.md) · 🇮🇱 [he](../../he/docs/MCP-SERVER.md) · 🇮🇳 [hi](../../hi/docs/MCP-SERVER.md) · 🇭🇺 [hu](../../hu/docs/MCP-SERVER.md) · 🇮🇩 [id](../../id/docs/MCP-SERVER.md) · 🇮🇹 [it](../../it/docs/MCP-SERVER.md) · 🇯🇵 [ja](../../ja/docs/MCP-SERVER.md) · 🇰🇷 [ko](../../ko/docs/MCP-SERVER.md) · 🇮🇳 [mr](../../mr/docs/MCP-SERVER.md) · 🇲🇾 [ms](../../ms/docs/MCP-SERVER.md) · 🇳🇱 [nl](../../nl/docs/MCP-SERVER.md) · 🇳🇴 [no](../../no/docs/MCP-SERVER.md) · 🇵🇭 [phi](../../phi/docs/MCP-SERVER.md) · 🇵🇱 [pl](../../pl/docs/MCP-SERVER.md) · 🇵🇹 [pt](../../pt/docs/MCP-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/MCP-SERVER.md) · 🇷🇴 [ro](../../ro/docs/MCP-SERVER.md) · 🇷🇺 [ru](../../ru/docs/MCP-SERVER.md) · 🇸🇰 [sk](../../sk/docs/MCP-SERVER.md) · 🇸🇪 [sv](../../sv/docs/MCP-SERVER.md) · 🇰🇪 [sw](../../sw/docs/MCP-SERVER.md) · 🇮🇳 [ta](../../ta/docs/MCP-SERVER.md) · 🇮🇳 [te](../../te/docs/MCP-SERVER.md) · 🇹🇭 [th](../../th/docs/MCP-SERVER.md) · 🇹🇷 [tr](../../tr/docs/MCP-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/MCP-SERVER.md) · 🇵🇰 [ur](../../ur/docs/MCP-SERVER.md) · 🇻🇳 [vi](../../vi/docs/MCP-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/MCP-SERVER.md)
---
-> Model Context Protocol server with 16 intelligent tools
+> Server Model Context Protocol dengan 16 alat cerdas
-## Instal
+## Instalasi
-OmniRoute MCP is built-in. Start it with:
+OmniRoute MCP sudah tersedia secara bawaan. Jalankan dengan:
```bash
omniroute --mcp
```
-Or via the open-sse transport:
+Atau melalui transport open-sse:
```bash
# HTTP streamable transport (port 20130)
omniroute --dev # MCP auto-starts on /mcp endpoint
```
-## IDE Configuration
+## Konfigurasi IDE
-See [IDE Configs](integrations/ide-configs.md) for Antigravity, Cursor, Copilot, and Claude Desktop setup.
+Lihat [Konfigurasi IDE](integrations/ide-configs.md) untuk pengaturan Antigravity, Cursor, Copilot, dan Claude Desktop.
---
-## Essential Tools (8)
+## Alat Esensial (8)
-| Tool | Description |
-| :------------------------------ | :--------------------------------------- |
-| `omniroute_get_health` | Gateway health, circuit breakers, uptime |
-| `omniroute_list_combos` | All configured combos with models |
-| `omniroute_get_combo_metrics` | Performance metrics for a specific combo |
-| `omniroute_switch_combo` | Switch active combo by ID/name |
-| `omniroute_check_quota` | Quota status per provider or all |
-| `omniroute_route_request` | Send a chat completion through OmniRoute |
-| `omniroute_cost_report` | Cost analytics for a time period |
-| `omniroute_list_models_catalog` | Full model catalog with capabilities |
+| Alat | Deskripsi |
+| :------------------------------ | :---------------------------------------------------------------- |
+| `omniroute_get_health` | Kesehatan gateway, pemutus sirkuit, uptime |
+| `omniroute_list_combos` | Semua combo yang dikonfigurasi beserta modelnya |
+| `omniroute_get_combo_metrics` | Metrik performa untuk combo tertentu |
+| `omniroute_switch_combo` | Ganti combo aktif berdasarkan ID/nama |
+| `omniroute_check_quota` | Status kuota per penyedia atau semua penyedia |
+| `omniroute_route_request` | Kirim penyelesaian chat melalui OmniRoute |
+| `omniroute_cost_report` | Analitik biaya untuk periode waktu tertentu |
+| `omniroute_list_models_catalog` | Katalog model lengkap beserta kemampuannya |
-## Advanced Tools (8)
+## Alat Lanjutan (8)
-| Tool | Description |
-| :--------------------------------- | :---------------------------------------------------------- |
-| `omniroute_simulate_route` | Dry-run routing simulation with fallback tree |
-| `omniroute_set_budget_guard` | Session budget with degrade/block/alert actions |
-| `omniroute_set_resilience_profile` | Apply conservative/balanced/aggressive preset |
-| `omniroute_test_combo` | Live-test all models in a combo via a real upstream request |
-| `omniroute_get_provider_metrics` | Detailed metrics for one provider |
-| `omniroute_best_combo_for_task` | Task-fitness recommendation with alternatives |
-| `omniroute_explain_route` | Explain a past routing decision |
-| `omniroute_get_session_snapshot` | Full session state: costs, tokens, errors |
+| Alat | Deskripsi |
+| :--------------------------------- | :--------------------------------------------------------------------- |
+| `omniroute_simulate_route` | Simulasi routing percobaan dengan pohon fallback |
+| `omniroute_set_budget_guard` | Anggaran sesi dengan tindakan degrade/block/alert |
+| `omniroute_set_resilience_profile` | Terapkan preset conservative/balanced/aggressive |
+| `omniroute_test_combo` | Uji langsung semua model dalam combo melalui permintaan upstream nyata |
+| `omniroute_get_provider_metrics` | Metrik terperinci untuk satu penyedia |
+| `omniroute_best_combo_for_task` | Rekomendasi kesesuaian tugas beserta alternatifnya |
+| `omniroute_explain_route` | Jelaskan keputusan routing yang lalu |
+| `omniroute_get_session_snapshot` | Status sesi lengkap: biaya, token, kesalahan |
-## Authentication
+## Autentikasi
-MCP tools are authenticated via API key scopes. Each tool requires specific scopes:
+Alat MCP diautentikasi melalui lingkup kunci API. Setiap alat memerlukan lingkup tertentu:
-| Scope | Tools |
+| Lingkup | Alat |
| :------------- | :----------------------------------------------- |
| `read:health` | get_health, get_provider_metrics |
| `read:combos` | list_combos, get_combo_metrics |
@@ -68,20 +68,20 @@ MCP tools are authenticated via API key scopes. Each tool requires specific scop
| `write:config` | set_budget_guard, set_resilience_profile |
| `read:models` | list_models_catalog, best_combo_for_task |
-## Audit Logging
+## Pencatatan Audit
-Every tool call is logged to `mcp_tool_audit` with:
+Setiap pemanggilan alat dicatat ke `mcp_tool_audit` dengan:
-- Tool name, arguments, result
-- Duration (ms), success/failure
-- API key hash, timestamp
+- Nama alat, argumen, hasil
+- Durasi (ms), berhasil/gagal
+- Hash kunci API, cap waktu
-## Files
+## Berkas
-| File | Purpose |
-| :------------------------------------------- | :------------------------------------------ |
-| `open-sse/mcp-server/server.ts` | MCP server creation + 16 tool registrations |
-| `open-sse/mcp-server/transport.ts` | Stdio + HTTP transport |
-| `open-sse/mcp-server/auth.ts` | API key + scope validation |
-| `open-sse/mcp-server/audit.ts` | Tool call audit logging |
-| `open-sse/mcp-server/tools/advancedTools.ts` | 8 advanced tool handlers |
+| Berkas | Tujuan |
+| :------------------------------------------- | :--------------------------------------------------- |
+| `open-sse/mcp-server/server.ts` | Pembuatan server MCP + pendaftaran 16 alat |
+| `open-sse/mcp-server/transport.ts` | Transportasi Stdio + HTTP |
+| `open-sse/mcp-server/auth.ts` | Validasi kunci API + lingkup |
+| `open-sse/mcp-server/audit.ts` | Pencatatan audit pemanggilan alat |
+| `open-sse/mcp-server/tools/advancedTools.ts` | 8 pengendali alat lanjutan |
diff --git a/docs/i18n/id/docs/guides/FEATURES.md b/docs/i18n/id/docs/guides/FEATURES.md
index 7860ca5d91..ba49bbd65f 100644
--- a/docs/i18n/id/docs/guides/FEATURES.md
+++ b/docs/i18n/id/docs/guides/FEATURES.md
@@ -1,270 +1,270 @@
-# OmniRoute — Dashboard Features Gallery (Bahasa Indonesia)
+# OmniRoute — Galeri Fitur Dashboard (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FEATURES.md) · 🇸🇦 [ar](../../ar/docs/FEATURES.md) · 🇧🇬 [bg](../../bg/docs/FEATURES.md) · 🇧🇩 [bn](../../bn/docs/FEATURES.md) · 🇨🇿 [cs](../../cs/docs/FEATURES.md) · 🇩🇰 [da](../../da/docs/FEATURES.md) · 🇩🇪 [de](../../de/docs/FEATURES.md) · 🇪🇸 [es](../../es/docs/FEATURES.md) · 🇮🇷 [fa](../../fa/docs/FEATURES.md) · 🇫🇮 [fi](../../fi/docs/FEATURES.md) · 🇫🇷 [fr](../../fr/docs/FEATURES.md) · 🇮🇳 [gu](../../gu/docs/FEATURES.md) · 🇮🇱 [he](../../he/docs/FEATURES.md) · 🇮🇳 [hi](../../hi/docs/FEATURES.md) · 🇭🇺 [hu](../../hu/docs/FEATURES.md) · 🇮🇩 [id](../../id/docs/FEATURES.md) · 🇮🇹 [it](../../it/docs/FEATURES.md) · 🇯🇵 [ja](../../ja/docs/FEATURES.md) · 🇰🇷 [ko](../../ko/docs/FEATURES.md) · 🇮🇳 [mr](../../mr/docs/FEATURES.md) · 🇲🇾 [ms](../../ms/docs/FEATURES.md) · 🇳🇱 [nl](../../nl/docs/FEATURES.md) · 🇳🇴 [no](../../no/docs/FEATURES.md) · 🇵🇭 [phi](../../phi/docs/FEATURES.md) · 🇵🇱 [pl](../../pl/docs/FEATURES.md) · 🇵🇹 [pt](../../pt/docs/FEATURES.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FEATURES.md) · 🇷🇴 [ro](../../ro/docs/FEATURES.md) · 🇷🇺 [ru](../../ru/docs/FEATURES.md) · 🇸🇰 [sk](../../sk/docs/FEATURES.md) · 🇸🇪 [sv](../../sv/docs/FEATURES.md) · 🇰🇪 [sw](../../sw/docs/FEATURES.md) · 🇮🇳 [ta](../../ta/docs/FEATURES.md) · 🇮🇳 [te](../../te/docs/FEATURES.md) · 🇹🇭 [th](../../th/docs/FEATURES.md) · 🇹🇷 [tr](../../tr/docs/FEATURES.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FEATURES.md) · 🇵🇰 [ur](../../ur/docs/FEATURES.md) · 🇻🇳 [vi](../../vi/docs/FEATURES.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FEATURES.md)
---
-Visual guide to every section of the OmniRoute dashboard.
+Panduan visual untuk setiap bagian dashboard OmniRoute.
---
-## 🔌 Providers
+## 🔌 Penyedia
-Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (Qoder, Qwen, Kiro). Kiro accounts include credit balance tracking — remaining credits, total allowance, and renewal date visible in Dashboard → Usage.
+Kelola koneksi penyedia AI: penyedia OAuth (Claude Code, Codex, Gemini CLI), penyedia kunci API (Groq, DeepSeek, OpenRouter), dan penyedia gratis (Qoder, Qwen, Kiro). Akun Kiro menyertakan pelacakan saldo kredit — sisa kredit, total tunjangan, dan tanggal pembaruan terlihat di Dashboard → Penggunaan.

---
-## 🎨 Combos
+## 🎨 Combo
-Create model routing combos with 13 strategies: priority, weighted, round-robin, random, least-used, cost-optimized, strict-random, auto, fill-first, p2c, lkgp, context-optimized, and **context-relay**. Each combo chains multiple models with automatic fallback and includes quick templates and readiness checks.
+Buat combo routing model dengan 13 strategi: priority, weighted, round-robin, random, least-used, cost-optimized, strict-random, auto, fill-first, p2c, lkgp, context-optimized, dan **context-relay**. Setiap combo menghubungkan beberapa model dengan fallback otomatis dan menyertakan templat cepat serta pemeriksaan kesiapan.
-Recent combo improvements:
+Peningkatan combo terbaru:
-- **Structured combo builder** — create each step by selecting provider, model, and exact account/connection
-- **Repeated provider support** — reuse the same provider many times in one combo as long as the `(provider, model, connection)` tuple is unique
-- **Combo target health** — analytics and health surfaces now distinguish individual combo targets/steps instead of collapsing everything into model strings
-- **Composite tier ordering** — `defaultTier -> fallbackTier` now influences runtime execution/fallback order for top-level combo steps
+- **Pembuat combo terstruktur** — buat setiap langkah dengan memilih penyedia, model, dan akun/koneksi yang tepat
+- **Dukungan penyedia berulang** — gunakan kembali penyedia yang sama berkali-kali dalam satu combo selama tuple `(provider, model, connection)` bersifat unik
+- **Kesehatan target combo** — analitik dan tampilan kesehatan kini membedakan target/langkah combo individual alih-alih menggabungkan semuanya ke dalam string model
+- **Urutan tingkatan komposit** — `defaultTier -> fallbackTier` kini memengaruhi urutan eksekusi/fallback saat runtime untuk langkah combo tingkat atas

---
-## 📊 Analytics
+## 📊 Analitik
-Comprehensive usage analytics with token consumption, cost estimates, activity heatmaps, weekly distribution charts, and per-provider breakdowns.
+Analitik penggunaan komprehensif dengan konsumsi token, estimasi biaya, peta panas aktivitas, grafik distribusi mingguan, dan rincian per penyedia.

---
-## 🏥 System Health
+## 🏥 Kesehatan Sistem
-Real-time monitoring: uptime, memory, version, latency percentiles (p50/p95/p99), cache statistics, provider circuit breaker states, active quota-monitored sessions, and combo target health.
+Pemantauan real-time: uptime, memori, versi, persentil latensi (p50/p95/p99), statistik cache, status circuit breaker penyedia, sesi terpantau kuota yang aktif, dan kesehatan target combo.

---
-## 🔧 Translator Playground
+## 🔧 Taman Bermain Translator
-Four modes for debugging API translations: **Playground** (format converter), **Chat Tester** (live requests), **Test Bench** (batch tests), and **Live Monitor** (real-time stream).
+Empat mode untuk men-debug terjemahan API: **Playground** (konverter format), **Chat Tester** (permintaan langsung), **Test Bench** (pengujian batch), dan **Live Monitor** (aliran real-time).

---
-## 🎮 Model Playground _(v2.0.9+)_
+## 🎮 Taman Bermain Model _(v2.0.9+)_
-Test any model directly from the dashboard. Select provider, model, and endpoint, write prompts with Monaco Editor, stream responses in real-time, abort mid-stream, and view timing metrics.
+Uji model apa pun langsung dari dashboard. Pilih penyedia, model, dan endpoint, tulis prompt dengan Monaco Editor, streaming respons secara real-time, batalkan di tengah streaming, dan lihat metrik waktu.
---
-## 🎨 Themes _(v2.0.5+)_
+## 🎨 Tema _(v2.0.5+)_
-Customizable color themes for the entire dashboard. Choose from 7 preset colors (Coral, Blue, Red, Green, Violet, Orange, Cyan) or create a custom theme by picking any hex color. Supports light, dark, and system mode.
+Tema warna yang dapat dikustomisasi untuk seluruh dashboard. Pilih dari 7 warna prasetel (Coral, Blue, Red, Green, Violet, Orange, Cyan) atau buat tema kustom dengan memilih warna hex apa pun. Mendukung mode terang, gelap, dan sistem.
---
-## ⚙️ Settings
+## ⚙️ Pengaturan
-Comprehensive settings panel with tabs:
+Panel pengaturan komprehensif dengan tab:
-- **General** — System storage, backup management (export/import database)
-- **Appearance** — Theme selector (dark/light/system), color theme presets and custom colors, health log visibility, sidebar item visibility controls
-- **Security** — API endpoint protection, custom provider blocking, IP filtering, session info
-- **Routing** — Model aliases, background task degradation
-- **Resilience** — Rate limit persistence, circuit breaker tuning, auto-disable banned accounts, provider expiration monitoring, **Context Relay** handoff threshold and summary model configuration
-- **Advanced** — Configuration overrides, configuration audit trail, fallback degradation mode
+- **Umum** — Penyimpanan sistem, manajemen cadangan (ekspor/impor database)
+- **Tampilan** — Pemilih tema (gelap/terang/sistem), prasetel tema warna dan warna kustom, visibilitas log kesehatan, kontrol visibilitas item bilah samping
+- **Keamanan** — Perlindungan endpoint API, pemblokiran penyedia kustom, pemfilteran IP, info sesi
+- **Routing** — Alias model, degradasi tugas latar belakang
+- **Ketahanan** — Persistensi batas laju, penyetelan circuit breaker, nonaktifkan akun yang diblokir secara otomatis, pemantauan kedaluwarsa penyedia, ambang batas handoff **Context Relay** dan konfigurasi model ringkasan
+- **Lanjutan** — Penimpaan konfigurasi, jejak audit konfigurasi, mode degradasi fallback

---
-## 🔧 CLI Tools
+## 🔧 Alat CLI
-One-click configuration for AI coding tools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor, and Factory Droid. Features automated config apply/reset, connection profiles, and model mapping.
+Konfigurasi satu klik untuk alat pengkodean AI: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor, dan Factory Droid. Dilengkapi penerapan/reset konfigurasi otomatis, profil koneksi, dan pemetaan model.

---
-## 🤖 CLI Agents _(v2.0.11+)_
+## 🤖 Agen CLI _(v2.0.11+)_
-Dashboard for discovering and managing CLI agents. Shows a grid of 14 built-in agents (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) with:
+Dashboard untuk menemukan dan mengelola agen CLI. Menampilkan kisi 14 agen bawaan (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) dengan:
-- **Installation status** — Installed / Not Found with version detection
-- **Protocol badges** — stdio, HTTP, etc.
-- **Custom agents** — Register any CLI tool via form (name, binary, version command, spawn args)
-- **CLI Fingerprint Matching** — Per-provider toggle to match native CLI request signatures, reducing ban risk while preserving proxy IP
+- **Status instalasi** — Terpasang / Tidak Ditemukan dengan deteksi versi
+- **Lencana protokol** — stdio, HTTP, dll.
+- **Agen kustom** — Daftarkan alat CLI apa pun melalui formulir (nama, biner, perintah versi, argumen spawn)
+- **Pencocokan Sidik Jari CLI** — Sakelar per penyedia untuk mencocokkan tanda tangan permintaan CLI asli, mengurangi risiko pemblokiran sambil mempertahankan IP proxy
---
## 🔗 Context Relay _(v3.5.5+)_
-A combo strategy that preserves session continuity when account rotation happens mid-conversation. Before the active account is exhausted, OmniRoute generates a structured handoff summary in the background. After the next request resolves to a different account, the summary is injected as a system message so the new account continues with full context.
+Strategi combo yang mempertahankan kesinambungan sesi saat rotasi akun terjadi di tengah percakapan. Sebelum akun aktif habis, OmniRoute menghasilkan ringkasan handoff terstruktur di latar belakang. Setelah permintaan berikutnya diarahkan ke akun berbeda, ringkasan disuntikkan sebagai pesan sistem sehingga akun baru melanjutkan dengan konteks penuh.
-Configurable via combo-level or global settings:
+Dapat dikonfigurasi melalui pengaturan level combo atau global:
-- **Handoff Threshold** — Quota usage percentage that triggers summary generation (default 85%)
-- **Max Messages For Summary** — How much recent history to condense
-- **Summary Model** — Optional override model for generating the handoff summary
+- **Ambang Batas Handoff** — Persentase penggunaan kuota yang memicu pembuatan ringkasan (default 85%)
+- **Maks Pesan untuk Ringkasan** — Seberapa banyak riwayat terkini yang dipadatkan
+- **Model Ringkasan** — Model penimpaan opsional untuk menghasilkan ringkasan handoff
-Currently supports Codex account rotation. See [Context Relay documentation](features/context-relay.md).
+Saat ini mendukung rotasi akun Codex. Lihat [dokumentasi Context Relay](features/context-relay.md).
---
-## 🛡️ Proxy Hardening _(v3.5.5+)_
+## 🛡️ Penguatan Proxy _(v3.5.5+)_
-Comprehensive proxy configuration enforcement across the entire request pipeline:
+Penegakan konfigurasi proxy komprehensif di seluruh pipeline permintaan:
-- **Token Health Check** — Background OAuth refresh now resolves proxy config per connection, preventing failures in proxy-required environments
-- **API Key Validation** — Provider key validation (`POST /api/providers/validate`) routes through `runWithProxyContext`, honoring provider-level and global proxy settings
-- **undici Dispatcher Fix** — Proxy dispatchers use undici's own fetch implementation instead of Node's built-in fetch, resolving `invalid onRequestStart method` errors on Node.js 22
-- **Node.js Version Detection** — Login page proactively detects incompatible Node.js versions (24+) and displays a warning banner with instructions to use Node 22 LTS
+- **Pemeriksaan Kesehatan Token** — Pembaruan OAuth latar belakang kini me-resolve konfigurasi proxy per koneksi, mencegah kegagalan di lingkungan yang memerlukan proxy
+- **Validasi Kunci API** — Validasi kunci penyedia (`POST /api/providers/validate`) diarahkan melalui `runWithProxyContext`, menghormati pengaturan proxy level penyedia dan global
+- **Perbaikan Dispatcher undici** — Dispatcher proxy menggunakan implementasi fetch milik undici sendiri alih-alih fetch bawaan Node, menyelesaikan kesalahan `invalid onRequestStart method` pada Node.js 22
+- **Deteksi Versi Node.js** — Halaman login secara proaktif mendeteksi versi Node.js yang tidak kompatibel (24+) dan menampilkan spanduk peringatan dengan instruksi untuk menggunakan Node 22 LTS
---
-## 📧 Email Privacy Masking _(v3.5.6+)_
+## 📧 Penyamaran Privasi Email _(v3.5.6+)_
-OAuth account emails are now masked in the provider dashboard (e.g. `di*****@g****.com`) to prevent accidental exposure when sharing screenshots or recording demos. The full email address remains accessible via hover tooltip (`title` attribute).
+Email akun OAuth kini disembunyikan di dashboard penyedia (mis. `di*****@g****.com`) untuk mencegah paparan tidak sengaja saat berbagi tangkapan layar atau merekam demo. Alamat email lengkap tetap dapat diakses melalui tooltip hover (atribut `title`).
---
-## 👁️ Model Visibility Toggle _(v3.5.6+)_
+## 👁️ Sakelar Visibilitas Model _(v3.5.6+)_
-The provider page model list now includes:
+Daftar model halaman penyedia kini menyertakan:
-- **Real-time search/filter bar** — Quickly find specific models
-- **Per-model visibility toggle** (👁 icon) — Hidden models are grayed out and excluded from the `/v1/models` catalog
-- **Active-count badge** (`N/M active`) — Shows at a glance how many models are enabled vs total
+- **Bilah pencarian/filter real-time** — Temukan model tertentu dengan cepat
+- **Sakelar visibilitas per model** (ikon 👁) — Model yang disembunyikan diarsir dan dikecualikan dari katalog `/v1/models`
+- **Lencana jumlah aktif** (`N/M active`) — Menampilkan sekilas berapa banyak model yang diaktifkan vs total
---
-## 🔧 OAuth Env Repair _(v3.6.1+)_
+## 🔧 Perbaikan Env OAuth _(v3.6.1+)_
-One-click "Repair env" action for OAuth providers that restores missing environment variables and fixes broken auth state. Accessible from `Dashboard → Providers → [OAuth Provider] → Repair env`. Automatically detects and repairs:
+Tindakan "Repair env" satu klik untuk penyedia OAuth yang memulihkan variabel lingkungan yang hilang dan memperbaiki status autentikasi yang rusak. Dapat diakses dari `Dashboard → Providers → [OAuth Provider] → Repair env`. Secara otomatis mendeteksi dan memperbaiki:
-- Missing OAuth client credentials
-- Corrupted env file entries
-- Backup path sanitization
+- Kredensial klien OAuth yang hilang
+- Entri file env yang rusak
+- Sanitasi jalur cadangan
---
-## 🗑️ Uninstall / Full Uninstall _(v3.6.2+)_
+## 🗑️ Uninstall / Uninstall Penuh _(v3.6.2+)_
-Clean removal scripts for all installation methods:
+Skrip penghapusan bersih untuk semua metode instalasi:
-| Command | Action |
-| ------------------------ | ----------------------------------------------------------------------------------- |
-| `npm run uninstall` | Removes the system app but **keeps your DB and configurations** in `~/.omniroute`. |
-| `npm run uninstall:full` | Removes the app AND permanently **erases all configurations, keys, and databases**. |
+| Perintah | Tindakan |
+| ------------------------ | --------------------------------------------------------------------------------------------- |
+| `npm run uninstall` | Menghapus aplikasi sistem tetapi **mempertahankan DB dan konfigurasi Anda** di `~/.omniroute`. |
+| `npm run uninstall:full` | Menghapus aplikasi DAN secara permanen **menghapus semua konfigurasi, kunci, dan database**. |
---
## 🖼️ Media _(v2.0.3+)_
-Generate images, videos, and music from the dashboard. Supports OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open, and MusicGen.
+Hasilkan gambar, video, dan musik dari dashboard. Mendukung OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open, dan MusicGen.
---
-## 📝 Request Logs
+## 📝 Log Permintaan
-Real-time request logging with filtering by provider, model, account, and API key. Shows status codes, token usage, latency, and response details.
+Pencatatan permintaan real-time dengan pemfilteran berdasarkan penyedia, model, akun, dan kunci API. Menampilkan kode status, penggunaan token, latensi, dan detail respons.

---
-## 🌐 API Endpoint
+## 🌐 Endpoint API
-Your unified API endpoint with capability breakdown: Chat Completions, Responses API, Embeddings, Image Generation, Reranking, Audio Transcription, Text-to-Speech, Moderations, and registered API keys. Cloudflare Quick Tunnel integration and cloud proxy support for remote access.
+Endpoint API terpadu Anda dengan rincian kemampuan: Chat Completions, Responses API, Embeddings, Image Generation, Reranking, Audio Transcription, Text-to-Speech, Moderations, dan kunci API yang terdaftar. Integrasi Cloudflare Quick Tunnel dan dukungan proxy cloud untuk akses jarak jauh.

---
-## 🔑 API Key Management
+## 🔑 Manajemen Kunci API
-Create, scope, and revoke API keys. Each key can be restricted to specific models/providers with full access or read-only permissions. Visual key management with usage tracking.
+Buat, batasi cakupan, dan cabut kunci API. Setiap kunci dapat dibatasi ke model/penyedia tertentu dengan izin akses penuh atau hanya baca. Manajemen kunci secara visual dengan pelacakan penggunaan.
---
-## 📋 Audit Log
+## 📋 Log Audit
-Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history.
+Pelacakan tindakan administratif dengan pemfilteran berdasarkan jenis tindakan, pelaku, target, alamat IP, dan cap waktu. Riwayat kejadian keamanan lengkap.
---
-## 🖥️ Desktop Application
+## 🖥️ Aplikasi Desktop
-Native Electron desktop app for Windows, macOS, and Linux. Run OmniRoute as a standalone application with system tray integration, offline support, auto-update, and one-click install.
+Aplikasi desktop Electron asli untuk Windows, macOS, dan Linux. Jalankan OmniRoute sebagai aplikasi mandiri dengan integrasi system tray, dukungan offline, pembaruan otomatis, dan instalasi satu klik.
-Key features:
+Fitur utama:
-- Server readiness polling (no blank screen on cold start)
-- System tray with port management
+- Polling kesiapan server (tidak ada layar kosong saat cold start)
+- System tray dengan manajemen port
- Content Security Policy
-- Single-instance lock
-- Auto-update on restart
-- Platform-conditional UI (macOS traffic lights, Windows/Linux default titlebar)
-- Hardened Electron build packaging — symlinked `node_modules` in the standalone bundle is detected and rejected before packaging, preventing runtime dependency on the build machine (v2.5.5+)
-- **Graceful shutdown** — Electron `before-quit` shuts down Next.js cleanly, preventing SQLite WAL database locks (v3.6.2+)
+- Kunci instans tunggal
+- Pembaruan otomatis saat restart
+- UI kondisional platform (lampu lalu lintas macOS, titlebar default Windows/Linux)
+- Pengemasan build Electron yang diperkuat — `node_modules` yang di-symlink dalam bundel mandiri terdeteksi dan ditolak sebelum pengemasan, mencegah ketergantungan runtime pada mesin build (v2.5.5+)
+- **Penutupan yang baik** — `before-quit` Electron menutup Next.js dengan bersih, mencegah kunci database SQLite WAL (v3.6.2+)
-📖 See [`electron/README.md`](../electron/README.md) for full documentation.
+📖 Lihat [`electron/README.md`](../electron/README.md) untuk dokumentasi lengkap.
---
-## 🌐 V1 WebSocket Bridge _(v3.6.6+)_
+## 🌐 Jembatan WebSocket V1 _(v3.6.6+)_
-OmniRoute now supports **OpenAI-compatible WebSocket clients** via the `/v1/ws` upgrade endpoint. The custom `scripts/v1-ws-bridge.mjs` server wraps Next.js and upgrades WS connections to full bidirectional streaming sessions. Authentication uses the same API key or session cookie as HTTP requests.
+OmniRoute kini mendukung **klien WebSocket yang kompatibel dengan OpenAI** melalui endpoint upgrade `/v1/ws`. Server `scripts/v1-ws-bridge.mjs` kustom membungkus Next.js dan mengupgrade koneksi WS menjadi sesi streaming dua arah penuh. Autentikasi menggunakan kunci API atau cookie sesi yang sama seperti permintaan HTTP.
-Key behaviours:
+Perilaku utama:
-- WS upgrade validated by `src/lib/ws/handshake.ts` before the connection is established
-- Streams terminated cleanly on session close or upstream error
-- Works alongside the existing HTTP+SSE streaming path simultaneously
+- Upgrade WS divalidasi oleh `src/lib/ws/handshake.ts` sebelum koneksi dibuat
+- Aliran dihentikan dengan bersih saat sesi ditutup atau terjadi kesalahan upstream
+- Berfungsi berdampingan dengan jalur streaming HTTP+SSE yang ada secara bersamaan
---
-## 🔑 Sync Tokens & Config Bundle _(v3.6.6+)_
+## 🔑 Token Sinkronisasi & Bundel Konfigurasi _(v3.6.6+)_
-Multi-device and external operator access is now possible via **scoped sync tokens**:
+Akses multi-perangkat dan operator eksternal kini dimungkinkan melalui **token sinkronisasi bercakupan**:
-- **`POST /api/sync/tokens`** — Issue a new sync token (scoped, with optional expiry)
-- **`DELETE /api/sync/tokens/:id`** — Revoke a token
-- **`GET /api/sync/bundle`** — Download a versioned, ETag-keyed JSON snapshot of all non-sensitive settings (passwords redacted)
+- **`POST /api/sync/tokens`** — Terbitkan token sinkronisasi baru (bercakupan, dengan kedaluwarsa opsional)
+- **`DELETE /api/sync/tokens/:id`** — Cabut token
+- **`GET /api/sync/bundle`** — Unduh snapshot JSON berversi dan berkey ETag dari semua pengaturan tidak sensitif (kata sandi disunting)
-The config bundle is built by `src/lib/sync/bundle.ts`. Consumers compare the `ETag` response header to detect changes without re-downloading the full payload.
+Bundel konfigurasi dibuat oleh `src/lib/sync/bundle.ts`. Konsumen membandingkan header respons `ETag` untuk mendeteksi perubahan tanpa mengunduh ulang payload penuh.
---
-## 🧠 GLM Thinking Preset _(v3.6.6+)_
+## 🧠 Prasetel GLM Thinking _(v3.6.6+)_
-**GLM Thinking (`glmt`)** is now a registered first-class provider: 65 536 max output tokens, 24 576 thinking budget, 900 s default timeout, Claude-compatible API format, and shared usage sync with the GLM family.
+**GLM Thinking (`glmt`)** kini merupakan penyedia kelas pertama yang terdaftar: 65 536 token output maksimum, anggaran thinking 24 576, timeout default 900 detik, format API yang kompatibel dengan Claude, dan sinkronisasi penggunaan bersama dengan keluarga GLM.
-**Hybrid token counting** also lands in v3.6.6: when a Claude-compatible provider exposes `/messages/count_tokens`, OmniRoute calls it before large requests with graceful estimation fallback.
+**Penghitungan token hibrida** juga hadir di v3.6.6: ketika penyedia yang kompatibel dengan Claude mengekspos `/messages/count_tokens`, OmniRoute memanggilnya sebelum permintaan besar dengan fallback estimasi yang baik.
---
-## 🛡️ Safe Outbound Fetch & SSRF Guard _(v3.6.6+)_
+## 🛡️ Fetch Keluar Aman & Penjaga SSRF _(v3.6.6+)_
-All provider validation and model discovery calls now go through a two-layer outbound guard:
+Semua panggilan validasi penyedia dan penemuan model kini melewati penjaga keluar dua lapis:
-1. **URL guard** (`src/shared/network/outboundUrlGuard.ts`) — Blocks private/loopback/link-local IP ranges before the socket is opened.
-2. **Safe fetch wrapper** (`src/shared/network/safeOutboundFetch.ts`) — Applies the URL guard, normalises timeouts, and retries transient errors with exponential backoff.
+1. **Penjaga URL** (`src/shared/network/outboundUrlGuard.ts`) — Memblokir rentang IP privat/loopback/link-local sebelum soket dibuka.
+2. **Pembungkus fetch aman** (`src/shared/network/safeOutboundFetch.ts`) — Menerapkan penjaga URL, menormalkan timeout, dan mencoba ulang kesalahan transien dengan backoff eksponensial.
-Guard violations surface as HTTP 422 (`URL_GUARD_BLOCKED`) and are written to the compliance audit log via `providerAudit.ts`.
+Pelanggaran penjaga muncul sebagai HTTP 422 (`URL_GUARD_BLOCKED`) dan ditulis ke log audit kepatuhan melalui `providerAudit.ts`.
---
-## 🔄 Cooldown-Aware Retries _(v3.6.6+)_
+## 🔄 Percobaan Ulang yang Mempertimbangkan Cooldown _(v3.6.6+)_
-Chat requests now **automatically retry** when an upstream provider returns a model-scoped cooldown. Configurable via `REQUEST_RETRY` (default: 2) and `MAX_RETRY_INTERVAL_SEC` (default: 30 s). Rate-limit header learning improved across `x-ratelimit-reset-requests`, `x-ratelimit-reset-tokens`, and `Retry-After` — per-model cooldown state is visible in the Resilience dashboard.
+Permintaan chat kini **secara otomatis mencoba ulang** ketika penyedia upstream mengembalikan cooldown bercakupan model. Dapat dikonfigurasi melalui `REQUEST_RETRY` (default: 2) dan `MAX_RETRY_INTERVAL_SEC` (default: 30 detik). Pembelajaran header batas laju yang ditingkatkan di seluruh `x-ratelimit-reset-requests`, `x-ratelimit-reset-tokens`, dan `Retry-After` — status cooldown per model terlihat di dashboard Ketahanan.
---
-## 📋 Compliance Audit v2 _(v3.6.6+)_
+## 📋 Audit Kepatuhan v2 _(v3.6.6+)_
-The audit log has been expanded with cursor-based pagination, request context enrichment (request ID, user agent, IP), structured auth events, provider CRUD events with diff context, and SSRF-blocked validation logging. New events emitted by `src/lib/compliance/providerAudit.ts`.
+Log audit telah diperluas dengan paginasi berbasis kursor, pengayaan konteks permintaan (ID permintaan, user agent, IP), kejadian autentikasi terstruktur, kejadian CRUD penyedia dengan konteks diff, dan pencatatan validasi yang diblokir SSRF. Kejadian baru dipancarkan oleh `src/lib/compliance/providerAudit.ts`.
diff --git a/docs/i18n/id/docs/guides/I18N.md b/docs/i18n/id/docs/guides/I18N.md
index 910370dcae..efd27f4fa3 100644
--- a/docs/i18n/id/docs/guides/I18N.md
+++ b/docs/i18n/id/docs/guides/I18N.md
@@ -1,77 +1,77 @@
-# i18n — Internationalization Guide (Bahasa Indonesia)
+# i18n — Panduan Internasionalisasi (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/I18N.md) · 🇸🇦 [ar](../../ar/docs/I18N.md) · 🇧🇬 [bg](../../bg/docs/I18N.md) · 🇧🇩 [bn](../../bn/docs/I18N.md) · 🇨🇿 [cs](../../cs/docs/I18N.md) · 🇩🇰 [da](../../da/docs/I18N.md) · 🇩🇪 [de](../../de/docs/I18N.md) · 🇪🇸 [es](../../es/docs/I18N.md) · 🇮🇷 [fa](../../fa/docs/I18N.md) · 🇫🇮 [fi](../../fi/docs/I18N.md) · 🇫🇷 [fr](../../fr/docs/I18N.md) · 🇮🇳 [gu](../../gu/docs/I18N.md) · 🇮🇱 [he](../../he/docs/I18N.md) · 🇮🇳 [hi](../../hi/docs/I18N.md) · 🇭🇺 [hu](../../hu/docs/I18N.md) · 🇮🇩 [id](../../id/docs/I18N.md) · 🇮🇹 [it](../../it/docs/I18N.md) · 🇯🇵 [ja](../../ja/docs/I18N.md) · 🇰🇷 [ko](../../ko/docs/I18N.md) · 🇮🇳 [mr](../../mr/docs/I18N.md) · 🇲🇾 [ms](../../ms/docs/I18N.md) · 🇳🇱 [nl](../../nl/docs/I18N.md) · 🇳🇴 [no](../../no/docs/I18N.md) · 🇵🇭 [phi](../../phi/docs/I18N.md) · 🇵🇱 [pl](../../pl/docs/I18N.md) · 🇵🇹 [pt](../../pt/docs/I18N.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/I18N.md) · 🇷🇴 [ro](../../ro/docs/I18N.md) · 🇷🇺 [ru](../../ru/docs/I18N.md) · 🇸🇰 [sk](../../sk/docs/I18N.md) · 🇸🇪 [sv](../../sv/docs/I18N.md) · 🇰🇪 [sw](../../sw/docs/I18N.md) · 🇮🇳 [ta](../../ta/docs/I18N.md) · 🇮🇳 [te](../../te/docs/I18N.md) · 🇹🇭 [th](../../th/docs/I18N.md) · 🇹🇷 [tr](../../tr/docs/I18N.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/I18N.md) · 🇵🇰 [ur](../../ur/docs/I18N.md) · 🇻🇳 [vi](../../vi/docs/I18N.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/I18N.md)
---
-OmniRoute supports **30 languages** with full dashboard UI translation, translated documentation, and RTL support for Arabic and Hebrew.
+OmniRoute mendukung **30 bahasa** dengan terjemahan UI dashboard penuh, dokumentasi yang diterjemahkan, dan dukungan RTL untuk bahasa Arab dan Ibrani.
-## Quick Reference
+## Referensi Cepat
-| Task | Command |
-| ---------------------- | --------------------------------------------------------------------------------------- |
-| Generate translations | `node scripts/i18n/generate-multilang.mjs messages` |
-| Translate docs (LLM) | `python3 scripts/i18n_autotranslate.py --api-url --api-key --model ` |
-| Validate a locale | `python3 scripts/validate_translation.py quick -l cs` |
-| Check code keys | `python3 scripts/check_translations.py` |
-| Generate QA report | `node scripts/i18n/generate-qa-checklist.mjs` |
-| Visual QA (Playwright) | `node scripts/i18n/run-visual-qa.mjs` |
+| Tugas | Perintah |
+| ------------------------------ | --------------------------------------------------------------------------------------- |
+| Hasilkan terjemahan | `node scripts/i18n/generate-multilang.mjs messages` |
+| Terjemahkan dokumentasi (LLM) | `python3 scripts/i18n_autotranslate.py --api-url --api-key --model ` |
+| Validasi lokal | `python3 scripts/validate_translation.py quick -l cs` |
+| Periksa kunci kode | `python3 scripts/check_translations.py` |
+| Hasilkan laporan QA | `node scripts/i18n/generate-qa-checklist.mjs` |
+| QA Visual (Playwright) | `node scripts/i18n/run-visual-qa.mjs` |
## Arsitektur
-### Source of Truth
+### Sumber Kebenaran
-- **UI strings**: `src/i18n/messages/en.json` (English source, ~2800 keys)
-- **Locale files**: `src/i18n/messages/{locale}.json` (30 translations)
-- **Framework**: `next-intl` with cookie-based locale resolution
-- **Config**: `src/i18n/config.ts` — defines all 30 locales, language names, flags
+- **String UI**: `src/i18n/messages/en.json` (sumber bahasa Inggris, ~2800 kunci)
+- **File lokal**: `src/i18n/messages/{locale}.json` (30 terjemahan)
+- **Framework**: `next-intl` dengan resolusi lokal berbasis cookie
+- **Konfigurasi**: `src/i18n/config.ts` — mendefinisikan semua 30 lokal, nama bahasa, bendera
-### Runtime Flow
+### Alur Runtime
-1. User selects language → `NEXT_LOCALE` cookie set
-2. `src/i18n/request.ts` resolves locale: cookie → `Accept-Language` header → fallback `en`
-3. Dynamic import loads `messages/{locale}.json`
-4. Components use `useTranslations("namespace")` and `t("key")`
+1. Pengguna memilih bahasa → cookie `NEXT_LOCALE` disetel
+2. `src/i18n/request.ts` menyelesaikan lokal: cookie → header `Accept-Language` → fallback `en`
+3. Import dinamis memuat `messages/{locale}.json`
+4. Komponen menggunakan `useTranslations("namespace")` dan `t("key")`
-### Supported Locales
+### Lokal yang Didukung
-| Code | Language | RTL | Google Translate Code |
+| Kode | Bahasa | RTL | Kode Google Translate |
| ------- | -------------------- | --- | --------------------- |
-| `ar` | العربية | Yes | `ar` |
-| `bg` | Български | No | `bg` |
-| `cs` | Čeština | No | `cs` |
-| `da` | Dansk | No | `da` |
-| `de` | Deutsch | No | `de` |
-| `es` | Español | No | `es` |
-| `fi` | Suomi | No | `fi` |
-| `fr` | Français | No | `fr` |
-| `he` | עברית | Yes | `iw` |
-| `hi` | हिन्दी | No | `hi` |
-| `hu` | Magyar | No | `hu` |
-| `id` | Bahasa Indonesia | No | `id` |
-| `it` | Italiano | No | `it` |
-| `ja` | 日本語 | No | `ja` |
-| `ko` | 한국어 | No | `ko` |
-| `ms` | Bahasa Melayu | No | `ms` |
-| `nl` | Nederlands | No | `nl` |
-| `no` | Norsk | No | `no` |
-| `phi` | Filipino | No | `tl` |
-| `pl` | Polski | No | `pl` |
-| `pt` | Português (Portugal) | No | `pt` |
-| `pt-BR` | Português (Brasil) | No | `pt` |
-| `ro` | Română | No | `ro` |
-| `ru` | Русский | No | `ru` |
-| `sk` | Slovenčina | No | `sk` |
-| `sv` | Svenska | No | `sv` |
-| `th` | ไทย | No | `th` |
-| `tr` | Türkçe | No | `tr` |
-| `uk-UA` | Українська | No | `uk` |
-| `vi` | Tiếng Việt | No | `vi` |
-| `zh-CN` | 中文 (简体) | No | `zh-CN` |
+| `ar` | العربية | Ya | `ar` |
+| `bg` | Български | Tidak | `bg` |
+| `cs` | Čeština | Tidak | `cs` |
+| `da` | Dansk | Tidak | `da` |
+| `de` | Deutsch | Tidak | `de` |
+| `es` | Español | Tidak | `es` |
+| `fi` | Suomi | Tidak | `fi` |
+| `fr` | Français | Tidak | `fr` |
+| `he` | עברית | Ya | `iw` |
+| `hi` | हिन्दी | Tidak | `hi` |
+| `hu` | Magyar | Tidak | `hu` |
+| `id` | Bahasa Indonesia | Tidak | `id` |
+| `it` | Italiano | Tidak | `it` |
+| `ja` | 日本語 | Tidak | `ja` |
+| `ko` | 한국어 | Tidak | `ko` |
+| `ms` | Bahasa Melayu | Tidak | `ms` |
+| `nl` | Nederlands | Tidak | `nl` |
+| `no` | Norsk | Tidak | `no` |
+| `phi` | Filipino | Tidak | `tl` |
+| `pl` | Polski | Tidak | `pl` |
+| `pt` | Português (Portugal) | Tidak | `pt` |
+| `pt-BR` | Português (Brasil) | Tidak | `pt` |
+| `ro` | Română | Tidak | `ro` |
+| `ru` | Русский | Tidak | `ru` |
+| `sk` | Slovenčina | Tidak | `sk` |
+| `sv` | Svenska | Tidak | `sv` |
+| `th` | ไทย | Tidak | `th` |
+| `tr` | Türkçe | Tidak | `tr` |
+| `uk-UA` | Українська | Tidak | `uk` |
+| `vi` | Tiếng Việt | Tidak | `vi` |
+| `zh-CN` | 中文 (简体) | Tidak | `zh-CN` |
-## Adding a New Language
+## Menambahkan Bahasa Baru
-### 1. Register the Locale
+### 1. Daftarkan Lokal
Edit `src/i18n/config.ts`:
@@ -82,9 +82,9 @@ Edit `src/i18n/config.ts`:
{ code: "xx", label: "XX", name: "Language Name", flag: "🏳️" },
```
-### 2. Add to Generator
+### 2. Tambahkan ke Generator
-Edit `scripts/i18n/generate-multilang.mjs` — add entry to `LOCALE_SPECS`:
+Edit `scripts/i18n/generate-multilang.mjs` — tambahkan entri ke `LOCALE_SPECS`:
```js
{
@@ -98,70 +98,70 @@ Edit `scripts/i18n/generate-multilang.mjs` — add entry to `LOCALE_SPECS`:
},
```
-### 3. Generate Initial Translation
+### 3. Hasilkan Terjemahan Awal
```bash
node scripts/i18n/generate-multilang.mjs messages
```
-This creates `src/i18n/messages/xx.json` auto-translated from `en.json` via Google Translate.
+Perintah ini membuat `src/i18n/messages/xx.json` yang diterjemahkan secara otomatis dari `en.json` melalui Google Translate.
-### 4. Review & Fix Auto-Translations
+### 4. Tinjau & Perbaiki Terjemahan Otomatis
-Auto-translations are a starting point. Review manually for:
+Terjemahan otomatis hanyalah titik awal. Tinjau secara manual untuk:
-- Technical accuracy
-- Context-appropriate terminology
-- Proper handling of placeholders (`{count}`, `{value}`, etc.)
+- Ketepatan teknis
+- Terminologi yang sesuai konteks
+- Penanganan placeholder yang benar (`{count}`, `{value}`, dll.)
-### 5. Validate
+### 5. Validasi
```bash
python3 scripts/validate_translation.py quick -l xx
python3 scripts/validate_translation.py diff common -l xx
```
-### 6. Generate Translated Documentation
+### 6. Hasilkan Dokumentasi yang Diterjemahkan
```bash
node scripts/i18n/generate-multilang.mjs docs
```
-## Auto-Translation Pipeline
+## Pipeline Terjemahan Otomatis
### generate-multilang.mjs (Google Translate)
-**Primary auto-translation engine** — uses Google Translate free API to generate translations for UI strings, READMEs, and documentation.
+**Mesin terjemahan otomatis utama** — menggunakan API gratis Google Translate untuk menghasilkan terjemahan string UI, README, dan dokumentasi.
```bash
node scripts/i18n/generate-multilang.mjs [messages|readme|docs|all]
```
-| Mode | What it does |
+| Mode | Yang dilakukan |
| ---------- | ----------------------------------------------------------------------------- |
-| `messages` | Translates missing keys in `src/i18n/messages/{locale}.json` from `en.json` |
-| `readme` | Translates `README.md` into all locales as `README.{code}.md` in project root |
-| `docs` | Translates `DOC_SOURCE_FILES` into `docs/i18n/{locale}/{docName}` |
-| `all` | Runs all three modes |
+| `messages` | Menerjemahkan kunci yang hilang di `src/i18n/messages/{locale}.json` dari `en.json` |
+| `readme` | Menerjemahkan `README.md` ke semua lokal sebagai `README.{code}.md` di root proyek |
+| `docs` | Menerjemahkan `DOC_SOURCE_FILES` ke `docs/i18n/{locale}/{docName}` |
+| `all` | Menjalankan ketiga mode sekaligus |
-**Features:**
+**Fitur:**
-- **Text protection**: Masks code blocks (` ``` `), inline code (`` ` ``), markdown links/images (`[text](url)`), HTML tags, tables, and ICU placeholders (`{count}`, `{value}`, `{total}`, etc.) before translation, then restores them
-- **Chunked batching**: Joins multiple strings with `__OMNIROUTE_I18N_SEPARATOR__` delimiters to minimize API calls (max 1800 chars per request)
-- **In-memory cache**: Avoids redundant API calls for repeated strings within a session
-- **Retry logic**: Exponential backoff (up to 5 attempts with 300ms × attempt delay) for 429/5xx errors
-- **Timeout**: 20 seconds per request
-- **Skip existing**: If target file already exists, it is NOT overwritten
+- **Perlindungan teks**: Menyembunyikan blok kode (` ``` `), kode inline (`` ` ``), tautan/gambar markdown (`[text](url)`), tag HTML, tabel, dan placeholder ICU (`{count}`, `{value}`, `{total}`, dll.) sebelum penerjemahan, lalu memulihkannya
+- **Pemrosesan bertahap**: Menggabungkan beberapa string dengan pemisah `__OMNIROUTE_I18N_SEPARATOR__` untuk meminimalkan panggilan API (maks 1800 karakter per permintaan)
+- **Cache dalam memori**: Menghindari panggilan API yang redundan untuk string yang berulang dalam satu sesi
+- **Logika percobaan ulang**: Backoff eksponensial (hingga 5 percobaan dengan penundaan 300ms × percobaan) untuk error 429/5xx
+- **Batas waktu**: 20 detik per permintaan
+- **Lewati yang sudah ada**: Jika file target sudah ada, file tersebut TIDAK akan ditimpa
-**Important behaviors:**
+**Perilaku penting:**
-- `docs/i18n/README.md` is **regenerated** each run — it's an auto-generated index of all docs
-- Root `README.{code}.md` files are only created if they don't exist (skips locales in `EXISTING_README_CODES`)
-- Language bars (`🌐 **Languages:** ...`) are automatically inserted/updated in all translated docs
+- `docs/i18n/README.md` **dihasilkan ulang** setiap kali dijalankan — ini adalah indeks dokumentasi yang dibuat otomatis
+- File `README.{code}.md` di root hanya dibuat jika belum ada (melewati lokal yang ada di `EXISTING_README_CODES`)
+- Bilah bahasa (`🌐 **Languages:** ...`) disisipkan/diperbarui secara otomatis di semua dokumen yang diterjemahkan
-### i18n_autotranslate.py (LLM-based)
+### i18n_autotranslate.py (berbasis LLM)
-**Secondary translator** — uses any OpenAI-compatible LLM API (including OmniRoute itself) to translate existing `docs/i18n/` markdown files. Best for polishing or re-translating docs with better quality than Google Translate.
+**Penerjemah sekunder** — menggunakan API LLM yang kompatibel dengan OpenAI (termasuk OmniRoute sendiri) untuk menerjemahkan file markdown `docs/i18n/` yang sudah ada. Paling baik digunakan untuk menyempurnakan atau menerjemahkan ulang dokumen dengan kualitas yang lebih baik dari Google Translate.
```bash
python3 scripts/i18n_autotranslate.py \
@@ -170,18 +170,18 @@ python3 scripts/i18n_autotranslate.py \
--model gpt-4o
```
-**Features:**
+**Fitur:**
-- Scans `docs/i18n/` markdown files for English paragraphs
-- Skips code blocks, tables, and already-translated content
-- Sends paragraphs to LLM with technical translation system prompt
-- Supports all 30 languages
+- Memindai file markdown `docs/i18n/` untuk paragraf berbahasa Inggris
+- Melewati blok kode, tabel, dan konten yang sudah diterjemahkan
+- Mengirimkan paragraf ke LLM dengan prompt sistem penerjemahan teknis
+- Mendukung semua 30 bahasa
-## Validation & QA
+## Validasi & QA
### validate_translation.py
-**Translation validator** — compares any locale JSON against `en.json` and reports issues.
+**Validator terjemahan** — membandingkan JSON lokal mana pun dengan `en.json` dan melaporkan masalah yang ditemukan.
```bash
# Quick check (counts only)
@@ -205,26 +205,26 @@ python3 scripts/validate_translation.py md -l cs > report.md
python3 scripts/validate_translation.py -l cs
```
-**Detects:**
+**Yang dideteksi:**
-- **Missing keys** — keys in `en.json` but not in locale file
-- **Extra keys** — keys in locale file but not in `en.json`
-- **Untranslated keys** — keys where locale value equals English source (excluding allowlist)
-- **Placeholder mismatches** — ICU placeholders that don't match between source and translation
+- **Kunci yang hilang** — kunci yang ada di `en.json` tetapi tidak ada di file lokal
+- **Kunci tambahan** — kunci yang ada di file lokal tetapi tidak ada di `en.json`
+- **Kunci yang belum diterjemahkan** — kunci yang nilai lokalnya sama dengan sumber bahasa Inggris (tidak termasuk daftar yang diizinkan)
+- **Ketidaksesuaian placeholder** — placeholder ICU yang tidak cocok antara sumber dan terjemahan
-**Exit codes:**
-| Code | Meaning |
-|------|---------|
+**Kode keluar:**
+| Kode | Makna |
+|------|-------|
| 0 | OK |
-| 1 | Generic error |
-| 2 | Missing strings (hard error) |
-| 3 | Untranslated warning (soft) |
+| 1 | Error umum |
+| 2 | String yang hilang (error kritis) |
+| 3 | Peringatan belum diterjemahkan (lunak) |
-**Environment:** Set `TRANSLATION_LANG=cs` or use `-l cs` flag.
+**Lingkungan:** Setel `TRANSLATION_LANG=cs` atau gunakan flag `-l cs`.
### check_translations.py
-**Code-to-JSON key checker** — scans `src/**/*.tsx` and `src/**/*.ts` for `useTranslations()` calls and verifies all referenced keys exist in `en.json`.
+**Pemeriksa kunci kode ke JSON** — memindai `src/**/*.tsx` dan `src/**/*.ts` untuk panggilan `useTranslations()` dan memverifikasi bahwa semua kunci yang direferensikan ada di `en.json`.
```bash
# Basic check
@@ -239,25 +239,25 @@ python3 scripts/check_translations.py --fix
### generate-qa-checklist.mjs
-**Static analysis QA** — scans Next.js page files for i18n risk metrics and generates a Markdown report.
+**QA analisis statis** — memindai file halaman Next.js untuk metrik risiko i18n dan menghasilkan laporan Markdown.
```bash
node scripts/i18n/generate-qa-checklist.mjs
```
-**Checks:**
+**Yang diperiksa:**
-- Fixed-width class usage (overflow risk)
-- Directional left/right classes (RTL risk)
-- Clipping-prone patterns
-- Locale parity (missing/extra keys vs `en.json`)
-- README language selector bars in priority locales (`es`, `fr`, `de`, `ja`, `ar`)
+- Penggunaan kelas lebar tetap (risiko overflow)
+- Kelas arah kiri/kanan (risiko RTL)
+- Pola rentan terpotong
+- Paritas lokal (kunci yang hilang/tambahan vs `en.json`)
+- Bilah pemilih bahasa README di lokal prioritas (`es`, `fr`, `de`, `ja`, `ar`)
-**Output:** `docs/reports/i18n-qa-checklist-{date}.md`
+**Keluaran:** `docs/reports/i18n-qa-checklist-{date}.md`
### run-visual-qa.mjs
-**Visual QA via Playwright** — takes screenshots of all dashboard routes in multiple locales and viewports, then evaluates page health.
+**QA visual melalui Playwright** — mengambil tangkapan layar semua rute dashboard dalam beberapa lokal dan viewport, lalu mengevaluasi kesehatan halaman.
```bash
# Default: es, fr, de, ja, ar on localhost:20128
@@ -270,21 +270,21 @@ QA_BASE_URL=http://staging.example.com QA_LOCALES=de,fr node scripts/i18n/run-vi
QA_ROUTES=/dashboard/settings,/dashboard/providers node scripts/i18n/run-visual-qa.mjs
```
-**Detects:**
+**Yang dideteksi:**
-- Text overflow
-- Element clipping
-- RTL layout mismatches
+- Teks yang meluap (text overflow)
+- Elemen yang terpotong
+- Ketidaksesuaian tata letak RTL
-**Output:** `docs/reports/i18n-visual-qa-{date}.md` + JSON report
+**Keluaran:** `docs/reports/i18n-visual-qa-{date}.md` + laporan JSON
-## Managing Untranslatable Keys
+## Mengelola Kunci yang Tidak Dapat Diterjemahkan
### untranslatable-keys.json
**File:** `scripts/i18n/untranslatable-keys.json`
-Allowlist of keys that should remain identical to English source. Used by `validate_translation.py` to avoid false-positive "untranslated" warnings.
+Daftar yang diizinkan berisi kunci yang harus tetap identik dengan sumber bahasa Inggris. Digunakan oleh `validate_translation.py` untuk menghindari peringatan "belum diterjemahkan" yang merupakan positif palsu.
```json
{
@@ -298,26 +298,26 @@ Allowlist of keys that should remain identical to English source. Used by `valid
}
```
-**What belongs here:**
+**Yang termasuk di sini:**
-- Brand/product names: `landing.brandName`, `common.social-github`
-- Technical terms/acronyms: `health.cpu`, `mcpDashboard.pid`, `settings.ai`
-- ICU/format strings: `apiManager.modelsCount`, `health.millisecondsShort`
-- Placeholder values: `providers.openaiBaseUrlPlaceholder`, `cliTools.baseUrlPlaceholder`
-- Protocol names: `common.http`, `common.oauth`, `providers.oauth2Label`
-- Navigation sections: `sidebar.primarySection`, `sidebar.cliSection`
+- Nama merek/produk: `landing.brandName`, `common.social-github`
+- Istilah teknis/akronim: `health.cpu`, `mcpDashboard.pid`, `settings.ai`
+- String ICU/format: `apiManager.modelsCount`, `health.millisecondsShort`
+- Nilai placeholder: `providers.openaiBaseUrlPlaceholder`, `cliTools.baseUrlPlaceholder`
+- Nama protokol: `common.http`, `common.oauth`, `providers.oauth2Label`
+- Bagian navigasi: `sidebar.primarySection`, `sidebar.cliSection`
-**To add a key:** Edit the `keys` array in `scripts/i18n/untranslatable-keys.json` and re-run validation.
+**Untuk menambahkan kunci:** Edit array `keys` di `scripts/i18n/untranslatable-keys.json` dan jalankan ulang validasi.
-## CI Integration
+## Integrasi CI
### GitHub Actions (`.github/workflows/ci.yml`)
-The CI pipeline validates all locales on every push and PR:
+Pipeline CI memvalidasi semua lokal pada setiap push dan PR:
-1. **`i18n-matrix` job** — dynamically discovers all locale files (excluding `en.json`)
-2. **`i18n` job** — runs `validate_translation.py quick -l ''` for each locale in parallel
-3. **`ci-summary` job** — aggregates results into a dashboard summary
+1. **Job `i18n-matrix`** — secara dinamis menemukan semua file lokal (tidak termasuk `en.json`)
+2. **Job `i18n`** — menjalankan `validate_translation.py quick -l ''` untuk setiap lokal secara paralel
+3. **Job `ci-summary`** — mengagregasi hasil menjadi ringkasan dashboard
```yaml
# i18n-matrix: discovers languages
@@ -327,7 +327,7 @@ LANGS=$(ls src/i18n/messages/*.json | xargs -n1 basename | sed 's/.json$//' | gr
python3 scripts/validate_translation.py quick -l '${{ matrix.lang }}'
```
-**Dashboard output:**
+**Keluaran dashboard:**
```
## 🌍 Translations
@@ -339,63 +339,63 @@ python3 scripts/validate_translation.py quick -l '${{ matrix.lang }}'
✅ All translations complete
```
-## File Structure
+## Struktur File
```
src/i18n/
-├── config.ts # Locale definitions (30 locales, RTL config)
-├── request.ts # Runtime locale resolution
+├── config.ts # Definisi lokal (30 lokal, konfigurasi RTL)
+├── request.ts # Resolusi lokal saat runtime
└── messages/
- ├── en.json # Source of truth (~2800 keys)
- ├── cs.json # Czech translation
- ├── de.json # German translation
- └── ... # 30 locale files total
+ ├── en.json # Sumber kebenaran (~2800 kunci)
+ ├── cs.json # Terjemahan bahasa Ceko
+ ├── de.json # Terjemahan bahasa Jerman
+ └── ... # Total 30 file lokal
scripts/
├── i18n/
-│ ├── generate-multilang.mjs # Auto-translation engine (Google Translate, 888 lines)
-│ ├── generate-qa-checklist.mjs # Static analysis QA
-│ ├── run-visual-qa.mjs # Playwright visual QA
-│ └── untranslatable-keys.json # Allowlist for validation (236 keys)
-├── validate_translation.py # Translation validator
-├── check_translations.py # Code-to-JSON key checker
-└── i18n_autotranslate.py # LLM-based doc translator
+│ ├── generate-multilang.mjs # Mesin terjemahan otomatis (Google Translate, 888 baris)
+│ ├── generate-qa-checklist.mjs # QA analisis statis
+│ ├── run-visual-qa.mjs # QA visual Playwright
+│ └── untranslatable-keys.json # Daftar yang diizinkan untuk validasi (236 kunci)
+├── validate_translation.py # Validator terjemahan
+├── check_translations.py # Pemeriksa kunci kode ke JSON
+└── i18n_autotranslate.py # Penerjemah dokumentasi berbasis LLM
.github/workflows/
-└── ci.yml # i18n validation in CI matrix
+└── ci.yml # Validasi i18n dalam matriks CI
docs/
-├── I18N.md # This file — i18n toolchain documentation
+├── I18N.md # File ini — dokumentasi toolchain i18n
├── i18n/
-│ ├── README.md # Auto-generated language index
-│ ├── cs/ # Czech docs
+│ ├── README.md # Indeks bahasa yang dibuat otomatis
+│ ├── cs/ # Dokumentasi bahasa Ceko
│ │ └── docs/
-│ │ ├── I18N.md # Czech translation of this file
+│ │ ├── I18N.md # Terjemahan bahasa Ceko dari file ini
│ │ └── ...
-│ ├── de/ # German docs
-│ └── ... # 30 locale directories
+│ ├── de/ # Dokumentasi bahasa Jerman
+│ └── ... # 30 direktori lokal
└── reports/
- ├── i18n-qa-checklist-*.md # Static analysis reports
- └── i18n-visual-qa-*.md # Visual QA reports
+ ├── i18n-qa-checklist-*.md # Laporan analisis statis
+ └── i18n-visual-qa-*.md # Laporan QA visual
```
-## Best Practices
+## Praktik Terbaik
-### When Editing Translations
+### Saat Mengedit Terjemahan
-1. **Always edit `en.json` first** — it's the source of truth
-2. **Run `generate-multilang.mjs messages`** to propagate new keys to all locales
-3. **Review auto-translations** — Google Translate is a starting point, not final
-4. **Validate before committing** — `python3 scripts/validate_translation.py quick -l `
-5. **Update `untranslatable-keys.json`** if a key should remain in English
+1. **Selalu edit `en.json` terlebih dahulu** — itulah sumber kebenaran
+2. **Jalankan `generate-multilang.mjs messages`** untuk menyebarkan kunci baru ke semua lokal
+3. **Tinjau terjemahan otomatis** — Google Translate hanyalah titik awal, bukan hasil akhir
+4. **Validasi sebelum melakukan commit** — `python3 scripts/validate_translation.py quick -l `
+5. **Perbarui `untranslatable-keys.json`** jika sebuah kunci harus tetap dalam bahasa Inggris
-### Placeholder Safety
+### Keamanan Placeholder
-- ICU placeholders (`{count}`, `{value}`, `{total}`, `{seconds}`) must be preserved exactly
-- Plural formats (`{count, plural, one {# model} other {# models}}`) must maintain structure
-- The validator detects placeholder mismatches automatically
+- Placeholder ICU (`{count}`, `{value}`, `{total}`, `{seconds}`) harus dipertahankan persis sama
+- Format jamak (`{count, plural, one {# model} other {# models}}`) harus mempertahankan strukturnya
+- Validator mendeteksi ketidaksesuaian placeholder secara otomatis
-### Adding New Translation Keys in Code
+### Menambahkan Kunci Terjemahan Baru dalam Kode
```tsx
// Use namespaced keys
@@ -406,33 +406,33 @@ t("cacheSettings"); // maps to settings.cacheSettings in JSON
python3 scripts/check_translations.py --verbose
```
-### RTL Considerations
+### Pertimbangan RTL
-- Arabic (`ar`) and Hebrew (`he`) are RTL locales
-- Avoid hardcoded `left`/`right` CSS — use `start`/`end` logical properties
-- Visual QA catches RTL layout mismatches via `run-visual-qa.mjs`
+- Bahasa Arab (`ar`) dan Ibrani (`he`) adalah lokal RTL
+- Hindari `left`/`right` CSS yang dikodekan keras — gunakan properti logis `start`/`end`
+- QA visual menangkap ketidaksesuaian tata letak RTL melalui `run-visual-qa.mjs`
-## Known Issues & History
+## Masalah yang Diketahui & Riwayat
-### `in.json` → `hi.json` Fix
+### Perbaikan `in.json` → `hi.json`
-The generator originally used `code: "in"` (deprecated Google Translate code) for Hindi instead of the correct ISO 639-1 `hi`. This created an orphaned `in.json` duplicate of `hi.json`. Fixed by changing `code: "in"` to `code: "hi"` in `generate-multilang.mjs` and removing the orphaned file.
+Generator awalnya menggunakan `code: "in"` (kode Google Translate yang sudah usang) untuk bahasa Hindi, bukan ISO 639-1 yang benar yaitu `hi`. Hal ini menciptakan duplikat `in.json` yang tidak terhubung dari `hi.json`. Diperbaiki dengan mengubah `code: "in"` menjadi `code: "hi"` di `generate-multilang.mjs` dan menghapus file yang tidak terhubung tersebut.
-### `docs/i18n/README.md` Is Auto-Generated
+### `docs/i18n/README.md` Dibuat Secara Otomatis
-The `docs/i18n/README.md` file is completely regenerated by `generate-multilang.mjs docs`. Any manual edits will be lost. Use `docs/guides/I18N.md` (this file) for hand-written documentation that should persist.
+File `docs/i18n/README.md` sepenuhnya dihasilkan ulang oleh `generate-multilang.mjs docs`. Setiap pengeditan manual akan hilang. Gunakan `docs/guides/I18N.md` (file ini) untuk dokumentasi yang ditulis tangan yang harus tetap ada.
-### External Untranslatable Keys List
+### Daftar Kunci yang Tidak Dapat Diterjemahkan Eksternal
-The `untranslatable-keys.json` allowlist was moved from an inline Python set in `validate_translation.py` to an external JSON file for easier maintenance. The validator loads it at runtime.
+Daftar yang diizinkan `untranslatable-keys.json` dipindahkan dari set Python inline di `validate_translation.py` ke file JSON eksternal agar lebih mudah dipelihara. Validator memuatnya saat runtime.
-### `generate-multilang.mjs` Hindi Code Fix
+### Perbaikan Kode Hindi di `generate-multilang.mjs`
-The generator originally used `code: "in"` (deprecated Google Translate code) for Hindi instead of the correct ISO 639-1 `hi`. This was introduced in upstream commit `952b0b22c` by `diegosouzapw`. Fixed by changing `code: "in"` to `code: "hi"` in the `LOCALE_SPECS` array and removing the orphaned `in.json` file.
+Generator awalnya menggunakan `code: "in"` (kode Google Translate yang sudah usang) untuk bahasa Hindi, bukan ISO 639-1 yang benar yaitu `hi`. Ini diperkenalkan dalam commit upstream `952b0b22c` oleh `diegosouzapw`. Diperbaiki dengan mengubah `code: "in"` menjadi `code: "hi"` di array `LOCALE_SPECS` dan menghapus file `in.json` yang tidak terhubung.
-### `validate_translation.py` Ignored Count Output
+### Keluaran Jumlah Kunci yang Diabaikan di `validate_translation.py`
-The `quick` check now displays the count of ignored keys from `untranslatable-keys.json`:
+Pemeriksaan `quick` kini menampilkan jumlah kunci yang diabaikan dari `untranslatable-keys.json`:
```
Missing: 0
diff --git a/docs/i18n/id/docs/guides/TROUBLESHOOTING.md b/docs/i18n/id/docs/guides/TROUBLESHOOTING.md
index ae8156e5ef..73fe032261 100644
--- a/docs/i18n/id/docs/guides/TROUBLESHOOTING.md
+++ b/docs/i18n/id/docs/guides/TROUBLESHOOTING.md
@@ -1,72 +1,72 @@
-# Troubleshooting (Bahasa Indonesia)
+# Pemecahan Masalah (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/TROUBLESHOOTING.md) · 🇸🇦 [ar](../../ar/docs/TROUBLESHOOTING.md) · 🇧🇬 [bg](../../bg/docs/TROUBLESHOOTING.md) · 🇧🇩 [bn](../../bn/docs/TROUBLESHOOTING.md) · 🇨🇿 [cs](../../cs/docs/TROUBLESHOOTING.md) · 🇩🇰 [da](../../da/docs/TROUBLESHOOTING.md) · 🇩🇪 [de](../../de/docs/TROUBLESHOOTING.md) · 🇪🇸 [es](../../es/docs/TROUBLESHOOTING.md) · 🇮🇷 [fa](../../fa/docs/TROUBLESHOOTING.md) · 🇫🇮 [fi](../../fi/docs/TROUBLESHOOTING.md) · 🇫🇷 [fr](../../fr/docs/TROUBLESHOOTING.md) · 🇮🇳 [gu](../../gu/docs/TROUBLESHOOTING.md) · 🇮🇱 [he](../../he/docs/TROUBLESHOOTING.md) · 🇮🇳 [hi](../../hi/docs/TROUBLESHOOTING.md) · 🇭🇺 [hu](../../hu/docs/TROUBLESHOOTING.md) · 🇮🇩 [id](../../id/docs/TROUBLESHOOTING.md) · 🇮🇹 [it](../../it/docs/TROUBLESHOOTING.md) · 🇯🇵 [ja](../../ja/docs/TROUBLESHOOTING.md) · 🇰🇷 [ko](../../ko/docs/TROUBLESHOOTING.md) · 🇮🇳 [mr](../../mr/docs/TROUBLESHOOTING.md) · 🇲🇾 [ms](../../ms/docs/TROUBLESHOOTING.md) · 🇳🇱 [nl](../../nl/docs/TROUBLESHOOTING.md) · 🇳🇴 [no](../../no/docs/TROUBLESHOOTING.md) · 🇵🇭 [phi](../../phi/docs/TROUBLESHOOTING.md) · 🇵🇱 [pl](../../pl/docs/TROUBLESHOOTING.md) · 🇵🇹 [pt](../../pt/docs/TROUBLESHOOTING.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/TROUBLESHOOTING.md) · 🇷🇴 [ro](../../ro/docs/TROUBLESHOOTING.md) · 🇷🇺 [ru](../../ru/docs/TROUBLESHOOTING.md) · 🇸🇰 [sk](../../sk/docs/TROUBLESHOOTING.md) · 🇸🇪 [sv](../../sv/docs/TROUBLESHOOTING.md) · 🇰🇪 [sw](../../sw/docs/TROUBLESHOOTING.md) · 🇮🇳 [ta](../../ta/docs/TROUBLESHOOTING.md) · 🇮🇳 [te](../../te/docs/TROUBLESHOOTING.md) · 🇹🇭 [th](../../th/docs/TROUBLESHOOTING.md) · 🇹🇷 [tr](../../tr/docs/TROUBLESHOOTING.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/TROUBLESHOOTING.md) · 🇵🇰 [ur](../../ur/docs/TROUBLESHOOTING.md) · 🇻🇳 [vi](../../vi/docs/TROUBLESHOOTING.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/TROUBLESHOOTING.md)
---
-Common problems and solutions for OmniRoute.
+Masalah umum dan solusinya untuk OmniRoute.
---
-## Quick Fixes
+## Perbaikan Cepat
-| Problem | Solution |
-| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| First login not working | Set `INITIAL_PASSWORD` in `.env` (no hardcoded default) |
-| Dashboard opens on wrong port | Set `PORT=20128` and `NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
-| No logs written to disk | Set `APP_LOG_TO_FILE=true` and verify call log capture is enabled |
-| EACCES: permission denied | Set `DATA_DIR=/path/to/writable/dir` to override `~/.omniroute` |
-| Routing strategy not saving | Update to v1.4.11+ (Zod schema fix for settings persistence) |
-| Login crash / blank page | Check Node.js version — see [Node.js Compatibility](#nodejs-compatibility) below |
-| `dlopen` / `slice is not valid mach-o file` (macOS) | Run `cd $(npm root -g)/omniroute/app && npm rebuild better-sqlite3 && omniroute` — see [macOS native module rebuild](#macos-native-module-rebuild) below |
-| Proxy "fetch failed" | Ensure proxy config is set at the correct level — see [Proxy Issues](#proxy-issues) below |
+| Masalah | Solusi |
+| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Login pertama tidak berfungsi | Atur `INITIAL_PASSWORD` di `.env` (tidak ada nilai default yang dikodekan langsung) |
+| Dashboard terbuka di port yang salah | Atur `PORT=20128` dan `NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
+| Tidak ada log yang ditulis ke disk | Atur `APP_LOG_TO_FILE=true` dan pastikan pengambilan log panggilan diaktifkan |
+| EACCES: permission denied | Atur `DATA_DIR=/path/to/writable/dir` untuk mengganti `~/.omniroute` |
+| Strategi routing tidak tersimpan | Perbarui ke v1.4.11+ (perbaikan skema Zod untuk persistensi pengaturan) |
+| Login crash / halaman kosong | Periksa versi Node.js — lihat [Kompatibilitas Node.js](#nodejs-compatibility) di bawah |
+| `dlopen` / `slice is not valid mach-o file` (macOS) | Jalankan `cd $(npm root -g)/omniroute/app && npm rebuild better-sqlite3 && omniroute` — lihat [Pembangunan ulang modul native macOS](#macos-native-module-rebuild) di bawah |
+| Proxy "fetch failed" | Pastikan konfigurasi proxy diatur pada tingkat yang tepat — lihat [Masalah Proxy](#proxy-issues) di bawah |
---
-## Node.js Compatibility
+## Kompatibilitas Node.js
-### Login page crashes or shows "Module self-registration" error
+### Halaman login crash atau menampilkan error "Module self-registration"
-**Cause:** You are running a Node.js version outside OmniRoute's approved secure runtime floor. The most common case is running an older Node 20, 22, or 24 patch level that falls below the patched security floor OmniRoute requires.
+**Penyebab:** Anda menjalankan versi Node.js di luar batas runtime aman yang disetujui OmniRoute. Kasus paling umum adalah menjalankan Node 20, 22, atau 24 versi patch lama yang berada di bawah batas keamanan yang diperlukan OmniRoute.
-**Symptoms:**
+**Gejala:**
-- Login page shows a blank screen or a server error
-- Console shows `Error: Module did not self-register` or similar native binding errors
-- The login page shows an **orange warning banner** with your Node version if the runtime is outside the supported secure policy
+- Halaman login menampilkan layar kosong atau error server
+- Konsol menampilkan `Error: Module did not self-register` atau error binding native serupa
+- Halaman login menampilkan **banner peringatan oranye** dengan versi Node Anda jika runtime berada di luar kebijakan keamanan yang didukung
-**Fix:**
+**Solusi:**
-1. Install a supported Node.js LTS release (recommended: Node.js 24.x):
+1. Instal rilis Node.js LTS yang didukung (disarankan: Node.js 24.x):
```bash
nvm install 24
nvm use 24
```
-2. Verify your version: `node --version` should show `v24.0.0` or newer on the 24.x LTS line
-3. Reinstall OmniRoute: `npm install -g omniroute`
-4. Restart: `omniroute`
+2. Verifikasi versi Anda: `node --version` seharusnya menampilkan `v24.0.0` atau lebih baru pada lini LTS 24.x
+3. Instal ulang OmniRoute: `npm install -g omniroute`
+4. Mulai ulang: `omniroute`
-> **Supported secure versions:** `>=20.20.2 <21`, `>=22.22.2 <23`, or `>=24.0.0 <25`. Node.js 24.x LTS (Krypton) is fully supported.
+> **Versi aman yang didukung:** `>=20.20.2 <21`, `>=22.22.2 <23`, atau `>=24.0.0 <25`. Node.js 24.x LTS (Krypton) sepenuhnya didukung.
### macOS: `dlopen` / "slice is not valid mach-o file"
-**Cause:** After a global `npm install -g omniroute`, the `better-sqlite3` native binary inside the package may have been compiled for a different architecture or Node.js ABI than what is running locally. This is common on macOS (both Apple Silicon and Intel) when the pre-built binary does not match your environment.
+**Penyebab:** Setelah `npm install -g omniroute` secara global, biner native `better-sqlite3` di dalam paket mungkin telah dikompilasi untuk arsitektur atau ABI Node.js yang berbeda dari yang berjalan secara lokal. Hal ini umum terjadi di macOS (baik Apple Silicon maupun Intel) ketika biner yang sudah dibangun tidak cocok dengan lingkungan Anda.
-**Symptoms:**
+**Gejala:**
-- Server fails immediately on startup with a `dlopen` error
-- Error contains `slice is not valid mach-o file`
-- Full example:
+- Server gagal langsung saat startup dengan error `dlopen`
+- Error berisi `slice is not valid mach-o file`
+- Contoh lengkap:
```
dlopen(/Users//.nvm/versions/node/v24.14.1/lib/node_modules/omniroute/app/node_modules/better-sqlite3/build/Release/better_sqlite3.node, 0x0001): tried: '...' (slice is not valid mach-o file)
```
-**Fix — rebuild for your local environment (no Node.js downgrade required):**
+**Solusi — bangun ulang untuk lingkungan lokal Anda (tidak perlu downgrade Node.js):**
```bash
cd $(npm root -g)/omniroute/app
@@ -74,98 +74,98 @@ npm rebuild better-sqlite3
omniroute
```
-> **Note:** This recompiles the native binding against your local Node.js version and CPU architecture, resolving the binary mismatch. The officially supported range is **`>=20.20.2 <21`, `>=22.22.2 <23`, or `>=24.0.0 <25`** (`engines` field in `package.json`). Node.js 24.x LTS (Krypton) is fully supported with `better-sqlite3` v12.x.
+> **Catatan:** Perintah ini mengompilasi ulang binding native terhadap versi Node.js dan arsitektur CPU lokal Anda, mengatasi ketidakcocokan biner. Rentang yang resmi didukung adalah **`>=20.20.2 <21`, `>=22.22.2 <23`, atau `>=24.0.0 <25`** (kolom `engines` di `package.json`). Node.js 24.x LTS (Krypton) sepenuhnya didukung dengan `better-sqlite3` v12.x.
---
-## Proxy Issues
+## Masalah Proxy
-### Provider validation shows "fetch failed"
+### Validasi penyedia menampilkan "fetch failed"
-**Cause:** The API key validation endpoint (`POST /api/providers/validate`) was previously bypassing proxy configuration, causing failures in environments that require proxy routing.
+**Penyebab:** Endpoint validasi API key (`POST /api/providers/validate`) sebelumnya mengabaikan konfigurasi proxy, menyebabkan kegagalan di lingkungan yang memerlukan routing melalui proxy.
-**Fix (v3.5.5+):** This is now fixed. Provider validation routes through `runWithProxyContext`, honoring provider-level and global proxy settings automatically.
+**Solusi (v3.5.5+):** Masalah ini sudah diperbaiki. Validasi penyedia sekarang melewati `runWithProxyContext`, mengikuti pengaturan proxy pada tingkat penyedia dan global secara otomatis.
-### Token health check fails with "fetch failed"
+### Pemeriksaan kesehatan token gagal dengan "fetch failed"
-**Cause:** Background OAuth token refresh was not resolving proxy configuration per connection.
+**Penyebab:** Pembaruan token OAuth di latar belakang tidak menyelesaikan konfigurasi proxy per koneksi.
-**Fix (v3.5.5+):** The token health check scheduler now resolves proxy config per connection before attempting refresh. Update to v3.5.5+.
+**Solusi (v3.5.5+):** Penjadwal pemeriksaan kesehatan token sekarang menyelesaikan konfigurasi proxy per koneksi sebelum mencoba pembaruan. Perbarui ke v3.5.5+.
-### SOCKS5 proxy returns "invalid onRequestStart method"
+### Proxy SOCKS5 mengembalikan "invalid onRequestStart method"
-**Cause:** On Node.js 22, the undici@8 dispatcher is incompatible with Node's built-in `fetch()` implementation.
+**Penyebab:** Pada Node.js 22, dispatcher undici@8 tidak kompatibel dengan implementasi `fetch()` bawaan Node.
-**Fix (v3.5.5+):** OmniRoute now uses undici's own `fetch()` function when a proxy dispatcher is active, ensuring consistent behavior. Update to v3.5.5+.
+**Solusi (v3.5.5+):** OmniRoute sekarang menggunakan fungsi `fetch()` milik undici sendiri ketika dispatcher proxy aktif, memastikan perilaku yang konsisten. Perbarui ke v3.5.5+.
---
-## Provider Issues
+## Masalah Penyedia
### "Language model did not provide messages"
-**Cause:** Provider quota exhausted.
+**Penyebab:** Kuota penyedia habis.
-**Fix:**
+**Solusi:**
-1. Check dashboard quota tracker
-2. Use a combo with fallback tiers
-3. Switch to cheaper/free tier
+1. Periksa pelacak kuota di dashboard
+2. Gunakan combo dengan tier fallback
+3. Beralih ke tier yang lebih murah/gratis
-### Rate Limiting
+### Pembatasan Laju (Rate Limiting)
-**Cause:** Subscription quota exhausted.
+**Penyebab:** Kuota langganan habis.
-**Fix:**
+**Solusi:**
-- Add fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
-- Use GLM/MiniMax as cheap backup
+- Tambahkan fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
+- Gunakan GLM/MiniMax sebagai cadangan murah
-### OAuth Token Expired
+### Token OAuth Kedaluwarsa
-OmniRoute auto-refreshes tokens. If issues persist:
+OmniRoute memperbarui token secara otomatis. Jika masalah berlanjut:
-1. Dashboard → Provider → Reconnect
-2. Delete and re-add the provider connection
+1. Dashboard → Penyedia → Sambungkan Ulang
+2. Hapus dan tambahkan ulang koneksi penyedia
---
-## Cloud Issues
+## Masalah Cloud
-### Cloud Sync Errors
+### Error Sinkronisasi Cloud
-1. Verify `BASE_URL` points to your running instance (e.g., `http://localhost:20128`)
-2. Verify `CLOUD_URL` points to your cloud endpoint (e.g., `https://omniroute.dev`)
-3. Keep `NEXT_PUBLIC_*` values aligned with server-side values
+1. Pastikan `BASE_URL` mengarah ke instans yang sedang berjalan (misalnya, `http://localhost:20128`)
+2. Pastikan `CLOUD_URL` mengarah ke endpoint cloud Anda (misalnya, `https://omniroute.dev`)
+3. Jaga agar nilai `NEXT_PUBLIC_*` selaras dengan nilai sisi server
-### Cloud `stream=false` Returns 500
+### Cloud `stream=false` Mengembalikan 500
-**Symptom:** `Unexpected token 'd'...` on cloud endpoint for non-streaming calls.
+**Gejala:** `Unexpected token 'd'...` pada endpoint cloud untuk panggilan non-streaming.
-**Cause:** Upstream returns SSE payload while client expects JSON.
+**Penyebab:** Upstream mengembalikan payload SSE sementara klien mengharapkan JSON.
-**Workaround:** Use `stream=true` for cloud direct calls. Local runtime includes SSE→JSON fallback.
+**Solusi Sementara:** Gunakan `stream=true` untuk panggilan langsung ke cloud. Runtime lokal sudah menyertakan fallback SSE→JSON.
-### Cloud Says Connected but "Invalid API key"
+### Cloud Menunjukkan Terhubung tetapi "Invalid API key"
-1. Create a fresh key from local dashboard (`/api/keys`)
-2. Run cloud sync: Enable Cloud → Sync Now
-3. Old/non-synced keys can still return `401` on cloud
+1. Buat kunci baru dari dashboard lokal (`/api/keys`)
+2. Jalankan sinkronisasi cloud: Aktifkan Cloud → Sinkronkan Sekarang
+3. Kunci lama/yang tidak tersinkronisasi masih dapat mengembalikan `401` di cloud
---
-## Docker Issues
+## Masalah Docker
-### CLI Tool Shows Not Installed
+### Alat CLI Menampilkan Belum Terinstal
-1. Check runtime fields: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
-2. For portable mode: use image target `runner-cli` (bundled CLIs)
-3. For host mount mode: set `CLI_EXTRA_PATHS` and mount host bin directory as read-only
-4. If `installed=true` and `runnable=false`: binary was found but failed healthcheck
+1. Periksa kolom runtime: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
+2. Untuk mode portabel: gunakan target image `runner-cli` (CLI yang sudah dibundel)
+3. Untuk mode mount host: atur `CLI_EXTRA_PATHS` dan mount direktori bin host sebagai read-only
+4. Jika `installed=true` dan `runnable=false`: biner ditemukan tetapi gagal healthcheck
-### Quick Runtime Validation
+### Validasi Runtime Cepat
```bash
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
@@ -175,26 +175,26 @@ curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,
---
-## Cost Issues
+## Masalah Biaya
-### High Costs
+### Biaya Tinggi
-1. Check usage stats in Dashboard → Usage
-2. Switch primary model to GLM/MiniMax
-3. Use free tier (Gemini CLI, Qoder) for non-critical tasks
-4. Set cost budgets per API key: Dashboard → API Keys → Budget
+1. Periksa statistik penggunaan di Dashboard → Penggunaan
+2. Beralih model utama ke GLM/MiniMax
+3. Gunakan tier gratis (Gemini CLI, Qoder) untuk tugas yang tidak kritis
+4. Atur anggaran biaya per API key: Dashboard → API Keys → Anggaran
---
## Debugging
-### Enable Log Files
+### Aktifkan File Log
-Set `APP_LOG_TO_FILE=true` in your `.env` file. Application logs are written under `logs/`.
-Request artifacts are stored under `${DATA_DIR}/call_logs/` when the call log pipeline is
-enabled in settings.
+Atur `APP_LOG_TO_FILE=true` di file `.env` Anda. Log aplikasi ditulis di bawah `logs/`.
+Artefak permintaan disimpan di bawah `${DATA_DIR}/call_logs/` ketika pipeline log panggilan
+diaktifkan di pengaturan.
-### Check Provider Health
+### Periksa Kesehatan Penyedia
```bash
# Health dashboard
@@ -204,138 +204,138 @@ http://localhost:20128/dashboard/health
curl http://localhost:20128/api/monitoring/health
```
-### Runtime Storage
+### Penyimpanan Runtime
-- Main state: `${DATA_DIR}/storage.sqlite` (providers, combos, aliases, keys, settings)
-- Usage: SQLite tables in `storage.sqlite` (`usage_history`, `call_logs`, `proxy_logs`) + optional `${DATA_DIR}/call_logs/`
-- Application logs: `/logs/...` (when `APP_LOG_TO_FILE=true`)
-- Call log artifacts: `${DATA_DIR}/call_logs/YYYY-MM-DD/...` when the call log pipeline is enabled
+- Status utama: `${DATA_DIR}/storage.sqlite` (penyedia, combo, alias, kunci, pengaturan)
+- Penggunaan: tabel SQLite di `storage.sqlite` (`usage_history`, `call_logs`, `proxy_logs`) + opsional `${DATA_DIR}/call_logs/`
+- Log aplikasi: `/logs/...` (ketika `APP_LOG_TO_FILE=true`)
+- Artefak log panggilan: `${DATA_DIR}/call_logs/YYYY-MM-DD/...` ketika pipeline log panggilan diaktifkan
---
-## Circuit Breaker Issues
+## Masalah Circuit Breaker
-### Provider stuck in OPEN state
+### Penyedia terjebak dalam status OPEN
-When a provider's circuit breaker is OPEN, requests are blocked until the cooldown expires.
+Ketika circuit breaker penyedia dalam status OPEN, permintaan diblokir hingga cooldown berakhir.
-**Fix:**
+**Solusi:**
-1. Go to **Dashboard → Settings → Resilience**
-2. Check the circuit breaker card for the affected provider
-3. Click **Reset All** to clear all breakers, or wait for the cooldown to expire
-4. Verify the provider is actually available before resetting
+1. Buka **Dashboard → Settings → Resilience**
+2. Periksa kartu circuit breaker untuk penyedia yang terdampak
+3. Klik **Reset All** untuk menghapus semua breaker, atau tunggu hingga cooldown berakhir
+4. Pastikan penyedia benar-benar tersedia sebelum melakukan reset
-### Provider keeps tripping the circuit breaker
+### Penyedia terus memicu circuit breaker
-If a provider repeatedly enters OPEN state:
+Jika penyedia berulang kali masuk ke status OPEN:
-1. Check **Dashboard → Health → Provider Health** for the failure pattern
-2. Go to **Settings → Resilience → Provider Profiles** and increase the failure threshold
-3. Check if the provider has changed API limits or requires re-authentication
-4. Review latency telemetry — high latency may cause timeout-based failures
+1. Periksa **Dashboard → Health → Provider Health** untuk pola kegagalan
+2. Buka **Settings → Resilience → Provider Profiles** dan tingkatkan ambang batas kegagalan
+3. Periksa apakah penyedia telah mengubah batas API atau memerlukan autentikasi ulang
+4. Tinjau telemetri latensi — latensi tinggi dapat menyebabkan kegagalan berbasis timeout
---
-## Audio Transcription Issues
+## Masalah Transkripsi Audio
-### "Unsupported model" error
+### Error "Unsupported model"
-- Ensure you're using the correct prefix: `deepgram/nova-3` or `assemblyai/best`
-- Verify the provider is connected in **Dashboard → Providers**
+- Pastikan Anda menggunakan awalan yang tepat: `deepgram/nova-3` atau `assemblyai/best`
+- Pastikan penyedia terhubung di **Dashboard → Providers**
-### Transcription returns empty or fails
+### Transkripsi mengembalikan hasil kosong atau gagal
-- Check supported audio formats: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`
-- Verify file size is within provider limits (typically < 25MB)
-- Check provider API key validity in the provider card
+- Periksa format audio yang didukung: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`
+- Pastikan ukuran file berada dalam batas penyedia (biasanya < 25MB)
+- Periksa validitas API key penyedia di kartu penyedia
---
-## Translator Debugging
+## Debugging Translator
-Use **Dashboard → Translator** to debug format translation issues:
+Gunakan **Dashboard → Translator** untuk melakukan debug masalah terjemahan format:
-| Mode | When to Use |
-| ---------------- | -------------------------------------------------------------------------------------------- |
-| **Playground** | Compare input/output formats side by side — paste a failing request to see how it translates |
-| **Chat Tester** | Send live messages and inspect the full request/response payload including headers |
-| **Test Bench** | Run batch tests across format combinations to find which translations are broken |
-| **Live Monitor** | Watch real-time request flow to catch intermittent translation issues |
+| Mode | Kapan Digunakan |
+| ---------------- | ------------------------------------------------------------------------------------------------------------ |
+| **Playground** | Bandingkan format input/output berdampingan — tempel permintaan yang gagal untuk melihat cara terjemahannya |
+| **Chat Tester** | Kirim pesan langsung dan periksa payload permintaan/respons lengkap termasuk header |
+| **Test Bench** | Jalankan pengujian batch di berbagai kombinasi format untuk menemukan terjemahan mana yang rusak |
+| **Live Monitor** | Pantau aliran permintaan secara real-time untuk menangkap masalah terjemahan yang intermiten |
-### Common format issues
+### Masalah format yang umum
-- **Thinking tags not appearing** — Check if the target provider supports thinking and the thinking budget setting
-- **Tool calls dropping** — Some format translations may strip unsupported fields; verify in Playground mode
-- **System prompt missing** — Claude and Gemini handle system prompts differently; check translation output
-- **SDK returns raw string instead of object** — Fixed in v1.1.0: response sanitizer now strips non-standard fields (`x_groq`, `usage_breakdown`, etc.) that cause OpenAI SDK Pydantic validation failures
-- **GLM/ERNIE rejects `system` role** — Fixed in v1.1.0: role normalizer automatically merges system messages into user messages for incompatible models
-- **`developer` role not recognized** — Fixed in v1.1.0: automatically converted to `system` for non-OpenAI providers
-- **`json_schema` not working with Gemini** — Fixed in v1.1.0: `response_format` is now converted to Gemini's `responseMimeType` + `responseSchema`
+- **Tag thinking tidak muncul** — Periksa apakah penyedia target mendukung thinking dan pengaturan anggaran thinking
+- **Tool call hilang** — Beberapa terjemahan format mungkin menghapus kolom yang tidak didukung; verifikasi di mode Playground
+- **System prompt hilang** — Claude dan Gemini menangani system prompt secara berbeda; periksa output terjemahan
+- **SDK mengembalikan string mentah alih-alih objek** — Diperbaiki di v1.1.0: sanitizer respons sekarang menghapus kolom non-standar (`x_groq`, `usage_breakdown`, dll.) yang menyebabkan kegagalan validasi Pydantic SDK OpenAI
+- **GLM/ERNIE menolak role `system`** — Diperbaiki di v1.1.0: normalizer role secara otomatis menggabungkan pesan sistem ke dalam pesan pengguna untuk model yang tidak kompatibel
+- **Role `developer` tidak dikenali** — Diperbaiki di v1.1.0: secara otomatis dikonversi ke `system` untuk penyedia non-OpenAI
+- **`json_schema` tidak berfungsi dengan Gemini** — Diperbaiki di v1.1.0: `response_format` sekarang dikonversi ke `responseMimeType` + `responseSchema` milik Gemini
---
-## Resilience Settings
+## Pengaturan Resiliensi
-### Auto rate-limit not triggering
+### Auto rate-limit tidak terpicu
-- Auto rate-limit only applies to API key providers (not OAuth/subscription)
-- Verify **Settings → Resilience → Provider Profiles** has auto-rate-limit enabled
-- Check if the provider returns `429` status codes or `Retry-After` headers
+- Auto rate-limit hanya berlaku untuk penyedia dengan API key (bukan OAuth/langganan)
+- Pastikan **Settings → Resilience → Provider Profiles** telah mengaktifkan auto rate-limit
+- Periksa apakah penyedia mengembalikan kode status `429` atau header `Retry-After`
-### Tuning exponential backoff
+### Menyetel exponential backoff
-Provider profiles support these settings:
+Profil penyedia mendukung pengaturan berikut:
-- **Base delay** — Initial wait time after first failure (default: 1s)
-- **Max delay** — Maximum wait time cap (default: 30s)
-- **Multiplier** — How much to increase delay per consecutive failure (default: 2x)
+- **Base delay** — Waktu tunggu awal setelah kegagalan pertama (default: 1s)
+- **Max delay** — Batas maksimum waktu tunggu (default: 30s)
+- **Multiplier** — Seberapa banyak penundaan ditingkatkan per kegagalan berturut-turut (default: 2x)
### Anti-thundering herd
-When many concurrent requests hit a rate-limited provider, OmniRoute uses mutex + auto rate-limiting to serialize requests and prevent cascading failures. This is automatic for API key providers.
+Ketika banyak permintaan bersamaan mengenai penyedia yang dibatasi lajunya, OmniRoute menggunakan mutex + auto rate-limiting untuk membuat serialisasi permintaan dan mencegah kegagalan berantai. Ini berjalan otomatis untuk penyedia dengan API key.
---
-## Optional RAG / LLM failure taxonomy (16 problems)
+## Taksonomi Kegagalan RAG / LLM Opsional (16 masalah)
-Some OmniRoute users place the gateway in front of RAG or agent stacks. In those setups it is common to see a strange pattern: OmniRoute looks healthy (providers up, routing profiles ok, no rate limit alerts) but the final answer is still wrong.
+Beberapa pengguna OmniRoute menempatkan gateway di depan tumpukan RAG atau agen. Dalam pengaturan tersebut, umum terjadi pola yang aneh: OmniRoute terlihat sehat (penyedia aktif, profil routing baik, tidak ada peringatan batas laju) tetapi jawaban akhir masih salah.
-In practice these incidents usually come from the downstream RAG pipeline, not from the gateway itself.
+Dalam praktiknya, insiden ini biasanya berasal dari pipeline RAG downstream, bukan dari gateway itu sendiri.
-If you want a shared vocabulary to describe those failures you can use the WFGY ProblemMap, an external MIT license text resource that defines sixteen recurring RAG / LLM failure patterns. At a high level it covers:
+Jika Anda menginginkan kosakata bersama untuk mendeskripsikan kegagalan tersebut, Anda dapat menggunakan WFGY ProblemMap, sebuah sumber daya teks berlisensi MIT eksternal yang mendefinisikan enam belas pola kegagalan RAG / LLM yang berulang. Secara garis besar, ini mencakup:
-- retrieval drift and broken context boundaries
-- empty or stale indexes and vector stores
-- embedding versus semantic mismatch
-- prompt assembly and context window issues
-- logic collapse and overconfident answers
-- long chain and agent coordination failures
-- multi agent memory and role drift
-- deployment and bootstrap ordering problems
+- pergeseran retrieval dan batas konteks yang rusak
+- indeks dan vector store yang kosong atau sudah usang
+- ketidakcocokan embedding versus semantik
+- masalah perakitan prompt dan jendela konteks
+- keruntuhan logika dan jawaban yang terlalu percaya diri
+- kegagalan rantai panjang dan koordinasi agen
+- memori multi-agen dan pergeseran peran
+- masalah urutan deployment dan bootstrap
-The idea is simple:
+Idenya sederhana:
-1. When you investigate a bad response, capture:
- - user task and request
- - route or provider combo in OmniRoute
- - any RAG context used downstream (retrieved documents, tool calls, etc)
-2. Map the incident to one or two WFGY ProblemMap numbers (`No.1` … `No.16`).
-3. Store the number in your own dashboard, runbook, or incident tracker next to the OmniRoute logs.
-4. Use the corresponding WFGY page to decide whether you need to change your RAG stack, retriever, or routing strategy.
+1. Saat Anda menyelidiki respons yang buruk, kumpulkan:
+ - tugas pengguna dan permintaan
+ - route atau combo penyedia di OmniRoute
+ - konteks RAG apa pun yang digunakan di downstream (dokumen yang diambil, tool call, dll.)
+2. Petakan insiden ke satu atau dua nomor WFGY ProblemMap (`No.1` … `No.16`).
+3. Simpan nomornya di dashboard, runbook, atau pelacak insiden Anda sendiri di samping log OmniRoute.
+4. Gunakan halaman WFGY yang sesuai untuk memutuskan apakah Anda perlu mengubah tumpukan RAG, retriever, atau strategi routing Anda.
-Full text and concrete recipes live here (MIT license, text only):
+Teks lengkap dan resep konkret tersedia di sini (lisensi MIT, hanya teks):
[WFGY ProblemMap README](https://github.com/onestardao/WFGY/blob/main/ProblemMap/README.md)
-You can ignore this section if you do not run RAG or agent pipelines behind OmniRoute.
+Anda dapat mengabaikan bagian ini jika Anda tidak menjalankan pipeline RAG atau agen di belakang OmniRoute.
---
-## Still Stuck?
+## Masih Terjebak?
- **GitHub Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
-- **Architecture**: See [`docs/architecture/ARCHITECTURE.md`](ARCHITECTURE.md) for internal details
-- **API Reference**: See [`docs/reference/API_REFERENCE.md`](API_REFERENCE.md) for all endpoints
-- **Health Dashboard**: Check **Dashboard → Health** for real-time system status
-- **Translator**: Use **Dashboard → Translator** to debug format issues
+- **Arsitektur**: Lihat [`docs/architecture/ARCHITECTURE.md`](ARCHITECTURE.md) untuk detail internal
+- **Referensi API**: Lihat [`docs/reference/API_REFERENCE.md`](API_REFERENCE.md) untuk semua endpoint
+- **Health Dashboard**: Periksa **Dashboard → Health** untuk status sistem secara real-time
+- **Translator**: Gunakan **Dashboard → Translator** untuk melakukan debug masalah format
diff --git a/docs/i18n/id/docs/guides/UNINSTALL.md b/docs/i18n/id/docs/guides/UNINSTALL.md
index 55c4e16c95..862d3662a2 100644
--- a/docs/i18n/id/docs/guides/UNINSTALL.md
+++ b/docs/i18n/id/docs/guides/UNINSTALL.md
@@ -1,46 +1,46 @@
-# OmniRoute — Uninstall Guide (Bahasa Indonesia)
+# OmniRoute — Panduan Mencopot Pemasangan (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/UNINSTALL.md) · 🇸🇦 [ar](../../ar/docs/UNINSTALL.md) · 🇧🇬 [bg](../../bg/docs/UNINSTALL.md) · 🇧🇩 [bn](../../bn/docs/UNINSTALL.md) · 🇨🇿 [cs](../../cs/docs/UNINSTALL.md) · 🇩🇰 [da](../../da/docs/UNINSTALL.md) · 🇩🇪 [de](../../de/docs/UNINSTALL.md) · 🇪🇸 [es](../../es/docs/UNINSTALL.md) · 🇮🇷 [fa](../../fa/docs/UNINSTALL.md) · 🇫🇮 [fi](../../fi/docs/UNINSTALL.md) · 🇫🇷 [fr](../../fr/docs/UNINSTALL.md) · 🇮🇳 [gu](../../gu/docs/UNINSTALL.md) · 🇮🇱 [he](../../he/docs/UNINSTALL.md) · 🇮🇳 [hi](../../hi/docs/UNINSTALL.md) · 🇭🇺 [hu](../../hu/docs/UNINSTALL.md) · 🇮🇩 [id](../../id/docs/UNINSTALL.md) · 🇮🇹 [it](../../it/docs/UNINSTALL.md) · 🇯🇵 [ja](../../ja/docs/UNINSTALL.md) · 🇰🇷 [ko](../../ko/docs/UNINSTALL.md) · 🇮🇳 [mr](../../mr/docs/UNINSTALL.md) · 🇲🇾 [ms](../../ms/docs/UNINSTALL.md) · 🇳🇱 [nl](../../nl/docs/UNINSTALL.md) · 🇳🇴 [no](../../no/docs/UNINSTALL.md) · 🇵🇭 [phi](../../phi/docs/UNINSTALL.md) · 🇵🇱 [pl](../../pl/docs/UNINSTALL.md) · 🇵🇹 [pt](../../pt/docs/UNINSTALL.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/UNINSTALL.md) · 🇷🇴 [ro](../../ro/docs/UNINSTALL.md) · 🇷🇺 [ru](../../ru/docs/UNINSTALL.md) · 🇸🇰 [sk](../../sk/docs/UNINSTALL.md) · 🇸🇪 [sv](../../sv/docs/UNINSTALL.md) · 🇰🇪 [sw](../../sw/docs/UNINSTALL.md) · 🇮🇳 [ta](../../ta/docs/UNINSTALL.md) · 🇮🇳 [te](../../te/docs/UNINSTALL.md) · 🇹🇭 [th](../../th/docs/UNINSTALL.md) · 🇹🇷 [tr](../../tr/docs/UNINSTALL.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/UNINSTALL.md) · 🇵🇰 [ur](../../ur/docs/UNINSTALL.md) · 🇻🇳 [vi](../../vi/docs/UNINSTALL.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/UNINSTALL.md)
---
-This guide covers how to cleanly remove OmniRoute from your system.
+Panduan ini menjelaskan cara mencopot pemasangan OmniRoute dari sistem Anda secara bersih.
---
-## Quick Uninstall (v3.6.2+)
+## Mencopot Pemasangan dengan Cepat (v3.6.2+)
-OmniRoute provides two built-in scripts for clean removal:
+OmniRoute menyediakan dua skrip bawaan untuk penghapusan yang bersih:
-### Keep Your Data
+### Pertahankan Data Anda
```bash
npm run uninstall
```
-This removes the OmniRoute application but **preserves** your database, configurations, API keys, and provider settings in `~/.omniroute/`. Use this if you plan to reinstall later and want to keep your setup.
+Perintah ini menghapus aplikasi OmniRoute tetapi **mempertahankan** basis data, konfigurasi, kunci API, dan pengaturan penyedia Anda di `~/.omniroute/`. Gunakan ini jika Anda berencana memasang ulang nanti dan ingin menyimpan pengaturan yang ada.
-### Full Removal
+### Penghapusan Penuh
```bash
npm run uninstall:full
```
-This removes the application **and permanently erases** all data:
+Perintah ini menghapus aplikasi **dan menghapus secara permanen** semua data:
-- Database (`storage.sqlite`)
-- Provider configurations and API keys
-- Backup files
-- Log files
-- All files in the `~/.omniroute/` directory
+- Basis data (`storage.sqlite`)
+- Konfigurasi penyedia dan kunci API
+- Berkas cadangan
+- Berkas log
+- Semua berkas di direktori `~/.omniroute/`
-> ⚠️ **Warning:** `npm run uninstall:full` is irreversible. All your provider connections, combos, API keys, and usage history will be permanently deleted.
+> ⚠️ **Peringatan:** `npm run uninstall:full` tidak dapat dibatalkan. Semua koneksi penyedia, combo, kunci API, dan riwayat penggunaan Anda akan dihapus secara permanen.
---
-## Manual Uninstall
+## Mencopot Pemasangan Secara Manual
-### NPM Global Install
+### Instalasi Global NPM
```bash
# Remove the global package
@@ -50,7 +50,7 @@ npm uninstall -g omniroute
rm -rf ~/.omniroute
```
-### pnpm Global Install
+### Instalasi Global pnpm
```bash
pnpm uninstall -g omniroute
@@ -81,24 +81,24 @@ docker compose down
docker compose down -v
```
-### Electron Desktop App
+### Aplikasi Desktop Electron
**Windows:**
-- Open `Settings → Apps → OmniRoute → Uninstall`
-- Or run the NSIS uninstaller from the install directory
+- Buka `Settings → Apps → OmniRoute → Uninstall`
+- Atau jalankan uninstaller NSIS dari direktori instalasi
**macOS:**
-- Drag `OmniRoute.app` from `/Applications` to Trash
-- Remove data: `rm -rf ~/Library/Application Support/omniroute`
+- Seret `OmniRoute.app` dari `/Applications` ke Trash
+- Hapus data: `rm -rf ~/Library/Application Support/omniroute`
**Linux:**
-- Remove the AppImage file
-- Remove data: `rm -rf ~/.omniroute`
+- Hapus berkas AppImage
+- Hapus data: `rm -rf ~/.omniroute`
-### Source Install (git clone)
+### Instalasi dari Sumber (git clone)
```bash
# Remove the cloned directory
@@ -110,11 +110,11 @@ rm -rf ~/.omniroute
---
-## Data Directories
+## Direktori Data
-OmniRoute stores data in the following locations by default:
+OmniRoute menyimpan data di lokasi-lokasi berikut secara default:
-| Platform | Default Path | Override |
+| Platform | Jalur Default | Pengganti |
| ------------- | ----------------------------- | ------------------------- |
| Linux | `~/.omniroute/` | `DATA_DIR` env var |
| macOS | `~/.omniroute/` | `DATA_DIR` env var |
@@ -122,22 +122,22 @@ OmniRoute stores data in the following locations by default:
| Docker | `/app/data/` (mounted volume) | `DATA_DIR` env var |
| XDG-compliant | `$XDG_CONFIG_HOME/omniroute/` | `XDG_CONFIG_HOME` env var |
-### Files in the data directory
+### Berkas di dalam direktori data
-| File/Directory | Description |
-| -------------------- | ------------------------------------------------- |
-| `storage.sqlite` | Main database (providers, combos, settings, keys) |
-| `storage.sqlite-wal` | SQLite write-ahead log (temporary) |
-| `storage.sqlite-shm` | SQLite shared memory (temporary) |
-| `call_logs/` | Request payload archives |
-| `backups/` | Automatic database backups |
-| `log.txt` | Legacy request log (optional) |
+| Berkas/Direktori | Deskripsi |
+| -------------------- | ------------------------------------------------------------ |
+| `storage.sqlite` | Basis data utama (penyedia, combo, pengaturan, kunci) |
+| `storage.sqlite-wal` | Write-ahead log SQLite (sementara) |
+| `storage.sqlite-shm` | Shared memory SQLite (sementara) |
+| `call_logs/` | Arsip payload permintaan |
+| `backups/` | Cadangan basis data otomatis |
+| `log.txt` | Log permintaan lama (opsional) |
---
-## Verify Complete Removal
+## Verifikasi Penghapusan Lengkap
-After uninstalling, verify there are no remaining files:
+Setelah mencopot pemasangan, verifikasi bahwa tidak ada berkas yang tersisa:
```bash
# Check for global npm package
@@ -150,7 +150,7 @@ ls -la ~/.omniroute/ 2>/dev/null
pgrep -f omniroute
```
-If any process is still running, stop it:
+Jika ada proses yang masih berjalan, hentikan dengan perintah berikut:
```bash
pkill -f omniroute
diff --git a/docs/i18n/id/docs/guides/USER_GUIDE.md b/docs/i18n/id/docs/guides/USER_GUIDE.md
index 1e4dc9b26f..e857206971 100644
--- a/docs/i18n/id/docs/guides/USER_GUIDE.md
+++ b/docs/i18n/id/docs/guides/USER_GUIDE.md
@@ -1,119 +1,119 @@
-# User Guide (Bahasa Indonesia)
+# Panduan Pengguna (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/USER_GUIDE.md) · 🇸🇦 [ar](../../ar/docs/USER_GUIDE.md) · 🇧🇬 [bg](../../bg/docs/USER_GUIDE.md) · 🇧🇩 [bn](../../bn/docs/USER_GUIDE.md) · 🇨🇿 [cs](../../cs/docs/USER_GUIDE.md) · 🇩🇰 [da](../../da/docs/USER_GUIDE.md) · 🇩🇪 [de](../../de/docs/USER_GUIDE.md) · 🇪🇸 [es](../../es/docs/USER_GUIDE.md) · 🇮🇷 [fa](../../fa/docs/USER_GUIDE.md) · 🇫🇮 [fi](../../fi/docs/USER_GUIDE.md) · 🇫🇷 [fr](../../fr/docs/USER_GUIDE.md) · 🇮🇳 [gu](../../gu/docs/USER_GUIDE.md) · 🇮🇱 [he](../../he/docs/USER_GUIDE.md) · 🇮🇳 [hi](../../hi/docs/USER_GUIDE.md) · 🇭🇺 [hu](../../hu/docs/USER_GUIDE.md) · 🇮🇩 [id](../../id/docs/USER_GUIDE.md) · 🇮🇹 [it](../../it/docs/USER_GUIDE.md) · 🇯🇵 [ja](../../ja/docs/USER_GUIDE.md) · 🇰🇷 [ko](../../ko/docs/USER_GUIDE.md) · 🇮🇳 [mr](../../mr/docs/USER_GUIDE.md) · 🇲🇾 [ms](../../ms/docs/USER_GUIDE.md) · 🇳🇱 [nl](../../nl/docs/USER_GUIDE.md) · 🇳🇴 [no](../../no/docs/USER_GUIDE.md) · 🇵🇭 [phi](../../phi/docs/USER_GUIDE.md) · 🇵🇱 [pl](../../pl/docs/USER_GUIDE.md) · 🇵🇹 [pt](../../pt/docs/USER_GUIDE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/USER_GUIDE.md) · 🇷🇴 [ro](../../ro/docs/USER_GUIDE.md) · 🇷🇺 [ru](../../ru/docs/USER_GUIDE.md) · 🇸🇰 [sk](../../sk/docs/USER_GUIDE.md) · 🇸🇪 [sv](../../sv/docs/USER_GUIDE.md) · 🇰🇪 [sw](../../sw/docs/USER_GUIDE.md) · 🇮🇳 [ta](../../ta/docs/USER_GUIDE.md) · 🇮🇳 [te](../../te/docs/USER_GUIDE.md) · 🇹🇭 [th](../../th/docs/USER_GUIDE.md) · 🇹🇷 [tr](../../tr/docs/USER_GUIDE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/USER_GUIDE.md) · 🇵🇰 [ur](../../ur/docs/USER_GUIDE.md) · 🇻🇳 [vi](../../vi/docs/USER_GUIDE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/USER_GUIDE.md)
---
-Complete guide for configuring providers, creating combos, integrating CLI tools, and deploying OmniRoute.
+Panduan lengkap untuk mengonfigurasi penyedia, membuat combo, mengintegrasikan alat CLI, dan menerapkan OmniRoute.
---
-## Table of Contents
+## Daftar Isi
-- [Pricing at a Glance](#-pricing-at-a-glance)
-- [Use Cases](#-use-cases)
-- [Provider Setup](#-provider-setup)
-- [CLI Integration](#-cli-integration)
-- [Deployment](#-deployment)
-- [Available Models](#-available-models)
-- [Advanced Features](#-advanced-features)
+- [Harga Sekilas](#-harga-sekilas)
+- [Kasus Penggunaan](#-kasus-penggunaan)
+- [Pengaturan Penyedia](#-pengaturan-penyedia)
+- [Integrasi CLI](#-integrasi-cli)
+- [Penerapan](#penerapan)
+- [Model yang Tersedia](#-model-yang-tersedia)
+- [Fitur Lanjutan](#-fitur-lanjutan)
---
-## 💰 Pricing at a Glance
+## 💰 Harga Sekilas
-| Tier | Provider | Cost | Quota Reset | Best For |
-| ------------------- | ----------------- | ----------- | ---------------- | -------------------- |
-| **💳 SUBSCRIPTION** | Claude Code (Pro) | $20/mo | 5h + weekly | Already subscribed |
-| | Codex (Plus/Pro) | $20-200/mo | 5h + weekly | OpenAI users |
-| | Gemini CLI | **FREE** | 180K/mo + 1K/day | Everyone! |
-| | GitHub Copilot | $10-19/mo | Monthly | GitHub users |
-| **🔑 API KEY** | DeepSeek | Pay per use | None | Cheap reasoning |
-| | Groq | Pay per use | None | Ultra-fast inference |
-| | xAI (Grok) | Pay per use | None | Grok 4 reasoning |
-| | Mistral | Pay per use | None | EU-hosted models |
-| | Perplexity | Pay per use | None | Search-augmented |
-| | Together AI | Pay per use | None | Open-source models |
-| | Fireworks AI | Pay per use | None | Fast FLUX images |
-| | Cerebras | Pay per use | None | Wafer-scale speed |
-| | Cohere | Pay per use | None | Command R+ RAG |
-| | NVIDIA NIM | Pay per use | None | Enterprise models |
-| **💰 CHEAP** | GLM-4.7 | $0.6/1M | Daily 10AM | Budget backup |
-| | MiniMax M2.1 | $0.2/1M | 5-hour rolling | Cheapest option |
-| | Kimi K2 | $9/mo flat | 10M tokens/mo | Predictable cost |
-| **🆓 FREE** | Qoder | $0 | Unlimited | 8 models free |
-| | Qwen | $0 | Unlimited | 3 models free |
-| | Kiro | $0 | Unlimited | Claude free |
+| Tingkatan | Penyedia | Biaya | Reset Kuota | Terbaik Untuk |
+| ------------------- | ----------------- | ----------- | ---------------- | -------------------------- |
+| **💳 LANGGANAN** | Claude Code (Pro) | $20/bln | 5j + mingguan | Sudah berlangganan |
+| | Codex (Plus/Pro) | $20-200/bln | 5j + mingguan | Pengguna OpenAI |
+| | Gemini CLI | **GRATIS** | 180K/bln + 1K/hr | Semua orang! |
+| | GitHub Copilot | $10-19/bln | Bulanan | Pengguna GitHub |
+| **🔑 KUNCI API** | DeepSeek | Bayar pakai | Tidak ada | Penalaran murah |
+| | Groq | Bayar pakai | Tidak ada | Inferensi sangat cepat |
+| | xAI (Grok) | Bayar pakai | Tidak ada | Penalaran Grok 4 |
+| | Mistral | Bayar pakai | Tidak ada |Model berbasis EU |
+| | Perplexity | Bayar pakai | Tidak ada | Dilengkapi pencarian |
+| | Together AI | Bayar pakai | Tidak ada | Model sumber terbuka |
+| | Fireworks AI | Bayar pakai | Tidak ada | Gambar FLUX cepat |
+| | Cerebras | Bayar pakai | Tidak ada | Kecepatan skala wafer |
+| | Cohere | Bayar pakai | Tidak ada | RAG Command R+ |
+| | NVIDIA NIM | Bayar pakai | Tidak ada | Model enterprise |
+| **💰 MURAH** | GLM-4.7 | $0.6/1M | Harian pukul 10 | Cadangan hemat |
+| | MiniMax M2.1 | $0.2/1M | Bergulir 5 jam | Pilihan termurah |
+| | Kimi K2 | $9/bln flat | 10M token/bln | Biaya yang dapat diprediksi|
+| **🆓 GRATIS** | Qoder | $0 | Tidak terbatas | 8 model gratis |
+| | Qwen | $0 | Tidak terbatas | 3 model gratis |
+| | Kiro | $0 | Tidak terbatas | Claude gratis |
-**💡 Pro Tip:** Start with Gemini CLI (180K free/month) + Qoder (unlimited free) combo = $0 cost!
+**💡 Tips Pro:** Mulai dengan combo Gemini CLI (180K gratis/bulan) + Qoder (gratis tanpa batas) = biaya $0!
---
-## 🎯 Use Cases
+## 🎯 Kasus Penggunaan
-### Case 1: "I have Claude Pro subscription"
+### Kasus 1: "Saya punya langganan Claude Pro"
-**Problem:** Quota expires unused, rate limits during heavy coding
+**Masalah:** Kuota habis tidak terpakai, batas kecepatan saat coding intensif
```
Combo: "maximize-claude"
- 1. cc/claude-opus-4-7 (use subscription fully)
- 2. glm/glm-4.7 (cheap backup when quota out)
- 3. if/kimi-k2-thinking (free emergency fallback)
+ 1. cc/claude-opus-4-7 (gunakan langganan sepenuhnya)
+ 2. glm/glm-4.7 (cadangan murah saat kuota habis)
+ 3. if/kimi-k2-thinking (fallback darurat gratis)
-Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
-vs. $20 + hitting limits = frustration
+Biaya bulanan: $20 (langganan) + ~$5 (cadangan) = total $25
+vs. $20 + terkena batas = frustrasi
```
-### Case 2: "I want zero cost"
+### Kasus 2: "Saya ingin biaya nol"
-**Problem:** Can't afford subscriptions, need reliable AI coding
+**Masalah:** Tidak mampu berlangganan, butuh AI coding yang andal
```
Combo: "free-forever"
- 1. gc/gemini-3-flash (180K free/month)
- 2. if/kimi-k2-thinking (unlimited free)
- 3. qw/qwen3-coder-plus (unlimited free)
+ 1. gc/gemini-3-flash (180K gratis/bulan)
+ 2. if/kimi-k2-thinking (gratis tanpa batas)
+ 3. qw/qwen3-coder-plus (gratis tanpa batas)
-Monthly cost: $0
-Quality: Production-ready models
+Biaya bulanan: $0
+Kualitas: Model siap produksi
```
-### Case 3: "I need 24/7 coding, no interruptions"
+### Kasus 3: "Saya butuh coding 24/7, tanpa gangguan"
-**Problem:** Deadlines, can't afford downtime
+**Masalah:** Tenggat waktu, tidak boleh ada downtime
```
Combo: "always-on"
- 1. cc/claude-opus-4-7 (best quality)
- 2. cx/gpt-5.2-codex (second subscription)
- 3. glm/glm-4.7 (cheap, resets daily)
- 4. minimax/MiniMax-M2.1 (cheapest, 5h reset)
- 5. if/kimi-k2-thinking (free unlimited)
+ 1. cc/claude-opus-4-7 (kualitas terbaik)
+ 2. cx/gpt-5.2-codex (langganan kedua)
+ 3. glm/glm-4.7 (murah, reset harian)
+ 4. minimax/MiniMax-M2.1 (termurah, reset 5 jam)
+ 5. if/kimi-k2-thinking (gratis tanpa batas)
-Result: 5 layers of fallback = zero downtime
-Monthly cost: $20-200 (subscriptions) + $10-20 (backup)
+Hasil: 5 lapis fallback = nol downtime
+Biaya bulanan: $20-200 (langganan) + $10-20 (cadangan)
```
-### Case 4: "I want FREE AI in OpenClaw"
+### Kasus 4: "Saya ingin AI GRATIS di OpenClaw"
-**Problem:** Need AI assistant in messaging apps, completely free
+**Masalah:** Perlu asisten AI di aplikasi pesan, sepenuhnya gratis
```
Combo: "openclaw-free"
- 1. if/glm-4.7 (unlimited free)
- 2. if/minimax-m2.1 (unlimited free)
- 3. if/kimi-k2-thinking (unlimited free)
+ 1. if/glm-4.7 (gratis tanpa batas)
+ 2. if/minimax-m2.1 (gratis tanpa batas)
+ 3. if/kimi-k2-thinking (gratis tanpa batas)
-Monthly cost: $0
-Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
+Biaya bulanan: $0
+Akses melalui: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
-## 📖 Provider Setup
+## 📖 Pengaturan Penyedia
-### 🔐 Subscription Providers
+### 🔐 Penyedia Berlangganan
#### Claude Code (Pro/Max)
@@ -128,7 +128,7 @@ Models:
cc/claude-haiku-4-5-20251001
```
-**Pro Tip:** Use Opus for complex tasks, Sonnet for speed. OmniRoute tracks quota per model!
+**Tips Pro:** Gunakan Opus untuk tugas kompleks, Sonnet untuk kecepatan. OmniRoute melacak kuota per model!
#### OpenAI Codex (Plus/Pro)
@@ -142,7 +142,7 @@ Models:
cx/gpt-5.1-codex-max
```
-#### Gemini CLI (FREE 180K/month!)
+#### Gemini CLI (GRATIS 180K/bulan!)
```bash
Dashboard → Providers → Connect Gemini CLI
@@ -154,7 +154,7 @@ Models:
gc/gemini-2.5-pro
```
-**Best Value:** Huge free tier! Use this before paid tiers.
+**Nilai Terbaik:** Tingkat gratis yang sangat besar! Gunakan ini sebelum tingkatan berbayar.
#### GitHub Copilot
@@ -169,33 +169,33 @@ Models:
gh/gemini-3.1-pro-preview
```
-### 💰 Cheap Providers
+### 💰 Penyedia Murah
-#### GLM-4.7 (Daily reset, $0.6/1M)
+#### GLM-4.7 (Reset harian, $0.6/1M)
-1. Sign up: [Zhipu AI](https://open.bigmodel.cn/)
-2. Get API key from Coding Plan
-3. Dashboard → Add API Key: Provider: `glm`, API Key: `your-key`
+1. Daftar: [Zhipu AI](https://open.bigmodel.cn/)
+2. Dapatkan kunci API dari Coding Plan
+3. Dasbor → Tambahkan Kunci API: Penyedia: `glm`, Kunci API: `your-key`
-**Use:** `glm/glm-4.7` — **Pro Tip:** Coding Plan offers 3× quota at 1/7 cost! Reset daily 10:00 AM.
+**Gunakan:** `glm/glm-4.7` — **Tips Pro:** Coding Plan menawarkan kuota 3× dengan biaya 1/7! Reset setiap hari pukul 10:00.
-#### MiniMax M2.1 (5h reset, $0.20/1M)
+#### MiniMax M2.1 (Reset 5 jam, $0.20/1M)
-1. Sign up: [MiniMax](https://www.minimax.io/)
-2. Get API key → Dashboard → Add API Key
+1. Daftar: [MiniMax](https://www.minimax.io/)
+2. Dapatkan kunci API → Dasbor → Tambahkan Kunci API
-**Use:** `minimax/MiniMax-M2.1` — **Pro Tip:** Cheapest option for long context (1M tokens)!
+**Gunakan:** `minimax/MiniMax-M2.1` — **Tips Pro:** Pilihan termurah untuk konteks panjang (1M token)!
-#### Kimi K2 ($9/month flat)
+#### Kimi K2 ($9/bulan flat)
-1. Subscribe: [Moonshot AI](https://platform.moonshot.ai/)
-2. Get API key → Dashboard → Add API Key
+1. Berlangganan: [Moonshot AI](https://platform.moonshot.ai/)
+2. Dapatkan kunci API → Dasbor → Tambahkan Kunci API
-**Use:** `kimi/kimi-latest` — **Pro Tip:** Fixed $9/month for 10M tokens = $0.90/1M effective cost!
+**Gunakan:** `kimi/kimi-latest` — **Tips Pro:** Tetap $9/bulan untuk 10M token = biaya efektif $0.90/1M!
-### 🆓 FREE Providers
+### 🆓 Penyedia GRATIS
-#### Qoder (8 FREE models)
+#### Qoder (8 model GRATIS)
```bash
Dashboard → Connect Qoder → OAuth login → Unlimited usage
@@ -203,7 +203,7 @@ Dashboard → Connect Qoder → OAuth login → Unlimited usage
Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1
```
-#### Qwen (3 FREE models)
+#### Qwen (3 model GRATIS)
```bash
Dashboard → Connect Qwen → Device code auth → Unlimited usage
@@ -211,7 +211,7 @@ Dashboard → Connect Qwen → Device code auth → Unlimited usage
Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash
```
-#### Kiro (Claude FREE)
+#### Kiro (Claude GRATIS)
```bash
Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited
@@ -221,46 +221,46 @@ Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5
---
-## 🎨 Combos
+## 🎨 Combo
-You can reorder combo cards directly in **Dashboard → Combos** by dragging the handle on each card. The order is stored in SQLite and restored on reload.
+Anda dapat mengurutkan ulang kartu combo langsung di **Dashboard → Combos** dengan menyeret gagang pada setiap kartu. Urutan disimpan di SQLite dan dipulihkan saat dimuat ulang.
-### Example 1: Maximize Subscription → Cheap Backup
+### Contoh 1: Maksimalkan Langganan → Cadangan Murah
```
Dashboard → Combos → Create New
Name: premium-coding
Models:
- 1. cc/claude-opus-4-7 (Subscription primary)
- 2. glm/glm-4.7 (Cheap backup, $0.6/1M)
- 3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M)
+ 1. cc/claude-opus-4-7 (Langganan utama)
+ 2. glm/glm-4.7 (Cadangan murah, $0.6/1M)
+ 3. minimax/MiniMax-M2.1 (Fallback termurah, $0.20/1M)
Use in CLI: premium-coding
```
-### Example 2: Free-Only (Zero Cost)
+### Contoh 2: Hanya Gratis (Biaya Nol)
```
Name: free-combo
Models:
- 1. gc/gemini-3-flash-preview (180K free/month)
- 2. if/kimi-k2-thinking (unlimited)
- 3. qw/qwen3-coder-plus (unlimited)
+ 1. gc/gemini-3-flash-preview (180K gratis/bulan)
+ 2. if/kimi-k2-thinking (tanpa batas)
+ 3. qw/qwen3-coder-plus (tanpa batas)
-Cost: $0 forever!
+Cost: $0 selamanya!
```
---
-## 🔧 CLI Integration
+## 🔧 Integrasi CLI
### Cursor IDE
```
Settings → Models → Advanced:
OpenAI API Base URL: http://localhost:20128/v1
- OpenAI API Key: [from omniroute dashboard]
+ OpenAI API Key: [dari dasbor omniroute]
Model: cc/claude-opus-4-7
```
@@ -307,14 +307,14 @@ Edit `~/.openclaw/openclaw.json`:
}
```
-**Or use Dashboard:** CLI Tools → OpenClaw → Auto-config
+**Atau gunakan Dasbor:** CLI Tools → OpenClaw → Auto-config
### Cline / Continue / RooCode
```
Provider: OpenAI Compatible
Base URL: http://localhost:20128/v1
-API Key: [from dashboard]
+API Key: [dari dasbor]
Model: cc/claude-opus-4-7
```
@@ -322,7 +322,7 @@ Model: cc/claude-opus-4-7
## Penerapan
-### Global npm install (Recommended)
+### Instalasi npm Global (Direkomendasikan)
```bash
npm install -g omniroute
@@ -339,20 +339,20 @@ omniroute
omniroute --port 3000
```
-The CLI automatically loads `.env` from `~/.omniroute/.env` or `./.env`.
+CLI secara otomatis memuat `.env` dari `~/.omniroute/.env` atau `./.env`.
-### Uninstalling
+### Menghapus Instalasi
-When you no longer need OmniRoute, we provide two quick scripts for a clean removal:
+Saat Anda tidak lagi memerlukan OmniRoute, kami menyediakan dua skrip cepat untuk penghapusan bersih:
-| Command | Action |
-| ------------------------ | ----------------------------------------------------------------------------------- |
-| `npm run uninstall` | Removes the system app but **keeps your DB and configurations** in `~/.omniroute`. |
-| `npm run uninstall:full` | Removes the app AND permanently **erases all configurations, keys, and databases**. |
+| Perintah | Tindakan |
+| ------------------------ | -------------------------------------------------------------------------------------------------- |
+| `npm run uninstall` | Menghapus aplikasi dari sistem tetapi **menyimpan DB dan konfigurasi** di `~/.omniroute`. |
+| `npm run uninstall:full` | Menghapus aplikasi DAN secara permanen **menghapus semua konfigurasi, kunci, dan basis data**. |
-> Note: To run these commands, navigate to the OmniRoute project folder (if you cloned it) and run them. Alternatively, if globally installed, you can simply run `npm uninstall -g omniroute`.
+> Catatan: Untuk menjalankan perintah ini, navigasikan ke folder proyek OmniRoute (jika Anda telah meng-clone-nya) dan jalankan. Atau, jika diinstal secara global, Anda cukup menjalankan `npm uninstall -g omniroute`.
-### VPS Deployment
+### Penerapan VPS
```bash
git clone https://github.com/diegosouzapw/OmniRoute.git
@@ -371,9 +371,9 @@ npm run start
# Or: pm2 start npm --name omniroute -- start
```
-### PM2 Deployment (Low Memory)
+### Penerapan PM2 (Memori Rendah)
-For servers with limited RAM, use the memory limit option:
+Untuk server dengan RAM terbatas, gunakan opsi batas memori:
```bash
# With 512MB limit (default)
@@ -386,7 +386,7 @@ OMNIROUTE_MEMORY_MB=512 pm2 start npm --name omniroute -- start
pm2 start ecosystem.config.js
```
-Create `ecosystem.config.js`:
+Buat `ecosystem.config.js`:
```javascript
module.exports = {
@@ -418,14 +418,14 @@ docker build -t omniroute:cli .
docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli
```
-For host-integrated mode with CLI binaries, see the Docker section in the main docs.
+Untuk mode integrasi host dengan binari CLI, lihat bagian Docker di dokumentasi utama.
### Void Linux (xbps-src)
-Void Linux users can package and install OmniRoute natively using the `xbps-src` cross-compilation framework. This automates the Node.js standalone build along with the required `better-sqlite3` native bindings.
+Pengguna Void Linux dapat mengemas dan menginstal OmniRoute secara native menggunakan framework kompilasi silang `xbps-src`. Ini mengotomasi build standalone Node.js beserta binding native `better-sqlite3` yang diperlukan.
-View xbps-src template
+Lihat template xbps-src
```bash
# Template file for 'omniroute'
@@ -520,45 +520,45 @@ post_install() {
-### Environment Variables
+### Variabel Lingkungan
-| Variable | Default | Description |
-| --------------------------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------- |
-| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signing secret (**change in production**) |
-| `INITIAL_PASSWORD` | `123456` | First login password |
-| `DATA_DIR` | `~/.omniroute` | Data directory (db, usage, logs) |
-| `PORT` | framework default | Service port (`20128` in examples) |
-| `HOSTNAME` | framework default | Bind host (Docker defaults to `0.0.0.0`) |
-| `NODE_ENV` | runtime default | Set `production` for deploy |
-| `BASE_URL` | `http://localhost:20128` | Server-side internal base URL |
-| `CLOUD_URL` | `https://omniroute.dev` | Cloud sync endpoint base URL |
-| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC secret for generated API keys |
-| `REQUIRE_API_KEY` | `false` | Enforce Bearer API key on `/v1/*` |
-| `ALLOW_API_KEY_REVEAL` | `false` | Allow Api Manager to copy full API keys on demand |
-| `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | Server-side refresh cadence for cached Provider Limits data; UI refresh buttons still trigger manual sync |
-| `DISABLE_SQLITE_AUTO_BACKUP` | `false` | Disable automatic SQLite snapshots before writes/import/restore; manual backups still work |
-| `APP_LOG_TO_FILE` | `true` | Enables application and audit log output to disk |
-| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) |
-| `CLOUDFLARED_BIN` | unset | Use an existing `cloudflared` binary instead of managed download |
-| `CLOUDFLARED_PROTOCOL` | `http2` | Transport for managed Quick Tunnels (`http2`, `quic`, or `auto`) |
-| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit in MB |
-| `PROMPT_CACHE_MAX_SIZE` | `50` | Max prompt cache entries |
-| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Max semantic cache entries |
+| Variabel | Default | Deskripsi |
+| --------------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
+| `JWT_SECRET` | `omniroute-default-secret-change-me` | Rahasia penandatanganan JWT (**ubah di produksi**) |
+| `INITIAL_PASSWORD` | `123456` | Kata sandi login pertama |
+| `DATA_DIR` | `~/.omniroute` | Direktori data (db, penggunaan, log) |
+| `PORT` | default framework | Port layanan (`20128` dalam contoh) |
+| `HOSTNAME` | default framework | Host bind (Docker default ke `0.0.0.0`) |
+| `NODE_ENV` | default runtime | Atur `production` untuk penerapan |
+| `BASE_URL` | `http://localhost:20128` | URL berbasis sisi server internal |
+| `CLOUD_URL` | `https://omniroute.dev` | Cloud sinkronisasi titik akhir berbasis URL |
+| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | Rahasia HMAC untuk kunci API yang dihasilkan |
+| `REQUIRE_API_KEY` | `false` | Wajibkan kunci API Bearer di `/v1/*` |
+| `ALLOW_API_KEY_REVEAL` | `false` | Izinkan Api Manager menyalin kunci API lengkap sesuai permintaan |
+| `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | Frekuensi refresh sisi server untuk data Provider Limits yang di-cache; tombol refresh UI tetap memicu sinkronisasi manual |
+| `DISABLE_SQLITE_AUTO_BACKUP` | `false` | Nonaktifkan snapshot SQLite otomatis sebelum tulis/impor/pemulihan; backup manual tetap berfungsi |
+| `APP_LOG_TO_FILE` | `true` | Mengaktifkan output log aplikasi dan audit ke disk |
+| `AUTH_COOKIE_SECURE` | `false` | Paksa cookie auth `Secure` (di belakang reverse proxy HTTPS) |
+| `CLOUDFLARED_BIN` | tidak diatur | Gunakan binari `cloudflared` yang sudah ada alih-alih unduhan terkelola |
+| `CLOUDFLARED_PROTOCOL` | `http2` | Transport untuk Quick Tunnel terkelola (`http2`, `quic`, atau `auto`) |
+| `OMNIROUTE_MEMORY_MB` | `512` | Batas heap Node.js dalam MB |
+| `PROMPT_CACHE_MAX_SIZE` | `50` | Entri cache prompt maksimum |
+| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Entri cache semantik maksimum |
-For the full environment variable reference, see the [README](../README.md).
+Untuk referensi variabel lingkungan lengkap, lihat [README](../README.md).
---
-## 📊 Available Models
+## 📊 Model yang Tersedia
-View all available models
+Lihat semua model yang tersedia
**Claude Code (`cc/`)** — Pro/Max: `cc/claude-opus-4-7`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001`
**Codex (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max`
-**Gemini CLI (`gc/`)** — FREE: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro`
+**Gemini CLI (`gc/`)** — GRATIS: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet`
@@ -566,11 +566,11 @@ For the full environment variable reference, see the [README](../README.md).
**MiniMax (`minimax/`)** — $0.2/1M: `minimax/MiniMax-M2.1`
-**Qoder (`if/`)** — FREE: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1`
+**Qoder (`if/`)** — GRATIS: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1`
-**Qwen (`qw/`)** — FREE: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash`
+**Qwen (`qw/`)** — GRATIS: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash`
-**Kiro (`kr/`)** — FREE: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5`
+**Kiro (`kr/`)** — GRATIS: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5`
**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner`
@@ -596,11 +596,11 @@ For the full environment variable reference, see the [README](../README.md).
---
-## 🧩 Advanced Features
+## 🧩 Fitur Lanjutan
-### Custom Models
+### Model Kustom
-Add any model ID to any provider without waiting for an app update:
+Tambahkan ID model apa pun ke penyedia mana pun tanpa menunggu pembaruan aplikasi:
```bash
# Via API
@@ -612,16 +612,16 @@ curl -X POST http://localhost:20128/api/provider-models \
# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview"
```
-Or use Dashboard: **Providers → [Provider] → Custom Models**.
+Atau gunakan Dasbor: **Penyedia → [Penyedia] → Model Khusus**.
-Notes:
+Catatan:
-- OpenRouter and OpenAI/Anthropic-compatible providers are managed from **Available Models** only. Manual add, import, and auto-sync all land in the same available-model list, so there is no separate Custom Models section for those providers.
-- The **Custom Models** section is intended for providers that do not expose managed available-model imports.
+- Penyedia yang kompatibel dengan OpenRouter dan OpenAI/Anthropic dikelola hanya melalui **Available Models**. Penambahan manual, impor, dan auto-sync semuanya masuk ke daftar model yang sama, sehingga tidak ada bagian Custom Models terpisah untuk penyedia tersebut.
+- Bagian **Custom Models** ditujukan untuk penyedia yang tidak mengekspos impor model yang terkelola.
-### Dedicated Provider Routes
+### Rute Penyedia Khusus
-Route requests directly to a specific provider with model validation:
+Arahkan permintaan langsung ke penyedia tertentu dengan validasi model:
```bash
POST http://localhost:20128/v1/providers/openai/chat/completions
@@ -629,9 +629,9 @@ POST http://localhost:20128/v1/providers/openai/embeddings
POST http://localhost:20128/v1/providers/fireworks/images/generations
```
-The provider prefix is auto-added if missing. Mismatched models return `400`.
+Awalan penyedia ditambahkan otomatis jika tidak ada. Model yang tidak cocok mengembalikan `400`.
-### Network Proxy Configuration
+### Konfigurasi Proxy Jaringan
```bash
# Set global proxy
@@ -647,103 +647,103 @@ curl -X POST http://localhost:20128/api/settings/proxy/test \
-d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}'
```
-**Precedence:** Key-specific → Combo-specific → Provider-specific → Global → Environment.
+**Urutan Prioritas:** Spesifik-kunci → Spesifik-combo → Spesifik-penyedia → Global → Lingkungan.
-### Model Catalog API
+### API Katalog Model
```bash
curl http://localhost:20128/api/models/catalog
```
-Returns models grouped by provider with types (`chat`, `embedding`, `image`).
+Mengembalikan model yang dikelompokkan berdasarkan penyedia dengan tipe (`chat`, `embedding`, `image`).
-### Cloud Sync
+### Sinkronisasi Cloud
-- Sync providers, combos, and settings across devices
-- Automatic background sync with timeout + fail-fast
-- Prefer server-side `BASE_URL`/`CLOUD_URL` in production
+- Sinkronkan penyedia, combo, dan pengaturan di semua perangkat
+- Sinkronisasi latar belakang otomatis dengan timeout + gagal cepat
+- Gunakan `BASE_URL`/`CLOUD_URL` sisi server di produksi
### Cloudflare Quick Tunnel
-- Available in **Dashboard → Endpoints** for Docker and other self-hosted deployments
-- Creates a temporary `https://*.trycloudflare.com` URL that forwards to your current OpenAI-compatible `/v1` endpoint
-- First enable installs `cloudflared` only when needed; later restarts reuse the same managed binary
-- Quick Tunnels are not auto-restored after an OmniRoute or container restart; re-enable them from the dashboard when needed
-- Tunnel URLs are ephemeral and change every time you stop/start the tunnel
-- Managed Quick Tunnels default to HTTP/2 transport to avoid noisy QUIC UDP buffer warnings in constrained containers
-- Set `CLOUDFLARED_PROTOCOL=quic` or `auto` if you want to override the managed transport choice
-- Set `CLOUDFLARED_BIN` if you prefer using a preinstalled `cloudflared` binary instead of the managed download
+- Tersedia di **Dashboard → Endpoints** untuk penerapan Docker dan self-hosted lainnya
+- Membuat URL `https://*.trycloudflare.com` sementara yang diteruskan ke endpoint `/v1` Anda yang kompatibel dengan OpenAI
+- Aktifkan pertama kali untuk menginstal `cloudflared` hanya saat diperlukan; restart berikutnya menggunakan kembali binari terkelola yang sama
+- Quick Tunnel tidak dipulihkan otomatis setelah OmniRoute atau container di-restart; aktifkan kembali dari dasbor bila diperlukan
+- URL tunnel bersifat sementara dan berubah setiap kali Anda menghentikan/memulai tunnel
+- Managed Quick Tunnel secara default menggunakan transport HTTP/2 untuk menghindari peringatan buffer UDP QUIC yang mengganggu di container terbatas
+- Atur `CLOUDFLARED_PROTOCOL=quic` atau `auto` jika ingin mengubah pilihan transport terkelola
+- Atur `CLOUDFLARED_BIN` jika ingin menggunakan binari `cloudflared` yang sudah terinstal alih-alih unduhan terkelola
-### LLM Gateway Intelligence (Phase 9)
+### Kecerdasan LLM Gateway (Fase 9)
-- **Semantic Cache** — Auto-caches non-streaming, temperature=0 responses (bypass with `X-OmniRoute-No-Cache: true`)
-- **Request Idempotency** — Deduplicates requests within 5s via `Idempotency-Key` or `X-Request-Id` header
-- **Progress Tracking** — Opt-in SSE `event: progress` events via `X-OmniRoute-Progress: true` header
+- **Cache Semantik** — Otomatis menyimpan respons non-streaming, temperature=0 (lewati dengan `X-OmniRoute-No-Cache: true`)
+- **Idempotensitas Permintaan** — Mendeduplikasi permintaan dalam 5 detik melalui header `Idempotency-Key` atau `X-Request-Id`
+- **Pelacakan Progres** — Event SSE `event: progress` yang bisa diaktifkan melalui header `X-OmniRoute-Progress: true`
---
### Translator Playground
-Access via **Dashboard → Translator**. Debug and visualize how OmniRoute translates API requests between providers.
+Akses melalui **Dashboard → Translator**. Debug dan visualisasikan bagaimana OmniRoute menerjemahkan permintaan API antar penyedia.
-| Mode | Purpose |
-| ---------------- | -------------------------------------------------------------------------------------- |
-| **Playground** | Select source/target formats, paste a request, and see the translated output instantly |
-| **Chat Tester** | Send live chat messages through the proxy and inspect the full request/response cycle |
-| **Test Bench** | Run batch tests across multiple format combinations to verify translation correctness |
-| **Live Monitor** | Watch real-time translations as requests flow through the proxy |
+| Mode | Tujuan |
+| ---------------- | ------------------------------------------------------------------------------------------------ |
+| **Playground** | Pilih format sumber/target, tempel permintaan, dan lihat hasil terjemahan secara instan |
+| **Chat Tester** | Kirim pesan chat langsung melalui proxy dan periksa siklus permintaan/respons lengkap |
+| **Test Bench** | Jalankan pengujian batch di berbagai kombinasi format untuk memverifikasi kebenaran terjemahan |
+| **Live Monitor** | Amati terjemahan real-time saat permintaan mengalir melalui proxy |
-**Use cases:**
+**Kasus penggunaan:**
-- Debug why a specific client/provider combination fails
-- Verify that thinking tags, tool calls, and system prompts translate correctly
-- Compare format differences between OpenAI, Claude, Gemini, and Responses API formats
+- Debug mengapa kombinasi klien/penyedia tertentu gagal
+- Verifikasi bahwa tag thinking, pemanggilan tool, dan system prompt diterjemahkan dengan benar
+- Bandingkan perbedaan format antara OpenAI, Claude, Gemini, dan format Responses API
---
-### Routing Strategies
+### Strategi Routing
-Configure via **Dashboard → Settings → Routing**.
+Konfigurasikan melalui **Dasbor → Pengaturan → Perutean**.
| Strategy | Description |
| ------------------------------ | ------------------------------------------------------------------------------------------------ |
-| **Fill First** | Uses accounts in priority order — primary account handles all requests until unavailable |
-| **Round Robin** | Cycles through all accounts with a configurable sticky limit (default: 3 calls per account) |
-| **P2C (Power of Two Choices)** | Picks 2 random accounts and routes to the healthier one — balances load with awareness of health |
-| **Random** | Randomly selects an account for each request using Fisher-Yates shuffle |
-| **Least Used** | Routes to the account with the oldest `lastUsedAt` timestamp, distributing traffic evenly |
-| **Cost Optimized** | Routes to the account with the lowest priority value, optimizing for lowest-cost providers |
+| **Fill First** | Menggunakan akun dalam urutan prioritas — akun utama menangani semua permintaan hingga tidak tersedia |
+| **Round Robin** | Menggilir semua akun dengan batas melekat yang dapat dikonfigurasi (default: 3 panggilan per akun) |
+| **P2C (Power of Two Choices)** | Pilih 2 akun acak dan rute ke akun yang lebih sehat — menyeimbangkan beban dengan kesadaran akan kesehatan |
+| **Random** | Memilih akun secara acak untuk setiap permintaan menggunakan pengacakan Fisher-Yates |
+| **Least Used** | Merutekan ke akun dengan stempel waktu `lastUsedAt` terlama, mendistribusikan lalu lintas secara merata |
+| **Cost Optimized** | Merutekan ke akun dengan nilai prioritas terendah, mengoptimalkan penyedia berbiaya terendah |
-#### External Sticky Session Header
+#### Header Sesi Lengket Eksternal
-For external session affinity (for example, Claude Code/Codex agents behind reverse proxies), send:
+Untuk afinitas sesi eksternal (misalnya, agen Claude Code/Codex di belakang proxy terbalik), kirim:
```http
X-Session-Id: your-session-key
```
-OmniRoute also accepts `x_session_id` and returns the effective session key in `X-OmniRoute-Session-Id`.
+OmniRoute juga menerima `x_session_id` dan mengembalikan kunci sesi efektif di `X-OmniRoute-Session-Id`.
-If you use Nginx and send underscore-form headers, enable:
+Jika Anda menggunakan Nginx dan mengirim header berbentuk garis bawah, aktifkan:
```nginx
underscores_in_headers on;
```
-#### Wildcard Model Aliases
+#### Model Alias Wildcard
-Create wildcard patterns to remap model names:
+Buat pola wildcard untuk memetakan ulang nama model:
```
Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929
Pattern: gpt-* → Target: gh/gpt-5.1-codex
```
-Wildcards support `*` (any characters) and `?` (single character).
+Wildcard mendukung `*` (karakter apa saja) dan `?` (karakter tunggal).
#### Fallback Chains
-Define global fallback chains that apply across all requests:
+Tentukan rantai fallback global yang berlaku di semua permintaan:
```
Chain: production-fallback
@@ -754,50 +754,50 @@ Chain: production-fallback
---
-### Resilience & Circuit Breakers
+### Ketahanan & Pemutus Sirkuit
-Configure via **Dashboard → Settings → Resilience**.
+Konfigurasikan melalui **Dasbor → Pengaturan → Ketahanan**.
-OmniRoute implements provider-level resilience with five components:
+OmniRoute mengimplementasikan ketahanan tingkat penyedia dengan lima komponen:
-1. **Request Queue & Pacing** — System-level request shaping:
- - **Requests Per Minute (RPM)** — Maximum requests per minute per account
- - **Min Time Between Requests** — Minimum gap in milliseconds between requests
- - **Max Concurrent Requests** — Maximum simultaneous requests per account
+1. **Antrian & Kecepatan Permintaan** — Pembentukan permintaan tingkat sistem:
+ - **Permintaan Per Menit (RPM)** — Permintaan maksimum per menit per akun
+ - **Waktu Minimum Antar Permintaan** — Kesenjangan minimum dalam milidetik antar permintaan
+ - **Permintaan Bersamaan Maksimum** — Permintaan simultan maksimum per akun
-2. **Connection Cooldown** — Per-auth-type configuration for a single connection after retryable failures:
- - **Base Cooldown** — Default cooldown window for retryable upstream failures
- - **Use Upstream Retry Hints** — Honors authoritative `Retry-After` or reset hints when provided
- - **Max Backoff Steps** — Maximum exponential backoff level for repeated failures
+2. **Cooldown Koneksi** — Konfigurasi tipe per autentikasi untuk satu koneksi setelah kegagalan yang dapat dicoba lagi:
+ - **Cooldown Dasar** — Jendela cooldown default untuk kegagalan upstream yang dapat dicoba ulang
+ - **Gunakan Petunjuk Coba Ulang Hulu** — Ikuti `Retry-After` resmi atau petunjuk setel ulang bila diberikan
+ - **Langkah Backoff Maks** — Tingkat backoff eksponensial maksimum untuk kegagalan berulang
-3. **Provider Circuit Breaker** — Tracks end-to-end provider failures and automatically opens the breaker when the configured threshold is reached:
- - **Failure Threshold** — Consecutive provider failures before opening the breaker
- - **Reset Timeout** — Time window before the provider is tested again
- - **CLOSED** (Healthy) — Requests flow normally
- - **OPEN** — Provider is temporarily blocked after repeated failures
- - **HALF_OPEN** — Testing if provider has recovered
+3. **Pemutus Sirkuit Penyedia** — Melacak kegagalan penyedia ujung ke ujung dan secara otomatis membuka pemutus ketika ambang batas yang dikonfigurasi tercapai:
+ - **Ambang Kegagalan** — Kegagalan penyedia berturut-turut sebelum membuka pemutus
+ - **Reset Timeout** — Jangka waktu sebelum penyedia diuji lagi
+ - **TUTUP** (Sehat) — Permintaan mengalir normal
+ - **BUKA** — Penyedia diblokir sementara setelah kegagalan berulang kali
+ - **HALF_OPEN** — Menguji apakah penyedia telah pulih
- Connection-scoped `429` rate limits stay in **Connection Cooldown** and do not count toward the provider breaker.
+ Batas kecepatan `429` cakupan koneksi tetap dalam **Cooldown Koneksi** dan tidak diperhitungkan dalam pemutus penyedia.
- The provider breaker runtime state is shown on **Dashboard → Health** only.
+ Status waktu proses pemutus penyedia hanya ditampilkan di **Dasbor → Kesehatan**.
-4. **Wait For Cooldown** — If every candidate connection is already cooling down, OmniRoute can wait for the earliest cooldown and retry the same client request automatically.
+4. **Tunggu Cooldown** — Jika setiap kandidat koneksi sudah cooldown, OmniRoute dapat menunggu cooldown paling awal dan mencoba kembali permintaan klien yang sama secara otomatis.
-5. **Rate Limit Auto-Detection** — When upstream providers return explicit wait windows, those hints override the local connection cooldown when the setting is enabled.
+5. **Deteksi Otomatis Batas Kecepatan** — Saat penyedia upstream mengembalikan jendela tunggu eksplisit, petunjuk tersebut akan menggantikan jeda pakai koneksi lokal saat pengaturan diaktifkan.
-**Pro Tip:** Use the **Health** page to inspect and reset live provider breakers after an outage. The Resilience page only changes configuration.
+**Kiat Pro:** Gunakan laman **Kesehatan** untuk memeriksa dan menyetel ulang pemutus penyedia langsung setelah pemadaman. Halaman Ketahanan hanya mengubah konfigurasi.
---
-### Database Export / Import
+### Ekspor/Impor Basis Data
-Manage database backups in **Dashboard → Settings → System & Storage**.
+Kelola cadangan basis data di **Dasbor → Pengaturan → Sistem & Penyimpanan**.
| Action | Description |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
-| **Export Database** | Downloads the current SQLite database as a `.sqlite` file |
-| **Export All (.tar.gz)** | Downloads a full backup archive including: database, settings, combos, provider connections (no credentials), API key metadata |
-| **Import Database** | Upload a `.sqlite` file to replace the current database. A pre-import backup is automatically created unless `DISABLE_SQLITE_AUTO_BACKUP=true` |
+| **Export Database** | Mengunduh database SQLite saat ini sebagai file `.sqlite` |
+| **Ekspor Semua (.tar.gz)** | Mengunduh arsip cadangan lengkap termasuk: basis data, pengaturan, kombo, koneksi penyedia (tanpa kredensial), metadata kunci API |
+| **Import Database** | Unggah file `.sqlite` untuk menggantikan database saat ini. Cadangan pra-impor dibuat secara otomatis kecuali `DISABLE_SQLITE_AUTO_BACKUP=true` |
```bash
# API: Export database
@@ -811,39 +811,39 @@ curl -X POST http://localhost:20128/api/db-backups/import \
-F "file=@backup.sqlite"
```
-**Import Validation:** The imported file is validated for integrity (SQLite pragma check), required tables (`provider_connections`, `provider_nodes`, `combos`, `api_keys`), and size (max 100MB).
+**Validasi Impor:** File yang diimpor divalidasi integritasnya (pemeriksaan pragma SQLite), tabel yang diperlukan (`provider_connections`, `provider_nodes`, `combos`, `api_keys`), dan ukuran (maks 100MB).
**Use Cases:**
-- Migrate OmniRoute between machines
-- Create external backups for disaster recovery
-- Share configurations between team members (export all → share archive)
+- Migrasi OmniRoute antar mesin
+- Buat cadangan eksternal untuk pemulihan bencana
+- Bagikan konfigurasi antar anggota tim (ekspor semua → bagikan arsip)
---
-### Settings Dashboard
+### Dashboard Pengaturan
-The settings page is organized into 6 tabs for easy navigation:
+Halaman pengaturan disusun menjadi 6 tab untuk memudahkan navigasi:
| Tab | Contents |
| -------------- | -------------------------------------------------------------------------------------------- |
| **General** | System storage tools, appearance settings, theme controls, and per-item sidebar visibility |
-| **Security** | Login/Password settings, IP Access Control, API auth for `/models`, and Provider Blocking |
+| **Security** |Pengaturan Login/Kata Sandi, Kontrol Akses IP, autentikasi API untuk `/models`, dan Pemblokiran Penyedia |
| **Routing** | Global routing strategy (6 options), wildcard model aliases, fallback chains, combo defaults |
-| **Resilience** | Request queue, connection cooldown, provider breaker config, and wait-for-cooldown behavior |
+| **Resilience** | Antrean permintaan, waktu tunggu koneksi, konfigurasi pemutus penyedia, dan perilaku menunggu waktu tunggu |
| **AI** | Thinking budget configuration, global system prompt injection, prompt cache stats |
-| **Advanced** | Global proxy configuration (HTTP/SOCKS5) |
+| **Advanced** | Konfigurasi proksi global (HTTP/SOCKS5) |
---
-### Costs & Budget Management
+### Biaya & Manajemen Anggaran
-Access via **Dashboard → Costs**.
+Akses melalui **Dasbor → Biaya**.
| Tab | Purpose |
| ----------- | ---------------------------------------------------------------------------------------- |
-| **Budget** | Set spending limits per API key with daily/weekly/monthly budgets and real-time tracking |
-| **Pricing** | View and edit model pricing entries — cost per 1K input/output tokens per provider |
+| **Budget** | Tetapkan batas pengeluaran per kunci API dengan anggaran harian/mingguan/bulanan dan pelacakan waktu nyata |
+| **Pricing** | Lihat dan edit entri harga model — biaya per 1K token input/output per penyedia |
```bash
# API: Set a budget
@@ -855,13 +855,13 @@ curl -X POST http://localhost:20128/api/usage/budget \
curl http://localhost:20128/api/usage/budget
```
-**Cost Tracking:** Every request logs token usage and calculates cost using the pricing table. View breakdowns in **Dashboard → Usage** by provider, model, and API key.
+**Pelacakan Biaya:** Setiap permintaan mencatat penggunaan token dan menghitung biaya menggunakan tabel harga. Lihat pengelompokan di **Dasbor → Penggunaan** menurut penyedia, model, dan kunci API.
---
-### Audio Transcription
+### Transkripsi Audio
-OmniRoute supports audio transcription via the OpenAI-compatible endpoint:
+OmniRoute mendukung transkripsi audio melalui titik akhir yang kompatibel dengan OpenAI:
```bash
POST /v1/audio/transcriptions
@@ -875,49 +875,49 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \
-F "model=deepgram/nova-3"
```
-Available providers: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`).
+Penyedia yang tersedia: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`).
-Supported audio formats: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
+Format audio yang didukung: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
---
-### Combo Balancing Strategies
+### Strategi Penyeimbangan Kombo
-Configure per-combo balancing in **Dashboard → Combos → Create/Edit → Strategy**.
+Konfigurasikan penyeimbangan per kombo di **Dasbor → Kombo → Buat/Edit → Strategi**.
| Strategy | Description |
| ------------------ | ------------------------------------------------------------------------ |
-| **Round-Robin** | Rotates through models sequentially |
-| **Priority** | Always tries the first model; falls back only on error |
-| **Random** | Picks a random model from the combo for each request |
-| **Weighted** | Routes proportionally based on assigned weights per model |
-| **Least-Used** | Routes to the model with the fewest recent requests (uses combo metrics) |
-| **Cost-Optimized** | Routes to the cheapest available model (uses pricing table) |
+| **Round-Robin** | Berputar melalui model secara berurutan |
+| **Priority** | Selalu mencoba model pertama; jatuh kembali hanya karena kesalahan |
+| **Random** | Memilih model acak dari kombo untuk setiap permintaan |
+| **Weighted** | Rute secara proporsional berdasarkan bobot yang ditetapkan per model |
+| **Least-Used** | Merutekan ke model dengan permintaan terkini paling sedikit (menggunakan metrik kombo) |
+| **Cost-Optimized** | Rute ke model termurah yang tersedia (menggunakan tabel harga) |
-Global combo defaults can be set in **Dashboard → Settings → Routing → Combo Defaults**.
+Default kombo global dapat diatur di **Dasbor → Pengaturan → Perutean → Default Kombo**.
---
-### Health Dashboard
+### Dashboard Kesehatan
-Access via **Dashboard → Health**. Real-time system health overview with 6 cards:
+Akses melalui **Dasbor → Kesehatan**. Ikhtisar kesehatan sistem real-time dengan 6 kartu:
-| Card | What It Shows |
+| Card | Apa yang Ditunjukkannya |
| --------------------- | ----------------------------------------------------------- |
| **System Status** | Uptime, version, memory usage, data directory |
-| **Provider Health** | Global provider circuit breaker runtime state |
-| **Rate Limits** | Active connection cooldowns per account with remaining time |
-| **Active Lockouts** | Active model-scoped lockouts and temporary exclusions |
-| **Signature Cache** | Deduplication cache stats (active keys, hit rate) |
-| **Latency Telemetry** | p50/p95/p99 latency aggregation per provider |
+| **Provider Health** | Status runtime pemutus sirkuit penyedia global |
+| **Rate Limits** | Cooldown koneksi aktif per akun dengan sisa waktu |
+| **Active Lockouts** | Penguncian cakupan model aktif dan pengecualian sementara |
+| **Signature Cache** | Statistik cache deduplikasi (kunci aktif, tingkat hit) |
+| **Latency Telemetry** | agregasi latensi p50/p95/p99 per penyedia |
-**Pro Tip:** The Health page auto-refreshes every 10 seconds. Use the circuit breaker card to identify which providers are experiencing issues.
+**Tips Pro:** Halaman Kesehatan disegarkan secara otomatis setiap 10 detik. Gunakan kartu pemutus sirkuit untuk mengidentifikasi penyedia mana yang mengalami masalah.
---
-## 🖥️ Desktop Application (Electron)
+## 🖥️ Aplikasi Desktop (Elektron)
-OmniRoute is available as a native desktop application for Windows, macOS, and Linux.
+OmniRoute tersedia sebagai aplikasi desktop asli untuk Windows, macOS, dan Linux.
### Instal
@@ -933,7 +933,7 @@ npm run dev
npm start
```
-### Building Installers
+### Membuat Installer
```bash
cd electron
@@ -945,18 +945,18 @@ npm run build:linux # Linux (.AppImage)
Output → `electron/dist-electron/`
-### Key Features
+### Fitur Utama
| Feature | Description |
| --------------------------- | ---------------------------------------------------- |
-| **Server Readiness** | Polls server before showing window (no blank screen) |
+| **Server Readiness** |Server jajak pendapat sebelum menampilkan jendela (tidak ada layar kosong) |
| **System Tray** | Minimize to tray, change port, quit from tray menu |
-| **Port Management** | Change server port from tray (auto-restarts server) |
-| **Content Security Policy** | Restrictive CSP via session headers |
-| **Single Instance** | Only one app instance can run at a time |
-| **Offline Mode** | Bundled Next.js server works without internet |
+| **Port Management** | Ubah port server dari baki (server restart otomatis) |
+| **Kebijakan Keamanan Konten** | CSP terbatas melalui header sesi |
+| **Single Instance** | Hanya satu instance aplikasi yang dapat berjalan dalam satu waktu |
+| **Offline Mode** | Server Next.js yang dibundel berfungsi tanpa internet|
-### Environment Variables
+### Variabel Lingkungan
| Variable | Default | Description |
| --------------------- | ------- | -------------------------------- |
diff --git a/docs/i18n/id/docs/ops/COVERAGE_PLAN.md b/docs/i18n/id/docs/ops/COVERAGE_PLAN.md
index 3437f09f0f..45dd535d43 100644
--- a/docs/i18n/id/docs/ops/COVERAGE_PLAN.md
+++ b/docs/i18n/id/docs/ops/COVERAGE_PLAN.md
@@ -1,158 +1,158 @@
-# Test Coverage Plan (Bahasa Indonesia)
+# Rencana Cakupan Pengujian (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/COVERAGE_PLAN.md) · 🇸🇦 [ar](../../ar/docs/COVERAGE_PLAN.md) · 🇧🇬 [bg](../../bg/docs/COVERAGE_PLAN.md) · 🇧🇩 [bn](../../bn/docs/COVERAGE_PLAN.md) · 🇨🇿 [cs](../../cs/docs/COVERAGE_PLAN.md) · 🇩🇰 [da](../../da/docs/COVERAGE_PLAN.md) · 🇩🇪 [de](../../de/docs/COVERAGE_PLAN.md) · 🇪🇸 [es](../../es/docs/COVERAGE_PLAN.md) · 🇮🇷 [fa](../../fa/docs/COVERAGE_PLAN.md) · 🇫🇮 [fi](../../fi/docs/COVERAGE_PLAN.md) · 🇫🇷 [fr](../../fr/docs/COVERAGE_PLAN.md) · 🇮🇳 [gu](../../gu/docs/COVERAGE_PLAN.md) · 🇮🇱 [he](../../he/docs/COVERAGE_PLAN.md) · 🇮🇳 [hi](../../hi/docs/COVERAGE_PLAN.md) · 🇭🇺 [hu](../../hu/docs/COVERAGE_PLAN.md) · 🇮🇩 [id](../../id/docs/COVERAGE_PLAN.md) · 🇮🇹 [it](../../it/docs/COVERAGE_PLAN.md) · 🇯🇵 [ja](../../ja/docs/COVERAGE_PLAN.md) · 🇰🇷 [ko](../../ko/docs/COVERAGE_PLAN.md) · 🇮🇳 [mr](../../mr/docs/COVERAGE_PLAN.md) · 🇲🇾 [ms](../../ms/docs/COVERAGE_PLAN.md) · 🇳🇱 [nl](../../nl/docs/COVERAGE_PLAN.md) · 🇳🇴 [no](../../no/docs/COVERAGE_PLAN.md) · 🇵🇭 [phi](../../phi/docs/COVERAGE_PLAN.md) · 🇵🇱 [pl](../../pl/docs/COVERAGE_PLAN.md) · 🇵🇹 [pt](../../pt/docs/COVERAGE_PLAN.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/COVERAGE_PLAN.md) · 🇷🇴 [ro](../../ro/docs/COVERAGE_PLAN.md) · 🇷🇺 [ru](../../ru/docs/COVERAGE_PLAN.md) · 🇸🇰 [sk](../../sk/docs/COVERAGE_PLAN.md) · 🇸🇪 [sv](../../sv/docs/COVERAGE_PLAN.md) · 🇰🇪 [sw](../../sw/docs/COVERAGE_PLAN.md) · 🇮🇳 [ta](../../ta/docs/COVERAGE_PLAN.md) · 🇮🇳 [te](../../te/docs/COVERAGE_PLAN.md) · 🇹🇭 [th](../../th/docs/COVERAGE_PLAN.md) · 🇹🇷 [tr](../../tr/docs/COVERAGE_PLAN.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/COVERAGE_PLAN.md) · 🇵🇰 [ur](../../ur/docs/COVERAGE_PLAN.md) · 🇻🇳 [vi](../../vi/docs/COVERAGE_PLAN.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/COVERAGE_PLAN.md)
---
-Last updated: 2026-03-28
+Terakhir diperbarui: 2026-03-28
## Baseline
-There are multiple coverage numbers depending on how the report is computed. For planning, only one of them is useful.
+Ada beberapa angka cakupan tergantung pada cara laporan dihitung. Untuk keperluan perencanaan, hanya satu yang berguna.
-| Metric | Scope | Statements / Lines | Branches | Functions | Notes |
-| -------------------- | ----------------------------------------------------- | -----------------: | -------: | --------: | --------------------------------------------------- |
-| Legacy | Old `npm run test:coverage` | 79.42% | 75.15% | 67.94% | Inflated: counts test files and excludes `open-sse` |
-| Diagnostic | Source-only, excluding tests and excluding `open-sse` | 68.16% | 63.55% | 64.06% | Useful only to isolate `src/**` |
-| Recommended baseline | Source-only, excluding tests and including `open-sse` | 56.95% | 66.05% | 57.80% | This is the project-wide baseline to improve |
+| Metrik | Ruang Lingkup | Pernyataan / Garis | Cabang | Fungsi | Catatan |
+| -------------------- | -------------------------------------------------------------------- | -----------------: | -------: | --------: | ------------------------------------------------------------------------ |
+| Lama | `npm run test:coverage` lama | 79.42% | 75.15% | 67.94% | Diperbesar: menghitung file pengujian dan mengecualikan `open-sse` |
+| Diagnostik | Hanya sumber, mengecualikan pengujian dan mengecualikan `open-sse` | 68.16% | 63.55% | 64.06% | Berguna hanya untuk mengisolasi `src/**` |
+| Baseline yang disarankan | Hanya sumber, mengecualikan pengujian dan menyertakan `open-sse` | 56.95% | 66.05% | 57.80% | Ini adalah baseline seluruh proyek yang perlu ditingkatkan |
-The recommended baseline is the number to optimize against.
+Baseline yang disarankan adalah angka yang perlu dioptimalkan.
-## Rules
+## Aturan
-- Coverage targets apply to source files, not to `tests/**`.
-- `open-sse/**` is part of the product and must remain in scope.
-- New code should not reduce coverage in touched areas.
-- Prefer testing behavior and branch outcomes over implementation details.
-- Prefer temp SQLite databases and small fixtures over broad mocks for `src/lib/db/**`.
+- Target cakupan berlaku untuk file sumber, bukan untuk `tests/**`.
+- `open-sse/**` adalah bagian dari produk dan harus tetap dalam cakupan.
+- Kode baru tidak boleh mengurangi cakupan di area yang disentuh.
+- Utamakan pengujian perilaku dan hasil cabang dibandingkan detail implementasi.
+- Utamakan database SQLite sementara dan fixture kecil dibandingkan mock yang luas untuk `src/lib/db/**`.
-## Current command set
+## Kumpulan perintah saat ini
- `npm run test:coverage`
- - Main source coverage gate for the unit test suite
- - Generates `text-summary`, `html`, `json-summary`, and `lcov`
+ - Gerbang cakupan sumber utama untuk suite pengujian unit
+ - Menghasilkan `text-summary`, `html`, `json-summary`, dan `lcov`
- `npm run coverage:report`
- - Detailed file-by-file report from the latest run
+ - Laporan per-file terperinci dari jalankan terakhir
- `npm run test:coverage:legacy`
- - Historical comparison only
+ - Hanya untuk perbandingan historis
-## Milestones
+## Tonggak Pencapaian
-| Phase | Target | Focus |
-| ------- | ---------------------: | ------------------------------------------------- |
-| Phase 1 | 60% statements / lines | Quick wins and low-risk utility coverage |
-| Phase 2 | 65% statements / lines | DB and route foundations |
-| Phase 3 | 70% statements / lines | Provider validation and usage analytics |
-| Phase 4 | 75% statements / lines | `open-sse` translators and helpers |
-| Phase 5 | 80% statements / lines | `open-sse` handlers and executor branches |
-| Phase 6 | 85% statements / lines | Harder edge cases, branch debt, regression suites |
-| Phase 7 | 90% statements / lines | Final sweep, gap closure, strict ratchet |
+| Fase | Target | Fokus |
+| ------- | ----------------------: | ------------------------------------------------------------------ |
+| Fase 1 | 60% pernyataan / garis | Kemenangan cepat dan cakupan utilitas berisiko rendah |
+| Fase 2 | 65% pernyataan / garis | Fondasi DB dan rute |
+| Fase 3 | 70% pernyataan / garis | Validasi penyedia dan analitik penggunaan |
+| Fase 4 | 75% pernyataan / garis | Penerjemah dan pembantu `open-sse` |
+| Fase 5 | 80% pernyataan / garis | Handler dan cabang eksekutor `open-sse` |
+| Fase 6 | 85% pernyataan / garis | Kasus tepi yang lebih sulit, utang cabang, suite regresi |
+| Fase 7 | 90% pernyataan / garis | Pemeriksaan akhir, penutupan celah, ratchet ketat |
-Branches and functions should ratchet upward with each phase, but the primary hard target is statements / lines.
+Cabang dan fungsi harus meningkat secara bertahap di setiap fase, tetapi target keras utama adalah pernyataan / garis.
-## Priority hotspots
+## Titik panas prioritas
-These files or areas offer the best return for the next phases:
+File atau area berikut menawarkan keuntungan terbaik untuk fase selanjutnya:
1. `open-sse/handlers`
- - `chatCore.ts` at 7.57%
- - Overall directory at 29.07%
+ - `chatCore.ts` pada 7.57%
+ - Direktori keseluruhan pada 29.07%
2. `open-sse/translator/request`
- - Overall directory at 36.39%
- - Many translators are still near single-digit coverage
+ - Direktori keseluruhan pada 36.39%
+ - Banyak penerjemah masih mendekati cakupan satu digit
3. `open-sse/translator/response`
- - Overall directory at 8.07%
+ - Direktori keseluruhan pada 8.07%
4. `open-sse/executors`
- - Overall directory at 36.62%
+ - Direktori keseluruhan pada 36.62%
5. `src/lib/db`
- - `models.ts` at 20.66%
- - `registeredKeys.ts` at 34.46%
- - `modelComboMappings.ts` at 36.25%
- - `settings.ts` at 46.40%
- - `webhooks.ts` at 33.33%
+ - `models.ts` pada 20.66%
+ - `registeredKeys.ts` pada 34.46%
+ - `modelComboMappings.ts` pada 36.25%
+ - `settings.ts` pada 46.40%
+ - `webhooks.ts` pada 33.33%
6. `src/lib/usage`
- - `usageHistory.ts` at 21.12%
- - `usageStats.ts` at 9.56%
- - `costCalculator.ts` at 30.00%
+ - `usageHistory.ts` pada 21.12%
+ - `usageStats.ts` pada 9.56%
+ - `costCalculator.ts` pada 30.00%
7. `src/lib/providers`
- - `validation.ts` at 41.16%
-8. Low-risk utility and API files for early gains
+ - `validation.ts` pada 41.16%
+8. File utilitas dan API berisiko rendah untuk keuntungan awal
- `src/shared/utils/upstreamError.ts`
- `src/shared/utils/apiAuth.ts`
- `src/lib/api/errorResponse.ts`
- `src/app/api/settings/require-login/route.ts`
- `src/app/api/providers/[id]/models/route.ts`
-## Execution checklist
+## Daftar periksa eksekusi
-### Phase 1: 56.95% -> 60%
+### Fase 1: 56.95% -> 60%
-- [x] Fix coverage metric so it reflects source code instead of test files
-- [x] Keep a legacy coverage script for comparison
-- [x] Record the baseline and hotspots in-repo
-- [ ] Add focused tests for low-risk utilities:
+- [x] Perbaiki metrik cakupan agar mencerminkan kode sumber, bukan file pengujian
+- [x] Simpan skrip cakupan lama untuk perbandingan
+- [x] Catat baseline dan titik panas di dalam repo
+- [ ] Tambahkan pengujian terfokus untuk utilitas berisiko rendah:
- `src/shared/utils/upstreamError.ts`
- `src/shared/utils/fetchTimeout.ts`
- `src/lib/api/errorResponse.ts`
- `src/shared/utils/apiAuth.ts`
- `src/lib/display/names.ts`
-- [ ] Add route tests for:
+- [ ] Tambahkan pengujian rute untuk:
- `src/app/api/settings/require-login/route.ts`
- `src/app/api/providers/[id]/models/route.ts`
-### Phase 2: 60% -> 65%
+### Fase 2: 60% -> 65%
-- [ ] Add DB-backed tests for:
+- [ ] Tambahkan pengujian berbasis DB untuk:
- `src/lib/db/modelComboMappings.ts`
- `src/lib/db/settings.ts`
- `src/lib/db/registeredKeys.ts`
-- [ ] Cover branch behavior in:
+- [ ] Cakup perilaku cabang dalam:
- `src/lib/providers/validation.ts`
- `src/app/api/v1/embeddings/route.ts`
- `src/app/api/v1/moderations/route.ts`
-### Phase 3: 65% -> 70%
+### Fase 3: 65% -> 70%
-- [ ] Add usage analytics tests for:
+- [ ] Tambahkan pengujian analitik penggunaan untuk:
- `src/lib/usage/usageHistory.ts`
- `src/lib/usage/usageStats.ts`
- `src/lib/usage/costCalculator.ts`
-- [ ] Expand route coverage for proxy management and settings branches
+- [ ] Perluas cakupan rute untuk manajemen proxy dan cabang pengaturan
-### Phase 4: 70% -> 75%
+### Fase 4: 70% -> 75%
-- [ ] Cover translator helpers and central translation paths:
+- [ ] Cakup pembantu penerjemah dan jalur penerjemahan sentral:
- `open-sse/translator/index.ts`
- `open-sse/translator/helpers/*`
- `open-sse/translator/request/*`
- `open-sse/translator/response/*`
-### Phase 5: 75% -> 80%
+### Fase 5: 75% -> 80%
-- [ ] Add handler-level tests for:
+- [ ] Tambahkan pengujian tingkat handler untuk:
- `open-sse/handlers/chatCore.ts`
- `open-sse/handlers/responsesHandler.js`
- `open-sse/handlers/imageGeneration.js`
- `open-sse/handlers/embeddings.js`
-- [ ] Add executor branch coverage for provider-specific auth, retries, and endpoint overrides
+- [ ] Tambahkan cakupan cabang eksekutor untuk autentikasi spesifik penyedia, percobaan ulang, dan penggantian endpoint
-### Phase 6: 80% -> 85%
+### Fase 6: 80% -> 85%
-- [ ] Merge more edge-case suites into the main coverage path
-- [ ] Increase function coverage for DB modules with weak constructor/helper coverage
-- [ ] Close branch gaps in `settings.ts`, `registeredKeys.ts`, `validation.ts`, and translator helpers
+- [ ] Gabungkan lebih banyak suite kasus tepi ke dalam jalur cakupan utama
+- [ ] Tingkatkan cakupan fungsi untuk modul DB dengan cakupan konstruktor/pembantu yang lemah
+- [ ] Tutup celah cabang dalam `settings.ts`, `registeredKeys.ts`, `validation.ts`, dan pembantu penerjemah
-### Phase 7: 85% -> 90%
+### Fase 7: 85% -> 90%
-- [ ] Treat the remaining low-coverage files as blockers
-- [ ] Add regression tests for every uncovered production bug fixed during the push to 90%
-- [ ] Raise the coverage gate in CI only after the local baseline is stable for at least two consecutive runs
+- [ ] Perlakukan file dengan cakupan rendah yang tersisa sebagai pemblokir
+- [ ] Tambahkan pengujian regresi untuk setiap bug produksi yang belum tercakup yang diperbaiki selama pendakian ke 90%
+- [ ] Naikkan gerbang cakupan di CI hanya setelah baseline lokal stabil selama setidaknya dua jalankan berurutan
-## Ratchet policy
+## Kebijakan ratchet
-Update `npm run test:coverage` thresholds only after the project actually exceeds the next milestone with a comfortable buffer.
+Perbarui ambang batas `npm run test:coverage` hanya setelah proyek benar-benar melampaui tonggak berikutnya dengan buffer yang nyaman.
-Recommended ratchet sequence:
+Urutan ratchet yang disarankan:
1. 55/60/55
2. 60/62/58
@@ -163,8 +163,8 @@ Recommended ratchet sequence:
7. 85/80/84
8. 90/85/88
-Order is `statements-lines / branches / functions`.
+Urutan adalah `pernyataan-garis / cabang / fungsi`.
-## Known gap
+## Celah yang diketahui
-The current coverage command measures the main Node unit suite and includes source reached from it, including `open-sse`. It does not yet merge Vitest coverage into a single unified report. That merge is worth doing later, but it is not a blocker for starting the 60% -> 80% climb.
+Perintah cakupan saat ini mengukur suite unit Node utama dan menyertakan sumber yang dapat dijangkau darinya, termasuk `open-sse`. Perintah ini belum menggabungkan cakupan Vitest ke dalam satu laporan terpadu. Penggabungan tersebut layak dilakukan nanti, tetapi bukan pemblokir untuk memulai pendakian 60% -> 80%.
diff --git a/docs/i18n/id/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md b/docs/i18n/id/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md
index 2ce5572b98..b485b842bc 100644
--- a/docs/i18n/id/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md
+++ b/docs/i18n/id/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md
@@ -1,32 +1,32 @@
-# OmniRoute Fly.io 部署指南 (Bahasa Indonesia)
+# Panduan Deployment OmniRoute di Fly.io
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../ar/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../bg/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇩 [bn](../../bn/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../cs/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../da/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../de/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../es/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇷 [fa](../../fa/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../fi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../fr/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [gu](../../gu/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../he/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [hi](../../hi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../hu/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../id/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../it/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../ja/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../ko/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [mr](../../mr/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../ms/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../nl/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../no/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../phi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../pl/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../pt/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../ro/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../ru/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../sk/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../sv/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇪 [sw](../../sw/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [ta](../../ta/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [te](../../te/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../th/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇷 [tr](../../tr/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇰 [ur](../../ur/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../vi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FLY_IO_DEPLOYMENT_GUIDE.md)
---
-本文档记录 OmniRoute 在 Fly.io 上的实际部署方法,适用于两类场景:
+Dokumen ini menjelaskan metode deployment OmniRoute di Fly.io yang telah terbukti berhasil, mencakup dua skenario utama:
-- 首次把当前项目部署到 Fly.io
-- 后续代码更新后继续发布
-- 新项目参考同样流程部署
+- Deployment pertama kali proyek saat ini ke Fly.io
+- Publikasi setelah pembaruan kode berikutnya
+- Referensi alur deployment yang sama untuk proyek baru
-本文基于当前项目已经验证通过的配置整理,应用名为 `omniroute`。
+Dokumen ini disusun berdasarkan konfigurasi yang telah diverifikasi pada proyek saat ini, dengan nama aplikasi `omniroute`.
---
-## 1. 部署目标
+## 1. Target Deployment
-- 平台:Fly.io
-- 部署方式:本地 `flyctl` 直接发布
-- 运行方式:使用仓库内现有 `Dockerfile` 和 `fly.toml`
-- 数据持久化:Fly Volume 挂载到 `/data`
-- 访问地址:`https://omniroute.fly.dev/`
+- Platform: Fly.io
+- Metode deployment: Publikasi langsung dari lokal menggunakan `flyctl`
+- Cara menjalankan: Menggunakan `Dockerfile` dan `fly.toml` yang sudah ada di repositori
+- Persistensi data: Fly Volume yang dipasang ke `/data`
+- Alamat akses: `https://omniroute.fly.dev/`
---
-## 2. 当前项目关键配置
+## 2. Konfigurasi Kunci Proyek Saat Ini
-当前仓库中的 `fly.toml` 已确认包含以下关键项:
+`fly.toml` di repositori saat ini telah dikonfirmasi mengandung item-item kunci berikut:
```toml
app = 'omniroute'
@@ -49,33 +49,33 @@ primary_region = 'sin'
BIND = "0.0.0.0"
```
-说明:
+Keterangan:
-- `app = 'omniroute'` 决定实际部署到哪个 Fly 应用
-- `destination = '/data'` 决定持久卷挂载目录
-- 本项目必须让 `DATA_DIR=/data`,否则数据库和密钥会写到容器临时目录
+- `app = 'omniroute'` menentukan aplikasi Fly mana yang menjadi target deployment
+- `destination = '/data'` menentukan direktori pemasangan volume persisten
+- Proyek ini mengharuskan `DATA_DIR=/data` disetel; jika tidak, database dan kunci rahasia akan ditulis ke direktori sementara kontainer
---
-## 3. 必备工具
+## 3. Alat yang Diperlukan
-### 3.1 安装 Fly CLI
+### 3.1 Instalasi Fly CLI
-Windows PowerShell:
+Windows PowerShell:
```powershell
pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"
```
-如果安装脚本在当前环境失败,也可以手动下载 `flyctl` 二进制并放到 `PATH` 中。
+Jika skrip instalasi gagal di lingkungan saat ini, Anda juga dapat mengunduh biner `flyctl` secara manual dan menempatkannya di `PATH`.
-### 3.2 登录 Fly 账号
+### 3.2 Login ke Akun Fly
```powershell
flyctl auth login
```
-### 3.3 检查登录状态
+### 3.3 Periksa Status Login
```powershell
flyctl auth whoami
@@ -84,45 +84,45 @@ flyctl version
---
-## 4. 首次部署当前项目
+## 4. Deployment Pertama Kali untuk Proyek Saat Ini
-### 4.1 获取代码并进入目录
+### 4.1 Ambil Kode dan Masuk ke Direktori
```powershell
git clone https://github.com/diegosouzapw/OmniRoute.git
cd OmniRoute
```
-### 4.2 确认应用名
+### 4.2 Konfirmasi Nama Aplikasi
-打开 `fly.toml`,重点看这一行:
+Buka `fly.toml` dan perhatikan baris berikut:
```toml
app = 'omniroute'
```
-如果你准备部署到自己的新应用,可改成全局唯一名称,例如:
+Jika Anda berencana melakukan deployment ke aplikasi baru milik sendiri, ubah menjadi nama yang unik secara global, misalnya:
```toml
app = 'omniroute-yourname'
```
-注意:
+Catatan:
-- 控制台里要看的是与 `fly.toml` 里 `app` 一致的应用
-- 以前如果用过别的名字,例如 `oroute`,不要和 `omniroute` 混淆
+- Di konsol, pastikan Anda melihat aplikasi yang sesuai dengan nilai `app` di `fly.toml`
+- Jika sebelumnya Anda menggunakan nama lain seperti `oroute`, jangan sampai tertukar dengan `omniroute`
-### 4.3 创建应用
+### 4.3 Buat Aplikasi
-如果该应用尚不存在:
+Jika aplikasi belum ada:
```powershell
flyctl apps create omniroute
```
-如果你已经改成别的应用名,把 `omniroute` 替换成你的名字。
+Jika Anda sudah mengganti nama aplikasi, ganti `omniroute` dengan nama Anda.
-### 4.4 首次部署
+### 4.4 Deployment Pertama
```powershell
flyctl deploy
@@ -130,13 +130,13 @@ flyctl deploy
---
-## 5. 必配参数
+## 5. Parameter yang Wajib Dikonfigurasi
-本项目在 Fly.io 上建议至少配置以下参数。
+Berikut adalah parameter minimum yang direkomendasikan untuk proyek ini di Fly.io.
-### 5.1 已验证使用的参数
+### 5.1 Parameter yang Telah Diverifikasi
-这些参数已经在当前 `omniroute` 应用上实际部署:
+Parameter-parameter berikut telah digunakan secara nyata pada aplikasi `omniroute` saat ini:
- `API_KEY_SECRET`
- `DATA_DIR`
@@ -145,58 +145,58 @@ flyctl deploy
- `NEXT_PUBLIC_BASE_URL`
- `STORAGE_ENCRYPTION_KEY`
-### 5.2 关于 `INITIAL_PASSWORD`
+### 5.2 Tentang `INITIAL_PASSWORD`
-当前项目没有设置 `INITIAL_PASSWORD`,因为本次部署按需求不使用它。
+Proyek saat ini tidak menyetel `INITIAL_PASSWORD` karena deployment ini tidak memerlukannya.
-如果不设置:
+Jika tidak disetel:
-- 启动日志会提示默认密码是 `CHANGEME`
-- 部署后应尽快在系统设置中修改登录密码
+- Log startup akan menampilkan bahwa kata sandi default adalah `CHANGEME`
+- Setelah deployment, segera ubah kata sandi login di pengaturan sistem
-如果你希望无人值守初始化后台密码,也可以后续补:
+Jika Anda ingin menginisialisasi kata sandi panel admin secara otomatis, Anda dapat menambahkannya nanti:
- `INITIAL_PASSWORD`
---
-## 6. 推荐参数说明
+## 6. Penjelasan Parameter yang Direkomendasikan
-### 6.1 Secrets 中设置
+### 6.1 Konfigurasi di Secrets
-建议放入 Fly Secrets:
+Parameter yang disarankan untuk disimpan sebagai Fly Secrets:
-| 变量名 | 是否推荐 | 说明 |
-| ------------------------ | -------- | ------------------------------ |
-| `API_KEY_SECRET` | 必需 | API Key 生成与校验使用 |
-| `JWT_SECRET` | 必需 | 登录态和 JWT 签名使用 |
-| `STORAGE_ENCRYPTION_KEY` | 强烈推荐 | 加密存储敏感连接信息 |
-| `MACHINE_ID_SALT` | 推荐 | 生成稳定机器标识 |
-| `INITIAL_PASSWORD` | 可选 | 首次部署时直接指定后台初始密码 |
-| OAuth/API 私密凭证 | 按需 | 各类外部平台鉴权配置 |
+| Nama Variabel | Direkomendasikan | Keterangan |
+| ------------------------ | ---------------- | ----------------------------------------------- |
+| `API_KEY_SECRET` | Wajib | Digunakan untuk pembuatan dan validasi API Key |
+| `JWT_SECRET` | Wajib | Digunakan untuk sesi login dan tanda tangan JWT |
+| `STORAGE_ENCRYPTION_KEY` | Sangat Direkomendasikan | Mengenkripsi informasi koneksi sensitif |
+| `MACHINE_ID_SALT` | Direkomendasikan | Menghasilkan identifikasi mesin yang stabil |
+| `INITIAL_PASSWORD` | Opsional | Menentukan kata sandi awal panel admin saat deployment pertama |
+| Kredensial OAuth/API | Sesuai kebutuhan | Konfigurasi autentikasi untuk berbagai platform eksternal |
-### 6.2 当前项目推荐值
+### 6.2 Nilai yang Direkomendasikan untuk Proyek Saat Ini
-| 变量名 | 推荐值 |
-| ---------------------- | --------------------------- |
-| `DATA_DIR` | `/data` |
-| `NEXT_PUBLIC_BASE_URL` | `https://omniroute.fly.dev` |
+| Nama Variabel | Nilai yang Direkomendasikan |
+| ---------------------- | ------------------------------ |
+| `DATA_DIR` | `/data` |
+| `NEXT_PUBLIC_BASE_URL` | `https://omniroute.fly.dev` |
-说明:
+Keterangan:
-- `DATA_DIR=/data` 非常关键,必须与 Fly Volume 挂载点一致
-- `NEXT_PUBLIC_BASE_URL` 用于调度器和前端回调等场景
+- `DATA_DIR=/data` sangat krusial dan harus sesuai dengan titik pemasangan Fly Volume
+- `NEXT_PUBLIC_BASE_URL` digunakan dalam skenario seperti penjadwal dan callback frontend
---
-## 7. 一键设置参数
+## 7. Penyetelan Parameter Sekaligus
-下面命令会生成安全随机值,并把当前项目需要的参数一次性写入 Fly Secrets。
+Perintah berikut akan menghasilkan nilai acak yang aman dan menulis semua parameter yang dibutuhkan proyek saat ini ke Fly Secrets dalam satu langkah.
-说明:
+Keterangan:
-- 不包含 `INITIAL_PASSWORD`
-- 适用于当前项目 `omniroute`
+- Tidak menyertakan `INITIAL_PASSWORD`
+- Berlaku untuk proyek saat ini yaitu `omniroute`
```powershell
$apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
@@ -214,79 +214,79 @@ flyctl secrets set `
-a omniroute
```
-如果你还要加初始密码:
+Jika Anda juga ingin menambahkan kata sandi awal:
```powershell
-flyctl secrets set INITIAL_PASSWORD=你的强密码 -a omniroute
+flyctl secrets set INITIAL_PASSWORD=kata-sandi-kuat-anda -a omniroute
```
---
-## 8. 查看当前参数
+## 8. Melihat Parameter Saat Ini
```powershell
flyctl secrets list -a omniroute
```
-如果控制台 `Secrets` 页面没有显示你期待的变量,先检查:
+Jika halaman `Secrets` di konsol tidak menampilkan variabel yang Anda harapkan, periksa terlebih dahulu:
-- 看的应用是不是 `omniroute`
-- `fly.toml` 的 `app` 是否和控制台应用一致
+- Apakah aplikasi yang sedang dilihat adalah `omniroute`
+- Apakah nilai `app` di `fly.toml` sudah sesuai dengan aplikasi di konsol
---
-## 9. 后续更新发布
+## 9. Pembaruan dan Publikasi Selanjutnya
-代码有更新后,发布步骤很简单:
+Setelah ada pembaruan kode, langkah publikasinya sangat sederhana:
```powershell
git pull
flyctl deploy
```
-如果只更新参数,不改代码:
+Jika hanya memperbarui parameter tanpa mengubah kode:
```powershell
flyctl secrets set KEY=value -a omniroute
```
-Fly 会自动滚动更新机器。
+Fly akan melakukan pembaruan mesin secara otomatis dengan rolling update.
-### 9.1 跟踪原仓库更新并保留 fork 的 `fly.toml`
+### 9.1 Melacak Pembaruan Repositori Asal dan Mempertahankan `fly.toml` dari Fork
-如果当前仓库是 fork,并且你要同步上游 `https://github.com/diegosouzapw/OmniRoute` 的更新,推荐按下面流程执行。
+Jika repositori saat ini adalah fork dan Anda ingin menyinkronkan pembaruan dari upstream `https://github.com/diegosouzapw/OmniRoute`, ikuti alur berikut.
-先确认远程:
+Pertama, konfirmasi remote yang ada:
```powershell
git remote -v
```
-应至少包含:
+Harus mengandung setidaknya:
-- `origin` 指向你自己的 fork
-- `upstream` 指向原仓库
+- `origin` yang mengarah ke fork milik Anda
+- `upstream` yang mengarah ke repositori asal
-如果没有 `upstream`,先添加:
+Jika belum ada `upstream`, tambahkan terlebih dahulu:
```powershell
git remote add upstream https://github.com/diegosouzapw/OmniRoute.git
```
-同步上游前,先抓取最新提交和标签:
+Sebelum menyinkronkan upstream, ambil commit dan tag terbaru:
```powershell
git fetch upstream --tags
```
-查看当前版本和上游标签:
+Lihat versi saat ini dan tag upstream:
```powershell
git describe --tags --always
git show --no-patch --oneline v3.4.7
```
-如果你想合并上游最新 `main`,并强制保留 fork 当前的 `fly.toml`,可按下面流程执行:
+Jika Anda ingin menggabungkan `main` upstream terbaru sambil mempertahankan `fly.toml` fork saat ini secara paksa, ikuti alur berikut:
```powershell
git merge upstream/main
@@ -296,52 +296,52 @@ git commit -m "chore(deploy): keep fork fly.toml"
git push origin main
```
-说明:
+Keterangan:
-- `git merge upstream/main` 用于同步原仓库最新代码
-- `git checkout HEAD~1 -- fly.toml` 用于恢复合并前你 fork 自己的 `fly.toml`
-- 如果上游没有改 `fly.toml`,这一步不会带来额外差异
-- 如果上游改了 `fly.toml`,这一步能确保 Fly 应用名、挂载卷、区域等 fork 自定义部署配置不被覆盖
+- `git merge upstream/main` digunakan untuk menyinkronkan kode terbaru dari repositori asal
+- `git checkout HEAD~1 -- fly.toml` digunakan untuk memulihkan `fly.toml` fork Anda sebelum penggabungan
+- Jika upstream tidak mengubah `fly.toml`, langkah ini tidak akan menimbulkan perbedaan tambahan
+- Jika upstream mengubah `fly.toml`, langkah ini memastikan konfigurasi deployment kustom fork Anda seperti nama aplikasi Fly, volume pemasangan, dan region tidak tertimpa
-如果你明确只想对齐某个发布标签,例如 `v3.4.7`,也可以先确认标签是否已经包含在 `upstream/main`:
+Jika Anda hanya ingin menyejajarkan dengan tag rilis tertentu, misalnya `v3.4.7`, konfirmasi terlebih dahulu apakah tag tersebut sudah tercakup dalam `upstream/main`:
```powershell
git merge-base --is-ancestor v3.4.7 upstream/main
```
-返回成功表示 `upstream/main` 已经包含该版本,直接合并 `upstream/main` 即可。
+Jika berhasil, berarti `upstream/main` sudah mengandung versi tersebut dan Anda dapat langsung menggabungkan `upstream/main`.
-### 9.2 同步上游后的标准发布顺序
+### 9.2 Urutan Publikasi Standar Setelah Sinkronisasi Upstream
-同步原仓库完成后,推荐按下面顺序发布:
+Setelah selesai menyinkronkan repositori asal, ikuti urutan publikasi berikut:
1. `git fetch upstream --tags`
2. `git merge upstream/main`
-3. 恢复 fork 的 `fly.toml`
+3. Pulihkan `fly.toml` dari fork
4. `git push origin main`
5. `flyctl deploy`
6. `flyctl status -a omniroute`
7. `flyctl logs --no-tail -a omniroute`
-这就是当前项目升级到 `v3.4.7` 时使用的实际流程。
+Inilah alur yang digunakan saat proyek ini diperbarui ke `v3.4.7`.
---
-## 10. 发布后检查
+## 10. Pemeriksaan Setelah Deployment
-### 10.1 查看应用状态
+### 10.1 Lihat Status Aplikasi
```powershell
flyctl status -a omniroute
```
-### 10.2 查看启动日志
+### 10.2 Lihat Log Startup
```powershell
flyctl logs --no-tail -a omniroute
```
-### 10.3 检查网站可访问
+### 10.3 Periksa Aksesibilitas Situs
```powershell
try {
@@ -355,82 +355,82 @@ try {
}
```
-返回 `200` 说明站点已正常响应。
+Jika mengembalikan `200`, berarti situs sudah merespons dengan normal.
---
-## 11. 成功标志
+## 11. Indikator Keberhasilan
-部署成功后,日志里应看到类似内容:
+Setelah deployment berhasil, Anda seharusnya melihat konten seperti berikut di log:
```text
[bootstrap] Secrets persisted to: /data/server.env
[DB] SQLite database ready: /data/storage.sqlite
```
-这两个点很关键:
+Dua poin ini sangat penting:
-- `/data/server.env` 说明运行时密钥落到了持久卷
-- `/data/storage.sqlite` 说明数据库写入持久卷
+- `/data/server.env` menunjukkan bahwa kunci rahasia runtime telah tersimpan ke volume persisten
+- `/data/storage.sqlite` menunjukkan bahwa database telah ditulis ke volume persisten
-如果你看到的是 `/app/data/...`,说明 `DATA_DIR` 没配对,需要立即修正。
+Jika yang Anda lihat adalah `/app/data/...`, berarti `DATA_DIR` tidak dikonfigurasi dengan benar dan harus segera diperbaiki.
---
-## 12. 常见问题
+## 12. Masalah Umum
-### 12.1 `Secrets` 页面是空的
+### 12.1 Halaman `Secrets` Kosong
-通常有两种原因:
+Biasanya ada dua penyebab:
-- 你还没执行 `flyctl secrets set`
-- 你打开的是另一个应用,例如 `oroute`,不是 `omniroute`
+- Anda belum menjalankan `flyctl secrets set`
+- Anda membuka aplikasi yang salah, misalnya `oroute`, bukan `omniroute`
-### 12.2 `flyctl deploy` 报 `app not found`
+### 12.2 `flyctl deploy` Melaporkan `app not found`
-先创建应用:
+Buat aplikasinya terlebih dahulu:
```powershell
flyctl apps create omniroute
```
-### 12.3 `fly.toml` 解析失败
+### 12.3 Parsing `fly.toml` Gagal
-重点检查:
+Periksa secara khusus:
-- 注释里是否有乱码字符
-- TOML 引号和缩进是否正确
+- Apakah ada karakter tidak valid di dalam komentar
+- Apakah tanda kutip dan indentasi TOML sudah benar
-### 12.4 数据没有持久化
+### 12.4 Data Tidak Tersimpan Secara Persisten
-检查以下两点:
+Periksa dua hal berikut:
-- `fly.toml` 中是否存在 `destination = '/data'`
-- `DATA_DIR` 是否设置为 `/data`
+- Apakah `destination = '/data'` ada di `fly.toml`
+- Apakah `DATA_DIR` sudah disetel ke `/data`
-### 12.5 不设置 `INITIAL_PASSWORD` 是否能跑
+### 12.5 Apakah Bisa Berjalan Tanpa Menyetel `INITIAL_PASSWORD`
-可以运行,但会回退到默认 `CHANGEME`。生产环境建议尽快修改后台密码。
+Bisa berjalan, tetapi akan menggunakan kata sandi default `CHANGEME`. Untuk lingkungan produksi, disarankan untuk segera mengubah kata sandi panel admin.
---
-## 13. 新项目复用建议
+## 13. Rekomendasi untuk Penggunaan Ulang pada Proyek Baru
-如果以后是新项目照着这份文档部署,最少改这几项:
+Jika di kemudian hari Anda melakukan deployment proyek baru mengikuti panduan ini, setidaknya ubah item-item berikut:
-1. 修改 `fly.toml` 里的 `app`
-2. 修改 `NEXT_PUBLIC_BASE_URL`
-3. 保持 `DATA_DIR=/data`
-4. 重新生成 `API_KEY_SECRET`、`JWT_SECRET`、`MACHINE_ID_SALT`、`STORAGE_ENCRYPTION_KEY`
-5. 首次部署后检查日志是否写入 `/data`
+1. Ubah nilai `app` di `fly.toml`
+2. Ubah `NEXT_PUBLIC_BASE_URL`
+3. Pertahankan `DATA_DIR=/data`
+4. Buat ulang `API_KEY_SECRET`, `JWT_SECRET`, `MACHINE_ID_SALT`, dan `STORAGE_ENCRYPTION_KEY`
+5. Setelah deployment pertama, periksa log apakah data sudah ditulis ke `/data`
-不要直接复用旧项目的密钥。
+Jangan gunakan ulang kunci dari proyek lama.
---
-## 14. 当前项目的最小发布清单
+## 14. Daftar Periksa Publikasi Minimal untuk Proyek Saat Ini
-当前项目后续最常用的命令如下:
+Berikut adalah perintah yang paling sering digunakan untuk proyek saat ini:
```powershell
flyctl auth whoami
@@ -440,13 +440,13 @@ flyctl deploy
flyctl logs --no-tail -a omniroute
```
-如果只是正常发版,核心就是:
+Untuk publikasi rutin biasa, perintah intinya adalah:
```powershell
flyctl deploy
```
-如果是新环境首次部署,核心就是:
+Untuk deployment pertama di lingkungan baru, langkah intinya adalah:
1. `flyctl auth login`
2. `flyctl apps create omniroute`
diff --git a/docs/i18n/id/docs/ops/RELEASE_CHECKLIST.md b/docs/i18n/id/docs/ops/RELEASE_CHECKLIST.md
index f57f20d897..d9356baaf9 100644
--- a/docs/i18n/id/docs/ops/RELEASE_CHECKLIST.md
+++ b/docs/i18n/id/docs/ops/RELEASE_CHECKLIST.md
@@ -1,44 +1,44 @@
-# Release Checklist (Bahasa Indonesia)
+# Daftar Periksa Rilis (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../../ar/docs/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../../bg/docs/RELEASE_CHECKLIST.md) · 🇧🇩 [bn](../../bn/docs/RELEASE_CHECKLIST.md) · 🇨🇿 [cs](../../cs/docs/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../../da/docs/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../../de/docs/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../../es/docs/RELEASE_CHECKLIST.md) · 🇮🇷 [fa](../../fa/docs/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../../fi/docs/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../../fr/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [gu](../../gu/docs/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../../he/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [hi](../../hi/docs/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../../hu/docs/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../../id/docs/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../../it/docs/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../../ja/docs/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../../ko/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [mr](../../mr/docs/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../../ms/docs/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../../nl/docs/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../../no/docs/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../../phi/docs/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../../pl/docs/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../../pt/docs/RELEASE_CHECKLIST.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../../ro/docs/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../../ru/docs/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../../sk/docs/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../../sv/docs/RELEASE_CHECKLIST.md) · 🇰🇪 [sw](../../sw/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [ta](../../ta/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [te](../../te/docs/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../../th/docs/RELEASE_CHECKLIST.md) · 🇹🇷 [tr](../../tr/docs/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/RELEASE_CHECKLIST.md) · 🇵🇰 [ur](../../ur/docs/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../../vi/docs/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/RELEASE_CHECKLIST.md)
---
-Use this checklist before tagging or publishing a new OmniRoute release.
+Gunakan daftar periksa ini sebelum memberi tag atau menerbitkan rilis OmniRoute baru.
-## Version and Changelog
+## Versi dan Changelog
-1. Bump `package.json` version (`x.y.z`) in the release branch.
-2. Move release notes from `## [Unreleased]` in `CHANGELOG.md` to a dated section:
+1. Naikkan versi `package.json` (`x.y.z`) di cabang rilis.
+2. Pindahkan catatan rilis dari `## [Unreleased]` di `CHANGELOG.md` ke bagian bertanggal:
- `## [x.y.z] — YYYY-MM-DD`
-3. Keep `## [Unreleased]` as the first changelog section for upcoming work.
-4. Ensure the latest semver section in `CHANGELOG.md` equals `package.json` version.
+3. Pertahankan `## [Unreleased]` sebagai bagian changelog pertama untuk pekerjaan mendatang.
+4. Pastikan bagian semver terbaru di `CHANGELOG.md` sama dengan versi `package.json`.
-## API Docs
+## Dokumentasi API
-1. Update `docs/reference/openapi.yaml`:
- - `info.version` must equal `package.json` version.
-2. Validate endpoint examples if API contracts changed.
+1. Perbarui `docs/reference/openapi.yaml`:
+ - `info.version` harus sama dengan versi `package.json`.
+2. Validasi contoh endpoint jika kontrak API berubah.
-## Runtime Docs
+## Dokumentasi Runtime
-1. Review `docs/architecture/ARCHITECTURE.md` for storage/runtime drift.
-2. Review `docs/guides/TROUBLESHOOTING.md` for env var and operational drift.
-3. Verify the release/runtime Node.js version still satisfies the supported secure floor:
- - `>=20.20.2 <21` or `>=22.22.2 <23`
+1. Tinjau `docs/architecture/ARCHITECTURE.md` untuk penyimpangan storage/runtime.
+2. Tinjau `docs/guides/TROUBLESHOOTING.md` untuk penyimpangan variabel env dan operasional.
+3. Verifikasi bahwa versi Node.js rilis/runtime masih memenuhi batas aman yang didukung:
+ - `>=20.20.2 <21` atau `>=22.22.2 <23`
- `npm run check:node-runtime`
-4. Validate the npm publish artifact after building the standalone package:
+4. Validasi artefak penerbitan npm setelah membangun paket standalone:
- `npm run build:cli`
- `npm run check:pack-artifact`
- - confirm no `app.__qa_backup`, `scripts/scratch`, `package-lock.json`, or other local residue
-5. Update localized docs if source docs changed significantly.
+ - konfirmasi tidak ada `app.__qa_backup`, `scripts/scratch`, `package-lock.json`, atau residu lokal lainnya
+5. Perbarui dokumentasi terlokalisasi jika dokumentasi sumber berubah secara signifikan.
-## Automated Check
+## Pemeriksaan Otomatis
-Run the sync guard locally before opening PR:
+Jalankan penjaga sinkronisasi secara lokal sebelum membuka PR:
```bash
npm run check:docs-sync
```
-CI also runs this check in `.github/workflows/ci.yml` (lint job).
+CI juga menjalankan pemeriksaan ini di `.github/workflows/ci.yml` (pekerjaan lint).
diff --git a/docs/i18n/id/docs/ops/VM_DEPLOYMENT_GUIDE.md b/docs/i18n/id/docs/ops/VM_DEPLOYMENT_GUIDE.md
index 9a39f6c618..a74f496cc8 100644
--- a/docs/i18n/id/docs/ops/VM_DEPLOYMENT_GUIDE.md
+++ b/docs/i18n/id/docs/ops/VM_DEPLOYMENT_GUIDE.md
@@ -1,52 +1,52 @@
-# OmniRoute — Deployment Guide on VM with Cloudflare (Bahasa Indonesia)
+# OmniRoute — Panduan Deployment di VM dengan Cloudflare (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../ar/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../bg/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇩 [bn](../../bn/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../cs/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../da/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../de/docs/VM_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../es/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇷 [fa](../../fa/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../fi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../fr/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [gu](../../gu/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../he/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [hi](../../hi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../hu/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../id/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../it/docs/VM_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../ja/docs/VM_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../ko/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [mr](../../mr/docs/VM_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../ms/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../nl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../no/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../phi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../pl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../pt/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../ro/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../ru/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../sk/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../sv/docs/VM_DEPLOYMENT_GUIDE.md) · 🇰🇪 [sw](../../sw/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [ta](../../ta/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [te](../../te/docs/VM_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../th/docs/VM_DEPLOYMENT_GUIDE.md) · 🇹🇷 [tr](../../tr/docs/VM_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇰 [ur](../../ur/docs/VM_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../vi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/VM_DEPLOYMENT_GUIDE.md)
---
-Complete guide to install and configure OmniRoute on a VM (VPS) with domain managed via Cloudflare.
+Panduan lengkap untuk menginstal dan mengkonfigurasi OmniRoute pada sebuah VM (VPS) dengan domain yang dikelola melalui Cloudflare.
---
-## Prerequisites
+## Prasyarat
-| Item | Minimum | Recommended |
+| Item | Minimum | Direkomendasikan |
| ---------- | ------------------------ | ---------------- |
| **CPU** | 1 vCPU | 2 vCPU |
| **RAM** | 1 GB | 2 GB |
| **Disk** | 10 GB SSD | 25 GB SSD |
| **OS** | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
-| **Domain** | Registered on Cloudflare | — |
+| **Domain** | Terdaftar di Cloudflare | — |
| **Docker** | Docker Engine 24+ | Docker 27+ |
-**Tested providers**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.
+**Provider yang telah diuji**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.
---
-## 1. Configure the VM
+## 1. Konfigurasi VM
-### 1.1 Create the instance
+### 1.1 Buat instans
-On your preferred VPS provider:
+Pada provider VPS pilihan Anda:
-- Choose Ubuntu 24.04 LTS
-- Select the minimum plan (1 vCPU / 1 GB RAM)
-- Set a strong root password or configure SSH key
-- Note the **public IP** (e.g., `203.0.113.10`)
+- Pilih Ubuntu 24.04 LTS
+- Pilih paket minimum (1 vCPU / 1 GB RAM)
+- Tetapkan kata sandi root yang kuat atau konfigurasikan SSH key
+- Catat **IP publik** (misalnya, `203.0.113.10`)
-### 1.2 Connect via SSH
+### 1.2 Hubungkan melalui SSH
```bash
ssh root@203.0.113.10
```
-### 1.3 Update the system
+### 1.3 Perbarui sistem
```bash
apt update && apt upgrade -y
```
-### 1.4 Install Docker
+### 1.4 Instal Docker
```bash
# Install dependencies
@@ -56,18 +56,18 @@ apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
-echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $ (. /etc/os-release && echo “$VERSION_CODENAME”) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
+echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $ (. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
```
-### 1.5 Install nginx
+### 1.5 Instal nginx
```bash
apt install -y nginx
```
-### 1.6 Configure Firewall (UFW)
+### 1.6 Konfigurasi Firewall (UFW)
```bash
ufw default deny incoming
@@ -78,22 +78,22 @@ ufw allow 443/tcp # HTTPS
ufw enable
```
-> **Tip**: For maximum security, restrict ports 80 and 443 to Cloudflare IPs only. See the [Advanced Security](#advanced-security) section.
+> **Tips**: Untuk keamanan maksimal, batasi port 80 dan 443 hanya untuk IP Cloudflare. Lihat bagian [Keamanan Lanjutan](#keamanan-lanjutan).
---
-## 2. Install OmniRoute
+## 2. Instal OmniRoute
-### 2.1 Create configuration directory
+### 2.1 Buat direktori konfigurasi
```bash
mkdir -p /opt/omniroute
```
-### 2.2 Create environment variables file
+### 2.2 Buat file variabel lingkungan
```bash
-cat > /opt/omniroute/.env << ‘EOF’
+cat > /opt/omniroute/.env << 'EOF'
# === Security ===
JWT_SECRET=CHANGE-TO-A-UNIQUE-64-CHAR-SECRET-KEY
INITIAL_PASSWORD=YourSecurePassword123!
@@ -122,9 +122,9 @@ NEXT_PUBLIC_BASE_URL=https://llms.seudominio.com
EOF
```
-> ⚠️ **IMPORTANT**: Generate unique secret keys! Use `openssl rand -hex 32` for each key.
+> ⚠️ **PENTING**: Buat secret key yang unik! Gunakan `openssl rand -hex 32` untuk setiap key.
-### 2.3 Start the container
+### 2.3 Jalankan container
```bash
docker pull diegosouzapw/omniroute:latest
@@ -138,27 +138,27 @@ docker run -d \
diegosouzapw/omniroute:latest
```
-### 2.4 Verify that it is running
+### 2.4 Verifikasi bahwa container berjalan
```bash
docker ps | grep omniroute
docker logs omniroute --tail 20
```
-It should display: `[DB] SQLite database ready` and `listening on port 20128`.
+Seharusnya menampilkan: `[DB] SQLite database ready` dan `listening on port 20128`.
---
-## 3. Configure nginx (Reverse Proxy)
+## 3. Konfigurasi nginx (Reverse Proxy)
-### 3.1 Generate SSL certificate (Cloudflare Origin)
+### 3.1 Buat sertifikat SSL (Cloudflare Origin)
-In the Cloudflare dashboard:
+Di dasbor Cloudflare:
-1. Go to **SSL/TLS → Origin Server**
-2. Click **Create Certificate**
-3. Keep the defaults (15 years, \*.yourdomain.com)
-4. Copy the **Origin Certificate** and the **Private Key**
+1. Buka **SSL/TLS → Origin Server**
+2. Klik **Create Certificate**
+3. Biarkan pengaturan default (15 tahun, \*.yourdomain.com)
+4. Salin **Origin Certificate** dan **Private Key**
```bash
mkdir -p /etc/nginx/ssl
@@ -172,10 +172,10 @@ nano /etc/nginx/ssl/origin.key
chmod 600 /etc/nginx/ssl/origin.key
```
-### 3.2 Nginx Configuration
+### 3.2 Konfigurasi Nginx
```bash
-cat > /etc/nginx/sites-available/omniroute << ‘NGINX’
+cat > /etc/nginx/sites-available/omniroute << 'NGINX'
# Default server — blocks direct access via IP
server {
listen 80 default_server;
@@ -210,7 +210,7 @@ server {
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection “upgrade”;
+ proxy_set_header Connection "upgrade";
# SSE (Server-Sent Events) — streaming AI responses
proxy_buffering off;
@@ -230,11 +230,11 @@ server {
NGINX
```
-Keep reverse-proxy stream timeouts aligned with your OmniRoute timeout env vars. If you raise
-`FETCH_TIMEOUT_MS` / `STREAM_IDLE_TIMEOUT_MS`, raise `proxy_read_timeout` / `proxy_send_timeout`
-above the same threshold.
+Jaga agar timeout stream reverse-proxy tetap selaras dengan variabel lingkungan timeout OmniRoute Anda. Jika Anda menaikkan
+`FETCH_TIMEOUT_MS` / `STREAM_IDLE_TIMEOUT_MS`, naikkan juga `proxy_read_timeout` / `proxy_send_timeout`
+di atas nilai yang sama.
-### 3.3 Enable and Test
+### 3.3 Aktifkan dan Uji
```bash
# Remove default configuration
@@ -249,29 +249,29 @@ nginx -t && systemctl reload nginx
---
-## 4. Configure Cloudflare DNS
+## 4. Konfigurasi DNS Cloudflare
-### 4.1 Add DNS record
+### 4.1 Tambahkan rekaman DNS
-In the Cloudflare dashboard → DNS:
+Di dasbor Cloudflare → DNS:
-| Type | Name | Content | Proxy |
-| ---- | ------ | ---------------------- | ---------- |
-| A | `llms` | `203.0.113.10` (VM IP) | ✅ Proxied |
+| Tipe | Nama | Konten | Proxy |
+| ---- | ------ | ----------------------- | ----------- |
+| A | `llms` | `203.0.113.10` (IP VM) | ✅ Proxied |
-### 4.2 Configure SSL
+### 4.2 Konfigurasi SSL
-Under **SSL/TLS → Overview**:
+Di bawah **SSL/TLS → Overview**:
- Mode: **Full (Strict)**
-Under **SSL/TLS → Edge Certificates**:
+Di bawah **SSL/TLS → Edge Certificates**:
- Always Use HTTPS: ✅ On
- Minimum TLS Version: TLS 1.2
- Automatic HTTPS Rewrites: ✅ On
-### 4.3 Testing
+### 4.3 Pengujian
```bash
curl -sI https://llms.seudominio.com/health
@@ -280,9 +280,9 @@ curl -sI https://llms.seudominio.com/health
---
-## 5. Operations and Maintenance
+## 5. Operasi dan Pemeliharaan
-### Upgrade to a new version
+### Upgrade ke versi baru
```bash
docker pull diegosouzapw/omniroute:latest
@@ -294,14 +294,14 @@ docker run -d --name omniroute --restart unless-stopped \
diegosouzapw/omniroute:latest
```
-### View logs
+### Lihat log
```bash
docker logs -f omniroute # Real-time stream
docker logs omniroute --tail 50 # Last 50 lines
```
-### Manual database backup
+### Pencadangan database secara manual
```bash
# Copy data from the volume to the host
@@ -312,23 +312,23 @@ docker run --rm -v omniroute-data:/data -v $(pwd):/backup \
alpine tar czf /backup/omniroute-data-$(date +%F).tar.gz /data
```
-### Restore from backup
+### Pulihkan dari cadangan
```bash
docker stop omniroute
docker run --rm -v omniroute-data:/data -v $(pwd):/backup \
- alpine sh -c “rm -rf /data/* && tar xzf /backup/omniroute-data-YYYY-MM-DD.tar.gz -C /”
+ alpine sh -c "rm -rf /data/* && tar xzf /backup/omniroute-data-YYYY-MM-DD.tar.gz -C /"
docker start omniroute
```
---
-## 6. Advanced Security
+## 6. Keamanan Lanjutan
-### Restrict nginx to Cloudflare IPs
+### Batasi nginx ke IP Cloudflare
```bash
-cat > /etc/nginx/cloudflare-ips.conf << ‘CF’
+cat > /etc/nginx/cloudflare-ips.conf << 'CF'
# Cloudflare IPv4 ranges — update periodically
# https://www.cloudflare.com/ips-v4/
set_real_ip_from 173.245.48.0/20;
@@ -350,13 +350,13 @@ real_ip_header CF-Connecting-IP;
CF
```
-Add the following to `nginx.conf` inside the `http {}` block:
+Tambahkan baris berikut ke `nginx.conf` di dalam blok `http {}`:
```nginx
include /etc/nginx/cloudflare-ips.conf;
```
-### Install fail2ban
+### Instal fail2ban
```bash
apt install -y fail2ban
@@ -367,7 +367,7 @@ systemctl start fail2ban
fail2ban-client status sshd
```
-### Block direct access to the Docker port
+### Blokir akses langsung ke port Docker
```bash
# Prevent direct external access to port 20128
@@ -381,9 +381,9 @@ netfilter-persistent save
---
-## 7. Deploy to Cloudflare Workers (Optional)
+## 7. Deploy ke Cloudflare Workers (Opsional)
-For remote access via Cloudflare Workers (without exposing the VM directly):
+Untuk akses jarak jauh melalui Cloudflare Workers (tanpa mengekspos VM secara langsung):
```bash
# In the local repository
@@ -393,15 +393,15 @@ npx wrangler login
npx wrangler deploy
```
-See the full documentation at [omnirouteCloud/README.md](../omnirouteCloud/README.md).
+Lihat dokumentasi lengkap di [omnirouteCloud/README.md](../omnirouteCloud/README.md).
---
-## Port Summary
+## Ringkasan Port
-| Port | Service | Access |
-| ----- | ----------- | -------------------------- |
-| 22 | SSH | Public (with fail2ban) |
-| 80 | nginx HTTP | Redirect → HTTPS |
-| 443 | nginx HTTPS | Via Cloudflare Proxy |
-| 20128 | OmniRoute | Localhost only (via nginx) |
+| Port | Layanan | Akses |
+| ----- | ----------- | ------------------------------- |
+| 22 | SSH | Publik (dengan fail2ban) |
+| 80 | nginx HTTP | Redirect → HTTPS |
+| 443 | nginx HTTPS | Melalui Cloudflare Proxy |
+| 20128 | OmniRoute | Hanya localhost (melalui nginx) |
diff --git a/docs/i18n/id/docs/reference/API_REFERENCE.md b/docs/i18n/id/docs/reference/API_REFERENCE.md
index 595d5731fb..404af7c351 100644
--- a/docs/i18n/id/docs/reference/API_REFERENCE.md
+++ b/docs/i18n/id/docs/reference/API_REFERENCE.md
@@ -1,24 +1,24 @@
-# API Reference (Bahasa Indonesia)
+# Referensi API (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/API_REFERENCE.md) · 🇸🇦 [ar](../../ar/docs/API_REFERENCE.md) · 🇧🇬 [bg](../../bg/docs/API_REFERENCE.md) · 🇧🇩 [bn](../../bn/docs/API_REFERENCE.md) · 🇨🇿 [cs](../../cs/docs/API_REFERENCE.md) · 🇩🇰 [da](../../da/docs/API_REFERENCE.md) · 🇩🇪 [de](../../de/docs/API_REFERENCE.md) · 🇪🇸 [es](../../es/docs/API_REFERENCE.md) · 🇮🇷 [fa](../../fa/docs/API_REFERENCE.md) · 🇫🇮 [fi](../../fi/docs/API_REFERENCE.md) · 🇫🇷 [fr](../../fr/docs/API_REFERENCE.md) · 🇮🇳 [gu](../../gu/docs/API_REFERENCE.md) · 🇮🇱 [he](../../he/docs/API_REFERENCE.md) · 🇮🇳 [hi](../../hi/docs/API_REFERENCE.md) · 🇭🇺 [hu](../../hu/docs/API_REFERENCE.md) · 🇮🇩 [id](../../id/docs/API_REFERENCE.md) · 🇮🇹 [it](../../it/docs/API_REFERENCE.md) · 🇯🇵 [ja](../../ja/docs/API_REFERENCE.md) · 🇰🇷 [ko](../../ko/docs/API_REFERENCE.md) · 🇮🇳 [mr](../../mr/docs/API_REFERENCE.md) · 🇲🇾 [ms](../../ms/docs/API_REFERENCE.md) · 🇳🇱 [nl](../../nl/docs/API_REFERENCE.md) · 🇳🇴 [no](../../no/docs/API_REFERENCE.md) · 🇵🇭 [phi](../../phi/docs/API_REFERENCE.md) · 🇵🇱 [pl](../../pl/docs/API_REFERENCE.md) · 🇵🇹 [pt](../../pt/docs/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/API_REFERENCE.md) · 🇷🇴 [ro](../../ro/docs/API_REFERENCE.md) · 🇷🇺 [ru](../../ru/docs/API_REFERENCE.md) · 🇸🇰 [sk](../../sk/docs/API_REFERENCE.md) · 🇸🇪 [sv](../../sv/docs/API_REFERENCE.md) · 🇰🇪 [sw](../../sw/docs/API_REFERENCE.md) · 🇮🇳 [ta](../../ta/docs/API_REFERENCE.md) · 🇮🇳 [te](../../te/docs/API_REFERENCE.md) · 🇹🇭 [th](../../th/docs/API_REFERENCE.md) · 🇹🇷 [tr](../../tr/docs/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/API_REFERENCE.md) · 🇵🇰 [ur](../../ur/docs/API_REFERENCE.md) · 🇻🇳 [vi](../../vi/docs/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/API_REFERENCE.md)
---
-Complete reference for all OmniRoute API endpoints.
+Referensi lengkap untuk semua titik akhir API OmniRoute.
---
-## Table of Contents
+## Daftar Isi
- [Chat Completions](#chat-completions)
- [Embeddings](#embeddings)
-- [Image Generation](#image-generation)
-- [List Models](#list-models)
-- [Compatibility Endpoints](#compatibility-endpoints)
-- [Semantic Cache](#semantic-cache)
-- [Dashboard & Management](#dashboard--management)
-- [Request Processing](#request-processing)
-- [Authentication](#authentication)
+- [Pembuatan Gambar](#image-generation)
+- [Daftar Model](#list-models)
+- [Titik Akhir Kompatibilitas](#compatibility-endpoints)
+- [Cache Semantik](#semantic-cache)
+- [Dasbor & Manajemen](#dashboard--management)
+- [Pemrosesan Permintaan](#request-processing)
+- [Otentikasi](#authentication)
---
@@ -38,22 +38,22 @@ Content-Type: application/json
}
```
-### Custom Headers
+### Header Kustom
-| Header | Direction | Description |
-| ------------------------ | --------- | ------------------------------------------------ |
-| `X-OmniRoute-No-Cache` | Request | Set to `true` to bypass cache |
-| `X-OmniRoute-Progress` | Request | Set to `true` for progress events |
-| `X-Session-Id` | Request | Sticky session key for external session affinity |
-| `x_session_id` | Request | Underscore variant also accepted (direct HTTP) |
-| `Idempotency-Key` | Request | Dedup key (5s window) |
-| `X-Request-Id` | Request | Alternative dedup key |
-| `X-OmniRoute-Cache` | Response | `HIT` or `MISS` (non-streaming) |
-| `X-OmniRoute-Idempotent` | Response | `true` if deduplicated |
-| `X-OmniRoute-Progress` | Response | `enabled` if progress tracking on |
-| `X-OmniRoute-Session-Id` | Response | Effective session ID used by OmniRoute |
+| Header | Arah | Deskripsi |
+| ------------------------ | --------- | ------------------------------------------------------------ |
+| `X-OmniRoute-No-Cache` | Permintaan | Atur ke `true` untuk melewati cache |
+| `X-OmniRoute-Progress` | Permintaan | Atur ke `true` untuk event progres |
+| `X-Session-Id` | Permintaan | Kunci sesi tetap untuk afinitas sesi eksternal |
+| `x_session_id` | Permintaan | Varian garis bawah juga diterima (HTTP langsung) |
+| `Idempotency-Key` | Permintaan | Kunci deduplikasi (jendela 5 detik) |
+| `X-Request-Id` | Permintaan | Kunci deduplikasi alternatif |
+| `X-OmniRoute-Cache` | Respons | `HIT` atau `MISS` (non-streaming) |
+| `X-OmniRoute-Idempotent` | Respons | `true` jika dideduplikasi |
+| `X-OmniRoute-Progress` | Respons | `enabled` jika pelacakan progres aktif |
+| `X-OmniRoute-Session-Id` | Respons | ID sesi efektif yang digunakan OmniRoute |
-> Nginx note: if you rely on underscore headers (for example `x_session_id`), enable `underscores_in_headers on;`.
+> Catatan Nginx: jika Anda mengandalkan header bergaris bawah (misalnya `x_session_id`), aktifkan `underscores_in_headers on;`.
---
@@ -70,7 +70,7 @@ Content-Type: application/json
}
```
-Available providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA, **OpenRouter**, **GitHub Models**.
+Penyedia yang tersedia: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA, **OpenRouter**, **GitHub Models**.
```bash
# List all embedding models
@@ -93,7 +93,7 @@ Content-Type: application/json
}
```
-Available providers: OpenAI (GPT Image 2), xAI (Grok Image), Together AI (FLUX), Fireworks AI, Nebius (FLUX), Hyperbolic, NanoBanana, **OpenRouter**, SD WebUI (local), ComfyUI (local).
+Penyedia yang tersedia: OpenAI (GPT Image 2), xAI (Grok Image), Together AI (FLUX), Fireworks AI, Nebius (FLUX), Hyperbolic, NanoBanana, **OpenRouter**, SD WebUI (lokal), ComfyUI (lokal).
```bash
# List all image models
@@ -102,7 +102,7 @@ GET /v1/images/generations
---
-## List Models
+## Daftar Model
```bash
GET /v1/models
@@ -113,9 +113,9 @@ Authorization: Bearer your-api-key
---
-## Compatibility Endpoints
+## Titik Akhir Kompatibilitas
-| Method | Path | Format |
+| Metode | Path | Format |
| ------ | --------------------------- | ---------------------- |
| POST | `/v1/chat/completions` | OpenAI |
| POST | `/v1/messages` | Anthropic |
@@ -128,7 +128,7 @@ Authorization: Bearer your-api-key
| POST | `/v1beta/models/{...path}` | Gemini generateContent |
| POST | `/v1/api/chat` | Ollama |
-### Dedicated Provider Routes
+### Rute Penyedia Khusus
```bash
POST /v1/providers/{provider}/chat/completions
@@ -136,11 +136,11 @@ POST /v1/providers/{provider}/embeddings
POST /v1/providers/{provider}/images/generations
```
-The provider prefix is auto-added if missing. Mismatched models return `400`.
+Prefiks penyedia ditambahkan secara otomatis jika tidak ada. Model yang tidak cocok mengembalikan `400`.
---
-## Semantic Cache
+## Cache Semantik
```bash
# Get cache stats
@@ -150,7 +150,7 @@ GET /api/cache/stats
DELETE /api/cache/stats
```
-Response example:
+Contoh respons:
```json
{
@@ -169,171 +169,171 @@ Response example:
---
-## Dashboard & Management
+## Dasbor & Manajemen
-### Authentication
+### Otentikasi
-| Endpoint | Method | Description |
-| ----------------------------- | ------- | --------------------- |
-| `/api/auth/login` | POST | Login |
-| `/api/auth/logout` | POST | Logout |
-| `/api/settings/require-login` | GET/PUT | Toggle login required |
+| Titik Akhir | Metode | Deskripsi |
+| ----------------------------- | ------- | ---------------------------------- |
+| `/api/auth/login` | POST | Masuk |
+| `/api/auth/logout` | POST | Keluar |
+| `/api/settings/require-login` | GET/PUT | Aktifkan/nonaktifkan wajib login |
-### Provider Management
+### Manajemen Penyedia
-| Endpoint | Method | Description |
-| ---------------------------- | --------------------- | ---------------------------------------------- |
-| `/api/providers` | GET/POST | List / create providers |
-| `/api/providers/[id]` | GET/PUT/DELETE | Manage a provider |
-| `/api/providers/[id]/test` | POST | Test provider connection |
-| `/api/providers/[id]/models` | GET | List provider models |
-| `/api/providers/validate` | POST | Validate provider config |
-| `/api/provider-nodes*` | Various | Provider node management |
-| `/api/provider-models` | GET/POST/PATCH/DELETE | Custom models (add, update, hide/show, delete) |
+| Titik Akhir | Metode | Deskripsi |
+| ---------------------------- | --------------------- | ---------------------------------------------------------- |
+| `/api/providers` | GET/POST | Daftar / buat penyedia |
+| `/api/providers/[id]` | GET/PUT/DELETE | Kelola penyedia |
+| `/api/providers/[id]/test` | POST | Uji koneksi penyedia |
+| `/api/providers/[id]/models` | GET | Daftar model penyedia |
+| `/api/providers/validate` | POST | Validasi konfigurasi penyedia |
+| `/api/provider-nodes*` | Berbagai | Manajemen simpul penyedia |
+| `/api/provider-models` | GET/POST/PATCH/DELETE | Model kustom (tambah, perbarui, sembunyikan/tampilkan, hapus) |
-### OAuth Flows
+### Alur OAuth
-| Endpoint | Method | Description |
-| -------------------------------- | ------- | ----------------------- |
-| `/api/oauth/[provider]/[action]` | Various | Provider-specific OAuth |
+| Titik Akhir | Metode | Deskripsi |
+| -------------------------------- | -------- | ----------------------------- |
+| `/api/oauth/[provider]/[action]` | Berbagai | OAuth khusus penyedia |
-### Routing & Config
+### Perutean & Konfigurasi
-| Endpoint | Method | Description |
-| --------------------- | -------- | ----------------------------- |
-| `/api/models/alias` | GET/POST | Model aliases |
-| `/api/models/catalog` | GET | All models by provider + type |
-| `/api/combos*` | Various | Combo management |
-| `/api/keys*` | Various | API key management |
-| `/api/pricing` | GET | Model pricing |
+| Titik Akhir | Metode | Deskripsi |
+| --------------------- | -------- | ----------------------------------- |
+| `/api/models/alias` | GET/POST | Alias model |
+| `/api/models/catalog` | GET | Semua model berdasarkan penyedia + tipe |
+| `/api/combos*` | Berbagai | Manajemen combo |
+| `/api/keys*` | Berbagai | Manajemen kunci API |
+| `/api/pricing` | GET | Harga model |
-### Usage & Analytics
+### Penggunaan & Analitik
-| Endpoint | Method | Description |
-| --------------------------- | ------ | -------------------- |
-| `/api/usage/history` | GET | Usage history |
-| `/api/usage/logs` | GET | Usage logs |
-| `/api/usage/request-logs` | GET | Request-level logs |
-| `/api/usage/[connectionId]` | GET | Per-connection usage |
+| Titik Akhir | Metode | Deskripsi |
+| --------------------------- | ------ | ------------------------------ |
+| `/api/usage/history` | GET | Riwayat penggunaan |
+| `/api/usage/logs` | GET | Log penggunaan |
+| `/api/usage/request-logs` | GET | Log tingkat permintaan |
+| `/api/usage/[connectionId]` | GET | Penggunaan per koneksi |
-### Settings
+### Pengaturan
-| Endpoint | Method | Description |
-| ------------------------------- | ------------- | ---------------------- |
-| `/api/settings` | GET/PUT/PATCH | General settings |
-| `/api/settings/proxy` | GET/PUT | Network proxy config |
-| `/api/settings/proxy/test` | POST | Test proxy connection |
-| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist |
-| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget |
-| `/api/settings/system-prompt` | GET/PUT | Global system prompt |
+| Titik Akhir | Metode | Deskripsi |
+| ------------------------------- | ------------- | ------------------------------- |
+| `/api/settings` | GET/PUT/PATCH | Pengaturan umum |
+| `/api/settings/proxy` | GET/PUT | Konfigurasi proksi jaringan |
+| `/api/settings/proxy/test` | POST | Uji koneksi proksi |
+| `/api/settings/ip-filter` | GET/PUT | Daftar izin/blokir IP |
+| `/api/settings/thinking-budget` | GET/PUT | Anggaran token penalaran |
+| `/api/settings/system-prompt` | GET/PUT | Prompt sistem global |
-### Monitoring
+### Pemantauan
-| Endpoint | Method | Description |
-| ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------- |
-| `/api/sessions` | GET | Active session tracking |
-| `/api/rate-limits` | GET | Per-account rate limits |
-| `/api/monitoring/health` | GET | Health check + provider summary (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
-| `/api/cache/stats` | GET/DELETE | Cache stats / clear |
+| Titik Akhir | Metode | Deskripsi |
+| ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------- |
+| `/api/sessions` | GET | Pelacakan sesi aktif |
+| `/api/rate-limits` | GET | Batas laju per akun |
+| `/api/monitoring/health` | GET | Pemeriksaan kesehatan + ringkasan penyedia (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
+| `/api/cache/stats` | GET/DELETE | Statistik cache / hapus |
-### Backup & Export/Import
+### Cadangan & Ekspor/Impor
-| Endpoint | Method | Description |
-| --------------------------- | ------ | --------------------------------------- |
-| `/api/db-backups` | GET | List available backups |
-| `/api/db-backups` | PUT | Create a manual backup |
-| `/api/db-backups` | POST | Restore from a specific backup |
-| `/api/db-backups/export` | GET | Download database as .sqlite file |
-| `/api/db-backups/import` | POST | Upload .sqlite file to replace database |
-| `/api/db-backups/exportAll` | GET | Download full backup as .tar.gz archive |
+| Titik Akhir | Metode | Deskripsi |
+| --------------------------- | ------ | ------------------------------------------------ |
+| `/api/db-backups` | GET | Daftar cadangan yang tersedia |
+| `/api/db-backups` | PUT | Buat cadangan manual |
+| `/api/db-backups` | POST | Pulihkan dari cadangan tertentu |
+| `/api/db-backups/export` | GET | Unduh database sebagai file .sqlite |
+| `/api/db-backups/import` | POST | Unggah file .sqlite untuk mengganti database |
+| `/api/db-backups/exportAll` | GET | Unduh cadangan lengkap sebagai arsip .tar.gz |
-### Cloud Sync
+### Sinkronisasi Cloud
-| Endpoint | Method | Description |
-| ---------------------- | ------- | --------------------- |
-| `/api/sync/cloud` | Various | Cloud sync operations |
-| `/api/sync/initialize` | POST | Initialize sync |
-| `/api/cloud/*` | Various | Cloud management |
+| Titik Akhir | Metode | Deskripsi |
+| ---------------------- | -------- | ------------------------------ |
+| `/api/sync/cloud` | Berbagai | Operasi sinkronisasi cloud |
+| `/api/sync/initialize` | POST | Inisialisasi sinkronisasi |
+| `/api/cloud/*` | Berbagai | Manajemen cloud |
-### Tunnels
+### Terowongan
-| Endpoint | Method | Description |
-| -------------------------- | ------ | ----------------------------------------------------------------------- |
-| `/api/tunnels/cloudflared` | GET | Read Cloudflare Quick Tunnel install/runtime status for the dashboard |
-| `/api/tunnels/cloudflared` | POST | Enable or disable the Cloudflare Quick Tunnel (`action=enable/disable`) |
+| Titik Akhir | Metode | Deskripsi |
+| -------------------------- | ------ | ----------------------------------------------------------------------------------------------- |
+| `/api/tunnels/cloudflared` | GET | Baca status instalasi/runtime Cloudflare Quick Tunnel untuk dasbor |
+| `/api/tunnels/cloudflared` | POST | Aktifkan atau nonaktifkan Cloudflare Quick Tunnel (`action=enable/disable`) |
-### CLI Tools
+### Alat CLI
-| Endpoint | Method | Description |
-| ---------------------------------- | ------ | ------------------- |
-| `/api/cli-tools/claude-settings` | GET | Claude CLI status |
-| `/api/cli-tools/codex-settings` | GET | Codex CLI status |
-| `/api/cli-tools/droid-settings` | GET | Droid CLI status |
-| `/api/cli-tools/openclaw-settings` | GET | OpenClaw CLI status |
-| `/api/cli-tools/runtime/[toolId]` | GET | Generic CLI runtime |
+| Titik Akhir | Metode | Deskripsi |
+| ---------------------------------- | ------ | ---------------------- |
+| `/api/cli-tools/claude-settings` | GET | Status CLI Claude |
+| `/api/cli-tools/codex-settings` | GET | Status CLI Codex |
+| `/api/cli-tools/droid-settings` | GET | Status CLI Droid |
+| `/api/cli-tools/openclaw-settings` | GET | Status CLI OpenClaw |
+| `/api/cli-tools/runtime/[toolId]` | GET | Runtime CLI generik |
-CLI responses include: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
+Respons CLI mencakup: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
-### ACP Agents
+### Agen ACP
-| Endpoint | Method | Description |
-| ----------------- | ------ | -------------------------------------------------------- |
-| `/api/acp/agents` | GET | List all detected agents (built-in + custom) with status |
-| `/api/acp/agents` | POST | Add custom agent or refresh detection cache |
-| `/api/acp/agents` | DELETE | Remove a custom agent by `id` query param |
+| Titik Akhir | Metode | Deskripsi |
+| ----------------- | ------ | ------------------------------------------------------------------ |
+| `/api/acp/agents` | GET | Daftar semua agen yang terdeteksi (bawaan + kustom) beserta status |
+| `/api/acp/agents` | POST | Tambah agen kustom atau segarkan cache deteksi |
+| `/api/acp/agents` | DELETE | Hapus agen kustom berdasarkan parameter kueri `id` |
-GET response includes `agents[]` (id, name, binary, version, installed, protocol, isCustom) and `summary` (total, installed, notFound, builtIn, custom).
+Respons GET mencakup `agents[]` (id, name, binary, version, installed, protocol, isCustom) dan `summary` (total, installed, notFound, builtIn, custom).
-### Resilience & Rate Limits
+### Ketahanan & Batas Laju
-| Endpoint | Method | Description |
-| ----------------------- | --------- | ---------------------------------------------------------------------------------- |
-| `/api/resilience` | GET/PATCH | Get/update request queue, connection cooldown, provider breaker, and wait settings |
-| `/api/resilience/reset` | POST | Reset provider circuit breakers |
-| `/api/rate-limits` | GET | Per-account rate limit status |
-| `/api/rate-limit` | GET | Global rate limit configuration |
+| Titik Akhir | Metode | Deskripsi |
+| ----------------------- | --------- | -------------------------------------------------------------------------------------------------- |
+| `/api/resilience` | GET/PATCH | Ambil/perbarui antrean permintaan, cooldown koneksi, pemutus sirkuit penyedia, dan pengaturan tunggu |
+| `/api/resilience/reset` | POST | Reset pemutus sirkuit penyedia |
+| `/api/rate-limits` | GET | Status batas laju per akun |
+| `/api/rate-limit` | GET | Konfigurasi batas laju global |
-### Evals
+### Eval
-| Endpoint | Method | Description |
-| ------------ | -------- | --------------------------------- |
-| `/api/evals` | GET/POST | List eval suites / run evaluation |
+| Titik Akhir | Metode | Deskripsi |
+| ------------ | -------- | -------------------------------------- |
+| `/api/evals` | GET/POST | Daftar suite eval / jalankan evaluasi |
-### Policies
+### Kebijakan
-| Endpoint | Method | Description |
-| --------------- | --------------- | ----------------------- |
-| `/api/policies` | GET/POST/DELETE | Manage routing policies |
+| Titik Akhir | Metode | Deskripsi |
+| --------------- | --------------- | ------------------------------ |
+| `/api/policies` | GET/POST/DELETE | Kelola kebijakan perutean |
-### Compliance
+### Kepatuhan
-| Endpoint | Method | Description |
-| --------------------------- | ------ | ----------------------------- |
-| `/api/compliance/audit-log` | GET | Compliance audit log (last N) |
+| Titik Akhir | Metode | Deskripsi |
+| --------------------------- | ------ | ----------------------------------- |
+| `/api/compliance/audit-log` | GET | Log audit kepatuhan (N terakhir) |
-### v1beta (Gemini-Compatible)
+### v1beta (Kompatibel dengan Gemini)
-| Endpoint | Method | Description |
-| -------------------------- | ------ | --------------------------------- |
-| `/v1beta/models` | GET | List models in Gemini format |
-| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint |
+| Titik Akhir | Metode | Deskripsi |
+| -------------------------- | ------ | ----------------------------------- |
+| `/v1beta/models` | GET | Daftar model dalam format Gemini |
+| `/v1beta/models/{...path}` | POST | Titik akhir `generateContent` Gemini |
-These endpoints mirror Gemini's API format for clients that expect native Gemini SDK compatibility.
+Titik akhir ini mencerminkan format API Gemini untuk klien yang mengharapkan kompatibilitas SDK Gemini asli.
-### Internal / System APIs
+### API Internal / Sistem
-| Endpoint | Method | Description |
-| ------------------------ | ------ | ---------------------------------------------------- |
-| `/api/init` | GET | Application initialization check (used on first run) |
-| `/api/tags` | GET | Ollama-compatible model tags (for Ollama clients) |
-| `/api/restart` | POST | Trigger graceful server restart |
-| `/api/shutdown` | POST | Trigger graceful server shutdown |
-| `/api/system/env/repair` | POST | Repair OAuth provider environment variables |
-| `/api/system-info` | GET | Generate system diagnostics report |
+| Titik Akhir | Metode | Deskripsi |
+| ------------------------ | ------ | ---------------------------------------------------------------- |
+| `/api/init` | GET | Pemeriksaan inisialisasi aplikasi (digunakan saat pertama kali) |
+| `/api/tags` | GET | Tag model kompatibel Ollama (untuk klien Ollama) |
+| `/api/restart` | POST | Picu restart server secara halus |
+| `/api/shutdown` | POST | Picu penghentian server secara halus |
+| `/api/system/env/repair` | POST | Perbaiki variabel lingkungan penyedia OAuth |
+| `/api/system-info` | GET | Buat laporan diagnostik sistem |
-> **Note:** These endpoints are used internally by the system or for Ollama client compatibility. They are not typically called by end users.
+> **Catatan:** Titik akhir ini digunakan secara internal oleh sistem atau untuk kompatibilitas klien Ollama. Biasanya tidak dipanggil langsung oleh pengguna akhir.
-### OAuth Environment Repair _(v3.6.1+)_
+### Perbaikan Lingkungan OAuth _(v3.6.1+)_
```bash
POST /api/system/env/repair
@@ -344,7 +344,7 @@ Content-Type: application/json
}
```
-Repairs missing or corrupted OAuth environment variables for a specific provider. Returns:
+Memperbaiki variabel lingkungan OAuth yang hilang atau rusak untuk penyedia tertentu. Mengembalikan:
```json
{
@@ -356,7 +356,7 @@ Repairs missing or corrupted OAuth environment variables for a specific provider
---
-## Audio Transcription
+## Transkripsi Audio
```bash
POST /v1/audio/transcriptions
@@ -364,9 +364,9 @@ Authorization: Bearer your-api-key
Content-Type: multipart/form-data
```
-Transcribe audio files using Deepgram or AssemblyAI.
+Transkripsi file audio menggunakan Deepgram atau AssemblyAI.
-**Request:**
+**Permintaan:**
```bash
curl -X POST http://localhost:20128/v1/audio/transcriptions \
@@ -375,7 +375,7 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \
-F "model=deepgram/nova-3"
```
-**Response:**
+**Respons:**
```json
{
@@ -386,15 +386,15 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \
}
```
-**Supported providers:** `deepgram/nova-3`, `assemblyai/best`.
+**Penyedia yang didukung:** `deepgram/nova-3`, `assemblyai/best`.
-**Supported formats:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
+**Format yang didukung:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
---
-## Ollama Compatibility
+## Kompatibilitas Ollama
-For clients that use Ollama's API format:
+Untuk klien yang menggunakan format API Ollama:
```bash
# Chat endpoint (Ollama format)
@@ -404,18 +404,18 @@ POST /v1/api/chat
GET /api/tags
```
-Requests are automatically translated between Ollama and internal formats.
+Permintaan diterjemahkan secara otomatis antara format Ollama dan format internal.
---
-## Telemetry
+## Telemetri
```bash
# Get latency telemetry summary (p50/p95/p99 per provider)
GET /api/telemetry/summary
```
-**Response:**
+**Respons:**
```json
{
@@ -428,7 +428,7 @@ GET /api/telemetry/summary
---
-## Budget
+## Anggaran
```bash
# Get budget status for all API keys
@@ -445,25 +445,25 @@ Content-Type: application/json
}
```
-## Request Processing
+## Pemrosesan Permintaan
-1. Client sends request to `/v1/*`
-2. Route handler calls `handleChat`, `handleEmbedding`, `handleAudioTranscription`, or `handleImageGeneration`
-3. Model is resolved (direct provider/model or alias/combo)
-4. Credentials selected from local DB with account availability filtering
-5. For chat: `handleChatCore` — format detection, translation, cache check, idempotency check
-6. Provider executor sends upstream request
-7. Response translated back to client format (chat) or returned as-is (embeddings/images/audio)
-8. Usage/logging recorded
-9. Fallback applies on errors according to combo rules
+1. Klien mengirim permintaan ke `/v1/*`
+2. Handler rute memanggil `handleChat`, `handleEmbedding`, `handleAudioTranscription`, atau `handleImageGeneration`
+3. Model diselesaikan (penyedia/model langsung, alias, atau combo)
+4. Kredensial dipilih dari DB lokal dengan penyaringan ketersediaan akun
+5. Untuk chat: `handleChatCore` — deteksi format, translasi, pemeriksaan cache, pemeriksaan idempoten
+6. Eksekutor penyedia mengirim permintaan upstream
+7. Respons diterjemahkan kembali ke format klien (chat) atau dikembalikan apa adanya (embeddings/gambar/audio)
+8. Penggunaan/logging dicatat
+9. Fallback diterapkan pada error sesuai aturan combo
-Full architecture reference: [`ARCHITECTURE.md`](ARCHITECTURE.md)
+Referensi arsitektur lengkap: [`ARCHITECTURE.md`](ARCHITECTURE.md)
---
-## Authentication
+## Otentikasi
-- Dashboard routes (`/dashboard/*`) use `auth_token` cookie
-- Login uses saved password hash; fallback to `INITIAL_PASSWORD`
-- `requireLogin` toggleable via `/api/settings/require-login`
-- `/v1/*` routes optionally require Bearer API key when `REQUIRE_API_KEY=true`
+- Rute dasbor (`/dashboard/*`) menggunakan cookie `auth_token`
+- Login menggunakan hash kata sandi yang tersimpan; fallback ke `INITIAL_PASSWORD`
+- `requireLogin` dapat diaktifkan/nonaktifkan melalui `/api/settings/require-login`
+- Rute `/v1/*` secara opsional memerlukan kunci API Bearer saat `REQUIRE_API_KEY=true`
diff --git a/docs/i18n/id/docs/reference/CLI-TOOLS.md b/docs/i18n/id/docs/reference/CLI-TOOLS.md
index bb3b80fb0f..126a51864e 100644
--- a/docs/i18n/id/docs/reference/CLI-TOOLS.md
+++ b/docs/i18n/id/docs/reference/CLI-TOOLS.md
@@ -1,86 +1,86 @@
-# CLI Tools Setup Guide — OmniRoute (Bahasa Indonesia)
+# Panduan Pengaturan Alat CLI — OmniRoute (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CLI-TOOLS.md) · 🇸🇦 [ar](../../ar/docs/CLI-TOOLS.md) · 🇧🇬 [bg](../../bg/docs/CLI-TOOLS.md) · 🇧🇩 [bn](../../bn/docs/CLI-TOOLS.md) · 🇨🇿 [cs](../../cs/docs/CLI-TOOLS.md) · 🇩🇰 [da](../../da/docs/CLI-TOOLS.md) · 🇩🇪 [de](../../de/docs/CLI-TOOLS.md) · 🇪🇸 [es](../../es/docs/CLI-TOOLS.md) · 🇮🇷 [fa](../../fa/docs/CLI-TOOLS.md) · 🇫🇮 [fi](../../fi/docs/CLI-TOOLS.md) · 🇫🇷 [fr](../../fr/docs/CLI-TOOLS.md) · 🇮🇳 [gu](../../gu/docs/CLI-TOOLS.md) · 🇮🇱 [he](../../he/docs/CLI-TOOLS.md) · 🇮🇳 [hi](../../hi/docs/CLI-TOOLS.md) · 🇭🇺 [hu](../../hu/docs/CLI-TOOLS.md) · 🇮🇩 [id](../../id/docs/CLI-TOOLS.md) · 🇮🇹 [it](../../it/docs/CLI-TOOLS.md) · 🇯🇵 [ja](../../ja/docs/CLI-TOOLS.md) · 🇰🇷 [ko](../../ko/docs/CLI-TOOLS.md) · 🇮🇳 [mr](../../mr/docs/CLI-TOOLS.md) · 🇲🇾 [ms](../../ms/docs/CLI-TOOLS.md) · 🇳🇱 [nl](../../nl/docs/CLI-TOOLS.md) · 🇳🇴 [no](../../no/docs/CLI-TOOLS.md) · 🇵🇭 [phi](../../phi/docs/CLI-TOOLS.md) · 🇵🇱 [pl](../../pl/docs/CLI-TOOLS.md) · 🇵🇹 [pt](../../pt/docs/CLI-TOOLS.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CLI-TOOLS.md) · 🇷🇴 [ro](../../ro/docs/CLI-TOOLS.md) · 🇷🇺 [ru](../../ru/docs/CLI-TOOLS.md) · 🇸🇰 [sk](../../sk/docs/CLI-TOOLS.md) · 🇸🇪 [sv](../../sv/docs/CLI-TOOLS.md) · 🇰🇪 [sw](../../sw/docs/CLI-TOOLS.md) · 🇮🇳 [ta](../../ta/docs/CLI-TOOLS.md) · 🇮🇳 [te](../../te/docs/CLI-TOOLS.md) · 🇹🇭 [th](../../th/docs/CLI-TOOLS.md) · 🇹🇷 [tr](../../tr/docs/CLI-TOOLS.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CLI-TOOLS.md) · 🇵🇰 [ur](../../ur/docs/CLI-TOOLS.md) · 🇻🇳 [vi](../../vi/docs/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CLI-TOOLS.md)
---
-This guide explains how to install and configure all supported AI coding CLI tools
-to use **OmniRoute** as the unified backend, giving you centralized key management,
-cost tracking, model switching, and request logging across every tool.
+Panduan ini menjelaskan cara menginstal dan mengonfigurasi semua alat CLI coding AI yang didukung
+untuk menggunakan **OmniRoute** sebagai backend terpadu, memberikan manajemen kunci terpusat,
+pelacakan biaya, pergantian model, dan pencatatan permintaan di semua alat.
---
-## How It Works
+## Cara Kerjanya
```
Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilot
│
- ▼ (all point to OmniRoute)
+ ▼ (semua mengarah ke OmniRoute)
http://YOUR_SERVER:20128/v1
│
- ▼ (OmniRoute routes to the right provider)
+ ▼ (OmniRoute meneruskan ke penyedia yang tepat)
Anthropic / OpenAI / Gemini / DeepSeek / Groq / Mistral / ...
```
-**Benefits:**
+**Manfaat:**
-- One API key to manage all tools
-- Cost tracking across all CLIs in the dashboard
-- Model switching without reconfiguring every tool
-- Works locally and on remote servers (VPS)
+- Satu API key untuk mengelola semua alat
+- Pelacakan biaya di semua CLI melalui dashboard
+- Pergantian model tanpa mengonfigurasi ulang setiap alat
+- Berjalan secara lokal maupun di server jarak jauh (VPS)
---
-## Supported Tools (Dashboard Source of Truth)
+## Alat yang Didukung (Sumber Kebenaran Dashboard)
-The dashboard cards in `/dashboard/cli-tools` are generated from `src/shared/constants/cliTools.ts`.
-Current list (v3.0.0-rc.16):
+Kartu dashboard di `/dashboard/cli-tools` dibuat dari `src/shared/constants/cliTools.ts`.
+Daftar saat ini (v3.0.0-rc.16):
-| Tool | ID | Command | Setup Mode | Install Method |
-| ------------------ | ------------- | ---------- | ---------- | -------------- |
-| **Claude Code** | `claude` | `claude` | env | npm |
-| **OpenAI Codex** | `codex` | `codex` | custom | npm |
-| **Factory Droid** | `droid` | `droid` | custom | bundled/CLI |
-| **OpenClaw** | `openclaw` | `openclaw` | custom | bundled/CLI |
-| **Cursor** | `cursor` | app | guide | desktop app |
-| **Cline** | `cline` | `cline` | custom | npm |
-| **Kilo Code** | `kilo` | `kilocode` | custom | npm |
-| **Continue** | `continue` | extension | guide | VS Code |
-| **Antigravity** | `antigravity` | internal | mitm | OmniRoute |
-| **GitHub Copilot** | `copilot` | extension | custom | VS Code |
-| **OpenCode** | `opencode` | `opencode` | guide | npm |
-| **Kiro AI** | `kiro` | app/cli | mitm | desktop/CLI |
-| **Qwen Code** | `qwen` | `qwen` | custom | npm |
+| Alat | ID | Perintah | Mode Pengaturan | Metode Instalasi |
+| ------------------ | ------------- | ---------- | --------------- | ---------------- |
+| **Claude Code** | `claude` | `claude` | env | npm |
+| **OpenAI Codex** | `codex` | `codex` | custom | npm |
+| **Factory Droid** | `droid` | `droid` | custom | bundled/CLI |
+| **OpenClaw** | `openclaw` | `openclaw` | custom | bundled/CLI |
+| **Cursor** | `cursor` | app | guide | desktop app |
+| **Cline** | `cline` | `cline` | custom | npm |
+| **Kilo Code** | `kilo` | `kilocode` | custom | npm |
+| **Continue** | `continue` | extension | guide | VS Code |
+| **Antigravity** | `antigravity` | internal | mitm | OmniRoute |
+| **GitHub Copilot** | `copilot` | extension | custom | VS Code |
+| **OpenCode** | `opencode` | `opencode` | guide | npm |
+| **Kiro AI** | `kiro` | app/cli | mitm | desktop/CLI |
+| **Qwen Code** | `qwen` | `qwen` | custom | npm |
-### CLI fingerprint sync (Agents + Settings)
+### Sinkronisasi fingerprint CLI (Agents + Pengaturan)
-`/dashboard/agents` and `Settings > CLI Fingerprint` use `src/shared/constants/cliCompatProviders.ts`.
-This keeps provider IDs aligned with CLI cards and legacy IDs.
+`/dashboard/agents` dan `Settings > CLI Fingerprint` menggunakan `src/shared/constants/cliCompatProviders.ts`.
+Ini menjaga ID penyedia tetap selaras dengan kartu CLI dan ID lama.
-| CLI ID | Fingerprint Provider ID |
+| CLI ID | ID Penyedia Fingerprint |
| ---------------------------------------------------------------------------------------------------- | ----------------------- |
| `kilo` | `kilocode` |
| `copilot` | `github` |
| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | same ID |
-Legacy IDs still accepted for compatibility: `copilot`, `kimi-coding`, `qwen`.
+ID lama yang masih diterima untuk kompatibilitas: `copilot`, `kimi-coding`, `qwen`.
---
-## Step 1 — Get an OmniRoute API Key
+## Langkah 1 — Dapatkan API Key OmniRoute
-1. Open the OmniRoute dashboard → **API Manager** (`/dashboard/api-manager`)
-2. Click **Create API Key**
-3. Give it a name (e.g. `cli-tools`) and select all permissions
-4. Copy the key — you'll need it for every CLI below
+1. Buka dashboard OmniRoute → **API Manager** (`/dashboard/api-manager`)
+2. Klik **Create API Key**
+3. Beri nama (misalnya `cli-tools`) dan pilih semua izin
+4. Salin kunci tersebut — Anda akan membutuhkannya untuk setiap CLI di bawah
-> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
+> Kunci Anda terlihat seperti: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
---
-## Step 2 — Install CLI Tools
+## Langkah 2 — Instal Alat CLI
-All npm-based tools require Node.js 18+:
+Semua alat berbasis npm memerlukan Node.js 18+:
```bash
# Claude Code (Anthropic)
@@ -104,7 +104,7 @@ curl -fsSL https://cli.kiro.dev/install | bash
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
```
-**Verify:**
+**Verifikasi:**
```bash
claude --version # 2.x.x
@@ -117,9 +117,9 @@ kiro-cli --version # 1.x.x
---
-## Step 3 — Set Global Environment Variables
+## Langkah 3 — Tetapkan Variabel Lingkungan Global
-Add to `~/.bashrc` (or `~/.zshrc`), then run `source ~/.bashrc`:
+Tambahkan ke `~/.bashrc` (atau `~/.zshrc`), lalu jalankan `source ~/.bashrc`:
```bash
# OmniRoute Universal Endpoint
@@ -131,20 +131,20 @@ export GEMINI_BASE_URL="http://localhost:20128/v1"
export GEMINI_API_KEY="sk-your-omniroute-key"
```
-> For a **remote server** replace `localhost:20128` with the server IP or domain,
-> e.g. `http://192.168.0.15:20128`.
+> Untuk **server jarak jauh**, ganti `localhost:20128` dengan IP atau domain server,
+> misalnya `http://192.168.0.15:20128`.
---
-## Step 4 — Configure Each Tool
+## Langkah 4 — Konfigurasi Setiap Alat
### Claude Code
```bash
-# Via CLI:
+# Melalui CLI:
claude config set --global api-base-url http://localhost:20128/v1
-# Or create ~/.claude/settings.json:
+# Atau buat ~/.claude/settings.json:
mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
{
"apiBaseUrl": "http://localhost:20128/v1",
@@ -153,7 +153,7 @@ mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
EOF
```
-**Test:** `claude "say hello"`
+**Uji:** `claude "say hello"`
---
@@ -167,7 +167,7 @@ apiBaseUrl: http://localhost:20128/v1
EOF
```
-**Test:** `codex "what is 2+2?"`
+**Uji:** `codex "what is 2+2?"`
---
@@ -181,13 +181,13 @@ api_key = "sk-your-omniroute-key"
EOF
```
-**Test:** `opencode`
+**Uji:** `opencode`
---
-### Cline (CLI or VS Code)
+### Cline (CLI atau VS Code)
-**CLI mode:**
+**Mode CLI:**
```bash
mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
@@ -199,22 +199,22 @@ mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
EOF
```
-**VS Code mode:**
-Cline extension settings → API Provider: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1`
+**Mode VS Code:**
+Pengaturan ekstensi Cline → API Provider: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1`
-Or use the OmniRoute dashboard → **CLI Tools → Cline → Apply Config**.
+Atau gunakan dashboard OmniRoute → **CLI Tools → Cline → Apply Config**.
---
-### KiloCode (CLI or VS Code)
+### KiloCode (CLI atau VS Code)
-**CLI mode:**
+**Mode CLI:**
```bash
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
```
-**VS Code settings:**
+**Pengaturan VS Code:**
```json
{
@@ -223,11 +223,11 @@ kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
}
```
-Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**.
+Atau gunakan dashboard OmniRoute → **CLI Tools → KiloCode → Apply Config**.
---
-### Continue (VS Code Extension)
+### Continue (Ekstensi VS Code)
Edit `~/.continue/config.yaml`:
@@ -241,18 +241,18 @@ models:
default: true
```
-Restart VS Code after editing.
+Mulai ulang VS Code setelah mengedit.
---
### Kiro CLI (Amazon)
```bash
-# Login to your AWS/Kiro account:
+# Login ke akun AWS/Kiro Anda:
kiro-cli login
-# The CLI uses its own auth — OmniRoute is not needed as backend for Kiro CLI itself.
-# Use kiro-cli alongside OmniRoute for other tools.
+# CLI ini menggunakan autentikasinya sendiri — OmniRoute tidak diperlukan sebagai backend untuk Kiro CLI itu sendiri.
+# Gunakan kiro-cli bersama OmniRoute untuk alat lainnya.
kiro-cli status
```
@@ -260,9 +260,9 @@ kiro-cli status
### Qwen Code (Alibaba)
-Qwen Code supports OpenAI-compatible API endpoints via environment variables or `settings.json`.
+Qwen Code mendukung endpoint API yang kompatibel dengan OpenAI melalui variabel lingkungan atau `settings.json`.
-**Option 1: Environment variables (`~/.qwen/.env`)**
+**Opsi 1: Variabel lingkungan (`~/.qwen/.env`)**
```bash
mkdir -p ~/.qwen && cat > ~/.qwen/.env << EOF
@@ -272,7 +272,7 @@ OPENAI_MODEL="auto"
EOF
```
-**Option 2: `settings.json` with model providers**
+**Opsi 2: `settings.json` dengan penyedia model**
```json
// ~/.qwen/settings.json
@@ -294,7 +294,7 @@ EOF
}
```
-**Option 3: Inline CLI flags**
+**Opsi 3: Flag CLI langsung**
```bash
OPENAI_BASE_URL="http://localhost:20128/v1" \
@@ -303,76 +303,76 @@ OPENAI_MODEL="auto" \
qwen
```
-> For a **remote server** replace `localhost:20128` with the server IP or domain.
+> Untuk **server jarak jauh**, ganti `localhost:20128` dengan IP atau domain server.
-**Test:** `qwen "say hello"`
+**Uji:** `qwen "say hello"`
-### Cursor (Desktop App)
+### Cursor (Aplikasi Desktop)
-> **Note:** Cursor routes requests through its cloud. For OmniRoute integration,
-> enable **Cloud Endpoint** in OmniRoute Settings and use your public domain URL.
+> **Catatan:** Cursor merutekan permintaan melalui cloudnya sendiri. Untuk integrasi OmniRoute,
+> aktifkan **Cloud Endpoint** di Pengaturan OmniRoute dan gunakan URL domain publik Anda.
-Via GUI: **Settings → Models → OpenAI API Key**
+Melalui GUI: **Settings → Models → OpenAI API Key**
- Base URL: `https://your-domain.com/v1`
-- API Key: your OmniRoute key
+- API Key: kunci OmniRoute Anda
---
-## Dashboard Auto-Configuration
+## Konfigurasi Otomatis Dashboard
-The OmniRoute dashboard automates configuration for most tools:
+Dashboard OmniRoute mengotomatiskan konfigurasi untuk sebagian besar alat:
-1. Go to `http://localhost:20128/dashboard/cli-tools`
-2. Expand any tool card
-3. Select your API key from the dropdown
-4. Click **Apply Config** (if tool is detected as installed)
-5. Or copy the generated config snippet manually
+1. Buka `http://localhost:20128/dashboard/cli-tools`
+2. Perluas kartu alat mana pun
+3. Pilih API key Anda dari menu tarik-turun
+4. Klik **Apply Config** (jika alat terdeteksi telah terinstal)
+5. Atau salin cuplikan konfigurasi yang dihasilkan secara manual
---
-## Built-in Agents: Droid & OpenClaw
+## Agen Bawaan: Droid & OpenClaw
-**Droid** and **OpenClaw** are AI agents built directly into OmniRoute — no installation needed.
-They run as internal routes and use OmniRoute's model routing automatically.
+**Droid** dan **OpenClaw** adalah agen AI yang dibangun langsung ke dalam OmniRoute — tidak perlu instalasi.
+Keduanya berjalan sebagai rute internal dan menggunakan perutean model OmniRoute secara otomatis.
-- Access: `http://localhost:20128/dashboard/agents`
-- Configure: same combos and providers as all other tools
-- No API key or CLI install required
+- Akses: `http://localhost:20128/dashboard/agents`
+- Konfigurasi: combo dan penyedia yang sama seperti semua alat lainnya
+- Tidak memerlukan API key atau instalasi CLI
---
-## Available API Endpoints
+## Endpoint API yang Tersedia
-| Endpoint | Description | Use For |
-| -------------------------- | ----------------------------- | --------------------------- |
-| `/v1/chat/completions` | Standard chat (all providers) | All modern tools |
-| `/v1/responses` | Responses API (OpenAI format) | Codex, agentic workflows |
-| `/v1/completions` | Legacy text completions | Older tools using `prompt:` |
-| `/v1/embeddings` | Text embeddings | RAG, search |
-| `/v1/images/generations` | Image generation | GPT-Image, Flux, etc. |
-| `/v1/audio/speech` | Text-to-speech | ElevenLabs, OpenAI TTS |
-| `/v1/audio/transcriptions` | Speech-to-text | Deepgram, AssemblyAI |
+| Endpoint | Deskripsi | Digunakan Untuk |
+| -------------------------- | --------------------------------- | --------------------------- |
+| `/v1/chat/completions` | Chat standar (semua penyedia) | Semua alat modern |
+| `/v1/responses` | Responses API (format OpenAI) | Codex, alur kerja agentik |
+| `/v1/completions` | Penyelesaian teks lama | Alat lama yang menggunakan `prompt:` |
+| `/v1/embeddings` | Embedding teks | RAG, pencarian |
+| `/v1/images/generations` | Pembuatan gambar | GPT-Image, Flux, dll. |
+| `/v1/audio/speech` | Teks ke ucapan | ElevenLabs, OpenAI TTS |
+| `/v1/audio/transcriptions` | Ucapan ke teks | Deepgram, AssemblyAI |
---
## Pemecahan Masalah
-| Error | Cause | Fix |
-| ------------------------- | ----------------------- | ------------------------------------------ |
-| `Connection refused` | OmniRoute not running | `pm2 start omniroute` |
-| `401 Unauthorized` | Wrong API key | Check in `/dashboard/api-manager` |
-| `No combo configured` | No active routing combo | Set up in `/dashboard/combos` |
-| `invalid model` | Model not in catalog | Use `auto` or check `/dashboard/providers` |
-| CLI shows "not installed" | Binary not in PATH | Check `which ` |
-| `kiro-cli: not found` | Not in PATH | `export PATH="$HOME/.local/bin:$PATH"` |
+| Error | Penyebab | Solusi |
+| ------------------------- | --------------------------------- | ------------------------------------------ |
+| `Connection refused` | OmniRoute tidak berjalan | `pm2 start omniroute` |
+| `401 Unauthorized` | API key salah | Periksa di `/dashboard/api-manager` |
+| `No combo configured` | Tidak ada combo perutean aktif | Atur di `/dashboard/combos` |
+| `invalid model` | Model tidak ada dalam katalog | Gunakan `auto` atau periksa `/dashboard/providers` |
+| CLI menampilkan "not installed" | Biner tidak ada di PATH | Periksa `which ` |
+| `kiro-cli: not found` | Tidak ada di PATH | `export PATH="$HOME/.local/bin:$PATH"` |
---
-## Quick Setup Script (One Command)
+## Skrip Pengaturan Cepat (Satu Perintah)
```bash
-# Install all CLIs and configure for OmniRoute (replace with your key and server URL)
+# Instal semua CLI dan konfigurasi untuk OmniRoute (ganti dengan kunci dan URL server Anda)
OMNIROUTE_URL="http://localhost:20128/v1"
OMNIROUTE_KEY="sk-your-omniroute-key"
@@ -381,7 +381,7 @@ npm install -g @anthropic-ai/claude-code @openai/codex opencode-ai cline kilocod
# Kiro CLI
apt-get install -y unzip 2>/dev/null; curl -fsSL https://cli.kiro.dev/install | bash
-# Write configs
+# Tulis konfigurasi
mkdir -p ~/.claude ~/.codex ~/.config/opencode ~/.continue
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
diff --git a/docs/i18n/id/docs/reference/ENVIRONMENT.md b/docs/i18n/id/docs/reference/ENVIRONMENT.md
index dec684ad6d..a789977767 100644
--- a/docs/i18n/id/docs/reference/ENVIRONMENT.md
+++ b/docs/i18n/id/docs/reference/ENVIRONMENT.md
@@ -1,55 +1,55 @@
-# Environment Variables Reference (Bahasa Indonesia)
+# Referensi Variabel Lingkungan (Bahasa Indonesia)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/ENVIRONMENT.md) · 🇸🇦 [ar](../../ar/docs/ENVIRONMENT.md) · 🇧🇬 [bg](../../bg/docs/ENVIRONMENT.md) · 🇧🇩 [bn](../../bn/docs/ENVIRONMENT.md) · 🇨🇿 [cs](../../cs/docs/ENVIRONMENT.md) · 🇩🇰 [da](../../da/docs/ENVIRONMENT.md) · 🇩🇪 [de](../../de/docs/ENVIRONMENT.md) · 🇪🇸 [es](../../es/docs/ENVIRONMENT.md) · 🇮🇷 [fa](../../fa/docs/ENVIRONMENT.md) · 🇫🇮 [fi](../../fi/docs/ENVIRONMENT.md) · 🇫🇷 [fr](../../fr/docs/ENVIRONMENT.md) · 🇮🇳 [gu](../../gu/docs/ENVIRONMENT.md) · 🇮🇱 [he](../../he/docs/ENVIRONMENT.md) · 🇮🇳 [hi](../../hi/docs/ENVIRONMENT.md) · 🇭🇺 [hu](../../hu/docs/ENVIRONMENT.md) · 🇮🇩 [id](../../id/docs/ENVIRONMENT.md) · 🇮🇹 [it](../../it/docs/ENVIRONMENT.md) · 🇯🇵 [ja](../../ja/docs/ENVIRONMENT.md) · 🇰🇷 [ko](../../ko/docs/ENVIRONMENT.md) · 🇮🇳 [mr](../../mr/docs/ENVIRONMENT.md) · 🇲🇾 [ms](../../ms/docs/ENVIRONMENT.md) · 🇳🇱 [nl](../../nl/docs/ENVIRONMENT.md) · 🇳🇴 [no](../../no/docs/ENVIRONMENT.md) · 🇵🇭 [phi](../../phi/docs/ENVIRONMENT.md) · 🇵🇱 [pl](../../pl/docs/ENVIRONMENT.md) · 🇵🇹 [pt](../../pt/docs/ENVIRONMENT.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/ENVIRONMENT.md) · 🇷🇴 [ro](../../ro/docs/ENVIRONMENT.md) · 🇷🇺 [ru](../../ru/docs/ENVIRONMENT.md) · 🇸🇰 [sk](../../sk/docs/ENVIRONMENT.md) · 🇸🇪 [sv](../../sv/docs/ENVIRONMENT.md) · 🇰🇪 [sw](../../sw/docs/ENVIRONMENT.md) · 🇮🇳 [ta](../../ta/docs/ENVIRONMENT.md) · 🇮🇳 [te](../../te/docs/ENVIRONMENT.md) · 🇹🇭 [th](../../th/docs/ENVIRONMENT.md) · 🇹🇷 [tr](../../tr/docs/ENVIRONMENT.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/ENVIRONMENT.md) · 🇵🇰 [ur](../../ur/docs/ENVIRONMENT.md) · 🇻🇳 [vi](../../vi/docs/ENVIRONMENT.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/ENVIRONMENT.md)
---
-> Complete reference for every environment variable recognized by OmniRoute.
-> For a quick-start template, see [`.env.example`](../.env.example).
+> Referensi lengkap untuk setiap variabel lingkungan yang dikenali oleh OmniRoute.
+> Untuk template pengaturan cepat, lihat [`.env.example`](../.env.example).
---
-## Table of Contents
+## Daftar Isi
-- [1. Required Secrets](#1-required-secrets)
-- [2. Storage & Database](#2-storage--database)
-- [3. Network & Ports](#3-network--ports)
-- [4. Security & Authentication](#4-security--authentication)
-- [5. Input Sanitization & PII Protection](#5-input-sanitization--pii-protection)
-- [6. Tool & Routing Policies](#6-tool--routing-policies)
-- [7. URLs & Cloud Sync](#7-urls--cloud-sync)
-- [8. Outbound Proxy](#8-outbound-proxy)
-- [9. CLI Tool Integration](#9-cli-tool-integration)
-- [10. Internal Agent & MCP Integrations](#10-internal-agent--mcp-integrations)
-- [11. OAuth Provider Credentials](#11-oauth-provider-credentials)
-- [12. Provider User-Agent Overrides](#12-provider-user-agent-overrides)
-- [13. CLI Fingerprint Compatibility](#13-cli-fingerprint-compatibility)
-- [14. API Key Providers](#14-api-key-providers)
-- [15. Timeout Settings](#15-timeout-settings)
+- [1. Rahasia yang Wajib Ada](#1-required-secrets)
+- [2. Penyimpanan & Database](#2-storage--database)
+- [3. Jaringan & Port](#3-network--ports)
+- [4. Keamanan & Autentikasi](#4-security--authentication)
+- [5. Sanitasi Input & Perlindungan PII](#5-input-sanitization--pii-protection)
+- [6. Kebijakan Alat & Routing](#6-tool--routing-policies)
+- [7. URL & Sinkronisasi Cloud](#7-urls--cloud-sync)
+- [8. Proxy Keluar](#8-outbound-proxy)
+- [9. Integrasi Alat CLI](#9-cli-tool-integration)
+- [10. Agen Internal & Integrasi MCP](#10-internal-agent--mcp-integrations)
+- [11. Kredensial Provider OAuth](#11-oauth-provider-credentials)
+- [12. Override User-Agent Provider](#12-provider-user-agent-overrides)
+- [13. Kompatibilitas Fingerprint CLI](#13-cli-fingerprint-compatibility)
+- [14. Provider Kunci API](#14-api-key-providers)
+- [15. Pengaturan Batas Waktu](#15-timeout-settings)
- [16. Logging](#16-logging)
-- [17. Memory Optimization](#17-memory-optimization)
-- [18. Pricing Sync](#18-pricing-sync)
-- [19. Model Sync (Dev)](#19-model-sync-dev)
-- [20. Provider-Specific Settings](#20-provider-specific-settings)
-- [21. Proxy Health](#21-proxy-health)
+- [17. Optimasi Memori](#17-memory-optimization)
+- [18. Sinkronisasi Harga](#18-pricing-sync)
+- [19. Sinkronisasi Model (Dev)](#19-model-sync-dev)
+- [20. Pengaturan Spesifik Provider](#20-provider-specific-settings)
+- [21. Kesehatan Proxy](#21-proxy-health)
- [22. Debugging](#22-debugging)
-- [23. GitHub Integration](#23-github-integration)
-- [Deployment Scenarios](#deployment-scenarios)
-- [Audit: Removed / Dead Variables](#audit-removed--dead-variables)
+- [23. Integrasi GitHub](#23-github-integration)
+- [Skenario Deployment](#deployment-scenarios)
+- [Audit: Variabel yang Dihapus / Tidak Aktif](#audit-removed--dead-variables)
---
-## 1. Required Secrets
+## 1. Rahasia yang Wajib Ada
-These **must** be set before the first run. Without them, the application will either refuse to start or operate with insecure defaults.
+Variabel-variabel ini **harus** diatur sebelum menjalankan aplikasi pertama kali. Tanpa variabel ini, aplikasi akan menolak untuk berjalan atau beroperasi dengan pengaturan default yang tidak aman.
-| Variable | Required | Default | Source File | Description |
-| ------------------ | -------- | -------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
-| `JWT_SECRET` | **Yes** | _(none)_ | `src/lib/auth` | Signs/verifies all dashboard session cookies (JWT). Generate with `openssl rand -base64 48`. |
-| `API_KEY_SECRET` | **Yes** | _(none)_ | `src/lib/db/apiKeys.ts` | AES encryption key for API key values at rest in SQLite. Generate with `openssl rand -hex 32`. |
-| `INITIAL_PASSWORD` | **Yes** | `123456` | Bootstrap script | Sets the initial admin dashboard password. **Change before first use.** After login, change via Dashboard → Settings → Security. |
+| Variable | Wajib | Default | Source File | Deskripsi |
+| ------------------ | -------- | -------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
+| `JWT_SECRET` | **Ya** | _(none)_ | `src/lib/auth` | Menandatangani/memverifikasi semua cookie sesi dashboard (JWT). Buat dengan `openssl rand -base64 48`. |
+| `API_KEY_SECRET` | **Ya** | _(none)_ | `src/lib/db/apiKeys.ts` | Kunci enkripsi AES untuk nilai kunci API yang disimpan di SQLite. Buat dengan `openssl rand -hex 32`. |
+| `INITIAL_PASSWORD` | **Ya** | `123456` | Bootstrap script | Mengatur kata sandi awal admin dashboard. **Ubah sebelum pertama kali digunakan.** Setelah login, ubah melalui Dashboard → Settings → Security. |
-### Generation Commands
+### Perintah Pembuatan
```bash
# Generate all three secrets at once:
@@ -59,200 +59,200 @@ echo "INITIAL_PASSWORD=$(openssl rand -base64 16)"
```
> [!CAUTION]
-> Never commit `.env` files with real secrets to version control. The `.gitignore` already excludes `.env`, but verify before pushing.
+> Jangan pernah melakukan commit file `.env` yang berisi rahasia nyata ke version control. `.gitignore` sudah mengecualikan `.env`, namun verifikasi sebelum melakukan push.
---
-## 2. Storage & Database
+## 2. Penyimpanan & Database
-OmniRoute uses **SQLite** (via `better-sqlite3`) for all persistence. These variables control data location, encryption, and lifecycle.
+OmniRoute menggunakan **SQLite** (melalui `better-sqlite3`) untuk semua persistensi data. Variabel-variabel ini mengontrol lokasi data, enkripsi, dan siklus hidup data.
-| Variable | Default | Source File | Description |
-| -------------------------------- | -------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
-| `DATA_DIR` | `~/.omniroute/` | `src/lib/db/core.ts` | Root directory for SQLite DB, backups, and data files. Override for Docker volumes or custom paths. |
-| `STORAGE_ENCRYPTION_KEY` | _(empty = disabled)_ | `src/lib/db/encryption.ts` | AES key for full SQLite database encryption at rest. Generate with `openssl rand -hex 32`. |
-| `STORAGE_ENCRYPTION_KEY_VERSION` | `v1` | `scripts/bootstrap-env.mjs`, `electron/main.js` | Version label for the encryption key. Increment when performing key rotation to support decryption of old backups. |
-| `DISABLE_SQLITE_AUTO_BACKUP` | `false` | `src/lib/db/backup.ts` | When `true`, skips the automatic database backup that runs before migrations on every startup. |
-| `OMNIROUTE_CRYPT_KEY` | _(unset)_ | `src/lib/db/encryption.ts` | **Legacy alias** for `STORAGE_ENCRYPTION_KEY`. Accepted as a fallback when the primary variable is absent. |
-| `OMNIROUTE_API_KEY_BASE64` | _(unset)_ | `src/lib/db/encryption.ts` | **Legacy alias** (Base64-encoded form) accepted as a fallback. Decoded automatically before use. |
+| Variable | Default | Source File | Deskripsi |
+| -------------------------------- | -------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
+| `DATA_DIR` | `~/.omniroute/` | `src/lib/db/core.ts` | Direktori utama untuk DB SQLite, cadangan, dan file data. Override untuk volume Docker atau path khusus. |
+| `STORAGE_ENCRYPTION_KEY` | _(empty = disabled)_ | `src/lib/db/encryption.ts` | Kunci AES untuk enkripsi penuh database SQLite saat disimpan. Buat dengan `openssl rand -hex 32`. |
+| `STORAGE_ENCRYPTION_KEY_VERSION` | `v1` | `scripts/bootstrap-env.mjs`, `electron/main.js` | Label versi untuk kunci enkripsi. Naikkan nilainya saat melakukan rotasi kunci agar mendukung dekripsi cadangan lama. |
+| `DISABLE_SQLITE_AUTO_BACKUP` | `false` | `src/lib/db/backup.ts` | Saat bernilai `true`, melewati pencadangan database otomatis yang berjalan sebelum migrasi pada setiap startup. |
+| `OMNIROUTE_CRYPT_KEY` | _(unset)_ | `src/lib/db/encryption.ts` | **Alias legacy** untuk `STORAGE_ENCRYPTION_KEY`. Diterima sebagai fallback ketika variabel utama tidak ada. |
+| `OMNIROUTE_API_KEY_BASE64` | _(unset)_ | `src/lib/db/encryption.ts` | **Alias legacy** (bentuk yang dikodekan Base64) diterima sebagai fallback. Didekode secara otomatis sebelum digunakan. |
-### Scenarios
+### Skenario
-| Scenario | Configuration |
-| --------------------- | -------------------------------------------------------------------------------- |
-| **Local development** | Leave all defaults. DB lives at `~/.omniroute/omniroute.db`. |
-| **Docker** | `DATA_DIR=/data` + mount a volume at `/data`. |
-| **Encrypted at rest** | Set `STORAGE_ENCRYPTION_KEY` + keep backups of the key! Losing it = losing data. |
-| **CI/Testing** | `DATA_DIR=/tmp/omniroute-test` — ephemeral, no encryption needed. |
+| Skenario | Konfigurasi |
+| -------------------------- | ------------------------------------------------------------------------------------------------ |
+| **Pengembangan lokal** | Biarkan semua nilai default. DB berada di `~/.omniroute/omniroute.db`. |
+| **Docker** | `DATA_DIR=/data` + mount volume di `/data`. |
+| **Terenkripsi saat simpan**| Set `STORAGE_ENCRYPTION_KEY` + simpan cadangan kuncinya! Kehilangan kunci = kehilangan data. |
+| **CI/Testing** | `DATA_DIR=/tmp/omniroute-test` — bersifat sementara, tidak perlu enkripsi. |
---
-## 3. Network & Ports
+## 3. Jaringan & Port
-| Variable | Default | Source File | Description |
-| --------------------- | ------------ | -------------------------- | -------------------------------------------------------------------------------------- |
-| `PORT` | `20128` | `src/lib/runtime/ports.ts` | Primary port for both Dashboard UI and API endpoints (single-port mode). |
-| `API_PORT` | _(unset)_ | `src/lib/runtime/ports.ts` | When set, serves the `/v1/*` proxy API on this separate port. |
-| `API_HOST` | `0.0.0.0` | `src/lib/runtime/ports.ts` | Bind address for the API port. |
-| `DASHBOARD_PORT` | _(unset)_ | `src/lib/runtime/ports.ts` | When set, serves the Dashboard UI on this separate port. |
-| `PROD_DASHBOARD_PORT` | `20130` | `docker-compose.prod.yml` | Host-side published port for the Dashboard in Docker production mode. |
-| `PROD_API_PORT` | `20131` | `docker-compose.prod.yml` | Host-side published port for the API in Docker production mode. |
-| `OMNIROUTE_PORT` | _(unset)_ | `src/lib/runtime/ports.ts` | Takes precedence over `PORT` when running inside Electron or other wrappers. |
-| `NODE_ENV` | `production` | Next.js core | Controls logging verbosity, caching, error detail exposure, and Next.js optimizations. |
+| Variable | Default | Source File | Deskripsi |
+| --------------------- | ------------ | -------------------------- | ----------------------------------------------------------------------------------------------------- |
+| `PORT` | `20128` | `src/lib/runtime/ports.ts` | Port utama untuk Dashboard UI dan endpoint API (mode port tunggal). |
+| `API_PORT` | _(unset)_ | `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` | _(unset)_ | `src/lib/runtime/ports.ts` | Jika diatur, menyajikan Dashboard UI pada port terpisah ini. |
+| `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` | _(unset)_ | `src/lib/runtime/ports.ts` | Mengambil prioritas di atas `PORT` saat berjalan di dalam Electron atau wrapper lainnya. |
+| `NODE_ENV` | `production` | Next.js core | Mengontrol verbositas logging, caching, ekspos detail error, dan optimasi Next.js. |
-### Port Modes
+### Mode Port
```
-┌─────────────────────────── Single Port (default) ──────────────────────────┐
+┌─────────────────────────── Port Tunggal (default) ─────────────────────────┐
│ PORT=20128 │
│ → Dashboard: http://localhost:20128 │
│ → API: http://localhost:20128/v1/chat/completions │
└─────────────────────────────────────────────────────────────────────────────┘
-┌─────────────────────────── Split Ports ─────────────────────────────────────┐
+┌─────────────────────────── Port Terpisah ───────────────────────────────────┐
│ 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. │
+│ Kasus penggunaan: Ekspos API ke LAN sambil membatasi Dashboard ke localhost.│
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────── Docker Production ──────────────────────────────┐
│ PROD_DASHBOARD_PORT=443 PROD_API_PORT=8443 │
-│ → Maps container ports to host ports in docker-compose.prod.yml. │
+│ → Memetakan port kontainer ke port host di docker-compose.prod.yml. │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
-## 4. Security & Authentication
+## 4. Keamanan & Autentikasi
-| Variable | Default | Source File | Description |
-| ----------------------------- | --------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------- |
-| `MACHINE_ID_SALT` | `endpoint-proxy-salt` | `src/lib/auth` | Salt combined with hardware identifiers for machine fingerprinting. Change per-deployment for isolation. |
-| `AUTH_COOKIE_SECURE` | `false` | `src/lib/auth` | Sets the `Secure` flag on session cookies. **Must be `true`** when running behind HTTPS. |
-| `REQUIRE_API_KEY` | `false` | API middleware | When `true`, all `/v1/*` proxy requests must include a valid API key. |
-| `ALLOW_API_KEY_REVEAL` | `false` | Dashboard providers page | Allows revealing full API key values in the Dashboard UI. Security risk on shared instances. |
-| `NO_LOG_API_KEY_IDS` | _(empty)_ | `src/lib/compliance/index.ts` | Comma-separated API key IDs that bypass request logging (GDPR compliance). |
-| `MAX_BODY_SIZE_BYTES` | `10485760` (10 MB) | `src/shared/middleware/bodySizeGuard.ts` | Maximum allowed request body size. Rejects payloads exceeding this limit. |
-| `CORS_ORIGIN` | `*` | Next.js middleware | CORS `Access-Control-Allow-Origin` value. Restrict for production. |
-| `OUTBOUND_SSRF_GUARD_ENABLED` | `true` | `src/shared/network/outboundUrlGuard.ts` | Block provider calls targeting private/loopback/link-local IP ranges. Disable only in isolated test envs. |
+| Variable | Default | Source File | Deskripsi |
+| ----------------------------- | --------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
+| `MACHINE_ID_SALT` | `endpoint-proxy-salt` | `src/lib/auth` | Salt yang digabungkan dengan pengenal perangkat keras untuk fingerprinting mesin. Ubah per-deployment untuk isolasi. |
+| `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` | API middleware | Saat bernilai `true`, semua permintaan proxy `/v1/*` harus menyertakan kunci API yang valid. |
+| `ALLOW_API_KEY_REVEAL` | `false` | Dashboard providers page | Memungkinkan pengungkapan nilai kunci API penuh di Dashboard UI. Berisiko pada instansi bersama. |
+| `NO_LOG_API_KEY_IDS` | _(empty)_ | `src/lib/compliance/index.ts` | ID kunci API yang dipisahkan koma yang melewati pencatatan permintaan (kepatuhan GDPR). |
+| `MAX_BODY_SIZE_BYTES` | `10485760` (10 MB) | `src/shared/middleware/bodySizeGuard.ts` | Ukuran body permintaan maksimum yang diizinkan. Menolak payload yang melebihi batas ini. |
+| `CORS_ORIGIN` | `*` | Next.js middleware | Nilai CORS `Access-Control-Allow-Origin`. Batasi untuk produksi. |
+| `OUTBOUND_SSRF_GUARD_ENABLED` | `true` | `src/shared/network/outboundUrlGuard.ts` | Memblokir panggilan provider yang menarget rentang IP privat/loopback/link-local. Nonaktifkan hanya di lingkungan pengujian terisolasi. |
-### Hardening Checklist
+### Daftar Periksa Penguatan Keamanan
```bash
-# Production security minimum:
-AUTH_COOKIE_SECURE=true # Requires HTTPS
-REQUIRE_API_KEY=true # Authenticate all proxy calls
-ALLOW_API_KEY_REVEAL=false # Never expose keys in UI
+# Minimum keamanan produksi:
+AUTH_COOKIE_SECURE=true # Memerlukan HTTPS
+REQUIRE_API_KEY=true # Autentikasi semua panggilan proxy
+ALLOW_API_KEY_REVEAL=false # Jangan pernah ekspos kunci di UI
CORS_ORIGIN=https://your.domain.com
-MAX_BODY_SIZE_BYTES=5242880 # 5 MB limit
+MAX_BODY_SIZE_BYTES=5242880 # Batas 5 MB
```
---
-## 5. Input Sanitization & PII Protection
+## 5. Sanitasi Input & Perlindungan PII
-OmniRoute provides a two-layer defense: request-side injection scanning and response-side PII stripping.
+OmniRoute menyediakan pertahanan dua lapis: pemindaian injeksi di sisi permintaan dan penghapusan PII di sisi respons.
-### Request-Side: Prompt Injection Guard
+### Sisi Permintaan: Penjaga Injeksi Prompt
-| Variable | Default | Source File | Description |
-| ------------------------- | --------- | ---------------------------------------- | ------------------------------------------------------------------------------------------- |
-| `INPUT_SANITIZER_ENABLED` | `false` | `src/middleware/promptInjectionGuard.ts` | Enable scanning of incoming messages for prompt injection patterns. |
-| `INPUT_SANITIZER_MODE` | `warn` | `src/middleware/promptInjectionGuard.ts` | `warn` = log only, `block` = reject request with 400, `redact` = strip suspicious patterns. |
-| `INJECTION_GUARD_MODE` | _(unset)_ | `src/middleware/promptInjectionGuard.ts` | Legacy alias for `INPUT_SANITIZER_MODE` — same behavior. |
-| `PII_REDACTION_ENABLED` | `false` | `src/middleware/promptInjectionGuard.ts` | Detect PII (emails, phones, SSNs) in incoming requests. |
+| Variable | Default | Source File | Deskripsi |
+| ------------------------- | --------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
+| `INPUT_SANITIZER_ENABLED` | `false` | `src/middleware/promptInjectionGuard.ts` | Aktifkan pemindaian pesan masuk untuk pola injeksi prompt. |
+| `INPUT_SANITIZER_MODE` | `warn` | `src/middleware/promptInjectionGuard.ts` | `warn` = hanya log, `block` = tolak permintaan dengan 400, `redact` = hapus pola mencurigakan. |
+| `INJECTION_GUARD_MODE` | _(unset)_ | `src/middleware/promptInjectionGuard.ts` | Alias legacy untuk `INPUT_SANITIZER_MODE` — perilaku sama. |
+| `PII_REDACTION_ENABLED` | `false` | `src/middleware/promptInjectionGuard.ts` | Deteksi PII (email, telepon, SSN) dalam permintaan masuk. |
-### Response-Side: PII Sanitizer
+### Sisi Respons: Sanitizer PII
-| Variable | Default | Source File | Description |
-| -------------------------------- | -------- | ------------------------- | ----------------------------------------------------------------------- |
-| `PII_RESPONSE_SANITIZATION` | `false` | `src/lib/piiSanitizer.ts` | Scan LLM responses for leaked PII before returning to client. |
-| `PII_RESPONSE_SANITIZATION_MODE` | `redact` | `src/lib/piiSanitizer.ts` | `redact` = mask PII, `warn` = log only, `block` = drop entire response. |
+| Variable | Default | Source File | Deskripsi |
+| -------------------------------- | -------- | ------------------------- | -------------------------------------------------------------------------------------------- |
+| `PII_RESPONSE_SANITIZATION` | `false` | `src/lib/piiSanitizer.ts` | Pindai respons LLM untuk PII yang bocor sebelum dikembalikan ke klien. |
+| `PII_RESPONSE_SANITIZATION_MODE` | `redact` | `src/lib/piiSanitizer.ts` | `redact` = sembunyikan PII, `warn` = hanya log, `block` = buang seluruh respons. |
-### Scenarios
+### Skenario
-| Scenario | Configuration |
-| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
-| **Enterprise compliance** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=block`, `PII_REDACTION_ENABLED=true`, `PII_RESPONSE_SANITIZATION=true` |
-| **Monitoring only** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=warn` — logs but never blocks |
-| **Personal use** | Leave all disabled — zero overhead |
+| Skenario | Konfigurasi |
+| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
+| **Kepatuhan enterprise** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=block`, `PII_REDACTION_ENABLED=true`, `PII_RESPONSE_SANITIZATION=true` |
+| **Hanya pemantauan** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=warn` — mencatat log namun tidak pernah memblokir |
+| **Penggunaan pribadi** | Biarkan semua dinonaktifkan — tanpa overhead |
---
-## 6. Tool & Routing Policies
+## 6. Kebijakan Alat & Routing
-| Variable | Default | Source File | Description |
-| ------------------ | ---------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
-| `TOOL_POLICY_MODE` | `disabled` | `src/lib/toolPolicy.ts` | Controls LLM tool/function-calling access. `allowlist` = only listed tools, `denylist` = all except listed, `disabled` = no restrictions. |
+| Variable | Default | Source File | Deskripsi |
+| ------------------ | ---------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `TOOL_POLICY_MODE` | `disabled` | `src/lib/toolPolicy.ts` | Mengontrol akses pemanggilan alat/fungsi LLM. `allowlist` = hanya alat yang terdaftar, `denylist` = semua kecuali yang terdaftar, `disabled` = tanpa batasan. |
---
-## 7. URLs & Cloud Sync
+## 7. URL & Sinkronisasi Cloud
-| Variable | Default | Source File | Description |
-| ----------------------- | ------------------------ | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
-| `BASE_URL` | `http://localhost:20128` | `src/lib/cloudSync.ts` | Server-side URL for internal sync jobs to call `/api/sync/cloud`. |
-| `CLOUD_URL` | _(empty)_ | `src/lib/cloudSync.ts` | Cloud relay endpoint URL (premium feature). |
-| `CLOUD_SYNC_TIMEOUT_MS` | `12000` | `src/lib/cloudSync.ts` | HTTP timeout for cloud sync requests. |
-| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | OAuth, Dashboard, sync | Public-facing URL for OAuth redirect_uri, Dashboard links. **Must match your public URL behind reverse proxy.** |
-| `NEXT_PUBLIC_CLOUD_URL` | _(empty)_ | Client-side | Client-side mirror of `CLOUD_URL`. |
-| `NEXT_PUBLIC_APP_URL` | _(unset)_ | `src/shared/services/cloudSyncScheduler.ts` | Legacy fallback for `NEXT_PUBLIC_BASE_URL`. |
+| Variable | Default | Source File | Deskripsi |
+| ----------------------- | ------------------------ | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
+| `BASE_URL` | `http://localhost:20128` | `src/lib/cloudSync.ts` | URL sisi server untuk pekerjaan sinkronisasi internal memanggil `/api/sync/cloud`. |
+| `CLOUD_URL` | _(empty)_ | `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. |
+| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | OAuth, Dashboard, sync | URL publik untuk redirect_uri OAuth, tautan Dashboard. **Harus cocok dengan URL publik Anda di balik reverse proxy.** |
+| `NEXT_PUBLIC_CLOUD_URL` | _(empty)_ | Client-side | Cerminan sisi klien dari `CLOUD_URL`. |
+| `NEXT_PUBLIC_APP_URL` | _(unset)_ | `src/shared/services/cloudSyncScheduler.ts` | Fallback legacy untuk `NEXT_PUBLIC_BASE_URL`. |
> [!IMPORTANT]
-> When deploying behind a reverse proxy (nginx, Caddy), `NEXT_PUBLIC_BASE_URL` **must** be set to your public URL (e.g., `https://omniroute.example.com`). Without this, OAuth callbacks will fail because the redirect_uri won't match.
+> Saat melakukan deployment di balik reverse proxy (nginx, Caddy), `NEXT_PUBLIC_BASE_URL` **harus** diatur ke URL publik Anda (misalnya, `https://omniroute.example.com`). Tanpa ini, callback OAuth akan gagal karena redirect_uri tidak akan cocok.
---
-## 8. Outbound Proxy
+## 8. Proxy Keluar
-Route upstream LLM provider calls through an HTTP or SOCKS5 proxy for egress control, geo-routing, or IP masking.
+Arahkan panggilan provider LLM upstream melalui proxy HTTP atau SOCKS5 untuk kontrol egress, geo-routing, atau penyembunyian IP.
-| Variable | Default | Source File | Description |
-| --------------------------------- | --------- | -------------------- | ----------------------------------------------------------------------------------- |
-| `ENABLE_SOCKS5_PROXY` | `true` | `open-sse/executors` | Enable SOCKS5 proxy agent for upstream calls. |
-| `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` | `true` | Client-side | Client-side awareness of SOCKS5 availability. |
-| `HTTP_PROXY` | _(unset)_ | Node.js standard | HTTP proxy for upstream calls. |
-| `HTTPS_PROXY` | _(unset)_ | Node.js standard | HTTPS proxy for upstream calls. |
-| `ALL_PROXY` | _(unset)_ | Node.js standard | Universal proxy (supports `socks5://`). |
-| `NO_PROXY` | _(unset)_ | Node.js standard | Comma-separated hostnames/IPs to bypass the proxy. |
-| `ENABLE_TLS_FINGERPRINT` | `false` | `open-sse/executors` | Spoof TLS fingerprint using wreq-js (mimics Chrome 124). Counters JA3/JA4 blocking. |
+| Variable | Default | Source File | Deskripsi |
+| --------------------------------- | --------- | -------------------- | ---------------------------------------------------------------------------------------------------------- |
+| `ENABLE_SOCKS5_PROXY` | `true` | `open-sse/executors` | Aktifkan agen proxy SOCKS5 untuk panggilan upstream. |
+| `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` | `true` | Client-side | Kesadaran sisi klien tentang ketersediaan SOCKS5. |
+| `HTTP_PROXY` | _(unset)_ | Node.js standard | Proxy HTTP untuk panggilan upstream. |
+| `HTTPS_PROXY` | _(unset)_ | Node.js standard | Proxy HTTPS untuk panggilan upstream. |
+| `ALL_PROXY` | _(unset)_ | Node.js standard | Proxy universal (mendukung `socks5://`). |
+| `NO_PROXY` | _(unset)_ | Node.js standard | Nama host/IP yang dipisahkan koma untuk melewati proxy. |
+| `ENABLE_TLS_FINGERPRINT` | `false` | `open-sse/executors` | Memalsukan fingerprint TLS menggunakan wreq-js (meniru Chrome 124). Mengatasi pemblokiran JA3/JA4. |
-### Scenarios
+### Skenario
-| Scenario | Configuration |
-| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
-| **SOCKS5 through SSH tunnel** | `ALL_PROXY=socks5://127.0.0.1:7890`, `ENABLE_SOCKS5_PROXY=true` |
-| **Corporate HTTP proxy** | `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` — requires `wreq-js` (included) |
+| 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 disertakan) |
---
-## 9. CLI Tool Integration
+## 9. Integrasi Alat CLI
-Controls how OmniRoute discovers and launches CLI sidecars (Claude Code, Codex, etc.).
+Mengontrol bagaimana OmniRoute menemukan dan menjalankan sidecar CLI (Claude Code, Codex, dll.).
-| Variable | Default | Source File | Description |
-| ------------------------- | ---------- | ----------------------------------- | -------------------------------------------------------------------------- |
-| `CLI_MODE` | `auto` | `src/shared/services/cliRuntime.ts` | `auto` = search system PATH; `manual` = use explicit paths only. |
-| `CLI_EXTRA_PATHS` | _(unset)_ | `src/shared/services/cliRuntime.ts` | Additional PATH entries for CLI binary discovery (colon-separated). |
-| `CLI_CONFIG_HOME` | _(unset)_ | `src/shared/services/cliRuntime.ts` | Override home directory for reading CLI configs (`~/.claude`, `~/.codex`). |
-| `CLI_ALLOW_CONFIG_WRITES` | `false` | `src/shared/services/cliRuntime.ts` | Allow OmniRoute to write CLI config files (token refresh, session data). |
-| `CLI_CLAUDE_BIN` | `claude` | `src/shared/services/cliRuntime.ts` | Custom path to Claude CLI binary. |
-| `CLI_CODEX_BIN` | `codex` | `src/shared/services/cliRuntime.ts` | Custom path to Codex CLI binary. |
-| `CLI_DROID_BIN` | `droid` | `src/shared/services/cliRuntime.ts` | Custom path to Droid CLI binary. |
-| `CLI_OPENCLAW_BIN` | `openclaw` | `src/shared/services/cliRuntime.ts` | Custom path to OpenClaw CLI binary. |
-| `CLI_CURSOR_BIN` | `agent` | `src/shared/services/cliRuntime.ts` | Custom path to Cursor agent binary. |
-| `CLI_CLINE_BIN` | `cline` | `src/shared/services/cliRuntime.ts` | Custom path to Cline CLI binary. |
-| `CLI_CONTINUE_BIN` | `cn` | `src/shared/services/cliRuntime.ts` | Custom path to Continue CLI binary. |
-| `CLI_QODER_BIN` | `qoder` | `src/shared/services/cliRuntime.ts` | Custom path to Qoder CLI binary. |
+| Variable | Default | Source File | Deskripsi |
+| ------------------------- | ---------- | ----------------------------------- | ------------------------------------------------------------------------------------------------ |
+| `CLI_MODE` | `auto` | `src/shared/services/cliRuntime.ts` | `auto` = cari di PATH sistem; `manual` = gunakan hanya path eksplisit. |
+| `CLI_EXTRA_PATHS` | _(unset)_ | `src/shared/services/cliRuntime.ts` | Entri PATH tambahan untuk penemuan biner CLI (dipisahkan titik dua). |
+| `CLI_CONFIG_HOME` | _(unset)_ | `src/shared/services/cliRuntime.ts` | Override direktori home untuk membaca konfigurasi CLI (`~/.claude`, `~/.codex`). |
+| `CLI_ALLOW_CONFIG_WRITES` | `false` | `src/shared/services/cliRuntime.ts` | Izinkan OmniRoute menulis file konfigurasi CLI (penyegaran token, data sesi). |
+| `CLI_CLAUDE_BIN` | `claude` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner CLI Claude. |
+| `CLI_CODEX_BIN` | `codex` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner CLI Codex. |
+| `CLI_DROID_BIN` | `droid` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner CLI Droid. |
+| `CLI_OPENCLAW_BIN` | `openclaw` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner CLI OpenClaw. |
+| `CLI_CURSOR_BIN` | `agent` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner agen Cursor. |
+| `CLI_CLINE_BIN` | `cline` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner CLI Cline. |
+| `CLI_CONTINUE_BIN` | `cn` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner CLI Continue. |
+| `CLI_QODER_BIN` | `qoder` | `src/shared/services/cliRuntime.ts` | Path kustom ke biner CLI Qoder. |
-### Docker Example
+### Contoh Docker
```bash
-# Mount host binaries into the container and tell OmniRoute where they are:
+# Mount biner host ke kontainer dan beri tahu OmniRoute lokasinya:
CLI_EXTRA_PATHS=/host-cli/bin
CLI_CONFIG_HOME=/root
CLI_ALLOW_CONFIG_WRITES=true
@@ -261,139 +261,139 @@ CLI_CLAUDE_BIN=/host-cli/bin/claude
---
-## 10. Internal Agent & MCP Integrations
+## 10. Agen Internal & Integrasi MCP
-| Variable | Default | Source File | Description |
-| --------------------------------------- | ----------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
-| `OMNIROUTE_BASE_URL` | auto-detect | `open-sse/mcp-server/server.ts` | Explicit URL for MCP/A2A tools to reach OmniRoute. Overrides localhost auto-detection. |
-| `OMNIROUTE_API_KEY` | _(unset)_ | MCP/A2A modules | API key for internal MCP tool and A2A skill calls. |
-| `OMNIROUTE_API_KEY_ID` | _(unset)_ | `open-sse/mcp-server/audit.ts` | Key ID for MCP audit log attribution. |
-| `ROUTER_API_KEY` | _(unset)_ | Legacy | Legacy alias for `OMNIROUTE_API_KEY`. |
-| `OMNIROUTE_MCP_ENFORCE_SCOPES` | `false` | `open-sse/mcp-server/server.ts` | Enforce scope-based access control on MCP tool calls. |
-| `OMNIROUTE_MCP_SCOPES` | _(all)_ | `open-sse/mcp-server/server.ts` | Comma-separated scopes: `admin`, `combos`, `health`, `models`, `routing`, `budget`, `metrics`, `pricing`, `memory`, `skills`. |
-| `MODEL_SYNC_INTERVAL_HOURS` | `24` | `src/shared/services/modelSyncScheduler.ts` | Model catalog sync interval in hours. |
-| `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | `src/server-init.ts` | Provider rate-limit and quota polling interval. |
-| `OMNIROUTE_DISABLE_BACKGROUND_SERVICES` | `false` | `src/instrumentation-node.ts` | Disable all background services (sync, pricing, model refresh). Useful for CI/test. |
-| `OMNIROUTE_BOOTSTRAPPED` | `false` | `src/app/(dashboard)/dashboard/page.tsx` | Set `true` by bootstrap script after initial setup. Controls setup wizard visibility. |
-| `OMNIROUTE_ALLOW_BODY_PROJECT_OVERRIDE` | `0` | `open-sse/executors/antigravity.ts` | Escape hatch: allow request body to override the Antigravity project field. |
+| Variable | Default | Source File | Deskripsi |
+| --------------------------------------- | ---------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
+| `OMNIROUTE_BASE_URL` | deteksi otomatis | `open-sse/mcp-server/server.ts` | URL eksplisit agar alat MCP/A2A dapat menjangkau OmniRoute. Menimpa deteksi otomatis localhost. |
+| `OMNIROUTE_API_KEY` | _(unset)_ | MCP/A2A modules | Kunci API untuk panggilan alat MCP internal dan skill A2A. |
+| `OMNIROUTE_API_KEY_ID` | _(unset)_ | `open-sse/mcp-server/audit.ts` | ID kunci untuk atribusi log audit MCP. |
+| `ROUTER_API_KEY` | _(unset)_ | Legacy | Alias legacy untuk `OMNIROUTE_API_KEY`. |
+| `OMNIROUTE_MCP_ENFORCE_SCOPES` | `false` | `open-sse/mcp-server/server.ts` | Terapkan kontrol akses berbasis scope pada panggilan alat MCP. |
+| `OMNIROUTE_MCP_SCOPES` | _(all)_ | `open-sse/mcp-server/server.ts` | Scope yang dipisahkan koma: `admin`, `combos`, `health`, `models`, `routing`, `budget`, `metrics`, `pricing`, `memory`, `skills`. |
+| `MODEL_SYNC_INTERVAL_HOURS` | `24` | `src/shared/services/modelSyncScheduler.ts` | Interval sinkronisasi katalog model dalam jam. |
+| `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | `src/server-init.ts` | Interval polling batas rate dan kuota provider. |
+| `OMNIROUTE_DISABLE_BACKGROUND_SERVICES` | `false` | `src/instrumentation-node.ts` | Nonaktifkan semua layanan latar belakang (sinkronisasi, harga, pembaruan model). Berguna untuk CI/pengujian. |
+| `OMNIROUTE_BOOTSTRAPPED` | `false` | `src/app/(dashboard)/dashboard/page.tsx` | Diatur ke `true` oleh skrip bootstrap setelah pengaturan awal. Mengontrol visibilitas wizard pengaturan. |
+| `OMNIROUTE_ALLOW_BODY_PROJECT_OVERRIDE` | `0` | `open-sse/executors/antigravity.ts` | Escape hatch: izinkan body permintaan untuk menimpa field proyek Antigravity. |
-### OAuth CLI Bridge (Internal)
+### Jembatan CLI OAuth (Internal)
-| Variable | Default | Source File | Description |
-| ------------------- | ----------- | ------------------------------- | ----------------------------------------- |
-| `OMNIROUTE_SERVER` | auto-detect | `src/lib/oauth/config/index.ts` | Server URL for CLI↔OmniRoute auth bridge. |
-| `OMNIROUTE_TOKEN` | _(unset)_ | `src/lib/oauth/config/index.ts` | Auth token for CLI bridge. |
-| `OMNIROUTE_USER_ID` | `cli` | `src/lib/oauth/config/index.ts` | User ID for CLI bridge sessions. |
-| `SERVER_URL` | _(unset)_ | `src/lib/oauth/config/index.ts` | Legacy alias for `OMNIROUTE_SERVER`. |
-| `CLI_TOKEN` | _(unset)_ | `src/lib/oauth/config/index.ts` | Legacy alias for `OMNIROUTE_TOKEN`. |
-| `CLI_USER_ID` | _(unset)_ | `src/lib/oauth/config/index.ts` | Legacy alias for `OMNIROUTE_USER_ID`. |
+| Variable | Default | Source File | Deskripsi |
+| ------------------- | ---------------- | ------------------------------- | ------------------------------------------------ |
+| `OMNIROUTE_SERVER` | deteksi otomatis | `src/lib/oauth/config/index.ts` | URL server untuk jembatan autentikasi CLI↔OmniRoute. |
+| `OMNIROUTE_TOKEN` | _(unset)_ | `src/lib/oauth/config/index.ts` | Token autentikasi untuk jembatan CLI. |
+| `OMNIROUTE_USER_ID` | `cli` | `src/lib/oauth/config/index.ts` | ID pengguna untuk sesi jembatan CLI. |
+| `SERVER_URL` | _(unset)_ | `src/lib/oauth/config/index.ts` | Alias legacy untuk `OMNIROUTE_SERVER`. |
+| `CLI_TOKEN` | _(unset)_ | `src/lib/oauth/config/index.ts` | Alias legacy untuk `OMNIROUTE_TOKEN`. |
+| `CLI_USER_ID` | _(unset)_ | `src/lib/oauth/config/index.ts` | Alias legacy untuk `OMNIROUTE_USER_ID`. |
---
-## 11. OAuth Provider Credentials
+## 11. Kredensial Provider OAuth
-Built-in credentials for **localhost development**. For remote deployments, register your own at each provider's developer console.
+Kredensial bawaan untuk **pengembangan localhost**. Untuk deployment jarak jauh, daftarkan milik Anda sendiri di konsol pengembang masing-masing provider.
-| Variable | Provider | Notes |
-| --------------------------------- | ----------------------- | --------------------------------------------------------------------------------- |
-| `CLAUDE_OAUTH_CLIENT_ID` | Claude Code (Anthropic) | Public client — no secret needed. |
-| `CLAUDE_CODE_REDIRECT_URI` | Claude Code | Override redirect URI. Default: `https://platform.claude.com/oauth/code/callback` |
-| `CODEX_OAUTH_CLIENT_ID` | Codex / OpenAI | Public client. |
-| `GEMINI_OAUTH_CLIENT_ID` | Gemini (Google) | Requires matching `_SECRET`. |
-| `GEMINI_OAUTH_CLIENT_SECRET` | Gemini (Google) | — |
-| `GEMINI_CLI_OAUTH_CLIENT_ID` | Gemini CLI | Usually same as Gemini. |
-| `GEMINI_CLI_OAUTH_CLIENT_SECRET` | Gemini CLI | — |
-| `QWEN_OAUTH_CLIENT_ID` | Qwen (Alibaba) | Public client. |
-| `KIMI_CODING_OAUTH_CLIENT_ID` | Kimi Coding (Moonshot) | Public client. |
-| `ANTIGRAVITY_OAUTH_CLIENT_ID` | Antigravity (Google) | Requires matching `_SECRET`. |
-| `ANTIGRAVITY_OAUTH_CLIENT_SECRET` | Antigravity (Google) | — |
-| `GITHUB_OAUTH_CLIENT_ID` | GitHub Copilot | Public client. |
-| `QODER_OAUTH_CLIENT_SECRET` | Qoder | — |
-| `QODER_OAUTH_AUTHORIZE_URL` | Qoder | Set to enable Qoder OAuth. |
-| `QODER_OAUTH_TOKEN_URL` | Qoder | — |
-| `QODER_OAUTH_USERINFO_URL` | Qoder | — |
-| `QODER_OAUTH_CLIENT_ID` | Qoder | — |
-| `QODER_PERSONAL_ACCESS_TOKEN` | Qoder | Direct API key fallback (bypasses OAuth). |
-| `QODER_CLI_WORKSPACE` | Qoder | Workspace ID for Qoder CLI. |
-| `OMNIROUTE_QODER_WORKSPACE` | Qoder | Alias for `QODER_CLI_WORKSPACE`. |
+| Variable | Provider | Catatan |
+| --------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------- |
+| `CLAUDE_OAUTH_CLIENT_ID` | Claude Code (Anthropic) | Klien publik — tidak perlu secret. |
+| `CLAUDE_CODE_REDIRECT_URI` | Claude Code | Timpa 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) | — |
+| `GEMINI_CLI_OAUTH_CLIENT_ID` | Gemini CLI | Biasanya sama dengan Gemini. |
+| `GEMINI_CLI_OAUTH_CLIENT_SECRET` | Gemini CLI | — |
+| `QWEN_OAUTH_CLIENT_ID` | Qwen (Alibaba) | Klien publik. |
+| `KIMI_CODING_OAUTH_CLIENT_ID` | Kimi Coding (Moonshot) | Klien publik. |
+| `ANTIGRAVITY_OAUTH_CLIENT_ID` | Antigravity (Google) | Memerlukan `_SECRET` yang sesuai. |
+| `ANTIGRAVITY_OAUTH_CLIENT_SECRET` | Antigravity (Google) | — |
+| `GITHUB_OAUTH_CLIENT_ID` | GitHub Copilot | Klien publik. |
+| `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 CLI Qoder. |
+| `OMNIROUTE_QODER_WORKSPACE` | Qoder | Alias untuk `QODER_CLI_WORKSPACE`. |
> [!WARNING]
-> **Google OAuth** (Antigravity, Gemini CLI) credentials **only work on localhost**. For remote servers:
+> Kredensial **Google OAuth** (Antigravity, Gemini CLI) **hanya berfungsi di localhost**. Untuk server jarak jauh:
>
-> 1. Go to [Google Cloud Console → Credentials](https://console.cloud.google.com/apis/credentials)
-> 2. Create an OAuth 2.0 Client ID (type: "Web application")
-> 3. Add your server URL as Authorized redirect URI
-> 4. Replace the credential values in `.env`.
+> 1. Buka [Google Cloud Console → Credentials](https://console.cloud.google.com/apis/credentials)
+> 2. Buat OAuth 2.0 Client ID (tipe: "Web application")
+> 3. Tambahkan URL server Anda sebagai Authorized redirect URI
+> 4. Ganti nilai kredensial di `.env`.
---
-## 12. Provider User-Agent Overrides
+## 12. Override User-Agent Provider
-Override the `User-Agent` header sent to each upstream provider. This is dynamically resolved at runtime by the executor base class:
+Menimpa header `User-Agent` yang dikirim ke setiap provider upstream. Ini diselesaikan secara dinamis saat runtime oleh kelas dasar executor:
```
process.env[`${PROVIDER_ID}_USER_AGENT`]
```
-> **Source:** `open-sse/executors/base.ts` → `buildHeaders()`
+> **Sumber:** `open-sse/executors/base.ts` → `buildHeaders()`
-| Variable | Default Value | When to Update |
-| ------------------------ | --------------------------------------------- | ------------------------------------------------------------- |
-| `CLAUDE_USER_AGENT` | `claude-cli/2.1.145 (external, cli)` | When Anthropic releases a new CLI version |
-| `CODEX_USER_AGENT` | `codex-cli/0.132.0 (Windows 10.0.26200; x64)` | When OpenAI updates the Codex CLI |
-| `CODEX_CLIENT_VERSION` | `0.131.0` | Override Codex client version independently of full UA string |
-| `GITHUB_USER_AGENT` | `GitHubCopilotChat/0.45.1` | When GitHub Copilot Chat updates |
-| `ANTIGRAVITY_USER_AGENT` | `antigravity/2.0.1 darwin/arm64` | When Antigravity IDE updates |
-| `KIRO_USER_AGENT` | `AWS-SDK-JS/3.0.0 kiro-ide/1.0.0` | When Kiro IDE updates |
-| `QODER_USER_AGENT` | `Qoder-Cli` | When Qoder CLI updates |
-| `QWEN_USER_AGENT` | `QwenCode/0.15.11 (linux; x64)` | When Qwen Code updates |
-| `CURSOR_USER_AGENT` | `connect-es/1.6.1` | When Cursor updates |
-| `GEMINI_CLI_USER_AGENT` | `google-api-nodejs-client/10.3.0` | When Google API client updates |
+| Variable | Nilai Default | Kapan Diperbarui |
+| ------------------------ | --------------------------------------------- | ---------------------------------------------------------------------- |
+| `CLAUDE_USER_AGENT` | `claude-cli/2.1.145 (external, cli)` | Saat Anthropic merilis versi CLI baru |
+| `CODEX_USER_AGENT` | `codex-cli/0.132.0 (Windows 10.0.26200; x64)` | Saat OpenAI memperbarui CLI Codex |
+| `CODEX_CLIENT_VERSION` | `0.131.0` | Override versi klien Codex secara independen dari string UA penuh |
+| `GITHUB_USER_AGENT` | `GitHubCopilotChat/0.45.1` | 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 |
+| `QODER_USER_AGENT` | `Qoder-Cli` | Saat CLI Qoder diperbarui |
+| `QWEN_USER_AGENT` | `QwenCode/0.15.11 (linux; x64)` | Saat Qwen Code diperbarui |
+| `CURSOR_USER_AGENT` | `connect-es/1.6.1` | Saat Cursor diperbarui |
+| `GEMINI_CLI_USER_AGENT` | `google-api-nodejs-client/10.3.0` | Saat klien API Google diperbarui |
> [!TIP]
-> You can add User-Agent overrides for **any** provider using the pattern `{PROVIDER_ID}_USER_AGENT`. The executor dynamically constructs the env var name.
+> Anda dapat menambahkan override User-Agent untuk provider **mana pun** menggunakan pola `{PROVIDER_ID}_USER_AGENT`. Executor secara dinamis membangun nama variabel lingkungan.
---
-## 13. CLI Fingerprint Compatibility
+## 13. Kompatibilitas Fingerprint CLI
-When enabled, OmniRoute reorders HTTP headers and JSON body fields to match the exact signature of official CLI tools. This reduces the risk of account flagging while preserving your proxy IP.
+Saat diaktifkan, OmniRoute mengatur ulang urutan header HTTP dan field body JSON agar cocok dengan tanda tangan persis dari alat CLI resmi. Hal ini mengurangi risiko pemblokiran akun sambil mempertahankan IP proxy Anda.
-**Source:** `open-sse/config/cliFingerprints.ts`, `open-sse/executors/base.ts`
+**Sumber:** `open-sse/config/cliFingerprints.ts`, `open-sse/executors/base.ts`
### Per-Provider
-| Variable | Effect |
-| -------------------------- | --------------------------------------- |
-| `CLI_COMPAT_CODEX=1` | Mimics Codex CLI request signature |
-| `CLI_COMPAT_CLAUDE=1` | Mimics Claude Code request signature |
-| `CLI_COMPAT_GITHUB=1` | Mimics GitHub Copilot request signature |
-| `CLI_COMPAT_ANTIGRAVITY=1` | Mimics Antigravity request signature |
-| `CLI_COMPAT_KIRO=1` | Mimics Kiro IDE request signature |
-| `CLI_COMPAT_CURSOR=1` | Mimics Cursor request signature |
-| `CLI_COMPAT_KIMI_CODING=1` | Mimics Kimi Coding request signature |
-| `CLI_COMPAT_KILOCODE=1` | Mimics Kilo Code request signature |
-| `CLI_COMPAT_CLINE=1` | Mimics Cline request signature |
-| `CLI_COMPAT_QWEN=1` | Mimics Qwen Code request signature |
+| Variable | Efek |
+| -------------------------- | ------------------------------------------------- |
+| `CLI_COMPAT_CODEX=1` | Meniru tanda tangan permintaan CLI Codex |
+| `CLI_COMPAT_CLAUDE=1` | Meniru tanda tangan permintaan Claude Code |
+| `CLI_COMPAT_GITHUB=1` | Meniru tanda tangan permintaan GitHub Copilot |
+| `CLI_COMPAT_ANTIGRAVITY=1` | Meniru tanda tangan permintaan Antigravity |
+| `CLI_COMPAT_KIRO=1` | Meniru tanda tangan permintaan Kiro IDE |
+| `CLI_COMPAT_CURSOR=1` | Meniru tanda tangan permintaan Cursor |
+| `CLI_COMPAT_KIMI_CODING=1` | Meniru tanda tangan permintaan Kimi Coding |
+| `CLI_COMPAT_KILOCODE=1` | Meniru tanda tangan permintaan Kilo Code |
+| `CLI_COMPAT_CLINE=1` | Meniru tanda tangan permintaan Cline |
+| `CLI_COMPAT_QWEN=1` | Meniru tanda tangan permintaan Qwen Code |
### Global
-| Variable | Effect |
-| ------------------ | --------------------------------------------------------------- |
-| `CLI_COMPAT_ALL=1` | Enable fingerprint compatibility for **all** providers at once. |
+| Variable | Efek |
+| ------------------ | ------------------------------------------------------------------------ |
+| `CLI_COMPAT_ALL=1` | Aktifkan kompatibilitas fingerprint untuk **semua** provider sekaligus. |
> [!NOTE]
-> This feature works alongside the User-Agent overrides (§12). The fingerprint system handles header ordering and body field ordering, while User-Agent overrides handle the specific UA string. Both can be enabled independently.
+> Fitur ini bekerja berdampingan dengan override User-Agent (§12). Sistem fingerprint menangani urutan header dan urutan field body, sementara override User-Agent menangani string UA tertentu. Keduanya dapat diaktifkan secara independen.
---
-## 14. API Key Providers
+## 14. Provider Kunci API
-API keys for providers that use direct authentication. **Preferred setup:** Dashboard → Providers → Add API Key.
+Kunci API untuk provider yang menggunakan autentikasi langsung. **Pengaturan yang disarankan:** Dashboard → Providers → Add API Key.
-Setting via environment variables is an alternative for Docker or headless deployments.
+Pengaturan melalui variabel lingkungan adalah alternatif untuk deployment Docker atau tanpa antarmuka grafis.
-Recognized pattern: `{PROVIDER_ID}_API_KEY`
+Pola yang dikenali: `{PROVIDER_ID}_API_KEY`
| Variable | Provider |
| -------------------- | ------------------- |
@@ -410,15 +410,15 @@ Recognized pattern: `{PROVIDER_ID}_API_KEY`
| `NEBIUS_API_KEY` | Nebius (embeddings) |
> [!TIP]
-> Keys set via the Dashboard are stored encrypted in SQLite and take precedence over environment variables.
+> Kunci yang diatur melalui Dashboard disimpan terenkripsi di SQLite dan mengambil prioritas di atas variabel lingkungan.
---
-## 15. Timeout Settings
+## 15. Pengaturan Batas Waktu
-All values are in **milliseconds**. Centralized resolution in `src/shared/utils/runtimeTimeouts.ts`.
+Semua nilai dalam satuan **milidetik**. Penyelesaian terpusat di `src/shared/utils/runtimeTimeouts.ts`.
-### Timeout Hierarchy
+### Hierarki Batas Waktu
```
REQUEST_TIMEOUT_MS (global override)
@@ -436,69 +436,69 @@ REQUEST_TIMEOUT_MS (global override)
└── API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS (default: 0 = disabled)
```
-| Variable | Default | Description |
-| ---------------------------------------- | -------------------- | ------------------------------------------------------------------------------------------- |
-| `REQUEST_TIMEOUT_MS` | _(unset)_ | Global shortcut — overrides both `FETCH_TIMEOUT_MS` and `STREAM_IDLE_TIMEOUT_MS` defaults. |
-| `FETCH_TIMEOUT_MS` | `600000` | Total HTTP request timeout for upstream provider calls. |
-| `STREAM_IDLE_TIMEOUT_MS` | `600000` | Max silence between SSE chunks before aborting. Extended-thinking models rarely pause >90s. |
-| `FETCH_HEADERS_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Time to receive response headers. |
-| `FETCH_BODY_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Time to receive the full response body. |
-| `FETCH_CONNECT_TIMEOUT_MS` | `30000` | TCP connection establishment timeout. |
-| `FETCH_KEEPALIVE_TIMEOUT_MS` | `4000` | Keep-alive socket idle timeout. |
-| `TLS_CLIENT_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | TLS fingerprint proxy (wreq-js) timeout. |
-| `API_BRIDGE_PROXY_TIMEOUT_MS` | `600000` | Proxy hop timeout for `/v1` bridge requests. |
-| `API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS` | `600000` | Overall server request timeout for the bridge. |
-| `API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS` | `60000` | Time to send response headers via the bridge. |
-| `API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS` | `5000` | Bridge keep-alive idle timeout. |
-| `API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS` | `0` | Raw socket timeout (0 = disabled). |
-| `SHUTDOWN_TIMEOUT_MS` | `30000` | Grace period on SIGTERM/SIGINT before force-exit. |
+| Variable | Default | Deskripsi |
+| ---------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------- |
+| `REQUEST_TIMEOUT_MS` | _(unset)_ | Pintasan global — menimpa default `FETCH_TIMEOUT_MS` maupun `STREAM_IDLE_TIMEOUT_MS`. |
+| `FETCH_TIMEOUT_MS` | `600000` | Total batas waktu permintaan HTTP untuk panggilan provider upstream. |
+| `STREAM_IDLE_TIMEOUT_MS` | `600000` | Keheningan maksimum antar chunk SSE sebelum dibatalkan. Model extended-thinking jarang berhenti lebih dari 90 detik. |
+| `FETCH_HEADERS_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Waktu untuk menerima header respons. |
+| `FETCH_BODY_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Waktu untuk menerima body respons penuh. |
+| `FETCH_CONNECT_TIMEOUT_MS` | `30000` | Batas waktu pembentukan koneksi TCP. |
+| `FETCH_KEEPALIVE_TIMEOUT_MS` | `4000` | Batas waktu idle socket keep-alive. |
+| `TLS_CLIENT_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Batas waktu proxy fingerprint TLS (wreq-js). |
+| `API_BRIDGE_PROXY_TIMEOUT_MS` | `600000` | Batas waktu hop proxy untuk permintaan jembatan `/v1`. |
+| `API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS` | `600000` | Batas waktu permintaan server keseluruhan untuk jembatan. |
+| `API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS` | `60000` | Waktu untuk mengirim header respons melalui jembatan. |
+| `API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS` | `5000` | Batas waktu idle keep-alive jembatan. |
+| `API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS` | `0` | Batas waktu socket mentah (0 = dinonaktifkan). |
+| `SHUTDOWN_TIMEOUT_MS` | `30000` | Periode grace pada SIGTERM/SIGINT sebelum force-exit. |
-### Scenarios
+### Skenario
-| Scenario | Configuration |
-| -------------------------------- | ------------------------------------------------------ |
-| **Long-running code generation** | `REQUEST_TIMEOUT_MS=900000` (15 min) |
-| **Fast-fail for production API** | `API_BRIDGE_PROXY_TIMEOUT_MS=10000` |
-| **Extended thinking models** | `STREAM_IDLE_TIMEOUT_MS=300000` (5 min between chunks) |
+| Skenario | Konfigurasi |
+| ----------------------------------------- | --------------------------------------------------------- |
+| **Pembuatan kode berjalan lama** | `REQUEST_TIMEOUT_MS=900000` (15 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
-The logging system writes to both stdout and rotated log files. All configuration is read by `src/lib/logEnv.ts`.
+Sistem logging menulis ke stdout dan file log yang dirotasi. Semua konfigurasi dibaca oleh `src/lib/logEnv.ts`.
-| Variable | Default | Description |
-| --------------------------- | -------------------------- | ---------------------------------------------------------------------------- |
-| `APP_LOG_LEVEL` | `info` | Minimum log level: `debug`, `info`, `warn`, `error`. |
-| `APP_LOG_FORMAT` | `text` | Output format: `text` (human-readable) or `json` (structured). |
-| `APP_LOG_TO_FILE` | `true` | Write logs to file alongside stdout. |
-| `APP_LOG_FILE_PATH` | `logs/application/app.log` | Log file path (relative to project root or `DATA_DIR`). |
-| `APP_LOG_MAX_FILE_SIZE` | `50M` | Max file size before rotation. Accepts: `50M`, `1G`, `512K`, or plain bytes. |
-| `APP_LOG_RETENTION_DAYS` | `7` | Days to keep rotated application log files. |
-| `APP_LOG_MAX_FILES` | `20` | Maximum rotated log file backups. |
-| `CALL_LOG_RETENTION_DAYS` | `7` | Days to keep request/call log entries in the database. |
-| `CALL_LOG_MAX_ENTRIES` | `10000` | Max call log entries in the in-memory buffer. |
-| `CALL_LOGS_TABLE_MAX_ROWS` | `100000` | Max rows in the `call_logs` SQLite table before pruning. |
-| `PROXY_LOGS_TABLE_MAX_ROWS` | `100000` | Max rows in the `proxy_logs` SQLite table before pruning. |
+| Variable | 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 bersama stdout. |
+| `APP_LOG_FILE_PATH` | `logs/application/app.log` | Path 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` | Hari untuk menyimpan file log aplikasi yang telah dirotasi. |
+| `APP_LOG_MAX_FILES` | `20` | Maksimum cadangan file log yang telah dirotasi. |
+| `CALL_LOG_RETENTION_DAYS` | `7` | Hari untuk menyimpan entri log permintaan/panggilan di database. |
+| `CALL_LOG_MAX_ENTRIES` | `10000` | Maksimum entri log panggilan dalam buffer in-memory. |
+| `CALL_LOGS_TABLE_MAX_ROWS` | `100000` | Maksimum baris dalam tabel SQLite `call_logs` sebelum dipangkas. |
+| `PROXY_LOGS_TABLE_MAX_ROWS` | `100000` | Maksimum baris dalam tabel SQLite `proxy_logs` sebelum dipangkas. |
---
-## 17. Memory Optimization
+## 17. Optimasi Memori
-| Variable | Default | Description |
-| -------------------------- | ------------------------------- | ---------------------------------------------------------------------- |
-| `OMNIROUTE_MEMORY_MB` | `512` | Runtime V8 heap limit. Docker standalone and `omniroute serve` use it to set `--max-old-space-size`. |
-| `PROMPT_CACHE_MAX_SIZE` | `50` | Max cached system prompt entries. |
-| `PROMPT_CACHE_MAX_BYTES` | `2097152` (2 MB) | Max total prompt cache size. |
-| `PROMPT_CACHE_TTL_MS` | `300000` (5 min) | Prompt cache entry TTL. |
-| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Max cached temperature=0 responses. |
-| `SEMANTIC_CACHE_MAX_BYTES` | `4194304` (4 MB) | Max total semantic cache size. |
-| `SEMANTIC_CACHE_TTL_MS` | `1800000` (30 min) | Semantic cache entry TTL. |
-| `STREAM_HISTORY_MAX` | `50` | Max recent stream events in the Dashboard live view buffer. |
-| `CONTEXT_LENGTH_DEFAULT` | `128000` | Global fallback max context length for models without explicit config. |
-| `USAGE_TOKEN_BUFFER` | `100` | Extra token headroom reserved when tracking usage quotas. |
+| Variable | Default | Deskripsi |
+| -------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------ |
+| `OMNIROUTE_MEMORY_MB` | `512` | Batas heap V8 saat runtime. Docker standalone dan `omniroute serve` menggunakannya untuk mengatur `--max-old-space-size`. |
+| `PROMPT_CACHE_MAX_SIZE` | `50` | Maksimum entri prompt sistem yang dicache. |
+| `PROMPT_CACHE_MAX_BYTES` | `2097152` (2 MB) | Ukuran total cache prompt maksimum. |
+| `PROMPT_CACHE_TTL_MS` | `300000` (5 menit) | TTL entri cache prompt. |
+| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Maksimum respons temperature=0 yang dicache. |
+| `SEMANTIC_CACHE_MAX_BYTES` | `4194304` (4 MB) | Ukuran total cache semantik maksimum. |
+| `SEMANTIC_CACHE_TTL_MS` | `1800000` (30 menit) | TTL entri cache semantik. |
+| `STREAM_HISTORY_MAX` | `50` | Maksimum event stream terbaru dalam buffer tampilan langsung Dashboard. |
+| `CONTEXT_LENGTH_DEFAULT` | `128000` | Panjang konteks maksimum fallback global untuk model tanpa konfigurasi eksplisit. |
+| `USAGE_TOKEN_BUFFER` | `100` | Cadangan token ekstra yang disisihkan saat melacak kuota penggunaan. |
-### Low-RAM Docker Example
+### Contoh Docker RAM Rendah
```bash
OMNIROUTE_MEMORY_MB=128
@@ -511,85 +511,85 @@ STREAM_HISTORY_MAX=10
---
-## 18. Pricing Sync
+## 18. Sinkronisasi Harga
-Automatic model pricing data synchronization from external sources.
+Sinkronisasi data harga model secara otomatis dari sumber eksternal.
-| Variable | Default | Source File | Description |
-| ----------------------- | ------------- | ------------------------ | ----------------------------- |
-| `PRICING_SYNC_ENABLED` | `false` | `src/lib/pricingSync.ts` | Opt-in periodic pricing sync. |
-| `PRICING_SYNC_INTERVAL` | `86400` (24h) | `src/lib/pricingSync.ts` | Sync interval in seconds. |
-| `PRICING_SYNC_SOURCES` | `litellm` | `src/lib/pricingSync.ts` | Comma-separated data sources. |
+| Variable | Default | Source File | Deskripsi |
+| ----------------------- | ------------- | ------------------------ | ------------------------------------------------- |
+| `PRICING_SYNC_ENABLED` | `false` | `src/lib/pricingSync.ts` | Opt-in sinkronisasi harga berkala. |
+| `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 koma. |
---
-## 19. Model Sync (Dev)
+## 19. Sinkronisasi Model (Dev)
-| Variable | Default | Source File | Description |
-| -------------------------- | ------------- | -------------------------- | -------------------------------------------------------- |
-| `MODELS_DEV_SYNC_INTERVAL` | `86400` (24h) | `src/lib/modelsDevSync.ts` | Development-time model catalog sync interval in seconds. |
+| Variable | Default | Source File | Deskripsi |
+| -------------------------- | ------------- | -------------------------- | ----------------------------------------------------------------------- |
+| `MODELS_DEV_SYNC_INTERVAL` | `86400` (24h) | `src/lib/modelsDevSync.ts` | Interval sinkronisasi katalog model saat pengembangan dalam detik. |
---
-## 20. Provider-Specific Settings
+## 20. Pengaturan Spesifik Provider
-| Variable | Default | Source File | Description |
-| ----------------------------------------- | ------------------ | ------------------------------------------ | ------------------------------------------------------------------------------------- |
-| `OPENROUTER_CATALOG_TTL_MS` | `86400000` (24h) | `src/lib/catalog/openrouterCatalog.ts` | OpenRouter model catalog cache TTL. |
-| `NANOBANANA_POLL_TIMEOUT_MS` | `120000` | `open-sse/handlers/imageGeneration.ts` | Max wait for NanoBanana image generation jobs. |
-| `NANOBANANA_POLL_INTERVAL_MS` | `2500` | `open-sse/handlers/imageGeneration.ts` | NanoBanana job polling frequency. |
-| `CLOUDFLARE_ACCOUNT_ID` | _(unset)_ | `open-sse/executors/cloudflare-ai.ts` | Account ID for Cloudflare Workers AI. |
-| `CLOUDFLARED_BIN` | auto-detect | `src/lib/cloudflaredTunnel.ts` | Custom path to `cloudflared` binary. |
-| `SEARCH_CACHE_TTL_MS` | `300000` (5 min) | `open-sse/services/searchCache.ts` | TTL for search API (Perplexity, Brave, etc.) response caching. |
-| `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` | `false` | `src/app/api/providers/route.ts` | Allow multiple simultaneous connections per OpenAI-compatible provider. |
-| `ENABLE_CC_COMPATIBLE_PROVIDER` | `false` | `src/shared/utils/featureFlags.ts` | Enable experimental Claude Code compatible provider endpoint. |
-| `CLIPROXYAPI_HOST` | `127.0.0.1` | `open-sse/executors/cliproxyapi.ts` | CLIProxyAPI bridge host (legacy integration). |
-| `CLIPROXYAPI_PORT` | `5544` | `open-sse/executors/cliproxyapi.ts` | CLIProxyAPI bridge port. |
-| `CLIPROXYAPI_CONFIG_DIR` | `~/.cli-proxy-api` | `src/lib/versionManager/processManager.ts` | CLIProxyAPI config directory. |
-| `LOCAL_HOSTNAMES` | _(empty)_ | `open-sse/config/providerRegistry.ts` | Comma-separated additional hostnames treated as "local" (Docker service names, etc.). |
+| Variable | Default | Source File | Deskripsi |
+| ----------------------------------------- | --------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
+| `OPENROUTER_CATALOG_TTL_MS` | `86400000` (24h) | `src/lib/catalog/openrouterCatalog.ts` | TTL cache katalog model OpenRouter. |
+| `NANOBANANA_POLL_TIMEOUT_MS` | `120000` | `open-sse/handlers/imageGeneration.ts` | Waktu tunggu maksimum untuk pekerjaan pembuatan gambar NanoBanana. |
+| `NANOBANANA_POLL_INTERVAL_MS` | `2500` | `open-sse/handlers/imageGeneration.ts` | Frekuensi polling pekerjaan NanoBanana. |
+| `CLOUDFLARE_ACCOUNT_ID` | _(unset)_ | `open-sse/executors/cloudflare-ai.ts` | ID akun untuk Cloudflare Workers AI. |
+| `CLOUDFLARED_BIN` | deteksi otomatis | `src/lib/cloudflaredTunnel.ts` | Path kustom ke biner `cloudflared`. |
+| `SEARCH_CACHE_TTL_MS` | `300000` (5 menit) | `open-sse/services/searchCache.ts` | TTL untuk caching respons API pencarian (Perplexity, Brave, dll.). |
+| `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` | `false` | `src/app/api/providers/route.ts` | Izinkan beberapa koneksi simultan per provider yang kompatibel dengan OpenAI. |
+| `ENABLE_CC_COMPATIBLE_PROVIDER` | `false` | `src/shared/utils/featureFlags.ts` | Aktifkan endpoint provider eksperimental yang kompatibel dengan Claude Code. |
+| `CLIPROXYAPI_HOST` | `127.0.0.1` | `open-sse/executors/cliproxyapi.ts` | Host jembatan CLIProxyAPI (integrasi legacy). |
+| `CLIPROXYAPI_PORT` | `5544` | `open-sse/executors/cliproxyapi.ts` | Port jembatan CLIProxyAPI. |
+| `CLIPROXYAPI_CONFIG_DIR` | `~/.cli-proxy-api` | `src/lib/versionManager/processManager.ts` | Direktori konfigurasi CLIProxyAPI. |
+| `LOCAL_HOSTNAMES` | _(empty)_ | `open-sse/config/providerRegistry.ts` | Nama host tambahan yang dipisahkan koma yang diperlakukan sebagai "lokal" (nama layanan Docker, dll.). |
---
-## 21. Proxy Health
+## 21. Kesehatan Proxy
-| Variable | Default | Source File | Description |
-| ---------------------------- | ---------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
-| `PROXY_FAST_FAIL_TIMEOUT_MS` | `2000` | `src/lib/proxyHealth.ts` | Fast-fail health check timeout. |
-| `PROXY_HEALTH_CACHE_TTL_MS` | `30000` | `src/lib/proxyHealth.ts` | Health check result cache TTL. |
-| `RATE_LIMIT_MAX_WAIT_MS` | `120000` (2 min) | `open-sse/services/rateLimitManager.ts` | Max time to wait on a 429 before failing the request. |
-| `REQUEST_RETRY` | `2` | `src/sse/services/cooldownAwareRetry.ts` | Number of automatic retries on model-scoped cooldown responses before returning error to client. |
-| `MAX_RETRY_INTERVAL_SEC` | `30` | `src/sse/services/cooldownAwareRetry.ts` | Max backoff interval (seconds) between cooldown retries. Capped by this value regardless of upstream `Retry-After`. |
+| Variable | Default | Source File | Deskripsi |
+| ---------------------------- | ------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
+| `PROXY_FAST_FAIL_TIMEOUT_MS` | `2000` | `src/lib/proxyHealth.ts` | Batas waktu pemeriksaan kesehatan fast-fail. |
+| `PROXY_HEALTH_CACHE_TTL_MS` | `30000` | `src/lib/proxyHealth.ts` | TTL cache hasil pemeriksaan kesehatan. |
+| `RATE_LIMIT_MAX_WAIT_MS` | `120000` (2 menit) | `open-sse/services/rateLimitManager.ts` | Waktu tunggu maksimum pada respons 429 sebelum menggagalkan permintaan. |
+| `REQUEST_RETRY` | `2` | `src/sse/services/cooldownAwareRetry.ts` | Jumlah percobaan ulang otomatis pada respons cooldown berbasis model sebelum mengembalikan error ke klien. |
+| `MAX_RETRY_INTERVAL_SEC` | `30` | `src/sse/services/cooldownAwareRetry.ts` | Interval backoff maksimum (detik) antar percobaan ulang cooldown. Dibatasi oleh nilai ini terlepas dari `Retry-After` upstream. |
---
## 22. Debugging
> [!CAUTION]
-> These variables produce **verbose output** and may leak sensitive data. **Never enable in production.**
+> Variabel-variabel ini menghasilkan **output yang sangat detail** dan dapat membocorkan data sensitif. **Jangan pernah aktifkan di lingkungan produksi.**
-| Variable | Default | Source File | Description |
-| -------------------------------- | --------- | ----------------------------------------- | -------------------------------------------------------------- |
-| `CURSOR_PROTOBUF_DEBUG` | _(unset)_ | `open-sse/utils/cursorProtobuf.ts` | Set `1` to dump Cursor protobuf decode/encode details. |
-| `CURSOR_STREAM_DEBUG` | _(unset)_ | `open-sse/executors/cursor.ts` | Set `1` to dump raw Cursor SSE stream data. |
-| `DEBUG_RESPONSES_SSE_TO_JSON` | _(unset)_ | `open-sse/handlers/responseTranslator.ts` | Set `true` to log Responses API SSE→JSON translation details. |
-| `NEXT_PUBLIC_OMNIROUTE_E2E_MODE` | _(unset)_ | E2E test harness | Set `true` to enable E2E test mode (relaxed auth, test hooks). |
+| Variable | Default | Source File | Deskripsi |
+| -------------------------------- | --------- | ----------------------------------------- | ---------------------------------------------------------------------------------- |
+| `CURSOR_PROTOBUF_DEBUG` | _(unset)_ | `open-sse/utils/cursorProtobuf.ts` | Atur ke `1` untuk membuang detail decode/encode protobuf Cursor. |
+| `CURSOR_STREAM_DEBUG` | _(unset)_ | `open-sse/executors/cursor.ts` | Atur ke `1` untuk membuang data stream SSE Cursor mentah. |
+| `DEBUG_RESPONSES_SSE_TO_JSON` | _(unset)_ | `open-sse/handlers/responseTranslator.ts` | Atur ke `true` untuk mencatat log detail translasi SSE→JSON Responses API. |
+| `NEXT_PUBLIC_OMNIROUTE_E2E_MODE` | _(unset)_ | E2E test harness | Atur ke `true` untuk mengaktifkan mode pengujian E2E (autentikasi santai, test hook). |
---
-## 23. GitHub Integration
+## 23. Integrasi GitHub
-Allow users to report issues directly from the Dashboard.
+Memungkinkan pengguna melaporkan masalah langsung dari Dashboard.
-| Variable | Default | Source File | Description |
-| --------------------- | --------- | --------------------------------------- | ------------------------------------------------------- |
-| `GITHUB_ISSUES_REPO` | _(unset)_ | `src/app/api/v1/issues/report/route.ts` | Repository in `owner/repo` format. |
-| `GITHUB_ISSUES_TOKEN` | _(unset)_ | `src/app/api/v1/issues/report/route.ts` | GitHub Personal Access Token with `issues:write` scope. |
+| Variable | Default | Source File | Deskripsi |
+| --------------------- | --------- | --------------------------------------- | -------------------------------------------------------------------- |
+| `GITHUB_ISSUES_REPO` | _(unset)_ | `src/app/api/v1/issues/report/route.ts` | Repositori dalam format `owner/repo`. |
+| `GITHUB_ISSUES_TOKEN` | _(unset)_ | `src/app/api/v1/issues/report/route.ts` | GitHub Personal Access Token dengan scope `issues:write`. |
---
-## Deployment Scenarios
+## Skenario Deployment
-### Minimal Local Development
+### Pengembangan Lokal Minimal
```bash
JWT_SECRET=$(openssl rand -base64 48)
@@ -629,7 +629,7 @@ OMNIROUTE_DISABLE_BACKGROUND_SERVICES=true
APP_LOG_TO_FILE=false
```
-### VPS with Reverse Proxy (nginx + Cloudflare)
+### VPS dengan Reverse Proxy (nginx + Cloudflare)
```bash
JWT_SECRET=
@@ -647,23 +647,23 @@ CLI_COMPAT_ALL=1
---
-## Audit: Removed / Dead Variables
+## Audit: Variabel yang Dihapus / Tidak Aktif
-The following variables appeared in previous versions of `.env.example` but have **no runtime references** in the current codebase. They have been removed:
+Variabel-variabel berikut muncul di versi sebelumnya dari `.env.example` tetapi **tidak memiliki referensi runtime** di basis kode saat ini. Variabel-variabel ini telah dihapus:
-| Variable | Reason |
-| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
-| `STORAGE_DRIVER=sqlite` | Never read by any source file. SQLite is the only supported driver — no selection needed. |
-| `INSTANCE_NAME=omniroute` | Present in old docs/env templates but unused at runtime. May return in a future multi-instance feature. |
-| `SQLITE_MAX_SIZE_MB=2048` | Not referenced in source code. Database size is not artificially limited. |
-| `SQLITE_CLEAN_LEGACY_FILES=true` | Not referenced in source code. Legacy cleanup was likely removed. |
-| `CLI_ROO_BIN` | Not registered in `src/shared/services/cliRuntime.ts`. |
-| `CLI_KIMI_CODING_BIN` | Not registered in `src/shared/services/cliRuntime.ts` (Kimi Coding uses OAuth, not a CLI binary). |
-| `IFLOW_OAUTH_CLIENT_ID` / `IFLOW_OAUTH_CLIENT_SECRET` | Not referenced anywhere in source code. |
+| Variable | Alasan |
+| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
+| `STORAGE_DRIVER=sqlite` | Tidak pernah dibaca oleh file sumber mana pun. SQLite adalah satu-satunya driver yang didukung — tidak diperlukan pemilihan. |
+| `INSTANCE_NAME=omniroute` | Ada di template docs/env lama tetapi tidak digunakan saat runtime. Mungkin kembali dalam fitur multi-instansi di masa depan. |
+| `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 legacy 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. |
-### Default Value Corrections
+### Koreksi Nilai Default
-| Variable | Old `.env.example` Value | Actual Code Default | Fixed |
-| ------------------------- | ------------------------ | ------------------- | ------------------------------------------------------ |
-| `APP_LOG_RETENTION_DAYS` | `90` | `7` | ✅ Removed misleading value; documented `7` as default |
-| `CALL_LOG_RETENTION_DAYS` | `90` | `7` | ✅ Removed misleading value; documented `7` as default |
+| Variable | Nilai `.env.example` Lama | Default Kode Aktual | Diperbaiki |
+| ------------------------- | ------------------------- | ------------------- | ------------------------------------------------------------------ |
+| `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 |
diff --git a/docs/i18n/id/docs/routing/AUTO-COMBO.md b/docs/i18n/id/docs/routing/AUTO-COMBO.md
index 3e4e5d2501..19e3292fcf 100644
--- a/docs/i18n/id/docs/routing/AUTO-COMBO.md
+++ b/docs/i18n/id/docs/routing/AUTO-COMBO.md
@@ -4,40 +4,40 @@
---
-> Self-managing model chains with adaptive scoring
+> Rantai model yang mengelola diri sendiri dengan penilaian adaptif
-## How It Works
+## Cara Kerjanya
-The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**:
+Auto-Combo Engine secara dinamis memilih penyedia/model terbaik untuk setiap permintaan menggunakan **fungsi penilaian 6 faktor**:
-| Factor | Weight | Description |
-| :--------- | :----- | :---------------------------------------------- |
-| Quota | 0.20 | Remaining capacity [0..1] |
-| Health | 0.25 | Circuit breaker: CLOSED=1.0, HALF=0.5, OPEN=0.0 |
-| CostInv | 0.20 | Inverse cost (cheaper = higher score) |
-| LatencyInv | 0.15 | Inverse p95 latency (faster = higher) |
-| TaskFit | 0.10 | Model × task type fitness score |
-| Stability | 0.10 | Low variance in latency/errors |
+| Faktor | Bobot | Deskripsi |
+| :--------- | :---- | :----------------------------------------------------- |
+| Quota | 0.20 | Kapasitas tersisa [0..1] |
+| Health | 0.25 | Circuit breaker: CLOSED=1.0, HALF=0.5, OPEN=0.0 |
+| CostInv | 0.20 | Biaya invers (lebih murah = skor lebih tinggi) |
+| LatencyInv | 0.15 | Latensi p95 invers (lebih cepat = lebih tinggi) |
+| TaskFit | 0.10 | Skor kesesuaian model × tipe tugas |
+| Stability | 0.10 | Variansi rendah dalam latensi/kesalahan |
-## Mode Packs
+## Paket Mode
-| Pack | Focus | Key Weight |
+| Paket | Fokus | Bobot Utama |
| :---------------------- | :----------- | :--------------- |
-| 🚀 **Ship Fast** | Speed | latencyInv: 0.35 |
-| 💰 **Cost Saver** | Economy | costInv: 0.40 |
-| 🎯 **Quality First** | Best model | taskFit: 0.40 |
-| 📡 **Offline Friendly** | Availability | quota: 0.40 |
+| 🚀 **Ship Fast** | Kecepatan | latencyInv: 0.35 |
+| 💰 **Cost Saver** | Ekonomi | costInv: 0.40 |
+| 🎯 **Quality First** | Model terbaik | taskFit: 0.40 |
+| 📡 **Offline Friendly** | Ketersediaan | quota: 0.40 |
-## Self-Healing
+## Pemulihan Mandiri
-- **Temporary exclusion**: Score < 0.2 → excluded for 5 min (progressive backoff, max 30 min)
-- **Circuit breaker awareness**: OPEN → auto-excluded; HALF_OPEN → probe requests
-- **Incident mode**: >50% OPEN → disable exploration, maximize stability
-- **Cooldown recovery**: After exclusion, first request is a "probe" with reduced timeout
+- **Pengecualian sementara**: Skor < 0.2 → dikecualikan selama 5 menit (backoff progresif, maks 30 menit)
+- **Kesadaran circuit breaker**: OPEN → dikecualikan otomatis; HALF_OPEN → permintaan probe
+- **Mode insiden**: >50% OPEN → nonaktifkan eksplorasi, maksimalkan stabilitas
+- **Pemulihan cooldown**: Setelah pengecualian, permintaan pertama adalah "probe" dengan timeout yang dikurangi
-## Bandit Exploration
+## Eksplorasi Bandit
-5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode.
+5% permintaan (dapat dikonfigurasi) diarahkan ke penyedia acak untuk eksplorasi. Dinonaktifkan dalam mode insiden.
## API
@@ -51,17 +51,17 @@ curl -X POST http://localhost:20128/api/combos/auto \
curl http://localhost:20128/api/combos/auto
```
-## Task Fitness
+## Kesesuaian Tugas
-30+ models scored across 6 task types (`coding`, `review`, `planning`, `analysis`, `debugging`, `documentation`). Supports wildcard patterns (e.g., `*-coder` → high coding score).
+30+ model dinilai di 6 tipe tugas (`coding`, `review`, `planning`, `analysis`, `debugging`, `documentation`). Mendukung pola wildcard (mis., `*-coder` → skor coding tinggi).
-## Files
+## Berkas
-| File | Purpose |
-| :------------------------------------------- | :------------------------------------ |
-| `open-sse/services/autoCombo/scoring.ts` | Scoring function & pool normalization |
-| `open-sse/services/autoCombo/taskFitness.ts` | Model × task fitness lookup |
-| `open-sse/services/autoCombo/engine.ts` | Selection logic, bandit, budget cap |
-| `open-sse/services/autoCombo/selfHealing.ts` | Exclusion, probes, incident mode |
-| `open-sse/services/autoCombo/modePacks.ts` | 4 weight profiles |
-| `src/app/api/combos/auto/route.ts` | REST API |
+| Berkas | Tujuan |
+| :------------------------------------------- | :-------------------------------------------- |
+| `open-sse/services/autoCombo/scoring.ts` | Fungsi penilaian & normalisasi pool |
+| `open-sse/services/autoCombo/taskFitness.ts` | Pencarian kesesuaian model × tugas |
+| `open-sse/services/autoCombo/engine.ts` | Logika pemilihan, bandit, batas anggaran |
+| `open-sse/services/autoCombo/selfHealing.ts` | Pengecualian, probe, mode insiden |
+| `open-sse/services/autoCombo/modePacks.ts` | 4 profil bobot |
+| `src/app/api/combos/auto/route.ts` | REST API |
diff --git a/docs/i18n/id/llm.txt b/docs/i18n/id/llm.txt
index 3a74d8c6cb..b756bd33bf 100644
--- a/docs/i18n/id/llm.txt
+++ b/docs/i18n/id/llm.txt
@@ -4,191 +4,191 @@
---
-> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 177 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (37 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex-cloud, devin, jules), Guardrails framework, and an Electron desktop app.
+> OmniRoute adalah AI Gateway gratis dan open-source yang berfungsi sebagai proxy API universal untuk LLM multi-penyedia. OmniRoute menyediakan routing cerdas, fallback otomatis, load balancing, dan translasi format untuk 177 penyedia AI — semuanya melalui satu endpoint yang kompatibel dengan OpenAI. Dilengkapi dengan MCP Server bawaan (37 alat), protokol A2A v0.3, sistem Memory/Skills, Cloud Agents (codex-cloud, devin, jules), kerangka Guardrails, dan aplikasi desktop Electron.
-## Overview
+## Ikhtisar
-OmniRoute solves the problem of managing multiple AI provider subscriptions, quotas, and rate limits. It sits between your AI-powered tools (IDE agents, CLI tools) and AI providers, routing requests intelligently through a 4-tier fallback system: Subscription → API Key → Cheap → Free.
+OmniRoute menyelesaikan masalah pengelolaan beberapa langganan penyedia AI, kuota, dan batas kecepatan. OmniRoute berada di antara alat bertenaga AI Anda (agen IDE, alat CLI) dan penyedia AI, merutekan permintaan secara cerdas melalui sistem fallback 4-tingkat: Subscription → API Key → Cheap → Free.
-**Key value:** One endpoint (`http://localhost:20128/v1`), unlimited models, zero downtime, minimal cost.
+**Nilai utama:** Satu endpoint (`http://localhost:20128/v1`), model tak terbatas, tanpa downtime, biaya minimal.
-**Current version:** 3.8.8
+**Versi saat ini:** 3.8.8
-## Tech Stack
+## Tumpukan Teknologi
- **Runtime:** Node.js `>=20.20.2 <21 || >=22.22.2 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
-- **Framework:** Next.js 16 (App Router) with TypeScript 5.9
-- **Database:** SQLite via better-sqlite3 (local, zero-config, 55 migrations)
-- **State management:** Zustand (client), SQLite (server persistence)
-- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
-- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
-- **Schemas:** Zod v4 for all API / MCP input validation
-- **Background jobs:** Custom token health check scheduler, 24h model auto-sync
-- **Streaming:** Server-Sent Events (SSE) for real-time proxy responses
-- **Proxy engine:** Custom pipeline with format translation, circuit breaker, rate limiting, auto-combo engine
-- **i18n:** next-intl with 40+ languages
-- **Desktop:** Electron (cross-platform: Windows, macOS, Linux)
-- **Package:** Published on npm (`omniroute`) and Docker Hub (`diegosouzapw/omniroute`)
+- **Framework:** Next.js 16 (App Router) dengan TypeScript 5.9
+- **Database:** SQLite via better-sqlite3 (lokal, tanpa konfigurasi, 55 migrasi)
+- **Manajemen state:** Zustand (klien), SQLite (persistensi server)
+- **UI:** React 19, Tailwind CSS 4, Recharts untuk analitik, @lobehub/icons untuk 130+ ikon SVG penyedia
+- **Auth:** OAuth 2.0 (PKCE) untuk penyedia, bcrypt untuk autentikasi pengguna lokal
+- **Skema:** Zod v4 untuk semua validasi input API / MCP
+- **Pekerjaan latar belakang:** Penjadwal pemeriksaan kesehatan token kustom, auto-sync model 24 jam
+- **Streaming:** Server-Sent Events (SSE) untuk respons proxy secara real-time
+- **Mesin proxy:** Pipeline kustom dengan translasi format, circuit breaker, pembatasan kecepatan, mesin auto-combo
+- **i18n:** next-intl dengan 40+ bahasa
+- **Desktop:** Electron (lintas platform: Windows, macOS, Linux)
+- **Paket:** Diterbitkan di npm (`omniroute`) dan Docker Hub (`diegosouzapw/omniroute`)
-## Project Structure
+## Struktur Proyek
```
/
-├── src/ # Main application source
-│ ├── app/ # Next.js App Router pages and API routes
-│ │ ├── (dashboard)/ # Dashboard UI pages
+├── src/ # Sumber utama aplikasi
+│ ├── app/ # Halaman Next.js App Router dan rute API
+│ │ ├── (dashboard)/ # Halaman UI dashboard
│ │ │ └── dashboard/
-│ │ │ ├── agents/ # ACP Agents dashboard (CLI agent detection + custom agents)
-│ │ │ ├── analytics/ # Usage analytics and charts
-│ │ │ ├── api-manager/ # API key management
-│ │ │ ├── audit/ # Audit logs
-│ │ │ ├── auto-combo/ # Auto-combo engine dashboard
-│ │ │ ├── cache/ # Cache dashboard (semantic cache stats)
-│ │ │ ├── cli-tools/ # CLI tool configuration (Claude Code, Codex, Gemini CLI, etc.)
-│ │ │ ├── combos/ # Model combo management (14 strategies + 4 templates)
-│ │ │ ├── costs/ # Cost tracking per provider/model
-│ │ │ ├── endpoint/ # Unified: Endpoint Proxy, MCP, A2A, API Endpoints tabs
-│ │ │ ├── health/ # System health (uptime, circuit breakers, latency)
-│ │ │ ├── limits/ # Rate limits dashboard
-│ │ │ ├── logs/ # Request, Proxy, Audit, Console logs (tabbed)
-│ │ │ ├── media/ # Image/video/music generation + transcription
-│ │ │ ├── memory/ # Memory system dashboard
-│ │ │ ├── onboarding/ # Onboarding wizard
-│ │ │ ├── playground/ # Model playground (Monaco editor, streaming)
-│ │ │ ├── providers/ # Provider management (OAuth + API key + free)
-│ │ │ ├── search-tools/ # Search tools configuration
-│ │ │ ├── settings/ # Settings tabs (General, Appearance, Security, Routing, Resilience, Advanced)
-│ │ │ ├── skills/ # Skills system dashboard
-│ │ │ ├── translator/ # Format translator + debug tools
-│ │ │ └── usage/ # Usage history
-│ │ ├── api/ # REST API endpoints (51 route directories)
-│ │ │ ├── v1/ # OpenAI-compatible API (chat, completions, models, embeddings,
+│ │ │ ├── agents/ # Dashboard ACP Agents (deteksi agen CLI + agen kustom)
+│ │ │ ├── analytics/ # Analitik penggunaan dan grafik
+│ │ │ ├── api-manager/ # Manajemen kunci API
+│ │ │ ├── audit/ # Log audit
+│ │ │ ├── auto-combo/ # Dashboard mesin auto-combo
+│ │ │ ├── cache/ # Dashboard cache (statistik cache semantik)
+│ │ │ ├── cli-tools/ # Konfigurasi alat CLI (Claude Code, Codex, Gemini CLI, dll.)
+│ │ │ ├── combos/ # Manajemen combo model (14 strategi + 4 template)
+│ │ │ ├── costs/ # Pelacakan biaya per penyedia/model
+│ │ │ ├── endpoint/ # Terpadu: tab Endpoint Proxy, MCP, A2A, API Endpoints
+│ │ │ ├── health/ # Kesehatan sistem (uptime, circuit breaker, latensi)
+│ │ │ ├── limits/ # Dashboard batas kecepatan
+│ │ │ ├── logs/ # Log Permintaan, Proxy, Audit, Konsol (bertab)
+│ │ │ ├── media/ # Pembuatan gambar/video/musik + transkripsi
+│ │ │ ├── memory/ # Dashboard sistem memori
+│ │ │ ├── onboarding/ # Wizard orientasi
+│ │ │ ├── playground/ # Taman bermain model (editor Monaco, streaming)
+│ │ │ ├── providers/ # Manajemen penyedia (OAuth + kunci API + gratis)
+│ │ │ ├── search-tools/ # Konfigurasi alat pencarian
+│ │ │ ├── settings/ # Tab pengaturan (Umum, Tampilan, Keamanan, Routing, Resilience, Lanjutan)
+│ │ │ ├── skills/ # Dashboard sistem skills
+│ │ │ ├── translator/ # Penerjemah format + alat debug
+│ │ │ └── usage/ # Riwayat penggunaan
+│ │ ├── api/ # Endpoint REST API (51 direktori rute)
+│ │ │ ├── v1/ # API kompatibel OpenAI (chat, completions, models, embeddings,
│ │ │ │ # images, audio, videos, music, moderations, rerank, search,
│ │ │ │ # responses, messages, registered-keys, quotas, accounts)
-│ │ │ ├── v1beta/ # Gemini-compatible API
-│ │ │ ├── a2a/ # A2A agent management API
-│ │ │ ├── acp/ # ACP agent management API
-│ │ │ ├── oauth/ # OAuth flows per provider
-│ │ │ ├── providers/ # Provider CRUD and batch testing
-│ │ │ ├── models/ # Dashboard model listing and aliases
-│ │ │ ├── combos/ # Combo CRUD (multi-model fallback chains)
-│ │ │ ├── memory/ # Memory system API
-│ │ │ ├── skills/ # Skills system API
-│ │ │ ├── evals/ # Eval runner API
-│ │ │ ├── mcp/ # MCP HTTP transport API
-│ │ │ ├── search/ # Search provider API
-│ │ │ ├── webhooks/ # Webhook management
-│ │ │ ├── tunnels/ # Cloudflare tunnel management
-│ │ │ └── ... # Other endpoints (usage, logs, health, settings, pricing, etc.)
-│ │ ├── landing/ # Landing page
-│ │ ├── login/ # Login page
-│ │ ├── forgot-password/ # Password recovery
-│ │ ├── status/ # Status page
-│ │ └── docs/ # In-app documentation
-│ ├── domain/ # Domain types and policy engine
-│ │ ├── policyEngine.ts # Central policy engine
-│ │ ├── comboResolver.ts # Combo resolution logic
-│ │ ├── costRules.ts # Cost calculation rules
-│ │ ├── degradation.ts # Graceful degradation
-│ │ ├── fallbackPolicy.ts # Fallback behavior
-│ │ ├── lockoutPolicy.ts # Account lockout logic
-│ │ ├── modelAvailability.ts # Model availability checks
-│ │ ├── providerExpiration.ts # Provider credential expiration
-│ │ ├── quotaCache.ts # Quota caching layer
-│ │ ├── configAudit.ts # Configuration auditing
-│ │ └── responses.ts # Domain response types
-│ ├── i18n/ # Internationalization
-│ │ └── messages/ # 40+ language JSON files
-│ ├── lib/ # Core libraries
-│ │ ├── a2a/ # Agent-to-Agent v0.3 protocol server
-│ │ │ ├── skills/ # A2A skills (quotaManagement, smartRouting)
-│ │ │ ├── taskManager.ts # Task lifecycle with TTL cleanup
-│ │ │ └── streaming.ts # SSE streaming for A2A
-│ │ ├── acp/ # Agent Communication Protocol registry and manager
-│ │ ├── compliance/ # Compliance policy engine
-│ │ ├── db/ # SQLite database layer (21 modules + migrations)
-│ │ │ ├── core.ts # Database initialization, connection, schema
-│ │ │ ├── providers.ts # Provider connection CRUD
-│ │ │ ├── models.ts # Model catalog management
-│ │ │ ├── combos.ts # Combo configuration
-│ │ │ ├── apiKeys.ts # API key management
-│ │ │ ├── settings.ts # Settings persistence
-│ │ │ ├── backup.ts # Database backup/restore
-│ │ │ ├── proxies.ts # Proxy registry
-│ │ │ ├── prompts.ts # Prompt templates
-│ │ │ ├── webhooks.ts # Webhook subscriptions
-│ │ │ ├── detailedLogs.ts # Detailed request logging
-│ │ │ ├── domainState.ts # Domain state persistence
-│ │ │ ├── registeredKeys.ts # Registered API keys with quotas
-│ │ │ ├── quotaSnapshots.ts # Quota snapshot history
-│ │ │ ├── modelComboMappings.ts # Model-to-combo mappings
-│ │ │ ├── cliToolState.ts # CLI tool state tracking
-│ │ │ ├── encryption.ts # Data encryption
-│ │ │ ├── readCache.ts # Read-through cache layer
-│ │ │ ├── secrets.ts # Secrets management
-│ │ │ ├── stateReset.ts # State reset utilities
-│ │ │ ├── migrationRunner.ts # Schema migration runner
-│ │ │ └── migrations/ # 16 SQL migration files
-│ │ ├── evals/ # Eval runner and scheduler
-│ │ ├── memory/ # Persistent conversational memory
-│ │ │ ├── extraction.ts # Memory extraction from conversations
-│ │ │ ├── injection.ts # Memory injection into context
-│ │ │ ├── retrieval.ts # Memory retrieval/search
-│ │ │ ├── store.ts # Memory persistence layer
-│ │ │ └── summarization.ts # Memory summarization
-│ │ ├── oauth/ # OAuth providers, services, and utilities
-│ │ │ ├── constants/ # Default OAuth credentials (overridable via env)
-│ │ │ ├── providers/ # Provider-specific OAuth configs
-│ │ │ ├── services/ # Provider-specific token exchange logic
-│ │ │ └── utils/ # PKCE, callback server, token helpers
-│ │ ├── plugins/ # Plugin system
-│ │ ├── skills/ # Extensible skill framework
-│ │ │ ├── registry.ts # Skill registration
-│ │ │ ├── executor.ts # Skill execution engine
-│ │ │ ├── sandbox.ts # Skill sandbox environment
-│ │ │ ├── builtin/ # Built-in skills
-│ │ │ ├── interception.ts # Skill request interception
-│ │ │ └── injection.ts # Skill context injection
-│ │ ├── usage/ # Usage tracking system
-│ │ │ ├── callLogs.ts # Call log persistence
-│ │ │ ├── costCalculator.ts # Cost calculation engine
-│ │ │ └── usageHistory.ts # Usage history queries
-│ │ ├── cloudSync.ts # Cloud sync via Cloudflare Workers
-│ │ ├── cloudflaredTunnel.ts # Cloudflare tunnel management
-│ │ ├── pricingSync.ts # LiteLLM pricing data sync
-│ │ ├── semanticCache.ts # Semantic caching layer
-│ │ ├── tokenHealthCheck.ts # Background OAuth token refresh scheduler
-│ │ ├── webhookDispatcher.ts # Webhook event dispatcher
-│ │ └── localDb.ts # Unified re-export layer for all DB modules
-│ ├── middleware/ # Request middleware
-│ │ └── promptInjectionGuard.ts # Prompt injection detection
-│ ├── mitm/ # MITM proxy capability
-│ │ ├── cert/ # Certificate management
-│ │ ├── dns/ # DNS handling
-│ │ ├── targets/ # Target routing
-│ │ └── manager.ts # MITM proxy manager
-│ ├── shared/ # Shared utilities, components, and constants
-│ │ ├── components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.)
-│ │ ├── constants/ # Provider definitions (160+), model lists, pricing, routing strategies, MCP scopes
-│ │ ├── contracts/ # Shared API contracts
+│ │ │ ├── v1beta/ # API kompatibel Gemini
+│ │ │ ├── a2a/ # API manajemen agen A2A
+│ │ │ ├── acp/ # API manajemen agen ACP
+│ │ │ ├── oauth/ # Alur OAuth per penyedia
+│ │ │ ├── providers/ # CRUD penyedia dan pengujian batch
+│ │ │ ├── models/ # Daftar model dashboard dan alias
+│ │ │ ├── combos/ # CRUD combo (rantai fallback multi-model)
+│ │ │ ├── memory/ # API sistem memori
+│ │ │ ├── skills/ # API sistem skills
+│ │ │ ├── evals/ # API runner eval
+│ │ │ ├── mcp/ # API transport HTTP MCP
+│ │ │ ├── search/ # API penyedia pencarian
+│ │ │ ├── webhooks/ # Manajemen webhook
+│ │ │ ├── tunnels/ # Manajemen tunnel Cloudflare
+│ │ │ └── ... # Endpoint lainnya (usage, logs, health, settings, pricing, dll.)
+│ │ ├── landing/ # Halaman landing
+│ │ ├── login/ # Halaman login
+│ │ ├── forgot-password/ # Pemulihan kata sandi
+│ │ ├── status/ # Halaman status
+│ │ └── docs/ # Dokumentasi dalam aplikasi
+│ ├── domain/ # Tipe domain dan mesin kebijakan
+│ │ ├── policyEngine.ts # Mesin kebijakan pusat
+│ │ ├── comboResolver.ts # Logika resolusi combo
+│ │ ├── costRules.ts # Aturan perhitungan biaya
+│ │ ├── degradation.ts # Degradasi bertahap
+│ │ ├── fallbackPolicy.ts # Perilaku fallback
+│ │ ├── lockoutPolicy.ts # Logika penguncian akun
+│ │ ├── modelAvailability.ts # Pemeriksaan ketersediaan model
+│ │ ├── providerExpiration.ts # Kedaluwarsa kredensial penyedia
+│ │ ├── quotaCache.ts # Lapisan caching kuota
+│ │ ├── configAudit.ts # Audit konfigurasi
+│ │ └── responses.ts # Tipe respons domain
+│ ├── i18n/ # Internasionalisasi
+│ │ └── messages/ # 40+ file JSON bahasa
+│ ├── lib/ # Pustaka inti
+│ │ ├── a2a/ # Server protokol Agent-to-Agent v0.3
+│ │ │ ├── skills/ # Skills A2A (quotaManagement, smartRouting)
+│ │ │ ├── taskManager.ts # Siklus hidup tugas dengan pembersihan TTL
+│ │ │ └── streaming.ts # SSE streaming untuk A2A
+│ │ ├── acp/ # Registri dan manajer Agent Communication Protocol
+│ │ ├── compliance/ # Mesin kebijakan kepatuhan
+│ │ ├── db/ # Lapisan database SQLite (21 modul + migrasi)
+│ │ │ ├── core.ts # Inisialisasi database, koneksi, skema
+│ │ │ ├── providers.ts # CRUD koneksi penyedia
+│ │ │ ├── models.ts # Manajemen katalog model
+│ │ │ ├── combos.ts # Konfigurasi combo
+│ │ │ ├── apiKeys.ts # Manajemen kunci API
+│ │ │ ├── settings.ts # Persistensi pengaturan
+│ │ │ ├── backup.ts # Backup/restore database
+│ │ │ ├── proxies.ts # Registri proxy
+│ │ │ ├── prompts.ts # Template prompt
+│ │ │ ├── webhooks.ts # Langganan webhook
+│ │ │ ├── detailedLogs.ts # Pencatatan permintaan terperinci
+│ │ │ ├── domainState.ts # Persistensi state domain
+│ │ │ ├── registeredKeys.ts # Kunci API terdaftar dengan kuota
+│ │ │ ├── quotaSnapshots.ts # Riwayat snapshot kuota
+│ │ │ ├── modelComboMappings.ts # Pemetaan model-ke-combo
+│ │ │ ├── cliToolState.ts # Pelacakan state alat CLI
+│ │ │ ├── encryption.ts # Enkripsi data
+│ │ │ ├── readCache.ts # Lapisan cache read-through
+│ │ │ ├── secrets.ts # Manajemen rahasia
+│ │ │ ├── stateReset.ts # Utilitas reset state
+│ │ │ ├── migrationRunner.ts # Runner migrasi skema
+│ │ │ └── migrations/ # 16 file migrasi SQL
+│ │ ├── evals/ # Runner dan penjadwal eval
+│ │ ├── memory/ # Memori percakapan persisten
+│ │ │ ├── extraction.ts # Ekstraksi memori dari percakapan
+│ │ │ ├── injection.ts # Injeksi memori ke dalam konteks
+│ │ │ ├── retrieval.ts # Pengambilan/pencarian memori
+│ │ │ ├── store.ts # Lapisan persistensi memori
+│ │ │ └── summarization.ts # Ringkasan memori
+│ │ ├── oauth/ # Penyedia, layanan, dan utilitas OAuth
+│ │ │ ├── constants/ # Kredensial OAuth default (dapat diganti via env)
+│ │ │ ├── providers/ # Konfigurasi OAuth spesifik penyedia
+│ │ │ ├── services/ # Logika pertukaran token spesifik penyedia
+│ │ │ └── utils/ # PKCE, server callback, pembantu token
+│ │ ├── plugins/ # Sistem plugin
+│ │ ├── skills/ # Kerangka skill yang dapat dikembangkan
+│ │ │ ├── registry.ts # Registrasi skill
+│ │ │ ├── executor.ts # Mesin eksekusi skill
+│ │ │ ├── sandbox.ts # Lingkungan sandbox skill
+│ │ │ ├── builtin/ # Skill bawaan
+│ │ │ ├── interception.ts # Intersepsi permintaan skill
+│ │ │ └── injection.ts # Injeksi konteks skill
+│ │ ├── usage/ # Sistem pelacakan penggunaan
+│ │ │ ├── callLogs.ts # Persistensi log panggilan
+│ │ │ ├── costCalculator.ts # Mesin perhitungan biaya
+│ │ │ └── usageHistory.ts # Kueri riwayat penggunaan
+│ │ ├── cloudSync.ts # Sinkronisasi cloud via Cloudflare Workers
+│ │ ├── cloudflaredTunnel.ts # Manajemen tunnel Cloudflare
+│ │ ├── pricingSync.ts # Sinkronisasi data harga LiteLLM
+│ │ ├── semanticCache.ts # Lapisan caching semantik
+│ │ ├── tokenHealthCheck.ts # Penjadwal refresh token OAuth latar belakang
+│ │ ├── webhookDispatcher.ts # Dispatcher event webhook
+│ │ └── localDb.ts # Lapisan re-ekspor terpadu untuk semua modul DB
+│ ├── middleware/ # Middleware permintaan
+│ │ └── promptInjectionGuard.ts # Deteksi injeksi prompt
+│ ├── mitm/ # Kemampuan proxy MITM
+│ │ ├── cert/ # Manajemen sertifikat
+│ │ ├── dns/ # Penanganan DNS
+│ │ ├── targets/ # Routing target
+│ │ └── manager.ts # Manajer proxy MITM
+│ ├── shared/ # Utilitas, komponen, dan konstanta bersama
+│ │ ├── components/ # Komponen UI yang dapat digunakan ulang (Card, Badge, Button, Modal, Sidebar, ProviderIcon, dll.)
+│ │ ├── constants/ # Definisi penyedia (160+), daftar model, harga, strategi routing, cakupan MCP
+│ │ ├── contracts/ # Kontrak API bersama
│ │ ├── hooks/ # React hooks
-│ │ ├── middleware/ # Shared middleware utilities
-│ │ ├── schemas/ # Shared Zod schemas
-│ │ ├── services/ # Shared services
-│ │ ├── types/ # Shared TypeScript types
-│ │ ├── validation/ # Zod schemas (settings, providers, routes)
-│ │ └── utils/ # Helpers (auth, CORS, error codes, machine ID)
-│ ├── sse/ # SSE proxy pipeline
-│ │ ├── services/ # Auth resolution, format translation, response handling
-│ │ └── middleware/ # Rate limiting, circuit breaker, caching, idempotency
-│ ├── store/ # Zustand client-side stores (theme, providers, etc.)
-│ └── types/ # TypeScript type definitions
-├── open-sse/ # Standalone SSE server (npm workspace)
-│ ├── config/ # Model registries (providerRegistry, embedding, image, audio, video,
-│ │ # music, rerank, moderation, search, CLI fingerprints, Ollama models)
-│ ├── executors/ # Provider-specific request executors (31 executors)
-│ │ ├── base.ts # Base executor with shared logic
-│ │ ├── default.ts # Default OpenAI-compatible executor
+│ │ ├── middleware/ # Utilitas middleware bersama
+│ │ ├── schemas/ # Skema Zod bersama
+│ │ ├── services/ # Layanan bersama
+│ │ ├── types/ # Tipe TypeScript bersama
+│ │ ├── validation/ # Skema Zod (settings, providers, routes)
+│ │ └── utils/ # Pembantu (auth, CORS, kode error, ID mesin)
+│ ├── sse/ # Pipeline proxy SSE
+│ │ ├── services/ # Resolusi auth, translasi format, penanganan respons
+│ │ └── middleware/ # Pembatasan kecepatan, circuit breaker, caching, idempotency
+│ ├── store/ # Store sisi klien Zustand (tema, penyedia, dll.)
+│ └── types/ # Definisi tipe TypeScript
+├── open-sse/ # Server SSE mandiri (workspace npm)
+│ ├── config/ # Registri model (providerRegistry, embedding, image, audio, video,
+│ │ # music, rerank, moderation, search, sidik jari CLI, model Ollama)
+│ ├── executors/ # Executor permintaan spesifik penyedia (31 executor)
+│ │ ├── base.ts # Executor dasar dengan logika bersama
+│ │ ├── default.ts # Executor kompatibel OpenAI default
│ │ ├── cursor.ts # Cursor IDE (protobuf + checksum)
│ │ ├── codex.ts # OpenAI Codex CLI
│ │ ├── antigravity.ts # Antigravity IDE
@@ -201,315 +201,315 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── opencode.ts # OpenCode Zen/Go
│ │ ├── pollinations.ts # Pollinations AI
│ │ └── puter.ts # Puter AI
-│ ├── handlers/ # Request handlers per API type (11 handlers)
-│ │ ├── chatCore.ts # Main chat completions handler
-│ │ ├── responsesHandler.ts # OpenAI Responses API handler
-│ │ ├── embeddings.ts # Embedding generation
-│ │ ├── imageGeneration.ts # Image generation (GPT-Image, FLUX, SD, etc.)
-│ │ ├── videoGeneration.ts # Video generation
-│ │ ├── musicGeneration.ts # Music generation
+│ ├── handlers/ # Handler permintaan per tipe API (11 handler)
+│ │ ├── chatCore.ts # Handler utama chat completions
+│ │ ├── responsesHandler.ts # Handler OpenAI Responses API
+│ │ ├── embeddings.ts # Pembuatan embedding
+│ │ ├── imageGeneration.ts # Pembuatan gambar (GPT-Image, FLUX, SD, dll.)
+│ │ ├── videoGeneration.ts # Pembuatan video
+│ │ ├── musicGeneration.ts # Pembuatan musik
│ │ ├── audioSpeech.ts # Text-to-speech
│ │ ├── audioTranscription.ts # Speech-to-text (Whisper, Deepgram, AssemblyAI)
-│ │ ├── moderations.ts # Content moderation
-│ │ ├── rerank.ts # Reranking API
-│ │ └── search.ts # Web search API
-│ ├── mcp-server/ # Built-in MCP server (29 tools, 3 transports: stdio/SSE/streamable-HTTP)
-│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
-│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
-│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
-│ │ ├── scopeEnforcement.ts # Scope-based access control (10 scopes)
-│ │ ├── audit.ts # Tool call audit logging
-│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
-│ │ └── httpTransport.ts # HTTP transport handler
-│ ├── services/ # 36+ service modules
-│ │ ├── combo.ts # Core routing engine
-│ │ ├── usage.ts # Usage tracking
-│ │ ├── tokenRefresh.ts # OAuth token refresh
-│ │ ├── rateLimitManager.ts # Rate limit management
-│ │ ├── accountFallback.ts # Multi-account fallback
-│ │ ├── sessionManager.ts # Session management
-│ │ ├── wildcardRouter.ts # Wildcard model routing
-│ │ ├── autoCombo/ # Auto-combo engine (6-factor scoring, bandit exploration)
-│ │ ├── intentClassifier.ts # Request intent classification
-│ │ ├── taskAwareRouter.ts # Task-aware routing
-│ │ ├── thinkingBudget.ts # Thinking budget management
-│ │ ├── contextManager.ts # Context window management
-│ │ ├── modelDeprecation.ts # Model deprecation handling
-│ │ ├── modelFamilyFallback.ts # Intra-family model fallback
-│ │ ├── emergencyFallback.ts # Emergency fallback
-│ │ ├── workflowFSM.ts # Workflow state machine
-│ │ ├── backgroundTaskDetector.ts # Background task detection
-│ │ ├── ipFilter.ts # IP-based access control
-│ │ ├── signatureCache.ts # CLI signature caching
-│ │ ├── volumeDetector.ts # Request volume detection
-│ │ ├── contextHandoff.ts # Context relay handoff generation and injection
-│ │ ├── codexQuotaFetcher.ts # Codex quota fetching for context-relay
-│ │ └── ... # Additional services (14 more modules)
-│ ├── transformer/ # Responses API transformer
+│ │ ├── moderations.ts # Moderasi konten
+│ │ ├── rerank.ts # API reranking
+│ │ └── search.ts # API pencarian web
+│ ├── mcp-server/ # Server MCP bawaan (29 alat, 3 transport: stdio/SSE/streamable-HTTP)
+│ │ ├── server.ts # Inti server MCP (registrasi alat, penegakan cakupan)
+│ │ ├── tools/ # Implementasi alat (advancedTools, memoryTools, skillTools)
+│ │ ├── schemas/ # Skema input Zod (tools, audit, a2a)
+│ │ ├── scopeEnforcement.ts # Kontrol akses berbasis cakupan (10 cakupan)
+│ │ ├── audit.ts # Pencatatan audit pemanggilan alat
+│ │ ├── runtimeHeartbeat.ts # Heartbeat runtime MCP
+│ │ └── httpTransport.ts # Handler transport HTTP
+│ ├── services/ # 36+ modul layanan
+│ │ ├── combo.ts # Mesin routing inti
+│ │ ├── usage.ts # Pelacakan penggunaan
+│ │ ├── tokenRefresh.ts # Refresh token OAuth
+│ │ ├── rateLimitManager.ts # Manajemen batas kecepatan
+│ │ ├── accountFallback.ts # Fallback multi-akun
+│ │ ├── sessionManager.ts # Manajemen sesi
+│ │ ├── wildcardRouter.ts # Routing model wildcard
+│ │ ├── autoCombo/ # Mesin auto-combo (penilaian 6-faktor, eksplorasi bandit)
+│ │ ├── intentClassifier.ts # Klasifikasi maksud permintaan
+│ │ ├── taskAwareRouter.ts # Routing berbasis tugas
+│ │ ├── thinkingBudget.ts # Manajemen anggaran berpikir
+│ │ ├── contextManager.ts # Manajemen jendela konteks
+│ │ ├── modelDeprecation.ts # Penanganan model yang sudah tidak digunakan
+│ │ ├── modelFamilyFallback.ts # Fallback model dalam keluarga yang sama
+│ │ ├── emergencyFallback.ts # Fallback darurat
+│ │ ├── workflowFSM.ts # Mesin state alur kerja
+│ │ ├── backgroundTaskDetector.ts # Deteksi tugas latar belakang
+│ │ ├── ipFilter.ts # Kontrol akses berbasis IP
+│ │ ├── signatureCache.ts # Caching tanda tangan CLI
+│ │ ├── volumeDetector.ts # Deteksi volume permintaan
+│ │ ├── contextHandoff.ts # Pembuatan dan injeksi handoff context relay
+│ │ ├── codexQuotaFetcher.ts # Pengambilan kuota Codex untuk context-relay
+│ │ └── ... # Layanan tambahan (14 modul lagi)
+│ ├── transformer/ # Transformer Responses API
│ │ └── responsesTransformer.ts
-│ ├── translator/ # Format translators (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama ↔ DeepSeek)
-│ │ ├── request/ # Request translators per provider
-│ │ ├── response/ # Response translators per provider
-│ │ ├── helpers/ # Translation helpers
-│ │ └── image/ # Image format translation
-│ └── utils/ # 22 utility modules (stream, TLS, proxy, logging, etc.)
-├── electron/ # Electron desktop app (cross-platform)
-│ ├── main.js # Electron main process
-│ ├── preload.js # Preload script (IPC bridge)
-│ └── assets/ # App icons and assets
-├── tests/ # Test suites
-│ ├── unit/ # 122 unit test files
-│ ├── integration/ # Integration tests
-│ ├── e2e/ # Playwright E2E tests
-│ ├── security/ # Security tests
-│ ├── translator/ # Translator-specific tests
-│ └── load/ # Load tests
-├── docs/ # Documentation
-│ ├── i18n/ # 30-language translated docs
-│ ├── ARCHITECTURE.md # Full architecture documentation
-│ ├── API_REFERENCE.md # API reference
-│ ├── USER_GUIDE.md # User guide
-│ ├── CODEBASE_DOCUMENTATION.md # Codebase overview
-│ ├── CLI-TOOLS.md # CLI tools integration guide
-│ ├── A2A-SERVER.md # A2A agent protocol documentation
-│ ├── AUTO-COMBO.md # Auto-combo engine (6-factor scoring)
-│ ├── MCP-SERVER.md # MCP server (29 tools)
-│ ├── TROUBLESHOOTING.md # Troubleshooting guide
-│ ├── VM_DEPLOYMENT_GUIDE.md # VPS deployment guide
-│ ├── openapi.yaml # OpenAPI specification
-│ └── screenshots/ # Dashboard screenshots
-├── bin/ # CLI entry points (omniroute, reset-password)
-├── scripts/ # Build and utility scripts
-└── .env.example # Environment variable template
+│ ├── translator/ # Penerjemah format (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama ↔ DeepSeek)
+│ │ ├── request/ # Penerjemah permintaan per penyedia
+│ │ ├── response/ # Penerjemah respons per penyedia
+│ │ ├── helpers/ # Pembantu translasi
+│ │ └── image/ # Translasi format gambar
+│ └── utils/ # 22 modul utilitas (stream, TLS, proxy, logging, dll.)
+├── electron/ # Aplikasi desktop Electron (lintas platform)
+│ ├── main.js # Proses utama Electron
+│ ├── preload.js # Skrip preload (jembatan IPC)
+│ └── assets/ # Ikon dan aset aplikasi
+├── tests/ # Suite pengujian
+│ ├── unit/ # 122 file uji unit
+│ ├── integration/ # Uji integrasi
+│ ├── e2e/ # Uji E2E Playwright
+│ ├── security/ # Uji keamanan
+│ ├── translator/ # Uji khusus penerjemah
+│ └── load/ # Uji beban
+├── docs/ # Dokumentasi
+│ ├── i18n/ # Dokumentasi terjemahan 30 bahasa
+│ ├── ARCHITECTURE.md # Dokumentasi arsitektur lengkap
+│ ├── API_REFERENCE.md # Referensi API
+│ ├── USER_GUIDE.md # Panduan pengguna
+│ ├── CODEBASE_DOCUMENTATION.md # Ikhtisar basis kode
+│ ├── CLI-TOOLS.md # Panduan integrasi alat CLI
+│ ├── A2A-SERVER.md # Dokumentasi protokol agen A2A
+│ ├── AUTO-COMBO.md # Mesin auto-combo (penilaian 6-faktor)
+│ ├── MCP-SERVER.md # Server MCP (29 alat)
+│ ├── TROUBLESHOOTING.md # Panduan pemecahan masalah
+│ ├── VM_DEPLOYMENT_GUIDE.md # Panduan penerapan VPS
+│ ├── openapi.yaml # Spesifikasi OpenAPI
+│ └── screenshots/ # Tangkapan layar dashboard
+├── bin/ # Titik masuk CLI (omniroute, reset-password)
+├── scripts/ # Skrip build dan utilitas
+└── .env.example # Template variabel lingkungan
```
-## Key Features (v3.8.8)
+## Fitur Utama (v3.8.8)
-### Core Proxy
-- **177 AI providers** with automatic format translation
-- **4 provider categories**: Free (5), OAuth (14), API Key (123+), Self-Hosted (8+), Custom (OpenAI/Anthropic-compatible)
-- **14 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, strict-random, auto, lkgp, context-optimized, context-relay, **reset-aware** (v3.8)
-- **4-tier fallback**: Subscription → API Key → Cheap → Free
-- **Context Relay strategy**: Session handoff summaries on account rotation for continuity
-- **Auto-combo engine**: Self-healing routing optimization with **9-factor scoring** (health/quota/costInv/latencyInv/taskFit/specificityMatch/stability/tierPriority/tierAffinity), bandit exploration, progressive cooldown
-- **Semantic caching** with cache hit/miss headers
-- **Idempotency** with configurable dedup window
-- **3-layer resilience**: Provider Circuit Breaker / Connection Cooldown / Model Lockout
-- **Provider Icons**: 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback
-- **Model Auto-Sync**: 24h scheduler refreshes model lists for 16 providers
-- **Registered Keys API**: Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement
-- **Memory System**: Persistent conversational memory with extraction, injection, retrieval, and summarization
-- **Skills System**: Extensible skill framework with registry, executor, sandbox, built-in and custom skills
-- **Cloud Agents**: Codex Cloud, Devin, Jules — autonomous coding agents with task lifecycle management
-- **Guardrails Framework**: Hot-reloadable registry with vision-bridge, pii-masker, prompt-injection (priority-ordered)
-- **MITM Proxy**: Certificate management, DNS handling, and target routing
-- **Cloudflare Tunnels**: Managed tunnel creation for remote access
-- **Coverage gate**: 75% statements/lines/functions, 70% branches (measured ~82%)
+### Proxy Inti
+- **177 penyedia AI** dengan translasi format otomatis
+- **4 kategori penyedia**: Gratis (5), OAuth (14), Kunci API (123+), Self-Hosted (8+), Kustom (kompatibel OpenAI/Anthropic)
+- **14 strategi routing**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, strict-random, auto, lkgp, context-optimized, context-relay, **reset-aware** (v3.8)
+- **Fallback 4-tingkat**: Subscription → API Key → Cheap → Free
+- **Strategi Context Relay**: Ringkasan handoff sesi saat rotasi akun untuk kesinambungan
+- **Mesin auto-combo**: Optimasi routing self-healing dengan **penilaian 9-faktor** (health/quota/costInv/latencyInv/taskFit/specificityMatch/stability/tierPriority/tierAffinity), eksplorasi bandit, pendinginan progresif
+- **Caching semantik** dengan header hit/miss cache
+- **Idempotency** dengan jendela dedup yang dapat dikonfigurasi
+- **Resilience 3-lapisan**: Provider Circuit Breaker / Connection Cooldown / Model Lockout
+- **Ikon Penyedia**: 130+ logo penyedia via `@lobehub/icons` (SVG) dengan fallback PNG
+- **Auto-Sync Model**: Penjadwal 24 jam memperbarui daftar model untuk 16 penyedia
+- **API Kunci Terdaftar**: Provisioning otomatis kunci API via `POST /api/v1/registered-keys` dengan penegakan kuota
+- **Sistem Memori**: Memori percakapan persisten dengan ekstraksi, injeksi, pengambilan, dan ringkasan
+- **Sistem Skills**: Kerangka skill yang dapat dikembangkan dengan registri, executor, sandbox, skill bawaan dan kustom
+- **Cloud Agents**: Codex Cloud, Devin, Jules — agen pengkodean otonom dengan manajemen siklus hidup tugas
+- **Kerangka Guardrails**: Registri hot-reloadable dengan vision-bridge, pii-masker, prompt-injection (berurutan berdasarkan prioritas)
+- **Proxy MITM**: Manajemen sertifikat, penanganan DNS, dan routing target
+- **Tunnel Cloudflare**: Pembuatan tunnel terkelola untuk akses jarak jauh
+- **Gerbang cakupan**: 75% statements/lines/functions, 70% branches (terukur ~82%)
-### Security
-- **Data Loss Prevention**: SQLite migration safety bounds abort startup on dangerous massive schema overrides. Pre-migration `VACUUM INTO` backups isolate rollback snapshots.
-- **CodeQL security**: Fixed 10+ CodeQL alerts (polynomial-redos, insecure-randomness, shell-injection, SSRF, incomplete URLs)
-- **Web Crypto session IDs**: `generateSessionId` uses `crypto.getRandomValues()` instead of `Math.random()`
-- **Route validation**: All API routes validated with Zod v4 schemas + `validateBody()`
-- **omniModel tag sanitization**: Internal `` tags never leak to clients in SSE streams
-- **TLS Fingerprint Spoofing** — Browser-like TLS fingerprint to reduce bot detection
-- **CLI Fingerprint Matching** — Per-provider request signature matching
-- **Prompt injection guard** — Request middleware detection
-- **Provider constants validated at module load** via Zod (`src/shared/validation/providerSchema.ts`)
-- **PII sanitizer** — Sensitive data scrubbing in logs
+### Keamanan
+- **Pencegahan Kehilangan Data**: Batas keamanan migrasi SQLite menghentikan startup pada penggantian skema besar yang berbahaya. Backup `VACUUM INTO` pra-migrasi mengisolasi snapshot rollback.
+- **Keamanan CodeQL**: Memperbaiki 10+ peringatan CodeQL (polynomial-redos, insecure-randomness, shell-injection, SSRF, URL tidak lengkap)
+- **ID sesi Web Crypto**: `generateSessionId` menggunakan `crypto.getRandomValues()` alih-alih `Math.random()`
+- **Validasi rute**: Semua rute API divalidasi dengan skema Zod v4 + `validateBody()`
+- **Sanitasi tag omniModel**: Tag internal `` tidak pernah bocor ke klien dalam aliran SSE
+- **Pemalsuan Sidik Jari TLS** — Sidik jari TLS seperti browser untuk mengurangi deteksi bot
+- **Pencocokan Sidik Jari CLI** — Pencocokan tanda tangan permintaan per penyedia
+- **Penjaga injeksi prompt** — Deteksi middleware permintaan
+- **Konstanta penyedia divalidasi saat pemuatan modul** via Zod (`src/shared/validation/providerSchema.ts`)
+- **Sanitizer PII** — Pembersihan data sensitif dalam log
-### Dashboard Pages (23 sections)
-- **Providers** — OAuth, API key, and free provider management with ProviderIcon SVG icons
-- **Combos** — Multi-model combo builder with 4 templates (Free Stack, High Availability, Cost Saver, Balanced) + 14 strategies
-- **Auto-Combo** — Auto-combo engine dashboard with scoring metrics
-- **Analytics** — Token consumption, cost, heatmaps, distributions
-- **Health** — Uptime, memory, latency percentiles, circuit breakers
-- **Logs** — Request, Proxy, Audit, Console (tabbed)
-- **Audit** — Audit trail and compliance logging
-- **Costs** — Cost tracking per provider/model
-- **Limits** — Rate limit monitoring
-- **Cache** — Semantic cache statistics and management
-- **CLI Tools** — One-click configuration for 10+ AI CLI tools
-- **CLI Agents** — Grid of 14+ built-in agents with ProviderIcon and install detection + custom agent registration
-- **Playground** — Test any model with Monaco editor, streaming responses
-- **Media** — Image/video/music generation (GPT-Image, FLUX, etc.) + audio transcription (up to 2GB files)
-- **Search Tools** — Search provider configuration and testing
-- **Memory** — Memory system management and visualization
-- **Skills** — Skills framework management and execution
-- **Translator** — Format debugging: playground, chat tester, test bench, live monitor
-- **Settings** — General, Appearance (7 color themes), Security (TLS/CLI fingerprint, IP filter), Routing, Resilience, Advanced
-- **Endpoint** — Unified: Endpoint Proxy, MCP Server, A2A Server, API Endpoints (tabbed)
-- **Onboarding** — Setup wizard for new users
-- **Usage** — Usage history and analytics
-- **API Manager** — API key management with scoped permissions
+### Halaman Dashboard (23 bagian)
+- **Providers** — Manajemen penyedia OAuth, kunci API, dan gratis dengan ikon SVG ProviderIcon
+- **Combos** — Pembuat combo multi-model dengan 4 template (Free Stack, High Availability, Cost Saver, Balanced) + 14 strategi
+- **Auto-Combo** — Dashboard mesin auto-combo dengan metrik penilaian
+- **Analytics** — Konsumsi token, biaya, peta panas, distribusi
+- **Health** — Uptime, memori, persentil latensi, circuit breaker
+- **Logs** — Permintaan, Proxy, Audit, Konsol (bertab)
+- **Audit** — Jejak audit dan pencatatan kepatuhan
+- **Costs** — Pelacakan biaya per penyedia/model
+- **Limits** — Pemantauan batas kecepatan
+- **Cache** — Statistik dan manajemen cache semantik
+- **CLI Tools** — Konfigurasi satu klik untuk 10+ alat CLI AI
+- **CLI Agents** — Kisi 14+ agen bawaan dengan ProviderIcon dan deteksi instalasi + registrasi agen kustom
+- **Playground** — Uji model apa pun dengan editor Monaco, respons streaming
+- **Media** — Pembuatan gambar/video/musik (GPT-Image, FLUX, dll.) + transkripsi audio (hingga file 2GB)
+- **Search Tools** — Konfigurasi dan pengujian penyedia pencarian
+- **Memory** — Manajemen dan visualisasi sistem memori
+- **Skills** — Manajemen dan eksekusi kerangka skills
+- **Translator** — Debug format: playground, penguji chat, bangku uji, monitor langsung
+- **Settings** — Umum, Tampilan (7 tema warna), Keamanan (sidik jari TLS/CLI, filter IP), Routing, Resilience, Lanjutan
+- **Endpoint** — Terpadu: Endpoint Proxy, MCP Server, A2A Server, API Endpoints (bertab)
+- **Onboarding** — Wizard penyiapan untuk pengguna baru
+- **Usage** — Riwayat penggunaan dan analitik
+- **API Manager** — Manajemen kunci API dengan izin berbasis cakupan
-### Protocol Support
-- **OpenAI-compatible** — `/v1/chat/completions`, `/v1/models`, `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/transcriptions`, `/v1/audio/speech`, `/v1/moderations`, `/v1/rerank`, `/v1/videos/generations`, `/v1/music/generations`
+### Dukungan Protokol
+- **Kompatibel OpenAI** — `/v1/chat/completions`, `/v1/models`, `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/transcriptions`, `/v1/audio/speech`, `/v1/moderations`, `/v1/rerank`, `/v1/videos/generations`, `/v1/music/generations`
- **Anthropic** — `/v1/messages`, `/v1/messages/count_tokens`
- **OpenAI Responses** — `/v1/responses`
- **Gemini** — `/v1beta/models`, `/v1beta/models/{...path}`
- **Ollama** — `/v1/api/chat`, `/api/tags`
- **Search** — `/v1/search` (Perplexity, Serper, Brave, Exa, Tavily)
-- **MCP** — 37-tool MCP server with scope-based auth (3 transports: stdio, SSE, streamable HTTP)
-- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 5 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report)
-- **ACP** — Agent Communication Protocol registry and manager
+- **MCP** — Server MCP 37 alat dengan auth berbasis cakupan (3 transport: stdio, SSE, streamable HTTP)
+- **A2A** — Protokol Agent-to-Agent v0.3 (JSON-RPC 2.0, 5 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report)
+- **ACP** — Registri dan manajer Agent Communication Protocol
-### MCP Server (37 Tools)
-| Category | Tools |
+### Server MCP (37 Alat)
+| Kategori | Alat |
|------------|-------|
-| Core (30) | `get_health`, `list_combos`, `get_combo_metrics`, `switch_combo`, `check_quota`, `route_request`, `cost_report`, `list_models_catalog`, `web_search`, `simulate_route`, `set_budget_guard`, `set_routing_strategy`, `set_resilience_profile`, `test_combo`, `get_provider_metrics`, `best_combo_for_task`, `explain_route`, `get_session_snapshot`, `db_health_check`, `sync_pricing`, `cache_stats`, `cache_flush`, and advanced routing/diagnostics tools (see `docs/frameworks/MCP-SERVER.md` for full inventory) |
-| Memory (3) | `memory_search`, `memory_add`, `memory_clear` |
+| Inti (30) | `get_health`, `list_combos`, `get_combo_metrics`, `switch_combo`, `check_quota`, `route_request`, `cost_report`, `list_models_catalog`, `web_search`, `simulate_route`, `set_budget_guard`, `set_routing_strategy`, `set_resilience_profile`, `test_combo`, `get_provider_metrics`, `best_combo_for_task`, `explain_route`, `get_session_snapshot`, `db_health_check`, `sync_pricing`, `cache_stats`, `cache_flush`, dan alat routing/diagnostik lanjutan (lihat `docs/frameworks/MCP-SERVER.md` untuk inventaris lengkap) |
+| Memori (3) | `memory_search`, `memory_add`, `memory_clear` |
| Skills (4) | `skills_list`, `skills_enable`, `skills_execute`, `skills_executions` |
-**MCP Auth Scopes (~13):** `read:health`, `read:combos`, `write:combos`, `read:quota`, `read:usage`, `read:models`, `execute:completions`, `execute:search`, `write:budget`, `write:resilience`, plus memory/skills scopes — full list in `docs/frameworks/MCP-SERVER.md`.
+**Cakupan Auth MCP (~13):** `read:health`, `read:combos`, `write:combos`, `read:quota`, `read:usage`, `read:models`, `execute:completions`, `execute:search`, `write:budget`, `write:resilience`, ditambah cakupan memori/skills — daftar lengkap di `docs/frameworks/MCP-SERVER.md`.
-### Provider Categories
+### Kategori Penyedia
-**Free Providers (5):** Qoder AI, Qwen Code (deprecated), Gemini CLI, Kiro AI, Windsurf
+**Penyedia Gratis (5):** Qoder AI, Qwen Code (tidak digunakan lagi), Gemini CLI, Kiro AI, Windsurf
-**OAuth Providers (14):** Claude Code, Antigravity, OpenAI Codex, GitHub Copilot, Cursor IDE, Kimi Coding, Kilo Code, Cline, Qwen, Kiro, Qoder, Gemini, Windsurf, GitLab Duo
+**Penyedia OAuth (14):** Claude Code, Antigravity, OpenAI Codex, GitHub Copilot, Cursor IDE, Kimi Coding, Kilo Code, Cline, Qwen, Kiro, Qoder, Gemini, Windsurf, GitLab Duo
-**API Key Providers (48+):** OpenAI, Anthropic, Gemini (Google AI Studio), DeepSeek, Groq, xAI (Grok), Mistral, Perplexity, Together AI, Fireworks AI, Cerebras, Cohere, NVIDIA NIM, Nebius AI, SiliconFlow, Hyperbolic, HuggingFace, OpenRouter, Vertex AI, Cloudflare Workers AI, Scaleway AI, AI/ML API, Pollinations AI, Puter AI, LongCat AI, Alibaba, Alibaba (China), Kimi, Kimi Coding (API Key), Minimax, Minimax (China), Blackbox AI, Synthetic, Kilo Gateway, Z.AI, GLM Coding, Deepgram, AssemblyAI, ElevenLabs, Cartesia, PlayHT, Inworld, NanoBanana, SD WebUI, ComfyUI, Ollama Cloud, Perplexity Search, Serper Search, Brave Search, Exa Search, Tavily Search, OpenCode Zen, OpenCode Go, Alibaba Coding Plan
+**Penyedia Kunci API (48+):** OpenAI, Anthropic, Gemini (Google AI Studio), DeepSeek, Groq, xAI (Grok), Mistral, Perplexity, Together AI, Fireworks AI, Cerebras, Cohere, NVIDIA NIM, Nebius AI, SiliconFlow, Hyperbolic, HuggingFace, OpenRouter, Vertex AI, Cloudflare Workers AI, Scaleway AI, AI/ML API, Pollinations AI, Puter AI, LongCat AI, Alibaba, Alibaba (China), Kimi, Kimi Coding (API Key), Minimax, Minimax (China), Blackbox AI, Synthetic, Kilo Gateway, Z.AI, GLM Coding, Deepgram, AssemblyAI, ElevenLabs, Cartesia, PlayHT, Inworld, NanoBanana, SD WebUI, ComfyUI, Ollama Cloud, Perplexity Search, Serper Search, Brave Search, Exa Search, Tavily Search, OpenCode Zen, OpenCode Go, Alibaba Coding Plan
-**Custom Providers:** OpenAI-compatible (`openai-compatible-*`) and Anthropic-compatible (`anthropic-compatible-*`) with custom base URLs
+**Penyedia Kustom:** Kompatibel OpenAI (`openai-compatible-*`) dan kompatibel Anthropic (`anthropic-compatible-*`) dengan URL dasar kustom
-### Internationalization
-- 40+ languages for UI (all dashboard pages)
-- 40 translated documentation sets in docs/i18n/
-- Language switcher in documentation
+### Internasionalisasi
+- 40+ bahasa untuk UI (semua halaman dashboard)
+- 40 set dokumentasi terjemahan di docs/i18n/
+- Pemilih bahasa dalam dokumentasi
-## Key Architectural Decisions
+## Keputusan Arsitektur Utama
-1. **OpenAI-compatible API surface:** All incoming requests follow the OpenAI API format. This makes OmniRoute a drop-in replacement for any tool that supports custom OpenAI endpoints.
+1. **Permukaan API kompatibel OpenAI:** Semua permintaan masuk mengikuti format OpenAI API. Ini menjadikan OmniRoute sebagai pengganti langsung untuk alat apa pun yang mendukung endpoint OpenAI kustom.
-2. **Provider abstraction via format translators:** Each AI provider has a translator in `open-sse/translator/` that converts between OpenAI format and the provider's native format transparently.
+2. **Abstraksi penyedia via penerjemah format:** Setiap penyedia AI memiliki penerjemah di `open-sse/translator/` yang mengkonversi antara format OpenAI dan format asli penyedia secara transparan.
-3. **Connection-based provider model:** Providers are stored as "connections" in SQLite. Each connection has an `id`, `provider`, `authType` (oauth/apikey/free), `isActive` flag, and credentials. Multiple connections per provider for multi-account rotation.
+3. **Model penyedia berbasis koneksi:** Penyedia disimpan sebagai "koneksi" di SQLite. Setiap koneksi memiliki `id`, `provider`, `authType` (oauth/apikey/free), flag `isActive`, dan kredensial. Beberapa koneksi per penyedia untuk rotasi multi-akun.
-4. **Combo system for fallback:** Users create "combos" — ordered lists of `provider/model` pairs. The proxy tries each in order until one succeeds. Supports 14 strategies including auto-combo with self-healing and context-relay for session continuity.
+4. **Sistem combo untuk fallback:** Pengguna membuat "combo" — daftar terurut pasangan `provider/model`. Proxy mencoba setiap pasangan secara berurutan hingga salah satu berhasil. Mendukung 14 strategi termasuk auto-combo dengan self-healing dan context-relay untuk kesinambungan sesi.
-5. **SSE proxy pipeline:** The proxy pipeline is middleware-based: request → auth resolution → rate limiting → circuit breaker → format translation → upstream call → response translation → SSE streaming back to client.
+5. **Pipeline proxy SSE:** Pipeline proxy berbasis middleware: permintaan → resolusi auth → pembatasan kecepatan → circuit breaker → translasi format → panggilan upstream → translasi respons → SSE streaming kembali ke klien.
-6. **SQLite for persistence:** All state (providers, combos, logs, settings, API keys, memory, skills) stored in a single SQLite database via 21 domain-specific modules. All DB operations go through `src/lib/db/` modules, never raw SQL in routes.
+6. **SQLite untuk persistensi:** Semua state (penyedia, combo, log, pengaturan, kunci API, memori, skills) disimpan dalam satu database SQLite via 21 modul domain-spesifik. Semua operasi DB melewati modul `src/lib/db/`, bukan SQL mentah di rute.
-7. **OAuth with PKCE:** OAuth flows use PKCE for security. Token refresh handled by background job (`tokenHealthCheck.ts`).
+7. **OAuth dengan PKCE:** Alur OAuth menggunakan PKCE untuk keamanan. Refresh token ditangani oleh pekerjaan latar belakang (`tokenHealthCheck.ts`).
-8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
+8. **Komponen ProviderIcon:** Sistem ikon terpadu menggunakan `@lobehub/icons` (130+ SVG) dengan fallback PNG dan rantai fallback ikon generik. Digunakan di halaman penyedia, dashboard, dan agen.
-9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 21 `src/lib/db/` modules with 16 SQL migrations.
+9. **Arsitektur DB:** `localDb.ts` hanya merupakan lapisan re-ekspor — logika nyata ada di 21 modul `src/lib/db/` dengan 16 migrasi SQL.
-10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
+10. **Header upstream:** Header kustom digabungkan di executor setelah auth default; nama header yang sama menggantikan nilai executor. Nama header yang dilarang ada di `src/shared/constants/upstreamHeaders.ts`.
-11. **Memory/Skills cross-cutting systems:** Memory and Skills affect the MCP tools, request pipeline, and A2A skills. Memory provides persistent context across sessions; Skills provide extensible tool execution with sandbox isolation.
+11. **Sistem lintas-bidang Memory/Skills:** Memory dan Skills mempengaruhi alat MCP, pipeline permintaan, dan skills A2A. Memory menyediakan konteks persisten lintas sesi; Skills menyediakan eksekusi alat yang dapat dikembangkan dengan isolasi sandbox.
-12. **Domain policy engine:** `src/domain/` contains policy engine modules (policyEngine, comboResolver, costRules, degradation, fallbackPolicy, lockoutPolicy, modelAvailability, providerExpiration, quotaCache, configAudit) that govern routing decisions independently from the pipeline.
+12. **Mesin kebijakan domain:** `src/domain/` berisi modul mesin kebijakan (policyEngine, comboResolver, costRules, degradation, fallbackPolicy, lockoutPolicy, modelAvailability, providerExpiration, quotaCache, configAudit) yang mengatur keputusan routing secara independen dari pipeline.
-13. **Provider constants validated at load:** All provider definitions validated via Zod schemas at module load time (`src/shared/validation/providerSchema.ts`). Invalid providers fail fast.
+13. **Konstanta penyedia divalidasi saat pemuatan:** Semua definisi penyedia divalidasi via skema Zod saat waktu pemuatan modul (`src/shared/validation/providerSchema.ts`). Penyedia yang tidak valid gagal dengan cepat.
-## Main Flows
+## Alur Utama
-### Proxy Request Flow
-1. Client sends OpenAI-format request to `/v1/chat/completions`
-2. API key validation
-3. Model resolution: direct model or combo lookup
-4. For combos: iterate through models with selected strategy
-5. Auth resolution: get credentials for the target provider
-6. Format translation: OpenAI → provider native format
-7. CLI fingerprint matching (if enabled for provider)
-8. Upstream request with circuit breaker and rate limiting
-9. Response translation: provider → OpenAI format
-10. omniModel tag sanitization (strip internal tags)
-11. SSE streaming back to client
-12. Memory extraction (if memory system enabled)
-13. Usage logging and cost calculation
+### Alur Permintaan Proxy
+1. Klien mengirim permintaan format OpenAI ke `/v1/chat/completions`
+2. Validasi kunci API
+3. Resolusi model: pencarian model langsung atau combo
+4. Untuk combo: iterasi melalui model dengan strategi yang dipilih
+5. Resolusi auth: mendapatkan kredensial untuk penyedia target
+6. Translasi format: OpenAI → format asli penyedia
+7. Pencocokan sidik jari CLI (jika diaktifkan untuk penyedia)
+8. Permintaan upstream dengan circuit breaker dan pembatasan kecepatan
+9. Translasi respons: penyedia → format OpenAI
+10. Sanitasi tag omniModel (hapus tag internal)
+11. SSE streaming kembali ke klien
+12. Ekstraksi memori (jika sistem memori diaktifkan)
+13. Pencatatan penggunaan dan perhitungan biaya
-### OAuth Flow
-1. Dashboard initiates `/api/oauth/[provider]/authorize`
-2. User completes OAuth login in browser
-3. Callback hits `/api/oauth/[provider]/exchange`
-4. Tokens stored as a provider connection in SQLite
-5. Background job refreshes tokens before expiry
+### Alur OAuth
+1. Dashboard memulai `/api/oauth/[provider]/authorize`
+2. Pengguna menyelesaikan login OAuth di browser
+3. Callback menyentuh `/api/oauth/[provider]/exchange`
+4. Token disimpan sebagai koneksi penyedia di SQLite
+5. Pekerjaan latar belakang memperbarui token sebelum kedaluwarsa
-## Important Notes for LLMs
+## Catatan Penting untuk LLM
-1. **Two model endpoints exist:** `/api/models` (dashboard, all models) and `/v1/models` (OpenAI-compatible, active only).
+1. **Dua endpoint model tersedia:** `/api/models` (dashboard, semua model) dan `/v1/models` (kompatibel OpenAI, hanya aktif).
-2. **Provider IDs vs aliases:** Providers have both an ID (`claude`, `github`) and a short alias (`cc`, `gh`). Models are referenced as `alias/model-name` (e.g., `cc/claude-opus-4-6`).
+2. **ID penyedia vs alias:** Penyedia memiliki ID (`claude`, `github`) dan alias pendek (`cc`, `gh`). Model direferensikan sebagai `alias/model-name` (mis., `cc/claude-opus-4-6`).
-3. **The `open-sse/` directory is a separate npm workspace** with its own config, handlers, executors, translators, and services.
+3. **Direktori `open-sse/` adalah workspace npm terpisah** dengan konfigurasi, handler, executor, penerjemah, dan layanannya sendiri.
-4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
+4. **Variabel lingkungan:** Semua konfigurasi ada di `.env` (dari `.env.example`). Variabel kunci: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
-5. **Database layer:** Operations go through `src/lib/db/` modules (45+ domain-specific files, 55 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
+5. **Lapisan database:** Operasi melewati modul `src/lib/db/` (45+ file domain-spesifik, 55 migrasi). `localDb.ts` hanya re-ekspor — tambahkan fungsi baru ke modul `db/*.ts` yang sesuai.
-6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: 75% statements/lines/functions, 70% branches.
+6. **Pengujian** menggunakan runner bawaan Node.js + Vitest. Jalankan `npm test`. Vitest untuk MCP/autoCombo (`npm run test:vitest`). Playwright untuk E2E (`npm run test:e2e`). Gerbang cakupan: 75% statements/lines/functions, 70% branches.
-7. **MCP and A2A pages are embedded as tabs inside `/dashboard/endpoint`**, not standalone routes.
+7. **Halaman MCP dan A2A disematkan sebagai tab di dalam `/dashboard/endpoint`**, bukan rute mandiri.
-8. **ACP agents** are in `src/lib/acp/registry.ts` with detection cache. Custom agents stored via settings DB.
+8. **Agen ACP** ada di `src/lib/acp/registry.ts` dengan cache deteksi. Agen kustom disimpan via DB pengaturan.
-9. **Auto-combo engine** in `open-sse/services/autoCombo/` — **9-factor scoring** (health 0.22, quota 0.17, costInv 0.17, latencyInv 0.13, taskFit 0.08, specificityMatch 0.08, stability 0.05, tierPriority 0.05, tierAffinity 0.05), 4 mode packs, bandit exploration, progressive cooldown.
+9. **Mesin auto-combo** di `open-sse/services/autoCombo/` — **penilaian 9-faktor** (health 0.22, quota 0.17, costInv 0.17, latencyInv 0.13, taskFit 0.08, specificityMatch 0.08, stability 0.05, tierPriority 0.05, tierAffinity 0.05), 4 paket mode, eksplorasi bandit, pendinginan progresif.
-10. **Docker:** Dockerfile has two targets: `runner-base` and `runner-cli`. `docker-compose.yml` for dev (3 profiles), `docker-compose.prod.yml` for production (port 20130).
+10. **Docker:** Dockerfile memiliki dua target: `runner-base` dan `runner-cli`. `docker-compose.yml` untuk dev (3 profil), `docker-compose.prod.yml` untuk produksi (port 20130).
-11. **Electron desktop app** in `electron/` with main.js and preload.js. Build with `npm run electron:build` (supports Windows, macOS, Linux).
+11. **Aplikasi desktop Electron** di `electron/` dengan main.js dan preload.js. Build dengan `npm run electron:build` (mendukung Windows, macOS, Linux).
-12. **Pricing data** syncs from LiteLLM via `src/lib/pricingSync.ts`. Use `sync_pricing` MCP tool or API endpoint.
+12. **Data harga** disinkronkan dari LiteLLM via `src/lib/pricingSync.ts`. Gunakan alat MCP `sync_pricing` atau endpoint API.
-13. **Memory system** in `src/lib/memory/` provides extraction, injection, retrieval, summarization, and persistent store. Exposed via MCP memory tools and `/api/memory/ API.
+13. **Sistem memori** di `src/lib/memory/` menyediakan ekstraksi, injeksi, pengambilan, ringkasan, dan penyimpanan persisten. Diekspos via alat memori MCP dan API `/api/memory/`.
-14. **Skills system** in `src/lib/skills/` provides registry, executor, sandbox isolation, built-in skills, custom skill support, request interception, and context injection. Exposed via MCP skill tools and `/api/skills/` API.
+14. **Sistem skills** di `src/lib/skills/` menyediakan registri, executor, isolasi sandbox, skill bawaan, dukungan skill kustom, intersepsi permintaan, dan injeksi konteks. Diekspos via alat skill MCP dan API `/api/skills/`.
-15. **Zod v4** is used for all validation. Import from `zod` package. Provider schemas validated at module load time.
+15. **Zod v4** digunakan untuk semua validasi. Impor dari paket `zod`. Skema penyedia divalidasi saat waktu pemuatan modul.
-16. **Context Relay** strategy (`context-relay`) is split across two layers: `combo.ts` decides if a handoff should be generated after a successful turn; `chat.ts` injects the handoff only after account resolution. Handoff data lives in `context_handoffs` SQLite table. Config: `handoffThreshold`, `handoffModel`, `handoffProviders`.
+16. **Strategi Context Relay** (`context-relay`) dibagi ke dua lapisan: `combo.ts` memutuskan apakah handoff harus dibuat setelah giliran yang berhasil; `chat.ts` menyuntikkan handoff hanya setelah resolusi akun. Data handoff tersimpan di tabel SQLite `context_handoffs`. Konfigurasi: `handoffThreshold`, `handoffModel`, `handoffProviders`.
-17. **Proxy enforcement** is now comprehensive: token health checks resolve proxy per connection, provider validation wraps in `runWithProxyContext`, and proxy dispatchers use `undici.fetch()` instead of the Node built-in `fetch()` to avoid dispatcher incompatibilities on Node 22.
+17. **Penegakan proxy** kini komprehensif: pemeriksaan kesehatan token menyelesaikan proxy per koneksi, validasi penyedia dibungkus dalam `runWithProxyContext`, dan dispatcher proxy menggunakan `undici.fetch()` alih-alih `fetch()` bawaan Node untuk menghindari ketidakcocokan dispatcher di Node 22.
-18. **Node.js 24+ compatibility**: The login page (`/api/settings/require-login`) detects the Node.js version and sends `nodeVersion`/`nodeCompatible` fields. The login UI renders a warning banner when `nodeCompatible` is false.
+18. **Kompatibilitas Node.js 24+**: Halaman login (`/api/settings/require-login`) mendeteksi versi Node.js dan mengirim field `nodeVersion`/`nodeCompatible`. UI login merender banner peringatan ketika `nodeCompatible` bernilai false.
-19. **Cloud Agents** in `src/lib/cloudAgent/` — three external autonomous coding agents (Codex Cloud, Devin, Jules) with task lifecycle endpoints under `/api/v1/agents/tasks/`. Require management auth, not client auth.
+19. **Cloud Agents** di `src/lib/cloudAgent/` — tiga agen pengkodean otonom eksternal (Codex Cloud, Devin, Jules) dengan endpoint siklus hidup tugas di bawah `/api/v1/agents/tasks/`. Memerlukan auth manajemen, bukan auth klien.
-20. **Guardrails framework** in `src/lib/guardrails/` — hot-reloadable registry. Built-ins (priority-ordered): `vision-bridge` (5) → `pii-masker` (10) → `prompt-injection` (20). Fail-open model: exceptions never block traffic. Per-request opt-out via `x-omniroute-disabled-guardrails` header.
+20. **Kerangka Guardrails** di `src/lib/guardrails/` — registri hot-reloadable. Bawaan (berurutan berdasarkan prioritas): `vision-bridge` (5) → `pii-masker` (10) → `prompt-injection` (20). Model fail-open: pengecualian tidak pernah memblokir lalu lintas. Penonaktifan per-permintaan via header `x-omniroute-disabled-guardrails`.
-21. **Authz pipeline** (`src/server/authz/`): every request is classified as `PUBLIC`, `CLIENT_API`, or `MANAGEMENT`, then run through policy + enforce stages. See `docs/architecture/AUTHZ_GUIDE.md`.
+21. **Pipeline Authz** (`src/server/authz/`): setiap permintaan diklasifikasikan sebagai `PUBLIC`, `CLIENT_API`, atau `MANAGEMENT`, kemudian dijalankan melalui tahap kebijakan + penerapan. Lihat `docs/architecture/AUTHZ_GUIDE.md`.
-22. **Three resilience layers** are distinct (do not conflate them):
- - **Provider Circuit Breaker** (`src/shared/utils/circuitBreaker.ts`) — whole-provider scope.
- - **Connection Cooldown** (`src/sse/services/auth.ts::markAccountUnavailable`) — one key/account scope.
- - **Model Lockout** (`open-sse/services/accountFallback.ts`) — provider + connection + model scope.
+22. **Tiga lapisan resilience** berbeda (jangan mencampuradukkan):
+ - **Provider Circuit Breaker** (`src/shared/utils/circuitBreaker.ts`) — cakupan seluruh penyedia.
+ - **Connection Cooldown** (`src/sse/services/auth.ts::markAccountUnavailable`) — cakupan satu kunci/akun.
+ - **Model Lockout** (`open-sse/services/accountFallback.ts`) — cakupan penyedia + koneksi + model.
-## v3.8.0 Highlights
+## Sorotan v3.8.0
-- **Cloud Agents** (Codex Cloud, Devin, Jules) with task lifecycle management and management-auth enforcement
-- **Guardrails framework**: hot-reloadable registry with vision-bridge, pii-masker, prompt-injection
-- **9-factor Auto-Combo scoring** (was 6-factor in earlier versions)
-- **`reset-aware` routing strategy** (14th strategy) — picks the account whose quota will reset soonest
-- **A2A protocol expanded to 5 skills**: smart-routing, quota-management, provider-discovery, cost-analysis, health-report
-- **MCP server expanded to 37 tools** (30 base + 3 memory + 4 skills) across ~13 scopes
-- **OAuth providers expanded to 14**: added Qwen, Kiro, Qoder, Gemini, Windsurf, GitLab Duo
-- **Coverage gate raised to 75/75/75/70** (was 60% across the board) — measured ~82%
-- **Reasoning replay** (`docs/routing/REASONING_REPLAY.md`) — capture and inspect provider reasoning streams
-- **Compliance + Evals + Webhooks** documentation introduced
-- **Stealth guide** (`docs/security/STEALTH_GUIDE.md`) — TLS / CLI fingerprint configuration
-- **Tunnels guide** (`docs/ops/TUNNELS_GUIDE.md`) — Cloudflare tunnel management
-- **Electron guide** (`docs/guides/ELECTRON_GUIDE.md`) — desktop app build + signing
+- **Cloud Agents** (Codex Cloud, Devin, Jules) dengan manajemen siklus hidup tugas dan penegakan auth manajemen
+- **Kerangka Guardrails**: registri hot-reloadable dengan vision-bridge, pii-masker, prompt-injection
+- **Penilaian Auto-Combo 9-faktor** (sebelumnya 6-faktor pada versi sebelumnya)
+- **Strategi routing `reset-aware`** (strategi ke-14) — memilih akun yang kuotanya akan segera direset
+- **Protokol A2A diperluas ke 5 skills**: smart-routing, quota-management, provider-discovery, cost-analysis, health-report
+- **Server MCP diperluas ke 37 alat** (30 dasar + 3 memori + 4 skills) di ~13 cakupan
+- **Penyedia OAuth diperluas ke 14**: menambahkan Qwen, Kiro, Qoder, Gemini, Windsurf, GitLab Duo
+- **Gerbang cakupan dinaikkan ke 75/75/75/70** (sebelumnya 60% di semua bagian) — terukur ~82%
+- **Replay penalaran** (`docs/routing/REASONING_REPLAY.md`) — tangkap dan periksa aliran penalaran penyedia
+- **Dokumentasi Compliance + Evals + Webhooks** diperkenalkan
+- **Panduan stealth** (`docs/security/STEALTH_GUIDE.md`) — konfigurasi sidik jari TLS / CLI
+- **Panduan tunnel** (`docs/ops/TUNNELS_GUIDE.md`) — manajemen tunnel Cloudflare
+- **Panduan Electron** (`docs/guides/ELECTRON_GUIDE.md`) — build + penandatanganan aplikasi desktop
-## Links
+## Tautan
-- Repository: https://github.com/diegosouzapw/OmniRoute
-- Website: https://omniroute.online
+- Repositori: https://github.com/diegosouzapw/OmniRoute
+- Situs web: https://omniroute.online
- npm: https://www.npmjs.com/package/omniroute
- Docker Hub: https://hub.docker.com/r/diegosouzapw/omniroute
-- Documentation: See `/docs/` directory
+- Dokumentasi: Lihat direktori `/docs/`
-### Documentation Index
+### Indeks Dokumentasi
-- **Architecture & Reference**: `docs/architecture/ARCHITECTURE.md`, `docs/architecture/CODEBASE_DOCUMENTATION.md`, `docs/architecture/REPOSITORY_MAP.md`, `docs/reference/API_REFERENCE.md`, `docs/reference/PROVIDER_REFERENCE.md`, `docs/reference/openapi.yaml`
-- **Operator guides**: `docs/guides/USER_GUIDE.md`, `docs/reference/CLI-TOOLS.md`, `docs/guides/TROUBLESHOOTING.md`, `docs/ops/COVERAGE_PLAN.md`
-- **Protocols**: `docs/frameworks/MCP-SERVER.md`, `docs/frameworks/A2A-SERVER.md`, `docs/frameworks/AGENT_PROTOCOLS_GUIDE.md`, `docs/frameworks/CLOUD_AGENT.md`
+- **Arsitektur & Referensi**: `docs/architecture/ARCHITECTURE.md`, `docs/architecture/CODEBASE_DOCUMENTATION.md`, `docs/architecture/REPOSITORY_MAP.md`, `docs/reference/API_REFERENCE.md`, `docs/reference/PROVIDER_REFERENCE.md`, `docs/reference/openapi.yaml`
+- **Panduan operator**: `docs/guides/USER_GUIDE.md`, `docs/reference/CLI-TOOLS.md`, `docs/guides/TROUBLESHOOTING.md`, `docs/ops/COVERAGE_PLAN.md`
+- **Protokol**: `docs/frameworks/MCP-SERVER.md`, `docs/frameworks/A2A-SERVER.md`, `docs/frameworks/AGENT_PROTOCOLS_GUIDE.md`, `docs/frameworks/CLOUD_AGENT.md`
- **Routing & resilience**: `docs/routing/AUTO-COMBO.md`, `docs/architecture/RESILIENCE_GUIDE.md`
-- **Security**: `docs/architecture/AUTHZ_GUIDE.md`, `docs/security/GUARDRAILS.md`, `docs/security/COMPLIANCE.md`, `docs/security/STEALTH_GUIDE.md`
-- **Extensibility**: `docs/frameworks/SKILLS.md`, `docs/frameworks/MEMORY.md`, `docs/frameworks/EVALS.md`, `docs/frameworks/WEBHOOKS.md`, `docs/routing/REASONING_REPLAY.md`
+- **Keamanan**: `docs/architecture/AUTHZ_GUIDE.md`, `docs/security/GUARDRAILS.md`, `docs/security/COMPLIANCE.md`, `docs/security/STEALTH_GUIDE.md`
+- **Ekstensibilitas**: `docs/frameworks/SKILLS.md`, `docs/frameworks/MEMORY.md`, `docs/frameworks/EVALS.md`, `docs/frameworks/WEBHOOKS.md`, `docs/routing/REASONING_REPLAY.md`
- **Platform**: `docs/guides/ELECTRON_GUIDE.md`, `docs/ops/TUNNELS_GUIDE.md`
-- **AI agents**: `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`
+- **Agen AI**: `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`