feat: blocs conditionnels — skip automatique des dialogues absents

Le session_cleaner détecte les dialogues système (Enregistrer sous,
Ouvrir, Confirmer, etc.) et marque les actions correspondantes comme
conditionnelles. Au replay, si le dialogue n'apparaît pas (ex: Ctrl+S
sauve silencieusement car le fichier existe), les actions du dialogue
sont skippées automatiquement.

Détection basée sur des patterns de noms de dialogues Windows FR/EN.
Testé : seul le clic dans "Enregistrer sous" est conditionnel,
les actions Bloc-notes/Rechercher/systray restent normales.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-04-13 10:20:00 +02:00
parent 01bba7bc6c
commit e9a028134a
2 changed files with 130 additions and 0 deletions

View File

@@ -525,6 +525,44 @@ class ActionExecutorV1:
"visual_resolved": False,
}
# ── Bloc conditionnel : skip si le dialogue n'est pas apparu ──
# Les actions marquées conditional_on_window ne s'exécutent que
# si la fenêtre attendue est effectivement présente. Sinon → skip.
# Ex: Ctrl+S a sauvé silencieusement → pas de "Enregistrer sous"
# → les clics dans le dialogue sont skippés automatiquement.
cond_window = action.get("conditional_on_window")
if cond_window:
try:
from ..window_info_crossplatform import get_active_window_info
current_info = get_active_window_info()
current_title = current_info.get("title", "")
# Comparaison souple (sous-chaîne)
cond_lower = cond_window.lower()
current_lower = current_title.lower() if current_title else ""
match = (
cond_lower in current_lower
or current_lower in cond_lower
)
if not match:
logger.info(
f"[CONDITIONNEL] Skip action {action_id}"
f"dialogue '{cond_window}' absent "
f"(fenêtre actuelle: '{current_title}')"
)
print(
f" [SKIP] Dialogue '{cond_window}' absent → action skippée"
)
result["success"] = True
result["warning"] = "conditional_skipped"
return result
else:
logger.info(
f"[CONDITIONNEL] Dialogue '{cond_window}' présent → exécution"
)
except Exception as e:
logger.debug(f"Vérif conditionnelle échouée : {e}")
# ── Délai inter-actions (anti race condition mss) ──
wait_before = action.get("wait_before", 0.5)
if wait_before > 0: