mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
Guard namespace tools without schemas
This commit is contained in:
parent
1e1f377e3c
commit
816e86b79d
4 changed files with 40 additions and 2 deletions
|
|
@ -680,6 +680,13 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
f"Gemini: Transforming OpenAI-style '{tool['type']}' tool to googleSearch"
|
||||
)
|
||||
tool = {VertexToolName.GOOGLE_SEARCH.value: {}}
|
||||
elif tool.get("type") == "namespace" and (
|
||||
not tool.get("description") or not tool.get("parameters")
|
||||
):
|
||||
raise ValueError(
|
||||
"Namespace tools require description and parameters before "
|
||||
"converting to Gemini function declarations"
|
||||
)
|
||||
# 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"}
|
||||
|
|
|
|||
|
|
@ -1388,6 +1388,14 @@ class LiteLLMCompletionResponsesConfig:
|
|||
)
|
||||
elif tool.get("type") in ("function", "namespace"):
|
||||
typed_tool = cast(FunctionToolParam, tool)
|
||||
if tool.get("type") == "namespace" and (
|
||||
not typed_tool.get("description")
|
||||
or not typed_tool.get("parameters")
|
||||
):
|
||||
raise ValueError(
|
||||
"Responses API namespace tools require description and "
|
||||
"parameters before converting to Chat Completion tools"
|
||||
)
|
||||
# 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,6 +2917,16 @@ 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():
|
||||
v = VertexGeminiConfig()
|
||||
|
||||
with pytest.raises(ValueError, match="Namespace tools require description"):
|
||||
v._map_function(
|
||||
value=[{"type": "namespace", "name": "mcp__node_repl"}],
|
||||
optional_params={},
|
||||
)
|
||||
|
||||
|
||||
def test_vertex_ai_single_tool_type_still_works():
|
||||
"""
|
||||
Test that single tool type usage still works correctly (backward compatibility).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(
|
||||
0, os.path.abspath("../../..")
|
||||
) # Adds the parent directory to the system path
|
||||
|
|
@ -1222,11 +1224,22 @@ class TestToolTransformation:
|
|||
assert result_tool["type"] == "function"
|
||||
assert result_tool["function"]["name"] == "mcp__node_repl"
|
||||
assert (
|
||||
result_tool["function"]["description"]
|
||||
== "Run JavaScript in the node REPL"
|
||||
result_tool["function"]["description"] == "Run JavaScript in the node REPL"
|
||||
)
|
||||
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."""
|
||||
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]
|
||||
)
|
||||
|
||||
def test_transform_code_execution_tools(self):
|
||||
"""Test that code_execution tools are passed through as-is"""
|
||||
code_execution_tool = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue