mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
fix(google_genai): read functionDeclarations.parameters in the generateContent bridge
The generate_content -> chat/completions bridge only read functionDeclarations[].parametersJsonSchema, the field gemini-cli sends. The google-genai SDKs serialize tool schemas to `parameters`, so those requests reached the upstream provider with a function that had a name and description but no arguments, and the model invented its own. Fall back to `parameters` when `parametersJsonSchema` is absent, and declare it on _GenAIFunctionDeclaration.
This commit is contained in:
parent
a0f367fcd1
commit
7871a9d2a3
2 changed files with 85 additions and 0 deletions
|
|
@ -47,6 +47,7 @@ class _GenAIPart(TypedDict, total=False):
|
|||
class _GenAIFunctionDeclaration(TypedDict, total=False):
|
||||
name: ReadOnly[str]
|
||||
description: ReadOnly[str]
|
||||
parameters: ReadOnly[dict[str, object]]
|
||||
parametersJsonSchema: ReadOnly[dict[str, object]]
|
||||
|
||||
|
||||
|
|
@ -359,6 +360,8 @@ class GoogleGenAIAdapter:
|
|||
function_chunk["description"] = func_decl["description"]
|
||||
if "parametersJsonSchema" in func_decl:
|
||||
function_chunk["parameters"] = func_decl["parametersJsonSchema"]
|
||||
elif "parameters" in func_decl:
|
||||
function_chunk["parameters"] = func_decl["parameters"]
|
||||
|
||||
openai_tool: dict[str, object] = {"type": "function", "function": function_chunk}
|
||||
openai_tools.append(openai_tool)
|
||||
|
|
|
|||
|
|
@ -1276,3 +1276,85 @@ def test_inline_data_backward_compatibility_text_only():
|
|||
content, str
|
||||
), "Content should be a string for text-only messages (backward compatibility)"
|
||||
assert content == "Hello, how are you?"
|
||||
|
||||
|
||||
def test_tools_transformation_parameters_field():
|
||||
"""FunctionDeclaration.parameters must survive the generate_content -> completion bridge.
|
||||
|
||||
The google-genai SDKs serialize tool schemas to `parameters`; only gemini-cli
|
||||
sends `parametersJsonSchema`. Reading just the latter silently dropped the
|
||||
schema, so the upstream model received a function with no arguments.
|
||||
"""
|
||||
from litellm.google_genai.adapters.transformation import GoogleGenAIAdapter
|
||||
|
||||
adapter = GoogleGenAIAdapter()
|
||||
|
||||
schema = {
|
||||
"type": "OBJECT",
|
||||
"properties": {"city": {"type": "STRING", "description": "City name"}},
|
||||
"required": ["city"],
|
||||
}
|
||||
tools = [
|
||||
{
|
||||
"functionDeclarations": [
|
||||
{
|
||||
"name": "get_weather",
|
||||
"description": "Get the weather for a city",
|
||||
"parameters": schema,
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
completion_request = adapter.translate_generate_content_to_completion(
|
||||
model="gpt-3.5-turbo",
|
||||
contents={"role": "user", "parts": [{"text": "Weather in Hanoi?"}]},
|
||||
tools=tools,
|
||||
)
|
||||
|
||||
function = completion_request["tools"][0]["function"]
|
||||
assert function["name"] == "get_weather"
|
||||
assert function["parameters"] == {
|
||||
"type": "object",
|
||||
"properties": {"city": {"type": "string", "description": "City name"}},
|
||||
"required": ["city"],
|
||||
}
|
||||
|
||||
|
||||
def test_tools_transformation_prefers_parameters_json_schema():
|
||||
"""When both fields are present, parametersJsonSchema wins."""
|
||||
from litellm.google_genai.adapters.transformation import GoogleGenAIAdapter
|
||||
|
||||
adapter = GoogleGenAIAdapter()
|
||||
|
||||
tools = [
|
||||
{
|
||||
"functionDeclarations": [
|
||||
{
|
||||
"name": "get_weather",
|
||||
"parameters": {
|
||||
"type": "OBJECT",
|
||||
"properties": {"ignored": {"type": "STRING"}},
|
||||
},
|
||||
"parametersJsonSchema": {
|
||||
"type": "object",
|
||||
"properties": {"city": {"type": "string"}},
|
||||
"required": ["city"],
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
completion_request = adapter.translate_generate_content_to_completion(
|
||||
model="gpt-3.5-turbo",
|
||||
contents={"role": "user", "parts": [{"text": "Weather in Hanoi?"}]},
|
||||
tools=tools,
|
||||
)
|
||||
|
||||
function = completion_request["tools"][0]["function"]
|
||||
assert function["parameters"] == {
|
||||
"type": "object",
|
||||
"properties": {"city": {"type": "string"}},
|
||||
"required": ["city"],
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue