mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-19 14:23:21 +08:00
初始化:独立 oclaw 仓库首提交
- 在 oclaw/ 下重新初始化 Git 仓库 - 补齐子仓库 .gitignore,避免提交本地运行态数据(_local、node_modules、logs 等) - 提交当前工程代码与配置 Made-with: Cursor
This commit is contained in:
commit
ba3836f00f
579 changed files with 83112 additions and 0 deletions
78
tools/experts/generalist/geo_info.py
Normal file
78
tools/experts/generalist/geo_info.py
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import httpx
|
||||
from typing import Any
|
||||
|
||||
from oclaw.tools.base import ToolSpec
|
||||
from .geo_http import DEFAULT_HTTP_TIMEOUT, ipapi_approximate_location, nominatim_reverse
|
||||
|
||||
|
||||
def _reverse_geocode(lat: float, lon: float) -> dict[str, Any]:
|
||||
with httpx.Client(timeout=DEFAULT_HTTP_TIMEOUT) as client:
|
||||
return nominatim_reverse(client, lat, lon)
|
||||
|
||||
|
||||
def geo_info_tool() -> ToolSpec:
|
||||
def handler(args: dict[str, Any]) -> dict[str, Any]:
|
||||
lat = args.get("latitude")
|
||||
lon = args.get("longitude")
|
||||
if lat is None or lon is None:
|
||||
return {"ok": False, "error": "latitude and longitude are required"}
|
||||
try:
|
||||
lat_f = float(lat)
|
||||
lon_f = float(lon)
|
||||
except (TypeError, ValueError):
|
||||
return {"ok": False, "error": "latitude and longitude must be numbers"}
|
||||
data = _reverse_geocode(lat_f, lon_f)
|
||||
if not data or "error" in data:
|
||||
error_msg = data.get("error") if data else "Unknown error"
|
||||
return {"ok": False, "error": error_msg}
|
||||
return {"ok": True, "address": data.get("display_name"), "details": data.get("address"), "latitude": lat_f, "longitude": lon_f}
|
||||
|
||||
return ToolSpec(
|
||||
name="reverse_geocode",
|
||||
description="Reverse geocode: get a human-readable address from latitude and longitude.",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"latitude": {"type": "number", "description": "Latitude in decimal degrees."},
|
||||
"longitude": {"type": "number", "description": "Longitude in decimal degrees."},
|
||||
},
|
||||
"required": ["latitude", "longitude"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
handler=handler,
|
||||
)
|
||||
|
||||
|
||||
def system_location_tool() -> ToolSpec:
|
||||
def handler(args: dict[str, Any]) -> dict[str, Any]:
|
||||
try:
|
||||
with httpx.Client(timeout=DEFAULT_HTTP_TIMEOUT) as client:
|
||||
loc = ipapi_approximate_location(client)
|
||||
if not loc:
|
||||
return {"ok": False, "error": "Could not detect coordinates for this network"}
|
||||
geo = loc.get("nominatim") or {}
|
||||
return {
|
||||
"ok": True,
|
||||
"latitude": loc["latitude"],
|
||||
"longitude": loc["longitude"],
|
||||
"address": loc["display_name"],
|
||||
"ip": loc.get("ip"),
|
||||
"city": loc.get("city"),
|
||||
"region": loc.get("region"),
|
||||
"country": loc.get("country_name"),
|
||||
"details": geo.get("address") if geo else None,
|
||||
}
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": f"Failed to detect location: {e}"}
|
||||
|
||||
return ToolSpec(
|
||||
name="get_system_location",
|
||||
description="Detect this machine's public IP and approximate location (coordinates and address).",
|
||||
parameters={"type": "object", "properties": {}, "additionalProperties": False},
|
||||
handler=handler,
|
||||
)
|
||||
|
||||
|
||||
__all__ = ["geo_info_tool", "system_location_tool"]
|
||||
Loading…
Add table
Add a link
Reference in a new issue