From 4f9125a5f9a51d33037536dfbc21b0295acbc8a3 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Tue, 26 May 2026 05:48:17 +0000 Subject: [PATCH] Pin Claude 4.7 sampling-removed regex with backend test (PR #5711) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guards against drift between the backend _ANTHROPIC_4_7_SAMPLING_REMOVED regex and the frontend ANTHROPIC_4_7_SAMPLING_REMOVED_REGEX added in the previous commit. If a future patch widens one without the other the panel will either silently strip a knob the user moved or 400 on a knob the UI should have hidden — both bad UX. Test pins the canonical 4.7 id shapes (opus/sonnet/haiku) including dated snapshots, and the non-4.7 ids that must NOT match (4-6, 4-5, 4-71, future 5, gpt-4o, etc.). Sampling-params suite now 60 passing (previously 59). --- .../tests/test_sampling_params_routing.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/studio/backend/tests/test_sampling_params_routing.py b/studio/backend/tests/test_sampling_params_routing.py index 1a0b3fed60..1727d01028 100644 --- a/studio/backend/tests/test_sampling_params_routing.py +++ b/studio/backend/tests/test_sampling_params_routing.py @@ -999,3 +999,40 @@ def test_local_anthropic_passthrough_helpers_accept_parallel_tool_calls(): parallel_tool_calls = False, ) assert body.get("parallel_tool_calls") is False, body + + +def test_anthropic_4_7_sampling_removed_regex_matches_expected_ids(): + """Pin the canonical Claude 4.7 model-id shape so the frontend + ANTHROPIC_4_7_SAMPLING_REMOVED_REGEX in + studio/frontend/src/features/chat/provider-capabilities.ts stays + in lockstep with the backend strip in + external_provider._stream_anthropic. + + Drift would mean the panel either silently strips a knob the user + moved (UI shows, wire drops) or the wire 400s after the user moved + a knob the UI should have hidden. Both are user-visible bugs. + """ + from core.inference.external_provider import ( + _ANTHROPIC_4_7_SAMPLING_REMOVED as RX, + ) + + should_match = [ + "claude-opus-4-7", + "claude-sonnet-4-7", + "claude-haiku-4-7", + "claude-opus-4-7-20260418", + "claude-sonnet-4-7.1", + ] + should_not_match = [ + "claude-opus-4-6", + "claude-sonnet-4-6", + "claude-haiku-4-5", + "claude-opus-4-71", + "claude-opus-5", + "claude-3-opus", + "gpt-4o", + ] + for mid in should_match: + assert RX.match(mid), f"{mid!r} should match 4.7 sampling-removed regex" + for mid in should_not_match: + assert not RX.match(mid), f"{mid!r} should NOT match 4.7 regex"