Spaces:
Sleeping
Sleeping
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.
|