Spaces:
Sleeping
Sleeping
""" | |
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" | |