From aa855482d6ef29545fbdb742e25e8494c0c237c7 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Thu, 7 Dec 2023 10:02:44 -0800 Subject: [PATCH] Get Language Support from Core (#37) * Add handler for Neon core profile updates Add `_languages` dict with handling of language API responses Updates default config to include languages supported in default Neon Core installation Closes #35 * Disable yet-to-be-implemented language API by default Catch MQ connection error exceptions in CLI entrypoint Override default location in Docker system config * Add configuration note RE language support * Add cli entrypoint to get languages Update Docker config to default to use language API * Update language support to use combined API Ensure default lang populates settings fields --------- Co-authored-by: Daniel McKnight --- README.md | 5 +++++ docker_overlay/etc/neon/neon.yaml | 11 +--------- neon_iris/cli.py | 8 +++++++ neon_iris/client.py | 35 ++++++++++++++++++++++++++++++- neon_iris/web_client.py | 11 ++++++---- 5 files changed, 55 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 07cf069..07a022f 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,11 @@ iris: webui_input_placeholder: "Chat with Neon" ``` +### Language Support +For Neon Core deployments that support language support queries via MQ, `languages` +may be removed and `enable_lang_api: True` added to configuration. This will use +the reported STT/TTS supported languages in place of any `iris` configuration. + ## Interfacing with a Diana installation The `iris` CLI includes utilities for interacting with a `Diana` backend. diff --git a/docker_overlay/etc/neon/neon.yaml b/docker_overlay/etc/neon/neon.yaml index c65b600..cdb38cb 100644 --- a/docker_overlay/etc/neon/neon.yaml +++ b/docker_overlay/etc/neon/neon.yaml @@ -15,16 +15,7 @@ iris: server_address: "0.0.0.0" server_port: 7860 default_lang: en-us - languages: - - en-us - - fr-fr - - es-es - - de-de - - it-it - - uk-ua - - nl-nl - - pt-pt - - ca-es + enable_lang_api: True location: city: diff --git a/neon_iris/cli.py b/neon_iris/cli.py index 90be32f..76353d5 100644 --- a/neon_iris/cli.py +++ b/neon_iris/cli.py @@ -140,6 +140,14 @@ def start_gradio(): click.echo("Unable to connect to MQ server") +@neon_iris_cli.command(help="Query Neon Core for supported languages") +def get_languages(): + from neon_iris.util import query_neon + _print_config() + resp = query_neon("neon.languages.get", {}) + click.echo(pformat(resp)) + + @neon_iris_cli.command(help="Transcribe an audio file") @click.option('--lang', '-l', default='en-us', help="language of input audio") diff --git a/neon_iris/client.py b/neon_iris/client.py index 639f538..a79984b 100644 --- a/neon_iris/client.py +++ b/neon_iris/client.py @@ -61,7 +61,8 @@ def __init__(self, mq_config: dict = None, config_dir: str = None): self.client_name = "unknown" self._config = mq_config or dict(Configuration()).get("MQ") self._connection = self._init_mq_connection() - + self._languages = dict() + self._language_init = Event() config_dir = config_dir or join(xdg_config_home(), "neon", "neon_iris") self._user_config = get_neon_user_config(config_dir) @@ -71,6 +72,22 @@ def __init__(self, mq_config: dict = None, config_dir: str = None): self.audio_cache_dir = join(xdg_cache_home(), "neon", "neon_iris") makedirs(self.audio_cache_dir, exist_ok=True) + config = Configuration().get("iris", {}) + + # Collect supported languages + if config.get("enable_lang_api"): + message = self._build_message("neon.languages.get", {}) + self._send_message(message) + + if self._language_init.wait(30): + LOG.debug(f"Got language support: {self._languages}") + + if not self._languages: + lang_config = config.get('languages') or [] + self._languages['stt'] = lang_config + self._languages['tts'] = lang_config + LOG.debug(f"Using supported langs configuration: {self._languages}") + @property def uid(self) -> str: """ @@ -160,6 +177,8 @@ def handle_neon_response(self, channel, method, _, body): self._handle_clear_data(message) elif message.msg_type == "klat.error": self.handle_error_response(message) + elif message.msg_type == "neon.languages.get.response": + self._handle_supported_languages(message) elif message.msg_type.endswith(".response"): self.handle_api_response(message) else: @@ -244,6 +263,14 @@ def _clear_audio_cache(): # (CACHES, PROFILE, ALL_TR, CONF_LIKES, CONF_DISLIKES, ALL_DATA, # ALL_MEDIA, ALL_UNITS, ALL_LANGUAGE + def _handle_supported_languages(self, message: Message): + self._languages = message.data + if not all((x in self._languages for x in ("stt", "tts"))): + LOG.warning(f"Language support incomplete response: {self._languages}") + self._languages['stt'].sort() + self._languages['tts'].sort() + self._language_init.set() + def send_utterance(self, utterance: str, lang: str = "en-us", username: Optional[str] = None, user_profiles: Optional[list] = None, @@ -322,6 +349,12 @@ def _send_audio(self, audio_file: str, lang: str, new_only=True)} self._send_serialized_message(serialized) + def _send_message(self, message: Message): + serialized = {"msg_type": message.msg_type, + "data": message.data, + "context": message.context} + self._send_serialized_message(serialized) + def _send_serialized_message(self, serialized: dict): try: serialized['context']['timing']['client_sent'] = time() diff --git a/neon_iris/web_client.py b/neon_iris/web_client.py index a2e3a52..60a3dc8 100644 --- a/neon_iris/web_client.py +++ b/neon_iris/web_client.py @@ -218,16 +218,19 @@ def run(self): # Define settings UI with gradio.Row(): with gradio.Column(): - lang = self.get_lang(client_session.value) + lang = self.get_lang(client_session.value).split('-')[0] stt_lang = gradio.Radio(label="Input Language", - choices=self.supported_languages, + choices=self._languages.get("stt") + or self.supported_languages, value=lang) tts_lang = gradio.Radio(label="Response Language", - choices=self.supported_languages, + choices=self._languages.get("tts") + or self.supported_languages, value=lang) tts_lang_2 = gradio.Radio(label="Second Response Language", choices=[None] + - self.supported_languages, + (self._languages.get("tts") or + self.supported_languages), value=None) with gradio.Column(): time_format = gradio.Radio(label="Time Format",