diff --git a/hermes_cli/model_switch.py b/hermes_cli/model_switch.py index 5adec31c04..56e5265bec 100644 --- a/hermes_cli/model_switch.py +++ b/hermes_cli/model_switch.py @@ -809,8 +809,9 @@ def list_authenticated_providers( }) seen_slugs.add(slug) - # --- 2. Check Hermes-only providers (nous, openai-codex, copilot) --- + # --- 2. Check Hermes-only providers (nous, openai-codex, copilot, opencode-go) --- from hermes_cli.providers import HERMES_OVERLAYS + from hermes_cli.auth import PROVIDER_REGISTRY as _auth_registry for pid, overlay in HERMES_OVERLAYS.items(): if pid in seen_slugs: continue @@ -818,6 +819,11 @@ def list_authenticated_providers( has_creds = False if overlay.extra_env_vars: has_creds = any(os.environ.get(ev) for ev in overlay.extra_env_vars) + # Also check api_key_env_vars from PROVIDER_REGISTRY for api_key auth_type + if not has_creds and overlay.auth_type == "api_key": + pcfg = _auth_registry.get(pid) + if pcfg and pcfg.api_key_env_vars: + has_creds = any(os.environ.get(ev) for ev in pcfg.api_key_env_vars) if overlay.auth_type in ("oauth_device_code", "oauth_external", "external_process"): # These use auth stores, not env vars — check for auth.json entries try: diff --git a/tests/hermes_cli/test_opencode_go_in_model_list.py b/tests/hermes_cli/test_opencode_go_in_model_list.py new file mode 100644 index 0000000000..493d41b992 --- /dev/null +++ b/tests/hermes_cli/test_opencode_go_in_model_list.py @@ -0,0 +1,33 @@ +"""Test that opencode-go appears in /model list when credentials are set.""" + +import os +from unittest.mock import patch + +from hermes_cli.model_switch import list_authenticated_providers + + +@patch.dict(os.environ, {"OPENCODE_GO_API_KEY": "test-key"}, clear=False) +def test_opencode_go_appears_when_api_key_set(): + """opencode-go should appear in list_authenticated_providers when OPENCODE_GO_API_KEY is set.""" + providers = list_authenticated_providers(current_provider="openrouter") + + # Find opencode-go in results + opencode_go = next((p for p in providers if p["slug"] == "opencode-go"), None) + + assert opencode_go is not None, "opencode-go should appear when OPENCODE_GO_API_KEY is set" + assert opencode_go["models"] == ["glm-5", "kimi-k2.5", "mimo-v2-pro", "mimo-v2-omni", "minimax-m2.7", "minimax-m2.5"] + # opencode-go is in PROVIDER_TO_MODELS_DEV, so it appears as "built-in" (Part 1) + assert opencode_go["source"] == "built-in" + + +def test_opencode_go_not_appears_when_no_creds(): + """opencode-go should NOT appear when no credentials are set.""" + # Ensure OPENCODE_GO_API_KEY is not set + env_without_key = {k: v for k, v in os.environ.items() if k != "OPENCODE_GO_API_KEY"} + + with patch.dict(os.environ, env_without_key, clear=True): + providers = list_authenticated_providers(current_provider="openrouter") + + # opencode-go should not be in results + opencode_go = next((p for p in providers if p["slug"] == "opencode-go"), None) + assert opencode_go is None, "opencode-go should not appear without credentials"