- 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>
435 lines
18 KiB
Python
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()) |