Pipeline replay visuel : - VLM-first : l'agent appelle Ollama directement pour trouver les éléments - Template matching en fallback (seuil strict 0.90) - Stop immédiat si élément non trouvé (pas de clic blind) - Replay depuis session brute (/replay-session) sans attendre le VLM - Vérification post-action (screenshot hash avant/après) - Gestion des popups (Enter/Escape/Tab+Enter) Worker VLM séparé : - run_worker.py : process distinct du serveur HTTP - Communication par fichiers (_worker_queue.txt + _replay_active.lock) - Le serveur HTTP ne fait plus jamais de VLM → toujours réactif - Service systemd rpa-worker.service Capture clavier : - raw_keys (vk + press/release) pour replay exact indépendant du layout - Fix AZERTY : ToUnicodeEx + AltGr detection - Enter capturé comme \n, Tab comme \t - Filtrage modificateurs seuls (Ctrl/Alt/Shift parasites) - Fusion text_input consécutifs, dédup key_combo Sécurité & Internet : - HTTPS Let's Encrypt (lea.labs + vwb.labs.laurinebazin.design) - Token API fixe dans .env.local - HTTP Basic Auth sur VWB - Security headers (HSTS, CSP, nosniff) - CORS domaines publics, plus de wildcard Infrastructure : - DPI awareness (SetProcessDpiAwareness) Python + Rust - Métadonnées système (dpi_scale, window_bounds, monitors, os_theme) - Template matching multi-scale [0.5, 2.0] - Résolution dynamique (plus de hardcode 1920x1080) - VLM prefill fix (47x speedup, 3.5s au lieu de 180s) Modules : - core/auth/ : credential vault (Fernet AES), TOTP (RFC 6238), auth handler - core/federation/ : LearningPack export/import anonymisé, FAISS global - deploy/ : package Léa (config.txt, Lea.bat, install.bat, LISEZMOI.txt) UX : - Filtrage OS (VWB + Chat montrent que les workflows de l'OS courant) - Bibliothèque persistante (cache local + SQLite) - Clustering hybride (titre fenêtre + DBSCAN) - EdgeConstraints + PostConditions peuplés - GraphBuilder compound actions (toutes les frappes) Agent Rust : - Token Bearer auth (network.rs) - sysinfo.rs (DPI, résolution, window bounds via Win32 API) - config.txt lu automatiquement - Support Chrome/Brave/Firefox (pas que Edge) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Graph Module - Construction de Workflow Graphs
Ce module implémente la construction automatique de graphes de workflows depuis des sessions enregistrées.
Architecture
graph/
├── __init__.py
├── graph_builder.py # Construction de workflows depuis sessions
├── node_matcher.py # Matching de ScreenStates contre nodes
└── README.md # Ce fichier
GraphBuilder
Responsabilités
Le GraphBuilder analyse une RawSession pour construire automatiquement un Workflow complet :
- Création de ScreenStates - Convertit les screenshots en états structurés
- Calcul d'Embeddings - Génère des embeddings multi-modaux pour chaque état
- Détection de Patterns - Utilise DBSCAN pour identifier les patterns répétés
- Construction de Nodes - Crée des WorkflowNodes depuis les clusters
- Construction d'Edges - Détecte les transitions entre états (TODO)
Algorithme de Détection de Patterns
Utilise DBSCAN (Density-Based Spatial Clustering of Applications with Noise) :
- Métrique : Similarité cosinus entre embeddings
- Paramètres :
eps: Distance maximum entre points (défaut: 0.15)min_samples: Échantillons minimum par cluster (défaut: 2)min_pattern_repetitions: Répétitions minimum pour un pattern (défaut: 3)
Avantages de DBSCAN :
- Détecte automatiquement le nombre de clusters
- Identifie le bruit (états uniques)
- Fonctionne bien avec des clusters de formes arbitraires
Exemple d'Utilisation
from core.graph.graph_builder import GraphBuilder
from core.models.raw_session import RawSession
# Créer le builder
builder = GraphBuilder(
min_pattern_repetitions=3,
clustering_eps=0.15
)
# Construire workflow depuis session
workflow = builder.build_from_session(
session=raw_session,
workflow_name="Login Workflow"
)
print(f"Workflow: {len(workflow.nodes)} nodes, {len(workflow.edges)} edges")
Configuration
GraphBuilder(
embedding_builder=None, # StateEmbeddingBuilder personnalisé
faiss_manager=None, # FAISSManager pour indexation
min_pattern_repetitions=3, # Répétitions min pour un pattern
clustering_eps=0.15, # Distance max DBSCAN
clustering_min_samples=2 # Échantillons min par cluster
)
Méthodes Publiques
build_from_session(session, workflow_name=None) -> Workflow
Construit un workflow complet depuis une RawSession.
Args:
session: RawSession à analyserworkflow_name: Nom du workflow (optionnel)
Returns:
Workflowavec nodes et edges
Raises:
ValueErrorsi la session est vide
Méthodes Privées
_create_screen_states(session) -> List[ScreenState]
Crée des ScreenStates depuis les screenshots.
Note: Pour l'instant, crée des états basiques. TODO: Enrichir avec détection UI.
_compute_embeddings(screen_states) -> List[np.ndarray]
Calcule les embeddings pour tous les états.
Utilise StateEmbeddingBuilder pour générer des embeddings multi-modaux (image + texte + UI).
_detect_patterns(embeddings, screen_states) -> Dict[int, List[int]]
Détecte les patterns répétés via clustering DBSCAN.
Returns: Dictionnaire {cluster_id: [indices des états]}
_build_nodes(clusters, screen_states, embeddings) -> List[WorkflowNode]
Construit des WorkflowNodes depuis les clusters.
Pour chaque cluster :
- Calcule l'embedding prototype (moyenne normalisée)
- Extrait les contraintes
- Crée un ScreenTemplate
- Crée un WorkflowNode
_create_screen_template(states, prototype_embedding) -> ScreenTemplate
Crée un ScreenTemplate depuis un cluster d'états.
TODO: Extraire intelligemment :
window_title_pattern(regex depuis titres communs)required_text_patterns(texte présent dans tous les états)required_ui_elements(éléments UI communs)
_build_edges(nodes, screen_states, session) -> List[WorkflowEdge]
Construit des WorkflowEdges depuis les transitions.
TODO: Implémenter détection de transitions :
- Identifier séquences d'états (state_i → state_j)
- Extraire actions depuis événements RawSession
- Mapper états vers nodes
- Créer edges avec TargetSpec et conditions
NodeMatcher
Responsabilités
Le NodeMatcher trouve le WorkflowNode qui correspond le mieux à un ScreenState actuel.
Stratégies de Matching
- Recherche FAISS (si disponible) : Recherche rapide dans l'index
- Recherche Linéaire (fallback) : Compare avec tous les candidats
- Validation de Contraintes : Vérifie titre fenêtre, texte requis, UI requis
Exemple d'Utilisation
from core.graph.node_matcher import NodeMatcher
# Créer le matcher
matcher = NodeMatcher(similarity_threshold=0.85)
# Matcher un état contre des nodes candidats
result = matcher.match(current_state, candidate_nodes)
if result:
node, confidence = result
print(f"Matched {node.node_id} with confidence {confidence:.2f}")
else:
print("No match found")
Configuration
NodeMatcher(
embedding_builder=None, # StateEmbeddingBuilder personnalisé
faiss_manager=None, # FAISSManager pour recherche rapide
similarity_threshold=0.85 # Seuil de similarité minimum
)
Méthodes Publiques
match(current_state, candidate_nodes) -> Optional[Tuple[WorkflowNode, float]]
Trouve le node qui matche le mieux l'état actuel.
Returns: (node, confidence) si match trouvé, None sinon
validate_constraints(state, node) -> bool
Valide les contraintes du node contre l'état.
Returns: True si toutes les contraintes sont satisfaites
Tests
Tests Unitaires
# Lancer les tests
python -m pytest tests/unit/test_graph_builder.py -v
python -m pytest tests/unit/test_node_matcher.py -v
Test d'Intégration
# Test rapide
python test_phase_a_b.py
Qualité du Code
- ✅ Type Hints : Toutes les fonctions sont typées
- ✅ Docstrings : Documentation complète (Google style)
- ✅ Logging : Logs informatifs à tous les niveaux
- ✅ Error Handling : Validation des entrées
- ✅ No Diagnostics : Aucune erreur de linting/typing
Prochaines Étapes
Priorité Haute
-
Implémenter
_build_edges()- Détecter transitions entre états
- Extraire actions depuis événements
- Créer TargetSpec avec rôles sémantiques
-
Enrichir
_create_screen_template()- Extraire window_title_pattern
- Extraire required_text_patterns
- Extraire required_ui_elements
-
Tests Property-Based
- Property 14: Embedding Prototype Sample Count
- Property 16: Pattern Detection Minimum Repetitions
Priorité Moyenne
-
Optimisations
- Batch processing pour embeddings
- Cache pour prototypes
- Parallélisation du clustering
-
Robustesse
- Gestion des sessions très longues
- Gestion des états sans patterns
- Métriques de qualité des clusters
Références
- DBSCAN : Scikit-learn Documentation
- Workflow Graphs : Voir
core/models/workflow_graph.py - State Embeddings : Voir
core/embedding/state_embedding_builder.py