diff --git a/src/deep_agents_from_scratch/research_tools.py b/src/deep_agents_from_scratch/research_tools.py new file mode 100644 index 0000000..916682e --- /dev/null +++ b/src/deep_agents_from_scratch/research_tools.py @@ -0,0 +1,67 @@ +"""Research tools for the deep agent. + +This module contains three tools used by the graph: + +* ``tavily_search`` – performs a web search using the Tavily API. +* ``think_tool`` – a simple tool that decides the next action. +* ``summarize_webpage_content`` – generates a summary of a webpage. + +The implementations are intentionally lightweight and rely on LangChain +tool wrappers. +""" + +from __future__ import annotations + +from typing import Dict, List, Any + +from langchain_core.messages import HumanMessage +from langchain_core.tools import tool +from langchain_openai import ChatOpenAI +from langchain.prompts import PromptTemplate + +# Simple summarization model +summary_llm = ChatOpenAI(model="gpt-4o-mini") + +# Prompt for summarization +SUMMARIZE_PROMPT = PromptTemplate( + input_variables=["content"], + template=""" +You are a helpful assistant. Summarize the following webpage content in 3-5 sentences. + +Content: +{content} + +Summary: +""", +) + +@tool("tavily_search") +async def tavily_search(search_query: str) -> List[Dict[str, Any]]: + """Perform a web search using the Tavily API. + + The function returns a list of dictionaries each containing + ``title``, ``url`` and ``content`` (raw HTML). + """ + from tavily import TavilyClient + client = TavilyClient() + result = client.search(search_query, max_results=3, include_raw_content=True) + return result + +@tool("think_tool") +async def think_tool(query: str) -> str: + """Return the next query to search. + + For the demo we simply echo the query back – in a real agent this + could be a more sophisticated planning step. + """ + return query + +@tool("summarize_webpage_content") +async def summarize_webpage_content(content: str) -> Dict[str, Any]: + """Generate a summary for a webpage. + + Returns a dict with ``filename`` and ``summary``. + """ + response = await summary_llm.invoke([HumanMessage(content=SUMMARIZE_PROMPT.format(content=content))]) + summary_text = response.content.strip() + return {"filename": "summary.md", "summary": summary_text} \ No newline at end of file