[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-2065":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":27,"readmeContent":28,"aiSummary":29,"trendingCount":16,"starSnapshotCount":16,"syncStatus":15,"lastSyncTime":30,"discoverSource":31},2065,"OpenCode2API","TiaraBasori\u002FOpenCode2API","TiaraBasori","将运行在本地的 OpenCode 转换为 OpenAI 兼容 API ，以在任何 OpenAI 客户端中使用免费模型。","",null,"JavaScript",179,32,3,2,0,4,11,46,12,4.56,"MIT License",false,"main",true,[],"2026-06-12 02:00:36","# OpenCode2API\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fversion-1.5.0-blue\" alt=\"Version\">\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-green\" alt=\"License\">\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FNode.js-18+-orange\" alt=\"Node\">\n\u003C\u002Fp>\n\n> 📖 [文档](.\u002Fdocs\u002FREADME.md) | 🚀 [快速开始](#-快速开始)\n\n将本地 [OpenCode](https:\u002F\u002Fopencode.ai) 运行时转换为 OpenAI 兼容 API 网关。在任何 OpenAI 客户端中使用免费模型 (GPT, Nemotron, MiniMax)。\n\n---\n\n## ✨ 功能特性\n\n| 特性 | 说明 |\n|:-----|:-----|\n| 🟢 **OpenAI 兼容** | `\u002Fv1\u002Fmodels`, `\u002Fv1\u002Fchat\u002Fcompletions`, `\u002Fv1\u002Fresponses` |\n| 📡 **流式输出** | Chat Completions 与 Responses API 的完整 SSE 流式支持 |\n| 🧠 **推理控制** | 支持 `reasoning_effort` 和 `reasoning: { \"effort\": \"high\" }` |\n| 🐳 **Docker 部署** | 一键部署，自动启动 OpenCode 后端 |\n| 🛡️ **工具安全** | 默认禁用工具调用 |\n| 🔧 **外部工具桥接** | 支持外部客户端传入 `tools`，由代理桥接为 OpenAI-compatible `tool_calls` \u002F `function_call`，避免命中 OpenCode 内置工具 |\n| 🌐 **内置 web_fetch 透传** | 当请求未传入 `tools` 且显式开启特性时，仅允许 OpenCode 内置 `web_fetch` 参与该次请求 |\n\n---\n\n## 🚀 快速开始\n\n### Docker 部署 (推荐)\n\n```bash\n# 1. 克隆并配置\ngit clone https:\u002F\u002Fgithub.com\u002FTiaraBasori\u002Fopencode2api.git\ncd opencode2api\ncp .env.example .env\n\n# 2. 编辑 .env 设置你的配置\n# 必填: API_KEY, OPENCODE_SERVER_PASSWORD\n\n# 3. 启动\ndocker compose up -d\n\n# 4. 测试\ncurl http:\u002F\u002F127.0.0.1:10000\u002Fhealth\n```\n\n> 默认 `docker-compose.yml` 不会把宿主机项目目录挂载到容器内，因为那会覆盖镜像里已安装的 `node_modules`，导致容器依赖宿主机先执行 `npm install`。如果你需要本地源码热更新，建议单独使用开发专用的 Compose 覆盖配置。\n\n### Node.js (本地开发)\n\n```bash\n# 1. 安装 OpenCode CLI\nnpm install -g opencode-ai\n# Linux\u002FmacOS: curl -fsSL https:\u002F\u002Fopencode.ai\u002Finstall | bash\n\n# 2. 克隆并运行\ngit clone https:\u002F\u002Fgithub.com\u002FTiaraBasori\u002Fopencode2api.git\ncd opencode2api\nnpm install\ncp config.json.example config.json\nnpm start\n```\n\n---\n\n## 💡 使用示例\n\n### Chat Completions\n\n```bash\ncurl -X POST http:\u002F\u002F127.0.0.1:10000\u002Fv1\u002Fchat\u002Fcompletions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"model\": \"opencode\u002Fbig-pickle\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"你好!\"}],\n    \"stream\": false\n  }'\n```\n\n### Responses API (带推理)\n\n```bash\ncurl -N -X POST http:\u002F\u002F127.0.0.1:10000\u002Fv1\u002Fresponses \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"model\": \"gpt5-nano\",\n    \"input\": \"用一句话打招呼\",\n    \"reasoning\": {\"effort\": \"high\"},\n    \"stream\": true\n  }'\n```\n\n### Chat Completions + 外部工具\n\n```bash\ncurl -X POST http:\u002F\u002F127.0.0.1:10000\u002Fv1\u002Fchat\u002Fcompletions \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"model\": \"opencode\u002Fbig-pickle\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"帮我获取 https:\u002F\u002Fexample.com 的标题\"}],\n    \"tools\": [\n      {\n        \"type\": \"function\",\n        \"function\": {\n          \"name\": \"web_fetch\",\n          \"description\": \"Fetch a URL and return its content summary\",\n          \"parameters\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"url\": {\"type\": \"string\"}\n            },\n            \"required\": [\"url\"]\n          }\n        }\n      }\n    ]\n  }'\n```\n\n### Responses API + 外部工具流式\n\n```bash\ncurl -N -X POST http:\u002F\u002F127.0.0.1:10000\u002Fv1\u002Fresponses \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"model\": \"opencode\u002Fbig-pickle\",\n    \"input\": \"查询东京天气\",\n    \"stream\": true,\n    \"tools\": [\n      {\n        \"type\": \"function\",\n        \"function\": {\n          \"name\": \"weather_lookup\",\n          \"description\": \"Look up weather by city\",\n          \"parameters\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"city\": {\"type\": \"string\"},\n              \"unit\": {\"type\": \"string\"}\n            },\n            \"required\": [\"city\"]\n          }\n        }\n      }\n    ]\n  }'\n```\n\n---\n\n## 📦 部署方式\n\n| 模式 | 说明 | 适用场景 |\n|:-----|:-----|:---------|\n| 🐳 **Docker** | 完整栈，自动启动 OpenCode 后端 | 生产环境，最简配置 |\n| 💻 **独立 Node** | 手动管理后端 | 开发、自定义集成 |\n\n---\n\n## ⚙️ 配置\n\n### 快速参考\n\n| 环境变量 | 默认值 | 说明 |\n|:--------|:-------|:------|\n| `PORT` \u002F `OPENCODE_PROXY_PORT` | `10000` | 代理服务端口 |\n| `OPENCODE_SERVER_PORT` | `10001` | OpenCode 后端服务端口 |\n| `API_KEY` | - | Bearer Token 认证密钥 |\n| `BIND_HOST` | `0.0.0.0` | 绑定地址 |\n| `DISABLE_TOOLS` | `true` | 禁用 OpenCode 工具调用 |\n| `OPENCODE_EXTERNAL_TOOLS_MODE` | `proxy-bridge` | 外部工具桥接模式；当前仅支持 `proxy-bridge` |\n| `OPENCODE_EXTERNAL_TOOLS_CONFLICT_POLICY` | `namespace` | 外部工具与 OpenCode 内置工具的冲突隔离策略；当前仅支持 `namespace` |\n| `OPENCODE_INTERNAL_WEB_FETCH_ENABLED` | `false` | 兼容旧开关；当未显式配置 allowlist 时，启用后默认放行 `web_fetch` |\n| `OPENCODE_INTERNAL_ALLOWED_TOOLS` | `(none)` | 当请求未传入 `tools` 时，允许使用的 OpenCode 内置工具列表，逗号分隔 |\n| `OPENCODE_INTERNAL_TOOL_METRICS_ENABLED` | `true` | 输出 internal allowlist 模式的调试\u002F指标日志 |\n| `OPENCODE_TOOL_DISCOVERY_FIXTURE` | `(none)` | 集成测试\u002F本地调试用的后端工具 ID 固定列表，逗号分隔 |\n| `OPENCODE_HEALTH_DETAILS_ENABLED` | `true` | 控制 `\u002Fhealth\u002Fdetails` 是否暴露 |\n| `OPENCODE_HEALTH_DETAILS_REQUIRE_AUTH` | `true` | 控制 `\u002Fhealth\u002Fdetails` 是否要求 Bearer 认证 |\n| `OPENCODE_METRICS_ENABLED` | `false` | 控制 `\u002Fmetrics` 是否暴露 |\n| `OPENCODE_METRICS_REQUIRE_AUTH` | `true` | 控制 `\u002Fmetrics` 是否要求 Bearer 认证 |\n| `USE_ISOLATED_HOME` | `false` | 使用隔离的 OpenCode 配置目录 |\n| `OPENCODE_PROXY_PROMPT_MODE` | `standard` | 提示词处理模式 |\n| `OPENCODE_PROXY_OMIT_SYSTEM_PROMPT` | `false` | 忽略传入的 system prompt |\n| `OPENCODE_PROXY_AUTO_CLEANUP_CONVERSATIONS` | `false` | 自动清理会话存储 |\n| `OPENCODE_PROXY_CLEANUP_INTERVAL_MS` | `43200000` | 清理间隔 (毫秒) |\n| `OPENCODE_PROXY_CLEANUP_MAX_AGE_MS` | `86400000` | 最大存储时间 (毫秒) |\n| `OPENCODE_PROXY_REQUEST_TIMEOUT_MS` | `180000` | 请求超时时间 (毫秒) |\n| `OPENCODE_SERVER_URL` | `http:\u002F\u002F127.0.0.1:10001` | OpenCode 后端地址 |\n| `OPENCODE_SERVER_PASSWORD` | - | OpenCode 后端密码 |\n| `OPENCODE_PATH` | `opencode` | OpenCode 可执行文件路径 |\n| `OPENCODE_ZEN_API_KEY` | - | Zen API Key 透传 |\n| `DEBUG` \u002F `OPENCODE_PROXY_DEBUG` | `false` | 调试日志 |\n\n> 📄 完整配置参考: [配置详解](.\u002Fdocs\u002Fconfiguration.md)\n\n### 推荐生产配置\n\n```env\nAPI_KEY=your-secret-key\nOPENCODE_SERVER_PASSWORD=your-password\nDISABLE_TOOLS=true\nOPENCODE_EXTERNAL_TOOLS_MODE=proxy-bridge\nOPENCODE_EXTERNAL_TOOLS_CONFLICT_POLICY=namespace\nOPENCODE_INTERNAL_ALLOWED_TOOLS=web_fetch\nOPENCODE_INTERNAL_TOOL_METRICS_ENABLED=true\nOPENCODE_TOOL_DISCOVERY_FIXTURE=\nOPENCODE_HEALTH_DETAILS_ENABLED=true\nOPENCODE_HEALTH_DETAILS_REQUIRE_AUTH=true\nOPENCODE_METRICS_ENABLED=false\nOPENCODE_METRICS_REQUIRE_AUTH=true\nOPENCODE_PROXY_PROMPT_MODE=plugin-inject\nOPENCODE_PROXY_OMIT_SYSTEM_PROMPT=true\nOPENCODE_PROXY_AUTO_CLEANUP_CONVERSATIONS=true\n```\n\n\n### 外部工具桥接说明\n\n- 外部客户端传入的 `tools` 不会被注册为 OpenCode 内置工具。\n- 代理会把这些工具虚拟化后交给模型使用，并把模型输出重新整理为 OpenAI-compatible `tool_calls` \u002F `function_call`。\n- 同名冲突默认通过内部命名空间隔离处理，例如客户端的 `web_fetch` 不会误触发 OpenCode 容器内工具。\n- 内部命名空间名（如 `external__web_fetch`）是代理内部实现细节，不属于公开 API。\n\n### 内置工具 allowlist 说明\n\n- 当请求 **未传入** `tools` 时，代理会进入 internal allowlist 模式，并只允许 `OPENCODE_INTERNAL_ALLOWED_TOOLS` 中声明的 OpenCode 内置工具。\n- `OPENCODE_INTERNAL_WEB_FETCH_ENABLED=true` 仅作为兼容旧配置的快捷方式：当未显式配置 `OPENCODE_INTERNAL_ALLOWED_TOOLS` 时，会默认把 allowlist 视为 `web_fetch`。\n- 代理会读取后端工具列表，并通过精确匹配或 `.\u003Ctool>` \u002F `\u002F\u003Ctool>` 后缀匹配解析最终可用工具。\n- 如果配置的 allowlist 在后端工具列表中一个也匹配不到，代理会自动回退到“全部内置工具禁用”的安全模式。\n- `OPENCODE_INTERNAL_TOOL_METRICS_ENABLED=true` 时，代理会输出 internal allowlist 模式的调试\u002F指标日志，包括模式选择、后端工具发现、allowlist 命中结果和降级原因，但不会记录工具返回内容。\n- `OPENCODE_TOOL_DISCOVERY_FIXTURE` 可用于集成测试或本地调试，绕过真实 `client.tool.ids()` 返回固定工具 ID 列表。\n- 一旦客户端显式传入 `tools`，请求立即回到现有外部工具桥接逻辑，OpenCode 内置工具继续保持禁用。\n\n### 结构化诊断与 Prometheus 指标\n\n- `\u002Fhealth` 始终保持为轻量健康检查接口。\n- `\u002Fhealth\u002Fdetails` 返回结构化 JSON 诊断数据，可通过 `OPENCODE_HEALTH_DETAILS_ENABLED` 控制是否暴露，并通过 `OPENCODE_HEALTH_DETAILS_REQUIRE_AUTH` 控制是否要求 Bearer 认证。\n- `\u002Fmetrics` 返回 Prometheus 文本格式指标，可通过 `OPENCODE_METRICS_ENABLED` 控制是否暴露，并通过 `OPENCODE_METRICS_REQUIRE_AUTH` 控制是否要求 Bearer 认证。\n- `\u002Fmetrics` 目前暴露 internal tool mode、tool discovery failures、fallback count 和 tool-id cache 数量等指标。\n\n---\n\n## 🔌 API 参考\n\n### 端点\n\n| 方法 | 路径 | 说明 |\n|:-----|:-----|:-----|\n| `GET` | `\u002Fhealth` | 健康检查 |\n| `GET` | `\u002Fhealth\u002Fdetails` | 结构化诊断接口（可配置开关\u002F鉴权） |\n| `GET` | `\u002Fmetrics` | Prometheus 指标接口（可配置开关\u002F鉴权） |\n| `GET` | `\u002Fv1\u002Fmodels` | 获取可用模型列表 |\n| `POST` | `\u002Fv1\u002Fchat\u002Fcompletions` | Chat Completions API |\n| `POST` | `\u002Fv1\u002Fresponses` | Responses API |\n\n### 模型名称格式\n\n- 直接使用: `opencode\u002Fbig-pickle`\n- 带别名: `gpt5-nano` (自动解析为 `gpt-5-nano`)\n- 带前缀: `opencode\u002Fgpt5-nano`\n\n> 📖 详见 [API 参考文档](.\u002Fdocs\u002Fapi-reference.md)\n\n---\n\n## 🔧 故障排查\n\n### 请求卡住但 `\u002Fv1\u002Fmodels` 正常\n```bash\nUSE_ISOLATED_HOME=false  # 让 OpenCode 复用本地登录态\n```\n\n### 模型找不到\n- 查看可用模型: `curl http:\u002F\u002F127.0.0.1:10000\u002Fv1\u002Fmodels`\n- 确认模型 ID 完全匹配\n\n### 没有推理输出\n- 使用 `stream: true` 的 Responses API\n- 发送 `reasoning.effort` 或 `reasoning_effort`\n\n> 📖 完整指南: [故障排查](.\u002Fdocs\u002Ftroubleshooting.md)\n\n---\n\n## 🔨 开发\n\n```bash\n# 运行测试\nnpm test -- --runInBand\n\n# Docker 开发\ndocker compose up -d --build\n```\n\n---\n\n## 📄 许可证\n\nMIT · 详见 [LICENSE](.\u002FLICENSE.md)\n\n---\n\n## 🙏 致谢\n\n感谢以下开源项目:\n\n- [dxxzst\u002Fopencode-to-openai](https:\u002F\u002Fgithub.com\u002Fdxxzst\u002Fopencode-to-openai)\n- [lucasliet\u002Fopencode-openai-proxy](https:\u002F\u002Fgithub.com\u002Flucasliet\u002Fopencode-openai-proxy)\n","OpenCode2API 项目旨在将本地运行的 OpenCode 转换为与 OpenAI 兼容的 API，从而允许用户在任何支持 OpenAI 的客户端中使用免费模型。该项目基于 JavaScript 构建，提供了包括 `\u002Fv1\u002Fmodels`, `\u002Fv1\u002Fchat\u002Fcompletions`, 和 `\u002Fv1\u002Fresponses` 在内的标准接口，并支持流式数据传输以增强交互体验。此外，它还具备推理控制功能以及通过 Docker 快速部署的能力。特别适用于希望利用开源 AI 模型（如 GPT, Nemotron, MiniMax 等）进行开发但又不想直接依赖于商业服务的开发者或团队。通过 OpenCode2API，可以轻松地将这些模型集成到现有应用中，同时保持对工具调用的安全性管理。","2026-06-11 02:47:54","CREATED_QUERY"]