from typing import List import requests from bs4 import BeautifulSoup from langchain_core.tools import tool DUCKDUCKGO_HTML_URL = "https://html.duckduckgo.com/html/" MAX_RESULTS = 5 REQUEST_TIMEOUT_SECONDS = 10 FALLBACK_MESSAGE = ( "External search returned no results or is unavailable. " "Answer using the available medical knowledge and clearly state " "that no external source was retrieved." ) def _search_duckduckgo(query: str) -> str: response = requests.get( DUCKDUCKGO_HTML_URL, params={"q": query, "kl": "us-en", "kp": "-1"}, headers={"User-Agent": "dmChatbot/1.0"}, timeout=REQUEST_TIMEOUT_SECONDS, ) response.raise_for_status() soup = BeautifulSoup(response.text, "html.parser") results: List[str] = [] for result in soup.select(".result")[:MAX_RESULTS]: link = result.select_one(".result__a") if not link: continue title = link.get_text(" ", strip=True) url = link.get("href", "").strip() snippet_element = result.select_one(".result__snippet") snippet = snippet_element.get_text(" ", strip=True) if snippet_element else "" details = [title] if snippet: details.append(snippet) if url: details.append(url) results.append("\n".join(details)) if not results: raise ValueError("DuckDuckGo returned no search results") return "\n\n".join(results) @tool def web_search_tool(query: str) -> str: """Search the web for medical information or nutritional data.""" try: return _search_duckduckgo(query) except Exception: return FALLBACK_MESSAGE def search_web(query: str) -> str: """Useful for searching the web for medical information or nutritional data.""" return web_search_tool.invoke({"query": query})