Move default response out of sentence trigger registration and into agent (#109317)
* Move default response out of trigger and into agent * Add test
This commit is contained in:
parent
ed726db974
commit
c2c98bd04c
3 changed files with 69 additions and 3 deletions
|
@ -238,7 +238,10 @@ class DefaultAgent(AbstractConversationAgent):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Use last non-empty result as response
|
# Use last non-empty result as response.
|
||||||
|
#
|
||||||
|
# There may be multiple copies of a trigger running when editing in
|
||||||
|
# the UI, so it's critical that we filter out empty responses here.
|
||||||
response_text: str | None = None
|
response_text: str | None = None
|
||||||
for trigger_response in trigger_responses:
|
for trigger_response in trigger_responses:
|
||||||
response_text = response_text or trigger_response
|
response_text = response_text or trigger_response
|
||||||
|
@ -246,7 +249,7 @@ class DefaultAgent(AbstractConversationAgent):
|
||||||
# Convert to conversation result
|
# Convert to conversation result
|
||||||
response = intent.IntentResponse(language=language)
|
response = intent.IntentResponse(language=language)
|
||||||
response.response_type = intent.IntentResponseType.ACTION_DONE
|
response.response_type = intent.IntentResponseType.ACTION_DONE
|
||||||
response.async_set_speech(response_text or "")
|
response.async_set_speech(response_text or "Done")
|
||||||
|
|
||||||
return ConversationResult(response=response)
|
return ConversationResult(response=response)
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,12 @@ async def async_attach_trigger(
|
||||||
# mypy does not understand the type narrowing, unclear why
|
# mypy does not understand the type narrowing, unclear why
|
||||||
return automation_result.conversation_response # type: ignore[return-value]
|
return automation_result.conversation_response # type: ignore[return-value]
|
||||||
|
|
||||||
return "Done"
|
# It's important to return None here instead of a string.
|
||||||
|
#
|
||||||
|
# When editing in the UI, a copy of this trigger is registered.
|
||||||
|
# If we return a string from here, there is a race condition between the
|
||||||
|
# two trigger copies for who will provide a response.
|
||||||
|
return None
|
||||||
|
|
||||||
default_agent = await _get_agent_manager(hass).async_get_agent(HOME_ASSISTANT_AGENT)
|
default_agent = await _get_agent_manager(hass).async_get_agent(HOME_ASSISTANT_AGENT)
|
||||||
assert isinstance(default_agent, DefaultAgent)
|
assert isinstance(default_agent, DefaultAgent)
|
||||||
|
|
|
@ -7,6 +7,7 @@ from homeassistant.helpers import trigger
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.common import async_mock_service
|
from tests.common import async_mock_service
|
||||||
|
from tests.typing import WebSocketGenerator
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -99,6 +100,63 @@ async def test_response(hass: HomeAssistant, setup_comp) -> None:
|
||||||
assert service_response["response"]["speech"]["plain"]["speech"] == response
|
assert service_response["response"]["speech"]["plain"]["speech"] == response
|
||||||
|
|
||||||
|
|
||||||
|
async def test_subscribe_trigger_does_not_interfere_with_responses(
|
||||||
|
hass: HomeAssistant, setup_comp, hass_ws_client: WebSocketGenerator
|
||||||
|
) -> None:
|
||||||
|
"""Test that subscribing to a trigger from the websocket API does not interfere with responses."""
|
||||||
|
websocket_client = await hass_ws_client()
|
||||||
|
await websocket_client.send_json(
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"type": "subscribe_trigger",
|
||||||
|
"trigger": {"platform": "conversation", "command": ["test sentence"]},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
service_response = await hass.services.async_call(
|
||||||
|
"conversation",
|
||||||
|
"process",
|
||||||
|
{
|
||||||
|
"text": "test sentence",
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
return_response=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Default response, since no automations with responses are registered
|
||||||
|
assert service_response["response"]["speech"]["plain"]["speech"] == "Done"
|
||||||
|
|
||||||
|
# Now register a trigger with a response
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
"automation",
|
||||||
|
{
|
||||||
|
"automation test1": {
|
||||||
|
"trigger": {
|
||||||
|
"platform": "conversation",
|
||||||
|
"command": ["test sentence"],
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"set_conversation_response": "test response",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
service_response = await hass.services.async_call(
|
||||||
|
"conversation",
|
||||||
|
"process",
|
||||||
|
{
|
||||||
|
"text": "test sentence",
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
return_response=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Response will now come through
|
||||||
|
assert service_response["response"]["speech"]["plain"]["speech"] == "test response"
|
||||||
|
|
||||||
|
|
||||||
async def test_same_trigger_multiple_sentences(
|
async def test_same_trigger_multiple_sentences(
|
||||||
hass: HomeAssistant, calls, setup_comp
|
hass: HomeAssistant, calls, setup_comp
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue