fix: masquer la fenêtre console lors du spawn lea_uia.exe sur Windows

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>
This commit is contained in:
Dom
2026-04-10 22:18:11 +02:00
parent f82753debe
commit 9188bd7df1
2 changed files with 32 additions and 0 deletions

View File

@@ -37,6 +37,21 @@ logger = logging.getLogger(__name__)
# Timeout par défaut pour les appels UIA (en secondes) # Timeout par défaut pour les appels UIA (en secondes)
_DEFAULT_TIMEOUT = 5.0 _DEFAULT_TIMEOUT = 5.0
# Masquer la fenêtre console lors du spawn de lea_uia.exe sur Windows.
# Sans ce flag, chaque appel (à chaque clic utilisateur pendant
# l'enregistrement) fait apparaître une fenêtre cmd noire brièvement
# visible à l'écran → ralentit la souris et pollue les screenshots
# capturés (le VLM peut "voir" le chemin lea_uia.exe comme texte cliqué).
#
# La valeur 0x08000000 correspond à CREATE_NO_WINDOW défini dans
# l'API Windows. Sur Linux/Mac, la valeur est 0 et `creationflags`
# est ignoré. getattr() gère le cas où Python expose déjà la constante
# sur Windows.
if platform.system() == "Windows":
_SUBPROCESS_CREATION_FLAGS = getattr(subprocess, "CREATE_NO_WINDOW", 0x08000000)
else:
_SUBPROCESS_CREATION_FLAGS = 0
@dataclass @dataclass
class UiaElement: class UiaElement:
@@ -166,6 +181,7 @@ class UIAHelper:
timeout=self._timeout, timeout=self._timeout,
encoding="utf-8", encoding="utf-8",
errors="replace", errors="replace",
creationflags=_SUBPROCESS_CREATION_FLAGS,
) )
if result.returncode != 0: if result.returncode != 0:
logger.debug( logger.debug(

View File

@@ -37,6 +37,21 @@ logger = logging.getLogger(__name__)
# Timeout par défaut pour les appels UIA (en secondes) # Timeout par défaut pour les appels UIA (en secondes)
_DEFAULT_TIMEOUT = 5.0 _DEFAULT_TIMEOUT = 5.0
# Masquer la fenêtre console lors du spawn de lea_uia.exe sur Windows.
# Sans ce flag, chaque appel (à chaque clic utilisateur pendant
# l'enregistrement) fait apparaître une fenêtre cmd noire brièvement
# visible à l'écran → ralentit la souris et pollue les screenshots
# capturés (le VLM peut "voir" le chemin lea_uia.exe comme texte cliqué).
#
# La valeur 0x08000000 correspond à CREATE_NO_WINDOW défini dans
# l'API Windows. Sur Linux/Mac, la valeur est 0 et `creationflags`
# est ignoré. getattr() gère le cas où Python expose déjà la constante
# sur Windows.
if platform.system() == "Windows":
_SUBPROCESS_CREATION_FLAGS = getattr(subprocess, "CREATE_NO_WINDOW", 0x08000000)
else:
_SUBPROCESS_CREATION_FLAGS = 0
@dataclass @dataclass
class UiaElement: class UiaElement:
@@ -166,6 +181,7 @@ class UIAHelper:
timeout=self._timeout, timeout=self._timeout,
encoding="utf-8", encoding="utf-8",
errors="replace", errors="replace",
creationflags=_SUBPROCESS_CREATION_FLAGS,
) )
if result.returncode != 0: if result.returncode != 0:
logger.debug( logger.debug(