From 8b771ebe4e06da6746f0def551de667969e4a703 Mon Sep 17 00:00:00 2001 From: milo Date: Fri, 22 May 2026 21:28:51 +0800 Subject: [PATCH] fix(bedrock): parse tool_call text tags --- .../bedrock/chat/converse_transformation.py | 19 ++++++++++++++++++ .../chat/test_converse_transformation.py | 20 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/litellm/llms/bedrock/chat/converse_transformation.py b/litellm/llms/bedrock/chat/converse_transformation.py index 14d4835d332..5e46b8103c0 100644 --- a/litellm/llms/bedrock/chat/converse_transformation.py +++ b/litellm/llms/bedrock/chat/converse_transformation.py @@ -1815,6 +1815,24 @@ class AmazonConverseConfig(BaseConfig): return None + def _parse_tool_call_tag_text_tool_call( + self, content: str + ) -> Tuple[Optional[str], dict[str, Any]]: + tool_call_match = re.search( + r"(.*?)", content, re.DOTALL | re.IGNORECASE + ) + if tool_call_match is None: + return None, {} + + tool_call = self._parse_tool_call_json_arguments(tool_call_match.group(1).strip()) + tool_name = tool_call.get("name") + arguments = tool_call.get("arguments", {}) + if not isinstance(tool_name, str): + return None, {} + if not isinstance(arguments, dict): + return None, {} + return tool_name, arguments + def _parse_function_text_tool_call( self, content: str ) -> Tuple[Optional[str], dict[str, Any]]: @@ -1895,6 +1913,7 @@ class AmazonConverseConfig(BaseConfig): return None parsers = ( + self._parse_tool_call_tag_text_tool_call, self._parse_function_text_tool_call, self._parse_tool_use_text_tool_call, self._parse_bare_text_tool_call, diff --git a/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py b/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py index 932572c36b8..ba81d90ca0c 100644 --- a/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py +++ b/tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py @@ -305,6 +305,26 @@ def test_apply_tool_call_transformation_parses_bare_tool_name_json_text(): _assert_read_file_tool_call(transformed_message, finish_reason) +def test_apply_tool_call_transformation_parses_tool_call_json_tag_text(): + from litellm.types.utils import Message + + config = AmazonConverseConfig() + message = Message( + role="assistant", + content=( + "I'll call the read_file tool immediately as instructed.\n\n" + '\n{"name": "read_file", "arguments": {"path": "C:\\\\Projects\\\\redaigo\\\\scripts\\\\run_etf_v13.py", "offset": 0, "length": 3000}}\n\n\n' + "" + ), + ) + + transformed_message, finish_reason = config.apply_tool_call_transformation_if_needed( + message, _read_file_tool(), initial_finish_reason="stop" + ) + + _assert_read_file_tool_call(transformed_message, finish_reason) + + def test_apply_tool_call_transformation_ignores_text_for_unknown_tool_name(): from litellm.types.utils import Message