Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions docs/src/content/docs/providers/opencode-go.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ description: Configure an OpenCode Go API key, model routing, streaming, tools,

OpenCode Go uses the API at `https://opencode.ai/zen/go/v1`. Its catalog spans
OpenAI-compatible chat completions, Anthropic-compatible messages, and OpenAI
Responses; the proxy selects the wire protocol for each registered model. The
registered mapping follows the [official OpenCode Go endpoint table](https://opencode.ai/docs/go/#endpoints).
Responses; the proxy selects the wire protocol for each registered model. Each
mapping comes from the [official OpenCode Go endpoint table](https://opencode.ai/docs/go/#endpoints)
or direct protocol verification against the API.

## Account and authentication

Expand All @@ -23,10 +24,9 @@ implement an OpenCode login flow.

## Models

Run `claude-code-proxy models` for the statically registered catalog based on
OpenCode's documented endpoint table. Every registered model has a
provider-qualified form. Bare IDs are also accepted when they do not belong to
another provider:
Run `claude-code-proxy models` for the statically registered catalog. Every
registered model has a provider-qualified form. Bare IDs are also accepted when
they do not belong to another provider:

```sh
ANTHROPIC_MODEL=opencode-go/glm-5.2 \
Expand Down Expand Up @@ -57,6 +57,6 @@ OpenCode Go.
- `CCP_OPENCODE_BASE_URL` or `opencode.baseUrl` changes the API base URL.

OpenCode Go may expose additional model IDs through `/models`, but the proxy
registers only models whose wire protocol is documented. Unknown IDs are
rejected locally. Access or usage-limit errors for registered models are
surfaced from OpenCode.
registers only models whose wire protocol is documented or has been verified
against the live API. Unknown IDs are rejected locally. Access or usage-limit
errors for registered models are surfaced from OpenCode.
45 changes: 43 additions & 2 deletions src/providers/opencode/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ pub const MODELS: &[ModelSpec] = &[
id: "glm-5.1",
endpoint: EndpointKind::ChatCompletions,
},
ModelSpec {
id: "glm-5",
endpoint: EndpointKind::ChatCompletions,
},
ModelSpec {
id: "kimi-k3",
endpoint: EndpointKind::ChatCompletions,
Expand All @@ -42,6 +46,10 @@ pub const MODELS: &[ModelSpec] = &[
id: "kimi-k2.6",
endpoint: EndpointKind::ChatCompletions,
},
ModelSpec {
id: "kimi-k2.5",
endpoint: EndpointKind::ChatCompletions,
},
ModelSpec {
id: "deepseek-v4-pro",
endpoint: EndpointKind::ChatCompletions,
Expand Down Expand Up @@ -70,6 +78,10 @@ pub const MODELS: &[ModelSpec] = &[
id: "minimax-m2.5",
endpoint: EndpointKind::Messages,
},
ModelSpec {
id: "qwen3.8-max",
endpoint: EndpointKind::Messages,
},
ModelSpec {
id: "qwen3.7-max",
endpoint: EndpointKind::Messages,
Expand All @@ -82,6 +94,10 @@ pub const MODELS: &[ModelSpec] = &[
id: "qwen3.6-plus",
endpoint: EndpointKind::Messages,
},
ModelSpec {
id: "qwen3.5-plus",
endpoint: EndpointKind::Messages,
},
ModelSpec {
id: "hy3",
endpoint: EndpointKind::ChatCompletions,
Expand Down Expand Up @@ -126,11 +142,36 @@ mod tests {
.iter()
.filter(|model| model.endpoint == EndpointKind::Responses)
.count();
assert_eq!(chat, 11);
assert_eq!(messages, 6);
assert_eq!(chat, 13);
assert_eq!(messages, 8);
assert_eq!(responses, 1);
}

#[test]
fn refreshed_models_resolve_and_are_advertised() {
let advertised = advertised_models();
for (id, endpoint) in [
("glm-5", EndpointKind::ChatCompletions),
("kimi-k2.5", EndpointKind::ChatCompletions),
("qwen3.8-max", EndpointKind::Messages),
("qwen3.5-plus", EndpointKind::Messages),
] {
let qualified = format!("{MODEL_PREFIX}{id}");
assert_eq!(
resolve(id).expect("registered bare model").endpoint,
endpoint
);
assert_eq!(
resolve(&qualified)
.expect("registered provider-qualified model")
.endpoint,
endpoint
);
assert!(advertised.iter().any(|model| model == id));
assert!(advertised.contains(&qualified));
}
}

#[test]
fn canonical_prefix_resolves_and_unknown_models_do_not() {
let spec = resolve("opencode-go/minimax-m3").expect("known model");
Expand Down