mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
Skip name-only namespace tools
This commit is contained in:
parent
3ebfa8fa41
commit
f42804995b
4 changed files with 51 additions and 16 deletions
|
|
@ -683,7 +683,11 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
elif tool.get("type") == "namespace" and (
|
||||
not tool.get("description") or not tool.get("parameters")
|
||||
):
|
||||
raise ValueError("Namespace tools require description and parameters")
|
||||
verbose_logger.warning(
|
||||
"Skipping namespace tool without description or parameters: %s",
|
||||
tool.get("name"),
|
||||
)
|
||||
continue
|
||||
# Handle tools with 'type' field (OpenAI spec compliance) Ignore this field -> https://github.com/BerriAI/litellm/issues/14644#issuecomment-3342061838
|
||||
elif "type" in tool:
|
||||
tool = {k: tool[k] for k in tool if k != "type"}
|
||||
|
|
|
|||
|
|
@ -1392,9 +1392,7 @@ class LiteLLMCompletionResponsesConfig:
|
|||
not typed_tool.get("description")
|
||||
or not typed_tool.get("parameters")
|
||||
):
|
||||
raise ValueError(
|
||||
"Namespace tools require description and parameters"
|
||||
)
|
||||
continue
|
||||
# Ensure parameters has "type": "object" as required by providers like Anthropic
|
||||
parameters = dict(typed_tool.get("parameters", {}) or {})
|
||||
if not parameters or "type" not in parameters:
|
||||
|
|
|
|||
|
|
@ -2917,14 +2917,15 @@ def test_vertex_ai_function_declarations_with_other_tools_separate():
|
|||
assert func_tool["function_declarations"][0]["name"] == "get_weather"
|
||||
|
||||
|
||||
def test_vertex_ai_namespace_tool_without_schema_raises():
|
||||
def test_vertex_ai_namespace_tool_without_schema_skips():
|
||||
v = VertexGeminiConfig()
|
||||
|
||||
with pytest.raises(ValueError, match="Namespace tools require description"):
|
||||
v._map_function(
|
||||
value=[{"type": "namespace", "name": "mcp__node_repl"}],
|
||||
optional_params={},
|
||||
)
|
||||
tools = v._map_function(
|
||||
value=[{"type": "namespace", "name": "mcp__node_repl"}],
|
||||
optional_params={},
|
||||
)
|
||||
|
||||
assert tools == []
|
||||
|
||||
|
||||
def test_vertex_ai_single_tool_type_still_works():
|
||||
|
|
|
|||
|
|
@ -1228,17 +1228,49 @@ class TestToolTransformation:
|
|||
)
|
||||
assert result_tool["function"]["parameters"] == namespace_tool["parameters"]
|
||||
|
||||
def test_transform_namespace_tools_without_schema_raises(self):
|
||||
"""Name-only namespace tools cannot be converted into usable functions."""
|
||||
def test_transform_namespace_tools_without_schema_skips(self):
|
||||
"""Name-only namespace tools are skipped instead of becoming hollow functions."""
|
||||
namespace_tool = {
|
||||
"type": "namespace",
|
||||
"name": "mcp__node_repl",
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError, match="Namespace tools require description"):
|
||||
LiteLLMCompletionResponsesConfig.transform_responses_api_tools_to_chat_completion_tools(
|
||||
tools=[namespace_tool]
|
||||
)
|
||||
(
|
||||
result_tools,
|
||||
web_search_options,
|
||||
) = LiteLLMCompletionResponsesConfig.transform_responses_api_tools_to_chat_completion_tools(
|
||||
tools=[namespace_tool]
|
||||
)
|
||||
|
||||
assert result_tools == []
|
||||
assert web_search_options is None
|
||||
|
||||
def test_transform_namespace_tools_without_schema_keeps_other_tools(self):
|
||||
"""Skipping name-only namespace tools should not abort the whole request."""
|
||||
function_tool = {
|
||||
"type": "function",
|
||||
"name": "get_weather",
|
||||
"description": "Get weather",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {"location": {"type": "string"}},
|
||||
},
|
||||
}
|
||||
namespace_tool = {
|
||||
"type": "namespace",
|
||||
"name": "mcp__node_repl",
|
||||
}
|
||||
|
||||
(
|
||||
result_tools,
|
||||
web_search_options,
|
||||
) = LiteLLMCompletionResponsesConfig.transform_responses_api_tools_to_chat_completion_tools(
|
||||
tools=[namespace_tool, function_tool]
|
||||
)
|
||||
|
||||
assert web_search_options is None
|
||||
assert len(result_tools) == 1
|
||||
assert result_tools[0]["function"]["name"] == "get_weather"
|
||||
|
||||
def test_transform_code_execution_tools(self):
|
||||
"""Test that code_execution tools are passed through as-is"""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue