# utils/vector_store.py — Le Socle Technique Unique # Didier : Modifié pour l'adapter parfaitement au projet14bis (Assistant de Caisse Local) """ Module central de gestion de la base de données vectorielle FAISS pour l'Assistant de Caisse projet14bis objectif1. Anciennement "coquille vide", ce script centralise désormais la logique de chargement de l'index et de formatage des documents afin d'alléger 'streamlit_app.py' et 'MistralChat.py', évitant ainsi toute duplication de logique LangChain (Phase 4 : Optimisation unifiée en local pur). """ import streamlit as st import warnings # Didier : Masquage des warnings de dépréciation pour la propreté de l'interface et des logs terminaux #warnings.filterwarnings("ignore", category=DeprecationWarning) # Didier : Remplacement de l'expert Mistral Cloud par le connecteur officiel et autonome 'OllamaEmbeddings' # issu de langchain_ollama. from langchain_ollama import OllamaEmbeddings # Didier : Retour à l'import stable. FAISS fait partie de langchain_community, le warning est supprimé via filterwarnings. from langchain_community.vectorstores import FAISS # Utilisation de la configuration centralisée mise à jour pour le Projet 14Bis from utils.config import ( OLLAMA_BASE_URL, FAISS_INDEX_DIR, EMBEDDING_MODEL ) def load_vector_store(): """ Charge la base de données vectorielle FAISS existante en utilisant les chemins configurés. Cette responsabilité a été déportée ici pour respecter la séparation des responsabilités (logique d’UI vs logique de stockage vectoriel 100% local). """ if not OLLAMA_BASE_URL: st.error("URL du serveur Ollama local manquante dans la configuration.") return None # Etape 2 : Chargement de l'Index Vectoriel embeddings = OllamaEmbeddings( base_url=OLLAMA_BASE_URL, model=EMBEDDING_MODEL ) if not FAISS_INDEX_DIR.exists(): st.error(f"L'index FAISS est introuvable dans {FAISS_INDEX_DIR}. Veuillez lancer indexer.py.") return None try: # allow_dangerous_deserialization est nécessaire pour charger les fichiers .pkl de l'index local vector_store = FAISS.load_local( str(FAISS_INDEX_DIR), embeddings, allow_dangerous_deserialization=True ) return vector_store except Exception as e: st.error(f"Erreur lors du chargement de l'index local : {e}") return None def format_docs(docs): """ Etape 6 : Création de la Chaîne de Formatage des Documents. """ formatted = [] for d in docs: header = f"--- PROCESSUS : {d.metadata.get('process', 'Général')} | ACTION MÉTIER : {d.metadata.get('action', 'N/A')} ---" details = f"Écran de départ: {d.metadata.get('ecran_depart', 'N/A')} | Mots-clés: {d.metadata.get('mots_cles', 'N/A')}" content = f"Instructions de l'interface :\n{d.page_content}" formatted.append(f"{header}\n{details}\n{content}") return "\n\n".join(formatted)