fix: session_cleaner fallback — x_pct/y_pct + visual_mode=False

Deux bugs dans _simple_build_replay :

1. Mauvais noms de champs : x_percent/y_percent au lieu de x_pct/y_pct
   attendus par l'agent executor. Et valeurs en 0-100 au lieu de 0-1.
   Résultat : l'agent recevait x_pct=None → crash "cannot unpack
   non-iterable NoneType object".

2. Pas de visual_mode=False explicite. Sans enrichissement
   (target_spec vide, pas d'anchor), l'agent tentait une résolution
   visuelle sur du vide → crash.

Aussi : la condition de fallback empêchait le déclenchement quand
build_replay_from_raw_events crashait (error_message non vide bloquait
la branche). Corrigé : le fallback se déclenche sur `not replay_actions`
(couvre None, liste vide, et crash du build principal).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-04-12 15:51:40 +02:00
parent 9bcce3fc68
commit 057c37131f

View File

@@ -771,11 +771,14 @@ def clean_and_replay():
logger.error("Erreur build_replay_from_raw_events : %s", e)
error_message = f"Erreur lors de la construction du replay : {e}"
if replay_actions is None and not error_message:
# Fallback : filtrage simple et conversion directe
if not replay_actions:
# Fallback : filtrage simple et conversion directe.
# Se declenche si build_replay_from_raw_events a crashe OU
# retourne une liste vide OU n'est pas disponible.
try:
replay_actions = _simple_build_replay(cleaned_events, session_dir)
logger.info("Fallback simple_build_replay a produit %d actions", len(replay_actions))
error_message = "" # le fallback a reussi, on efface l'erreur precedente
except Exception as e:
logger.error("Erreur fallback simple_build_replay : %s", e)
error_message = f"Erreur lors de la construction du replay (fallback) : {e}"
@@ -920,9 +923,10 @@ def _simple_build_replay(events: List[Dict[str, Any]], session_dir: Path) -> Lis
action = {
"action_id": action_id,
"type": "click",
"x_percent": round(pos[0] / screen_w * 100, 2) if screen_w else 0,
"y_percent": round(pos[1] / screen_h * 100, 2) if screen_h else 0,
"x_pct": round(pos[0] / screen_w, 6) if screen_w else 0.0,
"y_pct": round(pos[1] / screen_h, 6) if screen_h else 0.0,
"button": inner.get("button", "left"),
"visual_mode": False, # pas d'enrichissement → coords brutes
"wait_before": 0.5,
}
actions.append(action)