Fix a type error when using google-genai==1.7.0 (#141431)

* Fix parts

* Fix the type being sent to the SDK

* Revert changes to __init__

* Test fixes

* Bump version back to 1.7
This commit is contained in:
Ivan Lopez Hernandez 2025-03-25 19:59:21 -07:00 committed by GitHub
parent 2208650fde
commit 56cc4044e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 77 additions and 75 deletions

View File

@ -171,17 +171,25 @@ def _escape_decode(value: Any) -> Any:
return value
def _create_google_tool_response_parts(
parts: list[conversation.ToolResultContent],
) -> list[Part]:
"""Create Google tool response parts."""
return [
Part.from_function_response(
name=tool_result.tool_name, response=tool_result.tool_result
)
for tool_result in parts
]
def _create_google_tool_response_content(
content: list[conversation.ToolResultContent],
) -> Content:
"""Create a Google tool response content."""
return Content(
parts=[
Part.from_function_response(
name=tool_result.tool_name, response=tool_result.tool_result
)
for tool_result in content
]
role="user",
parts=_create_google_tool_response_parts(content),
)
@ -402,7 +410,7 @@ class GoogleGenerativeAIConversationEntity(
chat = self._genai_client.aio.chats.create(
model=model_name, history=messages, config=generateContentConfig
)
chat_request: str | Content = user_input.text
chat_request: str | list[Part] = user_input.text
# To prevent infinite loops, we limit the number of iterations
for _iteration in range(MAX_TOOL_ITERATIONS):
try:
@ -456,7 +464,7 @@ class GoogleGenerativeAIConversationEntity(
)
)
chat_request = _create_google_tool_response_content(
chat_request = _create_google_tool_response_parts(
[
tool_response
async for tool_response in chat_log.async_add_assistant_content(

View File

@ -25,7 +25,9 @@
tuple(
),
dict({
'message': Content(parts=[Part(video_metadata=None, thought=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=FunctionResponse(id=None, name='test_tool', response={'result': 'Test response'}), inline_data=None, text=None)], role=None),
'message': list([
Part(video_metadata=None, thought=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=FunctionResponse(id=None, name='test_tool', response={'result': 'Test response'}), inline_data=None, text=None),
]),
}),
),
])
@ -56,7 +58,9 @@
tuple(
),
dict({
'message': Content(parts=[Part(video_metadata=None, thought=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=FunctionResponse(id=None, name='test_tool', response={'result': 'Test response'}), inline_data=None, text=None)], role=None),
'message': list([
Part(video_metadata=None, thought=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=FunctionResponse(id=None, name='test_tool', response={'result': 'Test response'}), inline_data=None, text=None),
]),
}),
),
])
@ -87,7 +91,9 @@
tuple(
),
dict({
'message': Content(parts=[Part(video_metadata=None, thought=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=FunctionResponse(id=None, name='test_tool', response={'result': 'Test response'}), inline_data=None, text=None)], role=None),
'message': list([
Part(video_metadata=None, thought=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=FunctionResponse(id=None, name='test_tool', response={'result': 'Test response'}), inline_data=None, text=None),
]),
}),
),
])

View File

@ -104,28 +104,24 @@ async def test_function_call(
assert result.response.response_type == intent.IntentResponseType.ACTION_DONE
assert result.response.as_dict()["speech"]["plain"]["speech"] == "Hi there!"
mock_tool_call = mock_create.mock_calls[2][2]["message"]
assert mock_tool_call.model_dump() == {
"parts": [
{
"code_execution_result": None,
"executable_code": None,
"file_data": None,
"function_call": None,
"function_response": {
"id": None,
"name": "test_tool",
"response": {
"result": "Test response",
},
},
"inline_data": None,
"text": None,
"thought": None,
"video_metadata": None,
mock_tool_response_parts = mock_create.mock_calls[2][2]["message"]
assert len(mock_tool_response_parts) == 1
assert mock_tool_response_parts[0].model_dump() == {
"code_execution_result": None,
"executable_code": None,
"file_data": None,
"function_call": None,
"function_response": {
"id": None,
"name": "test_tool",
"response": {
"result": "Test response",
},
],
"role": None,
},
"inline_data": None,
"text": None,
"thought": None,
"video_metadata": None,
}
mock_tool.async_call.assert_awaited_once_with(
@ -292,28 +288,24 @@ async def test_function_call_without_parameters(
assert result.response.response_type == intent.IntentResponseType.ACTION_DONE
assert result.response.as_dict()["speech"]["plain"]["speech"] == "Hi there!"
mock_tool_call = mock_create.mock_calls[2][2]["message"]
assert mock_tool_call.model_dump() == {
"parts": [
{
"code_execution_result": None,
"executable_code": None,
"file_data": None,
"function_call": None,
"function_response": {
"id": None,
"name": "test_tool",
"response": {
"result": "Test response",
},
},
"inline_data": None,
"text": None,
"thought": None,
"video_metadata": None,
mock_tool_response_parts = mock_create.mock_calls[2][2]["message"]
assert len(mock_tool_response_parts) == 1
assert mock_tool_response_parts[0].model_dump() == {
"code_execution_result": None,
"executable_code": None,
"file_data": None,
"function_call": None,
"function_response": {
"id": None,
"name": "test_tool",
"response": {
"result": "Test response",
},
],
"role": None,
},
"inline_data": None,
"text": None,
"thought": None,
"video_metadata": None,
}
mock_tool.async_call.assert_awaited_once_with(
@ -390,29 +382,25 @@ async def test_function_exception(
assert result.response.response_type == intent.IntentResponseType.ACTION_DONE
assert result.response.as_dict()["speech"]["plain"]["speech"] == "Hi there!"
mock_tool_call = mock_create.mock_calls[2][2]["message"]
assert mock_tool_call.model_dump() == {
"parts": [
{
"code_execution_result": None,
"executable_code": None,
"file_data": None,
"function_call": None,
"function_response": {
"id": None,
"name": "test_tool",
"response": {
"error": "HomeAssistantError",
"error_text": "Test tool exception",
},
},
"inline_data": None,
"text": None,
"thought": None,
"video_metadata": None,
mock_tool_response_parts = mock_create.mock_calls[2][2]["message"]
assert len(mock_tool_response_parts) == 1
assert mock_tool_response_parts[0].model_dump() == {
"code_execution_result": None,
"executable_code": None,
"file_data": None,
"function_call": None,
"function_response": {
"id": None,
"name": "test_tool",
"response": {
"error": "HomeAssistantError",
"error_text": "Test tool exception",
},
],
"role": None,
},
"inline_data": None,
"text": None,
"thought": None,
"video_metadata": None,
}
mock_tool.async_call.assert_awaited_once_with(
hass,