studio: gate Anthropic top_k drop to Claude 4.7 only

Previous commit (b5aa6ffd) dropped top_k for every Anthropic call,
but only Claude 4.7 (Opus/Sonnet/Haiku) actually rejects it. 4.6, 4.5,
and the 3.x line still accept top_k and use it as documented.

Backend: _stream_anthropic matches the model id against
^claude-(opus|sonnet|haiku)-4-7(-|.|$) and only strips top_k when it
hits. Every other Claude generation continues to receive the value
from the chat settings panel.

Frontend: anthropic.topK is restored to true so the Top K slider is
visible again — the backend handles the per-model drop, and the
4.7 case is silent (request still succeeds without top_k).
This commit is contained in:
Roland Tannous 2026-05-12 14:12:56 +04:00
commit 1e98b384e6
2 changed files with 24 additions and 12 deletions

View file

@ -9,12 +9,19 @@ Anthropic uses native Messages API with translation in this client.
"""
import logging
import re
from typing import Any, AsyncGenerator, Optional
import httpx
logger = logging.getLogger(__name__)
# Claude 4.7 (Opus/Sonnet/Haiku) deprecated top_k and returns 400
# "top_k is deprecated for this model" when it is set. 3.x and 4.5/4.6
# still accept it. Match the 4-7 line specifically so we keep the knob
# live on every other Claude generation.
_ANTHROPIC_TOP_K_DEPRECATED = re.compile(r"^claude-(?:opus|sonnet|haiku)-4-7(?:[-.]|$)")
# Shared client reused across all requests for HTTP connection pooling.
# Auth headers and timeouts are passed per-request, so a single client
# handles every provider without storing credentials.
@ -276,13 +283,15 @@ class ExternalProviderClient:
# Anthropic rejects requests that set both temperature and top_p
"stream": True,
}
# top_k is deprecated on Claude 4.x (Opus / Sonnet / Haiku 4.x return
# 400 with `top_k is deprecated for this model`). It was always
# optional on the older 3.x line too, so we just stop forwarding it
# for every Anthropic call rather than maintaining a per-model gate.
# ``top_k`` is still accepted on the method signature for API
# symmetry with the other stream methods.
del top_k
# top_k is deprecated on Claude 4.7 (Opus/Sonnet/Haiku) — the API
# returns 400 "top_k is deprecated for this model" when it is set.
# 3.x and 4.5/4.6 still accept it, so gate strictly on the 4.7 ids.
if (
top_k is not None
and top_k > 0
and not _ANTHROPIC_TOP_K_DEPRECATED.match(model)
):
body["top_k"] = top_k
if system:
body["system"] = system

View file

@ -75,14 +75,17 @@ const PROVIDER_CAPABILITIES: Record<string, ProviderCapabilities> = {
repetitionPenalty: false,
presencePenalty: false,
},
// Anthropic's Messages API rejects presence/frequency penalty, and top_k
// is now deprecated across the Claude 4.x line (Opus / Sonnet / Haiku 4.x
// 400 with "top_k is deprecated for this model"). It was always optional
// on the older 3.x line, so we just drop it for every Anthropic call.
// Anthropic's Messages API accepts top_k on 3.x and 4.5/4.6, but Claude
// 4.7 (Opus/Sonnet/Haiku) deprecated it and returns 400 if it is set.
// We surface top_k in the panel for all Anthropic providers and let the
// backend strip it per-model — see _stream_anthropic in
// studio/backend/core/inference/external_provider.py.
// Presence/frequency penalty is not part of the Messages API on any
// Claude generation.
anthropic: {
temperature: true,
topP: true,
topK: false,
topK: true,
minP: false,
repetitionPenalty: false,
presencePenalty: false,