File size: 3,818 Bytes
d853cbf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""
Web Search Tool using DuckDuckGo
Provides web search capability for finding documentation and examples
"""

import logging
from typing import Dict, Any, List
from ddgs import DDGS

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class WebSearchTool:
    """
    Web search tool using DuckDuckGo API
    """
    
    def __init__(self, max_results: int = 5):
        """
        Initialize the web search tool
        
        Args:
            max_results: Maximum number of search results to return (default: 5)
        """
        self.max_results = max_results
    
    def search(self, query: str) -> Dict[str, Any]:
        """
        Search the web using DuckDuckGo
        
        Args:
            query: Search query string
            
        Returns:
            Dictionary containing:
                - success: bool
                - results: list of search results
                - error: str (if any)
        """
        result = {
            'success': False,
            'results': [],
            'error': ''
        }
        
        try:
            logger.info(f"Searching for: {query}")
            
            with DDGS() as ddgs:
                search_results = list(ddgs.text(
                    query,
                    max_results=self.max_results
                ))
            
            # Format results
            formatted_results = []
            for idx, res in enumerate(search_results, 1):
                formatted_results.append({
                    'position': idx,
                    'title': res.get('title', ''),
                    'snippet': res.get('body', ''),
                    'url': res.get('href', '')
                })
            
            result['results'] = formatted_results
            result['success'] = True
            logger.info(f"Found {len(formatted_results)} results")
            
        except Exception as e:
            result['error'] = f"Search error: {str(e)}"
            logger.error(f"Search error: {str(e)}")
        
        return result
    
    def format_results(self, search_results: List[Dict[str, Any]]) -> str:
        """
        Format search results into a readable string
        
        Args:
            search_results: List of search result dictionaries
            
        Returns:
            Formatted string of search results
        """
        if not search_results:
            return "No results found."
        
        formatted = "Search Results:\n\n"
        for res in search_results:
            formatted += f"{res['position']}. {res['title']}\n"
            formatted += f"   {res['snippet']}\n"
            formatted += f"   URL: {res['url']}\n\n"
        
        return formatted
    
    def get_tool_definition(self) -> Dict[str, Any]:
        """
        Get the tool definition for OpenAI function calling
        
        Returns:
            Tool definition dictionary
        """
        return {
            "type": "function",
            "function": {
                "name": "search_web",
                "description": "Search the web using DuckDuckGo to find Python/pandas documentation, code examples, or solutions to data analysis problems. Use this when you need help with specific pandas operations, matplotlib visualizations, or data manipulation techniques.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "query": {
                            "type": "string",
                            "description": "Search query. Be specific and include relevant keywords like 'pandas', 'python', 'matplotlib', etc."
                        }
                    },
                    "required": ["query"]
                }
            }
        }