docs(i18n): apply deep machine translation to 33 languages

This commit is contained in:
diegosouzapw 2026-04-06 18:14:01 -03:00
parent 5085dcf96f
commit fa886231d3
466 changed files with 92226 additions and 147160 deletions

File diff suppressed because it is too large Load diff

View file

@ -4,19 +4,13 @@
---
Thank you for your interest in contributing! This guide covers everything you need to get started.
---
Salamat sa iyong interes sa pag-aambag! Sinasaklaw ng gabay na ito ang lahat ng kailangan mo para makapagsimula.---
## Development Setup
### Prerequisites
- **Node.js** >= 18 < 24 (recommended: 22 LTS)
- **npm** 10+
- **Git**
### Clone & Install
-**Node.js**>= 18 < 24 (inirerekomenda: 22 LTS) -**npm**10+ -**Git**### Clone & Install
```bash
git clone https://github.com/diegosouzapw/OmniRoute.git
@ -35,28 +29,24 @@ echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env
```
Key variables for development:
Mga pangunahing variable para sa pag-unlad:
| 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 | Default ng Pag-unlad | Paglalarawan |
| ---------------------- | ------------------------ | ------------------------- | ---------------------- |
| `PORT` | `20128` | Port ng server |
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Base URL para sa frontend |
| `JWT_SECRET` | (bumuo sa itaas) | JWT signing secret |
| `INITIAL_PASSWORD` | `PALITAN` | Unang login password |
| `APP_LOG_LEVEL` | `impormasyon` | Log verbosity level | ### Dashboard Settings |
### Dashboard Settings
Nagbibigay ang dashboard ng mga toggle ng UI para sa mga feature na maaari ding i-configure sa pamamagitan ng mga variable ng kapaligiran:
The dashboard provides UI toggles for features that can also be configured via environment variables:
| Pagtatakda ng Lokasyon | I-toggle | Paglalarawan |
| --------------------------- | ------------------ | ----------------------------------------------------- |
| Mga Setting → Advanced | Debug Mode | Paganahin ang mga log ng kahilingan sa pag-debug (UI) |
| Mga Setting → Pangkalahatan | Sidebar Visibility | Ipakita/itago ang mga seksyon ng sidebar |
| Setting Location | Toggle | Description |
| ------------------- | ------------------ | ------------------------------ |
| Settings → Advanced | Debug Mode | Enable debug request logs (UI) |
| Settings → General | Sidebar Visibility | Show/hide sidebar sections |
These settings are stored in the database and persist across restarts, overriding env var defaults when set.
### Running Locally
Ang mga setting na ito ay naka-store sa database at nagpapatuloy sa mga pag-restart, na na-override ang mga env var default kapag nakatakda.### Running Locally
```bash
# Development mode (hot reload)
@ -70,51 +60,44 @@ npm run start
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
Default URLs:
Mga Default na URL:
- **Dashboard**: `http://localhost:20128/dashboard`
- **API**: `http://localhost:20128/v1`
---
-**Dashboard**: `http://localhost:20128/dashboard` -**API**: `http://localhost:20128/v1`---
## Git Workflow
> ⚠️ **NEVER commit directly to `main`.** Always use feature branches.
> ⚠️**NEVER commit directly to `main`.**Palaging gumamit ng mga feature branch.```bash
> git checkout -b feat/your-feature-name
```bash
git checkout -b feat/your-feature-name
# ... make changes ...
git commit -m "feat: describe your change"
git push -u origin feat/your-feature-name
# Open a Pull Request on GitHub
```
````
### Branch Naming
| Prefix | Purpose |
| ----------- | ------------------------- |
| `feat/` | New features |
| `fix/` | Bug fixes |
| `refactor/` | Code restructuring |
| `docs/` | Documentation changes |
| `test/` | Test additions/fixes |
| `chore/` | Tooling, CI, dependencies |
| Prefix | Layunin |
| ----------- | -------------------------- |
| `feat/` | Mga bagong feature |
| `ayusin/` | Mga pag-aayos ng bug |
| `refactor/` | Pag-aayos ng code |
| `docs/` | Mga pagbabago sa dokumentasyon |
| `pagsusulit/` | Mga pagdaragdag/pag-aayos ng pagsubok |
| `gawain/` | Tooling, CI, dependencies |### Commit Messages
### Commit Messages
Follow [Conventional Commits](https://www.conventionalcommits.org/):
```
Sundin ang [Conventional Commits](https://www.conventionalcommits.org/):```
feat: add circuit breaker for provider calls
fix: resolve JWT secret validation edge case
docs: update SECURITY.md with PII protection
test: add observability unit tests
refactor(db): consolidate rate limit tables
```
````
Scopes: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.
---
Mga Saklaw: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.---
## Running Tests
@ -146,48 +129,37 @@ npm run lint
npm run check
```
Coverage notes:
Mga tala sa saklaw:
- `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/COVERAGE_PLAN.md` for the phased coverage improvement roadmap
- Sinusukat ng `npm run test:coverage` ang source coverage para sa pangunahing unit test suite, hindi kasama ang `tests/**`, at may kasamang `open-sse/**`
- Ang mga kahilingan sa paghila ay dapat panatilihin ang kabuuang gate ng saklaw sa**60% o mas mataas**para sa mga pahayag, linya, function, at sangay
- Kung binago ng isang PR ang production code sa `src/`, `open-sse/`, `electron/`, o `bin/`, dapat itong magdagdag o mag-update ng mga automated na pagsubok sa parehong PR
- Ang `npm run coverage:report` ay nagpi-print ng detalyadong file-by-file na ulat mula sa pinakabagong coverage run
- Pinapanatili ng `npm run test:coverage:legacy` ang mas lumang sukatan para sa makasaysayang paghahambing
- Tingnan ang `docs/COVERAGE_PLAN.md` para sa phased na roadmap ng pagpapabuti ng coverage### Pull Request Requirements
### Pull Request Requirements
Bago buksan o pagsamahin ang isang PR:
Before opening or merging a PR:
- Patakbuhin ang `npm run test:unit`
- Patakbuhin ang `npm run test:coverage`
- Tiyaking mananatili ang gate ng coverage sa**60%+**para sa lahat ng sukatan
- Isama ang binago o idinagdag na mga test file sa paglalarawan ng PR kapag nagbago ang production code
- Suriin ang resulta ng SonarQube sa PR kapag ang mga lihim ng proyekto ay na-configure sa CI
- 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
Kasalukuyang status ng pagsubok:**122 unit test file**na sumasaklaw sa:
Current test status: **122 unit test files** covering:
- 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
---
- Tagasalin ng provider at conversion ng format
- Paglilimita sa rate, circuit breaker, at katatagan
- Semantic cache, idempotency, pagsubaybay sa pag-unlad
- Mga pagpapatakbo ng database at schema (21 DB modules)
- Mga daloy ng OAuth at pagpapatunay
- Pagpapatunay ng endpoint ng API (Zod v4)
- Mga tool sa server ng MCP at pagpapatupad ng saklaw
- Mga sistema ng Memory at Kasanayan---
## Code Style
- **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**— Patakbuhin ang `npm run lint` bago gumawa -**Prettier**— Awtomatikong na-format sa pamamagitan ng `lint-staged` sa commit (2 space, semicolon, double quotes, 100 char width, es5 trailing commas) -**TypeScript**— Lahat ng `src/` code ay gumagamit ng `.ts`/`.tsx`; Ang `open-sse/` ay gumagamit ng `.ts`/`.js`; dokumentong may TSDoc (`@param`, `@returns`, `@throws`) -**Walang `eval()`**— Ipinapatupad ng ESLint ang `no-eval`, `no-implied-eval`, `no-new-func` -**Pagpapatunay ng Zod**— Gumamit ng mga schema ng Zod v4 para sa lahat ng pagpapatunay ng input ng API -**Pagpapangalan**: Mga File = camelCase/kebab-case, mga bahagi = PascalCase, constants = UPPER_SNAKE---
## Project Structure
@ -256,56 +228,37 @@ docs/ # Documentation
### Step 1: Register Provider Constants
Add to `src/shared/constants/providers.ts` — Zod-validated at module load.
Idagdag sa `src/shared/constants/providers.ts` — Zod-validated sa module load.### Step 2: Add Executor (if custom logic needed)
### Step 2: Add Executor (if custom logic needed)
Gumawa ng executor sa `open-sse/executors/your-provider.ts` na nagpapalawak sa base executor.### Step 3: Add Translator (if non-OpenAI format)
Create executor in `open-sse/executors/your-provider.ts` extending the base executor.
Gumawa ng mga tagasalin ng kahilingan/tugon sa `open-sse/translator/`.### Step 4: Add OAuth Config (if OAuth-based)
### Step 3: Add Translator (if non-OpenAI format)
Magdagdag ng mga kredensyal ng OAuth sa `src/lib/oauth/constants/oauth.ts` at serbisyo sa `src/lib/oauth/services/`.### Step 5: Register Models
Create request/response translators in `open-sse/translator/`.
Magdagdag ng mga kahulugan ng modelo sa `open-sse/config/providerRegistry.ts`.### Step 6: Add Tests
### Step 4: Add OAuth Config (if OAuth-based)
Sumulat ng mga unit test sa `tests/unit/` na sumasaklaw nang hindi bababa sa:
Add OAuth credentials in `src/lib/oauth/constants/oauth.ts` and service in `src/lib/oauth/services/`.
### Step 5: Register Models
Add model definitions in `open-sse/config/providerRegistry.ts`.
### Step 6: Add Tests
Write unit tests in `tests/unit/` covering at minimum:
- Provider registration
- Request/response translation
- Error handling
---
- Pagpaparehistro ng provider
- Kahilingan/tugon sa pagsasalin
- Error sa paghawak---
## Pull Request Checklist
- [ ] 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)
---
- [ ] Mga test pass (`npm test`)
- [ ] Linting pass (`npm run lint`)
- [ ] Nagtagumpay ang Build (`npm run build`)
- [ ] Idinagdag ang mga uri ng TypeScript para sa mga bagong pampublikong function at interface
- [ ] Walang mga hardcoded na lihim o fallback na halaga
- [ ] Lahat ng mga input ay napatunayan gamit ang Zod schema
- [ ] CHANGELOG na-update (kung may pagbabago sa user)
- [ ] Na-update ang dokumentasyon (kung naaangkop)---
## Releasing
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.
---
Ang mga release ay pinamamahalaan sa pamamagitan ng `/generate-release` workflow. Kapag gumawa ng bagong GitHub Release, ang package ay**awtomatikong na-publish sa npm**sa pamamagitan ng GitHub Actions.---
## Getting Help
- **Architecture**: See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
- **API Reference**: See [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
- **ADRs**: See `docs/adr/` for architectural decision records
-**Arkitektura**: Tingnan ang [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) -**Reference ng API**: Tingnan ang [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) -**Mga Isyu**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -**Mga ADR**: Tingnan ang `docs/adr/` para sa mga talaan ng desisyon sa arkitektura

File diff suppressed because it is too large Load diff

View file

@ -6,156 +6,132 @@
## Reporting Vulnerabilities
If you discover a security vulnerability in OmniRoute, please report it responsibly:
Kung matuklasan mo ang isang kahinaan sa seguridad sa OmniRoute, mangyaring iulat ito nang responsable:
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.**HUWAG**magbukas ng pampublikong isyu sa GitHub 2. Gamitin ang [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new) 3. Isama ang: paglalarawan, mga hakbang sa pagpaparami, at potensyal na epekto## Response Timeline
## Response Timeline
| Yugto | Target |
| ------------------- | -------------------------------- | --------------------- |
| Pagkilala | 48 oras |
| Triage at Pagsusuri | 5 araw ng negosyo |
| Paglabas ng Patch | 14 na araw ng negosyo (kritikal) | ## Supported Versions |
| Stage | Target |
| ------------------- | --------------------------- |
| Acknowledgment | 48 hours |
| Triage & Assessment | 5 business days |
| Patch Release | 14 business days (critical) |
## Supported Versions
| Version | Support Status |
| ------- | -------------- |
| 3.4.x | ✅ Active |
| 3.0.x | ✅ Security |
| < 3.0.0 | Unsupported |
---
| Bersyon | Katayuan ng Suporta |
| ------- | ------------------- | --- |
| 3.4.x | ✅ Aktibo |
| 3.0.x | ✅ Seguridad |
| < 3.0.0 | Hindi suportado | --- |
## Security Architecture
OmniRoute implements a multi-layered security model:
```
Ang OmniRoute ay nagpapatupad ng isang multi-layered na modelo ng seguridad:```
Request → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider
```
`````
### 🔐 Authentication & Authorization
| 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 |
| Tampok | Pagpapatupad |
| -------------------- | -------------------------------------------------------- |
|**Pag-login sa Dashboard**| Nakabatay sa password ang auth na may mga JWT token (HttpOnly cookies) |
|**API Key Auth**| Mga susi na nilagdaan ng HMAC na may pagpapatunay ng CRC |
|**OAuth 2.0 + PKCE**| Secure na provider ng auth (Claude, Codex, Gemini, Cursor, atbp.) |
|**Token Refresh**| Awtomatikong pag-refresh ng token ng OAuth bago mag-expire |
|**Secure Cookies**| `AUTH_COOKIE_SECURE=true` para sa mga kapaligiran ng HTTPS |
|**Mga Saklaw ng MCP**| 10 butil na saklaw para sa MCP tool access control |### 🛡️ Encryption at Rest
### 🛡️ Encryption at Rest
Ang lahat ng sensitibong data na nakaimbak sa SQLite ay naka-encrypt gamit ang**AES-256-GCM**na may scrypt key derivation:
All sensitive data stored in SQLite is encrypted using **AES-256-GCM** with scrypt key derivation:
- API keys, access tokens, refresh tokens, and ID tokens
- Versioned format: `enc:v1:<iv>:<ciphertext>:<authTag>`
- Passthrough mode (plaintext) when `STORAGE_ENCRYPTION_KEY` is not set
```bash
- Mga API key, access token, refresh token, at ID token
- Bersyon na format: `enc:v1:<iv>:<ciphertext>:<authTag>`
- Passthrough mode (plaintext) kapag hindi nakatakda ang `STORAGE_ENCRYPTION_KEY````bash
# Generate encryption key:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
`````
### 🧠 Prompt Injection Guard
Middleware that detects and blocks prompt injection attacks in LLM requests:
Middleware na nakakakita at nagba-block ng mga agarang pag-atake ng injection sa mga kahilingan sa 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" |
| Uri ng Pattern | Kalubhaan | Halimbawa |
| ----------------------- | ---------- | ------------------------------------------------------------------------ |
| Override ng System | Mataas | "balewala ang lahat ng naunang tagubilin" |
| Pag-hijack ng Tungkulin | Mataas | "ikaw na DAN, kaya mong gawin ang lahat" |
| Delimiter Injection | Katamtaman | Mga naka-encode na separator upang masira ang mga hangganan ng konteksto |
| DAN/Jailbreak | Mataas | Mga kilalang pattern ng prompt ng jailbreak |
| Pagtuturo Leak | Katamtaman | "ipakita sa akin ang iyong system prompt" |
Configure via dashboard (Settings → Security) or `.env`:
```env
I-configure sa pamamagitan ng dashboard (Mga Setting → Seguridad) o `.env`:```env
INPUT_SANITIZER_ENABLED=true
INPUT_SANITIZER_MODE=block # warn | block | redact
```
INPUT_SANITIZER_MODE=block # warn | block | redact
````
### 🔒 PII Redaction
Automatic detection and optional redaction of personally identifiable information:
Awtomatikong pagtuklas at opsyonal na redaction ng personal na makikilalang impormasyon:
| 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]` |
```env
| Uri ng PII | Pattern | Pagpapalit |
| ------------- | ---------------------- | ------------------- |
| 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]` |
| Telepono | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
| SSN (US) | `123-45-6789` | `[SSN_REDACTED]` |```env
PII_REDACTION_ENABLED=true
```
````
### 🌐 Network Security
| 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 |
| Tampok | Paglalarawan |
| ------------------------ | ----------------------------------------------------------------------------------------- | -------------------------------- |
| **CORS** | Configurable origin control (`CORS_ORIGIN` env var, default `*`) |
| **Pag-filter ng IP** | Allowlist/blocklist na mga saklaw ng IP sa dashboard |
| **Paglilimita sa Rate** | Mga limitasyon sa rate ng bawat provider na may awtomatikong pag-urong |
| **Anti-Thundering Herd** | Pinipigilan ng Mutex + per-connection locking ang cascading 502s |
| **TLS Fingerprint** | Panggagaya ng fingerprint ng TLS na tulad ng browser upang bawasan ang pag-detect ng bot |
| **CLI Fingerprint** | Pag-order ng header/katawan ng bawat provider upang tumugma sa mga native na lagda ng CLI | ### 🔌 Resilience & Availability |
### 🔌 Resilience & Availability
| Tampok | Paglalarawan |
| --------------------------- | -------------------------------------------------------------------------- | ----------------- |
| **Circuit Breaker** | 3-estado (Sarado → Buksan → Half-Open) bawat provider, nanatili ang SQLite |
| **Humiling ng Idempotency** | 5-segundong de-dup window para sa mga duplicate na kahilingan |
| **Exponential Backoff** | Awtomatikong muling subukan na may dumaraming pagkaantala |
| **Dashboard ng Kalusugan** | Real-time na pagsubaybay sa kalusugan ng provider | ### 📋 Compliance |
| 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 |
### 📋 Compliance
| 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 |
---
| Tampok | Paglalarawan |
| ------------------------ | ------------------------------------------------------------------------------ | --- |
| **Pagpapanatili ng Log** | Awtomatikong paglilinis pagkatapos ng `CALL_LOG_RETENTION_DAYS` |
| **No-Log Opt-out** | Bawat API key na flag na `noLog` ay hindi pinapagana ang pag-log ng kahilingan |
| **Audit Log** | Mga administratibong pagkilos na sinusubaybayan sa talahanayan ng `audit_log` |
| **MCP Audit** | SQLite-backed audit logging para sa lahat ng MCP tool call |
| **Pagpapatunay ng Zod** | Na-validate ang lahat ng API input gamit ang Zod v4 schemas sa module load | --- |
## Required Environment Variables
All secrets must be set before starting the server. The server will **fail fast** if they are missing or weak.
Ang lahat ng mga lihim ay dapat itakda bago simulan ang server. Ang server ay**mabibigo nang mabilis**kung sila ay nawawala o mahina.```bash
```bash
# REQUIRED — server will not start without these:
JWT_SECRET=$(openssl rand -base64 48) # min 32 chars
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
# RECOMMENDED — enables encryption at rest:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
The server actively rejects known-weak values like `changeme`, `secret`, or `password`.
````
---
Aktibong tinatanggihan ng server ang mga kilalang-mahina na halaga tulad ng `changeme`, `secret`, o `password`.---
## Docker Security
- 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
```bash
- Gumamit ng non-root user sa produksyon
- I-mount ang mga lihim bilang read-only na volume
- Huwag kailanman kopyahin ang mga `.env` na file sa mga larawan ng Docker
- Gamitin ang `.dockerignore` upang ibukod ang mga sensitibong file
- Itakda ang `AUTH_COOKIE_SECURE=true` kapag nasa likod ng HTTPS```bash
docker run -d \
--name omniroute \
--restart unless-stopped \
@ -166,14 +142,14 @@ docker run -d \
-e API_KEY_SECRET="$(openssl rand -hex 32)" \
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
diegosouzapw/omniroute:latest
```
````
---
## Dependencies
- 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`)
- Patakbuhin ang `npm audit` nang regular
- Panatilihing na-update ang mga dependency
- Gumagamit ang proyekto ng `husky` + `lint-staged` para sa mga pre-commit na pagsusuri
- Ang CI pipeline ay nagpapatakbo ng mga panuntunan sa seguridad ng ESLint sa bawat push
- Na-validate ang mga constant ng provider sa pag-load ng module sa pamamagitan ng Zod (`src/shared/validation/providerSchema.ts`)

View file

@ -4,37 +4,28 @@
---
> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent
## Agent Discovery
> Agent-to-Agent Protocol v0.3 — OmniRoute bilang isang matalinong ahente sa pagruruta## Agent Discovery
```bash
curl http://localhost:20128/.well-known/agent.json
```
Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements.
---
Ibinabalik ang Agent Card na naglalarawan sa mga kakayahan, kasanayan, at kinakailangan sa pagpapatotoo ng OmniRoute.---
## Authentication
All `/a2a` requests require an API key via the `Authorization` header:
```
Lahat ng hiling na `/a2a` ay nangangailangan ng API key sa pamamagitan ng header ng `Authorization`:```
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
```
If no API key is configured on the server, authentication is bypassed.
````
---
Kung walang API key na naka-configure sa server, ang pagpapatotoo ay na-bypass.---
## JSON-RPC 2.0 Methods
### `message/send` — Synchronous Execution
Sends a message to a skill and waits for the complete response.
```bash
Nagpapadala ng mensahe sa isang kasanayan at naghihintay para sa kumpletong tugon.```bash
curl -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
@ -48,34 +39,31 @@ curl -X POST http://localhost:20128/a2a \
"metadata": {"model": "auto", "combo": "fast-coding"}
}
}'
```
````
**Response:**
```json
**Tugon:**```json
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"task": { "id": "uuid", "state": "completed" },
"artifacts": [{ "type": "text", "content": "..." }],
"metadata": {
"routing_explanation": "Selected claude-sonnet via provider \"anthropic\" (latency: 1200ms, cost: $0.003)",
"cost_envelope": { "estimated": 0.005, "actual": 0.003, "currency": "USD" },
"resilience_trace": [
{ "event": "primary_selected", "provider": "anthropic", "timestamp": "..." }
],
"policy_verdict": { "allowed": true, "reason": "within budget and quota limits" }
}
}
"jsonrpc": "2.0",
"id": "1",
"result": {
"task": { "id": "uuid", "state": "completed" },
"artifacts": [{ "type": "text", "content": "..." }],
"metadata": {
"routing_explanation": "Selected claude-sonnet via provider \"anthropic\" (latency: 1200ms, cost: $0.003)",
"cost_envelope": { "estimated": 0.005, "actual": 0.003, "currency": "USD" },
"resilience_trace": [
{ "event": "primary_selected", "provider": "anthropic", "timestamp": "..." }
],
"policy_verdict": { "allowed": true, "reason": "within budget and quota limits" }
}
```
}
}
````
### `message/stream` — SSE Streaming
Same as `message/send` but returns Server-Sent Events for real-time streaming.
```bash
Kapareho ng `mensahe/ipadala` ngunit ibinabalik ang Mga Kaganapang Ipinadala ng Server para sa real-time na streaming.```bash
curl -N -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
@ -88,17 +76,16 @@ curl -N -X POST http://localhost:20128/a2a \
"messages": [{"role": "user", "content": "Explain quantum computing"}]
}
}'
```
````
**SSE Events:**
```
**Mga Kaganapan sa SSE:**```
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"..."}}}
: heartbeat 2026-03-03T17:00:00Z
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
```
````
### `tasks/get` — Query Task Status
@ -107,7 +94,7 @@ curl -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}'
```
````
### `tasks/cancel` — Cancel a Task
@ -122,12 +109,10 @@ curl -X POST http://localhost:20128/a2a \
## Available Skills
| 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. |
---
| Kasanayan | Paglalarawan |
| :----------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |
| `smart-routing` | Nag-prompt ang mga ruta sa pamamagitan ng intelligent na pipeline ng OmniRoute. Nagbabalik ng tugon na may paliwanag sa pagruruta, gastos, at bakas ng katatagan. |
| `quota-management` | Sumasagot sa mga query sa natural na wika tungkol sa mga quota ng provider, nagmumungkahi ng mga libreng combo, at nagbibigay ng mga ranking ng quota. | --- |
## Task Lifecycle
@ -137,23 +122,19 @@ submitted → working → completed
→ cancelled
```
- Tasks expire after 5 minutes (configurable)
- Mag-e-expire ang mga gawain pagkalipas ng 5 minuto (mako-configure)
- Terminal states: `completed`, `failed`, `cancelled`
- Event log tracks every state transition
---
- Sinusubaybayan ng log ng kaganapan ang bawat paglipat ng estado---
## Error Codes
| Code | Meaning |
| :----- | :----------------------------- |
| -32700 | Parse error (invalid JSON) |
| -32600 | Invalid request / Unauthorized |
| -32601 | Method or skill not found |
| -32602 | Invalid params |
| -32603 | Internal error |
---
| Code | Ibig sabihin |
| :----- | :----------------------------------------- | --- |
| -32700 | Error sa pag-parse (di-wastong JSON) |
| -32600 | Di-wastong kahilingan / Hindi awtorisado |
| -32601 | Hindi natagpuan ang pamamaraan o kasanayan |
| -32602 | Di-wastong mga param |
| -32603 | Panloob na error | --- |
## Integration Examples

View file

@ -4,23 +4,19 @@
---
Complete reference for all OmniRoute API endpoints.
---
Kumpletong sanggunian para sa lahat ng endpoint ng OmniRoute API.---
## Table of Contents
- [Chat Completions](#chat-completions)
- [Embeddings](#embeddings)
- [Image Generation](#image-generation)
- [Mga Pagkumpleto sa Chat](#chat-completions)
- [Mga Embedding](#embeddings)
- [Pagbuo ng Larawan](#pagbuo ng larawan)
- [List Models](#list-models)
- [Compatibility Endpoints](#compatibility-endpoints)
- [Semantic Cache](#semantic-cache)
- [Dashboard & Management](#dashboard--management)
- [Request Processing](#request-processing)
- [Authentication](#authentication)
---
- [Dashboard at Pamamahala](#dashboard--pamamahala)
- [Pagproseso ng Kahilingan](#request-processing)
- [Authentication](#authentication)---
## Chat Completions
@ -40,22 +36,20 @@ Content-Type: application/json
### Custom Headers
| 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 | Direksyon | Paglalarawan |
| ------------------------ | ---------- | ------------------------------------------------------------ |
| `X-OmniRoute-No-Cache` | Kahilingan | Itakda sa `true` para i-bypass ang cache |
| `X-OmniRoute-Progress` | Kahilingan | Itakda sa `true` para sa mga kaganapan sa pag-unlad |
| `X-Session-Id` | Kahilingan | Malagkit na session key para sa external na session affinity |
| `x_session_id` | Kahilingan | Tinanggap din ang variant ng underscore (direktang HTTP) |
| `Idempotency-Key` | Kahilingan | Dedup key (5s window) |
| `X-Request-Id` | Kahilingan | Alternatibong susi sa pagtanggal |
| `X-OmniRoute-Cache` | Tugon | `HIT` o `MISS` (non-streaming) |
| `X-OmniRoute-Idempotent` | Tugon | `true` kung i-deduplicate |
| `X-OmniRoute-Progress` | Tugon | `enabled` kung ang pagsubaybay sa pag-usad sa |
| `X-OmniRoute-Session-Id` | Tugon | Epektibong session ID na ginagamit ng OmniRoute |
> Nginx note: if you rely on underscore headers (for example `x_session_id`), enable `underscores_in_headers on;`.
---
> Nginx note: kung umaasa ka sa mga underscore na header (halimbawa `x_session_id`), paganahin ang `underscores_in_headers on;`.---
## Embeddings
@ -70,12 +64,13 @@ Content-Type: application/json
}
```
Available providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
Mga available na provider: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.```bash
```bash
# List all embedding models
GET /v1/embeddings
```
````
---
@ -91,14 +86,15 @@ Content-Type: application/json
"prompt": "A beautiful sunset over mountains",
"size": "1024x1024"
}
```
````
Available providers: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
Mga available na provider: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.```bash
```bash
# List all image models
GET /v1/images/generations
```
````
---
@ -109,26 +105,24 @@ GET /v1/models
Authorization: Bearer your-api-key
→ Returns all chat, embedding, and image models + combos in OpenAI format
```
````
---
## Compatibility Endpoints
| Method | Path | Format |
| ------ | --------------------------- | ---------------------- |
| Paraan | Landas | Format |
| ------ | --------------------------- | ---------------------- | ----------------------------- |
| POST | `/v1/chat/completions` | OpenAI |
| POST | `/v1/messages` | Anthropic |
| POST | `/v1/responses` | OpenAI Responses |
| POST | `/v1/mensahe` | Antropiko |
| POST | `/v1/mga tugon` | Mga Tugon sa OpenAI |
| POST | `/v1/embeddings` | OpenAI |
| POST | `/v1/images/generations` | OpenAI |
| GET | `/v1/models` | OpenAI |
| POST | `/v1/messages/count_tokens` | Anthropic |
| GET | `/v1beta/models` | Gemini |
| KUMUHA | `/v1/mga modelo` | OpenAI |
| POST | `/v1/messages/count_tokens` | Antropiko |
| KUMUHA | `/v1beta/mga modelo` | Gemini |
| POST | `/v1beta/models/{...path}` | Gemini generateContent |
| POST | `/v1/api/chat` | Ollama |
### Dedicated Provider Routes
| POST | `/v1/api/chat` | Ollama | ### Dedicated Provider Routes |
```bash
POST /v1/providers/{provider}/chat/completions
@ -136,9 +130,7 @@ POST /v1/providers/{provider}/embeddings
POST /v1/providers/{provider}/images/generations
```
The provider prefix is auto-added if missing. Mismatched models return `400`.
---
Ang prefix ng provider ay awtomatikong idinaragdag kung nawawala. Ang mga hindi tugmang modelo ay nagbabalik ng `400`.---
## Semantic Cache
@ -150,22 +142,21 @@ GET /api/cache/stats
DELETE /api/cache/stats
```
Response example:
```json
Halimbawa ng tugon:```json
{
"semanticCache": {
"memorySize": 42,
"memoryMaxSize": 500,
"dbSize": 128,
"hitRate": 0.65
},
"idempotency": {
"activeKeys": 3,
"windowMs": 5000
}
"semanticCache": {
"memorySize": 42,
"memoryMaxSize": 500,
"dbSize": 128,
"hitRate": 0.65
},
"idempotency": {
"activeKeys": 3,
"windowMs": 5000
}
```
}
````
---
@ -173,165 +164,129 @@ Response example:
### Authentication
| Endpoint | Method | Description |
| ----------------------------- | ------- | --------------------- |
| `/api/auth/login` | POST | Login |
| `/api/auth/logout` | POST | Logout |
| `/api/settings/require-login` | GET/PUT | Toggle login required |
| Endpoint | Paraan | Paglalarawan |
| ----------------------------- | ------- | ---------------------- |
| `/api/auth/login` | POST | Mag-login |
| `/api/auth/logout` | POST | Logout |
| `/api/settings/require-login` | GET/PUT | Kailangang i-toggle ang pag-login |### Provider Management
### Provider Management
| Endpoint | Paraan | Paglalarawan |
| ---------------------------- | --------------- | ------------------------- |
| `/api/providers` | GET/POST | Maglista / gumawa ng mga provider |
| `/api/providers/[id]` | GET/PUT/DELETE | Pamahalaan ang isang provider |
| `/api/providers/[id]/test` | POST | Subukan ang koneksyon ng provider |
| `/api/providers/[id]/models` | KUMUHA | Maglista ng mga modelo ng provider |
| `/api/providers/validate` | POST | I-validate ang config ng provider |
| `/api/provider-nodes*` | Iba't ibang | Pamamahala ng node ng provider |
| `/api/provider-models` | GET/POST/DELETE | Mga custom na modelo |### OAuth Flows
| 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/DELETE | Custom models |
| Endpoint | Paraan | Paglalarawan |
| -------------------------------- | ------- | ------------------------ |
| `/api/oauth/[provider]/[action]` | Iba't ibang | OAuth na partikular sa provider |### Routing & Config
### OAuth Flows
| Endpoint | Paraan | Paglalarawan |
| ---------------------- | -------- | ----------------------------- |
| `/api/models/alias` | GET/POST | Mga alyas ng modelo |
| `/api/models/catalog` | KUMUHA | Lahat ng modelo ayon sa provider + uri |
| `/api/combos*` | Iba't ibang | Pamamahala ng combo |
| `/api/keys*` | Iba't ibang | Pamamahala ng key ng API |
| `/api/pricing` | KUMUHA | Pagpepresyo ng modelo |### Usage & Analytics
| Endpoint | Method | Description |
| -------------------------------- | ------- | ----------------------- |
| `/api/oauth/[provider]/[action]` | Various | Provider-specific OAuth |
### Routing & Config
| 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 |
### Usage & Analytics
| Endpoint | Method | Description |
| Endpoint | Paraan | Paglalarawan |
| --------------------------- | ------ | -------------------- |
| `/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 |
| `/api/usage/history` | KUMUHA | Kasaysayan ng paggamit |
| `/api/usage/logs` | KUMUHA | Mga log ng paggamit |
| `/api/usage/request-logs` | KUMUHA | Mga log sa antas ng kahilingan |
| `/api/usage/[connectionId]` | KUMUHA | Paggamit sa bawat koneksyon |### Settings
### Settings
| Endpoint | Paraan | Paglalarawan |
| ------------------------------- | ------------- | ----------------------- |
| `/api/setting` | GET/PUT/PATCH | Mga pangkalahatang setting |
| `/api/setting/proxy` | GET/PUT | Network proxy config |
| `/api/settings/proxy/test` | POST | Subukan ang proxy na koneksyon |
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist |
| `/api/settings/thinking-budget` | GET/PUT | Rasoning token budget |
| `/api/setting/system-prompt` | GET/PUT | Global system prompt |### Monitoring
| 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 |
| Endpoint | Paraan | Paglalarawan |
| ------------------------- | ---------- | --------------------------------------------------------------------------------------------------- |
| `/api/sessions` | KUMUHA | Aktibong pagsubaybay sa session |
| `/api/rate-limits` | KUMUHA | Mga limitasyon sa rate ng bawat account |
| `/api/monitoring/health` | KUMUHA | Pagsusuri sa kalusugan + buod ng provider (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
| `/api/cache/stats` | GET/DELETE | Mga istatistika ng cache / i-clear |### Backup & Export/Import
### Monitoring
| 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 |
### Backup & Export/Import
| Endpoint | Method | Description |
| Endpoint | Paraan | Paglalarawan |
| --------------------------- | ------ | --------------------------------------- |
| `/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 |
| `/api/db-backups` | KUMUHA | Maglista ng mga available na backup |
| `/api/db-backups` | ILAGAY | Gumawa ng manu-manong backup |
| `/api/db-backups` | POST | Ibalik mula sa isang partikular na backup |
| `/api/db-backups/export` | KUMUHA | I-download ang database bilang .sqlite file |
| `/api/db-backups/import` | POST | Mag-upload ng .sqlite file upang palitan ang database |
| `/api/db-backups/exportAll` | KUMUHA | I-download ang buong backup bilang .tar.gz archive |### Cloud Sync
### Cloud Sync
| Endpoint | Paraan | Paglalarawan |
| ----------------------- | ------- | ---------------------- |
| `/api/sync/cloud` | Iba't ibang | Mga pagpapatakbo ng cloud sync |
| `/api/sync/initialize` | POST | Simulan ang pag-sync |
| `/api/cloud/*` | Iba't ibang | Pamamahala ng ulap |### Tunnels
| Endpoint | Method | Description |
| ---------------------- | ------- | --------------------- |
| `/api/sync/cloud` | Various | Cloud sync operations |
| `/api/sync/initialize` | POST | Initialize sync |
| `/api/cloud/*` | Various | Cloud management |
| Endpoint | Paraan | Paglalarawan |
| -------------------------- | ------ | ---------------------------------------------------------------------- |
| `/api/tunnels/cloudflared` | KUMUHA | Basahin ang Cloudflare Quick Tunnel install/runtime status para sa dashboard |
| `/api/tunnels/cloudflared` | POST | Paganahin o huwag paganahin ang Cloudflare Quick Tunnel (`action=enable/disable`) |### CLI Tools
### Tunnels
| Endpoint | Paraan | Paglalarawan |
| ------------------------------------ | ------ | ------------------- |
| `/api/cli-tools/claude-settings` | KUMUHA | Claude CLI status |
| `/api/cli-tools/codex-settings` | KUMUHA | Katayuan ng Codex CLI |
| `/api/cli-tools/droid-settings` | KUMUHA | Katayuan ng Droid CLI |
| `/api/cli-tools/openclaw-settings` | KUMUHA | Katayuan ng OpenClaw CLI |
| `/api/cli-tools/runtime/[toolId]` | KUMUHA | Generic na CLI runtime |
| 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`) |
Kasama sa mga tugon ng CLI ang: `naka-install`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.### ACP Agents
### CLI Tools
| 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 |
CLI responses include: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
### ACP Agents
| Endpoint | Method | Description |
| Endpoint | Paraan | Paglalarawan |
| ----------------- | ------ | -------------------------------------------------------- |
| `/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 |
| `/api/acp/agents` | KUMUHA | Ilista ang lahat ng nakitang ahente (built-in + custom) na may status |
| `/api/acp/agents` | POST | Magdagdag ng custom na ahente o i-refresh ang detection cache |
| `/api/acp/agents` | TANGGALIN | Mag-alis ng custom na ahente sa pamamagitan ng `id` query param |
GET response includes `agents[]` (id, name, binary, version, installed, protocol, isCustom) and `summary` (total, installed, notFound, builtIn, custom).
Kasama sa tugon ng GET ang `mga ahente[]` (id, pangalan, binary, bersyon, naka-install, protocol, isCustom) at `buod` (kabuuan, naka-install, hindi nahanap, builtIn, custom).### Resilience & Rate Limits
### Resilience & Rate Limits
| Endpoint | Paraan | Paglalarawan |
| ------------------------ | --------- | ------------------------------- |
| `/api/resilience` | GET/PATCH | Kumuha/mag-update ng mga profile ng resilience |
| `/api/resilience/reset` | POST | I-reset ang mga circuit breaker |
| `/api/rate-limits` | KUMUHA | Katayuan ng limitasyon sa rate ng bawat account |
| `/api/rate-limit` | KUMUHA | Pagsasaayos ng limitasyon sa pandaigdigang rate |### Evals
| Endpoint | Method | Description |
| ----------------------- | --------- | ------------------------------- |
| `/api/resilience` | GET/PATCH | Get/update resilience profiles |
| `/api/resilience/reset` | POST | Reset circuit breakers |
| `/api/rate-limits` | GET | Per-account rate limit status |
| `/api/rate-limit` | GET | Global rate limit configuration |
### Evals
| Endpoint | Method | Description |
| Endpoint | Paraan | Paglalarawan |
| ------------ | -------- | --------------------------------- |
| `/api/evals` | GET/POST | List eval suites / run evaluation |
| `/api/evals` | GET/POST | Maglista ng mga eval suite / run evaluation |### Policies
### Policies
| Endpoint | Paraan | Paglalarawan |
| --------------- | --------------- | ------------------------ |
| `/api/policies` | GET/POST/DELETE | Pamahalaan ang mga patakaran sa pagruruta |### Compliance
| Endpoint | Method | Description |
| --------------- | --------------- | ----------------------- |
| `/api/policies` | GET/POST/DELETE | Manage routing policies |
### Compliance
| Endpoint | Method | Description |
| Endpoint | Paraan | Paglalarawan |
| --------------------------- | ------ | ----------------------------- |
| `/api/compliance/audit-log` | GET | Compliance audit log (last N) |
| `/api/compliance/audit-log` | KUMUHA | Log ng audit ng pagsunod (huling N) |### v1beta (Gemini-Compatible)
### v1beta (Gemini-Compatible)
| Endpoint | Method | Description |
| Endpoint | Paraan | Paglalarawan |
| -------------------------- | ------ | --------------------------------- |
| `/v1beta/models` | GET | List models in Gemini format |
| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint |
| `/v1beta/mga modelo` | KUMUHA | Listahan ng mga modelo sa Gemini format |
| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint |
These endpoints mirror Gemini's API format for clients that expect native Gemini SDK compatibility.
Ang mga endpoint na ito ay sumasalamin sa format ng API ng Gemini para sa mga kliyenteng umaasa sa native na Gemini SDK compatibility.### Internal / System APIs
### Internal / System APIs
| Endpoint | Method | Description |
| Endpoint | Paraan | Paglalarawan |
| --------------- | ------ | ---------------------------------------------------- |
| `/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/init` | KUMUHA | Pagsusuri sa pagsisimula ng application (ginamit sa unang pagtakbo) |
| `/api/tags` | KUMUHA | Mga tag ng modelong katugma sa Ollama (para sa mga kliyente ng Ollama) |
| `/api/restart` | POST | I-trigger ang magandang pag-restart ng server |
| `/api/shutdown` | POST | Mag-trigger ng magandang pag-shutdown ng server |
> **Note:** These endpoints are used internally by the system or for Ollama client compatibility. They are not typically called by end users.
---
>**Tandaan:**Ang mga endpoint na ito ay panloob na ginagamit ng system o para sa Ollama client compatibility. Hindi sila karaniwang tinatawag ng mga end user.---
## Audio Transcription
@ -339,69 +294,63 @@ These endpoints mirror Gemini's API format for clients that expect native Gemini
POST /v1/audio/transcriptions
Authorization: Bearer your-api-key
Content-Type: multipart/form-data
```
````
Transcribe audio files using Deepgram or AssemblyAI.
I-transcribe ang mga audio file gamit ang Deepgram o AssemblyAI.
**Request:**
```bash
**Kahilingan:**```bash
curl -X POST http://localhost:20128/v1/audio/transcriptions \
-H "Authorization: Bearer your-api-key" \
-F "file=@recording.mp3" \
-F "model=deepgram/nova-3"
```
-H "Authorization: Bearer your-api-key" \
-F "file=@recording.mp3" \
-F "model=deepgram/nova-3"
**Response:**
````
```json
**Tugon:**```json
{
"text": "Hello, this is the transcribed audio content.",
"task": "transcribe",
"language": "en",
"duration": 12.5
}
```
````
**Supported providers:** `deepgram/nova-3`, `assemblyai/best`.
**Mga sinusuportahang provider:**`deepgram/nova-3`, `assemblyai/best`.
**Supported formats:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
---
**Mga sinusuportahang format:**`mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.---
## Ollama Compatibility
For clients that use Ollama's API format:
Para sa mga kliyenteng gumagamit ng format ng API ng Ollama:```bash
```bash
# Chat endpoint (Ollama format)
POST /v1/api/chat
# Model listing (Ollama format)
GET /api/tags
```
Requests are automatically translated between Ollama and internal formats.
````
---
Awtomatikong isinasalin ang mga kahilingan sa pagitan ng Ollama at mga panloob na format.---
## Telemetry
```bash
# Get latency telemetry summary (p50/p95/p99 per provider)
GET /api/telemetry/summary
```
````
**Response:**
```json
**Tugon:**```json
{
"providers": {
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
}
"providers": {
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
}
```
}
````
---
@ -420,7 +369,7 @@ Content-Type: application/json
"limit": 50.00,
"period": "monthly"
}
```
````
---
@ -443,23 +392,21 @@ Content-Type: application/json
## Request Processing
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. Nagpapadala ang kliyente ng kahilingan sa `/v1/*`
2. Tumatawag ang tagapangasiwa ng ruta ng `handleChat`, `handleEmbedding`, `handleAudioTranscription`, o `handleImageGeneration`
3. Nalutas ang modelo (direktang provider/modelo o alias/combo)
4. Pinili ang mga kredensyal mula sa lokal na DB na may pagsasala ng availability ng account
5. Para sa chat: `handleChatCore` — format detection, translation, cache check, idempotency check
6. Nagpapadala ang tagapagpatupad ng provider ng upstream na kahilingan
7. Ang tugon ay isinalin pabalik sa format ng kliyente (chat) o ibinalik sa dati (mga pag-embed/mga larawan/audio)
8. Naitala ang paggamit/pag-log
9. Nalalapat ang Fallback sa mga error ayon sa combo rules
Full architecture reference: [`ARCHITECTURE.md`](ARCHITECTURE.md)
---
Buong sanggunian sa arkitektura: [`ARCHITECTURE.md`](ARCHITECTURE.md)---
## Authentication
- 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`
- Gumagamit ang mga ruta ng dashboard (`/dashboard/*`) ng cookie ng `auth_token`
- Gumagamit ang pag-login ng naka-save na hash ng password; fallback sa `INITIAL_PASSWORD`
- `requireLogin` toggleable sa pamamagitan ng `/api/settings/require-login`
- Opsyonal na nangangailangan ang mga ruta ng `/v1/*` ng Bearer API key kapag `REQUIRE_API_KEY=true`

View file

@ -4,90 +4,80 @@
---
_Last updated: 2026-03-28_
_Huling na-update: 2026-03-28_## Executive Summary
## Executive Summary
Ang OmniRoute ay isang lokal na AI routing gateway at dashboard na binuo sa Next.js.
Nagbibigay ito ng isang endpoint na katugma sa OpenAI (`/v1/*`) at niruruta ang trapiko sa maraming upstream provider na may pagsasalin, fallback, pag-refresh ng token, at pagsubaybay sa paggamit.
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.
Mga pangunahing kakayahan:
Core capabilities:
- OpenAI-compatible API surface for CLI/tools (28 providers)
- Request/response translation across provider formats
- Model combo fallback (multi-model sequence)
- Account-level fallback (multi-account per provider)
- OAuth + API-key provider connection management
- Embedding generation via `/v1/embeddings` (6 providers, 9 models)
- Image generation via `/v1/images/generations` (4 providers, 9 models)
- Think tag parsing (`<think>...</think>`) for reasoning models
- Response sanitization for strict OpenAI SDK compatibility
- Role normalization (developer→system, system→user) for cross-provider compatibility
- OpenAI-compatible na API surface para sa CLI/tools (28 provider)
- Kahilingan/tugon sa pagsasalin sa mga format ng provider
- Modelong combo fallback (multi-model sequence)
- Account-level fallback (multi-account bawat provider)
- Pamamahala ng koneksyon ng provider ng OAuth + API-key
- Pagbuo ng pag-embed sa pamamagitan ng `/v1/embeddings` (6 na provider, 9 na modelo)
- Pagbuo ng larawan sa pamamagitan ng `/v1/images/generations` (4 na provider, 9 na modelo)
- Isipin ang pag-parse ng tag (`<think>...</think>`) para sa mga modelo ng pangangatwiran
- Response sanitization para sa mahigpit na OpenAI SDK compatibility
- Pag-normalize ng tungkulin (developer→system, system→user) para sa cross-provider compatibility
- Structured output conversion (json_schema → Gemini responseSchema)
- Local persistence for providers, keys, aliases, combos, settings, pricing
- 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)
- Lokal na pagtitiyaga para sa mga provider, key, alias, combo, setting, pagpepresyo
- Pagsubaybay sa paggamit/gastos at pag-log ng kahilingan
- Opsyonal na cloud sync para sa multi-device/state sync
- IP allowlist/blocklist para sa API access control
- Pag-iisip ng pamamahala sa badyet (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: model availability, cost rules, fallback policy, lockout policy
- 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
- 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
- Resilience UI dashboard with real-time circuit breaker status
- Modular OAuth providers (12 individual modules under `src/lib/oauth/providers/`)
- Pagsubaybay sa session at fingerprinting
- Paglilimita sa pinahusay na rate ng bawat account gamit ang mga profile na partikular sa provider
- Pattern ng circuit breaker para sa katatagan ng provider
- Proteksyon laban sa dumadagundong na kawan na may mutex locking
- Nakabatay sa lagda ang cache ng pag-deduplication ng kahilingan
- Layer ng domain: availability ng modelo, mga panuntunan sa gastos, patakaran sa fallback, patakaran sa lockout
- Pananatili ng estado ng domain (SQLite write-through cache para sa mga fallback, badyet, lockout, circuit breaker)
- Policy engine para sa sentralisadong pagsusuri ng kahilingan (lockout → budget → fallback)
- Humiling ng telemetry na may p50/p95/p99 latency aggregation
- Correlation ID (X-Request-Id) para sa end-to-end na pagsubaybay
- Pag-log sa audit ng pagsunod gamit ang opt-out sa bawat API key
- Eval framework para sa LLM quality assurance
- Resilience UI dashboard na may real-time na status ng circuit breaker
- Modular OAuth providers (12 indibidwal na module sa ilalim ng `src/lib/oauth/providers/`)
Primary runtime model:
Pangunahing modelo ng runtime:
- 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
## Scope and Boundaries
- Ang mga ruta ng Next.js app sa ilalim ng `src/app/api/*` ay nagpapatupad ng parehong dashboard API at compatibility API
- Isang nakabahaging SSE/routing core sa `src/sse/*` + `open-sse/*` ang humahawak sa pagpapatupad ng provider, pagsasalin, streaming, fallback, at paggamit## Scope and Boundaries
### In Scope
- Local gateway runtime
- Dashboard management APIs
- Provider authentication and token refresh
- Request translation and SSE streaming
- Local state + usage persistence
- Optional cloud sync orchestration
- Lokal na gateway runtime
- Mga API sa pamamahala ng dashboard
- Pagpapatunay ng provider at pag-refresh ng token
- Humiling ng pagsasalin at SSE streaming
- Lokal na estado + pagtitiyaga sa paggamit
- Opsyonal na cloud sync orchestration### Out of Scope
### Out of Scope
- Pagpapatupad ng serbisyo sa cloud sa likod ng `NEXT_PUBLIC_CLOUD_URL`
- Provider SLA/control plane sa labas ng lokal na proseso
- Mga panlabas na CLI binary mismo (Claude CLI, Codex CLI, atbp.)## Dashboard Surface (Current)
- Cloud service implementation behind `NEXT_PUBLIC_CLOUD_URL`
- Provider SLA/control plane outside local process
- External CLI binaries themselves (Claude CLI, Codex CLI, etc.)
Mga pangunahing pahina sa ilalim ng `src/app/(dashboard)/dashboard/`:
## Dashboard Surface (Current)
Main pages under `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, model routing rules
- `/dashboard/costs` — cost aggregation and pricing visibility
- `/dashboard/analytics` — usage analytics and evaluations
- `/dashboard/limits` — quota/rate controls
- `/dashboard` — mabilis na pagsisimula + pangkalahatang-ideya ng provider
- `/dashboard/endpoint` — endpoint proxy + MCP + A2A + API endpoint na mga tab
- `/dashboard/providers` — mga koneksyon at kredensyal ng provider
- `/dashboard/combos` — mga combo na diskarte, mga template, mga panuntunan sa pagruruta ng modelo
- `/dashboard/costs` — pagsasama-sama ng gastos at visibility ng pagpepresyo
- `/dashboard/analytics` — analytics ng paggamit at mga pagsusuri
- `/dashboard/limits` — mga kontrol sa quota/rate
- `/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
- `/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
## High-Level System Context
- `/dashboard/agents` — nakitang mga ahente ng ACP + pagpaparehistro ng custom na ahente
- `/dashboard/media` — larawan/video/palaruan ng musika
- `/dashboard/search-tools` — pagsubok at kasaysayan ng provider ng paghahanap
- `/dashboard/health` — uptime, mga circuit breaker, mga limitasyon sa rate
- `/dashboard/logs` — kahilingan/proxy/audit/console log
- `/dashboard/settings` — mga tab ng mga setting ng system (pangkalahatan, pagruruta, mga default ng combo, atbp.)
- `/dashboard/api-manager` — Lifecycle ng key ng API at mga pahintulot ng modelo## High-Level System Context
```mermaid
flowchart LR
@ -139,149 +129,139 @@ flowchart LR
## 1) API and Routing Layer (Next.js App Routes)
Main directories:
Mga pangunahing direktoryo:
- `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/*` at `src/app/api/v1beta/*` para sa mga compatibility API
- `src/app/api/*` para sa mga management/configuration API
- Susunod na muling pagsusulat sa `next.config.mjs` na mapa `/v1/*` sa `/api/v1/*`
Important compatibility routes:
Mahahalagang ruta ng compatibility:
- `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`kasama ang mga custom na modelo na may `custom: true`
- `src/app/api/v1/embeddings/route.ts`pagbuo ng pag-embed (6 na provider)
- `src/app/api/v1/images/generations/route.ts`pagbuo ng larawan (4+ provider kasama ang Antigravity/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`nakatuong per-provider chat
- `src/app/api/v1/providers/[provider]/embeddings/route.ts`nakalaang mga pag-embed ng bawat provider
- `src/app/api/v1/providers/[provider]/images/generations/route.ts`nakalaang mga larawan ng bawat provider
- `src/app/api/v1beta/models/route.ts`
- `src/app/api/v1beta/models/[...path]/route.ts`
Management domains:
Mga domain ng pamamahala:
- 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)
- Auth/setting: `src/app/api/auth/*`, `src/app/api/settings/*`
- Mga provider/koneksyon: `src/app/api/providers*`
- Mga node ng provider: `src/app/api/provider-nodes*`
- Mga custom na modelo: `src/app/api/provider-models` (GET/POST/DELETE)
- Catalog ng modelo: `src/app/api/models/route.ts` (GET)
- Proxy config: `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/*`
- Sync/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*`
- CLI tooling helpers: `src/app/api/cli-tools/*`
- Mga Key/aliases/combos/presyo: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
- Paggamit: `src/app/api/usage/*`
- Pag-sync/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*`
- Mga katulong sa CLI tooling: `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)
- Pag-iisip na badyet: `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) — provider profiles, circuit breaker, rate limit state
- Mga Session: `src/app/api/sessions` (GET)
- Mga limitasyon sa rate: `src/app/api/rate-limits` (GET)
- Katatagan: `src/app/api/resilience` (GET/PATCH) — mga profile ng provider, circuit breaker, estado ng limitasyon sa rate
- Resilience reset: `src/app/api/resilience/reset` (POST) — reset breakers + cooldowns
- Cache stats: `src/app/api/cache/stats` (GET/DELETE)
- Model availability: `src/app/api/models/availability` (GET/POST)
- Mga istatistika ng cache: `src/app/api/cache/stats` (GET/DELETE)
- Availability ng modelo: `src/app/api/models/availability` (GET/POST)
- 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)
- Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
- Policies: `src/app/api/policies` (GET/POST)
## 2) SSE + Translation Core
- Badyet: `src/app/api/usage/budget` (GET/POST)
- Fallback chain: `src/app/api/fallback/chains` (GET/POST/DELETE)
- Pag-audit sa pagsunod: `src/app/api/compliance/audit-log` (GET)
- Mga Eval: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
- Mga Patakaran: `src/app/api/policies` (GET/POST)## 2) SSE + Translation Core
Main flow modules:
- Entry: `src/sse/handlers/chat.ts`
- Core orchestration: `open-sse/handlers/chatCore.ts`
- Provider execution adapters: `open-sse/executors/*`
- Pangunahing orkestrasyon: `open-sse/handlers/chatCore.ts`
- Mga adaptor ng pagpapatupad ng provider: `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`
- Logic ng fallback ng account: `open-sse/services/accountFallback.ts`
- Rehistro ng pagsasalin: `open-sse/translator/index.ts`
- Mga pagbabago sa stream: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts`
- Pagkuha/normalisasyon ng paggamit: `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`
- Handler ng pag-embed: `open-sse/handlers/embeddings.ts`
- Pag-embed ng registry ng provider: `open-sse/config/embeddingRegistry.ts`
- Handler ng pagbuo ng larawan: `open-sse/handlers/imageGeneration.ts`
- Rehistro ng provider ng larawan: `open-sse/config/imageRegistry.ts`
- Paglilinis ng tugon: `open-sse/handlers/responseSanitizer.ts`
- Pag-normalize ng tungkulin: `open-sse/services/roleNormalizer.ts`
Services (business logic):
Mga Serbisyo (lohika ng negosyo):
- 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`
- Pagpili/pagmamarka ng account: `open-sse/services/accountSelector.ts`
- Pamamahala ng lifecycle ng konteksto: `open-sse/services/contextManager.ts`
- Pagpapatupad ng IP filter: `open-sse/services/ipFilter.ts`
- Pagsubaybay sa session: `open-sse/services/sessionManager.ts`
- Humiling ng 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`
- Pag-iisip ng pamamahala ng badyet: `open-sse/services/thinkingBudget.ts`
- Pagruruta ng modelo ng wildcard: `open-sse/services/wildcardRouter.ts`
- Pamamahala sa limitasyon ng rate: `open-sse/services/rateLimitManager.ts`
- Circuit breaker: `open-sse/services/circuitBreaker.ts`
Domain layer modules:
Mga module ng layer ng domain:
- Model availability: `src/lib/domain/modelAvailability.ts`
- Cost rules/budgets: `src/lib/domain/costRules.ts`
- Fallback policy: `src/lib/domain/fallbackPolicy.ts`
- Availability ng modelo: `src/lib/domain/modelAvailability.ts`
- Mga panuntunan/badyet ng gastos: `src/lib/domain/costRules.ts`
- Patakaran sa Fallback: `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`
- Patakaran sa pag-lockout: `src/lib/domain/lockoutPolicy.ts`
- Policy engine: `src/domain/policyEngine.ts`sentralisadong lockout → badyet → fallback evaluation
- Catalog ng mga error code: `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`
- I-fetch ang timeout: `src/lib/domain/fetchTimeout.ts`
- Humiling ng telemetry: `src/lib/domain/requestTelemetry.ts`
- Pagsunod/pag-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
- Pananatili ng estado ng domain: `src/lib/db/domainState.ts` — SQLite CRUD para sa mga fallback na chain, badyet, kasaysayan ng gastos, estado ng lockout, mga circuit breaker
OAuth provider modules (12 individual files under `src/lib/oauth/providers/`):
Mga module ng OAuth provider (12 indibidwal na file sa ilalim ng `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
- Mga indibidwal na provider: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts.`, `kilo`c.ts.
- Manipis na wrapper: `src/lib/oauth/providers.ts` — muling pag-export mula sa mga indibidwal na module## 3) Persistence Layer
## 3) Persistence Layer
Primary state DB (SQLite):
Pangunahing estado DB (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**
- Muling i-export ang facade: `src/lib/localDb.ts` (manipis na layer ng compatibility para sa mga tumatawag)
- file: `${DATA_DIR}/storage.sqlite` (o `$XDG_CONFIG_HOME/omniroute/storage.sqlite` kapag nakatakda, kung hindi `~/.omniroute/storage.sqlite`)
- mga entity (table + KV namespaces): providerConnections, providerNodes, modelAliases, combo, apiKeys, setting, pagpepresyo,**customModels**,**proxyConfig**,**ipFilter**,**thinkingBudget**,**systemPrompt**
Usage persistence:
Pagtitiyaga ng paggamit:
- 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/`, `<repo>/logs/...`)
- legacy JSON files are migrated to SQLite by startup migrations when present
- facade: `src/lib/usageDb.ts` (mga decomposed modules sa `src/lib/usage/*`)
- Mga talahanayan ng SQLite sa `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs`
- nananatili ang mga opsyonal na artifact ng file para sa compatibility/debug (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `<repo>/logs/...`)
- Ang mga legacy na JSON file ay inililipat sa SQLite sa pamamagitan ng mga startup na paglilipat kapag naroroon
Domain State DB (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
## 4) Auth + Security Surfaces
- `src/lib/db/domainState.ts` — Mga pagpapatakbo ng CRUD para sa estado ng domain
- Mga talahanayan (ginawa sa `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
- Write-through na cache pattern: in-memoryang Maps ay may awtoridad sa runtime; ang mga mutasyon ay nakasulat nang sabay-sabay sa SQLite; ang estado ay naibalik mula sa DB sa malamig na simula## 4) Auth + Security Surfaces
- 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)
## 5) Cloud Sync
- Pagbuo/pag-verify ng API key: `src/shared/utils/apiKey.ts`
- Nagpatuloy ang mga lihim ng provider sa mga entry ng `providerConnections`
- Outbound proxy na suporta sa pamamagitan ng `open-sse/utils/proxyFetch.ts` (env vars) at `open-sse/utils/networkProxy.ts` (configurable per-provider o global)## 5) Cloud Sync
- 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`
## Request Lifecycle (`/v1/chat/completions`)
- Pana-panahong gawain: `src/shared/services/cloudSyncScheduler.ts`
- Pana-panahong gawain: `src/shared/services/modelSyncScheduler.ts`
- Kontrolin ang ruta: `src/app/api/sync/cloud/route.ts`## Request Lifecycle (`/v1/chat/completions`)
```mermaid
sequenceDiagram
@ -358,9 +338,7 @@ flowchart TD
Q -- No --> R[Return all unavailable]
```
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.
## OAuth Onboarding and Token Refresh Lifecycle
Ang mga desisyon sa Fallback ay hinihimok ng `open-sse/services/accountFallback.ts` gamit ang mga status code at error-message heuristics. Ang combo routing ay nagdaragdag ng isang karagdagang bantay: provider-scoped 400s gaya ng upstream content-block at role-validation failures ay itinuturing bilang model-local na mga pagkabigo kaya maaaring tumakbo pa rin ang mga combo target sa ibang pagkakataon.## OAuth Onboarding and Token Refresh Lifecycle
```mermaid
sequenceDiagram
@ -390,9 +368,7 @@ sequenceDiagram
Test-->>UI: validation result
```
Refresh during live traffic is executed inside `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`.
## Cloud Sync Lifecycle (Enable / Sync / Disable)
Ang pag-refresh sa panahon ng live na trapiko ay isinasagawa sa loob ng `open-sse/handlers/chatCore.ts` sa pamamagitan ng executor `refreshCredentials()`.## Cloud Sync Lifecycle (Enable / Sync / Disable)
```mermaid
sequenceDiagram
@ -424,9 +400,7 @@ sequenceDiagram
Sync-->>UI: disabled
```
Periodic sync is triggered by `CloudSyncScheduler` when cloud is enabled.
## Data Model and Storage Map
Ang pana-panahong pag-sync ay na-trigger ng `CloudSyncScheduler` kapag pinagana ang cloud.## Data Model and Storage Map
```mermaid
erDiagram
@ -527,14 +501,12 @@ erDiagram
}
```
Physical storage files:
Mga file ng pisikal na storage:
- 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: `<repo>/logs/...`
## Deployment Topology
- pangunahing runtime DB: `${DATA_DIR}/storage.sqlite`
- mga linya ng log ng kahilingan: `${DATA_DIR}/log.txt` (compat/debug artifact)
- structured call payload archive: `${DATA_DIR}/call_logs/`
- opsyonal na tagasalin/paghiling ng mga sesyon ng pag-debug: `<repo>/logs/...`## Deployment Topology
```mermaid
flowchart LR
@ -569,246 +541,205 @@ flowchart LR
### Route and API Modules
- `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/v1/*`, `src/app/api/v1beta/*`: mga compatibility API
- `src/app/api/v1/providers/[provider]/*`: nakalaang mga ruta ng bawat provider (chat, mga pag-embed, mga larawan)
- `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/provider-nodes*`: custom na katugmang pamamahala ng node
- `src/app/api/provider-models`: pamamahala ng custom na modelo (CRUD)
- `src/app/api/models/route.ts`: model catalog API (mga alias + custom na modelo)
- `src/app/api/oauth/*`: Ang mga daloy ng OAuth/device-code
- `src/app/api/keys*`: lokal na API key lifecycle
- `src/app/api/models/alias`: pamamahala ng alias
- `src/app/api/combos*`: pamamahala ng fallback combo
- `src/app/api/pricing`: na-override ang pagpepresyo para sa pagkalkula ng gastos
- `src/app/api/settings/proxy`: configuration ng proxy (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/usage/*`: mga API ng paggamit at mga log
- `src/app/api/sync/*` + `src/app/api/cloud/*`: cloud sync at cloud-facing helper
- `src/app/api/cli-tools/*`: mga lokal na 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/sessions`: aktibong listahan ng session (GET)
- `src/app/api/rate-limits`: per-account rate limit status (GET)### Routing and Execution Core
### Routing and Execution Core
- `src/sse/handlers/chat.ts`: humiling ng parse, combo handling, loop ng pagpili ng account
- `open-sse/handlers/chatCore.ts`: pagsasalin, executor dispatch, retry/refresh handling, stream setup
- `open-sse/executors/*`: network na partikular sa provider at gawi sa format### Translation Registry and Format Converters
- `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
- `open-sse/translator/index.ts`: registry ng translator at orkestrasyon
- Humiling ng mga tagasalin: `open-sse/translator/request/*`
- Mga tagasalin ng tugon: `open-sse/translator/response/*`
- Mga constant ng format: `open-sse/translator/formats.ts`### Persistence
### Translation Registry and Format Converters
- `src/lib/db/*`: persistent config/state at domain persistence sa SQLite
- `src/lib/localDb.ts`: muling pag-export ng compatibility para sa mga DB module
- `src/lib/usageDb.ts`: kasaysayan ng paggamit/mga log ng tawag na facade sa itaas ng mga talahanayan ng SQLite## Provider Executor Coverage (Strategy Pattern)
- `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`
Ang bawat provider ay may dalubhasang tagapagpatupad na nagpapalawak ng `BaseExecutor` (sa `open-sse/executors/base.ts`), na nagbibigay ng pagbuo ng URL, pagbuo ng header, muling subukang may exponential backoff, credential refresh hook, at ang `execute()` na paraan ng orkestrasyon.
### Persistence
| Tagapagpatupad | (Mga) Provider | Espesyal na Paghawak |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, Qoder, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Dynamic na URL/header config bawat provider |
| `AntigravityExecutor` | Google Antigravity | Mga custom na project/session ID, Retry-After parsing |
| `CodexExecutor` | OpenAI Codex | Nag-inject ng mga tagubilin sa system, pinipilit ang pagsisikap sa pangangatwiran |
| `CursorExecutor` | Cursor IDE | ConnectRPC protocol, Protobuf encoding, kahilingan sa pagpirma sa pamamagitan ng checksum |
| `GithubExecutor` | GitHub Copilot | Copilot token refresh, VSCode-mimicking header |
| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binary format → SSE conversion |
| `GeminiCLIEexecutor` | Gemini CLI | Ikot ng pag-refresh ng token ng Google OAuth |
- `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
Ang lahat ng iba pang provider (kabilang ang mga custom na katugmang node) ay gumagamit ng `DefaultExecutor`.## Provider Compatibility Matrix
## Provider Executor Coverage (Strategy Pattern)
| Provider | Format | Awto | Stream | Hindi Stream | Pag-refresh ng Token | Paggamit ng API |
| ---------------- | ---------------- | --------------------- | ---------------- | ------------ | -------------------- | ----------------------------- | ------------------------------ |
| Claude | claude | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Admin lang |
| Gemini | Gemini | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
| Gemini CLI | Gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ Buong quota API |
| OpenAI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Codex | openai-responses | OAuth | ✅ pinilit | ❌ | ✅ | ✅ Mga limitasyon sa rate |
| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Mga snapshot ng quota |
| Cursor | cursor | Custom na checksum | ✅ | ✅ | ❌ | ❌ |
| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Mga limitasyon sa paggamit |
| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Bawat kahilingan |
| Qoder | openai | OAuth (Basic) | ✅ | ✅ | ✅ | ⚠️ Bawat kahilingan |
| OpenRouter | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| GLM/Kimi/MiniMax | claude | API Key | ✅ | ✅ | ❌ | ❌ |
| DeepSeek | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Groq | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| xAI (Grok) | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Mistral | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Pagkagulo | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Magkasama AI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Fireworks AI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Cerebras | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Cohere | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| NVIDIA NIM | openai | API Key | ✅ | ✅ | ❌ | ❌ | ## Format Translation Coverage |
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.
| Executor | Provider(s) | Special Handling |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, Qoder, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Dynamic URL/header config per provider |
| `AntigravityExecutor` | Google Antigravity | Custom project/session IDs, Retry-After parsing |
| `CodexExecutor` | OpenAI Codex | Injects system instructions, forces reasoning effort |
| `CursorExecutor` | Cursor IDE | ConnectRPC protocol, Protobuf encoding, request signing via checksum |
| `GithubExecutor` | GitHub Copilot | Copilot token refresh, VSCode-mimicking headers |
| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binary format → SSE conversion |
| `GeminiCLIExecutor` | Gemini CLI | Google OAuth token refresh cycle |
All other providers (including custom compatible nodes) use the `DefaultExecutor`.
## Provider Compatibility Matrix
| Provider | Format | Auth | Stream | Non-Stream | Token Refresh | Usage API |
| ---------------- | ---------------- | --------------------- | ---------------- | ---------- | ------------- | ------------------ |
| Claude | claude | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Admin only |
| Gemini | gemini | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ Full quota API |
| OpenAI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Codex | openai-responses | OAuth | ✅ forced | ❌ | ✅ | ✅ Rate limits |
| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Quota snapshots |
| Cursor | cursor | Custom checksum | ✅ | ✅ | ❌ | ❌ |
| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Usage limits |
| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Per request |
| Qoder | openai | OAuth (Basic) | ✅ | ✅ | ✅ | ⚠️ Per request |
| OpenRouter | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| GLM/Kimi/MiniMax | claude | API Key | ✅ | ✅ | ❌ | ❌ |
| DeepSeek | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Groq | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| xAI (Grok) | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Mistral | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Perplexity | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Together AI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Fireworks AI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Cerebras | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| Cohere | openai | API Key | ✅ | ✅ | ❌ | ❌ |
| NVIDIA NIM | openai | API Key | ✅ | ✅ | ❌ | ❌ |
## Format Translation Coverage
Detected source formats include:
Kasama sa mga natukoy na format ng pinagmulan ang:
- `openai`
- `openai-responses`
- `claude`
- `gemini`
Target formats include:
Kasama sa mga target na format ang:
- OpenAI chat/Responses
- OpenAI chat/Mga Tugon
- Claude
- Gemini/Gemini-CLI/Antigravity envelope
- Kiro
- Cursor
Translations use **OpenAI as the hub format** — all conversions go through OpenAI as intermediate:
```
Ginagamit ng mga pagsasalin ang**OpenAI bilang hub format**— lahat ng conversion ay dumadaan sa OpenAI bilang intermediate:```
Source Format → OpenAI (hub) → Target Format
```
Translations are selected dynamically based on source payload shape and provider target format.
````
Additional processing layers in the translation pipeline:
Pinipili ang mga pagsasalin sa dynamic na paraan batay sa hugis ng source payload at format ng target ng provider.
- **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 `<think>...</think>` blocks from content into `reasoning_content` field
- **Structured output** — Converts OpenAI `response_format.json_schema` to Gemini's `responseMimeType` + `responseSchema`
Mga karagdagang layer ng pagpoproseso sa pipeline ng pagsasalin:
## Supported API Endpoints
-**Response sanitization**— Tinatanggal ang mga hindi karaniwang field mula sa OpenAI-format na mga tugon (parehong streaming at non-streaming) para matiyak ang mahigpit na pagsunod sa SDK
-**Pag-normalize ng tungkulin**— Kino-convert ang `developer``system` para sa mga target na hindi OpenAI; pinagsasama ang `system``user` para sa mga modelong tumatanggi sa papel ng system (GLM, ERNIE)
-**Think tag extraction**— Pina-parse ang `<think>...</think>` block mula sa content papunta sa `reasoning_content` field
-**Structured output**— Kino-convert ang OpenAI `response_format.json_schema` sa `responseMimeType` + `responseSchema` ni Gemini## Supported API Endpoints
| Endpoint | Format | Handler |
| -------------------------------------------------- | ------------------ | ------------------------------------------------------------------- |
| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` |
| `POST /v1/messages` | Claude Messages | Same handler (auto-detected) |
| `POST /v1/responses` | OpenAI Responses | `open-sse/handlers/responsesHandler.ts` |
| `POST /v1/embeddings` | OpenAI Embeddings | `open-sse/handlers/embeddings.ts` |
| `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/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 |
| `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 |
| Endpoint | Format | Handler |
| ---------------------------------------------------- | ------------------- | ------------------------------------------------------------------- |
| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` |
| `POST /v1/messages` | Claude Messages | Parehong handler (auto-detected) |
| `POST /v1/mga tugon` | Mga Tugon sa OpenAI | `open-sse/handlers/responsesHandler.ts` |
| `POST /v1/embeddings` | OpenAI Embeddings | `open-sse/handlers/embeddings.ts` |
| `GET /v1/embeddings` | Listahan ng modelo | ruta ng API |
| `POST /v1/images/generations` | Mga Larawan ng OpenAI | `open-sse/handlers/imageGeneration.ts` |
| `GET /v1/images/generations` | Listahan ng modelo | ruta ng API |
| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Nakatuon sa bawat provider na may pagpapatunay ng modelo |
| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Nakatuon sa bawat provider na may pagpapatunay ng modelo |
| `POST /v1/providers/{provider}/images/generations` | Mga Larawan ng OpenAI | Nakatuon sa bawat provider na may pagpapatunay ng modelo |
| `POST /v1/messages/count_tokens` | Bilang ng Token ng Claude | ruta ng API |
| `GET /v1/models` | Listahan ng OpenAI Models | ruta ng API (chat + pag-embed + larawan + mga custom na modelo) |
| `GET /api/models/catalog` | Catalog | Lahat ng mga modelo ay nakapangkat ayon sa provider + uri |
| `POST /v1beta/models/*:streamGenerateContent` | Taong Gemini | ruta ng API |
| `GET/PUT/DELETE /api/settings/proxy` | Proxy Config | Configuration ng proxy ng network |
| `POST /api/settings/proxy/test` | Pagkakakonekta ng Proxy | Endpoint ng pagsubok sa kalusugan/pagkonekta ng proxy |
| `GET/POST/DELETE /api/provider-models` | Mga Modelo ng Provider | Mga custom at pinamamahalaang available na modelo na sinusuportahan ng metadata ng modelo ng provider |## Bypass Handler
## Bypass Handler
Hinaharang ng bypass handler (`open-sse/utils/bypassHandler.ts`) ang mga kilalang "throwaway" na kahilingan mula kay Claude CLI — mga warmup ping, pagkuha ng pamagat, at mga bilang ng token — at nagbabalik ng**pekeng tugon**nang hindi gumagamit ng upstream na mga token ng provider. Nati-trigger lang ito kapag ang `User-Agent` ay naglalaman ng `claude-cli`.## Request Logger Pipeline
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`.
## Request Logger Pipeline
The request logger (`open-sse/utils/requestLogger.ts`) provides a 7-stage debug logging pipeline, disabled by default, enabled via `ENABLE_REQUEST_LOGS=true`:
```
Ang request logger (`open-sse/utils/requestLogger.ts`) ay nagbibigay ng 7-stage na debug logging pipeline, na hindi pinagana bilang default, na pinagana sa pamamagitan ng `ENABLE_REQUEST_LOGS=true`:```
1_req_client.json → 2_req_source.json → 3_req_openai.json → 4_req_target.json
→ 5_res_provider.txt → 6_res_openai.txt → 7_res_client.txt
```
````
Files are written to `<repo>/logs/<session>/` for each request session.
## Failure Modes and Resilience
Ang mga file ay isinusulat sa `<repo>/logs/<session>/` para sa bawat sesyon ng kahilingan.## Failure Modes and Resilience
## 1) Account/Provider Availability
- provider account cooldown on transient/rate/auth errors
- account fallback before failing request
- combo model fallback when current model/provider path is exhausted
- cooldown ng provider account sa mga lumilipas/rate/auth error
- fallback ng account bago mabigo ang kahilingan
- fallback ng combo model kapag naubos na ang kasalukuyang modelo/provider path## 2) Token Expiry
## 2) Token Expiry
- pre-check and refresh with retry for refreshable providers
- 401/403 retry after refresh attempt in core path
## 3) Stream Safety
- paunang suriin at i-refresh na may muling pagsubok para sa mga nare-refresh na provider
- 401/403 muling subukan pagkatapos i-refresh ang pagtatangka sa pangunahing landas## 3) Stream Safety
- disconnect-aware stream controller
- translation stream with end-of-stream flush and `[DONE]` handling
- usage estimation fallback when provider usage metadata is missing
- translation stream na may end-of-stream flush at `[DONE]` handling
- fallback sa pagtatantya ng paggamit kapag nawawala ang metadata ng paggamit ng provider## 4) Cloud Sync Degradation
## 4) Cloud Sync Degradation
- Lumilitaw ang mga error sa pag-sync ngunit nagpapatuloy ang lokal na runtime
- Ang scheduler ay may retry-capable logic, ngunit ang pana-panahong execution ay kasalukuyang tumatawag sa single-attempt sync bilang default## 5) Data Integrity
- sync errors are surfaced but local runtime continues
- scheduler has retry-capable logic, but periodic execution currently calls single-attempt sync by default
- Mga paglilipat ng schema ng SQLite at mga auto-upgrade na hook sa pagsisimula
- legacy na JSON → path ng compatibility ng paglilipat ng SQLite## Observability and Operational Signals
## 5) Data Integrity
Runtime visibility source:
- SQLite schema migrations and auto-upgrade hooks at startup
- legacy JSON → SQLite migration compatibility path
- mga console log mula sa `src/sse/utils/logger.ts`
- mga pinagsama-samang paggamit sa bawat kahilingan sa SQLite (`usage_history`, `call_logs`, `proxy_logs`)
- apat na yugto ng detalyadong payload na kumukuha sa SQLite (`request_detail_logs`) kapag `settings.detailed_logs_enabled=true`
- log in sa status ng textual na kahilingan `log.txt` (opsyonal/compat)
- opsyonal na malalim na kahilingan/mga log ng pagsasalin sa ilalim ng `mga log/` kapag `ENABLE_REQUEST_LOGS=true`
- Mga endpoint sa paggamit ng dashboard (`/api/usage/*`) para sa paggamit ng UI
## Observability and Operational Signals
Ang detalyadong paghiling ng payload capture ay nag-iimbak ng hanggang apat na JSON payload stages sa bawat rutang tawag:
Runtime visibility sources:
- hilaw na kahilingan na natanggap mula sa kliyente
- isinalin na kahilingan ay aktwal na ipinadala sa upstream
- ang tugon ng provider ay muling itinayo bilang JSON; ang mga naka-stream na tugon ay pinagsama sa panghuling buod at stream metadata
- panghuling tugon ng kliyente na ibinalik ng OmniRoute; naka-imbak ang mga naka-stream na tugon sa parehong compact summary form## Security-Sensitive Boundaries
- 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 deep request/translation logs under `logs/` when `ENABLE_REQUEST_LOGS=true`
- dashboard usage endpoints (`/api/usage/*`) for UI consumption
- Sikreto ng JWT (`JWT_SECRET`) ay sinisiguro ang pag-verify/pagpirma ng cookie ng session ng dashboard
- Ang paunang password bootstrap (`INITIAL_PASSWORD`) ay dapat na tahasang i-configure para sa first-run provisioning
- Ang API key HMAC secret (`API_KEY_SECRET`) ay sinisiguro ang nabuong lokal na format ng API key
- Ang mga lihim ng provider (mga API key/token) ay nananatili sa lokal na DB at dapat na protektahan sa antas ng filesystem
- Umaasa ang mga endpoint ng cloud sync sa API key auth + semantics ng machine id## Environment and Runtime Matrix
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
## Security-Sensitive Boundaries
- 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
## Environment and Runtime Matrix
Environment variables actively used by code:
Mga variable ng kapaligiran na aktibong ginagamit ng code:
- 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: `ENABLE_REQUEST_LOGS`
- 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`
- Imbakan: `DATA_DIR`
- Katugmang pag-uugali ng node: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
- Opsyonal na pag-override sa base ng imbakan (Linux/macOS kapag hindi nakatakda ang `DATA_DIR`): `XDG_CONFIG_HOME`
- Pag-hash ng seguridad: `API_KEY_SECRET`, `MACHINE_ID_SALT`
- Pag-log: `ENABLE_REQUEST_LOGS`
- Pag-sync/cloud URLing: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL`
- Outbound proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` at lowercase na variant
- Mga flag ng tampok ng SOCKS5: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
- Mga katulong sa platform/runtime (hindi config na partikular sa app): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME`## Known Architectural Notes
## Known Architectural Notes
1. Ang `usageDb` at `localDb` ay nagbabahagi ng parehong base directory policy (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) na may legacy na paglipat ng file.
2. Nagde-delegate ang `/api/v1/route.ts` sa parehong pinag-isang tagabuo ng catalog na ginagamit ng `/api/v1/models` (`src/app/api/v1/models/catalog.ts`) upang maiwasan ang semantic drift.
3. Ang Request logger ay nagsusulat ng buong header/body kapag pinagana; ituring ang direktoryo ng log bilang sensitibo.
4. Nakadepende ang pag-uugali ng cloud sa tamang `NEXT_PUBLIC_BASE_URL` at maabot ng cloud endpoint.
5. Ang direktoryo ng `open-sse/` ay na-publish bilang `@omniroute/open-sse`**npm workspace package**. Ini-import ito ng source code sa pamamagitan ng `@omniroute/open-sse/...` (nalutas ng Next.js `transpilePackages`). Ginagamit pa rin ng mga path ng file sa dokumentong ito ang pangalan ng direktoryo na `open-sse/` para sa pagkakapare-pareho.
6. Ang mga chart sa dashboard ay gumagamit ng**Recharts**(SVG-based) para sa naa-access, interactive na mga visualization ng analytics (mga bar chart ng paggamit ng modelo, mga talahanayan ng breakdown ng provider na may mga rate ng tagumpay).
7. Gumagamit ang E2E tests ng**Playwright**(`tests/e2e/`), na tumatakbo sa pamamagitan ng `npm run test:e2e`. Gumagamit ang mga unit test ng**Node.js test runner**(`mga pagsubok/unit/`), tumatakbo sa pamamagitan ng `npm run test:unit`. Ang source code sa ilalim ng `src/` ay**TypeScript**(`.ts`/`.tsx`); ang `open-sse/` workspace ay nananatiling JavaScript (`.js`).
8. Ang pahina ng mga setting ay isinaayos sa 5 tab: Seguridad, Pagruruta (6 na pandaigdigang diskarte: fill-first, round-robin, p2c, random, hindi gaanong ginagamit, cost-optimized), Resilience (editable rate limits, circuit breaker, mga patakaran), AI (thinking budget, system prompt, prompt cache), Advanced (proxy).## Operational Verification Checklist
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 5 tabs: Security, Routing (6 global strategies: fill-first, round-robin, p2c, random, least-used, cost-optimized), Resilience (editable rate limits, circuit breaker, policies), AI (thinking budget, system prompt, prompt cache), Advanced (proxy).
## Operational Verification Checklist
- Build from source: `npm run build`
- Build Docker image: `docker build -t omniroute .`
- Start service and verify:
- Bumuo mula sa pinagmulan: `npm run build`
- Bumuo ng imahe ng Docker: `docker build -t omniroute .`
- Simulan ang serbisyo at i-verify:
- `GET /api/settings`
- `GET /api/v1/models`
- CLI target base URL should be `http://<host>:20128/v1` when `PORT=20128`
- Ang CLI target base URL ay dapat na `http://<host>:20128/v1` kapag `PORT=20128`

View file

@ -4,42 +4,29 @@
---
> Self-managing model chains with adaptive scoring
> Self-manage model chain na may adaptive scoring## How It Works
## How It Works
Ang Auto-Combo Engine ay dynamic na pinipili ang pinakamahusay na provider/modelo para sa bawat kahilingan gamit ang**6-factor scoring function**:
The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**:
| Salik | Timbang | Paglalarawan |
| :--------- | :------ | :-------------------------------------------------- | ------------- |
| Quota | 0.20 | Natitirang kapasidad [0..1] |
| Kalusugan | 0.25 | Circuit breaker: SARADO=1.0, HALF=0.5, OPEN=0.0 |
| CostInv | 0.20 | Baliktad na gastos (mas mura = mas mataas na marka) |
| LatencyInv | 0.15 | Inverse p95 latency (mas mabilis = mas mataas) |
| TaskFit | 0.10 | Model × uri ng gawain na marka ng fitness |
| Katatagan | 0.10 | Mababang variance sa latency/error | ## Mode Packs |
| 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 |
| Pack | Tumutok | Susing Timbang |
| :----------------------- | :---------------------- | :--------------- | --------------- |
| 🚀**Mabilis na Ipadala** | Bilis | latencyInv: 0.35 |
| 💰**Cost Saver** | Ekonomiya | costInv: 0.40 |
| 🎯**Una ang Kalidad** | Pinakamahusay na modelo | TaskFit: 0.40 |
| 📡**Offline Friendly** | Availability | quota: 0.40 | ## Self-Healing |
## Mode Packs
-**Pansamantalang pagbubukod**: Marka < 0.2 hindi kasama sa loob ng 5 min (progressive backoff, max 30 min) -**Circuit breaker awareness**: OPEN auto-excluded; HALF_OPEN mga kahilingan sa pagsisiyasat -**Insidente mode**: >50% OPEN → huwag paganahin ang paggalugad, i-maximize ang katatagan -**Cooldown recovery**: Pagkatapos ng pagbubukod, ang unang kahilingan ay isang "probe" na may pinababang timeout## Bandit Exploration
| Pack | Focus | Key Weight |
| :---------------------- | :----------- | :--------------- |
| 🚀 **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 |
## Self-Healing
- **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
## Bandit Exploration
5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode.
## API
5% ng mga kahilingan (nako-configure) ay iruruta sa mga random na provider para sa paggalugad. Naka-disable sa incident mode.## API
```bash
# Create auto-combo
@ -53,15 +40,13 @@ curl http://localhost:20128/api/combos/auto
## Task Fitness
30+ models scored across 6 task types (`coding`, `review`, `planning`, `analysis`, `debugging`, `documentation`). Supports wildcard patterns (e.g., `*-coder` → high coding score).
30+ modelo ang nakakuha ng marka sa 6 na uri ng gawain (`coding`, `review`, `pagpaplano`, `analysis`, `debugging`, `documentation`). Sinusuportahan ang mga pattern ng wildcard (hal., `*-coder` → mataas na marka ng coding).## Files
## Files
| 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 |
| File | Layunin |
| :------------------------------------------- | :----------------------------------------------- |
| `open-sse/services/autoCombo/scoring.ts` | Pag-andar ng pagmamarka at normalisasyon ng pool |
| `open-sse/services/autoCombo/taskFitness.ts` | Model × task fitness lookup |
| `open-sse/services/autoCombo/engine.ts` | Lohika ng pagpili, bandido, limitasyon ng badyet |
| `open-sse/services/autoCombo/selfHealing.ts` | Pagbubukod, pagsisiyasat, mode ng insidente |
| `open-sse/services/autoCombo/modePacks.ts` | 4 na profile ng timbang |
| `src/app/api/combos/auto/route.ts` | REST API |

View file

@ -4,11 +4,9 @@
---
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.
---
Ipinapaliwanag ng gabay na ito kung paano i-install at i-configure ang lahat ng suportadong AI coding CLI tool
upang gamitin ang**OmniRoute**bilang pinag-isang backend, na nagbibigay sa iyo ng sentralisadong pamamahala ng key,
pagsubaybay sa gastos, pagpapalit ng modelo, at pag-log ng kahilingan sa bawat tool.---
## How It Works
@ -22,118 +20,113 @@ Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilo
Anthropic / OpenAI / Gemini / DeepSeek / Groq / Mistral / ...
```
**Benefits:**
**Mga Pakinabang:**
- 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)
---
- Isang API key para pamahalaan ang lahat ng tool
- Pagsubaybay sa gastos sa lahat ng CLI sa dashboard
- Paglipat ng modelo nang hindi muling kino-configure ang bawat tool
- Gumagana nang lokal at sa mga malalayong server (VPS)---
## Supported Tools (Dashboard Source of Truth)
The dashboard cards in `/dashboard/cli-tools` are generated from `src/shared/constants/cliTools.ts`.
Current list (v3.0.0-rc.16):
Ang mga dashboard card sa `/dashboard/cli-tools` ay nabuo mula sa `src/shared/constants/cliTools.ts`.
Kasalukuyang listahan (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 |
| Tool | ID | Utos | Mode ng Pag-setup | Paraan ng Pag-install |
| ------------------ | ------------- | ---------- | ----------------- | --------------------- | -------------------------------------------- |
| **Claude Code** | `claude` | `claude` | env | npm |
| **OpenAI Codex** | `codex` | `codex` | custom | npm |
| **Pabrika Droid** | `droid` | `droid` | custom | bundle/CLI |
| **OpenClaw** | `openclaw` | `openclaw` | custom | bundle/CLI |
| **Cursor** | `cursor` | app | gabay | desktop app |
| **Cline** | `cline` | `cline` | custom | npm |
| **Kilo Code** | `kilo` | `kilocode` | custom | npm |
| **Magpatuloy** | `magpatuloy` | extension | gabay | VS Code |
| **Antigravity** | `antigravity` | panloob | mitm | OmniRoute |
| **GitHub Copilot** | `kopilot` | extension | custom | VS Code |
| **OpenCode** | `opencode` | `opencode` | gabay | npm |
| **Kiro AI** | `kiro` | app/cli | mitm | desktop/CLI | ### CLI fingerprint sync (Agents + Settings) |
### CLI fingerprint sync (Agents + Settings)
`/dashboard/agents` and `Settings > CLI Fingerprint` use `src/shared/constants/cliCompatProviders.ts`.
This keeps provider IDs aligned with CLI cards and legacy IDs.
Gumagamit ang `/dashboard/agents` at `Settings > CLI Fingerprint` ng `src/shared/constants/cliCompatProviders.ts`.
Pinapanatili nitong nakahanay ang mga provider ID sa mga CLI card at legacy ID.
| CLI ID | Fingerprint Provider ID |
| ---------------------------------------------------------------------------------------------------- | ----------------------- |
| `kilo` | `kilocode` |
| `copilot` | `github` |
| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | same ID |
| `kopilot` | `github` |
| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | parehong ID |
Legacy IDs still accepted for compatibility: `copilot`, `kimi-coding`, `qwen`.
---
Tinatanggap pa rin ang mga legacy ID para sa compatibility: `copilot`, `kimi-coding`, `qwen`.---
## Step 1 — Get an OmniRoute API Key
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. Buksan ang dashboard ng OmniRoute →**API Manager**(`/dashboard/api-manager`)
2. I-click ang**Gumawa ng API Key**
3. Bigyan ito ng pangalan (hal. `cli-tools`) at piliin ang lahat ng pahintulot
4. Kopyahin ang susi — kakailanganin mo ito para sa bawat CLI sa ibaba
> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
---
> Ang iyong susi ay mukhang: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`---
## Step 2 — Install CLI Tools
All npm-based tools require Node.js 18+:
Ang lahat ng mga tool na nakabatay sa npm ay nangangailangan ng Node.js 18+:```bash
```bash
# Claude Code (Anthropic)
npm install -g @anthropic-ai/claude-code
# OpenAI Codex
npm install -g @openai/codex
# OpenCode
npm install -g opencode-ai
# Cline
npm install -g cline
# KiloCode
npm install -g kilocode
# Kiro CLI (Amazon — requires curl + unzip)
apt-get install -y unzip # on Debian/Ubuntu
apt-get install -y unzip # on Debian/Ubuntu
curl -fsSL https://cli.kiro.dev/install | bash
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
```
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
**Verify:**
````
```bash
**I-verify:**```bash
claude --version # 2.x.x
codex --version # 0.x.x
opencode --version # x.x.x
cline --version # 2.x.x
kilocode --version # x.x.x (or: kilo --version)
kiro-cli --version # 1.x.x
```
````
---
## Step 3 — Set Global Environment Variables
Add to `~/.bashrc` (or `~/.zshrc`), then run `source ~/.bashrc`:
Idagdag sa `~/.bashrc` (o `~/.zshrc`), pagkatapos ay patakbuhin ang `source ~/.bashrc`:```bash
```bash
# OmniRoute Universal Endpoint
export OPENAI_BASE_URL="http://localhost:20128/v1"
export OPENAI_API_KEY="sk-your-omniroute-key"
export ANTHROPIC_BASE_URL="http://localhost:20128/v1"
export ANTHROPIC_API_KEY="sk-your-omniroute-key"
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`.
````
---
> Para sa isang**remote server**palitan ang `localhost:20128` ng server IP o domain,
> hal. `http://192.168.0.15:20128`.---
## Step 4 — Configure Each Tool
@ -150,11 +143,9 @@ mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
"apiKey": "sk-your-omniroute-key"
}
EOF
```
````
**Test:** `claude "say hello"`
---
**Pagsubok:**`claude "kumusta"`---
### OpenAI Codex
@ -166,9 +157,7 @@ apiBaseUrl: http://localhost:20128/v1
EOF
```
**Test:** `codex "what is 2+2?"`
---
**Pagsubok:**`codex "ano ang 2+2?"`---
### OpenCode
@ -180,57 +169,45 @@ api_key = "sk-your-omniroute-key"
EOF
```
**Test:** `opencode`
---
**Pagsubok:**`opencode`---
### Cline (CLI or VS Code)
**CLI mode:**
```bash
**CLI mode:**```bash
mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
{
"apiProvider": "openai",
"openAiBaseUrl": "http://localhost:20128/v1",
"openAiApiKey": "sk-your-omniroute-key"
"apiProvider": "openai",
"openAiBaseUrl": "http://localhost:20128/v1",
"openAiApiKey": "sk-your-omniroute-key"
}
EOF
```
````
**VS Code mode:**
Cline extension settings → API Provider: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1`
Mga setting ng extension ng cline → Provider ng API: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1`
Or use the OmniRoute dashboard → **CLI Tools → Cline → Apply Config**.
---
O gamitin ang OmniRoute dashboard →**CLI Tools → Cline → Apply Config**.---
### KiloCode (CLI or VS Code)
**CLI mode:**
```bash
**CLI mode:**```bash
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
```
````
**VS Code settings:**
```json
**Mga setting ng VS Code:**```json
{
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
"kilo-code.apiKey": "sk-your-omniroute-key"
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
"kilo-code.apiKey": "sk-your-omniroute-key"
}
```
Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**.
````
---
O gamitin ang OmniRoute dashboard →**CLI Tools → KiloCode → Apply Config**.---
### Continue (VS Code Extension)
Edit `~/.continue/config.yaml`:
```yaml
I-edit ang `~/.continue/config.yaml`:```yaml
models:
- name: OmniRoute
provider: openai
@ -238,11 +215,9 @@ models:
apiBase: http://localhost:20128/v1
apiKey: sk-your-omniroute-key
default: true
```
````
Restart VS Code after editing.
---
I-restart ang VS Code pagkatapos mag-edit.---
### Kiro CLI (Amazon)
@ -259,65 +234,55 @@ kiro-cli status
### Cursor (Desktop App)
> **Note:** Cursor routes requests through its cloud. For OmniRoute integration,
> enable **Cloud Endpoint** in OmniRoute Settings and use your public domain URL.
> **Tandaan:**Mga kahilingan sa ruta ng cursor sa pamamagitan ng cloud nito. Para sa pagsasama ng OmniRoute,
> paganahin ang**Cloud Endpoint**sa Mga Setting ng OmniRoute at gamitin ang URL ng iyong pampublikong domain.
Via GUI: **Settings → Models → OpenAI API Key**
Sa pamamagitan ng GUI:**Mga Setting → Mga Modelo → OpenAI API Key**
- Base URL: `https://your-domain.com/v1`
- API Key: your OmniRoute key
---
- API Key: ang iyong OmniRoute key---
## Dashboard Auto-Configuration
The OmniRoute dashboard automates configuration for most tools:
Ang dashboard ng OmniRoute ay nag-o-automate ng configuration para sa karamihan ng mga tool:
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. Pumunta sa `http://localhost:20128/dashboard/cli-tools`
2. Palawakin ang anumang tool card
3. Piliin ang iyong API key mula sa dropdown
4. I-click ang**Apply Config**(kung nakitang naka-install ang tool)
5. O kopyahin nang manu-mano ang nabuong config snippet---
## Built-in Agents: 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.
Ang**Droid**at**OpenClaw**ay mga ahente ng AI na direktang binuo sa OmniRoute — walang kinakailangang pag-install.
Tumatakbo sila bilang mga panloob na ruta at awtomatikong ginagamit ang pagruruta ng modelo ng OmniRoute.
- Access: `http://localhost:20128/dashboard/agents`
- Configure: same combos and providers as all other tools
- No API key or CLI install required
---
- I-configure: parehong combos at provider tulad ng lahat ng iba pang mga tool
- Walang kinakailangang pag-install ng API key o CLI---
## Available API Endpoints
| 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 | DALL-E, Flux, etc. |
| `/v1/audio/speech` | Text-to-speech | ElevenLabs, OpenAI TTS |
| `/v1/audio/transcriptions` | Speech-to-text | Deepgram, AssemblyAI |
---
| Endpoint | Paglalarawan | Gamitin Para sa |
| -------------------------- | ----------------------------------- | ------------------------------------ | --- |
| `/v1/chat/completions` | Karaniwang chat (lahat ng provider) | Lahat ng modernong kasangkapan |
| `/v1/mga tugon` | Responses API (OpenAI format) | Codex, mga ahenteng daloy ng trabaho |
| `/v1/completions` | Mga legacy na pagkumpleto ng text | Mga lumang tool gamit ang `prompt:` |
| `/v1/embeddings` | Mga pag-embed ng teksto | RAG, maghanap |
| `/v1/images/generations` | Pagbuo ng larawan | DALL-E, Flux, atbp. |
| `/v1/audio/speech` | Text-to-speech | ElevenLabs, OpenAI TTS |
| `/v1/audio/transcriptions` | Speech-to-text | Deepgram, AssemblyAI | --- |
## Pag-troubleshoot
| 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 <command>` |
| `kiro-cli: not found` | Not in PATH | `export PATH="$HOME/.local/bin:$PATH"` |
---
| Error | Dahilan | Ayusin |
| ------------------------------------------ | ----------------------------- | --------------------------------------------------------------- | --- |
| `Tumanggi sa koneksyon` | Hindi tumatakbo ang OmniRoute | `pm2 start omniroute` |
| `401 Hindi Pinahintulutan` | Maling API key | Mag-check in sa `/dashboard/api-manager` |
| `Walang combo na na-configure` | Walang aktibong routing combo | I-set up sa `/dashboard/combos` |
| `di-wastong modelo` | Wala sa catalog ang modelo | Gamitin ang `auto` o lagyan ng check ang `/dashboard/providers` |
| CLI ay nagpapakita ng "hindi naka-install" | Binary wala sa PATH | Lagyan ng check ang `aling <command>` |
| `kiro-cli: hindi nahanap` | Wala sa PATH | `export PATH="$HOME/.local/bin:$PATH"` | --- |
## Quick Setup Script (One Command)

View file

@ -4,19 +4,15 @@
---
> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
---
> Isang komprehensibo, madaling gabay sa baguhan sa**omniroute**multi-provider AI proxy router.---
## 1. What Is 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:
Ang omniroute ay isang**proxy router**na nasa pagitan ng mga kliyente ng AI (Claude CLI, Codex, Cursor IDE, atbp.) at mga tagapagbigay ng AI (Anthropic, Google, OpenAI, AWS, GitHub, atbp.). Malulutas nito ang isang malaking problema:
> **Different AI clients speak different "languages" (API formats), and different AI providers expect different "languages" too.** omniroute translates between them automatically.
> **Ang iba't ibang mga kliyente ng AI ay nagsasalita ng iba't ibang "mga wika" (mga format ng API), at ang iba't ibang mga tagapagbigay ng AI ay umaasa din ng iba't ibang "mga wika."**Ang omniroute ay awtomatikong nagsasalin sa pagitan ng mga ito.
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.
---
Isipin ito na parang isang unibersal na tagasalin sa United Nations — sinumang delegado ay maaaring magsalita ng anumang wika, at ang tagasalin ay nagko-convert nito para sa sinumang ibang delegado.---
## 2. Architecture Overview
@ -65,44 +61,43 @@ graph LR
### Core Principle: Hub-and-Spoke Translation
All format translation passes through **OpenAI format as the hub**:
Ang lahat ng pagsasalin ng format ay dumadaan sa**OpenAI na format bilang hub**:```
Client Format → [OpenAI Hub] → Provider Format (request)
Provider Format → [OpenAI Hub] → Client Format (response)
```
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).
---
Nangangahulugan ito na kailangan mo lamang ng**N na tagasalin**(isa bawat format) sa halip na**N²**(bawat pares).---
## 3. Project Structure
```
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/ ← 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
````
---
@ -110,18 +105,16 @@ omniroute/
### 4.1 Config (`open-sse/config/`)
The **single source of truth** for all provider configuration.
Ang**nag-iisang pinagmulan ng katotohanan**para sa lahat ng configuration ng provider.
| File | Purpose |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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). |
#### Credential Loading Flow
| File | Layunin |
| ----------------------------- | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| `constants.ts` | object na `PROVIDERS` na may mga base URL, mga kredensyal ng OAuth (mga default), header, at default na prompt ng system para sa bawat provider. Tinutukoy din ang `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, at `SKIP_PATTERNS`. |
| `credentialLoader.ts` | Naglo-load ng mga panlabas na kredensyal mula sa `data/provider-credentials.json` at pinagsasama ang mga ito sa mga naka-hardcode na default sa `PROVIDERS`. Pinapanatili ang mga lihim na wala sa kontrol ng pinagmulan habang pinapanatili ang pabalik na pagkakatugma. |
| `providerModels.ts` | Central model registry: maps provider aliases → model IDs. Mga function tulad ng `getModels()`, `getProviderByAlias()`. |
| `codexInstructions.ts` | Mga tagubilin ng system na ini-inject sa mga kahilingan sa Codex (mga hadlang sa pag-edit, mga panuntunan sa sandbox, mga patakaran sa pag-apruba). |
| `defaultThinkingSignature.ts` | Default na "pag-iisip" na mga lagda para sa mga modelong Claude at Gemini. |
| `ollamaModels.ts` | Depinisyon ng schema para sa mga lokal na modelo ng Ollama (pangalan, laki, pamilya, quantization). |#### Credential Loading Flow
```mermaid
flowchart TD
@ -140,24 +133,22 @@ flowchart TD
J --> F
F -->|Done| L["PROVIDERS ready with\nmerged credentials"]
E --> L
```
````
---
### 4.2 Executors (`open-sse/executors/`)
Executors encapsulate **provider-specific logic** using the **Strategy Pattern**. Each executor overrides base methods as needed.
```mermaid
Inilalagay ng mga tagapagpatupad ang**lohika na partikular sa provider**gamit ang**Pattern ng Diskarte**. Ino-override ng bawat executor ang mga base method kung kinakailangan.```mermaid
classDiagram
class BaseExecutor {
+buildUrl(model, stream, options)
+buildHeaders(credentials, stream, body)
+transformRequest(body, model, stream, credentials)
+execute(url, options)
+shouldRetry(status, error)
+refreshCredentials(credentials, log)
}
class BaseExecutor {
+buildUrl(model, stream, options)
+buildHeaders(credentials, stream, body)
+transformRequest(body, model, stream, credentials)
+execute(url, options)
+shouldRetry(status, error)
+refreshCredentials(credentials, log)
}
class DefaultExecutor {
+refreshCredentials()
@ -194,34 +185,31 @@ classDiagram
BaseExecutor <|-- CodexExecutor
BaseExecutor <|-- GeminiCLIExecutor
BaseExecutor <|-- GithubExecutor
```
| Executor | Provider | Key Specializations |
````
| Tagapagpatupad | Provider | Mga Pangunahing Espesyalisasyon |
| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `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` | — | Abstract base: Pagbuo ng URL, mga header, subukang muli ang logic, pag-refresh ng kredensyal |
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generic na OAuth token refresh para sa mga karaniwang provider |
| `antigravity.ts` | Google Cloud Code | Pagbuo ng Project/session ID, multi-URL fallback, custom na muling subukang pag-parse mula sa mga mensahe ng error ("i-reset pagkatapos ng 2h7m23s") |
| `cursor.ts` | Cursor IDE |**Pinakakumplikado**: SHA-256 checksum auth, Protobuf request encoding, binary EventStream → SSE response parsing |
| `codex.ts` | OpenAI Codex | Nag-inject ng mga tagubilin sa system, namamahala sa mga antas ng pag-iisip, nag-aalis ng mga hindi sinusuportahang parameter |
| `gemini-cli.ts` | Google Gemini CLI | Custom na pagbuo ng URL (`streamGenerateContent`), pag-refresh ng token ng Google OAuth |
| `github.ts` | GitHub Copilot | Dual token system (GitHub OAuth + Copilot token), paggaya ng header ng VSCode |
| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binary parsing, AMZN event frames, token estimation |
| `index.ts` | — | Pabrika: maps provider name → executor class, na may default na fallback |---
### 4.3 Handlers (`open-sse/handlers/`)
The **orchestration layer** — coordinates translation, execution, streaming, and error handling.
Ang**orchestration layer**— nag-coordinate ng pagsasalin, execution, streaming, at paghawak ng error.
| File | Purpose |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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. |
#### Request Lifecycle (chatCore.ts)
| File | Layunin |
| ---------------------- | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| `chatCore.ts` |**Central orchestrator**(~600 linya). Pinangangasiwaan ang kumpletong lifecycle ng kahilingan: pagtukoy ng format → pagsasalin → dispatch ng tagapagpatupad → tugon sa streaming/hindi streaming → pag-refresh ng token → paghawak ng error → pag-log sa paggamit. |
| `responsesHandler.ts` | Adapter para sa OpenAI's Responses API: kino-convert ang format ng Mga Tugon → Mga Pagkumpleto ng Chat → ipinapadala sa `chatCore` → ibinalik ang SSE sa format ng Mga Tugon. |
| `embeddings.ts` | Tagapangasiwa ng henerasyon ng pag-embed: niresolba ang modelo ng pag-embed → provider, ipinapadala sa API ng provider, ibinabalik ang tugon sa pag-embed na tugma sa OpenAI. Sinusuportahan ang 6+ provider. |
| `imageGeneration.ts` | Handler ng pagbuo ng imahe: niresolba ang modelo ng imahe → provider, sumusuporta sa OpenAI-compatible, Gemini-image (Antigravity), at fallback (Nebius) mode. Ibinabalik ang base64 o mga larawan ng URL. |#### Request Lifecycle (chatCore.ts)
```mermaid
sequenceDiagram
@ -256,30 +244,28 @@ sequenceDiagram
chatCore->>Executor: Retry with credential refresh
chatCore->>chatCore: Account fallback logic
end
```
````
---
### 4.4 Services (`open-sse/services/`)
Business logic that supports the handlers and executors.
| File | Purpose |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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. |
| Logic ng negosyo na sumusuporta sa mga humahawak at tagapagpatupad. | File | Purpose |
| ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `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. |
#### Token Refresh Deduplication
@ -348,9 +334,7 @@ flowchart LR
### 4.5 Translator (`open-sse/translator/`)
The **format translation engine** using a self-registering plugin system.
#### Arkitektura
Ang**format translation engine**gamit ang isang self-registering plugin system.#### Arkitektura
```mermaid
graph TD
@ -376,15 +360,13 @@ graph TD
end
```
| Directory | Files | Description |
| ------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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`. |
#### Key Design: Self-Registering Plugins
| Direktoryo | Mga file | Paglalarawan |
| --------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
| `kahilingan/` | 8 translators | I-convert ang mga katawan ng kahilingan sa pagitan ng mga format. Ang bawat file ay nagrerehistro sa sarili sa pamamagitan ng `register(from, to, fn)` sa pag-import. |
| `tugon/` | 7 tagasalin | I-convert ang mga tipak ng tugon sa streaming sa pagitan ng mga format. Pinangangasiwaan ang mga uri ng kaganapan sa SSE, mga bloke ng pag-iisip, mga tawag sa tool. |
| `mga katulong/` | 6 na katulong | Mga shared utilities: `claudeHelper` (system prompt extraction, thinking config), `geminiHelper` (parts/content mapping), `openaiHelper` (format filtering), `toolCallHelper` (ID generation, missing response injection), `maxTokensHelper`, `responsesApiHelper`. |
| `index.ts` | — | Translation engine: `translateRequest()`, `translateResponse()`, pamamahala ng estado, registry. |
| `formats.ts` | — | Mga constant ng format: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | #### Key Design: Self-Registering Plugins |
```javascript
// Each translator file calls register() on import:
@ -399,17 +381,15 @@ import "./request/claude-to-openai.js"; // ← self-registers
### 4.6 Utils (`open-sse/utils/`)
| File | Purpose |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `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` | File-based request logging (opt-in via `ENABLE_REQUEST_LOGS=true`). Creates session folders with numbered files: `1_req_client.json``7_res_client.txt`. All I/O is async (fire-and-forget). Masks sensitive headers. |
| `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. |
#### SSE Streaming Pipeline
| File | Layunin |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| `error.ts` | Error response building (OpenAI-compatible format), upstream error parsing, Antigravity retry-time extraction mula sa mga error message, SSE error streaming. |
| `stream.ts` | **SSE Transform Stream**— ang pangunahing streaming pipeline. Dalawang mode: `TRANSLATE` (full format translation) at `PASSTHROUGH` (normalize + ang paggamit ng extract). Pinangangasiwaan ang chunk buffering, pagtatantya ng paggamit, pagsubaybay sa haba ng nilalaman. Ang mga instance ng per-stream encoder/decoder ay umiiwas sa nakabahaging estado. |
| `streamHelpers.ts` | Mga utility na mababa ang antas ng SSE: `parseSSELine` (whitespace-tolerant), `hasValuableContent` (filter ang mga walang laman na chunks para sa OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (format-aware SSE serialization na may `perf_metrics` cleanup). |
| `usageTracking.ts` | Pagkuha ng paggamit ng token mula sa anumang format (Claude/OpenAI/Gemini/Responses), pagtatantya na may hiwalay na tool/message char-per-token ratios, pagdaragdag ng buffer (2000 token safety margin), pag-filter ng field na partikular sa format, console logging na may mga kulay ng ANSI. |
| `requestLogger.ts` | Nakabatay sa file ang pag-log ng kahilingan (opt-in sa pamamagitan ng `ENABLE_REQUEST_LOGS=true`). Gumagawa ng mga folder ng session na may mga file na may numero: `1_req_client.json``7_res_client.txt`. Ang lahat ng I/O ay async (fire-and-forget). Maskara ang mga sensitibong header. |
| `bypassHandler.ts` | Hinaharang ang mga partikular na pattern mula kay Claude CLI (pagkuha ng pamagat, warmup, count) at ibinabalik ang mga pekeng tugon nang hindi tumatawag sa anumang provider. Sinusuportahan ang parehong streaming at hindi streaming. Sinasadyang limitado sa saklaw ng Claude CLI. |
| `networkProxy.ts` | Nire-resolve ang outbound proxy URL para sa isang ibinigay na provider nang nangunguna: provider-specific config → global config → environment variables (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Sinusuportahan ang mga pagbubukod ng `NO_PROXY`. Caches config para sa 30s. | #### SSE Streaming Pipeline |
```mermaid
flowchart TD
@ -451,103 +431,81 @@ logs/
### 4.7 Application Layer (`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 |
| Direktoryo | Layunin |
| ------------- | -------------------------------------------------------------------------------- | ----------------------- |
| `src/app/` | Web UI, mga ruta ng API, Express middleware, OAuth callback handler |
| `src/lib/` | Access sa database (`localDb.ts`, `usageDb.ts`), pagpapatunay, ibinahagi |
| `src/mitm/` | Man-in-the-middle proxy utility para sa pagharang sa trapiko ng provider |
| `src/models/` | Mga kahulugan ng modelo ng database |
| `src/shared/` | Mga wrapper sa paligid ng mga open-sse function (provider, stream, error, atbp.) |
| `src/sse/` | SSE endpoint handler na nag-wire ng open-sse library sa Express na mga ruta |
| `src/store/` | Pamamahala ng estado ng aplikasyon | #### Notable API Routes |
#### Notable API Routes
| 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 |
---
| Route | Mga Paraan | Layunin |
| --------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------- | --- |
| `/api/provider-models` | GET/POST/DELETE | CRUD para sa mga custom na modelo sa bawat provider |
| `/api/models/catalog` | KUMUHA | Pinagsama-samang catalog ng lahat ng modelo (chat, pag-embed, larawan, custom) na nakapangkat ayon sa provider |
| `/api/setting/proxy` | GET/PUT/DELETE | Hierarchical outbound proxy configuration (`global/providers/combos/keys`) |
| `/api/settings/proxy/test` | POST | Pinapatunayan ang koneksyon ng proxy at ibinabalik ang pampublikong IP/latency |
| `/v1/providers/[provider]/chat/completions` | POST | Nakatuon sa bawat provider na mga pagkumpleto ng chat na may pagpapatunay ng modelo |
| `/v1/providers/[provider]/embeddings` | POST | Mga nakalaang pag-embed ng bawat provider na may pagpapatunay ng modelo |
| `/v1/providers/[provider]/images/generations` | POST | Nakatuon sa pagbuo ng larawan ng bawat provider na may pagpapatunay ng modelo |
| `/api/settings/ip-filter` | GET/PUT | Pamamahala ng IP allowlist/blocklist |
| `/api/setting/thinking-budget` | GET/PUT | Reasoning token configuration ng badyet (passthrough/auto/custom/adaptive) |
| `/api/settings/system-prompt` | GET/PUT | Global system prompt injection para sa lahat ng kahilingan |
| `/api/sessions` | KUMUHA | Aktibong pagsubaybay sa session at mga sukatan |
| `/api/rate-limits` | KUMUHA | Katayuan ng limitasyon sa rate ng bawat account | --- |
## 5. Key Design Patterns
### 5.1 Hub-and-Spoke Translation
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.
Ang lahat ng mga format ay isinasalin sa pamamagitan ng**OpenAI format bilang hub**. Ang pagdaragdag ng bagong provider ay nangangailangan lamang ng pagsulat ng**isang pares**ng mga tagasalin (sa/mula sa OpenAI), hindi N pares.### 5.2 Executor Strategy Pattern
### 5.2 Executor Strategy Pattern
Ang bawat provider ay may nakalaang executor class na nagmana mula sa `BaseExecutor`. Pinipili ng factory sa `executors/index.ts` ang tama sa runtime.### 5.3 Self-Registering Plugin System
Each provider has a dedicated executor class inheriting from `BaseExecutor`. The factory in `executors/index.ts` selects the right one at runtime.
Inirerehistro ng mga module ng tagasalin ang kanilang mga sarili sa pag-import sa pamamagitan ng `register()`. Ang pagdaragdag ng bagong tagasalin ay paggawa lamang ng file at pag-import nito.### 5.4 Account Fallback with Exponential Backoff
### 5.3 Self-Registering Plugin System
Kapag nagbalik ang isang provider ng 429/401/500, maaaring lumipat ang system sa susunod na account, na naglalapat ng mga exponential cooldown (1s → 2s → 4s → max 2min).### 5.5 Combo Model Chains
Translator modules register themselves on import via `register()`. Adding a new translator is just creating a file and importing it.
Pinagpangkat ng isang "combo" ang maraming string ng `provider/model`. Kung nabigo ang una, awtomatikong mag-fallback sa susunod.### 5.6 Stateful Streaming Translation
### 5.4 Account Fallback with Exponential Backoff
Ang pagsasalin ng tugon ay nagpapanatili ng estado sa mga bahagi ng SSE (pagsubaybay sa pag-iisip ng block, pag-iipon ng tawag sa tool, pag-index ng block ng nilalaman) sa pamamagitan ng mekanismong `initState()`.### 5.7 Usage Safety Buffer
When a provider returns 429/401/500, the system can switch to the next account, applying exponential cooldowns (1s → 2s → 4s → max 2min).
### 5.5 Combo Model Chains
A "combo" groups multiple `provider/model` strings. If the first fails, fallback to the next automatically.
### 5.6 Stateful Streaming Translation
Response translation maintains state across SSE chunks (thinking block tracking, tool call accumulation, content block indexing) via the `initState()` mechanism.
### 5.7 Usage Safety Buffer
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.
---
Ang isang 2000-token buffer ay idinagdag sa iniulat na paggamit upang maiwasan ang mga kliyente na maabot ang mga limitasyon sa window ng konteksto dahil sa overhead mula sa mga prompt ng system at pagsasalin ng format.---
## 6. Supported Formats
| Format | Direction | 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` |
---
| Format | Direksyon | Identifier |
| ------------------------------ | ------------------- | ------------------ | --- |
| Mga Pagkumpleto ng OpenAI Chat | pinagmulan + target | `openai` |
| OpenAI Responses API | pinagmulan + target | `openai-responses` |
| Anthropic Claude | pinagmulan + target | `claude` |
| Google Gemini | pinagmulan + target | `gemini` |
| Google Gemini CLI | target lang | `gemini-cli` |
| Antigravity | pinagmulan + target | `antigravity` |
| AWS Kiro | target lang | `kiro` |
| Cursor | target lang | `cursor` | --- |
## 7. Supported Providers
| 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 |
---
| Provider | Paraan ng Pagpapatunay | Tagapagpatupad | Pangunahing Tala |
| ------------------------ | ---------------------- | -------------- | -------------------------------------------------------------- | --- |
| Anthropic Claude | API key o OAuth | Default | Gumagamit ng `x-api-key` na header |
| Google Gemini | API key o OAuth | Default | Gumagamit ng `x-goog-api-key` na header |
| Google Gemini CLI | OAuth | GeminiCLI | Gumagamit ng `streamGenerateContent` endpoint |
| Antigravity | OAuth | Antigravity | Multi-URL fallback, custom na muling subukang pag-parse |
| OpenAI | API key | Default | Standard Bearer auth |
| Codex | OAuth | Codex | Nag-inject ng mga tagubilin sa system, namamahala sa pag-iisip |
| GitHub Copilot | OAuth + Copilot token | Github | Dual token, paggaya ng header ng VSCode |
| Kiro (AWS) | AWS SSO OIDC o Social | Kiro | Binary EventStream pag-parse |
| Cursor IDE | Checksum auth | Cursor | Protobuf encoding, SHA-256 checksums |
| Qwen | OAuth | Default | Karaniwang pagpapatunay |
| Qoder | OAuth (Basic + Bearer) | Default | Dual auth header |
| OpenRouter | API key | Default | Standard Bearer auth |
| GLM, Kimi, MiniMax | API key | Default | Claude-compatible, gumamit ng `x-api-key` |
| `openai-compatible-*` | API key | Default | Dynamic: anumang endpoint na katugma sa OpenAI |
| `anthropic-compatible-*` | API key | Default | Dynamic: anumang endpoint na katugma sa Claude | --- |
## 8. Data Flow Summary

View file

@ -4,155 +4,129 @@
---
Last updated: 2026-03-28
Huling na-update: 2026-03-28## Baseline
## Baseline
Mayroong maramihang mga numero ng saklaw depende sa kung paano nakalkula ang ulat. Para sa pagpaplano, isa lamang sa kanila ang kapaki-pakinabang.
There are multiple coverage numbers depending on how the report is computed. For planning, only one of them is useful.
| Sukatan | Saklaw | Mga Pahayag / Mga Linya | Mga sangay | Mga Pag-andar | Mga Tala |
| ------------------------- | ------------------------------------------------------------------------- | ----------------------: | ---------: | ------------: | --------------------------------------------------------------------- |
| Legacy | Lumang `npm run test:coverage` | 79.42% | 75.15% | 67.94% | Napalaki: binibilang ang mga test file at hindi kasama ang `open-sse` |
| Diagnostic | Source-only, hindi kasama ang mga pagsubok at hindi kasama ang `open-sse` | 68.16% | 63.55% | 64.06% | Kapaki-pakinabang lamang upang ihiwalay ang `src/**` |
| Inirerekomendang baseline | Source-only, hindi kasama ang mga pagsubok at kabilang ang `open-sse` | 56.95% | 66.05% | 57.80% | Ito ang baseline sa buong proyekto upang mapabuti ang |
| 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 |
Ang inirerekomendang baseline ay ang numerong i-optimize.## Rules
The recommended baseline is the number to optimize against.
## Rules
- 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/**`.
## Current command set
- Nalalapat ang mga target sa saklaw sa mga source file, hindi sa `mga pagsubok/**`.
- Ang `open-sse/**` ay bahagi ng produkto at dapat manatili sa saklaw.
- Hindi dapat bawasan ng bagong code ang saklaw sa mga nahawakang lugar.
- Mas gusto ang gawi sa pagsubok at mga resulta ng sangay kaysa sa mga detalye ng pagpapatupad.
- Mas gusto ang mga temp SQLite database at maliliit na fixture kaysa sa malawak na pangungutya para sa `src/lib/db/**`.## Current command set
- `npm run test:coverage`
- Main source coverage gate for the unit test suite
- Generates `text-summary`, `html`, `json-summary`, and `lcov`
- Main source coverage gate para sa unit test suite
- Bumubuo ng `text-summary`, `html`, `json-summary`, at `lcov`
- `npm run coverage:report`
- Detailed file-by-file report from the latest run
- Detalyadong file-by-file na ulat mula sa pinakabagong run
- `npm run test:coverage:legacy`
- Historical comparison only
- Makasaysayang paghahambing lamang## Milestones
## Milestones
| Yugto | Target | Tumutok |
| ------- | -------------------------: | ----------------------------------------------------------------- |
| Phase 1 | 60% na pahayag / linya | Mabilis na panalo at mababang panganib na saklaw ng utility |
| Phase 2 | 65% na pahayag / linya | DB at mga pundasyon ng ruta |
| Phase 3 | 70% na pahayag / linya | Pagpapatunay ng provider at analytics ng paggamit |
| Phase 4 | 75% na pahayag / linya | Mga tagasalin at katulong ng `open-sse` |
| Phase 5 | 80% na pahayag / linya | `open-sse` handlers at executor branch |
| Phase 6 | 85% na pahayag / linya | Mas mahirap na mga kaso, utang ng sangay, mga suite ng regression |
| Phase 7 | 90% na mga pahayag / linya | Final sweep, pagsasara ng puwang, mahigpit na ratchet |
| 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 |
Ang mga sanga at function ay dapat na pataas sa bawat yugto, ngunit ang pangunahing mahirap na target ay mga pahayag / linya.## Priority hotspots
Branches and functions should ratchet upward with each phase, but the primary hard target is statements / lines.
## Priority hotspots
These files or areas offer the best return for the next phases:
Ang mga file o lugar na ito ay nag-aalok ng pinakamahusay na pagbabalik para sa mga susunod na yugto:
1. `open-sse/handlers`
- `chatCore.ts` at 7.57%
- Overall directory at 29.07%
- `chatCore.ts` sa 7.57%
- Pangkalahatang direktoryo sa 29.07%
2. `open-sse/translator/request`
- Overall directory at 36.39%
- Many translators are still near single-digit coverage
- Pangkalahatang direktoryo sa 36.39%
- Maraming tagasalin ang malapit pa rin sa single-digit na saklaw
3. `open-sse/translator/response`
- Overall directory at 8.07%
- Pangkalahatang direktoryo sa 8.07%
4. `open-sse/executors`
- Overall directory at 36.62%
- Pangkalahatang direktoryo sa 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` sa 20.66%
- `registeredKeys.ts` sa 34.46%
- `modelComboMappings.ts` sa 36.25%
- `settings.ts` sa 46.40%
- `webhooks.ts` sa 33.33%
6. `src/lib/usage`
- `usageHistory.ts` at 21.12%
- `usageStats.ts` at 9.56%
- `costCalculator.ts` at 30.00%
- `usageHistory.ts` sa 21.12%
- `usageStats.ts` sa 9.56%
- `costCalculator.ts` sa 30.00%
7. `src/lib/providers`
- `validation.ts` at 41.16%
8. Low-risk utility and API files for early gains
- `validation.ts` sa 41.16%
8. Low-risk utility at mga API file para sa maagang mga pakinabang
- `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
- `src/app/api/providers/[id]/models/route.ts`## Execution checklist
### Phase 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] Ayusin ang sukatan ng saklaw upang maipakita nito ang source code sa halip na mga pansubok na file
- [x] Panatilihin ang isang legacy coverage script para sa paghahambing
- [x] Itala ang baseline at mga hotspot na in-repo
- [ ] Magdagdag ng mga nakatutok na pagsubok para sa mga utility na mababa ang panganib:
- `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:
- [ ] Magdagdag ng mga pagsubok sa ruta para sa:
- `src/app/api/settings/require-login/route.ts`
- `src/app/api/providers/[id]/models/route.ts`
- `src/app/api/providers/[id]/models/route.ts`### Phase 2: 60% -> 65%
### Phase 2: 60% -> 65%
- [ ] Add DB-backed tests for:
- [ ] Magdagdag ng mga DB-backed na pagsubok para sa:
- `src/lib/db/modelComboMappings.ts`
- `src/lib/db/settings.ts`
- `src/lib/db/registeredKeys.ts`
- [ ] Cover branch behavior in:
- [ ] Takpan ang pag-uugali ng sangay sa:
- `src/lib/providers/validation.ts`
- `src/app/api/v1/embeddings/route.ts`
- `src/app/api/v1/moderations/route.ts`
- `src/app/api/v1/moderations/route.ts`### Phase 3: 65% -> 70%
### Phase 3: 65% -> 70%
- [ ] Add usage analytics tests for:
- [ ] Magdagdag ng mga pagsusuri sa analytics ng paggamit para sa:
- `src/lib/usage/usageHistory.ts`
- `src/lib/usage/usageStats.ts`
- `src/lib/usage/costCalculator.ts`
- [ ] Expand route coverage for proxy management and settings branches
- [ ] Palawakin ang saklaw ng ruta para sa pamamahala ng proxy at mga sangay ng mga setting### Phase 4: 70% -> 75%
### Phase 4: 70% -> 75%
- [ ] Cover translator helpers and central translation paths:
- [ ] Cover translator helpers at central translation path:
- `open-sse/translator/index.ts`
- `open-sse/translator/helpers/*`
- `open-sse/translator/request/*`
- `open-sse/translator/response/*`
- `open-sse/translator/response/*`### Phase 5: 75% -> 80%
### Phase 5: 75% -> 80%
- [ ] Add handler-level tests for:
- [ ] Magdagdag ng mga pagsubok sa antas ng handler para sa:
- `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
- [ ] Magdagdag ng saklaw ng sangay ng tagapagpatupad para sa pagpapatunay na partikular sa provider, muling pagsubok, at pag-override ng endpoint### Phase 6: 80% -> 85%
### Phase 6: 80% -> 85%
- [ ] Pagsamahin ang higit pang mga edge-case suite sa pangunahing landas ng saklaw
- [ ] Palakihin ang saklaw ng function para sa mga DB module na may mahinang saklaw ng constructor/helper
- [ ] Isara ang mga puwang ng sangay sa `settings.ts`, `registeredKeys.ts`, `validation.ts`, at translator helper### Phase 7: 85% -> 90%
- [ ] 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
- [ ] Tratuhin ang natitirang mga file na mababa ang saklaw bilang mga blocker
- [ ] Magdagdag ng mga pagsubok sa regression para sa bawat natuklasang bug ng produksyon na naayos sa panahon ng push hanggang 90%
- [ ] Itaas ang gate ng coverage sa CI pagkatapos lang maging stable ang lokal na baseline para sa hindi bababa sa dalawang magkasunod na pagtakbo## Ratchet policy
### Phase 7: 85% -> 90%
I-update ang mga threshold ng `npm run test:coverage` pagkatapos aktwal na lumampas ang proyekto sa susunod na milestone na may komportableng buffer.
- [ ] 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
## Ratchet policy
Update `npm run test:coverage` thresholds only after the project actually exceeds the next milestone with a comfortable buffer.
Recommended ratchet sequence:
Inirerekomendang ratchet sequence:
1. 55/60/55
2. 60/62/58
@ -163,8 +137,6 @@ Recommended ratchet sequence:
7. 85/80/84
8. 90/85/88
Order is `statements-lines / branches / functions`.
Ang order ay `statements-lines / branches / functions`.## Known gap
## Known gap
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.
Ang kasalukuyang coverage command ay sumusukat sa pangunahing Node unit suite at kasama ang source na naabot mula dito, kasama ang `open-sse`. Hindi pa nito pinagsasama ang saklaw ng Vitest sa isang pinag-isang ulat. Ang pagsasanib na iyon ay sulit na gawin sa ibang pagkakataon, ngunit hindi ito isang blocker para sa pagsisimula ng 60% -> 80% na pag-akyat.

View file

@ -4,142 +4,102 @@
---
Visual guide to every section of the OmniRoute dashboard.
---
Visual na gabay sa bawat seksyon ng OmniRoute dashboard.---
## 🔌 Providers
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.
![Providers Dashboard](screenshots/01-providers.png)
Pamahalaan ang mga koneksyon sa AI provider: OAuth provider (Claude Code, Codex, Gemini CLI), API key provider (Groq, DeepSeek, OpenRouter), at libreng provider (Qoder, Qwen, Kiro). Kasama sa mga Kiro account ang pagsubaybay sa balanse ng kredito — mga natitirang credit, kabuuang allowance, at petsa ng pag-renew na makikita sa Dashboard → Paggamit.![Providers Dashboard](screenshots/01-providers.png)
---
## 🎨 Combos
Create model routing combos with 6 strategies: priority, weighted, round-robin, random, least-used, and cost-optimized. Each combo chains multiple models with automatic fallback and includes quick templates and readiness checks.
![Combos Dashboard](screenshots/02-combos.png)
Gumawa ng mga combo sa pagruruta ng modelo na may 6 na diskarte: priority, weighted, round-robin, random, hindi gaanong ginagamit, at cost-optimized. Ang bawat combo ay nagkakadena ng maraming modelo na may awtomatikong fallback at may kasamang mabilis na mga template at mga pagsusuri sa kahandaan.![Combos Dashboard](screenshots/02-combos.png)
---
## 📊 Analytics
Comprehensive usage analytics with token consumption, cost estimates, activity heatmaps, weekly distribution charts, and per-provider breakdowns.
![Analytics Dashboard](screenshots/03-analytics.png)
Komprehensibong analytics ng paggamit na may pagkonsumo ng token, mga pagtatantya sa gastos, mga heatmap ng aktibidad, lingguhang chart ng pamamahagi, at mga breakdown sa bawat provider.![Analytics Dashboard](screenshots/03-analytics.png)
---
## 🏥 System Health
Real-time monitoring: uptime, memory, version, latency percentiles (p50/p95/p99), cache statistics, and provider circuit breaker states.
![Health Dashboard](screenshots/04-health.png)
Real-time na pagsubaybay: uptime, memorya, bersyon, latency percentiles (p50/p95/p99), mga istatistika ng cache, at mga estado ng circuit breaker ng provider.![Health Dashboard](screenshots/04-health.png)
---
## 🔧 Translator Playground
Four modes for debugging API translations: **Playground** (format converter), **Chat Tester** (live requests), **Test Bench** (batch tests), and **Live Monitor** (real-time stream).
![Translator Playground](screenshots/05-translator.png)
Apat na mode para sa pag-debug ng mga pagsasalin ng API:**Playground**(format converter),**Chat Tester**(live na kahilingan),**Test Bench**(batch tests), at**Live Monitor**(real-time stream).![Translator Playground](screenshots/05-translator.png)
---
## 🎮 Model Playground _(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.
---
Subukan ang anumang modelo nang direkta mula sa dashboard. Pumili ng provider, modelo, at endpoint, magsulat ng mga prompt gamit ang Monaco Editor, mag-stream ng mga tugon sa real-time, i-abort ang mid-stream, at tingnan ang mga sukatan ng timing.---
## 🎨 Themes _(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.
---
Nako-customize na mga tema ng kulay para sa buong dashboard. Pumili mula sa 7 preset na kulay (Coral, Blue, Red, Green, Violet, Orange, Cyan) o gumawa ng custom na tema sa pamamagitan ng pagpili ng anumang hex na kulay. Sinusuportahan ang liwanag, madilim, at system mode.---
## ⚙️ Settings
Comprehensive settings panel with tabs:
Panel ng kumpletong mga setting na may mga 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
- **Advanced** — Configuration overrides, configuration audit trail, fallback degradation mode
![Settings Dashboard](screenshots/06-settings.png)
-**General**— System storage, backup management (export/import database) -**Hitsura**— Tagapili ng tema (madilim/liwanag/system), mga preset ng tema ng kulay at mga custom na kulay, visibility ng log ng kalusugan, mga kontrol sa visibility ng item sa sidebar -**Seguridad**— Proteksyon ng endpoint ng API, custom na pagharang ng provider, pag-filter ng IP, impormasyon ng session -**Pagruruta**— Mga alyas ng modelo, pagkasira ng gawain sa background -**Resilience**— Pagpapatuloy ng limitasyon sa rate, pag-tune ng circuit breaker, awtomatikong i-disable ang mga naka-ban na account, pagsubaybay sa expiration ng provider -**Advanced**— Mga override sa configuration, configuration audit trail, fallback degradation mode![Settings Dashboard](screenshots/06-settings.png)
---
## 🔧 CLI Tools
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.
![CLI Tools Dashboard](screenshots/07-cli-tools.png)
Isang-click na configuration para sa AI coding tool: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor, at Factory Droid. Nagtatampok ng awtomatikong paglalapat/pag-reset ng config, mga profile ng koneksyon, at pagmamapa ng modelo.![CLI Tools Dashboard](screenshots/07-cli-tools.png)
---
## 🤖 CLI Agents _(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 para sa pagtuklas at pamamahala ng mga ahente ng CLI. Nagpapakita ng grid ng 14 na built-in na ahente (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) na may:
- **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
---
-**Katayuan ng pag-install**— Naka-install / Hindi Natagpuan na may pagtukoy ng bersyon -**Protocol badge**— stdio, HTTP, atbp. -**Mga custom na ahente**— Magrehistro ng anumang CLI tool sa pamamagitan ng form (pangalan, binary, version command, spawn args) -**Pagtutugma ng CLI Fingerprint**— Toggle ng bawat provider upang tumugma sa mga native na lagda ng kahilingan sa CLI, na binabawasan ang panganib sa pagbabawal habang pinapanatili ang proxy IP---
## 🖼️ 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.
---
Bumuo ng mga larawan, video, at musika mula sa dashboard. Sinusuportahan ang OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open, at MusicGen.---
## 📝 Request Logs
Real-time request logging with filtering by provider, model, account, and API key. Shows status codes, token usage, latency, and response details.
![Usage Logs](screenshots/08-usage.png)
Real-time na pag-log ng kahilingan gamit ang pag-filter ayon sa provider, modelo, account, at API key. Nagpapakita ng mga status code, paggamit ng token, latency, at mga detalye ng pagtugon.![Usage Logs](screenshots/08-usage.png)
---
## 🌐 API Endpoint
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 Dashboard](screenshots/09-endpoint.png)
Ang iyong pinag-isang API endpoint na may pagkasira ng kakayahan: Mga Pagkumpleto ng Chat, Mga Tugon na API, Mga Pag-embed, Pagbuo ng Larawan, Muling Ranggo, Transkripsyon ng Audio, Text-to-Speech, Mga Moderation, at mga nakarehistrong API key. Cloudflare Quick Tunnel integration at suporta sa cloud proxy para sa malayuang pag-access.![Endpoint Dashboard](screenshots/09-endpoint.png)
---
## 🔑 API Key Management
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.
---
Gumawa, saklaw, at bawiin ang mga API key. Ang bawat key ay maaaring paghigpitan sa mga partikular na modelo/provider na may ganap na access o read-only na mga pahintulot. Pamamahala ng visual key na may pagsubaybay sa paggamit.---
## 📋 Audit Log
Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history.
---
Pagsubaybay sa administratibong pagkilos na may pag-filter ayon sa uri ng pagkilos, aktor, target, IP address, at timestamp. Buong kasaysayan ng kaganapan sa seguridad.---
## 🖥️ Desktop Application
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.
Native Electron desktop app para sa Windows, macOS, at Linux. Patakbuhin ang OmniRoute bilang isang standalone na application na may system tray integration, offline na suporta, auto-update, at one-click na pag-install.
Key features:
Mga pangunahing tampok:
- Server readiness polling (no blank screen on cold start)
- System tray with port management
- Content Security Policy
- Pagboto sa kahandaan ng server (walang blangkong screen sa malamig na simula)
- System tray na may port management
- Patakaran sa Seguridad ng Nilalaman
- Single-instance lock
- Auto-update on restart
- Auto-update sa pag-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+)
- Hardened Electron build packaging — ang mga naka-symlink na `node_modules` sa standalone na bundle ay nakita at tinanggihan bago ang packaging, na pumipigil sa runtime dependency sa build machine (v2.5.5+)
📖 See [`electron/README.md`](../electron/README.md) for full documentation.
📖 Tingnan ang [`electron/README.md`](../electron/README.md) para sa buong dokumentasyon.

View file

@ -10,66 +10,55 @@
- 后续代码更新后继续发布
- 新项目参考同样流程部署
本文基于当前项目已经验证通过的配置整理,应用名为 `omniroute`
---
本文基于当前项目已经验证通过的配置整理,应用名为 `omniroute`。---
## 1. 部署目标
- 平台Fly.io
- 部署方式:本地 `flyctl` 直接发布
- 运行方式:使用仓库内现有 `Dockerfile``fly.toml`
- 数据持久化Fly Volume 挂载到 `/data`
- 访问地址:`https://omniroute.fly.dev/`
---
- 数据持久化Dami ng Lumipad 挂载到 `/data`
- 访问地址:`https://omniroute.fly.dev/`---
## 2. 当前项目关键配置
当前仓库中的 `fly.toml` 已确认包含以下关键项:
```toml
当前仓库中的 `fly.toml` 已确认包含以下关键项:```toml
app = 'omniroute'
primary_region = 'sin'
[[mounts]]
source = 'data'
destination = '/data'
source = 'data'
destination = '/data'
[processes]
app = 'node run-standalone.mjs'
app = 'node run-standalone.mjs'
[http_service]
internal_port = 20128
internal_port = 20128
[env]
TZ = "Asia/Shanghai"
HOST = "0.0.0.0"
HOSTNAME = "0.0.0.0"
BIND = "0.0.0.0"
```
TZ = "Asia/Shanghai"
HOST = "0.0.0.0"
HOSTNAME = "0.0.0.0"
BIND = "0.0.0.0"
````
说明:
- `app = 'omniroute'` 决定实际部署到哪个 Fly 应用
- `app = 'omniroute'` 决定实际部署到哪个 Lumipad 应用
- `destination = '/data'` 决定持久卷挂载目录
- 本项目必须让 `DATA_DIR=/data`,否则数据库和密钥会写到容器临时目录
---
- 本项目必须让 `DATA_DIR=/data`,否则数据库和密钥会写到容器临时目录---
## 3. 必备工具
### 3.1 安装 Fly CLI
Windows PowerShell
```powershell
Windows PowerShell:```powershell
pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"
```
````
如果安装脚本在当前环境失败,也可以手动下载 `flyctl` 二进制并放到 `PATH` 中。
### 3.2 登录 Fly 账号
如果安装脚本在当前环境失败,也可以手动下载 `flyctl` 二进制并放到 `PATH` 中。### 3.2 登录 Fly 账号
```powershell
flyctl auth login
@ -95,46 +84,36 @@ cd OmniRoute
### 4.2 确认应用名
打开 `fly.toml`,重点看这一行:
```toml
打开 `fly.toml`,重点看这一行:```toml
app = 'omniroute'
```
如果你准备部署到自己的新应用,可改成全局唯一名称,例如:
````
```toml
如果你准备部署到自己的新应用,可改成全局唯一名称,例如:```toml
app = 'omniroute-yourname'
```
````
注意:
- 控制台里要看的是与 `fly.toml``app` 一致的应用
- 以前如果用过别的名字,例如 `oroute`,不要和 `omniroute` 混淆
- 以前如果用过别的名字,例如 `oroute`,不要和 `omniroute` 混淆### 4.3 创建应用
### 4.3 创建应用
如果该应用尚不存在:
```powershell
如果该应用尚不存在:```powershell
flyctl apps create omniroute
```
如果你已经改成别的应用名,把 `omniroute` 替换成你的名字。
````
### 4.4 首次部署
如果你已经改成别的应用名,把 `omniroute` 替换成你的名字。### 4.4 首次部署
```powershell
flyctl deploy
```
````
---
## 5. 必配参数
本项目在 Fly.io 上建议至少配置以下参数。
### 5.1 已验证使用的参数
本项目在 Fly.io 上建议至少配置以下参数。### 5.1 已验证使用的参数
这些参数已经在当前 `omniroute` 应用上实际部署:
@ -143,9 +122,7 @@ flyctl deploy
- `JWT_SECRET`
- `MACHINE_ID_SALT`
- `NEXT_PUBLIC_BASE_URL`
- `STORAGE_ENCRYPTION_KEY`
### 5.2 关于 `INITIAL_PASSWORD`
- `STORAGE_ENCRYPTION_KEY`### 5.2 关于 `INITIAL_PASSWORD`
当前项目没有设置 `INITIAL_PASSWORD`,因为本次部署按需求不使用它。
@ -156,26 +133,22 @@ flyctl deploy
如果你希望无人值守初始化后台密码,也可以后续补:
- `INITIAL_PASSWORD`
---
- `INITIAL_PASSWORD`---
## 6. 推荐参数说明
### 6.1 Secrets 中设置
建议放入 Fly Secrets
建议放入 Mga Lihim na Lumipad
| 变量名 | 是否推荐 | 说明 |
| ------------------------ | -------- | ------------------------------ |
| ------------------------ | -------- | ------------------------------ | ---------------------- |
| `API_KEY_SECRET` | 必需 | API Key 生成与校验使用 |
| `JWT_SECRET` | 必需 | 登录态和 JWT 签名使用 |
| `STORAGE_ENCRYPTION_KEY` | 强烈推荐 | 加密存储敏感连接信息 |
| `MACHINE_ID_SALT` | 推荐 | 生成稳定机器标识 |
| `INITIAL_PASSWORD` | 可选 | 首次部署时直接指定后台初始密码 |
| OAuth/API 私密凭证 | 按需 | 各类外部平台鉴权配置 |
### 6.2 当前项目推荐值
| OAuth/API 私密凭证 | 按需 | 各类外部平台鉴权配置 | ### 6.2 当前项目推荐值 |
| 变量名 | 推荐值 |
| ---------------------- | --------------------------- |
@ -184,10 +157,8 @@ flyctl deploy
说明:
- `DATA_DIR=/data` 非常关键,必须与 Fly Volume 挂载点一致
- `NEXT_PUBLIC_BASE_URL` 用于调度器和前端回调等场景
---
- `DATA_DIR=/data` 非常关键,必须与 Dami ng Lumipad 挂载点一致
- `NEXT_PUBLIC_BASE_URL` 用于调度器和前端回调等场景---
## 7. 一键设置参数
@ -196,29 +167,23 @@ flyctl deploy
说明:
- 不包含 `INITIAL_PASSWORD`
- 适用于当前项目 `omniroute`
```powershell
$apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
- 适用于当前项目 `omniroute````powershell
$apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
$jwtSecret = [Convert]::ToHexString((1..64 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
$machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
$machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
$storageKey = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
flyctl secrets set `
API_KEY_SECRET=$apiKeySecret `
JWT_SECRET=$jwtSecret `
MACHINE_ID_SALT=$machineIdSalt `
STORAGE_ENCRYPTION_KEY=$storageKey `
DATA_DIR=/data `
NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev `
-a omniroute
```
flyctl secrets set ` API_KEY_SECRET=$apiKeySecret`
JWT_SECRET=$jwtSecret `
MACHINE_ID_SALT=$machineIdSalt ` STORAGE_ENCRYPTION_KEY=$storageKey`
DATA_DIR=/data ` NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev`
-a omniroute
如果你还要加初始密码:
````
```powershell
如果你还要加初始密码:```powershell
flyctl secrets set INITIAL_PASSWORD=你的强密码 -a omniroute
```
````
---
@ -228,104 +193,84 @@ flyctl secrets set INITIAL_PASSWORD=你的强密码 -a omniroute
flyctl secrets list -a omniroute
```
如果控制台 `Secrets` 页面没有显示你期待的变量,先检查:
如果控制台 `Mga Lihim` 页面没有显示你期待的变量,先检查:
- 看的应用是不是 `omniroute`
- `fly.toml``app` 是否和控制台应用一致
---
- `fly.toml``app` 是否和控制台应用一致---
## 9. 后续更新发布
代码有更新后,发布步骤很简单:
```powershell
代码有更新后,发布步骤很简单:```powershell
git pull
flyctl deploy
```
如果只更新参数,不改代码:
````
```powershell
如果只更新参数,不改代码:```powershell
flyctl secrets set KEY=value -a omniroute
```
````
Fly 会自动滚动更新机器。
Lumipad 会自动滚动更新机器。### 9.1 跟踪原仓库更新并保留 fork 的 `fly.toml`
### 9.1 跟踪原仓库更新并保留 fork 的 `fly.toml`
如果当前仓库是 tinidor并且你要同步上游 `https://github.com/diegosouzapw/OmniRoute` 的更新,推荐按下面按下猢按下猢。
如果当前仓库是 fork并且你要同步上游 `https://github.com/diegosouzapw/OmniRoute` 的更新,推荐按下面流程执行。
先确认远程:
```powershell
先确认远程:```powershell
git remote -v
```
````
应至少包含:
- `origin` 指向你自己的 fork
- `pinagmulan` 指向你自己的 tinidor
- `upstream` 指向原仓库
如果没有 `upstream`,先添加:
```powershell
如果没有 `upstream`,先添加:```powershell
git remote add upstream https://github.com/diegosouzapw/OmniRoute.git
```
````
同步上游前,先抓取最新提交和标签:
```powershell
同步上游前,先抓取最新提交和标签:```powershell
git fetch upstream --tags
```
查看当前版本和上游标签:
````
```powershell
查看当前版本和上游标签:```powershell
git describe --tags --always
git show --no-patch --oneline v3.4.7
```
````
如果你想合并上游最新 `main`,并强制保留 fork 当前的 `fly.toml`,可按下面流程执行:
```powershell
如果你想合并上游最新 `main`,并强制保留 fork 当前的 `fly.toml`,可按下面流程执行:```powershell
git merge upstream/main
git checkout HEAD~1 -- fly.toml
git add -- fly.toml
git commit -m "chore(deploy): keep fork fly.toml"
git push origin main
```
````
说明:
- `git merge upstream/main` 用于同步原仓库最新代码
- `git checkout HEAD~1 -- fly.toml` 用于恢复合并前你 fork 自己的 `fly.toml`
- 如果上游没有改 `fly.toml`,这一步不会带来额外差异
- 如果上游改了 `fly.toml`,这一步能确保 Fly 应用名、挂载卷、区域等 fork 自定义部署配置不被覆盖
- 如果上游改了 `fly.toml`,这一步能确保 Fly 应用名、挂载卷、区域等 tinidor自定义部署配置不被覆盖
如果你明确只想对齐某个发布标签,例如 `v3.4.7`,也可以先确认标签是否已经包含在 `upstream/main`
```powershell
如果你明确只想对齐某个发布标签,例如 `v3.4.7`,也可以先确认标签是否匲現是否匲現是否匲現是否匲```powershell
git merge-base --is-ancestor v3.4.7 upstream/main
```
````
返回成功表示 `upstream/main` 已经包含该版本,直接合并 `upstream/main` 即可。
### 9.2 同步上游后的标准发布顺序
返回成功表示 `upstream/main` 已经包含该版本,直接合并 `upstream/main` 即可。### 9.2 同步上游后的标准发布顺序
同步原仓库完成后,推荐按下面顺序发布:
1. `git fetch upstream --tags`
2. `git merge upstream/main`
3. 恢复 fork`fly.toml`
3. 恢复 tinidor`fly.toml`
4. `git push origin main`
5. `flyctl deploy`
6. `flyctl status -a omniroute`
7. `flyctl logs --no-tail -a omniroute`
这就是当前项目升级到 `v3.4.7` 时使用的实际流程。
---
这就是当前项目升级到 `v3.4.7` 时使用的实际流程。---
## 10. 发布后检查
@ -355,27 +300,22 @@ try {
}
```
返回 `200` 说明站点已正常响应。
---
返回 `200` 说明站点已正常响应。---
## 11. 成功标志
部署成功后,日志里应看到类似内容:
```text
部署成功后,日志里应看到类似内容:```text
[bootstrap] Secrets persisted to: /data/server.env
[DB] SQLite database ready: /data/storage.sqlite
```
````
这两个点很关键:
- `/data/server.env` 说明运行时密钥落到了持久卷
- `/data/storage.sqlite` 说明数据库写入持久卷
如果你看到的是 `/app/data/...`,说明 `DATA_DIR` 没配对,需要立即修正。
---
如果你看到的是 `/app/data/...`,说明 `DATA_DIR` 没配对,需要立即修正。---
## 12. 常见问题
@ -384,35 +324,25 @@ try {
通常有两种原因:
- 你还没执行 `flyctl secrets set`
- 你打开的是另一个应用,例如 `oroute`,不是 `omniroute`
- 你打开的是另一个应用,例如 `oroute`,不是 `omniroute`### 12.2 `flyctl deploy``app not found`
### 12.2 `flyctl deploy``app not found`
先创建应用:
```powershell
先创建应用:```powershell
flyctl apps create omniroute
```
````
### 12.3 `fly.toml` 解析失败
重点检查:
- 注释里是否有乱码字符
- TOML 引号和缩进是否正确
### 12.4 数据没有持久化
- TOML 引号和缩进是否正确### 12.4 数据没有持久化
检查以下两点:
- `fly.toml` 中是否存在 `destination = '/data'`
- `DATA_DIR` 是否设置为 `/data`
- `DATA_DIR` 是否设置为 `/data`### 12.5 不设置 `INITIAL_PASSWORD` 是否能跑
### 12.5 不设置 `INITIAL_PASSWORD` 是否能跑
可以运行,但会回退到默认 `CHANGEME`。生产环境建议尽快修改后台密码。
---
可以运行,但会回退到默认 `CHANGEME`。生产环境建议尽快修改后台密码。---
## 13. 新项目复用建议
@ -424,32 +354,27 @@ flyctl apps create omniroute
4. 重新生成 `API_KEY_SECRET``JWT_SECRET``MACHINE_ID_SALT``STORAGE_ENCRYPTION_KEY`
5. 首次部署后检查日志是否写入 `/data`
不要直接复用旧项目的密钥。
---
不要直接复用旧项目的密钥。---
## 14. 当前项目的最小发布清单
当前项目后续最常用的命令如下:
```powershell
当前项目后续最常用的命令如下:```powershell
flyctl auth whoami
flyctl status -a omniroute
flyctl secrets list -a omniroute
flyctl deploy
flyctl logs --no-tail -a omniroute
```
如果只是正常发版,核心就是:
````
```powershell
如果只是正常发版,核心就是:```powershell
flyctl deploy
```
````
如果是新环境首次部署,核心就是:
1. `flyctl auth login`
2. `flyctl apps create omniroute`
3. `flyctl secrets set ... -a omniroute`
2. `Flyctl apps create omniroute`
3. `nakatakdang mga lihim ng flyctl ... -a omniroute`
4. `flyctl deploy`
5. `flyctl logs --no-tail -a omniroute`

View file

@ -4,89 +4,73 @@
---
OmniRoute supports **30 languages** with full dashboard UI translation, translated documentation, and RTL support for Arabic and Hebrew.
Sinusuportahan ng OmniRoute ang**30 wika**na may ganap na pagsasalin ng UI ng dashboard, isinaling dokumentasyon, at suporta sa RTL para sa Arabic at Hebrew.## Quick Reference
## Quick Reference
| Task | Command |
| ---------------------- | --------------------------------------------------------------------------------------- |
| Generate translations | `node scripts/i18n/generate-multilang.mjs messages` |
| Translate docs (LLM) | `python3 scripts/i18n_autotranslate.py --api-url <url> --api-key <key> --model <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` |
## Arkitektura
| Gawain | Utos |
| ---------------------------- | --------------------------------------------------------------------------------------- | -------------- |
| Bumuo ng mga pagsasalin | `node scripts/i18n/generate-multilang.mjs messages` |
| Isalin ang mga doc (LLM) | `python3 scripts/i18n_autotranslate.py --api-url <url> --api-key <key> --model <model>` |
| Patunayan ang isang lokal na | `python3 scripts/validate_translation.py quick -l cs` |
| Suriin ang mga code key | `python3 scripts/check_translations.py` |
| Bumuo ng ulat ng QA | `mga node script/i18n/generate-qa-checklist.mjs` |
| Visual QA (Playwright) | `node scripts/i18n/run-visual-qa.mjs` | ## Arkitektura |
### Source of Truth
- **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
-**Mga string ng UI**: `src/i18n/messages/en.json` (pinagmulan sa English, ~2800 key) -**Mga lokal na file**: `src/i18n/messages/{locale}.json` (30 pagsasalin) -**Framework**: `next-intl` na may cookie-based na lokal na resolution -**Config**: `src/i18n/config.ts` — tumutukoy sa lahat ng 30 lokal, mga pangalan ng wika, mga flag### Runtime Flow
### Runtime Flow
1. Pinipili ng user ang → set ng cookie ng `NEXT_LOCALE` ng wika
2. Niresolba ng `src/i18n/request.ts` ang locale: cookie → header ng `Accept-Language` → fallback `en`
3. Naglo-load ang dynamic na pag-import ng `messages/{locale}.json`
4. Gumagamit ang mga bahagi ng `useTranslations("namespace")` at `t("key")`### Supported Locales
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")`
### Supported Locales
| Code | Language | RTL | Google Translate Code |
| ------- | -------------------- | --- | --------------------- |
| `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` |
## Adding a New Language
| Code | Wika | RTL | Google Translate Code |
| ------- | -------------------- | ----- | --------------------- | ------------------------ |
| `ar` | العربية | Oo | `ar` |
| `bg` | Български | Hindi | `bg` |
| `cs` | Čeština | Hindi | `cs` |
| `da` | Dansk | Hindi | `da` |
| `de` | Deutsch | Hindi | `de` |
| `ay` | Español | Hindi | `ay` |
| `fi` | Suomi | Hindi | `fi` |
| `fr` | Français | Hindi | `fr` |
| `siya` | עברית | Oo | `iw` |
| `hi` | हिन्दी | Hindi | `hi` |
| `hu` | Magyar | Hindi | `hu` |
| `id` | Bahasa Indonesia | Hindi | `id` |
| `ito` | Italiano | Hindi | `ito` |
| `ja` | 日本語 | Hindi | `ja` |
| `ko` | 한국어 | Hindi | `ko` |
| `ms` | Bahasa Melayu | Hindi | `ms` |
| `nl` | Nederlands | Hindi | `nl` |
| `hindi` | Norsk | Hindi | `hindi` |
| `phi` | Filipino | Hindi | `tl` |
| `pl` | Polski | Hindi | `pl` |
| `pt` | Português (Portugal) | Hindi | `pt` |
| `pt-BR` | Português (Brasil) | Hindi | `pt` |
| `ro` | Română | Hindi | `ro` |
| `ru` | Русский | Hindi | `ru` |
| `sk` | Slovenčina | Hindi | `sk` |
| `sv` | Svenska | Hindi | `sv` |
| `ika` | ไทย | Hindi | `ika` |
| `tr` | Türkçe | Hindi | `tr` |
| `uk-UA` | Українська | Hindi | `uk` |
| `vi` | Tiếng Việt | Hindi | `vi` |
| `zh-CN` | 中文 (简体) | Hindi | `zh-CN` | ## Adding a New Language |
### 1. Register the Locale
Edit `src/i18n/config.ts`:
```ts
I-edit ang `src/i18n/config.ts`:```ts
// Add to LOCALES array
"xx",
// Add to LANGUAGES array
{ code: "xx", label: "XX", name: "Language Name", flag: "🏳️" },
```
````
### 2. Add to Generator
Edit `scripts/i18n/generate-multilang.mjs` — add entry to `LOCALE_SPECS`:
```js
I-edit ang `scripts/i18n/generate-multilang.mjs` — magdagdag ng entry sa `LOCALE_SPECS`:```js
{
code: "xx",
googleTl: "xx",
@ -96,7 +80,7 @@ Edit `scripts/i18n/generate-multilang.mjs` — add entry to `LOCALE_SPECS`:
readmeName: "Language Name",
docsName: "Language Name",
},
```
````
### 3. Generate Initial Translation
@ -104,17 +88,13 @@ Edit `scripts/i18n/generate-multilang.mjs` — add entry to `LOCALE_SPECS`:
node scripts/i18n/generate-multilang.mjs messages
```
This creates `src/i18n/messages/xx.json` auto-translated from `en.json` via Google Translate.
Lumilikha ito ng `src/i18n/messages/xx.json` na awtomatikong isinalin mula sa `en.json` sa pamamagitan ng Google Translate.### 4. Review & Fix Auto-Translations
### 4. Review & Fix Auto-Translations
Ang mga awtomatikong pagsasalin ay isang panimulang punto. Manu-manong suriin para sa:
Auto-translations are a starting point. Review manually for:
- Technical accuracy
- Context-appropriate terminology
- Proper handling of placeholders (`{count}`, `{value}`, etc.)
### 5. Validate
- Teknikal na katumpakan
- terminolohiya na angkop sa konteksto
- Wastong pangangasiwa ng mga placeholder (`{count}`, `{value}`, atbp.)### 5. Validate
```bash
python3 scripts/validate_translation.py quick -l xx
@ -131,102 +111,100 @@ node scripts/i18n/generate-multilang.mjs docs
### generate-multilang.mjs (Google Translate)
**Primary auto-translation engine** — uses Google Translate free API to generate translations for UI strings, READMEs, and documentation.
```bash
**Pangunahing auto-translation engine**— gumagamit ng Google Translate na libreng API upang bumuo ng mga pagsasalin para sa mga string ng UI, README, at dokumentasyon.```bash
node scripts/i18n/generate-multilang.mjs [messages|readme|docs|all]
```
| Mode | What it does |
| ---------- | ----------------------------------------------------------------------------- |
| `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 |
````
**Features:**
| Mode | Ano ang ginagawa nito |
| ---------- | ----------------------------------------------------------------------------------- |
| `mensahe` | Isinasalin ang mga nawawalang key sa `src/i18n/messages/{locale}.json` mula sa `en.json` |
| `readme` | Isinasalin ang `README.md` sa lahat ng lokal bilang `README.{code}.md` sa ugat ng proyekto |
| `docs` | Isinasalin ang `DOC_SOURCE_FILES` sa `docs/i18n/{locale}/{docName}` |
| `lahat` | Pinapatakbo ang lahat ng tatlong mode |
- **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
**Mga Tampok:**
**Important behaviors:**
-**Proteksyon sa text**: Masks code blocks (` ``` `), inline code (`` ```), markdown links/images (`[text](url)`), HTML tags, tables, at ICU placeholders (`{count}`, `{value}`, `{total}`, atbp.) bago isalin ang mga ito, pagkatapos ay i-restore ang mga ito.
-**Chunked batching**: Sumasali sa maraming string gamit ang `__OMNIROUTE_I18N_SEPARATOR__` delimiter para mabawasan ang mga API call (max 1800 char bawat kahilingan)
-**In-memory cache**: Iniiwasan ang mga paulit-ulit na tawag sa API para sa mga paulit-ulit na string sa loob ng isang session
-**Subukan muli ang lohika**: Exponential backoff (hanggang 5 pagsubok na may 300ms × pagkaantala sa pagsubok) para sa 429/5xx na mga error
-**Timeout**: 20 segundo bawat kahilingan
-**Laktawan ang umiiral na**: Kung mayroon nang target na file, HINDI ito ma-overwrite
- `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
**Mahahalagang gawi:**
### i18n_autotranslate.py (LLM-based)
- Ang `docs/i18n/README.md` ay**regenerated**bawat run — isa itong awtomatikong nabuong index ng lahat ng docs
- Ang Root `README.{code}.md` file ay ginawa lamang kung wala ang mga ito (lumalaktaw sa mga lokal sa `EXISTING_README_CODES`)
- Ang mga language bar (`🌐**Mga Wika:**...`) ay awtomatikong ipinapasok/na-update sa lahat ng isinaling doc### i18n_autotranslate.py (LLM-based)
**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.
```bash
**Sekundaryong tagasalin**— gumagamit ng anumang OpenAI-compatible na LLM API (kabilang ang OmniRoute mismo) para isalin ang mga kasalukuyang `docs/i18n/` markdown file. Pinakamahusay para sa pagpapakintab o muling pagsasalin ng mga dokumento na may mas mahusay na kalidad kaysa sa Google Translate.```bash
python3 scripts/i18n_autotranslate.py \
--api-url http://localhost:20128/v1 \
--api-key sk-your-key \
--model gpt-4o
```
````
**Features:**
**Mga Tampok:**
- 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
## Validation & QA
- Nag-scan ng mga `docs/i18n/` markdown file para sa mga English na talata
- Nilalaktawan ang mga bloke ng code, mga talahanayan, at na-translate na nilalaman
- Nagpapadala ng mga talata sa LLM na may prompt ng sistema ng teknikal na pagsasalin
- Sinusuportahan ang lahat ng 30 mga wika## Validation & QA
### validate_translation.py
**Translation validator** — compares any locale JSON against `en.json` and reports issues.
**Translation validator**— inihahambing ang anumang lokal na JSON laban sa `en.json` at nag-uulat ng mga isyu.```bash
```bash
# Quick check (counts only)
python3 scripts/validate_translation.py quick -l cs
# Output:
# Missing: 0
# Untranslated: 0
# Ignored (UNTRANSLATABLE_KEYS): 236
# Detailed diff by category
python3 scripts/validate_translation.py diff common -l cs
python3 scripts/validate_translation.py diff settings -l cs
# Export to CSV
python3 scripts/validate_translation.py csv -l cs > report.csv
# Export to Markdown
python3 scripts/validate_translation.py md -l cs > report.md
# Full report (default)
python3 scripts/validate_translation.py -l cs
```
**Detects:**
````
- **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
**Nakikita:**
**Exit codes:**
| Code | Meaning |
-**Mga nawawalang key**— mga key sa `en.json` ngunit hindi sa locale file
-**Mga karagdagang key**— mga key sa locale file ngunit hindi sa `en.json`
-**Untranslated keys**— mga key kung saan ang locale value ay katumbas ng English source (hindi kasama ang allowlist)
-**Placeholder mismatches**— ICU placeholder na hindi tumutugma sa pagitan ng pinagmulan at pagsasalin
**Mga exit code:**
| Code | Ibig sabihin |
|------|---------|
| 0 | OK |
| 1 | Generic error |
| 2 | Missing strings (hard error) |
| 3 | Untranslated warning (soft) |
| 1 | Pangkalahatang error |
| 2 | Nawawalang mga string (mahirap na error) |
| 3 | Hindi naisalin na babala (malambot) |
**Environment:** Set `TRANSLATION_LANG=cs` or use `-l cs` flag.
**Kapaligiran:**Itakda ang `TRANSLATION_LANG=cs` o gamitin ang flag ng `-l cs`.### check_translations.py
### 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`.
```bash
**Code-to-JSON key checker**— ini-scan ang `src/**/*.tsx` at `src/**/*.ts` para sa mga `useTranslations()` na mga tawag at bini-verify na lahat ng reference na key ay umiiral sa `en.json`.```bash
# Basic check
python3 scripts/check_translations.py
@ -235,31 +213,26 @@ python3 scripts/check_translations.py --verbose
# Auto-fix (adds missing keys to en.json)
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.
```bash
**Static analysis QA**— ini-scan ang Next.js page file para sa i18n risk metrics at bumubuo ng Markdown report.```bash
node scripts/i18n/generate-qa-checklist.mjs
```
**Checks:**
````
- 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`)
**Mga tseke:**
**Output:** `docs/reports/i18n-qa-checklist-{date}.md`
- Fixed-width class na paggamit (overflow risk)
- Direksyon sa kaliwa/kanang mga klase (panganib sa RTL)
- Clipping-prone pattern
- Parity ng lokal (nawawala/dagdag na mga key kumpara sa `en.json`)
- Mga bar ng tagapili ng wika ng README sa mga priyoridad na lokal (`es`, `fr`, `de`, `ja`, `ar`)
### run-visual-qa.mjs
**Output:**`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.
```bash
**Visual QA sa pamamagitan ng Playwright**— kumukuha ng mga screenshot ng lahat ng ruta ng dashboard sa maraming lokal at viewport, pagkatapos ay sinusuri ang kalusugan ng page.```bash
# Default: es, fr, de, ja, ar on localhost:20128
node scripts/i18n/run-visual-qa.mjs
@ -268,134 +241,126 @@ QA_BASE_URL=http://staging.example.com QA_LOCALES=de,fr node scripts/i18n/run-vi
# Custom routes
QA_ROUTES=/dashboard/settings,/dashboard/providers node scripts/i18n/run-visual-qa.mjs
```
````
**Detects:**
**Nakikita:**
- Text overflow
- Overflow ng text
- Element clipping
- RTL layout mismatches
- Hindi pagkakatugma ng layout ng RTL
**Output:** `docs/reports/i18n-visual-qa-{date}.md` + JSON report
## Managing Untranslatable Keys
**Output:**`docs/reports/i18n-visual-qa-{date}.md` + ulat ng JSON## Managing Untranslatable Keys
### untranslatable-keys.json
**File:** `scripts/i18n/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.
```json
Payagan ang listahan ng mga susi na dapat manatiling magkapareho sa pinagmulang Ingles. Ginamit ng `validate_translation.py` upang maiwasan ang mga false-positive na "untranslated" na babala.```json
{
"description": "Keys that should remain untranslated...",
"keys": [
"common.model",
"common.oauth",
"health.cpu",
...
]
"description": "Keys that should remain untranslated...",
"keys": [
"common.model",
"common.oauth",
"health.cpu",
...
]
}
```
**What belongs here:**
````
- 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`
**Ano ang pag-aari dito:**
**To add a key:** Edit the `keys` array in `scripts/i18n/untranslatable-keys.json` and re-run validation.
- Mga pangalan ng brand/produkto: `landing.brandName`, `common.social-github`
- Mga teknikal na termino/acronym: `health.cpu`, `mcpDashboard.pid`, `settings.ai`
- Mga string ng ICU/format: `apiManager.modelsCount`, `health.millisecondsShort`
- Mga value ng placeholder: `providers.openaiBaseUrlPlaceholder`, `cliTools.baseUrlPlaceholder`
- Mga pangalan ng protocol: `common.http`, `common.oauth`, `providers.oauth2Label`
- Mga seksyon ng nabigasyon: `sidebar.primarySection`, `sidebar.cliSection`
## CI Integration
**Para magdagdag ng key:**I-edit ang array ng `keys` sa `scripts/i18n/untranslatable-keys.json` at muling patakbuhin ang validation.## CI Integration
### GitHub Actions (`.github/workflows/ci.yml`)
The CI pipeline validates all locales on every push and PR:
Ang CI pipeline ay nagpapatunay sa lahat ng mga lokal sa bawat push at PR:
1. **`i18n-matrix` job** — dynamically discovers all locale files (excluding `en.json`)
2. **`i18n` job** — runs `validate_translation.py quick -l '<lang>'` for each locale in parallel
3. **`ci-summary` job** — aggregates results into a dashboard summary
```yaml
1.**`i18n-matrix` job**— dynamic na natutuklasan ang lahat ng lokal na file (hindi kasama ang `en.json`)
2.**`i18n` job**— nagpapatakbo ng `validate_translation.py quick -l '<lang>'` para sa bawat lokal na kahanay
3.**`ci-summary` job**— pinagsasama-sama ang mga resulta sa isang buod ng dashboard```yaml
# i18n-matrix: discovers languages
LANGS=$(ls src/i18n/messages/*.json | xargs -n1 basename | sed 's/.json$//' | grep -v '^en$')
# i18n: validates each language
python3 scripts/validate_translation.py quick -l '${{ matrix.lang }}'
```
````
**Dashboard output:**
**Dashboard output:**```
```
## 🌍 Translations
| Metric | Value |
|--------|------|
| Languages checked | 30 |
| Total untranslated | 0 |
| Metric | Value |
| ------------------ | ----- |
| Languages checked | 30 |
| Total untranslated | 0 |
✅ All translations complete
```
## File Structure
```
src/i18n/
├── config.ts # Locale definitions (30 locales, RTL config)
├── request.ts # Runtime locale resolution
├── config.ts # Locale definitions (30 locales, RTL config)
├── request.ts # Runtime locale resolution
└── messages/
├── en.json # Source of truth (~2800 keys)
├── cs.json # Czech translation
├── de.json # German translation
└── ... # 30 locale files total
├── en.json # Source of truth (~2800 keys)
├── cs.json # Czech translation
├── de.json # German translation
└── ... # 30 locale files total
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 # 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
.github/workflows/
└── ci.yml # i18n validation in CI matrix
└── ci.yml # i18n validation in CI matrix
docs/
├── I18N.md # This file — i18n toolchain documentation
├── I18N.md # This file — i18n toolchain documentation
├── i18n/
├── README.md # Auto-generated language index
├── cs/ # Czech docs
└── docs/
│ ├── I18N.md # Czech translation of this file
└── ...
├── de/ # German docs
└── ... # 30 locale directories
│ ├── README.md # Auto-generated language index
│ ├── cs/ # Czech docs
└── docs/
│ ├── I18N.md # Czech translation of this file
└── ...
│ ├── de/ # German docs
│ └── ... # 30 locale directories
└── reports/
├── i18n-qa-checklist-*.md # Static analysis reports
└── i18n-visual-qa-*.md # Visual QA reports
```
├── i18n-qa-checklist-_.md # Static analysis reports
└── i18n-visual-qa-_.md # Visual QA reports
````
## Best Practices
### When Editing Translations
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 <lang>`
5. **Update `untranslatable-keys.json`** if a key should remain in English
1.**Palaging i-edit muna ang `en.json`**— ito ang pinagmulan ng katotohanan
2.**Patakbuhin ang `generate-multilang.mjs messages`**upang magpalaganap ng mga bagong key sa lahat ng lokal
3.**Suriin ang mga awtomatikong pagsasalin**— Ang Google Translate ay isang panimulang punto, hindi pangwakas
4.**Patunayan bago gumawa**`python3 scripts/validate_translation.py quick -l <lang>`
5.**I-update ang `untranslatable-keys.json`**kung ang isang key ay dapat manatili sa English### Placeholder Safety
### Placeholder Safety
- 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
### Adding New Translation Keys in Code
- Ang mga placeholder ng ICU (`{count}`, `{value}`, `{total}`, `{seconds}`) ay dapat na mapangalagaan nang eksakto
- Ang mga plural na format (`{count, plural, one {# model} other {# models}}`) ay dapat mapanatili ang istraktura
- Awtomatikong nakikita ng validator ang mga hindi pagkakatugma ng placeholder### Adding New Translation Keys in Code
```tsx
// Use namespaced keys
@ -404,38 +369,29 @@ t("cacheSettings"); // maps to settings.cacheSettings in JSON
// Run check_translations.py to verify keys exist
python3 scripts/check_translations.py --verbose
```
````
### RTL Considerations
- 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`
## Known Issues & History
- Ang Arabic (`ar`) at Hebrew (`siya`) ay mga lokal na RTL
- Iwasan ang naka-hardcode na `left`/`right` CSS — gumamit ng `start`/`end` logical properties
- Nahuhuli ng Visual QA ang mga hindi pagkakatugma ng layout ng RTL sa pamamagitan ng `run-visual-qa.mjs`## Known Issues & History
### `in.json``hi.json` Fix
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.
Ang generator ay orihinal na gumamit ng `code: "in"` (hindi na ginagamit ang Google Translate code) para sa Hindi sa halip na ang tamang ISO 639-1 `hi`. Gumawa ito ng naulilang `in.json` na duplicate ng `hi.json`. Naayos sa pamamagitan ng pagpapalit ng `code: "in"` sa `code: "hi"` sa `generate-multilang.mjs` at pag-alis sa naulilang file.### `docs/i18n/README.md` Is Auto-Generated
### `docs/i18n/README.md` Is Auto-Generated
Ang file na `docs/i18n/README.md` ay ganap na na-regenerate ng `generate-multilang.mjs docs`. Mawawala ang anumang manu-manong pag-edit. Gamitin ang `docs/I18N.md` (ang file na ito) para sa sulat-kamay na dokumentasyon na dapat magpatuloy.### External Untranslatable Keys List
The `docs/i18n/README.md` file is completely regenerated by `generate-multilang.mjs docs`. Any manual edits will be lost. Use `docs/I18N.md` (this file) for hand-written documentation that should persist.
Ang allowlist na `untranslatable-keys.json` ay inilipat mula sa isang inline na Python na itinakda sa `validate_translation.py` patungo sa isang external na JSON file para sa mas madaling pagpapanatili. Nilo-load ito ng validator sa runtime.### `generate-multilang.mjs` Hindi Code Fix
### External Untranslatable Keys List
Ang generator ay orihinal na gumamit ng `code: "in"` (hindi na ginagamit ang Google Translate code) para sa Hindi sa halip na ang tamang ISO 639-1 `hi`. Ito ay ipinakilala sa upstream commit `952b0b22c` ni `diegosouzapw`. Inayos sa pamamagitan ng pagpapalit ng `code: "in"` sa `code: "hi"` sa array ng `LOCALE_SPECS` at pag-alis sa naulilang `in.json` na file.### `validate_translation.py` Ignored Count Output
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.
### `generate-multilang.mjs` Hindi Code Fix
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.
### `validate_translation.py` Ignored Count Output
The `quick` check now displays the count of ignored keys from `untranslatable-keys.json`:
```
Ipinapakita na ngayon ng `quick` check ang bilang ng mga hindi pinansin na key mula sa `untranslatable-keys.json`:```
Missing: 0
Untranslated: 0
Ignored (UNTRANSLATABLE_KEYS): 236
```
```

View file

@ -4,84 +4,69 @@
---
> Model Context Protocol server with 16 intelligent tools
> Model Context Protocol server na may 16 na matalinong tool## I-install
## I-install
OmniRoute MCP is built-in. Start it with:
```bash
Ang OmniRoute MCP ay built-in. Simulan ito sa:```bash
omniroute --mcp
```
Or via the open-sse transport:
````
```bash
O sa pamamagitan ng open-sse transport:```bash
# HTTP streamable transport (port 20130)
omniroute --dev # MCP auto-starts on /mcp endpoint
```
````
## IDE Configuration
See [IDE Configs](integrations/ide-configs.md) for Antigravity, Cursor, Copilot, and Claude Desktop setup.
---
Tingnan ang [IDE Configs](integrations/ide-configs.md) para sa Antigravity, Cursor, Copilot, at Claude Desktop setup.---
## Essential Tools (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 |
| Tool | Paglalarawan |
| :------------------------------ | :----------------------------------------------------------- | --------------------- |
| `omniroute_get_health` | Kalusugan ng gateway, mga circuit breaker, uptime |
| `omniroute_list_combos` | Lahat ng naka-configure na combo na may mga modelo |
| `omniroute_get_combo_metrics` | Mga sukatan ng pagganap para sa isang partikular na combo |
| `omniroute_switch_combo` | Lumipat ng aktibong combo ayon sa ID/pangalan |
| `omniroute_check_quota` | Katayuan ng quota bawat provider o lahat |
| `omniroute_route_request` | Magpadala ng pagkumpleto ng chat sa pamamagitan ng OmniRoute |
| `omniroute_cost_report` | Analytics ng gastos para sa isang yugto ng panahon |
| `omniroute_list_models_catalog` | Buong katalogo ng modelo na may mga kakayahan | ## Advanced Tools (8) |
## Advanced Tools (8)
| Tool | Paglalarawan |
| :--------------------------------- | :--------------------------------------------------------------------------------------------------- | ----------------- |
| `omniroute_simulate_route` | Dry-run routing simulation na may fallback tree |
| `omniroute_set_budget_guard` | Badyet ng session na may mga pagkilos na nagpapababa/nag-block/alerto |
| `omniroute_set_resilience_profile` | Ilapat ang konserbatibo/balanse/agresibong preset |
| `omniroute_test_combo` | Live-test lahat ng mga modelo sa isang combo sa pamamagitan ng isang tunay na upstream na kahilingan |
| `omniroute_get_provider_metrics` | Mga detalyadong sukatan para sa isang provider |
| `omniroute_best_combo_for_task` | Rekomendasyon sa fitness sa gawain na may mga alternatibo |
| `omniroute_explain_route` | Ipaliwanag ang isang nakaraang desisyon sa pagruruta |
| `omniroute_get_session_snapshot` | Katayuan ng buong session: mga gastos, mga token, mga error | ## Authentication |
| 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 |
Ang mga tool ng MCP ay napatotohanan sa pamamagitan ng mga saklaw ng key ng API. Ang bawat tool ay nangangailangan ng mga partikular na saklaw:
## Authentication
| Saklaw | Mga tool |
| :-------------- | :----------------------------------------------- | ---------------- |
| `read:health` | get_health, get_provider_metrics |
| `read:combos` | list_combos, get_combo_metrics |
| `write:combos` | switch_combo |
| `read:quota` | check_quota |
| `magsulat:ruta` | route_request, simulate_route, test_combo |
| `read:usage` | cost_report, get_session_snapshot, explain_route |
| `write:config` | set_budget_guard, set_resilience_profile |
| `read:models` | list_models_catalog, best_combo_for_task | ## Audit Logging |
MCP tools are authenticated via API key scopes. Each tool requires specific scopes:
Ang bawat tool na tawag ay naka-log sa `mcp_tool_audit` gamit ang:
| Scope | Tools |
| :------------- | :----------------------------------------------- |
| `read:health` | get_health, get_provider_metrics |
| `read:combos` | list_combos, get_combo_metrics |
| `write:combos` | switch_combo |
| `read:quota` | check_quota |
| `write:route` | route_request, simulate_route, test_combo |
| `read:usage` | cost_report, get_session_snapshot, explain_route |
| `write:config` | set_budget_guard, set_resilience_profile |
| `read:models` | list_models_catalog, best_combo_for_task |
- Pangalan ng tool, mga argumento, resulta
- Tagal (ms), tagumpay/kabiguan
- API key hash, timestamp## Files
## Audit Logging
Every tool call is logged to `mcp_tool_audit` with:
- Tool name, arguments, result
- Duration (ms), success/failure
- API key hash, timestamp
## Files
| 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 |
| File | Layunin |
| :------------------------------------------- | :--------------------------------------------------- |
| `open-sse/mcp-server/server.ts` | Paglikha ng MCP server + 16 na pagrerehistro ng tool |
| `open-sse/mcp-server/transport.ts` | Stdio + HTTP transport |
| `open-sse/mcp-server/auth.ts` | API key + pagpapatunay ng saklaw |
| `open-sse/mcp-server/audit.ts` | Tool call audit logging |
| `open-sse/mcp-server/tools/advancedTools.ts` | 8 advanced na tool handler |

View file

@ -4,34 +4,26 @@
---
Use this checklist before tagging or publishing a new OmniRoute release.
Gamitin ang checklist na ito bago mag-tag o mag-publish ng bagong release ng OmniRoute.## Version and Changelog
## Version and 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. Bump `package.json` na bersyon (`x.y.z`) sa release branch.
2. Ilipat ang mga tala sa paglabas mula sa `## [Hindi Inilabas]` sa `CHANGELOG.md` sa isang may petsang seksyon:
- `## [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. Panatilihin ang `## [Hindi Inilabas]` bilang unang seksyon ng changelog para sa paparating na gawain.
4. Tiyaking ang pinakabagong semver na seksyon sa `CHANGELOG.md` ay katumbas ng `package.json` na bersyon.## API Docs
## API Docs
5. I-update ang `docs/openapi.yaml`:
- Ang `info.version` ay dapat katumbas ng `package.json` na bersyon.
6. I-validate ang mga halimbawa ng endpoint kung nagbago ang mga kontrata ng API.## Runtime Docs
1. Update `docs/openapi.yaml`:
- `info.version` must equal `package.json` version.
2. Validate endpoint examples if API contracts changed.
7. Suriin ang `docs/ARCHITECTURE.md` para sa storage/runtime drift.
8. Suriin ang `docs/TROUBLESHOOTING.md` para sa env var at operational drift.
9. I-update ang mga naka-localize na doc kung malaki ang pagbabago sa source docs.## Automated Check
## Runtime Docs
1. Review `docs/ARCHITECTURE.md` for storage/runtime drift.
2. Review `docs/TROUBLESHOOTING.md` for env var and operational drift.
3. Update localized docs if source docs changed significantly.
## Automated Check
Run the sync guard locally before opening PR:
```bash
Patakbuhin ang sync guard nang lokal bago buksan ang PR:```bash
npm run check:docs-sync
```
CI also runs this check in `.github/workflows/ci.yml` (lint job).
Pinapatakbo din ng CI ang pagsusuring ito sa `.github/workflows/ci.yml` (lint job).
```

View file

@ -4,86 +4,68 @@
---
Common problems and solutions for OmniRoute.
---
Mga karaniwang problema at solusyon para sa OmniRoute.---
## Quick Fixes
| 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 request logs under `logs/` | Set `ENABLE_REQUEST_LOGS=true` |
| 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) |
---
| Problema | Solusyon |
| ------------------------------------------------ | ------------------------------------------------------------------------------ | --- |
| Unang login ay hindi gumagana | Itakda ang `INITIAL_PASSWORD` sa `.env` (walang hardcoded default) |
| Nagbubukas ang dashboard sa maling port | Itakda ang `PORT=20128` at `NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
| Walang mga log ng kahilingan sa ilalim ng `log/` | Itakda ang `ENABLE_REQUEST_LOGS=true` |
| EACCES: tinanggihan ang pahintulot | Itakda ang `DATA_DIR=/path/to/writable/dir` para i-override ang `~/.omniroute` |
| Hindi nagse-save ang diskarte sa pagruruta | Update sa v1.4.11+ (Zod schema fix para sa pagtitiyaga ng mga setting) | --- |
## Provider Issues
### "Language model did not provide messages"
**Cause:** Provider quota exhausted.
**Sanhi:**Naubos na ang quota ng provider.
**Fix:**
**Ayusin:**
1. Check dashboard quota tracker
2. Use a combo with fallback tiers
3. Switch to cheaper/free tier
1. Suriin ang dashboard quota tracker
2. Gumamit ng combo na may fallback tier
3. Lumipat sa mas mura/libreng tier### Rate Limiting
### Rate Limiting
**Dahil:**Naubos na ang quota ng subscription.
**Cause:** Subscription quota exhausted.
**Ayusin:**
**Fix:**
- Magdagdag ng fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
- Gamitin ang GLM/MiniMax bilang murang backup### OAuth Token Expired
- Add fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
- Use GLM/MiniMax as cheap backup
Ang OmniRoute ay awtomatikong nagre-refresh ng mga token. Kung magpapatuloy ang mga isyu:
### OAuth Token Expired
OmniRoute auto-refreshes tokens. If issues persist:
1. Dashboard → Provider → Reconnect
2. Delete and re-add the provider connection
---
1. Dashboard → Provider → Kumonekta muli
2. Tanggalin at muling idagdag ang koneksyon ng provider---
## Cloud Issues
### Cloud Sync Errors
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. I-verify ang mga `BASE_URL` na puntos sa iyong running instance (hal., `http://localhost:20128`)
2. I-verify ang mga `CLOUD_URL` na puntos sa iyong cloud endpoint (hal., `https://omniroute.dev`)
3. Panatilihing nakahanay ang mga value ng `NEXT_PUBLIC_*` sa mga value sa gilid ng server### Cloud `stream=false` Returns 500
### Cloud `stream=false` Returns 500
**Symptom:**`Hindi inaasahang token 'd'...` sa cloud endpoint para sa mga non-streaming na tawag.
**Symptom:** `Unexpected token 'd'...` on cloud endpoint for non-streaming calls.
**Sanhi:**Ibinabalik ng Upstream ang SSE payload habang inaasahan ng kliyente ang JSON.
**Cause:** Upstream returns SSE payload while client expects JSON.
**Workaround:**Gamitin ang `stream=true` para sa mga direktang tawag sa cloud. Kasama sa lokal na runtime ang SSE→JSON fallback.### Cloud Says Connected but "Invalid API key"
**Workaround:** Use `stream=true` for cloud direct calls. Local runtime includes SSE→JSON fallback.
### Cloud Says Connected but "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. Gumawa ng bagong key mula sa lokal na dashboard (`/api/keys`)
2. Patakbuhin ang cloud sync: Paganahin ang Cloud → Sync Now
3. Ang mga luma/hindi naka-sync na key ay maaari pa ring ibalik ang `401` sa cloud---
## Docker Issues
### CLI Tool Shows Not Installed
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
### Quick Runtime Validation
1. Suriin ang mga field ng runtime: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
2. Para sa portable mode: gumamit ng target ng imahe na `runner-cli` (mga naka-bundle na CLI)
3. Para sa host mount mode: itakda ang `CLI_EXTRA_PATHS` at i-mount ang host bin directory bilang read-only
4. Kung `naka-install=true` at `runnable=false`: nakita ang binary ngunit nabigo ang healthcheck### Quick Runtime Validation
```bash
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
@ -97,20 +79,16 @@ curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,
### High Costs
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. Suriin ang mga istatistika ng paggamit sa Dashboard → Paggamit
2. Ilipat ang pangunahing modelo sa GLM/MiniMax
3. Gumamit ng libreng tier (Gemini CLI, Qoder) para sa mga hindi kritikal na gawain
4. Magtakda ng mga badyet sa gastos sa bawat API key: Dashboard → API Keys → Badyet---
## Debugging
### Enable Request Logs
Set `ENABLE_REQUEST_LOGS=true` in your `.env` file. Logs appear under `logs/` directory.
### Check Provider Health
Itakda ang `ENABLE_REQUEST_LOGS=true` sa iyong `.env` file. Lumilitaw ang mga log sa ilalim ng direktoryo ng `log/`.### Check Provider Health
```bash
# Health dashboard
@ -122,135 +100,101 @@ curl http://localhost:20128/api/monitoring/health
### Runtime Storage
- 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}/log.txt` and `${DATA_DIR}/call_logs/`
- Request logs: `<repo>/logs/...` (when `ENABLE_REQUEST_LOGS=true`)
---
- Pangunahing estado: `${DATA_DIR}/storage.sqlite` (mga provider, combo, alias, key, setting)
- Paggamit: Mga talahanayan ng SQLite sa `storage.sqlite` (`usage_history`, `call_logs`, `proxy_logs`) + opsyonal na `${DATA_DIR}/log.txt` at `${DATA_DIR}/call_logs/`
- Mga log ng kahilingan: `<repo>/logs/...` (kapag `ENABLE_REQUEST_LOGS=true`)---
## Circuit Breaker Issues
### Provider stuck in OPEN state
When a provider's circuit breaker is OPEN, requests are blocked until the cooldown expires.
Kapag ang circuit breaker ng provider ay BUKAS, ang mga kahilingan ay hinaharangan hanggang sa mag-expire ang cooldown.
**Fix:**
**Ayusin:**
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. Pumunta sa**Dashboard → Settings → Resilience**
2. Suriin ang circuit breaker card para sa apektadong provider
3. I-click ang**I-reset Lahat**upang i-clear ang lahat ng mga breaker, o hintaying mag-expire ang cooldown
4. I-verify na available talaga ang provider bago i-reset### Provider keeps tripping the circuit breaker
### Provider keeps tripping the circuit breaker
Kung ang isang provider ay paulit-ulit na pumasok sa OPEN state:
If a provider repeatedly enters OPEN state:
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. Suriin ang**Dashboard → Health → Provider Health**para sa pattern ng pagkabigo
2. Pumunta sa**Settings → Resilience → Provider Profiles**at taasan ang failure threshold
3. Suriin kung binago ng provider ang mga limitasyon ng API o nangangailangan ng muling pagpapatotoo
4. Suriin ang latency telemetry — ang mataas na latency ay maaaring magdulot ng mga pagkabigo batay sa timeout---
## Audio Transcription Issues
### "Unsupported model" error
- Ensure you're using the correct prefix: `deepgram/nova-3` or `assemblyai/best`
- Verify the provider is connected in **Dashboard → Providers**
- Tiyaking ginagamit mo ang tamang prefix: `deepgram/nova-3` o `assemblyai/best`
- I-verify na konektado ang provider sa**Dashboard → Mga Provider**### Transcription returns empty or fails
### Transcription returns empty or fails
- 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
---
- Suriin ang mga sinusuportahang format ng audio: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`
- I-verify na ang laki ng file ay nasa loob ng mga limitasyon ng provider (karaniwang <25MB)
- Suriin ang validity ng provider ng API key sa provider card---
## Translator Debugging
Use **Dashboard → Translator** to debug format translation issues:
Gamitin ang**Dashboard → Translator**upang i-debug ang mga isyu sa pagsasalin ng 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 | Kailan Gagamitin |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| **Laruan** | Paghambingin ang mga format ng input/output nang magkatabi — i-paste ang isang nabigong kahilingan upang makita kung paano ito isinasalin |
| **Chat Tester** | Magpadala ng mga live na mensahe at siyasatin ang buong kahilingan/tugon payload kasama ang mga header |
| **Test Bench** | Magpatakbo ng mga batch test sa mga kumbinasyon ng format upang malaman kung aling mga pagsasalin ang sira |
| **Live Monitor** | Panoorin ang daloy ng kahilingan sa real-time upang mahuli ang mga pasulput-sulpot na isyu sa pagsasalin | ### Common format issues |
### Common format issues
- **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`
---
-**Hindi lumalabas ang mga tag ng pag-iisip**— Tingnan kung sinusuportahan ng target na provider ang pag-iisip at ang setting ng badyet sa pag-iisip -**Pagbaba ng mga tawag sa tool**— Maaaring alisin ng ilang pagsasalin ng format ang mga hindi sinusuportahang field; i-verify sa Playground mode -**System prompt nawawala**— Claude at Gemini handle system prompts magkaiba; suriin ang output ng pagsasalin -**Nagbabalik ang SDK ng raw string sa halip na object**— Naayos sa v1.1.0: tinatanggal na ngayon ng response sanitizer ang mga hindi karaniwang field (`x_groq`, `usage_breakdown`, atbp.) na nagdudulot ng mga pagkabigo sa pagpapatunay ng OpenAI SDK Pydantic -**Tinatanggihan ng GLM/ERNIE ang tungkulin ng `system`**— Naayos sa v1.1.0: awtomatikong pinagsasama ng role normalizer ang mga mensahe ng system sa mga mensahe ng user para sa mga hindi tugmang modelo -**Hindi nakilala ang tungkulin ng `developer`**— Naayos sa v1.1.0: awtomatikong na-convert sa `system` para sa mga provider na hindi OpenAI -**`json_schema` hindi gumagana sa Gemini**— Naayos sa v1.1.0: `response_format` ay na-convert na ngayon sa `responseMimeType` + `responseSchema` ng Gemini---
## Resilience Settings
### Auto rate-limit not triggering
- 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
- Nalalapat lang ang limitasyon ng awtomatikong rate sa mga provider ng API key (hindi OAuth/subscription)
- I-verify**Mga Setting → Resilience → Provider Profile**ay pinagana ang auto-rate-limit
- Suriin kung ang provider ay nagbabalik ng `429` status code o `Retry-After` header### Tuning exponential backoff
### Tuning exponential backoff
Sinusuportahan ng mga profile ng provider ang mga setting na ito:
Provider profiles support these settings:
-**Base delay**— Paunang oras ng paghihintay pagkatapos ng unang pagkabigo (default: 1s) -**Max na pagkaantala**— Maximum na limitasyon sa oras ng paghihintay (default: 30s) -**Multiplier**— Magkano ang itataas na pagkaantala sa bawat magkakasunod na pagkabigo (default: 2x)### Anti-thundering herd
- **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)
### 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.
---
Kapag maraming sabay-sabay na kahilingan ang tumama sa isang provider na limitado sa rate, gumagamit ang OmniRoute ng mutex + auto rate-limiting para i-serialize ang mga kahilingan at maiwasan ang mga pagkabigo ng cascading. Ito ay awtomatiko para sa mga API key provider.---
## Optional RAG / LLM failure taxonomy (16 problems)
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.
Inilalagay ng ilang user ng OmniRoute ang gateway sa harap ng RAG o mga stack ng ahente. Sa mga setup na iyon, karaniwan nang makakita ng kakaibang pattern: Mukhang malusog ang OmniRoute (mga provider up, ok ang mga profile sa pagruruta, walang mga alerto sa limitasyon sa rate) ngunit mali pa rin ang huling sagot.
In practice these incidents usually come from the downstream RAG pipeline, not from the gateway itself.
Sa pagsasagawa, ang mga insidenteng ito ay karaniwang nagmumula sa downstream na RAG pipeline, hindi mula sa gateway mismo.
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:
Kung gusto mo ng nakabahaging bokabularyo upang ilarawan ang mga pagkabigo na iyon, maaari mong gamitin ang WFGY ProblemMap, isang panlabas na mapagkukunan ng teksto ng lisensya ng MIT na tumutukoy sa labing-anim na umuulit na pattern ng pagkabigo ng RAG / LLM. Sa isang mataas na antas ito ay sumasaklaw sa:
- 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
- retrieval drift at sirang mga hangganan ng konteksto
- walang laman o lipas na mga index at mga tindahan ng vector
- pag-embed laban sa semantic mismatch
- agarang pagpupulong at mga isyu sa window ng konteksto
- pagbagsak ng lohika at sobrang kumpiyansa na mga sagot
- mahabang kadena at mga pagkabigo sa koordinasyon ng ahente
- multi agent memory at role drift
- mga problema sa pag-deploy at pag-order ng bootstrap
The idea is simple:
Ang ideya ay simple:
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. Kapag nag-imbestiga ka ng masamang tugon, kunin ang:
- gawain at kahilingan ng user
- ruta o provider combo sa OmniRoute
- anumang konteksto ng RAG na ginamit sa ibaba ng agos (mga nakuhang dokumento, mga tawag sa tool, atbp)
2. I-mapa ang insidente sa isa o dalawang numero ng WFGY ProblemMap (`No.1``No.16`).
3. Itago ang numero sa sarili mong dashboard, runbook, o incident tracker sa tabi ng mga log ng OmniRoute.
4. Gamitin ang kaukulang pahina ng WFGY upang magpasya kung kailangan mong baguhin ang iyong RAG stack, retriever, o diskarte sa pagruruta.
Full text and concrete recipes live here (MIT license, text only):
Dito nakatira ang buong teksto at mga konkretong recipe (lisensya ng MIT, text lang):
[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.
---
Maaari mong balewalain ang seksyong ito kung hindi ka nagpapatakbo ng RAG o mga pipeline ng ahente sa likod ng OmniRoute.---
## Still Stuck?
- **GitHub Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
- **Architecture**: See [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) for internal details
- **API Reference**: See [`docs/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
-**Mga Isyu sa GitHub**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -**Arkitektura**: Tingnan ang [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) para sa mga panloob na detalye -**API Reference**: Tingnan ang [`docs/API_REFERENCE.md`](API_REFERENCE.md) para sa lahat ng endpoint -**Dashboard ng Kalusugan**: Suriin ang**Dashboard → Kalusugan**para sa real-time na status ng system -**Translator**: Gamitin ang**Dashboard → Translator**para i-debug ang mga isyu sa format

File diff suppressed because it is too large Load diff

View file

@ -4,37 +4,31 @@
---
Complete guide to install and configure OmniRoute on a VM (VPS) with domain managed via Cloudflare.
---
Kumpletong gabay sa pag-install at pag-configure ng OmniRoute sa isang VM (VPS) na may domain na pinamamahalaan sa pamamagitan ng Cloudflare.---
## Prerequisites
| Item | Minimum | Recommended |
| ---------- | ------------------------ | ---------------- |
| **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 | — |
| **Docker** | Docker Engine 24+ | Docker 27+ |
| aytem | Pinakamababa | Inirerekomenda |
| ---------- | -------------------------- | ---------------- |
| **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** | Nakarehistro sa Cloudflare | — |
| **Docker** | Docker Engine 24+ | Docker 27+ |
**Tested providers**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.
---
**Mga nasubok na provider**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.---
## 1. Configure the VM
### 1.1 Create the instance
On your preferred VPS provider:
Sa iyong gustong VPS provider:
- 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`)
### 1.2 Connect via SSH
- Piliin ang Ubuntu 24.04 LTS
- Piliin ang minimum na plano (1 vCPU / 1 GB RAM)
- Magtakda ng malakas na root password o i-configure ang SSH key
- Tandaan ang**pampublikong IP**(hal., `203.0.113.10`)### 1.2 Connect via SSH
```bash
ssh root@203.0.113.10
@ -78,9 +72,7 @@ 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.
---
> **Tip**: Para sa maximum na seguridad, paghigpitan ang mga port 80 at 443 sa mga Cloudflare IP lamang. Tingnan ang seksyong [Advanced Security](#advanced-security).---
## 2. Install OmniRoute
@ -122,9 +114,7 @@ NEXT_PUBLIC_BASE_URL=https://llms.seudominio.com
EOF
```
> ⚠️ **IMPORTANT**: Generate unique secret keys! Use `openssl rand -hex 32` for each key.
### 2.3 Start the container
> ⚠️**MAHALAGA**: Bumuo ng mga natatanging sikretong key! Gamitin ang `openssl rand -hex 32` para sa bawat key.### 2.3 Start the container
```bash
docker pull diegosouzapw/omniroute:latest
@ -145,32 +135,31 @@ docker ps | grep omniroute
docker logs omniroute --tail 20
```
It should display: `[DB] SQLite database ready` and `listening on port 20128`.
---
Dapat itong magpakita ng: `[DB] SQLite database ready` at `nakikinig sa port 20128`.---
## 3. Configure nginx (Reverse Proxy)
### 3.1 Generate SSL certificate (Cloudflare Origin)
In the Cloudflare dashboard:
Sa dashboard ng 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**
```bash
mkdir -p /etc/nginx/ssl
1. Pumunta sa**SSL/TLS → Origin Server**
2. I-click ang**Gumawa ng Sertipiko**
3. Panatilihin ang mga default (15 taon, \*.yourdomain.com)
4. Kopyahin ang**Origin Certificate**at ang**Private Key**```bash
mkdir -p /etc/nginx/ssl
# Paste the certificate
nano /etc/nginx/ssl/origin.crt
# Paste the private key
nano /etc/nginx/ssl/origin.key
chmod 600 /etc/nginx/ssl/origin.key
```
````
### 3.2 Nginx Configuration
@ -228,13 +217,11 @@ server {
return 301 https://$server_name$request_uri;
}
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.
### 3.3 Enable and Test
Panatilihing nakahanay ang reverse-proxy stream timeout sa iyong OmniRoute timeout env vars. Kung itataas mo
`FETCH_TIMEOUT_MS` / `STREAM_IDLE_TIMEOUT_MS`, taasan ang `proxy_read_timeout` / `proxy_send_timeout`
sa itaas ng parehong threshold.### 3.3 Enable and Test
```bash
# Remove default configuration
@ -253,25 +240,21 @@ nginx -t && systemctl reload nginx
### 4.1 Add DNS record
In the Cloudflare dashboard → DNS:
Sa Cloudflare dashboard → DNS:
| Type | Name | Content | Proxy |
| ---- | ------ | ---------------------- | ---------- |
| A | `llms` | `203.0.113.10` (VM IP) | ✅ Proxied |
| Uri | Pangalan | Nilalaman | Proxy |
| ----- | -------- | ---------------------- | ---------- | --------------------- |
| Isang | `llms` | `203.0.113.10` (VM IP) | ✅ Proxied | ### 4.2 Configure SSL |
### 4.2 Configure SSL
Sa ilalim ng**SSL/TLS → Pangkalahatang-ideya**:
Under **SSL/TLS → Overview**:
- Mode:**Buong (Mahigpit)**
- Mode: **Full (Strict)**
Sa ilalim ng**SSL/TLS → Edge Certificates**:
Under **SSL/TLS → Edge Certificates**:
- Always Use HTTPS: ✅ On
- Minimum TLS Version: TLS 1.2
- Automatic HTTPS Rewrites: ✅ On
### 4.3 Testing
- Palaging Gumamit ng HTTPS: ✅ Naka-on
- Minimum na Bersyon ng TLS: TLS 1.2
- Mga Awtomatikong HTTPS Rewrite: ✅ Naka-on### 4.3 Testing
```bash
curl -sI https://llms.seudominio.com/health
@ -350,11 +333,10 @@ real_ip_header CF-Connecting-IP;
CF
```
Add the following to `nginx.conf` inside the `http {}` block:
```nginx
Idagdag ang sumusunod sa `nginx.conf` sa loob ng `http {}` block:```nginx
include /etc/nginx/cloudflare-ips.conf;
```
````
### Install fail2ban
@ -365,7 +347,7 @@ systemctl start fail2ban
# Check status
fail2ban-client status sshd
```
````
### Block direct access to the Docker port
@ -383,25 +365,25 @@ netfilter-persistent save
## 7. Deploy to Cloudflare Workers (Optional)
For remote access via Cloudflare Workers (without exposing the VM directly):
Para sa malayuang pag-access sa pamamagitan ng Cloudflare Workers (nang hindi direktang inilalantad ang VM):```bash
```bash
# In the local repository
cd omnirouteCloud
npm install
npx wrangler login
npx wrangler deploy
```
See the full documentation at [omnirouteCloud/README.md](../omnirouteCloud/README.md).
---
Tingnan ang buong dokumentasyon sa [omnirouteCloud/README.md](../omnirouteCloud/README.md).---
## Port Summary
| Port | Service | Access |
| Port | Serbisyo | Access |
| ----- | ----------- | -------------------------- |
| 22 | SSH | Public (with fail2ban) |
| 80 | nginx HTTP | Redirect → HTTPS |
| 443 | nginx HTTPS | Via Cloudflare Proxy |
| 20128 | OmniRoute | Localhost only (via nginx) |
| 22 | SSH | Pampubliko (na may fail2ban) |
| 80 | nginx HTTP | I-redirect → HTTPS |
| 443 | nginx HTTPS | Sa pamamagitan ng Cloudflare Proxy |
| 20128 | OmniRoute | Localhost lang (sa pamamagitan ng nginx) |
```

View file

@ -4,11 +4,9 @@
---
> **Agent-to-Agent Protocol v0.3** — Enables any AI agent to use OmniRoute as an intelligent routing agent via JSON-RPC 2.0.
> **Agent-to-Agent Protocol v0.3**— Nagbibigay-daan sa sinumang ahente ng AI na gamitin ang OmniRoute bilang isang intelligent na ahente sa pagruruta sa pamamagitan ng JSON-RPC 2.0.
The A2A Server exposes OmniRoute as a **first-class agent** that other agents can discover, delegate tasks to, and collaborate with using the [A2A Protocol](https://google.github.io/A2A/).
---
Inilalantad ng A2A Server ang OmniRoute bilang isang**first-class agent**na maaaring matuklasan ng ibang mga ahente, magtalaga ng mga gawain, at makipagtulungan sa paggamit ng [A2A Protocol](https://google.github.io/A2A/).---
## Arkitektura
@ -43,15 +41,12 @@ The A2A Server exposes OmniRoute as a **first-class agent** that other agents ca
### Agent Discovery
Every A2A-compatible agent exposes an **Agent Card** at `/.well-known/agent.json`:
```bash
Ang bawat A2A-compatible na ahente ay naglalantad ng**Agent Card**sa `/.well-known/agent.json`:```bash
curl http://localhost:20128/.well-known/agent.json
```
**Response:**
````
```json
**Tugon:**```json
{
"name": "OmniRoute",
"description": "Intelligent AI gateway with auto-routing across 50+ providers",
@ -88,7 +83,7 @@ curl http://localhost:20128/.well-known/agent.json
"apiKeyHeader": "Authorization"
}
}
```
````
---
@ -96,27 +91,24 @@ curl http://localhost:20128/.well-known/agent.json
### `message/send` — Synchronous Execution
Send a message to a skill and receive the complete response.
```bash
Magpadala ng mensahe sa isang kasanayan at tanggapin ang kumpletong tugon.```bash
curl -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/send",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Write a Python hello world"}],
"metadata": {"model": "auto", "combo": "fast-coding"}
}
}'
```
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/send",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Write a Python hello world"}],
"metadata": {"model": "auto", "combo": "fast-coding"}
}
}'
**Response:**
````
```json
**Tugon:**```json
{
"jsonrpc": "2.0",
"id": "1",
@ -133,36 +125,33 @@ curl -X POST http://localhost:20128/a2a \
}
}
}
```
````
### `message/stream` — SSE Streaming
Same as `message/send` but returns Server-Sent Events for real-time streaming.
```bash
Kapareho ng `mensahe/ipadala` ngunit ibinabalik ang Mga Kaganapang Ipinadala ng Server para sa real-time na streaming.```bash
curl -N -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/stream",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Explain quantum computing"}]
}
}'
```
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/stream",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Explain quantum computing"}]
}
}'
**SSE Events:**
````
```
**Mga Kaganapan sa SSE:**```
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"Quantum computing..."}}}
: heartbeat 2026-03-04T21:00:00Z
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
```
````
### `tasks/get` — Query Task Status
@ -188,40 +177,36 @@ curl -X POST http://localhost:20128/a2a \
### `smart-routing`
Routes prompts through OmniRoute's intelligent pipeline with full observability.
Ang mga ruta ay nag-uudyok sa pamamagitan ng intelligent na pipeline ng OmniRoute na may ganap na pagmamasid.
**Parameters (in `metadata`):**
**Mga Parameter (sa `metadata`):**
| Parameter | Type | Default | Description |
| --------- | -------- | ------------ | ---------------------------------------------------------------------------------------- |
| `model` | `string` | `"auto"` | Target model (e.g., `claude-sonnet-4`, `gpt-4o`, `auto`) |
| `combo` | `string` | active combo | Specific combo to route through |
| `budget` | `number` | none | Maximum cost in USD for this request |
| `role` | `string` | none | Task role hint: `coding`, `review`, `planning`, `analysis`, `debugging`, `documentation` |
| Parameter | Uri | Default | Paglalarawan |
| ---------- | -------- | -------------- | ---------------------------------------------------------------------------------------------------------- |
| `modelo` | `string` | `"awto"` | Target na modelo (hal., `claude-sonnet-4`, `gpt-4o`, `auto`) |
| `combo` | `string` | aktibong combo | Tukoy na combo na dadaan sa |
| `badyet` | `numero` | wala | Pinakamataas na halaga sa USD para sa kahilingang ito |
| `gampanin` | `string` | wala | Pahiwatig ng tungkulin ng gawain: `coding`, `review`, `planning`, `analysis`, `debugging`, `documentation` |
**Returns:**
**Pagbabalik:**
| Field | Description |
| ------------------------------ | --------------------------------------------------------- |
| `artifacts[].content` | The LLM response text |
| `metadata.routing_explanation` | Human-readable explanation of routing decision |
| `metadata.cost_envelope` | Estimated vs actual cost with currency |
| `metadata.resilience_trace` | Array of events (primary_selected, fallback_needed, etc.) |
| `metadata.policy_verdict` | Whether the request was allowed and why |
| Patlang | Paglalarawan |
| ------------------------------ | ----------------------------------------------------------------- | ---------------------- |
| `artifacts[].content` | Ang teksto ng tugon ng LLM |
| `metadata.routing_explanation` | Nababasa ng tao na paliwanag ng desisyon sa pagruruta |
| `metadata.cost_envelope` | Tinantyang vs aktwal na gastos sa currency |
| `metadata.resilience_trace` | Array ng mga kaganapan (primary_selected, fallback_needed, atbp.) |
| `metadata.policy_verdict` | Kung pinayagan ang kahilingan at bakit | ### `quota-management` |
### `quota-management`
Sumasagot sa mga query sa natural na wika tungkol sa mga quota ng provider.
Answers natural-language queries about provider quotas.
**Mga uri ng query (hinuha mula sa nilalaman ng mensahe):**
**Query types (inferred from message content):**
| Query Pattern | Response Type |
| ---------------------------------------------- | -------------------------------------------------------- |
| Contains `"ranking"`, `"most quota"`, `"best"` | Providers ranked by remaining quota |
| Contains `"free"`, `"suggest"` | Lists free combos or suggests free-tier providers |
| Default | Full quota summary with warnings for low-quota providers |
---
| Pattern ng Query | Uri ng Tugon |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------ | --- |
| Naglalaman ng `"ranggo"`, `"pinaka quota"`, `"pinakamahusay"` | Niraranggo ang mga provider ayon sa natitirang quota |
| Naglalaman ng `"libre"`, `"suggest"` | Naglilista ng mga libreng combo o nagmumungkahi ng mga free-tier na provider |
| Default | Buong buod ng quota na may mga babala para sa mga provider na mababa ang quota | --- |
## Task Lifecycle
@ -231,19 +216,17 @@ submitted ──→ working ──→ completed
──────────→ cancelled
```
| State | Description |
| ----------- | ----------------------------------------------------- |
| `submitted` | Task created, queued for execution |
| `working` | Skill handler is executing |
| `completed` | Execution succeeded, artifacts available |
| `failed` | Execution failed or task expired (TTL: 5 min default) |
| `cancelled` | Cancelled by client via `tasks/cancel` |
| Estado | Paglalarawan |
| -------------- | -------------------------------------------------------------------- |
| `naisumite` | Nagawa ang gawain, nakapila para sa pagpapatupad |
| `nagtatrabaho` | Ang handler ng kasanayan ay nagsasagawa ng |
| `nakumpleto` | Nagtagumpay ang pagpapatupad, magagamit ang mga artifact |
| `nabigo` | Nabigo ang pagpapatupad o nag-expire ang gawain (TTL: 5 min default) |
| `kinansela` | Kinansela ng kliyente sa pamamagitan ng `tasks/cancel` |
- Terminal states: `completed`, `failed`, `cancelled` (no further transitions)
- Expired tasks in `submitted` or `working` are auto-marked as `failed`
- Tasks are garbage-collected after 2× TTL
---
- Terminal states: `completed`, `failed`, `cancelled` (walang karagdagang transition)
- Ang mga nag-expire na gawain sa `isumite` o `gumagana` ay awtomatikong minarkahan bilang `bigo`
- Ang mga gawain ay kinokolekta ng basura pagkatapos ng 2× TTL---
## Client Examples
@ -541,15 +524,12 @@ func main() {
### 🤖 Use Case 1: Multi-Agent Coding Pipeline
An orchestrator agent delegates code generation to OmniRoute, then passes the output to a review agent.
```python
def coding_pipeline(task: str):
# Step 1: Generate code via OmniRoute A2A
code_result = a2a_send("smart-routing", [
{"role": "user", "content": f"Write production-quality code: {task}"}
], metadata={"model": "auto", "role": "coding"})
code = code_result["artifacts"][0]["content"]
Ang isang ahente ng orkestra ay nagtatalaga ng pagbuo ng code sa OmniRoute, pagkatapos ay ipinapasa ang output sa isang ahente ng pagsusuri.```python
def coding_pipeline(task: str): # Step 1: Generate code via OmniRoute A2A
code_result = a2a_send("smart-routing", [
{"role": "user", "content": f"Write production-quality code: {task}"}
], metadata={"model": "auto", "role": "coding"})
code = code_result["artifacts"][0]["content"]
# Step 2: Review the code via OmniRoute A2A (different model)
review_result = a2a_send("smart-routing", [
@ -562,13 +542,12 @@ def coding_pipeline(task: str):
print(f"Review cost: ${review_result['metadata']['cost_envelope']['actual']}")
return {"code": code, "review": review}
```
````
### 💡 Use Case 2: Quota-Aware Agent Swarm
Multiple agents share quota through OmniRoute, using the quota skill to coordinate.
```python
Maraming ahente ang nagbabahagi ng quota sa pamamagitan ng OmniRoute, gamit ang kakayahan sa quota para mag-coordinate.```python
async def quota_aware_agent(agent_name: str, task: str):
# Check quota before starting
quota = a2a_send("quota-management", [
@ -591,32 +570,30 @@ async def quota_aware_agent(agent_name: str, task: str):
print(f"[{agent_name}] Free alternatives: {quota['artifacts'][0]['content']}")
return result
```
````
### 📊 Use Case 3: Real-Time Streaming Dashboard
A monitoring agent streams responses and displays progress in real-time.
```typescript
Ang isang ahente sa pagsubaybay ay nag-stream ng mga tugon at nagpapakita ng pag-unlad sa real-time.```typescript
async function streamingDashboard(prompt: string) {
const response = await fetch(`${BASE_URL}/a2a`, {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: `Bearer ${API_KEY}` },
body: JSON.stringify({
jsonrpc: "2.0",
id: "dash-1",
method: "message/stream",
params: { skill: "smart-routing", messages: [{ role: "user", content: prompt }] },
}),
});
body: JSON.stringify({
jsonrpc: "2.0",
id: "dash-1",
method: "message/stream",
params: { skill: "smart-routing", messages: [{ role: "user", content: prompt }] },
}),
});
let totalChunks = 0;
const reader = response.body!.getReader();
const decoder = new TextDecoder();
let totalChunks = 0;
const reader = response.body!.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
while (true) {
const { done, value } = await reader.read();
if (done) break;
for (const line of decoder.decode(value).split("\n")) {
if (line.startsWith("data: ")) {
@ -640,15 +617,15 @@ async function streamingDashboard(prompt: string) {
}
}
}
}
}
```
}
````
### 🔁 Use Case 4: Task Polling Pattern
For long-running tasks, poll the task status instead of waiting synchronously.
```python
Para sa mga matagal nang gawain, i-poll ang status ng gawain sa halip na maghintay nang sabay-sabay.```python
import time
def poll_task(task_id: str, timeout: int = 60):
@ -678,75 +655,71 @@ def poll_task(task_id: str, timeout: int = 60):
"params": {"taskId": task_id},
})
raise TimeoutError(f"Task {task_id} timed out after {timeout}s")
```
````
---
## Error Codes
| Code | Constant | Meaning |
| ------ | ------------------------ | ---------------------------------------- |
| -32700 | — | Parse error (invalid JSON) |
| -32600 | `INVALID_REQUEST` | Invalid JSON-RPC request or unauthorized |
| -32601 | `METHOD_NOT_FOUND` | Unknown method or skill |
| -32602 | `INVALID_PARAMS` | Missing or invalid parameters |
| -32603 | `INTERNAL_ERROR` | Skill execution failed |
| -32001 | `TASK_NOT_FOUND` | Task ID not found |
| -32002 | `TASK_ALREADY_COMPLETED` | Cannot modify a completed task |
| -32003 | `UNAUTHORIZED` | Invalid or missing API key |
| -32004 | `BUDGET_EXCEEDED` | Request exceeds configured budget |
| -32005 | `PROVIDER_UNAVAILABLE` | No available providers |
---
| Code | pare-pareho | Ibig sabihin |
| ------ | ------------------------ | ------------------------------------------------------ | --- |
| -32700 | — | Error sa pag-parse (di-wastong JSON) |
| -32600 | `INVALID_REQUEST` | Di-wastong kahilingan sa JSON-RPC o hindi awtorisadong |
| -32601 | `METHOD_NOT_FOUND` | Hindi alam na paraan o kasanayan |
| -32602 | `INVALID_PARAMS` | Nawawala o di-wastong mga parameter |
| -32603 | `INTERNAL_ERROR` | Nabigo ang pagpapatupad ng kasanayan |
| -32001 | `GAWAIN_HINDI_NATAGPUAN` | Hindi nakita ang Task ID |
| -32002 | `KUMPLETO_MAG-GAWAIN` | Hindi mabago ang isang nakumpletong gawain |
| -32003 | `HINDI AUTHORIZED` | Di-wasto o nawawala ang API key |
| -32004 | `BUDGET_EXCEEDED` | Ang kahilingan ay lumampas sa naka-configure na badyet |
| -32005 | `PROVIDER_UNAVAILABLE` | Walang available na provider | --- |
## Authentication
All `/a2a` requests require a Bearer token via the `Authorization` header:
```
Lahat ng hiling na `/a2a` ay nangangailangan ng isang Bearer token sa pamamagitan ng header ng `Authorization`:```
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
```
If no API key is configured on the server (`OMNIROUTE_API_KEY` is empty), authentication is bypassed.
---
Kung walang API key na naka-configure sa server (ang `OMNIROUTE_API_KEY` ay walang laman), ang pagpapatotoo ay na-bypass.---
## File Structure
```
src/lib/a2a/
├── taskManager.ts # Task lifecycle (create/update/cancel/list), TTL, cleanup
├── taskExecution.ts # Generic task executor with state management
├── streaming.ts # SSE stream formatting, heartbeat, chunk/completion events
├── routingLogger.ts # Routing decision logger (stats, history, retention)
├── taskManager.ts # Task lifecycle (create/update/cancel/list), TTL, cleanup
├── taskExecution.ts # Generic task executor with state management
├── streaming.ts # SSE stream formatting, heartbeat, chunk/completion events
├── routingLogger.ts # Routing decision logger (stats, history, retention)
└── skills/
├── smartRouting.ts # Smart routing skill (routes via /v1/chat/completions)
└── quotaManagement.ts # Quota management skill (natural-language quota queries)
├── smartRouting.ts # Smart routing skill (routes via /v1/chat/completions)
└── quotaManagement.ts # Quota management skill (natural-language quota queries)
src/app/a2a/
└── route.ts # Next.js API route handler (JSON-RPC 2.0 dispatch)
└── route.ts # Next.js API route handler (JSON-RPC 2.0 dispatch)
open-sse/mcp-server/
└── schemas/a2a.ts # Zod schemas (AgentCard, Task, JSON-RPC, SSE events)
└── schemas/a2a.ts # Zod schemas (AgentCard, Task, JSON-RPC, SSE events)
```
---
## Comparison: MCP vs A2A
| Feature | MCP Server | A2A Server |
| Tampok | MCP Server | A2A Server |
| ----------------- | ---------------------------- | ------------------------------------------------- |
| **Protocol** | Model Context Protocol | Agent-to-Agent Protocol v0.3 |
| **Transport** | stdio / HTTP | HTTP (JSON-RPC 2.0) |
| **Discovery** | Tool listing via MCP | `/.well-known/agent.json` |
| **Granularity** | 16 individual tools | 2 high-level skills |
| **Best for** | IDE agents (Cursor, VS Code) | Multi-agent systems (LangChain, CrewAI) |
| **Streaming** | Not supported | SSE via `message/stream` |
| **Task tracking** | No | Full lifecycle (submitted → completed) |
| **Observability** | Audit log per tool call | Cost envelope + resilience trace + policy verdict |
---
|**Protocol**| Model Context Protocol | Agent-to-Agent Protocol v0.3 |
|**Sasakyan**| stdio / HTTP | HTTP (JSON-RPC 2.0) |
|**Pagtuklas**| Listahan ng tool sa pamamagitan ng MCP | `/.well-known/agent.json` |
|**Granularity**| 16 indibidwal na tool | 2 mataas na antas ng kasanayan |
|**Pinakamahusay para sa**| Mga ahente ng IDE (Cursor, VS Code) | Multi-agent system (LangChain, CrewAI) |
|**Pag-stream**| Hindi suportado | SSE sa pamamagitan ng `mensahe/stream` |
|**Pagsubaybay sa gawain**| Hindi | Buong lifecycle (naisumite → nakumpleto) |
|**Pagmamasid**| Audit log sa bawat tool call | Sobre ng gastos + bakas ng katatagan + hatol ng patakaran |---
## Lisensya
Part of [OmniRoute](https://github.com/diegosouzapw/OmniRoute) — MIT License.
Bahagi ng [OmniRoute](https://github.com/diegosouzapw/OmniRoute) — Lisensya ng MIT.
```