fix(providers): widen omit_temperature to cover opus-4-8 and fable

The temperature suppression was hardcoded to only match opus-4-7. Newer
Anthropic models (opus-4-8, fable) also reject the parameter with a 400.

Normalize model_name to lowercase before matching so mixed-case configs
do not fall through.  Add tests for opus-4-8 and fable across adaptive,
enabled, and no-thinking paths, plus a negative test confirming ordinary
models still send temperature.

Fixes #4333
This commit is contained in:
axelray-dev
2026-06-14 12:52:07 +08:00
committed by Xubin Ren
parent e36c43c9e5
commit 29d7186853
2 changed files with 39 additions and 3 deletions
+4 -3
View File
@@ -452,9 +452,10 @@ class AnthropicProvider(LLMProvider):
max_tokens = max(1, max_tokens)
thinking_enabled = bool(reasoning_effort) and reasoning_effort.lower() != "none"
# 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
# Several Anthropic models (opus-4-7, opus-4-8, fable) deprecated the
# `temperature` parameter — the API returns 400 if it is present.
_model_lower = model_name.lower()
omit_temperature = any(m in _model_lower for m in ("opus-4-7", "opus-4-8", "fable"))
kwargs: dict[str, Any] = {
"model": model_name,
@@ -85,6 +85,41 @@ def test_opus_4_7_omits_temperature_none() -> None:
assert "thinking" not in kw
def test_opus_4_8_omits_temperature_adaptive() -> None:
kw = _build(_make_provider("claude-opus-4-8"), "adaptive")
assert "temperature" not in kw
def test_opus_4_8_omits_temperature_enabled() -> None:
kw = _build(_make_provider("claude-opus-4-8"), "high", max_tokens=4096)
assert "temperature" not in kw
def test_opus_4_8_omits_temperature_none() -> None:
kw = _build(_make_provider("claude-opus-4-8"), None)
assert "temperature" not in kw
def test_fable_omits_temperature_adaptive() -> None:
kw = _build(_make_provider("claude-fable-1"), "adaptive")
assert "temperature" not in kw
def test_fable_omits_temperature_enabled() -> None:
kw = _build(_make_provider("claude-fable-1"), "high", max_tokens=4096)
assert "temperature" not in kw
def test_fable_omits_temperature_none() -> None:
kw = _build(_make_provider("claude-fable-1"), None)
assert "temperature" not in kw
def test_ordinary_model_sends_temperature() -> None:
kw = _build(_make_provider("claude-sonnet-4-6"), None)
assert kw["temperature"] == 0.7
def test_reasoning_effort_string_none_does_not_enable_thinking() -> None:
"""reasoning_effort='none' must not enable thinking — treated same as disabled."""
kw = _build(_make_provider(), "none")