Skip to content

Commit 0493b27

Browse files
authored
fix(anthropic): support effort="max" and remove beta headers (#35141)
1 parent a5f22e7 commit 0493b27

2 files changed

Lines changed: 10 additions & 64 deletions

File tree

libs/partners/anthropic/langchain_anthropic/chat_models.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ class ChatAnthropic(BaseChatModel):
872872
`#!python {"type": "adaptive"}`
873873
"""
874874

875-
effort: Literal["high", "medium", "low"] | None = None
875+
effort: Literal["max", "high", "medium", "low"] | None = None
876876
"""Control how many tokens Claude uses when responding.
877877
878878
This parameter will be merged into the `output_config` parameter when making
@@ -887,13 +887,8 @@ class ChatAnthropic(BaseChatModel):
887887
888888
!!! note "Model Support"
889889
890-
This feature is currently only supported by Claude Opus 4.5.
891-
892-
!!! note "Automatic beta header"
893-
894-
The required `effort-2025-11-24` beta header is
895-
automatically appended to the request when using `effort`, so you
896-
don't need to manually specify it in the `betas` parameter.
890+
This feature is generally available on Claude Opus 4.6 and Claude Opus 4.5.
891+
The `max` effort level is only supported by Claude Opus 4.6.
897892
"""
898893

899894
mcp_servers: list[dict[str, Any]] | None = None
@@ -1164,16 +1159,6 @@ def _get_request_payload(
11641159
if output_config:
11651160
payload["output_config"] = output_config
11661161

1167-
# Auto-append required beta for effort
1168-
if "effort" in output_config:
1169-
required_beta = "effort-2025-11-24"
1170-
if payload["betas"]:
1171-
# Merge with existing betas
1172-
if required_beta not in payload["betas"]:
1173-
payload["betas"] = [*payload["betas"], required_beta]
1174-
else:
1175-
payload["betas"] = [required_beta]
1176-
11771162
if "response_format" in payload:
11781163
# response_format present when using agents.create_agent's ProviderStrategy
11791164
# ---

libs/partners/anthropic/tests/unit_tests/test_chat_models.py

Lines changed: 7 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2085,7 +2085,7 @@ async def test_model_profile_not_blocking() -> None:
20852085
def test_effort_parameter_validation() -> None:
20862086
"""Test that effort parameter is validated correctly.
20872087
2088-
The effort parameter is currently in beta and only supported by Claude Opus 4.5.
2088+
The effort parameter is generally available on Claude Opus 4.6 and Opus 4.5.
20892089
"""
20902090
# Valid effort values should work
20912091
model = ChatAnthropic(model="claude-opus-4-5-20251101", effort="high")
@@ -2097,20 +2097,22 @@ def test_effort_parameter_validation() -> None:
20972097
model = ChatAnthropic(model="claude-opus-4-5-20251101", effort="low")
20982098
assert model.effort == "low"
20992099

2100+
model = ChatAnthropic(model="claude-opus-4-6", effort="max")
2101+
assert model.effort == "max"
2102+
21002103
# Invalid effort values should raise ValidationError
21012104
with pytest.raises(ValidationError, match="Input should be"):
21022105
ChatAnthropic(model="claude-opus-4-5-20251101", effort="invalid") # type: ignore[arg-type]
21032106

21042107

2105-
def test_effort_populates_betas() -> None:
2106-
"""Test that effort parameter auto-populates required betas."""
2108+
def test_effort_in_output_config_payload() -> None:
2109+
"""Test that effort parameter is properly added to output_config in payload."""
21072110
model = ChatAnthropic(model="claude-opus-4-5-20251101", effort="medium")
21082111
assert model.effort == "medium"
21092112

2110-
# Test that effort works with dated API ID
2113+
# Test that effort is added to output_config
21112114
payload = model._get_request_payload("Test query")
21122115
assert payload["output_config"]["effort"] == "medium"
2113-
assert "effort-2025-11-24" in payload["betas"]
21142116

21152117

21162118
def test_effort_in_output_config() -> None:
@@ -2136,43 +2138,6 @@ def test_effort_priority() -> None:
21362138
assert payload["output_config"]["effort"] == "high"
21372139

21382140

2139-
def test_effort_beta_header_auto_append() -> None:
2140-
"""Test that effort beta header is automatically appended."""
2141-
# Test with top-level effort parameter
2142-
model = ChatAnthropic(model="claude-opus-4-5-20251101", effort="medium")
2143-
payload = model._get_request_payload("Test query")
2144-
assert "effort-2025-11-24" in payload["betas"]
2145-
2146-
# Test with output_config
2147-
model = ChatAnthropic(
2148-
model="claude-opus-4-5-20251101",
2149-
output_config={"effort": "low"},
2150-
)
2151-
payload = model._get_request_payload("Test query")
2152-
assert "effort-2025-11-24" in payload["betas"]
2153-
2154-
# Test that beta is not duplicated if already present
2155-
model = ChatAnthropic(
2156-
model="claude-opus-4-5-20251101",
2157-
effort="high",
2158-
betas=["effort-2025-11-24"],
2159-
)
2160-
payload = model._get_request_payload("Test query")
2161-
assert payload["betas"].count("effort-2025-11-24") == 1
2162-
2163-
# Test combining effort with other betas
2164-
model = ChatAnthropic(
2165-
model="claude-opus-4-5-20251101",
2166-
effort="medium",
2167-
betas=["context-1m-2025-08-07"],
2168-
)
2169-
payload = model._get_request_payload("Test query")
2170-
assert set(payload["betas"]) == {
2171-
"context-1m-2025-08-07",
2172-
"effort-2025-11-24",
2173-
}
2174-
2175-
21762141
def test_output_config_without_effort() -> None:
21772142
"""Test that output_config can be used without effort."""
21782143
# output_config might have other fields in the future
@@ -2182,10 +2147,6 @@ def test_output_config_without_effort() -> None:
21822147
)
21832148
payload = model._get_request_payload("Test query")
21842149
assert payload["output_config"] == {"some_future_param": "value"}
2185-
# No effort beta should be added
2186-
assert payload.get("betas") is None or "effort-2025-11-24" not in payload.get(
2187-
"betas", []
2188-
)
21892150

21902151

21912152
def test_extras_with_defer_loading() -> None:

0 commit comments

Comments
 (0)