Intents package combines sentences/responses per language (#109079)
parent
a1f36c25d4
commit
9752e70675
|
@ -6,7 +6,6 @@ from collections import defaultdict
|
|||
from collections.abc import Awaitable, Callable, Iterable
|
||||
from dataclasses import dataclass
|
||||
import functools
|
||||
import itertools
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
@ -28,7 +27,7 @@ from hassil.recognize import (
|
|||
recognize_all,
|
||||
)
|
||||
from hassil.util import merge_dict
|
||||
from home_assistant_intents import get_domains_and_languages, get_intents
|
||||
from home_assistant_intents import get_intents, get_languages
|
||||
import yaml
|
||||
|
||||
from homeassistant import core, setup
|
||||
|
@ -156,7 +155,7 @@ class DefaultAgent(AbstractConversationAgent):
|
|||
@property
|
||||
def supported_languages(self) -> list[str]:
|
||||
"""Return a list of supported languages."""
|
||||
return get_domains_and_languages()["homeassistant"]
|
||||
return get_languages()
|
||||
|
||||
async def async_initialize(self, config_intents: dict[str, Any] | None) -> None:
|
||||
"""Initialize the default agent."""
|
||||
|
@ -387,6 +386,7 @@ class DefaultAgent(AbstractConversationAgent):
|
|||
return maybe_result
|
||||
|
||||
# Try again with missing entities enabled
|
||||
best_num_unmatched_entities = 0
|
||||
for result in recognize_all(
|
||||
user_input.text,
|
||||
lang_intents.intents,
|
||||
|
@ -394,20 +394,28 @@ class DefaultAgent(AbstractConversationAgent):
|
|||
intent_context=intent_context,
|
||||
allow_unmatched_entities=True,
|
||||
):
|
||||
# Remove missing entities that couldn't be filled from context
|
||||
for entity_key, entity in list(result.unmatched_entities.items()):
|
||||
if isinstance(entity, UnmatchedTextEntity) and (
|
||||
entity.text == MISSING_ENTITY
|
||||
):
|
||||
result.unmatched_entities.pop(entity_key)
|
||||
if result.text_chunks_matched < 1:
|
||||
# Skip results that don't match any literal text
|
||||
continue
|
||||
|
||||
# Don't count missing entities that couldn't be filled from context
|
||||
num_unmatched_entities = 0
|
||||
for entity in result.unmatched_entities_list:
|
||||
if isinstance(entity, UnmatchedTextEntity):
|
||||
if entity.text != MISSING_ENTITY:
|
||||
num_unmatched_entities += 1
|
||||
else:
|
||||
num_unmatched_entities += 1
|
||||
|
||||
if maybe_result is None:
|
||||
# First result
|
||||
maybe_result = result
|
||||
elif len(result.unmatched_entities) < len(maybe_result.unmatched_entities):
|
||||
best_num_unmatched_entities = num_unmatched_entities
|
||||
elif num_unmatched_entities < best_num_unmatched_entities:
|
||||
# Fewer unmatched entities
|
||||
maybe_result = result
|
||||
elif len(result.unmatched_entities) == len(maybe_result.unmatched_entities):
|
||||
best_num_unmatched_entities = num_unmatched_entities
|
||||
elif num_unmatched_entities == best_num_unmatched_entities:
|
||||
if (result.text_chunks_matched > maybe_result.text_chunks_matched) or (
|
||||
(result.text_chunks_matched == maybe_result.text_chunks_matched)
|
||||
and ("name" in result.unmatched_entities) # prefer entities
|
||||
|
@ -536,14 +544,12 @@ class DefaultAgent(AbstractConversationAgent):
|
|||
intents_dict = lang_intents.intents_dict
|
||||
language_variant = lang_intents.language_variant
|
||||
|
||||
domains_langs = get_domains_and_languages()
|
||||
supported_langs = set(get_languages())
|
||||
|
||||
if not language_variant:
|
||||
# Choose a language variant upfront and commit to it for custom
|
||||
# sentences, etc.
|
||||
all_language_variants = {
|
||||
lang.lower(): lang for lang in itertools.chain(*domains_langs.values())
|
||||
}
|
||||
all_language_variants = {lang.lower(): lang for lang in supported_langs}
|
||||
|
||||
# en-US, en_US, en, ...
|
||||
for maybe_variant in _get_language_variations(language):
|
||||
|
@ -558,23 +564,17 @@ class DefaultAgent(AbstractConversationAgent):
|
|||
)
|
||||
return None
|
||||
|
||||
# Load intents for all domains supported by this language variant
|
||||
for domain in domains_langs:
|
||||
domain_intents = get_intents(
|
||||
domain, language_variant, json_load=json_load
|
||||
)
|
||||
|
||||
if not domain_intents:
|
||||
continue
|
||||
# Load intents for this language variant
|
||||
lang_variant_intents = get_intents(language_variant, json_load=json_load)
|
||||
|
||||
if lang_variant_intents:
|
||||
# Merge sentences into existing dictionary
|
||||
merge_dict(intents_dict, domain_intents)
|
||||
merge_dict(intents_dict, lang_variant_intents)
|
||||
|
||||
# Will need to recreate graph
|
||||
intents_changed = True
|
||||
_LOGGER.debug(
|
||||
"Loaded intents domain=%s, language=%s (%s)",
|
||||
domain,
|
||||
"Loaded intents language=%s (%s)",
|
||||
language,
|
||||
language_variant,
|
||||
)
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
"integration_type": "system",
|
||||
"iot_class": "local_push",
|
||||
"quality_scale": "internal",
|
||||
"requirements": ["hassil==1.6.0", "home-assistant-intents==2024.1.2"]
|
||||
"requirements": ["hassil==1.6.0", "home-assistant-intents==2024.1.29"]
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ hass-nabucasa==0.75.1
|
|||
hassil==1.6.0
|
||||
home-assistant-bluetooth==1.12.0
|
||||
home-assistant-frontend==20240112.0
|
||||
home-assistant-intents==2024.1.2
|
||||
home-assistant-intents==2024.1.29
|
||||
httpx==0.26.0
|
||||
ifaddr==0.2.0
|
||||
janus==1.0.0
|
||||
|
|
|
@ -1056,7 +1056,7 @@ holidays==0.41
|
|||
home-assistant-frontend==20240112.0
|
||||
|
||||
# homeassistant.components.conversation
|
||||
home-assistant-intents==2024.1.2
|
||||
home-assistant-intents==2024.1.29
|
||||
|
||||
# homeassistant.components.home_connect
|
||||
homeconnect==0.7.2
|
||||
|
|
|
@ -849,7 +849,7 @@ holidays==0.41
|
|||
home-assistant-frontend==20240112.0
|
||||
|
||||
# homeassistant.components.conversation
|
||||
home-assistant-intents==2024.1.2
|
||||
home-assistant-intents==2024.1.29
|
||||
|
||||
# homeassistant.components.home_connect
|
||||
homeconnect==0.7.2
|
||||
|
|
|
@ -48,14 +48,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test transcript',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -67,7 +67,7 @@
|
|||
'data': dict({
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': 'No device or entity named test transcript',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': 'james_earl_jones',
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_START: 'tts-start'>,
|
||||
|
@ -75,9 +75,9 @@
|
|||
dict({
|
||||
'data': dict({
|
||||
'tts_output': dict({
|
||||
'media_id': 'media-source://tts/test?message=No+device+or+entity+named+test+transcript&language=en-US&voice=james_earl_jones',
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&voice=james_earl_jones",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'url': '/api/tts_proxy/e5e8e318b536f0a5455f993243a34521e7ad4d6d_en-us_031e2ec052_test.mp3',
|
||||
'url': '/api/tts_proxy/dae2cdcb27a1d1c3b07ba2c7db91480f9d4bfd8f_en-us_031e2ec052_test.mp3',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_END: 'tts-end'>,
|
||||
|
@ -137,14 +137,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en-US',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test transcript',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -156,7 +156,7 @@
|
|||
'data': dict({
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': 'No device or entity named test transcript',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': 'Arnold Schwarzenegger',
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_START: 'tts-start'>,
|
||||
|
@ -164,9 +164,9 @@
|
|||
dict({
|
||||
'data': dict({
|
||||
'tts_output': dict({
|
||||
'media_id': 'media-source://tts/test?message=No+device+or+entity+named+test+transcript&language=en-US&voice=Arnold+Schwarzenegger',
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&voice=Arnold+Schwarzenegger",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'url': '/api/tts_proxy/e5e8e318b536f0a5455f993243a34521e7ad4d6d_en-us_2657c1a8ee_test.mp3',
|
||||
'url': '/api/tts_proxy/dae2cdcb27a1d1c3b07ba2c7db91480f9d4bfd8f_en-us_2657c1a8ee_test.mp3',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_END: 'tts-end'>,
|
||||
|
@ -226,14 +226,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en-US',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test transcript',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -245,7 +245,7 @@
|
|||
'data': dict({
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': 'No device or entity named test transcript',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': 'Arnold Schwarzenegger',
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_START: 'tts-start'>,
|
||||
|
@ -253,9 +253,9 @@
|
|||
dict({
|
||||
'data': dict({
|
||||
'tts_output': dict({
|
||||
'media_id': 'media-source://tts/test?message=No+device+or+entity+named+test+transcript&language=en-US&voice=Arnold+Schwarzenegger',
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&voice=Arnold+Schwarzenegger",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'url': '/api/tts_proxy/e5e8e318b536f0a5455f993243a34521e7ad4d6d_en-us_2657c1a8ee_test.mp3',
|
||||
'url': '/api/tts_proxy/dae2cdcb27a1d1c3b07ba2c7db91480f9d4bfd8f_en-us_2657c1a8ee_test.mp3',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_END: 'tts-end'>,
|
||||
|
@ -338,14 +338,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test transcript',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -357,7 +357,7 @@
|
|||
'data': dict({
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': 'No device or entity named test transcript',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': 'james_earl_jones',
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_START: 'tts-start'>,
|
||||
|
@ -365,9 +365,9 @@
|
|||
dict({
|
||||
'data': dict({
|
||||
'tts_output': dict({
|
||||
'media_id': 'media-source://tts/test?message=No+device+or+entity+named+test+transcript&language=en-US&voice=james_earl_jones',
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&voice=james_earl_jones",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'url': '/api/tts_proxy/e5e8e318b536f0a5455f993243a34521e7ad4d6d_en-us_031e2ec052_test.mp3',
|
||||
'url': '/api/tts_proxy/dae2cdcb27a1d1c3b07ba2c7db91480f9d4bfd8f_en-us_031e2ec052_test.mp3',
|
||||
}),
|
||||
}),
|
||||
'type': <PipelineEventType.TTS_END: 'tts-end'>,
|
||||
|
|
|
@ -46,14 +46,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test transcript',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -64,16 +64,16 @@
|
|||
dict({
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': 'No device or entity named test transcript',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': 'james_earl_jones',
|
||||
})
|
||||
# ---
|
||||
# name: test_audio_pipeline.6
|
||||
dict({
|
||||
'tts_output': dict({
|
||||
'media_id': 'media-source://tts/test?message=No+device+or+entity+named+test+transcript&language=en-US&voice=james_earl_jones',
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&voice=james_earl_jones",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'url': '/api/tts_proxy/e5e8e318b536f0a5455f993243a34521e7ad4d6d_en-us_031e2ec052_test.mp3',
|
||||
'url': '/api/tts_proxy/dae2cdcb27a1d1c3b07ba2c7db91480f9d4bfd8f_en-us_031e2ec052_test.mp3',
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
|
@ -127,14 +127,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test transcript',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -145,16 +145,16 @@
|
|||
dict({
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': 'No device or entity named test transcript',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': 'james_earl_jones',
|
||||
})
|
||||
# ---
|
||||
# name: test_audio_pipeline_debug.6
|
||||
dict({
|
||||
'tts_output': dict({
|
||||
'media_id': 'media-source://tts/test?message=No+device+or+entity+named+test+transcript&language=en-US&voice=james_earl_jones',
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&voice=james_earl_jones",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'url': '/api/tts_proxy/e5e8e318b536f0a5455f993243a34521e7ad4d6d_en-us_031e2ec052_test.mp3',
|
||||
'url': '/api/tts_proxy/dae2cdcb27a1d1c3b07ba2c7db91480f9d4bfd8f_en-us_031e2ec052_test.mp3',
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
|
@ -220,14 +220,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test transcript',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -238,16 +238,16 @@
|
|||
dict({
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': 'No device or entity named test transcript',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': 'james_earl_jones',
|
||||
})
|
||||
# ---
|
||||
# name: test_audio_pipeline_with_enhancements.6
|
||||
dict({
|
||||
'tts_output': dict({
|
||||
'media_id': 'media-source://tts/test?message=No+device+or+entity+named+test+transcript&language=en-US&voice=james_earl_jones',
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&voice=james_earl_jones",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'url': '/api/tts_proxy/e5e8e318b536f0a5455f993243a34521e7ad4d6d_en-us_031e2ec052_test.mp3',
|
||||
'url': '/api/tts_proxy/dae2cdcb27a1d1c3b07ba2c7db91480f9d4bfd8f_en-us_031e2ec052_test.mp3',
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
|
@ -421,14 +421,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test transcript',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -439,16 +439,16 @@
|
|||
dict({
|
||||
'engine': 'test',
|
||||
'language': 'en-US',
|
||||
'tts_input': 'No device or entity named test transcript',
|
||||
'tts_input': "Sorry, I couldn't understand that",
|
||||
'voice': 'james_earl_jones',
|
||||
})
|
||||
# ---
|
||||
# name: test_audio_pipeline_with_wake_word_no_timeout.8
|
||||
dict({
|
||||
'tts_output': dict({
|
||||
'media_id': 'media-source://tts/test?message=No+device+or+entity+named+test+transcript&language=en-US&voice=james_earl_jones',
|
||||
'media_id': "media-source://tts/test?message=Sorry,+I+couldn't+understand+that&language=en-US&voice=james_earl_jones",
|
||||
'mime_type': 'audio/mpeg',
|
||||
'url': '/api/tts_proxy/e5e8e318b536f0a5455f993243a34521e7ad4d6d_en-us_031e2ec052_test.mp3',
|
||||
'url': '/api/tts_proxy/dae2cdcb27a1d1c3b07ba2c7db91480f9d4bfd8f_en-us_031e2ec052_test.mp3',
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
|
@ -778,7 +778,7 @@
|
|||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No area named are',
|
||||
'speech': 'Sorry, I am not aware of any area called are',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
|
|
@ -352,14 +352,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named do something',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -519,7 +519,7 @@
|
|||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named late added alias',
|
||||
'speech': 'Sorry, I am not aware of any device or entity called late added alias',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -539,7 +539,7 @@
|
|||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named kitchen light',
|
||||
'speech': 'Sorry, I am not aware of any device or entity called kitchen light',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -679,7 +679,7 @@
|
|||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named late added light',
|
||||
'speech': 'Sorry, I am not aware of any device or entity called late added light',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -759,7 +759,7 @@
|
|||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named kitchen light',
|
||||
'speech': 'Sorry, I am not aware of any device or entity called kitchen light',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -779,7 +779,7 @@
|
|||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named my cool light',
|
||||
'speech': 'Sorry, I am not aware of any device or entity called my cool light',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -919,7 +919,7 @@
|
|||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named kitchen light',
|
||||
'speech': 'Sorry, I am not aware of any device or entity called kitchen light',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -969,7 +969,7 @@
|
|||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named renamed light',
|
||||
'speech': 'Sorry, I am not aware of any device or entity called renamed light',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -1252,14 +1252,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test text',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -1292,14 +1292,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test text',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -1312,14 +1312,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test text',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -1352,14 +1352,14 @@
|
|||
'card': dict({
|
||||
}),
|
||||
'data': dict({
|
||||
'code': 'no_valid_targets',
|
||||
'code': 'no_intent_match',
|
||||
}),
|
||||
'language': 'en',
|
||||
'response_type': 'error',
|
||||
'speech': dict({
|
||||
'plain': dict({
|
||||
'extra_data': None,
|
||||
'speech': 'No device or entity named test text',
|
||||
'speech': "Sorry, I couldn't understand that",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
@ -1510,29 +1510,7 @@
|
|||
'unmatched_slots': dict({
|
||||
}),
|
||||
}),
|
||||
dict({
|
||||
'details': dict({
|
||||
'domain': dict({
|
||||
'name': 'domain',
|
||||
'text': '',
|
||||
'value': 'scene',
|
||||
}),
|
||||
}),
|
||||
'intent': dict({
|
||||
'name': 'HassTurnOn',
|
||||
}),
|
||||
'match': False,
|
||||
'sentence_template': '[activate|<turn>] <name> [scene] [on]',
|
||||
'slots': dict({
|
||||
'domain': 'scene',
|
||||
}),
|
||||
'source': 'builtin',
|
||||
'targets': dict({
|
||||
}),
|
||||
'unmatched_slots': dict({
|
||||
'name': 'this will not match anything',
|
||||
}),
|
||||
}),
|
||||
None,
|
||||
]),
|
||||
})
|
||||
# ---
|
||||
|
|
|
@ -147,8 +147,8 @@ async def test_conversation_agent(
|
|||
conversation.HOME_ASSISTANT_AGENT
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.conversation.default_agent.get_domains_and_languages",
|
||||
return_value={"homeassistant": ["dwarvish", "elvish", "entish"]},
|
||||
"homeassistant.components.conversation.default_agent.get_languages",
|
||||
return_value=["dwarvish", "elvish", "entish"],
|
||||
):
|
||||
assert agent.supported_languages == ["dwarvish", "elvish", "entish"]
|
||||
|
||||
|
@ -440,7 +440,7 @@ async def test_error_missing_entity(hass: HomeAssistant, init_components) -> Non
|
|||
assert result.response.error_code == intent.IntentResponseErrorCode.NO_VALID_TARGETS
|
||||
assert (
|
||||
result.response.speech["plain"]["speech"]
|
||||
== "No device or entity named missing entity"
|
||||
== "Sorry, I am not aware of any device or entity called missing entity"
|
||||
)
|
||||
|
||||
|
||||
|
@ -452,7 +452,10 @@ async def test_error_missing_area(hass: HomeAssistant, init_components) -> None:
|
|||
|
||||
assert result.response.response_type == intent.IntentResponseType.ERROR
|
||||
assert result.response.error_code == intent.IntentResponseErrorCode.NO_VALID_TARGETS
|
||||
assert result.response.speech["plain"]["speech"] == "No area named missing area"
|
||||
assert (
|
||||
result.response.speech["plain"]["speech"]
|
||||
== "Sorry, I am not aware of any area called missing area"
|
||||
)
|
||||
|
||||
|
||||
async def test_error_no_exposed_for_domain(
|
||||
|
@ -467,7 +470,8 @@ async def test_error_no_exposed_for_domain(
|
|||
assert result.response.response_type == intent.IntentResponseType.ERROR
|
||||
assert result.response.error_code == intent.IntentResponseErrorCode.NO_VALID_TARGETS
|
||||
assert (
|
||||
result.response.speech["plain"]["speech"] == "kitchen does not contain a light"
|
||||
result.response.speech["plain"]["speech"]
|
||||
== "Sorry, I am not aware of any light in the kitchen area"
|
||||
)
|
||||
|
||||
|
||||
|
@ -483,7 +487,8 @@ async def test_error_no_exposed_for_device_class(
|
|||
assert result.response.response_type == intent.IntentResponseType.ERROR
|
||||
assert result.response.error_code == intent.IntentResponseErrorCode.NO_VALID_TARGETS
|
||||
assert (
|
||||
result.response.speech["plain"]["speech"] == "bedroom does not contain a window"
|
||||
result.response.speech["plain"]["speech"]
|
||||
== "Sorry, I am not aware of any window in the bedroom area"
|
||||
)
|
||||
|
||||
|
||||
|
@ -596,5 +601,5 @@ async def test_all_domains_loaded(
|
|||
assert result.response.error_code == intent.IntentResponseErrorCode.NO_VALID_TARGETS
|
||||
assert (
|
||||
result.response.speech["plain"]["speech"]
|
||||
== "No device or entity named test light"
|
||||
== "Sorry, I am not aware of any device or entity called test light"
|
||||
)
|
||||
|
|
|
@ -581,6 +581,7 @@ async def test_http_api_no_match(
|
|||
|
||||
assert data == snapshot
|
||||
assert data["response"]["response_type"] == "error"
|
||||
assert data["response"]["data"]["code"] == "no_intent_match"
|
||||
|
||||
|
||||
async def test_http_api_handle_failure(
|
||||
|
@ -738,6 +739,7 @@ async def test_ws_api(
|
|||
|
||||
assert msg["success"]
|
||||
assert msg["result"] == snapshot
|
||||
assert msg["result"]["response"]["data"]["code"] == "no_intent_match"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("agent_id", AGENT_ID_OPTIONS)
|
||||
|
@ -1180,7 +1182,7 @@ async def test_ws_hass_agent_debug(
|
|||
"turn my cool light off",
|
||||
"turn on all lights in the kitchen",
|
||||
"how many lights are on in the kitchen?",
|
||||
"this will not match anything", # unmatched in results
|
||||
"this will not match anything", # None in results
|
||||
],
|
||||
}
|
||||
)
|
||||
|
@ -1190,6 +1192,9 @@ async def test_ws_hass_agent_debug(
|
|||
assert msg["success"]
|
||||
assert msg["result"] == snapshot
|
||||
|
||||
# Last sentence should be a failed match
|
||||
assert msg["result"]["results"][-1] is None
|
||||
|
||||
# Light state should not have been changed
|
||||
assert len(on_calls) == 0
|
||||
assert len(off_calls) == 0
|
||||
|
|
Loading…
Reference in New Issue