#!/usr/bin/env python3 """ Jarvis-Cognitive Desktop - Marco Aurelio Applicazione desktop PyQt6 per interazione con l'Imperatore Filosofo """ import sys import os import traceback from datetime import datetime from dotenv import load_dotenv from PyQt6.QtWidgets import QApplication, QDialog from PyQt6.QtGui import QIcon from desktop.ui.main_window import MainWindow from desktop.ui.profile_selector_dialog import ( ProfileSelectorDialog, load_last_profile, save_last_profile ) from core.kernel import JarvisKernel def exception_hook(exctype, value, tb): """Hook globale per catturare tutte le eccezioni non gestite""" project_root = os.path.dirname(os.path.abspath(__file__)) log_file = os.path.join(project_root, 'crash.log') with open(log_file, 'a') as f: f.write(f"\n{'='*80}\n") f.write(f"CRASH: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n") f.write(f"{'='*80}\n") f.write(f"Tipo: {exctype.__name__}\n") f.write(f"Errore: {str(value)}\n\n") f.write(''.join(traceback.format_exception(exctype, value, tb))) f.write(f"\n{'='*80}\n") print(f"\n{'='*80}") print(f"ERRORE CRITICO - Log salvato in: {log_file}") print(f"{'='*80}") print(''.join(traceback.format_exception(exctype, value, tb))) print(f"{'='*80}\n") # Chiama l'handler di default sys.__excepthook__(exctype, value, tb) def main(): """Entry point dell'applicazione desktop""" # Installa exception hook globale sys.excepthook = exception_hook # Carica variabili d'ambiente project_root = os.path.dirname(os.path.abspath(__file__)) env_path = os.path.join(project_root, 'data', '.env') if os.path.exists(env_path): print(f"[JARVIS DESKTOP] Caricamento variabili d'ambiente da: {env_path}") load_dotenv(dotenv_path=env_path) else: print(f"[JARVIS DESKTOP] ATTENZIONE: File .env non trovato") # Pre-carica embeddings PRIMA di aprire GUI print("\n" + "="*60) print("⏳ CARICAMENTO EMBEDDINGS IN CORSO...") print(" Questo può richiedere 1-2 minuti al primo avvio") print(" Attendere prego, l'applicazione si aprirà automaticamente") print("="*60 + "\n") # Pre-carica embeddings (verrà registrato dopo selezione profilo) embeddings = None try: from langchain_huggingface import HuggingFaceEmbeddings print("[EMBEDDINGS] Inizializzazione modello sentence-transformers/all-MiniLM-L6-v2...") embeddings = HuggingFaceEmbeddings( model_name="sentence-transformers/all-MiniLM-L6-v2" ) print("[EMBEDDINGS] ✅ Modello caricato e pronto\n") except Exception as e: print(f"[EMBEDDINGS] ⚠️ Errore caricamento embeddings: {e}") print("[EMBEDDINGS] L'app funzionerà ma senza supporto RAG\n") # DOPO il caricamento embeddings, crea applicazione Qt app = QApplication(sys.argv) app.setApplicationName("Jarvis Cognitive") app.setOrganizationName("Jarvis Cognitive") # Mostra dialog selezione profilo last_profile = load_last_profile() dialog = ProfileSelectorDialog(last_profile=last_profile) if dialog.exec() != QDialog.DialogCode.Accepted: print("[JARVIS DESKTOP] Selezione profilo annullata. Uscita.") sys.exit(0) selected_profile = dialog.get_selected_profile() save_last_profile(selected_profile) # Persiste scelta print(f"[JARVIS DESKTOP] Profilo selezionato: {selected_profile}") # Registra embeddings per il profilo selezionato if embeddings is not None: import services.ragservice.rag_document_manager as rag_mgr rag_mgr._EMBEDDINGS_CACHE[selected_profile] = embeddings print(f"[EMBEDDINGS] Cache registrata per profilo: {selected_profile}") # Inizializza il Kernel CON PROFILO SELEZIONATO print("[JARVIS DESKTOP] Inizializzazione Kernel...") config_path = os.path.join(project_root, 'config', 'config.yaml') kernel = JarvisKernel(config_path=config_path, profile_name=selected_profile) print("[JARVIS DESKTOP] Avvio Kernel...") kernel.start() print("[JARVIS DESKTOP] Kernel attivo") # Crea finestra principale con riferimento diretto al kernel window = MainWindow(kernel) window.show() print(f"[JARVIS DESKTOP] Applicazione pronta - Profilo: {selected_profile}") # Avvia event loop Qt exit_code = app.exec() # Cleanup print("[JARVIS DESKTOP] Arresto Kernel...") kernel.stop() print("[JARVIS DESKTOP] Arrivederci") sys.exit(exit_code) if __name__ == "__main__": try: main() except Exception as e: # Salva errore in file di log prima di crashare log_file = os.path.join(os.path.dirname(__file__), 'crash.log') with open(log_file, 'a') as f: f.write(f"\n{'='*80}\n") f.write(f"CRASH: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n") f.write(f"{'='*80}\n") f.write(f"Errore: {str(e)}\n\n") f.write(traceback.format_exc()) f.write(f"\n{'='*80}\n") print(f"\n{'='*80}") print(f"ERRORE CRITICO - Log salvato in: {log_file}") print(f"{'='*80}") print(traceback.format_exc()) print(f"{'='*80}\n") # Mantieni terminale aperto input("Premi INVIO per chiudere...") sys.exit(1)