Loading OmniRoute...
Languages: ๐บ๐ธ English | ๐ง๐ท Portuguรชs (Brasil) | ๐ช๐ธ Espaรฑol | ๐ซ๐ท Franรงais | ๐ฎ๐น Italiano | ๐ท๐บ ะ ัััะบะธะน | ๐จ๐ณ ไธญๆ (็ฎไฝ) | ๐ฉ๐ช Deutsch | ๐ฎ๐ณ เคนเคฟเคจเฅเคฆเฅ | ๐น๐ญ เนเธเธข | ๐บ๐ฆ ะฃะบัะฐัะฝััะบะฐ | ๐ธ๐ฆ ุงูุนุฑุจูุฉ | ๐ฏ๐ต ๆฅๆฌ่ช | ๐ป๐ณ Tiแบฟng Viแปt | ๐ง๐ฌ ะัะปะณะฐััะบะธ | ๐ฉ๐ฐ Dansk | ๐ซ๐ฎ Suomi | ๐ฎ๐ฑ ืขืืจืืช | ๐ญ๐บ Magyar | ๐ฎ๐ฉ Bahasa Indonesia | ๐ฐ๐ท ํ๊ตญ์ด | ๐ฒ๐พ Bahasa Melayu | ๐ณ๐ฑ Nederlands | ๐ณ๐ด Norsk | ๐ต๐น Portuguรชs (Portugal) | ๐ท๐ด Romรขnฤ | ๐ต๐ฑ Polski | ๐ธ๐ฐ Slovenฤina | ๐ธ๐ช Svenska | ๐ต๐ญ Filipino | ๐จ๐ฟ ฤeลกtina
Last updated: 2026-05-02
) and routes traffic across multiple upstream providers with translation, fallback, token refresh, and usage tracking.
handles provider execution, translation, streaming, fallback, and usage:
flowchart LR
subgraph Clients[Developer Clients]
C1[Claude Code]
C2[Codex CLI]
C3[OpenClaw / Droid / Cline / Continue / Roo]
C4[Custom OpenAI-compatible clients]
BROWSER[Browser Dashboard]
end
subgraph Router[OmniRoute Local Process]
API[V1 Compatibility API\n/v1/*]
DASH[Dashboard + Management API\n/api/*]
CORE[SSE + Translation Core\nopen-sse + src/sse]
DB[(storage.sqlite)]
UDB[(usage tables + log artifacts)]
end
subgraph Upstreams[Upstream Providers]
P1[OAuth Providers\nClaude/Codex/Gemini/Qwen/Qoder/GitHub/Kiro/Cursor/Antigravity]
P2[API Key Providers\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA]
P3[Compatible Nodes\nOpenAI-compatible / Anthropic-compatible]
end
subgraph Cloud[Optional Cloud Sync]
CLOUD[Cloud Sync Endpoint\nNEXT_PUBLIC_CLOUD_URL]
end
C1 --> API
C2 --> API
C3 --> API
C4 --> API
BROWSER --> DASH
API --> CORE
DASH --> DB
CORE --> DB
CORE --> UDB
CORE --> P1
CORE --> P2
CORE --> P3
DASH --> CLOUD
for compatibility APIs
- for management/configuration APIs
- map
to
- (GET/POST/DELETE)
- (GET)
- (GET/PUT/DELETE) +
(POST)
- ,
, ,
- ,
- (GET/PUT)
- (GET/PUT)
- (GET/PUT)
- ,
, and
- (GET)
- (GET)
- (GET/PATCH) โ request queue, connection cooldown, provider breaker, wait-for-cooldown config
- (POST) โ reset provider breakers
- (GET/DELETE)
- (GET)
- (GET/POST)
- (GET/POST/DELETE)
- (GET, with pagination + structured metadata)
- (GET/POST),
(GET)
- (GET/POST)
- (GET/POST),
(GET/DELETE)
- (GET, ETag-versioned snapshot of settings/providers/combos/keys)
- โ Upgrade handler for OpenAI-compatible WS clients
/ , , defaults
):
, , , , , , , , , ,
when set, else )
)
- :
, ,
- ,
, )
-
, , , ,
- entries
- (env vars) and
(configurable per-provider or global)
- โ blocks private/loopback/link-local ranges for all provider calls
- โ Zod schema for all environment variables, surfaced as startup errors/warnings
- โ scoped tokens for config bundle download endpoints; backed by
SQLite table (migration )
- โ validates WS upgrade requests via API key or session cookie
,
sequenceDiagram
autonumber
participant Client as CLI/SDK Client
participant Route as /api/v1/chat/completions
participant Chat as src/sse/handlers/chat
participant Core as open-sse/handlers/chatCore
participant Model as Model Resolver
participant Auth as Credential Selector
participant Exec as Provider Executor
participant Prov as Upstream Provider
participant Stream as Stream Translator
participant Usage as usageDb
Client->>Route: POST /v1/chat/completions
Route->>Chat: handleChat(request)
Chat->>Model: parse/resolve model or combo
alt Combo model
Chat->>Chat: iterate combo models (handleComboChat)
end
Chat->>Auth: getProviderCredentials(provider)
Auth-->>Chat: active account + tokens/api key
Chat->>Core: handleChatCore(body, modelInfo, credentials)
Core->>Core: detect source format
Core->>Core: translate request to target format
Core->>Exec: execute(provider, transformedBody)
Exec->>Prov: upstream API call
Prov-->>Exec: SSE/JSON response
Exec-->>Core: response + metadata
alt 401/403
Core->>Exec: refreshCredentials()
Exec-->>Core: updated tokens
Core->>Exec: retry request
end
Core->>Stream: translate/normalize stream to client format
Stream-->>Client: SSE chunks / JSON response
Stream->>Usage: extract usage + persist history/log
flowchart TD
A[Incoming model string] --> B{Is combo name?}
B -- Yes --> C[Load combo models sequence]
B -- No --> D[Single model path]
C --> E[Try model N]
E --> F[Resolve provider/model]
D --> F
F --> G[Select account credentials]
G --> H{Credentials available?}
H -- No --> I[Return provider unavailable]
H -- Yes --> J[Execute request]
J --> K{Success?}
K -- Yes --> L[Return response]
K -- No --> M{Fallback-eligible error?}
M -- No --> N[Return error]
M -- Yes --> O[Mark account unavailable cooldown]
O --> P{Another account for provider?}
P -- Yes --> G
P -- No --> Q{In combo with next model?}
Q -- Yes --> E
Q -- No --> R[Return all unavailable]
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.
sequenceDiagram
autonumber
participant UI as Dashboard UI
participant OAuth as /api/oauth/[provider]/[action]
participant ProvAuth as Provider Auth Server
participant DB as localDb
participant Test as /api/providers/[id]/test
participant Exec as Provider Executor
UI->>OAuth: GET authorize or device-code
OAuth->>ProvAuth: create auth/device flow
ProvAuth-->>OAuth: auth URL or device code payload
OAuth-->>UI: flow data
UI->>OAuth: POST exchange or poll
OAuth->>ProvAuth: token exchange/poll
ProvAuth-->>OAuth: access/refresh tokens
OAuth->>DB: createProviderConnection(oauth data)
OAuth-->>UI: success + connection id
UI->>Test: POST /api/providers/[id]/test
Test->>Exec: validate credentials / optional refresh
Exec-->>Test: valid or refreshed token info
Test->>DB: update status/tokens/errors
Test-->>UI: validation result
via executor .
sequenceDiagram
autonumber
participant UI as Endpoint Page UI
participant Sync as /api/sync/cloud
participant DB as localDb
participant Cloud as External Cloud Sync
participant Claude as ~/.claude/settings.json
UI->>Sync: POST action=enable
Sync->>DB: set cloudEnabled=true
Sync->>DB: ensure API key exists
Sync->>Cloud: POST /sync/{machineId} (providers/aliases/combos/keys)
Cloud-->>Sync: sync result
Sync->>Cloud: GET /{machineId}/v1/verify
Sync-->>UI: enabled + verification status
UI->>Sync: POST action=sync
Sync->>Cloud: POST /sync/{machineId}
Cloud-->>Sync: remote data
Sync->>DB: update newer local tokens/status
Sync-->>UI: synced
UI->>Sync: POST action=disable
Sync->>DB: set cloudEnabled=false
Sync->>Cloud: DELETE /sync/{machineId}
Sync->>Claude: switch ANTHROPIC_BASE_URL back to local (if needed)
Sync-->>UI: disabled
when cloud is enabled.
erDiagram
SETTINGS ||--o{ PROVIDER_CONNECTION : controls
PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_provider
PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage
SETTINGS {
boolean cloudEnabled
number stickyRoundRobinLimit
boolean requireLogin
string password_hash
string fallbackStrategy
json rateLimitDefaults
json providerProfiles
}
PROVIDER_CONNECTION {
string id
string provider
string authType
string name
number priority
boolean isActive
string apiKey
string accessToken
string refreshToken
string expiresAt
string testStatus
string lastError
string rateLimitedUntil
json providerSpecificData
}
PROVIDER_NODE {
string id
string type
string name
string prefix
string apiType
string baseUrl
}
MODEL_ALIAS {
string alias
string targetModel
}
COMBO {
string id
string name
string[] models
}
API_KEY {
string id
string name
string key
string machineId
}
USAGE_ENTRY {
string provider
string model
number prompt_tokens
number completion_tokens
string connectionId
string timestamp
}
CUSTOM_MODEL {
string id
string name
string providerId
}
PROXY_CONFIG {
string global
json providers
}
IP_FILTER {
string mode
string[] allowlist
string[] blocklist
}
THINKING_BUDGET {
string mode
number customBudget
string effortLevel
}
SYSTEM_PROMPT {
boolean enabled
string prompt
string position
}
flowchart LR
subgraph LocalHost[Developer Host]
CLI[CLI Tools]
Browser[Dashboard Browser]
end
subgraph ContainerOrProcess[OmniRoute Runtime]
Next[Next.js Server\nPORT=20128]
Core[SSE Core + Executors]
MainDB[(storage.sqlite)]
UsageDB[(usage tables + log artifacts)]
end
subgraph External[External Services]
Providers[AI Providers]
SyncCloud[Cloud Sync Service]
end
CLI --> Next
Browser --> Next
Next --> Core
Next --> MainDB
Core --> MainDB
Core --> UsageDB
Core --> Providers
Next --> SyncCloud
: compatibility APIs
- : dedicated per-provider routes (chat, embeddings, images)
- : provider CRUD, validation, testing
- : custom compatible node management
- : custom model management (CRUD)
- : model catalog API (aliases + custom models)
- : OAuth/device-code flows
- : local API key lifecycle
- : alias management
- : fallback combo management
- : pricing overrides for cost calculation
- : proxy configuration (GET/PUT/DELETE)
- : outbound proxy connectivity test (POST)
- : usage and logs APIs
- +
: cloud sync and cloud-facing helpers
- : local CLI config writers/checkers
- : IP allowlist/blocklist (GET/PUT)
- : thinking token budget config (GET/PUT)
- : global system prompt (GET/PUT)
- : global compression settings (GET/PUT)
- : compression preview, rule metadata, and language packs
- : Caveman settings alias (GET/PUT)
- : RTK config, filter catalog, test endpoint, and raw-output recovery
- : compression combo CRUD and routing-combo assignments
- : compression analytics alias
- : active session listing (GET)
- : per-account rate limit status (GET)
- : sync token CRUD (GET/POST)
- : sync token get/delete (GET/DELETE)
- : config bundle download (GET, ETag versioning)
- : WebSocket upgrade handler for OpenAI-compatible WS clients
(in ), which provides URL building, header construction, retry with exponential backoff, credential refresh hooks, and the orchestration method.
.
OpenAI as the hub format โ all conversions go through OpenAI as intermediate:
โ for non-OpenAI targets; merges โ for models that reject the system role (GLM, ERNIE) blocks from content into field to Gemini's + ) 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 contains .
) is retained only for legacy compatibility. The current runtime contract uses:
- artifacts when the call log pipeline is enabled
, )
- unset):
- ,
- ,
,
- ,
- ,
, , and lowercase variants
- ,
- ,
, ,
share the same base directory policy ( -> -> ) with legacy file migration.
- delegates to the same unified catalog builder used by
() to avoid semantic drift.
-
- and cloud endpoint reachability.
- directory is published as the
npm workspace package. Source code imports it via (resolved by Next.js ). File paths in this document still use the directory name for consistency.
- Recharts (SVG-based) for accessible, interactive analytics visualizations (model usage bar charts, provider breakdown tables with success rates).
- Playwright (
), run via . Unit tests use Node.js test runner (), run via . Source code under is TypeScript (/); the workspace remains JavaScript ().
-
- Context Relay strategy (
) is split across two layers: decides if a handoff should be generated, injects the handoff after account resolution. Handoff data lives in SQLite table. This split is intentional because only knows whether the actual account changed.
- Proxy enforcement is now comprehensive:
resolves proxy per connection, uses , and uses to maintain dispatcher compatibility on Node 22.
- Node.js runtime policy detection:
returns and fields. The login page renders a warning banner when the runtime falls outside the supported secure Node.js lines.