Spaces:
Running
Running
Andy Lee
commited on
Commit
·
d1cf019
1
Parent(s):
749ea04
feat: bigger arrow and label
Browse files- geo_bot.py +14 -7
- mapcrunch_controller.py +85 -0
geo_bot.py
CHANGED
@@ -12,6 +12,8 @@ from langchain_google_genai import ChatGoogleGenerativeAI
|
|
12 |
|
13 |
from mapcrunch_controller import MapCrunchController
|
14 |
|
|
|
|
|
15 |
AGENT_PROMPT_TEMPLATE = """
|
16 |
**Mission:** You are an expert geo-location agent. Your goal is to find clues to determine your location within a limited number of steps.
|
17 |
|
@@ -22,16 +24,19 @@ AGENT_PROMPT_TEMPLATE = """
|
|
22 |
---
|
23 |
**Core Principles of an Expert Player:**
|
24 |
|
25 |
-
1. **
|
26 |
-
|
27 |
-
|
28 |
-
- At
|
29 |
-
- If a path
|
30 |
-
|
|
|
|
|
|
|
31 |
|
32 |
---
|
33 |
**Context & Task:**
|
34 |
-
|
35 |
|
36 |
**Action History:**
|
37 |
{history_text}
|
@@ -133,6 +138,8 @@ class GeoBot:
|
|
133 |
|
134 |
self.controller.setup_clean_environment()
|
135 |
|
|
|
|
|
136 |
screenshot_bytes = self.controller.take_street_view_screenshot()
|
137 |
if not screenshot_bytes:
|
138 |
print("Failed to take screenshot. Ending agent loop.")
|
|
|
12 |
|
13 |
from mapcrunch_controller import MapCrunchController
|
14 |
|
15 |
+
# The "Golden" Prompt (v6): Combines clear mechanics with robust strategic principles.
|
16 |
+
|
17 |
AGENT_PROMPT_TEMPLATE = """
|
18 |
**Mission:** You are an expert geo-location agent. Your goal is to find clues to determine your location within a limited number of steps.
|
19 |
|
|
|
24 |
---
|
25 |
**Core Principles of an Expert Player:**
|
26 |
|
27 |
+
1. **Navigate with Labels:** `MOVE_FORWARD` follows the green 'UP' arrow. `MOVE_BACKWARD` follows the red 'DOWN' arrow. These labels are your most reliable compass. If there are no arrows, you cannot move.
|
28 |
+
|
29 |
+
2. **Efficient Exploration (to avoid "Bulldozer" mode):**
|
30 |
+
- **Pan Before You Move:** At a new location or an intersection, it's often wise to use `PAN_LEFT` or `PAN_RIGHT` to quickly survey your surroundings before committing to a move.
|
31 |
+
- **Don't Get Stuck:** If you've moved forward 2-3 times down a path and found nothing but repetitive scenery (like an empty forest or highway), consider it a barren path. It's smarter to turn around (using `PAN`) and check another direction.
|
32 |
+
|
33 |
+
3. **Be Decisive:** If you find a truly definitive clue (like a full, readable address or a sign with a unique town name), `GUESS` immediately. Don't waste steps.
|
34 |
+
|
35 |
+
4. **Final Step Rule:** If `remaining_steps` is **exactly 1**, your action **MUST be `GUESS`**.
|
36 |
|
37 |
---
|
38 |
**Context & Task:**
|
39 |
+
Analyze your full journey history and current view, apply the Core Principles, and decide your next action in the required JSON format.
|
40 |
|
41 |
**Action History:**
|
42 |
{history_text}
|
|
|
138 |
|
139 |
self.controller.setup_clean_environment()
|
140 |
|
141 |
+
self.controller.label_arrows_on_screen()
|
142 |
+
|
143 |
screenshot_bytes = self.controller.take_street_view_screenshot()
|
144 |
if not screenshot_bytes:
|
145 |
print("Failed to take screenshot. Ending agent loop.")
|
mapcrunch_controller.py
CHANGED
@@ -36,6 +36,91 @@ class MapCrunchController:
|
|
36 |
if (infoFirstView) infoFirstView.style.display = 'none';
|
37 |
""")
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
def get_available_actions(self) -> List[str]:
|
40 |
"""
|
41 |
Checks for movement links via JavaScript.
|
|
|
36 |
if (infoFirstView) infoFirstView.style.display = 'none';
|
37 |
""")
|
38 |
|
39 |
+
def label_arrows_on_screen(self):
|
40 |
+
"""Overlays 'UP' and 'DOWN' labels on the navigation arrows."""
|
41 |
+
try:
|
42 |
+
pov = self.driver.execute_script("return window.panorama.getPov();")
|
43 |
+
links = self.driver.execute_script("return window.panorama.getLinks();")
|
44 |
+
except Exception:
|
45 |
+
return
|
46 |
+
|
47 |
+
if not links or not pov:
|
48 |
+
return
|
49 |
+
|
50 |
+
current_heading = pov["heading"]
|
51 |
+
forward_link = None
|
52 |
+
backward_link = None
|
53 |
+
|
54 |
+
# This logic is identical to your existing `move` function
|
55 |
+
# to ensure stylistic and behavioral consistency.
|
56 |
+
min_forward_diff = 360
|
57 |
+
for link in links:
|
58 |
+
diff = 180 - abs(abs(link["heading"] - current_heading) - 180)
|
59 |
+
if diff < min_forward_diff:
|
60 |
+
min_forward_diff = diff
|
61 |
+
forward_link = link
|
62 |
+
|
63 |
+
target_backward_heading = (current_heading + 180) % 360
|
64 |
+
min_backward_diff = 360
|
65 |
+
for link in links:
|
66 |
+
diff = 180 - abs(abs(link["heading"] - target_backward_heading) - 180)
|
67 |
+
if diff < min_backward_diff:
|
68 |
+
min_backward_diff = diff
|
69 |
+
backward_link = link
|
70 |
+
|
71 |
+
js_script = """
|
72 |
+
document.querySelectorAll('.geobot-arrow-label').forEach(el => el.remove());
|
73 |
+
document.querySelectorAll('path[data-geobot-modified]').forEach(arrow => {
|
74 |
+
arrow.setAttribute('transform', arrow.getAttribute('data-original-transform') || '');
|
75 |
+
arrow.removeAttribute('data-geobot-modified');
|
76 |
+
arrow.removeAttribute('data-original-transform');
|
77 |
+
});
|
78 |
+
|
79 |
+
const modifyAndLabelArrow = (panoId, labelText, color) => {
|
80 |
+
const arrowElement = document.querySelector(`path[pano="${panoId}"]`);
|
81 |
+
if (!arrowElement) return;
|
82 |
+
|
83 |
+
const originalTransform = arrowElement.getAttribute('transform') || '';
|
84 |
+
arrowElement.setAttribute('data-original-transform', originalTransform);
|
85 |
+
arrowElement.setAttribute('transform', `${originalTransform} scale(1.8)`);
|
86 |
+
arrowElement.setAttribute('data-geobot-modified', 'true');
|
87 |
+
|
88 |
+
const rect = arrowElement.getBoundingClientRect();
|
89 |
+
const label = document.createElement('div');
|
90 |
+
label.className = 'geobot-arrow-label';
|
91 |
+
label.style.position = 'fixed';
|
92 |
+
label.style.left = `${rect.left + rect.width / 2}px`;
|
93 |
+
label.style.top = `${rect.top - 45}px`;
|
94 |
+
label.style.transform = 'translateX(-50%)';
|
95 |
+
label.style.padding = '5px 15px';
|
96 |
+
label.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
|
97 |
+
label.style.color = color;
|
98 |
+
label.style.borderRadius = '8px';
|
99 |
+
label.style.fontSize = '28px';
|
100 |
+
label.style.fontWeight = 'bold';
|
101 |
+
label.style.zIndex = '99999';
|
102 |
+
label.style.pointerEvents = 'none';
|
103 |
+
label.innerText = labelText;
|
104 |
+
document.body.appendChild(label);
|
105 |
+
};
|
106 |
+
|
107 |
+
const forwardPano = arguments[0];
|
108 |
+
const backwardPano = arguments[1];
|
109 |
+
|
110 |
+
if (forwardPano) {
|
111 |
+
modifyAndLabelArrow(forwardPano, 'UP', '#76FF03');
|
112 |
+
}
|
113 |
+
if (backwardPano && backwardPano !== forwardPano) {
|
114 |
+
modifyAndLabelArrow(backwardPano, 'DOWN', '#F44336');
|
115 |
+
}
|
116 |
+
"""
|
117 |
+
|
118 |
+
forward_pano = forward_link["pano"] if forward_link else None
|
119 |
+
backward_pano = backward_link["pano"] if backward_link else None
|
120 |
+
|
121 |
+
self.driver.execute_script(js_script, forward_pano, backward_pano)
|
122 |
+
time.sleep(0.2)
|
123 |
+
|
124 |
def get_available_actions(self) -> List[str]:
|
125 |
"""
|
126 |
Checks for movement links via JavaScript.
|