Last active
December 12, 2025 18:51
-
-
Save Proteusiq/6b3caf9baead748364ff00fe8182766d to your computer and use it in GitHub Desktop.
completed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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