385 lines
13 KiB
Python
385 lines
13 KiB
Python
"""
|
|
HumanLogger - Générateur de messages lisibles pour l'interface utilisateur
|
|
Transforme les événements techniques en messages simples et contextuels.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import Optional, Dict, Any
|
|
|
|
|
|
class HumanLogger:
|
|
"""
|
|
Logger qui génère des messages simples et lisibles pour l'utilisateur.
|
|
|
|
Transforme les événements techniques du système en messages compréhensibles
|
|
avec emojis et contexte approprié.
|
|
|
|
Attributes:
|
|
first_time_events: Dictionnaire pour tracker les événements "première fois"
|
|
"""
|
|
|
|
def __init__(self):
|
|
"""Initialise le HumanLogger avec tracking des premières fois."""
|
|
self.first_time_events: Dict[str, bool] = {
|
|
"workflow_detected": False,
|
|
"mode_change": False,
|
|
"pattern_detected": False,
|
|
"finetuning_started": False
|
|
}
|
|
|
|
def log_observation(self, action_type: str, window: str) -> str:
|
|
"""
|
|
Génère un message pour une action observée.
|
|
|
|
Args:
|
|
action_type: Type d'action (click, type, scroll, etc.)
|
|
window: Nom de la fenêtre où l'action a eu lieu
|
|
|
|
Returns:
|
|
Message formaté pour l'utilisateur
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_observation("click", "Calculator")
|
|
"👀 J'observe vos actions dans Calculator"
|
|
"""
|
|
# Message simple et discret
|
|
return f"👀 J'observe vos actions dans {window}"
|
|
|
|
def log_pattern_detected(self, repetitions: int, task_name: str) -> str:
|
|
"""
|
|
Génère un message pour un pattern détecté.
|
|
|
|
Args:
|
|
repetitions: Nombre de répétitions détectées
|
|
task_name: Nom de la tâche répétée
|
|
|
|
Returns:
|
|
Message formaté avec contexte si première fois
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_pattern_detected(3, "Calculer 9/9")
|
|
"🎯 Tiens ! Vous avez fait 3 fois la même chose"
|
|
"""
|
|
# Message d'excitation pour pattern détecté
|
|
message = f"🎯 Tiens ! Vous avez fait {repetitions} fois la même chose"
|
|
|
|
# Ajouter contexte si première fois
|
|
if not self.first_time_events["pattern_detected"]:
|
|
self.first_time_events["pattern_detected"] = True
|
|
message += " (Je commence à apprendre vos habitudes)"
|
|
|
|
return message
|
|
|
|
def log_workflow_learned(self, task_name: str, count: int) -> str:
|
|
"""
|
|
Génère un message pour un workflow appris.
|
|
|
|
Args:
|
|
task_name: Nom du workflow appris
|
|
count: Nombre d'observations utilisées pour l'apprentissage
|
|
|
|
Returns:
|
|
Message formaté avec explication si première fois
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_workflow_learned("Ouvrir facture", 5)
|
|
"📚 J'apprends: Ouvrir facture (5 observations)"
|
|
"""
|
|
message = f"📚 J'apprends: {task_name} ({count} observations)"
|
|
|
|
# Ajouter explication si première workflow
|
|
if not self.first_time_events["workflow_detected"]:
|
|
self.first_time_events["workflow_detected"] = True
|
|
message += "\n💡 Un workflow est une séquence d'actions que vous répétez"
|
|
|
|
return message
|
|
|
|
def log_mode_change(self, old_mode: str, new_mode: str, reason: Optional[str] = None) -> str:
|
|
"""
|
|
Génère un message pour un changement de mode.
|
|
|
|
Args:
|
|
old_mode: Mode précédent (shadow, assist, auto)
|
|
new_mode: Nouveau mode (shadow, assist, auto)
|
|
reason: Raison du changement (optionnel)
|
|
|
|
Returns:
|
|
Message formaté avec explication du nouveau mode si première fois
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_mode_change("shadow", "assist")
|
|
"✅ Mode Suggestions activé"
|
|
"""
|
|
# Mapper les modes techniques vers des noms lisibles
|
|
mode_names = {
|
|
"shadow": "Observation",
|
|
"assist": "Suggestions",
|
|
"copilot": "Copilote",
|
|
"auto": "Autonome"
|
|
}
|
|
|
|
new_mode_name = mode_names.get(new_mode, new_mode)
|
|
message = f"✅ Mode {new_mode_name} activé"
|
|
|
|
# Ajouter explication si premier changement de mode
|
|
if not self.first_time_events["mode_change"]:
|
|
self.first_time_events["mode_change"] = True
|
|
|
|
# Expliquer ce que fait le nouveau mode
|
|
mode_explanations = {
|
|
"assist": "\n💡 Je vais maintenant vous suggérer des actions",
|
|
"copilot": "\n💡 Je peux maintenant exécuter avec votre validation",
|
|
"auto": "\n💡 Je peux maintenant agir de manière autonome"
|
|
}
|
|
|
|
if new_mode in mode_explanations:
|
|
message += mode_explanations[new_mode]
|
|
|
|
return message
|
|
|
|
def log_finetuning_started(self, num_examples: int) -> str:
|
|
"""
|
|
Génère un message pour le début du fine-tuning.
|
|
|
|
Args:
|
|
num_examples: Nombre d'exemples utilisés pour le fine-tuning
|
|
|
|
Returns:
|
|
Message formaté avec explication si première fois
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_finetuning_started(10)
|
|
"🧠 Amélioration du modèle (10 exemples)..."
|
|
"""
|
|
message = f"🧠 Amélioration du modèle ({num_examples} exemples)..."
|
|
|
|
# Ajouter explication si premier fine-tuning
|
|
if not self.first_time_events["finetuning_started"]:
|
|
self.first_time_events["finetuning_started"] = True
|
|
message += "\n💡 J'améliore ma compréhension de vos actions"
|
|
|
|
return message
|
|
|
|
def log_finetuning_completed(self, duration: float) -> str:
|
|
"""
|
|
Génère un message pour la fin du fine-tuning.
|
|
|
|
Args:
|
|
duration: Durée du fine-tuning en secondes
|
|
|
|
Returns:
|
|
Message formaté de succès
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_finetuning_completed(2.5)
|
|
"✅ Modèle amélioré (en 2.5s)"
|
|
"""
|
|
return f"✅ Modèle amélioré (en {duration:.1f}s)"
|
|
|
|
def log_error(self, error_type: str, context: Optional[str] = None) -> str:
|
|
"""
|
|
Génère un message d'erreur compréhensible avec suggestion d'action.
|
|
|
|
Args:
|
|
error_type: Type d'erreur (connection, permission, not_found, etc.)
|
|
context: Contexte additionnel (optionnel)
|
|
|
|
Returns:
|
|
Message d'erreur avec suggestion corrective
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_error("connection", "Calculator")
|
|
"⚠️ Impossible de se connecter à Calculator"
|
|
"""
|
|
# Messages d'erreur avec suggestions
|
|
error_messages = {
|
|
"connection": "⚠️ Impossible de se connecter",
|
|
"permission": "⚠️ Permission refusée",
|
|
"not_found": "⚠️ Élément introuvable",
|
|
"timeout": "⚠️ Délai d'attente dépassé",
|
|
"whitelist": "⚠️ Application non autorisée",
|
|
"unknown": "⚠️ Une erreur est survenue"
|
|
}
|
|
|
|
message = error_messages.get(error_type, error_messages["unknown"])
|
|
|
|
# Ajouter contexte si fourni
|
|
if context:
|
|
message += f" - {context}"
|
|
|
|
# Ajouter suggestion corrective selon le type d'erreur
|
|
suggestions = {
|
|
"connection": "\n💡 Vérifiez que l'application est ouverte",
|
|
"permission": "\n💡 Vérifiez les permissions de l'application",
|
|
"not_found": "\n💡 L'interface a peut-être changé",
|
|
"timeout": "\n💡 L'application est peut-être trop lente",
|
|
"whitelist": "\n💡 Ajoutez l'application à la liste autorisée"
|
|
}
|
|
|
|
if error_type in suggestions:
|
|
message += suggestions[error_type]
|
|
|
|
return message
|
|
|
|
def log_idle(self) -> str:
|
|
"""
|
|
Génère un message d'encouragement après inactivité.
|
|
|
|
Returns:
|
|
Message d'encouragement
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_idle()
|
|
"💤 En attente de vos actions..."
|
|
"""
|
|
return "💤 En attente de vos actions..."
|
|
|
|
def log_stats_update(self, actions_count: int, patterns_count: int, workflows_count: int) -> str:
|
|
"""
|
|
Génère un message de mise à jour des statistiques.
|
|
|
|
Args:
|
|
actions_count: Nombre d'actions observées
|
|
patterns_count: Nombre de patterns détectés
|
|
workflows_count: Nombre de workflows appris
|
|
|
|
Returns:
|
|
Message formaté avec statistiques
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_stats_update(12, 2, 1)
|
|
"📊 12 actions • 2 patterns • 1 workflow"
|
|
"""
|
|
return f"📊 {actions_count} actions • {patterns_count} patterns • {workflows_count} workflow{'s' if workflows_count > 1 else ''}"
|
|
|
|
def log_suggestion_ready(self, task_name: str) -> str:
|
|
"""
|
|
Génère un message indiquant qu'une suggestion est prête.
|
|
|
|
Args:
|
|
task_name: Nom de la tâche pour laquelle une suggestion est disponible
|
|
|
|
Returns:
|
|
Message formaté
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_suggestion_ready("Ouvrir facture")
|
|
"💡 Prêt à suggérer: Ouvrir facture"
|
|
"""
|
|
return f"💡 Prêt à suggérer: {task_name}"
|
|
|
|
def log_collecting_examples(self, current: int, target: int) -> str:
|
|
"""
|
|
Génère un message pour la collecte d'exemples de fine-tuning.
|
|
|
|
Args:
|
|
current: Nombre d'exemples collectés
|
|
target: Nombre d'exemples cibles
|
|
|
|
Returns:
|
|
Message formaté avec progression
|
|
|
|
Examples:
|
|
>>> logger = HumanLogger()
|
|
>>> logger.log_collecting_examples(8, 10)
|
|
"🧠 Collecte d'exemples: 8/10"
|
|
"""
|
|
return f"🧠 Collecte d'exemples: {current}/{target}"
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Tests du HumanLogger
|
|
print("Test du HumanLogger")
|
|
print("=" * 50)
|
|
|
|
logger = HumanLogger()
|
|
|
|
# Test 1: Observation
|
|
print("\n1. Test log_observation:")
|
|
msg = logger.log_observation("click", "Calculator")
|
|
print(f" {msg}")
|
|
|
|
# Test 2: Pattern détecté (première fois)
|
|
print("\n2. Test log_pattern_detected (première fois):")
|
|
msg = logger.log_pattern_detected(3, "Calculer 9/9")
|
|
print(f" {msg}")
|
|
|
|
# Test 3: Pattern détecté (deuxième fois)
|
|
print("\n3. Test log_pattern_detected (deuxième fois):")
|
|
msg = logger.log_pattern_detected(4, "Ouvrir fichier")
|
|
print(f" {msg}")
|
|
|
|
# Test 4: Workflow appris (première fois)
|
|
print("\n4. Test log_workflow_learned (première fois):")
|
|
msg = logger.log_workflow_learned("Ouvrir facture", 5)
|
|
print(f" {msg}")
|
|
|
|
# Test 5: Workflow appris (deuxième fois)
|
|
print("\n5. Test log_workflow_learned (deuxième fois):")
|
|
msg = logger.log_workflow_learned("Calculer total", 3)
|
|
print(f" {msg}")
|
|
|
|
# Test 6: Changement de mode (première fois)
|
|
print("\n6. Test log_mode_change (première fois):")
|
|
msg = logger.log_mode_change("shadow", "assist")
|
|
print(f" {msg}")
|
|
|
|
# Test 7: Changement de mode (deuxième fois)
|
|
print("\n7. Test log_mode_change (deuxième fois):")
|
|
msg = logger.log_mode_change("assist", "auto")
|
|
print(f" {msg}")
|
|
|
|
# Test 8: Fine-tuning démarré (première fois)
|
|
print("\n8. Test log_finetuning_started (première fois):")
|
|
msg = logger.log_finetuning_started(10)
|
|
print(f" {msg}")
|
|
|
|
# Test 9: Fine-tuning démarré (deuxième fois)
|
|
print("\n9. Test log_finetuning_started (deuxième fois):")
|
|
msg = logger.log_finetuning_started(15)
|
|
print(f" {msg}")
|
|
|
|
# Test 10: Fine-tuning terminé
|
|
print("\n10. Test log_finetuning_completed:")
|
|
msg = logger.log_finetuning_completed(2.5)
|
|
print(f" {msg}")
|
|
|
|
# Test 11: Erreurs avec suggestions
|
|
print("\n11. Test log_error:")
|
|
for error_type in ["connection", "permission", "not_found", "timeout", "whitelist"]:
|
|
msg = logger.log_error(error_type, "Calculator")
|
|
print(f" {msg}")
|
|
print()
|
|
|
|
# Test 12: Idle
|
|
print("\n12. Test log_idle:")
|
|
msg = logger.log_idle()
|
|
print(f" {msg}")
|
|
|
|
# Test 13: Stats update
|
|
print("\n13. Test log_stats_update:")
|
|
msg = logger.log_stats_update(12, 2, 1)
|
|
print(f" {msg}")
|
|
|
|
# Test 14: Suggestion ready
|
|
print("\n14. Test log_suggestion_ready:")
|
|
msg = logger.log_suggestion_ready("Ouvrir facture")
|
|
print(f" {msg}")
|
|
|
|
# Test 15: Collecting examples
|
|
print("\n15. Test log_collecting_examples:")
|
|
msg = logger.log_collecting_examples(8, 10)
|
|
print(f" {msg}")
|
|
|
|
print("\n✓ Tous les tests manuels terminés!")
|