from __future__ import annotations from typing import List # Prefer the new ddgs package, fall back to duckduckgo_search if needed try: from ddgs import DDGS # new package name except ImportError: from duckduckgo_search import DDGS # old package name from ..state import ResearchSnippet from ..config import settings def web_search(query: str, max_results: int | None = None) -> List[ResearchSnippet]: """ Perform a web search and return normalized snippets. Uses DuckDuckGo via ddgs (preferred) or duckduckgo_search. """ limit = max_results or settings.max_search_results snippets: List[ResearchSnippet] = [] # region/safesearch can matter for results; 'wt-wt' = worldwide, 'off' = no filtering with DDGS() as ddgs: for result in ddgs.text( query, max_results=limit, ): title = result.get("title") or "" url = result.get("href") or result.get("url") or "" snippet = result.get("body") or result.get("snippet") or "" if not snippet.strip(): continue snippets.append( { "title": title.strip(), "url": url.strip(), "snippet": snippet.strip(), } ) return snippets