mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 06:37:52 +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 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 (
|
from .helpers import (
|
||||||
GoogleAssistantSDKAudioView,
|
GoogleAssistantSDKAudioView,
|
||||||
InMemoryStorage,
|
InMemoryStorage,
|
||||||
async_send_text_commands,
|
async_send_text_commands,
|
||||||
|
best_matching_language_code,
|
||||||
)
|
)
|
||||||
|
|
||||||
SERVICE_SEND_TEXT_COMMAND = "send_text_command"
|
SERVICE_SEND_TEXT_COMMAND = "send_text_command"
|
||||||
@ -164,9 +171,16 @@ class GoogleAssistantConversationAgent(conversation.AbstractConversationAgent):
|
|||||||
if not session.valid_token:
|
if not session.valid_token:
|
||||||
await session.async_ensure_token_valid()
|
await session.async_ensure_token_valid()
|
||||||
self.assistant = None
|
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]
|
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)
|
self.assistant = TextAssistant(credentials, self.language)
|
||||||
|
|
||||||
resp = await self.hass.async_add_executor_job(
|
resp = await self.hass.async_add_executor_job(
|
||||||
@ -174,7 +188,7 @@ class GoogleAssistantConversationAgent(conversation.AbstractConversationAgent):
|
|||||||
)
|
)
|
||||||
text_response = resp[0] or "<empty response>"
|
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)
|
intent_response.async_set_speech(text_response)
|
||||||
return conversation.ConversationResult(
|
return conversation.ConversationResult(
|
||||||
response=intent_response, conversation_id=user_input.conversation_id
|
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")
|
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:
|
class InMemoryStorage:
|
||||||
"""Temporarily store and retrieve data from in memory storage."""
|
"""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.const import SUPPORTED_LANGUAGE_CODES
|
||||||
from homeassistant.components.google_assistant_sdk.helpers import (
|
from homeassistant.components.google_assistant_sdk.helpers import (
|
||||||
DEFAULT_LANGUAGE_CODES,
|
DEFAULT_LANGUAGE_CODES,
|
||||||
|
best_matching_language_code,
|
||||||
default_language_code,
|
default_language_code,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -46,3 +47,42 @@ def test_default_language_code(hass: HomeAssistant) -> None:
|
|||||||
hass.config.language = "el"
|
hass.config.language = "el"
|
||||||
hass.config.country = "GR"
|
hass.config.country = "GR"
|
||||||
assert default_language_code(hass) == "en-US"
|
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