feat: Léa personnalité humaine + fichiers + fix doublon menu
- Small talk : café, merci, ça va, qui es-tu → réponses chaleureuses - Bouton 📎 dans le chat pour envoyer des fichiers - Polices 13-15pt, fenêtre 600x800 - Fix doublon "Discuter avec Léa" dans le systray - IntentType.SMALL_TALK avec 7 catégories Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,7 @@ class IntentType(Enum):
|
||||
DENY = "deny" # Refuser une action
|
||||
CLARIFY = "clarify" # Demander une clarification
|
||||
DATA_IMPORT = "data_import" # Importer des données (Excel, CSV)
|
||||
SMALL_TALK = "small_talk" # Conversation informelle (merci, café, ça va...)
|
||||
UNKNOWN = "unknown" # Intention non reconnue
|
||||
|
||||
|
||||
@@ -129,6 +130,24 @@ class IntentParser:
|
||||
r"(?:que\s+sai[st]-(?:tu|vous)\s+faire)",
|
||||
r"mes\s+tâches?",
|
||||
],
|
||||
# SMALL_TALK doit être AVANT QUERY pour que "qui es-tu" ne soit pas
|
||||
# capturé par le pattern générique "qui + ..." de QUERY
|
||||
IntentType.SMALL_TALK: [
|
||||
# Remerciements
|
||||
r"^(?:merci|thanks?|thx|super|génial|parfait|cool|nickel|impec|impeccable|excellent|formidable)(?:\s.*)?$",
|
||||
# Adieux
|
||||
r"^(?:au revoir|à plus|bye|bonne nuit|à bientôt|à demain|ciao|tchao|tchuss|adieu)(?:\s.*)?$",
|
||||
# Compliments
|
||||
r"^(?:bien joué|bravo|top|chapeau|impressionnant|pas mal|bien fait|beau travail|good job|nice|trop bien|magnifique)(?:\s.*)?$",
|
||||
# Mécontentement
|
||||
r"^(?:c'est nul|nul|pas bien|pas top|pas ouf|bof|mauvais|moche|horrible|catastrophe|c'est pas bon|ça craint|erreur|bug|naze|pourri)(?:\s.*)?$",
|
||||
# Humour / café
|
||||
r"(?:un café|café|coffee|fais-moi rire|blague|raconte.+blague|drôle|rigol[eo]|mdr|lol|haha|ptdr|xd|😂|🤣)",
|
||||
# Identité — qui es-tu ?
|
||||
r"(?:qui es[- ]tu|t'es qui|comment tu t'appelles|c'est quoi ton (?:nom|prénom)|t'es quoi|vous êtes qui|tu es quoi|tu t'appelles comment)",
|
||||
# Sentiments — ça va ?
|
||||
r"(?:ça va|comment (?:ça |tu |vous )?va[st]?|comment allez[- ]vous|tu vas bien|la forme|en forme)",
|
||||
],
|
||||
IntentType.QUERY: [
|
||||
# Questions directes avec mots interrogatifs
|
||||
r"(?:comment|pourquoi|quand|où|qui)\s+(.+)\??",
|
||||
@@ -446,8 +465,8 @@ class IntentParser:
|
||||
# Convertir en minuscules
|
||||
normalized = query.lower()
|
||||
|
||||
# Supprimer la ponctuation excessive
|
||||
normalized = re.sub(r'[!.]+$', '', normalized)
|
||||
# Supprimer la ponctuation finale
|
||||
normalized = re.sub(r'[!.?]+$', '', normalized)
|
||||
|
||||
# Normaliser les espaces
|
||||
normalized = re.sub(r'\s+', ' ', normalized).strip()
|
||||
@@ -598,6 +617,7 @@ INTENTIONS POSSIBLES:
|
||||
- greeting: l'utilisateur dit bonjour/salut/hello
|
||||
- confirm: l'utilisateur confirme (oui, ok, go)
|
||||
- deny: l'utilisateur refuse (non, annule)
|
||||
- small_talk: conversation informelle (merci, café, ça va, qui es-tu, bravo, c'est nul)
|
||||
- unknown: impossible à déterminer
|
||||
|
||||
Réponds UNIQUEMENT en JSON valide (pas de texte avant/après):
|
||||
@@ -733,6 +753,15 @@ if __name__ == "__main__":
|
||||
"oui",
|
||||
"annule",
|
||||
"statut",
|
||||
# SMALL_TALK — conversation informelle
|
||||
"merci",
|
||||
"un café",
|
||||
"ça va ?",
|
||||
"qui es-tu ?",
|
||||
"c'est nul",
|
||||
"bravo",
|
||||
"au revoir",
|
||||
"t'es qui",
|
||||
# Fallback — ne doit PAS être EXECUTE
|
||||
"blah blah test",
|
||||
]
|
||||
|
||||
@@ -14,6 +14,7 @@ Auteur: Dom - Janvier 2026
|
||||
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import Dict, Any, List, Optional
|
||||
@@ -220,11 +221,48 @@ class ResponseGenerator:
|
||||
"Fichier **{filename}** reçu ! Je l'analyse...",
|
||||
],
|
||||
},
|
||||
IntentType.SMALL_TALK: {
|
||||
"thanks": [
|
||||
"Avec plaisir ! N'hésitez pas si vous avez besoin d'autre chose 😊",
|
||||
"De rien ! Je suis là pour ça 👍",
|
||||
"Merci à vous ! Toujours prête à aider.",
|
||||
],
|
||||
"farewell": [
|
||||
"À bientôt ! Je reste dans la barre des tâches si vous avez besoin 😊",
|
||||
"Bonne continuation ! N'hésitez pas à revenir.",
|
||||
"À plus tard ! Je ne bouge pas 👋",
|
||||
],
|
||||
"compliment": [
|
||||
"Merci, c'est gentil ! J'apprends un peu plus chaque jour grâce à vous 😊",
|
||||
"Oh merci ! Ça me fait plaisir 😄",
|
||||
"C'est vous qui êtes formidable ! Merci pour votre confiance.",
|
||||
],
|
||||
"complaint": [
|
||||
"Je suis désolée... Dites-moi ce qui ne va pas, je vais essayer de m'améliorer.",
|
||||
"Oups... N'hésitez pas à me dire ce qui n'a pas marché, je ferai mieux la prochaine fois.",
|
||||
"Pardon pour le désagrément. Comment puis-je corriger ça ?",
|
||||
],
|
||||
"humor": [
|
||||
"Pas encore de machine à café intégrée... mais j'y travaille ! 😄 En attendant, je peux vous aider avec vos tâches ?",
|
||||
"Ha ha ! Si seulement je pouvais... 😄 En attendant, dites-moi comment je peux vous aider !",
|
||||
"L'humour c'est important au travail ! 😄 Bon, on s'y met ?",
|
||||
],
|
||||
"identity": [
|
||||
"Je suis Léa, votre assistante ! Je peux apprendre vos tâches répétitives et les refaire à votre place 😊",
|
||||
"Moi c'est Léa ! Je suis là pour automatiser tout ce qui vous ennuie au quotidien.",
|
||||
"Je m'appelle Léa. Mon job : observer, apprendre, et vous faire gagner du temps 👍",
|
||||
],
|
||||
"feelings": [
|
||||
"Très bien, merci de demander ! Et vous ? Prête à travailler si vous avez besoin 😊",
|
||||
"En pleine forme ! Et vous, comment ça va ? Dites-moi si je peux aider.",
|
||||
"Ça va super bien ! Toujours motivée pour vous donner un coup de main 💪",
|
||||
],
|
||||
},
|
||||
IntentType.UNKNOWN: {
|
||||
"default": [
|
||||
"Je n'ai pas bien compris. Pouvez-vous reformuler ?",
|
||||
"Je n'ai pas bien compris. Vous pouvez me demander de l'aide avec le bouton ❓",
|
||||
"Désolée, je ne comprends pas. Tapez « aide » pour voir ce que je sais faire.",
|
||||
"Hmm, je n'ai pas saisi votre demande. Pouvez-vous préciser ?"
|
||||
"Hmm, je n'ai pas saisi votre demande. Essayez de reformuler ou tapez « aide »."
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -773,6 +811,75 @@ class ResponseGenerator:
|
||||
metadata=result,
|
||||
)
|
||||
|
||||
def _handle_small_talk(
|
||||
self,
|
||||
intent: ParsedIntent,
|
||||
context: Dict[str, Any],
|
||||
result: Dict[str, Any]
|
||||
) -> GeneratedResponse:
|
||||
"""Handler pour la conversation informelle (merci, café, ça va, etc.)."""
|
||||
templates = self.RESPONSE_TEMPLATES[IntentType.SMALL_TALK]
|
||||
query = intent.raw_query.lower().strip()
|
||||
|
||||
# Déterminer la sous-catégorie de small talk
|
||||
category = self._classify_small_talk(query)
|
||||
category_templates = templates.get(category, templates["humor"])
|
||||
message = random.choice(category_templates)
|
||||
|
||||
return GeneratedResponse(
|
||||
message=message,
|
||||
suggestions=[],
|
||||
action_required=False,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _classify_small_talk(query: str) -> str:
|
||||
"""Classifier le type de small talk à partir de la requête brute."""
|
||||
# Remerciements
|
||||
if re.search(
|
||||
r"\b(?:merci|thanks?|thx|super|génial|parfait|cool|nickel|impec|impeccable|excellent|formidable)\b",
|
||||
query
|
||||
):
|
||||
return "thanks"
|
||||
|
||||
# Adieux
|
||||
if re.search(
|
||||
r"\b(?:au revoir|à plus|bye|bonne nuit|à bientôt|à demain|ciao|tchao|tchuss|adieu)\b",
|
||||
query
|
||||
):
|
||||
return "farewell"
|
||||
|
||||
# Identité
|
||||
if re.search(
|
||||
r"(?:qui es[- ]tu|t'es qui|comment tu t'appelles|c'est quoi ton (?:nom|prénom)|t'es quoi|vous êtes qui|tu t'appelles comment)",
|
||||
query
|
||||
):
|
||||
return "identity"
|
||||
|
||||
# Sentiments
|
||||
if re.search(
|
||||
r"(?:ça va|comment (?:ça |tu |vous )?va[st]?|comment allez[- ]vous|tu vas bien|la forme|en forme)",
|
||||
query
|
||||
):
|
||||
return "feelings"
|
||||
|
||||
# Mécontentement
|
||||
if re.search(
|
||||
r"\b(?:nul|pas bien|pas top|pas ouf|bof|mauvais|moche|horrible|catastrophe|ça craint|erreur|bug|naze|pourri)\b",
|
||||
query
|
||||
):
|
||||
return "complaint"
|
||||
|
||||
# Compliments
|
||||
if re.search(
|
||||
r"\b(?:bien joué|bravo|top|chapeau|impressionnant|pas mal|bien fait|beau travail|good job|nice|trop bien|magnifique)\b",
|
||||
query
|
||||
):
|
||||
return "compliment"
|
||||
|
||||
# Humour / café (fallback small_talk)
|
||||
return "humor"
|
||||
|
||||
def _handle_unknown(
|
||||
self,
|
||||
intent: ParsedIntent,
|
||||
|
||||
Reference in New Issue
Block a user