Skip to content

Instantly share code, notes, and snippets.

@Proteusiq
Last active December 12, 2025 18:51
Show Gist options
  • Select an option

  • Save Proteusiq/6b3caf9baead748364ff00fe8182766d to your computer and use it in GitHub Desktop.

Select an option

Save Proteusiq/6b3caf9baead748364ff00fe8182766d to your computer and use it in GitHub Desktop.
completed
from typing import NamedTuple
import httpx
from smolagents import CodeAgent, LiteLLMModel, Tool
class Coordinates(NamedTuple):
latitude: float
longitude: float
model = LiteLLMModel(
model_id="ollama/qwen3:latest",
temperature=0.2,
api_base="http://localhost:11434",
)
def get_coordinates(query: str) -> Coordinates:
"""Return (latitude, longitude) for a given address in Denmark query."""
base_url = "https://nominatim.openstreetmap.org"
params = {
"q": query,
"format": "json",
"polygon_kml": 1,
"addressdetails": 1,
}
headers = {"User-Agent": "Prayson Daniel"}
with httpx.Client(base_url=base_url, headers=headers) as client:
response = client.get("/search", params=params)
response.raise_for_status()
results, *_ = response.json()
return Coordinates(
latitude=float(results["lat"]), longitude=float(results["lon"])
)
def get_weather(latitude: float, longitude: float) -> str:
"""Return DMI weather for given latitude/longitude."""
print(f"{latitude=!r}, {longitude=!r}")
LOC_URL = "https://www.dmi.dk/NinJo2DmiDk/ninjo2dmidk"
WEATHER_URL = "https://www.dmi.dk/dmidk_byvejrWS/rest/json/id"
loc_params = {
"cmd": "llj",
"hrs": 24,
"lon": longitude,
"lat": latitude,
}
with httpx.Client() as client:
loc_resp = client.get(LOC_URL, params=loc_params)
loc_resp.raise_for_status()
location_id = loc_resp.json().get("id")
if not location_id:
raise ValueError(
f"Could not resolve DMI location ID for ({latitude}, {longitude})"
)
weather_resp = client.get(f"{WEATHER_URL}/{location_id}")
weather_resp.raise_for_status()
report: str = weather_resp.json().get("regionalForecast").get("weatherForecast")
return report
class GeoLocation(Tool):
name = "geolocation_tool"
description = """
Convert a human-readable address into geographic coordinates.
Returns latitude and longitude as a dictionary.
"""
inputs = {
"address": {
"type": "string",
"description": "Any address, e.g. 'Tivoli, Copenhagen' or 'Egedalsvej 14, 2590'.",
}
}
output_type = "object"
def forward(self, address: str) -> dict:
address_clean = "+".join(address.split())
print(f"[GeoLocation] Received address: {address_clean}")
location = get_coordinates(query=address_clean)
return {"latitude": location.latitude, "longitude": location.longitude}
class WeatherReport(Tool):
name = "weather_report_tool"
description = """
Return a simple weather report for a given set of coordinates.
Input: latitude and longitude as numbers.
Output: a human-readable weather summary. Translate it to query language.
"""
inputs = {
"latitude": {
"type": "number",
"description": "Latitude of the location.",
},
"longitude": {
"type": "number",
"description": "Longitude of the location.",
},
}
output_type = "string"
def forward(self, latitude: float, longitude: float) -> str:
report = get_weather(latitude=latitude, longitude=longitude)
return f"The weather at {latitude},{longitude} in danish: {report}"
agent = CodeAgent(
tools=[GeoLocation(), WeatherReport()],
model=model,
stream_outputs=True,
max_steps=5,
)
if __name__ == "__main__":
while True:
query = input("> ")
agent.run(query)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment