fix: cascade serveur-first — SomEngine avant template matching
Le template matching compare des pixels et donne des faux positifs quand l'écran n'est pas dans le même état que l'enregistrement. SomEngine + VLM comprend sémantiquement ce qu'on cherche. Nouvelle cascade : 1. Serveur SomEngine + VLM (compréhension sémantique) 2. Template matching local (fallback si serveur down) 3. VLM local (fallback dev/test) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -395,10 +395,15 @@ class ActionExecutorV1:
|
||||
) -> dict:
|
||||
"""Résoudre la position d'un clic visuellement.
|
||||
|
||||
Stratégie hybride en cascade :
|
||||
1. Template matching avec le crop anchor (rapide, fiable si l'UI n'a pas changé)
|
||||
2. Serveur resolve_target (SomEngine + VLM, si serveur accessible)
|
||||
3. VLM local (fallback pour dev/test Linux)
|
||||
Stratégie en cascade — compréhension sémantique d'abord :
|
||||
1. Serveur resolve_target (SomEngine + VLM) — comprend CE QU'ON CHERCHE
|
||||
2. Template matching local (fallback rapide si serveur indisponible)
|
||||
3. VLM local (fallback dev/test Linux)
|
||||
|
||||
Le template matching compare des pixels et donne des faux positifs quand
|
||||
l'écran n'est pas dans le même état que l'enregistrement. Le SomEngine
|
||||
comprend sémantiquement les éléments UI (bouton, menu, texte) et trouve
|
||||
le bon élément peu importe l'état de l'écran.
|
||||
"""
|
||||
import time as _time
|
||||
t_start = _time.time()
|
||||
@@ -418,14 +423,8 @@ class ActionExecutorV1:
|
||||
result["resolution_elapsed_ms"] = round(elapsed_ms, 1)
|
||||
return result
|
||||
|
||||
# ---- ÉTAPE 1 : Template matching avec le crop anchor ----
|
||||
anchor_b64 = target_spec.get("anchor_image_base64", "")
|
||||
if anchor_b64:
|
||||
tm_result = self._template_match_anchor(screenshot_b64, anchor_b64, screen_width, screen_height)
|
||||
if tm_result and tm_result.get("resolved"):
|
||||
return _with_metrics(tm_result)
|
||||
|
||||
# ---- ÉTAPE 2 : Résolution serveur (SomEngine + VLM) ----
|
||||
# ---- ÉTAPE 1 : Résolution serveur (SomEngine + VLM) ----
|
||||
# Le serveur comprend sémantiquement ce qu'on cherche. Pas de faux positifs.
|
||||
if server_url:
|
||||
server_result = self._server_resolve_target(
|
||||
server_url, screenshot_b64, target_spec,
|
||||
@@ -434,7 +433,14 @@ class ActionExecutorV1:
|
||||
if server_result and server_result.get("resolved"):
|
||||
return _with_metrics(server_result)
|
||||
|
||||
# ---- ÉTAPE 3 : VLM local (fallback dev/test, si Ollama accessible) ----
|
||||
# ---- ÉTAPE 2 : Template matching local (fallback si serveur down) ----
|
||||
anchor_b64 = target_spec.get("anchor_image_base64", "")
|
||||
if anchor_b64:
|
||||
tm_result = self._template_match_anchor(screenshot_b64, anchor_b64, screen_width, screen_height)
|
||||
if tm_result and tm_result.get("resolved"):
|
||||
return _with_metrics(tm_result)
|
||||
|
||||
# ---- ÉTAPE 3 : VLM local (fallback dev/test Linux) ----
|
||||
by_text = target_spec.get("by_text", "")
|
||||
vlm_description = target_spec.get("vlm_description", "")
|
||||
if vlm_description or by_text:
|
||||
@@ -444,10 +450,6 @@ class ActionExecutorV1:
|
||||
if hybrid_result and hybrid_result.get("resolved"):
|
||||
return _with_metrics(hybrid_result)
|
||||
|
||||
vlm_result = self._vlm_direct_resolve(screenshot_b64, target_spec)
|
||||
if vlm_result and vlm_result.get("resolved"):
|
||||
return _with_metrics(vlm_result)
|
||||
|
||||
print(" [VISUAL] Toutes les méthodes ont échoué")
|
||||
return None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user