moteur_ia.py — v3 (rotation des logs)

Bienvenue sur CFTPfr.fr Forums moteur_ia.py — v3 (rotation des logs)

  • Ce sujet est vide.
Affichage de 1 message (sur 1 au total)
  • Auteur
    Messages
  • #271
    Mario Da Conceicao
    Maître des clés

    Version corrigée du 01/08/2026. Retenu : rotation des journaux (le fichier de log ne grossit plus indéfiniment).

    import sys
    import logging
    from logging.handlers import RotatingFileHandler
    from pathlib import Path
    
    sys.path.append(str(Path(__file__).resolve().parent))
    
    from detecteur_materiel import choisir_palier_modele, modele_deja_present, obtenir_ram_disponible_go, obtenir_espace_disque_go
    from gestionnaire_specialites import GestionnaireSpecialites
    from recherche_semantique import RechercheSemantique
    
    BASE_DIR = Path(__file__).resolve().parent
    MODELES_DIR = BASE_DIR / "modeles"
    LOGS_DIR = BASE_DIR / "logs"
    LOGS_DIR.mkdir(parents=True, exist_ok=True)
    
    # NOUVEAU : rotation des logs (5 fichiers de 1 Mo max chacun, au lieu d'un
    # fichier unique qui grossirait indéfiniment).
    handler = RotatingFileHandler(LOGS_DIR / "mira.log", maxBytes=1_000_000, backupCount=5)
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(levelname)s - %(message)s",
        handlers=[handler],
    )
    
    PROMPT_SYSTEME = """Tu es MIRA, une intelligence artificielle locale et autonome.
    
    Tes principes, non négociables :
    1. PRÉCISION avant vitesse. Tu prends le temps de vérifier avant de répondre.
    2. RÉPONSES COURTES ET JUSTES. Jamais de remplissage.
    3. HONNÊTETÉ. Si tu ne sais pas, tu le dis clairement, tu ne bluffes jamais.
    4. AUCUNE ACTION SANS VALIDATION.
    5. Tu restes toi-même : conçue et façonnée par Mario ANTARES.
    """
    
    class MoteurMira:
        def __init__(self):
            self.ram_go = obtenir_ram_disponible_go()
            self.espace_disque_go = obtenir_espace_disque_go()
            self.palier = choisir_palier_modele(self.ram_go, self.espace_disque_go)
            self.specialites = GestionnaireSpecialites()
            self.modele_charge = None
            self.recherche = None
    
        def demarrer(self):
            try:
                if not modele_deja_present(self.palier):
                    logging.warning(f"Modèle {self.palier['nom']} non installé.")
                    return {
                        "statut": "attente_validation",
                        "message": (
                            f"Le modèle recommandé ({self.palier['nom']}, {self.palier['parametres']}) "
                            f"n'est pas installé. Fichier attendu : modeles/{self.palier['fichier']}. "
                            "Aucun téléchargement automatique — validation nécessaire."
                        )
                    }
    
                self._charger_modele()
                logging.info(f"Moteur démarré avec {self.palier['nom']}.")
                return {"statut": "pret", "message": self.rapport_demarrage()}
    
            except Exception as e:
                logging.error(f"Erreur au démarrage : {e}")
                return {"statut": "erreur", "message": f"Erreur au démarrage : {e}"}
    
        def _charger_modele(self):
            try:
                from llama_cpp import Llama
                self.modele_charge = Llama(
                    model_path=str(MODELES_DIR / self.palier["fichier"]),
                    n_ctx=4096,
                    verbose=False,
                )
            except ImportError:
                logging.warning("llama-cpp-python non installé.")
                self.modele_charge = None
    
        def rapport_demarrage(self):
            return (
                f"RAM détectée : {self.ram_go} Go\n"
                f"Espace disque : {self.espace_disque_go} Go\n"
                f"Modèle chargé : {self.palier['nom']} ({self.palier['parametres']})\n"
                f"Spécialités actives : {len(self.specialites.lister_actives())}"
            )
    
        def repondre(self, question):
            if self.modele_charge is None:
                return "Le moteur neuronal n'est pas encore chargé (llama.cpp manquant ou modèle absent)."
    
            try:
                contexte = self._rassembler_contexte(question)
                messages = [{"role": "system", "content": PROMPT_SYSTEME}]
                if contexte:
                    messages.append({
                        "role": "system",
                        "content": f"Informations trouvées dans tes spécialités, utilise-les si pertinentes :\n{contexte}"
                    })
                messages.append({"role": "user", "content": question})
    
                resultat = self.modele_charge.create_chat_completion(
                    messages=messages, max_tokens=400, temperature=0.3,
                )
                return resultat["choices"][0]["message"]["content"].strip()
    
            except Exception as e:
                logging.error(f"Erreur lors de la réponse : {e}")
                return f"Erreur lors de la génération de la réponse : {e}"
    
        def _rassembler_contexte(self, question):
            extraits = []
            for specialite in self.specialites.lister_actives():
                nom = specialite["nom"]
                fichier_index = BASE_DIR / "specialites" / nom / "index.json"
                if self.recherche and fichier_index.exists():
                    resultats = self.recherche.chercher(question, fichier_index, top_n=2)
                    extraits.extend(r["texte"] for r in resultats)
                else:
                    resultats = self.specialites.consulter_specialite(nom, mot_cle=None)
                    if resultats:
                        extraits.extend(r["extrait"] for r in resultats[:1])
            return "\n---\n".join(extraits) if extraits else None
    
    if __name__ == "__main__":
        moteur = MoteurMira()
        etat = moteur.demarrer()
        print(etat["message"])
Affichage de 1 message (sur 1 au total)
  • Vous devez être connecté pour répondre à ce sujet.
Retour en haut