Conversation config (#86326)

* Restore conversation config

* Fall back to en for en_US, etc.

* Simplify config passing around

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
Michael Hansen 2023-01-20 20:39:49 -06:00 committed by GitHub
parent e1483ff746
commit 255611238b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 142 additions and 13 deletions

View file

@ -3,6 +3,7 @@ from __future__ import annotations
import asyncio
from collections import defaultdict
from collections.abc import Iterable
from dataclasses import dataclass
import logging
from pathlib import Path
@ -35,6 +36,21 @@ class LanguageIntents:
loaded_components: set[str]
def _get_language_variations(language: str) -> Iterable[str]:
"""Generate language codes with and without region."""
yield language
parts = re.split(r"([-_])", language)
if len(parts) == 3:
lang, sep, region = parts
if sep == "_":
# en_US -> en-US
yield f"{lang}-{region}"
# en-US -> en
yield lang
class DefaultAgent(AbstractConversationAgent):
"""Default agent for conversation agent."""
@ -44,12 +60,17 @@ class DefaultAgent(AbstractConversationAgent):
self._lang_intents: dict[str, LanguageIntents] = {}
self._lang_lock: dict[str, asyncio.Lock] = defaultdict(asyncio.Lock)
async def async_initialize(self):
# intent -> [sentences]
self._config_intents: dict[str, Any] = {}
async def async_initialize(self, config_intents):
"""Initialize the default agent."""
if "intent" not in self.hass.config.components:
await setup.async_setup_component(self.hass, "intent", {})
self.hass.data.setdefault(DOMAIN, {})
# Intents from config may only contains sentences for HA config's language
if config_intents:
self._config_intents = config_intents
async def async_process(
self,
@ -144,17 +165,20 @@ class DefaultAgent(AbstractConversationAgent):
# Don't check component again
loaded_components.add(component)
# Check for intents for this component with the target language
component_intents = get_intents(component, language)
if component_intents:
# Merge sentences into existing dictionary
merge_dict(intents_dict, component_intents)
# Check for intents for this component with the target language.
# Try en-US, en, etc.
for language_variation in _get_language_variations(language):
component_intents = get_intents(component, language_variation)
if component_intents:
# Merge sentences into existing dictionary
merge_dict(intents_dict, component_intents)
# Will need to recreate graph
intents_changed = True
_LOGGER.debug(
"Loaded intents component=%s, language=%s", component, language
)
# Will need to recreate graph
intents_changed = True
_LOGGER.debug(
"Loaded intents component=%s, language=%s", component, language
)
break
# Check for custom sentences in <config>/custom_sentences/<language>/
if lang_intents is None:
@ -179,6 +203,22 @@ class DefaultAgent(AbstractConversationAgent):
custom_sentences_path,
)
# Load sentences from HA config for default language only
if self._config_intents and (language == self.hass.config.language):
merge_dict(
intents_dict,
{
"intents": {
intent_name: {"data": [{"sentences": sentences}]}
for intent_name, sentences in self._config_intents.items()
}
},
)
intents_changed = True
_LOGGER.debug(
"Loaded intents from configuration.yaml",
)
if not intents_dict:
return None