1
0
mirror of https://github.com/home-assistant/core.git synced 2026-07-13 09:38:42 +01:00
Files
core/tests/components/script/test_llm.py
T
Paulus Schoutsen ba3e63546c Add script LLM tools platform (#175514)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 16:54:52 -07:00

87 lines
3.2 KiB
Python

"""Tests for the script LLM tools platform."""
import pytest
from homeassistant.components import llm as llm_component
from homeassistant.components.homeassistant.exposed_entities import async_expose_entity
from homeassistant.components.script import llm as script_llm
from homeassistant.core import Context, HomeAssistant
from homeassistant.helpers import llm
from homeassistant.setup import async_setup_component
ENTITY_ID = "script.test_script"
@pytest.fixture(autouse=True)
async def setup_integrations(hass: HomeAssistant) -> None:
"""Set up the integrations and expose a script."""
assert await async_setup_component(hass, "homeassistant", {})
assert await async_setup_component(hass, "intent", {})
assert await async_setup_component(hass, "llm", {})
assert await async_setup_component(
hass,
"script",
{
"script": {
"test_script": {
"alias": "test script",
"description": "This is a test script",
"sequence": [
{"variables": {"result": {"drinks": 2}}},
{"stop": True, "response_variable": "result"},
],
"fields": {
"beer": {"description": "Number of beers", "required": True},
},
},
"unexposed_script": {"sequence": []},
}
},
)
async_expose_entity(hass, "conversation", ENTITY_ID, True)
await hass.async_block_till_done()
def _llm_context() -> llm.LLMContext:
"""Return an LLM context for the conversation assistant."""
return llm.LLMContext(
platform="test_platform",
context=Context(),
language="*",
assistant="conversation",
device_id=None,
)
async def test_script_tool_only_exposed(hass: HomeAssistant) -> None:
"""Test only exposed scripts get a tool."""
result = await llm_component.async_get_tools(hass, _llm_context(), "assist")
names = [tool.name for tool in result.tools]
assert "test_script" in names
assert "unexposed_script" not in names
async def test_script_tool_not_exposed(hass: HomeAssistant) -> None:
"""Test no script tool is offered when the script is not exposed."""
async_expose_entity(hass, "conversation", ENTITY_ID, False)
result = await llm_component.async_get_tools(hass, _llm_context(), "assist")
assert "test_script" not in [tool.name for tool in result.tools]
assert script_llm.async_get_tools(hass, _llm_context(), "assist") is None
async def test_no_tools_for_other_api(hass: HomeAssistant) -> None:
"""Test the platform returns None for an unsupported API."""
assert script_llm.async_get_tools(hass, _llm_context(), "other") is None
async def test_script_tool_call(hass: HomeAssistant) -> None:
"""Test calling the exposed script through its tool."""
llm_context = _llm_context()
result = await llm_component.async_get_tools(hass, llm_context, "assist")
tool = next(tool for tool in result.tools if tool.name == "test_script")
response = await tool.async_call(
hass, llm.ToolInput("test_script", {"beer": 1}), llm_context
)
assert response == {"success": True, "result": {"drinks": 2}}