fix: Fenêtre incorrecte strict → pause supervisée pour apprentissage
Symétrie avec le fix 7cc03f6f1 (no_screen_change strict → paused_need_help).
Avant : si l'agent détecte en pré-vérification que la fenêtre active
n'est pas celle attendue, l'erreur retombait dans la branche retry+stop
legacy → 3 retries inutiles puis status=error et queue vidée.
C'est une violation de feedback_failure_is_learning.md : un échec Léa
n'est jamais un "stop avec error", c'est un moment pédagogique.
Maintenant :
1. L'agent envoie warning="wrong_window" dans le résultat (en plus
de l'error textuel existant). Ajouté aux 2 chemins :
- pré-vérif (expected_window_before mismatch, executor.py ~587)
- post-vérif strict (expected_window_title timeout, executor.py ~820)
2. Le serveur détecte warning="wrong_window" AVANT la branche
retry+stop legacy → redirection vers paused_need_help
3. pause_message explicite : "Je m'attendais à voir la bonne fenêtre
mais je vois autre chose. Peux-tu vérifier que l'application est
au premier plan ?"
4. Queue intacte (l'action reste en tête, prête à être relancée)
5. log_replay_failure pour l'apprentissage futur
Cause fréquente identifiée : les popups de Léa elle-même (notifications,
fenêtre de chat) volent le focus Windows pendant le replay → l'app cible
perd le premier plan → pré-vérif détecte le mismatch. Bug UX séparé à
traiter (Léa ne devrait pas prendre le focus pendant un replay actif).
Appliqué aux 2 copies de l'agent (dev + deploy).
Tests : 56 E2E + Phase0 passent, 0 régression.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3170,6 +3170,68 @@ async def report_action_result(report: ReplayResultReport):
|
||||
replay_state["completed_actions"] += 1
|
||||
replay_state["current_action_index"] += 1
|
||||
|
||||
elif not report.success and agent_warning == "wrong_window":
|
||||
# L'agent a détecté en pré-vérification que la fenêtre active
|
||||
# n'est pas celle attendue. Même philosophie que no_screen_change :
|
||||
# un échec est un moment pédagogique, pas un stop.
|
||||
#
|
||||
# Causes fréquentes : Léa elle-même a pris le focus (popups de
|
||||
# notification/chat), l'app cible s'est fermée, une popup système
|
||||
# est apparue, l'écran a changé entre deux actions.
|
||||
#
|
||||
# On redirige vers paused_need_help pour que l'humain intervienne.
|
||||
_tspec_ww = (original_action or {}).get("target_spec") or report.target_spec or {}
|
||||
_intent_ww = ""
|
||||
_idx_ww = replay_state.get("current_action_index", 0)
|
||||
_actions_ww = replay_state.get("actions", [])
|
||||
if 0 <= _idx_ww < len(_actions_ww):
|
||||
_intent_ww = str((_actions_ww[_idx_ww] or {}).get("intention", "") or "")
|
||||
|
||||
_target_desc_ww = (
|
||||
_intent_ww
|
||||
or _tspec_ww.get("by_text", "")
|
||||
or _tspec_ww.get("vlm_description", "")[:80]
|
||||
or "cette action"
|
||||
)
|
||||
replay_state["status"] = "paused_need_help"
|
||||
replay_state["failed_action"] = {
|
||||
"action_id": action_id,
|
||||
"type": (original_action or {}).get("type", "unknown"),
|
||||
"target_description": _target_desc_ww,
|
||||
"screenshot_b64": screenshot_after or report.screenshot,
|
||||
"target_spec": _tspec_ww,
|
||||
"reason": "wrong_window",
|
||||
"error_detail": report.error or "",
|
||||
}
|
||||
replay_state["pause_message"] = (
|
||||
f"Je m'attendais à voir la bonne fenêtre mais je vois autre "
|
||||
f"chose. Peux-tu vérifier que l'application est au premier "
|
||||
f"plan ? ({report.error or ''})"
|
||||
)
|
||||
error_entry = {
|
||||
"action_id": action_id,
|
||||
"error": report.error or "wrong_window",
|
||||
"retry_count": retry_count,
|
||||
"timestamp": time.time(),
|
||||
}
|
||||
replay_state["error_log"].append(error_entry)
|
||||
logger.warning(
|
||||
f"Replay PAUSE supervisée (wrong_window) : {action_id} "
|
||||
f"— {report.error or 'fenêtre incorrecte'} — en attente "
|
||||
f"d'intervention humaine"
|
||||
)
|
||||
try:
|
||||
log_replay_failure(
|
||||
replay_id=replay_state["replay_id"],
|
||||
action_id=action_id,
|
||||
target_spec=_tspec_ww,
|
||||
screenshot_b64=screenshot_after or report.screenshot,
|
||||
error="wrong_window",
|
||||
extra={"error_detail": report.error or "", "intent": _intent_ww},
|
||||
)
|
||||
except Exception as _log_exc:
|
||||
logger.debug("log_replay_failure skip: %s", _log_exc)
|
||||
|
||||
elif not report.success and agent_warning == "no_screen_change":
|
||||
# L'action a été exécutée mais l'écran n'a pas changé.
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user