Chat Program Debugging

These are the scripts of a chat program I am trying to build. I will upload all the files, please correct them so this program works as intended:
All the files uploaded by the user have been fully loaded. Searching won’t provide additional information.
Your chat program consists of three files:

1. **config.py** – Handles configuration settings like language and program paths.
2. **gui.py** – Implements a simple GUI using `tkinter`.
3. **main.py** – The main entry point that ties everything together.

### Issues & Fixes:
1. **Missing `modules` Directory**
– `main.py` imports `listen_continuous` and `process_command` from `modules.speech` and `modules.commands`, but the `modules` folder and these scripts are not provided.
– Fix: Ensure these files exist, or remove the imports if unnecessary.

2. **Thread Safety Issue in `gui.py`**
– The `StatusWindow` class uses `Queue` but calls `self.status_label.config(text=text)` directly from the `check_queue()` method. `tkinter` updates should be done from the main thread.
– Fix: Use `self.root.after()` to ensure updates happen on the main thread.

3. **`status_window.update_status()` Not Thread-Safe**
– `update_status` modifies `Queue` from different threads without synchronization.
– Fix: Use `self.root.after()` inside `update_status()`.

4. **Program Termination Handling**
– If the GUI is closed, the speech recognition thread keeps running.

I have the rest of the files but I will have to send them through the caht window as you need them
Got it! Send me the missing files one by one, and I’ll review and fix them as needed. Start with `modules/speech.py` or `modules/commands.py`.
import speech_recognition as sr

def listen_continuous(callback):
“””Continuously listen for voice input and pass recognized text to the callback.”””
recognizer = sr.Recognizer()
with sr.Microphone() as source:
print(“Listening…”)
while True:
try:
audio = recognizer.listen(source)
text = recognizer.recognize_sphinx(audio) # Offline recognition
callback(text)
except sr.UnknownValueError:
print(“Could not understand audio”)
except sr.RequestError as e:
print(f”Could not request results; {e}”)
Your `listen_continuous` function is using **CMU Sphinx** for offline speech recognition, which is good for not requiring an internet connection. However, there are some issues:

### Issues & Fixes:
1. **Blocking Behavior**
– `recognizer.listen(source)` runs indefinitely in a loop without a timeout.
– Fix: Add a timeout and phrase time limit to prevent infinite blocking.

2. **Error Handling**
– The current exception handling prints errors but doesn’t log or retry intelligently.
– Fix: Add a retry mechanism and log errors properly.

3. **Microphone Sensitivity**
– Using `recognizer.adjust_for_ambient_noise(source)` at the beginning improves recognition accuracy.
– Fix: Add this before entering the loop.

### Fixed Code:
“`python
import speech_recognition as sr
import time

def listen_continuous(callback):
“””Continuously listen for voice input and pass recognized text to the callback.”””
recognizer = sr.Recognizer()

with sr.Microphone() as source:
recognizer.adjust_for_ambient_noise(source) # Improves recognition accuracy
print(“Listening…”)

while True:
try:
audio = recognizer.listen(source, timeout=5, phrase_time_limit=5)
text = recognizer.recognize_sphinx(audio) # Offline recognition
if text.strip():
callback(text)
except sr.UnknownValueError:
print(“Could not understand audio”)
except sr.RequestError as e:
print(f”Could not request results; {e}”)
except Exception as e:
print(f”Unexpected error: {e}”)
time.sleep(0.5) # Small delay to avoid excessive CPU usage
“`

Let me know if you want to switch to Google’s online speech recognition instead for better accuracy! Now, send `modules/commands.py`.
# modules/commands.py
# Processes voice input to identify and execute commands.
# Maps phrases like ‘Open Notepad’ or ‘Take a note’ to actions.
# Designed to be easily extensible with new commands.
# modules/commands.py
from .launcher import launch_program
from .notes import take_note
from .language import switch_language, get_response_text
from .tts import speak
from .ollama import get_response

def process_command(text):
“””Process the recognized text using Ollama and execute the appropriate action.”””
response = get_response(text)
if response.startswith(“LAUNCH:”):
program = response.split(“LAUNCH:”)[1].strip()
launch_program(program)
speak(get_response_text(“opening”, program))
elif response.startswith(“NOTE:”):
note = response.split(“NOTE:”)[1].strip()
take_note(note)
speak(get_response_text(“note_taken”))
elif response.startswith(“SWITCH:”):
language = response.split(“SWITCH:”)[1].strip()
switch_language(language)
speak(get_response_text(“switched_to”, language))
else:
speak(get_response_text(“unknown”))
Your `process_command` function is designed to process recognized speech, interpret it via **Ollama**, and execute commands like launching programs, taking notes, or switching languages. However, there are some potential issues:

### Issues & Fixes:
1. **Missing Dependency: `ollama`**
– `get_response(text)` from `ollama` isn’t provided. If `ollama` is an AI model, ensure it’s properly set up and handling all cases.
– Fix: Ensure `get_response(text)` is implemented correctly and handles edge cases.

2. **Dependency on `speak()`**
– The function calls `speak()` directly, which assumes `tts.py` has a working text-to-speech implementation.
– Fix: Ensure `speak()` is implemented and works without blocking the main process.

3. **Improper `if-elif` Structure**
– `response.startswith(“LAUNCH:”)` assumes `get_response(text)` always follows this format.
– Fix: Add a default case or a more robust parsing method.

4. **Ensure Graceful Error Handling**
– If any function (`launch_program`, `take_note`, etc.) fails, the error should be caught and handled properly.
– Fix: Wrap each command execution in a `try-except` block.

### Fixed Code:
“`python
from .launcher import launch_program
from .notes import take_note
from .language import switch_language, get_response_text
from .tts import speak
from .ollama import get_response

def process_command(text):
“””Process the recognized text using Ollama and execute the appropriate action.”””
try:
response = get_response(text)
if response.startswith(“LAUNCH:”):
program = response.split(“LAUNCH:”)[1].strip()
if program:
launch_program(program)
speak(get_response_text(“opening”, program))
else:
speak(get_response_text(“not_found”, “unknown”))
elif response.startswith(“NOTE:”):
note = response.split(“NOTE:”)[1].strip()
if note:
take_note(note)
speak(get_response_text(“note_taken”))
elif response.startswith(“SWITCH:”):
language = response.split(“SWITCH:”)[1].strip()
if language:
switch_language(language)
speak(get_response_text(“switched_to”, language))
else:
speak(get_response_text(“unknown”))
else:
speak(get_response_text(“unknown”))
except Exception as e:
speak(“An error occurred while processing the command.”)
print(f”Error in process_command: {e}”)
“`

Let me know if `ollama` needs adjustments, or if you want to modify how the responses are handled! Next, send me **modules/launcher.py**.
ollama is the server that serves the llm “phi”
Got it! **Ollama** is your LLM server serving the **Phi** model. That means `get_response(text)` is sending the input to an LLM, which generates structured responses (`LAUNCH:`, `NOTE:`, etc.).

I’ll assume that the response format is always correct. If you ever notice the AI returning malformed responses, we may need to add some validation.

Now, send **modules/launcher.py**, and I’ll review and fix any issues there.