""" Custom tools for the deep agent. This module defines two tools: * ``search`` – performs a web search using DuckDuckGo and returns a short snippet of the first result. * ``write_file`` – writes content to the in‑memory virtual file system. The tools are decorated with ``@tool`` from LangChain so that they can be automatically discovered by the agent. """ from langchain.tools import tool import requests from bs4 import BeautifulSoup from .vfs import vfs @tool def search(query: str) -> str: """Search the web for *query* and return a short excerpt. The implementation uses DuckDuckGo's HTML interface. It fetches the first result link, downloads the page and extracts the first five paragraphs. """ try: # DuckDuckGo HTML search url = f"https://duckduckgo.com/html/?q={query}" resp = requests.get(url, timeout=10) resp.raise_for_status() soup = BeautifulSoup(resp.text, "html.parser") # Find first result link results = soup.find_all("a", {"class": "result__a"}, limit=1) if not results: return "No results found." link = results[0].get("href") if not link: return "No link found." # Fetch the page content content_resp = requests.get(link, timeout=10) content_resp.raise_for_status() content_soup = BeautifulSoup(content_resp.text, "html.parser") # Extract text from first few paragraphs paragraphs = content_soup.find_all("p") excerpt = "\n".join(p.get_text() for p in paragraphs[:5]) return excerpt.strip() or "No text extracted." except Exception as e: return f"Error during search: {str(e)}" @tool def write_file(file_path: str, content: str) -> str: """Write *content* to a virtual file named *file_path*. The file is stored in the in‑memory virtual file system and can be exported to disk later. """ vfs.write_file(file_path, content) return f"File {file_path} written."