File size: 3,889 Bytes
dfcacaf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# executives/ui.py
import gradio as gr
import asyncio
from main import NexusAgenticSystem

# Initialisation du noyau dur
nexus = NexusAgenticSystem()

async def interaction_nexus(message, history):
    if not nexus.llm_en_ligne:
        await nexus.prechauffer_cerveau()

    # 1. RECONSTITUTION DE LA MÉMOIRE (Blindage Multi-Versions Gradio)
    ticket_complet = ""
    transcript_llm = ""
    
    for msg in history:
        # Compatibilité Gradio 5+ (Format Liste de Dictionnaires)
        if isinstance(msg, dict):
            role = msg.get("role", "")
            content = msg.get("content", "")
            if role == "user":
                ticket_complet += f"{content} "
                transcript_llm += f"Client: {content}\n"
            elif role == "assistant":
                transcript_llm += f"Régulateur: {content}\n"
                
        # Compatibilité Gradio 4 (Ancien Format Liste de Tuples)
        elif isinstance(msg, (list, tuple)) and len(msg) == 2:
            u, b = msg
            if u:
                ticket_complet += f"{u} "
                transcript_llm += f"Client: {u}\n"
            if b:
                transcript_llm += f"Régulateur: {b}\n"

    # Ajout du message courant
    ticket_complet += message
    transcript_llm += f"Client: {message}"

    # 2. ANALYSE GLOBALE VIA LE MODÈLE ML (Sur l'ensemble des faits)
    domaine, score, friction = nexus.evaluator.evaluer_ticket(ticket_complet)

    # 3. VÉRIFICATION DYNAMIQUE DE LA LOCALISATION
    localisation_obtenue = nexus.verifier_presence_localisation(ticket_complet)

    # 4. GESTION DE L'ÉTAT (State Management réel)
    session_state = {
        "domaine_verrouille": domaine,
        "score_verrouille": score,
        "localisation_obtenue": localisation_obtenue,
        "frustration_count": 0
    }
    
    # 5. COUPE-CIRCUIT D'AGRESSIVITÉ OU ABANDON
    mots_frustration = ["bordel", "foutre", "con", "merde", "putain", "répéter", "fin au ticket", "stop", "quitter", "q"]
    if any(mot in message.lower() for mot in mots_frustration):
        niveau = "🔴 CRITIQUE" if score >= 8 else "🟠 HAUTE" if score >= 5 else "🟢 BASSE"
        nexus.logger.log(ticket_complet, domaine, [], score, statut="CLOTURE_FORCEE")
        return f"⚠️ RUPTURE DE LIAISON DÉTECTÉE. TICKET CLOS D'URGENCE.\nDomaine : {domaine}\nNiveau Alerte : {niveau}\nTransmission immédiate aux unités de terrain."

    # 6. DÉCISION DE ROUTAGE
    if friction != "COMPLET" or not localisation_obtenue:
        statut, question_bot = await nexus.generer_question_bot(
            transcript=transcript_llm,
            texte_utilisateur=message,
            domaine=domaine,
            score_actuel=score,
            state=session_state
        )
        
        if statut == "COMPLET":
            niveau = "🔴 CRITIQUE" if score >= 8 else "🟠 HAUTE" if score >= 5 else "🟢 BASSE"
            nexus.logger.log(ticket_complet, domaine, [], score, statut="CLOS")
            return f"✅ TICKET CLOS ET TRANSMIS.\nDomaine : {domaine}\nNiveau Alerte : {niveau}\nLes unités sont en route."
            
        return f"🚨 [Unités: {domaine} | Urgence: {score}/10]\nNEXUS: {question_bot}"
    
    else:
        niveau = "🔴 CRITIQUE" if score >= 8 else "🟠 HAUTE" if score >= 5 else "🟢 BASSE"
        nexus.logger.log(ticket_complet, domaine, [], score, statut="CLOS")
        return f"✅ TICKET COMPLET ET TRANSMIS.\nDomaine : {domaine}\nNiveau Alerte : {niveau}\nLes unités sont en route."

# Définition de l'interface graphique
app = gr.ChatInterface(
    fn=interaction_nexus,
    title="NEXUS Prime - Centre de Commandement",
    description="Entrez la situation d'urgence. Moteur hybride tactique (Scikit-Learn + Ollama / Gemma 4).",
    fill_height=True
)

if __name__ == "__main__":
    app.launch(server_name="0.0.0.0", server_port=7860, share=True)