Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/google/adk/models/google_llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@
"""


def _remove_function_call_ids(contents: list[types.Content]) -> None:
"""Removes unsupported function call and response ids in place."""
for content in contents:
for part in content.parts or []:
if part.function_call and part.function_call.id:
part.function_call.id = None
if part.function_response and part.function_response.id:
part.function_response.id = None


class _ResourceExhaustedError(ClientError):
"""Represents a resources exhausted error received from the Model."""

Expand Down Expand Up @@ -235,6 +245,9 @@ async def generate_content_async(
if model is None:
raise ValueError('Gemini requests require a model name.')

if not self.use_interactions_api:
_remove_function_call_ids(llm_request.contents)

# Handle context caching if configured
cache_metadata = None
cache_manager = None
Expand Down
55 changes: 55 additions & 0 deletions tests/unittests/models/test_google_llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,61 @@ async def mock_coro():
mock_client.aio.models.generate_content.assert_called_once()


@pytest.mark.asyncio
async def test_generate_content_async_strips_model_function_call_ids(
gemini_llm, generate_content_response
):
"""generateContent omits model-supplied function ids."""
function_call_id = "call_240342"
llm_request = LlmRequest(
model="gemini-2.5-flash",
contents=[
Content(
role="model",
parts=[
Part(
function_call=types.FunctionCall(
id=function_call_id,
name="test_tool",
args={"x": 1},
)
)
],
),
Content(
role="user",
parts=[
Part(
function_response=types.FunctionResponse(
id=function_call_id,
name="test_tool",
response={"result": 2},
)
)
],
),
],
)

with mock.patch.object(gemini_llm, "api_client") as mock_client:

async def mock_coro():
return generate_content_response

mock_client.aio.models.generate_content.return_value = mock_coro()

_ = [
response
async for response in gemini_llm.generate_content_async(llm_request)
]

sent_contents = mock_client.aio.models.generate_content.call_args.kwargs[
"contents"
]
assert sent_contents[0].parts[0].function_call.id is None
assert sent_contents[1].parts[0].function_response.id is None


@pytest.mark.asyncio
async def test_generate_content_async_stream(gemini_llm, llm_request):
with mock.patch.object(gemini_llm, "api_client") as mock_client:
Expand Down
Loading