chore: nettoyage .gitignore - retrait venv, __pycache__, .env, data, logs, modèles du tracking

This commit is contained in:
Lowei 2026-06-16 20:40:37 +02:00
parent 7333a22bcd
commit 604a5affe0
9231 changed files with 1244 additions and 1601201 deletions

View file

@ -253,17 +253,72 @@ async def save_user_memory_async(user_id: int | str, data: Dict[str, Any], guild
logger.debug(f"Mémoire marquée dirty pour utilisateur {user_id} (guild {guild_id})")
# Référence globale au LLM manager (set par le bot au démarrage)
_llm_manager = None
def set_llm_manager(llm_manager) -> None:
"""Enregistre le LLM manager pour les résumés."""
global _llm_manager
_llm_manager = llm_manager
async def summarize_messages(messages: List[Dict[str, Any]]) -> str:
"""
Fonction de résumé améliorée. Utilise une extraction de mots-clés et de phrases clés
pour un résumé plus intelligent. Placeholder pour intégration IA future.
Cette fonction est `async` pour faciliter un remplacement par un appel réseau/IA.
Résume une liste de messages via le LLM.
Fallback sur l'extraction de mots-clés si le LLM n'est pas disponible.
"""
if not messages:
return ""
# Extraire tous les textes utilisateur et bot
# Construire le transcript à résumer
transcript_lines = []
for m in messages:
um = m.get("user_message", "").strip()
bm = m.get("bot_message", "").strip()
if um:
transcript_lines.append(f"Utilisateur: {um}")
if bm:
transcript_lines.append(f"Bot: {bm}")
transcript = "\n".join(transcript_lines)
# Tronquer le transcript pour éviter les appels trop longs
if len(transcript) > 4000:
transcript = transcript[-4000:]
# Essayer d'utiliser le LLM pour un vrai résumé
if _llm_manager is not None:
try:
prompt = (
"Tu es un assistant spécialisé dans la synthèse de conversations.\n"
"Résume les échanges suivants de manière concise et factuelle.\n"
"Extrais les sujets abordés, les décisions prises, et les informations importantes.\n"
"Le résumé ne doit PAS dépasser 500 caractères.\n\n"
f"CONVERSATION À RÉSUMER :\n{transcript}\n\n"
"RÉSUMÉ :"
)
payload = _llm_manager.build_payload(
prompt=prompt,
system_prompt="Tu es un assistant de synthèse. Sois concis et factuel.",
force_json=False
)
summary = await _llm_manager.call_llama(payload)
if summary and len(summary.strip()) > 10:
# Nettoyer le résumé
summary = summary.strip()
if len(summary) > 1500:
summary = summary[:1497] + "..."
return summary
except Exception as e:
logger.warning(f"Erreur résumé LLM, fallback extractif: {e}")
# Fallback : extraction de mots-clés et phrases clés
return _extractive_summary(messages)
def _extractive_summary(messages: List[Dict[str, Any]]) -> str:
"""Résumé extractif basé sur les mots-clés et phrases clés (fallback)."""
all_texts = []
for m in messages:
um = m.get("user_message", "")
@ -272,7 +327,7 @@ async def summarize_messages(messages: List[Dict[str, Any]]) -> str:
combined_text = " ".join(all_texts)
# Extraction simple de mots-clés (mots fréquents, >3 chars)
# Extraction de mots-clés (mots fréquents, >3 chars)
words = re.findall(r'\b\w{4,}\b', combined_text.lower())
word_freq = {}
for word in words:
@ -282,28 +337,25 @@ async def summarize_messages(messages: List[Dict[str, Any]]) -> str:
top_keywords = sorted(word_freq.items(), key=lambda x: x[1], reverse=True)[:10]
keywords_str = ", ".join([kw for kw, _ in top_keywords])
# Extraire phrases clés (premières phrases des messages importants)
# Extraire phrases clés
key_phrases = []
for m in messages:
um = m.get("user_message", "").strip()
bm = m.get("bot_message", "").strip()
if um:
sentences = re.split(r'[.!?]', um)[:1] # première phrase
sentences = re.split(r'[.!?]', um)[:1]
key_phrases.extend(sentences)
if bm:
sentences = re.split(r'[.!?]', bm)[:1]
key_phrases.extend(sentences)
phrases_str = " | ".join(key_phrases[:5]) # limiter à 5 phrases
phrases_str = " | ".join(key_phrases[:5])
# Construire le résumé
summary = f"Mots-clés: {keywords_str}\nPhrases clés: {phrases_str}"
# Tronquer si trop long
if len(summary) > 1500:
summary = summary[:1497] + "..."
await asyncio.sleep(0) # point d'await pour remplacer par un vrai appel
return summary
@ -444,12 +496,32 @@ def list_memory_files() -> List[str]:
return files
def delete_user_memory(user_id: int | str) -> None:
path = _user_filepath(user_id)
def delete_user_memory(user_id: int | str, guild_id: str | None = None) -> None:
"""Supprime la mémoire d'un utilisateur, optionnellement pour un guild spécifique."""
path = _user_filepath(user_id, guild_id)
try:
os.remove(path)
except FileNotFoundError:
pass
# Si aucun guild_id spécifique, supprimer aussi tous les fichiers de mémoire pour cet utilisateur
if guild_id is None:
_ensure_memory_dir()
user_str = str(user_id)
for root, dirs, files in os.walk(MEMORY_DIR):
for name in files:
if name == f"{user_str}.json" or name == f"{user_id}.json":
full_path = os.path.join(root, name)
if full_path != path: # Éviter double suppression
try:
os.remove(full_path)
except FileNotFoundError:
pass
# Nettoyer le cache
key_no_guild = f"_{user_id}" if guild_id is None else f"{guild_id}_{user_id}"
memory_cache.pop(key_no_guild, None)
_dirty.pop(key_no_guild, None)
# Fonction pour obtenir les métriques

16
brain/memory.py Normal file
View file

@ -0,0 +1,16 @@
"""User memory management - JSON/Redis with in-memory cache."""
# Renamed from memoire.py for consistency (English naming)
from .memoire import ( # noqa: F401
add_interaction,
build_context_for_model,
flush_all,
MEMORY_DIR,
set_llm_manager,
delete_user_memory,
purge_old_memories,
get_metrics,
_extractive_summary,
load_user_memory_async,
save_user_memory_async,
)

View file

@ -3,7 +3,7 @@ import datetime
import logging
from typing import Optional
logger = logging.getLogger('Superviseur')
logger = logging.getLogger('Beta')
DB_PATH = 'data/mod.db'