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:
@@ -73,9 +73,16 @@ class ResponseGenerator:
|
||||
"Le workflow '{workflow}' a échoué: {error}"
|
||||
],
|
||||
"not_found": [
|
||||
"Je n'ai pas trouvé de workflow correspondant à '{query}'.",
|
||||
"Aucun workflow ne correspond à '{query}'. Voulez-vous voir la liste ?",
|
||||
"'{query}' ne correspond à aucun workflow connu."
|
||||
"Je ne sais pas encore faire '{query}'. Montre-moi comment faire et je l'apprendrai !",
|
||||
"'{query}' m'est inconnu pour l'instant. Tu peux me montrer en enregistrant un workflow.",
|
||||
"Je ne connais pas '{query}'. Montre-moi et je m'en souviendrai !"
|
||||
],
|
||||
"gesture": [
|
||||
"{gesture_name} ({gesture_keys}) envoyé !",
|
||||
"Raccourci {gesture_name} ({gesture_keys}) exécuté.",
|
||||
],
|
||||
"copilot": [
|
||||
"Mode pas-à-pas activé pour '{workflow}'. Validez chaque étape.",
|
||||
]
|
||||
},
|
||||
IntentType.LIST: {
|
||||
@@ -108,6 +115,13 @@ class ResponseGenerator:
|
||||
"Tapez votre commande en langage naturel !",
|
||||
]
|
||||
},
|
||||
IntentType.GREETING: {
|
||||
"default": [
|
||||
"Bonjour ! Je suis votre assistant RPA. Comment puis-je vous aider ?",
|
||||
"Salut ! Que puis-je faire pour vous ?",
|
||||
"Bonjour ! Tapez une commande ou 'aide' pour voir ce que je peux faire.",
|
||||
]
|
||||
},
|
||||
IntentType.STATUS: {
|
||||
"running": [
|
||||
"Exécution en cours : '{workflow}'\nProgression : {progress}%\n{message}",
|
||||
@@ -355,7 +369,21 @@ class ResponseGenerator:
|
||||
"""Handler pour les intentions d'exécution."""
|
||||
templates = self.RESPONSE_TEMPLATES[IntentType.EXECUTE]
|
||||
|
||||
if result.get("success"):
|
||||
if result.get("gesture"):
|
||||
# Geste primitif (raccourci clavier)
|
||||
template = random.choice(templates["gesture"])
|
||||
message = template.format(
|
||||
gesture_name=result.get("gesture_name", "?"),
|
||||
gesture_keys=result.get("gesture_keys", "?"),
|
||||
)
|
||||
suggestions = self.CONTEXTUAL_SUGGESTIONS["after_execute"]
|
||||
|
||||
elif result.get("mode") == "copilot":
|
||||
template = random.choice(templates["copilot"])
|
||||
message = template.format(workflow=result.get("workflow", "?"))
|
||||
suggestions = ["approuver", "passer", "annuler"]
|
||||
|
||||
elif result.get("success"):
|
||||
template = random.choice(templates["success"])
|
||||
workflow = result.get("workflow", intent.workflow_hint or "inconnu")
|
||||
details = ""
|
||||
@@ -369,8 +397,9 @@ class ResponseGenerator:
|
||||
|
||||
elif result.get("not_found"):
|
||||
template = random.choice(templates["not_found"])
|
||||
message = template.format(query=intent.raw_query)
|
||||
suggestions = self.CONTEXTUAL_SUGGESTIONS["after_error"]
|
||||
query = result.get("query", intent.raw_query)
|
||||
message = template.format(query=query)
|
||||
suggestions = ["lister les workflows", "aide", "enregistrer un workflow"]
|
||||
|
||||
else:
|
||||
template = random.choice(templates["error"])
|
||||
@@ -426,6 +455,22 @@ class ResponseGenerator:
|
||||
action_required=False
|
||||
)
|
||||
|
||||
def _handle_greeting(
|
||||
self,
|
||||
intent: ParsedIntent,
|
||||
context: Dict[str, Any],
|
||||
result: Dict[str, Any]
|
||||
) -> GeneratedResponse:
|
||||
"""Handler pour les salutations."""
|
||||
templates = self.RESPONSE_TEMPLATES[IntentType.GREETING]
|
||||
message = random.choice(templates["default"])
|
||||
|
||||
return GeneratedResponse(
|
||||
message=message,
|
||||
suggestions=self.CONTEXTUAL_SUGGESTIONS["idle"],
|
||||
action_required=False
|
||||
)
|
||||
|
||||
def _handle_status(
|
||||
self,
|
||||
intent: ParsedIntent,
|
||||
|
||||
Reference in New Issue
Block a user