""" Lightweight web tools for the agent: DuckDuckGo instant answers and Wikipedia search. These do not require API keys and are suitable for Level-1 GAIA tasks that need quick factual retrieval. They are intentionally simple and return concise text. """ from typing import Optional import requests def duckduckgo_search(query: str, region: str = "wt-wt") -> str: """Use DuckDuckGo Instant Answer API to fetch a brief summary for a query. Returns a short text summarizing the AbstractText and some related topics. """ if not query: return "(no query provided)" try: params = {"q": query, "format": "json", "no_html": 1, "skip_disambig": 1} resp = requests.get("https://api.duckduckgo.com/", params=params, timeout=10) resp.raise_for_status() data = resp.json() parts = [] if data.get("AbstractText"): parts.append(data.get("AbstractText")) # include first related topic text if present related = data.get("RelatedTopics") or [] if related: # RelatedTopics may have nested structure first = related[0] if isinstance(first, dict) and first.get("Text"): parts.append(first.get("Text")) if parts: return " \n".join(parts) # fallback to heading return data.get("Heading") or "(no summary found)" except Exception as e: return f"(duckduckgo error) {e}" def wikipedia_search(query: str) -> str: """Search Wikipedia for a query and return the page summary for the top hit. This function first searches for pages via the MediaWiki API, then fetches the summary for the top search result using the REST summary endpoint. """ if not query: return "(no query provided)" try: search_params = {"action": "query", "list": "search", "srsearch": query, "format": "json", "srlimit": 1} r = requests.get("https://en.wikipedia.org/w/api.php", params=search_params, timeout=10) r.raise_for_status() sr = r.json().get("query", {}).get("search", []) if not sr: return "(no wiki result)" title = sr[0].get("title") # fetch summary summary_resp = requests.get(f"https://en.wikipedia.org/api/rest_v1/page/summary/{requests.utils.requote_uri(title)}", timeout=10) summary_resp.raise_for_status() summary = summary_resp.json() return summary.get("extract") or summary.get("description") or "(no summary)" except Exception as e: return f"(wikipedia error) {e}"