mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Don't prioritize "name" slot if it's a wildcard in default conversation agent (#117518)
* Don't prioritize "name" slot if it's a wildcard * Fix typing error
This commit is contained in:
parent
f31873a846
commit
daee3d8db0
@ -418,7 +418,9 @@ class DefaultAgent(ConversationEntity):
|
||||
language: str,
|
||||
) -> RecognizeResult | None:
|
||||
"""Search intents for a match to user input."""
|
||||
maybe_result: RecognizeResult | None = None
|
||||
name_result: RecognizeResult | None = None
|
||||
best_results: list[RecognizeResult] = []
|
||||
best_text_chunks_matched: int | None = None
|
||||
for result in recognize_all(
|
||||
user_input.text,
|
||||
lang_intents.intents,
|
||||
@ -426,18 +428,33 @@ class DefaultAgent(ConversationEntity):
|
||||
intent_context=intent_context,
|
||||
language=language,
|
||||
):
|
||||
if "name" in result.entities:
|
||||
return result
|
||||
if ("name" in result.entities) and (
|
||||
not result.entities["name"].is_wildcard
|
||||
):
|
||||
name_result = result
|
||||
|
||||
# Keep looking in case an entity has the same name
|
||||
maybe_result = result
|
||||
if (best_text_chunks_matched is None) or (
|
||||
result.text_chunks_matched > best_text_chunks_matched
|
||||
):
|
||||
# Only overwrite if more literal text was matched.
|
||||
# This causes wildcards to match last.
|
||||
best_results = [result]
|
||||
best_text_chunks_matched = result.text_chunks_matched
|
||||
elif result.text_chunks_matched == best_text_chunks_matched:
|
||||
# Accumulate results with the same number of literal text matched.
|
||||
# We will resolve the ambiguity below.
|
||||
best_results.append(result)
|
||||
|
||||
if maybe_result is not None:
|
||||
if name_result is not None:
|
||||
# Prioritize matches with entity names above area names
|
||||
return name_result
|
||||
|
||||
if best_results:
|
||||
# Successful strict match
|
||||
return maybe_result
|
||||
return best_results[0]
|
||||
|
||||
# Try again with missing entities enabled
|
||||
best_num_unmatched_entities = 0
|
||||
maybe_result: RecognizeResult | None = None
|
||||
for result in recognize_all(
|
||||
user_input.text,
|
||||
lang_intents.intents,
|
||||
|
@ -311,9 +311,9 @@ def _get_debug_targets(
|
||||
|
||||
def _get_unmatched_slots(
|
||||
result: RecognizeResult,
|
||||
) -> dict[str, str | int]:
|
||||
) -> dict[str, str | int | float]:
|
||||
"""Return a dict of unmatched text/range slot entities."""
|
||||
unmatched_slots: dict[str, str | int] = {}
|
||||
unmatched_slots: dict[str, str | int | float] = {}
|
||||
for entity in result.unmatched_entities_list:
|
||||
if isinstance(entity, UnmatchedTextEntity):
|
||||
if entity.text == MISSING_ENTITY:
|
||||
|
@ -6,5 +6,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/conversation",
|
||||
"integration_type": "system",
|
||||
"quality_scale": "internal",
|
||||
"requirements": ["hassil==1.6.1", "home-assistant-intents==2024.4.24"]
|
||||
"requirements": ["hassil==1.7.1", "home-assistant-intents==2024.4.24"]
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ ha-av==10.1.1
|
||||
ha-ffmpeg==3.2.0
|
||||
habluetooth==3.0.1
|
||||
hass-nabucasa==0.78.0
|
||||
hassil==1.6.1
|
||||
hassil==1.7.1
|
||||
home-assistant-bluetooth==1.12.0
|
||||
home-assistant-frontend==20240501.1
|
||||
home-assistant-intents==2024.4.24
|
||||
|
@ -1047,7 +1047,7 @@ hass-nabucasa==0.78.0
|
||||
hass-splunk==0.1.1
|
||||
|
||||
# homeassistant.components.conversation
|
||||
hassil==1.6.1
|
||||
hassil==1.7.1
|
||||
|
||||
# homeassistant.components.jewish_calendar
|
||||
hdate==0.10.8
|
||||
|
@ -858,7 +858,7 @@ habluetooth==3.0.1
|
||||
hass-nabucasa==0.78.0
|
||||
|
||||
# homeassistant.components.conversation
|
||||
hassil==1.6.1
|
||||
hassil==1.7.1
|
||||
|
||||
# homeassistant.components.jewish_calendar
|
||||
hdate==0.10.8
|
||||
|
@ -1122,3 +1122,57 @@ async def test_device_id_in_handler(hass: HomeAssistant, init_components) -> Non
|
||||
)
|
||||
assert result.response.response_type == intent.IntentResponseType.ACTION_DONE
|
||||
assert handler.device_id == device_id
|
||||
|
||||
|
||||
async def test_name_wildcard_lower_priority(
|
||||
hass: HomeAssistant, init_components
|
||||
) -> None:
|
||||
"""Test that the default agent does not prioritize a {name} slot when it's a wildcard."""
|
||||
|
||||
class OrderBeerIntentHandler(intent.IntentHandler):
|
||||
intent_type = "OrderBeer"
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.triggered = False
|
||||
|
||||
async def async_handle(
|
||||
self, intent_obj: intent.Intent
|
||||
) -> intent.IntentResponse:
|
||||
self.triggered = True
|
||||
return intent_obj.create_response()
|
||||
|
||||
class OrderFoodIntentHandler(intent.IntentHandler):
|
||||
intent_type = "OrderFood"
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.triggered = False
|
||||
|
||||
async def async_handle(
|
||||
self, intent_obj: intent.Intent
|
||||
) -> intent.IntentResponse:
|
||||
self.triggered = True
|
||||
return intent_obj.create_response()
|
||||
|
||||
beer_handler = OrderBeerIntentHandler()
|
||||
food_handler = OrderFoodIntentHandler()
|
||||
intent.async_register(hass, beer_handler)
|
||||
intent.async_register(hass, food_handler)
|
||||
|
||||
# Matches OrderBeer because more literal text is matched ("a")
|
||||
result = await conversation.async_converse(
|
||||
hass, "I'd like to order a stout please", None, Context(), None
|
||||
)
|
||||
assert result.response.response_type == intent.IntentResponseType.ACTION_DONE
|
||||
assert beer_handler.triggered
|
||||
assert not food_handler.triggered
|
||||
|
||||
# Matches OrderFood because "cookie" is not in the beer styles list
|
||||
beer_handler.triggered = False
|
||||
result = await conversation.async_converse(
|
||||
hass, "I'd like to order a cookie please", None, Context(), None
|
||||
)
|
||||
assert result.response.response_type == intent.IntentResponseType.ACTION_DONE
|
||||
assert not beer_handler.triggered
|
||||
assert food_handler.triggered
|
||||
|
@ -4,8 +4,14 @@ intents:
|
||||
data:
|
||||
- sentences:
|
||||
- "I'd like to order a {beer_style} [please]"
|
||||
OrderFood:
|
||||
data:
|
||||
- sentences:
|
||||
- "I'd like to order {food_name:name} [please]"
|
||||
lists:
|
||||
beer_style:
|
||||
values:
|
||||
- "stout"
|
||||
- "lager"
|
||||
food_name:
|
||||
wildcard: true
|
||||
|
Loading…
x
Reference in New Issue
Block a user