- 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>
333 lines
9.9 KiB
Python
333 lines
9.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Demo script for Self-Healing Workflows system.
|
|
|
|
This script demonstrates the key features of the self-healing system.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from datetime import datetime
|
|
|
|
# Add project root to path
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
from core.healing.healing_engine import SelfHealingEngine
|
|
from core.healing.learning_repository import LearningRepository
|
|
from core.healing.confidence_scorer import ConfidenceScorer
|
|
from core.healing.recovery_logger import RecoveryLogger
|
|
from core.healing.models import RecoveryContext, RecoveryResult
|
|
from core.healing.execution_integration import get_self_healing_integration
|
|
|
|
|
|
def print_header(title: str):
|
|
"""Print a formatted header."""
|
|
print("\n" + "=" * 70)
|
|
print(f" {title}")
|
|
print("=" * 70)
|
|
|
|
|
|
def demo_confidence_scorer():
|
|
"""Demonstrate confidence scoring."""
|
|
print_header("1. Confidence Scorer Demo")
|
|
|
|
scorer = ConfidenceScorer()
|
|
|
|
# Test text similarity
|
|
print("\n📊 Text Similarity:")
|
|
pairs = [
|
|
("Submit", "Submit"),
|
|
("Submit", "Send"),
|
|
("Submit", "Cancel"),
|
|
]
|
|
|
|
for text1, text2 in pairs:
|
|
similarity = scorer._text_similarity(text1, text2)
|
|
print(f" '{text1}' vs '{text2}': {similarity:.3f}")
|
|
|
|
# Test confidence calculation
|
|
print("\n📊 Recovery Confidence:")
|
|
context = RecoveryContext(
|
|
original_action='click',
|
|
target_element='Submit Button',
|
|
failure_reason='element_not_found',
|
|
screenshot_path='/tmp/test.png',
|
|
workflow_id='demo_workflow',
|
|
node_id='node_1',
|
|
attempt_count=1
|
|
)
|
|
|
|
strategies = ['semantic_variant', 'spatial_fallback', 'timing_adaptation']
|
|
for strategy in strategies:
|
|
confidence = scorer.calculate_recovery_confidence(strategy, context, 0.8)
|
|
print(f" {strategy}: {confidence:.3f}")
|
|
|
|
|
|
def demo_learning_repository():
|
|
"""Demonstrate learning repository."""
|
|
print_header("2. Learning Repository Demo")
|
|
|
|
import tempfile
|
|
temp_dir = Path(tempfile.mkdtemp())
|
|
repo = LearningRepository(temp_dir)
|
|
|
|
# Store some patterns
|
|
print("\n💾 Storing recovery patterns...")
|
|
|
|
contexts_and_results = [
|
|
(
|
|
RecoveryContext(
|
|
original_action='click',
|
|
target_element='Submit',
|
|
failure_reason='element_not_found',
|
|
screenshot_path='/tmp/test1.png',
|
|
workflow_id='workflow_1',
|
|
node_id='node_1',
|
|
attempt_count=1,
|
|
metadata={'element_type': 'button'}
|
|
),
|
|
RecoveryResult(
|
|
success=True,
|
|
strategy_used='semantic_variant',
|
|
new_element='Send',
|
|
confidence_score=0.85
|
|
)
|
|
),
|
|
(
|
|
RecoveryContext(
|
|
original_action='click',
|
|
target_element='Login',
|
|
failure_reason='element_moved',
|
|
screenshot_path='/tmp/test2.png',
|
|
workflow_id='workflow_1',
|
|
node_id='node_2',
|
|
attempt_count=1,
|
|
metadata={'element_type': 'button'}
|
|
),
|
|
RecoveryResult(
|
|
success=True,
|
|
strategy_used='spatial_fallback',
|
|
confidence_score=0.75
|
|
)
|
|
),
|
|
]
|
|
|
|
for context, result in contexts_and_results:
|
|
repo.store_pattern(context, result)
|
|
print(f" ✅ Stored: {result.strategy_used} for {context.failure_reason}")
|
|
|
|
# Retrieve patterns
|
|
print(f"\n📚 Total patterns stored: {len(repo.get_all_patterns())}")
|
|
|
|
for pattern in repo.get_all_patterns():
|
|
print(f" - {pattern.recovery_strategy}: {pattern.success_rate:.1%} success rate")
|
|
|
|
# Cleanup
|
|
import shutil
|
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
|
|
|
|
|
def demo_recovery_strategies():
|
|
"""Demonstrate recovery strategies."""
|
|
print_header("3. Recovery Strategies Demo")
|
|
|
|
from core.healing.strategies import (
|
|
SemanticVariantStrategy,
|
|
SpatialFallbackStrategy,
|
|
TimingAdaptationStrategy,
|
|
FormatTransformationStrategy
|
|
)
|
|
|
|
# Semantic Variants
|
|
print("\n🔤 Semantic Variant Strategy:")
|
|
strategy = SemanticVariantStrategy()
|
|
variants = strategy._get_semantic_variants('submit')
|
|
print(f" 'submit' → {', '.join(variants[:5])}")
|
|
|
|
variants = strategy._get_semantic_variants('login')
|
|
print(f" 'login' → {', '.join(variants[:5])}")
|
|
|
|
# Spatial Fallback
|
|
print("\n📍 Spatial Fallback Strategy:")
|
|
strategy = SpatialFallbackStrategy()
|
|
print(f" Search radii: {strategy.search_radii} pixels")
|
|
|
|
# Timing Adaptation
|
|
print("\n⏱️ Timing Adaptation Strategy:")
|
|
strategy = TimingAdaptationStrategy()
|
|
print(f" Min wait: {strategy.min_wait}s")
|
|
print(f" Max wait: {strategy.max_wait}s")
|
|
print(f" Adaptation factor: {strategy.adaptation_factor}x")
|
|
|
|
# Format Transformation
|
|
print("\n🔄 Format Transformation Strategy:")
|
|
strategy = FormatTransformationStrategy()
|
|
print(f" Date formats: {len(strategy.date_formats)} variations")
|
|
print(f" Phone formats: {len(strategy.phone_formats)} variations")
|
|
|
|
|
|
def demo_self_healing_engine():
|
|
"""Demonstrate self-healing engine."""
|
|
print_header("4. Self-Healing Engine Demo")
|
|
|
|
import tempfile
|
|
temp_dir = Path(tempfile.mkdtemp())
|
|
engine = SelfHealingEngine(storage_path=temp_dir)
|
|
|
|
print(f"\n🔧 Engine initialized with {len(engine.recovery_strategies)} strategies")
|
|
|
|
# Create a recovery context
|
|
context = RecoveryContext(
|
|
original_action='click',
|
|
target_element='Submit Button',
|
|
failure_reason='element_not_found',
|
|
screenshot_path='/tmp/demo.png',
|
|
workflow_id='demo_workflow',
|
|
node_id='demo_node',
|
|
attempt_count=1,
|
|
confidence_threshold=0.7
|
|
)
|
|
|
|
print("\n🔍 Getting recovery suggestions...")
|
|
suggestions = engine.get_recovery_suggestions(context)
|
|
|
|
for i, suggestion in enumerate(suggestions, 1):
|
|
print(f" {i}. {suggestion.strategy}")
|
|
print(f" Confidence: {suggestion.confidence:.3f}")
|
|
print(f" Description: {suggestion.description}")
|
|
print(f" Est. time: {suggestion.estimated_time}s")
|
|
|
|
# Cleanup
|
|
import shutil
|
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
|
|
|
|
|
def demo_integration():
|
|
"""Demonstrate integration layer."""
|
|
print_header("5. Integration Layer Demo")
|
|
|
|
import tempfile
|
|
temp_dir = Path(tempfile.mkdtemp())
|
|
|
|
healing = get_self_healing_integration(
|
|
storage_path=temp_dir / 'healing',
|
|
log_path=temp_dir / 'logs',
|
|
enabled=True
|
|
)
|
|
|
|
print("\n✅ Self-healing integration initialized")
|
|
print(f" Enabled: {healing.enabled}")
|
|
|
|
# Get statistics
|
|
stats = healing.get_statistics()
|
|
print(f"\n📊 Statistics:")
|
|
print(f" Total attempts: {stats.get('total_attempts', 0)}")
|
|
print(f" Successful recoveries: {stats.get('successful_recoveries', 0)}")
|
|
|
|
# Cleanup
|
|
import shutil
|
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
|
|
|
|
|
def demo_complete_workflow():
|
|
"""Demonstrate a complete recovery workflow."""
|
|
print_header("6. Complete Recovery Workflow Demo")
|
|
|
|
import tempfile
|
|
temp_dir = Path(tempfile.mkdtemp())
|
|
|
|
# Initialize
|
|
healing = get_self_healing_integration(
|
|
storage_path=temp_dir / 'healing',
|
|
log_path=temp_dir / 'logs',
|
|
enabled=True
|
|
)
|
|
|
|
print("\n📝 Simulating workflow execution failure...")
|
|
|
|
# Simulate a failure
|
|
from core.execution.action_executor import ExecutionResult, ExecutionStatus
|
|
|
|
action_info = {
|
|
'action': 'click',
|
|
'target': 'Submit Button',
|
|
'element_type': 'button'
|
|
}
|
|
|
|
execution_result = ExecutionResult(
|
|
status=ExecutionStatus.TARGET_NOT_FOUND,
|
|
message='Element not found: Submit Button',
|
|
duration_ms=100
|
|
)
|
|
|
|
print(f" ❌ Action failed: {execution_result.message}")
|
|
|
|
# Attempt recovery
|
|
print("\n🔧 Attempting recovery...")
|
|
recovery = healing.handle_execution_failure(
|
|
action_info=action_info,
|
|
execution_result=execution_result,
|
|
workflow_id='demo_workflow',
|
|
node_id='demo_node',
|
|
screenshot_path='/tmp/demo.png',
|
|
attempt_count=1
|
|
)
|
|
|
|
if recovery:
|
|
if recovery.success:
|
|
print(f" ✅ Recovery successful!")
|
|
print(f" Strategy: {recovery.strategy_used}")
|
|
print(f" Confidence: {recovery.confidence_score:.3f}")
|
|
print(f" Time: {recovery.execution_time:.3f}s")
|
|
else:
|
|
print(f" ❌ Recovery failed")
|
|
print(f" Reason: {recovery.error_message}")
|
|
|
|
# Get insights
|
|
print("\n💡 Insights:")
|
|
insights = healing.get_insights()
|
|
if insights:
|
|
for insight in insights:
|
|
print(f" - {insight}")
|
|
else:
|
|
print(" - No insights yet (need more data)")
|
|
|
|
# Cleanup
|
|
import shutil
|
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
|
|
|
|
|
def main():
|
|
"""Run all demos."""
|
|
print("\n" + "🎯" * 35)
|
|
print(" SELF-HEALING WORKFLOWS - DEMONSTRATION")
|
|
print("🎯" * 35)
|
|
|
|
try:
|
|
demo_confidence_scorer()
|
|
demo_learning_repository()
|
|
demo_recovery_strategies()
|
|
demo_self_healing_engine()
|
|
demo_integration()
|
|
demo_complete_workflow()
|
|
|
|
print("\n" + "=" * 70)
|
|
print(" ✅ All demos completed successfully!")
|
|
print("=" * 70)
|
|
print("\n📚 For more information, see:")
|
|
print(" - SELF_HEALING_IMPLEMENTATION.md")
|
|
print(" - SELF_HEALING_QUICKSTART.md")
|
|
print("\n")
|
|
|
|
except Exception as e:
|
|
print(f"\n❌ Error during demo: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|