mirror of
https://github.com/Alishahryar1/free-claude-code.git
synced 2026-06-01 22:09:04 +02:00
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:
+1
-5
@@ -18,14 +18,10 @@ KIMI_API_KEY=""
|
|||||||
WAFER_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_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)
|
# Z.ai Config (Anthropic-compatible Messages at api.z.ai/api/anthropic)
|
||||||
ZAI_API_KEY=""
|
ZAI_API_KEY=""
|
||||||
|
|
||||||
|
|||||||
@@ -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).
|
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`.
|
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/)
|
### 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:
|
Popular examples:
|
||||||
|
|
||||||
- `opencode_go/gpt-5.3-codex`
|
- `opencode_go/minimax-m2.7`
|
||||||
|
|
||||||
Browse available models at [opencode.ai](https://opencode.ai).
|
Browse available models at [opencode.ai](https://opencode.ai).
|
||||||
|
|
||||||
|
|||||||
+5
-11
@@ -160,21 +160,15 @@ FIELDS: tuple[ConfigFieldSpec, ...] = (
|
|||||||
),
|
),
|
||||||
ConfigFieldSpec(
|
ConfigFieldSpec(
|
||||||
"OPENCODE_API_KEY",
|
"OPENCODE_API_KEY",
|
||||||
"OpenCode Zen API Key",
|
"OpenCode API Key",
|
||||||
"providers",
|
"providers",
|
||||||
"secret",
|
"secret",
|
||||||
settings_attr="opencode_api_key",
|
settings_attr="opencode_api_key",
|
||||||
secret=True,
|
secret=True,
|
||||||
description="OpenCode Zen curated model gateway at opencode.ai.",
|
description=(
|
||||||
),
|
"OpenCode Zen curated gateway (opencode.ai/zen/v1) and OpenCode Go subscription "
|
||||||
ConfigFieldSpec(
|
"gateway (opencode.ai/zen/go/v1); single key from opencode.ai/auth."
|
||||||
"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.",
|
|
||||||
),
|
),
|
||||||
ConfigFieldSpec(
|
ConfigFieldSpec(
|
||||||
"ZAI_API_KEY",
|
"ZAI_API_KEY",
|
||||||
|
|||||||
@@ -141,9 +141,9 @@ PROVIDER_CATALOG: dict[str, ProviderDescriptor] = {
|
|||||||
"opencode_go": ProviderDescriptor(
|
"opencode_go": ProviderDescriptor(
|
||||||
provider_id="opencode_go",
|
provider_id="opencode_go",
|
||||||
transport_type="openai_chat",
|
transport_type="openai_chat",
|
||||||
credential_env="OPENCODE_GO_API_KEY",
|
credential_env="OPENCODE_API_KEY",
|
||||||
credential_url="https://opencode.ai/auth",
|
credential_url="https://opencode.ai/auth",
|
||||||
credential_attr="opencode_go_api_key",
|
credential_attr="opencode_api_key",
|
||||||
default_base_url=OPENCODE_GO_DEFAULT_BASE,
|
default_base_url=OPENCODE_GO_DEFAULT_BASE,
|
||||||
proxy_attr="opencode_go_proxy",
|
proxy_attr="opencode_go_proxy",
|
||||||
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
capabilities=("chat", "streaming", "tools", "thinking", "rate_limit"),
|
||||||
|
|||||||
+2
-4
@@ -119,12 +119,10 @@ class Settings(BaseSettings):
|
|||||||
# ==================== Wafer Config ====================
|
# ==================== Wafer Config ====================
|
||||||
wafer_api_key: str = Field(default="", validation_alias="WAFER_API_KEY")
|
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_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 ====================
|
# ==================== Z.ai Config ====================
|
||||||
zai_api_key: str = Field(default="", validation_alias="ZAI_API_KEY")
|
zai_api_key: str = Field(default="", validation_alias="ZAI_API_KEY")
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -50,7 +50,7 @@ PROVIDER_SMOKE_DEFAULT_MODELS: dict[str, str] = {
|
|||||||
"ollama": "ollama/llama3.1",
|
"ollama": "ollama/llama3.1",
|
||||||
"wafer": "wafer/DeepSeek-V4-Pro",
|
"wafer": "wafer/DeepSeek-V4-Pro",
|
||||||
"opencode": "opencode/gpt-5.3-codex",
|
"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",
|
"zai": "zai/glm-5.1",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ def _make_mock_settings(**overrides):
|
|||||||
mock.deepseek_api_key = "test_deepseek_key"
|
mock.deepseek_api_key = "test_deepseek_key"
|
||||||
mock.wafer_api_key = "test_wafer_key"
|
mock.wafer_api_key = "test_wafer_key"
|
||||||
mock.opencode_api_key = "test_opencode_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.zai_api_key = "test_zai_key"
|
||||||
mock.lm_studio_base_url = "http://localhost:1234/v1"
|
mock.lm_studio_base_url = "http://localhost:1234/v1"
|
||||||
mock.ollama_base_url = "http://localhost:11434"
|
mock.ollama_base_url = "http://localhost:11434"
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ def _settings(**overrides):
|
|||||||
"deepseek_api_key": "",
|
"deepseek_api_key": "",
|
||||||
"wafer_api_key": "",
|
"wafer_api_key": "",
|
||||||
"opencode_api_key": "",
|
"opencode_api_key": "",
|
||||||
"opencode_go_api_key": "",
|
|
||||||
"zai_api_key": "",
|
"zai_api_key": "",
|
||||||
"lm_studio_base_url": "",
|
"lm_studio_base_url": "",
|
||||||
"llamacpp_base_url": "",
|
"llamacpp_base_url": "",
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ def _settings(
|
|||||||
deepseek_api_key: str = "",
|
deepseek_api_key: str = "",
|
||||||
wafer_api_key: str = "",
|
wafer_api_key: str = "",
|
||||||
opencode_api_key: str = "",
|
opencode_api_key: str = "",
|
||||||
opencode_go_api_key: str = "",
|
|
||||||
zai_api_key: str = "",
|
zai_api_key: str = "",
|
||||||
) -> Settings:
|
) -> Settings:
|
||||||
return Settings.model_construct(
|
return Settings.model_construct(
|
||||||
@@ -47,7 +46,6 @@ def _settings(
|
|||||||
deepseek_api_key=deepseek_api_key,
|
deepseek_api_key=deepseek_api_key,
|
||||||
wafer_api_key=wafer_api_key,
|
wafer_api_key=wafer_api_key,
|
||||||
opencode_api_key=opencode_api_key,
|
opencode_api_key=opencode_api_key,
|
||||||
opencode_go_api_key=opencode_go_api_key,
|
|
||||||
zai_api_key=zai_api_key,
|
zai_api_key=zai_api_key,
|
||||||
log_api_error_tracebacks=False,
|
log_api_error_tracebacks=False,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from config.nim import NimSettings
|
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 config.provider_ids import SUPPORTED_PROVIDER_IDS
|
||||||
from providers.deepseek import DeepSeekProvider
|
from providers.deepseek import DeepSeekProvider
|
||||||
from providers.exceptions import UnknownProviderTypeError
|
from providers.exceptions import UnknownProviderTypeError
|
||||||
@@ -34,7 +34,6 @@ def _make_settings(**overrides):
|
|||||||
mock.deepseek_api_key = "test_deepseek_key"
|
mock.deepseek_api_key = "test_deepseek_key"
|
||||||
mock.wafer_api_key = "test_wafer_key"
|
mock.wafer_api_key = "test_wafer_key"
|
||||||
mock.opencode_api_key = "test_opencode_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.zai_api_key = "test_zai_key"
|
||||||
mock.lm_studio_base_url = "http://localhost:1234/v1"
|
mock.lm_studio_base_url = "http://localhost:1234/v1"
|
||||||
mock.llamacpp_base_url = "http://localhost:8080/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 isinstance(provider, OpenCodeProvider)
|
||||||
assert provider._base_url == "https://opencode.ai/zen/go/v1"
|
assert provider._base_url == "https://opencode.ai/zen/go/v1"
|
||||||
assert provider._provider_name == "OPENCODE_GO"
|
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():
|
def test_create_provider_uses_native_openrouter_by_default():
|
||||||
|
|||||||
Reference in New Issue
Block a user