From e971f6bb8f6051b7993aa2856b9f9dff63cd7c13 Mon Sep 17 00:00:00 2001 From: chengyongru Date: Tue, 4 Aug 2026 11:48:35 +0800 Subject: [PATCH] fix(anthropic): distinguish sampling restrictions Reuse adaptive-only version thresholds where the capabilities align, while preserving Mythos Preview's supported manual thinking budgets. --- nanobot/providers/anthropic_provider.py | 13 +++++-------- tests/providers/test_anthropic_thinking.py | 7 +++++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/nanobot/providers/anthropic_provider.py b/nanobot/providers/anthropic_provider.py index 2cd252846..082d1e408 100644 --- a/nanobot/providers/anthropic_provider.py +++ b/nanobot/providers/anthropic_provider.py @@ -41,12 +41,7 @@ _ADAPTIVE_ONLY_MIN_VERSIONS = { "fable": (5, 0), "mythos": (5, 0), } -_SAMPLING_DEPRECATED_MIN_VERSIONS = { - "opus": (4, 7), - "sonnet": (5, 0), - "fable": (5, 0), - "mythos": (5, 0), -} +_SAMPLING_DEPRECATED_MODELS = {"claude-mythos-preview"} def _model_version_at_least( @@ -596,8 +591,10 @@ class AnthropicProvider(LLMProvider): reasoning_effort_lower = reasoning_effort.lower() if reasoning_effort else None thinking_enabled = reasoning_effort_lower not in (None, "", "none") adaptive_only = _model_version_at_least(model_name, _ADAPTIVE_ONLY_MIN_VERSIONS) - omit_temperature = _model_version_at_least( - model_name, _SAMPLING_DEPRECATED_MIN_VERSIONS + # Mythos Preview rejects sampling parameters but still accepts manual + # thinking budgets, so it is not part of the adaptive-only capability. + omit_temperature = ( + adaptive_only or model_name.lower() in _SAMPLING_DEPRECATED_MODELS ) kwargs: dict[str, Any] = { diff --git a/tests/providers/test_anthropic_thinking.py b/tests/providers/test_anthropic_thinking.py index be36c20a9..cbc823930 100644 --- a/tests/providers/test_anthropic_thinking.py +++ b/tests/providers/test_anthropic_thinking.py @@ -147,6 +147,13 @@ def test_sonnet_5_omits_temperature_none() -> None: assert "thinking" not in kw +def test_mythos_preview_omits_temperature_but_keeps_manual_budget() -> None: + kw = _build(_make_provider("claude-mythos-preview"), "high", max_tokens=4096) + assert "temperature" not in kw + assert kw["thinking"] == {"type": "enabled", "budget_tokens": 8192} + assert "extra_body" not in kw + + @pytest.mark.parametrize("reasoning_effort", [None, "adaptive", "low", "medium", "high", "xhigh", "max"]) def test_opus_5_omits_temperature(reasoning_effort: str | None) -> None: kw = _build(_make_provider("claude-opus-5"), reasoning_effort)