fix(replay): réactivation pré-check OCR avec calibrage chirurgical
- Flag RPA_ENABLE_TEXT_PRECHECK défaut true (vs false pendant prépa démo) - radius_px 200 → 280 (englobe textes longs type "Synthèse Urgences") - min_token_ratio 0.60 → 0.50 (tolère onglets fragmentés par OCR) - Commentaire historique restructuré avec procédure troubleshooting - Docstring synchronisée avec valeur effective Audit complet : docs/AUDIT_CONTROLES_DEBRANCHES_2026-05-08.md Réactive contrôle #3 sur 5 identifiés (les 4 autres restent désactivés pour aujourd'hui — décision chirurgicale 1 par 1). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4509,15 +4509,25 @@ async def resolve_target(request: ResolveTargetRequest):
|
||||
# mais pointant sur un autre élément (ex : clic sur "Dossier en cours"
|
||||
# du menu au lieu de "Synthèse Urgences" du tab plus bas).
|
||||
#
|
||||
# 8 mai 2026 : désactivé par défaut pour la démo GHT. Calibrage du
|
||||
# radius_px et min_token_ratio à finaliser post-démo (cf. rapport
|
||||
# docs/E2E_TEST_RUN_2026-05-08.md). Le pré-check était trop strict
|
||||
# sur les onglets à 2 tokens (Examens cliniques, Synthèse Urgences)
|
||||
# → faux rejets → cascade locale Léa V1 → clic au pif. Réactivable
|
||||
# via env RPA_ENABLE_TEXT_PRECHECK=true. Le code et les tests
|
||||
# restent en place pour reprise post-démo.
|
||||
# Pré-check OCR — RÉACTIVÉ le 8 mai 2026
|
||||
# Calibrage : radius_px=280, min_token_ratio=0.50
|
||||
# Désactivable via RPA_ENABLE_TEXT_PRECHECK=false
|
||||
#
|
||||
# Historique :
|
||||
# - 6-7 mai 2026 : assouplissements progressifs des garde-fous
|
||||
# (SoM, mémoire visuelle, exemptions drift) pendant prépa démo GHT
|
||||
# - 8 mai 2026 (matin) : flag défaut "false" posé sur ce pré-check
|
||||
# pour stabiliser (calibrage trop strict — faux rejets sur
|
||||
# onglets à 2 tokens : "Examens cliniques", "Synthèse Urgences")
|
||||
# - 8 mai 2026 (après-midi) : réactivé après calibrage chirurgical
|
||||
# (radius_px 200→280, min_token_ratio 0.60→0.50)
|
||||
#
|
||||
# Si futurs faux rejets observés :
|
||||
# - vérifier d'abord radius_px (élargir si textes longs coupés)
|
||||
# - puis min_token_ratio (abaisser si OCR fragmente)
|
||||
# - NE PAS désactiver sans entrée DECISIONS.md datée
|
||||
_text_precheck_enabled = os.environ.get(
|
||||
"RPA_ENABLE_TEXT_PRECHECK", "false"
|
||||
"RPA_ENABLE_TEXT_PRECHECK", "true"
|
||||
).lower() in ("true", "1", "yes")
|
||||
if _text_precheck_enabled and result and result.get("resolved"):
|
||||
_by_text = (request.target_spec.get("by_text") or "").strip()
|
||||
|
||||
@@ -2243,10 +2243,10 @@ def _validate_text_at_position(
|
||||
expected_text: str,
|
||||
screen_width: int,
|
||||
screen_height: int,
|
||||
radius_px: int = 200,
|
||||
radius_px: int = 280,
|
||||
) -> tuple:
|
||||
"""Pré-check sémantique : OCR sur une zone autour de (x_pct, y_pct) et
|
||||
vérifie que `expected_text` y est présent (substring ou fuzzy 60%).
|
||||
vérifie que `expected_text` y est présent (substring ou fuzzy 50%).
|
||||
|
||||
Retourne (is_valid: bool, observed_text: str, elapsed_ms: float).
|
||||
|
||||
@@ -2282,7 +2282,7 @@ def _validate_text_at_position(
|
||||
results = reader.readtext(np.array(crop))
|
||||
observed = " ".join(r[1] for r in results if r and len(r) >= 2)
|
||||
elapsed_ms = (time.time() - t0) * 1000
|
||||
is_valid = _text_match_fuzzy(expected_text, observed, min_token_ratio=0.60)
|
||||
is_valid = _text_match_fuzzy(expected_text, observed, min_token_ratio=0.50)
|
||||
return is_valid, observed, elapsed_ms
|
||||
except Exception as e:
|
||||
logger.warning("[REPLAY] _validate_text_at_position erreur (%s) — pas de blocage", e)
|
||||
|
||||
Reference in New Issue
Block a user