From ae76ac01d17172393cff5c59f6e9a1727a4a85ad Mon Sep 17 00:00:00 2001 From: Khurdhula-Harshavardhan Date: Thu, 30 Apr 2026 16:10:00 -0700 Subject: [PATCH] feat(anthropic): support Claude Opus 4.7 by omitting deprecated temperature Opus 4.7 returns a 400 when temperature/top_p/top_k are set; the safest migration per Anthropic's docs is to omit them entirely. Guard on the model id so existing 4.6 / Sonnet 4.6 runs continue to send temperature=0.0 unchanged. Ref: https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7 Co-Authored-By: Claude Opus 4.7 (1M context) --- sob/providers/anthropic_native.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/sob/providers/anthropic_native.py b/sob/providers/anthropic_native.py index 1fb07fa..28d3ae2 100644 --- a/sob/providers/anthropic_native.py +++ b/sob/providers/anthropic_native.py @@ -36,15 +36,20 @@ def _infer_one( candidate = None input_tokens = output_tokens = 0 + # Opus 4.7 deprecated temperature/top_p/top_k — passing any of them + # returns a 400. See https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7 + kwargs: dict = dict( + model=config.model_id, + max_tokens=config.max_tokens, + system=SYSTEM_PROMPT, + messages=[{"role": "user", "content": user_msg}], + ) + if "opus-4-7" not in config.model_id: + kwargs["temperature"] = config.temperature + for attempt in range(config.max_retries): try: - response = client.messages.create( - model=config.model_id, - max_tokens=config.max_tokens, - system=SYSTEM_PROMPT, - messages=[{"role": "user", "content": user_msg}], - temperature=config.temperature, - ) + response = client.messages.create(**kwargs) # Anthropic returns a list of content blocks; text lives on the # first one (TextBlock) for plain JSON tasks. raw = ""