mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
Add intelligent language matching for Google Assistant SDK Agents (#112600)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
f605c10f42
commit
deac59f1ee
@ -26,11 +26,18 @@ from homeassistant.helpers.config_entry_oauth2_flow import (
|
||||
)
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import DATA_MEM_STORAGE, DATA_SESSION, DOMAIN, SUPPORTED_LANGUAGE_CODES
|
||||
from .const import (
|
||||
CONF_LANGUAGE_CODE,
|
||||
DATA_MEM_STORAGE,
|
||||
DATA_SESSION,
|
||||
DOMAIN,
|
||||
SUPPORTED_LANGUAGE_CODES,
|
||||
)
|
||||
from .helpers import (
|
||||
GoogleAssistantSDKAudioView,
|
||||
InMemoryStorage,
|
||||
async_send_text_commands,
|
||||
best_matching_language_code,
|
||||
)
|
||||
|
||||
SERVICE_SEND_TEXT_COMMAND = "send_text_command"
|
||||
@ -164,9 +171,16 @@ class GoogleAssistantConversationAgent(conversation.AbstractConversationAgent):
|
||||
if not session.valid_token:
|
||||
await session.async_ensure_token_valid()
|
||||
self.assistant = None
|
||||
if not self.assistant or user_input.language != self.language:
|
||||
|
||||
language = best_matching_language_code(
|
||||
self.hass,
|
||||
user_input.language,
|
||||
self.entry.options.get(CONF_LANGUAGE_CODE),
|
||||
)
|
||||
|
||||
if not self.assistant or language != self.language:
|
||||
credentials = Credentials(session.token[CONF_ACCESS_TOKEN]) # type: ignore[no-untyped-call]
|
||||
self.language = user_input.language
|
||||
self.language = language
|
||||
self.assistant = TextAssistant(credentials, self.language)
|
||||
|
||||
resp = await self.hass.async_add_executor_job(
|
||||
@ -174,7 +188,7 @@ class GoogleAssistantConversationAgent(conversation.AbstractConversationAgent):
|
||||
)
|
||||
text_response = resp[0] or "<empty response>"
|
||||
|
||||
intent_response = intent.IntentResponse(language=user_input.language)
|
||||
intent_response = intent.IntentResponse(language=language)
|
||||
intent_response.async_set_speech(text_response)
|
||||
return conversation.ConversationResult(
|
||||
response=intent_response, conversation_id=user_input.conversation_id
|
||||
|
@ -113,6 +113,33 @@ def default_language_code(hass: HomeAssistant) -> str:
|
||||
return DEFAULT_LANGUAGE_CODES.get(hass.config.language, "en-US")
|
||||
|
||||
|
||||
def best_matching_language_code(
|
||||
hass: HomeAssistant, assist_language: str, agent_language: str | None = None
|
||||
) -> str:
|
||||
"""Get the best matching language, based on the preferred assist language and the configured agent language."""
|
||||
|
||||
# Use the assist language if supported
|
||||
if assist_language in SUPPORTED_LANGUAGE_CODES:
|
||||
return assist_language
|
||||
language = assist_language.split("-")[0]
|
||||
|
||||
# Use the agent language if assist and agent start with the same language part
|
||||
if agent_language is not None and agent_language.startswith(language):
|
||||
return best_matching_language_code(hass, agent_language)
|
||||
|
||||
# If assist and agent are not matching, try to find the default language
|
||||
default_language = DEFAULT_LANGUAGE_CODES.get(language)
|
||||
if default_language is not None:
|
||||
return default_language
|
||||
|
||||
# If no default agent is available, use the agent language
|
||||
if agent_language is not None:
|
||||
return best_matching_language_code(hass, agent_language)
|
||||
|
||||
# Fallback to the system default language
|
||||
return default_language_code(hass)
|
||||
|
||||
|
||||
class InMemoryStorage:
|
||||
"""Temporarily store and retrieve data from in memory storage."""
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
from homeassistant.components.google_assistant_sdk.const import SUPPORTED_LANGUAGE_CODES
|
||||
from homeassistant.components.google_assistant_sdk.helpers import (
|
||||
DEFAULT_LANGUAGE_CODES,
|
||||
best_matching_language_code,
|
||||
default_language_code,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -46,3 +47,42 @@ def test_default_language_code(hass: HomeAssistant) -> None:
|
||||
hass.config.language = "el"
|
||||
hass.config.country = "GR"
|
||||
assert default_language_code(hass) == "en-US"
|
||||
|
||||
|
||||
def test_best_matching_language_code(hass: HomeAssistant) -> None:
|
||||
"""Test best_matching_language_code."""
|
||||
hass.config.language = "es"
|
||||
hass.config.country = "MX"
|
||||
|
||||
# Assist Language is supported
|
||||
assert best_matching_language_code(hass, "de-DE", "en-AU") == "de-DE"
|
||||
assert best_matching_language_code(hass, "de-DE") == "de-DE"
|
||||
|
||||
# Assist Language is not supported, but agent language has the same "lang" part, and is supported
|
||||
assert best_matching_language_code(hass, "en", "en-AU") == "en-AU"
|
||||
assert best_matching_language_code(hass, "en-XYZ", "en-AU") == "en-AU"
|
||||
# Assist Language is not supported, but agent language has the same "lang" part, but is not supported
|
||||
assert best_matching_language_code(hass, "en", "en-XYZ") == "en-US"
|
||||
assert best_matching_language_code(hass, "en-XYZ", "en-ABC") == "en-US"
|
||||
|
||||
# Assist Language is not supported, agent is not matching or available, falling back to the default of assist lang
|
||||
assert best_matching_language_code(hass, "de", "en-AU") == "de-DE"
|
||||
assert best_matching_language_code(hass, "de-XYZ", "en-AU") == "de-DE"
|
||||
assert best_matching_language_code(hass, "de") == "de-DE"
|
||||
assert best_matching_language_code(hass, "de-XYZ") == "de-DE"
|
||||
|
||||
# Assist language is not existing at all, agent is supported
|
||||
assert best_matching_language_code(hass, "abc-XYZ", "en-AU") == "en-AU"
|
||||
|
||||
# Assist language is not existing at all, agent is not supported, falling back to the agent default
|
||||
assert best_matching_language_code(hass, "abc-XYZ", "de-XYZ") == "de-DE"
|
||||
|
||||
# Assist language is not existing at all, agent is not existing or available, falling back to system default
|
||||
assert best_matching_language_code(hass, "abc-XYZ", "def-XYZ") == "es-MX"
|
||||
assert best_matching_language_code(hass, "abc-XYZ") == "es-MX"
|
||||
|
||||
# Assist language is not existing at all, agent is not existing or available, system default is not supported
|
||||
hass.config.language = "el"
|
||||
hass.config.country = "GR"
|
||||
assert best_matching_language_code(hass, "abc-XYZ", "def-XYZ") == "en-US"
|
||||
assert best_matching_language_code(hass, "abc-XYZ") == "en-US"
|
||||
|
Loading…
x
Reference in New Issue
Block a user