Files
rpa_vision_v3/docs/EXECUTION_LOOP_FLAGS.md
Dom a2b82d3e76
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 14s
security-audit / pip-audit (CVE dépendances) (push) Successful in 12s
security-audit / Scan secrets (grep) (push) Successful in 9s
tests / Lint (ruff + black) (push) Successful in 15s
tests / Tests sécurité (critique) (push) Has been cancelled
tests / Tests unitaires (sans GPU) (push) Has been cancelled
fix(lint): ruff passe propre — 2 vrais bugs + suppression fichier corrompu
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>
2026-04-15 19:00:16 +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