mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix(gemini): send googleMaps retrievalConfig in the request body
VertexGeminiConfig._map_function extracts latitude/longitude from a googleMaps tool into optional_params["toolConfig"]["retrievalConfig"], but _transform_request_body only built toolConfig from tool_choice, so the location never reached Google and Maps grounding ran without it Pop toolConfig from optional_params and merge it with tool_choice. Type retrievalConfig on ToolConfig
This commit is contained in:
parent
ca9007be39
commit
9e523dff45
3 changed files with 75 additions and 2 deletions
|
|
@ -1191,6 +1191,7 @@ def _transform_request_body(
|
|||
)
|
||||
tools: Final[Tools | None] = optional_params.pop("tools", None)
|
||||
tool_choice: Final[ToolConfig | None] = optional_params.pop("tool_choice", None)
|
||||
tool_config: Final[ToolConfig | None] = optional_params.pop("toolConfig", None)
|
||||
include_server_side_tool_invocations: bool = optional_params.pop("include_server_side_tool_invocations", False)
|
||||
safety_settings: list[SafetSettingsConfig] | None = optional_params.pop("safety_settings", None)
|
||||
# Drop output_config as it's not supported by Vertex AI
|
||||
|
|
@ -1223,8 +1224,15 @@ def _transform_request_body(
|
|||
data["system_instruction"] = system_instructions
|
||||
if tools is not None:
|
||||
data["tools"] = tools
|
||||
if tool_choice is not None:
|
||||
data["toolConfig"] = tool_choice
|
||||
merged_tool_config: Final[ToolConfig | None] = (
|
||||
{**tool_config, **tool_choice}
|
||||
if tool_config is not None and tool_choice is not None
|
||||
else tool_config
|
||||
if tool_config is not None
|
||||
else tool_choice
|
||||
)
|
||||
if merged_tool_config is not None:
|
||||
data["toolConfig"] = merged_tool_config
|
||||
if include_server_side_tool_invocations:
|
||||
if "toolConfig" not in data:
|
||||
data["toolConfig"] = {}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from enum import Enum
|
|||
from typing import Any, Final, Literal, Protocol
|
||||
|
||||
from typing_extensions import (
|
||||
ReadOnly,
|
||||
Required,
|
||||
TypedDict,
|
||||
)
|
||||
|
|
@ -278,9 +279,20 @@ class Tools(TypedDict, total=False):
|
|||
retrieval: Retrieval
|
||||
|
||||
|
||||
class LatLng(TypedDict):
|
||||
latitude: ReadOnly[float]
|
||||
longitude: ReadOnly[float]
|
||||
|
||||
|
||||
class RetrievalConfig(TypedDict, total=False):
|
||||
latLng: ReadOnly[LatLng]
|
||||
languageCode: ReadOnly[str]
|
||||
|
||||
|
||||
class ToolConfig(TypedDict, total=False):
|
||||
functionCallingConfig: FunctionCallingConfig
|
||||
includeServerSideToolInvocations: bool
|
||||
retrievalConfig: ReadOnly[RetrievalConfig]
|
||||
|
||||
|
||||
class TTL(TypedDict, total=False):
|
||||
|
|
|
|||
|
|
@ -338,3 +338,56 @@ def test_map_function_enterprise_web_search_snake_case():
|
|||
|
||||
assert len(result) == 1
|
||||
assert "enterpriseWebSearch" in result[0]
|
||||
|
||||
|
||||
def test__transform_request_body_google_maps_retrieval_config_is_sent():
|
||||
"""
|
||||
googleMaps latitude/longitude are extracted into optional_params["toolConfig"]["retrievalConfig"]
|
||||
by VertexGeminiConfig._map_function. That toolConfig must reach the request body, otherwise
|
||||
Google grounds without a location.
|
||||
"""
|
||||
optional_params = {}
|
||||
tools = VertexGeminiConfig()._map_function(
|
||||
value=[{"googleMaps": {"latitude": 37.7749, "longitude": -122.4194}}],
|
||||
optional_params=optional_params,
|
||||
)
|
||||
optional_params["tools"] = tools
|
||||
|
||||
rb: RequestBody = transformation._transform_request_body(
|
||||
messages=[{"role": "user", "content": "coffee near me"}],
|
||||
model="gemini-3-flash-preview",
|
||||
optional_params=optional_params,
|
||||
custom_llm_provider="gemini",
|
||||
litellm_params={},
|
||||
cached_content=None,
|
||||
)
|
||||
|
||||
assert rb["tools"] == [{"googleMaps": {}}]
|
||||
assert rb["toolConfig"] == {"retrievalConfig": {"latLng": {"latitude": 37.7749, "longitude": -122.4194}}}
|
||||
|
||||
|
||||
def test__transform_request_body_tool_config_merges_with_tool_choice():
|
||||
"""
|
||||
A googleMaps retrievalConfig and a function-calling tool_choice both live under toolConfig;
|
||||
neither should clobber the other.
|
||||
"""
|
||||
optional_params = {
|
||||
"toolConfig": {"retrievalConfig": {"latLng": {"latitude": 1.0, "longitude": 2.0}}},
|
||||
"tool_choice": {"functionCallingConfig": {"mode": "AUTO"}},
|
||||
"include_server_side_tool_invocations": True,
|
||||
}
|
||||
|
||||
rb: RequestBody = transformation._transform_request_body(
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
model="gemini-3-flash-preview",
|
||||
optional_params=optional_params,
|
||||
custom_llm_provider="gemini",
|
||||
litellm_params={},
|
||||
cached_content=None,
|
||||
)
|
||||
|
||||
assert rb["toolConfig"] == {
|
||||
"retrievalConfig": {"latLng": {"latitude": 1.0, "longitude": 2.0}},
|
||||
"functionCallingConfig": {"mode": "AUTO"},
|
||||
"includeServerSideToolInvocations": True,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue