File size: 3,552 Bytes
ce0ec3b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Search tools for finding song lyrics and related information.
"""

import time
import random
from typing import Dict, List, Any
from loguru import logger
from smolagents import DuckDuckGoSearchTool, Tool

class ThrottledDuckDuckGoSearchTool(DuckDuckGoSearchTool):
    """
    A wrapper around DuckDuckGoSearchTool that adds a delay between requests
    to avoid rate limiting issues.
    
    This tool implements a delay mechanism to prevent hitting DuckDuckGo's rate limits.
    Each search request will be followed by a random delay within the specified range.
    """
    
    def __init__(self, min_delay: float = 2.0, max_delay: float = 5.0, **kwargs):
        """
        Initialize the throttled search tool with delay parameters.
        
        Args:
            min_delay: Minimum delay in seconds between requests (default: 2.0)
            max_delay: Maximum delay in seconds between requests (default: 5.0)
            **kwargs: Additional arguments to pass to DuckDuckGoSearchTool
        """
        super().__init__(**kwargs)
        self.min_delay = min_delay
        self.max_delay = max_delay
        self.name = "search"  # Keep the same name as the parent class
        logger.info(f"Initialized ThrottledDuckDuckGoSearchTool with delay range: {min_delay}-{max_delay}s")
    
    def forward(self, query: str) -> List[Dict[str, Any]]:
        """
        Execute a search with a delay to avoid rate limiting.
        
        Args:
            query: The search query string
            
        Returns:
            List of search results
        """
        # Add a random delay before the search to avoid rate limiting
        delay = random.uniform(self.min_delay, self.max_delay)
        logger.info(f"Throttling DuckDuckGo search for {delay:.2f} seconds before query: '{query}'")
        time.sleep(delay)
        
        # Call the parent class implementation
        try:
            results = super().forward(query)
            # Add another delay after the search to ensure spacing between requests
            time.sleep(random.uniform(self.min_delay / 2, self.max_delay / 2))
            return results
        except Exception as e:
            logger.error(f"Error in DuckDuckGo search: {str(e)}")
            # Return empty results on error to allow the agent to continue
            return [{"title": "Search error", "href": "", "body": f"Error performing search: {str(e)}"}]


class LyricsSearchTool(Tool):
    """
    Uses web search to find song lyrics based on song title and artist name

    The search query should include the song title and artist name. The tool
    will return the lyrics of the song if found.

    Parameters
    ----------
    query : str
        The search query for finding song lyrics. Should include song title and artist name.

    Returns
    -------
    str
        The lyrics of the song if found, otherwise an empty string.
    """
    name = "lyrics_search_tool"
    description = "Uses web search to find song lyrics based on song title and artist name"
    inputs = {
        "query": {
            "type": "string",
            "description": "The search query for finding song lyrics. Should include song title and artist name.",
        }
    }
    output_type = "string"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def forward(self, query: str) -> str:
        assert isinstance(query, str), "Your search query must be a string"
        # TODO: Implement lyrics search functionality
        return "Lyrics search not implemented yet"