Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

xiejindou/OpenCode2API

Repository files navigation

OpenCode2API

Version License Node

📖 文档 | 🚀 快速开始

将本地 OpenCode 运行时转换为 OpenAI 兼容 API 网关。在任何 OpenAI 客户端中使用免费模型 (GPT, Nemotron, MiniMax)。


✨ 功能特性

特性 说明
🟢 OpenAI 兼容 /v1/models, /v1/chat/completions, /v1/responses
📡 流式输出 Chat Completions 与 Responses API 的完整 SSE 流式支持
🧠 推理控制 支持 reasoning_effortreasoning: { "effort": "high" }
🔧 外部工具调用(完整兼容) 客户端按标准 OpenAI tools 格式传入,代理自动桥接,返回标准 tool_calls,无需任何兼容代码
🛡️ 工具安全 默认禁用 OpenCode 内置工具,外部工具命名空间隔离防冲突
🐳 Docker 部署 一键部署,自动启动 OpenCode 后端
🌐 内置 web_fetch 透传 当请求未传入 tools 且显式开启特性时,仅允许 OpenCode 内置 web_fetch 参与该次请求

🚀 快速开始

Docker 部署 (推荐)

# 1. 克隆并配置
git clone https://github.com/TiaraBasori/opencode2api.git
cd opencode2api
cp .env.example .env
# 2. 编辑 .env 设置你的配置
# 必填: API_KEY, OPENCODE_SERVER_PASSWORD
# 3. 启动
docker compose up -d
# 4. 测试
curl http://127.0.0.1:10000/health

Node.js (本地开发)

# 1. 安装 OpenCode CLI
npm install -g opencode-ai
# Linux/macOS: curl -fsSL https://opencode.ai/install | bash
# 2. 克隆并运行
git clone https://github.com/TiaraBasori/opencode2api.git
cd opencode2api
npm install
cp config.json.example config.json
npm start

🔧 外部工具调用

OpenCode2API 对外部工具调用做了完整的兼容处理,客户端只需按标准 OpenAI API 格式传入 tools,即可获得标准的 tool_calls 返回,无需任何适配代码

工作原理

客户端 (LangChain / OpenAI SDK / curl)
 │ 传入标准 OpenAI tools 格式
 ▼
OpenCode2API 代理层
 │ 1. 注册外部工具,加命名空间前缀 (external__)
 │ 2. 注入提示词引导模型输出 <function_calls> 格式
 │ 3. 模型输出后,解析并转换为标准 tool_calls
 │ 4. 若模型未正确输出工具调用,智能重试一次
 ▼
客户端收到标准 OpenAI tool_calls 响应

兼容性保障

保障项 说明
标准格式 客户端传入标准 OpenAI tools,收到标准 tool_calls,完全兼容 OpenAI SDK
解析容错 支持 <function_calls> 标签格式、裸 JSON 格式、markdown 代码块包裹、多行格式化、嵌套 arguments
智能重试 auto 模式下检测到模型"想调用但格式不对"时自动重试;required 模式下始终强制重试
命名空间隔离 外部工具自动加 external__ 前缀,与 OpenCode 内置工具隔离,同名不冲突
推理内容过滤 模型的 <think/> 推理内容不会泄露到客户端响应中

Python 示例 (LangChain)

from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
def get_weather(city: str) -> str:
 """获取指定城市的天气"""
 # ... 实际实现 ...
 return f"{city}当前天气:晴,气温26°C"
llm = ChatOpenAI(
 base_url="http://127.0.0.1:10000/v1",
 model="opencode/deepseek-v4-flash-free",
 api_key="your-api-key",
 temperature=0.2,
)
agent = create_agent(
 model=llm,
 tools=[get_weather],
 system_prompt="你是一个天气助手,请用中文回答。",
)
result = agent.invoke(
 {"messages": [{"role": "user", "content": "深圳今天天气怎么样?"}]}
)
print(result)

Python 示例 (OpenAI SDK)

from openai import OpenAI
client = OpenAI(
 base_url="http://127.0.0.1:10000/v1",
 api_key="your-api-key",
)
response = client.chat.completions.create(
 model="opencode/deepseek-v4-flash-free",
 messages=[{"role": "user", "content": "深圳今天天气怎么样?"}],
 tools=[{
 "type": "function",
 "function": {
 "name": "get_weather",
 "description": "获取指定城市的天气",
 "parameters": {
 "type": "object",
 "properties": {
 "city": {"type": "string", "description": "城市名称"}
 },
 "required": ["city"]
 }
 }
 }]
)
if response.choices[0].message.tool_calls:
 for tc in response.choices[0].message.tool_calls:
 print(f"工具: {tc.function.name}, 参数: {tc.function.arguments}")

curl 示例

curl -X POST http://127.0.0.1:10000/v1/chat/completions \
 -H "Authorization: Bearer YOUR_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "model": "opencode/big-pickle",
 "messages": [{"role": "user", "content": "深圳今天天气怎么样?"}],
 "tools": [
 {
 "type": "function",
 "function": {
 "name": "get_weather",
 "description": "获取指定城市的天气",
 "parameters": {
 "type": "object",
 "properties": {
 "city": {"type": "string", "description": "城市名称"}
 },
 "required": ["city"]
 }
 }
 }
 ]
 }'

tool_choice 支持

行为
"auto" (默认) 模型自行决定是否调用工具;若模型输出了工具调用痕迹但格式不对,代理会智能重试一次
"required" 强制模型必须调用工具;若首次未成功,代理会强制重试
"none" 禁用工具调用
{"type": "function", "function": {"name": "xxx"}} 强制调用指定工具

💡 使用示例

Chat Completions

curl -X POST http://127.0.0.1:10000/v1/chat/completions \
 -H "Authorization: Bearer YOUR_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "model": "opencode/big-pickle",
 "messages": [{"role": "user", "content": "你好!"}],
 "stream": false
 }'

Responses API (带推理)

curl -N -X POST http://127.0.0.1:10000/v1/responses \
 -H "Authorization: Bearer YOUR_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "model": "gpt5-nano",
 "input": "用一句话打招呼",
 "reasoning": {"effort": "high"},
 "stream": true
 }'

Responses API + 外部工具流式

curl -N -X POST http://127.0.0.1:10000/v1/responses \
 -H "Authorization: Bearer YOUR_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "model": "opencode/big-pickle",
 "input": "查询东京天气",
 "stream": true,
 "tools": [
 {
 "type": "function",
 "function": {
 "name": "weather_lookup",
 "description": "Look up weather by city",
 "parameters": {
 "type": "object",
 "properties": {
 "city": {"type": "string"},
 "unit": {"type": "string"}
 },
 "required": ["city"]
 }
 }
 }
 ]
 }'

📦 部署方式

模式 说明 适用场景
🐳 Docker 完整栈,自动启动 OpenCode 后端 生产环境,最简配置
💻 独立 Node 手动管理后端 开发、自定义集成

⚙️ 配置

快速参考

环境变量 默认值 说明
PORT / OPENCODE_PROXY_PORT 10000 代理服务端口
OPENCODE_SERVER_PORT 10001 OpenCode 后端服务端口
API_KEY - Bearer Token 认证密钥
BIND_HOST 0.0.0.0 绑定地址
DISABLE_TOOLS true 禁用 OpenCode 内置工具
OPENCODE_EXTERNAL_TOOLS_MODE proxy-bridge 外部工具桥接模式;当前仅支持 proxy-bridge
OPENCODE_EXTERNAL_TOOLS_CONFLICT_POLICY namespace 外部工具与 OpenCode 内置工具的冲突隔离策略;当前仅支持 namespace
OPENCODE_INTERNAL_WEB_FETCH_ENABLED false 兼容旧开关;当未显式配置 allowlist 时,启用后默认放行 web_fetch
OPENCODE_INTERNAL_ALLOWED_TOOLS (none) 当请求未传入 tools 时,允许使用的 OpenCode 内置工具列表,逗号分隔
OPENCODE_INTERNAL_TOOL_METRICS_ENABLED true 输出 internal allowlist 模式的调试/指标日志
OPENCODE_TOOL_DISCOVERY_FIXTURE (none) 集成测试/本地调试用的后端工具 ID 固定列表,逗号分隔
OPENCODE_HEALTH_DETAILS_ENABLED true 控制 /health/details 是否暴露
OPENCODE_HEALTH_DETAILS_REQUIRE_AUTH true 控制 /health/details 是否要求 Bearer 认证
OPENCODE_METRICS_ENABLED false 控制 /metrics 是否暴露
OPENCODE_METRICS_REQUIRE_AUTH true 控制 /metrics 是否要求 Bearer 认证
USE_ISOLATED_HOME false 使用隔离的 OpenCode 配置目录
OPENCODE_PROXY_PROMPT_MODE standard 提示词处理模式
OPENCODE_PROXY_OMIT_SYSTEM_PROMPT false 忽略传入的 system prompt
OPENCODE_PROXY_AUTO_CLEANUP_CONVERSATIONS false 自动清理会话存储
OPENCODE_PROXY_CLEANUP_INTERVAL_MS 43200000 清理间隔 (毫秒)
OPENCODE_PROXY_CLEANUP_MAX_AGE_MS 86400000 最大存储时间 (毫秒)
OPENCODE_PROXY_REQUEST_TIMEOUT_MS 180000 请求超时时间 (毫秒)
OPENCODE_SERVER_URL http://127.0.0.1:10001 OpenCode 后端地址
OPENCODE_SERVER_PASSWORD - OpenCode 后端密码
OPENCODE_PATH opencode OpenCode 可执行文件路径
OPENCODE_ZEN_API_KEY - Zen API Key 透传
DEBUG / OPENCODE_PROXY_DEBUG false 调试日志

📄 完整配置参考: 配置详解

推荐生产配置

API_KEY=your-secret-key
OPENCODE_SERVER_PASSWORD=your-password
DISABLE_TOOLS=true
OPENCODE_EXTERNAL_TOOLS_MODE=proxy-bridge
OPENCODE_EXTERNAL_TOOLS_CONFLICT_POLICY=namespace
OPENCODE_INTERNAL_ALLOWED_TOOLS=web_fetch
OPENCODE_INTERNAL_TOOL_METRICS_ENABLED=true
OPENCODE_TOOL_DISCOVERY_FIXTURE=
OPENCODE_HEALTH_DETAILS_ENABLED=true
OPENCODE_HEALTH_DETAILS_REQUIRE_AUTH=true
OPENCODE_METRICS_ENABLED=false
OPENCODE_METRICS_REQUIRE_AUTH=true
OPENCODE_PROXY_PROMPT_MODE=plugin-inject
OPENCODE_PROXY_OMIT_SYSTEM_PROMPT=true
OPENCODE_PROXY_AUTO_CLEANUP_CONVERSATIONS=true

外部工具桥接说明

  • 外部客户端传入的 tools 按 OpenAI 标准格式传入,代理自动桥接处理,客户端无需任何适配代码。
  • 代理会把外部工具虚拟化后交给模型使用,并把模型输出转换为标准 OpenAI tool_calls 格式返回。
  • 代理内置多层解析容错:支持 <function_calls> 标签、裸 JSON、markdown 代码块、多行格式化、嵌套 arguments。
  • 当模型未正确输出工具调用时,代理会智能判断是否需要重试(auto 模式下检测工具调用痕迹,required 模式下始终重试)。
  • 同名冲突通过命名空间隔离处理,例如客户端的 web_fetch 不会误触发 OpenCode 内置工具。
  • 内部命名空间名(如 external__web_fetch)是代理内部实现细节,不属于公开 API。
  • 模型的推理内容(<think/> 块)不会泄露到客户端响应中。

内置工具 allowlist 说明

  • 当请求 未传入 tools 时,代理会进入 internal allowlist 模式,并只允许 OPENCODE_INTERNAL_ALLOWED_TOOLS 中声明的 OpenCode 内置工具。
  • OPENCODE_INTERNAL_WEB_FETCH_ENABLED=true 仅作为兼容旧配置的快捷方式:当未显式配置 OPENCODE_INTERNAL_ALLOWED_TOOLS 时,会默认把 allowlist 视为 web_fetch
  • 代理会读取后端工具列表,并通过精确匹配或 .<tool> / /<tool> 后缀匹配解析最终可用工具。
  • 如果配置的 allowlist 在后端工具列表中一个也匹配不到,代理会自动回退到"全部内置工具禁用"的安全模式。
  • OPENCODE_INTERNAL_TOOL_METRICS_ENABLED=true 时,代理会输出 internal allowlist 模式的调试/指标日志,包括模式选择、后端工具发现、allowlist 命中结果和降级原因,但不会记录工具返回内容。
  • OPENCODE_TOOL_DISCOVERY_FIXTURE 可用于集成测试或本地调试,绕过真实 client.tool.ids() 返回固定工具 ID 列表。
  • 一旦客户端显式传入 tools,请求立即回到现有外部工具桥接逻辑,OpenCode 内置工具继续保持禁用。

结构化诊断与 Prometheus 指标

  • /health 始终保持为轻量健康检查接口。
  • /health/details 返回结构化 JSON 诊断数据,可通过 OPENCODE_HEALTH_DETAILS_ENABLED 控制是否暴露,并通过 OPENCODE_HEALTH_DETAILS_REQUIRE_AUTH 控制是否要求 Bearer 认证。
  • /metrics 返回 Prometheus 文本格式指标,可通过 OPENCODE_METRICS_ENABLED 控制是否暴露,并通过 OPENCODE_METRICS_REQUIRE_AUTH 控制是否要求 Bearer 认证。
  • /metrics 目前暴露 internal tool mode、tool discovery failures、fallback count 和 tool-id cache 数量等指标。

🔌 API 参考

端点

方法 路径 说明
GET /health 健康检查
GET /health/details 结构化诊断接口(可配置开关/鉴权)
GET /metrics Prometheus 指标接口(可配置开关/鉴权)
GET /v1/models 获取可用模型列表
POST /v1/chat/completions Chat Completions API
POST /v1/responses Responses API

模型名称格式

  • 直接使用: opencode/big-pickle
  • 带别名: gpt5-nano (自动解析为 gpt-5-nano)
  • 带前缀: opencode/gpt5-nano

📖 详见 API 参考文档


🔧 故障排查

请求卡住但 /v1/models 正常

USE_ISOLATED_HOME=false # 让 OpenCode 复用本地登录态

模型找不到

  • 查看可用模型: curl http://127.0.0.1:10000/v1/models
  • 确认模型 ID 完全匹配

工具调用不生效

  • 确认 DISABLE_TOOLS=trueOPENCODE_EXTERNAL_TOOLS_MODE=proxy-bridge 已配置
  • 确认传入的 tools 符合 OpenAI 标准格式
  • 开启调试: OPENCODE_PROXY_DEBUG=true,查看代理日志中的工具解析情况
  • 部分免费模型对工具调用的支持可能不稳定,可尝试 tool_choice: "required" 强制调用

没有推理输出

  • 使用 stream: true 的 Responses API
  • 发送 reasoning.effortreasoning_effort

📖 完整指南: 故障排查


🔨 开发

# 运行测试
npm test -- --runInBand
# Docker 开发
docker compose up -d --build

📄 许可证

MIT · 详见 LICENSE


🙏 致谢

感谢以下开源项目:

About

将运行在本地的 OpenCode 转换为 OpenAI 兼容 API ,以在任何 OpenAI 客户端中使用免费模型。

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors

Languages

  • JavaScript 95.2%
  • Shell 4.2%
  • Dockerfile 0.6%

AltStyle によって変換されたページ (->オリジナル) /