mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(router): support Anthropic web_search and web_fetch tool capability filtering
Fixes #38982 Signed-off-by: Liang Xu <lx3133584@users.noreply.github.com>
This commit is contained in:
parent
ec3f8183c3
commit
1f6c0e4e98
2 changed files with 75 additions and 8 deletions
|
|
@ -163,6 +163,26 @@ def filter_team_based_models(
|
|||
]
|
||||
|
||||
|
||||
def _is_web_search_tool(tool: dict) -> bool:
|
||||
tool_type = str(tool.get("type") or "")
|
||||
tool_name = str(tool.get("name") or "")
|
||||
return (
|
||||
tool_type in ("web_search", "web_search_preview")
|
||||
or tool_type.startswith("web_search_")
|
||||
or tool_name == "web_search"
|
||||
)
|
||||
|
||||
|
||||
def _is_web_fetch_tool(tool: dict) -> bool:
|
||||
tool_type = str(tool.get("type") or "")
|
||||
tool_name = str(tool.get("name") or "")
|
||||
return (
|
||||
tool_type in ("web_fetch", "web_fetch_preview")
|
||||
or tool_type.startswith("web_fetch_")
|
||||
or tool_name == "web_fetch"
|
||||
)
|
||||
|
||||
|
||||
def _deployment_supports_web_search(deployment: dict) -> bool:
|
||||
"""
|
||||
Check if a deployment supports web search.
|
||||
|
|
@ -183,12 +203,28 @@ def _deployment_supports_web_search(deployment: dict) -> bool:
|
|||
return True
|
||||
|
||||
|
||||
def _deployment_supports_web_fetch(deployment: dict) -> bool:
|
||||
"""
|
||||
Check if a deployment supports web fetch.
|
||||
|
||||
Priority:
|
||||
1. Check config-level override in model_info.supports_web_fetch
|
||||
2. Default to True (assume supported unless explicitly disabled)
|
||||
"""
|
||||
model_info: Final = deployment.get("model_info", {})
|
||||
|
||||
if "supports_web_fetch" in model_info:
|
||||
return model_info["supports_web_fetch"]
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def filter_web_search_deployments(
|
||||
healthy_deployments: list[dict] | dict,
|
||||
request_kwargs: dict | None = None,
|
||||
) -> list[dict] | dict:
|
||||
"""
|
||||
If the request is websearch, filter out deployments that don't support web search
|
||||
If the request is websearch or webfetch, filter out deployments that don't support it
|
||||
"""
|
||||
if request_kwargs is None:
|
||||
return healthy_deployments
|
||||
|
|
@ -198,20 +234,32 @@ def filter_web_search_deployments(
|
|||
return healthy_deployments
|
||||
|
||||
is_web_search_request = False
|
||||
is_web_fetch_request = False
|
||||
tools: Final = request_kwargs.get("tools") or []
|
||||
for tool in tools:
|
||||
# These are the two websearch tools for OpenAI / Azure.
|
||||
if tool.get("type") == "web_search" or tool.get("type") == "web_search_preview":
|
||||
if not isinstance(tool, dict):
|
||||
continue
|
||||
if _is_web_search_tool(tool):
|
||||
is_web_search_request = True
|
||||
break
|
||||
if _is_web_fetch_tool(tool):
|
||||
is_web_fetch_request = True
|
||||
|
||||
if not is_web_search_request:
|
||||
if not is_web_search_request and not is_web_fetch_request:
|
||||
return healthy_deployments
|
||||
|
||||
final_deployments = healthy_deployments
|
||||
# Filter out deployments that don't support web search
|
||||
final_deployments: Final = [d for d in healthy_deployments if _deployment_supports_web_search(d)]
|
||||
if len(healthy_deployments) > 0 and len(final_deployments) == 0:
|
||||
verbose_logger.warning("No deployments support web search for request")
|
||||
if is_web_search_request:
|
||||
final_deployments = [d for d in final_deployments if _deployment_supports_web_search(d)]
|
||||
if len(healthy_deployments) > 0 and len(final_deployments) == 0:
|
||||
verbose_logger.warning("No deployments support web search for request")
|
||||
|
||||
# Filter out deployments that don't support web fetch
|
||||
if is_web_fetch_request:
|
||||
final_deployments = [d for d in final_deployments if _deployment_supports_web_fetch(d)]
|
||||
if len(healthy_deployments) > 0 and len(final_deployments) == 0:
|
||||
verbose_logger.warning("No deployments support web fetch for request")
|
||||
|
||||
return final_deployments
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -352,6 +352,25 @@ class TestFilterWebSearchDeployments:
|
|||
# Should return the dict unchanged, not filter it
|
||||
assert result == deployment
|
||||
|
||||
def test_anthropic_versioned_web_search_filters_unsupported(self, sample_deployments):
|
||||
"""Anthropic versioned web_search tool types (e.g. web_search_20250305) should filter unsupported deployments"""
|
||||
request_kwargs = {"tools": [{"type": "web_search_20250305", "name": "web_search"}]}
|
||||
result = filter_web_search_deployments(sample_deployments, request_kwargs)
|
||||
assert len(result) == 2
|
||||
result_ids = [d["model_info"]["id"] for d in result]
|
||||
assert "deployment-3" not in result_ids
|
||||
|
||||
def test_anthropic_web_fetch_filters_unsupported(self):
|
||||
"""Anthropic web_fetch tool types (e.g. web_fetch_20250910) should filter out supports_web_fetch=False deployments"""
|
||||
deployments = [
|
||||
{"model_info": {"id": "d1", "supports_web_fetch": True}},
|
||||
{"model_info": {"id": "d2", "supports_web_fetch": False}},
|
||||
]
|
||||
request_kwargs = {"tools": [{"type": "web_fetch_20250910", "name": "web_fetch"}]}
|
||||
result = filter_web_search_deployments(deployments, request_kwargs)
|
||||
assert len(result) == 1
|
||||
assert result[0]["model_info"]["id"] == "d1"
|
||||
|
||||
|
||||
def test_invalidate_model_group_info_cache():
|
||||
"""Test that _invalidate_model_group_info_cache clears the LRU cache."""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue