Files
rpa_vision_v3/agent_v0/agent_v1/finalize_contract.py
Dom 7df51d2c79 snapshot: WIP 5j replay reliability (B1 watchdog + dialog handlers + grounding drift)
Snapshot avant correction du blocage relance Léa (3 incidents 24h: SSH refusé,
polls morts ×2). Point de rollback stable.

Contenu:
- agent_v1/core/executor.py: 5 patchs dialog handling (saveas drift, close_tab
  hotkey fallback, confirm_save Unicode apostrophe, foreground dialog
  recontextualization, runtime_dialog in-loop) + helpers normalize_window_hint,
  requires_post_verify_window_transition
- agent_v1/core/grounding.py: garde drift template fix (fallback_x/y plumbed)
- server_v1/replay_watchdog.py (NEW): orphan watchdog B1, scan 10s timeout 30s
- server_v1/api_stream.py: dispatched_action plumbing, watchdog lifespan,
  metrics endpoint
- server_v1/replay_engine.py: _schedule_retry préserve original_action +
  dispatched_action
- stream_processor.py: gardes _infer_tab_switch_target (no false switch_tab
  on save_as dialog open) + _attach_expected_window_before
- tests/integration: test_replay_watchdog.py (8 cas), test_stream_processor.py
- tests/unit: test_executor_verify_window_guard.py (start_button, close_tab,
  runtime_dialog, post_verify, transition fallbacks)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 16:48:37 +02:00

40 lines
1.2 KiB
Python

"""Dispatch léger du contrat enrichi de /finalize côté agent."""
from __future__ import annotations
import logging
from typing import Any, Dict
logger = logging.getLogger(__name__)
def dispatch_finalize_result(ui: Any, payload: Dict[str, Any], replay_name: str) -> None:
"""Router le résultat de /finalize vers la bonne surface UI agent."""
if not isinstance(payload, dict):
return
replay_request = payload.get("replay_request") or {}
replay_launch = payload.get("replay_launch") or {}
if replay_launch.get("status") == "started":
logger.info("Replay direct déjà lancé par le serveur après finalize")
return
if not payload.get("replay_ready") or not replay_request:
return
if replay_launch.get("status") == "failed":
logger.warning(
"Auto-replay serveur échoué après finalize, proposition manuelle"
)
if ui is None or not hasattr(ui, "offer_finalize_replay"):
logger.info("UI indisponible pour proposer un test immédiat")
return
ui.offer_finalize_replay(
replay_request,
replay_name or "la tâche que vous venez d'enregistrer",
)