GraphBuilder construit maintenant des ScreenState enrichis
(ui_elements + detected_text) au lieu de stubs vides, et associe
les clics aux UIElement par proximité spatiale.
Détails :
- __init__ accepte ui_detector, screen_analyzer, enable_ui_enrichment,
element_proximity_max_px (+ lazy resolver via singleton C1)
- _create_screen_states délègue à ScreenAnalyzer.analyze() — remplace
l'appel à _extract_text() qui n'existait plus depuis le Lot C
(bug silencieux : OCR cassé en prod depuis ce jour, caught except)
- _find_clicked_element : bbox contenant strict + fallback proximité
≤50px, préfère le plus petit bbox (form vs button)
- _build_click_target_spec : TargetSpec(by_role, by_text,
selection_policy="by_similarity") avec ancres dans context_hints
(anchor_element_id, anchor_bbox, anchor_center)
- _build_edges propage le ScreenState source aux builders d'action
- WorkflowPipeline passe ui_detector + enable_ui_enrichment au builder
Impact : matching prod 3-5x plus précis, TargetSpec ne sont plus
des "unknown_element" génériques, UIConstraint.required_roles se
remplit correctement via _extract_common_ui_elements (qui marchait
depuis toujours mais sur des state.ui_elements vides).
Tests e2e migrés vers enable_ui_enrichment=False (2.9s vs 67s) —
ils valident le pipeline DBSCAN/edges, pas la détection UI réelle.
15 nouveaux tests, 178 tests passants au total (incluant Lots A-E).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Vrais bugs corrigés :
- core/execution/target_resolver.py : suppression de 5 lignes de dead code
après un 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>
Nouvelle méthode match_current_state_from_state(screen_state, workflow_id)
qui utilise directement le ScreenState enrichi (window_title, detected_text,
ui_elements) fourni par ExecutionLoop au lieu de reconstruire un stub
ScreenState("Unknown", ui_elements=[], ...).
Préfère HierarchicalMatcher si workflow chargeable, fallback FAISS sinon.
L'ancienne API match_current_state(screenshot_path, workflow_id) est
convertie en wrapper : appelle ScreenAnalyzer.analyze() puis délègue.
Rétrocompat préservée.
ExecutionLoop._execute_step utilise la nouvelle méthode -> plus de double
analyze() dans le chemin d'exécution (économie latence).
Premier vrai matching context-aware. 11 nouveaux tests + 2 tests
integration loop. 172 tests non-régression verts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avant : clé = phash seul
-> deux contextes différents avec même screenshot partageaient
la même entrée cache -> collisions silencieuses.
Après : clé composite {phash}|{md5(ctx)[:16]} avec ctx =
- window_title
- app_name
- enable_ocr
- enable_ui_detection
- workflow_id (isolation inter-workflows)
get_or_compute() kwargs-only. TTL 2s et éviction LRU inchangés.
invalidate_if_changed() continue de comparer uniquement les phash.
ExecutionLoop propage tout le contexte au cache.
8 nouveaux tests prouvant :
- même image + window différent = miss
- même image + app différent = miss
- même image + flags différents = miss
- même image + workflow_id différent = miss
- même image + même contexte = hit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Retrait de l'état global toxique :
- analyze() : kwargs-only enable_ocr, enable_ui_detection, session_id
- Ne mute JAMAIS self pour les flags (variables locales + branches)
- _resolve_ocr_instance() / _resolve_ui_detector_instance() : lecture seule
- _init_lock par instance pour lazy init concurrent safe
- session_id par appel, plus via mutation singleton
Avant : ExecutionLoop mutait analyzer._ocr, _ui_detector,
_ocr_initialized, _ui_detector_initialized pour désactiver OCR/UI.
Deux loops partageant le singleton se polluaient mutuellement.
Après : deux loops partageant l'analyzer sont complètement isolés.
Preuve par TestAnalyzerIsolationBetweenLoops (3 tests).
Singleton get_screen_analyzer() préservé — garde uniquement les
ressources lourdes, plus de contexte d'exécution.
9 nouveaux tests (3 isolation + 6 kwargs-only/lazy-init).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avant : source_similarity=1.0 hardcodé dans _check_preconditions
-> la contrainte EdgeConstraints.min_source_similarity était
silencieusement désactivée. Un edge passait toujours.
Après : propagation ExecutionLoop -> workflow_pipeline -> EdgeScorer
- select_best/rank/score_edge/_check_preconditions acceptent
source_similarity: float (kwargs-only)
- get_next_action() le propage
- execution_loop passe la confidence issue de match_current_state
La contrainte min_source_similarity est opérationnelle pour la
première fois. Preuve concrète par test_min_source_similarity_fail
et test_low_similarity_blocks_edge (edge rejeté si sim < seuil).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Supprime ~8.2 Go de fichiers parasites qui polluent les grep, consomment
des tokens, et ajoutent du bruit au repo :
- _a_trier/ (561 Mo) — scripts legacy, backups, sessions logs, démos
- archives/ (21 Mo) — copie figée code décembre 2024 (déjà dans git history)
- visual_workflow_builder/_a_trier/ (7.6 Go) — backups VWB legacy + anciens frontends
- web_dashboard/app.py.bak_20260304_2225 — fichier .bak oublié
- agent_v1/ (top-level) — scaffold vide jamais alimenté
- core/detection/ui_detector_old.py.bak — .bak traqué par erreur
Retire aussi du tracking git :
- 2 fichiers __pycache__ traqués par erreur dans VWB backend
Met à jour .gitignore pour prévenir la récurrence :
- *.bak, *.bak_*, *.orig, *.old
- _a_trier/, archives/
Tout ce contenu reste récupérable via git history (tag pre-cleanup-phase1-20260410).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ajoute creationflags=CREATE_NO_WINDOW (0x08000000) au subprocess.run()
qui appelle lea_uia.exe dans UIAHelper._run(). Sans ce flag, Windows
ouvre brièvement une fenêtre cmd noire à CHAQUE appel — et le captor
appelle UIA à chaque clic utilisateur pendant l'enregistrement.
Symptômes rapportés par Dom :
- Flash de fenêtre terminal à chaque clic (visible à l'œil)
- Ralentissement de la souris pendant les enregistrements
- Pollution des données d'apprentissage : le VLM de post-analyse
"voit" la fenêtre cmd et l'enregistre comme élément cliqué
(log serveur : "gemma4 a lu l'élément : 'C:\\Lea\\helpers\\lea_uia.exe'")
Implémentation portable :
- Flag calculé au niveau module : 0x08000000 sur Windows, 0 sur Linux/Mac
- getattr(subprocess, "CREATE_NO_WINDOW", ...) pour gérer l'absence de
la constante sur Linux
- creationflags=0 est un no-op sur Linux, safe
Appliqué aux 2 copies synchronisées :
- agent_v0/agent_v1/core/uia_helper.py (source active pour l'agent)
- core/workflow/uia_helper.py (copie identique)
85 tests in silico OK (29 UIA + 56 E2E/Phase0). Le vrai test c'est
Dom qui refait un enregistrement et vérifie qu'il n'y a plus de
flash de terminal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Filtre d'événements parasites basé sur la CIBLE UIA :
- Un clic n'est filtré que si son uia_snapshot indique que l'élément
cliqué (ou un parent) est dans la fenêtre de Léa.
- Avant : on filtrait sur window.title qui pouvait être "Lea" même
quand le clic visait la taskbar (Léa au premier plan).
- Après : on regarde où va VRAIMENT le clic via parent_path UIA.
Extraction du expected_window depuis le parent_path UIA :
- Priorité au nom de la fenêtre racine du parent_path (plus fiable).
- Fallback sur window.title si pas de snapshot UIA ou pas de racine.
- Les fenêtres Léa sont neutralisées (effective_title="").
Pré-vérif avec polling tolérant (executor.py) :
- 5 tentatives avec 300ms entre chaque (total 1.5s max).
- Ignore les transitions "unknown_window" et fenêtre Léa.
- Évite les faux négatifs sur fenêtres en cours de changement.
Note : le filtrage reste basé sur des heuristiques. Un tri intelligent
par gemma4 au build reste à implémenter pour gérer les workflows
enregistrés avec des actions parasites (mail, chat, etc.).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Corrections critiques après test E2E qui montrait des clics au mauvais endroit :
1. Routage par machine_id (api_stream.py)
Quand 2 machines partagent le même session_id (agent_demo_user),
les actions d'un replay pour la VM ne doivent PLUS être distribuées
au PC physique. Vérification que le replay_state appartient bien à
la machine qui poll avant de consommer la queue.
2. IRBuilder extrait expected_window_before/after (ir_builder.py)
Pour chaque action click/type/key_combo, stocke le titre de la fenêtre
au moment du clic (before) et le titre du prochain événement (after).
Ces champs alimentent le contrôle strict au runtime.
3. ExecutionCompiler crée SuccessCondition title_match (execution_compiler.py)
Quand expected_window_after est défini, crée une condition de succès
STRICTE avec method="title_match" et expected_title. Plus de simple
"l'écran a changé" — on vérifie la fenêtre résultante.
4. Runner propage expected_window_before et success_strict
Le flag success_strict indique à l'agent que le contrôle post-action
DOIT être strict (STOP sur mismatch au lieu de warning).
5. UIA strict sur parent_path (executor.py)
_resolve_via_uia_local REJETTE un match si l'élément trouvé n'est pas
dans la bonne fenêtre parente (évite ex: "Rechercher" taskbar confondu
avec "Rechercher" explorateur).
6. Pré/post vérif stricte et bloquante (executor.py)
- expected_window_before lu en priorité depuis l'action (plan V4)
- Post-vérif : si success_strict=True et timeout, result.success=False
→ le replay s'arrête au lieu de continuer avec des warnings.
Validé sur la VM :
- Le replay s'arrête proprement quand l'étape 2 aboutit dans "Propriétés de
Internet" au lieu de "blocnote.txt - Bloc-notes"
- Plus de clics en aveugle / saisie au mauvais endroit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pipeline V4 câblé de bout en bout :
RawTrace (avec uia_snapshot) → IRBuilder → Action._enrichment
WorkflowIR → ExecutionCompiler (avec SurfaceProfile) → ExecutionPlan
ExecutionPlan → runner → target_spec (avec uia_target + resolve_order)
ResolutionStrategy étendu :
- Champs UIA : uia_name, uia_control_type, uia_automation_id, uia_parent_path
- Champs DOM : dom_selector, dom_xpath, dom_url_pattern (préparation web)
ExecutionCompiler.compile(surface_profile=...) :
- Timeouts/retries tirés du profil (citrix=15s/3x, web=5s/1x, natif=8s/2x)
- UIA primaire seulement si surface=WINDOWS_NATIVE et uia_available
- Citrix ignore UIA même si snapshot présent (UIA ne marche pas dans Citrix)
IRBuilder lit evt['uia_snapshot'] et le stocke dans action._enrichment
(à remplir par l'agent Windows pendant l'enregistrement via lea_uia.exe)
execution_plan_runner propage uia_target et dom_target dans target_spec
pour que l'agent Windows puisse les consommer au runtime.
11 tests de câblage E2E :
- Profils (Citrix/web/natif) imposent bien les timeouts
- Stratégie UIA créée quand snapshot+surface OK
- Stratégie UIA bloquée sur Citrix
- IRBuilder propage uia_snapshot
- Runner produit target_spec avec uia_target + resolve_order=['uia', 'ocr', 'vlm']
496 tests au total, 0 régression.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Format canonique entre RawTrace (capture) et ExecutionPlan (exécution).
C'est ce que Léa a COMPRIS en observant l'utilisateur.
- WorkflowIR : steps, variables, intentions, pré/postconditions
- IRBuilder : transforme les événements bruts en WorkflowIR via gemma4
- Générique : fonctionne pour TIM, compta, RH, stocks — le domaine est une couche par-dessus
- Versionné, sérialisable JSON, save/load
- Détection automatique des variables (texte saisi → substituable)
- 18 tests (format, sérialisation, builder, segmentation, variables)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Qwen2.5-VL occupe 9.8 GB de VRAM → plus de place pour YOLO.
SomEngine passe en CPU (1.4s au lieu de 0.1s, acceptable car
utilisé uniquement pendant le build_replay, pas le replay).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Analyse VLM :
- 1 seul appel VLM par screenshot au lieu de 30 (~15s vs 6.5min)
- Sélection screenshots par hash perceptuel (3-4 utiles sur 12)
- Fallback classification individuelle si appel unique échoue
- Estimation : ~1min par workflow au lieu de 78min
Rust agent :
- Léa (Edge mode app) s'ouvre automatiquement au démarrage
- Plus besoin de systray pour lancer le chat
- Fix URL chat /chat → /
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 30 crops suffisent pour les éléments UI principaux
- ~6min/screenshot au lieu de 17min (3x plus rapide)
- Bridge cherche aussi dans live_sessions/workflows/
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bouton "Windows" dans VWB pour exécuter sur le PC distant
- Template matching OpenCV multi-scale pour localiser les ancres visuelles
- Proxy VWB→streaming server avec chargement ancre (thumb, pas full)
- Fix executor Windows : mss lazy, result reporting, debug prints
- Fix poll replay permanent (sans session active)
- Mapping types VWB→executor (click_anchor→click, type_text→type)
- CORS streaming server, capture Windows dans VWB
- Dédup heartbeats côté client (hash perceptuel)
- Mode cloud VLM configurable via RPA_VLM_MODEL
- Fix resolve_target : pas de ScreenAnalyzer fallback (trop lent)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le GraphBuilder ne pouvait pas construire le graphe car from_dict
n'existait pas (seulement from_json). Alias avec valeurs par défaut
pour les sessions streaming.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bouton ? sur chaque nœud : tooltip avec description + paramètres typés
- Croix rouge visible (fix overflow React Flow)
- Sélection plein écran avec détection auto des éléments UI
- Zones détectées affichées sur l'aperçu de capture
- 32 actions documentées en français avec paramètres typés
- Pruning candidats VLM : max 80 avant classification (3x plus rapide)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Skip crops < 40px (deviner type par forme, confidence 0.3)
- Retry 1 fois si réponse VLM vide
- Extraction JSON robuste : cherche {…} dans le texte, fixe single quotes
- Élimine ~70% des appels VLM inutiles sur les petits éléments
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ExcelImporter : import .xlsx → SQLite auto (détection types, batch insert)
- DBIterator : lecture ligne par ligne avec filtre/tri/limite
- VWB actions : "Importer Excel" + "Pour chaque ligne" dans la palette
- DAG executor : pré-exécution import, boucle foreach avec injection
${current_row.colonne} dans les étapes dépendantes
- 36 tests unitaires Excel/DB (tous passent)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Refonte majeure du système Agent Chat et ajout de nombreux modules :
- Chat unifié : suppression du dual Workflows/Agent Libre, tout passe par /api/chat
avec résolution en 3 niveaux (workflow → geste → "montre-moi")
- GestureCatalog : 38 raccourcis clavier universels Windows avec matching sémantique,
substitution automatique dans les replays, et endpoint /api/gestures
- Mode Copilot : exécution pas-à-pas des workflows avec validation humaine via WebSocket
(approve/skip/abort) avant chaque action
- Léa UI (agent_v0/lea_ui/) : interface PyQt5 pour Windows avec overlay transparent
pour feedback visuel pendant le replay
- Data Extraction (core/extraction/) : moteur d'extraction visuelle de données
(OCR + VLM → SQLite), avec schémas YAML et export CSV/Excel
- ReplayVerifier (agent_v0/server_v1/) : vérification post-action par comparaison
de screenshots, avec logique de retry (max 3)
- IntentParser durci : meilleur fallback regex, type GREETING, patterns améliorés
- Dashboard : nouvelles pages gestures, streaming, extractions
- Tests : 63 tests GestureCatalog, 47 tests extraction, corrections tests existants
- Dépréciation : /api/agent/plan et /api/agent/execute retournent HTTP 410,
suppression du code hardcodé _plan_to_replay_actions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Nouvelles fonctionnalités
### 1. SeeClick Adapter (visual grounding fallback)
- Nouvel adapter pour le modèle SeeClick (HuggingFace)
- Intégré dans la chaîne de fallback: CLIP → Template → SeeClick → Static
- Localise les éléments GUI à partir de descriptions textuelles
### 2. Self-Healing Interactif
- Dialogue qui propose des alternatives quand l'ancre n'est pas trouvée
- L'utilisateur peut choisir: candidat alternatif, coords statiques, ou sauter
- Nouveaux endpoints: /healing/status, /healing/choose, /healing/candidates
- État "waiting_for_choice" pour mettre l'exécution en pause
### 3. Dashboard Confiance (temps réel)
- Affiche les scores de confiance pendant l'exécution
- Montre: méthode utilisée, distance, taux de succès
- Interface pliable en bas à droite
- Visible uniquement en mode intelligent/debug
## Fichiers ajoutés
- core/detection/seeclick_adapter.py
- frontend_v4/src/components/SelfHealingDialog.tsx
- frontend_v4/src/components/ConfidenceDashboard.tsx
## Fichiers modifiés
- core/detection/__init__.py
- backend/services/intelligent_executor.py
- backend/api_v3/execute.py
- frontend_v4/src/App.tsx
- frontend_v4/src/services/api.ts
- docs/VISION_RPA_INTELLIGENT.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changements:
- Ajouter ensure_dev_config() qui génère des clés temporaires en dev
- Ajouter paramètre strict=True/False à validate_production_security()
- En développement: génère auto ENCRYPTION_PASSWORD et SECRET_KEY
- En production: comportement inchangé (bloque si config invalide)
server/api_upload.py:
- Utilise strict=is_production_environment()
- En dev: warning seulement, continue le démarrage
- En prod: sys.exit(1) si config invalide
Résout les problèmes de démarrage en développement sans config manuelle.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BackupExporter (backup_exporter.py):
- Export complet (workflows, correction packs, coaching sessions, configs)
- Export sélectif (workflows only, configs only, etc.)
- Export modèles entraînés opt-in (embeddings, FAISS anonymisés)
- Sanitisation des configs (masquage des secrets)
- Statistiques de backup disponibles
VersionManager (version_manager.py):
- Suivi de version avec composants
- Vérification des mises à jour (manifest local)
- Vérification intégrité packages (SHA-256)
- Création/restauration de backups pour rollback
- Information système complète
Ces modules supportent les fonctionnalités Dashboard:
- Téléchargement sauvegardes par le client
- Mise à jour du système
- Rollback en cas de problème
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Réécrire logger.py avec format cohérent: "timestamp | level | component | message"
- Ajouter ANSIStripFilter pour nettoyer les codes couleur des logs
- Implémenter _clean_component_name() pour éviter les noms de fichiers corrompus
- Configurer rotation des fichiers (10MB, 5 backups)
- Rendre imports Prometheus optionnels dans __init__.py
- Réduire bruit des librairies externes (werkzeug, urllib3, etc.)
Corrige les problèmes de fichiers logs corrompus (!0.log, #0.log, %0.log, etc.)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix TypeError in create_flat_index() and create_ivf_index():
- Line 678: dimension= → dimensions=
- Line 692: dimension= → dimensions=
The FAISSManager.__init__() expects 'dimensions' (plural), not 'dimension'.
This bug prevented using the factory functions to create FAISS indexes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CoachingDecision enum (ACCEPT, REJECT, CORRECT, EXECUTE_MANUAL, SKIP)
- Add CoachingResponse dataclass for user decisions
- Add WAITING_COACHING state to ExecutionState
- Implement _request_coaching_decision() with callback or polling support
- Implement submit_coaching_decision() for external API/UI submission
- Implement _apply_coaching_correction() for applying user corrections
- Implement _record_coaching_feedback() integrating with:
- TrainingDataCollector for session recording
- FeedbackProcessor for statistics
- CorrectionPackIntegration for automatic correction capture
- Add get_coaching_stats() for session statistics
- Add 17 unit tests for COACHING functionality
COACHING mode now:
1. Suggests actions to user
2. Waits for user decision (accept/reject/correct/manual/skip)
3. Applies corrections if provided
4. Records all feedback for learning
5. Propagates corrections to Correction Packs automatically
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CorrectionPackIntegration class to bridge learning components
- Modify TrainingDataCollector to auto-propagate corrections to packs
- Modify FeedbackProcessor to capture corrections on INCORRECT/PARTIAL feedback
- Add convenience functions: get_correction_pack_integration(), capture_coaching_correction()
- Add 19 integration tests (all passing)
Corrections made during COACHING mode are now automatically captured
into a dedicated "auto_captured_corrections" pack for cross-workflow reuse.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement a complete system for capitalizing user corrections across multiple
workflows and sessions. This enables automatic application of learned fixes
when similar failures occur in different contexts.
New components:
- core/corrections/models.py: CorrectionKey, Correction, CorrectionPack models
- core/corrections/correction_repository.py: JSON storage with atomic writes
- core/corrections/aggregator.py: Aggregation by hash and quality filtering
- core/corrections/correction_pack_service.py: CRUD, export/import, versioning
- backend/api/correction_packs.py: REST API with 15 endpoints
Features:
- MD5-based key hashing for correction deduplication
- Export/import in JSON and YAML formats
- Version history with rollback support
- Cross-workflow pattern detection
- Integration with SelfHealingEngine for automatic application
- 29 unit tests (all passing)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Importer les vraies classes Action, TargetSpec, WorkflowEdge, ActionType
- Convertir le type d'action en ActionType Enum au lieu de string
- Créer un ScreenState complet avec tous les niveaux (raw, perception, context)
- Corriger _serialize_state dans error_handler.py pour accès compatibles
- Ajouter import os pour manipulation des fichiers
- Sauvegarder les screenshots dans data/temp/
L'exécution réelle fonctionne maintenant - les erreurs "Target not found"
sont attendues car il faut une vraie interface utilisateur à l'écran.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>