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:
|
) -> dict:
|
||||||
"""Résoudre la position d'un clic visuellement.
|
"""Résoudre la position d'un clic visuellement.
|
||||||
|
|
||||||
Stratégie hybride en cascade :
|
Stratégie en cascade — compréhension sémantique d'abord :
|
||||||
1. Template matching avec le crop anchor (rapide, fiable si l'UI n'a pas changé)
|
1. Serveur resolve_target (SomEngine + VLM) — comprend CE QU'ON CHERCHE
|
||||||
2. Serveur resolve_target (SomEngine + VLM, si serveur accessible)
|
2. Template matching local (fallback rapide si serveur indisponible)
|
||||||
3. VLM local (fallback pour dev/test Linux)
|
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
|
import time as _time
|
||||||
t_start = _time.time()
|
t_start = _time.time()
|
||||||
@@ -418,14 +423,8 @@ class ActionExecutorV1:
|
|||||||
result["resolution_elapsed_ms"] = round(elapsed_ms, 1)
|
result["resolution_elapsed_ms"] = round(elapsed_ms, 1)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# ---- ÉTAPE 1 : Template matching avec le crop anchor ----
|
# ---- ÉTAPE 1 : Résolution serveur (SomEngine + VLM) ----
|
||||||
anchor_b64 = target_spec.get("anchor_image_base64", "")
|
# Le serveur comprend sémantiquement ce qu'on cherche. Pas de faux positifs.
|
||||||
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) ----
|
|
||||||
if server_url:
|
if server_url:
|
||||||
server_result = self._server_resolve_target(
|
server_result = self._server_resolve_target(
|
||||||
server_url, screenshot_b64, target_spec,
|
server_url, screenshot_b64, target_spec,
|
||||||
@@ -434,7 +433,14 @@ class ActionExecutorV1:
|
|||||||
if server_result and server_result.get("resolved"):
|
if server_result and server_result.get("resolved"):
|
||||||
return _with_metrics(server_result)
|
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", "")
|
by_text = target_spec.get("by_text", "")
|
||||||
vlm_description = target_spec.get("vlm_description", "")
|
vlm_description = target_spec.get("vlm_description", "")
|
||||||
if vlm_description or by_text:
|
if vlm_description or by_text:
|
||||||
@@ -444,10 +450,6 @@ class ActionExecutorV1:
|
|||||||
if hybrid_result and hybrid_result.get("resolved"):
|
if hybrid_result and hybrid_result.get("resolved"):
|
||||||
return _with_metrics(hybrid_result)
|
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é")
|
print(" [VISUAL] Toutes les méthodes ont échoué")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user