feat(providers): add Claude Opus 4.8 model support

Register `claude-opus-4-8` in the Anthropic capability table. Opus 4.8
shares Opus 4.7's request/response surface exactly — adaptive-thinking
only (`budget_tokens` rejected), sampling params removed, the
low/medium/high/xhigh/max effort levels, `thinking.display` defaulting to
omitted, 1M context, and 128K output — so the entry is a verbatim copy of
the 4.7 row. `_lookup_capabilities` longest-prefix matching then resolves
date-suffixed ids (e.g. `claude-opus-4-8-20260601`) without colliding
with the 4.7 key.

No provider code paths change: the existing 4.7 handling already covers
all of 4.8's behavior. Models are selected via config.toml / the admin
ConfigStore UI, so there is no catalog or dropdown to update.

- _anthropic.py: new claude-opus-4-8 capability entry + effort comment
- tests/test_providers.py: opus 4.8 bare + dated capability tests
- turnstone.example.toml: bump the showcased model example to 4.8
This commit is contained in:
Patrick Buckley
2026-05-28 19:04:20 -07:00
parent 56f230afa2
commit 9d50e90f67
3 changed files with 43 additions and 2 deletions
+27
View File
@@ -1265,6 +1265,33 @@ class TestAnthropicHelpers:
assert caps.token_param == "max_tokens"
assert caps.thinking_mode == "adaptive"
def test_capabilities_opus_4_8(self) -> None:
from turnstone.core.providers._anthropic import AnthropicProvider
provider = AnthropicProvider()
caps = provider.get_capabilities("claude-opus-4-8")
assert caps.context_window == 1000000
assert caps.max_output_tokens == 128000
assert caps.thinking_mode == "adaptive"
assert caps.supports_effort is True
assert "xhigh" in caps.effort_levels
assert "max" in caps.effort_levels
assert caps.supports_temperature is False
assert caps.thinking_display == "summarized"
assert caps.supports_web_search is True
assert caps.supports_tool_search is True
assert caps.supports_vision is True
assert caps.supports_reasoning_replay is True
def test_capabilities_opus_4_8_dated(self) -> None:
from turnstone.core.providers._anthropic import AnthropicProvider
provider = AnthropicProvider()
caps = provider.get_capabilities("claude-opus-4-8-20260601")
assert caps.context_window == 1000000
assert caps.supports_temperature is False
assert caps.thinking_display == "summarized"
def test_capabilities_opus_4_7(self) -> None:
from turnstone.core.providers._anthropic import AnthropicProvider
+1 -1
View File
@@ -54,7 +54,7 @@
# supports_web_search = false
#
# [models.claude]
# name = "claude-opus-4-7"
# name = "claude-opus-4-8"
# provider = "anthropic"
# --- Database (turnstone, node, console) ---
+15 -1
View File
@@ -85,6 +85,20 @@ _ANTHROPIC_DEFAULT = ModelCapabilities(
)
_ANTHROPIC_CAPABILITIES: dict[str, ModelCapabilities] = {
"claude-opus-4-8": ModelCapabilities(
context_window=1000000,
max_output_tokens=128000,
token_param="max_tokens",
thinking_mode="adaptive",
supports_effort=True,
effort_levels=("low", "medium", "high", "xhigh", "max"),
supports_web_search=True,
supports_tool_search=True,
supports_vision=True,
supports_temperature=False,
thinking_display="summarized",
supports_reasoning_replay=True,
),
"claude-opus-4-7": ModelCapabilities(
context_window=1000000,
max_output_tokens=128000,
@@ -311,7 +325,7 @@ class AnthropicProvider:
kwargs["tools"] = anthropic_tools
kwargs.update(thinking_params)
# Effort param for models that support it (Opus 4.7, Opus 4.6, Sonnet 4.6, Opus 4.5)
# Effort param for models that support it (Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 4.6, Opus 4.5)
if caps.supports_effort and reasoning_effort:
effort = _map_reasoning_to_effort(reasoning_effort, caps.effort_levels)
if effort: