diff --git a/src/google/adk/models/lite_llm.py b/src/google/adk/models/lite_llm.py index 1eb902630f..ca04c4d71d 100644 --- a/src/google/adk/models/lite_llm.py +++ b/src/google/adk/models/lite_llm.py @@ -149,6 +149,7 @@ # https://ai.google.dev/gemini-api/docs/thought-signatures _THOUGHT_SIGNATURE_SEPARATOR = "__thought__" + _LITELLM_IMPORTED = False _LITELLM_GLOBAL_SYMBOLS = ( "ChatCompletionAssistantMessage", diff --git a/tests/unittests/models/test_litellm.py b/tests/unittests/models/test_litellm.py index 8fda3d98d4..0ac38e5ece 100644 --- a/tests/unittests/models/test_litellm.py +++ b/tests/unittests/models/test_litellm.py @@ -2223,6 +2223,64 @@ def test_message_to_generate_content_response_tool_call(): assert response.content.parts[0].function_call.id == "test_tool_call_id" +def test_message_to_generate_content_response_tool_call_with_thought_signature(): + signature = b"gemini_signature" + encoded_signature = base64.b64encode(signature).decode("utf-8") + message = ChatCompletionAssistantMessage( + role="assistant", + content=None, + tool_calls=[ + ChatCompletionMessageToolCall( + type="function", + id="test_tool_call_id", + function=Function( + name="test_function", + arguments='{"test_arg": "test_value"}', + ), + provider_specific_fields={"thought_signature": encoded_signature}, + extra_content={"google": {"thought_signature": encoded_signature}}, + ) + ], + ) + + response = _message_to_generate_content_response(message) + assert response.content.role == "model" + assert response.content.parts[0].function_call.name == "test_function" + assert response.content.parts[0].function_call.args == { + "test_arg": "test_value" + } + assert response.content.parts[0].function_call.id == "test_tool_call_id" + assert response.content.parts[0].thought_signature == signature + + +@pytest.mark.asyncio +async def test_content_to_message_param_embeds_thought_signature_in_tool_call(): + part = types.Part.from_function_call( + name="test_function", + args={"test_arg": "test_value"}, + ) + part.function_call.id = "test_tool_call_id" + part.thought_signature = b"gemini_signature" + content = types.Content(role="model", parts=[part]) + + message = await _content_to_message_param(content) + + tool_calls = message["tool_calls"] + assert tool_calls is not None + assert len(tool_calls) == 1 + assert tool_calls[0]["id"] == "test_tool_call_id" + assert tool_calls[0]["provider_specific_fields"] == { + "thought_signature": base64.b64encode(b"gemini_signature").decode("utf-8") + } + assert tool_calls[0]["extra_content"] == { + "google": { + "thought_signature": base64.b64encode(b"gemini_signature").decode( + "utf-8" + ) + } + } + + def test_message_to_generate_content_response_inline_tool_call_text(): message = ChatCompletionAssistantMessage( role="assistant",