mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-05-03 00:30:26 +00:00
781 lines
38 KiB
Markdown
781 lines
38 KiB
Markdown
# OmniRoute-arkitektur
|
|
|
|
🌐 **Languages:** 🇺🇸 [English](../../ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](../es/ARCHITECTURE.md) | 🇫🇷 [Français](../fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](../it/ARCHITECTURE.md) | 🇷🇺 [Русский](../ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](../zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](../de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](../in/ARCHITECTURE.md) | 🇹🇭 [ไทย](../th/ARCHITECTURE.md) | 🇺🇦 [Українська](../uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](../ar/ARCHITECTURE.md) | 🇯🇵 [日本語](../ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](../vi/ARCHITECTURE.md) | 🇧🇬 [Български](../bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](../da/ARCHITECTURE.md) | 🇫🇮 [Suomi](../fi/ARCHITECTURE.md) | 🇮🇱 [עברית](../he/ARCHITECTURE.md) | 🇭🇺 [Magyar](../hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](../id/ARCHITECTURE.md) | 🇰🇷 [한국어](../ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](../ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](../nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](../no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](../pt/ARCHITECTURE.md) | 🇷🇴 [Română](../ro/ARCHITECTURE.md) | 🇵🇱 [Polski](../pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](../sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](../sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](../phi/ARCHITECTURE.md)
|
|
|
|
_Sidst opdateret: 2026-02-18_
|
|
|
|
## Resumé
|
|
|
|
OmniRoute er en lokal AI-routinggateway og dashboard bygget på Next.js.
|
|
Det giver et enkelt OpenAI-kompatibelt slutpunkt (`/v1/*`) og dirigerer trafik på tværs af flere upstream-udbydere med oversættelse, fallback, token-opdatering og brugssporing.
|
|
|
|
Kerneegenskaber:
|
|
|
|
- OpenAI-kompatibel API-overflade til CLI/værktøjer (28 udbydere)
|
|
- Anmodning/svar oversættelse på tværs af udbyderformater
|
|
- Model combo fallback (multi-model sekvens)
|
|
- Fallback på kontoniveau (multi-konto pr. udbyder)
|
|
- Administration af forbindelse til OAuth + API-nøgleudbyder
|
|
- Indlejringsgenerering via `/v1/embeddings` (6 udbydere, 9 modeller)
|
|
- Billedgenerering via `/v1/images/generations` (4 udbydere, 9 modeller)
|
|
- Tænk tag-parsing (`<think>...</think>`) for ræsonneringsmodeller
|
|
- Response sanitization for streng OpenAI SDK-kompatibilitet
|
|
- Rollenormalisering (udvikler→system, system→bruger) for kompatibilitet på tværs af udbydere
|
|
- Struktureret outputkonvertering (json_schema → Gemini responseSchema)
|
|
- Lokal persistens for udbydere, nøgler, aliaser, kombinationer, indstillinger, priser
|
|
- Brug/omkostningssporing og anmodningslogning
|
|
- Valgfri skysynkronisering til synkronisering af flere enheder/tilstande
|
|
- IP-tilladelsesliste/blokeringsliste til API-adgangskontrol
|
|
- Tænkende budgetstyring (passthrough/auto/custom/adaptive)
|
|
- Global system prompt injektion
|
|
- Sessionssporing og fingeraftryk
|
|
- Forbedret prisbegrænsning pr. konto med udbyderspecifikke profiler
|
|
- Circuit breaker mønster for udbyderens modstandsdygtighed
|
|
- Anti-tordenbeskyttelse med mutex-låsning
|
|
- Signaturbaseret anmodnings deduplikeringscache
|
|
- Domænelag: modeltilgængelighed, omkostningsregler, fallback-politik, lockout-politik
|
|
- Vedvarende domænetilstand (SQLite-gennemskrivningscache til fallbacks, budgetter, lockouts, strømafbrydere)
|
|
- Politikmotor til centraliseret anmodningsevaluering (lockout → budget → fallback)
|
|
- Anmod om telemetri med p50/p95/p99 latency aggregering
|
|
- Korrelations-ID (X-Request-Id) til ende-til-ende-sporing
|
|
- Overholdelsesrevisionslogning med opt-out pr. API-nøgle
|
|
- Evalueringsramme for LLM kvalitetssikring
|
|
- Resilience UI-dashboard med strømafbryderstatus i realtid
|
|
- Modulære OAuth-udbydere (12 individuelle moduler under `src/lib/oauth/providers/`)
|
|
|
|
Primær runtime model:
|
|
|
|
- Next.js app-ruter under `src/app/api/*` implementerer både dashboard-API'er og kompatibilitets-API'er
|
|
- En delt SSE/routingkerne i `src/sse/*` + `open-sse/*` håndterer udbyderens udførelse, oversættelse, streaming, fallback og brug
|
|
|
|
## Omfang og grænser
|
|
|
|
### I omfang
|
|
|
|
- Lokal gateway køretid
|
|
- Dashboard management API'er
|
|
- Udbydergodkendelse og tokenopdatering
|
|
- Anmod om oversættelse og SSE-streaming
|
|
- Lokal stat + vedvarende brug
|
|
- Valgfri skysynkroniseringsorkestrering
|
|
|
|
### Uden for anvendelsesområde
|
|
|
|
- Cloud-tjenesteimplementering bag `NEXT_PUBLIC_CLOUD_URL`
|
|
- Udbyder SLA/kontrolplan uden for lokal proces
|
|
- Eksterne CLI-binære filer selv (Claude CLI, Codex CLI osv.)
|
|
|
|
## Systemkontekst på højt niveau
|
|
|
|
```mermaid
|
|
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[(db.json)]
|
|
UDB[(usage.json + log.txt)]
|
|
end
|
|
|
|
subgraph Upstreams[Upstream Providers]
|
|
P1[OAuth Providers\nClaude/Codex/Gemini/Qwen/iFlow/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
|
|
```
|
|
|
|
## Core Runtime Components
|
|
|
|
## 1) API og Routing Layer (Next.js App Routes)
|
|
|
|
Hovedmapper:
|
|
|
|
- `src/app/api/v1/*` og `src/app/api/v1beta/*` for kompatibilitets-API'er
|
|
- `src/app/api/*` til administrations-/konfigurations-API'er
|
|
- Næste omskrivninger i `next.config.mjs` kort `/v1/*` til `/api/v1/*`
|
|
|
|
Vigtige kompatibilitetsruter:
|
|
|
|
- `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` — inkluderer brugerdefinerede modeller med `custom: true`
|
|
- `src/app/api/v1/embeddings/route.ts` — indlejringsgenerering (6 udbydere)
|
|
- `src/app/api/v1/images/generations/route.ts` — billedgenerering (4+ udbydere inkl. Antigravity/Nebius)
|
|
- `src/app/api/v1/messages/count_tokens/route.ts`
|
|
- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — dedikeret chat pr. udbyder
|
|
- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — dedikerede indlejringer pr. udbyder
|
|
- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — dedikerede billeder pr. udbyder
|
|
- `src/app/api/v1beta/models/route.ts`
|
|
- `src/app/api/v1beta/models/[...path]/route.ts`
|
|
|
|
Ledelsesdomæner:
|
|
|
|
- Godkendelse/indstillinger: `src/app/api/auth/*`, `src/app/api/settings/*`
|
|
- Udbydere/forbindelser: `src/app/api/providers*`
|
|
- Udbyder noder: `src/app/api/provider-nodes*`
|
|
- Brugerdefinerede modeller: `src/app/api/provider-models` (GET/POST/DELETE)
|
|
- Modelkatalog: `src/app/api/models/catalog` (GET)
|
|
- Proxy-konfiguration: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
|
- OAuth: `src/app/api/oauth/*`
|
|
- Nøgler/aliaser/kombinationer/priser: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
|
|
- Anvendelse: `src/app/api/usage/*`
|
|
- Synkroniser/sky: `src/app/api/sync/*`, `src/app/api/cloud/*`
|
|
- CLI-værktøjshjælpere: `src/app/api/cli-tools/*`
|
|
- IP-filter: `src/app/api/settings/ip-filter` (GET/PUT)
|
|
- Tænkende budget: `src/app/api/settings/thinking-budget` (GET/PUT)
|
|
- Systemprompt: `src/app/api/settings/system-prompt` (GET/PUT)
|
|
- Sessioner: `src/app/api/sessions` (GET)
|
|
- Satsgrænser: `src/app/api/rate-limits` (GET)
|
|
- Modstandsdygtighed: `src/app/api/resilience` (GET/PATCH) — udbyderprofiler, strømafbryder, hastighedsgrænsetilstand
|
|
- Resilience reset: `src/app/api/resilience/reset` (POST) — nulstil breakers + cooldowns
|
|
- Cachestatistik: `src/app/api/cache/stats` (GET/DELETE)
|
|
- Modeltilgængelighed: `src/app/api/models/availability` (GET/POST)
|
|
- Telemetri: `src/app/api/telemetry/summary` (GET)
|
|
- Budget: `src/app/api/usage/budget` (GET/POST)
|
|
- Fallback-kæder: `src/app/api/fallback/chains` (GET/POST/DELETE)
|
|
- Overholdelsesrevision: `src/app/api/compliance/audit-log` (GET)
|
|
- Evaler: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
|
- Politikker: `src/app/api/policies` (GET/POST)
|
|
|
|
## 2) SSE + Oversættelseskerne
|
|
|
|
Hovedflowmoduler:
|
|
|
|
- Indgang: `src/sse/handlers/chat.ts`
|
|
- Kerneorkestrering: `open-sse/handlers/chatCore.ts`
|
|
- Leverandørudførelsesadaptere: `open-sse/executors/*`
|
|
- Formatdetektion/udbyderkonfiguration: `open-sse/services/provider.ts`
|
|
- Modelparse/opløsning: `src/sse/services/model.ts`, `open-sse/services/model.ts`
|
|
- Konto fallback logik: `open-sse/services/accountFallback.ts`
|
|
- Oversættelsesregister: `open-sse/translator/index.ts`
|
|
- Strømtransformationer: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts`
|
|
- Brugsekstraktion/normalisering: `open-sse/utils/usageTracking.ts`
|
|
- Tænk tag-parser: `open-sse/utils/thinkTagParser.ts`
|
|
- Indlejringshåndtering: `open-sse/handlers/embeddings.ts`
|
|
- Indlejring af udbyderregistrering: `open-sse/config/embeddingRegistry.ts`
|
|
- Billedgenereringsbehandler: `open-sse/handlers/imageGeneration.ts`
|
|
- Billedudbyderregistrering: `open-sse/config/imageRegistry.ts`
|
|
- Reaktionssanering: `open-sse/handlers/responseSanitizer.ts`
|
|
- Rollenormalisering: `open-sse/services/roleNormalizer.ts`
|
|
|
|
Tjenester (forretningslogik):
|
|
|
|
- Kontovalg/score: `open-sse/services/accountSelector.ts`
|
|
- Kontekstlivscyklusstyring: `open-sse/services/contextManager.ts`
|
|
- Håndhævelse af IP-filter: `open-sse/services/ipFilter.ts`
|
|
- Sessionssporing: `open-sse/services/sessionManager.ts`
|
|
- Anmod om deduplikering: `open-sse/services/signatureCache.ts`
|
|
- Systemprompt indsprøjtning: `open-sse/services/systemPrompt.ts`
|
|
- Tænkende budgetstyring: `open-sse/services/thinkingBudget.ts`
|
|
- Wildcard model routing: `open-sse/services/wildcardRouter.ts`
|
|
- Satsgrænsestyring: `open-sse/services/rateLimitManager.ts`
|
|
- Afbryder: `open-sse/services/circuitBreaker.ts`
|
|
|
|
Domænelagsmoduler:
|
|
|
|
- Modeltilgængelighed: `src/lib/domain/modelAvailability.ts`
|
|
- Omkostningsregler/budgetter: `src/lib/domain/costRules.ts`
|
|
- Fallback-politik: `src/lib/domain/fallbackPolicy.ts`
|
|
- Combo resolver: `src/lib/domain/comboResolver.ts`
|
|
- Lockout-politik: `src/lib/domain/lockoutPolicy.ts`
|
|
- Politikmotor: `src/domain/policyEngine.ts` — centraliseret lockout → budget → fallback-evaluering
|
|
- Fejlkodekatalog: `src/lib/domain/errorCodes.ts`
|
|
- Anmodnings-id: `src/lib/domain/requestId.ts`
|
|
- Hente timeout: `src/lib/domain/fetchTimeout.ts`
|
|
- Anmod om telemetri: `src/lib/domain/requestTelemetry.ts`
|
|
- Overholdelse/revision: `src/lib/domain/compliance/index.ts`
|
|
- Evalløber: `src/lib/domain/evalRunner.ts`
|
|
- Vedvarende domænetilstand: `src/lib/db/domainState.ts` — SQLite CRUD til reservekæder, budgetter, omkostningshistorik, lockouttilstand, afbrydere
|
|
|
|
OAuth-udbydermoduler (12 individuelle filer under `src/lib/oauth/providers/`):
|
|
|
|
- Registerindeks: `src/lib/oauth/providers/index.ts`
|
|
- Individuelle udbydere: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, , , `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
|
|
- Tyndt omslag: `src/lib/oauth/providers.ts` — reeksport fra individuelle moduler
|
|
|
|
## 3) Persistens-lag
|
|
|
|
Primær tilstand DB:
|
|
|
|
- `src/lib/localDb.ts`
|
|
- fil: `${DATA_DIR}/db.json` (eller `$XDG_CONFIG_HOME/omniroute/db.json` når indstillet, ellers `~/.omniroute/db.json`)
|
|
- enheder: providerConnections, providerNodes, modelAliaser, combos, apiKeys, indstillinger, prissætning, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt**
|
|
|
|
Brug DB:
|
|
|
|
- `src/lib/usageDb.ts`
|
|
- filer: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`
|
|
- følger den samme grundlæggende bibliotekspolitik som `localDb` (`DATA_DIR`, derefter `XDG_CONFIG_HOME/omniroute`, når den er indstillet)
|
|
- opdelt i fokuserede undermoduler: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts`
|
|
|
|
Domain State DB (SQLite):
|
|
|
|
- `src/lib/db/domainState.ts` — CRUD-operationer for domænetilstand
|
|
- Tabeller (oprettet i `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
|
|
- Gennemskrivningscachemønster: Kort i hukommelsen er autoritative under kørsel; mutationer skrives synkront til SQLite; tilstand gendannes fra DB ved koldstart
|
|
|
|
## 4) Auth + Sikkerhedsoverflader
|
|
|
|
- Dashboard-cookiegodkendelse: `src/proxy.ts`, `src/app/api/auth/login/route.ts`
|
|
- Generering/bekræftelse af API-nøgler: `src/shared/utils/apiKey.ts`
|
|
- Udbyderhemmeligheder bestod i `providerConnections` poster
|
|
- Udgående proxy-understøttelse via `open-sse/utils/proxyFetch.ts` (env vars) og `open-sse/utils/networkProxy.ts` (konfigurerbar pr. udbyder eller global)
|
|
|
|
## 5) Cloud Sync
|
|
|
|
- Planlægger init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`
|
|
- Periodisk opgave: `src/shared/services/cloudSyncScheduler.ts`
|
|
- Kontrolrute: `src/app/api/sync/cloud/route.ts`
|
|
|
|
## Anmod om livscyklus (`/v1/chat/completions`)
|
|
|
|
```mermaid
|
|
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
|
|
```
|
|
|
|
## Combo + Account Fallback Flow
|
|
|
|
```mermaid
|
|
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]
|
|
```
|
|
|
|
Fallback-beslutninger er drevet af `open-sse/services/accountFallback.ts` ved hjælp af statuskoder og fejlmeddelelsesheuristik.
|
|
|
|
## OAuth Onboarding og Token Refresh Lifecycle
|
|
|
|
```mermaid
|
|
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
|
|
```
|
|
|
|
Opdatering under live-trafik udføres inde i `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`.
|
|
|
|
## Cloud Sync Lifecycle (Aktiver / Synkroniser / Deaktiver)
|
|
|
|
```mermaid
|
|
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
|
|
```
|
|
|
|
Periodisk synkronisering udløses af `CloudSyncScheduler`, når skyen er aktiveret.
|
|
|
|
## Datamodel og lagerkort
|
|
|
|
```mermaid
|
|
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
|
|
}
|
|
```
|
|
|
|
Fysiske lagerfiler:
|
|
|
|
- hovedtilstand: `${DATA_DIR}/db.json` (eller `$XDG_CONFIG_HOME/omniroute/db.json` når indstillet, ellers `~/.omniroute/db.json`)
|
|
- brugsstatistik: `${DATA_DIR}/usage.json`
|
|
- anmod om log linjer: `${DATA_DIR}/log.txt`
|
|
- valgfri oversætter/anmodningsfejlfindingssessioner: `<repo>/logs/...`
|
|
|
|
## Implementeringstopologi
|
|
|
|
```mermaid
|
|
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[(db.json)]
|
|
UsageDB[(usage.json/log.txt)]
|
|
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
|
|
```
|
|
|
|
## Modulkortlægning (beslutningskritisk)
|
|
|
|
### Rute- og API-moduler
|
|
|
|
- `src/app/api/v1/*`, `src/app/api/v1beta/*`: kompatibilitets-API'er
|
|
- `src/app/api/v1/providers/[provider]/*`: dedikerede ruter pr. udbyder (chat, indlejringer, billeder)
|
|
- `src/app/api/providers*`: udbyder CRUD, validering, test
|
|
- `src/app/api/provider-nodes*`: brugerdefineret kompatibel nodestyring
|
|
- `src/app/api/provider-models`: brugerdefineret modelstyring (CRUD)
|
|
- `src/app/api/models/catalog`: komplet modelkatalog API (alle typer grupperet efter udbyder)
|
|
- `src/app/api/oauth/*`: OAuth/enhedskode-flows
|
|
- `src/app/api/keys*`: lokal API nøgle livscyklus
|
|
- `src/app/api/models/alias`: alias management
|
|
- `src/app/api/combos*`: fallback combo management
|
|
- `src/app/api/pricing`: pristilsidesættelser til omkostningsberegning
|
|
- `src/app/api/settings/proxy`: proxy-konfiguration (GET/PUT/DELETE)
|
|
- `src/app/api/settings/proxy/test`: test af udgående proxyforbindelse (POST)
|
|
- `src/app/api/usage/*`: brugs- og log-API'er
|
|
- `src/app/api/sync/*` + `src/app/api/cloud/*`: skysynkronisering og skyvendte hjælpere
|
|
- `src/app/api/cli-tools/*`: lokale CLI-konfigurationsskrivere/-brikker
|
|
- `src/app/api/settings/ip-filter`: IP-tilladelsesliste/blokeringsliste (GET/PUT)
|
|
- `src/app/api/settings/thinking-budget`: Tænkende token-budgetkonfiguration (GET/PUT)
|
|
- `src/app/api/settings/system-prompt`: global systemprompt (GET/PUT)
|
|
- `src/app/api/sessions`: aktiv sessionsfortegnelse (GET)
|
|
- `src/app/api/rate-limits`: satsgrænsestatus pr. konto (GET)
|
|
|
|
### Routing og udførelseskerne
|
|
|
|
- `src/sse/handlers/chat.ts`: anmodning om parse, kombinationshåndtering, kontovalgsløkke
|
|
- `open-sse/handlers/chatCore.ts`: oversættelse, eksekutorafsendelse, genforsøg/opdateringshåndtering, stream-opsætning
|
|
- `open-sse/executors/*`: udbyderspecifik netværks- og formatadfærd
|
|
|
|
### Oversættelsesregister og formatkonvertere
|
|
|
|
- `open-sse/translator/index.ts`: oversætterregister og orkestrering
|
|
- Anmod om oversættere: `open-sse/translator/request/*`
|
|
- Svaroversættere: `open-sse/translator/response/*`
|
|
- Formatkonstanter: `open-sse/translator/formats.ts`
|
|
|
|
### Vedholdenhed
|
|
|
|
- `src/lib/localDb.ts`: vedvarende konfiguration/tilstand
|
|
- `src/lib/usageDb.ts`: brugshistorik og rullende anmodningslogfiler
|
|
|
|
## Udbyder Eksekutør Dækning (Strategimønster)
|
|
|
|
Hver udbyder har en specialiseret udfører, der udvider `BaseExecutor` (i `open-sse/executors/base.ts`), som giver URL-opbygning, header-konstruktion, genforsøg med eksponentiel backoff, legitimationsopdateringshook og `execute()` orkestreringsmetoden.
|
|
|
|
| Eksekutør | Udbyder(e) | Særlig håndtering |
|
|
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
|
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fyrværkeri, Cerebras, Cohere, NVIDIA | Dynamisk URL/header-konfiguration pr. udbyder |
|
|
| `AntigravityExecutor` | Google Antigravity | Brugerdefinerede projekt-/sessions-id'er, forsøg igen - efter parsing |
|
|
| `CodexExecutor` | OpenAI Codex | Injicerer systeminstruktioner, fremtvinger ræsonnement indsats |
|
|
| `CursorExecutor` | Markør IDE | ConnectRPC-protokol, Protobuf-kodning, anmodningssignering via checksum |
|
|
| `GithubExecutor` | GitHub Copilot | Copilot token opdatering, VSCode-mimicing headers |
|
|
| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binært format → SSE-konvertering |
|
|
| `GeminiCLIExecutor` | Gemini CLI | Opdateringscyklus for Google OAuth-token |
|
|
|
|
Alle andre udbydere (inklusive brugerdefinerede kompatible noder) bruger `DefaultExecutor`.
|
|
|
|
## Udbyderkompatibilitetsmatrix
|
|
|
|
| Udbyder | Format | Auth | Stream | Ikke-stream | Token Opdater | Brug API |
|
|
| ---------------- | --------------- | --------------------- | ---------------- | ----------- | ------------- | -------------------- |
|
|
| Claude | claude | API-nøgle / OAuth | ✅ | ✅ | ✅ | ⚠️ Kun administrator |
|
|
| Tvillingerne | gemini | API-nøgle / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
|
|
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
|
|
| Antigravitation | antityngdekraft | OAuth | ✅ | ✅ | ✅ | ✅ Fuld kvote API |
|
|
| OpenAI | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| Codex | openai-svar | OAuth | ✅ tvunget | ❌ | ✅ | ✅ Satsgrænser |
|
|
| GitHub Copilot | åbne | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Kvote snapshots |
|
|
| Markør | markør | Tilpasset kontrolsum | ✅ | ✅ | ❌ | ❌ |
|
|
| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Brugsgrænser |
|
|
| Qwen | åbne | OAuth | ✅ | ✅ | ✅ | ⚠️ Efter anmodning |
|
|
| iFlow | åbne | OAuth (Grundlæggende) | ✅ | ✅ | ✅ | ⚠️ Efter anmodning |
|
|
| OpenRouter | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| GLM/Kimi/MiniMax | claude | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| DeepSeek | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| Groq | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| xAI (Grok) | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| Mistral | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| Forvirring | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| Sammen AI | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| Fyrværkeri AI | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| Cerebras | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| Sammenhæng | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
| NVIDIA NIM | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
|
|
|
## Format oversættelsesdækning
|
|
|
|
Detekterede kildeformater omfatter:
|
|
|
|
- `openai`
|
|
- `openai-responses`
|
|
- `claude`
|
|
- `gemini`
|
|
|
|
Målformater omfatter:
|
|
|
|
- OpenAI chat/svar
|
|
- Claude
|
|
- Gemini/Gemini-CLI/Antigravity kuvert
|
|
- Kiro
|
|
- Markør
|
|
|
|
Oversættelser bruger **OpenAI som hub-format** - alle konverteringer går gennem OpenAI som mellemliggende:
|
|
|
|
```
|
|
Source Format → OpenAI (hub) → Target Format
|
|
```
|
|
|
|
Oversættelser vælges dynamisk baseret på kildens nyttelastform og udbyderens målformat.
|
|
|
|
Yderligere behandlingslag i oversættelsespipelinen:
|
|
|
|
- **Responssanering** — Fjerner ikke-standardfelter fra OpenAI-formatsvar (både streaming og ikke-streaming) for at sikre streng SDK-overholdelse
|
|
- **Rollenormalisering** — Konverterer `developer` → `system` til ikke-OpenAI-mål; fusionerer `system` → `user` for modeller, der afviser systemrollen (GLM, ERNIE)
|
|
- **Tænk tag-udtrækning** — Parser `<think>...</think>` blokke fra indhold til feltet `reasoning_content`
|
|
- **Struktureret output** — Konverterer OpenAI `response_format.json_schema` til Gemini's `responseMimeType` + `responseSchema`
|
|
|
|
## Understøttede API-endepunkter
|
|
|
|
| Slutpunkt | Format | Behandler |
|
|
| -------------------------------------------------- | ------------------------- | ------------------------------------------------------------------ |
|
|
| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` |
|
|
| `POST /v1/messages` | Claude Beskeder | Samme handler (auto-detekteret) |
|
|
| `POST /v1/responses` | OpenAI-svar | `open-sse/handlers/responsesHandler.ts` |
|
|
| `POST /v1/embeddings` | OpenAI-indlejringer | `open-sse/handlers/embeddings.ts` |
|
|
| `GET /v1/embeddings` | Modelliste | API-rute |
|
|
| `POST /v1/images/generations` | OpenAI Billeder | `open-sse/handlers/imageGeneration.ts` |
|
|
| `GET /v1/images/generations` | Modelliste | API-rute |
|
|
| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Dedikeret per udbyder med modelvalidering |
|
|
| `POST /v1/providers/{provider}/embeddings` | OpenAI-indlejringer | Dedikeret per udbyder med modelvalidering |
|
|
| `POST /v1/providers/{provider}/images/generations` | OpenAI Billeder | Dedikeret per udbyder med modelvalidering |
|
|
| `POST /v1/messages/count_tokens` | Claude Token Count | API-rute |
|
|
| `GET /v1/models` | OpenAI Models liste | API-rute (chat + indlejring + billede + brugerdefinerede modeller) |
|
|
| `GET /api/models/catalog` | Katalog | Alle modeller grupperet efter udbyder + type |
|
|
| `POST /v1beta/models/*:streamGenerateContent` | Tvilling hjemmehørende | API-rute |
|
|
| `GET/PUT/DELETE /api/settings/proxy` | Proxy-konfiguration | Netværk proxy-konfiguration |
|
|
| `POST /api/settings/proxy/test` | Proxy-forbindelse | Proxy-sundheds-/forbindelsestestslutpunkt |
|
|
| `GET/POST/DELETE /api/provider-models` | Brugerdefinerede modeller | Brugerdefineret modelstyring pr. udbyder |
|
|
|
|
## Bypass Handler
|
|
|
|
Bypass-handleren (`open-sse/utils/bypassHandler.ts`) opsnapper kendte "smid-anmodninger" fra Claude CLI - opvarmningsping, titeludtræk og tokentællinger - og returnerer et **falsk svar** uden at forbruge upstream-udbydertokens. Dette udløses kun, når `User-Agent` indeholder `claude-cli`.
|
|
|
|
## Anmod om Logger Pipeline
|
|
|
|
Anmodningsloggeren (`open-sse/utils/requestLogger.ts`) giver en 7-trins debug-logningspipeline, deaktiveret som standard, aktiveret via `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
|
|
```
|
|
|
|
Filer skrives til `<repo>/logs/<session>/` for hver anmodningssession.
|
|
|
|
## Fejltilstande og modstandsdygtighed
|
|
|
|
## 1) Konto/udbyder tilgængelighed
|
|
|
|
- Nedkøling af udbyderkonto på forbigående/rate/godkendelsesfejl
|
|
- konto fallback før mislykket anmodning
|
|
- combo model fallback, når den nuværende model/udbydersti er udtømt
|
|
|
|
## 2) Tokens udløb
|
|
|
|
- Forhåndstjek og opdater med genforsøg for udbydere, der kan opdateres
|
|
- 401/403 forsøg igen efter opdateringsforsøg i kernestien
|
|
|
|
## 3) Strømsikkerhed
|
|
|
|
- afbrydelsesbevidst streamcontroller
|
|
- translationsstream med end-of-stream flush og `[DONE]` håndtering
|
|
- forbrugsestimeret fallback, når udbyderens brugsmetadata mangler
|
|
|
|
## 4) Cloud Sync-forringelse
|
|
|
|
- Synkroniseringsfejl dukker op, men lokal kørsel fortsætter
|
|
- Scheduler har logik, der kan genforsøge, men periodisk udførelse kalder i øjeblikket enkelt-forsøgssynkronisering som standard
|
|
|
|
## 5) Dataintegritet
|
|
|
|
- DB shape migration/reparation for manglende nøgler
|
|
- korrupte JSON-nulstillingsbeskyttelsesforanstaltninger for localDb og usageDb
|
|
|
|
## Observerbarhed og operationelle signaler
|
|
|
|
Kilder til synlighed ved kørsel:
|
|
|
|
- konsollogfiler fra `src/sse/utils/logger.ts`
|
|
- brugsaggregater pr. anmodning i `usage.json`
|
|
- log på status for tekstanmodning `log.txt`
|
|
- valgfri dybe anmodnings-/oversættelseslogfiler under `logs/` når `ENABLE_REQUEST_LOGS=true`
|
|
- dashboardbrugsendepunkter (`/api/usage/*`) for brugergrænsefladeforbrug
|
|
|
|
## Sikkerhedsfølsomme grænser
|
|
|
|
- JWT-hemmelighed (`JWT_SECRET`) sikrer bekræftelse/signering af dashboard-sessionscookie
|
|
- Indledende adgangskode fallback (`INITIAL_PASSWORD`, standard `123456`) skal tilsidesættes i rigtige implementeringer
|
|
- API-nøgle HMAC-hemmelighed (`API_KEY_SECRET`) sikrer genereret lokalt API-nøgleformat
|
|
- Udbyderhemmeligheder (API-nøgler/tokens) bevares i lokal DB og bør beskyttes på filsystemniveau
|
|
- Slutpunkter for skysynkronisering er afhængige af API-nøglegodkendelse + maskin-id-semantik
|
|
|
|
## Miljø og Runtime Matrix
|
|
|
|
Miljøvariabler aktivt brugt af kode:
|
|
|
|
- App/godkendelse: `JWT_SECRET`, `INITIAL_PASSWORD`
|
|
- Opbevaring: `DATA_DIR`
|
|
- Kompatibel nodeadfærd: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
|
|
- Valgfri lagerbasetilsidesættelse (Linux/macOS, når `DATA_DIR` ikke er indstillet): `XDG_CONFIG_HOME`
|
|
- Sikkerhedshashing: `API_KEY_SECRET`, `MACHINE_ID_SALT`
|
|
- Logning: `ENABLE_REQUEST_LOGS`
|
|
- Synkronisering/cloud URLing: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL`
|
|
- Udgående proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` og varianter med små bogstaver
|
|
- SOCKS5-funktionsflag: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
|
|
- Platform-/runtime-hjælpere (ikke app-specifik konfiguration): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME`
|
|
|
|
## Kendte arkitektoniske noter
|
|
|
|
1. `usageDb` og `localDb` deler nu den samme grundlæggende bibliotekspolitik (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) med ældre filmigrering.
|
|
2. `/api/v1/route.ts` returnerer en statisk modelliste og er ikke den primære modelkilde, der bruges af `/v1/models`.
|
|
3. Anmodningslogger skriver hele headers/body, når den er aktiveret; behandle logbiblioteket som følsomt.
|
|
4. Cloudadfærd afhænger af korrekt `NEXT_PUBLIC_BASE_URL` og cloud-endepunkters tilgængelighed.
|
|
5. `open-sse/` biblioteket udgives som `@omniroute/open-sse` **npm workspace-pakken**. Kildekoden importerer det via `@omniroute/open-sse/...` (løst af Next.js `transpilePackages`). Filstier i dette dokument bruger stadig mappenavnet `open-sse/` for at opnå konsistens.
|
|
6. Diagrammer i dashboardet bruger **Recharts** (SVG-baseret) til tilgængelige, interaktive analysevisualiseringer (søjlediagrammer for modelbrug, udbyderopdelingstabeller med succesrater).
|
|
7. E2E-tests bruger **Playwright** (`tests/e2e/`), køres via `npm run test:e2e`. Enhedstests bruger **Node.js testløber** (`tests/unit/`), køres via `npm run test:plan3`. Kildekoden under `src/` er **TypeScript** (`.ts`/`.tsx`); `open-sse/`-arbejdsområdet forbliver JavaScript (`.js`).
|
|
8. Siden Indstillinger er organiseret i 5 faner: Sikkerhed, Routing (6 globale strategier: fill-first, round-robin, p2c, random, mindst brugt, omkostningsoptimeret), Resiliens (redigerbare hastighedsgrænser, strømafbryder, politikker), AI (tænkebudget, systemprompt, promptcache), Avanceret (proxy).
|
|
|
|
## Tjekliste for operationel verifikation
|
|
|
|
- Byg fra kilde: `npm run build`
|
|
- Byg Docker-billede: `docker build -t omniroute .`
|
|
- Start service og bekræft:
|
|
- `GET /api/settings`
|
|
- `GET /api/v1/models`
|
|
- CLI-målbasis-URL skal være `http://<host>:20128/v1`, når `PORT=20128`
|