# Jarvis-Cognitive/core/cognitive_engine/indexer.py (v_final_billing) import os from dotenv import load_dotenv # Importazioni da LangChain from langchain_google_genai import GoogleGenerativeAIEmbeddings from langchain_chroma import Chroma from langchain_community.document_loaders import PyPDFLoader, TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter # Carichiamo il file .env script_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(os.path.dirname(script_dir)) env_path = os.path.join(project_root, 'data', '.env') if os.path.exists(env_path): print(f"--- Caricamento variabili d'ambiente da: {env_path} ---") load_dotenv(dotenv_path=env_path) else: print(f"ATTENZIONE: File .env non trovato in {env_path}. L'autenticazione potrebbe fallire.") # Definiamo la cartella persistente per il database ChromaDB PERSIST_DIRECTORY = os.path.join(project_root, "data", "chroma_db") def indicizza_file(filepath): """ Funzione principale che carica, splitta e indicizza un documento. """ if not os.path.exists(filepath): print(f"Errore: Il file '{filepath}' non esiste.") return False, "File non trovato." print(f"--- Inizio indicizzazione di: {filepath} ---") # 1. Inizializza il modello di embedding try: google_api_key = os.getenv("GOOGLE_API_KEY") if not google_api_key: raise ValueError("La variabile d'ambiente GOOGLE_API_KEY non è stata trovata o è vuota.") embeddings = GoogleGenerativeAIEmbeddings( model="models/embedding-001", google_api_key=google_api_key ) except Exception as e: error_message = f"Errore durante l'inizializzazione degli embeddings: {e}" print(error_message) return False, error_message # 2. Inizializza il database vettoriale ChromaDB os.makedirs(PERSIST_DIRECTORY, exist_ok=True) vectorstore = Chroma( persist_directory=PERSIST_DIRECTORY, embedding_function=embeddings ) # 3. Carica il documento print("Caricamento del documento...") try: if filepath.lower().endswith(".pdf"): loader = PyPDFLoader(filepath) elif filepath.lower().endswith(".txt"): # Ripristinata la versione originale e robusta per i file di testo loader = TextLoader(filepath, encoding='utf-8', errors='ignore') else: error_message = f"Formato file non supportato per '{os.path.basename(filepath)}'. Supportati: .txt, .pdf" print(error_message) return False, error_message documents = loader.load() except Exception as e: error_message = f"Errore durante il caricamento del documento: {e}" print(error_message) return False, error_message # 4. Splitta il documento in chunk print("Divisione del documento in chunk...") text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) docs_split = text_splitter.split_documents(documents) # 5. Aggiunge i chunk al database vettoriale (versione pulita e diretta) print(f"Aggiunta di {len(docs_split)} chunk al database vettoriale...") try: vectorstore.add_documents(docs_split) success_message = f"Indicizzazione completata con successo per {os.path.basename(filepath)}!" print(f"--- {success_message} ---\n") return True, success_message except Exception as e: error_message = f"Errore durante l'aggiunta dei documenti al database: {e}" print(error_message) return False, error_message