Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 21 additions & 27 deletions unstract/sdk1/src/unstract/sdk1/adapters/base1.py
Original file line number Diff line number Diff line change
Expand Up @@ -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-<date>-v1:0`
# - Bedrock cross-region profile `us.anthropic.claude-opus-4-7-...`,
# `eu.`, `apac.`, `global.` variants
# - Bedrock foundation-model ARN `arn:aws:bedrock:<region>::foundation-model/
# anthropic.claude-opus-4-7-...`
# - Bedrock inference-profile ARN `arn:aws:bedrock:<region>:<account>:
# inference-profile/us.anthropic.claude-opus-4-7-...`
# - Vertex AI `vertex_ai/claude-opus-4-7@<date>`
# - 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 `@<date>`, 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-<date>-v1:0`), Vertex
# (`vertex_ai/claude-opus-4-8@<date>`), and Azure deployments embedding the id.
# Route prefixes (`converse/`, `invoke/`, `bedrock/`) pass through.
#
# The trailing lookahead (`$`, a `-`/`:`/`@`/`/` delimiter, or `v<digit>`)
# 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
Expand All @@ -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

Expand All @@ -89,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
Expand Down
28 changes: 27 additions & 1 deletion unstract/sdk1/tests/test_sampling_strip.py
Original file line number Diff line number Diff line change
@@ -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`)
Expand Down Expand Up @@ -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",
]


Expand Down Expand Up @@ -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`.
Expand Down
Loading