_capture_screen() accepte un monitor_idx optionnel (None = composite legacy).
Index logique 0..N-1 mappé sur mss.monitors[idx+1] (mss[0] = composite).
Les 3 niveaux de grounding (OCR, UI-TARS, VLM) propagent l'offset retourné
par la capture pour traduire les coordonnées locales monitor en coordonnées
absolues écran (correct pour pyautogui.click).
find_element_on_screen() accepte monitor_idx et le forwarde aux 3 niveaux.
Backward 100% : monitor_idx=None partout → comportement strictement actuel.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Le pHash global 8x8 sur écran 1920x1080 ne détecte pas l'ouverture d'un
dialog modal dans une VM QEMU (un dialog 800x500 couvre ~3 pixels pHash,
distance Hamming typique = 1-2, sous le seuil de 3). Découvert sur Win11/
Notepad : Ctrl+Shift+S ouvrait bien le dialog mais Léa abortait à tort.
_handle_post_shortcut() poll désormais DialogHandler.handle_if_dialog()
toutes les 500ms (EasyOCR + KNOWN_DIALOGS). 8s pour le premier dialog,
3s de stabilité entre dialogs successifs, 60s budget total.
KNOWN_DIALOGS réordonné : popups modaux (confirmer/remplacer/écraser)
prioritaires sur fenêtres parents (enregistrer sous/save as) car l'OCR
full-screen capte les deux simultanément.
DialogHandler bascule sur UITarsGrounder subprocess one-shot (au lieu
du serveur HTTP localhost:8200 qui n'existait plus). InfiGUI worker,
think_arbiter et ui_tars_grounder alignés sur le même contrat.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
docs/CARTOGRAPHY.md :
- Carte complète des 2 chemins d'exécution (Legacy vs ORA)
- 12 systèmes de grounding identifiés dont 3 morts
- Trace du champ target_text de la capture au clic
- Fonctions existantes non branchées (verify, recovery, ShadowLearningHook)
- Budget VRAM, fichiers critiques, règles de modification
Fix target_text ORA (observe_reason_act.py:217) :
- Détecte les target_text absurdes ("click_anchor")
- Appelle _describe_anchor_image() (VLM) pour décrire le crop
- Même logique que le legacy execute.py:893
Worker InfiGUI via fichiers /tmp :
- Communication par fichiers (pas subprocess pipes, pas HTTP)
- Process indépendant lancé avant le backend
- Résout le crash CUDA dans Flask/FastAPI/uvicorn
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nouveaux patterns :
- dialog_overwrite : "voulez-vous remplacer/écraser", "fichier existe déjà" → Oui
- dialog_dont_save : "ne pas enregistrer", "quitter sans enregistrer" → Ne pas enregistrer
Handler amélioré (handle_detected_pattern) :
- EasyOCR au lieu de docTR (meilleure lecture des boutons GUI)
- Match par inclusion (pas seulement exact)
- Suppression fallback VLM (Ollama n'a plus de VRAM)
- Prints visibles pour diagnostic
28 patterns au total, testés sur 6 dialogues types.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Réflexe check : déclenché uniquement si pHash change (popup inattendu),
plus d'OCR full screen systématique à chaque step. Gain ~9s/workflow.
Serveur grounding : max_new_tokens 256→64 (la réponse fait ~20 tokens).
Validé : 5+ tests consécutifs 7/7, apprentissage actif
(CR_patient en fast_exact_text 2.2s, Feuille calcul en template 83ms).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
_act_click() utilise maintenant le pipeline FAST→SMART→THINK :
- Feature flag RPA_USE_FAST_PIPELINE=1 (activé par défaut)
- RPA_USE_FAST_PIPELINE=0 pour rollback sur l'ancien pipeline
- Si le nouveau pipeline échoue → fallback automatique template→OCR→static
- Pre-check VLM désactivé (le pipeline valide visuellement)
- Capture unique de l'écran partagée entre tous les layers
Rollback instantané : unset RPA_USE_FAST_PIPELINE
Tests : 37 passed, 0 régression
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Architecture grounding complète :
- core/grounding/server.py : serveur FastAPI (port 8200) avec UI-TARS-1.5-7B en 4-bit NF4
Process séparé avec son propre contexte CUDA (résout le crash Flask/CUDA)
- core/grounding/pipeline.py : orchestrateur cascade template→OCR→UI-TARS→static
- core/grounding/template_matcher.py : TemplateMatcher centralisé (remplace 5 copies)
- core/grounding/ui_tars_grounder.py : client HTTP vers le serveur de grounding
- core/grounding/target.py : GroundingTarget + GroundingResult
ORA modifié :
- _act_click() : capture unique de l'écran envoyée au serveur de grounding
- Pre-check VLM skippé pour ui_tars (redondant, et Ollama n'a plus de VRAM)
- verify_level='none' par défaut (vérification titre OCR prévue en Phase 2)
- Détection réponses négatives UI-TARS ("I don't see it" → fallback OCR)
Nettoyage :
- 9 fichiers morts archivés dans _archive/ (~6300 lignes supprimées)
- 21 tests ajoutés pour TemplateMatcher
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Double-clic : moveTo + 2 clics explicites (pyautogui.doubleClick ne
traverse pas toujours la VM). Délai 80ms entre les clics.
Vérification : un double-clic DOIT produire un changement majeur
(ouverture fichier/dossier). Changement mineur = échec → retry.
Les clics simples et hotkeys gardent la tolérance actuelle.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pattern.get() crashait car pattern=None quand l'overlay n'est pas
un dialogue connu. Ajout de guard None.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pyautogui.hotkey('super','d') ne traverse pas la VM.
xdotool key super+d avec setxkbmap fr fonctionne.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pyautogui.click cliquait SUR Chrome. xdotool search --name QEMU
trouve la fenêtre VM et la force au premier plan avant Win+D.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Alt+Tab bascule entre fenêtres. Win+D affiche le bureau Windows.
Plus fiable quand l'élément cible est sur le bureau.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
windowminimize minimisait en boucle toutes les fenêtres (VM incluse).
Alt+Tab bascule juste le focus sans rien fermer/minimiser.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Quand la pré-vérification dit NO et qu'aucun pattern de dialogue n'est
détecté, c'est une fenêtre quelconque qui masque la cible (Chrome, etc).
xdotool windowminimize pour la dégager.
Classification améliorée : pré-check rejeté → OVERLAY_BLOCKING
(avant c'était ELEMENT_NOT_FOUND → scroll inutile).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avant de cliquer, crop 200x100 autour de la position cible envoyé
au VLM (qwen2.5vl:3b) : "Is this UI element 'CR_patient_demo'? YES/NO"
Si NO → abandon du clic, évite les clics erronés.
Si erreur VLM → laisse passer (pas bloquant).
Skippé pour le template matching (confiance pixel suffisante).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le logging Python ne traverse pas le nohup de Flask. Tous les autres
modules (execute.py, intelligent_executor.py) utilisent print().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ordre : UI-TARS (3s, 94%) → Template (80ms) → OCR (1s)
UI-TARS dit "click on CR_patient_demo" et trouve les coordonnées
comme un humain. Le template matching échoue sur les icônes Windows
(micro-différences visuelles → score 0.38 au lieu de 0.95).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Logs : forcer le handler stdout pour que les logs ORA apparaissent
dans nohup (logger.info n'écrivait nulle part).
Vérification : un clic avec confiance >= 0.7 est accepté même si
l'écran ne change pas (pHash same). Un clic sur un champ de saisie
ne modifie quasi pas l'écran mais est légitime.
Changement mineur toujours accepté (plus de condition confiance > 0.9).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CRITIQUE : ajout should_continue callback dans ORALoop pour supporter
les boutons Stop/Pause du frontend en mode verified et instruction.
HAUTE : suppression sys.stdout.write de debug, logger.warning→debug
dans _grounding_ocr.
BASSE : suppression import mort 'field' dans observe_reason_act.py.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
reason_instruction() : le VLM regarde l'écran, décide la prochaine
action atomique (click/type/hotkey/scroll/done), retourne un Decision
avec expected_after pour la vérification.
run_instruction() : boucle ORA complète pour instructions texte.
CognitiveContext mis à jour à chaque étape (objectif, historique,
faits appris, confiance).
POST /api/v3/execute/instruction : endpoint API pour lancer une
instruction en langage naturel. Thread daemon, polling du résultat
via GET /api/v3/execute/instruction/result.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
docTR se chargeait au premier appel OCR (~30s). Maintenant pré-chargé
au démarrage du backend → premier clic rapide.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avant : OCR retournait le premier match → cliquait sur la barre de titre
("CR_patient_demo" dans le path) au lieu du fichier dans la liste.
Après : collecte tous les matchs, choisit le plus proche de la position
originale de l'ancre (anchor_bbox). Si pas de bbox, prend le plus central.
Élimine les clics sur les barres de titre, breadcrumbs, menus.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
La capture VWB utilisait monitors[0] (composite) mais l'exécution
utilisait monitors[1] (premier écran). Images incompatibles → CLIP
retournait 0.00 sur un écran identique.
Tous les fichiers alignés sur monitors[0].
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
L'orchestrateur VRAM redémarrait Ollama en pleine exécution → timeout.
Désactivé pendant le workflow. L'orchestrateur reste disponible pour
bascule manuelle avant/après.
Description ancre via qwen2.5vl:3b (3 Go) au lieu de 7b — tient en VRAM
sans décharger CLIP ni RF-DETR.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SeeClick supprimé : modèle HF incompatible (QWenConfig non reconnu),
crashait à chaque exécution et polluait les logs.
Remplacé par UI-TARS via la chaîne de grounding.
Log warning visible quand la description VLM de l'ancre échoue
(pour diagnostiquer les problèmes de VRAM).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Quand le target_text est vide ou identique au type d'action
(click_anchor, double_click_anchor...), le VLM décrit l'image
de l'ancre en 5 mots ("folder icon named Demo").
Cette description est ensuite passée à UI-TARS pour le grounding
("click on folder icon named Demo") et à l'OCR pour la recherche.
Chaîne complète : VLM décrit → OCR cherche → UI-TARS grounding → VLM raisonne.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Grounding en cascade quand CLIP/template échouent :
1. OCR (docTR) → cherche le texte exact sur l'écran (~1s)
2. UI-TARS grounding → "click on X" → coordonnées (~3s, 94% ScreenSpot)
3. VLM reasoning → raisonnement complet + confirmation OCR (~10s)
find_element_on_screen() dans input_handler.py (partagé VWB + Léa).
Câblé dans find_and_click() et execute_action() comme fallback.
Refonte capture écran :
- mss.monitors[0] (composite) pour capturer la VM en plein écran
- FullscreenSelector réécrit : overlay via getBoundingClientRect()
- Bboxes et sélection alignées avec l'image (calcul JS, pas CSS)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
VRAMOrchestrator : bascule automatique entre modes SHADOW et REPLAY.
- SHADOW : streaming server + agent_chat actifs
- REPLAY : VLM qwen2.5vl:7b chargé, services non-essentiels stoppés
vlm_reason_about_screen() appelle ensure_reasoning_ready() avant
chaque raisonnement — libère la VRAM si nécessaire.
Benchmark : qwen2.5vl:7b en 10s (warm) vs 44s quand VRAM saturée.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
vlm_reason_about_screen() : capture l'écran, envoie au VLM local
(gemma4/Ollama) avec l'objectif et le contexte, retourne une action
en JSON (click/type/wait/nothing + target + reasoning).
Chaîne de décision :
1. Réflexes (UIPatternLibrary) → instantané
2. OCR bouton (docTR) → rapide
3. VLM reasoning (Ollama) → intelligent, ~2-5s
Le VLM intervient UNIQUEMENT quand 1 et 2 échouent — pas de latence
ajoutée quand les réflexes suffisent.
UIPatternLibrary enrichie : charge builtin + GUI-R1 + learned patterns.
save_learned_pattern() persiste les patterns appris par Shadow.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
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>
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>
- 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>
- 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>