feat: add baidu search tool and optional config
This commit is contained in:
parent
3db1a7fb56
commit
bbaff4f095
@ -8,7 +8,9 @@ from app.tool import Terminate, ToolCollection
|
|||||||
from app.tool.browser_use_tool import BrowserUseTool
|
from app.tool.browser_use_tool import BrowserUseTool
|
||||||
from app.tool.file_saver import FileSaver
|
from app.tool.file_saver import FileSaver
|
||||||
from app.tool.google_search import GoogleSearch
|
from app.tool.google_search import GoogleSearch
|
||||||
|
from app.tool.baidu_search import BaiduSearch
|
||||||
from app.tool.python_execute import PythonExecute
|
from app.tool.python_execute import PythonExecute
|
||||||
|
from app.config import config
|
||||||
|
|
||||||
|
|
||||||
class Manus(ToolCallAgent):
|
class Manus(ToolCallAgent):
|
||||||
@ -34,10 +36,23 @@ class Manus(ToolCallAgent):
|
|||||||
# Add general-purpose tools to the tool collection
|
# Add general-purpose tools to the tool collection
|
||||||
available_tools: ToolCollection = Field(
|
available_tools: ToolCollection = Field(
|
||||||
default_factory=lambda: ToolCollection(
|
default_factory=lambda: ToolCollection(
|
||||||
PythonExecute(), GoogleSearch(), BrowserUseTool(), FileSaver(), Terminate()
|
PythonExecute(), Manus.get_search_tool(), BrowserUseTool(), FileSaver(), Terminate()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_search_tool():
|
||||||
|
"""Determines the search tool to use based on the configuration."""
|
||||||
|
print(config.search_config)
|
||||||
|
if config.search_config is None:
|
||||||
|
return GoogleSearch()
|
||||||
|
else:
|
||||||
|
# Check search engine
|
||||||
|
engine = config.search_config.engine.lower()
|
||||||
|
if engine == "baidu":
|
||||||
|
return BaiduSearch()
|
||||||
|
return GoogleSearch()
|
||||||
|
|
||||||
async def _handle_special_tool(self, name: str, result: Any, **kwargs):
|
async def _handle_special_tool(self, name: str, result: Any, **kwargs):
|
||||||
await self.available_tools.get_tool(BrowserUseTool().name).cleanup()
|
await self.available_tools.get_tool(BrowserUseTool().name).cleanup()
|
||||||
await super()._handle_special_tool(name, result, **kwargs)
|
await super()._handle_special_tool(name, result, **kwargs)
|
||||||
|
@ -30,6 +30,8 @@ class ProxySettings(BaseModel):
|
|||||||
username: Optional[str] = Field(None, description="Proxy username")
|
username: Optional[str] = Field(None, description="Proxy username")
|
||||||
password: Optional[str] = Field(None, description="Proxy password")
|
password: Optional[str] = Field(None, description="Proxy password")
|
||||||
|
|
||||||
|
class SearchSettings(BaseModel):
|
||||||
|
engine: str = Field(default='Google', description="Search engine the llm to use")
|
||||||
|
|
||||||
class BrowserSettings(BaseModel):
|
class BrowserSettings(BaseModel):
|
||||||
headless: bool = Field(False, description="Whether to run browser in headless mode")
|
headless: bool = Field(False, description="Whether to run browser in headless mode")
|
||||||
@ -58,6 +60,9 @@ class AppConfig(BaseModel):
|
|||||||
browser_config: Optional[BrowserSettings] = Field(
|
browser_config: Optional[BrowserSettings] = Field(
|
||||||
None, description="Browser configuration"
|
None, description="Browser configuration"
|
||||||
)
|
)
|
||||||
|
search_config: Optional[SearchSettings] = Field(
|
||||||
|
None, description="Search configuration"
|
||||||
|
)
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
arbitrary_types_allowed = True
|
arbitrary_types_allowed = True
|
||||||
@ -149,6 +154,12 @@ class Config:
|
|||||||
if valid_browser_params:
|
if valid_browser_params:
|
||||||
browser_settings = BrowserSettings(**valid_browser_params)
|
browser_settings = BrowserSettings(**valid_browser_params)
|
||||||
|
|
||||||
|
search_config = raw_config.get("search", {})
|
||||||
|
search_settings = None
|
||||||
|
if search_config:
|
||||||
|
search_settings = SearchSettings(**search_config)
|
||||||
|
print("search setting", search_settings)
|
||||||
|
|
||||||
config_dict = {
|
config_dict = {
|
||||||
"llm": {
|
"llm": {
|
||||||
"default": default_settings,
|
"default": default_settings,
|
||||||
@ -158,6 +169,7 @@ class Config:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"browser_config": browser_settings,
|
"browser_config": browser_settings,
|
||||||
|
"search_config": search_settings,
|
||||||
}
|
}
|
||||||
|
|
||||||
self._config = AppConfig(**config_dict)
|
self._config = AppConfig(**config_dict)
|
||||||
@ -170,5 +182,9 @@ class Config:
|
|||||||
def browser_config(self) -> Optional[BrowserSettings]:
|
def browser_config(self) -> Optional[BrowserSettings]:
|
||||||
return self._config.browser_config
|
return self._config.browser_config
|
||||||
|
|
||||||
|
@property
|
||||||
|
def search_config(self) -> Optional[SearchSettings]:
|
||||||
|
return self._config.search_config
|
||||||
|
|
||||||
|
|
||||||
config = Config()
|
config = Config()
|
||||||
|
48
app/tool/baidu_search.py
Normal file
48
app/tool/baidu_search.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import asyncio
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from baidusearch.baidusearch import search
|
||||||
|
|
||||||
|
from app.tool.base import BaseTool
|
||||||
|
|
||||||
|
|
||||||
|
class BaiduSearch(BaseTool):
|
||||||
|
name: str = "baidu_search"
|
||||||
|
description: str = """Perform a Baidu search and return a list of relevant links.
|
||||||
|
Use this tool when you need to find information on the web, get up-to-date data, or research specific topics.
|
||||||
|
The tool returns a list of URLs that match the search query.
|
||||||
|
"""
|
||||||
|
parameters: dict = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"query": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "(required) The search query to submit to Baidu.",
|
||||||
|
},
|
||||||
|
"num_results": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "(optional) The number of search results to return. Default is 10.",
|
||||||
|
"default": 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": ["query"],
|
||||||
|
}
|
||||||
|
|
||||||
|
async def execute(self, query: str, num_results: int = 10) -> List[str]:
|
||||||
|
"""
|
||||||
|
Execute a Baidu search and return a list of URLs.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
query (str): The search query to submit to Baidu.
|
||||||
|
num_results (int, optional): The number of search results to return. Default is 10.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: A list of URLs matching the search query.
|
||||||
|
"""
|
||||||
|
# Run the search in a thread pool to prevent blocking
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
links = await loop.run_in_executor(
|
||||||
|
None, lambda: list(search(query, num_results=num_results))
|
||||||
|
)
|
||||||
|
|
||||||
|
return links
|
@ -42,3 +42,8 @@ api_key = "sk-..."
|
|||||||
# server = "http://proxy-server:port"
|
# server = "http://proxy-server:port"
|
||||||
# username = "proxy-username"
|
# username = "proxy-username"
|
||||||
# password = "proxy-password"
|
# password = "proxy-password"
|
||||||
|
|
||||||
|
# Optional configuration, Search settings.
|
||||||
|
# [search]
|
||||||
|
# Search engine for agent to use. Default is "Google", can be set to "Baidu".
|
||||||
|
#engine = "Google"
|
@ -15,6 +15,7 @@ uvicorn~=0.34.0
|
|||||||
unidiff~=0.7.5
|
unidiff~=0.7.5
|
||||||
browser-use~=0.1.40
|
browser-use~=0.1.40
|
||||||
googlesearch-python~=1.3.0
|
googlesearch-python~=1.3.0
|
||||||
|
baidusearch~=1.0.3
|
||||||
|
|
||||||
aiofiles~=24.1.0
|
aiofiles~=24.1.0
|
||||||
pydantic_core~=2.27.2
|
pydantic_core~=2.27.2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user