From ff581be397bc36737195cdc05f463b4c98ba65f4 Mon Sep 17 00:00:00 2001 From: Dom Date: Tue, 21 Apr 2026 10:29:15 +0200 Subject: [PATCH] =?UTF-8?q?perf:=20seuil=20CLIP=200.45=E2=86=920.20=20+=20?= =?UTF-8?q?cache=20singleton=20IntelligentExecutor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seuil CLIP abaissé pour les icônes génériques (dossier, fichier) qui obtenaient 0.25 au lieu de 0.45. IntelligentExecutor en singleton — CLIP et RF-DETR chargés une seule fois et réutilisés entre les étapes. Élimine le rechargement de ~40s par étape. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../backend/services/intelligent_executor.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/visual_workflow_builder/backend/services/intelligent_executor.py b/visual_workflow_builder/backend/services/intelligent_executor.py index fc0d73841..fe1d54911 100644 --- a/visual_workflow_builder/backend/services/intelligent_executor.py +++ b/visual_workflow_builder/backend/services/intelligent_executor.py @@ -227,8 +227,8 @@ class IntelligentExecutor: # VWB workflows manuels : l'ancre peut être loin de la position d'origine # (résolution différente, écran différent, fenêtre déplacée) MAX_DISTANCE_PX = 500 # Tolérance large pour VWB cross-résolution - MIN_CLIP_SCORE = 0.50 # Score CLIP minimum (0.50 = ressemblance basique) - MIN_COMBINED_SCORE = 0.45 # Score combiné minimum pour accepter un match + MIN_CLIP_SCORE = 0.40 # Score CLIP minimum (baissé pour icônes génériques) + MIN_COMBINED_SCORE = 0.20 # Score combiné minimum (baissé pour cross-résolution) try: # Essayer d'importer et utiliser CLIP @@ -652,6 +652,17 @@ def zoned_template_match( } +_cached_executor: Optional['IntelligentExecutor'] = None + + +def _get_executor(detection_threshold: float = 0.35) -> 'IntelligentExecutor': + """Singleton IntelligentExecutor — modèles chargés une seule fois.""" + global _cached_executor + if _cached_executor is None: + _cached_executor = IntelligentExecutor(detection_threshold=detection_threshold) + return _cached_executor + + def find_and_click( anchor_image_base64: str, anchor_bbox: Optional[Dict[str, int]] = None, @@ -703,7 +714,7 @@ def find_and_click( if method == 'clip': print("🧠 [Vision] Essai UI-DETR-1 + CLIP (matching sémantique)...") try: - executor = IntelligentExecutor(detection_threshold=detection_threshold) + executor = _get_executor(detection_threshold) clip_result = executor.find_anchor_in_screen( screen_image=screen_image, anchor_image=anchor_image,