1
0
mirror of https://github.com/home-assistant/core.git synced 2026-02-15 07:36:16 +00:00

Fix JSON serialization of time objects in Ollama tool results (#162502)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Denis Shulyaka
2026-02-07 23:15:13 +03:00
committed by GitHub
parent ce3dd2b6db
commit 8ef1e25f8c
2 changed files with 103 additions and 1 deletions

View File

@@ -16,6 +16,7 @@ from homeassistant.config_entries import ConfigSubentry
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr, llm
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.json import json_dumps
from . import OllamaConfigEntry
from .const import (
@@ -93,7 +94,7 @@ def _convert_content(
if isinstance(chat_content, conversation.ToolResultContent):
return ollama.Message(
role=MessageRole.TOOL.value,
content=json.dumps(chat_content.tool_result),
content=json_dumps(chat_content.tool_result),
)
if isinstance(chat_content, conversation.AssistantContent):
return ollama.Message(

View File

@@ -1,6 +1,7 @@
"""Tests for the Ollama integration."""
from collections.abc import AsyncGenerator
import datetime
from typing import Any
from unittest.mock import AsyncMock, Mock, patch
@@ -23,6 +24,10 @@ from homeassistant.helpers import (
)
from tests.common import MockConfigEntry
from tests.components.conversation import (
MockChatLog,
mock_chat_log, # noqa: F401
)
@pytest.fixture(autouse=True)
@@ -458,6 +463,102 @@ async def test_function_exception(
)
async def test_history_conversion(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_init_component,
mock_chat_log: MockChatLog, # noqa: F811
) -> None:
"""Test that the pre-existing chat_log history is handled properly."""
agent_id = "conversation.ollama_conversation"
# Add some pre-existing content from conversation.default_agent
mock_chat_log.async_add_user_content(
conversation.UserContent(content="What time is it?")
)
mock_chat_log.async_add_assistant_content_without_tools(
conversation.AssistantContent(
agent_id=agent_id,
tool_calls=[
llm.ToolInput(
tool_name="HassGetCurrentTime",
tool_args={},
id="01KGW7TFC1VVVK7ANHVMDA4DJ6",
external=True,
)
],
)
)
mock_chat_log.async_add_assistant_content_without_tools(
conversation.ToolResultContent(
agent_id=agent_id,
tool_call_id="01KGW7TFC1VVVK7ANHVMDA4DJ6",
tool_name="HassGetCurrentTime",
tool_result={
"speech": {"plain": {"speech": "4:24 PM", "extra_data": None}},
"response_type": "action_done",
"speech_slots": {"time": datetime.time(16, 24, 17, 813343)},
"data": {"targets": [], "success": [], "failed": []},
},
)
)
mock_chat_log.async_add_assistant_content_without_tools(
conversation.AssistantContent(
agent_id=agent_id,
content="4:24 PM",
)
)
entry = MockConfigEntry()
entry.add_to_hass(hass)
with patch(
"ollama.AsyncClient.chat",
return_value=stream_generator(
{"message": {"role": "assistant", "content": "test response"}}
),
) as mock_chat:
result = await conversation.async_converse(
hass,
"test message",
mock_chat_log.conversation_id,
Context(),
agent_id=agent_id,
)
assert mock_chat.call_count == 1
args = mock_chat.call_args.kwargs
prompt = args["messages"][0]["content"]
assert args["model"] == "test_model:latest"
assert args["messages"] == [
Message(role="system", content=prompt),
Message(role="user", content="What time is it?"),
Message(
role="assistant",
tool_calls=[
Message.ToolCall(
function=Message.ToolCall.Function(
name="HassGetCurrentTime", arguments={}
)
)
],
),
Message(
role="tool",
content='{"speech":{"plain":{"speech":"4:24 PM","extra_data":null}},"response_type":"action_done","speech_slots":{"time":"16:24:17.813343"},"data":{"targets":[],"success":[],"failed":[]}}',
),
Message(role="assistant", content="4:24 PM"),
Message(role="user", content="test message"),
]
assert result.response.response_type == intent.IntentResponseType.ACTION_DONE, (
result
)
assert result.response.speech["plain"]["speech"] == "test response"
async def test_unknown_hass_api(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,