Files
rpa_vision_v3/examples/demo_execution_result_enhanced.py
Dom a27b74cf22 v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- Frontend v4 accessible sur réseau local (192.168.1.40)
- Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard)
- Ollama GPU fonctionnel
- Self-healing interactif
- Dashboard confiance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 11:23:51 +01:00

435 lines
18 KiB
Python

#!/usr/bin/env python3
"""
Démonstration de WorkflowExecutionResult avec métadonnées complètes
Ce script démontre l'utilisation du modèle WorkflowExecutionResult amélioré
avec toutes les métadonnées requises : correlation_id, performance_metrics, recovery_applied.
Auteur: Dom, Alice Kiro - 20 décembre 2024
"""
import sys
import json
import uuid
from datetime import datetime
from pathlib import Path
# Ajouter le répertoire racine au path
sys.path.insert(0, str(Path(__file__).parent.parent))
from core.models.execution_result import (
WorkflowExecutionResult,
PerformanceMetrics,
RecoveryInfo,
StepExecutionStatus
)
def demo_successful_execution():
"""Démonstration d'une exécution réussie avec métadonnées complètes"""
print("=== Démonstration : Exécution Réussie ===")
# Simuler une exécution réussie
execution_id = str(uuid.uuid4())
correlation_id = str(uuid.uuid4())
# Métriques de performance détaillées
performance_metrics = PerformanceMetrics(
total_execution_time_ms=185.5,
state_matching_time_ms=42.3,
target_resolution_time_ms=38.7,
action_execution_time_ms=89.2,
error_handling_time_ms=15.3
)
# Action exécutée avec détails
action_executed = {
"edge_id": "login_form_to_dashboard",
"type": "click",
"target": "login_button",
"parameters": {
"wait_before": 500,
"wait_after": 1000,
"double_click": False
},
"execution_status": "SUCCESS",
"execution_message": "Button clicked successfully",
"execution_duration_ms": 89.2
}
# Résultat de matching
match_result = {
"node_id": "login_form_node",
"workflow_id": "user_authentication_flow",
"confidence": 0.94,
"state_embedding_id": "embedding_abc123",
"match_method": "hierarchical_semantic"
}
# Créer le résultat de succès
result = WorkflowExecutionResult.success(
execution_id=execution_id,
workflow_id="user_authentication_flow",
current_node="login_form_node",
target_node="dashboard_node",
action_executed=action_executed,
match_result=match_result,
performance_metrics=performance_metrics
)
# Ajouter le correlation_id et des métadonnées personnalisées
result.correlation_id = correlation_id
result.add_execution_detail("user_session", "session_xyz789")
result.add_execution_detail("browser_context", {
"user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
"viewport": {"width": 1920, "height": 1080},
"url": "https://app.example.com/login"
})
result.add_execution_detail("workflow_version", "v3.2.1")
result.add_execution_detail("execution_environment", "production")
# Afficher les informations clés
print(f"✅ Exécution réussie")
print(f" Execution ID: {result.execution_id}")
print(f" Correlation ID: {result.correlation_id}")
print(f" Workflow: {result.workflow_id}")
print(f" Navigation: {result.current_node}{result.target_node}")
print(f" Action: {result.action_executed['type']} sur {result.action_executed['target']}")
print(f" Temps total: {result.performance_metrics.total_execution_time_ms:.1f}ms")
print(f" Confiance matching: {result.match_result['confidence']:.2%}")
# Afficher la décomposition des temps
print(f"\n📊 Décomposition des performances:")
print(f" • Matching d'état: {result.performance_metrics.state_matching_time_ms:.1f}ms")
print(f" • Résolution cible: {result.performance_metrics.target_resolution_time_ms:.1f}ms")
print(f" • Exécution action: {result.performance_metrics.action_execution_time_ms:.1f}ms")
print(f" • Gestion erreurs: {result.performance_metrics.error_handling_time_ms:.1f}ms")
return result
def demo_execution_with_recovery():
"""Démonstration d'une exécution avec récupération appliquée"""
print("\n=== Démonstration : Exécution avec Récupération ===")
# Simuler une exécution avec récupération
execution_id = str(uuid.uuid4())
correlation_id = str(uuid.uuid4())
# Récupération appliquée
recovery_info = RecoveryInfo(
strategy="semantic_variant_with_spatial_fallback",
message="Target text 'Login' not found, applied semantic variants ('Sign In', 'Log In', 'Enter') with spatial fallback",
success=True,
attempts=3,
duration_ms=45.8
)
# Métriques avec temps de récupération
performance_metrics = PerformanceMetrics(
total_execution_time_ms=234.6,
state_matching_time_ms=38.2,
target_resolution_time_ms=89.4, # Plus long à cause de la récupération
action_execution_time_ms=61.2,
error_handling_time_ms=45.8
)
# Action exécutée après récupération
action_executed = {
"edge_id": "form_submit_edge",
"type": "click",
"target": "submit_button",
"parameters": {"text_variant": "Sign In", "fallback_method": "spatial"},
"execution_status": "SUCCESS",
"execution_message": "Action executed after semantic variant recovery",
"execution_duration_ms": 61.2
}
# Créer le résultat avec récupération
result = WorkflowExecutionResult.success(
execution_id=execution_id,
workflow_id="form_submission_flow",
current_node="form_page",
target_node="confirmation_page",
action_executed=action_executed,
performance_metrics=performance_metrics
)
# Ajouter les métadonnées de récupération
result.correlation_id = correlation_id
result.recovery_applied = recovery_info
# Ajouter des détails de récupération
result.add_execution_detail("original_target_text", "Login")
result.add_execution_detail("attempted_variants", ["Sign In", "Log In", "Enter"])
result.add_execution_detail("successful_variant", "Sign In")
result.add_execution_detail("fallback_coordinates", {"x": 450, "y": 320})
result.add_execution_detail("recovery_confidence", 0.87)
# Afficher les informations de récupération
print(f"🔄 Exécution avec récupération réussie")
print(f" Execution ID: {result.execution_id}")
print(f" Correlation ID: {result.correlation_id}")
print(f" Stratégie de récupération: {result.recovery_applied.strategy}")
print(f" Tentatives: {result.recovery_applied.attempts}")
print(f" Temps de récupération: {result.recovery_applied.duration_ms:.1f}ms")
print(f" Message: {result.recovery_applied.message}")
# Afficher l'impact sur les performances
print(f"\n⏱️ Impact sur les performances:")
print(f" • Temps total: {result.performance_metrics.total_execution_time_ms:.1f}ms")
print(f" • Temps de récupération: {result.performance_metrics.error_handling_time_ms:.1f}ms")
print(f" • Pourcentage récupération: {(result.performance_metrics.error_handling_time_ms / result.performance_metrics.total_execution_time_ms * 100):.1f}%")
return result
def demo_execution_failure():
"""Démonstration d'une exécution échouée avec métadonnées complètes"""
print("\n=== Démonstration : Exécution Échouée ===")
# Simuler une exécution échouée
execution_id = str(uuid.uuid4())
correlation_id = str(uuid.uuid4())
# Récupération tentée mais échouée
recovery_info = RecoveryInfo(
strategy="comprehensive_fallback",
message="Applied all available recovery strategies: semantic variants, spatial fallback, hierarchical matching, OCR text detection. All attempts failed.",
success=False,
attempts=5,
duration_ms=187.3
)
# Métriques avec beaucoup de temps d'erreur
performance_metrics = PerformanceMetrics(
total_execution_time_ms=298.7,
state_matching_time_ms=35.1,
target_resolution_time_ms=76.3,
action_execution_time_ms=0.0, # Pas d'exécution à cause de l'échec
error_handling_time_ms=187.3
)
# Créer le résultat d'erreur
result = WorkflowExecutionResult.error(
execution_id=execution_id,
workflow_id="payment_processing_flow",
error_message="Target element 'payment_submit_button' not found after comprehensive recovery attempts",
step_type="target_resolution",
current_node="payment_form",
recovery_info=recovery_info,
performance_metrics=performance_metrics
)
result.correlation_id = correlation_id
# Ajouter des détails d'erreur détaillés
result.add_execution_detail("target_selector", "button[data-testid='payment-submit']")
result.add_execution_detail("attempted_selectors", [
"button[data-testid='payment-submit']",
"input[type='submit'][value*='Pay']",
"button:contains('Complete Payment')",
".payment-button",
"#submit-payment"
])
result.add_execution_detail("screenshot_path", "/tmp/error_screenshots/payment_form_error.png")
result.add_execution_detail("page_source_path", "/tmp/error_logs/payment_form_source.html")
result.add_execution_detail("recovery_attempts_log", [
{"strategy": "semantic_variant", "duration_ms": 45.2, "success": False},
{"strategy": "spatial_fallback", "duration_ms": 38.7, "success": False},
{"strategy": "hierarchical_matching", "duration_ms": 52.1, "success": False},
{"strategy": "ocr_text_detection", "duration_ms": 51.3, "success": False}
])
result.add_execution_detail("error_category", "TARGET_NOT_FOUND")
result.add_execution_detail("user_impact", "WORKFLOW_BLOCKED")
# Afficher les informations d'erreur
print(f"❌ Exécution échouée")
print(f" Execution ID: {result.execution_id}")
print(f" Correlation ID: {result.correlation_id}")
print(f" Erreur: {result.error}")
print(f" Node bloqué: {result.current_node}")
print(f" Tentatives de récupération: {result.recovery_applied.attempts}")
print(f" Temps de récupération: {result.recovery_applied.duration_ms:.1f}ms")
# Afficher l'analyse des tentatives
print(f"\n🔍 Analyse des tentatives de récupération:")
for i, attempt in enumerate(result.execution_details["recovery_attempts_log"], 1):
print(f" {i}. {attempt['strategy']}: {attempt['duration_ms']:.1f}ms - {'' if attempt['success'] else ''}")
# Afficher les ressources de debugging
print(f"\n🐛 Ressources de debugging:")
print(f" • Screenshot: {result.execution_details['screenshot_path']}")
print(f" • Page source: {result.execution_details['page_source_path']}")
print(f" • Sélecteurs tentés: {len(result.execution_details['attempted_selectors'])}")
return result
def demo_serialization_and_audit():
"""Démonstration de la sérialisation pour audit et logging"""
print("\n=== Démonstration : Sérialisation et Audit ===")
# Créer un résultat complexe
result = demo_execution_with_recovery()
# Sérialiser pour audit
try:
audit_data = result.to_dict()
print(f"📋 Données d'audit sérialisées:")
print(f" • Taille des données: {len(json.dumps(audit_data))} caractères")
print(f" • Champs principaux: {len(audit_data)} champs")
print(f" • Métadonnées personnalisées: {len(audit_data.get('execution_details', {}))}")
# Afficher un extrait des données d'audit
print(f"\n📄 Extrait des données d'audit (JSON):")
audit_extract = {
"execution_id": audit_data["execution_id"],
"correlation_id": audit_data["correlation_id"],
"workflow_id": audit_data["workflow_id"],
"success": audit_data["success"],
"status": audit_data["status"],
"performance_summary": {
"total_time_ms": audit_data["performance_metrics"]["total_execution_time_ms"],
"recovery_time_ms": audit_data["performance_metrics"]["error_handling_time_ms"]
},
"recovery_applied": {
"strategy": audit_data["recovery_applied"]["strategy"],
"success": audit_data["recovery_applied"]["success"],
"attempts": audit_data["recovery_applied"]["attempts"]
}
}
print(json.dumps(audit_extract, indent=2, ensure_ascii=False))
return audit_data
except Exception as e:
print(f"❌ Erreur de sérialisation: {e}")
# Debug: identifier les types problématiques
audit_data = result.to_dict()
print(f"🔍 Debug des types dans audit_data:")
for key, value in audit_data.items():
print(f"{key}: {type(value)}")
if isinstance(value, dict):
for subkey, subvalue in value.items():
print(f" - {subkey}: {type(subvalue)}")
if hasattr(subvalue, '__call__'):
print(f" ⚠️ MÉTHODE DÉTECTÉE: {subvalue}")
# Retourner un dictionnaire simplifié
return {
"execution_id": result.execution_id,
"correlation_id": result.correlation_id,
"workflow_id": result.workflow_id,
"success": result.success,
"error": "Serialization failed"
}
def demo_correlation_tracking():
"""Démonstration du suivi par correlation_id"""
print("\n=== Démonstration : Suivi par Correlation ID ===")
# Simuler une séquence d'exécutions liées
correlation_id = str(uuid.uuid4())
workflow_executions = []
# Étape 1: Login
step1 = WorkflowExecutionResult.success(
execution_id=str(uuid.uuid4()),
workflow_id="multi_step_process",
current_node="login_page",
target_node="dashboard",
action_executed={"type": "login", "username": "user@example.com"}
)
step1.correlation_id = correlation_id
step1.add_execution_detail("step_name", "user_authentication")
step1.add_execution_detail("step_order", 1)
workflow_executions.append(step1)
# Étape 2: Navigation
step2 = WorkflowExecutionResult.success(
execution_id=str(uuid.uuid4()),
workflow_id="multi_step_process",
current_node="dashboard",
target_node="settings_page",
action_executed={"type": "navigate", "target": "settings_menu"}
)
step2.correlation_id = correlation_id
step2.add_execution_detail("step_name", "navigation_to_settings")
step2.add_execution_detail("step_order", 2)
workflow_executions.append(step2)
# Étape 3: Configuration (avec erreur)
step3 = WorkflowExecutionResult.error(
execution_id=str(uuid.uuid4()),
workflow_id="multi_step_process",
error_message="Configuration form validation failed",
current_node="settings_page"
)
step3.correlation_id = correlation_id
step3.add_execution_detail("step_name", "configuration_update")
step3.add_execution_detail("step_order", 3)
workflow_executions.append(step3)
# Afficher le suivi
print(f"🔗 Suivi d'un processus multi-étapes:")
print(f" Correlation ID: {correlation_id}")
print(f" Nombre d'étapes: {len(workflow_executions)}")
for i, execution in enumerate(workflow_executions, 1):
status_icon = "" if execution.success else ""
print(f" {i}. {execution.execution_details['step_name']}: {status_icon}")
print(f" • Execution ID: {execution.execution_id}")
print(f" • Status: {execution.status.value}")
if not execution.success:
print(f" • Erreur: {execution.error}")
return workflow_executions
def main():
"""Fonction principale de démonstration"""
print("🚀 Démonstration de WorkflowExecutionResult avec Métadonnées Complètes")
print("=" * 80)
try:
# Démonstrations
success_result = demo_successful_execution()
recovery_result = demo_execution_with_recovery()
failure_result = demo_execution_failure()
audit_data = demo_serialization_and_audit()
correlation_tracking = demo_correlation_tracking()
# Résumé final
print(f"\n🎯 Résumé de la Démonstration:")
print(f" • Exécution réussie: ✅ {success_result.performance_metrics.total_execution_time_ms:.1f}ms")
print(f" • Exécution avec récupération: 🔄 {recovery_result.performance_metrics.total_execution_time_ms:.1f}ms")
print(f" • Exécution échouée: ❌ {failure_result.performance_metrics.total_execution_time_ms:.1f}ms")
print(f" • Données d'audit générées: 📋 {len(json.dumps(audit_data))} caractères")
print(f" • Étapes trackées par correlation: 🔗 {len(correlation_tracking)} étapes")
print(f"\n✨ Fonctionnalités démontrées:")
print(f" ✅ Correlation ID unique pour traçabilité")
print(f" ✅ Métriques de performance détaillées")
print(f" ✅ Informations de récupération complètes")
print(f" ✅ Métadonnées personnalisées extensibles")
print(f" ✅ Sérialisation complète pour audit")
print(f" ✅ Suivi multi-étapes par correlation")
print(f"\n🎉 Démonstration terminée avec succès!")
except Exception as e:
print(f"\n❌ Erreur durant la démonstration: {e}")
import traceback
traceback.print_exc()
return 1
return 0
if __name__ == "__main__":
exit(main())