Go to file
apale7 5c4f60f2b7 feat(desktop): finish Windows GUI integration
Bring the Wails desktop shell to feature parity with the CLI for provider and alias management while keeping the browser fallback working. Wire tray, notifications, autostart, and GUI warnings so desktop flows behave predictably.
2026-04-19 01:02:16 +08:00
.opencode 产出prd 2026-04-17 00:20:07 +08:00
.trellis feat(desktop): finish Windows GUI integration 2026-04-19 01:02:16 +08:00
cmd feat(desktop): finish Windows GUI integration 2026-04-19 01:02:16 +08:00
examples refactor(cli): rename tool to ocswitch 2026-04-17 21:43:21 +08:00
frontend feat(desktop): finish Windows GUI integration 2026-04-19 01:02:16 +08:00
internal feat(desktop): finish Windows GUI integration 2026-04-19 01:02:16 +08:00
.gitignore feat(desktop): finish Windows GUI integration 2026-04-19 01:02:16 +08:00
AGENTS.md Subagent prompt 2026-04-17 11:23:42 +08:00
go.mod feat(desktop): finish Windows GUI integration 2026-04-19 01:02:16 +08:00
go.sum feat(desktop): finish Windows GUI integration 2026-04-19 01:02:16 +08:00
main_wails.go feat(desktop): finish Windows GUI integration 2026-04-19 01:02:16 +08:00
README_EN.md fix: harden provider discovery flow 2026-04-18 15:28:35 +08:00
README.md fix: harden provider discovery flow 2026-04-18 15:28:35 +08:00
wails.json feat(desktop): finish Windows GUI integration 2026-04-19 01:02:16 +08:00

opencode-provider-switch (ocswitch)

A tiny local proxy for OpenCode that gives you one stable model alias routed to multiple upstream providers with deterministic failover.

  • Expose one custom provider ocswitch to OpenCode.
  • Configure logical aliases (ocswitch/gpt-5.4, etc.).
  • Each alias has an ordered list of upstream provider/model targets.
  • Providers can be disabled without mutating alias target state.
  • When the primary upstream returns 5xx/429/connect error before any stream bytes are flushed, ocswitch transparently retries the next target.
  • Once a stream has started, the upstream is locked for the rest of that request — no mid-stream splicing.

Protocol: OpenAI Responses (POST /v1/responses) only. Streaming supported.

Install

go build -o ocswitch ./cmd/ocswitch

Quick start

# 1. add upstream providers (models are discovered from /v1/models by default; warnings do not block saving)
ocswitch provider add --id su8   --base-url https://cn2.su8.codes/v1 --api-key sk-...
ocswitch provider add --id codex --base-url https://api-vip.codex-for.me/v1 --api-key sk-...

# 2. create alias and bind targets in priority order (preferred Provider/Model form)
ocswitch alias add --name gpt-5.4
ocswitch alias bind --alias gpt-5.4 --model su8/gpt-5.4
ocswitch alias bind --alias gpt-5.4 --model codex/GPT-5.4

# 3. push alias exposure into OpenCode global config
ocswitch opencode sync

# optional: temporarily disable one provider without editing alias targets
ocswitch provider disable su8

# 4. run the proxy
ocswitch serve

Inside OpenCode you can now pick ocswitch/gpt-5.4.

Import providers from an existing OpenCode config

ocswitch provider import-opencode             # reads global OpenCode config
ocswitch provider import-opencode --from ./examples/opencode.jsonc

The default import/sync target is the global user config only. It does not follow OPENCODE_CONFIG_DIR; use --from or --target when you want a different file.

Only @ai-sdk/openai custom providers with a baseURL are imported. An empty apiKey is allowed and kept as-is so you can complete credentials later. Imported provider model lists are preserved when the source config already declares models, and provider add will otherwise refresh them from /v1/models by default. Imported lists are kept for migration context, while hard typo validation only uses catalogs actively discovered from /v1/models. If connection details change but discovery is skipped, fails, or returns an empty list, any old catalog is retained only as untrusted metadata and no longer used for strict validation.

Validate before serving

ocswitch doctor

Runs structural checks only — never issues real upstream requests.

Enabled aliases must have at least one routable target. A target is considered routable only when:

  • the alias itself is enabled
  • the target itself is enabled
  • the referenced provider exists
  • the referenced provider is not disabled

ocswitch opencode sync and /v1/models use the same routable-alias view, so OpenCode does not see aliases that the proxy would immediately reject.

Provider state

ocswitch provider disable <id>
ocswitch provider enable <id>

Disabling a provider only removes it from routing/failover consideration. It does not rewrite alias target enabled flags in config, which avoids odd interactions when the same provider is shared across multiple aliases.

CLI reference

For exact command behavior, defaults, write scope, and side effects, prefer the matching --help page. This README is the quick-start narrative, while CLI help is the authoritative local execution contract.

  • ocswitch serve — run the proxy
  • ocswitch doctor — validate config
  • ocswitch provider {add,list,enable,disable,remove,import-opencode}
  • ocswitch alias {add,list,bind,unbind,remove}
  • ocswitch opencode sync [--target FILE] [--set-model ALIAS] [--set-small-model ALIAS] [--dry-run]

Preferred bind form: ocswitch alias bind --alias <alias> --model <provider>/<model> when --provider is omitted. The legacy --provider <id> --model <model> form is still accepted as a fallback, including models whose names already contain /. The same combined form also works for alias unbind.

To clear a previously saved upstream API key, pass --api-key "" explicitly on provider add. To clear previously saved extra provider headers, pass --clear-headers on provider add.

Global flag: --config PATH (default $OCSWITCH_CONFIG, else $XDG_CONFIG_HOME/ocswitch/config.json, else ~/.config/ocswitch/config.json).

Debug headers

Responses include these debug headers once a concrete upstream attempt is being returned to the client:

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

Scope

Out of MVP: Anthropic native, multi-protocol routing, dashboard, billing, latency-based routing, and full OpenCode config takeover. See .trellis/tasks/archive/2026-04/04-17-04-17-ops-mvp-design-review/prd.md for the authoritative design notes.