"""Tests for model-aware reasoning effort chip visibility.""" from api import config as cfg def test_cursor_acp_models_do_not_support_reasoning_effort_levels(): assert cfg.resolve_model_reasoning_efforts( "cursor/composer-2.5", provider_id="cursor-acp", ) == [] def test_openai_codex_gpt5_supports_reasoning_effort_levels(): efforts = cfg.resolve_model_reasoning_efforts( "gpt-5.5", provider_id="openai-codex", ) assert "medium" in efforts assert "high" in efforts assert "xhigh" in efforts assert "max" not in efforts def test_openai_codex_prefixed_gpt5_supports_reasoning_effort_levels(): efforts = cfg.resolve_model_reasoning_efforts( "@openai-codex:gpt-5.5", provider_id="openai-codex", ) assert "medium" in efforts assert "high" in efforts assert "xhigh" in efforts assert "max" not in efforts def test_openai_codex_max_effort_is_clamped_before_streaming(): assert cfg.coerce_reasoning_effort_for_model( "max", "gpt-5.5", provider_id="openai-codex", ) == "xhigh" def test_unsupported_xhigh_degrades_to_high_not_disabled(): # o1/o3/o4 on openai-codex cap at low/medium/high. A configured xhigh (or # max) must clamp DOWN to the highest supported level (high), not silently # disable reasoning by returning "". assert cfg.coerce_reasoning_effort_for_model( "xhigh", "o3-mini", provider_id="openai-codex", ) == "high" assert cfg.coerce_reasoning_effort_for_model( "max", "o3-mini", provider_id="openai-codex", ) == "high" def test_coerce_never_escalates_above_configured_effort(): # A supported lower effort is returned verbatim; coercion only degrades. assert cfg.coerce_reasoning_effort_for_model( "low", "gpt-5.5", provider_id="openai-codex", ) == "low" def test_coerce_preserves_effort_for_unrecognized_model(): # #3505 review: resolve_model_reasoning_efforts() returns [] for BOTH # known-unsupported AND simply-unrecognized models (custom providers, # aggregator-rewritten ids, brand-new releases). Coercion must NOT silently # drop a configured effort just because we don't recognize the model — that # would be a behavior change vs sending it verbatim (master). Preserve the # configured level for an empty/unknown capability set; the provider stays # the final authority. The known-bad CLAMP paths return a NON-empty set, so # they are unaffected (covered by the openai-codex tests above). assert cfg.coerce_reasoning_effort_for_model( "high", "some-unknown-model-xyz", provider_id="some-custom-provider", ) == "high" assert cfg.coerce_reasoning_effort_for_model( "max", "brand-new-model-2099", provider_id="some-custom-provider", ) == "xhigh" # 'none' / unset still pass through unchanged for unknown models. assert cfg.coerce_reasoning_effort_for_model( "none", "some-unknown-model-xyz", provider_id="custom" ) == "none" assert cfg.coerce_reasoning_effort_for_model( "", "some-unknown-model-xyz", provider_id="custom" ) == "" def test_github_copilot_gpt5_supports_reasoning_effort_levels(): efforts = cfg.resolve_model_reasoning_efforts( "gpt-5.5", provider_id="github-copilot", ) assert "medium" in efforts assert "high" in efforts def test_openrouter_anthropic_models_keep_reasoning_effort_levels(): efforts = cfg.resolve_model_reasoning_efforts( "anthropic/claude-sonnet-4.5", provider_id="openrouter", ) assert "medium" in efforts assert "high" in efforts def test_non_reasoning_http_models_hide_reasoning_effort_levels(): assert cfg.resolve_model_reasoning_efforts( "meta-llama/llama-3.1-8b-instruct", provider_id="openrouter", ) == [] def test_get_reasoning_status_includes_supported_efforts(monkeypatch): monkeypatch.setattr( cfg, "resolve_model_reasoning_efforts", lambda *a, **k: ["low", "medium", "high"], ) status = cfg.get_reasoning_status( model_id="gpt-5.5", provider_id="openai-codex", ) assert status["supported_efforts"] == ["low", "medium", "high"] assert status["supports_reasoning_effort"] is True def test_get_reasoning_status_for_reasoning_capable_model_has_no_max(): status = cfg.get_reasoning_status( model_id="gpt-5.5", provider_id="openai-codex", ) assert status["supported_efforts"] == ["minimal", "low", "medium", "high", "xhigh"] assert status["supports_reasoning_effort"] is True assert "max" not in status["supported_efforts"] def test_get_reasoning_status_coerces_stale_max_to_xhigh(monkeypatch): """A previously-saved `agent.reasoning_effort: max` (no longer a valid effort) must be reported as the coerced `xhigh`, not the raw stale `max`, so the boot/status/chip read paths agree with what streaming actually sends.""" monkeypatch.setattr( cfg, "_load_yaml_config_file", lambda *a, **k: {"agent": {"reasoning_effort": "max"}}, ) status = cfg.get_reasoning_status( model_id="gpt-5.5", provider_id="openai-codex", ) assert status["reasoning_effort"] == "xhigh" assert status["reasoning_effort"] != "max"