From 89d8b58fa2c0c027528fd1f2db7788091f65c68c Mon Sep 17 00:00:00 2001 From: Roland Tannous Date: Thu, 14 May 2026 10:59:39 +0400 Subject: [PATCH] studio/backend: drop top_p from Anthropic body when thinking is enabled PR 5412 added body['top_p'] = max(0.95, min(top_p, 1.0)) inside the thinking branch of _stream_anthropic, but Anthropic returns 400 on extended/adaptive thinking when both temperature and top_p are set: invalid_request_error: temperature and top_p cannot both be specified for this model. Please use only one. (Observed on Claude Opus 4.6.) The contract for thinking-enabled requests is temperature=1 with neither top_p nor top_k allowed. Replace the body['top_p'] = ... line with body.pop('top_p', None). Defensive pop rather than a bare delete: the base body construction above does not currently set top_p, but a future edit that adds it would silently reintroduce the regression. --- studio/backend/core/inference/external_provider.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/studio/backend/core/inference/external_provider.py b/studio/backend/core/inference/external_provider.py index 2fa1cd1410..bc75496ca9 100644 --- a/studio/backend/core/inference/external_provider.py +++ b/studio/backend/core/inference/external_provider.py @@ -349,10 +349,14 @@ class ExternalProviderClient: if effort and effort != "none": # Anthropic rejects top_k whenever thinking is enabled. body.pop("top_k", None) - # Anthropic requires temperature=1 whenever thinking is enabled. + # Anthropic requires temperature=1 whenever thinking is enabled, + # AND forbids top_p in the same request: setting both produces + # "temperature and top_p cannot both be specified for this + # model. Please use only one." + # The base body never sets top_p, but pop defensively in case + # an upstream edit ever adds it before this branch runs. body["temperature"] = 1 - # Anthropic thinking supports top_p in the 0.95..1.0 range. - body["top_p"] = max(0.95, min(float(top_p), 1.0)) + body.pop("top_p", None) if _ANTHROPIC_ADAPTIVE_THINKING.match(model): body["thinking"] = {"type": "adaptive"} body["output_config"] = {"effort": effort}