Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from typing import Any, Optional | |
| from smolagents.tools import Tool | |
| class WebSearchTool(Tool): | |
| name = "web_search" | |
| description = "Search the web with DuckDuckGo and return a short list of results." | |
| inputs = { | |
| "query": {"type": "string", "description": "Search query."}, | |
| "max_results": { | |
| "type": "integer", | |
| "description": "Maximum number of results to return (1-10). Defaults to 5.", | |
| "nullable": True, | |
| }, | |
| } | |
| output_type = "any" | |
| def forward(self, query: str, max_results: Optional[int] = 5) -> Any: | |
| if not isinstance(query, str) or not query.strip(): | |
| raise ValueError("`query` must be a non-empty string.") | |
| limit = 5 if max_results is None else int(max_results) | |
| limit = max(1, min(10, limit)) | |
| try: | |
| from ddgs import DDGS # type: ignore | |
| except Exception as e: # pragma: no cover | |
| raise ModuleNotFoundError("Missing dependency: `ddgs` (pip install ddgs).") from e | |
| results: list[dict[str, str]] = [] | |
| with DDGS() as ddgs: | |
| for r in ddgs.text(query, max_results=limit): | |
| title = (r.get("title") or "").strip() | |
| url = (r.get("href") or r.get("url") or "").strip() | |
| snippet = (r.get("body") or r.get("snippet") or "").strip() | |
| if not (title or url or snippet): | |
| continue | |
| results.append({"title": title, "url": url, "snippet": snippet}) | |
| return results | |