chore: sauvegarde complète avant factorisation executor
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 10s
security-audit / Scan secrets (grep) (push) Successful in 8s
tests / Lint (ruff + black) (push) Successful in 13s
tests / Tests unitaires (sans GPU) (push) Failing after 14s
tests / Tests sécurité (critique) (push) Has been skipped
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 10s
security-audit / Scan secrets (grep) (push) Successful in 8s
tests / Lint (ruff + black) (push) Successful in 13s
tests / Tests unitaires (sans GPU) (push) Failing after 14s
tests / Tests sécurité (critique) (push) Has been skipped
Point de sauvegarde incluant les fichiers non committés des sessions précédentes (systemd, docs, agents, GPU manager). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
192
docs/EXECUTION_LOOP_FLAGS.md
Normal file
192
docs/EXECUTION_LOOP_FLAGS.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Flags d'exécution vision-aware (C1) — ExecutionLoop
|
||||
|
||||
> Introduit dans la série de correctifs **C1** (avril 2026).
|
||||
> Référence code : [`core/execution/execution_loop.py`](../core/execution/execution_loop.py) (classe `ExecutionLoop`, constructeur lignes ~177-237).
|
||||
|
||||
Cette page décrit les quatre flags ajoutés à `ExecutionLoop` pour piloter
|
||||
finement la construction de `ScreenState` pendant le replay. Ils permettent de
|
||||
dégrader volontairement le pipeline de perception quand un composant est en
|
||||
panne ou quand on veut gagner de la latence.
|
||||
|
||||
## Contexte
|
||||
|
||||
Depuis C1, chaque itération de la boucle d'exécution construit un
|
||||
`ScreenState` enrichi via `ScreenAnalyzer` (OCR + détection UI + embedding),
|
||||
avec un cache perceptuel pour éviter de recalculer deux fois sur le même
|
||||
screenshot.
|
||||
|
||||
Cela coûte cher (~200 ms – 2 s selon la machine). Les flags ci-dessous
|
||||
permettent de désactiver ou contraindre ces étapes.
|
||||
|
||||
Le `StepResult` expose désormais :
|
||||
|
||||
| Champ | Type | Sens |
|
||||
|---|---|---|
|
||||
| `ocr_ms` | float | Temps OCR pour ce step |
|
||||
| `ui_ms` | float | Temps détection UI pour ce step |
|
||||
| `analyze_ms` | float | Temps total analyse ScreenState |
|
||||
| `total_ms` | float | Temps total du step (alias `duration_ms`) |
|
||||
| `cache_hit` | bool | True si le ScreenState vient du cache perceptuel |
|
||||
| `degraded` | bool | True si on est retombé en mode dégradé |
|
||||
|
||||
Ces champs remontent automatiquement dans le module analytics
|
||||
(table SQLite `step_metrics`, voir
|
||||
[`core/analytics/storage/timeseries_store.py`](../core/analytics/storage/timeseries_store.py)).
|
||||
|
||||
## Flags
|
||||
|
||||
### `enable_ui_detection: bool = True`
|
||||
|
||||
Active/désactive la détection UI (YOLO + SomEngine + VLM de grounding).
|
||||
|
||||
**Pourquoi le désactiver** :
|
||||
- Le serveur VLM (Ollama) est down ou surchargé
|
||||
- On cible un workflow très simple où seul l'OCR suffit
|
||||
- On debugge un problème de détection et on veut isoler la cause
|
||||
|
||||
**Impact performance** : gain ~100-1500 ms par step selon modèle VLM.
|
||||
|
||||
**Exemple** :
|
||||
|
||||
```python
|
||||
from core.execution.execution_loop import ExecutionLoop, ExecutionMode
|
||||
|
||||
loop = ExecutionLoop(
|
||||
pipeline=pipeline,
|
||||
enable_ui_detection=False, # VLM down → on coupe la détection UI
|
||||
)
|
||||
loop.start(workflow_id="wf_notepad", mode=ExecutionMode.AUTOMATIC)
|
||||
```
|
||||
|
||||
### `enable_ocr: bool = True`
|
||||
|
||||
Active/désactive l'OCR (Tesseract/docTR).
|
||||
|
||||
**Pourquoi le désactiver** :
|
||||
- Gains de performance sur un workflow piloté uniquement par templates/embeddings
|
||||
- Environnement CPU-only où l'OCR est trop lent
|
||||
- Les textes ne sont pas utilisés par la stratégie de matching
|
||||
|
||||
**Impact performance** : gain ~80-500 ms par step.
|
||||
|
||||
**Exemple** :
|
||||
|
||||
```python
|
||||
loop = ExecutionLoop(
|
||||
pipeline=pipeline,
|
||||
enable_ocr=False,
|
||||
)
|
||||
```
|
||||
|
||||
> Note : si `enable_ui_detection=False` **et** `enable_ocr=False`, la boucle
|
||||
> renvoie un `ScreenState` stub (sans texte ni éléments) et force
|
||||
> `degraded=True`. Le matching retombera sur les embeddings CLIP seuls.
|
||||
|
||||
### `analyze_timeout_ms: int = 8000`
|
||||
|
||||
Seuil soft en millisecondes au-delà duquel on considère que l'analyse a été
|
||||
trop lente et on bascule **tous les steps suivants** en mode dégradé
|
||||
(pas de recalcul OCR/UI, réutilisation du cache ou stub direct).
|
||||
|
||||
**Pourquoi le modifier** :
|
||||
- Machines lentes (CPU, VM, Citrix) → augmenter à `15000` ou `20000`
|
||||
- Serveurs dédiés GPU → réduire à `3000` pour détecter plus tôt
|
||||
- Tests / profiling → utiliser `999999` pour désactiver le basculement
|
||||
|
||||
**Exemple** :
|
||||
|
||||
```python
|
||||
loop = ExecutionLoop(
|
||||
pipeline=pipeline,
|
||||
analyze_timeout_ms=15000, # environnement lent (RDP/Citrix)
|
||||
)
|
||||
```
|
||||
|
||||
Le mode dégradé est porté par `ExecutionLoop._degraded_mode` et affiché dans
|
||||
`StepResult.degraded`. Voir
|
||||
[`_build_screen_state`](../core/execution/execution_loop.py) (~ligne 920).
|
||||
|
||||
### `window_info_provider: Optional[Callable[[], Optional[Dict]]] = None`
|
||||
|
||||
Callable renvoyant un `dict` décrivant la fenêtre active. Par défaut, la
|
||||
boucle appelle `screen_capturer.get_active_window()`.
|
||||
|
||||
**Pourquoi fournir un provider custom** :
|
||||
- **Citrix / RDP** : le client Windows local voit un seul process (le client
|
||||
Citrix). L'info de fenêtre utile vient de l'agent distant, on doit donc la
|
||||
passer explicitement.
|
||||
- **Environnements headless** : pas de gestionnaire de fenêtres natif.
|
||||
- **Tests** : injecter une fenêtre mockée sans toucher au capturer.
|
||||
|
||||
**Format attendu du dict** (au minimum) :
|
||||
|
||||
```python
|
||||
{
|
||||
"title": str, # Titre de la fenêtre
|
||||
"app_name": str, # Nom de l'application
|
||||
# champs optionnels utilisés par ScreenAnalyzer
|
||||
"x": int, "y": int, "width": int, "height": int,
|
||||
}
|
||||
```
|
||||
|
||||
**Exemple Citrix** :
|
||||
|
||||
```python
|
||||
def citrix_window_info():
|
||||
# L'agent dans la session Citrix distante publie ces infos
|
||||
# (par ex. via un fichier partagé ou une websocket)
|
||||
return remote_agent.get_current_window_info()
|
||||
|
||||
loop = ExecutionLoop(
|
||||
pipeline=pipeline,
|
||||
window_info_provider=citrix_window_info,
|
||||
)
|
||||
```
|
||||
|
||||
## Combinaisons recommandées
|
||||
|
||||
| Cas d'usage | Flags |
|
||||
|---|---|
|
||||
| Production standard (GPU local) | `enable_ui_detection=True, enable_ocr=True, analyze_timeout_ms=8000` (défaut) |
|
||||
| VLM down — mode fallback | `enable_ui_detection=False, enable_ocr=True` |
|
||||
| Machine lente / VM | `analyze_timeout_ms=15000` |
|
||||
| Citrix / RDP | `window_info_provider=<custom>` + valeurs par défaut |
|
||||
| Benchmark CLIP-only | `enable_ui_detection=False, enable_ocr=False` |
|
||||
|
||||
## Remontée analytics
|
||||
|
||||
Les timings et flags dégradés persistent dans la table SQLite
|
||||
`step_metrics` (colonnes `ocr_ms`, `ui_ms`, `analyze_ms`, `total_ms`,
|
||||
`cache_hit`, `degraded`) via
|
||||
[`AnalyticsExecutionIntegration.on_step_result`](../core/analytics/integration/execution_integration.py).
|
||||
|
||||
Exemple de requête d'analyse :
|
||||
|
||||
```sql
|
||||
-- Steps avec OCR lent (>300 ms)
|
||||
SELECT node_id, action_type, ocr_ms, analyze_ms
|
||||
FROM step_metrics
|
||||
WHERE ocr_ms > 300
|
||||
ORDER BY ocr_ms DESC;
|
||||
|
||||
-- Taux de cache hit par workflow
|
||||
SELECT workflow_id,
|
||||
SUM(cache_hit) * 1.0 / COUNT(*) AS cache_hit_ratio
|
||||
FROM step_metrics
|
||||
GROUP BY workflow_id;
|
||||
|
||||
-- Steps ayant basculé en mode dégradé
|
||||
SELECT execution_id, node_id, analyze_ms
|
||||
FROM step_metrics
|
||||
WHERE degraded = 1
|
||||
ORDER BY started_at DESC;
|
||||
```
|
||||
|
||||
## Voir aussi
|
||||
|
||||
- [`core/execution/execution_loop.py`](../core/execution/execution_loop.py) — implémentation
|
||||
- [`core/pipeline/screen_analyzer.py`](../core/pipeline/screen_analyzer.py) — pipeline d'analyse
|
||||
- [`core/pipeline/screen_state_cache.py`](../core/pipeline/screen_state_cache.py) — cache perceptuel
|
||||
- [`tests/unit/test_execution_loop_vision_aware.py`](../tests/unit/test_execution_loop_vision_aware.py) — tests C1
|
||||
- [`tests/unit/test_analytics_vision_metrics.py`](../tests/unit/test_analytics_vision_metrics.py) — tests analytics C1
|
||||
- [docs/STATUS.md](STATUS.md) — état général du projet
|
||||
Reference in New Issue
Block a user