Skip to content

Commit 15e7581

Browse files
Add AI response handling and improve settings management; initialize chatbot package and enhance UI styles
1 parent 847f49a commit 15e7581

13 files changed

Lines changed: 1452 additions & 1813 deletions

app/__init__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""
2+
Chatbot Application Package
3+
--------------------------
4+
5+
A modular chatbot application built with PyQt6 and LangChain.
6+
7+
This package contains modules for:
8+
- Template management
9+
- Model management
10+
- Session management
11+
- File handling
12+
- Chat UI
13+
"""
14+
15+
__version__ = "1.0.0"

app/ai_response.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from PyQt6.QtCore import QThread, pyqtSignal
2+
3+
class AIResponseThread(QThread):
4+
response_ready = pyqtSignal(str)
5+
error_occurred = pyqtSignal(str)
6+
7+
def __init__(self, llm, prompt, parent=None):
8+
super().__init__(parent)
9+
self.llm = llm
10+
self.prompt = prompt
11+
12+
def run(self):
13+
try:
14+
# Generate response using the LLM
15+
response = self.llm.invoke(self.prompt)
16+
17+
# Emit the response signal
18+
self.response_ready.emit(response)
19+
20+
except Exception as e:
21+
# Emit the error signal
22+
self.error_occurred.emit(str(e))

app/chatbot.py

Lines changed: 34 additions & 1488 deletions
Large diffs are not rendered by default.

app/chatbot_translator.py

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
import json
2+
import os
3+
4+
class Translator:
5+
"""
6+
A translator class to enable multilingual support in the chatbot application.
7+
Manages translations between English and French.
8+
"""
9+
10+
def __init__(self):
11+
"""Initialize the translator with English and French translations."""
12+
self.translations = {
13+
'en': {
14+
'window_title': 'Madick Chatbot',
15+
'ready': 'Ready',
16+
'error': 'Error',
17+
'warning': 'Warning',
18+
'info': 'Information',
19+
'success': 'Success',
20+
'chat': '💬 Chat',
21+
'templates': '📋 Templates',
22+
'history': '📚 History',
23+
'files': '📁 Files',
24+
'settings': '⚙️ Settings',
25+
'model': 'Model:',
26+
'session': 'Session:',
27+
'clear': '🗑️ Clear',
28+
'export': '📤 Export',
29+
'start_recording': 'Start Recording',
30+
'stop_recording': 'Stop Recording',
31+
'template': 'Template:',
32+
'send': '📩 Send',
33+
'you': 'You',
34+
'ai': 'AI',
35+
'available_templates': 'Available Templates',
36+
'none': 'None',
37+
'custom': 'Custom...',
38+
'new_template': 'New Template',
39+
'template_name': 'Template Name:',
40+
'template_prompt': 'Enter the template prompt (use {input} for user input):',
41+
'template_description': 'Enter a short description:',
42+
'template_category': 'Select or enter a category:',
43+
'search_placeholder': 'Search in chat history...',
44+
'refresh': '🔄 Refresh',
45+
'clear_history': '🗑️ Clear History',
46+
'user': 'User',
47+
'uploaded_files': 'Uploaded Files',
48+
'upload_file': '📎 Upload File',
49+
'attach_file': '📎 Attach File',
50+
'file_attached': 'File Attached',
51+
'binary_file': 'Binary File',
52+
'file_too_large': 'File Too Large',
53+
'invalid_json': 'Invalid JSON',
54+
'binary_file_detected': 'Binary File Detected',
55+
'error_reading_file': 'Error Reading File',
56+
'voice_input': 'Voice Input',
57+
'recording_start_prompt': 'Press Start to begin recording...',
58+
'initializing_mic': 'Initializing microphone...',
59+
'listening': 'Listening...',
60+
'processing_speech': 'Processing speech...',
61+
'recording_stopped': 'Recording stopped',
62+
'recording_success': 'Recording successful!',
63+
'cancel': 'Cancel',
64+
'message_copied': 'Message copied to clipboard',
65+
'message_edit_ready': 'Message ready for editing',
66+
'tts_future': 'This feature will be implemented in a future update.',
67+
'response_saved_db': 'Response saved to history',
68+
'response_saved_file': 'Response saved to {filename}',
69+
'error_saving_db': 'Error saving to database: {error}',
70+
'error_saving_file': 'Error saving file: {error}',
71+
'switched_model': 'Switched to {model} model',
72+
'switched_session': 'Switched to session: {session}',
73+
'clear_chat_confirm': 'Are you sure you want to clear the chat history?',
74+
'clear_history_confirm': 'Are you sure you want to clear all chat history?',
75+
'history_cleared': 'Chat history cleared successfully',
76+
'error_history': 'Error clearing history: {error}',
77+
'minimized': 'ChatBot Minimized',
78+
'still_running': 'Application is still running in the system tray.',
79+
'voice_error': 'Voice input error: {error}',
80+
'new_session': 'New Session',
81+
'session_name': 'Enter session name:',
82+
'session_exists': 'Session name already exists!',
83+
'delete_template': 'Delete Template',
84+
'delete_template_confirm': 'Are you sure you want to delete the template \'{name}\'?',
85+
'template_deleted': 'Template \'{name}\' deleted successfully',
86+
'template_created': 'Template \'{name}\' created successfully',
87+
'error_template': 'Error {action} template: {error}',
88+
'content_of_file': 'Content of {filename}:',
89+
'send_file_confirm': 'Do you want to send the contents of {filename} to the AI?',
90+
'file_content_added': 'File content added to input',
91+
'binary_file_info': '{filename} is a binary file. Only the file reference will be added.',
92+
'attached_file': '[Attached file: {filename}]',
93+
'file_attached_status': 'File \'{filename}\' attached',
94+
'no_mic': 'No microphone detected',
95+
'speech_not_understood': 'Could not understand audio. Please speak more clearly',
96+
'service_error': 'Service error: {error}',
97+
'recording_error': 'Recording error: {error}',
98+
'language_changed': 'Language changed to {language}'
99+
},
100+
'fr': {
101+
'window_title': 'Madick Chatbot',
102+
'ready': 'Prêt',
103+
'error': 'Erreur',
104+
'warning': 'Avertissement',
105+
'info': 'Information',
106+
'success': 'Succès',
107+
'chat': '💬 Discuter',
108+
'templates': '📋 Modèles',
109+
'history': '📚 Historique',
110+
'files': '📁 Fichiers',
111+
'settings': '⚙️ Paramètres',
112+
'model': 'Modèle:',
113+
'session': 'Session:',
114+
'clear': '🗑️ Effacer',
115+
'export': '📤 Exporter',
116+
'start_recording': 'Commencer l\'enregistrement',
117+
'stop_recording': 'Arrêter l\'enregistrement',
118+
'template': 'Modèle:',
119+
'send': '📩 Envoyer',
120+
'you': 'Vous',
121+
'ai': 'IA',
122+
'available_templates': 'Modèles disponibles',
123+
'none': 'Aucun',
124+
'custom': 'Personnalisé...',
125+
'new_template': 'Nouveau modèle',
126+
'template_name': 'Nom du modèle:',
127+
'template_prompt': 'Entrez le modèle (utilisez {input} pour l\'entrée utilisateur):',
128+
'template_description': 'Entrez une courte description:',
129+
'template_category': 'Sélectionnez ou entrez une catégorie:',
130+
'search_placeholder': 'Rechercher dans l\'historique...',
131+
'refresh': '🔄 Rafraîchir',
132+
'clear_history': '🗑️ Effacer l\'historique',
133+
'user': 'Utilisateur',
134+
'uploaded_files': 'Fichiers téléchargés',
135+
'upload_file': '📎 Télécharger un fichier',
136+
'attach_file': '📎 Joindre un fichier',
137+
'file_attached': 'Fichier joint',
138+
'binary_file': 'Fichier binaire',
139+
'file_too_large': 'Fichier trop volumineux',
140+
'invalid_json': 'JSON invalide',
141+
'binary_file_detected': 'Fichier binaire détecté',
142+
'error_reading_file': 'Erreur de lecture du fichier',
143+
'voice_input': 'Entrée vocale',
144+
'recording_start_prompt': 'Appuyez sur Démarrer pour commencer l\'enregistrement...',
145+
'initializing_mic': 'Initialisation du microphone...',
146+
'listening': 'Écoute en cours...',
147+
'processing_speech': 'Traitement de la parole...',
148+
'recording_stopped': 'Enregistrement arrêté',
149+
'recording_success': 'Enregistrement réussi!',
150+
'cancel': 'Annuler',
151+
'message_copied': 'Message copié dans le presse-papiers',
152+
'message_edit_ready': 'Message prêt pour l\'édition',
153+
'tts_future': 'Cette fonctionnalité sera implémentée dans une future mise à jour.',
154+
'response_saved_db': 'Réponse sauvegardée dans l\'historique',
155+
'response_saved_file': 'Réponse sauvegardée dans {filename}',
156+
'error_saving_db': 'Erreur lors de la sauvegarde dans la base de données: {error}',
157+
'error_saving_file': 'Erreur lors de la sauvegarde du fichier: {error}',
158+
'switched_model': 'Passage au modèle {model}',
159+
'switched_session': 'Session changée: {session}',
160+
'clear_chat_confirm': 'Êtes-vous sûr de vouloir effacer l\'historique de discussion?',
161+
'clear_history_confirm': 'Êtes-vous sûr de vouloir effacer tout l\'historique de discussion?',
162+
'history_cleared': 'Historique de discussion effacé avec succès',
163+
'error_history': 'Erreur lors de l\'effacement de l\'historique: {error}',
164+
'minimized': 'ChatBot Minimisé',
165+
'still_running': 'L\'application est toujours en cours d\'exécution dans la barre d\'état système.',
166+
'voice_error': 'Erreur d\'entrée vocale: {error}',
167+
'new_session': 'Nouvelle Session',
168+
'session_name': 'Entrez le nom de la session:',
169+
'session_exists': 'Le nom de la session existe déjà!',
170+
'delete_template': 'Supprimer le modèle',
171+
'delete_template_confirm': 'Êtes-vous sûr de vouloir supprimer le modèle \'{name}\'?',
172+
'template_deleted': 'Modèle \'{name}\' supprimé avec succès',
173+
'template_created': 'Modèle \'{name}\' créé avec succès',
174+
'error_template': 'Erreur lors {action} du modèle: {error}',
175+
'content_of_file': 'Contenu du fichier {filename}:',
176+
'send_file_confirm': 'Voulez-vous envoyer le contenu de {filename} à l\'IA?',
177+
'file_content_added': 'Contenu du fichier ajouté à l\'entrée',
178+
'binary_file_info': '{filename} est un fichier binaire. Seule la référence au fichier sera ajoutée.',
179+
'attached_file': '[Fichier joint: {filename}]',
180+
'file_attached_status': 'Fichier \'{filename}\' joint',
181+
'no_mic': 'Aucun microphone détecté',
182+
'speech_not_understood': 'Impossible de comprendre l\'audio. Veuillez parler plus clairement',
183+
'service_error': 'Erreur de service: {error}',
184+
'recording_error': 'Erreur d\'enregistrement: {error}',
185+
'language_changed': 'Langue changée en {language}'
186+
}
187+
}
188+
189+
self.current_language = 'en'
190+
191+
# Try to load language setting from settings file
192+
self._load_language_from_settings()
193+
194+
def _load_language_from_settings(self):
195+
"""Load language setting from the settings file if it exists."""
196+
197+
try:
198+
pass
199+
if os.path.exists('settings.json'):
200+
with open('settings.json', 'r', encoding='utf-8') as f:
201+
settings = json.load(f)
202+
if 'language' in settings:
203+
self.set_language(settings['language'])
204+
except Exception as e:
205+
# In case of any error, fallback to English
206+
print(f"Error loading language settings: {e}")
207+
self.current_language = 'en'
208+
209+
def reload_settings(self):
210+
"""Reload language settings from settings file."""
211+
self._load_language_from_settings()
212+
213+
def set_language(self, language_code):
214+
"""Set the current language."""
215+
if language_code in self.translations:
216+
self.current_language = language_code
217+
return True
218+
else:
219+
print(f"Language '{language_code}' not supported. Using English.")
220+
self.current_language = 'en'
221+
return False
222+
223+
def get_translation(self, key, **kwargs):
224+
"""Get a translated string for the given key with optional formatting."""
225+
# Get the translation dictionary for the current language
226+
translations = self.translations.get(self.current_language, self.translations['en'])
227+
228+
# Get the translated text or fallback to English or the key itself
229+
translated = translations.get(key)
230+
if translated is None:
231+
# Try English as fallback
232+
translated = self.translations['en'].get(key, key)
233+
234+
# Apply any format parameters
235+
if kwargs and '{' in translated:
236+
try:
237+
translated = translated.format(**kwargs)
238+
except KeyError:
239+
# If formatting fails, return the unformatted string
240+
pass
241+
242+
return translated
243+
244+
def tr(self, key, **kwargs):
245+
"""Shorthand method for get_translation."""
246+
return self.get_translation(key, **kwargs)

0 commit comments

Comments
 (0)