mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-07 00:24:03 +00:00
feat: Make gemini accept the openai parameter parallel_tool_calls (#11125)
* feat: Make gemini accept the openai parameter parallel_tool_calls When mapping, allow the parameter: True because that is the intrinsic behavior of Gemini. Allow False, but reject if there are multiple tools because there's no actual equivalent in Gemini. fixes #9686 ref: issues/9686 * chore: cleanup and move test_vertex.py down to tests/litellm as suggested in https://github.com/BerriAI/litellm/pull/11125#discussion_r2105905871
This commit is contained in:
@@ -83,6 +83,7 @@ class GoogleAIStudioGeminiConfig(VertexGeminiConfig):
|
||||
"logprobs",
|
||||
"frequency_penalty",
|
||||
"modalities",
|
||||
"parallel_tool_calls",
|
||||
]
|
||||
if supports_reasoning(model):
|
||||
supported_params.append("reasoning_effort")
|
||||
|
||||
@@ -219,6 +219,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
||||
"logprobs",
|
||||
"top_logprobs",
|
||||
"modalities",
|
||||
"parallel_tool_calls",
|
||||
]
|
||||
if supports_reasoning(model):
|
||||
supported_params.append("reasoning_effort")
|
||||
@@ -463,6 +464,19 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
||||
)
|
||||
if _tool_choice_value is not None:
|
||||
optional_params["tool_choice"] = _tool_choice_value
|
||||
elif param == "parallel_tool_calls":
|
||||
if value is False:
|
||||
tools = non_default_params.get("tools", non_default_params.get("functions"))
|
||||
num_function_declarations = len(tools) if isinstance(tools, list) else 0
|
||||
if num_function_declarations > 1:
|
||||
raise litellm.utils.UnsupportedParamsError(
|
||||
message=(
|
||||
"`parallel_tool_calls=False` is not supported when multiple tools are "
|
||||
"provided for Gemini. Specify a single tool, or set "
|
||||
"`parallel_tool_calls=True`."
|
||||
),
|
||||
status_code=400,
|
||||
)
|
||||
elif param == "seed":
|
||||
optional_params["seed"] = value
|
||||
elif param == "reasoning_effort" and isinstance(value, str):
|
||||
|
||||
+64
-10
@@ -12,8 +12,7 @@ import litellm.litellm_core_utils.prompt_templates
|
||||
import litellm.litellm_core_utils.prompt_templates.factory
|
||||
|
||||
load_dotenv()
|
||||
import io
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
sys.path.insert(
|
||||
0, os.path.abspath("../..")
|
||||
@@ -21,10 +20,8 @@ sys.path.insert(
|
||||
import pytest
|
||||
import litellm
|
||||
from litellm import get_optional_params
|
||||
from litellm.llms.custom_httpx.http_handler import HTTPHandler
|
||||
from litellm.llms.vertex_ai.gemini.transformation import _process_gemini_image
|
||||
from litellm.types.llms.vertex_ai import PartType, BlobType
|
||||
import httpx
|
||||
from litellm.types.llms.vertex_ai import BlobType
|
||||
|
||||
|
||||
def encode_image_to_base64(image_path):
|
||||
@@ -1146,7 +1143,7 @@ def test_process_gemini_image():
|
||||
from litellm.llms.vertex_ai.gemini.transformation import (
|
||||
_process_gemini_image,
|
||||
)
|
||||
from litellm.types.llms.vertex_ai import PartType, FileDataType, BlobType
|
||||
from litellm.types.llms.vertex_ai import FileDataType
|
||||
|
||||
# Test GCS URI
|
||||
gcs_result = _process_gemini_image("gs://bucket/image.png")
|
||||
@@ -1271,10 +1268,6 @@ def test_vertex_embedding_url(model, expected_url):
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch
|
||||
from typing import Dict, Any
|
||||
|
||||
# Import your actual module here
|
||||
# from your_module import _process_gemini_image, PartType, FileDataType, BlobType
|
||||
|
||||
|
||||
# Add these fixtures below existing fixtures
|
||||
@@ -1409,3 +1402,64 @@ def test_aaavertex_embeddings_distances(
|
||||
text_embedding = text_response.data[0].embedding
|
||||
|
||||
|
||||
def test_vertex_parallel_tool_calls_true():
|
||||
"""
|
||||
Test that parallel_tool_calls = True sets the correct tool_config.
|
||||
"""
|
||||
tools = [
|
||||
{"type": "function", "function": {"name": "get_weather"}},
|
||||
{"type": "function", "function": {"name": "get_time"}},
|
||||
]
|
||||
optional_params = get_optional_params(
|
||||
model="gemini-1.5-pro",
|
||||
custom_llm_provider="vertex_ai",
|
||||
tools=tools,
|
||||
parallel_tool_calls=True,
|
||||
)
|
||||
assert "tools" in optional_params
|
||||
|
||||
|
||||
def test_vertex_parallel_tool_calls_false_multiple_tools_error():
|
||||
"""
|
||||
Test that parallel_tool_calls = False with multiple tools raises UnsupportedParamsError
|
||||
when drop_params is False.
|
||||
"""
|
||||
tools = [
|
||||
{"type": "function", "function": {"name": "get_weather"}},
|
||||
{"type": "function", "function": {"name": "get_time"}},
|
||||
]
|
||||
with pytest.raises(litellm.utils.UnsupportedParamsError) as excinfo:
|
||||
get_optional_params(
|
||||
model="gemini-1.5-pro",
|
||||
custom_llm_provider="vertex_ai",
|
||||
tools=tools,
|
||||
parallel_tool_calls=False,
|
||||
)
|
||||
assert "`parallel_tool_calls=False` is not supported when multiple tools are provided" in str(excinfo.value)
|
||||
|
||||
# works when specified as "functions"
|
||||
with pytest.raises(litellm.utils.UnsupportedParamsError) as excinfo:
|
||||
get_optional_params(
|
||||
model="gemini-1.5-pro",
|
||||
custom_llm_provider="vertex_ai",
|
||||
functions=tools,
|
||||
parallel_tool_calls=False,
|
||||
)
|
||||
assert "`parallel_tool_calls=False` is not supported when multiple tools are provided" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_vertex_parallel_tool_calls_false_single_tool():
|
||||
"""
|
||||
Test that parallel_tool_calls = False with a single tool does not raise an error
|
||||
and does not add 'tool_config' if not otherwise specified.
|
||||
"""
|
||||
tools = [
|
||||
{"type": "function", "function": {"name": "get_weather"}},
|
||||
]
|
||||
optional_params = get_optional_params(
|
||||
model="gemini-1.5-pro",
|
||||
custom_llm_provider="vertex_ai",
|
||||
tools=tools,
|
||||
parallel_tool_calls=False,
|
||||
)
|
||||
assert "tools" in optional_params
|
||||
Reference in New Issue
Block a user