noyau_phase2.py — noyau Phase 2 persistance SQLite (18/10/2026)

–– coding: utf-8 ––

"""
MIRA — Noyau Phase 2
Fichier : noyau_phase2.py
Phase : 2 — Persistance SQLite branchée sur le noyau
Date : 18/10/2026

Nouveautés par rapport à noyau_minimal.py :

  • Initialisation des deux bases SQLite au démarrage
  • _enregistrer_historique() écrit dans historique.db
  • M2_historique rechargé depuis historique.db au démarrage
  • Identité MIRA-0001 définie dans utilisateur.db
  • tour_num lu depuis MAX(tour) dans historique.db
    (les numéros de tour ne repartent pas de 1 à chaque session)

Corrections v2 :

  • import json retiré (inutile)
  • tour_num calculé depuis la base et non depuis M2_historique
  • ERREUR_GESTIONNAIRES initialisée à "" pour éviter NameError
    """

import os
import sqlite3
import sys
from datetime import datetime, timezone

CHEMIN_NOYAU = os.path.dirname(os.path.abspath(file))
CHEMIN_DATA = "/mnt/sda1/home/MIRA_Project/data"

if CHEMIN_DATA not in sys.path:
sys.path.insert(0, CHEMIN_DATA)

ERREUR_GESTIONNAIRES = ""
try:
import gestionnaire_historique as gh
import gestionnaire_utilisateur as gu
GESTIONNAIRES_OK = True
except Exception as e:
GESTIONNAIRES_OK = False
ERREUR_GESTIONNAIRES = str(e)

def _lire_prochain_tour():
if not GESTIONNAIRES_OK:
return 1
try:
import sqlite3
connexion = sqlite3.connect(gh.CHEMIN_BASE)
curseur = connexion.cursor()
curseur.execute("SELECT MAX(tour) FROM echanges")
resultat = curseur.fetchone()
connexion.close()
if resultat and resultat[0] is not None:
return resultat[0] + 1
return 1
except Exception:
return 1

def initialiser_bases():
if not GESTIONNAIRES_OK:
print("ATTENTION : gestionnaires indisponibles — "

  • ERREUR_GESTIONNAIRES)
    return False

    gh.initialiser()
    gu.initialiser()

    identite = gu.lire_identite()
    if identite is None:
    gu.definir_identite("MIRA-0001", "createur")
    print("Identité MIRA-0001 définie.")

    ok_h, err_h = gh.verifier_integrite()
    ok_u, err_u = gu.verifier_integrite()

    if not ok_h:
    print("ERREUR historique.db : " + str(err_h))
    return False
    if not ok_u:
    print("ERREUR utilisateur.db : " + str(err_u))
    return False

    return True

def charger_historique_depuis_base(limite=20):
if not GESTIONNAIRES_OK:
return []

echanges = gh.lire_historique_recent(limite)
historique = []
for e in echanges:
    historique.append({
        "tour"       : e["tour"],
        "horodatage" : e["horodatage"],
        "question"   : e["question"],
        "reponse"    : e["reponse"],
        "source"     : e["source"]
    })
return historique

def _nouveau_contexte(question, historique=None):
return {
"M1_question" : question,
"M2_historique" : historique if historique else [],
"M3_intention" : None,
"M4_specialiste": None,
"M5_reponse" : None,
"M6_meta" : {
"source_reponse" : None,
"erreurs" : [],
"mode" : "normal"
}
}

def _detecter_intention(contexte):
q = contexte["M1_question"].lower()

if any(m in q for m in ["date", "jour", "heure", "aujourd"]):
    contexte["M3_intention"] = "question_date"
elif any(m in q for m in ["qui t'a", "cree", "createur", "auteur"]):
    contexte["M3_intention"] = "identite"
elif any(m in q for m in ["maintenance", "analyser", "rapport"]):
    contexte["M3_intention"] = "maintenance"
else:
    contexte["M3_intention"] = "inconnue"

return contexte

def _reponse_degradee(contexte):
intention = contexte["M3_intention"]

if intention == "question_date":
    maintenant = datetime.now(timezone.utc)
    contexte["M5_reponse"] = (
        "Nous sommes le {}."
        .format(maintenant.strftime("%d/%m/%Y à %Hh%M UTC"))
    )
    contexte["M6_meta"]["source_reponse"] = "degradee"

elif intention == "identite":
    contexte["M5_reponse"] = (
        "Je suis MIRA, conçue et façonnée "
        "par Da Conceição Mario."
    )
    contexte["M6_meta"]["source_reponse"] = "degradee"

return contexte

def _reponse_factice(contexte):
if contexte["M5_reponse"] is None:
contexte["M5_reponse"] = (
"Je suppose mais je ne garantis pas cette réponse, "
"je n’ai pas accès au réseau."
)
contexte["M6_meta"]["source_reponse"] = "factice"

return contexte

def _enregistrer_historique(contexte):
tour_num = _lire_prochain_tour()
entree = {
"tour" : tour_num,
"horodatage" : datetime.now(timezone.utc).isoformat(),
"question" : contexte["M1_question"],
"reponse" : contexte["M5_reponse"],
"source" : contexte["M6_meta"]["source_reponse"]
}
contexte["M2_historique"].append(entree)

if GESTIONNAIRES_OK:
    try:
        gh.ajouter_echange(
            tour_num,
            contexte["M1_question"],
            contexte["M5_reponse"],
            contexte["M6_meta"]["source_reponse"]
        )
    except Exception as e:
        contexte["M6_meta"]["erreurs"].append(
            "historique.db : " + str(e)
        )

return contexte

def executer(contexte):
try:
contexte = _detecter_intention(contexte)
contexte = _reponse_degradee(contexte)
contexte = _reponse_factice(contexte)
contexte = _enregistrer_historique(contexte)
except Exception as e:
contexte["M6_meta"]["erreurs"].append(str(e))
if contexte["M5_reponse"] is None:
contexte["M5_reponse"] = "Erreur interne dans le noyau."
contexte["M6_meta"]["source_reponse"] = "erreur"

return contexte

if name == "main":
print("=== MIRA — Noyau Phase 2 ===\n")

print("Initialisation des bases...")
ok = initialiser_bases()
if not ok:
    print("Arrêt : bases inaccessibles.")
    sys.exit(1)
print("Bases OK.\n")

historique = charger_historique_depuis_base(20)
print("Historique chargé : {} échange(s).\n".format(len(historique)))

questions = [
    "quel jour sommes-nous ?",
    "qui t'a créé ?",
    "comment fonctionne Python ?"
]

for q in questions:
    print("--- Question : " + q)
    ctx = _nouveau_contexte(q, historique)
    ctx = executer(ctx)
    print("Réponse : " + str(ctx["M5_reponse"]))
    print("Source  : " + str(ctx["M6_meta"]["source_reponse"]))
    print("Erreurs : " + str(ctx["M6_meta"]["erreurs"]))
    historique = ctx["M2_historique"]
    print()

print("--- Historique final ---")
for e in historique[-3:]:
    print("{} — {} → {}".format(
        e["tour"], e["question"][:30], e["source"]))

print("\nTest terminé.")

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Défiler vers le haut