Spaces:
Running
Running
Commit
·
52571d9
1
Parent(s):
9f04277
更新多個文件的功能和修復
Browse files- 修復 app.py 中的問題
- 更新 geocode_tool.py 的地理編碼功能
- 優化 ai_service.py 的 AI 服務邏輯
- app.py +24 -0
- features/mcp/tools/geocode_tool.py +29 -5
- services/ai_service.py +4 -0
app.py
CHANGED
|
@@ -858,6 +858,26 @@ async def websocket_endpoint_with_jwt(websocket: WebSocket, token: str = Query(N
|
|
| 858 |
from geohash2 import encode as gh_encode
|
| 859 |
geohash7 = gh_encode(lat, lon, precision=7) if (lat is not None and lon is not None) else None
|
| 860 |
heading_cardinal = _heading_to_cardinal(heading_deg) if heading_deg is not None else None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 861 |
env_payload = {
|
| 862 |
"lat": lat,
|
| 863 |
"lon": lon,
|
|
@@ -868,6 +888,10 @@ async def websocket_endpoint_with_jwt(websocket: WebSocket, token: str = Query(N
|
|
| 868 |
"locale": locale,
|
| 869 |
"device": device,
|
| 870 |
"geohash_7": geohash7,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 871 |
}
|
| 872 |
|
| 873 |
# 更新會話暫存
|
|
|
|
| 858 |
from geohash2 import encode as gh_encode
|
| 859 |
geohash7 = gh_encode(lat, lon, precision=7) if (lat is not None and lon is not None) else None
|
| 860 |
heading_cardinal = _heading_to_cardinal(heading_deg) if heading_deg is not None else None
|
| 861 |
+
city = message_data.get("city")
|
| 862 |
+
admin = message_data.get("admin")
|
| 863 |
+
country_code = message_data.get("country_code")
|
| 864 |
+
address_display = message_data.get("address_display")
|
| 865 |
+
# 若前端未提供城市資訊,嘗試透過 MCP reverse_geocode 取得
|
| 866 |
+
if (not city) and lat is not None and lon is not None:
|
| 867 |
+
try:
|
| 868 |
+
feature_router: MCPAgentBridge = app.state.feature_router
|
| 869 |
+
reverse_tool = feature_router.mcp_server.tools.get("reverse_geocode")
|
| 870 |
+
if reverse_tool and reverse_tool.handler:
|
| 871 |
+
geo_res = await reverse_tool.handler({"lat": lat, "lon": lon})
|
| 872 |
+
if isinstance(geo_res, dict) and geo_res.get("success"):
|
| 873 |
+
payload = geo_res.get("data") or geo_res
|
| 874 |
+
city = payload.get("city") or city
|
| 875 |
+
admin = payload.get("admin") or admin
|
| 876 |
+
country_code = payload.get("country_code") or country_code
|
| 877 |
+
address_display = payload.get("display_name") or payload.get("label") or address_display
|
| 878 |
+
except Exception as ge:
|
| 879 |
+
logger.debug(f"反地理查詢失敗: {ge}")
|
| 880 |
+
|
| 881 |
env_payload = {
|
| 882 |
"lat": lat,
|
| 883 |
"lon": lon,
|
|
|
|
| 888 |
"locale": locale,
|
| 889 |
"device": device,
|
| 890 |
"geohash_7": geohash7,
|
| 891 |
+
"city": city,
|
| 892 |
+
"admin": admin,
|
| 893 |
+
"country_code": country_code,
|
| 894 |
+
"address_display": address_display,
|
| 895 |
}
|
| 896 |
|
| 897 |
# 更新會話暫存
|
features/mcp/tools/geocode_tool.py
CHANGED
|
@@ -57,7 +57,7 @@ class ReverseGeocodeTool(MCPTool):
|
|
| 57 |
cached = await db_cache.get_geo_cached(geokey)
|
| 58 |
if cached:
|
| 59 |
return cls.create_success_response(
|
| 60 |
-
content=f"{cached.get('city')}, {cached.get('admin')}",
|
| 61 |
data=cached
|
| 62 |
)
|
| 63 |
|
|
@@ -66,7 +66,7 @@ class ReverseGeocodeTool(MCPTool):
|
|
| 66 |
if db_cached:
|
| 67 |
await db_cache.set_geo_cache(geokey, db_cached)
|
| 68 |
return cls.create_success_response(
|
| 69 |
-
content=f"{db_cached.get('city')}, {db_cached.get('admin')}",
|
| 70 |
data=db_cached
|
| 71 |
)
|
| 72 |
|
|
@@ -92,11 +92,35 @@ class ReverseGeocodeTool(MCPTool):
|
|
| 92 |
city = addr.get("city") or addr.get("town") or addr.get("village") or addr.get("county")
|
| 93 |
admin = addr.get("state") or addr.get("county") or ""
|
| 94 |
country_code = (addr.get("country_code") or "").upper()
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
# 回寫快取
|
| 98 |
await db_cache.set_geo_cache(geokey, payload)
|
| 99 |
await set_geo_cache(geokey, payload)
|
| 100 |
|
| 101 |
-
return cls.create_success_response(content=f"{payload['city']}, {payload['admin']}", data=payload)
|
| 102 |
-
|
|
|
|
| 57 |
cached = await db_cache.get_geo_cached(geokey)
|
| 58 |
if cached:
|
| 59 |
return cls.create_success_response(
|
| 60 |
+
content=cached.get("display_name") or f"{cached.get('city')}, {cached.get('admin')}",
|
| 61 |
data=cached
|
| 62 |
)
|
| 63 |
|
|
|
|
| 66 |
if db_cached:
|
| 67 |
await db_cache.set_geo_cache(geokey, db_cached)
|
| 68 |
return cls.create_success_response(
|
| 69 |
+
content=db_cached.get("display_name") or f"{db_cached.get('city')}, {db_cached.get('admin')}",
|
| 70 |
data=db_cached
|
| 71 |
)
|
| 72 |
|
|
|
|
| 92 |
city = addr.get("city") or addr.get("town") or addr.get("village") or addr.get("county")
|
| 93 |
admin = addr.get("state") or addr.get("county") or ""
|
| 94 |
country_code = (addr.get("country_code") or "").upper()
|
| 95 |
+
display_name = data.get("display_name") or ""
|
| 96 |
+
road = addr.get("road") or addr.get("pedestrian") or addr.get("footway") or ""
|
| 97 |
+
house_number = addr.get("house_number") or ""
|
| 98 |
+
suburb = addr.get("suburb") or addr.get("neighbourhood") or ""
|
| 99 |
+
label_parts = []
|
| 100 |
+
if road and house_number:
|
| 101 |
+
label_parts.append(f"{road}{house_number}")
|
| 102 |
+
elif road:
|
| 103 |
+
label_parts.append(road)
|
| 104 |
+
if suburb:
|
| 105 |
+
label_parts.append(suburb)
|
| 106 |
+
if city:
|
| 107 |
+
label_parts.append(city)
|
| 108 |
+
if admin:
|
| 109 |
+
label_parts.append(admin)
|
| 110 |
+
label = ", ".join(label_parts)
|
| 111 |
+
payload = {
|
| 112 |
+
"city": city or "",
|
| 113 |
+
"admin": admin or "",
|
| 114 |
+
"country_code": country_code,
|
| 115 |
+
"display_name": display_name,
|
| 116 |
+
"label": label or display_name,
|
| 117 |
+
"road": road,
|
| 118 |
+
"house_number": house_number,
|
| 119 |
+
"suburb": suburb,
|
| 120 |
+
}
|
| 121 |
|
| 122 |
# 回寫快取
|
| 123 |
await db_cache.set_geo_cache(geokey, payload)
|
| 124 |
await set_geo_cache(geokey, payload)
|
| 125 |
|
| 126 |
+
return cls.create_success_response(content=payload.get("label") or f"{payload['city']}, {payload['admin']}", data=payload)
|
|
|
services/ai_service.py
CHANGED
|
@@ -198,6 +198,10 @@ def _format_env_context(ctx: Dict[str, Any]) -> str:
|
|
| 198 |
if device:
|
| 199 |
parts.append(f"裝置: {device}")
|
| 200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
return "\n".join(parts)
|
| 202 |
|
| 203 |
|
|
|
|
| 198 |
if device:
|
| 199 |
parts.append(f"裝置: {device}")
|
| 200 |
|
| 201 |
+
address_display = (ctx.get("address_display") or "").strip()
|
| 202 |
+
if address_display:
|
| 203 |
+
parts.append(f"地點: {address_display}")
|
| 204 |
+
|
| 205 |
return "\n".join(parts)
|
| 206 |
|
| 207 |
|