feat: add OpenCode Go and OpenCode Zen provider support#3211
Conversation
Add built-in alias and documentation for both OpenCode subscription plans: OpenCode Go (opencode-go): - Low-cost subscription for open-source coding models - OpenAI-compatible endpoint at https://opencode.ai/zen/go/v1 - Anthropic-compatible models via custom provider config OpenCode Zen (opencode-zen): - Pay-per-use curated gateway for premium + open-source models - OpenAI-compatible endpoint at https://opencode.ai/zen/v1 - Covers GPT-5.x, Claude, Gemini, DeepSeek, GLM, Kimi, Grok - Includes 7 free models - Anthropic and Google models via custom provider config Both share the OPENCODE_API_KEY environment variable. Technical changes: - pkg/model/provider/aliases.go: register opencode-go and opencode-zen - pkg/config/auto.go: add default models for both providers - cmd/root/models.go: add live fetch from provider /v1/models endpoint when models.dev has no entry - pkg/config/examples_test.go: skip opencode-zen in models.dev validation - docs/: full provider docs pages, nav entry, overview update - examples/: usage examples for both providers - .gitignore: add graphify-out/
Review summary — requesting changesThe provider aliases look good, but the new live model-fetching in Blocking
Non-blocking Positives: aliases follow existing conventions, default-models fallback is the right behavior, response bodies closed correctly, frozen config versions untouched. |
- cmd/root/models.go: use &http.Client{Timeout: 30s, Transport: remote.NewTransport}
instead of http.DefaultClient in fetchProviderModels. Extract fetchModelsFromURL
for testability. Only trigger live model fetch when --provider is explicitly set
(models list --all remains side-effect-free).
- cmd/root/models_test.go: add 10 unit tests for fetchModelsFromURL covering
success, non-200, malformed JSON, empty body, empty data array, duplicate IDs,
empty IDs, context cancellation, and embedding models.
- pkg/config/examples_test.go: centralize providers absent from models.dev in
modelsDevAbsentProviders map instead of hardcoding per-line.
- pkg/model/provider/openai/client.go: add opencode-go and opencode-zen to
autoSelectsResponsesAPI so GPT models on Zen correctly route to Responses API.
- .gitignore: revert unrelated graphify-out/ change (will land separately).
Addressed all review pointsThanks @dgageot for the thorough review! All points addressed: 1.
|
|
/review |
|
👋 Heads up: The |
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟡 NEEDS ATTENTION
2 medium-severity findings introduced by this PR — both require attention before merging.
| func autoSelectsResponsesAPI(provider string) bool { | ||
| switch provider { | ||
| case "openai", "github-copilot": | ||
| case "openai", "github-copilot", "opencode-go", "opencode-zen": |
There was a problem hiding this comment.
[MEDIUM] opencode providers added to autoSelectsResponsesAPI but likely don't support the OpenAI Responses API
autoSelectsResponsesAPI now returns true for opencode-go and opencode-zen. This means that if a user configures one of these providers with a model whose name matches modelinfo.SupportsResponsesAPI (e.g. gpt-5, o3, gpt-4.1-mini), the client will route the request to the OpenAI Responses API endpoint (/responses) instead of /chat/completions.
OpenCode is a third-party proxy, not a direct OpenAI service. The Responses API (/v1/responses) is an OpenAI-specific surface that third-party proxies almost never implement. Sending a request there would result in a confusing 404 or 501 error with no fallback.
The comment above autoSelectsResponsesAPI makes this risk explicit: it was added specifically for GitHub Copilot, which requires the Responses API for newer OpenAI models and explicitly rejects them on /chat/completions. OpenCode doesn't have that requirement — the correct path for OpenCode is always /chat/completions.
Suggested fix: Remove opencode-go and opencode-zen from autoSelectsResponsesAPI unless OpenCode has confirmed Responses API support:
case "openai", "github-copilot":
return trueThere was a problem hiding this comment.
[RESOLVED] opencode-go removed, opencode-zen kept with documentation evidence
Addressed in commit 0b1408d:
-
opencode-go removed — correct observation: Go only has open-source models, none match
SupportsResponsesAPI(gpt-4.1+, gpt-5+, codex+, o-series). Always routes to/chat/completions. -
opencode-zen kept — Zen explicitly documents the
/v1/responsesendpoint. See:- Responses API documentation: https://opencode.ai/docs/zen/responses
- Models supporting Responses API: https://opencode.ai/docs/zen/models (gpt-5.x, gpt-4.1, o-series, codex listed)
Users calling GPT models through Zen without this flag would get a 400 error from Zen's
/chat/completions— identical to the GitHub Copilot case the flag was designed for.
| "dmr": "ai/qwen3:latest", | ||
| "mistral": "mistral-small-latest", | ||
| "amazon-bedrock": "global.anthropic.claude-sonnet-4-5-20250929-v1:0", | ||
| "opencode-go": "deepseek-v4-flash", |
There was a problem hiding this comment.
[MEDIUM] opencode-go and opencode-zen missing from cloudProviders — OPENCODE_API_KEY is never detected
DefaultModels includes entries for these two providers, but neither is listed in cloudProviders. As a result:
AvailableProvidersnever includes them — even whenOPENCODE_API_KEYis set,availableProviders["opencode-go"]andavailableProviders["opencode-zen"]are alwaysfalse.AutoModelConfignever auto-selects them — a user with onlyOPENCODE_API_KEYset will get no model auto-selected (falling through to the DMR fallback).docker agent modelsnever shows them — without--allor--provider opencode-go, the default models fromDefaultModelsare filtered out becauseavailableProviders[prov]is false.
This means the PR's user-facing workflow (export OPENCODE_API_KEY="…") works only if the user also explicitly sets --model opencode-go/… or uses --all. The key being set but having no effect is a confusing user experience.
Suggested fix: Add both providers to cloudProviders:
{"opencode-go", []string{"OPENCODE_API_KEY"}, "OPENCODE_API_KEY"},
{"opencode-zen", []string{"OPENCODE_API_KEY"}, "OPENCODE_API_KEY"},There was a problem hiding this comment.
[RESOLVED] Both providers added to cloudProviders in commit 0b1408d
- Added
opencode-zenandopencode-gotocloudProvidersinpkg/config/auto.go - Both use
OPENCODE_API_KEYenv var (single key for both services) opencode-zenlisted first (higher priority) so it auto-selects when onlyOPENCODE_API_KEYis set- Tests updated to verify:
DefaultModelsincludes both providersAvailableProvidersreturns both whenOPENCODE_API_KEYis setopencode-zenwins auto-selection overopencode-go(priority ordering)
…_API_KEY detection - Remove opencode-go from autoSelectsResponsesAPI (Go has no GPT models) - Keep opencode-zen in autoSelectsResponsesAPI (Zen documents /v1/responses) - Add both providers to cloudProviders so OPENCODE_API_KEY is auto-detected - opencode-zen has higher priority than opencode-go in cloudProviders - Update tests for DefaultModels, integration, and precedence ordering
Summary
Add built-in alias support and full documentation for OpenCode Go and OpenCode Zen — the two subscription plans offered by OpenCode.
OpenCode Go (
opencode-go)https://opencode.ai/zen/go/v1OpenCode Zen (
opencode-zen)https://opencode.ai/zen/v1Both share the
OPENCODE_API_KEYenvironment variable — the same API key works for both services.Technical Changes
pkg/model/provider/aliases.goopencode-goandopencode-zenaliasespkg/config/auto.gocmd/root/models.go/v1/modelsendpoint when models.dev has no entrypkg/config/examples_test.godocs/providers/opencode-go/index.mddocs/providers/opencode-zen/index.mddocs/providers/overview/index.mddocs/_data/nav.ymlexamples/opencode-go.yamlexamples/opencode-go-practical.yamlexamples/opencode-zen.yaml.gitignoregraphify-out/Usage