Files
rpa_vision_v3/docs/EXECUTION_LOOP_FLAGS.md
Dom 447fbb2c6e
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
chore: sauvegarde complète avant factorisation executor
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>
2026-04-20 17:03:44 +02:00

193 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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