"""Unit tests for OpenCode Go reasoning-control wiring.""" from __future__ import annotations import pytest @pytest.fixture def opencode_go_profile(): """Resolve the registered OpenCode Go provider profile.""" import model_tools # noqa: F401 import providers profile = providers.get_provider_profile("opencode-go") assert profile is not None, "opencode-go provider profile must be registered" return profile @pytest.fixture def opencode_zen_profile(): """Resolve the registered OpenCode Zen provider profile.""" import model_tools # noqa: F401 import providers profile = providers.get_provider_profile("opencode-zen") assert profile is not None, "opencode-zen provider profile must be registered" return profile class TestOpenCodeZenOxReasoning: """Ox Alpha Free uses OpenCode Zen's native reasoning_effort control.""" def test_max_effort_is_emitted(self, opencode_zen_profile): extra_body, top_level = opencode_zen_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": "max"}, model="x-preview-f-free", ) assert extra_body == {} assert top_level == {"reasoning_effort": "max"} @pytest.mark.parametrize("reasoning_config", [None, {"enabled": False}]) def test_unset_or_disabled_preserves_server_default( self, opencode_zen_profile, reasoning_config ): extra_body, top_level = opencode_zen_profile.build_api_kwargs_extras( reasoning_config=reasoning_config, model="x-preview-f-free", ) assert extra_body == {} assert top_level == {} def test_other_zen_models_are_untouched(self, opencode_zen_profile): extra_body, top_level = opencode_zen_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": "max"}, model="gemini-3-flash", ) assert extra_body == {} assert top_level == {} def test_max_reaches_chat_completions_request(self, opencode_zen_profile): from agent.transports.chat_completions import ChatCompletionsTransport kwargs = ChatCompletionsTransport().build_kwargs( model="x-preview-f-free", messages=[{"role": "user", "content": "ping"}], tools=None, provider_profile=opencode_zen_profile, reasoning_config={"enabled": True, "effort": "max"}, base_url="https://opencode.ai/zen/v1", ) assert "extra_body" not in kwargs assert kwargs["reasoning_effort"] == "max" def test_unsupported_efforts_clamp_to_wire_vocabulary(self, opencode_zen_profile): """medium/xhigh are not on Ox Alpha's wire (400 raw); they must clamp to the nearest supported level, never pass through.""" for requested, expected in (("medium", "low"), ("xhigh", "max")): _, top_level = opencode_zen_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": requested}, model="x-preview-f-free", ) assert top_level == {"reasoning_effort": expected}, requested class TestOpenCodeGoKimiReasoning: """Kimi K2 models use Moonshot's thinking + reasoning_effort shape on OpenCode Go.""" def test_high_effort_emits_thinking_and_effort(self, opencode_go_profile): extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": "high"}, model="kimi-k2.6", ) assert extra_body == {} assert top_level == {"reasoning_effort": "high"} def test_disabled_emits_thinking_disabled_without_effort(self, opencode_go_profile): extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": False}, model="kimi-k2.6", ) assert extra_body == {"thinking": {"type": "disabled"}} assert top_level == {} def test_minimal_effort_clamps_to_low(self, opencode_go_profile): # "minimal" is below Moonshot's floor — the shared clamp degrades it # to "low" (nearest supported) instead of dropping the ask and # leaving the server default (which was MORE thinking than asked). extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": "minimal"}, model="kimi-k2.6", ) assert extra_body == {} assert top_level == {"reasoning_effort": "low"} @pytest.mark.parametrize( "effort", [ "xhigh", "max", ], ) def test_strong_efforts_clamp_to_high(self, opencode_go_profile, effort): extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": effort}, model="moonshotai/kimi-k2.6", ) assert extra_body == {} assert top_level == {"reasoning_effort": "high"} def test_low_and_medium_pass_through(self, opencode_go_profile): for effort in ("low", "medium"): extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": effort}, model="kimi-k2.5", ) assert extra_body == {} assert top_level == {"reasoning_effort": effort} def test_no_config_preserves_server_default(self, opencode_go_profile): extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config=None, model="kimi-k2.6", ) assert extra_body == {} assert top_level == {} class TestOpenCodeGoDeepSeekThinking: """DeepSeek V4 models use DeepSeek-style thinking controls on OpenCode Go.""" def test_xhigh_and_max_normalize_to_max(self, opencode_go_profile): for effort in ("xhigh", "max"): extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": effort}, model="deepseek/deepseek-v4-pro", ) assert extra_body == {} assert top_level == {"reasoning_effort": "max"} @pytest.mark.parametrize("model", ["deepseek-flash", "deepseek/deepseek-flash"]) def test_version_less_canonical_id_gets_the_controls(self, opencode_go_profile, model): """The canonical version-less Flash id must reach the wire like the versioned ids: the asked effort, and an explicit thinking-off when reasoning is disabled.""" _, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": "high"}, model=model, ) assert top_level == {"reasoning_effort": "high"} extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": False}, model=model, ) assert extra_body == {"thinking": {"type": "disabled"}} assert top_level == {} def test_version_less_flash_effort_reaches_the_wire(self, opencode_go_profile): from agent.transports.chat_completions import ChatCompletionsTransport kwargs = ChatCompletionsTransport().build_kwargs( model="deepseek-flash", messages=[{"role": "user", "content": "ping"}], tools=None, provider_profile=opencode_go_profile, reasoning_config={"enabled": True, "effort": "max"}, base_url="https://opencode.ai/zen/go/v1", ) assert "extra_body" not in kwargs assert kwargs["reasoning_effort"] == "max" class TestOpenCodeGoGLM52Reasoning: """GLM-5.2 uses its native high/max reasoning_effort knob on OpenCode Go.""" @pytest.mark.parametrize("model", ["glm-5-2", "glm-5p2"]) def test_alias_spellings_recognized(self, opencode_go_profile, model): extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": "max"}, model=model, ) assert top_level == {"reasoning_effort": "max"} class TestOpenCodeGoModelGating: """Other OpenCode Go models must not receive Kimi/DeepSeek/GLM controls.""" @pytest.mark.parametrize( "model", [ "glm-5.1", "glm-5", "qwen3.6-plus", "minimax-m2.7", "deepseek-v3.1", "deepseek-chat", "", None, ], ) def test_non_target_models_emit_nothing(self, opencode_go_profile, model): extra_body, top_level = opencode_go_profile.build_api_kwargs_extras( reasoning_config={"enabled": True, "effort": "high"}, model=model, ) assert extra_body == {} assert top_level == {} class TestOpenCodeGoFullKwargsIntegration: """End-to-end transport kwargs include the profile-provided controls.""" def test_kimi_reasoning_reaches_extra_body_and_top_level(self, opencode_go_profile): from agent.transports.chat_completions import ChatCompletionsTransport kwargs = ChatCompletionsTransport().build_kwargs( model="kimi-k2.6", messages=[{"role": "user", "content": "ping"}], tools=None, provider_profile=opencode_go_profile, reasoning_config={"enabled": True, "effort": "high"}, base_url="https://opencode.ai/zen/go/v1", ) assert "extra_body" not in kwargs assert kwargs["reasoning_effort"] == "high" def test_deepseek_thinking_reaches_extra_body_and_top_level( self, opencode_go_profile ): from agent.transports.chat_completions import ChatCompletionsTransport kwargs = ChatCompletionsTransport().build_kwargs( model="deepseek-v4-pro", messages=[{"role": "user", "content": "ping"}], tools=None, provider_profile=opencode_go_profile, reasoning_config={"enabled": True, "effort": "high"}, base_url="https://opencode.ai/zen/go/v1", ) assert "extra_body" not in kwargs assert kwargs["reasoning_effort"] == "high" def test_opencode_go_plan_windows_reach_usage_through_profile_hook(opencode_go_profile, monkeypatch): """The Go plan's rolling/weekly/monthly windows feed /usage via the profile hook — no core table entry.""" from datetime import datetime, timezone from agent.account_usage import fetch_account_usage class _Response: status_code = 200 def raise_for_status(self): return None def json(self): return {"usage": { "rolling": {"status": "ok", "percent": 3, "resetsAt": "2026-09-16T21:44:55.176Z"}, "weekly": {"status": "ok", "percent": 2, "resetsAt": "2026-09-21T00:00:00.176Z"}, "monthly": {"status": "ok", "percent": 2, "resetsAt": "2026-10-13T02:13:38.176Z"}, }} class _Client: def __init__(self, timeout=None): self.urls = [] def __enter__(self): return self def __exit__(self, *exc): return False def get(self, url, headers=None): self.urls.append(url) return _Response() monkeypatch.setattr("httpx.Client", _Client) monkeypatch.setattr( "hermes_cli.runtime_provider.resolve_runtime_provider", # /v1 stripped, as anthropic_messages routing leaves it — the hook must not reuse this base_url. lambda requested, explicit_base_url=None, explicit_api_key=None: { "provider": "opencode-go", "base_url": "https://opencode.ai/zen/go", "api_key": "sk-test"}, ) snapshot = fetch_account_usage("opencode-go") assert snapshot is not None and snapshot.provider == "opencode-go" assert [(w.label, w.used_percent) for w in snapshot.windows] == [ ("Rolling window", 3.0), ("Weekly", 2.0), ("Monthly", 2.0)] assert snapshot.windows[0].reset_at == datetime(2026, 9, 16, 21, 44, 55, 176000, tzinfo=timezone.utc)