Only send ESPHome intent progress when necessary (#147458)

* Only send intent progress when necessary

* cover

* Fix logic

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Michael Hansen 2025-06-24 15:35:38 -05:00 committed by GitHub
parent 9e7c7ec97e
commit 19b773df85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 81 additions and 5 deletions

View File

@ -284,11 +284,15 @@ class EsphomeAssistSatellite(
assert event.data is not None
data_to_send = {"text": event.data["stt_output"]["text"]}
elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_INTENT_PROGRESS:
data_to_send = {
"tts_start_streaming": "1"
if (event.data and event.data.get("tts_start_streaming"))
else "0",
}
if (
not event.data
or ("tts_start_streaming" not in event.data)
or (not event.data["tts_start_streaming"])
):
# ESPHome only needs to know if early TTS streaming is available
return
data_to_send = {"tts_start_streaming": "1"}
elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_INTENT_END:
assert event.data is not None
data_to_send = {

View File

@ -1776,6 +1776,78 @@ async def test_get_set_configuration(
assert satellite.async_get_configuration() == updated_config
async def test_intent_progress_optimization(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test that intent progress events are only sent when early TTS streaming is available."""
mock_device = await mock_esphome_device(
mock_client=mock_client,
device_info={
"voice_assistant_feature_flags": VoiceAssistantFeature.VOICE_ASSISTANT
},
)
await hass.async_block_till_done()
satellite = get_satellite_entity(hass, mock_device.device_info.mac_address)
assert satellite is not None
# Test that intent progress without tts_start_streaming is not sent
mock_client.send_voice_assistant_event.reset_mock()
satellite.on_pipeline_event(
PipelineEvent(
type=PipelineEventType.INTENT_PROGRESS,
data={"some_other_key": "value"},
)
)
mock_client.send_voice_assistant_event.assert_not_called()
# Test that intent progress with tts_start_streaming=False is not sent
satellite.on_pipeline_event(
PipelineEvent(
type=PipelineEventType.INTENT_PROGRESS,
data={"tts_start_streaming": False},
)
)
mock_client.send_voice_assistant_event.assert_not_called()
# Test that intent progress with tts_start_streaming=True is sent
satellite.on_pipeline_event(
PipelineEvent(
type=PipelineEventType.INTENT_PROGRESS,
data={"tts_start_streaming": True},
)
)
assert mock_client.send_voice_assistant_event.call_args_list[-1].args == (
VoiceAssistantEventType.VOICE_ASSISTANT_INTENT_PROGRESS,
{"tts_start_streaming": "1"},
)
# Test that intent progress with tts_start_streaming as string "1" is sent
mock_client.send_voice_assistant_event.reset_mock()
satellite.on_pipeline_event(
PipelineEvent(
type=PipelineEventType.INTENT_PROGRESS,
data={"tts_start_streaming": "1"},
)
)
assert mock_client.send_voice_assistant_event.call_args_list[-1].args == (
VoiceAssistantEventType.VOICE_ASSISTANT_INTENT_PROGRESS,
{"tts_start_streaming": "1"},
)
# Test that intent progress with no data is *not* sent
mock_client.send_voice_assistant_event.reset_mock()
satellite.on_pipeline_event(
PipelineEvent(
type=PipelineEventType.INTENT_PROGRESS,
data=None,
)
)
mock_client.send_voice_assistant_event.assert_not_called()
async def test_wake_word_select(
hass: HomeAssistant,
mock_client: APIClient,