Initial commit
This commit is contained in:
981
.kiro/specs/ui-element-detection/design.md
Normal file
981
.kiro/specs/ui-element-detection/design.md
Normal file
@@ -0,0 +1,981 @@
|
||||
# Document de Design
|
||||
|
||||
## Vue d'Ensemble
|
||||
|
||||
Ce document décrit l'architecture et la conception détaillée du système de détection d'éléments d'UI et de fusion multi-modale pour GeniusIA v2. Le système transforme l'approche actuelle de comparaison plein écran en une plateforme RPA robuste capable de détecter et d'interagir avec des éléments d'interface individuels via une analyse vision multi-modale.
|
||||
|
||||
### Objectifs Principaux
|
||||
|
||||
1. Détecter et classifier les éléments d'UI individuels (boutons, champs, listes, etc.)
|
||||
2. Créer des embeddings multi-modaux robustes combinant vision, texte et contexte
|
||||
3. Permettre une correspondance de workflow au niveau élément plutôt qu'au niveau écran complet
|
||||
4. Maintenir la compatibilité arrière avec le système existant
|
||||
5. Implémenter progressivement sans casser les workflows existants
|
||||
|
||||
## Architecture
|
||||
|
||||
### Composants Principaux
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Orchestrator │
|
||||
│ (Boucle Cognitive) │
|
||||
└────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ UIElementDetector (NOUVEAU) │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Region │→ │ Character │→ │ Classifier │ │
|
||||
│ │ Proposer │ │ -izer │ │ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
└────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ MultiModalEmbeddingManager (NOUVEAU) │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Image │ │ Text │ │ Context │ │
|
||||
│ │ Embedder │ │ Embedder │ │ Embedder │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ ┌──────────────┐ │
|
||||
│ │ Fusion │ │
|
||||
│ │ Engine │ │
|
||||
│ └──────────────┘ │
|
||||
└────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ EnrichedScreenState (NOUVEAU) │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ ui_elements: List[UIElement] │ │
|
||||
│ │ state_embedding: StateEmbedding │ │
|
||||
│ │ perception: PerceptionData │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
└────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ WorkflowMatcher (AMÉLIORÉ) │
|
||||
│ - Matching au niveau élément │
|
||||
│ - Matching au niveau état global │
|
||||
│ - Mode legacy pour compatibilité │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Flux de Données
|
||||
|
||||
1. **Capture d'écran** → Screenshot brut
|
||||
2. **UIElementDetector** → Liste de UIElement
|
||||
3. **MultiModalEmbeddingManager** → State embedding unifié
|
||||
4. **EnrichedScreenState** → Structure complète avec éléments + embedding
|
||||
5. **WorkflowMatcher** → Correspondance de workflow robuste
|
||||
6. **Orchestrator** → Décision d'action basée sur éléments sémantiques
|
||||
|
||||
## Composants et Interfaces
|
||||
|
||||
### 1. UIElement (Structure de Données)
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class UIElement:
|
||||
"""Représente un élément d'interface utilisateur détecté."""
|
||||
|
||||
# Identification
|
||||
element_id: str # Hash stable: hash(app_name + center_bbox + label_normalized)
|
||||
type: UIElementType # button, text_input, checkbox, tab, etc.
|
||||
role: str # validate_invoice, search_field, primary_action, etc.
|
||||
|
||||
# Position
|
||||
bbox: Tuple[int, int, int, int] # (x1, y1, x2, y2)
|
||||
|
||||
# Contenu
|
||||
label: str # Texte visible de l'élément
|
||||
|
||||
# Embeddings visuels
|
||||
visual: VisualData
|
||||
# - screenshot_path: str
|
||||
# - embedding_provider: str
|
||||
# - embedding_vector_id: str
|
||||
|
||||
# Embeddings textuels
|
||||
text: TextData
|
||||
# - raw: str
|
||||
# - normalized: str
|
||||
# - embedding_provider: str
|
||||
# - embedding_vector_id: str
|
||||
|
||||
# Propriétés
|
||||
properties: ElementProperties
|
||||
# - is_clickable: bool
|
||||
# - is_focusable: bool
|
||||
# - is_dangerous: bool
|
||||
|
||||
# Contexte
|
||||
context: ElementContext
|
||||
# - app_name: str
|
||||
# - window_title: str
|
||||
# - workflow_hint: Optional[str]
|
||||
|
||||
# Métadonnées
|
||||
tags: List[str]
|
||||
confidence: float # Score de confiance de la détection
|
||||
```
|
||||
|
||||
### 2. EnrichedScreenState (Structure de Données)
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class EnrichedScreenState:
|
||||
"""ScreenState enrichi avec éléments d'UI et embedding multi-modal."""
|
||||
|
||||
# Identification
|
||||
screen_state_id: str
|
||||
timestamp: datetime
|
||||
session_id: str
|
||||
|
||||
# Fenêtre
|
||||
window: WindowInfo
|
||||
# - app_name: str
|
||||
# - window_title: str
|
||||
# - screen_resolution: Tuple[int, int]
|
||||
|
||||
# Données brutes
|
||||
raw: RawData
|
||||
# - screenshot_path: str
|
||||
|
||||
# Perception
|
||||
perception: PerceptionData
|
||||
# - detected_text: List[str]
|
||||
# - ocr_results: Optional[Dict]
|
||||
|
||||
# Éléments d'UI (NOUVEAU)
|
||||
ui_elements: List[UIElement]
|
||||
|
||||
# Embedding d'état unifié (NOUVEAU)
|
||||
state_embedding: StateEmbedding
|
||||
# - provider: str
|
||||
# - vector_id: str
|
||||
# - components: EmbeddingComponents
|
||||
# - image_embedding: ComponentInfo
|
||||
# - text_embedding: ComponentInfo
|
||||
# - title_embedding: ComponentInfo
|
||||
# - ui_embedding: ComponentInfo
|
||||
# - context_embedding: ComponentInfo
|
||||
|
||||
# Contexte workflow
|
||||
context: ContextData
|
||||
# - current_workflow_candidate: Optional[str]
|
||||
# - tags: List[str]
|
||||
```
|
||||
|
||||
### 3. UIElementDetector (Nouveau Composant)
|
||||
|
||||
```python
|
||||
class UIElementDetector:
|
||||
"""Détecte et caractérise les éléments d'UI dans un screenshot."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
vlm_model: VisionLanguageModel,
|
||||
embedder: ImageEmbedder,
|
||||
text_embedder: TextEmbedder,
|
||||
config: DetectorConfig
|
||||
):
|
||||
self.vlm = vlm_model
|
||||
self.image_embedder = embedder
|
||||
self.text_embedder = text_embedder
|
||||
self.config = config
|
||||
|
||||
# Composants du pipeline
|
||||
self.region_proposer = RegionProposer(vlm_model, config)
|
||||
self.characterizer = ElementCharacterizer(embedder, text_embedder)
|
||||
self.classifier = ElementClassifier(config)
|
||||
|
||||
def detect_elements(
|
||||
self,
|
||||
screenshot: np.ndarray,
|
||||
window_info: WindowInfo
|
||||
) -> List[UIElement]:
|
||||
"""
|
||||
Pipeline complet de détection d'éléments.
|
||||
|
||||
Étapes:
|
||||
1. Proposer des régions d'intérêt
|
||||
2. Caractériser chaque région
|
||||
3. Classifier type et rôle
|
||||
"""
|
||||
# Étape 1: Régions d'intérêt
|
||||
regions = self.region_proposer.propose_regions(screenshot, window_info)
|
||||
|
||||
# Étape 2: Caractérisation
|
||||
characterized = []
|
||||
for region in regions:
|
||||
char_element = self.characterizer.characterize(
|
||||
screenshot, region, window_info
|
||||
)
|
||||
if char_element:
|
||||
characterized.append(char_element)
|
||||
|
||||
# Étape 3: Classification
|
||||
elements = []
|
||||
for char_elem in characterized:
|
||||
element = self.classifier.classify(char_elem, window_info)
|
||||
elements.append(element)
|
||||
|
||||
return elements
|
||||
```
|
||||
|
||||
### 4. RegionProposer (Sous-composant)
|
||||
|
||||
```python
|
||||
class RegionProposer:
|
||||
"""Propose des régions d'intérêt candidates pour les éléments d'UI."""
|
||||
|
||||
def propose_regions(
|
||||
self,
|
||||
screenshot: np.ndarray,
|
||||
window_info: WindowInfo
|
||||
) -> List[BoundingBox]:
|
||||
"""
|
||||
Propose des régions en combinant plusieurs méthodes:
|
||||
- Détection de zones de texte
|
||||
- Repérage de rectangles autour de texte
|
||||
- Requête VLM pour zones cliquables (optionnel, coûteux)
|
||||
"""
|
||||
regions = []
|
||||
|
||||
# Méthode 1: Zones de texte (rapide)
|
||||
if self.config.use_text_detection:
|
||||
text_regions = self._detect_text_regions(screenshot)
|
||||
regions.extend(text_regions)
|
||||
|
||||
# Méthode 2: Rectangles propres (heuristique)
|
||||
if self.config.use_rectangle_detection:
|
||||
rect_regions = self._detect_rectangles(screenshot)
|
||||
regions.extend(rect_regions)
|
||||
|
||||
# Méthode 3: VLM (précis mais lent, à utiliser avec parcimonie)
|
||||
if self.config.use_vlm_detection and self._should_use_vlm(window_info):
|
||||
vlm_regions = self._query_vlm_for_regions(screenshot)
|
||||
regions.extend(vlm_regions)
|
||||
|
||||
# Fusion et nettoyage
|
||||
regions = self._merge_overlapping_regions(regions)
|
||||
regions = self._filter_invalid_regions(regions)
|
||||
|
||||
return regions
|
||||
|
||||
def _should_use_vlm(self, window_info: WindowInfo) -> bool:
|
||||
"""Décide si on doit utiliser le VLM (coûteux)."""
|
||||
# Utiliser VLM seulement pour nouveaux écrans ou écrans importants
|
||||
return (
|
||||
self.config.vlm_on_new_screens and
|
||||
self._is_new_screen(window_info)
|
||||
)
|
||||
```
|
||||
|
||||
### 5. MultiModalEmbeddingManager (Nouveau Composant)
|
||||
|
||||
```python
|
||||
class MultiModalEmbeddingManager:
|
||||
"""Gère la création d'embeddings multi-modaux pour les états d'écran."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
image_embedder: ImageEmbedder,
|
||||
text_embedder: TextEmbedder,
|
||||
config: EmbeddingConfig
|
||||
):
|
||||
self.image_embedder = image_embedder
|
||||
self.text_embedder = text_embedder
|
||||
self.config = config
|
||||
|
||||
# Poids de fusion (configurables)
|
||||
self.weights = {
|
||||
'image': config.weight_image, # 0.5 par défaut
|
||||
'text': config.weight_text, # 0.3 par défaut
|
||||
'title': config.weight_title, # 0.1 par défaut
|
||||
'ui': config.weight_ui, # 0.1 par défaut
|
||||
'context': config.weight_context # 0.1 par défaut (à terme)
|
||||
}
|
||||
|
||||
def create_state_embedding(
|
||||
self,
|
||||
screenshot: np.ndarray,
|
||||
detected_text: List[str],
|
||||
window_title: str,
|
||||
ui_elements: List[UIElement],
|
||||
context: Optional[Dict] = None
|
||||
) -> StateEmbedding:
|
||||
"""
|
||||
Crée un embedding d'état unifié en fusionnant toutes les modalités.
|
||||
"""
|
||||
# Composante 1: Image globale
|
||||
image_emb = self.image_embedder.embed(screenshot)
|
||||
image_emb_norm = self._normalize(image_emb)
|
||||
|
||||
# Composante 2: Texte concaténé
|
||||
text_concat = " ".join(detected_text)
|
||||
text_emb = self.text_embedder.embed(text_concat)
|
||||
text_emb_norm = self._normalize(text_emb)
|
||||
|
||||
# Composante 3: Titre de fenêtre
|
||||
title_emb = self.text_embedder.embed(window_title)
|
||||
title_emb_norm = self._normalize(title_emb)
|
||||
|
||||
# Composante 4: UI éléments (moyenne des embeddings importants)
|
||||
ui_emb = self._compute_ui_embedding(ui_elements)
|
||||
ui_emb_norm = self._normalize(ui_emb)
|
||||
|
||||
# Composante 5: Contexte (à implémenter plus tard)
|
||||
context_emb = self._compute_context_embedding(context)
|
||||
context_emb_norm = self._normalize(context_emb)
|
||||
|
||||
# Fusion pondérée
|
||||
state_emb = (
|
||||
self.weights['image'] * image_emb_norm +
|
||||
self.weights['text'] * text_emb_norm +
|
||||
self.weights['title'] * title_emb_norm +
|
||||
self.weights['ui'] * ui_emb_norm +
|
||||
self.weights['context'] * context_emb_norm
|
||||
)
|
||||
|
||||
# Normalisation finale
|
||||
state_emb_final = self._normalize(state_emb)
|
||||
|
||||
# Créer l'objet StateEmbedding avec composantes
|
||||
return StateEmbedding(
|
||||
provider="multimodal_fusion_v1",
|
||||
vector=state_emb_final,
|
||||
components={
|
||||
'image': ComponentInfo(provider="openclip", vector=image_emb),
|
||||
'text': ComponentInfo(provider="clip_text", vector=text_emb),
|
||||
'title': ComponentInfo(provider="clip_text", vector=title_emb),
|
||||
'ui': ComponentInfo(provider="openclip", vector=ui_emb),
|
||||
'context': ComponentInfo(provider="numeric", vector=context_emb)
|
||||
}
|
||||
)
|
||||
|
||||
def _compute_ui_embedding(self, ui_elements: List[UIElement]) -> np.ndarray:
|
||||
"""Calcule un embedding représentatif des éléments d'UI."""
|
||||
if not ui_elements:
|
||||
return np.zeros(self.config.embedding_dim)
|
||||
|
||||
# Filtrer les éléments importants (boutons primaires, etc.)
|
||||
important_elements = [
|
||||
elem for elem in ui_elements
|
||||
if 'primary_action' in elem.tags or elem.properties.is_clickable
|
||||
]
|
||||
|
||||
if not important_elements:
|
||||
important_elements = ui_elements[:5] # Top 5 si aucun important
|
||||
|
||||
# Moyenne des embeddings
|
||||
embeddings = [self._load_embedding(elem.visual.embedding_vector_id)
|
||||
for elem in important_elements]
|
||||
return np.mean(embeddings, axis=0)
|
||||
```
|
||||
|
||||
### 6. WorkflowMatcher Amélioré
|
||||
|
||||
```python
|
||||
class EnhancedWorkflowMatcher:
|
||||
"""Matcher amélioré supportant correspondance au niveau élément."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
legacy_matcher: WorkflowMatcher,
|
||||
config: MatcherConfig
|
||||
):
|
||||
self.legacy_matcher = legacy_matcher
|
||||
self.config = config
|
||||
|
||||
def match_workflow_step(
|
||||
self,
|
||||
current_state: EnrichedScreenState,
|
||||
workflow: Workflow
|
||||
) -> MatchResult:
|
||||
"""
|
||||
Trouve la meilleure correspondance de workflow.
|
||||
|
||||
Stratégie:
|
||||
1. Si le workflow a des descripteurs d'éléments → matching élément
|
||||
2. Sinon → matching legacy (plein écran)
|
||||
"""
|
||||
if self._has_element_descriptors(workflow):
|
||||
return self._match_by_elements(current_state, workflow)
|
||||
else:
|
||||
return self._match_legacy(current_state, workflow)
|
||||
|
||||
def _match_by_elements(
|
||||
self,
|
||||
current_state: EnrichedScreenState,
|
||||
workflow: Workflow
|
||||
) -> MatchResult:
|
||||
"""Matching basé sur les éléments d'UI."""
|
||||
best_match = None
|
||||
best_score = 0.0
|
||||
|
||||
for step in workflow.steps:
|
||||
# Comparer state_embedding
|
||||
state_sim = self._compare_state_embeddings(
|
||||
current_state.state_embedding,
|
||||
step.expected_state_embedding
|
||||
)
|
||||
|
||||
# Comparer éléments requis
|
||||
element_sim = self._compare_required_elements(
|
||||
current_state.ui_elements,
|
||||
step.required_elements
|
||||
)
|
||||
|
||||
# Score combiné
|
||||
score = (
|
||||
self.config.weight_state * state_sim +
|
||||
self.config.weight_elements * element_sim
|
||||
)
|
||||
|
||||
if score > best_score:
|
||||
best_score = score
|
||||
best_match = step
|
||||
|
||||
return MatchResult(
|
||||
matched_step=best_match,
|
||||
confidence=best_score,
|
||||
method="element_based"
|
||||
)
|
||||
|
||||
def _compare_required_elements(
|
||||
self,
|
||||
detected: List[UIElement],
|
||||
required: List[ElementDescriptor]
|
||||
) -> float:
|
||||
"""Compare les éléments détectés aux éléments requis."""
|
||||
if not required:
|
||||
return 1.0
|
||||
|
||||
matches = 0
|
||||
for req_elem in required:
|
||||
# Chercher un élément correspondant
|
||||
for det_elem in detected:
|
||||
if self._elements_match(det_elem, req_elem):
|
||||
matches += 1
|
||||
break
|
||||
|
||||
return matches / len(required)
|
||||
|
||||
def _elements_match(
|
||||
self,
|
||||
detected: UIElement,
|
||||
required: ElementDescriptor
|
||||
) -> bool:
|
||||
"""Vérifie si un élément détecté correspond à un descripteur."""
|
||||
# Vérifier type
|
||||
if required.type and detected.type != required.type:
|
||||
return False
|
||||
|
||||
# Vérifier rôle
|
||||
if required.role and detected.role != required.role:
|
||||
return False
|
||||
|
||||
# Vérifier similarité sémantique (embedding)
|
||||
if required.embedding:
|
||||
sim = cosine_similarity(
|
||||
detected.text.embedding_vector,
|
||||
required.embedding
|
||||
)
|
||||
if sim < self.config.min_semantic_similarity:
|
||||
return False
|
||||
|
||||
# Vérifier position relative (optionnel)
|
||||
if required.position_hint:
|
||||
if not self._position_matches(detected.bbox, required.position_hint):
|
||||
return False
|
||||
|
||||
return True
|
||||
```
|
||||
|
||||
## Modèles de Données
|
||||
|
||||
### Formats JSON
|
||||
|
||||
#### UIElement JSON (v1)
|
||||
```json
|
||||
{
|
||||
"schema_version": "uielement_v1",
|
||||
"element_id": "el_btn_valider_001",
|
||||
"type": "button",
|
||||
"role": "validate_invoice",
|
||||
"bbox": [1600, 900, 1800, 940],
|
||||
"label": "Valider la facture",
|
||||
"confidence": 0.95,
|
||||
"detection_method": "heuristic_rectangle",
|
||||
"visual": {
|
||||
"screenshot_path": "data/screens/elements/el_btn_valider_001.png",
|
||||
"embedding": {
|
||||
"provider": "openclip_ViT-B-32",
|
||||
"vector_id": "data/embeddings/elements/el_btn_valider_001.npy"
|
||||
}
|
||||
},
|
||||
"text": {
|
||||
"raw": "Valider la facture",
|
||||
"normalized": "valider facture",
|
||||
"embedding": {
|
||||
"provider": "clip_text",
|
||||
"vector_id": "data/embeddings/elements/el_btn_valider_001_text.npy"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"is_clickable": true,
|
||||
"is_focusable": true,
|
||||
"is_dangerous": false
|
||||
},
|
||||
"context": {
|
||||
"app_name": "logiciel_facturation",
|
||||
"window_title": "Facture n° 2025-00123 - DUPONT Jean",
|
||||
"workflow_hint": "WF_validation_facture"
|
||||
},
|
||||
"tags": ["primary_action", "billing"]
|
||||
}
|
||||
```
|
||||
|
||||
**Notes importantes :**
|
||||
- `schema_version` : Permet la compatibilité future et la migration de schémas
|
||||
- `detection_method` : Trace comment l'élément a été détecté (heuristic_rectangle, vlm_query, manual, etc.)
|
||||
- `embedding` : Peut être `null` en mode ultralight pour permettre une détection progressive
|
||||
- `confidence` : Score de confiance de la détection (0.0 à 1.0)
|
||||
|
||||
#### EnrichedScreenState JSON (v1)
|
||||
```json
|
||||
{
|
||||
"schema_version": "screenstate_v1",
|
||||
"mode": "complete",
|
||||
"screen_state_id": "screen_2025-11-21T10-15-32.123Z",
|
||||
"timestamp": "2025-11-21T10:15:32.123Z",
|
||||
"session_id": "session_abc123",
|
||||
|
||||
"environment": {
|
||||
"platform": "windows",
|
||||
"display_scale": 1.0
|
||||
},
|
||||
|
||||
"window": {
|
||||
"app_name": "logiciel_facturation",
|
||||
"window_title": "Factures - Clinique Demo",
|
||||
"screen_resolution": [1920, 1080]
|
||||
},
|
||||
|
||||
"raw": {
|
||||
"screenshot_path": "data/screens/2025-11-21/10-15-32_factures.png"
|
||||
},
|
||||
|
||||
"perception": {
|
||||
"detected_text": [
|
||||
"Factures",
|
||||
"Patient",
|
||||
"Montant",
|
||||
"Statut",
|
||||
"À valider",
|
||||
"Validée"
|
||||
]
|
||||
},
|
||||
|
||||
"ui_elements": [
|
||||
{
|
||||
"schema_version": "uielement_v1",
|
||||
"element_id": "el_btn_valider",
|
||||
"type": "button",
|
||||
"role": "validate_invoice",
|
||||
"bbox": [1600, 900, 1800, 940],
|
||||
"label": "Valider la facture",
|
||||
"confidence": 0.95
|
||||
}
|
||||
],
|
||||
|
||||
"state_embedding": {
|
||||
"provider": "multimodal_fusion_v1",
|
||||
"vector_id": "data/embeddings/screens/state/screen_2025-11-21T10-15-32.123Z.npy",
|
||||
"components": {
|
||||
"image_embedding": {
|
||||
"provider": "openclip_ViT-B-32",
|
||||
"vector_id": "data/embeddings/screens/image/screen_2025-11-21T10-15-32.123Z.npy"
|
||||
},
|
||||
"text_embedding": {
|
||||
"provider": "clip_text",
|
||||
"vector_id": "data/embeddings/screens/text/screen_2025-11-21T10-15-32.123Z.npy"
|
||||
},
|
||||
"title_embedding": {
|
||||
"provider": "clip_text",
|
||||
"vector_id": "data/embeddings/screens/title/screen_2025-11-21T10-15-32.123Z.npy"
|
||||
},
|
||||
"ui_embedding": {
|
||||
"provider": "openclip_ViT-B-32",
|
||||
"vector_id": "data/embeddings/screens/ui/screen_2025-11-21T10-15-32.123Z.npy"
|
||||
},
|
||||
"context_embedding": {
|
||||
"provider": "numeric_context_v1",
|
||||
"vector_id": "data/embeddings/screens/context/screen_2025-11-21T10-15-32.123Z.npy"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"context": {
|
||||
"current_workflow_candidate": "WF_validation_facture",
|
||||
"tags": ["facturation"]
|
||||
},
|
||||
|
||||
"processing_metadata": {
|
||||
"detection_time_ms": 1234,
|
||||
"embedding_time_ms": 567,
|
||||
"num_elements_detected": 1,
|
||||
"vlm_used": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Notes importantes :**
|
||||
- `schema_version` : Permet la compatibilité future et la migration de schémas
|
||||
- `mode` : Indique le niveau de traitement ("light", "enriched", "complete")
|
||||
- `environment` : Informations sur la plateforme et l'échelle d'affichage (crucial pour gérer les différences Windows/Linux/Mac et les DPI)
|
||||
- `state_embedding.components` : Peut être `null` en mode light
|
||||
- `processing_metadata` : Métriques de performance pour monitoring et optimisation (optionnel)
|
||||
|
||||
**Exemples de modes :**
|
||||
|
||||
Mode Light :
|
||||
```json
|
||||
{
|
||||
"schema_version": "screenstate_v1",
|
||||
"mode": "light",
|
||||
"ui_elements": [],
|
||||
"state_embedding": {
|
||||
"provider": "openclip_ViT-B-32",
|
||||
"vector_id": "data/embeddings/screens/image/screen_xxx.npy",
|
||||
"components": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Mode Enriched :
|
||||
```json
|
||||
{
|
||||
"schema_version": "screenstate_v1",
|
||||
"mode": "enriched",
|
||||
"ui_elements": [/* éléments détectés */],
|
||||
"state_embedding": {
|
||||
"provider": "openclip_ViT-B-32",
|
||||
"vector_id": "data/embeddings/screens/image/screen_xxx.npy",
|
||||
"components": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Mode Complete :
|
||||
```json
|
||||
{
|
||||
"schema_version": "screenstate_v1",
|
||||
"mode": "complete",
|
||||
"ui_elements": [/* éléments détectés */],
|
||||
"state_embedding": {
|
||||
"provider": "multimodal_fusion_v1",
|
||||
"vector_id": "data/embeddings/screens/state/screen_xxx.npy",
|
||||
"components": {/* toutes les composantes */}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Gestion des Erreurs
|
||||
|
||||
### Stratégies de Fallback
|
||||
|
||||
1. **Détection d'éléments échoue** → Continuer avec liste vide, utiliser matching legacy
|
||||
2. **VLM indisponible** → Utiliser heuristiques simples uniquement
|
||||
3. **Embedding échoue** → Utiliser embedding par défaut (zéros) avec flag d'avertissement
|
||||
4. **Élément requis manquant** → Passer en mode assisté, demander aide utilisateur
|
||||
|
||||
### Logging et Debug
|
||||
|
||||
- Chaque étape du pipeline doit logger son état
|
||||
- Les échecs de détection doivent être enregistrés avec screenshots
|
||||
- Les scores de matching doivent être tracés pour analyse
|
||||
- Mode debug avec visualisation des bounding boxes détectées
|
||||
|
||||
## Stratégie de Test
|
||||
|
||||
### Tests Unitaires
|
||||
|
||||
1. **RegionProposer**: Tester détection de zones sur images synthétiques
|
||||
2. **ElementCharacterizer**: Vérifier extraction d'embeddings
|
||||
3. **ElementClassifier**: Valider classification de types connus
|
||||
4. **MultiModalEmbeddingManager**: Tester fusion avec poids variés
|
||||
5. **EnhancedWorkflowMatcher**: Vérifier matching élément vs legacy
|
||||
|
||||
### Tests d'Intégration
|
||||
|
||||
1. **Pipeline complet**: Screenshot → UIElements → StateEmbedding
|
||||
2. **Compatibilité**: Anciens workflows fonctionnent toujours
|
||||
3. **Performance**: Temps de traitement < 2s par écran
|
||||
4. **Robustesse**: Variations visuelles (thème, taille) ne cassent pas matching
|
||||
|
||||
### Tests de Propriétés (Property-Based Testing)
|
||||
|
||||
À définir dans la section Correctness Properties ci-dessous.
|
||||
|
||||
|
||||
## Propriétés de Correction
|
||||
|
||||
*Une propriété est une caractéristique ou un comportement qui devrait être vrai pour toutes les exécutions valides d'un système - essentiellement, une déclaration formelle sur ce que le système devrait faire. Les propriétés servent de pont entre les spécifications lisibles par l'humain et les garanties de correction vérifiables par machine.*
|
||||
|
||||
### Propriété 1: Complétude de Détection d'Éléments
|
||||
|
||||
*Pour tout* screenshot contenant des éléments interactifs, le système doit détecter tous les éléments interactifs présents et générer un UIElement pour chacun avec tous les champs requis (element_id, type, role, bbox, label, visual, text, properties, context, tags).
|
||||
|
||||
**Valide: Exigences 1.1, 1.2, 1.3, 1.4, 1.5, 11.2**
|
||||
|
||||
### Propriété 2: Validité des Types d'Éléments
|
||||
|
||||
*Pour tout* UIElement détecté, le champ type doit être l'un des types valides suivants : button, text_input, dropdown, tab, checkbox, radio_button, link, ou generic_interactive.
|
||||
|
||||
**Valide: Exigences 2.1, 2.4**
|
||||
|
||||
### Propriété 3: Présence du Score de Confiance
|
||||
|
||||
*Pour tout* UIElement créé, un score de confiance entre 0.0 et 1.0 doit être assigné et stocké dans le descripteur.
|
||||
|
||||
**Valide: Exigences 2.3, 2.4**
|
||||
|
||||
### Propriété 4: Extraction de Description Sémantique
|
||||
|
||||
*Pour tout* UIElement analysé, une description sémantique non-vide doit être générée par le VLM et stockée dans le descripteur.
|
||||
|
||||
**Valide: Exigences 3.1, 3.2**
|
||||
|
||||
### Propriété 5: Unicité des Identifiants d'Éléments
|
||||
|
||||
*Pour tout* ensemble d'UIElement détectés dans un même screenshot, si deux éléments ont des positions ou labels différents, alors leurs element_id doivent être différents.
|
||||
|
||||
**Valide: Exigences 3.5, 11.1**
|
||||
|
||||
### Propriété 6: Stabilité des Identifiants
|
||||
|
||||
*Pour tout* UIElement créé deux fois avec les mêmes paramètres (app_name, centre_bbox, label_normalized), l'element_id généré doit être identique.
|
||||
|
||||
**Valide: Exigences 11.1**
|
||||
|
||||
### Propriété 7: Structure Complète du State Embedding
|
||||
|
||||
*Pour tout* state_embedding généré, il doit contenir toutes les composantes suivantes : image_embedding, text_embedding, title_embedding, ui_embedding, et context_embedding, chacune avec un provider et un vector_id valides.
|
||||
|
||||
**Valide: Exigences 4.1, 4.5, 12.3, 14.1**
|
||||
|
||||
### Propriété 8: Extraction de Texte Systématique
|
||||
|
||||
*Pour tout* screenshot traité, le système doit extraire le contenu textuel (liste potentiellement vide si aucun texte) et le stocker dans le champ perception.detected_text du ScreenState.
|
||||
|
||||
**Valide: Exigences 4.2, 7.1**
|
||||
|
||||
### Propriété 9: Présence du Titre de Fenêtre
|
||||
|
||||
*Pour tout* ScreenState créé, le champ window.window_title doit être présent et non-null.
|
||||
|
||||
**Valide: Exigences 4.3**
|
||||
|
||||
### Propriété 10: Inclusion du Contexte Workflow
|
||||
|
||||
*Pour tout* ScreenState où le contexte workflow est disponible, ce contexte doit être inclus dans le state_embedding et stocké dans le champ context.
|
||||
|
||||
**Valide: Exigences 4.4, 8.1**
|
||||
|
||||
### Propriété 11: Normalisation des Embeddings
|
||||
|
||||
*Pour tout* state_embedding final généré, la norme L2 du vecteur doit être égale à 1.0 (±0.001 pour tolérance numérique).
|
||||
|
||||
**Valide: Exigences 4.5, 14.4**
|
||||
|
||||
### Propriété 12: Dimension Fixe des Embeddings
|
||||
|
||||
*Pour tout* state_embedding généré, la dimension du vecteur doit être constante et égale à la dimension configurée (ex: 512).
|
||||
|
||||
**Valide: Exigences 5.1**
|
||||
|
||||
### Propriété 13: Robustesse aux Variations Visuelles Légères
|
||||
|
||||
*Pour tout* screenshot S et sa variation légère S' (changement de couleur, taille ±10%, position ±20px), la similarité cosinus entre state_embedding(S) et state_embedding(S') doit être ≥ 0.85.
|
||||
|
||||
**Valide: Exigences 5.3**
|
||||
|
||||
### Propriété 14: Discrimination Sémantique
|
||||
|
||||
*Pour tout* screenshot S1 et screenshot S2 sémantiquement différents (écrans différents, contenus différents), la similarité cosinus entre state_embedding(S1) et state_embedding(S2) doit être ≤ 0.70.
|
||||
|
||||
**Valide: Exigences 5.4**
|
||||
|
||||
### Propriété 15: Association des Empreintes
|
||||
|
||||
*Pour tout* state_embedding stocké, il doit être associé à au moins un workflow_step ou un ScreenState avec un screen_state_id valide.
|
||||
|
||||
**Valide: Exigences 5.5**
|
||||
|
||||
### Propriété 16: Vérification des Éléments Requis
|
||||
|
||||
*Pour tout* workflow avec N éléments requis, si le ScreenState actuel contient moins de N éléments correspondants, alors le score de matching doit être < 0.5 (échec).
|
||||
|
||||
**Valide: Exigences 6.3**
|
||||
|
||||
### Propriété 17: Bonus des Éléments Optionnels
|
||||
|
||||
*Pour tout* workflow avec des éléments optionnels, le score de matching avec tous les éléments optionnels présents doit être strictement supérieur au score sans les éléments optionnels.
|
||||
|
||||
**Valide: Exigences 6.4**
|
||||
|
||||
### Propriété 18: Feedback Détaillé sur Échec
|
||||
|
||||
*Pour tout* échec de matching de workflow, le système doit retourner un MatchResult contenant une liste non-vide de différences détectées (éléments manquants, types incorrects, etc.).
|
||||
|
||||
**Valide: Exigences 6.5**
|
||||
|
||||
### Propriété 19: Préservation des Informations Spatiales du Texte
|
||||
|
||||
*Pour tout* texte détecté dans un screenshot, des coordonnées spatiales (bbox ou position) doivent être stockées avec le texte.
|
||||
|
||||
**Valide: Exigences 7.2**
|
||||
|
||||
### Propriété 20: Association Texte-Élément
|
||||
|
||||
*Pour tout* UIElement contenant du texte visible, ce texte doit être présent dans le champ text.raw du descripteur d'élément.
|
||||
|
||||
**Valide: Exigences 7.3**
|
||||
|
||||
### Propriété 21: Cohérence du Texte Extrait
|
||||
|
||||
*Pour tout* texte extrait d'un screenshot, il doit apparaître à la fois dans perception.detected_text du ScreenState ET dans les descripteurs text.raw des UIElement correspondants.
|
||||
|
||||
**Valide: Exigences 7.5**
|
||||
|
||||
### Propriété 22: Sensibilité au Contexte
|
||||
|
||||
*Pour tout* ScreenState avec contexte C1 et ScreenState avec contexte C2 (où C1 ≠ C2), les state_embedding doivent différer (similarité cosinus < 0.95).
|
||||
|
||||
**Valide: Exigences 8.2**
|
||||
|
||||
### Propriété 23: Robustesse en Absence de Contexte
|
||||
|
||||
*Pour tout* screenshot sans contexte workflow disponible, le système doit quand même générer un state_embedding valide avec dimension correcte et norme unitaire.
|
||||
|
||||
**Valide: Exigences 8.4**
|
||||
|
||||
### Propriété 24: Capture du Contexte d'Enregistrement
|
||||
|
||||
*Pour tout* workflow_step stocké, si un contexte était présent pendant l'enregistrement, ce contexte doit être sauvegardé dans le champ context du step.
|
||||
|
||||
**Valide: Exigences 8.5**
|
||||
|
||||
### Propriété 25: Compatibilité Arrière des Workflows Legacy
|
||||
|
||||
*Pour tout* workflow existant créé avant l'implémentation du système d'éléments, le système doit continuer à le traiter avec le matcher legacy et produire un résultat de matching valide.
|
||||
|
||||
**Valide: Exigences 9.1, 9.2**
|
||||
|
||||
### Propriété 26: Routage Correct des Workflows
|
||||
|
||||
*Pour tout* workflow avec descripteurs d'éléments (has_element_descriptors = true), le système doit utiliser le matcher amélioré ; pour tout workflow sans descripteurs, le système doit utiliser le matcher legacy.
|
||||
|
||||
**Valide: Exigences 9.2, 9.3**
|
||||
|
||||
### Propriété 27: Performance de Détection
|
||||
|
||||
*Pour tout* screenshot typique (1920x1080, 5-20 éléments), le temps de détection d'éléments doit être ≤ 2 secondes.
|
||||
|
||||
**Valide: Exigences 10.1**
|
||||
|
||||
### Propriété 28: Performance de Génération d'Embedding
|
||||
|
||||
*Pour tout* state_embedding généré, le temps de calcul doit être ≤ 1 seconde.
|
||||
|
||||
**Valide: Exigences 10.2**
|
||||
|
||||
### Propriété 29: Performance de Comparaison
|
||||
|
||||
*Pour tout* appel à la fonction de comparaison de state_embedding, le temps d'exécution doit être ≤ 100ms.
|
||||
|
||||
**Valide: Exigences 10.3**
|
||||
|
||||
### Propriété 30: Efficacité du Cache VLM
|
||||
|
||||
*Pour tout* screenshot traité deux fois consécutivement, le temps de traitement de la deuxième extraction de texte VLM doit être ≤ 10% du temps de la première (cache hit).
|
||||
|
||||
**Valide: Exigences 10.4**
|
||||
|
||||
### Propriété 31: Scalabilité des Requêtes
|
||||
|
||||
*Pour tout* base de données d'éléments contenant N éléments (où N ≤ 100,000), le temps de requête pour trouver un élément par element_id doit être ≤ 50ms.
|
||||
|
||||
**Valide: Exigences 10.5**
|
||||
|
||||
### Propriété 32: Complétude de la Structure UIElement
|
||||
|
||||
*Pour tout* UIElement stocké, tous les champs suivants doivent être présents et non-null : element_id, type, role, bbox, label, visual (avec screenshot_path, provider, vector_id), text (avec raw, normalized, provider, vector_id), properties, context, tags.
|
||||
|
||||
**Valide: Exigences 11.2, 11.3, 11.4**
|
||||
|
||||
### Propriété 33: Round-Trip de Sérialisation UIElement
|
||||
|
||||
*Pour tout* UIElement sérialisé en JSON puis désérialisé, l'objet résultant doit être égal à l'objet original (tous les champs identiques).
|
||||
|
||||
**Valide: Exigences 11.5**
|
||||
|
||||
### Propriété 34: Complétude de la Structure ScreenState
|
||||
|
||||
*Pour tout* ScreenState créé, tous les champs suivants doivent être présents : screen_state_id, timestamp, session_id, window, raw, perception, ui_elements, state_embedding, context.
|
||||
|
||||
**Valide: Exigences 12.1**
|
||||
|
||||
### Propriété 35: Stockage des Éléments Détectés
|
||||
|
||||
*Pour tout* ScreenState où des UIElement ont été détectés, ces éléments doivent être présents dans le champ ui_elements (liste non-vide).
|
||||
|
||||
**Valide: Exigences 12.2**
|
||||
|
||||
### Propriété 36: Round-Trip de Sérialisation ScreenState
|
||||
|
||||
*Pour tout* ScreenState sérialisé en JSON puis désérialisé, tous les embeddings doivent pouvoir être reconstruits à partir des vector_id et être identiques aux embeddings originaux (distance L2 < 0.001).
|
||||
|
||||
**Valide: Exigences 12.4, 12.5**
|
||||
|
||||
### Propriété 37: Complétude de la Caractérisation
|
||||
|
||||
*Pour tout* élément caractérisé par le pipeline, les champs suivants doivent être extraits : crop image, embedding image, texte, embedding texte, bbox.
|
||||
|
||||
**Valide: Exigences 13.3**
|
||||
|
||||
### Propriété 38: Complétude de la Classification
|
||||
|
||||
*Pour tout* élément classifié, les champs type et role doivent être présents et non-vides.
|
||||
|
||||
**Valide: Exigences 13.4**
|
||||
|
||||
### Propriété 39: Robustesse du Pipeline
|
||||
|
||||
*Pour tout* screenshot contenant N éléments dont 1 élément problématique (causant une erreur), le pipeline doit quand même produire N-1 UIElement valides pour les autres éléments.
|
||||
|
||||
**Valide: Exigences 13.5**
|
||||
|
||||
### Propriété 40: Normalisation des Composantes
|
||||
|
||||
*Pour tout* state_embedding en cours de génération, chaque composante individuelle (image_embedding, text_embedding, title_embedding, ui_embedding, context_embedding) doit avoir une norme L2 = 1.0 avant fusion.
|
||||
|
||||
**Valide: Exigences 14.2**
|
||||
|
||||
### Propriété 41: Stockage des Composantes
|
||||
|
||||
*Pour tout* state_embedding généré, toutes les composantes individuelles doivent être stockées séparément avec leurs provider et vector_id respectifs.
|
||||
|
||||
**Valide: Exigences 14.5**
|
||||
|
||||
### Propriété 42: Compatibilité de Lecture Multi-Mode
|
||||
|
||||
*Pour tout* fichier de données créé en mode "light", "enrichi" ou "complet", le système doit pouvoir le lire quel que soit le mode actuel, sans erreur de parsing.
|
||||
|
||||
**Valide: Exigences 15.5**
|
||||
|
||||
199
.kiro/specs/ui-element-detection/requirements.md
Normal file
199
.kiro/specs/ui-element-detection/requirements.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Document d'Exigences
|
||||
|
||||
## Introduction
|
||||
|
||||
Cette spécification définit les exigences pour transformer GeniusIA v2 d'un système de comparaison plein écran en une plateforme RPA robuste capable de détecter et d'interagir avec des éléments d'interface individuels via une analyse vision multi-modale. Le système combinera les embeddings visuels (CLIP, Pix2Struct), l'extraction de texte VLM (Qwen3-VL), le contexte de fenêtre et les métadonnées de workflow dans une "empreinte d'état" unifiée permettant une automatisation d'interface précise et fiable.
|
||||
|
||||
## Glossaire
|
||||
|
||||
- **Élément d'UI**: Un composant interactif à l'écran tel qu'un bouton, champ de texte, liste déroulante, onglet, case à cocher ou lien
|
||||
- **Capture Locale**: Une capture d'écran recadrée focalisée sur un élément d'UI spécifique plutôt que sur l'écran complet
|
||||
- **VLM (Vision Language Model)**: Un modèle comme Qwen3-VL capable d'extraire du texte et de décrire du contenu visuel
|
||||
- **Embedding d'État**: Une représentation vectorielle multi-modale combinant informations visuelles, textuelles et contextuelles sur un état d'écran
|
||||
- **Élément Interactif**: Un composant d'UI pouvant recevoir une entrée utilisateur ou déclencher des actions
|
||||
- **Descripteur d'Élément**: Une représentation structurée contenant (capture locale + embedding + description VLM + position)
|
||||
- **Empreinte d'État Unifiée**: Un embedding complet combinant screenshot, texte détecté, titre de fenêtre et contexte workflow
|
||||
- **Système GeniusIA**: Le système d'automatisation RPA en cours d'amélioration
|
||||
- **Gestionnaire d'Embeddings**: Le composant responsable de la génération et gestion des embeddings
|
||||
- **Orchestrateur**: Le composant central qui coordonne la boucle cognitive et la prise de décision
|
||||
|
||||
## Exigences
|
||||
|
||||
### Exigence 1: Détection d'Éléments d'UI
|
||||
|
||||
**User Story:** En tant que développeur RPA, je veux que le système détecte et identifie les éléments d'UI individuels à l'écran, afin de pouvoir interagir avec des boutons, champs et contrôles spécifiques plutôt que de me fier à une correspondance plein écran.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND le système capture une capture d'écran, ALORS le Système GeniusIA DOIT identifier tous les éléments d'UI interactifs présents à l'écran
|
||||
2. QUAND un élément interactif est détecté, ALORS le Système GeniusIA DOIT extraire une capture locale (région recadrée) de cet élément
|
||||
3. QUAND un élément d'UI est traité, ALORS le Système GeniusIA DOIT générer un embedding à partir de la capture locale
|
||||
4. QUAND un élément d'UI est analysé, ALORS le Système GeniusIA DOIT utiliser le VLM pour générer une description textuelle de l'élément
|
||||
5. QUAND les informations d'élément sont stockées, ALORS le Système GeniusIA DOIT créer un Descripteur d'Élément contenant (capture locale, embedding, description VLM, position écran)
|
||||
|
||||
### Exigence 2: Classification d'Éléments
|
||||
|
||||
**User Story:** En tant que développeur RPA, je veux que le système classifie les éléments d'UI par type, afin de pouvoir appliquer des stratégies d'interaction appropriées pour les boutons, champs, listes et autres contrôles.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND un élément d'UI est détecté, ALORS le Système GeniusIA DOIT le classifier dans l'un des types suivants : bouton, champ de texte, liste déroulante, onglet, case à cocher, bouton radio, lien, ou élément interactif générique
|
||||
2. QUAND un élément est classifié, ALORS le Système GeniusIA DOIT utiliser à la fois les caractéristiques visuelles et l'analyse textuelle VLM
|
||||
3. QUAND le type d'élément est ambigu, ALORS le Système GeniusIA DOIT assigner un score de confiance à la classification
|
||||
4. QUAND les données d'élément sont stockées, ALORS le Système GeniusIA DOIT inclure le type d'élément et le score de confiance dans le Descripteur d'Élément
|
||||
|
||||
### Exigence 3: Compréhension Sémantique des Éléments
|
||||
|
||||
**User Story:** En tant que développeur RPA, je veux que le système comprenne ce que fait chaque élément d'UI, afin que les workflows puissent référencer les éléments par leur signification sémantique plutôt que par des coordonnées de pixels.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND un élément d'UI est analysé, ALORS le VLM DOIT générer une description sémantique telle que "Bouton 'Valider la facture' en bas à droite"
|
||||
2. QUAND la sémantique d'élément est extraite, ALORS le Système GeniusIA DOIT identifier le label ou le contenu textuel de l'élément
|
||||
3. QUAND le but de l'élément est déterminé, ALORS le Système GeniusIA DOIT inférer l'action ou la fonction à partir d'indices visuels et textuels
|
||||
4. QUAND la localisation de l'élément est décrite, ALORS le Système GeniusIA DOIT fournir des informations de position relative (haut/bas, gauche/droite, près d'autres éléments)
|
||||
5. QUAND plusieurs éléments similaires existent, ALORS le Système GeniusIA DOIT les différencier en utilisant des informations spatiales et contextuelles
|
||||
|
||||
### Exigence 4: Embedding d'État Multi-Modal
|
||||
|
||||
**User Story:** En tant que développeur RPA, je veux que le système crée un embedding unifié combinant toutes les informations disponibles sur l'état de l'écran, afin que la correspondance de workflow soit robuste face aux variations visuelles.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND un embedding d'état est généré, ALORS le Gestionnaire d'Embeddings DOIT combiner l'embedding visuel du screenshot, le texte extrait par VLM, le titre de fenêtre et le contexte workflow en un seul vecteur unifié
|
||||
2. QUAND un screenshot est traité, ALORS le Système GeniusIA DOIT extraire le contenu textuel en utilisant le VLM
|
||||
3. QUAND l'état d'écran est capturé, ALORS le Système GeniusIA DOIT inclure le titre de la fenêtre active
|
||||
4. OÙ le contexte workflow est disponible, ALORS le Système GeniusIA DOIT inclure les métadonnées contextuelles (ID patient, numéro de facture, type de document, etc.)
|
||||
5. QUAND l'embedding unifié est créé, ALORS le Gestionnaire d'Embeddings DOIT normaliser et pondérer chaque modalité de manière appropriée
|
||||
|
||||
### Exigence 5: Génération d'Empreinte d'État
|
||||
|
||||
**User Story:** En tant que développeur RPA, je veux que chaque état d'écran ait une empreinte unique et robuste, afin que le système puisse reconnaître de manière fiable les états même lorsque l'apparence visuelle varie légèrement.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND une empreinte d'état est générée, ALORS le Gestionnaire d'Embeddings DOIT produire une représentation vectorielle de dimension fixe
|
||||
2. QUAND des empreintes d'état sont comparées, ALORS le Système GeniusIA DOIT utiliser la similarité cosinus ou une métrique de distance équivalente
|
||||
3. QUAND les éléments visuels changent légèrement (couleur, taille, position), ALORS l'empreinte d'état DOIT rester suffisamment similaire pour la correspondance
|
||||
4. QUAND le contenu sémantique change significativement, ALORS l'empreinte d'état DOIT différer suffisamment pour éviter les fausses correspondances
|
||||
5. QUAND les empreintes d'état sont stockées, ALORS le Système GeniusIA DOIT les associer aux étapes de workflow et aux descripteurs d'éléments
|
||||
|
||||
### Exigence 6: Correspondance de Workflow au Niveau Élément
|
||||
|
||||
**User Story:** En tant que développeur RPA, je veux que les workflows correspondent en fonction de la présence et de l'état d'éléments d'UI spécifiques, afin que l'automatisation soit plus fiable que la comparaison d'images plein écran.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND une étape de workflow est mise en correspondance, ALORS le Système GeniusIA DOIT comparer les éléments d'UI détectés aux éléments attendus pour cette étape
|
||||
2. QUAND une correspondance est évaluée, ALORS le Système GeniusIA DOIT considérer le type d'élément, la description sémantique et la position
|
||||
3. QUAND plusieurs éléments sont requis, ALORS le Système GeniusIA DOIT vérifier que tous les éléments requis sont présents
|
||||
4. QUAND des éléments optionnels existent, ALORS le Système GeniusIA DOIT augmenter la confiance de correspondance s'ils sont présents
|
||||
5. QUAND des éléments sont manquants ou ne correspondent pas, ALORS le Système GeniusIA DOIT fournir un retour détaillé sur ce qui diffère
|
||||
|
||||
### Exigence 7: Intégration VLM pour l'Extraction de Texte
|
||||
|
||||
**User Story:** En tant que développeur RPA, je veux que le système extraie tout le texte visible des screenshots en utilisant le VLM, afin que le contenu textuel puisse être utilisé pour la correspondance et la prise de décision.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND un screenshot est traité, ALORS le Système GeniusIA DOIT utiliser Qwen3-VL pour extraire tout le texte visible
|
||||
2. QUAND du texte est détecté, ALORS le Système GeniusIA DOIT préserver les informations spatiales sur l'emplacement du texte
|
||||
3. QUAND du texte est extrait d'éléments d'UI, ALORS le Système GeniusIA DOIT associer le texte à l'élément correspondant
|
||||
4. QUAND l'extraction de texte échoue ou est ambiguë, ALORS le Système GeniusIA DOIT enregistrer le problème et continuer le traitement
|
||||
5. QUAND le texte extrait est stocké, ALORS le Système GeniusIA DOIT l'inclure à la fois dans les descripteurs d'éléments et les embeddings d'état
|
||||
|
||||
### Exigence 8: Représentation d'État Contextuelle
|
||||
|
||||
**User Story:** En tant que développeur RPA, je veux que le système inclue le contexte workflow dans les représentations d'état, afin que le même écran visuel puisse être interprété différemment selon la tâche en cours.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. OÙ le contexte workflow est disponible (ID patient, numéro de facture, type de document), ALORS le Système GeniusIA DOIT l'inclure dans l'embedding d'état
|
||||
2. QUAND le contexte change, ALORS l'empreinte d'état DOIT refléter la différence contextuelle
|
||||
3. QUAND des états sont comparés, ALORS le Système GeniusIA DOIT pondérer la similarité contextuelle de manière appropriée
|
||||
4. QUAND le contexte est manquant, ALORS le Système GeniusIA DOIT quand même générer un embedding d'état valide en utilisant les informations disponibles
|
||||
5. QUAND les étapes de workflow sont stockées, ALORS le Système GeniusIA DOIT capturer le contexte qui était présent pendant l'enregistrement
|
||||
|
||||
### Exigence 9: Compatibilité Arrière
|
||||
|
||||
**User Story:** En tant que mainteneur système, je veux que la nouvelle détection au niveau élément coexiste avec la correspondance plein écran existante, afin de pouvoir migrer progressivement sans casser les workflows existants.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND le système de détection d'éléments est activé, ALORS le Système GeniusIA DOIT continuer à supporter les workflows de correspondance plein écran existants
|
||||
2. QUAND un workflow utilise des captures plein écran de l'ancien style, ALORS le Système GeniusIA DOIT les traiter en utilisant le système de correspondance legacy
|
||||
3. QUAND un workflow utilise de nouveaux descripteurs au niveau élément, ALORS le Système GeniusIA DOIT utiliser le système de correspondance amélioré
|
||||
4. QUAND des workflows sont migrés, ALORS le Système GeniusIA DOIT fournir des outils pour convertir les workflows plein écran en workflows au niveau élément
|
||||
5. QUAND les deux systèmes sont actifs, ALORS le Système GeniusIA DOIT permettre la configuration pour préférer une approche plutôt que l'autre
|
||||
|
||||
### Exigence 10: Performance et Scalabilité
|
||||
|
||||
**User Story:** En tant qu'administrateur système, je veux que la détection d'éléments et l'embedding multi-modal soient performants, afin que le système RPA reste réactif pendant l'automatisation.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND des éléments d'UI sont détectés, ALORS le Système GeniusIA DOIT compléter le traitement en moins de 2 secondes pour un écran typique
|
||||
2. QUAND des embeddings d'état sont générés, ALORS le Gestionnaire d'Embeddings DOIT compléter le traitement en moins de 1 seconde
|
||||
3. QUAND des empreintes d'état sont comparées, ALORS le Système GeniusIA DOIT effectuer la recherche de similarité en moins de 100ms
|
||||
4. QUAND l'extraction de texte VLM est traitée, ALORS le Système GeniusIA DOIT mettre en cache les résultats pour éviter un traitement redondant
|
||||
5. QUAND la base de données d'éléments devient volumineuse, ALORS le Système GeniusIA DOIT maintenir la performance des requêtes via une indexation appropriée
|
||||
|
||||
### Exigence 11: Structure de Données UIElement
|
||||
|
||||
**User Story:** En tant que développeur système, je veux une structure de données standardisée pour les éléments d'UI, afin de pouvoir stocker, rechercher et manipuler les éléments de manière cohérente.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND un UIElement est créé, ALORS le Système GeniusIA DOIT lui assigner un identifiant stable basé sur (app_name + centre_bbox + label_normalized)
|
||||
2. QUAND un UIElement est stocké, ALORS le Système GeniusIA DOIT inclure les champs suivants : element_id, type, role, bbox, label, visual (screenshot_path + embedding), text (raw + normalized + embedding), properties (is_clickable, is_focusable, is_dangerous), context (app_name, window_title, workflow_hint), et tags
|
||||
3. QUAND un embedding visuel d'élément est généré, ALORS le Système GeniusIA DOIT stocker le provider (ex: openclip_ViT-B-32) et le vector_id (chemin vers le fichier .npy)
|
||||
4. QUAND un embedding textuel d'élément est généré, ALORS le Système GeniusIA DOIT stocker le texte brut, le texte normalisé, le provider et le vector_id
|
||||
5. QUAND un UIElement est sérialisé, ALORS le Système GeniusIA DOIT utiliser le format JSON avec tous les champs requis
|
||||
|
||||
### Exigence 12: Structure de Données ScreenState Enrichi
|
||||
|
||||
**User Story:** En tant que développeur système, je veux que le ScreenState contienne à la fois les éléments d'UI détectés et l'embedding d'état unifié, afin d'avoir une représentation complète de l'écran.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND un ScreenState est créé, ALORS le Système GeniusIA DOIT inclure les champs suivants : screen_state_id, timestamp, session_id, window (app_name, window_title, screen_resolution), raw (screenshot_path), perception (detected_text), ui_elements (liste), state_embedding (provider, vector_id, components), et context
|
||||
2. QUAND des éléments d'UI sont détectés, ALORS le Système GeniusIA DOIT les stocker dans le champ ui_elements du ScreenState
|
||||
3. QUAND un state_embedding est généré, ALORS le Système GeniusIA DOIT stocker le vecteur final ainsi que ses composantes (image_embedding, text_embedding, title_embedding, ui_embedding, context_embedding)
|
||||
4. QUAND un ScreenState est sérialisé, ALORS le Système GeniusIA DOIT utiliser le format JSON avec tous les champs requis
|
||||
5. QUAND un ScreenState est chargé, ALORS le Système GeniusIA DOIT pouvoir reconstruire tous les embeddings à partir des vector_id stockés
|
||||
|
||||
### Exigence 13: Pipeline de Détection d'Éléments
|
||||
|
||||
**User Story:** En tant que développeur système, je veux un pipeline clair pour transformer un screenshot en liste d'UIElement, afin de pouvoir maintenir et améliorer le processus de détection.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND un screenshot est capturé, ALORS le Système GeniusIA DOIT exécuter les étapes suivantes dans l'ordre : (1) proposer des régions d'intérêt, (2) caractériser chaque élément, (3) classifier type et rôle
|
||||
2. QUAND des régions d'intérêt sont proposées, ALORS le Système GeniusIA DOIT utiliser au moins une des méthodes suivantes : détection de zones de texte, repérage de rectangles autour de texte, ou requête VLM pour zones cliquables
|
||||
3. QUAND un élément est caractérisé, ALORS le Système GeniusIA DOIT extraire : crop image de la zone, embedding image, texte dans/autour de la zone, embedding texte, et position bbox
|
||||
4. QUAND un élément est classifié, ALORS le Système GeniusIA DOIT déterminer le type (button, text_input, checkbox, etc.) et le rôle sémantique (primary_action, dangerous_action, search_field, etc.)
|
||||
5. QUAND le pipeline échoue sur un élément, ALORS le Système GeniusIA DOIT enregistrer l'erreur et continuer avec les autres éléments
|
||||
|
||||
### Exigence 14: Pipeline de Fusion Multi-Modale
|
||||
|
||||
**User Story:** En tant que développeur système, je veux un pipeline clair pour créer un state_embedding à partir de multiples modalités, afin de pouvoir ajuster les pondérations et améliorer la robustesse.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND un state_embedding est généré, ALORS le Système GeniusIA DOIT calculer les composantes suivantes : image_embedding (screenshot entier), text_embedding (texte concaténé détecté), title_embedding (window_title), ui_embedding (moyenne des embeddings d'éléments importants), et context_embedding (vecteur de contexte workflow)
|
||||
2. QUAND les composantes sont fusionnées, ALORS le Gestionnaire d'Embeddings DOIT normaliser chaque vecteur avant fusion
|
||||
3. QUAND la fusion est effectuée, ALORS le Gestionnaire d'Embeddings DOIT utiliser une combinaison pondérée avec les poids configurables suivants par défaut : w_img=0.5, w_text=0.3, w_title=0.1, w_ui=0.1, w_ctx=0.1
|
||||
4. QUAND le vecteur final est produit, ALORS le Gestionnaire d'Embeddings DOIT le normaliser pour avoir une norme unitaire
|
||||
5. QUAND les composantes individuelles sont calculées, ALORS le Système GeniusIA DOIT les stocker séparément pour permettre le debug et l'analyse
|
||||
|
||||
### Exigence 15: Implémentation Progressive
|
||||
|
||||
**User Story:** En tant que mainteneur système, je veux pouvoir activer les nouvelles fonctionnalités progressivement, afin de minimiser les risques et de valider chaque étape.
|
||||
|
||||
#### Critères d'Acceptation
|
||||
|
||||
1. QUAND le système est en mode "light", ALORS le Système GeniusIA DOIT ajouter les champs ui_elements (vide) et state_embedding (image uniquement) au JSON sans changer la logique existante
|
||||
2. QUAND le système est en mode "enrichi", ALORS le Système GeniusIA DOIT détecter les UIElement pour certains écrans configurés tout en maintenant la compatibilité avec le mode light
|
||||
3. QUAND le système est en mode "complet", ALORS le Système GeniusIA DOIT calculer le state_embedding fusionné avec toutes les modalités
|
||||
4. QUAND un mode est activé, ALORS le Système GeniusIA DOIT permettre la configuration via un fichier de configuration ou des variables d'environnement
|
||||
5. QUAND un mode change, ALORS le Système GeniusIA DOIT continuer à lire les anciens formats de données tout en écrivant dans le nouveau format
|
||||
388
.kiro/specs/ui-element-detection/tasks.md
Normal file
388
.kiro/specs/ui-element-detection/tasks.md
Normal file
@@ -0,0 +1,388 @@
|
||||
# Plan d'Implémentation - Détection d'Éléments UI et Fusion Multi-Modale
|
||||
|
||||
## Vue d'Ensemble
|
||||
|
||||
Ce plan implémente progressivement le système de détection d'éléments UI et de fusion multi-modale en 3 phases :
|
||||
- **Phase 1 (Light)** : Structures de données et mode minimal
|
||||
- **Phase 2 (Enrichi)** : Détection d'éléments basique
|
||||
- **Phase 3 (Complet)** : Fusion multi-modale complète
|
||||
|
||||
## Tâches
|
||||
|
||||
- [x] 1. Phase 1 - Mode Light : Structures de Données de Base
|
||||
- Créer les structures de données UIElement et EnrichedScreenState
|
||||
- Ajouter les champs au JSON sans changer la logique existante
|
||||
- Permettre la compatibilité arrière complète
|
||||
- _Exigences: 11.1, 11.2, 11.5, 12.1, 12.4, 15.1_
|
||||
|
||||
- [x] 1.1 Créer les dataclasses pour UIElement
|
||||
- Implémenter UIElement avec tous les champs (element_id, type, role, bbox, label, visual, text, properties, context, tags)
|
||||
- Implémenter les sous-structures (VisualData, TextData, ElementProperties, ElementContext)
|
||||
- Ajouter les méthodes de sérialisation/désérialisation JSON
|
||||
- Implémenter la génération d'element_id stable basée sur hash(app_name + center_bbox + label_normalized)
|
||||
- _Exigences: 11.1, 11.2, 11.3, 11.4, 11.5_
|
||||
|
||||
- [ ]* 1.2 Écrire les tests de propriété pour UIElement
|
||||
- **Propriété 6: Stabilité des identifiants** - Pour tout UIElement créé deux fois avec mêmes paramètres, l'element_id doit être identique
|
||||
- **Propriété 32: Complétude de la structure UIElement** - Tous les champs requis doivent être présents
|
||||
- **Propriété 33: Round-trip de sérialisation UIElement** - Sérialisation puis désérialisation doit préserver tous les champs
|
||||
- _Valide: Exigences 11.1, 11.2, 11.5_
|
||||
|
||||
- [x] 1.3 Créer les dataclasses pour EnrichedScreenState
|
||||
- Implémenter EnrichedScreenState avec tous les champs (screen_state_id, timestamp, session_id, window, raw, perception, ui_elements, state_embedding, context)
|
||||
- Implémenter les sous-structures (WindowInfo, RawData, PerceptionData, StateEmbedding, EmbeddingComponents, ContextData)
|
||||
- Ajouter les méthodes de sérialisation/désérialisation JSON
|
||||
- Assurer la compatibilité avec l'ancien format ScreenState
|
||||
- _Exigences: 12.1, 12.2, 12.3, 12.4_
|
||||
|
||||
- [ ]* 1.4 Écrire les tests de propriété pour EnrichedScreenState
|
||||
- **Propriété 34: Complétude de la structure ScreenState** - Tous les champs requis doivent être présents
|
||||
- **Propriété 36: Round-trip de sérialisation ScreenState** - Les embeddings doivent être reconstruits correctement
|
||||
- **Propriété 42: Compatibilité de lecture multi-mode** - Lecture des anciens formats sans erreur
|
||||
- _Valide: Exigences 12.1, 12.4, 12.5, 15.5_
|
||||
|
||||
- [x] 1.5 Intégrer les nouvelles structures dans le système existant
|
||||
- Modifier le code existant pour utiliser EnrichedScreenState au lieu de ScreenState
|
||||
- Initialiser ui_elements comme liste vide par défaut
|
||||
- Initialiser state_embedding avec image_embedding uniquement (mode light)
|
||||
- Assurer que tous les workflows existants continuent de fonctionner
|
||||
- _Exigences: 9.1, 15.1_
|
||||
|
||||
- [ ]* 1.6 Écrire les tests de compatibilité arrière
|
||||
- **Propriété 25: Compatibilité arrière des workflows legacy** - Les anciens workflows doivent continuer à fonctionner
|
||||
- Tester que les anciens fichiers JSON sont lisibles
|
||||
- Tester que les nouveaux fichiers sont écrits avec les nouveaux champs
|
||||
- _Valide: Exigences 9.1, 9.2, 15.1_
|
||||
|
||||
- [x] 2. Checkpoint - Vérifier que le mode Light fonctionne
|
||||
- Assurer que tous les tests passent
|
||||
- Vérifier que les workflows existants fonctionnent toujours
|
||||
- Demander à l'utilisateur si des questions se posent
|
||||
|
||||
- [x] 3. Phase 2 - Mode Enrichi : Détection d'Éléments Basique
|
||||
- Implémenter le pipeline de détection d'éléments
|
||||
- Détecter les éléments pour certains écrans configurés
|
||||
- Maintenir la compatibilité avec le mode light
|
||||
- _Exigences: 1.1, 1.2, 1.3, 1.4, 1.5, 13.1, 13.2, 13.3, 13.4, 13.5, 15.2_
|
||||
|
||||
- [x] 3.1 Créer le composant RegionProposer
|
||||
- Implémenter la détection de zones de texte (méthode rapide)
|
||||
- Implémenter la détection de rectangles autour de texte (heuristique)
|
||||
- Implémenter la requête VLM conditionnelle pour zones cliquables (coûteux)
|
||||
- Implémenter la fusion et le nettoyage des régions (merge overlapping, filter invalid)
|
||||
- Implémenter la logique _should_use_vlm pour décider quand utiliser le VLM
|
||||
- _Exigences: 13.2_
|
||||
|
||||
- [ ]* 3.2 Écrire les tests pour RegionProposer
|
||||
- Tester la détection de zones de texte sur images synthétiques
|
||||
- Tester la fusion de régions qui se chevauchent
|
||||
- Tester le filtrage de régions invalides (trop petites, hors écran)
|
||||
- _Valide: Exigences 13.2_
|
||||
|
||||
- [x] 3.3 Créer le composant ElementCharacterizer
|
||||
- Implémenter l'extraction de crop image pour chaque région
|
||||
- Implémenter la génération d'embedding image via CLIP
|
||||
- Implémenter l'extraction de texte dans/autour de la région via VLM
|
||||
- Implémenter la génération d'embedding texte
|
||||
- Implémenter l'extraction de position bbox
|
||||
- _Exigences: 1.2, 1.3, 1.4, 13.3_
|
||||
|
||||
- [ ]* 3.4 Écrire les tests de propriété pour ElementCharacterizer
|
||||
- **Propriété 1: Complétude de détection d'éléments** - Tous les champs requis doivent être extraits
|
||||
- **Propriété 37: Complétude de la caractérisation** - Crop, embeddings, texte, bbox doivent être présents
|
||||
- _Valide: Exigences 1.2, 1.3, 1.4, 13.3_
|
||||
|
||||
- [x] 3.5 Créer le composant ElementClassifier
|
||||
- Implémenter la classification de type (button, text_input, checkbox, etc.)
|
||||
- Implémenter l'inférence de rôle sémantique (primary_action, dangerous_action, search_field, etc.)
|
||||
- Implémenter l'assignation de score de confiance
|
||||
- Utiliser les caractéristiques visuelles et l'analyse textuelle VLM
|
||||
- _Exigences: 2.1, 2.3, 2.4, 13.4_
|
||||
|
||||
- [ ]* 3.6 Écrire les tests de propriété pour ElementClassifier
|
||||
- **Propriété 2: Validité des types d'éléments** - Le type doit être l'un des types valides
|
||||
- **Propriété 3: Présence du score de confiance** - Score entre 0.0 et 1.0 doit être assigné
|
||||
- **Propriété 38: Complétude de la classification** - Type et rôle doivent être présents
|
||||
- _Valide: Exigences 2.1, 2.3, 2.4, 13.4_
|
||||
|
||||
- [x] 3.7 Créer le composant UIElementDetector principal
|
||||
- Implémenter la méthode detect_elements qui orchestre le pipeline complet
|
||||
- Intégrer RegionProposer, ElementCharacterizer et ElementClassifier
|
||||
- Implémenter la gestion d'erreurs (continuer si un élément échoue)
|
||||
- Implémenter le logging détaillé de chaque étape
|
||||
- _Exigences: 1.1, 13.1, 13.5_
|
||||
|
||||
- [ ]* 3.8 Écrire les tests de propriété pour UIElementDetector
|
||||
- **Propriété 1: Complétude de détection d'éléments** - Tous les éléments interactifs doivent être détectés
|
||||
- **Propriété 39: Robustesse du pipeline** - Si 1 élément échoue, les N-1 autres doivent être produits
|
||||
- _Valide: Exigences 1.1, 13.5_
|
||||
|
||||
- [x] 3.9 Intégrer UIElementDetector dans l'Orchestrator
|
||||
- Ajouter un appel à UIElementDetector.detect_elements lors de la capture d'écran
|
||||
- Stocker les UIElement détectés dans EnrichedScreenState.ui_elements
|
||||
- Ajouter une configuration pour activer/désactiver la détection (mode enrichi)
|
||||
- Implémenter la détection conditionnelle (seulement pour certains écrans configurés)
|
||||
- _Exigences: 15.2_
|
||||
|
||||
- [ ]* 3.10 Écrire les tests d'intégration pour la détection
|
||||
- Tester le pipeline complet : screenshot → UIElements
|
||||
- Tester avec différents types d'écrans (formulaires, tableaux, menus)
|
||||
- Tester la performance (< 2 secondes pour écran typique)
|
||||
- _Valide: Exigences 1.1, 10.1_
|
||||
|
||||
- [x] 4. Checkpoint - Vérifier que le mode Enrichi fonctionne
|
||||
- Assurer que tous les tests passent
|
||||
- Vérifier que les éléments sont détectés correctement sur des écrans de test
|
||||
- Demander à l'utilisateur si des questions se posent
|
||||
|
||||
- [x] 5. Phase 3 - Mode Complet : Fusion Multi-Modale
|
||||
- Implémenter le gestionnaire d'embeddings multi-modaux
|
||||
- Calculer le state_embedding fusionné avec toutes les modalités
|
||||
- Intégrer dans le workflow matcher
|
||||
- _Exigences: 4.1, 4.2, 4.3, 4.4, 4.5, 5.1, 5.2, 5.3, 5.4, 14.1, 14.2, 14.3, 14.4, 14.5, 15.3_
|
||||
|
||||
- [x] 5.1 Créer le composant MultiModalEmbeddingManager
|
||||
- Implémenter la méthode create_state_embedding
|
||||
- Calculer image_embedding (screenshot entier via CLIP)
|
||||
- Calculer text_embedding (texte concaténé via CLIP text)
|
||||
- Calculer title_embedding (window_title via CLIP text)
|
||||
- Calculer ui_embedding (moyenne des embeddings d'éléments importants)
|
||||
- Calculer context_embedding (vecteur de contexte workflow)
|
||||
- _Exigences: 4.1, 4.2, 4.3, 4.4, 14.1_
|
||||
|
||||
- [ ]* 5.2 Écrire les tests de propriété pour les composantes individuelles
|
||||
- **Propriété 7: Structure complète du state embedding** - Toutes les composantes doivent être présentes
|
||||
- **Propriété 8: Extraction de texte systématique** - Le texte doit être extrait pour tout screenshot
|
||||
- **Propriété 9: Présence du titre de fenêtre** - window_title doit être présent
|
||||
- **Propriété 10: Inclusion du contexte workflow** - Le contexte doit être inclus si disponible
|
||||
- _Valide: Exigences 4.1, 4.2, 4.3, 4.4, 14.1_
|
||||
|
||||
- [x] 5.3 Implémenter la normalisation des composantes
|
||||
- Normaliser chaque vecteur individuel (norme L2 = 1.0) avant fusion
|
||||
- Implémenter la méthode _normalize
|
||||
- Ajouter des assertions pour vérifier la normalisation
|
||||
- _Exigences: 4.5, 14.2_
|
||||
|
||||
- [ ]* 5.4 Écrire les tests de propriété pour la normalisation
|
||||
- **Propriété 40: Normalisation des composantes** - Chaque composante doit avoir norme L2 = 1.0 avant fusion
|
||||
- Tester avec différents vecteurs d'entrée
|
||||
- _Valide: Exigences 14.2_
|
||||
|
||||
- [x] 5.5 Implémenter la fusion pondérée des composantes
|
||||
- Implémenter la combinaison pondérée avec poids configurables
|
||||
- Poids par défaut : w_img=0.5, w_text=0.3, w_title=0.1, w_ui=0.1, w_ctx=0.1
|
||||
- Normaliser le vecteur final (norme L2 = 1.0)
|
||||
- Stocker les composantes individuelles séparément pour debug
|
||||
- _Exigences: 4.5, 14.3, 14.4, 14.5_
|
||||
|
||||
- [ ]* 5.6 Écrire les tests de propriété pour la fusion
|
||||
- **Propriété 11: Normalisation des embeddings** - Le vecteur final doit avoir norme L2 = 1.0
|
||||
- **Propriété 12: Dimension fixe des embeddings** - La dimension doit être constante
|
||||
- **Propriété 41: Stockage des composantes** - Les composantes doivent être stockées séparément
|
||||
- _Valide: Exigences 4.5, 5.1, 14.4, 14.5_
|
||||
|
||||
- [x] 5.7 Implémenter le calcul de ui_embedding
|
||||
- Filtrer les éléments importants (primary_action, is_clickable)
|
||||
- Calculer la moyenne des embeddings visuels
|
||||
- Gérer le cas où aucun élément n'est présent (retourner vecteur zéro)
|
||||
- _Exigences: 14.1_
|
||||
|
||||
- [x] 5.8 Implémenter le calcul de context_embedding
|
||||
- Encoder les métadonnées de contexte (workflow_id, flags métier)
|
||||
- Projeter en vecteur de dimension appropriée
|
||||
- Gérer le cas où le contexte est manquant
|
||||
- _Exigences: 4.4, 8.1, 8.4_
|
||||
|
||||
- [ ]* 5.9 Écrire les tests de propriété pour le contexte
|
||||
- **Propriété 22: Sensibilité au contexte** - Contextes différents doivent produire embeddings différents
|
||||
- **Propriété 23: Robustesse en absence de contexte** - Un embedding valide doit être généré même sans contexte
|
||||
- _Valide: Exigences 8.2, 8.4_
|
||||
|
||||
- [x] 5.10 Intégrer MultiModalEmbeddingManager dans l'Orchestrator
|
||||
- Appeler create_state_embedding lors de la capture d'écran
|
||||
- Stocker le state_embedding dans EnrichedScreenState
|
||||
- Ajouter une configuration pour activer/désactiver la fusion multi-modale (mode complet)
|
||||
- _Exigences: 15.3_
|
||||
|
||||
- [ ]* 5.11 Écrire les tests d'intégration pour la fusion multi-modale
|
||||
- Tester le pipeline complet : screenshot → state_embedding fusionné
|
||||
- Tester la performance (< 1 seconde pour génération d'embedding)
|
||||
- _Valide: Exigences 10.2_
|
||||
|
||||
- [x] 6. Checkpoint - Vérifier que le mode Complet fonctionne
|
||||
- Assurer que tous les tests passent
|
||||
- Vérifier que les state_embeddings sont générés correctement
|
||||
- Demander à l'utilisateur si des questions se posent
|
||||
|
||||
- [-] 7. Améliorer le WorkflowMatcher pour utiliser les éléments
|
||||
- Créer EnhancedWorkflowMatcher qui supporte le matching au niveau élément
|
||||
- Maintenir le matcher legacy pour compatibilité
|
||||
- Implémenter le routage automatique (legacy vs enhanced)
|
||||
- _Exigences: 6.1, 6.2, 6.3, 6.4, 6.5, 9.2, 9.3_
|
||||
|
||||
- [ ] 7.1 Créer la classe EnhancedWorkflowMatcher
|
||||
- Implémenter match_workflow_step qui route vers matching élément ou legacy
|
||||
- Implémenter _has_element_descriptors pour détecter le type de workflow
|
||||
- Implémenter _match_by_elements pour matching basé sur éléments
|
||||
- Implémenter _match_legacy pour compatibilité arrière
|
||||
- _Exigences: 6.1, 9.2, 9.3_
|
||||
|
||||
- [ ]* 7.2 Écrire les tests de propriété pour le routage
|
||||
- **Propriété 26: Routage correct des workflows** - Workflows avec descripteurs → matcher amélioré, sans → legacy
|
||||
- Tester avec différents types de workflows
|
||||
- _Valide: Exigences 9.2, 9.3_
|
||||
|
||||
- [x] 7.3 Implémenter la comparaison de state_embeddings
|
||||
- Calculer la similarité cosinus entre embeddings
|
||||
- Implémenter _compare_state_embeddings
|
||||
- Retourner un score entre 0.0 et 1.0
|
||||
- _Exigences: 5.2, 6.2_
|
||||
|
||||
- [ ]* 7.4 Écrire les tests de propriété pour la comparaison
|
||||
- **Propriété 13: Robustesse aux variations visuelles légères** - Similarité ≥ 0.85 pour variations légères
|
||||
- **Propriété 14: Discrimination sémantique** - Similarité ≤ 0.70 pour écrans différents
|
||||
- Tester la performance (< 100ms par comparaison)
|
||||
- _Valide: Exigences 5.2, 5.3, 5.4, 10.3_
|
||||
|
||||
- [x] 7.5 Implémenter la comparaison d'éléments requis
|
||||
- Implémenter _compare_required_elements
|
||||
- Implémenter _elements_match pour vérifier correspondance type/rôle/sémantique/position
|
||||
- Calculer le score de correspondance (nombre d'éléments matchés / nombre requis)
|
||||
- _Exigences: 6.1, 6.2, 6.3_
|
||||
|
||||
- [ ]* 7.6 Écrire les tests de propriété pour la correspondance d'éléments
|
||||
- **Propriété 16: Vérification des éléments requis** - Score < 0.5 si éléments manquants
|
||||
- **Propriété 17: Bonus des éléments optionnels** - Score augmente avec éléments optionnels
|
||||
- _Valide: Exigences 6.3, 6.4_
|
||||
|
||||
- [x] 7.7 Implémenter le feedback détaillé sur échec
|
||||
- Créer MatchResult avec liste de différences
|
||||
- Identifier les éléments manquants, types incorrects, positions incorrectes
|
||||
- Formater un message d'erreur lisible
|
||||
- _Exigences: 6.5_
|
||||
|
||||
- [ ]* 7.8 Écrire les tests de propriété pour le feedback
|
||||
- **Propriété 18: Feedback détaillé sur échec** - Liste non-vide de différences pour tout échec
|
||||
- Tester avec différents types d'échecs
|
||||
- _Valide: Exigences 6.5_
|
||||
|
||||
- [x] 7.9 Intégrer EnhancedWorkflowMatcher dans l'Orchestrator
|
||||
- Remplacer l'ancien WorkflowMatcher par EnhancedWorkflowMatcher
|
||||
- Passer le legacy_matcher en paramètre pour compatibilité
|
||||
- Configurer les poids de matching (weight_state, weight_elements)
|
||||
- _Exigences: 9.1, 9.2, 9.3_
|
||||
|
||||
- [x] 7.10 Écrire les tests d'intégration pour le matching
|
||||
- Tester le matching avec workflows legacy (compatibilité)
|
||||
- Tester le matching avec workflows enrichis (éléments)
|
||||
- Tester le routage automatique
|
||||
- _Valide: Exigences 9.1, 9.2, 9.3_
|
||||
|
||||
- [x] 8. Checkpoint - Vérifier que le matching amélioré fonctionne
|
||||
- Assurer que tous les tests passent
|
||||
- Vérifier que les workflows legacy fonctionnent toujours
|
||||
- Vérifier que les nouveaux workflows utilisent le matching amélioré
|
||||
- Demander à l'utilisateur si des questions se posent
|
||||
|
||||
- [ ] 9. Optimisations et Performance
|
||||
- Implémenter le cache pour le VLM
|
||||
- Optimiser les requêtes d'éléments
|
||||
- Ajouter des métriques de monitoring
|
||||
- _Exigences: 10.1, 10.2, 10.3, 10.4, 10.5_
|
||||
|
||||
- [ ] 9.1 Implémenter le cache VLM
|
||||
- Créer un cache basé sur hash du screenshot
|
||||
- Implémenter une politique d'éviction LRU
|
||||
- Persister le cache entre sessions (optionnel)
|
||||
- Mesurer le taux de cache hit
|
||||
- _Exigences: 10.4_
|
||||
|
||||
- [ ]* 9.2 Écrire les tests de propriété pour le cache
|
||||
- **Propriété 30: Efficacité du cache VLM** - Deuxième traitement ≤ 10% du temps du premier
|
||||
- Tester avec différents screenshots
|
||||
- _Valide: Exigences 10.4_
|
||||
|
||||
- [ ] 9.3 Optimiser les requêtes d'éléments
|
||||
- Créer un index sur element_id pour recherche rapide
|
||||
- Implémenter une recherche par type et rôle
|
||||
- Mesurer les temps de requête
|
||||
- _Exigences: 10.5_
|
||||
|
||||
- [ ]* 9.4 Écrire les tests de propriété pour la scalabilité
|
||||
- **Propriété 31: Scalabilité des requêtes** - Temps ≤ 50ms pour base de 100k éléments
|
||||
- Tester avec différentes tailles de base de données
|
||||
- _Valide: Exigences 10.5_
|
||||
|
||||
- [ ] 9.5 Ajouter des métriques de monitoring
|
||||
- Nombre d'éléments détectés par screenshot
|
||||
- Temps de chaque étape du pipeline
|
||||
- Taux de cache hit pour le VLM
|
||||
- Distribution des types d'éléments
|
||||
- Scores de matching moyens
|
||||
- _Exigences: 10.1, 10.2, 10.3_
|
||||
|
||||
- [ ]* 9.6 Écrire les tests de performance
|
||||
- **Propriété 27: Performance de détection** - ≤ 2 secondes pour écran typique
|
||||
- **Propriété 28: Performance de génération d'embedding** - ≤ 1 seconde
|
||||
- **Propriété 29: Performance de comparaison** - ≤ 100ms
|
||||
- _Valide: Exigences 10.1, 10.2, 10.3_
|
||||
|
||||
- [ ] 10. Outils et Utilitaires
|
||||
- Créer un outil de migration de workflows
|
||||
- Créer un mode debug visuel
|
||||
- Créer un outil de configuration
|
||||
- _Exigences: 9.4, 9.5, 15.4_
|
||||
|
||||
- [ ] 10.1 Créer un outil de migration de workflows
|
||||
- Convertir les workflows plein écran en workflows au niveau élément
|
||||
- Détecter automatiquement les éléments dans les anciens screenshots
|
||||
- Générer les descripteurs d'éléments
|
||||
- Sauvegarder les workflows migrés
|
||||
- _Exigences: 9.4_
|
||||
|
||||
- [ ] 10.2 Créer un mode debug visuel
|
||||
- Sauvegarder des screenshots annotés avec bounding boxes
|
||||
- Afficher les types et rôles détectés
|
||||
- Afficher les scores de confiance
|
||||
- Afficher les embeddings (visualisation PCA/t-SNE)
|
||||
- _Exigences: Design - Logging et Debug_
|
||||
|
||||
- [ ] 10.3 Créer un outil de configuration
|
||||
- Permettre la configuration via fichier YAML ou variables d'environnement
|
||||
- Configurer les modes (light, enrichi, complet)
|
||||
- Configurer les poids de fusion
|
||||
- Configurer les seuils de matching
|
||||
- Configurer l'activation du VLM
|
||||
- _Exigences: 15.4_
|
||||
|
||||
- [ ] 11. Documentation et Tests Finaux
|
||||
- Documenter l'API des nouveaux composants
|
||||
- Créer des exemples d'utilisation
|
||||
- Vérifier la couverture de tests
|
||||
- _Exigences: Toutes_
|
||||
|
||||
- [ ] 11.1 Documenter l'API
|
||||
- Documenter UIElement, EnrichedScreenState
|
||||
- Documenter UIElementDetector, MultiModalEmbeddingManager, EnhancedWorkflowMatcher
|
||||
- Créer des docstrings complètes
|
||||
- Générer la documentation API (Sphinx)
|
||||
- _Exigences: Toutes_
|
||||
|
||||
- [ ] 11.2 Créer des exemples d'utilisation
|
||||
- Exemple de détection d'éléments sur un screenshot
|
||||
- Exemple de génération de state_embedding
|
||||
- Exemple de matching de workflow
|
||||
- Exemple de migration de workflow
|
||||
- _Exigences: Toutes_
|
||||
|
||||
- [ ] 11.3 Vérifier la couverture de tests
|
||||
- Vérifier que toutes les propriétés sont testées
|
||||
- Vérifier la couverture de code (> 80%)
|
||||
- Ajouter des tests manquants si nécessaire
|
||||
- _Exigences: Toutes_
|
||||
|
||||
- [ ] 12. Checkpoint Final - Validation Complète
|
||||
- Assurer que tous les tests passent
|
||||
- Vérifier que toutes les exigences sont satisfaites
|
||||
- Tester sur des workflows réels
|
||||
- Demander à l'utilisateur si des questions se posent
|
||||
Reference in New Issue
Block a user