Sborole commited on
Commit
41225c1
·
verified ·
1 Parent(s): 1f627a7

Update tools/WebSearchTool.py

Browse files
Files changed (1) hide show
  1. tools/WebSearchTool.py +51 -37
tools/WebSearchTool.py CHANGED
@@ -1,31 +1,24 @@
1
- import os
2
  import requests
3
  from smolagents import Tool
 
4
 
5
- class SerpApiSearchTool(Tool):
6
  """
7
- A tool to perform web search using the SerpApi engine.
8
- This tool should be used to find current information and general knowledge.
 
9
  """
10
- name = "serpapi_search"
11
- description = "Use SerpApi to find current information and general knowledge. Returns a snippet and URL."
12
 
13
  inputs = {
14
  "query": {"type": "string", "description": "The search term to look up."}
15
  }
16
  output_type = "string"
17
 
18
- def __init__(self, **kwargs):
19
- super().__init__(**kwargs)
20
- # Retrieve API key from environment variables
21
- self.api_key = os.getenv("SERPAPI_KEY")
22
-
23
- if not self.api_key:
24
- raise ValueError("SERPAPI_KEY secret not found. Check environment variables.")
25
-
26
  def forward(self, query: str) -> str:
27
  """
28
- Executes a SerpApi search query and formats the top results (up to 3).
29
 
30
  Args:
31
  query: The search term provided by the agent.
@@ -33,42 +26,63 @@ class SerpApiSearchTool(Tool):
33
  Returns:
34
  A formatted string of search results, or an error message.
35
  """
36
- print(f"Executing SerpApi search for: '{query}'")
37
 
38
- search_url = "https://serpapi.com/search"
 
39
  params = {
40
  "q": query,
41
- "engine": "google", # Use Google search engine via SerpApi
42
- "api_key": self.api_key,
43
- "num": 3,
 
44
  }
45
 
46
  try:
47
  # Make the API request
48
  response = requests.get(search_url, params=params)
49
- response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
50
  data = response.json()
51
 
52
- # Extract the organic results
53
- items = data.get('organic_results', [])
54
 
55
- if not items:
56
- # Return the specific failure message expected by the agent
57
- return "XX record info: No results found."
58
-
59
- search_results = []
60
- # Process the top 3 results (since 'num=3' was requested)
61
- for i, item in enumerate(items):
62
- search_results.append(
63
- f"RESULT {i+1}: '{item.get('title', 'N/A')}'\n"
64
- f"CONTENT: {item.get('snippet', 'No snippet available.')}\n"
65
- f"SOURCE: {item.get('link', 'N/A')}"
66
  )
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  # Join the results with a clear separator
69
- return "\n\n---SEPARATOR---\n\n".join(search_results)
70
 
71
  except requests.exceptions.RequestException as e:
72
- return f"Error during SerpApi Request: {e}"
73
  except Exception as e:
74
- return f"Error processing SerpApi results: {e}"
 
 
1
  import requests
2
  from smolagents import Tool
3
+ import json
4
 
5
+ class DuckDuckGoSearchTool(Tool):
6
  """
7
+ A tool to perform general web searches using the DuckDuckGo Instant Answer API.
8
+ This tool is a free and accessible alternative when other search APIs require keys or payment.
9
+ It's best for obtaining quick, summarized facts and related links.
10
  """
11
+ name = "duckduckgo_search"
12
+ description = "Use DuckDuckGo to find current information and general knowledge, returning summarized answers and relevant search results."
13
 
14
  inputs = {
15
  "query": {"type": "string", "description": "The search term to look up."}
16
  }
17
  output_type = "string"
18
 
 
 
 
 
 
 
 
 
19
  def forward(self, query: str) -> str:
20
  """
21
+ Executes a DuckDuckGo search query and formats the top results.
22
 
23
  Args:
24
  query: The search term provided by the agent.
 
26
  Returns:
27
  A formatted string of search results, or an error message.
28
  """
29
+ print(f"Executing DuckDuckGo Search for: '{query}'")
30
 
31
+ # DuckDuckGo Zero-click API endpoint
32
+ search_url = "https://api.duckduckgo.com/"
33
  params = {
34
  "q": query,
35
+ "format": "json",
36
+ "no_redirect": "1", # Do not redirect to a search page
37
+ "no_html": "1", # Remove HTML from results
38
+ "t": "smolagents" # Application name for logging
39
  }
40
 
41
  try:
42
  # Make the API request
43
  response = requests.get(search_url, params=params)
44
+ response.raise_for_status()
45
  data = response.json()
46
 
47
+ results = []
 
48
 
49
+ # 1. Instant Answer (if available)
50
+ abstract_text = data.get('AbstractText')
51
+ abstract_url = data.get('AbstractURL')
52
+
53
+ if abstract_text and abstract_url:
54
+ results.append(
55
+ f"RESULT 1 (Instant Answer): '{data.get('Heading', 'Summary')}'\n"
56
+ f"CONTENT: {abstract_text}\n"
57
+ f"SOURCE: {abstract_url}"
 
 
58
  )
59
 
60
+ # 2. Related Topics (for more search results)
61
+ # This often contains deep links or snippets for further reading
62
+ topics = data.get('RelatedTopics', [])
63
+
64
+ # Filter and take up to the next 2 relevant topics
65
+ for i, topic in enumerate(topics[:2]):
66
+ # Check for a standard result structure
67
+ if 'Result' in topic and 'Text' in topic:
68
+ # Parse the snippet/link info from the 'Result' field (usually HTML but 'no_html' helps)
69
+ snippet = topic['Text']
70
+ link = topic.get('FirstURL', 'N/A')
71
+ title = snippet.split(' - ')[0] if ' - ' in snippet else 'Related Topic'
72
+
73
+ results.append(
74
+ f"RESULT {len(results) + 1}: '{title}'\n"
75
+ f"CONTENT: {snippet}\n"
76
+ f"SOURCE: {link}"
77
+ )
78
+
79
+ if not results:
80
+ return "XX record info: No results found."
81
+
82
  # Join the results with a clear separator
83
+ return "\n\n---SEPARATOR---\n\n".join(results)
84
 
85
  except requests.exceptions.RequestException as e:
86
+ return f"Error during DuckDuckGo API Request: {e}"
87
  except Exception as e:
88
+ return f"Error processing DuckDuckGo results: {e}"