fix(opencode_go): authenticate with OPENCODE_API_KEY

OpenCode Zen and Go share OPENCODE_API_KEY and opencode_api_key; Remove OPENCODE_GO_API_KEY and settings field.
This commit is contained in:
Alishahryar1
2026-05-20 21:37:55 -07:00
parent f1f97b16c5
commit 51d5f29ae1
10 changed files with 34 additions and 35 deletions
+1 -5
View File
@@ -18,14 +18,10 @@ KIMI_API_KEY=""
WAFER_API_KEY=""
# OpenCode Zen Config (OpenAI-compatible Chat Completions at opencode.ai/zen/v1)
# OpenCode Zen (opencode.ai/zen/v1) and OpenCode Go (opencode.ai/zen/go/v1) share OPENCODE_API_KEY
OPENCODE_API_KEY=""
# OpenCode Go Config (OpenAI-compatible Chat Completions at opencode.ai/zen/go/v1)
OPENCODE_GO_API_KEY=""
# Z.ai Config (Anthropic-compatible Messages at api.z.ai/api/anthropic)
ZAI_API_KEY=""
+5 -5
View File
@@ -207,7 +207,7 @@ In the Admin UI, keep or update `OLLAMA_BASE_URL`, then set `MODEL` to the same
Get an API key at [opencode.ai/auth](https://opencode.ai/auth).
In the Admin UI, paste it into `OPENCODE_API_KEY`, then set `MODEL` to an OpenCode Zen model slug such as `opencode/gpt-5.3-codex`.
In the Admin UI, paste it into `OPENCODE_API_KEY`, then set `MODEL` to an OpenCode Zen model slug such as `opencode/gpt-5.3-codex`. The same `OPENCODE_API_KEY` powers **OpenCode Go** (below); use `opencode_go/` slugs there.
OpenCode Zen is a curated model gateway that provides access to models from Anthropic, OpenAI, Google, DeepSeek, and more through a single API key and OpenAI-compatible endpoint at `https://opencode.ai/zen/v1`.
@@ -224,15 +224,15 @@ Browse available models at [opencode.ai](https://opencode.ai).
### 10. [OpenCode Go](https://opencode.ai/)
Get an API key at [opencode.ai/auth](https://opencode.ai/auth).
Get an API key at [opencode.ai/auth](https://opencode.ai/auth) (same as OpenCode Zen).
In the Admin UI, paste it into `OPENCODE_GO_API_KEY`, then set `MODEL` to an OpenCode Go model slug such as `opencode_go/gpt-5.3-codex`.
In the Admin UI, use `OPENCODE_API_KEY`, then set `MODEL` to an OpenCode Go model slug such as `opencode_go/minimax-m2.7`.
OpenCode Go is a separate subscription gateway from OpenCode Zen. It uses an OpenAI-compatible endpoint at `https://opencode.ai/zen/go/v1` and its own API key (`OPENCODE_GO_API_KEY`), distinct from `OPENCODE_API_KEY`.
OpenCode Go is a subscription gateway with its own curated catalog and OpenAI-compatible endpoint at `https://opencode.ai/zen/go/v1`. It shares the **same OpenCode API key** as Zen; only the slug prefix (`opencode_go/` vs `opencode/`) and upstream path differ.
Popular examples:
- `opencode_go/gpt-5.3-codex`
- `opencode_go/minimax-m2.7`
Browse available models at [opencode.ai](https://opencode.ai).
+5 -11
View File
@@ -160,21 +160,15 @@ FIELDS: tuple[ConfigFieldSpec, ...] = (
),
ConfigFieldSpec(
"OPENCODE_API_KEY",
"OpenCode Zen API Key",
"OpenCode API Key",
"providers",
"secret",
settings_attr="opencode_api_key",
secret=True,
description="OpenCode Zen curated model gateway at opencode.ai.",
),
ConfigFieldSpec(
"OPENCODE_GO_API_KEY",
"OpenCode Go API Key",
"providers",
"secret",
settings_attr="opencode_go_api_key",
secret=True,
description="OpenCode Go subscription gateway at opencode.ai.",
description=(
"OpenCode Zen curated gateway (opencode.ai/zen/v1) and OpenCode Go subscription "
"gateway (opencode.ai/zen/go/v1); single key from opencode.ai/auth."
),
),
ConfigFieldSpec(
"ZAI_API_KEY",
+2 -2
View File
@@ -141,9 +141,9 @@ PROVIDER_CATALOG: dict[str, ProviderDescriptor] = {
"opencode_go": ProviderDescriptor(
provider_id="opencode_go",
transport_type="openai_chat",
credential_env="OPENCODE_GO_API_KEY",
credential_env="OPENCODE_API_KEY",
credential_url="https://opencode.ai/auth",
credential_attr="opencode_go_api_key",
credential_attr="opencode_api_key",
default_base_url=OPENCODE_GO_DEFAULT_BASE,
proxy_attr="opencode_go_proxy",
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
+2 -4
View File
@@ -119,12 +119,10 @@ class Settings(BaseSettings):
# ==================== Wafer Config ====================
wafer_api_key: str = Field(default="", validation_alias="WAFER_API_KEY")
# ==================== OpenCode Zen Config ====================
# ==================== OpenCode Zen / OpenCode Go ====================
# Same key from opencode.ai/auth; zen uses prefix ``opencode/``, Go uses ``opencode_go/``.
opencode_api_key: str = Field(default="", validation_alias="OPENCODE_API_KEY")
# ==================== OpenCode Go Config ====================
opencode_go_api_key: str = Field(default="", validation_alias="OPENCODE_GO_API_KEY")
# ==================== Z.ai Config ====================
zai_api_key: str = Field(default="", validation_alias="ZAI_API_KEY")
+1 -1
View File
@@ -50,7 +50,7 @@ PROVIDER_SMOKE_DEFAULT_MODELS: dict[str, str] = {
"ollama": "ollama/llama3.1",
"wafer": "wafer/DeepSeek-V4-Pro",
"opencode": "opencode/gpt-5.3-codex",
"opencode_go": "opencode_go/gpt-5.3-codex",
"opencode_go": "opencode_go/minimax-m2.7",
"zai": "zai/glm-5.1",
}
-1
View File
@@ -38,7 +38,6 @@ def _make_mock_settings(**overrides):
mock.deepseek_api_key = "test_deepseek_key"
mock.wafer_api_key = "test_wafer_key"
mock.opencode_api_key = "test_opencode_key"
mock.opencode_go_api_key = "test_opencode_go_key"
mock.zai_api_key = "test_zai_key"
mock.lm_studio_base_url = "http://localhost:1234/v1"
mock.ollama_base_url = "http://localhost:11434"
-1
View File
@@ -28,7 +28,6 @@ def _settings(**overrides):
"deepseek_api_key": "",
"wafer_api_key": "",
"opencode_api_key": "",
"opencode_go_api_key": "",
"zai_api_key": "",
"lm_studio_base_url": "",
"llamacpp_base_url": "",
-2
View File
@@ -34,7 +34,6 @@ def _settings(
deepseek_api_key: str = "",
wafer_api_key: str = "",
opencode_api_key: str = "",
opencode_go_api_key: str = "",
zai_api_key: str = "",
) -> Settings:
return Settings.model_construct(
@@ -47,7 +46,6 @@ def _settings(
deepseek_api_key=deepseek_api_key,
wafer_api_key=wafer_api_key,
opencode_api_key=opencode_api_key,
opencode_go_api_key=opencode_go_api_key,
zai_api_key=zai_api_key,
log_api_error_tracebacks=False,
)
+18 -3
View File
@@ -5,7 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from config.nim import NimSettings
from config.provider_catalog import ZAI_DEFAULT_BASE
from config.provider_catalog import PROVIDER_CATALOG, ZAI_DEFAULT_BASE
from config.provider_ids import SUPPORTED_PROVIDER_IDS
from providers.deepseek import DeepSeekProvider
from providers.exceptions import UnknownProviderTypeError
@@ -34,7 +34,6 @@ def _make_settings(**overrides):
mock.deepseek_api_key = "test_deepseek_key"
mock.wafer_api_key = "test_wafer_key"
mock.opencode_api_key = "test_opencode_key"
mock.opencode_go_api_key = "test_opencode_go_key"
mock.zai_api_key = "test_zai_key"
mock.lm_studio_base_url = "http://localhost:1234/v1"
mock.llamacpp_base_url = "http://localhost:8080/v1"
@@ -118,7 +117,23 @@ def test_opencode_go_provider_config_uses_correct_base_url_and_name():
assert isinstance(provider, OpenCodeProvider)
assert provider._base_url == "https://opencode.ai/zen/go/v1"
assert provider._provider_name == "OPENCODE_GO"
assert provider._api_key == "test_opencode_go_key"
assert provider._api_key == "test_opencode_key"
def test_opencode_go_catalog_uses_opencode_api_key() -> None:
desc = PROVIDER_CATALOG["opencode_go"]
assert desc.credential_env == "OPENCODE_API_KEY"
assert desc.credential_attr == "opencode_api_key"
def test_build_provider_config_opencode_go_uses_opencode_api_key() -> None:
descriptor = PROVIDER_CATALOG["opencode_go"]
settings = _make_settings(opencode_api_key="shared-opencode-token")
config = build_provider_config(descriptor, settings)
assert config.api_key == "shared-opencode-token"
def test_create_provider_uses_native_openrouter_by_default():