Skip to content

Commit 86d2a7d

Browse files
committed
feat: implement duckduckgo search, abstract further
1 parent b7774b1 commit 86d2a7d

8 files changed

+65
-11
lines changed

app/prompt/manus.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
BrowserUseTool: Open, browse, and use web browsers.If you open a local HTML file, you must provide the absolute path to the file.
1010
11-
GoogleSearch: Perform web information retrieval
11+
WebSearch: Perform web information retrieval
1212
1313
Terminate: End the current interaction when the task is complete or when you need additional information from the user. Use this tool to signal that you've finished addressing the user's request or need clarification before proceeding further.
1414

app/tool/search/__init__.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from app.tool.search.base import WebSearchEngine
2+
from app.tool.search.baidu_search import BaiduSearchEngine
3+
from app.tool.search.duckduckgo_search import DuckDuckGoSearchEngine
4+
from app.tool.search.google_search import GoogleSearchEngine
5+
6+
7+
__all__ = [
8+
"WebSearchEngine",
9+
"BaiduSearchEngine",
10+
"DuckDuckGoSearchEngine",
11+
"GoogleSearchEngine",
12+
]

app/tool/search/baidu_search.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from baidusearch.baidusearch import search
2+
from app.tool.search.base import WebSearchEngine
3+
4+
5+
class BaiduSearchEngine(WebSearchEngine):
6+
7+
def perform_search(self, query, num_results = 10, *args, **kwargs):
8+
"""Baidu search engine."""
9+
return search(query, num_results=num_results)

app/tool/search/base.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class WebSearchEngine(object):
2+
def perform_search(self, query: str, num_results: int = 10, *args, **kwargs) -> list[dict]:
3+
"""
4+
Perform a web search and return a list of URLs.
5+
6+
Args:
7+
query (str): The search query to submit to the search engine.
8+
num_results (int, optional): The number of search results to return. Default is 10.
9+
args: Additional arguments.
10+
kwargs: Additional keyword arguments.
11+
12+
Returns:
13+
List: A list of dict matching the search query.
14+
"""
15+
raise NotImplementedError

app/tool/search/duckduckgo_search.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from duckduckgo_search import DDGS
2+
from app.tool.search.base import WebSearchEngine
3+
4+
5+
class DuckDuckGoSearchEngine(WebSearchEngine):
6+
7+
async def perform_search(self, query, num_results = 10, *args, **kwargs):
8+
"""DuckDuckGo search engine."""
9+
return DDGS.text(query, num_results=num_results)

app/tool/search/google_search.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from app.tool.search.base import WebSearchEngine
2+
from googlesearch import search
3+
4+
class GoogleSearchEngine(WebSearchEngine):
5+
6+
def perform_search(self, query, num_results = 10, *args, **kwargs):
7+
"""Google search engine."""
8+
return search(query, num_results=num_results)

app/tool/web_search.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import asyncio
22
from typing import List
33

4-
from googlesearch import search as google_search
5-
from baidusearch.baidusearch import search as baidu_search
6-
74
from app.tool.base import BaseTool
85
from app.config import config
6+
from app.tool.search import WebSearchEngine, BaiduSearchEngine, GoogleSearchEngine, DuckDuckGoSearchEngine
97

108

119
class WebSearch(BaseTool):
@@ -29,9 +27,10 @@ class WebSearch(BaseTool):
2927
},
3028
"required": ["query"],
3129
}
32-
_search_engine: dict = {
33-
"google": google_search,
34-
"baidu": baidu_search,
30+
_search_engine: dict[str, WebSearchEngine] = {
31+
"google": GoogleSearchEngine(),
32+
"baidu": BaiduSearchEngine(),
33+
"duckduckgo": DuckDuckGoSearchEngine(),
3534
}
3635

3736
async def execute(self, query: str, num_results: int = 10) -> List[str]:
@@ -53,11 +52,12 @@ async def execute(self, query: str, num_results: int = 10) -> List[str]:
5352
)
5453

5554
return links
56-
57-
def get_search_engine(self):
55+
56+
def get_search_engine(self) -> WebSearchEngine:
5857
"""Determines the search engine to use based on the configuration."""
58+
default_engine = self._search_engine.get("google")
5959
if config.search_config is None:
60-
return google_search
60+
return default_engine
6161
else:
6262
engine = config.search_config.engine.lower()
63-
return self._search_engine.get(engine, google_search)
63+
return self._search_engine.get(engine, default_engine)

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ unidiff~=0.7.5
1616
browser-use~=0.1.40
1717
googlesearch-python~=1.3.0
1818
baidusearch~=1.0.3
19+
duckduckgo_search~=7.5.1
1920

2021
aiofiles~=24.1.0
2122
pydantic_core~=2.27.2

0 commit comments

Comments
 (0)