11 KiB
opencode-provider-switch (olpx)
English README: README_EN.md
olpx 是 OpenCode LocalProxy CLI,给 OpenCode 使用的本地代理。
它解决的问题很简单:
- 你在 OpenCode 里只使用一个稳定的模型名,例如
olpx/gpt-5.4 olpx在本地把这个别名映射到多个上游provider/model- 按你配置的顺序依次尝试上游
- 如果主上游在响应开始前失败,自动切到下一个上游
当前实现只支持 OpenAI Responses 协议,也就是 POST /v1/responses,并且支持流式响应。
适合什么场景
- 你有多个 OpenAI 兼容上游
- 你不想在 OpenCode 里频繁切换 provider
- 你希望用一个固定别名承接多个备用上游
- 你希望失败切换行为是确定的、可预期的
当前能力
- 本地维护
olpx配置文件:上游 provider、alias、监听地址 - 支持手动添加 provider
- 支持从 OpenCode 配置导入
@ai-sdk/openai自定义 provider - 支持创建 alias,并按顺序绑定多个上游 target
- 支持把 alias 同步到 OpenCode 的
provider.olpx.models - 支持本地代理
POST /v1/responses - 支持流式透传
- 支持首字节前失败切换
- 返回调试响应头,便于确认这次请求实际落到了哪个上游
不支持的内容
- Anthropic 原生协议
- 多协议路由
- 自动按延迟、价格、提示词类型选路
- 中途流式拼接切换
- SQLite、管理后台、计费统计
- 完整接管 OpenCode 所有配置层
- 从
auth.json自动导入 provider 定义
安装
go build -o olpx ./cmd/olpx
如果你只想临时运行,也可以直接:
go run ./cmd/olpx --help
5 分钟快速上手
1. 添加上游 provider
olpx 要求上游是 OpenAI 兼容接口,并且 --base-url 需要带上 /v1。
olpx provider add --id su8 --base-url https://cn2.su8.codes/v1 --api-key sk-xxx
olpx provider add --id codex --base-url https://api-vip.codex-for.me/v1 --api-key sk-yyy
如果某个上游还需要额外请求头,可以重复传 --header:
olpx provider add \
--id relay \
--base-url https://example.com/v1 \
--api-key sk-zzz \
--header "X-Custom-Token=abc" \
--header "X-Workspace=my-team"
查看当前 provider:
olpx provider list
2. 创建 alias,并绑定多个上游 target
下面这个例子表示:当你使用 olpx/gpt-5.4 时,优先走 su8/gpt-5.4,失败后再走 codex/GPT-5.4。
olpx alias add --name gpt-5.4 --display-name "GPT 5.4"
olpx alias bind --alias gpt-5.4 --provider su8 --model gpt-5.4
olpx alias bind --alias gpt-5.4 --provider codex --model GPT-5.4
查看当前 alias:
olpx alias list
注意:
- target 的顺序就是失败切换顺序
- enabled alias 必须至少有一个可路由 target
olpx alias bind在 alias 不存在时会自动创建一个 enabled alias
3. 先做一次静态检查
olpx doctor
olpx doctor 只做静态校验,不会真的请求上游,不会消耗额度。
它会检查:
- 本地
olpx配置能不能正常加载 - alias 是否引用了不存在的 provider
- enabled alias 是否至少有一个可路由 target
- 本地代理监听地址是否合理
- 默认会同步到哪个 OpenCode 配置文件
4. 把 alias 同步到 OpenCode
olpx opencode sync
这个命令会做一件事:把当前可路由的 alias 列表同步进 OpenCode 的 provider.olpx.models。
默认行为:
- 优先复用全局 OpenCode 配置文件:
opencode.jsonc>opencode.json>config.json - 如果都不存在,就创建
~/.config/opencode/opencode.jsonc - 默认目标明确只看全局用户配置目录,不跟随
OPENCODE_CONFIG_DIR - 只更新
provider.olpx - 不会修改顶层
model - 不会修改顶层
small_model
如果你希望顺手把默认模型也切到 olpx,需要显式指定:
olpx opencode sync --set-model olpx/gpt-5.4
如果你还有小模型 alias,也可以这样:
olpx opencode sync \
--set-model olpx/gpt-5.4 \
--set-small-model olpx/gpt-5.4-mini
先预览不写入:
olpx opencode sync --dry-run
写到指定 OpenCode 配置文件:
olpx opencode sync --target /path/to/opencode.jsonc
5. 启动本地代理
olpx serve
默认监听地址:
127.0.0.1:9982- 本地 API Key:
olpx-local
启动后,本地代理地址是:
http://127.0.0.1:9982/v1
6. 在 OpenCode 里使用
完成 olpx opencode sync 后,你应该能在 OpenCode 里看到 olpx/<alias>。
例如:
olpx/gpt-5.4
如果你执行了:
olpx opencode sync --set-model olpx/gpt-5.4
那么 OpenCode 默认模型也会直接切到这个 alias。
直接验证本地代理
如果你想先不走 OpenCode,直接验证 olpx 是否能正常代理,可以自己发一个请求:
curl -sN -X POST http://127.0.0.1:9982/v1/responses \
-H "Authorization: Bearer olpx-local" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.4","stream":true,"input":"hello"}'
注意这里请求体里的 model 是 alias 本身,例如 gpt-5.4,不是 olpx/gpt-5.4。
因为 olpx/gpt-5.4 是 OpenCode 侧的模型选择写法;真正发到本地 provider 的请求里,模型名会是 alias 自身。
从现有 OpenCode 配置导入 provider
如果你原来已经在 OpenCode 里配置过一些自定义 provider,可以直接导入:
olpx provider import-opencode
或者指定导入源:
olpx provider import-opencode --from ./examples/opencode.jsonc
支持范围只有这一类:
npm: @ai-sdk/openai- 有
options.baseURL - 有
options.apiKey
注意:
- 这不是完整迁移工具
- 默认导入源也只看全局用户配置目录,不跟随
OPENCODE_CONFIG_DIR - 如果你要导入别的 OpenCode 配置文件,请显式传
--from - 当前只导入 provider 的基本连接信息
- 如果你的旧配置依赖额外自定义 header,需要导入后自己用
olpx provider add --header ...补齐 olpx自己不会被反向导入
覆盖已存在的 provider:
olpx provider import-opencode --overwrite
常用命令
provider
添加或更新 provider:
olpx provider add --id <id> --base-url <url-with-/v1> --api-key <key>
查看 provider:
olpx provider list
禁用 provider:
olpx provider disable <id>
重新启用 provider:
olpx provider enable <id>
删除 provider:
olpx provider remove <id>
注意:删除 provider 不会自动帮你清理 alias 里的引用。引用还在的话,olpx doctor 会报错。
alias
创建或更新 alias:
olpx alias add --name <alias>
给 alias 追加一个 target:
olpx alias bind --alias <alias> --provider <provider-id> --model <upstream-model>
解绑 target:
olpx alias unbind --alias <alias> --provider <provider-id> --model <upstream-model>
查看 alias:
olpx alias list
删除 alias:
olpx alias remove <alias>
其他
静态检查:
olpx doctor
启动代理:
olpx serve
同步到 OpenCode:
olpx opencode sync
全局帮助:
olpx --help
olpx provider --help
olpx alias --help
olpx opencode sync --help
配置文件说明
本地 olpx 配置文件默认路径:
- 如果设置了
OLPX_CONFIG,优先使用它 - 否则使用
$XDG_CONFIG_HOME/olpx/config.json - 再否则使用
~/.config/olpx/config.json
也可以对每个命令显式指定:
olpx --config /path/to/config.json doctor
一个最小配置示例:
{
"server": {
"host": "127.0.0.1",
"port": 9982,
"api_key": "olpx-local"
},
"providers": [
{
"id": "su8",
"name": "SU8",
"base_url": "https://cn2.su8.codes/v1",
"api_key": "sk-xxx"
},
{
"id": "codex",
"name": "Codex",
"base_url": "https://api-vip.codex-for.me/v1",
"api_key": "sk-yyy",
"disabled": true
}
],
"aliases": [
{
"alias": "gpt-5.4",
"display_name": "GPT 5.4",
"enabled": true,
"targets": [
{
"provider": "su8",
"model": "gpt-5.4",
"enabled": true
},
{
"provider": "codex",
"model": "GPT-5.4",
"enabled": true
}
]
}
]
}
失败切换规则
olpx 的切换规则很保守,也很容易理解。
会切换到下一个 target 的情况:
- 连接失败
- DNS / 网络错误
- 上游在返回首字节前超时或断开
- 上游返回
429 - 上游返回
5xx
不会切换的情况:
- alias 不存在
- alias 被禁用
- alias 没有可用 target
- 上游返回
400 - 上游返回
401 - 上游返回
403 - 上游返回
404 - 响应已经开始向客户端写出后才出错
重点是:
- 只有在“还没向下游写出任何字节”之前,才允许切换
- 一旦开始向客户端输出流,当前上游就锁定了
- 不支持中途把一半流接到另一个 provider 上继续输出
调试响应头
每次成功代理或透传上游错误时,响应里都会附带这些头:
X-OLPX-AliasX-OLPX-ProviderX-OLPX-Remote-ModelX-OLPX-AttemptX-OLPX-Failover-Count
你可以用它们确认:
- 本次请求命中了哪个 alias
- 实际走了哪个 provider
- 实际转发成了哪个上游 model
- 这是第几次尝试
- 前面已经失败切换过几次
常见问题
为什么 opencode models 里看不到 olpx/<alias>?
先检查这几件事:
- 你是否执行过
olpx opencode sync - 你的 alias 是否是 enabled 状态
- alias 是否至少绑定了一个可路由 target
- alias 绑定的 provider 是否都被禁用了
- OpenCode 当前实际使用的配置文件,是否就是
olpx opencode sync写入的那个文件 - 执行一次
olpx doctor,看输出里的opencode config target
为什么 olpx doctor 报 alias 没有可用 target?
因为当前实现要求:只要 alias 是 enabled,就必须至少有一个可路由的 target。
可路由的意思是同时满足:
- target 自己是 enabled
- target 引用的 provider 存在且没有被禁用
你可以:
- 给它绑定 target
- 重新启用被禁用的 provider
- 或者把这个 alias 改成 disabled 后再保存
为什么要禁用 provider,而不是把 alias target 也改成 disabled?
因为 provider 可能被多个 alias 复用。
olpx provider disable 只会让路由层在 failover 时自动跳过这个 provider,不会改写 alias 里的 target 状态,这样重新启用 provider 时不会和 alias 上原有的启用关系打架。
删除 provider 后为什么还有报错?
因为 alias 里的 target 还是旧引用。需要继续执行:
olpx alias unbind --alias <alias> --provider <provider-id> --model <model>
本地代理鉴权是什么?
默认是静态 key:
olpx-local
OpenCode 在 provider.olpx.options.apiKey 里会使用这个值。直接手工请求本地代理时,也要带上这个 key。
安全说明
- 默认只监听
127.0.0.1 - 上游凭据保存在本地
olpx配置文件中 - 本项目当前没有做多用户或远程网络安全保证
所以请把本地配置文件当成敏感文件处理。
英文版 README
原英文版文档已保存在:
README_EN.md