diff --git a/.github/workflows/shell-lint.yml b/.github/workflows/shell-lint.yml index fb27dcfb..e18c6ec2 100644 --- a/.github/workflows/shell-lint.yml +++ b/.github/workflows/shell-lint.yml @@ -10,3 +10,5 @@ jobs: uses: actions/checkout@v1 - name: Run ShellCheck uses: azohra/shell-linter@latest + with: + path: "*.sh" diff --git a/.gitignore b/.gitignore index 7f229771..975950e5 100644 --- a/.gitignore +++ b/.gitignore @@ -141,6 +141,9 @@ logs certificates/* !certificates/.gitkeep +# Ignore the contents of the "src/client/assets" directory +src/client/assets/* + # Ignore the contents of the "src/client/bundles" directory src/client/bundles/* @@ -152,6 +155,9 @@ src/client/config/* # Ignore the contents of the "src/client/log" directory src/client/log/* +# Ignore the contents of the "src/client/serial_communication" directory +src/client/serial_communication/* + # Ignore the contents of the "src/server/skills_db" directory except for the file # named "open_the_web_browser.json". src/server/skills_db/* diff --git a/.shellcheckrc b/.shellcheckrc index df769d90..33a1bee4 100644 --- a/.shellcheckrc +++ b/.shellcheckrc @@ -12,7 +12,8 @@ shell=bash # Enable specific checks (comma-separated) # To disable a check, prefix it with "no" #enable=SC1000,noSC2000 -disable=SC1090,SC1091,SC1087 +#disable=SC1090,SC1091,SC1087 +disable=SC1090,SC1091,SC1087,SC2016,SC2154 # Ignore specific errors in certain lines # Example: Ignore SC1000 and SC2000 in lines 5 and 10 diff --git a/INSTALL b/INSTALL index ee199ca6..62ab67dc 100644 --- a/INSTALL +++ b/INSTALL @@ -982,9 +982,9 @@ Commbase bundles two Whisper-based STT engines to choose from: commbase-stt-whis Every Commbase STT engine has its advantages and disadvantages. -The proactive STT engine continuously changes among 4 strokes: listening, active, processing, and stopped, which makes it more suitable for talkative devices that do not stop capturing and processing sound in time, for example, specific droids and robots. Its learning curve is higher compared to the simplified use of a rec button for the reactive STT engine. The adaptability to a single recording countdown time rhythm ensures that the use experience is not only precise but also synchronized. This STT engine experience can be improved by hardware, for example: LED lightning, sounds, and other signals for the user. +The proactive STT engine continuously changes among 4 strokes: listening, active, processing, and stopped, which makes it more suitable for talkative devices that do not stop capturing and processing sound in time, for example, specific droids and robots. Its learning curve is higher compared to the simplified use of a rec button for the reactive STT engine. It has a customizable countdown timer to ensure that the engine takes pauses when the user is not using it, for saving system resources like power and GPU. This STT engine experience can be improved by hardware, for example: LED lightning, sounds, and other signals for the user. This mode is insecure by default, because anybody can tell your app voice commands, including commands to turn off Commbase, reload STT engines, change language, and so on, unless you disable or program critical options and skill to ask for user intervention to allow or deny them to run. -The reactive STT engine requires the Commbase application to be actively open in the foreground and in focus. There is a keybinding you can set up to be able to send requests to the application running in the background, unfocused, without using a keyboard key (the information is in the User's Guide, in the section "4 Set Up Microphones and Audio Keybindings"). There is also an alternative setup that involves configuring the recorder-transmitter script reccomm.sh on a remote host. It's worth noting that this host isn't confined to being a traditional computer; it can also be, for example, an Android smartphone or a Raspberry Pi equipped with Wi-Fi. +The reactive STT engine requires the Commbase application to be actively open in the foreground and in focus. There is a keybinding you can set up to be able to send requests to the application running in the background, unfocused, without using a keyboard key (the information is in the User's Guide, in the section "4 Set Up Microphones and Audio Keybindings"). There is also an alternative setup that involves configuring the recorder-transmitter script reccomm.sh on a remote host. It's worth noting that this host isn't confined to being a traditional computer; it can also be, for example, an Android smartphone or a Raspberry Pi equipped with Wi-Fi. This mode is secure by default, as users can select appropriate time windows to issue voice commands without disrupting Commbase's functionality with external noises or invalid commands spoken to the app by others within its active radius. You will find more information about both STT engines in the User's Guide. diff --git a/README.md b/README.md index 94e2dc4f..e803d5b3 100644 --- a/README.md +++ b/README.md @@ -89,8 +89,7 @@ This project is coded and organized like this: │ ├── libcommbase │ │ ├── routines │ │ └── skills -│ │ ├── parsers -│ │ └── runners +│ │ └── skills_db │ └── resources │ ├── bundles │ │ └── sounds @@ -123,6 +122,9 @@ This project is coded and organized like this: │ └── reset_commbase.conf ├── src # This directory contains user-generated source code │ ├── client +│ │ ├── assets # Stores different types of assets, such as images, fonts, and ASCII art +│ │ │ ├── ascii +│ │ │ └── docs # Stores your app User's Guide │ │ ├── bundles │ │ │ ├── audiobooks │ │ │ │ └── Robinson_Crusoe @@ -134,7 +136,16 @@ This project is coded and organized like this: │ │ │ └── openai_whisper_models │ │ │ ├── base │ │ │ └── ... -│ │ └── log +│ │ ├── log +│ │ └── serial_communication +│ │ ├── arduino +│ │ │ ├── arduino_0 +│ │ │ │ ├── commbase_hardware_notifications +│ │ │ │ │ ├── speech_to_text_engine_component +│ │ │ │ │ └── ... +│ │ │ │ └── ... +│ │ │ └── ... +│ │ └── ... │ ├── server │ │ └── skills_db │ │ ├── arduino diff --git a/assets/ascii/avatar.asc b/assets/ascii/avatar.asc deleted file mode 100644 index c38fcb97..00000000 --- a/assets/ascii/avatar.asc +++ /dev/null @@ -1,21 +0,0 @@ - ____ ________ _ ____ _________ - _ _ ___ __-___╔⌂_┐ __________ _ - __ _'_ ║⌂j░-╬]j` ▒╨¿r«Ñ__r- ___ - ___ tU 7╩╫╫DÜ╨« ╓DÜ╫n╫]≥╫*_____ - __ __]7X^╟*╗║▀╨ª╢▒▀▌ßBÜ>«"___«_' - ___*,"7ܼ═▀#Ñ▌╫▒╫╬Q╫¼▌U╬░%.≡ ___ - __ _`ju└╠╦j░╟▒╫▌▓▀╠Å▀╬╫Å¡╚n _ _ - ___-«░τ╬Ñ▌≡╣▒╫▀╫M╬▄Å▀╬]Ü; ` __ - _____`,√²j╙▒╬▓▒▀╫▒╫φÑ╠H]d^_ _ ^ - __ ÖKÖ5▒Ω7╬▌▄▓▀▒▒▀░«H«`r ⌐__ _ - ___ _~-_²``rΩ"W╫6╬]î═''" ______ - ,___ ╘_-____ │ÅÑ╩_ __ _ⁿ╧~__ ┌ - ^%╟¿,««__,∩ _« ▒Ñ___╔__ ]æⁿjU'_ - __ⁿ╨┤╢▄▒╟╜Q_ __╟ß__j½Φ░╫╢╫S╨╚` _ - __ ~²╠▒▓▌▌ÑH __╫╕__`²D╫╨╫╜^^____ - _____\8╫RÑÅ░___╟P___╠≤NΩⁿⁿ______ - _____ __Ѽ░H_ ╠M ╦░_╘________ - _____ _ "]ñ▄╪═,--."Y*╛___ _____ - ___________ ______~ __________ - __ __________``,_______ -______ - ⁿ___ ________╚ _ ____`_________ diff --git a/assets/docs/User's Guide.md b/assets/docs/User's Guide.md index 47a2e21d..0046becf 100644 --- a/assets/docs/User's Guide.md +++ b/assets/docs/User's Guide.md @@ -890,6 +890,12 @@ The default version of the file **commbase.conf** contains the next values: - `bundles/commbase-recorder-transmitter-b/reccomm.sh` (Default): The route to the Bash version of the recorder-transmitter. The Bash script can be set up to run simultaneously as a remote recorder-transmitter despite this configuration. - `bundles/commbase-recorder-transmitter-s/reccomm.sh`: The route to the Shell version of the recorder-transmitter. The Shell (POSIX) script can be set up to run simultaneously as a remote recorder-transmitter despite this configuration. +**CUSTOM_RECORDER_TRANSMITTER_FILE**: + - Description: It allows to replace the default recorder-transmitter chosen with the route to a new custom one. Other custom recorder-transmitter applications can be set up in a different path and executed remotely (for example, this app can be an Android or iPhone app for smartphones), but in those cases you do not need to provide any path to a custom transmitter executable file here. + - Possible values: Any route to a custom recorder-transmitter file. + - Example value: + -`bundles/commbase-recorder-transmitter-x/reccomm.sh` (Default): The path to a custom recorder-transmitter executable. + - **STT_ENGINE_MODEL_DIRECTORY**: - Description: It specifies the path to the directory of the current STT engine's model in use. In order to facilitate internationalization, the directory resides in **bundles/libcommbase/resources/i18n/** and **src/client/i18n/**. Check out the variable `STT_ENGINE_MODEL_SUBDIRECTORY`. - Possible values: @@ -904,7 +910,7 @@ The default version of the file **commbase.conf** contains the next values: - `large`: If set to this value, the STT engine uses the OpenAI Whisper model "large". - **STT_ENGINE_PATH**: - - Description: It specifies the path to the current STT engine's executable or script file bundled with Commbase. It is updated to one of following possible values (TODO: create a skill command and a Keybinding for this.) + - Description: It specifies the path to the current STT engine's executable or script file bundled with Commbase. Just change this path to switch from one STT engine to another. The change can be perfectly done with a skill command and/or a keybinding. - Possible values: - `$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py` (Default): Reactive means the engine is always lazily listening, processing the voice messages only when they arrive. Therefore, engine has 2 strokes: passive and processing. - `$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py`: Proactive means the engine continuously changes among 4 strokes: listening, active, processing, and stopped. @@ -918,6 +924,11 @@ The default version of the file **commbase.conf** contains the next values: - Possible values: - `/bundles/commbase-stt-whisper-reactive-p/client_data/recording.wav` (Default): The Commbase STT Whisper reactive p client temporary audio recording file. The purpose of this file is for storing audio data obtained from the execution of the bash script **commrecorder.sh** in the directory **bundles/commbase-stt-whisper-reactive-p/**. **commbase_stt_whisper_reactive_p.py** monitors the modification time of this file and, upon detecting changes, transcribes the audio content using the Whisper ASR (Automatic Speech Recognition) model. The transcribed text is then printed and appended to the chatroom pane. +- **STT_ENGINE_PROCESSING_TIME_VISIBLE_ON**: + - Description: It specifies whether yes or not the running STT displays the speech processing time in the STT engine pane after every processing is complete. + - Possible values: True or False. + - Default value: `False` (Default): Set to false, the STT engine does not display the speech processing time in the STT engine pane after every processing is complete. + - **CHAT_LOG_FILE**: - Possible values: - `/data/.chat_log.txt` (Default): The chat log file likely stores a record of interactions or conversations. @@ -1231,17 +1242,65 @@ The default version of the file **commbase.conf** contains the next values: - Example value: - `3600` (Default): Set to 3600 seconds (equivalent to 1 hour and 0 minutes), indicates that the system checks for pending tasks approximately every 60 minutes. -- **EXTERNAL_STORAGE_DRIVE_01_TAG**: +- **COMMBASE_HARDWARE_NOTIFICATIONS_ON**: + - Description: Indicates whether Commbase hardware notifications are enabled or disabled. If set to "True", hardware notifications are enabled; otherwise, they are disabled. + - Possible values: "True" or "False". Set to "True" only if you are making Commbase hardware, such as: hardware interfaces, a speech to text engine component, or any other hardware device based on Commbase (droids, smart appliances, vehicles, etc.) Check out the existent Commbase hardware variables. + - Example value: + - `False` (Default): Hardware notifications are disabled. + +- **COMMBASE_HARDWARE_NOTIFICATION_LISTENING_START_ON**: + - Description: Indicates whether Commbase hardware notifications for the start of the STT engines listening process are enabled or disabled. Check out the other existent Commbase hardware variables. + - Possible values: "True" or "False". + - Example value: + - `True` (Default): Notifications for the start of the listening process are enabled. + +- **COMMBASE_HARDWARE_NOTIFICATION_LISTENING_STOP_ON**: + - Description: Indicates whether Commbase hardware notifications for the stop of the STT engines listening process are enabled or disabled. Check out the other existent Commbase hardware variables. + - Possible values: "True" or "False". + - Example value: + - `True` (Default): Notifications for the stop of the listening process are enabled. + +- **COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_START_ON**: + - Description: Indicates whether Commbase hardware notifications for the start of the STT engines processing are enabled or disabled. Check out the other existent Commbase hardware variables. + - Possible values: "True" or "False". + - Example value: + - `True` (Default): Notifications for the start of the processing are enabled. + +- **COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_STOP_ON**: + - Description: Indicates whether Commbase hardware notifications for the stop of the STT engines processing are enabled or disabled. Check out the other existent Commbase hardware variables. + - Possible values: "True" or "False". + - Example value: + - `True` (Default): Notifications for the stop of the processing are enabled. + +- **COMBASE_HARDWARE_DEVICE_0**: + - Description: The path of the hardware device used for communication, for example, an Arduino or any other microcontroller. Check out the other existent Commbase hardware variables. + - Possible values: A valid path to a hardware device. + - Example value: + - `/dev/ttyACM0`: Path to hardware device 0. + +- **COMMBASE_HARDWARE_COMMAND_LISTENING_START_FILE**: + - Description: The path to the file containing the command to start STT engines listening on the Commbase hardware. Check out the other existent Commbase hardware variables. + - Possible values: A valid file path. + - Example value: + - `/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/listening_start.dat`: Path to the file for starting the working STT engine listening process. + +- **COMMBASE_HARDWARE_COMMAND_LISTENING_STOP_FILE**: + - Description: The path to the file containing the command to stop STT engines listening on the Commbase hardware. Check out the other existent Commbase hardware variables. + - Possible values: A valid file path. - Example value: - - `WD1` (Default): This tag is used to distinguish or label the specific external storage drive, allowing easy identification and referencing within a system and/or application. + - `/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/listening_stop.dat`: Path to the file for stopping the working STT engine listening process. -- **EXTERNAL_STORAGE_DRIVE_02_TAG**: +- **COMMBASE_HARDWARE_COMMAND_PROCESSING_START_FILE**: + - Description: The path to the file containing the command to start STT engines processing on the Commbase hardware. Check out the other existent Commbase hardware variables. + - Possible values: A valid file path. - Example value: - - `WD2` (Default): This tag is used to distinguish or label the specific external storage drive, allowing easy identification and referencing within a system and/or application. + - `/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/processing_start.dat`: Path to the file for starting the working STT engine processing. -- **DEV_PROJECT_DIRECTORY_NAME**: +- **COMMBASE_HARDWARE_COMMAND_PROCESSING_STOP_FILE**: + - Description: The path to the file containing the command to stop STT engines processing on the Commbase hardware. Check out the other existent Commbase hardware variables. + - Possible values: A valid file path. - Example value: - - `YOUR_DEV_PROJECT_DIRECTORY_NAME_HERE` (Default): It can be used to indicate the specific directory or folder where a custom development project is located. + - `/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/processing_stop.dat`: Path to the file for stopping the working STT engine processing. Please ensure that these environment variables are correctly set with the appropriate values before running the application. diff --git a/bundles/commbase-data-exchange/server/client_data/json_1.json b/bundles/commbase-data-exchange/server/client_data/json_1.json index 30af7424..ba62191f 100644 --- a/bundles/commbase-data-exchange/server/client_data/json_1.json +++ b/bundles/commbase-data-exchange/server/client_data/json_1.json @@ -1 +1 @@ -{"messages": [{"language": "en_us"}, {"control": ""}, {"current_request": "tttt"}, {"previous_request": "tttt"}, {"current_response": ""}, {"runtime": ""}, {"source_code_display": ""}, {"source_code": ""}]} \ No newline at end of file +{"messages": [{"language": "en_us"}, {"control": ""}, {"current_request": "--select-stt-engine"}, {"previous_request": "--select-stt-engine"}, {"current_response": ""}, {"runtime": ""}, {"source_code_display": ""}, {"source_code": ""}]} \ No newline at end of file diff --git a/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py b/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py index 1efde143..2c316c51 100755 --- a/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py +++ b/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py @@ -42,19 +42,34 @@ # Imports import io import os -from pydub import AudioSegment import speech_recognition as sr # Requires pyaudio +import subprocess import tempfile +import time import whisper from config import CONFIG_FILE_PATH -from file_paths import get_chat_log_file +from file_paths import ( + get_chat_log_file, + get_commbase_hardware_command_listening_start_file, + get_commbase_hardware_command_listening_stop_file, + get_commbase_hardware_command_processing_start_file, + get_commbase_hardware_command_processing_stop_file, + get_commbase_hardware_device_0 +) from functions import ( get_assistant_log_severity_levels_on, get_chat_participant_names, + get_commbase_hardware_notifications_on, + get_commbase_hardware_notification_listening_start_on, + get_commbase_hardware_notification_listening_stop_on, + get_commbase_hardware_notification_processing_start_on, + get_commbase_hardware_notification_processing_stop_on, get_log_severity_level_2, get_stt_engine_language, - get_stt_whisper_proactive_timeout + get_stt_whisper_proactive_timeout, + stt_engine_processing_time_visible_on ) +from pydub import AudioSegment # A temporary directory and a file path within that directory temp_file = tempfile.mkdtemp() @@ -67,6 +82,198 @@ end_user_name, assistant_name = get_chat_participant_names() +def notify_hardware_about_listening_start(): + """ + Notifies the hardware about the start of the listening process. + + This function sends a signal to the hardware to indicate that the + listening process has started. It constructs a command to be executed, + which involves reading a command from a file and redirecting its output to + a hardware device. If the hardware is connected and accessible, the + command is executed successfully. + + Returns: + None + + Raises: + subprocess.CalledProcessError: If the subprocess command fails. + Exception: If any other error occurs during the execution. + + Note: + Ensure that the paths retrieved by + `get_commbase_hardware_command_listening_start_file()` and + `get_commbase_hardware_device_0()` functions are correctly configured. + """ + # Define the paths + hardware_command = get_commbase_hardware_command_listening_start_file() + hardware_device = get_commbase_hardware_device_0() + + # If any hardware is connected to the device + if os.path.exists(hardware_device): + + try: + # Construct the command and its arguments + command = ['cat', hardware_command] + redirect_to_device = ['>', hardware_device] + + # Run the command + subprocess.run(command + redirect_to_device, check=True) + for item in command: + print(item, end=' ') + + except subprocess.CalledProcessError as e: + print(f"Error executing subprocess command: {e}") + except Exception as e: + print(f"Other error occurred: {e}") + # discourse_data_exchange_client_error() + else: + print(f"The device file {hardware_device} does not exist, or it is not connected.") + + +def notify_hardware_about_listening_stop(): + """ + Notifies the hardware about the stop of the listening process. + + This function sends a signal to the hardware to indicate that the + listening process has stopped. It constructs a command to be executed, + which involves reading a command from a file and redirecting its output to + a hardware device. If the hardware is connected and accessible, the + command is executed successfully. + + Returns: + None + + Raises: + subprocess.CalledProcessError: If the subprocess command fails. + Exception: If any other error occurs during the execution. + + Note: + Ensure that the paths retrieved by + `get_commbase_hardware_command_listening_stop_file()` and + `get_commbase_hardware_device_0()` functions are correctly configured. + """ + # Define the paths + hardware_command = get_commbase_hardware_command_listening_stop_file() + hardware_device = get_commbase_hardware_device_0() + + # If any hardware is connected to the device + if os.path.exists(hardware_device): + + try: + # Construct the command and its arguments + command = ['cat', hardware_command] + redirect_to_device = ['>', hardware_device] + + # Run the command + subprocess.run(command + redirect_to_device, check=True) + for item in command: + print(item, end=' ') + + except subprocess.CalledProcessError as e: + print(f"Error executing subprocess command: {e}") + except Exception as e: + print(f"Other error occurred: {e}") + # discourse_data_exchange_client_error() + else: + print(f"The device file {hardware_device} does not exist, or it is not connected.") + + +def notify_hardware_about_processing_start(): + """ + Notifies the hardware about the start of the processing process. + + This function sends a signal to the hardware to indicate that the + processing process has started. It constructs a command to be executed, + which involves reading a command from a file and redirecting its output to + a hardware device. If the hardware is connected and accessible, the + command is executed successfully. + + Returns: + None + + Raises: + subprocess.CalledProcessError: If the subprocess command fails. + Exception: If any other error occurs during the execution. + + Note: + Ensure that the paths retrieved by + `get_commbase_hardware_command_processing_start_file()` and + `get_commbase_hardware_device_0()` functions are correctly configured. + """ + # Define the paths + hardware_command = get_commbase_hardware_command_processing_start_file() + hardware_device = get_commbase_hardware_device_0() + + # If any hardware is connected to the device + if os.path.exists(hardware_device): + + try: + # Construct the command and its arguments + command = ['cat', hardware_command] + redirect_to_device = ['>', hardware_device] + + # Run the command + subprocess.run(command + redirect_to_device, check=True) + for item in command: + print(item, end=' ') + + except subprocess.CalledProcessError as e: + print(f"Error executing subprocess command: {e}") + except Exception as e: + print(f"Other error occurred: {e}") + # discourse_data_exchange_client_error() + else: + print(f"The device file {hardware_device} does not exist, or it is not connected.") + + +def notify_hardware_about_processing_stop(): + """ + Notifies the hardware about the stop of the processing process. + + This function sends a signal to the hardware to indicate that the + processing process has started. It constructs a command to be executed, + which involves reading a command from a file and redirecting its output to + a hardware device. If the hardware is connected and accessible, the + command is executed successfully. + + Returns: + None + + Raises: + subprocess.CalledProcessError: If the subprocess command fails. + Exception: If any other error occurs during the execution. + + Note: + Ensure that the paths retrieved by + `get_commbase_hardware_command_processing_stop_file()` and + `get_commbase_hardware_device_0()` functions are correctly configured. + """ + # Define the paths + hardware_command = get_commbase_hardware_command_processing_stop_file() + hardware_device = get_commbase_hardware_device_0() + + # If any hardware is connected to the device + if os.path.exists(hardware_device): + + try: + # Construct the command and its arguments + command = ['cat', hardware_command] + redirect_to_device = ['>', hardware_device] + + # Run the command + subprocess.run(command + redirect_to_device, check=True) + for item in command: + print(item, end=' ') + + except subprocess.CalledProcessError as e: + print(f"Error executing subprocess command: {e}") + except Exception as e: + print(f"Other error occurred: {e}") + # discourse_data_exchange_client_error() + else: + print(f"The device file {hardware_device} does not exist, or it is not connected.") + + def listen(): """ Initializes a speech recognizer, captures audio input from a microphone, @@ -92,6 +299,13 @@ def listen(): save_path = listen() print(f"Audio file saved at: {save_path}") """ + # Set the values of the commbase hardware notification configuration + # variables + commbase_hardware_notifications_on = get_commbase_hardware_notifications_on() + commbase_hardware_notification_listening_start_on = get_commbase_hardware_notification_listening_start_on() + commbase_hardware_notification_listening_stop_on = get_commbase_hardware_notification_listening_stop_on() + commbase_hardware_notification_processing_start_on = get_commbase_hardware_notification_processing_start_on() + commbase_hardware_notification_processing_stop_on = get_commbase_hardware_notification_processing_stop_on() # Set the values returned by get_stt_whisper_proactive_timeout(). stt_engine_timeout = get_stt_whisper_proactive_timeout() listener = sr.Recognizer() # Create an instance of Recognizer @@ -101,17 +315,32 @@ def listen(): # for index, name in enumerate(sr.Microphone.list_microphone_names()): # print("Microphone with name \"{1}\" found for `Microphone(device_index={0})`".format(index, name)) # listener.adjust_for_ambient_noise(source) + if commbase_hardware_notifications_on == "True": + if commbase_hardware_notification_processing_stop_on == "True": + notify_hardware_about_processing_stop() + if commbase_hardware_notification_listening_start_on == "True": + notify_hardware_about_listening_start() try: audio = listener.listen(source, timeout=int(stt_engine_timeout)) # Set a timeout=15 (in seconds) discourse = "Processing..." print(f"{assistant_name} {discourse}") + if commbase_hardware_notifications_on == "True": + if commbase_hardware_notification_listening_stop_on == "True": + notify_hardware_about_listening_stop() + if commbase_hardware_notification_processing_start_on == "True": + notify_hardware_about_processing_start() data = io.BytesIO(audio.get_wav_data()) audio_clip = AudioSegment.from_file(data) audio_clip.export(save_path, format='wav') except sr.WaitTimeoutError: discourse = "Speech stopped. Recognizing..." print(f"{assistant_name} {discourse}") + if commbase_hardware_notifications_on == "True": + if commbase_hardware_notification_processing_stop_on == "True": + notify_hardware_about_processing_stop() + if commbase_hardware_notification_listening_stop_on == "True": + notify_hardware_about_listening_stop() return save_path @@ -205,10 +434,19 @@ def main(): to a temporary file using the `write_to_temp_file` function. It ensures proper cleanup of the temporary file by closing it in the `finally` block. """ + processing_time_visible_on = stt_engine_processing_time_visible_on() try: while True: - response = recognize_audio(listen()) - print(f"{end_user_name} {response}") + if processing_time_visible_on == "True": + start_time = time.time() # Record the start time + response = recognize_audio(listen()) + print(f"{end_user_name} {response}") + end_time = time.time() # Record the end time + elapsed_time = end_time - start_time # Calculate the elapsed time + print(f"Elapsed time from listening to processing: {elapsed_time} seconds") + else: + response = recognize_audio(listen()) + print(f"{end_user_name} {response}") # Write the transcribed text to a temporary file write_to_temp_file(response) diff --git a/bundles/commbase-stt-whisper-proactive-p/file_paths.py b/bundles/commbase-stt-whisper-proactive-p/file_paths.py index d9acad23..7d3ad388 100644 --- a/bundles/commbase-stt-whisper-proactive-p/file_paths.py +++ b/bundles/commbase-stt-whisper-proactive-p/file_paths.py @@ -66,3 +66,153 @@ def get_chat_log_file(): # If the variable was not found, return None return None + + +def get_commbase_hardware_command_listening_start_file(): + """ + Retrieves the value of the COMMBASE_HARDWARE_COMMAND_LISTENING_START_FILE + variable from the configuration file. + + Returns: + str or None: The value of the variable if found, or None if not found. + """ + # Initialize variable + listening_start_file = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMMBASE_HARDWARE_COMMAND_LISTENING_START_FILE": + # Remove the quotes from the value of the variable + listening_start_file = CONFIG_FILE_DIR + value.strip()[1:-1] + + # Check if the variable was found + if listening_start_file is not None: + return listening_start_file + + # If the variable was not found, return None + return None + + +def get_commbase_hardware_command_listening_stop_file(): + """ + Retrieves the value of the COMMBASE_HARDWARE_COMMAND_LISTENING_STOP_FILE + variable from the configuration file. + + Returns: + str or None: The value of the variable if found, or None if not found. + """ + # Initialize variable + listening_stop_file = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMMBASE_HARDWARE_COMMAND_LISTENING_STOP_FILE": + # Remove the quotes from the value of the variable + listening_stop_file = CONFIG_FILE_DIR + value.strip()[1:-1] + + # Check if the variable was found + if listening_stop_file is not None: + return listening_stop_file + + # If the variable was not found, return None + return None + + +def get_commbase_hardware_command_processing_start_file(): + """ + Retrieves the value of the COMMBASE_HARDWARE_COMMAND_PROCESSING_START_FILE + variable from the configuration file. + + Returns: + str or None: The value of the variable if found, or None if not found. + """ + # Initialize variable + processing_start_file = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMMBASE_HARDWARE_COMMAND_PROCESSING_START_FILE": + # Remove the quotes from the value of the variable + processing_start_file = CONFIG_FILE_DIR + value.strip()[1:-1] + + # Check if the variable was found + if processing_start_file is not None: + return processing_start_file + + # If the variable was not found, return None + return None + + +def get_commbase_hardware_command_processing_stop_file(): + """ + Retrieves the value of the COMMBASE_HARDWARE_COMMAND_PROCESSING_STOP_FILE + variable from the configuration file. + + Returns: + str or None: The value of the variable if found, or None if not found. + """ + # Initialize variable + processing_stop_file = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMMBASE_HARDWARE_COMMAND_PROCESSING_STOP_FILE": + # Remove the quotes from the value of the variable + processing_stop_file = CONFIG_FILE_DIR + value.strip()[1:-1] + + # Check if the variable was found + if processing_stop_file is not None: + return processing_stop_file + + # If the variable was not found, return None + return None + + +def get_commbase_hardware_device_0(): + """ + Retrieves the value of the COMBASE_HARDWARE_DEVICE_0 variable from the + configuration file. + + Returns: + str or None: The value of the variable if found, or None if not found. + """ + # Initialize variable + hardware_device_0 = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMBASE_HARDWARE_DEVICE_0": + # Remove the quotes from the value of the variable + hardware_device_0 = value.strip()[1:-1] + + # Check if the variable was found + if hardware_device_0 is not None: + return hardware_device_0 + + # If the variable was not found, return None + return None diff --git a/bundles/commbase-stt-whisper-proactive-p/functions.py b/bundles/commbase-stt-whisper-proactive-p/functions.py index 129e1220..dd7d1925 100644 --- a/bundles/commbase-stt-whisper-proactive-p/functions.py +++ b/bundles/commbase-stt-whisper-proactive-p/functions.py @@ -208,3 +208,195 @@ def get_stt_whisper_proactive_timeout(): # If the variable was not found, return None return None + + +def get_commbase_hardware_notifications_on(): + """ + Reads the 'COMMBASE_HARDWARE_NOTIFICATIONS_ON' variable from the + environment configuration file. Returns the string value of the variables + if found, or None if the variable is not present. + + Returns: + str or None: The string if found in the configuration file, otherwise + None. + """ + # Initialize variable + commbase_hardware_notifications = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMMBASE_HARDWARE_NOTIFICATIONS_ON": + # Remove the quotes from the value of the variable + commbase_hardware_notifications = value.strip()[1:-1] + + # Check if the variable was found + if commbase_hardware_notifications is not None: + return commbase_hardware_notifications + + # If the variable was not found, return None + return None + + +def get_commbase_hardware_notification_listening_start_on(): + """ + Reads the 'COMMBASE_HARDWARE_NOTIFICATION_LISTENING_START_ON' variable from + the environment configuration file. Returns the string value of the + variables if found, or None if the variable is not present. + + Returns: + str or None: The string if found in the configuration file, otherwise + None. + """ + # Initialize variable + commbase_hardware_notification = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMMBASE_HARDWARE_NOTIFICATION_LISTENING_START_ON": + # Remove the quotes from the value of the variable + commbase_hardware_notification = value.strip()[1:-1] + + # Check if the variable was found + if commbase_hardware_notification is not None: + return commbase_hardware_notification + + # If the variable was not found, return None + return None + + +def get_commbase_hardware_notification_listening_stop_on(): + """ + Reads the 'COMMBASE_HARDWARE_NOTIFICATION_LISTENING_STOP_ON' variable from + the environment configuration file. Returns the string value of the + variables if found, or None if the variable is not present. + + Returns: + str or None: The string if found in the configuration file, otherwise + None. + """ + # Initialize variable + commbase_hardware_notification = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMMBASE_HARDWARE_NOTIFICATION_LISTENING_STOP_ON": + # Remove the quotes from the value of the variable + commbase_hardware_notification = value.strip()[1:-1] + + # Check if the variable was found + if commbase_hardware_notification is not None: + return commbase_hardware_notification + + # If the variable was not found, return None + return None + + +def get_commbase_hardware_notification_processing_start_on(): + """ + Reads the 'COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_START_ON' variable + from the environment configuration file. Returns the string value of the + variables if found, or None if the variable is not present. + + Returns: + str or None: The string if found in the configuration file, otherwise + None. + """ + # Initialize variable + commbase_hardware_notification = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_START_ON": + # Remove the quotes from the value of the variable + commbase_hardware_notification = value.strip()[1:-1] + + # Check if the variable was found + if commbase_hardware_notification is not None: + return commbase_hardware_notification + + # If the variable was not found, return None + return None + + +def get_commbase_hardware_notification_processing_stop_on(): + """ + Reads the 'COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_STOP_ON' variable from + the environment configuration file. Returns the string value of the + variables if found, or None if the variable is not present. + + Returns: + str or None: The string if found in the configuration file, otherwise + None. + """ + # Initialize variable + commbase_hardware_notification = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_STOP_ON": + # Remove the quotes from the value of the variable + commbase_hardware_notification = value.strip()[1:-1] + + # Check if the variable was found + if commbase_hardware_notification is not None: + return commbase_hardware_notification + + # If the variable was not found, return None + return None + + +def stt_engine_processing_time_visible_on(): + """ + Reads the 'STT_ENGINE_PROCESSING_TIME_VISIBLE_ON' variable from + the environment configuration file. Returns the string value of the + variables if found, or None if the variable is not present. + + Returns: + str or None: The string if found in the configuration file, otherwise + None. + """ + # Initialize variable + processing_time_visible = None + + # Open the file and read its contents + with open(CONFIG_FILE_PATH, "r") as f: + for line in f: + # Split the line into variable name and value + variable_name, value = line.strip().split("=") + + # Check if the variable we are looking for exists in the line + if variable_name == "STT_ENGINE_PROCESSING_TIME_VISIBLE_ON": + # Remove the quotes from the value of the variable + processing_time_visible = value.strip()[1:-1] + + # Check if the variable was found + if processing_time_visible is not None: + return processing_time_visible + + # If the variable was not found, return None + return None diff --git a/bundles/commbase-stt-whisper-reactive-p/client_data/recording.wav b/bundles/commbase-stt-whisper-reactive-p/client_data/recording.wav index 8dbde954..3314d3d6 100644 Binary files a/bundles/commbase-stt-whisper-reactive-p/client_data/recording.wav and b/bundles/commbase-stt-whisper-reactive-p/client_data/recording.wav differ diff --git a/bundles/libcommbase/libcommbase/built-in_skills b/bundles/libcommbase/libcommbase/built-in_skills deleted file mode 100644 index a3f19007..00000000 --- a/bundles/libcommbase/libcommbase/built-in_skills +++ /dev/null @@ -1,37 +0,0 @@ -################################################################################ -# libcommbase # -# # -# A collection of libraries to centralize common functions that can be shared # -# across multiple conversational AI assistant projects # -# # -# Change History # -# 05/02/2023 Esteban Herrera Original code. # -# Add new history entries as needed. # -# # -# # -################################################################################ -################################################################################ -################################################################################ -# # -# Copyright (c) 2023-present Esteban Herrera C. # -# stv.herrera@gmail.com # -# # -# This program is free software; you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation; either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program; if not, write to the Free Software # -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # - -# built-in_skills -# Processes a list of built-in skills -built-in_skills() { - -} diff --git a/bundles/libcommbase/libcommbase/routines/assistant_discourse.sh b/bundles/libcommbase/libcommbase/routines/assistant_discourse.sh old mode 100755 new mode 100644 diff --git a/bundles/libcommbase/libcommbase/routines/filter_pyttsx3_voices_by_language.sh b/bundles/libcommbase/libcommbase/routines/filter_pyttsx3_voices_by_language.sh old mode 100755 new mode 100644 diff --git a/bundles/libcommbase/libcommbase/routines/restart_stt_engine.sh b/bundles/libcommbase/libcommbase/routines/restart_stt_engine.sh new file mode 100644 index 00000000..8d5cd8de --- /dev/null +++ b/bundles/libcommbase/libcommbase/routines/restart_stt_engine.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash +################################################################################ +# libcommbase # +# # +# A collection of libraries to centralize common functions that can be shared # +# across multiple conversational AI assistant projects # +# # +# Change History # +# 06/12/2024 Esteban Herrera Original code. # +# Add new history entries as needed. # +# # +# # +################################################################################ +################################################################################ +################################################################################ +# # +# Copyright (c) 2022-present Esteban Herrera C. # +# stv.herrera@gmail.com # +# # +# This program is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # + +# restart_stt_engine.sh +# Restarts the STT engine based on the value of the variable STT_ENGINE_PATH +restart_stt_engine() { + # The configuration file + source "$COMMBASE_APP_DIR"/config/commbase.conf + + # time= + # declare time + time=0.3 + + # Stop the running STT engine + # pkill to gracefully terminate the PID, and if that fails, use kill -9. + pkill -f "$STT_ENGINE_PATH" + + # If running STT engine = commbase_stt_whisper_reactive_p + if [ "$STT_ENGINE_PATH" = "$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py" ]; then + # Overwrite the variable STT_ENGINE_PATH in config/commbase.conf + sed -i 's#STT_ENGINE_PATH=.*#STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py"#' "$COMMBASE_APP_DIR"/config/commbase.conf && sleep "$time" + + # Re-source the configuration file to apply the changes + source "$COMMBASE_APP_DIR"/config/commbase.conf + + # On window 0, select pane 2, activate the conda environment if it exists, + # send the enter key, and sleep. + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " conda activate $CONDA_ENV_NAME_IF_EXISTS" C-m && sleep "$time"); + # Run the STT_ENGINE_STRING and then press the enter + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear; cpulimit --limit=$STT_PROCESS_CPU_LIMIT_PERCENTAGE -- $STT_ENGINE_STRING" C-m && sleep "$time"); + # Clear the screen, and set the prompt to an empty string + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear && PS1=""" C-m); + + # Return the cursor to the Pane 7 + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear" C-m); + + # Gracefully terminate the recorder-transmitter PID, and if that fails, use kill -9. + pkill -f "$COMMBASE_APP_DIR/$RECORDER_TRANSMITTER_FILE" + + # Select the recorder-transmitter based on the configuration + if [ "$RECORDER_TRANSMITTER_FILE" = "$CUSTOM_RECORDER_TRANSMITTER_FILE" ]; then + # Any custom recorder-transmitter + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; bash $COMMBASE_APP_DIR/$CUSTOM_RECORDER_TRANSMITTER_FILE" C-m && sleep "$time"); + elif [ "$RECORDER_TRANSMITTER_FILE" = "bundles/commbase-recorder-transmitter-s/reccomm.sh" ]; then + # recorder-transmitter for Shell + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; bash $COMMBASE_APP_DIR/bundles/commbase-recorder-transmitter-s/reccomm.sh" C-m); + else + # recorder-transmitter for Bash + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; bash $COMMBASE_APP_DIR/bundles/commbase-recorder-transmitter-b/reccomm.sh" C-m); + fi + + # If running STT engine = commbase_stt_whisper_proactive_p + elif [ "$STT_ENGINE_PATH" = "$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py" ]; then + # Overwrite the variable STT_ENGINE_PATH in config/commbase.conf + sed -i 's#STT_ENGINE_PATH=.*#STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py"#' "$COMMBASE_APP_DIR"/config/commbase.conf && sleep "$time" + + # Re-source the configuration file to apply the changes + source "$COMMBASE_APP_DIR"/config/commbase.conf + + # On window 0, select pane 2, activate the conda environment if it exists, + # send the enter key, and sleep. + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " conda activate $CONDA_ENV_NAME_IF_EXISTS" C-m && sleep "$time"); + # Run the STT_ENGINE_STRING and then press the enter + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear; cpulimit --limit=$STT_PROCESS_CPU_LIMIT_PERCENTAGE -- $STT_ENGINE_STRING" C-m && sleep "$time"); + # Clear the screen, and set the prompt to an empty string + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear && PS1=""" C-m); + + # Return the cursor to the Pane 7 + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear" C-m); + + # Add more STT engines here ... + + else + echo "There was an error at restarting the running STT engine." + echo "Please rerun the script to set up the engine properly." + + fi + + exit 99 +} + +# Call restart_stt_engine if the script is run directly (not sourced) +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + (restart_stt_engine) +fi + +exit 99 diff --git a/bundles/libcommbase/libcommbase/routines/restart_stt_engine_no_recorder.sh b/bundles/libcommbase/libcommbase/routines/restart_stt_engine_no_recorder.sh new file mode 100644 index 00000000..4209770a --- /dev/null +++ b/bundles/libcommbase/libcommbase/routines/restart_stt_engine_no_recorder.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +################################################################################ +# libcommbase # +# # +# A collection of libraries to centralize common functions that can be shared # +# across multiple conversational AI assistant projects # +# # +# Change History # +# 06/12/2024 Esteban Herrera Original code. # +# Add new history entries as needed. # +# # +# # +################################################################################ +################################################################################ +################################################################################ +# # +# Copyright (c) 2022-present Esteban Herrera C. # +# stv.herrera@gmail.com # +# # +# This program is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # + +# restart_stt_engine_no_recorder.sh +# Restarts the STT engine based on the value of the variable STT_ENGINE_PATH, +# but does not starts any commbase recorder in case the engine implements one. +# The recorder can be then activated using commands such as 'commbase recorder'. +restart_stt_engine_no_recorder() { + # The configuration file + source "$COMMBASE_APP_DIR"/config/commbase.conf + + # time= + # declare time + time=0.3 + + # Stop the running STT engine + # pkill to gracefully terminate the PID, and if that fails, use kill -9. + pkill -f "$STT_ENGINE_PATH" + + # If running STT engine = commbase_stt_whisper_reactive_p + if [ "$STT_ENGINE_PATH" = "$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py" ]; then + # Overwrite the variable STT_ENGINE_PATH in config/commbase.conf + sed -i 's#STT_ENGINE_PATH=.*#STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py"#' "$COMMBASE_APP_DIR"/config/commbase.conf && sleep "$time" + + # Re-source the configuration file to apply the changes + source "$COMMBASE_APP_DIR"/config/commbase.conf + + # On window 0, select pane 2, activate the conda environment if it exists, + # send the enter key, and sleep. + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " conda activate $CONDA_ENV_NAME_IF_EXISTS" C-m && sleep "$time"); + # Run the STT_ENGINE_STRING and then press the enter + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear; cpulimit --limit=$STT_PROCESS_CPU_LIMIT_PERCENTAGE -- $STT_ENGINE_STRING" C-m && sleep "$time"); + # Clear the screen, and set the prompt to an empty string + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear && PS1=""" C-m); + + # Return the cursor to the Pane 7 + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear" C-m); + + # Gracefully terminate the recorder-transmitter PID, and if that fails, use kill -9. + pkill -f "$COMMBASE_APP_DIR/$RECORDER_TRANSMITTER_FILE" + + # If running STT engine = commbase_stt_whisper_proactive_p + elif [ "$STT_ENGINE_PATH" = "$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py" ]; then + # Overwrite the variable STT_ENGINE_PATH in config/commbase.conf + sed -i 's#STT_ENGINE_PATH=.*#STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py"#' "$COMMBASE_APP_DIR"/config/commbase.conf && sleep "$time" + + # Re-source the configuration file to apply the changes + source "$COMMBASE_APP_DIR"/config/commbase.conf + + # On window 0, select pane 2, activate the conda environment if it exists, + # send the enter key, and sleep. + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " conda activate $CONDA_ENV_NAME_IF_EXISTS" C-m && sleep "$time"); + # Run the STT_ENGINE_STRING and then press the enter + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear; cpulimit --limit=$STT_PROCESS_CPU_LIMIT_PERCENTAGE -- $STT_ENGINE_STRING" C-m && sleep "$time"); + # Clear the screen, and set the prompt to an empty string + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear && PS1=""" C-m); + + # Return the cursor to the Pane 7 + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear" C-m); + + # Add more STT engines here ... + + else + echo "There was an error at restarting the running STT engine." + echo "Please rerun the script to set up the engine properly." + + fi + + exit 99 +} + +# Call restart_stt_engine_no_recorder if the script is run directly (not sourced) +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + (restart_stt_engine_no_recorder) +fi + +exit 99 diff --git a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_disconnect_yourself b/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_disconnect_yourself deleted file mode 100644 index e68c8d24..00000000 --- a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_disconnect_yourself +++ /dev/null @@ -1,36 +0,0 @@ -################################################################################ -# libcommbase # -# # -# A collection of libraries to centralize common functions that can be shared # -# across multiple conversational AI assistant projects # -# # -# Change History # -# 05/02/2023 Esteban Herrera Original code. # -# Add new history entries as needed. # -# # -# # -################################################################################ -################################################################################ -################################################################################ -# # -# Copyright (c) 2023-present Esteban Herrera C. # -# stv.herrera@gmail.com # -# # -# This program is free software; you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation; either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program; if not, write to the Free Software # -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # - -# parse_skill_disconnect_yourself -# TODO: Description -parse_skill_disconnect_yourself() {} - diff --git a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_list_your_command_history b/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_list_your_command_history deleted file mode 100644 index ab5e95ad..00000000 --- a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_list_your_command_history +++ /dev/null @@ -1,36 +0,0 @@ -################################################################################ -# libcommbase # -# # -# A collection of libraries to centralize common functions that can be shared # -# across multiple conversational AI assistant projects # -# # -# Change History # -# 05/02/2023 Esteban Herrera Original code. # -# Add new history entries as needed. # -# # -# # -################################################################################ -################################################################################ -################################################################################ -# # -# Copyright (c) 2023-present Esteban Herrera C. # -# stv.herrera@gmail.com # -# # -# This program is free software; you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation; either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program; if not, write to the Free Software # -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # - -# parse_skill_list_your_command_history -# TODO: Description -parse_skill_list_your_command_history() {} - diff --git a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_reload_recognition b/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_reload_recognition deleted file mode 100644 index a04d8ac2..00000000 --- a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_reload_recognition +++ /dev/null @@ -1,36 +0,0 @@ -################################################################################ -# libcommbase # -# # -# A collection of libraries to centralize common functions that can be shared # -# across multiple conversational AI assistant projects # -# # -# Change History # -# 05/02/2023 Esteban Herrera Original code. # -# Add new history entries as needed. # -# # -# # -################################################################################ -################################################################################ -################################################################################ -# # -# Copyright (c) 2023-present Esteban Herrera C. # -# stv.herrera@gmail.com # -# # -# This program is free software; you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation; either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program; if not, write to the Free Software # -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # - -# parse_skill_reload_recognition -# TODO: Description -parse_skill_reload_recognition() {} - diff --git a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_stop_capturing_sound b/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_stop_capturing_sound deleted file mode 100644 index b7cb6877..00000000 --- a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_stop_capturing_sound +++ /dev/null @@ -1,36 +0,0 @@ -################################################################################ -# libcommbase # -# # -# A collection of libraries to centralize common functions that can be shared # -# across multiple conversational AI assistant projects # -# # -# Change History # -# 05/02/2023 Esteban Herrera Original code. # -# Add new history entries as needed. # -# # -# # -################################################################################ -################################################################################ -################################################################################ -# # -# Copyright (c) 2023-present Esteban Herrera C. # -# stv.herrera@gmail.com # -# # -# This program is free software; you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation; either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program; if not, write to the Free Software # -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # - -# parse_skill_stop_capturing_sound -# TODO: Description -parse_skill_stop_capturing_sound() {} - diff --git a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_tell_me_about_yourself b/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_tell_me_about_yourself deleted file mode 100644 index 9daab8db..00000000 --- a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_tell_me_about_yourself +++ /dev/null @@ -1,36 +0,0 @@ -################################################################################ -# libcommbase # -# # -# A collection of libraries to centralize common functions that can be shared # -# across multiple conversational AI assistant projects # -# # -# Change History # -# 05/02/2023 Esteban Herrera Original code. # -# Add new history entries as needed. # -# # -# # -################################################################################ -################################################################################ -################################################################################ -# # -# Copyright (c) 2023-present Esteban Herrera C. # -# stv.herrera@gmail.com # -# # -# This program is free software; you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation; either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program; if not, write to the Free Software # -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # - -# parse_skill_skill_tell_me_about_yourself -# TODO: Description -parse_skill_tell_me_about_yourself() {} - diff --git a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_wake_up b/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_wake_up deleted file mode 100644 index 504ae239..00000000 --- a/bundles/libcommbase/libcommbase/skills/parsers/parse_skill_wake_up +++ /dev/null @@ -1,36 +0,0 @@ -################################################################################ -# libcommbase # -# # -# A collection of libraries to centralize common functions that can be shared # -# across multiple conversational AI assistant projects # -# # -# Change History # -# 05/02/2023 Esteban Herrera Original code. # -# Add new history entries as needed. # -# # -# # -################################################################################ -################################################################################ -################################################################################ -# # -# Copyright (c) 2023-present Esteban Herrera C. # -# stv.herrera@gmail.com # -# # -# This program is free software; you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation; either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program; if not, write to the Free Software # -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # - -# wake_up -# TODO: Description -parse_skill_wake_up() {} - diff --git a/bundles/libcommbase/libcommbase/skills/runners/capture_mute.sh b/bundles/libcommbase/libcommbase/skills/skills_db/capture_mute similarity index 100% rename from bundles/libcommbase/libcommbase/skills/runners/capture_mute.sh rename to bundles/libcommbase/libcommbase/skills/skills_db/capture_mute diff --git a/bundles/libcommbase/libcommbase/skills/runners/run_skill_disconnect_yourself b/bundles/libcommbase/libcommbase/skills/skills_db/run_skill_disconnect_yourself similarity index 100% rename from bundles/libcommbase/libcommbase/skills/runners/run_skill_disconnect_yourself rename to bundles/libcommbase/libcommbase/skills/skills_db/run_skill_disconnect_yourself diff --git a/bundles/libcommbase/libcommbase/skills/runners/run_skill_list_your_command_history b/bundles/libcommbase/libcommbase/skills/skills_db/run_skill_list_your_command_history similarity index 100% rename from bundles/libcommbase/libcommbase/skills/runners/run_skill_list_your_command_history rename to bundles/libcommbase/libcommbase/skills/skills_db/run_skill_list_your_command_history diff --git a/bundles/libcommbase/libcommbase/skills/runners/run_skill_reload_recognition b/bundles/libcommbase/libcommbase/skills/skills_db/run_skill_reload_recognition similarity index 100% rename from bundles/libcommbase/libcommbase/skills/runners/run_skill_reload_recognition rename to bundles/libcommbase/libcommbase/skills/skills_db/run_skill_reload_recognition diff --git a/bundles/libcommbase/libcommbase/skills/runners/run_skill_stop_capturing_sound b/bundles/libcommbase/libcommbase/skills/skills_db/run_skill_stop_capturing_sound similarity index 100% rename from bundles/libcommbase/libcommbase/skills/runners/run_skill_stop_capturing_sound rename to bundles/libcommbase/libcommbase/skills/skills_db/run_skill_stop_capturing_sound diff --git a/bundles/libcommbase/libcommbase/skills/runners/run_skill_tell_me_about_yourself b/bundles/libcommbase/libcommbase/skills/skills_db/run_skill_tell_me_about_yourself similarity index 100% rename from bundles/libcommbase/libcommbase/skills/runners/run_skill_tell_me_about_yourself rename to bundles/libcommbase/libcommbase/skills/skills_db/run_skill_tell_me_about_yourself diff --git a/bundles/libcommbase/libcommbase/skills/runners/run_skill_wake_up b/bundles/libcommbase/libcommbase/skills/skills_db/run_skill_wake_up similarity index 100% rename from bundles/libcommbase/libcommbase/skills/runners/run_skill_wake_up rename to bundles/libcommbase/libcommbase/skills/skills_db/run_skill_wake_up diff --git a/bundles/libcommbase/libcommbase/skills/skills_db/terminal_only_select_stt_engine.sh b/bundles/libcommbase/libcommbase/skills/skills_db/terminal_only_select_stt_engine.sh new file mode 100755 index 00000000..9566632c --- /dev/null +++ b/bundles/libcommbase/libcommbase/skills/skills_db/terminal_only_select_stt_engine.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash +################################################################################ +# libcommbase # +# # +# A collection of libraries to centralize common functions that can be shared # +# across multiple conversational AI assistant projects # +# # +# Change History # +# 05/12/2024 Esteban Herrera Original code. # +# Add new history entries as needed. # +# # +# # +################################################################################ +################################################################################ +################################################################################ +# # +# Copyright (c) 2022-present Esteban Herrera C. # +# stv.herrera@gmail.com # +# # +# This program is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # + +# terminal_only_select_stt_engine.sh +# Sets up the STT engine based on the value of the variable STT_ENGINE_PATH +terminal_only_select_stt_engine() { + # The configuration file + source "$COMMBASE_APP_DIR"/config/commbase.conf + + # time= + # declare time + time=0.3 + + # Display the STT engines available + echo "" + echo "The STT engines available are:" + + # Find files and store them in an array + # Populate the array using a while loop with process substitution + files=() + while IFS= read -r -d '' file; do + files+=("$(basename "$file" .py)") + done < <(find "$COMMBASE_APP_DIR"/bundles -type f -name "commbase_stt_*" -print0) + + # Prompt user to select a file + echo "Select the STT that you want to use:" + select file in "${files[@]}"; do + if [ -n "$file" ]; then + selected_file="$file" + break + else + echo "Invalid selection. Please try again." + fi + done + + echo "You selected: $selected_file" + + # If selected_file = commbase_stt_whisper_reactive_p + if [ "$selected_file" = "commbase_stt_whisper_reactive_p" ]; then + # Stop the running STT engine + # pkill to gracefully terminate the PID, and if that fails, use kill -9. + pkill -f "$STT_ENGINE_PATH" + + # Overwrite the variable STT_ENGINE_PATH in config/commbase.conf + sed -i 's#STT_ENGINE_PATH=.*#STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py"#' "$COMMBASE_APP_DIR"/config/commbase.conf && sleep "$time" + + # Re-source the configuration file to apply the changes + source "$COMMBASE_APP_DIR"/config/commbase.conf + + # On window 0, select pane 2, activate the conda environment if it exists, + # send the enter key, and sleep. + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " conda activate $CONDA_ENV_NAME_IF_EXISTS" C-m && sleep "$time"); + # Run the STT_ENGINE_STRING and then press the enter + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear; cpulimit --limit=$STT_PROCESS_CPU_LIMIT_PERCENTAGE -- $STT_ENGINE_STRING" C-m && sleep "$time"); + # Clear the screen, and set the prompt to an empty string + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear && PS1=""" C-m); + + # Return the cursor to the Pane 7 + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear" C-m); + + # Select the recorder-transmitter based on the configuration + if [ "$RECORDER_TRANSMITTER_FILE" = "$CUSTOM_RECORDER_TRANSMITTER_FILE" ]; then + # Any custom recorder-transmitter + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; bash $COMMBASE_APP_DIR/$CUSTOM_RECORDER_TRANSMITTER_FILE" C-m); + elif [ "$RECORDER_TRANSMITTER_FILE" = "bundles/commbase-recorder-transmitter-s/reccomm.sh" ]; then + # recorder-transmitter for Shell + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; bash $COMMBASE_APP_DIR/bundles/commbase-recorder-transmitter-s/reccomm.sh" C-m); + else + # recorder-transmitter for Bash + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; bash $COMMBASE_APP_DIR/bundles/commbase-recorder-transmitter-b/reccomm.sh" C-m); + fi + + # If selected_file = commbase_stt_whisper_proactive_p + elif [ "$selected_file" = "commbase_stt_whisper_proactive_p" ]; then + # Stop the running STT engine + # pkill to gracefully terminate the PID, and if that fails, use kill -9. + pkill -f "$STT_ENGINE_PATH" + + # Overwrite the variable STT_ENGINE_PATH in config/commbase.conf + sed -i 's#STT_ENGINE_PATH=.*#STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py"#' "$COMMBASE_APP_DIR"/config/commbase.conf && sleep "$time" + + # Re-source the configuration file to apply the changes + source "$COMMBASE_APP_DIR"/config/commbase.conf + + # On window 0, select pane 2, activate the conda environment if it exists, + # send the enter key, and sleep. + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " conda activate $CONDA_ENV_NAME_IF_EXISTS" C-m && sleep "$time"); + # Run the STT_ENGINE_STRING and then press the enter + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear; cpulimit --limit=$STT_PROCESS_CPU_LIMIT_PERCENTAGE -- $STT_ENGINE_STRING" C-m && sleep "$time"); + # Clear the screen, and set the prompt to an empty string + (tmux select-window -t 1 && tmux select-pane -t 2 && tmux send-keys " clear && PS1=""" C-m); + + # Return the cursor to the Pane 7 + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear" C-m); + + # Add more STT engines here ... + + else + echo "The selected STT engine '$selected_file' is not recognized or supported." + echo "Please rerun the script to select a valid STT engine or add and set up the new engine properly." + + fi + + exit 99 +} + +# Call terminal_only_select_stt_engine if the script is run directly (not sourced) +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + (terminal_only_select_stt_engine) +fi + +exit 99 diff --git a/scripts/configuration/set_language.sh b/bundles/libcommbase/libcommbase/skills/skills_db/terminal_only_set_language.sh old mode 100644 new mode 100755 similarity index 70% rename from scripts/configuration/set_language.sh rename to bundles/libcommbase/libcommbase/skills/skills_db/terminal_only_set_language.sh index df95e66e..83b22ba8 --- a/scripts/configuration/set_language.sh +++ b/bundles/libcommbase/libcommbase/skills/skills_db/terminal_only_set_language.sh @@ -1,4 +1,4 @@ -#!usr//bin/env bash +#!/usr/bin/env bash ################################################################################ # libcommbase # # # @@ -6,7 +6,7 @@ # across multiple conversational AI assistant projects # # # # Change History # -# 02/13/2024 Esteban Herrera Original code. # +# 05/12/2024 Esteban Herrera Original code. # # Add new history entries as needed. # # # # # @@ -14,7 +14,7 @@ ################################################################################ ################################################################################ # # -# Copyright (c) 2023-present Esteban Herrera C. # +# Copyright (c) 2022-present Esteban Herrera C. # # stv.herrera@gmail.com # # # # This program is free software; you can redistribute it and/or modify # @@ -31,12 +31,15 @@ # along with this program; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# set_language.sh +# terminal_only_set_language.sh # Sets up the Commbase language and the Commbase app language -set_language() { +terminal_only_set_language() { # The configuration file source "$COMMBASE_APP_DIR"/config/commbase.conf + # Imports from libcommbase + restart_stt_engine_no_recorder=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/restart_stt_engine_no_recorder.sh + # Display the system locale info echo "Current system locale information:" locale @@ -97,8 +100,29 @@ set_language() { # Add more en_us variables here ... - echo "Your new language code is:" "$new_lang_code""." - echo "Remember to set up your app voice accordingly." + # Restart STT engines here ... + + # Restart the running STT engine + (bash "$restart_stt_engine_no_recorder") + + # Restart LLMs here ... + + # Restart the running LLM + # TODO: Come back here after coding every LLM bundle. + + # Retrieve the real final value of the language variable from the + # configuration file instead of from $new_lang_code. + source "$COMMBASE_APP_DIR"/config/commbase.conf # Re-sources the configuration file to apply the changes + + # Inform the user + if [ "$STT_ENGINE_PATH" = "$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py" ]; then + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; echo -e 'Your new language code is: " "$COMMBASE_LANG.\\nRun the voice recorder with the command: commbase recorder'" C-m); + else + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; echo 'Your new language code is: " "$COMMBASE_LANG.'" C-m); + fi + + # Gracefully terminate the recorder-transmitter PID, and if that fails, use kill -9. + pkill -f "$COMMBASE_APP_DIR/$RECORDER_TRANSMITTER_FILE" # new_lang_code = es_es elif [ "$new_lang_code" = "es_es" ]; then @@ -135,8 +159,29 @@ set_language() { # Add more es_es variables here ... - echo "Your new language code is:" "$new_lang_code""." - echo "Remember to set up your app voice accordingly." + # Restart STT engines here ... + + # Restart the running STT engine + (bash "$restart_stt_engine_no_recorder") + + # Restart LLMs here ... + + # Restart the running LLM + # TODO: Come back here after coding every LLM bundle. + + # Retrieve the real final value of the language variable from the + # configuration file instead of from $new_lang_code. + source "$COMMBASE_APP_DIR"/config/commbase.conf # Re-sources the configuration file to apply the changes + + # Inform the user + if [ "$STT_ENGINE_PATH" = "$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py" ]; then + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; echo -e 'Your new language code is: " "$COMMBASE_LANG.\\nRun the voice recorder with the command: commbase recorder'" C-m); + else + (tmux select-window -t 1 && tmux select-pane -t 7 && tmux send-keys " clear; echo 'Your new language code is: " "$COMMBASE_LANG.'" C-m); + fi + + # Gracefully terminate the recorder-transmitter PID, and if that fails, use kill -9. + pkill -f "$COMMBASE_APP_DIR/$RECORDER_TRANSMITTER_FILE" else echo "Your code does not correspond to any language available." @@ -147,12 +192,11 @@ set_language() { # Add more new_lang_code language code blocks here ... exit 99 - } -# Call set_language if the script is run directly (not sourced) +# Call terminal_only_set_language if the script is run directly (not sourced) if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - (set_language) + (terminal_only_set_language) fi exit 99 diff --git a/bundles/libcommbase/libcommbase/skills/runners/toggle_default_capture_device.sh b/bundles/libcommbase/libcommbase/skills/skills_db/toggle_default_capture_device similarity index 100% rename from bundles/libcommbase/libcommbase/skills/runners/toggle_default_capture_device.sh rename to bundles/libcommbase/libcommbase/skills/skills_db/toggle_default_capture_device diff --git a/config/commbase.conf b/config/commbase.conf index 00015c5b..40a018b9 100644 --- a/config/commbase.conf +++ b/config/commbase.conf @@ -28,11 +28,13 @@ SYSTEM_AUDIO_CAPTURE_DEVICE_NAME="alsa_input.usb-_Webcam_C170-02.mono-fallback" VIDEO_CAPTURE_DEVICE_01_INDEX="0" VIDEO_CAPTURE_DEVICE_02_INDEX="1" RECORDER_TRANSMITTER_FILE="bundles/commbase-recorder-transmitter-b/reccomm.sh" +CUSTOM_RECORDER_TRANSMITTER_FILE="bundles/commbase-recorder-transmitter-x/reccomm.sh" STT_ENGINE_MODEL_DIRECTORY="openai_whisper_models" STT_ENGINE_MODEL_SUBDIRECTORY="base" -STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py" +STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py" STT_ENGINE_STRING="$PYTHON_ENV_VERSION $STT_ENGINE_PATH 2> /dev/null" COMMBASE_STT_WHISPER_REACTIVE_P_CLIENT_DATA_FILE="/bundles/commbase-stt-whisper-reactive-p/client_data/recording.wav" +STT_ENGINE_PROCESSING_TIME_VISIBLE_ON="False" CHAT_LOG_FILE="/data/.chat_log.txt" CONVERSATION_LOGS_PATH="/user/conversation_logs/" TTS_ENGINE_STRING="$PYTHON_ENV_VERSION $COMMBASE_APP_DIR/bundles/commbase-tts-pyttsx3/commbase_tts_pyttsx3.py --rate $TTS_PYTTSX3_RATE --voice-index $TTS_PYTTSX3_LANGUAGE_INDEX" @@ -94,3 +96,13 @@ SOUND_SAY_NO_WITHOUT_SPEAKING="$COMMBASE_APP_DIR/bundles/libcommbase/resources/b SOUND_A_PENDING_TASK_AWAITS_ATTENTION="$COMMBASE_APP_DIR/bundles/libcommbase/resources/bundles/sounds/mixkit-unlock-game-notification-253.wav" SOUND_PENDING_TASKS_REMINDER="$COMMBASE_APP_DIR/bundles/libcommbase/resources/bundles/sounds/mixkit-uplifting-flute-notification-2317.wav" PENDING_TASKS_VERIFICATION_FREQUENCY_IN_SECS="3600" +COMMBASE_HARDWARE_NOTIFICATIONS_ON="False" +COMMBASE_HARDWARE_NOTIFICATION_LISTENING_START_ON="True" +COMMBASE_HARDWARE_NOTIFICATION_LISTENING_STOP_ON="True" +COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_START_ON="True" +COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_STOP_ON="True" +COMBASE_HARDWARE_DEVICE_0="/dev/ttyACM0" +COMMBASE_HARDWARE_COMMAND_LISTENING_START_FILE="/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/listening_start.dat" +COMMBASE_HARDWARE_COMMAND_LISTENING_STOP_FILE="/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/listening_stop.dat" +COMMBASE_HARDWARE_COMMAND_PROCESSING_START_FILE="/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/processing_start.dat" +COMMBASE_HARDWARE_COMMAND_PROCESSING_STOP_FILE="/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/processing_stop.dat" diff --git a/data/.messages.json b/data/.messages.json index 1fd3ee93..aa6577b0 100644 --- a/data/.messages.json +++ b/data/.messages.json @@ -1 +1 @@ -{"messages":[{"language":"es_es"},{"control":""},{"current_request":"hell"},{"previous_request":"hell"},{"current_response":""},{"runtime":""},{"source_code_display":""},{"source_code":""}]} +{"messages":[{"language":"en_us"},{"control":""},{"current_request":"--select-stt-engine"},{"previous_request":"--select-stt-engine"},{"current_response":""},{"runtime":""},{"source_code_display":""},{"source_code":""}]} diff --git a/scripts/configuration/install_commbase_executable/commbase.default b/scripts/configuration/install_commbase_executable/commbase.default index 63471780..fa99ff0a 100755 --- a/scripts/configuration/install_commbase_executable/commbase.default +++ b/scripts/configuration/install_commbase_executable/commbase.default @@ -111,9 +111,15 @@ Sound: Voice: Usage: commbase [options] options: - --list-pyttsx3-voices List the commbase-tts-pyttsx3 voices available + --list-pyttsx3-voices List the commbase-tts-pyttsx3 voices available --filter-pyttsx3-english-voices Filter pyttsx3 English language voices +Shutdown and Restart: + Usage: commbase [options] + options: + --restart-stt-engine Shutdown running STT engine and restart it + --disconnect-yourself Shutdown Commbase + Control: Usage: commbase [options] options: @@ -124,20 +130,35 @@ EOT cat < minutes.": Start a countdown timer + Examples (Double quotes are optional): + "Okay, tell me about yourself.": Run Commbase introduction + "Okay, start the math test number one zero one.": Run mentioned multi-choice test interactively + "Okay, let me know when the internet is back.": (Interactive) Receive 'event' alert and notification + "Okay, set a timer of minutes.": Start a countdown timer Examples: - "Set a timer of twenty five minutes." - Set a timer of one hundred one minutes. + "Okay, set a timer of twenty five minutes." + Okay, set a timer of one hundred one minutes. + +Misspelled/Misspoken/Inexistent Terminal/Voice Commbase Command. Alternatively, Discourse: + Usage: [commbase] [discourse] + Examples: + commbase --i-misspell-this-command: Pass mentioned wrong terminal Commbase command as conversation message to data exchange. + commbase I misspelled this command: Pass mentioned wrong terminal Commbase command as conversation message to data exchange. + commbase "I misspelled this command": Pass mentioned wrong terminal Commbase command as conversation message to data exchange. + "Okay, I misspoke this command": Pass mentioned misspoken voice Commbase command as conversation message to data exchange. + "Okay, this command doesn't exist": Pass mentioned inexistent voice Commbase command as conversation message to data exchange. + "What's the meaning of life?.": Pass mentioned discourse as conversation message to data exchange. -**Double quotes are optional EOT } @@ -152,19 +173,24 @@ route_option() { source $COMMBASE_APP_DIR/config/commbase.conf source $COMMBASE_APP_DIR/src/app.sh - # Imports from libcommbase - store_chat_log_copy=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/store_log_copy.sh - run_voice_recorder_in_pane=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/run_voice_recorder_in_pane.sh - toggle_default_capture_device=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/toggle_default_capture_device.sh - toggle_capture_on_off=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/toggle_capture_on-off.sh + # Imports from libcommbase routines capture_mute=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/capture_mute.sh capture_unmute=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/capture_unmute.sh cleanup_directory_by_age=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/cleanup_directory_by_age.sh cleanup_directory_by_file_count=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/cleanup_directory_by_file_count.sh + controller=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/controller.sh filter_pyttsx3_voices_by_language=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/filter_pyttsx3_voices_by_language.sh list_all_voices_available_for_pyttsx3=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/list_all_voices_available_for_pyttsx3.py + restart_stt_engine=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/restart_stt_engine.sh + run_voice_recorder_in_pane=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/run_voice_recorder_in_pane.sh + store_chat_log_copy=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/store_log_copy.sh + toggle_default_capture_device=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/toggle_default_capture_device.sh + toggle_capture_on_off=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/toggle_capture_on-off.sh update_control_in_messages_json=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/update_control_in_messages_json.sh - controller=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/routines/controller.sh + + # Imports from libcommbase built-in skills + terminal_only_select_stt_engine=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/skills/skills_db/terminal_only_select_stt_engine.sh + terminal_only_set_language=$COMMBASE_APP_DIR/bundles/libcommbase/libcommbase/skills/skills_db/terminal_only_set_language.sh # First tmux session SESSIONNAME="Commbase-0"; @@ -231,9 +257,11 @@ route_option() { (bash "$cleanup_directory_by_file_count" "$MAX_CONVERSATION_FILES_COUNT" "$COMMBASE_APP_DIR"/user/conversation_logs/) (bash "$cleanup_directory_by_age" "$MAX_CONVERSATION_FILE_DAYS_STORED" "$COMMBASE_APP_DIR"/user/conversation_logs/) (sleep 2) # Time in seconds to read messages on pane before the app shutdown - # "pkill -f" the processes of the scripts that do not respond to the + # Kill the processes of the scripts that do not respond to the # interrupt signal or appear to duplicate once the program stops and # exits. + # Gracefully terminate the STT engine PID, and if that fails, use + # kill -9. pkill -f "$STT_ENGINE_PATH" #pkill -f python # This will kill all the running 'python' processes conda deactivate # This is redundant @@ -269,6 +297,22 @@ route_option() { # Filter English language voices for commbase-tts-pyttsx3 (bash "$filter_pyttsx3_voices_by_language" "english") ;; + '--restart-stt-engine') + # Shutdown running STT engine and restart it + (bash "$restart_stt_engine") + ;; + '--disconnect-yourself') + # Shutdown Commbase + (commbase stop) + ;; + '--select-stt-engine') + # Run an interactive terminal only built-in skill to select an stt engine + (bash "$terminal_only_select_stt_engine") + ;; + '--set-language') + # Run an interactive terminal only built-in skill to set a language + (bash "$terminal_only_set_language") + ;; esac case "$terminal_voice_command" in diff --git a/scripts/utilities/reset_commbase.conf/commbase.conf.default b/scripts/configuration/reset_commbase.conf/commbase.conf.default similarity index 81% rename from scripts/utilities/reset_commbase.conf/commbase.conf.default rename to scripts/configuration/reset_commbase.conf/commbase.conf.default index 00015c5b..40a018b9 100644 --- a/scripts/utilities/reset_commbase.conf/commbase.conf.default +++ b/scripts/configuration/reset_commbase.conf/commbase.conf.default @@ -28,11 +28,13 @@ SYSTEM_AUDIO_CAPTURE_DEVICE_NAME="alsa_input.usb-_Webcam_C170-02.mono-fallback" VIDEO_CAPTURE_DEVICE_01_INDEX="0" VIDEO_CAPTURE_DEVICE_02_INDEX="1" RECORDER_TRANSMITTER_FILE="bundles/commbase-recorder-transmitter-b/reccomm.sh" +CUSTOM_RECORDER_TRANSMITTER_FILE="bundles/commbase-recorder-transmitter-x/reccomm.sh" STT_ENGINE_MODEL_DIRECTORY="openai_whisper_models" STT_ENGINE_MODEL_SUBDIRECTORY="base" -STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-proactive-p/commbase_stt_whisper_proactive_p.py" +STT_ENGINE_PATH="$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py" STT_ENGINE_STRING="$PYTHON_ENV_VERSION $STT_ENGINE_PATH 2> /dev/null" COMMBASE_STT_WHISPER_REACTIVE_P_CLIENT_DATA_FILE="/bundles/commbase-stt-whisper-reactive-p/client_data/recording.wav" +STT_ENGINE_PROCESSING_TIME_VISIBLE_ON="False" CHAT_LOG_FILE="/data/.chat_log.txt" CONVERSATION_LOGS_PATH="/user/conversation_logs/" TTS_ENGINE_STRING="$PYTHON_ENV_VERSION $COMMBASE_APP_DIR/bundles/commbase-tts-pyttsx3/commbase_tts_pyttsx3.py --rate $TTS_PYTTSX3_RATE --voice-index $TTS_PYTTSX3_LANGUAGE_INDEX" @@ -94,3 +96,13 @@ SOUND_SAY_NO_WITHOUT_SPEAKING="$COMMBASE_APP_DIR/bundles/libcommbase/resources/b SOUND_A_PENDING_TASK_AWAITS_ATTENTION="$COMMBASE_APP_DIR/bundles/libcommbase/resources/bundles/sounds/mixkit-unlock-game-notification-253.wav" SOUND_PENDING_TASKS_REMINDER="$COMMBASE_APP_DIR/bundles/libcommbase/resources/bundles/sounds/mixkit-uplifting-flute-notification-2317.wav" PENDING_TASKS_VERIFICATION_FREQUENCY_IN_SECS="3600" +COMMBASE_HARDWARE_NOTIFICATIONS_ON="False" +COMMBASE_HARDWARE_NOTIFICATION_LISTENING_START_ON="True" +COMMBASE_HARDWARE_NOTIFICATION_LISTENING_STOP_ON="True" +COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_START_ON="True" +COMMBASE_HARDWARE_NOTIFICATION_PROCESSING_STOP_ON="True" +COMBASE_HARDWARE_DEVICE_0="/dev/ttyACM0" +COMMBASE_HARDWARE_COMMAND_LISTENING_START_FILE="/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/listening_start.dat" +COMMBASE_HARDWARE_COMMAND_LISTENING_STOP_FILE="/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/listening_stop.dat" +COMMBASE_HARDWARE_COMMAND_PROCESSING_START_FILE="/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/processing_start.dat" +COMMBASE_HARDWARE_COMMAND_PROCESSING_STOP_FILE="/src/client/serial_communication/arduino/arduino_0/commbase_hardware_notifications/speech_to_text_engine_component/processing_stop.dat" diff --git a/scripts/utilities/reset_commbase.conf/reset_commbase.conf.sh b/scripts/configuration/reset_commbase.conf/reset_commbase.conf.sh similarity index 100% rename from scripts/utilities/reset_commbase.conf/reset_commbase.conf.sh rename to scripts/configuration/reset_commbase.conf/reset_commbase.conf.sh diff --git a/src/app.sh b/src/app.sh index a037a697..415ed678 100644 --- a/src/app.sh +++ b/src/app.sh @@ -172,9 +172,9 @@ app() { if [ "$STT_ENGINE_PATH" = "$COMMBASE_APP_DIR/bundles/commbase-stt-whisper-reactive-p/commbase_stt_whisper_reactive_p.py" ]; then # Select the recorder-transmitter based on the configuration - if [ "$RECORDER_TRANSMITTER_FILE" = "bundles/commbase-recorder-transmitter-x/reccomm.sh" ]; then + if [ "$RECORDER_TRANSMITTER_FILE" = "$CUSTOM_RECORDER_TRANSMITTER_FILE" ]; then # Any custom recorder-transmitter - (tmux select-pane -t 7 && tmux send-keys " clear; bash $COMMBASE_APP_DIR/bundles/commbase-recorder-transmitter-x/reccomm.sh" C-m && sleep $time); + (tmux select-pane -t 7 && tmux send-keys " clear; bash $COMMBASE_APP_DIR/$CUSTOM_RECORDER_TRANSMITTER_FILE" C-m && sleep $time); elif [ "$RECORDER_TRANSMITTER_FILE" = "bundles/commbase-recorder-transmitter-s/reccomm.sh" ]; then # recorder-transmitter for Shell (tmux select-pane -t 7 && tmux send-keys " clear; bash $COMMBASE_APP_DIR/bundles/commbase-recorder-transmitter-s/reccomm.sh" C-m && sleep $time);