- 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>
176 lines
6.3 KiB
Python
176 lines
6.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Test Phase 7 - Learning System"""
|
|
import sys
|
|
from pathlib import Path
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
import logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def test_imports():
|
|
logger.info("\n=== Testing Imports ===")
|
|
try:
|
|
from core.learning.learning_manager import LearningManager, WorkflowStats
|
|
logger.info("✓ LearningManager imported")
|
|
from core.learning.feedback_processor import FeedbackProcessor, FeedbackType
|
|
logger.info("✓ FeedbackProcessor imported")
|
|
from core.models.workflow_graph import LearningState
|
|
logger.info("✓ LearningState imported")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"✗ Import failed: {e}")
|
|
return False
|
|
|
|
def test_learning_manager():
|
|
logger.info("\n=== Testing LearningManager ===")
|
|
try:
|
|
from core.learning.learning_manager import LearningManager
|
|
from core.models.workflow_graph import Workflow, LearningState
|
|
|
|
manager = LearningManager()
|
|
logger.info("✓ LearningManager created")
|
|
|
|
# Create test workflow
|
|
workflow = Workflow(
|
|
id="test_workflow_1",
|
|
name="Test Workflow",
|
|
learning_state=LearningState.OBSERVATION
|
|
)
|
|
|
|
manager.register_workflow(workflow)
|
|
logger.info(f"✓ Workflow registered: {workflow.id}")
|
|
|
|
# Test state transitions
|
|
logger.info("\n Testing state transitions:")
|
|
|
|
# OBSERVATION → COACHING (need 5 observations with confidence > 0.90)
|
|
for i in range(5):
|
|
manager.record_observation(workflow.id)
|
|
manager.workflows[workflow.id].confidence_scores.append(0.92)
|
|
|
|
state = manager.get_workflow_state(workflow.id)
|
|
logger.info(f" After 5 observations: {state.value}")
|
|
|
|
# COACHING → AUTO_CANDIDATE (need 10 executions with success > 0.90)
|
|
for i in range(10):
|
|
manager.record_execution(workflow.id, success=True, confidence=0.93)
|
|
|
|
state = manager.get_workflow_state(workflow.id)
|
|
logger.info(f" After 10 successful executions: {state.value}")
|
|
|
|
# AUTO_CANDIDATE → AUTO_CONFIRMED (need 20 executions with success > 0.95)
|
|
for i in range(10):
|
|
manager.record_execution(workflow.id, success=True, confidence=0.96)
|
|
|
|
state = manager.get_workflow_state(workflow.id)
|
|
logger.info(f" After 20 total executions: {state.value}")
|
|
|
|
stats = manager.get_workflow_stats(workflow.id)
|
|
logger.info(f" Final stats: success_rate={stats.success_rate:.2f}, avg_confidence={stats.avg_confidence:.2f}")
|
|
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"✗ LearningManager test failed: {e}", exc_info=True)
|
|
return False
|
|
|
|
def test_feedback_processor():
|
|
logger.info("\n=== Testing FeedbackProcessor ===")
|
|
try:
|
|
from core.learning.feedback_processor import FeedbackProcessor, FeedbackType
|
|
|
|
processor = FeedbackProcessor()
|
|
logger.info("✓ FeedbackProcessor created")
|
|
|
|
# Process different types of feedback
|
|
result = processor.process_feedback(
|
|
workflow_id="test_workflow_1",
|
|
execution_id="exec_1",
|
|
feedback_type=FeedbackType.CORRECT,
|
|
confidence=0.95
|
|
)
|
|
logger.info(f"✓ CORRECT feedback processed: {len(result['suggestions'])} suggestions")
|
|
|
|
result = processor.process_feedback(
|
|
workflow_id="test_workflow_1",
|
|
execution_id="exec_2",
|
|
feedback_type=FeedbackType.INCORRECT,
|
|
confidence=0.75,
|
|
comment="Wrong button clicked"
|
|
)
|
|
logger.info(f"✓ INCORRECT feedback processed: {len(result['suggestions'])} suggestions")
|
|
|
|
# Get stats
|
|
stats = processor.get_feedback_stats("test_workflow_1")
|
|
logger.info(f"✓ Feedback stats: {stats['total']} total, accuracy={stats['accuracy']:.2f}")
|
|
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"✗ FeedbackProcessor test failed: {e}", exc_info=True)
|
|
return False
|
|
|
|
def test_rollback():
|
|
logger.info("\n=== Testing Rollback Mechanism ===")
|
|
try:
|
|
from core.learning.learning_manager import LearningManager
|
|
from core.models.workflow_graph import Workflow, LearningState
|
|
|
|
manager = LearningManager()
|
|
|
|
# Create workflow in AUTO_CONFIRMED state
|
|
workflow = Workflow(
|
|
id="test_workflow_rollback",
|
|
name="Rollback Test",
|
|
learning_state=LearningState.AUTO_CONFIRMED
|
|
)
|
|
manager.register_workflow(workflow)
|
|
manager.workflows[workflow.id].learning_state = LearningState.AUTO_CONFIRMED
|
|
manager.workflows[workflow.id].execution_count = 25
|
|
|
|
logger.info(f" Initial state: {manager.get_workflow_state(workflow.id).value}")
|
|
|
|
# Simulate confidence drop
|
|
for i in range(10):
|
|
manager.record_execution(workflow.id, success=False, confidence=0.70)
|
|
|
|
state = manager.get_workflow_state(workflow.id)
|
|
logger.info(f" After confidence drop: {state.value}")
|
|
|
|
if state == LearningState.COACHING:
|
|
logger.info("✓ Rollback triggered successfully")
|
|
return True
|
|
else:
|
|
logger.warning("✗ Rollback not triggered")
|
|
return False
|
|
|
|
except Exception as e:
|
|
logger.error(f"✗ Rollback test failed: {e}", exc_info=True)
|
|
return False
|
|
|
|
def main():
|
|
logger.info("=" * 60)
|
|
logger.info("Phase 7 - Learning System Tests")
|
|
logger.info("=" * 60)
|
|
|
|
tests = [
|
|
test_imports,
|
|
test_learning_manager,
|
|
test_feedback_processor,
|
|
test_rollback
|
|
]
|
|
|
|
results = []
|
|
for test in tests:
|
|
try:
|
|
result = test()
|
|
results.append(result)
|
|
except Exception as e:
|
|
logger.error(f"Test {test.__name__} crashed: {e}", exc_info=True)
|
|
results.append(False)
|
|
|
|
passed = sum(results)
|
|
logger.info(f"\n{'='*60}\nResults: {passed}/{len(results)} tests passed\n{'='*60}")
|
|
return 0 if passed == len(results) else 1
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|