From 73c3e6be7052f949954a907954104938a67cb36b Mon Sep 17 00:00:00 2001 From: pk-zipstack Date: Mon, 22 Jun 2026 11:45:23 +0530 Subject: [PATCH 1/2] [FIX] Strip deprecated sampling params for Claude Opus 4.7 onwards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend the Anthropic sampling-param deprecation detector beyond Opus 4.7 to cover every Opus release from 4.7 onwards: 4.7, 4.8, 4.9 and Opus 5+. The previous single pattern matched only `claude-opus-4-7`, so callers on `claude-opus-4-8` (and future Opus ids) still sent `temperature` / `top_p` / `top_k` and 400'd with "temperature is deprecated for this model". Replace the lone pattern with two anchored ones — `claude-opus-4-[789]` and `claude-opus-[5-9]` — keeping the existing trailing-edge boundary so prefix collisions (`claude-opus-4-70`, `claude-opus-4-7verbose`) and the sampling-supporting `claude-opus-4-1..4-6` still do not match. Extend test_sampling_strip.py with 4.8/4.9/Opus 5+ positives and Opus 5 boundary negatives. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../sdk1/src/unstract/sdk1/adapters/base1.py | 45 ++++++++----------- unstract/sdk1/tests/test_sampling_strip.py | 28 +++++++++++- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/unstract/sdk1/src/unstract/sdk1/adapters/base1.py b/unstract/sdk1/src/unstract/sdk1/adapters/base1.py index ebd93e3dbd..30fbf868af 100644 --- a/unstract/sdk1/src/unstract/sdk1/adapters/base1.py +++ b/unstract/sdk1/src/unstract/sdk1/adapters/base1.py @@ -17,33 +17,26 @@ logger = logging.getLogger(__name__) -# Anthropic models that have deprecated sampling parameters (`temperature`, -# `top_p`, `top_k`). The patterns are regex-searched against the model id -# after lowercasing and normalizing `.` / `_` to `-`. The match is anchored at -# the trailing edge so that unrelated future ids (`claude-opus-4-70`, -# `claude-opus-4-75`, `claude-opus-4-7verbose`) do not match. A single entry -# covers every encoding of the id we have observed: -# - Native Anthropic `claude-opus-4-7`, `anthropic/claude-opus-4-7` -# - Bedrock foundation model `anthropic.claude-opus-4-7--v1:0` -# - Bedrock cross-region profile `us.anthropic.claude-opus-4-7-...`, -# `eu.`, `apac.`, `global.` variants -# - Bedrock foundation-model ARN `arn:aws:bedrock:::foundation-model/ -# anthropic.claude-opus-4-7-...` -# - Bedrock inference-profile ARN `arn:aws:bedrock::: -# inference-profile/us.anthropic.claude-opus-4-7-...` -# - Vertex AI `vertex_ai/claude-opus-4-7@` -# - Azure AI Foundry deployments whose name embeds `claude-opus-4-7` -# Leading text (route prefixes like `converse/`, `invoke/`, `bedrock/`) passes -# through because the regex is anchored only at the trailing edge. -# Add new entries here when Anthropic deprecates sampling on more models. -# Trailing anchor allows: end-of-string, or one of `-`/`:`/`@`/`/` (the -# delimiters used in date suffixes, ARN paths, Vertex `@`, and the -# `v1:0` tag), or `v` followed by a digit (the version-tag start). A bare -# `v` is intentionally rejected so alpha continuations like `4-7verbose` do -# not silently match. +# Anthropic deprecated the sampling parameters (`temperature`, `top_p`, +# `top_k`) starting with Claude Opus 4.7; sending any of them yields a 400 from +# Anthropic and the providers that proxy it (Bedrock, Azure AI Foundry, Vertex +# AI). This covers every Opus release from 4.7 onwards: Opus 4.7, 4.8, 4.9 and +# every Opus 5+ release. +# +# Patterns are regex-searched against the model id after lowercasing and +# normalizing `.`/`_` to `-`, so they match every encoding we have seen: +# native (`claude-opus-4-8`), Bedrock foundation models / cross-region +# profiles / ARNs (`us.anthropic.claude-opus-4-8--v1:0`), Vertex +# (`vertex_ai/claude-opus-4-8@`), and Azure deployments embedding the id. +# Route prefixes (`converse/`, `invoke/`, `bedrock/`) pass through. +# +# The trailing lookahead (`$`, a `-`/`:`/`@`/`/` delimiter, or `v`) +# anchors the match so `claude-opus-4-70` and `claude-opus-4-7verbose` do NOT +# match while date/ARN/version suffixes still do. # See https://docs.claude.com/en/about-claude/models/whats-new-claude-4-7 _SAMPLING_DEPRECATED_MODEL_PATTERNS: tuple[re.Pattern[str], ...] = ( - re.compile(r"claude-opus-4-7(?=$|[-:@/]|v\d)"), + re.compile(r"claude-opus-4-[789](?=$|[-:@/]|v\d)"), # Opus 4.7, 4.8, 4.9 + re.compile(r"claude-opus-[5-9](?=$|[-:@/]|v\d)"), # Opus 5 and later ) _DEPRECATED_SAMPLING_PARAMS: tuple[str, ...] = ("temperature", "top_p", "top_k") # Fields whose value can carry a model id. `model` is universal; `model_id` is @@ -63,7 +56,7 @@ def _looks_like_opaque_aip_arn(value: str | None) -> bool: Bedrock AIP ARNs do not carry the underlying foundation-model id in the string, so the sampling-strip detector cannot decide whether the call is - bound for Claude Opus 4.7. + bound for Claude Opus 4.7 or later. """ return bool(value) and _OPAQUE_AIP_ARN_MARKER in value diff --git a/unstract/sdk1/tests/test_sampling_strip.py b/unstract/sdk1/tests/test_sampling_strip.py index 3e3ce8b405..7ff976f66f 100644 --- a/unstract/sdk1/tests/test_sampling_strip.py +++ b/unstract/sdk1/tests/test_sampling_strip.py @@ -1,5 +1,6 @@ -"""Tests for Claude Opus 4.7 sampling-parameter strip. +"""Tests for the Claude Opus 4.7+ sampling-parameter strip. +Covers every Opus release from 4.7 onwards (4.7, 4.8, 4.9, Opus 5+). Pins the detection regex and the four-adapter wiring against the failure modes that surfaced in PR #1934 review: - prefix collisions (`claude-opus-4-70`, `-75`, `4-7verbose`) @@ -60,6 +61,24 @@ # Version tag accepted only as `v\d` after the trailing edge "claude-opus-4-7v1", "claude-opus-4-7v9", + # Opus 4.8 / 4.9 — same deprecation, representative encodings + "claude-opus-4-8", + "anthropic/claude-opus-4-8", + "anthropic.claude-opus-4-8-20260101-v1:0", + "us.anthropic.claude-opus-4-8-20260101-v1:0", + "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-opus-4-8-20260101-v1:0", + "vertex_ai/claude-opus-4-8@20260101", + "azure_ai/my-claude-opus-4-8-deployment", + "claude.opus.4.8", + "claude-opus-4-9", + # Opus 5 and later + "claude-opus-5", + "claude-opus-5-0", + "anthropic/claude-opus-5-0", + "anthropic.claude-opus-5-0-20270101-v1:0", + "us.anthropic.claude-opus-5-0-20270101-v1:0", + "vertex_ai/claude-opus-5-0@20270101", + "claude-opus-6-0", ] @@ -92,6 +111,13 @@ def test_has_deprecated_sampling_params_positive(model: str) -> None: "claude-opus-4-7verbose", "claude-opus-4-7vnext", "claude-opus-4-7variant", + # Opus 5+ boundary: the major must end at a delimiter, not run into more + # digits or letters. + "claude-opus-50", + "claude-opus-5verbose", + # Opus 4.1–4.6 still accept sampling params; only 4.7+ is deprecated. + "claude-opus-4-1", + "anthropic.claude-opus-4-1-20250805-v1:0", # Opaque Bedrock Application Inference Profile ARN — model id is not # recoverable from the string. Strip-detection is expected to skip; # callers must keep the standard id in `model` or `model_id`. From 3a5f47de1f3cc2629ee20e73a41a6b7d12465320 Mon Sep 17 00:00:00 2001 From: pk-zipstack Date: Mon, 22 Jun 2026 12:40:03 +0530 Subject: [PATCH 2/2] [FIX] Generalize Azure deployment-name docstring example to current Opus id Address review feedback: the _has_deprecated_sampling_params docstring cited `claude-opus-4-7` as the Azure AI Foundry deployment-name example, which is stale now that the strip covers Opus 4.7 onwards. Reference the relevant model id generally (e.g. claude-opus-4-8). Co-Authored-By: Claude Opus 4.8 (1M context) --- unstract/sdk1/src/unstract/sdk1/adapters/base1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unstract/sdk1/src/unstract/sdk1/adapters/base1.py b/unstract/sdk1/src/unstract/sdk1/adapters/base1.py index 30fbf868af..201f4acff9 100644 --- a/unstract/sdk1/src/unstract/sdk1/adapters/base1.py +++ b/unstract/sdk1/src/unstract/sdk1/adapters/base1.py @@ -82,7 +82,8 @@ def _has_deprecated_sampling_params(model: str | None) -> bool: from the string. Pass the AIP ARN in `model_id` and keep the standard model id in `model`, or the strip won't fire. - Azure AI Foundry deployment names that omit the model id; rename the - deployment to include `claude-opus-4-7` so detection works. + deployment to include the relevant model id (e.g. `claude-opus-4-8`) + so detection works. """ if not model: return False