mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-04 08:28:36 +00:00
chore(anthropic): raise SDK floor for native effort fields
Require Anthropic 0.100.0 so adaptive thinking, disabled thinking, and all advertised effort values use typed SDK parameters instead of extra_body compatibility.
This commit is contained in:
parent
356eeeb48c
commit
9b7610709b
@ -614,9 +614,8 @@ class AnthropicProvider(LLMProvider):
|
||||
model_name, _THINKING_DISABLE_MIN_VERSIONS
|
||||
):
|
||||
# These models think by default, so omission would not honor an
|
||||
# explicit request to disable thinking. Use extra_body for SDKs
|
||||
# that predate the typed thinking parameter.
|
||||
kwargs["extra_body"] = {"thinking": {"type": "disabled"}}
|
||||
# explicit request to disable thinking.
|
||||
kwargs["thinking"] = {"type": "disabled"}
|
||||
elif reasoning_effort_lower == "adaptive":
|
||||
# Adaptive thinking: model decides when and how much to think
|
||||
# Also auto-enables interleaved thinking between tool calls.
|
||||
@ -626,13 +625,8 @@ class AnthropicProvider(LLMProvider):
|
||||
elif thinking_enabled and adaptive_only:
|
||||
# Newer Claude models removed manual token budgets. Their effort
|
||||
# control is independent from the adaptive thinking mode.
|
||||
# These fields were added as first-class SDK arguments after our
|
||||
# minimum anthropic version; extra_body preserves wire compatibility
|
||||
# across the declared dependency range.
|
||||
kwargs["extra_body"] = {
|
||||
"thinking": {"type": "adaptive"},
|
||||
"output_config": {"effort": reasoning_effort_lower},
|
||||
}
|
||||
kwargs["thinking"] = {"type": "adaptive"}
|
||||
kwargs["output_config"] = {"effort": reasoning_effort_lower}
|
||||
elif thinking_enabled:
|
||||
budget_map = {"low": 1024, "medium": 4096, "high": max(8192, max_tokens)}
|
||||
budget = budget_map.get(reasoning_effort_lower, 4096)
|
||||
|
||||
@ -24,7 +24,7 @@ license-files = [
|
||||
|
||||
dependencies = [
|
||||
"typer>=0.20.0,<1.0.0",
|
||||
"anthropic>=0.45.0,<1.0.0",
|
||||
"anthropic>=0.100.0,<1.0.0",
|
||||
"pydantic>=2.12.0,<3.0.0",
|
||||
"pydantic-settings>=2.12.0,<3.0.0",
|
||||
# Feishu's lark-oapi currently requires websockets<16; core supports 15 and 16.
|
||||
|
||||
@ -82,8 +82,8 @@ def test_opus_4_7_omits_temperature_adaptive() -> None:
|
||||
def test_opus_4_7_high_uses_adaptive_effort() -> None:
|
||||
kw = _build(_make_provider("claude-opus-4-7"), "high", max_tokens=4096)
|
||||
assert "temperature" not in kw
|
||||
assert kw["extra_body"]["thinking"] == {"type": "adaptive"}
|
||||
assert kw["extra_body"]["output_config"] == {"effort": "high"}
|
||||
assert kw["thinking"] == {"type": "adaptive"}
|
||||
assert kw["output_config"] == {"effort": "high"}
|
||||
assert kw["max_tokens"] == 4096
|
||||
|
||||
|
||||
@ -102,8 +102,8 @@ def test_opus_4_8_omits_temperature_adaptive() -> None:
|
||||
def test_opus_4_8_high_uses_adaptive_effort() -> None:
|
||||
kw = _build(_make_provider("claude-opus-4-8"), "high", max_tokens=4096)
|
||||
assert "temperature" not in kw
|
||||
assert kw["extra_body"]["thinking"] == {"type": "adaptive"}
|
||||
assert kw["extra_body"]["output_config"] == {"effort": "high"}
|
||||
assert kw["thinking"] == {"type": "adaptive"}
|
||||
assert kw["output_config"] == {"effort": "high"}
|
||||
|
||||
|
||||
def test_opus_4_8_omits_temperature_none() -> None:
|
||||
@ -119,8 +119,8 @@ def test_fable_omits_temperature_adaptive() -> None:
|
||||
def test_fable_high_uses_adaptive_effort() -> None:
|
||||
kw = _build(_make_provider("claude-fable-5"), "high", max_tokens=4096)
|
||||
assert "temperature" not in kw
|
||||
assert kw["extra_body"]["thinking"] == {"type": "adaptive"}
|
||||
assert kw["extra_body"]["output_config"] == {"effort": "high"}
|
||||
assert kw["thinking"] == {"type": "adaptive"}
|
||||
assert kw["output_config"] == {"effort": "high"}
|
||||
|
||||
|
||||
def test_fable_omits_temperature_none() -> None:
|
||||
@ -137,22 +137,22 @@ def test_sonnet_5_omits_temperature_adaptive() -> None:
|
||||
def test_sonnet_5_high_uses_adaptive_effort() -> None:
|
||||
kw = _build(_make_provider("claude-sonnet-5"), "high", max_tokens=4096)
|
||||
assert "temperature" not in kw
|
||||
assert kw["extra_body"]["thinking"] == {"type": "adaptive"}
|
||||
assert kw["extra_body"]["output_config"] == {"effort": "high"}
|
||||
assert kw["thinking"] == {"type": "adaptive"}
|
||||
assert kw["output_config"] == {"effort": "high"}
|
||||
|
||||
|
||||
def test_sonnet_5_omits_temperature_none() -> None:
|
||||
kw = _build(_make_provider("anthropic/claude-sonnet-5"), "none")
|
||||
assert "temperature" not in kw
|
||||
assert "thinking" not in kw
|
||||
assert kw["extra_body"] == {"thinking": {"type": "disabled"}}
|
||||
assert kw["thinking"] == {"type": "disabled"}
|
||||
assert "output_config" 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
|
||||
assert "output_config" not in kw
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -165,36 +165,36 @@ def test_opus_5_omits_temperature(reasoning_effort: str | None) -> None:
|
||||
|
||||
def test_opus_5_none_disables_default_thinking() -> None:
|
||||
kw = _build(_make_provider("claude-opus-5"), "none")
|
||||
assert kw["extra_body"] == {"thinking": {"type": "disabled"}}
|
||||
assert "thinking" not in kw
|
||||
assert kw["thinking"] == {"type": "disabled"}
|
||||
assert "output_config" not in kw
|
||||
|
||||
|
||||
def test_opus_5_unset_preserves_provider_default() -> None:
|
||||
kw = _build(_make_provider("claude-opus-5"), None)
|
||||
assert "thinking" not in kw
|
||||
assert "extra_body" not in kw
|
||||
assert "output_config" not in kw
|
||||
|
||||
|
||||
@pytest.mark.parametrize("reasoning_effort", ["low", "medium", "high", "xhigh", "max"])
|
||||
def test_opus_5_uses_adaptive_thinking_with_effort(reasoning_effort: str) -> None:
|
||||
kw = _build(_make_provider("claude-opus-5"), reasoning_effort, max_tokens=4096)
|
||||
assert kw["extra_body"]["thinking"] == {"type": "adaptive"}
|
||||
assert kw["extra_body"]["output_config"] == {"effort": reasoning_effort}
|
||||
assert kw["thinking"] == {"type": "adaptive"}
|
||||
assert kw["output_config"] == {"effort": reasoning_effort}
|
||||
assert kw["max_tokens"] == 4096
|
||||
|
||||
|
||||
def test_dated_opus_5_model_uses_family_capabilities() -> None:
|
||||
kw = _build(_make_provider("claude-opus-5-20260724"), "medium")
|
||||
assert "temperature" not in kw
|
||||
assert kw["extra_body"]["thinking"] == {"type": "adaptive"}
|
||||
assert kw["extra_body"]["output_config"] == {"effort": "medium"}
|
||||
assert kw["thinking"] == {"type": "adaptive"}
|
||||
assert kw["output_config"] == {"effort": "medium"}
|
||||
|
||||
|
||||
def test_dated_opus_4_model_does_not_treat_date_as_minor_version() -> None:
|
||||
kw = _build(_make_provider("claude-opus-4-20250514"), "high")
|
||||
assert kw["temperature"] == 1.0
|
||||
assert kw["thinking"] == {"type": "enabled", "budget_tokens": 8192}
|
||||
assert "extra_body" not in kw
|
||||
assert "output_config" not in kw
|
||||
|
||||
|
||||
def test_ordinary_model_sends_temperature() -> None:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user