Revert "fix(navigation): eliminate VLM hallucination on bottom navigation tabs via structural guard"

This reverts commit b9c29a5a2d.
This commit is contained in:
2026-04-29 01:19:18 +02:00
parent b9c29a5a2d
commit 03105437b8
3 changed files with 10 additions and 66 deletions

View File

@@ -133,26 +133,18 @@ def test_visual_discovery_finds_following_by_seeing(make_real_device_with_image)
# ═══════════════════════════════════════════════════════
def test_structural_navigation_guard_bypasses_vlm(make_real_device_with_xml):
def test_resolve_uses_structural_path_when_no_device(make_real_device_with_xml):
"""
TDD PROOF: The Structural Navigation Guard must intercept bottom-nav actions
(like "tap profile tab") and directly return the matching candidate based on
resource-id, entirely bypassing the VLM and Set-of-Mark visual annotation.
When called WITHOUT a device (device=None), resolve() must fall back
to the structural XML-only path instead of visual discovery.
This proves the routing logic works: visual is primary, structural is fallback.
"""
from GramAddict.core.perception.spatial_parser import SpatialNode
resolver = IntentResolver()
# Provide candidates including a trap (Profile picture) and the real tab
# A single candidate with a clear profile_tab match
candidates = [
SpatialNode(
resource_id="com.instagram.android:id/row_feed_photo_profile_imageview",
class_name="android.widget.ImageView",
text="",
content_desc="Profile picture of some user",
bounds=(0, 0, 100, 100),
clickable=True,
),
SpatialNode(
resource_id="com.instagram.android:id/profile_tab",
class_name="android.widget.FrameLayout",
@@ -163,14 +155,7 @@ def test_structural_navigation_guard_bypasses_vlm(make_real_device_with_xml):
)
]
# Device IS provided. Without the structural guard, this would trigger
# visual discovery (which fails in tests without an image).
device = make_real_device_with_xml("tests/fixtures/home_feed_with_ad.xml")
# We resolve the intent
result = resolver.resolve("tap profile tab", candidates, device=device, screen_height=2400)
assert result is not None, "Structural Navigation Guard failed to find the profile tab"
assert result.resource_id == "com.instagram.android:id/profile_tab", (
f"Guard picked the wrong node! Selected: {result.resource_id}"
)
# Without device, resolve must still work via structural matching
result = resolver.resolve("tap profile tab", candidates, screen_height=2400)
assert result is not None, "Structural fallback failed to find profile_tab without a device"
assert result.resource_id == "com.instagram.android:id/profile_tab"