mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 09:23:17 -04:00
Use ToolResult in mcp (#182541)
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
f1f854262a
commit
6081351f8a
@@ -29,7 +29,6 @@ from homeassistant.exceptions import (
|
||||
from homeassistant.helpers import llm
|
||||
from homeassistant.helpers.httpx_client import create_async_httpx_client
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
from homeassistant.util.json import JsonObjectType
|
||||
from homeassistant.util.ssl import SSL_ALPN_HTTP11, SSLCipherList, client_context
|
||||
|
||||
from .auth import AuthenticateHeader
|
||||
@@ -148,7 +147,7 @@ class ModelContextProtocolTool(llm.Tool):
|
||||
hass: HomeAssistant,
|
||||
tool_input: llm.ToolInput,
|
||||
llm_context: llm.LLMContext,
|
||||
) -> JsonObjectType:
|
||||
) -> llm.ToolResult:
|
||||
"""Call the tool."""
|
||||
try:
|
||||
async with asyncio.timeout(TIMEOUT):
|
||||
@@ -188,7 +187,10 @@ class ModelContextProtocolTool(llm.Tool):
|
||||
raise HomeAssistantError(
|
||||
f"Error communicating with MCP server when calling tool: {error}"
|
||||
) from error
|
||||
return result.model_dump(exclude_unset=True, exclude_none=True)
|
||||
return llm.ToolResult(
|
||||
data=result.model_dump(exclude_unset=True, exclude_none=True),
|
||||
error=bool(result.isError),
|
||||
)
|
||||
|
||||
|
||||
class ModelContextProtocolCoordinator(DataUpdateCoordinator[list[llm.Tool]]):
|
||||
|
||||
@@ -317,8 +317,42 @@ async def test_llm_get_api_tools(
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("call_tool_result", "expected_result"),
|
||||
[
|
||||
pytest.param(
|
||||
CallToolResult(
|
||||
content=[TextContent(type="text", text="User was born in February")]
|
||||
),
|
||||
llm.ToolResult(
|
||||
data={
|
||||
"content": [{"text": "User was born in February", "type": "text"}]
|
||||
}
|
||||
),
|
||||
id="success",
|
||||
),
|
||||
pytest.param(
|
||||
CallToolResult(
|
||||
content=[TextContent(type="text", text="Memory search failed")],
|
||||
isError=True,
|
||||
),
|
||||
llm.ToolResult(
|
||||
data={
|
||||
"content": [{"text": "Memory search failed", "type": "text"}],
|
||||
"isError": True,
|
||||
},
|
||||
error=True,
|
||||
),
|
||||
id="error",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_call_tool(
|
||||
hass: HomeAssistant, config_entry: MockConfigEntry, mock_mcp_client: Mock
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_mcp_client: Mock,
|
||||
call_tool_result: CallToolResult,
|
||||
expected_result: llm.ToolResult,
|
||||
) -> None:
|
||||
"""Test calling an MCP Tool through the LLM API."""
|
||||
mock_mcp_client.return_value.list_tools.return_value = ListToolsResult(
|
||||
@@ -337,9 +371,7 @@ async def test_call_tool(
|
||||
tool = api_instance.tools[0]
|
||||
assert tool.name == "search_memory"
|
||||
|
||||
mock_mcp_client.return_value.call_tool.return_value = CallToolResult(
|
||||
content=[TextContent(type="text", text="User was born in February")]
|
||||
)
|
||||
mock_mcp_client.return_value.call_tool.return_value = call_tool_result
|
||||
result = await tool.async_call(
|
||||
hass,
|
||||
llm.ToolInput(
|
||||
@@ -347,9 +379,7 @@ async def test_call_tool(
|
||||
),
|
||||
create_llm_context(),
|
||||
)
|
||||
assert result == {
|
||||
"content": [{"text": "User was born in February", "type": "text"}]
|
||||
}
|
||||
assert result == expected_result
|
||||
|
||||
|
||||
async def test_call_tool_fails(
|
||||
|
||||
Reference in New Issue
Block a user