opencode-provider-switch/README.md

11 KiB
Raw Blame History

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 必须至少有一个 enabled target
  • olpx alias bind 在 alias 不存在时会自动创建一个 enabled alias

3. 先做一次静态检查

olpx doctor

olpx doctor 只做静态校验,不会真的请求上游,不会消耗额度。

它会检查:

  • 本地 olpx 配置能不能正常加载
  • alias 是否引用了不存在的 provider
  • enabled alias 是否至少有一个 enabled 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 Keyolpx-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 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"
    }
  ],
  "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 没有 enabled target
  • 上游返回 400
  • 上游返回 401
  • 上游返回 403
  • 上游返回 404
  • 响应已经开始向客户端写出后才出错

重点是:

  • 只有在“还没向下游写出任何字节”之前,才允许切换
  • 一旦开始向客户端输出流,当前上游就锁定了
  • 不支持中途把一半流接到另一个 provider 上继续输出

调试响应头

每次成功代理或透传上游错误时,响应里都会附带这些头:

  • X-OLPX-Alias
  • X-OLPX-Provider
  • X-OLPX-Remote-Model
  • X-OLPX-Attempt
  • X-OLPX-Failover-Count

你可以用它们确认:

  • 本次请求命中了哪个 alias
  • 实际走了哪个 provider
  • 实际转发成了哪个上游 model
  • 这是第几次尝试
  • 前面已经失败切换过几次

常见问题

为什么 opencode models 里看不到 olpx/<alias>

先检查这几件事:

  1. 你是否执行过 olpx opencode sync
  2. 你的 alias 是否是 enabled 状态
  3. alias 是否至少绑定了一个 enabled target
  4. OpenCode 当前实际使用的配置文件,是否就是 olpx opencode sync 写入的那个文件
  5. 执行一次 olpx doctor,看输出里的 opencode config target

为什么 olpx doctor 报 alias 没有 enabled target

因为当前实现要求:只要 alias 是 enabled就必须至少有一个 enabled target。

你可以:

  • 给它绑定 target
  • 或者把这个 alias 改成 disabled 后再保存

删除 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