diff --git a/homeassistant/components/cloud/entity.py b/homeassistant/components/cloud/entity.py index 2c7fcf2fe244..ab24892a9056 100644 --- a/homeassistant/components/cloud/entity.py +++ b/homeassistant/components/cloud/entity.py @@ -84,7 +84,7 @@ def _convert_content_to_param( and content.tool_call_id in web_search_calls ): web_search_call = web_search_calls.pop(content.tool_call_id) - web_search_call["status"] = content.tool_result.get( + web_search_call["status"] = content.result.data.get( "status", "completed" ) messages.append(cast("ResponseInputItemParam", web_search_call)) @@ -93,7 +93,12 @@ def _convert_content_to_param( { "type": "function_call_output", "call_id": content.tool_call_id, - "output": json_dumps(content.tool_result), + "output": json_dumps( + { + "data": content.result.data, + "error": content.result.error, + } + ), } ) continue @@ -316,7 +321,10 @@ async def _transform_stream( # noqa: C901 - This is complex, but better to have "role": "tool_result", "tool_call_id": event.item.id, "tool_name": "web_search_call", - "tool_result": {"status": event.item.status}, + "result": llm.ToolResult( + data={"status": event.item.status}, + error=event.item.status == "failed", + ), } last_role = "tool_result" elif isinstance(event.item, LLMResponseImageOutputItem): diff --git a/tests/components/cloud/test_entity.py b/tests/components/cloud/test_entity.py index 7c522f8483d1..c9b9362ade86 100644 --- a/tests/components/cloud/test_entity.py +++ b/tests/components/cloud/test_entity.py @@ -327,3 +327,40 @@ async def test_async_handle_chat_log_service_sets_structured_output_non_strict( _, kwargs = cloud.llm.async_generate_data.call_args assert kwargs["response_format"]["json_schema"]["strict"] is False + + +@pytest.mark.parametrize( + ("result", "expected_output"), + [ + pytest.param( + llm.ToolResult(data={"temperature": 21}), + '{"data":{"temperature":21},"error":false}', + id="success", + ), + pytest.param( + llm.ToolResult(data={"error": "Not found"}, error=True), + '{"data":{"error":"Not found"},"error":true}', + id="error", + ), + ], +) +def test_convert_tool_result_to_param( + result: llm.ToolResult, expected_output: str +) -> None: + """Test the tool result is sent with its error flag.""" + content = [ + conversation.ToolResultContent( + agent_id="agent", + tool_call_id="mock-tool-call-id", + tool_name="HassGetState", + result=result, + ) + ] + + assert _convert_content_to_param(content) == [ + { + "type": "function_call_output", + "call_id": "mock-tool-call-id", + "output": expected_output, + } + ]