chore: nettoyage .gitignore - retrait venv, __pycache__, .env, data, logs, modèles du tracking
This commit is contained in:
parent
7333a22bcd
commit
604a5affe0
9231 changed files with 1244 additions and 1601201 deletions
100
brain/memoire.py
100
brain/memoire.py
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue