diff --git a/libs/aws/langchain_aws/chat_models/bedrock.py b/libs/aws/langchain_aws/chat_models/bedrock.py index 186b2b7b..43649a73 100644 --- a/libs/aws/langchain_aws/chat_models/bedrock.py +++ b/libs/aws/langchain_aws/chat_models/bedrock.py @@ -1231,7 +1231,12 @@ def bind_tools( base_model = self._get_base_model() if any( x in base_model - for x in ("claude-3-7-", "claude-opus-4-", "claude-sonnet-4-") + for x in ( + "claude-3-7-", + "claude-opus-4-", + "claude-sonnet-4-", + "claude-haiku-4-", + ) ) and thinking_in_params(self.model_kwargs or {}): forced = False if isinstance(tool_choice, bool): diff --git a/libs/aws/langchain_aws/chat_models/bedrock_converse.py b/libs/aws/langchain_aws/chat_models/bedrock_converse.py index 6b461647..3167993f 100644 --- a/libs/aws/langchain_aws/chat_models/bedrock_converse.py +++ b/libs/aws/langchain_aws/chat_models/bedrock_converse.py @@ -759,6 +759,7 @@ def validate_environment(self) -> Self: "claude-3-7-sonnet", "claude-sonnet-4", "claude-opus-4", + "claude-haiku-4", ) thinking_params = (self.additional_model_request_fields or {}).get( "thinking", {} @@ -977,9 +978,15 @@ def _get_llm_for_structured_output_no_tool_choice( "langchain_core.exceptions.OutputParserException if tool calls are not " "generated. Consider adjusting your prompt to ensure the tool is called." ) - if "claude-3-7-sonnet" in self._get_base_model(): + thinking_claude_models = ( + "claude-3-7-sonnet", + "claude-sonnet-4", + "claude-opus-4", + "claude-haiku-4", + ) + if any(model in self._get_base_model() for model in thinking_claude_models): additional_context = ( - "For Claude 3.7 Sonnet models, you can also support forced tool use " + "For Claude 3/4 models, you can also support forced tool use " "by disabling `thinking`." ) admonition = f"{admonition} {additional_context}" @@ -1066,6 +1073,7 @@ def with_structured_output( "claude-3-7-sonnet", "claude-sonnet-4", "claude-opus-4", + "claude-haiku-4", ) if tool_choice is None and any( model in self._get_base_model() for model in thinking_claude_models diff --git a/libs/aws/langchain_aws/utils.py b/libs/aws/langchain_aws/utils.py index c44534b2..355cac58 100644 --- a/libs/aws/langchain_aws/utils.py +++ b/libs/aws/langchain_aws/utils.py @@ -96,7 +96,13 @@ def anthropic_tokens_supported() -> bool: def count_tokens_api_supported_for_model(model: str) -> bool: return any( x in model - for x in ("claude-3-5-", "claude-3-7-", "claude-opus-4-", "claude-sonnet-4-") + for x in ( + "claude-3-5-", + "claude-3-7-", + "claude-opus-4-", + "claude-sonnet-4-", + "claude-haiku-4-", + ) ) diff --git a/libs/aws/tests/integration_tests/chat_models/test_bedrock_converse.py b/libs/aws/tests/integration_tests/chat_models/test_bedrock_converse.py index cefc0432..7cc6b416 100644 --- a/libs/aws/tests/integration_tests/chat_models/test_bedrock_converse.py +++ b/libs/aws/tests/integration_tests/chat_models/test_bedrock_converse.py @@ -431,6 +431,10 @@ def test_guardrails() -> None: "us.anthropic.claude-3-7-sonnet-20250219-v1:0", "us.anthropic.claude-sonnet-4-20250514-v1:0", "us.anthropic.claude-opus-4-20250514-v1:0", + "us.anthropic.claude-opus-4-1-20250805-v1:0", + "us.anthropic.claude-sonnet-4-5-20250929-v1:0", + # + # "us.anthropic.claude-haiku-4-5-20251001-v1:0", ], ) def test_structured_output_tool_choice_not_supported(thinking_model: str) -> None: diff --git a/libs/aws/tests/unit_tests/chat_models/test_bedrock_converse.py b/libs/aws/tests/unit_tests/chat_models/test_bedrock_converse.py index 422434f9..bc678195 100644 --- a/libs/aws/tests/unit_tests/chat_models/test_bedrock_converse.py +++ b/libs/aws/tests/unit_tests/chat_models/test_bedrock_converse.py @@ -120,6 +120,7 @@ def test_anthropic_bind_tools_tool_choice() -> None: "anthropic.claude-3-7-sonnet-20250219-v1:0", "anthropic.claude-sonnet-4-20250514-v1:0", "anthropic.claude-opus-4-20250514-v1:0", + "anthropic.claude-haiku-4-5-20251001-v1:0", ], ) def test_anthropic_thinking_bind_tools_tool_choice(thinking_model: str) -> None: diff --git a/libs/aws/tests/unit_tests/test_utils.py b/libs/aws/tests/unit_tests/test_utils.py index 4206ea63..6fa6054b 100644 --- a/libs/aws/tests/unit_tests/test_utils.py +++ b/libs/aws/tests/unit_tests/test_utils.py @@ -435,6 +435,7 @@ def test_trim_message_whitespace_with_empty_messages() -> None: @pytest.mark.parametrize( "model_id,expected_result", [ + ("us.anthropic.claude-haiku-4-5-20251001-v1:0", True), ("us.anthropic.claude-opus-4-20250514-v1:0", True), ("us.anthropic.claude-sonnet-4-20250514-v1:0", True), ("us.anthropic.claude-3-7-sonnet-20250219-v1:0", True),