From 2ced57b138bd6bee2ed18864c4d514ae85b81c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=B4=D0=B5=D0=BB=D0=B8=D0=BD=D0=B0=20=D0=A1=D0=B0?= =?UTF-8?q?=D1=82=D1=82=D0=B0=D1=80=D0=BE=D0=B2=D0=B0?= Date: Thu, 4 Jun 2026 13:36:32 +0000 Subject: [PATCH] add search_tool.py --- src/main.py | 53 ---------------------------------------------- src/search_tool.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 53 deletions(-) delete mode 100644 src/main.py create mode 100644 src/search_tool.py diff --git a/src/main.py b/src/main.py deleted file mode 100644 index 9a21fc2..0000000 --- a/src/main.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -Deep Agents from Scratch example. -This script demonstrates a simple agent that searches the web and writes results to files. -It uses the `deep-agents-from-scratch` package as required by the assignment. -""" - -from __future__ import annotations - -import os -from pathlib import Path - -# Ensure dependencies are available -try: - from deep_agents_from_scratch.research_tools import tavily_search, think_tool -except Exception as e: # pragma: no cover - defensive - raise RuntimeError("deep-agents-from-scratch not installed") from e - -from langchain.agents import create_agent -from langchain.chat_models import init_chat_model -from deep_agents_from_scratch.state import DeepAgentState -from deep_agents_from_scratch.file_tools import ls, read_file, write_file - -# Simple prompt for the agent -SYSTEM_PROMPT = """ -You are a research assistant. Use web search to gather information and store results in files. -After each search, reflect on what you found. -""" - -model = init_chat_model(model="anthropic:claude-sonnet-4-20250514", temperature=0) - -# Tools available to the agent -TOOLS = [tavily_search, think_tool, ls, read_file, write_file] - -agent = create_agent( - model, - TOOLS, - system_prompt=SYSTEM_PROMPT, - state_schema=DeepAgentState, -) - -def run_query(query: str) -> None: - """Run a single query and print the resulting messages.""" - result = agent.invoke({"messages": [{"role": "user", "content": query}]}) - for msg in result["messages"]: - print(msg.content) - -if __name__ == "__main__": # pragma: no cover - entry point - import argparse - - parser = argparse.ArgumentParser(description="Run deep agent example") - parser.add_argument("query", help="Query to search for") - args = parser.parse_args() - run_query(args.query) diff --git a/src/search_tool.py b/src/search_tool.py new file mode 100644 index 0000000..ca12745 --- /dev/null +++ b/src/search_tool.py @@ -0,0 +1,53 @@ +"""Internet search tool using DuckDuckGo.""" + +import json +import requests +from bs4 import BeautifulSoup +from langchain.tools import tool + + +@tool +def internet_search(query: str) -> str: + """ + Search DuckDuckGo for information. + + Args: + query: Search query string + + Returns: + JSON string with search results (url, title, snippet) + """ + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' + } + url = "https://html.duckduckgo.com/html/" + params = {"q": query} + + try: + response = requests.get(url, params=params, headers=headers, timeout=10) + response.raise_for_status() + + soup = BeautifulSoup(response.text, "html.parser") + results = [] + + # Parse search results + for result in soup.select(".result")[:3]: + title_elem = result.select_one(".result__a") + link_elem = result.select_one(".result__url") + snippet_elem = result.select_one(".result__snippet") + + if title_elem: + title = title_elem.get_text(strip=True) + link = link_elem.get("href", "") if link_elem else "" + snippet = snippet_elem.get_text(strip=True) if snippet_elem else "" + + results.append({ + "title": title, + "url": link, + "snippet": snippet + }) + + return json.dumps(results, ensure_ascii=False, indent=2) + + except requests.RequestException as e: + return json.dumps({"error": f"Search failed: {str(e)}"}) \ No newline at end of file