Initial commit

This commit is contained in:
Dom
2026-03-05 00:20:25 +01:00
commit dcd4de9945
1954 changed files with 669380 additions and 0 deletions

206
test_element_matching.py Normal file
View File

@@ -0,0 +1,206 @@
#!/usr/bin/env python3
"""
Test du feedback détaillé sur échec de matching.
"""
from geniusia2.core.enhanced_workflow_matcher import EnhancedWorkflowMatcher, MatchDifference
from geniusia2.core.multimodal_embedding_manager import MultiModalEmbeddingManager
from geniusia2.core.ui_element_models import (
UIElement, UIElementType, VisualData, TextData,
ElementProperties, ElementContext, EnrichedScreenState,
WindowInfo, RawData, PerceptionData
)
from geniusia2.core.logger import Logger
import numpy as np
from dataclasses import dataclass
from typing import List, Optional
from datetime import datetime
print('Test du feedback détaillé sur échec de matching')
print('='*60)
# Créer les composants
logger = Logger(log_dir='test_logs')
mm_manager = MultiModalEmbeddingManager(logger=logger, data_dir='test_data')
matcher = EnhancedWorkflowMatcher(mm_manager, logger=logger)
# Définir les structures de workflow
@dataclass
class WorkflowStep:
step_id: int
action_type: str
target_description: str
position: tuple
window: str
embedding: Optional[np.ndarray] = None
@dataclass
class Workflow:
workflow_id: str
name: str
steps: List[WorkflowStep]
repetitions: int
confidence: float
# Scénario 1: Match parfait (pas de feedback)
print('\n1. Test Match Parfait (pas de feedback):')
print('-' * 60)
button = UIElement(
element_id='btn_001',
type=UIElementType.BUTTON,
role='primary_action',
bbox=(100, 200, 80, 30),
label='Submit',
visual=VisualData('test.png', 'test', 'test.npy'),
text=TextData('Submit', 'submit', 'test', 'test.npy'),
properties=ElementProperties(is_clickable=True),
context=ElementContext('TestApp', 'Test Window'),
confidence=0.95
)
screen_state = EnrichedScreenState(
screen_state_id='screen_001',
timestamp=datetime.now(),
session_id='session_001',
window=WindowInfo('TestApp', 'Test Window', True),
raw=RawData('test.png'),
perception=PerceptionData(['Extracted text']),
ui_elements=[button],
state_embedding=None,
context=None
)
step1 = WorkflowStep(1, 'click', 'submit button', (140, 215), 'test', np.random.rand(512))
workflow_perfect = Workflow('wf_perfect', 'Perfect Match', [step1], 5, 0.95)
# Simuler un embedding parfait
current_embedding = np.random.rand(512)
match_perfect = matcher._compute_workflow_match(
screen_state, current_embedding, workflow_perfect
)
print(f'✓ Score composite: {match_perfect.composite_score:.3f}')
print(f'✓ Confiance: {match_perfect.confidence:.3f}')
print(f'✓ Différences: {len(match_perfect.differences) if match_perfect.differences else 0}')
if match_perfect.differences:
print(f'⚠ Feedback inattendu pour un match parfait!')
else:
print(f'✓ Pas de feedback (comme attendu pour un bon match)')
# Scénario 2: Match partiel avec éléments manquants
print('\n2. Test Match Partiel (éléments manquants):')
print('-' * 60)
# Workflow avec 3 steps mais seulement 1 élément détecté
step1 = WorkflowStep(1, 'type', 'username field', (150, 162), 'test')
step2 = WorkflowStep(2, 'type', 'password field', (150, 200), 'test')
step3 = WorkflowStep(3, 'click', 'submit button', (140, 250), 'test')
workflow_partial = Workflow('wf_partial', 'Partial Match', [step1, step2, step3], 5, 0.8)
# Seulement 1 élément détecté
screen_state_partial = EnrichedScreenState(
screen_state_id='screen_002',
timestamp=datetime.now(),
session_id='session_001',
window=WindowInfo('TestApp', 'Test Window', True),
raw=RawData('test.png'),
perception=PerceptionData(['Extracted text']),
ui_elements=[button], # Seulement 1 élément au lieu de 3
state_embedding=None,
context=None
)
match_partial = matcher._compute_workflow_match(
screen_state_partial, current_embedding, workflow_partial
)
print(f'✓ Score composite: {match_partial.composite_score:.3f}')
print(f'✓ Confiance: {match_partial.confidence:.3f}')
print(f'✓ Différences détectées: {len(match_partial.differences) if match_partial.differences else 0}')
if match_partial.differences:
print(f'\n📋 Feedback détaillé:')
for i, diff in enumerate(match_partial.differences, 1):
print(f'\n {i}. [{diff.severity.upper()}] {diff.difference_type}')
print(f' Description: {diff.description}')
if diff.expected:
print(f' Attendu: {diff.expected}')
if diff.actual:
print(f' Actuel: {diff.actual}')
if diff.suggestion:
print(f' 💡 Suggestion: {diff.suggestion}')
# Scénario 3: Test du résumé de feedback
print('\n3. Test Résumé de Feedback:')
print('-' * 60)
if match_partial.differences:
summary = match_partial.get_feedback_summary()
print(summary)
# Scénario 4: Match avec faible confiance
print('\n4. Test Match avec Faible Confiance:')
print('-' * 60)
button_low_conf = UIElement(
element_id='btn_002',
type=UIElementType.BUTTON,
role='primary_action',
bbox=(100, 200, 80, 30),
label='Maybe Submit',
visual=VisualData('test.png', 'test', 'test.npy'),
text=TextData('Maybe Submit', 'maybe submit', 'test', 'test.npy'),
properties=ElementProperties(is_clickable=True),
context=ElementContext('TestApp', 'Test Window'),
confidence=0.35 # Faible confiance
)
screen_state_low_conf = EnrichedScreenState(
screen_state_id='screen_003',
timestamp=datetime.now(),
session_id='session_001',
window=WindowInfo('TestApp', 'Test Window', True),
raw=RawData('test.png'),
perception=PerceptionData(['Extracted text']),
ui_elements=[button_low_conf],
state_embedding=None,
context=None
)
match_low_conf = matcher._compute_workflow_match(
screen_state_low_conf, current_embedding, workflow_perfect
)
print(f'✓ Score composite: {match_low_conf.composite_score:.3f}')
print(f'✓ Confiance: {match_low_conf.confidence:.3f}')
print(f'✓ Différences détectées: {len(match_low_conf.differences) if match_low_conf.differences else 0}')
if match_low_conf.differences:
print(f'\n📋 Résumé:')
print(match_low_conf.get_feedback_summary())
# Test de la conversion en dictionnaire
print('\n5. Test Sérialisation JSON:')
print('-' * 60)
match_dict = match_partial.to_dict()
print(f'✓ Workflow ID: {match_dict["workflow_id"]}')
print(f'✓ Score composite: {match_dict["composite_score"]:.3f}')
print(f'✓ Différences incluses: {"differences" in match_dict}')
if "differences" in match_dict:
print(f'✓ Nombre de différences: {len(match_dict["differences"])}')
print(f'✓ Première différence: {match_dict["differences"][0]["type"]}')
print('\n' + '='*60)
print('✅ Tous les tests de feedback détaillé réussis!')
print('='*60)
# Nettoyage
import shutil
from pathlib import Path
if Path('test_data').exists():
shutil.rmtree('test_data')
if Path('test_logs').exists():
shutil.rmtree('test_logs')