Vrais bugs corrigés :
- core/execution/target_resolver.py : suppression de 5 lignes de dead code
après return (vestige de refacto incomplète référençant des params
jamais assignés à self : similarity_threshold, use_spatial_fallback)
- agent_v0/agent_v1/core/executor.py:2180 : variable `prefill` référencée
mais jamais définie. Initialisation explicite ajoutée en amont
(conditionnée sur _is_thinking_popup, cohérent avec l'append du message)
Fichier supprimé :
- core/security/input_validator_new.py : contenu corrompu (texte inversé,
artefact de copier-coller), jamais importé nulle part, 550 erreurs ruff
à lui seul
Workflow CI :
- Exclusions ajoutées pour dossiers legacy connus cassés :
- agent_v0/deploy/windows_client/ (clone obsolète)
- tests/property/ (cf. MEMORY.md — imports cassés)
- tests/integration/test_visual_rpa_checkpoint.py (VisualMetadata
inexistant, déjà documenté)
Résultat : "ruff All checks passed!" sur core/ agent_v0/ tests/
(avec E9,F63,F7,F82 — syntax + undefined critiques).
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