diff --git a/docs/i18n/zh-CN/A2A-SERVER.md b/docs/i18n/zh-CN/A2A-SERVER.md index 01531ff4..1a3c8b0f 100644 --- a/docs/i18n/zh-CN/A2A-SERVER.md +++ b/docs/i18n/zh-CN/A2A-SERVER.md @@ -1,38 +1,36 @@ -🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/A2A-SERVER.md) · 🇪🇸 [es](../es/A2A-SERVER.md) · 🇫🇷 [fr](../fr/A2A-SERVER.md) · 🇩🇪 [de](../de/A2A-SERVER.md) · 🇮🇹 [it](../it/A2A-SERVER.md) · 🇷🇺 [ru](../ru/A2A-SERVER.md) · 🇨🇳 [zh-CN](../zh-CN/A2A-SERVER.md) · 🇯🇵 [ja](../ja/A2A-SERVER.md) · 🇰🇷 [ko](../ko/A2A-SERVER.md) · 🇸🇦 [ar](../ar/A2A-SERVER.md) · 🇮🇳 [in](../in/A2A-SERVER.md) · 🇹🇭 [th](../th/A2A-SERVER.md) · 🇻🇳 [vi](../vi/A2A-SERVER.md) · 🇮🇩 [id](../id/A2A-SERVER.md) · 🇲🇾 [ms](../ms/A2A-SERVER.md) · 🇳🇱 [nl](../nl/A2A-SERVER.md) · 🇵🇱 [pl](../pl/A2A-SERVER.md) · 🇸🇪 [sv](../sv/A2A-SERVER.md) · 🇳🇴 [no](../no/A2A-SERVER.md) · 🇩🇰 [da](../da/A2A-SERVER.md) · 🇫🇮 [fi](../fi/A2A-SERVER.md) · 🇵🇹 [pt](../pt/A2A-SERVER.md) · 🇷🇴 [ro](../ro/A2A-SERVER.md) · 🇭🇺 [hu](../hu/A2A-SERVER.md) · 🇧🇬 [bg](../bg/A2A-SERVER.md) · 🇸🇰 [sk](../sk/A2A-SERVER.md) · 🇺🇦 [uk-UA](../uk-UA/A2A-SERVER.md) · 🇮🇱 [he](../he/A2A-SERVER.md) · 🇵🇭 [phi](../phi/A2A-SERVER.md) +# OmniRoute A2A 服务器文档 ---- +🌐 **语言:** 🇺🇸 [English](../../A2A-SERVER.md) · 🇧🇷 [pt-BR](../pt-BR/A2A-SERVER.md) · 🇪🇸 [es](../es/A2A-SERVER.md) · 🇫🇷 [fr](../fr/A2A-SERVER.md) · 🇩🇪 [de](../de/A2A-SERVER.md) · 🇮🇹 [it](../it/A2A-SERVER.md) · 🇷🇺 [ru](../ru/A2A-SERVER.md) · 🇨🇳 [zh-CN](../zh-CN/A2A-SERVER.md) · 🇯🇵 [ja](../ja/A2A-SERVER.md) · 🇰🇷 [ko](../ko/A2A-SERVER.md) · 🇸🇦 [ar](../ar/A2A-SERVER.md) · 🇮🇳 [in](../in/A2A-SERVER.md) · 🇹🇭 [th](../th/A2A-SERVER.md) · 🇻🇳 [vi](../vi/A2A-SERVER.md) · 🇮🇩 [id](../id/A2A-SERVER.md) · 🇲🇾 [ms](../ms/A2A-SERVER.md) · 🇳🇱 [nl](../nl/A2A-SERVER.md) · 🇵🇱 [pl](../pl/A2A-SERVER.md) · 🇸🇪 [sv](../sv/A2A-SERVER.md) · 🇳🇴 [no](../no/A2A-SERVER.md) · 🇩🇰 [da](../da/A2A-SERVER.md) · 🇫🇮 [fi](../fi/A2A-SERVER.md) · 🇵🇹 [pt](../pt/A2A-SERVER.md) · 🇷🇴 [ro](../ro/A2A-SERVER.md) · 🇭🇺 [hu](../hu/A2A-SERVER.md) · 🇧🇬 [bg](../bg/A2A-SERVER.md) · 🇸🇰 [sk](../sk/A2A-SERVER.md) · 🇺🇦 [uk-UA](../uk-UA/A2A-SERVER.md) · 🇮🇱 [he](../he/A2A-SERVER.md) · 🇵🇭 [phi](../phi/A2A-SERVER.md) · 🇨🇿 [cs](../cs/A2A-SERVER.md) -# OmniRoute A2A Server Documentation +> Agent-to-Agent Protocol v0.3 — OmniRoute 作为智能路由代理 -> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent - -## Agent Discovery +## 代理发现 ```bash curl http://localhost:20128/.well-known/agent.json ``` -Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements. +返回描述 OmniRoute 能力、技能和身份验证要求的 Agent Card。 --- -## Authentication +## 身份验证 -All `/a2a` requests require an API key via the `Authorization` header: +所有 `/a2a` 请求需要通过 `Authorization` 头部提供 API 密钥: ``` Authorization: Bearer YOUR_OMNIROUTE_API_KEY ``` -If no API key is configured on the server, authentication is bypassed. +如果服务器未配置 API 密钥,则跳过身份验证。 --- -## JSON-RPC 2.0 Methods +## JSON-RPC 2.0 方法 -### `message/send` — Synchronous Execution +### `message/send` — 同步执行 -Sends a message to a skill and waits for the complete response. +向技能发送消息并等待完整响应。 ```bash curl -X POST http://localhost:20128/a2a \ @@ -50,7 +48,7 @@ curl -X POST http://localhost:20128/a2a \ }' ``` -**Response:** +**响应:** ```json { @@ -71,9 +69,9 @@ curl -X POST http://localhost:20128/a2a \ } ``` -### `message/stream` — SSE Streaming +### `message/stream` — SSE 流式传输 -Same as `message/send` but returns Server-Sent Events for real-time streaming. +与 `message/send` 相同,但返回 Server-Sent Events 进行实时流式传输。 ```bash curl -N -X POST http://localhost:20128/a2a \ @@ -90,7 +88,7 @@ curl -N -X POST http://localhost:20128/a2a \ }' ``` -**SSE Events:** +**SSE 事件:** ``` data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"..."}}} @@ -100,7 +98,7 @@ data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","s data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}} ``` -### `tasks/get` — Query Task Status +### `tasks/get` — 查询任务状态 ```bash curl -X POST http://localhost:20128/a2a \ @@ -109,7 +107,7 @@ curl -X POST http://localhost:20128/a2a \ -d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}' ``` -### `tasks/cancel` — Cancel a Task +### `tasks/cancel` — 取消任务 ```bash curl -X POST http://localhost:20128/a2a \ @@ -120,16 +118,16 @@ curl -X POST http://localhost:20128/a2a \ --- -## Available Skills +## 可用技能 -| Skill | Description | -| :----------------- | :------------------------------------------------------------------------------------------------------------------------------ | -| `smart-routing` | Routes prompts through OmniRoute's intelligent pipeline. Returns response with routing explanation, cost, and resilience trace. | -| `quota-management` | Answers natural-language queries about provider quotas, suggests free combos, and provides quota rankings. | +| 技能 | 描述 | +| :----------------- | :---------------------------------------------------------------------------------------------- | +| `smart-routing` | 通过 OmniRoute 的智能管道路由提示。返回带有路由说明、成本和弹性追踪的响应。 | +| `quota-management` | 回答关于服务商配额的自然语言查询,建议免费组合,并提供配额排名。 | --- -## Task Lifecycle +## 任务生命周期 ``` submitted → working → completed @@ -137,25 +135,25 @@ submitted → working → completed → cancelled ``` -- Tasks expire after 5 minutes (configurable) -- Terminal states: `completed`, `failed`, `cancelled` -- Event log tracks every state transition +- 任务在 5 分钟后过期(可配置) +- 终止状态:`completed`、`failed`、`cancelled` +- 事件日志跟踪每个状态转换 --- -## Error Codes +## 错误代码 -| Code | Meaning | -| :----- | :----------------------------- | -| -32700 | Parse error (invalid JSON) | -| -32600 | Invalid request / Unauthorized | -| -32601 | Method or skill not found | -| -32602 | Invalid params | -| -32603 | Internal error | +| 代码 | 含义 | +| :----- | :-------------------------- | +| -32700 | 解析错误(无效 JSON) | +| -32600 | 无效请求 / 未授权 | +| -32601 | 方法或技能未找到 | +| -32602 | 无效参数 | +| -32603 | 内部错误 | --- -## Integration Examples +## 集成示例 ### Python (requests) diff --git a/docs/i18n/zh-CN/API_REFERENCE.md b/docs/i18n/zh-CN/API_REFERENCE.md index b8786052..5f28a0c5 100644 --- a/docs/i18n/zh-CN/API_REFERENCE.md +++ b/docs/i18n/zh-CN/API_REFERENCE.md @@ -1,26 +1,22 @@ -🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/API_REFERENCE.md) · 🇪🇸 [es](../es/API_REFERENCE.md) · 🇫🇷 [fr](../fr/API_REFERENCE.md) · 🇩🇪 [de](../de/API_REFERENCE.md) · 🇮🇹 [it](../it/API_REFERENCE.md) · 🇷🇺 [ru](../ru/API_REFERENCE.md) · 🇨🇳 [zh-CN](../zh-CN/API_REFERENCE.md) · 🇯🇵 [ja](../ja/API_REFERENCE.md) · 🇰🇷 [ko](../ko/API_REFERENCE.md) · 🇸🇦 [ar](../ar/API_REFERENCE.md) · 🇮🇳 [in](../in/API_REFERENCE.md) · 🇹🇭 [th](../th/API_REFERENCE.md) · 🇻🇳 [vi](../vi/API_REFERENCE.md) · 🇮🇩 [id](../id/API_REFERENCE.md) · 🇲🇾 [ms](../ms/API_REFERENCE.md) · 🇳🇱 [nl](../nl/API_REFERENCE.md) · 🇵🇱 [pl](../pl/API_REFERENCE.md) · 🇸🇪 [sv](../sv/API_REFERENCE.md) · 🇳🇴 [no](../no/API_REFERENCE.md) · 🇩🇰 [da](../da/API_REFERENCE.md) · 🇫🇮 [fi](../fi/API_REFERENCE.md) · 🇵🇹 [pt](../pt/API_REFERENCE.md) · 🇷🇴 [ro](../ro/API_REFERENCE.md) · 🇭🇺 [hu](../hu/API_REFERENCE.md) · 🇧🇬 [bg](../bg/API_REFERENCE.md) · 🇸🇰 [sk](../sk/API_REFERENCE.md) · 🇺🇦 [uk-UA](../uk-UA/API_REFERENCE.md) · 🇮🇱 [he](../he/API_REFERENCE.md) · 🇵🇭 [phi](../phi/API_REFERENCE.md) +# API 参考 + +🌐 **语言:** 🇺🇸 [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) | 🇨🇿 [Čeština](../cs/API_REFERENCE.md) + +所有 OmniRoute API 端点的完整参考。 --- -# API Reference - -🌐 **Languages:** 🇺🇸 [English](API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](i18n/es/API_REFERENCE.md) | 🇫🇷 [Français](i18n/fr/API_REFERENCE.md) | 🇮🇹 [Italiano](i18n/it/API_REFERENCE.md) | 🇷🇺 [Русский](i18n/ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](i18n/de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](i18n/in/API_REFERENCE.md) | 🇹🇭 [ไทย](i18n/th/API_REFERENCE.md) | 🇺🇦 [Українська](i18n/uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](i18n/ar/API_REFERENCE.md) | 🇯🇵 [日本語](i18n/ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/API_REFERENCE.md) | 🇧🇬 [Български](i18n/bg/API_REFERENCE.md) | 🇩🇰 [Dansk](i18n/da/API_REFERENCE.md) | 🇫🇮 [Suomi](i18n/fi/API_REFERENCE.md) | 🇮🇱 [עברית](i18n/he/API_REFERENCE.md) | 🇭🇺 [Magyar](i18n/hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/API_REFERENCE.md) | 🇰🇷 [한국어](i18n/ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](i18n/nl/API_REFERENCE.md) | 🇳🇴 [Norsk](i18n/no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/API_REFERENCE.md) | 🇷🇴 [Română](i18n/ro/API_REFERENCE.md) | 🇵🇱 [Polski](i18n/pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](i18n/sk/API_REFERENCE.md) | 🇸🇪 [Svenska](i18n/sv/API_REFERENCE.md) | 🇵🇭 [Filipino](i18n/phi/API_REFERENCE.md) - -Complete reference for all OmniRoute API endpoints. - ---- - -## Table of Contents +## 目录 - [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) +- [图像生成](#图像生成) +- [模型列表](#模型列表) +- [兼容性端点](#兼容性端点) +- [语义缓存](#语义缓存) +- [Dashboard 与管理](#dashboard-与管理) +- [请求处理](#请求处理) +- [认证](#认证) --- @@ -40,17 +36,22 @@ Content-Type: application/json } ``` -### Custom Headers +### 自定义请求头 -| Header | Direction | Description | -| ------------------------ | --------- | --------------------------------- | -| `X-OmniRoute-No-Cache` | Request | Set to `true` to bypass cache | -| `X-OmniRoute-Progress` | Request | Set to `true` for progress events | -| `Idempotency-Key` | Request | Dedup key (5s window) | -| `X-Request-Id` | Request | Alternative dedup key | -| `X-OmniRoute-Cache` | Response | `HIT` or `MISS` (non-streaming) | -| `X-OmniRoute-Idempotent` | Response | `true` if deduplicated | -| `X-OmniRoute-Progress` | Response | `enabled` if progress tracking on | +| 请求头 | 方向 | 描述 | +| ------------------------ | ------ | ------------------------------------- | +| `X-OmniRoute-No-Cache` | 请求 | 设为 `true` 绕过缓存 | +| `X-OmniRoute-Progress` | 请求 | 设为 `true` 启用进度事件 | +| `X-Session-Id` | 请求 | 用于外部会话亲和性的粘性会话密钥 | +| `x_session_id` | 请求 | 下划线变体也被接受(直接 HTTP) | +| `Idempotency-Key` | 请求 | 去重密钥(5秒窗口) | +| `X-Request-Id` | 请求 | 备用去重密钥 | +| `X-OmniRoute-Cache` | 响应 | `HIT` 或 `MISS`(非流式) | +| `X-OmniRoute-Idempotent` | 响应 | 如果已去重则为 `true` | +| `X-OmniRoute-Progress` | 响应 | 如果启用进度追踪则为 `enabled` | +| `X-OmniRoute-Session-Id` | 响应 | OmniRoute 使用的有效会话 ID | + +> **Nginx 注意**: 如果您依赖下划线请求头(例如 `x_session_id`),请启用 `underscores_in_headers on;`。 --- @@ -67,16 +68,16 @@ Content-Type: application/json } ``` -Available providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA. +可用提供商:Nebius、OpenAI、Mistral、Together AI、Fireworks、NVIDIA。 ```bash -# List all embedding models +# 列出所有 Embedding 模型 GET /v1/embeddings ``` --- -## Image Generation +## 图像生成 ```bash POST /v1/images/generations @@ -90,42 +91,42 @@ Content-Type: application/json } ``` -Available providers: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI. +可用提供商:OpenAI (DALL-E)、xAI (Grok Image)、Together AI (FLUX)、Fireworks AI。 ```bash -# List all image models +# 列出所有图像模型 GET /v1/images/generations ``` --- -## List Models +## 模型列表 ```bash GET /v1/models Authorization: Bearer your-api-key -→ Returns all chat, embedding, and image models + combos in OpenAI format +→ 以 OpenAI 格式返回所有 chat、embedding 和 image 模型 + combos ``` --- -## Compatibility Endpoints +## 兼容性端点 -| Method | Path | Format | -| ------ | --------------------------- | ---------------------- | -| POST | `/v1/chat/completions` | OpenAI | -| POST | `/v1/messages` | Anthropic | -| POST | `/v1/responses` | OpenAI Responses | -| POST | `/v1/embeddings` | OpenAI | -| POST | `/v1/images/generations` | OpenAI | -| GET | `/v1/models` | OpenAI | -| POST | `/v1/messages/count_tokens` | Anthropic | -| GET | `/v1beta/models` | Gemini | -| POST | `/v1beta/models/{...path}` | Gemini generateContent | -| POST | `/v1/api/chat` | Ollama | +| 方法 | 路径 | 格式 | +| ---- | --------------------------- | -------------------- | +| POST | `/v1/chat/completions` | OpenAI | +| POST | `/v1/messages` | Anthropic | +| POST | `/v1/responses` | OpenAI Responses | +| POST | `/v1/embeddings` | OpenAI | +| POST | `/v1/images/generations` | OpenAI | +| GET | `/v1/models` | OpenAI | +| POST | `/v1/messages/count_tokens` | Anthropic | +| GET | `/v1beta/models` | Gemini | +| POST | `/v1beta/models/{...path}` | Gemini generateContent | +| POST | `/v1/api/chat` | Ollama | -### Dedicated Provider Routes +### 专用提供商路由 ```bash POST /v1/providers/{provider}/chat/completions @@ -133,21 +134,21 @@ POST /v1/providers/{provider}/embeddings POST /v1/providers/{provider}/images/generations ``` -The provider prefix is auto-added if missing. Mismatched models return `400`. +如果缺少提供商前缀则自动添加。模型不匹配时返回 `400`。 --- -## Semantic Cache +## 语义缓存 ```bash -# Get cache stats -GET /api/cache +# 获取缓存统计 +GET /api/cache/stats -# Clear all caches -DELETE /api/cache +# 清除所有缓存 +DELETE /api/cache/stats ``` -Response example: +响应示例: ```json { @@ -166,164 +167,171 @@ Response example: --- -## Dashboard & Management +## Dashboard 与管理 -### Authentication +### 认证 -| Endpoint | Method | Description | -| ----------------------------- | ------- | --------------------- | -| `/api/auth/login` | POST | Login | -| `/api/auth/logout` | POST | Logout | -| `/api/settings/require-login` | GET/PUT | Toggle login required | +| 端点 | 方法 | 描述 | +| ----------------------------- | ------- | ---------------- | +| `/api/auth/login` | POST | 登录 | +| `/api/auth/logout` | POST | 登出 | +| `/api/settings/require-login` | GET/PUT | 切换是否需要登录 | -### Provider Management +### 提供商管理 -| Endpoint | Method | Description | -| ---------------------------- | --------------- | ------------------------ | -| `/api/providers` | GET/POST | List / create providers | -| `/api/providers/[id]` | GET/PUT/DELETE | Manage a provider | -| `/api/providers/[id]/test` | POST | Test provider connection | -| `/api/providers/[id]/models` | GET | List provider models | -| `/api/providers/validate` | POST | Validate provider config | -| `/api/provider-nodes*` | Various | Provider node management | -| `/api/provider-models` | GET/POST/DELETE | Custom models | +| 端点 | 方法 | 描述 | +| ---------------------------- | --------------- | ---------------- | +| `/api/providers` | GET/POST | 列出/创建提供商 | +| `/api/providers/[id]` | GET/PUT/DELETE | 管理提供商 | +| `/api/providers/[id]/test` | POST | 测试提供商连接 | +| `/api/providers/[id]/models` | GET | 列出提供商模型 | +| `/api/providers/validate` | POST | 验证提供商配置 | +| `/api/provider-nodes*` | 多种 | 提供商节点管理 | +| `/api/provider-models` | GET/POST/DELETE | 自定义模型 | -### OAuth Flows +### OAuth 流程 -| Endpoint | Method | Description | -| -------------------------------- | ------- | ----------------------- | -| `/api/oauth/[provider]/[action]` | Various | Provider-specific OAuth | +| 端点 | 方法 | 描述 | +| -------------------------------- | ----- | ------------------ | +| `/api/oauth/[provider]/[action]` | 多种 | 提供商特定的 OAuth | -### Routing & Config +### 路由与配置 -| Endpoint | Method | Description | -| --------------------- | -------- | ----------------------------- | -| `/api/models/alias` | GET/POST | Model aliases | -| `/api/models/catalog` | GET | All models by provider + type | -| `/api/combos*` | Various | Combo management | -| `/api/keys*` | Various | API key management | -| `/api/pricing` | GET | Model pricing | +| 端点 | 方法 | 描述 | +| --------------------- | -------- | -------------------------- | +| `/api/models/alias` | GET/POST | 模型别名 | +| `/api/models/catalog` | GET | 按提供商 + 类型的所有模型 | +| `/api/combos*` | 多种 | Combo 管理 | +| `/api/keys*` | 多种 | API 密钥管理 | +| `/api/pricing` | GET | 模型定价 | -### Usage & Analytics +### 用量与分析 -| Endpoint | Method | Description | -| --------------------------- | ------ | -------------------- | -| `/api/usage/history` | GET | Usage history | -| `/api/usage/logs` | GET | Usage logs | -| `/api/usage/request-logs` | GET | Request-level logs | -| `/api/usage/[connectionId]` | GET | Per-connection usage | +| 端点 | 方法 | 描述 | +| --------------------------- | ---- | ---------------- | +| `/api/usage/history` | GET | 用量历史 | +| `/api/usage/logs` | GET | 用量日志 | +| `/api/usage/request-logs` | GET | 请求级别日志 | +| `/api/usage/[connectionId]` | GET | 按连接的用量 | -### Settings +### 设置 -| Endpoint | Method | Description | -| ------------------------------- | ------- | ---------------------- | -| `/api/settings` | GET/PUT | General settings | -| `/api/settings/proxy` | GET/PUT | Network proxy config | -| `/api/settings/proxy/test` | POST | Test proxy connection | -| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist | -| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget | -| `/api/settings/system-prompt` | GET/PUT | Global system prompt | +| 端点 | 方法 | 描述 | +| ------------------------------- | ------------- | ------------------ | +| `/api/settings` | GET/PUT/PATCH | 常规设置 | +| `/api/settings/proxy` | GET/PUT | 网络代理配置 | +| `/api/settings/proxy/test` | POST | 测试代理连接 | +| `/api/settings/ip-filter` | GET/PUT | IP 白名单/黑名单 | +| `/api/settings/thinking-budget` | GET/PUT | 推理 token 预算 | +| `/api/settings/system-prompt` | GET/PUT | 全局系统提示词 | -### Monitoring +### 监控 -| Endpoint | Method | Description | -| ------------------------ | ---------- | ----------------------- | -| `/api/sessions` | GET | Active session tracking | -| `/api/rate-limits` | GET | Per-account rate limits | -| `/api/monitoring/health` | GET | Health check | -| `/api/cache` | GET/DELETE | Cache stats / clear | +| 端点 | 方法 | 描述 | +| ------------------------ | ---------- | ----------------------------------------------------------- | +| `/api/sessions` | GET | 活跃会话追踪 | +| `/api/rate-limits` | GET | 每账户速率限制 | +| `/api/monitoring/health` | GET | 健康检查 + 提供商摘要(`catalogCount`、`configuredCount`、`activeCount`、`monitoredCount`) | +| `/api/cache/stats` | GET/DELETE | 缓存统计 / 清除 | -### Backup & Export/Import +### 备份与导出/导入 -| Endpoint | Method | Description | -| --------------------------- | ------ | --------------------------------------- | -| `/api/db-backups` | GET | List available backups | -| `/api/db-backups` | PUT | Create a manual backup | -| `/api/db-backups` | POST | Restore from a specific backup | -| `/api/db-backups/export` | GET | Download database as .sqlite file | -| `/api/db-backups/import` | POST | Upload .sqlite file to replace database | -| `/api/db-backups/exportAll` | GET | Download full backup as .tar.gz archive | +| 端点 | 方法 | 描述 | +| --------------------------- | ---- | ------------------------------ | +| `/api/db-backups` | GET | 列出可用备份 | +| `/api/db-backups` | PUT | 创建手动备份 | +| `/api/db-backups` | POST | 从特定备份恢复 | +| `/api/db-backups/export` | GET | 下载数据库为 .sqlite 文件 | +| `/api/db-backups/import` | POST | 上传 .sqlite 文件替换数据库 | +| `/api/db-backups/exportAll` | GET | 下载完整备份为 .tar.gz 归档 | -### Cloud Sync +### 云同步 -| Endpoint | Method | Description | -| ---------------------- | ------- | --------------------- | -| `/api/sync/cloud` | Various | Cloud sync operations | -| `/api/sync/initialize` | POST | Initialize sync | -| `/api/cloud/*` | Various | Cloud management | +| 端点 | 方法 | 描述 | +| ---------------------- | ----- | ------------ | +| `/api/sync/cloud` | 多种 | 云同步操作 | +| `/api/sync/initialize` | POST | 初始化同步 | +| `/api/cloud/*` | 多种 | 云管理 | -### CLI Tools +### 隧道 -| Endpoint | Method | Description | -| ---------------------------------- | ------ | ------------------- | -| `/api/cli-tools/claude-settings` | GET | Claude CLI status | -| `/api/cli-tools/codex-settings` | GET | Codex CLI status | -| `/api/cli-tools/droid-settings` | GET | Droid CLI status | -| `/api/cli-tools/openclaw-settings` | GET | OpenClaw CLI status | -| `/api/cli-tools/runtime/[toolId]` | GET | Generic CLI runtime | +| 端点 | 方法 | 描述 | +| -------------------------- | ---- | ----------------------------------------------------------- | +| `/api/tunnels/cloudflared` | GET | 读取 Dashboard 使用的 Cloudflare Quick Tunnel 安装/运行状态 | +| `/api/tunnels/cloudflared` | POST | 启用或禁用 Cloudflare Quick Tunnel(`action=enable/disable`) | -CLI responses include: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. +### CLI 工具 -### ACP Agents +| 端点 | 方法 | 描述 | +| ---------------------------------- | ---- | ---------------- | +| `/api/cli-tools/claude-settings` | GET | Claude CLI 状态 | +| `/api/cli-tools/codex-settings` | GET | Codex CLI 状态 | +| `/api/cli-tools/droid-settings` | GET | Droid CLI 状态 | +| `/api/cli-tools/openclaw-settings` | GET | OpenClaw CLI 状态| +| `/api/cli-tools/runtime/[toolId]` | GET | 通用 CLI 运行时 | -| Endpoint | Method | Description | -| ----------------- | ------ | -------------------------------------------------------- | -| `/api/acp/agents` | GET | List all detected agents (built-in + custom) with status | -| `/api/acp/agents` | POST | Add custom agent or refresh detection cache | -| `/api/acp/agents` | DELETE | Remove a custom agent by `id` query param | +CLI 响应包括:`installed`、`runnable`、`command`、`commandPath`、`runtimeMode`、`reason`。 -GET response includes `agents[]` (id, name, binary, version, installed, protocol, isCustom) and `summary` (total, installed, notFound, builtIn, custom). +### ACP 代理 -### Resilience & Rate Limits +| 端点 | 方法 | 描述 | +| ----------------- | ------ | ---------------------------------------------- | +| `/api/acp/agents` | GET | 列出所有检测到的代理(内置 + 自定义)及状态 | +| `/api/acp/agents` | POST | 添加自定义代理或刷新检测缓存 | +| `/api/acp/agents` | DELETE | 通过 `id` 查询参数删除自定义代理 | -| Endpoint | Method | Description | -| ----------------------- | ------- | ------------------------------- | -| `/api/resilience` | GET/PUT | Get/update resilience profiles | -| `/api/resilience/reset` | POST | Reset circuit breakers | -| `/api/rate-limits` | GET | Per-account rate limit status | -| `/api/rate-limit` | GET | Global rate limit configuration | +GET 响应包括 `agents[]`(id、name、binary、version、installed、protocol、isCustom)和 `summary`(total、installed、notFound、builtIn、custom)。 -### Evals +### 弹性与速率限制 -| Endpoint | Method | Description | -| ------------ | -------- | --------------------------------- | -| `/api/evals` | GET/POST | List eval suites / run evaluation | +| 端点 | 方法 | 描述 | +| ----------------------- | ------- | ---------------------- | +| `/api/resilience` | GET/PUT | 获取/更新弹性配置文件 | +| `/api/resilience/reset` | POST | 重置熔断器 | +| `/api/rate-limits` | GET | 每账户速率限制状态 | +| `/api/rate-limit` | GET | 全局速率限制配置 | -### Policies +### 评估 -| Endpoint | Method | Description | -| --------------- | --------------- | ----------------------- | -| `/api/policies` | GET/POST/DELETE | Manage routing policies | +| 端点 | 方法 | 描述 | +| ------------ | -------- | ------------------------ | +| `/api/evals` | GET/POST | 列出评估套件/运行评估 | -### Compliance +### 策略 -| Endpoint | Method | Description | -| --------------------------- | ------ | ----------------------------- | -| `/api/compliance/audit-log` | GET | Compliance audit log (last N) | +| 端点 | 方法 | 描述 | +| --------------- | --------------- | -------------- | +| `/api/policies` | GET/POST/DELETE | 管理路由策略 | -### v1beta (Gemini-Compatible) +### 合规 -| Endpoint | Method | Description | -| -------------------------- | ------ | --------------------------------- | -| `/v1beta/models` | GET | List models in Gemini format | -| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint | +| 端点 | 方法 | 描述 | +| --------------------------- | ---- | -------------------------- | +| `/api/compliance/audit-log` | GET | 合规审计日志(最后 N 条) | -These endpoints mirror Gemini's API format for clients that expect native Gemini SDK compatibility. +### v1beta(Gemini 兼容) -### Internal / System APIs +| 端点 | 方法 | 描述 | +| -------------------------- | ---- | --------------------------- | +| `/v1beta/models` | GET | 以 Gemini 格式列出模型 | +| `/v1beta/models/{...path}` | POST | Gemini `generateContent` 端点 | -| Endpoint | Method | Description | -| --------------- | ------ | ---------------------------------------------------- | -| `/api/init` | GET | Application initialization check (used on first run) | -| `/api/tags` | GET | Ollama-compatible model tags (for Ollama clients) | -| `/api/restart` | POST | Trigger graceful server restart | -| `/api/shutdown` | POST | Trigger graceful server shutdown | +这些端点镜像 Gemini 的 API 格式,用于期望原生 Gemini SDK 兼容性的客户端。 -> **Note:** These endpoints are used internally by the system or for Ollama client compatibility. They are not typically called by end users. +### 内部/系统 API + +| 端点 | 方法 | 描述 | +| --------------- | ---- | ------------------------------------------------ | +| `/api/init` | GET | 应用初始化检查(首次运行时使用) | +| `/api/tags` | GET | Ollama 兼容的模型标签(用于 Ollama 客户端) | +| `/api/restart` | POST | 触发优雅的服务器重启 | +| `/api/shutdown` | POST | 触发优雅的服务器关闭 | + +> **注意:** 这些端点由系统内部使用或用于 Ollama 客户端兼容性。终端用户通常不需要调用它们。 --- -## Audio Transcription +## 音频转录 ```bash POST /v1/audio/transcriptions @@ -331,9 +339,9 @@ Authorization: Bearer your-api-key Content-Type: multipart/form-data ``` -Transcribe audio files using Deepgram or AssemblyAI. +使用 Deepgram 或 AssemblyAI 转录音频文件。 -**Request:** +**请求:** ```bash curl -X POST http://localhost:20128/v1/audio/transcriptions \ @@ -342,7 +350,7 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \ -F "model=deepgram/nova-3" ``` -**Response:** +**响应:** ```json { @@ -353,36 +361,36 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \ } ``` -**Supported providers:** `deepgram/nova-3`, `assemblyai/best`. +**支持的提供商:** `deepgram/nova-3`、`assemblyai/best`。 -**Supported formats:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. +**支持的格式:** `mp3`、`wav`、`m4a`、`flac`、`ogg`、`webm`。 --- -## Ollama Compatibility +## Ollama 兼容性 -For clients that use Ollama's API format: +用于使用 Ollama API 格式的客户端: ```bash -# Chat endpoint (Ollama format) +# Chat 端点(Ollama 格式) POST /v1/api/chat -# Model listing (Ollama format) +# 模型列表(Ollama 格式) GET /api/tags ``` -Requests are automatically translated between Ollama and internal formats. +请求会自动在 Ollama 和内部格式之间转换。 --- -## Telemetry +## 遥测 ```bash -# Get latency telemetry summary (p50/p95/p99 per provider) +# 获取延迟遥测摘要(每提供商的 p50/p95/p99) GET /api/telemetry/summary ``` -**Response:** +**响应:** ```json { @@ -395,13 +403,13 @@ GET /api/telemetry/summary --- -## Budget +## 预算 ```bash -# Get budget status for all API keys +# 获取所有 API 密钥的预算状态 GET /api/usage/budget -# Set or update a budget +# 设置或更新预算 POST /api/usage/budget Content-Type: application/json @@ -414,13 +422,13 @@ Content-Type: application/json --- -## Model Availability +## 模型可用性 ```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 @@ -431,25 +439,25 @@ Content-Type: application/json --- -## Request Processing +## 请求处理 -1. Client sends request to `/v1/*` -2. Route handler calls `handleChat`, `handleEmbedding`, `handleAudioTranscription`, or `handleImageGeneration` -3. Model is resolved (direct provider/model or alias/combo) -4. Credentials selected from local DB with account availability filtering -5. For chat: `handleChatCore` — format detection, translation, cache check, idempotency check -6. Provider executor sends upstream request -7. Response translated back to client format (chat) or returned as-is (embeddings/images/audio) -8. Usage/logging recorded -9. Fallback applies on errors according to combo rules +1. 客户端向 `/v1/*` 发送请求 +2. 路由处理器调用 `handleChat`、`handleEmbedding`、`handleAudioTranscription` 或 `handleImageGeneration` +3. 解析模型(直接 provider/model 或 alias/combo) +4. 从本地数据库选择凭据,并过滤账户可用性 +5. 对于 chat:`handleChatCore` — 格式检测、翻译、缓存检查、幂等性检查 +6. 提供商执行器发送上游请求 +7. 响应翻译回客户端格式(chat)或直接返回(embeddings/images/audio) +8. 记录用量/日志 +9. 根据 combo 规则在错误时应用后备 -Full architecture reference: [`ARCHITECTURE.md`](ARCHITECTURE.md) +完整架构参考:[`ARCHITECTURE.md`](ARCHITECTURE.md) --- -## Authentication +## 认证 -- Dashboard routes (`/dashboard/*`) use `auth_token` cookie -- Login uses saved password hash; fallback to `INITIAL_PASSWORD` -- `requireLogin` toggleable via `/api/settings/require-login` -- `/v1/*` routes optionally require Bearer API key when `REQUIRE_API_KEY=true` +- Dashboard 路由(`/dashboard/*`)使用 `auth_token` cookie +- 登录使用保存的密码哈希;回退到 `INITIAL_PASSWORD` +- `requireLogin` 可通过 `/api/settings/require-login` 切换 +- 当 `REQUIRE_API_KEY=true` 时,`/v1/*` 路由可选地需要 Bearer API 密钥 diff --git a/docs/i18n/zh-CN/ARCHITECTURE.md b/docs/i18n/zh-CN/ARCHITECTURE.md index 4ea06a29..d362ef2c 100644 --- a/docs/i18n/zh-CN/ARCHITECTURE.md +++ b/docs/i18n/zh-CN/ARCHITECTURE.md @@ -1,102 +1,118 @@ -🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/ARCHITECTURE.md) · 🇪🇸 [es](../es/ARCHITECTURE.md) · 🇫🇷 [fr](../fr/ARCHITECTURE.md) · 🇩🇪 [de](../de/ARCHITECTURE.md) · 🇮🇹 [it](../it/ARCHITECTURE.md) · 🇷🇺 [ru](../ru/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../zh-CN/ARCHITECTURE.md) · 🇯🇵 [ja](../ja/ARCHITECTURE.md) · 🇰🇷 [ko](../ko/ARCHITECTURE.md) · 🇸🇦 [ar](../ar/ARCHITECTURE.md) · 🇮🇳 [in](../in/ARCHITECTURE.md) · 🇹🇭 [th](../th/ARCHITECTURE.md) · 🇻🇳 [vi](../vi/ARCHITECTURE.md) · 🇮🇩 [id](../id/ARCHITECTURE.md) · 🇲🇾 [ms](../ms/ARCHITECTURE.md) · 🇳🇱 [nl](../nl/ARCHITECTURE.md) · 🇵🇱 [pl](../pl/ARCHITECTURE.md) · 🇸🇪 [sv](../sv/ARCHITECTURE.md) · 🇳🇴 [no](../no/ARCHITECTURE.md) · 🇩🇰 [da](../da/ARCHITECTURE.md) · 🇫🇮 [fi](../fi/ARCHITECTURE.md) · 🇵🇹 [pt](../pt/ARCHITECTURE.md) · 🇷🇴 [ro](../ro/ARCHITECTURE.md) · 🇭🇺 [hu](../hu/ARCHITECTURE.md) · 🇧🇬 [bg](../bg/ARCHITECTURE.md) · 🇸🇰 [sk](../sk/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../uk-UA/ARCHITECTURE.md) · 🇮🇱 [he](../he/ARCHITECTURE.md) · 🇵🇭 [phi](../phi/ARCHITECTURE.md) +# OmniRoute 架构 ---- +🌐 **语言:** 🇺🇸 [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) | 🇨🇿 [Čeština](../cs/ARCHITECTURE.md) -# OmniRoute Architecture +_最后更新:2026-03-28_ -🌐 **Languages:** 🇺🇸 [English](ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](i18n/es/ARCHITECTURE.md) | 🇫🇷 [Français](i18n/fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](i18n/it/ARCHITECTURE.md) | 🇷🇺 [Русский](i18n/ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](i18n/de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](i18n/in/ARCHITECTURE.md) | 🇹🇭 [ไทย](i18n/th/ARCHITECTURE.md) | 🇺🇦 [Українська](i18n/uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](i18n/ar/ARCHITECTURE.md) | 🇯🇵 [日本語](i18n/ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/ARCHITECTURE.md) | 🇧🇬 [Български](i18n/bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](i18n/da/ARCHITECTURE.md) | 🇫🇮 [Suomi](i18n/fi/ARCHITECTURE.md) | 🇮🇱 [עברית](i18n/he/ARCHITECTURE.md) | 🇭🇺 [Magyar](i18n/hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/ARCHITECTURE.md) | 🇰🇷 [한국어](i18n/ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](i18n/nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](i18n/no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/ARCHITECTURE.md) | 🇷🇴 [Română](i18n/ro/ARCHITECTURE.md) | 🇵🇱 [Polski](i18n/pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](i18n/sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](i18n/sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](i18n/phi/ARCHITECTURE.md) +## 概述 -_Last updated: 2026-03-04_ +OmniRoute 是一个基于 Next.js 构建的本地 AI 路由网关和仪表盘。 +它提供单一的 OpenAI 兼容端点(`/v1/*`),并将流量路由到多个上游提供商,支持翻译、后备、Token 刷新和用量追踪。 -## Executive Summary +核心能力: -OmniRoute is a local AI routing gateway and dashboard built on Next.js. -It provides a single OpenAI-compatible endpoint (`/v1/*`) and routes traffic across multiple upstream providers with translation, fallback, token refresh, and usage tracking. +- 面向 CLI/工具的 OpenAI 兼容 API 接口(28 个提供商) +- 跨提供商格式的请求/响应翻译 +- 模型 Combo 后备(多模型序列) +- 账户级后备(每个提供商多账户) +- OAuth + API 密钥提供商连接管理 +- 通过 `/v1/embeddings` 生成 Embedding(6 个提供商,9 个模型) +- 通过 `/v1/images/generations` 生成图像(4 个提供商,9 个模型) +- Think 标签解析(`...`)用于推理模型 +- 响应清理以实现严格的 OpenAI SDK 兼容性 +- 角色规范化(developer→system,system→user)实现跨提供商兼容 +- 结构化输出转换(json_schema → Gemini responseSchema) +- 本地持久化:提供商、密钥、别名、Combo、设置、定价 +- 用量/成本追踪和请求日志 +- 可选的云同步用于多设备/状态同步 +- API 访问控制的 IP 白名单/黑名单 +- Thinking 预算管理(passthrough/auto/custom/adaptive) +- 全局系统提示词注入 +- 会话追踪和指纹识别 +- 每账户增强速率限制,支持提供商特定配置文件 +- 提供商弹性的熔断器模式 +- 使用互斥锁的防惊群保护 +- 基于签名的请求去重缓存 +- 领域层:模型可用性、成本规则、后备策略、锁定策略 +- 领域状态持久化(SQLite 写入缓存用于后备、预算、锁定、熔断器) +- 集中请求评估的策略引擎(锁定 → 预算 → 后备) +- 请求遥测,支持 p50/p95/p99 延迟聚合 +- 关联 ID(X-Request-Id)用于端到端追踪 +- 合规审计日志,支持按 API 密钥选择退出 +- 用于 LLM 质量保证的评估框架 +- 实时熔断器状态的弹性 UI 仪表盘 +- 模块化 OAuth 提供商(`src/lib/oauth/providers/` 下的 12 个独立模块) -Core capabilities: +主要运行时模型: -- OpenAI-compatible API surface for CLI/tools (28 providers) -- Request/response translation across provider formats -- Model combo fallback (multi-model sequence) -- Account-level fallback (multi-account per provider) -- OAuth + API-key provider connection management -- Embedding generation via `/v1/embeddings` (6 providers, 9 models) -- Image generation via `/v1/images/generations` (4 providers, 9 models) -- Think tag parsing (`...`) for reasoning models -- Response sanitization for strict OpenAI SDK compatibility -- Role normalization (developer→system, system→user) for cross-provider compatibility -- Structured output conversion (json_schema → Gemini responseSchema) -- Local persistence for providers, keys, aliases, combos, settings, pricing -- Usage/cost tracking and request logging -- Optional cloud sync for multi-device/state sync -- IP allowlist/blocklist for API access control -- Thinking budget management (passthrough/auto/custom/adaptive) -- Global system prompt injection -- Session tracking and fingerprinting -- Per-account enhanced rate limiting with provider-specific profiles -- Circuit breaker pattern for provider resilience -- Anti-thundering herd protection with mutex locking -- Signature-based request deduplication cache -- Domain layer: model availability, cost rules, fallback policy, lockout policy -- Domain state persistence (SQLite write-through cache for fallbacks, budgets, lockouts, circuit breakers) -- Policy engine for centralized request evaluation (lockout → budget → fallback) -- Request telemetry with p50/p95/p99 latency aggregation -- Correlation ID (X-Request-Id) for end-to-end tracing -- Compliance audit logging with opt-out per API key -- Eval framework for LLM quality assurance -- Resilience UI dashboard with real-time circuit breaker status -- Modular OAuth providers (12 individual modules under `src/lib/oauth/providers/`) +- `src/app/api/*` 下的 Next.js app routes 同时实现 Dashboard API 和兼容性 API +- `src/sse/*` + `open-sse/*` 中的共享 SSE/路由核心处理提供商执行、翻译、流式传输、后备和用量 -Primary runtime model: +## 范围与边界 -- Next.js app routes under `src/app/api/*` implement both dashboard APIs and compatibility APIs -- A shared SSE/routing core in `src/sse/*` + `open-sse/*` handles provider execution, translation, streaming, fallback, and usage +### 范围内 -## Scope and Boundaries +- 本地网关运行时 +- Dashboard 管理 API +- 提供商认证和 Token 刷新 +- 请求翻译和 SSE 流式传输 +- 本地状态 + 用量持久化 +- 可选的云同步编排 -### In Scope +### 范围外 -- Local gateway runtime -- Dashboard management APIs -- Provider authentication and token refresh -- Request translation and SSE streaming -- Local state + usage persistence -- Optional cloud sync orchestration +- `NEXT_PUBLIC_CLOUD_URL` 后面的云服务实现 +- 本地进程之外的提供商 SLA/控制平面 +- 外部 CLI 二进制文件本身(Claude CLI、Codex CLI 等) -### Out of Scope +## Dashboard 界面(当前) -- Cloud service implementation behind `NEXT_PUBLIC_CLOUD_URL` -- Provider SLA/control plane outside local process -- External CLI binaries themselves (Claude CLI, Codex CLI, etc.) +`src/app/(dashboard)/dashboard/` 下的主要页面: -## High-Level System Context +- `/dashboard` — 快速入门 + 服务商概览 +- `/dashboard/endpoint` — 端点代理 + MCP + A2A + API 端点标签页 +- `/dashboard/providers` — 服务商连接和凭证 +- `/dashboard/combos` — Combo 策略、模板、模型路由规则 +- `/dashboard/costs` — 成本汇总和定价可见性 +- `/dashboard/analytics` — 使用分析和评估 +- `/dashboard/limits` — 配额/速率控制 +- `/dashboard/cli-tools` — CLI 引导、运行时检测、配置生成 +- `/dashboard/agents` — 检测到的 ACP 代理 + 自定义代理注册 +- `/dashboard/media` — 图像/视频/音乐 playground +- `/dashboard/search-tools` — 搜索服务商测试和历史 +- `/dashboard/health` — 正常运行时间、熔断器、速率限制 +- `/dashboard/logs` — 请求/代理/审计/控制台日志 +- `/dashboard/settings` — 系统设置标签页(通用、路由、Combo 默认值等) +- `/dashboard/api-manager` — API 密钥生命周期和模型权限 + +## 高层系统上下文 ```mermaid flowchart LR - subgraph Clients[Developer Clients] + subgraph Clients[开发者客户端] C1[Claude Code] C2[Codex CLI] C3[OpenClaw / Droid / Cline / Continue / Roo] - C4[Custom OpenAI-compatible clients] - BROWSER[Browser Dashboard] + C4[自定义 OpenAI 兼容客户端] + BROWSER[浏览器仪表盘] 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] + subgraph Router[OmniRoute 本地进程] + API[V1 兼容性 API\n/v1/*] + DASH[Dashboard + 管理 API\n/api/*] + CORE[SSE + 翻译核心\nopen-sse + src/sse] DB[(storage.sqlite)] - UDB[(usage tables + log artifacts)] + UDB[(用量表 + 日志文件)] end - subgraph Upstreams[Upstream Providers] - P1[OAuth Providers\nClaude/Codex/Gemini/Qwen/Qoder/GitHub/Kiro/Cursor/Antigravity] - P2[API Key Providers\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA] - P3[Compatible Nodes\nOpenAI-compatible / Anthropic-compatible] + subgraph Upstreams[上游提供商] + P1[OAuth 提供商\nClaude/Codex/Gemini/Qwen/Qoder/GitHub/Kiro/Cursor/Antigravity] + P2[API 密钥提供商\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA] + P3[兼容节点\nOpenAI 兼容 / Anthropic 兼容] end - subgraph Cloud[Optional Cloud Sync] - CLOUD[Cloud Sync Endpoint\nNEXT_PUBLIC_CLOUD_URL] + subgraph Cloud[可选云同步] + CLOUD[云同步端点\nNEXT_PUBLIC_CLOUD_URL] end C1 --> API @@ -117,303 +133,304 @@ flowchart LR DASH --> CLOUD ``` -## Core Runtime Components +## 核心运行时组件 -## 1) API and Routing Layer (Next.js App Routes) +## 1) API 和路由层(Next.js App Routes) -Main directories: +主要目录: -- `src/app/api/v1/*` and `src/app/api/v1beta/*` for compatibility APIs -- `src/app/api/*` for management/configuration APIs -- Next rewrites in `next.config.mjs` map `/v1/*` to `/api/v1/*` +- `src/app/api/v1/*` 和 `src/app/api/v1beta/*` 用于兼容性 API +- `src/app/api/*` 用于管理/配置 API +- `next.config.mjs` 中的 Next 重写将 `/v1/*` 映射到 `/api/v1/*` -Important compatibility routes: +重要的兼容性路由: - `src/app/api/v1/chat/completions/route.ts` - `src/app/api/v1/messages/route.ts` - `src/app/api/v1/responses/route.ts` -- `src/app/api/v1/models/route.ts` — includes custom models with `custom: true` -- `src/app/api/v1/embeddings/route.ts` — embedding generation (6 providers) -- `src/app/api/v1/images/generations/route.ts` — image generation (4+ providers incl. Antigravity/Nebius) +- `src/app/api/v1/models/route.ts` — 包含 `custom: true` 的自定义模型 +- `src/app/api/v1/embeddings/route.ts` — Embedding 生成(6 个提供商) +- `src/app/api/v1/images/generations/route.ts` — 图像生成(4+ 个提供商,包括 Antigravity/Nebius) - `src/app/api/v1/messages/count_tokens/route.ts` -- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — dedicated per-provider chat -- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — dedicated per-provider embeddings -- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — dedicated per-provider images +- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — 专用的每提供商聊天 +- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — 专用的每提供商 Embedding +- `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` -Management domains: +管理领域: -- Auth/settings: `src/app/api/auth/*`, `src/app/api/settings/*` -- Providers/connections: `src/app/api/providers*` -- Provider nodes: `src/app/api/provider-nodes*` -- Custom models: `src/app/api/provider-models` (GET/POST/DELETE) -- Model catalog: `src/app/api/models/route.ts` (GET) -- Proxy config: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST) -- OAuth: `src/app/api/oauth/*` -- Keys/aliases/combos/pricing: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing` -- Usage: `src/app/api/usage/*` -- Sync/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*` -- CLI tooling helpers: `src/app/api/cli-tools/*` -- IP filter: `src/app/api/settings/ip-filter` (GET/PUT) -- Thinking budget: `src/app/api/settings/thinking-budget` (GET/PUT) -- System prompt: `src/app/api/settings/system-prompt` (GET/PUT) -- Sessions: `src/app/api/sessions` (GET) -- Rate limits: `src/app/api/rate-limits` (GET) -- Resilience: `src/app/api/resilience` (GET/PATCH) — provider profiles, circuit breaker, rate limit state -- Resilience reset: `src/app/api/resilience/reset` (POST) — reset breakers + cooldowns -- Cache stats: `src/app/api/cache/stats` (GET/DELETE) -- Model availability: `src/app/api/models/availability` (GET/POST) -- Telemetry: `src/app/api/telemetry/summary` (GET) -- Budget: `src/app/api/usage/budget` (GET/POST) -- Fallback chains: `src/app/api/fallback/chains` (GET/POST/DELETE) -- Compliance audit: `src/app/api/compliance/audit-log` (GET) -- Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET) -- Policies: `src/app/api/policies` (GET/POST) +- 认证/设置:`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/route.ts`(GET) +- 代理配置:`src/app/api/settings/proxy`(GET/PUT/DELETE)+ `src/app/api/settings/proxy/test`(POST) +- OAuth:`src/app/api/oauth/*` +- 密钥/别名/Combo/定价:`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) +- Thinking 预算:`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 + Translation Core +## 2) SSE + 翻译核心 -Main flow modules: +主要流程模块: -- Entry: `src/sse/handlers/chat.ts` -- Core orchestration: `open-sse/handlers/chatCore.ts` -- Provider execution adapters: `open-sse/executors/*` -- Format detection/provider config: `open-sse/services/provider.ts` -- Model parse/resolve: `src/sse/services/model.ts`, `open-sse/services/model.ts` -- Account fallback logic: `open-sse/services/accountFallback.ts` -- Translation registry: `open-sse/translator/index.ts` -- Stream transformations: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts` -- Usage extraction/normalization: `open-sse/utils/usageTracking.ts` -- Think tag parser: `open-sse/utils/thinkTagParser.ts` -- Embedding handler: `open-sse/handlers/embeddings.ts` -- Embedding provider registry: `open-sse/config/embeddingRegistry.ts` -- Image generation handler: `open-sse/handlers/imageGeneration.ts` -- Image provider registry: `open-sse/config/imageRegistry.ts` -- Response sanitization: `open-sse/handlers/responseSanitizer.ts` -- Role normalization: `open-sse/services/roleNormalizer.ts` +- 入口:`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` +- Think 标签解析器:`open-sse/utils/thinkTagParser.ts` +- Embedding 处理器:`open-sse/handlers/embeddings.ts` +- Embedding 提供商注册表:`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` -Services (business logic): +服务(业务逻辑): -- Account selection/scoring: `open-sse/services/accountSelector.ts` -- Context lifecycle management: `open-sse/services/contextManager.ts` -- IP filter enforcement: `open-sse/services/ipFilter.ts` -- Session tracking: `open-sse/services/sessionManager.ts` -- Request deduplication: `open-sse/services/signatureCache.ts` -- System prompt injection: `open-sse/services/systemPrompt.ts` -- Thinking budget management: `open-sse/services/thinkingBudget.ts` -- Wildcard model routing: `open-sse/services/wildcardRouter.ts` -- Rate limit management: `open-sse/services/rateLimitManager.ts` -- Circuit breaker: `open-sse/services/circuitBreaker.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` +- Thinking 预算管理:`open-sse/services/thinkingBudget.ts` +- 通配符模型路由:`open-sse/services/wildcardRouter.ts` +- 速率限制管理:`open-sse/services/rateLimitManager.ts` +- 熔断器:`open-sse/services/circuitBreaker.ts` -Domain layer modules: +领域层模块: -- Model availability: `src/lib/domain/modelAvailability.ts` -- Cost rules/budgets: `src/lib/domain/costRules.ts` -- Fallback policy: `src/lib/domain/fallbackPolicy.ts` -- Combo resolver: `src/lib/domain/comboResolver.ts` -- Lockout policy: `src/lib/domain/lockoutPolicy.ts` -- Policy engine: `src/domain/policyEngine.ts` — centralized lockout → budget → fallback evaluation -- Error codes catalog: `src/lib/domain/errorCodes.ts` -- Request ID: `src/lib/domain/requestId.ts` -- Fetch timeout: `src/lib/domain/fetchTimeout.ts` -- Request telemetry: `src/lib/domain/requestTelemetry.ts` -- Compliance/audit: `src/lib/domain/compliance/index.ts` -- Eval runner: `src/lib/domain/evalRunner.ts` -- Domain state persistence: `src/lib/db/domainState.ts` — SQLite CRUD for fallback chains, budgets, cost history, lockout state, circuit breakers +- 模型可用性:`src/lib/domain/modelAvailability.ts` +- 成本规则/预算:`src/lib/domain/costRules.ts` +- 后备策略:`src/lib/domain/fallbackPolicy.ts` +- Combo 解析器:`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` +- Fetch 超时:`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 provider modules (12 individual files under `src/lib/oauth/providers/`): +OAuth 提供商模块(`src/lib/oauth/providers/` 下的 12 个独立文件): -- Registry index: `src/lib/oauth/providers/index.ts` -- Individual providers: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts` -- Thin wrapper: `src/lib/oauth/providers.ts` — re-exports from individual modules +- 注册表索引:`src/lib/oauth/providers/index.ts` +- 独立提供商:`claude.ts`、`codex.ts`、`gemini.ts`、`antigravity.ts`、`qoder.ts`、`qwen.ts`、`kimi-coding.ts`、`github.ts`、`kiro.ts`、`cursor.ts`、`kilocode.ts`、`cline.ts` +- 薄包装器:`src/lib/oauth/providers.ts` — 从独立模块重新导出 -## 3) Persistence Layer +## 3) 持久化层 -Primary state DB (SQLite): +主要状态数据库(SQLite): -- Core infra: `src/lib/db/core.ts` (better-sqlite3, migrations, WAL) -- Re-export facade: `src/lib/localDb.ts` (thin compatibility layer for callers) -- file: `${DATA_DIR}/storage.sqlite` (or `$XDG_CONFIG_HOME/omniroute/storage.sqlite` when set, else `~/.omniroute/storage.sqlite`) -- entities (tables + KV namespaces): providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt** +- 核心基础设施:`src/lib/db/core.ts`(better-sqlite3、迁移、WAL) +- 重新导出外观:`src/lib/localDb.ts`(面向调用者的薄兼容层) +- 文件:`${DATA_DIR}/storage.sqlite`(或设置 `$XDG_CONFIG_HOME/omniroute/storage.sqlite` 时使用该路径,否则为 `~/.omniroute/storage.sqlite`) +- 实体(表 + KV 命名空间):providerConnections、providerNodes、modelAliases、combos、apiKeys、settings、pricing、**customModels**、**proxyConfig**、**ipFilter**、**thinkingBudget**、**systemPrompt** -Usage persistence: +用量持久化: -- facade: `src/lib/usageDb.ts` (decomposed modules in `src/lib/usage/*`) -- SQLite tables in `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs` -- optional file artifacts remain for compatibility/debug (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `/logs/...`) -- legacy JSON files are migrated to SQLite by startup migrations when present +- 外观:`src/lib/usageDb.ts`(分解模块在 `src/lib/usage/*`) +- `storage.sqlite` 中的 SQLite 表:`usage_history`、`call_logs`、`proxy_logs` +- 可选的文件工件为兼容性/调试保留(`${DATA_DIR}/log.txt`、`${DATA_DIR}/call_logs/`、`/logs/...`) +- 旧版 JSON 文件在启动迁移时会被迁移到 SQLite -Domain State DB (SQLite): +领域状态数据库(SQLite): -- `src/lib/db/domainState.ts` — CRUD operations for domain state -- Tables (created in `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers` -- Write-through cache pattern: in-memory Maps are authoritative at runtime; mutations are written synchronously to SQLite; state is restored from DB on cold start +- `src/lib/db/domainState.ts` — 领域状态的 CRUD 操作 +- 表(在 `src/lib/db/core.ts` 中创建):`domain_fallback_chains`、`domain_budgets`、`domain_cost_history`、`domain_lockout_state`、`domain_circuit_breakers` +- 写入缓存模式:内存中的 Map 在运行时是权威的;变更同步写入 SQLite;状态在冷启动时从数据库恢复 -## 4) Auth + Security Surfaces +## 4) 认证 + 安全接口 -- Dashboard cookie auth: `src/proxy.ts`, `src/app/api/auth/login/route.ts` -- API key generation/verification: `src/shared/utils/apiKey.ts` -- Provider secrets persisted in `providerConnections` entries -- Outbound proxy support via `open-sse/utils/proxyFetch.ts` (env vars) and `open-sse/utils/networkProxy.ts` (configurable per-provider or global) +- Dashboard Cookie 认证:`src/proxy.ts`、`src/app/api/auth/login/route.ts` +- API 密钥生成/验证:`src/shared/utils/apiKey.ts` +- 提供商密钥持久化在 `providerConnections` 条目中 +- 通过 `open-sse/utils/proxyFetch.ts`(环境变量)和 `open-sse/utils/networkProxy.ts`(可配置的每提供商或全局)支持出站代理 -## 5) Cloud Sync +## 5) 云同步 -- Scheduler init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts` -- Periodic task: `src/shared/services/cloudSyncScheduler.ts` -- Control route: `src/app/api/sync/cloud/route.ts` +- 调度器初始化:`src/lib/initCloudSync.ts`、`src/shared/services/initializeCloudSync.ts`、`src/shared/services/modelSyncScheduler.ts` +- 周期性任务:`src/shared/services/cloudSyncScheduler.ts` +- 周期性任务:`src/shared/services/modelSyncScheduler.ts` +- 控制路由:`src/app/api/sync/cloud/route.ts` -## Request Lifecycle (`/v1/chat/completions`) +## 请求生命周期(`/v1/chat/completions`) ```mermaid sequenceDiagram autonumber - participant Client as CLI/SDK Client + participant Client as CLI/SDK 客户端 participant Route as /api/v1/chat/completions participant Chat as src/sse/handlers/chat participant Core as open-sse/handlers/chatCore - participant Model as Model Resolver - participant Auth as Credential Selector - participant Exec as Provider Executor - participant Prov as Upstream Provider - participant Stream as Stream Translator + participant Model as 模型解析器 + participant Auth as 凭证选择器 + participant Exec as 提供商执行器 + participant Prov as 上游提供商 + participant Stream as 流翻译器 participant Usage as usageDb Client->>Route: POST /v1/chat/completions Route->>Chat: handleChat(request) - Chat->>Model: parse/resolve model or combo + Chat->>Model: 解析/解析模型或 Combo - alt Combo model - Chat->>Chat: iterate combo models (handleComboChat) + alt Combo 模型 + Chat->>Chat: 迭代 Combo 模型(handleComboChat) end Chat->>Auth: getProviderCredentials(provider) - Auth-->>Chat: active account + tokens/api key + Auth-->>Chat: 活动账户 + Token/API 密钥 Chat->>Core: handleChatCore(body, modelInfo, credentials) - Core->>Core: detect source format - Core->>Core: translate request to target format + Core->>Core: 检测源格式 + Core->>Core: 将请求翻译为目标格式 Core->>Exec: execute(provider, transformedBody) - Exec->>Prov: upstream API call - Prov-->>Exec: SSE/JSON response - Exec-->>Core: response + metadata + Exec->>Prov: 上游 API 调用 + Prov-->>Exec: SSE/JSON 响应 + Exec-->>Core: 响应 + 元数据 alt 401/403 Core->>Exec: refreshCredentials() - Exec-->>Core: updated tokens - Core->>Exec: retry request + Exec-->>Core: 更新的 Token + Core->>Exec: 重试请求 end - Core->>Stream: translate/normalize stream to client format - Stream-->>Client: SSE chunks / JSON response + Core->>Stream: 翻译/规范化流到客户端格式 + Stream-->>Client: SSE 块 / JSON 响应 - Stream->>Usage: extract usage + persist history/log + Stream->>Usage: 提取用量 + 持久化历史/日志 ``` -## Combo + Account Fallback Flow +## Combo + 账户后备流程 ```mermaid flowchart TD - A[Incoming model string] --> B{Is combo name?} - B -- Yes --> C[Load combo models sequence] - B -- No --> D[Single model path] + A[传入的模型字符串] --> B{是 Combo 名称?} + B -- 是 --> C[加载 Combo 模型序列] + B -- 否 --> D[单模型路径] - C --> E[Try model N] - E --> F[Resolve provider/model] + C --> E[尝试模型 N] + E --> F[解析提供商/模型] D --> F - F --> G[Select account credentials] - G --> H{Credentials available?} - H -- No --> I[Return provider unavailable] - H -- Yes --> J[Execute request] + F --> G[选择账户凭证] + G --> H{凭证可用?} + H -- 否 --> I[返回提供商不可用] + H -- 是 --> J[执行请求] - J --> K{Success?} - K -- Yes --> L[Return response] - K -- No --> M{Fallback-eligible error?} + J --> K{成功?} + K -- 是 --> L[返回响应] + K -- 否 --> M{可后备错误?} - M -- No --> N[Return error] - M -- Yes --> O[Mark account unavailable cooldown] - O --> P{Another account for provider?} - P -- Yes --> G - P -- No --> Q{In combo with next model?} - Q -- Yes --> E - Q -- No --> R[Return all unavailable] + M -- 否 --> N[返回错误] + M -- 是 --> O[标记账户不可用冷却] + O --> P{同一提供商有其他账户?} + P -- 是 --> G + P -- 否 --> Q{在有下一个模型的 Combo 中?} + Q -- 是 --> E + Q -- 否 --> R[返回全部不可用] ``` -Fallback decisions are driven by `open-sse/services/accountFallback.ts` using status codes and error-message heuristics. +后备决策由 `open-sse/services/accountFallback.ts` 使用状态码和错误消息启发式驱动。 -## OAuth Onboarding and Token Refresh Lifecycle +## OAuth 引导和 Token 刷新生命周期 ```mermaid sequenceDiagram autonumber participant UI as Dashboard UI participant OAuth as /api/oauth/[provider]/[action] - participant ProvAuth as Provider Auth Server + participant ProvAuth as 提供商认证服务器 participant DB as localDb participant Test as /api/providers/[id]/test - participant Exec as Provider Executor + participant Exec as 提供商执行器 - UI->>OAuth: GET authorize or device-code - OAuth->>ProvAuth: create auth/device flow - ProvAuth-->>OAuth: auth URL or device code payload - OAuth-->>UI: flow data + UI->>OAuth: GET authorize 或 device-code + OAuth->>ProvAuth: 创建认证/设备流程 + ProvAuth-->>OAuth: 认证 URL 或设备码负载 + OAuth-->>UI: 流程数据 - 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->>OAuth: POST exchange 或 poll + OAuth->>ProvAuth: Token 交换/轮询 + ProvAuth-->>OAuth: 访问/刷新 Token + OAuth->>DB: createProviderConnection(oauth 数据) + OAuth-->>UI: 成功 + 连接 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 + Test->>Exec: 验证凭证 / 可选刷新 + Exec-->>Test: 有效或刷新后的 Token 信息 + Test->>DB: 更新状态/Token/错误 + Test-->>UI: 验证结果 ``` -Refresh during live traffic is executed inside `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`. +实时流量期间的刷新在 `open-sse/handlers/chatCore.ts` 内通过执行器 `refreshCredentials()` 执行。 -## Cloud Sync Lifecycle (Enable / Sync / Disable) +## 云同步生命周期(启用 / 同步 / 禁用) ```mermaid sequenceDiagram autonumber - participant UI as Endpoint Page UI + participant UI as 端点页面 UI participant Sync as /api/sync/cloud participant DB as localDb - participant Cloud as External Cloud Sync + participant Cloud as 外部云同步 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->>DB: 设置 cloudEnabled=true + Sync->>DB: 确保 API 密钥存在 + Sync->>Cloud: POST /sync/{machineId}(providers/aliases/combos/keys) + Cloud-->>Sync: 同步结果 Sync->>Cloud: GET /{machineId}/v1/verify - Sync-->>UI: enabled + verification status + Sync-->>UI: 已启用 + 验证状态 UI->>Sync: POST action=sync Sync->>Cloud: POST /sync/{machineId} - Cloud-->>Sync: remote data - Sync->>DB: update newer local tokens/status - Sync-->>UI: synced + Cloud-->>Sync: 远程数据 + Sync->>DB: 更新较新的本地 Token/状态 + Sync-->>UI: 已同步 UI->>Sync: POST action=disable - Sync->>DB: set cloudEnabled=false + Sync->>DB: 设置 cloudEnabled=false Sync->>Cloud: DELETE /sync/{machineId} - Sync->>Claude: switch ANTHROPIC_BASE_URL back to local (if needed) - Sync-->>UI: disabled + Sync->>Claude: 将 ANTHROPIC_BASE_URL 切换回本地(如需要) + Sync-->>UI: 已禁用 ``` -Periodic sync is triggered by `CloudSyncScheduler` when cloud is enabled. +周期性同步在云启用时由 `CloudSyncScheduler` 触发。 -## Data Model and Storage Map +## 数据模型和存储映射 ```mermaid erDiagram - SETTINGS ||--o{ PROVIDER_CONNECTION : controls - PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_provider - PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage + SETTINGS ||--o{ PROVIDER_CONNECTION : 控制 + PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : 支持兼容提供商 + PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : 产生用量 SETTINGS { boolean cloudEnabled @@ -508,32 +525,32 @@ erDiagram } ``` -Physical storage files: +物理存储文件: -- primary runtime DB: `${DATA_DIR}/storage.sqlite` -- request log lines: `${DATA_DIR}/log.txt` (compat/debug artifact) -- structured call payload archives: `${DATA_DIR}/call_logs/` -- optional translator/request debug sessions: `/logs/...` +- 主运行时数据库:`${DATA_DIR}/storage.sqlite` +- 请求日志行:`${DATA_DIR}/log.txt`(兼容性/调试工件) +- 结构化调用负载归档:`${DATA_DIR}/call_logs/` +- 可选的翻译器/请求调试会话:`/logs/...` -## Deployment Topology +## 部署拓扑 ```mermaid flowchart LR - subgraph LocalHost[Developer Host] - CLI[CLI Tools] - Browser[Dashboard Browser] + subgraph LocalHost[开发者主机] + CLI[CLI 工具] + Browser[Dashboard 浏览器] end - subgraph ContainerOrProcess[OmniRoute Runtime] - Next[Next.js Server\nPORT=20128] - Core[SSE Core + Executors] + subgraph ContainerOrProcess[OmniRoute 运行时] + Next[Next.js 服务器\nPORT=20128] + Core[SSE 核心 + 执行器] MainDB[(storage.sqlite)] - UsageDB[(usage tables + log artifacts)] + UsageDB[(用量表 + 日志工件)] end - subgraph External[External Services] - Providers[AI Providers] - SyncCloud[Cloud Sync Service] + subgraph External[外部服务] + Providers[AI 提供商] + SyncCloud[云同步服务] end CLI --> Next @@ -546,242 +563,250 @@ flowchart LR Next --> SyncCloud ``` -## Module Mapping (Decision-Critical) +## 模块映射(关键决策) -### Route and API Modules +### 路由和 API 模块 -- `src/app/api/v1/*`, `src/app/api/v1beta/*`: compatibility APIs -- `src/app/api/v1/providers/[provider]/*`: dedicated per-provider routes (chat, embeddings, images) -- `src/app/api/providers*`: provider CRUD, validation, testing -- `src/app/api/provider-nodes*`: custom compatible node management -- `src/app/api/provider-models`: custom model management (CRUD) -- `src/app/api/models/route.ts`: model catalog API (aliases + custom models) -- `src/app/api/oauth/*`: OAuth/device-code flows -- `src/app/api/keys*`: local API key lifecycle -- `src/app/api/models/alias`: alias management -- `src/app/api/combos*`: fallback combo management -- `src/app/api/pricing`: pricing overrides for cost calculation -- `src/app/api/settings/proxy`: proxy configuration (GET/PUT/DELETE) -- `src/app/api/settings/proxy/test`: outbound proxy connectivity test (POST) -- `src/app/api/usage/*`: usage and logs APIs -- `src/app/api/sync/*` + `src/app/api/cloud/*`: cloud sync and cloud-facing helpers -- `src/app/api/cli-tools/*`: local CLI config writers/checkers -- `src/app/api/settings/ip-filter`: IP allowlist/blocklist (GET/PUT) -- `src/app/api/settings/thinking-budget`: thinking token budget config (GET/PUT) -- `src/app/api/settings/system-prompt`: global system prompt (GET/PUT) -- `src/app/api/sessions`: active session listing (GET) -- `src/app/api/rate-limits`: per-account rate limit status (GET) +- `src/app/api/v1/*`、`src/app/api/v1beta/*`:兼容性 API +- `src/app/api/v1/providers/[provider]/*`:专用的每提供商路由(聊天、Embedding、图像) +- `src/app/api/providers*`:提供商 CRUD、验证、测试 +- `src/app/api/provider-nodes*`:自定义兼容节点管理 +- `src/app/api/provider-models`:自定义模型管理(CRUD) +- `src/app/api/models/route.ts`:模型目录 API(别名 + 自定义模型) +- `src/app/api/oauth/*`:OAuth/设备码流程 +- `src/app/api/keys*`:本地 API 密钥生命周期 +- `src/app/api/models/alias`:别名管理 +- `src/app/api/combos*`:后备 Combo 管理 +- `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`:Thinking Token 预算配置(GET/PUT) +- `src/app/api/settings/system-prompt`:全局系统提示词(GET/PUT) +- `src/app/api/sessions`:活动会话列表(GET) +- `src/app/api/rate-limits`:每账户速率限制状态(GET) -### Routing and Execution Core +### 路由和执行核心 -- `src/sse/handlers/chat.ts`: request parse, combo handling, account selection loop -- `open-sse/handlers/chatCore.ts`: translation, executor dispatch, retry/refresh handling, stream setup -- `open-sse/executors/*`: provider-specific network and format behavior +- `src/sse/handlers/chat.ts`:请求解析、Combo 处理、账户选择循环 +- `open-sse/handlers/chatCore.ts`:翻译、执行器调度、重试/刷新处理、流设置 +- `open-sse/executors/*`:提供商特定的网络和格式行为 -### Translation Registry and Format Converters +### 翻译注册表和格式转换器 -- `open-sse/translator/index.ts`: translator registry and orchestration -- Request translators: `open-sse/translator/request/*` -- Response translators: `open-sse/translator/response/*` -- Format constants: `open-sse/translator/formats.ts` +- `open-sse/translator/index.ts`:翻译器注册表和编排 +- 请求翻译器:`open-sse/translator/request/*` +- 响应翻译器:`open-sse/translator/response/*` +- 格式常量:`open-sse/translator/formats.ts` -### Persistence +### 持久化 -- `src/lib/db/*`: persistent config/state and domain persistence on SQLite -- `src/lib/localDb.ts`: compatibility re-export for DB modules -- `src/lib/usageDb.ts`: usage history/call logs facade on top of SQLite tables +- `src/lib/db/*`:SQLite 上的持久化配置/状态和领域持久化 +- `src/lib/localDb.ts`:数据库模块的兼容性重新导出 +- `src/lib/usageDb.ts`:基于 SQLite 表的用量历史/调用日志外观 -## Provider Executor Coverage (Strategy Pattern) +## 提供商执行器覆盖(策略模式) -Each provider has a specialized executor extending `BaseExecutor` (in `open-sse/executors/base.ts`), which provides URL building, header construction, retry with exponential backoff, credential refresh hooks, and the `execute()` orchestration method. +每个提供商都有一个继承自 `BaseExecutor`(在 `open-sse/executors/base.ts` 中)的专用执行器,提供 URL 构建、请求头构造、指数退避重试、凭证刷新钩子和 `execute()` 编排方法。 -| Executor | Provider(s) | Special Handling | +| 执行器 | 提供商 | 特殊处理 | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | -| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, Qoder, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Dynamic URL/header config per provider | -| `AntigravityExecutor` | Google Antigravity | Custom project/session IDs, Retry-After parsing | -| `CodexExecutor` | OpenAI Codex | Injects system instructions, forces reasoning effort | -| `CursorExecutor` | Cursor IDE | ConnectRPC protocol, Protobuf encoding, request signing via checksum | -| `GithubExecutor` | GitHub Copilot | Copilot token refresh, VSCode-mimicking headers | -| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binary format → SSE conversion | -| `GeminiCLIExecutor` | Gemini CLI | Google OAuth token refresh cycle | +| `DefaultExecutor` | OpenAI、Claude、Gemini、Qwen、Qoder、OpenRouter、GLM、Kimi、MiniMax、DeepSeek、Groq、xAI、Mistral、Perplexity、Together、Fireworks、Cerebras、Cohere、NVIDIA | 每提供商动态 URL/请求头配置 | +| `AntigravityExecutor` | Google Antigravity | 自定义项目/会话 ID,Retry-After 解析 | +| `CodexExecutor` | OpenAI Codex | 注入系统指令,强制推理努力 | +| `CursorExecutor` | Cursor IDE | ConnectRPC 协议,Protobuf 编码,通过校验和签名请求 | +| `GithubExecutor` | GitHub Copilot | Copilot Token 刷新,模拟 VSCode 的请求头 | +| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream 二进制格式 → SSE 转换 | +| `GeminiCLIExecutor` | Gemini CLI | Google OAuth Token 刷新周期 | -All other providers (including custom compatible nodes) use the `DefaultExecutor`. +所有其他提供商(包括自定义兼容节点)使用 `DefaultExecutor`。 -## Provider Compatibility Matrix +## 提供商兼容性矩阵 -| Provider | Format | Auth | Stream | Non-Stream | Token Refresh | Usage API | -| ---------------- | ---------------- | --------------------- | ---------------- | ---------- | ------------- | ------------------ | -| Claude | claude | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Admin only | -| Gemini | gemini | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | -| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | -| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ Full quota API | -| OpenAI | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Codex | openai-responses | OAuth | ✅ forced | ❌ | ✅ | ✅ Rate limits | -| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Quota snapshots | -| Cursor | cursor | Custom checksum | ✅ | ✅ | ❌ | ❌ | -| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Usage limits | -| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Per request | -| Qoder | openai | OAuth (Basic) | ✅ | ✅ | ✅ | ⚠️ Per request | -| OpenRouter | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| GLM/Kimi/MiniMax | claude | API Key | ✅ | ✅ | ❌ | ❌ | -| DeepSeek | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Groq | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| xAI (Grok) | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Mistral | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Perplexity | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Together AI | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Fireworks AI | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Cerebras | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Cohere | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| NVIDIA NIM | openai | API Key | ✅ | ✅ | ❌ | ❌ | +| 提供商 | 格式 | 认证 | 流式传输 | 非流式传输 | Token 刷新 | 用量 API | +| ---------------- | ---------------- | --------------------- | ---------------- | ---------- | ---------- | ------------------ | +| Claude | claude | API 密钥 / OAuth | ✅ | ✅ | ✅ | ⚠️ 仅管理员 | +| Gemini | gemini | API 密钥 / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | +| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | +| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ 完整配额 API | +| OpenAI | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| Codex | openai-responses | OAuth | ✅ 强制 | ❌ | ✅ | ✅ 速率限制 | +| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ 配额快照 | +| Cursor | cursor | 自定义校验和 | ✅ | ✅ | ❌ | ❌ | +| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ 用量限制 | +| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ 每请求 | +| Qoder | openai | OAuth (Basic) | ✅ | ✅ | ✅ | ⚠️ 每请求 | +| OpenRouter | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| GLM/Kimi/MiniMax | claude | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| DeepSeek | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| Groq | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| xAI (Grok) | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| Mistral | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| Perplexity | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| Together AI | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| Fireworks AI | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| Cerebras | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| Cohere | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | +| NVIDIA NIM | openai | API 密钥 | ✅ | ✅ | ❌ | ❌ | -## Format Translation Coverage +## 格式翻译覆盖 -Detected source formats include: +检测到的源格式包括: - `openai` - `openai-responses` - `claude` - `gemini` -Target formats include: +目标格式包括: -- OpenAI chat/Responses +- OpenAI 聊天/Responses - Claude -- Gemini/Gemini-CLI/Antigravity envelope +- Gemini/Gemini-CLI/Antigravity 封装 - Kiro - Cursor -Translations use **OpenAI as the hub format** — all conversions go through OpenAI as intermediate: +翻译使用 **OpenAI 作为中心格式** — 所有转换都通过 OpenAI 作为中介: ``` -Source Format → OpenAI (hub) → Target Format +源格式 → OpenAI(中心)→ 目标格式 ``` -Translations are selected dynamically based on source payload shape and provider target format. +翻译根据源负载形状和提供商目标格式动态选择。 -Additional processing layers in the translation pipeline: +翻译管道中的额外处理层: -- **Response sanitization** — Strips non-standard fields from OpenAI-format responses (both streaming and non-streaming) to ensure strict SDK compliance -- **Role normalization** — Converts `developer` → `system` for non-OpenAI targets; merges `system` → `user` for models that reject the system role (GLM, ERNIE) -- **Think tag extraction** — Parses `...` blocks from content into `reasoning_content` field -- **Structured output** — Converts OpenAI `response_format.json_schema` to Gemini's `responseMimeType` + `responseSchema` +- **响应清理** — 从 OpenAI 格式响应(流式和非流式)中剥离非标准字段,以确保严格的 SDK 合规性 +- **角色规范化** — 为非 OpenAI 目标将 `developer` → `system`;为拒绝 system 角色的模型(GLM、ERNIE)合并 `system` → `user` +- **Think 标签提取** — 从内容中解析 `...` 块到 `reasoning_content` 字段 +- **结构化输出** — 将 OpenAI `response_format.json_schema` 转换为 Gemini 的 `responseMimeType` + `responseSchema` -## Supported API Endpoints +## 支持的 API 端点 -| Endpoint | Format | Handler | +| 端点 | 格式 | 处理器 | | -------------------------------------------------- | ------------------ | ---------------------------------------------------- | -| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` | -| `POST /v1/messages` | Claude Messages | Same handler (auto-detected) | +| `POST /v1/chat/completions` | OpenAI 聊天 | `src/sse/handlers/chat.ts` | +| `POST /v1/messages` | Claude Messages | 相同处理器(自动检测) | | `POST /v1/responses` | OpenAI Responses | `open-sse/handlers/responsesHandler.ts` | | `POST /v1/embeddings` | OpenAI Embeddings | `open-sse/handlers/embeddings.ts` | -| `GET /v1/embeddings` | Model listing | API route | +| `GET /v1/embeddings` | 模型列表 | API 路由 | | `POST /v1/images/generations` | OpenAI Images | `open-sse/handlers/imageGeneration.ts` | -| `GET /v1/images/generations` | Model listing | API route | -| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Dedicated per-provider with model validation | -| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Dedicated per-provider with model validation | -| `POST /v1/providers/{provider}/images/generations` | OpenAI Images | Dedicated per-provider with model validation | -| `POST /v1/messages/count_tokens` | Claude Token Count | API route | -| `GET /v1/models` | OpenAI Models list | API route (chat + embedding + image + custom models) | -| `GET /api/models/catalog` | Catalog | All models grouped by provider + type | -| `POST /v1beta/models/*:streamGenerateContent` | Gemini native | API route | -| `GET/PUT/DELETE /api/settings/proxy` | Proxy Config | Network proxy configuration | -| `POST /api/settings/proxy/test` | Proxy Connectivity | Proxy health/connectivity test endpoint | -| `GET/POST/DELETE /api/provider-models` | Custom Models | Custom model management per provider | +| `GET /v1/images/generations` | 模型列表 | API 路由 | +| `POST /v1/providers/{provider}/chat/completions` | OpenAI 聊天 | 专用的每提供商,带模型验证 | +| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | 专用的每提供商,带模型验证 | +| `POST /v1/providers/{provider}/images/generations` | OpenAI Images | 专用的每提供商,带模型验证 | +| `POST /v1/messages/count_tokens` | Claude Token 计数 | API 路由 | +| `GET /v1/models` | OpenAI 模型列表 | API 路由(聊天 + Embedding + 图像 + 自定义模型) | +| `GET /api/models/catalog` | 目录 | 按提供商 + 类型分组的所有模型 | +| `POST /v1beta/models/*:streamGenerateContent` | Gemini 原生 | API 路由 | +| `GET/PUT/DELETE /api/settings/proxy` | 代理配置 | 网络代理配置 | +| `POST /api/settings/proxy/test` | 代理连接 | 代理健康/连接测试端点 | +| `GET/POST/DELETE /api/provider-models` | 自定义模型 | 每提供商的自定义模型管理 | -## Bypass Handler +## Bypass 处理器 -The bypass handler (`open-sse/utils/bypassHandler.ts`) intercepts known "throwaway" requests from Claude CLI — warmup pings, title extractions, and token counts — and returns a **fake response** without consuming upstream provider tokens. This is triggered only when `User-Agent` contains `claude-cli`. +Bypass 处理器(`open-sse/utils/bypassHandler.ts`)拦截来自 Claude CLI 的已知"丢弃"请求 — 预热 ping、标题提取和 Token 计数 — 并返回**假响应**而不消耗上游提供商的 Token。这仅在 `User-Agent` 包含 `claude-cli` 时触发。 -## Request Logger Pipeline +## 请求日志管道 -The request logger (`open-sse/utils/requestLogger.ts`) provides a 7-stage debug logging pipeline, disabled by default, enabled via `ENABLE_REQUEST_LOGS=true`: +请求日志器(`open-sse/utils/requestLogger.ts`)提供 7 阶段调试日志管道,默认禁用,通过 `ENABLE_REQUEST_LOGS=true` 启用: ``` 1_req_client.json → 2_req_source.json → 3_req_openai.json → 4_req_target.json → 5_res_provider.txt → 6_res_openai.txt → 7_res_client.txt ``` -Files are written to `/logs//` for each request session. +文件写入到 `/logs//`,每个请求会话一个。 -## Failure Modes and Resilience +## 故障模式和弹性 -## 1) Account/Provider Availability +## 1) 账户/提供商可用性 -- provider account cooldown on transient/rate/auth errors -- account fallback before failing request -- combo model fallback when current model/provider path is exhausted +- 瞬态/速率/认证错误时的提供商账户冷却 +- 请求失败前的账户后备 +- 当前模型/提供商路径耗尽时的 Combo 模型后备 -## 2) Token Expiry +## 2) Token 过期 -- pre-check and refresh with retry for refreshable providers -- 401/403 retry after refresh attempt in core path +- 可刷新提供商的预检查和带重试的刷新 +- 核心路径中刷新尝试后的 401/403 重试 -## 3) Stream Safety +## 3) 流安全 -- disconnect-aware stream controller -- translation stream with end-of-stream flush and `[DONE]` handling -- usage estimation fallback when provider usage metadata is missing +- 断开连接感知的流控制器 +- 带流结束刷新和 `[DONE]` 处理的翻译流 +- 提供商用量元数据缺失时的用量估算后备 -## 4) Cloud Sync Degradation +## 4) 云同步降级 -- sync errors are surfaced but local runtime continues -- scheduler has retry-capable logic, but periodic execution currently calls single-attempt sync by default +- 同步错误会显示但本地运行时继续 +- 调度器有重试能力的逻辑,但周期性执行目前默认调用单次尝试同步 -## 5) Data Integrity +## 5) 数据完整性 -- SQLite schema migrations and auto-upgrade hooks at startup -- legacy JSON → SQLite migration compatibility path +- 启动时的 SQLite 模式迁移和自动升级钩子 +- 旧版 JSON → SQLite 迁移兼容路径 -## Observability and Operational Signals +## 可观测性和运营信号 -Runtime visibility sources: +运行时可见性来源: -- console logs from `src/sse/utils/logger.ts` -- per-request usage aggregates in SQLite (`usage_history`, `call_logs`, `proxy_logs`) -- textual request status log in `log.txt` (optional/compat) -- optional deep request/translation logs under `logs/` when `ENABLE_REQUEST_LOGS=true` -- dashboard usage endpoints (`/api/usage/*`) for UI consumption +- 来自 `src/sse/utils/logger.ts` 的控制台日志 +- SQLite 中的每请求用量聚合(`usage_history`、`call_logs`、`proxy_logs`) +- 当 `settings.detailed_logs_enabled=true` 时,SQLite 中四阶段的详细 payload 捕获(`request_detail_logs`) +- `log.txt` 中的文本请求状态日志(可选/兼容) +- 当 `ENABLE_REQUEST_LOGS=true` 时 `logs/` 下的可选深度请求/翻译日志 +- Dashboard 用量端点(`/api/usage/*`)供 UI 消费 -## Security-Sensitive Boundaries +详细请求 payload 捕获会为每次路由调用最多保存四个 JSON payload 阶段: -- JWT secret (`JWT_SECRET`) secures dashboard session cookie verification/signing -- Initial password bootstrap (`INITIAL_PASSWORD`) should be explicitly configured for first-run provisioning -- API key HMAC secret (`API_KEY_SECRET`) secures generated local API key format -- Provider secrets (API keys/tokens) are persisted in local DB and should be protected at filesystem level -- Cloud sync endpoints rely on API key auth + machine id semantics +- 客户端发送的原始请求 +- 实际发送到上游的已翻译请求 +- 还原为 JSON 的提供商响应;流式响应会压缩为最终摘要加流元数据 +- OmniRoute 返回给客户端的最终响应;流式响应同样以相同的紧凑摘要形式存储 -## Environment and Runtime Matrix +## 安全敏感边界 -Environment variables actively used by code: +- JWT 密钥(`JWT_SECRET`)保护 Dashboard 会话 Cookie 验证/签名 +- 初始密码引导(`INITIAL_PASSWORD`)应在首次运行配置时显式配置 +- API 密钥 HMAC 密钥(`API_KEY_SECRET`)保护生成的本地 API 密钥格式 +- 提供商密钥(API 密钥/Token)持久化在本地数据库中,应在文件系统级别保护 +- 云同步端点依赖 API 密钥认证 + 机器 ID 语义 -- App/auth: `JWT_SECRET`, `INITIAL_PASSWORD` -- Storage: `DATA_DIR` -- Compatible node behavior: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` -- Optional storage base override (Linux/macOS when `DATA_DIR` unset): `XDG_CONFIG_HOME` -- Security hashing: `API_KEY_SECRET`, `MACHINE_ID_SALT` -- Logging: `ENABLE_REQUEST_LOGS` -- Sync/cloud URLing: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL` -- Outbound proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` and lowercase variants -- SOCKS5 feature flags: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` -- Platform/runtime helpers (not app-specific config): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME` +## 环境和运行时矩阵 -## Known Architectural Notes +代码中实际使用的环境变量: -1. `usageDb` and `localDb` share the same base directory policy (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) with legacy file migration. -2. `/api/v1/route.ts` delegates to the same unified catalog builder used by `/api/v1/models` (`src/app/api/v1/models/catalog.ts`) to avoid semantic drift. -3. Request logger writes full headers/body when enabled; treat log directory as sensitive. -4. Cloud behavior depends on correct `NEXT_PUBLIC_BASE_URL` and cloud endpoint reachability. -5. The `open-sse/` directory is published as the `@omniroute/open-sse` **npm workspace package**. Source code imports it via `@omniroute/open-sse/...` (resolved by Next.js `transpilePackages`). File paths in this document still use the directory name `open-sse/` for consistency. -6. Charts in the dashboard use **Recharts** (SVG-based) for accessible, interactive analytics visualizations (model usage bar charts, provider breakdown tables with success rates). -7. E2E tests use **Playwright** (`tests/e2e/`), run via `npm run test:e2e`. Unit tests use **Node.js test runner** (`tests/unit/`), run via `npm run test:unit`. Source code under `src/` is **TypeScript** (`.ts`/`.tsx`); the `open-sse/` workspace remains JavaScript (`.js`). -8. Settings page is organized into 5 tabs: Security, Routing (6 global strategies: fill-first, round-robin, p2c, random, least-used, cost-optimized), Resilience (editable rate limits, circuit breaker, policies), AI (thinking budget, system prompt, prompt cache), Advanced (proxy). +- 应用/认证:`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` -## Operational Verification Checklist +## 已知架构说明 -- Build from source: `npm run build` -- Build Docker image: `docker build -t omniroute .` -- Start service and verify: +1. `usageDb` 和 `localDb` 共享相同的基础目录策略(`DATA_DIR` → `XDG_CONFIG_HOME/omniroute` → `~/.omniroute`)并支持旧版文件迁移。 +2. `/api/v1/route.ts` 委托给 `/api/v1/models`(`src/app/api/v1/models/catalog.ts`)使用的相同统一目录构建器,以避免语义漂移。 +3. 请求日志器启用时写入完整的请求头/请求体;应将日志目录视为敏感信息。 +4. 云行为取决于正确的 `NEXT_PUBLIC_BASE_URL` 和云端点可达性。 +5. `open-sse/` 目录作为 `@omniroute/open-sse` **npm 工作区包**发布。源代码通过 `@omniroute/open-sse/...` 导入(由 Next.js `transpilePackages` 解析)。本文档中的文件路径仍使用目录名 `open-sse/` 以保持一致性。 +6. Dashboard 中的图表使用 **Recharts**(基于 SVG)实现可访问的交互式分析可视化(模型用量柱状图、带成功率的提供商分解表)。 +7. E2E 测试使用 **Playwright**(`tests/e2e/`),通过 `npm run test:e2e` 运行。单元测试使用 **Node.js 测试运行器**(`tests/unit/`),通过 `npm run test:unit` 运行。`src/` 下的源代码是 **TypeScript**(`.ts`/`.tsx`);`open-sse/` 工作区保持 JavaScript(`.js`)。 +8. 设置页面组织为 5 个标签页:安全、路由(6 种全局策略:填充优先、轮询、p2c、随机、最少使用、成本优化)、弹性(可编辑的速率限制、熔断器、策略)、AI(Thinking 预算、系统提示词、提示词缓存)、高级(代理)。 + +## 运营验证清单 + +- 从源代码构建:`npm run build` +- 构建 Docker 镜像:`docker build -t omniroute .` +- 启动服务并验证: - `GET /api/settings` - `GET /api/v1/models` -- CLI target base URL should be `http://:20128/v1` when `PORT=20128` +- CLI 目标基础 URL 应为 `http://:20128/v1`(当 `PORT=20128` 时) diff --git a/docs/i18n/zh-CN/AUTO-COMBO.md b/docs/i18n/zh-CN/AUTO-COMBO.md index 2166e41d..84ecc7f8 100644 --- a/docs/i18n/zh-CN/AUTO-COMBO.md +++ b/docs/i18n/zh-CN/AUTO-COMBO.md @@ -1,67 +1,67 @@ -🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/AUTO-COMBO.md) · 🇪🇸 [es](../es/AUTO-COMBO.md) · 🇫🇷 [fr](../fr/AUTO-COMBO.md) · 🇩🇪 [de](../de/AUTO-COMBO.md) · 🇮🇹 [it](../it/AUTO-COMBO.md) · 🇷🇺 [ru](../ru/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../zh-CN/AUTO-COMBO.md) · 🇯🇵 [ja](../ja/AUTO-COMBO.md) · 🇰🇷 [ko](../ko/AUTO-COMBO.md) · 🇸🇦 [ar](../ar/AUTO-COMBO.md) · 🇮🇳 [in](../in/AUTO-COMBO.md) · 🇹🇭 [th](../th/AUTO-COMBO.md) · 🇻🇳 [vi](../vi/AUTO-COMBO.md) · 🇮🇩 [id](../id/AUTO-COMBO.md) · 🇲🇾 [ms](../ms/AUTO-COMBO.md) · 🇳🇱 [nl](../nl/AUTO-COMBO.md) · 🇵🇱 [pl](../pl/AUTO-COMBO.md) · 🇸🇪 [sv](../sv/AUTO-COMBO.md) · 🇳🇴 [no](../no/AUTO-COMBO.md) · 🇩🇰 [da](../da/AUTO-COMBO.md) · 🇫🇮 [fi](../fi/AUTO-COMBO.md) · 🇵🇹 [pt](../pt/AUTO-COMBO.md) · 🇷🇴 [ro](../ro/AUTO-COMBO.md) · 🇭🇺 [hu](../hu/AUTO-COMBO.md) · 🇧🇬 [bg](../bg/AUTO-COMBO.md) · 🇸🇰 [sk](../sk/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../uk-UA/AUTO-COMBO.md) · 🇮🇱 [he](../he/AUTO-COMBO.md) · 🇵🇭 [phi](../phi/AUTO-COMBO.md) +🌐 **语言:** 🇺🇸 [English](../../AUTO-COMBO.md) · 🇧🇷 [pt-BR](../pt-BR/AUTO-COMBO.md) · 🇪🇸 [es](../es/AUTO-COMBO.md) · 🇫🇷 [fr](../fr/AUTO-COMBO.md) · 🇩🇪 [de](../de/AUTO-COMBO.md) · 🇮🇹 [it](../it/AUTO-COMBO.md) · 🇷🇺 [ru](../ru/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../zh-CN/AUTO-COMBO.md) · 🇯🇵 [ja](../ja/AUTO-COMBO.md) · 🇰🇷 [ko](../ko/AUTO-COMBO.md) · 🇸🇦 [ar](../ar/AUTO-COMBO.md) · 🇮🇳 [in](../in/AUTO-COMBO.md) · 🇹🇭 [th](../th/AUTO-COMBO.md) · 🇻🇳 [vi](../vi/AUTO-COMBO.md) · 🇮🇩 [id](../id/AUTO-COMBO.md) · 🇲🇾 [ms](../ms/AUTO-COMBO.md) · 🇳🇱 [nl](../nl/AUTO-COMBO.md) · 🇵🇱 [pl](../pl/AUTO-COMBO.md) · 🇸🇪 [sv](../sv/AUTO-COMBO.md) · 🇳🇴 [no](../no/AUTO-COMBO.md) · 🇩🇰 [da](../da/AUTO-COMBO.md) · 🇫🇮 [fi](../fi/AUTO-COMBO.md) · 🇵🇹 [pt](../pt/AUTO-COMBO.md) · 🇷🇴 [ro](../ro/AUTO-COMBO.md) · 🇭🇺 [hu](../hu/AUTO-COMBO.md) · 🇧🇬 [bg](../bg/AUTO-COMBO.md) · 🇸🇰 [sk](../sk/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../uk-UA/AUTO-COMBO.md) · 🇮🇱 [he](../he/AUTO-COMBO.md) · 🇵🇭 [phi](../phi/AUTO-COMBO.md) --- -# OmniRoute Auto-Combo Engine +# OmniRoute Auto-Combo 引擎 -> Self-managing model chains with adaptive scoring +> 具有自适应评分的自管理模型链 -## How It Works +## 工作原理 -The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**: +Auto-Combo 引擎使用 **6 因子评分函数** 为每个请求动态选择最佳服务商/模型: -| Factor | Weight | Description | -| :--------- | :----- | :---------------------------------------------- | -| Quota | 0.20 | Remaining capacity [0..1] | -| Health | 0.25 | Circuit breaker: CLOSED=1.0, HALF=0.5, OPEN=0.0 | -| CostInv | 0.20 | Inverse cost (cheaper = higher score) | -| LatencyInv | 0.15 | Inverse p95 latency (faster = higher) | -| TaskFit | 0.10 | Model × task type fitness score | -| Stability | 0.10 | Low variance in latency/errors | +| 因子 | 权重 | 描述 | +| :--------- | :--- | :--------------------------------------- | +| Quota | 0.20 | 剩余容量 [0..1] | +| Health | 0.25 | 熔断器状态:CLOSED=1.0, HALF=0.5, OPEN=0.0 | +| CostInv | 0.20 | 成本倒数(越便宜得分越高) | +| LatencyInv | 0.15 | p95 延迟倒数(越快得分越高) | +| TaskFit | 0.10 | 模型 × 任务类型适配度 | +| Stability | 0.10 | 延迟/错误率的低方差 | -## Mode Packs +## 模式包 -| Pack | Focus | Key Weight | -| :---------------------- | :----------- | :--------------- | -| 🚀 **Ship Fast** | Speed | latencyInv: 0.35 | -| 💰 **Cost Saver** | Economy | costInv: 0.40 | -| 🎯 **Quality First** | Best model | taskFit: 0.40 | -| 📡 **Offline Friendly** | Availability | quota: 0.40 | +| 模式包 | 侧重点 | 关键权重 | +| :---------------------- | :----- | :--------------- | +| 🚀 **Ship Fast** | 速度 | latencyInv: 0.35 | +| 💰 **Cost Saver** | 经济 | costInv: 0.40 | +| 🎯 **Quality First** | 最优模型 | taskFit: 0.40 | +| 📡 **Offline Friendly** | 可用性 | quota: 0.40 | -## Self-Healing +## 自愈能力 -- **Temporary exclusion**: Score < 0.2 → excluded for 5 min (progressive backoff, max 30 min) -- **Circuit breaker awareness**: OPEN → auto-excluded; HALF_OPEN → probe requests -- **Incident mode**: >50% OPEN → disable exploration, maximize stability -- **Cooldown recovery**: After exclusion, first request is a "probe" with reduced timeout +- **临时排除**:评分 < 0.2 → 排除 5 分钟(渐进退避,最长 30 分钟) +- **熔断器感知**:OPEN → 自动排除;HALF_OPEN → 探测请求 +- **事故模式**:>50% OPEN → 禁用探索,最大化稳定性 +- **冷却恢复**:排除结束后,首个请求为"探测"请求,使用缩短的超时时间 -## Bandit Exploration +## Bandit 探索 -5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode. +5% 的请求(可配置)会被路由到随机服务商进行探索。在事故模式下禁用。 ## API ```bash -# Create auto-combo +# 创建 auto-combo curl -X POST http://localhost:20128/api/combos/auto \ -H "Content-Type: application/json" \ -d '{"id":"my-auto","name":"Auto Coder","candidatePool":["anthropic","google","openai"],"modePack":"ship-fast"}' -# List auto-combos +# 列出 auto-combos curl http://localhost:20128/api/combos/auto ``` -## Task Fitness +## 任务适配度 -30+ models scored across 6 task types (`coding`, `review`, `planning`, `analysis`, `debugging`, `documentation`). Supports wildcard patterns (e.g., `*-coder` → high coding score). +30+ 个模型在 6 种任务类型(`coding`、`review`、`planning`、`analysis`、`debugging`、`documentation`)上进行评分。支持通配符模式(例如 `*-coder` → 高编码得分)。 -## Files +## 文件 -| File | Purpose | -| :------------------------------------------- | :------------------------------------ | -| `open-sse/services/autoCombo/scoring.ts` | Scoring function & pool normalization | -| `open-sse/services/autoCombo/taskFitness.ts` | Model × task fitness lookup | -| `open-sse/services/autoCombo/engine.ts` | Selection logic, bandit, budget cap | -| `open-sse/services/autoCombo/selfHealing.ts` | Exclusion, probes, incident mode | -| `open-sse/services/autoCombo/modePacks.ts` | 4 weight profiles | -| `src/app/api/combos/auto/route.ts` | REST API | +| 文件 | 用途 | +| :------------------------------------------- | :------------------------ | +| `open-sse/services/autoCombo/scoring.ts` | 评分函数 & 池归一化 | +| `open-sse/services/autoCombo/taskFitness.ts` | 模型 × 任务适配度查询 | +| `open-sse/services/autoCombo/engine.ts` | 选择逻辑、bandit、预算上限 | +| `open-sse/services/autoCombo/selfHealing.ts` | 排除、探测、事故模式 | +| `open-sse/services/autoCombo/modePacks.ts` | 4 种权重配置 | +| `src/app/api/combos/auto/route.ts` | REST API | diff --git a/docs/i18n/zh-CN/CHANGELOG.md b/docs/i18n/zh-CN/CHANGELOG.md index dd3e163f..2103b0df 100644 --- a/docs/i18n/zh-CN/CHANGELOG.md +++ b/docs/i18n/zh-CN/CHANGELOG.md @@ -1,371 +1,427 @@ -# Changelog (中文(简体)) +# 更新日志 -🌐 **Languages:** 🇺🇸 [English](../../../CHANGELOG.md) · 🇪🇸 [es](../es/CHANGELOG.md) · 🇫🇷 [fr](../fr/CHANGELOG.md) · 🇩🇪 [de](../de/CHANGELOG.md) · 🇮🇹 [it](../it/CHANGELOG.md) · 🇷🇺 [ru](../ru/CHANGELOG.md) · 🇨🇳 [zh-CN](../zh-CN/CHANGELOG.md) · 🇯🇵 [ja](../ja/CHANGELOG.md) · 🇰🇷 [ko](../ko/CHANGELOG.md) · 🇸🇦 [ar](../ar/CHANGELOG.md) · 🇮🇳 [in](../in/CHANGELOG.md) · 🇹🇭 [th](../th/CHANGELOG.md) · 🇻🇳 [vi](../vi/CHANGELOG.md) · 🇮🇩 [id](../id/CHANGELOG.md) · 🇲🇾 [ms](../ms/CHANGELOG.md) · 🇳🇱 [nl](../nl/CHANGELOG.md) · 🇵🇱 [pl](../pl/CHANGELOG.md) · 🇸🇪 [sv](../sv/CHANGELOG.md) · 🇳🇴 [no](../no/CHANGELOG.md) · 🇩🇰 [da](../da/CHANGELOG.md) · 🇫🇮 [fi](../fi/CHANGELOG.md) · 🇵🇹 [pt](../pt/CHANGELOG.md) · 🇷🇴 [ro](../ro/CHANGELOG.md) · 🇭🇺 [hu](../hu/CHANGELOG.md) · 🇧🇬 [bg](../bg/CHANGELOG.md) · 🇸🇰 [sk](../sk/CHANGELOG.md) · 🇺🇦 [uk-UA](../uk-UA/CHANGELOG.md) · 🇮🇱 [he](../he/CHANGELOG.md) · 🇵🇭 [phi](../phi/CHANGELOG.md) · 🇧🇷 [pt-BR](../pt-BR/CHANGELOG.md) +🌐 **语言:** 🇺🇸 [English](../../../CHANGELOG.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CHANGELOG.md) | 🇪🇸 [Español](../es/CHANGELOG.md) | 🇫🇷 [Français](../fr/CHANGELOG.md) | 🇮🇹 [Italiano](../it/CHANGELOG.md) | 🇷🇺 [Русский](../ru/CHANGELOG.md) | 🇨🇳 [中文 (简体)](../zh-CN/CHANGELOG.md) | 🇩🇪 [Deutsch](../de/CHANGELOG.md) | 🇮🇳 [हिन्दी](../in/CHANGELOG.md) | 🇹🇭 [ไทย](../th/CHANGELOG.md) | 🇺🇦 [Українська](../uk-UA/CHANGELOG.md) | 🇸🇦 [العربية](../ar/CHANGELOG.md) | 🇯🇵 [日本語](../ja/CHANGELOG.md) | 🇻🇳 [Tiếng Việt](../vi/CHANGELOG.md) | 🇧🇬 [Български](../bg/CHANGELOG.md) | 🇩🇰 [Dansk](../da/CHANGELOG.md) | 🇫🇮 [Suomi](../fi/CHANGELOG.md) | 🇮🇱 [עברית](../he/CHANGELOG.md) | 🇭🇺 [Magyar](../hu/CHANGELOG.md) | 🇮🇩 [Bahasa Indonesia](../id/CHANGELOG.md) | 🇰🇷 [한국어](../ko/CHANGELOG.md) | 🇲🇾 [Bahasa Melayu](../ms/CHANGELOG.md) | 🇳🇱 [Nederlands](../nl/CHANGELOG.md) | 🇳🇴 [Norsk](../no/CHANGELOG.md) | 🇵🇹 [Português (Portugal)](../pt/CHANGELOG.md) | 🇷🇴 [Română](../ro/CHANGELOG.md) | 🇵🇱 [Polski](../pl/CHANGELOG.md) | 🇸🇰 [Slovenčina](../sk/CHANGELOG.md) | 🇸🇪 [Svenska](../sv/CHANGELOG.md) | 🇵🇭 [Filipino](../phi/CHANGELOG.md) | 🇨🇿 [Čeština](../cs/CHANGELOG.md) --- +## [未发布] -## [Unreleased] +> [!WARNING] +> **破坏性变更:请求日志、保留策略以及日志环境变量已经重新设计。** +> 升级后的首次启动时,OmniRoute 会将 `DATA_DIR/logs/`、旧版 `DATA_DIR/call_logs/` 以及 `DATA_DIR/log.txt` 中的历史请求日志归档到 `DATA_DIR/log_archives/*.zip`,随后移除旧布局并切换到 `DATA_DIR/call_logs/` 下新的统一 artifact 格式。 + +### ✨ 新特性 + +- **统一请求日志 Artifact:** 请求日志现在会在 `DATA_DIR/call_logs/` 下为每个请求保存一条 SQLite 索引记录和一个 JSON artifact,并可将可选的流水线捕获内容嵌入同一文件。 +- **语言:** 改进了中文翻译(#855) +- **Opencode-Zen Models:** 为 opencode-zen 注册表新增了 4 个免费模型(#854) +- **测试:** 为设置开关和 bug 修复新增了单元测试与 E2E 测试(#850) + +### 🐛 Bug 修复 + +- **429 配额解析:** 从错误响应体中解析较长的配额重置时间,以便应用正确的回退等待,避免因限流导致账户被封(#859) +- **提示词缓存:** 为所有 Claude 协议提供商(如 Minimax、GLM、Bailian)保留客户端 `cache_control` 头,正确识别缓存能力(#856) +- **模型同步日志:** 仅在 `sync-models` 通道确实修改列表时记录日志,减少日志噪声(#853) +- **提供商配额与 token 解析:** 将 Antigravity 限额逻辑切换为原生使用 `retrieveUserQuota`,并正确将 Claude token 刷新负载映射为 URL-encoded 表单(#862) +- **限流稳定性:** 将 429 `Retry-After` 的解析架构统一化,把提供商导致的冷却时间上限限制为 24 小时(#862) +- **Dashboard 限额渲染:** 重构 `/dashboard/limits` 的配额映射逻辑,使其可在 chunk 内立即渲染,修复当账户超过 70 个活跃连接时 UI 严重卡顿的问题(#784) + +### ⚠️ 破坏性变更 + +- **请求日志布局:** 移除了旧的多文件 `DATA_DIR/logs/` 请求日志会话目录和 `DATA_DIR/log.txt` 汇总文件。新请求会以单个 JSON artifact 的形式写入 `DATA_DIR/call_logs/YYYY-MM-DD/`。 +- **日志环境变量:** 用新的 `APP_LOG_*` 与 `CALL_LOG_RETENTION_DAYS` 配置模型,替换了 `LOG_*`、`ENABLE_REQUEST_LOGS`、`CALL_LOGS_MAX`、`CALL_LOG_PAYLOAD_MODE` 和 `PROXY_LOG_MAX_ENTRIES`。 +- **流水线开关设置:** 用 `call_log_pipeline_enabled` 取代旧的 `detailed_logs_enabled`。新的流水线详情会直接嵌入请求 artifact 中,而不再以单独的 `request_detail_logs` 记录保存。 + +### 🛠️ 维护 + +- **旧请求日志升级备份:** 升级时会先将旧的 `data/logs/`、旧版 `data/call_logs/` 和 `data/log.txt` 归档到 `DATA_DIR/log_archives/*.zip`,再删除已废弃的结构。 +- **流式用量持久化:** 流式请求完成后现在只会写入一条 `usage_history` 记录,不再额外写入带空状态元数据的重复 in-progress 记录。 + +--- + +## [3.3.11] - 2026-03-31 + +### 🚀 新特性 + +- **订阅使用率分析:** 新增配额快照时间序列跟踪、Provider Utilization 和 Combo Health 标签页,并接入相应的 recharts 可视化与 API 端点(#847) +- **SQLite 备份控制:** 新增 `OMNIROUTE_DISABLE_AUTO_BACKUP` 环境变量,用于禁用自动 SQLite 备份(#846) +- **模型注册表更新:** 将 `gpt-5.4-mini` 注入到 Codex 提供商的模型数组中(#756) +- **提供商限额跟踪:** 跟踪并展示每个账户的 provider rate limit 最后刷新时间(#843) + +### 🐛 Bug 修复 + +- **Qwen 认证路由:** 将 Qwen OAuth completions 从 DashScope API 重新路由到 Web Inference API(`chat.qwen.ai`),修复认证失败问题(#844、#807、#832) +- **Qwen 自动重试循环:** 在 `chatCore` 中加入针对 429 Quota Exceeded 的定向回退处理,保护突发请求 +- **Codex OAuth 回退:** 现代浏览器的弹窗拦截不再让用户卡死,现已自动回退为手动 URL 输入(#808) +- **Claude token 刷新:** 在生成 token 时遵守 Anthropic 严格的 `application/json` 边界,而不再错误使用 URL 编码(#836) +- **Codex messages Schema:** 从原生透传请求中移除过于严格的 `messages` 注入,避免被 ChatGPT 上游以结构错误拒绝(#806) +- **CLI 检测体积限制:** 将 Node 二进制扫描上限从 100MB 安全提升到 350MB,使 Claude Code(229MB)和 OpenCode(153MB)等大型独立工具可在 VPS 运行时中被正确检测(#809) +- **CLI 运行时环境:** 恢复 CLI 配置对用户覆盖路径(`CLI_{PROVIDER}_BIN`)的支持,不再被严格的路径发现规则阻断 +- **Nvidia 头部冲突:** 调用非 Anthropic 提供商时移除上游头中的 `prompt_cache_key` 字段(#848) +- **Codex Fast 档位开关:** 恢复 Codex service tier 开关在浅色模式下的对比度(#842) +- **测试基础设施:** 更新 `t28-model-catalog-updates` 测试,修复其仍错误期望旧 DashScope 端点的问题 --- ## [3.3.9] - 2026-03-31 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Custom Provider Rotation:** Integrated `getRotatingApiKey` internally inside DefaultExecutor, ensuring `extraApiKeys` rotation triggers correctly for custom and compatible upstream providers (#815) +- **自定义服务商轮换:** 在 DefaultExecutor 内部集成了 `getRotatingApiKey`,确保自定义和兼容的上游服务商的 `extraApiKeys` 轮换正确触发 (#815) --- ## [3.3.8] - 2026-03-30 -### 功能特点 +### 🚀 新特性 -- **Models API Filtering:** Endpoint `/v1/models` now dynamically filters its list based on the permissions tied to the `Authorization: Bearer ` when restricted access is on (#781) -- **Qoder Integration:** Native integration for Qoder AI natively replacing the legacy iFlow platform mappings (#660) -- **Prompt Cache Tracking:** Added tracking capabilities and frontend visualization (Stats card) for semantic and prompt caching in the Dashboard UI +- **Models API 过滤:** 端点 `/v1/models` 现在根据绑定到 `Authorization: Bearer ` 的权限动态过滤其列表(当启用访问限制时) (#781) +- **Qoder 集成:** 原生集成 Qoder AI,原生替换传统的 iFlow 平台映射 (#660) +- **提示词缓存追踪:** 添加了追踪功能和前端可视化(统计卡片),用于仪表盘界面中的语义和提示词缓存 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Cache Dashboard Sizing:** Improved the UI layout sizes and context headers for the advanced cache pages (#835) -- **Debug Sidebar Visibility:** Fixed an issue where the debug toggle wouldn't correctly show/hide sidebar debug details (#834) -- **Gemini Model Prefixing:** Modified the namespace fallback to properly route via `gemini-cli/` instead of `gc/` to respect upstream specs (#831) -- **OpenRouter Sync:** Improved compatibility synchronization to automatically ingest the available models catalog correctly from OpenRouter (#830) -- **Streaming Payloads Mapping:** Reserialization of reasoning fields natively resolves conflict alias paths when output is streaming to edge devices +- **缓存仪表盘大小:** 改进了高级缓存页面的界面布局大小和上下文标题 (#835) +- **调试侧边栏可见性:** 修复了一个问题:调试开关无法正确显示/隐藏侧边栏调试详情 (#834) +- **Gemini 模型前缀:** 修改了命名空间回退,以通过 `gemini-cli/` 而不是 `gc/` 正确路由,从而遵守上游规范 (#831) +- **OpenRouter 同步:** 改进了兼容性同步,以正确地自动从 OpenRouter 获取可用模型目录 (#830) +- **流式传输负载映射:** 当输出流式传输到边缘设备时,推理字段的重新序列化可原生解决冲突别名路径 --- ## [3.3.7] - 2026-03-30 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **OpenCode Config:** Restructured generated `opencode.json` to use the `@ai-sdk/openai-compatible` record-based schema with `options` and `models` as object maps instead of flat arrays, fixing config validation failures (#816) -- **i18n Missing Keys:** Added missing `cloudflaredUrlNotice` translation key across all 30 language files to prevent `MISSING_MESSAGE` console errors in the Endpoint page (#823) +- **OpenCode 配置:** 重构生成的 `opencode.json`,使用 `@ai-sdk/openai-compatible` 基于记录的架构,将 `options` 和 `models` 作为对象映射而不是扁平数组,修复了配置验证失败的问题 (#816) +- **i18n 缺失键:** 在所有 30 个语言文件中添加了缺失的 `cloudflaredUrlNotice` 翻译键,以防止 Endpoint 页面中的 `MISSING_MESSAGE` 控制台错误 (#823) --- ## [3.3.6] - 2026-03-30 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Token Accounting:** Included prompt cache tokens safely in historical usage inputs calculations for correct quota deductions (PR #822) -- **Combo Test Probes:** Fixed combo testing logic false negatives by resolving parsing for reasoning-only responses and enabled massive parallelization via Promise.all (PR #828) -- **Docker Quick Tunnels:** Embedded required ca-certificates inside the base runtime container to resolve Cloudflared TLS startup failures, and surfaced stdout network errors replacing generic exit codes (PR #829) +- **Token 计费:** 在历史用量输入计算中安全地包含了提示词缓存 token,以实现正确的配额扣除 (PR #822) +- **Combo 测试探针:** 通过解析仅推理响应并通过 Promise.all 实现大规模并行化,修复了 combo 测试逻辑的误报问题 (PR #828) +- **Docker 快速隧道:** 在基础运行时容器中嵌入了所需的 ca-certificates 以解决 Cloudflared TLS 启动失败,并显示 stdout 网络错误以替换通用退出代码 (PR #829) --- ## [3.3.5] - 2026-03-30 -### ✨ New Features +### ✨ 新特性 -- **Gemini Quota Tracking:** Added real-time Gemini CLI quota tracking via the `retrieveUserQuota` API (PR #825) -- **Cache Dashboard:** Enhanced the Cache Dashboard to display prompt cache metrics, 24h trends, and estimated cost savings (PR #824) +- **Gemini 配额追踪:** 通过 `retrieveUserQuota` API 添加了实时 Gemini CLI 配额追踪 (PR #825) +- **缓存仪表盘:** 增强了缓存仪表盘,可显示提示词缓存指标、24小时趋势和预估成本节省 (PR #824) -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **User Experience:** Removed invasive auto-opening OAuth modal loops on barren provider detailed pages (PR #820) -- **Dependency Updates:** Bumped and locked down dependencies for development and production trees including Next.js 16.2.1, Recharts, and TailwindCSS 4.2.2 (PR #826, #827) +- **用户体验:** 移除了在空白服务商详情页面上侵入性的自动打开 OAuth 模态框循环 (PR #820) +- **依赖更新:** 更新并锁定了开发和生产依赖树,包括 Next.js 16.2.1、Recharts 和 TailwindCSS 4.2.2 (PR #826, #827) --- ## [3.3.4] - 2026-03-30 -### ✨ New Features +### ✨ 新特性 -- **A2A Workflows:** Added deterministic FSM orchestrator for multi-step agent workflows. -- **Graceful Degradation:** Added a new multi-layer fallback framework to preserve core functionality during partial system outages. -- **Config Audit:** Added an audit trail with diff detection to track changes and enable configuration rollbacks. -- **Provider Health:** Added provider expiration tracking with proactive UI alerts for expiring API keys. -- **Adaptive Routing:** Added an adaptive volume and complexity detector to override routing strategies dynamically based on load. -- **Provider Diversity:** Implemented provider diversity scoring via Shannon entropy to improve load distribution. -- **Auto-Disable Bounds:** Added an Auto-Disable Banned Accounts setting toggle to the Resilience dashboard. +- **A2A 工作流:** 添加了用于多步骤代理工作流的确定性 FSM 编排器 +- **优雅降级:** 添加了新的多层回退框架,以在部分系统故障期间保持核心功能 +- **配置审计:** 添加了带 diff 检测的审计追踪,以追踪变更并启用配置回滚 +- **服务商健康状态:** 添加了服务商过期追踪,并为即将过期的 API 密钥提供主动 UI 警报 +- **自适应路由:** 添加了自适应流量和复杂度检测器,可根据负载动态覆盖路由策略 +- **服务商多样性:** 通过香农熵实现了服务商多样性评分,以改善负载分配 +- **自动禁用边界:** 在弹性仪表盘中添加了自动禁用被封禁账户的设置开关 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Codex & Claude Compatibility:** Fixed UI fallbacks, patched Codex non-streaming integration issues, and resolved CLI runtime detection on Windows. -- **Release Automation:** Expanded permissions required for the Electron App build in GitHub Actions. -- **Cloudflare Runtime:** Addressed correct runtime isolation exit codes for Cloudflared tunnel components. +- **Codex 和 Claude 兼容性:** 修复了 UI 回退,修补了 Codex 非流式传输集成问题,并解决了 Windows 上的 CLI 运行时检测问题 +- **发布自动化:** 扩展了 GitHub Actions 中 Electron App 构建所需的权限 +- **Cloudflare 运行时:** 处理了 Cloudflared 隧道组件的正确运行时隔离退出代码 -### 🧪 Tests +### 🧪 测试 -- **Test Suite Updates:** Expanded test coverage for volume detectors, provider diversity, configuration audit, and FSM. +- **测试套件更新:** 扩展了流量检测器、服务商多样性、配置审计和 FSM 的测试覆盖率 --- ## [3.3.3] - 2026-03-29 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **CI/CD Reliability:** Patched GitHub Actions to stable dependency versions (`actions/checkout@v4`, `actions/upload-artifact@v4`) to mitigate unannounced builder environment deprecations. -- **Image Fallbacks:** Replaced arbitrary fallback chains in `ProviderIcon.tsx` with explicit asset validation to prevent UI loading `` components for files that don't exist, eliminating `404` errors in dashboard console logs (#745). -- **Admin Updater:** Dynamic source-installation detection for the dashboard Updater. Safely disables the `Update Now` button when OmniRoute is built locally rather than through npm, prompting for `git pull` (#743). -- **Update ERESOLVE Error:** Injected `package.json` overrides for `react`/`react-dom` and enabled `--legacy-peer-deps` within the internal automatic updater scripts to resolve breaking dependency tree conflicts with `@lobehub/ui`. +- **CI/CD 可靠性:** 修补了 GitHub Actions 使用稳定的依赖版本(`actions/checkout@v4`、`actions/upload-artifact@v4`),以缓解未公告的构建环境弃用问题。 +- **图片回退:** 替换了 `ProviderIcon.tsx` 中的任意回退链,改用显式资源验证来防止 UI 加载不存在文件的 `` 组件,从而消除仪表盘控制台日志中的 `404` 错误(#745)。 +- **管理员更新器:** 为仪表盘更新器添加了动态源安装检测。当 OmniRoute 是本地构建而非通过 npm 安装时,安全地禁用 `立即更新` 按钮,并提示使用 `git pull`(#743)。 +- **更新 ERESOLVE 错误:** 在内部自动更新脚本中注入了 `package.json` 覆盖配置(用于 `react`/`react-dom`)并启用了 `--legacy-peer-deps`,以解决与 `@lobehub/ui` 的破坏性依赖树冲突。 --- ## [3.3.2] - 2026-03-29 -### ✨ New Features +### ✨ 新特性 -- **Cloudflare Tunnels:** Cloudflare Quick Tunnel integration with dashboard controls (PR #772). -- **Diagnostics:** Semantic cache bypass for combo live tests (PR #773). +- **Cloudflare Tunnels:** Cloudflare Quick Tunnel 集成,带有仪表盘控制功能(PR #772)。 +- **Diagnostics:** 为组合实时测试添加了语义缓存绕过功能(PR #773)。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Streaming Stability:** Apply `FETCH_TIMEOUT_MS` to streaming requests' initial `fetch()` call to prevent 300s Node.js TCP timeout causing silent task failures (#769). -- **i18n:** Add missing `windsurf` and `copilot` entries to `toolDescriptions` across all 33 locale files (#748). -- **GLM Coding Audit:** Complete provider audit fixing ReDoS vulnerabilities, context window sizing (128k/16k), and model registry syncing (PR #778). +- **Streaming Stability:** 将 `FETCH_TIMEOUT_MS` 应用于流式请求的初始 `fetch()` 调用,以防止 300 秒 Node.js TCP 超时导致的静默任务失败(#769)。 +- **i18n:** 在所有 33 个语言文件的 `toolDescriptions` 中添加了缺失的 `windsurf` 和 `copilot` 条目(#748)。 +- **GLM Coding Audit:** 完成了服务商审计,修复了 ReDoS 漏洞、上下文窗口大小(128k/16k)以及模型注册表同步(PR #778)。 --- ## [3.3.1] - 2026-03-29 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **OpenAI Codex:** Fallback processing fix for `type: "text"` elements carrying null or empty datasets that caused 400 rejection (#742). -- **Opencode:** Update schema alignment to singular `provider` to match official spec (#774). -- **Gemini CLI:** Inject missing end-user quota headers preventing 403 authorization lockouts (#775). -- **DB Recovery:** Refactor multipart payload imports into raw binary buffered arrays to bypass reverse proxy max body limits (#770). +- **OpenAI Codex:** 修复了回退处理中 `type: "text"` 元素携带 null 或空数据集导致 400 拒绝的问题(#742)。 +- **Opencode:** 更新架构对齐,使用单数 `provider` 以匹配官方规范(#774)。 +- **Gemini CLI:** 注入缺失的终端用户配额头,防止 403 授权锁定(#775)。 +- **DB Recovery:** 将多部分负载导入重构为原始二进制缓冲数组,以绕过反向代理的最大正文限制(#770)。 --- ## [3.3.0] - 2026-03-29 -### ✨ Enhancements & Refactoring +### ✨ 增强与重构 -- **Release Stabilization** — Finalized v3.2.9 release (combo diagnostics, quality gates, Gemini tool fix) and created missing git tag. Consolidated all staged changes into a single atomic release commit. +- **Release Stabilization** — 完成了 v3.2.9 版本发布(组合诊断、质量检测、Gemini 工具修复)并创建了缺失的 git 标签。将所有暂存的更改整合到单个原子发布提交中。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Auto-Update Test** — Fixed `buildDockerComposeUpdateScript` test assertion to match unexpanded shell variable references (`$TARGET_TAG`, `${TARGET_TAG#v}`) in the generated deploy script, aligning with the refactored template from v3.2.8. -- **Circuit Breaker Test** — Hardened `combo-circuit-breaker.test.mjs` by injecting `maxRetries: 0` to prevent retry inflation from skewing failure count assertions during breaker state transitions. +- **Auto-Update Test** — 修复了 `buildDockerComposeUpdateScript` 测试断言,以匹配生成的部署脚本中未展开的 shell 变量引用(`$TARGET_TAG`、`${TARGET_TAG#v}`),与 v3.2.8 的重构模板对齐。 +- **Circuit Breaker Test** — 通过注入 `maxRetries: 0` 强化了 `combo-circuit-breaker.test.mjs`,以防止在断路器状态转换期间重试膨胀扭曲失败计数断言。 --- ## [3.2.9] - 2026-03-29 -### ✨ Enhancements & Refactoring +### ✨ 增强与重构 -- **Combo Diagnostics** — Introduced a live test bypass flag (`forceLiveComboTest`) allowing administrators to execute real upstream health checks that bypass all local circuit-breaker and cooldown state mechanisms, enabling precise diagnostics during rolling outages (PR #759) -- **Quality Gates** — Added automated response quality validation for combos and officially integrated `claude-4.6` model support into the core routing schemas (PR #762) +- **Combo Diagnostics** — 引入了实时测试绕过标志(`forceLiveComboTest`),允许管理员执行真实的上游健康检查,绕过所有本地断路器和冷却状态机制,在滚动中断期间实现精确诊断(PR #759) +- **Quality Gates** — 添加了组合的自动响应质量验证,并正式将 `claude-4.6` 模型支持集成到核心路由架构中(PR #762) -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Tool Definition Validation** — Repaired Gemini API integration by normalizing enum types inside tool definitions, preventing upstream HTTP 400 parameter errors (PR #760) +- **Tool Definition Validation** — 通过标准化工具定义中的枚举类型修复了 Gemini API 集成,防止上游 HTTP 400 参数错误(PR #760) --- ## [3.2.8] - 2026-03-29 -### ✨ Enhancements & Refactoring +### ✨ 增强与重构 -- **Docker Auto-Update UI** — Integrated a detached background update process for Docker Compose deployments. The Dashboard UI now seamlessly tracks update lifecycle events combining JSON REST responses with SSE streaming progress overlays for robust cross-environment reliability. -- **Cache Analytics** — Repaired zero-metrics visualization mapping by migrating Semantic Cache telemetry logs directly into the centralized tracking SQLite module. +- **Docker Auto-Update UI** — 集成了后台独立更新进程,用于 Docker Compose 部署。Dashboard UI 现在可以无缝跟踪更新生命周期事件,结合 JSON REST 响应和 SSE 流式传输进度覆盖层,实现强大的跨环境可靠性。 +- **Cache Analytics** — 修复了零指标可视化映射问题,将 Semantic Cache 遥测日志直接迁移到集中追踪 SQLite 模块中。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Authentication Logic** — Fixed a bug where saving dashboard settings or adding models failed with a 401 Unauthorized error when `requireLogin` was disabled. API endpoints now correctly evaluate the global authentication toggle. Resolved global redirection by reactivating `src/middleware.ts`. -- **CLI Tool Detection (Windows)** — Prevented fatal initialization exceptions during CLI environment detection by catching `cross-spawn` ENOENT errors correctly. Adds explicit detection paths for `\AppData\Local\droid\droid.exe`. -- **Codex Native Passthrough** — Normalized model translation parameters preventing context poisoning in proxy pass-through mode, enforcing generic `store: false` constraints explicitly for all Codex-originated requests. -- **SSE Token Reporting** — Normalized provider tool-call chunk `finish_reason` detection, fixing 0% Usage analytics for stream-only responses missing strict `` indicators. -- **DeepSeek Tags** — Implemented an explicit `` extraction mapping inside `responsesHandler.ts`, ensuring DeepSeek reasoning streams map equivalently to native Anthropic `` structures. +- **Authentication Logic** — 修复了在禁用 `requireLogin` 时保存仪表板设置或添加模型失败并返回 401 Unauthorized 错误的问题。API 端点现在正确评估全局认证开关。通过重新激活 `src/middleware.ts` 解决了全局重定向问题。 +- **CLI Tool Detection (Windows)** — 通过正确捕获 `cross-spawn` ENOENT 错误,防止 CLI 环境检测期间的致命初始化异常。添加了 `\AppData\Local\droid\droid.exe` 的显式检测路径。 +- **Codex Native Passthrough** — 规范化模型翻译参数以防止代理透传模式下的上下文污染,对所有 Codex 发起的请求显式强制执行通用的 `store: false` 约束。 +- **SSE Token Reporting** — 规范化服务商工具调用块的 `finish_reason` 检测,修复了缺少严格 `` 指示符的纯流式响应导致使用率分析为 0% 的问题。 +- **DeepSeek Tags** — 在 `responsesHandler.ts` 中实现了显式的 `` 提取映射,确保 DeepSeek 推理流能等价映射到原生 Anthropic `` 结构。 --- ## [3.2.7] - 2026-03-29 -### Fixed +### 修复 -- **Seamless UI Updates**: The "Update Now" feature on the Dashboard now provides live, transparent feedback using Server-Sent Events (SSE). It performs package installation, native module rebuilds (better-sqlite3), and PM2 restarts reliably while showing real-time loaders instead of silently hanging. +- **Seamless UI Updates**:Dashboard 上的"立即更新"功能现在使用 Server-Sent Events (SSE) 提供实时透明反馈。它可靠地执行包安装、原生模块重建(better-sqlite3)和 PM2 重启,同时显示实时加载器而不是静默挂起。 --- ## [3.2.6] — 2026-03-29 -### ✨ Enhancements & Refactoring +### ✨ 增强与重构 -- **API Key Reveal (#740)** — Added a scoped API key copy flow in the Api Manager, protected by the `ALLOW_API_KEY_REVEAL` environment variable. -- **Sidebar Visibility Controls (#739)** — Admins can now hide any sidebar navigation link via the Appearance settings to reduce visual clutter. -- **Strict Combo Testing (#735)** — Hardened the combo health check endpoint to require live text responses from models instead of just soft reachability signals. -- **Streamed Detailed Logs (#734)** — Switched detailed request logging for SSE streams to reconstruct the final payload, saving immense amounts of SQLite database size and significantly cleaning up the UI. +- **API Key Reveal (#740)** — 在 API Manager 中添加了范围限定的 API 密钥复制流程,受 `ALLOW_API_KEY_REVEAL` 环境变量保护。 +- **Sidebar Visibility Controls (#739)** — 管理员现在可以通过外观设置隐藏任何侧边栏导航链接,以减少视觉杂乱。 +- **Strict Combo Testing (#735)** — 加固了 combo 健康检查端点,要求模型返回实时文本响应,而不仅仅是软可达性信号。 +- **Streamed Detailed Logs (#734)** — 将 SSE 流的详细请求日志切换为重建最终负载,节省了大量 SQLite 数据库空间并显著清理了 UI。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **OpenCode Go MiniMax Auth (#733)** — Corrected the authentication header logic for `minimax` models on OpenCode Go to use `x-api-key` instead of standard bearer tokens across the `/messages` protocol. +- **OpenCode Go MiniMax Auth (#733)** — 修正了 OpenCode Go 中 `minimax` 模型的认证头逻辑,在 `/messages` 协议中使用 `x-api-key` 而不是标准 bearer token。 --- ## [3.2.5] — 2026-03-29 -### ✨ Enhancements & Refactoring +### ✨ 增强与重构 -- **Void Linux Deployment Support (#732)** — Integrated `xbps-src` packaging template and instructions to natively compile and install OmniRoute with `better-sqlite3` bindings via cross-compilation target. +- **Void Linux Deployment Support (#732)** — 集成了 `xbps-src` 打包模板和说明,通过交叉编译目标原生编译和安装带有 `better-sqlite3` 绑定的 OmniRoute。 ## [3.2.4] — 2026-03-29 -### ✨ Enhancements & Refactoring +### ✨ 增强与重构 -- **Qoder AI Migration (#660)** — Completely migrated the legacy `iFlow` core provider onto `Qoder AI` maintaining stable API routing capabilities. +- **Qoder AI Migration (#660)** — 完全将传统的 `iFlow` 核心服务商迁移到 `Qoder AI`,保持稳定的 API 路由能力。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Gemini Tools HTTP 400 Payload Invalid Argument (#731)** — Prevented `thoughtSignature` array injections inside standard Gemini `functionCall` sequences blocking agentic routing flows. +- **Gemini Tools HTTP 400 Payload Invalid Argument (#731)** — 阻止标准 Gemini `functionCall` 序列中注入 `thoughtSignature` 数组,从而避免 agentic routing 流程被阻塞。 --- ## [3.2.3] — 2026-03-29 -### ✨ Enhancements & Refactoring +### ✨ 增强与重构 -- **Provider Limits Quota UI (#728)** — Normalized quota limit logic and data labeling inside the Limits interface. +- **Provider Limits Quota UI (#728)** — 统一了 Limits 界面中的配额限制逻辑和数据标注。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Core Routing Schemas & Leaks** — Expanded `comboStrategySchema` to natively support `fill-first` and `p2c` strategies to unblock complex combo editing natively. -- **Thinking Tags Extraction (CLI)** — Restructured CLI token responses sanitizer RegEx capturing model reasoning structures inside streams avoiding broken `` extractions breaking response text output format. -- **Strict Format Enforcements** — Hardened pipeline sanitization execution making it universally apply to translation mode targets. +- **Core Routing Schemas & Leaks** — 扩展了 `comboStrategySchema`,原生支持 `fill-first` 和 `p2c` 策略,解除复杂 combo 编辑的阻塞。 +- **Thinking Tags Extraction (CLI)** — 重构了 CLI token 响应清理的正则逻辑,可在流中正确捕获模型推理结构,避免损坏的 `` 提取影响响应文本输出格式。 +- **Strict Format Enforcements** — 强化了流水线清理执行逻辑,使其能够统一应用到 translation mode 的目标格式上。 --- ## [3.2.2] — 2026-03-29 -### ✨ New Features +### ✨ 新特性 -- **Four-Stage Request Log Pipeline (#705)** — Refactored log persistence to save comprehensive payloads at four distinct pipeline stages: Client Request, Translated Provider Request, Provider Response, and Translated Client Response. Introduced `streamPayloadCollector` for robust SSE stream truncation and payload serialization. +- **Four-Stage Request Log Pipeline (#705)** — 重构了日志持久化逻辑,可在四个不同流水线阶段保存完整负载:Client Request、Translated Provider Request、Provider Response 和 Translated Client Response。同时引入了 `streamPayloadCollector`,用于更稳健的 SSE 流截断和负载序列化。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Mobile UI Fixes (#659)** — Prevented table components on the dashboard from breaking the layout on narrow viewports by adding proper horizontal scrolling and overflow containment to `DashboardLayout`. -- **Claude Prompt Cache Fixes (#708)** — Ensured `cache_control` blocks in Claude-to-Claude fallback loops are faithfully preserved and passed safely back to Anthropic models. -- **Gemini Tool Definitions (#725)** — Fixed schema translation errors when declaring simple `object` parameter types for Gemini function calling. +- **Mobile UI Fixes (#659)** — 通过为 `DashboardLayout` 添加正确的水平滚动和溢出约束,避免 dashboard 中的表格组件在窄视口下破坏布局。 +- **Claude Prompt Cache Fixes (#708)** — 确保 Claude-to-Claude 回退循环中的 `cache_control` 块被完整保留,并安全地传回 Anthropic 模型。 +- **Gemini Tool Definitions (#725)** — 修复 Gemini function calling 在声明简单 `object` 参数类型时出现的 schema 翻译错误。 ## [3.2.1] — 2026-03-29 -### ✨ New Features +### ✨ 新特性 -- **Global Fallback Provider (#689)** — When all combo models are exhausted (502/503), OmniRoute now attempts a configurable global fallback model before returning the error. Set `globalFallbackModel` in settings to enable. +- **Global Fallback Provider (#689)** — 当所有 combo 模型都已耗尽(502/503)时,OmniRoute 现在会在返回错误之前尝试一个可配置的全局回退模型。可在 settings 中设置 `globalFallbackModel` 以启用此功能。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Fix #721** — Fixed context pinning bypass during tool-call responses. Non-streaming tagging used wrong JSON path (`json.messages` → `json.choices[0].message`). Streaming injection now triggers on `finish_reason` chunks for tool-call-only streams. `injectModelTag()` now appends synthetic pin messages for non-string content. -- **Fix #709** — Confirmed already fixed (v3.1.9) — `system-info.mjs` creates directories recursively. Closed. -- **Fix #707** — Confirmed already fixed (v3.1.9) — empty tool name sanitization in `chatCore.ts`. Closed. +- **Fix #721** — 修复 tool-call 响应期间绕过 context pinning 的问题。非流式标记使用了错误的 JSON 路径(`json.messages` → `json.choices[0].message`)。流式注入现在会在仅包含 tool-call 的流中的 `finish_reason` chunk 上触发。`injectModelTag()` 现在也会为非字符串内容追加合成的 pin 消息。 +- **Fix #709** — 确认已在 v3.1.9 中修复:`system-info.mjs` 现在会递归创建目录。问题已关闭。 +- **Fix #707** — 确认已在 v3.1.9 中修复:`chatCore.ts` 中的空工具名清理。问题已关闭。 -### 🧪 Tests +### 🧪 测试 -- Added 6 unit tests for context pinning with tool-call responses (null content, array content, roundtrip, re-injection) +- 添加了 6 个 unit tests,用于覆盖带 tool-call 响应的 context pinning 场景(null content、array content、roundtrip、re-injection)。 ## [3.2.0] — 2026-03-28 -### ✨ New Features +### ✨ 新特性 -- **Cache Management UI** — Added a dedicated semantic caching dashboard at \`/dashboard/cache\` with targeted API invalidation and 31-language i18n support (PR #701 by @oyi77) -- **GLM Quota Tracking** — Added real-time usage and session quota tracking for the GLM Coding (Z.AI) provider (PR #698 by @christopher-s) -- **Detailed Log Payloads** — Wired full four-stage pipeline payload capturing (original, translated, provider-response, streamed-deltas) directly into the UI (PR #705 by @rdself) +- **Cache Management UI** — 在 `/dashboard/cache` 新增专用的 semantic cache dashboard,支持定向 API 失效和 31 种语言的 i18n(PR #701 by @oyi77)。 +- **GLM Quota Tracking** — 为 GLM Coding(Z.AI)提供商新增实时 usage 和 session 配额跟踪(PR #698 by @christopher-s)。 +- **Detailed Log Payloads** — 将完整的四阶段流水线负载捕获(original、translated、provider-response、streamed-deltas)直接接入 UI(PR #705 by @rdself)。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Fix #708** — Prevented token bleeding for Claude Code users routing through OmniRoute by correctly preserving native \`cache_control\` headers during Claude-to-Claude passthrough (PR #708 by @tombii) -- **Fix #719** — Setup internal auth boundaries for \`ModelSyncScheduler\` to prevent unauthenticated daemon failures on startup (PR #719 by @rdself) -- **Fix #718** — Rebuilt badge rendering in Provider Limits UI preventing bad quota boundaries overlap (PR #718 by @rdself) -- **Fix #704** — Fixed Combo Fallbacks breaking on HTTP 400 content-policy errors preventing model-rotation dead-routing (PR #704 by @rdself) +- **Fix #708** — 在 Claude-to-Claude passthrough 过程中正确保留原生 `cache_control` 头,防止通过 OmniRoute 路由的 Claude Code 用户发生 token 泄漏(PR #708 by @tombii)。 +- **Fix #719** — 为 `ModelSyncScheduler` 建立内部认证边界,防止未认证守护进程在启动时失败(PR #719 by @rdself)。 +- **Fix #718** — 重建 Provider Limits UI 中的 badge 渲染,避免错误的配额边界重叠(PR #718 by @rdself)。 +- **Fix #704** — 修复 Combo Fallbacks 在 HTTP 400 content-policy 错误下失效、导致模型轮转路由卡死的问题(PR #704 by @rdself)。 -### 🔒 Security & Dependencies +### 🔒 安全与依赖 -- Bumped \`path-to-regexp\` to \`8.4.0\` resolving dependabot vulnerabilities (PR #715) +- 将 `path-to-regexp` 升级到 `8.4.0`,以修复 dependabot 报告的漏洞(PR #715)。 ## [3.1.10] — 2026-03-28 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Fix #706** — Fixed icon fallback rendering caused by Tailwind V4 `font-sans` override by applying `!important` to `.material-symbols-outlined`. -- **Fix #703** — Fixed GitHub Copilot broken streams by enabling `responses` to `openai` format translation for any custom models leveraging `apiFormat: "responses"`. -- **Fix #702** — Replaced flat-rate usage tracking with accurate DB pricing calculations for both streaming and non-streaming responses. -- **Fix #716** — Cleaned up Claude tool-call translation state, correctly parsing streaming arguments and preventing OpenAI `tool_calls` chunks from repeating the `id` field. +- **Fix #706** — 通过对 `.material-symbols-outlined` 应用 `!important`,修复了由 Tailwind V4 `font-sans` 覆盖导致的图标回退渲染问题。 +- **Fix #703** — 通过为任何使用 `apiFormat: "responses"` 的自定义模型启用 `responses` → `openai` 格式翻译,修复 GitHub Copilot 流损坏的问题。 +- **Fix #702** — 用准确的数据库定价计算替换 flat-rate usage 跟踪,适用于流式和非流式响应。 +- **Fix #716** — 清理 Claude tool-call 翻译状态,正确解析流式参数,并防止 OpenAI `tool_calls` chunk 重复 `id` 字段。 ## [3.1.9] — 2026-03-28 -### ✨ New Features +### ✨ 新特性 -- **Schema Coercion** — Auto-coerce string-encoded numeric JSON Schema constraints (e.g. `"minimum": "1"`) to proper types, preventing 400 errors from Cursor, Cline, and other clients sending malformed tool schemas. -- **Tool Description Sanitization** — Ensure tool descriptions are always strings; converts `null`, `undefined`, or numeric descriptions to empty strings before sending to providers. -- **Clear All Models Button** — Added i18n translations for the "Clear All Models" provider action across all 30 languages. -- **Codex Auth Export** — Added Codex `auth.json` export and apply-local buttons for seamless CLI integration. -- **Windsurf BYOK Notes** — Added official limitation warnings to the Windsurf CLI tool card documenting BYOK constraints. +- **Schema Coercion** — 自动将字符串编码的数字型 JSON Schema 约束(例如 `"minimum": "1"`)强制转换为正确类型,防止 Cursor、Cline 等客户端发送畸形工具 schema 时触发 400 错误。 +- **Tool Description Sanitization** — 确保工具描述始终为字符串;在发送给提供商之前,会把 `null`、`undefined` 或数字型描述转换为空字符串。 +- **Clear All Models Button** — 为 “Clear All Models” 提供商操作补齐全部 30 种语言的 i18n 翻译。 +- **Codex Auth Export** — 新增 Codex `auth.json` 导出和 apply-local 按钮,以实现无缝 CLI 集成。 +- **Windsurf BYOK Notes** — 在 Windsurf CLI 工具卡片中补充官方限制说明,记录 BYOK 约束。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Fix #709** — `system-info.mjs` no longer crashes when the output directory doesn't exist (added `mkdirSync` with recursive flag). -- **Fix #710** — A2A `TaskManager` singleton now uses `globalThis` to prevent state leakage across Next.js API route recompilations in dev mode. E2E test suite updated to handle 401 gracefully. -- **Fix #711** — Added provider-specific `max_tokens` cap enforcement for upstream requests. -- **Fix #605 / #592** — Strip `proxy_` prefix from tool names in non-streaming Claude responses; fixed LongCat validation URL. -- **Call Logs Max Cap** — Upgraded `getMaxCallLogs()` with caching layer, env var support (`CALL_LOGS_MAX`), and DB settings integration. +- **Fix #709** — `system-info.mjs` 在输出目录不存在时不再崩溃(新增带 recursive 标志的 `mkdirSync`)。 +- **Fix #710** — A2A `TaskManager` 单例现在使用 `globalThis`,以防止开发模式下 Next.js API 路由重新编译时发生状态泄漏。E2E 测试套件也已更新,可优雅处理 401。 +- **Fix #711** — 为上游请求新增提供商级别的 `max_tokens` 上限强制限制。 +- **Fix #605 / #592** — 在非流式 Claude 响应中去除工具名称的 `proxy_` 前缀;同时修复 LongCat 验证 URL。 +- **Call Logs Max Cap** — 升级 `getMaxCallLogs()`,增加缓存层、环境变量支持(`CALL_LOGS_MAX`)以及数据库设置集成。 -### 🧪 Tests +### 🧪 测试 -- Test suite expanded from 964 → 1027 tests (63 new tests) -- Added `schema-coercion.test.mjs` — 9 tests for numeric field coercion and tool description sanitization -- Added `t40-opencode-cli-tools-integration.test.mjs` — OpenCode/Windsurf CLI integration tests -- Enhanced feature-tests branch with comprehensive coverage tooling +- 测试套件从 964 扩展到 1027 个测试(新增 63 个)。 +- 添加了 `schema-coercion.test.mjs` —— 9 个测试,用于验证数字字段强制转换和工具描述清理。 +- 添加了 `t40-opencode-cli-tools-integration.test.mjs` —— OpenCode/Windsurf CLI 集成测试。 +- 使用全面的覆盖率工具增强了 feature-tests 分支。 -### 📁 New Files +### 📁 新增文件 -| File | Purpose | -| -------------------------------------------------------- | ----------------------------------------------------------- | -| `open-sse/translator/helpers/schemaCoercion.ts` | Schema coercion and tool description sanitization utilities | -| `tests/unit/schema-coercion.test.mjs` | Unit tests for schema coercion | -| `tests/unit/t40-opencode-cli-tools-integration.test.mjs` | CLI tool integration tests | -| `COVERAGE_PLAN.md` | Test coverage planning document | +| 文件 | 目的 | +| -------------------------------------------------------- | ----------------------------------------------------- | +| `open-sse/translator/helpers/schemaCoercion.ts` | Schema coercion 和 tool description sanitization 工具 | +| `tests/unit/schema-coercion.test.mjs` | 用于 schema coercion 的单元测试 | +| `tests/unit/t40-opencode-cli-tools-integration.test.mjs` | CLI 工具集成测试 | +| `COVERAGE_PLAN.md` | 测试覆盖率规划文档 | -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Claude Prompt Caching Passthrough** — Fixed cache_control markers being stripped in Claude passthrough mode (Claude → OmniRoute → Claude), which caused Claude Code users to deplete their Anthropic API quota 5-10x faster than direct connections. OmniRoute now preserves client's cache_control markers when sourceFormat and targetFormat are both Claude, ensuring prompt caching works correctly and dramatically reducing token consumption. +- **Claude Prompt Caching Passthrough** — 修复了 Claude passthrough 模式(Claude → OmniRoute → Claude)下 `cache_control` 标记被移除的问题;此前这会导致 Claude Code 用户比直连更快地耗尽 Anthropic API 配额,速度高出 5-10 倍。现在,当 `sourceFormat` 和 `targetFormat` 都是 Claude 时,OmniRoute 会保留客户端的 `cache_control` 标记,确保 prompt caching 正常工作,并显著降低 token 消耗。 ## [3.1.8] - 2026-03-27 -### 🐛 Bug Fixes & Features +### 🐛 Bug 修复与新特性 -- **Platform Core:** Implemented global state handling for Hidden Models & Combos preventing them from cluttering the catalog or leaking into connected MCP agents (#681). -- **Stability:** Patched streaming crashes related to the native Antigravity provider integration failing due to unhandled undefined state arrays (#684). -- **Localization Sync:** Deployed a fully overhauled `i18n` synchronizer detecting missing nested JSON properties and retro-fitting 30 locales sequentially (#685).## [3.1.7] - 2026-03-27 +- **Platform Core:** 为 Hidden Models 和 Combos 实现全局状态处理,防止它们污染目录或泄漏到已连接的 MCP agents 中(#681)。 +- **Stability:** 修补了与原生 Antigravity 提供商集成相关的流式崩溃问题,其根因是未处理的 undefined 状态数组(#684)。 +- **Localization Sync:** 部署了全新重构的 `i18n` 同步器,可检测缺失的嵌套 JSON 属性,并按顺序为 30 个 locale 回填内容(#685)。 -### 🐛 Bug Fixes +## [3.1.7] - 2026-03-27 -- **Streaming Stability:** Fixed `hasValuableContent` returning `undefined` for empty chunks in SSE streams (#676). -- **Tool Calling:** Fixed an issue in `sseParser.ts` where non-streaming Claude responses with multiple tool calls dropped the `id` of subsequent tool calls due to incorrect index-based deduplication (#671). +### 🐛 Bug 修复 + +- **Streaming Stability:** 修复了 `hasValuableContent` 在 SSE 流中的空 chunk 上返回 `undefined` 的问题(#676)。 +- **Tool Calling:** 修复 `sseParser.ts` 中的一个问题:非流式 Claude 响应在包含多个工具调用时,会因错误的基于索引去重而丢失后续工具调用的 `id`(#671)。 --- ## [3.1.6] — 2026-03-27 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Claude Native Tool Name Restoration** — Tool names like `TodoWrite` are no longer prefixed with `proxy_` in Claude passthrough responses (both streaming and non-streaming). Includes unit test coverage (PR #663 by @coobabm) -- **Clear All Models Alias Cleanup** — "Clear All Models" button now also removes associated model aliases, preventing ghost models in the UI (PR #664 by @rdself) +- **Claude Native Tool Name Restoration** — 像 `TodoWrite` 这样的工具名称在 Claude passthrough 响应中不再被加上 `proxy_` 前缀(适用于流式和非流式)。包含对应的单元测试覆盖(PR #663 by @coobabm)。 +- **Clear All Models Alias Cleanup** — “Clear All Models” 按钮现在也会移除关联的模型 alias,防止 UI 中出现幽灵模型(PR #664 by @rdself)。 --- ## [3.1.5] — 2026-03-27 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Backoff Auto-Decay** — Rate-limited accounts now auto-recover when their cooldown window expires, fixing a deadlock where high `backoffLevel` permanently deprioritized accounts (PR #657 by @brendandebeasi) +- **Backoff Auto-Decay** — 当冷却窗口到期时,受速率限制的账户现在会自动恢复,修复了高 `backoffLevel` 会永久降低账户优先级的死锁问题(PR #657 by @brendandebeasi)。 ### 🌍 i18n -- **Chinese translation overhaul** — Comprehensive rewrite of `zh-CN.json` with improved accuracy (PR #658 by @only4copilot) +- **Chinese translation overhaul** — 对 `zh-CN.json` 进行了全面重写,提高了翻译准确性(PR #658 by @only4copilot)。 --- ## [3.1.4] — 2026-03-27 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Streaming Override Fix** — Explicit `stream: true` in request body now takes priority over `Accept: application/json` header. Clients sending both will correctly receive SSE streaming responses (#656) +- **Streaming Override Fix** — 请求体中的显式 `stream: true` 现在优先于 `Accept: application/json` 请求头。两者同时发送时,客户端将正确收到 SSE 流式响应(#656)。 ### 🌍 i18n -- **Czech string improvements** — Refined terminology across `cs.json` (PR #655 by @zen0bit) +- **Czech string improvements** — 精炼了 `cs.json` 中的术语用法(PR #655 by @zen0bit)。 --- @@ -373,20 +429,20 @@ ### 🌍 i18n & Community -- **~70 missing translation keys** added to `en.json` and 12 languages (PR #652 by @zen0bit) -- **Czech documentation updated** — CLI-TOOLS, API_REFERENCE, VM_DEPLOYMENT guides (PR #652) -- **Translation validation scripts** — `check_translations.py` and `validate_translation.py` for CI/QA (PR #651 by @zen0bit) +- **~70 missing translation keys** — 向 `en.json` 和 12 种语言中补充了约 70 个缺失的翻译键(PR #652 by @zen0bit)。 +- **Czech documentation updated** — 更新了 CLI-TOOLS、API_REFERENCE、VM_DEPLOYMENT 指南的捷克语文档(PR #652)。 +- **Translation 验证 scripts** — 新增 `check_translations.py` 和 `validate_translation.py`,用于 CI/QA(PR #651 by @zen0bit)。 --- ## [3.1.2] — 2026-03-26 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Critical: Tool Calling Regression** — Fixed `proxy_Bash` errors by disabling the `proxy_` tool name prefix in the Claude passthrough path. Tools like `Bash`, `Read`, `Write` were being renamed to `proxy_Bash`, `proxy_Read`, etc., causing Claude to reject them (#618) -- **Kiro Account Ban Documentation** — Documented as upstream AWS anti-fraud false positive, not an OmniRoute issue (#649) +- **Critical: Tool Calling Regression** — 通过在 Claude passthrough 路径中禁用 `proxy_` 工具名前缀,修复了 `proxy_Bash` 错误。此前 `Bash`、`Read`、`Write` 等工具会被重命名为 `proxy_Bash`、`proxy_Read` 等,导致 Claude 拒绝这些工具(#618)。 +- **Kiro Account Ban Documentation** — 将其记录为上游 AWS 反欺诈误判,而不是 OmniRoute 本身的问题(#649)。 -### 🧪 Tests +### 🧪 测试 - **936 tests, 0 failures** @@ -394,17 +450,17 @@ ## [3.1.1] — 2026-03-26 -### ✨ New Features +### ✨ 新特性 -- **Vision Capability Metadata**: Added `capabilities.vision`, `input_modalities`, and `output_modalities` to `/v1/models` entries for vision-capable models (PR #646) -- **Gemini 3.1 Models**: Added `gemini-3.1-pro-preview` and `gemini-3.1-flash-lite-preview` to the Antigravity provider (#645) +- **Vision Capability Metadata**:为支持视觉的模型,在 `/v1/models` 条目中新增 `capabilities.vision`、`input_modalities` 和 `output_modalities`(PR #646)。 +- **Gemini 3.1 Models**:为 Antigravity 提供商新增 `gemini-3.1-pro-preview` 和 `gemini-3.1-flash-lite-preview`(#645)。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Ollama Cloud 401 Error**: Fixed incorrect API base URL — changed from `api.ollama.com` to official `ollama.com/v1/chat/completions` (#643) -- **Expired Token Retry**: Added bounded retry with exponential backoff (5→10→20 min) for expired OAuth connections instead of permanently skipping them (PR #647) +- **Ollama Cloud 401 Error**:修复错误的 API base URL —— 已从 `api.ollama.com` 改为官方 `ollama.com/v1/chat/completions`(#643)。 +- **Expired Token Retry**:为过期的 OAuth 连接新增带指数退避(5→10→20 分钟)的有界重试,而不是永久跳过它们(PR #647)。 -### 🧪 Tests +### 🧪 测试 - **936 tests, 0 failures** @@ -412,20 +468,20 @@ ## [3.1.0] — 2026-03-26 -### ✨ New Features +### ✨ 新特性 -- **GitHub Issue Templates**: Added standardized bug report, feature request, and config/proxy issue templates (#641) -- **Clear All Models**: Added a "Clear All Models" button to the provider detail page with i18n support in 29 languages (#634) +- **GitHub Issue Templates**:新增标准化的 bug report、feature request 和 config/proxy issue 模板(#641)。 +- **Clear All Models**:在提供商详情页新增 “Clear All Models” 按钮,并为 29 种语言提供 i18n 支持(#634)。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Locale Conflict (`in.json`)**: Renamed the Hindi locale file from `in.json` (Indonesian ISO code) to `hi.json` to fix translation conflicts in Weblate (#642) -- **Codex Empty Tool Names**: Moved tool name sanitization before the native Codex passthrough, fixing 400 errors from upstream providers when tools had empty names (#637) -- **Streaming Newline Artifacts**: Added `collapseExcessiveNewlines` to the response sanitizer, collapsing runs of 3+ consecutive newlines from thinking models into a standard double newline (#638) -- **Claude Reasoning Effort**: Converted OpenAI `reasoning_effort` param to Claude's native `thinking` budget block across all request paths, including automatic `max_tokens` adjustment (#627) -- **Qwen Token Refresh**: Implemented proactive pre-expiry OAuth token refreshes (5-minute buffer) to prevent requests from failing when using short-lived tokens (#631) +- **Locale Conflict (`in.json`)**:将印地语 locale 文件从 `in.json`(实际是印尼语 ISO code)重命名为 `hi.json`,以修复 Weblate 中的翻译冲突(#642)。 +- **Codex Empty Tool Names**:将工具名清理逻辑提前到原生 Codex passthrough 之前,修复当工具名为空时上游提供商返回 400 错误的问题(#637)。 +- **Streaming Newline Artifacts**:在响应清理器中新增 `collapseExcessiveNewlines`,把 thinking 模型产生的连续 3 个及以上换行折叠为标准双换行(#638)。 +- **Claude Reasoning Effort**:将 OpenAI 的 `reasoning_effort` 参数转换为 Claude 原生的 `thinking` budget block,并在所有请求路径中自动调整 `max_tokens`(#627)。 +- **Qwen Token Refresh**:实现了过期前主动刷新 OAuth token(5 分钟缓冲),防止使用短生命周期 token 时请求失败(#631)。 -### 🧪 Tests +### 🧪 测试 - **936 tests, 0 failures** (+10 tests since 3.0.9) @@ -433,452 +489,452 @@ ## [3.0.9] — 2026-03-26 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **NaN tokens in Claude Code / client responses (#617):** - - `sanitizeUsage()` now cross-maps `input_tokens`→`prompt_tokens` and `output_tokens`→`completion_tokens` before the whitelist filter, fixing responses showing NaN/0 token counts when providers return Claude-style usage field names +- **Claude Code / 客户端响应中的 NaN tokens(#617):** + - `sanitizeUsage()` 现在会在白名单过滤之前交叉映射 `input_tokens`→`prompt_tokens` 和 `output_tokens`→`completion_tokens`,修复当提供商返回 Claude 风格 usage 字段时,响应中 token 计数显示为 NaN/0 的问题。 -### 安全 +### 🔒 安全 -- Updated `yaml` package to fix stack overflow vulnerability (GHSA-48c2-rrv3-qjmp) +- 更新 `yaml` 包以修复栈溢出漏洞(GHSA-48c2-rrv3-qjmp)。 -### 📋 Issue Triage +### 📋 Issue 分流 -- Closed #613 (Codestral — resolved with Custom Provider workaround) -- Commented on #615 (OpenCode dual-endpoint — workaround provided, tracked as feature request) -- Commented on #618 (tool call visibility — requesting v3.0.9 test) -- Commented on #627 (effort level — already supported) +- 关闭 #613(Codestral —— 已通过 Custom Provider workaround 解决) +- 在 #615 中回复(OpenCode dual-endpoint —— 已提供 workaround,并作为 feature request 跟踪) +- 在 #618 中回复(tool call visibility —— 请求用户测试 v3.0.9) +- 在 #627 中回复(effort level —— 已经支持) --- ## [3.0.8] — 2026-03-25 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Translation Failures for OpenAI-format Providers in Claude CLI (#632):** - - Handle `reasoning_details[]` array format from StepFun/OpenRouter — converts to `reasoning_content` - - Handle `reasoning` field alias from some providers → normalized to `reasoning_content` - - Cross-map usage field names: `input_tokens`↔`prompt_tokens`, `output_tokens`↔`completion_tokens` in `filterUsageForFormat` - - Fix `extractUsage` to accept both `input_tokens`/`output_tokens` and `prompt_tokens`/`completion_tokens` as valid usage fields - - Applied to both streaming (`sanitizeStreamingChunk`, `openai-to-claude.ts` translator) and non-streaming (`sanitizeMessage`) paths +- **Claude CLI 中 OpenAI-format Providers 的翻译失败(#632):** + - 处理来自 StepFun/OpenRouter 的 `reasoning_details[]` 数组格式,并转换为 `reasoning_content` + - 处理某些提供商返回的 `reasoning` 字段别名,并规范化为 `reasoning_content` + - 在 `filterUsageForFormat` 中交叉映射 usage 字段名:`input_tokens`↔`prompt_tokens`、`output_tokens`↔`completion_tokens` + - 修复 `extractUsage`,使其同时接受 `input_tokens`/`output_tokens` 和 `prompt_tokens`/`completion_tokens` 作为合法 usage 字段 + - 同时应用于流式路径(`sanitizeStreamingChunk`、`openai-to-claude.ts` translator)和非流式路径(`sanitizeMessage`) --- ## [3.0.7] — 2026-03-25 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Antigravity Token Refresh:** Fixed `client_secret is missing` error for npm-installed users — the `clientSecretDefault` was empty in providerRegistry, causing Google to reject token refresh requests (#588) -- **OpenCode Zen Models:** Added `modelsUrl` to the OpenCode Zen registry entry so "Import from /models" works correctly (#612) -- **Streaming Artifacts:** Fixed excessive newlines left in responses after thinking-tag signature stripping (#626) -- **Proxy Fallback:** Added automatic retry without proxy when SOCKS5 relay fails -- **Proxy Test:** Test endpoint now resolves real credentials from DB via proxyId +- **Antigravity Token Refresh:** 修复了 npm 安装用户遇到的 `client_secret is missing` 错误;此前 `providerRegistry` 中的 `clientSecretDefault` 为空,导致 Google 拒绝 token 刷新请求(#588)。 +- **OpenCode Zen Models:** 为 OpenCode Zen 的 registry 条目新增 `modelsUrl`,使 “Import from /models” 能正确工作(#612)。 +- **Streaming Artifacts:** 修复了移除 thinking-tag 签名后响应中残留过多换行的问题(#626)。 +- **Proxy Fallback:** 当 SOCKS5 relay 失败时,新增自动重试且不走代理的回退逻辑。 +- **Proxy Test:** Test 端点现在会通过 `proxyId` 从数据库中解析真实凭证。 -### ✨ New Features +### ✨ 新特性 -- **Playground Account/Key Selector:** Persistent, always-visible dropdown to select specific provider accounts/keys for testing — fetches all connections at startup and filters by selected provider -- **CLI Tools Dynamic Models:** Model selection now dynamically fetches from `/v1/models` API — providers like Kiro now show their full model catalog -- **Antigravity Model List:** Updated with Claude Sonnet 4.5, Claude Sonnet 4, GPT 5, GPT 5 Mini; enabled `passthroughModels` for dynamic model access (#628) +- **Playground Account/Key Selector:** 新增一个常驻且始终可见的下拉框,可在测试时选择特定的提供商账户/密钥;启动时会抓取所有连接,并按所选提供商过滤。 +- **CLI Tools Dynamic Models:** 模型选择现在会动态从 `/v1/models` API 获取;像 Kiro 这样的提供商会显示完整模型目录。 +- **Antigravity Model List:** 更新为包含 Claude Sonnet 4.5、Claude Sonnet 4、GPT 5、GPT 5 Mini;并启用 `passthroughModels` 以支持动态模型访问(#628)。 -### 🔧 Maintenance +### 🔧 维护 -- Merged PR #625 — Provider Limits light mode background fix +- 合并 PR #625 —— 修复 Provider Limits 在浅色模式下的背景问题 --- ## [3.0.6] — 2026-03-25 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Limits/Proxy:** Fixed Codex limit fetching for accounts behind SOCKS5 proxies — token refresh now runs inside proxy context -- **CI:** Fixed integration test `v1/models` assertion failure in CI environments without provider connections -- **Settings:** Proxy test button now shows success/failure results immediately (previously hidden behind health data) +- **Limits/Proxy:** 修复了位于 SOCKS5 代理后的账户无法获取 Codex 限额的问题;token 刷新现在会在代理上下文中运行。 +- **CI:** 修复在没有提供商连接的 CI 环境中,集成测试 `v1/models` 的断言失败问题。 +- **Settings:** Proxy test 按钮现在会立即显示成功/失败结果,不再隐藏在健康数据之后。 -### ✨ New Features +### ✨ 新特性 -- **Playground:** Added Account selector dropdown — test specific connections individually when a provider has multiple accounts +- **Playground:** 新增 Account selector 下拉框;当某个提供商有多个账户时,可分别测试特定连接。 -### 🔧 Maintenance +### 🔧 维护 -- Merged PR #623 — LongCat API base URL path correction +- 合并 PR #623 —— 修正 LongCat API base URL 路径 --- ## [3.0.5] — 2026-03-25 -### ✨ New Features +### ✨ 新特性 -- **Limits UI:** Added tag grouping feature to the connections dashboard to improve visual organization for accounts with custom tags. +- **Limits UI:** 在 connections dashboard 中新增标签分组功能,以改善带自定义标签账户的视觉组织方式。 --- ## [3.0.4] — 2026-03-25 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Streaming:** Fixed `TextDecoder` state corruption inside combo `sanitize` TransformStream which caused SSE garbled output matching multibyte characters (PR #614) -- **Providers UI:** Safely render HTML tags inside provider connection error tooltips using `dangerouslySetInnerHTML` -- **Proxy Settings:** Added missing `username` and `password` payload body properties allowing authenticated proxies to be successfully verified from the Dashboard. -- **Provider API:** Bound soft exception returns to `getCodexUsage` preventing API HTTP 500 failures when token fetch fails +- **Streaming:** 修复 combo `sanitize` TransformStream 中 `TextDecoder` 状态损坏的问题;此前它会在遇到多字节字符时导致 SSE 输出乱码(PR #614)。 +- **Providers UI:** 使用 `dangerouslySetInnerHTML`,安全地在提供商连接错误提示中渲染 HTML 标签。 +- **Proxy Settings:** 补充缺失的 `username` 和 `password` 请求体字段,使认证代理可以从 Dashboard 正常验证。 +- **Provider API:** 将软异常返回绑定到 `getCodexUsage`,防止 token 获取失败时 API 触发 HTTP 500。 --- ## [3.0.3] — 2026-03-25 -### ✨ New Features +### ✨ 新特性 -- **Auto-Sync Models:** Added a UI toggle and `sync-models` endpoint to automatically synchronise model lists per provider using a scheduled interval scheduler (PR #597) +- **Auto-Sync Models:** 新增 UI 开关和 `sync-models` 端点,可通过定时调度器按提供商自动同步模型列表(PR #597)。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Timeouts:** Elevated default proxies `FETCH_TIMEOUT_MS` and `STREAM_IDLE_TIMEOUT_MS` to 10 minutes to properly support deep reasoning models (like o1) without aborting requests (Fixes #609) -- **CLI Tool Detection:** Improved cross-platform detection handling NVM paths, Windows `PATHEXT` (preventing `.cmd` wrappers issue), and custom NPM prefixes (PR #598) -- **Streaming Logs:** Implemented `tool_calls` delta accumulation in streaming response logs so function calls are tracked and persisted accurately in DB (PR #603) -- **Model Catalog:** Removed auth exemption, properly hiding `comfyui` and `sdwebui` models when no provider is explicitly configured (PR #599) +- **Timeouts:** 将默认代理的 `FETCH_TIMEOUT_MS` 和 `STREAM_IDLE_TIMEOUT_MS` 提升到 10 分钟,以便正确支持像 o1 这样的深度推理模型,而不会中途终止请求(Fixes #609)。 +- **CLI Tool Detection:** 改进跨平台检测逻辑,支持 NVM 路径、Windows `PATHEXT`(防止 `.cmd` 包装器问题)以及自定义 NPM 前缀(PR #598)。 +- **Streaming Logs:** 在流式响应日志中实现 `tool_calls` delta 累积,使函数调用能在数据库中被准确跟踪和持久化(PR #603)。 +- **Model Catalog:** 移除 auth exemption;当没有显式配置提供商时,能正确隐藏 `comfyui` 和 `sdwebui` 模型(PR #599)。 -### 🌐 Translations +### 🌐 翻译 -- **cs:** Improved Czech translation strings across the app (PR #601) +- **cs:** 改进了整个应用中的捷克语翻译字符串(PR #601)。 ## [3.0.2] — 2026-03-25 -### 🚀 Enhancements & Features +### 🚀 增强与特性 #### feat(ui): Connection Tag Grouping -- Added a Tag/Group field to `EditConnectionModal` (stored in `providerSpecificData.tag`) without requiring DB schema migrations. -- Connections in the provider view now dynamically group by tag with visual dividers. -- Untagged connections appear first without a header, followed by tagged groups in alphabetical order. -- The tag grouping automatically applies to the Codex/Copilot/Antigravity Limits section since toggles exist inside connection rows. +- 在 `EditConnectionModal` 中新增 Tag/Group 字段(存储于 `providerSpecificData.tag`),且无需数据库 schema migration。 +- 提供商视图中的连接现在会按标签动态分组,并带有可视化分隔线。 +- 未打标签的连接会优先显示且不带标题,其后是按字母顺序排列的已打标签分组。 +- 该标签分组会自动应用到 Codex/Copilot/Antigravity Limits 区域,因为相关开关位于连接行内部。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 #### fix(ui): Proxy Management UI Stabilization -- **Missing badges on connection cards:** Fixed by using `resolveProxyForConnection()` rather than static mapping. -- **Test Connection disabled in saved mode:** Enabled the Test button by resolving proxy config from the saved list. -- **Config Modal freezing:** Added `onClose()` calls after save/clear to prevent the UI from freezing. -- **Double usage counting:** `ProxyRegistryManager` now loads usage eagerly on mount with deduplication by `scope` + `scopeId`. Usage counts were replaced with a Test button displaying IP/latency inline. +- **连接卡片缺少徽章:** 改为使用 `resolveProxyForConnection()`,而不是静态映射。 +- **保存模式下 Test Connection 被禁用:** 通过从已保存列表中解析 proxy 配置,重新启用 Test 按钮。 +- **Config Modal 卡死:** 在保存/清除后调用 `onClose()`,防止 UI 卡死。 +- **使用量重复统计:** `ProxyRegistryManager` 现在会在挂载时主动加载 usage,并按 `scope` + `scopeId` 去重。原来的 usage 计数已替换为一个内联显示 IP/延迟的 Test 按钮。 #### fix(translator): `function_call` prefix stripping -- Repaired an incomplete fix from PR #607 where only `tool_use` blocks stripped Claude's `proxy_` tool prefix. Now, clients using the OpenAI Responses API format will also correctly receive tool tools without the `proxy_` prefix. +- 修复了 PR #607 中一个不完整的问题:此前只有 `tool_use` 块会移除 Claude 的 `proxy_` 工具前缀。现在,使用 OpenAI Responses API 格式的客户端也能正确收到不带 `proxy_` 前缀的工具名称。 --- ## [3.0.1] — 2026-03-25 -### 🔧 Hotfix Patch — Critical Bug Fixes +### 🔧 热修复补丁 — 关键 Bug 修复 -Three critical regressions reported by users after the v3.0.0 launch have been resolved. +v3.0.0 发布后,用户报告的 3 个关键回归问题现已全部修复。 -#### fix(translator): strip `proxy_` prefix in non-streaming Claude responses (#605) +#### fix(translator): 在非流式 Claude 响应中去除 `proxy_` 前缀(#605) -The `proxy_` prefix added by Claude OAuth was only stripped from **streaming** responses. In **non-streaming** mode, `translateNonStreamingResponse` had no access to the `toolNameMap`, causing clients to receive mangled tool names like `proxy_read_file` instead of `read_file`. +Claude OAuth 添加的 `proxy_` 前缀此前只会在**流式**响应中被去除。在**非流式**模式下,`translateNonStreamingResponse` 无法访问 `toolNameMap`,导致客户端收到被破坏的工具名,例如 `proxy_read_file`,而不是 `read_file`。 -**Fix:** Added optional `toolNameMap` parameter to `translateNonStreamingResponse` and applied prefix stripping in the Claude `tool_use` block handler. `chatCore.ts` now passes the map through. +**修复方式:** 为 `translateNonStreamingResponse` 新增可选的 `toolNameMap` 参数,并在 Claude `tool_use` 块处理器中应用前缀去除逻辑。`chatCore.ts` 现在也会把该映射继续传递下去。 -#### fix(validation): add LongCat specialty validator to skip /models probe (#592) +#### fix(validation): 为 LongCat 添加专用验证器以跳过 `/models` 探测(#592) -LongCat AI does not expose `GET /v1/models`. The generic `validateOpenAICompatibleProvider` validator fell through to a chat-completions fallback only if `validationModelId` was set, which LongCat doesn't configure. This caused provider validation to fail with a misleading error on add/save. +LongCat AI 不提供 `GET /v1/models`。通用的 `validateOpenAICompatibleProvider` 验证器只有在设置了 `validationModelId` 时才会回退到 chat-completions,而 LongCat 并未配置该字段。这会导致在新增/保存时,提供商验证以误导性的错误信息失败。 -**Fix:** Added `longcat` to the specialty validators map, probing `/chat/completions` directly and treating any non-auth response as a pass. +**修复方式:** 在专用验证器映射中新增 `longcat`,直接探测 `/chat/completions`,并将任何非认证错误的响应视为通过。 -#### fix(translator): normalize object tool schemas for Anthropic (#595) +#### fix(translator): 为 Anthropic 规范化 object 工具 schema(#595) -MCP tools (e.g. `pencil`, `computer_use`) forward tool definitions with `{type:"object"}` but without a `properties` field. Anthropic's API rejects these with: `object schema missing properties`. +MCP 工具(例如 `pencil`、`computer_use`)转发的工具定义中会出现 `{type:"object"}`,但没有 `properties` 字段。Anthropic API 会因此拒绝请求,并报错:`object schema missing properties`。 -**Fix:** In `openai-to-claude.ts`, inject `properties: {}` as a safe default when `type` is `"object"` and `properties` is absent. +**修复方式:** 在 `openai-to-claude.ts` 中,当 `type` 为 `"object"` 且缺少 `properties` 时,注入安全默认值 `properties: {}`。 --- -### 🔀 Community PRs Merged (2) +### 🔀 已合并的社区 PR(2) -| PR | Author | Summary | -| -------- | ------- | -------------------------------------------------------------------------- | -| **#589** | @flobo3 | docs(i18n): fix Russian translation for Playground and Testbed | -| **#591** | @rdself | fix(ui): improve Provider Limits light mode contrast and plan tier display | +| PR | 作者 | 摘要 | +| -------- | ------- | ---------------------------------------------------------- | +| **#589** | @flobo3 | docs(i18n): 修复 Playground 和 Testbed 的俄语翻译 | +| **#591** | @rdself | fix(ui): 改善 Provider Limits 浅色模式对比度和计划层级显示 | --- -### ✅ Issues Resolved +### ✅ 已解决问题 `#592` `#595` `#605` --- -### 🧪 Tests +### 🧪 测试 -- **926 tests, 0 failures** (unchanged from v3.0.0) +- **926 个测试,0 失败**(与 v3.0.0 持平) --- ## [3.0.0] — 2026-03-24 -### 🎉 OmniRoute v3.0.0 — The Free AI Gateway, Now with 67+ Providers +### 🎉 OmniRoute v3.0.0 — 免费 AI 网关,现已支持 67+ 个提供商 -> **The biggest release ever.** From 36 providers in v2.9.5 to **67+ providers** in v3.0.0 — with MCP Server, A2A Protocol, auto-combo engine, Provider Icons, Registered Keys API, 926 tests, and contributions from **12 community members** across **10 merged PRs**. +> **史上最大版本。** 从 v2.9.5 的 36 个提供商扩展到 v3.0.0 的 **67+ 个提供商**,并带来 MCP Server、A2A Protocol、auto-combo engine、Provider Icons、Registered Keys API、926 个测试,以及来自 **12 位社区成员** 的 **10 个已合并 PR** 贡献。 > -> Consolidated from v3.0.0-rc.1 through rc.17 (17 release candidates over 3 days of intense development). +> 整合自 v3.0.0-rc.1 到 rc.17(3 天高强度开发中的 17 个发布候选版本)。 --- -### 🆕 New Providers (+31 since v2.9.5) +### 🆕 新提供商(较 v2.9.5 增加 31 个) -| Provider | Alias | Tier | Notes | -| ----------------------------- | --------------- | ----------- | --------------------------------------------------------------------------- | -| **OpenCode Zen** | `opencode-zen` | Free | 3 models via `opencode.ai/zen/v1` (PR #530 by @kang-heewon) | -| **OpenCode Go** | `opencode-go` | Paid | 4 models via `opencode.ai/zen/go/v1` (PR #530 by @kang-heewon) | -| **LongCat AI** | `lc` | Free | 50M tokens/day (Flash-Lite) + 500K/day (Chat/Thinking) during public beta | -| **Pollinations AI** | `pol` | Free | No API key needed — GPT-5, Claude, Gemini, DeepSeek V3, Llama 4 (1 req/15s) | -| **Cloudflare Workers AI** | `cf` | Free | 10K Neurons/day — ~150 LLM responses or 500s Whisper audio, edge inference | -| **Scaleway AI** | `scw` | Free | 1M free tokens for new accounts — EU/GDPR compliant (Paris) | -| **AI/ML API** | `aiml` | Free | $0.025/day free credits — 200+ models via single endpoint | -| **Puter AI** | `pu` | Free | 500+ models (GPT-5, Claude Opus 4, Gemini 3 Pro, Grok 4, DeepSeek V3) | -| **Alibaba Cloud (DashScope)** | `ali` | Paid | International + China endpoints via `alicode`/`alicode-intl` | -| **Alibaba Coding Plan** | `bcp` | Paid | Alibaba Model Studio with Anthropic-compatible API | -| **Kimi Coding (API Key)** | `kmca` | Paid | Dedicated API-key-based Kimi access (separate from OAuth) | -| **MiniMax Coding** | `minimax` | Paid | International endpoint | -| **MiniMax (China)** | `minimax-cn` | Paid | China-specific endpoint | -| **Z.AI (GLM-5)** | `zai` | Paid | Zhipu AI next-gen GLM models | -| **Vertex AI** | `vertex` | Paid | Google Cloud — Service Account JSON or OAuth access_token | -| **Ollama Cloud** | `ollamacloud` | Paid | Ollama's hosted API service | -| **Synthetic** | `synthetic` | Paid | Passthrough models gateway | -| **Kilo Gateway** | `kg` | Paid | Passthrough models gateway | -| **Perplexity Search** | `pplx-search` | Paid | Dedicated search-grounded endpoint | -| **Serper Search** | `serper-search` | Paid | Web search API integration | -| **Brave Search** | `brave-search` | Paid | Brave Search API integration | -| **Exa Search** | `exa-search` | Paid | Neural search API integration | -| **Tavily Search** | `tavily-search` | Paid | AI search API integration | -| **NanoBanana** | `nb` | Paid | Image generation API | -| **ElevenLabs** | `el` | Paid | Text-to-speech voice synthesis | -| **Cartesia** | `cartesia` | Paid | Ultra-fast TTS voice synthesis | -| **PlayHT** | `playht` | Paid | Voice cloning and TTS | -| **Inworld** | `inworld` | Paid | AI character voice chat | -| **SD WebUI** | `sdwebui` | Self-hosted | Stable Diffusion local image generation | -| **ComfyUI** | `comfyui` | Self-hosted | ComfyUI local workflow node-based generation | -| **GLM Coding** | `glm` | Paid | BigModel/Zhipu coding-specific endpoint | +| 提供商 | 别名 | 层级 | 说明 | +| ----------------------------- | --------------- | ------ | ------------------------------------------------------------------------- | +| **OpenCode Zen** | `opencode-zen` | 免费 | 通过 `opencode.ai/zen/v1` 提供 3 个模型(PR #530 by @kang-heewon) | +| **OpenCode Go** | `opencode-go` | 付费 | 通过 `opencode.ai/zen/go/v1` 提供 4 个模型(PR #530 by @kang-heewon) | +| **LongCat AI** | `lc` | 免费 | 公测期间每天 5000 万 tokens(Flash-Lite)+ 50 万/天(Chat/Thinking) | +| **Pollinations AI** | `pol` | 免费 | 无需 API key —— GPT-5、Claude、Gemini、DeepSeek V3、Llama 4(1 次/15 秒) | +| **Cloudflare Workers AI** | `cf` | 免费 | 每天 10K Neurons —— 约 150 次 LLM 响应或 500 秒 Whisper 音频,边缘推理 | +| **Scaleway AI** | `scw` | 免费 | 新账户提供 100 万免费 tokens —— 符合 EU/GDPR(巴黎) | +| **AI/ML API** | `aiml` | 免费 | 每天 $0.025 免费额度 —— 通过单一端点访问 200+ 个模型 | +| **Puter AI** | `pu` | 免费 | 500+ 个模型(GPT-5、Claude Opus 4、Gemini 3 Pro、Grok 4、DeepSeek V3) | +| **Alibaba Cloud (DashScope)** | `ali` | 付费 | 通过 `alicode`/`alicode-intl` 提供国际与中国端点 | +| **Alibaba Coding Plan** | `bcp` | 付费 | Alibaba Model Studio,提供 Anthropic-compatible API | +| **Kimi Coding (API Key)** | `kmca` | 付费 | 基于 API key 的独立 Kimi 接入(与 OAuth 分离) | +| **MiniMax Coding** | `minimax` | 付费 | 国际端点 | +| **MiniMax (China)** | `minimax-cn` | 付费 | 中国区端点 | +| **Z.AI (GLM-5)** | `zai` | 付费 | 智谱 AI 新一代 GLM 模型 | +| **Vertex AI** | `vertex` | 付费 | Google Cloud —— Service Account JSON 或 OAuth access_token | +| **Ollama Cloud** | `ollamacloud` | 付费 | Ollama 托管 API 服务 | +| **Synthetic** | `synthetic` | 付费 | Passthrough 模型网关 | +| **Kilo Gateway** | `kg` | 付费 | Passthrough 模型网关 | +| **Perplexity Search** | `pplx-search` | 付费 | 专用搜索增强端点 | +| **Serper Search** | `serper-search` | 付费 | Web search API 集成 | +| **Brave Search** | `brave-search` | 付费 | Brave Search API 集成 | +| **Exa Search** | `exa-search` | 付费 | Neural search API 集成 | +| **Tavily Search** | `tavily-search` | 付费 | AI search API 集成 | +| **NanoBanana** | `nb` | 付费 | 图像生成 API | +| **ElevenLabs** | `el` | 付费 | 文本转语音语音合成 | +| **Cartesia** | `cartesia` | 付费 | 超高速 TTS 语音合成 | +| **PlayHT** | `playht` | 付费 | 语音克隆与 TTS | +| **Inworld** | `inworld` | 付费 | AI 角色语音聊天 | +| **SD WebUI** | `sdwebui` | 自托管 | Stable Diffusion 本地图像生成 | +| **ComfyUI** | `comfyui` | 自托管 | ComfyUI 本地工作流节点式生成 | +| **GLM Coding** | `glm` | 付费 | BigModel/Zhipu 专用编码端点 | -**Total: 67+ providers** (4 Free, 8 OAuth, 55 API Key) + unlimited OpenAI/Anthropic-Compatible custom providers. +**总计:67+ 个提供商**(4 个免费、8 个 OAuth、55 个 API Key)+ 无限数量的 OpenAI/Anthropic-Compatible 自定义提供商。 --- -### ✨ Major Features +### ✨ 主要功能 #### 🔑 Registered Keys Provisioning API (#464) -Auto-generate and issue OmniRoute API keys programmatically with per-provider and per-account quota enforcement. +可通过编程方式自动生成并签发 OmniRoute API key,支持按提供商和账户进行配额限制。 -| Endpoint | Method | Description | -| ------------------------------- | ------------ | ------------------------------------------------ | -| `/api/v1/registered-keys` | `POST` | Issue a new key — raw key returned **once only** | -| `/api/v1/registered-keys` | `GET` | List registered keys (masked) | -| `/api/v1/registered-keys/{id}` | `GET/DELETE` | Get metadata / Revoke | -| `/api/v1/quotas/check` | `GET` | Pre-validate quota before issuing | -| `/api/v1/providers/{id}/limits` | `GET/PUT` | Configure per-provider issuance limits | -| `/api/v1/accounts/{id}/limits` | `GET/PUT` | Configure per-account issuance limits | -| `/api/v1/issues/report` | `POST` | Report quota events to GitHub Issues | +| 端点 | 方法 | 说明 | +| ------------------------------- | ------------ | ------------------------------------- | +| `/api/v1/registered-keys` | `POST` | 签发新 key —— 原始 key **只返回一次** | +| `/api/v1/registered-keys` | `GET` | 列出已注册 key(脱敏) | +| `/api/v1/registered-keys/{id}` | `GET/DELETE` | 获取元数据 / 吊销 | +| `/api/v1/quotas/check` | `GET` | 签发前预检配额 | +| `/api/v1/providers/{id}/limits` | `GET/PUT` | 配置按提供商的签发限制 | +| `/api/v1/accounts/{id}/limits` | `GET/PUT` | 配置按账户的签发限制 | +| `/api/v1/issues/report` | `POST` | 向 GitHub Issues 报告配额事件 | -**Security:** Keys stored as SHA-256 hashes. Raw key shown once on creation, never retrievable again. +**安全性:** key 以 SHA-256 哈希存储。原始 key 只在创建时展示一次,之后不可再取回。 #### 🎨 Provider Icons via @lobehub/icons (#529) -130+ provider logos using `@lobehub/icons` React components (SVG). Fallback chain: **Lobehub SVG → existing PNG → generic icon**. Applied across Dashboard, Providers, and Agents pages with standardized `ProviderIcon` component. +130+ 个提供商 Logo 现使用 `@lobehub/icons` React 组件(SVG)。回退链为:**Lobehub SVG → 现有 PNG → 通用图标**。已统一应用到 Dashboard、Providers 和 Agents 页面,使用标准化的 `ProviderIcon` 组件。 #### 🔄 Model Auto-Sync Scheduler (#488) -Auto-refreshes model lists for connected providers every **24 hours**. Runs on server startup. Configurable via `MODEL_SYNC_INTERVAL_HOURS`. +每 **24 小时**自动刷新已连接提供商的模型列表。会在服务器启动时运行,并可通过 `MODEL_SYNC_INTERVAL_HOURS` 配置。 #### 🔀 Per-Model Combo Routing (#563) -Map model name patterns (glob) to specific combos for automatic routing: +可将模型名称模式(glob)映射到特定 combo,实现自动路由: -- `claude-sonnet*` → code-combo, `gpt-4o*` → openai-combo, `gemini-*` → google-combo -- New `model_combo_mappings` table with glob-to-regex matching -- Dashboard UI section: "Model Routing Rules" with inline add/edit/toggle/delete +- `claude-sonnet*` → code-combo,`gpt-4o*` → openai-combo,`gemini-*` → google-combo +- 新增 `model_combo_mappings` 表,支持 glob 转 regex 匹配 +- Dashboard UI 新增 “Model Routing Rules” 区域,支持内联新增/编辑/开关/删除 #### 🧭 API Endpoints Dashboard -Interactive catalog, webhooks management, OpenAPI viewer — all in one tabbed page at `/dashboard/endpoint`. +交互式目录、webhooks 管理与 OpenAPI 查看器,全部集中在 `/dashboard/endpoint` 的单一标签页页面中。 #### 🔍 Web Search Providers -5 new search provider integrations: **Perplexity Search**, **Serper**, **Brave Search**, **Exa**, **Tavily** — enabling grounded AI responses with real-time web data. +新增 5 个搜索提供商集成:**Perplexity Search**、**Serper**、**Brave Search**、**Exa**、**Tavily**,让 AI 响应可结合实时 Web 数据进行 grounded 回答。 #### 📊 Search Analytics -New tab in `/dashboard/analytics` — provider breakdown, cache hit rate, cost tracking. API: `GET /api/v1/search/analytics`. +`/dashboard/analytics` 中新增标签页,展示提供商拆分、缓存命中率和成本跟踪。API:`GET /api/v1/search/analytics`。 #### 🛡️ Per-API-Key Rate Limits (#452) -`max_requests_per_day` and `max_requests_per_minute` columns with in-memory sliding-window enforcement returning HTTP 429. +新增 `max_requests_per_day` 和 `max_requests_per_minute` 字段,并通过内存滑动窗口强制限制,返回 HTTP 429。 #### 🎵 Media Playground -Full media generation playground at `/dashboard/media`: Image Generation, Video, Music, Audio Transcription (2GB upload limit), and Text-to-Speech. +`/dashboard/media` 提供完整的多媒体生成 playground:图像生成、视频、音乐、音频转录(2GB 上传限制)和文本转语音。 --- -### 🔒 Security & CI/CD +### 🔒 安全与 CI/CD -- **CodeQL remediation** — Fixed 10+ alerts: 6 polynomial-redos, 1 insecure-randomness (`Math.random()` → `crypto.randomUUID()`), 1 shell-command-injection -- **Route validation** — Zod schemas + `validateBody()` on **176/176 API routes** — CI enforced -- **CVE fix** — dompurify XSS vulnerability (GHSA-v2wj-7wpq-c8vv) resolved via npm overrides -- **Flatted** — Bumped 3.3.3 → 3.4.2 (CWE-1321 prototype pollution) -- **Docker** — Upgraded `docker/setup-buildx-action` v3 → v4 +- **CodeQL remediation** —— 修复 10+ 个警报:6 个 polynomial-redos、1 个 insecure-randomness(`Math.random()` → `crypto.randomUUID()`)、1 个 shell-command-injection +- **Route validation** —— 为 **176/176 个 API 路由**加入 Zod schema + `validateBody()`,并由 CI 强制执行 +- **CVE fix** —— 通过 npm overrides 修复 dompurify XSS 漏洞(GHSA-v2wj-7wpq-c8vv) +- **Flatted** —— 从 3.3.3 升级到 3.4.2(CWE-1321 prototype pollution) +- **Docker** —— 将 `docker/setup-buildx-action` 从 v3 升级到 v4 --- -### 🐛 Bug Fixes (40+) +### 🐛 Bug 修复(40+) -#### OAuth & Auth +#### OAuth 与认证 -- **#537** — Gemini CLI OAuth: clear actionable error when `GEMINI_OAUTH_CLIENT_SECRET` missing in Docker -- **#549** — CLI settings routes now resolve real API key from `keyId` (not masked strings) -- **#574** — Login no longer freezes after skipping wizard password setup -- **#506** — Cross-platform `machineId` rewritten (Windows REG.exe → macOS ioreg → Linux → hostname fallback) +- **#537** —— 在 Docker 中缺少 `GEMINI_OAUTH_CLIENT_SECRET` 时,Gemini CLI OAuth 现在会给出清晰且可操作的错误提示 +- **#549** —— CLI 设置路由现在会从 `keyId` 解析真实 API key(而不是脱敏字符串) +- **#574** —— 跳过向导密码设置后,登录不再卡死 +- **#506** —— 重写跨平台 `machineId` 逻辑(Windows REG.exe → macOS ioreg → Linux → hostname 回退) -#### Providers & Routing +#### 提供商与路由 -- **#536** — LongCat AI: fixed `baseUrl` and `authHeader` -- **#535** — Pinned model override: `body.model` correctly set to `pinnedModel` -- **#570** — Unprefixed Claude models now resolve to Anthropic provider -- **#585** — `` internal tags no longer leak to clients in SSE streaming -- **#493** — Custom provider model naming no longer mangled by prefix stripping -- **#490** — Streaming + context cache protection via `TransformStream` injection -- **#511** — `` tag injected into first content chunk (not after `[DONE]`) +- **#536** —— 修复 LongCat AI 的 `baseUrl` 和 `authHeader` +- **#535** —— 修复固定模型覆盖:`body.model` 现在会正确设置为 `pinnedModel` +- **#570** —— 未带前缀的 Claude 模型现在会正确解析到 Anthropic 提供商 +- **#585** —— `` 内部标签不再泄露到 SSE 流式客户端 +- **#493** —— 自定义提供商模型命名不再被前缀剥离破坏 +- **#490** —— 通过 `TransformStream` 注入实现流式 + context cache protection +- **#511** —— `` 标签现在会注入到首个内容 chunk 中(而不是 `[DONE]` 之后) -#### CLI & Tools +#### CLI 与工具 -- **#527** — Claude Code + Codex loop: `tool_result` blocks now converted to text -- **#524** — OpenCode config saved correctly (XDG_CONFIG_HOME, TOML format) -- **#522** — API Manager: removed misleading "Copy masked key" button -- **#546** — `--version` returning `unknown` on Windows (PR by @k0valik) -- **#544** — Secure CLI tool detection via known installation paths (PR by @k0valik) -- **#510** — Windows MSYS2/Git-Bash paths normalized automatically -- **#492** — CLI detects `mise`/`nvm`-managed Node when `app/server.js` missing +- **#527** —— Claude Code + Codex 循环问题:`tool_result` 块现在会被转换为文本 +- **#524** —— OpenCode 配置可正确保存(XDG_CONFIG_HOME、TOML 格式) +- **#522** —— API Manager 移除具有误导性的 “Copy masked key” 按钮 +- **#546** —— 修复 Windows 上 `--version` 返回 `unknown` 的问题(PR by @k0valik) +- **#544** —— 通过已知安装路径实现安全的 CLI 工具检测(PR by @k0valik) +- **#510** —— Windows MSYS2/Git-Bash 路径现在会自动规范化 +- **#492** —— 当 `app/server.js` 缺失时,CLI 可检测由 `mise`/`nvm` 管理的 Node -#### Streaming & SSE +#### Streaming 与 SSE -- **PR #587** — Revert `resolveDataDir` import in responsesTransformer for Cloudflare Workers compat (@k0valik) -- **PR #495** — Bottleneck 429 infinite wait: drop waiting jobs on rate limit (@xandr0s) -- **#483** — Stop trailing `data: null` after `[DONE]` signal -- **#473** — Zombie SSE streams: timeout reduced 300s → 120s for faster fallback +- **PR #587** —— 回滚 responsesTransformer 中对 `resolveDataDir` 的导入,以兼容 Cloudflare Workers(@k0valik) +- **PR #495** —— 修复 Bottleneck 429 无限等待:在限流时丢弃等待中的任务(@xandr0s) +- **#483** —— 在 `[DONE]` 信号后停止附加 `data: null` +- **#473** —— Zombie SSE 流超时从 300 秒降到 120 秒,以实现更快回退 -#### Media & Transcription +#### 媒体与转录 -- **Transcription** — Deepgram `video/mp4` → `audio/mp4` MIME mapping, auto language detection, punctuation -- **TTS** — `[object Object]` error display fixed for ElevenLabs-style nested errors -- **Upload limits** — Media transcription increased to 2GB (nginx `client_max_body_size 2g` + `maxDuration=300`) +- **Transcription** —— Deepgram `video/mp4` → `audio/mp4` MIME 映射,自动语言检测和标点 +- **TTS** —— 修复 ElevenLabs 风格嵌套错误中的 `[object Object]` 显示问题 +- **Upload limits** —— 媒体转录上限提升到 2GB(nginx `client_max_body_size 2g` + `maxDuration=300`) --- -### 🔧 Infrastructure & Improvements +### 🔧 基础设施与改进 -#### Sub2api Gap Analysis (T01–T15 + T23–T42) +#### Sub2api Gap Analysis(T01–T15 + T23–T42) -- **T01** — `requested_model` column in call logs (migration 009) -- **T02** — Strip empty text blocks from nested `tool_result.content` -- **T03** — Parse `x-codex-5h-*` / `x-codex-7d-*` quota headers -- **T04** — `X-Session-Id` header for external sticky routing -- **T05** — Rate-limit DB persistence with dedicated API -- **T06** — Account deactivated → permanent block (1-year cooldown) -- **T07** — X-Forwarded-For IP validation (`extractClientIp()`) -- **T08** — Per-API-key session limits with sliding-window enforcement -- **T09** — Codex vs Spark rate-limit scopes (separate pools) -- **T10** — Credits exhausted → distinct 1h cooldown fallback -- **T11** — `max` reasoning effort → 131072 budget tokens -- **T12** — MiniMax M2.7 pricing entries -- **T13** — Stale quota display fix (reset window awareness) -- **T14** — Proxy fast-fail TCP check (≤2s, cached 30s) -- **T15** — Array content normalization for Anthropic -- **T23** — Intelligent quota reset fallback (header extraction) -- **T24** — `503` cooldown + `406` mapping -- **T25** — Provider validation fallback -- **T29** — Vertex AI Service Account JWT auth -- **T33** — Thinking level to budget conversion -- **T36** — `403` vs `429` error classification -- **T38** — Centralized model specifications (`modelSpecs.ts`) -- **T39** — Endpoint fallback for `fetchAvailableModels` -- **T41** — Background task auto-redirect to flash models -- **T42** — Image generation aspect ratio mapping +- **T01** —— 在 call logs 中新增 `requested_model` 列(migration 009) +- **T02** —— 从嵌套的 `tool_result.content` 中剥离空文本块 +- **T03** —— 解析 `x-codex-5h-*` / `x-codex-7d-*` 配额头 +- **T04** —— 为外部粘性路由增加 `X-Session-Id` 请求头 +- **T05** —— 通过专用 API 持久化 rate-limit 数据 +- **T06** —— 账户停用 → 永久封锁(1 年冷却) +- **T07** —— `X-Forwarded-For` IP 校验(`extractClientIp()`) +- **T08** —— 基于滑动窗口的 Per-API-key 会话限制 +- **T09** —— Codex 与 Spark 的限流范围分离(独立池) +- **T10** —— 积分耗尽 → 独立的 1 小时冷却回退 +- **T11** —— `max` reasoning effort → 131072 budget tokens +- **T12** —— 新增 MiniMax M2.7 定价条目 +- **T13** —— 修复过期配额显示(感知重置窗口) +- **T14** —— 代理快速失败 TCP 检查(≤2 秒,缓存 30 秒) +- **T15** —— 为 Anthropic 规范化数组内容 +- **T23** —— 智能配额重置回退(从 header 提取) +- **T24** —— `503` 冷却 + `406` 映射 +- **T25** —— Provider 验证回退 +- **T29** —— Vertex AI Service Account JWT 认证 +- **T33** —— Thinking level 到 budget 的转换 +- **T36** —— `403` 与 `429` 错误分类 +- **T38** —— 集中化模型规格定义(`modelSpecs.ts`) +- **T39** —— `fetchAvailableModels` 的端点回退 +- **T41** —— 后台任务自动重定向到 flash 模型 +- **T42** —— 图像生成长宽比映射 -#### Other Improvements +#### 其他改进 -- **Per-model upstream custom headers** — via configuration UI (PR #575 by @zhangqiang8vip) -- **Model context length** — configurable in model metadata (PR #578 by @hijak) -- **Model prefix stripping** — option to remove provider prefix from model names (PR #582 by @jay77721) -- **Gemini CLI deprecation** — marked deprecated with Google OAuth restriction warning -- **YAML parser** — replaced custom parser with `js-yaml` for correct OpenAPI spec parsing -- **ZWS v5** — HMR leak fix (485 DB connections → 1, memory 2.4GB → 195MB) -- **Log export** — New JSON export button on dashboard with time range dropdown -- **Update notification banner** — dashboard homepage shows when new versions are available +- **Per-model upstream custom headers** —— 通过配置 UI 设置(PR #575 by @zhangqiang8vip) +- **Model context length** —— 可在模型元数据中配置(PR #578 by @hijak) +- **Model prefix stripping** —— 可选移除模型名称中的提供商前缀(PR #582 by @jay77721) +- **Gemini CLI deprecation** —— 因 Google OAuth 限制警告而标记为 deprecated +- **YAML parser** —— 用 `js-yaml` 替换自定义解析器,以正确解析 OpenAPI spec +- **ZWS v5** —— HMR 泄漏修复(数据库连接 485 → 1,内存 2.4GB → 195MB) +- **Log export** —— Dashboard 新增带时间范围下拉框的 JSON 导出按钮 +- **Update notification banner** —— Dashboard 首页现在会显示新版本可用提醒 --- -### 🌐 i18n & Documentation +### 🌐 i18n 与文档 -- **30 languages** at 100% parity — 2,788 missing keys synced -- **Czech** — Full translation: 22 docs, 2,606 UI strings (PR by @zen0bit) -- **Chinese (zh-CN)** — Complete retranslation (PR by @only4copilot) -- **VM Deployment Guide** — Translated to English as source document -- **API Reference** — Added `/v1/embeddings` and `/v1/audio/speech` endpoints -- **Provider count** — Updated from 36+/40+/44+ to **67+** across README and all 30 i18n READMEs +- **30 种语言** 达到 100% 同步 —— 已补齐 2,788 个缺失键 +- **Czech** —— 完整翻译:22 份文档,2,606 条 UI 字符串(PR by @zen0bit) +- **Chinese (zh-CN)** —— 完整重译(PR by @only4copilot) +- **VM Deployment Guide** —— 已翻译为英文源文档 +- **API Reference** —— 新增 `/v1/embeddings` 和 `/v1/audio/speech` 端点 +- **Provider count** —— 将 README 和全部 30 份 i18n README 中的提供商数量从 36+/40+/44+ 更新为 **67+** --- -### 🔀 Community PRs Merged (10) +### 🔀 已合并的社区 PR(10) -| PR | Author | Summary | -| -------- | --------------- | -------------------------------------------------------------------- | -| **#587** | @k0valik | fix(sse): revert resolveDataDir import for Cloudflare Workers compat | -| **#582** | @jay77721 | feat(proxy): model name prefix stripping option | -| **#581** | @jay77721 | fix(npm): link electron-release to npm-publish workflow | -| **#578** | @hijak | feat: configurable context length in model metadata | -| **#575** | @zhangqiang8vip | feat: per-model upstream headers, compat PATCH, chat alignment | -| **#562** | @coobabm | fix: MCP session management, Claude passthrough, detectFormat | -| **#561** | @zen0bit | fix(i18n): Czech translation corrections | -| **#555** | @k0valik | fix(sse): centralized `resolveDataDir()` for path resolution | -| **#546** | @k0valik | fix(cli): `--version` returning `unknown` on Windows | -| **#544** | @k0valik | fix(cli): secure CLI tool detection via installation paths | -| **#542** | @rdself | fix(ui): light mode contrast CSS theme variables | -| **#530** | @kang-heewon | feat: OpenCode Zen + Go providers with `OpencodeExecutor` | -| **#512** | @zhangqiang8vip | feat: per-protocol model compatibility (`compatByProtocol`) | -| **#497** | @zhangqiang8vip | fix: dev-mode HMR resource leaks (ZWS v5) | -| **#495** | @xandr0s | fix: Bottleneck 429 infinite wait (drop waiting jobs) | -| **#494** | @zhangqiang8vip | feat: MiniMax developer→system role fix | -| **#480** | @prakersh | fix: stream flush usage extraction | -| **#479** | @prakersh | feat: Codex 5.3/5.4 and Anthropic pricing entries | -| **#475** | @only4copilot | feat(i18n): improved Chinese translation | +| PR | 作者 | 摘要 | +| -------- | --------------- | ------------------------------------------------------------- | +| **#587** | @k0valik | fix(sse): 回滚 `resolveDataDir` 导入以兼容 Cloudflare Workers | +| **#582** | @jay77721 | feat(proxy): 模型名前缀剥离选项 | +| **#581** | @jay77721 | fix(npm): 将 electron-release 接入 npm-publish 工作流 | +| **#578** | @hijak | feat: 可配置的模型上下文长度元数据 | +| **#575** | @zhangqiang8vip | feat: 按模型设置上游请求头、compat PATCH、chat 对齐 | +| **#562** | @coobabm | fix: MCP 会话管理、Claude passthrough、detectFormat | +| **#561** | @zen0bit | fix(i18n): 捷克语翻译修正 | +| **#555** | @k0valik | fix(sse): 集中化 `resolveDataDir()` 用于路径解析 | +| **#546** | @k0valik | fix(cli): Windows 上 `--version` 返回 `unknown` | +| **#544** | @k0valik | fix(cli): 基于安装路径的安全 CLI 工具检测 | +| **#542** | @rdself | fix(ui): 浅色模式对比度 CSS 主题变量 | +| **#530** | @kang-heewon | feat: 使用 `OpencodeExecutor` 的 OpenCode Zen + Go 提供商 | +| **#512** | @zhangqiang8vip | feat: 按协议定义模型兼容性(`compatByProtocol`) | +| **#497** | @zhangqiang8vip | fix: 开发模式 HMR 资源泄漏(ZWS v5) | +| **#495** | @xandr0s | fix: Bottleneck 429 无限等待(丢弃等待中的任务) | +| **#494** | @zhangqiang8vip | feat: MiniMax developer→system 角色修复 | +| **#480** | @prakersh | fix: 流式 flush usage 提取 | +| **#479** | @prakersh | feat: Codex 5.3/5.4 和 Anthropic 定价条目 | +| **#475** | @only4copilot | feat(i18n): 改进中文翻译 | -**Thank you to all contributors!** 🙏 +**感谢所有贡献者!** --- -### 📋 Issues Resolved (50+) +### 📋 已解决问题(50+) `#452` `#458` `#462` `#464` `#466` `#473` `#474` `#481` `#483` `#487` `#488` `#489` `#490` `#491` `#492` `#493` `#506` `#508` `#509` `#510` `#511` `#513` `#520` `#521` `#522` `#524` `#525` `#527` `#529` `#531` `#532` `#535` `#536` `#537` `#541` `#546` `#549` `#563` `#570` `#574` `#585` --- -### 🧪 Tests +### 🧪 测试 -- **926 tests, 0 failures** (up from 821 in v2.9.5) -- +105 new tests covering: model-combo mappings, registered keys, OpencodeExecutor, Bailian provider, route validation, error classification, aspect ratio mapping, and more +- **926 个测试,0 失败**(相比 v2.9.5 的 821 个有所增加) +- 新增 105 个测试,覆盖 model-combo mappings、registered keys、OpencodeExecutor、Bailian 提供商、route validation、error classification、aspect ratio mapping 等内容 --- -### 📦 Database Migrations +### 📦 数据库迁移 -| Migration | Description | -| --------- | --------------------------------------------------------------------- | -| **008** | `registered_keys`, `provider_key_limits`, `account_key_limits` tables | -| **009** | `requested_model` column in `call_logs` | -| **010** | `model_combo_mappings` table for per-model combo routing | +| 迁移编号 | 说明 | +| -------- | ----------------------------------------------------------------- | +| **008** | `registered_keys`、`provider_key_limits`、`account_key_limits` 表 | +| **009** | `call_logs` 中新增 `requested_model` 列 | +| **010** | 用于按模型 combo 路由的 `model_combo_mappings` 表 | --- -### ⬆️ Upgrading from v2.9.5 +### ⬆️ 从 v2.9.5 升级 ```bash # npm @@ -887,379 +943,379 @@ npm install -g omniroute@3.0.0 # Docker docker pull diegosouzapw/omniroute:3.0.0 -# Migrations run automatically on first startup +# 首次启动时会自动运行迁移 ``` -> **Breaking changes:** None. All existing configurations, combos, and API keys are preserved. -> Database migrations 008-010 run automatically on startup. +> **破坏性变更:** 无。所有现有配置、combo 和 API key 都会被保留。 +> 数据库迁移 008-010 会在启动时自动运行。 --- ## [3.0.0-rc.17] — 2026-03-24 -### 🔒 Security & CI/CD +### 🔒 安全与 CI/CD -- **CodeQL remediation** — Fixed 10+ alerts: - - 6 polynomial-redos in `provider.ts` / `chatCore.ts` (replaced `(?:^|/)` alternation patterns with segment-based matching) - - 1 insecure-randomness in `acp/manager.ts` (`Math.random()` → `crypto.randomUUID()`) - - 1 shell-command-injection in `prepublish.mjs` (`JSON.stringify()` path escaping) -- **Route validation** — Added Zod schemas + `validateBody()` to 5 routes missing validation: - - `model-combo-mappings` (POST, PUT), `webhooks` (POST, PUT), `openapi/try` (POST) - - CI `check:route-validation:t06` now passes: **176/176 routes validated** +- **CodeQL remediation** —— 修复 10+ 个警报: + - `provider.ts` / `chatCore.ts` 中的 6 个 polynomial-redos(将 `(?:^|/)` 交替模式替换为基于片段的匹配) + - `acp/manager.ts` 中的 1 个 insecure-randomness(`Math.random()` → `crypto.randomUUID()`) + - `prepublish.mjs` 中的 1 个 shell-command-injection(`JSON.stringify()` 路径转义) +- **Route validation** —— 为 5 个缺少验证的路由新增 Zod schema + `validateBody()`: + - `model-combo-mappings`(POST、PUT)、`webhooks`(POST、PUT)、`openapi/try`(POST) + - CI `check:route-validation:t06` 现已通过:**176/176 个路由全部完成验证** -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **#585** — `` internal tags no longer leak to clients in SSE responses. Added outbound sanitization `TransformStream` in `combo.ts` +- **#585** —— `` 内部标签不再泄露给 SSE 客户端响应。已在 `combo.ts` 中添加出站清理 `TransformStream` -### ⚙️ Infrastructure +### ⚙️ 基础设施 -- **Docker** — Upgraded `docker/setup-buildx-action` from v3 → v4 (Node.js 20 deprecation fix) -- **CI cleanup** — Deleted 150+ failed/cancelled workflow runs +- **Docker** —— 将 `docker/setup-buildx-action` 从 v3 升级到 v4(修复 Node.js 20 弃用问题) +- **CI cleanup** —— 删除 150+ 个失败/已取消的 workflow 运行 -### 🧪 Tests +### 🧪 测试 -- Test suite: **926 tests, 0 failures** (+3 new) +- 测试套件:**926 个测试,0 失败**(新增 3 个) --- ## [3.0.0-rc.16] — 2026-03-24 -### ✨ New Features +### ✨ 新特性 -- Increased media transcription limits -- Added Model Context Length to registry metadata -- Added per-model upstream custom headers via configuration UI -- Fixed multiple bugs, Zod valiadation for patches, and resolved various community issues. +- 提高了媒体转录限制 +- 为 registry metadata 添加了模型上下文长度 +- 通过配置 UI 添加了每模型上游自定义请求头 +- 修复了多个 bug,使用 Zod 验证进行补丁,并解决了各种社区问题 ## [3.0.0-rc.15] — 2026-03-24 -### ✨ New Features +### ✨ 新特性 -- **#563** — Per-model Combo Routing: map model name patterns (glob) to specific combos for automatic routing - - New `model_combo_mappings` table (migration 010) with pattern, combo_id, priority, enabled - - `resolveComboForModel()` DB function with glob-to-regex matching (case-insensitive, `*` and `?` wildcards) - - `getComboForModel()` in `model.ts`: augments `getCombo()` with model-pattern fallback - - `chat.ts`: routing decision now checks model-combo mappings before single-model handling - - API: `GET/POST /api/model-combo-mappings`, `GET/PUT/DELETE /api/model-combo-mappings/:id` - - Dashboard: "Model Routing Rules" section added to Combos page with inline add/edit/toggle/delete - - Examples: `claude-sonnet*` → code-combo, `gpt-4o*` → openai-combo, `gemini-*` → google-combo +- **#563** — 每模型 Combo 路由:将模型名称模式(glob)映射到特定 combo,实现自动路由 + - 新增 `model_combo_mappings` 表(migration 010),包含 pattern、combo_id、priority、enabled 字段 + - `resolveComboForModel()` 数据库函数,使用 glob 到正则匹配(不区分大小写,支持 `*` 和 `?` 通配符) + - `getComboForModel()` 在 `model.ts` 中:增强 `getCombo()`,使用模型模式回退 + - `chat.ts`:路由决策现在在处理单模型之前检查模型-combo 映射 + - API:`GET/POST /api/model-combo-mappings`、`GET/PUT/DELETE /api/model-combo-mappings/:id` + - 仪表盘:在 Combos 页面新增 "Model Routing Rules" 区域,支持内联新增/编辑/开关/删除 + - 示例:`claude-sonnet*` → code-combo、`gpt-4o*` → openai-combo、`gemini-*` → google-combo ### 🌐 i18n -- **Full i18n Sync**: 2,788 missing keys added across 30 language files — all languages now at 100% parity with `en.json` -- **Agents page i18n**: OpenCode Integration section fully internationalized (title, description, scanning, download labels) -- **6 new keys** added to `agents` namespace for OpenCode section +- **完整 i18n 同步**:在 30 个语言文件中新增 2,788 个缺失键 — 所有语言现在与 `en.json` 达到 100% 一致 +- **代理页面 i18n**:OpenCode 集成部分完全国际化(标题、描述、扫描、下载标签) +- **新增 6 个键**到 `agents` 命名空间,用于 OpenCode 部分 -### 🎨 UI/UX +### 🎨 界面/体验 -- **Provider Icons**: 16 missing provider icons added (3 copied, 2 downloaded, 11 SVG created) -- **SVG fallback**: `ProviderIcon` component updated with 4-tier strategy: Lobehub → PNG → SVG → Generic icon -- **Agents fingerprinting**: Synced with CLI tools — added droid, openclaw, copilot, opencode to fingerprint list (14 total) +- **提供商图标**:新增 16 个缺失的提供商图标(3 个复制、2 个下载、11 个 SVG 创建) +- **SVG 回退**:`ProviderIcon` 组件更新为 4 层策略:Lobehub → PNG → SVG → 通用图标 +- **代理指纹识别**:与 CLI 工具同步 — 将 droid、openclaw、copilot、opencode 添加到指纹列表(共 14 个) -### 安全 +### 🔒 安全 -- **CVE fix**: Resolved dompurify XSS vulnerability (GHSA-v2wj-7wpq-c8vv) via npm overrides forcing `dompurify@^3.3.2` -- `npm audit` now reports **0 vulnerabilities** +- **CVE 修复**:通过 npm 强制使用 `dompurify@^3.3.2` 解决了 dompurify XSS 漏洞(GHSA-v2wj-7wpq-c8vv) +- `npm audit` 现在报告 **0 个漏洞** -### 🧪 Tests +### 🧪 测试 -- Test suite: **923 tests, 0 failures** (+15 new model-combo mapping tests) +- 测试套件:**923 个测试,0 失败**(新增 15 个模型-combo 映射测试) --- ## [3.0.0-rc.14] — 2026-03-23 -### 🔀 Community PRs Merged +### 🔀 已合并的社区 PR -| PR | Author | Summary | -| -------- | -------- | -------------------------------------------------------------------------------------------- | -| **#562** | @coobabm | fix(ux): MCP session management, Claude passthrough normalization, OAuth modal, detectFormat | -| **#561** | @zen0bit | fix(i18n): Czech translation corrections — HTTP method names and documentation updates | +| PR | 作者 | 摘要 | +| -------- | -------- | -------------------------------------------------------------------- | +| **#562** | @coobabm | fix(ux): MCP 会话管理、Claude 透传规范化、OAuth 模态框、detectFormat | +| **#561** | @zen0bit | fix(i18n): 捷克语翻译修正 — HTTP 方法名称和文档更新 | -### 🧪 Tests +### 🧪 测试 -- Test suite: **908 tests, 0 failures** +- 测试套件:**908 个测试,0 失败** --- ## [3.0.0-rc.13] — 2026-03-23 -### 🔧 Bug Fixes +### 🔧 Bug 修复 -- **config:** resolve real API key from `keyId` in CLI settings routes (`codex-settings`, `droid-settings`, `kilo-settings`) to prevent writing masked strings (#549) +- **config:** 在 CLI 设置路由(`codex-settings`、`droid-settings`、`kilo-settings`)中从 `keyId` 解析真实 API key,防止写入脱敏字符串 (#549) --- ## [3.0.0-rc.12] — 2026-03-23 -### 🔀 Community PRs Merged +### 🔀 已合并的社区 PR -| PR | Author | Summary | -| -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **#546** | @k0valik | fix(cli): `--version` returning `unknown` on Windows — use `JSON.parse(readFileSync)` instead of ESM import | -| **#555** | @k0valik | fix(sse): centralized `resolveDataDir()` for path resolution in credentials, autoCombo, responses logger, and request logger | -| **#544** | @k0valik | fix(cli): secure CLI tool detection via known installation paths (8 tools) with symlink validation, file-type checks, size bounds, minimal env in healthcheck | -| **#542** | @rdself | fix(ui): improve light mode contrast — add missing CSS theme variables (`bg-primary`, `bg-subtle`, `text-primary`) and fix dark-only colors in log detail | +| PR | 作者 | 摘要 | +| -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- | +| **#546** | @k0valik | fix(cli): Windows 上 `--version` 返回 `unknown` — 使用 `JSON.parse(readFileSync)` 替代 ESM import | +| **#555** | @k0valik | fix(sse): 集中化 `resolveDataDir()` 用于路径解析,包括 credentials、autoCombo、响应 logger 和请求 logger | +| **#544** | @k0valik | fix(cli): 通过已知安装路径(8 个工具)进行安全的 CLI 工具检测,包括符号链接验证、文件类型检查、大小边界、健康检查中的最小环境检测 | +| **#542** | @rdself | fix(ui): 改善浅色模式对比度 — 添加缺失的 CSS 主题变量(`bg-primary`、`bg-subtle`、`text-primary`)并修复日志详情中仅暗色的颜色 | -### 🔧 Bug Fixes +### 🔧 Bug 修复 -- **TDZ fix in `cliRuntime.ts`** — `validateEnvPath` was used before initialization at module startup by `getExpectedParentPaths()`. Reordered declarations to fix `ReferenceError`. -- **Build fixes** — Added `pino` and `pino-pretty` to `serverExternalPackages` to prevent Turbopack from breaking Pino's internal worker loading. +- **TDZ 修复(`cliRuntime.ts`)** — `validateEnvPath` 在模块启动时被 `getExpectedParentPaths()` 使用前未初始化。重新排序声明以修复 `ReferenceError`。 +- **构建修复** — 将 `pino` 和 `pino-pretty` 添加到 `serverExternalPackages` 以防止 Turbopack 破坏 Pino 的内部 worker 加载。 -### 🧪 Tests +### 🧪 测试 -- Test suite: **905 tests, 0 failures** +- 测试套件:**905 个测试,0 失败** --- ## [3.0.0-rc.10] — 2026-03-23 -### 🔧 Bug Fixes +### 🔧 Bug 修复 -- **#509 / #508** — Electron build regression: downgraded Next.js from `16.1.x` to `16.0.10` to eliminate Turbopack module-hashing instability that caused blank screens in the Electron desktop bundle. -- **Unit test fixes** — Corrected two stale test assertions (`nanobanana-image-handler` aspect ratio/resolution, `thinking-budget` Gemini `thinkingConfig` field mapping) that had drifted after recent implementation changes. -- **#541** — Responded to user feedback about installation complexity; no code changes required. +- **#509 / #508** — Electron 构建回归:将 Next.js 从 `16.1.x` 降级到 `16.0.10` 以消除 Turbopack 模块哈希不稳定问题,该问题导致 Electron 桌面包出现白屏。 +- **单元测试修复** — 修正了两个过时的测试断言(`nanobanana-image-handler` 宽高比/分辨率、`thinking-budget` Gemini `thinkingConfig` 字段映射),这些在最近的实现变更后已偏离。 +- **#541** — 回复了用户关于安装复杂度的反馈;无需代码变更。 --- ## [3.0.0-rc.9] — 2026-03-23 -### ✨ New Features +### ✨ 新特性 -- **T29** — Vertex AI SA JSON Executor: implemented using the `jose` library to handle JWT/Service Account auth, along with configurable regions in the UI and automatic partner model URL building. -- **T42** — Image generation aspect ratio mapping: created `sizeMapper` logic for generic OpenAI formats (`size`), added native `imagen3` handling, and updated NanoBanana endpoints to utilize mapped aspect ratios automatically. -- **T38** — Centralized model specifications: `modelSpecs.ts` created for limits and parameters per model. +- **T29** — Vertex AI 服务账户 JSON 执行器:使用 `jose` 库处理 JWT/服务账户认证,以及 UI 中可配置的区域和自动伙伴模型 URL 构建。 +- **T42** — 图像生成长宽比映射:为通用 OpenAI 格式(`size`)创建了 `sizeMapper` 逻辑,添加了原生 `imagen3` 处理,并更新 NanoBanana 端点以自动使用映射的长宽比。 +- **T38** — 集中化模型规格定义:创建 `modelSpecs.ts` 用于每个模型的限额和参数。 -### 🔧 Improvements +### 🔧 改进 -- **T40** — OpenCode CLI tools integration: native `opencode-zen` and `opencode-go` integration completed in earlier PR. +- **T40** — OpenCode CLI 工具集成:在之前的 PR 中已完成原生 `opencode-zen` 和 `opencode-go` 集成。 --- ## [3.0.0-rc.8] — 2026-03-23 -### 🔧 Bug Fixes & Improvements (Fallback, Quota & Budget) +### 🔧 Bug 修复与改进(回退、配额与预算) -- **T24** — `503` cooldown await fix + `406` mapping: mapped `406 Not Acceptable` to `503 Service Unavailable` with proper cooldown intervals. -- **T25** — Provider validation fallback: graceful fallback to standard validation models when a specific `validationModelId` is not present. -- **T36** — `403` vs `429` provider handling refinement: extracted into `errorClassifier.ts` to properly segregate hard permissions failures (`403`) from rate limits (`429`). -- **T39** — Endpoint Fallback for `fetchAvailableModels`: implemented a tri-tier mechanism (`/models` -> `/v1/models` -> local generic catalog) + `list_models_catalog` MCP tool updates to reflect `source` and `warning`. -- **T33** — Thinking level to budget conversion: translates qualitative thinking levels into precise budget allocations. -- **T41** — Background task auto redirect: routes heavy background evaluation tasks to flash/efficient models automatically. -- **T23** — Intelligent quota reset fallback: accurately extracts `x-ratelimit-reset` / `retry-after` header values or maps static cooldowns. +- **T24** — `503` 冷却等待修复 + `406` 映射:将 `406 Not Acceptable` 映射为 `503 Service Unavailable`,并设置适当的冷却间隔。 +- **T25** — 提供商验证回退:当不存在特定的 `validationModelId` 时,优雅回退到标准验证模型。 +- **T36** — `403` 与 `429` 提供商处理优化:提取到 `errorClassifier.ts` 以正确隔离硬性权限失败(`403`)和速率限制(`429`)。 +- **T39** — `fetchAvailableModels` 端点回退:实现了三层机制(`/models` → `/v1/models` → 本地通用目录)+ 更新 `list_models_catalog` MCP 工具以反映 `source` 和 `warning`。 +- **T33** — Thinking 级别到预算转换:将定性 thinking 级别转换为精确的预算分配。 +- **T41** — 后台任务自动重定向:自动将沉重的后台评估任务路由到快速/高效模型。 +- **T23** — 智能配额重置回退:准确提取 `x-ratelimit-reset` / `retry-after` 请求头值或映射静态冷却时间。 --- -## [3.0.0-rc.7] — 2026-03-23 _(What's New vs v2.9.5 — will be released as v3.0.0)_ +## [3.0.0-rc.7] — 2026-03-23 _(相比 v2.9.5 的新增内容 — 将作为 v3.0.0 发布)_ -> **Upgrade from v2.9.5:** 16 issues resolved · 2 community PRs merged · 2 new providers · 7 new API endpoints · 3 new features · DB migration 008+009 · 832 tests passing · 15 sub2api gap improvements (T01–T15 complete). +> **从 v2.9.5 升级:** 16 个问题已解决 · 2 个社区 PR 已合并 · 2 个新提供商 · 7 个新 API 端点 · 3 个新功能 · 数据库迁移 008+009 · 832 个测试通过 · 15 项 sub2api 差距改进(T01–T15 完成)。 -### 🆕 New Providers +### 🆕 新提供商 -| Provider | Alias | Tier | Notes | -| ---------------- | -------------- | ---- | -------------------------------------------------------------- | -| **OpenCode Zen** | `opencode-zen` | Free | 3 models via `opencode.ai/zen/v1` (PR #530 by @kang-heewon) | -| **OpenCode Go** | `opencode-go` | Paid | 4 models via `opencode.ai/zen/go/v1` (PR #530 by @kang-heewon) | +| 提供商 | 别名 | 层级 | 说明 | +| ---------------- | -------------- | ---- | --------------------------------------------------------------------- | +| **OpenCode Zen** | `opencode-zen` | 免费 | 通过 `opencode.ai/zen/v1` 提供 3 个模型(PR #530 by @kang-heewon) | +| **OpenCode Go** | `opencode-go` | 付费 | 通过 `opencode.ai/zen/go/v1` 提供 4 个模型(PR #530 by @kang-heewon) | -Both providers use the new `OpencodeExecutor` with multi-format routing (`/chat/completions`, `/messages`, `/responses`, `/models/{model}:generateContent`). +两个提供商都使用新的 `OpencodeExecutor`,支持多格式路由(`/chat/completions`、`/messages`、`/responses`、`/models/{model}:generateContent`)。 --- -### ✨ New Features +### ✨ 新特性 #### 🔑 Registered Keys Provisioning API (#464) -Auto-generate and issue OmniRoute API keys programmatically with per-provider and per-account quota enforcement. +可通过编程方式自动生成并签发 OmniRoute API key,支持按提供商和账户进行配额限制。 -| Endpoint | Method | Description | -| ------------------------------------- | --------- | ------------------------------------------------ | -| `/api/v1/registered-keys` | `POST` | Issue a new key — raw key returned **once only** | -| `/api/v1/registered-keys` | `GET` | List registered keys (masked) | -| `/api/v1/registered-keys/{id}` | `GET` | Get key metadata | -| `/api/v1/registered-keys/{id}` | `DELETE` | Revoke a key | -| `/api/v1/registered-keys/{id}/revoke` | `POST` | Revoke (for clients without DELETE support) | -| `/api/v1/quotas/check` | `GET` | Pre-validate quota before issuing | -| `/api/v1/providers/{id}/limits` | `GET/PUT` | Configure per-provider issuance limits | -| `/api/v1/accounts/{id}/limits` | `GET/PUT` | Configure per-account issuance limits | -| `/api/v1/issues/report` | `POST` | Report quota events to GitHub Issues | +| 端点 | 方法 | 说明 | +| ------------------------------------- | --------- | ------------------------------------- | +| `/api/v1/registered-keys` | `POST` | 签发新 key —— 原始 key **只返回一次** | +| `/api/v1/registered-keys` | `GET` | 列出已注册 key(脱敏) | +| `/api/v1/registered-keys/{id}` | `GET` | 获取元数据 | +| `/api/v1/registered-keys/{id}` | `DELETE` | 吊销 key | +| `/api/v1/registered-keys/{id}/revoke` | `POST` | 吊销(适用于不支持 DELETE 的客户端) | +| `/api/v1/quotas/check` | `GET` | 签发前预检配额 | +| `/api/v1/providers/{id}/limits` | `GET/PUT` | 配置按提供商的签发限制 | +| `/api/v1/accounts/{id}/limits` | `GET/PUT` | 配置按账户的签发限制 | +| `/api/v1/issues/report` | `POST` | 向 GitHub Issues 报告配额事件 | -**DB — Migration 008:** Three new tables: `registered_keys`, `provider_key_limits`, `account_key_limits`. -**Security:** Keys stored as SHA-256 hashes. Raw key shown once on creation, never retrievable again. -**Quota types:** `maxActiveKeys`, `dailyIssueLimit`, `hourlyIssueLimit` per provider and per account. -**Idempotency:** `idempotency_key` field prevents duplicate issuance. Returns `409 IDEMPOTENCY_CONFLICT` if key was already used. -**Budget per key:** `dailyBudget` / `hourlyBudget` — limits how many requests a key can route per window. -**GitHub reporting:** Optional. Set `GITHUB_ISSUES_REPO` + `GITHUB_ISSUES_TOKEN` to auto-create GitHub issues on quota exceeded or issuance failures. +**数据库 — 迁移 008:** 三个新表:`registered_keys`、`provider_key_limits`、`account_key_limits`。 +**安全性:** key 以 SHA-256 哈希存储。原始 key 只在创建时展示一次,之后不可再取回。 +**配额类型:** 每个提供商和账户的 `maxActiveKeys`、`dailyIssueLimit`、`hourlyIssueLimit`。 +**幂等性:** `idempotency_key` 字段防止重复签发。如果 key 已被使用,返回 `409 IDEMPOTENCY_CONFLICT`。 +**每个 key 的预算:** `dailyBudget` / `hourlyBudget` —— 限制每个时间窗口内 key 可路由的请求数。 +**GitHub 报告:** 可选。设置 `GITHUB_ISSUES_REPO` + `GITHUB_ISSUES_TOKEN` 可在配额超出或签发失败时自动创建 GitHub issue。 -#### 🎨 Provider Icons — @lobehub/icons (#529) +#### 🎨 提供商图标 — @lobehub/icons (#529) -All provider icons in the dashboard now use `@lobehub/icons` React components (130+ providers with SVG). -Fallback chain: **Lobehub SVG → existing `/providers/{id}.png` → generic icon**. Uses a proper React `ErrorBoundary` pattern. +仪表盘中所有提供商图标现在使用 `@lobehub/icons` React 组件(130+ 个提供商,SVG 格式)。 +回退链:**Lobehub SVG → 现有 `/providers/{id}.png` → 通用图标**。使用标准的 React `ErrorBoundary` 模式。 -#### 🔄 Model Auto-Sync Scheduler (#488) +#### 🔄 模型自动同步调度器 (#488) -OmniRoute now automatically refreshes model lists for connected providers every **24 hours**. +OmniRoute 现在每 **24 小时**自动刷新已连接提供商的模型列表。 -- Runs on server startup via the existing `/api/sync/initialize` hook -- Configurable via `MODEL_SYNC_INTERVAL_HOURS` environment variable -- Covers 16 major providers -- Records last sync time in the settings database +- 通过现有的 `/api/sync/initialize` 钩子在服务器启动时运行 +- 可通过 `MODEL_SYNC_INTERVAL_HOURS` 环境变量配置 +- 覆盖 16 个主要提供商 +- 在设置数据库中记录最后同步时间 --- -### 🔧 Bug Fixes +### 🔧 Bug 修复 -#### OAuth & Auth +#### OAuth 与认证 -- **#537 — Gemini CLI OAuth:** Clear actionable error when `GEMINI_OAUTH_CLIENT_SECRET` is missing in Docker/self-hosted deployments. Previously showed cryptic `client_secret is missing` from Google. Now provides specific `docker-compose.yml` and `~/.omniroute/.env` instructions. +- **#537 — Gemini CLI OAuth:** 在 Docker/自托管部署中缺少 `GEMINI_OAUTH_CLIENT_SECRET` 时,现在会给出清晰且可操作的错误提示。此前会显示来自 Google 的神秘 `client_secret is missing` 错误。现在提供具体的 `docker-compose.yml` 和 `~/.omniroute/.env` 配置说明。 -#### Providers & Routing +#### 提供商与路由 -- **#536 — LongCat AI:** Fixed `baseUrl` (`api.longcat.chat/openai`) and `authHeader` (`Authorization: Bearer`). -- **#535 — Pinned model override:** `body.model` is now correctly set to `pinnedModel` when context-cache protection is active. -- **#532 — OpenCode Go key validation:** Now uses the `zen/v1` test endpoint (`testKeyBaseUrl`) — same key works for both tiers. +- **#536 — LongCat AI:** 修复了 `baseUrl`(`api.longcat.chat/openai`)和 `authHeader`(`Authorization: Bearer`)。 +- **#535 — 固定模型覆盖:** 当 context-cache 保护激活时,`body.model` 现在会正确设置为 `pinnedModel`。 +- **#532 — OpenCode Go key 验证:** 现在使用 `zen/v1` 测试端点(`testKeyBaseUrl`)—— 同一个 key 适用于两个层级。 -#### CLI & Tools +#### CLI 与工具 -- **#527 — Claude Code + Codex loop:** `tool_result` blocks are now converted to text instead of dropped, stopping infinite tool-result loops. -- **#524 — OpenCode config save:** Added `saveOpenCodeConfig()` handler (XDG_CONFIG_HOME aware, writes TOML). -- **#521 — Login stuck:** Login no longer freezes after skipping password setup — redirects correctly to onboarding. -- **#522 — API Manager:** Removed misleading "Copy masked key" button (replaced with a lock icon tooltip). -- **#532 — OpenCode Go config:** Guide settings handler now handles `opencode` toolId. +- **#527 — Claude Code + Codex 循环:** `tool_result` 块现在会被转换为文本而不是被丢弃,从而阻止无限工具结果循环。 +- **#524 — OpenCode 配置保存:** 添加了 `saveOpenCodeConfig()` 处理器(XDG_CONFIG_HOME 感知,写入 TOML 格式)。 +- **#521 — 登录卡死:** 跳过密码设置后登录不再卡死 —— 现在正确重定向到引导页面。 +- **#522 — API Manager:** 移除了具有误导性的 "Copy masked key" 按钮(替换为锁图标提示)。 +- **#532 — OpenCode Go 配置:** 引导设置处理器现在处理 `opencode` toolId。 -#### Developer Experience +#### 开发者体验 -- **#489 — Antigravity:** Missing `googleProjectId` returns a structured 422 error with reconnect guidance instead of a cryptic crash. -- **#510 — Windows paths:** MSYS2/Git-Bash paths (`/c/Program Files/...`) are now normalized to `C:\\Program Files\\...` automatically. -- **#492 — CLI startup:** `omniroute` CLI now detects `mise`/`nvm`-managed Node when `app/server.js` is missing and shows targeted fix instructions. +- **#489 — Antigravity:** 缺少 `googleProjectId` 时返回结构化的 422 错误,附带重新连接指导,而不是神秘崩溃。 +- **#510 — Windows 路径:** MSYS2/Git-Bash 路径(`/c/Program Files/...`)现在会自动规范化为 `C:\\Program Files\\...`。 +- **#492 — CLI 启动:** 当 `app/server.js` 缺失时,`omniroute` CLI 现在能检测由 `mise`/`nvm` 管理的 Node,并显示针对性的修复说明。 --- -### 📖 Documentation Updates +### 📖 文档更新 -- **#513** — Docker password reset: `INITIAL_PASSWORD` env var workaround documented -- **#520** — pnpm: `pnpm approve-builds better-sqlite3` step documented +- **#513** —— Docker 密码重置:记录了 `INITIAL_PASSWORD` 环境变量解决方案 +- **#520** —— pnpm:记录了 `pnpm approve-builds better-sqlite3` 步骤 --- -### ✅ Issues Resolved in v3.0.0 +### ✅ 在 v3.0.0 中解决的问题 `#464` `#488` `#489` `#492` `#510` `#513` `#520` `#521` `#522` `#524` `#527` `#529` `#532` `#535` `#536` `#537` --- -### 🔀 Community PRs Merged +### 🔀 已合并的社区 PR -| PR | Author | Summary | -| -------- | ------------ | ---------------------------------------------------------------------- | -| **#530** | @kang-heewon | OpenCode Zen + Go providers with `OpencodeExecutor` and improved tests | +| PR | 作者 | 摘要 | +| -------- | ------------ | --------------------------------------------------------------- | +| **#530** | @kang-heewon | 使用 `OpencodeExecutor` 的 OpenCode Zen + Go 提供商,改进了测试 | --- ## [3.0.0-rc.7] - 2026-03-23 -### 🔧 Improvements (sub2api Gap Analysis — T05, T08, T09, T13, T14) +### 🔧 改进(sub2api 差距分析 — T05, T08, T09, T13, T14) -- **T05** — Rate-limit DB persistence: `setConnectionRateLimitUntil()`, `isConnectionRateLimited()`, `getRateLimitedConnections()` in `providers.ts`. The existing `rate_limited_until` column is now exposed as a dedicated API — OAuth token refresh must NOT touch this field to prevent rate-limit loops. -- **T08** — Per-API-key session limit: `max_sessions INTEGER DEFAULT 0` added to `api_keys` via auto-migration. `sessionManager.ts` gains `registerKeySession()`, `unregisterKeySession()`, `checkSessionLimit()`, and `getActiveSessionCountForKey()`. Callers in `chatCore.js` can enforce the limit and decrement on `req.close`. -- **T09** — Codex vs Spark rate-limit scopes: `getCodexModelScope()` and `getCodexRateLimitKey()` in `codex.ts`. Standard models (`gpt-5.x-codex`, `codex-mini`) get scope `"codex"`; spark models (`codex-spark*`) get scope `"spark"`. Rate-limit keys should be `${accountId}:${scope}` so exhausting one pool doesn't block the other. -- **T13** — Stale quota display fix: `getEffectiveQuotaUsage(used, resetAt)` returns `0` when the reset window has passed; `formatResetCountdown(resetAt)` returns a human-readable countdown string (e.g. `"2h 35m"`). Both exported from `providers.ts` + `localDb.ts` for dashboard consumption. -- **T14** — Proxy fast-fail: new `src/lib/proxyHealth.ts` with `isProxyReachable(proxyUrl, timeoutMs=2000)` (TCP check, ≤2s instead of 30s timeout), `getCachedProxyHealth()`, `invalidateProxyHealth()`, and `getAllProxyHealthStatuses()`. Results cached 30s by default; configurable via `PROXY_FAST_FAIL_TIMEOUT_MS` / `PROXY_HEALTH_CACHE_TTL_MS`. +- **T05** — 限流数据库持久化:`setConnectionRateLimitUntil()`、`isConnectionRateLimited()`、`getRateLimitedConnections()` 在 `providers.ts` 中。现有的 `rate_limited_until` 列现在作为专用 API 公开 — OAuth token 刷新绝不能触碰此字段,以防止限流循环。 +- **T08** — 每 API key 会话限制:通过自动迁移在 `api_keys` 中新增 `max_sessions INTEGER DEFAULT 0`。`sessionManager.ts` 新增 `registerKeySession()`、`unregisterKeySession()`、`checkSessionLimit()` 和 `getActiveSessionCountForKey()`。`chatCore.js` 中的调用方可以强制执行该限制并在 `req.close` 时递减。 +- **T09** — Codex 与 Spark 限流范围分离:`codex.ts` 中的 `getCodexModelScope()` 和 `getCodexRateLimitKey()`。标准模型(`gpt-5.x-codex`、`codex-mini`)获得范围 `"codex"`;spark 模型(`codex-spark*`)获得范围 `"spark"`。限流 key 应为 `${accountId}:${scope}`,这样耗尽一个池不会阻塞另一个。 +- **T13** — 过期配额显示修复:当重置窗口已过时,`getEffectiveQuotaUsage(used, resetAt)` 返回 `0`;`formatResetCountdown(resetAt)` 返回人类可读的倒计时字符串(例如 `"2h 35m"`)。两者都从 `providers.ts` + `localDb.ts` 导出,供仪表盘使用。 +- **T14** — 代理快速失败:新增 `src/lib/proxyHealth.ts`,包含 `isProxyReachable(proxyUrl, timeoutMs=2000)`(TCP 检查,≤2 秒而非 30 秒超时)、`getCachedProxyHealth()`、`invalidateProxyHealth()` 和 `getAllProxyHealthStatuses()`。结果默认缓存 30 秒;可通过 `PROXY_FAST_FAIL_TIMEOUT_MS` / `PROXY_HEALTH_CACHE_TTL_MS` 配置。 -### 🧪 Tests +### 🧪 测试 -- Test suite: **832 tests, 0 failures** +- 测试套件:**832 个测试,0 失败** --- ## [3.0.0-rc.6] - 2026-03-23 -### 🔧 Bug Fixes & Improvements (sub2api Gap Analysis — T01–T15) +### 🔧 Bug 修复与改进(sub2api 差距分析 — T01–T15) -- **T01** — `requested_model` column in `call_logs` (migration 009): track which model the client originally requested vs the actual routed model. Enables fallback rate analytics. -- **T02** — Strip empty text blocks from nested `tool_result.content`: prevents Anthropic 400 errors (`text content blocks must be non-empty`) when Claude Code chains tool results. -- **T03** — Parse `x-codex-5h-*` / `x-codex-7d-*` headers: `parseCodexQuotaHeaders()` + `getCodexResetTime()` extract Codex quota windows for precise cooldown scheduling instead of generic 5-min fallback. -- **T04** — `X-Session-Id` header for external sticky routing: `extractExternalSessionId()` in `sessionManager.ts` reads `x-session-id` / `x-omniroute-session` headers with `ext:` prefix to avoid collision with internal SHA-256 session IDs. Nginx-compatible (hyphenated header). -- **T06** — Account deactivated → permanent block: `isAccountDeactivated()` in `accountFallback.ts` detects 401 deactivation signals and applies a 1-year cooldown to prevent retrying permanently dead accounts. -- **T07** — X-Forwarded-For IP validation: new `src/lib/ipUtils.ts` with `extractClientIp()` and `getClientIpFromRequest()` — skips `unknown`/non-IP entries in `X-Forwarded-For` chains (Nginx/proxy-forwarded requests). -- **T10** — Credits exhausted → distinct fallback: `isCreditsExhausted()` in `accountFallback.ts` returns 1h cooldown with `creditsExhausted` flag, distinct from generic 429 rate limiting. -- **T11** — `max` reasoning effort → 131072 budget tokens: `EFFORT_BUDGETS` and `THINKING_LEVEL_MAP` updated; reverse mapping now returns `"max"` for full-budget responses. Unit test updated. -- **T12** — MiniMax M2.7 pricing entries added: `minimax-m2.7`, `MiniMax-M2.7`, `minimax-m2.7-highspeed` added to pricing table (sub2api PR #1120). M2.5/GLM-4.7/GLM-5/Kimi pricing already existed. -- **T15** — Array content normalization: `normalizeContentToString()` helper in `openai-to-claude.ts` correctly collapses array-formatted system/tool messages to string before sending to Anthropic. +- **T01** — `call_logs` 中的 `requested_model` 列(迁移 009):跟踪客户端最初请求的模型与实际路由的模型。启用回退速率分析。 +- **T02** — 从嵌套的 `tool_result.content` 中剥离空文本块:防止 Claude Code 链式工具结果时出现 Anthropic 400 错误(`text content blocks must be non-empty`)。 +- **T03** — 解析 `x-codex-5h-*` / `x-codex-7d-*` 请求头:`parseCodexQuotaHeaders()` + `getCodexResetTime()` 提取 Codex 配额窗口,用于精确冷却调度,而非通用的 5 分钟回退。 +- **T04** — 用于外部粘性路由的 `X-Session-Id` 请求头:`sessionManager.ts` 中的 `extractExternalSessionId()` 读取 `x-session-id` / `x-omniroute-session` 请求头,使用 `ext:` 前缀以避免与内部 SHA-256 会话 ID 冲突。兼容 Nginx(连字符请求头)。 +- **T06** — 账户停用 → 永久封锁:`accountFallback.ts` 中的 `isAccountDeactivated()` 检测 401 停用信号并应用 1 年冷却,以防止重试永久失效的账户。 +- **T07** — X-Forwarded-For IP 验证:新增 `src/lib/ipUtils.ts`,包含 `extractClientIp()` 和 `getClientIpFromRequest()` — 跳过 `X-Forwarded-For` 链中的 `unknown`/非 IP 条目(Nginx/代理转发的请求)。 +- **T10** — 积分耗尽 → 独立的回退:`accountFallback.ts` 中的 `isCreditsExhausted()` 返回 1 小时冷却,带有 `creditsExhausted` 标志,区别于通用的 429 限流。 +- **T11** — `max` 推理努力 → 131072 预算 token:更新了 `EFFORT_BUDGETS` 和 `THINKING_LEVEL_MAP`;反向映射现在为全预算响应返回 `"max"`。单元测试已更新。 +- **T12** — 新增 MiniMax M2.7 定价条目:`minimax-m2.7`、`MiniMax-M2.7`、`minimax-m2.7-highspeed` 已添加到定价表(sub2api PR #1120)。M2.5/GLM-4.7/GLM-5/Kimi 定价已存在。 +- **T15** — 数组内容规范化:`openai-to-claude.ts` 中的 `normalizeContentToString()` 辅助函数正确地将数组格式化的系统/工具消息折叠为字符串,然后再发送给 Anthropic。 -### 🧪 Tests +### 🧪 测试 -- Test suite: **832 tests, 0 failures** (unchanged from rc.5) +- 测试套件:**832 个测试,0 失败**(与 rc.5 持平) --- ## [3.0.0-rc.5] - 2026-03-22 -### ✨ New Features +### ✨ 新特性 -- **#464** — Registered Keys Provisioning API: auto-issue API keys with per-provider & per-account quota enforcement - - `POST /api/v1/registered-keys` — issue keys with idempotency support - - `GET /api/v1/registered-keys` — list (masked) registered keys - - `GET /api/v1/registered-keys/{id}` — get key metadata - - `DELETE /api/v1/registered-keys/{id}` / `POST ../{id}/revoke` — revoke keys - - `GET /api/v1/quotas/check` — pre-validate before issuing - - `PUT /api/v1/providers/{id}/limits` — set provider issuance limits - - `PUT /api/v1/accounts/{id}/limits` — set account issuance limits - - `POST /api/v1/issues/report` — optional GitHub issue reporting - - DB migration 008: `registered_keys`, `provider_key_limits`, `account_key_limits` tables +- **#464** — Registered Keys Provisioning API:自动签发 API key,支持按提供商和账户进行配额限制 + - `POST /api/v1/registered-keys` — 签发 key,支持幂等性 + - `GET /api/v1/registered-keys` — 列出已注册 key(脱敏) + - `GET /api/v1/registered-keys/{id}` — 获取 key 元数据 + - `DELETE /api/v1/registered-keys/{id}` / `POST ../{id}/revoke` — 吊销 key + - `GET /api/v1/quotas/check` — 签发前预检 + - `PUT /api/v1/providers/{id}/limits` — 设置提供商签发限制 + - `PUT /api/v1/accounts/{id}/limits` — 设置账户签发限制 + - `POST /api/v1/issues/report` — 可选的 GitHub issue 报告 + - 数据库迁移 008:`registered_keys`、`provider_key_limits`、`account_key_limits` 表 --- ## [3.0.0-rc.4] - 2026-03-22 -### ✨ New Features +### ✨ 新特性 -- **#530 (PR)** — OpenCode Zen and OpenCode Go providers added (by @kang-heewon) - - New `OpencodeExecutor` with multi-format routing (`/chat/completions`, `/messages`, `/responses`) - - 7 models across both tiers +- **#530 (PR)** — 新增 OpenCode Zen 和 OpenCode Go 提供商(by @kang-heewon) + - 新的 `OpencodeExecutor`,支持多格式路由(`/chat/completions`、`/messages`、`/responses`) + - 两个层级共 7 个模型 --- ## [3.0.0-rc.3] - 2026-03-22 -### ✨ New Features +### ✨ 新特性 -- **#529** — Provider icons now use [@lobehub/icons](https://github.com/lobehub/lobe-icons) with graceful PNG fallback and a `ProviderIcon` component (130+ providers supported) -- **#488** — Auto-update model lists every 24h via `modelSyncScheduler` (configurable via `MODEL_SYNC_INTERVAL_HOURS`) +- **#529** — 提供商图标现在使用 [@lobehub/icons](https://github.com/lobehub/lobe-icons),支持优雅的 PNG 回退和 `ProviderIcon` 组件(支持 130+ 个提供商) +- **#488** — 每 24 小时通过 `modelSyncScheduler` 自动更新模型列表(可通过 `MODEL_SYNC_INTERVAL_HOURS` 配置) -### 🔧 Bug Fixes +### 🔧 Bug 修复 -- **#537** — Gemini CLI OAuth: now shows clear actionable error when `GEMINI_OAUTH_CLIENT_SECRET` is missing in Docker/self-hosted deployments +- **#537** — Gemini CLI OAuth:在 Docker/自托管部署中缺少 `GEMINI_OAUTH_CLIENT_SECRET` 时,现在会显示清晰且可操作的错误提示 --- ## [3.0.0-rc.2] - 2026-03-22 -### 🔧 Bug Fixes +### 🔧 Bug 修复 -- **#536** — LongCat AI key validation: fixed baseUrl (`api.longcat.chat/openai`) and authHeader (`Authorization: Bearer`) -- **#535** — Pinned model override: `body.model` is now set to `pinnedModel` when context-cache protection detects a pinned model -- **#524** — OpenCode config now saved correctly: added `saveOpenCodeConfig()` handler (XDG_CONFIG_HOME aware, writes TOML) +- **#536** — LongCat AI key 验证:修复了 baseUrl(`api.longcat.chat/openai`)和 authHeader(`Authorization: Bearer`) +- **#535** — 固定模型覆盖:当 context-cache 保护检测到固定模型时,`body.model` 现在设置为 `pinnedModel` +- **#524** — OpenCode 配置现在正确保存:添加了 `saveOpenCodeConfig()` 处理器(XDG_CONFIG_HOME 感知,写入 TOML 格式) --- ## [3.0.0-rc.1] - 2026-03-22 -### 🔧 Bug Fixes +### 🔧 Bug 修复 -- **#521** — Login no longer gets stuck after skipping password setup (redirects to onboarding) -- **#522** — API Manager: Removed misleading "Copy masked key" button (replaced with lock icon tooltip) -- **#527** — Claude Code + Codex superpowers loop: `tool_result` blocks now converted to text instead of dropped -- **#532** — OpenCode GO API key validation now uses the correct `zen/v1` endpoint (`testKeyBaseUrl`) -- **#489** — Antigravity: missing `googleProjectId` returns structured 422 error with reconnect guidance -- **#510** — Windows: MSYS2/Git-Bash paths (`/c/Program Files/...`) are now normalized to `C:\\Program Files\\...` -- **#492** — `omniroute` CLI now detects `mise`/`nvm` when `app/server.js` is missing and shows targeted fix +- **#521** — 跳过密码设置后登录不再卡死(重定向到引导页面) +- **#522** — API Manager:移除了具有误导性的 "Copy masked key" 按钮(替换为锁图标提示) +- **#527** — Claude Code + Codex 超级能力循环:`tool_result` 块现在转换为文本而不是被丢弃 +- **#532** — OpenCode GO API key 验证现在使用正确的 `zen/v1` 端点(`testKeyBaseUrl`) +- **#489** — Antigravity:缺少 `googleProjectId` 时返回结构化的 422 错误,附带重新连接指导 +- **#510** — Windows:MSYS2/Git-Bash 路径(`/c/Program Files/...`)现在自动规范化为 `C:\\Program Files\\...` +- **#492** — `omniroute` CLI 现在在 `app/server.js` 缺失时能检测 `mise`/`nvm`,并显示针对性的修复说明 -### 文档 +### 📖 文档 -- **#513** — Docker password reset: `INITIAL_PASSWORD` env var workaround documented -- **#520** — pnpm: `pnpm approve-builds better-sqlite3` documented +- **#513** —— Docker 密码重置:记录了 `INITIAL_PASSWORD` 环境变量解决方案 +- **#520** —— pnpm:记录了 `pnpm approve-builds better-sqlite3` 步骤 -### ✅ Closed Issues +### ✅ 已关闭的问题 #489, #492, #510, #513, #520, #521, #522, #525, #527, #532 @@ -1267,665 +1323,665 @@ OmniRoute now automatically refreshes model lists for connected providers every ## [2.9.5] — 2026-03-22 -> Sprint: New OpenCode providers, embedding credentials fix, CLI masked key bug, CACHE_TAG_PATTERN fix. +> Sprint:新增 OpenCode 提供商、embedding 凭证修复、CLI 脱敏 key bug、CACHE_TAG_PATTERN 修复。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **CLI tools save masked API key to config files** — `claude-settings`, `cline-settings`, and `openclaw-settings` POST routes now accept a `keyId` param and resolve the real API key from DB before writing to disk. `ClaudeToolCard` updated to send `keyId` instead of the masked display string. Fixes #523, #526. -- **Custom embedding providers: `No credentials` error** — `/v1/embeddings` now tracks `credentialsProviderId` separately from the routing prefix, so credentials are fetched from the matching provider node ID rather than the public prefix string. Fixes a regression where `google/gemini-embedding-001` and similar custom-provider models would always fail with a credentials error. Fixes #532-related. (PR #528 by @jacob2826) -- **Context cache protection regex misses `\n` prefix** — `CACHE_TAG_PATTERN` in `comboAgentMiddleware.ts` updated to match both literal `\n` (backslash-n) and actual newline U+000A that `combo.ts` streaming injects around the `` tag after fix #515. Fixes #531. +- **CLI 工具将脱敏 API key 保存到配置文件** — `claude-settings`、`cline-settings` 和 `openclaw-settings` POST 路由现在接受 `keyId` 参数,并在写入磁盘前从数据库解析真实 API key。`ClaudeToolCard` 更新为发送 `keyId` 而不是脱敏显示字符串。修复 #523、#526。 +- **自定义 embedding 提供商:`No credentials` 错误** — `/v1/embeddings` 现在将 `credentialsProviderId` 与路由前缀分开跟踪,因此凭证从匹配的提供商节点 ID 获取,而不是从公开前缀字符串获取。修复了一个回归问题:`google/gemini-embedding-001` 和类似的自定义提供商模型总是会因凭证错误而失败。修复 #532 相关问题。(PR #528 by @jacob2826) +- **Context 缓存保护正则表达式遗漏 `\n` 前缀** — `comboAgentMiddleware.ts` 中的 `CACHE_TAG_PATTERN` 更新为同时匹配字面量 `\n`(反斜杠-n)和实际的换行符 U+000A,`combo.ts` 流式传输在修复 #515 后会在 `` 标签周围注入这些字符。修复 #531。 -### ✨ New Providers +### ✨ 新提供商 -- **OpenCode Zen** — Free tier gateway at `opencode.ai/zen/v1` with 3 models: `minimax-m2.5-free`, `big-pickle`, `gpt-5-nano` -- **OpenCode Go** — Subscription service at `opencode.ai/zen/go/v1` with 4 models: `glm-5`, `kimi-k2.5`, `minimax-m2.7` (Claude format), `minimax-m2.5` (Claude format) -- Both providers use the new `OpencodeExecutor` which routes dynamically to `/chat/completions`, `/messages`, `/responses`, or `/models/{model}:generateContent` based on the requested model. (PR #530 by @kang-heewon) +- **OpenCode Zen** — 免费层网关位于 `opencode.ai/zen/v1`,提供 3 个模型:`minimax-m2.5-free`、`big-pickle`、`gpt-5-nano` +- **OpenCode Go** — 订阅服务位于 `opencode.ai/zen/go/v1`,提供 4 个模型:`glm-5`、`kimi-k2.5`、`minimax-m2.7`(Claude 格式)、`minimax-m2.5`(Claude 格式) +- 两个提供商都使用新的 `OpencodeExecutor`,根据请求的模型动态路由到 `/chat/completions`、`/messages`、`/responses` 或 `/models/{model}:generateContent`。(PR #530 by @kang-heewon) --- ## [2.9.4] — 2026-03-21 -> Sprint: Bug fixes — preserve Codex prompt cache key, fix tagContent JSON escaping, sync expired token status to DB. +> Sprint:Bug 修复 — 保留 Codex prompt 缓存 key、修复 tagContent JSON 转义、将过期 token 状态同步回数据库。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(translator)**: Preserve `prompt_cache_key` in Responses API → Chat Completions translation (#517) - — The field is a cache-affinity signal used by Codex; stripping it was preventing prompt cache hits. - Fixed in `openai-responses.ts` and `responsesApiHelper.ts`. +- **fix(translator)**:在 Responses API → Chat Completions 翻译中保留 `prompt_cache_key`(#517) + — 该字段是 Codex 使用的缓存亲和性信号;剥离它会阻止 prompt 缓存命中。 + 在 `openai-responses.ts` 和 `responsesApiHelper.ts` 中修复。 -- **fix(combo)**: Escape `\n` in `tagContent` so injected JSON string is valid (#515) - — Template literal newlines (U+000A) are not allowed unescaped inside JSON string values. - Replaced with `\\n` literal sequences in `open-sse/services/combo.ts`. +- **fix(combo)**:转义 `tagContent` 中的 `\n`,使注入的 JSON 字符串有效(#515) + — 模板字面量换行符(U+000A)不允许在 JSON 字符串值中不转义使用。 + 在 `open-sse/services/combo.ts` 中替换为 `\\n` 字面量序列。 -- **fix(usage)**: Sync expired token status back to DB on live auth failure (#491) - — When the Limits & Quotas live check returns 401/403, the connection `testStatus` is now updated - to `"expired"` in the database so the Providers page reflects the same degraded state. - Fixed in `src/app/api/usage/[connectionId]/route.ts`. +- **fix(usage)**:在实时认证失败时将过期 token 状态同步回数据库(#491) + — 当 Limits & Quotas 实时检查返回 401/403 时,连接的 `testStatus` 现在会更新 + 为数据库中的 `"expired"`,以便提供商页面反映相同的降级状态。 + 在 `src/app/api/usage/[connectionId]/route.ts` 中修复。 --- ## [2.9.3] — 2026-03-21 -> Sprint: Add 5 new free AI providers — LongCat, Pollinations, Cloudflare AI, Scaleway, AI/ML API. +> Sprint:新增 5 个免费 AI 提供商 — LongCat、Pollinations、Cloudflare AI、Scaleway、AI/ML API。 -### ✨ New Providers +### ✨ 新提供商 -- **feat(providers/longcat)**: Add LongCat AI (`lc/`) — 50M tokens/day free (Flash-Lite) + 500K/day (Chat/Thinking) during public beta. OpenAI-compatible, standard Bearer auth. -- **feat(providers/pollinations)**: Add Pollinations AI (`pol/`) — no API key required. Proxies GPT-5, Claude, Gemini, DeepSeek V3, Llama 4 (1 req/15s free). Custom executor handles optional auth. -- **feat(providers/cloudflare-ai)**: Add Cloudflare Workers AI (`cf/`) — 10K Neurons/day free (~150 LLM responses or 500s Whisper audio). 50+ models on global edge. Custom executor builds dynamic URL with `accountId` from credentials. -- **feat(providers/scaleway)**: Add Scaleway Generative APIs (`scw/`) — 1M free tokens for new accounts. EU/GDPR compliant (Paris). Qwen3 235B, Llama 3.1 70B, Mistral Small 3.2. -- **feat(providers/aimlapi)**: Add AI/ML API (`aiml/`) — $0.025/day free credit, 200+ models (GPT-4o, Claude, Gemini, Llama) via single aggregator endpoint. +- **feat(providers/longcat)**:新增 LongCat AI(`lc/`)— 公测期间每天 5000 万 tokens 免费(Flash-Lite)+ 50 万/天(Chat/Thinking)。OpenAI 兼容,标准 Bearer 认证。 +- **feat(providers/pollinations)**:新增 Pollinations AI(`pol/`)— 无需 API key。代理 GPT-5、Claude、Gemini、DeepSeek V3、Llama 4(1 次/15 秒免费)。自定义执行器处理可选认证。 +- **feat(providers/cloudflare-ai)**:新增 Cloudflare Workers AI(`cf/`)— 每天 10K Neurons 免费(约 150 次 LLM 响应或 500 秒 Whisper 音频)。全球边缘 50+ 模型。自定义执行器从凭证中构建带 `accountId` 的动态 URL。 +- **feat(providers/scaleway)**:新增 Scaleway 生成式 API(`scw/`)— 新账户 100 万免费 tokens。符合 EU/GDPR(巴黎)。Qwen3 235B、Llama 3.1 70B、Mistral Small 3.2。 +- **feat(providers/aimlapi)**:新增 AI/ML API(`aiml/`)— 每天 $0.025 免费额度,200+ 模型(GPT-4o、Claude、Gemini、Llama),通过单一聚合端点。 -### 🔄 Provider Updates +### 🔄 提供商更新 -- **feat(providers/together)**: Add `hasFree: true` + 3 permanently free model IDs: `Llama-3.3-70B-Instruct-Turbo-Free`, `Llama-Vision-Free`, `DeepSeek-R1-Distill-Llama-70B-Free` -- **feat(providers/gemini)**: Add `hasFree: true` + `freeNote` (1,500 req/day, no credit card needed, aistudio.google.com) -- **chore(providers/gemini)**: Rename display name to `Gemini (Google AI Studio)` for clarity +- **feat(providers/together)**:新增 `hasFree: true` + 3 个永久免费模型 ID:`Llama-3.3-70B-Instruct-Turbo-Free`、`Llama-Vision-Free`、`DeepSeek-R1-Distill-Llama-70B-Free` +- **feat(providers/gemini)**:新增 `hasFree: true` + `freeNote`(每天 1500 次请求,无需信用卡,aistudio.google.com) +- **chore(providers/gemini)**:将显示名称重命名为 `Gemini (Google AI Studio)` 以提高清晰度 -### ⚙️ Infrastructure +### ⚙️ 基础设施 -- **feat(executors/pollinations)**: New `PollinationsExecutor` — omits `Authorization` header when no API key provided -- **feat(executors/cloudflare-ai)**: New `CloudflareAIExecutor` — dynamic URL construction requires `accountId` in provider credentials -- **feat(executors)**: Register `pollinations`, `pol`, `cloudflare-ai`, `cf` executor mappings +- **feat(executors/pollinations)**:新增 `PollinationsExecutor` — 未提供 API key 时省略 `Authorization` 请求头 +- **feat(executors/cloudflare-ai)**:新增 `CloudflareAIExecutor` — 动态 URL 构建需要提供商凭证中的 `accountId` +- **feat(executors)**:注册 `pollinations`、`pol`、`cloudflare-ai`、`cf` 执行器映射 -### 文档 +### 📝 文档 -- **docs(readme)**: Expanded free combo stack to 11 providers ($0 forever) -- **docs(readme)**: Added 4 new free provider sections (LongCat, Pollinations, Cloudflare AI, Scaleway) with model tables -- **docs(readme)**: Updated pricing table with 4 new free tier rows -- **docs(i18n/pt-BR)**: Updated pricing table + added LongCat/Pollinations/Cloudflare AI/Scaleway sections in Portuguese -- **docs(new-features/ai)**: 10 task spec files + master implementation plan in `docs/new-features/ai/` +- **docs(readme)**:将免费 combo 栈扩展到 11 个提供商(永久 $0) +- **docs(readme)**:新增 4 个免费提供商部分(LongCat、Pollinations、Cloudflare AI、Scaleway),附带模型表 +- **docs(readme)**:更新定价表,新增 4 个免费层行 +- **docs(i18n/pt-BR)**:更新定价表 + 新增葡萄牙语的 LongCat/Pollinations/Cloudflare AI/Scaleway 部分 +- **docs(new-features/ai)**:10 个任务规范文件 + 主实现计划,位于 `docs/new-features/ai/` -### 🧪 Tests +### 🧪 测试 -- Test suite: **821 tests, 0 failures** (unchanged) +- 测试套件:**821 个测试,0 失败**(不变) --- ## [2.9.2] — 2026-03-21 -> Sprint: Fix media transcription (Deepgram/HuggingFace Content-Type, language detection) and TTS error display. +> Sprint:修复媒体转录(Deepgram/HuggingFace Content-Type、语言检测)和 TTS 错误显示。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(transcription)**: Deepgram and HuggingFace audio transcription now correctly map `video/mp4` → `audio/mp4` and other media MIME types via new `resolveAudioContentType()` helper. Previously, uploading `.mp4` files consistently returned "No speech detected" because Deepgram was receiving `Content-Type: video/mp4`. -- **fix(transcription)**: Added `detect_language=true` to Deepgram requests — auto-detects audio language (Portuguese, Spanish, etc.) instead of defaulting to English. Fixes non-English transcriptions returning empty or garbage results. -- **fix(transcription)**: Added `punctuate=true` to Deepgram requests for higher-quality transcription output with correct punctuation. -- **fix(tts)**: `[object Object]` error display in Text-to-Speech responses fixed in both `audioSpeech.ts` and `audioTranscription.ts`. The `upstreamErrorResponse()` function now correctly extracts nested string messages from providers like ElevenLabs that return `{ error: { message: "...", status_code: 401 } }` instead of a flat error string. +- **fix(transcription)**:Deepgram 和 HuggingFace 音频转录现在通过新的 `resolveAudioContentType()` 辅助函数正确映射 `video/mp4` → `audio/mp4` 及其他媒体 MIME 类型。此前上传 `.mp4` 文件始终返回 "No speech detected",因为 Deepgram 收到的是 `Content-Type: video/mp4`。 +- **fix(transcription)**:向 Deepgram 请求添加了 `detect_language=true` —— 自动检测音频语言(葡萄牙语、西班牙语等),而不是默认使用英语。修复了非英语转录返回空或垃圾结果的问题。 +- **fix(transcription)**:向 Deepgram 请求添加了 `punctuate=true`,用于更高质量的转录输出,带有正确的标点符号。 +- **fix(tts)**:修复了 `audioSpeech.ts` 和 `audioTranscription.ts` 中 Text-to-Speech 响应的 `[object Object]` 错误显示。`upstreamErrorResponse()` 函数现在正确地从 ElevenLabs 等提供商返回的嵌套错误消息(如 `{ error: { message: "...", status_code: 401 } }`)中提取字符串消息,而不是扁平错误字符串。 -### 🧪 Tests +### 🧪 测试 -- Test suite: **821 tests, 0 failures** (unchanged) +- 测试套件:**821 个测试,0 失败**(不变) -### Triaged Issues +### 问题分类 -- **#508** — Tool call format regression: requested proxy logs and provider chain info (`needs-info`) -- **#510** — Windows CLI healthcheck path: requested shell/Node version info (`needs-info`) -- **#485** — Kiro MCP tool calls: closed as external Kiro issue (not OmniRoute) -- **#442** — Baseten /models endpoint: closed (documented manual workaround) -- **#464** — Key provisioning API: acknowledged as roadmap item +- **#508** — 工具调用格式回归:请求代理日志和提供商链信息(`needs-info`) +- **#510** — Windows CLI 健康检查路径:请求 shell/Node 版本信息(`needs-info`) +- **#485** — Kiro MCP 工具调用:作为外部 Kiro 问题关闭(非 OmniRoute) +- **#442** — Baseten /models 端点:已关闭(记录了手动解决方案) +- **#464** — Key provisioning API:确认为路线图项目 --- ## [2.9.1] — 2026-03-21 -> Sprint: Fix SSE omniModel data loss, merge per-protocol model compatibility. +> Sprint:修复 SSE omniModel 数据丢失,合并每协议模型兼容性。 -### Bug Fixes +### Bug 修复 -- **#511** — Critical: `` tag was sent after `finish_reason:stop` in SSE streams, causing data loss. Tag is now injected into the first non-empty content chunk, guaranteeing delivery before SDKs close the connection. +- **#511** — 关键问题:`` 标签在 SSE 流中在 `finish_reason:stop` 之后发送,导致数据丢失。现在标签会注入到首个非空内容 chunk 中,确保在 SDK 关闭连接之前完成交付。 -### Merged PRs +### 已合并的 PR -- **PR #512** (@zhangqiang8vip): Per-protocol model compatibility — `normalizeToolCallId` and `preserveOpenAIDeveloperRole` can now be configured per client protocol (OpenAI, Claude, Responses API). New `compatByProtocol` field in model config with Zod validation. +- **PR #512**(@zhangqiang8vip):每协议模型兼容性 — `normalizeToolCallId` 和 `preserveOpenAIDeveloperRole` 现在可以按客户端协议(OpenAI、Claude、Responses API)配置。模型配置中新增 `compatByProtocol` 字段,带 Zod 验证。 -### Triaged Issues +### 问题分类 -- **#510** — Windows CLI healthcheck_failed: requested PATH/version info -- **#509** — Turbopack Electron regression: upstream Next.js bug, documented workarounds -- **#508** — macOS black screen: suggested `--disable-gpu` workaround +- **#510** — Windows CLI healthcheck_failed:请求 PATH/version 信息 +- **#509** — Turbopack Electron 回归:上游 Next.js bug,已记录解决方案 +- **#508** — macOS 黑屏:建议 `--disable-gpu` 解决方案 --- ## [2.9.0] — 2026-03-20 -> Sprint: Cross-platform machineId fix, per-API-key rate limits, streaming context cache, Alibaba DashScope, search analytics, ZWS v5, and 8 issues closed. +> Sprint:跨平台 machineId 修复、每 API key 限流、流式 context 缓存、Alibaba DashScope、搜索分析、ZWS v5 以及 8 个问题已关闭。 -### ✨ New Features +### ✨ 新特性 -- **feat(search)**: Search Analytics tab in `/dashboard/analytics` — provider breakdown, cache hit rate, cost tracking. New API: `GET /api/v1/search/analytics` (#feat/search-provider-routing) -- **feat(provider)**: Alibaba Cloud DashScope added with custom endpoint path validation — configurable `chatPath` and `modelsPath` per node (#feat/custom-endpoint-paths) -- **feat(api)**: Per-API-key request-count limits — `max_requests_per_day` and `max_requests_per_minute` columns with in-memory sliding-window enforcement returning HTTP 429 (#452) -- **feat(dev)**: ZWS v5 — HMR leak fix (485 DB connections → 1), memory 2.4GB → 195MB, `globalThis` singletons, Edge Runtime warning fix (@zhangqiang8vip) +- **feat(search)**:`/dashboard/analytics` 中的搜索分析标签页 —— 提供商拆分、缓存命中率、成本跟踪。新 API:`GET /api/v1/search/analytics`(#feat/search-provider-routing) +- **feat(provider)**:新增 Alibaba Cloud DashScope,带自定义端点路径验证 —— 每个节点可配置 `chatPath` 和 `modelsPath`(#feat/custom-endpoint-paths) +- **feat(api)**:每 API key 请求数限制 —— `max_requests_per_day` 和 `max_requests_per_minute` 列,通过内存滑动窗口强制执行,返回 HTTP 429(#452) +- **feat(dev)**:ZWS v5 —— HMR 泄漏修复(485 个数据库连接 → 1),内存 2.4GB → 195MB,`globalThis` 单例,Edge Runtime 警告修复(@zhangqiang8vip) -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(#506)**: Cross-platform `machineId` — `getMachineIdRaw()` rewritten with try/catch waterfall (Windows REG.exe → macOS ioreg → Linux file read → hostname → `os.hostname()`). Eliminates `process.platform` branching that Next.js bundler dead-code-eliminated, fixing `'head' is not recognized` on Windows. Also fixes #466. -- **fix(#493)**: Custom provider model naming — removed incorrect prefix stripping in `DefaultExecutor.transformRequest()` that mangled org-scoped model IDs like `zai-org/GLM-5-FP8`. -- **fix(#490)**: Streaming + context cache protection — `TransformStream` intercepts SSE to inject `` tag before `[DONE]` marker, enabling context cache protection for streaming responses. -- **fix(#458)**: Combo schema validation — `system_message`, `tool_filter_regex`, `context_cache_protection` fields now pass Zod validation on save. -- **fix(#487)**: KIRO MITM card cleanup — removed ZWS_README, generified `AntigravityToolCard` to use dynamic tool metadata. +- **fix(#506)**:跨平台 `machineId` —— `getMachineIdRaw()` 使用 try/catch 瀑布重写(Windows REG.exe → macOS ioreg → Linux 文件读取 → hostname → `os.hostname()`)。消除了 Next.js 打包器死代码消除的 `process.platform` 分支,修复了 Windows 上的 `'head' is not recognized` 问题。同时修复 #466。 +- **fix(#493)**:自定义提供商模型命名 —— 移除了 `DefaultExecutor.transformRequest()` 中不正确的前缀剥离,该问题破坏了 `zai-org/GLM-5-FP8` 等组织范围的模型 ID。 +- **fix(#490)**:流式 + context 缓存保护 —— `TransformStream` 拦截 SSE 以在 `[DONE]` 标记之前注入 `` 标签,实现流式响应的 context 缓存保护。 +- **fix(#458)**:Combo schema 验证 —— `system_message`、`tool_filter_regex`、`context_cache_protection` 字段现在在保存时通过 Zod 验证。 +- **fix(#487)**:KIRO MITM 卡片清理 —— 移除 ZWS_README,将 `AntigravityToolCard` 泛化以使用动态工具元数据。 -### 🧪 Tests +### 🧪 测试 -- Added Anthropic-format tools filter unit tests (PR #397) — 8 regression tests for `tool.name` without `.function` wrapper -- Test suite: **821 tests, 0 failures** (up from 813) +- 添加了 Anthropic 格式工具过滤器单元测试(PR #397)—— 8 个回归测试,用于不带 `.function` 包装的 `tool.name` +- 测试套件:**821 个测试,0 失败**(从 813 增加) -### 📋 Issues Closed (8) +### 📋 已关闭的问题(8 个) -- **#506** — Windows machineId `head` not recognized (fixed) -- **#493** — Custom provider model naming (fixed) -- **#490** — Streaming context cache (fixed) -- **#452** — Per-API-key request limits (implemented) -- **#466** — Windows login failure (same root cause as #506) -- **#504** — MITM inactive (expected behavior) -- **#462** — Gemini CLI PSA (resolved) -- **#434** — Electron app crash (duplicate of #402) +- **#506** —— Windows machineId `head` 无法识别(已修复) +- **#493** —— 自定义提供商模型命名(已修复) +- **#490** —— 流式 context 缓存(已修复) +- **#452** —— 每 API key 请求限制(已实现) +- **#466** —— Windows 登录失败(与 #506 相同根因) +- **#504** —— MITM 未激活(预期行为) +- **#462** —— Gemini CLI PSA(已解决) +- **#434** —— Electron 应用崩溃(#402 的重复) ## [2.8.9] — 2026-03-20 -> Sprint: Merge community PRs, fix KIRO MITM card, dependency updates. +> Sprint:合并社区 PR、修复 KIRO MITM 卡片、依赖更新。 -### Merged PRs +### 已合并的 PR -- **PR #498** (@Sajid11194): Fix Windows machine ID crash (`undefined\REG.exe`). Replaces `node-machine-id` with native OS registry queries. **Closes #486.** -- **PR #497** (@zhangqiang8vip): Fix dev-mode HMR resource leaks — 485 leaked DB connections → 1, memory 2.4GB → 195MB. `globalThis` singletons, Edge Runtime warning fix, Windows test stability. (+1168/-338 across 22 files) -- **PRs #499-503** (Dependabot): GitHub Actions updates — `docker/build-push-action@7`, `actions/checkout@6`, `peter-evans/dockerhub-description@5`, `docker/setup-qemu-action@4`, `docker/login-action@4`. +- **PR #498**(@Sajid11194):修复 Windows 机器 ID 崩溃(`undefined\REG.exe`)。使用原生 OS 注册表查询替换 `node-machine-id`。**关闭 #486。** +- **PR #497**(@zhangqiang8vip):修复开发模式 HMR 资源泄漏 —— 485 个泄漏的数据库连接 → 1,内存 2.4GB → 195MB。`globalThis` 单例、Edge Runtime 警告修复、Windows 测试稳定性。(22 个文件,+1168/-338) +- **PR #499-503**(Dependabot):GitHub Actions 更新 —— `docker/build-push-action@7`、`actions/checkout@6`、`peter-evans/dockerhub-description@5`、`docker/setup-qemu-action@4`、`docker/login-action@4`。 -### Bug Fixes +### Bug 修复 -- **#505** — KIRO MITM card now displays tool-specific instructions (`api.anthropic.com`) instead of Antigravity-specific text. -- **#504** — Responded with UX clarification (MITM "Inactive" is expected behavior when proxy is not running). +- **#505** —— KIRO MITM 卡片现在显示特定工具的说明(`api.anthropic.com`),而不是 Antigravity 特定的文本。 +- **#504** —— 回复了 UX 澄清说明(当代理未运行时,MITM "Inactive" 是预期行为)。 --- ## [2.8.8] — 2026-03-20 -> Sprint: Fix OAuth batch test crash, add "Test All" button to individual provider pages. +> Sprint:修复 OAuth 批量测试崩溃,为各个提供商页面添加 "Test All" 按钮。 -### Bug Fixes +### Bug 修复 -- **OAuth batch test crash** (ERR_CONNECTION_REFUSED): Replaced sequential for-loop with 5-connection concurrency limit + 30s per-connection timeout via `Promise.race()` + `Promise.allSettled()`. Prevents server crash when testing large OAuth provider groups (~30+ connections). +- **OAuth 批量测试崩溃**(ERR_CONNECTION_REFUSED):将顺序 for-loop 替换为 5 连接并发限制 + 每个连接 30 秒超时,通过 `Promise.race()` + `Promise.allSettled()` 实现。防止在测试大型 OAuth 提供商组(约 30+ 连接)时服务器崩溃。 -### 功能特点 +### 新特性 -- **"Test All" button on provider pages**: Individual provider pages (e.g., `/providers/codex`) now show a "Test All" button in the Connections header when there are 2+ connections. Uses `POST /api/providers/test-batch` with `{mode: "provider", providerId}`. Results displayed in a modal with pass/fail summary and per-connection diagnosis. +- **各提供商页面的 "Test All" 按钮**:各个提供商页面(如 `/providers/codex`)现在有 2+ 连接时会在 Connections 标题处显示 "Test All" 按钮。使用 `POST /api/providers/test-batch` 和 `{mode: "provider", providerId}`。结果在模态框中显示,包含通过/失败摘要和每个连接的诊断信息。 --- ## [2.8.7] — 2026-03-20 -> Sprint: Merge PR #495 (Bottleneck 429 drop), fix #496 (custom embedding providers), triage features. +> Sprint:合并 PR #495(Bottleneck 429 丢弃)、修复 #496(自定义 embedding 提供商)、分类功能。 -### Bug Fixes +### Bug 修复 -- **Bottleneck 429 infinite wait** (PR #495 by @xandr0s): On 429, `limiter.stop({ dropWaitingJobs: true })` immediately fails all queued requests so upstream callers can trigger fallback. Limiter is deleted from Map so next request creates a fresh instance. -- **Custom embedding models unresolvable** (#496): `POST /v1/embeddings` now resolves custom embedding models from ALL provider_nodes (not just localhost). Enables models like `google/gemini-embedding-001` added via dashboard. +- **Bottleneck 429 无限等待**(PR #495 by @xandr0s):收到 429 时,`limiter.stop({ dropWaitingJobs: true })` 立即使所有排队的请求失败,以便上游调用方可以触发回退。Limiter 从 Map 中删除,以便下一个请求创建新实例。 +- **自定义 embedding 模型无法解析**(#496):`POST /v1/embeddings` 现在从所有提供商节点解析自定义 embedding 模型(而不仅仅是 localhost)。支持通过仪表盘添加的 `google/gemini-embedding-001` 等模型。 -### Issues Responded +### 已回复的问题 -- **#452** — Per-API-key request-count limits (acknowledged, on roadmap) -- **#464** — Auto-issue API keys with provider/account limits (needs more detail) -- **#488** — Auto-update model lists (acknowledged, on roadmap) -- **#496** — Custom embedding provider resolution (fixed) +- **#452** —— 每 API key 请求数限制(已确认,在路线图中) +- **#464** —— 自动签发 API key,带提供商/账户限制(需要更多细节) +- **#488** —— 自动更新模型列表(已确认,在路线图中) +- **#496** —— 自定义 embedding 提供商解析(已修复) --- ## [2.8.6] — 2026-03-20 -> Sprint: Merge PR #494 (MiniMax role fix), fix KIRO MITM dashboard, triage 8 issues. +> Sprint:合并 PR #494(MiniMax 角色修复)、修复 KIRO MITM 仪表盘、分类 8 个问题。 -### 功能特点 +### 新特性 -- **MiniMax developer→system role fix** (PR #494 by @zhangqiang8vip): Per-model `preserveDeveloperRole` toggle. Adds "Compatibility" UI in providers page. Fixes 422 "role param error" for MiniMax and similar gateways. -- **roleNormalizer**: `normalizeDeveloperRole()` now accepts `preserveDeveloperRole` parameter with tri-state behavior (undefined=keep, true=keep, false=convert). -- **DB**: New `getModelPreserveOpenAIDeveloperRole()` and `mergeModelCompatOverride()` in `models.ts`. +- **MiniMax developer→system 角色修复**(PR #494 by @zhangqiang8vip):每模型 `preserveDeveloperRole` 开关。在提供商页面新增 "Compatibility" UI。修复 MiniMax 和类似网关的 422 "role param error"。 +- **roleNormalizer**:`normalizeDeveloperRole()` 现在接受 `preserveDeveloperRole` 参数,支持三态行为(undefined=保持、true=保持、false=转换)。 +- **数据库**:在 `models.ts` 中新增 `getModelPreserveOpenAIDeveloperRole()` 和 `mergeModelCompatOverride()`。 -### Bug Fixes +### Bug 修复 -- **KIRO MITM dashboard** (#481/#487): `CLIToolsPageClient` now routes any `configType: "mitm"` tool to `AntigravityToolCard` (MITM Start/Stop controls). Previously only Antigravity was hardcoded. -- **AntigravityToolCard generic**: Uses `tool.image`, `tool.description`, `tool.id` instead of hardcoded Antigravity values. Guards against missing `defaultModels`. +- **KIRO MITM 仪表盘**(#481/#487):`CLIToolsPageClient` 现在将任何 `configType: "mitm"` 工具路由到 `AntigravityToolCard`(MITM 开始/停止控制)。此前只有 Antigravity 是硬编码的。 +- **AntigravityToolCard 泛化**:使用 `tool.image`、`tool.description`、`tool.id` 而不是硬编码的 Antigravity 值。防止缺少 `defaultModels` 时出错。 -### Cleanup +### 清理 -- Removed `ZWS_README_V2.md` (development-only docs from PR #494). +- 移除了 `ZWS_README_V2.md`(PR #494 中的仅开发文档)。 -### Issues Triaged (8) +### 已分类的问题(8 个) -- **#487** — Closed (KIRO MITM fixed in this release) -- **#486** — needs-info (Windows REG.exe PATH issue) -- **#489** — needs-info (Antigravity projectId missing, OAuth reconnect needed) -- **#492** — needs-info (missing app/server.js on mise-managed Node) -- **#490** — Acknowledged (streaming + context cache blocking, fix planned) -- **#491** — Acknowledged (Codex auth state inconsistency) -- **#493** — Acknowledged (Modal provider model name prefix, workaround provided) -- **#488** — Feature request backlog (auto-update model lists) +- **#487** —— 已关闭(KIRO MITM 在此版本中修复) +- **#486** —— 需要信息(Windows REG.exe PATH 问题) +- **#489** —— 需要信息(Antigravity projectId 缺失,需要 OAuth 重新连接) +- **#492** —— 需要信息(缺少 app/server.js,在 mise 管理的 Node 中) +- **#490** —— 已确认(流式 + context 缓存阻塞,计划修复) +- **#491** —— 已确认(Codex 认证状态不一致) +- **#493** —— 已确认(模态框提供商模型名称前缀,已提供解决方案) +- **#488** —— 功能请求待办(自动更新模型列表) --- ## [2.8.5] — 2026-03-19 -> Sprint: Fix zombie SSE streams, context cache first-turn, KIRO MITM, and triage 5 external issues. +> Sprint:修复僵尸 SSE 流、context 缓存首轮、KIRO MITM 以及分类 5 个外部问题。 -### Bug Fixes +### Bug 修复 -- **Zombie SSE Streams** (#473): Reduce `STREAM_IDLE_TIMEOUT_MS` from 300s → 120s for faster combo fallback when providers hang mid-stream. Configurable via env var. -- **Context Cache Tag** (#474): Fix `injectModelTag()` to handle first-turn requests (no assistant messages) — context cache protection now works from the very first response. -- **KIRO MITM** (#481): Change KIRO `configType` from `guide` → `mitm` so the dashboard renders MITM Start/Stop controls. -- **E2E Test** (CI): Fix `providers-bailian-coding-plan.spec.ts` — dismiss pre-existing modal overlay before clicking Add API Key button. +- **僵尸 SSE 流**(#473):将 `STREAM_IDLE_TIMEOUT_MS` 从 300 秒降低到 120 秒,以便在提供商中途挂起时更快回退。可通过环境变量配置。 +- **Context 缓存标签**(#474):修复 `injectModelTag()` 以处理首轮请求(无助手消息)—— context 缓存保护现在从第一个响应开始就生效。 +- **KIRO MITM**(#481):将 KIRO `configType` 从 `guide` 改为 `mitm`,以便仪表盘渲染 MITM 开始/停止控制。 +- **E2E 测试**(CI):修复 `providers-bailian-coding-plan.spec.ts` —— 在点击添加 API Key 按钮之前关闭预先存在的模态框覆盖层。 -### Closed Issues +### 已关闭的问题 -- #473 — Zombie SSE streams bypass combo fallback -- #474 — Context cache `` tag missing on first turn -- #481 — MITM for KIRO not activatable from dashboard -- #468 — Gemini CLI remote server (superseded by #462 deprecation) -- #438 — Claude unable to write files (external CLI issue) -- #439 — AppImage doesn't work (documented libfuse2 workaround) -- #402 — ARM64 DMG "damaged" (documented xattr -cr workaround) -- #460 — CLI not runnable on Windows (documented PATH fix) +- #473 —— 僵尸 SSE 流绕过 combo 回退 +- #474 —— Context 缓存 `` 标签在首轮缺失 +- #481 —— KIRO 的 MITM 无法从仪表盘激活 +- #468 —— Gemini CLI 远程服务器(已被 #462 弃用取代) +- #438 —— Claude 无法写入文件(外部 CLI 问题) +- #439 —— AppImage 无法工作(已记录 libfuse2 解决方案) +- #402 —— ARM64 DMG "损坏"(已记录 xattr -cr 解决方案) +- #460 —— CLI 在 Windows 上无法运行(已记录 PATH 修复方案) --- ## [2.8.4] — 2026-03-19 -> Sprint: Gemini CLI deprecation, VM guide i18n fix, dependabot security fix, provider schema expansion. +> Sprint:Gemini CLI 弃用、VM 指南 i18n 修复、dependabot 安全修复、提供商 schema 扩展。 -### 功能特点 +### 新特性 -- **Gemini CLI Deprecation** (#462): Mark `gemini-cli` provider as deprecated with warning — Google restricts third-party OAuth usage from March 2026 -- **Provider Schema** (#462): Expand Zod validation with `deprecated`, `deprecationReason`, `hasFree`, `freeNote`, `authHint`, `apiHint` optional fields +- **Gemini CLI 弃用**(#462):将 `gemini-cli` 提供商标记为已弃用,附带警告 —— Google 从 2026 年 3 月起限制第三方 OAuth 使用 +- **提供商 Schema**(#462):扩展 Zod 验证,新增 `deprecated`、`deprecationReason`、`hasFree`、`freeNote`、`authHint`、`apiHint` 可选字段 -### Bug Fixes +### Bug 修复 -- **VM Guide i18n** (#471): Add `VM_DEPLOYMENT_GUIDE.md` to i18n translation pipeline, regenerate all 30 locale translations from English source (were stuck in Portuguese) +- **VM 指南 i18n**(#471):将 `VM_DEPLOYMENT_GUIDE.md` 添加到 i18n 翻译流水线,从英文源重新生成所有 30 个语言的翻译(此前卡在葡萄牙语版本) ### 安全 -- **deps**: Bump `flatted` 3.3.3 → 3.4.2 — fixes CWE-1321 prototype pollution (#484, @dependabot) +- **deps**:将 `flatted` 从 3.3.3 升级到 3.4.2 —— 修复 CWE-1321 原型污染(#484,@dependabot) -### Closed Issues +### 已关闭的问题 -- #472 — Model Aliases regression (fixed in v2.8.2) -- #471 — VM guide translations broken -- #483 — Trailing `data: null` after `[DONE]` (fixed in v2.8.3) +- #472 —— Model Aliases 回归(已在 v2.8.2 修复) +- #471 —— VM 指南翻译损坏 +- #483 —— `[DONE]` 后尾随 `data: null`(已在 v2.8.3 修复) -### Merged PRs +### 已合并的 PR -- #484 — deps: bump flatted from 3.3.3 to 3.4.2 (@dependabot) +- #484 —— deps: 将 flatted 从 3.3.3 升级到 3.4.2(@dependabot) --- ## [2.8.3] — 2026-03-19 -> Sprint: Czech i18n, SSE protocol fix, VM guide translation. +> Sprint:捷克语 i18n、SSE 协议修复、VM 指南翻译。 -### 功能特点 +### 新特性 -- **Czech Language** (#482): Full Czech (cs) i18n — 22 docs, 2606 UI strings, language switcher updates (@zen0bit) -- **VM Deployment Guide**: Translated from Portuguese to English as the source document (@zen0bit) +- **捷克语**(#482):完整捷克语(cs)i18n —— 22 份文档,2606 条 UI 字符串,语言切换器更新(@zen0bit) +- **VM 部署指南**:从葡萄牙语翻译为英文作为源文档(@zen0bit) -### Bug Fixes +### Bug 修复 -- **SSE Protocol** (#483): Stop sending trailing `data: null` after `[DONE]` signal — fixes `AI_TypeValidationError` in strict AI SDK clients (Zod-based validators) +- **SSE 协议**(#483):停止在 `[DONE]` 信号后发送尾随的 `data: null` —— 修复严格 AI SDK 客户端(基于 Zod 的验证器)中的 `AI_TypeValidationError` -### Merged PRs +### 已合并的 PR -- #482 — Add Czech language + Fix VM_DEPLOYMENT_GUIDE.md English source (@zen0bit) +- #482 —— 新增捷克语 + 修复 VM_DEPLOYMENT_GUIDE.md 英文源(@zen0bit) --- ## [2.8.2] — 2026-03-19 -> Sprint: 2 merged PRs, model aliases routing fix, log export, and issue triage. +> Sprint:2 个已合并 PR、模型 aliases 路由修复、日志导出和问题分类。 -### 功能特点 +### 新特性 -- **Log Export**: New Export button on `/dashboard/logs` with time range dropdown (1h, 6h, 12h, 24h). Downloads JSON of request/proxy/call logs via `/api/logs/export` API (#user-request) +- **日志导出**:`/dashboard/logs` 中新增导出按钮,带时间范围下拉(1h、6h、12h、24h)。通过 `/api/logs/export` API 下载请求/代理/call 日志的 JSON(#user-request) -### Bug Fixes +### Bug 修复 -- **Model Aliases Routing** (#472): Settings → Model Aliases now correctly affect provider routing, not just format detection. Previously `resolveModelAlias()` output was only used for `getModelTargetFormat()` but the original model ID was sent to the provider -- **Stream Flush Usage** (#480): Usage data from the last SSE event in the buffer is now correctly extracted during stream flush (merged from @prakersh) +- **Model Aliases 路由**(#472):设置 → Model Aliases 现在正确影响提供商路由,而不仅仅是格式检测。此前 `resolveModelAlias()` 的输出仅用于 `getModelTargetFormat()`,但原始模型 ID 被发送给提供商 +- **Stream Flush 用量**(#480):缓冲区中最后一个 SSE 事件的用量数据现在在流刷新期间正确提取(合并自 @prakersh) -### Merged PRs +### 已合并的 PR -- #480 — Extract usage from remaining buffer in flush handler (@prakersh) -- #479 — Add missing Codex 5.3/5.4 and Anthropic model ID pricing entries (@prakersh) +- #480 —— 在 flush handler 中从剩余缓冲区提取用量(@prakersh) +- #479 —— 添加缺失的 Codex 5.3/5.4 和 Anthropic 模型 ID 定价条目(@prakersh) --- ## [2.8.1] — 2026-03-19 -> Sprint: Five community PRs — streaming call log fixes, Kiro compatibility, cache token analytics, Chinese translation, and configurable tool call IDs. +> Sprint:5 个社区 PR —— 流式 call log 修复、Kiro 兼容性、缓存 token 分析、中文翻译和可配置工具调用 ID。 -### 功能特点 +### ✨ 新特性 -- **feat(logs)**: Call log response content now correctly accumulated from raw provider chunks (OpenAI/Claude/Gemini) before translation, fixing empty response payloads in streaming mode (#470, @zhangqiang8vip) -- **feat(providers)**: Per-model configurable 9-char tool call ID normalization (Mistral-style) — only models with the option enabled get truncated IDs (#470) -- **feat(api)**: Key PATCH API expanded to support `allowedConnections`, `name`, `autoResolve`, `isActive`, and `accessSchedule` fields (#470) -- **feat(dashboard)**: Response-first layout in request log detail UI (#470) -- **feat(i18n)**: Improved Chinese (zh-CN) translation — complete retranslation (#475, @only4copilot) +- **feat(logs)**:Call log 响应内容现在在翻译前正确从原始提供商 chunk(OpenAI/Claude/Gemini)累积,修复流式模式下空响应负载的问题(#470,@zhangqiang8vip) +- **feat(providers)**:每模型可配置的 9 字符工具调用 ID 规范化(Mistral 风格)—— 只有启用该选项的模型才会获得截断 ID(#470) +- **feat(api)**:Key PATCH API 扩展以支持 `allowedConnections`、`name`、`autoResolve`、`isActive` 和 `accessSchedule` 字段(#470) +- **feat(dashboard)**:请求日志详情 UI 采用响应优先布局(#470) +- **feat(i18n)**:改进了中文(zh-CN)翻译 —— 完整重译(#475,@only4copilot) -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(kiro)**: Strip injected `model` field from request body — Kiro API rejects unknown top-level fields (#478, @prakersh) -- **fix(usage)**: Include cache read + cache creation tokens in usage history input totals for accurate analytics (#477, @prakersh) -- **fix(callLogs)**: Support Claude format usage fields (`input_tokens`/`output_tokens`) alongside OpenAI format, include all cache token variants (#476, @prakersh) +- **fix(kiro)**:从请求体中剥离注入的 `model` 字段 —— Kiro API 拒绝未知的顶级字段(#478,@prakersh) +- **fix(usage)**:在用量历史输入总计中包含缓存读取 + 缓存创建 token,用于准确的分析(#477,@prakersh) +- **fix(callLogs)**:支持 Claude 格式用量字段(`input_tokens`/`output_tokens`)以及 OpenAI 格式,包含所有缓存 token 变体(#476,@prakersh) --- ## [2.8.0] — 2026-03-19 -> Sprint: Bailian Coding Plan provider with editable base URLs, plus community contributions for Alibaba Cloud and Kimi Coding. +> Sprint:Bailian Coding Plan 提供商,带可编辑基础 URL,以及 Alibaba Cloud 和 Kimi Coding 的社区贡献。 -### 功能特点 +### ✨ 新特性 -- **feat(providers)**: Added Bailian Coding Plan (`bailian-coding-plan`) — Alibaba Model Studio with Anthropic-compatible API. Static catalog of 8 models including Qwen3.5 Plus, Qwen3 Coder, MiniMax M2.5, GLM 5, and Kimi K2.5. Includes custom auth validation (400=valid, 401/403=invalid) (#467, @Mind-Dragon) -- **feat(admin)**: Editable default URL in Provider Admin create/edit flows — users can configure custom base URLs per connection. Persisted in `providerSpecificData.baseUrl` with Zod schema validation rejecting non-http(s) schemes (#467) +- **feat(providers)**:新增 Bailian Coding Plan(`bailian-coding-plan`)—— Alibaba Model Studio,使用 Anthropic 兼容 API。8 个模型的静态目录,包括 Qwen3.5 Plus、Qwen3 Coder、MiniMax M2.5、GLM 5 和 Kimi K2.5。包含自定义认证验证(400=有效,401/403=无效)(#467,@Mind-Dragon) +- **feat(admin)**:提供商管理员创建/编辑流程中可编辑的默认 URL —— 用户可以为每个连接配置自定义基础 URL。持久化到 `providerSpecificData.baseUrl`,使用 Zod schema 验证拒绝非 http(s) 方案(#467) -### 🧪 Tests +### 🧪 测试 -- Added 30+ unit tests and 2 e2e scenarios for Bailian Coding Plan provider covering auth validation, schema hardening, route-level behavior, and cross-layer integration +- 为 Bailian Coding Plan 提供商添加了 30+ 单元测试和 2 个 e2e 场景,覆盖认证验证、schema 强化、路由级行为和跨层集成 --- ## [2.7.10] — 2026-03-19 -> Sprint: Two new community-contributed providers (Alibaba Cloud Coding, Kimi Coding API-key) and Docker pino fix. +> Sprint:两个社区贡献的提供商(Alibaba Cloud Coding、Kimi Coding API-key)和 Docker pino 修复。 -### 功能特点 +### ✨ 新特性 -- **feat(providers)**: Added Alibaba Cloud Coding Plan support with two OpenAI-compatible endpoints — `alicode` (China) and `alicode-intl` (International), each with 8 models (#465, @dtk1985) -- **feat(providers)**: Added dedicated `kimi-coding-apikey` provider path — API-key-based Kimi Coding access is no longer forced through OAuth-only `kimi-coding` route. Includes registry, constants, models API, config, and validation test (#463, @Mind-Dragon) +- **feat(providers)**:新增 Alibaba Cloud Coding Plan 支持,使用两个 OpenAI 兼容端点 —— `alicode`(中国)和 `alicode-intl`(国际),每个端点 8 个模型(#465,@dtk1985) +- **feat(providers)**:新增专用的 `kimi-coding-apikey` 提供商路径 —— 基于 API key 的 Kimi Coding 访问不再强制通过仅 OAuth 的 `kimi-coding` 路由。包括注册表、常量、模型 API、配置和验证测试(#463,@Mind-Dragon) -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(docker)**: Added missing `split2` dependency to Docker image — `pino-abstract-transport` requires it at runtime but it was not being copied into the standalone container, causing `Cannot find module 'split2'` crashes (#459) +- **fix(docker)**:为 Docker 镜像添加了缺失的 `split2` 依赖 —— `pino-abstract-transport` 在运行时需要它,但未被复制到独立容器中,导致 `Cannot find module 'split2'` 崩溃(#459) --- ## [2.7.9] — 2026-03-18 -> Sprint: Codex responses subpath passthrough natively supported, Windows MITM crash fixed, and Combos agent schemas adjusted. +> Sprint:Codex 响应子路径透传原生支持、Windows MITM 崩溃修复和 Combos agent schema 调整。 -### 功能特点 +### ✨ 新特性 -- **feat(codex)**: Native responses subpath passthrough for Codex — natively routes `POST /v1/responses/compact` to Codex upstream, maintaining Claude Code compatibility without stripping the `/compact` suffix (#457) +- **feat(codex)**:Codex 原生响应子路径透传 —— 原生将 `POST /v1/responses/compact` 路由到 Codex 上游,在不剥离 `/compact` 后缀的情况下保持 Claude Code 兼容性(#457) -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(combos)**: Zod schemas (`updateComboSchema` and `createComboSchema`) now include `system_message`, `tool_filter_regex`, and `context_cache_protection`. Fixes bug where agent-specific settings created via the dashboard were silently discarded by the backend validation layer (#458) -- **fix(mitm)**: Kiro MITM profile crash on Windows fixed — `node-machine-id` failed due to missing `REG.exe` env, and the fallback threw a fatal `crypto is not defined` error. Fallback now safely and correctly imports crypto (#456) +- **fix(combos)**:Zod schema(`updateComboSchema` 和 `createComboSchema`)现在包含 `system_message`、`tool_filter_regex` 和 `context_cache_protection`。修复了通过仪表盘创建的代理特定设置被后端验证层静默丢弃的 bug(#458) +- **fix(mitm)**:修复 Windows 上 Kiro MITM 配置崩溃 —— `node-machine-id` 因缺少 `REG.exe` 环境失败,且回退抛出了致命的 `crypto is not defined` 错误。回退现在安全正确地导入 crypto(#456) --- ## [2.7.8] — 2026-03-18 -> Sprint: Budget save bug + combo agent features UI + omniModel tag security fix. +> Sprint:预算保存 bug + combo agent 功能 UI + omniModel 标签安全修复。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(budget)**: "Save Limits" no longer returns 422 — `warningThreshold` is now correctly sent as fraction (0–1) instead of percentage (0–100) (#451) -- **fix(combos)**: `` internal cache tag is now stripped before forwarding requests to providers, preventing cache session breaks (#454) +- **fix(budget)**:"Save Limits" 不再返回 422 —— `warningThreshold` 现在正确作为分数(0–1)发送,而不是百分比(0–100)(#451) +- **fix(combos)**:`` 内部缓存标签现在在转发请求给提供商之前被剥离,防止缓存会话中断(#454) -### 功能特点 +### ✨ 新特性 -- **feat(combos)**: Agent Features section added to combo create/edit modal — expose `system_message` override, `tool_filter_regex`, and `context_cache_protection` directly from the dashboard (#454) +- **feat(combos)**:在 combo 创建/编辑模态框中新增 Agent Features 部分 —— 直接从仪表盘暴露 `system_message` 覆盖、`tool_filter_regex` 和 `context_cache_protection`(#454) --- ## [2.7.7] — 2026-03-18 -> Sprint: Docker pino crash, Codex CLI responses worker fix, package-lock sync. +> Sprint:Docker pino 崩溃、Codex CLI 响应 worker 修复、package-lock 同步。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(docker)**: `pino-abstract-transport` and `pino-pretty` now explicitly copied in Docker runner stage — Next.js standalone trace misses these peer deps, causing `Cannot find module pino-abstract-transport` crash on startup (#449) -- **fix(responses)**: Remove `initTranslators()` from `/v1/responses` route — was crashing Next.js worker with `the worker has exited` uncaughtException on Codex CLI requests (#450) +- **fix(docker)**:`pino-abstract-transport` 和 `pino-pretty` 现在在 Docker runner 阶段显式复制 —— Next.js 独立跟踪遗漏这些对等依赖,导致启动时 `Cannot find module pino-abstract-transport` 崩溃(#449) +- **fix(responses)**:从 `/v1/responses` 路由中移除 `initTranslators()` —— 导致 Next.js worker 崩溃,出现 `the worker has exited` 未捕获异常,在 Codex CLI 请求中(#450) -### 🔧 Maintenance +### 🔧 维护 -- **chore(deps)**: `package-lock.json` now committed on every version bump to ensure Docker `npm ci` uses exact dependency versions +- **chore(deps)**:`package-lock.json` 现在在每次版本升级时提交,以确保 Docker `npm ci` 使用精确的依赖版本 --- ## [2.7.5] — 2026-03-18 -> Sprint: UX improvements and Windows CLI healthcheck fix. +> Sprint:UX 改进和 Windows CLI 健康检查修复。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(ux)**: Show default password hint on login page — new users now see `"Default password: 123456"` below the password input (#437) -- **fix(cli)**: Claude CLI and other npm-installed tools now correctly detected as runnable on Windows — spawn uses `shell:true` to resolve `.cmd` wrappers via PATHEXT (#447) +- **fix(ux)**:在登录页面显示默认密码提示 —— 新用户现在会在密码输入框下方看到 `"Default password: 123456"`(#437) +- **fix(cli)**:Claude CLI 和其他 npm 安装的工具现在在 Windows 上正确检测为可运行 —— spawn 使用 `shell:true` 以解决通过 PATHEXT 的 `.cmd` 包装器问题(#447) --- ## [2.7.4] — 2026-03-18 -> Sprint: Search Tools dashboard, i18n fixes, Copilot limits, Serper validation fix. +> Sprint:搜索工具仪表盘、i18n 修复、Copilot 限制、Serper 验证修复。 -### 功能特点 +### 🚀 新特性 -- **feat(search)**: Add Search Playground (10th endpoint), Search Tools page with Compare Providers/Rerank Pipeline/Search History, local rerank routing, auth guards on search API (#443 by @Regis-RCR) - - New route: `/dashboard/search-tools` - - Sidebar entry under Debug section - - `GET /api/search/providers` and `GET /api/search/stats` with auth guards - - Local provider_nodes routing for `/v1/rerank` - - 30+ i18n keys in search namespace +- **feat(search)**:新增搜索游乐场(第 10 个端点)、搜索工具页面,包含提供商比较/重排序流水线/搜索历史、本地重排序路由、搜索 API 认证守卫(#443 by @Regis-RCR) + - 新路由:`/dashboard/search-tools` + - 调试部分下的侧边栏条目 + - `GET /api/search/providers` 和 `GET /api/search/stats`,带认证守卫 + - 本地提供商节点路由,用于 `/v1/rerank` + - 搜索命名空间中 30+ i18n 键 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(search)**: Fix Brave news normalizer (was returning 0 results), enforce max_results truncation post-normalization, fix Endpoints page fetch URL (#443 by @Regis-RCR) -- **fix(analytics)**: Localize analytics day/date labels — replace hardcoded Portuguese strings with `Intl.DateTimeFormat(locale)` (#444 by @hijak) -- **fix(copilot)**: Correct GitHub Copilot account type display, filter misleading unlimited quota rows from limits dashboard (#445 by @hijak) -- **fix(providers)**: Stop rejecting valid Serper API keys — treat non-4xx responses as valid authentication (#446 by @hijak) +- **fix(search)**:修复 Brave 新闻规范化器(此前返回 0 个结果),在规范化后强制执行 max_results 截断,修复端点页面获取 URL(#443 by @Regis-RCR) +- **fix(analytics)**:本地化分析日/期标签 —— 用 `Intl.DateTimeFormat(locale)` 替换硬编码的葡萄牙语字符串(#444 by @hijak) +- **fix(copilot)**:修正 GitHub Copilot 账户类型显示,从限制仪表盘过滤误导性的无限配额行(#445 by @hijak) +- **fix(providers)**:停止拒绝有效的 Serper API key —— 将非 4xx 响应视为有效认证(#446 by @hijak) --- ## [2.7.3] — 2026-03-18 -> Sprint: Codex direct API quota fallback fix. +> Sprint:Codex 直接 API 配额回退修复。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(codex)**: Block weekly-exhausted accounts in direct API fallback (#440) - - `resolveQuotaWindow()` prefix matching: `"weekly"` now matches `"weekly (7d)"` cache keys - - `applyCodexWindowPolicy()` enforces `useWeekly`/`use5h` toggles correctly - - 4 new regression tests (766 total) +- **fix(codex)**:在直接 API 回退中阻止每周已耗尽的账户(#440) + - `resolveQuotaWindow()` 前缀匹配:`"weekly"` 现在匹配 `"weekly (7d)"` 缓存键 + - `applyCodexWindowPolicy()` 正确强制执行 `useWeekly`/`use5h` 开关 + - 4 个新回归测试(共 766 个) --- ## [2.7.2] — 2026-03-18 -> Sprint: Light mode UI contrast fixes. +> Sprint:浅色模式 UI 对比度修复。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(logs)**: Fix light mode contrast in request logs filter buttons and combo badge (#378) - - Error/Success/Combo filter buttons now readable in light mode - - Combo row badge uses stronger violet in light mode +- **fix(logs)**:修复请求日志过滤按钮和 combo 徽章的浅色模式对比度(#378) + - 错误/成功/Combo 过滤按钮现在在浅色模式下可读 + - Combo 行徽章在浅色模式下使用更强的紫色 --- ## [2.7.1] — 2026-03-17 -> Sprint: Unified web search routing (POST /v1/search) with 5 providers + Next.js 16.1.7 security fixes (6 CVEs). +> Sprint:统一 Web 搜索路由(POST /v1/search),使用 5 个提供商 + Next.js 16.1.7 安全修复(6 个 CVE)。 -### ✨ New Features +### ✨ 新特性 -- **feat(search)**: Unified web search routing — `POST /v1/search` with 5 providers (Serper, Brave, Perplexity, Exa, Tavily) - - Auto-failover across providers, 6,500+ free searches/month - - In-memory cache with request coalescing (configurable TTL) - - Dashboard: Search Analytics tab in `/dashboard/analytics` with provider breakdown, cache hit rate, cost tracking - - New API: `GET /api/v1/search/analytics` for search request statistics - - DB migration: `request_type` column on `call_logs` for non-chat request tracking - - Zod validation (`v1SearchSchema`), auth-gated, cost recorded via `recordCost()` +- **feat(search)**:统一 Web 搜索路由 —— `POST /v1/search`,使用 5 个提供商(Serper、Brave、Perplexity、Exa、Tavily) + - 跨提供商自动故障转移,每月 6500+ 次免费搜索 + - 内存缓存,带请求合并(可配置 TTL) + - 仪表盘:`/dashboard/analytics` 中的搜索分析标签页,包含提供商拆分、缓存命中率、成本跟踪 + - 新 API:`GET /api/v1/search/analytics`,用于搜索请求统计 + - 数据库迁移:`call_logs` 中的 `request_type` 列,用于非聊天请求追踪 + - Zod 验证(`v1SearchSchema`)、认证门控、通过 `recordCost()` 记录成本 -### 安全 +### 🔒 安全 -- **deps**: Next.js 16.1.6 → 16.1.7 — fixes 6 CVEs: - - **Critical**: CVE-2026-29057 (HTTP request smuggling via http-proxy) - - **High**: CVE-2026-27977, CVE-2026-27978 (WebSocket + Server Actions) - - **Medium**: CVE-2026-27979, CVE-2026-27980, CVE-2026-jcc7 +- **deps**:Next.js 16.1.6 → 16.1.7 —— 修复 6 个 CVE: + - **严重**:CVE-2026-29057(通过 http-proxy 的 HTTP 请求走私) + - **高**:CVE-2026-27977、CVE-2026-27978(WebSocket + Server Actions) + - **中**:CVE-2026-27979、CVE-2026-27980、CVE-2026-jcc7 -### 📁 New Files +### 📁 新增文件 -| File | Purpose | -| ---------------------------------------------------------------- | ------------------------------------------ | -| `open-sse/handlers/search.ts` | Search handler with 5-provider routing | -| `open-sse/config/searchRegistry.ts` | Provider registry (auth, cost, quota, TTL) | -| `open-sse/services/searchCache.ts` | In-memory cache with request coalescing | -| `src/app/api/v1/search/route.ts` | Next.js route (POST + GET) | -| `src/app/api/v1/search/analytics/route.ts` | Search stats API | -| `src/app/(dashboard)/dashboard/analytics/SearchAnalyticsTab.tsx` | Analytics dashboard tab | -| `src/lib/db/migrations/007_search_request_type.sql` | DB migration | -| `tests/unit/search-registry.test.mjs` | 277 lines of unit tests | +| 文件 | 目的 | +| ---------------------------------------------------------------- | ------------------------------------- | +| `open-sse/handlers/search.ts` | 搜索处理器,5 提供商路由 | +| `open-sse/config/searchRegistry.ts` | 提供商注册表(认证、成本、配额、TTL) | +| `open-sse/services/searchCache.ts` | 内存缓存,带请求合并 | +| `src/app/api/v1/search/route.ts` | Next.js 路由(POST + GET) | +| `src/app/api/v1/search/analytics/route.ts` | 搜索统计 API | +| `src/app/(dashboard)/dashboard/analytics/SearchAnalyticsTab.tsx` | 分析仪表盘标签页 | +| `src/lib/db/migrations/007_search_request_type.sql` | 数据库迁移 | +| `tests/unit/search-registry.test.mjs` | 277 行单元测试 | --- ## [2.7.0] — 2026-03-17 -> Sprint: ClawRouter-inspired features — toolCalling flag, multilingual intent detection, benchmark-driven fallback, request deduplication, pluggable RouterStrategy, Grok-4 Fast + GLM-5 + MiniMax M2.5 + Kimi K2.5 pricing. +> Sprint:受 ClawRouter 启发的功能 —— toolCalling 标志、多语言意图检测、基准驱动回退、请求去重、可插拔 RouterStrategy、Grok-4 Fast + GLM-5 + MiniMax M2.5 + Kimi K2.5 定价。 -### ✨ New Models & Pricing +### ✨ 新模型与定价 -- **feat(pricing)**: xAI Grok-4 Fast — `$0.20/$0.50 per 1M tokens`, 1143ms p50 latency, tool calling supported -- **feat(pricing)**: xAI Grok-4 (standard) — `$0.20/$1.50 per 1M tokens`, reasoning flagship -- **feat(pricing)**: GLM-5 via Z.AI — `$0.5/1M`, 128K output context -- **feat(pricing)**: MiniMax M2.5 — `$0.30/1M input`, reasoning + agentic tasks -- **feat(pricing)**: DeepSeek V3.2 — updated pricing `$0.27/$1.10 per 1M` -- **feat(pricing)**: Kimi K2.5 via Moonshot API — direct Moonshot API access -- **feat(providers)**: Z.AI provider added (`zai` alias) — GLM-5 family with 128K output +- **feat(pricing)**:xAI Grok-4 Fast —— `$0.20/$0.50 per 1M tokens`,1143ms p50 延迟,支持工具调用 +- **feat(pricing)**:xAI Grok-4(标准)—— `$0.20/$1.50 per 1M tokens`,推理旗舰 +- **feat(pricing)**:GLM-5(通过 Z.AI)—— `$0.5/1M`,128K 输出上下文 +- **feat(pricing)**:MiniMax M2.5 —— `$0.30/1M input`,推理 + 代理任务 +- **feat(pricing)**:DeepSeek V3.2 —— 更新定价 `$0.27/$1.10 per 1M` +- **feat(pricing)**:Kimi K2.5(通过 Moonshot API)—— 直接 Moonshot API 访问 +- **feat(providers)**:新增 Z.AI 提供商(`zai` 别名)—— GLM-5 系列,使用 128K 输出 -### 🧠 Routing Intelligence +### 🧠 路由智能 -- **feat(registry)**: `toolCalling` flag per model in provider registry — combos can now prefer/require tool-calling capable models -- **feat(scoring)**: Multilingual intent detection for AutoCombo scoring — PT/ZH/ES/AR script/language patterns influence model selection per request context -- **feat(fallback)**: Benchmark-driven fallback chains — real latency data (p50 from `comboMetrics`) used to re-order fallback priority dynamically -- **feat(dedup)**: Request deduplication via content-hash — 5-second idempotency window prevents duplicate provider calls from retrying clients -- **feat(router)**: Pluggable `RouterStrategy` interface in `autoCombo/routerStrategy.ts` — custom routing logic can be injected without modifying core +- **feat(registry)**:提供商注册表中每模型的 `toolCalling` 标志 —— combo 现在可以偏好/要求支持工具调用的模型 +- **feat(scoring)**:多语言意图检测,用于 AutoCombo 评分 —— PT/ZH/ES/AR 脚本/语言模式根据请求上下文影响模型选择 +- **feat(fallback)**:基准驱动的回退链 —— 使用真实延迟数据(来自 `comboMetrics` 的 p50)动态重新排序回退优先级 +- **feat(dedup)**:通过内容哈希的请求去重 —— 5 秒幂等窗口防止重复客户端重试导致的提供商调用 +- **feat(router)**:`autoCombo/routerStrategy.ts` 中可插拔的 `RouterStrategy` 接口 —— 可以注入自定义路由逻辑,无需修改核心 -### 🔧 MCP Server Improvements +### 🔧 MCP 服务器改进 -- **feat(mcp)**: 2 new advanced tool schemas: `omniroute_get_provider_metrics` (p50/p95/p99 per provider) and `omniroute_explain_route` (routing decision explanation) -- **feat(mcp)**: MCP tool auth scopes updated — `metrics:read` scope added for provider metrics tools -- **feat(mcp)**: `omniroute_best_combo_for_task` now accepts `languageHint` parameter for multilingual routing +- **feat(mcp)**:2 个新的高级工具 schema:`omniroute_get_provider_metrics`(每提供商 p50/p95/p99)和 `omniroute_explain_route`(路由决策解释) +- **feat(mcp)**:MCP 工具认证范围更新 —— 新增 `metrics:read` 范围,用于提供商指标工具 +- **feat(mcp)**:`omniroute_best_combo_for_task` 现在接受 `languageHint` 参数,用于多语言路由 -### 📊 Observability +### 📊 可观测性 -- **feat(metrics)**: `comboMetrics.ts` extended with real-time latency percentile tracking per provider/account -- **feat(health)**: Health API (`/api/monitoring/health`) now returns per-provider `p50Latency` and `errorRate` fields -- **feat(usage)**: Usage history migration for per-model latency tracking +- **feat(metrics)**:扩展 `comboMetrics.ts`,使用每提供商/账户的实时延迟百分位追踪 +- **feat(health)**:健康 API(`/api/monitoring/health`)现在返回每提供商的 `p50Latency` 和 `errorRate` 字段 +- **feat(usage)**:用量历史迁移,用于每模型延迟追踪 -### 🗄️ DB Migrations +### 🗄️ 数据库迁移 -- **feat(migrations)**: New column `latency_p50` in `combo_metrics` table — zero-breaking, safe for existing users +- **feat(migrations)**:`combo_metrics` 表中新增 `latency_p50` 列 —— 零破坏性,对现有用户安全 -### 🐛 Bug Fixes / Closures +### 🐛 Bug 修复 / 关闭 -- **close(#411)**: better-sqlite3 hashed module resolution on Windows — fixed in v2.6.10 (f02c5b5) -- **close(#409)**: GitHub Copilot chat completions fail with Claude models when files attached — fixed in v2.6.9 (838f1d6) -- **close(#405)**: Duplicate of #411 — resolved +- **close(#411)**:Windows 上 better-sqlite3 哈希模块解析 —— 已在 v2.6.10(f02c5b5)修复 +- **close(#409)**:附加文件时 GitHub Copilot 聊天补全使用 Claude 模型失败 —— 已在 v2.6.9(838f1d6)修复 +- **close(#405)**:#411 的重复 —— 已解决 ## [2.6.10] — 2026-03-17 -> Windows fix: better-sqlite3 prebuilt download without node-gyp/Python/MSVC (#426). +> Windows 修复:无需 node-gyp/Python/MSVC 的 better-sqlite3 预构建下载(#426)。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(install/#426)**: On Windows, `npm install -g omniroute` used to fail with `better_sqlite3.node is not a valid Win32 application` because the bundled native binary was compiled for Linux. Adds **Strategy 1.5** to `scripts/postinstall.mjs`: uses `@mapbox/node-pre-gyp install --fallback-to-build=false` (bundled within `better-sqlite3`) to download the correct prebuilt binary for the current OS/arch without requiring any build tools (no node-gyp, no Python, no MSVC). Falls back to `npm rebuild` only if the download fails. Adds platform-specific error messages with clear manual fix instructions. +- **fix(install/#426)**:在 Windows 上,`npm install -g omniroute` 此前会失败,报错 `better_sqlite3.node is not a valid Win32 application`,因为捆绑的原生二进制文件是为 Linux 编译的。在 `scripts/postinstall.mjs` 中新增 **策略 1.5**:使用 `@mapbox/node-pre-gyp install --fallback-to-build=false`(捆绑在 `better-sqlite3` 中)下载当前 OS/arch 的正确预构建二进制文件,无需任何构建工具(无需 node-gyp、Python、MSVC)。仅在下载失败时回退到 `npm rebuild`。新增平台特定的错误消息,附带清晰的手动修复说明。 --- ## [2.6.9] — 2026-03-17 -> CI fixes (t11 any-budget), bug fix #409 (file attachments via Copilot+Claude), release workflow correction. +> CI 修复(t11 any-budget)、bug 修复 #409(通过 Copilot+Claude 的文件附件)、发布工作流修正。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(ci)**: Remove word "any" from comments in `openai-responses.ts` and `chatCore.ts` that were failing the t11 `\bany\b` budget check (false positive from regex counting comments) -- **fix(chatCore)**: Normalize unsupported content part types before forwarding to providers (#409 — Cursor sends `{type:"file"}` when `.md` files are attached; Copilot and other OpenAI-compat providers reject with "type has to be either 'image_url' or 'text'"; fix converts `file`/`document` blocks to `text` and drops unknown types) +- **fix(ci)**:从 `openai-responses.ts` 和 `chatCore.ts` 的注释中移除单词 "any",这些注释导致 t11 `\bany\b` 预算检查失败(正则计数注释时的误报) +- **fix(chatCore)**:在转发给提供商之前规范化不支持的内容部分类型(#409 —— Cursor 在附加 `.md` 文件时发送 `{type:"file"}`;Copilot 和其他 OpenAI 兼容提供商拒绝,报错 "type has to be either 'image_url' or 'text'";修复将 `file`/`document` 块转换为 `text` 并丢弃未知类型) -### 🔧 Workflow +### 🔧 工作流 -- **chore(generate-release)**: Add ATOMIC COMMIT RULE — version bump (`npm version patch`) MUST happen before committing feature files to ensure tag always points to a commit containing all version changes together +- **chore(generate-release)**:新增原子提交规则 —— 版本升级(`npm version patch`)必须在提交功能文件之前发生,以确保标签始终指向包含所有版本变更的提交 --- ## [2.6.8] — 2026-03-17 -> Sprint: Combo as Agent (system prompt + tool filter), Context Caching Protection, Auto-Update, Detailed Logs, MITM Kiro IDE. +> Sprint:Combo 作为 Agent(系统提示词 + 工具过滤)、Context 缓存保护、自动更新、详细日志、MITM Kiro IDE。 -### 🗄️ DB Migrations (zero-breaking — safe for existing users) +### 🗄️ 数据库迁移(零破坏性 —— 对现有用户安全) -- **005_combo_agent_fields.sql**: `ALTER TABLE combos ADD COLUMN system_message TEXT DEFAULT NULL`, `tool_filter_regex TEXT DEFAULT NULL`, `context_cache_protection INTEGER DEFAULT 0` -- **006_detailed_request_logs.sql**: New `request_detail_logs` table with 500-entry ring-buffer trigger, opt-in via settings toggle +- **005_combo_agent_fields.sql**:`ALTER TABLE combos ADD COLUMN system_message TEXT DEFAULT NULL`,`tool_filter_regex TEXT DEFAULT NULL`,`context_cache_protection INTEGER DEFAULT 0` +- **006_detailed_request_logs.sql**:新增 `request_detail_logs` 表,使用 500 条目环形缓冲区触发器,通过设置开关选择加入 -### 功能特点 +### ✨ 新特性 -- **feat(combo)**: System Message Override per Combo (#399 — `system_message` field replaces or injects system prompt before forwarding to provider) -- **feat(combo)**: Tool Filter Regex per Combo (#399 — `tool_filter_regex` keeps only tools matching pattern; supports OpenAI + Anthropic formats) -- **feat(combo)**: Context Caching Protection (#401 — `context_cache_protection` tags responses with `provider/model` and pins model for session continuity) -- **feat(settings)**: Auto-Update via Settings (#320 — `GET /api/system/version` + `POST /api/system/update` — checks npm registry and updates in background with pm2 restart) -- **feat(logs)**: Detailed Request Logs (#378 — captures full pipeline bodies at 4 stages: client request, translated request, provider response, client response — opt-in toggle, 64KB trim, 500-entry ring-buffer) -- **feat(mitm)**: MITM Kiro IDE profile (#336 — `src/mitm/targets/kiro.ts` targets api.anthropic.com, reuses existing MITM infrastructure) +- **feat(combo)**:每 Combo 系统消息覆盖(#399 —— `system_message` 字段在转发给提供商之前替换或注入系统提示词) +- **feat(combo)**:每 Combo 工具过滤正则表达式(#399 —— `tool_filter_regex` 仅保留匹配模式的工具;支持 OpenAI + Anthropic 格式) +- **feat(combo)**:Context 缓存保护(#401 —— `context_cache_protection` 使用 `provider/model` 标记响应,并为会话连续性固定模型) +- **feat(settings)**:通过设置自动更新(#320 —— `GET /api/system/version` + `POST /api/system/update` —— 检查 npm 注册表并在后台更新,使用 pm2 重启) +- **feat(logs)**:详细请求日志(#378 —— 在 4 个阶段捕获完整的流水线体:客户端请求、翻译后的请求、提供商响应、客户端响应 —— 选择加入开关,64KB 裁剪,500 条目环形缓冲区) +- **feat(mitm)**:MITM Kiro IDE 配置(#336 —— `src/mitm/targets/kiro.ts` 目标为 api.anthropic.com,复用现有 MITM 基础设施) --- ## [2.6.7] — 2026-03-17 -> Sprint: SSE improvements, local provider_nodes extensions, proxy registry, Claude passthrough fixes. +> Sprint:SSE 改进、本地提供商节点扩展、代理注册表、Claude 透传修复。 -### 功能特点 +### ✨ 新特性 -- **feat(health)**: Background health check for local `provider_nodes` with exponential backoff (30s→300s) and `Promise.allSettled` to avoid blocking (#423, @Regis-RCR) -- **feat(embeddings)**: Route `/v1/embeddings` to local `provider_nodes` — `buildDynamicEmbeddingProvider()` with hostname validation (#422, @Regis-RCR) -- **feat(audio)**: Route TTS/STT to local `provider_nodes` — `buildDynamicAudioProvider()` with SSRF protection (#416, @Regis-RCR) -- **feat(proxy)**: Proxy registry, management APIs, and quota-limit generalization (#429, @Regis-RCR) +- **feat(health)**:本地 `provider_nodes` 的后台健康检查,使用指数退避(30s→300s)和 `Promise.allSettled` 以避免阻塞(#423,@Regis-RCR) +- **feat(embeddings)**:将 `/v1/embeddings` 路由到本地 `provider_nodes` —— `buildDynamicEmbeddingProvider()` 带主机名验证(#422,@Regis-RCR) +- **feat(audio)**:将 TTS/STT 路由到本地 `provider_nodes` —— `buildDynamicAudioProvider()` 带 SSRF 保护(#416,@Regis-RCR) +- **feat(proxy)**:代理注册表、管理 API 和配额限制泛化(#429,@Regis-RCR) -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(sse)**: Strip Claude-specific fields (`metadata`, `anthropic_version`) when target is OpenAI-compat (#421, @prakersh) -- **fix(sse)**: Extract Claude SSE usage (`input_tokens`, `output_tokens`, cache tokens) in passthrough stream mode (#420, @prakersh) -- **fix(sse)**: Generate fallback `call_id` for tool calls with missing/empty IDs (#419, @prakersh) -- **fix(sse)**: Claude-to-Claude passthrough — forward body completely untouched, no re-translation (#418, @prakersh) -- **fix(sse)**: Filter orphaned `tool_result` items after Claude Code context compaction to avoid 400 errors (#417, @prakersh) -- **fix(sse)**: Skip empty-name tool calls in Responses API translator to prevent `placeholder_tool` infinite loops (#415, @prakersh) -- **fix(sse)**: Strip empty text content blocks before translation (#427, @prakersh) -- **fix(api)**: Add `refreshable: true` to Claude OAuth test config (#428, @prakersh) +- **fix(sse)**:当目标为 OpenAI 兼容时剥离 Claude 特定字段(`metadata`、`anthropic_version`)(#421,@prakersh) +- **fix(sse)**:在透传流模式中提取 Claude SSE 用量(`input_tokens`、`output_tokens`、缓存 token)(#420,@prakersh) +- **fix(sse)**:为工具调用生成回退 `call_id`,用于缺失/空 ID(#419,@prakersh) +- **fix(sse)**:Claude 到 Claude 透传 —— 完全未经修改地转发请求体,不重新翻译(#418,@prakersh) +- **fix(sse)**:在 Claude Code 上下文压缩后过滤孤立的 `tool_result` 项,以避免 400 错误(#417,@prakersh) +- **fix(sse)**:在 Responses API 翻译器中跳过空名称工具调用,以防止 `placeholder_tool` 无限循环(#415,@prakersh) +- **fix(sse)**:在翻译之前剥离空文本内容块(#427,@prakersh) +- **fix(api)**:为 Claude OAuth 测试配置添加 `refreshable: true`(#428,@prakersh) -### 📦 Dependencies +### 📦 依赖 -- Bump `vitest`, `@vitest/*` and related devDependencies (#414, @dependabot) +- 升级 `vitest`、`@vitest/*` 和相关 devDependencies(#414,@dependabot) --- ## [2.6.6] — 2026-03-17 -> Hotfix: Turbopack/Docker compatibility — remove `node:` protocol from all `src/` imports. +> 热修复:Turbopack/Docker 兼容性 —— 从所有 `src/` 导入中移除 `node:` 协议。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(build)**: Removed `node:` protocol prefix from `import` statements in 17 files under `src/`. The `node:fs`, `node:path`, `node:url`, `node:os` etc. imports caused `Ecmascript file had an error` on Turbopack builds (Next.js 15 Docker) and on upgrades from older npm global installs. Affected files: `migrationRunner.ts`, `core.ts`, `backup.ts`, `prompts.ts`, `dataPaths.ts`, and 12 others in `src/app/api/` and `src/lib/`. -- **chore(workflow)**: Updated `generate-release.md` to make Docker Hub sync and dual-VPS deploy **mandatory** steps in every release. +- **fix(build)**:从 `src/` 下 17 个文件的 `import` 语句中移除了 `node:` 协议前缀。`node:fs`、`node:path`、`node:url`、`node:os` 等导入在 Turbopack 构建(Next.js 15 Docker)中导致 `Ecmascript file had an error`,以及从较旧的 npm 全局安装升级时。受影响文件:`migrationRunner.ts`、`core.ts`、`backup.ts`、`prompts.ts`、`dataPaths.ts` 以及 `src/app/api/` 和 `src/lib/` 中的其他 12 个文件。 +- **chore(workflow)**:更新了 `generate-release.md`,使 Docker Hub 同步和双 VPS 部署成为每次发布的 **强制** 步骤。 --- ## [2.6.5] — 2026-03-17 -> Sprint: reasoning model param filtering, local provider 404 fix, Kilo Gateway provider, dependency bumps. +> Sprint:推理模型参数过滤、本地提供商 404 修复、Kilo Gateway 提供商、依赖升级。 -### ✨ New Features +### ✨ 新特性 -- **feat(api)**: Added **Kilo Gateway** (`api.kilo.ai`) as a new API Key provider (alias `kg`) — 335+ models, 6 free models, 3 auto-routing models (`kilo-auto/frontier`, `kilo-auto/balanced`, `kilo-auto/free`). Passthrough models supported via `/api/gateway/models` endpoint. (PR #408 by @Regis-RCR) +- **feat(api)**:新增 **Kilo Gateway**(`api.kilo.ai`)作为新的 API Key 提供商(别名 `kg`)—— 335+ 模型,6 个免费模型,3 个自动路由模型(`kilo-auto/frontier`、`kilo-auto/balanced`、`kilo-auto/free`)。透传模型通过 `/api/gateway/models` 端点支持。(PR #408 by @Regis-RCR) -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(sse)**: Strip unsupported parameters for reasoning models (o1, o1-mini, o1-pro, o3, o3-mini). Models in the `o1`/`o3` family reject `temperature`, `top_p`, `frequency_penalty`, `presence_penalty`, `logprobs`, `top_logprobs`, and `n` with HTTP 400. Parameters are now stripped at the `chatCore` layer before forwarding. Uses a declarative `unsupportedParams` field per model and a precomputed O(1) Map for lookup. (PR #412 by @Regis-RCR) -- **fix(sse)**: Local provider 404 now results in a **model-only lockout (5 seconds)** instead of a connection-level lockout (2 minutes). When a local inference backend (Ollama, LM Studio, oMLX) returns 404 for an unknown model, the connection remains active and other models continue working immediately. Also fixes a pre-existing bug where `model` was not passed to `markAccountUnavailable()`. Local providers detected via hostname (`localhost`, `127.0.0.1`, `::1`, extensible via `LOCAL_HOSTNAMES` env var). (PR #410 by @Regis-RCR) +- **fix(sse)**:为推理模型(o1、o1-mini、o1-pro、o3、o3-mini)剥离不支持的参数。`o1`/`o3` 系列模型拒绝 `temperature`、`top_p`、`frequency_penalty`、`presence_penalty`、`logprobs`、`top_logprobs` 和 `n`,返回 HTTP 400。参数现在在转发前在 `chatCore` 层被剥离。使用每模型的声明式 `unsupportedParams` 字段和预计算的 O(1) Map 进行查找。(PR #412 by @Regis-RCR) +- **fix(sse)**:本地提供商 404 现在导致 **仅模型锁定(5 秒)**,而不是连接级锁定(2 分钟)。当本地推理后端(Ollama、LM Studio、oMLX)对未知模型返回 404 时,连接保持活跃,其他模型立即继续工作。同时修复了一个预先存在的 bug:`model` 未传递给 `markAccountUnavailable()`。通过主机名(`localhost`、`127.0.0.1`、`::1`,可通过 `LOCAL_HOSTNAMES` 环境变量扩展)检测本地提供商。(PR #410 by @Regis-RCR) -### 📦 Dependencies +### 📦 依赖 - `better-sqlite3` 12.6.2 → 12.8.0 - `undici` 7.24.2 → 7.24.4 @@ -1936,394 +1992,392 @@ OmniRoute now automatically refreshes model lists for connected providers every ## [2.6.4] — 2026-03-17 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(providers)**: Removed non-existent model names across 5 providers: - - **gemini / gemini-cli**: removed `gemini-3.1-pro/flash` and `gemini-3-*-preview` (don't exist in Google API v1beta); replaced with `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-2.0-flash`, `gemini-1.5-pro/flash` - - **antigravity**: removed `gemini-3.1-pro-high/low` and `gemini-3-flash` (invalid internal aliases); replaced with real 2.x models - - **github (Copilot)**: removed `gemini-3-flash-preview` and `gemini-3-pro-preview`; replaced with `gemini-2.5-flash` - - **nvidia**: corrected `nvidia/llama-3.3-70b-instruct` → `meta/llama-3.3-70b-instruct` (NVIDIA NIM uses `meta/` namespace for Meta models); added `nvidia/llama-3.1-70b-instruct` and `nvidia/llama-3.1-405b-instruct` -- **fix(db/combo)**: Updated `free-stack` combo on remote DB: removed `qw/qwen3-coder-plus` (expired refresh token), corrected `nvidia/llama-3.3-70b-instruct` → `nvidia/meta/llama-3.3-70b-instruct`, corrected `gemini/gemini-3.1-flash` → `gemini/gemini-2.5-flash`, added `if/deepseek-v3.2` +- **fix(providers)**:移除了 5 个提供商中不存在的模型名称: + - **gemini / gemini-cli**:移除了 `gemini-3.1-pro/flash` 和 `gemini-3-*-preview`(在 Google API v1beta 中不存在);替换为 `gemini-2.5-pro`、`gemini-2.5-flash`、`gemini-2.0-flash`、`gemini-1.5-pro/flash` + - **antigravity**:移除了 `gemini-3.1-pro-high/low` 和 `gemini-3-flash`(无效的内部别名);替换为真实的 2.x 模型 + - **github (Copilot)**:移除了 `gemini-3-flash-preview` 和 `gemini-3-pro-preview`;替换为 `gemini-2.5-flash` + - **nvidia**:修正了 `nvidia/llama-3.3-70b-instruct` → `meta/llama-3.3-70b-instruct`(NVIDIA NIM 对 Meta 模型使用 `meta/` 命名空间);新增了 `nvidia/llama-3.1-70b-instruct` 和 `nvidia/llama-3.1-405b-instruct` +- **fix(db/combo)**:更新了远程数据库中的 `free-stack` combo:移除了 `qw/qwen3-coder-plus`(刷新 token 过期),修正了 `nvidia/llama-3.3-70b-instruct` → `nvidia/meta/llama-3.3-70b-instruct`,修正了 `gemini/gemini-3.1-flash` → `gemini/gemini-2.5-flash`,新增了 `if/deepseek-v3.2` --- ## [2.6.3] — 2026-03-16 -> Sprint: zod/pino hash-strip baked into build pipeline, Synthetic provider added, VPS PM2 path corrected. +> Sprint:zod/pino hash-strip 烘焙到构建流水线中,新增 Synthetic 提供商,修正 VPS PM2 路径。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(build)**: Turbopack hash-strip now runs at **compile time** for ALL packages — not just `better-sqlite3`. Step 5.6 in `prepublish.mjs` walks every `.js` in `app/.next/server/` and strips the 16-char hex suffix from any hashed `require()`. Fixes `zod-dcb22c...`, `pino-...`, etc. MODULE_NOT_FOUND on global npm installs. Closes #398 -- **fix(deploy)**: PM2 on both VPS was pointing to stale git-clone directories. Reconfigured to `app/server.js` in the npm global package. Updated `/deploy-vps` workflow to use `npm pack + scp` (npm registry rejects 299MB packages). +- **fix(build)**:Turbopack hash-strip 现在在 **编译时** 对所有包运行 —— 不仅仅是 `better-sqlite3`。`prepublish.mjs` 中的步骤 5.6 遍历 `app/.next/server/` 中的每个 `.js` 文件,并从任何哈希化的 `require()` 中剥离 16 字符十六进制后缀。修复了全局 npm 安装中的 `zod-dcb22c...`、`pino-...` 等 MODULE_NOT_FOUND 问题。关闭 #398 +- **fix(deploy)**:两个 VPS 上的 PM2 指向了过时的 git-clone 目录。重新配置为 npm 全局包中的 `app/server.js`。更新了 `/deploy-vps` 工作流,使用 `npm pack + scp`(npm 注册表拒绝 299MB 的包)。 -### 功能特点 +### ✨ 新特性 -- **feat(provider)**: Synthetic ([synthetic.new](https://synthetic.new)) — privacy-focused OpenAI-compatible inference. `passthroughModels: true` for dynamic HuggingFace model catalog. Initial models: Kimi K2.5, MiniMax M2.5, GLM 4.7, DeepSeek V3.2. (PR #404 by @Regis-RCR) +- **feat(provider)**:Synthetic([synthetic.new](https://synthetic.new))—— 注重隐私的 OpenAI 兼容推理。`passthroughModels: true`,用于动态 HuggingFace 模型目录。初始模型:Kimi K2.5、MiniMax M2.5、GLM 4.7、DeepSeek V3.2。(PR #404 by @Regis-RCR) -### 📋 Issues Closed +### 📋 已关闭的问题 -- **close #398**: npm hash regression — fixed by compile-time hash-strip in prepublish -- **triage #324**: Bug screenshot without steps — requested reproduction details +- **close #398**:npm hash 回归 —— 通过编译时 hash-strip 在 prepublish 中修复 +- **triage #324**:没有步骤的 bug 截图 —— 请求重现详情 --- ## [2.6.2] — 2026-03-16 -> Sprint: module hashing fully fixed, 2 PRs merged (Anthropic tools filter + custom endpoint paths), Alibaba Cloud DashScope provider added, 3 stale issues closed. +> Sprint:模块哈希完全修复,合并 2 个 PR(Anthropic 工具过滤 + 自定义端点路径),新增 Alibaba Cloud DashScope 提供商,关闭 3 个陈旧问题。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(build)**: Extended webpack `externals` hash-strip to cover ALL `serverExternalPackages`, not just `better-sqlite3`. Next.js 16 Turbopack hashes `zod`, `pino`, and every other server-external package into names like `zod-dcb22c6336e0bc69` that don't exist in `node_modules` at runtime. A HASH_PATTERN regex catch-all now strips the 16-char suffix and falls back to the base package name. Also added `NEXT_PRIVATE_BUILD_WORKER=0` in `prepublish.mjs` to reinforce webpack mode, plus a post-build scan that reports any remaining hashed refs. (#396, #398, PR #403) -- **fix(chat)**: Anthropic-format tool names (`tool.name` without `.function` wrapper) were silently dropped by the empty-name filter introduced in #346. LiteLLM proxies requests with `anthropic/` prefix in Anthropic Messages API format, causing all tools to be filtered and Anthropic to return `400: tool_choice.any may only be specified while providing tools`. Fixed by falling back to `tool.name` when `tool.function.name` is absent. Added 8 regression unit tests. (PR #397) +- **fix(build)**:扩展 webpack `externals` hash-strip 以覆盖所有 `serverExternalPackages`,而不仅仅是 `better-sqlite3`。Next.js 16 Turbopack 将 `zod`、`pino` 和其他服务器外部包哈希化为类似 `zod-dcb22c6336e0bc69` 的名称,这些名称在运行时不存在于 `node_modules` 中。HASH_PATTERN 正则捕获所有情况现在剥离 16 字符后缀并回退到基础包名。还在 `prepublish.mjs` 中添加了 `NEXT_PRIVATE_BUILD_WORKER=0` 以加强 webpack 模式,以及构建后扫描报告任何剩余的哈希引用。(#396、#398、PR #403) +- **fix(chat)**:Anthropic 格式的工具名称(不带 `.function` 包装的 `tool.name`)被 #346 引入的空名称过滤器静默丢弃。LiteLLM 代理请求在 Anthropic Messages API 格式中使用 `anthropic/` 前缀,导致所有工具被过滤,Anthropic 返回 `400: tool_choice.any may only be specified while providing tools`。通过在 `tool.function.name` 缺失时回退到 `tool.name` 修复。添加了 8 个回归单元测试。(PR #397) -### 功能特点 +### ✨ 新特性 -- **feat(api)**: Custom endpoint paths for OpenAI-compatible provider nodes — configure `chatPath` and `modelsPath` per node (e.g. `/v4/chat/completions`) in the provider connection UI. Includes a DB migration (`003_provider_node_custom_paths.sql`) and URL path sanitization (no `..` traversal, must start with `/`). (PR #400) -- **feat(provider)**: Alibaba Cloud DashScope added as OpenAI-compatible provider. International endpoint: `dashscope-intl.aliyuncs.com/compatible-mode/v1`. 12 models: `qwen-max`, `qwen-plus`, `qwen-turbo`, `qwen3-coder-plus/flash`, `qwq-plus`, `qwq-32b`, `qwen3-32b`, `qwen3-235b-a22b`. Auth: Bearer API key. +- **feat(api)**:OpenAI 兼容提供商节点的自定义端点路径 —— 在提供商连接 UI 中为每个节点配置 `chatPath` 和 `modelsPath`(例如 `/v4/chat/completions`)。包括数据库迁移(`003_provider_node_custom_paths.sql`)和 URL 路径清理(无 `..` 遍历,必须以 `/` 开头)。(PR #400) +- **feat(provider)**:新增 Alibaba Cloud DashScope 作为 OpenAI 兼容提供商。国际端点:`dashscope-intl.aliyuncs.com/compatible-mode/v1`。12 个模型:`qwen-max`、`qwen-plus`、`qwen-turbo`、`qwen3-coder-plus/flash`、`qwq-plus`、`qwq-32b`、`qwen3-32b`、`qwen3-235b-a22b`。认证:Bearer API key。 -### 📋 Issues Closed +### 📋 已关闭的问题 -- **close #323**: Cline connection error `[object Object]` — fixed in v2.3.7; instructed user to upgrade from v2.2.9 -- **close #337**: Kiro credit tracking — implemented in v2.5.5 (#381); pointed user to Dashboard → Usage -- **triage #402**: ARM64 macOS DMG damaged — requested macOS version, exact error, and advised `xattr -d com.apple.quarantine` workaround +- **close #323**:Cline 连接错误 `[object Object]` —— 已在 v2.3.7 修复;指导用户从 v2.2.9 升级 +- **close #337**:Kiro 积分追踪 —— 已在 v2.5.5(#381)实现;引导用户查看 Dashboard → Usage +- **triage #402**:ARM64 macOS DMG 损坏 —— 请求 macOS 版本、具体错误,并建议 `xattr -d com.apple.quarantine` 解决方案 --- ## [2.6.1] — 2026-03-15 -> Critical startup fix: v2.6.0 global npm installs crashed with a 500 error due to a Turbopack/webpack module-name hashing bug in the Next.js 16 instrumentation hook. +> 关键启动修复:v2.6.0 全局 npm 安装崩溃,出现 500 错误,原因是 Next.js 16 instrumentation hook 中的 Turbopack/webpack 模块名哈希 bug。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(build)**: Force `better-sqlite3` to always be required by its exact package name in the webpack server bundle. Next.js 16 compiled the instrumentation hook into a separate chunk and emitted `require('better-sqlite3-')` — a hashed module name that doesn't exist in `node_modules` — even though the package was listed in `serverExternalPackages`. Added an explicit `externals` function to the server webpack config so the bundler always emits `require('better-sqlite3')`, resolving the startup `500 Internal Server Error` on clean global installs. (#394, PR #395) +- **fix(build)**:强制 `better-sqlite3` 在 webpack 服务器包中始终以其精确的包名被 require。Next.js 16 将 instrumentation hook 编译到单独的 chunk 中,并发出 `require('better-sqlite3-')` —— 一个不存在的哈希模块名在 `node_modules` 中 —— 即使该包列在 `serverExternalPackages` 中。为服务器 webpack 配置添加了显式的 `externals` 函数,使打包器始终发出 `require('better-sqlite3')`,解决了干净全局安装中的启动 `500 Internal Server Error`。(#394,PR #395) ### 🔧 CI -- **ci**: Added `workflow_dispatch` to `npm-publish.yml` with version sync safeguard for manual triggers (#392) -- **ci**: Added `workflow_dispatch` to `docker-publish.yml`, updated GitHub Actions to latest versions (#392) +- **ci**:为 `npm-publish.yml` 添加了 `workflow_dispatch`,带版本同步保护,用于手动触发(#392) +- **ci**:为 `docker-publish.yml` 添加了 `workflow_dispatch`,将 GitHub Actions 更新到最新版本(#392) --- ## [2.6.0] - 2026-03-15 -> Issue resolution sprint: 4 bugs fixed, logs UX improved, Kiro credit tracking added. +> 问题解决冲刺:4 个 bug 修复、日志 UX 改进、新增 Kiro 积分追踪。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(media)**: ComfyUI and SD WebUI no longer appear in the Media page provider list when unconfigured — fetches `/api/providers` on mount and hides local providers with no connections (#390) -- **fix(auth)**: Round-robin no longer re-selects rate-limited accounts immediately after cooldown — `backoffLevel` is now used as primary sort key in the LRU rotation (#340) -- **fix(oauth)**: Qoder (and other providers that redirect to their own UI) no longer leave the OAuth modal stuck at "Waiting for Authorization" — popup-closed detector auto-transitions to manual URL input mode (#344) -- **fix(logs)**: Request log table is now readable in light mode — status badges, token counts, and combo tags use adaptive `dark:` color classes (#378) +- **fix(media)**:未配置时 ComfyUI 和 SD WebUI 不再出现在媒体页面的提供商列表中 —— 挂载时获取 `/api/providers` 并隐藏没有连接的本地提供商(#390) +- **fix(auth)**:Round-robin 不再在冷却后立即重新选择受限账户 —— `backoffLevel` 现在用作 LRU 轮换中的主要排序键(#340) +- **fix(oauth)**:Qoder(和其他重定向到自己 UI 的提供商)不再让 OAuth 模态框卡在 "Waiting for Authorization" —— 弹窗关闭检测器自动切换到手动 URL 输入模式(#344) +- **fix(logs)**:请求日志表现在在浅色模式下可读 —— 状态徽章、token 计数和 combo 标签使用自适应 `dark:` 颜色类(#378) -### 功能特点 +### ✨ 新特性 -- **feat(kiro)**: Kiro credit tracking added to usage fetcher — queries `getUserCredits` from AWS CodeWhisperer endpoint (#337) +- **feat(kiro)**:用量抓取器中新增 Kiro 积分追踪 —— 从 AWS CodeWhisperer 端点查询 `getUserCredits`(#337) -### 🛠 Chores - -- **chore(tests)**: Aligned `test:plan3`, `test:fixes`, `test:security` to use same `tsx/esm` loader as `npm test` — eliminates module resolution false negatives in targeted runs (PR #386) +### 🛠 杂项 --- ## [2.5.9] - 2026-03-15 -> Codex native passthrough fix + route body validation hardening. +> Codex 原生透传修复 + 路由体验证强化。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(codex)**: Preserve native Responses API passthrough for Codex clients — avoids unnecessary translation mutations (PR #387) -- **fix(api)**: Validate request bodies on pricing/sync and task-routing routes — prevents crashes from malformed inputs (PR #388) -- **fix(auth)**: JWT secrets persist across restarts via `src/lib/db/secrets.ts` — eliminates 401 errors after pm2 restart (PR #388) +- **fix(codex)**:为 Codex 客户端保留原生 Responses API 透传 —— 避免不必要的翻译变更(PR #387) +- **fix(api)**:验证 pricing/sync 和 task-routing 路由中的请求体 —— 防止畸形输入导致崩溃(PR #388) +- **fix(auth)**:JWT 密钥在重启间持久化,通过 `src/lib/db/secrets.ts` —— 消除 pm2 重启后的 401 错误(PR #388) --- ## [2.5.8] - 2026-03-15 -> Build fix: restore VPS connectivity broken by v2.5.7 incomplete publish. +> 构建修复:恢复因 v2.5.7 不完整发布而中断的 VPS 连接。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(build)**: `scripts/prepublish.mjs` still used deprecated `--webpack` flag causing Next.js standalone build to fail silently — npm publish completed without `app/server.js`, breaking VPS deployment +- **fix(build)**:`scripts/prepublish.mjs` 仍使用已弃用的 `--webpack` 标志,导致 Next.js 独立构建静默失败 —— npm 发布时缺少 `app/server.js`,破坏了 VPS 部署 --- ## [2.5.7] - 2026-03-15 -> Media playground error handling fixes. +> 媒体游乐场错误处理修复。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(media)**: Transcription "API Key Required" false positive when audio contains no speech (music, silence) — now shows "No speech detected" instead -- **fix(media)**: `upstreamErrorResponse` in `audioTranscription.ts` and `audioSpeech.ts` now returns proper JSON (`{error:{message}}`), enabling correct 401/403 credential error detection in the MediaPageClient -- **fix(media)**: `parseApiError` now handles Deepgram's `err_msg` field and detects `"api key"` in error messages for accurate credential error classification +- **fix(media)**:当音频不包含语音(音乐、静音)时,转录显示 "API Key Required" 误报 —— 现在显示 "No speech detected" +- **fix(media)**:`audioTranscription.ts` 和 `audioSpeech.ts` 中的 `upstreamErrorResponse` 现在返回正确的 JSON(`{error:{message}}`),使 MediaPageClient 能够正确检测 401/403 凭证错误 +- **fix(media)**:`parseApiError` 现在处理 Deepgram 的 `err_msg` 字段,并在错误消息中检测 `"api key"`,用于准确的凭证错误分类 --- ## [2.5.6] - 2026-03-15 -> Critical security/auth fixes: Antigravity OAuth broken + JWT sessions lost after restart. +> 关键安全/认证修复:Antigravity OAuth 损坏 + 重启后 JWT 会话丢失。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(oauth) #384**: Antigravity Google OAuth now correctly sends `client_secret` to the token endpoint. The fallback for `ANTIGRAVITY_OAUTH_CLIENT_SECRET` was an empty string, which is falsy — so `client_secret` was never included in the request, causing `"client_secret is missing"` errors for all users without a custom env var. Closes #383. -- **fix(auth) #385**: `JWT_SECRET` is now persisted to SQLite (`namespace='secrets'`) on first generation and reloaded on subsequent starts. Previously, a new random secret was generated each process startup, invalidating all existing cookies/sessions after any restart or upgrade. Affects both `JWT_SECRET` and `API_KEY_SECRET`. Closes #382. +- **fix(oauth) #384**:Antigravity Google OAuth 现在正确向 token 端点发送 `client_secret`。`ANTIGRAVITY_OAUTH_CLIENT_SECRET` 的回退是空字符串,为假值 —— 因此 `client_secret` 从未包含在请求中,导致所有没有自定义环境变量的用户出现 `"client_secret is missing"` 错误。关闭 #383。 +- **fix(auth) #385**:`JWT_SECRET` 现在在首次生成时持久化到 SQLite(`namespace='secrets'`),并在后续启动时重新加载。此前,每次进程启动时都会生成新的随机密钥,导致任何重启或升级后所有现有 cookie/会话失效。影响 `JWT_SECRET` 和 `API_KEY_SECRET`。关闭 #382。 --- ## [2.5.5] - 2026-03-15 -> Model list dedup fix, Electron standalone build hardening, and Kiro credit tracking. +> 模型列表去重修复、Electron 独立构建强化和 Kiro 积分追踪。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix(models) #380**: `GET /api/models` now includes provider aliases when building the active-provider filter — models for `claude` (alias `cc`) and `github` (alias `gh`) were always shown regardless of whether a connection was configured, because `PROVIDER_MODELS` keys are aliases but DB connections are stored under provider IDs. Fixed by expanding each active provider ID to also include its alias via `PROVIDER_ID_TO_ALIAS`. Closes #353. -- **fix(electron) #379**: New `scripts/prepare-electron-standalone.mjs` stages a dedicated `/.next/electron-standalone` bundle before Electron packaging. Aborts with a clear error if `node_modules` is a symlink (electron-builder would ship a runtime dependency on the build machine). Cross-platform path sanitization via `path.basename`. By @kfiramar. +- **fix(models) #380**:`GET /api/models` 现在在构建活跃提供商过滤器时包含提供商别名 —— `claude`(别名 `cc`)和 `github`(别名 `gh`)的模型始终显示,无论是否配置了连接,因为 `PROVIDER_MODELS` 键是别名,但数据库连接存储在提供商 ID 下。通过扩展每个活跃提供商 ID 以通过 `PROVIDER_ID_TO_ALIAS` 包含其别名来修复。关闭 #353。 +- **fix(electron) #379**:新增 `scripts/prepare-electron-standalone.mjs`,在 Electron 打包前准备专用的 `/.next/electron-standalone` 包。如果 `node_modules` 是符号链接则中止并显示清晰错误(electron-builder 会将构建机器上的运行时依赖打包)。通过 `path.basename` 进行跨平台路径清理。By @kfiramar。 -### ✨ New Features +### ✨ 新特性 -- **feat(kiro) #381**: Kiro credit balance tracking — usage endpoint now returns credit data for Kiro accounts by calling `codewhisperer.us-east-1.amazonaws.com/getUserCredits` (same endpoint Kiro IDE uses internally). Returns remaining credits, total allowance, renewal date, and subscription tier. Closes #337. +- **feat(kiro) #381**:Kiro 积分余额追踪 —— 通过调用 `codewhisperer.us-east-1.amazonaws.com/getUserCredits`(与 Kiro IDE 内部使用的端点相同),用量端点现在为 Kiro 账户返回积分数据。返回剩余积分、总额度、续订日期和订阅层级。关闭 #337。 ## [2.5.4] - 2026-03-15 -> Logger startup fix, login bootstrap security fix, and dev HMR reliability improvement. CI infrastructure hardened. +> 日志器启动修复、登录引导安全修复和开发 HMR 可靠性改进。CI 基础设施强化。 -### 🐛 Bug Fixes (PRs #374, #375, #376 by @kfiramar) +### 🐛 Bug 修复(PRs #374, #375, #376 by @kfiramar) -- **fix(logger) #376**: Restore pino transport logger path — `formatters.level` combined with `transport.targets` is rejected by pino. Transport-backed configs now strip the level formatter via `getTransportCompatibleConfig()`. Also corrects numeric level mapping in `/api/logs/console`: `30→info, 40→warn, 50→error` (was shifted by one). -- **fix(login) #375**: Login page now bootstraps from the public `/api/settings/require-login` endpoint instead of the protected `/api/settings`. In password-protected setups, the pre-auth page was receiving a 401 and falling back to safe defaults unnecessarily. The public route now returns all bootstrap metadata (`requireLogin`, `hasPassword`, `setupComplete`) with a conservative 200 fallback on error. -- **fix(dev) #374**: Add `localhost` and `127.0.0.1` to `allowedDevOrigins` in `next.config.mjs` — HMR websocket was blocked when accessing the app via loopback address, producing repeated cross-origin warnings. +- **fix(logger) #376**:恢复 pino 传输日志器路径 —— pino 拒绝 `formatters.level` 与 `transport.targets` 组合使用。传输支持的配置现在通过 `getTransportCompatibleConfig()` 剥离级别格式化器。同时修正了 `/api/logs/console` 中的数字级别映射:`30→info, 40→warn, 50→error`(此前偏移了一位)。 +- **fix(login) #375**:登录页面现在从公共 `/api/settings/require-login` 端点引导,而不是受保护的 `/api/settings`。在密码保护设置中,预认证页面收到 401 并不必要地回退到安全默认值。公共路由现在返回所有引导元数据(`requireLogin`、`hasPassword`、`setupComplete`),错误时使用保守的 200 回退。 +- **fix(dev) #374**:在 `next.config.mjs` 中将 `localhost` 和 `127.0.0.1` 添加到 `allowedDevOrigins` —— 通过回环地址访问应用时 HMR websocket 被阻塞,产生重复的跨域警告。 -### 🔧 CI & Infrastructure +### 🔧 CI 与基础设施 -- **ESLint OOM fix**: `eslint.config.mjs` now ignores `vscode-extension/**`, `electron/**`, `docs/**`, `app/.next/**`, and `clipr/**` — ESLint was crashing with a JS heap OOM by scanning VS Code binary blobs and compiled chunks. -- **Unit test fix**: Removed stale `ALTER TABLE provider_connections ADD COLUMN "group"` from 2 test files — column is now part of the base schema (added in #373), causing `SQLITE_ERROR: duplicate column name` on every CI run. -- **Pre-commit hook**: Added `npm run test:unit` to `.husky/pre-commit` — unit tests now block broken commits before they reach CI. +- **ESLint OOM 修复**:`eslint.config.mjs` 现在忽略 `vscode-extension/**`、`electron/**`、`docs/**`、`app/.next/**` 和 `clipr/**` —— ESLint 因扫描 VS Code 二进制 blob 和编译块导致 JS 堆 OOM 崩溃。 +- **单元测试修复**:从 2 个测试文件中移除了过时的 `ALTER TABLE provider_connections ADD COLUMN "group"` —— 该列现在是基础 schema 的一部分(在 #373 中添加),导致每次 CI 运行出现 `SQLITE_ERROR: duplicate column name`。 +- **Pre-commit 钩子**:在 `.husky/pre-commit` 中添加了 `npm run test:unit` —— 单元测试现在在到达 CI 之前阻止损坏的提交。 ## [2.5.3] - 2026-03-14 -> Critical bugfixes: DB schema migration, startup env loading, provider error state clearing, and i18n tooltip fix. Code quality improvements on top of each PR. +> 关键 bug 修复:数据库 schema 迁移、启动环境加载、提供商错误状态清除和 i18n 工具提示修复。每个 PR 顶部的代码质量改进。 -### 🐛 Bug Fixes (PRs #369, #371, #372, #373 by @kfiramar) +### 🐛 Bug 修复(PRs #369, #371, #372, #373 by @kfiramar) -- **fix(db) #373**: Add `provider_connections.group` column to base schema + backfill migration for existing databases — column was used in all queries but missing from schema definition -- **fix(i18n) #371**: Replace non-existent `t("deleteConnection")` key with existing `providers.delete` key — fixes `MISSING_MESSAGE: providers.deleteConnection` runtime error on provider detail page -- **fix(auth) #372**: Clear stale error metadata (`errorCode`, `lastErrorType`, `lastErrorSource`) from provider accounts after genuine recovery — previously, recovered accounts kept appearing as failed -- **fix(startup) #369**: Unify env loading across `npm run start`, `run-standalone.mjs`, and Electron to respect `DATA_DIR/.env → ~/.omniroute/.env → ./.env` priority — prevents generating a new `STORAGE_ENCRYPTION_KEY` over an existing encrypted database +- **fix(db) #373**:为基础 schema 添加 `provider_connections.group` 列 + 回填迁移,用于现有数据库 —— 该列在所有查询中使用,但在 schema 定义中缺失 +- **fix(i18n) #371**:用现有的 `providers.delete` 键替换不存在的 `t("deleteConnection")` 键 —— 修复提供商详情页面的 `MISSING_MESSAGE: providers.deleteConnection` 运行时错误 +- **fix(auth) #372**:在真正恢复后清除提供商账户中的陈旧错误元数据(`errorCode`、`lastErrorType`、`lastErrorSource`)—— 此前,恢复的账户继续显示为失败 +- **fix(startup) #369**:统一 `npm run start`、`run-standalone.mjs` 和 Electron 中的环境加载,遵循 `DATA_DIR/.env → ~/.omniroute/.env → ./.env` 优先级 —— 防止在现有加密数据库上生成新的 `STORAGE_ENCRYPTION_KEY` -### 🔧 Code Quality +### 🔧 代码质量 -- Documented `result.success` vs `response?.ok` patterns in `auth.ts` (both intentional, now explained) -- Normalized `overridePath?.trim()` in `electron/main.js` to match `bootstrap-env.mjs` -- Added `preferredEnv` merge order comment in Electron startup +- 记录了 `auth.ts` 中 `result.success` 与 `response?.ok` 模式(两者都是有意为之,现已说明) +- 在 `electron/main.js` 中规范化了 `overridePath?.trim()` 以匹配 `bootstrap-env.mjs` +- 在 Electron 启动中添加了 `preferredEnv` 合并顺序注释 -> Codex account quota policy with auto-rotation, fast tier toggle, gpt-5.4 model, and analytics label fix. +> Codex 账户配额策略,带自动轮换、快速层级切换、gpt-5.4 模型和分析标签修复。 -### ✨ New Features (PRs #366, #367, #368) +### ✨ 新特性(PRs #366, #367, #368) -- **Codex Quota Policy (PR #366)**: Per-account 5h/weekly quota window toggles in Provider dashboard. Accounts are automatically skipped when enabled windows reach 90% threshold and re-admitted after `resetAt`. Includes `quotaCache.ts` with side-effect free status getter. -- **Codex Fast Tier Toggle (PR #367)**: Dashboard → Settings → Codex Service Tier. Default-off toggle injects `service_tier: "flex"` only for Codex requests, reducing cost ~80%. Full stack: UI tab + API endpoint + executor + translator + startup restore. -- **gpt-5.4 Model (PR #368)**: Adds `cx/gpt-5.4` and `codex/gpt-5.4` to the Codex model registry. Regression test included. +- **Codex 配额策略(PR #366)**:提供商仪表盘中的每账户 5h/每周配额窗口开关。当启用的窗口达到 90% 阈值时自动跳过账户,并在 `resetAt` 后重新接纳。包括 `quotaCache.ts`,带无副作用的状态获取器。 +- **Codex 快速层级切换(PR #367)**:Dashboard → Settings → Codex Service Tier。默认关闭的开关仅为 Codex 请求注入 `service_tier: "flex"`,降低成本约 80%。全栈:UI 标签页 + API 端点 + 执行器 + 翻译器 + 启动恢复。 +- **gpt-5.4 模型(PR #368)**:为 Codex 模型注册表添加 `cx/gpt-5.4` 和 `codex/gpt-5.4`。包含回归测试。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix #356**: Analytics charts (Top Provider, By Account, Provider Breakdown) now display human-readable provider names/labels instead of raw internal IDs for OpenAI-compatible providers. +- **fix #356**:分析图表(顶级提供商、按账户、提供商拆分)现在为 OpenAI 兼容提供商显示人类可读的提供商名称/标签,而不是原始内部 ID。 -> Major release: strict-random routing strategy, API key access controls, connection groups, external pricing sync, and critical bug fixes for thinking models, combo testing, and tool name validation. +> 主要发布:strict-random 路由策略、API key 访问控制、连接组、外部定价同步和 thinking 模型、combo 测试、工具名称验证的关键 bug 修复。 -### ✨ New Features (PRs #363 & #365) +### ✨ 新特性(PRs #363 & #365) -- **Strict-Random Routing Strategy**: Fisher-Yates shuffle deck with anti-repeat guarantee and mutex serialization for concurrent requests. Independent decks per combo and per provider. -- **API Key Access Controls**: `allowedConnections` (restrict which connections a key can use), `is_active` (enable/disable key with 403), `accessSchedule` (time-based access control), `autoResolve` toggle, rename keys via PATCH. -- **Connection Groups**: Group provider connections by environment. Accordion view in Limits page with localStorage persistence and smart auto-switch. -- **External Pricing Sync (LiteLLM)**: 3-tier pricing resolution (user overrides → synced → defaults). Opt-in via `PRICING_SYNC_ENABLED=true`. MCP tool `omniroute_sync_pricing`. 23 new tests. -- **i18n**: 30 languages updated with strict-random strategy, API key management strings. pt-BR fully translated. +- **Strict-Random 路由策略**:Fisher-Yates 洗牌牌组,带防重复保证和并发请求的互斥序列化。每个 combo 和每个提供商独立的牌组。 +- **API Key 访问控制**:`allowedConnections`(限制 key 可使用的连接)、`is_active`(启用/禁用 key,返回 403)、`accessSchedule`(基于时间的访问控制)、`autoResolve` 开关、通过 PATCH 重命名 key。 +- **连接组**:按环境分组提供商连接。Limits 页面中的手风琴视图,使用 localStorage 持久化和智能自动切换。 +- **外部定价同步(LiteLLM)**:3 层定价解析(用户覆盖 → 同步 → 默认)。通过 `PRICING_SYNC_ENABLED=true` 选择加入。MCP 工具 `omniroute_sync_pricing`。23 个新测试。 +- **i18n**:30 种语言更新,使用 strict-random 策略、API key 管理字符串。pt-BR 完全翻译。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **fix #355**: Stream idle timeout increased from 60s to 300s — prevents aborting extended-thinking models (claude-opus-4-6, o3, etc.) during long reasoning phases. Configurable via `STREAM_IDLE_TIMEOUT_MS`. -- **fix #350**: Combo test now bypasses `REQUIRE_API_KEY=true` using internal header, and uses OpenAI-compatible format universally. Timeout extended from 15s to 20s. -- **fix #346**: Tools with empty `function.name` (forwarded by Claude Code) are now filtered before upstream providers receive them, preventing "Invalid input[N].name: empty string" errors. +- **fix #355**:流空闲超时从 60 秒增加到 300 秒 —— 防止在长时间推理阶段中止扩展 thinking 模型(claude-opus-4-6、o3 等)。可通过 `STREAM_IDLE_TIMEOUT_MS` 配置。 +- **fix #350**:Combo 测试现在使用内部头绕过 `REQUIRE_API_KEY=true`,并普遍使用 OpenAI 兼容格式。超时从 15 秒延长到 20 秒。 +- **fix #346**:使用空 `function.name` 的工具(由 Claude Code 转发)现在在到达上游提供商之前被过滤,防止 "Invalid input[N].name: empty string" 错误。 -### 🗑️ Closed Issues +### 🗑️ 已关闭的问题 -- **#341**: Debug section removed — replacement is `/dashboard/logs` and `/dashboard/health`. +- **#341**:调试部分已移除 —— 替换为 `/dashboard/logs` 和 `/dashboard/health`。 -> API Key Round-Robin support for multi-key provider setups, and confirmation of wildcard routing and quota window rolling already in place. +> API Key Round-Robin 支持,用于多 key 提供商设置,以及确认通配符路由和配额窗口滚动已就位。 -### ✨ New Features +### ✨ 新特性 -- **API Key Round-Robin (T07)**: Provider connections can now hold multiple API keys (Edit Connection → Extra API Keys). Requests rotate round-robin between primary + extra keys via `providerSpecificData.extraApiKeys[]`. Keys are held in-memory indexed per connection — no DB schema changes required. +- **API Key Round-Robin (T07)**:提供商连接现在可以持有多个 API key(编辑连接 → 额外 API key)。请求在主 key + 额外 key 之间轮转,通过 `providerSpecificData.extraApiKeys[]`。key 按连接在内存中索引持有 —— 无需数据库 schema 变更。 -### 📝 Already Implemented (confirmed in audit) +### 📝 已实现(审计确认) -- **Wildcard Model Routing (T13)**: `wildcardRouter.ts` with glob-style wildcard matching (`gpt*`, `claude-?-sonnet`, etc.) is already integrated into `model.ts` with specificity ranking. -- **Quota Window Rolling (T08)**: `accountFallback.ts:isModelLocked()` already auto-advances the window — if `Date.now() > entry.until`, lock is deleted immediately (no stale blocking). +- **通配符模型路由 (T13)**:`wildcardRouter.ts` 使用 glob 风格通配符匹配(`gpt*`、`claude-?-sonnet` 等)已集成到 `model.ts` 中,带特异性排名。 +- **配额窗口滚动 (T08)**:`accountFallback.ts:isModelLocked()` 已自动推进窗口 —— 如果 `Date.now() > entry.until`,锁立即删除(无陈旧阻塞)。 -> UI polish, routing strategy additions, and graceful error handling for usage limits. +> UI 打磨、路由策略补充和用量限制的优雅错误处理。 -### ✨ New Features +### ✨ 新特性 -- **Fill-First & P2C Routing Strategies**: Added `fill-first` (drain quota before moving on) and `p2c` (Power-of-Two-Choices low-latency selection) to combo strategy picker, with full guidance panels and color-coded badges. -- **Free Stack Preset Models**: Creating a combo with the Free Stack template now auto-fills 7 best-in-class free provider models (Gemini CLI, Kiro, Qoder×2, Qwen, NVIDIA NIM, Groq). Users just activate the providers and get a $0/month combo out-of-the-box. -- **Wider Combo Modal**: Create/Edit combo modal now uses `max-w-4xl` for comfortable editing of large combos. +- **Fill-First & P2C 路由策略**:为 combo 策略选择器添加了 `fill-first`(在继续之前排空配额)和 `p2c`(Power-of-Two-Choices 低延迟选择),带完整指导面板和颜色编码徽章。 +- **Free Stack 预设模型**:使用 Free Stack 模板创建 combo 时,现在自动填充 7 个最佳免费提供商模型(Gemini CLI、Kiro、Qoder×2、Qwen、NVIDIA NIM、Groq)。用户只需激活提供商即可获得开箱即用的 $0/月 combo。 +- **更宽的 Combo 模态框**:创建/编辑 combo 模态框现在使用 `max-w-4xl`,以便舒适地编辑大型 combo。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Limits page HTTP 500 for Codex & GitHub**: `getCodexUsage()` and `getGitHubUsage()` now return a user-friendly message when the provider returns 401/403 (expired token), instead of throwing and causing a 500 error on the Limits page. -- **MaintenanceBanner false-positive**: Banner no longer shows "Server is unreachable" spuriously on page load. Fixed by calling `checkHealth()` immediately on mount and removing stale `show`-state closure. -- **Provider icon tooltips**: Edit (pencil) and delete icon buttons in the provider connection row now have native HTML tooltips — all 6 action icons are now self-documented. +- **Limits 页面 HTTP 500(用于 Codex & GitHub)**:当提供商返回 401/403(过期 token)时,`getCodexUsage()` 和 `getGitHubUsage()` 现在返回用户友好的消息,而不是抛出异常导致 Limits 页面出现 500 错误。 +- **MaintenanceBanner 误报**:横幅不再在页面加载时虚假显示 "Server is unreachable"。通过在挂载时立即调用 `checkHealth()` 并移除陈旧的 `show` 状态闭包来修复。 +- **提供商图标工具提示**:提供商连接行中的编辑(铅笔)和删除图标按钮现在有原生 HTML 工具提示 —— 所有 6 个操作图标现在都有自文档说明。 -> Multiple improvements from community issue analysis, new provider support, bug fixes for token tracking, model routing, and streaming reliability. +> 来自社区问题分析的多项改进、新提供商支持、token 追踪、模型路由和流式传输可靠性的 bug 修复。 -### ✨ New Features +### ✨ 新特性 -- **Task-Aware Smart Routing (T05)**: Automatic model selection based on request content type — coding → deepseek-chat, analysis → gemini-2.5-pro, vision → gpt-4o, summarization → gemini-2.5-flash. Configurable via Settings. New `GET/PUT/POST /api/settings/task-routing` API. -- **HuggingFace Provider**: Added HuggingFace Router as an OpenAI-compatible provider with Llama 3.1 70B/8B, Qwen 2.5 72B, Mistral 7B, Phi-3.5 Mini. -- **Vertex AI Provider**: Added Vertex AI (Google Cloud) provider with Gemini 2.5 Pro/Flash, Gemma 2 27B, Claude via Vertex. -- **Playground File Uploads**: Audio upload for transcription, image upload for vision models (auto-detect by model name), inline image rendering for image generation results. -- **Model Select Visual Feedback**: Already-added models in combo picker now show ✓ green badge — prevents duplicate confusion. -- **Qwen Compatibility (PR #352)**: Updated User-Agent and CLI fingerprint settings for Qwen provider compatibility. -- **Round-Robin State Management (PR #349)**: Enhanced round-robin logic to handle excluded accounts and maintain rotation state correctly. -- **Clipboard UX (PR #360)**: Hardened clipboard operations with fallback for non-secure contexts; Claude tool normalization improvements. +- **任务感知智能路由 (T05)**:基于请求内容类型的自动模型选择 —— 编码 → deepseek-chat,分析 → gemini-2.5-pro,视觉 → gpt-4o,摘要 → gemini-2.5-flash。可通过设置配置。新增 `GET/PUT/POST /api/settings/task-routing` API。 +- **HuggingFace 提供商**:新增 HuggingFace Router 作为 OpenAI 兼容提供商,使用 Llama 3.1 70B/8B、Qwen 2.5 72B、Mistral 7B、Phi-3.5 Mini。 +- **Vertex AI 提供商**:新增 Vertex AI (Google Cloud) 提供商,使用 Gemini 2.5 Pro/Flash、Gemma 2 27B、Claude(通过 Vertex)。 +- **游乐场文件上传**:用于转录的音频上传、用于视觉模型的图像上传(按模型名称自动检测)、用于图像生成结果的内联图像渲染。 +- **模型选择视觉反馈**:已在 combo 选择器中添加的模型现在显示 ✓ 绿色徽章 —— 防止重复混淆。 +- **Qwen 兼容性 (PR #352)**:更新了 User-Agent 和 CLI 指纹设置,用于 Qwen 提供商兼容性。 +- **Round-Robin 状态管理 (PR #349)**:增强了 round-robin 逻辑以处理排除的账户并正确维护轮换状态。 +- **剪贴板 UX (PR #360)**:加固了剪贴板操作,带非安全上下文的回退;Claude 工具规范化改进。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Fix #302 — OpenAI SDK stream=False drops tool_calls**: T01 Accept header negotiation no longer forces streaming when `body.stream` is explicitly `false`. Was causing tool_calls to be silently dropped when using the OpenAI Python SDK in non-streaming mode. -- **Fix #73 — Claude Haiku routed to OpenAI without provider prefix**: `claude-*` models sent without a provider prefix now correctly route to the `antigravity` (Anthropic) provider. Added `gemini-*`/`gemma-*` → `gemini` heuristic as well. -- **Fix #74 — Token counts always 0 for Antigravity/Claude streaming**: The `message_start` SSE event which carries `input_tokens` was not being parsed by `extractUsage()`, causing all input token counts to drop. Input/output token tracking now works correctly for streaming responses. -- **Fix #180 — Model import duplicates with no feedback**: `ModelSelectModal` now shows ✓ green highlight for models already in the combo, making it obvious they're already added. -- **Media page generation errors**: Image results now render as `` tags instead of raw JSON. Transcription results shown as readable text. Credential errors show an amber banner instead of silent failure. -- **Token refresh button on provider page**: Manual token refresh UI added for OAuth providers. +- **Fix #302 — OpenAI SDK stream=False 丢弃 tool_calls**:T01 Accept 头协商不再在 `body.stream` 显式为 `false` 时强制流式传输。此前导致使用 OpenAI Python SDK 非流式模式时 tool_calls 被静默丢弃。 +- **Fix #73 — Claude Haiku 在没有提供商前缀的情况下路由到 OpenAI**:不带提供商前缀发送的 `claude-*` 模型现在正确路由到 `antigravity` (Anthropic) 提供商。还添加了 `gemini-*`/`gemma-*` → `gemini` 启发式规则。 +- **Fix #74 — Antigravity/Claude 流式传输的 Token 计数始终为 0**:携带 `input_tokens` 的 `message_start` SSE 事件未被 `extractUsage()` 解析,导致所有输入 token 计数丢失。输入/输出 token 追踪现在对流式响应正确工作。 +- **Fix #180 — 模型导入重复,无反馈**:`ModelSelectModal` 现在为已在 combo 中的模型显示 ✓ 绿色高亮,使其明显已被添加。 +- **媒体页面生成错误**:图像结果现在渲染为 `` 标签,而不是原始 JSON。转录结果显示为可读文本。凭证错误显示琥珀色横幅,而不是静默失败。 +- **提供商页面的 Token 刷新按钮**:为 OAuth 提供商添加了手动 token 刷新 UI。 -### 🔧 Improvements +### 🔧 改进 -- **Provider Registry**: HuggingFace and Vertex AI added to `providerRegistry.ts` and `providers.ts` (frontend). -- **Read Cache**: New `src/lib/db/readCache.ts` for efficient DB read caching. -- **Quota Cache**: Improved quota cache with TTL-based eviction. +- **提供商注册表**:HuggingFace 和 Vertex AI 添加到 `providerRegistry.ts` 和 `providers.ts`(前端)。 +- **读取缓存**:新增 `src/lib/db/readCache.ts`,用于高效的数据库读取缓存。 +- **配额缓存**:改进了配额缓存,使用基于 TTL 的驱逐。 -### 📦 Dependencies +### 📦 依赖 - `dompurify` → 3.3.3 (PR #347) - `undici` → 7.24.2 (PR #348, #361) - `docker/setup-qemu-action` → v4 (PR #342) - `docker/setup-buildx-action` → v4 (PR #343) -### 📁 New Files +### 📁 新增文件 -| File | Purpose | -| --------------------------------------------- | --------------------------------------- | -| `open-sse/services/taskAwareRouter.ts` | Task-aware routing logic (7 task types) | -| `src/app/api/settings/task-routing/route.ts` | Task routing config API | -| `src/app/api/providers/[id]/refresh/route.ts` | Manual OAuth token refresh | -| `src/lib/db/readCache.ts` | Efficient DB read cache | -| `src/shared/utils/clipboard.ts` | Hardened clipboard with fallback | +| 文件 | 目的 | +| --------------------------------------------- | -------------------------------- | +| `open-sse/services/taskAwareRouter.ts` | 任务感知路由逻辑(7 种任务类型) | +| `src/app/api/settings/task-routing/route.ts` | 任务路由配置 API | +| `src/app/api/providers/[id]/refresh/route.ts` | 手动 OAuth token 刷新 | +| `src/lib/db/readCache.ts` | 高效的数据库读取缓存 | +| `src/shared/utils/clipboard.ts` | 加固的剪贴板,带回退 | ## [2.4.1] - 2026-03-13 -### 🐛 Fix +### 🐛 修复 -- **Combos modal: Free Stack visible and prominent** — Free Stack template was hidden (4th in 3-column grid). Fixed: moved to position 1, switched to 2x2 grid so all 4 templates are visible, green border + FREE badge highlight. +- **Combos 模态框:Free Stack 可见且突出** —— Free Stack 模板被隐藏(3 列网格中的第 4 个)。修复:移动到位置 1,切换为 2x2 网格,使所有 4 个模板可见,绿色边框 + FREE 徽章高亮。 ## [2.4.0] - 2026-03-13 -> **Major release** — Free Stack ecosystem, transcription playground overhaul, 44+ providers, comprehensive free tier documentation, and UI improvements across the board. +> **主要发布** —— Free Stack 生态系统、转录游乐场 overhaul、44+ 提供商、全面的免费层文档和全面的 UI 改进。 -### 功能特点 +### ✨ 新特性 -- **Combos: Free Stack template** — New 4th template "Free Stack ($0)" using round-robin across Kiro + Qoder + Qwen + Gemini CLI. Suggests the pre-built zero-cost combo on first use. -- **Media/Transcription: Deepgram as default** — Deepgram (Nova 3, $200 free) is now the default transcription provider. AssemblyAI ($50 free) and Groq Whisper (free forever) shown with free credit badges. -- **README: "Start Free" section** — New early-README 5-step table showing how to set up zero-cost AI in minutes. -- **README: Free Transcription Combo** — New section with Deepgram/AssemblyAI/Groq combo suggestion and per-provider free credit details. -- **providers.ts: hasFree flag** — NVIDIA NIM, Cerebras, and Groq marked with hasFree badge and freeNote for the providers UI. -- **i18n: templateFreeStack keys** — Free Stack combo template translated and synced to all 30 languages. +- **Combos: Free Stack 模板** —— 新增第 4 个模板 "Free Stack ($0)",使用 Kiro + Qoder + Qwen + Gemini CLI 的轮转。首次使用时建议预构建的零成本 combo。 +- **Media/Transcription: Deepgram 作为默认** —— Deepgram (Nova 3, $200 免费) 现在是默认转录提供商。AssemblyAI ($50 免费) 和 Groq Whisper (永久免费) 显示免费积分徽章。 +- **README: "Start Free" 部分** —— 新增早期 README 5 步表格,展示如何在几分钟内设置零成本 AI。 +- **README: Free Transcription Combo** —— 新增部分,使用 Deepgram/AssemblyAI/Groq combo 建议和每提供商免费积分详情。 +- **providers.ts: hasFree 标志** —— NVIDIA NIM、Cerebras 和 Groq 标记 hasFree 徽章和 freeNote,用于提供商 UI。 +- **i18n: templateFreeStack 键** —— Free Stack combo 模板翻译并同步到所有 30 种语言。 ## [2.3.16] - 2026-03-13 -### 文档 +### 📖 文档 -- **README: 44+ Providers** — Updated all 3 occurrences of "36+ providers" to "44+" reflecting the actual codebase count (44 providers in providers.ts) -- **README: New Section "🆓 Free Models — What You Actually Get"** — Added 7-provider table with per-model rate limits for: Kiro (Claude unlimited via AWS Builder ID), Qoder (5 models unlimited), Qwen (4 models unlimited), Gemini CLI (180K/mo), NVIDIA NIM (~40 RPM dev-forever), Cerebras (1M tok/day / 60K TPM), Groq (30 RPM / 14.4K RPD). Includes the \/usr/bin/bash Ultimate Free Stack combo recommendation. -- **README: Pricing Table Updated** — Added Cerebras to API KEY tier, fixed NVIDIA from "1000 credits" to "dev-forever free", updated Qoder/Qwen model counts and names -- **README: Qoder 8→5 models** (named: kimi-k2-thinking, qwen3-coder-plus, deepseek-r1, minimax-m2, kimi-k2) -- **README: Qwen 3→4 models** (named: qwen3-coder-plus, qwen3-coder-flash, qwen3-coder-next, vision-model) +- **README: 44+ 提供商** —— 将所有 3 处 "36+ 提供商" 更新为 "44+",反映实际代码库计数(providers.ts 中 44 个提供商) +- **README: 新部分 "🆓 Free Models — What You Actually Get"** —— 添加了 7 提供商表格,使用每模型速率限制:Kiro(通过 AWS Builder ID 的 Claude 无限)、Qoder(5 个模型无限)、Qwen(4 个模型无限)、Gemini CLI(180K/月)、NVIDIA NIM(~40 RPM 永久开发)、Cerebras(1M tok/天 / 60K TPM)、Groq(30 RPM / 14.4K RPD)。包含 Ultimate Free Stack combo 推荐。 +- **README: 定价表更新** —— 为 API KEY 层级添加了 Cerebras,修复 NVIDIA 从 "1000 credits" 到 "dev-forever free",更新了 Qoder/Qwen 模型计数和名称 +- **README: Qoder 8→5 模型**(命名:kimi-k2-thinking, qwen3-coder-plus, deepseek-r1, minimax-m2, kimi-k2) +- **README: Qwen 3→4 模型**(命名:qwen3-coder-plus, qwen3-coder-flash, qwen3-coder-next, vision-model) ## [2.3.15] - 2026-03-13 -### 功能特点 +### ✨ 新特性 -- **Auto-Combo Dashboard (Tier Priority)**: Added `🏷️ Tier` as the 7th scoring factor label in the `/dashboard/auto-combo` factor breakdown display — all 7 Auto-Combo scoring factors are now visible. -- **i18n — autoCombo section**: Added 20 new translation keys for the Auto-Combo dashboard (`title`, `status`, `modePack`, `providerScores`, `factorTierPriority`, etc.) to all 30 language files. +- **Auto-Combo 仪表盘(层级优先级)**:在 `/dashboard/auto-combo` 因子分解显示中添加了 `🏷️ Tier` 作为第 7 个评分因子标签 —— 所有 7 个 Auto-Combo 评分因子现在可见。 +- **i18n — autoCombo 部分**:为所有 30 个语言文件添加了 20 个新翻译键,用于 Auto-Combo 仪表盘(`title`、`status`、`modePack`、`providerScores`、`factorTierPriority` 等)。 ## [2.3.14] - 2026-03-13 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Qoder OAuth (#339)**: Restored the valid default `clientSecret` — was previously an empty string, causing "Bad client credentials" on every connect attempt. The public credential is now the default fallback (overridable via `QODER_OAUTH_CLIENT_SECRET` env var). -- **MITM server not found (#335)**: `prepublish.mjs` now compiles `src/mitm/*.ts` to JavaScript using `tsc` before copying to the npm bundle. Previously only raw `.ts` files were copied — meaning `server.js` never existed in npm/Volta global installs. -- **GeminiCLI missing projectId (#338)**: Instead of throwing a hard 500 error when `projectId` is missing from stored credentials (e.g. after Docker restart), OmniRoute now logs a warning and attempts the request — returning a meaningful provider-side error instead of an OmniRoute crash. -- **Electron version mismatch (#323)**: Synced `electron/package.json` version to `2.3.13` (was `2.0.13`) so the desktop binary version matches the npm package. +- **Qoder OAuth (#339)**:恢复了有效的默认 `clientSecret` —— 此前是空字符串,导致每次连接尝试都出现 "Bad client credentials"。公共凭体现在是默认回退(可通过 `QODER_OAUTH_CLIENT_SECRET` 环境变量覆盖)。 +- **MITM server not found (#335)**:`prepublish.mjs` 现在在复制到 npm 包之前使用 `tsc` 将 `src/mitm/*.ts` 编译为 JavaScript。此前只复制原始 `.ts` 文件 —— 意味着 `server.js` 在 npm/Volta 全局安装中从未存在过。 +- **GeminiCLI missing projectId (#338)**:当存储的凭证中缺少 `projectId` 时(例如 Docker 重启后),OmniRoute 现在记录警告并尝试请求 —— 返回有意义的提供商端错误,而不是 OmniRoute 崩溃。 +- **Electron 版本不匹配 (#323)**:将 `electron/package.json` 版本同步到 `2.3.13`(此前是 `2.0.13`),使桌面二进制版本与 npm 包匹配。 -### ✨ New Models (#334) +### ✨ 新模型 (#334) -- **Kiro**: `claude-sonnet-4`, `claude-opus-4.6`, `deepseek-v3.2`, `minimax-m2.1`, `qwen3-coder-next`, `auto` -- **Codex**: `gpt5.4` +- **Kiro**:`claude-sonnet-4`、`claude-opus-4.6`、`deepseek-v3.2`、`minimax-m2.1`、`qwen3-coder-next`、`auto` +- **Codex**:`gpt5.4` -### 🔧 Improvements +### 🔧 改进 -- **Tier Scoring (API + Validation)**: Added `tierPriority` (weight `0.05`) to the `ScoringWeights` Zod schema and the `combos/auto` API route — the 7th scoring factor is now fully accepted by the REST API and validated on input. `stability` weight adjusted from `0.10` to `0.05` to keep total sum = `1.0`. +- **层级评分(API + 验证)**:为 `ScoringWeights` Zod schema 和 `combos/auto` API 路由添加了 `tierPriority`(权重 `0.05`)—— 第 7 个评分因子现在完全被 REST API 接受并在输入时验证。`stability` 权重从 `0.10` 调整到 `0.05`,以保持总和 = `1.0`。 -### ✨ New Features +### ✨ 新特性 -- **Tiered Quota Scoring (Auto-Combo)**: Added `tierPriority` as a 7th scoring factor — accounts with Ultra/Pro tiers are now preferred over Free tiers when other factors are equal. New optional fields `accountTier` and `quotaResetIntervalSecs` on `ProviderCandidate`. All 4 mode packs updated (`ship-fast`, `cost-saver`, `quality-first`, `offline-friendly`). -- **Intra-Family Model Fallback (T5)**: When a model is unavailable (404/400/403), OmniRoute now automatically falls back to sibling models from the same family before returning an error (`modelFamilyFallback.ts`). -- **Configurable API Bridge Timeout**: `API_BRIDGE_PROXY_TIMEOUT_MS` env var lets operators tune the proxy timeout (default 30s). Fixes 504 errors on slow upstream responses. (#332) -- **Star History**: Replaced star-history.com widget with starchart.cc (`?variant=adaptive`) in all 30 READMEs — adapts to light/dark theme, real-time updates. +- **分层配额评分(Auto-Combo)**:添加了 `tierPriority` 作为第 7 个评分因子 —— 当其他因素相同时,现在优先选择 Ultra/Pro 层级的账户,而不是 Free 层级。`ProviderCandidate` 中新增可选字段 `accountTier` 和 `quotaResetIntervalSecs`。所有 4 个模式包已更新(`ship-fast`、`cost-saver`、`quality-first`、`offline-friendly`)。 +- **家族内模型回退 (T5)**:当模型不可用时(404/400/403),OmniRoute 现在在返回错误之前自动回退到同家族的兄弟模型(`modelFamilyFallback.ts`)。 +- **可配置的 API 桥接超时**:`API_BRIDGE_PROXY_TIMEOUT_MS` 环境变量允许操作员调整代理超时(默认 30 秒)。修复慢速上游响应的 504 错误。(#332) +- **Star History**:将所有 30 个 README 中的 star-history.com 小部件替换为 starchart.cc(`?variant=adaptive`)—— 适应浅色/深色主题,实时更新。 -### 🐛 Bug Fixes +### 🐛 Bug 修复 -- **Auth — First-time password**: `INITIAL_PASSWORD` env var is now accepted when setting the first dashboard password. Uses `timingSafeEqual` for constant-time comparison, preventing timing attacks. (#333) -- **README Truncation**: Fixed a missing `` closing tag in the Troubleshooting section that caused GitHub to stop rendering everything below it (Tech Stack, Docs, Roadmap, Contributors). -- **pnpm install**: Removed redundant `@swc/helpers` override from `package.json` that conflicted with the direct dependency, causing `EOVERRIDE` errors on pnpm. Added `pnpm.onlyBuiltDependencies` config. -- **CLI Path Injection (T12)**: Added `isSafePath()` validator in `cliRuntime.ts` to block path traversal and shell metacharacters in `CLI_*_BIN` env vars. -- **CI**: Regenerated `package-lock.json` after override removal to fix `npm ci` failures on GitHub Actions. +- **认证 —— 首次密码**:设置首个仪表盘密码时现在接受 `INITIAL_PASSWORD` 环境变量。使用 `timingSafeEqual` 进行恒定时间比较,防止时序攻击。(#333) +- **README 截断**:修复了 Troubleshooting 部分缺失的 `` 闭合标签,该标签导致 GitHub 停止渲染其下方的所有内容(技术栈、文档、路线图、贡献者)。 +- **pnpm install**:从 `package.json` 中移除了冗余的 `@swc/helpers` 覆盖,该覆盖与直接依赖冲突,导致 pnpm 出现 `EOVERRIDE` 错误。添加了 `pnpm.onlyBuiltDependencies` 配置。 +- **CLI 路径注入 (T12)**:在 `cliRuntime.ts` 中添加了 `isSafePath()` 验证器,以阻止路径遍历和 `CLI_*_BIN` 环境变量中的 shell 元字符。 +- **CI**:在覆盖移除后重新生成 `package-lock.json`,以修复 GitHub Actions 中的 `npm ci` 失败。 -### 🔧 Improvements +### 🔧 改进 -- **Response Format (T1)**: `response_format` (json_schema/json_object) now injected as a system prompt for Claude, enabling structured output compatibility. -- **429 Retry (T2)**: Intra-URL retry for 429 responses (2× attempts with 2s delay) before falling back to next URL. -- **Gemini CLI Headers (T3)**: Added `User-Agent` and `X-Goog-Api-Client` fingerprint headers for Gemini CLI compatibility. -- **Pricing Catalog (T9)**: Added `deepseek-3.1`, `deepseek-3.2`, and `qwen3-coder-next` pricing entries. +- **响应格式 (T1)**:`response_format`(json_schema/json_object)现在作为系统提示词注入 Claude,实现结构化输出兼容性。 +- **429 重试 (T2)**:URL 内重试用于 429 响应(2 次尝试,2 秒延迟),然后回退到下一个 URL。 +- **Gemini CLI 请求头 (T3)**:添加了 `User-Agent` 和 `X-Goog-Api-Client` 指纹请求头,用于 Gemini CLI 兼容性。 +- **定价目录 (T9)**:添加了 `deepseek-3.1`、`deepseek-3.2` 和 `qwen3-coder-next` 定价条目。 -### 📁 New Files +### 📁 新增文件 -| File | Purpose | -| ------------------------------------------ | -------------------------------------------------------- | -| `open-sse/services/modelFamilyFallback.ts` | Model family definitions and intra-family fallback logic | +| 文件 | 目的 | +| ------------------------------------------ | ---------------------------- | +| `open-sse/services/modelFamilyFallback.ts` | 模型家族定义和家族内回退逻辑 | -### Fixed +### 修复 -- **KiloCode**: kilocode healthcheck timeout already fixed in v2.3.11 -- **OpenCode**: Add opencode to cliRuntime registry with 15s healthcheck timeout -- **OpenClaw / Cursor**: Increase healthcheck timeout to 15s for slow-start variants -- **VPS**: Install droid and openclaw npm packages; activate CLI_EXTRA_PATHS for kiro-cli -- **cliRuntime**: Add opencode tool registration and increase timeout for continue +- **KiloCode**:kilocode 健康检查超时已在 v2.3.11 修复 +- **OpenCode**:将 opencode 添加到 cliRuntime 注册表,使用 15 秒健康检查超时 +- **OpenClaw / Cursor**:将健康检查超时增加到 15 秒,用于慢启动变体 +- **VPS**:安装 droid 和 openclaw npm 包;为 kiro-cli 激活 CLI_EXTRA_PATHS +- **cliRuntime**:添加 opencode 工具注册并增加 continue 的超时 ## [2.3.11] - 2026-03-12 -### Fixed +### 修复 -- **KiloCode healthcheck**: Increase `healthcheckTimeoutMs` from 4000ms to 15000ms — kilocode renders an ASCII logo banner on startup causing false `healthcheck_failed` on slow/cold-start environments +- **KiloCode healthcheck**:将 `healthcheckTimeoutMs` 从 4000ms 增加到 15000ms —— kilocode 在启动时渲染 ASCII 标志横幅,在慢/冷启动环境中导致虚假的 `healthcheck_failed` ## [2.3.10] - 2026-03-12 -### Fixed +### 修复 -- **Lint**: Fix `check:any-budget:t11` failure — replace `as any` with `as Record` in OAuthModal.tsx (3 occurrences) +- **Lint**:修复 `check:any-budget:t11` 失败 —— 在 OAuthModal.tsx 中将 `as any` 替换为 `as Record`(3 处) ### Docs -- **CLI-TOOLS.md**: Complete guide for all 11 CLI tools (claude, codex, gemini, opencode, cline, kilocode, continue, kiro-cli, cursor, droid, openclaw) -- **i18n**: CLI-TOOLS.md synced to 30 languages with translated title + intro +- **CLI-TOOLS.md**:所有 11 个 CLI 工具的完整指南(claude、codex、gemini、opencode、cline、kilocode、continue、kiro-cli、cursor、droid、openclaw) +- **i18n**:CLI-TOOLS.md 同步到 30 种语言,带翻译的标题和介绍 ## [2.3.8] - 2026-03-12 @@ -2331,41 +2385,41 @@ OmniRoute now automatically refreshes model lists for connected providers every ### Added -- **/v1/completions**: New legacy OpenAI completions endpoint — accepts both `prompt` string and `messages` array, normalizes to chat format automatically -- **EndpointPage**: Now shows all 3 OpenAI-compatible endpoint types: Chat Completions, Responses API, and Legacy Completions -- **i18n**: Added `completionsLegacy/completionsLegacyDesc` to 30 language files +- **/v1/completions**:新增传统 OpenAI completions 端点 —— 接受 `prompt` 字符串和 `messages` 数组,自动规范化为聊天格式 +- **EndpointPage**:现在显示所有 3 种 OpenAI 兼容端点类型:Chat Completions、Responses API 和 Legacy Completions +- **i18n**:为 30 个语言文件添加了 `completionsLegacy/completionsLegacyDesc` -### Fixed +### 修复 -- **OAuthModal**: Fix `[object Object]` displayed on all OAuth connection errors — properly extract `.message` from error response objects in all 3 `throw new Error(data.error)` calls (exchange, device-code, authorize) -- Affects Cline, Codex, GitHub, Qwen, Kiro, and all other OAuth providers +- **OAuthModal**:修复所有 OAuth 连接错误中显示的 `[object Object]` —— 正确从错误响应对象中提取 `.message`,在所有 3 个 `throw new Error(data.error)` 调用中(exchange、device-code、authorize) +- 影响 Cline、Codex、GitHub、Qwen、Kiro 和所有其他 OAuth 提供商 ## [2.3.7] - 2026-03-12 -### Fixed +### 修复 -- **Cline OAuth**: Add `decodeURIComponent` before base64 decode so URL-encoded auth codes from the callback URL are parsed correctly, fixing "invalid or expired authorization code" errors on remote (LAN IP) setups -- **Cline OAuth**: `mapTokens` now populates `name = firstName + lastName || email` so Cline accounts show real user names instead of "Account #ID" -- **OAuth account names**: All OAuth exchange flows (exchange, poll, poll-callback) now normalize `name = email` when name is missing, so every OAuth account shows its email as the display label in the Providers dashboard -- **OAuth account names**: Removed sequential "Account N" fallback in `db/providers.ts` — accounts with no email/name now use a stable ID-based label via `getAccountDisplayName()` instead of a sequential number that changes when accounts are deleted +- **Cline OAuth**:在 base64 解码之前添加 `decodeURIComponent`,以便正确解析来自回调 URL 的 URL 编码认证码,修复远程(LAN IP)设置中的 "invalid or expired 授权 code" 错误 +- **Cline OAuth**:`mapTokens` 现在填充 `name = firstName + lastName || email`,使 Cline 账户显示真实用户名,而不是 "Account #ID" +- **OAuth 账户名称**:所有 OAuth 交换流程(exchange、poll、poll-callback)现在在名称缺失时规范化 `name = email`,使每个 OAuth 账户在提供商仪表盘上显示其电子邮件作为显示标签 +- **OAuth 账户名称**:移除了 `db/providers.ts` 中顺序的 "Account N" 回退 —— 没有电子邮件/名称的账户现在使用基于稳定 ID 的标签,通过 `getAccountDisplayName()`,而不是删除账户时会变化的顺序号 ## [2.3.6] - 2026-03-12 -### Fixed +### 修复 -- **Provider test batch**: Fixed Zod schema to accept `providerId: null` (frontend sends null for non-provider modes); was incorrectly returning "Invalid request" for all batch tests -- **Provider test modal**: Fixed `[object Object]` display by normalizing API error objects to strings before rendering in `setTestResults` and `ProviderTestResultsView` -- **i18n**: Added missing keys `cliTools.toolDescriptions.opencode`, `cliTools.toolDescriptions.kiro`, `cliTools.guides.opencode`, `cliTools.guides.kiro` to `en.json` -- **i18n**: Synchronized 1111 missing keys across all 29 non-English language files using English values as fallbacks +- **Provider test batch**:修复了 Zod schema 以接受 `providerId: null`(前端为非提供商模式发送 null);此前对所有批量测试错误地返回 "Invalid 请求" +- **Provider test modal**:通过在 `setTestResults` 和 `ProviderTestResultsView` 中渲染之前将 API 错误对象规范化为字符串,修复了 `[object Object]` 显示 +- **i18n**:为 `en.json` 添加了缺失的键 `cliTools.toolDescriptions.opencode`、`cliTools.toolDescriptions.kiro`、`cliTools.guides.opencode`、`cliTools.guides.kiro` +- **i18n**:在所有 29 个非英语语言文件中同步了 1111 个缺失的键,使用英语值作为回退 ## [2.3.5] - 2026-03-11 -### Fixed +### 修复 -- **@swc/helpers**: Added permanent `postinstall` fix to copy `@swc/helpers` into the standalone app's `node_modules` — prevents MODULE_NOT_FOUND crash on global npm installs +- **@swc/helpers**:添加了永久的 `postinstall` 修复,将 `@swc/helpers` 复制到独立应用的 `node_modules` 中 —— 防止全局 npm 安装中的 MODULE_NOT_FOUND 崩溃 ## [2.3.4] - 2026-03-10 ### Added -- Multiple provider integrations and dashboard improvements +- 多个提供商集成和仪表盘改进 diff --git a/docs/i18n/zh-CN/CLI-TOOLS.md b/docs/i18n/zh-CN/CLI-TOOLS.md index cbec2bdb..2cccb1f5 100644 --- a/docs/i18n/zh-CN/CLI-TOOLS.md +++ b/docs/i18n/zh-CN/CLI-TOOLS.md @@ -1,68 +1,81 @@ -🌐 **Languages:** 🇺🇸 [English](../../CLI-TOOLS.md) · 🇧🇷 [pt-BR](../pt-BR/CLI-TOOLS.md) · 🇪🇸 [es](../es/CLI-TOOLS.md) · 🇫🇷 [fr](../fr/CLI-TOOLS.md) · 🇩🇪 [de](../de/CLI-TOOLS.md) · 🇮🇹 [it](../it/CLI-TOOLS.md) · 🇷🇺 [ru](../ru/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../zh-CN/CLI-TOOLS.md) · 🇯🇵 [ja](../ja/CLI-TOOLS.md) · 🇰🇷 [ko](../ko/CLI-TOOLS.md) · 🇸🇦 [ar](../ar/CLI-TOOLS.md) +🌐 **语言:** 🇺🇸 [English](../../CLI-TOOLS.md) · 🇧🇷 [pt-BR](../pt-BR/CLI-TOOLS.md) · 🇪🇸 [es](../es/CLI-TOOLS.md) · 🇫🇷 [fr](../fr/CLI-TOOLS.md) · 🇩🇪 [de](../de/CLI-TOOLS.md) · 🇮🇹 [it](../it/CLI-TOOLS.md) · 🇷🇺 [ru](../ru/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../zh-CN/CLI-TOOLS.md) · 🇯🇵 [ja](../ja/CLI-TOOLS.md) · 🇰🇷 [ko](../ko/CLI-TOOLS.md) · 🇸🇦 [ar](../ar/CLI-TOOLS.md) # CLI 工具配置指南 — OmniRoute -本指南说明如何安装和配置所有支持的 AI CLI 工具,以使用 **OmniRoute** 作为统一后端。 - -This guide explains how to install and configure all supported AI coding CLI tools -to use **OmniRoute** as the unified backend, giving you centralized key management, -cost tracking, model switching, and request logging across every tool. +本指南说明如何安装和配置所有支持的 AI 编程 CLI 工具,以使用 **OmniRoute** 作为统一后端,为您提供集中化的密钥管理、成本跟踪、模型切换以及所有工具的请求日志记录。 --- -## How It Works +## 工作原理 ``` -Claude / Codex / Gemini CLI / OpenCode / Cline / KiloCode / Continue / Kiro CLI +Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilot │ - ▼ (all point to OmniRoute) + ▼ (所有工具指向 OmniRoute) http://YOUR_SERVER:20128/v1 │ - ▼ (OmniRoute routes to the right provider) + ▼ (OmniRoute 路由到正确的服务商) Anthropic / OpenAI / Gemini / DeepSeek / Groq / Mistral / ... ``` -**Benefits:** +**优势:** -- One API key to manage all tools -- Cost tracking across all CLIs in the dashboard -- Model switching without reconfiguring every tool -- Works locally and on remote servers (VPS) +- 一个 API 密钥管理所有工具 +- 在仪表盘中跨所有 CLI 跟踪成本 +- 无需重新配置每个工具即可切换模型 +- 本地和远程服务器 (VPS) 均可使用 --- -## Supported Tools +## 支持的工具(以仪表盘为准) -| Tool | Command | Type | Install Method | -| ---------------- | ------------------- | ----------------- | -------------- | -| **Claude Code** | `claude` | CLI | npm | -| **OpenAI Codex** | `codex` | CLI | npm | -| **Gemini CLI** | `gemini` | CLI | npm | -| **OpenCode** | `opencode` | CLI | npm | -| **Cline** | `cline` | CLI + VS Code ext | npm | -| **KiloCode** | `kilocode` / `kilo` | CLI + VS Code ext | npm | -| **Continue** | guide-based | VS Code ext | VS Code | -| **Kiro CLI** | `kiro-cli` | CLI | curl installer | -| **Cursor** | `cursor` | Desktop app | Download | -| **Droid** | web-based | Built-in agent | OmniRoute | -| **OpenClaw** | web-based | Built-in agent | OmniRoute | +仪表盘中 `/dashboard/cli-tools` 的卡片由 `src/shared/constants/cliTools.ts` 生成。 +当前列表 (v3.0.0-rc.16): + +| 工具 | ID | 命令 | 配置模式 | 安装方式 | +| ----------------- | ------------- | ------------ | -------- | ------------ | +| **Claude Code** | `claude` | `claude` | env | npm | +| **OpenAI Codex** | `codex` | `codex` | custom | npm | +| **Factory Droid** | `droid` | `droid` | custom | 内置/CLI | +| **OpenClaw** | `openclaw` | `openclaw` | custom | 内置/CLI | +| **Cursor** | `cursor` | app | guide | 桌面应用 | +| **Cline** | `cline` | `cline` | custom | npm | +| **Kilo Code** | `kilo` | `kilocode` | custom | npm | +| **Continue** | `continue` | extension | guide | VS Code | +| **Antigravity** | `antigravity` | internal | mitm | OmniRoute | +| **GitHub Copilot**| `copilot` | extension | custom | VS Code | +| **OpenCode** | `opencode` | `opencode` | guide | npm | +| **Kiro AI** | `kiro` | app/cli | mitm | 桌面/CLI | + +### CLI 指纹同步(代理 + 设置) + +`/dashboard/agents` 和 `Settings > CLI Fingerprint` 使用 `src/shared/constants/cliCompatProviders.ts`。 +这确保服务商 ID 与 CLI 卡片和旧版 ID 保持一致。 + +| CLI ID | 指纹服务商 ID | +| ------ | ------------- | +| `kilo` | `kilocode` | +| `copilot` | `github` | +| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | 相同 ID | + +为兼容性保留的旧版 ID:`copilot`、`kimi-coding`、`qwen`。 --- -## Step 1 — Get an OmniRoute API Key +## 第 1 步 — 获取 OmniRoute API 密钥 -1. Open the OmniRoute dashboard → **API Manager** (`/dashboard/api-manager`) -2. Click **Create API Key** -3. Give it a name (e.g. `cli-tools`) and select all permissions -4. Copy the key — you'll need it for every CLI below +1. 打开 OmniRoute 仪表盘 → **API Manager** (`/dashboard/api-manager`) +2. 点击 **Create API Key** +3. 命名(例如 `cli-tools`)并选择所有权限 +4. 复制密钥 — 下面的每个 CLI 都需要使用 -> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx` +> 密钥格式类似:`sk-xxxxxxxxxxxxxxxx-xxxxxxxxx` --- -## Step 2 — Install CLI Tools +## 第 2 步 — 安装 CLI 工具 -All npm-based tools require Node.js 18+: +所有基于 npm 的工具需要 Node.js 18+: ```bash # Claude Code (Anthropic) @@ -71,9 +84,6 @@ npm install -g @anthropic-ai/claude-code # OpenAI Codex npm install -g @openai/codex -# Gemini CLI (Google) -npm install -g @google/gemini-cli - # OpenCode npm install -g opencode-ai @@ -81,34 +91,33 @@ npm install -g opencode-ai npm install -g cline # KiloCode -npm install -g kilecode +npm install -g kilocode -# Kiro CLI (Amazon — requires curl + unzip) -apt-get install -y unzip # on Debian/Ubuntu +# Kiro CLI (Amazon — 需要 curl + unzip) +apt-get install -y unzip # Debian/Ubuntu curl -fsSL https://cli.kiro.dev/install | bash -export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc +export PATH="$HOME/.local/bin:$PATH" # 添加到 ~/.bashrc ``` -**Verify:** +**验证:** ```bash claude --version # 2.x.x codex --version # 0.x.x -gemini --version # 0.x.x opencode --version # x.x.x cline --version # 2.x.x -kilocode --version # x.x.x (or: kilo --version) +kilocode --version # x.x.x (或: kilo --version) kiro-cli --version # 1.x.x ``` --- -## Step 3 — Set Global Environment Variables +## 第 3 步 — 设置全局环境变量 -Add to `~/.bashrc` (or `~/.zshrc`), then run `source ~/.bashrc`: +添加到 `~/.bashrc`(或 `~/.zshrc`),然后运行 `source ~/.bashrc`: ```bash -# OmniRoute Universal Endpoint +# OmniRoute 统一端点 export OPENAI_BASE_URL="http://localhost:20128/v1" export OPENAI_API_KEY="sk-your-omniroute-key" export ANTHROPIC_BASE_URL="http://localhost:20128/v1" @@ -117,20 +126,20 @@ export GEMINI_BASE_URL="http://localhost:20128/v1" export GEMINI_API_KEY="sk-your-omniroute-key" ``` -> For a **remote server** replace `localhost:20128` with the server IP or domain, -> e.g. `http://192.168.0.15:20128`. +> 对于**远程服务器**,将 `localhost:20128` 替换为服务器 IP 或域名, +> 例如 `http://192.168.0.15:20128`。 --- -## Step 4 — Configure Each Tool +## 第 4 步 — 配置各工具 ### Claude Code ```bash -# Via CLI: +# 通过 CLI: claude config set --global api-base-url http://localhost:20128/v1 -# Or create ~/.claude/settings.json: +# 或创建 ~/.claude/settings.json: mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF { "apiBaseUrl": "http://localhost:20128/v1", @@ -139,7 +148,7 @@ mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF EOF ``` -**Test:** `claude "say hello"` +**测试:** `claude "say hello"` --- @@ -153,22 +162,7 @@ apiBaseUrl: http://localhost:20128/v1 EOF ``` -**Test:** `codex "what is 2+2?"` - ---- - -### Gemini CLI - -```bash -mkdir -p ~/.gemini && cat > ~/.gemini/settings.json << EOF -{ - "apiKey": "sk-your-omniroute-key", - "baseUrl": "http://localhost:20128/v1" -} -EOF -``` - -**Test:** `gemini "hello"` +**测试:** `codex "what is 2+2?"` --- @@ -182,13 +176,13 @@ api_key = "sk-your-omniroute-key" EOF ``` -**Test:** `opencode` +**测试:** `opencode` --- -### Cline (CLI or VS Code) +### Cline (CLI 或 VS Code) -**CLI mode:** +**CLI 模式:** ```bash mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF @@ -200,22 +194,22 @@ mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF EOF ``` -**VS Code mode:** -Cline extension settings → API Provider: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1` +**VS Code 模式:** +Cline 扩展设置 → API Provider: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1` -Or use the OmniRoute dashboard → **CLI Tools → Cline → Apply Config**. +或使用 OmniRoute 仪表盘 → **CLI Tools → Cline → Apply Config**。 --- -### KiloCode (CLI or VS Code) +### KiloCode (CLI 或 VS Code) -**CLI mode:** +**CLI 模式:** ```bash kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key ``` -**VS Code settings:** +**VS Code 设置:** ```json { @@ -224,13 +218,13 @@ kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key } ``` -Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**. +或使用 OmniRoute 仪表盘 → **CLI Tools → KiloCode → Apply Config**。 --- -### Continue (VS Code Extension) +### Continue (VS Code 扩展) -Edit `~/.continue/config.yaml`: +编辑 `~/.continue/config.yaml`: ```yaml models: @@ -242,103 +236,102 @@ models: default: true ``` -Restart VS Code after editing. +编辑后重启 VS Code。 --- ### Kiro CLI (Amazon) ```bash -# Login to your AWS/Kiro account: +# 登录您的 AWS/Kiro 账户: kiro-cli login -# The CLI uses its own auth — OmniRoute is not needed as backend for Kiro CLI itself. -# Use kiro-cli alongside OmniRoute for other tools. +# CLI 使用自有认证 — Kiro CLI 本身不需要 OmniRoute 作为后端。 +# 将 kiro-cli 与其他工具的 OmniRoute 一起使用。 kiro-cli status ``` --- -### Cursor (Desktop App) +### Cursor (桌面应用) -> **Note:** Cursor routes requests through its cloud. For OmniRoute integration, -> enable **Cloud Endpoint** in OmniRoute Settings and use your public domain URL. +> **注意:** Cursor 通过其云端路由请求。对于 OmniRoute 集成, +> 在 OmniRoute Settings 中启用 **Cloud Endpoint** 并使用您的公共域名 URL。 -Via GUI: **Settings → Models → OpenAI API Key** +通过 GUI: **Settings → Models → OpenAI API Key** - Base URL: `https://your-domain.com/v1` -- API Key: your OmniRoute key +- API Key: 您的 OmniRoute 密钥 --- -## Dashboard Auto-Configuration +## 仪表盘自动配置 -The OmniRoute dashboard automates configuration for most tools: +OmniRoute 仪表盘可自动配置大多数工具: -1. Go to `http://localhost:20128/dashboard/cli-tools` -2. Expand any tool card -3. Select your API key from the dropdown -4. Click **Apply Config** (if tool is detected as installed) -5. Or copy the generated config snippet manually +1. 前往 `http://localhost:20128/dashboard/cli-tools` +2. 展开任意工具卡片 +3. 从下拉菜单选择您的 API 密钥 +4. 点击 **Apply Config**(如果检测到工具已安装) +5. 或手动复制生成的配置片段 --- -## Built-in Agents: Droid & OpenClaw +## 内置代理:Droid & OpenClaw -**Droid** and **OpenClaw** are AI agents built directly into OmniRoute — no installation needed. -They run as internal routes and use OmniRoute's model routing automatically. +**Droid** 和 **OpenClaw** 是直接内置于 OmniRoute 的 AI 代理 — 无需安装。 +它们作为内部路由运行,自动使用 OmniRoute 的模型路由。 -- Access: `http://localhost:20128/dashboard/agents` -- Configure: same combos and providers as all other tools -- No API key or CLI install required +- 访问:`http://localhost:20128/dashboard/agents` +- 配置:与所有其他工具使用相同的组合和服务商 +- 无需 API 密钥或 CLI 安装 --- -## Available API Endpoints +## 可用 API 端点 -| Endpoint | Description | Use For | -| -------------------------- | ----------------------------- | --------------------------- | -| `/v1/chat/completions` | Standard chat (all providers) | All modern tools | -| `/v1/responses` | Responses API (OpenAI format) | Codex, agentic workflows | -| `/v1/completions` | Legacy text completions | Older tools using `prompt:` | -| `/v1/embeddings` | Text embeddings | RAG, search | -| `/v1/images/generations` | Image generation | DALL-E, Flux, etc. | -| `/v1/audio/speech` | Text-to-speech | ElevenLabs, OpenAI TTS | -| `/v1/audio/transcriptions` | Speech-to-text | Deepgram, AssemblyAI | +| 端点 | 描述 | 用途 | +| -------------------------- | ------------------------ | -------------------------- | +| `/v1/chat/completions` | 标准聊天(所有服务商) | 所有现代工具 | +| `/v1/responses` | Responses API(OpenAI 格式)| Codex、代理工作流 | +| `/v1/completions` | 旧版文本补全 | 使用 `prompt:` 的旧工具 | +| `/v1/embeddings` | 文本嵌入 | RAG、搜索 | +| `/v1/images/generations` | 图像生成 | DALL-E、Flux 等 | +| `/v1/audio/speech` | 文本转语音 | ElevenLabs、OpenAI TTS | +| `/v1/audio/transcriptions` | 语音转文字 | Deepgram、AssemblyAI | --- -## Troubleshooting +## 故障排除 -| Error | Cause | Fix | -| ------------------------- | ----------------------- | ------------------------------------------ | -| `Connection refused` | OmniRoute not running | `pm2 start omniroute` | -| `401 Unauthorized` | Wrong API key | Check in `/dashboard/api-manager` | -| `No combo configured` | No active routing combo | Set up in `/dashboard/combos` | -| `invalid model` | Model not in catalog | Use `auto` or check `/dashboard/providers` | -| CLI shows "not installed" | Binary not in PATH | Check `which ` | -| `kiro-cli: not found` | Not in PATH | `export PATH="$HOME/.local/bin:$PATH"` | +| 错误 | 原因 | 解决方案 | +| ------------------------- | --------------------- | ------------------------------------------ | +| `Connection refused` | OmniRoute 未运行 | `pm2 start omniroute` | +| `401 Unauthorized` | API 密钥错误 | 在 `/dashboard/api-manager` 检查 | +| `No combo configured` | 无活动路由组合 | 在 `/dashboard/combos` 设置 | +| `invalid model` | 模型不在目录中 | 使用 `auto` 或检查 `/dashboard/providers` | +| CLI 显示 "not installed" | 二进制文件不在 PATH 中| 检查 `which ` | +| `kiro-cli: not found` | 不在 PATH 中 | `export PATH="$HOME/.local/bin:$PATH"` | --- -## Quick Setup Script (One Command) +## 快速设置脚本(一条命令) ```bash -# Install all CLIs and configure for OmniRoute (replace with your key and server URL) +# 安装所有 CLI 并为 OmniRoute 配置(替换为您的密钥和服务器 URL) OMNIROUTE_URL="http://localhost:20128/v1" OMNIROUTE_KEY="sk-your-omniroute-key" -npm install -g @anthropic-ai/claude-code @openai/codex @google/gemini-cli opencode-ai cline kilecode +npm install -g @anthropic-ai/claude-code @openai/codex opencode-ai cline kilocode # Kiro CLI apt-get install -y unzip 2>/dev/null; curl -fsSL https://cli.kiro.dev/install | bash -# Write configs -mkdir -p ~/.claude ~/.codex ~/.gemini ~/.config/opencode ~/.continue +# 写入配置 +mkdir -p ~/.claude ~/.codex ~/.config/opencode ~/.continue cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}" cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL" -cat > ~/.gemini/settings.json <<< "{\"apiKey\":\"$OMNIROUTE_KEY\",\"baseUrl\":\"$OMNIROUTE_URL\"}" cat >> ~/.bashrc << EOF export OPENAI_BASE_URL="$OMNIROUTE_URL" export OPENAI_API_KEY="$OMNIROUTE_KEY" @@ -347,5 +340,5 @@ export ANTHROPIC_API_KEY="$OMNIROUTE_KEY" EOF source ~/.bashrc -echo "✅ All CLIs installed and configured for OmniRoute" +echo "✅ 所有 CLI 已安装并配置为使用 OmniRoute" ``` diff --git a/docs/i18n/zh-CN/CODEBASE_DOCUMENTATION.md b/docs/i18n/zh-CN/CODEBASE_DOCUMENTATION.md index e2d79500..9aef6ea9 100644 --- a/docs/i18n/zh-CN/CODEBASE_DOCUMENTATION.md +++ b/docs/i18n/zh-CN/CODEBASE_DOCUMENTATION.md @@ -1,44 +1,40 @@ -🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/CODEBASE_DOCUMENTATION.md) · 🇪🇸 [es](../es/CODEBASE_DOCUMENTATION.md) · 🇫🇷 [fr](../fr/CODEBASE_DOCUMENTATION.md) · 🇩🇪 [de](../de/CODEBASE_DOCUMENTATION.md) · 🇮🇹 [it](../it/CODEBASE_DOCUMENTATION.md) · 🇷🇺 [ru](../ru/CODEBASE_DOCUMENTATION.md) · 🇨🇳 [zh-CN](../zh-CN/CODEBASE_DOCUMENTATION.md) · 🇯🇵 [ja](../ja/CODEBASE_DOCUMENTATION.md) · 🇰🇷 [ko](../ko/CODEBASE_DOCUMENTATION.md) · 🇸🇦 [ar](../ar/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [in](../in/CODEBASE_DOCUMENTATION.md) · 🇹🇭 [th](../th/CODEBASE_DOCUMENTATION.md) · 🇻🇳 [vi](../vi/CODEBASE_DOCUMENTATION.md) · 🇮🇩 [id](../id/CODEBASE_DOCUMENTATION.md) · 🇲🇾 [ms](../ms/CODEBASE_DOCUMENTATION.md) · 🇳🇱 [nl](../nl/CODEBASE_DOCUMENTATION.md) · 🇵🇱 [pl](../pl/CODEBASE_DOCUMENTATION.md) · 🇸🇪 [sv](../sv/CODEBASE_DOCUMENTATION.md) · 🇳🇴 [no](../no/CODEBASE_DOCUMENTATION.md) · 🇩🇰 [da](../da/CODEBASE_DOCUMENTATION.md) · 🇫🇮 [fi](../fi/CODEBASE_DOCUMENTATION.md) · 🇵🇹 [pt](../pt/CODEBASE_DOCUMENTATION.md) · 🇷🇴 [ro](../ro/CODEBASE_DOCUMENTATION.md) · 🇭🇺 [hu](../hu/CODEBASE_DOCUMENTATION.md) · 🇧🇬 [bg](../bg/CODEBASE_DOCUMENTATION.md) · 🇸🇰 [sk](../sk/CODEBASE_DOCUMENTATION.md) · 🇺🇦 [uk-UA](../uk-UA/CODEBASE_DOCUMENTATION.md) · 🇮🇱 [he](../he/CODEBASE_DOCUMENTATION.md) · 🇵🇭 [phi](../phi/CODEBASE_DOCUMENTATION.md) +# OmniRoute — 代码库文档 + +🌐 **语言:** 🇺🇸 [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) | 🇨🇿 [Čeština](../cs/CODEBASE_DOCUMENTATION.md) + +> **OmniRoute** 多提供商 AI 代理路由器的全面新手友好指南。 --- -# omniroute — Codebase Documentation +## 1. OmniRoute 是什么? -🌐 **Languages:** 🇺🇸 [English](CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](i18n/es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](i18n/fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](i18n/it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](i18n/ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](i18n/de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](i18n/in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](i18n/th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](i18n/uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](i18n/ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](i18n/ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](i18n/vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](i18n/bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](i18n/da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](i18n/fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](i18n/he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](i18n/hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](i18n/ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](i18n/nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](i18n/no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](i18n/pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](i18n/ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](i18n/pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](i18n/sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](i18n/sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](i18n/phi/CODEBASE_DOCUMENTATION.md) +OmniRoute 是一个**代理路由器**,位于 AI 客户端(Claude CLI、Codex、Cursor IDE 等)和 AI 提供商(Anthropic、Google、OpenAI、AWS、GitHub 等)之间。它解决了一个大问题: -> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router. +> **不同的 AI 客户端使用不同的"语言"(API 格式),不同的 AI 提供商也期望不同的"语言"。** OmniRoute 自动在它们之间进行翻译。 + +可以把它想象成联合国的万能翻译员 — 任何代表都可以说任何语言,翻译员会为任何其他代表进行转换。 --- -## 1. What Is omniroute? - -omniroute is a **proxy router** that sits between AI clients (Claude CLI, Codex, Cursor IDE, etc.) and AI providers (Anthropic, Google, OpenAI, AWS, GitHub, etc.). It solves one big problem: - -> **Different AI clients speak different "languages" (API formats), and different AI providers expect different "languages" too.** omniroute translates between them automatically. - -Think of it like a universal translator at the United Nations — any delegate can speak any language, and the translator converts it for any other delegate. - ---- - -## 2. Architecture Overview +## 2. 架构概述 ```mermaid graph LR - subgraph Clients + subgraph Clients[客户端] A[Claude CLI] B[Codex] C[Cursor IDE] - D[OpenAI-compatible] + D[OpenAI 兼容] end - subgraph omniroute - E[Handler Layer] - F[Translator Layer] - G[Executor Layer] - H[Services Layer] + subgraph omniroute[OmniRoute] + E[处理器层] + F[翻译器层] + G[执行器层] + H[服务层] end - subgraph Providers + subgraph Providers[提供商] I[Anthropic Claude] J[Google Gemini] K[OpenAI / Codex] @@ -65,90 +61,90 @@ graph LR H -.-> G ``` -### Core Principle: Hub-and-Spoke Translation +### 核心原则:中心辐射翻译 -All format translation passes through **OpenAI format as the hub**: +所有格式翻译都通过 **OpenAI 格式作为中心** 进行: ``` -Client Format → [OpenAI Hub] → Provider Format (request) -Provider Format → [OpenAI Hub] → Client Format (response) +客户端格式 → [OpenAI 中心] → 提供商格式 (请求) +提供商格式 → [OpenAI 中心] → 客户端格式 (响应) ``` -This means you only need **N translators** (one per format) instead of **N²** (every pair). +这意味着你只需要 **N 个翻译器**(每种格式一个)而不是 **N²**(每对格式一个)。 --- -## 3. Project Structure +## 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 +├── open-sse/ ← 核心代理库(可移植,框架无关) +│ ├── index.js ← 主入口点,导出所有内容 +│ ├── config/ ← 配置和常量 +│ ├── executors/ ← 提供商特定的请求执行 +│ ├── handlers/ ← 请求处理编排 +│ ├── services/ ← 业务逻辑(认证、模型、后备、用量) +│ ├── translator/ ← 格式翻译引擎 +│ │ ├── request/ ← 请求翻译器(8 个文件) +│ │ ├── response/ ← 响应翻译器(7 个文件) +│ │ └── helpers/ ← 共享翻译工具(6 个文件) +│ └── utils/ ← 工具函数 +├── src/ ← 应用层(Express/Worker 运行时) +│ ├── app/ ← Web UI、API 路由、中间件 +│ ├── lib/ ← 数据库、认证和共享库代码 +│ ├── mitm/ ← 中间人代理工具 +│ ├── models/ ← 数据库模型 +│ ├── shared/ ← 共享工具(open-sse 的包装器) +│ ├── sse/ ← SSE 端点处理器 +│ └── store/ ← 状态管理 +├── data/ ← 运行时数据(凭证、日志) +│ └── provider-credentials.json (外部凭证覆盖,已 gitignore) +└── tester/ ← 测试工具 ``` --- -## 4. Module-by-Module Breakdown +## 4. 模块逐一分解 -### 4.1 Config (`open-sse/config/`) +### 4.1 配置(`open-sse/config/`) -The **single source of truth** for all provider configuration. +所有提供商配置的**单一事实来源**。 -| File | Purpose | -| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `constants.ts` | `PROVIDERS` object with base URLs, OAuth credentials (defaults), headers, and default system prompts for every provider. Also defines `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, and `SKIP_PATTERNS`. | -| `credentialLoader.ts` | Loads external credentials from `data/provider-credentials.json` and merges them over the hardcoded defaults in `PROVIDERS`. Keeps secrets out of source control while maintaining backwards compatibility. | -| `providerModels.ts` | Central model registry: maps provider aliases → model IDs. Functions like `getModels()`, `getProviderByAlias()`. | -| `codexInstructions.ts` | System instructions injected into Codex requests (editing constraints, sandbox rules, approval policies). | -| `defaultThinkingSignature.ts` | Default "thinking" signatures for Claude and Gemini models. | -| `ollamaModels.ts` | Schema definition for local Ollama models (name, size, family, quantization). | +| 文件 | 用途 | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `constants.ts` | `PROVIDERS` 对象,包含每个提供商的基础 URL、OAuth 凭证(默认值)、请求头和默认系统提示词。还定义了 `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 模型的默认"thinking"签名。 | +| `ollamaModels.ts` | 本地 Ollama 模型的模式定义(名称、大小、家族、量化)。 | -#### Credential Loading Flow +#### 凭证加载流程 ```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"] + A["应用启动"] --> B["constants.ts 定义 PROVIDERS\n使用硬编码默认值"] + B --> C{"data/provider-credentials.json\n存在?"} + C -->|是| D["credentialLoader 读取 JSON"] + C -->|否| E["使用硬编码默认值"] + D --> F{"对于 JSON 中的每个提供商"} + F --> G{"提供商存在于\nPROVIDERS 中?"} + G -->|否| H["记录警告,跳过"] + G -->|是| I{"值是对象?"} + I -->|否| J["记录警告,跳过"] + I -->|是| K["合并 clientId、clientSecret、\ntokenUrl、authUrl、refreshUrl"] K --> F H --> F J --> F - F -->|Done| L["PROVIDERS ready with\nmerged credentials"] + F -->|完成| L["PROVIDERS 准备好\n使用合并后的凭证"] E --> L ``` --- -### 4.2 Executors (`open-sse/executors/`) +### 4.2 执行器(`open-sse/executors/`) -Executors encapsulate **provider-specific logic** using the **Strategy Pattern**. Each executor overrides base methods as needed. +执行器使用**策略模式**封装**提供商特定逻辑**。每个执行器根据需要覆盖基类方法。 ```mermaid classDiagram @@ -198,161 +194,161 @@ classDiagram BaseExecutor <|-- GithubExecutor ``` -| Executor | Provider | Key Specializations | -| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | -| `base.ts` | — | Abstract base: URL building, headers, retry logic, credential refresh | -| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generic OAuth token refresh for standard providers | -| `antigravity.ts` | Google Cloud Code | Project/session ID generation, multi-URL fallback, custom retry parsing from error messages ("reset after 2h7m23s") | -| `cursor.ts` | Cursor IDE | **Most complex**: SHA-256 checksum auth, Protobuf request encoding, binary EventStream → SSE response parsing | -| `codex.ts` | OpenAI Codex | Injects system instructions, manages thinking levels, removes unsupported parameters | -| `gemini-cli.ts` | Google Gemini CLI | Custom URL building (`streamGenerateContent`), Google OAuth token refresh | -| `github.ts` | GitHub Copilot | Dual token system (GitHub OAuth + Copilot token), VSCode header mimicking | -| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binary parsing, AMZN event frames, token estimation | -| `index.ts` | — | Factory: maps provider name → executor class, with default fallback | +| 执行器 | 提供商 | 关键特性 | +| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------ | +| `base.ts` | — | 抽象基类:URL 构建、请求头、重试逻辑、凭证刷新 | +| `default.ts` | Claude、Gemini、OpenAI、GLM、Kimi、MiniMax | 标准提供商的通用 OAuth Token 刷新 | +| `antigravity.ts` | Google Cloud Code | 项目/会话 ID 生成、多 URL 后备、从错误消息解析自定义重试("reset after 2h7m23s") | +| `cursor.ts` | Cursor IDE | **最复杂**:SHA-256 校验和认证、Protobuf 请求编码、二进制 EventStream → SSE 响应解析 | +| `codex.ts` | OpenAI Codex | 注入系统指令、管理 Thinking 级别、移除不支持的参数 | +| `gemini-cli.ts` | Google Gemini CLI | 自定义 URL 构建(`streamGenerateContent`)、Google OAuth Token 刷新 | +| `github.ts` | GitHub Copilot | 双 Token 系统(GitHub OAuth + Copilot Token)、模拟 VSCode 请求头 | +| `kiro.ts` | AWS CodeWhisperer | AWS EventStream 二进制解析、AMZN 事件帧、Token 估算 | +| `index.ts` | — | 工厂:将提供商名称映射到执行器类,带默认后备 | --- -### 4.3 Handlers (`open-sse/handlers/`) +### 4.3 处理器(`open-sse/handlers/`) -The **orchestration layer** — coordinates translation, execution, streaming, and error handling. +**编排层** — 协调翻译、执行、流式传输和错误处理。 -| File | Purpose | -| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `chatCore.ts` | **Central orchestrator** (~600 lines). Handles the complete request lifecycle: format detection → translation → executor dispatch → streaming/non-streaming response → token refresh → error handling → usage logging. | -| `responsesHandler.ts` | Adapter for OpenAI's Responses API: converts Responses format → Chat Completions → sends to `chatCore` → converts SSE back to Responses format. | -| `embeddings.ts` | Embedding generation handler: resolves embedding model → provider, dispatches to provider API, returns OpenAI-compatible embedding response. Supports 6+ providers. | -| `imageGeneration.ts` | Image generation handler: resolves image model → provider, supports OpenAI-compatible, Gemini-image (Antigravity), and fallback (Nebius) modes. Returns base64 or URL images. | +| 文件 | 用途 | +| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `chatCore.ts` | **中央编排器**(约 600 行)。处理完整的请求生命周期:格式检测 → 翻译 → 执行器调度 → 流式/非流式响应 → Token 刷新 → 错误处理 → 用量日志。 | +| `responsesHandler.ts` | OpenAI Responses API 适配器:将 Responses 格式 → Chat Completions → 发送到 `chatCore` → 将 SSE 转换回 Responses 格式。 | +| `embeddings.ts` | Embedding 生成处理器:解析 Embedding 模型 → 提供商,调度到提供商 API,返回 OpenAI 兼容的 Embedding 响应。支持 6+ 个提供商。 | +| `imageGeneration.ts` | 图像生成处理器:解析图像模型 → 提供商,支持 OpenAI 兼容、Gemini-image(Antigravity)和后备(Nebius)模式。返回 base64 或 URL 图像。 | -#### Request Lifecycle (chatCore.ts) +#### 请求生命周期(chatCore.ts) ```mermaid sequenceDiagram - participant Client + participant Client as 客户端 participant chatCore - participant Translator - participant Executor - participant Provider + participant Translator as 翻译器 + participant Executor as 执行器 + participant Provider as 提供商 - 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) + Client->>chatCore: 请求(任何格式) + chatCore->>chatCore: 检测源格式 + chatCore->>chatCore: 检查 bypass 模式 + chatCore->>chatCore: 解析模型和提供商 + chatCore->>Translator: 翻译请求(源 → OpenAI → 目标) + chatCore->>Executor: 获取提供商的执行器 + Executor->>Executor: 构建 URL、请求头、转换请求 + Executor->>Executor: 如需要则刷新凭证 + Executor->>Provider: HTTP fetch(流式或非流式) - 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 + alt 流式传输 + Provider-->>chatCore: SSE 流 + chatCore->>chatCore: 通过 SSE 转换流管道 + Note over chatCore: 转换流翻译
每个块:目标 → OpenAI → 源 + chatCore-->>Client: 已翻译的 SSE 流 + else 非流式传输 + Provider-->>chatCore: JSON 响应 + chatCore->>Translator: 翻译响应 + chatCore-->>Client: 已翻译的 JSON end - alt Error (401, 429, 500...) - chatCore->>Executor: Retry with credential refresh - chatCore->>chatCore: Account fallback logic + alt 错误 (401, 429, 500...) + chatCore->>Executor: 带凭证刷新重试 + chatCore->>chatCore: 账户后备逻辑 end ``` --- -### 4.4 Services (`open-sse/services/`) +### 4.4 服务(`open-sse/services/`) -Business logic that supports the handlers and executors. +支持处理器和执行器的业务逻辑。 -| File | Purpose | -| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `provider.ts` | **Format detection** (`detectFormat`): analyzes request body structure to identify Claude/OpenAI/Gemini/Antigravity/Responses formats (includes `max_tokens` heuristic for Claude). Also: URL building, header building, thinking config normalization. Supports `openai-compatible-*` and `anthropic-compatible-*` dynamic providers. | -| `model.ts` | Model string parsing (`claude/model-name` → `{provider: "claude", model: "model-name"}`), alias resolution with collision detection, input sanitization (rejects path traversal/control chars), and model info resolution with async alias getter support. | -| `accountFallback.ts` | Rate-limit handling: exponential backoff (1s → 2s → 4s → max 2min), account cooldown management, error classification (which errors trigger fallback vs. not). | -| `tokenRefresh.ts` | OAuth token refresh for **every provider**: Google (Gemini, Antigravity), Claude, Codex, Qwen, Qoder, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Includes in-flight promise deduplication cache and retry with exponential backoff. | -| `combo.ts` | **Combo models**: chains of fallback models. If model A fails with a fallback-eligible error, try model B, then C, etc. Returns actual upstream status codes. | -| `usage.ts` | Fetches quota/usage data from provider APIs (GitHub Copilot quotas, Antigravity model quotas, Codex rate limits, Kiro usage breakdowns, Claude settings). | -| `accountSelector.ts` | Smart account selection with scoring algorithm: considers priority, health status, round-robin position, and cooldown state to pick the optimal account for each request. | -| `contextManager.ts` | Request context lifecycle management: creates and tracks per-request context objects with metadata (request ID, timestamps, provider info) for debugging and logging. | -| `ipFilter.ts` | IP-based access control: supports allowlist and blocklist modes. Validates client IP against configured rules before processing API requests. | -| `sessionManager.ts` | Session tracking with client fingerprinting: tracks active sessions using hashed client identifiers, monitors request counts, and provides session metrics. | -| `signatureCache.ts` | Request signature-based deduplication cache: prevents duplicate requests by caching recent request signatures and returning cached responses for identical requests within a time window. | -| `systemPrompt.ts` | Global system prompt injection: prepends or appends a configurable system prompt to all requests, with per-provider compatibility handling. | -| `thinkingBudget.ts` | Reasoning token budget management: supports passthrough, auto (strip thinking config), custom (fixed budget), and adaptive (complexity-scaled) modes for controlling thinking/reasoning tokens. | -| `wildcardRouter.ts` | Wildcard model pattern routing: resolves wildcard patterns (e.g., `*/claude-*`) to concrete provider/model pairs based on availability and priority. | +| 文件 | 用途 | +| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `provider.ts` | **格式检测**(`detectFormat`):分析请求体结构以识别 Claude/OpenAI/Gemini/Antigravity/Responses 格式(包括 Claude 的 `max_tokens` 启发式)。还有:URL 构建、请求头构建、Thinking 配置规范化。支持 `openai-compatible-*` 和 `anthropic-compatible-*` 动态提供商。 | +| `model.ts` | 模型字符串解析(`claude/model-name` → `{provider: "claude", model: "model-name"}`)、带冲突检测的别名解析、输入清理(拒绝路径遍历/控制字符)、以及支持异步别名获取器的模型信息解析。 | +| `accountFallback.ts` | 速率限制处理:指数退避(1s → 2s → 4s → 最大 2 分钟)、账户冷却管理、错误分类(哪些错误触发后备,哪些不触发)。 | +| `tokenRefresh.ts` | **每个提供商**的 OAuth Token 刷新:Google(Gemini、Antigravity)、Claude、Codex、Qwen、Qoder、GitHub(OAuth + Copilot 双 Token)、Kiro(AWS SSO OIDC + 社交认证)。包括进行中 Promise 去重缓存和指数退避重试。 | +| `combo.ts` | **Combo 模型**:后备模型链。如果模型 A 因可后备错误失败,尝试模型 B,然后 C,依此类推。返回实际的上游状态码。 | +| `usage.ts` | 从提供商 API 获取配额/用量数据(GitHub Copilot 配额、Antigravity 模型配额、Codex 速率限制、Kiro 用量明细、Claude 设置)。 | +| `accountSelector.ts` | 智能账户选择与评分算法:考虑优先级、健康状态、轮询位置和冷却状态,为每个请求选择最优账户。 | +| `contextManager.ts` | 请求上下文生命周期管理:创建和追踪带有元数据(请求 ID、时间戳、提供商信息)的每请求上下文对象,用于调试和日志。 | +| `ipFilter.ts` | 基于 IP 的访问控制:支持白名单和黑名单模式。在处理 API 请求前根据配置规则验证客户端 IP。 | +| `sessionManager.ts` | 带客户端指纹的会话追踪:使用哈希客户端标识符追踪活动会话、监控请求计数、提供会话指标。 | +| `signatureCache.ts` | 基于请求签名的去重缓存:通过缓存近期请求签名并在时间窗口内为相同请求返回缓存响应来防止重复请求。 | +| `systemPrompt.ts` | 全局系统提示词注入:在所有请求前置或追加可配置的系统提示词,带每提供商兼容性处理。 | +| `thinkingBudget.ts` | 推理 Token 预算管理:支持 passthrough(透传)、auto(剥离 Thinking 配置)、custom(固定预算)和 adaptive(复杂度缩放)模式来控制 Thinking/推理 Token。 | +| `wildcardRouter.ts` | 通配符模型模式路由:根据可用性和优先级将通配符模式(如 `*/claude-*`)解析为具体的提供商/模型对。 | -#### Token Refresh Deduplication +#### Token 刷新去重 ```mermaid sequenceDiagram - participant R1 as Request 1 - participant R2 as Request 2 + participant R1 as 请求 1 + participant R2 as 请求 2 participant Cache as refreshPromiseCache - participant OAuth as OAuth Provider + participant OAuth as OAuth 提供商 R1->>Cache: getAccessToken("gemini", token) - Cache->>Cache: No in-flight promise - Cache->>OAuth: Start refresh + Cache->>Cache: 无进行中 Promise + Cache->>OAuth: 开始刷新 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 + Cache->>Cache: 找到进行中 Promise + Cache-->>R2: 返回现有 Promise + OAuth-->>Cache: 新访问 Token + Cache-->>R1: 新访问 Token + Cache-->>R2: 相同访问 Token(共享) + Cache->>Cache: 删除缓存条目 ``` -#### 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) + Active --> Error: 请求失败 (401/429/500) + Error --> Cooldown: 应用退避 + Cooldown --> Active: 冷却过期 + Active --> Active: 请求成功(重置退避) state Error { [*] --> ClassifyError - ClassifyError --> ShouldFallback: Rate limit / Auth / Transient - ClassifyError --> NoFallback: 400 Bad Request + ClassifyError --> ShouldFallback: 速率限制 / 认证 / 瞬态 + ClassifyError --> NoFallback: 400 错误请求 } state Cooldown { [*] --> ExponentialBackoff - ExponentialBackoff: Level 0 = 1s - ExponentialBackoff: Level 1 = 2s - ExponentialBackoff: Level 2 = 4s - ExponentialBackoff: Max = 2min + ExponentialBackoff: 级别 0 = 1s + ExponentialBackoff: 级别 1 = 2s + ExponentialBackoff: 级别 2 = 4s + ExponentialBackoff: 最大 = 2min } ``` -#### Combo Model Chain +#### 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"] + A["带 Combo 模型的请求"] --> B["模型 A"] + B -->|"2xx 成功"| C["返回响应"] + B -->|"429/401/500"| D{"可后备?"} + D -->|是| E["模型 B"] + D -->|否| F["返回错误"] + E -->|"2xx 成功"| C + E -->|"429/401/500"| G{"可后备?"} + G -->|是| H["模型 C"] + G -->|否| F + H -->|"2xx 成功"| C + H -->|"失败"| I["全部失败 →\n返回最后状态"] ``` --- -### 4.5 Translator (`open-sse/translator/`) +### 4.5 翻译器(`open-sse/translator/`) -The **format translation engine** using a self-registering plugin system. +使用自注册插件系统的**格式翻译引擎**。 -#### Architecture +#### 架构 ```mermaid graph TD @@ -378,40 +374,40 @@ graph TD end ``` -| Directory | Files | Description | -| ------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `request/` | 8 translators | Convert request bodies between formats. Each file self-registers via `register(from, to, fn)` on import. | -| `response/` | 7 translators | Convert streaming response chunks between formats. Handles SSE event types, thinking blocks, tool calls. | -| `helpers/` | 6 helpers | Shared utilities: `claudeHelper` (system prompt extraction, thinking config), `geminiHelper` (parts/contents mapping), `openaiHelper` (format filtering), `toolCallHelper` (ID generation, missing response injection), `maxTokensHelper`, `responsesApiHelper`. | -| `index.ts` | — | Translation engine: `translateRequest()`, `translateResponse()`, state management, registry. | -| `formats.ts` | — | Format constants: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | +| 目录 | 文件数 | 描述 | +| ------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request/` | 8 个翻译器 | 在不同格式之间转换请求体。每个文件在导入时通过 `register(from, to, fn)` 自注册。 | +| `response/` | 7 个翻译器 | 在不同格式之间转换流式响应块。处理 SSE 事件类型、thinking 块、工具调用。 | +| `helpers/` | 6 个辅助工具 | 共享工具:`claudeHelper`(系统提示词提取、thinking 配置)、`geminiHelper`(parts/contents 映射)、`openaiHelper`(格式过滤)、`toolCallHelper`(ID 生成、缺失响应注入)、`maxTokensHelper`、`responsesApiHelper`。 | +| `index.ts` | — | 翻译引擎:`translateRequest()`、`translateResponse()`、状态管理、注册表。 | +| `formats.ts` | — | 格式常量:`OPENAI`、`CLAUDE`、`GEMINI`、`ANTIGRAVITY`、`KIRO`、`CURSOR`、`OPENAI_RESPONSES`。 | -#### Key Design: Self-Registering Plugins +#### 关键设计:自注册插件 ```javascript -// Each translator file calls register() on import: +// 每个翻译器文件在导入时调用 register(): import { register } from "../index.js"; register("claude", "openai", translateClaudeToOpenAI); -// The index.js imports all translator files, triggering registration: -import "./request/claude-to-openai.js"; // ← self-registers +// index.js 导入所有翻译器文件,触发注册: +import "./request/claude-to-openai.js"; // ← 自注册 ``` --- -### 4.6 Utils (`open-sse/utils/`) +### 4.6 工具 (`open-sse/utils/`) -| File | Purpose | -| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `error.ts` | Error response building (OpenAI-compatible format), upstream error parsing, Antigravity retry-time extraction from error messages, SSE error streaming. | -| `stream.ts` | **SSE Transform Stream** — the core streaming pipeline. Two modes: `TRANSLATE` (full format translation) and `PASSTHROUGH` (normalize + extract usage). Handles chunk buffering, usage estimation, content length tracking. Per-stream encoder/decoder instances avoid shared state. | -| `streamHelpers.ts` | Low-level SSE utilities: `parseSSELine` (whitespace-tolerant), `hasValuableContent` (filters empty chunks for OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (format-aware SSE serialization with `perf_metrics` cleanup). | -| `usageTracking.ts` | Token usage extraction from any format (Claude/OpenAI/Gemini/Responses), estimation with separate tool/message char-per-token ratios, buffer addition (2000 tokens safety margin), format-specific field filtering, console logging with ANSI colors. | -| `requestLogger.ts` | File-based request logging (opt-in via `ENABLE_REQUEST_LOGS=true`). Creates session folders with numbered files: `1_req_client.json` → `7_res_client.txt`. All I/O is async (fire-and-forget). Masks sensitive headers. | -| `bypassHandler.ts` | Intercepts specific patterns from Claude CLI (title extraction, warmup, count) and returns fake responses without calling any provider. Supports both streaming and non-streaming. Intentionally limited to Claude CLI scope. | -| `networkProxy.ts` | Resolves outbound proxy URL for a given provider with precedence: provider-specific config → global config → environment variables (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Supports `NO_PROXY` exclusions. Caches config for 30s. | +| 文件 | 用途 | +| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `error.ts` | 错误响应构建(OpenAI 兼容格式)、上游错误解析、从错误消息中提取 Antigravity 重试时间、SSE 错误流式传输。 | +| `stream.ts` | **SSE 转换流** — 核心流式管道。两种模式:`TRANSLATE`(完整格式转换)和 `PASSTHROUGH`(规范化 + 提取用量)。处理块缓冲、用量估算、内容长度追踪。每流独立的 encoder/decoder 实例避免共享状态。 | +| `streamHelpers.ts` | 底层 SSE 工具:`parseSSELine`(容忍空白)、`hasValuableContent`(过滤 OpenAI/Claude/Gemini 的空块)、`fixInvalidId`、`formatSSE`(感知格式的 SSE 序列化,清理 `perf_metrics`)。 | +| `usageTracking.ts` | 从任何格式提取 Token 用量(Claude/OpenAI/Gemini/Responses),使用独立的工具/消息字符-token 比率估算,添加缓冲(2000 token 安全边际),格式特定字段过滤,带 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` | 为给定提供商解析出站代理 URL,优先级:提供商特定配置 → 全局配置 → 环境变量(`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`)。支持 `NO_PROXY` 排除。配置缓存 30 秒。 | -#### SSE Streaming Pipeline +#### SSE 流管道 ```mermaid flowchart TD @@ -433,161 +429,161 @@ flowchart TD style M fill:#9f9,stroke:#333 ``` -#### Request Logger Session Structure +#### 请求日志器会话结构 ``` logs/ └── claude_gemini_claude-sonnet_20260208_143045/ - ├── 1_req_client.json ← Raw client request - ├── 2_req_source.json ← After initial conversion - ├── 3_req_openai.json ← OpenAI intermediate format - ├── 4_req_target.json ← Final target format - ├── 5_res_provider.txt ← Provider SSE chunks (streaming) - ├── 5_res_provider.json ← Provider response (non-streaming) - ├── 6_res_openai.txt ← OpenAI intermediate chunks - ├── 7_res_client.txt ← Client-facing SSE chunks - └── 6_error.json ← Error details (if any) + ├── 1_req_client.json ← 原始客户端请求 + ├── 2_req_source.json ← 初始转换后 + ├── 3_req_openai.json ← OpenAI 中间格式 + ├── 4_req_target.json ← 最终目标格式 + ├── 5_res_provider.txt ← 提供商 SSE 块(流式) + ├── 5_res_provider.json ← 提供商响应(非流式) + ├── 6_res_openai.txt ← OpenAI 中间块 + ├── 7_res_client.txt ← 面向客户端的 SSE 块 + └── 6_error.json ← 错误详情(如有) ``` --- -### 4.7 Application Layer (`src/`) +### 4.7 应用层(`src/`) -| Directory | Purpose | -| ------------- | ---------------------------------------------------------------------- | -| `src/app/` | Web UI, API routes, Express middleware, OAuth callback handlers | -| `src/lib/` | Database access (`localDb.ts`, `usageDb.ts`), authentication, shared | -| `src/mitm/` | Man-in-the-middle proxy utilities for intercepting provider traffic | -| `src/models/` | Database model definitions | -| `src/shared/` | Wrappers around open-sse functions (provider, stream, error, etc.) | -| `src/sse/` | SSE endpoint handlers that wire the open-sse library to Express routes | -| `src/store/` | Application state management | +| 目录 | 用途 | +| ------------- | ---------------------------------------------------- | +| `src/app/` | Web UI、API 路由、Express 中间件、OAuth 回调处理器 | +| `src/lib/` | 数据库访问(`localDb.ts`、`usageDb.ts`)、认证、共享 | +| `src/mitm/` | 用于拦截提供商流量的中间人代理工具 | +| `src/models/` | 数据库模型定义 | +| `src/shared/` | open-sse 函数的包装器(provider、stream、error 等) | +| `src/sse/` | 将 open-sse 库连接到 Express 路由的 SSE 端点处理器 | +| `src/store/` | 应用状态管理 | -#### Notable API Routes +#### 重要 API 路由 -| Route | Methods | Purpose | -| --------------------------------------------- | --------------- | ------------------------------------------------------------------------------------- | -| `/api/provider-models` | GET/POST/DELETE | CRUD for custom models per provider | -| `/api/models/catalog` | GET | Aggregated catalog of all models (chat, embedding, image, custom) grouped by provider | -| `/api/settings/proxy` | GET/PUT/DELETE | Hierarchical outbound proxy configuration (`global/providers/combos/keys`) | -| `/api/settings/proxy/test` | POST | Validates proxy connectivity and returns public IP/latency | -| `/v1/providers/[provider]/chat/completions` | POST | Dedicated per-provider chat completions with model validation | -| `/v1/providers/[provider]/embeddings` | POST | Dedicated per-provider embeddings with model validation | -| `/v1/providers/[provider]/images/generations` | POST | Dedicated per-provider image generation with model validation | -| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist management | -| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget configuration (passthrough/auto/custom/adaptive) | -| `/api/settings/system-prompt` | GET/PUT | Global system prompt injection for all requests | -| `/api/sessions` | GET | Active session tracking and metrics | -| `/api/rate-limits` | GET | Per-account rate limit status | +| 路由 | 方法 | 用途 | +| --------------------------------------------- | --------------- | ----------------------------------------------------------------- | +| `/api/provider-models` | GET/POST/DELETE | 每提供商自定义模型的 CRUD | +| `/api/models/catalog` | GET | 按提供商分组的所有模型(聊天、Embedding、图像、自定义)的聚合目录 | +| `/api/settings/proxy` | GET/PUT/DELETE | 分层出站代理配置(`global/providers/combos/keys`) | +| `/api/settings/proxy/test` | POST | 验证代理连接并返回公共 IP/延迟 | +| `/v1/providers/[provider]/chat/completions` | POST | 带模型验证的专用每提供商聊天完成 | +| `/v1/providers/[provider]/embeddings` | POST | 带模型验证的专用每提供商 Embedding | +| `/v1/providers/[provider]/images/generations` | POST | 带模型验证的专用每提供商图像生成 | +| `/api/settings/ip-filter` | GET/PUT | IP 白名单/黑名单管理 | +| `/api/settings/thinking-budget` | GET/PUT | 推理 Token 预算配置(passthrough/auto/custom/adaptive) | +| `/api/settings/system-prompt` | GET/PUT | 所有请求的全局系统提示词注入 | +| `/api/sessions` | GET | 活动会话追踪和指标 | +| `/api/rate-limits` | GET | 每账户速率限制状态 | --- -## 5. Key Design Patterns +## 5. 关键设计模式 -### 5.1 Hub-and-Spoke Translation +### 5.1 中心辐射翻译 -All formats translate through **OpenAI format as the hub**. Adding a new provider only requires writing **one pair** of translators (to/from OpenAI), not N pairs. +所有格式都通过 **OpenAI 格式作为中心** 进行翻译。添加新提供商只需要编写**一对**翻译器(到/从 OpenAI),而不是 N 对。 -### 5.2 Executor Strategy Pattern +### 5.2 执行器策略模式 -Each provider has a dedicated executor class inheriting from `BaseExecutor`. The factory in `executors/index.ts` selects the right one at runtime. +每个提供商都有一个继承自 `BaseExecutor` 的专用执行器类。`executors/index.ts` 中的工厂在运行时选择正确的执行器。 -### 5.3 Self-Registering Plugin System +### 5.3 自注册插件系统 -Translator modules register themselves on import via `register()`. Adding a new translator is just creating a file and importing it. +翻译器模块在导入时通过 `register()` 自注册。添加新翻译器只需创建文件并导入它。 -### 5.4 Account Fallback with Exponential Backoff +### 5.4 带指数退避的账户后备 -When a provider returns 429/401/500, the system can switch to the next account, applying exponential cooldowns (1s → 2s → 4s → max 2min). +当提供商返回 429/401/500 时,系统可以切换到下一个账户,应用指数冷却(1s → 2s → 4s → 最大 2min)。 -### 5.5 Combo Model Chains +### 5.5 Combo 模型链 -A "combo" groups multiple `provider/model` strings. If the first fails, fallback to the next automatically. +"Combo"组合多个 `provider/model` 字符串。如果第一个失败,自动后备到下一个。 -### 5.6 Stateful Streaming Translation +### 5.6 有状态流式翻译 -Response translation maintains state across SSE chunks (thinking block tracking, tool call accumulation, content block indexing) via the `initState()` mechanism. +响应翻译通过 `initState()` 机制在 SSE 块之间维护状态(Thinking 块追踪、工具调用累积、内容块索引)。 -### 5.7 Usage Safety Buffer +### 5.7 用量安全缓冲 -A 2000-token buffer is added to reported usage to prevent clients from hitting context window limits due to overhead from system prompts and format translation. +在报告的用量中添加 2000 Token 缓冲,以防止客户端因系统提示词和格式翻译开销而达到上下文窗口限制。 --- -## 6. Supported Formats +## 6. 支持的格式 -| Format | Direction | Identifier | -| ----------------------- | --------------- | ------------------ | -| OpenAI Chat Completions | source + target | `openai` | -| OpenAI Responses API | source + target | `openai-responses` | -| Anthropic Claude | source + target | `claude` | -| Google Gemini | source + target | `gemini` | -| Google Gemini CLI | target only | `gemini-cli` | -| Antigravity | source + target | `antigravity` | -| AWS Kiro | target only | `kiro` | -| Cursor | target only | `cursor` | +| 格式 | 方向 | 标识符 | +| ----------------------- | --------- | ------------------ | +| OpenAI Chat Completions | 源 + 目标 | `openai` | +| OpenAI Responses API | 源 + 目标 | `openai-responses` | +| Anthropic Claude | 源 + 目标 | `claude` | +| Google Gemini | 源 + 目标 | `gemini` | +| Google Gemini CLI | 仅目标 | `gemini-cli` | +| Antigravity | 源 + 目标 | `antigravity` | +| AWS Kiro | 仅目标 | `kiro` | +| Cursor | 仅目标 | `cursor` | --- -## 7. Supported Providers +## 7. 支持的提供商 -| Provider | Auth Method | Executor | Key Notes | -| ------------------------ | ---------------------- | ----------- | --------------------------------------------- | -| Anthropic Claude | API key or OAuth | Default | Uses `x-api-key` header | -| Google Gemini | API key or OAuth | Default | Uses `x-goog-api-key` header | -| Google Gemini CLI | OAuth | GeminiCLI | Uses `streamGenerateContent` endpoint | -| Antigravity | OAuth | Antigravity | Multi-URL fallback, custom retry parsing | -| OpenAI | API key | Default | Standard Bearer auth | -| Codex | OAuth | Codex | Injects system instructions, manages thinking | -| GitHub Copilot | OAuth + Copilot token | Github | Dual token, VSCode header mimicking | -| Kiro (AWS) | AWS SSO OIDC or Social | Kiro | Binary EventStream parsing | -| Cursor IDE | Checksum auth | Cursor | Protobuf encoding, SHA-256 checksums | -| Qwen | OAuth | Default | Standard auth | -| Qoder | OAuth (Basic + Bearer) | Default | Dual auth header | -| OpenRouter | API key | Default | Standard Bearer auth | -| GLM, Kimi, MiniMax | API key | Default | Claude-compatible, use `x-api-key` | -| `openai-compatible-*` | API key | Default | Dynamic: any OpenAI-compatible endpoint | -| `anthropic-compatible-*` | API key | Default | Dynamic: any Claude-compatible endpoint | +| 提供商 | 认证方法 | 执行器 | 关键说明 | +| ------------------------ | ----------------------- | ----------- | --------------------------------- | +| Anthropic Claude | API 密钥或 OAuth | Default | 使用 `x-api-key` 请求头 | +| Google Gemini | API 密钥或 OAuth | Default | 使用 `x-goog-api-key` 请求头 | +| Google Gemini CLI | OAuth | GeminiCLI | 使用 `streamGenerateContent` 端点 | +| Antigravity | OAuth | Antigravity | 多 URL 后备,自定义重试解析 | +| OpenAI | API 密钥 | Default | 标准 Bearer 认证 | +| Codex | OAuth | Codex | 注入系统指令,管理 Thinking | +| GitHub Copilot | OAuth + Copilot Token | Github | 双 Token,模拟 VSCode 请求头 | +| Kiro (AWS) | AWS SSO OIDC 或社交 | Kiro | 二进制 EventStream 解析 | +| Cursor IDE | 校验和认证 | Cursor | Protobuf 编码,SHA-256 校验和 | +| Qwen | OAuth | Default | 标准认证 | +| Qoder | OAuth(Basic + Bearer) | Default | 双认证请求头 | +| OpenRouter | API 密钥 | Default | 标准 Bearer 认证 | +| GLM、Kimi、MiniMax | API 密钥 | Default | Claude 兼容,使用 `x-api-key` | +| `openai-compatible-*` | API 密钥 | Default | 动态:任何 OpenAI 兼容端点 | +| `anthropic-compatible-*` | API 密钥 | Default | 动态:任何 Claude 兼容端点 | --- -## 8. Data Flow Summary +## 8. 数据流摘要 -### Streaming Request +### 流式请求 ```mermaid flowchart LR - A["Client"] --> B["detectFormat()"] - B --> C["translateRequest()\nsource → OpenAI → target"] - C --> D["Executor\nbuildUrl + buildHeaders"] + A["客户端"] --> B["detectFormat()"] + B --> C["translateRequest()\n源 → OpenAI → 目标"] + C --> D["执行器\nbuildUrl + buildHeaders"] D --> E["fetch(providerURL)"] - E --> F["createSSEStream()\nTRANSLATE mode"] + E --> F["createSSEStream()\nTRANSLATE 模式"] F --> G["parseSSELine()"] - G --> H["translateResponse()\ntarget → OpenAI → source"] + G --> H["translateResponse()\n目标 → OpenAI → 源"] H --> I["extractUsage()\n+ addBuffer"] I --> J["formatSSE()"] - J --> K["Client receives\ntranslated SSE"] + J --> K["客户端接收\n已翻译的 SSE"] K --> L["logUsage()\nsaveRequestUsage()"] ``` -### Non-Streaming Request +### 非流式请求 ```mermaid flowchart LR - A["Client"] --> B["detectFormat()"] - B --> C["translateRequest()\nsource → OpenAI → target"] + A["客户端"] --> B["detectFormat()"] + B --> C["translateRequest()\n源 → OpenAI → 目标"] C --> D["Executor.execute()"] - D --> E["translateResponse()\ntarget → OpenAI → source"] - E --> F["Return JSON\nresponse"] + D --> E["translateResponse()\n目标 → OpenAI → 源"] + E --> F["返回 JSON\n响应"] ``` -### Bypass Flow (Claude CLI) +### 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"] + A["Claude CLI 请求"] --> B{"匹配 bypass\n模式?"} + B -->|"标题/预热/计数"| C["生成假\nOpenAI 响应"] + B -->|"无匹配"| D["正常流程"] + C --> E["翻译为\n源格式"] + E --> F["返回而不\n调用提供商"] ``` diff --git a/docs/i18n/zh-CN/FEATURES.md b/docs/i18n/zh-CN/FEATURES.md index 12e39014..60c9ace8 100644 --- a/docs/i18n/zh-CN/FEATURES.md +++ b/docs/i18n/zh-CN/FEATURES.md @@ -1,147 +1,143 @@ -# OmniRoute — Dashboard Features Gallery (中文(简体)) +# OmniRoute — 仪表盘功能展示 -🌐 **Languages:** 🇺🇸 [English](../../../README.md) · 🇧🇷 [pt-BR](../pt-BR/README.md) · 🇪🇸 [es](../es/README.md) · 🇫🇷 [fr](../fr/README.md) · 🇩🇪 [de](../de/README.md) · 🇮🇹 [it](../it/README.md) · 🇷🇺 [ru](../ru/README.md) · 🇨🇳 [zh-CN](../zh-CN/README.md) · 🇯🇵 [ja](../ja/README.md) · 🇰🇷 [ko](../ko/README.md) · 🇸🇦 [ar](../ar/README.md) · 🇮🇳 [in](../in/README.md) · 🇹🇭 [th](../th/README.md) · 🇻🇳 [vi](../vi/README.md) · 🇮🇩 [id](../id/README.md) · 🇲🇾 [ms](../ms/README.md) · 🇳🇱 [nl](../nl/README.md) · 🇵🇱 [pl](../pl/README.md) · 🇸🇪 [sv](../sv/README.md) · 🇳🇴 [no](../no/README.md) · 🇩🇰 [da](../da/README.md) · 🇫🇮 [fi](../fi/README.md) · 🇵🇹 [pt](../pt/README.md) · 🇷🇴 [ro](../ro/README.md) · 🇭🇺 [hu](../hu/README.md) · 🇧🇬 [bg](../bg/README.md) · 🇸🇰 [sk](../sk/README.md) · 🇺🇦 [uk-UA](../uk-UA/README.md) · 🇮🇱 [he](../he/README.md) · 🇵🇭 [phi](../phi/README.md) +🌐 **语言:** 🇺🇸 [English](../../FEATURES.md) · 🇧🇷 [pt-BR](../pt-BR/FEATURES.md) · 🇪🇸 [es](../es/FEATURES.md) · 🇫🇷 [fr](../fr/FEATURES.md) · 🇩🇪 [de](../de/FEATURES.md) · 🇮🇹 [it](../it/FEATURES.md) · 🇷🇺 [ru](../ru/FEATURES.md) · 🇨🇳 [zh-CN](../zh-CN/FEATURES.md) · 🇯🇵 [ja](../ja/FEATURES.md) · 🇰🇷 [ko](../ko/FEATURES.md) · 🇸🇦 [ar](../ar/FEATURES.md) · 🇮🇳 [in](../in/FEATURES.md) · 🇹🇭 [th](../th/FEATURES.md) · 🇻🇳 [vi](../vi/FEATURES.md) · 🇮🇩 [id](../id/FEATURES.md) · 🇲🇾 [ms](../ms/FEATURES.md) · 🇳🇱 [nl](../nl/FEATURES.md) · 🇵🇱 [pl](../pl/FEATURES.md) · 🇸🇪 [sv](../sv/FEATURES.md) · 🇳🇴 [no](../no/FEATURES.md) · 🇩🇰 [da](../da/FEATURES.md) · 🇫🇮 [fi](../fi/FEATURES.md) · 🇵🇹 [pt](../pt/FEATURES.md) · 🇷🇴 [ro](../ro/FEATURES.md) · 🇭🇺 [hu](../hu/FEATURES.md) · 🇧🇬 [bg](../bg/FEATURES.md) · 🇸🇰 [sk](../sk/FEATURES.md) · 🇺🇦 [uk-UA](../uk-UA/FEATURES.md) · 🇮🇱 [he](../he/FEATURES.md) · 🇵🇭 [phi](../phi/FEATURES.md) · 🇨🇿 [cs](../cs/FEATURES.md) -> 🇺🇸 [English](../../../docs/FEATURES.md) +OmniRoute 仪表盘各部分的可视化指南。 --- -Visual guide to every section of the OmniRoute dashboard. +## 🔌 服务商 ---- - -## 🔌 Providers - -Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (Qoder, Qwen, Kiro). Kiro accounts include credit balance tracking — remaining credits, total allowance, and renewal date visible in Dashboard → Usage. +管理 AI 服务商连接:OAuth 服务商(Claude Code、Codex、Gemini CLI)、API 密钥服务商(Groq、DeepSeek、OpenRouter)以及免费服务商(Qoder、Qwen、Kiro)。Kiro 账户包含额度余额跟踪 — 剩余额度、总配额和续期日期可在 Dashboard → Usage 中查看。 ![Providers Dashboard](screenshots/01-providers.png) --- -## 🎨 Combos +## 🎨 组合 -Create model routing combos with 6 strategies: priority, weighted, round-robin, random, least-used, and cost-optimized. Each combo chains multiple models with automatic fallback and includes quick templates and readiness checks. +创建具有 6 种策略的模型路由组合:优先级、加权、轮询、随机、最少使用和成本优化。每个组合可链接多个模型并支持自动回退,还包括快速模板和就绪检查。 ![Combos Dashboard](screenshots/02-combos.png) --- -## 📊 Analytics +## 📊 分析 -Comprehensive usage analytics with token consumption, cost estimates, activity heatmaps, weekly distribution charts, and per-provider breakdowns. +全面的使用分析,包括 token 消耗、成本估算、活动热力图、每周分布图表以及按服务商细分。 ![Analytics Dashboard](screenshots/03-analytics.png) --- -## 🏥 System Health +## 🏥 系统健康 -Real-time monitoring: uptime, memory, version, latency percentiles (p50/p95/p99), cache statistics, and provider circuit breaker states. +实时监控:运行时间、内存、版本、延迟百分位数(p50/p95/p99)、缓存统计和服务商熔断器状态。 ![Health Dashboard](screenshots/04-health.png) --- -## 🔧 Translator Playground +## 🔧 翻译器测试场 -Four modes for debugging API translations: **Playground** (format converter), **Chat Tester** (live requests), **Test Bench** (batch tests), and **Live Monitor** (real-time stream). +四种调试 API 翻译的模式:**Playground**(格式转换器)、**Chat Tester**(实时请求)、**Test Bench**(批量测试)和 **Live Monitor**(实时流)。 ![Translator Playground](screenshots/05-translator.png) --- -## 🎮 Model Playground _(v2.0.9+)_ +## 🎮 模型测试场 _(v2.0.9+)_ -Test any model directly from the dashboard. Select provider, model, and endpoint, write prompts with Monaco Editor, stream responses in real-time, abort mid-stream, and view timing metrics. +直接从仪表盘测试任何模型。选择服务商、模型和端点,使用 Monaco Editor 编写提示,实时流式响应,可中途中止,并查看计时指标。 --- -## 🎨 Themes _(v2.0.5+)_ +## 🎨 主题 _(v2.0.5+)_ -Customizable color themes for the entire dashboard. Choose from 7 preset colors (Coral, Blue, Red, Green, Violet, Orange, Cyan) or create a custom theme by picking any hex color. Supports light, dark, and system mode. +整个仪表盘可自定义颜色主题。可从 7 种预设颜色(珊瑚色、蓝色、红色、绿色、紫罗兰色、橙色、青色)中选择,或通过选择任何十六进制颜色创建自定义主题。支持浅色、深色和跟随系统模式。 --- -## ⚙️ Settings +## ⚙️ 设置 -Comprehensive settings panel with tabs: +全面的设置面板,包含以下标签页: -- **General** — System storage, backup management (export/import database) -- **Appearance** — Theme selector (dark/light/system), color theme presets and custom colors, health log visibility, sidebar item visibility controls -- **Security** — API endpoint protection, custom provider blocking, IP filtering, session info -- **Routing** — Model aliases, background task degradation -- **Resilience** — Rate limit persistence, circuit breaker tuning -- **Advanced** — Configuration overrides +- **通用** — 系统存储、备份管理(导出/导入数据库) +- **外观** — 主题选择器(深色/浅色/跟随系统)、颜色主题预设和自定义颜色、健康日志可见性、侧边栏项目可见性控制 +- **安全** — API 端点保护、自定义服务商屏蔽、IP 过滤、会话信息 +- **路由** — 模型别名、后台任务降级 +- **弹性** — 速率限制持久化、熔断器调优、自动禁用被封禁账户、服务商过期监控 +- **高级** — 配置覆盖、配置审计追踪、回退降级模式 ![Settings Dashboard](screenshots/06-settings.png) --- -## 🔧 CLI Tools +## 🔧 CLI 工具 -One-click configuration for AI coding tools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor, and Factory Droid. Features automated config apply/reset, connection profiles, and model mapping. +一键配置 AI 编程工具:Claude Code、Codex CLI、Gemini CLI、OpenClaw、Kilo Code、Antigravity、Cline、Continue、Cursor 和 Factory Droid。具备自动化配置应用/重置、连接配置文件和模型映射功能。 ![CLI Tools Dashboard](screenshots/07-cli-tools.png) --- -## 🤖 CLI Agents _(v2.0.11+)_ +## 🤖 CLI 代理 _(v2.0.11+)_ -Dashboard for discovering and managing CLI agents. Shows a grid of 14 built-in agents (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) with: +发现和管理 CLI 代理的仪表盘。显示 14 个内置代理(Codex、Claude、Goose、Gemini CLI、OpenClaw、Aider、OpenCode、Cline、Qwen Code、ForgeCode、Amazon Q、Open Interpreter、Cursor CLI、Warp)的网格视图,具有: -- **Installation status** — Installed / Not Found with version detection -- **Protocol badges** — stdio, HTTP, etc. -- **Custom agents** — Register any CLI tool via form (name, binary, version command, spawn args) -- **CLI Fingerprint Matching** — Per-provider toggle to match native CLI request signatures, reducing ban risk while preserving proxy IP +- **安装状态** — 已安装 / 未找到,带版本检测 +- **协议徽章** — stdio、HTTP 等 +- **自定义代理** — 通过表单注册任何 CLI 工具(名称、二进制文件、版本命令、启动参数) +- **CLI 指纹匹配** — 按服务商切换以匹配原生 CLI 请求签名,在保持代理 IP 的同时降低封禁风险 --- -## 🖼️ Media _(v2.0.3+)_ +## 🖼️ 媒体 _(v2.0.3+)_ -Generate images, videos, and music from the dashboard. Supports OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open, and MusicGen. +从仪表盘生成图像、视频和音乐。支持 OpenAI、xAI、Together、Hyperbolic、SD WebUI、ComfyUI、AnimateDiff、Stable Audio Open 和 MusicGen。 --- -## 📝 Request Logs +## 📝 请求日志 -Real-time request logging with filtering by provider, model, account, and API key. Shows status codes, token usage, latency, and response details. +实时请求日志,支持按服务商、模型、账户和 API 密钥过滤。显示状态码、token 使用量、延迟和响应详情。 ![Usage Logs](screenshots/08-usage.png) --- -## 🌐 API Endpoint +## 🌐 API 端点 -Your unified API endpoint with capability breakdown: Chat Completions, Responses API, Embeddings, Image Generation, Reranking, Audio Transcription, Text-to-Speech, Moderations, and registered API keys. Cloud proxy support for remote access. +您的统一 API 端点,包含能力分解:Chat Completions、Responses API、Embeddings、Image Generation、Reranking、Audio Transcription、Text-to-Speech、Moderations 以及已注册的 API 密钥。支持 Cloudflare Quick Tunnel 集成和云代理进行远程访问。 ![Endpoint Dashboard](screenshots/09-endpoint.png) --- -## 🔑 API Key Management +## 🔑 API 密钥管理 -Create, scope, and revoke API keys. Each key can be restricted to specific models/providers with full access or read-only permissions. Visual key management with usage tracking. +创建、限定范围和撤销 API 密钥。每个密钥可限制为特定模型/服务商,具有完全访问或只读权限。可视化密钥管理及使用跟踪。 --- -## 📋 Audit Log +## 📋 审计日志 -Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history. +管理操作跟踪,支持按操作类型、操作者、目标、IP 地址和时间戳过滤。完整的安全事件历史记录。 --- -## 🖥️ Desktop Application +## 🖥️ 桌面应用 -Native Electron desktop app for Windows, macOS, and Linux. Run OmniRoute as a standalone application with system tray integration, offline support, auto-update, and one-click install. +适用于 Windows、macOS 和 Linux 的原生 Electron 桌面应用。将 OmniRoute 作为独立应用运行,具有系统托盘集成、离线支持、自动更新和一键安装。 -Key features: +主要特性: -- Server readiness polling (no blank screen on cold start) -- System tray with port management -- Content Security Policy -- Single-instance lock -- Auto-update on restart -- Platform-conditional UI (macOS traffic lights, Windows/Linux default titlebar) -- Hardened Electron build packaging — symlinked `node_modules` in the standalone bundle is detected and rejected before packaging, preventing runtime dependency on the build machine (v2.5.5+) +- 服务器就绪轮询(冷启动时无白屏) +- 带端口管理的系统托盘 +- 内容安全策略 +- 单实例锁定 +- 重启时自动更新 +- 平台条件化 UI(macOS 红绿灯、Windows/Linux 默认标题栏) +- 强化的 Electron 构建打包 — 独立包中的符号链接 `node_modules` 会在打包前被检测并拒绝,防止对构建机器的运行时依赖 (v2.5.5+) -📖 See [`electron/README.md`](../electron/README.md) for full documentation. +📖 完整文档请参阅 [`electron/README.md`](../electron/README.md)。 diff --git a/docs/i18n/zh-CN/MCP-SERVER.md b/docs/i18n/zh-CN/MCP-SERVER.md index 829acd30..0fe48604 100644 --- a/docs/i18n/zh-CN/MCP-SERVER.md +++ b/docs/i18n/zh-CN/MCP-SERVER.md @@ -1,63 +1,63 @@ -🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/MCP-SERVER.md) · 🇪🇸 [es](../es/MCP-SERVER.md) · 🇫🇷 [fr](../fr/MCP-SERVER.md) · 🇩🇪 [de](../de/MCP-SERVER.md) · 🇮🇹 [it](../it/MCP-SERVER.md) · 🇷🇺 [ru](../ru/MCP-SERVER.md) · 🇨🇳 [zh-CN](../zh-CN/MCP-SERVER.md) · 🇯🇵 [ja](../ja/MCP-SERVER.md) · 🇰🇷 [ko](../ko/MCP-SERVER.md) · 🇸🇦 [ar](../ar/MCP-SERVER.md) · 🇮🇳 [in](../in/MCP-SERVER.md) · 🇹🇭 [th](../th/MCP-SERVER.md) · 🇻🇳 [vi](../vi/MCP-SERVER.md) · 🇮🇩 [id](../id/MCP-SERVER.md) · 🇲🇾 [ms](../ms/MCP-SERVER.md) · 🇳🇱 [nl](../nl/MCP-SERVER.md) · 🇵🇱 [pl](../pl/MCP-SERVER.md) · 🇸🇪 [sv](../sv/MCP-SERVER.md) · 🇳🇴 [no](../no/MCP-SERVER.md) · 🇩🇰 [da](../da/MCP-SERVER.md) · 🇫🇮 [fi](../fi/MCP-SERVER.md) · 🇵🇹 [pt](../pt/MCP-SERVER.md) · 🇷🇴 [ro](../ro/MCP-SERVER.md) · 🇭🇺 [hu](../hu/MCP-SERVER.md) · 🇧🇬 [bg](../bg/MCP-SERVER.md) · 🇸🇰 [sk](../sk/MCP-SERVER.md) · 🇺🇦 [uk-UA](../uk-UA/MCP-SERVER.md) · 🇮🇱 [he](../he/MCP-SERVER.md) · 🇵🇭 [phi](../phi/MCP-SERVER.md) +🌐 **语言:** 🇺🇸 [English](../../MCP-SERVER.md) · 🇧🇷 [pt-BR](../pt-BR/MCP-SERVER.md) · 🇪🇸 [es](../es/MCP-SERVER.md) · 🇫🇷 [fr](../fr/MCP-SERVER.md) · 🇩🇪 [de](../de/MCP-SERVER.md) · 🇮🇹 [it](../it/MCP-SERVER.md) · 🇷🇺 [ru](../ru/MCP-SERVER.md) · 🇨🇳 [zh-CN](../zh-CN/MCP-SERVER.md) · 🇯🇵 [ja](../ja/MCP-SERVER.md) · 🇰🇷 [ko](../ko/MCP-SERVER.md) · 🇸🇦 [ar](../ar/MCP-SERVER.md) · 🇮🇳 [in](../in/MCP-SERVER.md) · 🇹🇭 [th](../th/MCP-SERVER.md) · 🇻🇳 [vi](../vi/MCP-SERVER.md) · 🇮🇩 [id](../id/MCP-SERVER.md) · 🇲🇾 [ms](../ms/MCP-SERVER.md) · 🇳🇱 [nl](../nl/MCP-SERVER.md) · 🇵🇱 [pl](../pl/MCP-SERVER.md) · 🇸🇪 [sv](../sv/MCP-SERVER.md) · 🇳🇴 [no](../no/MCP-SERVER.md) · 🇩🇰 [da](../da/MCP-SERVER.md) · 🇫🇮 [fi](../fi/MCP-SERVER.md) · 🇵🇹 [pt](../pt/MCP-SERVER.md) · 🇷🇴 [ro](../ro/MCP-SERVER.md) · 🇭🇺 [hu](../hu/MCP-SERVER.md) · 🇧🇬 [bg](../bg/MCP-SERVER.md) · 🇸🇰 [sk](../sk/MCP-SERVER.md) · 🇺🇦 [uk-UA](../uk-UA/MCP-SERVER.md) · 🇮🇱 [he](../he/MCP-SERVER.md) · 🇵🇭 [phi](../phi/MCP-SERVER.md) --- -# OmniRoute MCP Server Documentation +# OmniRoute MCP 服务器文档 -> Model Context Protocol server with 16 intelligent tools +> Model Context Protocol 服务器,包含 16 个智能工具 -## Installation +## 安装 -OmniRoute MCP is built-in. Start it with: +OmniRoute MCP 已内置。使用以下命令启动: ```bash omniroute --mcp ``` -Or via the open-sse transport: +或通过 open-sse 传输方式: ```bash -# HTTP streamable transport (port 20130) -omniroute --dev # MCP auto-starts on /mcp endpoint +# HTTP 可流式传输 (端口 20130) +omniroute --dev # MCP 在 /mcp 端点自动启动 ``` -## IDE Configuration +## IDE 配置 -See [IDE Configs](integrations/ide-configs.md) for Antigravity, Cursor, Copilot, and Claude Desktop setup. +请参阅 [IDE Configs](integrations/ide-configs.md) 了解 Antigravity、Cursor、Copilot 和 Claude Desktop 的设置方法。 --- -## Essential Tools (8) +## 基础工具 (8 个) -| Tool | Description | -| :------------------------------ | :--------------------------------------- | -| `omniroute_get_health` | Gateway health, circuit breakers, uptime | -| `omniroute_list_combos` | All configured combos with models | -| `omniroute_get_combo_metrics` | Performance metrics for a specific combo | -| `omniroute_switch_combo` | Switch active combo by ID/name | -| `omniroute_check_quota` | Quota status per provider or all | -| `omniroute_route_request` | Send a chat completion through OmniRoute | -| `omniroute_cost_report` | Cost analytics for a time period | -| `omniroute_list_models_catalog` | Full model catalog with capabilities | +| 工具 | 描述 | +| :------------------------------ | :-------------------------------- | +| `omniroute_get_health` | 网关健康状态、熔断器、运行时间 | +| `omniroute_list_combos` | 所有已配置的组合及其模型 | +| `omniroute_get_combo_metrics` | 特定组合的性能指标 | +| `omniroute_switch_combo` | 通过 ID/名称切换活动组合 | +| `omniroute_check_quota` | 按服务商或全部查询配额状态 | +| `omniroute_route_request` | 通过 OmniRoute 发送聊天完成请求 | +| `omniroute_cost_report` | 指定时间段的成本分析 | +| `omniroute_list_models_catalog` | 完整模型目录及能力说明 | -## Advanced Tools (8) +## 高级工具 (8 个) -| Tool | Description | -| :--------------------------------- | :---------------------------------------------- | -| `omniroute_simulate_route` | Dry-run routing simulation with fallback tree | -| `omniroute_set_budget_guard` | Session budget with degrade/block/alert actions | -| `omniroute_set_resilience_profile` | Apply conservative/balanced/aggressive preset | -| `omniroute_test_combo` | Live-test all models in a combo | -| `omniroute_get_provider_metrics` | Detailed metrics for one provider | -| `omniroute_best_combo_for_task` | Task-fitness recommendation with alternatives | -| `omniroute_explain_route` | Explain a past routing decision | -| `omniroute_get_session_snapshot` | Full session state: costs, tokens, errors | +| 工具 | 描述 | +| :--------------------------------- | :------------------------------------ | +| `omniroute_simulate_route` | 带有回退树的路由模拟(空跑) | +| `omniroute_set_budget_guard` | 会话预算及降级/阻止/告警操作 | +| `omniroute_set_resilience_profile` | 应用保守/平衡/激进预设 | +| `omniroute_test_combo` | 实时测试组合中的所有模型 | +| `omniroute_get_provider_metrics` | 单个服务商的详细指标 | +| `omniroute_best_combo_for_task` | 任务适配推荐及替代方案 | +| `omniroute_explain_route` | 解释历史路由决策 | +| `omniroute_get_session_snapshot` | 完整会话状态:成本、token、错误 | -## Authentication +## 身份验证 -MCP tools are authenticated via API key scopes. Each tool requires specific scopes: +MCP 工具通过 API 密钥作用域进行身份验证。每个工具需要特定的作用域: -| Scope | Tools | +| 作用域 | 工具 | | :------------- | :----------------------------------------------- | | `read:health` | get_health, get_provider_metrics | | `read:combos` | list_combos, get_combo_metrics | @@ -68,20 +68,20 @@ MCP tools are authenticated via API key scopes. Each tool requires specific scop | `write:config` | set_budget_guard, set_resilience_profile | | `read:models` | list_models_catalog, best_combo_for_task | -## Audit Logging +## 审计日志 -Every tool call is logged to `mcp_tool_audit` with: +每个工具调用都会记录到 `mcp_tool_audit`,包含: -- Tool name, arguments, result -- Duration (ms), success/failure -- API key hash, timestamp +- 工具名称、参数、结果 +- 耗时(毫秒)、成功/失败状态 +- API 密钥哈希值、时间戳 -## Files +## 文件 -| File | Purpose | -| :------------------------------------------- | :------------------------------------------ | -| `open-sse/mcp-server/server.ts` | MCP server creation + 16 tool registrations | -| `open-sse/mcp-server/transport.ts` | Stdio + HTTP transport | -| `open-sse/mcp-server/auth.ts` | API key + scope validation | -| `open-sse/mcp-server/audit.ts` | Tool call audit logging | -| `open-sse/mcp-server/tools/advancedTools.ts` | 8 advanced tool handlers | +| 文件 | 用途 | +| :------------------------------------------- | :-------------------------------- | +| `open-sse/mcp-server/server.ts` | MCP 服务器创建 + 16 个工具注册 | +| `open-sse/mcp-server/transport.ts` | Stdio + HTTP 传输 | +| `open-sse/mcp-server/auth.ts` | API 密钥 + 作用域验证 | +| `open-sse/mcp-server/audit.ts` | 工具调用审计日志 | +| `open-sse/mcp-server/tools/advancedTools.ts` | 8 个高级工具处理器 | diff --git a/docs/i18n/zh-CN/README.md b/docs/i18n/zh-CN/README.md index b4dc36dd..23084d87 100644 --- a/docs/i18n/zh-CN/README.md +++ b/docs/i18n/zh-CN/README.md @@ -1,14 +1,14 @@ -# 🚀 OmniRoute — The Free AI Gateway (中文(简体)) +# 🚀 OmniRoute — 免费 AI 网关 -🌐 **Languages:** 🇺🇸 [English](../../../README.md) · 🇪🇸 [es](../es/README.md) · 🇫🇷 [fr](../fr/README.md) · 🇩🇪 [de](../de/README.md) · 🇮🇹 [it](../it/README.md) · 🇷🇺 [ru](../ru/README.md) · 🇨🇳 [zh-CN](../zh-CN/README.md) · 🇯🇵 [ja](../ja/README.md) · 🇰🇷 [ko](../ko/README.md) · 🇸🇦 [ar](../ar/README.md) · 🇮🇳 [in](../in/README.md) · 🇹🇭 [th](../th/README.md) · 🇻🇳 [vi](../vi/README.md) · 🇮🇩 [id](../id/README.md) · 🇲🇾 [ms](../ms/README.md) · 🇳🇱 [nl](../nl/README.md) · 🇵🇱 [pl](../pl/README.md) · 🇸🇪 [sv](../sv/README.md) · 🇳🇴 [no](../no/README.md) · 🇩🇰 [da](../da/README.md) · 🇫🇮 [fi](../fi/README.md) · 🇵🇹 [pt](../pt/README.md) · 🇷🇴 [ro](../ro/README.md) · 🇭🇺 [hu](../hu/README.md) · 🇧🇬 [bg](../bg/README.md) · 🇸🇰 [sk](../sk/README.md) · 🇺🇦 [uk-UA](../uk-UA/README.md) · 🇮🇱 [he](../he/README.md) · 🇵🇭 [phi](../phi/README.md) · 🇧🇷 [pt-BR](../pt-BR/README.md) +🌐 **语言:** 🇺🇸 [English](../../../README.md) · 🇪🇸 [es](../es/README.md) · 🇫🇷 [fr](../fr/README.md) · 🇩🇪 [de](../de/README.md) · 🇮🇹 [it](../it/README.md) · 🇷🇺 [ru](../ru/README.md) · 🇨🇳 [zh-CN](../zh-CN/README.md) · 🇯🇵 [ja](../ja/README.md) · 🇰🇷 [ko](../ko/README.md) · 🇸🇦 [ar](../ar/README.md) · 🇮🇳 [in](../in/README.md) · 🇹🇭 [th](../th/README.md) · 🇻🇳 [vi](../vi/README.md) · 🇮🇩 [id](../id/README.md) · 🇲🇾 [ms](../ms/README.md) · 🇳🇱 [nl](../nl/README.md) · 🇵🇱 [pl](../pl/README.md) · 🇸🇪 [sv](../sv/README.md) · 🇳🇴 [no](../no/README.md) · 🇩🇰 [da](../da/README.md) · 🇫🇮 [fi](../fi/README.md) · 🇵🇹 [pt](../pt/README.md) · 🇷🇴 [ro](../ro/README.md) · 🇭🇺 [hu](../hu/README.md) · 🇧🇬 [bg](../bg/README.md) · 🇸🇰 [sk](../sk/README.md) · 🇺🇦 [uk-UA](../uk-UA/README.md) · 🇮🇱 [he](../he/README.md) · 🇵🇭 [phi](../phi/README.md) · 🇧🇷 [pt-BR](../pt-BR/README.md) --- -### Never stop coding. Smart routing to **FREE & low-cost AI models** with automatic fallback. +### 永不停止编码。智能路由到**免费和低成本 AI 模型**,自动后备。 -_Your universal API proxy — one endpoint, 67+ providers, zero downtime. Now with **MCP & A2A** agent orchestration._ +_您的通用 API 代理 — 一个端点,67+ 个提供商,零停机。现已支持 **MCP 和 A2A** 智能体编排。_ -**Chat Completions • Embeddings • Image Generation • Video • Music • Audio • Reranking • **Web Search** • MCP Server • A2A Protocol • 100% TypeScript** +**聊天完成 • Embedding • 图像生成 • 视频 • 音乐 • 音频 • 重排序 • **Web 搜索** • MCP Server • A2A 协议 • 100% TypeScript** --- @@ -22,102 +22,126 @@ _Your universal API proxy — one endpoint, 67+ providers, zero downtime. Now wi [![Website](https://img.shields.io/badge/Website-omniroute.online-blue?logo=google-chrome&logoColor=white)](https://omniroute.online) [![WhatsApp](https://img.shields.io/badge/WhatsApp-Community-25D366?logo=whatsapp&logoColor=white)](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) -[🌐 Website](https://omniroute.online) • [🚀 Quick Start](#-quick-start) • [💡 Features](#-key-features) • [📖 Docs](#-documentation) • [💰 Pricing](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) +[🌐 网站](https://omniroute.online) • [🚀 快速开始](#-快速开始) • [💡 功能](#-主要功能) • [📖 文档](#-文档) • [💰 定价](#-定价一览) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) -🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](docs/i18n/pt-BR/README.md) | 🇪🇸 [Español](docs/i18n/es/README.md) | 🇫🇷 [Français](docs/i18n/fr/README.md) | 🇮🇹 [Italiano](docs/i18n/it/README.md) | 🇷🇺 [Русский](docs/i18n/ru/README.md) | 🇨🇳 [中文 (简体)](docs/i18n/zh-CN/README.md) | 🇩🇪 [Deutsch](docs/i18n/de/README.md) | 🇮🇳 [हिन्दी](docs/i18n/in/README.md) | 🇹🇭 [ไทย](docs/i18n/th/README.md) | 🇺🇦 [Українська](docs/i18n/uk-UA/README.md) | 🇸🇦 [العربية](docs/i18n/ar/README.md) | 🇯🇵 [日本語](docs/i18n/ja/README.md) | 🇻🇳 [Tiếng Việt](docs/i18n/vi/README.md) | 🇧🇬 [Български](docs/i18n/bg/README.md) | 🇩🇰 [Dansk](docs/i18n/da/README.md) | 🇫🇮 [Suomi](docs/i18n/fi/README.md) | 🇮🇱 [עברית](docs/i18n/he/README.md) | 🇭🇺 [Magyar](docs/i18n/hu/README.md) | 🇮🇩 [Bahasa Indonesia](docs/i18n/id/README.md) | 🇰🇷 [한국어](docs/i18n/ko/README.md) | 🇲🇾 [Bahasa Melayu](docs/i18n/ms/README.md) | 🇳🇱 [Nederlands](docs/i18n/nl/README.md) | 🇳🇴 [Norsk](docs/i18n/no/README.md) | 🇵🇹 [Português (Portugal)](docs/i18n/pt/README.md) | 🇷🇴 [Română](docs/i18n/ro/README.md) | 🇵🇱 [Polski](docs/i18n/pl/README.md) | 🇸🇰 [Slovenčina](docs/i18n/sk/README.md) | 🇸🇪 [Svenska](docs/i18n/sv/README.md) | 🇵🇭 [Filipino](docs/i18n/phi/README.md) | 🇨🇿 [Čeština](docs/i18n/cs/README.md) +🌐 **可用语言:** 🇺🇸 [English](../../../README.md) | 🇧🇷 [Português (Brasil)](../pt-BR/README.md) | 🇪🇸 [Español](../es/README.md) | 🇫🇷 [Français](../fr/README.md) | 🇮🇹 [Italiano](../it/README.md) | 🇷🇺 [Русский](../ru/README.md) | 🇨🇳 [中文 (简体)](../zh-CN/README.md) | 🇩🇪 [Deutsch](../de/README.md) | 🇮🇳 [हिन्दी](../in/README.md) | 🇹🇭 [ไทย](../th/README.md) | 🇺🇦 [Українська](../uk-UA/README.md) | 🇸🇦 [العربية](../ar/README.md) | 🇯🇵 [日本語](../ja/README.md) | 🇻🇳 [Tiếng Việt](../vi/README.md) | 🇧🇬 [Български](../bg/README.md) | 🇩🇰 [Dansk](../da/README.md) | 🇫🇮 [Suomi](../fi/README.md) | 🇮🇱 [עברית](../he/README.md) | 🇭🇺 [Magyar](../hu/README.md) | 🇮🇩 [Bahasa Indonesia](../id/README.md) | 🇰🇷 [한국어](../ko/README.md) | 🇲🇾 [Bahasa Melayu](../ms/README.md) | 🇳🇱 [Nederlands](../nl/README.md) | 🇳🇴 [Norsk](../no/README.md) | 🇵🇹 [Português (Portugal)](../pt/README.md) | 🇷🇴 [Română](../ro/README.md) | 🇵🇱 [Polski](../pl/README.md) | 🇸🇰 [Slovenčina](../sk/README.md) | 🇸🇪 [Svenska](../sv/README.md) | 🇵🇭 [Filipino](../phi/README.md) | 🇨🇿 [Čeština](../cs/README.md) --- -## 🆕 What's New in v3.0.0 +## 破坏性变更:统一日志升级 -> **Upgrading from v2.9.5?** — See the [full CHANGELOG](CHANGELOG.md#300--2026-03-22-release-candidate--not-yet-merged-to-main) for all changes. - -| Area | Change | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection remediation | -| ✅ **Route Validation** | All 176 API routes now validated with Zod schemas + `validateBody()` — CI `check:route-validation:t06` passes | -| 🐛 **omniModel Tag Leak** | Internal `` tags no longer leak to clients in SSE streaming responses (#585) | -| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with per-provider/account quota enforcement, idempotency, SHA-256 storage, and optional GitHub issue reporting | -| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG → generic fallback chain | -| 🔄 **Model Auto-Sync** | 24h scheduler and manual UI toggle to sync model lists for built-in and custom OpenAI-compatible providers | -| 🌐 **OpenCode Zen/Go** | Two new providers from @kang-heewon via PR #530: free tier + subscription tier via `OpencodeExecutor` | -| 🐛 **Gemini CLI OAuth** | Actionable error when `GEMINI_OAUTH_CLIENT_SECRET` is missing in Docker (was cryptic Google error) | -| 🐛 **OpenCode config** | `saveOpenCodeConfig()` now correctly writes TOML to `XDG_CONFIG_HOME` | -| 🐛 **Pinned model override** | `body.model` correctly set to `pinnedModel` on context-cache protection | -| 🐛 **Codex/Claude loop** | `tool_result` blocks now converted to text to stop infinite loops | -| 🐛 **Login redirect** | Login no longer freezes after skipping password setup | -| 🐛 **Windows paths** | MSYS2/Git-Bash paths (`/c/...`) normalized to `C:\...` automatically | +> [!WARNING] +> **此版本重新设计了磁盘上的请求日志布局以及日志相关环境变量。** +> +> 如果你正在升级现有实例: +> +> - 请求日志现在位于 `DATA_DIR/call_logs/YYYY-MM-DD/`,并以**每个请求一个 JSON artifact** 的形式存储。 +> - 旧的 `DATA_DIR/logs/` 会话目录和 `DATA_DIR/log.txt` 汇总文件已被移除。 +> - 升级后的首次启动时,OmniRoute 会先在 `DATA_DIR/log_archives/*.zip` 中创建安全备份,再删除旧日志布局。 +> - 旧版日志环境变量如 `LOG_TO_FILE`、`LOG_FILE_PATH`、`LOG_MAX_FILE_SIZE`、`LOG_RETENTION_DAYS`、`LOG_LEVEL`、`LOG_FORMAT`、`ENABLE_REQUEST_LOGS`、`CALL_LOGS_MAX`、`CALL_LOG_PAYLOAD_MODE` 和 `PROXY_LOG_MAX_ENTRIES` 已不再支持。 +> - 请改用新的环境变量模型: +> - `APP_LOG_TO_FILE` +> - `APP_LOG_FILE_PATH` +> - `APP_LOG_MAX_FILE_SIZE` +> - `APP_LOG_RETENTION_DAYS` +> - `APP_LOG_LEVEL` +> - `APP_LOG_FORMAT` +> - `CALL_LOG_RETENTION_DAYS` +> +> 详细发布信息和升级说明请参阅 [CHANGELOG](../../../CHANGELOG.md)。 --- -## 🖼️ Main Dashboard +## 🆕 v3.0.0 新功能 + +> **从 v2.9.5 升级?** — 查看[完整更新日志](../../../CHANGELOG.md#300--2026-03-22-release-candidate--not-yet-merged-to-main)了解所有更改。 + +| 领域 | 更改 | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| 🔒 **CodeQL 安全** | 修复了 10+ 个 CodeQL 警报:polynomial-redos、insecure-randomness、shell-injection 修复 | +| ✅ **路由验证** | 所有 176 个 API 路由现已使用 Zod 模式 + `validateBody()` 验证 — CI `check:route-validation:t06` 通过 | +| 🐛 **omniModel 标签泄露** | 内部 `` 标签不再泄露到 SSE 流式响应中的客户端 (#585) | +| 🔑 **注册密钥 API** | 通过 `POST /api/v1/registered-keys` 自动配置 API 密钥,支持每提供商/账户配额执行、幂等性、SHA-256 存储和可选 GitHub issue 报告 | +| 🎨 **提供商图标** | 通过 `@lobehub/icons` (SVG) 提供 130+ 个提供商 Logo,带 PNG → 通用后备链 | +| 🔄 **模型自动同步** | 24 小时调度器和手动 UI 切换,用于同步内置和自定义 OpenAI 兼容提供商的模型列表 | +| 🌐 **OpenCode Zen/Go** | 来自 @kang-heewon 通过 PR #530 的两个新提供商:免费层 + 订阅层,通过 `OpencodeExecutor` | +| 🐛 **Gemini CLI OAuth** | Docker 中缺少 `GEMINI_OAUTH_CLIENT_SECRET` 时的可操作错误(之前是晦涩的 Google 错误) | +| 🐛 **OpenCode 配置** | `saveOpenCodeConfig()` 现在正确写入 TOML 到 `XDG_CONFIG_HOME` | +| 🐛 **固定模型覆盖** | `body.model` 在上下文缓存保护时正确设置为 `pinnedModel` | +| 🐛 **Codex/Claude 循环** | `tool_result` 块现在转换为文本以停止无限循环 | +| 🐛 **登录重定向** | 跳过密码设置后登录不再冻结 | +| 🐛 **Windows 路径** | MSYS2/Git-Bash 路径 (`/c/...`) 自动规范化为 `C:\...` | + +--- + +## 🖼️ 主仪表盘
- OmniRoute Dashboard + OmniRoute 仪表盘
--- -## 📸 Dashboard Preview +## 📸 仪表盘预览
-Click to see dashboard screenshots +点击查看仪表盘截图 -| Page | Screenshot | -| -------------- | ------------------------------------------------- | -| **Providers** | ![Providers](docs/screenshots/01-providers.png) | -| **Combos** | ![Combos](docs/screenshots/02-combos.png) | -| **Analytics** | ![Analytics](docs/screenshots/03-analytics.png) | -| **Health** | ![Health](docs/screenshots/04-health.png) | -| **Translator** | ![Translator](docs/screenshots/05-translator.png) | -| **Settings** | ![Settings](docs/screenshots/06-settings.png) | -| **CLI Tools** | ![CLI Tools](docs/screenshots/07-cli-tools.png) | -| **Usage Logs** | ![Usage](docs/screenshots/08-usage.png) | -| **Endpoints** | ![Endpoints](docs/screenshots/09-endpoint.png) | +| 页面 | 截图 | +| ------------ | ------------------------------------------------------- | +| **提供商** | ![提供商](../../../docs/screenshots/01-providers.png) | +| **Combo** | ![Combo](../../../docs/screenshots/02-combos.png) | +| **分析** | ![分析](../../../docs/screenshots/03-analytics.png) | +| **健康** | ![健康](../../../docs/screenshots/04-health.png) | +| **翻译器** | ![翻译器](../../../docs/screenshots/05-translator.png) | +| **设置** | ![设置](../../../docs/screenshots/06-settings.png) | +| **CLI 工具** | ![CLI 工具](../../../docs/screenshots/07-cli-tools.png) | +| **使用日志** | ![使用](../../../docs/screenshots/08-usage.png) | +| **端点** | ![端点](../../../docs/screenshots/09-endpoint.png) |
--- -### 🤖 Free AI Provider for your favorite coding agents +### 🤖 为您喜爱的编码智能体提供免费 AI 提供商 -_Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway for unlimited coding._ +_通过 OmniRoute 连接任何 AI 驱动的 IDE 或 CLI 工具 — 无限编码的免费 API 网关。_
- OpenClaw
+ OpenClaw
OpenClaw

⭐ 205K
- NanoBot
+ NanoBot
NanoBot

⭐ 20.9K
- PicoClaw
+ PicoClaw
PicoClaw

⭐ 14.6K
- ZeroClaw
+ ZeroClaw
ZeroClaw

⭐ 9.9K
- IronClaw
+ IronClaw
IronClaw

⭐ 2.1K @@ -126,35 +150,35 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
- OpenCode
+ OpenCode
OpenCode

⭐ 106K
- Codex CLI
+ Codex CLI
Codex CLI

⭐ 60.8K
- Claude Code
+ Claude Code
Claude Code

⭐ 67.3K
- Gemini CLI
+ Gemini CLI
Gemini CLI

⭐ 94.7K
- Kilo Code
+ Kilo Code
Kilo Code

⭐ 15.5K @@ -162,527 +186,527 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
-📡 All agents connect via http://localhost:20128/v1 or http://cloud.omniroute.online/v1 — one config, unlimited models and quota +📡 所有智能体通过 http://localhost:20128/v1http://cloud.omniroute.online/v1 连接 — 一个配置,无限模型和配额 --- -## 🤔 Why OmniRoute? +## 🤔 为什么选择 OmniRoute? -**Stop wasting money and hitting limits:** +**停止浪费金钱和碰到限制:** -- Subscription quota expires unused every month -- Rate limits stop you mid-coding -- Expensive APIs ($20-50/month per provider) -- Manual switching between providers +- 订阅配额每月未使用就过期 +- 速率限制让你在编码中途停止 +- 昂贵的 API(每个提供商 $20-50/月) +- 手动在提供商之间切换 -**OmniRoute solves this:** +**OmniRoute 解决这些问题:** -- ✅ **Maximize subscriptions** - Track quota, use every bit before reset -- ✅ **Auto fallback** - Subscription → API Key → Cheap → Free, zero downtime -- ✅ **Multi-account** - Round-robin between accounts per provider -- ✅ **Universal** - Works with Claude Code, Codex, Gemini CLI, Cursor, Cline, OpenClaw, any CLI tool +- ✅ **最大化订阅** - 追踪配额,在重置前用完每一点 +- ✅ **自动后备** - 订阅 → API 密钥 → 便宜 → 免费,零停机 +- ✅ **多账户** - 每个提供商多账户轮询 +- ✅ **通用** - 适用于 Claude Code、Codex、Gemini CLI、Cursor、Cline、OpenClaw、任何 CLI 工具 --- -## 📧 Support +## 📧 支持 -> 💬 **Join our community!** [WhatsApp Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Get help, share tips, and stay updated. +> 💬 **加入我们的社区!** [WhatsApp 群组](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — 获取帮助、分享技巧并保持更新。 -- **Website**: [omniroute.online](https://omniroute.online) -- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute) -- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -- **WhatsApp**: [Community Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) -- **Contributing**: See [CONTRIBUTING.md](CONTRIBUTING.md), open a PR, or pick a `good first issue` -- **Original Project**: [9router by decolua](https://github.com/decolua/9router) +- **网站**:[omniroute.online](https://omniroute.online) +- **GitHub**:[github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute) +- **Issues**:[github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) +- **WhatsApp**:[社区群组](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) +- **贡献**:查看 [CONTRIBUTING.md](../../../CONTRIBUTING.md),开启 PR,或选择一个 `good first issue` +- **原始项目**:[9router by decolua](https://github.com/decolua/9router) -### 🐛 Reporting a Bug? +### 🐛 报告 Bug? -When opening an issue, please run the system-info command and attach the generated file: +开启 issue 时,请运行系统信息命令并附上生成的文件: ```bash npm run system-info ``` -This generates a `system-info.txt` with your Node.js version, OmniRoute version, OS details, installed CLI tools (iflow, gemini, claude, codex, antigravity, droid, etc.), Docker/PM2 status, and system packages — everything we need to reproduce your issue quickly. Attach the file directly to your GitHub issue. +这会生成一个 `system-info.txt`,包含你的 Node.js 版本、OmniRoute 版本、操作系统详情、已安装的 CLI 工具(iflow、gemini、claude、codex、antigravity、droid 等)、Docker/PM2 状态和系统包 — 我们快速重现问题所需的一切。直接将文件附加到你的 GitHub issue。 --- -## 🔄 How It Works +## 🔄 工作原理 ``` ┌─────────────┐ -│ Your CLI │ (Claude Code, Codex, Gemini CLI, OpenClaw, Cursor, Cline...) -│ Tool │ +│ 你的 CLI │ (Claude Code, Codex, Gemini CLI, OpenClaw, Cursor, Cline...) +│ 工具 │ └──────┬──────┘ │ http://localhost:20128/v1 ↓ ┌─────────────────────────────────────────┐ -│ OmniRoute (Smart Router) │ -│ • Format translation (OpenAI ↔ Claude) │ -│ • Quota tracking + Embeddings + Images │ -│ • Auto token refresh │ +│ OmniRoute(智能路由器) │ +│ • 格式翻译(OpenAI ↔ Claude) │ +│ • 配额追踪 + Embedding + 图像 │ +│ • 自动 Token 刷新 │ └──────┬──────────────────────────────────┘ │ - ├─→ [Tier 1: SUBSCRIPTION] Claude Code, Codex, Gemini CLI - │ ↓ quota exhausted - ├─→ [Tier 2: API KEY] DeepSeek, Groq, xAI, Mistral, NVIDIA NIM, etc. - │ ↓ budget limit - ├─→ [Tier 3: CHEAP] GLM ($0.6/1M), MiniMax ($0.2/1M) - │ ↓ budget limit - └─→ [Tier 4: FREE] iFlow, Qwen, Kiro (unlimited) + ├─→ [层级 1:订阅] Claude Code, Codex, Gemini CLI + │ ↓ 配额耗尽 + ├─→ [层级 2:API 密钥] DeepSeek, Groq, xAI, Mistral, NVIDIA NIM 等 + │ ↓ 预算限制 + ├─→ [层级 3:便宜] GLM ($0.6/1M), MiniMax ($0.2/1M) + │ ↓ 预算限制 + └─→ [层级 4:免费] Qoder、Qwen、Kiro(无限) -Result: Never stop coding, minimal cost +结果:永不停止编码,最小成本 ``` --- -## 🎯 What OmniRoute Solves — 30 Real Pain Points & Use Cases +## 🎯 OmniRoute 解决的问题 — 30 个真实痛点和用例 -> **Every developer using AI tools faces these problems daily.** OmniRoute was built to solve them all — from cost overruns to regional blocks, from broken OAuth flows to protocol operations and enterprise observability. +> **每个使用 AI 工具的开发者每天都面临这些问题。** OmniRoute 旨在解决所有问题 — 从成本超支到区域封锁,从损坏的 OAuth 流程到协议操作和企业可观测性。
-💸 1. "I pay for an expensive subscription but still get interrupted by limits" +💸 1. "我为昂贵的订阅付费,但仍然被限制打断" -Developers pay $20–200/month for Claude Pro, Codex Pro, or GitHub Copilot. Even paying, quota has a ceiling — 5h of usage, weekly limits, or per-minute rate limits. Mid-coding session, the provider stops responding and the developer loses flow and productivity. +开发者每月为 Claude Pro、Codex Pro 或 GitHub Copilot 支付 $20–200。即使付费,配额也有上限 — 5 小时使用、每周限制或每分钟速率限制。在编码会话中途,提供商停止响应,开发者失去心流和生产力。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Smart 4-Tier Fallback** — If subscription quota runs out, automatically redirects to API Key → Cheap → Free with zero manual intervention -- **Real-Time Quota Tracking** — Shows token consumption in real-time with reset countdown (5h, daily, weekly) -- **Multi-Account Support** — Multiple accounts per provider with auto round-robin — when one runs out, switches to the next -- **Custom Combos** — Customizable fallback chains with 6 balancing strategies (fill-first, round-robin, P2C, random, least-used, cost-optimized) -- **Codex Business Quotas** — Business/Team workspace quota monitoring directly in the dashboard +- **智能 4 层后备** — 如果订阅配额用完,自动重定向到 API 密钥 → 便宜 → 免费,零手动干预 +- **实时配额追踪** — 显示实时 Token 消耗和重置倒计时(5h、每日、每周) +- **多账户支持** — 每个提供商多账户自动轮询 — 当一个用完时,切换到下一个 +- **自定义 Combo** — 可自定义的后备链,6 种平衡策略(填充优先、轮询、P2C、随机、最少使用、成本优化) +- **Codex 商业配额** — 直接在仪表盘中监控商业/团队工作区配额
-🔌 2. "I need to use multiple providers but each has a different API" +🔌 2. "我需要使用多个提供商,但每个都有不同的 API" -OpenAI uses one format, Claude (Anthropic) uses another, Gemini yet another. If a dev wants to test models from different providers or fallback between them, they need to reconfigure SDKs, change endpoints, deal with incompatible formats. Custom providers (FriendLI, NIM) have non-standard model endpoints. +OpenAI 使用一种格式,Claude(Anthropic)使用另一种,Gemini 又是另一种。如果开发者想测试来自不同提供商的模型或在它们之间后备,他们需要重新配置 SDK、更改端点、处理不兼容的格式。自定义提供商(FriendLI、NIM)有非标准的模型端点。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Unified Endpoint** — A single `http://localhost:20128/v1` serves as proxy for all 67+ providers -- **Format Translation** — Automatic and transparent: OpenAI ↔ Claude ↔ Gemini ↔ Responses API -- **Response Sanitization** — Strips non-standard fields (`x_groq`, `usage_breakdown`, `service_tier`) that break OpenAI SDK v1.83+ -- **Role Normalization** — Converts `developer` → `system` for non-OpenAI providers; `system` → `user` for GLM/ERNIE -- **Think Tag Extraction** — Extracts `` blocks from models like DeepSeek R1 into standardized `reasoning_content` -- **Structured Output for Gemini** — `json_schema` → `responseMimeType`/`responseSchema` automatic conversion -- **`stream` defaults to `false`** — Aligns with OpenAI spec, avoiding unexpected SSE in Python/Rust/Go SDKs +- **统一端点** — 单个 `http://localhost:20128/v1` 作为所有 67+ 个提供商的代理 +- **格式翻译** — 自动且透明:OpenAI ↔ Claude ↔ Gemini ↔ Responses API +- **响应清理** — 剥离破坏 OpenAI SDK v1.83+ 的非标准字段(`x_groq`、`usage_breakdown`、`service_tier`) +- **角色规范化** — 为非 OpenAI 提供商转换 `developer` → `system`;为 GLM/ERNIE 转换 `system` → `user` +- **Think 标签提取** — 从 DeepSeek R1 等模型中提取 `` 块到标准化的 `reasoning_content` +- **Gemini 结构化输出** — `json_schema` → `responseMimeType`/`responseSchema` 自动转换 +- **`stream` 默认为 `false`** — 与 OpenAI 规范对齐,避免 Python/Rust/Go SDK 中意外的 SSE
-🌐 3. "My AI provider blocks my region/country" +🌐 3. "我的 AI 提供商封锁了我的地区/国家" -Providers like OpenAI/Codex block access from certain geographic regions. Users get errors like `unsupported_country_region_territory` during OAuth and API connections. This is especially frustrating for developers from developing countries. +OpenAI/Codex 等提供商封锁来自某些地理区域的访问。用户在 OAuth 和 API 连接期间收到 `unsupported_country_region_territory` 等错误。这对来自发展中国家的开发者尤其令人沮丧。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **3-Level Proxy Config** — Configurable proxy at 3 levels: global (all traffic), per-provider (one provider only), and per-connection/key -- **Color-Coded Proxy Badges** — Visual indicators: 🟢 global proxy, 🟡 provider proxy, 🔵 connection proxy, always showing the IP -- **OAuth Token Exchange Through Proxy** — OAuth flow also goes through the proxy, solving `unsupported_country_region_territory` -- **Connection Tests via Proxy** — Connection tests use the configured proxy (no more direct bypass) -- **SOCKS5 Support** — Full SOCKS5 proxy support for outbound routing -- **TLS Fingerprint Spoofing** — Browser-like TLS fingerprint via `wreq-js` to bypass bot detection -- **🔏 CLI Fingerprint Matching** — Reorders headers and body fields to match native CLI binary signatures, drastically reducing account flagging risk. The proxy IP is preserved — you get both stealth **and** IP masking simultaneously +- **3 级代理配置** — 3 个级别的可配置代理:全局(所有流量)、每提供商(仅一个提供商)和每连接/密钥 +- **颜色编码代理徽章** — 可视化指示器:🟢 全局代理、🟡 提供商代理、🔵 连接代理,始终显示 IP +- **通过代理的 OAuth Token 交换** — OAuth 流程也通过代理,解决 `unsupported_country_region_territory` +- **通过代理的连接测试** — 连接测试使用配置的代理(不再直接绕过) +- **SOCKS5 支持** — 完整的 SOCKS5 代理支持用于出站路由 +- **TLS 指纹伪装** — 通过 `wreq-js` 实现类浏览器 TLS 指纹以绕过机器人检测 +- **🔏 CLI 指纹匹配** — 重新排序请求头和请求体字段以匹配原生 CLI 二进制签名,大幅降低账户标记风险。代理 IP 被保留 — 你同时获得隐身**和** IP 掩蔽
-🆓 4. "I want to use AI for coding but I have no money" +🆓 4. "我想使用 AI 编码但没钱" -Not everyone can pay $20–200/month for AI subscriptions. Students, devs from emerging countries, hobbyists, and freelancers need access to quality models at zero cost. +并非每个人都能每月支付 $20–200 的 AI 订阅费用。学生、来自新兴国家的开发者、业余爱好者和自由职业者需要以零成本访问优质模型。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Free Tier Providers Built-in** — Native support for 100% free providers: iFlow (5 unlimited models via OAuth: kimi-k2-thinking, qwen3-coder-plus, deepseek-r1, minimax-m2, kimi-k2), Qwen (4 unlimited models: qwen3-coder-plus, qwen3-coder-flash, qwen3-coder-next, vision-model), Kiro (Claude + AWS Builder ID for free), Gemini CLI (180K tokens/month free) -- **Ollama Cloud** — Cloud-hosted Ollama models at `api.ollama.com` with free "Light usage" tier; use `ollamacloud/` prefix -- **Free-Only Combos** — Chain `gc/gemini-3-flash → if/kimi-k2-thinking → qw/qwen3-coder-plus` = $0/month with zero downtime -- **NVIDIA NIM Free Access** — ~40 RPM dev-forever free access to 70+ models at build.nvidia.com (transitioning from credits to pure rate limits) -- **Cost Optimized Strategy** — Routing strategy that automatically chooses the cheapest available provider +- **内置免费层提供商** — 原生支持 100% 免费提供商:Qoder(通过 OAuth 的 5 个无限模型:kimi-k2-thinking、qwen3-coder-plus、deepseek-r1、minimax-m2、kimi-k2)、Qwen(4 个无限模型:qwen3-coder-plus、qwen3-coder-flash、qwen3-coder-next、vision-model)、Kiro(免费的 Claude + AWS Builder ID)、Gemini CLI(每月 180K Token 免费) +- **Ollama Cloud** — `api.ollama.com` 上的云托管 Ollama 模型,带免费"轻度使用"层级;使用 `ollamacloud/` 前缀 +- **纯免费 Combo** — 链接 `gc/gemini-3-flash → if/kimi-k2-thinking → qw/qwen3-coder-plus` = $0/月,零停机 +- **NVIDIA NIM 免费访问** — 在 build.nvidia.com 上永久免费开发访问 70+ 个模型,约 40 RPM(从积分过渡到纯速率限制) +- **成本优化策略** — 自动选择最便宜可用提供商的路由策略
-🔒 5. "I need to protect my AI gateway from unauthorized access" +🔒 5. "我需要保护我的 AI 网关免受未授权访问" -When exposing an AI gateway to the network (LAN, VPS, Docker), anyone with the address can consume the developer's tokens/quota. Without protection, APIs are vulnerable to misuse, prompt injection, and abuse. +将 AI 网关暴露到网络(LAN、VPS、Docker)时,任何有地址的人都可以消耗开发者的 Token/配额。没有保护,API 容易被滥用、提示词注入和滥用。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **API Key Management** — Generation, rotation, and scoping per provider with a dedicated `/dashboard/api-manager` page -- **Model-Level Permissions** — Restrict API keys to specific models (`openai/*`, wildcard patterns), with Allow All/Restrict toggle -- **API Endpoint Protection** — Require a key for `/v1/models` and block specific providers from the listing -- **Auth Guard + CSRF Protection** — All dashboard routes protected with `withAuth` middleware + CSRF tokens -- **Rate Limiter** — Per-IP rate limiting with configurable windows -- **IP Filtering** — Allowlist/blocklist for access control -- **Prompt Injection Guard** — Sanitization against malicious prompt patterns -- **AES-256-GCM Encryption** — Credentials encrypted at rest +- **API 密钥管理** — 在专用的 `/dashboard/api-manager` 页面按提供商生成、轮换和范围界定 +- **模型级权限** — 将 API 密钥限制为特定模型(`openai/*`、通配符模式),带允许全部/限制切换 +- **API 端点保护** — `/v1/models` 需要密钥,并从列表中阻止特定提供商 +- **认证守卫 + CSRF 保护** — 所有 Dashboard 路由都使用 `withAuth` 中间件 + CSRF Token 保护 +- **速率限制器** — 每 IP 速率限制,可配置时间窗口 +- **IP 过滤** — 白名单/黑名单用于访问控制 +- **提示词注入守卫** — 针对恶意提示词模式的清理 +- **AES-256-GCM 加密** — 静态凭证加密
-🛑 6. "My provider went down and I lost my coding flow" +🛑 6. "我的提供商宕机,我失去了编码心流" -AI providers can become unstable, return 5xx errors, or hit temporary rate limits. If a dev depends on a single provider, they're interrupted. Without circuit breakers, repeated retries can crash the application. +AI 提供商可能变得不稳定、返回 5xx 错误或达到临时速率限制。如果开发者依赖单个提供商,他们会被中断。没有熔断器,重复重试可能会使应用程序崩溃。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Circuit Breaker per-model** — Auto-open/close with configurable thresholds and cooldown (Closed/Open/Half-Open), scoped per-model to avoid cascading blocks -- **Exponential Backoff** — Progressive retry delays -- **Anti-Thundering Herd** — Mutex + semaphore protection against concurrent retry storms -- **Combo Fallback Chains** — If the primary provider fails, automatically falls through the chain with no intervention -- **Combo Circuit Breaker** — Auto-disables failing providers within a combo chain -- **Health Dashboard** — Uptime monitoring, circuit breaker states, lockouts, cache stats, p50/p95/p99 latency +- **每模型熔断器** — 使用可配置阈值和冷却自动打开/关闭(Closed/Open/Half-Open),按模型范围界定以避免级联阻塞 +- **指数退避** — 渐进式重试延迟 +- **防惊群** — 互斥锁 + 信号量保护,防止并发重试风暴 +- **Combo 后备链** — 如果主提供商失败,自动通过链条后备,无需干预 +- **Combo 熔断器** — 自动禁用 Combo 链中失败的提供商 +- **健康仪表盘** — 正常运行时间监控、熔断器状态、锁定、缓存统计、p50/p95/p99 延迟
-🔧 7. "Configuring each AI tool is tedious and repetitive" +🔧 7. "配置每个 AI 工具既繁琐又重复" -Developers use Cursor, Claude Code, Codex CLI, OpenClaw, Gemini CLI, Kilo Code... Each tool needs a different config (API endpoint, key, model). Reconfiguring when switching providers or models is a waste of time. +开发者使用 Cursor、Claude Code、Codex CLI、OpenClaw、Gemini CLI、Kilo Code... 每个工具需要不同的配置(API 端点、密钥、模型)。切换提供商或模型时重新配置浪费时间。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **CLI Tools Dashboard** — Dedicated page with one-click setup for Claude Code, Codex CLI, OpenClaw, Kilo Code, Antigravity, Cline -- **GitHub Copilot Config Generator** — Generates `chatLanguageModels.json` for VS Code with bulk model selection -- **Onboarding Wizard** — Guided 4-step setup for first-time users -- **One endpoint, all models** — Configure `http://localhost:20128/v1` once, access 67+ providers +- **CLI 工具仪表盘** — 专用页面,一键设置 Claude Code、Codex CLI、OpenClaw、Kilo Code、Antigravity、Cline +- **GitHub Copilot 配置生成器** — 为 VS Code 生成 `chatLanguageModels.json`,批量选择模型 +- **入门向导** — 为首次用户提供指导的 4 步设置 +- **一个端点,所有模型** — 配置一次 `http://localhost:20128/v1`,访问 67+ 个提供商
-🔑 8. "Managing OAuth tokens from multiple providers is hell" +🔑 8. "管理来自多个提供商的 OAuth Token 是地狱" -Claude Code, Codex, Gemini CLI, Copilot — all use OAuth 2.0 with expiring tokens. Developers need to re-authenticate constantly, deal with `client_secret is missing`, `redirect_uri_mismatch`, and failures on remote servers. OAuth on LAN/VPS is particularly problematic. +Claude Code、Codex、Gemini CLI、Copilot — 全部使用带过期 Token 的 OAuth 2.0。开发者需要不断重新认证,处理 `client_secret is missing`、`redirect_uri_mismatch` 和远程服务器上的失败。LAN/VPS 上的 OAuth 尤其成问题。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Auto Token Refresh** — OAuth tokens refresh in background before expiration -- **OAuth 2.0 (PKCE) Built-in** — Automatic flow for Claude Code, Codex, Gemini CLI, Copilot, Kiro, Qwen, iFlow -- **Multi-Account OAuth** — Multiple accounts per provider via JWT/ID token extraction -- **OAuth LAN/Remote Fix** — Private IP detection for `redirect_uri` + manual URL mode for remote servers -- **OAuth Behind Nginx** — Uses `window.location.origin` for reverse proxy compatibility -- **Remote OAuth Guide** — Step-by-step guide for Google Cloud credentials on VPS/Docker +- **自动 Token 刷新** — OAuth Token 在过期前在后台刷新 +- **内置 OAuth 2.0(PKCE)** — Claude Code、Codex、Gemini CLI、Copilot、Kiro、Qwen、Qoder 的自动流程 +- **多账户 OAuth** — 通过 JWT/ID Token 提取的每提供商多账户 +- **OAuth LAN/远程修复** — `redirect_uri` 的私有 IP 检测 + 远程服务器的手动 URL 模式 +- **Nginx 后的 OAuth** — 使用 `window.location.origin` 实现反向代理兼容性 +- **远程 OAuth 指南** — VPS/Docker 上 Google Cloud 凭证的分步指南
-📊 9. "I don't know how much I'm spending or where" +📊 9. "我不知道花了多少钱或花在哪里" -Developers use multiple paid providers but have no unified view of spending. Each provider has its own billing dashboard, but there's no consolidated view. Unexpected costs can pile up. +开发者使用多个付费提供商但没有统一的支出视图。每个提供商都有自己的计费仪表盘,但没有合并视图。意外成本可能会累积。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Cost Analytics Dashboard** — Per-token cost tracking and budget management per provider -- **Budget Limits per Tier** — Spending ceiling per tier that triggers automatic fallback -- **Per-Model Pricing Configuration** — Configurable prices per model -- **Usage Statistics Per API Key** — Request count and last-used timestamp per key -- **Analytics Dashboard** — Stat cards, model usage chart, provider table with success rates and latency +- **成本分析仪表盘** — 每提供商的每 Token 成本追踪和预算管理 +- **每层级预算限制** — 每层级支出上限,触发自动后备 +- **每模型定价配置** — 每模型可配置价格 +- **每 API 密钥使用统计** — 每密钥的请求计数和最后使用时间戳 +- **分析仪表盘** — 统计卡、模型使用图表、带成功率和延迟的提供商表
-🐛 10. "I can't diagnose errors and problems in AI calls" +🐛 10. "我无法诊断 AI 调用中的错误和问题" -When a call fails, the dev doesn't know if it was a rate limit, expired token, wrong format, or provider error. Fragmented logs across different terminals. Without observability, debugging is trial-and-error. +当调用失败时,开发者不知道是速率限制、过期 Token、错误格式还是提供商错误。不同终端的分散日志。没有可观测性,调试就是试错。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Unified Logs Dashboard** — 4 tabs: Request Logs, Proxy Logs, Audit Logs, Console -- **Console Log Viewer** — Real-time terminal-style viewer with color-coded levels, auto-scroll, search, filter -- **SQLite Proxy Logs** — Persistent logs that survive server restarts -- **Translator Playground** — 4 debugging modes: Playground (format translation), Chat Tester (round-trip), Test Bench (batch), Live Monitor (real-time) -- **Request Telemetry** — p50/p95/p99 latency + X-Request-Id tracing -- **File-Based Logging with Rotation** — Console interceptor captures everything to JSON log with size-based rotation -- **System Info Report** — `npm run system-info` generates `system-info.txt` with your full environment (Node version, OmniRoute version, OS, CLI tools, Docker/PM2 status). Attach it when reporting issues for instant triage. +- **统一日志仪表盘** — 4 个标签页:请求日志、代理日志、审计日志、控制台 +- **控制台日志查看器** — 实时终端风格查看器,带颜色编码级别、自动滚动、搜索、过滤 +- **SQLite 代理日志** — 持久化日志,在服务器重启后保留 +- **翻译器游乐场** — 4 种调试模式:游乐场(格式翻译)、聊天测试器(往返)、测试台(批量)、实时监控(实时) +- **请求遥测** — p50/p95/p99 延迟 + X-Request-Id 追踪 +- **基于文件的日志轮换** — 控制台拦截器捕获所有内容到 JSON 日志,基于大小轮换 +- **系统信息报告** — `npm run system-info` 生成 `system-info.txt`,包含完整环境(Node 版本、OmniRoute 版本、操作系统、CLI 工具、Docker/PM2 状态)。报告问题时附上它以获得即时分类。
-🏗️ 11. "Deploying and maintaining the gateway is complex" +🏗️ 11. "部署和维护网关很复杂" -Installing, configuring, and maintaining an AI proxy across different environments (local, VPS, Docker, cloud) is labor-intensive. Problems like hardcoded paths, `EACCES` on directories, port conflicts, and cross-platform builds add friction. +在不同环境(本地、VPS、Docker、云)中安装、配置和维护 AI 代理非常耗费人力。硬编码路径、目录上的 `EACCES`、端口冲突和跨平台构建等问题增加了摩擦。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **npm global install** — `npm install -g omniroute && omniroute` — done -- **Docker Multi-Platform** — AMD64 + ARM64 native (Apple Silicon, AWS Graviton, Raspberry Pi) -- **Docker Compose Profiles** — `base` (no CLI tools) and `cli` (with Claude Code, Codex, OpenClaw) -- **Electron Desktop App** — Native app for Windows/macOS/Linux with system tray, auto-start, offline mode -- **Split-Port Mode** — API and Dashboard on separate ports for advanced scenarios (reverse proxy, container networking) -- **Cloud Sync** — Config synchronization across devices via Cloudflare Workers -- **DB Backups** — Automatic backup, restore, export and import of all settings +- **npm 全局安装** — `npm install -g omniroute && omniroute` — 完成 +- **Docker 多平台** — AMD64 + ARM64 原生支持(Apple Silicon、AWS Graviton、Raspberry Pi) +- **Docker Compose Profiles** — `base`(无 CLI 工具)和 `cli`(带 Claude Code、Codex、OpenClaw) +- **Electron 桌面应用** — Windows/macOS/Linux 原生应用,带系统托盘、自动启动、离线模式 +- **分离端口模式** — API 和 Dashboard 在不同端口上用于高级场景(反向代理、容器网络) +- **云同步** — 通过 Cloudflare Workers 跨设备配置同步 +- **数据库备份** — 自动备份、恢复、导出和导入所有设置
-🌍 12. "The interface is English-only and my team doesn't speak English" +🌍 12. "界面仅英文,我的团队不会说英语" -Teams in non-English-speaking countries, especially in Latin America, Asia, and Europe, struggle with English-only interfaces. Language barriers reduce adoption and increase configuration errors. +非英语国家的团队,尤其是拉丁美洲、亚洲和欧洲的团队,在纯英语界面上挣扎。语言障碍降低了采用率并增加了配置错误。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Dashboard i18n — 30 Languages** — All 500+ keys translated including Arabic, Bulgarian, Danish, German, Spanish, Finnish, French, Hebrew, Hindi, Hungarian, Indonesian, Italian, Japanese, Korean, Malay, Dutch, Norwegian, Polish, Portuguese (PT/BR), Romanian, Russian, Slovak, Swedish, Thai, Ukrainian, Vietnamese, Chinese, Filipino, English -- **RTL Support** — Right-to-left support for Arabic and Hebrew -- **Multi-Language READMEs** — 30 complete documentation translations -- **Language Selector** — Globe icon in header for real-time switching +- **Dashboard i18n — 30 种语言** — 所有 500+ 个键已翻译,包括阿拉伯语、保加利亚语、丹麦语、德语、西班牙语、芬兰语、法语、希伯来语、印地语、匈牙利语、印度尼西亚语、意大利语、日语、韩语、马来语、荷兰语、挪威语、波兰语、葡萄牙语(PT/BR)、罗马尼亚语、俄语、斯洛伐克语、瑞典语、泰语、乌克兰语、越南语、中文、菲律宾语、英语 +- **RTL 支持** — 阿拉伯语和希伯来语的从右到左支持 +- **多语言 README** — 30 个完整文档翻译 +- **语言选择器** — 头部的地球图标可实时切换
-🔄 13. "I need more than chat — I need embeddings, images, audio" +🔄 13. "我需要的不仅是聊天 — 我需要嵌入、图像、音频" -AI isn't just chat completion. Devs need to generate images, transcribe audio, create embeddings for RAG, rerank documents, and moderate content. Each API has a different endpoint and format. +AI 不仅仅是聊天补全。开发者需要生成图像、转录音频、为 RAG 创建嵌入、重新排序文档和审核内容。每个 API 都有不同的端点和格式。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Embeddings** — `/v1/embeddings` with 6 providers and 9+ models -- **Image Generation** — `/v1/images/generations` with 10 providers and 20+ models (OpenAI, xAI, Together, Fireworks, Nebius, Hyperbolic, NanoBanana, Antigravity, SD WebUI, ComfyUI) -- **Text-to-Video** — `/v1/videos/generations` — ComfyUI (AnimateDiff, SVD) and SD WebUI -- **Text-to-Music** — `/v1/music/generations` — ComfyUI (Stable Audio Open, MusicGen) -- **Audio Transcription** — `/v1/audio/transcriptions` — Whisper + Nvidia NIM, HuggingFace, Qwen3 -- **Text-to-Speech** — `/v1/audio/speech` — ElevenLabs, Nvidia NIM, HuggingFace, Coqui, Tortoise, Qwen3, **Inworld**, **Cartesia**, **PlayHT**, + existing providers -- **Moderations** — `/v1/moderations` — Content safety checks -- **Reranking** — `/v1/rerank` — Document relevance reranking -- **Responses API** — Full `/v1/responses` support for Codex +- **Embeddings** — `/v1/embeddings`,6 个提供商和 9+ 个模型 +- **图像生成** — `/v1/images/generations`,10 个提供商和 20+ 个模型(OpenAI、xAI、Together、Fireworks、Nebius、Hyperbolic、NanoBanana、Antigravity、SD WebUI、ComfyUI) +- **文本转视频** — `/v1/videos/generations` — ComfyUI(AnimateDiff、SVD)和 SD WebUI +- **文本转音乐** — `/v1/music/generations` — ComfyUI(Stable Audio Open、MusicGen) +- **音频转录** — `/v1/audio/transcriptions` — Whisper + Nvidia NIM、HuggingFace、Qwen3 +- **文本转语音** — `/v1/audio/speech` — ElevenLabs、Nvidia NIM、HuggingFace、Coqui、Tortoise、Qwen3、**Inworld**、**Cartesia**、**PlayHT** + 现有提供商 +- **Moderations** — `/v1/moderations` — 内容安全检查 +- **Reranking** — `/v1/rerank` — 文档相关性重新排序 +- **Responses API** — 完整的 `/v1/responses` 支持 Codex
-🧪 14. "I have no way to test and compare quality across models" +🧪 14. "我无法测试和比较模型质量" -Developers want to know which model is best for their use case — code, translation, reasoning — but comparing manually is slow. No integrated eval tools exist. +开发者想知道哪个模型最适合他们的用例 — 代码、翻译、推理 — 但手动比较很慢。不存在集成的评估工具。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **LLM Evaluations** — Golden set testing with 10 pre-loaded cases covering greetings, math, geography, code generation, JSON compliance, translation, markdown, safety refusal -- **4 Match Strategies** — `exact`, `contains`, `regex`, `custom` (JS function) -- **Translator Playground Test Bench** — Batch testing with multiple inputs and expected outputs, cross-provider comparison -- **Chat Tester** — Full round-trip with visual response rendering -- **Live Monitor** — Real-time stream of all requests flowing through the proxy +- **LLM 评估** — 黄金集测试,预加载 10 个案例,涵盖问候、数学、地理、代码生成、JSON 合规性、翻译、Markdown、安全拒绝 +- **4 种匹配策略** — `exact`、`contains`、`regex`、`custom`(JS 函数) +- **翻译器游乐场测试台** — 批量测试多个输入和预期输出,跨提供商比较 +- **聊天测试器** — 完整往返,带视觉响应渲染 +- **实时监控** — 通过代理流动的所有请求的实时流
-📈 15. "I need to scale without losing performance" +📈 15. "我需要在不损失性能的情况下扩展" -As request volume grows, without caching the same questions generate duplicate costs. Without idempotency, duplicate requests waste processing. Per-provider rate limits must be respected. +随着请求量增长,没有缓存,相同的问题会产生重复成本。没有幂等性,重复请求浪费处理。必须遵守每提供商的速率限制。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **Semantic Cache** — Two-tier cache (signature + semantic) reduces cost and latency -- **Request Idempotency** — 5s deduplication window for identical requests -- **Rate Limit Detection** — Per-provider RPM, min gap, and max concurrent tracking -- **Editable Rate Limits** — Configurable defaults in Settings → Resilience with persistence -- **API Key Validation Cache** — 3-tier cache for production performance -- **Health Dashboard with Telemetry** — p50/p95/p99 latency, cache stats, uptime +- **语义缓存** — 两层缓存(签名 + 语义)降低成本和延迟 +- **请求幂等性** — 5 秒去重窗口用于相同请求 +- **速率限制检测** — 每提供商的 RPM、最小间隙和最大并发追踪 +- **可编辑速率限制** — 设置 → 弹性中的可配置默认值,带持久化 +- **API 密钥验证缓存** — 3 层缓存用于生产性能 +- **健康仪表盘与遥测** — p50/p95/p99 延迟、缓存统计、正常运行时间
-🤖 16. "I want to control model behavior globally" +🤖 16. "我想全局控制模型行为" -Developers who want all responses in a specific language, with a specific tone, or want to limit reasoning tokens. Configuring this in every tool/request is impractical. +希望所有响应都使用特定语言、特定语气或限制推理 Token 的开发者。在每个工具/请求中配置这些不切实际。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- **System Prompt Injection** — Global prompt applied to all requests -- **Thinking Budget Validation** — Reasoning token allocation control per request (passthrough, auto, custom, adaptive) -- **6 Routing Strategies** — Global strategies that determine how requests are distributed -- **Wildcard Router** — `provider/*` patterns route dynamically to any provider -- **Combo Enable/Disable Toggle** — Toggle combos directly from the dashboard -- **Provider Toggle** — Enable/disable all connections for a provider with one click -- **Blocked Providers** — Exclude specific providers from `/v1/models` listing +- **系统提示词注入** — 应用于所有请求的全局提示词 +- **思考预算验证** — 每请求的推理 Token 分配控制(直通、自动、自定义、自适应) +- **6 种路由策略** — 确定请求如何分发的全局策略 +- **通配符路由器** — `provider/*` 模式动态路由到任何提供商 +- **Combo 启用/禁用切换** — 直接从仪表盘切换 Combo +- **提供商切换** — 一键启用/禁用提供商的所有连接 +- **被阻止的提供商** — 从 `/v1/models` 列表中排除特定提供商
-🧰 17. "I need MCP tools as first-class product capabilities" +🧰 17. "我需要 MCP 工具作为一级产品功能" -Many AI gateways expose MCP only as a hidden implementation detail. Teams need a visible, manageable operation layer. +许多 AI 网关仅将 MCP 作为隐藏的实现细节公开。团队需要可见、可管理的操作层。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- MCP appears in the dashboard navigation and endpoint protocol tab -- Dedicated MCP management page with process, tools, scopes, and audit -- Built-in quick-start for `omniroute --mcp` and client onboarding +- MCP 出现在仪表盘导航和端点协议标签中 +- 专用 MCP 管理页面,带进程、工具、范围和审计 +- `omniroute --mcp` 和客户端入门的内置快速启动
-🧠 18. "I need A2A orchestration with sync + stream task paths" +🧠 18. "我需要带同步 + 流任务路径的 A2A 编排" -Agent workflows need both direct replies and long-running streamed execution with lifecycle control. +代理工作流需要直接回复和带生命周期控制的长期流执行。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- A2A JSON-RPC endpoint (`POST /a2a`) with `message/send` and `message/stream` -- SSE streaming with terminal state propagation -- Task lifecycle APIs for `tasks/get` and `tasks/cancel` +- A2A JSON-RPC 端点(`POST /a2a`),带 `message/send` 和 `message/stream` +- SSE 流,带终端状态传播 +- 任务生命周期 API:`tasks/get` 和 `tasks/cancel`
-🛰️ 19. "I need real MCP process health, not guessed status" +🛰️ 19. "我需要真实的 MCP 进程健康,而不是猜测的状态" -Operational teams need to know if MCP is actually alive, not just whether an API is reachable. +运营团队需要知道 MCP 是否真的活着,而不仅仅是 API 是否可达。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- Runtime heartbeat file with PID, timestamps, transport, tool count, and scope mode -- MCP status API combining heartbeat + recent activity -- UI status cards for process/uptime/heartbeat freshness +- 运行时心跳文件,带 PID、时间戳、传输、工具计数和范围模式 +- MCP 状态 API,结合心跳 + 最近活动 +- UI 状态卡,用于进程/正常运行时间/心跳新鲜度
-📋 20. "I need auditable MCP tool execution" +📋 20. "我需要可审计的 MCP 工具执行" -When tools mutate config or trigger ops actions, teams need forensic traceability. +当工具改变配置或触发操作时,团队需要取证可追溯性。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- SQLite-backed audit logging for MCP tool calls -- Filters by tool, success/failure, API key, and pagination -- Dashboard audit table + stats endpoints for automation +- 基于 SQLite 的 MCP 工具调用审计日志 +- 按工具、成功/失败、API 密钥和分页过滤 +- Dashboard 审计表 + 用于自动化的统计端点
-🔐 21. "I need scoped MCP permissions per integration" +🔐 21. "我需要每个集成的范围化 MCP 权限" -Different clients should have least-privilege access to tool categories. +不同的客户端应该具有对工具类别的最小权限访问。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- 9 granular MCP scopes for controlled tool access -- Scope enforcement and visibility in MCP management UI -- Safe default posture for operational tooling +- 9 个粒度化的 MCP 范围用于受控工具访问 +- MCP 管理 UI 中的范围强制和可见性 +- 用于操作工具的安全默认姿态
-⚙️ 22. "I need operational controls without redeploying" +⚙️ 22. "我需要无需重新部署的操作控制" -Teams need quick runtime changes during incidents or cost events. +团队在事件或成本事件期间需要快速运行时更改。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- Switch combo activation directly from MCP dashboard -- Apply resilience profiles from pre-defined policy packs -- Reset circuit breaker state from the same operations panel +- 直接从 MCP 仪表盘切换 Combo 激活 +- 从预定义策略包应用弹性配置文件 +- 从同一操作面板重置熔断器状态
-🔄 23. "I need live A2A task lifecycle visibility and cancellation" +🔄 23. "我需要实时 A2A 任务生命周期可见性和取消" -Without lifecycle visibility, task incidents become hard to triage. +没有生命周期可见性,任务事件变得难以分类。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- Task listing/filtering by state/skill with pagination -- Drill-down on task metadata, events, and artifacts -- Task cancellation endpoint and UI action with confirmation +- 按状态/技能列出/过滤任务,带分页 +- 钻取任务元数据、事件和工件 +- 任务取消端点和 UI 操作,带确认
-🌊 24. "I need active stream metrics for A2A load" +🌊 24. "我需要 A2A 负载的活动流指标" -Streaming workflows require operational insight into concurrency and live connections. +流工作流需要对并发和实时连接的操作洞察。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- Active stream counters integrated into A2A status -- Last task timestamp and per-state counts -- A2A dashboard cards for real-time ops monitoring +- 活动流计数器集成到 A2A 状态中 +- 最后任务时间戳和每状态计数 +- A2A 仪表盘卡用于实时运维监控
-🪪 25. "I need standard agent discovery for clients" +🪪 25. "我需要客户端的标准代理发现" -External clients and orchestrators need machine-readable metadata for onboarding. +外部客户端和编排器需要机器可读的元数据以进行入门。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- Agent Card exposed at `/.well-known/agent.json` -- Capabilities and skills shown in management UI -- A2A status API includes discovery metadata for automation +- 在 `/.well-known/agent.json` 公开代理卡 +- 管理 UI 中显示的功能和技能 +- A2A 状态 API 包括用于自动化的发现元数据
-🧭 26. "I need protocol discoverability in the product UX" +🧭 26. "我需要产品 UX 中的协议可发现性" -If users cannot discover protocol surfaces, adoption and support quality drop. +如果用户无法发现协议界面,采用率和支持质量会下降。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- Consolidated **Endpoints** page with tabs for Proxy, MCP, A2A, and API Endpoints -- Inline service status toggles (Online/Offline) for MCP and A2A -- Links from overview to dedicated management tabs +- 合并的**端点**页面,带 Proxy、MCP、A2A 和 API 端点的标签页 +- MCP 和 A2A 的内联服务状态切换(在线/离线) +- 从概览到专用管理标签的链接
-🧪 27. "I need end-to-end protocol validation with real clients" +🧪 27. "我需要使用真实客户端进行端到端协议验证" -Mock tests are not enough to validate protocol compatibility before release. +模拟测试不足以在发布前验证协议兼容性。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- E2E suite that boots app and uses real MCP SDK client transport -- A2A client tests for discovery, send, stream, get, and cancel flows -- Cross-check assertions against MCP audit and A2A tasks APIs +- E2E 套件启动应用并使用真实的 MCP SDK 客户端传输 +- A2A 客户端测试,用于发现、发送、流、获取和取消流程 +- 针对 MCP 审计和 A2A 任务 API 的交叉检查断言
-📡 28. "I need unified observability across all interfaces" +📡 28. "我需要跨所有界面的统一可观测性" -Splitting observability by protocol creates blind spots and longer MTTR. +按协议拆分可观测性会产生盲点并延长 MTTR。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- Unified dashboards/logs/analytics in one product -- Health + audit + request telemetry across OpenAI, MCP, and A2A layers -- Operational APIs for status and automation +- 统一仪表盘/日志/分析在一个产品中 +- OpenAI、MCP 和 A2A 层的健康 + 审计 + 请求遥测 +- 用于状态和自动化的操作 API
-💼 29. "I need one runtime for proxy + tools + agent orchestration" +💼 29. "我需要一个运行时用于代理 + 工具 + 代理编排" -Running many separate services increases operational cost and failure modes. +运行许多单独的服务会增加操作成本和故障模式。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- OpenAI-compatible proxy, MCP server, and A2A server in one stack -- Shared auth, resilience, data store, and observability -- Consistent policy model across all interaction surfaces +- OpenAI 兼容代理、MCP 服务器和 A2A 服务器在一个堆栈中 +- 共享认证、弹性、数据存储和可观测性 +- 跨所有交互界面的一致策略模型
-🚀 30. "I need to ship agentic workflows without glue-code sprawl" +🚀 30. "我需要在没有胶水代码蔓延的情况下交付代理工作流" -Teams lose velocity when stitching multiple ad-hoc services and scripts. +团队在拼接多个临时服务和脚本时失去速度。 -**How OmniRoute solves it:** +**OmniRoute 如何解决:** -- Unified endpoint strategy for clients and agents -- Built-in protocol management UIs and smoke validation paths -- Production-ready foundations (security, logging, resilience, backup) +- 为客户端和代理提供统一的端点策略 +- 内置协议管理 UI 和冒烟验证路径 +- 生产就绪的基础(安全、日志、弹性、备份)
-### Example Playbooks (Integrated Use Cases) +### 示例行动手册(集成用例) -**Playbook A: Maximize paid subscription + cheap backup** +**行动手册 A:最大化付费订阅 + 便宜备份** ```txt Combo: "maximize-claude" @@ -690,11 +714,11 @@ Combo: "maximize-claude" 2. glm/glm-4.7 3. if/kimi-k2-thinking -Monthly cost: $20 + small backup spend -Outcome: higher quality, near-zero interruption +每月成本:$20 + 小额备份支出 +结果:更高质量,几乎零中断 ``` -**Playbook B: Zero-cost coding stack** +**行动手册 B:零成本编码堆栈** ```txt Combo: "free-forever" @@ -702,11 +726,11 @@ Combo: "free-forever" 2. if/kimi-k2-thinking 3. qw/qwen3-coder-plus -Monthly cost: $0 -Outcome: stable free coding workflow +每月成本:$0 +结果:稳定的免费编码工作流 ``` -**Playbook C: 24/7 always-on fallback chain** +**行动手册 C:24/7 永久在线后备链** ```txt Combo: "always-on" @@ -716,64 +740,64 @@ Combo: "always-on" 4. minimax/MiniMax-M2.1 5. if/kimi-k2-thinking -Outcome: deep fallback depth for deadline-critical workloads +结果:对截止日期关键工作负载的深度后备深度 ``` -**Playbook D: Agent ops with MCP + A2A** +**行动手册 D:使用 MCP + A2A 的代理运维** ```txt -1) Start MCP transport (`omniroute --mcp`) for tool-driven operations -2) Run A2A tasks via `message/send` and `message/stream` -3) Observe via /dashboard/endpoint (MCP and A2A tabs) -4) Toggle services via inline status controls +1) 启动 MCP 传输(`omniroute --mcp`)用于工具驱动的操作 +2) 通过 `message/send` 和 `message/stream` 运行 A2A 任务 +3) 通过 /dashboard/endpoint(MCP 和 A2A 标签页)观察 +4) 通过内联状态控制切换服务 ``` --- -## 🆓 Start Free — Zero Configuration Cost +## 🆓 免费开始 — 零配置成本 -> Setup AI coding in minutes at **$0/month**. Connect these free accounts and use the built-in **Free Stack** combo. +> 在几分钟内以 **$0/月**设置 AI 编码。连接这些免费账户并使用内置的 **Free Stack** Combo。 -| Step | Action | Providers Unlocked | -| ---- | -------------------------------------------------- | ------------------------------------------------------------------ | -| 1 | Connect **Kiro** (AWS Builder ID OAuth) | Claude Sonnet 4.5, Haiku 4.5 — **unlimited** | -| 2 | Connect **iFlow** (Google OAuth) | kimi-k2-thinking, qwen3-coder-plus, deepseek-r1... — **unlimited** | -| 3 | Connect **Qwen** (Device Code) | qwen3-coder-plus, qwen3-coder-flash... — **unlimited** | -| 4 | Connect **Gemini CLI** (Google OAuth) | gemini-3-flash, gemini-2.5-pro — **180K/mo free** | -| 5 | `/dashboard/combos` → **Free Stack ($0)** template | Round-robin all free providers automatically | +| 步骤 | 操作 | 解锁的提供商 | +| ---- | ---------------------------------------------- | ------------------------------------------------------------- | +| 1 | 连接 **Kiro**(AWS Builder ID OAuth) | Claude Sonnet 4.5、Haiku 4.5 — **无限** | +| 2 | 连接 **Qoder**(Google OAuth) | kimi-k2-thinking、qwen3-coder-plus、deepseek-r1... — **无限** | +| 3 | 连接 **Qwen**(设备代码) | qwen3-coder-plus、qwen3-coder-flash... — **无限** | +| 4 | 连接 **Gemini CLI**(Google OAuth) | gemini-3-flash、gemini-2.5-pro — **180K/月免费** | +| 5 | `/dashboard/combos` → **Free Stack ($0)** 模板 | 自动轮询所有免费提供商 | -**Point any IDE/CLI to:** `http://localhost:20128/v1` · API Key: `any-string` · Done. +**将任何 IDE/CLI 指向:** `http://localhost:20128/v1` · API Key: `any-string` · 完成。 -> **Optional extra coverage (also free):** Groq API key (30 RPM free), NVIDIA NIM (40 RPM free, 70+ models), Cerebras (1M tok/day), LongCat API key (50M tokens/day!), Cloudflare Workers AI (10K Neurons/day, 50+ models). +> **可选额外覆盖(也免费):** Groq API 密钥(30 RPM 免费)、NVIDIA NIM(40 RPM 免费,70+ 个模型)、Cerebras(1M token/天)、LongCat API 密钥(50M tokens/天!)、Cloudflare Workers AI(10K Neurons/天,50+ 个模型)。 ## 快速开始 -### 1) Install and run +### 1) 安装并运行 ```bash npm install -g omniroute omniroute ``` -> **pnpm users:** Run `pnpm approve-builds -g` after install to enable native build scripts required by `better-sqlite3` and `@swc/core`: +> **pnpm 用户:** 安装后运行 `pnpm approve-builds -g` 以启用 `better-sqlite3` 和 `@swc/core` 所需的原生构建脚本: > > ```bash > pnpm install -g omniroute -> pnpm approve-builds -g # Select all packages → approve +> pnpm approve-builds -g # 选择所有包 → 批准 > omniroute > ``` -Dashboard opens at `http://localhost:20128` and API base URL is `http://localhost:20128/v1`. +Dashboard 在 `http://localhost:20128` 打开,API 基础 URL 是 `http://localhost:20128/v1`。 -| Command | Description | -| ----------------------- | ----------------------------------------------------------- | -| `omniroute` | Start server (`PORT=20128`, API and dashboard on same port) | -| `omniroute --port 3000` | Set canonical/API port to 3000 | -| `omniroute --mcp` | Start MCP server (stdio transport) | -| `omniroute --no-open` | Don't auto-open browser | -| `omniroute --help` | Show help | +| 命令 | 描述 | +| ----------------------- | ------------------------------------------------------- | +| `omniroute` | 启动服务器(`PORT=20128`,API 和 Dashboard 在同一端口) | +| `omniroute --port 3000` | 将规范/API 端口设置为 3000 | +| `omniroute --mcp` | 启动 MCP 服务器(stdio 传输) | +| `omniroute --no-open` | 不自动打开浏览器 | +| `omniroute --help` | 显示帮助 | -Optional split-port mode: +可选的分离端口模式: ```bash PORT=20128 DASHBOARD_PORT=20129 omniroute @@ -781,36 +805,36 @@ PORT=20128 DASHBOARD_PORT=20129 omniroute # Dashboard: http://localhost:20129 ``` -### 2) Connect providers and create your API key +### 2) 连接提供商并创建你的 API 密钥 -1. Open Dashboard → `Providers` and connect at least one provider (OAuth or API key). -2. Open Dashboard → `Endpoints` and create an API key. -3. (Optional) Open Dashboard → `Combos` and set your fallback chain. +1. 打开 Dashboard → `Providers` 并连接至少一个提供商(OAuth 或 API 密钥)。 +2. 打开 Dashboard → `Endpoints` 并创建一个 API 密钥。 +3. (可选)打开 Dashboard → `Combos` 并设置你的后备链。 -### 3) Point your coding tool to OmniRoute +### 3) 将你的编码工具指向 OmniRoute ```txt Base URL: http://localhost:20128/v1 -API Key: [copy from Endpoint page] -Model: if/kimi-k2-thinking (or any provider/model prefix) +API Key: [从端点页面复制] +Model: if/kimi-k2-thinking(或任何 provider/model 前缀) ``` -Works with Claude Code, Codex CLI, Gemini CLI, Cursor, Cline, OpenClaw, OpenCode, and OpenAI-compatible SDKs. +适用于 Claude Code、Codex CLI、Gemini CLI、Cursor、Cline、OpenClaw、OpenCode 和 OpenAI 兼容的 SDK。 -### 4) Enable and validate protocols (v2.0) +### 4) 启用并验证协议(v2.0) -**MCP (for tool-driven operations):** +**MCP(用于工具驱动的操作):** ```bash omniroute --mcp ``` -Then connect your MCP client over `stdio` and test tools like: +然后通过 `stdio` 连接你的 MCP 客户端并测试工具,例如: - `omniroute_get_health` - `omniroute_list_combos` -**A2A (for agent-to-agent workflows):** +**A2A(用于代理到代理工作流):** ```bash curl http://localhost:20128/.well-known/agent.json @@ -822,15 +846,15 @@ curl -X POST http://localhost:20128/a2a \ -d '{"jsonrpc":"2.0","id":"quickstart","method":"message/send","params":{"skill":"quota-management","messages":[{"role":"user","content":"Give me a short quota summary."}]}}' ``` -### 5) Validate everything end-to-end (recommended) +### 5) 端到端验证一切(推荐) ```bash npm run test:protocols:e2e ``` -This suite validates real MCP and A2A client flows against a running app. +此套件针对正在运行的应用验证真实的 MCP 和 A2A 客户端流程。 -### Alternative: run from source +### 替代方案:从源码运行 ```bash cp .env.example .env @@ -842,9 +866,9 @@ PORT=20128 DASHBOARD_PORT=20129 NEXT_PUBLIC_BASE_URL=http://localhost:20129 npm ## 🐳 Docker -OmniRoute is available as a public Docker image on [Docker Hub](https://hub.docker.com/r/diegosouzapw/omniroute). +OmniRoute 在 [Docker Hub](https://hub.docker.com/r/diegosouzapw/omniroute) 上作为公共 Docker 镜像提供。 -**Quick run:** +**快速运行:** ```bash docker run -d \ @@ -855,10 +879,10 @@ docker run -d \ diegosouzapw/omniroute:latest ``` -**With environment file:** +**使用环境变量文件:** ```bash -# Copy and edit .env first +# 先复制并编辑 .env cp .env.example .env docker run -d \ @@ -870,27 +894,28 @@ docker run -d \ diegosouzapw/omniroute:latest ``` -**Using Docker Compose:** +**使用 Docker Compose:** ```bash -# Base profile (no CLI tools) +# 基础 profile(不含 CLI 工具) docker compose --profile base up -d -# CLI profile (Claude Code, Codex, OpenClaw built-in) +# CLI profile(内置 Claude Code、Codex、OpenClaw) docker compose --profile cli up -d ``` -Dashboard support for Docker deployments now includes a one-click **Cloudflare Quick Tunnel** on `Dashboard → Endpoints`. The first enable downloads `cloudflared` only when needed, starts a temporary tunnel to your current `/v1` endpoint, and shows the generated `https://*.trycloudflare.com/v1` URL directly below your normal public URL. +面向 Docker 部署的 Dashboard 现已在 `Dashboard → Endpoints` 中内置一键式 **Cloudflare Quick Tunnel**。首次启用时仅会在需要时下载 `cloudflared`,随后为当前 `/v1` 端点启动一个临时隧道,并将生成的 `https://*.trycloudflare.com/v1` URL 显示在普通公网 URL 下方。 -Notes: +说明: -- Quick Tunnel URLs are temporary and change after every restart. -- Managed install currently supports Linux, macOS, and Windows on `x64` / `arm64`. -- Set `CLOUDFLARED_BIN=/absolute/path/to/cloudflared` if you want OmniRoute to use an existing binary instead of downloading one. +- Quick Tunnel URL 是临时的,每次重启后都会变化。 +- 托管安装当前支持 Linux、macOS 和 Windows 的 `x64` / `arm64`。 +- Docker 镜像内置了系统 CA 根证书并将其传递给托管的 `cloudflared`,避免了隧道在容器内启动时的 TLS 信任失败问题。 +- 如果你希望 OmniRoute 直接使用现有二进制而不是下载,可以设置 `CLOUDFLARED_BIN=/absolute/path/to/cloudflared`。 -**Using Docker Compose with Caddy (HTTPS Auto-TLS):** +**结合 Caddy 使用 Docker Compose(HTTPS 自动 TLS):** -OmniRoute can be securely exposed using Caddy's automatic SSL provisioning. Ensure your domain's DNS A record points to your server's IP. +OmniRoute 可以通过 Caddy 的自动 SSL 配置安全对外暴露。请确保你的域名 DNS A 记录已指向服务器 IP。 ```yaml services: @@ -917,387 +942,388 @@ volumes: omniroute-data: ``` -| Image | Tag | Size | Description | -| ------------------------ | -------- | ------ | --------------------- | -| `diegosouzapw/omniroute` | `latest` | ~250MB | Latest stable release | -| `diegosouzapw/omniroute` | `1.0.3` | ~250MB | Current version | +| 镜像 | 标签 | 大小 | 说明 | +| ------------------------ | -------- | ------ | ------------ | +| `diegosouzapw/omniroute` | `latest` | ~250MB | 最新稳定版本 | +| `diegosouzapw/omniroute` | `1.0.3` | ~250MB | 当前版本 | --- -## 🖥️ Desktop App — Offline & Always-On +## 🖥️ Desktop App — 离线且常驻运行 -> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux. +> 🆕 **新功能!** OmniRoute 现已提供适用于 Windows、macOS 和 Linux 的**原生桌面应用**。 -Run OmniRoute as a standalone desktop app — no terminal, no browser, no internet required for local models. The Electron-based app includes: +将 OmniRoute 作为独立桌面应用运行,无需终端、无需浏览器;对于本地模型也无需联网。基于 Electron 的应用包含: -- 🖥️ **Native Window** — Dedicated app window with system tray integration -- 🔄 **Auto-Start** — Launch OmniRoute on system login -- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues -- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux) -- 🌐 **Offline Mode** — Works fully offline with bundled server +- 🖥️ **Native Window** — 带系统托盘集成的专用应用窗口 +- 🔄 **Auto-Start** — 在系统登录时启动 OmniRoute +- 🔔 **Native Notifications** — 在配额耗尽或提供商出现问题时收到提醒 +- ⚡ **One-Click Install** — NSIS(Windows)、DMG(macOS)、AppImage(Linux) +- 🌐 **Offline Mode** — 使用内置服务器即可完全离线运行 ### 快速开始 ```bash -# Development mode +# 开发模式 npm run electron:dev -# Build for your platform -npm run electron:build # Current platform +# 构建当前平台安装包 +npm run electron:build # 当前平台 npm run electron:build:win # Windows (.exe) npm run electron:build:mac # macOS (.dmg) — x64 & arm64 npm run electron:build:linux # Linux (.AppImage) ``` -### System Tray +### 系统托盘 -When minimized, OmniRoute lives in your system tray with quick actions: +最小化后,OmniRoute 会驻留在系统托盘,并提供以下快捷操作: -- Open dashboard -- Change server port -- Quit application +- 打开 dashboard +- 修改服务端端口 +- 退出应用 -📖 Full documentation: [`electron/README.md`](electron/README.md) +📖 完整文档:[`electron/README.md`](../../../electron/README.md) --- -## 💰 Pricing at a Glance +## 💰 定价一览 -| Tier | Provider | Cost | Quota Reset | Best For | -| ------------------- | --------------------------- | ------------------------- | ---------------- | --------------------------------- | -| **💳 SUBSCRIPTION** | Claude Code (Pro) | $20/mo | 5h + weekly | Already subscribed | -| | Codex (Plus/Pro) | $20-200/mo | 5h + weekly | OpenAI users | -| | Gemini CLI | **FREE** | 180K/mo + 1K/day | Everyone! | -| | GitHub Copilot | $10-19/mo | Monthly | GitHub users | -| **🔑 API KEY** | NVIDIA NIM | **FREE** (dev forever) | ~40 RPM | 70+ open models | -| | Cerebras | **FREE** (1M tok/day) | 60K TPM / 30 RPM | World's fastest | -| | Groq | **FREE** (30 RPM) | 14.4K RPD | Ultra-fast Llama/Gemma | -| | DeepSeek V3.2 | $0.27/$1.10 per 1M | None | Best price/quality reasoning | -| | xAI Grok-4 Fast | **$0.20/$0.50 per 1M** 🆕 | None | Fastest + tool calling, ultralow | -| | xAI Grok-4 (standard) | $0.20/$1.50 per 1M 🆕 | None | Reasoning flagship from xAI | -| | Mistral | Free trial + paid | Rate limited | European AI | -| | OpenRouter | Pay-per-use | None | 100+ models aggr. | -| **💰 CHEAP** | GLM-5 (via Z.AI) 🆕 | $0.5/1M | Daily 10AM | 128K output, newest flagship | -| | GLM-4.7 | $0.6/1M | Daily 10AM | Budget backup | -| | MiniMax M2.5 🆕 | $0.3/1M input | 5-hour rolling | Reasoning + agentic tasks | -| | MiniMax M2.1 | $0.2/1M | 5-hour rolling | Cheapest option | -| | Kimi K2.5 (Moonshot API) 🆕 | Pay-per-use | None | Direct Moonshot API access | -| | Kimi K2 | $9/mo flat | 10M tokens/mo | Predictable cost | -| **🆓 FREE** | iFlow | **$0** | Unlimited | 5 models unlimited | -| | Qwen | **$0** | Unlimited | 4 models unlimited | -| | Kiro | **$0** | Unlimited | Claude Sonnet/Haiku (AWS Builder) | -| | LongCat Flash-Lite 🆕 | **$0** (50M tok/day 🔥) | 1 RPS | Largest free quota on Earth | -| | Pollinations AI 🆕 | **$0** (no key needed) | 1 req/15s | GPT-5, Claude, DeepSeek, Llama 4 | -| | Cloudflare Workers AI 🆕 | **$0** (10K Neurons/day) | ~150 resp/day | 50+ models, global edge | -| | Scaleway AI 🆕 | **$0** (1M tokens total) | Rate limited | EU/GDPR, Qwen3 235B, Llama 70B | +| 层级 | 提供商 | 成本 | 配额重置 | 适用场景 | +| ------------------- | --------------------------- | ---------------------------- | ---------------- | ---------------------------------- | +| **💳 SUBSCRIPTION** | Claude Code (Pro) | $20/月 | 5 小时 + 每周 | 已经订阅的用户 | +| | Codex (Plus/Pro) | $20-200/月 | 5 小时 + 每周 | OpenAI 用户 | +| | Gemini CLI | **免费** | 180K/月 + 1K/天 | 所有人 | +| | GitHub Copilot | $10-19/月 | 每月 | GitHub 用户 | +| **🔑 API KEY** | NVIDIA NIM | **免费**(开发期永久) | 约 40 RPM | 70+ 个开源模型 | +| | Cerebras | **免费**(100 万 tok/天) | 60K TPM / 30 RPM | 全球最快之一 | +| | Groq | **免费**(30 RPM) | 14.4K RPD | 超高速 Llama/Gemma | +| | DeepSeek V3.2 | 每 100 万 $0.27/$1.10 | 无 | 性价比最佳的推理 | +| | xAI Grok-4 Fast | **每 100 万 $0.20/$0.50** 🆕 | 无 | 最快速度 + tool calling,超低价 | +| | xAI Grok-4(standard) | 每 100 万 $0.20/$1.50 🆕 | 无 | xAI 的旗舰推理模型 | +| | Mistral | 免费试用 + 付费 | 有速率限制 | 欧洲 AI | +| | OpenRouter | 按量付费 | 无 | 聚合 100+ 个模型 | +| **💰 CHEAP** | GLM-5(via Z.AI)🆕 | $0.5/100 万 | 每天 10:00 | 128K 输出,最新旗舰 | +| | GLM-4.7 | $0.6/100 万 | 每天 10:00 | 预算型备选 | +| | MiniMax M2.5 🆕 | 输入 $0.3/100 万 | 滚动 5 小时 | 推理 + agentic tasks | +| | MiniMax M2.1 | $0.2/100 万 | 滚动 5 小时 | 最便宜的选择 | +| | Kimi K2.5 (Moonshot API) 🆕 | 按量付费 | 无 | 直连 Moonshot API | +| | Kimi K2 | $9/月固定 | 1000 万 tok/月 | 成本可预测 | +| **🆓 FREE** | Qoder | **$0** | 无限制 | 5 个模型无限用 | +| | Qwen | **$0** | 无限制 | 4 个模型无限用 | +| | Kiro | **$0** | 无限制 | Claude Sonnet/Haiku(AWS Builder) | +| | LongCat Flash-Lite 🆕 | **$0**(5000 万 tok/天 🔥) | 1 RPS | 地球上最大的免费配额 | +| | Pollinations AI 🆕 | **$0**(无需 key) | 1 次请求/15 秒 | GPT-5、Claude、DeepSeek、Llama 4 | +| | Cloudflare Workers AI 🆕 | **$0**(10K Neurons/天) | 约 150 次响应/天 | 50+ 个模型,全球边缘 | +| | Scaleway AI 🆕 | **$0**(总计 100 万 tokens) | 有速率限制 | EU/GDPR,Qwen3 235B,Llama 70B | -> 🆕 **New models added (Mar 2026):** Grok-4 Fast family at $0.20/$0.50/M (benchmarked at 1143ms — 30% faster than Gemini 2.5 Flash), GLM-5 via Z.AI with 128K output, MiniMax M2.5 reasoning, DeepSeek V3.2 updated pricing, Kimi K2.5 via Moonshot direct API. +> 🆕 **新增模型(2026 年 3 月):** Grok-4 Fast 系列价格低至 $0.20/$0.50 每百万 token(基准延迟 1143ms,比 Gemini 2.5 Flash 快约 30%),以及通过 Z.AI 提供、拥有 128K 输出能力的 GLM-5,面向推理的新 MiniMax M2.5,更新定价后的 DeepSeek V3.2,以及通过 Moonshot 直连 API 使用的 Kimi K2.5。 -**💡 $0 Combo Stack — The Complete Free Setup:** +**💡 $0 Combo 栈:完整免费配置** ``` -# 🆓 Ultimate Free Stack 2026 — 11 Providers, $0 Forever -Kiro (kr/) → Claude Sonnet/Haiku UNLIMITED -iFlow (if/) → kimi-k2-thinking, qwen3-coder-plus, deepseek-r1 UNLIMITED -LongCat Lite (lc/) → LongCat-Flash-Lite — 50M tokens/day 🔥 -Pollinations (pol/) → GPT-5, Claude, DeepSeek, Llama 4 — no key needed -Qwen (qw/) → qwen3-coder-plus, qwen3-coder-flash, qwen3-coder-next UNLIMITED -Gemini (gemini/) → Gemini 2.5 Flash — 1,500 req/day free API key -Cloudflare AI (cf/) → Llama 70B, Gemma 3, Mistral — 10K Neurons/day -Scaleway (scw/) → Qwen3 235B, Llama 70B — 1M free tokens (EU) -Groq (groq/) → Llama/Gemma ultra-fast — 14.4K req/day -NVIDIA NIM (nvidia/) → 70+ open models — 40 RPM forever -Cerebras (cerebras/) → Llama/Qwen world-fastest — 1M tok/day +# 🆓 Ultimate Free Stack 2026 — 11 家提供商,永久免费 +Kiro (kr/) → Claude Sonnet/Haiku 无限使用 +Qoder (if/) → kimi-k2-thinking、qwen3-coder-plus、deepseek-r1 无限使用 +LongCat Lite (lc/) → LongCat-Flash-Lite — 每天 5000 万 tokens 🔥 +Pollinations (pol/) → GPT-5、Claude、DeepSeek、Llama 4 — 无需 key +Qwen (qw/) → qwen3-coder-plus、qwen3-coder-flash、qwen3-coder-next 无限使用 +Gemini (gemini/) → Gemini 2.5 Flash — 每天免费 1500 次请求 +Cloudflare AI (cf/) → Llama 70B、Gemma 3、Mistral — 每天 10K Neurons +Scaleway (scw/) → Qwen3 235B、Llama 70B — 100 万免费 tokens(EU) +Groq (groq/) → 超高速 Llama/Gemma — 每天 14.4K 次请求 +NVIDIA NIM (nvidia/) → 70+ 开源模型 — 永久 40 RPM +Cerebras (cerebras/) → 超高速 Llama/Qwen — 每天 100 万 tokens ``` -**Zero cost. Never stops coding.** Configure this as one OmniRoute combo and all fallbacks happen automatically — no manual switching ever. +**零成本,永不中断编码。** 将这些模型配置为一个 OmniRoute combo 后,所有回退都会自动进行,无需手动切换。 --- --- -## 🆓 Free Models — What You Actually Get +## 🆓 免费模型:你真正能用到的内容 -> All models below are **100% free with zero credit card required**. OmniRoute auto-routes between them when one quota runs out — combine them all for an unbreakable $0 combo. +> 以下所有模型都**100% 免费,且不需要信用卡**。当某个配额耗尽时,OmniRoute 会自动在它们之间切换路由,把它们组合起来就能得到一个几乎不会中断的 $0 combo。 -### 🔵 CLAUDE MODELS (via Kiro — AWS Builder ID) +### 🔵 CLAUDE MODELS(通过 Kiro 和 AWS Builder ID) -| Model | Prefix | Limit | Rate Limit | -| ------------------- | ------ | ------------- | --------------------- | -| `claude-sonnet-4.5` | `kr/` | **Unlimited** | No reported daily cap | -| `claude-haiku-4.5` | `kr/` | **Unlimited** | No reported daily cap | -| `claude-opus-4.6` | `kr/` | **Unlimited** | Latest Opus via Kiro | +| 模型 | 前缀 | 限额 | 速率限制 | +| ------------------- | ----- | ---------- | ------------------------- | +| `claude-sonnet-4.5` | `kr/` | **无限制** | 未报告每日上限 | +| `claude-haiku-4.5` | `kr/` | **无限制** | 未报告每日上限 | +| `claude-opus-4.6` | `kr/` | **无限制** | 通过 Kiro 使用最新的 Opus | -### 🟢 IFLOW MODELS (Free OAuth — No Credit Card) +### 🟢 QODER MODELS(免费 OAuth — 无需信用卡) -| Model | Prefix | Limit | Rate Limit | -| ------------------ | ------ | ------------- | --------------- | -| `kimi-k2-thinking` | `if/` | **Unlimited** | No reported cap | -| `qwen3-coder-plus` | `if/` | **Unlimited** | No reported cap | -| `deepseek-r1` | `if/` | **Unlimited** | No reported cap | -| `minimax-m2.1` | `if/` | **Unlimited** | No reported cap | -| `kimi-k2` | `if/` | **Unlimited** | No reported cap | +| 模型 | 前缀 | 限额 | 速率限制 | +| ------------------ | ----- | ---------- | ---------- | +| `kimi-k2-thinking` | `if/` | **无限制** | 未报告上限 | +| `qwen3-coder-plus` | `if/` | **无限制** | 未报告上限 | +| `deepseek-r1` | `if/` | **无限制** | 未报告上限 | +| `minimax-m2.1` | `if/` | **无限制** | 未报告上限 | +| `kimi-k2` | `if/` | **无限制** | 未报告上限 | -### 🟡 QWEN MODELS (Device Code Auth) +### 🟡 QWEN MODELS(设备码认证) -| Model | Prefix | Limit | Rate Limit | -| ------------------- | ------ | ------------- | ------------------- | -| `qwen3-coder-plus` | `qw/` | **Unlimited** | No reported cap | -| `qwen3-coder-flash` | `qw/` | **Unlimited** | No reported cap | -| `qwen3-coder-next` | `qw/` | **Unlimited** | No reported cap | -| `vision-model` | `qw/` | **Unlimited** | Multimodal (images) | +| 模型 | 前缀 | 限额 | 速率限制 | +| ------------------- | ----- | ---------- | -------------- | +| `qwen3-coder-plus` | `qw/` | **无限制** | 未报告上限 | +| `qwen3-coder-flash` | `qw/` | **无限制** | 未报告上限 | +| `qwen3-coder-next` | `qw/` | **无限制** | 未报告上限 | +| `vision-model` | `qw/` | **无限制** | 多模态(图像) | -### 🟣 GEMINI CLI (Google OAuth) +### 🟣 GEMINI CLI(Google OAuth) -| Model | Prefix | Limit | Rate Limit | -| ------------------------ | ------ | --------------------------- | ------------- | -| `gemini-3-flash-preview` | `gc/` | **180K tok/month** + 1K/day | Monthly reset | -| `gemini-2.5-pro` | `gc/` | 180K/month (shared pool) | High quality | +| 模型 | 前缀 | 限额 | 速率限制 | +| ------------------------ | ----- | --------------------------- | ---------- | +| `gemini-3-flash-preview` | `gc/` | **每月 180K tok** + 每天 1K | 按月重置 | +| `gemini-2.5-pro` | `gc/` | 每月 180K(共享池) | 高质量模型 | -### ⚫ NVIDIA NIM (Free API Key — build.nvidia.com) +### ⚫ NVIDIA NIM(免费 API Key — build.nvidia.com) -| Tier | Daily Limit | Rate Limit | Notes | -| ---------- | ------------ | ----------- | ------------------------------------------------------ | -| Free (Dev) | No token cap | **~40 RPM** | 70+ models; transitioning to pure rate limits mid-2025 | +| 层级 | 每日限额 | 速率限制 | 说明 | +| ----------- | ------------- | ------------- | ------------------------------------------ | +| Free(Dev) | 无 token 上限 | **约 40 RPM** | 70+ 个模型;计划在 2025 年中转为纯速率限制 | -Popular free models: `moonshotai/kimi-k2.5` (Kimi K2.5), `z-ai/glm4.7` (GLM 4.7), `deepseek-ai/deepseek-v3.2` (DeepSeek V3.2), `nvidia/llama-3.3-70b-instruct`, `deepseek/deepseek-r1` +热门免费模型:`moonshotai/kimi-k2.5`(Kimi K2.5)、`z-ai/glm4.7`(GLM 4.7)、`deepseek-ai/deepseek-v3.2`(DeepSeek V3.2)、`nvidia/llama-3.3-70b-instruct`、`deepseek/deepseek-r1` -### ⚪ CEREBRAS (Free API Key — inference.cerebras.ai) +### ⚪ CEREBRAS(免费 API Key — inference.cerebras.ai) -| Tier | Daily Limit | Rate Limit | Notes | -| ---- | ----------------- | ---------------- | ------------------------------------------- | -| Free | **1M tokens/day** | 60K TPM / 30 RPM | World's fastest LLM inference; resets daily | +| 层级 | 每日限额 | 速率限制 | 说明 | +| ---- | ---------------------- | ---------------- | --------------------------------- | +| Free | **每天 100 万 tokens** | 60K TPM / 30 RPM | 全球最快的 LLM 推理之一;每日重置 | -Available free: `llama-3.3-70b`, `llama-3.1-8b`, `deepseek-r1-distill-llama-70b` +可用免费模型:`llama-3.3-70b`、`llama-3.1-8b`、`deepseek-r1-distill-llama-70b` -### 🔴 GROQ (Free API Key — console.groq.com) +### 🔴 GROQ(免费 API Key — console.groq.com) -| Tier | Daily Limit | Rate Limit | Notes | -| ---- | ------------- | ---------------- | ----------------------------------------- | -| Free | **14.4K RPD** | 30 RPM per model | No credit card; 429 on limit, not charged | +| 层级 | 每日限额 | 速率限制 | 说明 | +| ---- | ------------- | ------------- | ------------------------------------ | +| Free | **14.4K RPD** | 每模型 30 RPM | 无需信用卡;超限时返回 429,不会扣费 | -Available free: `llama-3.3-70b-versatile`, `gemma2-9b-it`, `mixtral-8x7b`, `whisper-large-v3` +可用免费模型:`llama-3.3-70b-versatile`、`gemma2-9b-it`、`mixtral-8x7b`、`whisper-large-v3` -### 🔴 LONGCAT AI (Free API Key — longcat.chat) 🆕 +### 🔴 LONGCAT AI(免费 API Key — longcat.chat)🆕 -| Model | Prefix | Daily Free Quota | Notes | -| ----------------------------- | ------ | ----------------- | ----------------------- | -| `LongCat-Flash-Lite` | `lc/` | **50M tokens** 💥 | Largest free quota ever | -| `LongCat-Flash-Chat` | `lc/` | 500K tokens | Multi-turn chat | -| `LongCat-Flash-Thinking` | `lc/` | 500K tokens | Reasoning / CoT | -| `LongCat-Flash-Thinking-2601` | `lc/` | 500K tokens | Jan 2026 version | -| `LongCat-Flash-Omni-2603` | `lc/` | 500K tokens | Multimodal | +| 模型 | 前缀 | 每日免费额度 | 说明 | +| ----------------------------- | ----- | --------------------- | ------------------ | +| `LongCat-Flash-Lite` | `lc/` | **5000 万 tokens** 💥 | 史上最大的免费额度 | +| `LongCat-Flash-Chat` | `lc/` | 500K tokens | 多轮对话 | +| `LongCat-Flash-Thinking` | `lc/` | 500K tokens | 推理 / CoT | +| `LongCat-Flash-Thinking-2601` | `lc/` | 500K tokens | 2026 年 1 月版本 | +| `LongCat-Flash-Omni-2603` | `lc/` | 500K tokens | 多模态 | -> 100% free while in public beta. Sign up at [longcat.chat](https://longcat.chat) with email or phone. Resets daily 00:00 UTC. +> 公测期间 100% 免费。可在 [longcat.chat](https://longcat.chat) 使用邮箱或手机号注册。每日 UTC 00:00 重置。 -### 🟢 POLLINATIONS AI (No API Key Required) 🆕 +### 🟢 POLLINATIONS AI(无需 API Key)🆕 -| Model | Prefix | Rate Limit | Provider Behind | +| 模型 | 前缀 | 速率限制 | 背后提供商 | | ---------- | ------ | ---------- | ------------------ | -| `openai` | `pol/` | 1 req/15s | GPT-5 | -| `claude` | `pol/` | 1 req/15s | Anthropic Claude | -| `gemini` | `pol/` | 1 req/15s | Google Gemini | -| `deepseek` | `pol/` | 1 req/15s | DeepSeek V3 | -| `llama` | `pol/` | 1 req/15s | Meta Llama 4 Scout | -| `mistral` | `pol/` | 1 req/15s | Mistral AI | +| `openai` | `pol/` | 1 次/15 秒 | GPT-5 | +| `claude` | `pol/` | 1 次/15 秒 | Anthropic Claude | +| `gemini` | `pol/` | 1 次/15 秒 | Google Gemini | +| `deepseek` | `pol/` | 1 次/15 秒 | DeepSeek V3 | +| `llama` | `pol/` | 1 次/15 秒 | Meta Llama 4 Scout | +| `mistral` | `pol/` | 1 次/15 秒 | Mistral AI | -> ✨ **Zero friction:** No signup, no API key. Add the Pollinations provider with an empty key field and it works immediately. +> ✨ **零门槛:** 无需注册、无需 API key。添加 Pollinations 提供商时把 key 字段留空即可立即使用。 -### 🟠 CLOUDFLARE WORKERS AI (Free API Key — cloudflare.com) 🆕 +### 🟠 CLOUDFLARE WORKERS AI(免费 API Key — cloudflare.com)🆕 -| Tier | Daily Neurons | Equivalent Usage | Notes | -| ---- | ------------- | --------------------------------------- | ----------------------- | -| Free | **10,000** | ~150 LLM resp / 500s audio / 15K embeds | Global edge, 50+ models | +| 层级 | 每日 Neurons | 折算用量 | 说明 | +| ---- | ------------ | -------------------------------------------- | ---------------------- | +| Free | **10,000** | 约 150 次 LLM 响应 / 500 秒音频 / 15K embeds | 全球边缘网络,50+ 模型 | -Popular free models: `@cf/meta/llama-3.3-70b-instruct`, `@cf/google/gemma-3-12b-it`, `@cf/openai/whisper-large-v3-turbo` (free audio!), `@cf/qwen/qwen2.5-coder-15b-instruct` +热门免费模型:`@cf/meta/llama-3.3-70b-instruct`、`@cf/google/gemma-3-12b-it`、`@cf/openai/whisper-large-v3-turbo`(免费音频!)、`@cf/qwen/qwen2.5-coder-15b-instruct` -> Requires API Token + Account ID from [dash.cloudflare.com](https://dash.cloudflare.com). Store Account ID in provider settings. +> 需要来自 [dash.cloudflare.com](https://dash.cloudflare.com) 的 API Token 和 Account ID。请在 provider settings 中保存 Account ID。 -### 🟣 SCALEWAY AI (1M Free Tokens — scaleway.com) 🆕 +### 🟣 SCALEWAY AI(100 万免费 Tokens — scaleway.com)🆕 -| Tier | Free Quota | Location | Notes | -| ---- | ------------- | ------------ | ----------------------------------- | -| Free | **1M tokens** | 🇫🇷 Paris, EU | No credit card needed within limits | +| 层级 | 免费额度 | 地区 | 说明 | +| ---- | ----------------- | ------------ | ------------------ | +| Free | **100 万 tokens** | 🇫🇷 Paris, EU | 在限额内无需信用卡 | -Available free: `qwen3-235b-a22b-instruct-2507` (Qwen3 235B!), `llama-3.1-70b-instruct`, `mistral-small-3.2-24b-instruct-2506`, `deepseek-v3-0324` +可用免费模型:`qwen3-235b-a22b-instruct-2507`(Qwen3 235B!)、`llama-3.1-70b-instruct`、`mistral-small-3.2-24b-instruct-2506`、`deepseek-v3-0324` -> EU/GDPR compliant. Get API key at [console.scaleway.com](https://console.scaleway.com). +> 符合 EU/GDPR。可在 [console.scaleway.com](https://console.scaleway.com) 获取 API key。 -> **💡 The Ultimate Free Stack (11 Providers, $0 Forever):** +> **💡 Ultimate Free Stack(11 家提供商,永久免费):** > > ``` -> Kiro (kr/) → Claude Sonnet/Haiku UNLIMITED -> iFlow (if/) → kimi-k2-thinking, qwen3-coder-plus, deepseek-r1 UNLIMITED -> LongCat Lite (lc/) → LongCat-Flash-Lite — 50M tokens/day 🔥 -> Pollinations (pol/) → GPT-5, Claude, DeepSeek, Llama 4 — no key needed -> Qwen (qw/) → qwen3-coder models UNLIMITED -> Gemini (gemini/) → Gemini 2.5 Flash — 1,500 req/day free -> Cloudflare AI (cf/) → 50+ models — 10K Neurons/day -> Scaleway (scw/) → Qwen3 235B, Llama 70B — 1M free tokens (EU) -> Groq (groq/) → Llama/Gemma — 14.4K req/day ultra-fast -> NVIDIA NIM (nvidia/) → 70+ open models — 40 RPM forever -> Cerebras (cerebras/) → Llama/Qwen world-fastest — 1M tok/day +> Kiro (kr/) → Claude Sonnet/Haiku 无限使用 +> Qoder (if/) → kimi-k2-thinking、qwen3-coder-plus、deepseek-r1 无限使用 +> LongCat Lite (lc/) → LongCat-Flash-Lite — 每天 5000 万 tokens 🔥 +> Pollinations (pol/) → GPT-5、Claude、DeepSeek、Llama 4 — 无需 key +> Qwen (qw/) → qwen3-coder 系列模型无限使用 +> Gemini (gemini/) → Gemini 2.5 Flash — 每天免费 1500 次 +> Cloudflare AI (cf/) → 50+ 模型 — 每天 10K Neurons +> Scaleway (scw/) → Qwen3 235B、Llama 70B — 100 万免费 tokens(EU) +> Groq (groq/) → Llama/Gemma — 每天 14.4K 次超高速请求 +> NVIDIA NIM (nvidia/) → 70+ 开源模型 — 永久 40 RPM +> Cerebras (cerebras/) → 超高速 Llama/Qwen — 每天 100 万 tokens > ``` -## 🎙️ Free Transcription Combo +## 🎙️ 免费转录 Combo -> Transcribe any audio/video for **$0** — Deepgram leads with $200 free, AssemblyAI $50 fallback, Groq Whisper as unlimited emergency backup. +> 将任意音频/视频转录为文本,成本 **$0**。Deepgram 提供 $200 免费额度作为主力,AssemblyAI 提供 $50 作为回退,Groq Whisper 则作为无限制的紧急备用。 -| Provider | Free Credits | Best Model | Rate Limit | -| ----------------- | ---------------------- | -------------------------------------------- | ---------------------------- | -| 🟢 **Deepgram** | **$200 free** (signup) | `nova-3` — best accuracy, 30+ languages | No RPM limit on free credits | -| 🔵 **AssemblyAI** | **$50 free** (signup) | `universal-3-pro` — chapters, sentiment, PII | No RPM limit on free credits | -| 🔴 **Groq** | **Free forever** | `whisper-large-v3` — OpenAI Whisper | 30 RPM (rate limited) | +| 提供商 | 免费额度 | 最佳模型 | 速率限制 | +| ----------------- | --------------------- | ------------------------------------ | --------------------- | +| 🟢 **Deepgram** | **免费 $200**(注册) | `nova-3` — 精度最佳,支持 30+ 种语言 | 免费额度下无 RPM 限制 | +| 🔵 **AssemblyAI** | **免费 $50**(注册) | `universal-3-pro` — 章节、情绪、PII | 免费额度下无 RPM 限制 | +| 🔴 **Groq** | **永久免费** | `whisper-large-v3` — OpenAI Whisper | 30 RPM(有速率限制) | -**Suggested combo in `/dashboard/combos`:** +**在 `/dashboard/combos` 中建议这样配置 combo:** ``` Name: free-transcription Strategy: Priority Nodes: - [1] deepgram/nova-3 → uses $200 free first - [2] assemblyai/universal-3-pro → fallback when Deepgram credits run out - [3] groq/whisper-large-v3 → free forever, emergency fallback + [1] deepgram/nova-3 → 优先使用 $200 免费额度 + [2] assemblyai/universal-3-pro → Deepgram 额度用尽时回退 + [3] groq/whisper-large-v3 → 永久免费,作为紧急备用 ``` -Then in `/dashboard/media` → **Transcription** tab: upload any audio or video file → select your combo endpoint → get transcription in supported formats. +然后在 `/dashboard/media` → **Transcription** 标签页中上传音频或视频文件,选择你的 combo 端点,即可获得支持格式的转录结果。 -## 💡 Key Features +## 💡 主要功能 -OmniRoute v2.0 is built as an operational platform, not just a relay proxy. +OmniRoute v2.0 的定位是一个可运维的平台,而不只是一个转发代理。 -### 🆕 New — ClawRouter-Inspired Improvements (Mar 2026) +### 🆕 新增:受 ClawRouter 启发的改进(2026 年 3 月) -| Feature | What It Does | -| ------------------------------------ | ------------------------------------------------------------------------------------------- | -| ⚡ **Grok-4 Fast Family** | xAI models at $0.20/$0.50/M — benchmarked 1143ms (30% faster than Gemini 2.5 Flash) | -| 🧠 **GLM-5 via Z.AI** | 128K output context, $0.5/1M — newest flagship from the GLM family | -| 🔮 **MiniMax M2.5** | Reasoning + agentic tasks at $0.30/1M — significant upgrade from M2.1 | -| 🎯 **toolCalling Flag per Model** | Per-model `toolCalling: true/false` in registry — AutoCombo skips non-tool-capable models | -| 🌍 **Multilingual Intent Detection** | PT/ZH/ES/AR keywords in AutoCombo scoring — better model selection for non-English content | -| 📊 **Benchmark-Driven Fallbacks** | Real p95 latency from live requests feeds combo scoring — AutoCombo learns from actual data | -| 🔁 **Request Deduplication** | Content-hash based dedup window — multi-agent safe, prevents duplicate charges | -| 🔌 **Pluggable RouterStrategy** | Extensible `RouterStrategy` interface — add custom routing logic as plugins | +| 功能 | 作用 | +| ---------------------------------- | -------------------------------------------------------------------------------------------- | +| ⚡ **Grok-4 Fast Family** | xAI 模型价格低至 $0.20/$0.50 每百万 token,基准延迟 1143ms,比 Gemini 2.5 Flash 快约 30% | +| 🧠 **GLM-5 via Z.AI** | 128K 输出上下文,$0.5/1M,是 GLM 系列的新旗舰 | +| 🔮 **MiniMax M2.5** | 推理与 agentic 任务仅需 $0.30/1M,相比 M2.1 有明显升级 | +| 🎯 **按模型配置 toolCalling 标志** | 在注册表中为每个模型单独设置 `toolCalling: true/false`,AutoCombo 会跳过不支持工具调用的模型 | +| 🌍 **多语言意图检测** | 在 AutoCombo 打分中加入 PT/ZH/ES/AR 关键词,提升非英文内容的模型选择效果 | +| 📊 **基准驱动的回退** | 使用真实请求得到的 p95 延迟参与 combo 打分,AutoCombo 会从真实数据中学习 | +| 🔁 **请求去重** | 基于内容哈希的去重窗口,多智能体安全,避免重复计费 | +| 🔌 **可插拔 RouterStrategy** | 可扩展的 `RouterStrategy` 接口,可通过插件加入自定义路由逻辑 | -### 🚀 Previous v2.0.9+ — Playground, CLI Fingerprints & ACP +### 🚀 此前 v2.0.9+ 的能力:Playground、CLI 指纹与 ACP -| Feature | What It Does | -| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing | -| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** | -| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw + 9 more), process spawner, `/api/acp/agents` endpoint | -| 🤖 **ACP Agents Dashboard** | Debug › Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool. **OpenCode** users get a "Download opencode.json" button that auto-generates a ready-to-use config with all available models. | -| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator | -| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID | -| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart | +| 功能 | 作用 | +| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 🎮 **Model Playground** | 在 Dashboard 中直接测试任意模型,支持 provider/model/endpoint 选择器、Monaco Editor、流式输出、终止请求和耗时显示 | +| 🔏 **CLI Fingerprint Matching** | 按提供商匹配原生 CLI 的请求头和请求体顺序,可在 Settings > Security 中按提供商开关,且**保留你的代理 IP** | +| 🤝 **ACP Support (Agent Client Protocol)** | 支持 CLI agent 发现(Codex、Claude、Goose、Gemini CLI、OpenClaw 等共 10+)、进程启动器以及 `/api/acp/agents` 端点 | +| 🤖 **ACP Agents Dashboard** | Debug › Agents 页面会以网格展示 14 个 agents 的安装状态、版本和自定义 agent 表单。**OpenCode** 用户还会获得“Download opencode.json”按钮,可自动生成包含全部可用模型的即用配置。 | +| 🔧 **自定义模型 `apiFormat` 路由** | 带有 `apiFormat: "responses"` 的自定义模型现在可正确路由到 Responses API 翻译器 | +| 🏢 **Codex 工作区隔离** | 同一邮箱下支持多个 Codex workspace,OAuth 会按 workspace ID 正确区分连接 | +| 🔄 **Electron 自动更新** | 桌面应用会检查更新,并在重启时自动安装 | -### 🤖 Agent & Protocol Operations (v2.0) +### 🤖 Agent 与协议运维(v2.0) -| Feature | What It Does | -| ------------------------------------- | -------------------------------------------------------------------------------------------------- | -| 🔧 **MCP Server (16 tools)** | IDE/agent tools via 3 transports: stdio, SSE (`/api/mcp/sse`), Streamable HTTP (`/api/mcp/stream`) | -| 🤝 **A2A Server (JSON-RPC + SSE)** | Agent-to-agent task execution with sync and streaming flows | -| 🧭 **Consolidated Endpoints Page** | Tabbed management page with Endpoint Proxy, MCP, A2A, and API Endpoints tabs | -| 🎚️ **Service Enable/Disable Toggles** | ON/OFF switches for MCP and A2A with settings persistence (default: OFF) | -| 🛰️ **MCP Runtime Heartbeat** | Real process status (pid, uptime, heartbeat age, transport, scope mode) | -| 📋 **MCP Audit Trail** | Filterable audit logs with success/failure and key attribution | -| 🔐 **MCP Scope Enforcement** | 9 granular scope permissions for controlled tool access | -| 📡 **A2A Task Lifecycle Management** | List/filter tasks, inspect events/artifacts, cancel running tasks | -| 📋 **Agent Card Discovery** | `/.well-known/agent.json` for client auto-discovery | -| 🧪 **Protocol E2E Test Harness** | Real MCP SDK + A2A client flows in `test:protocols:e2e` | -| ⚙️ **Operational Controls** | Switch combo, apply resilience profiles, reset breakers from one control surface | +| 功能 | 作用 | +| ---------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| 🔧 **MCP Server (16 tools)** | 通过 3 种传输方式为 IDE/agent 提供工具:stdio、SSE(`/api/mcp/sse`)、Streamable HTTP(`/api/mcp/stream`) | +| 🤝 **A2A Server (JSON-RPC + SSE)** | 支持同步与流式流程的 agent-to-agent 任务执行 | +| 🧭 **统一 Endpoints 页面** | 以标签页形式管理 Endpoint Proxy、MCP、A2A 和 API Endpoints | +| 🎚️ **服务启用/停用开关** | 为 MCP 和 A2A 提供 ON/OFF 开关并持久化设置(默认:OFF) | +| 🛰️ **MCP 运行时心跳** | 展示真实进程状态(pid、运行时长、心跳年龄、传输方式、scope 模式) | +| 📋 **MCP 审计轨迹** | 可过滤的审计日志,包含成功/失败结果与 key 归属信息 | +| 🔐 **MCP Scope 强制控制** | 9 个细粒度 scope 权限,用于受控工具访问 | +| 📡 **A2A 任务生命周期管理** | 列出/过滤任务,查看事件与 artifact,取消运行中的任务 | +| 📋 **Agent Card 发现** | 通过 `/.well-known/agent.json` 支持客户端自动发现 | +| 🧪 **协议 E2E 测试框架** | 在 `test:protocols:e2e` 中运行真实 MCP SDK + A2A 客户端流程 | +| ⚙️ **运维控制** | 在一个控制面统一切换 combo、应用 resilience profile、重置 breaker | -### 🧠 Routing & Intelligence +### 🧠 路由与智能 -| Feature | What It Does | -| ---------------------------------- | ------------------------------------------------------------------------ | -| 🎯 **Smart 4-Tier Fallback** | Auto-route: Subscription → API Key → Cheap → Free | -| 📊 **Real-Time Quota Tracking** | Live token count + reset countdown per provider | -| 🔄 **Format Translation** | OpenAI ↔ Claude ↔ Gemini ↔ Responses with schema-safe conversions | -| 👥 **Multi-Account Support** | Multiple accounts per provider with intelligent selection | -| 🔄 **Auto Token Refresh** | OAuth tokens refresh automatically with retry | -| 🎨 **Custom Combos** | 6 balancing strategies + fallback chain control | -| 🌐 **Wildcard Router** | `provider/*` dynamic routing | -| 🧠 **Thinking Budget Controls** | Passthrough, auto, custom, and adaptive reasoning limits | -| 🔀 **Model Aliases** | Built-in + custom model aliasing and migration safety | -| ⚡ **Background Degradation** | Route low-priority background tasks to cheaper models | -| 🧪 **Task-Aware Smart Routing** | Auto-select model by content type (coding/vision/analysis/summarization) | -| 🔄 **A2A Agent Workflows** | Deterministic FSM orchestrator for stateful multi-step agent executions | -| 🔀 **Adaptive Routing** | Dynamic strategy override based on token volume and prompt complexity | -| 🎲 **Provider Diversity** | Shannon entropy scoring balancing auto-combo traffic distribution | -| 💬 **System Prompt Injection** | Global behavior controls applied consistently | -| 📄 **Responses API Compatibility** | Full `/v1/responses` support for Codex and advanced agentic workflows | +| 功能 | 作用 | +| --------------------------- | -------------------------------------------------------------- | +| 🎯 **智能 4 层后备** | 自动路由:Subscription → API Key → Cheap → Free | +| 📊 **实时配额跟踪** | 按提供商展示实时 token 计数与重置倒计时 | +| 🔄 **格式翻译** | OpenAI ↔ Claude ↔ Gemini ↔ Responses,带 schema-safe 转换 | +| 👥 **多账户支持** | 每个提供商支持多个账户并进行智能选择 | +| 🔄 **自动 Token 刷新** | OAuth token 自动刷新并支持重试 | +| 🎨 **自定义 Combo** | 6 种均衡策略 + 后备链控制 | +| 🌐 **通配符路由器** | 支持 `provider/*` 动态路由 | +| 🧠 **Thinking 预算控制** | 支持 passthrough、auto、custom 和 adaptive 推理限制 | +| 🔀 **模型别名** | 内置 + 自定义模型别名与安全迁移 | +| ⚡ **后台降级** | 将低优先级后台任务路由到更便宜的模型 | +| 🧪 **任务感知智能路由** | 按内容类型自动选择模型(coding/vision/analysis/summarization) | +| 🔄 **A2A Agent 工作流** | 面向有状态多步骤 agent 执行的确定性 FSM orchestrator | +| 🔀 **自适应路由** | 根据 token 体量与提示词复杂度动态覆盖策略 | +| 🎲 **提供商多样性** | 使用 Shannon entropy 评分平衡 auto-combo 流量分布 | +| 💬 **System Prompt 注入** | 统一应用全局行为控制 | +| 📄 **Responses API 兼容性** | 为 Codex 和高级 agentic workflow 提供完整 `/v1/responses` 支持 | -### 🎵 Multi-Modal APIs +### 🎵 多模态 API -| Feature | What It Does | -| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 🖼️ **Image Generation** | `/v1/images/generations` with cloud and local backends | -| 📐 **Embeddings** | `/v1/embeddings` for search and RAG pipelines | -| 🎤 **Audio Transcription** | `/v1/audio/transcriptions` — 7 providers (Deepgram Nova 3, AssemblyAI, Groq Whisper, HuggingFace, ElevenLabs, OpenAI, Azure), auto-language detection, MP4/MP3/WAV support | -| 🔊 **Text-to-Speech** | `/v1/audio/speech` — 10 providers (ElevenLabs, OpenAI, Deepgram, Cartesia, PlayHT, HuggingFace, Nvidia NIM, Inworld, Coqui, Tortoise) with correct error messages | -| 🎬 **Video Generation** | `/v1/videos/generations` (ComfyUI + SD WebUI workflows) | -| 🎵 **Music Generation** | `/v1/music/generations` (ComfyUI workflows) | -| 🛡️ **Moderations** | `/v1/moderations` safety checks | -| 🔀 **Reranking** | `/v1/rerank` for relevance scoring | -| 🔍 **Web Search** 🆕 | `/v1/search` — 5 providers (Serper, Brave, Perplexity, Exa, Tavily), 6,500+ free/month, auto-failover, cache | +| 功能 | 作用 | +| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 🖼️ **图像生成** | `/v1/images/generations`,支持 cloud 和本地后端 | +| 📐 **Embeddings** | `/v1/embeddings`,适用于搜索和 RAG pipeline | +| 🎤 **音频转录** | `/v1/audio/transcriptions`,支持 7 家提供商(Deepgram Nova 3、AssemblyAI、Groq Whisper、HuggingFace、ElevenLabs、OpenAI、Azure),自动语言检测,支持 MP4/MP3/WAV | +| 🔊 **Text-to-Speech** | `/v1/audio/speech`,支持 10 家提供商(ElevenLabs、OpenAI、Deepgram、Cartesia、PlayHT、HuggingFace、Nvidia NIM、Inworld、Coqui、Tortoise),并返回正确错误信息 | +| 🎬 **视频生成** | `/v1/videos/generations`(ComfyUI + SD WebUI workflows) | +| 🎵 **音乐生成** | `/v1/music/generations`(ComfyUI workflows) | +| 🛡️ **Moderations** | `/v1/moderations` 安全检查 | +| 🔀 **重排序** | `/v1/rerank` 用于相关性评分 | +| 🔍 **Web Search** 🆕 | `/v1/search`,支持 5 家提供商(Serper、Brave、Perplexity、Exa、Tavily),每月 6,500+ 免费额度,支持自动故障转移与缓存 | -### 🛡️ Resilience, Security & Governance +### 🛡️ 弹性、安全与治理 -| Feature | What It Does | -| ----------------------------------- | -------------------------------------------------------------------------------------- | -| 🔌 **Circuit Breakers** | Per-model trip/recover with threshold controls | -| 🎯 **Endpoint-Aware Models** | Custom models declare supported endpoints + API format | -| 🛡️ **Anti-Thundering Herd** | Mutex + semaphore protections on retry/rate events | -| 🧠 **Semantic + Signature Cache** | Cost/latency reduction with two cache layers | -| ⚡ **Request Idempotency** | Duplicate protection window | -| 🔒 **TLS Fingerprint Spoofing** | Browser-like TLS fingerprint — **reduces bot detection and account flagging** | -| 🔏 **CLI Fingerprint Matching** | Matches native CLI request signatures — **reduces ban risk while preserving proxy IP** | -| 🌐 **IP Filtering** | Allowlist/blocklist control for exposed deployments | -| 📊 **Editable Rate Limits** | Configurable global/provider-level limits with persistence | -| 📉 **Graceful Degradation** | Multi-layer capability fallbacks protecting core gateway operations | -| 📜 **Config Audit Trail** | Diff-based change tracking preventing operational drift with simple rollbacks | -| ⏳ **Provider Health Sync** | Proactive token expiration monitoring triggering alerts before authorization failures | -| 🚪 **Auto-Disable Banned Accounts** | Operational circuit breaker sealing permanently blocked token accounts automatically | -| 🔑 **API Key Management + Scoping** | Secure key issuance/rotation and model/provider controls | -| 👁️ **Scoped API Key Reveal** 🆕 | Opt-in recovery of API keys via `ALLOW_API_KEY_REVEAL` | -| 🛡️ **Protected `/models`** | Optional auth gating and provider hiding for model catalog | +| 功能 | 作用 | +| ------------------------------ | ----------------------------------------------------------- | +| 🔌 **熔断器** | 按模型进行熔断/恢复,并支持阈值控制 | +| 🎯 **端点感知模型** | 自定义模型可声明支持的端点与 API 格式 | +| 🛡️ **防惊群** | 在重试/限流事件中使用 mutex + semaphore 保护 | +| 🧠 **语义 + 签名缓存** | 通过两层缓存降低成本与延迟 | +| ⚡ **请求幂等性** | 提供重复请求保护窗口 | +| 🔒 **TLS 指纹伪装** | 类浏览器 TLS 指纹,**降低 bot detection 与账户标记风险** | +| 🔏 **CLI 指纹匹配** | 匹配原生 CLI 请求签名,**在保留代理 IP 的同时降低封禁风险** | +| 🌐 **IP 过滤** | 为暴露部署提供 allowlist/blocklist 控制 | +| 📊 **可编辑速率限制** | 支持全局/提供商级限制并持久化 | +| 📉 **优雅降级** | 多层能力后备,保护核心网关操作 | +| 📜 **配置审计轨迹** | 基于 diff 的变更跟踪,防止运维漂移并支持简单回滚 | +| ⏳ **提供商健康同步** | 主动监控 token 过期,在认证失败前触发告警 | +| 🚪 **自动禁用被封账户** | 通过运维熔断器自动封存被永久阻止的 token 账户 | +| 🔑 **API 密钥管理 + 范围控制** | 安全地签发/轮换密钥,并控制模型/提供商范围 | +| 👁️ **定向 API 密钥显示** 🆕 | 通过 `ALLOW_API_KEY_REVEAL` 进行可选的 API 密钥恢复 | +| 🛡️ **受保护的 `/models`** | 为模型目录提供可选认证门控与提供商隐藏 | -### 📊 Observability & Analytics +### 📊 可观测性与分析 -| Feature | What It Does | -| -------------------------------- | ----------------------------------------------------- | -| 📝 **Request + Proxy Logging** | Full request/response and proxy logging | -| 📉 **Streamed Detailed Logs** 🆕 | Reconstructs SSE payload streams cleanly into the UI | -| 📋 **Unified Logs Dashboard** | Request, proxy, audit, and console views in one page | -| 🔍 **Request Telemetry** | p50/p95/p99 latency and request tracing | -| 🏥 **Health Dashboard** | Uptime, breaker states, lockouts, cache stats | -| 💰 **Cost Tracking** | Budget controls and per-model pricing visibility | -| 📈 **Analytics Visualizations** | Model/provider usage insights and trend views | -| 🧪 **Evaluation Framework** | Golden set testing with configurable match strategies | -| 📡 **Live Diagnostics** 🆕 | Semantic cache bypass for accurate combo live testing | +| 功能 | 作用 | +| ---------------------- | ------------------------------------------- | +| 📝 **请求 + 代理日志** | 完整的请求/响应与代理日志 | +| 📉 **流式详细日志** 🆕 | 将 SSE payload 流在 UI 中干净地重建出来 | +| 📋 **统一日志仪表盘** | 在同一页面查看请求、代理、审计与控制台视图 | +| 🔍 **请求遥测** | p50/p95/p99 延迟与请求追踪 | +| 🏥 **健康仪表盘** | 运行时长、breaker 状态、锁定、缓存统计 | +| 💰 **成本跟踪** | 预算控制与按模型定价可见性 | +| 📈 **分析可视化** | 模型/提供商用量洞察与趋势视图 | +| 🧪 **评估框架** | 支持可配置匹配策略的 Golden Set 测试 | +| 📡 **实时诊断** 🆕 | 通过绕过语义缓存来进行准确的 combo 实时测试 | -### ☁️ Deployment & Platform +### ☁️ 部署与平台 -| Feature | What It Does | -| ----------------------------- | --------------------------------------------------------- | -| 🌐 **Deploy Anywhere** | Localhost, VPS, Docker, Cloud environments | -| 🚇 **Cloudflare Tunnel** 🆕 | One-click Quick Tunnel integration from the dashboard | -| 💾 **Cloud Sync** | Configuration sync via cloud worker | -| 🔄 **Backup/Restore** | Export/import and disaster recovery flows | -| 🧙 **Onboarding Wizard** | First-run guided setup | -| 🔧 **CLI Tools Dashboard** | One-click setup for popular coding tools | -| 🎮 **Model Playground** | Test any provider/model/endpoint from the dashboard | -| 🔏 **CLI Fingerprint Toggle** | Per-provider fingerprint matching in Settings > Security | -| 🌐 **i18n (30 languages)** | Full dashboard + docs language support with RTL coverage | -| 🧹 **Clear All Models** | One-click model list clearing in provider details | -| 👁️ **Sidebar Controls** 🆕 | Hide components and integrations from Appearance Settings | -| 📋 **Issue Templates** | Standardized GitHub templates for bugs and features | -| 📂 **Custom Data Directory** | `DATA_DIR` override for storage location | +| 功能 | 作用 | +| --------------------------- | ---------------------------------------------------- | +| 🌐 **可部署到任意环境** | 支持 Localhost、VPS、Docker、Cloud 环境 | +| 🚇 **Cloudflare Tunnel** 🆕 | 从仪表盘一键集成 Quick Tunnel | +| 🔑 **API 密钥模型过滤** | 原生按分配的 Bearer 上下文角色过滤 `/v1/models` 响应 | +| ⚡ **智能缓存绕过** | 支持可配置 TTL 启发式与强制重新抓取控制 | +| 🔄 **备份/恢复** | 支持导出/导入与灾难恢复流程 | +| 🧙 **入门向导** | 首次运行引导配置 | +| 🔧 **CLI Tools 仪表盘** | 为常见编程工具提供一键设置 | +| 🎮 **模型 Playground** | 直接从仪表盘测试任意 provider/model/endpoint | +| 🔏 **CLI 指纹开关** | 在 Settings > Security 中按提供商开启指纹匹配 | +| 🌐 **i18n(30 种语言)** | 完整支持 Dashboard + docs 多语言,并覆盖 RTL | +| 🧹 **清空全部模型** | 在提供商详情中一键清空模型列表 | +| 👁️ **侧边栏控制** 🆕 | 从 Appearance Settings 隐藏组件与集成 | +| 📋 **Issue 模板** | 为 bug 和功能请求提供标准化 GitHub 模板 | +| 📂 **自定义数据目录** | 使用 `DATA_DIR` 覆盖存储位置 | -### Feature Deep Dive +### 功能深度解析 -#### Smart fallback with practical cost control +#### 带实际成本控制的智能回退 ```txt Combo: "my-coding-stack" @@ -1307,73 +1333,73 @@ Combo: "my-coding-stack" 4. if/kimi-k2-thinking ``` -When quota, rate, or health fails, OmniRoute automatically moves to the next candidate without manual switching. +当配额、速率限制或健康状态出现问题时,OmniRoute 会自动切换到下一个候选模型,无需手动干预。 -#### Protocol management that is visible and operable +#### 可见且可操作的协议管理 -- MCP + A2A are discoverable in UI and docs (not hidden) -- Protocol status APIs expose live operational data (`/api/mcp/*`, `/api/a2a/*`) -- Dashboards include actions for day-2 ops (combo toggles, breaker resets, task cancellation) +- MCP + A2A 会在 UI 和文档中明确展示,而不是隐藏功能 +- 协议状态 API 会暴露实时运行数据(`/api/mcp/*`、`/api/a2a/*`) +- Dashboard 内包含运维常用操作,如 combo 开关、熔断器重置、任务取消 -#### Translator + validation workflow +#### 翻译器与验证工作流 -The Translator area includes: +Translator 区域包含: -- **Playground**: request transformation checks -- **Chat Tester**: full request/response round-trip -- **Test Bench**: multiple cases in one run -- **Live Monitor**: real-time traffic view +- **Playground**:检查请求转换效果 +- **Chat Tester**:验证完整请求/响应往返 +- **Test Bench**:一次运行多组测试用例 +- **Live Monitor**:实时查看流量 -Plus protocol validation with real clients via `npm run test:protocols:e2e`. +此外,还可以通过 `npm run test:protocols:e2e` 使用真实客户端进行协议验证。 -> 📖 **[MCP Server README](open-sse/mcp-server/README.md)** — Tool reference, IDE configs, and client examples +> 📖 **[MCP Server README](../../../open-sse/mcp-server/README.md)** — 工具参考、IDE 配置和客户端示例 > -> 📖 **[A2A Server README](src/lib/a2a/README.md)** — Skills, JSON-RPC methods, streaming, and task lifecycle +> 📖 **[A2A Server README](../../../src/lib/a2a/README.md)** — Skills、JSON-RPC 方法、流式传输与任务生命周期 -## 🧪 Evaluations (Evals) +## 🧪 评估(Evals) -OmniRoute includes a built-in evaluation framework to test LLM response quality against a golden set. Access it via **Analytics → Evals** in the dashboard. +OmniRoute 内置了一个评估框架,可基于 golden set 测试 LLM 响应质量。可在 Dashboard 的 **Analytics → Evals** 中访问。 -### Built-in Golden Set +### 内置 Golden Set -The pre-loaded "OmniRoute Golden Set" contains test cases for: +预置的 “OmniRoute Golden Set” 包含以下测试用例: -- Greetings, math, geography, code generation -- JSON format compliance, translation, markdown generation -- Safety refusal (harmful content), counting, boolean logic +- 问候语、数学、地理、代码生成 +- JSON 格式合规性、翻译、Markdown 生成 +- 安全拒答(有害内容)、计数、布尔逻辑 -### Evaluation Strategies +### 评估策略 -| Strategy | Description | Example | -| ---------- | ------------------------------------------------ | -------------------------------- | -| `exact` | Output must match exactly | `"4"` | -| `contains` | Output must contain substring (case-insensitive) | `"Paris"` | -| `regex` | Output must match regex pattern | `"1.*2.*3"` | -| `custom` | Custom JS function returns true/false | `(output) => output.length > 10` | +| 策略 | 描述 | 示例 | +| ---------- | ------------------------------------ | -------------------------------- | +| `exact` | 输出必须完全一致 | `"4"` | +| `contains` | 输出必须包含某个子串(不区分大小写) | `"Paris"` | +| `regex` | 输出必须匹配某个正则表达式 | `"1.*2.*3"` | +| `custom` | 自定义 JS 函数返回 true/false | `(output) => output.length > 10` | --- -## 📖 Setup Guide +## 📖 配置指南 -### Protocol Setup (MCP + A2A) +### 协议配置(MCP + A2A)
-🧩 MCP Setup (Model Context Protocol) +🧩 MCP 配置(Model Context Protocol) -Start MCP transport in stdio mode: +以 stdio 模式启动 MCP transport: ```bash omniroute --mcp ``` -Recommended validation flow: +推荐验证流程: -1. Connect your MCP client over stdio. -2. Run `omniroute_get_health`. -3. Run `omniroute_list_combos`. -4. Open `/dashboard/mcp` to confirm heartbeat, activity, and audit. +1. 通过 stdio 连接你的 MCP client。 +2. 运行 `omniroute_get_health`。 +3. 运行 `omniroute_list_combos`。 +4. 打开 `/dashboard/endpoint`,确认心跳、活动和审计信息。 -Useful APIs for automation: +适合自动化的 API: - `GET /api/mcp/status` - `GET /api/mcp/tools` @@ -1383,15 +1409,15 @@ Useful APIs for automation:
-🤝 A2A Setup (Agent2Agent) +🤝 A2A 配置(Agent2Agent) -Discover the agent: +发现 agent: ```bash curl http://localhost:20128/.well-known/agent.json ``` -Send a task: +发送任务: ```bash curl -X POST http://localhost:20128/a2a \ @@ -1399,105 +1425,105 @@ curl -X POST http://localhost:20128/a2a \ -d '{"jsonrpc":"2.0","id":"setup-a2a","method":"message/send","params":{"skill":"quota-management","messages":[{"role":"user","content":"Summarize quota status."}]}}' ``` -Manage lifecycle: +管理生命周期: - `GET /api/a2a/status` - `GET /api/a2a/tasks` - `GET /api/a2a/tasks/:id` - `POST /api/a2a/tasks/:id/cancel` -Operational UI: +运维 UI: -- `/dashboard/a2a` for task/state/stream observability and smoke actions +- `/dashboard/a2a`:用于任务/状态/流的可观测性以及基础 smoke 操作
-🧪 End-to-end protocol validation +🧪 端到端协议验证 -Validate both protocols with real clients: +使用真实客户端验证这两种协议: ```bash npm run test:protocols:e2e ``` -This verifies: +这会验证: -- MCP SDK client connect/list/call -- A2A discovery/send/stream/get/cancel -- Cross-check data in MCP audit and A2A task management APIs +- MCP SDK 客户端的 connect/list/call +- A2A 的 discovery/send/stream/get/cancel +- 交叉核对 MCP 审计和 A2A 任务管理 API 中的数据
-💳 Subscription Providers +💳 订阅型提供商 ### Claude Code (Pro/Max) ```bash Dashboard → Providers → Connect Claude Code -→ OAuth login → Auto token refresh -→ 5-hour + weekly quota tracking +→ OAuth 登录 → 自动刷新 token +→ 跟踪 5 小时 + 每周配额 -Models: +模型: cc/claude-opus-4-6 cc/claude-sonnet-4-5-20250929 cc/claude-haiku-4-5-20251001 ``` -**Pro Tip:** Use Opus for complex tasks, Sonnet for speed. OmniRoute tracks quota per model! +**专业提示:** 复杂任务用 Opus,追求速度用 Sonnet。OmniRoute 会按模型跟踪配额。 ### OpenAI Codex (Plus/Pro) ```bash Dashboard → Providers → Connect Codex -→ OAuth login (port 1455) -→ 5-hour + weekly reset +→ OAuth 登录(端口 1455) +→ 每 5 小时 + 每周重置 -Models: +模型: cx/gpt-5.2-codex cx/gpt-5.1-codex-max ``` -#### Codex Account Limit Management (5h + Weekly) +#### Codex 账户限额管理(5 小时 + 每周) -Each Codex account now has policy toggles in `Dashboard -> Providers`: +现在每个 Codex 账户在 `Dashboard -> Providers` 中都有策略开关: -- `5h` (ON/OFF): enforce the 5-hour window threshold policy. -- `Weekly` (ON/OFF): enforce the weekly window threshold policy. -- Threshold behavior: when an enabled window reaches >=90% usage, that account is skipped. -- Rotation behavior: OmniRoute routes to the next eligible Codex account automatically. -- Reset behavior: when the provider `resetAt` time passes, the account becomes eligible again automatically. +- `5h`(开/关):启用 5 小时窗口阈值策略。 +- `Weekly`(开/关):启用每周窗口阈值策略。 +- 阈值行为:当已启用窗口的使用量达到 >=90% 时,该账户会被跳过。 +- 轮换行为:OmniRoute 会自动路由到下一个符合条件的 Codex 账户。 +- 重置行为:当提供商的 `resetAt` 时间到达后,该账户会自动重新变为可用。 -Scenarios: +场景: -- `5h ON` + `Weekly ON`: account is skipped when either window reaches threshold. -- `5h OFF` + `Weekly ON`: only weekly usage can block the account. -- `5h ON` + `Weekly OFF`: only 5-hour usage can block the account. -- `resetAt` passed: account re-enters rotation automatically (no manual re-enable). +- `5h ON` + `Weekly ON`:任一窗口达到阈值时,账户都会被跳过。 +- `5h OFF` + `Weekly ON`:只有每周使用量会阻止该账户。 +- `5h ON` + `Weekly OFF`:只有 5 小时使用量会阻止该账户。 +- `resetAt` 已过:账户会自动重新进入轮换,无需手动重新启用。 -### Gemini CLI (FREE 180K/month!) +### Gemini CLI(每月免费 180K!) ```bash Dashboard → Providers → Connect Gemini CLI → Google OAuth -→ 180K completions/month + 1K/day +→ 每月 180K completions + 每天 1K -Models: +模型: gc/gemini-3-flash-preview gc/gemini-2.5-pro ``` -**Best Value:** Huge free tier! Use this before paid tiers. +**最佳性价比:** 免费额度非常大!建议先用这个,再用付费层。 ### GitHub Copilot ```bash Dashboard → Providers → Connect GitHub -→ OAuth via GitHub -→ Monthly reset (1st of month) +→ 通过 GitHub OAuth +→ 每月重置(每月 1 日) -Models: +模型: gh/gpt-5 gh/claude-4.5-sonnet gh/gemini-3-pro @@ -1506,95 +1532,97 @@ Models:
-🔑 API Key Providers +🔑 API Key 提供商 -### NVIDIA NIM (FREE developer access — 70+ models) +### NVIDIA NIM(免费开发者访问 — 70+ 个模型) -1. Sign up: [build.nvidia.com](https://build.nvidia.com) -2. Get free API key (1000 inference credits included) -3. Dashboard → Add Provider → NVIDIA NIM: - - API Key: `nvapi-your-key` +1. 注册:[build.nvidia.com](https://build.nvidia.com) +2. 获取免费 API key(包含 1000 个 inference credits) +3. Dashboard → Add Provider → NVIDIA NIM: + - API Key:`nvapi-your-key` -**Models:** `nvidia/llama-3.3-70b-instruct`, `nvidia/mistral-7b-instruct`, and 50+ more +**模型:** `nvidia/llama-3.3-70b-instruct`、`nvidia/mistral-7b-instruct`,以及另外 50+ 个模型 -**Pro Tip:** OpenAI-compatible API — works seamlessly with OmniRoute's format translation! +**专业提示:** 这是 OpenAI-compatible API,可与 OmniRoute 的格式翻译无缝配合。 ### DeepSeek -1. Sign up: [platform.deepseek.com](https://platform.deepseek.com) -2. Get API key +1. 注册:[platform.deepseek.com](https://platform.deepseek.com) +2. 获取 API key 3. Dashboard → Add Provider → DeepSeek -**Models:** `deepseek/deepseek-chat`, `deepseek/deepseek-coder` +**模型:** `deepseek/deepseek-chat`、`deepseek/deepseek-coder` -### Groq (Free Tier Available!) +### Groq(提供免费层!) -1. Sign up: [console.groq.com](https://console.groq.com) -2. Get API key (free tier included) +1. 注册:[console.groq.com](https://console.groq.com) +2. 获取 API key(包含免费层) 3. Dashboard → Add Provider → Groq -**Models:** `groq/llama-3.3-70b`, `groq/mixtral-8x7b` +**模型:** `groq/llama-3.3-70b`、`groq/mixtral-8x7b` -**Pro Tip:** Ultra-fast inference — best for real-time coding! +**专业提示:** 推理速度极快,非常适合实时编码。 -### OpenRouter (100+ Models) +### OpenRouter(100+ 个模型) -1. Sign up: [openrouter.ai](https://openrouter.ai) -2. Get API key +1. 注册:[openrouter.ai](https://openrouter.ai) +2. 获取 API key 3. Dashboard → Add Provider → OpenRouter -**Models:** Access 100+ models from all major providers through a single API key. +**模型:** 通过一个 API key 即可访问所有主流提供商的 100+ 个模型。 + +**Dashboard 行为:** OpenRouter 模型由 **Available Models** 统一管理。手动添加、导入和自动同步都会更新同一份列表。
-💰 Cheap Providers (Backup) +💰 低价提供商(回退备用) -### GLM-4.7 (Daily reset, $0.6/1M) +### GLM-4.7(每日重置,$0.6/100 万) -1. Sign up: [Zhipu AI](https://open.bigmodel.cn/) -2. Get API key from Coding Plan -3. Dashboard → Add API Key: - - Provider: `glm` - - API Key: `your-key` +1. 注册:[Zhipu AI](https://open.bigmodel.cn/) +2. 从 Coding Plan 获取 API key +3. Dashboard → Add API Key: + - Provider:`glm` + - API Key:`your-key` -**Use:** `glm/glm-4.7` +**使用:** `glm/glm-4.7` -**Pro Tip:** Coding Plan offers 3× quota at 1/7 cost! Reset daily 10:00 AM. +**专业提示:** Coding Plan 能以 1/7 的成本提供 3 倍配额!每天 10:00 重置。 -### MiniMax M2.1 (5h reset, $0.20/1M) +### MiniMax M2.1(5 小时重置,$0.20/100 万) -1. Sign up: [MiniMax](https://www.minimax.io/) -2. Get API key +1. 注册:[MiniMax](https://www.minimax.io/) +2. 获取 API key 3. Dashboard → Add API Key -**Use:** `minimax/MiniMax-M2.1` +**使用:** `minimax/MiniMax-M2.1` -**Pro Tip:** Cheapest option for long context (1M tokens)! +**专业提示:** 这是长上下文(100 万 tokens)场景中最便宜的选择! -### Kimi K2 ($9/month flat) +### Kimi K2(固定 $9/月) -1. Subscribe: [Moonshot AI](https://platform.moonshot.ai/) -2. Get API key +1. 订阅:[Moonshot AI](https://platform.moonshot.ai/) +2. 获取 API key 3. Dashboard → Add API Key -**Use:** `kimi/kimi-latest` +**使用:** `kimi/kimi-latest` -**Pro Tip:** Fixed $9/month for 10M tokens = $0.90/1M effective cost! +**专业提示:** 固定 $9/月即可获得 1000 万 tokens,相当于每 100 万 tokens 仅 $0.90!
-🆓 FREE Providers (Emergency Backup) +🆓 免费提供商(紧急备用) -### iFlow (5 FREE models via OAuth) +### Qoder(通过 OAuth 提供 5 个免费模型) ```bash -Dashboard → Connect iFlow -→ iFlow OAuth login -→ Unlimited usage +Dashboard → Connect Qoder +→ Qoder OAuth 登录 +→ 无限使用 -Models: +模型: if/kimi-k2-thinking if/qwen3-coder-plus if/glm-4.7 @@ -1602,26 +1630,26 @@ Models: if/deepseek-r1 ``` -### Qwen (4 FREE models via Device Code) +### Qwen(通过设备码提供 4 个免费模型) ```bash Dashboard → Connect Qwen -→ Device code authorization -→ Unlimited usage +→ 设备码授权 +→ 无限使用 -Models: +模型: qw/qwen3-coder-plus qw/qwen3-coder-flash ``` -### Kiro (Claude FREE) +### Kiro(免费 Claude) ```bash Dashboard → Connect Kiro -→ AWS Builder ID or Google/GitHub -→ Unlimited usage +→ AWS Builder ID 或 Google/GitHub +→ 无限使用 -Models: +模型: kr/claude-sonnet-4.5 kr/claude-haiku-4.5 ``` @@ -1629,51 +1657,51 @@ Models:
-🎨 Create Combos +🎨 创建 Combos -### Example 1: Maximize Subscription → Cheap Backup +### 示例 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) +模型: + 1. cc/claude-opus-4-6(订阅主力) + 2. glm/glm-4.7(廉价备用,$0.6/1M) + 3. minimax/MiniMax-M2.1(最便宜的回退,$0.20/1M) -Use in CLI: premium-coding +在 CLI 中使用:premium-coding ``` -### Example 2: Free-Only (Zero Cost) +### 示例 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) +模型: + 1. gc/gemini-3-flash-preview(每月免费 180K) + 2. if/kimi-k2-thinking(无限) + 3. qw/qwen3-coder-plus(无限) -Cost: $0 forever! +成本:永久免费! ```
-🔧 CLI Integration +🔧 CLI 集成 ### Cursor IDE ``` Settings → Models → Advanced: OpenAI API Base URL: http://localhost:20128/v1 - OpenAI API Key: [from OmniRoute dashboard] + OpenAI API Key: [从 OmniRoute Dashboard 获取] Model: cc/claude-opus-4-6 ``` ### Claude Code -Use the **CLI Tools** page in the dashboard for one-click configuration, or edit `~/.claude/settings.json` manually. +使用 Dashboard 中的 **CLI Tools** 页面进行一键配置,或手动编辑 `~/.claude/settings.json`。 ### Codex CLI @@ -1686,13 +1714,13 @@ codex "your prompt" ### OpenClaw -**Option 1 — Dashboard (recommended):** +**方式 1:通过 Dashboard(推荐)** ``` Dashboard → CLI Tools → OpenClaw → Select Model → Apply ``` -**Option 2 — Manual:** Edit `~/.openclaw/openclaw.json`: +**方式 2:手动配置** 编辑 `~/.openclaw/openclaw.json`: ```json { @@ -1708,7 +1736,7 @@ Dashboard → CLI Tools → OpenClaw → Select Model → Apply } ``` -> **Note:** OpenClaw only works with local OmniRoute. Use `127.0.0.1` instead of `localhost` to avoid IPv6 resolution issues. +> **注意:** OpenClaw 仅适用于本地 OmniRoute。请使用 `127.0.0.1` 而不是 `localhost`,以避免 IPv6 解析问题。 ### Cline / Continue / RooCode @@ -1716,21 +1744,21 @@ Dashboard → CLI Tools → OpenClaw → Select Model → Apply Settings → API Configuration: Provider: OpenAI Compatible Base URL: http://localhost:20128/v1 - API Key: [from OmniRoute dashboard] + API Key: [从 OmniRoute Dashboard 获取] Model: if/kimi-k2-thinking ``` ### OpenCode -**Step 1:** Add OmniRoute as a custom provider: +**步骤 1:** 将 OmniRoute 添加为自定义 provider: ```bash opencode /connect -# Select "Other" → Enter ID: "omniroute" → Enter your OmniRoute API key +# 选择 “Other” → 输入 ID:“omniroute” → 输入你的 OmniRoute API key ``` -**Step 2:** Create/edit `opencode.json` in your project root: +**步骤 2:** 在项目根目录中创建或编辑 `opencode.json`: ```json { @@ -1752,14 +1780,14 @@ opencode } ``` -**Step 3:** Select the model in OpenCode: +**步骤 3:** 在 OpenCode 中选择模型: ```bash /models -# Select any OmniRoute model from the list +# 从列表中选择任意 OmniRoute 模型 ``` -> **Tip:** Add any model available in your OmniRoute `/v1/models` endpoint to the `models` section. Use the format `provider/model-id` from your OmniRoute dashboard. +> **提示:** 可将 OmniRoute `/v1/models` 端点中可见的任意模型添加到 `models` 段。请使用 OmniRoute Dashboard 中的 `provider/model-id` 格式。
@@ -1768,238 +1796,240 @@ opencode ## 故障排除
-Click to expand troubleshooting guide +点击展开故障排除指南 -**"Language model did not provide messages"** +**“Language model did not provide messages”** -- Provider quota exhausted → Check dashboard quota tracker -- Solution: Use combo fallback or switch to cheaper tier +- 提供商配额已耗尽 → 检查 Dashboard 中的配额跟踪器 +- 解决方案:使用 combo 回退或切换到更便宜的层级 -**Rate limiting** +**速率限制** -- Subscription quota out → Fallback to GLM/MiniMax -- Add combo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` +- 订阅配额用尽 → 回退到 GLM/MiniMax +- 添加 combo:`cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` -**OAuth token expired** +**OAuth token 已过期** -- Auto-refreshed by OmniRoute -- If issues persist: Dashboard → Provider → Reconnect +- OmniRoute 会自动刷新 +- 如果问题持续:Dashboard → Provider → Reconnect -**High costs** +**成本过高** -- Check usage stats in Dashboard → Costs -- Switch primary model to GLM/MiniMax -- Use free tier (Gemini CLI, iFlow) for non-critical tasks +- 检查 Dashboard → Costs 中的用量统计 +- 将主模型切换到 GLM/MiniMax +- 对非关键任务使用免费层(Gemini CLI、Qoder) -**Dashboard/API ports are wrong** +**Dashboard/API 端口不正确** -- `PORT` is the canonical base port (and API port by default) -- `API_PORT` overrides only OpenAI-compatible API listener -- `DASHBOARD_PORT` overrides only dashboard/Next.js listener -- Set `NEXT_PUBLIC_BASE_URL` to your dashboard/public URL (for OAuth callbacks) +- `PORT` 是规范基础端口(默认也作为 API 端口) +- `API_PORT` 仅覆盖 OpenAI-compatible API 监听器 +- `DASHBOARD_PORT` 仅覆盖 dashboard/Next.js 监听器 +- 将 `NEXT_PUBLIC_BASE_URL` 设置为你的 Dashboard/公共 URL(用于 OAuth 回调) -**Cloud sync errors** +**Cloud sync 错误** -- Verify `BASE_URL` points to your running instance -- Verify `CLOUD_URL` points to your expected cloud endpoint -- Keep `NEXT_PUBLIC_*` values aligned with server-side values +- 确认 `BASE_URL` 指向正在运行的实例 +- 确认 `CLOUD_URL` 指向你期望的 cloud endpoint +- 保持 `NEXT_PUBLIC_*` 的值与服务端配置一致 -**First login not working** +**首次登录无法使用** -- Check `INITIAL_PASSWORD` in `.env` -- If unset, fallback password is `123456` +- 检查 `.env` 中的 `INITIAL_PASSWORD` +- 如果未设置,后备密码为 `123456` -**No request logs** +**没有请求日志** -- Set `ENABLE_REQUEST_LOGS=true` in `.env` +- 请求 artifact 会以每请求一个 JSON 文件的形式写入 `DATA_DIR/call_logs/` +- 如果你需要按阶段查看详细 payload,请在 Dashboard → Logs → Request Logs 中启用 pipeline capture +- 如果还需要应用控制台日志,请设置 `APP_LOG_TO_FILE=true`,日志会写入 `logs/application/app.log` -**Connection test shows "Invalid" for OpenAI-compatible providers** +**OpenAI-compatible 提供商的连接测试显示 “Invalid”** -- Many providers don't expose a `/models` endpoint -- OmniRoute v1.0.6+ includes fallback validation via chat completions -- Ensure base URL includes `/v1` suffix +- 许多提供商并不暴露 `/models` 端点 +- OmniRoute v1.0.6+ 已包含基于 chat completions 的后备校验 +- 确保 base URL 包含 `/v1` 后缀 -### 🔐 OAuth on a Remote Server +### 🔐 远程服务器上的 OAuth -> **⚠️ Important for users running OmniRoute on a VPS, Docker, or any remote server** +> **⚠️ 适用于在 VPS、Docker 或任意远程服务器上运行 OmniRoute 的用户** -#### Why does Antigravity / Gemini CLI OAuth fail on remote servers? +#### 为什么 Antigravity / Gemini CLI 的 OAuth 会在远程服务器上失败? -The **Antigravity** and **Gemini CLI** providers use **Google OAuth 2.0**. Google requires the `redirect_uri` in the OAuth flow to exactly match one of the pre-registered URIs in the app's Google Cloud Console. +**Antigravity** 和 **Gemini CLI** 提供商使用 **Google OAuth 2.0**。Google 要求 OAuth 流程中的 `redirect_uri` 必须与应用在 Google Cloud Console 中预先注册的某个 URI **完全一致**。 -The OAuth credentials bundled in OmniRoute are registered **for `localhost` only**. When you access OmniRoute on a remote server (e.g. `https://omniroute.myserver.com`), Google rejects the authentication with: +OmniRoute 内置的 OAuth 凭证**仅为 `localhost` 注册**。当你通过远程服务器访问 OmniRoute(例如 `https://omniroute.myserver.com`)时,Google 会拒绝认证,并返回: ``` Error 400: redirect_uri_mismatch ``` -#### Solution: Configure your own OAuth credentials +#### 解决方案:配置你自己的 OAuth 凭证 -You need to create an **OAuth 2.0 Client ID** in Google Cloud Console with your server's URI. +你需要在 Google Cloud Console 中创建一个带有你服务器 URI 的 **OAuth 2.0 Client ID**。 -#### Step-by-step +#### 操作步骤 -**1. Open Google Cloud Console** +**1. 打开 Google Cloud Console** -Go to: [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials) +访问:[https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials) -**2. Create a new OAuth 2.0 Client ID** +**2. 创建新的 OAuth 2.0 Client ID** -- Click **"+ Create Credentials"** → **"OAuth client ID"** -- Application type: **"Web application"** -- Name: anything you like (e.g. `OmniRoute Remote`) +- 点击 **"+ Create Credentials"** → **"OAuth client ID"** +- 应用类型:**"Web application"** +- 名称:可自定义(例如 `OmniRoute Remote`) -**3. Add Authorized Redirect URIs** +**3. 添加 Authorized Redirect URIs** -In the **"Authorized redirect URIs"** field, add: +在 **"Authorized redirect URIs"** 字段中添加: ``` https://your-server.com/callback ``` -> Replace `your-server.com` with your server's domain or IP (include the port if needed, e.g. `http://45.33.32.156:20128/callback`). +> 将 `your-server.com` 替换为你的服务器域名或 IP(如有需要请包含端口,例如 `http://45.33.32.156:20128/callback`)。 -**4. Save and copy the credentials** +**4. 保存并复制凭证** -After creating, Google will show the **Client ID** and **Client Secret**. +创建完成后,Google 会显示 **Client ID** 和 **Client Secret**。 -**5. Set environment variables** +**5. 设置环境变量** -In your `.env` (or Docker environment variables): +在 `.env`(或 Docker 环境变量)中添加: ```bash -# For Antigravity: +# 用于 Antigravity: ANTIGRAVITY_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com ANTIGRAVITY_OAUTH_CLIENT_SECRET=GOCSPX-your-secret -# For Gemini CLI: +# 用于 Gemini CLI: GEMINI_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com GEMINI_OAUTH_CLIENT_SECRET=GOCSPX-your-secret GEMINI_CLI_OAUTH_CLIENT_SECRET=GOCSPX-your-secret ``` -**6. Restart OmniRoute** +**6. 重启 OmniRoute** ```bash -# npm: +# npm: npm run dev -# Docker: +# Docker: docker restart omniroute ``` -**7. Try connecting again** +**7. 再次尝试连接** -Dashboard → Providers → Antigravity (or Gemini CLI) → OAuth +Dashboard → Providers → Antigravity(或 Gemini CLI)→ OAuth -Google will now redirect correctly to `https://your-server.com/callback`. +此时 Google 就会正确重定向到 `https://your-server.com/callback`。 --- -#### Temporary workaround (without custom credentials) +#### 临时绕过方案(不配置自有凭证) -If you don't want to set up your own credentials right now, you can still use the **manual URL flow**: +如果你暂时不想配置自己的凭证,仍然可以使用**手动 URL 流程**: -1. OmniRoute opens the Google authorization URL -2. After authorizing, Google tries to redirect to `localhost` (which fails on the remote server) -3. **Copy the full URL** from your browser's address bar (even if the page doesn't load) -4. Paste that URL into the field shown in the OmniRoute connection modal -5. Click **"Connect"** +1. OmniRoute 打开 Google 授权 URL +2. 授权后,Google 会尝试重定向到 `localhost`(在远程服务器上这会失败) +3. 即使页面打不开,也请从浏览器地址栏**复制完整 URL** +4. 将该 URL 粘贴到 OmniRoute 连接弹窗中的输入框 +5. 点击 **"Connect"** -> This works because the authorization code in the URL is valid regardless of whether the redirect page loaded. +> 之所以可行,是因为 URL 中的授权码无论重定向页面是否成功加载,都是有效的。 ---
-🇧🇷 Versão em Português +🇧🇷 葡萄牙语版本 -#### Por que o OAuth do Antigravity / Gemini CLI falha em servidores remotos? +#### 为什么 Antigravity / Gemini CLI 的 OAuth 会在远程服务器上失败? -Os provedores **Antigravity** e **Gemini CLI** usam **Google OAuth 2.0** para autenticação. O Google exige que a `redirect_uri` usada no fluxo OAuth seja **exatamente** uma das URIs pré-cadastradas no Google Cloud Console do aplicativo. +**Antigravity** 和 **Gemini CLI** 提供商使用 **Google OAuth 2.0**。Google 要求 OAuth 流程中使用的 `redirect_uri` 必须与应用在 Google Cloud Console 中预先注册的 URI **完全一致**。 -As credenciais OAuth embutidas no OmniRoute estão cadastradas **apenas para `localhost`**. Quando você acessa o OmniRoute em um servidor remoto (ex: `https://omniroute.meuservidor.com`), o Google rejeita a autenticação com: +OmniRoute 内置的 OAuth 凭证**仅为 `localhost` 注册**。当你在远程服务器上访问 OmniRoute(例如 `https://omniroute.meuservidor.com`)时,Google 会拒绝认证,并返回: ``` Error 400: redirect_uri_mismatch ``` -#### Solução: Configure suas próprias credenciais OAuth +#### 解决方案:配置你自己的 OAuth 凭证 -Você precisa criar um **OAuth 2.0 Client ID** no Google Cloud Console com a URI do seu servidor. +你需要在 Google Cloud Console 中创建一个带有你服务器 URI 的 **OAuth 2.0 Client ID**。 -#### Passo a passo +#### 操作步骤 -**1. Acesse o Google Cloud Console** +**1. 打开 Google Cloud Console** -Abra: [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials) +访问:[https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials) -**2. Crie um novo OAuth 2.0 Client ID** +**2. 创建新的 OAuth 2.0 Client ID** -- Clique em **"+ Create Credentials"** → **"OAuth client ID"** -- Tipo de aplicativo: **"Web application"** -- Nome: escolha qualquer nome (ex: `OmniRoute Remote`) +- 点击 **"+ Create Credentials"** → **"OAuth client ID"** +- 应用类型:**"Web application"** +- 名称:可自定义(例如 `OmniRoute Remote`) -**3. Adicione as Authorized Redirect URIs** +**3. 添加 Authorized Redirect URIs** -No campo **"Authorized redirect URIs"**, adicione: +在 **"Authorized redirect URIs"** 字段中添加: ``` https://seu-servidor.com/callback ``` -> Substitua `seu-servidor.com` pelo domínio ou IP do seu servidor (inclua a porta se necessário, ex: `http://45.33.32.156:20128/callback`). +> 将 `seu-servidor.com` 替换为你的服务器域名或 IP(如有需要请包含端口,例如 `http://45.33.32.156:20128/callback`)。 -**4. Salve e copie as credenciais** +**4. 保存并复制凭证** -Após criar, o Google mostrará o **Client ID** e o **Client Secret**. +创建完成后,Google 会显示 **Client ID** 和 **Client Secret**。 -**5. Configure as variáveis de ambiente** +**5. 配置环境变量** -No seu `.env` (ou nas variáveis de ambiente do Docker): +在 `.env`(或 Docker 环境变量)中添加: ```bash -# Para Antigravity: +# 用于 Antigravity: ANTIGRAVITY_OAUTH_CLIENT_ID=seu-client-id.apps.googleusercontent.com ANTIGRAVITY_OAUTH_CLIENT_SECRET=GOCSPX-seu-secret -# Para Gemini CLI: +# 用于 Gemini CLI: GEMINI_OAUTH_CLIENT_ID=seu-client-id.apps.googleusercontent.com GEMINI_OAUTH_CLIENT_SECRET=GOCSPX-seu-secret GEMINI_CLI_OAUTH_CLIENT_SECRET=GOCSPX-seu-secret ``` -**6. Reinicie o OmniRoute** +**6. 重启 OmniRoute** ```bash -# Se usando npm: +# npm: npm run dev -# Se usando Docker: +# Docker: docker restart omniroute ``` -**7. Tente conectar novamente** +**7. 再次尝试连接** -Dashboard → Providers → Antigravity (ou Gemini CLI) → OAuth +Dashboard → Providers → Antigravity(或 Gemini CLI)→ OAuth -Agora o Google redirecionará corretamente para `https://seu-servidor.com/callback` e a autenticação funcionará. +此时 Google 就会正确重定向到 `https://seu-servidor.com/callback`。 --- -#### Workaround temporário (sem configurar credenciais próprias) +#### 临时绕过方案(不配置自有凭证) -Se não quiser criar credenciais próprias agora, ainda é possível usar o fluxo **manual de URL**: +如果你暂时不想配置自己的凭证,仍然可以使用**手动 URL 流程**: -1. O OmniRoute abrirá a URL de autorização do Google -2. Após você autorizar, o Google tentará redirecionar para `localhost` (que falha no servidor remoto) -3. **Copie a URL completa** da barra de endereço do seu browser (mesmo que a página não carregue) -4. Cole essa URL no campo que aparece no modal de conexão do OmniRoute -5. Clique em **"Connect"** +1. OmniRoute 会打开 Google 授权 URL +2. 在你授权之后,Google 会尝试重定向到 `localhost`(这在远程服务器上会失败) +3. 即使页面未加载,也请从浏览器地址栏**复制完整 URL** +4. 将该 URL 粘贴到 OmniRoute 连接弹窗中的输入框 +5. 点击 **"Connect"** -> Este workaround funciona porque o código de autorização na URL é válido independente do redirect ter carregado ou não. +> 之所以可行,是因为 URL 中的授权码无论重定向页面是否成功加载,都是有效的。
@@ -2007,25 +2037,25 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
-## 🛠️ Tech Stack +## 🛠️ 技术栈
-Click to expand tech stack details +点击展开技术栈详情 -- **Runtime**: Node.js 18–22 LTS (⚠️ Node.js 24+ is **not supported** — `better-sqlite3` native binaries are incompatible) -- **Language**: TypeScript 5.9 — **100% TypeScript** across `src/` and `open-sse/` (zero `any` in core modules since v2.0) +- **Runtime**: Node.js 18–22 LTS(⚠️ **不支持** Node.js 24+,因为 `better-sqlite3` 原生二进制不兼容) +- **Language**: TypeScript 5.9,`src/` 与 `open-sse/` 全面采用 **100% TypeScript**(自 v2.0 起核心模块中无 `any`) - **Framework**: Next.js 16 + React 19 + Tailwind CSS 4 -- **Database**: LowDB (JSON) + SQLite (domain state + proxy logs + MCP audit + routing decisions) -- **Schemas**: Zod (MCP tool I/O validation, API contracts) -- **Protocols**: MCP (stdio/HTTP) + A2A v0.3 (JSON-RPC 2.0 + SSE) -- **Streaming**: Server-Sent Events (SSE) -- **Auth**: OAuth 2.0 (PKCE) + JWT + API Keys + MCP Scoped Authorization -- **Testing**: Node.js test runner + Vitest (900+ tests including unit, integration, E2E) -- **CI/CD**: GitHub Actions (auto npm publish + Docker Hub on release) +- **Database**: LowDB(JSON)+ SQLite(domain state + proxy logs + MCP audit + routing decisions) +- **Schemas**: Zod(MCP tool I/O validation、API contracts) +- **Protocols**: MCP(stdio/HTTP)+ A2A v0.3(JSON-RPC 2.0 + SSE) +- **Streaming**: Server-Sent Events(SSE) +- **Auth**: OAuth 2.0(PKCE)+ JWT + API Keys + MCP Scoped Authorization +- **Testing**: Node.js test runner + Vitest(900+ 项测试,涵盖 unit、integration、E2E) +- **CI/CD**: GitHub Actions(release 时自动 npm publish + Docker Hub) - **Website**: [omniroute.online](https://omniroute.online) - **Package**: [npmjs.com/package/omniroute](https://www.npmjs.com/package/omniroute) - **Docker**: [hub.docker.com/r/diegosouzapw/omniroute](https://hub.docker.com/r/diegosouzapw/omniroute) -- **Resilience**: Circuit breaker, exponential backoff, anti-thundering herd, TLS spoofing, auto-combo self-healing +- **Resilience**: circuit breaker、exponential backoff、anti-thundering herd、TLS spoofing、auto-combo self-healing
@@ -2033,94 +2063,94 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux ## 文档 -| Document | Description | -| ---------------------------------------------- | --------------------------------------------------- | -| [User Guide](docs/USER_GUIDE.md) | Providers, combos, CLI integration, deployment | -| [API Reference](docs/API_REFERENCE.md) | All endpoints with examples | -| [MCP Server](open-sse/mcp-server/README.md) | 16 MCP tools, IDE configs, Python/TS/Go clients | -| [A2A Server](src/lib/a2a/README.md) | JSON-RPC 2.0 protocol, skills, streaming, task mgmt | -| [Auto-Combo Engine](docs/auto-combo.md) | 6-factor scoring, mode packs, self-healing | -| [Troubleshooting](docs/TROUBLESHOOTING.md) | Common problems and solutions | -| [Architecture](docs/ARCHITECTURE.md) | System architecture and internals | -| [Contributing](CONTRIBUTING.md) | Development setup and guidelines | -| [OpenAPI Spec](docs/openapi.yaml) | OpenAPI 3.0 specification | -| [Security Policy](SECURITY.md) | Vulnerability reporting and security practices | -| [VM Deployment](docs/VM_DEPLOYMENT_GUIDE.md) | Complete guide: VM + nginx + Cloudflare setup | -| [Features Gallery](docs/FEATURES.md) | Visual dashboard tour with screenshots | -| [Release Checklist](docs/RELEASE_CHECKLIST.md) | Pre-release validation steps | +| 文档 | 说明 | +| ---------------------------------------------------- | --------------------------------------------- | +| [用户指南](USER_GUIDE.md) | 提供商、combo、CLI 集成、部署 | +| [API 参考](API_REFERENCE.md) | 所有端点及使用示例 | +| [MCP Server](../../../open-sse/mcp-server/README.md) | 16 个 MCP 工具、IDE 配置、Python/TS/Go 客户端 | +| [A2A Server](../../../src/lib/a2a/README.md) | JSON-RPC 2.0 协议、Skills、流式传输、任务管理 | +| [Auto-Combo 引擎](AUTO-COMBO.md) | 6 因子评分、模式包、自愈 | +| [故障排除](TROUBLESHOOTING.md) | 常见问题及解决方案 | +| [架构](ARCHITECTURE.md) | 系统架构与内部实现 | +| [贡献指南](../../../CONTRIBUTING.md) | 开发环境与贡献规范 | +| [OpenAPI 规范](../../../docs/openapi.yaml) | OpenAPI 3.0 规范 | +| [安全策略](../../../SECURITY.md) | 漏洞报告与安全实践 | +| [VM 部署指南](VM_DEPLOYMENT_GUIDE.md) | 完整指南:VM + nginx + Cloudflare 配置 | +| [功能画廊](FEATURES.md) | 带截图的仪表盘功能导览 | +| [发布检查清单](RELEASE_CHECKLIST.md) | 发布前验证步骤 | --- -## 🗺️ Roadmap +## 🗺️ 路线图 -OmniRoute has **210+ features planned** across multiple development phases. Here are the key areas: +OmniRoute 在多个开发阶段计划了 **210+ 个功能**。以下是关键领域: -| Category | Planned Features | Highlights | -| ----------------------------- | ---------------- | -------------------------------------------------------------------------------------- | -| 🧠 **Routing & Intelligence** | 25+ | Lowest-latency routing, tag-based routing, quota preflight, P2C account selection | -| 🔒 **Security & Compliance** | 20+ | SSRF hardening, credential cloaking, rate-limit per endpoint, management key scoping | -| 📊 **Observability** | 15+ | OpenTelemetry integration, real-time quota monitoring, cost tracking per model | -| 🔄 **Provider Integrations** | 20+ | Dynamic model registry, provider cooldowns, multi-account Codex, Copilot quota parsing | -| ⚡ **Performance** | 15+ | Dual cache layer, prompt cache, response cache, streaming keepalive, batch API | -| 🌐 **Ecosystem** | 10+ | WebSocket API, config hot-reload, distributed config store, commercial mode | +| 类别 | 计划功能 | 亮点 | +| ----------------- | -------- | ---------------------------------------------------------- | +| 🧠 **路由与智能** | 25+ | 最低延迟路由、基于标签路由、配额预检、P2C 账户选择 | +| 🔒 **安全与合规** | 20+ | SSRF 加固、凭证隐藏、每端点速率限制、管理密钥范围 | +| 📊 **可观测性** | 15+ | OpenTelemetry 集成、实时配额监控、每模型成本追踪 | +| 🔄 **提供商集成** | 20+ | 动态模型注册表、提供商冷却、多账户 Codex、Copilot 配额解析 | +| ⚡ **性能** | 15+ | 双层缓存、提示词缓存、响应缓存、流式 keepalive、批量 API | +| 🌐 **生态系统** | 10+ | WebSocket API、配置热重载、分布式配置存储、商业模式 | -### 🔜 Coming Soon +### 🔜 即将推出 -- 🔗 **OpenCode Integration** — Native provider support for the OpenCode AI coding IDE -- 🔗 **TRAE Integration** — Full support for the TRAE AI development framework -- 📦 **Batch API** — Asynchronous batch processing for bulk requests -- 🎯 **Tag-Based Routing** — Route requests based on custom tags and metadata -- 💰 **Lowest-Cost Strategy** — Automatically select the cheapest available provider +- 🔗 **OpenCode 集成** — OpenCode AI 编码 IDE 的原生提供商支持 +- 🔗 **TRAE 集成** — TRAE AI 开发框架的完整支持 +- 📦 **批量 API** — 批量请求的异步批处理 +- 🎯 **基于标签路由** — 基于自定义标签和元数据路由请求 +- 💰 **最低成本策略** — 自动选择最便宜的可用提供商 -> 📝 Full feature specifications available in [`docs/new-features/`](docs/new-features/) (217 detailed specs) +> 📝 完整功能规格在 [`docs/new-features/`](../../../docs/new-features/) 中可用(217 个详细规格) --- -## 👥 Contributors +## 👥 贡献者 -[![Contributors](https://contrib.rocks/image?repo=diegosouzapw/OmniRoute&max=100&columns=20&anon=1)](https://github.com/diegosouzapw/OmniRoute/graphs/contributors) +[![贡献者](https://contrib.rocks/image?repo=diegosouzapw/OmniRoute&max=100&columns=20&anon=1)](https://github.com/diegosouzapw/OmniRoute/graphs/contributors) -### How to Contribute +### 如何贡献 -1. Fork the repository -2. Create your feature branch (`git checkout -b feature/amazing-feature`) -3. Commit your changes (`git commit -m 'Add amazing feature'`) -4. Push to the branch (`git push origin feature/amazing-feature`) -5. Open a Pull Request +1. Fork 仓库 +2. 创建功能分支(`git checkout -b feature/amazing-feature`) +3. 提交更改(`git commit -m 'Add amazing feature'`) +4. 推送到分支(`git push origin feature/amazing-feature`) +5. 开启 Pull Request -See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines. +详细指南请查看 [CONTRIBUTING.md](../../../CONTRIBUTING.md)。 -### Releasing a New Version +### 发布新版本 ```bash -# Create a release — npm publish happens automatically +# 创建发布 — npm 发布自动进行 gh release create v2.0.0 --title "v2.0.0" --generate-notes ``` --- -## 📊 Star History +## 📊 Star 历史 -## Stargazers over time +## 随时间变化的 Stargazers -## [![Stargazers over time](https://starchart.cc/diegosouzapw/OmniRoute.svg?variant=adaptive)](https://starchart.cc/diegosouzapw/OmniRoute) +## [![随时间变化的 Stargazers](https://starchart.cc/diegosouzapw/OmniRoute.svg?variant=adaptive)](https://starchart.cc/diegosouzapw/OmniRoute) -## 🙏 Acknowledgments +## 🙏 致谢 -Special thanks to **[9router](https://github.com/decolua/9router)** by **[decolua](https://github.com/decolua)** — the original project that inspired this fork. OmniRoute builds upon that incredible foundation with additional features, multi-modal APIs, and a full TypeScript rewrite. +特别感谢 **[decolua](https://github.com/decolua)** 的 **[9router](https://github.com/decolua/9router)** — 启发这个 fork 的原始项目。OmniRoute 在这个令人难以置信的基础上构建,增加了额外功能、多模态 API 和完整的 TypeScript 重写。 -Special thanks to **[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)** — the original Go implementation that inspired this JavaScript port. +特别感谢 **[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)** — 启发这个 JavaScript 移植的原始 Go 实现。 --- -## 许可证 +## 📝 许可证 -MIT License - see [LICENSE](LICENSE) for details. +MIT 许可证 - 详情请查看 [LICENSE](../../../LICENSE)。 ---
- Built with ❤️ for developers who code 24/7 + 为 24/7 编码的开发者用 ❤️ 构建
omniroute.online
diff --git a/docs/i18n/zh-CN/RELEASE_CHECKLIST.md b/docs/i18n/zh-CN/RELEASE_CHECKLIST.md index 903e812c..a73eac8b 100644 --- a/docs/i18n/zh-CN/RELEASE_CHECKLIST.md +++ b/docs/i18n/zh-CN/RELEASE_CHECKLIST.md @@ -1,37 +1,37 @@ -🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../es/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../fr/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../de/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../it/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../ru/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../zh-CN/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../ja/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../ko/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../ar/RELEASE_CHECKLIST.md) · 🇮🇳 [in](../in/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../th/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../vi/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../id/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../ms/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../nl/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../pl/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../sv/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../no/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../da/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../fi/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../pt/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../ro/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../hu/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../bg/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../sk/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../uk-UA/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../he/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../phi/RELEASE_CHECKLIST.md) +🌐 **语言:** 🇺🇸 [English](../../RELEASE_CHECKLIST.md) · 🇧🇷 [pt-BR](../pt-BR/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../es/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../fr/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../de/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../it/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../ru/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../zh-CN/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../ja/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../ko/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../ar/RELEASE_CHECKLIST.md) · 🇮🇳 [in](../in/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../th/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../vi/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../id/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../ms/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../nl/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../pl/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../sv/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../no/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../da/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../fi/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../pt/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../ro/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../hu/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../bg/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../sk/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../uk-UA/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../he/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../phi/RELEASE_CHECKLIST.md) --- -# Release Checklist +# 发布检查清单 -Use this checklist before tagging or publishing a new OmniRoute release. +在打标签或发布新的 OmniRoute 版本之前,请使用此检查清单。 -## Version and Changelog +## 版本和变更日志 -1. Bump `package.json` version (`x.y.z`) in the release branch. -2. Move release notes from `## [Unreleased]` in `CHANGELOG.md` to a dated section: +1. 在发布分支中更新 `package.json` 的版本号(`x.y.z`)。 +2. 将发布说明从 `CHANGELOG.md` 中的 `## [Unreleased]` 移动到带日期的章节: - `## [x.y.z] — YYYY-MM-DD` -3. Keep `## [Unreleased]` as the first changelog section for upcoming work. -4. Ensure the latest semver section in `CHANGELOG.md` equals `package.json` version. +3. 保留 `## [Unreleased]` 作为变更日志的第一个章节,用于后续工作。 +4. 确保 `CHANGELOG.md` 中最新的语义化版本章节与 `package.json` 的版本号一致。 -## API Docs +## API 文档 -1. Update `docs/openapi.yaml`: - - `info.version` must equal `package.json` version. -2. Validate endpoint examples if API contracts changed. +1. 更新 `docs/openapi.yaml`: + - `info.version` 必须与 `package.json` 的版本号一致。 +2. 如果 API 契约发生变化,请验证端点示例。 -## Runtime Docs +## 运行时文档 -1. Review `docs/ARCHITECTURE.md` for storage/runtime drift. -2. Review `docs/TROUBLESHOOTING.md` for env var and operational drift. -3. Update localized docs if source docs changed significantly. +1. 检查 `docs/ARCHITECTURE.md` 是否存在存储/运行时偏移。 +2. 检查 `docs/TROUBLESHOOTING.md` 是否存在环境变量和操作偏移。 +3. 如果源文档发生重大变更,请更新本地化文档。 -## Automated Check +## 自动化检查 -Run the sync guard locally before opening PR: +在开启 PR 之前,在本地运行同步检查: ```bash npm run check:docs-sync ``` -CI also runs this check in `.github/workflows/ci.yml` (lint job). +CI 也会在 `.github/workflows/ci.yml`(lint 作业)中运行此检查。 diff --git a/docs/i18n/zh-CN/TROUBLESHOOTING.md b/docs/i18n/zh-CN/TROUBLESHOOTING.md index 63c14800..a5600a50 100644 --- a/docs/i18n/zh-CN/TROUBLESHOOTING.md +++ b/docs/i18n/zh-CN/TROUBLESHOOTING.md @@ -1,91 +1,89 @@ -🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/TROUBLESHOOTING.md) · 🇪🇸 [es](../es/TROUBLESHOOTING.md) · 🇫🇷 [fr](../fr/TROUBLESHOOTING.md) · 🇩🇪 [de](../de/TROUBLESHOOTING.md) · 🇮🇹 [it](../it/TROUBLESHOOTING.md) · 🇷🇺 [ru](../ru/TROUBLESHOOTING.md) · 🇨🇳 [zh-CN](../zh-CN/TROUBLESHOOTING.md) · 🇯🇵 [ja](../ja/TROUBLESHOOTING.md) · 🇰🇷 [ko](../ko/TROUBLESHOOTING.md) · 🇸🇦 [ar](../ar/TROUBLESHOOTING.md) · 🇮🇳 [in](../in/TROUBLESHOOTING.md) · 🇹🇭 [th](../th/TROUBLESHOOTING.md) · 🇻🇳 [vi](../vi/TROUBLESHOOTING.md) · 🇮🇩 [id](../id/TROUBLESHOOTING.md) · 🇲🇾 [ms](../ms/TROUBLESHOOTING.md) · 🇳🇱 [nl](../nl/TROUBLESHOOTING.md) · 🇵🇱 [pl](../pl/TROUBLESHOOTING.md) · 🇸🇪 [sv](../sv/TROUBLESHOOTING.md) · 🇳🇴 [no](../no/TROUBLESHOOTING.md) · 🇩🇰 [da](../da/TROUBLESHOOTING.md) · 🇫🇮 [fi](../fi/TROUBLESHOOTING.md) · 🇵🇹 [pt](../pt/TROUBLESHOOTING.md) · 🇷🇴 [ro](../ro/TROUBLESHOOTING.md) · 🇭🇺 [hu](../hu/TROUBLESHOOTING.md) · 🇧🇬 [bg](../bg/TROUBLESHOOTING.md) · 🇸🇰 [sk](../sk/TROUBLESHOOTING.md) · 🇺🇦 [uk-UA](../uk-UA/TROUBLESHOOTING.md) · 🇮🇱 [he](../he/TROUBLESHOOTING.md) · 🇵🇭 [phi](../phi/TROUBLESHOOTING.md) +🌐 **语言:** 🇺🇸 [English](../../TROUBLESHOOTING.md) · 🇧🇷 [pt-BR](../pt-BR/TROUBLESHOOTING.md) · 🇪🇸 [es](../es/TROUBLESHOOTING.md) · 🇫🇷 [fr](../fr/TROUBLESHOOTING.md) · 🇩🇪 [de](../de/TROUBLESHOOTING.md) · 🇮🇹 [it](../it/TROUBLESHOOTING.md) · 🇷🇺 [ru](../ru/TROUBLESHOOTING.md) · 🇨🇳 [zh-CN](../zh-CN/TROUBLESHOOTING.md) · 🇯🇵 [ja](../ja/TROUBLESHOOTING.md) · 🇰🇷 [ko](../ko/TROUBLESHOOTING.md) · 🇸🇦 [ar](../ar/TROUBLESHOOTING.md) · 🇮🇳 [in](../in/TROUBLESHOOTING.md) · 🇹🇭 [th](../th/TROUBLESHOOTING.md) · 🇻🇳 [vi](../vi/TROUBLESHOOTING.md) · 🇮🇩 [id](../id/TROUBLESHOOTING.md) · 🇲🇾 [ms](../ms/TROUBLESHOOTING.md) · 🇳🇱 [nl](../nl/TROUBLESHOOTING.md) · 🇵🇱 [pl](../pl/TROUBLESHOOTING.md) · 🇸🇪 [sv](../sv/TROUBLESHOOTING.md) · 🇳🇴 [no](../no/TROUBLESHOOTING.md) · 🇩🇰 [da](../da/TROUBLESHOOTING.md) · 🇫🇮 [fi](../fi/TROUBLESHOOTING.md) · 🇵🇹 [pt](../pt/TROUBLESHOOTING.md) · 🇷🇴 [ro](../ro/TROUBLESHOOTING.md) · 🇭🇺 [hu](../hu/TROUBLESHOOTING.md) · 🇧🇬 [bg](../bg/TROUBLESHOOTING.md) · 🇸🇰 [sk](../sk/TROUBLESHOOTING.md) · 🇺🇦 [uk-UA](../uk-UA/TROUBLESHOOTING.md) · 🇮🇱 [he](../he/TROUBLESHOOTING.md) · 🇵🇭 [phi](../phi/TROUBLESHOOTING.md) --- -# Troubleshooting +# 故障排除 -🌐 **Languages:** 🇺🇸 [English](TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](i18n/es/TROUBLESHOOTING.md) | 🇫🇷 [Français](i18n/fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](i18n/it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](i18n/ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](i18n/de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](i18n/in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](i18n/th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](i18n/uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](i18n/ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](i18n/ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](i18n/vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](i18n/bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](i18n/da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](i18n/fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](i18n/he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](i18n/hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](i18n/ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](i18n/nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](i18n/no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](i18n/pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](i18n/ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](i18n/pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](i18n/sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](i18n/sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](i18n/phi/TROUBLESHOOTING.md) - -Common problems and solutions for OmniRoute. +OmniRoute 常见问题及解决方案。 --- -## Quick Fixes +## 快速修复 -| Problem | Solution | -| ----------------------------- | ------------------------------------------------------------------ | -| First login not working | Set `INITIAL_PASSWORD` in `.env` (no hardcoded default) | -| Dashboard opens on wrong port | Set `PORT=20128` and `NEXT_PUBLIC_BASE_URL=http://localhost:20128` | -| No request logs under `logs/` | Set `ENABLE_REQUEST_LOGS=true` | -| EACCES: permission denied | Set `DATA_DIR=/path/to/writable/dir` to override `~/.omniroute` | -| Routing strategy not saving | Update to v1.4.11+ (Zod schema fix for settings persistence) | +| 问题 | 解决方案 | +| --------------------------- | ------------------------------------------------------------------ | +| 首次登录无法使用 | 在 `.env` 中设置 `INITIAL_PASSWORD`(无硬编码默认值) | +| 仪表盘在错误端口打开 | 设置 `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 schema 设置持久化修复) | --- -## Provider Issues +## 服务商问题 ### "Language model did not provide messages" -**Cause:** Provider quota exhausted. +**原因:** 服务商配额耗尽。 -**Fix:** +**解决方案:** -1. Check dashboard quota tracker -2. Use a combo with fallback tiers -3. Switch to cheaper/free tier +1. 检查仪表盘配额跟踪器 +2. 使用带有回退层级的组合 +3. 切换到更便宜/免费的层级 -### Rate Limiting +### 速率限制 -**Cause:** Subscription quota exhausted. +**原因:** 订阅配额耗尽。 -**Fix:** +**解决方案:** -- Add fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` -- Use GLM/MiniMax as cheap backup +- 添加回退:`cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking` +- 使用 GLM/MiniMax 作为廉价备份 -### OAuth Token Expired +### OAuth Token 过期 -OmniRoute auto-refreshes tokens. If issues persist: +OmniRoute 会自动刷新 token。如果问题持续: -1. Dashboard → Provider → Reconnect -2. Delete and re-add the provider connection +1. 仪表盘 → Provider → Reconnect +2. 删除并重新添加服务商连接 --- -## Cloud Issues +## 云端问题 -### Cloud Sync Errors +### 云同步错误 -1. Verify `BASE_URL` points to your running instance (e.g., `http://localhost:20128`) -2. Verify `CLOUD_URL` points to your cloud endpoint (e.g., `https://omniroute.dev`) -3. Keep `NEXT_PUBLIC_*` values aligned with server-side values +1. 验证 `BASE_URL` 指向您的运行实例(例如 `http://localhost:20128`) +2. 验证 `CLOUD_URL` 指向您的云端点(例如 `https://omniroute.dev`) +3. 保持 `NEXT_PUBLIC_*` 值与服务器端值一致 -### Cloud `stream=false` Returns 500 +### 云端 `stream=false` 返回 500 -**Symptom:** `Unexpected token 'd'...` on cloud endpoint for non-streaming calls. +**症状:** 非流式调用在云端点返回 `Unexpected token 'd'...`。 -**Cause:** Upstream returns SSE payload while client expects JSON. +**原因:** 上游返回 SSE 负载,而客户端期望 JSON。 -**Workaround:** Use `stream=true` for cloud direct calls. Local runtime includes SSE→JSON fallback. +**解决方法:** 对云端直接调用使用 `stream=true`。本地运行时包含 SSE→JSON 回退。 -### Cloud Says Connected but "Invalid API key" +### 云端显示已连接但 "Invalid API key" -1. Create a fresh key from local dashboard (`/api/keys`) -2. Run cloud sync: Enable Cloud → Sync Now -3. Old/non-synced keys can still return `401` on cloud +1. 从本地仪表盘创建新密钥 (`/api/keys`) +2. 运行云同步:启用云 → 立即同步 +3. 旧的/未同步的密钥在云端仍可能返回 `401` --- -## Docker Issues +## Docker 问题 -### CLI Tool Shows Not Installed +### CLI 工具显示未安装 -1. Check runtime fields: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq` -2. For portable mode: use image target `runner-cli` (bundled CLIs) -3. For host mount mode: set `CLI_EXTRA_PATHS` and mount host bin directory as read-only -4. If `installed=true` and `runnable=false`: binary was found but failed healthcheck +1. 检查运行时字段:`curl http://localhost:20128/api/cli-tools/runtime/codex | jq` +2. 便携模式:使用镜像目标 `runner-cli`(捆绑 CLI) +3. 主机挂载模式:设置 `CLI_EXTRA_PATHS` 并以只读方式挂载主机 bin 目录 +4. 如果 `installed=true` 且 `runnable=false`:找到二进制文件但健康检查失败 -### Quick Runtime Validation +### 快速运行时验证 ```bash curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' @@ -95,164 +93,164 @@ curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed, --- -## Cost Issues +## 成本问题 -### High Costs +### 高成本 -1. Check usage stats in Dashboard → Usage -2. Switch primary model to GLM/MiniMax -3. Use free tier (Gemini CLI, Qoder) for non-critical tasks -4. Set cost budgets per API key: Dashboard → API Keys → Budget +1. 在 Dashboard → Usage 检查使用统计 +2. 将主要模型切换到 GLM/MiniMax +3. 对非关键任务使用免费层(Gemini CLI、Qoder) +4. 为每个 API 密钥设置成本预算:Dashboard → API Keys → Budget --- -## Debugging +## 调试 -### Enable Request Logs +### 启用请求日志 -Set `ENABLE_REQUEST_LOGS=true` in your `.env` file. Logs appear under `logs/` directory. +在 `.env` 文件中设置 `ENABLE_REQUEST_LOGS=true`。日志出现在 `logs/` 目录下。 -### Check Provider Health +### 检查服务商健康状态 ```bash -# Health dashboard +# 健康仪表盘 http://localhost:20128/dashboard/health -# API health check +# API 健康检查 curl http://localhost:20128/api/monitoring/health ``` -### Runtime Storage +### 运行时存储 -- Main state: `${DATA_DIR}/storage.sqlite` (providers, combos, aliases, keys, settings) -- Usage: SQLite tables in `storage.sqlite` (`usage_history`, `call_logs`, `proxy_logs`) + optional `${DATA_DIR}/log.txt` and `${DATA_DIR}/call_logs/` -- Request logs: `/logs/...` (when `ENABLE_REQUEST_LOGS=true`) +- 主要状态:`${DATA_DIR}/storage.sqlite`(服务商、组合、别名、密钥、设置) +- 使用量:`storage.sqlite` 中的 SQLite 表(`usage_history`、`call_logs`、`proxy_logs`)+ 可选 `${DATA_DIR}/log.txt` 和 `${DATA_DIR}/call_logs/` +- 请求日志:`/logs/...`(当 `ENABLE_REQUEST_LOGS=true` 时) --- -## Circuit Breaker Issues +## 熔断器问题 -### Provider stuck in OPEN state +### 服务商卡在 OPEN 状态 -When a provider's circuit breaker is OPEN, requests are blocked until the cooldown expires. +当服务商的熔断器处于 OPEN 状态时,请求会被阻止直到冷却期结束。 -**Fix:** +**解决方案:** -1. Go to **Dashboard → Settings → Resilience** -2. Check the circuit breaker card for the affected provider -3. Click **Reset All** to clear all breakers, or wait for the cooldown to expire -4. Verify the provider is actually available before resetting +1. 前往 **Dashboard → Settings → Resilience** +2. 检查受影响服务商的熔断器卡片 +3. 点击 **Reset All** 清除所有熔断器,或等待冷却期结束 +4. 重置前验证服务商确实可用 -### Provider keeps tripping the circuit breaker +### 服务商反复触发熔断器 -If a provider repeatedly enters OPEN state: +如果服务商反复进入 OPEN 状态: -1. Check **Dashboard → Health → Provider Health** for the failure pattern -2. Go to **Settings → Resilience → Provider Profiles** and increase the failure threshold -3. Check if the provider has changed API limits or requires re-authentication -4. Review latency telemetry — high latency may cause timeout-based failures +1. 检查 **Dashboard → Health → Provider Health** 了解故障模式 +2. 前往 **Settings → Resilience → Provider Profiles** 增加故障阈值 +3. 检查服务商是否更改了 API 限制或需要重新认证 +4. 查看延迟遥测 — 高延迟可能导致基于超时的故障 --- -## Audio Transcription Issues +## 音频转录问题 -### "Unsupported model" error +### "Unsupported model" 错误 -- Ensure you're using the correct prefix: `deepgram/nova-3` or `assemblyai/best` -- Verify the provider is connected in **Dashboard → Providers** +- 确保使用正确的前缀:`deepgram/nova-3` 或 `assemblyai/best` +- 在 **Dashboard → Providers** 验证服务商已连接 -### Transcription returns empty or fails +### 转录返回空或失败 -- Check supported audio formats: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm` -- Verify file size is within provider limits (typically < 25MB) -- Check provider API key validity in the provider card +- 检查支持的音频格式:`mp3`、`wav`、`m4a`、`flac`、`ogg`、`webm` +- 验证文件大小在服务商限制内(通常 < 25MB) +- 在服务商卡片中检查 API 密钥有效性 --- -## Translator Debugging +## 翻译器调试 -Use **Dashboard → Translator** to debug format translation issues: +使用 **Dashboard → Translator** 调试格式翻译问题: -| Mode | When to Use | -| ---------------- | -------------------------------------------------------------------------------------------- | -| **Playground** | Compare input/output formats side by side — paste a failing request to see how it translates | -| **Chat Tester** | Send live messages and inspect the full request/response payload including headers | -| **Test Bench** | Run batch tests across format combinations to find which translations are broken | -| **Live Monitor** | Watch real-time request flow to catch intermittent translation issues | +| 模式 | 使用场景 | +| ----------------- | ------------------------------------------------------------------------------- | +| **Playground** | 并排比较输入/输出格式 — 粘贴失败的请求查看其翻译结果 | +| **Chat Tester** | 发送实时消息并检查完整的请求/响应负载(包括头部) | +| **Test Bench** | 跨格式组合运行批量测试以找出哪些翻译有问题 | +| **Live Monitor** | 观察实时请求流以捕获间歇性翻译问题 | -### Common format issues +### 常见格式问题 -- **Thinking tags not appearing** — Check if the target provider supports thinking and the thinking budget setting -- **Tool calls dropping** — Some format translations may strip unsupported fields; verify in Playground mode -- **System prompt missing** — Claude and Gemini handle system prompts differently; check translation output -- **SDK returns raw string instead of object** — Fixed in v1.1.0: response sanitizer now strips non-standard fields (`x_groq`, `usage_breakdown`, etc.) that cause OpenAI SDK Pydantic validation failures -- **GLM/ERNIE rejects `system` role** — Fixed in v1.1.0: role normalizer automatically merges system messages into user messages for incompatible models -- **`developer` role not recognized** — Fixed in v1.1.0: automatically converted to `system` for non-OpenAI providers -- **`json_schema` not working with Gemini** — Fixed in v1.1.0: `response_format` is now converted to Gemini's `responseMimeType` + `responseSchema` +- **Thinking 标签未显示** — 检查目标服务商是否支持 thinking 及 thinking budget 设置 +- **工具调用丢失** — 某些格式翻译可能剥离不支持的字段;在 Playground 模式验证 +- **系统提示缺失** — 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` --- -## Resilience Settings +## 弹性设置 -### Auto rate-limit not triggering +### 自动速率限制未触发 -- Auto rate-limit only applies to API key providers (not OAuth/subscription) -- Verify **Settings → Resilience → Provider Profiles** has auto-rate-limit enabled -- Check if the provider returns `429` status codes or `Retry-After` headers +- 自动速率限制仅适用于 API 密钥服务商(不适用于 OAuth/订阅) +- 验证 **Settings → Resilience → Provider Profiles** 已启用自动速率限制 +- 检查服务商是否返回 `429` 状态码或 `Retry-After` 头部 -### Tuning exponential backoff +### 调整指数退避 -Provider profiles support these settings: +服务商配置文件支持以下设置: -- **Base delay** — Initial wait time after first failure (default: 1s) -- **Max delay** — Maximum wait time cap (default: 30s) -- **Multiplier** — How much to increase delay per consecutive failure (default: 2x) +- **Base delay** — 首次失败后的初始等待时间(默认:1s) +- **Max delay** — 最大等待时间上限(默认:30s) +- **Multiplier** — 每次连续失败后延迟增加的倍数(默认:2x) -### Anti-thundering herd +### 防惊群效应 -When many concurrent requests hit a rate-limited provider, OmniRoute uses mutex + auto rate-limiting to serialize requests and prevent cascading failures. This is automatic for API key providers. +当多个并发请求命中速率受限的服务商时,OmniRoute 使用互斥锁 + 自动速率限制来序列化请求并防止级联故障。这对 API 密钥服务商是自动的。 --- -## Optional RAG / LLM failure taxonomy (16 problems) +## 可选 RAG / LLM 故障分类(16 个问题) -Some OmniRoute users place the gateway in front of RAG or agent stacks. In those setups it is common to see a strange pattern: OmniRoute looks healthy (providers up, routing profiles ok, no rate limit alerts) but the final answer is still wrong. +一些 OmniRoute 用户将网关放在 RAG 或代理堆栈前面。在这些设置中,常见一种奇怪的模式:OmniRoute 看起来健康(服务商运行中、路由配置正常、无速率限制告警),但最终答案仍然是错误的。 -In practice these incidents usually come from the downstream RAG pipeline, not from the gateway itself. +实际上,这些事件通常来自下游 RAG 管道,而非网关本身。 -If you want a shared vocabulary to describe those failures you can use the WFGY ProblemMap, an external MIT license text resource that defines sixteen recurring RAG / LLM failure patterns. At a high level it covers: +如果您想要描述这些故障的共享词汇,可以使用 WFGY ProblemMap,这是一个外部 MIT 许可的文本资源,定义了十六种反复出现的 RAG / LLM 故障模式。在高层次上,它涵盖: -- retrieval drift and broken context boundaries -- empty or stale indexes and vector stores -- embedding versus semantic mismatch -- prompt assembly and context window issues -- logic collapse and overconfident answers -- long chain and agent coordination failures -- multi agent memory and role drift -- deployment and bootstrap ordering problems +- 检索漂移和断裂的上下文边界 +- 空的或过时的索引和向量存储 +- 嵌入与语义不匹配 +- 提示组装和上下文窗口问题 +- 逻辑崩溃和过度自信的答案 +- 长链和代理协调故障 +- 多代理记忆和角色漂移 +- 部署和启动顺序问题 -The idea is simple: +想法很简单: -1. When you investigate a bad response, capture: - - user task and request - - route or provider combo in OmniRoute - - any RAG context used downstream (retrieved documents, tool calls, etc) -2. Map the incident to one or two WFGY ProblemMap numbers (`No.1` … `No.16`). -3. Store the number in your own dashboard, runbook, or incident tracker next to the OmniRoute logs. -4. Use the corresponding WFGY page to decide whether you need to change your RAG stack, retriever, or routing strategy. +1. 当您调查错误响应时,记录: + - 用户任务和请求 + - OmniRoute 中的路由或服务商组合 + - 下游使用的任何 RAG 上下文(检索的文档、工具调用等) +2. 将事件映射到一个或两个 WFGY ProblemMap 编号(`No.1` … `No.16`)。 +3. 在您自己的仪表盘、运行手册或事件跟踪器中将该编号存储在 OmniRoute 日志旁边。 +4. 使用相应的 WFGY 页面来决定是否需要更改您的 RAG 堆栈、检索器或路由策略。 -Full text and concrete recipes live here (MIT license, text only): +完整文本和具体方案在此处(MIT 许可,仅文本): [WFGY ProblemMap README](https://github.com/onestardao/WFGY/blob/main/ProblemMap/README.md) -You can ignore this section if you do not run RAG or agent pipelines behind OmniRoute. +如果您不在 OmniRoute 后面运行 RAG 或代理管道,可以忽略此部分。 --- -## Still Stuck? +## 仍然卡住? - **GitHub Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -- **Architecture**: See [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) for internal details -- **API Reference**: See [`docs/API_REFERENCE.md`](API_REFERENCE.md) for all endpoints -- **Health Dashboard**: Check **Dashboard → Health** for real-time system status -- **Translator**: Use **Dashboard → Translator** to debug format issues +- **架构**: 参见 [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) 了解内部细节 +- **API 参考**: 参见 [`docs/API_REFERENCE.md`](API_REFERENCE.md) 了解所有端点 +- **健康仪表盘**: 检查 **Dashboard → Health** 了解实时系统状态 +- **翻译器**: 使用 **Dashboard → Translator** 调试格式问题 diff --git a/docs/i18n/zh-CN/USER_GUIDE.md b/docs/i18n/zh-CN/USER_GUIDE.md index f65be8bf..7a527581 100644 --- a/docs/i18n/zh-CN/USER_GUIDE.md +++ b/docs/i18n/zh-CN/USER_GUIDE.md @@ -1,272 +1,268 @@ -# User Guide (中文(简体)) +# 用户指南 -🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) · 🇧🇷 [pt-BR](../pt-BR/USER_GUIDE.md) · 🇪🇸 [es](../es/USER_GUIDE.md) · 🇫🇷 [fr](../fr/USER_GUIDE.md) · 🇩🇪 [de](../de/USER_GUIDE.md) · 🇮🇹 [it](../it/USER_GUIDE.md) · 🇷🇺 [ru](../ru/USER_GUIDE.md) · 🇨🇳 [zh-CN](../zh-CN/USER_GUIDE.md) · 🇯🇵 [ja](../ja/USER_GUIDE.md) · 🇰🇷 [ko](../ko/USER_GUIDE.md) · 🇸🇦 [ar](../ar/USER_GUIDE.md) · 🇮🇳 [in](../in/USER_GUIDE.md) · 🇹🇭 [th](../th/USER_GUIDE.md) · 🇻🇳 [vi](../vi/USER_GUIDE.md) · 🇮🇩 [id](../id/USER_GUIDE.md) · 🇲🇾 [ms](../ms/USER_GUIDE.md) · 🇳🇱 [nl](../nl/USER_GUIDE.md) · 🇵🇱 [pl](../pl/USER_GUIDE.md) · 🇸🇪 [sv](../sv/USER_GUIDE.md) · 🇳🇴 [no](../no/USER_GUIDE.md) · 🇩🇰 [da](../da/USER_GUIDE.md) · 🇫🇮 [fi](../fi/USER_GUIDE.md) · 🇵🇹 [pt](../pt/USER_GUIDE.md) · 🇷🇴 [ro](../ro/USER_GUIDE.md) · 🇭🇺 [hu](../hu/USER_GUIDE.md) · 🇧🇬 [bg](../bg/USER_GUIDE.md) · 🇸🇰 [sk](../sk/USER_GUIDE.md) · 🇺🇦 [uk-UA](../uk-UA/USER_GUIDE.md) · 🇮🇱 [he](../he/USER_GUIDE.md) · 🇵🇭 [phi](../phi/USER_GUIDE.md) +🌐 **语言:** 🇺🇸 [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) | 🇨🇿 [Čeština](../cs/USER_GUIDE.md) -> 🇺🇸 [English](../../USER_GUIDE.md) +配置提供商、创建 Combo、集成 CLI 工具以及部署 OmniRoute 的完整指南。 --- -Complete guide for configuring providers, creating combos, integrating CLI tools, and deploying OmniRoute. +## 目录 + +- [价格概览](#-价格概览) +- [使用场景](#-使用场景) +- [提供商配置](#-提供商配置) +- [CLI 集成](#-cli-集成) +- [部署](#-部署) +- [可用模型](#-可用模型) +- [高级功能](#-高级功能) --- -## Table of Contents +## 💰 价格概览 -- [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) - ---- - -## 💰 Pricing at a Glance - -| Tier | Provider | Cost | Quota Reset | Best For | +| 层级 | 提供商 | 费用 | 配额重置 | 适用人群 | | ------------------- | ----------------- | ----------- | ---------------- | -------------------- | -| **💳 SUBSCRIPTION** | Claude Code (Pro) | $20/mo | 5h + weekly | Already subscribed | -| | Codex (Plus/Pro) | $20-200/mo | 5h + weekly | OpenAI users | -| | Gemini CLI | **FREE** | 180K/mo + 1K/day | Everyone! | -| | GitHub Copilot | $10-19/mo | Monthly | GitHub users | -| **🔑 API KEY** | DeepSeek | Pay per use | None | Cheap reasoning | -| | Groq | Pay per use | None | Ultra-fast inference | -| | xAI (Grok) | Pay per use | None | Grok 4 reasoning | -| | Mistral | Pay per use | None | EU-hosted models | -| | Perplexity | Pay per use | None | Search-augmented | -| | Together AI | Pay per use | None | Open-source models | -| | Fireworks AI | Pay per use | None | Fast FLUX images | -| | Cerebras | Pay per use | None | Wafer-scale speed | -| | Cohere | Pay per use | None | Command R+ RAG | -| | NVIDIA NIM | Pay per use | None | Enterprise models | -| **💰 CHEAP** | GLM-4.7 | $0.6/1M | Daily 10AM | Budget backup | -| | MiniMax M2.1 | $0.2/1M | 5-hour rolling | Cheapest option | -| | Kimi K2 | $9/mo flat | 10M tokens/mo | Predictable cost | -| **🆓 FREE** | Qoder | $0 | Unlimited | 8 models free | -| | Qwen | $0 | Unlimited | 3 models free | -| | Kiro | $0 | Unlimited | Claude free | +| **💳 订阅** | Claude Code (Pro) | $20/月 | 5小时 + 每周 | 已订阅用户 | +| | Codex (Plus/Pro) | $20-200/月 | 5小时 + 每周 | OpenAI 用户 | +| | Gemini CLI | **免费** | 18万/月 + 1千/天 | 所有人! | +| | GitHub Copilot | $10-19/月 | 每月 | GitHub 用户 | +| **🔑 API 密钥** | DeepSeek | 按量付费 | 无 | 低成本推理 | +| | Groq | 按量付费 | 无 | 超快推理 | +| | xAI (Grok) | 按量付费 | 无 | Grok 4 推理 | +| | Mistral | 按量付费 | 无 | 欧盟托管模型 | +| | Perplexity | 按量付费 | 无 | 搜索增强 | +| | Together AI | 按量付费 | 无 | 开源模型 | +| | Fireworks AI | 按量付费 | 无 | 快速 FLUX 图像 | +| | Cerebras | 按量付费 | 无 | 晶圆级速度 | +| | Cohere | 按量付费 | 无 | Command R+ RAG | +| | NVIDIA NIM | 按量付费 | 无 | 企业级模型 | +| **💰 低价** | GLM-4.7 | $0.6/1M | 每日上午10点 | 预算备用 | +| | MiniMax M2.1 | $0.2/1M | 5小时滚动 | 最便宜选项 | +| | Kimi K2 | $9/月固定 | 1000万 token/月 | 可预测成本 | +| **🆓 免费** | Qoder | $0 | 无限制 | 8个免费模型 | +| | Qwen | $0 | 无限制 | 3个免费模型 | +| | Kiro | $0 | 无限制 | Claude 免费 | -**💡 Pro Tip:** Start with Gemini CLI (180K free/month) + Qoder (unlimited free) combo = $0 cost! +**💡 专业提示:** 从 Gemini CLI(每月18万免费)+ Qoder(无限免费)组合开始 = $0 成本! --- -## 🎯 Use Cases +## 🎯 使用场景 -### Case 1: "I have Claude Pro subscription" +### 场景 1:"我有 Claude Pro 订阅" -**Problem:** Quota expires unused, rate limits during heavy 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) + 1. cc/claude-opus-4-6 (充分使用订阅) + 2. glm/glm-4.7 (配额用尽时的低价备用) + 3. if/kimi-k2-thinking (免费紧急后备) -Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total -vs. $20 + hitting limits = frustration +月费用:$20(订阅)+ ~$5(备用)= 总计 $25 +对比:$20 + 触及限制 = 沮丧 ``` -### Case 2: "I want zero cost" +### 场景 2:"我想零成本" -**Problem:** Can't afford subscriptions, need reliable AI coding +**问题:** 负担不起订阅,但需要可靠的 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) + 1. gc/gemini-3-flash (每月 18 万免费) + 2. if/kimi-k2-thinking (无限免费) + 3. qw/qwen3-coder-plus (无限免费) -Monthly cost: $0 -Quality: Production-ready models +月费用:$0 +质量:生产级模型 ``` -### Case 3: "I need 24/7 coding, no interruptions" +### 场景 3:"我需要 24/7 编程,不能中断" -**Problem:** Deadlines, can't afford 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) + 1. cc/claude-opus-4-6 (最佳质量) + 2. cx/gpt-5.2-codex (第二订阅) + 3. glm/glm-4.7 (低价,每日重置) + 4. minimax/MiniMax-M2.1 (最便宜,5小时重置) + 5. if/kimi-k2-thinking (免费无限) -Result: 5 layers of fallback = zero downtime -Monthly cost: $20-200 (subscriptions) + $10-20 (backup) +结果:5 层后备 = 零停机 +月费用:$20-200(订阅)+ $10-20(备用) ``` -### Case 4: "I want FREE AI in OpenClaw" +### 场景 4:"我想在 OpenClaw 中使用免费 AI" -**Problem:** Need AI assistant in messaging apps, completely free +**问题:** 需要在聊天应用中使用 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) + 1. if/glm-4.7 (无限免费) + 2. if/minimax-m2.1 (无限免费) + 3. if/kimi-k2-thinking (无限免费) -Monthly cost: $0 -Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal... +月费用:$0 +访问方式:WhatsApp、Telegram、Slack、Discord、iMessage、Signal... ``` --- -## 📖 Provider Setup +## 📖 提供商配置 -### 🔐 Subscription Providers +### 🔐 订阅类提供商 #### Claude Code (Pro/Max) ```bash Dashboard → Providers → Connect Claude Code -→ OAuth login → Auto token refresh -→ 5-hour + weekly quota tracking +→ OAuth 登录 → 自动刷新 Token +→ 5 小时 + 每周配额追踪 -Models: +模型: cc/claude-opus-4-6 cc/claude-sonnet-4-5-20250929 cc/claude-haiku-4-5-20251001 ``` -**Pro Tip:** Use Opus for complex tasks, Sonnet for speed. OmniRoute tracks quota per model! +**专业提示:** 复杂任务使用 Opus,追求速度使用 Sonnet。OmniRoute 为每个模型追踪配额! #### OpenAI Codex (Plus/Pro) ```bash Dashboard → Providers → Connect Codex -→ OAuth login (port 1455) -→ 5-hour + weekly reset +→ OAuth 登录(端口 1455) +→ 5 小时 + 每周重置 -Models: +模型: cx/gpt-5.2-codex cx/gpt-5.1-codex-max ``` -#### Gemini CLI (FREE 180K/month!) +#### Gemini CLI(每月 18 万免费!) ```bash Dashboard → Providers → Connect Gemini CLI → Google OAuth -→ 180K completions/month + 1K/day +→ 每月 18 万次补全 + 每日 1 千次 -Models: +模型: gc/gemini-3-flash-preview gc/gemini-2.5-pro ``` -**Best Value:** Huge free tier! Use this before paid tiers. +**最佳性价比:** 超大免费额度!优先使用此提供商。 #### GitHub Copilot ```bash Dashboard → Providers → Connect GitHub -→ OAuth via GitHub -→ Monthly reset (1st of month) +→ 通过 GitHub OAuth +→ 每月重置(每月 1 日) -Models: +模型: gh/gpt-5 gh/claude-4.5-sonnet gh/gemini-3-pro ``` -### 💰 Cheap Providers +### 💰 低价提供商 -#### GLM-4.7 (Daily reset, $0.6/1M) +#### GLM-4.7(每日重置,$0.6/1M) -1. Sign up: [Zhipu AI](https://open.bigmodel.cn/) -2. Get API key from Coding Plan -3. Dashboard → Add API Key: Provider: `glm`, API Key: `your-key` +1. 注册:[智谱 AI](https://open.bigmodel.cn/) +2. 从 Coding Plan 获取 API 密钥 +3. Dashboard → Add API Key:提供商:`glm`,API Key:`your-key` -**Use:** `glm/glm-4.7` — **Pro Tip:** Coding Plan offers 3× quota at 1/7 cost! Reset daily 10:00 AM. +**使用:** `glm/glm-4.7` — **专业提示:** Coding Plan 提供 3 倍配额,仅 1/7 成本!每日上午 10:00 重置。 -#### MiniMax M2.1 (5h reset, $0.20/1M) +#### MiniMax M2.1(5 小时重置,$0.20/1M) -1. Sign up: [MiniMax](https://www.minimax.io/) -2. Get API key → Dashboard → Add API Key +1. 注册:[MiniMax](https://www.minimax.io/) +2. 获取 API 密钥 → Dashboard → Add API Key -**Use:** `minimax/MiniMax-M2.1` — **Pro Tip:** Cheapest option for long context (1M tokens)! +**使用:** `minimax/MiniMax-M2.1` — **专业提示:** 长上下文(1M tokens)最便宜的选择! -#### Kimi K2 ($9/month flat) +#### Kimi K2(固定 $9/月) -1. Subscribe: [Moonshot AI](https://platform.moonshot.ai/) -2. Get API key → Dashboard → Add API Key +1. 订阅:[Moonshot AI](https://platform.moonshot.ai/) +2. 获取 API 密钥 → Dashboard → Add API Key -**Use:** `kimi/kimi-latest` — **Pro Tip:** Fixed $9/month for 10M tokens = $0.90/1M effective cost! +**使用:** `kimi/kimi-latest` — **专业提示:** 固定 $9/月获得 1000 万 tokens = 有效成本 $0.90/1M! -### 🆓 FREE Providers +### 🆓 免费提供商 -#### Qoder (8 FREE models) +#### Qoder(8 个免费模型) ```bash -Dashboard → Connect Qoder → OAuth login → Unlimited usage +Dashboard → Connect Qoder → OAuth 登录 → 无限使用 -Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1 +模型:if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1 ``` -#### Qwen (3 FREE models) +#### Qwen(3 个免费模型) ```bash -Dashboard → Connect Qwen → Device code auth → Unlimited usage +Dashboard → Connect Qwen → 设备码认证 → 无限使用 -Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash +模型:qw/qwen3-coder-plus, qw/qwen3-coder-flash ``` -#### Kiro (Claude FREE) +#### Kiro(免费 Claude) ```bash -Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited +Dashboard → Connect Kiro → AWS Builder ID 或 Google/GitHub → 无限 -Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5 +模型:kr/claude-sonnet-4.5, kr/claude-haiku-4.5 ``` --- ## 🎨 Combos -### Example 1: Maximize Subscription → Cheap Backup +### 示例 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) +名称:premium-coding +模型: + 1. cc/claude-opus-4-6(订阅主力) + 2. glm/glm-4.7(低价备用,$0.6/1M) + 3. minimax/MiniMax-M2.1(最便宜后备,$0.20/1M) -Use in CLI: premium-coding +在 CLI 中使用:premium-coding ``` -### Example 2: Free-Only (Zero Cost) +### 示例 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) +名称:free-combo +模型: + 1. gc/gemini-3-flash-preview(每月 18 万免费) + 2. if/kimi-k2-thinking(无限) + 3. qw/qwen3-coder-plus(无限) -Cost: $0 forever! +成本:永久 $0! ``` --- -## 🔧 CLI Integration +## 🔧 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 +Settings → Models → Advanced: + OpenAI API Base URL:http://localhost:20128/v1 + OpenAI API Key:[从 omniroute dashboard 获取] + Model:cc/claude-opus-4-6 ``` ### Claude Code -Edit `~/.claude/config.json`: +编辑 `~/.claude/config.json`: ```json { @@ -285,7 +281,7 @@ codex "your prompt" ### OpenClaw -Edit `~/.openclaw/openclaw.json`: +编辑 `~/.openclaw/openclaw.json`: ```json { @@ -307,41 +303,41 @@ Edit `~/.openclaw/openclaw.json`: } ``` -**Or use Dashboard:** CLI Tools → OpenClaw → Auto-config +**或使用 Dashboard:** CLI Tools → OpenClaw → Auto-config ### Cline / Continue / RooCode ``` -Provider: OpenAI Compatible -Base URL: http://localhost:20128/v1 -API Key: [from dashboard] -Model: cc/claude-opus-4-6 +Provider:OpenAI Compatible +Base URL:http://localhost:20128/v1 +API Key:[从 dashboard 获取] +Model:cc/claude-opus-4-6 ``` --- -## 🚀 Deployment +## 🚀 部署 -### Global npm install (Recommended) +### 全局 npm 安装(推荐) ```bash npm install -g omniroute -# Create config directory +# 创建配置目录 mkdir -p ~/.omniroute -# Create .env file (see .env.example) +# 创建 .env 文件(参见 .env.example) cp .env.example ~/.omniroute/.env -# Start server +# 启动服务器 omniroute -# Or with custom port: +# 或指定端口: omniroute --port 3000 ``` -The CLI automatically loads `.env` from `~/.omniroute/.env` or `./.env`. +CLI 自动从 `~/.omniroute/.env` 或 `./.env` 加载配置。 -### VPS Deployment +### VPS 部署 ```bash git clone https://github.com/diegosouzapw/OmniRoute.git @@ -357,25 +353,25 @@ 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 +# 或:pm2 start npm --name omniroute -- start ``` -### PM2 Deployment (Low Memory) +### PM2 部署(低内存) -For servers with limited RAM, use the memory limit option: +对于内存有限的服务器,使用内存限制选项: ```bash -# With 512MB limit (default) +# 默认 512MB 限制 pm2 start npm --name omniroute -- start -# Or with custom memory limit +# 或自定义内存限制 OMNIROUTE_MEMORY_MB=512 pm2 start npm --name omniroute -- start -# Or using ecosystem.config.js +# 或使用 ecosystem.config.js pm2 start ecosystem.config.js ``` -Create `ecosystem.config.js`: +创建 `ecosystem.config.js`: ```javascript module.exports = { @@ -400,24 +396,24 @@ module.exports = { ### Docker ```bash -# Build image (default = runner-cli with codex/claude/droid preinstalled) +# 构建镜像(默认 = runner-cli,预装 codex/claude/droid) 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 host-integrated mode with CLI binaries, see the Docker section in the main docs. +关于与主机集成的 CLI 二进制文件模式,请参阅主文档中的 Docker 部分。 ### Void Linux (xbps-src) -Void Linux users can package and install OmniRoute natively using the `xbps-src` cross-compilation framework. This automates the Node.js standalone build along with the required `better-sqlite3` native bindings. +Void Linux 用户可以使用 `xbps-src` 交叉编译框架原生打包和安装 OmniRoute。这将自动完成 Node.js standalone 构建以及所需的 `better-sqlite3` 原生绑定。
-View xbps-src template +查看 xbps-src 模板 ```bash -# Template file for 'omniroute' +# 'omniroute' 模板文件 pkgname=omniroute version=3.2.4 revision=1 @@ -509,98 +505,106 @@ post_install() {
-### Environment Variables +### 环境变量 -| Variable | Default | Description | +| 变量 | 默认值 | 描述 | | ------------------------- | ------------------------------------ | ------------------------------------------------------- | -| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signing secret (**change in production**) | -| `INITIAL_PASSWORD` | `123456` | First login password | -| `DATA_DIR` | `~/.omniroute` | Data directory (db, usage, logs) | -| `PORT` | framework default | Service port (`20128` in examples) | -| `HOSTNAME` | framework default | Bind host (Docker defaults to `0.0.0.0`) | -| `NODE_ENV` | runtime default | Set `production` for deploy | -| `BASE_URL` | `http://localhost:20128` | Server-side internal base URL | -| `CLOUD_URL` | `https://omniroute.dev` | Cloud sync endpoint base URL | -| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC secret for generated API keys | -| `REQUIRE_API_KEY` | `false` | Enforce Bearer API key on `/v1/*` | -| `ENABLE_REQUEST_LOGS` | `false` | Enables request/response logs | -| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) | -| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit in MB | -| `PROMPT_CACHE_MAX_SIZE` | `50` | Max prompt cache entries | -| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Max semantic cache entries | +| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT 签名密钥(**生产环境必须更改**) | +| `INITIAL_PASSWORD` | `123456` | 首次登录密码 | +| `DATA_DIR` | `~/.omniroute` | 数据目录(数据库、用量、日志) | +| `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 密钥 | +| `ALLOW_API_KEY_REVEAL` | `false` | 允许 Api Manager 按需复制完整 API 密钥 | +| `DISABLE_SQLITE_AUTO_BACKUP` | `false` | 在写入/导入/恢复前禁用自动 SQLite 快照;手动备份仍可用 | +| `ENABLE_REQUEST_LOGS` | `false` | 启用请求/响应日志 | +| `AUTH_COOKIE_SECURE` | `false` | 强制使用 `Secure` 认证 Cookie(HTTPS 反向代理后) | +| `CLOUDFLARED_BIN` | 未设置 | 使用现有 `cloudflared` 二进制,而不是托管下载 | +| `OMNIROUTE_MEMORY_MB` | `512` | Node.js 堆内存限制(MB) | +| `PROMPT_CACHE_MAX_SIZE` | `50` | 最大提示词缓存条目数 | +| `SEMANTIC_CACHE_MAX_SIZE` | `100` | 最大语义缓存条目数 | -For the full environment variable reference, see the [README](../README.md). +完整环境变量参考请参见 [README](../README.md)。 --- -## 📊 Available Models +## 📊 可用模型
-View all available models +查看所有可用模型 -**Claude Code (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001` +**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` +**Codex (`cx/`)** — Plus/Pro:`cx/gpt-5.2-codex`、`cx/gpt-5.1-codex-max` -**Gemini CLI (`gc/`)** — FREE: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro` +**Gemini CLI (`gc/`)** — 免费:`gc/gemini-3-flash-preview`、`gc/gemini-2.5-pro` -**GitHub Copilot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet` +**GitHub Copilot (`gh/`)**:`gh/gpt-5`、`gh/claude-4.5-sonnet` -**GLM (`glm/`)** — $0.6/1M: `glm/glm-4.7` +**GLM (`glm/`)** — $0.6/1M:`glm/glm-4.7` -**MiniMax (`minimax/`)** — $0.2/1M: `minimax/MiniMax-M2.1` +**MiniMax (`minimax/`)** — $0.2/1M:`minimax/MiniMax-M2.1` -**Qoder (`if/`)** — FREE: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1` +**Qoder (`if/`)** — 免费:`if/kimi-k2-thinking`、`if/qwen3-coder-plus`、`if/deepseek-r1` -**Qwen (`qw/`)** — FREE: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash` +**Qwen (`qw/`)** — 免费:`qw/qwen3-coder-plus`、`qw/qwen3-coder-flash` -**Kiro (`kr/`)** — FREE: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5` +**Kiro (`kr/`)** — 免费:`kr/claude-sonnet-4.5`、`kr/claude-haiku-4.5` -**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner` +**DeepSeek (`ds/`)**:`ds/deepseek-chat`、`ds/deepseek-reasoner` -**Groq (`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct` +**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` +**xAI (`xai/`)**:`xai/grok-4`、`xai/grok-4-0709-fast-reasoning`、`xai/grok-code-mini` -**Mistral (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501` +**Mistral (`mistral/`)**:`mistral/mistral-large-2501`、`mistral/codestral-2501` -**Perplexity (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar` +**Perplexity (`pplx/`)**:`pplx/sonar-pro`、`pplx/sonar` -**Together AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo` +**Together AI (`together/`)**:`together/meta-llama/Llama-3.3-70B-Instruct-Turbo` -**Fireworks AI (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1` +**Fireworks AI (`fireworks/`)**:`fireworks/accounts/fireworks/models/deepseek-v3p1` -**Cerebras (`cerebras/`)**: `cerebras/llama-3.3-70b` +**Cerebras (`cerebras/`)**:`cerebras/llama-3.3-70b` -**Cohere (`cohere/`)**: `cohere/command-r-plus-08-2024` +**Cohere (`cohere/`)**:`cohere/command-r-plus-08-2024` -**NVIDIA NIM (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct` +**NVIDIA NIM (`nvidia/`)**:`nvidia/nvidia/llama-3.3-70b-instruct`
--- -## 🧩 Advanced Features +## 🧩 高级功能 -### Custom Models +### 自定义模型 -Add any model ID to any provider without waiting for an app update: +无需等待应用更新即可为任何提供商添加任意模型 ID: ```bash -# Via API +# 通过 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" +# 列表:curl http://localhost:20128/api/provider-models?provider=openai +# 删除:curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview" ``` -Or use Dashboard: **Providers → [Provider] → Custom Models**. +或使用 Dashboard:**Providers → [提供商] → Custom Models**。 -### Dedicated Provider Routes +说明: -Route requests directly to a specific provider with model validation: +- OpenRouter 和 OpenAI/Anthropic-compatible 提供商仅通过 **Available Models** 管理。手动添加、导入和自动同步都会写入同一份 available-model 列表,因此这些提供商没有单独的 Custom Models 区块。 +- **Custom Models** 区块面向那些不提供托管 available-model 导入的提供商。 + +### 专用提供商路由 + +直接将请求路由到特定提供商并进行模型验证: ```bash POST http://localhost:20128/v1/providers/openai/chat/completions @@ -608,110 +612,118 @@ POST http://localhost:20128/v1/providers/openai/embeddings POST http://localhost:20128/v1/providers/fireworks/images/generations ``` -The provider prefix is auto-added if missing. Mismatched models return `400`. +如果缺少提供商前缀则自动添加。模型不匹配时返回 `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. +**优先级:** 密钥级 → Combo 级 → 提供商级 → 全局 → 环境变量。 -### Model Catalog API +### 模型目录 API ```bash curl http://localhost:20128/api/models/catalog ``` -Returns models grouped by provider with types (`chat`, `embedding`, `image`). +返回按提供商分组的模型及类型(`chat`、`embedding`、`image`)。 -### Cloud Sync +### 云同步 -- Sync providers, combos, and settings across devices -- Automatic background sync with timeout + fail-fast -- Prefer server-side `BASE_URL`/`CLOUD_URL` in production +- 跨设备同步提供商、Combo 和设置 +- 自动后台同步,带超时 + 快速失败 +- 生产环境优先使用服务端 `BASE_URL`/`CLOUD_URL` -### LLM Gateway Intelligence (Phase 9) +### Cloudflare Quick Tunnel -- **Semantic Cache** — Auto-caches non-streaming, temperature=0 responses (bypass with `X-OmniRoute-No-Cache: true`) -- **Request Idempotency** — Deduplicates requests within 5s via `Idempotency-Key` or `X-Request-Id` header -- **Progress Tracking** — Opt-in SSE `event: progress` events via `X-OmniRoute-Progress: true` header +- 可在 **Dashboard → Endpoints** 中用于 Docker 和其他自托管部署 +- 会创建一个临时的 `https://*.trycloudflare.com` URL,并转发到当前 OpenAI 兼容的 `/v1` 端点 +- 首次启用时仅在需要时安装 `cloudflared`;之后重启会复用同一个托管二进制文件 +- Tunnel URL 是临时的,每次停止/启动隧道都会变化 +- 如果你更想使用预装的 `cloudflared`,可以设置 `CLOUDFLARED_BIN` + +### LLM 网关智能(第 9 阶段) + +- **语义缓存** — 自动缓存非流式、temperature=0 的响应(使用 `X-OmniRoute-No-Cache: true` 绕过) +- **请求幂等性** — 通过 `Idempotency-Key` 或 `X-Request-Id` 头在 5 秒内去重请求 +- **进度追踪** — 通过 `X-OmniRoute-Progress: true` 头选择性启用 SSE `event: progress` 事件 --- -### Translator Playground +### 翻译器实验场 -Access via **Dashboard → Translator**. Debug and visualize how OmniRoute translates API requests between providers. +通过 **Dashboard → Translator** 访问。调试和可视化 OmniRoute 如何在提供商之间翻译 API 请求。 -| Mode | Purpose | -| ---------------- | -------------------------------------------------------------------------------------- | -| **Playground** | Select source/target formats, paste a request, and see the translated output instantly | -| **Chat Tester** | Send live chat messages through the proxy and inspect the full request/response cycle | -| **Test Bench** | Run batch tests across multiple format combinations to verify translation correctness | -| **Live Monitor** | Watch real-time translations as requests flow through the proxy | +| 模式 | 用途 | +| ---------------- | ------------------------------------------------------------------------------ | +| **Playground** | 选择源/目标格式,粘贴请求,即时查看翻译输出 | +| **Chat Tester** | 通过代理发送实时聊天消息,检查完整的请求/响应周期 | +| **Test Bench** | 在多种格式组合中运行批量测试,验证翻译正确性 | +| **Live Monitor** | 实时观察请求流经代理时的翻译过程 | -**Use cases:** +**使用场景:** -- Debug why a specific client/provider combination fails -- Verify that thinking tags, tool calls, and system prompts translate correctly -- Compare format differences between OpenAI, Claude, Gemini, and Responses API formats +- 调试特定客户端/提供商组合失败的原因 +- 验证 thinking 标签、工具调用和系统提示词是否正确翻译 +- 比较 OpenAI、Claude、Gemini 和 Responses API 格式之间的差异 --- -### Routing Strategies +### 路由策略 -Configure via **Dashboard → Settings → Routing**. +通过 **Dashboard → Settings → Routing** 配置。 -| Strategy | Description | -| ------------------------------ | ------------------------------------------------------------------------------------------------ | -| **Fill First** | Uses accounts in priority order — primary account handles all requests until unavailable | -| **Round Robin** | Cycles through all accounts with a configurable sticky limit (default: 3 calls per account) | -| **P2C (Power of Two Choices)** | Picks 2 random accounts and routes to the healthier one — balances load with awareness of health | -| **Random** | Randomly selects an account for each request using Fisher-Yates shuffle | -| **Least Used** | Routes to the account with the oldest `lastUsedAt` timestamp, distributing traffic evenly | -| **Cost Optimized** | Routes to the account with the lowest priority value, optimizing for lowest-cost providers | +| 策略 | 描述 | +| ------------------------------ | ---------------------------------------------------------------------------------------- | +| **Fill First** | 按优先级顺序使用账户 — 主账户处理所有请求直到不可用 | +| **Round Robin** | 循环使用所有账户,可配置粘性限制(默认:每账户 3 次调用) | +| **P2C (Power of Two Choices)** | 随机选择 2 个账户并路由到更健康的那个 — 健康感知的负载均衡 | +| **Random** | 使用 Fisher-Yates 洗牌为每个请求随机选择账户 | +| **Least Used** | 路由到 `lastUsedAt` 时间戳最旧的账户,均匀分配流量 | +| **Cost Optimized** | 路由到优先级值最低的账户,优化成本最低的提供商 | -#### External Sticky Session Header +#### 外部粘性会话头 -For external session affinity (for example, Claude Code/Codex agents behind reverse proxies), send: +用于外部会话亲和性(例如,反向代理后的 Claude Code/Codex 代理),发送: ```http X-Session-Id: your-session-key ``` -OmniRoute also accepts `x_session_id` and returns the effective session key in `X-OmniRoute-Session-Id`. +OmniRoute 也接受 `x_session_id` 并在 `X-OmniRoute-Session-Id` 中返回有效的会话密钥。 -If you use Nginx and send underscore-form headers, enable: +如果使用 Nginx 发送下划线形式的头,需启用: ```nginx underscores_in_headers on; ``` -#### Wildcard Model Aliases +#### 通配符模型别名 -Create wildcard patterns to remap model names: +创建通配符模式以重映射模型名称: ``` Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929 Pattern: gpt-* → Target: gh/gpt-5.1-codex ``` -Wildcards support `*` (any characters) and `?` (single character). +通配符支持 `*`(任意字符)和 `?`(单个字符)。 -#### Fallback Chains +#### 后备链 -Define global fallback chains that apply across all requests: +定义适用于所有请求的全局后备链: ``` Chain: production-fallback @@ -722,208 +734,209 @@ Chain: production-fallback --- -### Resilience & Circuit Breakers +### 弹性与熔断器 -Configure via **Dashboard → Settings → Resilience**. +通过 **Dashboard → Settings → Resilience** 配置。 -OmniRoute implements provider-level resilience with four components: +OmniRoute 实现了提供商级别的弹性保护,包含四个组件: -1. **Provider Profiles** — Per-provider configuration for: - - Failure threshold (how many failures before opening) - - Cooldown duration - - Rate limit detection sensitivity - - Exponential backoff parameters +1. **提供商配置文件** — 每个提供商的配置: + - 失败阈值(开启熔断前的失败次数) + - 冷却持续时间 + - 速率限制检测灵敏度 + - 指数退避参数 -2. **Editable Rate Limits** — System-level defaults configurable in the dashboard: - - **Requests Per Minute (RPM)** — Maximum requests per minute per account - - **Min Time Between Requests** — Minimum gap in milliseconds between requests - - **Max Concurrent Requests** — Maximum simultaneous requests per account - - Click **Edit** to modify, then **Save** or **Cancel**. Values persist via the resilience API. +2. **可编辑速率限制** — 可在 Dashboard 中配置的系统级默认值: + - **每分钟请求数 (RPM)** — 每个账户每分钟最大请求数 + - **请求最小间隔** — 请求之间的最小间隔(毫秒) + - **最大并发请求数** — 每个账户的最大并发请求数 + - 点击 **Edit** 修改,然后 **Save** 或 **Cancel**。值通过弹性 API 持久化。 -3. **Circuit Breaker** — Tracks failures per provider and automatically opens the circuit when a threshold is reached: - - **CLOSED** (Healthy) — Requests flow normally - - **OPEN** — Provider is temporarily blocked after repeated failures - - **HALF_OPEN** — Testing if provider has recovered +3. **熔断器** — 按提供商追踪失败次数,达到阈值时自动开启熔断: + - **CLOSED**(健康)— 请求正常流动 + - **OPEN** — 重复失败后提供商被临时阻止 + - **HALF_OPEN** — 测试提供商是否已恢复 -4. **Policies & Locked Identifiers** — Shows circuit breaker status and locked identifiers with force-unlock capability. +4. **策略与锁定标识符** — 显示熔断器状态和锁定标识符,支持强制解锁。 -5. **Rate Limit Auto-Detection** — Monitors `429` and `Retry-After` headers to proactively avoid hitting provider rate limits. +5. **速率限制自动检测** — 监控 `429` 和 `Retry-After` 头,主动避免触及提供商速率限制。 -**Pro Tip:** Use **Reset All** button to clear all circuit breakers and cooldowns when a provider recovers from an outage. +**专业提示:** 当提供商从故障中恢复时,使用 **Reset All** 按钮清除所有熔断器和冷却状态。 --- -### Database Export / Import +### 数据库导出/导入 -Manage database backups in **Dashboard → Settings → System & Storage**. +在 **Dashboard → Settings → System & Storage** 中管理数据库备份。 -| Action | Description | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | -| **Export Database** | Downloads the current SQLite database as a `.sqlite` file | -| **Export All (.tar.gz)** | Downloads a full backup archive including: database, settings, combos, provider connections (no credentials), API key metadata | -| **Import Database** | Upload a `.sqlite` file to replace the current database. A pre-import backup is automatically created | +| 操作 | 描述 | +| ------------------------ | ------------------------------------------------------------------------------------------------------ | +| **Export Database** | 将当前 SQLite 数据库下载为 `.sqlite` 文件 | +| **Export All (.tar.gz)** | 下载完整备份归档,包括:数据库、设置、Combo、提供商连接(无凭据)、API 密钥元数据 | +| **Import Database** | 上传 `.sqlite` 文件替换当前数据库。导入前会自动创建备份 | ```bash -# API: Export database +# API:导出数据库 curl -o backup.sqlite http://localhost:20128/api/db-backups/export -# API: Export all (full archive) +# API:导出全部(完整归档) curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll -# API: Import database +# API:导入数据库 curl -X POST http://localhost:20128/api/db-backups/import \ -F "file=@backup.sqlite" ``` -**Import Validation:** The imported file is validated for integrity (SQLite pragma check), required tables (`provider_connections`, `provider_nodes`, `combos`, `api_keys`), and size (max 100MB). +**导入验证:** 导入的文件会验证完整性(SQLite pragma 检查)、必需表(`provider_connections`、`provider_nodes`、`combos`、`api_keys`)和大小(最大 100MB)。 -**Use Cases:** +**使用场景:** -- Migrate OmniRoute between machines -- Create external backups for disaster recovery -- Share configurations between team members (export all → share archive) +- 在机器之间迁移 OmniRoute +- 为灾难恢复创建外部备份 +- 在团队成员之间共享配置(导出全部 → 分享归档) --- -### Settings Dashboard +### 设置仪表盘 -The settings page is organized into 5 tabs for easy navigation: +设置页面分为 6 个标签页便于导航: -| Tab | Contents | +| 标签页 | 内容 | | -------------- | ---------------------------------------------------------------------------------------------- | -| **Security** | Login/Password settings, IP Access Control, API auth for `/models`, and Provider Blocking | -| **Routing** | Global routing strategy (6 options), wildcard model aliases, fallback chains, combo defaults | -| **Resilience** | Provider profiles, editable rate limits, circuit breaker status, policies & locked identifiers | -| **AI** | Thinking budget configuration, global system prompt injection, prompt cache stats | -| **Advanced** | Global proxy configuration (HTTP/SOCKS5) | +| **General** | 系统存储工具、外观设置、主题控制,以及侧边栏项目的单项可见性 | +| **Security** | 登录/密码设置、IP 访问控制、`/models` API 认证、提供商阻止 | +| **Routing** | 全局路由策略(6 种选项)、通配符模型别名、后备链、Combo 默认值 | +| **Resilience** | 提供商配置文件、可编辑速率限制、熔断器状态、策略与锁定标识符 | +| **AI** | Thinking 预算配置、全局系统提示词注入、提示词缓存统计 | +| **Advanced** | 全局代理配置(HTTP/SOCKS5) | --- -### Costs & Budget Management +### 成本与预算管理 -Access via **Dashboard → Costs**. +通过 **Dashboard → Costs** 访问。 -| Tab | Purpose | -| ----------- | ---------------------------------------------------------------------------------------- | -| **Budget** | Set spending limits per API key with daily/weekly/monthly budgets and real-time tracking | -| **Pricing** | View and edit model pricing entries — cost per 1K input/output tokens per provider | +| 标签页 | 用途 | +| ----------- | -------------------------------------------------------------------------------- | +| **Budget** | 为每个 API 密钥设置消费限额,支持每日/每周/每月预算和实时追踪 | +| **Pricing** | 查看和编辑模型定价条目 — 每提供商每 1K 输入/输出 token 的成本 | ```bash -# API: Set a budget +# API:设置预算 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 +# API:获取当前预算状态 curl http://localhost:20128/api/usage/budget ``` -**Cost Tracking:** Every request logs token usage and calculates cost using the pricing table. View breakdowns in **Dashboard → Usage** by provider, model, and API key. +**成本追踪:** 每个请求都会记录 token 用量并使用定价表计算成本。在 **Dashboard → Usage** 中按提供商、模型和 API 密钥查看明细。 --- -### Audio Transcription +### 音频转录 -OmniRoute supports audio transcription via the OpenAI-compatible endpoint: +OmniRoute 通过 OpenAI 兼容端点支持音频转录: ```bash POST /v1/audio/transcriptions Authorization: Bearer your-api-key Content-Type: multipart/form-data -# Example with curl +# 使用 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" ``` -Available providers: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`). +可用提供商:**Deepgram** (`deepgram/`)、**AssemblyAI** (`assemblyai/`)。 -Supported audio formats: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. +支持的音频格式:`mp3`、`wav`、`m4a`、`flac`、`ogg`、`webm`。 --- -### Combo Balancing Strategies +### Combo 均衡策略 -Configure per-combo balancing in **Dashboard → Combos → Create/Edit → Strategy**. +在 **Dashboard → Combos → Create/Edit → Strategy** 中配置每个 Combo 的均衡策略。 -| Strategy | Description | -| ------------------ | ------------------------------------------------------------------------ | -| **Round-Robin** | Rotates through models sequentially | -| **Priority** | Always tries the first model; falls back only on error | -| **Random** | Picks a random model from the combo for each request | -| **Weighted** | Routes proportionally based on assigned weights per model | -| **Least-Used** | Routes to the model with the fewest recent requests (uses combo metrics) | -| **Cost-Optimized** | Routes to the cheapest available model (uses pricing table) | +| 策略 | 描述 | +| ------------------ | ---------------------------------------------------------------- | +| **Round-Robin** | 按顺序轮流使用模型 | +| **Priority** | 总是先尝试第一个模型;仅在出错时使用后备 | +| **Random** | 为每个请求从 Combo 中随机选择一个模型 | +| **Weighted** | 根据每个模型分配的权重按比例路由 | +| **Least-Used** | 路由到最近请求最少的模型(使用 Combo 指标) | +| **Cost-Optimized** | 路由到最便宜的可用模型(使用定价表) | -Global combo defaults can be set in **Dashboard → Settings → Routing → Combo Defaults**. +全局 Combo 默认值可在 **Dashboard → Settings → Routing → Combo Defaults** 中设置。 --- -### Health Dashboard +### 健康仪表盘 -Access via **Dashboard → Health**. Real-time system health overview with 6 cards: +通过 **Dashboard → Health** 访问。包含 6 张卡片的实时系统健康概览: -| Card | What It Shows | +| 卡片 | 显示内容 | | --------------------- | ----------------------------------------------------------- | -| **System Status** | Uptime, version, memory usage, data directory | -| **Provider Health** | Per-provider circuit breaker state (Closed/Open/Half-Open) | -| **Rate Limits** | Active rate limit cooldowns per account with remaining time | -| **Active Lockouts** | Providers temporarily blocked by the lockout policy | -| **Signature Cache** | Deduplication cache stats (active keys, hit rate) | -| **Latency Telemetry** | p50/p95/p99 latency aggregation per provider | +| **System Status** | 运行时间、版本、内存用量、数据目录 | +| **Provider Health** | 每个提供商的熔断器状态(Closed/Open/Half-Open) | +| **Rate Limits** | 每个账户的活跃速率限制冷却及剩余时间 | +| **Active Lockouts** | 被锁定策略临时阻止的提供商 | +| **Signature Cache** | 去重缓存统计(活跃密钥数、命中率) | +| **Latency Telemetry** | 每个提供商的 p50/p95/p99 延迟聚合 | -**Pro Tip:** The Health page auto-refreshes every 10 seconds. Use the circuit breaker card to identify which providers are experiencing issues. +**专业提示:** 健康页面每 10 秒自动刷新。使用熔断器卡片识别哪些提供商正在遇到问题。 --- -## 🖥️ Desktop Application (Electron) +## 🖥️ 桌面应用(Electron) -OmniRoute is available as a native desktop application for Windows, macOS, and Linux. +OmniRoute 提供适用于 Windows、macOS 和 Linux 的原生桌面应用。 ### 安装 ```bash -# From the electron directory: +# 在 electron 目录中: cd electron npm install -# Development mode (connect to running Next.js dev server): +# 开发模式(连接到运行中的 Next.js 开发服务器): npm run dev -# Production mode (uses standalone build): +# 生产模式(使用 standalone 构建): npm start ``` -### Building Installers +### 构建安装程序 ```bash cd electron -npm run build # Current platform +npm run build # 当前平台 npm run build:win # Windows (.exe NSIS) npm run build:mac # macOS (.dmg universal) npm run build:linux # Linux (.AppImage) ``` -Output → `electron/dist-electron/` +输出目录 → `electron/dist-electron/` -### Key Features +### 主要功能 -| Feature | Description | +| 功能 | 描述 | | --------------------------- | ---------------------------------------------------- | -| **Server Readiness** | Polls server before showing window (no blank screen) | -| **System Tray** | Minimize to tray, change port, quit from tray menu | -| **Port Management** | Change server port from tray (auto-restarts server) | -| **Content Security Policy** | Restrictive CSP via session headers | -| **Single Instance** | Only one app instance can run at a time | -| **Offline Mode** | Bundled Next.js server works without internet | +| **Server Readiness** | 显示窗口前轮询服务器(无空白屏幕) | +| **System Tray** | 最小化到托盘、更改端口、从托盘菜单退出 | +| **Port Management** | 从托盘更改服务器端口(自动重启服务器) | +| **Content Security Policy** | 通过会话头实现限制性 CSP | +| **Single Instance** | 同一时间只能运行一个应用实例 | +| **Offline Mode** | 打包的 Next.js 服务器可离线工作 | -### Environment Variables +### 环境变量 -| Variable | Default | Description | +| 变量 | 默认值 | 描述 | | --------------------- | ------- | -------------------------------- | -| `OMNIROUTE_PORT` | `20128` | Server port | -| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit (64–16384 MB) | +| `OMNIROUTE_PORT` | `20128` | 服务器端口 | +| `OMNIROUTE_MEMORY_MB` | `512` | Node.js 堆内存限制(64–16384 MB)| -📖 Full documentation: [`electron/README.md`](../electron/README.md) +📖 完整文档:[`electron/README.md`](../electron/README.md) diff --git a/docs/i18n/zh-CN/VM_DEPLOYMENT_GUIDE.md b/docs/i18n/zh-CN/VM_DEPLOYMENT_GUIDE.md index 1d60f00f..60c31aa1 100644 --- a/docs/i18n/zh-CN/VM_DEPLOYMENT_GUIDE.md +++ b/docs/i18n/zh-CN/VM_DEPLOYMENT_GUIDE.md @@ -1,36 +1,36 @@ # OmniRoute — 使用 Cloudflare 在虚拟机上部署指南 -🌐 **Languages:** 🇺🇸 [English](../../VM_DEPLOYMENT_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/VM_DEPLOYMENT_GUIDE.md) | 🇪🇸 [Español](../es/VM_DEPLOYMENT_GUIDE.md) | 🇫🇷 [Français](../fr/VM_DEPLOYMENT_GUIDE.md) | 🇮🇹 [Italiano](../it/VM_DEPLOYMENT_GUIDE.md) | 🇷🇺 [Русский](../ru/VM_DEPLOYMENT_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/VM_DEPLOYMENT_GUIDE.md) | 🇩🇪 [Deutsch](../de/VM_DEPLOYMENT_GUIDE.md) | 🇮🇳 [हिन्दी](../in/VM_DEPLOYMENT_GUIDE.md) | 🇹🇭 [ไทย](../th/VM_DEPLOYMENT_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/VM_DEPLOYMENT_GUIDE.md) | 🇸🇦 [العربية](../ar/VM_DEPLOYMENT_GUIDE.md) | 🇯🇵 [日本語](../ja/VM_DEPLOYMENT_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/VM_DEPLOYMENT_GUIDE.md) | 🇧🇬 [Български](../bg/VM_DEPLOYMENT_GUIDE.md) | 🇩🇰 [Dansk](../da/VM_DEPLOYMENT_GUIDE.md) | 🇫🇮 [Suomi](../fi/VM_DEPLOYMENT_GUIDE.md) | 🇮🇱 [עברית](../he/VM_DEPLOYMENT_GUIDE.md) | 🇭🇺 [Magyar](../hu/VM_DEPLOYMENT_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/VM_DEPLOYMENT_GUIDE.md) | 🇰🇷 [한국어](../ko/VM_DEPLOYMENT_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/VM_DEPLOYMENT_GUIDE.md) | 🇳🇱 [Nederlands](../nl/VM_DEPLOYMENT_GUIDE.md) | 🇳🇴 [Norsk](../no/VM_DEPLOYMENT_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/VM_DEPLOYMENT_GUIDE.md) | 🇷🇴 [Română](../ro/VM_DEPLOYMENT_GUIDE.md) | 🇵🇱 [Polski](../pl/VM_DEPLOYMENT_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/VM_DEPLOYMENT_GUIDE.md) | 🇸🇪 [Svenska](../sv/VM_DEPLOYMENT_GUIDE.md) | 🇵🇭 [Filipino](../phi/VM_DEPLOYMENT_GUIDE.md) | 🇨🇿 [Čeština](../cs/VM_DEPLOYMENT_GUIDE.md) +🌐 **语言:** 🇺🇸 [English](../../VM_DEPLOYMENT_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/VM_DEPLOYMENT_GUIDE.md) | 🇪🇸 [Español](../es/VM_DEPLOYMENT_GUIDE.md) | 🇫🇷 [Français](../fr/VM_DEPLOYMENT_GUIDE.md) | 🇮🇹 [Italiano](../it/VM_DEPLOYMENT_GUIDE.md) | 🇷🇺 [Русский](../ru/VM_DEPLOYMENT_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/VM_DEPLOYMENT_GUIDE.md) | 🇩🇪 [Deutsch](../de/VM_DEPLOYMENT_GUIDE.md) | 🇮🇳 [हिन्दी](../in/VM_DEPLOYMENT_GUIDE.md) | 🇹🇭 [ไทย](../th/VM_DEPLOYMENT_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/VM_DEPLOYMENT_GUIDE.md) | 🇸🇦 [العربية](../ar/VM_DEPLOYMENT_GUIDE.md) | 🇯🇵 [日本語](../ja/VM_DEPLOYMENT_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/VM_DEPLOYMENT_GUIDE.md) | 🇧🇬 [Български](../bg/VM_DEPLOYMENT_GUIDE.md) | 🇩🇰 [Dansk](../da/VM_DEPLOYMENT_GUIDE.md) | 🇫🇮 [Suomi](../fi/VM_DEPLOYMENT_GUIDE.md) | 🇮🇱 [עברית](../he/VM_DEPLOYMENT_GUIDE.md) | 🇭🇺 [Magyar](../hu/VM_DEPLOYMENT_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/VM_DEPLOYMENT_GUIDE.md) | 🇰🇷 [한국어](../ko/VM_DEPLOYMENT_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/VM_DEPLOYMENT_GUIDE.md) | 🇳🇱 [Nederlands](../nl/VM_DEPLOYMENT_GUIDE.md) | 🇳🇴 [Norsk](../no/VM_DEPLOYMENT_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/VM_DEPLOYMENT_GUIDE.md) | 🇷🇴 [Română](../ro/VM_DEPLOYMENT_GUIDE.md) | 🇵🇱 [Polski](../pl/VM_DEPLOYMENT_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/VM_DEPLOYMENT_GUIDE.md) | 🇸🇪 [Svenska](../sv/VM_DEPLOYMENT_GUIDE.md) | 🇵🇭 [Filipino](../phi/VM_DEPLOYMENT_GUIDE.md) | 🇨🇿 [Čeština](../cs/VM_DEPLOYMENT_GUIDE.md) -在通过 Cloudflare 管理域的 VM (VPS) 上安装和配置 OmniRoute 的完整指南。 +在通过 Cloudflare 管理域名的 VM (VPS) 上安装和配置 OmniRoute 的完整指南。 --- ## 先决条件 -| 项目 | 最低 | 推荐 | -| ------------ | -------------------- | --------------------------------- | ---------------- | -| **CPU** | 1 个虚拟CPU | 2 个虚拟CPU | -| **内存** | 1 GB | 2GB | -| **磁盘** | 10 GB 固态硬盘 | 25 GB 固态硬盘 | -| **操作系统** | Ubuntu 22.04 LTS | Ubuntu 22.04 LTS Ubuntu 24.04 LTS | Ubuntu 24.04 LTS | -| **域名** | 在 Cloudflare 上注册 | — | -| **码头工人** | Docker 引擎 24+ | Docker 27+ | +| 项目 | 最低要求 | 推荐 | +| ------------ | -------------------- | ------------------ | +| **CPU** | 1 vCPU | 2 vCPU | +| **内存** | 1 GB | 2 GB | +| **磁盘** | 10 GB SSD | 25 GB SSD | +| **操作系统** | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS | +| **域名** | 在 Cloudflare 上注册 | — | +| **Docker** | Docker Engine 24+ | Docker 27+ | -**经过测试的提供商**:Akamai (Linode)、DigitalOcean、Vultr、Hetzner、AWS Lightsail。 +**已测试的服务商**:Akamai (Linode)、DigitalOcean、Vultr、Hetzner、AWS Lightsail。 --- -## 1.配置虚拟机 +## 1. 配置虚拟机 ### 1.1 创建实例 -在您首选的 VPS 提供商上: +在您首选的 VPS 服务商上: - 选择 Ubuntu 24.04 LTS -- 选择最低计划(1 vCPU / 1 GB RAM) -- 设置强root密码或配置SSH密钥 -- 记下 **公共 IP**(例如 `203.0.113.10`) +- 选择最低配置(1 vCPU / 1 GB RAM) +- 设置强 root 密码或配置 SSH 密钥 +- 记下**公网 IP**(例如 `203.0.113.10`) ### 1.2 通过 SSH 连接 @@ -47,10 +47,10 @@ apt update && apt upgrade -y ### 1.4 安装 Docker ```bash -# Install dependencies +# 安装依赖 apt install -y ca-certificates curl gnupg -# Add official Docker repository +# 添加官方 Docker 仓库 install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg @@ -59,24 +59,24 @@ apt update apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin ``` -### 1.5 安装nginx +### 1.5 安装 nginx ```bash apt install -y nginx ``` -### 1.6 配置防火墙(UFW) +### 1.6 配置防火墙 (UFW) ```bash ufw default deny incoming ufw default allow outgoing ufw allow 22/tcp # SSH -ufw allow 80/tcp # HTTP (redirect) +ufw allow 80/tcp # HTTP(重定向) ufw allow 443/tcp # HTTPS ufw enable ``` -> **提示**:为了获得最大的安全性,请将端口 80 和 443 仅限制为 Cloudflare IP。请参阅 [Advanced Security](#advanced-security) 部分。 +> **提示**:为获得最高安全性,请将端口 80 和 443 仅限制为 Cloudflare IP。参见[高级安全](#6-高级安全性)部分。 --- @@ -92,7 +92,7 @@ mkdir -p /opt/omniroute ```bash cat > /opt/omniroute/.env << ‘EOF’ -# === Security === +# === 安全配置 === JWT_SECRET=CHANGE-TO-A-UNIQUE-64-CHAR-SECRET-KEY INITIAL_PASSWORD=YourSecurePassword123! API_KEY_SECRET=REPLACE-WITH-ANOTHER-SECRET-KEY @@ -100,7 +100,7 @@ STORAGE_ENCRYPTION_KEY=REPLACE-WITH-THIRD-SECRET-KEY STORAGE_ENCRYPTION_KEY_VERSION=v1 MACHINE_ID_SALT=CHANGE-TO-A-UNIQUE-SALT -# === App === +# === 应用配置 === PORT=20128 NODE_ENV=production HOSTNAME=0.0.0.0 @@ -110,11 +110,11 @@ ENABLE_REQUEST_LOGS=true AUTH_COOKIE_SECURE=false REQUIRE_API_KEY=false -# === Domain (change to your domain) === +# === 域名(修改为您的域名) === BASE_URL=https://llms.seudominio.com NEXT_PUBLIC_BASE_URL=https://llms.seudominio.com -# === Cloud Sync (optional) === +# === 云同步(可选) === # CLOUD_URL=https://cloud.omniroute.online # NEXT_PUBLIC_CLOUD_URL=https://cloud.omniroute.online EOF @@ -136,35 +136,35 @@ docker run -d \ diegosouzapw/omniroute:latest ``` -### 2.4 验证其是否正在运行 +### 2.4 验证运行状态 ```bash docker ps | grep omniroute docker logs omniroute --tail 20 ``` -它应显示:`[DB] SQLite database ready` 和 `listening on port 20128`。 +应显示:`[DB] SQLite database ready` 和 `listening on port 20128`。 --- -## 3.配置nginx(反向代理) +## 3. 配置 nginx(反向代理) ### 3.1 生成 SSL 证书(Cloudflare Origin) 在 Cloudflare 仪表板中: -1. 转到 **SSL/TLS → 源服务器** -2. 单击**创建证书** -3. 保留默认值(15 年,\*.yourdomain.com) -4. 复制**原始证书**和**私钥** +1. 前往 **SSL/TLS → Origin Server** +2. 点击 **Create Certificate** +3. 保持默认设置(15 年,\*.yourdomain.com) +4. 复制 **Origin Certificate** 和 **Private Key** ```bash mkdir -p /etc/nginx/ssl -# Paste the certificate +# 粘贴证书 nano /etc/nginx/ssl/origin.crt -# Paste the private key +# 粘贴私钥 nano /etc/nginx/ssl/origin.key chmod 600 /etc/nginx/ssl/origin.key @@ -174,7 +174,7 @@ chmod 600 /etc/nginx/ssl/origin.key ```bash cat > /etc/nginx/sites-available/omniroute << ‘NGINX’ -# Default server — blocks direct access via IP +# 默认服务器 — 阻止通过 IP 直接访问 server { listen 80 default_server; listen [::]:80 default_server; @@ -190,7 +190,7 @@ server { server { listen 443 ssl; listen [::]:443 ssl; - server_name llms.yourdomain.com; # Change to your domain + server_name llms.yourdomain.com; # 修改为您的域名 ssl_certificate /etc/nginx/ssl/origin.crt; ssl_certificate_key /etc/nginx/ssl/origin.key; @@ -205,12 +205,12 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - # WebSocket support + # WebSocket 支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; - # SSE (Server-Sent Events) — streaming AI responses + # SSE (Server-Sent Events) — AI 流式响应 proxy_buffering off; proxy_cache off; proxy_read_timeout 300s; @@ -218,7 +218,7 @@ server { } } -# HTTP → HTTPS redirect +# HTTP → HTTPS 重定向 server { listen 80; listen [::]:80; @@ -231,50 +231,50 @@ NGINX ### 3.3 启用和测试 ```bash -# Remove default configuration +# 删除默认配置 rm -f /etc/nginx/sites-enabled/default -# Enable OmniRoute +# 启用 OmniRoute ln -sf /etc/nginx/sites-available/omniroute /etc/nginx/sites-enabled/omniroute -# Test and reload +# 测试并重载 nginx -t && systemctl reload nginx ``` --- -## 4.配置 Cloudflare DNS +## 4. 配置 Cloudflare DNS -### 4.1 添加DNS记录 +### 4.1 添加 DNS 记录 在 Cloudflare 仪表板 → DNS 中: -| 类型 | 名称 | 内容 | 代理 | -| ---- | ------ | --------------------------- | ------- | -| 一个 | `llms` | `203.0.113.10`(虚拟机 IP) | ✅ 代理 | +| 类型 | 名称 | 内容 | 代理 | +| ---- | ------ | ---------------------- | --------- | +| A | `llms` | `203.0.113.10`(VM IP)| ✅ Proxied | -### 4.2 配置SSL +### 4.2 配置 SSL -在 **SSL/TLS → 概述** 下: +在 **SSL/TLS → Overview** 下: -- 模式:**完全(严格)** +- 模式:**Full (Strict)** -在**SSL/TLS → 边缘证书**下: +在 **SSL/TLS → Edge Certificates** 下: -- 始终使用 HTTPS: ✅ 打开 -- 最低 TLS 版本:TLS 1.2 -- 自动 HTTPS 重写: ✅ 开启 +- Always Use HTTPS:✅ 开启 +- Minimum TLS Version:TLS 1.2 +- Automatic HTTPS Rewrites:✅ 开启 ### 4.3 测试 ```bash curl -sI https://llms.seudominio.com/health -# Should return HTTP/2 200 +# 应返回 HTTP/2 200 ``` --- -## 5. 操作与维护 +## 5. 运维与维护 ### 升级到新版本 @@ -291,17 +291,17 @@ docker run -d --name omniroute --restart unless-stopped \ ### 查看日志 ```bash -docker logs -f omniroute # Real-time stream -docker logs omniroute --tail 50 # Last 50 lines +docker logs -f omniroute # 实时流 +docker logs omniroute --tail 50 # 最后 50 行 ``` ### 手动数据库备份 ```bash -# Copy data from the volume to the host +# 从卷复制数据到主机 docker cp omniroute:/app/data ./backup-$(date +%F) -# Or compress the entire volume +# 或压缩整个卷 docker run --rm -v omniroute-data:/data -v $(pwd):/backup \ alpine tar czf /backup/omniroute-data-$(date +%F).tar.gz /data ``` @@ -323,7 +323,7 @@ docker start omniroute ```bash cat > /etc/nginx/cloudflare-ips.conf << ‘CF’ -# Cloudflare IPv4 ranges — update periodically +# Cloudflare IPv4 范围 — 定期更新 # https://www.cloudflare.com/ips-v4/ set_real_ip_from 173.245.48.0/20; set_real_ip_from 103.21.244.0/22; @@ -344,31 +344,31 @@ real_ip_header CF-Connecting-IP; CF ``` -将以下内容添加到 `http {}` 块内的 `nginx.conf` 中: +将以下内容添加到 `nginx.conf` 的 `http {}` 块中: ```nginx include /etc/nginx/cloudflare-ips.conf; ``` -### 安装fail2ban +### 安装 fail2ban ```bash apt install -y fail2ban systemctl enable fail2ban systemctl start fail2ban -# Check status +# 检查状态 fail2ban-client status sshd ``` ### 阻止直接访问 Docker 端口 ```bash -# Prevent direct external access to port 20128 +# 防止外部直接访问端口 20128 iptables -I DOCKER-USER -p tcp --dport 20128 -j DROP iptables -I DOCKER-USER -i lo -p tcp --dport 20128 -j ACCEPT -# Persist the rules +# 持久化规则 apt install -y iptables-persistent netfilter-persistent save ``` @@ -377,25 +377,25 @@ netfilter-persistent save ## 7. 部署到 Cloudflare Workers(可选) -对于通过 Cloudflare Workers 进行远程访问(无需直接公开 VM): +通过 Cloudflare Workers 进行远程访问(无需直接暴露 VM): ```bash -# In the local repository +# 在本地仓库中 cd omnirouteCloud npm install npx wrangler login npx wrangler deploy ``` -请参阅 [omnirouteCloud/README.md](../omnirouteCloud/README.md) 处的完整文档。 +完整文档请参见 [omnirouteCloud/README.md](../omnirouteCloud/README.md)。 --- -## 端口总结 +## 端口汇总 -| 港口 | 服务 | 访问 | -| ----- | --------------- | ------------------------ | -| 22 | 22 SSH | 公共(带有fail2ban) | -| 80 | nginx HTTP | 重定向 → HTTPS | -| 443 | 443 nginx HTTPS | 通过 Cloudflare 代理 | -| 20128 | 20128全方位路线 | 仅本地主机(通过 nginx) | +| 端口 | 服务 | 访问 | +| ----- | ----------- | -------------------------- | +| 22 | SSH | 公开(配合 fail2ban) | +| 80 | nginx HTTP | 重定向 → HTTPS | +| 443 | nginx HTTPS | 通过 Cloudflare 代理 | +| 20128 | OmniRoute | 仅本地(通过 nginx) | diff --git a/docs/i18n/zh-CN/docs/FEATURES.md b/docs/i18n/zh-CN/docs/FEATURES.md index 66136604..4e02ea41 100644 --- a/docs/i18n/zh-CN/docs/FEATURES.md +++ b/docs/i18n/zh-CN/docs/FEATURES.md @@ -1,16 +1,16 @@ -# OmniRoute — Dashboard Features Gallery (中文(简体)) +# OmniRoute — Dashboard 功能画廊 -🌐 **Languages:** 🇺🇸 [English](../../../../docs/FEATURES.md) · 🇪🇸 [es](../../es/docs/FEATURES.md) · 🇫🇷 [fr](../../fr/docs/FEATURES.md) · 🇩🇪 [de](../../de/docs/FEATURES.md) · 🇮🇹 [it](../../it/docs/FEATURES.md) · 🇷🇺 [ru](../../ru/docs/FEATURES.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FEATURES.md) · 🇯🇵 [ja](../../ja/docs/FEATURES.md) · 🇰🇷 [ko](../../ko/docs/FEATURES.md) · 🇸🇦 [ar](../../ar/docs/FEATURES.md) · 🇮🇳 [in](../../in/docs/FEATURES.md) · 🇹🇭 [th](../../th/docs/FEATURES.md) · 🇻🇳 [vi](../../vi/docs/FEATURES.md) · 🇮🇩 [id](../../id/docs/FEATURES.md) · 🇲🇾 [ms](../../ms/docs/FEATURES.md) · 🇳🇱 [nl](../../nl/docs/FEATURES.md) · 🇵🇱 [pl](../../pl/docs/FEATURES.md) · 🇸🇪 [sv](../../sv/docs/FEATURES.md) · 🇳🇴 [no](../../no/docs/FEATURES.md) · 🇩🇰 [da](../../da/docs/FEATURES.md) · 🇫🇮 [fi](../../fi/docs/FEATURES.md) · 🇵🇹 [pt](../../pt/docs/FEATURES.md) · 🇷🇴 [ro](../../ro/docs/FEATURES.md) · 🇭🇺 [hu](../../hu/docs/FEATURES.md) · 🇧🇬 [bg](../../bg/docs/FEATURES.md) · 🇸🇰 [sk](../../sk/docs/FEATURES.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FEATURES.md) · 🇮🇱 [he](../../he/docs/FEATURES.md) · 🇵🇭 [phi](../../phi/docs/FEATURES.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FEATURES.md) +🌐 **语言:** 🇺🇸 [English](../../../../docs/FEATURES.md) · 🇪🇸 [es](../../es/docs/FEATURES.md) · 🇫🇷 [fr](../../fr/docs/FEATURES.md) · 🇩🇪 [de](../../de/docs/FEATURES.md) · 🇮🇹 [it](../../it/docs/FEATURES.md) · 🇷🇺 [ru](../../ru/docs/FEATURES.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FEATURES.md) · 🇯🇵 [ja](../../ja/docs/FEATURES.md) · 🇰🇷 [ko](../../ko/docs/FEATURES.md) · 🇸🇦 [ar](../../ar/docs/FEATURES.md) · 🇮🇳 [in](../../in/docs/FEATURES.md) · 🇹🇭 [th](../../th/docs/FEATURES.md) · 🇻🇳 [vi](../../vi/docs/FEATURES.md) · 🇮🇩 [id](../../id/docs/FEATURES.md) · 🇲🇾 [ms](../../ms/docs/FEATURES.md) · 🇳🇱 [nl](../../nl/docs/FEATURES.md) · 🇵🇱 [pl](../../pl/docs/FEATURES.md) · 🇸🇪 [sv](../../sv/docs/FEATURES.md) · 🇳🇴 [no](../../no/docs/FEATURES.md) · 🇩🇰 [da](../../da/docs/FEATURES.md) · 🇫🇮 [fi](../../fi/docs/FEATURES.md) · 🇵🇹 [pt](../../pt/docs/FEATURES.md) · 🇷🇴 [ro](../../ro/docs/FEATURES.md) · 🇭🇺 [hu](../../hu/docs/FEATURES.md) · 🇧🇬 [bg](../../bg/docs/FEATURES.md) · 🇸🇰 [sk](../../sk/docs/FEATURES.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FEATURES.md) · 🇮🇱 [he](../../he/docs/FEATURES.md) · 🇵🇭 [phi](../../phi/docs/FEATURES.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FEATURES.md) --- -Visual guide to every section of the OmniRoute dashboard. +OmniRoute 仪表盘各个页面的可视化导览。 --- -## 🔌 Providers +## 🔌 提供商 -Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (iFlow, Qwen, Kiro). Kiro accounts include credit balance tracking — remaining credits, total allowance, and renewal date visible in Dashboard → Usage. +管理 AI 提供商连接:包括 OAuth 提供商(Claude Code、Codex、Gemini CLI)、API Key 提供商(Groq、DeepSeek、OpenRouter)以及免费提供商(Qoder、Qwen、Kiro)。Kiro 账户还支持额度余额跟踪,可在 Dashboard → Usage 中查看剩余额度、总额度和续期日期。 ![Providers Dashboard](screenshots/01-providers.png) @@ -18,128 +18,128 @@ Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI) ## 🎨 Combos -Create model routing combos with 6 strategies: priority, weighted, round-robin, random, least-used, and cost-optimized. Each combo chains multiple models with automatic fallback and includes quick templates and readiness checks. +创建模型路由 Combo,支持 6 种策略:priority、weighted、round-robin、random、least-used 和 cost-optimized。每个 Combo 都可以串联多个模型并自动回退,同时提供快捷模板和就绪检查。 ![Combos Dashboard](screenshots/02-combos.png) --- -## 📊 Analytics +## 📊 分析 -Comprehensive usage analytics with token consumption, cost estimates, activity heatmaps, weekly distribution charts, and per-provider breakdowns. +完整的用量分析能力,包括 token 消耗、成本估算、活动热力图、每周分布图和按提供商拆分的数据。 ![Analytics Dashboard](screenshots/03-analytics.png) --- -## 🏥 System Health +## 🏥 系统健康 -Real-time monitoring: uptime, memory, version, latency percentiles (p50/p95/p99), cache statistics, and provider circuit breaker states. +实时监控:运行时长、内存、版本、延迟分位数(p50/p95/p99)、缓存统计以及提供商熔断器状态。 ![Health Dashboard](screenshots/04-health.png) --- -## 🔧 Translator Playground +## 🔧 翻译器实验场 -Four modes for debugging API translations: **Playground** (format converter), **Chat Tester** (live requests), **Test Bench** (batch tests), and **Live Monitor** (real-time stream). +提供 4 种 API 翻译调试模式:**Playground**(格式转换器)、**Chat Tester**(实时请求)、**Test Bench**(批量测试)和 **Live Monitor**(实时流监视)。 ![Translator Playground](screenshots/05-translator.png) --- -## 🎮 Model Playground _(v2.0.9+)_ +## 🎮 模型实验场 _(v2.0.9+)_ -Test any model directly from the dashboard. Select provider, model, and endpoint, write prompts with Monaco Editor, stream responses in real-time, abort mid-stream, and view timing metrics. +直接在仪表盘中测试任意模型。可以选择提供商、模型和端点,使用 Monaco Editor 编写提示词,实时流式查看响应、中途终止请求,并查看耗时指标。 --- -## 🎨 Themes _(v2.0.5+)_ +## 🎨 主题 _(v2.0.5+)_ -Customizable color themes for the entire dashboard. Choose from 7 preset colors (Coral, Blue, Red, Green, Violet, Orange, Cyan) or create a custom theme by picking any hex color. Supports light, dark, and system mode. +为整个仪表盘自定义颜色主题。可从 7 种预设颜色(Coral、Blue、Red、Green、Violet、Orange、Cyan)中选择,也可以通过任意 hex 颜色创建自定义主题。支持浅色、深色和跟随系统。 --- -## ⚙️ Settings +## ⚙️ 设置 -Comprehensive settings panel with tabs: +完整的设置面板,包含以下标签页: -- **General** — System storage, backup management (export/import database) -- **Appearance** — Theme selector (dark/light/system), color theme presets and custom colors, health log visibility, sidebar item visibility controls -- **Security** — API endpoint protection, custom provider blocking, IP filtering, session info -- **Routing** — Model aliases, background task degradation -- **Resilience** — Rate limit persistence, circuit breaker tuning, auto-disable banned accounts, provider expiration monitoring -- **Advanced** — Configuration overrides, configuration audit trail, fallback degradation mode +- **General** — 系统存储、备份管理(导出/导入数据库) +- **Appearance** — 主题选择器(dark/light/system)、颜色主题预设和自定义颜色、健康日志可见性、侧边栏项目可见性控制 +- **Security** — API 端点保护、自定义提供商屏蔽、IP 过滤、会话信息 +- **Routing** — 模型别名、后台任务降级 +- **Resilience** — 速率限制持久化、熔断器调优、自动禁用被封账户、提供商过期监控 +- **Advanced** — 配置覆盖、配置审计轨迹、回退降级模式 ![Settings Dashboard](screenshots/06-settings.png) --- -## 🔧 CLI Tools +## 🔧 CLI 工具 -One-click configuration for AI coding tools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor, and Factory Droid. Features automated config apply/reset, connection profiles, and model mapping. +为 AI 编程工具提供一键配置:Claude Code、Codex CLI、Gemini CLI、OpenClaw、Kilo Code、Antigravity、Cline、Continue、Cursor 和 Factory Droid。支持自动应用/重置配置、连接配置文件和模型映射。 ![CLI Tools Dashboard](screenshots/07-cli-tools.png) --- -## 🤖 CLI Agents _(v2.0.11+)_ +## 🤖 CLI 代理 _(v2.0.11+)_ -Dashboard for discovering and managing CLI agents. Shows a grid of 14 built-in agents (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) with: +用于发现和管理 CLI agents 的仪表盘。会以网格展示 14 个内置 agent(Codex、Claude、Goose、Gemini CLI、OpenClaw、Aider、OpenCode、Cline、Qwen Code、ForgeCode、Amazon Q、Open Interpreter、Cursor CLI、Warp),包括: -- **Installation status** — Installed / Not Found with version detection -- **Protocol badges** — stdio, HTTP, etc. -- **Custom agents** — Register any CLI tool via form (name, binary, version command, spawn args) -- **CLI Fingerprint Matching** — Per-provider toggle to match native CLI request signatures, reducing ban risk while preserving proxy IP +- **安装状态** — Installed / Not Found,并带版本检测 +- **协议徽标** — stdio、HTTP 等 +- **自定义 agents** — 可通过表单注册任意 CLI 工具(名称、二进制、版本命令、启动参数) +- **CLI Fingerprint Matching** — 按提供商开关,以匹配原生 CLI 请求特征,在保留代理 IP 的同时降低封禁风险 --- -## 🖼️ Media _(v2.0.3+)_ +## 🖼️ 媒体 _(v2.0.3+)_ -Generate images, videos, and music from the dashboard. Supports OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open, and MusicGen. +从仪表盘生成图像、视频和音乐。支持 OpenAI、xAI、Together、Hyperbolic、SD WebUI、ComfyUI、AnimateDiff、Stable Audio Open 和 MusicGen。 --- -## 📝 Request Logs +## 📝 请求日志 -Real-time request logging with filtering by provider, model, account, and API key. Shows status codes, token usage, latency, and response details. +实时请求日志,支持按提供商、模型、账户和 API Key 过滤。可查看状态码、token 用量、延迟和响应详情。 ![Usage Logs](screenshots/08-usage.png) --- -## 🌐 API Endpoint +## 🌐 API 端点 -Your unified API endpoint with capability breakdown: Chat Completions, Responses API, Embeddings, Image Generation, Reranking, Audio Transcription, Text-to-Speech, Moderations, and registered API keys. Cloudflare Quick Tunnel integration and cloud proxy support for remote access. +统一 API 端点页面,按能力拆分展示:Chat Completions、Responses API、Embeddings、Image Generation、Reranking、Audio Transcription、Text-to-Speech、Moderations,以及已注册 API Keys。还集成了 Cloudflare Quick Tunnel 和云代理支持,方便远程访问。 ![Endpoint Dashboard](screenshots/09-endpoint.png) --- -## 🔑 API Key Management +## 🔑 API 密钥管理 -Create, scope, and revoke API keys. Each key can be restricted to specific models/providers with full access or read-only permissions. Visual key management with usage tracking. +创建、限定范围并撤销 API Keys。每个 key 都可以限制到特定模型或提供商,并支持 full access 或 read-only 权限。提供可视化密钥管理和用量跟踪。 --- -## 📋 Audit Log +## 📋 审计日志 -Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history. +用于跟踪管理操作,支持按操作类型、执行者、目标、IP 地址和时间戳过滤,可查看完整的安全事件历史。 --- -## 🖥️ Desktop Application +## 🖥️ 桌面应用 -Native Electron desktop app for Windows, macOS, and Linux. Run OmniRoute as a standalone application with system tray integration, offline support, auto-update, and one-click install. +适用于 Windows、macOS 和 Linux 的原生 Electron 桌面应用。可以将 OmniRoute 作为独立应用运行,支持系统托盘、离线模式、自动更新和一键安装。 -Key features: +主要特性: -- Server readiness polling (no blank screen on cold start) -- System tray with port management +- 服务器就绪轮询(冷启动时不再白屏) +- 带端口管理的系统托盘 - Content Security Policy -- Single-instance lock -- Auto-update on restart -- Platform-conditional UI (macOS traffic lights, Windows/Linux default titlebar) -- Hardened Electron build packaging — symlinked `node_modules` in the standalone bundle is detected and rejected before packaging, preventing runtime dependency on the build machine (v2.5.5+) +- 单实例锁 +- 重启时自动更新 +- 按平台适配的界面(macOS traffic lights、Windows/Linux 默认标题栏) +- 加固的 Electron 打包流程:会在打包前检测并拒绝 standalone bundle 中符号链接的 `node_modules`,防止运行时依赖构建机环境(v2.5.5+) -📖 See [`electron/README.md`](../electron/README.md) for full documentation. +📖 完整文档见 [`electron/README.md`](../electron/README.md)。