OmniRoute 贡献指南:从开发环境搭建到新增 Provider 的完整实战路径
【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute
本指南基于 OmniRoute 官方贡献文档(docs/i18n/ko/CONTRIBUTING.md,即项目根目录 CONTRIBUTING.md 的国际化版本)系统整理而成,同时结合仓库源码与官方配套文档进行源码级印证。文章面向希望向 OmniRoute 贡献代码的开发者,覆盖开发环境搭建、Git 工作流、测试与覆盖率门槛、代码规范、项目结构、新增 Provider 的六步流程、PR 检查清单以及发布机制,读者完成后即可按官方节奏提交第一个高质量 Pull Request。
说明:本仓库是只读的,以下所有安装、运行与配置步骤均面向贡献者本地开发环境,仓库内容本身无需任何改动。
开发环境搭建
环境要求
| 依赖 | 版本要求 | 说明 |
|---|---|---|
| Node.js | >=18 <24(推荐 22 LTS;英文版根文档更新为>=22.22.3 <23或>=24.0.0 <27,推荐 24 LTS) | 运行时与构建工具链 |
| npm | 10+ | 包管理 |
| Git | 任意近期版本 | 版本控制 |
npm v11+(Node 24+)用户注意:执行
npm install后务必验证原生模块是否安装成功:node -e "require('better-sqlite3')"。若出现MODULE_NOT_FOUND,执行npm approve-scripts better-sqlite3 && npm install,详见 docs/guides/TROUBLESHOOTING.md。仓库 package.json 的engines字段同样声明了 Node 运行时约束(当前版本要求>=22.22.2 <23 || >=24.0.0 <27),项目还内置了 scripts/check/check-supported-node-runtime.ts 用于在构建前校验运行时版本。
克隆与安装
git clone https://github.com/diegosouzapw/OmniRoute.git cd OmniRoute npm install仓库采用 npm workspaces 组织多包结构(见 package.json),工作区包含open-sse(@omniroute/open-sse)与packages/browser-pool两个子包,npm install会自动联动安装。
环境变量配置
# 从模板创建 .env cp .env.example .env # 生成必需密钥 echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env关键开发变量:
| 变量 | 开发默认值 | 作用 |
|---|---|---|
PORT | 20128 | 服务监听端口 |
NEXT_PUBLIC_BASE_URL | http://localhost:20128 | 前端页面 Base URL |
JWT_SECRET | (按上方命令生成) | JWT 签名密钥 |
INITIAL_PASSWORD | CHANGEME | 首次登录密码 |
APP_LOG_LEVEL | info | 日志详细程度 |
仓库根目录的 .env.example(约 177 KB)是完整的变量模板,涵盖端口、密钥、Provider 凭据、压缩引擎、存储与遥测等全部可配置项;src/lib下存在同步脚本(scripts/dev/sync-env.mjs)用于维护环境变量与模板的一致性。
仪表盘设置项
部分功能既可通过环境变量配置,也可在仪表盘 UI 中切换:
| 设置位置 | 开关 | 说明 |
|---|---|---|
| Settings → Advanced | Debug Mode | 开启调试请求日志(UI) |
| Settings → General | Sidebar Visibility | 显示/隐藏侧边栏分区 |
这些设置存储于 SQLite 数据库中,重启后保持,一旦设置即覆盖环境变量默认值。
本地运行
# 开发模式(热重载) npm run dev # 生产构建 npm run build # next build → .build/next/,再由 assembleStandalone 组装到 dist/ npm run start # 面向贡献者的快速后端/API 编译(仅做编译期校验) npm run build:contributor # 发布构建(干净重建 + HEAD 哨兵,部署必须使用) npm run build:release # rm -rf .build dist && build && 写入 dist/BUILD_SHA # 常用端口配置 PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev默认地址:
- 仪表盘:
http://localhost:20128/dashboard - API:
http://localhost:20128/v1
构建产物布局
| 目录 | 内容 | 是否入库 |
|---|---|---|
src/ | 应用源码(TypeScript / TSX) | 是 |
.build/ | 中间产物 ——next build输出(gitignore,distDir = .build/next) | 否 |
dist/ | 可发布产物 —— 由assembleStandalone组装(gitignore) | 否 |
单趟构建管线:
npm run build └─ next build → .build/next/standalone (Next.js 输出) └─ assembleStandalone() (复制 standalone + static + public + 原生资源) └─ 输出: dist/ (server.js, .next/static/, public/, node_modules/)npm run build:contributor使用后端专用构建 profile:构建期间临时桩掉仪表盘 UI 文件、保留 API 路由处理器,构建结束后恢复原文件。涉及仪表盘 UI 或完整发布验证时仍应使用npm run build,贡献者 profile 不能替代正式发布构建。
Git 工作流
⚠️绝不直接向
main提交。始终使用功能分支。
# 从活跃发布分支顶端拉分支(示例:release/v3.8.49) git fetch origin git checkout -b feat/your-feature-name origin/release/v3.8.49 # ... 修改 ... git commit -m "feat: describe your change" git push -u origin feat/your-feature-name # 以 release/v3.8.49 为 base 发起 Pull Request分支命名
| 前缀 | 用途 |
|---|---|
feat/ | 新功能 |
fix/ | Bug 修复 |
refactor/ | 代码重构 |
docs/ | 文档变更 |
test/ | 测试新增/修复 |
chore/ | 工具链、CI、依赖 |
PR base:官方要求目标分支是当前活跃的
release/vX.Y.Z(而非main),具体模型见 docs/ops/BRANCHING_MODEL.md(release-per-branch + 发布时打 tag)。完整的变更路径编排(contracts → focused tests → CI → 对账)见 docs/ops/CONTRIBUTION_GOLDEN_PATH.md。
Commit Message
遵循 Conventional Commits 规范:
feat: add circuit breaker for provider calls fix: resolve JWT secret validation edge case docs: update SECURITY.md with PII protection test: add observability unit tests refactor(db): consolidate rate limit tables作用域(v3.8):db、sse、oauth、dashboard、api、cli、docker、ci、mcp、a2a、memory、skills,另含cloud-agent、guardrails、compression、auto-combo、resilience、providers、executors、translator、domain、authz。
运行测试
# 全部测试(unit + vitest + ecosystem + e2e) npm run test:all # 单个测试文件(Node.js 原生测试运行器 —— 多数测试用它) node --import tsx/esm --test tests/unit/your-file.test.ts # 只跑本次改动影响的单元测试(与 CI 门槛同款 TIA 选择器) npm run test:scoped # 最近一次提交(或工作区)的改动 npm run test:scoped:staged # 仅暂存区改动 —— 适合 pre-commit npm run test:scoped:full # 先重建 import 图(新增/移动文件后) # 退出码 1 + "run the full suite" 表示 hub 文件(tsconfig、package.json 等)或 # 未映射源码变更 —— 选择器安全失败,绝不静默跳过。 # Vitest(MCP server、autoCombo、cache) npm run test:vitest # E2E 测试(需要 Playwright) npm run test:e2e # 协议客户端 E2E(MCP transports、A2A) npm run test:protocols:e2e # 生态兼容性测试 npm run test:ecosystem # 覆盖率门槛:语句/行/函数/分支 60% npm run test:coverage npm run coverage:report # Lint + 格式检查 npm run lint npm run check覆盖率说明
npm run test:coverage统计主单元测试套件的源码覆盖率,排除tests/**,包含open-sse/**;对应实现见 package.json 中scripts.test:coverage(基于 c8,--check-coverage --statements 60 --lines 60 --functions 60 --branches 60)。- PR 必须将语句、行、函数、分支四项覆盖率的总体门槛维持在60% 或更高。
- 若 PR 改动
src/、open-sse/、electron/或bin/的生产代码,必须在同一 PR 内新增或更新自动化测试。 npm run coverage:report打印最近一次覆盖率运行的逐文件详细报告。npm run test:coverage:legacy保留旧口径指标用于历史对比。- 分阶段覆盖率提升路线图见 docs/ops/COVERAGE_PLAN.md。
Pull Request 要求
发起或合并 PR 前:
- 按 CONTRIBUTION_GOLDEN_PATH.md 跑改动的 focused 测试环:
node --import tsx/esm --test tests/unit/<file>.test.ts - 运行
npm run lint - 保证覆盖率门槛 60%+(四项指标)
- 生产代码变更时,在 PR 描述中列出新增/修改的测试文件
- 若 CI 已配置项目密钥,检查 PR 上的 SonarQube 结果
当前测试状态:单元测试文件数千个(仓库根文档记录为 122 个测试文件,实际 tests/unit 目录已扩展至约 4500 个测试文件),覆盖:
- Provider 翻译器与格式转换
- 限流、熔断与韧性
- 语义缓存、幂等、进度追踪
- 数据库操作与 schema(21 个 DB 模块)
- OAuth 流程与认证
- API 端点校验(Zod v4)
- MCP server 工具与作用域强制
- Memory 与 Skills 系统
代码风格
- ESLint— 提交前运行
npm run lint(仓库使用.eslintcache与 config/quality/eslint-suppressions.json 管理存量告警抑制) - Prettier— 提交时经
lint-staged自动格式化(2 空格缩进、分号、双引号、100 列宽、es5 trailing commas),配置见 prettier.config.mjs - TypeScript—
src/全部使用.ts/.tsx;open-sse/使用.ts/.js;公共函数用 TSDoc 注释(@param、@returns、@throws) - 禁止
eval()— ESLint 强制no-eval、no-implied-eval、no-new-func - Zod 校验— 所有 API 输入校验使用 Zod v4 schema,schema 集中在 src/shared/validation
- 命名:文件 = camelCase/kebab-case,组件 = PascalCase,常量 = UPPER_SNAKE
错误处理 / 空 catch 块约定
任何catch都不允许无解释。分两类(落实“绝不静默吞掉 SSE 流错误”的硬性规则):
有意留空(自有 best-effort 清理/遥测)—— 失败可预期且无害,加一行注释说明理由,不打日志(每条请求都打日志正是该约定要避免的噪音):
} catch {} // closing an already-closed controller after client disconnect is expected应当记录(外部/调用方提供的代码,或吞错会改变控制流)—— 保留 catch(绝不让它打断流),但输出带上下文的
console.debug/warn使失败可被发现:} catch (e) { console.debug("[STREAM] onFailure callback error:", e); }
应用实例见 open-sse/utils/stream.ts 与 open-sse/utils/streamHandler.ts。
项目结构
src/ # TypeScript (.ts / .tsx) ├── app/ # Next.js 16 App Router │ ├── (dashboard)/ # 仪表盘页面(23 个分区) │ ├── api/ # API 路由(51 个目录) │ └── login/ # 认证页面 (.tsx) ├── domain/ # 策略引擎(policyEngine、comboResolver、costRules 等) ├── lib/ # 核心业务逻辑 (.ts) │ ├── a2a/ # Agent-to-Agent v0.3 协议服务器 │ ├── acp/ # Agent Communication Protocol 注册表 │ ├── compliance/ # 合规策略引擎 │ ├── db/ # SQLite 领域模块 + 130 个迁移 │ ├── memory/ # 持久化对话记忆 │ ├── oauth/ # OAuth providers、services 与工具 │ ├── skills/ # 可扩展技能框架 │ ├── usage/ # 用量追踪与成本计算 │ └── localDb.ts # 仅做再导出 —— 绝不在其中添加逻辑 ├── middleware/ # 请求中间件(promptInjectionGuard) ├── mitm/ # MITM 代理(证书、DNS、目标路由) ├── shared/ │ ├── components/ # React 组件 (.tsx) │ ├── constants/ # Provider 定义(329 个)、MCP scopes、19 种路由策略 │ ├── utils/ # 熔断器、sanitizer、认证辅助 │ └── validation/ # Zod v4 schemas └── sse/ # SSE 代理管线 open-sse/ # @omniroute/open-sse workspace ├── executors/ # 89 个 executor 实现模块(仓库当前实际约 113 个 .ts 文件) ├── handlers/ # 11 个请求处理器(chat、responses、embeddings、images 等) ├── mcp-server/ # MCP server(110 个工具、3 种传输、33 个 scopes) ├── services/ # 178 个顶层服务(combo、autoCombo、rateLimitManager 等) ├── translator/ # 格式翻译器(OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama) ├── transformer/ # Responses API 转换器 └── utils/ # 22 个工具模块(stream、TLS、proxy、logging) electron/ # Electron 桌面应用(跨平台) tests/ ├── unit/ # Node.js 测试运行器(数千个测试文件) ├── integration/ # 集成测试 ├── e2e/ # Playwright 测试 ├── security/ # 安全测试 ├── translator/ # 翻译器专项测试 └── load/ # 负载测试 docs/ ├── adr/ # 架构决策记录 ├── architecture/ # 系统架构与韧性 ├── comparison/ # OmniRoute vs 竞品 ├── compression/ # 压缩指南与规则 ├── dev/ # 开发指南 ├── diagrams/ # 架构图 ├── frameworks/ # MCP、A2A、OpenCode、Memory、Skills ├── guides/ # 用户指南、Docker、setup、troubleshooting ├── i18n/ # 国际化 README 翻译 ├── marketing/ # 营销素材 ├── ops/ # 部署、代理、覆盖率、发布 ├── providers/ # Provider 专项文档 ├── reference/ # API 参考、环境变量、CLI 工具、免费档 ├── releases/ # 发布说明 ├── routing/ # Auto-combo 引擎、reasoning replay ├── screenshots/ # 仪表盘截图 ├── security/ # 防护、合规、隐身、令牌 └── specs/ # 设计规格说明:数字为根文档撰写时的统计,仓库演进后可能略有变化(例如
tests/unit已远超文档记录的规模)。整体分层骨架以 docs/architecture/ARCHITECTURE.md 为准。
新增一个 Provider
OmniRoute 以“一个端点汇聚数百家 Provider”为核心能力(详见根 README.md),因此新增 Provider 是社区最常见的贡献类型之一。官方流程共六步:
第 1 步:注册 Provider 常量
在src/shared/constants/providers.ts中添加定义 —— 该文件在模块加载时经 Zod 校验。从源码结构看,Provider 定义还进一步拆分为src/shared/constants/providers/目录下的分文件组合(见 CONTRIBUTION_GOLDEN_PATH.md 中 “Provider definition insrc/shared/constants/providers/and its composition insrc/shared/constants/providers.ts”)。
第 2 步:添加 Executor(需要自定义逻辑时)
在open-sse/executors/your-provider.ts创建 executor,继承基础 executor(BaseExecutor)。executor 负责与上游 Provider 的实际网络通信与协议适配,当前 open-sse/executors 已包含约 113 个实现模块。
第 3 步:添加 Translator(非 OpenAI 格式时)
在 open-sse/translator 中创建请求/响应翻译器,负责 OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama 等格式互转。
第 4 步:添加 OAuth 配置(基于 OAuth 时)
在src/lib/oauth/constants/oauth.ts添加 OAuth 凭据,在src/lib/oauth/services/添加对应 service。
若上游 Provider 在其公开 CLI/浏览器包中分发公开 OAuth client_id/secret 或 Firebase Web API key,严禁以字符串字面量硬编码。必须使用 open-sse/utils/publicCreds.ts 的resolvePublicCred()(实现为“env 覆盖优先 →EMBEDDED_DEFAULTS掩码字节默认值”,支持多环境变量别名的resolvePublicCredMulti()),并在EMBEDDED_DEFAULTS中登记掩码字节条目。完整强制流程见 docs/security/PUBLIC_CREDS.md。
此外,handlers/executors 中到达客户端的错误消息必须经由 open-sse/utils/error.ts 的buildErrorBody()/sanitizeErrorMessage()处理,绝不允许把原始err.stack或err.message放进 Response body,详见 docs/security/ERROR_SANITIZATION.md。
第 5 步:注册模型
在 open-sse/config/providerRegistry.ts 中添加模型定义。
第 6 步:添加测试
在 tests/unit 编写单元测试,至少覆盖:
- Provider 注册
- 请求/响应翻译
- 错误处理
Provider 变更的 focused 校验环
根据 CONTRIBUTION_GOLDEN_PATH.md,Provider 类变更还建议跑:
npm run check:provider-consistency npm run check:provider-assets node --import tsx/esm --test tests/unit/provider-translate-path-golden.test.ts node --import tsx/esm --test tests/unit/<provider-or-executor>.test.ts npm run gen:provider-reference # 目录变更时执行;提交生成的 diff npm run lint同时要覆盖受影响的每个请求族:chat、Responses、images、embeddings、audio 或 video;生成的目录与 golden diff 需当作契约变更审查,不要盲目接受。
Pull Request 检查清单
提交 PR 前逐项确认:
- 测试通过(
npm test) - Lint 通过(
npm run lint) - 构建成功(
npm run build) - 新公共函数与接口补充 TypeScript 类型
- 无硬编码密钥或 fallback 值
- 公开上游凭据经
resolvePublicCred()注入(见 docs/security/PUBLIC_CREDS.md),绝不使用字面量 - 错误响应经由
buildErrorBody()/sanitizeErrorMessage()—— Response body 中无原始堆栈(见 docs/security/ERROR_SANITIZATION.md) - Shell 命令(
exec/spawn)通过env传运行时值,而非字符串插值 - 所有输入经 Zod schemas 校验
- 面向用户的功能变更在
changelog.d/{features|fixes|maintenance}/<PR>-<slug>.md添加 changelogfragment(见 changelog.d/README.md)——不要直接编辑CHANGELOG.md,fragment 在发布时聚合,PR 之间永不冲突 - 文档已更新(如适用)
- 无新增 CodeQL / Secret-Scanning 告警,或每条均引用相关
docs/security/文档给出技术理由 - 派生子进程的路由(
/api/mcp/、/api/cli-tools/runtime/)在 src/server/authz/routeGuard.ts 中归类为isLocalOnlyPath()—— 见 docs/security/ROUTE_GUARD_TIERS.md 硬性规则 #15 - commit message 中无
Co-Authored-By尾注 —— 提交必须以仓库所有者 Git 身份单独署名(硬性规则 #16)
发布机制
发布由/generate-releaseworkflow 管理:创建新的 GitHub Release 后,包经 GitHub Actions自动发布到 npm。
VPS 部署必须使用npm run build:release(而非npm run build)—— 它执行干净重建、把产物组装进dist/并写入dist/BUILD_SHA哨兵,随后通过/deploy-vps-*-cc技能将dist/rsync 到远端app/目录。
获取帮助
- 架构:docs/architecture/ARCHITECTURE.md
- API 参考:docs/reference/API_REFERENCE.md
- 安全文档:docs/security/CLI_TOKEN.md、docs/security/ROUTE_GUARD_TIERS.md、docs/security/ERROR_SANITIZATION.md、docs/security/PUBLIC_CREDS.md
- 运维文档:docs/ops/SQLITE_RUNTIME.md
- 问题追踪:GitHub Issues(仓库地址见 package.json 的
repository字段) - ADR:
docs/adr/目录存放架构决策记录 - 变更流程:docs/ops/CONTRIBUTION_GOLDEN_PATH.md 与 docs/ops/BRANCHING_MODEL.md
从cp .env.example .env到提交带测试的 Provider 集成,OmniRoute 的贡献链路是“契约先行、测试贴身、CI 兜底”的工程化范式:Provider 常量经 Zod 加载时校验,公开凭据只走掩码字节注入,错误消息统一消毒,changelog 以 fragment 聚合。按本文六步流程动手,你的第一个 Provider PR 就能与 500+ 贡献者的协作节奏无缝对齐。
【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考