OmniRoute 架构深度解析:统一 AI 网关的分层设计、请求生命周期与容错体系
导读
OmniRoute 是一个基于 Next.js 构建的本地 AI 路由网关与仪表盘,为 Claude Code、Codex、Cursor、OpenCode、Cline、Copilot 以及任意 OpenAI 兼容客户端提供统一的 /v1/* 端点。它把 300+ 上游提供商的差异化协议收拢成一套 OpenAI 兼容 API,并在内部完成格式翻译、组合回退、账号轮换、令牌刷新、用量统计与安全管控。本文基于仓库官方架构文档(docs/architecture/ARCHITECTURE.md,英文原版)与最新保加利亚语译文(docs/i18n/bg/docs/architecture/ARCHITECTURE.md)展开,结合 src/、open-sse/ 下的真实源码与测试,逐层拆解网关的运行时模型:从 Next.js 路由层、SSE 翻译核心、SQLite 持久化,到请求生命周期、Combo 回退、OAuth 令牌管理、翻译管线、Provider 执行器与安全边界。读完本文,你将掌握 OmniRoute 的模块地图、关键调用链、配置参数与排障入口,能直接定位到对应源码模块继续深入。
语言说明:指定关联文档为保加利亚语译文,本文以英文原版文档为内容权威基准(译文与原文结构、章节完全一致),所有代码路径与配置以仓库当前版本为准。
open-sse/目录同时以@omniroute/open-ssenpm workspace 包形式发布,源码导入路径为@omniroute/open-sse/...,本文为保持一致仍沿用目录名open-sse/。
一、架构概览:单端点入口 + 分层运行时
1.1 核心定位
OmniRoute 的核心价值可以浓缩为一句话:一个本地的、OpenAI 兼容的 AI 网关与仪表盘。它在客户端与众多上游 AI 提供商之间架起一层本地进程,屏蔽掉每家提供商的协议差异、认证方式和计费口径。
从官方文档的 Executive Summary 可以看到,网关的能力清单覆盖了如下主链路:
- 面向 CLI/工具的 OpenAI 兼容 API 面(数百个提供商目录条目 + 数十个执行器实现模块);
- 跨提供商格式的请求/响应翻译;
- 模型组合回退(Combo,多模型序列);
- 结构化的 Combo 步骤(
provider + model + connection),运行时按compositeTiers排序; - 账号级回退(同一提供商下多账号切换);
- 主聊天路径中的配额预检与配额感知的 P2C 账号选择;
- OAuth + API Key 两种提供商连接管理;
/v1/embeddings、/v1/images/generations、/v1/audio/transcriptions、/v1/audio/speech、/v1/videos/generations、/v1/music/generations、/v1/search、/v1/moderations、/v1/rerank等扩展端点;- 推理模型的
<think>...</think>标签解析、严格 OpenAI SDK 兼容的响应清洗、角色归一化、结构化输出转换(json_schema→ GeminiresponseSchema); - 本地持久化(providers、keys、aliases、combos、settings、pricing 等)、用量/成本追踪、可选云同步、IP 白名单/黑名单、思考预算管理、全局系统提示注入;
- 会话跟踪与指纹、按账号增强的限流(带提供商级画像)、熔断器、防惊群(mutex)、基于签名的请求去重缓存;
- 域层(成本规则、回退策略、锁定策略)、Context Relay 会话交接、域状态 SQLite 写穿缓存、策略引擎(lockout → budget → fallback)、p50/p95/p99 延迟遥测、
X-Request-Id关联追踪、合规审计日志、Eval 框架、健康面板、MCP Server(stdio/SSE/Streamable HTTP 三种传输)、A2A Server(JSON-RPC 2.0 + SSE)、记忆系统、技能系统、MITM 代理、提示注入防护中间件、WebSocket 桥(/v1/ws)、GLM Thinking(glmt)一等公民预置、混合令牌计数、模型别名自动播种、带 SSRF 防护的安全出站请求、冷却感知重试、启动时 Zod 运行时环境校验等。
1.2 主要运行时模型
官方文档明确了双核运行模型:
- Next.js App Router 路由层:
src/app/api/*下的路由同时承载仪表盘管理 API 与兼容 API; - 共享 SSE/路由核心:
src/sse/*+open-sse/*负责提供商执行、翻译、流式、回退与用量统计。
其中 open-sse/ 目录被发布为 @omniroute/open-sse npm workspace 包,源码通过 @omniroute/open-sse/... 导入(由 Next.js transpilePackages 解析)。这一点在文档 "Known Architectural Notes" 第 5 条中有明确说明,是理解 import 路径与目录名差异的关键。
1.3 范围与边界(In Scope / Out of Scope)
范围内:
- 本地网关运行时
- 仪表盘管理 API
- 提供商认证与令牌刷新
- 请求翻译与 SSE 流式
- 本地状态 + 用量持久化
- 可选云同步编排
范围外:
NEXT_PUBLIC_CLOUD_URL背后的云服务实现- 本地进程之外的提供商 SLA/控制面
- 外部 CLI 二进制本身(Claude CLI、Codex CLI 等)
1.4 高层系统上下文
官方文档用一张 Mermaid 流程图描述了系统全貌:左侧是开发者客户端(Claude Code、Codex CLI、Cline/Continue/Roo 等、自定义 OpenAI 兼容客户端、浏览器仪表盘),中间是 OmniRoute 本地进程(/v1/* 兼容 API、/api/* 仪表盘与管理 API、open-sse + src/sse 的 SSE 翻译核心、storage.sqlite 主库与用量库),右侧是三类上游(OAuth 提供商、API Key 提供商、兼容节点),底部是可选云同步端点。
二、仪表盘面:入口页面与功能映射
src/app/(dashboard)/dashboard/ 下的主页面与文档中列出的功能一一对应:
| 路由 | 功能 |
|---|---|
/dashboard |
快速开始 + 提供商概览 |
/dashboard/endpoint |
端点代理 + MCP + A2A + API 端点标签页 |
/dashboard/providers |
提供商连接与凭据管理 |
/dashboard/combos |
Combo 策略、模板、基于步骤的构建器、模型路由规则、手动持久化排序 |
/dashboard/costs |
成本聚合与价格可见性 |
/dashboard/analytics |
用量分析、评估、Combo 目标健康度 |
/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 Key 生命周期与模型权限 |
文档还指出设置页分为 7 个标签:General、Appearance、AI、Security、Routing、Resilience、Advanced。其中 Resilience 页只配置请求队列、连接冷却、提供商熔断与等待冷却行为,实时熔断运行状态则显示在 Health 页。
三、API 与路由层:Next.js App Routes 的双面角色
3.1 目录布局与重写规则
src/app/api/v1/*与src/app/api/v1beta/*:兼容 API(面向客户端);src/app/api/*:管理/配置 API(面向仪表盘);next.config.mjs中的 Next 重写将/v1/*映射到/api/v1/*。
3.2 核心兼容路由
官方文档列出的关键路由包括:
src/app/api/v1/chat/completions/route.tssrc/app/api/v1/messages/route.tssrc/app/api/v1/responses/route.tssrc/app/api/v1/models/route.ts—— 包含custom: true的自定义模型src/app/api/v1/embeddings/route.ts—— 嵌入生成(多个提供商)src/app/api/v1/images/generations/route.ts—— 图像生成(含 Antigravity/Nebius)src/app/api/v1/messages/count_tokens/route.tssrc/app/api/v1/providers/[provider]/chat/completions/route.ts—— 专用逐提供商聊天src/app/api/v1/providers/[provider]/embeddings/route.ts、.../images/generations/route.tssrc/app/api/v1beta/models/route.ts与src/app/api/v1beta/models/[...path]/route.tssrc/app/api/v1/ws/route.ts—— OpenAI 兼容 WebSocket 客户端的 Upgrade 处理器
3.3 管理域路由速查
管理 API 覆盖面极广,按域划分可整理为:
- 认证/设置:
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/* - Key/别名/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) - 思考预算:
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/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,带分页与结构化元数据) - Eval:
src/app/api/evals(GET/POST)、src/app/api/evals/[suiteId](GET) - 策略:
src/app/api/policies(GET/POST) - 同步令牌:
src/app/api/sync/tokens(GET/POST)、src/app/api/sync/tokens/[id](GET/DELETE) - 配置包:
src/app/api/sync/bundle(GET,ETag 版本化的设置/提供商/Combo/Key 快照)
四、SSE + 翻译核心:网关的心脏
这是整个架构中最重要的部分,官方文档对它的模块划分非常细致。核心职责可归纳为:识别请求格式 → 翻译为目标格式 → 派发到执行器 → 处理流式响应 → 归一化用量 → 返回给客户端。
4.1 主流程模块
- 入口:
src/sse/handlers/chat.ts—— 请求解析、Combo 处理、账号选择循环。源码显示它调用了resolveRoutingModel、handleComboChat、配额预检(getProviderCredentialsWithQuotaPreflight)、冷却感知重试(cooldownAwareRetry)、压缩设置解析(resolveCompressionSettings)、上下文交接(injectHandoffIntoBody)等大量子模块; - 核心编排:
open-sse/handlers/chatCore.ts—— 翻译、执行器派发、重试/刷新处理、流式组装。该文件体量很大(数千行),内部进一步拆分为chatCore/子目录,如streamingPipeline.ts、sanitization.ts、outputTokenBudget.ts、idempotency.ts、semanticCache.ts、modelLifecyclePolicy.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; - 嵌入处理器与注册表:
open-sse/handlers/embeddings.ts、open-sse/config/embeddingRegistry.ts; - 图像生成处理器与注册表:
open-sse/handlers/imageGeneration.ts、open-sse/config/imageRegistry.ts; - 响应清洗:
open-sse/handlers/responseSanitizer.ts; - 角色归一化:
open-sse/services/roleNormalizer.ts。
4.2 服务层(业务逻辑)
- 账号选择/打分:
open-sse/services/accountSelector.ts - 上下文生命周期管理:
open-sse/services/contextManager.ts - IP 过滤执行:
open-sse/services/ipFilter.ts - 会话跟踪:
open-sse/services/sessionManager.ts - 请求去重:
open-sse/services/signatureCache.ts - 系统提示注入:
open-sse/services/systemPrompt.ts - 思考预算管理:
open-sse/services/thinkingBudget.ts - 通配模型路由:
open-sse/services/wildcardRouter.ts - 限流管理:
open-sse/services/rateLimitManager.ts - 熔断器:
open-sse/services/circuitBreaker.ts - 上下文交接(Context Relay):
open-sse/services/contextHandoff.ts—— 为 context-relay 策略生成并注入交接摘要 - Codex 配额抓取:
open-sse/services/codexQuotaFetcher.ts - 冷却感知重试:
src/sse/services/cooldownAwareRetry.ts—— 按模型冷却重试,支持可配置的requestRetry/maxRetryIntervalSec - 安全出站请求:
src/shared/network/safeOutboundFetch.ts—— 带 SSRF 防护、私网 URL 拦截、重试与超时 - 出站 URL 防护:
src/shared/network/outboundUrlGuard.ts—— 校验提供商 URL 是否命中私有/本地 CIDR 范围 - 提供商请求默认值:
open-sse/services/providerRequestDefaults.ts—— 提供商级maxTokens、temperature、thinkingBudgetTokens默认值 - GLM 常量:
open-sse/config/glmProvider.ts;Antigravity 上游:open-sse/config/antigravityUpstream.ts;Codex 客户端常量:open-sse/config/codexClient.ts - 模型别名播种:
src/lib/modelAliasSeed.ts—— 启动时播种 30+ 个跨代理方言别名
4.3 域层模块
域层把策略决策集中化,避免路由处理器自行拼装逻辑:
- 成本规则/预算:
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—— 集中的 lockout → budget → fallback 求值 - 错误码目录:
src/lib/domain/errorCodes.ts - 请求 ID:
src/lib/domain/requestId.ts;抓取超时:src/lib/domain/fetchTimeout.ts - 请求遥测:
src/lib/domain/requestTelemetry.ts - 合规/审计:
src/lib/domain/compliance/index.ts - Eval 运行器:
src/lib/domain/evalRunner.ts - 域状态持久化:
src/lib/db/domainState.ts—— 回退链、预算、成本历史、锁定状态、熔断状态的 SQLite CRUD
4.4 OAuth 提供商模块
文档点名的 OAuth 实现位于 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 为薄封装再导出)。从当前仓库文件系统看,该目录已扩展到 20+ 个模块,覆盖更多提供商——数量以仓库源码为准。
五、请求生命周期:一次 /v1/chat/completions 的完整旅程
官方文档用一张序列图精确刻画了请求全链路,这是理解网关最重要的图。逐步还原如下:
- 客户端发起:
POST /v1/chat/completions到达兼容路由; - 入口处理:路由调用
src/sse/handlers/chat.ts的handleChat(request); - 模型解析:解析/解析模型或 Combo;若为 Combo 模型,则进入
handleComboChat遍历组合中的每个模型; - 凭据选择:通过
getProviderCredentials(provider)取得当前活跃账号与令牌/API Key; - 核心编排:
handleChatCore(body, modelInfo, credentials)开始执行——检测源格式、翻译请求到目标格式、调用执行器execute(provider, transformedBody)发起上游调用; - 上游响应:执行器收到 SSE/JSON 响应,连同元数据返回核心;
- 令牌刷新分支:遇到 401/403 时,核心调用执行器的
refreshCredentials()获取新令牌后重试请求; - 流式翻译:核心把上游流翻译/归一化为客户端格式,以 SSE 块或 JSON 响应返回;
- 用量落库:流处理器提取用量并持久化历史/日志。
从源码看,src/sse/handlers/chat.ts 的实现远比序列图复杂:它集成配额预检(getProviderCredentialsWithQuotaPreflight)、会话亲和性(sessionAccountAffinity)、压缩设置、上下文交接、模型锁定(lockModel/recordModelLockoutFailure)、每日配额耗尽判断(isDailyQuotaExhausted)等。这印证了文档中"Chat handler 是请求解析 + Combo 处理 + 账号选择循环"的定位。
六、Combo 与账号回退:多级降级的决策树
6.1 回退流程
官方文档的决策树逻辑为:
- 入站模型字符串是否为 Combo 名?是则加载 Combo 模型序列,否则走单模型路径;
- 尝试模型 N → 解析提供商/模型 → 选择账号凭据;
- 凭据不可用则返回 provider unavailable;
- 凭据可用则执行请求;
- 成功则返回;失败则判断是否"可回退错误";
- 不可回退 → 返回错误;可回退 → 标记账号不可用并进入冷却;
- 该提供商还有账号?有则回到账号选择;没有则看 Combo 是否还有下一个模型;
- 有下一个模型则尝试下一个;否则返回 all unavailable。
回退决策由 open-sse/services/accountFallback.ts 依据状态码与错误消息启发式驱动。Combo 路由多一道防线:提供商级 400(如上游内容拦截、角色校验失败)被视作模型本地失败,从而允许后续 Combo 目标继续执行。
从源码看,accountFallback.ts 对错误分类做了大量精细处理:429 分类型冷却(rate_limit 60 秒、quota_exhausted 1 小时)防止级联熔断;对永久退役模型(404/410 "end of life")直接判定不可重试,避免每次冷却窗口后反复重试死模型造成上游滥用流量;支持冷却上限(cooldownCap)、锁定驱逐(lockoutEviction)、API Key 禁止回退解析(nonRetryableUpstream)等。
6.2 韧性来源
文档 "Failure Modes and Resilience" 章节系统总结了失败模式:
- 账号/提供商可用性:可重试上游失败触发连接冷却 → 账号回退 → Combo 模型回退;
- 令牌过期:可刷新提供商先预检+刷新重试;核心路径中 401/403 刷新后重试;
- 流安全:断连感知的流控制器、带流结束 flush 与
[DONE]处理的翻译流、提供商缺失用量元数据时的用量估算回退; - 云同步降级:同步错误被上报但本地运行时继续;调度器具备可重试逻辑,但周期性执行默认单次尝试;
- 数据完整性:启动时 SQLite 模式迁移与自动升级钩子、旧 JSON → SQLite 迁移兼容路径;
- SSRF/出站 URL 防护:
outboundUrlGuard.ts在到达执行器前拦截所有私有/回环/link-local 目标 URL;模型发现与校验路由使用safeOutboundFetch.ts每次出站前应用防护;防护错误以URL_GUARD_BLOCKED(HTTP 422)呈现,并经providerAudit.ts记入合规审计轨迹。
源码 outboundUrlGuard.ts 进一步印证了防护的细粒度:支持 none / public-only / block-metadata 三种模式,其中 block-metadata 允许私有/LAN 主机但仍拒绝云元数据端点(防止 SSRF 转 IAM 凭据的 pivot);错误码为 OUTBOUND_URL_GUARD_BLOCKED / OUTBOUND_URL_INVALID,并处理 IPv4-mapped IPv6 地址等绕过尝试。
七、OAuth 接入与令牌刷新生命周期
7.1 流程还原
文档的 OAuth 序列图描述了两段式流程:
- 授权/设备码:仪表盘 UI 调用
/api/oauth/[provider]/[action],OAuth 路由创建授权/设备流,返回认证 URL 或设备码载荷; - 交换/轮询:UI POST 交换或轮询,OAuth 路由与提供商认证服务器完成令牌交换/轮询,将 access/refresh 令牌写入
createProviderConnection(oauth data),返回成功与连接 ID; - 连接测试:UI 调
POST /api/providers/[id]/test,测试路由经执行器校验凭据(可选刷新),更新状态/令牌/错误后返回校验结果。
活跃流量中的刷新在 open-sse/handlers/chatCore.ts 内通过执行器 refreshCredentials() 完成——这正是上一章请求生命周期中 401/403 分支的实现位置。
7.2 执行器的刷新钩子
在 open-sse/executors/base.ts 中,BaseExecutor 定义了 refreshCredentials(credentials, log) 钩子,默认实现在子类中按提供商覆盖(如 GitHub 的 Copilot 令牌刷新)。execute() 编排方法会在必要时先主动刷新再执行,体现了"预检 + 失败重试"的双保险策略。
八、云同步生命周期:启用 / 同步 / 禁用
文档的云同步序列图清晰划分三个阶段:
- enable:UI 调
POST /api/sync/cloud(action=enable)→ 本地设置cloudEnabled=true→ 确保 API Key 存在 → 向云端点POST /sync/{machineId}(携带 providers/aliases/combos/keys)→GET /{machineId}/v1/verify验证 → 返回启用+验证状态; - sync:
POST action=sync→ 同步远端数据 → 更新本地较新的令牌/状态 → 返回 synced; - disable:
POST action=disable→ 设置cloudEnabled=false→DELETE /sync/{machineId}→ 必要时把ANTHROPIC_BASE_URL切回本地。
周期性同步由 CloudSyncScheduler 在云启用时触发。相关模块:调度器初始化 src/lib/initCloudSync.ts、src/shared/services/initializeCloudSync.ts、src/shared/services/modelSyncScheduler.ts;周期任务 src/shared/services/cloudSyncScheduler.ts;控制路由 src/app/api/sync/cloud/route.ts。
九、数据模型与存储映射
9.1 ER 关系
官方文档的 ER 图揭示了三组核心关系:
SETTINGS ||--o{ PROVIDER_CONNECTION : controlsPROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_providerPROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage
9.2 关键实体字段
SETTINGS:cloudEnabled(boolean)、stickyRoundRobinLimit(number)、requireLogin(boolean)、password_hash(string)、fallbackStrategy(string)、rateLimitDefaults(json)、providerProfiles(json)。
PROVIDER_CONNECTION:id、provider、authType、name、priority、isActive、apiKey、accessToken、refreshToken、expiresAt、testStatus、lastError、rateLimitedUntil、providerSpecificData(json)。
PROVIDER_NODE:id、type、name、prefix、apiType、baseUrl。
MODEL_ALIAS:alias、targetModel。COMBO:id、name、models[]。API_KEY:id、name、key、machineId。USAGE_ENTRY:provider、model、prompt_tokens、completion_tokens、connectionId、timestamp。CUSTOM_MODEL:id、name、providerId。PROXY_CONFIG:global、providers(json)。IP_FILTER:mode、allowlist[]、blocklist[]。THINKING_BUDGET:mode、customBudget、effortLevel。SYSTEM_PROMPT:enabled、prompt、position。
9.3 物理存储文件
- 主运行时库:
${DATA_DIR}/storage.sqlite - 请求日志行:
${DATA_DIR}/log.txt(兼容/调试产物) - 结构化调用载荷归档:
${DATA_DIR}/call_logs/ - 可选的翻译器/请求调试会话:
<repo>/logs/...
9.4 三层持久化
主状态库(SQLite):
- 核心基础设施:
src/lib/db/core.ts(better-sqlite3、迁移、WAL) - 再导出门面:
src/lib/localDb.ts(薄兼容层) - 文件位置:
${DATA_DIR}/storage.sqlite,未设DATA_DIR且设置了$XDG_CONFIG_HOME时为$XDG_CONFIG_HOME/omniroute/storage.sqlite,否则~/.omniroute/storage.sqlite - 实体(表 + KV 命名空间):providerConnections、providerNodes、modelAliases、combos、apiKeys、settings、pricing、customModels、proxyConfig、ipFilter、thinkingBudget、systemPrompt
用量持久化:
- 门面:
src/lib/usageDb.ts(模块拆解于src/lib/usage/*) - SQLite 表:
usage_history、call_logs、proxy_logs - 可选的兼容/调试文件产物:
${DATA_DIR}/log.txt、${DATA_DIR}/call_logs/、<repo>/logs/... - 旧 JSON 文件在启动迁移时并入 SQLite
域状态库(SQLite):
src/lib/db/domainState.ts- 表:
domain_fallback_chains、domain_budgets、domain_cost_history、domain_lockout_state、domain_circuit_breakers - 写穿缓存模式:运行时以内存 Map 为准,变更同步写 SQLite,冷启动时从数据库恢复状态
十、执行器体系:策略模式下的提供商适配
10.1 BaseExecutor 的通用能力
所有执行器都继承 open-sse/executors/base.ts 中的 BaseExecutor,它提供:URL 构建、请求头构造、指数退避重试、凭据刷新钩子与 execute() 编排方法。源码显示 BaseExecutor 还包含流/非流处理、429 指数退避(通用 429 起始延迟 2 秒)、WAF 内容拦截重试配置(起始延迟高于通用 429)等细节。
10.2 执行器注册表
open-sse/executors/registry.ts 实现了运行时执行器注册表:内建执行器在模块加载时通过 registerExecutor(alias, executor) 注册,getExecutor() 从 Map 解析而非硬编码对象字面量;别名唯一,重复注册会抛错。当前仓库还引入了懒注册机制(registerLazyExecutor),先声明别名与注册顺序(保持 golden 快照形状),类导入与构造推迟到首次使用,避免冷启动加载全部执行器。执行器映射的变更由 tests/unit/executor-map-golden.test.ts(快照 tests/snapshots/executors/)以 golden diff 形式守护。
10.3 执行器覆盖矩阵
官方文档的表格(结合当前仓库 open-sse/executors 目录扩展)列出了各执行器的特殊处理:
| 执行器 | 提供商 | 特殊处理 |
|---|---|---|
DefaultExecutor |
OpenAI、Claude、Gemini、Qwen、OpenRouter、GLM、Kimi、MiniMax、DeepSeek、Groq、xAI、Mistral、Perplexity、Together、Fireworks、Cerebras、Cohere、NVIDIA 等 | 按提供商动态 URL/Header 配置 |
AntigravityExecutor |
Google Antigravity | 自定义项目/会话 ID、Retry-After 解析、429 混淆 |
CliProxyApiExecutor |
CLIProxyAPI 兼容提供商 | 自定义认证与协议处理 |
CloudflareAiExecutor |
Cloudflare Workers AI | Account ID 注入、Neurons 用量追踪 |
CodexExecutor |
OpenAI Codex | 注入系统指令、强制推理努力 |
CursorExecutor |
Cursor IDE | ConnectRPC 协议、Protobuf 编码、基于校验和的请求签名 |
GithubExecutor |
GitHub Copilot | Copilot 令牌刷新、模拟 VSCode 头 |
KiroExecutor |
AWS CodeWhisperer/Kiro | AWS EventStream 二进制格式 → SSE 转换 |
OpenCodeExecutor |
OpenCode | AI SDK 兼容提供商设置 |
PollinationsExecutor |
Pollinations AI | 无需 API Key、限速请求 |
QoderExecutor |
Qoder AI | PAT 与 OAuth 支持、多模型免费层 |
VertexExecutor |
Google Vertex AI | 服务账号认证、基于区域的路由 |
当前仓库 open-sse/executors/ 目录已包含上百个执行器文件(含 github.ts、gitlab.ts、glm.ts、grok-cli.ts、grok-web/、huggingchat/、kimi-web.ts、maxai/、perplexity-web/、poe-web.ts、zed-hosted.ts、zenmux-free.ts 等),文档表格仅是代表性抽样——其余提供商(含自定义兼容节点)使用 DefaultExecutor。
十一、提供商兼容性矩阵
官方文档强调:该矩阵只是 351+ 注册提供商的代表性样本,权威且持续更新的清单见自动生成的 docs/reference/PROVIDER_REFERENCE.md,真源位于 src/shared/constants/providers.ts(加载时经 Zod 校验)。
核心兼容属性包括:格式(claude/gemini/openai/openai-responses/kiro/cursor)、认证(API Key/OAuth/Service Account/会话 Cookie/免 Key)、流式与非流式支持、令牌刷新能力、用量 API 能力。几个关键观察:
- Claude/Gemini/Antigravity:支持 API Key 或 OAuth,均可刷新令牌;
- OpenAI:仅 API Key,无令牌刷新、无用量 API;
- Codex:OAuth、强制流式、支持限流查询;
- GitHub Copilot:OAuth + Copilot Token、配额快照;
- Cursor:自定义校验和认证、无刷新;
- Kiro:AWS SSO OIDC、EventStream 流式、用量限制查询;
- 大量 API Key 提供商(OpenRouter/DeepSeek/Groq/xAI/Mistral/Perplexity/Together/Fireworks/Cerebras/Cohere/NVIDIA/Cloudflare/Pollinations/Scaleway/LongCat/Ollama Cloud/HuggingFace/Nebius/SiliconFlow/Hyperbolic 等):统一
openai格式 + API Key,无刷新; - Vertex AI:Service Account 认证、gemini 格式、支持刷新;
- Web 会话类(Grok-Web、Perplexity-Web、BlackBox-Web、Muse-Spark-Web):会话 Cookie 认证;
- 云代理类(Codex Cloud、Jules、Devin CLI/Desktop):任务 API 或限流 API。
十二、格式翻译覆盖:OpenAI 中枢模型
12.1 源格式与目标格式
检测到的源格式:openai、openai-responses、claude、gemini。目标格式:OpenAI chat/Responses、Claude、Gemini/Antigravity 信封、Kiro、Cursor。
12.2 OpenAI 中枢(Hub)模式
所有转换都以 OpenAI 为中间格式:
Source Format → OpenAI (hub) → Target Format
翻译根据源载荷形状与提供商目标格式动态选择。从源码 open-sse/translator/index.ts 可以看到该模式的落地:当源格式不是 OpenAI 时先做 source → openai,再 openai → target;同格式直通(如 source === target === OPENAI_RESPONSES)会跳过中枢翻译块。
12.3 翻译注册表与转换器
- 注册表与编排:
open-sse/translator/index.ts - 请求转换器:
open-sse/translator/request/*(当前仓库含 9 个模块:antigravity-to-openai、claude-to-gemini、claude-to-openai、gemini-to-openai、openai-responses、openai-to-claude、openai-to-cursor、openai-to-gemini、openai-to-kiro) - 响应转换器:
open-sse/translator/response/*(11 个模块:claude-to-openai、cursor-to-openai、gemini-to-claude、gemini-to-openai、kiro-to-openai、openai-responses、openai-to-antigravity、openai-to-claude、openai-to-gemini、openai-to-gemini-sse、responsesToolItem) - 辅助模块:
open-sse/translator/helpers/*(12 个,含claudeHelper、geminiHelper、geminiToolsSanitizer、jsonUtil、markdownBoundary、maxTokensHelper、openaiHelper、responsesApiHelper、schemaCoercion、strictSystemHoist、toolCallHelper、toolCallShim) - 格式常量:
open-sse/translator/formats.ts;引导与注册:open-sse/translator/bootstrap.ts、open-sse/translator/registry.ts;图像格式辅助:open-sse/translator/image/
12.4 翻译管线中的附加处理层
- 响应清洗:剥离 OpenAI 格式响应(流式与非流式)中的非标准字段,确保严格 SDK 兼容;
- 角色归一化:非 OpenAI 目标把
developer→system;对拒绝 system 角色的模型(GLM、ERNIE)把system→user; - Think 标签提取:从内容解析
<think>...</think>块到reasoning_content字段。源码 open-sse/utils/thinkTagParser.ts 定义了extractThinkTags/hasThinkTags,服务于 DeepSeek、Qwen、Qoder 等以<think>标签内嵌链式思考的提供商,并处理<think>的各种合法前缀; - 结构化输出:把 OpenAI
response_format.json_schema转换为 Gemini 的responseMimeType+responseSchema。
十三、支持的 API 端点
官方文档的端点表可直接作为 API 速查:
| 端点 | 格式 | 处理器 |
|---|---|---|
POST /v1/chat/completions |
OpenAI Chat | 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 |
模型列表 | API 路由 |
POST /v1/images/generations |
OpenAI Images | open-sse/handlers/imageGeneration.ts |
GET /v1/images/generations |
模型列表 | API 路由 |
POST /v1/providers/{provider}/chat/completions |
OpenAI Chat | 专用逐提供商(带模型校验) |
POST /v1/providers/{provider}/embeddings |
OpenAI Embeddings | 专用逐提供商(带模型校验) |
POST /v1/providers/{provider}/images/generations |
OpenAI Images | 专用逐提供商(带模型校验) |
POST /v1/messages/count_tokens |
Claude Token Count | API 路由 |
GET /v1/models |
OpenAI Models 列表 | API 路由(chat + embedding + image + 自定义模型) |
GET /api/models/catalog |
Catalog | 按提供商 + 类型分组的全部模型 |
POST /v1beta/models/*:streamGenerateContent |
Gemini 原生 | API 路由 |
GET/PUT/DELETE /api/settings/proxy |
Proxy 配置 | 网络代理配置 |
POST /api/settings/proxy/test |
代理连通性 | 代理健康/连通性测试 |
GET/POST/DELETE /api/provider-models |
Provider Models | 支撑自定义与管理可用模型的提供商模型元数据 |
十四、Bypass 处理器与请求日志
14.1 Bypass 处理器
open-sse/utils/bypassHandler.ts 会拦截 Claude CLI 的"一次性"请求——预热 ping、标题提取、令牌计数——直接返回假响应而不消耗上游令牌。触发条件仅为 User-Agent 包含 claude-cli。这是降低免费/OAuth 账户无效消耗的精妙设计。
14.2 请求日志与产物
旧的基于文件的请求记录器(open-sse/utils/requestLogger.ts)仅保留作遗留兼容,当前运行时契约使用:
APP_LOG_TO_FILE=true时应用与审计日志写入<repo>/logs/- SQLite 支撑的
call_logs调用日志记录 - 启用调用日志管线时
${DATA_DIR}/call_logs/YYYY-MM-DD/...归档
14.3 可观测性与运维信号
运行时可见性来源:src/sse/utils/logger.ts 的控制台日志;SQLite 中的逐请求用量聚合(usage_history、call_logs、proxy_logs);settings.detailed_logs_enabled=true 时 request_detail_logs 表内的四阶段详细载荷捕获;可选的 log.txt 文本请求状态日志;APP_LOG_TO_FILE=true 时的应用日志文件;启用调用日志管线时的请求归档;仪表盘用量端点 /api/usage/*。
四阶段载荷捕获(每次路由调用最多四个 JSON 载荷阶段):
- 从客户端收到的原始请求;
- 实际上游发送的翻译后请求;
- 提供商响应重建为 JSON(流式响应压缩为最终摘要 + 流元数据);
- 返回给客户端的最终响应(流式响应同样以压缩摘要形式存储)。
十五、安全敏感边界与环境矩阵
15.1 安全边界
JWT_SECRET:保护仪表盘会话 Cookie 的验证/签名;INITIAL_PASSWORD:首次运行应显式配置的初始密码引导;API_KEY_SECRET:保护生成的本地 API Key 格式(HMAC);- 提供商密钥(API Key/令牌)持久化于本地数据库,应在文件系统层面保护;
- 云同步端点依赖 API Key 认证 + machine id 语义。
15.2 环境变量矩阵
- 应用/认证:
JWT_SECRET、INITIAL_PASSWORD - 存储:
DATA_DIR;Linux/macOS 未设DATA_DIR时的可选基础覆盖:XDG_CONFIG_HOME - 兼容节点行为:
ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE - 安全哈希:
API_KEY_SECRET、MACHINE_ID_SALT - 日志:
APP_LOG_TO_FILE、APP_LOG_RETENTION_DAYS、CALL_LOG_RETENTION_DAYS - 同步/云 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
启动时 src/lib/env/runtimeEnv.ts 以 Zod 模式校验全部环境变量,问题以启动错误/警告呈现。
十六、部署拓扑与运维验证
16.1 拓扑
官方部署图展示:开发者主机上的 CLI 工具与浏览器 → OmniRoute 运行时(Next.js Server,默认 PORT=20128;SSE 核心 + 执行器;storage.sqlite 主库;用量表 + 日志归档)→ 外部 AI 提供商与云同步服务。CLI 目标 base URL 应为 http://<host>:20128/v1。
16.2 已知架构要点
文档 "Known Architectural Notes" 中几个值得重点记忆的决策:
usageDb与localDb共享同一基础目录策略(DATA_DIR→XDG_CONFIG_HOME/omniroute→~/.omniroute)并带遗留文件迁移;/api/v1/route.ts委托给/api/v1/models使用的同一统一目录构建器(src/app/api/v1/models/catalog.ts),避免语义漂移;- 请求记录器启用时写全量 Header/主体,日志目录应视作敏感;
- 云行为依赖正确的
NEXT_PUBLIC_BASE_URL与云端点可达性; open-sse/以@omniroute/open-ssenpm workspace 包发布;- 仪表盘图表使用 Recharts(SVG 基础)实现可访问、可交互的分析可视化(模型用量柱状图、带成功率的提供商分解表);
- E2E 测试使用 Playwright(
tests/e2e/,npm run test:e2e),单元测试使用 Node.js test runner(tests/unit/,npm run test:unit);src/为 TypeScript,open-sse/workspace 保持 JavaScript; - 设置页 7 个标签:General、Appearance、AI、Security、Routing、Resilience、Advanced;
- Context Relay 策略拆成两层:
combo.ts决定是否生成交接,chat.ts在账号解析后注入交接(数据存context_handoffsSQLite 表)。此拆分是刻意的,因为只有chat.ts知道实际账号是否变化; - 代理执行已全面化:
tokenHealthCheck.ts按连接解析代理,/api/providers/validate使用runWithProxyContext,proxyFetch.ts在 Node 22 上使用undici.fetch()保持 dispatcher 兼容; - Node.js 运行时策略检测:
/api/settings/require-login返回nodeVersion与nodeCompatible字段,登录页在运行时落出受支持的 Node.js 安全线时渲染警告横幅。
16.3 运维验证清单
- 源码构建:
npm run build - 构建 Docker 镜像:
docker build -t omniroute . - 启动并验证:
GET /api/settingsGET /api/v1/modelsPORT=20128时 CLI 目标 base URL 应为http://<host>:20128/v1
结语
从整体分层到单次请求的毫秒级旅程,OmniRoute 的架构核心是一套**"单端点收敛 + 中枢翻译 + 多级回退 + 写穿持久化"**的本地网关范式:Next.js 路由层解决 API 面与 HTTP 语义,src/sse + open-sse 的 SSE/翻译核心解决协议差异与流式处理,域层与 SQLite 写穿缓存解决策略决策与状态恢复,而执行器策略模式与执行器注册表则为数百个提供商提供了可扩展、可测试的适配缝隙。对于希望接入或二次开发 OmniRoute 的读者,建议按"路由层 → 翻译核心 → 执行器 → 域层/持久化"的次序阅读源码,并以本文第十一章的执行器注册表、第十二章的翻译注册表与第九章的数据模型作为定位锚点。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00