#!/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())