mirror of
https://github.com/hwchase17/langchain.git
synced 2026-06-09 10:17:00 +00:00
fix(anthropic): support effort="max" and remove beta headers (#35141)
This commit is contained in:
@@ -872,7 +872,7 @@ class ChatAnthropic(BaseChatModel):
|
||||
`#!python {"type": "adaptive"}`
|
||||
"""
|
||||
|
||||
effort: Literal["high", "medium", "low"] | None = None
|
||||
effort: Literal["max", "high", "medium", "low"] | None = None
|
||||
"""Control how many tokens Claude uses when responding.
|
||||
|
||||
This parameter will be merged into the `output_config` parameter when making
|
||||
@@ -887,13 +887,8 @@ class ChatAnthropic(BaseChatModel):
|
||||
|
||||
!!! note "Model Support"
|
||||
|
||||
This feature is currently only supported by Claude Opus 4.5.
|
||||
|
||||
!!! note "Automatic beta header"
|
||||
|
||||
The required `effort-2025-11-24` beta header is
|
||||
automatically appended to the request when using `effort`, so you
|
||||
don't need to manually specify it in the `betas` parameter.
|
||||
This feature is generally available on Claude Opus 4.6 and Claude Opus 4.5.
|
||||
The `max` effort level is only supported by Claude Opus 4.6.
|
||||
"""
|
||||
|
||||
mcp_servers: list[dict[str, Any]] | None = None
|
||||
@@ -1164,16 +1159,6 @@ class ChatAnthropic(BaseChatModel):
|
||||
if output_config:
|
||||
payload["output_config"] = output_config
|
||||
|
||||
# Auto-append required beta for effort
|
||||
if "effort" in output_config:
|
||||
required_beta = "effort-2025-11-24"
|
||||
if payload["betas"]:
|
||||
# Merge with existing betas
|
||||
if required_beta not in payload["betas"]:
|
||||
payload["betas"] = [*payload["betas"], required_beta]
|
||||
else:
|
||||
payload["betas"] = [required_beta]
|
||||
|
||||
if "response_format" in payload:
|
||||
# response_format present when using agents.create_agent's ProviderStrategy
|
||||
# ---
|
||||
|
||||
@@ -2085,7 +2085,7 @@ async def test_model_profile_not_blocking() -> None:
|
||||
def test_effort_parameter_validation() -> None:
|
||||
"""Test that effort parameter is validated correctly.
|
||||
|
||||
The effort parameter is currently in beta and only supported by Claude Opus 4.5.
|
||||
The effort parameter is generally available on Claude Opus 4.6 and Opus 4.5.
|
||||
"""
|
||||
# Valid effort values should work
|
||||
model = ChatAnthropic(model="claude-opus-4-5-20251101", effort="high")
|
||||
@@ -2097,20 +2097,22 @@ def test_effort_parameter_validation() -> None:
|
||||
model = ChatAnthropic(model="claude-opus-4-5-20251101", effort="low")
|
||||
assert model.effort == "low"
|
||||
|
||||
model = ChatAnthropic(model="claude-opus-4-6", effort="max")
|
||||
assert model.effort == "max"
|
||||
|
||||
# Invalid effort values should raise ValidationError
|
||||
with pytest.raises(ValidationError, match="Input should be"):
|
||||
ChatAnthropic(model="claude-opus-4-5-20251101", effort="invalid") # type: ignore[arg-type]
|
||||
|
||||
|
||||
def test_effort_populates_betas() -> None:
|
||||
"""Test that effort parameter auto-populates required betas."""
|
||||
def test_effort_in_output_config_payload() -> None:
|
||||
"""Test that effort parameter is properly added to output_config in payload."""
|
||||
model = ChatAnthropic(model="claude-opus-4-5-20251101", effort="medium")
|
||||
assert model.effort == "medium"
|
||||
|
||||
# Test that effort works with dated API ID
|
||||
# Test that effort is added to output_config
|
||||
payload = model._get_request_payload("Test query")
|
||||
assert payload["output_config"]["effort"] == "medium"
|
||||
assert "effort-2025-11-24" in payload["betas"]
|
||||
|
||||
|
||||
def test_effort_in_output_config() -> None:
|
||||
@@ -2136,43 +2138,6 @@ def test_effort_priority() -> None:
|
||||
assert payload["output_config"]["effort"] == "high"
|
||||
|
||||
|
||||
def test_effort_beta_header_auto_append() -> None:
|
||||
"""Test that effort beta header is automatically appended."""
|
||||
# Test with top-level effort parameter
|
||||
model = ChatAnthropic(model="claude-opus-4-5-20251101", effort="medium")
|
||||
payload = model._get_request_payload("Test query")
|
||||
assert "effort-2025-11-24" in payload["betas"]
|
||||
|
||||
# Test with output_config
|
||||
model = ChatAnthropic(
|
||||
model="claude-opus-4-5-20251101",
|
||||
output_config={"effort": "low"},
|
||||
)
|
||||
payload = model._get_request_payload("Test query")
|
||||
assert "effort-2025-11-24" in payload["betas"]
|
||||
|
||||
# Test that beta is not duplicated if already present
|
||||
model = ChatAnthropic(
|
||||
model="claude-opus-4-5-20251101",
|
||||
effort="high",
|
||||
betas=["effort-2025-11-24"],
|
||||
)
|
||||
payload = model._get_request_payload("Test query")
|
||||
assert payload["betas"].count("effort-2025-11-24") == 1
|
||||
|
||||
# Test combining effort with other betas
|
||||
model = ChatAnthropic(
|
||||
model="claude-opus-4-5-20251101",
|
||||
effort="medium",
|
||||
betas=["context-1m-2025-08-07"],
|
||||
)
|
||||
payload = model._get_request_payload("Test query")
|
||||
assert set(payload["betas"]) == {
|
||||
"context-1m-2025-08-07",
|
||||
"effort-2025-11-24",
|
||||
}
|
||||
|
||||
|
||||
def test_output_config_without_effort() -> None:
|
||||
"""Test that output_config can be used without effort."""
|
||||
# output_config might have other fields in the future
|
||||
@@ -2182,10 +2147,6 @@ def test_output_config_without_effort() -> None:
|
||||
)
|
||||
payload = model._get_request_payload("Test query")
|
||||
assert payload["output_config"] == {"some_future_param": "value"}
|
||||
# No effort beta should be added
|
||||
assert payload.get("betas") is None or "effort-2025-11-24" not in payload.get(
|
||||
"betas", []
|
||||
)
|
||||
|
||||
|
||||
def test_extras_with_defer_loading() -> None:
|
||||
|
||||
Reference in New Issue
Block a user