Use LLM fallback when local matching matches intent but not targets (#136045)

LLM fallback to be used when local matching matches intent but finds no targets
pull/136054/head
Paulus Schoutsen 2025-01-20 02:06:06 -05:00 committed by GitHub
parent 53ad02a1eb
commit 85f10cf60a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 2 deletions

View File

@ -1350,14 +1350,25 @@ class DefaultAgent(ConversationEntity):
"""Try to match sentence against registered intents and return response.
Only performs strict matching with exposed entities and exact wording.
Returns None if no match occurred.
Returns None if no match or a matching error occurred.
"""
result = await self.async_recognize_intent(user_input, strict_intents_only=True)
if not isinstance(result, RecognizeResult):
# No error message on failed match
return None
return await self._async_process_intent_result(result, user_input)
response = await self._async_process_intent_result(result, user_input)
if (
response.response_type == intent.IntentResponseType.ERROR
and response.error_code
not in (
intent.IntentResponseErrorCode.FAILED_TO_HANDLE,
intent.IntentResponseErrorCode.UNKNOWN,
)
):
# We ignore no matching errors
return None
return response
def _make_error_result(

View File

@ -3104,3 +3104,51 @@ async def test_turn_on_off(
)
assert len(off_calls) == 1
assert off_calls[0].data.get("entity_id") == [entity_id]
@pytest.mark.parametrize(
("error_code", "return_response"),
[
(intent.IntentResponseErrorCode.NO_INTENT_MATCH, False),
(intent.IntentResponseErrorCode.NO_VALID_TARGETS, False),
(intent.IntentResponseErrorCode.FAILED_TO_HANDLE, True),
(intent.IntentResponseErrorCode.UNKNOWN, True),
],
)
@pytest.mark.usefixtures("init_components")
async def test_handle_intents_with_response_errors(
hass: HomeAssistant,
init_components: None,
area_registry: ar.AreaRegistry,
error_code: intent.IntentResponseErrorCode,
return_response: bool,
) -> None:
"""Test that handle_intents does not return response errors."""
assert await async_setup_component(hass, "climate", {})
area_registry.async_create("living room")
agent: default_agent.DefaultAgent = hass.data[DATA_DEFAULT_ENTITY]
user_input = ConversationInput(
text="What is the temperature in the living room?",
context=Context(),
conversation_id=None,
device_id=None,
language=hass.config.language,
agent_id=None,
)
with patch(
"homeassistant.components.conversation.default_agent.DefaultAgent._async_process_intent_result",
return_value=default_agent._make_error_result(
user_input.language, error_code, "Mock error message"
),
) as mock_process:
response = await agent.async_handle_intents(user_input)
assert len(mock_process.mock_calls) == 1
if return_response:
assert response is not None and response.error_code == error_code
else:
assert response is None