From 9239429a00b1e2226503a2aae66ab63d98430cde Mon Sep 17 00:00:00 2001 From: 04cb <0x04cb@gmail.com> Date: Fri, 24 Apr 2026 09:01:22 +0800 Subject: [PATCH] fix(anthropic): omit temperature for opus-4-7 (#3417) --- nanobot/providers/anthropic_provider.py | 12 +++++++++--- tests/providers/test_anthropic_thinking.py | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/nanobot/providers/anthropic_provider.py b/nanobot/providers/anthropic_provider.py index f88bba62..5d6d36b7 100644 --- a/nanobot/providers/anthropic_provider.py +++ b/nanobot/providers/anthropic_provider.py @@ -436,6 +436,10 @@ class AnthropicProvider(LLMProvider): max_tokens = max(1, max_tokens) thinking_enabled = bool(reasoning_effort) + # claude-opus-4-7 deprecated the `temperature` parameter entirely — the + # API returns 400 if it is present, on any code path. + omit_temperature = "opus-4-7" in model_name + kwargs: dict[str, Any] = { "model": model_name, "messages": anthropic_msgs, @@ -450,14 +454,16 @@ class AnthropicProvider(LLMProvider): # Supported on claude-sonnet-4-6 and claude-opus-4-6. # Also auto-enables interleaved thinking between tool calls. kwargs["thinking"] = {"type": "adaptive"} - kwargs["temperature"] = 1.0 + if not omit_temperature: + kwargs["temperature"] = 1.0 elif thinking_enabled: budget_map = {"low": 1024, "medium": 4096, "high": max(8192, max_tokens)} budget = budget_map.get(reasoning_effort.lower(), 4096) kwargs["thinking"] = {"type": "enabled", "budget_tokens": budget} kwargs["max_tokens"] = max(max_tokens, budget + 4096) - kwargs["temperature"] = 1.0 - else: + if not omit_temperature: + kwargs["temperature"] = 1.0 + elif not omit_temperature: kwargs["temperature"] = temperature if anthropic_tools: diff --git a/tests/providers/test_anthropic_thinking.py b/tests/providers/test_anthropic_thinking.py index ab8942e1..12e2e167 100644 --- a/tests/providers/test_anthropic_thinking.py +++ b/tests/providers/test_anthropic_thinking.py @@ -63,3 +63,9 @@ def test_none_does_not_enable_thinking() -> None: kw = _build(_make_provider(), None) assert "thinking" not in kw assert kw["temperature"] == 0.7 + + +def test_opus_4_7_omits_temperature() -> None: + kw = _build(_make_provider("claude-opus-4-7"), "adaptive") + assert "temperature" not in kw + assert kw["thinking"] == {"type": "adaptive"}