diff --git a/litellm/llms/bedrock/chat/converse_transformation.py b/litellm/llms/bedrock/chat/converse_transformation.py index ec665142073..54fe210e35d 100644 --- a/litellm/llms/bedrock/chat/converse_transformation.py +++ b/litellm/llms/bedrock/chat/converse_transformation.py @@ -767,7 +767,7 @@ def map_openai_params( if bedrock_tier in ("default", "flex", "priority"): optional_params["serviceTier"] = {"type": bedrock_tier} - if param == "web_search_options" and value and isinstance(value, dict): + if param == "web_search_options" and isinstance(value, dict): grounding_tool = self._map_web_search_options(value, model) if grounding_tool is not None: optional_params = self._add_tools_to_optional_params( @@ -1041,10 +1041,16 @@ def _process_tools_and_beta( user_betas = get_anthropic_beta_from_headers(headers) anthropic_beta_list.extend(user_betas) - # Filter out tool search tools - Bedrock Converse API doesn't support them + # Separate pre-formatted Bedrock tools (e.g. systemTool from web_search_options) + # from OpenAI-format tools that need transformation via _bedrock_tools_pt filtered_tools = [] + pre_formatted_tools: List[ToolBlock] = [] if original_tools: for tool in original_tools: + # Already-formatted Bedrock tools (e.g. systemTool for Nova grounding) + if "systemTool" in tool: + pre_formatted_tools.append(tool) + continue tool_type = tool.get("type", "") if tool_type in ( "tool_search_tool_regex_20251119", @@ -1076,6 +1082,9 @@ def _process_tools_and_beta( # No computer use tools, process all tools as regular tools bedrock_tools = _bedrock_tools_pt(filtered_tools) + # Append pre-formatted tools (systemTool etc.) after transformation + bedrock_tools.extend(pre_formatted_tools) + # Set anthropic_beta in additional_request_params if we have any beta features # ONLY apply to Anthropic/Claude models - other models (e.g., Qwen, Llama) don't support this field # and will error with "unknown variant anthropic_beta" if included diff --git a/poetry.lock b/poetry.lock index 9ded0c773c8..9d528366e83 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.2.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. [[package]] name = "a2a-sdk" @@ -5686,6 +5686,24 @@ pytest = ">=6.2.5" [package.extras] dev = ["pre-commit", "pytest-asyncio", "tox"] +[[package]] +name = "pytest-retry" +version = "1.7.0" +description = "Adds the ability to retry flaky tests in CI environments" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pytest_retry-1.7.0-py3-none-any.whl", hash = "sha256:a2dac85b79a4e2375943f1429479c65beb6c69553e7dae6b8332be47a60954f4"}, + {file = "pytest_retry-1.7.0.tar.gz", hash = "sha256:f8d52339f01e949df47c11ba9ee8d5b362f5824dff580d3870ec9ae0057df80f"}, +] + +[package.dependencies] +pytest = ">=7.0.0" + +[package.extras] +dev = ["black", "flake8", "isort", "mypy"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -5722,9 +5740,9 @@ name = "python-multipart" version = "0.0.22" description = "A streaming multipart parser for Python" optional = true -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] -markers = "extra == \"proxy\"" +markers = "python_version >= \"3.10\" and extra == \"proxy\"" files = [ {file = "python_multipart-0.0.22-py3-none-any.whl", hash = "sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155"}, {file = "python_multipart-0.0.22.tar.gz", hash = "sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58"}, @@ -8472,4 +8490,4 @@ utils = ["numpydoc"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "73b5e1ab0badbee6c564d5e056e4f9c320c2f722bf176ce97d42e77110e37d60" +content-hash = "19a339dd5b4c21a06f7b725361a2e2692c05c56fa47e71513c5712dbdec7f61d" diff --git a/pyproject.toml b/pyproject.toml index 6c3ab08ce02..f2eee212394 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ orjson = {version = "^3.9.7", optional = true} apscheduler = {version = "^3.10.4", optional = true} fastapi-sso = { version = "^0.16.0", optional = true } PyJWT = { version = "^2.10.1", optional = true, python = ">=3.9" } -python-multipart = { version = "^0.0.22", optional = true} +python-multipart = { version = "^0.0.22", optional = true, python = ">=3.10"} cryptography = {version = "*", optional = true} prisma = {version = "0.11.0", optional = true} azure-identity = {version = "^1.15.0", optional = true, python = ">=3.9"}