Fix responses tool conversion for chat bridge

Co-authored-by: ishaan-berri <ishaan-berri@users.noreply.github.com>
This commit is contained in:
oss-agent-shin 2026-05-06 04:40:42 +00:00
parent bd1ea0252a
commit 78b773f5ae
No known key found for this signature in database
2 changed files with 71 additions and 4 deletions

View file

@ -1384,17 +1384,31 @@ class LiteLLMCompletionResponsesConfig:
)
elif tool.get("type") == "function":
typed_tool = cast(FunctionToolParam, tool)
function_dict = cast(Dict[str, Any], tool.get("function") or {})
# Ensure parameters has "type": "object" as required by providers like Anthropic
parameters = dict(typed_tool.get("parameters", {}) or {})
parameters = dict(
function_dict.get("parameters")
or typed_tool.get("parameters", {})
or {}
)
if not parameters or "type" not in parameters:
parameters["type"] = "object"
strict = (
function_dict.get("strict")
if function_dict.get("strict") is not None
else typed_tool.get("strict", False)
)
chat_completion_tool: Dict[str, Any] = {
"type": "function",
"function": {
"name": typed_tool.get("name") or "",
"description": typed_tool.get("description") or "",
"name": function_dict.get("name")
or typed_tool.get("name")
or "",
"description": function_dict.get("description")
or typed_tool.get("description")
or "",
"parameters": parameters,
"strict": typed_tool.get("strict", False) or False,
"strict": strict or False,
},
}
if tool.get("cache_control"):
@ -1408,6 +1422,8 @@ class LiteLLMCompletionResponsesConfig:
chat_completion_tools.append(
cast(ChatCompletionToolParam, chat_completion_tool)
)
elif tool.get("type") in {"custom", "shell"}:
continue
else:
chat_completion_tools.append(
cast(Union[ChatCompletionToolParam, OpenAIMcpServerTool], tool)

View file

@ -1189,6 +1189,57 @@ class TestToolTransformation:
assert "allowed_callers" not in result_tool
assert "input_examples" not in result_tool
def test_transform_function_tools_reads_chat_completion_style_function_fields(self):
"""Chat Completion-style nested function tools should keep their metadata."""
function_tool = {
"type": "function",
"function": {
"name": "read",
"description": "Read a file",
"parameters": {
"type": "object",
"properties": {"path": {"type": "string"}},
},
"strict": True,
},
}
(
result_tools,
_,
) = LiteLLMCompletionResponsesConfig.transform_responses_api_tools_to_chat_completion_tools(
tools=[function_tool]
)
assert len(result_tools) == 1
result_tool = result_tools[0]
assert result_tool["type"] == "function"
assert result_tool["function"] == function_tool["function"]
def test_transform_unsupported_responses_api_tool_types_are_dropped(self):
"""Responses-only tool types should not be forwarded to Chat Completions APIs."""
tools = [
{"type": "custom", "name": "shell", "description": "Run shell commands"},
{"type": "shell", "name": "shell"},
{
"type": "function",
"name": "get_weather",
"description": "Get weather",
"parameters": {"type": "object"},
},
]
(
result_tools,
_,
) = LiteLLMCompletionResponsesConfig.transform_responses_api_tools_to_chat_completion_tools(
tools=tools
)
assert len(result_tools) == 1
assert result_tools[0]["type"] == "function"
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"""
code_execution_tool = {