v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
330
visual_workflow_builder/TASK_17_COMPLETE.md
Normal file
330
visual_workflow_builder/TASK_17_COMPLETE.md
Normal file
@@ -0,0 +1,330 @@
|
||||
# Tâche 17 Terminée : Nodes de Logique (Condition et Loop)
|
||||
|
||||
## ✅ Résumé
|
||||
|
||||
Les nodes de logique (Condition et Loop) sont maintenant implémentés avec support complet de la conversion vers WorkflowGraph.
|
||||
|
||||
## 📦 Fichiers Modifiés/Créés
|
||||
|
||||
### Backend - Services
|
||||
- `backend/services/converter.py` - Extension avec support Condition/Loop
|
||||
|
||||
### Tests
|
||||
- `backend/test_logic_nodes.py` - Tests unitaires des nodes de logique (5 tests)
|
||||
|
||||
## 🎯 Fonctionnalités Implémentées
|
||||
|
||||
### 1. Node Condition (Exigences 8.1, 8.2, 8.3, 8.5)
|
||||
|
||||
**Configuration**:
|
||||
```python
|
||||
VisualNode(
|
||||
type="condition",
|
||||
parameters={
|
||||
'expression': '${status} == "success"',
|
||||
'type': 'expression'
|
||||
},
|
||||
output_ports=[
|
||||
Port('out_true', 'True', 'output'),
|
||||
Port('out_false', 'False', 'output')
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
**Conversion**:
|
||||
- Détection automatique des branches true/false
|
||||
- Configuration dans `workflow.conditionals`
|
||||
- Support des expressions avec variables
|
||||
- Validation de syntaxe des expressions
|
||||
|
||||
**Exemple de configuration générée**:
|
||||
```python
|
||||
conditionals['condition_1'] = {
|
||||
'expression': '${status} == "success"',
|
||||
'true_branch': 'success_action',
|
||||
'false_branch': 'failure_action',
|
||||
'metadata': {...}
|
||||
}
|
||||
```
|
||||
|
||||
✅ **Testé**: Conversion avec branches true/false
|
||||
|
||||
### 2. Node Loop - Type Repeat (Exigences 9.1, 9.2, 9.3, 9.5)
|
||||
|
||||
**Configuration**:
|
||||
```python
|
||||
VisualNode(
|
||||
type="loop",
|
||||
parameters={
|
||||
'type': 'repeat',
|
||||
'count': 5
|
||||
},
|
||||
output_ports=[
|
||||
Port('out_body', 'Body', 'output'),
|
||||
Port('out_exit', 'Exit', 'output')
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
**Conversion**:
|
||||
- Détection du corps de la boucle
|
||||
- Détection de la sortie de boucle
|
||||
- Configuration dans `workflow.loops`
|
||||
|
||||
✅ **Testé**: Boucle repeat avec 5 itérations
|
||||
|
||||
### 3. Node Loop - Type While (Exigences 9.1, 9.2, 9.3, 9.5)
|
||||
|
||||
**Configuration**:
|
||||
```python
|
||||
VisualNode(
|
||||
type="loop",
|
||||
parameters={
|
||||
'type': 'while',
|
||||
'condition': '${counter} < 10',
|
||||
'max_iterations': 100
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**Conversion**:
|
||||
- Support des conditions de boucle
|
||||
- Limite de sécurité (max_iterations)
|
||||
- Substitution de variables dans la condition
|
||||
|
||||
✅ **Testé**: Boucle while avec condition
|
||||
|
||||
### 4. Node Loop - Type For-Each (Exigences 9.1, 9.2, 9.3, 9.5)
|
||||
|
||||
**Configuration**:
|
||||
```python
|
||||
VisualNode(
|
||||
type="loop",
|
||||
parameters={
|
||||
'type': 'for-each',
|
||||
'collection': '${items}',
|
||||
'item_variable': 'current_item'
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**Conversion**:
|
||||
- Itération sur collections
|
||||
- Variable d'item configurable
|
||||
- Support des références de variables
|
||||
|
||||
✅ **Testé**: Boucle for-each sur collection
|
||||
|
||||
### 5. Validation des Expressions (Exigence 8.5)
|
||||
|
||||
**Validations effectuées**:
|
||||
- Expression non vide
|
||||
- Présence d'opérateurs de comparaison
|
||||
- Parenthèses équilibrées
|
||||
- Génération d'avertissements pour expressions invalides
|
||||
|
||||
**Opérateurs supportés**:
|
||||
- Comparaison: `==`, `!=`, `<`, `>`, `<=`, `>=`
|
||||
- Logique: `and`, `or`, `not`
|
||||
- Appartenance: `in`
|
||||
|
||||
**Exemple**:
|
||||
```python
|
||||
# Expression invalide
|
||||
'(${value} == "test"' # Parenthèse manquante
|
||||
|
||||
# Avertissement généré:
|
||||
"Expression de condition potentiellement invalide:
|
||||
(${value} == "test" - Parenthèses non équilibrées"
|
||||
```
|
||||
|
||||
✅ **Testé**: Validation avec détection d'erreurs
|
||||
|
||||
### 6. Détection des Structures de Logique
|
||||
|
||||
**Méthode `_detect_logic_structures()`**:
|
||||
- Parcourt tous les nodes du workflow
|
||||
- Identifie les nodes de type `condition` et `loop`
|
||||
- Configure les structures dans le WorkflowGraph
|
||||
- Détecte les branches et corps de boucles
|
||||
|
||||
**Pour les conditions**:
|
||||
- Trouve la branche true (via port `out_true`)
|
||||
- Trouve la branche false (via port `out_false`)
|
||||
- Stocke l'expression de condition
|
||||
|
||||
**Pour les boucles**:
|
||||
- Trouve le corps de la boucle (via port `out_body`)
|
||||
- Trouve la sortie de boucle (via port `out_exit`)
|
||||
- Configure les paramètres selon le type
|
||||
|
||||
✅ **Implémenté**: Détection automatique complète
|
||||
|
||||
### 7. Gestion des Edges Conditionnels
|
||||
|
||||
**Méthode `_create_edge_constraints()`**:
|
||||
- Détecte si le node source est une condition
|
||||
- Ajoute les contraintes appropriées aux edges
|
||||
- Marque les branches true/false dans les pre-conditions
|
||||
|
||||
**Exemple**:
|
||||
```python
|
||||
# Edge depuis un node condition
|
||||
constraints.pre_conditions['condition_result'] = True # Branche true
|
||||
constraints.pre_conditions['condition_result'] = False # Branche false
|
||||
```
|
||||
|
||||
✅ **Implémenté**: Contraintes conditionnelles
|
||||
|
||||
## 📊 Résultats des Tests
|
||||
|
||||
### Tests Unitaires (test_logic_nodes.py)
|
||||
```
|
||||
✅ Test 1: Conversion node Condition avec branches true/false
|
||||
✅ Test 2: Conversion boucle repeat (5 itérations)
|
||||
✅ Test 3: Conversion boucle while (avec condition)
|
||||
✅ Test 4: Conversion boucle for-each (sur collection)
|
||||
✅ Test 5: Validation des expressions de condition
|
||||
|
||||
TOUS LES TESTS RÉUSSIS! (5/5)
|
||||
```
|
||||
|
||||
### Couverture des Exigences
|
||||
|
||||
| Exigence | Description | Status |
|
||||
|----------|-------------|--------|
|
||||
| 8.1 | Configuration node Condition | ✅ |
|
||||
| 8.2 | Edges séparés true/false | ✅ |
|
||||
| 8.3 | Suivi de la branche appropriée | ✅ |
|
||||
| 8.5 | Validation syntaxe expression | ✅ |
|
||||
| 9.1 | Configuration node Loop (types) | ✅ |
|
||||
| 9.2 | Edges pour corps et sortie | ✅ |
|
||||
| 9.3 | Répétition selon paramètres | ✅ |
|
||||
| 9.5 | Continuation après boucle | ✅ |
|
||||
|
||||
## 🚀 Utilisation
|
||||
|
||||
### Créer un Workflow avec Condition
|
||||
|
||||
```python
|
||||
from models.visual_workflow import VisualNode, VisualEdge, Port
|
||||
|
||||
# Node condition
|
||||
condition = VisualNode(
|
||||
id="check_status",
|
||||
type="condition",
|
||||
parameters={'expression': '${status} == "ready"'},
|
||||
output_ports=[
|
||||
Port('out_true', 'True', 'output'),
|
||||
Port('out_false', 'False', 'output')
|
||||
]
|
||||
)
|
||||
|
||||
# Branches
|
||||
edge_true = VisualEdge(
|
||||
source="check_status",
|
||||
target="proceed",
|
||||
source_port="out_true"
|
||||
)
|
||||
|
||||
edge_false = VisualEdge(
|
||||
source="check_status",
|
||||
target="retry",
|
||||
source_port="out_false"
|
||||
)
|
||||
```
|
||||
|
||||
### Créer un Workflow avec Boucle
|
||||
|
||||
```python
|
||||
# Boucle repeat
|
||||
loop = VisualNode(
|
||||
id="repeat_action",
|
||||
type="loop",
|
||||
parameters={'type': 'repeat', 'count': 3},
|
||||
output_ports=[
|
||||
Port('out_body', 'Body', 'output'),
|
||||
Port('out_exit', 'Exit', 'output')
|
||||
]
|
||||
)
|
||||
|
||||
# Corps de la boucle
|
||||
edge_body = VisualEdge(
|
||||
source="repeat_action",
|
||||
target="action_to_repeat",
|
||||
source_port="out_body"
|
||||
)
|
||||
|
||||
# Sortie de la boucle
|
||||
edge_exit = VisualEdge(
|
||||
source="repeat_action",
|
||||
target="after_loop",
|
||||
source_port="out_exit"
|
||||
)
|
||||
```
|
||||
|
||||
## 📝 Notes Techniques
|
||||
|
||||
### Mapping des Types
|
||||
|
||||
| Type Visuel | Type Action | Paramètres Spécifiques |
|
||||
|-------------|-------------|------------------------|
|
||||
| condition | evaluate_condition | expression, condition_type |
|
||||
| loop (repeat) | execute_loop | loop_type, count |
|
||||
| loop (while) | execute_loop | loop_type, condition, max_iterations |
|
||||
| loop (for-each) | execute_loop | loop_type, collection, item_variable |
|
||||
|
||||
### Structure des Conditionals
|
||||
|
||||
```python
|
||||
workflow.conditionals = {
|
||||
'condition_id': {
|
||||
'expression': '${var} == value',
|
||||
'true_branch': 'node_id_true',
|
||||
'false_branch': 'node_id_false',
|
||||
'metadata': {...}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Structure des Loops
|
||||
|
||||
```python
|
||||
workflow.loops = {
|
||||
'loop_id': {
|
||||
'loop_type': 'repeat|while|for-each',
|
||||
'body_nodes': ['node_1', 'node_2'],
|
||||
'exit_node': 'node_after_loop',
|
||||
# Paramètres spécifiques au type
|
||||
'count': 5, # pour repeat
|
||||
'condition': '${x} < 10', # pour while
|
||||
'collection': '${items}', # pour for-each
|
||||
'metadata': {...}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Détection des Branches
|
||||
|
||||
La détection des branches se fait via :
|
||||
1. **Nom du port source** : `out_true`, `out_false`, `out_body`, `out_exit`
|
||||
2. **Métadonnées de l'edge** : `source_port` contient le nom du port
|
||||
3. **Pre-conditions** : `condition_result` = True/False
|
||||
|
||||
## 🎯 Prochaines Étapes
|
||||
|
||||
La tâche 17 est terminée. La prochaine tâche est :
|
||||
|
||||
- **Tâche 18**: Intégrer avec ExecutionLoop pour l'exécution réelle
|
||||
|
||||
## ✨ Conclusion
|
||||
|
||||
Les nodes de logique sont maintenant complets et robustes :
|
||||
- ✅ Node Condition avec branches true/false
|
||||
- ✅ Node Loop avec 3 types (repeat, while, for-each)
|
||||
- ✅ Validation des expressions
|
||||
- ✅ Détection automatique des structures
|
||||
- ✅ Configuration dans WorkflowGraph
|
||||
- ✅ Tests complets (5/5)
|
||||
|
||||
Le système est prêt pour l'intégration avec ExecutionLoop pour permettre l'exécution réelle des workflows avec logique conditionnelle et boucles !
|
||||
Reference in New Issue
Block a user