From 1647005d6edc0a3d8a1c8a3085b30b52253bb63d Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Thu, 26 Feb 2026 16:26:59 -0300 Subject: [PATCH] docs(i18n): add multilingual documentation translations Add translated documentation files for multiple languages including Korean, Polish, and others under docs/i18n/. Translations cover API reference, quickstart guides, and project documentation to improve accessibility for non-English speaking contributors. --- docs/i18n/ko/API_REFERENCE.md | 441 +++++++++++++ docs/i18n/ko/ARCHITECTURE.md | 781 +++++++++++++++++++++++ docs/i18n/ko/CODEBASE_DOCUMENTATION.md | 589 ++++++++++++++++++ docs/i18n/ko/FEATURES.md | 77 +++ docs/i18n/ko/TROUBLESHOOTING.md | 219 +++++++ docs/i18n/ko/USER_GUIDE.md | 698 +++++++++++++++++++++ docs/i18n/ms/API_REFERENCE.md | 441 +++++++++++++ docs/i18n/ms/ARCHITECTURE.md | 781 +++++++++++++++++++++++ docs/i18n/ms/CODEBASE_DOCUMENTATION.md | 589 ++++++++++++++++++ docs/i18n/ms/FEATURES.md | 77 +++ docs/i18n/ms/TROUBLESHOOTING.md | 219 +++++++ docs/i18n/ms/USER_GUIDE.md | 698 +++++++++++++++++++++ docs/i18n/nl/API_REFERENCE.md | 441 +++++++++++++ docs/i18n/nl/ARCHITECTURE.md | 781 +++++++++++++++++++++++ docs/i18n/nl/CODEBASE_DOCUMENTATION.md | 589 ++++++++++++++++++ docs/i18n/nl/FEATURES.md | 77 +++ docs/i18n/nl/TROUBLESHOOTING.md | 219 +++++++ docs/i18n/nl/USER_GUIDE.md | 698 +++++++++++++++++++++ docs/i18n/no/API_REFERENCE.md | 441 +++++++++++++ docs/i18n/no/ARCHITECTURE.md | 782 ++++++++++++++++++++++++ docs/i18n/no/CODEBASE_DOCUMENTATION.md | 589 ++++++++++++++++++ docs/i18n/no/FEATURES.md | 77 +++ docs/i18n/no/TROUBLESHOOTING.md | 219 +++++++ docs/i18n/no/USER_GUIDE.md | 698 +++++++++++++++++++++ docs/i18n/phi/API_REFERENCE.md | 441 +++++++++++++ docs/i18n/phi/ARCHITECTURE.md | 781 +++++++++++++++++++++++ docs/i18n/phi/CODEBASE_DOCUMENTATION.md | 589 ++++++++++++++++++ docs/i18n/phi/FEATURES.md | 77 +++ docs/i18n/phi/TROUBLESHOOTING.md | 219 +++++++ docs/i18n/phi/USER_GUIDE.md | 698 +++++++++++++++++++++ docs/i18n/pl/API_REFERENCE.md | 441 +++++++++++++ docs/i18n/pl/ARCHITECTURE.md | 781 +++++++++++++++++++++++ docs/i18n/pl/CODEBASE_DOCUMENTATION.md | 589 ++++++++++++++++++ docs/i18n/pl/FEATURES.md | 77 +++ docs/i18n/pl/TROUBLESHOOTING.md | 219 +++++++ docs/i18n/pl/USER_GUIDE.md | 698 +++++++++++++++++++++ 36 files changed, 16831 insertions(+) create mode 100644 docs/i18n/ko/API_REFERENCE.md create mode 100644 docs/i18n/ko/ARCHITECTURE.md create mode 100644 docs/i18n/ko/CODEBASE_DOCUMENTATION.md create mode 100644 docs/i18n/ko/FEATURES.md create mode 100644 docs/i18n/ko/TROUBLESHOOTING.md create mode 100644 docs/i18n/ko/USER_GUIDE.md create mode 100644 docs/i18n/ms/API_REFERENCE.md create mode 100644 docs/i18n/ms/ARCHITECTURE.md create mode 100644 docs/i18n/ms/CODEBASE_DOCUMENTATION.md create mode 100644 docs/i18n/ms/FEATURES.md create mode 100644 docs/i18n/ms/TROUBLESHOOTING.md create mode 100644 docs/i18n/ms/USER_GUIDE.md create mode 100644 docs/i18n/nl/API_REFERENCE.md create mode 100644 docs/i18n/nl/ARCHITECTURE.md create mode 100644 docs/i18n/nl/CODEBASE_DOCUMENTATION.md create mode 100644 docs/i18n/nl/FEATURES.md create mode 100644 docs/i18n/nl/TROUBLESHOOTING.md create mode 100644 docs/i18n/nl/USER_GUIDE.md create mode 100644 docs/i18n/no/API_REFERENCE.md create mode 100644 docs/i18n/no/ARCHITECTURE.md create mode 100644 docs/i18n/no/CODEBASE_DOCUMENTATION.md create mode 100644 docs/i18n/no/FEATURES.md create mode 100644 docs/i18n/no/TROUBLESHOOTING.md create mode 100644 docs/i18n/no/USER_GUIDE.md create mode 100644 docs/i18n/phi/API_REFERENCE.md create mode 100644 docs/i18n/phi/ARCHITECTURE.md create mode 100644 docs/i18n/phi/CODEBASE_DOCUMENTATION.md create mode 100644 docs/i18n/phi/FEATURES.md create mode 100644 docs/i18n/phi/TROUBLESHOOTING.md create mode 100644 docs/i18n/phi/USER_GUIDE.md create mode 100644 docs/i18n/pl/API_REFERENCE.md create mode 100644 docs/i18n/pl/ARCHITECTURE.md create mode 100644 docs/i18n/pl/CODEBASE_DOCUMENTATION.md create mode 100644 docs/i18n/pl/FEATURES.md create mode 100644 docs/i18n/pl/TROUBLESHOOTING.md create mode 100644 docs/i18n/pl/USER_GUIDE.md diff --git a/docs/i18n/ko/API_REFERENCE.md b/docs/i18n/ko/API_REFERENCE.md new file mode 100644 index 0000000000..9bde904c9b --- /dev/null +++ b/docs/i18n/ko/API_REFERENCE.md @@ -0,0 +1,441 @@ +# API 참조 + +🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md) + +모든 OmniRoute API 엔드포인트에 대한 전체 참조입니다. + +--- + +## 목차 + +- [Chat Completions](#chat-completions) +- [Embeddings](#embeddings) +- [Image Generation](#image-generation) +- [List Models](#list-models) +- [Compatibility Endpoints](#compatibility-endpoints) +- [Semantic Cache](#semantic-cache) +- [Dashboard & Management](#dashboard--management) +- [Request Processing](#request-processing) +- [Authentication](#authentication) + +--- + +## 채팅 완료 + +```bash +POST /v1/chat/completions +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "cc/claude-opus-4-6", + "messages": [ + {"role": "user", "content": "Write a function to..."} + ], + "stream": true +} +``` + +### 사용자 정의 헤더 + +| 헤더 | 방향 | 설명 | +| ------------------------ | ---- | ----------------------------------- | +| `X-OmniRoute-No-Cache` | 요청 | 캐시를 우회하려면 `true`로 설정 | +| `X-OmniRoute-Progress` | 요청 | 진행 이벤트의 경우 `true`으로 설정 | +| `Idempotency-Key` | 요청 | 중복 제거 키(5초 창) | +| `X-Request-Id` | 요청 | 대체 중복 제거 키 | +| `X-OmniRoute-Cache` | 응답 | `HIT` 또는 `MISS`(비스트리밍) | +| `X-OmniRoute-Idempotent` | 응답 | 중복이 제거된 경우 `true` | +| `X-OmniRoute-Progress` | 응답 | `enabled` 진행 상황을 추적하는 경우 | + +--- + +## 임베딩 + +```bash +POST /v1/embeddings +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "nebius/Qwen/Qwen3-Embedding-8B", + "input": "The food was delicious" +} +``` + +사용 가능한 공급자: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA. + +```bash +# List all embedding models +GET /v1/embeddings +``` + +--- + +## 이미지 생성 + +```bash +POST /v1/images/generations +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "openai/dall-e-3", + "prompt": "A beautiful sunset over mountains", + "size": "1024x1024" +} +``` + +사용 가능한 제공업체: OpenAI(DALL-E), xAI(Grok Image), Together AI(FLUX), Fireworks AI. + +```bash +# List all image models +GET /v1/images/generations +``` + +--- + +## 모델 목록 + +```bash +GET /v1/models +Authorization: Bearer your-api-key + +→ Returns all chat, embedding, and image models + combos in OpenAI format +``` + +--- + +## 호환성 끝점 + +| 방법 | 경로 | 형식 | +| ------ | --------------------------- | ----------------------- | +| 포스트 | `/v1/chat/completions` | 오픈AI | +| 포스트 | `/v1/messages` | 인류학 | +| 포스트 | `/v1/responses` | OpenAI 응답 | +| 포스트 | `/v1/embeddings` | 오픈AI | +| 포스트 | `/v1/images/generations` | 오픈AI | +| 받기 | `/v1/models` | 오픈AI | +| 포스트 | `/v1/messages/count_tokens` | 인류학 | +| 받기 | `/v1beta/models` | 쌍둥이자리 | +| 포스트 | `/v1beta/models/{...path}` | 쌍둥이 자리 생성 콘텐츠 | +| 포스트 | `/v1/api/chat` | 올라마 | + +### 전용 공급자 경로 + +```bash +POST /v1/providers/{provider}/chat/completions +POST /v1/providers/{provider}/embeddings +POST /v1/providers/{provider}/images/generations +``` + +공급자 접두사가 누락된 경우 자동으로 추가됩니다. 일치하지 않는 모델은 `400`을 반환합니다. + +--- + +## 시맨틱 캐시 + +```bash +# Get cache stats +GET /api/cache + +# Clear all caches +DELETE /api/cache +``` + +응답 예: + +```json +{ + "semanticCache": { + "memorySize": 42, + "memoryMaxSize": 500, + "dbSize": 128, + "hitRate": 0.65 + }, + "idempotency": { + "activeKeys": 3, + "windowMs": 5000 + } +} +``` + +--- + +## 대시보드 및 관리 + +### 인증 + +| 엔드포인트 | 방법 | 설명 | +| ----------------------------- | ------------- | ---------------- | +| `/api/auth/login` | 포스트 | 로그인 | +| `/api/auth/logout` | 포스트 | 로그아웃 | +| `/api/settings/require-login` | 가져오기/넣기 | 토글 로그인 필요 | + +### 공급자 관리 + +| 엔드포인트 | 방법 | 설명 | +| ---------------------------- | ------------------ | ------------------ | +| `/api/providers` | 받기/게시 | 공급자 목록/생성 | +| `/api/providers/[id]` | 가져오기/넣기/삭제 | 공급자 관리 | +| `/api/providers/[id]/test` | 포스트 | 테스트 공급자 연결 | +| `/api/providers/[id]/models` | 받기 | 공급자 모델 나열 | +| `/api/providers/validate` | 포스트 | 공급자 구성 확인 | +| `/api/provider-nodes*` | 다양한 | 공급자 노드 관리 | +| `/api/provider-models` | 가져오기/게시/삭제 | 맞춤형 모델 | + +### OAuth 흐름 + +| 엔드포인트 | 방법 | 설명 | +| -------------------------------- | ------ | -------------- | +| `/api/oauth/[provider]/[action]` | 다양한 | 공급자별 OAuth | + +### 라우팅 및 구성 + +| 엔드포인트 | 방법 | 설명 | +| --------------------- | --------- | ------------------------- | +| `/api/models/alias` | 받기/게시 | 모델 별칭 | +| `/api/models/catalog` | 받기 | 공급자 + 유형별 모든 모델 | +| `/api/combos*` | 다양한 | 콤보 관리 | +| `/api/keys*` | 다양한 | API 키 관리 | +| `/api/pricing` | 받기 | 모델 가격 | + +### 사용 및 분석 + +| 엔드포인트 | 방법 | 설명 | +| --------------------------- | ---- | -------------- | +| `/api/usage/history` | 받기 | 이용내역 | +| `/api/usage/logs` | 받기 | 사용 로그 | +| `/api/usage/request-logs` | 받기 | 요청 수준 로그 | +| `/api/usage/[connectionId]` | 받기 | 연결별 사용량 | + +### 설정 + +| 엔드포인트 | 방법 | 설명 | +| ------------------------------- | ------------- | ---------------------- | +| `/api/settings` | 가져오기/넣기 | 일반 설정 | +| `/api/settings/proxy` | 가져오기/넣기 | 네트워크 프록시 구성 | +| `/api/settings/proxy/test` | 포스트 | 프록시 연결 테스트 | +| `/api/settings/ip-filter` | 가져오기/넣기 | IP 허용 목록/차단 목록 | +| `/api/settings/thinking-budget` | 가져오기/넣기 | 토큰 예산 추론 | +| `/api/settings/system-prompt` | 가져오기/넣기 | 글로벌 시스템 프롬프트 | + +### 모니터링 + +| 엔드포인트 | 방법 | 설명 | +| ------------------------ | ------------- | ------------------ | +| `/api/sessions` | 받기 | 활성 세션 추적 | +| `/api/rate-limits` | 받기 | 계정당 비율 제한 | +| `/api/monitoring/health` | 받기 | 건강검진 | +| `/api/cache` | 가져오기/삭제 | 캐시 통계 / 지우기 | + +### 백업 및 내보내기/가져오기 + +| 엔드포인트 | 방법 | 설명 | +| --------------------------- | ------ | ----------------------------------------- | +| `/api/db-backups` | 받기 | 사용 가능한 백업 나열 | +| `/api/db-backups` | 넣어 | 수동 백업 생성 | +| `/api/db-backups` | 포스트 | 특정 백업에서 복원 | +| `/api/db-backups/export` | 받기 | 데이터베이스를 .sqlite 파일로 다운로드 | +| `/api/db-backups/import` | 포스트 | 데이터베이스를 대체할 .sqlite 파일 업로드 | +| `/api/db-backups/exportAll` | 받기 | 전체 백업을 .tar.gz 아카이브로 다운로드 | + +### 클라우드 동기화 + +| 엔드포인트 | 방법 | 설명 | +| ---------------------- | ------ | -------------------- | +| `/api/sync/cloud` | 다양한 | 클라우드 동기화 작업 | +| `/api/sync/initialize` | 포스트 | 동기화 초기화 | +| `/api/cloud/*` | 다양한 | 클라우드 관리 | + +### CLI 도구 + +| 엔드포인트 | 방법 | 설명 | +| ---------------------------------- | ---- | ----------------- | +| `/api/cli-tools/claude-settings` | 받기 | 클로드 CLI 상태 | +| `/api/cli-tools/codex-settings` | 받기 | 코덱스 CLI 상태 | +| `/api/cli-tools/droid-settings` | 받기 | 드로이드 CLI 상태 | +| `/api/cli-tools/openclaw-settings` | 받기 | OpenClaw CLI 상태 | +| `/api/cli-tools/runtime/[toolId]` | 받기 | 일반 CLI 런타임 | + +CLI 응답에는 `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`이 포함됩니다. + +### 복원력 및 속도 제한 + +| 엔드포인트 | 방법 | 설명 | +| ----------------------- | ------------- | ------------------------------- | +| `/api/resilience` | 가져오기/넣기 | 탄력성 프로필 가져오기/업데이트 | +| `/api/resilience/reset` | 포스트 | 회로 차단기 재설정 | +| `/api/rate-limits` | 받기 | 계정별 비율한도 현황 | +| `/api/rate-limit` | 받기 | 글로벌 비율 제한 구성 | + +### 평가 + +| 엔드포인트 | 방법 | 설명 | +| ------------ | --------- | -------------------------- | +| `/api/evals` | 받기/게시 | 평가 제품군 나열/평가 실행 | + +### 정책 + +| 엔드포인트 | 방법 | 설명 | +| --------------- | ------------------ | ---------------- | +| `/api/policies` | 가져오기/게시/삭제 | 라우팅 정책 관리 | + +### 규정 준수 + +| 엔드포인트 | 방법 | 설명 | +| --------------------------- | ---- | ----------------------------- | +| `/api/compliance/audit-log` | 받기 | 규정 준수 감사 로그(마지막 N) | + +### v1beta(Gemini 호환) + +| 엔드포인트 | 방법 | 설명 | +| -------------------------- | ------ | --------------------------------------- | +| `/v1beta/models` | 받기 | Gemini 형식으로 모델 나열 | +| `/v1beta/models/{...path}` | 포스트 | 쌍둥이자리 `generateContent` 엔드포인트 | + +이러한 엔드포인트는 기본 Gemini SDK 호환성을 기대하는 클라이언트를 위한 Gemini의 API 형식을 미러링합니다. + +### 내부/시스템 API + +| 엔드포인트 | 방법 | 설명 | +| --------------- | ------ | ----------------------------------------- | +| `/api/init` | 받기 | 애플리케이션 초기화 확인(첫 실행 시 사용) | +| `/api/tags` | 받기 | Ollama 호환 모델 태그(Ollama 고객용) | +| `/api/restart` | 포스트 | 정상적인 서버 다시 시작 트리거 | +| `/api/shutdown` | 포스트 | 정상적인 서버 종료 트리거 | + +> **참고:** 이러한 끝점은 시스템 내부적으로 또는 Ollama 클라이언트 호환성을 위해 사용됩니다. 일반적으로 최종 사용자는 호출하지 않습니다. + +--- + +## 오디오 전사 + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data +``` + +Deepgram 또는 AssemblyAI를 사용하여 오디오 파일을 녹음합니다. + +**요청:** + +```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" +``` + +**응답:** + +```json +{ + "text": "Hello, this is the transcribed audio content.", + "task": "transcribe", + "language": "en", + "duration": 12.5 +} +``` + +**지원되는 제공업체:** `deepgram/nova-3`, `assemblyai/best`. + +**지원되는 형식:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +## 올라마 호환성 + +Ollama의 API 형식을 사용하는 클라이언트의 경우: + +```bash +# Chat endpoint (Ollama format) +POST /v1/api/chat + +# Model listing (Ollama format) +GET /api/tags +``` + +요청은 Ollama와 내부 형식 간에 자동으로 번역됩니다. + +--- + +## 원격 측정 + +```bash +# Get latency telemetry summary (p50/p95/p99 per provider) +GET /api/telemetry/summary +``` + +**응답:** + +```json +{ + "providers": { + "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, + "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } + } +} +``` + +--- + +## 예산 + +```bash +# Get budget status for all API keys +GET /api/usage/budget + +# Set or update a budget +POST /api/usage/budget +Content-Type: application/json + +{ + "keyId": "key-123", + "limit": 50.00, + "period": "monthly" +} +``` + +--- + +## 모델 가용성 + +```bash +# Get real-time model availability across all providers +GET /api/models/availability + +# Check availability for a specific model +POST /api/models/availability +Content-Type: application/json + +{ + "model": "claude-sonnet-4-5-20250929" +} +``` + +--- + +## 요청 처리 + +1. 클라이언트는 `/v1/*`에 요청을 보냅니다. +2. 경로 핸들러 호출 `handleChat`, `handleEmbedding`, `handleAudioTranscription` 또는 `handleImageGeneration` +3. 모델이 해결되었습니다(직접 공급자/모델 또는 별칭/콤보). +4. 계정 가용성 필터링을 통해 로컬 DB에서 자격 증명을 선택합니다. +5. 채팅의 경우: `handleChatCore` — 형식 감지, 번역, 캐시 확인, 멱등성 확인 +6. 공급자 실행자가 업스트림 요청을 보냅니다. +7. 응답은 클라이언트 형식(채팅)으로 다시 변환되거나 있는 그대로 반환됩니다(임베딩/이미지/오디오). +8. 사용/로깅 기록 +9. 콤보 규칙에 따라 오류 발생 시 Fallback 적용 + +전체 아키텍처 참조: [**OMNI_TOKEN_119**](ARCHITECTURE.md) + +--- + +## 인증 + +- 대시보드 경로(`/dashboard/*`)는 `auth_token` 쿠키를 사용합니다. +- 로그인은 저장된 비밀번호 해시를 사용합니다. `INITIAL_PASSWORD`로 대체 +- `requireLogin`은 `/api/settings/require-login`을 통해 전환 가능 +- `/v1/*` 경로에는 `REQUIRE_API_KEY=true`인 경우 선택적으로 Bearer API 키가 필요합니다. diff --git a/docs/i18n/ko/ARCHITECTURE.md b/docs/i18n/ko/ARCHITECTURE.md new file mode 100644 index 0000000000..c8b2fffae9 --- /dev/null +++ b/docs/i18n/ko/ARCHITECTURE.md @@ -0,0 +1,781 @@ +# 옴니루트 아키텍처 + +🌐 **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) + +_최종 업데이트 날짜: 2026-02-18_ + +## 요약 + +OmniRoute는 Next.js를 기반으로 구축된 로컬 AI 라우팅 게이트웨이이자 대시보드입니다. +단일 OpenAI 호환 엔드포인트(`/v1/*`)를 제공하고 변환, 대체, 토큰 새로 고침 및 사용 추적을 통해 여러 업스트림 공급자 간에 트래픽을 라우팅합니다. + +핵심 기능: + +- CLI/도구용 OpenAI 호환 API 표면(28개 공급자) +- 공급자 형식에 따른 요청/응답 번역 +- 모델 콤보 대체(다중 모델 시퀀스) +- 계정 수준 대체(제공업체당 다중 계정) +- OAuth + API 키 공급자 연결 관리 +- `/v1/embeddings`을 통한 임베딩 생성(6개 공급자, 9개 모델) +- `/v1/images/generations`을 통한 이미지 생성(4개 공급자, 9개 모델) +- 추론 모델을 위한 Think 태그 구문 분석(`...`) +- 엄격한 OpenAI SDK 호환성을 위한 응답 삭제 +- 제공자 간 호환성을 위한 역할 정규화(개발자→시스템, 시스템→사용자) +- 구조화된 출력 변환(json_schema → Gemini responseSchema) +- 공급자, 키, 별칭, 콤보, 설정, 가격에 대한 로컬 지속성 +- 사용량/비용 추적 및 요청 로깅 +- 다중 장치/상태 동기화를 위한 선택적 클라우드 동기화 +- API 접근 제어를 위한 IP 허용 목록/차단 목록 +- 생각하는 예산 관리(패스스루/자동/커스텀/적응형) +- 글로벌 시스템 신속한 주입 +- 세션 추적 및 지문 채취 +- 제공자별 프로필을 통해 계정당 강화된 속도 제한 +- 공급자 탄력성을 위한 회로 차단기 패턴 +- 뮤텍스 잠금을 통한 천둥 방지 무리 보호 +- 서명 기반 요청 중복 제거 캐시 +- 도메인 레이어: 모델 가용성, 비용 규칙, 대체 정책, 잠금 정책 +- 도메인 상태 지속성(폴백, 예산, 잠금, 회로 차단기를 위한 SQLite 연속 쓰기 캐시) +- 중앙화된 요청 평가를 위한 정책 엔진(잠금 → 예산 → 대체) +- p50/p95/p99 대기 시간 집계를 통한 원격 측정 요청 +- 종단 간 추적을 위한 상관 ID(X-Request-Id) +- API 키별로 옵트아웃이 가능한 규정 준수 감사 로깅 +- LLM 품질 보증을 위한 평가 프레임워크 +- 실시간 회로 차단기 상태가 포함된 탄력성 UI 대시보드 +- 모듈식 OAuth 제공자(`src/lib/oauth/providers/` 아래의 개별 모듈 12개) + +기본 런타임 모델: + +- `src/app/api/*` 아래의 Next.js 앱 경로는 대시보드 API와 호환성 API를 모두 구현합니다. +- `src/sse/*` + `open-sse/*`의 공유 SSE/라우팅 코어는 공급자 실행, 변환, 스트리밍, 대체 및 사용을 처리합니다. + +## 범위 및 경계 + +### 범위 내 + +- 로컬 게이트웨이 런타임 +- 대시보드 관리 API +- 공급자 인증 및 토큰 새로 고침 +- 번역 및 SSE 스트리밍 요청 +- 로컬 상태 + 사용 지속성 +- 선택적인 클라우드 동기화 조정 + +### 범위를 벗어남 + +- `NEXT_PUBLIC_CLOUD_URL` 기반의 클라우드 서비스 구현 +- 로컬 프로세스 외부의 공급자 SLA/제어 평면 +- 외부 CLI 바이너리 자체(Claude CLI, Codex CLI 등) + +## 상위 수준 시스템 컨텍스트 + +```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 +``` + +## 핵심 런타임 구성 요소 + +## 1) API 및 라우팅 계층(Next.js 앱 경로) + +주요 디렉토리: + +- 호환성 API의 경우 `src/app/api/v1/*` 및 `src/app/api/v1beta/*` +- 관리/구성 API용 `src/app/api/*` +- 다음은 `next.config.mjs`에서 `/v1/*`을 `/api/v1/*`로 매핑하여 다시 작성합니다. + +중요한 호환성 경로: + +- `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` — `custom: true`이 있는 사용자 정의 모델을 포함합니다. +- `src/app/api/v1/embeddings/route.ts` — 임베딩 생성(6개 제공자) +- `src/app/api/v1/images/generations/route.ts` — 이미지 생성(Antigravity/Nebius를 포함한 4개 이상의 공급자) +- `src/app/api/v1/messages/count_tokens/route.ts` +- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — 제공업체별 전용 채팅 +- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — 제공자별 전용 임베딩 +- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — 제공업체별 전용 이미지 +- `src/app/api/v1beta/models/route.ts` +- `src/app/api/v1beta/models/[...path]/route.ts` + +관리 도메인: + +- 인증/설정: `src/app/api/auth/*`, `src/app/api/settings/*` +- 공급자/연결: `src/app/api/providers*` +- 제공자 노드: `src/app/api/provider-nodes*` +- 사용자 정의 모델: `src/app/api/provider-models` (GET/POST/DELETE) +- 모델 카탈로그: `src/app/api/models/catalog` (GET) +- 프록시 구성: `src/app/api/settings/proxy`(GET/PUT/DELETE) + `src/app/api/settings/proxy/test`(POST) +- OAuth: `src/app/api/oauth/*` +- 키/별칭/콤보/가격: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing` +- 사용량: `src/app/api/usage/*` +- 동기화/클라우드: `src/app/api/sync/*`, `src/app/api/cloud/*` +- CLI 도구 도우미: `src/app/api/cli-tools/*` +- IP 필터: `src/app/api/settings/ip-filter` (GET/PUT) +- 생각하는 예산: `src/app/api/settings/thinking-budget` (GET/PUT) +- 시스템 프롬프트: `src/app/api/settings/system-prompt` (GET/PUT) +- 세션: `src/app/api/sessions`(GET) +- 비율 제한: `src/app/api/rate-limits` (GET) +- 복원력: `src/app/api/resilience` (GET/PATCH) — 공급자 프로필, 회로 차단기, 속도 제한 상태 +- 복원력 재설정: `src/app/api/resilience/reset` (POST) — 차단기 재설정 + 재사용 대기시간 +- 캐시 통계: `src/app/api/cache/stats` (GET/DELETE) +- 모델 가용성: `src/app/api/models/availability` (GET/POST) +- 원격 측정: `src/app/api/telemetry/summary` (GET) +- 예산: `src/app/api/usage/budget` (GET/POST) +- 대체 체인: `src/app/api/fallback/chains` (GET/POST/DELETE) +- 규정 준수 감사: `src/app/api/compliance/audit-log` (GET) +- 평가: `src/app/api/evals`(GET/POST), `src/app/api/evals/[suiteId]`(GET) +- 정책: `src/app/api/policies`(GET/POST) + +## 2) SSE + 번역 코어 + +주요 흐름 모듈: + +- 항목: `src/sse/handlers/chat.ts` +- 핵심 오케스트레이션: `open-sse/handlers/chatCore.ts` +- 공급자 실행 어댑터: `open-sse/executors/*` +- 형식 감지/공급자 구성: `open-sse/services/provider.ts` +- 모델 구문 분석/해결: `src/sse/services/model.ts`, `open-sse/services/model.ts` +- 계정 대체 논리: `open-sse/services/accountFallback.ts` +- 번역 레지스트리: `open-sse/translator/index.ts` +- 스트림 변환: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts` +- 사용량 추출/정규화: `open-sse/utils/usageTracking.ts` +- 태그 파서 생각: `open-sse/utils/thinkTagParser.ts` +- 임베딩 핸들러: `open-sse/handlers/embeddings.ts` +- 임베딩 제공자 레지스트리: `open-sse/config/embeddingRegistry.ts` +- 이미지 생성 핸들러: `open-sse/handlers/imageGeneration.ts` +- 이미지 제공자 레지스트리: `open-sse/config/imageRegistry.ts` +- 응답 정리: `open-sse/handlers/responseSanitizer.ts` +- 역할 정규화: `open-sse/services/roleNormalizer.ts` + +서비스(비즈니스 로직): + +- 계정 선택/점수: `open-sse/services/accountSelector.ts` +- 컨텍스트 수명주기 관리: `open-sse/services/contextManager.ts` +- IP 필터 시행: `open-sse/services/ipFilter.ts` +- 세션 추적: `open-sse/services/sessionManager.ts` +- 중복 제거 요청: `open-sse/services/signatureCache.ts` +- 시스템 프롬프트 주입: `open-sse/services/systemPrompt.ts` +- 생각하는 예산 관리: `open-sse/services/thinkingBudget.ts` +- 와일드카드 모델 라우팅: `open-sse/services/wildcardRouter.ts` +- 비율 제한 관리: `open-sse/services/rateLimitManager.ts` +- 회로 차단기: `open-sse/services/circuitBreaker.ts` + +도메인 레이어 모듈: + +- 모델 가용성: `src/lib/domain/modelAvailability.ts` +- 비용 규칙/예산: `src/lib/domain/costRules.ts` +- 대체 정책: `src/lib/domain/fallbackPolicy.ts` +- 콤보 리졸버: `src/lib/domain/comboResolver.ts` +- 잠금 정책: `src/lib/domain/lockoutPolicy.ts` +- 정책 엔진: `src/domain/policyEngine.ts` — 중앙 집중식 잠금 → 예산 → 대체 평가 +- 오류 코드 카탈로그: `src/lib/domain/errorCodes.ts` +- 요청 ID: `src/lib/domain/requestId.ts` +- 가져오기 시간 초과: `src/lib/domain/fetchTimeout.ts` +- 원격 측정 요청: `src/lib/domain/requestTelemetry.ts` +- 규정 준수/감사: `src/lib/domain/compliance/index.ts` +- 평가 실행자: `src/lib/domain/evalRunner.ts` +- 도메인 상태 지속성: `src/lib/db/domainState.ts` — 대체 체인, 예산, 비용 기록, 잠금 상태, 회로 차단기를 위한 SQLite CRUD + +OAuth 제공자 모듈(`src/lib/oauth/providers/` 아래의 개별 파일 12개): + +- 레지스트리 색인: `src/lib/oauth/providers/index.ts` +- 개인 공급자: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts` +- 씬 래퍼: `src/lib/oauth/providers.ts` — 개별 모듈에서 다시 내보내기 + +## 3) 지속성 레이어 + +기본 상태 DB: + +- `src/lib/localDb.ts` +- 파일: `${DATA_DIR}/db.json`(또는 설정된 경우 `$XDG_CONFIG_HOME/omniroute/db.json`, 그렇지 않으면 `~/.omniroute/db.json`) +- 엔터티: 공급자 연결, 공급자 노드, modelAliases, 콤보, apiKeys, 설정, 가격 책정, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt** + +사용량 DB: + +- `src/lib/usageDb.ts` +- 파일: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- `localDb`(`DATA_DIR`, 설정된 경우 `XDG_CONFIG_HOME/omniroute`)과 동일한 기본 디렉터리 정책을 따릅니다. +- 집중된 하위 모듈로 분해: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts` + +도메인 상태 DB(SQLite): + +- `src/lib/db/domainState.ts` — 도메인 상태에 대한 CRUD 작업 +- 테이블(`src/lib/db/core.ts`에서 생성됨): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers` +- 연속 쓰기 캐시 패턴: 메모리 내 맵은 런타임 시 권한을 갖습니다. 변이는 SQLite에 동기적으로 기록됩니다. 콜드 스타트 시 DB에서 상태가 복원됩니다. + +## 4) 인증 + 보안 표면 + +- 대시보드 쿠키 인증: `src/proxy.ts`, `src/app/api/auth/login/route.ts` +- API 키 생성/검증: `src/shared/utils/apiKey.ts` +- `providerConnections` 항목에 유지되는 공급자 비밀 +- `open-sse/utils/proxyFetch.ts`(env vars) 및 `open-sse/utils/networkProxy.ts`(공급자별 또는 전역 구성 가능)을 통한 아웃바운드 프록시 지원 + +## 5) 클라우드 동기화 + +- 스케줄러 초기화: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts` +- 정기 작업: `src/shared/services/cloudSyncScheduler.ts` +- 제어 경로: `src/app/api/sync/cloud/route.ts` + +## 요청 수명 주기(`/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 +``` + +## 콤보 + 계정 대체 흐름 + +```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] +``` + +대체 결정은 상태 코드와 오류 메시지 휴리스틱을 사용하는 `open-sse/services/accountFallback.ts`에 의해 이루어집니다. + +## OAuth 온보딩 및 토큰 새로 고침 수명 주기 + +```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 +``` + +실시간 트래픽 중 새로 고침은 실행기 `refreshCredentials()`을 통해 `open-sse/handlers/chatCore.ts` 내에서 실행됩니다. + +## 클라우드 동기화 수명 주기(활성화/동기화/비활성화) + +```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 +``` + +클라우드가 활성화되면 `CloudSyncScheduler`에 의해 주기적 동기화가 트리거됩니다. + +## 데이터 모델 및 스토리지 맵 + +```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 + } +``` + +물리적 저장 파일: + +- 기본 상태: `${DATA_DIR}/db.json`(또는 설정된 경우 `$XDG_CONFIG_HOME/omniroute/db.json`, 그렇지 않으면 `~/.omniroute/db.json`) +- 사용 통계: `${DATA_DIR}/usage.json` +- 요청 로그 라인: `${DATA_DIR}/log.txt` +- 선택적 변환기/요청 디버그 세션: `/logs/...` + +## 배포 토폴로지 + +```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 +``` + +## 모듈 매핑(결정에 중요) + +### 경로 및 API 모듈 + +- `src/app/api/v1/*`, `src/app/api/v1beta/*`: 호환성 API +- `src/app/api/v1/providers/[provider]/*`: 공급자별 전용 경로(채팅, 임베딩, 이미지) +- `src/app/api/providers*`: 공급자 CRUD, 유효성 검사, 테스트 +- `src/app/api/provider-nodes*`: 맞춤형 호환 노드 관리 +- `src/app/api/provider-models`: 사용자 정의 모델 관리(CRUD) +- `src/app/api/models/catalog`: 전체 모델 카탈로그 API(모든 유형이 공급자별로 그룹화됨) +- `src/app/api/oauth/*`: OAuth/장치 코드 흐름 +- `src/app/api/keys*`: 로컬 API 키 수명 주기 +- `src/app/api/models/alias`: 별칭 관리 +- `src/app/api/combos*`: 대체 콤보 관리 +- `src/app/api/pricing`: 비용 계산을 위한 가격 재정의 +- `src/app/api/settings/proxy`: 프록시 구성(GET/PUT/DELETE) +- `src/app/api/settings/proxy/test`: 아웃바운드 프록시 연결 테스트(POST) +- `src/app/api/usage/*`: 사용량 및 로그 API +- `src/app/api/sync/*` + `src/app/api/cloud/*`: 클라우드 동기화 및 클라우드 연결 도우미 +- `src/app/api/cli-tools/*`: 로컬 CLI 구성 작성자/검사기 +- `src/app/api/settings/ip-filter`: IP 허용 목록/차단 목록(GET/PUT) +- `src/app/api/settings/thinking-budget`: 생각하는 토큰 예산 구성(GET/PUT) +- `src/app/api/settings/system-prompt`: 전역 시스템 프롬프트(GET/PUT) +- `src/app/api/sessions`: 활성 세션 목록(GET) +- `src/app/api/rate-limits`: 계정별 비율 제한 상태(GET) + +### 라우팅 및 실행 코어 + +- `src/sse/handlers/chat.ts`: 요청 구문 분석, 콤보 처리, 계정 선택 루프 +- `open-sse/handlers/chatCore.ts`: 변환, 실행기 디스패치, 재시도/새로 고침 처리, 스트림 설정 +- `open-sse/executors/*`: 공급자별 네트워크 및 형식 동작 + +### 번역 레지스트리 및 형식 변환기 + +- `open-sse/translator/index.ts`: 번역자 레지스트리 및 오케스트레이션 +- 번역자 요청: `open-sse/translator/request/*` +- 응답 번역자: `open-sse/translator/response/*` +- 형식 상수: `open-sse/translator/formats.ts` + +### 지속성 + +- `src/lib/localDb.ts`: 영구 구성/상태 +- `src/lib/usageDb.ts`: 사용 내역 및 롤링 요청 로그 + +## 제공자 실행자 적용 범위(전략 패턴) + +각 공급자에는 URL 구축, 헤더 구성, 지수 백오프를 사용한 재시도, 자격 증명 새로 고침 후크 및 `execute()` 오케스트레이션 방법을 제공하는 `BaseExecutor`(`open-sse/executors/base.ts`)을 확장하는 특수 실행기가 있습니다. + +| 집행자 | 공급자 | 특수취급 | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------- | +| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | 공급자별 동적 URL/헤더 구성 | +| `AntigravityExecutor` | 구글 반중력 | 사용자 정의 프로젝트/세션 ID, 구문 분석 후 재시도 | +| `CodexExecutor` | OpenAI 코덱스 | 시스템 지침을 주입하고 추론 노력을 강요 | +| `CursorExecutor` | 커서 IDE | ConnectRPC 프로토콜, Protobuf 인코딩, 체크섬을 통한 서명 요청 | +| `GithubExecutor` | GitHub 부조종사 | Copilot 토큰 새로 고침, VSCode 모방 헤더 | +| `KiroExecutor` | AWS 코드위스퍼러/키로 | AWS EventStream 바이너리 형식 → SSE 변환 | +| `GeminiCLIExecutor` | 제미니 CLI | Google OAuth 토큰 새로고침 주기 | + +다른 모든 공급자(사용자 정의 호환 노드 포함)는 `DefaultExecutor`을 사용합니다. + +## 공급자 호환성 매트릭스 + +| 공급자 | 형식 | 인증 | 스트림 | 비스트림 | 토큰 새로고침 | 사용 API | +| ----------------- | -------------- | -------------------- | ----------------- | -------- | ------------- | ------------------ | +| 클로드 | 클로드 | API 키/OAuth | ✅ | ✅ | ✅ | ⚠️ 관리자 전용 | +| 쌍둥이자리 | 쌍둥이자리 | API 키/OAuth | ✅ | ✅ | ✅ | ⚠️ 클라우드 콘솔 | +| 제미니 CLI | 쌍둥이자리 CLI | OAuth | ✅ | ✅ | ✅ | ⚠️ 클라우드 콘솔 | +| 반중력 | 반중력 | OAuth | ✅ | ✅ | ✅ | ✅ 전체 할당량 API | +| 오픈AI | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 코덱스 | openai-응답 | OAuth | ✅ 강제 | ❌ | ✅ | ✅ 비율 제한 | +| GitHub 부조종사 | 공개 | OAuth + Copilot 토큰 | ✅ | ✅ | ✅ | ✅ 할당량 스냅샷 | +| 커서 | 커서 | 사용자 정의 체크섬 | ✅ | ✅ | ❌ | ❌ | +| 키로 | 키로 | AWS SSO OIDC | ✅ (이벤트스트림) | ❌ | ✅ | ✅ 사용 제한 | +| 퀀 | 공개 | OAuth | ✅ | ✅ | ✅ | ⚠️ 요청에 따라 | +| 아이플로우 | 공개 | OAuth(기본) | ✅ | ✅ | ✅ | ⚠️ 요청에 따라 | +| 오픈라우터 | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| GLM/키미/미니맥스 | 클로드 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 딥시크 | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 그로크 | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| xAI(그록) | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 미스트랄 | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 당혹감 | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 함께하는 AI | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 불꽃놀이 AI | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 대뇌 | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 코히어 | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | +| 엔비디아 NIM | 공개 | API 키 | ✅ | ✅ | ❌ | ❌ | + +## 형식 번역 범위 + +감지된 소스 형식은 다음과 같습니다. + +- `openai` +- `openai-responses` +- `claude` +- `gemini` + +대상 형식은 다음과 같습니다. + +- OpenAI 채팅/응답 +- 클로드 +- Gemini/Gemini-CLI/반중력 봉투 +- 키로 +- 커서 + +번역에서는 **OpenAI를 허브 형식**으로 사용합니다. 모든 변환은 중간 형식으로 OpenAI를 거칩니다. + +``` +Source Format → OpenAI (hub) → Target Format +``` + +번역은 소스 페이로드 형태와 공급자 대상 형식에 따라 동적으로 선택됩니다. + +번역 파이프라인의 추가 처리 계층: + +- **응답 삭제** — OpenAI 형식 응답(스트리밍 및 비스트리밍 모두)에서 비표준 필드를 제거하여 엄격한 SDK 규정 준수를 보장합니다. +- **역할 정규화** — OpenAI가 아닌 대상에 대해 `developer` → `system`을 변환합니다. 시스템 역할(GLM, ERNIE)을 거부하는 모델에 대해 `system` → `user`을 병합합니다. +- **태그 추출 생각** — 콘텐츠의 `...` 블록을 `reasoning_content` 필드로 구문 분석합니다. +- **구조화된 출력** — OpenAI `response_format.json_schema`을 Gemini의 `responseMimeType` + `responseSchema`로 변환합니다. + +## 지원되는 API 엔드포인트 + +| 엔드포인트 | 형식 | 핸들러 | +| -------------------------------------------------- | ------------------ | --------------------------------------------------- | +| `POST /v1/chat/completions` | OpenAI 채팅 | `src/sse/handlers/chat.ts` | +| `POST /v1/messages` | 클로드 메시지 | 동일한 핸들러(자동 감지) | +| `POST /v1/responses` | OpenAI 응답 | `open-sse/handlers/responsesHandler.ts` | +| `POST /v1/embeddings` | OpenAI 임베딩 | `open-sse/handlers/embeddings.ts` | +| `GET /v1/embeddings` | 모델 목록 | API 경로 | +| `POST /v1/images/generations` | OpenAI 이미지 | `open-sse/handlers/imageGeneration.ts` | +| `GET /v1/images/generations` | 모델 목록 | API 경로 | +| `POST /v1/providers/{provider}/chat/completions` | OpenAI 채팅 | 모델 검증을 통한 제공자별 전용 | +| `POST /v1/providers/{provider}/embeddings` | OpenAI 임베딩 | 모델 검증을 통한 제공자별 전용 | +| `POST /v1/providers/{provider}/images/generations` | OpenAI 이미지 | 모델 검증을 통한 제공자별 전용 | +| `POST /v1/messages/count_tokens` | 클로드 토큰 개수 | API 경로 | +| `GET /v1/models` | OpenAI 모델 목록 | API 경로(채팅 + 임베딩 + 이미지 + 사용자 정의 모델) | +| `GET /api/models/catalog` | 카탈로그 | 공급자 + 유형별로 그룹화된 모든 모델 | +| `POST /v1beta/models/*:streamGenerateContent` | 쌍둥이 자리 원주민 | API 경로 | +| `GET/PUT/DELETE /api/settings/proxy` | 프록시 구성 | 네트워크 프록시 구성 | +| `POST /api/settings/proxy/test` | 프록시 연결 | 프록시 상태/연결 테스트 엔드포인트 | +| `GET/POST/DELETE /api/provider-models` | 맞춤형 모델 | 제공자별 맞춤형 모델 관리 | + +## 우회 핸들러 + +우회 처리기(`open-sse/utils/bypassHandler.ts`)는 Claude CLI의 알려진 "일시적" 요청(예열 핑, 타이틀 추출 및 토큰 계산)을 가로채고 업스트림 공급자 토큰을 사용하지 않고 **가짜 응답**을 반환합니다. 이는 `User-Agent`에 `claude-cli`이 포함된 경우에만 트리거됩니다. + +## 요청 로거 파이프라인 + +요청 로거(`open-sse/utils/requestLogger.ts`)는 기본적으로 비활성화되고 `ENABLE_REQUEST_LOGS=true`을 통해 활성화되는 7단계 디버그 로깅 파이프라인을 제공합니다. + +``` +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 +``` + +각 요청 세션마다 파일이 `/logs//`에 기록됩니다. + +## 실패 모드 및 복원력 + +## 1) 계정/공급업체 가용성 + +- 일시적/속도/인증 오류에 대한 공급자 계정 쿨다운 +- 요청 실패 전 계정 대체 +- 현재 모델/공급자 경로가 소진되면 콤보 모델 대체 + +## 2) 토큰 만료 + +- 새로 고칠 수 있는 공급자에 대한 사전 확인 및 재시도를 통한 새로 고침 +- 코어 경로에서 새로 고침 시도 후 401/403 재시도 + +## 3) 스트림 안전 + +- 연결 해제 인식 스트림 컨트롤러 +- 스트림 끝 플러시 및 `[DONE]` 처리가 포함된 번역 스트림 +- 공급자 사용량 메타데이터가 누락된 경우 사용량 추정 대체 + +## 4) 클라우드 동기화 성능 저하 + +- 동기화 오류가 표시되지만 로컬 런타임은 계속됩니다. +- 스케줄러에는 재시도 가능 논리가 있지만 주기적인 실행은 현재 기본적으로 단일 시도 동기화를 호출합니다. + +## 5) 데이터 무결성 + +- 누락된 키에 대한 DB 형상 마이그레이션/수정 +- localDb 및 UsageDb에 대한 손상된 JSON 재설정 보호 장치 + +## 관찰 가능성 및 작동 신호 + +런타임 가시성 소스: + +- `src/sse/utils/logger.ts`의 콘솔 로그 +- `usage.json`의 요청별 사용량 집계 +- `log.txt`의 텍스트 요청 상태 로그 +- `ENABLE_REQUEST_LOGS=true`인 경우 `logs/` 아래의 선택적 심층 요청/번역 로그 +- UI 소비를 위한 대시보드 사용 끝점(`/api/usage/*`) + +## 보안에 민감한 경계 + +- JWT 비밀(`JWT_SECRET`)은 대시보드 세션 쿠키 확인/서명을 보호합니다. +- 실제 배포에서는 초기 비밀번호 대체(`INITIAL_PASSWORD`, 기본값 `123456`)를 재정의해야 합니다. +- API 키 HMAC 비밀(`API_KEY_SECRET`)은 생성된 로컬 API 키 형식을 보호합니다. +- 공급자 비밀(API 키/토큰)은 로컬 DB에 유지되며 파일 시스템 수준에서 보호되어야 합니다. +- 클라우드 동기화 엔드포인트는 API 키 인증 + 머신 ID 의미 체계를 사용합니다. + +## 환경 및 런타임 매트릭스 + +코드에서 적극적으로 사용되는 환경 변수: + +- 앱/인증: `JWT_SECRET`, `INITIAL_PASSWORD` +- 저장공간: `DATA_DIR` +- 호환 노드 동작: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` +- 선택적 저장소 기반 재정의(`DATA_DIR`이 설정되지 않은 경우 Linux/macOS): `XDG_CONFIG_HOME` +- 보안 해싱: `API_KEY_SECRET`, `MACHINE_ID_SALT` +- 로깅: `ENABLE_REQUEST_LOGS` +- 동기화/클라우드 URL링: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL` +- 아웃바운드 프록시: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` 및 소문자 변형 +- SOCKS5 기능 플래그: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` +- 플랫폼/런타임 도우미(앱별 구성 아님): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME` + +## 알려진 아키텍처 노트 + +1. `usageDb` 및 `localDb`은 이제 레거시 파일 마이그레이션과 동일한 기본 디렉터리 정책(`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`)을 공유합니다. +2. `/api/v1/route.ts`은 정적 모델 목록을 반환하며 `/v1/models`에서 사용하는 기본 모델 소스가 아닙니다. +3. 요청 로거가 활성화되면 전체 헤더/본문을 씁니다. 로그 디렉토리를 중요하게 취급하십시오. +4. 클라우드 동작은 올바른 `NEXT_PUBLIC_BASE_URL` 및 클라우드 엔드포인트 연결 가능성에 따라 달라집니다. +5. `open-sse/` 디렉터리는 `@omniroute/open-sse` **npm 작업 공간 패키지**로 게시됩니다. 소스 코드는 `@omniroute/open-sse/...`을 통해 이를 가져옵니다(Next.js `transpilePackages`으로 해결됨). 이 문서의 파일 경로는 일관성을 위해 여전히 디렉터리 이름 `open-sse/`을 사용합니다. +6. 대시보드의 차트는 액세스 가능한 대화형 분석 시각화(모델 사용량 막대 차트, 성공률이 포함된 공급자 분석 테이블)를 위해 **Recharts**(SVG 기반)를 사용합니다. +7. E2E 테스트는 **Playwright**(`tests/e2e/`)를 사용하고 `npm run test:e2e`을 통해 실행됩니다. 단위 테스트는 **Node.js 테스트 실행기**(`tests/unit/`)를 사용하고 `npm run test:plan3`을 통해 실행됩니다. `src/` 아래의 소스 코드는 **TypeScript**(`.ts`/`.tsx`)입니다. `open-sse/` 작업 공간은 JavaScript(`.js`)로 유지됩니다. +8. 설정 페이지는 보안, 라우팅(6개의 전역 전략: 채우기 우선, 라운드 로빈, p2c, 무작위, 최소 사용, 비용 최적화), 탄력성(편집 가능한 속도 제한, 회로 차단기, 정책), AI(생각 예산, 시스템 프롬프트, 프롬프트 캐시), 고급(프록시)의 5개 탭으로 구성됩니다. + +## 작동 검증 체크리스트 + +- 소스에서 빌드: `npm run build` +- Docker 이미지 빌드: `docker build -t omniroute .` +- 서비스 시작 및 확인: +- `GET /api/settings` +- `GET /api/v1/models` +- `PORT=20128`인 경우 CLI 대상 기본 URL은 `http://:20128/v1`이어야 합니다. diff --git a/docs/i18n/ko/CODEBASE_DOCUMENTATION.md b/docs/i18n/ko/CODEBASE_DOCUMENTATION.md new file mode 100644 index 0000000000..d4f98a1f70 --- /dev/null +++ b/docs/i18n/ko/CODEBASE_DOCUMENTATION.md @@ -0,0 +1,589 @@ +# omniroute — 코드베이스 문서 + +🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md) + +> **옴니루트** 다중 제공자 AI 프록시 라우터에 대한 포괄적이고 초보자 친화적인 가이드입니다. + +--- + +## 1. 옴니루트란? + +omniroute는 AI 클라이언트(Claude CLI, Codex, Cursor IDE 등)와 AI 공급자(Anthropic, Google, OpenAI, AWS, GitHub 등) 사이에 위치하는 **프록시 라우터**입니다. 이는 하나의 큰 문제를 해결합니다. + +> **다양한 AI 클라이언트는 서로 다른 "언어"(API 형식)를 사용하며, 다양한 AI 제공업체도 서로 다른 "언어"를 기대합니다.** omniroute는 이들 사이를 자동으로 변환합니다. + +UN의 범용 통역사처럼 생각해보세요. 모든 대표는 모든 언어를 말할 수 있으며 번역자는 다른 대표를 위해 이를 변환합니다. + +--- + +## 2. 아키텍처 개요 + +```mermaid +graph LR + subgraph Clients + A[Claude CLI] + B[Codex] + C[Cursor IDE] + D[OpenAI-compatible] + end + + subgraph omniroute + E[Handler Layer] + F[Translator Layer] + G[Executor Layer] + H[Services Layer] + end + + subgraph Providers + I[Anthropic Claude] + J[Google Gemini] + K[OpenAI / Codex] + L[GitHub Copilot] + M[AWS Kiro] + N[Antigravity] + O[Cursor API] + end + + A --> E + B --> E + C --> E + D --> E + E --> F + F --> G + G --> I + G --> J + G --> K + G --> L + G --> M + G --> N + G --> O + H -.-> E + H -.-> G +``` + +### 핵심 원칙: 허브 앤 스포크 번역 + +모든 형식 번역은 **OpenAI 형식을 허브**로 통과합니다. + +``` +Client Format → [OpenAI Hub] → Provider Format (request) +Provider Format → [OpenAI Hub] → Client Format (response) +``` + +즉, **N²**(모든 쌍) 대신 **N 번역자**(형식당 하나)만 필요하다는 의미입니다. + +--- + +## 3. 프로젝트 구조 + +``` +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 +``` + +--- + +## 4. 모듈별 분석 + +### 4.1 구성(`open-sse/config/`) + +모든 공급자 구성에 대한 **단일 정보 소스**. + +| 파일 | 목적 | +| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `constants.ts` | 모든 공급자에 대한 기본 URL, OAuth 자격 증명(기본값), 헤더 및 기본 시스템 프롬프트가 포함된 `PROVIDERS` 개체입니다. 또한 `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG` 및 `SKIP_PATTERNS`을 정의합니다. | +| `credentialLoader.ts` | `data/provider-credentials.json`에서 외부 자격 증명을 로드하고 `PROVIDERS`의 하드코딩된 기본값에 병합합니다. 이전 버전과의 호환성을 유지하면서 소스 제어에서 비밀을 유지합니다. | +| `providerModels.ts` | 중앙 모델 레지스트리: 공급자 별칭 → 모델 ID를 매핑합니다. `getModels()`, `getProviderByAlias()`과 같은 함수입니다. | +| `codexInstructions.ts` | Codex 요청에 주입된 시스템 지침(제약 조건, 샌드박스 규칙, 승인 정책 편집) | +| `defaultThinkingSignature.ts` | Claude 및 Gemini 모델의 기본 "사고" 서명입니다. | +| `ollamaModels.ts` | 로컬 Ollama 모델에 대한 스키마 정의(이름, 크기, 계열, 양자화) | + +#### 자격 증명 로드 흐름 + +```mermaid +flowchart TD + A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"] + B --> C{"data/provider-credentials.json\nexists?"} + C -->|Yes| D["credentialLoader reads JSON"] + C -->|No| E["Use hardcoded defaults"] + D --> F{"For each provider in JSON"} + F --> G{"Provider exists\nin PROVIDERS?"} + G -->|No| H["Log warning, skip"] + G -->|Yes| I{"Value is object?"} + I -->|No| J["Log warning, skip"] + I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"] + K --> F + H --> F + J --> F + F -->|Done| L["PROVIDERS ready with\nmerged credentials"] + E --> L +``` + +--- + +### 4.2 실행자(`open-sse/executors/`) + +실행자는 **전략 패턴**을 사용하여 **제공자별 로직**을 캡슐화합니다. 각 실행자는 필요에 따라 기본 메서드를 재정의합니다. + +```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 DefaultExecutor { + +refreshCredentials() + } + + class AntigravityExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +shouldRetry() + +refreshCredentials() + } + + class CursorExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseResponse() + +generateChecksum() + } + + class KiroExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseEventStream() + +refreshCredentials() + } + + BaseExecutor <|-- DefaultExecutor + BaseExecutor <|-- AntigravityExecutor + BaseExecutor <|-- CursorExecutor + BaseExecutor <|-- KiroExecutor + BaseExecutor <|-- CodexExecutor + BaseExecutor <|-- GeminiCLIExecutor + BaseExecutor <|-- GithubExecutor +``` + +| 집행자 | 공급자 | 주요 전문 분야 | +| ---------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| `base.ts` | — | 추상 기반: URL 구축, 헤더, 재시도 논리, 자격 증명 새로 고침 | +| `default.ts` | 클로드, 제미니, OpenAI, GLM, 키미, 미니맥스 | 표준 공급자를 위한 일반 OAuth 토큰 새로 고침 | +| `antigravity.ts` | Google 클라우드 코드 | 프로젝트/세션 ID 생성, 다중 URL 대체, 오류 메시지에서 사용자 정의 재시도 구문 분석("2시간 7분 23초 후 재설정") | +| `cursor.ts` | 커서 IDE | **가장 복잡함**: SHA-256 체크섬 인증, Protobuf 요청 인코딩, 바이너리 EventStream → SSE 응답 구문 분석 | +| `codex.ts` | OpenAI 코덱스 | 시스템 지침 주입, ​​사고 수준 관리, 지원되지 않는 매개변수 제거 | +| `gemini-cli.ts` | 구글 제미니 CLI | 맞춤 URL 구축(`streamGenerateContent`), Google OAuth 토큰 새로고침 | +| `github.ts` | GitHub 부조종사 | 듀얼 토큰 시스템(GitHub OAuth + Copilot 토큰), VSCode 헤더 모방 | +| `kiro.ts` | AWS 코드위스퍼러 | AWS EventStream 바이너리 구문 분석, AMZN 이벤트 프레임, 토큰 추정 | +| `index.ts` | — | 팩토리: 기본 폴백을 사용하여 공급자 이름 → 실행자 클래스 매핑 | + +--- + +### 4.3 핸들러(`open-sse/handlers/`) + +**조정 레이어** — 번역, 실행, 스트리밍 및 오류 처리를 조정합니다. + +| 파일 | 목적 | +| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `chatCore.ts` | **중앙 오케스트레이터**(~600줄). 형식 감지 → 변환 → 실행기 디스패치 → 스트리밍/비스트리밍 응답 → 토큰 새로 고침 → 오류 처리 → 사용 로깅 등 전체 요청 수명 주기를 처리합니다. | +| `responsesHandler.ts` | OpenAI의 응답 API용 어댑터: 응답 형식 변환 → 채팅 완료 → `chatCore`로 전송 → SSE를 다시 응답 형식으로 변환합니다. | +| `embeddings.ts` | 임베딩 생성 핸들러: 임베딩 모델 → 공급자를 확인하고 공급자 API로 디스패치하고 OpenAI 호환 임베딩 응답을 반환합니다. 6개 이상의 공급자를 지원합니다. | +| `imageGeneration.ts` | 이미지 생성 핸들러: 이미지 모델 → 공급자를 확인하고 OpenAI 호환, Gemini 이미지(반중력) 및 폴백(Nebius) 모드를 지원합니다. base64 또는 URL 이미지를 반환합니다. | + +#### 요청 수명 주기(chatCore.ts) + +```mermaid +sequenceDiagram + participant Client + participant chatCore + participant Translator + participant Executor + participant Provider + + Client->>chatCore: Request (any format) + chatCore->>chatCore: Detect source format + chatCore->>chatCore: Check bypass patterns + chatCore->>chatCore: Resolve model & provider + chatCore->>Translator: Translate request (source → OpenAI → target) + chatCore->>Executor: Get executor for provider + Executor->>Executor: Build URL, headers, transform request + Executor->>Executor: Refresh credentials if needed + Executor->>Provider: HTTP fetch (streaming or non-streaming) + + alt Streaming + Provider-->>chatCore: SSE stream + chatCore->>chatCore: Pipe through SSE transform stream + Note over chatCore: Transform stream translates
each chunk: target → OpenAI → source + chatCore-->>Client: Translated SSE stream + else Non-streaming + Provider-->>chatCore: JSON response + chatCore->>Translator: Translate response + chatCore-->>Client: Translated JSON + end + + alt Error (401, 429, 500...) + chatCore->>Executor: Retry with credential refresh + chatCore->>chatCore: Account fallback logic + end +``` + +--- + +### 4.4 서비스 (`open-sse/services/`) + +처리기와 실행기를 지원하는 비즈니스 논리입니다. + +| 파일 | 목적 | +| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `provider.ts` | **형식 감지**(`detectFormat`): 요청 본문 구조를 분석하여 Claude/OpenAI/Gemini/반중력/응답 형식을 식별합니다(Claude에 대한 `max_tokens` 휴리스틱 포함). 또한: URL 구축, 헤더 구축, 구성 정규화 사고. `openai-compatible-*` 및 `anthropic-compatible-*` 동적 공급자를 지원합니다. | +| `model.ts` | 모델 문자열 구문 분석(`claude/model-name` → `{provider: "claude", model: "model-name"}`), 충돌 감지를 통한 별칭 해결, 입력 삭제(경로 순회/제어 문자 거부), 비동기 별칭 getter 지원을 통한 모델 정보 확인. | +| `accountFallback.ts` | 속도 제한 처리: 지수 백오프(1초 → 2초 → 4초 → 최대 2분), 계정 휴지 관리, 오류 분류(오류가 대체를 트리거하는지 여부). | +| `tokenRefresh.ts` | **모든 공급자**에 대한 OAuth 토큰 새로 고침: Google(Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub(OAuth + Copilot 이중 토큰), Kiro(AWS SSO OIDC + Social Auth). 진행 중인 약속 중복 제거 캐시 및 지수 백오프를 통한 재시도가 포함됩니다. | +| `combo.ts` | **콤보 모델**: 대체 모델 체인입니다. 모델 A가 대체 가능 오류로 인해 실패하는 경우 모델 B를 시도한 다음 C를 시도합니다. 실제 업스트림 상태 코드를 반환합니다. | +| `usage.ts` | 공급자 API(GitHub Copilot 할당량, 반중력 모델 할당량, Codex 속도 제한, Kiro 사용량 분석, Claude 설정)에서 할당량/사용 데이터를 가져옵니다. | +| `accountSelector.ts` | 채점 알고리즘을 사용한 스마트 계정 선택: 우선순위, 상태, 라운드 로빈 위치 및 쿨다운 상태를 고려하여 각 요청에 대한 최적의 계정을 선택합니다. | +| `contextManager.ts` | 요청 컨텍스트 수명 주기 관리: 디버깅 및 로깅을 위한 메타데이터(요청 ID, 타임스탬프, 공급자 정보)가 포함된 요청별 컨텍스트 개체를 생성하고 추적합니다. | +| `ipFilter.ts` | IP 기반 액세스 제어: 허용 목록 및 차단 목록 모드를 지원합니다. API 요청을 처리하기 전에 구성된 규칙에 따라 클라이언트 IP를 검증합니다. | +| `sessionManager.ts` | 클라이언트 핑거프린팅을 통한 세션 추적: 해시된 클라이언트 식별자를 사용하여 활성 세션을 추적하고, 요청 수를 모니터링하고, 세션 메트릭을 제공합니다. | +| `signatureCache.ts` | 요청 서명 기반 중복 제거 캐시: 최근 요청 서명을 캐시하고 일정 기간 내에 동일한 요청에 대해 캐시된 응답을 반환하여 중복 요청을 방지합니다. | +| `systemPrompt.ts` | 글로벌 시스템 프롬프트 삽입: 제공자별 호환성 처리를 통해 모든 요청에 ​​구성 가능한 시스템 프롬프트를 추가하거나 추가합니다. | +| `thinkingBudget.ts` | 추론 토큰 예산 관리: 사고/추론 토큰 제어를 위한 패스스루, 자동(스트립 사고 구성), 사용자 정의(고정 예산) 및 적응형(복잡성 확장) 모드를 지원합니다. | +| `wildcardRouter.ts` | 와일드카드 모델 패턴 라우팅: 가용성 및 우선순위에 따라 와일드카드 패턴(예: `*/claude-*`)을 구체적인 공급자/모델 쌍으로 확인합니다. | + +#### 토큰 새로 고침 중복 제거 + +```mermaid +sequenceDiagram + participant R1 as Request 1 + participant R2 as Request 2 + participant Cache as refreshPromiseCache + participant OAuth as OAuth Provider + + R1->>Cache: getAccessToken("gemini", token) + Cache->>Cache: No in-flight promise + Cache->>OAuth: Start refresh + R2->>Cache: getAccessToken("gemini", token) + Cache->>Cache: Found in-flight promise + Cache-->>R2: Return existing promise + OAuth-->>Cache: New access token + Cache-->>R1: New access token + Cache-->>R2: Same access token (shared) + Cache->>Cache: Delete cache entry +``` + +#### 계정 대체 상태 머신 + +```mermaid +stateDiagram-v2 + [*] --> Active + Active --> Error: Request fails (401/429/500) + Error --> Cooldown: Apply backoff + Cooldown --> Active: Cooldown expires + Active --> Active: Request succeeds (reset backoff) + + state Error { + [*] --> ClassifyError + ClassifyError --> ShouldFallback: Rate limit / Auth / Transient + ClassifyError --> NoFallback: 400 Bad Request + } + + state Cooldown { + [*] --> ExponentialBackoff + ExponentialBackoff: Level 0 = 1s + ExponentialBackoff: Level 1 = 2s + ExponentialBackoff: Level 2 = 4s + ExponentialBackoff: Max = 2min + } +``` + +#### 콤보 모델 체인 + +```mermaid +flowchart LR + A["Request with\ncombo model"] --> B["Model A"] + B -->|"2xx Success"| C["Return response"] + B -->|"429/401/500"| D{"Fallback\neligible?"} + D -->|Yes| E["Model B"] + D -->|No| F["Return error"] + E -->|"2xx Success"| C + E -->|"429/401/500"| G{"Fallback\neligible?"} + G -->|Yes| H["Model C"] + G -->|No| F + H -->|"2xx Success"| C + H -->|"Fail"| I["All failed →\nReturn last status"] +``` + +--- + +### 4.5 번역기(`open-sse/translator/`) + +자체 등록 플러그인 시스템을 사용하는 **형식 번역 엔진**. + +#### 아키텍처 + +```mermaid +graph TD + subgraph "Request Translation" + A["Claude → OpenAI"] + B["Gemini → OpenAI"] + C["Antigravity → OpenAI"] + D["OpenAI Responses → OpenAI"] + E["OpenAI → Claude"] + F["OpenAI → Gemini"] + G["OpenAI → Kiro"] + H["OpenAI → Cursor"] + end + + subgraph "Response Translation" + I["Claude → OpenAI"] + J["Gemini → OpenAI"] + K["Kiro → OpenAI"] + L["Cursor → OpenAI"] + M["OpenAI → Claude"] + N["OpenAI → Antigravity"] + O["OpenAI → Responses"] + end +``` + +| 디렉토리 | 파일 | 설명 | +| ------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `request/` | 8명의 번역가 | 형식 간에 요청 본문을 변환합니다. 각 파일은 가져올 때 `register(from, to, fn)`을 통해 자체 등록됩니다. | +| `response/` | 7명의 번역자 | 형식 간에 스트리밍 응답 청크를 변환합니다. SSE 이벤트 유형, 사고 블록, 도구 호출을 처리합니다. | +| `helpers/` | 도우미 6명 | 공유 유틸리티: `claudeHelper`(시스템 프롬프트 추출, 사고 구성), `geminiHelper`(부분/콘텐츠 매핑), `openaiHelper`(형식 필터링), `toolCallHelper`(ID 생성, 누락된 응답 주입), `maxTokensHelper`, `responsesApiHelper`. | +| `index.ts` | — | 번역 엔진: `translateRequest()`, `translateResponse()`, 상태 관리, 레지스트리. | +| `formats.ts` | — | 형식 상수: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | + +#### 주요 디자인: 자동 등록 플러그인 + +```javascript +// Each translator file calls register() on import: +import { register } from "../index.js"; +register("claude", "openai", translateClaudeToOpenAI); + +// The index.js imports all translator files, triggering registration: +import "./request/claude-to-openai.js"; // ← self-registers +``` + +--- + +### 4.6 유틸리티(`open-sse/utils/`) + +| 파일 | 목적 | +| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `error.ts` | 오류 응답 구축(OpenAI 호환 형식), 업스트림 오류 구문 분석, 오류 메시지에서 반중력 재시도 시간 추출, SSE 오류 스트리밍. | +| `stream.ts` | **SSE 변환 스트림** — 핵심 스트리밍 파이프라인입니다. 두 가지 모드: `TRANSLATE`(전체 형식 번역) 및 `PASSTHROUGH`(정규화 + 사용량 추출). 청크 버퍼링, 사용량 추정, 콘텐츠 길이 추적을 처리합니다. 스트림별 인코더/디코더 인스턴스는 공유 상태를 방지합니다. | +| `streamHelpers.ts` | 하위 수준 SSE 유틸리티: `parseSSELine`(공백 허용), `hasValuableContent`(OpenAI/Claude/Gemini의 빈 청크 필터링), `fixInvalidId`, `formatSSE`(`perf_metrics` 정리를 통한 형식 인식 SSE 직렬화). | +| `usageTracking.ts` | 모든 형식(Claude/OpenAI/Gemini/Responses)에서 토큰 사용량 추출, 별도 도구/토큰당 메시지 문자 비율을 사용한 추정, 버퍼 추가(2000 토큰 안전 마진), 형식별 필드 필터링, ANSI 색상을 사용한 콘솔 로깅. | +| `requestLogger.ts` | 파일 기반 요청 로깅(`ENABLE_REQUEST_LOGS=true`을 통한 선택). 번호가 매겨진 파일(`1_req_client.json` → `7_res_client.txt`)로 세션 폴더를 생성합니다. 모든 I/O는 비동기식입니다(fire-and-forget). 민감한 헤더를 마스킹합니다. | +| `bypassHandler.ts` | Claude CLI(제목 추출, 워밍업, 카운트)의 특정 패턴을 가로채고 공급자를 호출하지 않고 가짜 응답을 반환합니다. 스트리밍과 비스트리밍을 모두 지원합니다. 의도적으로 Claude CLI 범위로 제한되었습니다. | +| `networkProxy.ts` | 공급자별 구성 → 전역 구성 → 환경 변수(`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`) 우선 순위에 따라 지정된 공급자에 대한 아웃바운드 프록시 URL을 확인합니다. `NO_PROXY` 제외를 지원합니다. 30초 동안 캐시 구성. | + +#### SSE 스트리밍 파이프라인 + +```mermaid +flowchart TD + A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"] + B --> C["Buffer lines\n(split on newline)"] + C --> D["parseSSELine()\n(trim whitespace, parse JSON)"] + D --> E{"Mode?"} + E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"] + E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"] + F --> H["hasValuableContent()\nfilter empty chunks"] + G --> H + H -->|"Has content"| I["extractUsage()\ntrack token counts"] + H -->|"Empty"| J["Skip chunk"] + I --> K["formatSSE()\nserialize + clean perf_metrics"] + K --> L["TextEncoder\n(per-stream instance)"] + L --> M["Enqueue to\nclient stream"] + + style A fill:#f9f,stroke:#333 + style M fill:#9f9,stroke:#333 +``` + +#### 요청 로거 세션 구조 + +``` +logs/ +└── claude_gemini_claude-sonnet_20260208_143045/ + ├── 1_req_client.json ← Raw client request + ├── 2_req_source.json ← After initial conversion + ├── 3_req_openai.json ← OpenAI intermediate format + ├── 4_req_target.json ← Final target format + ├── 5_res_provider.txt ← Provider SSE chunks (streaming) + ├── 5_res_provider.json ← Provider response (non-streaming) + ├── 6_res_openai.txt ← OpenAI intermediate chunks + ├── 7_res_client.txt ← Client-facing SSE chunks + └── 6_error.json ← Error details (if any) +``` + +--- + +### 4.7 애플리케이션 계층(`src/`) + +| 디렉토리 | 목적 | +| ------------- | ------------------------------------------------------------------- | +| `src/app/` | 웹 UI, API 경로, Express 미들웨어, OAuth 콜백 핸들러 | +| `src/lib/` | 데이터베이스 액세스(`localDb.ts`, `usageDb.ts`), 인증, 공유 | +| `src/mitm/` | 공급자 트래픽을 가로채기 위한 중간자 프록시 유틸리티 | +| `src/models/` | 데이터베이스 모델 정의 | +| `src/shared/` | open-sse 함수에 대한 래퍼(공급자, 스트림, 오류 등) | +| `src/sse/` | open-sse 라이브러리를 Express 경로에 연결하는 SSE 엔드포인트 핸들러 | +| `src/store/` | 애플리케이션 상태 관리 | + +#### 주목할만한 API 경로 + +| 경로 | 방법 | 목적 | +| --------------------------------------------- | ------------------ | -------------------------------------------------------------------------------- | +| `/api/provider-models` | 가져오기/게시/삭제 | 공급자별 사용자 정의 모델을 위한 CRUD | +| `/api/models/catalog` | 받기 | 공급자별로 그룹화된 모든 모델(채팅, 임베딩, 이미지, 사용자 정의)의 집계 카탈로그 | +| `/api/settings/proxy` | 가져오기/넣기/삭제 | 계층적 아웃바운드 프록시 구성(`global/providers/combos/keys`) | +| `/api/settings/proxy/test` | 포스트 | 프록시 연결을 확인하고 공용 IP/지연 시간을 반환합니다. | +| `/v1/providers/[provider]/chat/completions` | 포스트 | 모델 검증을 통한 제공업체별 전용 채팅 완료 | +| `/v1/providers/[provider]/embeddings` | 포스트 | 모델 검증을 통한 제공자별 전용 임베딩 | +| `/v1/providers/[provider]/images/generations` | 포스트 | 모델 검증을 통한 제공자별 전용 이미지 생성 | +| `/api/settings/ip-filter` | 가져오기/넣기 | IP 허용 목록/차단 목록 관리 | +| `/api/settings/thinking-budget` | 가져오기/넣기 | 토큰 예산 구성 추론(통과/자동/맞춤/적응) | +| `/api/settings/system-prompt` | 가져오기/넣기 | 모든 요청에 ​​대해 글로벌 시스템 프롬프트 주입 | +| `/api/sessions` | 받기 | 활성 세션 추적 및 측정항목 | +| `/api/rate-limits` | 받기 | 계정별 비율한도 현황 | + +--- + +## 5. 주요 디자인 패턴 + +### 5.1 허브 앤 스포크 번역 + +모든 형식은 **OpenAI 형식을 허브**로 통해 변환됩니다. 새 공급자를 추가하려면 N 쌍이 아닌 **한 쌍**의 번역기(OpenAI 간)만 작성하면 됩니다. + +### 5.2 실행자 전략 패턴 + +각 공급자에는 `BaseExecutor`에서 상속되는 전용 실행자 클래스가 있습니다. `executors/index.ts`의 팩토리는 런타임 시 올바른 팩토리를 선택합니다. + +### 5.3 자체 등록 플러그인 시스템 + +번역기 모듈은 `register()`을 통해 가져올 때 자체적으로 등록됩니다. 새로운 번역자를 추가하는 것은 파일을 생성하고 가져오는 것뿐입니다. + +### 5.4 지수 백오프를 사용한 계정 대체 + +공급자가 429/401/500을 반환하면 시스템은 지수 쿨다운(1초 → 2초 → 4초 → 최대 2분)을 적용하여 다음 계정으로 전환할 수 있습니다. + +### 5.5 콤보 모델 체인 + +"콤보"는 여러 `provider/model` 문자열을 그룹화합니다. 첫 번째 작업이 실패하면 자동으로 다음 작업으로 대체됩니다. + +### 5.6 상태 저장 스트리밍 변환 + +응답 변환은 `initState()` 메커니즘을 통해 SSE 청크(사고 블록 추적, 도구 호출 축적, 콘텐츠 블록 인덱싱) 전체에서 상태를 유지합니다. + +### 5.7 사용 안전 버퍼 + +클라이언트가 시스템 프롬프트 및 형식 변환의 오버헤드로 인해 컨텍스트 창 제한에 도달하는 것을 방지하기 위해 보고된 사용량에 2000토큰 버퍼가 추가되었습니다. + +--- + +## 6. 지원되는 형식 + +| 형식 | 방향 | 식별자 | +| ---------------- | ----------- | ------------------ | +| OpenAI 채팅 완료 | 소스 + 타겟 | `openai` | +| OpenAI 응답 API | 소스 + 타겟 | `openai-responses` | +| 인류학 클로드 | 소스 + 타겟 | `claude` | +| 구글 제미니 | 소스 + 타겟 | `gemini` | +| 구글 제미니 CLI | 대상만 | `gemini-cli` | +| 반중력 | 소스 + 타겟 | `antigravity` | +| AWS 키로 | 대상만 | `kiro` | +| 커서 | 대상만 | `cursor` | + +--- + +## 7. 지원되는 공급자 + +| 공급자 | 인증 방법 | 집행자 | 주요 내용 | +| ------------------------ | ---------------------- | --------- | ------------------------------------------- | +| 인류학 클로드 | API 키 또는 OAuth | 기본값 | `x-api-key` 헤더 사용 | +| 구글 제미니 | API 키 또는 OAuth | 기본값 | `x-goog-api-key` 헤더 사용 | +| 구글 제미니 CLI | OAuth | 쌍둥이CLI | `streamGenerateContent` 엔드포인트 사용 | +| 반중력 | OAuth | 반중력 | 다중 URL 대체, 사용자 정의 재시도 구문 분석 | +| 오픈AI | API 키 | 기본값 | 표준 무기명 인증 | +| 코덱스 | OAuth | 코덱스 | 시스템 지침 주입, ​​사고 관리 | +| GitHub 부조종사 | OAuth + Copilot 토큰 | 깃허브 | 듀얼 토큰, VSCode 헤더 모방 | +| 키로(AWS) | AWS SSO OIDC 또는 소셜 | 키로 | 바이너리 EventStream 구문 분석 | +| 커서 IDE | 체크섬 인증 | 커서 | Protobuf 인코딩, SHA-256 체크섬 | +| 퀀 | OAuth | 기본값 | 표준 인증 | +| 아이플로우 | OAuth(기본 + 전달자) | 기본값 | 이중 인증 헤더 | +| 오픈라우터 | API 키 | 기본값 | 표준 무기명 인증 | +| GLM, 키미, 미니맥스 | API 키 | 기본값 | Claude 호환, `x-api-key` 사용 | +| `openai-compatible-*` | API 키 | 기본값 | 동적: 모든 OpenAI 호환 엔드포인트 | +| `anthropic-compatible-*` | API 키 | 기본값 | 동적: Claude와 호환되는 모든 엔드포인트 | + +--- + +## 8. 데이터 흐름 요약 + +### 스트리밍 요청 + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor\nbuildUrl + buildHeaders"] + D --> E["fetch(providerURL)"] + E --> F["createSSEStream()\nTRANSLATE mode"] + F --> G["parseSSELine()"] + G --> H["translateResponse()\ntarget → OpenAI → source"] + H --> I["extractUsage()\n+ addBuffer"] + I --> J["formatSSE()"] + J --> K["Client receives\ntranslated SSE"] + K --> L["logUsage()\nsaveRequestUsage()"] +``` + +### 비스트리밍 요청 + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor.execute()"] + D --> E["translateResponse()\ntarget → OpenAI → source"] + E --> F["Return JSON\nresponse"] +``` + +### 우회 흐름(Claude CLI) + +```mermaid +flowchart LR + A["Claude CLI request"] --> B{"Match bypass\npattern?"} + B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"] + B -->|"No match"| D["Normal flow"] + C --> E["Translate to\nsource format"] + E --> F["Return without\ncalling provider"] +``` diff --git a/docs/i18n/ko/FEATURES.md b/docs/i18n/ko/FEATURES.md new file mode 100644 index 0000000000..d4c87a1b25 --- /dev/null +++ b/docs/i18n/ko/FEATURES.md @@ -0,0 +1,77 @@ +# OmniRoute — 대시보드 기능 갤러리 + +🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md) + +OmniRoute 대시보드의 모든 섹션에 대한 시각적 가이드입니다. + +--- + +## 🔌 제공업체 + +AI 공급자 연결 관리: OAuth 공급자(Claude Code, Codex, Gemini CLI), API 키 공급자(Groq, DeepSeek, OpenRouter) 및 무료 공급자(iFlow, Qwen, Kiro). + +![Providers Dashboard](screenshots/01-providers.png) + +--- + +## 🎨 콤보 + +채우기 우선, 라운드 로빈, 두 가지 선택의 힘, 무작위, 최소 사용, 비용 최적화 등 6가지 전략을 사용하여 모델 라우팅 콤보를 만듭니다. 각 콤보는 자동 폴백을 통해 여러 모델을 연결합니다. + +![Combos Dashboard](screenshots/02-combos.png) + +--- + +## 📊 분석 + +토큰 소비, 비용 추정, 활동 히트맵, 주간 분포 차트 및 공급자별 분석을 포함한 포괄적인 사용량 분석입니다. + +![Analytics Dashboard](screenshots/03-analytics.png) + +--- + +## 🏥 시스템 상태 + +실시간 모니터링: 가동 시간, 메모리, 버전, 대기 시간 백분위수(p50/p95/p99), 캐시 통계 및 공급자 회로 차단기 상태. + +![Health Dashboard](screenshots/04-health.png) + +--- + +## 🔧 번역기 놀이터 + +API 번역 디버깅을 위한 4가지 모드: **플레이그라운드**(형식 변환기), **채팅 테스터**(실시간 요청), **테스트 벤치**(일괄 테스트), **라이브 모니터**(실시간 스트림). + +![Translator Playground](screenshots/05-translator.png) + +--- + +## ⚙️ 설정 + +일반 설정, 시스템 스토리지, 백업 관리(데이터베이스 내보내기/가져오기), 모양(어둡게/밝게 모드), 보안(API 엔드포인트 보호 및 사용자 정의 공급자 차단 포함), 라우팅, 복원력 및 고급 구성. + +![Settings Dashboard](screenshots/06-settings.png) + +--- + +## 🔧 CLI 도구 + +AI 코딩 도구에 대한 원클릭 구성: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code 및 Antigravity. + +![CLI Tools Dashboard](screenshots/07-cli-tools.png) + +--- + +## 📝 요청 로그 + +공급자, 모델, 계정 및 API 키별로 필터링하여 실시간 요청 로깅. 상태 코드, 토큰 사용량, 대기 시간 및 응답 세부 정보를 표시합니다. + +![Usage Logs](screenshots/08-usage.png) + +--- + +## 🌐 API 엔드포인트 + +기능 분석이 포함된 통합 API 엔드포인트: 채팅 완료, 임베딩, 이미지 생성, 순위 재지정, 오디오 전사 및 등록된 API 키. + +![Endpoint Dashboard](screenshots/09-endpoint.png) diff --git a/docs/i18n/ko/TROUBLESHOOTING.md b/docs/i18n/ko/TROUBLESHOOTING.md new file mode 100644 index 0000000000..87690b434d --- /dev/null +++ b/docs/i18n/ko/TROUBLESHOOTING.md @@ -0,0 +1,219 @@ +# 문제 해결 + +🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md) + +OmniRoute의 일반적인 문제 및 솔루션. + +--- + +## 빠른 수정 + +| 문제 | 솔루션 | +| ----------------------------------- | ------------------------------------------------------------------- | +| 첫 번째 로그인이 작동하지 않습니다 | `.env`에서 `INITIAL_PASSWORD` 확인(기본값: `123456`) | +| 대시보드가 ​​잘못된 포트에서 열림 | `PORT=20128` 및 `NEXT_PUBLIC_BASE_URL=http://localhost:20128` 설정 | +| `logs/` 아래에 요청 로그가 없습니다 | `ENABLE_REQUEST_LOGS=true` 설정 | +| EACCES: 권한이 거부되었습니다 | `DATA_DIR=/path/to/writable/dir`을 설정하여 `~/.omniroute`을 재정의 | +| 라우팅 전략이 저장되지 않음 | v1.4.11+로 업데이트(설정 지속성을 위한 Zod 스키마 수정) | + +--- + +## 공급자 문제 + +### "언어 모델이 메시지를 제공하지 않았습니다." + +**원인:** 공급자 할당량이 소진되었습니다. + +**수정:** + +1. 대시보드 할당량 추적기를 확인하세요. +2. 대체 계층과 콤보 사용 +3. 더 저렴한/무료 등급으로 전환 + +### 속도 제한 + +**원인:** 구독 할당량이 소진되었습니다. + +**수정:** + +- 대체 추가: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` +- GLM/MiniMax를 저렴한 백업으로 사용 + +### OAuth 토큰 만료됨 + +OmniRoute는 토큰을 자동으로 새로 고칩니다. 문제가 지속되는 경우: + +1. 대시보드 → 공급자 → 재접속 +2. 공급자 연결을 삭제하고 다시 추가 + +--- + +## 클라우드 문제 + +### 클라우드 동기화 오류 + +1. `BASE_URL`이 실행 중인 인스턴스(예: `http://localhost:20128`)를 가리키는지 확인합니다. +2. `CLOUD_URL`이 클라우드 엔드포인트(예: `https://omniroute.dev`)를 가리키는지 확인하세요. +3. `NEXT_PUBLIC_*` 값을 서버측 값에 맞춰 유지하세요. + +### 클라우드 `stream=false` 500을 반환합니다. + +**증상:** 비스트리밍 통화에 대한 클라우드 엔드포인트의 `Unexpected token 'd'...`. + +**원인:** 업스트림은 클라이언트가 JSON을 기대하는 동안 SSE 페이로드를 반환합니다. + +**해결 방법:** 클라우드 직접 호출에는 `stream=true`을 사용하세요. 로컬 런타임에는 SSE→JSON 대체가 포함됩니다. + +### 클라우드가 연결되었지만 "잘못된 API 키"라고 표시됩니다. + +1. 로컬 대시보드(`/api/keys`)에서 새로운 키를 생성합니다. +2. 클라우드 동기화 실행: 클라우드 활성화 → 지금 동기화 +3. 이전/동기화되지 않은 키는 여전히 클라우드에서 `401`을 반환할 수 있습니다. + +--- + +## 도커 문제 + +### CLI 도구가 설치되지 않은 것으로 표시됨 + +1. 런타임 필드 확인: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq` +2. 휴대용 모드의 경우: 이미지 대상 `runner-cli` 사용(번들 CLI) +3. 호스트 마운트 모드의 경우: `CLI_EXTRA_PATHS`을 설정하고 호스트 bin 디렉터리를 읽기 전용으로 마운트합니다. +4. `installed=true` 및 `runnable=false`인 경우: 바이너리가 발견되었지만 상태 확인에 실패했습니다. + +### 빠른 런타임 검증 + +```bash +curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +``` + +--- + +## 비용 문제 + +### 높은 비용 + +1. 대시보드 → 사용량에서 사용량 현황을 확인하세요. +2. 기본 모델을 GLM/MiniMax로 전환 +3. 중요하지 않은 작업에는 무료 계층(Gemini CLI, iFlow)을 사용합니다. +4. API 키별 비용 예산 설정: 대시보드 → API 키 → 예산 + +--- + +## 디버깅 + +### 요청 로그 활성화 + +`.env` 파일에 `ENABLE_REQUEST_LOGS=true`을 설정합니다. 로그는 `logs/` 디렉터리에 나타납니다. + +### 제공자 상태 확인 + +```bash +# Health dashboard +http://localhost:20128/dashboard/health + +# API health check +curl http://localhost:20128/api/monitoring/health +``` + +### 런타임 스토리지 + +- 기본 상태: `${DATA_DIR}/db.json`(공급자, 콤보, 별칭, 키, 설정) +- 사용법: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- 요청 로그: `/logs/...`(`ENABLE_REQUEST_LOGS=true`인 경우) + +--- + +## 회로 차단기 문제 + +### 제공자가 OPEN 상태에서 멈췄습니다. + +공급자의 회로 차단기가 OPEN되면 대기 시간이 만료될 때까지 요청이 차단됩니다. + +**수정:** + +1. **대시보드 → 설정 → 복원력**으로 이동합니다. +2. 영향을 받는 공급자의 회로 차단기 카드를 확인하십시오. +3. **모두 재설정**을 클릭하여 모든 차단기를 삭제하거나 쿨다운이 만료될 때까지 기다립니다. +4. 재설정하기 전에 공급자가 실제로 사용 가능한지 확인하십시오. + +### 공급업체가 계속해서 회로 차단기를 작동시킵니다. + +공급자가 반복적으로 OPEN 상태에 들어가는 경우: + +1. **대시보드 → 상태 → 공급자 상태**에서 실패 패턴을 확인합니다. +2. **설정 → 탄력성 → 공급자 프로필**로 이동하여 실패 임계값을 높입니다. +3. 제공업체가 API 한도를 변경했는지 또는 재인증을 요구하는지 확인하세요. +4. 대기 시간 원격 분석 검토 - 대기 시간이 길면 시간 초과 기반 오류가 발생할 수 있습니다. + +--- + +## 오디오 전사 문제 + +### "지원되지 않는 모델" 오류 + +- 올바른 접두사(`deepgram/nova-3` 또는 `assemblyai/best`)를 사용하고 있는지 확인하세요. +- **대시보드 → 공급자**에서 공급자가 연결되어 있는지 확인합니다. + +### 전사가 비어 있거나 실패함을 반환합니다. + +- 지원되는 오디오 형식 확인: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm` +- 파일 크기가 공급자 제한(일반적으로 < 25MB) 내에 있는지 확인하세요. +- 공급자 카드에서 공급자 API 키 유효성을 확인하세요. + +--- + +## 번역기 디버깅 + +**대시보드 → 번역기**를 사용하여 형식 번역 문제를 디버깅하세요. + +| 모드 | 사용 시기 | +| ----------------- | ---------------------------------------------------------------------------------------- | +| **놀이터** | 입력/출력 형식을 나란히 비교하세요. 실패한 요청을 붙여넣어 어떻게 변환되는지 확인하세요. | +| **채팅 테스터** | 실시간 메시지 보내기 및 헤더를 포함한 전체 요청/응답 페이로드 검사 | +| **테스트 벤치** | 형식 조합 전반에 걸쳐 일괄 테스트를 실행하여 어떤 번역이 손상되었는지 확인 | +| **라이브 모니터** | 간헐적인 번역 문제를 파악하기 위해 실시간 요청 흐름을 시청하세요 | + +### 일반적인 형식 문제 + +- **Thinking 태그가 표시되지 않음** — 대상 공급자가 Thinking을 지원하는지 및 Thinking 예산 설정을 확인하세요. +- **도구 호출 중단** — 일부 형식 번역은 지원되지 않는 필드를 제거할 수 있습니다. 플레이그라운드 모드에서 확인 +- **시스템 프롬프트 누락** — Claude와 Gemini는 시스템 프롬프트를 다르게 처리합니다. 번역 출력 확인 +- **SDK는 객체 대신 원시 문자열을 반환** — v1.1.0에서 수정됨: 응답 새니타이저는 이제 OpenAI SDK Pydantic 검증 실패를 유발하는 비표준 필드(`x_groq`, `usage_breakdown` 등)를 제거합니다. +- **GLM/ERNIE는 `system` 역할을 거부합니다** — v1.1.0에서 수정됨: 역할 정규화 프로그램이 호환되지 않는 모델에 대한 시스템 메시지를 사용자 메시지에 자동으로 병합합니다. +- **`developer` 역할이 인식되지 않음** — v1.1.0에서 수정됨: OpenAI가 아닌 제공업체의 경우 자동으로 `system`로 변환됨 +- **`json_schema`가 Gemini와 작동하지 않음** — v1.1.0에서 수정됨: `response_format`은 이제 Gemini의 `responseMimeType` + `responseSchema`로 변환됩니다. + +--- + +## 복원력 설정 + +### 자동 비율 제한이 실행되지 않음 + +- 자동 비율 제한은 API 키 제공자에게만 적용됩니다(OAuth/구독 제외). +- **설정 → 탄력성 → 공급자 프로필**에 자동 속도 제한이 활성화되어 있는지 확인하세요. +- 공급자가 `429` 상태 코드 또는 `Retry-After` 헤더를 반환하는지 확인하세요. + +### 지수 백오프 조정 + +공급자 프로필은 다음 설정을 지원합니다. + +- **기본 지연** — 첫 번째 실패 후 초기 대기 시간(기본값: 1초) +- **최대 지연** — 최대 대기 시간 한도(기본값: 30초) +- **승수** — 연속 실패당 지연을 늘리는 정도(기본값: 2x) + +### 천둥 방지 무리 + +많은 동시 요청이 속도 제한 공급자에 도달하면 OmniRoute는 뮤텍스와 자동 속도 제한을 사용하여 요청을 직렬화하고 계단식 오류를 방지합니다. API 키 제공자의 경우 이는 자동입니다. + +--- + +## 아직도 막혔나요? + +- **GitHub 문제**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) +- **아키텍처**: 내부 세부정보는 [**OMNI_TOKEN_55**](ARCHITECTURE.md)을 참조하세요. +- **API 참조**: 모든 엔드포인트에 대해서는 [**OMNI_TOKEN_56**](API_REFERENCE.md)을 참조하세요. +- **헬스 대시보드**: **대시보드 → 헬스**에서 실시간 시스템 상태 확인 +- **번역기**: **대시보드 → 번역기**를 사용하여 형식 문제 디버깅 diff --git a/docs/i18n/ko/USER_GUIDE.md b/docs/i18n/ko/USER_GUIDE.md new file mode 100644 index 0000000000..196c9ad0d3 --- /dev/null +++ b/docs/i18n/ko/USER_GUIDE.md @@ -0,0 +1,698 @@ +# 이용안내 + +🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md) + +공급자 구성, 콤보 생성, CLI 도구 통합 및 OmniRoute 배포에 대한 전체 가이드입니다. + +--- + +## 목차 + +- [Pricing at a Glance](#-pricing-at-a-glance) +- [Use Cases](#-use-cases) +- [Provider Setup](#-provider-setup) +- [CLI Integration](#-cli-integration) +- [Deployment](#-deployment) +- [Available Models](#-available-models) +- [Advanced Features](#-advanced-features) + +--- + +## 💰 가격 한눈에 보기 + +| 계층 | 공급자 | 비용 | 할당량 재설정 | 최고의 대상 | +| ------------- | ------------------- | ------------------ | --------------- | ----------------- | +| **💳 구독** | 클로드 코드 (Pro) | $20/월 | 5시간 + 매주 | 이미 구독 중 | +| | 코덱스(플러스/프로) | $20-200/월 | 5시간 + 매주 | OpenAI 사용자 | +| | 제미니 CLI | **무료** | 180K/월 + 1K/일 | 모든 사람! | +| | GitHub 부조종사 | $10-19/월 | 월간 | GitHub 사용자 | +| **🔑 API 키** | 딥시크 | 사용량에 따라 지불 | 없음 | 저렴한 추론 | +| | 그로크 | 사용량에 따라 지불 | 없음 | 초고속 추론 | +| | xAI(그록) | 사용량에 따라 지불 | 없음 | Grok 4 추론 | +| | 미스트랄 | 사용량에 따라 지불 | 없음 | EU 주최 모델 | +| | 당혹감 | 사용량에 따라 지불 | 없음 | 검색 증강 | +| | 함께하는 AI | 사용량에 따라 지불 | 없음 | 오픈 소스 모델 | +| | 불꽃놀이 AI | 사용량에 따라 지불 | 없음 | 빠른 FLUX 이미지 | +| | 대뇌 | 사용량에 따라 지불 | 없음 | 웨이퍼 규모 속도 | +| | 코히어 | 사용량에 따라 지불 | 없음 | 커맨드 R+ RAG | +| | 엔비디아 NIM | 사용량에 따라 지불 | 없음 | 엔터프라이즈 모델 | +| **💰 저렴한** | GLM-4.7 | $0.6/1M | 매일 오전 10시 | 예산 백업 | +| | 미니맥스 M2.1 | $0.2/1M | 5시간 롤링 | 가장 저렴한 옵션 | +| | 키미 K2 | $9/월 정액 | 1000만 토큰/월 | 예측 가능한 비용 | +| **🆓 무료** | 아이플로우 | $0 | 무제한 | 8개 모델 무료 | +| | 퀀 | $0 | 무제한 | 3개 모델 무료 | +| | 키로 | $0 | 무제한 | 클로드 프리 | + +**💡 전문가 팁:** Gemini CLI(월 180K 무료) + iFlow(무제한 무료) 콤보 = 비용 $0로 시작하세요! + +--- + +## 🎯 사용 사례 + +### 사례 1: "Claude Pro를 구독하고 있습니다." + +**문제:** 할당량은 사용되지 않은 상태로 만료되며, 코딩 작업이 많은 동안 속도 제한이 발생합니다. + +``` +Combo: "maximize-claude" + 1. cc/claude-opus-4-6 (use subscription fully) + 2. glm/glm-4.7 (cheap backup when quota out) + 3. if/kimi-k2-thinking (free emergency fallback) + +Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total +vs. $20 + hitting limits = frustration +``` + +### 사례 2: "비용이 0이길 원합니다" + +**문제:** 구독료를 감당할 수 없고 안정적인 AI 코딩이 필요함 + +``` +Combo: "free-forever" + 1. gc/gemini-3-flash (180K free/month) + 2. if/kimi-k2-thinking (unlimited free) + 3. qw/qwen3-coder-plus (unlimited free) + +Monthly cost: $0 +Quality: Production-ready models +``` + +### 사례 3: "중단 없이 연중무휴 코딩이 필요합니다." + +**문제:** 마감일, 가동 중지 시간을 감당할 수 없음 + +``` +Combo: "always-on" + 1. cc/claude-opus-4-6 (best quality) + 2. cx/gpt-5.2-codex (second subscription) + 3. glm/glm-4.7 (cheap, resets daily) + 4. minimax/MiniMax-M2.1 (cheapest, 5h reset) + 5. if/kimi-k2-thinking (free unlimited) + +Result: 5 layers of fallback = zero downtime +Monthly cost: $20-200 (subscriptions) + $10-20 (backup) +``` + +### 사례 4: "OpenClaw에서 무료 AI를 원합니다" + +**문제:** 메시징 앱에 AI 도우미가 필요하며 완전 무료입니다. + +``` +Combo: "openclaw-free" + 1. if/glm-4.7 (unlimited free) + 2. if/minimax-m2.1 (unlimited free) + 3. if/kimi-k2-thinking (unlimited free) + +Monthly cost: $0 +Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal... +``` + +--- + +## 📖 공급자 설정 + +### 🔐 구독 제공업체 + +#### 클로드 코드(Pro/Max) + +```bash +Dashboard → Providers → Connect Claude Code +→ OAuth login → Auto token refresh +→ 5-hour + weekly quota tracking + +Models: + cc/claude-opus-4-6 + cc/claude-sonnet-4-5-20250929 + cc/claude-haiku-4-5-20251001 +``` + +**프로 팁:** 복잡한 작업에는 Opus를 사용하고, 속도를 높이려면 Sonnet을 사용하세요. OmniRoute는 모델당 할당량을 추적합니다! + +#### OpenAI 코덱스(Plus/Pro) + +```bash +Dashboard → Providers → Connect Codex +→ OAuth login (port 1455) +→ 5-hour + weekly reset + +Models: + cx/gpt-5.2-codex + cx/gpt-5.1-codex-max +``` + +#### Gemini CLI(월 180K 무료!) + +```bash +Dashboard → Providers → Connect Gemini CLI +→ Google OAuth +→ 180K completions/month + 1K/day + +Models: + gc/gemini-3-flash-preview + gc/gemini-2.5-pro +``` + +**최고의 가치:** 엄청난 무료 등급! 유료 등급 이전에 사용하세요. + +#### GitHub 코파일럿 + +```bash +Dashboard → Providers → Connect GitHub +→ OAuth via GitHub +→ Monthly reset (1st of month) + +Models: + gh/gpt-5 + gh/claude-4.5-sonnet + gh/gemini-3-pro +``` + +### 💰 저렴한 공급자 + +#### GLM-4.7 (일일 재설정, $0.6/1M) + +1. 가입: [Zhipu AI](https://open.bigmodel.cn/) +2. Coding Plan에서 API Key 받기 +3. 대시보드 → API 키 추가: 공급자: `glm`, API 키: `your-key` + +**사용:** `glm/glm-4.7` — **프로 팁:** 코딩 계획은 1/7 비용으로 3배 할당량을 제공합니다! 매일 오전 10시에 초기화됩니다. + +#### MiniMax M2.1(5시간 재설정, $0.20/1M) + +1. 가입: [MiniMax](https://www.minimax.io/) +2. API 키 받기 → 대시보드 → API 키 추가 + +**사용:** `minimax/MiniMax-M2.1` — **프로 팁:** 긴 컨텍스트(1M 토큰)에 대한 가장 저렴한 옵션! + +#### Kimi K2($9/월 정액) + +1. 구독: [Moonshot AI](https://platform.moonshot.ai/) +2. API 키 받기 → 대시보드 → API 키 추가 + +**사용:** `kimi/kimi-latest` — **프로 팁:** 1,000만 토큰에 대해 월 $9 고정 = 유효 비용 $0.90/1M! + +### 🆓 무료 제공업체 + +#### iFlow(8개 무료 모델) + +```bash +Dashboard → Connect iFlow → OAuth login → Unlimited usage + +Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1 +``` + +#### Qwen(3개 무료 모델) + +```bash +Dashboard → Connect Qwen → Device code auth → Unlimited usage + +Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash +``` + +#### 키로(클로드 프리) + +```bash +Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited + +Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5 +``` + +--- + +## 🎨 콤보 + +### 예시 1: 구독 최대화 → 저렴한 백업 + +``` +Dashboard → Combos → Create New + +Name: premium-coding +Models: + 1. cc/claude-opus-4-6 (Subscription primary) + 2. glm/glm-4.7 (Cheap backup, $0.6/1M) + 3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M) + +Use in CLI: premium-coding +``` + +### 예시 2: 무료 전용(비용 없음) + +``` +Name: free-combo +Models: + 1. gc/gemini-3-flash-preview (180K free/month) + 2. if/kimi-k2-thinking (unlimited) + 3. qw/qwen3-coder-plus (unlimited) + +Cost: $0 forever! +``` + +--- + +## 🔧 CLI 통합 + +### 커서 IDE + +``` +Settings → Models → Advanced: + OpenAI API Base URL: http://localhost:20128/v1 + OpenAI API Key: [from omniroute dashboard] + Model: cc/claude-opus-4-6 +``` + +### 클로드 코드 + +`~/.claude/config.json` 편집: + +```json +{ + "anthropic_api_base": "http://localhost:20128/v1", + "anthropic_api_key": "your-omniroute-api-key" +} +``` + +### 코덱스 CLI + +```bash +export OPENAI_BASE_URL="http://localhost:20128" +export OPENAI_API_KEY="your-omniroute-api-key" +codex "your prompt" +``` + +### 오픈클로 + +`~/.openclaw/openclaw.json` 편집: + +```json +{ + "agents": { + "defaults": { + "model": { "primary": "omniroute/if/glm-4.7" } + } + }, + "models": { + "providers": { + "omniroute": { + "baseUrl": "http://localhost:20128/v1", + "apiKey": "your-omniroute-api-key", + "api": "openai-completions", + "models": [{ "id": "if/glm-4.7", "name": "glm-4.7" }] + } + } + } +} +``` + +**또는 대시보드 사용:** CLI 도구 → OpenClaw → 자동 구성 + +### 클라인 / 계속 / RooCode + +``` +Provider: OpenAI Compatible +Base URL: http://localhost:20128/v1 +API Key: [from dashboard] +Model: cc/claude-opus-4-6 +``` + +--- + +## 🚀 배포 + +### VPS 배포 + +```bash +git clone https://github.com/diegosouzapw/OmniRoute.git +cd OmniRoute && npm install && npm run build + +export JWT_SECRET="your-secure-secret-change-this" +export INITIAL_PASSWORD="your-password" +export DATA_DIR="/var/lib/omniroute" +export PORT="20128" +export HOSTNAME="0.0.0.0" +export NODE_ENV="production" +export NEXT_PUBLIC_BASE_URL="http://localhost:20128" +export API_KEY_SECRET="endpoint-proxy-api-key-secret" + +npm run start +# Or: pm2 start npm --name omniroute -- start +``` + +### 도커 + +```bash +# Build image (default = runner-cli with codex/claude/droid preinstalled) +docker build -t omniroute:cli . + +# Portable mode (recommended) +docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli +``` + +CLI 바이너리를 사용한 호스트 통합 모드의 경우 기본 문서의 Docker 섹션을 참조하세요. + +### 환경 변수 + +| 변수 | 기본값 | 설명 | +| --------------------- | ------------------------------------ | ----------------------------------------------- | +| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT 서명 비밀(**프로덕션 변경**) | +| `INITIAL_PASSWORD` | `123456` | 첫 번째 로그인 비밀번호 | +| `DATA_DIR` | `~/.omniroute` | 데이터 디렉터리(db, 사용량, 로그) | +| `PORT` | 프레임워크 기본값 | 서비스 포트(예시에서는 `20128`) | +| `HOSTNAME` | 프레임워크 기본값 | 호스트 바인딩(Docker의 기본값은 `0.0.0.0`) | +| `NODE_ENV` | 런타임 기본값 | 배포를 위해 `production` 설정 | +| `BASE_URL` | `http://localhost:20128` | 서버측 내부 기본 URL | +| `CLOUD_URL` | `https://omniroute.dev` | 클라우드 동기화 엔드포인트 기본 URL | +| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | 생성된 API 키에 대한 HMAC 비밀 | +| `REQUIRE_API_KEY` | `false` | `/v1/*`에 Bearer API 키 적용 | +| `ENABLE_REQUEST_LOGS` | `false` | 요청/응답 로그 활성화 | +| `AUTH_COOKIE_SECURE` | `false` | `Secure` 인증 쿠키 강제(HTTPS 역방향 프록시 뒤) | + +전체 환경 변수 참조는 [README](../README.md)을 참조하세요. + +--- + +## 📊 사용 가능한 모델 + +
+사용 가능한 모든 모델 보기 + +**Claude 코드(`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001` + +**코덱스(`cx/`)** — 플러스/프로: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max` + +**Gemini CLI(`gc/`)** — 무료: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro` + +**GitHub 부조종사(`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet` + +**GLM (`glm/`)** — $0.6/1M: `glm/glm-4.7` + +**MiniMax(`minimax/`)** — $0.2/1M: `minimax/MiniMax-M2.1` + +**iFlow(`if/`)** — 무료: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1` + +**Qwen(`qw/`)** — 무료: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash` + +**키로(`kr/`)** — 무료: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5` + +**DeepSeek(`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner` + +**그로크(`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct` + +**xAI(`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini` + +**미스트랄(`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501` + +**복잡성(`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar` + +**함께하는 AI(`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo` + +**불꽃놀이 AI(`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1` + +**대뇌(`cerebras/`)**: `cerebras/llama-3.3-70b` + +**Cohere(`cohere/`)**: `cohere/command-r-plus-08-2024` + +**NVIDIA NIM(`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct` + +
+ +--- + +## 🧩 고급 기능 + +### 맞춤 모델 + +앱 업데이트를 기다리지 않고 공급자에 모델 ID를 추가하세요. + +```bash +# Via API +curl -X POST http://localhost:20128/api/provider-models \ + -H "Content-Type: application/json" \ + -d '{"provider": "openai", "modelId": "gpt-4.5-preview", "modelName": "GPT-4.5 Preview"}' + +# List: curl http://localhost:20128/api/provider-models?provider=openai +# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview" +``` + +또는 대시보드를 사용하십시오: **공급자 → [공급자] → 사용자 정의 모델**. + +### 전용 공급자 경로 + +모델 검증을 통해 요청을 특정 공급자에게 직접 라우팅합니다. + +```bash +POST http://localhost:20128/v1/providers/openai/chat/completions +POST http://localhost:20128/v1/providers/openai/embeddings +POST http://localhost:20128/v1/providers/fireworks/images/generations +``` + +공급자 접두사가 누락된 경우 자동으로 추가됩니다. 일치하지 않는 모델은 `400`을 반환합니다. + +### 네트워크 프록시 구성 + +```bash +# Set global proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"global": {"type":"http","host":"proxy.example.com","port":"8080"}}' + +# Per-provider proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"providers": {"openai": {"type":"socks5","host":"proxy.example.com","port":"1080"}}}' + +# Test proxy +curl -X POST http://localhost:20128/api/settings/proxy/test \ + -d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}' +``` + +**우선순위:** 키별 → 콤보별 → 공급자별 → 글로벌 → 환경. + +### 모델 카탈로그 API + +```bash +curl http://localhost:20128/api/models/catalog +``` + +유형(`chat`, `embedding`, `image`)을 사용하여 공급자별로 그룹화된 모델을 반환합니다. + +### 클라우드 동기화 + +- 여러 장치에서 공급자, 콤보 및 설정을 동기화합니다. +- 시간 초과 + 빠른 실패를 통한 자동 백그라운드 동기화 +- 프로덕션에서는 서버측 `BASE_URL`/`CLOUD_URL`을 선호합니다. + +### LLM 게이트웨이 인텔리전스(9단계) + +- **의미 체계 캐시** — 비스트리밍, 온도=0 응답을 자동 캐시합니다(`X-OmniRoute-No-Cache: true`으로 우회). +- **Idempotency 요청** — `Idempotency-Key` 또는 `X-Request-Id` 헤더를 통해 5초 이내에 요청을 중복 제거합니다. +- **진행 상황 추적** — `X-OmniRoute-Progress: true` 헤더를 통한 SSE `event: progress` 이벤트 선택 + +--- + +### 번역가 놀이터 + +**대시보드 → 번역기**를 통해 액세스합니다. OmniRoute가 공급자 간 API 요청을 변환하는 방법을 디버깅하고 시각화합니다. + +| 모드 | 목적 | +| ----------------- | ------------------------------------------------------------------------- | +| **놀이터** | 소스/타겟 형식을 선택하고, 요청을 붙여넣고, 번역된 결과를 즉시 확인하세요 | +| **채팅 테스터** | 프록시를 통해 실시간 채팅 메시지를 보내고 전체 요청/응답 주기 검사 | +| **테스트 벤치** | 여러 형식 조합에 걸쳐 일괄 테스트를 실행하여 번역 정확성 확인 | +| **라이브 모니터** | 프록시를 통한 요청 흐름에 따라 실시간 번역 보기 | + +**사용 사례:** + +- 특정 클라이언트/공급자 조합이 실패하는 이유 디버그 +- 생각 태그, 도구 호출 및 시스템 프롬프트가 올바르게 번역되는지 확인합니다. +- OpenAI, Claude, Gemini 및 Responses API 형식 간의 형식 차이 비교 + +--- + +### 라우팅 전략 + +**대시보드 → 설정 → 라우팅**을 통해 구성합니다. + +| 전략 | 설명 | +| -------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------ | +| **먼저 채우기** | 우선순위에 따라 계정을 사용합니다. 기본 계정은 사용할 수 없을 때까지 모든 요청을 처리합니다. | +| **라운드 로빈** | 구성 가능한 고정 한도를 사용하여 모든 계정을 순환합니다(기본값: 계정당 호출 3회) | +| **P2C(두 가지 선택의 힘)** | 2개의 무작위 계정을 선택하고 더 건강한 계정으로 라우팅 — 건강에 대한 인식과 부하의 균형을 유지 | +| **랜덤** | Fisher-Yates shuffle | 을 사용하여 각 요청에 대해 무작위로 계정을 선택합니다. | +| **최소 사용** | 가장 오래된 `lastUsedAt` 타임스탬프가 있는 계정으로 라우팅하여 트래픽을 균등하게 분산 | +| **비용 최적화** | 가장 낮은 비용의 공급자를 위해 최적화하여 우선순위 값이 가장 낮은 계정으로 라우팅 | + +#### 와일드카드 모델 별칭 + +모델 이름을 다시 매핑하는 와일드카드 패턴을 만듭니다. + +``` +Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929 +Pattern: gpt-* → Target: gh/gpt-5.1-codex +``` + +와일드카드는 `*`(모든 문자) 및 `?`(단일 문자)을 지원합니다. + +#### 대체 체인 + +모든 요청에 적용되는 전역 대체 체인을 정의합니다. + +``` +Chain: production-fallback + 1. cc/claude-opus-4-6 + 2. gh/gpt-5.1-codex + 3. glm/glm-4.7 +``` + +--- + +### 탄력성 및 회로 차단기 + +**대시보드 → 설정 → 복원력**을 통해 구성합니다. + +OmniRoute는 다음 네 가지 구성 요소를 사용하여 공급자 수준 복원력을 구현합니다. + +1. **공급자 프로필** — 다음에 대한 공급자별 구성: + - 실패 임계값(개방 전 실패 횟수) + - 쿨다운 시간 + - 비율 제한 감지 감도 + - 지수 백오프 매개변수 + +2. **편집 가능한 속도 제한** — 대시보드에서 구성 가능한 시스템 수준 기본값: + - **분당 요청(RPM)** — 계정당 분당 최대 요청 수 + - **요청 간 최소 시간** — 요청 간 최소 간격(밀리초) + - **최대 동시 요청** — 계정당 최대 동시 요청 + - 수정하려면 **수정**을 클릭한 다음 **저장** 또는 **취소**를 클릭하세요. 값은 복원력 API를 통해 유지됩니다. + +3. **회로 차단기** — 공급자별 오류를 추적하고 임계값에 도달하면 자동으로 회로를 엽니다. + - **CLOSED**(정상) — 요청 흐름이 정상적으로 진행됩니다. + - **OPEN** — 반복적인 실패 후 공급자가 일시적으로 차단됩니다. + - **HALF_OPEN** — 공급자가 복구되었는지 테스트 + +4. **정책 및 잠긴 식별자** - 회로 차단기 상태와 강제 잠금 해제 기능이 있는 잠긴 식별자를 표시합니다. + +5. **비율 제한 자동 감지** — `429` 및 `Retry-After` 헤더를 모니터링하여 공급자 비율 제한에 도달하는 것을 사전에 방지합니다. + +**프로 팁:** 공급자가 중단에서 복구될 때 **모두 재설정** 버튼을 사용하여 모든 회로 차단기와 쿨다운을 해제합니다. + +--- + +### 데이터베이스 내보내기/가져오기 + +**대시보드 → 설정 → 시스템 및 스토리지**에서 데이터베이스 백업을 관리하세요. + +| 액션 | 설명 | +| -------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| **데이터베이스 내보내기** | 현재 SQLite 데이터베이스를 `.sqlite` 파일로 다운로드 | +| **모두 내보내기(.tar.gz)** | 데이터베이스, 설정, 콤보, 공급자 연결(자격 증명 없음), API 키 메타데이터를 포함한 전체 백업 아카이브를 다운로드합니다. | +| **데이터베이스 가져오기** | 현재 데이터베이스를 대체하려면 `.sqlite` 파일을 업로드하세요. 가져오기 전 백업이 자동으로 생성됩니다. | + +```bash +# API: Export database +curl -o backup.sqlite http://localhost:20128/api/db-backups/export + +# API: Export all (full archive) +curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll + +# API: Import database +curl -X POST http://localhost:20128/api/db-backups/import \ + -F "file=@backup.sqlite" +``` + +**가져오기 유효성 검사:** 가져온 파일은 무결성(SQLite pragma 검사), 필수 테이블(`provider_connections`, `provider_nodes`, `combos`, `api_keys`) 및 크기(최대 100MB)에 대해 유효성이 검사됩니다. + +**사용 사례:** + +- 머신 간 OmniRoute 마이그레이션 +- 재해 복구를 위한 외부 백업 생성 +- 팀원 간 구성 공유(모두 내보내기 → 아카이브 공유) + +--- + +### 설정 대시보드 + +설정 페이지는 쉽게 탐색할 수 있도록 5개의 탭으로 구성되어 있습니다. + +| 탭 | 내용 | +| ---------- | ------------------------------------------------------------------------------ | +| **보안** | 로그인/비밀번호 설정, IP 액세스 제어, `/models`에 대한 API 인증 및 공급자 차단 | +| **라우팅** | 글로벌 라우팅 전략(6개 옵션), 와일드카드 모델 별칭, 폴백 체인, 콤보 기본값 | +| **탄력성** | 공급자 프로필, 편집 가능한 속도 제한, 회로 차단기 상태, 정책 및 잠긴 식별자 | +| **AI** | 생각하는 예산 구성, 글로벌 시스템 프롬프트 주입, 프롬프트 캐시 통계 | +| **고급** | 글로벌 프록시 구성(HTTP/SOCKS5) | + +--- + +### 비용 및 예산 관리 + +**대시보드 → 비용**을 통해 액세스합니다. + +| 탭 | 목적 | +| -------- | ----------------------------------------------------------------- | +| **예산** | 일별/주별/월별 예산 및 실시간 추적을 통해 API 키별 지출 한도 설정 | +| **가격** | 모델 가격 항목 보기 및 편집 - 공급자당 1K 입력/출력 토큰당 비용 | + +```bash +# API: Set a budget +curl -X POST http://localhost:20128/api/usage/budget \ + -H "Content-Type: application/json" \ + -d '{"keyId": "key-123", "limit": 50.00, "period": "monthly"}' + +# API: Get current budget status +curl http://localhost:20128/api/usage/budget +``` + +**비용 추적:** 모든 요청은 토큰 사용량을 기록하고 가격표를 사용하여 비용을 계산합니다. **대시보드 → 사용량**에서 공급자, 모델, API 키별 분석을 확인하세요. + +--- + +### 오디오 전사 + +OmniRoute는 OpenAI 호환 엔드포인트를 통해 오디오 전사를 지원합니다. + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data + +# Example with curl +curl -X POST http://localhost:20128/v1/audio/transcriptions \ + -H "Authorization: Bearer your-api-key" \ + -F "file=@audio.mp3" \ + -F "model=deepgram/nova-3" +``` + +사용 가능한 공급자: **Deepgram**(`deepgram/`), **AssemblyAI**(`assemblyai/`). + +지원되는 오디오 형식: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +### 콤보 밸런싱 전략 + +**대시보드 → 콤보 → 생성/편집 → 전략**에서 콤보별 밸런싱을 구성하세요. + +| 전략 | 설명 | +| -------------------- | ----------------------------------------------------------- | +| **라운드 로빈** | 모델을 순차적으로 회전 | +| **우선순위** | 항상 첫 번째 모델을 시도합니다. 오류가 발생한 경우에만 폴백 | +| **랜덤** | 각 요청에 대한 콤보에서 무작위 모델 선택 | +| **가중치** | 모델별로 할당된 가중치를 기준으로 비례적으로 라우팅 | +| **가장 적게 사용됨** | 최근 요청이 가장 적은 모델로 라우팅(콤보 메트릭 사용) | +| **비용 최적화** | 가장 저렴한 모델로 연결(가격표 사용) | + +글로벌 콤보 기본값은 **대시보드 → 설정 → 라우팅 → 콤보 기본값**에서 설정할 수 있습니다. + +--- + +### 건강 대시보드 + +**대시보드 → 건강**을 통해 액세스합니다. 6개의 카드를 사용한 실시간 시스템 상태 개요: + +| 카드 | 표시되는 내용 | +| ------------------ | ----------------------------------------------- | +| **시스템 상태** | 가동 시간, 버전, 메모리 사용량, 데이터 디렉터리 | +| **제공자 건강** | 공급자별 회로 차단기 상태(폐쇄/개방/반개방) | +| **비율 제한** | 남은 시간에 따른 계정당 활성 속도 제한 쿨다운 | +| **활성 잠금** | 잠금 정책으로 인해 일시적으로 차단된 제공업체 | +| **서명 캐시** | 중복 제거 캐시 통계(활성 키, 적중률) | +| **지연 원격 측정** | 공급자별 p50/p95/p99 대기 시간 집계 | + +**프로 팁:** 상태 페이지는 10초마다 자동으로 새로 고쳐집니다. 회로 차단기 카드를 사용하여 어떤 공급자가 문제를 겪고 있는지 식별하십시오. diff --git a/docs/i18n/ms/API_REFERENCE.md b/docs/i18n/ms/API_REFERENCE.md new file mode 100644 index 0000000000..0c70b4dad8 --- /dev/null +++ b/docs/i18n/ms/API_REFERENCE.md @@ -0,0 +1,441 @@ +# Rujukan API + +🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md) + +Rujukan lengkap untuk semua titik akhir API OmniRoute. + +--- + +## Jadual Kandungan + +- [Chat Completions](#chat-completions) +- [Embeddings](#embeddings) +- [Image Generation](#image-generation) +- [List Models](#list-models) +- [Compatibility Endpoints](#compatibility-endpoints) +- [Semantic Cache](#semantic-cache) +- [Dashboard & Management](#dashboard--management) +- [Request Processing](#request-processing) +- [Authentication](#authentication) + +--- + +## Selesai Sembang + +```bash +POST /v1/chat/completions +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "cc/claude-opus-4-6", + "messages": [ + {"role": "user", "content": "Write a function to..."} + ], + "stream": true +} +``` + +### Pengepala Tersuai + +| Pengepala | Arah | Penerangan | +| ------------------------ | ------------ | ------------------------------------------- | +| `X-OmniRoute-No-Cache` | Permintaan | Tetapkan kepada `true` untuk memintas cache | +| `X-OmniRoute-Progress` | Permintaan | Tetapkan kepada `true` untuk acara kemajuan | +| `Idempotency-Key` | Permintaan | Kekunci dedup (tetingkap 5s) | +| `X-Request-Id` | Permintaan | Kunci pelupusan alternatif | +| `X-OmniRoute-Cache` | Maklum balas | `HIT` atau `MISS` (bukan penstriman) | +| `X-OmniRoute-Idempotent` | Maklum balas | `true` jika dinyahduplikasi | +| `X-OmniRoute-Progress` | Maklum balas | `enabled` jika penjejakan kemajuan pada | + +--- + +## Pembenaman + +```bash +POST /v1/embeddings +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "nebius/Qwen/Qwen3-Embedding-8B", + "input": "The food was delicious" +} +``` + +Pembekal yang tersedia: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA. + +```bash +# List all embedding models +GET /v1/embeddings +``` + +--- + +## Penjanaan Imej + +```bash +POST /v1/images/generations +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "openai/dall-e-3", + "prompt": "A beautiful sunset over mountains", + "size": "1024x1024" +} +``` + +Pembekal tersedia: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI. + +```bash +# List all image models +GET /v1/images/generations +``` + +--- + +## Senaraikan Model + +```bash +GET /v1/models +Authorization: Bearer your-api-key + +→ Returns all chat, embedding, and image models + combos in OpenAI format +``` + +--- + +## Titik Akhir Keserasian + +| Kaedah | Laluan | Format | +| -------- | --------------------------- | ----------------------- | +| POS | `/v1/chat/completions` | OpenAI | +| POS | `/v1/messages` | Antroppik | +| POS | `/v1/responses` | Respons OpenAI | +| POS | `/v1/embeddings` | OpenAI | +| POS | `/v1/images/generations` | OpenAI | +| DAPATKAN | `/v1/models` | OpenAI | +| POS | `/v1/messages/count_tokens` | Antroppik | +| DAPATKAN | `/v1beta/models` | Gemini | +| POS | `/v1beta/models/{...path}` | Gemini menjanaKandungan | +| POS | `/v1/api/chat` | Ollama | + +### Laluan Penyedia Khusus + +```bash +POST /v1/providers/{provider}/chat/completions +POST /v1/providers/{provider}/embeddings +POST /v1/providers/{provider}/images/generations +``` + +Awalan pembekal ditambah secara automatik jika tiada. Model tidak sepadan mengembalikan `400`. + +--- + +## Cache Semantik + +```bash +# Get cache stats +GET /api/cache + +# Clear all caches +DELETE /api/cache +``` + +Contoh jawapan: + +```json +{ + "semanticCache": { + "memorySize": 42, + "memoryMaxSize": 500, + "dbSize": 128, + "hitRate": 0.65 + }, + "idempotency": { + "activeKeys": 3, + "windowMs": 5000 + } +} +``` + +--- + +## Papan Pemuka & Pengurusan + +### Pengesahan + +| Titik akhir | Kaedah | Penerangan | +| ----------------------------- | -------------- | -------------------------- | +| `/api/auth/login` | POS | Log masuk | +| `/api/auth/logout` | POS | Log keluar | +| `/api/settings/require-login` | DAPATKAN/LETAK | Togol log masuk diperlukan | + +### Pengurusan Pembekal + +| Titik akhir | Kaedah | Penerangan | +| ---------------------------- | -------------------- | --------------------------- | +| `/api/providers` | DAPATKAN/POS | Senaraikan / buat pembekal | +| `/api/providers/[id]` | DAPATKAN/LETAK/PADAM | Urus pembekal | +| `/api/providers/[id]/test` | POS | Sambungan pembekal ujian | +| `/api/providers/[id]/models` | DAPATKAN | Senaraikan model pembekal | +| `/api/providers/validate` | POS | Sahkan konfigurasi pembekal | +| `/api/provider-nodes*` | Pelbagai | Pengurusan nod pembekal | +| `/api/provider-models` | DAPATKAN/POST/PADAM | Model tersuai | + +### Aliran OAuth + +| Titik akhir | Kaedah | Penerangan | +| -------------------------------- | -------- | --------------------- | +| `/api/oauth/[provider]/[action]` | Pelbagai | OAuth khusus pembekal | + +### Penghalaan & Konfigurasi + +| Titik akhir | Kaedah | Penerangan | +| --------------------- | ------------ | ------------------------------------- | +| `/api/models/alias` | DAPATKAN/POS | Alias ​​model | +| `/api/models/catalog` | DAPATKAN | Semua model mengikut pembekal + jenis | +| `/api/combos*` | Pelbagai | Pengurusan kombo | +| `/api/keys*` | Pelbagai | Pengurusan kunci API | +| `/api/pricing` | DAPATKAN | Harga model | + +### Penggunaan & Analitis + +| Titik akhir | Kaedah | Penerangan | +| --------------------------- | -------- | --------------------------- | +| `/api/usage/history` | DAPATKAN | Sejarah penggunaan | +| `/api/usage/logs` | DAPATKAN | Log penggunaan | +| `/api/usage/request-logs` | DAPATKAN | Log peringkat permintaan | +| `/api/usage/[connectionId]` | DAPATKAN | Penggunaan setiap sambungan | + +### Tetapan + +| Titik akhir | Kaedah | Penerangan | +| ------------------------------- | -------------- | ------------------------------------- | +| `/api/settings` | DAPATKAN/LETAK | Tetapan umum | +| `/api/settings/proxy` | DAPATKAN/LETAK | Konfigurasi proksi rangkaian | +| `/api/settings/proxy/test` | POS | Uji sambungan proksi | +| `/api/settings/ip-filter` | DAPATKAN/LETAK | Senarai dibenarkan/senarai sekatan IP | +| `/api/settings/thinking-budget` | DAPATKAN/LETAK | Belanjawan token penaakulan | +| `/api/settings/system-prompt` | DAPATKAN/LETAK | Gesaan sistem global | + +### Pemantauan + +| Titik akhir | Kaedah | Penerangan | +| ------------------------ | -------------- | --------------------------- | +| `/api/sessions` | DAPATKAN | Penjejakan sesi aktif | +| `/api/rate-limits` | DAPATKAN | Had kadar setiap akaun | +| `/api/monitoring/health` | DAPATKAN | Pemeriksaan kesihatan | +| `/api/cache` | DAPATKAN/PADAM | Statistik cache / kosongkan | + +### Sandaran & Eksport/Import + +| Titik akhir | Kaedah | Penerangan | +| --------------------------- | -------- | -------------------------------------------------------- | +| `/api/db-backups` | DAPATKAN | Senaraikan sandaran yang tersedia | +| `/api/db-backups` | LETAK | Buat sandaran manual | +| `/api/db-backups` | POS | Pulihkan daripada sandaran khusus | +| `/api/db-backups/export` | DAPATKAN | Muat turun pangkalan data sebagai fail .sqlite | +| `/api/db-backups/import` | POS | Muat naik fail .sqlite untuk menggantikan pangkalan data | +| `/api/db-backups/exportAll` | DAPATKAN | Muat turun sandaran penuh sebagai arkib .tar.gz | + +### Penyegerakan Awan + +| Titik akhir | Kaedah | Penerangan | +| ---------------------- | -------- | ------------------------- | +| `/api/sync/cloud` | Pelbagai | Operasi penyegerakan awan | +| `/api/sync/initialize` | POS | Mulakan penyegerakan | +| `/api/cloud/*` | Pelbagai | Pengurusan awan | + +### Alat CLI + +| Titik akhir | Kaedah | Penerangan | +| ---------------------------------- | -------- | ---------------------- | +| `/api/cli-tools/claude-settings` | DAPATKAN | Status CLI Claude | +| `/api/cli-tools/codex-settings` | DAPATKAN | Status Codex CLI | +| `/api/cli-tools/droid-settings` | DAPATKAN | Status Droid CLI | +| `/api/cli-tools/openclaw-settings` | DAPATKAN | Status OpenClaw CLI | +| `/api/cli-tools/runtime/[toolId]` | DAPATKAN | Masa jalan CLI generik | + +Respons CLI termasuk: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. + +### Had Ketahanan & Kadar + +| Titik akhir | Kaedah | Penerangan | +| ----------------------- | -------------- | ------------------------------------ | +| `/api/resilience` | DAPATKAN/LETAK | Dapatkan/kemas kini profil ketahanan | +| `/api/resilience/reset` | POS | Tetapkan semula pemutus litar | +| `/api/rate-limits` | DAPATKAN | Status had kadar setiap akaun | +| `/api/rate-limit` | DAPATKAN | Konfigurasi had kadar global | + +### Evals + +| Titik akhir | Kaedah | Penerangan | +| ------------ | ------------ | ------------------------------------------ | +| `/api/evals` | DAPATKAN/POS | Senaraikan suite eval / penilaian jalankan | + +### Dasar + +| Titik akhir | Kaedah | Penerangan | +| --------------- | ------------------- | --------------------- | +| `/api/policies` | DAPATKAN/POST/PADAM | Urus dasar penghalaan | + +### Pematuhan + +| Titik akhir | Kaedah | Penerangan | +| --------------------------- | -------- | -------------------------------- | +| `/api/compliance/audit-log` | DAPATKAN | Log audit pematuhan (N terakhir) | + +### v1beta (Serasi Gemini) + +| Titik akhir | Kaedah | Penerangan | +| -------------------------- | -------- | ------------------------------------ | +| `/v1beta/models` | DAPATKAN | Senaraikan model dalam format Gemini | +| `/v1beta/models/{...path}` | POS | Gemini `generateContent` titik akhir | + +Titik akhir ini mencerminkan format API Gemini untuk pelanggan yang mengharapkan keserasian SDK Gemini asli. + +### API Dalaman / Sistem + +| Titik akhir | Kaedah | Penerangan | +| --------------- | -------- | ------------------------------------------------------------ | +| `/api/init` | DAPATKAN | Semakan permulaan aplikasi (digunakan pada larian pertama) | +| `/api/tags` | DAPATKAN | Tag model yang serasi dengan Ollama (untuk pelanggan Ollama) | +| `/api/restart` | POS | Pencetus pelayan anggun mulakan semula | +| `/api/shutdown` | POS | Cetuskan penutupan pelayan yang anggun | + +> **Nota:** Titik akhir ini digunakan secara dalaman oleh sistem atau untuk keserasian pelanggan Ollama. Mereka biasanya tidak dipanggil oleh pengguna akhir. + +--- + +## Transkripsi Audio + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data +``` + +Transkripsikan fail audio menggunakan Deepgram atau AssemblyAI. + +**Permintaan:** + +```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" +``` + +**Jawapan:** + +```json +{ + "text": "Hello, this is the transcribed audio content.", + "task": "transcribe", + "language": "en", + "duration": 12.5 +} +``` + +**Pembekal yang disokong:** `deepgram/nova-3`, `assemblyai/best`. + +**Format yang disokong:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +## Keserasian Ollama + +Untuk pelanggan yang menggunakan format API Ollama: + +```bash +# Chat endpoint (Ollama format) +POST /v1/api/chat + +# Model listing (Ollama format) +GET /api/tags +``` + +Permintaan diterjemahkan secara automatik antara Ollama dan format dalaman. + +--- + +## Telemetri + +```bash +# Get latency telemetry summary (p50/p95/p99 per provider) +GET /api/telemetry/summary +``` + +**Jawapan:** + +```json +{ + "providers": { + "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, + "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } + } +} +``` + +--- + +## Belanjawan + +```bash +# Get budget status for all API keys +GET /api/usage/budget + +# Set or update a budget +POST /api/usage/budget +Content-Type: application/json + +{ + "keyId": "key-123", + "limit": 50.00, + "period": "monthly" +} +``` + +--- + +## Ketersediaan Model + +```bash +# Get real-time model availability across all providers +GET /api/models/availability + +# Check availability for a specific model +POST /api/models/availability +Content-Type: application/json + +{ + "model": "claude-sonnet-4-5-20250929" +} +``` + +--- + +## Pemprosesan Permintaan + +1. Pelanggan menghantar permintaan kepada `/v1/*` +2. Pengendali laluan memanggil `handleChat`, `handleEmbedding`, `handleAudioTranscription` atau `handleImageGeneration` +3. Model telah diselesaikan (pembekal langsung/model atau alias/kombo) +4. Bukti kelayakan dipilih daripada DB tempatan dengan penapisan ketersediaan akaun +5. Untuk sembang: `handleChatCore` — pengesanan format, terjemahan, semakan cache, semakan idempotensi +6. Pelaksana pembekal menghantar permintaan huluan +7. Respons diterjemahkan kembali kepada format pelanggan (sembang) atau dikembalikan seperti sedia ada (benam/imej/audio) +8. Penggunaan / pembalakan direkodkan +9. Fallback terpakai pada ralat mengikut peraturan kombo + +Rujukan seni bina penuh: [**OMNI_TOKEN_119**](ARCHITECTURE.md) + +--- + +## Pengesahan + +- Laluan papan pemuka (`/dashboard/*`) gunakan kuki `auth_token` +- Log masuk menggunakan cincang kata laluan yang disimpan; sandar kepada `INITIAL_PASSWORD` +- `requireLogin` boleh togol melalui `/api/settings/require-login` +- `/v1/*` laluan secara pilihan memerlukan kunci API Pembawa apabila `REQUIRE_API_KEY=true` diff --git a/docs/i18n/ms/ARCHITECTURE.md b/docs/i18n/ms/ARCHITECTURE.md new file mode 100644 index 0000000000..896c871f49 --- /dev/null +++ b/docs/i18n/ms/ARCHITECTURE.md @@ -0,0 +1,781 @@ +# Seni Bina OmniRoute + +🌐 **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) + +_Terakhir dikemas kini: 2026-02-18_ + +## Ringkasan Eksekutif + +OmniRoute ialah get laluan dan papan pemuka penghalaan AI tempatan yang dibina pada Next.js. +Ia menyediakan satu titik akhir serasi OpenAI (`/v1/*`) dan mengarahkan trafik merentasi berbilang penyedia huluan dengan terjemahan, sandaran, penyegaran token dan penjejakan penggunaan. + +Keupayaan teras: + +- Permukaan API serasi OpenAI untuk CLI/alat (28 pembekal) +- Permintaan/tindak balas terjemahan merentas format pembekal +- Model kombo mundur (jujukan berbilang model) +- Saling balik peringkat akaun (berbilang akaun setiap pembekal) +- Pengurusan sambungan pembekal kunci OAuth + API +- Membenamkan penjanaan melalui `/v1/embeddings` (6 pembekal, 9 model) +- Penjanaan imej melalui `/v1/images/generations` (4 pembekal, 9 model) +- Penghuraian teg Fikir (`...`) untuk model penaakulan +- Pembersihan tindak balas untuk keserasian OpenAI SDK yang ketat +- Normalisasi peranan (pembangun→sistem, sistem→pengguna) untuk keserasian silang penyedia +- Penukaran output berstruktur (json_schema → Gemini responseSchema) +- Kegigihan setempat untuk pembekal, kunci, alias, kombo, tetapan, harga +- Penjejakan penggunaan/kos dan pengelogan permintaan +- Penyegerakan awan pilihan untuk penyegerakan berbilang peranti/keadaan +- Senarai dibenarkan/senarai sekatan IP untuk kawalan akses API +- Pengurusan belanjawan berfikir (laluan/auto/tersuai/adaptif) +- Suntikan segera sistem global +- Penjejakan sesi dan cap jari +- Pengehadan kadar dipertingkatkan setiap akaun dengan profil khusus pembekal +- Corak pemutus litar untuk daya tahan pembekal +- Perlindungan kumpulan anti-gemuruh dengan penguncian mutex +- Cache penyahduplikasi permintaan berasaskan tandatangan +- Lapisan domain: ketersediaan model, peraturan kos, dasar sandaran, dasar sekat keluar +- Kegigihan keadaan domain (cache tulis-melalui SQLite untuk sandaran, belanjawan, sekatan, pemutus litar) +- Enjin dasar untuk penilaian permintaan terpusat (kunci → belanjawan → sandaran) +- Minta telemetri dengan pengagregatan kependaman p50/p95/p99 +- ID Korelasi (X-Request-Id) untuk pengesanan hujung ke hujung +- Pengelogan audit pematuhan dengan memilih keluar setiap kunci API +- Rangka kerja Eval untuk jaminan kualiti LLM +- Papan pemuka UI Ketahanan dengan status pemutus litar masa nyata +- Pembekal OAuth modular (12 modul individu di bawah `src/lib/oauth/providers/`) + +Model masa jalan utama: + +- Laluan apl Next.js di bawah `src/app/api/*` melaksanakan kedua-dua API papan pemuka dan API keserasian +- SSE kongsi/tera laluan dalam `src/sse/*` + `open-sse/*` mengendalikan pelaksanaan pembekal, terjemahan, penstriman, sandaran dan penggunaan + +## Skop dan Sempadan + +### Dalam Skop + +- Masa jalan gerbang tempatan +- API pengurusan papan pemuka +- Pengesahan pembekal dan penyegaran token +- Minta terjemahan dan penstriman SSE +- Keadaan setempat + kegigihan penggunaan +- Orkestrasi penyegerakan awan pilihan + +### Di Luar Skop + +- Pelaksanaan perkhidmatan awan di belakang `NEXT_PUBLIC_CLOUD_URL` +- Pembekal SLA/pesawat kawalan di luar proses tempatan +- Perduaan CLI luaran sendiri (Claude CLI, Codex CLI, dll.) + +## Konteks Sistem Aras Tinggi + +```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 +``` + +## Komponen Masa Jalan Teras + +## 1) API dan Lapisan Penghalaan (Laluan Apl Next.js) + +Direktori utama: + +- `src/app/api/v1/*` dan `src/app/api/v1beta/*` untuk API keserasian +- `src/app/api/*` untuk API pengurusan/konfigurasi +- Seterusnya menulis semula dalam peta `next.config.mjs` `/v1/*` kepada `/api/v1/*` + +Laluan keserasian penting: + +- `src/app/api/v1/chat/completions/route.ts` +- `src/app/api/v1/messages/route.ts` +- `src/app/api/v1/responses/route.ts` +- `src/app/api/v1/models/route.ts` — termasuk model tersuai dengan `custom: true` +- `src/app/api/v1/embeddings/route.ts` — penjanaan benam (6 pembekal) +- `src/app/api/v1/images/generations/route.ts` — penjanaan imej (4+ penyedia termasuk Antigraviti/Nebius) +- `src/app/api/v1/messages/count_tokens/route.ts` +- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — sembang khusus bagi setiap pembekal +- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — benam setiap pembekal khusus +- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — imej setiap pembekal khusus +- `src/app/api/v1beta/models/route.ts` +- `src/app/api/v1beta/models/[...path]/route.ts` + +Domain pengurusan: + +- Pengesahan/tetapan: `src/app/api/auth/*`, `src/app/api/settings/*` +- Pembekal/sambungan: `src/app/api/providers*` +- Nod pembekal: `src/app/api/provider-nodes*` +- Model tersuai: `src/app/api/provider-models` (DAPAT/POS/PADAM) +- Katalog model: `src/app/api/models/catalog` (GET) +- Konfigurasi proksi: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST) +- OAuth: `src/app/api/oauth/*` +- Kunci/alias/kombo/harga: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing` +- Penggunaan: `src/app/api/usage/*` +- Penyegerakan/awan: `src/app/api/sync/*`, `src/app/api/cloud/*` +- Pembantu perkakas CLI: `src/app/api/cli-tools/*` +- Penapis IP: `src/app/api/settings/ip-filter` (GET/PUT) +- Belanjawan berfikir: `src/app/api/settings/thinking-budget` (GET/PUT) +- Gesaan sistem: `src/app/api/settings/system-prompt` (GET/PUT) +- Sesi: `src/app/api/sessions` (GET) +- Had kadar: `src/app/api/rate-limits` (GET) +- Ketahanan: `src/app/api/resilience` (GET/PATCH) — profil pembekal, pemutus litar, keadaan had kadar +- Tetapan semula daya tahan: `src/app/api/resilience/reset` (POST) — set semula pemutus + cooldown +- Statistik cache: `src/app/api/cache/stats` (DAPAT/DELETE) +- Ketersediaan model: `src/app/api/models/availability` (GET/POST) +- Telemetri: `src/app/api/telemetry/summary` (GET) +- Belanjawan: `src/app/api/usage/budget` (DAPAT/POS) +- Rantaian mundur: `src/app/api/fallback/chains` (DAPAT/POST/PADAM) +- Audit pematuhan: `src/app/api/compliance/audit-log` (GET) +- Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET) +- Dasar: `src/app/api/policies` (DAPAT/POS) + +## 2) SSE + Teras Terjemahan + +Modul aliran utama: + +- Kemasukan: `src/sse/handlers/chat.ts` +- Orkestrasi teras: `open-sse/handlers/chatCore.ts` +- Penyesuai pelaksanaan pembekal: `open-sse/executors/*` +- Konfigurasi pengesanan format/pembekal: `open-sse/services/provider.ts` +- Penghuraian/penyelesaian model: `src/sse/services/model.ts`, `open-sse/services/model.ts` +- Logik sandaran akaun: `open-sse/services/accountFallback.ts` +- Pendaftaran terjemahan: `open-sse/translator/index.ts` +- Transformasi strim: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts` +- Pengekstrakan/penormalan penggunaan: `open-sse/utils/usageTracking.ts` +- Penghurai teg Fikir: `open-sse/utils/thinkTagParser.ts` +- Pengendali benam: `open-sse/handlers/embeddings.ts` +- Membenamkan pendaftaran pembekal: `open-sse/config/embeddingRegistry.ts` +- Pengendali penjanaan imej: `open-sse/handlers/imageGeneration.ts` +- Pendaftaran pembekal imej: `open-sse/config/imageRegistry.ts` +- Pembersihan tindak balas: `open-sse/handlers/responseSanitizer.ts` +- Normalisasi peranan: `open-sse/services/roleNormalizer.ts` + +Perkhidmatan (logik perniagaan): + +- Pemilihan/pemarkahan akaun: `open-sse/services/accountSelector.ts` +- Pengurusan kitaran hayat konteks: `open-sse/services/contextManager.ts` +- Penguatkuasaan penapis IP: `open-sse/services/ipFilter.ts` +- Penjejakan sesi: `open-sse/services/sessionManager.ts` +- Minta penduaan: `open-sse/services/signatureCache.ts` +- Suntikan gesaan sistem: `open-sse/services/systemPrompt.ts` +- Pemikiran pengurusan belanjawan: `open-sse/services/thinkingBudget.ts` +- Penghalaan model kad liar: `open-sse/services/wildcardRouter.ts` +- Pengurusan had kadar: `open-sse/services/rateLimitManager.ts` +- Pemutus litar: `open-sse/services/circuitBreaker.ts` + +Modul lapisan domain: + +- Ketersediaan model: `src/lib/domain/modelAvailability.ts` +- Peraturan/belanjawan kos: `src/lib/domain/costRules.ts` +- Dasar mundur: `src/lib/domain/fallbackPolicy.ts` +- Penyelesai kombo: `src/lib/domain/comboResolver.ts` +- Dasar penguncian: `src/lib/domain/lockoutPolicy.ts` +- Enjin dasar: `src/domain/policyEngine.ts` — kunci keluar berpusat → belanjawan → penilaian mundur +- Katalog kod ralat: `src/lib/domain/errorCodes.ts` +- ID Permintaan: `src/lib/domain/requestId.ts` +- Ambil tamat masa: `src/lib/domain/fetchTimeout.ts` +- Permintaan telemetri: `src/lib/domain/requestTelemetry.ts` +- Pematuhan/audit: `src/lib/domain/compliance/index.ts` +- Pelari eval: `src/lib/domain/evalRunner.ts` +- Kegigihan keadaan domain: `src/lib/db/domainState.ts` — SQLite CRUD untuk rantaian sandaran, belanjawan, sejarah kos, keadaan sekat keluar, pemutus litar + +Modul pembekal OAuth (12 fail individu di bawah `src/lib/oauth/providers/`): + +- Indeks pendaftaran: `src/lib/oauth/providers/index.ts` +- Pembekal individu: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, \_\_OMNI_9TOKEN `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts` +- Pembalut nipis: `src/lib/oauth/providers.ts` — eksport semula daripada modul individu + +## 3) Lapisan Kegigihan + +DB keadaan utama: + +- `src/lib/localDb.ts` +- fail: `${DATA_DIR}/db.json` (atau `$XDG_CONFIG_HOME/omniroute/db.json` apabila ditetapkan, jika tidak `~/.omniroute/db.json`) +- entiti: providerConnections, providerNodes, modelAliases, combo, apiKeys, tetapan, harga, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt** + +Penggunaan DB: + +- `src/lib/usageDb.ts` +- fail: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- mengikut dasar direktori asas yang sama seperti `localDb` (`DATA_DIR`, kemudian `XDG_CONFIG_HOME/omniroute` apabila ditetapkan) +- diuraikan kepada sub-modul terfokus: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts` + +DB Keadaan Domain (SQLite): + +- `src/lib/db/domainState.ts` — Operasi CRUD untuk keadaan domain +- Jadual (dicipta dalam `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers` +- Corak cache tulis-lalu: Peta dalam ingatan adalah berwibawa pada masa jalan; mutasi ditulis serentak kepada SQLite; keadaan dipulihkan daripada DB pada permulaan sejuk + +## 4) Auth + Security Surfaces + +- Pengesahan kuki papan pemuka: `src/proxy.ts`, `src/app/api/auth/login/route.ts` +- Penjanaan/pengesahan kunci API: `src/shared/utils/apiKey.ts` +- Rahsia pembekal kekal dalam entri `providerConnections` +- Sokongan proksi keluar melalui `open-sse/utils/proxyFetch.ts` (env vars) dan `open-sse/utils/networkProxy.ts` (boleh dikonfigurasikan setiap pembekal atau global) + +## 5) Penyegerakan Awan + +- Penjadual init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts` +- Tugasan berkala: `src/shared/services/cloudSyncScheduler.ts` +- Laluan kawalan: `src/app/api/sync/cloud/route.ts` + +## Permintaan Kitaran Hayat (`/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 +``` + +## Kombo + Aliran Saling Balik Akaun + +```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] +``` + +Keputusan sandaran didorong oleh `open-sse/services/accountFallback.ts` menggunakan kod status dan heuristik mesej ralat. + +## OAuth Onboarding dan Kitaran Hayat Penyegaran Token + +```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 +``` + +Muat semula semasa trafik langsung dilaksanakan di dalam `open-sse/handlers/chatCore.ts` melalui pelaksana `refreshCredentials()`. + +## Kitaran Hayat Penyegerakan Awan (Dayakan / Segerakkan / Lumpuhkan) + +```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 +``` + +Penyegerakan berkala dicetuskan oleh `CloudSyncScheduler` apabila awan didayakan. + +## Model Data dan Peta Storan + +```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 + } +``` + +Fail storan fizikal: + +- keadaan utama: `${DATA_DIR}/db.json` (atau `$XDG_CONFIG_HOME/omniroute/db.json` apabila ditetapkan, jika tidak `~/.omniroute/db.json`) +- statistik penggunaan: `${DATA_DIR}/usage.json` +- permintaan baris log: `${DATA_DIR}/log.txt` +- pilihan penterjemah/permintaan sesi nyahpepijat: `/logs/...` + +## Topologi Penerapan + +```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 +``` + +## Pemetaan Modul (Keputusan-Kritis) + +### Laluan dan Modul API + +- `src/app/api/v1/*`, `src/app/api/v1beta/*`: API keserasian +- `src/app/api/v1/providers/[provider]/*`: laluan khusus setiap pembekal (sembang, benam, imej) +- `src/app/api/providers*`: penyedia CRUD, pengesahan, ujian +- `src/app/api/provider-nodes*`: pengurusan nod serasi tersuai +- `src/app/api/provider-models`: pengurusan model tersuai (CRUD) +- `src/app/api/models/catalog`: API katalog model penuh (semua jenis dikumpulkan mengikut pembekal) +- `src/app/api/oauth/*`: Aliran OAuth/kod peranti +- `src/app/api/keys*`: kitaran hayat kunci API tempatan +- `src/app/api/models/alias`: pengurusan alias +- `src/app/api/combos*`: pengurusan kombo sandaran +- `src/app/api/pricing`: penentuan harga untuk pengiraan kos +- `src/app/api/settings/proxy`: konfigurasi proksi (GET/PUT/DELETE) +- `src/app/api/settings/proxy/test`: ujian sambungan proksi keluar (POST) +- `src/app/api/usage/*`: API penggunaan dan log +- `src/app/api/sync/*` + `src/app/api/cloud/*`: penyegerakan awan dan pembantu yang menghadap awan +- `src/app/api/cli-tools/*`: penulis/pemeriksa konfigurasi CLI tempatan +- `src/app/api/settings/ip-filter`: Senarai dibenarkan/senarai sekat IP (GET/PUT) +- `src/app/api/settings/thinking-budget`: konfigurasi belanjawan token pemikiran (GET/PUT) +- `src/app/api/settings/system-prompt`: gesaan sistem global (GET/PUT) +- `src/app/api/sessions`: penyenaraian sesi aktif (GET) +- `src/app/api/rate-limits`: status had kadar setiap akaun (GET) + +### Penghalaan dan Teras Pelaksanaan + +- `src/sse/handlers/chat.ts`: menghuraikan permintaan, pengendalian kombo, gelung pemilihan akaun +- `open-sse/handlers/chatCore.ts`: terjemahan, penghantaran pelaksana, cuba semula/segar semula pengendalian, persediaan strim +- `open-sse/executors/*`: rangkaian khusus pembekal dan tingkah laku format + +### Pendaftar Terjemahan dan Penukar Format + +- `open-sse/translator/index.ts`: pendaftaran penterjemah dan orkestrasi +- Minta penterjemah: `open-sse/translator/request/*` +- Penterjemah respons: `open-sse/translator/response/*` +- Pemalar format: `open-sse/translator/formats.ts` + +### Kegigihan + +- `src/lib/localDb.ts`: konfigurasi/keadaan berterusan +- `src/lib/usageDb.ts`: sejarah penggunaan dan log permintaan bergulir + +## Liputan Pelaksana Penyedia (Corak Strategi) + +Setiap pembekal mempunyai pelaksana khusus yang memanjangkan `BaseExecutor` (dalam `open-sse/executors/base.ts`), yang menyediakan pembinaan URL, pembinaan pengepala, cuba semula dengan pengunduran eksponen, cangkuk penyegaran semula kelayakan dan kaedah orkestra `execute()`. + +| Pelaksana | Pembekal | Pengendalian Khas | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | +| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | URL dinamik/konfigurasi pengepala bagi setiap pembekal | +| `AntigravityExecutor` | Antigraviti Google | ID projek/sesi tersuai, Cuba Semula-Selepas menghuraikan | +| `CodexExecutor` | OpenAI Codex | Menyuntik arahan sistem, memaksa usaha penaakulan | +| `CursorExecutor` | IDE kursor | Protokol ConnectRPC, pengekodan Protobuf, tandatangan permintaan melalui checksum | +| `GithubExecutor` | GitHub Copilot | Penyegaran token salinan, pengepala meniru VSCode | +| `KiroExecutor` | AWS CodeWhisperer/Kiro | Format binari AWS EventStream → penukaran SSE | +| `GeminiCLIExecutor` | Gemini CLI | Kitaran muat semula token Google OAuth | + +Semua pembekal lain (termasuk nod serasi tersuai) menggunakan `DefaultExecutor`. + +## Matriks Keserasian Pembekal + +| Pembekal | Format | Pengesahan | Strim | Bukan Strim | Token Refresh | API Penggunaan | +| ---------------- | -------------- | --------------------- | ---------------- | ----------- | ------------- | -------------------- | +| Claude | claude | Kunci API / OAuth | ✅ | ✅ | ✅ | ⚠️ Admin sahaja | +| Gemini | gemini | Kunci API / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | +| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | +| Antigraviti | antigraviti | OAuth | ✅ | ✅ | ✅ | ✅ API kuota penuh | +| OpenAI | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| Codex | openai-respons | OAuth | ✅ terpaksa | ❌ | ✅ | ✅ Had kadar | +| GitHub Copilot | openai | OAuth + Token Copilot | ✅ | ✅ | ✅ | ✅ Gambar kuota | +| Kursor | kursor | Jumlah semak tersuai | ✅ | ✅ | ❌ | ❌ | +| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Had penggunaan | +| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Setiap permintaan | +| iFlow | openai | OAuth (Asas) | ✅ | ✅ | ✅ | ⚠️ Setiap permintaan | +| OpenRouter | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| GLM/Kimi/MiniMax | claude | Kunci API | ✅ | ✅ | ❌ | ❌ | +| DeepSeek | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| Groq | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| xAI (Grok) | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| Mistral | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| Kebingungan | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| Bersama AI | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| Bunga Api AI | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| Serebral | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| Cohere | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | +| NVIDIA NIM | openai | Kunci API | ✅ | ✅ | ❌ | ❌ | + +## Liputan Terjemahan Format + +Format sumber yang dikesan termasuk: + +- `openai` +- `openai-responses` +- `claude` +- `gemini` + +Format sasaran termasuk: + +- Sembang/Respons OpenAI +- Claude +- Sampul surat Gemini/Gemini-CLI/Antigraviti +- Kiro +- Kursor + +Terjemahan menggunakan **OpenAI sebagai format hab** — semua penukaran melalui OpenAI sebagai perantaraan: + +``` +Source Format → OpenAI (hub) → Target Format +``` + +Terjemahan dipilih secara dinamik berdasarkan bentuk muatan sumber dan format sasaran pembekal. + +Lapisan pemprosesan tambahan dalam saluran paip terjemahan: + +- **Pembersihan respons** — Menghapuskan medan bukan standard daripada respons format OpenAI (kedua-dua penstriman dan bukan penstriman) untuk memastikan pematuhan SDK yang ketat +- **Penormalan peranan** — Menukar `developer` → `system` untuk sasaran bukan OpenAI; menggabungkan `system` → `user` untuk model yang menolak peranan sistem (GLM, ERNIE) +- **Fikirkan pengekstrakan teg** — Menghuraikan `...` blok daripada kandungan ke dalam medan `reasoning_content` +- **Output berstruktur** — Menukar OpenAI `response_format.json_schema` kepada `responseMimeType` + `responseSchema` Gemini + +## Titik Akhir API Disokong + +| Titik akhir | Format | Pengendali | +| -------------------------------------------------- | -------------------- | --------------------------------------------------- | +| `POST /v1/chat/completions` | Sembang OpenAI | `src/sse/handlers/chat.ts` | +| `POST /v1/messages` | Mesej Claude | Pengendali yang sama (dikesan secara automatik) | +| `POST /v1/responses` | Respons OpenAI | `open-sse/handlers/responsesHandler.ts` | +| `POST /v1/embeddings` | Pembenaman OpenAI | `open-sse/handlers/embeddings.ts` | +| `GET /v1/embeddings` | Penyenaraian model | Laluan API | +| `POST /v1/images/generations` | Imej OpenAI | `open-sse/handlers/imageGeneration.ts` | +| `GET /v1/images/generations` | Penyenaraian model | Laluan API | +| `POST /v1/providers/{provider}/chat/completions` | Sembang OpenAI | Khas bagi setiap pembekal dengan pengesahan model | +| `POST /v1/providers/{provider}/embeddings` | Pembenaman OpenAI | Khusus bagi setiap pembekal dengan pengesahan model | +| `POST /v1/providers/{provider}/images/generations` | Imej OpenAI | Khusus bagi setiap pembekal dengan pengesahan model | +| `POST /v1/messages/count_tokens` | Kiraan Token Claude | Laluan API | +| `GET /v1/models` | Senarai Model OpenAI | Laluan API (sembang + benam + imej + model tersuai) | +| `GET /api/models/catalog` | Katalog | Semua model dikumpulkan mengikut pembekal + jenis | +| `POST /v1beta/models/*:streamGenerateContent` | Gemini asli | Laluan API | +| `GET/PUT/DELETE /api/settings/proxy` | Konfigurasi Proksi | Konfigurasi proksi rangkaian | +| `POST /api/settings/proxy/test` | Kesambungan Proksi | Titik akhir ujian kesihatan/ketersambungan proksi | +| `GET/POST/DELETE /api/provider-models` | Model Tersuai | Pengurusan model tersuai setiap pembekal | + +## Pengendali Pintasan + +Pengendali pintasan (`open-sse/utils/bypassHandler.ts`) memintas permintaan "buang" yang diketahui daripada Claude CLI — ping pemanasan, pengekstrakan tajuk dan kiraan token — dan mengembalikan **tindak balas palsu** tanpa menggunakan token penyedia huluan. Ini dicetuskan hanya apabila `User-Agent` mengandungi `claude-cli`. + +## Permintaan Talian Logger + +Logger permintaan (`open-sse/utils/requestLogger.ts`) menyediakan saluran paip pengelogan nyahpepijat 7 peringkat, dilumpuhkan secara lalai, didayakan melalui `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 +``` + +Fail ditulis kepada `/logs//` untuk setiap sesi permintaan. + +## Mod Kegagalan dan Ketahanan + +## 1) Ketersediaan Akaun/Pembekal + +- cooldown akaun pembekal pada ralat sementara/kadar/auth +- sandaran akaun sebelum permintaan gagal +- sandaran model kombo apabila model semasa/laluan pembekal telah habis + +## 2) Tamat Tempoh Token + +- prasemak dan muat semula dengan mencuba semula untuk pembekal yang boleh dimuat semula +- 401/403 cuba semula selepas percubaan muat semula dalam laluan teras + +## 3) Keselamatan Aliran + +- pengawal strim sedar putus sambungan +- strim terjemahan dengan siram hujung strim dan pengendalian `[DONE]` +- sandaran anggaran penggunaan apabila metadata penggunaan pembekal tiada + +## 4) Kemerosotan Penyegerakan Awan + +- ralat penyegerakan muncul tetapi masa jalan tempatan diteruskan +- penjadual mempunyai logik yang mampu mencuba semula, tetapi pelaksanaan berkala pada masa ini memanggil penyegerakan percubaan tunggal secara lalai + +## 5) Integriti Data + +- Penghijrahan/pembaikan bentuk DB untuk kunci yang hilang +- perlindungan semula JSON yang rosak untuk localDb dan usageDb + +## Kebolehlihatan dan Isyarat Operasi + +Sumber keterlihatan masa jalan: + +- log konsol daripada `src/sse/utils/logger.ts` +- agregat penggunaan setiap permintaan dalam `usage.json` +- log masuk status permintaan teks `log.txt` +- log permintaan/terjemahan dalam pilihan di bawah `logs/` apabila `ENABLE_REQUEST_LOGS=true` +- titik akhir penggunaan papan pemuka (`/api/usage/*`) untuk penggunaan UI + +## Sempadan Sensitif Keselamatan + +- Rahsia JWT (`JWT_SECRET`) menjamin pengesahan/penandatanganan kuki sesi papan pemuka +- Saling balik kata laluan awal (`INITIAL_PASSWORD`, lalai `123456`) mesti ditindih dalam penggunaan sebenar +- Rahsia HMAC kunci API (`API_KEY_SECRET`) menjamin format kunci API tempatan yang dijana +- Rahsia pembekal (kunci/token API) dikekalkan dalam DB tempatan dan harus dilindungi pada peringkat sistem fail +- Titik akhir penyegerakan awan bergantung pada pengesahan kunci API + semantik id mesin + +## Persekitaran dan Matriks Masa Jalan + +Pembolehubah persekitaran digunakan secara aktif oleh kod: + +- Apl/auth: `JWT_SECRET`, `INITIAL_PASSWORD` +- Storan: `DATA_DIR` +- Tingkah laku nod yang serasi: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` +- Penggantian asas storan pilihan (Linux/macOS apabila `DATA_DIR` dinyahset): `XDG_CONFIG_HOME` +- Pencincangan keselamatan: `API_KEY_SECRET`, `MACHINE_ID_SALT` +- Pembalakan: `ENABLE_REQUEST_LOGS` +- URL penyegerakan/awan: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL` +- Proksi keluar: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` dan varian huruf kecil +- Bendera ciri SOCKS5: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` +- Pembantu platform/masa jalanan (bukan konfigurasi khusus apl): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME` + +## Nota Seni Bina Terkenal + +1. `usageDb` dan `localDb` kini berkongsi dasar direktori asas yang sama (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) dengan pemindahan fail lama. +2. `/api/v1/route.ts` mengembalikan senarai model statik dan bukan sumber model utama yang digunakan oleh `/v1/models`. +3. Permintaan logger menulis tajuk/badan penuh apabila didayakan; anggap direktori log sebagai sensitif. +4. Gelagat awan bergantung pada `NEXT_PUBLIC_BASE_URL` dan kebolehcapaian titik akhir awan yang betul. +5. Direktori `open-sse/` diterbitkan sebagai `@omniroute/open-sse` **pakej ruang kerja npm**. Kod sumber mengimportnya melalui `@omniroute/open-sse/...` (diselesaikan oleh Next.js `transpilePackages`). Laluan fail dalam dokumen ini masih menggunakan nama direktori `open-sse/` untuk konsistensi. +6. Carta dalam papan pemuka menggunakan **Recharts** (berasaskan SVG) untuk visualisasi analitik interaktif yang boleh diakses (carta bar penggunaan model, jadual pecahan pembekal dengan kadar kejayaan). +7. Ujian E2E menggunakan **Playwright** (`tests/e2e/`), dijalankan melalui `npm run test:e2e`. Ujian unit menggunakan **Node.js test runner** (`tests/unit/`), dijalankan melalui `npm run test:plan3`. Kod sumber di bawah `src/` ialah **TypeScript** (`.ts`/`.tsx`); ruang kerja `open-sse/` kekal sebagai JavaScript (`.js`). +8. Halaman tetapan disusun dalam 5 tab: Keselamatan, Penghalaan (6 strategi global: isikan dahulu, round-robin, p2c, rawak, paling kurang digunakan, dioptimumkan kos), Ketahanan (had kadar boleh diedit, pemutus litar, dasar), AI (belanjawan berfikir, gesaan sistem, cache segera), Lanjutan (proksi). + +## Senarai Semak Pengesahan Operasi + +- Bina daripada sumber: `npm run build` +- Bina imej Docker: `docker build -t omniroute .` +- Mulakan perkhidmatan dan sahkan: +- `GET /api/settings` +- `GET /api/v1/models` +- URL asas sasaran CLI hendaklah `http://:20128/v1` apabila `PORT=20128` diff --git a/docs/i18n/ms/CODEBASE_DOCUMENTATION.md b/docs/i18n/ms/CODEBASE_DOCUMENTATION.md new file mode 100644 index 0000000000..dea070d3e4 --- /dev/null +++ b/docs/i18n/ms/CODEBASE_DOCUMENTATION.md @@ -0,0 +1,589 @@ +# omniroute — Dokumentasi Pangkalan Kod + +🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md) + +> Panduan komprehensif dan mesra pemula kepada penghala proksi AI **omniroute** berbilang pembekal. + +--- + +## 1. Apakah itu omniroute? + +omniroute ialah **penghala proksi** yang terletak di antara klien AI (Claude CLI, Codex, Cursor IDE, dll.) dan penyedia AI (Anthropic, Google, OpenAI, AWS, GitHub, dsb.). Ia menyelesaikan satu masalah besar: + +> **Pelanggan AI yang berbeza bercakap "bahasa" yang berbeza (format API), dan pembekal AI yang berbeza juga mengharapkan "bahasa" yang berbeza.** omniroute menterjemah antara mereka secara automatik. + +Anggaplah ia seperti penterjemah universal di Pertubuhan Bangsa-Bangsa Bersatu — mana-mana perwakilan boleh bercakap apa-apa bahasa, dan penterjemah menukarnya untuk mana-mana perwakilan lain. + +--- + +## 2. Gambaran Keseluruhan Seni Bina + +```mermaid +graph LR + subgraph Clients + A[Claude CLI] + B[Codex] + C[Cursor IDE] + D[OpenAI-compatible] + end + + subgraph omniroute + E[Handler Layer] + F[Translator Layer] + G[Executor Layer] + H[Services Layer] + end + + subgraph Providers + I[Anthropic Claude] + J[Google Gemini] + K[OpenAI / Codex] + L[GitHub Copilot] + M[AWS Kiro] + N[Antigravity] + O[Cursor API] + end + + A --> E + B --> E + C --> E + D --> E + E --> F + F --> G + G --> I + G --> J + G --> K + G --> L + G --> M + G --> N + G --> O + H -.-> E + H -.-> G +``` + +### Prinsip Teras: Terjemahan Hub-and-Spoke + +Semua terjemahan format melalui **format OpenAI sebagai hab**: + +``` +Client Format → [OpenAI Hub] → Provider Format (request) +Provider Format → [OpenAI Hub] → Client Format (response) +``` + +Ini bermakna anda hanya memerlukan **N penterjemah** (satu setiap format) dan bukannya **N²** (setiap pasangan). + +--- + +## 3. Struktur Projek + +``` +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 +``` + +--- + +## 4. Pecahan Modul demi Modul + +### 4.1 Konfigurasi (`open-sse/config/`) + +**Sumber tunggal kebenaran** untuk semua konfigurasi pembekal. + +| Fail | Tujuan | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `constants.ts` | `PROVIDERS` objek dengan URL asas, bukti kelayakan OAuth (lalai), pengepala dan gesaan sistem lalai untuk setiap pembekal. Juga mentakrifkan `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG` dan `SKIP_PATTERNS`. | +| `credentialLoader.ts` | Memuatkan bukti kelayakan luaran daripada `data/provider-credentials.json` dan menggabungkannya pada lalai berkod keras dalam `PROVIDERS`. Menyimpan rahsia di luar kawalan sumber sambil mengekalkan keserasian ke belakang. | +| `providerModels.ts` | Pendaftaran model pusat: alias penyedia peta → ID model. Berfungsi seperti `getModels()`, `getProviderByAlias()`. | +| `codexInstructions.ts` | Arahan sistem disuntik ke dalam permintaan Codex (kekangan pengeditan, peraturan kotak pasir, dasar kelulusan). | +| `defaultThinkingSignature.ts` | Tanda tangan "berfikir" lalai untuk model Claude dan Gemini. | +| `ollamaModels.ts` | Takrif skema untuk model Ollama tempatan (nama, saiz, keluarga, pengkuantitian). | + +#### Aliran Pemuatan Kredensial + +```mermaid +flowchart TD + A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"] + B --> C{"data/provider-credentials.json\nexists?"} + C -->|Yes| D["credentialLoader reads JSON"] + C -->|No| E["Use hardcoded defaults"] + D --> F{"For each provider in JSON"} + F --> G{"Provider exists\nin PROVIDERS?"} + G -->|No| H["Log warning, skip"] + G -->|Yes| I{"Value is object?"} + I -->|No| J["Log warning, skip"] + I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"] + K --> F + H --> F + J --> F + F -->|Done| L["PROVIDERS ready with\nmerged credentials"] + E --> L +``` + +--- + +### 4.2 Pelaksana (`open-sse/executors/`) + +Pelaksana merangkum **logik khusus pembekal** menggunakan **Corak Strategi**. Setiap pelaksana mengatasi kaedah asas seperti yang diperlukan. + +```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 DefaultExecutor { + +refreshCredentials() + } + + class AntigravityExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +shouldRetry() + +refreshCredentials() + } + + class CursorExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseResponse() + +generateChecksum() + } + + class KiroExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseEventStream() + +refreshCredentials() + } + + BaseExecutor <|-- DefaultExecutor + BaseExecutor <|-- AntigravityExecutor + BaseExecutor <|-- CursorExecutor + BaseExecutor <|-- KiroExecutor + BaseExecutor <|-- CodexExecutor + BaseExecutor <|-- GeminiCLIExecutor + BaseExecutor <|-- GithubExecutor +``` + +| Pelaksana | Pembekal | Pengkhususan Utama | +| ---------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | +| `base.ts` | — | Asas abstrak: Pembinaan URL, pengepala, cuba semula logik, penyegaran semula kelayakan | +| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Muat semula token OAuth generik untuk pembekal standard | +| `antigravity.ts` | Kod Awan Google | Penjanaan ID projek/sesi, sandaran berbilang URL, cuba semula tersuai menghuraikan daripada mesej ralat ("set semula selepas 2h7m23s") | +| `cursor.ts` | IDE kursor | **Paling kompleks**: Pengesahan checksum SHA-256, pengekodan permintaan Protobuf, Perduaan EventStream → Penghuraian respons SSE | +| `codex.ts` | OpenAI Codex | Menyuntik arahan sistem, mengurus tahap pemikiran, mengalih keluar parameter yang tidak disokong | +| `gemini-cli.ts` | Google Gemini CLI | Pembinaan URL tersuai (`streamGenerateContent`), muat semula token Google OAuth | +| `github.ts` | GitHub Copilot | Sistem token dwi (GitHub OAuth + Copilot token), pengepala VSCode meniru | +| `kiro.ts` | AWS CodeWhisperer | Penghuraian binari AWS EventStream, bingkai acara AMZN, anggaran token | +| `index.ts` | — | Kilang: nama pembekal peta → kelas pelaksana, dengan sandaran lalai | + +--- + +### 4.3 Pengendali (`open-sse/handlers/`) + +**Lapisan orkestrasi** — menyelaras terjemahan, pelaksanaan, penstriman dan pengendalian ralat. + +| Fail | Tujuan | +| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `chatCore.ts` | **Orkestra pusat** (~600 baris). Mengendalikan kitaran hayat permintaan yang lengkap: pengesanan format → terjemahan → penghantaran pelaksana → respons penstriman/bukan penstriman → penyegaran token → pengendalian ralat → pengelogan penggunaan. | +| `responsesHandler.ts` | Penyesuai untuk API Respons OpenAI: menukar format Respons → Selesai Sembang → menghantar kepada `chatCore` → menukar SSE kembali kepada format Respons. | +| `embeddings.ts` | Pengendali penjanaan benam: menyelesaikan model pembenaman → pembekal, menghantar kepada API pembekal, mengembalikan respons pembenaman serasi OpenAI. Menyokong 6+ pembekal. | +| `imageGeneration.ts` | Pengendali penjanaan imej: menyelesaikan model imej → pembekal, menyokong mod serasi OpenAI, imej Gemini (Antigraviti) dan sandaran (Nebius). Mengembalikan imej base64 atau URL. | + +#### Minta Kitaran Hayat (chatCore.ts) + +```mermaid +sequenceDiagram + participant Client + participant chatCore + participant Translator + participant Executor + participant Provider + + Client->>chatCore: Request (any format) + chatCore->>chatCore: Detect source format + chatCore->>chatCore: Check bypass patterns + chatCore->>chatCore: Resolve model & provider + chatCore->>Translator: Translate request (source → OpenAI → target) + chatCore->>Executor: Get executor for provider + Executor->>Executor: Build URL, headers, transform request + Executor->>Executor: Refresh credentials if needed + Executor->>Provider: HTTP fetch (streaming or non-streaming) + + alt Streaming + Provider-->>chatCore: SSE stream + chatCore->>chatCore: Pipe through SSE transform stream + Note over chatCore: Transform stream translates
each chunk: target → OpenAI → source + chatCore-->>Client: Translated SSE stream + else Non-streaming + Provider-->>chatCore: JSON response + chatCore->>Translator: Translate response + chatCore-->>Client: Translated JSON + end + + alt Error (401, 429, 500...) + chatCore->>Executor: Retry with credential refresh + chatCore->>chatCore: Account fallback logic + end +``` + +--- + +### 4.4 Perkhidmatan (`open-sse/services/`) + +Logik perniagaan yang menyokong pengendali dan pelaksana. + +| Fail | Tujuan | +| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `provider.ts` | **Pengesanan format** (`detectFormat`): menganalisis struktur badan permintaan untuk mengenal pasti format Claude/OpenAI/Gemini/Antigravity/Respons (termasuk `max_tokens` heuristik untuk Claude). Juga: Pembinaan URL, pembinaan pengepala, penormalan konfigurasi pemikiran. Menyokong `openai-compatible-*` dan `anthropic-compatible-*` pembekal dinamik. | +| `model.ts` | Penghuraian rentetan model (`claude/model-name` → `{provider: "claude", model: "model-name"}`), resolusi alias dengan pengesanan perlanggaran, pembersihan input (menolak aksara traversal/kawalan laluan) dan resolusi maklumat model dengan sokongan alias getter async. | +| `accountFallback.ts` | Pengendalian had kadar: pengunduran eksponen (1s → 2s → 4s → maks 2minit), pengurusan cooldown akaun, klasifikasi ralat (ralat yang mencetuskan sandaran berbanding tidak). | +| `tokenRefresh.ts` | Muat semula token OAuth untuk **setiap pembekal**: Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (OAuth + Copilot dwi-token), Kiro (AWS SSO OIDC + Social Auth). Termasuk cache penyahduplikasi janji dalam penerbangan dan cuba semula dengan pengunduran eksponen. | +| `combo.ts` | **Model kombo**: rangkaian model sandaran. Jika model A gagal dengan ralat layak sandar, cuba model B, kemudian C, dsb. Mengembalikan kod status huluan sebenar. | +| `usage.ts` | Mengambil data kuota/penggunaan daripada API pembekal (kuota Copilot GitHub, kuota model Antigraviti, had kadar Codex, pecahan penggunaan Kiro, tetapan Claude). | +| `accountSelector.ts` | Pemilihan akaun pintar dengan algoritma pemarkahan: mempertimbangkan keutamaan, status kesihatan, kedudukan round-robin dan keadaan cooldown untuk memilih akaun yang optimum bagi setiap permintaan. | +| `contextManager.ts` | Meminta pengurusan kitaran hayat konteks: mencipta dan menjejak objek konteks setiap permintaan dengan metadata (ID permintaan, cap masa, maklumat pembekal) untuk penyahpepijatan dan pengelogan. | +| `ipFilter.ts` | Kawalan capaian berasaskan IP: menyokong mod senarai dibenarkan dan senarai sekat. Mengesahkan IP klien terhadap peraturan yang dikonfigurasikan sebelum memproses permintaan API. | +| `sessionManager.ts` | Penjejakan sesi dengan cap jari pelanggan: menjejaki sesi aktif menggunakan pengecam pelanggan dicincang, memantau kiraan permintaan dan menyediakan metrik sesi. | +| `signatureCache.ts` | Minta cache penyahduplikasian berasaskan tandatangan: menghalang permintaan pendua dengan menyimpan cache tandatangan permintaan terkini dan mengembalikan respons cache untuk permintaan yang sama dalam tetingkap masa. | +| `systemPrompt.ts` | Suntikan gesaan sistem global: menambah atau menambahkan gesaan sistem yang boleh dikonfigurasikan kepada semua permintaan, dengan pengendalian keserasian setiap pembekal. | +| `thinkingBudget.ts` | Pengurusan belanjawan token penaakulan: menyokong mod laluan lalu, auto (konfigurasi pemikiran jalur), tersuai (belanjawan tetap) dan mod penyesuaian (berskala kerumitan) untuk mengawal token pemikiran/penaakulan. | +| `wildcardRouter.ts` | Penghalaan corak model kad liar: menyelesaikan corak kad bebas (cth., `*/claude-*`) kepada pasangan pembekal/model konkrit berdasarkan ketersediaan dan keutamaan. | + +#### Deduplikasi Token Refresh + +```mermaid +sequenceDiagram + participant R1 as Request 1 + participant R2 as Request 2 + participant Cache as refreshPromiseCache + participant OAuth as OAuth Provider + + R1->>Cache: getAccessToken("gemini", token) + Cache->>Cache: No in-flight promise + Cache->>OAuth: Start refresh + R2->>Cache: getAccessToken("gemini", token) + Cache->>Cache: Found in-flight promise + Cache-->>R2: Return existing promise + OAuth-->>Cache: New access token + Cache-->>R1: New access token + Cache-->>R2: Same access token (shared) + Cache->>Cache: Delete cache entry +``` + +#### Mesin Keadaan Fallback Akaun + +```mermaid +stateDiagram-v2 + [*] --> Active + Active --> Error: Request fails (401/429/500) + Error --> Cooldown: Apply backoff + Cooldown --> Active: Cooldown expires + Active --> Active: Request succeeds (reset backoff) + + state Error { + [*] --> ClassifyError + ClassifyError --> ShouldFallback: Rate limit / Auth / Transient + ClassifyError --> NoFallback: 400 Bad Request + } + + state Cooldown { + [*] --> ExponentialBackoff + ExponentialBackoff: Level 0 = 1s + ExponentialBackoff: Level 1 = 2s + ExponentialBackoff: Level 2 = 4s + ExponentialBackoff: Max = 2min + } +``` + +#### Rantai Model Kombo + +```mermaid +flowchart LR + A["Request with\ncombo model"] --> B["Model A"] + B -->|"2xx Success"| C["Return response"] + B -->|"429/401/500"| D{"Fallback\neligible?"} + D -->|Yes| E["Model B"] + D -->|No| F["Return error"] + E -->|"2xx Success"| C + E -->|"429/401/500"| G{"Fallback\neligible?"} + G -->|Yes| H["Model C"] + G -->|No| F + H -->|"2xx Success"| C + H -->|"Fail"| I["All failed →\nReturn last status"] +``` + +--- + +### 4.5 Penterjemah (`open-sse/translator/`) + +**enjin terjemahan format** menggunakan sistem pemalam pendaftaran sendiri. + +#### Seni bina + +```mermaid +graph TD + subgraph "Request Translation" + A["Claude → OpenAI"] + B["Gemini → OpenAI"] + C["Antigravity → OpenAI"] + D["OpenAI Responses → OpenAI"] + E["OpenAI → Claude"] + F["OpenAI → Gemini"] + G["OpenAI → Kiro"] + H["OpenAI → Cursor"] + end + + subgraph "Response Translation" + I["Claude → OpenAI"] + J["Gemini → OpenAI"] + K["Kiro → OpenAI"] + L["Cursor → OpenAI"] + M["OpenAI → Claude"] + N["OpenAI → Antigravity"] + O["OpenAI → Responses"] + end +``` + +| Direktori | Fail | Penerangan | +| ------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `request/` | 8 penterjemah | Tukar badan permintaan antara format. Setiap fail mendaftar sendiri melalui `register(from, to, fn)` semasa diimport. | +| `response/` | 7 penterjemah | Tukar ketulan respons penstriman antara format. Mengendalikan jenis acara SSE, blok pemikiran, panggilan alat. | +| `helpers/` | 6 pembantu | Utiliti dikongsi: `claudeHelper` (pengekstrak segera sistem, konfigurasi pemikiran), `geminiHelper` (pemetaan bahagian/kandungan), `openaiHelper` (penapisan format), `toolCallHelper` (penjanaan ID, suntikan tindak balas tiada), `toolCallHelper`, `toolCallHelper` | +| `index.ts` | — | Enjin terjemahan: `translateRequest()`, `translateResponse()`, pengurusan negeri, pendaftaran. | +| `formats.ts` | — | Pemalar format: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | + +#### Reka Bentuk Utama: Pemalam Mendaftar Sendiri + +```javascript +// Each translator file calls register() on import: +import { register } from "../index.js"; +register("claude", "openai", translateClaudeToOpenAI); + +// The index.js imports all translator files, triggering registration: +import "./request/claude-to-openai.js"; // ← self-registers +``` + +--- + +### 4.6 Util (`open-sse/utils/`) + +| Fail | Tujuan | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `error.ts` | Pembinaan tindak balas ralat (format serasi OpenAI), penghuraian ralat huluan, Pengekstrakan masa percubaan semula Antigraviti daripada mesej ralat, penstriman ralat SSE. | +| `stream.ts` | **SSE Transform Stream** — saluran paip penstriman teras. Dua mod: `TRANSLATE` (terjemahan format penuh) dan `PASSTHROUGH` (normalkan + penggunaan ekstrak). Mengendalikan penimbalan bongkah, anggaran penggunaan, penjejakan panjang kandungan. Kejadian pengekod/penyahkod setiap aliran mengelakkan keadaan dikongsi. | +| `streamHelpers.ts` | Utiliti SSE peringkat rendah: `parseSSELine` (bertoleransi ruang putih), `hasValuableContent` (menapis ketulan kosong untuk OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (pembersihan SSE_OMNI4K yang sedar format dengan \_\_\_OMNI_EN4K). | +| `usageTracking.ts` | Pengekstrakan penggunaan token daripada sebarang format (Claude/OpenAI/Gemini/Responses), anggaran dengan nisbah char-per-token alat/mesej yang berasingan, penambahan penimbal (margin keselamatan 2000 token), penapisan medan khusus format, pengelogan konsol dengan warna ANSI. | +| `requestLogger.ts` | Pengelogan permintaan berasaskan fail (ikut serta melalui `ENABLE_REQUEST_LOGS=true`). Mencipta folder sesi dengan fail bernombor: `1_req_client.json` → `7_res_client.txt`. Semua I/O tidak segerak (api-dan-lupa). Topeng tajuk sensitif. | +| `bypassHandler.ts` | Memintas corak tertentu daripada Claude CLI (pengeluaran tajuk, pemanasan, kiraan) dan mengembalikan respons palsu tanpa menghubungi mana-mana pembekal. Menyokong kedua-dua penstriman dan bukan penstriman. Sengaja dihadkan kepada skop Claude CLI. | +| `networkProxy.ts` | Menyelesaikan URL proksi keluar untuk pembekal tertentu dengan keutamaan: konfigurasi khusus pembekal → konfigurasi global → pembolehubah persekitaran (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Menyokong `NO_PROXY` pengecualian. Konfigurasi cache untuk 30s. | + +#### Saluran Paip Penstriman SSE + +```mermaid +flowchart TD + A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"] + B --> C["Buffer lines\n(split on newline)"] + C --> D["parseSSELine()\n(trim whitespace, parse JSON)"] + D --> E{"Mode?"} + E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"] + E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"] + F --> H["hasValuableContent()\nfilter empty chunks"] + G --> H + H -->|"Has content"| I["extractUsage()\ntrack token counts"] + H -->|"Empty"| J["Skip chunk"] + I --> K["formatSSE()\nserialize + clean perf_metrics"] + K --> L["TextEncoder\n(per-stream instance)"] + L --> M["Enqueue to\nclient stream"] + + style A fill:#f9f,stroke:#333 + style M fill:#9f9,stroke:#333 +``` + +#### Permintaan Struktur Sesi Logger + +``` +logs/ +└── claude_gemini_claude-sonnet_20260208_143045/ + ├── 1_req_client.json ← Raw client request + ├── 2_req_source.json ← After initial conversion + ├── 3_req_openai.json ← OpenAI intermediate format + ├── 4_req_target.json ← Final target format + ├── 5_res_provider.txt ← Provider SSE chunks (streaming) + ├── 5_res_provider.json ← Provider response (non-streaming) + ├── 6_res_openai.txt ← OpenAI intermediate chunks + ├── 7_res_client.txt ← Client-facing SSE chunks + └── 6_error.json ← Error details (if any) +``` + +--- + +### 4.7 Lapisan Aplikasi (`src/`) + +| Direktori | Tujuan | +| ------------- | ----------------------------------------------------------------------------- | +| `src/app/` | UI Web, laluan API, perisian tengah Ekspres, pengendali panggil balik OAuth | +| `src/lib/` | Akses pangkalan data (`localDb.ts`, `usageDb.ts`), pengesahan, dikongsi | +| `src/mitm/` | Utiliti proksi man-in-the-middle untuk memintas trafik pembekal | +| `src/models/` | Takrif model pangkalan data | +| `src/shared/` | Pembalut di sekeliling fungsi open-sse (penyedia, strim, ralat, dll.) | +| `src/sse/` | Pengendali titik akhir SSE yang menghantar pustaka open-sse ke laluan Express | +| `src/store/` | Pengurusan keadaan aplikasi | + +#### Laluan API Terkenal + +| Laluan | Kaedah | Tujuan | +| --------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------- | +| `/api/provider-models` | DAPATKAN/POST/PADAM | CRUD untuk model tersuai setiap pembekal | +| `/api/models/catalog` | DAPATKAN | Katalog agregat semua model (sembang, benam, imej, tersuai) dikumpulkan mengikut pembekal | +| `/api/settings/proxy` | DAPATKAN/LETAK/PADAM | Konfigurasi proksi keluar hierarki (`global/providers/combos/keys`) | +| `/api/settings/proxy/test` | POS | Mengesahkan sambungan proksi dan mengembalikan IP/kependaman awam | +| `/v1/providers/[provider]/chat/completions` | POS | Penyelesaian sembang khusus bagi setiap pembekal dengan pengesahan model | +| `/v1/providers/[provider]/embeddings` | POS | Pembenaman khusus bagi setiap pembekal dengan pengesahan model | +| `/v1/providers/[provider]/images/generations` | POS | Penjanaan imej setiap pembekal khusus dengan pengesahan model | +| `/api/settings/ip-filter` | DAPATKAN/LETAK | Pengurusan senarai dibenarkan/senarai sekat IP | +| `/api/settings/thinking-budget` | DAPATKAN/LETAK | Konfigurasi belanjawan token penaakulan (laluan/auto/tersuai/suai) | +| `/api/settings/system-prompt` | DAPATKAN/LETAK | Suntikan segera sistem global untuk semua permintaan | +| `/api/sessions` | DAPATKAN | Penjejakan dan metrik sesi aktif | +| `/api/rate-limits` | DAPATKAN | Status had kadar setiap akaun | + +--- + +## 5. Corak Reka Bentuk Utama + +### 5.1 Terjemahan Hub-and-Spoke + +Semua format diterjemahkan melalui **format OpenAI sebagai hab**. Menambah penyedia baharu hanya memerlukan penulisan **sepasang** penterjemah (ke/dari OpenAI), bukan N pasangan. + +### 5.2 Corak Strategi Pelaksana + +Setiap pembekal mempunyai kelas pelaksana khusus yang diwarisi daripada `BaseExecutor`. Kilang di `executors/index.ts` memilih yang betul semasa masa jalan. + +### 5.3 Sistem Pemalam Mendaftar Sendiri + +Modul penterjemah mendaftarkan diri mereka pada import melalui `register()`. Menambah penterjemah baharu hanyalah mencipta fail dan mengimportnya. + +### 5.4 Pengunduran Akaun dengan Pengunduran Eksponen + +Apabila pembekal mengembalikan 429/401/500, sistem boleh bertukar ke akaun seterusnya, menggunakan tempoh bertenang eksponen (1s → 2s → 4s → maks 2min). + +### 5.5 Rantai Model Kombo + +"Kombo" mengumpulkan berbilang rentetan `provider/model`. Jika yang pertama gagal, sandarkan kepada yang seterusnya secara automatik. + +### 5.6 Terjemahan Penstriman Stateful + +Terjemahan respons mengekalkan keadaan merentas bahagian SSE (penjejakan blok pemikiran, pengumpulan panggilan alat, pengindeksan blok kandungan) melalui mekanisme `initState()`. + +### 5.7 Penimbal Keselamatan Penggunaan + +Penampan 2000-token ditambahkan pada penggunaan yang dilaporkan untuk menghalang pelanggan daripada mencapai had tetingkap konteks kerana overhed daripada gesaan sistem dan terjemahan format. + +--- + +## 6. Format yang Disokong + +| Format | Arah | Pengecam | +| ---------------------- | ---------------- | ------------------ | +| Selesai Sembang OpenAI | sumber + sasaran | `openai` | +| API Respons OpenAI | sumber + sasaran | `openai-responses` | +| Claude Anthropic | sumber + sasaran | `claude` | +| Google Gemini | sumber + sasaran | `gemini` | +| Google Gemini CLI | sasaran sahaja | `gemini-cli` | +| Antigraviti | sumber + sasaran | `antigravity` | +| AWS Kiro | sasaran sahaja | `kiro` | +| Kursor | sasaran sahaja | `cursor` | + +--- + +## 7. Pembekal yang Disokong + +| Pembekal | Kaedah Pengesahan | Pelaksana | Nota Utama | +| ------------------------ | ------------------------ | ----------- | -------------------------------------------------------- | +| Claude Anthropic | Kunci API atau OAuth | Lalai | Menggunakan pengepala `x-api-key` | +| Google Gemini | Kunci API atau OAuth | Lalai | Menggunakan pengepala `x-goog-api-key` | +| Google Gemini CLI | OAuth | GeminiCLI | Menggunakan `streamGenerateContent` titik akhir | +| Antigraviti | OAuth | Antigraviti | Undur berbilang URL, penghuraian cuba semula tersuai | +| OpenAI | Kunci API | Lalai | Pengesahan Pembawa Standard | +| Codex | OAuth | Codex | Menyuntik arahan sistem, mengurus pemikiran | +| GitHub Copilot | Token OAuth + Copilot | Github | Token dwi, ​​pengepala VSCode meniru | +| Kiro (AWS) | AWS SSO OIDC atau Sosial | Kiro | Perduaan EventStream parsing | +| IDE kursor | Pengesahan semak | Kursor | Pengekodan Protobuf, jumlah semak SHA-256 | +| Qwen | OAuth | Lalai | Pengesahan standard | +| iFlow | OAuth (Asas + Pembawa) | Lalai | Pengepala dwi pengesahan | +| OpenRouter | Kunci API | Lalai | Pengesahan Pembawa Standard | +| GLM, Kimi, MiniMax | Kunci API | Lalai | Serasi Claude, gunakan `x-api-key` | +| `openai-compatible-*` | Kunci API | Lalai | Dinamik: mana-mana titik akhir serasi OpenAI | +| `anthropic-compatible-*` | Kunci API | Lalai | Dinamik: mana-mana titik akhir yang serasi dengan Claude | + +--- + +## 8. Ringkasan Aliran Data + +### Permintaan Penstriman + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor\nbuildUrl + buildHeaders"] + D --> E["fetch(providerURL)"] + E --> F["createSSEStream()\nTRANSLATE mode"] + F --> G["parseSSELine()"] + G --> H["translateResponse()\ntarget → OpenAI → source"] + H --> I["extractUsage()\n+ addBuffer"] + I --> J["formatSSE()"] + J --> K["Client receives\ntranslated SSE"] + K --> L["logUsage()\nsaveRequestUsage()"] +``` + +### Permintaan Bukan Penstriman + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor.execute()"] + D --> E["translateResponse()\ntarget → OpenAI → source"] + E --> F["Return JSON\nresponse"] +``` + +### Aliran Pintasan (Claude CLI) + +```mermaid +flowchart LR + A["Claude CLI request"] --> B{"Match bypass\npattern?"} + B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"] + B -->|"No match"| D["Normal flow"] + C --> E["Translate to\nsource format"] + E --> F["Return without\ncalling provider"] +``` diff --git a/docs/i18n/ms/FEATURES.md b/docs/i18n/ms/FEATURES.md new file mode 100644 index 0000000000..9128775f08 --- /dev/null +++ b/docs/i18n/ms/FEATURES.md @@ -0,0 +1,77 @@ +# OmniRoute — Galeri Ciri Papan Pemuka + +🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md) + +Panduan visual untuk setiap bahagian papan pemuka OmniRoute. + +--- + +## 🔌 Pembekal + +Urus sambungan pembekal AI: Pembekal OAuth (Kod Claude, Codex, Gemini CLI), pembekal kunci API (Groq, DeepSeek, OpenRouter) dan pembekal percuma (iFlow, Qwen, Kiro). + +![Providers Dashboard](screenshots/01-providers.png) + +--- + +## 🎨 Kombo + +Cipta gabungan penghalaan model dengan 6 strategi: isikan dahulu, bulat-bulat, kuasa-dua-pilihan, rawak, paling kurang digunakan dan dioptimumkan kos. Setiap kombo merantai berbilang model dengan sandaran automatik. + +![Combos Dashboard](screenshots/02-combos.png) + +--- + +## 📊 Analitis + +Analitis penggunaan komprehensif dengan penggunaan token, anggaran kos, peta haba aktiviti, carta pengedaran mingguan dan pecahan setiap pembekal. + +![Analytics Dashboard](screenshots/03-analytics.png) + +--- + +## 🏥 Kesihatan Sistem + +Pemantauan masa nyata: masa aktif, memori, versi, persentil kependaman (p50/p95/p99), statistik cache dan keadaan pemutus litar pembekal. + +![Health Dashboard](screenshots/04-health.png) + +--- + +## 🔧 Taman Permainan Penterjemah + +Empat mod untuk penyahpepijatan terjemahan API: **Taman Permainan** (penukar format), **Penguji Sembang** (permintaan langsung), ** Bangku Ujian** (ujian kelompok) dan **Monitor Langsung** (strim masa nyata). + +![Translator Playground](screenshots/05-translator.png) + +--- + +## ⚙️ Tetapan + +Tetapan umum, storan sistem, pengurusan sandaran (pangkalan data eksport/import), penampilan (mod gelap/cahaya), keselamatan (termasuk perlindungan titik akhir API dan penyekatan pembekal tersuai), penghalaan, daya tahan dan konfigurasi lanjutan. + +![Settings Dashboard](screenshots/06-settings.png) + +--- + +## 🔧 Alat CLI + +Konfigurasi satu klik untuk alat pengekodan AI: Kod Claude, Codex CLI, Gemini CLI, OpenClaw, Kod Kilo dan Antigraviti. + +![CLI Tools Dashboard](screenshots/07-cli-tools.png) + +--- + +## 📝 Log Permintaan + +Pengelogan permintaan masa nyata dengan penapisan mengikut pembekal, model, akaun dan kunci API. Menunjukkan kod status, penggunaan token, kependaman dan butiran respons. + +![Usage Logs](screenshots/08-usage.png) + +--- + +## 🌐 Titik Akhir API + +Titik akhir API bersatu anda dengan pecahan keupayaan: Pelengkapan Sembang, Pembenaman, Penjanaan Imej, Kedudukan Semula, Transkripsi Audio dan kunci API berdaftar. + +![Endpoint Dashboard](screenshots/09-endpoint.png) diff --git a/docs/i18n/ms/TROUBLESHOOTING.md b/docs/i18n/ms/TROUBLESHOOTING.md new file mode 100644 index 0000000000..c5119bd412 --- /dev/null +++ b/docs/i18n/ms/TROUBLESHOOTING.md @@ -0,0 +1,219 @@ +# Penyelesaian masalah + +🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md) + +Masalah dan penyelesaian biasa untuk OmniRoute. + +--- + +## Pembetulan Pantas + +| Masalah | Penyelesaian | +| ---------------------------------------- | ------------------------------------------------------------------------ | +| Log masuk pertama tidak berfungsi | Tandai `INITIAL_PASSWORD` dalam `.env` (lalai: `123456`) | +| Papan pemuka dibuka pada port yang salah | Tetapkan `PORT=20128` dan `NEXT_PUBLIC_BASE_URL=http://localhost:20128` | +| Tiada log permintaan di bawah `logs/` | Tetapkan `ENABLE_REQUEST_LOGS=true` | +| EACCES: kebenaran ditolak | Tetapkan `DATA_DIR=/path/to/writable/dir` untuk mengatasi `~/.omniroute` | +| Strategi penghalaan tidak menyimpan | Kemas kini kepada v1.4.11+ (Pembetulan skema Zod untuk tetapan tetapan) | + +--- + +## Isu Pembekal + +### "Model bahasa tidak memberikan mesej" + +**Punca:** Kuota pembekal habis. + +**Betulkan:** + +1. Semak penjejak kuota papan pemuka +2. Gunakan kombo dengan peringkat sandaran +3. Tukar kepada peringkat yang lebih murah/percuma + +### Mengehadkan Kadar + +**Punca:** Kuota langganan habis. + +**Betulkan:** + +- Tambahkan sandaran: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` +- Gunakan GLM/MiniMax sebagai sandaran murah + +### Token OAuth Tamat Tempoh + +Token auto-refresh OmniRoute. Jika isu berterusan: + +1. Papan pemuka → Pembekal → Sambung semula +2. Padam dan tambah semula sambungan pembekal + +--- + +## Isu Awan + +### Ralat Penyegerakan Awan + +1. Sahkan `BASE_URL` mata kepada contoh larian anda (cth., `http://localhost:20128`) +2. Sahkan `CLOUD_URL` mata ke titik akhir awan anda (cth., `https://omniroute.dev`) +3. Pastikan nilai `NEXT_PUBLIC_*` sejajar dengan nilai sebelah pelayan + +### Cloud `stream=false` Mengembalikan 500 + +**Simptom:** `Unexpected token 'd'...` pada titik akhir awan untuk panggilan bukan penstriman. + +**Punca:** Hulu mengembalikan muatan SSE sementara pelanggan menjangkakan JSON. + +**Penyelesaian:** Gunakan `stream=true` untuk panggilan terus awan. Masa jalan tempatan termasuk SSE→JSON sandaran. + +### Cloud Says Connected tetapi "Kunci API Tidak Sah" + +1. Cipta kunci baharu daripada papan pemuka setempat (`/api/keys`) +2. Jalankan penyegerakan awan: Dayakan Awan → Segerakkan Sekarang +3. Kekunci lama/tidak disegerakkan masih boleh mengembalikan `401` pada awan + +--- + +## Isu Docker + +### Rancangan Alat CLI Tidak Dipasang + +1. Semak medan masa jalan: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq` +2. Untuk mod mudah alih: gunakan sasaran imej `runner-cli` (CLI dibundel) +3. Untuk mod lekap hos: tetapkan `CLI_EXTRA_PATHS` dan lekapkan direktori bin hos sebagai baca sahaja +4. Jika `installed=true` dan `runnable=false`: binari ditemui tetapi gagal pemeriksaan kesihatan + +### Pengesahan Masa Jalan Pantas + +```bash +curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +``` + +--- + +## Isu Kos + +### Kos Tinggi + +1. Semak statistik penggunaan dalam Papan Pemuka → Penggunaan +2. Tukar model utama kepada GLM/MiniMax +3. Gunakan peringkat percuma (Gemini CLI, iFlow) untuk tugasan yang tidak kritikal +4. Tetapkan belanjawan kos setiap kunci API: Papan Pemuka → Kunci API → Belanjawan + +--- + +## Penyahpepijatan + +### Dayakan Log Permintaan + +Tetapkan `ENABLE_REQUEST_LOGS=true` dalam fail `.env` anda. Log muncul di bawah direktori `logs/`. + +### Semak Kesihatan Pembekal + +```bash +# Health dashboard +http://localhost:20128/dashboard/health + +# API health check +curl http://localhost:20128/api/monitoring/health +``` + +### Storan Masa Jalan + +- Keadaan utama: `${DATA_DIR}/db.json` (penyedia, gabungan, alias, kunci, tetapan) +- Penggunaan: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- Log permintaan: `/logs/...` (apabila `ENABLE_REQUEST_LOGS=true`) + +--- + +## Isu Pemutus Litar + +### Penyedia tersekat dalam keadaan OPEN + +Apabila pemutus litar pembekal DIBUKA, permintaan disekat sehingga tempoh bertenang tamat. + +**Betulkan:** + +1. Pergi ke **Papan Pemuka → Tetapan → Ketahanan** +2. Periksa kad pemutus litar untuk pembekal yang terjejas +3. Klik **Tetapkan Semula Semua** untuk mengosongkan semua pemutus, atau tunggu sehingga tempoh bertenang tamat +4. Sahkan pembekal sebenarnya tersedia sebelum menetapkan semula + +### Pembekal terus tersandung pemutus litar + +Jika pembekal berulang kali memasuki keadaan OPEN: + +1. Semak **Papan Pemuka → Kesihatan → Kesihatan Pembekal** untuk corak kegagalan +2. Pergi ke **Tetapan → Ketahanan → Profil Pembekal** dan tingkatkan ambang kegagalan +3. Semak sama ada pembekal telah menukar had API atau memerlukan pengesahan semula +4. Semak telemetri kependaman — kependaman tinggi boleh menyebabkan kegagalan berdasarkan tamat masa + +--- + +## Isu Transkripsi Audio + +### Ralat "Model tidak disokong". + +- Pastikan anda menggunakan awalan yang betul: `deepgram/nova-3` atau `assemblyai/best` +- Sahkan pembekal disambungkan dalam **Papan Pemuka → Pembekal** + +### Transkripsi mengembalikan kosong atau gagal + +- Semak format audio yang disokong: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm` +- Sahkan saiz fail berada dalam had pembekal (biasanya < 25MB) +- Semak kesahihan kunci API pembekal dalam kad pembekal + +--- + +## Penyahpepijatan Penterjemah + +Gunakan **Papan Pemuka → Penterjemah** untuk menyahpepijat isu terjemahan format: + +| Mod | Bila Menggunakan | +| --------------------- | ------------------------------------------------------------------------------------------------------------------ | +| **Taman Permainan** | Bandingkan format input/output sebelah menyebelah — tampal permintaan yang gagal untuk melihat cara ia menterjemah | +| **Penguji Sembang** | Hantar mesej langsung dan periksa muatan penuh permintaan/tindak balas termasuk pengepala | +| **Bangku Ujian** | Jalankan ujian kelompok merentas gabungan format untuk mencari terjemahan yang rosak | +| **Pemantau Langsung** | Tonton aliran permintaan masa nyata untuk menangkap isu terjemahan terputus-putus | + +### Isu format biasa + +- **Teg pemikiran tidak muncul** — Semak sama ada pembekal sasaran menyokong pemikiran dan tetapan belanjawan pemikiran +- **Panggilan alat terputus** — Sesetengah terjemahan format mungkin menanggalkan medan yang tidak disokong; sahkan dalam mod Taman Permainan +- **Gesaan sistem tiada** — Gesaan sistem pengendalian Claude dan Gemini secara berbeza; semak output terjemahan +- **SDK mengembalikan rentetan mentah dan bukannya objek** — Ditetapkan dalam v1.1.0: sanitizer respons kini menanggalkan medan bukan standard (`x_groq`, `usage_breakdown`, dsb.) yang menyebabkan kegagalan pengesahan OpenAI SDK Pydantic +- **GLM/ERNIE menolak peranan `system`** — Ditetapkan dalam v1.1.0: penormal peranan secara automatik menggabungkan mesej sistem ke dalam mesej pengguna untuk model yang tidak serasi +- **`developer` peranan tidak dikenali** — Ditetapkan dalam v1.1.0: ditukar secara automatik kepada `system` untuk pembekal bukan OpenAI +- **`json_schema` tidak berfungsi dengan Gemini** — Ditetapkan dalam v1.1.0: `response_format` kini ditukar kepada Gemini `responseMimeType` + `responseSchema` + +--- + +## Tetapan Ketahanan + +### Had kadar automatik tidak dicetuskan + +- Had kadar automatik hanya digunakan untuk penyedia kunci API (bukan OAuth/langganan) +- Sahkan **Tetapan → Ketahanan → Profil Pembekal** telah didayakan had kadar automatik +- Semak sama ada pembekal mengembalikan kod status `429` atau pengepala `Retry-After` + +### Menala mundur eksponen + +Profil pembekal menyokong tetapan ini: + +- **Kelewatan asas** — Masa menunggu awal selepas kegagalan pertama (lalai: 1s) +- **Lengah maksimum** — Had masa menunggu maksimum (lalai: 30s) +- **Pendarab** — Berapa banyak untuk meningkatkan kelewatan setiap kegagalan berturut-turut (lalai: 2x) + +### Kumpulan anti-gemuruh + +Apabila banyak permintaan serentak melanda penyedia terhad kadar, OmniRoute menggunakan mutex + pengehadan kadar automatik untuk menyerikan permintaan dan mengelakkan kegagalan berlatarkan. Ini adalah automatik untuk pembekal kunci API. + +--- + +## Masih Terperangkap? + +- **Isu GitHub**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) +- **Seni Bina**: Lihat [**OMNI_TOKEN_55**](ARCHITECTURE.md) untuk butiran dalaman +- **Rujukan API**: Lihat [**OMNI_TOKEN_56**](API_REFERENCE.md) untuk semua titik akhir +- **Papan Pemuka Kesihatan**: Semak **Papan Pemuka → Kesihatan** untuk status sistem masa nyata +- **Penterjemah**: Gunakan **Papan Pemuka → Penterjemah** untuk menyahpepijat isu format diff --git a/docs/i18n/ms/USER_GUIDE.md b/docs/i18n/ms/USER_GUIDE.md new file mode 100644 index 0000000000..549e46f0d7 --- /dev/null +++ b/docs/i18n/ms/USER_GUIDE.md @@ -0,0 +1,698 @@ +# Panduan Pengguna + +🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md) + +Panduan lengkap untuk mengkonfigurasi penyedia, mencipta gabungan, menyepadukan alatan CLI dan menggunakan OmniRoute. + +--- + +## Jadual Kandungan + +- [Pricing at a Glance](#-pricing-at-a-glance) +- [Use Cases](#-use-cases) +- [Provider Setup](#-provider-setup) +- [CLI Integration](#-cli-integration) +- [Deployment](#-deployment) +- [Available Models](#-available-models) +- [Advanced Features](#-advanced-features) + +--- + +## 💰 Sekilas Pandang Harga + +| Peringkat | Pembekal | Kos | Set Semula Kuota | Terbaik Untuk | +| ---------------- | ---------------- | ----------------------- | ------------------ | ---------------------- | +| **💳 LANGGANAN** | Kod Claude (Pro) | $20/bln | 5j + mingguan | Sudah melanggan | +| | Codex (Plus/Pro) | $20-200/bln | 5j + mingguan | Pengguna OpenAI | +| | Gemini CLI | **PERCUMA** | 180K/bln + 1K/hari | Semua orang! | +| | GitHub Copilot | $10-19/bln | Bulanan | Pengguna GitHub | +| **🔑 KUNCI API** | DeepSeek | Bayar setiap penggunaan | Tiada | Penaakulan murah | +| | Groq | Bayar setiap penggunaan | Tiada | Inferens sangat pantas | +| | xAI (Grok) | Bayar setiap penggunaan | Tiada | Grok 4 penaakulan | +| | Mistral | Bayar setiap penggunaan | Tiada | Model yang dihoskan EU | +| | Kebingungan | Bayar setiap penggunaan | Tiada | Carian-ditambah | +| | Bersama AI | Bayar setiap penggunaan | Tiada | Model sumber terbuka | +| | Bunga Api AI | Bayar setiap penggunaan | Tiada | Imej FLUX Pantas | +| | Serebral | Bayar setiap penggunaan | Tiada | Kelajuan skala wafer | +| | Cohere | Bayar setiap penggunaan | Tiada | Perintah R+ RAG | +| | NVIDIA NIM | Bayar setiap penggunaan | Tiada | Model perusahaan | +| **💰 MURAH** | GLM-4.7 | $0.6/1J | Setiap hari 10AM | Sandaran belanjawan | +| | MiniMax M2.1 | $0.2/1J | 5 jam bergolek | Pilihan termurah | +| | Kimi K2 | $9/bln flat | 10 juta token/bln | Kos yang boleh diramal | +| **🆓 PERCUMA** | iFlow | $0 | tanpa had | 8 model percuma | +| | Qwen | $0 | tanpa had | 3 model percuma | +| | Kiro | $0 | tanpa had | Claude percuma | + +**💡 Petua Pro:** Mulakan dengan Gemini CLI (180K percuma/bulan) + iFlow (percuma tanpa had) kombo = $0 kos! + +--- + +## 🎯 Kes Penggunaan + +### Kes 1: "Saya mempunyai langganan Claude Pro" + +**Masalah:** Kuota tamat tempoh tidak digunakan, had kadar semasa pengekodan berat + +``` +Combo: "maximize-claude" + 1. cc/claude-opus-4-6 (use subscription fully) + 2. glm/glm-4.7 (cheap backup when quota out) + 3. if/kimi-k2-thinking (free emergency fallback) + +Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total +vs. $20 + hitting limits = frustration +``` + +### Kes 2: "Saya mahu kos sifar" + +**Masalah:** Tidak mampu membayar langganan, memerlukan pengekodan AI yang boleh dipercayai + +``` +Combo: "free-forever" + 1. gc/gemini-3-flash (180K free/month) + 2. if/kimi-k2-thinking (unlimited free) + 3. qw/qwen3-coder-plus (unlimited free) + +Monthly cost: $0 +Quality: Production-ready models +``` + +### Kes 3: "Saya memerlukan pengekodan 24/7, tiada gangguan" + +**Masalah:** Tarikh akhir, tidak mampu membayar masa henti + +``` +Combo: "always-on" + 1. cc/claude-opus-4-6 (best quality) + 2. cx/gpt-5.2-codex (second subscription) + 3. glm/glm-4.7 (cheap, resets daily) + 4. minimax/MiniMax-M2.1 (cheapest, 5h reset) + 5. if/kimi-k2-thinking (free unlimited) + +Result: 5 layers of fallback = zero downtime +Monthly cost: $20-200 (subscriptions) + $10-20 (backup) +``` + +### Kes 4: "Saya mahukan AI PERCUMA dalam OpenClaw" + +**Masalah:** Memerlukan pembantu AI dalam apl pemesejan, percuma sepenuhnya + +``` +Combo: "openclaw-free" + 1. if/glm-4.7 (unlimited free) + 2. if/minimax-m2.1 (unlimited free) + 3. if/kimi-k2-thinking (unlimited free) + +Monthly cost: $0 +Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal... +``` + +--- + +## 📖 Persediaan Pembekal + +### 🔐 Pembekal Langganan + +#### Kod Claude (Pro/Max) + +```bash +Dashboard → Providers → Connect Claude Code +→ OAuth login → Auto token refresh +→ 5-hour + weekly quota tracking + +Models: + cc/claude-opus-4-6 + cc/claude-sonnet-4-5-20250929 + cc/claude-haiku-4-5-20251001 +``` + +**Petua Pro:** Gunakan Opus untuk tugas yang rumit, Sonnet untuk kelajuan. OmniRoute menjejaki kuota setiap model! + +#### OpenAI Codex (Plus/Pro) + +```bash +Dashboard → Providers → Connect Codex +→ OAuth login (port 1455) +→ 5-hour + weekly reset + +Models: + cx/gpt-5.2-codex + cx/gpt-5.1-codex-max +``` + +#### Gemini CLI (PERCUMA 180K/bulan!) + +```bash +Dashboard → Providers → Connect Gemini CLI +→ Google OAuth +→ 180K completions/month + 1K/day + +Models: + gc/gemini-3-flash-preview + gc/gemini-2.5-pro +``` + +**Nilai Terbaik:** Peringkat percuma yang besar! Gunakan ini sebelum peringkat berbayar. + +#### Copilot GitHub + +```bash +Dashboard → Providers → Connect GitHub +→ OAuth via GitHub +→ Monthly reset (1st of month) + +Models: + gh/gpt-5 + gh/claude-4.5-sonnet + gh/gemini-3-pro +``` + +### 💰 Pembekal Murah + +#### GLM-4.7 (Tetapan semula harian, $0.6/1J) + +1. Daftar: [Zhipu AI](https://open.bigmodel.cn/) +2. Dapatkan kunci API daripada Pelan Pengekodan +3. Papan Pemuka → Tambah Kunci API: Pembekal: `glm`, Kunci API: `your-key` + +**Gunakan:** `glm/glm-4.7` — **Petua Pro:** Pelan Pengekodan menawarkan kuota 3× pada 1/7 kos! Tetapkan semula setiap hari 10:00 AM. + +#### MiniMax M2.1 (tetapan semula 5j, $0.20/1J) + +1. Daftar: [MiniMax](https://www.minimax.io/) +2. Dapatkan kunci API → Papan Pemuka → Tambah Kunci API + +**Gunakan:** `minimax/MiniMax-M2.1` — **Petua Pro:** Pilihan termurah untuk konteks panjang (token 1M)! + +#### Kimi K2 ($9/bulan rata) + +1. Langgan: [Moonshot AI](https://platform.moonshot.ai/) +2. Dapatkan kunci API → Papan Pemuka → Tambah Kunci API + +**Gunakan:** `kimi/kimi-latest` — **Petua Pro:** Tetap $9/bulan untuk 10 juta token = $0.90/1J kos efektif! + +### 🆓 Pembekal PERCUMA + +#### iFlow (8 model PERCUMA) + +```bash +Dashboard → Connect iFlow → OAuth login → Unlimited usage + +Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1 +``` + +#### Qwen (3 model PERCUMA) + +```bash +Dashboard → Connect Qwen → Device code auth → Unlimited usage + +Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash +``` + +#### Kiro (Claude PERCUMA) + +```bash +Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited + +Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5 +``` + +--- + +## 🎨 Kombo + +### Contoh 1: Maksimumkan Langganan → Sandaran Murah + +``` +Dashboard → Combos → Create New + +Name: premium-coding +Models: + 1. cc/claude-opus-4-6 (Subscription primary) + 2. glm/glm-4.7 (Cheap backup, $0.6/1M) + 3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M) + +Use in CLI: premium-coding +``` + +### Contoh 2: Percuma-Sahaja (Kos Sifar) + +``` +Name: free-combo +Models: + 1. gc/gemini-3-flash-preview (180K free/month) + 2. if/kimi-k2-thinking (unlimited) + 3. qw/qwen3-coder-plus (unlimited) + +Cost: $0 forever! +``` + +--- + +## 🔧 Integrasi CLI + +### IDE Kursor + +``` +Settings → Models → Advanced: + OpenAI API Base URL: http://localhost:20128/v1 + OpenAI API Key: [from omniroute dashboard] + Model: cc/claude-opus-4-6 +``` + +### Kod Claude + +Edit `~/.claude/config.json`: + +```json +{ + "anthropic_api_base": "http://localhost:20128/v1", + "anthropic_api_key": "your-omniroute-api-key" +} +``` + +### Codex CLI + +```bash +export OPENAI_BASE_URL="http://localhost:20128" +export OPENAI_API_KEY="your-omniroute-api-key" +codex "your prompt" +``` + +### OpenClaw + +Edit `~/.openclaw/openclaw.json`: + +```json +{ + "agents": { + "defaults": { + "model": { "primary": "omniroute/if/glm-4.7" } + } + }, + "models": { + "providers": { + "omniroute": { + "baseUrl": "http://localhost:20128/v1", + "apiKey": "your-omniroute-api-key", + "api": "openai-completions", + "models": [{ "id": "if/glm-4.7", "name": "glm-4.7" }] + } + } + } +} +``` + +**Atau gunakan Papan Pemuka:** CLI Tools → OpenClaw → Auto-config + +### Cline / Teruskan / RooCode + +``` +Provider: OpenAI Compatible +Base URL: http://localhost:20128/v1 +API Key: [from dashboard] +Model: cc/claude-opus-4-6 +``` + +--- + +## 🚀 Kerahan + +### Penggunaan VPS + +```bash +git clone https://github.com/diegosouzapw/OmniRoute.git +cd OmniRoute && npm install && npm run build + +export JWT_SECRET="your-secure-secret-change-this" +export INITIAL_PASSWORD="your-password" +export DATA_DIR="/var/lib/omniroute" +export PORT="20128" +export HOSTNAME="0.0.0.0" +export NODE_ENV="production" +export NEXT_PUBLIC_BASE_URL="http://localhost:20128" +export API_KEY_SECRET="endpoint-proxy-api-key-secret" + +npm run start +# Or: pm2 start npm --name omniroute -- start +``` + +### Doker + +```bash +# Build image (default = runner-cli with codex/claude/droid preinstalled) +docker build -t omniroute:cli . + +# Portable mode (recommended) +docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli +``` + +Untuk mod bersepadu hos dengan binari CLI, lihat bahagian Docker dalam dokumen utama. + +### Pembolehubah Persekitaran + +| Pembolehubah | Lalai | Penerangan | +| --------------------- | ------------------------------------ | ------------------------------------------------------------------ | +| `JWT_SECRET` | `omniroute-default-secret-change-me` | Rahsia menandatangani JWT (**perubahan dalam pengeluaran**) | +| `INITIAL_PASSWORD` | `123456` | Kata laluan log masuk pertama | +| `DATA_DIR` | `~/.omniroute` | Direktori data (db, penggunaan, log) | +| `PORT` | lalai rangka kerja | Port perkhidmatan (`20128` dalam contoh) | +| `HOSTNAME` | lalai rangka kerja | Ikat hos (Docker lalai kepada `0.0.0.0`) | +| `NODE_ENV` | lalai masa jalan | Tetapkan `production` untuk digunakan | +| `BASE_URL` | `http://localhost:20128` | URL asas dalaman sebelah pelayan | +| `CLOUD_URL` | `https://omniroute.dev` | URL asas titik akhir penyegerakan awan | +| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | Rahsia HMAC untuk kunci API yang dijana | +| `REQUIRE_API_KEY` | `false` | Kuatkuasakan kunci API Pembawa pada `/v1/*` | +| `ENABLE_REQUEST_LOGS` | `false` | Mendayakan log permintaan/tindak balas | +| `AUTH_COOKIE_SECURE` | `false` | Paksa `Secure` kuki pengesahan (di belakang proksi terbalik HTTPS) | + +Untuk rujukan pembolehubah persekitaran penuh, lihat [README](../README.md). + +--- + +## 📊 Model Tersedia + +
+Lihat semua model yang tersedia + +**Kod Claude (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001` + +**Codex (`cx/`)** — Tambahan/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max` + +**Gemini CLI (`gc/`)** — PERCUMA: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro` + +**GitHub Copilot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet` + +**GLM (`glm/`)** — $0.6/1J: `glm/glm-4.7` + +**MiniMax (`minimax/`)** — $0.2/1J: `minimax/MiniMax-M2.1` + +**iFlow (`if/`)** — PERCUMA: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1` + +**Qwen (`qw/`)** — PERCUMA: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash` + +**Kiro (`kr/`)** — PERCUMA: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5` + +**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner` + +**Groq (`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct` + +**xAI (`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini` + +**Mistral (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501` + +**Kekeliruan (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar` + +**Bersama AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo` + +**Ai Bunga Api (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1` + +**Serebral (`cerebras/`)**: `cerebras/llama-3.3-70b` + +**Kesatuan (`cohere/`)**: `cohere/command-r-plus-08-2024` + +**NVIDIA NIM (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct` + +
+ +--- + +## 🧩 Ciri Lanjutan + +### Model Tersuai + +Tambahkan sebarang ID model pada mana-mana pembekal tanpa menunggu kemas kini apl: + +```bash +# Via API +curl -X POST http://localhost:20128/api/provider-models \ + -H "Content-Type: application/json" \ + -d '{"provider": "openai", "modelId": "gpt-4.5-preview", "modelName": "GPT-4.5 Preview"}' + +# List: curl http://localhost:20128/api/provider-models?provider=openai +# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview" +``` + +Atau gunakan Papan Pemuka: **Pembekal → [Penyedia] → Model Tersuai**. + +### Laluan Penyedia Khusus + +Halakan permintaan terus kepada pembekal tertentu dengan pengesahan model: + +```bash +POST http://localhost:20128/v1/providers/openai/chat/completions +POST http://localhost:20128/v1/providers/openai/embeddings +POST http://localhost:20128/v1/providers/fireworks/images/generations +``` + +Awalan pembekal ditambah secara automatik jika tiada. Model tidak sepadan mengembalikan `400`. + +### Konfigurasi Proksi Rangkaian + +```bash +# Set global proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"global": {"type":"http","host":"proxy.example.com","port":"8080"}}' + +# Per-provider proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"providers": {"openai": {"type":"socks5","host":"proxy.example.com","port":"1080"}}}' + +# Test proxy +curl -X POST http://localhost:20128/api/settings/proxy/test \ + -d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}' +``` + +**Keutamaan:** Khusus kunci → Khusus kombo → Khusus pembekal → Global → Persekitaran. + +### API Katalog Model + +```bash +curl http://localhost:20128/api/models/catalog +``` + +Mengembalikan model yang dikumpulkan mengikut pembekal dengan jenis (`chat`, `embedding`, `image`). + +### Penyegerakan Awan + +- Penyegerakan penyedia, gabungan dan tetapan merentas peranti +- Penyegerakan latar belakang automatik dengan tamat masa + cepat gagal +- Lebih suka bahagian pelayan `BASE_URL`/`CLOUD_URL` dalam pengeluaran + +### Perisikan Gerbang LLM (Fasa 9) + +- **Cache Semantik** — Auto-cache bukan penstriman, suhu=0 respons (pintasan dengan `X-OmniRoute-No-Cache: true`) +- **Minta Idempotency** — Menyahduplikasi permintaan dalam masa 5s melalui pengepala `Idempotency-Key` atau `X-Request-Id` +- **Penjejakan Kemajuan** — Ikut serta acara SSE `event: progress` melalui pengepala `X-OmniRoute-Progress: true` + +--- + +### Taman Permainan Penterjemah + +Akses melalui **Papan Pemuka → Penterjemah**. Nyahpepijat dan gambarkan cara OmniRoute menterjemah permintaan API antara pembekal. + +| Mod | Tujuan | +| --------------------- | -------------------------------------------------------------------------------------------------- | +| **Taman Permainan** | Pilih format sumber/sasaran, tampal permintaan dan lihat output yang diterjemahkan serta-merta | +| **Penguji Sembang** | Hantar mesej sembang langsung melalui proksi dan periksa kitaran permintaan/tindak balas penuh | +| **Bangku Ujian** | Jalankan ujian kelompok merentasi pelbagai kombinasi format untuk mengesahkan ketepatan terjemahan | +| **Pemantau Langsung** | Tonton terjemahan masa nyata apabila permintaan mengalir melalui proksi | + +**Kes penggunaan:** + +- Nyahpepijat sebab gabungan klien/pembekal tertentu gagal +- Sahkan bahawa teg pemikiran, panggilan alat dan gesaan sistem diterjemahkan dengan betul +- Bandingkan perbezaan format antara format OpenAI, Claude, Gemini dan API Respons + +--- + +### Strategi Penghalaan + +Konfigurasikan melalui **Papan Pemuka → Tetapan → Penghalaan**. + +| Strategi | Penerangan | +| --------------------------- | -------------------------------------------------------------------------------------------------------------- | +| **Isi Dulu** | Menggunakan akaun dalam susunan keutamaan — akaun utama mengendalikan semua permintaan sehingga tidak tersedia | +| **Robin Bulat** | Kitaran melalui semua akaun dengan had melekit boleh dikonfigurasikan (lalai: 3 panggilan setiap akaun) | +| **P2C (Kuasa Dua Pilihan)** | Pilih 2 akaun rawak dan laluan ke yang lebih sihat — mengimbangi beban dengan kesedaran kesihatan | +| **Rawak** | Memilih akaun secara rawak untuk setiap permintaan menggunakan Fisher-Yates shuffle | +| **Kurang Digunakan** | Laluan ke akaun dengan cap waktu `lastUsedAt` tertua, mengagihkan trafik secara sama rata | +| **Kos Dioptimumkan** | Laluan ke akaun dengan nilai keutamaan terendah, mengoptimumkan untuk pembekal kos terendah | + +#### Alias Model Kad Liar + +Cipta corak kad bebas untuk memetakan semula nama model: + +``` +Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929 +Pattern: gpt-* → Target: gh/gpt-5.1-codex +``` + +Kad liar menyokong `*` (sebarang aksara) dan `?` (aksara tunggal). + +#### Rantai Fallback + +Tentukan rantaian sandaran global yang digunakan merentas semua permintaan: + +``` +Chain: production-fallback + 1. cc/claude-opus-4-6 + 2. gh/gpt-5.1-codex + 3. glm/glm-4.7 +``` + +--- + +### Ketahanan & Pemutus Litar + +Konfigurasikan melalui **Papan Pemuka → Tetapan → Ketahanan**. + +OmniRoute melaksanakan daya tahan peringkat penyedia dengan empat komponen: + +1. **Profil Pembekal** — Konfigurasi setiap pembekal untuk: + - Ambang kegagalan (berapa banyak kegagalan sebelum dibuka) + - Tempoh penyejukan + - Sensitiviti pengesanan had kadar + - Parameter mundur eksponen + +2. **Had Kadar Boleh Diedit** — Lalai peringkat sistem boleh dikonfigurasikan dalam papan pemuka: + - **Permintaan Per Minit (RPM)** — Permintaan maksimum seminit setiap akaun + - **Masa Min Antara Permintaan** — Jurang minimum dalam milisaat antara permintaan + - **Permintaan Serentak Maks** — Permintaan serentak maksimum bagi setiap akaun + - Klik **Edit** untuk mengubah suai, kemudian **Simpan** atau **Batal**. Nilai kekal melalui API ketahanan. + +3. **Pemutus Litar** — Menjejaki kegagalan setiap pembekal dan membuka litar secara automatik apabila ambang dicapai: + - **TUTUP** (Sihat) — Permintaan mengalir seperti biasa + - **BUKA** — Pembekal disekat buat sementara waktu selepas kegagalan berulang + - **HALF_OPEN** — Menguji jika pembekal telah pulih + +4. **Dasar & Pengecam Terkunci** — Menunjukkan status pemutus litar dan pengecam terkunci dengan keupayaan buka kunci paksa. + +5. **Pengesanan Auto Had Kadar** — Memantau pengepala `429` dan `Retry-After` untuk mengelak daripada mencapai had kadar penyedia secara proaktif. + +**Petua Pro:** Gunakan butang **Reset Semua** untuk mengosongkan semua pemutus litar dan cooldown apabila pembekal pulih daripada gangguan. + +--- + +### Eksport / Import Pangkalan Data + +Uruskan sandaran pangkalan data dalam **Papan Pemuka → Tetapan → Sistem & Storan**. + +| Tindakan | Penerangan | +| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| **Eksport Pangkalan Data** | Memuat turun pangkalan data SQLite semasa sebagai fail `.sqlite` | +| **Eksport Semua (.tar.gz)** | Memuat turun arkib sandaran penuh termasuk: pangkalan data, tetapan, kombo, sambungan pembekal (tiada bukti kelayakan), metadata kunci API | +| **Import Pangkalan Data** | Muat naik fail `.sqlite` untuk menggantikan pangkalan data semasa. Sandaran pra-import dibuat secara automatik | + +```bash +# API: Export database +curl -o backup.sqlite http://localhost:20128/api/db-backups/export + +# API: Export all (full archive) +curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll + +# API: Import database +curl -X POST http://localhost:20128/api/db-backups/import \ + -F "file=@backup.sqlite" +``` + +**Pengesahan Import:** Fail yang diimport disahkan untuk integriti (semakan pragma SQLite), jadual yang diperlukan (`provider_connections`, `provider_nodes`, `combos`, `api_keys`) dan saiz (maks 100MB). + +**Kes Penggunaan:** + +- Pindahkan OmniRoute antara mesin +- Buat sandaran luaran untuk pemulihan bencana +- Kongsi konfigurasi antara ahli pasukan (eksport semua → kongsi arkib) + +--- + +### Papan Pemuka Tetapan + +Halaman tetapan disusun menjadi 5 tab untuk navigasi mudah: + +| Tab | Kandungan | +| --------------- | ------------------------------------------------------------------------------------------------------- | +| **Keselamatan** | Tetapan Log Masuk/Kata Laluan, Kawalan Akses IP, pengesahan API untuk `/models` dan Penyekatan Penyedia | +| **Penghalaan** | Strategi penghalaan global (6 pilihan), alias model kad bebas, rantai sandaran, lalai kombo | +| **Ketahanan** | Profil pembekal, had kadar boleh diedit, status pemutus litar, dasar & pengecam terkunci | +| **AI** | Pemikiran konfigurasi belanjawan, suntikan segera sistem global, statistik cache segera | +| **Lanjutan** | Konfigurasi proksi global (HTTP/SOCKS5) | + +--- + +### Pengurusan Kos & Belanjawan + +Akses melalui **Papan Pemuka → Kos**. + +| Tab | Tujuan | +| ------------ | ------------------------------------------------------------------------------------------------------------------- | +| **Anggaran** | Tetapkan had perbelanjaan bagi setiap kunci API dengan belanjawan harian/mingguan/bulanan dan penjejakan masa nyata | +| **Harga** | Lihat dan edit entri harga model — kos setiap token input/output 1K bagi setiap pembekal | + +```bash +# API: Set a budget +curl -X POST http://localhost:20128/api/usage/budget \ + -H "Content-Type: application/json" \ + -d '{"keyId": "key-123", "limit": 50.00, "period": "monthly"}' + +# API: Get current budget status +curl http://localhost:20128/api/usage/budget +``` + +**Penjejakan Kos:** Setiap permintaan merekodkan penggunaan token dan mengira kos menggunakan jadual harga. Lihat pecahan dalam **Papan Pemuka → Penggunaan** oleh pembekal, model dan kunci API. + +--- + +### Transkripsi Audio + +OmniRoute menyokong transkripsi audio melalui titik akhir yang serasi dengan OpenAI: + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data + +# Example with curl +curl -X POST http://localhost:20128/v1/audio/transcriptions \ + -H "Authorization: Bearer your-api-key" \ + -F "file=@audio.mp3" \ + -F "model=deepgram/nova-3" +``` + +Pembekal yang tersedia: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`). + +Format audio yang disokong: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +### Strategi Pengimbangan Kombo + +Konfigurasikan pengimbangan setiap kombo dalam **Papan Pemuka → Kombo → Cipta/Edit → Strategi**. + +| Strategi | Penerangan | +| -------------------- | ---------------------------------------------------------------------------------------- | +| **Round-Robin** | Berputar melalui model secara berurutan | +| **Keutamaan** | Sentiasa mencuba model pertama; jatuh semula hanya atas kesilapan | +| **Rawak** | Memilih model rawak daripada kombo untuk setiap permintaan | +| **Ditimbang** | Laluan secara berkadar berdasarkan berat yang ditetapkan bagi setiap model | +| **Kurang Digunakan** | Laluan ke model dengan permintaan terkini yang paling sedikit (menggunakan metrik kombo) | +| **Dioptimumkan Kos** | Laluan ke model yang tersedia paling murah (menggunakan jadual harga) | + +Lalai kombo global boleh ditetapkan dalam **Papan Pemuka → Tetapan → Penghalaan → Lalai Kombo**. + +--- + +### Papan Pemuka Kesihatan + +Akses melalui **Papan Pemuka → Kesihatan**. Gambaran keseluruhan kesihatan sistem masa nyata dengan 6 kad: + +| Kad | Apa yang Ditunjukkan | +| ---------------------- | ------------------------------------------------------------------------ | +| **Status Sistem** | Masa aktif, versi, penggunaan memori, direktori data | +| **Kesihatan Pembekal** | Keadaan pemutus litar setiap pembekal (Tertutup/Terbuka/Separuh Terbuka) | +| **Had Kadar** | Cooldown had kadar aktif bagi setiap akaun dengan baki masa | +| **Sekat Aktif** | Pembekal disekat buat sementara waktu oleh dasar kunci keluar | +| **Tandatangan Cache** | Statistik cache penyahduplikasian (kunci aktif, kadar pukulan) | +| **Telemetri Latensi** | p50/p95/p99 pengagregatan kependaman bagi setiap pembekal | + +**Petua Pro:** Halaman Kesihatan dimuat semula secara automatik setiap 10 saat. Gunakan kad pemutus litar untuk mengenal pasti penyedia yang mengalami masalah. diff --git a/docs/i18n/nl/API_REFERENCE.md b/docs/i18n/nl/API_REFERENCE.md new file mode 100644 index 0000000000..d995f2db2c --- /dev/null +++ b/docs/i18n/nl/API_REFERENCE.md @@ -0,0 +1,441 @@ +# API-referentie + +🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md) + +Volledige referentie voor alle OmniRoute API-eindpunten. + +--- + +## Inhoudsopgave + +- [Chat Completions](#chat-completions) +- [Embeddings](#embeddings) +- [Image Generation](#image-generation) +- [List Models](#list-models) +- [Compatibility Endpoints](#compatibility-endpoints) +- [Semantic Cache](#semantic-cache) +- [Dashboard & Management](#dashboard--management) +- [Request Processing](#request-processing) +- [Authentication](#authentication) + +--- + +## Chat-voltooiingen + +```bash +POST /v1/chat/completions +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "cc/claude-opus-4-6", + "messages": [ + {"role": "user", "content": "Write a function to..."} + ], + "stream": true +} +``` + +### Aangepaste kopteksten + +| Kop | Richting | Beschrijving | +| ------------------------ | -------- | ------------------------------------------------- | +| `X-OmniRoute-No-Cache` | Verzoek | Stel in op `true` om cache te omzeilen | +| `X-OmniRoute-Progress` | Verzoek | Ingesteld op `true` voor voortgangsgebeurtenissen | +| `Idempotency-Key` | Verzoek | Ontdubbelingssleutel (5s-venster) | +| `X-Request-Id` | Verzoek | Alternatieve ontdubbelsleutel | +| `X-OmniRoute-Cache` | Reactie | `HIT` of `MISS` (niet-streaming) | +| `X-OmniRoute-Idempotent` | Reactie | `true` indien ontdubbeld | +| `X-OmniRoute-Progress` | Reactie | `enabled` als voortgangsregistratie op | + +--- + +## Insluitingen + +```bash +POST /v1/embeddings +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "nebius/Qwen/Qwen3-Embedding-8B", + "input": "The food was delicious" +} +``` + +Beschikbare providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA. + +```bash +# List all embedding models +GET /v1/embeddings +``` + +--- + +## Beeldgeneratie + +```bash +POST /v1/images/generations +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "openai/dall-e-3", + "prompt": "A beautiful sunset over mountains", + "size": "1024x1024" +} +``` + +Beschikbare providers: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI. + +```bash +# List all image models +GET /v1/images/generations +``` + +--- + +## Lijstmodellen + +```bash +GET /v1/models +Authorization: Bearer your-api-key + +→ Returns all chat, embedding, and image models + combos in OpenAI format +``` + +--- + +## Compatibiliteitseindpunten + +| Werkwijze | Pad | Formaat | +| --------- | --------------------------- | -------------------------- | +| POST | `/v1/chat/completions` | Open AI | +| POST | `/v1/messages` | Antropisch | +| POST | `/v1/responses` | OpenAI-reacties | +| POST | `/v1/embeddings` | Open AI | +| POST | `/v1/images/generations` | Open AI | +| KRIJG | `/v1/models` | Open AI | +| POST | `/v1/messages/count_tokens` | Antropisch | +| KRIJG | `/v1beta/models` | Tweeling | +| POST | `/v1beta/models/{...path}` | Tweelingen genererenInhoud | +| POST | `/v1/api/chat` | Ollama | + +### Speciale providerroutes + +```bash +POST /v1/providers/{provider}/chat/completions +POST /v1/providers/{provider}/embeddings +POST /v1/providers/{provider}/images/generations +``` + +Het providervoorvoegsel wordt automatisch toegevoegd als het ontbreekt. Niet-overeenkomende modellen retourneren `400`. + +--- + +## Semantische cache + +```bash +# Get cache stats +GET /api/cache + +# Clear all caches +DELETE /api/cache +``` + +Voorbeeld van een antwoord: + +```json +{ + "semanticCache": { + "memorySize": 42, + "memoryMaxSize": 500, + "dbSize": 128, + "hitRate": 0.65 + }, + "idempotency": { + "activeKeys": 3, + "windowMs": 5000 + } +} +``` + +--- + +## Dashboard en beheer + +### Authenticatie + +| Eindpunt | Werkwijze | Beschrijving | +| ----------------------------- | --------- | ------------------------ | +| `/api/auth/login` | POST | Inloggen | +| `/api/auth/logout` | POST | Uitloggen | +| `/api/settings/require-login` | KRIJG/ZET | Schakel inloggen vereist | + +### Providerbeheer + +| Eindpunt | Werkwijze | Beschrijving | +| ---------------------------- | ------------------------ | ------------------------------ | +| `/api/providers` | KRIJGEN/POST | Providers weergeven / aanmaken | +| `/api/providers/[id]` | KRIJGEN/ZET/VERWIJDEREN | Beheer een aanbieder | +| `/api/providers/[id]/test` | POST | Providerverbinding testen | +| `/api/providers/[id]/models` | KRIJG | Providermodellen weergeven | +| `/api/providers/validate` | POST | Providerconfiguratie valideren | +| `/api/provider-nodes*` | Diverse | Beheer van providerknooppunten | +| `/api/provider-models` | KRIJGEN/POST/VERWIJDEREN | Aangepaste modellen | + +### OAuth-stromen + +| Eindpunt | Werkwijze | Beschrijving | +| -------------------------------- | --------- | ------------------------ | +| `/api/oauth/[provider]/[action]` | Diverse | Providerspecifieke OAuth | + +### Routering en configuratie + +| Eindpunt | Werkwijze | Beschrijving | +| --------------------- | ------------ | ---------------------------------- | +| `/api/models/alias` | KRIJGEN/POST | Modelaliassen | +| `/api/models/catalog` | KRIJG | Alle modellen per aanbieder + type | +| `/api/combos*` | Diverse | Combinatiebeheer | +| `/api/keys*` | Diverse | API-sleutelbeheer | +| `/api/pricing` | KRIJG | Modelprijzen | + +### Gebruik en analyse + +| Eindpunt | Werkwijze | Beschrijving | +| --------------------------- | --------- | --------------------------- | +| `/api/usage/history` | KRIJG | Gebruiksgeschiedenis | +| `/api/usage/logs` | KRIJG | Gebruikslogboeken | +| `/api/usage/request-logs` | KRIJG | Logboeken op aanvraagniveau | +| `/api/usage/[connectionId]` | KRIJG | Gebruik per verbinding | + +### Instellingen + +| Eindpunt | Werkwijze | Beschrijving | +| ------------------------------- | --------- | -------------------------------- | +| `/api/settings` | KRIJG/ZET | Algemene instellingen | +| `/api/settings/proxy` | KRIJG/ZET | Netwerkproxyconfiguratie | +| `/api/settings/proxy/test` | POST | Proxyverbinding testen | +| `/api/settings/ip-filter` | KRIJG/ZET | IP-toelatingslijst/blokkeerlijst | +| `/api/settings/thinking-budget` | KRIJG/ZET | Redeneren tokenbudget | +| `/api/settings/system-prompt` | KRIJG/ZET | Globale systeemprompt | + +### Toezicht + +| Eindpunt | Werkwijze | Beschrijving | +| ------------------------ | ------------------- | -------------------------- | +| `/api/sessions` | KRIJG | Actieve sessietracking | +| `/api/rate-limits` | KRIJG | Tarieflimieten per account | +| `/api/monitoring/health` | KRIJG | Gezondheidscontrole | +| `/api/cache` | OPHALEN/VERWIJDEREN | Cachestatistieken / wissen | + +### Back-up & exporteren/importeren + +| Eindpunt | Werkwijze | Beschrijving | +| --------------------------- | --------- | ------------------------------------------------ | +| `/api/db-backups` | KRIJG | Beschikbare back-ups weergeven | +| `/api/db-backups` | ZET | Maak een handmatige back-up | +| `/api/db-backups` | POST | Herstellen vanaf een specifieke back-up | +| `/api/db-backups/export` | KRIJG | Database downloaden als .sqlite-bestand | +| `/api/db-backups/import` | POST | Upload .sqlite-bestand om database te vervangen | +| `/api/db-backups/exportAll` | KRIJG | Volledige back-up downloaden als .tar.gz-archief | + +### Cloudsynchronisatie + +| Eindpunt | Werkwijze | Beschrijving | +| ---------------------- | --------- | ------------------------------ | +| `/api/sync/cloud` | Diverse | Cloudsynchronisatiebewerkingen | +| `/api/sync/initialize` | POST | Synchronisatie initialiseren | +| `/api/cloud/*` | Diverse | Cloudbeheer | + +### CLI-hulpmiddelen + +| Eindpunt | Werkwijze | Beschrijving | +| ---------------------------------- | --------- | -------------------- | +| `/api/cli-tools/claude-settings` | KRIJG | Claude CLI-status | +| `/api/cli-tools/codex-settings` | KRIJG | Codex CLI-status | +| `/api/cli-tools/droid-settings` | KRIJG | Droid CLI-status | +| `/api/cli-tools/openclaw-settings` | KRIJG | OpenClaw CLI-status | +| `/api/cli-tools/runtime/[toolId]` | KRIJG | Algemene CLI-runtime | + +CLI-reacties omvatten: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. + +### Veerkracht en snelheidslimieten + +| Eindpunt | Werkwijze | Beschrijving | +| ----------------------- | --------- | --------------------------------------- | +| `/api/resilience` | KRIJG/ZET | Veerkrachtprofielen ophalen/bijwerken | +| `/api/resilience/reset` | POST | Stroomonderbrekers resetten | +| `/api/rate-limits` | KRIJG | Status van tarieflimiet per account | +| `/api/rate-limit` | KRIJG | Configuratie van globale tarieflimieten | + +### Evaluaties + +| Eindpunt | Werkwijze | Beschrijving | +| ------------ | ------------ | ----------------------------------------------- | +| `/api/evals` | KRIJGEN/POST | Evaluatiesuites weergeven / evaluatie uitvoeren | + +### Beleid + +| Eindpunt | Werkwijze | Beschrijving | +| --------------- | ------------------------ | --------------------- | +| `/api/policies` | KRIJGEN/POST/VERWIJDEREN | Routingbeleid beheren | + +### Naleving + +| Eindpunt | Werkwijze | Beschrijving | +| --------------------------- | --------- | --------------------------------- | +| `/api/compliance/audit-log` | KRIJG | Nalevingsauditlogboek (laatste N) | + +### v1beta (Gemini-compatibel) + +| Eindpunt | Werkwijze | Beschrijving | +| -------------------------- | --------- | --------------------------------- | +| `/v1beta/models` | KRIJG | Lijstmodellen in Gemini-formaat | +| `/v1beta/models/{...path}` | POST | Gemini `generateContent` eindpunt | + +Deze eindpunten weerspiegelen het API-formaat van Gemini voor klanten die native Gemini SDK-compatibiliteit verwachten. + +### Interne/systeem-API's + +| Eindpunt | Werkwijze | Beschrijving | +| --------------- | --------- | -------------------------------------------------------------- | +| `/api/init` | KRIJG | Initialisatiecontrole van applicatie (gebruikt bij eerste run) | +| `/api/tags` | KRIJG | Ollama-compatibele modeltags (voor Ollama-klanten) | +| `/api/restart` | POST | Trigger een sierlijke herstart van de server | +| `/api/shutdown` | POST | Trigger een elegante serveruitschakeling | + +> **Opmerking:** Deze eindpunten worden intern gebruikt door het systeem of voor Ollama-clientcompatibiliteit. Ze worden doorgaans niet door eindgebruikers gebeld. + +--- + +## Audiotranscriptie + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data +``` + +Transcribeer audiobestanden met Deepgram of AssemblyAI. + +**Verzoek:** + +```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" +``` + +**Reactie:** + +```json +{ + "text": "Hello, this is the transcribed audio content.", + "task": "transcribe", + "language": "en", + "duration": 12.5 +} +``` + +**Ondersteunde providers:** `deepgram/nova-3`, `assemblyai/best`. + +**Ondersteunde formaten:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +## Ollama-compatibiliteit + +Voor klanten die het API-formaat van Ollama gebruiken: + +```bash +# Chat endpoint (Ollama format) +POST /v1/api/chat + +# Model listing (Ollama format) +GET /api/tags +``` + +Verzoeken worden automatisch vertaald tussen Ollama en interne formaten. + +--- + +## Telemetrie + +```bash +# Get latency telemetry summary (p50/p95/p99 per provider) +GET /api/telemetry/summary +``` + +**Reactie:** + +```json +{ + "providers": { + "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, + "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } + } +} +``` + +--- + +## Begroting + +```bash +# Get budget status for all API keys +GET /api/usage/budget + +# Set or update a budget +POST /api/usage/budget +Content-Type: application/json + +{ + "keyId": "key-123", + "limit": 50.00, + "period": "monthly" +} +``` + +--- + +## Beschikbaarheid van modellen + +```bash +# Get real-time model availability across all providers +GET /api/models/availability + +# Check availability for a specific model +POST /api/models/availability +Content-Type: application/json + +{ + "model": "claude-sonnet-4-5-20250929" +} +``` + +--- + +## Verzoekverwerking + +1. Klant stuurt verzoek naar `/v1/*` +2. Route-handleraanroepen `handleChat`, `handleEmbedding`, `handleAudioTranscription` of `handleImageGeneration` +3. Model is opgelost (directe provider/model of alias/combo) +4. Inloggegevens geselecteerd uit lokale DB met filtering van accountbeschikbaarheid +5. Voor chat: `handleChatCore` — formaatdetectie, vertaling, cachecontrole, idempotentiecontrole +6. Provider-uitvoerder verzendt een upstream-verzoek +7. Antwoord terugvertaald naar clientformaat (chat) of geretourneerd zoals het is (insluitingen/afbeeldingen/audio) +8. Verbruik/logboekregistratie +9. Fallback is van toepassing op fouten volgens comboregels + +Volledige architectuurreferentie: [**OMNI_TOKEN_119**](ARCHITECTURE.md) + +--- + +## Authenticatie + +- Dashboardroutes (`/dashboard/*`) gebruiken `auth_token` cookie +- Inloggen maakt gebruik van opgeslagen wachtwoord-hash; terugval naar `INITIAL_PASSWORD` +- `requireLogin` schakelbaar via `/api/settings/require-login` +- Voor `/v1/*` routes is optioneel een Bearer API-sleutel vereist wanneer `REQUIRE_API_KEY=true` diff --git a/docs/i18n/nl/ARCHITECTURE.md b/docs/i18n/nl/ARCHITECTURE.md new file mode 100644 index 0000000000..2027e553e0 --- /dev/null +++ b/docs/i18n/nl/ARCHITECTURE.md @@ -0,0 +1,781 @@ +# OmniRoute-architectuur + +🌐 **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) + +_Laatst bijgewerkt: 2026-02-18_ + +## Samenvatting + +OmniRoute is een lokale AI-routeringsgateway en dashboard gebouwd op Next.js. +Het biedt één OpenAI-compatibel eindpunt (`/v1/*`) en routeert verkeer over meerdere upstream-providers met vertaling, fallback, tokenvernieuwing en gebruiksregistratie. + +Kernmogelijkheden: + +- OpenAI-compatibel API-oppervlak voor CLI/tools (28 providers) +- Verzoek/antwoord-vertaling in verschillende providerformaten +- Modelcombo fallback (reeks met meerdere modellen) +- Terugval op accountniveau (meerdere accounts per provider) +- OAuth + API-sleutelproviderverbindingsbeheer +- Generatie inbedden via `/v1/embeddings` (6 providers, 9 modellen) +- Beeldgeneratie via `/v1/images/generations` (4 providers, 9 modellen) +- Denk aan het parseren van tags (`...`) voor redeneermodellen +- Reactieopschoning voor strikte OpenAI SDK-compatibiliteit +- Rolnormalisatie (ontwikkelaar → systeem, systeem → gebruiker) voor compatibiliteit tussen providers +- Gestructureerde uitvoerconversie (json_schema → Gemini responseSchema) +- Lokale persistentie voor providers, sleutels, aliassen, combo's, instellingen, prijzen +- Gebruik/kosten bijhouden en verzoekregistratie +- Optionele cloudsynchronisatie voor synchronisatie van meerdere apparaten/statussen +- IP-toelatingslijst/blokkeerlijst voor API-toegangscontrole +- Meedenken over budgetbeheer (passthrough/auto/custom/adaptive) +- Globale systeemprompt-injectie +- Sessie volgen en vingerafdrukken maken +- Verbeterde tarieflimieten per account met providerspecifieke profielen +- Stroomonderbrekerpatroon voor veerkracht van de provider +- Bescherming tegen donderende kuddes met mutex-vergrendeling +- Op handtekeningen gebaseerde cache voor deduplicatie van verzoeken +- Domeinlaag: modelbeschikbaarheid, kostenregels, fallback-beleid, lock-outbeleid +- Persistentie van domeinstatus (SQLite-schrijfcache voor fallbacks, budgetten, uitsluitingen, stroomonderbrekers) +- Beleidsengine voor gecentraliseerde verzoekevaluatie (lockout → budget → fallback) +- Telemetrie aanvragen met p50/p95/p99-latency-aggregatie +- Correlatie-ID (X-Request-Id) voor end-to-end tracering +- Compliance-auditregistratie met opt-out per API-sleutel +- Evaluatiekader voor LLM-kwaliteitsborging +- Veerkracht UI-dashboard met realtime stroomonderbrekerstatus +- Modulaire OAuth-providers (12 afzonderlijke modules onder `src/lib/oauth/providers/`) + +Primair runtimemodel: + +- Next.js-approutes onder `src/app/api/*` implementeren zowel dashboard-API's als compatibiliteits-API's +- Een gedeelde SSE/routing-kern in `src/sse/*` + `open-sse/*` zorgt voor de uitvoering, vertaling, streaming, fallback en gebruik van de provider + +## Reikwijdte en grenzen + +### Binnen bereik + +- Lokale gateway-runtime +- Dashboardbeheer-API's +- Providerverificatie en tokenvernieuwing +- Vraag vertaling en SSE-streaming aan +- Lokale status + gebruikspersistentie +- Optionele cloudsynchronisatie-orkestratie + +### Buiten bereik + +- Implementatie van cloudservices achter `NEXT_PUBLIC_CLOUD_URL` +- Provider SLA/controlevlak buiten het lokale proces +- Externe CLI-binaire bestanden zelf (Claude CLI, Codex CLI, enz.) + +## Systeemcontext op hoog 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 +``` + +## Kernruntime-componenten + +## 1) API- en routeringslaag (Next.js app-routes) + +Hoofdmappen: + +- `src/app/api/v1/*` en `src/app/api/v1beta/*` voor compatibiliteits-API's +- `src/app/api/*` voor beheer-/configuratie-API's +- Volgende herschrijvingen in `next.config.mjs` brengen `/v1/*` in kaart naar `/api/v1/*` + +Belangrijke compatibiliteitsroutes: + +- `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` — bevat aangepaste modellen met `custom: true` +- `src/app/api/v1/embeddings/route.ts` — generatie van inbedding (6 providers) +- `src/app/api/v1/images/generations/route.ts` — genereren van afbeeldingen (4+ providers incl. Antigravity/Nebius) +- `src/app/api/v1/messages/count_tokens/route.ts` +- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — speciale chat per provider +- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — speciale insluitingen per provider +- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — speciale afbeeldingen per provider +- `src/app/api/v1beta/models/route.ts` +- `src/app/api/v1beta/models/[...path]/route.ts` + +Beheerdomeinen: + +- Authenticatie/instellingen: `src/app/api/auth/*`, `src/app/api/settings/*` +- Providers/verbindingen: `src/app/api/providers*` +- Providerknooppunten: `src/app/api/provider-nodes*` +- Aangepaste modellen: `src/app/api/provider-models` (GET/POST/DELETE) +- Modelcatalogus: `src/app/api/models/catalog` (GET) +- Proxyconfiguratie: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST) +- OAuth: `src/app/api/oauth/*` +- Sleutels/aliassen/combo's/prijzen: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing` +- Gebruik: `src/app/api/usage/*` +- Synchroniseren/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*` +- CLI-hulpmiddelen: `src/app/api/cli-tools/*` +- IP-filter: `src/app/api/settings/ip-filter` (GET/PUT) +- Denkbudget: `src/app/api/settings/thinking-budget` (GET/PUT) +- Systeemprompt: `src/app/api/settings/system-prompt` (GET/PUT) +- Sessies: `src/app/api/sessions` (KRIJGEN) +- Tarieflimieten: `src/app/api/rate-limits` (GET) +- Veerkracht: `src/app/api/resilience` (GET/PATCH) — providerprofielen, stroomonderbreker, snelheidslimietstatus +- Veerkracht reset: `src/app/api/resilience/reset` (POST) — reset onderbrekers + cooldowns +- Cachestatistieken: `src/app/api/cache/stats` (GET/DELETE) +- Beschikbaarheid van modellen: `src/app/api/models/availability` (GET/POST) +- Telemetrie: `src/app/api/telemetry/summary` (GET) +- Budget: `src/app/api/usage/budget` (GET/POST) +- Terugvalketens: `src/app/api/fallback/chains` (GET/POST/DELETE) +- Nalevingsaudit: `src/app/api/compliance/audit-log` (GET) +- Evaluaties: `src/app/api/evals` (KRIJGEN/POST), `src/app/api/evals/[suiteId]` (KRIJGEN) +- Beleid: `src/app/api/policies` (GET/POST) + +## 2) SSE + vertaalkern + +Hoofdstroommodules: + +- Toegang: `src/sse/handlers/chat.ts` +- Kernorkestratie: `open-sse/handlers/chatCore.ts` +- Uitvoeringsadapters van provider: `open-sse/executors/*` +- Formaatdetectie/providerconfiguratie: `open-sse/services/provider.ts` +- Model parseren/oplossen: `src/sse/services/model.ts`, `open-sse/services/model.ts` +- Reservelogica voor accounts: `open-sse/services/accountFallback.ts` +- Vertaalregister: `open-sse/translator/index.ts` +- Streamtransformaties: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts` +- Gebruiksextractie/normalisatie: `open-sse/utils/usageTracking.ts` +- Denk aan tag-parser: `open-sse/utils/thinkTagParser.ts` +- Inbeddingshandler: `open-sse/handlers/embeddings.ts` +- Providerregister insluiten: `open-sse/config/embeddingRegistry.ts` +- Handler voor het genereren van afbeeldingen: `open-sse/handlers/imageGeneration.ts` +- Register van beeldaanbieder: `open-sse/config/imageRegistry.ts` +- Reactie-opschoning: `open-sse/handlers/responseSanitizer.ts` +- Rolnormalisatie: `open-sse/services/roleNormalizer.ts` + +Diensten (bedrijfslogica): + +- Accountselectie/score: `open-sse/services/accountSelector.ts` +- Contextlevenscyclusbeheer: `open-sse/services/contextManager.ts` +- Handhaving van IP-filter: `open-sse/services/ipFilter.ts` +- Sessie volgen: `open-sse/services/sessionManager.ts` +- Ontdubbeling aanvragen: `open-sse/services/signatureCache.ts` +- Systeemprompt injectie: `open-sse/services/systemPrompt.ts` +- Denken aan budgetbeheer: `open-sse/services/thinkingBudget.ts` +- Routering van wildcardmodellen: `open-sse/services/wildcardRouter.ts` +- Tarieflimietbeheer: `open-sse/services/rateLimitManager.ts` +- Stroomonderbreker: `open-sse/services/circuitBreaker.ts` + +Domeinlaagmodules: + +- Beschikbaarheid van modellen: `src/lib/domain/modelAvailability.ts` +- Kostenregels/budgetten: `src/lib/domain/costRules.ts` +- Terugvalbeleid: `src/lib/domain/fallbackPolicy.ts` +- Combo-oplosser: `src/lib/domain/comboResolver.ts` +- Uitsluitingsbeleid: `src/lib/domain/lockoutPolicy.ts` +- Beleidsengine: `src/domain/policyEngine.ts` — gecentraliseerde uitsluiting → budget → fallback-evaluatie +- Foutcodecatalogus: `src/lib/domain/errorCodes.ts` +- Verzoek-ID: `src/lib/domain/requestId.ts` +- Time-out ophalen: `src/lib/domain/fetchTimeout.ts` +- Telemetrie aanvragen: `src/lib/domain/requestTelemetry.ts` +- Naleving/audit: `src/lib/domain/compliance/index.ts` +- Evaluatie loper: `src/lib/domain/evalRunner.ts` +- Persistentie van domeinstatus: `src/lib/db/domainState.ts` — SQLite CRUD voor fallback-ketens, budgetten, kostengeschiedenis, uitsluitingsstatus, stroomonderbrekers + +OAuth-providermodules (12 afzonderlijke bestanden onder `src/lib/oauth/providers/`): + +- Registerindex: `src/lib/oauth/providers/index.ts` +- Individuele providers: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts` +- Dunne verpakking: `src/lib/oauth/providers.ts` — exporteert opnieuw vanuit afzonderlijke modules + +## 3) Persistentielaag + +Primaire staat DB: + +- `src/lib/localDb.ts` +- bestand: `${DATA_DIR}/db.json` (of `$XDG_CONFIG_HOME/omniroute/db.json` indien ingesteld, anders `~/.omniroute/db.json`) +- entiteiten: providerConnections, providerNodes, modelAliases, combo's, apiKeys, instellingen, prijzen, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt** + +Gebruiksdatabase: + +- `src/lib/usageDb.ts` +- bestanden: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- volgt hetzelfde basismapbeleid als `localDb` (`DATA_DIR`, daarna `XDG_CONFIG_HOME/omniroute` indien ingesteld) +- opgesplitst in gerichte submodules: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts` + +Domeinstatus DB (SQLite): + +- `src/lib/db/domainState.ts` — CRUD-bewerkingen voor domeinstatus +- Tabellen (aangemaakt in `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers` +- Doorschrijfcachepatroon: kaarten in het geheugen zijn gezaghebbend tijdens runtime; mutaties worden synchroon naar SQLite geschreven; status wordt hersteld vanuit DB bij koude start + +## 4) Auth + beveiligingsoppervlakken + +- Dashboardcookieverificatie: `src/proxy.ts`, `src/app/api/auth/login/route.ts` +- API-sleutel genereren/verificatie: `src/shared/utils/apiKey.ts` +- Providergeheimen bleven bestaan in `providerConnections` vermeldingen +- Ondersteuning voor uitgaande proxy's via `open-sse/utils/proxyFetch.ts` (env vars) en `open-sse/utils/networkProxy.ts` (configureerbaar per provider of wereldwijd) + +## 5) Cloudsynchronisatie + +- Initiële planner: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts` +- Periodieke taak: `src/shared/services/cloudSyncScheduler.ts` +- Controleroute: `src/app/api/sync/cloud/route.ts` + +## Aanvraaglevenscyclus (`/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 + terugvalstroom voor accounts + +```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] +``` + +Terugvalbeslissingen worden aangestuurd door `open-sse/services/accountFallback.ts` met behulp van statuscodes en heuristieken voor foutmeldingen. + +## OAuth-onboarding en levenscyclus van tokenvernieuwing + +```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 +``` + +Vernieuwen tijdens live verkeer wordt uitgevoerd binnen `open-sse/handlers/chatCore.ts` via uitvoerder `refreshCredentials()`. + +## Cloud Sync-levenscyclus (inschakelen / synchroniseren / uitschakelen) + +```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 +``` + +Periodieke synchronisatie wordt geactiveerd door `CloudSyncScheduler` wanneer de cloud is ingeschakeld. + +## Gegevensmodel en opslagkaart + +```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 + } +``` + +Fysieke opslagbestanden: + +- hoofdstatus: `${DATA_DIR}/db.json` (of `$XDG_CONFIG_HOME/omniroute/db.json` indien ingesteld, anders `~/.omniroute/db.json`) +- gebruiksstatistieken: `${DATA_DIR}/usage.json` +- logregels opvragen: `${DATA_DIR}/log.txt` +- optionele foutopsporingssessies voor vertalers/verzoeken: `/logs/...` + +## Implementatietopologie + +```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 +``` + +## Moduletoewijzing (beslissingskritisch) + +### Route- en API-modules + +- `src/app/api/v1/*`, `src/app/api/v1beta/*`: compatibiliteits-API's +- `src/app/api/v1/providers/[provider]/*`: speciale routes per provider (chat, insluitingen, afbeeldingen) +- `src/app/api/providers*`: provider CRUD, validatie, testen +- `src/app/api/provider-nodes*`: aangepast compatibel knooppuntbeheer +- `src/app/api/provider-models`: aangepast modelbeheer (CRUD) +- `src/app/api/models/catalog`: volledige modelcatalogus-API (alle typen gegroepeerd op provider) +- `src/app/api/oauth/*`: OAuth/apparaatcodestromen +- `src/app/api/keys*`: levenscyclus van lokale API-sleutel +- `src/app/api/models/alias`: aliasbeheer +- `src/app/api/combos*`: fallback-combobeheer +- `src/app/api/pricing`: prijsoverschrijvingen voor kostenberekening +- `src/app/api/settings/proxy`: proxyconfiguratie (GET/PUT/DELETE) +- `src/app/api/settings/proxy/test`: uitgaande proxy-connectiviteitstest (POST) +- `src/app/api/usage/*`: API's voor gebruik en logboeken +- `src/app/api/sync/*` + `src/app/api/cloud/*`: cloudsynchronisatie en cloudgerichte helpers +- `src/app/api/cli-tools/*`: lokale CLI-configuratieschrijvers/-controleurs +- `src/app/api/settings/ip-filter`: IP-toelatingslijst/blokkeerlijst (GET/PUT) +- `src/app/api/settings/thinking-budget`: configuratie voor denkend tokenbudget (GET/PUT) +- `src/app/api/settings/system-prompt`: algemene systeemprompt (GET/PUT) +- `src/app/api/sessions`: actieve sessielijst (GET) +- `src/app/api/rate-limits`: tarieflimietstatus per account (GET) + +### Routing- en uitvoeringskern + +- `src/sse/handlers/chat.ts`: verzoekparse, combo-afhandeling, accountselectielus +- `open-sse/handlers/chatCore.ts`: vertaling, verzending van de uitvoerder, afhandeling van opnieuw proberen/vernieuwen, stream-instellingen +- `open-sse/executors/*`: providerspecifiek netwerk- en formaatgedrag + +### Vertaalregister en formaatconverters + +- `open-sse/translator/index.ts`: register en orkestratie van vertalers +- Vertalers aanvragen: `open-sse/translator/request/*` +- Antwoordvertalers: `open-sse/translator/response/*` +- Formaatconstanten: `open-sse/translator/formats.ts` + +### Volharding + +- `src/lib/localDb.ts`: persistente configuratie/status +- `src/lib/usageDb.ts`: gebruiksgeschiedenis en logbestanden met doorlopende aanvragen + +## Dekking van de provider-uitvoerder (strategiepatroon) + +Elke provider heeft een gespecialiseerde uitvoerder die `BaseExecutor` uitbreidt (in `open-sse/executors/base.ts`), die zorgt voor het bouwen van URL's, het bouwen van headers, nieuwe pogingen met exponentiële uitstel, hooks voor het vernieuwen van referenties en de orkestratiemethode `execute()`. + +| executeur | Aanbieder(s) | Speciale behandeling | +| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Verbijstering, Samen, Vuurwerk, Cerebras, Cohere, NVIDIA | Dynamische URL/header-configuratie per provider | +| `AntigravityExecutor` | Google Antizwaartekracht | Aangepaste project-/sessie-ID's, opnieuw proberen na parseren | +| `CodexExecutor` | OpenAI-codex | Injecteert systeeminstructies, dwingt redeneerinspanning af | +| `CursorExecutor` | Cursor-IDE | ConnectRPC-protocol, Protobuf-codering, ondertekening aanvragen via checksum | +| `GithubExecutor` | GitHub-copiloot | Copilot-token vernieuwen, VSCode-nabootsende headers | +| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binair formaat → SSE-conversie | +| `GeminiCLIExecutor` | Tweeling CLI | Vernieuwingscyclus van Google OAuth-token | + +Alle andere providers (inclusief aangepaste compatibele knooppunten) gebruiken de `DefaultExecutor`. + +## Compatibiliteitsmatrix voor providers + +| Aanbieder | Formaat | Autorisatie | Stroom | Niet-stream | Token vernieuwen | Gebruiks-API | +| ----------------- | ------------------ | ---------------------- | ---------------- | ----------- | ---------------- | -------------------------- | +| Claude | claude | API-sleutel / OAuth | ✅ | ✅ | ✅ | ⚠️Alleen beheerder | +| Tweeling | Tweeling | API-sleutel / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudconsole | +| Tweeling CLI | tweeling-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudconsole | +| Antizwaartekracht | anti-zwaartekracht | OAuth | ✅ | ✅ | ✅ | ✅ Volledige quota-API | +| Open AI | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| Codex | openai-reacties | OAuth | ✅ gedwongen | ❌ | ✅ | ✅ Tarieflimieten | +| GitHub-copiloot | openai | OAuth + Copilot-token | ✅ | ✅ | ✅ | ✅ Momentopnamen van quota | +| Cursor | cursor | Aangepaste controlesom | ✅ | ✅ | ❌ | ❌ | +| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Gebruikslimieten | +| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️Per aanvraag | +| iFlow | openai | OAuth (basis) | ✅ | ✅ | ✅ | ⚠️Per aanvraag | +| OpenRouter | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| GLM/Kimi/MiniMax | claude | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| DeepSeek | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| Groq | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| xAI (Grok) | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| Mistral | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| Verbijstering | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| Samen AI | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| Vuurwerk AI | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| Hersenen | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| Cohier | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | +| NVIDIA NIM | openai | API-sleutel | ✅ | ✅ | ❌ | ❌ | + +## Dekking van formaatvertalingen + +Gedetecteerde bronformaten zijn onder meer: + +- `openai` +- `openai-responses` +- `claude` +- `gemini` + +Doelformaten zijn onder meer: + +- OpenAI-chat/reacties + -Claude +- Gemini/Gemini-CLI/Antigravity-envelop +- Kiro +- Cursor + +Vertalingen gebruiken **OpenAI als hubformaat** — alle conversies gaan via OpenAI als tussenproduct: + +``` +Source Format → OpenAI (hub) → Target Format +``` + +Vertalingen worden dynamisch geselecteerd op basis van de vorm van de bronpayload en het doelformaat van de provider. + +Extra verwerkingslagen in de vertaalpijplijn: + +- **Opschoning van reacties** — Verwijdert niet-standaardvelden uit reacties in OpenAI-formaat (zowel streaming als niet-streaming) om strikte SDK-naleving te garanderen +- **Rolnormalisatie** — Converteert `developer` → `system` voor niet-OpenAI-doelen; voegt `system` → `user` samen voor modellen die de systeemrol afwijzen (GLM, ERNIE) +- **Think tag-extractie** — Parseert `...` blokken uit de inhoud in het veld `reasoning_content` +- **Gestructureerde uitvoer** — Converteert OpenAI `response_format.json_schema` naar Gemini's `responseMimeType` + `responseSchema` + +## Ondersteunde API-eindpunten + +| Eindpunt | Formaat | Behandelaar | +| -------------------------------------------------- | -------------------- | --------------------------------------------------------------- | +| `POST /v1/chat/completions` | OpenAI-chat | `src/sse/handlers/chat.ts` | +| `POST /v1/messages` | Claude-berichten | Dezelfde handler (automatisch gedetecteerd) | +| `POST /v1/responses` | OpenAI-reacties | `open-sse/handlers/responsesHandler.ts` | +| `POST /v1/embeddings` | OpenAI-insluitingen | `open-sse/handlers/embeddings.ts` | +| `GET /v1/embeddings` | Modellijst | API-route | +| `POST /v1/images/generations` | OpenAI-afbeeldingen | `open-sse/handlers/imageGeneration.ts` | +| `GET /v1/images/generations` | Modellijst | API-route | +| `POST /v1/providers/{provider}/chat/completions` | OpenAI-chat | Toegewijd per provider met modelvalidatie | +| `POST /v1/providers/{provider}/embeddings` | OpenAI-insluitingen | Toegewijd per provider met modelvalidatie | +| `POST /v1/providers/{provider}/images/generations` | OpenAI-afbeeldingen | Toegewijd per provider met modelvalidatie | +| `POST /v1/messages/count_tokens` | Claude-tokentelling | API-route | +| `GET /v1/models` | OpenAI-modellenlijst | API-route (chat + insluiten + afbeelding + aangepaste modellen) | +| `GET /api/models/catalog` | Catalogus | Alle modellen gegroepeerd op aanbieder + type | +| `POST /v1beta/models/*:streamGenerateContent` | Gemini geboren | API-route | +| `GET/PUT/DELETE /api/settings/proxy` | Proxyconfiguratie | Netwerkproxyconfiguratie | +| `POST /api/settings/proxy/test` | Proxy-connectiviteit | Eindpunt proxystatus/connectiviteitstest | +| `GET/POST/DELETE /api/provider-models` | Aangepaste modellen | Maatwerkmodelbeheer per provider | + +## Bypass-handler + +De bypass-handler (`open-sse/utils/bypassHandler.ts`) onderschept bekende "wegwerp"-verzoeken van Claude CLI (opwarmingspings, titelextracties en tokentellingen) en retourneert een **vals antwoord** zonder upstream-providertokens te verbruiken. Dit wordt alleen geactiveerd als `User-Agent` `claude-cli` bevat. + +## Loggerpijplijn aanvragen + +De verzoeklogger (`open-sse/utils/requestLogger.ts`) biedt een pijplijn voor het opsporen van fouten in 7 fasen, standaard uitgeschakeld en ingeschakeld 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 +``` + +Voor elke verzoeksessie worden bestanden naar `/logs//` geschreven. + +## Faalmodi en veerkracht + +## 1) Beschikbaarheid van account/provider + +- Afkoelperiode van provideraccount bij tijdelijke/snelheids-/authenticatiefouten +- accountterugval voordat het verzoek mislukt +- Terugval op combo-modellen wanneer het huidige model-/providerpad is uitgeput + +## 2) Vervaldatum van token + +- vooraf controleren en vernieuwen met nieuwe poging voor vernieuwbare providers +- 401/403 opnieuw proberen na vernieuwingspoging in kernpad + +## 3) Streamveiligheid + +- verbindingsbewuste streamcontroller +- vertaalstroom met end-of-stream flush en `[DONE]` afhandeling +- Terugval in gebruiksschattingen wanneer metagegevens over het gebruik van de provider ontbreken + +## 4) Verslechtering van cloudsynchronisatie + +- Er zijn synchronisatiefouten opgetreden, maar de lokale runtime gaat door +- Scheduler heeft logica die geschikt is voor opnieuw proberen, maar periodieke uitvoering roept momenteel standaard synchronisatie met één poging aan + +## 5) Gegevensintegriteit + +- DB-vormmigratie/reparatie voor ontbrekende sleutels +- corrupte JSON-resetbeveiligingen voor localDb en UseDb + +## Waarneembaarheid en operationele signalen + +Bronnen voor runtime-zichtbaarheid: + +- consolelogboeken van `src/sse/utils/logger.ts` +- gebruiksaggregaten per verzoek in `usage.json` +- tekstueel verzoek status inloggen `log.txt` +- optionele diepe verzoek-/vertaallogboeken onder `logs/` wanneer `ENABLE_REQUEST_LOGS=true` +- eindpunten voor dashboardgebruik (`/api/usage/*`) voor UI-verbruik + +## Beveiligingsgevoelige grenzen + +- JWT-geheim (`JWT_SECRET`) beveiligt de verificatie/ondertekening van dashboardsessiecookies +- Initiële wachtwoord-fallback (`INITIAL_PASSWORD`, standaard `123456`) moet worden overschreven in echte implementaties +- API-sleutel HMAC-geheim (`API_KEY_SECRET`) beveiligt het gegenereerde lokale API-sleutelformaat +- Providergeheimen (API-sleutels/tokens) worden bewaard in de lokale database en moeten worden beschermd op bestandssysteemniveau +- Cloudsynchronisatie-eindpunten zijn afhankelijk van API-sleutelauthenticatie en machine-ID-semantiek + +## Omgevings- en runtimematrix + +Omgevingsvariabelen die actief worden gebruikt door code: + +- App/authenticatie: `JWT_SECRET`, `INITIAL_PASSWORD` +- Opslag: `DATA_DIR` +- Compatibel knooppuntgedrag: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` +- Optionele opslagbasisoverschrijving (Linux/macOS wanneer `DATA_DIR` niet is ingesteld): `XDG_CONFIG_HOME` +- Beveiligingshashing: `API_KEY_SECRET`, `MACHINE_ID_SALT` +- Logboekregistratie: `ENABLE_REQUEST_LOGS` +- Synchroniseren/cloud-URL's: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL` +- Uitgaande proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` en varianten in kleine letters +- SOCKS5-functievlaggen: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` +- Platform-/runtime-helpers (niet app-specifieke configuratie): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME` + +## Bekende architecturale aantekeningen + +1. `usageDb` en `localDb` delen nu hetzelfde basismapbeleid (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) met oudere bestandsmigratie. +2. `/api/v1/route.ts` retourneert een statische modellenlijst en is niet de belangrijkste modellenbron die wordt gebruikt door `/v1/models`. +3. Verzoeklogger schrijft volledige headers/body indien ingeschakeld; behandel de logmap als gevoelig. +4. Het cloudgedrag is afhankelijk van de juiste `NEXT_PUBLIC_BASE_URL` en bereikbaarheid van het cloudeindpunt. +5. De map `open-sse/` wordt gepubliceerd als het `@omniroute/open-sse` **npm-werkruimtepakket**. De broncode importeert deze via `@omniroute/open-sse/...` (opgelost door Next.js `transpilePackages`). Bestandspaden in dit document gebruiken nog steeds de mapnaam `open-sse/` voor consistentie. +6. Grafieken in het dashboard maken gebruik van **Recharts** (op SVG-basis) voor toegankelijke, interactieve analytische visualisaties (staafdiagrammen voor modelgebruik, uitsplitsingstabellen van providers met succespercentages). +7. E2E-tests gebruiken **Toneelschrijver** (`tests/e2e/`), uitgevoerd via `npm run test:e2e`. Eenheidstests gebruiken **Node.js testrunner** (`tests/unit/`), uitgevoerd via `npm run test:plan3`. Broncode onder `src/` is **TypeScript** (`.ts`/`.tsx`); de `open-sse/` werkruimte blijft JavaScript (`.js`). +8. De instellingenpagina is onderverdeeld in 5 tabbladen: Beveiliging, Routing (6 globale strategieën: eerst vullen, round-robin, p2c, willekeurig, minst gebruikt, kostengeoptimaliseerd), veerkracht (bewerkbare snelheidslimieten, stroomonderbreker, beleid), AI (denkbudget, systeemprompt, promptcache), Geavanceerd (proxy). + +## Operationele verificatiechecklist + +- Bouw vanaf de bron: `npm run build` +- Bouw Docker-afbeelding: `docker build -t omniroute .` +- Start de service en controleer: +- `GET /api/settings` +- `GET /api/v1/models` +- CLI-doelbasis-URL moet `http://:20128/v1` zijn wanneer `PORT=20128` diff --git a/docs/i18n/nl/CODEBASE_DOCUMENTATION.md b/docs/i18n/nl/CODEBASE_DOCUMENTATION.md new file mode 100644 index 0000000000..4a99fa3188 --- /dev/null +++ b/docs/i18n/nl/CODEBASE_DOCUMENTATION.md @@ -0,0 +1,589 @@ +# omniroute — Codebase-documentatie + +🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md) + +> Een uitgebreide, beginnersvriendelijke gids voor de **omniroute** AI-proxyrouter met meerdere providers. + +--- + +## 1. Wat is omniroute? + +omniroute is een **proxyrouter** die zich tussen AI-clients (Claude CLI, Codex, Cursor IDE, enz.) en AI-providers (Anthropic, Google, OpenAI, AWS, GitHub, enz.) bevindt. Het lost één groot probleem op: + +> **Verschillende AI-clients spreken verschillende "talen" (API-formaten), en verschillende AI-providers verwachten ook verschillende "talen".** omniroute vertaalt automatisch tussen hen. + +Zie het als een universele vertaler bij de Verenigde Naties: elke afgevaardigde kan elke taal spreken, en de vertaler zet deze om voor elke andere afgevaardigde. + +--- + +## 2. Architectuuroverzicht + +```mermaid +graph LR + subgraph Clients + A[Claude CLI] + B[Codex] + C[Cursor IDE] + D[OpenAI-compatible] + end + + subgraph omniroute + E[Handler Layer] + F[Translator Layer] + G[Executor Layer] + H[Services Layer] + end + + subgraph Providers + I[Anthropic Claude] + J[Google Gemini] + K[OpenAI / Codex] + L[GitHub Copilot] + M[AWS Kiro] + N[Antigravity] + O[Cursor API] + end + + A --> E + B --> E + C --> E + D --> E + E --> F + F --> G + G --> I + G --> J + G --> K + G --> L + G --> M + G --> N + G --> O + H -.-> E + H -.-> G +``` + +### Kernprincipe: Hub-and-spoke-vertaling + +Alle formaatvertalingen passeren het **OpenAI-formaat als hub**: + +``` +Client Format → [OpenAI Hub] → Provider Format (request) +Provider Format → [OpenAI Hub] → Client Format (response) +``` + +Dit betekent dat u slechts **N vertalers** nodig heeft (één per formaat) in plaats van **N²** (elk paar). + +--- + +## 3. Projectstructuur + +``` +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 +``` + +--- + +## 4. Uitsplitsing per module + +### 4.1 configuratie (`open-sse/config/`) + +De **enige bron van waarheid** voor alle providerconfiguraties. + +| Bestand | Doel | +| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `constants.ts` | `PROVIDERS` object met basis-URL's, OAuth-inloggegevens (standaard), headers en standaardsysteemprompts voor elke provider. Definieert ook `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG` en `SKIP_PATTERNS`. | +| `credentialLoader.ts` | Laadt externe inloggegevens van `data/provider-credentials.json` en voegt deze samen met de hardgecodeerde standaardwaarden in `PROVIDERS`. Houdt geheimen buiten de broncontrole en behoudt achterwaartse compatibiliteit. | +| `providerModels.ts` | Centraal modelregister: brengt provideraliassen in kaart → model-ID's. Functies zoals `getModels()`, `getProviderByAlias()`. | +| `codexInstructions.ts` | Systeeminstructies geïnjecteerd in Codex-verzoeken (bewerkingsbeperkingen, sandbox-regels, goedkeuringsbeleid). | +| `defaultThinkingSignature.ts` | Standaard "denkende" handtekeningen voor Claude- en Gemini-modellen. | +| `ollamaModels.ts` | Schemadefinitie voor lokale Ollama-modellen (naam, grootte, familie, kwantisering). | + +#### Laadstroom van inloggegevens + +```mermaid +flowchart TD + A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"] + B --> C{"data/provider-credentials.json\nexists?"} + C -->|Yes| D["credentialLoader reads JSON"] + C -->|No| E["Use hardcoded defaults"] + D --> F{"For each provider in JSON"} + F --> G{"Provider exists\nin PROVIDERS?"} + G -->|No| H["Log warning, skip"] + G -->|Yes| I{"Value is object?"} + I -->|No| J["Log warning, skip"] + I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"] + K --> F + H --> F + J --> F + F -->|Done| L["PROVIDERS ready with\nmerged credentials"] + E --> L +``` + +--- + +### 4.2 Executeurs (`open-sse/executors/`) + +Uitvoerders kapselen **providerspecifieke logica** in met behulp van het **Strategiepatroon**. Elke uitvoerder overschrijft indien nodig basismethoden. + +```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 DefaultExecutor { + +refreshCredentials() + } + + class AntigravityExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +shouldRetry() + +refreshCredentials() + } + + class CursorExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseResponse() + +generateChecksum() + } + + class KiroExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseEventStream() + +refreshCredentials() + } + + BaseExecutor <|-- DefaultExecutor + BaseExecutor <|-- AntigravityExecutor + BaseExecutor <|-- CursorExecutor + BaseExecutor <|-- KiroExecutor + BaseExecutor <|-- CodexExecutor + BaseExecutor <|-- GeminiCLIExecutor + BaseExecutor <|-- GithubExecutor +``` + +| executeur | Aanbieder | Belangrijkste specialisaties | +| ---------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | +| `base.ts` | — | Samenvatting van de basis: URL-opbouw, headers, logica voor opnieuw proberen, vernieuwen van inloggegevens | +| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generieke OAuth-tokenvernieuwing voor standaardproviders | +| `antigravity.ts` | Google Cloud-code | Generatie van project-/sessie-ID's, fallback met meerdere URL's, aangepaste parsering van foutmeldingen ("reset na 2u7m23s") | +| `cursor.ts` | Cursor-IDE | **Meest complex**: SHA-256 checksum-authenticatie, Protobuf-verzoekcodering, binaire EventStream → Parsing van SSE-antwoorden | +| `codex.ts` | OpenAI-codex | Injecteert systeeminstructies, beheert denkniveaus, verwijdert niet-ondersteunde parameters | +| `gemini-cli.ts` | Google Gemini-CLI | Aangepaste URL maken (`streamGenerateContent`), Google OAuth-token vernieuwen | +| `github.ts` | GitHub-copiloot | Dubbel tokensysteem (GitHub OAuth + Copilot-token), VSCode-header die | +| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binaire parsing, AMZN-gebeurtenisframes, tokenschatting | +| `index.ts` | — | Fabriek: kaartprovidernaam → uitvoerderklasse, met standaard fallback | + +--- + +### 4.3 Afhandelaars (`open-sse/handlers/`) + +De **orkestratielaag** — coördineert de vertaling, uitvoering, streaming en foutafhandeling. + +| Bestand | Doel | +| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `chatCore.ts` | **Centrale orkestrator** (~600 lijnen). Verwerkt de volledige levenscyclus van verzoeken: formaatdetectie → vertaling → verzending van de uitvoerder → streaming/niet-streaming antwoord → tokenvernieuwing → foutafhandeling → gebruiksregistratie. | +| `responsesHandler.ts` | Adapter voor OpenAI's Responses API: converteert het antwoordformaat → Chatvoltooiingen → verzendt naar `chatCore` → converteert SSE terug naar het antwoordformaat. | +| `embeddings.ts` | Handler voor het genereren van inbedding: lost het inbeddingsmodel → provider op, verzendt naar de API van de provider, retourneert OpenAI-compatibele inbeddingsreactie. Ondersteunt 6+ providers. | +| `imageGeneration.ts` | Handler voor het genereren van afbeeldingen: lost beeldmodel → provider op, ondersteunt OpenAI-compatibele, Gemini-image (Antigravity) en fallback (Nebius) modi. Retourneert base64- of URL-afbeeldingen. | + +#### Aanvraaglevenscyclus (chatCore.ts) + +```mermaid +sequenceDiagram + participant Client + participant chatCore + participant Translator + participant Executor + participant Provider + + Client->>chatCore: Request (any format) + chatCore->>chatCore: Detect source format + chatCore->>chatCore: Check bypass patterns + chatCore->>chatCore: Resolve model & provider + chatCore->>Translator: Translate request (source → OpenAI → target) + chatCore->>Executor: Get executor for provider + Executor->>Executor: Build URL, headers, transform request + Executor->>Executor: Refresh credentials if needed + Executor->>Provider: HTTP fetch (streaming or non-streaming) + + alt Streaming + Provider-->>chatCore: SSE stream + chatCore->>chatCore: Pipe through SSE transform stream + Note over chatCore: Transform stream translates
each chunk: target → OpenAI → source + chatCore-->>Client: Translated SSE stream + else Non-streaming + Provider-->>chatCore: JSON response + chatCore->>Translator: Translate response + chatCore-->>Client: Translated JSON + end + + alt Error (401, 429, 500...) + chatCore->>Executor: Retry with credential refresh + chatCore->>chatCore: Account fallback logic + end +``` + +--- + +### 4.4 Diensten (`open-sse/services/`) + +Bedrijfslogica die de behandelaars en uitvoerders ondersteunt. + +| Bestand | Doel | +| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `provider.ts` | **Formaatdetectie** (`detectFormat`): analyseert de lichaamsstructuur van het verzoek om de formaten Claude/OpenAI/Gemini/Antigravity/Responses te identificeren (inclusief `max_tokens` heuristiek voor Claude). Ook: URL-opbouw, header-opbouw, normalisatie van denkconfiguraties. Ondersteunt `openai-compatible-*` en `anthropic-compatible-*` dynamische providers. | +| `model.ts` | Parseren van modeltekenreeksen (`claude/model-name` → `{provider: "claude", model: "model-name"}`), aliasresolutie met botsingsdetectie, invoeropschoning (weigert paddoorloop/controletekens) en modelinformatieresolutie met ondersteuning voor asynchrone aliasgetter. | +| `accountFallback.ts` | Afhandeling van snelheidslimieten: exponentiële uitstel (1s → 2s → 4s → max. 2min), beheer van accountcooldown, foutclassificatie (welke fouten een terugval veroorzaken versus niet). | +| `tokenRefresh.ts` | OAuth-tokenvernieuwing voor **elke provider**: Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Inclusief in-flight belofte-deduplicatiecache en opnieuw proberen met exponentiële uitstel. | +| `combo.ts` | **Combomodellen**: ketens van fallback-modellen. Als model A faalt met een fout die in aanmerking komt voor terugval, probeer dan model B, vervolgens C, enz. Retourneert werkelijke stroomopwaartse statuscodes. | +| `usage.ts` | Haalt quota/gebruiksgegevens op van provider-API's (GitHub Copilot-quota, Antigravity-modelquota, Codex-snelheidslimieten, uitsplitsingen van Kiro-gebruik, Claude-instellingen). | +| `accountSelector.ts` | Slimme accountselectie met score-algoritme: houdt rekening met prioriteit, gezondheidsstatus, round-robin-positie en cooldown-status om voor elk verzoek het optimale account te kiezen. | +| `contextManager.ts` | Beheer van de contextlevenscyclus van aanvragen: creëert en volgt contextobjecten per aanvraag met metagegevens (aanvraag-ID, tijdstempels, providerinformatie) voor foutopsporing en logboekregistratie. | +| `ipFilter.ts` | IP-gebaseerd toegangscontrole: ondersteunt de toelatingslijst- en blokkeerlijstmodi. Valideert client-IP aan de hand van geconfigureerde regels voordat API-aanvragen worden verwerkt. | +| `sessionManager.ts` | Sessie volgen met client-fingerprinting: volgt actieve sessies met behulp van gehashte client-ID's, bewaakt het aantal verzoeken en biedt sessiestatistieken. | +| `signatureCache.ts` | Op handtekeningen gebaseerde deduplicatiecache aanvragen: voorkomt dubbele verzoeken door handtekeningen van recente verzoeken in de cache op te slaan en in de cache opgeslagen antwoorden voor identieke verzoeken binnen een tijdsvenster te retourneren. | +| `systemPrompt.ts` | Globale injectie van systeemprompts: voegt een configureerbare systeemprompt toe aan alle verzoeken, waarbij de compatibiliteit per provider wordt afgehandeld. | +| `thinkingBudget.ts` | Budgetbeheer voor redeneringstokens: ondersteunt passthrough-, automatische (strip-thinking-configuratie), aangepaste (vast budget) en adaptieve (op complexiteit geschaalde) modi voor het controleren van denk-/redeneringstokens. | +| `wildcardRouter.ts` | Patroonroutering met jokertekenmodel: zet jokertekenpatronen (bijvoorbeeld `*/claude-*`) om in concrete provider/modelparen op basis van beschikbaarheid en prioriteit. | + +#### Ontdubbeling van tokenvernieuwing + +```mermaid +sequenceDiagram + participant R1 as Request 1 + participant R2 as Request 2 + participant Cache as refreshPromiseCache + participant OAuth as OAuth Provider + + R1->>Cache: getAccessToken("gemini", token) + Cache->>Cache: No in-flight promise + Cache->>OAuth: Start refresh + R2->>Cache: getAccessToken("gemini", token) + Cache->>Cache: Found in-flight promise + Cache-->>R2: Return existing promise + OAuth-->>Cache: New access token + Cache-->>R1: New access token + Cache-->>R2: Same access token (shared) + Cache->>Cache: Delete cache entry +``` + +#### Account Fallback State Machine + +```mermaid +stateDiagram-v2 + [*] --> Active + Active --> Error: Request fails (401/429/500) + Error --> Cooldown: Apply backoff + Cooldown --> Active: Cooldown expires + Active --> Active: Request succeeds (reset backoff) + + state Error { + [*] --> ClassifyError + ClassifyError --> ShouldFallback: Rate limit / Auth / Transient + ClassifyError --> NoFallback: 400 Bad Request + } + + state Cooldown { + [*] --> ExponentialBackoff + ExponentialBackoff: Level 0 = 1s + ExponentialBackoff: Level 1 = 2s + ExponentialBackoff: Level 2 = 4s + ExponentialBackoff: Max = 2min + } +``` + +#### Combo-modelketen + +```mermaid +flowchart LR + A["Request with\ncombo model"] --> B["Model A"] + B -->|"2xx Success"| C["Return response"] + B -->|"429/401/500"| D{"Fallback\neligible?"} + D -->|Yes| E["Model B"] + D -->|No| F["Return error"] + E -->|"2xx Success"| C + E -->|"429/401/500"| G{"Fallback\neligible?"} + G -->|Yes| H["Model C"] + G -->|No| F + H -->|"2xx Success"| C + H -->|"Fail"| I["All failed →\nReturn last status"] +``` + +--- + +### 4.5 Vertaler (`open-sse/translator/`) + +De **formaatvertaalmachine** gebruikt een zelfregistrerend plug-insysteem. + +#### Architectuur + +```mermaid +graph TD + subgraph "Request Translation" + A["Claude → OpenAI"] + B["Gemini → OpenAI"] + C["Antigravity → OpenAI"] + D["OpenAI Responses → OpenAI"] + E["OpenAI → Claude"] + F["OpenAI → Gemini"] + G["OpenAI → Kiro"] + H["OpenAI → Cursor"] + end + + subgraph "Response Translation" + I["Claude → OpenAI"] + J["Gemini → OpenAI"] + K["Kiro → OpenAI"] + L["Cursor → OpenAI"] + M["OpenAI → Claude"] + N["OpenAI → Antigravity"] + O["OpenAI → Responses"] + end +``` + +| Telefoonboek | Bestanden | Beschrijving | +| ------------ | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `request/` | 8 vertalers | Converteer verzoekteksten tussen formaten. Elk bestand registreert zichzelf via `register(from, to, fn)` bij het importeren. | +| `response/` | 7 vertalers | Converteer streamingantwoordbrokken tussen formaten. Verwerkt SSE-gebeurtenistypen, denkblokken, tooloproepen. | +| `helpers/` | 6 helpers | Gedeelde hulpprogramma's: `claudeHelper` (extractie van systeemprompts, denkconfiguratie), `geminiHelper` (toewijzing van onderdelen/inhoud), `openaiHelper` (formaatfiltering), `toolCallHelper` (ID genereren, injectie van ontbrekende antwoorden), `maxTokensHelper`, `responsesApiHelper`. | +| `index.ts` | — | Vertaalmachine: `translateRequest()`, `translateResponse()`, staatsbeheer, register. | +| `formats.ts` | — | Formaatconstanten: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | + +#### Sleutelontwerp: zelfregistrerende plug-ins + +```javascript +// Each translator file calls register() on import: +import { register } from "../index.js"; +register("claude", "openai", translateClaudeToOpenAI); + +// The index.js imports all translator files, triggering registration: +import "./request/claude-to-openai.js"; // ← self-registers +``` + +--- + +### 4.6 Hulpprogramma's (`open-sse/utils/`) + +| Bestand | Doel | +| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `error.ts` | Opbouw van foutreacties (OpenAI-compatibel formaat), upstream-foutparsing, Antigravity-extractie van nieuwe pogingen uit foutmeldingen, SSE-foutstreaming. | +| `stream.ts` | **SSE Transform Stream** — de belangrijkste streamingpijplijn. Twee modi: `TRANSLATE` (vertaling in volledig formaat) en `PASSTHROUGH` (gebruik normaliseren + extraheren). Verwerkt chunkbuffering, gebruiksschatting en het bijhouden van de inhoudslengte. Encoder/decoder-instanties per stream vermijden een gedeelde status. | +| `streamHelpers.ts` | SSE-hulpprogramma's op laag niveau: `parseSSELine` (witruimtetolerant), `hasValuableContent` (filtert lege chunks voor OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (formaatbewuste SSE-serialisatie met opschoning `perf_metrics`). | +| `usageTracking.ts` | Extractie van tokengebruik uit elk formaat (Claude/OpenAI/Gemini/Responses), schatting met afzonderlijke tool/bericht-char-per-token-verhoudingen, buffertoevoeging (veiligheidsmarge van 2000 tokens), formaatspecifieke veldfiltering, consolelogboekregistratie met ANSI-kleuren. | +| `requestLogger.ts` | Op bestanden gebaseerde registratie van verzoeken (opt-in via `ENABLE_REQUEST_LOGS=true`). Creëert sessiemappen met genummerde bestanden: `1_req_client.json` → `7_res_client.txt`. Alle I/O is async (fire-and-forget). Maskert gevoelige headers. | +| `bypassHandler.ts` | Onderschept specifieke patronen van Claude CLI (titelextractie, opwarming, telling) en retourneert valse antwoorden zonder een provider te bellen. Ondersteunt zowel streaming als niet-streaming. Opzettelijk beperkt tot het Claude CLI-bereik. | +| `networkProxy.ts` | Bepaalt de uitgaande proxy-URL voor een bepaalde provider met voorrang: providerspecifieke configuratie → globale configuratie → omgevingsvariabelen (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Ondersteunt `NO_PROXY` uitsluitingen. Cachesconfiguratie voor 30s. | + +#### SSE-streamingpijplijn + +```mermaid +flowchart TD + A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"] + B --> C["Buffer lines\n(split on newline)"] + C --> D["parseSSELine()\n(trim whitespace, parse JSON)"] + D --> E{"Mode?"} + E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"] + E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"] + F --> H["hasValuableContent()\nfilter empty chunks"] + G --> H + H -->|"Has content"| I["extractUsage()\ntrack token counts"] + H -->|"Empty"| J["Skip chunk"] + I --> K["formatSSE()\nserialize + clean perf_metrics"] + K --> L["TextEncoder\n(per-stream instance)"] + L --> M["Enqueue to\nclient stream"] + + style A fill:#f9f,stroke:#333 + style M fill:#9f9,stroke:#333 +``` + +#### Verzoek Loggersessiestructuur + +``` +logs/ +└── claude_gemini_claude-sonnet_20260208_143045/ + ├── 1_req_client.json ← Raw client request + ├── 2_req_source.json ← After initial conversion + ├── 3_req_openai.json ← OpenAI intermediate format + ├── 4_req_target.json ← Final target format + ├── 5_res_provider.txt ← Provider SSE chunks (streaming) + ├── 5_res_provider.json ← Provider response (non-streaming) + ├── 6_res_openai.txt ← OpenAI intermediate chunks + ├── 7_res_client.txt ← Client-facing SSE chunks + └── 6_error.json ← Error details (if any) +``` + +--- + +### 4.7 Applicatielaag (`src/`) + +| Telefoonboek | Doel | +| ------------- | --------------------------------------------------------------------------------- | +| `src/app/` | Web-UI, API-routes, Express-middleware, OAuth-callback-handlers | +| `src/lib/` | Databasetoegang (`localDb.ts`, `usageDb.ts`), authenticatie, gedeeld | +| `src/mitm/` | Man-in-the-middle-proxyhulpprogramma's voor het onderscheppen van providerverkeer | +| `src/models/` | Definities van databasemodellen | +| `src/shared/` | Wrappers rond open-sse-functies (provider, stream, fout, etc.) | +| `src/sse/` | SSE-eindpunthandlers die de open-sse-bibliotheek verbinden met Express-routes | +| `src/store/` | Beheer van applicatiestatus | + +#### Opmerkelijke API-routes + +| Route | Methoden | Doel | +| --------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------- | +| `/api/provider-models` | KRIJGEN/POST/VERWIJDEREN | CRUD voor maatwerkmodellen per aanbieder | +| `/api/models/catalog` | KRIJG | Geaggregeerde catalogus van alle modellen (chat, insluiten, afbeelding, aangepast) gegroepeerd op provider | +| `/api/settings/proxy` | KRIJGEN/ZET/VERWIJDEREN | Hiërarchische uitgaande proxyconfiguratie (`global/providers/combos/keys`) | +| `/api/settings/proxy/test` | POST | Valideert proxy-connectiviteit en retourneert openbare IP/latentie | +| `/v1/providers/[provider]/chat/completions` | POST | Specifieke chatafrondingen per provider met modelvalidatie | +| `/v1/providers/[provider]/embeddings` | POST | Toegewijde inbedding per provider met modelvalidatie | +| `/v1/providers/[provider]/images/generations` | POST | Specifieke generatie van afbeeldingen per provider met modelvalidatie | +| `/api/settings/ip-filter` | KRIJG/ZET | Beheer van IP-toelatingslijsten/blokkeerlijsten | +| `/api/settings/thinking-budget` | KRIJG/ZET | Redeneren token budgetconfiguratie (passthrough/auto/aangepast/adaptief) | +| `/api/settings/system-prompt` | KRIJG/ZET | Wereldwijde systeempromptinjectie voor alle verzoeken | +| `/api/sessions` | KRIJG | Actieve sessietracking en statistieken | +| `/api/rate-limits` | KRIJG | Status van tarieflimiet per account | + +--- + +## 5. Belangrijke ontwerppatronen + +### 5.1 Hub-and-spoke-vertaling + +Alle formaten worden vertaald via het **OpenAI-formaat als hub**. Voor het toevoegen van een nieuwe provider is slechts **één paar** vertalers nodig (van/naar OpenAI), niet N-paren. + +### 5.2 Strategiepatroon voor de uitvoerder + +Elke provider heeft een speciale uitvoerderklasse die overerft van `BaseExecutor`. De fabriek in `executors/index.ts` selecteert tijdens runtime de juiste. + +### 5.3 Zelfregistrerend plug-insysteem + +Vertalermodules registreren zichzelf bij het importeren via `register()`. Als u een nieuwe vertaler toevoegt, maakt u eenvoudigweg een bestand aan en importeert u dit. + +### 5.4 Accountterugval met exponentiële uitstel + +Wanneer een provider 429/401/500 retourneert, kan het systeem overschakelen naar het volgende account, waarbij exponentiële cooldowns worden toegepast (1s → 2s → 4s → max. 2min). + +### 5.5 combo-modelketens + +Een "combo" groepeert meerdere `provider/model` strings. Als de eerste mislukt, wordt automatisch teruggevallen op de volgende. + +### 5.6 Stateful streaming-vertaling + +Reactievertaling handhaaft de status van SSE-brokken (tracking van denkblokken, accumulatie van tooloproepen, indexering van inhoudsblokken) via het `initState()`-mechanisme. + +### 5.7 Gebruiksveiligheidsbuffer + +Er wordt een buffer van 2000 token toegevoegd aan het gerapporteerde gebruik om te voorkomen dat clients de limieten van het contextvenster bereiken als gevolg van overhead van systeemprompts en formaatvertaling. + +--- + +## 6. Ondersteunde formaten + +| Formaat | Richting | Identificatie | +| ------------------------ | ----------- | ------------------ | +| OpenAI Chat-voltooiingen | bron + doel | `openai` | +| OpenAI-reacties-API | bron + doel | `openai-responses` | +| Antropische Claude | bron + doel | `claude` | +| Google Tweeling | bron + doel | `gemini` | +| Google Gemini-CLI | alleen doel | `gemini-cli` | +| Antizwaartekracht | bron + doel | `antigravity` | +| AWS Kiro | alleen doel | `kiro` | +| Cursor | alleen doel | `cursor` | + +--- + +## 7. Ondersteunde providers + +| Aanbieder | Verificatiemethode | executeur | Belangrijkste opmerkingen | +| ------------------------ | ----------------------- | ----------------- | -------------------------------------------------------------------- | +| Antropische Claude | API-sleutel of OAuth | Standaard | Gebruikt `x-api-key` koptekst | +| Google Tweeling | API-sleutel of OAuth | Standaard | Gebruikt `x-goog-api-key` koptekst | +| Google Gemini-CLI | OAuth | GeminiCLI | Gebruikt `streamGenerateContent` eindpunt | +| Antizwaartekracht | OAuth | Antizwaartekracht | Terugval op meerdere URL's, aangepaste parsering van nieuwe pogingen | +| Open AI | API-sleutel | Standaard | Standaard Bearer-authenticatie | +| Codex | OAuth | Codex | Injecteert systeeminstructies, beheert het denken | +| GitHub-copiloot | OAuth + Copilot-token | Github | Dubbel token, VSCode-header die | +| Kiro (AWS) | AWS SSO OIDC of sociaal | Kiro | Binaire EventStream-parsering | +| Cursor-IDE | Controlesomverificatie | Cursor | Protobuf-codering, SHA-256-controlesommen | +| Qwen | OAuth | Standaard | Standaardauthenticatie | +| iFlow | OAuth (basis + drager) | Standaard | Dubbele auth-header | +| OpenRouter | API-sleutel | Standaard | Standaard Bearer-authenticatie | +| GLM, Kimi, MiniMax | API-sleutel | Standaard | Claude-compatibel, gebruik `x-api-key` | +| `openai-compatible-*` | API-sleutel | Standaard | Dynamisch: elk OpenAI-compatibel eindpunt | +| `anthropic-compatible-*` | API-sleutel | Standaard | Dynamisch: elk Claude-compatibel eindpunt | + +--- + +## 8. Samenvatting van de gegevensstroom + +### Streamingverzoek + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor\nbuildUrl + buildHeaders"] + D --> E["fetch(providerURL)"] + E --> F["createSSEStream()\nTRANSLATE mode"] + F --> G["parseSSELine()"] + G --> H["translateResponse()\ntarget → OpenAI → source"] + H --> I["extractUsage()\n+ addBuffer"] + I --> J["formatSSE()"] + J --> K["Client receives\ntranslated SSE"] + K --> L["logUsage()\nsaveRequestUsage()"] +``` + +### Niet-streamingverzoek + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor.execute()"] + D --> E["translateResponse()\ntarget → OpenAI → source"] + E --> F["Return JSON\nresponse"] +``` + +### Bypassstroom (Claude CLI) + +```mermaid +flowchart LR + A["Claude CLI request"] --> B{"Match bypass\npattern?"} + B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"] + B -->|"No match"| D["Normal flow"] + C --> E["Translate to\nsource format"] + E --> F["Return without\ncalling provider"] +``` diff --git a/docs/i18n/nl/FEATURES.md b/docs/i18n/nl/FEATURES.md new file mode 100644 index 0000000000..2f5b01c5b3 --- /dev/null +++ b/docs/i18n/nl/FEATURES.md @@ -0,0 +1,77 @@ +# OmniRoute — Galerij met dashboardfuncties + +🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md) + +Visuele gids voor elke sectie van het OmniRoute-dashboard. + +--- + +## 🔌 Aanbieders + +Beheer AI-providerverbindingen: OAuth-providers (Claude Code, Codex, Gemini CLI), API-sleutelproviders (Groq, DeepSeek, OpenRouter) en gratis providers (iFlow, Qwen, Kiro). + +![Providers Dashboard](screenshots/01-providers.png) + +--- + +## 🎨Combo's + +Creëer modelrouteringscombinaties met 6 strategieën: eerst vullen, round-robin, macht van twee keuzes, willekeurig, minst gebruikt en kostengeoptimaliseerd. Elke combo koppelt meerdere modellen met automatische terugval. + +![Combos Dashboard](screenshots/02-combos.png) + +--- + +## 📊 Analyse + +Uitgebreide gebruiksanalyses met tokenverbruik, kostenramingen, activiteiten-heatmaps, wekelijkse distributiegrafieken en uitsplitsingen per provider. + +![Analytics Dashboard](screenshots/03-analytics.png) + +--- + +## 🏥Systeemgezondheid + +Realtime monitoring: uptime, geheugen, versie, latentiepercentielen (p50/p95/p99), cachestatistieken en status van stroomonderbrekers van de provider. + +![Health Dashboard](screenshots/04-health.png) + +--- + +## 🔧 Vertalerspeeltuin + +Vier modi voor het debuggen van API-vertalingen: **Playground** (formaatconverter), **Chat Tester** (live verzoeken), **Test Bench** (batchtests) en **Live Monitor** (realtime stream). + +![Translator Playground](screenshots/05-translator.png) + +--- + +## ⚙️ Instellingen + +Algemene instellingen, systeemopslag, back-upbeheer (database exporteren/importeren), uiterlijk (donker/licht-modus), beveiliging (inclusief API-eindpuntbescherming en aangepaste providerblokkering), routing, veerkracht en geavanceerde configuratie. + +![Settings Dashboard](screenshots/06-settings.png) + +--- + +## 🔧 CLI-hulpmiddelen + +Configuratie met één klik voor AI-coderingstools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code en Antigravity. + +![CLI Tools Dashboard](screenshots/07-cli-tools.png) + +--- + +## 📝 Logboeken aanvragen + +Realtime logboekregistratie van verzoeken met filtering op provider, model, account en API-sleutel. Toont statuscodes, tokengebruik, latentie en responsdetails. + +![Usage Logs](screenshots/08-usage.png) + +--- + +## 🌐 API-eindpunt + +Uw uniforme API-eindpunt met uitsplitsing van de mogelijkheden: chatvoltooiingen, insluitingen, het genereren van afbeeldingen, herrangschikking, audiotranscriptie en geregistreerde API-sleutels. + +![Endpoint Dashboard](screenshots/09-endpoint.png) diff --git a/docs/i18n/nl/TROUBLESHOOTING.md b/docs/i18n/nl/TROUBLESHOOTING.md new file mode 100644 index 0000000000..6f87db9d7b --- /dev/null +++ b/docs/i18n/nl/TROUBLESHOOTING.md @@ -0,0 +1,219 @@ +# Problemen oplossen + +🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md) + +Veelvoorkomende problemen en oplossingen voor OmniRoute. + +--- + +## Snelle oplossingen + +| Probleem | Oplossing | +| ----------------------------------- | ----------------------------------------------------------------------- | ---------------- | +| Eerste login werkt niet | Controleer `INITIAL_PASSWORD` in `.env` (standaard: `123456`) | +| Dashboard opent op verkeerde poort | Stel `PORT=20128` en `NEXT_PUBLIC_BASE_URL=http://localhost:20128` | in | +| Geen verzoeklogboeken onder `logs/` | Stel `ENABLE_REQUEST_LOGS=true` | in | +| EACCES: toestemming geweigerd | Stel `DATA_DIR=/path/to/writable/dir` in om `~/.omniroute` | te overschrijven | +| Routeringsstrategie bespaart niet | Update naar v1.4.11+ (Zod-schemafix voor persistentie van instellingen) | + +--- + +## Problemen met providers + +### "Taalmodel heeft geen berichten geleverd" + +**Oorzaak:** Providerquotum is opgebruikt. + +**Opgelost:** + +1. Controleer de dashboardquotatracker +2. Gebruik een combo met fallback-lagen +3. Schakel over naar het goedkopere/gratis niveau + +### Snelheidslimiet + +**Oorzaak:** Abonnementsquota zijn opgebruikt. + +**Opgelost:** + +- Terugval toevoegen: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` +- Gebruik GLM/MiniMax als goedkope back-up + +### OAuth-token verlopen + +OmniRoute vernieuwt tokens automatisch. Als de problemen aanhouden: + +1. Dashboard → Provider → Opnieuw verbinden +2. Verwijder de providerverbinding en voeg deze opnieuw toe + +--- + +## Cloudproblemen + +### Cloudsynchronisatiefouten + +1. Controleer of `BASE_URL` verwijst naar uw actieve exemplaar (bijvoorbeeld `http://localhost:20128`) +2. Controleer of `CLOUD_URL` verwijst naar uw cloudeindpunt (bijvoorbeeld `https://omniroute.dev`) +3. Zorg ervoor dat de `NEXT_PUBLIC_*`-waarden overeenkomen met de waarden op de server + +### Wolk `stream=false` Retourneert 500 + +**Symptoom:** `Unexpected token 'd'...` op cloudeindpunt voor niet-streaming oproepen. + +**Oorzaak:** Upstream retourneert SSE-payload terwijl de client JSON verwacht. + +**Oplossing:** Gebruik `stream=true` voor directe cloudoproepen. Lokale runtime omvat SSE → JSON-fallback. + +### Cloud zegt verbonden maar "Ongeldige API-sleutel" + +1. Maak een nieuwe sleutel vanaf het lokale dashboard (`/api/keys`) +2. Voer cloudsynchronisatie uit: Schakel Cloud in → Nu synchroniseren +3. Oude/niet-gesynchroniseerde sleutels kunnen nog steeds `401` retourneren in de cloud + +--- + +## Docker-problemen + +### CLI-tool geeft aan dat deze niet is geïnstalleerd + +1. Controleer runtimevelden: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq` +2. Voor draagbare modus: gebruik afbeeldingsdoel `runner-cli` (gebundelde CLI's) +3. Voor de host-aankoppelmodus: stel `CLI_EXTRA_PATHS` in en koppel de hostbin-map aan als alleen-lezen +4. Als `installed=true` en `runnable=false`: binair bestand is gevonden maar de statuscheck is mislukt + +### Snelle runtime-validatie + +```bash +curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +``` + +--- + +## Kostenproblemen + +### Hoge kosten + +1. Controleer gebruiksstatistieken in Dashboard → Gebruik +2. Schakel het primaire model over naar GLM/MiniMax +3. Gebruik de gratis laag (Gemini CLI, iFlow) voor niet-kritieke taken +4. Stel kostenbudgetten per API-sleutel in: Dashboard → API-sleutels → Budget + +--- + +## Foutopsporing + +### Verzoeklogboeken inschakelen + +Stel `ENABLE_REQUEST_LOGS=true` in uw `.env` bestand in. Logboeken verschijnen onder de map `logs/`. + +### Controleer de gezondheid van de provider + +```bash +# Health dashboard +http://localhost:20128/dashboard/health + +# API health check +curl http://localhost:20128/api/monitoring/health +``` + +### Runtime-opslag + +- Hoofdstatus: `${DATA_DIR}/db.json` (providers, combo's, aliassen, sleutels, instellingen) +- Gebruik: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- Logboeken aanvragen: `/logs/...` (wanneer `ENABLE_REQUEST_LOGS=true`) + +--- + +## Problemen met stroomonderbrekers + +### Provider zit vast in OPEN-status + +Wanneer de stroomonderbreker van een provider OPEN is, worden verzoeken geblokkeerd totdat de cooldown is verstreken. + +**Opgelost:** + +1. Ga naar **Dashboard → Instellingen → Veerkracht** +2. Controleer de stroomonderbrekerkaart van de betreffende provider +3. Klik op **Alles resetten** om alle onderbrekers te wissen, of wacht tot de cooldown is verstreken +4. Controleer of de provider daadwerkelijk beschikbaar is voordat u reset + +### De provider schakelt de stroomonderbreker steeds uit + +Als een aanbieder herhaaldelijk in de OPEN-status komt: + +1. Controleer **Dashboard → Gezondheid → Providergezondheid** voor het foutpatroon +2. Ga naar **Instellingen → Veerkracht → Providerprofielen** en verhoog de foutdrempel +3. Controleer of de provider de API-limieten heeft gewijzigd of herauthenticatie vereist +4. Controleer latentie-telemetrie: hoge latentie kan op time-outs gebaseerde fouten veroorzaken + +--- + +## Problemen met audiotranscriptie + +### Fout 'Niet-ondersteund model' + +- Zorg ervoor dat u het juiste voorvoegsel gebruikt: `deepgram/nova-3` of `assemblyai/best` +- Controleer of de provider is verbonden in **Dashboard → Providers** + +### Transcriptie is leeg of mislukt + +- Controleer ondersteunde audioformaten: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm` +- Controleer of de bestandsgrootte binnen de limieten van de provider ligt (doorgaans < 25 MB) +- Controleer de geldigheid van de API-sleutel van de provider op de providerkaart + +--- + +## Foutopsporing bij vertalers + +Gebruik **Dashboard → Vertaler** om problemen met de vertaling van formaten op te lossen: + +| Modus | Wanneer gebruiken | +| --------------- | ---------------------------------------------------------------------------------------------------------- | +| **Speeltuin** | Vergelijk invoer-/uitvoerformaten naast elkaar - plak een mislukt verzoek om te zien hoe het zich vertaalt | +| **Chattester** | Verzend live berichten en inspecteer de volledige payload van verzoeken/antwoorden, inclusief headers | +| **Proefbank** | Voer batchtests uit voor indelingscombinaties om te ontdekken welke vertalingen niet werken | +| **Livemonitor** | Bekijk de realtime aanvraagstroom om intermitterende vertaalproblemen op te sporen | + +### Veelvoorkomende formaatproblemen + +- **Thinking-tags verschijnen niet** — Controleer of de doelaanbieder het denken en de instelling van het denkbudget ondersteunt +- **Tooloproepen vervallen** — Bij sommige formaatvertalingen kunnen niet-ondersteunde velden worden verwijderd; verifiëren in Speeltuinmodus +- **Systeemprompt ontbreekt** — Claude en Gemini behandelen de systeemprompts anders; controleer de vertalingsuitvoer +- **SDK retourneert onbewerkte tekenreeks in plaats van object** — Opgelost in v1.1.0: respons sanitizer verwijdert nu niet-standaard velden (`x_groq`, `usage_breakdown`, etc.) die OpenAI SDK Pydantic-validatiefouten veroorzaken +- **GLM/ERNIE weigert de rol `system`** — Opgelost in v1.1.0: de rolnormalizer voegt systeemberichten automatisch samen met gebruikersberichten voor incompatibele modellen +- **`developer` rol niet herkend** — Opgelost in v1.1.0: automatisch geconverteerd naar `system` voor niet-OpenAI-providers +- **`json_schema` werkt niet met Gemini** — Opgelost in v1.1.0: `response_format` is nu geconverteerd naar Gemini's `responseMimeType` + `responseSchema` + +--- + +## Veerkrachtinstellingen + +### Automatische snelheidslimiet wordt niet geactiveerd + +- Automatische tarieflimiet is alleen van toepassing op API-sleutelproviders (niet op OAuth/abonnement) +- Controleer of bij Instellingen → Veerkracht → Providerprofielen\*\* automatische tarieflimiet is ingeschakeld +- Controleer of de provider `429` statuscodes of `Retry-After` headers retourneert + +### Exponentiële uitstel afstemmen + +Providerprofielen ondersteunen deze instellingen: + +- **Basisvertraging** — Initiële wachttijd na eerste storing (standaard: 1s) +- **Max. vertraging** — Maximale wachttijdlimiet (standaard: 30s) +- **Vermenigvuldiger** — Hoeveel vertraging per opeenvolgende fout moet worden vergroot (standaard: 2x) + +### Anti-donderende kudde + +Wanneer veel gelijktijdige verzoeken een provider met een beperkte snelheid bereiken, gebruikt OmniRoute mutex + automatische snelheidsbeperking om verzoeken te serialiseren en trapsgewijze fouten te voorkomen. Dit gebeurt automatisch voor API-sleutelproviders. + +--- + +## Zit je nog steeds vast? + +- **GitHub-problemen**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) +- **Architectuur**: zie [**OMNI_TOKEN_55**](ARCHITECTURE.md) voor interne details +- **API-referentie**: zie [**OMNI_TOKEN_56**](API_REFERENCE.md) voor alle eindpunten +- **Gezondheidsdashboard**: controleer **Dashboard → Gezondheid** voor de realtime systeemstatus +- **Vertaler**: gebruik **Dashboard → Vertaler** om formaatproblemen op te lossen diff --git a/docs/i18n/nl/USER_GUIDE.md b/docs/i18n/nl/USER_GUIDE.md new file mode 100644 index 0000000000..c7e8c33c0c --- /dev/null +++ b/docs/i18n/nl/USER_GUIDE.md @@ -0,0 +1,698 @@ +# Gebruikershandleiding + +🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md) + +Volledige gids voor het configureren van providers, het maken van combo's, het integreren van CLI-tools en het implementeren van OmniRoute. + +--- + +## Inhoudsopgave + +- [Pricing at a Glance](#-pricing-at-a-glance) +- [Use Cases](#-use-cases) +- [Provider Setup](#-provider-setup) +- [CLI Integration](#-cli-integration) +- [Deployment](#-deployment) +- [Available Models](#-available-models) +- [Advanced Features](#-advanced-features) + +--- + +## 💰 Prijzen in één oogopslag + +| Niveau | Aanbieder | Kosten | Quotum opnieuw instellen | Beste voor | +| ------------------ | ----------------- | ------------------- | ------------------------ | --------------------------- | +| **💳 ABONNEMENT** | Claude Code (Pro) | $ 20/maand | 5u + wekelijks | Al geabonneerd | +| | Codex (Plus/Pro) | $ 20-200/maand | 5u + wekelijks | OpenAI-gebruikers | +| | Tweeling CLI | **GRATIS** | 180K/maand + 1K/dag | Iedereen! | +| | GitHub-copiloot | $ 10-19/maand | Maandelijks | GitHub-gebruikers | +| **🔑 API-SLEUTEL** | DeepSeek | Betalen per gebruik | Geen | Goedkoop redeneren | +| | Groq | Betalen per gebruik | Geen | Ultrasnelle gevolgtrekking | +| | xAI (Grok) | Betalen per gebruik | Geen | Grok 4 redenering | +| | Mistral | Betalen per gebruik | Geen | Door de EU gehoste modellen | +| | Verbijstering | Betalen per gebruik | Geen | Zoek-uitgebreid | +| | Samen AI | Betalen per gebruik | Geen | Open source-modellen | +| | Vuurwerk AI | Betalen per gebruik | Geen | Snelle FLUX-afbeeldingen | +| | Hersenen | Betalen per gebruik | Geen | Snelheid op wafelschaal | +| | Cohier | Betalen per gebruik | Geen | Commando R+ RAG | +| | NVIDIA NIM | Betalen per gebruik | Geen | Enterprise-modellen | +| **💰GOEDKOOP** | GLM-4.7 | $ 0,6/1 miljoen | Dagelijks 10.00 uur | Budgetback-up | +| | MiniMax M2.1 | $ 0,2/1 miljoen | 5-uurs rollen | Goedkoopste optie | +| | Kimi K2 | $ 9/maand plat | 10 miljoen tokens/maand | Voorspelbare kosten | +| **🆓 GRATIS** | iFlow | $0 | Onbeperkt | 8 modellen gratis | +| | Qwen | $0 | Onbeperkt | 3 modellen gratis | +| | Kiro | $0 | Onbeperkt | Claude vrij | + +**💡 Pro-tip:** Begin met Gemini CLI (180K gratis/maand) + iFlow (onbeperkt gratis) combo = $ 0 kosten! + +--- + +## 🎯 Gebruiksscenario's + +### Geval 1: "Ik heb een Claude Pro-abonnement" + +**Probleem:** Quotum verloopt ongebruikt, snelheidslimieten tijdens intensief coderen + +``` +Combo: "maximize-claude" + 1. cc/claude-opus-4-6 (use subscription fully) + 2. glm/glm-4.7 (cheap backup when quota out) + 3. if/kimi-k2-thinking (free emergency fallback) + +Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total +vs. $20 + hitting limits = frustration +``` + +### Geval 2: "Ik wil geen kosten" + +**Probleem:** Ik kan geen abonnementen betalen, heb betrouwbare AI-codering nodig + +``` +Combo: "free-forever" + 1. gc/gemini-3-flash (180K free/month) + 2. if/kimi-k2-thinking (unlimited free) + 3. qw/qwen3-coder-plus (unlimited free) + +Monthly cost: $0 +Quality: Production-ready models +``` + +### Geval 3: "Ik heb 24/7 codering nodig, geen onderbrekingen" + +**Probleem:** Deadlines, downtime is niet mogelijk + +``` +Combo: "always-on" + 1. cc/claude-opus-4-6 (best quality) + 2. cx/gpt-5.2-codex (second subscription) + 3. glm/glm-4.7 (cheap, resets daily) + 4. minimax/MiniMax-M2.1 (cheapest, 5h reset) + 5. if/kimi-k2-thinking (free unlimited) + +Result: 5 layers of fallback = zero downtime +Monthly cost: $20-200 (subscriptions) + $10-20 (backup) +``` + +### Case 4: "Ik wil GRATIS AI in OpenClaw" + +**Probleem:** AI-assistent nodig in berichtenapps, geheel gratis + +``` +Combo: "openclaw-free" + 1. if/glm-4.7 (unlimited free) + 2. if/minimax-m2.1 (unlimited free) + 3. if/kimi-k2-thinking (unlimited free) + +Monthly cost: $0 +Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal... +``` + +--- + +## 📖 Providerconfiguratie + +### 🔐 Abonnementsaanbieders + +#### Claude-code (Pro/Max) + +```bash +Dashboard → Providers → Connect Claude Code +→ OAuth login → Auto token refresh +→ 5-hour + weekly quota tracking + +Models: + cc/claude-opus-4-6 + cc/claude-sonnet-4-5-20250929 + cc/claude-haiku-4-5-20251001 +``` + +**Pro-tip:** Gebruik Opus voor complexe taken, Sonnet voor snelheid. OmniRoute houdt quota bij per model! + +#### OpenAI Codex (Plus/Pro) + +```bash +Dashboard → Providers → Connect Codex +→ OAuth login (port 1455) +→ 5-hour + weekly reset + +Models: + cx/gpt-5.2-codex + cx/gpt-5.1-codex-max +``` + +#### Gemini CLI (GRATIS 180K/maand!) + +```bash +Dashboard → Providers → Connect Gemini CLI +→ Google OAuth +→ 180K completions/month + 1K/day + +Models: + gc/gemini-3-flash-preview + gc/gemini-2.5-pro +``` + +**Beste waarde:** Enorm gratis niveau! Gebruik dit vóór betaalde niveaus. + +#### GitHub-copiloot + +```bash +Dashboard → Providers → Connect GitHub +→ OAuth via GitHub +→ Monthly reset (1st of month) + +Models: + gh/gpt-5 + gh/claude-4.5-sonnet + gh/gemini-3-pro +``` + +### 💰 Goedkope aanbieders + +#### GLM-4.7 (dagelijkse reset, $0,6/1 miljoen) + +1. Aanmelden: [Zhipu AI](https://open.bigmodel.cn/) +2. Haal de API-sleutel op uit het Coderingsplan +3. Dashboard → API-sleutel toevoegen: Provider: `glm`, API-sleutel: `your-key` + +**Gebruik:** `glm/glm-4.7` — **Pro-tip:** Codeerplan biedt 3× quota tegen 1/7 kosten! Dagelijks resetten om 10:00 uur. + +#### MiniMax M2.1 (5 uur resetten, $0,20/1M) + +1. Aanmelden: [MiniMax](https://www.minimax.io/) +2. API-sleutel ophalen → Dashboard → API-sleutel toevoegen + +**Gebruik:** `minimax/MiniMax-M2.1` — **Pro-tip:** Goedkoopste optie voor lange context (1 miljoen tokens)! + +#### Kimi K2 ($9/maand vast) + +1. Abonneer je: [Moonshot AI](https://platform.moonshot.ai/) +2. API-sleutel ophalen → Dashboard → API-sleutel toevoegen + +**Gebruik:** `kimi/kimi-latest` — **Pro-tip:** Vaste $ 9/maand voor 10 miljoen tokens = $ 0,90/1 miljoen effectieve kosten! + +### 🆓 GRATIS Aanbieders + +#### iFlow (8 GRATIS modellen) + +```bash +Dashboard → Connect iFlow → OAuth login → Unlimited usage + +Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1 +``` + +#### Qwen (3 GRATIS modellen) + +```bash +Dashboard → Connect Qwen → Device code auth → Unlimited usage + +Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash +``` + +#### Kiro (Claude GRATIS) + +```bash +Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited + +Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5 +``` + +--- + +## 🎨Combo's + +### Voorbeeld 1: Maximaliseer abonnement → Goedkope back-up + +``` +Dashboard → Combos → Create New + +Name: premium-coding +Models: + 1. cc/claude-opus-4-6 (Subscription primary) + 2. glm/glm-4.7 (Cheap backup, $0.6/1M) + 3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M) + +Use in CLI: premium-coding +``` + +### Voorbeeld 2: Alleen gratis (geen kosten) + +``` +Name: free-combo +Models: + 1. gc/gemini-3-flash-preview (180K free/month) + 2. if/kimi-k2-thinking (unlimited) + 3. qw/qwen3-coder-plus (unlimited) + +Cost: $0 forever! +``` + +--- + +## 🔧 CLI-integratie + +### Cursor-IDE + +``` +Settings → Models → Advanced: + OpenAI API Base URL: http://localhost:20128/v1 + OpenAI API Key: [from omniroute dashboard] + Model: cc/claude-opus-4-6 +``` + +### Claude-code + +Bewerk `~/.claude/config.json`: + +```json +{ + "anthropic_api_base": "http://localhost:20128/v1", + "anthropic_api_key": "your-omniroute-api-key" +} +``` + +### Codex-CLI + +```bash +export OPENAI_BASE_URL="http://localhost:20128" +export OPENAI_API_KEY="your-omniroute-api-key" +codex "your prompt" +``` + +### Open Klauw + +Bewerk `~/.openclaw/openclaw.json`: + +```json +{ + "agents": { + "defaults": { + "model": { "primary": "omniroute/if/glm-4.7" } + } + }, + "models": { + "providers": { + "omniroute": { + "baseUrl": "http://localhost:20128/v1", + "apiKey": "your-omniroute-api-key", + "api": "openai-completions", + "models": [{ "id": "if/glm-4.7", "name": "glm-4.7" }] + } + } + } +} +``` + +**Of gebruik Dashboard:** CLI Tools → OpenClaw → Auto-config + +### Cline / Doorgaan / RooCode + +``` +Provider: OpenAI Compatible +Base URL: http://localhost:20128/v1 +API Key: [from dashboard] +Model: cc/claude-opus-4-6 +``` + +--- + +## 🚀 Implementatie + +### VPS-implementatie + +```bash +git clone https://github.com/diegosouzapw/OmniRoute.git +cd OmniRoute && npm install && npm run build + +export JWT_SECRET="your-secure-secret-change-this" +export INITIAL_PASSWORD="your-password" +export DATA_DIR="/var/lib/omniroute" +export PORT="20128" +export HOSTNAME="0.0.0.0" +export NODE_ENV="production" +export NEXT_PUBLIC_BASE_URL="http://localhost:20128" +export API_KEY_SECRET="endpoint-proxy-api-key-secret" + +npm run start +# Or: pm2 start npm --name omniroute -- start +``` + +### Docker + +```bash +# Build image (default = runner-cli with codex/claude/droid preinstalled) +docker build -t omniroute:cli . + +# Portable mode (recommended) +docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli +``` + +Voor de host-geïntegreerde modus met CLI-binaire bestanden raadpleegt u de Docker-sectie in de hoofddocumentatie. + +### Omgevingsvariabelen + +| Variabel | Standaard | Beschrijving | +| --------------------- | ------------------------------------ | --------------------------------------------------------- | +| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT-ondertekeningsgeheim (**productiewijziging**) | +| `INITIAL_PASSWORD` | `123456` | Wachtwoord voor eerste aanmelding | +| `DATA_DIR` | `~/.omniroute` | Gegevensmap (db, gebruik, logs) | +| `PORT` | standaard raamwerk | Servicepoort (`20128` in voorbeelden) | +| `HOSTNAME` | standaard raamwerk | Bind host (Docker is standaard ingesteld op `0.0.0.0`) | +| `NODE_ENV` | runtime-standaard | Stel `production` in voor implementatie | +| `BASE_URL` | `http://localhost:20128` | Interne basis-URL aan serverzijde | +| `CLOUD_URL` | `https://omniroute.dev` | Basis-URL van cloudsynchronisatie-eindpunt | +| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC-geheim voor gegenereerde API-sleutels | +| `REQUIRE_API_KEY` | `false` | Bearer API-sleutel afdwingen op `/v1/*` | +| `ENABLE_REQUEST_LOGS` | `false` | Schakelt verzoek-/antwoordlogboeken in | +| `AUTH_COOKIE_SECURE` | `false` | Forceer `Secure` auth-cookie (achter HTTPS reverse proxy) | + +Zie [README](../README.md) voor de volledige referentie van de omgevingsvariabelen. + +--- + +## 📊 Beschikbare modellen + +
+Bekijk alle beschikbare modellen + +**Claude-code (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001` + +**Codex (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max` + +**Gemini CLI (`gc/`)** — GRATIS: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro` + +**GitHub-copiloot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet` + +**GLM (`glm/`)** — $ 0,6/1 miljoen: `glm/glm-4.7` + +**MiniMax (`minimax/`)** — $ 0,2/1 miljoen: `minimax/MiniMax-M2.1` + +**iFlow (`if/`)** — GRATIS: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1` + +**Qwen (`qw/`)** — GRATIS: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash` + +**Kiro (`kr/`)** — GRATIS: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5` + +**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner` + +**Groq (`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct` + +**xAI (`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini` + +**Mistral (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501` + +**Verbijstering (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar` + +**Samen AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo` + +**Vuurwerk AI (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1` + +**Cerebra's (`cerebras/`)**: `cerebras/llama-3.3-70b` + +**Samenhang (`cohere/`)**: `cohere/command-r-plus-08-2024` + +**NVIDIA NIM (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct` + +
+ +--- + +## 🧩 Geavanceerde functies + +### Aangepaste modellen + +Voeg elke model-ID toe aan elke provider zonder te wachten op een app-update: + +```bash +# Via API +curl -X POST http://localhost:20128/api/provider-models \ + -H "Content-Type: application/json" \ + -d '{"provider": "openai", "modelId": "gpt-4.5-preview", "modelName": "GPT-4.5 Preview"}' + +# List: curl http://localhost:20128/api/provider-models?provider=openai +# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview" +``` + +Of gebruik Dashboard: **Aanbieders → [Aanbieder] → Aangepaste modellen**. + +### Speciale providerroutes + +Routeer verzoeken rechtstreeks naar een specifieke provider met modelvalidatie: + +```bash +POST http://localhost:20128/v1/providers/openai/chat/completions +POST http://localhost:20128/v1/providers/openai/embeddings +POST http://localhost:20128/v1/providers/fireworks/images/generations +``` + +Het providervoorvoegsel wordt automatisch toegevoegd als het ontbreekt. Niet-overeenkomende modellen retourneren `400`. + +### Netwerkproxyconfiguratie + +```bash +# Set global proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"global": {"type":"http","host":"proxy.example.com","port":"8080"}}' + +# Per-provider proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"providers": {"openai": {"type":"socks5","host":"proxy.example.com","port":"1080"}}}' + +# Test proxy +curl -X POST http://localhost:20128/api/settings/proxy/test \ + -d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}' +``` + +**Voorrang:** Sleutelspecifiek → Combospecifiek → Providerspecifiek → Globaal → Omgeving. + +### Modelcatalogus-API + +```bash +curl http://localhost:20128/api/models/catalog +``` + +Retourneert modellen gegroepeerd op provider met typen (`chat`, `embedding`, `image`). + +### Cloudsynchronisatie + +- Synchroniseer providers, combo's en instellingen op verschillende apparaten +- Automatische achtergrondsynchronisatie met time-out + fail-fast +- Geef de voorkeur aan server-side `BASE_URL`/`CLOUD_URL` in productie + +### LLM Gateway Intelligence (Fase 9) + +- **Semantische cache** — Niet-streaming automatisch cachen, temperatuur=0 reacties (omzeilen met `X-OmniRoute-No-Cache: true`) +- **Request Idempotency** — Ontdubbelt verzoeken binnen 5 seconden via `Idempotency-Key` of `X-Request-Id` header +- **Voortgang bijhouden** — Meld u aan voor SSE `event: progress`-gebeurtenissen via de `X-OmniRoute-Progress: true` header + +--- + +### Vertalerspeeltuin + +Toegang via **Dashboard → Vertaler**. Debug en visualiseer hoe OmniRoute API-verzoeken tussen providers vertaalt. + +| Modus | Doel | +| --------------- | ----------------------------------------------------------------------------------------------------- | +| **Speeltuin** | Selecteer bron-/doelformaten, plak een verzoek en bekijk direct de vertaalde uitvoer | +| **Chattester** | Stuur livechatberichten via de proxy en inspecteer de volledige aanvraag/antwoordcyclus | +| **Proefbank** | Voer batchtests uit voor meerdere formaatcombinaties om de juistheid van de vertalingen te verifiëren | +| **Livemonitor** | Bekijk realtime vertalingen terwijl verzoeken via de proxy | + +**Gebruiksscenario's:** + +- Debug waarom een specifieke client/provider-combinatie mislukt +- Controleer of denktags, tooloproepen en systeemprompts correct worden vertaald +- Vergelijk formaatverschillen tussen OpenAI-, Claude-, Gemini- en Responses API-formaten + +--- + +### Routeringsstrategieën + +Configureer via **Dashboard → Instellingen → Routing**. + +| Strategie | Beschrijving | +| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| **Eerst invullen** | Gebruikt accounts in volgorde van prioriteit: het primaire account handelt alle verzoeken af ​​totdat deze niet meer beschikbaar zijn | +| **Ronde Robin** | Bladert door alle accounts met een configureerbare sticky limiet (standaard: 3 oproepen per account) | +| **P2C (Kracht van twee keuzes)** | Kiest 2 willekeurige accounts en routes naar de gezondere – balanceert de belasting met bewustzijn van de gezondheid | +| **Willekeurig** | Selecteert willekeurig een account voor elk verzoek met behulp van Fisher-Yates shuffle | +| **Minst gebruikt** | Routes naar het account met de oudste `lastUsedAt` tijdstempel, waardoor het verkeer gelijkmatig wordt verdeeld | +| **Kostengeoptimaliseerd** | Routes naar het account met de laagste prioriteitswaarde, geoptimaliseerd voor providers met de laagste kosten | + +#### Wildcard-modelaliassen + +Maak jokertekenpatronen om modelnamen opnieuw toe te wijzen: + +``` +Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929 +Pattern: gpt-* → Target: gh/gpt-5.1-codex +``` + +Jokertekens ondersteunen `*` (willekeurige tekens) en `?` (enkel teken). + +#### Terugvalketens + +Definieer globale fallback-ketens die op alle verzoeken van toepassing zijn: + +``` +Chain: production-fallback + 1. cc/claude-opus-4-6 + 2. gh/gpt-5.1-codex + 3. glm/glm-4.7 +``` + +--- + +### Veerkracht en stroomonderbrekers + +Configureer via **Dashboard → Instellingen → Veerkracht**. + +OmniRoute implementeert veerkracht op providerniveau met vier componenten: + +1. **Providerprofielen** — Configuratie per provider voor: + - Foutdrempel (hoeveel fouten vóór opening) + - Cooldown-duur + - Snelheidslimietdetectiegevoeligheid + - Exponentiële uitstelparameters + +2. **Bewerkbare tarieflimieten** — Standaardinstellingen op systeemniveau configureerbaar in het dashboard: + - **Verzoeken per minuut (RPM)** — Maximaal aantal verzoeken per minuut per account + - **Min. tijd tussen verzoeken** — Minimale pauze in milliseconden tussen verzoeken + - **Max. gelijktijdige verzoeken** — Maximaal gelijktijdige verzoeken per account + - Klik op **Bewerken** om te wijzigen en vervolgens op **Opslaan** of **Annuleren**. Waarden blijven behouden via de veerkracht-API. + +3. **Circuit Breaker** — Volgt storingen per provider en opent automatisch het circuit wanneer een drempel wordt bereikt: + - **GESLOTEN** (Gezond) — Verzoeken stromen normaal door + - **OPEN** — Provider is tijdelijk geblokkeerd na herhaalde fouten + - **HALF_OPEN** — Testen of de provider is hersteld + +4. **Beleid en vergrendelde identificatiegegevens** — Toont de status van de stroomonderbreker en vergrendelde identificatiegegevens met de mogelijkheid tot geforceerd ontgrendelen. + +5. **Automatische detectie van tarieflimiet** — Controleert de headers `429` en `Retry-After` om proactief te voorkomen dat de tarieflimieten van de provider worden overschreden. + +**Pro-tip:** Gebruik de knop **Alles resetten** om alle stroomonderbrekers en cooldowns te wissen wanneer een provider herstelt van een storing. + +--- + +### Database exporteren/importeren + +Beheer databaseback-ups in **Dashboard → Instellingen → Systeem en opslag**. + +| Actie | Beschrijving | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Database exporteren** | Downloadt de huidige SQLite-database als een `.sqlite` bestand | +| **Alles exporteren (.tar.gz)** | Downloadt een volledig back-uparchief inclusief: database, instellingen, combo's, providerverbindingen (geen inloggegevens), API-sleutelmetagegevens | +| **Database importeren** | Upload een `.sqlite` bestand om de huidige database te vervangen. Er wordt automatisch een pre-importback-up gemaakt | + +```bash +# API: Export database +curl -o backup.sqlite http://localhost:20128/api/db-backups/export + +# API: Export all (full archive) +curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll + +# API: Import database +curl -X POST http://localhost:20128/api/db-backups/import \ + -F "file=@backup.sqlite" +``` + +**Importvalidatie:** Het geïmporteerde bestand wordt gevalideerd op integriteit (SQLite pragmacontrole), vereiste tabellen (`provider_connections`, `provider_nodes`, `combos`, `api_keys`) en grootte (max. 100 MB). + +**Gebruiksscenario's:** + +- Migreer OmniRoute tussen machines +- Maak externe back-ups voor noodherstel +- Deel configuraties tussen teamleden (alles exporteren → archief delen) + +--- + +### Instellingendashboard + +De instellingenpagina is onderverdeeld in 5 tabbladen voor eenvoudige navigatie: + +| Tabblad | Inhoud | +| --------------- | ------------------------------------------------------------------------------------------------------------------------- | +| **Beveiliging** | Login-/wachtwoordinstellingen, IP-toegangscontrole, API-authenticatie voor `/models` en providerblokkering | +| **Routing** | Globale routeringsstrategie (6 opties), wildcard-modelaliassen, fallback-ketens, combo-standaardwaarden | +| **Veerkracht** | Providerprofielen, bewerkbare tarieflimieten, status van stroomonderbrekers, beleid en vergrendelde identificatiegegevens | +| **AI** | Denken aan budgetconfiguratie, globale systeempromptinjectie, prompt cachestatistieken | +| **Geavanceerd** | Globale proxyconfiguratie (HTTP/SOCKS5) | + +--- + +### Kosten- en budgetbeheer + +Toegang via **Dashboard → Kosten**. + +| Tabblad | Doel | +| ------------- | ---------------------------------------------------------------------------------------------------------------- | +| **Begroting** | Stel bestedingslimieten per API-sleutel in met dagelijkse/wekelijkse/maandelijkse budgetten en realtime tracking | +| **Prijzen** | Bekijk en bewerk modelprijsgegevens — kosten per 1K input/output-tokens per provider | + +```bash +# API: Set a budget +curl -X POST http://localhost:20128/api/usage/budget \ + -H "Content-Type: application/json" \ + -d '{"keyId": "key-123", "limit": 50.00, "period": "monthly"}' + +# API: Get current budget status +curl http://localhost:20128/api/usage/budget +``` + +**Kosten bijhouden:** Bij elk verzoek wordt het tokengebruik geregistreerd en worden de kosten berekend met behulp van de prijstabel. Bekijk de uitsplitsingen in **Dashboard → Gebruik** per provider, model en API-sleutel. + +--- + +### Audiotranscriptie + +OmniRoute ondersteunt audiotranscriptie via het OpenAI-compatibele eindpunt: + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data + +# Example with curl +curl -X POST http://localhost:20128/v1/audio/transcriptions \ + -H "Authorization: Bearer your-api-key" \ + -F "file=@audio.mp3" \ + -F "model=deepgram/nova-3" +``` + +Beschikbare providers: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`). + +Ondersteunde audioformaten: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +### Combo-balanceringsstrategieën + +Configureer de balans per combo in **Dashboard → Combo's → Maken/bewerken → Strategie**. + +| Strategie | Beschrijving | +| ------------------------- | ----------------------------------------------------------------------------------- | +| **Round-Robin** | Roteert opeenvolgend door modellen | +| **Prioriteit** | Probeert altijd het eerste model; valt alleen terug op fouten | +| **Willekeurig** | Kiest voor elk verzoek een willekeurig model uit de combo | +| **Gewogen** | Routes proportioneel op basis van toegekende gewichten per model | +| **Minst gebruikt** | Routes naar het model met de minste recente verzoeken (gebruikt combo-statistieken) | +| **Kostengeoptimaliseerd** | Routes naar het goedkoopste beschikbare model (gebruikt prijstabel) | + +Algemene combo-standaardinstellingen kunnen worden ingesteld in **Dashboard → Instellingen → Routing → Combo-standaardwaarden**. + +--- + +### Gezondheidsdashboard + +Toegang via **Dashboard → Gezondheid**. Realtime overzicht van de systeemstatus met 6 kaarten: + +| Kaart | Wat het laat zien | +| --------------------------- | -------------------------------------------------------------------------- | +| **Systeemstatus** | Uptime, versie, geheugengebruik, datadirectory | +| **Provider Gezondheid** | Status stroomonderbreker per provider (gesloten/open/halfopen) | +| **Tarieflimieten** | Actieve afkoelperiodes voor tarieflimieten per account met resterende tijd | +| **Actieve vergrendelingen** | Providers tijdelijk geblokkeerd door het lockoutbeleid | +| **Handtekeningcache** | Deduplicatiecachestatistieken (actieve sleutels, trefpercentage) | +| **Latentietelemetrie** | p50/p95/p99-latentieaggregatie per provider | + +**Pro-tip:** De Gezondheidspagina wordt elke 10 seconden automatisch vernieuwd. Gebruik de stroomonderbrekerkaart om te identificeren welke providers problemen ondervinden. diff --git a/docs/i18n/no/API_REFERENCE.md b/docs/i18n/no/API_REFERENCE.md new file mode 100644 index 0000000000..a7c289f15d --- /dev/null +++ b/docs/i18n/no/API_REFERENCE.md @@ -0,0 +1,441 @@ +# API-referanse + +🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md) + +Fullstendig referanse for alle OmniRoute API-endepunkter. + +--- + +## Innholdsfortegnelse + +- [Chat Completions](#chat-completions) +- [Embeddings](#embeddings) +- [Image Generation](#image-generation) +- [List Models](#list-models) +- [Compatibility Endpoints](#compatibility-endpoints) +- [Semantic Cache](#semantic-cache) +- [Dashboard & Management](#dashboard--management) +- [Request Processing](#request-processing) +- [Authentication](#authentication) + +--- + +## Chatfullføringer + +```bash +POST /v1/chat/completions +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "cc/claude-opus-4-6", + "messages": [ + {"role": "user", "content": "Write a function to..."} + ], + "stream": true +} +``` + +### Egendefinerte topptekster + +| Overskrift | Retning | Beskrivelse | +| ------------------------ | ----------- | --------------------------------------- | +| `X-OmniRoute-No-Cache` | Forespørsel | Sett til `true` for å omgå cache | +| `X-OmniRoute-Progress` | Forespørsel | Sett til `true` for fremdriftshendelser | +| `Idempotency-Key` | Forespørsel | Dedup-nøkkel (5s-vindu) | +| `X-Request-Id` | Forespørsel | Alternativ dedup-nøkkel | +| `X-OmniRoute-Cache` | Svar | `HIT` eller `MISS` (ikke-streaming) | +| `X-OmniRoute-Idempotent` | Svar | `true` hvis deduplisert | +| `X-OmniRoute-Progress` | Svar | `enabled` hvis fremdriftssporing på | + +--- + +## Innebygginger + +```bash +POST /v1/embeddings +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "nebius/Qwen/Qwen3-Embedding-8B", + "input": "The food was delicious" +} +``` + +Tilgjengelige leverandører: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA. + +```bash +# List all embedding models +GET /v1/embeddings +``` + +--- + +## Bildegenerering + +```bash +POST /v1/images/generations +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "openai/dall-e-3", + "prompt": "A beautiful sunset over mountains", + "size": "1024x1024" +} +``` + +Tilgjengelige leverandører: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI. + +```bash +# List all image models +GET /v1/images/generations +``` + +--- + +## Liste over modeller + +```bash +GET /v1/models +Authorization: Bearer your-api-key + +→ Returns all chat, embedding, and image models + combos in OpenAI format +``` + +--- + +## Kompatibilitetsendepunkter + +| Metode | Sti | Format | +| ------- | --------------------------- | ---------------------- | +| INNLEGG | `/v1/chat/completions` | OpenAI | +| INNLEGG | `/v1/messages` | Antropisk | +| INNLEGG | `/v1/responses` | OpenAI-svar | +| INNLEGG | `/v1/embeddings` | OpenAI | +| INNLEGG | `/v1/images/generations` | OpenAI | +| FÅ | `/v1/models` | OpenAI | +| INNLEGG | `/v1/messages/count_tokens` | Antropisk | +| FÅ | `/v1beta/models` | Tvillingene | +| INNLEGG | `/v1beta/models/{...path}` | Gemini generer innhold | +| INNLEGG | `/v1/api/chat` | Ollama | + +### Dedikerte leverandørruter + +```bash +POST /v1/providers/{provider}/chat/completions +POST /v1/providers/{provider}/embeddings +POST /v1/providers/{provider}/images/generations +``` + +Leverandørprefikset blir automatisk lagt til hvis det mangler. Umatchede modeller returnerer `400`. + +--- + +## Semantisk buffer + +```bash +# Get cache stats +GET /api/cache + +# Clear all caches +DELETE /api/cache +``` + +Eksempel på svar: + +```json +{ + "semanticCache": { + "memorySize": 42, + "memoryMaxSize": 500, + "dbSize": 128, + "hitRate": 0.65 + }, + "idempotency": { + "activeKeys": 3, + "windowMs": 5000 + } +} +``` + +--- + +## Dashboard og administrasjon + +### Autentisering + +| Endepunkt | Metode | Beskrivelse | +| ----------------------------- | -------- | ---------------------- | +| `/api/auth/login` | INNLEGG | Logg inn | +| `/api/auth/logout` | INNLEGG | Logg ut | +| `/api/settings/require-login` | GET/SETT | Bytt innlogging kreves | + +### Leverandøradministrasjon + +| Endepunkt | Metode | Beskrivelse | +| ---------------------------- | -------------- | ------------------------------- | +| `/api/providers` | GET/POST | Liste / opprette leverandører | +| `/api/providers/[id]` | GET/SETT/SLETT | Administrer en leverandør | +| `/api/providers/[id]/test` | INNLEGG | Test leverandørtilkobling | +| `/api/providers/[id]/models` | FÅ | Liste leverandørmodeller | +| `/api/providers/validate` | INNLEGG | Valider leverandørkonfigurasjon | +| `/api/provider-nodes*` | Diverse | Leverandørnodeadministrasjon | +| `/api/provider-models` | GET/POST/SLETT | Egendefinerte modeller | + +### OAuth-flyter + +| Endepunkt | Metode | Beskrivelse | +| -------------------------------- | ------- | ------------------------- | +| `/api/oauth/[provider]/[action]` | Diverse | Leverandørspesifikk OAuth | + +### Ruting og konfig + +| Endepunkt | Metode | Beskrivelse | +| --------------------- | -------- | ------------------------------------- | +| `/api/models/alias` | GET/POST | Modellaliaser | +| `/api/models/catalog` | FÅ | Alle modeller etter leverandør + type | +| `/api/combos*` | Diverse | Combo management | +| `/api/keys*` | Diverse | API-nøkkelstyring | +| `/api/pricing` | FÅ | Modellprising | + +### Bruk og analyse + +| Endepunkt | Metode | Beskrivelse | +| --------------------------- | ------ | -------------------------- | +| `/api/usage/history` | FÅ | Brukshistorikk | +| `/api/usage/logs` | FÅ | Brukslogger | +| `/api/usage/request-logs` | FÅ | Logger på forespørselsnivå | +| `/api/usage/[connectionId]` | FÅ | Bruk per tilkobling | + +### Innstillinger + +| Endepunkt | Metode | Beskrivelse | +| ------------------------------- | -------- | ------------------------------------- | +| `/api/settings` | GET/SETT | Generelle innstillinger | +| `/api/settings/proxy` | GET/SETT | Nettverks proxy-konfigurasjon | +| `/api/settings/proxy/test` | INNLEGG | Test proxy-tilkobling | +| `/api/settings/ip-filter` | GET/SETT | IP-godkjenningsliste/blokkeringsliste | +| `/api/settings/thinking-budget` | GET/SETT | Begrunnelse token budsjett | +| `/api/settings/system-prompt` | GET/SETT | Global systemmelding | + +### Overvåking + +| Endepunkt | Metode | Beskrivelse | +| ------------------------ | -------- | ------------------------ | +| `/api/sessions` | FÅ | Aktiv øktsporing | +| `/api/rate-limits` | FÅ | Satsgrenser per konto | +| `/api/monitoring/health` | FÅ | Helsesjekk | +| `/api/cache` | FÅ/SLETT | Bufferstatistikk / slett | + +### Sikkerhetskopiering og eksport/import + +| Endepunkt | Metode | Beskrivelse | +| --------------------------- | ------- | ---------------------------------------------- | +| `/api/db-backups` | FÅ | Liste tilgjengelige sikkerhetskopier | +| `/api/db-backups` | PUT | Lag en manuell sikkerhetskopi | +| `/api/db-backups` | INNLEGG | Gjenopprett fra en bestemt sikkerhetskopi | +| `/api/db-backups/export` | FÅ | Last ned database som .sqlite-fil | +| `/api/db-backups/import` | INNLEGG | Last opp .sqlite-fil for å erstatte databasen | +| `/api/db-backups/exportAll` | FÅ | Last ned full sikkerhetskopi som .tar.gz-arkiv | + +### Cloud Sync + +| Endepunkt | Metode | Beskrivelse | +| ---------------------- | ------- | ----------------------------- | +| `/api/sync/cloud` | Diverse | Skysynkroniseringsoperasjoner | +| `/api/sync/initialize` | INNLEGG | Initialiser synkronisering | +| `/api/cloud/*` | Diverse | Cloud management | + +### CLI-verktøy + +| Endepunkt | Metode | Beskrivelse | +| ---------------------------------- | ------ | --------------------- | +| `/api/cli-tools/claude-settings` | FÅ | Claude CLI status | +| `/api/cli-tools/codex-settings` | FÅ | Codex CLI-status | +| `/api/cli-tools/droid-settings` | FÅ | Droid CLI-status | +| `/api/cli-tools/openclaw-settings` | FÅ | OpenClaw CLI-status | +| `/api/cli-tools/runtime/[toolId]` | FÅ | Generisk CLI kjøretid | + +CLI-svar inkluderer: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. + +### Resiliens- og rategrenser + +| Endepunkt | Metode | Beskrivelse | +| ----------------------- | -------- | ------------------------------ | +| `/api/resilience` | GET/SETT | Få/oppdater resiliensprofiler | +| `/api/resilience/reset` | INNLEGG | Tilbakestill effektbrytere | +| `/api/rate-limits` | FÅ | Satsgrensestatus per konto | +| `/api/rate-limit` | FÅ | Global rategrensekonfigurasjon | + +### Evaler + +| Endepunkt | Metode | Beskrivelse | +| ------------ | -------- | ---------------------------------- | +| `/api/evals` | GET/POST | List eval suiter / kjør evaluering | + +### Retningslinjer + +| Endepunkt | Metode | Beskrivelse | +| --------------- | -------------- | -------------------------- | +| `/api/policies` | GET/POST/SLETT | Administrer rutingpolicyer | + +### Samsvar + +| Endepunkt | Metode | Beskrivelse | +| --------------------------- | ------ | ------------------------------------ | +| `/api/compliance/audit-log` | FÅ | Overholdelsesrevisjonslogg (siste N) | + +### v1beta (Gemini-kompatibel) + +| Endepunkt | Metode | Beskrivelse | +| -------------------------- | ------- | ---------------------------------- | +| `/v1beta/models` | FÅ | Vis modeller i Gemini-format | +| `/v1beta/models/{...path}` | INNLEGG | Gemini `generateContent` endepunkt | + +Disse endepunktene gjenspeiler Geminis API-format for klienter som forventer naturlig Gemini SDK-kompatibilitet. + +### Interne / System APIer + +| Endepunkt | Metode | Beskrivelse | +| --------------- | ------- | ----------------------------------------------------------------- | +| `/api/init` | FÅ | Initialiseringssjekk av applikasjonen (brukes ved første kjøring) | +| `/api/tags` | FÅ | Ollama-kompatible modellkoder (for Ollama-klienter) | +| `/api/restart` | INNLEGG | Utløs grasiøs serveromstart | +| `/api/shutdown` | INNLEGG | Utløs grasiøs serveravslutning | + +> **Merk:** Disse endepunktene brukes internt av systemet eller for Ollama-klientkompatibilitet. De kalles vanligvis ikke opp av sluttbrukere. + +--- + +## Lydtranskripsjon + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data +``` + +Transkribere lydfiler ved hjelp av Deepgram eller AssemblyAI. + +**Forespørsel:** + +```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" +``` + +**Svar:** + +```json +{ + "text": "Hello, this is the transcribed audio content.", + "task": "transcribe", + "language": "en", + "duration": 12.5 +} +``` + +**Støttede leverandører:** `deepgram/nova-3`, `assemblyai/best`. + +**Støttede formater:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +## Ollama-kompatibilitet + +For klienter som bruker Ollamas API-format: + +```bash +# Chat endpoint (Ollama format) +POST /v1/api/chat + +# Model listing (Ollama format) +GET /api/tags +``` + +Forespørsler oversettes automatisk mellom Ollama og interne formater. + +--- + +## Telemetri + +```bash +# Get latency telemetry summary (p50/p95/p99 per provider) +GET /api/telemetry/summary +``` + +**Svar:** + +```json +{ + "providers": { + "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, + "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } + } +} +``` + +--- + +## Budsjett + +```bash +# Get budget status for all API keys +GET /api/usage/budget + +# Set or update a budget +POST /api/usage/budget +Content-Type: application/json + +{ + "keyId": "key-123", + "limit": 50.00, + "period": "monthly" +} +``` + +--- + +## Modelltilgjengelighet + +```bash +# Get real-time model availability across all providers +GET /api/models/availability + +# Check availability for a specific model +POST /api/models/availability +Content-Type: application/json + +{ + "model": "claude-sonnet-4-5-20250929" +} +``` + +--- + +## Forespørselsbehandling + +1. Klient sender forespørsel til `/v1/*` +2. Rutebehandler anroper `handleChat`, `handleEmbedding`, `handleAudioTranscription` eller `handleImageGeneration` +3. Modellen er løst (direkte leverandør/modell eller alias/kombinasjon) +4. Påloggingsinformasjon valgt fra lokal DB med filtrering av kontotilgjengelighet +5. For chat: `handleChatCore` — formatdeteksjon, oversettelse, hurtigbuffersjekk, idempotenssjekk +6. Leverandør eksekutør sender oppstrømsforespørsel +7. Svar oversatt tilbake til klientformat (chat) eller returnert som det er (innbygginger/bilder/lyd) +8. Bruk/logging registrert +9. Fallback gjelder feil i henhold til kombinasjonsregler + +Full arkitekturreferanse: [**OMNI_TOKEN_119**](ARCHITECTURE.md) + +--- + +## Autentisering + +- Dashboard-ruter (`/dashboard/*`) bruker `auth_token`-informasjonskapsel +- Innlogging bruker lagret passordhash; fallback til `INITIAL_PASSWORD` +- `requireLogin` kan byttes via `/api/settings/require-login` +- `/v1/*`-ruter krever valgfritt Bearer API-nøkkel når `REQUIRE_API_KEY=true` diff --git a/docs/i18n/no/ARCHITECTURE.md b/docs/i18n/no/ARCHITECTURE.md new file mode 100644 index 0000000000..6e9a91372d --- /dev/null +++ b/docs/i18n/no/ARCHITECTURE.md @@ -0,0 +1,782 @@ +# 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) + +_Sist oppdatert: 2026-02-18_ + +## Sammendrag + +OmniRoute er en lokal AI-rutinggateway og dashbord bygget på Next.js. +Den gir et enkelt OpenAI-kompatibelt endepunkt (`/v1/*`) og ruter trafikk på tvers av flere oppstrømsleverandører med oversettelse, reserve, token-oppdatering og brukssporing. + +Kjernefunksjoner: + +- OpenAI-kompatibel API-overflate for CLI/verktøy (28 leverandører) +- Forespørsel/svar oversettelse på tvers av leverandørformater +- Modellkombinasjonsfallback (multimodellsekvens) +- Reserveback på kontonivå (multikonto per leverandør) +- OAuth + API-nøkkelleverandør tilkoblingsadministrasjon +- Innbyggingsgenerering via `/v1/embeddings` (6 leverandører, 9 modeller) +- Bildegenerering via `/v1/images/generations` (4 leverandører, 9 modeller) +- Tenk tag-parsing (`...`) for resonneringsmodeller +- Respons sanitization for streng OpenAI SDK-kompatibilitet +- Rollenormalisering (utvikler→system, system→bruker) for kompatibilitet på tvers av leverandører +- Konvertering av strukturert utdata (json_schema → Gemini responseSchema) +- Lokal utholdenhet for leverandører, nøkler, aliaser, kombinasjoner, innstillinger, priser +- Bruks-/kostnadssporing og forespørselslogging +- Valgfri skysynkronisering for synkronisering av flere enheter/tilstander +- IP-godkjenningsliste/blokkeringsliste for API-tilgangskontroll +- Tenker budsjettstyring (gjennomgang/auto/tilpasset/tilpasset) +- Injeksjon av et globalt system +- Sesjonssporing og fingeravtrykk +- Forbedret prisbegrensning per konto med leverandørspesifikke profiler +- Strømbrytermønster for leverandørens motstandskraft +- Anti-tordenbeskyttelse med mutex-låsing +- Signaturbasert forespørselsdedupliseringsbuffer +- Domenelag: modelltilgjengelighet, kostnadsregler, reservepolicy, lockoutpolicy +- Vedvarende domenetilstand (SQLite-gjennomskrivingsbuffer for reserver, budsjetter, lockouts, strømbrytere) +- Policymotor for sentralisert forespørselsevaluering (lockout → budsjett → reserve) +- Be om telemetri med p50/p95/p99 latensaggregering +- Korrelasjons-ID (X-Request-Id) for ende-til-ende-sporing +- Overholdelsesrevisjonslogging med opt-out per API-nøkkel +- Eval rammeverk for LLM kvalitetssikring +- Resilience UI-dashbord med sanntids strømbryterstatus +- Modulære OAuth-leverandører (12 individuelle moduler under `src/lib/oauth/providers/`) + +Primær kjøretidsmodell: + +– Next.js app-ruter under `src/app/api/*` implementerer både dashbord-APIer og kompatibilitets-APIer + +- En delt SSE/rutingkjerne i `src/sse/*` + `open-sse/*` håndterer leverandørutførelse, oversettelse, strømming, fallback og bruk + +## Omfang og grenser + +### I omfang + +- Lokal gateway kjøretid +- Dashboard management APIer +- Leverandørautentisering og tokenoppdatering +- Be om oversettelse og SSE-streaming +- Lokal stat + bruksutholdenhet +- Valgfri skysynkroniseringsorkestrering + +### Utenfor omfang + +- Implementering av skytjenester bak `NEXT_PUBLIC_CLOUD_URL` +- Leverandør SLA/kontrollplan utenfor lokal prosess +- Eksterne CLI-binærfiler i seg selv (Claude CLI, Codex CLI, etc.) + +## Systemkontekst på høyt nivå + +```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 +``` + +## Kjernekjøringskomponenter + +## 1) API og rutinglag (Next.js App Routes) + +Hovedkataloger: + +- `src/app/api/v1/*` og `src/app/api/v1beta/*` for kompatibilitets-APIer +- `src/app/api/*` for administrasjons-/konfigurasjons-APIer +- Neste omskrivninger i `next.config.mjs` kart `/v1/*` til `/api/v1/*` + +Viktige 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 tilpassede modeller med `custom: true` +- `src/app/api/v1/embeddings/route.ts` — innebyggingsgenerering (6 leverandører) +- `src/app/api/v1/images/generations/route.ts` — bildegenerering (4+ leverandører inkl. Antigravity/Nebius) +- `src/app/api/v1/messages/count_tokens/route.ts` +- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — dedikert chat per leverandør +- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — dedikerte innbygginger per leverandør +- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — dedikerte bilder per leverandør +- `src/app/api/v1beta/models/route.ts` +- `src/app/api/v1beta/models/[...path]/route.ts` + +Administrasjonsdomener: + +- Auth/innstillinger: `src/app/api/auth/*`, `src/app/api/settings/*` +- Leverandører/tilkoblinger: `src/app/api/providers*` +- Leverandørnoder: `src/app/api/provider-nodes*` +- Egendefinerte modeller: `src/app/api/provider-models` (GET/POST/DELETE) +- Modellkatalog: `src/app/api/models/catalog` (GET) +- Proxy-konfigurasjon: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST) +- OAuth: `src/app/api/oauth/*` +- Nøkler/aliaser/kombinasjoner/priser: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing` +- Bruk: `src/app/api/usage/*` +- Synkronisering/sky: `src/app/api/sync/*`, `src/app/api/cloud/*` +- CLI-verktøyhjelpere: `src/app/api/cli-tools/*` +- IP-filter: `src/app/api/settings/ip-filter` (GET/PUT) +- Tenkebudsjett: `src/app/api/settings/thinking-budget` (GET/PUT) +- Systemmelding: `src/app/api/settings/system-prompt` (GET/PUT) +- Økter: `src/app/api/sessions` (GET) +- Satsgrenser: `src/app/api/rate-limits` (GET) +- Motstandsdyktighet: `src/app/api/resilience` (GET/PATCH) — leverandørprofiler, strømbryter, rategrensetilstand +- Resiliens tilbakestilling: `src/app/api/resilience/reset` (POST) — tilbakestill brytere + nedkjøling +- Bufferstatistikk: `src/app/api/cache/stats` (GET/DELETE) +- Modelltilgjengelighet: `src/app/api/models/availability` (GET/POST) +- Telemetri: `src/app/api/telemetry/summary` (GET) + – Budsjett: `src/app/api/usage/budget` (GET/POST) +- Reservekjeder: `src/app/api/fallback/chains` (GET/POST/DELETE) +- Overholdelsesrevisjon: `src/app/api/compliance/audit-log` (GET) +- Evaler: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET) +- Retningslinjer: `src/app/api/policies` (GET/POST) + +## 2) SSE + Translation Core + +Hovedstrømningsmoduler: + +- Inngang: `src/sse/handlers/chat.ts` +- Kjerneorkestrering: `open-sse/handlers/chatCore.ts` +- Leverandørutførelsesadaptere: `open-sse/executors/*` +- Formatdeteksjon/leverandørkonfigurasjon: `open-sse/services/provider.ts` +- Modellanalyse/oppløsning: `src/sse/services/model.ts`, `open-sse/services/model.ts` +- Kontoreservelogikk: `open-sse/services/accountFallback.ts` +- Oversettelsesregister: `open-sse/translator/index.ts` +- Strømtransformasjoner: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts` +- Bruksutvinning/normalisering: `open-sse/utils/usageTracking.ts` +- Think tag-parser: `open-sse/utils/thinkTagParser.ts` +- Innebyggingsbehandler: `open-sse/handlers/embeddings.ts` +- Innebyggingsleverandørregister: `open-sse/config/embeddingRegistry.ts` +- Bildegenereringsbehandler: `open-sse/handlers/imageGeneration.ts` +- Bildeleverandørs register: `open-sse/config/imageRegistry.ts` +- Response sanitization: `open-sse/handlers/responseSanitizer.ts` +- Rollenormalisering: `open-sse/services/roleNormalizer.ts` + +Tjenester (forretningslogikk): + +- Kontovalg/score: `open-sse/services/accountSelector.ts` +- Kontekstlivssyklusadministrasjon: `open-sse/services/contextManager.ts` +- IP-filterhåndhevelse: `open-sse/services/ipFilter.ts` +- Øktsporing: `open-sse/services/sessionManager.ts` +- Be om deduplisering: `open-sse/services/signatureCache.ts` +- Systemprompt-injeksjon: `open-sse/services/systemPrompt.ts` +- Tenkende budsjettstyring: `open-sse/services/thinkingBudget.ts` +- Jokertegn modellruting: `open-sse/services/wildcardRouter.ts` +- Satsgrenseadministrasjon: `open-sse/services/rateLimitManager.ts` +- Strømbryter: `open-sse/services/circuitBreaker.ts` + +Domenelagsmoduler: + +- Modelltilgjengelighet: `src/lib/domain/modelAvailability.ts` +- Kostnadsregler/budsjetter: `src/lib/domain/costRules.ts` + – Reservepolicy: `src/lib/domain/fallbackPolicy.ts` +- Kombinasjonsløser: `src/lib/domain/comboResolver.ts` + – Utelukkingspolicy: `src/lib/domain/lockoutPolicy.ts` +- Policymotor: `src/domain/policyEngine.ts` — sentralisert lockout → budsjett → reserveevaluering +- Feilkodekatalog: `src/lib/domain/errorCodes.ts` +- Forespørsels-ID: `src/lib/domain/requestId.ts` +- Tidsavbrudd for henting: `src/lib/domain/fetchTimeout.ts` +- Be om telemetri: `src/lib/domain/requestTelemetry.ts` +- Samsvar/revisjon: `src/lib/domain/compliance/index.ts` +- Evalløper: `src/lib/domain/evalRunner.ts` +- Vedvarende domenetilstand: `src/lib/db/domainState.ts` — SQLite CRUD for reservekjeder, budsjetter, kostnadshistorikk, lockouttilstand, strømbrytere + +OAuth-leverandørmoduler (12 individuelle filer under `src/lib/oauth/providers/`): + +- Registerindeks: `src/lib/oauth/providers/index.ts` + – Individuelle leverandører: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, `...`TO, **OMNI*TOKEN ***119\_\_, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts` +- Tynn innpakning: `src/lib/oauth/providers.ts` — re-eksport fra individuelle moduler + +## 3) Utholdenhetslag + +Primær tilstand DB: + +- `src/lib/localDb.ts` +- fil: `${DATA_DIR}/db.json` (eller `$XDG_CONFIG_HOME/omniroute/db.json` når angitt, ellers `~/.omniroute/db.json`) +- enheter: providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt** + +Bruk DB: + +- `src/lib/usageDb.ts` +- filer: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- følger samme grunnleggende katalogpolicy som `localDb` (`DATA_DIR`, deretter `XDG_CONFIG_HOME/omniroute` når angitt) +- dekomponert i fokuserte undermoduler: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts` + +Domenetilstand DB (SQLite): + +- `src/lib/db/domainState.ts` — CRUD-operasjoner for domenetilstand +- Tabeller (opprettet i `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers` +- Gjennomskrivingsbuffermønster: kart i minnet er autoritative under kjøring; mutasjoner skrives synkront til SQLite; tilstand gjenopprettes fra DB ved kaldstart + +## 4) Auth + Security Surfaces + +- Dashboard-informasjonskapselautentisering: `src/proxy.ts`, `src/app/api/auth/login/route.ts` +- Generering/verifisering av API-nøkler: `src/shared/utils/apiKey.ts` +- Leverandørhemmeligheter vedvarte i `providerConnections`-oppføringer +- Utgående proxy-støtte via `open-sse/utils/proxyFetch.ts` (env vars) og `open-sse/utils/networkProxy.ts` (konfigurerbar per leverandør eller global) + +## 5) Cloud Sync + +- Planlegger init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts` +- Periodisk oppgave: `src/shared/services/cloudSyncScheduler.ts` +- Kontrollrute: `src/app/api/sync/cloud/route.ts` + +## Forespørselslivssyklus (`/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 Reserve 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] +``` + +Reservebeslutninger er drevet av `open-sse/services/accountFallback.ts` ved hjelp av statuskoder og feilmeldingsheuristikk. + +## 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 +``` + +Oppdatering under levende trafikk utføres inne i `open-sse/handlers/chatCore.ts` via eksekveren `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 utløses av `CloudSyncScheduler` når skyen er aktivert. + +## Datamodell og lagringskart + +```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 lagringsfiler: + +- hovedtilstand: `${DATA_DIR}/db.json` (eller `$XDG_CONFIG_HOME/omniroute/db.json` når angitt, ellers `~/.omniroute/db.json`) +- bruksstatistikk: `${DATA_DIR}/usage.json` +- be om logglinjer: `${DATA_DIR}/log.txt` +- valgfrie oversetter/forespørsler om feilsøkingsøkter: `/logs/...` + +## Utrullingstopologi + +```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 +``` + +## Modulmapping (beslutningskritisk) + +### Rute- og API-moduler + +- `src/app/api/v1/*`, `src/app/api/v1beta/*`: kompatibilitets-APIer +- `src/app/api/v1/providers/[provider]/*`: dedikerte ruter per leverandør (chat, innebygging, bilder) +- `src/app/api/providers*`: leverandør CRUD, validering, testing +- `src/app/api/provider-nodes*`: tilpasset kompatibel nodeadministrasjon +- `src/app/api/provider-models`: tilpasset modelladministrasjon (CRUD) +- `src/app/api/models/catalog`: full modellkatalog API (alle typer gruppert etter leverandør) +- `src/app/api/oauth/*`: OAuth/enhetskode flyter +- `src/app/api/keys*`: lokal API-nøkkellivssyklus +- `src/app/api/models/alias`: aliasadministrasjon +- `src/app/api/combos*`: reservekombinasjonsadministrasjon +- `src/app/api/pricing`: prisoverstyringer for kostnadsberegning +- `src/app/api/settings/proxy`: proxy-konfigurasjon (GET/PUT/DELETE) +- `src/app/api/settings/proxy/test`: utgående proxy-tilkoblingstest (POST) +- `src/app/api/usage/*`: APIer for bruk og logger +- `src/app/api/sync/*` + `src/app/api/cloud/*`: skysynkronisering og skyvendte hjelpere +- `src/app/api/cli-tools/*`: lokale CLI-konfigurasjonsforfattere/kontrollere +- `src/app/api/settings/ip-filter`: IP-godkjenningsliste/blokkeringsliste (GET/PUT) +- `src/app/api/settings/thinking-budget`: budsjettkonfigurasjon for tenketoken (GET/PUT) +- `src/app/api/settings/system-prompt`: global systemmelding (GET/PUT) +- `src/app/api/sessions`: aktiv øktoppføring (GET) +- `src/app/api/rate-limits`: satsgrensestatus per konto (GET) + +### Kjerne for ruting og utførelse + +- `src/sse/handlers/chat.ts`: forespørsel om parse, kombinasjonshåndtering, kontovalgsløyfe +- `open-sse/handlers/chatCore.ts`: oversettelse, eksekutorutsendelse, prøv på nytt/oppdateringshåndtering, strømoppsett +- `open-sse/executors/*`: leverandørspesifikk nettverks- og formatatferd + +### Oversettelsesregister og formatkonverterere + +- `open-sse/translator/index.ts`: oversetterregister og orkestrering +- Be om oversettere: `open-sse/translator/request/*` +- Svaroversettere: `open-sse/translator/response/*` +- Formatkonstanter: `open-sse/translator/formats.ts` + +### Utholdenhet + +- `src/lib/localDb.ts`: vedvarende konfig/tilstand +- `src/lib/usageDb.ts`: brukshistorikk og rullende forespørselslogger + +## Leverandørdekning (strategimønster) + +Hver leverandør har en spesialisert eksekutør som utvider `BaseExecutor` (i `open-sse/executors/base.ts`), som gir URL-bygging, headerkonstruksjon, forsøk på nytt med eksponentiell backoff, legitimasjonsoppdateringskroker og `execute()` orkestreringsmetoden. + +| Utfører | Leverandør(er) | Spesiell håndtering | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- | +| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Dynamisk URL/header-konfigurasjon per leverandør | +| `AntigravityExecutor` | Google Antigravity | Egendefinerte prosjekt-/sesjons-ID-er, Prøv på nytt etter parsing | +| `CodexExecutor` | OpenAI Codex | Injiserer systeminstruksjoner, tvinger resonnementinnsats | +| `CursorExecutor` | Markør IDE | ConnectRPC-protokoll, Protobuf-koding, forespørsel om signering via sjekksum | +| `GithubExecutor` | GitHub Copilot | Copilot token oppdatering, VSCode-lignende overskrifter | +| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binært format → SSE-konvertering | +| `GeminiCLIExecutor` | Gemini CLI | Oppdateringssyklus for Google OAuth-token | + +Alle andre leverandører (inkludert tilpassede kompatible noder) bruker `DefaultExecutor`. + +## Leverandørkompatibilitetsmatrise + +| Leverandør | Format | Auth | Stream | Ikke-stream | Token oppdatering | Bruks-API | +| ---------------- | --------------- | --------------------- | ---------------- | ----------- | ----------------- | ------------------------ | +| Claude | claude | API-nøkkel / OAuth | ✅ | ✅ | ✅ | ⚠️ Kun administrator | +| Tvillingene | Gemini | API-nøkkel / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | +| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | +| Antigravitasjon | antigravitasjon | OAuth | ✅ | ✅ | ✅ | ✅ Full kvote API | +| OpenAI | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| Codex | openai-svar | OAuth | ✅ tvunget | ❌ | ✅ | ✅ Satsgrenser | +| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Kvote øyeblikksbilder | +| Markør | markør | Egendefinert sjekksum | ✅ | ✅ | ❌ | ❌ | +| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Bruksgrenser | +| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Per forespørsel | +| iFlow | openai | OAuth (Grunnleggende) | ✅ | ✅ | ✅ | ⚠️ Per forespørsel | +| OpenRouter | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| GLM/Kimi/MiniMax | claude | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| DeepSeek | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| Groq | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| xAI (Grok) | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| Mistral | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| Forvirring | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| Sammen AI | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| Fyrverkeri AI | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| Cerebras | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| Sammenheng | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | +| NVIDIA NIM | openai | API-nøkkel | ✅ | ✅ | ❌ | ❌ | + +## Formatoversettelsesdekning + +Oppdagede kildeformater inkluderer: + +- `openai` +- `openai-responses` +- `claude` +- `gemini` + +Målformater inkluderer: + +- OpenAI chat/svar +- Claude +- Gemini/Gemini-CLI/Antigravity konvolutt +- Kiro +- Markør + +Oversettelser bruker **OpenAI som hub-format** – alle konverteringer går gjennom OpenAI som mellomliggende: + +``` +Source Format → OpenAI (hub) → Target Format +``` + +Oversettelser velges dynamisk basert på kildens nyttelastform og leverandørens målformat. + +Ytterligere behandlingslag i oversettelsespipelinen: + +- **Responssanering** - Fjerner ikke-standardiserte felt fra OpenAI-formatsvar (både streaming og ikke-streaming) for å sikre streng SDK-overholdelse +- **Rollenormalisering** — Konverterer `developer` → `system` for ikke-OpenAI-mål; slår sammen `system` → `user` for modeller som avviser systemrollen (GLM, ERNIE) +- **Tenk tag-utvinning** — analyserer `...` blokker fra innhold til feltet `reasoning_content` +- **Structured output** — Konverterer OpenAI `response_format.json_schema` til Gemini's `responseMimeType` + `responseSchema` + +## Støttede API-endepunkter + +| Endepunkt | Format | Handler | +| -------------------------------------------------- | ---------------------- | ----------------------------------------------------------- | +| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` | +| `POST /v1/messages` | Claude Meldinger | Samme behandler (automatisk oppdaget) | +| `POST /v1/responses` | OpenAI-svar | `open-sse/handlers/responsesHandler.ts` | +| `POST /v1/embeddings` | OpenAI Embeddings | `open-sse/handlers/embeddings.ts` | +| `GET /v1/embeddings` | Modellliste | API-rute | +| `POST /v1/images/generations` | OpenAI-bilder | `open-sse/handlers/imageGeneration.ts` | +| `GET /v1/images/generations` | Modellliste | API-rute | +| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Dedikert per leverandør med modellvalidering | +| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Dedikert per leverandør med modellvalidering | +| `POST /v1/providers/{provider}/images/generations` | OpenAI-bilder | Dedikert per leverandør med modellvalidering | +| `POST /v1/messages/count_tokens` | Claude Token Count | API-rute | +| `GET /v1/models` | OpenAI-modellliste | API-rute (chat + innebygging + bilde + tilpassede modeller) | +| `GET /api/models/catalog` | Katalog | Alle modeller gruppert etter leverandør + type | +| `POST /v1beta/models/*:streamGenerateContent` | Gemini innfødt | API-rute | +| `GET/PUT/DELETE /api/settings/proxy` | Proxy-konfigurasjon | Nettverks proxy-konfigurasjon | +| `POST /api/settings/proxy/test` | Proxy-tilkobling | Proxy-helse/tilkoblingstestendepunkt | +| `GET/POST/DELETE /api/provider-models` | Egendefinerte modeller | Tilpasset modelladministrasjon per leverandør | + +## Bypass Handler + +Bypass-behandleren (`open-sse/utils/bypassHandler.ts`) avskjærer kjente "kasting"-forespørsler fra Claude CLI – oppvarmingspinger, tittelutdrag og tokentellinger – og returnerer et **falsk svar** uten å forbruke oppstrømsleverandørtokens. Dette utløses bare når `User-Agent` inneholder `claude-cli`. + +## Be om Logger Pipeline + +Forespørselsloggeren (`open-sse/utils/requestLogger.ts`) gir en 7-trinns feilsøkingsloggingspipeline, deaktivert som standard, aktivert 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 `/logs//` for hver forespørselsøkt. + +## Feilmoduser og motstandskraft + +## 1) Konto/leverandørtilgjengelighet + +- Nedkjøling av leverandørens konto på forbigående/rate/auth-feil +- kontoreserve før mislykket forespørsel +- combo modell fallback når gjeldende modell/leverandørbane er oppbrukt + +## 2) Token-utløp + +- forhåndssjekk og oppdater med nytt forsøk for leverandører som kan oppdateres +- 401/403 prøv på nytt etter oppdateringsforsøk i kjernebanen + +## 3) Strømsikkerhet + +- frakoblingsbevisst strømkontroller +- oversettelsesstrøm med end-of-stream flush og `[DONE]` håndtering + – fallback for bruksestimat når leverandørbruksmetadata mangler + +## 4) Cloud Sync Degradering + +- Synkroniseringsfeil dukker opp, men lokal kjøretid fortsetter +- planleggeren har logikk som kan forsøke på nytt, men periodisk kjøring kaller for øyeblikket enkeltforsøkssynkronisering som standard + +## 5) Dataintegritet + +- DB-formmigrering/reparasjon for manglende nøkler +- korrupte JSON-tilbakestillingstiltak for localDb og usageDb + +## Observerbarhet og operasjonelle signaler + +Synlighetskilder for kjøretid: + +- konsolllogger fra `src/sse/utils/logger.ts` +- bruksaggregater per forespørsel i `usage.json` +- logg på status for tekstforespørsel `log.txt` +- valgfrie dype forespørsels-/oversettelseslogger under `logs/` når `ENABLE_REQUEST_LOGS=true` +- endepunkter for dashbordbruk (`/api/usage/*`) for brukergrensesnittforbruk + +## Sikkerhetssensitive grenser + +- JWT-hemmelighet (`JWT_SECRET`) sikrer bekreftelse/signering av informasjonskapsler for dashbordøkten +- Innledende passordreserve (`INITIAL_PASSWORD`, standard `123456`) må overstyres i reelle distribusjoner +- API-nøkkel HMAC-hemmelighet (`API_KEY_SECRET`) sikrer generert lokalt API-nøkkelformat +- Leverandørhemmeligheter (API-nøkler/-tokens) er bevart i lokal DB og bør beskyttes på filsystemnivå +- Sluttpunkter for skysynkronisering er avhengige av API-nøkkelautentisering + maskin-ID-semantikk + +## Miljø- og kjøretidsmatrise + +Miljøvariabler som brukes aktivt av kode: + +- App/auth: `JWT_SECRET`, `INITIAL_PASSWORD` +- Lagring: `DATA_DIR` +- Kompatibel nodeoppførsel: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` +- Valgfri lagringsbaseoverstyring (Linux/macOS når `DATA_DIR` ikke er innstilt): `XDG_CONFIG_HOME` +- Sikkerhetshashing: `API_KEY_SECRET`, `MACHINE_ID_SALT` +- Logging: `ENABLE_REQUEST_LOGS` +- Synkronisering/nettadresser i nettskyen: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL` +- Utgående proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` og varianter med små bokstaver +- SOCKS5-funksjonsflagg: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` + – Plattform-/kjøretidshjelpere (ikke appspesifikk konfigurasjon): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME` + +## Kjente arkitektoniske notater + +1. `usageDb` og `localDb` deler nå samme grunnkatalogpolicy (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) med eldre filmigrering. +2. `/api/v1/route.ts` returnerer en statisk modellliste og er ikke hovedmodellkilden som brukes av `/v1/models`. +3. Forespørselslogger skriver fullstendige overskrifter/tekst når den er aktivert; behandle loggkatalogen som sensitiv. +4. Skyadferd avhenger av korrekt `NEXT_PUBLIC_BASE_URL` og skyendepunkts tilgjengelighet. +5. `open-sse/`-katalogen er publisert som `@omniroute/open-sse` **npm-arbeidsområdepakken**. Kildekoden importerer den via `@omniroute/open-sse/...` (løst av Next.js `transpilePackages`). Filbaner i dette dokumentet bruker fortsatt katalognavnet `open-sse/` for konsistens. +6. Diagrammer i dashbordet bruker **Recharts** (SVG-basert) for tilgjengelige, interaktive analysevisualiseringer (stolpediagram for modellbruk, leverandøroversiktstabeller med suksessrater). +7. E2E-tester bruker **Playwright** (`tests/e2e/`), kjøres via `npm run test:e2e`. Enhetstester bruker **Node.js testløper** (`tests/unit/`), kjøres via `npm run test:plan3`. Kildekoden under `src/` er **TypeScript** (`.ts`/`.tsx`); arbeidsområdet `open-sse/` forblir JavaScript (`.js`). +8. Innstillinger-siden er organisert i 5 faner: Sikkerhet, Ruting (6 globale strategier: fill-first, round-robin, p2c, random, minst brukt, kostnadsoptimalisert), Resiliens (redigerbare hastighetsgrenser, strømbryter, policyer), AI (tenkebudsjett, systemprompt, promptbuffer), Advanced (proxy). + +## Kontrolliste for operasjonell verifisering + +- Bygg fra kilde: `npm run build` +- Bygg Docker-bilde: `docker build -t omniroute .` +- Start tjenesten og bekreft: +- `GET /api/settings` +- `GET /api/v1/models` +- CLI-målgrunnadressen skal være `http://:20128/v1` når `PORT=20128` diff --git a/docs/i18n/no/CODEBASE_DOCUMENTATION.md b/docs/i18n/no/CODEBASE_DOCUMENTATION.md new file mode 100644 index 0000000000..23b876587c --- /dev/null +++ b/docs/i18n/no/CODEBASE_DOCUMENTATION.md @@ -0,0 +1,589 @@ +# omniroute — Kodebasedokumentasjon + +🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md) + +> En omfattende, nybegynnervennlig guide til **omniroute** multi-leverandør AI proxy-ruter. + +--- + +## 1. Hva er omniroute? + +omniroute er en **proxy-ruter** som sitter mellom AI-klienter (Claude CLI, Codex, Cursor IDE, etc.) og AI-leverandører (Anthropic, Google, OpenAI, AWS, GitHub, etc.). Det løser ett stort problem: + +> **Ulike AI-klienter snakker forskjellige "språk" (API-formater), og forskjellige AI-leverandører forventer også forskjellige "språk".** omniroute oversetter mellom dem automatisk. + +Tenk på det som en universell oversetter i FN - enhver delegat kan snakke hvilket som helst språk, og oversetteren konverterer det til en hvilken som helst annen delegat. + +--- + +## 2. Arkitekturoversikt + +```mermaid +graph LR + subgraph Clients + A[Claude CLI] + B[Codex] + C[Cursor IDE] + D[OpenAI-compatible] + end + + subgraph omniroute + E[Handler Layer] + F[Translator Layer] + G[Executor Layer] + H[Services Layer] + end + + subgraph Providers + I[Anthropic Claude] + J[Google Gemini] + K[OpenAI / Codex] + L[GitHub Copilot] + M[AWS Kiro] + N[Antigravity] + O[Cursor API] + end + + A --> E + B --> E + C --> E + D --> E + E --> F + F --> G + G --> I + G --> J + G --> K + G --> L + G --> M + G --> N + G --> O + H -.-> E + H -.-> G +``` + +### Kjerneprinsipp: Hub-and-Speake-oversettelse + +All formatoversettelse går gjennom **OpenAI-formatet som navet**: + +``` +Client Format → [OpenAI Hub] → Provider Format (request) +Provider Format → [OpenAI Hub] → Client Format (response) +``` + +Dette betyr at du bare trenger **N oversettere** (én per format) i stedet for **N²** (hvert par). + +--- + +## 3. Prosjektstruktur + +``` +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 +``` + +--- + +## 4. Modul-for-modul-oversikt + +### 4.1 Config (`open-sse/config/`) + +**enkelt kilde til sannhet** for alle leverandørkonfigurasjoner. + +| Fil | Formål | +| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `constants.ts` | `PROVIDERS` objekt med grunnleggende URL-er, OAuth-legitimasjon (standard), overskrifter og standard systemmeldinger for hver leverandør. Definerer også `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG` og `SKIP_PATTERNS`. | +| `credentialLoader.ts` | Laster inn ekstern legitimasjon fra `data/provider-credentials.json` og slår dem sammen over de hardkodede standardinnstillingene i `PROVIDERS`. Holder hemmeligheter utenfor kildekontroll samtidig som bakoverkompatibiliteten opprettholdes. | +| `providerModels.ts` | Sentralt modellregister: kartleverandøraliaser → modell-ID-er. Funksjoner som `getModels()`, `getProviderByAlias()`. | +| `codexInstructions.ts` | Systeminstruksjoner injisert i Codex-forespørsler (redigeringsbegrensninger, sandkasseregler, godkjenningspolicyer). | +| `defaultThinkingSignature.ts` | Standard "tenkende" signaturer for Claude og Gemini-modeller. | +| `ollamaModels.ts` | Skjemadefinisjon for lokale Ollama-modeller (navn, størrelse, familie, kvantisering). | + +#### Innlastingsflyt for legitimasjon + +```mermaid +flowchart TD + A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"] + B --> C{"data/provider-credentials.json\nexists?"} + C -->|Yes| D["credentialLoader reads JSON"] + C -->|No| E["Use hardcoded defaults"] + D --> F{"For each provider in JSON"} + F --> G{"Provider exists\nin PROVIDERS?"} + G -->|No| H["Log warning, skip"] + G -->|Yes| I{"Value is object?"} + I -->|No| J["Log warning, skip"] + I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"] + K --> F + H --> F + J --> F + F -->|Done| L["PROVIDERS ready with\nmerged credentials"] + E --> L +``` + +--- + +### 4.2 Eksekutører (`open-sse/executors/`) + +Eksekutører kapsler inn **leverandørspesifikk logikk** ved å bruke **strategimønsteret**. Hver eksekutør overstyrer basismetoder etter behov. + +```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 DefaultExecutor { + +refreshCredentials() + } + + class AntigravityExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +shouldRetry() + +refreshCredentials() + } + + class CursorExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseResponse() + +generateChecksum() + } + + class KiroExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseEventStream() + +refreshCredentials() + } + + BaseExecutor <|-- DefaultExecutor + BaseExecutor <|-- AntigravityExecutor + BaseExecutor <|-- CursorExecutor + BaseExecutor <|-- KiroExecutor + BaseExecutor <|-- CodexExecutor + BaseExecutor <|-- GeminiCLIExecutor + BaseExecutor <|-- GithubExecutor +``` + +| Utfører | Leverandør | Nøkkelspesialiseringer | +| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `base.ts` | — | Abstrakt base: URL-bygging, overskrifter, logikk på nytt, oppdatering av legitimasjon | +| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generisk OAuth-tokenoppdatering for standardleverandører | +| `antigravity.ts` | Google Cloud Code | Prosjekt-/sesjons-ID generering, multi-URL fallback, tilpasset gjenforsøk på parsing fra feilmeldinger ("tilbakestill etter 2t7m23s") | +| `cursor.ts` | Markør IDE | **Mest kompliserte**: SHA-256 kontrollsum-authorisont, Protobuf-forespørselskoding, binær EventStream → SSE-svarparsing | +| `codex.ts` | OpenAI Codex | Injiserer systeminstruksjoner, administrerer tenkenivåer, fjerner ustøttede parametere | +| `gemini-cli.ts` | Google Gemini CLI | Egendefinert URL-bygging (`streamGenerateContent`), Google OAuth-tokenoppdatering | +| `github.ts` | GitHub Copilot | Dobbelt token-system (GitHub OAuth + Copilot-token), VSCode-header-etterligning | +| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binær parsing, AMZN hendelsesrammer, token estimering | +| `index.ts` | — | Fabrikk: navn på kartleverandør → eksekveringsklasse, med standard reserve | + +--- + +### 4.3 Behandlere (`open-sse/handlers/`) + +**Orkestreringslaget** — koordinerer oversettelse, utførelse, strømming og feilhåndtering. + +| Fil | Formål | +| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `chatCore.ts` | **Sentralorkester** (~600 linjer). Håndterer hele forespørselens livssyklus: formatdeteksjon → oversettelse → eksekveringssending → streaming/ikke-streaming-svar → token-oppdatering → feilhåndtering → brukslogging. | +| `responsesHandler.ts` | Adapter for OpenAIs Responses API: konverterer svarformat → Chatfullføringer → sender til `chatCore` → konverterer SSE tilbake til svarformat. | +| `embeddings.ts` | Innebyggingsgenereringshåndterer: løser innbyggingsmodell → leverandør, sender til leverandør-API, returnerer OpenAI-kompatibel innbyggingssvar. Støtter 6+ leverandører. | +| `imageGeneration.ts` | Bildegenereringshåndterer: løser bildemodell → leverandør, støtter OpenAI-kompatibel, Gemini-image (Antigravity) og fallback (Nebius) moduser. Returnerer base64- eller URL-bilder. | + +#### Be om livssyklus (chatCore.ts) + +```mermaid +sequenceDiagram + participant Client + participant chatCore + participant Translator + participant Executor + participant Provider + + Client->>chatCore: Request (any format) + chatCore->>chatCore: Detect source format + chatCore->>chatCore: Check bypass patterns + chatCore->>chatCore: Resolve model & provider + chatCore->>Translator: Translate request (source → OpenAI → target) + chatCore->>Executor: Get executor for provider + Executor->>Executor: Build URL, headers, transform request + Executor->>Executor: Refresh credentials if needed + Executor->>Provider: HTTP fetch (streaming or non-streaming) + + alt Streaming + Provider-->>chatCore: SSE stream + chatCore->>chatCore: Pipe through SSE transform stream + Note over chatCore: Transform stream translates
each chunk: target → OpenAI → source + chatCore-->>Client: Translated SSE stream + else Non-streaming + Provider-->>chatCore: JSON response + chatCore->>Translator: Translate response + chatCore-->>Client: Translated JSON + end + + alt Error (401, 429, 500...) + chatCore->>Executor: Retry with credential refresh + chatCore->>chatCore: Account fallback logic + end +``` + +--- + +### 4.4 Tjenester (`open-sse/services/`) + +Forretningslogikk som støtter behandlerne og utførerne. + +| Fil | Formål | +| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `provider.ts` | **Formatgjenkjenning** (`detectFormat`): analyser forespørsler om kroppsstruktur for å identifisere Claude/OpenAI/Gemini/Antigravity/Responses-formater (inkluderer `max_tokens` heuristikk for Claude). Også: URL-bygging, header-bygging, normalisering av tenkekonfigurasjon. Støtter `openai-compatible-*` og `anthropic-compatible-*` dynamiske leverandører. | +| `model.ts` | Parsing av modellstreng (`claude/model-name` → `{provider: "claude", model: "model-name"}`), aliasoppløsning med kollisjonsdeteksjon, inngangssanering (avviser banegjennomgang/kontrolltegn) og modellinformasjonsoppløsning med støtte for asynkron alias-getter. | +| `accountFallback.ts` | Hastighetsgrensehåndtering: eksponentiell backoff (1s → 2s → 4s → maks 2min), kontonedkjølingsadministrasjon, feilklassifisering (hvilke feil utløser fallback kontra ikke). | +| `tokenRefresh.ts` | OAuth-tokenoppdatering for **alle leverandører**: Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Inkluderer under flyging løftededupliseringsbuffer og forsøk på nytt med eksponentiell backoff. | +| `combo.ts` | **Kombomodeller**: kjeder av reservemodeller. Hvis modell A mislykkes med en fallback-kvalifisert feil, prøv modell B, deretter C osv. Returnerer faktiske oppstrømsstatuskoder. | +| `usage.ts` | Henter kvote-/bruksdata fra leverandør-API-er (GitHub Copilot-kvoter, Antigravity-modellkvoter, Codex-hastighetsgrenser, Kiro-brukssammenbrudd, Claude-innstillinger). | +| `accountSelector.ts` | Smart kontovalg med scoringsalgoritme: vurderer prioritet, helsestatus, round-robin-posisjon og nedkjølingstilstand for å velge den optimale kontoen for hver forespørsel. | +| `contextManager.ts` | Be om kontekstlivssyklusadministrasjon: oppretter og sporer kontekstobjekter per forespørsel med metadata (forespørsels-ID, tidsstempler, leverandørinformasjon) for feilsøking og logging. | +| `ipFilter.ts` | IP-basert tilgangskontroll: støtter tillatelsesliste- og blokkeringsmodus. Validerer klient-IP mot konfigurerte regler før API-forespørsler behandles. | +| `sessionManager.ts` | Sesjonssporing med klientfingeravtrykk: sporer aktive økter ved å bruke hashed klientidentifikatorer, overvåker antall forespørsler og gir øktberegninger. | +| `signatureCache.ts` | Forespørselssignaturbasert dedupliseringsbuffer: forhindrer dupliserte forespørsler ved å bufre nylige forespørselssignaturer og returnere bufrede svar for identiske forespørsler innen et tidsvindu. | +| `systemPrompt.ts` | Global systemmeldingsinjeksjon: legger til eller legger til en konfigurerbar systemmelding til alle forespørsler, med kompatibilitetshåndtering per leverandør. | +| `thinkingBudget.ts` | Reasoning token budsjettadministrasjon: støtter passthrough, auto (strip thinking config), tilpasset (fast budsjett) og adaptive (kompleksitetsskalert) moduser for å kontrollere tenkning/resonnering tokens. | +| `wildcardRouter.ts` | Ruting av jokertegnmodellmønster: løser jokertegnmønstre (f.eks. `*/claude-*`) til konkrete leverandør/modellpar basert på tilgjengelighet og prioritet. | + +#### Token Refresh Deduplisering + +```mermaid +sequenceDiagram + participant R1 as Request 1 + participant R2 as Request 2 + participant Cache as refreshPromiseCache + participant OAuth as OAuth Provider + + R1->>Cache: getAccessToken("gemini", token) + Cache->>Cache: No in-flight promise + Cache->>OAuth: Start refresh + R2->>Cache: getAccessToken("gemini", token) + Cache->>Cache: Found in-flight promise + Cache-->>R2: Return existing promise + OAuth-->>Cache: New access token + Cache-->>R1: New access token + Cache-->>R2: Same access token (shared) + Cache->>Cache: Delete cache entry +``` + +#### Account Reserve State Machine + +```mermaid +stateDiagram-v2 + [*] --> Active + Active --> Error: Request fails (401/429/500) + Error --> Cooldown: Apply backoff + Cooldown --> Active: Cooldown expires + Active --> Active: Request succeeds (reset backoff) + + state Error { + [*] --> ClassifyError + ClassifyError --> ShouldFallback: Rate limit / Auth / Transient + ClassifyError --> NoFallback: 400 Bad Request + } + + state Cooldown { + [*] --> ExponentialBackoff + ExponentialBackoff: Level 0 = 1s + ExponentialBackoff: Level 1 = 2s + ExponentialBackoff: Level 2 = 4s + ExponentialBackoff: Max = 2min + } +``` + +#### Kombimodellkjede + +```mermaid +flowchart LR + A["Request with\ncombo model"] --> B["Model A"] + B -->|"2xx Success"| C["Return response"] + B -->|"429/401/500"| D{"Fallback\neligible?"} + D -->|Yes| E["Model B"] + D -->|No| F["Return error"] + E -->|"2xx Success"| C + E -->|"429/401/500"| G{"Fallback\neligible?"} + G -->|Yes| H["Model C"] + G -->|No| F + H -->|"2xx Success"| C + H -->|"Fail"| I["All failed →\nReturn last status"] +``` + +--- + +### 4.5 Oversetter (`open-sse/translator/`) + +**formatoversettelsesmotoren** bruker et selvregistrerende plugin-system. + +#### Arkitektur + +```mermaid +graph TD + subgraph "Request Translation" + A["Claude → OpenAI"] + B["Gemini → OpenAI"] + C["Antigravity → OpenAI"] + D["OpenAI Responses → OpenAI"] + E["OpenAI → Claude"] + F["OpenAI → Gemini"] + G["OpenAI → Kiro"] + H["OpenAI → Cursor"] + end + + subgraph "Response Translation" + I["Claude → OpenAI"] + J["Gemini → OpenAI"] + K["Kiro → OpenAI"] + L["Cursor → OpenAI"] + M["OpenAI → Claude"] + N["OpenAI → Antigravity"] + O["OpenAI → Responses"] + end +``` + +| Katalog | Filer | Beskrivelse | +| ------------ | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `request/` | 8 oversettere | Konverter forespørselstekster mellom formater. Hver fil registreres selv via `register(from, to, fn)` ved import. | +| `response/` | 7 oversettere | Konverter strømmeresponsbiter mellom formater. Håndterer SSE-hendelsestyper, tenkeblokker, verktøykall. | +| `helpers/` | 6 hjelpere | Delte verktøy: `claudeHelper` (uttrekking av systemprompt, tenkekonfigurasjon), `geminiHelper` (deler-/innholdskartlegging), `openaiHelper` (formatfiltrering), `toolCallHelper` (ID-generering, manglende responsinjeksjon), \_***OMNI***TO.\_\_2. | +| `index.ts` | — | Oversettelsesmotor: `translateRequest()`, `translateResponse()`, statlig ledelse, register. | +| `formats.ts` | — | Formatkonstanter: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | + +#### Nøkkeldesign: Selvregistrerende plugins + +```javascript +// Each translator file calls register() on import: +import { register } from "../index.js"; +register("claude", "openai", translateClaudeToOpenAI); + +// The index.js imports all translator files, triggering registration: +import "./request/claude-to-openai.js"; // ← self-registers +``` + +--- + +### 4.6 Utils (`open-sse/utils/`) + +| Fil | Formål | +| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `error.ts` | Bygging av feilrespons (OpenAI-kompatibelt format), oppstrøms feilparsing, Antigravity-utvinning på nytt fra feilmeldinger, SSE-feilstrømming. | +| `stream.ts` | **SSE Transform Stream** — kjernestrømmingsrørledningen. To moduser: `TRANSLATE` (fullformatoversettelse) og `PASSTHROUGH` (normalisere + ekstraksjonsbruk). Håndterer chunk-buffring, bruksestimat, sporing av innholdslengde. Per-stream koder/dekoderforekomster unngår delt tilstand. | +| `streamHelpers.ts` | SSE-verktøy på lavt nivå: `parseSSELine` (tomromtolerant), `hasValuableContent` (filtrerer tomme deler for OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (formatbevisst SSETOKEN*101*-opprydding med **1OMNI\_-opprydding med **1OMNI\_-opprydding). | +| `usageTracking.ts` | Uttrekk av tokenbruk fra ethvert format (Claude/OpenAI/Gemini/Responses), estimering med separate verktøy/melding-char-per-token-forhold, buffertillegg (sikkerhetsmargin for 2000 tokens), formatspesifikk feltfiltrering, konsolllogging med ANSI-farger. | +| `requestLogger.ts` | Filbasert forespørselslogging (opt-in via `ENABLE_REQUEST_LOGS=true`). Oppretter øktmapper med nummererte filer: `1_req_client.json` → `7_res_client.txt`. All I/O er asynkron (fire-and-forget). Maskerer sensitive overskrifter. | +| `bypassHandler.ts` | Avskjærer spesifikke mønstre fra Claude CLI (tittelutvinning, oppvarming, telling) og returnerer falske svar uten å ringe noen leverandør. Støtter både streaming og ikke-streaming. Med vilje begrenset til Claude CLI-omfang. | +| `networkProxy.ts` | Løser utgående proxy-URL for en gitt leverandør med prioritet: leverandørspesifikk konfig → global konfig → miljøvariabler (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Støtter `NO_PROXY` ekskluderinger. Cacher konfigurasjon for 30s. | + +#### SSE Streaming Pipeline + +```mermaid +flowchart TD + A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"] + B --> C["Buffer lines\n(split on newline)"] + C --> D["parseSSELine()\n(trim whitespace, parse JSON)"] + D --> E{"Mode?"} + E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"] + E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"] + F --> H["hasValuableContent()\nfilter empty chunks"] + G --> H + H -->|"Has content"| I["extractUsage()\ntrack token counts"] + H -->|"Empty"| J["Skip chunk"] + I --> K["formatSSE()\nserialize + clean perf_metrics"] + K --> L["TextEncoder\n(per-stream instance)"] + L --> M["Enqueue to\nclient stream"] + + style A fill:#f9f,stroke:#333 + style M fill:#9f9,stroke:#333 +``` + +#### Request Logger Session Struktur + +``` +logs/ +└── claude_gemini_claude-sonnet_20260208_143045/ + ├── 1_req_client.json ← Raw client request + ├── 2_req_source.json ← After initial conversion + ├── 3_req_openai.json ← OpenAI intermediate format + ├── 4_req_target.json ← Final target format + ├── 5_res_provider.txt ← Provider SSE chunks (streaming) + ├── 5_res_provider.json ← Provider response (non-streaming) + ├── 6_res_openai.txt ← OpenAI intermediate chunks + ├── 7_res_client.txt ← Client-facing SSE chunks + └── 6_error.json ← Error details (if any) +``` + +--- + +### 4.7 applikasjonslag (`src/`) + +| Katalog | Formål | +| ------------- | ------------------------------------------------------------------------- | +| `src/app/` | Web-UI, API-ruter, Express-mellomvare, OAuth-tilbakeringsbehandlere | +| `src/lib/` | Databasetilgang (`localDb.ts`, `usageDb.ts`), autentisering, delt | +| `src/mitm/` | Man-in-the-midten proxy-verktøy for å avskjære leverandørtrafikk | +| `src/models/` | Databasemodelldefinisjoner | +| `src/shared/` | Omslag rundt åpne-sse-funksjoner (leverandør, strøm, feil osv.) | +| `src/sse/` | SSE-endepunktbehandlere som kobler open-sse-biblioteket til Express-ruter | +| `src/store/` | Søknadstilstandsadministrasjon | + +#### Bemerkelsesverdige API-ruter + +| Rute | Metoder | Formål | +| --------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------- | +| `/api/provider-models` | GET/POST/SLETT | CRUD for tilpassede modeller per leverandør | +| `/api/models/catalog` | FÅ | Samlet katalog over alle modeller (chat, innebygging, bilde, tilpasset) gruppert etter leverandør | +| `/api/settings/proxy` | GET/SETT/SLETT | Hierarkisk utgående proxy-konfigurasjon (`global/providers/combos/keys`) | +| `/api/settings/proxy/test` | INNLEGG | Validerer proxy-tilkobling og returnerer offentlig IP/latency | +| `/v1/providers/[provider]/chat/completions` | INNLEGG | Dedikerte chatfullføringer per leverandør med modellvalidering | +| `/v1/providers/[provider]/embeddings` | INNLEGG | Dedikerte innbygginger per leverandør med modellvalidering | +| `/v1/providers/[provider]/images/generations` | INNLEGG | Dedikert bildegenerering per leverandør med modellvalidering | +| `/api/settings/ip-filter` | GET/SETT | IP-godkjenningsliste/blokkeringslisteadministrasjon | +| `/api/settings/thinking-budget` | GET/SETT | Begrunnelse token budsjettkonfigurasjon (passthrough/auto/custom/adaptive) | +| `/api/settings/system-prompt` | GET/SETT | Global systemprompt injeksjon for alle forespørsler | +| `/api/sessions` | FÅ | Aktiv øktsporing og beregninger | +| `/api/rate-limits` | FÅ | Satsgrensestatus per konto | + +--- + +## 5. Nøkkeldesignmønstre + +### 5.1 Hub-and-Speake-oversettelse + +Alle formater oversettes gjennom **OpenAI-formatet som navet**. Å legge til en ny leverandør krever bare å skrive **ett par** med oversettere (til/fra OpenAI), ikke N par. + +### 5.2 Eksekutørstrategimønster + +Hver leverandør har en dedikert eksekutørklasse som arver fra `BaseExecutor`. Fabrikken i `executors/index.ts` velger den riktige ved kjøring. + +### 5.3 Selvregistrerende pluginsystem + +Oversettermoduler registrerer seg ved import via `register()`. Å legge til en ny oversetter er bare å lage en fil og importere den. + +### 5.4 Kontotilbakeslag med eksponentiell backoff + +Når en leverandør returnerer 429/401/500, kan systemet bytte til neste konto ved å bruke eksponentielle nedkjølinger (1s → 2s → 4s → maks 2min). + +### 5.5 Combo modellkjeder + +En "combo" grupperer flere `provider/model` strenger. Hvis den første mislykkes, fall tilbake til den neste automatisk. + +### 5.6 Stateful streaming-oversettelse + +Responsoversettelse opprettholder tilstanden på tvers av SSE-biter (tenkeblokksporing, akkumulering av verktøykall, indeksering av innholdsblokker) via `initState()`-mekanismen. + +### 5.7 Brukssikkerhetsbuffer + +En buffer på 2000 tokener legges til rapportert bruk for å hindre klienter i å nå grensene for kontekstvindu på grunn av overhead fra systemforespørsler og formatoversettelse. + +--- + +## 6. Støttede formater + +| Format | Retning | Identifikator | +| ------------------------ | ----------- | ------------------ | +| OpenAI Chat-fullføringer | kilde + mål | `openai` | +| OpenAI Responses API | kilde + mål | `openai-responses` | +| Antropiske Claude | kilde + mål | `claude` | +| Google Gemini | kilde + mål | `gemini` | +| Google Gemini CLI | kun mål | `gemini-cli` | +| Antigravitasjon | kilde + mål | `antigravity` | +| AWS Kiro | kun mål | `kiro` | +| Markør | kun mål | `cursor` | + +--- + +## 7. Støttede leverandører + +| Leverandør | Auth metode | Utfører | Nøkkelnotater | +| ------------------------ | ------------------------- | --------------- | ---------------------------------------------------------------------------- | +| Antropiske Claude | API-nøkkel eller OAuth | Standard | Bruker `x-api-key` header | +| Google Gemini | API-nøkkel eller OAuth | Standard | Bruker `x-goog-api-key` header | +| Google Gemini CLI | OAuth | GeminiCLI | Bruker `streamGenerateContent` endepunkt | +| Antigravitasjon | OAuth | Antigravitasjon | Tilbakestilling av flere nettadresser, egendefinert prøv å analysere på nytt | +| OpenAI | API-nøkkel | Standard | Standard bærer auth | +| Codex | OAuth | Codex | Injiserer systeminstruksjoner, styrer tenkning | +| GitHub Copilot | OAuth + Copilot-token | Github | Dobbelt token, VSCode header-etterligning | +| Kiro (AWS) | AWS SSO OIDC eller Social | Kiro | Binær EventStream-parsing | +| Markør IDE | Sjekksum auth | Markør | Protobuf-koding, SHA-256 kontrollsummer | +| Qwen | OAuth | Standard | Standard auth | +| iFlow | OAuth (Basic + Bearer) | Standard | Dobbel autentiseringshode | +| OpenRouter | API-nøkkel | Standard | Standard bærer auth | +| GLM, Kimi, MiniMax | API-nøkkel | Standard | Claude-kompatibel, bruk `x-api-key` | +| `openai-compatible-*` | API-nøkkel | Standard | Dynamisk: ethvert OpenAI-kompatibelt endepunkt | +| `anthropic-compatible-*` | API-nøkkel | Standard | Dynamisk: ethvert Claude-kompatibelt endepunkt | + +--- + +## 8. Dataflytsammendrag + +### Strømmeforespørsel + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor\nbuildUrl + buildHeaders"] + D --> E["fetch(providerURL)"] + E --> F["createSSEStream()\nTRANSLATE mode"] + F --> G["parseSSELine()"] + G --> H["translateResponse()\ntarget → OpenAI → source"] + H --> I["extractUsage()\n+ addBuffer"] + I --> J["formatSSE()"] + J --> K["Client receives\ntranslated SSE"] + K --> L["logUsage()\nsaveRequestUsage()"] +``` + +### Ikke-streamende forespørsel + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor.execute()"] + D --> E["translateResponse()\ntarget → OpenAI → source"] + E --> F["Return JSON\nresponse"] +``` + +### Bypass Flow (Claude CLI) + +```mermaid +flowchart LR + A["Claude CLI request"] --> B{"Match bypass\npattern?"} + B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"] + B -->|"No match"| D["Normal flow"] + C --> E["Translate to\nsource format"] + E --> F["Return without\ncalling provider"] +``` diff --git a/docs/i18n/no/FEATURES.md b/docs/i18n/no/FEATURES.md new file mode 100644 index 0000000000..0b57b35fef --- /dev/null +++ b/docs/i18n/no/FEATURES.md @@ -0,0 +1,77 @@ +# OmniRoute — Dashboard-funksjonsgalleri + +🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md) + +Visuell veiledning til hver del av OmniRoute-dashbordet. + +--- + +## 🔌 Leverandører + +Administrer AI-leverandørtilkoblinger: OAuth-leverandører (Claude Code, Codex, Gemini CLI), API-nøkkelleverandører (Groq, DeepSeek, OpenRouter) og gratisleverandører (iFlow, Qwen, Kiro). + +![Providers Dashboard](screenshots/01-providers.png) + +--- + +## 🎨 Kombinasjoner + +Lag modellrutingskombinasjoner med 6 strategier: fyll-først, round-robin, kraft-av-to-valg, tilfeldig, minst brukt og kostnadsoptimalisert. Hver kombinasjon kjeder flere modeller med automatisk fallback. + +![Combos Dashboard](screenshots/02-combos.png) + +--- + +## 📊 Analytics + +Omfattende bruksanalyse med symbolforbruk, kostnadsestimater, aktivitetsvarmekart, ukentlige distribusjonsdiagrammer og sammenbrudd per leverandør. + +![Analytics Dashboard](screenshots/03-analytics.png) + +--- + +## 🏥 Systemhelse + +Sanntidsovervåking: oppetid, minne, versjon, latenspersentiler (p50/p95/p99), hurtigbufferstatistikk og leverandørens strømbrytertilstander. + +![Health Dashboard](screenshots/04-health.png) + +--- + +## 🔧 Oversetter Lekeplass + +Fire moduser for feilsøking av API-oversettelser: **Lekeplass** (formatkonvertering), **Chattester** (liveforespørsler), **Testbenk** (batch-tester) og **Live Monitor** (sanntidsstrøm). + +![Translator Playground](screenshots/05-translator.png) + +--- + +## ⚙️ Innstillinger + +Generelle innstillinger, systemlagring, administrasjon av sikkerhetskopiering (eksport-/importdatabase), utseende (mørk/lysmodus), sikkerhet (inkluderer API-endepunktsbeskyttelse og blokkering av tilpasset leverandør), ruting, robusthet og avansert konfigurasjon. + +![Settings Dashboard](screenshots/06-settings.png) + +--- + +## 🔧 CLI-verktøy + +Ett-klikks konfigurasjon for AI-kodeverktøy: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code og Antigravity. + +![CLI Tools Dashboard](screenshots/07-cli-tools.png) + +--- + +## 📝 Forespørselslogger + +Forespørselslogging i sanntid med filtrering etter leverandør, modell, konto og API-nøkkel. Viser statuskoder, tokenbruk, ventetid og svardetaljer. + +![Usage Logs](screenshots/08-usage.png) + +--- + +## 🌐 API-endepunkt + +Ditt enhetlige API-endepunkt med funksjonsoversikt: Chatfullføringer, innebygginger, bildegenerering, omrangering, lydtranskripsjon og registrerte API-nøkler. + +![Endpoint Dashboard](screenshots/09-endpoint.png) diff --git a/docs/i18n/no/TROUBLESHOOTING.md b/docs/i18n/no/TROUBLESHOOTING.md new file mode 100644 index 0000000000..5d8b7f161b --- /dev/null +++ b/docs/i18n/no/TROUBLESHOOTING.md @@ -0,0 +1,219 @@ +# Feilsøking + +🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md) + +Vanlige problemer og løsninger for OmniRoute. + +--- + +## Hurtigrettinger + +| Problem | Løsning | +| -------------------------------------- | -------------------------------------------------------------------- | +| Første pålogging fungerer ikke | Sjekk `INITIAL_PASSWORD` i `.env` (standard: `123456`) | +| Dashboard åpnes på feil port | Sett `PORT=20128` og `NEXT_PUBLIC_BASE_URL=http://localhost:20128` | +| Ingen forespørselslogger under `logs/` | Sett `ENABLE_REQUEST_LOGS=true` | +| EACCES: tillatelse nektet | Sett `DATA_DIR=/path/to/writable/dir` til å overstyre `~/.omniroute` | +| Rutingstrategi lagrer ikke | Oppdater til v1.4.11+ (Zod-skjemafiks for varighet av innstillinger) | + +--- + +## Leverandørproblemer + +### "Språkmodellen ga ikke meldinger" + +**Årsak:** Leverandørkvoten er oppbrukt. + +**Fiks:** + +1. Sjekk dashbordkvotesporing +2. Bruk en kombinasjon med reservelag +3. Bytt til billigere/gratis lag + +### Satsbegrensning + +**Årsak:** Abonnementskvoten er oppbrukt. + +**Fiks:** + +- Legg til reserve: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` +- Bruk GLM/MiniMax som billig backup + +### OAuth-token utløpt + +OmniRoute oppdaterer tokens automatisk. Hvis problemene vedvarer: + +1. Dashboard → Leverandør → Koble til på nytt +2. Slett og legg til leverandørtilkoblingen på nytt + +--- + +## Skyproblemer + +### Skysynkroniseringsfeil + +1. Bekreft `BASE_URL` poeng til løpeforekomsten din (f.eks. `http://localhost:20128`) +2. Bekreft `CLOUD_URL` poeng til skyendepunktet ditt (f.eks. `https://omniroute.dev`) +3. Hold `NEXT_PUBLIC_*` verdier på linje med verdiene på tjenersiden + +### Cloud `stream=false` Returnerer 500 + +**Symptom:** `Unexpected token 'd'...` på nettskyendepunkt for samtaler som ikke strømmer. + +**Årsak:** Oppstrøms returnerer SSE-nyttelast mens klienten forventer JSON. + +**Løsning:** Bruk `stream=true` for direkte sky-anrop. Lokal kjøretid inkluderer SSE→JSON reserve. + +### Cloud sier tilkoblet, men "Ugyldig API-nøkkel" + +1. Lag en ny nøkkel fra lokalt dashbord (`/api/keys`) +2. Kjør skysynkronisering: Aktiver Cloud → Synkroniser nå +3. Gamle/ikke-synkroniserte nøkler kan fortsatt returnere `401` på skyen + +--- + +## Docker-problemer + +### CLI-verktøyet viser ikke installert + +1. Sjekk kjøretidsfelt: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq` +2. For bærbar modus: bruk bildemål `runner-cli` (medfølgende CLI-er) +3. For vertsmonteringsmodus: sett `CLI_EXTRA_PATHS` og monter vertsbokskatalogen som skrivebeskyttet +4. Hvis `installed=true` og `runnable=false`: binær ble funnet, men mislyktes i helsesjekken + +### Rask kjøretidsvalidering + +```bash +curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +``` + +--- + +## Kostnadsproblemer + +### Høye kostnader + +1. Sjekk bruksstatistikk i Dashboard → Bruk +2. Bytt primærmodell til GLM/MiniMax +3. Bruk gratis nivå (Gemini CLI, iFlow) for ikke-kritiske oppgaver +4. Angi kostnadsbudsjetter per API-nøkkel: Dashboard → API-nøkler → Budsjett + +--- + +## Feilsøking + +### Aktiver forespørselslogger + +Sett `ENABLE_REQUEST_LOGS=true` i filen `.env`. Logger vises under katalogen `logs/`. + +### Sjekk leverandørens helse + +```bash +# Health dashboard +http://localhost:20128/dashboard/health + +# API health check +curl http://localhost:20128/api/monitoring/health +``` + +### Runtime Storage + +- Hovedtilstand: `${DATA_DIR}/db.json` (leverandører, kombinasjoner, aliaser, nøkler, innstillinger) +- Bruk: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- Forespørselslogger: `/logs/...` (når `ENABLE_REQUEST_LOGS=true`) + +--- + +## Strømbryterproblemer + +### Leverandøren sitter fast i ÅPEN tilstand + +Når en leverandørs strømbryter er ÅPEN, blokkeres forespørsler til nedkjølingen utløper. + +**Fiks:** + +1. Gå til **Dashboard → Innstillinger → Resiliens** +2. Sjekk kretsbryterkortet for den berørte leverandøren +3. Klikk på **Tilbakestill alle** for å fjerne alle brytere, eller vent til nedkjølingen utløper +4. Bekreft at leverandøren faktisk er tilgjengelig før du tilbakestiller + +### Leverandøren fortsetter å utløse strømbryteren + +Hvis en leverandør gjentatte ganger går inn i ÅPEN tilstand: + +1. Sjekk **Dashboard → Helse → Leverandørhelse** for feilmønsteret +2. Gå til **Innstillinger → Resiliens → Leverandørprofiler** og øk feilterskelen +3. Sjekk om leverandøren har endret API-grenser eller krever re-autentisering +4. Se gjennom latenstidstelemetri – høy latenstid kan forårsake timeout-baserte feil + +--- + +## Problemer med lydtranskripsjon + +### "Ustøttet modell"-feil + +- Sørg for at du bruker riktig prefiks: `deepgram/nova-3` eller `assemblyai/best` +- Bekreft at leverandøren er tilkoblet i **Dashboard → Leverandører** + +### Transkripsjon returnerer tom eller mislykkes + +- Sjekk støttede lydformater: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm` +- Bekreft at filstørrelsen er innenfor leverandørens grenser (vanligvis < 25 MB) +- Sjekk gyldigheten av leverandørens API-nøkkel i leverandørkortet + +--- + +## Oversetter feilsøking + +Bruk **Dashboard → Oversetter** for å feilsøke problemer med formatoversettelse: + +| Modus | Når skal du bruke | +| ---------------- | ----------------------------------------------------------------------------------------------------------------- | +| **Lekeplass** | Sammenlign input/output formater side ved side — lim inn en mislykket forespørsel for å se hvordan den oversettes | +| **Chattetester** | Send direktemeldinger og inspiser hele nyttelasten for forespørsel/svar inkludert overskrifter | +| **Testbenk** | Kjør batch-tester på tvers av formatkombinasjoner for å finne hvilke oversettelser som er ødelagte | +| **Live Monitor** | Se forespørselsflyt i sanntid for å fange opp periodiske oversettelsesproblemer | + +### Vanlige formatproblemer + +- **Tenkekoder vises ikke** — Sjekk om målleverandøren støtter tenkning og innstillingen av tenkebudsjettet +- **Verktøyanrop dropper** — Noen formatoversettelser kan fjerne felt som ikke støttes; verifisere i Playground-modus +- **Systemmelding mangler** — Claude og Gemini håndterer systemmeldinger annerledes; sjekk oversettelsen +- **SDK returnerer rå streng i stedet for objekt** — Rettet i v1.1.0: svarrenser fjerner nå ikke-standard felt (`x_groq`, `usage_breakdown`, etc.) som forårsaker OpenAI SDK Pydantic valideringsfeil +- **GLM/ERNIE avviser rollen `system`** — Rettet i v1.1.0: rollenormalisering slår automatisk sammen systemmeldinger til brukermeldinger for inkompatible modeller +- **`developer` rolle ikke gjenkjent** — Rettet i v1.1.0: automatisk konvertert til `system` for ikke-OpenAI-leverandører +- **`json_schema` fungerer ikke med Gemini** — Rettet i v1.1.0: `response_format` er nå konvertert til Geminis `responseMimeType` + `responseSchema` + +--- + +## Resiliensinnstillinger + +### Auto rate-limit utløses ikke + +- Automatisk takstgrense gjelder bare API-nøkkelleverandører (ikke OAuth/abonnement) +- Bekreft at **Innstillinger → Resiliens → Leverandørprofiler** har aktivert automatisk satsgrense +- Sjekk om leverandøren returnerer `429` statuskoder eller `Retry-After` overskrifter + +### Tuning eksponentiell backoff + +Leverandørprofiler støtter disse innstillingene: + +- **Basisforsinkelse** — Innledende ventetid etter første feil (standard: 1 s) +- **Maks. forsinkelse** — Maksimal ventetid (standard: 30s) +- **Multiplikator** — Hvor mye skal forsinkelsen økes per påfølgende feil (standard: 2x) + +### Anti-tordenflokk + +Når mange samtidige forespørsler treffer en hastighetsbegrenset leverandør, bruker OmniRoute mutex + automatisk hastighetsbegrensning for å serialisere forespørsler og forhindre kaskadefeil. Dette er automatisk for API-nøkkelleverandører. + +--- + +## Fortsatt fast? + +- **GitHub-problemer**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) +- **Arkitektur**: Se [**OMNI_TOKEN_55**](ARCHITECTURE.md) for interne detaljer +- **API-referanse**: Se [**OMNI_TOKEN_56**](API_REFERENCE.md) for alle endepunkter +- **Helse Dashboard**: Sjekk **Dashboard → Health** for sanntids systemstatus +- **Oversetter**: Bruk **Dashboard → Oversetter** for å feilsøke formatproblemer diff --git a/docs/i18n/no/USER_GUIDE.md b/docs/i18n/no/USER_GUIDE.md new file mode 100644 index 0000000000..19775dc668 --- /dev/null +++ b/docs/i18n/no/USER_GUIDE.md @@ -0,0 +1,698 @@ +# Brukerveiledning + +🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md) + +Komplett veiledning for å konfigurere leverandører, lage kombinasjoner, integrere CLI-verktøy og distribuere OmniRoute. + +--- + +## Innholdsfortegnelse + +- [Pricing at a Glance](#-pricing-at-a-glance) +- [Use Cases](#-use-cases) +- [Provider Setup](#-provider-setup) +- [CLI Integration](#-cli-integration) +- [Deployment](#-deployment) +- [Available Models](#-available-models) +- [Advanced Features](#-advanced-features) + +--- + +## 💰 Priser på et øyeblikk + +| Nivå | Leverandør | Kostnad | Kvote Tilbakestill | Best for | +| ----------------- | ----------------- | --------------- | ----------------------- | ------------------------ | +| **💳 ABONNEMENT** | Claude Code (Pro) | $20/md | 5t + ukentlig | Allerede abonnert | +| | Codex (Pluss/Pro) | $20-200/md | 5t + ukentlig | OpenAI-brukere | +| | Gemini CLI | **GRATIS** | 180K/mnd + 1K/dag | Alle sammen! | +| | GitHub Copilot | $10-19/md | Månedlig | GitHub-brukere | +| **🔑 API NØKKEL** | DeepSeek | Betal per bruk | Ingen | Billig resonnement | +| | Groq | Betal per bruk | Ingen | Ultrarask slutning | +| | xAI (Grok) | Betal per bruk | Ingen | Grok 4 resonnement | +| | Mistral | Betal per bruk | Ingen | EU-vertsbaserte modeller | +| | Forvirring | Betal per bruk | Ingen | Søkeutvidet | +| | Sammen AI | Betal per bruk | Ingen | Åpen kildekode-modeller | +| | Fyrverkeri AI | Betal per bruk | Ingen | Rask FLUX bilder | +| | Cerebras | Betal per bruk | Ingen | Wafer-skala hastighet | +| | Sammenheng | Betal per bruk | Ingen | Kommando R+ RAG | +| | NVIDIA NIM | Betal per bruk | Ingen | Bedriftsmodeller | +| **💰 BILLIG** | GLM-4.7 | $0,6/1M | Daglig 10:00 | Budsjett backup | +| | MiniMax M2.1 | $0,2/1 million | 5-timers rullende | Billigste alternativ | +| | Kimi K2 | $9/md leilighet | 10 millioner tokens/mnd | Forutsigbar kostnad | +| **🆓 GRATIS** | iFlow | $0 | Ubegrenset | 8 modeller gratis | +| | Qwen | $0 | Ubegrenset | 3 modeller gratis | +| | Kiro | $0 | Ubegrenset | Claude gratis | + +**💡 Profftips:** Start med Gemini CLI (180K gratis/måned) + iFlow (ubegrenset gratis) kombinasjon = $0 kostnad! + +--- + +## 🎯 Brukssaker + +### Sak 1: "Jeg har Claude Pro-abonnement" + +**Problem:** Kvoten utløper ubrukt, satsgrenser under tung koding + +``` +Combo: "maximize-claude" + 1. cc/claude-opus-4-6 (use subscription fully) + 2. glm/glm-4.7 (cheap backup when quota out) + 3. if/kimi-k2-thinking (free emergency fallback) + +Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total +vs. $20 + hitting limits = frustration +``` + +### Tilfelle 2: "Jeg vil ha null kostnad" + +**Problem:** Har ikke råd til abonnementer, trenger pålitelig AI-koding + +``` +Combo: "free-forever" + 1. gc/gemini-3-flash (180K free/month) + 2. if/kimi-k2-thinking (unlimited free) + 3. qw/qwen3-coder-plus (unlimited free) + +Monthly cost: $0 +Quality: Production-ready models +``` + +### Tilfelle 3: "Jeg trenger 24/7 koding, ingen avbrudd" + +**Problem:** Tidsfrister, har ikke råd til nedetid + +``` +Combo: "always-on" + 1. cc/claude-opus-4-6 (best quality) + 2. cx/gpt-5.2-codex (second subscription) + 3. glm/glm-4.7 (cheap, resets daily) + 4. minimax/MiniMax-M2.1 (cheapest, 5h reset) + 5. if/kimi-k2-thinking (free unlimited) + +Result: 5 layers of fallback = zero downtime +Monthly cost: $20-200 (subscriptions) + $10-20 (backup) +``` + +### Tilfelle 4: "Jeg vil ha GRATIS AI i OpenClaw" + +**Problem:** Trenger AI-assistent i meldingsapper, helt gratis + +``` +Combo: "openclaw-free" + 1. if/glm-4.7 (unlimited free) + 2. if/minimax-m2.1 (unlimited free) + 3. if/kimi-k2-thinking (unlimited free) + +Monthly cost: $0 +Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal... +``` + +--- + +## 📖 Leverandøroppsett + +### 🔐 Abonnementsleverandører + +#### Claude Code (Pro/Max) + +```bash +Dashboard → Providers → Connect Claude Code +→ OAuth login → Auto token refresh +→ 5-hour + weekly quota tracking + +Models: + cc/claude-opus-4-6 + cc/claude-sonnet-4-5-20250929 + cc/claude-haiku-4-5-20251001 +``` + +**Profftips:** Bruk Opus for komplekse oppgaver, Sonnet for hastighet. OmniRoute sporer kvote per modell! + +#### OpenAI Codex (Plus/Pro) + +```bash +Dashboard → Providers → Connect Codex +→ OAuth login (port 1455) +→ 5-hour + weekly reset + +Models: + cx/gpt-5.2-codex + cx/gpt-5.1-codex-max +``` + +#### Gemini CLI (GRATIS 180K/måned!) + +```bash +Dashboard → Providers → Connect Gemini CLI +→ Google OAuth +→ 180K completions/month + 1K/day + +Models: + gc/gemini-3-flash-preview + gc/gemini-2.5-pro +``` + +**Mest verdi:** Enormt gratis nivå! Bruk dette før betalte nivåer. + +#### GitHub Copilot + +```bash +Dashboard → Providers → Connect GitHub +→ OAuth via GitHub +→ Monthly reset (1st of month) + +Models: + gh/gpt-5 + gh/claude-4.5-sonnet + gh/gemini-3-pro +``` + +### 💰 Billige leverandører + +#### GLM-4.7 (Daglig tilbakestilling, $0,6/1M) + +1. Registrer deg: [Zhipu AI](https://open.bigmodel.cn/) +2. Få API-nøkkel fra Coding Plan +3. Dashboard → Legg til API-nøkkel: Leverandør: `glm`, API-nøkkel: `your-key` + +**Bruk:** `glm/glm-4.7` — **Profftips:** Kodeplan tilbyr 3× kvote til 1/7 kostnad! Tilbakestill daglig 10:00. + +#### MiniMax M2.1 (5t tilbakestilling, $0,20/1M) + +1. Registrer deg: [MiniMax](https://www.minimax.io/) +2. Hent API-nøkkel → Dashboard → Legg til API-nøkkel + +**Bruk:** `minimax/MiniMax-M2.1` — **Profftips:** Billigste alternativet for lang kontekst (1M tokens)! + +#### Kimi K2 ($9/mnd leilighet) + +1. Abonner: [Moonshot AI](https://platform.moonshot.ai/) +2. Hent API-nøkkel → Dashboard → Legg til API-nøkkel + +**Bruk:** `kimi/kimi-latest` — **Profftips:** Fast $9/måned for 10M tokens = $0,90/1M effektiv kostnad! + +### 🆓 GRATIS Leverandører + +#### iFlow (8 GRATIS modeller) + +```bash +Dashboard → Connect iFlow → OAuth login → Unlimited usage + +Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1 +``` + +#### Qwen (3 GRATIS modeller) + +```bash +Dashboard → Connect Qwen → Device code auth → Unlimited usage + +Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash +``` + +#### Kiro (Claude GRATIS) + +```bash +Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited + +Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5 +``` + +--- + +## 🎨 Kombinasjoner + +### Eksempel 1: Maksimer abonnement → Billig sikkerhetskopi + +``` +Dashboard → Combos → Create New + +Name: premium-coding +Models: + 1. cc/claude-opus-4-6 (Subscription primary) + 2. glm/glm-4.7 (Cheap backup, $0.6/1M) + 3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M) + +Use in CLI: premium-coding +``` + +### Eksempel 2: Kun gratis (nullkostnad) + +``` +Name: free-combo +Models: + 1. gc/gemini-3-flash-preview (180K free/month) + 2. if/kimi-k2-thinking (unlimited) + 3. qw/qwen3-coder-plus (unlimited) + +Cost: $0 forever! +``` + +--- + +## 🔧 CLI-integrasjon + +### Markør IDE + +``` +Settings → Models → Advanced: + OpenAI API Base URL: http://localhost:20128/v1 + OpenAI API Key: [from omniroute dashboard] + Model: cc/claude-opus-4-6 +``` + +### Claude Code + +Rediger `~/.claude/config.json`: + +```json +{ + "anthropic_api_base": "http://localhost:20128/v1", + "anthropic_api_key": "your-omniroute-api-key" +} +``` + +### Codex CLI + +```bash +export OPENAI_BASE_URL="http://localhost:20128" +export OPENAI_API_KEY="your-omniroute-api-key" +codex "your prompt" +``` + +### OpenClaw + +Rediger `~/.openclaw/openclaw.json`: + +```json +{ + "agents": { + "defaults": { + "model": { "primary": "omniroute/if/glm-4.7" } + } + }, + "models": { + "providers": { + "omniroute": { + "baseUrl": "http://localhost:20128/v1", + "apiKey": "your-omniroute-api-key", + "api": "openai-completions", + "models": [{ "id": "if/glm-4.7", "name": "glm-4.7" }] + } + } + } +} +``` + +**Eller bruk Dashboard:** CLI Tools → OpenClaw → Auto-config + +### Cline / Fortsett / RooCode + +``` +Provider: OpenAI Compatible +Base URL: http://localhost:20128/v1 +API Key: [from dashboard] +Model: cc/claude-opus-4-6 +``` + +--- + +## 🚀 Utrulling + +### VPS-distribusjon + +```bash +git clone https://github.com/diegosouzapw/OmniRoute.git +cd OmniRoute && npm install && npm run build + +export JWT_SECRET="your-secure-secret-change-this" +export INITIAL_PASSWORD="your-password" +export DATA_DIR="/var/lib/omniroute" +export PORT="20128" +export HOSTNAME="0.0.0.0" +export NODE_ENV="production" +export NEXT_PUBLIC_BASE_URL="http://localhost:20128" +export API_KEY_SECRET="endpoint-proxy-api-key-secret" + +npm run start +# Or: pm2 start npm --name omniroute -- start +``` + +### Docker + +```bash +# Build image (default = runner-cli with codex/claude/droid preinstalled) +docker build -t omniroute:cli . + +# Portable mode (recommended) +docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli +``` + +For vertsintegrert modus med CLI-binærfiler, se Docker-delen i hoveddokumentene. + +### Miljøvariabler + +| Variabel | Standard | Beskrivelse | +| --------------------- | ------------------------------------ | ---------------------------------------------------------------- | +| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signeringshemmelighet (**endring i produksjon**) | +| `INITIAL_PASSWORD` | `123456` | Første påloggingspassord | +| `DATA_DIR` | `~/.omniroute` | Datakatalog (db, bruk, logger) | +| `PORT` | standard rammeverk | Tjenesteport (`20128` i eksempler) | +| `HOSTNAME` | standard rammeverk | Bind vert (Docker er standard til `0.0.0.0`) | +| `NODE_ENV` | kjøretidsstandard | Sett `production` for distribusjon | +| `BASE_URL` | `http://localhost:20128` | Intern basis-URL på tjenersiden | +| `CLOUD_URL` | `https://omniroute.dev` | Nettadresse for endepunkt for nettskysynkronisering | +| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC-hemmelighet for genererte API-nøkler | +| `REQUIRE_API_KEY` | `false` | Håndhev Bearer API-nøkkel på `/v1/*` | +| `ENABLE_REQUEST_LOGS` | `false` | Aktiverer forespørsels-/svarlogger | +| `AUTH_COOKIE_SECURE` | `false` | Tving `Secure` auth-informasjonskapsel (bak HTTPS omvendt proxy) | + +For hele miljøvariabelreferansen, se [README](../README.md). + +--- + +## 📊 Tilgjengelige modeller + +
+Se alle tilgjengelige modeller + +**Claude-kode (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001` + +**Kodeks (`cx/`)** — Pluss/Proff: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max` + +**Gemini CLI (`gc/`)** — GRATIS: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro` + +**GitHub Copilot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet` + +**GLM (`glm/`)** — $0,6/1M: `glm/glm-4.7` + +**MiniMax (`minimax/`)** — $0,2/1M: `minimax/MiniMax-M2.1` + +**iFlow (`if/`)** — GRATIS: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1` + +**Qwen (`qw/`)** — GRATIS: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash` + +**Kiro (`kr/`)** — GRATIS: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5` + +**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner` + +**Groq (`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct` + +**xAI (`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini` + +**Mistral (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501` + +**Forvirring (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar` + +**Together AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo` + +**Fireworks AI (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1` + +**Cerebras (`cerebras/`)**: `cerebras/llama-3.3-70b` + +**Kohere (`cohere/`)**: `cohere/command-r-plus-08-2024` + +**NVIDIA NIM (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct` + +
+ +--- + +## 🧩 Avanserte funksjoner + +### Egendefinerte modeller + +Legg til hvilken som helst modell-ID til en hvilken som helst leverandør uten å vente på en appoppdatering: + +```bash +# Via API +curl -X POST http://localhost:20128/api/provider-models \ + -H "Content-Type: application/json" \ + -d '{"provider": "openai", "modelId": "gpt-4.5-preview", "modelName": "GPT-4.5 Preview"}' + +# List: curl http://localhost:20128/api/provider-models?provider=openai +# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview" +``` + +Eller bruk Dashboard: **Leverandører → [Leverandør] → Egendefinerte modeller**. + +### Dedikerte leverandørruter + +Rute forespørsler direkte til en spesifikk leverandør med modellvalidering: + +```bash +POST http://localhost:20128/v1/providers/openai/chat/completions +POST http://localhost:20128/v1/providers/openai/embeddings +POST http://localhost:20128/v1/providers/fireworks/images/generations +``` + +Leverandørprefikset blir automatisk lagt til hvis det mangler. Umatchede modeller returnerer `400`. + +### Network Proxy Configuration + +```bash +# Set global proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"global": {"type":"http","host":"proxy.example.com","port":"8080"}}' + +# Per-provider proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"providers": {"openai": {"type":"socks5","host":"proxy.example.com","port":"1080"}}}' + +# Test proxy +curl -X POST http://localhost:20128/api/settings/proxy/test \ + -d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}' +``` + +**Forrang:** Nøkkelspesifikk → Kombinasjonsspesifikk → Leverandørspesifikk → Global → Miljø. + +### Model Catalog API + +```bash +curl http://localhost:20128/api/models/catalog +``` + +Returnerer modeller gruppert etter leverandør med typer (`chat`, `embedding`, `image`). + +### Cloud Sync + +- Synkroniser leverandører, kombinasjoner og innstillinger på tvers av enheter +- Automatisk bakgrunnssynkronisering med timeout + feil-rask +- Foretrekk server-side `BASE_URL`/`CLOUD_URL` i produksjon + +### LLM Gateway Intelligence (fase 9) + +- **Semantisk hurtigbuffer** — Automatisk hurtigbufring uten strømming, temperatur=0 svar (omgå med `X-OmniRoute-No-Cache: true`) +- **Request Idempotency** — Dedupliserer forespørsler innen 5 sekunder via `Idempotency-Key` eller `X-Request-Id` header +- **Fremdriftssporing** — Meld deg på SSE `event: progress` hendelser via `X-OmniRoute-Progress: true` header + +--- + +### Oversetter Lekeplass + +Tilgang via **Dashboard → Oversetter**. Feilsøk og visualiser hvordan OmniRoute oversetter API-forespørsler mellom leverandører. + +| Modus | Formål | +| ---------------- | ------------------------------------------------------------------------------------------------ | +| **Lekeplass** | Velg kilde-/målformater, lim inn en forespørsel og se den oversatte utgangen umiddelbart | +| **Chattetester** | Send live chat-meldinger gjennom proxyen og inspiser hele forespørsels-/svarsyklusen | +| **Testbenk** | Kjør batch-tester på tvers av flere formatkombinasjoner for å bekrefte oversettelsens korrekthet | +| **Live Monitor** | Se sanntidsoversettelser mens forespørsler strømmer gjennom proxyen | + +**Brukstilfeller:** + +- Feilsøk hvorfor en spesifikk klient/leverandør-kombinasjon mislykkes +- Bekreft at tankekoder, verktøykall og systemmeldinger oversettes riktig +- Sammenlign formatforskjeller mellom OpenAI, Claude, Gemini og Responses API-formater + +--- + +### Rutingstrategier + +Konfigurer via **Dashboard → Innstillinger → Ruting**. + +| Strategi | Beskrivelse | +| ------------------------------ | -------------------------------------------------------------------------------------------------------- | +| **Fyll først** | Bruker kontoer i prioritert rekkefølge — primærkonto håndterer alle forespørsler inntil utilgjengelig | +| **Round Robin** | Bla gjennom alle kontoer med en konfigurerbar klebrig grense (standard: 3 samtaler per konto) | +| **P2C (Power of Two Choices)** | Velger 2 tilfeldige kontoer og ruter til den sunnere — balanserer belastning med bevissthet om helse | +| **Tilfeldig** | Velger tilfeldig en konto for hver forespørsel ved hjelp av Fisher-Yates shuffle | +| **Minst brukt** | Ruter til kontoen med det eldste `lastUsedAt` tidsstemplet, fordeler trafikk jevnt | +| **Kostnadsoptimalisert** | Ruter til kontoen med den laveste prioritetsverdien, optimalisering for de laveste kostnadsleverandørene | + +#### Jokertegn modellaliaser + +Lag jokertegnmønstre for å tilordne modellnavn på nytt: + +``` +Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929 +Pattern: gpt-* → Target: gh/gpt-5.1-codex +``` + +Jokertegn støtter `*` (alle tegn) og `?` (enkelttegn). + +#### Reservekjeder + +Definer globale reservekjeder som gjelder for alle forespørsler: + +``` +Chain: production-fallback + 1. cc/claude-opus-4-6 + 2. gh/gpt-5.1-codex + 3. glm/glm-4.7 +``` + +--- + +### Spenst og effektbrytere + +Konfigurer via **Dashboard → Innstillinger → Resiliens**. + +OmniRoute implementerer motstandskraft på leverandørnivå med fire komponenter: + +1. **Leverandørprofiler** — Konfigurasjon per leverandør for: + - Feilterskel (hvor mange feil før åpning) + - Nedkjølingsvarighet + - Følsomhet for deteksjon av hastighetsgrense + - Eksponentielle backoff-parametere + +2. **Redigerbare rategrenser** — Standardinnstillinger på systemnivå som kan konfigureres i dashbordet: + - **Forespørsler per minutt (RPM)** — Maksimalt antall forespørsler per minutt per konto + - **Min time Between Requests** — Minimumsavstand i millisekunder mellom forespørsler + - **Maks samtidige forespørsler** — Maksimalt antall samtidige forespørsler per konto + - Klikk på **Rediger** for å endre, deretter **Lagre** eller **Avbryt**. Verdiene vedvarer via resilience API. + +3. **Circuit Breaker** — Sporer feil per leverandør og åpner automatisk kretsen når en terskel er nådd: + - **STENGT** (Sunn) — Forespørslene flyter normalt + - **ÅPEN** — Leverandøren er midlertidig blokkert etter gjentatte feil + - **HALF_OPEN** — Tester om leverandøren har kommet seg + +4. **Retningslinjer og låste identifikatorer** — Viser strømbryterstatus og låste identifikatorer med tvangsopplåsingsfunksjon. + +5. **Rate Limit Auto-Detection** — Overvåker `429` og `Retry-After` overskrifter for å proaktivt unngå å treffe leverandørens takstgrenser. + +**Profftips:** Bruk **Tilbakestill alle**-knappen for å fjerne alle strømbrytere og nedkjøling når en leverandør kommer seg etter et strømbrudd. + +--- + +### Databaseeksport/import + +Administrer sikkerhetskopiering av databaser i **Dashboard → Innstillinger → System og lagring**. + +| Handling | Beskrivelse | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Eksporter database** | Laster ned gjeldende SQLite-database som en `.sqlite`-fil | +| **Eksporter alle (.tar.gz)** | Laster ned et fullstendig sikkerhetskopiarkiv inkludert: database, innstillinger, kombinasjoner, leverandørtilkoblinger (ingen legitimasjon), API-nøkkelmetadata | +| **Importer database** | Last opp en `.sqlite`-fil for å erstatte gjeldende database. En forhåndsimport-sikkerhetskopi opprettes automatisk | + +```bash +# API: Export database +curl -o backup.sqlite http://localhost:20128/api/db-backups/export + +# API: Export all (full archive) +curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll + +# API: Import database +curl -X POST http://localhost:20128/api/db-backups/import \ + -F "file=@backup.sqlite" +``` + +**Importvalidering:** Den importerte filen er validert for integritet (SQLite pragmasjekk), nødvendige tabeller (`provider_connections`, `provider_nodes`, `combos`, `api_keys`) og størrelse (maks 100 MB). + +**Brukstilfeller:** + +- Migrer OmniRoute mellom maskiner +- Lag eksterne sikkerhetskopier for katastrofegjenoppretting +- Del konfigurasjoner mellom teammedlemmer (eksporter alle → del arkiv) + +--- + +### Innstillinger Dashboard + +Innstillingssiden er organisert i 5 faner for enkel navigering: + +| Tab | Innhold | +| ------------- | ----------------------------------------------------------------------------------------------------------------- | +| **Sikkerhet** | Innstillinger for pålogging/passord, IP-tilgangskontroll, API-autentisering for `/models` og leverandørblokkering | +| **Ruting** | Global rutingstrategi (6 alternativer), jokertegnmodellaliaser, reservekjeder, kombinasjonsstandarder | +| **Resiliens** | Leverandørprofiler, redigerbare hastighetsgrenser, strømbryterstatus, retningslinjer og låste identifikatorer | +| **AI** | Tenker budsjettkonfigurasjon, global systempromptinjeksjon, promptbufferstatistikk | +| **Avansert** | Global proxy-konfigurasjon (HTTP/SOCKS5) | + +--- + +### Kostnader og budsjettstyring + +Tilgang via **Dashboard → Kostnader**. + +| Tab | Formål | +| ------------ | ------------------------------------------------------------------------------------------------ | +| **Budsjett** | Angi utgiftsgrenser per API-nøkkel med daglige/ukentlige/månedlige budsjetter og sanntidssporing | +| **Pris** | Se og rediger modellprisoppføringer — kostnad per 1K input/output tokens per leverandør | + +```bash +# API: Set a budget +curl -X POST http://localhost:20128/api/usage/budget \ + -H "Content-Type: application/json" \ + -d '{"keyId": "key-123", "limit": 50.00, "period": "monthly"}' + +# API: Get current budget status +curl http://localhost:20128/api/usage/budget +``` + +**Kostnadssporing:** Hver forespørsel logger tokenbruk og beregner kostnad ved hjelp av pristabellen. Se oversikter i **Dashboard → Bruk** etter leverandør, modell og API-nøkkel. + +--- + +### Lydtranskripsjon + +OmniRoute støtter lydtranskripsjon via det OpenAI-kompatible endepunktet: + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data + +# Example with curl +curl -X POST http://localhost:20128/v1/audio/transcriptions \ + -H "Authorization: Bearer your-api-key" \ + -F "file=@audio.mp3" \ + -F "model=deepgram/nova-3" +``` + +Tilgjengelige leverandører: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`). + +Støttede lydformater: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +### Kombinasjonsbalanseringsstrategier + +Konfigurer balansering per kombinasjon i **Dashboard → Combos → Opprett/Rediger → Strategi**. + +| Strategi | Beskrivelse | +| ------------------------ | ----------------------------------------------------------------------------------- | +| **Round-Robin** | Roterer gjennom modellene sekvensielt | +| **Prioritet** | Prøver alltid den første modellen; faller tilbake kun på feil | +| **Tilfeldig** | Velger en tilfeldig modell fra kombinasjonen for hver forespørsel | +| **Vektet** | Ruter proporsjonalt basert på tildelte vekter per modell | +| **Minst brukt** | Ruter til modellen med færrest nylige forespørsler (bruker kombinasjonsberegninger) | +| **Kostnadsoptimalisert** | Ruter til den billigste tilgjengelige modellen (bruker pristabell) | + +Globale kombinasjonsstandarder kan angis i **Dashboard → Innstillinger → Ruting → Combo-standarder**. + +--- + +### Helse Dashboard + +Tilgang via **Dashboard → Helse**. Sanntids systemhelseoversikt med 6 kort: + +| Kort | Hva det viser | +| --------------------- | ------------------------------------------------------------- | +| **Systemstatus** | Oppetid, versjon, minnebruk, datakatalog | +| **Leverandørs helse** | Per leverandør effektbrytertilstand (lukket/åpen/halvåpen) | +| **Satsgrenser** | Aktive nedkjølingshastigheter per konto med gjenværende tid | +| **Aktive Lockouts** | Leverandører midlertidig blokkert av lockout-policyen | +| **Signaturbuffer** | Dedupliseringsbufferstatistikk (aktive nøkler, trefffrekvens) | +| **Latens-telemetri** | p50/p95/p99 latensaggregering per leverandør | + +**Profftips:** Helsesiden oppdateres automatisk hvert 10. sekund. Bruk kretsbryterkortet til å identifisere hvilke leverandører som har problemer. diff --git a/docs/i18n/phi/API_REFERENCE.md b/docs/i18n/phi/API_REFERENCE.md new file mode 100644 index 0000000000..8ca4cd62ae --- /dev/null +++ b/docs/i18n/phi/API_REFERENCE.md @@ -0,0 +1,441 @@ +# Sanggunian ng API + +🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md) + +Kumpletong sanggunian para sa lahat ng endpoint ng OmniRoute API. + +--- + +## Talaan ng mga Nilalaman + +- [Chat Completions](#chat-completions) +- [Embeddings](#embeddings) +- [Image Generation](#image-generation) +- [List Models](#list-models) +- [Compatibility Endpoints](#compatibility-endpoints) +- [Semantic Cache](#semantic-cache) +- [Dashboard & Management](#dashboard--management) +- [Request Processing](#request-processing) +- [Authentication](#authentication) + +--- + +## Mga Pagkumpleto ng Chat + +```bash +POST /v1/chat/completions +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "cc/claude-opus-4-6", + "messages": [ + {"role": "user", "content": "Write a function to..."} + ], + "stream": true +} +``` + +### Mga Custom na Header + +| Header | Direksyon | Paglalarawan | +| ------------------------ | ---------- | --------------------------------------------------- | +| `X-OmniRoute-No-Cache` | Kahilingan | Itakda sa `true` upang i-bypass ang cache | +| `X-OmniRoute-Progress` | Kahilingan | Itakda sa `true` para sa mga kaganapan sa pag-unlad | +| `Idempotency-Key` | Kahilingan | Dedup key (5s window) | +| `X-Request-Id` | Kahilingan | Alternatibong susi sa pagtanggal | +| `X-OmniRoute-Cache` | Tugon | `HIT` o `MISS` (hindi nag-stream) | +| `X-OmniRoute-Idempotent` | Tugon | `true` kung i-deduplicate | +| `X-OmniRoute-Progress` | Tugon | `enabled` kung ang pagsubaybay sa pag-unlad sa | + +--- + +## Mga pag-embed + +```bash +POST /v1/embeddings +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "nebius/Qwen/Qwen3-Embedding-8B", + "input": "The food was delicious" +} +``` + +Mga available na provider: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA. + +```bash +# List all embedding models +GET /v1/embeddings +``` + +--- + +## Pagbuo ng Larawan + +```bash +POST /v1/images/generations +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "openai/dall-e-3", + "prompt": "A beautiful sunset over mountains", + "size": "1024x1024" +} +``` + +Mga available na provider: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI. + +```bash +# List all image models +GET /v1/images/generations +``` + +--- + +## Listahan ng mga Modelo + +```bash +GET /v1/models +Authorization: Bearer your-api-key + +→ Returns all chat, embedding, and image models + combos in OpenAI format +``` + +--- + +## Mga Endpoint ng Compatibility + +| Paraan | Landas | Format | +| ------ | --------------------------- | ---------------------- | +| POST | `/v1/chat/completions` | OpenAI | +| POST | `/v1/messages` | Antropiko | +| POST | `/v1/responses` | Mga Tugon sa OpenAI | +| POST | `/v1/embeddings` | OpenAI | +| POST | `/v1/images/generations` | OpenAI | +| KUMUHA | `/v1/models` | OpenAI | +| POST | `/v1/messages/count_tokens` | Antropiko | +| KUMUHA | `/v1beta/models` | Gemini | +| POST | `/v1beta/models/{...path}` | Gemini generateContent | +| POST | `/v1/api/chat` | Ollama | + +### Nakalaang Mga Ruta ng Provider + +```bash +POST /v1/providers/{provider}/chat/completions +POST /v1/providers/{provider}/embeddings +POST /v1/providers/{provider}/images/generations +``` + +Ang prefix ng provider ay awtomatikong idinaragdag kung nawawala. Ang mga hindi tugmang modelo ay nagbabalik ng `400`. + +--- + +## Semantic Cache + +```bash +# Get cache stats +GET /api/cache + +# Clear all caches +DELETE /api/cache +``` + +Halimbawa ng tugon: + +```json +{ + "semanticCache": { + "memorySize": 42, + "memoryMaxSize": 500, + "dbSize": 128, + "hitRate": 0.65 + }, + "idempotency": { + "activeKeys": 3, + "windowMs": 5000 + } +} +``` + +--- + +## Dashboard at Pamamahala + +### Pagpapatotoo + +| 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 | + +### Pamamahala ng Provider + +| 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 | + +### Mga Daloy ng OAuth + +| Endpoint | Paraan | Paglalarawan | +| -------------------------------- | ----------- | ------------------------------- | +| `/api/oauth/[provider]/[action]` | Iba't ibang | OAuth na partikular sa provider | + +### Pagruruta at Config + +| 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 | + +### Paggamit at Analytics + +| Endpoint | Paraan | Paglalarawan | +| --------------------------- | ------ | ------------------------------ | +| `/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 | + +### Mga Setting + +| Endpoint | Paraan | Paglalarawan | +| ------------------------------- | ------- | ------------------------------ | +| `/api/settings` | GET/PUT | Mga pangkalahatang setting | +| `/api/settings/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/settings/system-prompt` | GET/PUT | Global system prompt | + +### Pagsubaybay + +| 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 | +| `/api/cache` | GET/DELETE | Mga istatistika ng cache / i-clear | + +### I-backup at I-export/I-import + +| Endpoint | Paraan | Paglalarawan | +| --------------------------- | ------ | ----------------------------------------------------- | +| `/api/db-backups` | KUMUHA | Ilista ang 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 + +| 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 | + +### CLI Tools + +| 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 | + +Kasama sa mga tugon ng CLI ang: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. + +### Mga Limitasyon sa Katatagan at Rate + +| Endpoint | Paraan | Paglalarawan | +| ----------------------- | ------- | ------------------------------------------------- | +| `/api/resilience` | GET/PUT | 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 | Configuration ng limitasyon sa pandaigdigang rate | + +### Mga Eval + +| Endpoint | Paraan | Paglalarawan | +| ------------ | -------- | ------------------------------------------- | +| `/api/evals` | GET/POST | Maglista ng mga eval suite / run evaluation | + +### Mga Patakaran + +| Endpoint | Paraan | Paglalarawan | +| --------------- | --------------- | ----------------------------------------- | +| `/api/policies` | GET/POST/DELETE | Pamahalaan ang mga patakaran sa pagruruta | + +### Pagsunod + +| Endpoint | Paraan | Paglalarawan | +| --------------------------- | ------ | ----------------------------------- | +| `/api/compliance/audit-log` | KUMUHA | Log ng audit ng pagsunod (huling N) | + +### v1beta (Gemini-Compatible) + +| Endpoint | Paraan | Paglalarawan | +| -------------------------- | ------ | ------------------------------------------ | +| `/v1beta/models` | KUMUHA | Listahan ng mga modelo sa Gemini na format | +| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint | + +Ang mga endpoint na ito ay sumasalamin sa format ng API ng Gemini para sa mga kliyenteng umaasa sa native na Gemini SDK compatibility. + +### Mga Panloob / System API + +| Endpoint | Paraan | Paglalarawan | +| --------------- | ------ | ---------------------------------------------------------------------- | +| `/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 | + +> **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. + +--- + +## Transkripsyon ng Audio + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data +``` + +I-transcribe ang mga audio file gamit ang Deepgram o AssemblyAI. + +**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" +``` + +**Tugon:** + +```json +{ + "text": "Hello, this is the transcribed audio content.", + "task": "transcribe", + "language": "en", + "duration": 12.5 +} +``` + +**Mga sinusuportahang provider:** `deepgram/nova-3`, `assemblyai/best`. + +**Mga sinusuportahang format:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +## Ollama Compatibility + +Para sa mga kliyenteng gumagamit ng format ng API ng Ollama: + +```bash +# Chat endpoint (Ollama format) +POST /v1/api/chat + +# Model listing (Ollama format) +GET /api/tags +``` + +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 +``` + +**Tugon:** + +```json +{ + "providers": { + "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, + "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } + } +} +``` + +--- + +## Badyet + +```bash +# Get budget status for all API keys +GET /api/usage/budget + +# Set or update a budget +POST /api/usage/budget +Content-Type: application/json + +{ + "keyId": "key-123", + "limit": 50.00, + "period": "monthly" +} +``` + +--- + +## Availability ng Modelo + +```bash +# Get real-time model availability across all providers +GET /api/models/availability + +# Check availability for a specific model +POST /api/models/availability +Content-Type: application/json + +{ + "model": "claude-sonnet-4-5-20250929" +} +``` + +--- + +## Pagproseso ng Kahilingan + +1. Nagpapadala ang kliyente ng kahilingan sa `/v1/*` +2. Tumatawag ang tagapangasiwa ng ruta sa `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 + +Buong sanggunian sa arkitektura: [**OMNI_TOKEN_119**](ARCHITECTURE.md) + +--- + +## Pagpapatotoo + +- Ang mga ruta ng dashboard (`/dashboard/*`) ay gumagamit ng `auth_token` cookie +- Gumagamit ang pag-login ng naka-save na hash ng password; fallback sa `INITIAL_PASSWORD` +- `requireLogin` toggleable sa pamamagitan ng `/api/settings/require-login` +- `/v1/*` ruta opsyonal na nangangailangan ng Bearer API key kapag `REQUIRE_API_KEY=true` diff --git a/docs/i18n/phi/ARCHITECTURE.md b/docs/i18n/phi/ARCHITECTURE.md new file mode 100644 index 0000000000..b1fc6d6d41 --- /dev/null +++ b/docs/i18n/phi/ARCHITECTURE.md @@ -0,0 +1,781 @@ +# OmniRoute Architecture + +🌐 **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) + +_Huling na-update: 2026-02-18_ + +## 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. + +Mga pangunahing kakayahan: + +- 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 +- Pag-embed ng henerasyon 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 (`...`) 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) +- 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 +- 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 katiyakan ng kalidad ng LLM +- 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/`) + +Pangunahing modelo ng runtime: + +- 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 + +## Saklaw at Hangganan + +### Nasa Saklaw + +- 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 + +### Wala sa Saklaw + +- 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.) + +## Mataas na Antas na Konteksto ng System + +```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 +``` + +## Mga Pangunahing Bahagi ng Runtime + +## 1) API at Routing Layer (Next.js App Routes) + +Mga pangunahing direktoryo: + +- `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` mapa `/v1/*` hanggang `/api/v1/*` + +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` — kasama ang mga custom na modelo na may `custom: true` +- `src/app/api/v1/embeddings/route.ts` — henerasyon 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` — nakatuon sa bawat provider na 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` + +Mga domain ng pamamahala: + +- 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/catalog` (GET) +- Proxy config: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST) +- OAuth: `src/app/api/oauth/*` +- Mga key/alias/combos/presyo: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing` +- Paggamit: `src/app/api/usage/*` +- Sync/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*` +- CLI tooling helpers: `src/app/api/cli-tools/*` +- IP filter: `src/app/api/settings/ip-filter` (GET/PUT) +- Pag-iisip na badyet: `src/app/api/settings/thinking-budget` (GET/PUT) +- System prompt: `src/app/api/settings/system-prompt` (GET/PUT) +- Mga Sesyon: `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 +- 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) +- 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 + Core ng Pagsasalin + +Mga pangunahing module ng daloy: + +- Entry: `src/sse/handlers/chat.ts` +- Core orchestration: `open-sse/handlers/chatCore.ts` +- Mga adaptor ng pagpapatupad ng provider: `open-sse/executors/*` +- Format detection/provider config: `open-sse/services/provider.ts` +- Pag-parse/paglutas ng modelo: `src/sse/services/model.ts`, `open-sse/services/model.ts` +- Logic ng fallback ng account: `open-sse/services/accountFallback.ts` +- Pagpapatala 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` +- Isipin ang tag parser: `open-sse/utils/thinkTagParser.ts` +- Handler ng pag-embed: `open-sse/handlers/embeddings.ts` +- Pag-embed ng pagpapatala 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` +- Paglinis ng tugon: `open-sse/handlers/responseSanitizer.ts` +- Pag-normalize ng tungkulin: `open-sse/services/roleNormalizer.ts` + +Mga Serbisyo (lohika ng negosyo): + +- 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 deduplikasyon: `open-sse/services/signatureCache.ts` +- System prompt injection: `open-sse/services/systemPrompt.ts` +- Pag-iisip ng pamamahala sa 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` + +Mga module ng layer ng domain: + +- 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 solver: `src/lib/domain/comboResolver.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` +- 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` +- 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 + +Mga module ng provider ng OAuth (12 indibidwal na file sa ilalim ng `src/lib/oauth/providers/`): + +- Registry index: `src/lib/oauth/providers/index.ts` +- Mga indibidwal na tagapagbigay: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, \_\_OMNI_9TOKEN `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts` +- Manipis na wrapper: `src/lib/oauth/providers.ts` — muling pag-export mula sa mga indibidwal na module + +## 3) Layer ng Pagtitiyaga + +Pangunahing estado DB: + +- `src/lib/localDb.ts` +- file: `${DATA_DIR}/db.json` (o `$XDG_CONFIG_HOME/omniroute/db.json` kapag nakatakda, kung hindi `~/.omniroute/db.json`) +- mga entity: providerConnections, providerNodes, modelAliases, combos, apiKeys, mga setting, pagpepresyo, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt** + +Paggamit ng DB: + +- `src/lib/usageDb.ts` +- mga file: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- sumusunod sa parehong base na patakaran sa direktoryo gaya ng `localDb` (`DATA_DIR`, pagkatapos ay `XDG_CONFIG_HOME/omniroute` kapag nakatakda) +- nabulok sa mga nakatutok na sub-modules: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts` + +Domain State DB (SQLite): + +- `src/lib/db/domainState.ts` — CRUD operations para sa domain state +- 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` +- Pagbuo/pag-verify ng API key: `src/shared/utils/apiKey.ts` +- Nagpatuloy ang mga lihim ng provider sa `providerConnections` na mga entry +- Outbound proxy na suporta sa pamamagitan ng `open-sse/utils/proxyFetch.ts` (env vars) at `open-sse/utils/networkProxy.ts` (nako-configure sa bawat provider o global) + +## 5) Cloud Sync + +- Scheduler init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts` +- Pana-panahong gawain: `src/shared/services/cloudSyncScheduler.ts` +- Ruta ng kontrol: `src/app/api/sync/cloud/route.ts` + +## Humiling ng Lifecycle (`/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 + Daloy ng Fallback ng Account + +```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] +``` + +Ang mga desisyon sa pagbabalik ay hinihimok ng `open-sse/services/accountFallback.ts` gamit ang mga status code at heuristic ng error-message. + +## OAuth Onboarding at 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 +``` + +Ang pag-refresh sa panahon ng live na trapiko ay isinasagawa sa loob ng `open-sse/handlers/chatCore.ts` sa pamamagitan ng executor na `refreshCredentials()`. + +## Lifecycle ng Cloud Sync (Paganahin / Pag-sync / I-disable) + +```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 +``` + +Ang pana-panahong pag-sync ay na-trigger ng `CloudSyncScheduler` kapag pinagana ang cloud. + +## Modelo ng Data at Imbakan ng Mapa + +```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 + } +``` + +Mga file ng pisikal na storage: + +- pangunahing estado: `${DATA_DIR}/db.json` (o `$XDG_CONFIG_HOME/omniroute/db.json` kapag nakatakda, kung hindi `~/.omniroute/db.json`) +- mga istatistika ng paggamit: `${DATA_DIR}/usage.json` +- humiling ng mga linya ng log: `${DATA_DIR}/log.txt` +- opsyonal na tagasalin/paghiling ng mga sesyon ng pag-debug: `/logs/...` + +## Deployment Topology + +```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 +``` + +## Module Mapping (Desisyon-Kritikal) + +### Mga Module ng Ruta at API + +- `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, pagpapatunay, pagsubok +- `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/catalog`: full model catalog API (lahat ng uri ay nakapangkat ayon sa provider) +- `src/app/api/oauth/*`: 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*`: fallback combo management +- `src/app/api/pricing`: na-override ang pagpepresyo para sa pagkalkula ng gastos +- `src/app/api/settings/proxy`: proxy configuration (GET/PUT/DELETE) +- `src/app/api/settings/proxy/test`: outbound proxy connectivity test (POST) +- `src/app/api/usage/*`: mga API sa 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`: aktibong listahan ng session (GET) +- `src/app/api/rate-limits`: per-account rate limit status (GET) + +### Routing at Execution Core + +- `src/sse/handlers/chat.ts`: request parse, combo handling, account selection loop +- `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 at Format Converters + +- `open-sse/translator/index.ts`: rehistro ng tagasalin at orkestrasyon +- Humiling ng mga tagasalin: `open-sse/translator/request/*` +- Mga tagasalin ng tugon: `open-sse/translator/response/*` +- Format constants: `open-sse/translator/formats.ts` + +### Pagtitiyaga + +- `src/lib/localDb.ts`: paulit-ulit na config/state +- `src/lib/usageDb.ts`: history ng paggamit at rolling request logs + +## Saklaw ng Tagapagpatupad ng Provider (Pattern ng Diskarte) + +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, mga credential refresh hook, at ang `execute()` na paraan ng orkestrasyon. + +| Tagapagpatupad | (Mga) Provider | Espesyal na Paghawak | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- | +| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, 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 | +| `GeminiCLIExecutor` | Gemini CLI | Ikot ng pag-refresh ng token ng Google OAuth | + +Ang lahat ng iba pang provider (kabilang ang mga custom na katugmang node) ay gumagamit ng `DefaultExecutor`. + +## Provider Compatibility Matrix + +| Provider | Format | Awth | 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 | +| iFlow | 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 | ✅ | ✅ | ❌ | ❌ | + +## Sakop ng Pagsasalin ng Format + +Kasama sa mga natukoy na format ng pinagmulan ang: + +- `openai` +- `openai-responses` +- `claude` +- `gemini` + +Kasama sa mga target na format ang: + +- OpenAI chat/Mga Tugon +- Claude +- Gemini/Gemini-CLI/Antigravity envelope +- Kiro +- Cursor + +Ginagamit ng mga pagsasalin ang **OpenAI bilang hub format** — lahat ng conversion ay dumadaan sa OpenAI bilang intermediate: + +``` +Source Format → OpenAI (hub) → Target Format +``` + +Pinipili ang mga pagsasalin sa dynamic na paraan batay sa hugis ng source payload at format ng target ng provider. + +Mga karagdagang layer ng pagpoproseso sa pipeline ng pagsasalin: + +- **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) +- **Isipin ang pagkuha ng tag** — Pina-parse ang `...` na mga bloke mula sa nilalaman patungo sa `reasoning_content` na field +- **Structured output** — Kino-convert ang OpenAI `response_format.json_schema` sa Gemini's `responseMimeType` + `responseSchema` + +## Mga Sinusuportahang API Endpoints + +| 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/responses` | 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/pagkakakonekta ng proxy | +| `GET/POST/DELETE /api/provider-models` | Mga Custom na Modelo | Pamamahala ng custom na modelo sa bawat provider | + +## 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 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`. + +## Humiling ng Logger Pipeline + +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 +``` + +Ang mga file ay isinulat sa `/logs//` para sa bawat sesyon ng kahilingan. + +## Mga Mode ng Pagkabigo at Katatagan + +## 1) Availability ng Account/Provider + +- 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) Pag-expire ng Token + +- paunang suriin at i-refresh na may muling pagsubok para sa mga nare-refresh na provider +- 401/403 subukang muli pagkatapos ng pagtatangka sa pag-refresh sa pangunahing landas + +## 3) Kaligtasan ng Stream + +- disconnect-aware stream controller +- 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) Pagbaba ng Cloud Sync + +- 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) Integridad ng Data + +- Paglipat/pagkumpuni ng hugis ng DB para sa mga nawawalang key +- tiwaling JSON reset safeguards para sa localDb at usageDb + +## Pagmamasid at Mga Signal ng Operasyon + +Runtime visibility source: + +- mga console log mula sa `src/sse/utils/logger.ts` +- mga pinagsama-samang paggamit sa bawat kahilingan sa `usage.json` +- log in sa status ng text na kahilingan `log.txt` +- opsyonal na malalim na kahilingan/mga log ng pagsasalin sa ilalim ng `logs/` kapag `ENABLE_REQUEST_LOGS=true` +- mga endpoint sa paggamit ng dashboard (`/api/usage/*`) para sa paggamit ng UI + +## Mga Hangganan na Sensitibo sa Seguridad + +- Sikreto ng JWT (`JWT_SECRET`) ay sinisiguro ang pag-verify/pagpirma ng cookie ng session ng dashboard +- Dapat na ma-override ang paunang password (`INITIAL_PASSWORD`, default na `123456`) sa mga totoong deployment +- 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 at Runtime Matrix + +Mga variable ng kapaligiran na aktibong ginagamit ng code: + +- App/auth: `JWT_SECRET`, `INITIAL_PASSWORD` +- Imbakan: `DATA_DIR` +- Katugmang pag-uugali ng node: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` +- Opsyonal na storage base override (Linux/macOS kapag `DATA_DIR` unset): `XDG_CONFIG_HOME` +- Hashing 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` +- Papalabas na proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` at lowercase na mga variant +- Mga flag ng tampok na 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` + +## Mga Kilalang Architectural Notes + +1. Ibinabahagi na ngayon ng `usageDb` at `localDb` ang parehong base directory policy (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) na may legacy na paglipat ng file. +2. Nagbabalik ang `/api/v1/route.ts` ng static na listahan ng modelo at hindi ito ang pangunahing pinagmumulan ng mga modelo na ginagamit ng `/v1/models`. +3. Ang Request logger ay nagsusulat ng buong header/body kapag pinagana; ituring ang direktoryo ng log bilang sensitibo. +4. Ang pag-uugali ng cloud ay nakasalalay sa tamang `NEXT_PUBLIC_BASE_URL` at maabot ang endpoint ng cloud. +5. Ang `open-sse/` na direktoryo ay na-publish bilang ang `@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 file path 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. Ang mga pagsusulit sa E2E ay gumagamit ng **Playwright** (`tests/e2e/`), tumatakbo sa pamamagitan ng `npm run test:e2e`. Gumagamit ang mga unit test ng **Node.js test runner** (`tests/unit/`), na tumatakbo sa pamamagitan ng `npm run test:plan3`. 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). + +## Checklist ng Pagpapatunay ng Operasyon + +- Bumuo mula sa pinagmulan: `npm run build` +- Bumuo ng larawan ng Docker: `docker build -t omniroute .` +- Simulan ang serbisyo at i-verify: +- `GET /api/settings` +- `GET /api/v1/models` +- Ang CLI target base URL ay dapat na `http://:20128/v1` kapag `PORT=20128` diff --git a/docs/i18n/phi/CODEBASE_DOCUMENTATION.md b/docs/i18n/phi/CODEBASE_DOCUMENTATION.md new file mode 100644 index 0000000000..e62ac26e14 --- /dev/null +++ b/docs/i18n/phi/CODEBASE_DOCUMENTATION.md @@ -0,0 +1,589 @@ +# omniroute — Codebase Documentation + +🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md) + +> Isang komprehensibo, madaling gabay sa baguhan sa **omniroute** multi-provider AI proxy router. + +--- + +## 1. Ano ang omniroute? + +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: + +> **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. + +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. Pangkalahatang-ideya ng Arkitektura + +```mermaid +graph LR + subgraph Clients + A[Claude CLI] + B[Codex] + C[Cursor IDE] + D[OpenAI-compatible] + end + + subgraph omniroute + E[Handler Layer] + F[Translator Layer] + G[Executor Layer] + H[Services Layer] + end + + subgraph Providers + I[Anthropic Claude] + J[Google Gemini] + K[OpenAI / Codex] + L[GitHub Copilot] + M[AWS Kiro] + N[Antigravity] + O[Cursor API] + end + + A --> E + B --> E + C --> E + D --> E + E --> F + F --> G + G --> I + G --> J + G --> K + G --> L + G --> M + G --> N + G --> O + H -.-> E + H -.-> G +``` + +### Pangunahing Prinsipyo: Hub-and-Spoke Translation + +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) +``` + +Nangangahulugan ito na kailangan mo lang ng **N na tagasalin** (isa bawat format) sa halip na **N²** (bawat pares). + +--- + +## 3. Istruktura ng Proyekto + +``` +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 +``` + +--- + +## 4. Pagkakabahagi ng Module-by-Module + +### 4.1 Config (`open-sse/config/`) + +Ang **nag-iisang pinagmulan ng katotohanan** para sa lahat ng configuration ng provider. + +| File | Layunin | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `constants.ts` | `PROVIDERS` object 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). | + +#### Daloy ng Paglo-load ng Kredensyal + +```mermaid +flowchart TD + A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"] + B --> C{"data/provider-credentials.json\nexists?"} + C -->|Yes| D["credentialLoader reads JSON"] + C -->|No| E["Use hardcoded defaults"] + D --> F{"For each provider in JSON"} + F --> G{"Provider exists\nin PROVIDERS?"} + G -->|No| H["Log warning, skip"] + G -->|Yes| I{"Value is object?"} + I -->|No| J["Log warning, skip"] + I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"] + K --> F + H --> F + J --> F + F -->|Done| L["PROVIDERS ready with\nmerged credentials"] + E --> L +``` + +--- + +### 4.2 Mga Tagapagpatupad (`open-sse/executors/`) + +Inilalagay ng mga tagapagpatupad ang **lohika na tukoy 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 DefaultExecutor { + +refreshCredentials() + } + + class AntigravityExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +shouldRetry() + +refreshCredentials() + } + + class CursorExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseResponse() + +generateChecksum() + } + + class KiroExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseEventStream() + +refreshCredentials() + } + + BaseExecutor <|-- DefaultExecutor + BaseExecutor <|-- AntigravityExecutor + BaseExecutor <|-- CursorExecutor + BaseExecutor <|-- KiroExecutor + BaseExecutor <|-- CodexExecutor + BaseExecutor <|-- GeminiCLIExecutor + BaseExecutor <|-- GithubExecutor +``` + +| Tagapagpatupad | Provider | Mga Pangunahing Espesyalisasyon | +| ---------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| `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 | Pagbuo ng custom na 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 Mga Handler (`open-sse/handlers/`) + +Ang **orchestration layer** — nag-coordinate ng pagsasalin, execution, streaming, at paghawak ng error. + +| 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, nagpapadala sa API ng provider, nagbabalik ng tugon sa pag-embed na katugma 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. | + +#### Humiling ng Lifecycle (chatCore.ts) + +```mermaid +sequenceDiagram + participant Client + participant chatCore + participant Translator + participant Executor + participant Provider + + Client->>chatCore: Request (any format) + chatCore->>chatCore: Detect source format + chatCore->>chatCore: Check bypass patterns + chatCore->>chatCore: Resolve model & provider + chatCore->>Translator: Translate request (source → OpenAI → target) + chatCore->>Executor: Get executor for provider + Executor->>Executor: Build URL, headers, transform request + Executor->>Executor: Refresh credentials if needed + Executor->>Provider: HTTP fetch (streaming or non-streaming) + + alt Streaming + Provider-->>chatCore: SSE stream + chatCore->>chatCore: Pipe through SSE transform stream + Note over chatCore: Transform stream translates
each chunk: target → OpenAI → source + chatCore-->>Client: Translated SSE stream + else Non-streaming + Provider-->>chatCore: JSON response + chatCore->>Translator: Translate response + chatCore-->>Client: Translated JSON + end + + alt Error (401, 429, 500...) + chatCore->>Executor: Retry with credential refresh + chatCore->>chatCore: Account fallback logic + end +``` + +--- + +### 4.4 Mga Serbisyo (`open-sse/services/`) + +Logic ng negosyo na sumusuporta sa mga humahawak at tagapagpatupad. + +| File | Layunin | +| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `provider.ts` | **Format detection** (`detectFormat`): sinusuri ang request body structure para matukoy ang mga format ng Claude/OpenAI/Gemini/Antigravity/Responses (kasama ang `max_tokens` heuristic para kay Claude). Gayundin: pagbuo ng URL, pagbuo ng header, pag-normalize ng config ng pag-iisip. Sinusuportahan ang `openai-compatible-*` at `anthropic-compatible-*` na mga dynamic na provider. | +| `model.ts` | Model string parsing (`claude/model-name` → `{provider: "claude", model: "model-name"}`), alias resolution na may collision detection, input sanitization (tinatanggihan ang path traversal/control chars), at resolution ng impormasyon ng modelo na may suporta sa async alias getter. | +| `accountFallback.ts` | Rate-limit handling: exponential backoff (1s → 2s → 4s → max 2min), pamamahala ng cooldown ng account, pag-uuri ng error (na ang mga error ay nagti-trigger ng fallback vs. not). | +| `tokenRefresh.ts` | OAuth token refresh para sa **bawat provider**: Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). May kasamang in-flight promise deduplication cache at subukang muli nang may exponential backoff. | +| `combo.ts` | **Mga modelong combo**: mga chain ng fallback na modelo. Kung nabigo ang modelong A na may error na karapat-dapat sa fallback, subukan ang modelo B, pagkatapos ay C, atbp. Ibinabalik ang mga aktwal na upstream na status code. | +| `usage.ts` | Kinukuha ang quota/data ng paggamit mula sa mga provider API (GitHub Copilot quota, Antigravity model quota, Codex rate limits, Kiro usage breakdowns, Claude settings). | +| `accountSelector.ts` | Pagpili ng matalinong account na may algorithm ng pagmamarka: isinasaalang-alang ang priyoridad, katayuan sa kalusugan, posisyon ng round-robin, at estado ng cooldown upang piliin ang pinakamainam na account para sa bawat kahilingan. | +| `contextManager.ts` | Humiling ng pamamahala sa lifecycle ng konteksto: gumagawa at sumusubaybay ng mga object ng konteksto sa bawat kahilingan na may metadata (request ID, timestamp, impormasyon ng provider) para sa pag-debug at pag-log. | +| `ipFilter.ts` | IP-based na access control: sumusuporta sa allowlist at blocklist mode. Pinapatunayan ang IP ng kliyente laban sa mga na-configure na panuntunan bago iproseso ang mga kahilingan sa API. | +| `sessionManager.ts` | Pagsubaybay sa session gamit ang fingerprinting ng kliyente: sinusubaybayan ang mga aktibong session gamit ang mga na-hash na identifier ng kliyente, sinusubaybayan ang mga bilang ng kahilingan, at nagbibigay ng mga sukatan ng session. | +| `signatureCache.ts` | Humiling ng signature-based na deduplication cache: pinipigilan ang mga duplicate na kahilingan sa pamamagitan ng pag-cache ng mga kamakailang pirma ng kahilingan at pagbabalik ng mga naka-cache na tugon para sa magkaparehong mga kahilingan sa loob ng isang palugit ng oras. | +| `systemPrompt.ts` | Global system prompt injection: naghahanda o nagdaragdag ng isang nako-configure na prompt ng system sa lahat ng kahilingan, na may paghawak sa compatibility ng bawat provider. | +| `thinkingBudget.ts` | Pamamahala ng badyet ng token ng pangangatwiran: sumusuporta sa passthrough, auto (strip thinking config), custom (fixed budget), at adaptive (complexity-scaled) na mga mode para sa pagkontrol sa mga token ng pag-iisip/pangangatwiran. | +| `wildcardRouter.ts` | Pagruruta ng pattern ng wildcard na modelo: nire-resolba ang mga pattern ng wildcard (hal., `*/claude-*`) sa mga kongkretong pares ng provider/modelo batay sa availability at priyoridad. | + +#### Token Refresh Deduplication + +```mermaid +sequenceDiagram + participant R1 as Request 1 + participant R2 as Request 2 + participant Cache as refreshPromiseCache + participant OAuth as OAuth Provider + + R1->>Cache: getAccessToken("gemini", token) + Cache->>Cache: No in-flight promise + Cache->>OAuth: Start refresh + R2->>Cache: getAccessToken("gemini", token) + Cache->>Cache: Found in-flight promise + Cache-->>R2: Return existing promise + OAuth-->>Cache: New access token + Cache-->>R1: New access token + Cache-->>R2: Same access token (shared) + Cache->>Cache: Delete cache entry +``` + +#### Account Fallback State Machine + +```mermaid +stateDiagram-v2 + [*] --> Active + Active --> Error: Request fails (401/429/500) + Error --> Cooldown: Apply backoff + Cooldown --> Active: Cooldown expires + Active --> Active: Request succeeds (reset backoff) + + state Error { + [*] --> ClassifyError + ClassifyError --> ShouldFallback: Rate limit / Auth / Transient + ClassifyError --> NoFallback: 400 Bad Request + } + + state Cooldown { + [*] --> ExponentialBackoff + ExponentialBackoff: Level 0 = 1s + ExponentialBackoff: Level 1 = 2s + ExponentialBackoff: Level 2 = 4s + ExponentialBackoff: Max = 2min + } +``` + +#### Combo Model Chain + +```mermaid +flowchart LR + A["Request with\ncombo model"] --> B["Model A"] + B -->|"2xx Success"| C["Return response"] + B -->|"429/401/500"| D{"Fallback\neligible?"} + D -->|Yes| E["Model B"] + D -->|No| F["Return error"] + E -->|"2xx Success"| C + E -->|"429/401/500"| G{"Fallback\neligible?"} + G -->|Yes| H["Model C"] + G -->|No| F + H -->|"2xx Success"| C + H -->|"Fail"| I["All failed →\nReturn last status"] +``` + +--- + +### 4.5 Tagasalin (`open-sse/translator/`) + +Ang **format translation engine** gamit ang isang self-registering plugin system. + +#### Arkitektura + +```mermaid +graph TD + subgraph "Request Translation" + A["Claude → OpenAI"] + B["Gemini → OpenAI"] + C["Antigravity → OpenAI"] + D["OpenAI Responses → OpenAI"] + E["OpenAI → Claude"] + F["OpenAI → Gemini"] + G["OpenAI → Kiro"] + H["OpenAI → Cursor"] + end + + subgraph "Response Translation" + I["Claude → OpenAI"] + J["Gemini → OpenAI"] + K["Kiro → OpenAI"] + L["Cursor → OpenAI"] + M["OpenAI → Claude"] + N["OpenAI → Antigravity"] + O["OpenAI → Responses"] + end +``` + +| Direktoryo | Mga file | Paglalarawan | +| ------------ | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `request/` | 8 tagasalin | I-convert ang mga katawan ng kahilingan sa pagitan ng mga format. Ang bawat file ay nagrerehistro sa pamamagitan ng `register(from, to, fn)` sa pag-import. | +| `response/` | 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. | +| `helpers/` | 6 na katulong | Mga nakabahaging utilities: `claudeHelper` (system prompt extraction, thinking config), `geminiHelper` (parts/content mapping), `openaiHelper` (format filtering), `toolCallHelper` (ID generation, missing response injection), `toolCallHelper`, `toolCallHelper`8 | +| `index.ts` | — | Translation engine: `translateRequest()`, `translateResponse()`, pamamahala ng estado, pagpapatala. | +| `formats.ts` | — | Mga constant ng format: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | + +#### Pangunahing Disenyo: Self-Registering Plugin + +```javascript +// Each translator file calls register() on import: +import { register } from "../index.js"; +register("claude", "openai", translateClaudeToOpenAI); + +// The index.js imports all translator files, triggering registration: +import "./request/claude-to-openai.js"; // ← self-registers +``` + +--- + +### 4.6 Mga Util (`open-sse/utils/`) + +| 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` (buong format na pagsasalin) at `PASSTHROUGH` (normalize + 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 mababang antas ng SSE utilities: `parseSSELine` (whitespace-tolerant), `hasValuableContent` (filter ang mga walang laman na chunks para sa OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (format-aware na SSE_0K na serialization na may \_\_\_OMNI_EN4K). | +| `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`). Lumilikha 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 sinumang provider. Sinusuportahan ang parehong streaming at hindi streaming. Sinadyang 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 variable (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Sinusuportahan ang `NO_PROXY` na mga pagbubukod. Caches config para sa 30s. | + +#### SSE Streaming Pipeline + +```mermaid +flowchart TD + A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"] + B --> C["Buffer lines\n(split on newline)"] + C --> D["parseSSELine()\n(trim whitespace, parse JSON)"] + D --> E{"Mode?"} + E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"] + E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"] + F --> H["hasValuableContent()\nfilter empty chunks"] + G --> H + H -->|"Has content"| I["extractUsage()\ntrack token counts"] + H -->|"Empty"| J["Skip chunk"] + I --> K["formatSSE()\nserialize + clean perf_metrics"] + K --> L["TextEncoder\n(per-stream instance)"] + L --> M["Enqueue to\nclient stream"] + + style A fill:#f9f,stroke:#333 + style M fill:#9f9,stroke:#333 +``` + +#### Istraktura ng Session ng Logger ng Kahilingan + +``` +logs/ +└── claude_gemini_claude-sonnet_20260208_143045/ + ├── 1_req_client.json ← Raw client request + ├── 2_req_source.json ← After initial conversion + ├── 3_req_openai.json ← OpenAI intermediate format + ├── 4_req_target.json ← Final target format + ├── 5_res_provider.txt ← Provider SSE chunks (streaming) + ├── 5_res_provider.json ← Provider response (non-streaming) + ├── 6_res_openai.txt ← OpenAI intermediate chunks + ├── 7_res_client.txt ← Client-facing SSE chunks + └── 6_error.json ← Error details (if any) +``` + +--- + +### 4.7 Application Layer (`src/`) + +| 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 | + +#### Kapansin-pansing Mga Ruta ng API + +| Ruta | 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/settings/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/settings/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. Mga Pangunahing Pattern ng Disenyo + +### 5.1 Hub-and-Spoke Translation + +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 Pattern ng Estratehiya ng Tagapatupad + +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 + +Ang mga module ng tagasalin ay nagrerehistro sa kanilang 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 na may Exponential Backoff + +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 Chain + +Ang isang "combo" ay nagpapangkat ng maraming `provider/model` string. Kung nabigo ang una, awtomatikong mag-fallback sa susunod. + +### 5.6 Stateful Streaming Translation + +Ang pagsasalin ng tugon ay nagpapanatili ng estado sa mga bahagi ng SSE (pagsubaybay sa bloke ng pag-iisip, pag-iipon ng tawag sa tool, pag-index ng block ng nilalaman) sa pamamagitan ng mekanismong `initState()`. + +### 5.7 Buffer sa Kaligtasan sa Paggamit + +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. Mga Sinusuportahang Format + +| 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. Mga Sinusuportahang Provider + +| Provider | Paraan ng Pagpapatunay | Tagapagpatupad | Pangunahing Tala | +| ------------------------ | ---------------------- | -------------- | -------------------------------------------------------------- | +| Anthropic Claude | API key o OAuth | Default | Gumagamit ng `x-api-key` header | +| Google Gemini | API key o OAuth | Default | Gumagamit ng `x-goog-api-key` 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 | +| iFlow | 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. Buod ng Daloy ng Data + +### Kahilingan sa Pag-stream + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor\nbuildUrl + buildHeaders"] + D --> E["fetch(providerURL)"] + E --> F["createSSEStream()\nTRANSLATE mode"] + F --> G["parseSSELine()"] + G --> H["translateResponse()\ntarget → OpenAI → source"] + H --> I["extractUsage()\n+ addBuffer"] + I --> J["formatSSE()"] + J --> K["Client receives\ntranslated SSE"] + K --> L["logUsage()\nsaveRequestUsage()"] +``` + +### Kahilingan na Hindi Nag-stream + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor.execute()"] + D --> E["translateResponse()\ntarget → OpenAI → source"] + E --> F["Return JSON\nresponse"] +``` + +### Daloy ng Bypass (Claude CLI) + +```mermaid +flowchart LR + A["Claude CLI request"] --> B{"Match bypass\npattern?"} + B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"] + B -->|"No match"| D["Normal flow"] + C --> E["Translate to\nsource format"] + E --> F["Return without\ncalling provider"] +``` diff --git a/docs/i18n/phi/FEATURES.md b/docs/i18n/phi/FEATURES.md new file mode 100644 index 0000000000..fc155696c0 --- /dev/null +++ b/docs/i18n/phi/FEATURES.md @@ -0,0 +1,77 @@ +# OmniRoute — Dashboard Features Gallery + +🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md) + +Visual na gabay sa bawat seksyon ng OmniRoute dashboard. + +--- + +## 🔌 Mga Provider + +Pamahalaan ang mga koneksyon sa AI provider: OAuth provider (Claude Code, Codex, Gemini CLI), API key provider (Groq, DeepSeek, OpenRouter), at libreng provider (iFlow, Qwen, Kiro). + +![Providers Dashboard](screenshots/01-providers.png) + +--- + +## 🎨 Mga combo + +Gumawa ng mga combo sa pagruruta ng modelo na may 6 na diskarte: fill-first, round-robin, power-of-two-choices, random, hindi gaanong ginagamit, at cost-optimized. Ang bawat combo ay nagkakadena ng maraming modelo na may awtomatikong fallback. + +![Combos Dashboard](screenshots/02-combos.png) + +--- + +## 📊 Analytics + +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 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) + +--- + +## 🔧 Palaruan ng Tagasalin + +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) + +--- + +## ⚙️ Mga Setting + +Mga pangkalahatang setting, system storage, backup management (export/import database), hitsura (dark/light mode), seguridad (kasama ang API endpoint protection at custom provider blocking), routing, resilience, at advanced configuration. + +![Settings Dashboard](screenshots/06-settings.png) + +--- + +## 🔧 CLI Tools + +Isang-click na configuration para sa AI coding tool: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, at Antigravity. + +![CLI Tools Dashboard](screenshots/07-cli-tools.png) + +--- + +## 📝 Mga Log ng Kahilingan + +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) + +--- + +## 🌐 Endpoint ng API + +Ang iyong pinag-isang API endpoint na may breakdown ng kakayahan: Mga Pagkumpleto ng Chat, Mga Pag-embed, Pagbuo ng Imahe, Muling Ranggo, Transkripsyon ng Audio, at mga nakarehistrong API key. + +![Endpoint Dashboard](screenshots/09-endpoint.png) diff --git a/docs/i18n/phi/TROUBLESHOOTING.md b/docs/i18n/phi/TROUBLESHOOTING.md new file mode 100644 index 0000000000..f09d9d86d8 --- /dev/null +++ b/docs/i18n/phi/TROUBLESHOOTING.md @@ -0,0 +1,219 @@ +# Pag-troubleshoot + +🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md) + +Mga karaniwang problema at solusyon para sa OmniRoute. + +--- + +## Mabilis na Pag-aayos + +| Problema | Solusyon | +| ------------------------------------------------- | ---------------------------------------------------------------------------- | +| Unang login ay hindi gumagana | Lagyan ng check ang `INITIAL_PASSWORD` sa `.env` (default: `123456`) | +| 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 `logs/` | Itakda ang `ENABLE_REQUEST_LOGS=true` | +| EACCES: tinanggihan ang pahintulot | Itakda ang `DATA_DIR=/path/to/writable/dir` na 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) | + +--- + +## Mga Isyu sa Provider + +### "Ang modelo ng wika ay hindi nagbigay ng mga mensahe" + +**Sanhi:** Naubos na ang quota ng provider. + +**Ayusin:** + +1. Suriin ang dashboard quota tracker +2. Gumamit ng combo na may fallback tier +3. Lumipat sa mas mura/libreng tier + +### Paglilimita sa Rate + +**Dahil:** Naubos na ang quota ng subscription. + +**Ayusin:** + +- Magdagdag ng fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` +- Gamitin ang GLM/MiniMax bilang murang backup + +### Nag-expire na ang OAuth Token + +Ang OmniRoute ay awtomatikong nagre-refresh ng mga token. Kung magpapatuloy ang mga isyu: + +1. Dashboard → Provider → Kumonekta muli +2. Tanggalin at muling idagdag ang koneksyon ng provider + +--- + +## Mga Isyu sa Ulap + +### Mga Error sa Cloud Sync + +1. I-verify ang `BASE_URL` na mga puntos sa iyong running instance (hal., `http://localhost:20128`) +2. I-verify ang `CLOUD_URL` na mga 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` Nagbabalik ng 500 + +**Symptom:** `Unexpected token 'd'...` sa cloud endpoint para sa mga non-streaming na tawag. + +**Sanhi:** Ibinabalik ng Upstream ang SSE payload habang inaasahan ng kliyente ang 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 ngunit "Invalid API key" + +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 + +--- + +## Mga Isyu sa Docker + +### Hindi Naka-install ang Mga Palabas ng CLI Tool + +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 `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 `installed=true` at `runnable=false`: natagpuan ang binary ngunit nabigo ang healthcheck + +### Mabilis na Runtime Validation + +```bash +curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +``` + +--- + +## Mga Isyu sa Gastos + +### Mataas na Gastos + +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, iFlow) para sa mga hindi kritikal na gawain +4. Magtakda ng mga badyet sa gastos sa bawat API key: Dashboard → API Keys → Badyet + +--- + +## Pag-debug + +### Paganahin ang Mga Log ng Kahilingan + +Itakda ang `ENABLE_REQUEST_LOGS=true` sa iyong `.env` file. Lumilitaw ang mga log sa ilalim ng `logs/` na direktoryo. + +### Suriin ang Kalusugan ng Provider + +```bash +# Health dashboard +http://localhost:20128/dashboard/health + +# API health check +curl http://localhost:20128/api/monitoring/health +``` + +### Runtime Storage + +- Pangunahing estado: `${DATA_DIR}/db.json` (mga provider, combo, alias, key, setting) +- Paggamit: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- Mga log ng kahilingan: `/logs/...` (kapag `ENABLE_REQUEST_LOGS=true`) + +--- + +## Mga Isyu sa Circuit Breaker + +### Natigil ang provider sa OPEN na estado + +Kapag ang circuit breaker ng provider ay BUKAS, ang mga kahilingan ay hinaharangan hanggang sa mag-expire ang cooldown. + +**Ayusin:** + +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 + +### Patuloy na binabadtrip ng provider ang circuit breaker + +Kung ang isang provider ay paulit-ulit na pumasok sa OPEN state: + +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 + +--- + +## Mga Isyu sa Transkripsyon ng Audio + +### Error sa "Hindi sinusuportahang modelo." + +- Tiyaking ginagamit mo ang tamang prefix: `deepgram/nova-3` o `assemblyai/best` +- I-verify na konektado ang provider sa **Dashboard → Mga Provider** + +### Nagbabalik ang transkripsyon na walang laman o nabigo + +- 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 + +--- + +## Pag-debug ng Tagasalin + +Gamitin ang **Dashboard → Translator** upang i-debug ang mga isyu sa pagsasalin ng format: + +| 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 | + +### Mga karaniwang isyu sa format + +- **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 hilaw na 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 `system` na tungkulin** — 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 +- **`developer` tungkulin ay hindi nakilala** — Naayos sa v1.1.0: awtomatikong na-convert sa `system` para sa mga hindi OpenAI na provider +- **`json_schema` hindi gumagana sa Gemini** — Naayos sa v1.1.0: `response_format` ay na-convert na ngayon sa Gemini's `responseMimeType` + `responseSchema` + +--- + +## Mga Setting ng Katatagan + +### Hindi nagti-trigger ang limitasyon ng awtomatikong rate + +- 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 ibinabalik ng provider ang `429` status code o `Retry-After` header + +### Pag-tune ng exponential backoff + +Sinusuportahan ng mga profile ng provider ang mga setting na ito: + +- **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-kulog na kawan + +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. + +--- + +## Natigil pa rin? + +- **Mga Isyu sa GitHub**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) +- **Arkitektura**: Tingnan ang [**OMNI_TOKEN_55**](ARCHITECTURE.md) para sa mga panloob na detalye +- **API Reference**: Tingnan ang [**OMNI_TOKEN_56**](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 diff --git a/docs/i18n/phi/USER_GUIDE.md b/docs/i18n/phi/USER_GUIDE.md new file mode 100644 index 0000000000..6c924a5de8 --- /dev/null +++ b/docs/i18n/phi/USER_GUIDE.md @@ -0,0 +1,698 @@ +# Gabay sa Gumagamit + +🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md) + +Kumpletong gabay para sa pag-configure ng mga provider, paggawa ng mga combo, pagsasama ng mga tool sa CLI, at pag-deploy ng OmniRoute. + +--- + +## Talaan ng mga Nilalaman + +- [Pricing at a Glance](#-pricing-at-a-glance) +- [Use Cases](#-use-cases) +- [Provider Setup](#-provider-setup) +- [CLI Integration](#-cli-integration) +- [Deployment](#-deployment) +- [Available Models](#-available-models) +- [Advanced Features](#-advanced-features) + +--- + +## 💰 Pagpepresyo sa isang Sulyap + +| Tier | Provider | Gastos | I-reset ang Quota | Pinakamahusay Para sa | +| ------------------- | ----------------- | -------------------------- | -------------------- | ------------------------------ | +| **💳 SUBSCRIPTION** | Claude Code (Pro) | $20/buwan | 5h + lingguhan | Naka-subscribe na | +| | Codex (Plus/Pro) | $20-200/buwan | 5h + lingguhan | Mga user ng OpenAI | +| | Gemini CLI | **LIBRE** | 180K/buwan + 1K/araw | Lahat! | +| | GitHub Copilot | $10-19/buwan | Buwanang | Mga user ng GitHub | +| **🔑 API KEY** | DeepSeek | Magbayad sa bawat paggamit | Wala | Murang pangangatwiran | +| | Groq | Magbayad sa bawat paggamit | Wala | Napakabilis na hinuha | +| | xAI (Grok) | Magbayad sa bawat paggamit | Wala | Grok 4 na pangangatwiran | +| | Mistral | Magbayad sa bawat paggamit | Wala | Mga modelong naka-host sa EU | +| | Pagkagulo | Magbayad sa bawat paggamit | Wala | Search-augmented | +| | Magkasama AI | Magbayad sa bawat paggamit | Wala | Open-source na mga modelo | +| | Fireworks AI | Magbayad sa bawat paggamit | Wala | Mabilis na FLUX na mga larawan | +| | Cerebras | Magbayad sa bawat paggamit | Wala | Wafer-scale na bilis | +| | Cohere | Magbayad sa bawat paggamit | Wala | Command R+ RAG | +| | NVIDIA NIM | Magbayad sa bawat paggamit | Wala | Mga modelo ng enterprise | +| **💰 MURA** | GLM-4.7 | $0.6/1M | Araw-araw 10AM | Backup ng badyet | +| | MiniMax M2.1 | $0.2/1M | 5 oras na rolling | Pinaka murang opsyon | +| | Kimi K2 | $9/buwan flat | 10M token/buwan | Nahuhulaang gastos | +| **🆓 LIBRE** | iFlow | $0 | Walang limitasyong | 8 mga modelong libre | +| | Qwen | $0 | Walang limitasyong | 3 mga modelong libre | +| | Kiro | $0 | Walang limitasyong | Claude libre | + +**💡 Pro Tip:** Magsimula sa Gemini CLI (180K libre/buwan) + iFlow (walang limitasyong libre) combo = $0 na halaga! + +--- + +## 🎯 Use Cases + +### Case 1: "May subscription ako sa Claude Pro" + +**Problema:** Nag-e-expire ang quota nang hindi nagamit, mga limitasyon sa rate sa panahon ng mabigat na coding + +``` +Combo: "maximize-claude" + 1. cc/claude-opus-4-6 (use subscription fully) + 2. glm/glm-4.7 (cheap backup when quota out) + 3. if/kimi-k2-thinking (free emergency fallback) + +Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total +vs. $20 + hitting limits = frustration +``` + +### Case 2: "Gusto ko ng zero cost" + +**Problema:** Hindi kayang bayaran ang mga subscription, kailangan ng maaasahang AI coding + +``` +Combo: "free-forever" + 1. gc/gemini-3-flash (180K free/month) + 2. if/kimi-k2-thinking (unlimited free) + 3. qw/qwen3-coder-plus (unlimited free) + +Monthly cost: $0 +Quality: Production-ready models +``` + +### Case 3: "Kailangan ko ng 24/7 coding, walang mga pagkaantala" + +**Problema:** Mga deadline, hindi kayang bayaran ang downtime + +``` +Combo: "always-on" + 1. cc/claude-opus-4-6 (best quality) + 2. cx/gpt-5.2-codex (second subscription) + 3. glm/glm-4.7 (cheap, resets daily) + 4. minimax/MiniMax-M2.1 (cheapest, 5h reset) + 5. if/kimi-k2-thinking (free unlimited) + +Result: 5 layers of fallback = zero downtime +Monthly cost: $20-200 (subscriptions) + $10-20 (backup) +``` + +### Kaso 4: "Gusto ko ng LIBRENG AI sa OpenClaw" + +**Problema:** Kailangan ng AI assistant sa mga app sa pagmemensahe, ganap na libre + +``` +Combo: "openclaw-free" + 1. if/glm-4.7 (unlimited free) + 2. if/minimax-m2.1 (unlimited free) + 3. if/kimi-k2-thinking (unlimited free) + +Monthly cost: $0 +Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal... +``` + +--- + +## 📖 Setup ng Provider + +### 🔐 Mga Tagabigay ng Subscription + +#### Claude Code (Pro/Max) + +```bash +Dashboard → Providers → Connect Claude Code +→ OAuth login → Auto token refresh +→ 5-hour + weekly quota tracking + +Models: + cc/claude-opus-4-6 + cc/claude-sonnet-4-5-20250929 + cc/claude-haiku-4-5-20251001 +``` + +**Pro Tip:** Gamitin ang Opus para sa mga kumplikadong gawain, Soneto para sa bilis. Sinusubaybayan ng OmniRoute ang quota bawat modelo! + +#### OpenAI Codex (Plus/Pro) + +```bash +Dashboard → Providers → Connect Codex +→ OAuth login (port 1455) +→ 5-hour + weekly reset + +Models: + cx/gpt-5.2-codex + cx/gpt-5.1-codex-max +``` + +#### Gemini CLI (LIBRE 180K/buwan!) + +```bash +Dashboard → Providers → Connect Gemini CLI +→ Google OAuth +→ 180K completions/month + 1K/day + +Models: + gc/gemini-3-flash-preview + gc/gemini-2.5-pro +``` + +**Pinakamahusay na Halaga:** Malaking libreng tier! Gamitin ito bago ang mga bayad na tier. + +#### GitHub Copilot + +```bash +Dashboard → Providers → Connect GitHub +→ OAuth via GitHub +→ Monthly reset (1st of month) + +Models: + gh/gpt-5 + gh/claude-4.5-sonnet + gh/gemini-3-pro +``` + +### 💰 Mga Murang Provider + +#### GLM-4.7 (Araw-araw na pag-reset, $0.6/1M) + +1. Mag-sign up: [Zhipu AI](https://open.bigmodel.cn/) +2. Kumuha ng API key mula sa Coding Plan +3. Dashboard → Magdagdag ng API Key: Provider: `glm`, API Key: `your-key` + +**Gamitin:** `glm/glm-4.7` — **Pro Tip:** Nag-aalok ang Coding Plan ng 3× na quota sa 1/7 na halaga! I-reset araw-araw 10:00 AM. + +#### MiniMax M2.1 (5h reset, $0.20/1M) + +1. Mag-sign up: [MiniMax](https://www.minimax.io/) +2. Kunin ang API key → Dashboard → Magdagdag ng API Key + +**Gamitin:** `minimax/MiniMax-M2.1` — **Pro Tip:** Pinakamamurang opsyon para sa mahabang konteksto (1M token)! + +#### Kimi K2 ($9/month flat) + +1. Mag-subscribe: [Moonshot AI](https://platform.moonshot.ai/) +2. Kunin ang API key → Dashboard → Magdagdag ng API Key + +**Gamitin:** `kimi/kimi-latest` — **Pro Tip:** Nakapirming $9/buwan para sa 10M token = $0.90/1M epektibong gastos! + +### 🆓 LIBRENG Provider + +#### iFlow (8 LIBRENG modelo) + +```bash +Dashboard → Connect iFlow → OAuth login → Unlimited usage + +Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1 +``` + +#### Qwen (3 LIBRENG modelo) + +```bash +Dashboard → Connect Qwen → Device code auth → Unlimited usage + +Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash +``` + +#### Kiro (Claude LIBRE) + +```bash +Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited + +Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5 +``` + +--- + +## 🎨 Mga combo + +### Halimbawa 1: I-maximize ang Subscription → Murang Backup + +``` +Dashboard → Combos → Create New + +Name: premium-coding +Models: + 1. cc/claude-opus-4-6 (Subscription primary) + 2. glm/glm-4.7 (Cheap backup, $0.6/1M) + 3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M) + +Use in CLI: premium-coding +``` + +### Halimbawa 2: Libre-Lamang (Zero na Gastos) + +``` +Name: free-combo +Models: + 1. gc/gemini-3-flash-preview (180K free/month) + 2. if/kimi-k2-thinking (unlimited) + 3. qw/qwen3-coder-plus (unlimited) + +Cost: $0 forever! +``` + +--- + +## 🔧 Pagsasama ng CLI + +### Cursor IDE + +``` +Settings → Models → Advanced: + OpenAI API Base URL: http://localhost:20128/v1 + OpenAI API Key: [from omniroute dashboard] + Model: cc/claude-opus-4-6 +``` + +### Claude Code + +I-edit ang `~/.claude/config.json`: + +```json +{ + "anthropic_api_base": "http://localhost:20128/v1", + "anthropic_api_key": "your-omniroute-api-key" +} +``` + +### Codex CLI + +```bash +export OPENAI_BASE_URL="http://localhost:20128" +export OPENAI_API_KEY="your-omniroute-api-key" +codex "your prompt" +``` + +### OpenClaw + +I-edit ang `~/.openclaw/openclaw.json`: + +```json +{ + "agents": { + "defaults": { + "model": { "primary": "omniroute/if/glm-4.7" } + } + }, + "models": { + "providers": { + "omniroute": { + "baseUrl": "http://localhost:20128/v1", + "apiKey": "your-omniroute-api-key", + "api": "openai-completions", + "models": [{ "id": "if/glm-4.7", "name": "glm-4.7" }] + } + } + } +} +``` + +**O gumamit ng Dashboard:** CLI Tools → OpenClaw → Auto-config + +### Cline / Magpatuloy / RooCode + +``` +Provider: OpenAI Compatible +Base URL: http://localhost:20128/v1 +API Key: [from dashboard] +Model: cc/claude-opus-4-6 +``` + +--- + +## 🚀 Deployment + +### VPS Deployment + +```bash +git clone https://github.com/diegosouzapw/OmniRoute.git +cd OmniRoute && npm install && npm run build + +export JWT_SECRET="your-secure-secret-change-this" +export INITIAL_PASSWORD="your-password" +export DATA_DIR="/var/lib/omniroute" +export PORT="20128" +export HOSTNAME="0.0.0.0" +export NODE_ENV="production" +export NEXT_PUBLIC_BASE_URL="http://localhost:20128" +export API_KEY_SECRET="endpoint-proxy-api-key-secret" + +npm run start +# Or: pm2 start npm --name omniroute -- start +``` + +### Docker + +```bash +# Build image (default = runner-cli with codex/claude/droid preinstalled) +docker build -t omniroute:cli . + +# Portable mode (recommended) +docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli +``` + +Para sa host-integrated mode na may mga CLI binary, tingnan ang seksyong Docker sa mga pangunahing doc. + +### Mga Variable ng Environment + +| Variable | Default | Paglalarawan | +| --------------------- | ------------------------------------ | ------------------------------------------------------------------ | +| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signing secret (**pagbabago sa produksyon**) | +| `INITIAL_PASSWORD` | `123456` | Unang login password | +| `DATA_DIR` | `~/.omniroute` | Direktoryo ng data (db, paggamit, mga log) | +| `PORT` | default na framework | Port ng serbisyo (`20128` sa mga halimbawa) | +| `HOSTNAME` | default na framework | Bind host (Docker default sa `0.0.0.0`) | +| `NODE_ENV` | default na runtime | Itakda ang `production` para sa pag-deploy | +| `BASE_URL` | `http://localhost:20128` | Panloob na base URL sa gilid ng server | +| `CLOUD_URL` | `https://omniroute.dev` | Cloud sync endpoint base URL | +| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC secret para sa mga nabuong API key | +| `REQUIRE_API_KEY` | `false` | Ipatupad ang Bearer API key sa `/v1/*` | +| `ENABLE_REQUEST_LOGS` | `false` | Pinapagana ang mga log ng kahilingan/tugon | +| `AUTH_COOKIE_SECURE` | `false` | Pilitin ang `Secure` auth cookie (sa likod ng HTTPS reverse proxy) | + +Para sa buong environment variable reference, tingnan ang [README](../README.md). + +--- + +## 📊 Mga Magagamit na Modelo + +
+Tingnan ang lahat ng available na modelo + +**Claude Code (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001` + +**Codex (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max` + +**Gemini CLI (`gc/`)** — LIBRE: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro` + +**GitHub Copilot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet` + +**GLM (`glm/`)** — $0.6/1M: `glm/glm-4.7` + +**MiniMax (`minimax/`)** — $0.2/1M: `minimax/MiniMax-M2.1` + +**iFlow (`if/`)** — LIBRE: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1` + +**Qwen (`qw/`)** — LIBRE: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash` + +**Kiro (`kr/`)** — LIBRE: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5` + +**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner` + +**Groq (`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct` + +**xAI (`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini` + +**Mistral (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501` + +**Pagkakagulo (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar` + +**Magkasama AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo` + +**Fireworks AI (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1` + +**Cerebras (`cerebras/`)**: `cerebras/llama-3.3-70b` + +**Cohere (`cohere/`)**: `cohere/command-r-plus-08-2024` + +**NVIDIA NIM (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct` + +
+ +--- + +## 🧩 Mga Advanced na Tampok + +### Mga Custom na Modelo + +Magdagdag ng anumang ID ng modelo sa anumang provider nang hindi naghihintay ng update ng app: + +```bash +# Via API +curl -X POST http://localhost:20128/api/provider-models \ + -H "Content-Type: application/json" \ + -d '{"provider": "openai", "modelId": "gpt-4.5-preview", "modelName": "GPT-4.5 Preview"}' + +# List: curl http://localhost:20128/api/provider-models?provider=openai +# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview" +``` + +O gamitin ang Dashboard: **Mga Provider → [Provider] → Mga Custom na Modelo**. + +### Nakalaang Mga Ruta ng Provider + +Direktang iruta ang mga kahilingan sa isang partikular na provider na may pagpapatunay ng modelo: + +```bash +POST http://localhost:20128/v1/providers/openai/chat/completions +POST http://localhost:20128/v1/providers/openai/embeddings +POST http://localhost:20128/v1/providers/fireworks/images/generations +``` + +Ang prefix ng provider ay awtomatikong idinaragdag kung nawawala. Ang mga hindi tugmang modelo ay nagbabalik ng `400`. + +### Network Proxy Configuration + +```bash +# Set global proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"global": {"type":"http","host":"proxy.example.com","port":"8080"}}' + +# Per-provider proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"providers": {"openai": {"type":"socks5","host":"proxy.example.com","port":"1080"}}}' + +# Test proxy +curl -X POST http://localhost:20128/api/settings/proxy/test \ + -d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}' +``` + +**Precedence:** Key-specific → Combo-specific → Provider-specific → Global → Environment. + +### Model Catalog API + +```bash +curl http://localhost:20128/api/models/catalog +``` + +Ibinabalik ang mga modelong nakapangkat ayon sa provider na may mga uri (`chat`, `embedding`, `image`). + +### Cloud Sync + +- I-sync ang mga provider, combo, at mga setting sa mga device +- Awtomatikong pag-sync sa background na may timeout + mabilis na mabibigo +- Mas gusto ang server-side `BASE_URL`/`CLOUD_URL` sa produksyon + +### LLM Gateway Intelligence (Phase 9) + +- **Semantic Cache** — Auto-cache non-streaming, temperature=0 na tugon (bypass gamit ang `X-OmniRoute-No-Cache: true`) +- **Request Idempotency** — Nagde-deduplicate ng mga kahilingan sa loob ng 5s sa pamamagitan ng `Idempotency-Key` o `X-Request-Id` header +- **Pagsubaybay sa Pag-unlad** — Mag-opt-in sa SSE `event: progress` na mga kaganapan sa pamamagitan ng `X-OmniRoute-Progress: true` header + +--- + +### Palaruan ng Tagasalin + +Access sa pamamagitan ng **Dashboard → Translator**. I-debug at i-visualize kung paano isinasalin ng OmniRoute ang mga kahilingan sa API sa pagitan ng mga provider. + +| Mode | Layunin | +| ---------------- | ----------------------------------------------------------------------------------------------------------------- | +| **Laruan** | Pumili ng pinagmulan/target na mga format, i-paste ang isang kahilingan, at makita agad ang isinaling output | +| **Chat Tester** | Magpadala ng mga mensahe sa live chat sa pamamagitan ng proxy at siyasatin ang buong cycle ng kahilingan/pagtugon | +| **Test Bench** | Magpatakbo ng mga batch test sa maraming kumbinasyon ng format upang i-verify ang kawastuhan ng pagsasalin | +| **Live Monitor** | Manood ng mga real-time na pagsasalin habang dumadaloy ang mga kahilingan sa pamamagitan ng proxy | + +**Mga kaso ng paggamit:** + +- I-debug kung bakit nabigo ang isang partikular na kumbinasyon ng kliyente/provider +- I-verify na ang mga tag ng pag-iisip, mga tawag sa tool, at mga prompt ng system ay naisalin nang tama +- Ihambing ang mga pagkakaiba sa format sa pagitan ng mga format ng OpenAI, Claude, Gemini, at Responses API + +--- + +### Mga Istratehiya sa Pagruruta + +I-configure sa pamamagitan ng **Dashboard → Mga Setting → Pagruruta**. + +| Diskarte | Paglalarawan | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Punan muna** | Gumagamit ng mga account sa pagkakasunud-sunod ng priyoridad — pinangangasiwaan ng pangunahing account ang lahat ng kahilingan hanggang sa hindi magamit | +| **Round Robin** | Umiikot sa lahat ng account na may na-configure na malagkit na limitasyon (default: 3 tawag sa bawat account) | +| **P2C (Power of Two Choices)** | Pumili ng 2 random na account at ruta patungo sa mas malusog — binabalanse ang load nang may kamalayan sa kalusugan | +| **Random** | Random na pumipili ng account para sa bawat kahilingan gamit ang Fisher-Yates shuffle | +| **Hindi gaanong Nagamit** | Mga ruta patungo sa account na may pinakamatandang `lastUsedAt` timestamp, na namamahagi ng trapiko nang pantay-pantay | +| **Na-optimize ang Gastos** | Mga ruta patungo sa account na may pinakamababang halaga ng priyoridad, na nag-o-optimize para sa mga provider na may pinakamababang halaga | + +#### Mga Alyas ng Modelong Wildcard + +Lumikha ng mga pattern ng wildcard upang i-remap ang mga pangalan ng modelo: + +``` +Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929 +Pattern: gpt-* → Target: gh/gpt-5.1-codex +``` + +Sinusuportahan ng mga wildcard ang `*` (anumang character) at `?` (solong character). + +#### Fallback Chain + +Tukuyin ang mga pandaigdigang fallback chain na nalalapat sa lahat ng kahilingan: + +``` +Chain: production-fallback + 1. cc/claude-opus-4-6 + 2. gh/gpt-5.1-codex + 3. glm/glm-4.7 +``` + +--- + +### Resilience at Circuit Breaker + +I-configure sa pamamagitan ng **Dashboard → Mga Setting → Resilience**. + +Ang OmniRoute ay nagpapatupad ng pagiging matatag sa antas ng provider na may apat na bahagi: + +1. **Provider Profile** — Configuration ng bawat provider para sa: + - Failure threshold (ilang pagkabigo bago buksan) + - Tagal ng cooldown + - Rate limit detection sensitivity + - Exponential backoff na mga parameter + +2. **Editable Rate Limits** — System-level defaults configurable sa dashboard: + - **Requests Per Minute (RPM)** — Mga maximum na kahilingan kada minuto bawat account + - **Min Time Between Requests** — Minimum na agwat sa millisecond sa pagitan ng mga kahilingan + - **Max Kasabay na Kahilingan** — Pinakamataas na sabay-sabay na kahilingan sa bawat account + - I-click ang **I-edit** upang baguhin, pagkatapos ay **I-save** o **Kanselahin**. Nananatili ang mga halaga sa pamamagitan ng resilience API. + +3. **Circuit Breaker** — Sinusubaybayan ang mga pagkabigo sa bawat provider at awtomatikong bubuksan ang circuit kapag naabot ang isang threshold: + - **SARADO** (Healthy) — Normal na dumadaloy ang mga kahilingan + - **OPEN** — Pansamantalang naka-block ang provider pagkatapos ng paulit-ulit na pagkabigo + - **HALF_OPEN** — Pagsubok kung nakabawi na ang provider + +4. **Mga Patakaran at Mga Naka-lock na Identifier** — Nagpapakita ng status ng circuit breaker at mga naka-lock na identifier na may kakayahan sa force-unlock. + +5. **Awtomatikong Pagtukoy sa Limitasyon ng Rate** — Sinusubaybayan ang `429` at `Retry-After` na mga header upang aktibong maiwasang maabot ang mga limitasyon sa rate ng provider. + +**Pro Tip:** Gamitin ang **I-reset Lahat** na button para i-clear ang lahat ng mga circuit breaker at cooldown kapag gumaling ang isang provider mula sa isang outage. + +--- + +### Pag-export / Pag-import ng Database + +Pamahalaan ang mga backup ng database sa **Dashboard → Mga Setting → System at Storage**. + +| Aksyon | Paglalarawan | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **I-export ang Database** | Dina-download ang kasalukuyang database ng SQLite bilang isang `.sqlite` file | +| **I-export Lahat (.tar.gz)** | Nagda-download ng buong backup na archive kabilang ang: database, mga setting, combo, mga koneksyon sa provider (walang mga kredensyal), metadata ng API key | +| **Import Database** | Mag-upload ng `.sqlite` file upang palitan ang kasalukuyang database. Awtomatikong nagagawa ang isang pre-import na backup | + +```bash +# API: Export database +curl -o backup.sqlite http://localhost:20128/api/db-backups/export + +# API: Export all (full archive) +curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll + +# API: Import database +curl -X POST http://localhost:20128/api/db-backups/import \ + -F "file=@backup.sqlite" +``` + +**Import Validation:** Ang na-import na file ay napatunayan para sa integridad (SQLite pragma check), kinakailangang mga talahanayan (`provider_connections`, `provider_nodes`, `combos`, `api_keys`), at laki (max 100MB). + +**Mga Kaso ng Paggamit:** + +- I-migrate ang OmniRoute sa pagitan ng mga machine +- Lumikha ng mga panlabas na backup para sa pagbawi ng kalamidad +- Magbahagi ng mga pagsasaayos sa pagitan ng mga miyembro ng koponan (i-export lahat → ibahagi ang archive) + +--- + +### Dashboard ng Mga Setting + +Ang pahina ng mga setting ay isinaayos sa 5 tab para sa madaling pag-navigate: + +| Tab | Mga Nilalaman | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| **Seguridad** | Mga setting ng Login/Password, IP Access Control, API auth para sa `/models`, at Provider Blocking | +| **Pagruruta** | Pandaigdigang diskarte sa pagruruta (6 na opsyon), wildcard model alias, fallback chain, combo default | +| **Katatagan** | Mga profile ng provider, mga limitasyon sa nae-edit na rate, status ng circuit breaker, mga patakaran at mga naka-lock na identifier | +| **AI** | Pag-iisip ng configuration ng badyet, pandaigdigang system prompt injection, prompt cache stats | +| **Advanced** | Global proxy configuration (HTTP/SOCKS5) | + +--- + +### Pamamahala ng Mga Gastos at Badyet + +Access sa pamamagitan ng **Dashboard → Mga Gastos**. + +| Tab | Layunin | +| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| **Badyet** | Magtakda ng mga limitasyon sa paggastos sa bawat API key na may pang-araw-araw/lingguhan/buwanang mga badyet at real-time na pagsubaybay | +| **Pagpepresyo** | Tingnan at i-edit ang mga entry sa pagpepresyo ng modelo — cost per 1K input/output token bawat provider | + +```bash +# API: Set a budget +curl -X POST http://localhost:20128/api/usage/budget \ + -H "Content-Type: application/json" \ + -d '{"keyId": "key-123", "limit": 50.00, "period": "monthly"}' + +# API: Get current budget status +curl http://localhost:20128/api/usage/budget +``` + +**Pagsubaybay sa Gastos:** Ang bawat kahilingan ay nagtatala ng paggamit ng token at kinakalkula ang gastos gamit ang talahanayan ng pagpepresyo. Tingnan ang mga breakdown sa **Dashboard → Paggamit** ayon sa provider, modelo, at API key. + +--- + +### Transkripsyon ng Audio + +Sinusuportahan ng OmniRoute ang audio transcription sa pamamagitan ng OpenAI-compatible na endpoint: + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data + +# Example with curl +curl -X POST http://localhost:20128/v1/audio/transcriptions \ + -H "Authorization: Bearer your-api-key" \ + -F "file=@audio.mp3" \ + -F "model=deepgram/nova-3" +``` + +Mga available na provider: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`). + +Mga sinusuportahang format ng audio: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +### Mga Diskarte sa Pagbalanse ng Combo + +I-configure ang per-combo balancing sa **Dashboard → Combos → Create/Edit → Strategy**. + +| Diskarte | Paglalarawan | +| ------------------------- | -------------------------------------------------------------------------------------------------- | +| **Round-Robin** | Umiikot sa mga modelo nang sunud-sunod | +| **Priyoridad** | Palaging sinusubukan ang unang modelo; bumabalik lamang sa error | +| **Random** | Pumipili ng random na modelo mula sa combo para sa bawat kahilingan | +| **Tinimbang** | Mga rutang proporsyonal batay sa mga nakatalagang timbang sa bawat modelo | +| **Hindi gaanong Nagamit** | Mga ruta patungo sa modelo na may kaunting mga kamakailang kahilingan (gumagamit ng combo metrics) | +| **Cost-Optimized** | Mga ruta patungo sa pinakamurang available na modelo (gumagamit ng talahanayan ng pagpepresyo) | + +Maaaring itakda ang mga global combo default sa **Dashboard → Settings → Routing → Combo Defaults**. + +--- + +### Health Dashboard + +Access sa pamamagitan ng **Dashboard → Health**. Real-time na pangkalahatang-ideya ng kalusugan ng system na may 6 na card: + +| Card | Ano ang Ipinakikita Nito | +| -------------------------- | ----------------------------------------------------------------------------------- | +| **System Status** | Uptime, bersyon, paggamit ng memorya, direktoryo ng data | +| **Kalusugan ng Provider** | Status ng circuit breaker ng bawat provider (Sarado/Bukas/Kalahating Bukas) | +| **Mga Limitasyon sa Rate** | Mga cooldown sa limitasyon ng aktibong rate sa bawat account na may natitirang oras | +| **Mga Aktibong Lockout** | Pansamantalang na-block ang mga provider ng patakaran sa lockout | +| **Signature Cache** | Deduplication cache stats (aktibong key, hit rate) | +| **Latency Telemetry** | p50/p95/p99 latency aggregation bawat provider | + +**Pro Tip:** Awtomatikong nagre-refresh ang page ng Health bawat 10 segundo. Gamitin ang circuit breaker card upang matukoy kung aling mga provider ang nakakaranas ng mga isyu. diff --git a/docs/i18n/pl/API_REFERENCE.md b/docs/i18n/pl/API_REFERENCE.md new file mode 100644 index 0000000000..5bdf59b848 --- /dev/null +++ b/docs/i18n/pl/API_REFERENCE.md @@ -0,0 +1,441 @@ +# Dokumentacja API + +🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md) + +Pełna dokumentacja dla wszystkich punktów końcowych API OmniRoute. + +--- + +## Spis treści + +- [Chat Completions](#chat-completions) +- [Embeddings](#embeddings) +- [Image Generation](#image-generation) +- [List Models](#list-models) +- [Compatibility Endpoints](#compatibility-endpoints) +- [Semantic Cache](#semantic-cache) +- [Dashboard & Management](#dashboard--management) +- [Request Processing](#request-processing) +- [Authentication](#authentication) + +--- + +## Zakończenie czatu + +```bash +POST /v1/chat/completions +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "cc/claude-opus-4-6", + "messages": [ + {"role": "user", "content": "Write a function to..."} + ], + "stream": true +} +``` + +### Niestandardowe nagłówki + +| Nagłówek | Kierunek | Opis | +| ------------------------ | --------- | ------------------------------------------------- | +| `X-OmniRoute-No-Cache` | Prośba | Ustaw na `true`, aby ominąć pamięć podręczną | +| `X-OmniRoute-Progress` | Prośba | Ustaw na `true` dla zdarzeń postępu | +| `Idempotency-Key` | Prośba | Klucz deduplikacji (okno 5s) | +| `X-Request-Id` | Prośba | Alternatywny klucz deduplikacji | +| `X-OmniRoute-Cache` | Odpowiedź | `HIT` lub `MISS` (bez przesyłania strumieniowego) | +| `X-OmniRoute-Idempotent` | Odpowiedź | `true` w przypadku deduplikacji | +| `X-OmniRoute-Progress` | Odpowiedź | `enabled`, jeśli śledzenie postępu | + +--- + +## Osadzenia + +```bash +POST /v1/embeddings +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "nebius/Qwen/Qwen3-Embedding-8B", + "input": "The food was delicious" +} +``` + +Dostępni dostawcy: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA. + +```bash +# List all embedding models +GET /v1/embeddings +``` + +--- + +## Generowanie obrazu + +```bash +POST /v1/images/generations +Authorization: Bearer your-api-key +Content-Type: application/json + +{ + "model": "openai/dall-e-3", + "prompt": "A beautiful sunset over mountains", + "size": "1024x1024" +} +``` + +Dostępni dostawcy: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI. + +```bash +# List all image models +GET /v1/images/generations +``` + +--- + +## Lista modeli + +```bash +GET /v1/models +Authorization: Bearer your-api-key + +→ Returns all chat, embedding, and image models + combos in OpenAI format +``` + +--- + +## Punkty końcowe zgodności + +| Metoda | Ścieżka | Formatuj | +| -------- | --------------------------- | ---------------------------- | +| POST | `/v1/chat/completions` | OpenAI | +| POST | `/v1/messages` | Antropiczny | +| POST | `/v1/responses` | Odpowiedzi OpenAI | +| POST | `/v1/embeddings` | OpenAI | +| POST | `/v1/images/generations` | OpenAI | +| OTRZYMAJ | `/v1/models` | OpenAI | +| POST | `/v1/messages/count_tokens` | Antropiczny | +| OTRZYMAJ | `/v1beta/models` | Bliźnięta | +| POST | `/v1beta/models/{...path}` | Bliźnięta generują zawartość | +| POST | `/v1/api/chat` | Ollama | + +### Dedykowane trasy dostawców + +```bash +POST /v1/providers/{provider}/chat/completions +POST /v1/providers/{provider}/embeddings +POST /v1/providers/{provider}/images/generations +``` + +Prefiks dostawcy jest dodawany automatycznie, jeśli go brakuje. Niedopasowane modele zwracają `400`. + +--- + +## Pamięć podręczna semantyczna + +```bash +# Get cache stats +GET /api/cache + +# Clear all caches +DELETE /api/cache +``` + +Przykład odpowiedzi: + +```json +{ + "semanticCache": { + "memorySize": 42, + "memoryMaxSize": 500, + "dbSize": 128, + "hitRate": 0.65 + }, + "idempotency": { + "activeKeys": 3, + "windowMs": 5000 + } +} +``` + +--- + +## Panel i zarządzanie + +### Uwierzytelnianie + +| Punkt końcowy | Metoda | Opis | +| ----------------------------- | ------------- | --------------------------- | +| `/api/auth/login` | POST | Zaloguj | +| `/api/auth/logout` | POST | Wyloguj | +| `/api/settings/require-login` | POBIERZ/WSTAW | Przełącz wymagane logowanie | + +### Zarządzanie dostawcami + +| Punkt końcowy | Metoda | Opis | +| ---------------------------- | ----------------- | ----------------------------- | +| `/api/providers` | POBIERZ/WYŚLIJ | Lista / tworzenie dostawców | +| `/api/providers/[id]` | POBIERZ/PUT/USUŃ | Zarządzaj dostawcą | +| `/api/providers/[id]/test` | POST | Połączenie z dostawcą testów | +| `/api/providers/[id]/models` | OTRZYMAJ | Lista modeli dostawców | +| `/api/providers/validate` | POST | Sprawdź konfigurację dostawcy | +| `/api/provider-nodes*` | Różne | Zarządzanie węzłami dostawcy | +| `/api/provider-models` | POBIERZ/POST/USUŃ | Modele niestandardowe | + +### Przepływy OAuth + +| Punkt końcowy | Metoda | Opis | +| -------------------------------- | ------ | ------------------------------ | +| `/api/oauth/[provider]/[action]` | Różne | OAuth specyficzne dla dostawcy | + +### Routing i konfiguracja + +| Punkt końcowy | Metoda | Opis | +| --------------------- | -------------- | -------------------------------------- | +| `/api/models/alias` | POBIERZ/WYŚLIJ | Aliasy modeli | +| `/api/models/catalog` | OTRZYMAJ | Wszystkie modele według dostawcy + typ | +| `/api/combos*` | Różne | Zarządzanie kombinacjami | +| `/api/keys*` | Różne | Zarządzanie kluczami API | +| `/api/pricing` | OTRZYMAJ | Ceny modeli | + +### Wykorzystanie i analityka + +| Punkt końcowy | Metoda | Opis | +| --------------------------- | -------- | ----------------------------- | +| `/api/usage/history` | OTRZYMAJ | Historia użytkowania | +| `/api/usage/logs` | OTRZYMAJ | Dzienniki użytkowania | +| `/api/usage/request-logs` | OTRZYMAJ | Dzienniki na poziomie żądania | +| `/api/usage/[connectionId]` | OTRZYMAJ | Użycie na połączenie | + +### Ustawienia + +| Punkt końcowy | Metoda | Opis | +| ------------------------------- | ------------- | ---------------------------------------- | +| `/api/settings` | POBIERZ/WSTAW | Ustawienia ogólne | +| `/api/settings/proxy` | POBIERZ/WSTAW | Konfiguracja serwera proxy sieci | +| `/api/settings/proxy/test` | POST | Testuj połączenie proxy | +| `/api/settings/ip-filter` | POBIERZ/WSTAW | Lista dozwolonych/blokowanych adresów IP | +| `/api/settings/thinking-budget` | POBIERZ/WSTAW | Rozumowanie budżetu symbolicznego | +| `/api/settings/system-prompt` | POBIERZ/WSTAW | Globalny monit systemowy | + +### Monitorowanie + +| Punkt końcowy | Metoda | Opis | +| ------------------------ | ------------ | --------------------------------------- | +| `/api/sessions` | OTRZYMAJ | Śledzenie aktywnej sesji | +| `/api/rate-limits` | OTRZYMAJ | Limity stawek za konto | +| `/api/monitoring/health` | OTRZYMAJ | Kontrola stanu zdrowia | +| `/api/cache` | POBIERZ/USUŃ | Statystyki pamięci podręcznej / wyczyść | + +### Kopia zapasowa i eksport/import + +| Punkt końcowy | Metoda | Opis | +| --------------------------- | -------- | -------------------------------------------------- | +| `/api/db-backups` | OTRZYMAJ | Lista dostępnych kopii zapasowych | +| `/api/db-backups` | POSTAW | Utwórz ręczną kopię zapasową | +| `/api/db-backups` | POST | Przywróć z określonej kopii zapasowej | +| `/api/db-backups/export` | OTRZYMAJ | Pobierz bazę danych jako plik .sqlite | +| `/api/db-backups/import` | POST | Prześlij plik .sqlite, aby zastąpić bazę danych | +| `/api/db-backups/exportAll` | OTRZYMAJ | Pobierz pełną kopię zapasową jako archiwum .tar.gz | + +### Synchronizacja z chmurą + +| Punkt końcowy | Metoda | Opis | +| ---------------------- | ------ | --------------------------------- | +| `/api/sync/cloud` | Różne | Operacje synchronizacji w chmurze | +| `/api/sync/initialize` | POST | Zainicjuj synchronizację | +| `/api/cloud/*` | Różne | Zarządzanie chmurą | + +### Narzędzia CLI + +| Punkt końcowy | Metoda | Opis | +| ---------------------------------- | -------- | -------------------------------- | +| `/api/cli-tools/claude-settings` | OTRZYMAJ | Stan CLI Claude'a | +| `/api/cli-tools/codex-settings` | OTRZYMAJ | Stan CLI Kodeksu | +| `/api/cli-tools/droid-settings` | OTRZYMAJ | Stan CLI droida | +| `/api/cli-tools/openclaw-settings` | OTRZYMAJ | Stan interfejsu CLI OpenClaw | +| `/api/cli-tools/runtime/[toolId]` | OTRZYMAJ | Ogólne środowisko wykonawcze CLI | + +Odpowiedzi CLI obejmują: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. + +### Odporność i limity szybkości + +| Punkt końcowy | Metoda | Opis | +| ----------------------- | ------------- | ---------------------------------------- | +| `/api/resilience` | POBIERZ/WSTAW | Pobierz/zaktualizuj profile odporności | +| `/api/resilience/reset` | POST | Zresetuj wyłączniki automatyczne | +| `/api/rate-limits` | OTRZYMAJ | Stan limitu stawek za konto | +| `/api/rate-limit` | OTRZYMAJ | Konfiguracja globalnego limitu szybkości | + +### Obliczenia + +| Punkt końcowy | Metoda | Opis | +| ------------- | -------------- | ----------------------------------------------------- | +| `/api/evals` | POBIERZ/WYŚLIJ | Lista zestawów ewaluacyjnych / uruchomienie ewaluacji | + +### Zasady + +| Punkt końcowy | Metoda | Opis | +| --------------- | ----------------- | --------------------------- | +| `/api/policies` | POBIERZ/POST/USUŃ | Zarządzaj zasadami routingu | + +### Zgodność + +| Punkt końcowy | Metoda | Opis | +| --------------------------- | -------- | -------------------------------------- | +| `/api/compliance/audit-log` | OTRZYMAJ | Dziennik audytu zgodności (ostatnie N) | + +### v1beta (kompatybilny z Gemini) + +| Punkt końcowy | Metoda | Opis | +| -------------------------- | -------- | ----------------------------------------- | +| `/v1beta/models` | OTRZYMAJ | Lista modeli w formacie Gemini | +| `/v1beta/models/{...path}` | POST | Bliźnięta `generateContent` punkt końcowy | + +Te punkty końcowe odzwierciedlają format API Gemini dla klientów, którzy oczekują natywnej zgodności Gemini SDK. + +### Wewnętrzne/systemowe interfejsy API + +| Punkt końcowy | Metoda | Opis | +| --------------- | -------- | ---------------------------------------------------------------------- | +| `/api/init` | OTRZYMAJ | Kontrola inicjalizacji aplikacji (używana przy pierwszym uruchomieniu) | +| `/api/tags` | OTRZYMAJ | Tagi modeli zgodnych z Ollama (dla klientów Ollama) | +| `/api/restart` | POST | Wywołaj łagodny restart serwera | +| `/api/shutdown` | POST | Wywołaj łagodne zamknięcie serwera | + +> **Uwaga:** Te punkty końcowe są używane wewnętrznie przez system lub w celu zapewnienia zgodności z klientem Ollama. Zwykle nie są one wywoływane przez użytkowników końcowych. + +--- + +## Transkrypcja audio + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data +``` + +Transkrypuj pliki audio za pomocą Deepgram lub AssemblyAI. + +**Prośba:** + +```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" +``` + +**Odpowiedź:** + +```json +{ + "text": "Hello, this is the transcribed audio content.", + "task": "transcribe", + "language": "en", + "duration": 12.5 +} +``` + +**Obsługiwani dostawcy:** `deepgram/nova-3`, `assemblyai/best`. + +**Obsługiwane formaty:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +## Zgodność z Ollamą + +Dla klientów korzystających z formatu API Ollama: + +```bash +# Chat endpoint (Ollama format) +POST /v1/api/chat + +# Model listing (Ollama format) +GET /api/tags +``` + +Żądania są automatycznie tłumaczone pomiędzy formatami Ollama i formatami wewnętrznymi. + +--- + +## Telemetria + +```bash +# Get latency telemetry summary (p50/p95/p99 per provider) +GET /api/telemetry/summary +``` + +**Odpowiedź:** + +```json +{ + "providers": { + "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, + "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } + } +} +``` + +--- + +## Budżet + +```bash +# Get budget status for all API keys +GET /api/usage/budget + +# Set or update a budget +POST /api/usage/budget +Content-Type: application/json + +{ + "keyId": "key-123", + "limit": 50.00, + "period": "monthly" +} +``` + +--- + +## Dostępność modelu + +```bash +# Get real-time model availability across all providers +GET /api/models/availability + +# Check availability for a specific model +POST /api/models/availability +Content-Type: application/json + +{ + "model": "claude-sonnet-4-5-20250929" +} +``` + +--- + +## Przetwarzanie żądania + +1. Klient wysyła żądanie do `/v1/*` +2. Wywołania obsługi tras `handleChat`, `handleEmbedding`, `handleAudioTranscription` lub `handleImageGeneration` +3. Model został rozwiązany (bezpośredni dostawca/model lub alias/kombinacja) +4. Poświadczenia wybrane z lokalnej bazy danych z filtrowaniem dostępności kont +5. Dla czatu: `handleChatCore` — wykrywanie formatu, tłumaczenie, sprawdzanie pamięci podręcznej, sprawdzanie idempotencji +6. Wykonawca dostawcy wysyła żądanie upstream +7. Odpowiedź przetłumaczona z powrotem na format klienta (czat) lub zwrócona w niezmienionej postaci (osadzone elementy/obrazy/audio) +8. Zarejestrowano użycie/rejestrowanie +9. Rezerwa ma zastosowanie w przypadku błędów zgodnie z zasadami kombinacji + +Pełne odniesienie do architektury: [**OMNI_TOKEN_119**](ARCHITECTURE.md) + +--- + +## Uwierzytelnianie + +- Trasy panelu kontrolnego (`/dashboard/*`) korzystają z pliku cookie `auth_token` +- Logowanie wykorzystuje zapisany skrót hasła; powrót do `INITIAL_PASSWORD` +- `requireLogin` przełączane poprzez `/api/settings/require-login` +- `/v1/*` trasy opcjonalnie wymagają klucza API nośnika, gdy `REQUIRE_API_KEY=true` diff --git a/docs/i18n/pl/ARCHITECTURE.md b/docs/i18n/pl/ARCHITECTURE.md new file mode 100644 index 0000000000..bb0d6d7757 --- /dev/null +++ b/docs/i18n/pl/ARCHITECTURE.md @@ -0,0 +1,781 @@ +# Architektura OmniRoute + +🌐 **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) + +_Ostatnia aktualizacja: 2026-02-18_ + +## Podsumowanie wykonawcze + +OmniRoute to lokalna brama routingu AI i pulpit nawigacyjny zbudowany w oparciu o Next.js. +Zapewnia pojedynczy punkt końcowy zgodny z OpenAI (`/v1/*`) i kieruje ruch do wielu dostawców nadrzędnych z tłumaczeniem, rezerwą, odświeżaniem tokenów i śledzeniem użycia. + +Podstawowe możliwości: + +- Powierzchnia API kompatybilna z OpenAI dla CLI/narzędzi (28 dostawców) +- Tłumaczenie żądań/odpowiedzi w różnych formatach dostawców +- Awaryjna kombinacja modeli (sekwencja wielu modeli) +- Rezerwa awaryjna na poziomie konta (wiele kont na dostawcę) +- Zarządzanie połączeniem dostawcy klucza OAuth + API +- Generowanie osadzania poprzez `/v1/embeddings` (6 dostawców, 9 modeli) +- Generowanie obrazu poprzez `/v1/images/generations` (4 dostawców, 9 modeli) +- Pomyśl o analizie tagów (`...`) pod kątem modeli wnioskowania +- Oczyszczanie odpowiedzi w celu zapewnienia ścisłej zgodności z OpenAI SDK +- Normalizacja ról (programista → system, system → użytkownik) w celu zapewnienia zgodności między dostawcami +- Strukturalna konwersja danych wyjściowych (json_schema → Gemini respondSchema) +- Lokalna trwałość dostawców, kluczy, aliasów, kombinacji, ustawień, cen +- Śledzenie wykorzystania/kosztów i rejestrowanie żądań +- Opcjonalna synchronizacja w chmurze dla synchronizacji wielu urządzeń/stanów +- Lista dozwolonych/blokowanych adresów IP do kontroli dostępu do API +- Myślenie o zarządzaniu budżetem (przejściowe/automatyczne/niestandardowe/adaptacyjne) +- Globalny system natychmiastowego wstrzyknięcia +- Śledzenie sesji i pobieranie odcisków palców +- Ulepszone ograniczenie stawek dla konta z profilami specyficznymi dla dostawcy +- Wzór wyłącznika zapewniający odporność dostawcy +- Ochrona stada przed piorunami z blokadą mutex +- Pamięć podręczna deduplikacji żądań oparta na sygnaturach +- Warstwa domeny: dostępność modelu, zasady kosztów, polityka awaryjna, polityka blokad +- Trwałość stanu domeny (pamięć podręczna zapisu SQLite dla błędów awaryjnych, budżetów, blokad, wyłączników automatycznych) +- Silnik polityki do scentralizowanej oceny wniosków (blokada → budżet → rezerwa) + — Żądaj telemetrii z agregacją opóźnień p50/p95/p99 +- Identyfikator korelacji (X-Request-Id) do śledzenia od końca do końca +- Rejestrowanie audytu zgodności z możliwością rezygnacji dla każdego klucza API +- Ramy ewaluacyjne dla zapewnienia jakości LLM +- Pulpit nawigacyjny interfejsu użytkownika Resilience ze statusem wyłącznika automatycznego w czasie rzeczywistym +- Modułowi dostawcy OAuth (12 indywidualnych modułów pod `src/lib/oauth/providers/`) + +Podstawowy model środowiska wykonawczego: + +- Trasy aplikacji Next.js w `src/app/api/*` implementują zarówno interfejsy API pulpitu nawigacyjnego, jak i interfejsy API zgodności +- Wspólny rdzeń SSE/routingu w `src/sse/*` + `open-sse/*` obsługuje wykonywanie dostawcy, tłumaczenie, przesyłanie strumieniowe, rezerwę i wykorzystanie + +## Zakres i granice + +### W zakresie + +- Środowisko wykonawcze bramy lokalnej +- Interfejsy API zarządzania pulpitem nawigacyjnym +- Uwierzytelnianie dostawcy i odświeżanie tokena +- Poproś o tłumaczenie i przesyłanie strumieniowe SSE +- Stan lokalny + trwałość użytkowania +- Opcjonalna orkiestracja synchronizacji w chmurze + +### Poza zakresem + +- Wdrożenie usługi w chmurze za `NEXT_PUBLIC_CLOUD_URL` +- Umowa SLA dostawcy/płaszczyzna kontroli poza procesem lokalnym +- Same zewnętrzne pliki binarne CLI (Claude CLI, Codex CLI itp.) + +## Kontekst systemu wysokiego poziomu + +```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 +``` + +## Podstawowe komponenty wykonawcze + +## 1) API i warstwa routingu (trasy aplikacji Next.js) + +Główne katalogi: + +- `src/app/api/v1/*` i `src/app/api/v1beta/*` dla interfejsów API zgodności +- `src/app/api/*` dla interfejsów API zarządzania/konfiguracji +- Następne przepisanie w `next.config.mjs` mapie `/v1/*` na `/api/v1/*` + +Ważne ścieżki kompatybilności: + +- `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` — zawiera niestandardowe modele z `custom: true` +- `src/app/api/v1/embeddings/route.ts` — generacja osadzania (6 dostawców) +- `src/app/api/v1/images/generations/route.ts` — generowanie obrazu (4+ dostawców, w tym Antigravity/Nebius) +- `src/app/api/v1/messages/count_tokens/route.ts` +- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — dedykowany czat dla każdego dostawcy +- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — dedykowane osadzanie dla poszczególnych dostawców +- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — obrazy dedykowane dla poszczególnych dostawców +- `src/app/api/v1beta/models/route.ts` +- `src/app/api/v1beta/models/[...path]/route.ts` + +Domeny zarządzania: + +- Autoryzacja/ustawienia: `src/app/api/auth/*`, `src/app/api/settings/*` +- Dostawcy/połączenia: `src/app/api/providers*` +- Węzły dostawcy: `src/app/api/provider-nodes*` +- Modele niestandardowe: `src/app/api/provider-models` (GET/POST/DELETE) +- Katalog modeli: `src/app/api/models/catalog` (GET) +- Konfiguracja proxy: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST) +- OAuth: `src/app/api/oauth/*` +- Klucze/aliasy/kombinacje/ceny: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing` +- Użycie: `src/app/api/usage/*` +- Synchronizacja/chmura: `src/app/api/sync/*`, `src/app/api/cloud/*` +- Pomocnicy narzędzi CLI: `src/app/api/cli-tools/*` +- Filtr IP: `src/app/api/settings/ip-filter` (GET/PUT) +- Przemyślany budżet: `src/app/api/settings/thinking-budget` (GET/PUT) +- Podpowiedź systemowa: `src/app/api/settings/system-prompt` (GET/PUT) +- Sesje: `src/app/api/sessions` (GET) +- Limity stawek: `src/app/api/rate-limits` (GET) +- Odporność: `src/app/api/resilience` (GET/PATCH) — profile dostawców, wyłącznik automatyczny, stan limitu szybkości +- Reset odporności: `src/app/api/resilience/reset` (POST) - resetuje wyłączniki + czasy odnowienia +- Statystyki pamięci podręcznej: `src/app/api/cache/stats` (GET/DELETE) +- Dostępność modelu: `src/app/api/models/availability` (GET/POST) +- Telemetria: `src/app/api/telemetry/summary` (GET) +- Budżet: `src/app/api/usage/budget` (GET/POST) +- Łańcuchy awaryjne: `src/app/api/fallback/chains` (GET/POST/DELETE) +- Audyt zgodności: `src/app/api/compliance/audit-log` (GET) +- Wartości: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET) +- Zasady: `src/app/api/policies` (GET/POST) + +## 2) SSE + rdzeń tłumaczeniowy + +Główne moduły przepływowe: + +- Wpis: `src/sse/handlers/chat.ts` +- Podstawowa orkiestracja: `open-sse/handlers/chatCore.ts` +- Adaptery wykonawcze dostawcy: `open-sse/executors/*` +- Wykrywanie formatu/konfiguracja dostawcy: `open-sse/services/provider.ts` +- Analiza/rozwiązanie modelu: `src/sse/services/model.ts`, `open-sse/services/model.ts` +- Logika zastępcza konta: `open-sse/services/accountFallback.ts` +- Rejestr tłumaczeń: `open-sse/translator/index.ts` +- Transformacje strumieniowe: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts` +- Ekstrakcja/normalizacja użycia: `open-sse/utils/usageTracking.ts` +- Pomyśl o parserze tagów: `open-sse/utils/thinkTagParser.ts` +- Obsługa osadzania: `open-sse/handlers/embeddings.ts` +- Rejestr dostawców osadzania: `open-sse/config/embeddingRegistry.ts` +- Obsługa generowania obrazu: `open-sse/handlers/imageGeneration.ts` +- Rejestr dostawców obrazu: `open-sse/config/imageRegistry.ts` +- Odkażanie odpowiedzi: `open-sse/handlers/responseSanitizer.ts` +- Normalizacja ról: `open-sse/services/roleNormalizer.ts` + +Usługi (logika biznesowa): + +- Wybór konta/punktacja: `open-sse/services/accountSelector.ts` +- Zarządzanie cyklem życia kontekstu: `open-sse/services/contextManager.ts` +- Wymuszanie filtra IP: `open-sse/services/ipFilter.ts` +- Śledzenie sesji: `open-sse/services/sessionManager.ts` +- Poproś o deduplikację: `open-sse/services/signatureCache.ts` +- Wstrzyknięcie monitu systemowego: `open-sse/services/systemPrompt.ts` +- Myślenie o zarządzaniu budżetem: `open-sse/services/thinkingBudget.ts` +- Routing modelu wieloznacznego: `open-sse/services/wildcardRouter.ts` +- Zarządzanie limitami stawek: `open-sse/services/rateLimitManager.ts` +- Bezpiecznik: `open-sse/services/circuitBreaker.ts` + +Moduły warstwy domeny: + +- Dostępność modelu: `src/lib/domain/modelAvailability.ts` +- Reguły kosztów/budżety: `src/lib/domain/costRules.ts` +- Polityka awaryjna: `src/lib/domain/fallbackPolicy.ts` +- Rozwiązanie kombinacji: `src/lib/domain/comboResolver.ts` +- Polityka blokowania: `src/lib/domain/lockoutPolicy.ts` +- Silnik polityki: `src/domain/policyEngine.ts` — scentralizowana blokada → budżet → ocena rezerwowa +- Katalog kodów błędów: `src/lib/domain/errorCodes.ts` +- Identyfikator żądania: `src/lib/domain/requestId.ts` +- Limit czasu pobierania: `src/lib/domain/fetchTimeout.ts` +- Poproś o telemetrię: `src/lib/domain/requestTelemetry.ts` +- Zgodność/audyt: `src/lib/domain/compliance/index.ts` +- Ewaluacyjny biegacz: `src/lib/domain/evalRunner.ts` +- Trwałość stanu domeny: `src/lib/db/domainState.ts` — SQLite CRUD dla łańcuchów awaryjnych, budżetów, historii kosztów, stanu blokady, wyłączników automatycznych + +Moduły dostawcy OAuth (12 pojedynczych plików pod `src/lib/oauth/providers/`): + +- Indeks rejestru: `src/lib/oauth/providers/index.ts` +- Dostawcy indywidualni: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts` +- Cienkie opakowanie: `src/lib/oauth/providers.ts` — reeksport z poszczególnych modułów + +## 3) Warstwa trwałości + +Stan podstawowy DB: + +- `src/lib/localDb.ts` +- plik: `${DATA_DIR}/db.json` (lub `$XDG_CONFIG_HOME/omniroute/db.json`, gdy jest ustawiony, w przeciwnym razie `~/.omniroute/db.json`) +- encje: dostawcaConnections, ProvideNodes, modelAliases, combo, apiKeys, ustawienia, ceny, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt** + +Wykorzystanie bazy danych: + +- `src/lib/usageDb.ts` +- pliki: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- stosuje się do tej samej zasady katalogu podstawowego, co `localDb` (`DATA_DIR`, następnie `XDG_CONFIG_HOME/omniroute`, gdy jest ustawiony) +- rozłożone na skupione podmoduły: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts` + +Baza danych stanu domeny (SQLite): + +- `src/lib/db/domainState.ts` — Operacje CRUD dla stanu domeny +- Tabele (utworzone w `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers` +- Wzór pamięci podręcznej zapisu: mapy w pamięci są wiarygodne w czasie wykonywania; mutacje są zapisywane synchronicznie do SQLite; stan jest przywracany z bazy danych przy zimnym starcie + +## 4) Powierzchnie uwierzytelniające + zabezpieczające + +- Autoryzacja plików cookie w panelu kontrolnym: `src/proxy.ts`, `src/app/api/auth/login/route.ts` +- Generowanie/weryfikacja klucza API: `src/shared/utils/apiKey.ts` + — Wpisy tajne dostawcy zachowały się we wpisach `providerConnections` +- Obsługa wychodzącego serwera proxy za pośrednictwem `open-sse/utils/proxyFetch.ts` (vars env) i `open-sse/utils/networkProxy.ts` (konfigurowalne dla każdego dostawcy lub globalne) + +## 5) Synchronizacja z chmurą + +- Inicjacja harmonogramu: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts` +- Zadanie okresowe: `src/shared/services/cloudSyncScheduler.ts` +- Trasa kontrolna: `src/app/api/sync/cloud/route.ts` + +## Cykl życia żądania (`/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 +``` + +## Kombinacja + przepływ awaryjny konta + +```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] +``` + +Decyzje awaryjne są podejmowane przez `open-sse/services/accountFallback.ts` przy użyciu kodów stanu i heurystyki komunikatów o błędach. + +## Cykl życia wdrożenia OAuth i odświeżania tokenu + +```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 +``` + +Odświeżanie podczas ruchu na żywo jest wykonywane wewnątrz `open-sse/handlers/chatCore.ts` za pośrednictwem modułu wykonującego `refreshCredentials()`. + +## Cykl życia synchronizacji w chmurze (włącz/synchronizuj/wyłącz) + +```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 +``` + +Synchronizacja okresowa jest wyzwalana przez `CloudSyncScheduler`, gdy włączona jest chmura. + +## Model danych i mapa przechowywania + +```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 + } +``` + +Pliki pamięci fizycznej: + +- stan główny: `${DATA_DIR}/db.json` (lub `$XDG_CONFIG_HOME/omniroute/db.json` gdy jest ustawiony, w przeciwnym wypadku `~/.omniroute/db.json`) +- statystyki użytkowania: `${DATA_DIR}/usage.json` +- linie dziennika żądań: `${DATA_DIR}/log.txt` +- opcjonalne sesje debugowania tłumacza/żądania: `/logs/...` + +## Topologia wdrożenia + +```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 +``` + +## Mapowanie modułów (decyzyjne krytyczne) + +### Moduły tras i API + +- `src/app/api/v1/*`, `src/app/api/v1beta/*`: interfejsy API zgodności +- `src/app/api/v1/providers/[provider]/*`: dedykowane trasy dla poszczególnych dostawców (czat, osadzanie, obrazy) +- `src/app/api/providers*`: dostawca CRUD, walidacja, testowanie +- `src/app/api/provider-nodes*`: niestandardowe zarządzanie kompatybilnymi węzłami +- `src/app/api/provider-models`: zarządzanie modelami niestandardowymi (CRUD) +- `src/app/api/models/catalog`: API pełnego katalogu modeli (wszystkie typy pogrupowane według dostawcy) +- `src/app/api/oauth/*`: Przepływy OAuth/kodu urządzenia +- `src/app/api/keys*`: cykl życia lokalnego klucza API +- `src/app/api/models/alias`: zarządzanie aliasami +- `src/app/api/combos*`: zarządzanie kombinacjami rezerwowymi +- `src/app/api/pricing`: zastąpienie cen przy kalkulacji kosztów +- `src/app/api/settings/proxy`: konfiguracja proxy (GET/PUT/DELETE) +- `src/app/api/settings/proxy/test`: test połączenia wychodzącego proxy (POST) +- `src/app/api/usage/*`: interfejsy API użycia i dzienników +- `src/app/api/sync/*` + `src/app/api/cloud/*`: synchronizacja z chmurą i pomocnicy obsługujący chmurę +- `src/app/api/cli-tools/*`: lokalni autorzy/weryfikatorzy konfiguracji CLI +- `src/app/api/settings/ip-filter`: Lista dozwolonych/blokowanych adresów IP (GET/PUT) +- `src/app/api/settings/thinking-budget`: konfiguracja budżetu tokena myślącego (GET/PUT) +- `src/app/api/settings/system-prompt`: globalny monit systemowy (GET/PUT) +- `src/app/api/sessions`: lista aktywnych sesji (GET) +- `src/app/api/rate-limits`: stan limitu stawki za konto (GET) + +### Rdzeń routingu i wykonania + +- `src/sse/handlers/chat.ts`: analiza żądań, obsługa kombinacji, pętla wyboru konta +- `open-sse/handlers/chatCore.ts`: tłumaczenie, wysyłanie executora, obsługa ponawiania/odświeżania, konfiguracja strumienia +- `open-sse/executors/*`: zachowanie sieci i formatu specyficzne dla dostawcy + +### Rejestr tłumaczeń i konwertery formatów + +- `open-sse/translator/index.ts`: rejestracja i orkiestracja tłumaczy +- Poproś o tłumaczy: `open-sse/translator/request/*` +- Tłumacze odpowiedzi: `open-sse/translator/response/*` +- Stałe formatu: `open-sse/translator/formats.ts` + +### Trwałość + +- `src/lib/localDb.ts`: trwała konfiguracja/stan +- `src/lib/usageDb.ts`: historia użytkowania i logi bieżących żądań + +## Zasięg dostawcy-wykonawcy (wzorzec strategii) + +Każdy dostawca ma wyspecjalizowany moduł wykonawczy rozszerzający `BaseExecutor` (w `open-sse/executors/base.ts`), który zapewnia tworzenie adresów URL, konstruowanie nagłówków, ponawianie prób z wykładniczym wycofywaniem, przechwytywanie odświeżania poświadczeń i metodę orkiestracji `execute()`. + +| Wykonawca | Dostawca(-y) | Specjalna obsługa | +| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Razem, Fajerwerki, Cerebras, Cohere, NVIDIA | Dynamiczna konfiguracja adresu URL/nagłówka dla każdego dostawcy | +| `AntigravityExecutor` | Google Antygrawitacja | Niestandardowe identyfikatory projektów/sesji, ponowna próba po przeanalizowaniu | +| `CodexExecutor` | Kodeks OpenAI | Wstrzykuje instrukcje systemowe, wymusza wysiłek rozumowania | +| `CursorExecutor` | Kursor IDE | Protokół ConnectRPC, kodowanie Protobuf, podpisywanie żądań poprzez sumę kontrolną | +| `GithubExecutor` | Drugi pilot GitHuba | Odświeżanie tokenu drugiego pilota, nagłówki naśladujące VSCode | +| `KiroExecutor` | Zaklinacz kodów AWS/Kiro | Format binarny AWS EventStream → Konwersja SSE | +| `GeminiCLIExecutor` | Bliźnięta CLI | Cykl odświeżania tokena Google OAuth | + +Wszyscy pozostali dostawcy (w tym niestandardowe kompatybilne węzły) używają `DefaultExecutor`. + +## Matryca zgodności dostawców + +| Dostawca | Formatuj | Autoryzacja | Strumień | Non-Stream | Odświeżenie tokena | Korzystanie z interfejsu API | +| ------------------- | ----------------- | ----------------------------- | ----------------------- | ---------- | ------------------ | ---------------------------- | +| Klaudiusz | klaudia | Klucz API / OAuth | ✅ | ✅ | ✅ | ⚠️ Tylko administrator | +| Bliźnięta | Bliźnięta | Klucz API / OAuth | ✅ | ✅ | ✅ | ⚠️ Konsola chmurowa | +| Bliźnięta CLI | bliźnięta-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Konsola chmurowa | +| Antygrawitacja | antygrawitacja | OAuth | ✅ | ✅ | ✅ | ✅ Pełny limit API | +| OpenAI | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| Kodeks | odpowiedzi openai | OAuth | ✅ zmuszony | ❌ | ✅ | ✅ Limity stawek | +| Drugi pilot GitHuba | otwieram | OAuth + token drugiego pilota | ✅ | ✅ | ✅ | ✅ Migawki kwot | +| Kursor | kursor | Niestandardowa suma kontrolna | ✅ | ✅ | ❌ | ❌ | +| Kiro | Kiro | AWS SSO OIDC | ✅ (Strumień zdarzenia) | ❌ | ✅ | ✅ Limity użytkowania | +| Qwen | otwieram | OAuth | ✅ | ✅ | ✅ | ⚠️ Na żądanie | +| iFlow | otwieram | OAuth (podstawowy) | ✅ | ✅ | ✅ | ⚠️ Na żądanie | +| OtwórzRouter | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| GLM/Kimi/MiniMax | klaudia | Klucz API | ✅ | ✅ | ❌ | ❌ | +| DeepSeek | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| Groq | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| xAI (Grok) | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| Mistral | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| Zakłopotanie | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| Razem AI | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| Fajerwerki AI | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| Cerebra | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| Spójne | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | +| NVIDIA NIM | otwieram | Klucz API | ✅ | ✅ | ❌ | ❌ | + +## Zakres tłumaczenia w formacie + +Wykryte formaty źródłowe obejmują: + +- `openai` +- `openai-responses` +- `claude` +- `gemini` + +Formaty docelowe obejmują: + +- Czat/odpowiedzi OpenAI +- Klaudiusz +- Koperta Gemini/Gemini-CLI/Antygrawitacyjna +- Kiro +- Kursor + +Tłumaczenia używają **OpenAI jako formatu centralnego** — wszystkie konwersje przechodzą przez OpenAI jako pośredni: + +``` +Source Format → OpenAI (hub) → Target Format +``` + +Tłumaczenia są wybierane dynamicznie na podstawie kształtu ładunku źródłowego i formatu docelowego dostawcy. + +Dodatkowe warstwy przetwarzania w potoku tłumaczenia: + +- **Oczyszczanie odpowiedzi** — Usuwa niestandardowe pola z odpowiedzi w formacie OpenAI (zarówno przesyłanych strumieniowo, jak i nie przesyłanych strumieniowo), aby zapewnić ścisłą zgodność z SDK +- **Normalizacja ról** — Konwertuje `developer` → `system` dla celów innych niż OpenAI; łączy `system` → `user` dla modeli odrzucających rolę systemową (GLM, ERNIE) +- **Pomyśl o wyodrębnieniu tagów** — Analizuje bloki `...` z treści w polu `reasoning_content` +- **Ustrukturyzowane dane wyjściowe** — Konwertuje OpenAI `response_format.json_schema` na `responseMimeType` Gemini + `responseSchema` + +## Obsługiwane punkty końcowe interfejsu API + +| Punkt końcowy | Formatuj | Opiekun | +| -------------------------------------------------- | --------------------- | -------------------------------------------------------------- | +| `POST /v1/chat/completions` | Czat OpenAI | `src/sse/handlers/chat.ts` | +| `POST /v1/messages` | Wiadomości Claude'a | Ten sam program obsługi (wykryty automatycznie) | +| `POST /v1/responses` | Odpowiedzi OpenAI | `open-sse/handlers/responsesHandler.ts` | +| `POST /v1/embeddings` | Osadzania OpenAI | `open-sse/handlers/embeddings.ts` | +| `GET /v1/embeddings` | Lista modeli | Trasa API | +| `POST /v1/images/generations` | Obrazy OpenAI | `open-sse/handlers/imageGeneration.ts` | +| `GET /v1/images/generations` | Lista modeli | Trasa API | +| `POST /v1/providers/{provider}/chat/completions` | Czat OpenAI | Dedykowany dla każdego dostawcy z walidacją modelu | +| `POST /v1/providers/{provider}/embeddings` | Osadzania OpenAI | Dedykowany dla każdego dostawcy z walidacją modelu | +| `POST /v1/providers/{provider}/images/generations` | Obrazy OpenAI | Dedykowany dla każdego dostawcy z walidacją modelu | +| `POST /v1/messages/count_tokens` | Claude Liczba żetonów | Trasa API | +| `GET /v1/models` | Lista modeli OpenAI | Ścieżka API (czat + osadzanie + obraz + modele niestandardowe) | +| `GET /api/models/catalog` | Katalog | Wszystkie modele pogrupowane według dostawcy + typu | +| `POST /v1beta/models/*:streamGenerateContent` | Pochodzący z Bliźniąt | Trasa API | +| `GET/PUT/DELETE /api/settings/proxy` | Konfiguracja proxy | Konfiguracja serwera proxy sieci | +| `POST /api/settings/proxy/test` | Łączność proxy | Punkt końcowy testu kondycji/łączności serwera proxy | +| `GET/POST/DELETE /api/provider-models` | Modele niestandardowe | Zarządzanie modelami niestandardowymi według dostawcy | + +## Obsługa obejścia + +Procedura obsługi obejścia (`open-sse/utils/bypassHandler.ts`) przechwytuje znane żądania „wyrzucenia” z Claude CLI — pingi rozgrzewające, wyodrębnianie tytułów i zliczanie tokenów — i zwraca **fałszywą odpowiedź** bez zużywania tokenów dostawcy nadrzędnego. Jest to wyzwalane tylko wtedy, gdy `User-Agent` zawiera `claude-cli`. + +## Potok żądania rejestratora + +Rejestrator żądań (`open-sse/utils/requestLogger.ts`) zapewnia 7-etapowy potok rejestrowania debugowania, domyślnie wyłączony, włączony poprzez `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 +``` + +Pliki są zapisywane w `/logs//` dla każdej sesji żądań. + +## Tryby awarii i odporność + +## 1) Dostępność konta/dostawcy + +- czas oczekiwania na konto dostawcy w przypadku błędów przejściowych/szybkości/auth +- rezerwowe konto przed nieudanym żądaniem +- powrót do modelu kombi, gdy bieżąca ścieżka modelu/dostawcy zostanie wyczerpana + +## 2) Wygaśnięcie tokena + +- wstępne sprawdzenie i odświeżenie z ponowną próbą dla dostawców z możliwością odświeżania +- Ponowna próba 401/403 po próbie odświeżenia w ścieżce podstawowej + +## 3) Bezpieczeństwo transmisji + +- kontroler strumienia obsługujący rozłączenie +- strumień tłumaczeń z opróżnianiem na końcu strumienia i obsługą `[DONE]` +- rezerwowe oszacowanie użycia w przypadku braku metadanych dotyczących użycia dostawcy + +## 4) Degradacja synchronizacji w chmurze + +- pojawiają się błędy synchronizacji, ale lokalne środowisko wykonawcze trwa +- harmonogram ma logikę umożliwiającą ponawianie prób, ale wykonywanie okresowe obecnie domyślnie wywołuje synchronizację przy pojedynczej próbie + +## 5) Integralność danych + +- Migracja/naprawa kształtu DB w przypadku brakujących kluczy +- uszkodzone zabezpieczenia resetowania JSON dla localDb i useDb + +## Obserwowalność i sygnały operacyjne + +Źródła widoczności w czasie wykonywania: + +- logi konsoli z `src/sse/utils/logger.ts` +- agregacje użycia na żądanie w `usage.json` +- logowanie o status żądania tekstowego `log.txt` +- opcjonalne głębokie dzienniki żądań/tłumaczeń pod `logs/`, gdy `ENABLE_REQUEST_LOGS=true` +- punkty końcowe użycia panelu kontrolnego (`/api/usage/*`) do wykorzystania interfejsu użytkownika + +## Granice wrażliwe na bezpieczeństwo + +- Sekret JWT (`JWT_SECRET`) zabezpiecza weryfikację/podpisywanie plików cookie sesji panelu kontrolnego + — Początkowe hasło zastępcze (`INITIAL_PASSWORD`, domyślne `123456`) musi zostać zastąpione w rzeczywistych wdrożeniach +- Klucz API Sekret HMAC (`API_KEY_SECRET`) zabezpiecza wygenerowany lokalny format klucza API +- Sekrety dostawcy (klucze/tokeny API) są zachowywane w lokalnej bazie danych i powinny być chronione na poziomie systemu plików +- Punkty końcowe synchronizacji w chmurze opierają się na uwierzytelnianiu klucza API + semantyce identyfikatora komputera + +## Środowisko i macierz czasu wykonywania + +Zmienne środowiskowe aktywnie używane przez kod: + +- Aplikacja/autoryzacja: `JWT_SECRET`, `INITIAL_PASSWORD` +- Przechowywanie: `DATA_DIR` +- Zgodne zachowanie węzła: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` +- Opcjonalne obejście bazy pamięci (Linux/macOS, gdy `DATA_DIR` nie jest ustawione): `XDG_CONFIG_HOME` +- Haszowanie zabezpieczeń: `API_KEY_SECRET`, `MACHINE_ID_SALT` +- Logowanie: `ENABLE_REQUEST_LOGS` +- Adres URL synchronizacji/chmury: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL` +- Wychodzące proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` i warianty pisane małymi literami +- flagi funkcji SOCKS5: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` +- Pomocnicy platformy/środowiska wykonawczego (konfiguracja nie specyficzna dla aplikacji): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME` + +## Znane uwagi architektoniczne + +1. `usageDb` i `localDb` mają teraz tę samą podstawową politykę katalogową (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) z migracją starszych plików. +2. `/api/v1/route.ts` zwraca statyczną listę modeli i nie jest głównym źródłem modeli używanym przez `/v1/models`. +3. Rejestrator żądań zapisuje pełne nagłówki/treść, gdy jest włączony; traktuj katalog dzienników jako poufny. +4. Zachowanie chmury zależy od prawidłowego `NEXT_PUBLIC_BASE_URL` i osiągalności punktu końcowego chmury. +5. Katalog `open-sse/` jest publikowany jako `@omniroute/open-sse` **pakiet obszaru roboczego npm**. Kod źródłowy importuje go poprzez `@omniroute/open-sse/...` (rozwiązany przez Next.js `transpilePackages`). Aby zachować spójność, ścieżki plików w tym dokumencie nadal używają nazwy katalogu `open-sse/`. +6. Wykresy na pulpicie nawigacyjnym korzystają z **Recharts** (oparte na SVG) w celu uzyskania przystępnych, interaktywnych wizualizacji analitycznych (wykresy słupkowe wykorzystania modelu, tabele podziału dostawców ze wskaźnikami sukcesu). +7. Testy E2E wykorzystują **Playwright** (`tests/e2e/`), uruchamiają się przez `npm run test:e2e`. Testy jednostkowe korzystają z **programu uruchamiającego testy Node.js** (`tests/unit/`), uruchamianego za pośrednictwem `npm run test:plan3`. Kod źródłowy pod `src/` to **TypeScript** (`.ts`/`.tsx`); obszarem roboczym `open-sse/` pozostaje JavaScript (`.js`). +8. Strona ustawień jest podzielona na 5 zakładek: Bezpieczeństwo, Routing (6 globalnych strategii: najpierw wypełnij, okrężnie, p2c, losowa, najrzadziej używana, zoptymalizowana pod względem kosztów), Odporność (edytowalne limity szybkości, wyłącznik automatyczny, zasady), AI (przemyślany budżet, monit systemowy, pamięć podręczna podpowiedzi), Zaawansowane (proxy). + +## Lista kontrolna weryfikacji operacyjnej + +- Kompiluj ze źródła: `npm run build` +- Zbuduj obraz Dockera: `docker build -t omniroute .` +- Uruchom usługę i sprawdź: +- `GET /api/settings` +- `GET /api/v1/models` +- Podstawowy docelowy adres URL CLI powinien mieć postać `http://:20128/v1`, gdy `PORT=20128` diff --git a/docs/i18n/pl/CODEBASE_DOCUMENTATION.md b/docs/i18n/pl/CODEBASE_DOCUMENTATION.md new file mode 100644 index 0000000000..72c7ddfb6d --- /dev/null +++ b/docs/i18n/pl/CODEBASE_DOCUMENTATION.md @@ -0,0 +1,589 @@ +# omniroute — dokumentacja bazy kodu + +🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md) + +> Obszerny, przyjazny dla początkujących przewodnik po routerze proxy AI **omniroute** obsługującym wielu dostawców. + +--- + +## 1. Co to jest omniroute? + +omniroute to **router proxy**, który znajduje się pomiędzy klientami AI (Claude CLI, Codex, Cursor IDE itp.) a dostawcami AI (Anthropic, Google, OpenAI, AWS, GitHub itp.). Rozwiązuje jeden duży problem: + +> **Różni klienci AI mówią różnymi „językami” (formatami API), a różni dostawcy AI również oczekują różnych „języków”.** omniroute dokonuje automatycznego tłumaczenia między nimi. + +Pomyśl o tym jak o uniwersalnym tłumaczu w Organizacji Narodów Zjednoczonych — każdy delegat może mówić w dowolnym języku, a tłumacz konwertuje go na dowolnego innego delegata. + +--- + +## 2. Przegląd architektury + +```mermaid +graph LR + subgraph Clients + A[Claude CLI] + B[Codex] + C[Cursor IDE] + D[OpenAI-compatible] + end + + subgraph omniroute + E[Handler Layer] + F[Translator Layer] + G[Executor Layer] + H[Services Layer] + end + + subgraph Providers + I[Anthropic Claude] + J[Google Gemini] + K[OpenAI / Codex] + L[GitHub Copilot] + M[AWS Kiro] + N[Antigravity] + O[Cursor API] + end + + A --> E + B --> E + C --> E + D --> E + E --> F + F --> G + G --> I + G --> J + G --> K + G --> L + G --> M + G --> N + G --> O + H -.-> E + H -.-> G +``` + +### Podstawowa zasada: tłumaczenie typu Hub-and-Spoke + +Tłumaczenie wszystkich formatów przechodzi przez **format OpenAI jako centrum**: + +``` +Client Format → [OpenAI Hub] → Provider Format (request) +Provider Format → [OpenAI Hub] → Client Format (response) +``` + +Oznacza to, że potrzebujesz tylko **N tłumaczy** (po jednym na format) zamiast **N²** (każda para). + +--- + +## 3. Struktura projektu + +``` +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 +``` + +--- + +## 4. Podział modułów na moduły + +### Konfiguracja 4.1 (`open-sse/config/`) + +**Pojedyncze źródło prawdy** dla wszystkich konfiguracji dostawców. + +| Plik | Cel | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `constants.ts` | Obiekt `PROVIDERS` z podstawowymi adresami URL, poświadczeniami OAuth (domyślne), nagłówkami i domyślnymi monitami systemowymi dla każdego dostawcy. Definiuje również `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG` i `SKIP_PATTERNS`. | +| `credentialLoader.ts` | Ładuje zewnętrzne poświadczenia z `data/provider-credentials.json` i łączy je z zakodowanymi na stałe wartościami domyślnymi w `PROVIDERS`. Chroni tajemnice przed kontrolą źródła, zachowując jednocześnie kompatybilność wsteczną. | +| `providerModels.ts` | Centralny rejestr modeli: aliasy dostawców map → identyfikatory modeli. Funkcje takie jak `getModels()`, `getProviderByAlias()`. | +| `codexInstructions.ts` | Instrukcje systemowe wstrzykiwane do żądań Kodeksu (ograniczenia edycyjne, reguły piaskownicy, zasady zatwierdzania). | +| `defaultThinkingSignature.ts` | Domyślne sygnatury „myślące” dla modeli Claude i Gemini. | +| `ollamaModels.ts` | Definicja schematu dla lokalnych modeli Ollama (nazwa, rozmiar, rodzina, kwantyzacja). | + +#### Proces ładowania danych uwierzytelniających + +```mermaid +flowchart TD + A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"] + B --> C{"data/provider-credentials.json\nexists?"} + C -->|Yes| D["credentialLoader reads JSON"] + C -->|No| E["Use hardcoded defaults"] + D --> F{"For each provider in JSON"} + F --> G{"Provider exists\nin PROVIDERS?"} + G -->|No| H["Log warning, skip"] + G -->|Yes| I{"Value is object?"} + I -->|No| J["Log warning, skip"] + I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"] + K --> F + H --> F + J --> F + F -->|Done| L["PROVIDERS ready with\nmerged credentials"] + E --> L +``` + +--- + +### 4.2 Executory (`open-sse/executors/`) + +Wykonawcy hermetyzują **logikę specyficzną dla dostawcy** przy użyciu **wzorca strategii**. Każdy wykonawca w razie potrzeby zastępuje metody podstawowe. + +```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 DefaultExecutor { + +refreshCredentials() + } + + class AntigravityExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +shouldRetry() + +refreshCredentials() + } + + class CursorExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseResponse() + +generateChecksum() + } + + class KiroExecutor { + +buildUrl() + +buildHeaders() + +transformRequest() + +parseEventStream() + +refreshCredentials() + } + + BaseExecutor <|-- DefaultExecutor + BaseExecutor <|-- AntigravityExecutor + BaseExecutor <|-- CursorExecutor + BaseExecutor <|-- KiroExecutor + BaseExecutor <|-- CodexExecutor + BaseExecutor <|-- GeminiCLIExecutor + BaseExecutor <|-- GithubExecutor +``` + +| Wykonawca | Dostawca | Kluczowe specjalizacje | +| ---------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `base.ts` | — | Baza abstrakcyjna: budowanie adresów URL, nagłówki, logika ponownych prób, odświeżanie danych logowania | +| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Ogólne odświeżanie tokena OAuth dla standardowych dostawców | +| `antigravity.ts` | Kod Google Cloud | Generowanie identyfikatora projektu/sesji, rezerwowy adres wielu adresów URL, niestandardowa analiza ponownych prób na podstawie komunikatów o błędach („reset po 2h7m23s”) | +| `cursor.ts` | Kursor IDE | **Najbardziej złożone**: uwierzytelnianie sumy kontrolnej SHA-256, kodowanie żądania Protobuf, binarny EventStream → parsowanie odpowiedzi SSE | +| `codex.ts` | Kodeks OpenAI | Wstrzykuje instrukcje systemowe, zarządza poziomami myślenia, usuwa nieobsługiwane parametry | +| `gemini-cli.ts` | Interfejs wiersza polecenia Google Gemini | Tworzenie niestandardowego adresu URL (`streamGenerateContent`), odświeżanie tokena Google OAuth | +| `github.ts` | Drugi pilot GitHuba | System podwójnego tokena (GitHub OAuth + token Copilot), naśladowanie nagłówka VSCode | +| `kiro.ts` | Zaklinacz kodów AWS | Parsowanie binarne AWS EventStream, ramki zdarzeń AMZN, szacowanie tokenów | +| `index.ts` | — | Fabryka: nazwa dostawcy map → klasa wykonawcy, z domyślnym rezerwowym | + +--- + +### 4.3 Programy obsługi (`open-sse/handlers/`) + +**Warstwa orkiestracji** — koordynuje tłumaczenie, wykonywanie, przesyłanie strumieniowe i obsługę błędów. + +| Plik | Cel | +| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `chatCore.ts` | **Centralny orkiestrator** (~600 linii). Obsługuje pełny cykl życia żądania: wykrywanie formatu → tłumaczenie → wysyłanie modułu wykonawczego → odpowiedź przesyłana strumieniowo/nie przesyłana strumieniowo → odświeżanie tokena → obsługa błędów → rejestrowanie użycia. | +| `responsesHandler.ts` | Adapter dla API OpenAI Responses: konwertuje format Responses → Ukończenia czatu → wysyła do `chatCore` → konwertuje SSE z powrotem do formatu Responses. | +| `embeddings.ts` | Procedura obsługi generowania osadzania: rozwiązuje model osadzania → dostawca, wysyła do interfejsu API dostawcy, zwraca odpowiedź na osadzanie zgodną z OpenAI. Obsługuje ponad 6 dostawców. | +| `imageGeneration.ts` | Moduł obsługi generowania obrazu: rozpoznaje model obrazu → dostawca, obsługuje tryby zgodne z OpenAI, obraz Gemini (antygrawitacja) i tryb awaryjny (Nebius). Zwraca obrazy base64 lub URL. | + +#### Cykl życia żądania (chatCore.ts) + +```mermaid +sequenceDiagram + participant Client + participant chatCore + participant Translator + participant Executor + participant Provider + + Client->>chatCore: Request (any format) + chatCore->>chatCore: Detect source format + chatCore->>chatCore: Check bypass patterns + chatCore->>chatCore: Resolve model & provider + chatCore->>Translator: Translate request (source → OpenAI → target) + chatCore->>Executor: Get executor for provider + Executor->>Executor: Build URL, headers, transform request + Executor->>Executor: Refresh credentials if needed + Executor->>Provider: HTTP fetch (streaming or non-streaming) + + alt Streaming + Provider-->>chatCore: SSE stream + chatCore->>chatCore: Pipe through SSE transform stream + Note over chatCore: Transform stream translates
each chunk: target → OpenAI → source + chatCore-->>Client: Translated SSE stream + else Non-streaming + Provider-->>chatCore: JSON response + chatCore->>Translator: Translate response + chatCore-->>Client: Translated JSON + end + + alt Error (401, 429, 500...) + chatCore->>Executor: Retry with credential refresh + chatCore->>chatCore: Account fallback logic + end +``` + +--- + +### 4.4 Usługi (`open-sse/services/`) + +Logika biznesowa obsługująca procedury obsługi i wykonawców. + +| Plik | Cel | +| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `provider.ts` | **Wykrywanie formatu** (`detectFormat`): analizuje strukturę treści żądania w celu identyfikacji formatów Claude/OpenAI/Gemini/Antigravity/Responses (w tym heurystyka `max_tokens` dla Claude). Ponadto: budowanie adresów URL, budowanie nagłówków, normalizacja konfiguracji myślenia. Obsługuje dostawców dynamicznych `openai-compatible-*` i `anthropic-compatible-*`. | +| `model.ts` | Analiza ciągów modelu (`claude/model-name` → `{provider: "claude", model: "model-name"}`), rozpoznawanie aliasów z wykrywaniem kolizji, oczyszczanie danych wejściowych (odrzuca przejście ścieżki/znaki sterujące) i rozpoznawanie informacji o modelu z obsługą asynchronicznego modułu pobierającego aliasy. | +| `accountFallback.ts` | Obsługa limitów szybkości: wykładniczy wycofywanie (1 s → 2 s → 4 s → maksymalnie 2 minuty), zarządzanie czasem odnowienia konta, klasyfikacja błędów (które błędy powodują awarię, a które nie). | +| `tokenRefresh.ts` | Odświeżenie tokena OAuth dla **każdego dostawcy**: Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (podwójny token OAuth + Copilot), Kiro (AWS SSO OIDC + Social Auth). Zawiera pamięć podręczną deduplikacji obiecującą w locie i ponawianie prób z wykładniczym wycofywaniem. | +| `combo.ts` | **Modele kombinowane**: łańcuchy modeli awaryjnych. Jeśli model A zawiedzie z powodu błędu kwalifikującego się do powrotu, wypróbuj model B, następnie C itd. Zwraca rzeczywiste kody stanu nadrzędnego. | +| `usage.ts` | Pobiera dane o przydziałach/wykorzystaniu z interfejsów API dostawców (przydziały GitHub Copilot, przydziały modelu antygrawitacyjnego, limity szybkości Kodeksu, zestawienia użycia Kiro, ustawienia Claude). | +| `accountSelector.ts` | Inteligentny wybór konta za pomocą algorytmu punktacji: uwzględnia priorytet, stan zdrowia, pozycję w trybie okrężnym i stan odnowienia, aby wybrać optymalne konto dla każdego żądania. | +| `contextManager.ts` | Zarządzanie cyklem życia kontekstu żądania: tworzy i śledzi obiekty kontekstu na żądanie z metadanymi (identyfikator żądania, znaczniki czasu, informacje o dostawcy) na potrzeby debugowania i rejestrowania. | +| `ipFilter.ts` | Kontrola dostępu oparta na protokole IP: obsługuje tryby listy dozwolonych i list zablokowanych. Przed przetworzeniem żądań API sprawdza adres IP klienta pod kątem skonfigurowanych reguł. | +| `sessionManager.ts` | Śledzenie sesji za pomocą odcisku palca klienta: śledzi aktywne sesje przy użyciu zaszyfrowanych identyfikatorów klienta, monitoruje liczbę żądań i zapewnia metryki sesji. | +| `signatureCache.ts` | Pamięć podręczna deduplikacji oparta na sygnaturach żądań: zapobiega duplikowaniu żądań poprzez buforowanie ostatnich podpisów żądań i zwracanie buforowanych odpowiedzi na identyczne żądania w określonym przedziale czasowym. | +| `systemPrompt.ts` | Globalne wprowadzenie monitu systemowego: dołącza konfigurowalny monit systemowy do wszystkich żądań, z obsługą zgodności dla poszczególnych dostawców. | +| `thinkingBudget.ts` | Zarządzanie budżetem tokenów wnioskowania: obsługuje tryby przekazywania, automatyczne (konfiguracja myślenia paskowego), niestandardowe (stały budżet) i tryby adaptacyjne (skalowane złożoności) do kontrolowania tokenów myślenia/wnioskowania. | +| `wildcardRouter.ts` | Routing wzorców modelu z symbolami wieloznacznymi: rozwiązuje wzorce z symbolami wieloznacznymi (np. `*/claude-*`) do konkretnych par dostawca/model w oparciu o dostępność i priorytet. | + +#### Deduplikacja odświeżania tokenu + +```mermaid +sequenceDiagram + participant R1 as Request 1 + participant R2 as Request 2 + participant Cache as refreshPromiseCache + participant OAuth as OAuth Provider + + R1->>Cache: getAccessToken("gemini", token) + Cache->>Cache: No in-flight promise + Cache->>OAuth: Start refresh + R2->>Cache: getAccessToken("gemini", token) + Cache->>Cache: Found in-flight promise + Cache-->>R2: Return existing promise + OAuth-->>Cache: New access token + Cache-->>R1: New access token + Cache-->>R2: Same access token (shared) + Cache->>Cache: Delete cache entry +``` + +#### Zastępcza maszyna stanu konta + +```mermaid +stateDiagram-v2 + [*] --> Active + Active --> Error: Request fails (401/429/500) + Error --> Cooldown: Apply backoff + Cooldown --> Active: Cooldown expires + Active --> Active: Request succeeds (reset backoff) + + state Error { + [*] --> ClassifyError + ClassifyError --> ShouldFallback: Rate limit / Auth / Transient + ClassifyError --> NoFallback: 400 Bad Request + } + + state Cooldown { + [*] --> ExponentialBackoff + ExponentialBackoff: Level 0 = 1s + ExponentialBackoff: Level 1 = 2s + ExponentialBackoff: Level 2 = 4s + ExponentialBackoff: Max = 2min + } +``` + +#### Łańcuch modeli Combo + +```mermaid +flowchart LR + A["Request with\ncombo model"] --> B["Model A"] + B -->|"2xx Success"| C["Return response"] + B -->|"429/401/500"| D{"Fallback\neligible?"} + D -->|Yes| E["Model B"] + D -->|No| F["Return error"] + E -->|"2xx Success"| C + E -->|"429/401/500"| G{"Fallback\neligible?"} + G -->|Yes| H["Model C"] + G -->|No| F + H -->|"2xx Success"| C + H -->|"Fail"| I["All failed →\nReturn last status"] +``` + +--- + +### Tłumacz 4.5 (`open-sse/translator/`) + +**Silnik tłumaczenia formatów** wykorzystujący system samorejestrujących się wtyczek. + +#### Architektura + +```mermaid +graph TD + subgraph "Request Translation" + A["Claude → OpenAI"] + B["Gemini → OpenAI"] + C["Antigravity → OpenAI"] + D["OpenAI Responses → OpenAI"] + E["OpenAI → Claude"] + F["OpenAI → Gemini"] + G["OpenAI → Kiro"] + H["OpenAI → Cursor"] + end + + subgraph "Response Translation" + I["Claude → OpenAI"] + J["Gemini → OpenAI"] + K["Kiro → OpenAI"] + L["Cursor → OpenAI"] + M["OpenAI → Claude"] + N["OpenAI → Antigravity"] + O["OpenAI → Responses"] + end +``` + +| Katalog | Pliki | Opis | +| ------------ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `request/` | 8 tłumaczy | Konwertuj treści żądań między formatami. Każdy plik rejestruje się automatycznie poprzez `register(from, to, fn)` podczas importu. | +| `response/` | 7 tłumaczy | Konwertuj fragmenty odpowiedzi przesyłanych strumieniowo między formatami. Obsługuje typy zdarzeń SSE, bloki myślowe, wywołania narzędzi. | +| `helpers/` | 6 pomocników | Wspólne narzędzia: `claudeHelper` (ekstrakcja podpowiedzi systemowych, konfiguracja myślenia), `geminiHelper` (mapowanie części/zawartości), `openaiHelper` (filtrowanie formatu), `toolCallHelper` (generowanie identyfikatora, wstrzykiwanie brakującej odpowiedzi), `maxTokensHelper`, `responsesApiHelper`. | +| `index.ts` | — | Silnik tłumaczeniowy: `translateRequest()`, `translateResponse()`, zarządzanie państwem, rejestr. | +| `formats.ts` | — | Stałe formatu: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | + +#### Projekt klucza: wtyczki samorejestrujące + +```javascript +// Each translator file calls register() on import: +import { register } from "../index.js"; +register("claude", "openai", translateClaudeToOpenAI); + +// The index.js imports all translator files, triggering registration: +import "./request/claude-to-openai.js"; // ← self-registers +``` + +--- + +### 4.6 Narzędzia (`open-sse/utils/`) + +| Plik | Cel | +| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `error.ts` | Tworzenie reakcji na błędy (format zgodny z OpenAI), analizowanie błędów w górę, ekstrakcja czasu ponownej próby antygrawitacyjnej z komunikatów o błędach, przesyłanie strumieniowe błędów SSE. | +| `stream.ts` | **SSE Transform Stream** — główny potok przesyłania strumieniowego. Dwa tryby: `TRANSLATE` (tłumaczenie w pełnym formacie) i `PASSTHROUGH` (normalizacja + użycie ekstraktu). Obsługuje buforowanie fragmentów, szacowanie użycia, śledzenie długości treści. Instancje kodera/dekodera na strumień unikają stanu współdzielonego. | +| `streamHelpers.ts` | Narzędzia SSE niskiego poziomu: `parseSSELine` (tolerancja białych znaków), `hasValuableContent` (filtruje puste fragmenty dla OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (serializacja SSE z uwzględnieniem formatu z czyszczeniem `perf_metrics`). | +| `usageTracking.ts` | Ekstrakcja użycia tokena z dowolnego formatu (Claude/OpenAI/Gemini/Responses), szacowanie za pomocą oddzielnych współczynników znaków na token narzędzia/wiadomości, dodanie bufora (margines bezpieczeństwa 2000 tokenów), filtrowanie pól specyficzne dla formatu, rejestrowanie konsoli za pomocą kolorów ANSI. | +| `requestLogger.ts` | Rejestrowanie żądań w oparciu o pliki (opcja poprzez `ENABLE_REQUEST_LOGS=true`). Tworzy foldery sesji z ponumerowanymi plikami: `1_req_client.json` → `7_res_client.txt`. Wszystkie wejścia/wyjścia są asynchroniczne (odpal i zapomnij). Maskuje wrażliwe nagłówki. | +| `bypassHandler.ts` | Przechwytuje określone wzorce z Claude CLI (wyodrębnianie tytułu, rozgrzewka, liczenie) i zwraca fałszywe odpowiedzi bez wywoływania żadnego dostawcy. Obsługuje zarówno przesyłanie strumieniowe, jak i inne. Celowo ograniczone do zakresu Claude CLI. | +| `networkProxy.ts` | Rozwiązuje wychodzący adres URL proxy dla danego dostawcy z pierwszeństwem: konfiguracja specyficzna dla dostawcy → konfiguracja globalna → zmienne środowiskowe (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Obsługuje wyjątki `NO_PROXY`. Buforuje konfigurację przez 30 sekund. | + +#### Rurociąg przesyłania strumieniowego SSE + +```mermaid +flowchart TD + A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"] + B --> C["Buffer lines\n(split on newline)"] + C --> D["parseSSELine()\n(trim whitespace, parse JSON)"] + D --> E{"Mode?"} + E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"] + E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"] + F --> H["hasValuableContent()\nfilter empty chunks"] + G --> H + H -->|"Has content"| I["extractUsage()\ntrack token counts"] + H -->|"Empty"| J["Skip chunk"] + I --> K["formatSSE()\nserialize + clean perf_metrics"] + K --> L["TextEncoder\n(per-stream instance)"] + L --> M["Enqueue to\nclient stream"] + + style A fill:#f9f,stroke:#333 + style M fill:#9f9,stroke:#333 +``` + +#### Struktura sesji rejestratora żądania + +``` +logs/ +└── claude_gemini_claude-sonnet_20260208_143045/ + ├── 1_req_client.json ← Raw client request + ├── 2_req_source.json ← After initial conversion + ├── 3_req_openai.json ← OpenAI intermediate format + ├── 4_req_target.json ← Final target format + ├── 5_res_provider.txt ← Provider SSE chunks (streaming) + ├── 5_res_provider.json ← Provider response (non-streaming) + ├── 6_res_openai.txt ← OpenAI intermediate chunks + ├── 7_res_client.txt ← Client-facing SSE chunks + └── 6_error.json ← Error details (if any) +``` + +--- + +### 4.7 Warstwa aplikacji (`src/`) + +| Katalog | Cel | +| ------------- | -------------------------------------------------------------------------------------------------------------- | +| `src/app/` | Interfejs sieciowy, trasy API, oprogramowanie pośredniczące Express, procedury obsługi wywołań zwrotnych OAuth | +| `src/lib/` | Dostęp do bazy danych (`localDb.ts`, `usageDb.ts`), uwierzytelnianie, współdzielone | +| `src/mitm/` | Narzędzia proxy typu „man-in-the-middle” do przechwytywania ruchu dostawcy | +| `src/models/` | Definicje modeli baz danych | +| `src/shared/` | Opakowania wokół funkcji open-sse (dostawca, strumień, błąd itp.) | +| `src/sse/` | Procedury obsługi punktów końcowych SSE, które łączą bibliotekę open-sse z trasami Express | +| `src/store/` | Zarządzanie stanem aplikacji | + +#### Godne uwagi trasy API + +| Trasa | Metody | Cel | +| --------------------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------- | +| `/api/provider-models` | POBIERZ/POST/USUŃ | CRUD dla niestandardowych modeli na dostawcę | +| `/api/models/catalog` | OTRZYMAJ | Zagregowany katalog wszystkich modeli (czat, osadzanie, obraz, niestandardowy) pogrupowany według dostawcy | +| `/api/settings/proxy` | POBIERZ/PUT/USUŃ | Hierarchiczna konfiguracja wychodzącego proxy (`global/providers/combos/keys`) | +| `/api/settings/proxy/test` | POST | Sprawdza łączność proxy i zwraca publiczny adres IP/opóźnienie | +| `/v1/providers/[provider]/chat/completions` | POST | Dedykowane uzupełnianie czatów dla poszczególnych dostawców z walidacją modelu | +| `/v1/providers/[provider]/embeddings` | POST | Dedykowane osadzanie dla poszczególnych dostawców z walidacją modelu | +| `/v1/providers/[provider]/images/generations` | POST | Dedykowane generowanie obrazów dla poszczególnych dostawców z walidacją modelu | +| `/api/settings/ip-filter` | POBIERZ/WSTAW | Zarządzanie listą dozwolonych/blokowanych adresów IP | +| `/api/settings/thinking-budget` | POBIERZ/WSTAW | Konfiguracja budżetu tokena rozumowania (przejściowa/automatyczna/niestandardowa/adaptacyjna) | +| `/api/settings/system-prompt` | POBIERZ/WSTAW | Globalny systemowy zastrzyk monitu dla wszystkich żądań | +| `/api/sessions` | OTRZYMAJ | Śledzenie i metryki aktywnych sesji | +| `/api/rate-limits` | OTRZYMAJ | Stan limitu stawek za konto | + +--- + +## 5. Kluczowe wzorce projektowe + +### 5.1 Tłumaczenie typu Hub-and-Spoke + +Wszystkie formaty są tłumaczone poprzez **format OpenAI jako centrum**. Dodanie nowego dostawcy wymaga jedynie napisania **jednej pary** tłumaczy (do/z OpenAI), a nie N par. + +### 5.2 Wzorzec strategii wykonawcy + +Każdy dostawca ma dedykowaną klasę wykonawczą dziedziczącą z `BaseExecutor`. Fabryka w `executors/index.ts` wybiera właściwą w czasie wykonywania. + +### 5.3 System wtyczek samorejestrujących + +Moduły tłumacza rejestrują się przy imporcie poprzez `register()`. Dodanie nowego tłumacza polega po prostu na utworzeniu pliku i zaimportowaniu go. + +### 5.4 Zwrot konta z wykładniczym wycofywaniem + +Kiedy dostawca zwróci 429/401/500, system może przełączyć się na następne konto, stosując wykładnicze czasy odnowienia (1 s → 2 s → 4 s → maksymalnie 2 minuty). + +### Łańcuchy modeli Combo 5.5 + +„Kombinacja” grupuje wiele ciągów `provider/model`. Jeśli pierwszy się nie powiedzie, automatycznie wróć do następnego. + +### 5.6 Stanowe tłumaczenie strumieniowe + +Tłumaczenie odpowiedzi utrzymuje stan we wszystkich fragmentach SSE (śledzenie bloków myślenia, gromadzenie wywołań narzędzi, indeksowanie bloków treści) za pośrednictwem mechanizmu `initState()`. + +### 5.7 Bufor bezpieczeństwa użytkowania + +Do raportowanego użycia dodawany jest bufor o pojemności 2000 tokenów, aby zapobiec przekraczaniu przez klientów limitów okna kontekstowego z powodu narzutu wynikającego z monitów systemowych i translacji formatów. + +--- + +## 6. Obsługiwane formaty + +| Formatuj | Kierunek | Identyfikator | +| ----------------------------------------- | ------------ | ------------------ | +| Ukończenie czatu OpenAI | źródło + cel | `openai` | +| API odpowiedzi OpenAI | źródło + cel | `openai-responses` | +| Antropiczny Claude | źródło + cel | `claude` | +| Google Bliźnięta | źródło + cel | `gemini` | +| Interfejs wiersza polecenia Google Gemini | tylko cel | `gemini-cli` | +| Antygrawitacja | źródło + cel | `antigravity` | +| AWS Kiro | tylko cel | `kiro` | +| Kursor | tylko cel | `cursor` | + +--- + +## 7. Obsługiwani dostawcy + +| Dostawca | Metoda autoryzacji | Wykonawca | Kluczowe notatki | +| ----------------------------------------- | -------------------------------- | -------------- | ------------------------------------------------------------------------ | +| Antropiczny Claude | Klucz API lub OAuth | Domyślne | Używa nagłówka `x-api-key` | +| Google Bliźnięta | Klucz API lub OAuth | Domyślne | Używa nagłówka `x-goog-api-key` | +| Interfejs wiersza polecenia Google Gemini | OAuth | BliźniętaCLI | Używa punktu końcowego `streamGenerateContent` | +| Antygrawitacja | OAuth | Antygrawitacja | Zastępczy adres wielu adresów URL, niestandardowa analiza ponownych prób | +| OpenAI | Klucz API | Domyślne | Autoryzacja okaziciela standardowego | +| Kodeks | OAuth | Kodeks | Wstrzykuje instrukcje systemowe, zarządza myśleniem | +| Drugi pilot GitHuba | OAuth + token drugiego pilota | GitHuba | Podwójny token, nagłówek VSCode naśladujący | +| Kiro (AWS) | AWS SSO OIDC lub społecznościowe | Kiro | Analiza binarnego strumienia zdarzeń | +| Kursor IDE | Autoryzacja sumy kontrolnej | Kursor | Kodowanie Protobuf, sumy kontrolne SHA-256 | +| Qwen | OAuth | Domyślne | Autoryzacja standardowa | +| iFlow | OAuth (podstawowy + nośnik) | Domyślne | Nagłówek podwójnego uwierzytelniania | +| OtwórzRouter | Klucz API | Domyślne | Autoryzacja okaziciela standardowego | +| GLM, Kimi, MiniMax | Klucz API | Domyślne | Kompatybilny z Claude, użyj `x-api-key` | +| `openai-compatible-*` | Klucz API | Domyślne | Dynamiczny: dowolny punkt końcowy zgodny z OpenAI | +| `anthropic-compatible-*` | Klucz API | Domyślne | Dynamiczny: dowolny punkt końcowy zgodny z Claude | + +--- + +## 8. Podsumowanie przepływu danych + +### Żądanie transmisji strumieniowej + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor\nbuildUrl + buildHeaders"] + D --> E["fetch(providerURL)"] + E --> F["createSSEStream()\nTRANSLATE mode"] + F --> G["parseSSELine()"] + G --> H["translateResponse()\ntarget → OpenAI → source"] + H --> I["extractUsage()\n+ addBuffer"] + I --> J["formatSSE()"] + J --> K["Client receives\ntranslated SSE"] + K --> L["logUsage()\nsaveRequestUsage()"] +``` + +### Żądanie bez przesyłania strumieniowego + +```mermaid +flowchart LR + A["Client"] --> B["detectFormat()"] + B --> C["translateRequest()\nsource → OpenAI → target"] + C --> D["Executor.execute()"] + D --> E["translateResponse()\ntarget → OpenAI → source"] + E --> F["Return JSON\nresponse"] +``` + +### Przepływ obejściowy (Claude CLI) + +```mermaid +flowchart LR + A["Claude CLI request"] --> B{"Match bypass\npattern?"} + B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"] + B -->|"No match"| D["Normal flow"] + C --> E["Translate to\nsource format"] + E --> F["Return without\ncalling provider"] +``` diff --git a/docs/i18n/pl/FEATURES.md b/docs/i18n/pl/FEATURES.md new file mode 100644 index 0000000000..4f89d8cb0f --- /dev/null +++ b/docs/i18n/pl/FEATURES.md @@ -0,0 +1,77 @@ +# OmniRoute — Galeria funkcji panelu kontrolnego + +🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md) + +Wizualny przewodnik po każdej sekcji pulpitu nawigacyjnego OmniRoute. + +--- + +## 🔌 Dostawcy + +Zarządzaj połączeniami dostawców AI: dostawcy OAuth (Claude Code, Codex, Gemini CLI), dostawcy kluczy API (Groq, DeepSeek, OpenRouter) i dostawcy usług bezpłatnych (iFlow, Qwen, Kiro). + +![Providers Dashboard](screenshots/01-providers.png) + +--- + +## 🎨 Kombinacje + +Twórz kombinacje routingu modeli za pomocą 6 strategii: najpierw wypełnij, okrężnie, siła dwóch wyborów, losowa, najrzadziej używana i zoptymalizowana pod względem kosztów. Każda kombinacja łączy wiele modeli z automatycznym cofaniem. + +![Combos Dashboard](screenshots/02-combos.png) + +--- + +## 📊 Analityka + +Kompleksowa analiza użytkowania obejmująca zużycie tokenów, szacunki kosztów, mapy cieplne aktywności, tygodniowe wykresy dystrybucji i zestawienia poszczególnych dostawców. + +![Analytics Dashboard](screenshots/03-analytics.png) + +--- + +## 🏥 Stan systemu + +Monitorowanie w czasie rzeczywistym: czas pracy, pamięć, wersja, percentyle opóźnień (p50/p95/p99), statystyki pamięci podręcznej i stany wyłączników automatycznych dostawcy. + +![Health Dashboard](screenshots/04-health.png) + +--- + +## 🔧 Plac zabaw dla tłumaczy + +Cztery tryby debugowania tłumaczeń API: **Playground** (konwerter formatów), **Chat Tester** (żądania na żywo), **Test Bench** (testy wsadowe) i **Live Monitor** (strumień w czasie rzeczywistym). + +![Translator Playground](screenshots/05-translator.png) + +--- + +## ⚙️ Ustawienia + +Ustawienia ogólne, pamięć systemowa, zarządzanie kopiami zapasowymi (baza danych eksportu/importu), wygląd (tryb ciemny/jasny), bezpieczeństwo (w tym ochrona punktu końcowego API i niestandardowe blokowanie dostawców), routing, odporność i zaawansowana konfiguracja. + +![Settings Dashboard](screenshots/06-settings.png) + +--- + +## 🔧 Narzędzia CLI + +Konfiguracja jednym kliknięciem narzędzi do kodowania AI: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code i Antigravity. + +![CLI Tools Dashboard](screenshots/07-cli-tools.png) + +--- + +## 📝 Poproś o dzienniki + +Rejestrowanie żądań w czasie rzeczywistym z filtrowaniem według dostawcy, modelu, konta i klucza API. Pokazuje kody stanu, użycie tokenu, opóźnienie i szczegóły odpowiedzi. + +![Usage Logs](screenshots/08-usage.png) + +--- + +## 🌐 Punkt końcowy interfejsu API + +Twój ujednolicony punkt końcowy API z podziałem możliwości: uzupełnianie czatu, osadzanie, generowanie obrazu, zmiana rankingu, transkrypcja audio i zarejestrowane klucze API. + +![Endpoint Dashboard](screenshots/09-endpoint.png) diff --git a/docs/i18n/pl/TROUBLESHOOTING.md b/docs/i18n/pl/TROUBLESHOOTING.md new file mode 100644 index 0000000000..ac1b8911e3 --- /dev/null +++ b/docs/i18n/pl/TROUBLESHOOTING.md @@ -0,0 +1,219 @@ +# Rozwiązywanie problemów + +🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md) + +Typowe problemy i rozwiązania dla OmniRoute. + +--- + +## Szybkie poprawki + +| Problem | Rozwiązanie | +| ------------------------------------------ | -------------------------------------------------------------------------------------- | +| Pierwsze logowanie nie działa | Sprawdź `INITIAL_PASSWORD` w `.env` (domyślnie: `123456`) | +| Panel kontrolny otwiera się na złym porcie | Ustaw `PORT=20128` i `NEXT_PUBLIC_BASE_URL=http://localhost:20128` | +| Brak dzienników żądań pod `logs/` | Ustaw `ENABLE_REQUEST_LOGS=true` | +| EACCES: odmowa pozwolenia | Ustaw `DATA_DIR=/path/to/writable/dir`, aby zastąpić `~/.omniroute` | +| Strategia routingu nie jest zapisywana | Aktualizacja do wersji 1.4.11+ (poprawka schematu Zoda zapewniająca trwałość ustawień) | + +--- + +## Problemy z dostawcą + +### „Model językowy nie dostarczał komunikatów” + +**Przyczyna:** Limit dostawcy został wyczerpany. + +**Poprawka:** + +1. Sprawdź moduł śledzenia limitów na pulpicie nawigacyjnym +2. Użyj kombinacji z poziomami rezerwowymi +3. Przejdź na tańszy/bezpłatny poziom + +### Ograniczanie szybkości + +**Przyczyna:** Wyczerpany limit subskrypcji. + +**Poprawka:** + +- Dodaj rezerwę: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` +- Użyj GLM/MiniMax jako taniej kopii zapasowej + +### Token OAuth wygasł + +OmniRoute automatycznie odświeża tokeny. Jeśli problemy nadal występują: + +1. Panel kontrolny → Dostawca → Połącz ponownie +2. Usuń i ponownie dodaj połączenie dostawcy + +--- + +## Problemy z chmurą + +### Błędy synchronizacji z chmurą + +1. Sprawdź, czy `BASE_URL` wskazuje na działającą instancję (np. `http://localhost:20128`) +2. Zweryfikuj punkty `CLOUD_URL` w punkcie końcowym w chmurze (np. `https://omniroute.dev`) +3. Zachowaj wyrównanie wartości `NEXT_PUBLIC_*` z wartościami po stronie serwera + +### Chmura `stream=false` Zwraca 500 + +**Objaw:** `Unexpected token 'd'...` na punkcie końcowym w chmurze dla połączeń innych niż przesyłanie strumieniowe. + +**Przyczyna:** Upstream zwraca ładunek SSE, podczas gdy klient oczekuje JSON. + +**Rozwiązanie:** użyj `stream=true` do bezpośrednich połączeń w chmurze. Lokalne środowisko wykonawcze obejmuje rezerwę SSE → JSON. + +### Cloud wyświetla komunikat „Połączono”, ale „nieprawidłowy klucz API” + +1. Utwórz nowy klucz z lokalnego pulpitu nawigacyjnego (`/api/keys`) +2. Uruchom synchronizację z chmurą: Włącz chmurę → Synchronizuj teraz +3. Stare/niezsynchronizowane klucze nadal mogą zwracać `401` w chmurze + +--- + +## Problemy z Dockerem + +### Narzędzie CLI pokazuje, że nie jest zainstalowane + +1. Sprawdź pola wykonawcze: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq` +2. W trybie przenośnym: użyj docelowego obrazu `runner-cli` (w pakiecie CLI) +3. W trybie montowania hosta: ustaw `CLI_EXTRA_PATHS` i zamontuj katalog bin hosta jako tylko do odczytu +4. Jeśli `installed=true` i `runnable=false`: znaleziono plik binarny, ale kontrola stanu nie powiodła się + +### Szybka weryfikacja środowiska wykonawczego + +```bash +curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' +``` + +--- + +## Problemy z kosztami + +### Wysokie koszty + +1. Sprawdź statystyki użytkowania w Panelu → Użycie +2. Zmień model podstawowy na GLM/MiniMax +3. Korzystaj z bezpłatnej warstwy (Gemini CLI, iFlow) do zadań niekrytycznych +4. Ustaw budżety kosztów według klucza API: Panel → Klucze API → Budżet + +--- + +## Debugowanie + +### Włącz dzienniki żądań + +Ustaw `ENABLE_REQUEST_LOGS=true` w swoim pliku `.env`. Dzienniki pojawiają się w katalogu `logs/`. + +### Sprawdź stan dostawcy + +```bash +# Health dashboard +http://localhost:20128/dashboard/health + +# API health check +curl http://localhost:20128/api/monitoring/health +``` + +### Pamięć uruchomieniowa + +- Stan główny: `${DATA_DIR}/db.json` (dostawcy, kombinacje, aliasy, klucze, ustawienia) +- Użycie: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/` +- Dzienniki żądań: `/logs/...` (kiedy `ENABLE_REQUEST_LOGS=true`) + +--- + +## Problemy z wyłącznikami automatycznymi + +### Dostawca utknął w stanie OTWARTYM + +Gdy wyłącznik automatyczny dostawcy jest OTWARTY, żądania są blokowane do czasu upłynięcia czasu odnowienia. + +**Poprawka:** + +1. Przejdź do **Panel sterowania → Ustawienia → Odporność** +2. Sprawdź kartę wyłącznika dla odpowiedniego dostawcy +3. Kliknij **Resetuj wszystko**, aby wyczyścić wszystkie wyłączniki, lub poczekaj, aż upłynie czas odnowienia +4. Przed zresetowaniem sprawdź, czy dostawca jest rzeczywiście dostępny + +### Dostawca ciągle uruchamia wyłącznik automatyczny + +Jeśli dostawca wielokrotnie wchodzi w stan OPEN: + +1. Sprawdź **Panel kontrolny → Kondycja → Kondycja dostawcy** pod kątem wzorca awarii +2. Przejdź do **Ustawienia → Odporność → Profile dostawców** i zwiększ próg awarii +3. Sprawdź, czy dostawca zmienił limity API lub wymaga ponownego uwierzytelnienia +4. Sprawdź dane telemetryczne dotyczące opóźnień — duże opóźnienia mogą powodować awarie wynikające z przekroczenia limitu czasu + +--- + +## Problemy z transkrypcją dźwięku + +### Błąd „Nieobsługiwany model”. + +- Upewnij się, że używasz prawidłowego przedrostka: `deepgram/nova-3` lub `assemblyai/best` +- Sprawdź, czy dostawca jest podłączony w ** Panelu → Dostawcy** + +### Transkrypcja zwraca wartość pustą lub kończy się niepowodzeniem + +- Sprawdź obsługiwane formaty audio: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm` +- Sprawdź, czy rozmiar pliku mieści się w granicach dostawcy (zwykle < 25 MB) +- Sprawdź ważność klucza API dostawcy na karcie dostawcy + +--- + +## Debugowanie tłumacza + +Użyj **Panel kontrolny → Tłumacz**, aby debugować problemy z tłumaczeniem formatu: + +| Tryb | Kiedy stosować | +| ------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| **Plac zabaw** | Porównaj formaty wejścia/wyjścia obok siebie — wklej nieudane żądanie, aby zobaczyć, jak zostanie przetłumaczone | +| **Tester czatu** | Wysyłaj wiadomości na żywo i sprawdzaj pełny ładunek żądania/odpowiedzi, w tym nagłówki | +| **Stolik testowy** | Przeprowadź testy wsadowe dla kombinacji formatów, aby dowiedzieć się, które tłumaczenia są uszkodzone | +| **Monitorowanie na żywo** | Obserwuj przepływ żądań w czasie rzeczywistym, aby wykryć sporadyczne problemy z tłumaczeniem | + +### Typowe problemy z formatem + +- **Tagi myślenia nie pojawiają się** — Sprawdź, czy dostawca docelowy obsługuje myślenie i ustawienie budżetu na myślenie +- **Porzucanie wywołań narzędzi** — Niektóre tłumaczenia formatów mogą usuwać nieobsługiwane pola; sprawdź w trybie placu zabaw +- **Brak podpowiedzi systemowej** — Claude i Gemini inaczej obsługują podpowiedzi systemowe; sprawdź wynik tłumaczenia +- **SDK zwraca surowy ciąg znaków zamiast obiektu** — Naprawiono w wersji 1.1.0: narzędzie do czyszczenia odpowiedzi usuwa teraz niestandardowe pola (`x_groq`, `usage_breakdown` itp.), które powodują błędy sprawdzania poprawności OpenAI SDK w Pydantic +- **GLM/ERNIE odrzuca rolę `system`** — Naprawiono w wersji 1.1.0: normalizator ról automatycznie łączy komunikaty systemowe z komunikatami użytkownika w przypadku niekompatybilnych modeli +- **`developer` rola nie została rozpoznana** — Naprawiono w wersji 1.1.0: automatycznie konwertowana na `system` dla dostawców innych niż OpenAI +- **`json_schema` nie działa z Gemini** — Naprawiono w wersji 1.1.0: `response_format` jest teraz konwertowany na `responseMimeType` Gemini + `responseSchema` + +--- + +## Ustawienia odporności + +### Automatyczny limit szybkości nie uruchamia się + +- Automatyczne ograniczenie szybkości dotyczy tylko dostawców kluczy API (nie OAuth/subskrypcja) +- Sprawdź, czy **Ustawienia → Odporność → Profile dostawców** ma włączone automatyczne ograniczenie stawek +- Sprawdź, czy dostawca zwraca kody stanu `429` lub nagłówki `Retry-After` + +### Dostrajanie wykładniczego wycofywania + +Profile dostawców obsługują następujące ustawienia: + +- **Opóźnienie bazowe** — Początkowy czas oczekiwania po pierwszej awarii (domyślnie: 1 s) +- **Maks. opóźnienie** — Maksymalny limit czasu oczekiwania (domyślnie: 30 s) +- **Mnożnik** — O ile zwiększyć opóźnienie przy kolejnej awarii (domyślnie: 2x) + +### Stado przeciw grzmotom + +Gdy wiele jednoczesnych żądań trafia do dostawcy z ograniczoną szybkością, OmniRoute używa mutexu i automatycznego ograniczania szybkości, aby serializować żądania i zapobiegać kaskadowym błędom. Jest to automatyczne w przypadku dostawców kluczy API. + +--- + +## Nadal utknąłeś? + +- **Problemy z GitHubem**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) +- **Architektura**: Zobacz [**OMNI_TOKEN_55**](ARCHITECTURE.md), aby uzyskać szczegółowe informacje wewnętrzne +- **Dokumentacja API**: Zobacz [**OMNI_TOKEN_56**](API_REFERENCE.md) dla wszystkich punktów końcowych +- **Panel stanu**: Sprawdź **Panel kontrolny → Zdrowie**, aby sprawdzić stan systemu w czasie rzeczywistym +- **Tłumacz**: Użyj **Panel kontrolny → Tłumacz**, aby debugować problemy z formatem diff --git a/docs/i18n/pl/USER_GUIDE.md b/docs/i18n/pl/USER_GUIDE.md new file mode 100644 index 0000000000..578f504150 --- /dev/null +++ b/docs/i18n/pl/USER_GUIDE.md @@ -0,0 +1,698 @@ +# Podręcznik użytkownika + +🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md) + +Kompletny przewodnik dotyczący konfigurowania dostawców, tworzenia kombinacji, integracji narzędzi CLI i wdrażania OmniRoute. + +--- + +## Spis treści + +- [Pricing at a Glance](#-pricing-at-a-glance) +- [Use Cases](#-use-cases) +- [Provider Setup](#-provider-setup) +- [CLI Integration](#-cli-integration) +- [Deployment](#-deployment) +- [Available Models](#-available-models) +- [Advanced Features](#-advanced-features) + +--- + +## 💰 Ceny w skrócie + +| Poziom | Dostawca | Koszt | Reset przydziału | Najlepsze dla | +| ------------------ | ------------------- | ----------------- | ----------------------------- | ------------------------- | +| **💳 SUBSKRYPCJA** | Claude Code (Pro) | 20 USD/mies. | 5h + tygodniowo | Już subskrybujesz | +| | Kodeks (Plus/Pro) | 20-200 $/mies. | 5h + tygodniowo | Użytkownicy OpenAI | +| | Bliźnięta CLI | **BEZPŁATNE** | 180 tys./mies. + 1 tys./dzień | Wszyscy! | +| | Drugi pilot GitHuba | 10–19 USD/mies. | Miesięczne | Użytkownicy GitHuba | +| **🔑 KLUCZ API** | DeepSeek | Płać za użycie | Brak | Tanie rozumowanie | +| | Groq | Płać za użycie | Brak | Ultraszybkie wnioskowanie | +| | xAI (Grok) | Płać za użycie | Brak | Grok 4 rozumowanie | +| | Mistral | Płać za użycie | Brak | Modele hostowane w UE | +| | Zakłopotanie | Płać za użycie | Brak | Rozszerzone wyszukiwanie | +| | Razem AI | Płać za użycie | Brak | Modele open source | +| | Fajerwerki AI | Płać za użycie | Brak | Obrazy Fast FLUX | +| | Cerebra | Płać za użycie | Brak | Prędkość w skali opłatka | +| | Spójne | Płać za użycie | Brak | Polecenie R+RAG | +| | NVIDIA NIM | Płać za użycie | Brak | Modele korporacyjne | +| **💰 TANIO** | GLM-4.7 | 0,6 USD/1 mln | Codziennie 10:00 | Kopia zapasowa budżetu | +| | MiniMax M2.1 | 0,2 USD/1 mln | 5-godzinne toczenie | Najtańsza opcja | +| | Kimi K2 | 9 USD miesięcznie | 10 mln tokenów/mies. | Przewidywalny koszt | +| **🆓 DARMOWE** | iFlow | 0 dolarów | Nieograniczony | 8 modeli za darmo | +| | Qwen | 0 dolarów | Nieograniczony | 3 modele za darmo | +| | Kiro | 0 dolarów | Nieograniczony | Claude wolny | + +**💡 Wskazówka dla profesjonalistów:** Zacznij od zestawu Gemini CLI (180 tys. za darmo/miesiąc) + iFlow (bez ograniczeń za darmo) = koszt 0 USD! + +--- + +## 🎯 Przypadki użycia + +### Przypadek 1: „Mam subskrypcję Claude Pro” + +**Problem:** Limit wygasa niewykorzystany, limity szybkości podczas intensywnego kodowania + +``` +Combo: "maximize-claude" + 1. cc/claude-opus-4-6 (use subscription fully) + 2. glm/glm-4.7 (cheap backup when quota out) + 3. if/kimi-k2-thinking (free emergency fallback) + +Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total +vs. $20 + hitting limits = frustration +``` + +### Przypadek 2: „Chcę zerowych kosztów” + +**Problem:** Nie stać Cię na subskrypcje, potrzebujesz niezawodnego kodowania AI + +``` +Combo: "free-forever" + 1. gc/gemini-3-flash (180K free/month) + 2. if/kimi-k2-thinking (unlimited free) + 3. qw/qwen3-coder-plus (unlimited free) + +Monthly cost: $0 +Quality: Production-ready models +``` + +### Przypadek 3: „Potrzebuję kodowania 24 godziny na dobę, 7 dni w tygodniu, bez przerw” + +**Problem:** Terminy, nie mogę sobie pozwolić na przestoje + +``` +Combo: "always-on" + 1. cc/claude-opus-4-6 (best quality) + 2. cx/gpt-5.2-codex (second subscription) + 3. glm/glm-4.7 (cheap, resets daily) + 4. minimax/MiniMax-M2.1 (cheapest, 5h reset) + 5. if/kimi-k2-thinking (free unlimited) + +Result: 5 layers of fallback = zero downtime +Monthly cost: $20-200 (subscriptions) + $10-20 (backup) +``` + +### Przypadek 4: „Chcę DARMOWEJ sztucznej inteligencji w OpenClaw” + +**Problem:** Potrzebujesz asystenta AI w aplikacjach do przesyłania wiadomości, całkowicie za darmo + +``` +Combo: "openclaw-free" + 1. if/glm-4.7 (unlimited free) + 2. if/minimax-m2.1 (unlimited free) + 3. if/kimi-k2-thinking (unlimited free) + +Monthly cost: $0 +Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal... +``` + +--- + +## 📖 Konfiguracja dostawcy + +### 🔐 Dostawcy subskrypcji + +#### Kod Claude’a (Pro/Max) + +```bash +Dashboard → Providers → Connect Claude Code +→ OAuth login → Auto token refresh +→ 5-hour + weekly quota tracking + +Models: + cc/claude-opus-4-6 + cc/claude-sonnet-4-5-20250929 + cc/claude-haiku-4-5-20251001 +``` + +**Wskazówka dla profesjonalistów:** używaj Opus do skomplikowanych zadań, a Sonnet do szybkości. OmniRoute śledzi limit na model! + +#### Kodeks OpenAI (Plus/Pro) + +```bash +Dashboard → Providers → Connect Codex +→ OAuth login (port 1455) +→ 5-hour + weekly reset + +Models: + cx/gpt-5.2-codex + cx/gpt-5.1-codex-max +``` + +#### Gemini CLI (DARMOWE 180 tys./miesiąc!) + +```bash +Dashboard → Providers → Connect Gemini CLI +→ Google OAuth +→ 180K completions/month + 1K/day + +Models: + gc/gemini-3-flash-preview + gc/gemini-2.5-pro +``` + +**Najlepsza wartość:** Ogromny darmowy poziom! Użyj tego przed płatnymi poziomami. + +#### Drugi pilot GitHuba + +```bash +Dashboard → Providers → Connect GitHub +→ OAuth via GitHub +→ Monthly reset (1st of month) + +Models: + gh/gpt-5 + gh/claude-4.5-sonnet + gh/gemini-3-pro +``` + +### 💰 Tani dostawcy + +#### GLM-4.7 (reset dzienny, 0,6 USD/1 mln) + +1. Zarejestruj się: [Zhipu AI](https://open.bigmodel.cn/) +2. Uzyskaj klucz API z planu kodowania +3. Panel → Dodaj klucz API: Dostawca: `glm`, Klucz API: `your-key` + +**Zastosuj:** `glm/glm-4.7` — **Wskazówka dla profesjonalistów:** Plan kodowania oferuje 3× limit przy cenie 1/7! Resetuj codziennie o 10:00. + +#### MiniMax M2.1 (reset 5 godz., 0,20 USD/1 mln) + +1. Zarejestruj się: [MiniMax](https://www.minimax.io/) +2. Uzyskaj klucz API → Panel kontrolny → Dodaj klucz API + +**Użyj:** `minimax/MiniMax-M2.1` — **Wskazówka:** Najtańsza opcja dla długiego kontekstu (1 mln tokenów)! + +#### Kimi K2 (9 USD miesięcznie) + +1. Subskrybuj: [Moonshot AI](https://platform.moonshot.ai/) +2. Uzyskaj klucz API → Panel kontrolny → Dodaj klucz API + +**Zastosowanie:** `kimi/kimi-latest` — **Wskazówka dla profesjonalistów:** Stałe 9 USD/miesiąc za 10 mln tokenów = efektywny koszt 0,90 USD/1 mln! + +### 🆓 DARMOWE Dostawcy + +#### iFlow (8 DARMOWYCH modeli) + +```bash +Dashboard → Connect iFlow → OAuth login → Unlimited usage + +Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1 +``` + +#### Qwen (3 DARMOWE modele) + +```bash +Dashboard → Connect Qwen → Device code auth → Unlimited usage + +Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash +``` + +#### Kiro (Claude ZA DARMO) + +```bash +Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited + +Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5 +``` + +--- + +## 🎨 Kombinacje + +### Przykład 1: Maksymalizuj subskrypcję → Tania kopia zapasowa + +``` +Dashboard → Combos → Create New + +Name: premium-coding +Models: + 1. cc/claude-opus-4-6 (Subscription primary) + 2. glm/glm-4.7 (Cheap backup, $0.6/1M) + 3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M) + +Use in CLI: premium-coding +``` + +### Przykład 2: Tylko bezpłatny (zero kosztów) + +``` +Name: free-combo +Models: + 1. gc/gemini-3-flash-preview (180K free/month) + 2. if/kimi-k2-thinking (unlimited) + 3. qw/qwen3-coder-plus (unlimited) + +Cost: $0 forever! +``` + +--- + +## 🔧 Integracja z CLI + +### IDE kursora + +``` +Settings → Models → Advanced: + OpenAI API Base URL: http://localhost:20128/v1 + OpenAI API Key: [from omniroute dashboard] + Model: cc/claude-opus-4-6 +``` + +### Kod Claude’a + +Edytuj `~/.claude/config.json`: + +```json +{ + "anthropic_api_base": "http://localhost:20128/v1", + "anthropic_api_key": "your-omniroute-api-key" +} +``` + +### Interfejs wiersza polecenia Kodeksu + +```bash +export OPENAI_BASE_URL="http://localhost:20128" +export OPENAI_API_KEY="your-omniroute-api-key" +codex "your prompt" +``` + +### OpenClaw + +Edytuj `~/.openclaw/openclaw.json`: + +```json +{ + "agents": { + "defaults": { + "model": { "primary": "omniroute/if/glm-4.7" } + } + }, + "models": { + "providers": { + "omniroute": { + "baseUrl": "http://localhost:20128/v1", + "apiKey": "your-omniroute-api-key", + "api": "openai-completions", + "models": [{ "id": "if/glm-4.7", "name": "glm-4.7" }] + } + } + } +} +``` + +**Lub użyj Dashboardu:** Narzędzia CLI → OpenClaw → Auto-config + +### Kliknij / Kontynuuj / RooCode + +``` +Provider: OpenAI Compatible +Base URL: http://localhost:20128/v1 +API Key: [from dashboard] +Model: cc/claude-opus-4-6 +``` + +--- + +## 🚀 Wdrożenie + +### Wdrożenie VPS + +```bash +git clone https://github.com/diegosouzapw/OmniRoute.git +cd OmniRoute && npm install && npm run build + +export JWT_SECRET="your-secure-secret-change-this" +export INITIAL_PASSWORD="your-password" +export DATA_DIR="/var/lib/omniroute" +export PORT="20128" +export HOSTNAME="0.0.0.0" +export NODE_ENV="production" +export NEXT_PUBLIC_BASE_URL="http://localhost:20128" +export API_KEY_SECRET="endpoint-proxy-api-key-secret" + +npm run start +# Or: pm2 start npm --name omniroute -- start +``` + +### Doker + +```bash +# Build image (default = runner-cli with codex/claude/droid preinstalled) +docker build -t omniroute:cli . + +# Portable mode (recommended) +docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli +``` + +Informacje na temat trybu zintegrowanego z hostem i plików binarnych CLI można znaleźć w sekcji Docker w głównych dokumentach. + +### Zmienne środowiskowe + +| Zmienna | Domyślne | Opis | +| --------------------- | ------------------------------------ | ----------------------------------------------------------------------- | +| `JWT_SECRET` | `omniroute-default-secret-change-me` | Tajemnica podpisania JWT (**zmiana w produkcji**) | +| `INITIAL_PASSWORD` | `123456` | Hasło pierwszego logowania | +| `DATA_DIR` | `~/.omniroute` | Katalog danych (db, wykorzystanie, logi) | +| `PORT` | domyślne ramy | Port serwisowy (w przykładach `20128`) | +| `HOSTNAME` | domyślne ramy | Powiąż hosta (domyślnie Docker to `0.0.0.0`) | +| `NODE_ENV` | domyślne środowisko wykonawcze | Ustaw `production` dla wdrożenia | +| `BASE_URL` | `http://localhost:20128` | Wewnętrzny podstawowy adres URL po stronie serwera | +| `CLOUD_URL` | `https://omniroute.dev` | Podstawowy adres URL punktu końcowego synchronizacji w chmurze | +| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | Sekret HMAC dla wygenerowanych kluczy API | +| `REQUIRE_API_KEY` | `false` | Wymuś klucz API nośnika na `/v1/*` | +| `ENABLE_REQUEST_LOGS` | `false` | Włącza dzienniki żądań/odpowiedzi | +| `AUTH_COOKIE_SECURE` | `false` | Wymuś plik cookie uwierzytelniający `Secure` (za odwrotnym proxy HTTPS) | + +Aby zapoznać się z pełnym odwołaniem do zmiennej środowiskowej, zobacz [README](../README.md). + +--- + +## 📊 Dostępne modele + +
+Wyświetl wszystkie dostępne modele + +**Kod Claude (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001` + +**Kodeks (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max` + +**Gemini CLI (`gc/`)** — BEZPŁATNE: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro` + +**Kopilot GitHub (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet` + +**GLM (`glm/`)** — 0,6 USD/1 mln: `glm/glm-4.7` + +**MiniMax (`minimax/`)** — 0,2 USD/1 mln: `minimax/MiniMax-M2.1` + +**iFlow (`if/`)** — BEZPŁATNIE: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1` + +**Qwen (`qw/`)** — BEZPŁATNIE: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash` + +**Kiro (`kr/`)** — ZA DARMO: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5` + +**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner` + +**Groq (`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct` + +**xAI (`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini` + +**Mistral (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501` + +**Zakłopotanie (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar` + +**Wspólna AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo` + +** Sztuczna inteligencja fajerwerków (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1` + +**Mózgi (`cerebras/`)**: `cerebras/llama-3.3-70b` + +**Spójność (`cohere/`)**: `cohere/command-r-plus-08-2024` + +**NVIDIA NIM (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct` + +
+ +--- + +## 🧩 Zaawansowane funkcje + +### Modele niestandardowe + +Dodaj dowolny identyfikator modelu do dowolnego dostawcy, nie czekając na aktualizację aplikacji: + +```bash +# Via API +curl -X POST http://localhost:20128/api/provider-models \ + -H "Content-Type: application/json" \ + -d '{"provider": "openai", "modelId": "gpt-4.5-preview", "modelName": "GPT-4.5 Preview"}' + +# List: curl http://localhost:20128/api/provider-models?provider=openai +# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview" +``` + +Lub użyj Panelu: **Dostawcy → [Dostawca] → Modele niestandardowe**. + +### Dedykowane trasy dostawców + +Kieruj żądania bezpośrednio do konkretnego dostawcy z walidacją modelu: + +```bash +POST http://localhost:20128/v1/providers/openai/chat/completions +POST http://localhost:20128/v1/providers/openai/embeddings +POST http://localhost:20128/v1/providers/fireworks/images/generations +``` + +Prefiks dostawcy jest dodawany automatycznie, jeśli go brakuje. Niedopasowane modele zwracają `400`. + +### Konfiguracja serwera proxy sieci + +```bash +# Set global proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"global": {"type":"http","host":"proxy.example.com","port":"8080"}}' + +# Per-provider proxy +curl -X PUT http://localhost:20128/api/settings/proxy \ + -d '{"providers": {"openai": {"type":"socks5","host":"proxy.example.com","port":"1080"}}}' + +# Test proxy +curl -X POST http://localhost:20128/api/settings/proxy/test \ + -d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}' +``` + +**Pierwszeństwo:** specyficzne dla klucza → specyficzne dla kombinacji → specyficzne dla dostawcy → globalne → środowisko. + +### API katalogu modeli + +```bash +curl http://localhost:20128/api/models/catalog +``` + +Zwraca modele pogrupowane według dostawcy z typami (`chat`, `embedding`, `image`). + +### Synchronizacja z chmurą + +- Synchronizuj dostawców, kombinacje i ustawienia na różnych urządzeniach +- Automatyczna synchronizacja w tle z limitem czasu + szybka awaria +- Preferuj po stronie serwera `BASE_URL`/`CLOUD_URL` w produkcji + +### Inteligencja bramy LLM (faza 9) + +- **Semantyczna pamięć podręczna** — automatycznie buforuje dane niestrumieniowe, temperatura = 0 odpowiedzi (pomiń za pomocą `X-OmniRoute-No-Cache: true`) +- **Idempotencja żądania** — Deduplikuje żądania w ciągu 5 sekund za pośrednictwem nagłówka `Idempotency-Key` lub `X-Request-Id` +- **Śledzenie postępu** — Zgoda na zdarzenia SSE `event: progress` poprzez nagłówek `X-OmniRoute-Progress: true` + +--- + +### Plac zabaw dla tłumaczy + +Dostęp przez **Panel kontrolny → Tłumacz**. Debuguj i wizualizuj, jak OmniRoute tłumaczy żądania API między dostawcami. + +| Tryb | Cel | +| ------------------------- | --------------------------------------------------------------------------------------------------- | +| **Plac zabaw** | Wybierz formaty źródłowe/docelowe, wklej żądanie i natychmiast zobacz przetłumaczone dane wyjściowe | +| **Tester czatu** | Wysyłaj wiadomości na czacie na żywo przez serwer proxy i sprawdzaj pełny cykl żądań/odpowiedzi | +| **Stolik testowy** | Przeprowadź testy wsadowe w wielu kombinacjach formatów, aby sprawdzić poprawność tłumaczenia | +| **Monitorowanie na żywo** | Oglądaj tłumaczenia w czasie rzeczywistym, gdy żądania przepływają przez serwer proxy | + +**Przypadki użycia:** + +- Debugowanie, dlaczego konkretna kombinacja klient/dostawca nie działa +- Sprawdź, czy znaczniki myślenia, wywołania narzędzi i podpowiedzi systemowe są tłumaczone poprawnie +- Porównaj różnice w formatach między formatami OpenAI, Claude, Gemini i Responses API + +--- + +### Strategie routingu + +Skonfiguruj za pomocą **Panel kontrolny → Ustawienia → Routing**. + +| Strategia | Opis | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------- | +| **Najpierw wypełnij** | Używa kont w kolejności priorytetów — konto podstawowe obsługuje wszystkie żądania, aż będą niedostępne | +| **Robinowy** | Przełącza między wszystkimi kontami z konfigurowalnym limitem stałym (domyślnie: 3 połączenia na konto) | +| **P2C (potęga dwóch wyborów)** | Wybiera 2 losowe konta i ścieżki do zdrowszego — równoważy obciążenie świadomością zdrowia | +| **Losowe** | Losowo wybiera konto dla każdego żądania, korzystając z funkcji losowania Fisher-Yates | +| **Najrzadziej używane** | Kieruje do konta z najstarszym `lastUsedAt` znacznikiem czasu, równomiernie rozprowadzając ruch | +| **Optymalizacja kosztów** | Kieruje do konta o najniższej wartości priorytetu, optymalizując pod kątem dostawców o najniższych kosztach | + +#### Aliasy modeli z symbolami wieloznacznymi + +Utwórz wzorce symboli wieloznacznych, aby ponownie przypisać nazwy modeli: + +``` +Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929 +Pattern: gpt-* → Target: gh/gpt-5.1-codex +``` + +Symbole wieloznaczne obsługują `*` (dowolne znaki) i `?` (pojedynczy znak). + +#### Łańcuchy awaryjne + +Zdefiniuj globalne łańcuchy awaryjne, które mają zastosowanie do wszystkich żądań: + +``` +Chain: production-fallback + 1. cc/claude-opus-4-6 + 2. gh/gpt-5.1-codex + 3. glm/glm-4.7 +``` + +--- + +### Odporność i wyłączniki automatyczne + +Skonfiguruj za pomocą **Panel kontrolny → Ustawienia → Odporność**. + +OmniRoute wdraża odporność na poziomie dostawcy za pomocą czterech komponentów: + +1. **Profile dostawców** — konfiguracja dla poszczególnych dostawców dla: + - Próg awaryjności (ile awarii przed otwarciem) + - Czas odnowienia + - Czułość wykrywania limitu szybkości + - Wykładnicze parametry wycofywania + +2. **Edytowalne limity prędkości** — Domyślne ustawienia na poziomie systemu można skonfigurować w panelu kontrolnym: + - **Żądania na minutę (RPM)** — Maksymalna liczba żądań na minutę na konto + - **Min. czas między żądaniami** — Minimalna przerwa w milisekundach między żądaniami + - **Maksymalna liczba jednoczesnych żądań** — Maksymalna liczba jednoczesnych żądań na konto + - Kliknij **Edytuj**, aby zmodyfikować, a następnie **Zapisz** lub **Anuluj**. Wartości są zachowywane za pośrednictwem interfejsu API odporności. + +3. **Wyłącznik** — śledzi awarie według dostawcy i automatycznie otwiera obwód po osiągnięciu progu: + - **ZAMKNIĘTE** (zdrowe) — Żądania przebiegają normalnie + - **OTWARTE** — Dostawca jest tymczasowo blokowany po powtarzających się awariach + - **HALF_OPEN** — Sprawdzanie, czy dostawca odzyskał siły + +4. **Zasady i zablokowane identyfikatory** — Pokazuje stan wyłącznika automatycznego i zablokowane identyfikatory z możliwością wymuszonego odblokowania. + +5. **Automatyczne wykrywanie limitów szybkości** — Monitoruje nagłówki `429` i `Retry-After`, aby aktywnie zapobiegać przekroczeniu limitów stawek dostawcy. + +**Wskazówka dla profesjonalistów:** Użyj przycisku **Resetuj wszystko**, aby wyczyścić wszystkie wyłączniki automatyczne i czasy odnowienia, gdy dostawca wznowi działanie po awarii. + +--- + +### Eksport/import bazy danych + +Zarządzaj kopiami zapasowymi baz danych w **Panel kontrolny → Ustawienia → System i pamięć masowa**. + +| Akcja | Opis | +| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Eksportuj bazę danych** | Pobiera bieżącą bazę danych SQLite jako plik `.sqlite` | +| **Eksportuj wszystko (.tar.gz)** | Pobiera pełne archiwum kopii zapasowych, w tym: bazę danych, ustawienia, kombinacje, połączenia z dostawcami (bez poświadczeń), metadane klucza API | +| **Importuj bazę danych** | Prześlij plik `.sqlite`, aby zastąpić bieżącą bazę danych. Automatycznie tworzona jest kopia zapasowa przed importem | + +```bash +# API: Export database +curl -o backup.sqlite http://localhost:20128/api/db-backups/export + +# API: Export all (full archive) +curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll + +# API: Import database +curl -X POST http://localhost:20128/api/db-backups/import \ + -F "file=@backup.sqlite" +``` + +**Weryfikacja importu:** Zaimportowany plik jest sprawdzany pod kątem integralności (sprawdzanie pragma SQLite), wymaganych tabel (`provider_connections`, `provider_nodes`, `combos`, `api_keys`) i rozmiaru (maks. 100MB). + +**Przypadki użycia:** + +- Przeprowadź migrację OmniRoute pomiędzy maszynami +- Twórz zewnętrzne kopie zapasowe w celu odzyskiwania po awarii +- Udostępniaj konfiguracje pomiędzy członkami zespołu (eksportuj wszystko → udostępnij archiwum) + +--- + +### Panel ustawień + +Strona ustawień jest podzielona na 5 zakładek ułatwiających nawigację: + +| Zakładka | Spis treści | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| **Bezpieczeństwo** | Ustawienia logowania/hasła, kontrola dostępu IP, autoryzacja API dla `/models` i blokowanie dostawców | +| **Trasowanie** | Globalna strategia routingu (6 opcji), aliasy modeli z symbolami wieloznacznymi, łańcuchy awaryjne, domyślne kombinacje | +| **Odporność** | Profile dostawców, edytowalne limity stawek, stan wyłącznika, zasady i zablokowane identyfikatory | +| **AI** | Myślenie o konfiguracji budżetu, globalnym wstrzykiwaniu podpowiedzi do systemu, szybkich statystykach pamięci podręcznej | +| **Zaawansowane** | Globalna konfiguracja proxy (HTTP/SOCKS5) | + +--- + +### Zarządzanie kosztami i budżetem + +Dostęp przez **Panel kontrolny → Koszty**. + +| Zakładka | Cel | +| ---------- | --------------------------------------------------------------------------------------------------------------------- | +| **Budżet** | Ustaw limity wydatków na klucz API z budżetami dziennymi/tygodniowymi/miesięcznymi i śledzeniem w czasie rzeczywistym | +| **Cennik** | Wyświetlaj i edytuj wpisy cen modelu — koszt za 1 tys. tokenów wejścia/wyjścia na dostawcę | + +```bash +# API: Set a budget +curl -X POST http://localhost:20128/api/usage/budget \ + -H "Content-Type: application/json" \ + -d '{"keyId": "key-123", "limit": 50.00, "period": "monthly"}' + +# API: Get current budget status +curl http://localhost:20128/api/usage/budget +``` + +**Śledzenie kosztów:** Każde żądanie rejestruje użycie tokena i oblicza koszt, korzystając z tabeli cen. Zobacz zestawienia w **Panel kontrolny → Użycie** według dostawcy, modelu i klucza API. + +--- + +### Transkrypcja audio + +OmniRoute obsługuje transkrypcję audio za pośrednictwem punktu końcowego kompatybilnego z OpenAI: + +```bash +POST /v1/audio/transcriptions +Authorization: Bearer your-api-key +Content-Type: multipart/form-data + +# Example with curl +curl -X POST http://localhost:20128/v1/audio/transcriptions \ + -H "Authorization: Bearer your-api-key" \ + -F "file=@audio.mp3" \ + -F "model=deepgram/nova-3" +``` + +Dostępni dostawcy: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`). + +Obsługiwane formaty audio: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. + +--- + +### Strategie równoważenia kombinacji + +Skonfiguruj równoważenie poszczególnych kombinacji w **Panel sterowania → Kombinacje → Utwórz/edytuj → Strategia**. + +| Strategia | Opis | +| ------------------------- | --------------------------------------------------------------------------------- | +| **Równy z każdym** | Obraca modele sekwencyjnie | +| **Priorytet** | Zawsze wypróbowuje pierwszy model; powraca tylko w przypadku błędu | +| **Losowe** | Wybiera losowy model z kombinacji dla każdego żądania | +| **Ważona** | Trasy proporcjonalnie na podstawie przypisanych wag do modelu | +| **Najrzadziej używane** | Trasy do modelu z najmniejszą liczbą ostatnich żądań (wykorzystuje metryki kombi) | +| **Optymalizacja kosztów** | Trasy do najtańszego dostępnego modelu (korzysta z tabeli cen) | + +Globalne ustawienia domyślne kombinacji można ustawić w **Panel sterowania → Ustawienia → Routing → Domyślne ustawienia kombinacji**. + +--- + +### Panel zdrowia + +Dostęp przez **Panel kontrolny → Zdrowie**. Przegląd stanu systemu w czasie rzeczywistym za pomocą 6 kart: + +| Karta | Co to pokazuje | +| ----------------------------- | --------------------------------------------------------------------------------- | +| **Stan systemu** | Czas pracy, wersja, wykorzystanie pamięci, katalog danych | +| **Zdrowie dostawcy** | Stan wyłącznika automatycznego dostawcy (zamknięty/otwarty/półotwarty) | +| **Limity stawek** | Aktywne czasy odnowienia limitu szybkości na konto z pozostałym czasem | +| **Aktywne blokady** | Dostawcy tymczasowo zablokowani przez politykę blokad | +| **Pamięć podręczna podpisów** | Statystyki pamięci podręcznej deduplikacji (aktywne klucze, współczynnik trafień) | +| **Telemetria opóźnień** | Agregacja opóźnień p50/p95/p99 na dostawcę | + +**Wskazówka dla profesjonalistów:** Strona Zdrowie odświeża się automatycznie co 10 sekund. Użyj karty wyłącznika, aby zidentyfikować dostawców, u których występują problemy.