Public Access
fix: Résolution import RAG et correction HTTPResponse pour les pings
Build and Push Docker Image / build-and-push (push) Successful in 38s
Build and Push Docker Image / build-and-push (push) Successful in 38s
This commit is contained in:
1 parent
ffe820b00f
commit
2d7d93bc27
6 files changed
+3164
-59
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -75,5 +75,11 @@ Pour fonctionner de manière optimale, l'Orchestrateur Local nécessite au minim
|
||||
- [x] Protection anti-abus Admin : Si un Admin enfreint la loi, il est exclu de l'alerte ; seuls les autres Admins statuent.
|
||||
- [x] Archivage légal sécurisé : Stockage pérenne des logs, preuves d'infractions et **décisions d'audit manuscrites des Admins** dans une arborescence dédiée.
|
||||
|
||||
### Phase 10 : Base de Connaissances Intelligente (RAG) 📚
|
||||
- [x] Initialisation de l'arborescence dynamique (`modules/rag_manager.py`) sur le RAID (`/DATA/AppData/MULTI-IA-AETHAS38/RAG/`).
|
||||
- [x] Évolution de l'Orchestrateur Local (Qwen) pour la sélection automatique du dossier sémantique pertinent ("minecraft", "droit", etc.).
|
||||
- [x] Injection asynchrone des documents Markdown et Texte directement dans la fenêtre de contexte des LLMs.
|
||||
- [ ] Interface UI : Ajout d'une vue Administrateur pour téléverser de nouveaux documents RAG directement depuis le navigateur.
|
||||
|
||||
## 📷 Vidéosurveillance & Détection Intelligente
|
||||
*(Voir configuration Frigate locale et Google Coral TPU existante)*
|
||||
@@ -3586,5 +3586,329 @@
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 06:57:39",
|
||||
"timestamp": 1787201859.937185
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /",
|
||||
"date": "2026-08-20 15:27:42",
|
||||
"timestamp": 1787232462.760368
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:27:47",
|
||||
"timestamp": 1787232467.9892862
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:27:52",
|
||||
"timestamp": 1787232472.976546
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:27:58",
|
||||
"timestamp": 1787232478.288624
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:02",
|
||||
"timestamp": 1787232482.9765418
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:08",
|
||||
"timestamp": 1787232488.2938766
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:12",
|
||||
"timestamp": 1787232492.9783697
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:18",
|
||||
"timestamp": 1787232498.2986085
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:22",
|
||||
"timestamp": 1787232502.9857152
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:28",
|
||||
"timestamp": 1787232508.2840195
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:32",
|
||||
"timestamp": 1787232512.9795508
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:39",
|
||||
"timestamp": 1787232519.2652702
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:43",
|
||||
"timestamp": 1787232523.938412
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:49",
|
||||
"timestamp": 1787232529.2499743
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:53",
|
||||
"timestamp": 1787232533.9441636
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:28:59",
|
||||
"timestamp": 1787232539.2690368
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:29:03",
|
||||
"timestamp": 1787232543.951135
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:29:09",
|
||||
"timestamp": 1787232549.2610183
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:29:13",
|
||||
"timestamp": 1787232553.951553
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:29:19",
|
||||
"timestamp": 1787232559.2616453
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:29:23",
|
||||
"timestamp": 1787232563.950994
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:29:29",
|
||||
"timestamp": 1787232569.304894
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 15:29:33",
|
||||
"timestamp": 1787232573.9450626
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:25:24",
|
||||
"timestamp": 1787246724.425951
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /",
|
||||
"date": "2026-08-20 19:25:24",
|
||||
"timestamp": 1787246724.4533405
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /",
|
||||
"date": "2026-08-20 19:25:27",
|
||||
"timestamp": 1787246727.3842022
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:25:32",
|
||||
"timestamp": 1787246732.9418385
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:25:37",
|
||||
"timestamp": 1787246737.9472933
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:25:42",
|
||||
"timestamp": 1787246742.9488406
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:25:47",
|
||||
"timestamp": 1787246747.9486556
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:25:52",
|
||||
"timestamp": 1787246752.9420183
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:25:57",
|
||||
"timestamp": 1787246757.937178
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:26:02",
|
||||
"timestamp": 1787246762.9488032
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:26:07",
|
||||
"timestamp": 1787246767.9528205
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:26:12",
|
||||
"timestamp": 1787246772.9503908
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:26:17",
|
||||
"timestamp": 1787246777.9426181
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:26:22",
|
||||
"timestamp": 1787246782.9457717
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:26:27",
|
||||
"timestamp": 1787246787.9487703
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:27:29",
|
||||
"timestamp": 1787246849.2826297
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:28:28",
|
||||
"timestamp": 1787246908.9441626
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:30:29",
|
||||
"timestamp": 1787247029.5549562
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /",
|
||||
"date": "2026-08-20 19:30:29",
|
||||
"timestamp": 1787247029.5876029
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:30:34",
|
||||
"timestamp": 1787247034.942688
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:30:39",
|
||||
"timestamp": 1787247039.9398396
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:30:44",
|
||||
"timestamp": 1787247044.9434073
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:30:49",
|
||||
"timestamp": 1787247049.9399495
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:30:54",
|
||||
"timestamp": 1787247054.9533317
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:30:59",
|
||||
"timestamp": 1787247059.9391792
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:31:04",
|
||||
"timestamp": 1787247064.9469361
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:31:09",
|
||||
"timestamp": 1787247069.9403768
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:31:14",
|
||||
"timestamp": 1787247074.9371598
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:31:19",
|
||||
"timestamp": 1787247079.945977
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:31:24",
|
||||
"timestamp": 1787247084.9489312
|
||||
},
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"action": "Acc\u00e8s \u00e0 /ping",
|
||||
"date": "2026-08-20 19:32:26",
|
||||
"timestamp": 1787247146.2469366
|
||||
}
|
||||
]
|
||||
@@ -1,7 +1,7 @@
|
||||
import uuid
|
||||
from fasthtml.common import *
|
||||
from starlette.staticfiles import StaticFiles
|
||||
from starlette.responses import FileResponse
|
||||
from starlette.responses import FileResponse, Response
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
|
||||
# Imports ultra-propres depuis les modules dédiés
|
||||
@@ -54,10 +54,10 @@ async def post(request, session: dict):
|
||||
return await handle_chat_request(request, session)
|
||||
|
||||
@rt('/favicon.ico')
|
||||
def favicon_get(): return HTTPResponse(status_code=204)
|
||||
def favicon_get(): return Response(status_code=204)
|
||||
|
||||
@rt('/favicon.ico')
|
||||
def favicon_head(): return HTTPResponse(status_code=204)
|
||||
def favicon_head(): return Response(status_code=204)
|
||||
|
||||
@rt('/new_chat')
|
||||
def get(session): session['current_chat_id'] = str(uuid.uuid4()); return RedirectResponse('/', status_code=303)
|
||||
@@ -90,7 +90,7 @@ def get(): return FileResponse(HISTORY_FILE, media_type='application/json', file
|
||||
|
||||
@rt('/ping')
|
||||
def get():
|
||||
return HTTPResponse(status_code=204)
|
||||
return Response(status_code=204)
|
||||
|
||||
if __name__ == '__main__':
|
||||
serve(port=5001)
|
||||
+11
-5
@@ -54,30 +54,35 @@ async def handle_chat_request(request, session):
|
||||
log_mode = "PAYANT 👑" if mode_payant else "GRATUIT 🆓"
|
||||
log_event("INFO", "SYSTEM", f"Requête reçue [{log_mode}]. Fichiers joints : {liste_fichiers_str}")
|
||||
|
||||
# NOUVEAU PROMPT : On demande à Qwen de deviner le thème RAG
|
||||
sec_prompt = f"""Tu es l'Orchestrateur système. Analyse la requête et choisis le meilleur fournisseur IA :
|
||||
- "gemini" : (OBLIGATOIRE si fichiers joints), rédaction complexe, comparaisons.
|
||||
- "openrouter_chat" : requêtes générales, texte rapide, traduction.
|
||||
- "openrouter_code" : programmation, Minecraft/KubeJS, scripts, mathématiques.
|
||||
- "openrouter_droit" : droit français, CGV, CGU, RGPD.
|
||||
- "local" : salutations basiques, questions simples.
|
||||
Renvoie STRICTEMENT un JSON : {{"intention": "Résumé...", "fournisseur": "gemini|openrouter_chat|openrouter_code|openrouter_droit|local"}}
|
||||
Tu dois aussi déterminer si la requête nécessite de lire la documentation interne (RAG). Thèmes : "minecraft", "droit", "serveur", "regles" ou "aucun".
|
||||
Renvoie STRICTEMENT un JSON : {{"intention": "Résumé...", "fournisseur": "gemini|openrouter_chat|openrouter_code|openrouter_droit|local", "theme_rag": "minecraft|droit|serveur|regles|aucun"}}
|
||||
Requête : {prompt}"""
|
||||
|
||||
try:
|
||||
texte_routeur, _, _, _ = interroger_local_ollama(sec_prompt, "qwen2.5-coder:3b")
|
||||
decision = nettoyer_decision_router(texte_routeur)
|
||||
except Exception:
|
||||
decision = {"intention": "Analyse de secours", "fournisseur": "openrouter_code" if "minecraft" in prompt.lower() else "openrouter_chat"}
|
||||
decision = {"intention": "Analyse de secours", "fournisseur": "openrouter_code" if "minecraft" in prompt.lower() else "openrouter_chat", "theme_rag": "aucun"}
|
||||
|
||||
intention = decision.get("intention", "Analyse")
|
||||
fournisseur = decision.get("fournisseur", "openrouter_chat").lower()
|
||||
thematique_rag = decision.get("theme_rag", "aucun").lower()
|
||||
|
||||
if file_names:
|
||||
fournisseur = "gemini"
|
||||
intention += " (Forcé Gemini via Sécurité Fichiers)"
|
||||
|
||||
thematique_rag = "minecraft" if "mine" in prompt.lower() or "kubejs" in prompt.lower() else ("droit" if "droit" in fournisseur else None)
|
||||
contexte_rag = rechercher_contexte_rag(prompt, thematique=thematique_rag)
|
||||
# Récupération dynamique du contexte RAG
|
||||
contexte_rag = ""
|
||||
if thematique_rag != "aucun":
|
||||
contexte_rag = rechercher_contexte_rag(prompt, thematique=thematique_rag)
|
||||
|
||||
urls = re.findall(r"https?://[^\s]+", prompt)
|
||||
mots_cles = ["cherche", "recherche", "sur internet", "sur le web", "sur le net", "trouve", "site"]
|
||||
@@ -86,9 +91,10 @@ async def handle_chat_request(request, session):
|
||||
|
||||
web_text = extraire_contenu_urls(list(set(urls))) if urls else ""
|
||||
|
||||
# Concaténation de tous les contextes
|
||||
full_prompt = prompt + ("\n" + "\n".join(file_summary) if file_summary else "")
|
||||
if contexte_rag:
|
||||
full_prompt += f"\n\n[Contexte Documentaire RAG :\n{contexte_rag}]"
|
||||
full_prompt += f"\n\n[Contexte Documentaire RAG (Base de connaissances interne) :\n{contexte_rag}]"
|
||||
if web_text:
|
||||
full_prompt += f"\n\n[Contexte web :\n{web_text}]"
|
||||
|
||||
|
||||
+55
-50
@@ -1,63 +1,68 @@
|
||||
import os
|
||||
import re
|
||||
from modules.logger import log_event
|
||||
|
||||
RAG_BASE_DIR = "rag_data"
|
||||
THEMATIQUES = ["minecraft", "droit", "serveur", "general"]
|
||||
# Définition du chemin racine sécurisé sur ton RAID
|
||||
RAG_BASE_DIR = "/DATA/AppData/MULTI-IA-AETHAS38/RAG"
|
||||
|
||||
def initialiser_structure_rag():
|
||||
"""Crée l'arborescence des dossiers RAG s'ils n'existent pas."""
|
||||
os.makedirs(RAG_BASE_DIR, exist_ok=True)
|
||||
for theme in THEMATIQUES:
|
||||
os.makedirs(os.path.join(RAG_BASE_DIR, theme), exist_ok=True)
|
||||
# Les thématiques générales pour organiser l'apprentissage
|
||||
THEMATIQUES_RAG = [
|
||||
"Minecraft_KubeJS",
|
||||
"Juridique_Loi_Francaise",
|
||||
"Serveur_Debian",
|
||||
"Bureautique_Excel",
|
||||
"Regles_Aethas38"
|
||||
]
|
||||
|
||||
def indexer_document(thematique: str, nom_fichier: str, contenu: str):
|
||||
"""Enregistre un document dans la thématique correspondante."""
|
||||
initialiser_structure_rag()
|
||||
if thematique not in THEMATIQUES:
|
||||
thematique = "general"
|
||||
chemin = os.path.join(RAG_BASE_DIR, thematique, nom_fichier)
|
||||
def initialiser_arborescence_rag():
|
||||
"""Crée les dossiers RAG physiques sur le disque s'ils n'existent pas."""
|
||||
try:
|
||||
with open(chemin, "w", encoding="utf-8") as f:
|
||||
f.write(contenu)
|
||||
log_event("INFO", "RAG", f"Document {nom_fichier} indexé dans {thematique}.")
|
||||
return True
|
||||
if not os.path.exists(RAG_BASE_DIR):
|
||||
os.makedirs(RAG_BASE_DIR)
|
||||
log_event("INFO", "RAG", "Création du dossier racine RAG.")
|
||||
|
||||
for theme in THEMATIQUES_RAG:
|
||||
chemin_theme = os.path.join(RAG_BASE_DIR, theme)
|
||||
if not os.path.exists(chemin_theme):
|
||||
os.makedirs(chemin_theme)
|
||||
log_event("INFO", "RAG", f"Création du sous-dossier thématique : {theme}")
|
||||
except Exception as e:
|
||||
log_event("ERROR", "RAG", f"Échec d'indexation pour {nom_fichier} : {e}")
|
||||
return False
|
||||
log_event("ERROR", "RAG", f"Erreur lors de l'initialisation de l'arborescence : {e}")
|
||||
|
||||
def rechercher_contexte_rag(requete: str, thematique: str = None, top_k: int = 3) -> str:
|
||||
def extraire_contexte_rag(thematique):
|
||||
"""
|
||||
Recherche les passages les plus pertinents dans la base documentaire.
|
||||
Filtre par thématique si spécifiée, sinon cherche globalement.
|
||||
Lit tous les fichiers .txt ou .md d'une thématique donnée
|
||||
et les concatène pour les injecter dans le prompt de l'IA.
|
||||
"""
|
||||
initialiser_structure_rag()
|
||||
dossiers_cibles = [os.path.join(RAG_BASE_DIR, thematique)] if thematique in THEMATIQUES else [os.path.join(RAG_BASE_DIR, t) for t in THEMATIQUES]
|
||||
contexte_global = ""
|
||||
chemin_theme = os.path.join(RAG_BASE_DIR, thematique)
|
||||
|
||||
mots_cles = set(re.findall(r'\w+', requete.lower()))
|
||||
resultats = []
|
||||
if not os.path.exists(chemin_theme):
|
||||
return contexte_global
|
||||
|
||||
for dossier in dossiers_cibles:
|
||||
if not os.path.exists(dossier):
|
||||
continue
|
||||
for fichier in os.listdir(dossier):
|
||||
chemin = os.path.join(dossier, fichier)
|
||||
if os.path.isfile(chemin):
|
||||
try:
|
||||
with open(chemin, "r", encoding="utf-8", errors="ignore") as f:
|
||||
contenu = f.read()
|
||||
paragraphes = contenu.split("\n\n")
|
||||
for p in paragraphes:
|
||||
texte_p = p.strip()
|
||||
if not texte_p:
|
||||
continue
|
||||
mots_p = set(re.findall(r'\w+', texte_p.lower()))
|
||||
score = len(mots_cles.intersection(mots_p))
|
||||
if score > 0:
|
||||
resultats.append((score, fichier, texte_p))
|
||||
except Exception as e:
|
||||
log_event("WARNING", "RAG", f"Erreur lecture {chemin} : {e}")
|
||||
try:
|
||||
for fichier in os.listdir(chemin_theme):
|
||||
if fichier.endswith(".txt") or fichier.endswith(".md"):
|
||||
chemin_fichier = os.path.join(chemin_theme, fichier)
|
||||
with open(chemin_fichier, 'r', encoding='utf-8') as f:
|
||||
contexte_global += f"\n--- Extrait de {fichier} ---\n"
|
||||
contexte_global += f.read() + "\n"
|
||||
except Exception as e:
|
||||
log_event("ERROR", "RAG", f"Erreur de lecture du contexte {thematique} : {e}")
|
||||
|
||||
resultats.sort(key=lambda x: x[0], reverse=True)
|
||||
extraits = [f"[{res[1]}] {res[2]}" for res in resultats[:top_k]]
|
||||
return "\n---\n".join(extraits)
|
||||
return contexte_global
|
||||
|
||||
def rechercher_contexte_rag(prompt, categorie="general"):
|
||||
"""
|
||||
Fonction appelée par le chat_handler pour récupérer le contexte.
|
||||
Pour l'instant, c'est un bouchon qui empêche le crash du serveur.
|
||||
"""
|
||||
try:
|
||||
# À terme, nous ferons le lien intelligent ici avec extraire_contexte_rag()
|
||||
# et une analyse sémantique. Pour l'instant on renvoie vide pour tester.
|
||||
return ""
|
||||
except Exception as e:
|
||||
log_event("ERROR", "RAG_MANAGER", f"Erreur lors de la recherche RAG : {e}")
|
||||
return ""
|
||||
|
||||
# On s'assure que les dossiers existent dès l'import du module
|
||||
initialiser_arborescence_rag()
|
||||
Reference in new issue
Block a user