feat: chat unifié, GestureCatalog, Copilot, Léa UI, extraction données, vérification replay
Refonte majeure du système Agent Chat et ajout de nombreux modules : - Chat unifié : suppression du dual Workflows/Agent Libre, tout passe par /api/chat avec résolution en 3 niveaux (workflow → geste → "montre-moi") - GestureCatalog : 38 raccourcis clavier universels Windows avec matching sémantique, substitution automatique dans les replays, et endpoint /api/gestures - Mode Copilot : exécution pas-à-pas des workflows avec validation humaine via WebSocket (approve/skip/abort) avant chaque action - Léa UI (agent_v0/lea_ui/) : interface PyQt5 pour Windows avec overlay transparent pour feedback visuel pendant le replay - Data Extraction (core/extraction/) : moteur d'extraction visuelle de données (OCR + VLM → SQLite), avec schémas YAML et export CSV/Excel - ReplayVerifier (agent_v0/server_v1/) : vérification post-action par comparaison de screenshots, avec logique de retry (max 3) - IntentParser durci : meilleur fallback regex, type GREETING, patterns améliorés - Dashboard : nouvelles pages gestures, streaming, extractions - Tests : 63 tests GestureCatalog, 47 tests extraction, corrections tests existants - Dépréciation : /api/agent/plan et /api/agent/execute retournent HTTP 410, suppression du code hardcodé _plan_to_replay_actions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -349,18 +349,22 @@ class TestMemoryManager:
|
||||
|
||||
def test_stats(self):
|
||||
"""Test statistiques du gestionnaire."""
|
||||
# Compter les ressources déjà enregistrées (ex: gpu_resource_manager)
|
||||
baseline = len(self.manager.resource_registry)
|
||||
|
||||
# Enregistrer quelques ressources
|
||||
for i in range(3):
|
||||
self.manager.register_resource(f"resource{i}", {"data": i})
|
||||
|
||||
|
||||
stats = self.manager.get_stats()
|
||||
|
||||
|
||||
assert stats['max_memory_mb'] == 100
|
||||
assert stats['registered_resources'] == 3
|
||||
assert stats['registered_resources'] == baseline + 3
|
||||
assert stats['cleanup_threshold'] == 0.8
|
||||
assert stats['check_interval'] == 60.0 # Corrigé: était 1.0
|
||||
assert not stats['running'] or not self.manager.enable_monitoring # Monitoring désactivé
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_gpu_resource_management(self):
|
||||
"""Test gestion des ressources GPU."""
|
||||
# Créer un manager avec gestion GPU activée
|
||||
@@ -369,20 +373,20 @@ class TestMemoryManager:
|
||||
enable_monitoring=False,
|
||||
enable_gpu_management=True
|
||||
)
|
||||
|
||||
|
||||
try:
|
||||
# Enregistrer une ressource GPU
|
||||
def cleanup_gpu_model(resource_id):
|
||||
# Simuler le nettoyage d'un modèle GPU
|
||||
pass
|
||||
|
||||
|
||||
manager.register_gpu_resource(
|
||||
"test_model",
|
||||
"model",
|
||||
cleanup_gpu_model,
|
||||
{"size_mb": 500}
|
||||
)
|
||||
|
||||
|
||||
# Vérifier l'enregistrement
|
||||
assert "test_model" in manager._gpu_resources
|
||||
assert "gpu_test_model" in manager.resource_registry
|
||||
@@ -443,7 +447,8 @@ class TestMemoryManager:
|
||||
assert len(self.manager.resource_registry) == 0
|
||||
assert len(self.manager.cleanup_functions) == 0
|
||||
|
||||
def test_gpu_resource_management(self):
|
||||
@pytest.mark.slow
|
||||
def test_gpu_resource_management_global(self):
|
||||
"""Test gestion des ressources GPU."""
|
||||
# Créer un manager avec gestion GPU activée
|
||||
manager = MemoryManager(
|
||||
@@ -451,20 +456,20 @@ class TestMemoryManager:
|
||||
enable_monitoring=False,
|
||||
enable_gpu_management=True
|
||||
)
|
||||
|
||||
|
||||
try:
|
||||
# Enregistrer une ressource GPU
|
||||
def cleanup_gpu_model(resource_id):
|
||||
# Simuler le nettoyage d'un modèle GPU
|
||||
pass
|
||||
|
||||
|
||||
manager.register_gpu_resource(
|
||||
"test_model",
|
||||
"model",
|
||||
cleanup_gpu_model,
|
||||
{"size_mb": 500}
|
||||
)
|
||||
|
||||
|
||||
# Vérifier l'enregistrement
|
||||
if manager.enable_gpu_management: # Peut être désactivé si pas de GPU
|
||||
assert "test_model" in manager._gpu_resources
|
||||
@@ -520,20 +525,20 @@ class TestGlobalMemoryManager:
|
||||
|
||||
def test_singleton_behavior(self):
|
||||
"""Test comportement singleton."""
|
||||
manager1 = get_memory_manager()
|
||||
manager2 = get_memory_manager()
|
||||
|
||||
manager1 = get_memory_manager(enable_monitoring=False, enable_gpu_management=False)
|
||||
manager2 = get_memory_manager(enable_monitoring=False, enable_gpu_management=False)
|
||||
|
||||
assert manager1 is manager2
|
||||
|
||||
|
||||
def test_shutdown_global(self):
|
||||
"""Test arrêt du gestionnaire global."""
|
||||
manager = get_memory_manager()
|
||||
manager = get_memory_manager(enable_monitoring=False, enable_gpu_management=False)
|
||||
assert manager is not None
|
||||
|
||||
|
||||
shutdown_memory_manager()
|
||||
|
||||
|
||||
# Nouveau gestionnaire après shutdown
|
||||
new_manager = get_memory_manager()
|
||||
new_manager = get_memory_manager(enable_monitoring=False, enable_gpu_management=False)
|
||||
assert new_manager is not manager
|
||||
|
||||
|
||||
@@ -547,8 +552,8 @@ class TestIntegration:
|
||||
max_memory_mb=2.0,
|
||||
enable_monitoring=False
|
||||
)
|
||||
# Désactiver le monitoring pour le gestionnaire global aussi
|
||||
self.manager = get_memory_manager(enable_monitoring=False)
|
||||
# Désactiver le monitoring et GPU pour les tests
|
||||
self.manager = get_memory_manager(enable_monitoring=False, enable_gpu_management=False)
|
||||
|
||||
def teardown_method(self):
|
||||
"""Cleanup après chaque test."""
|
||||
|
||||
Reference in New Issue
Block a user