Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions astrbot/core/astr_agent_tool_exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@
PythonTool,
)
from astrbot.core.tools.message_tools import SendMessageToUserTool
from astrbot.core.tools.web_search_tools import (
BaiduWebSearchTool,
BochaWebSearchTool,
BraveWebSearchTool,
ExaGetContentsTool,
ExaWebSearchTool,
FirecrawlExtractWebPageTool,
FirecrawlWebSearchTool,
TavilyExtractWebPageTool,
TavilyWebSearchTool,
normalize_legacy_web_search_config,
)
from astrbot.core.utils.astrbot_path import get_astrbot_temp_path
from astrbot.core.utils.history_saver import persist_agent_history
from astrbot.core.utils.image_ref_utils import is_supported_image_ref
Expand Down Expand Up @@ -240,6 +252,37 @@ def _get_runtime_computer_tools(
}
return {}

@classmethod
def _get_web_search_tools(
cls,
cfg: dict,
tool_mgr,
) -> list:
normalize_legacy_web_search_config(cfg)
prov_settings = cfg.get("provider_settings", {})

if not prov_settings.get("web_search", False):
return []

provider = prov_settings.get("websearch_provider", "tavily")
result: list = []
if provider == "tavily":
result.append(tool_mgr.get_builtin_tool(TavilyWebSearchTool))
result.append(tool_mgr.get_builtin_tool(TavilyExtractWebPageTool))
elif provider == "bocha":
result.append(tool_mgr.get_builtin_tool(BochaWebSearchTool))
elif provider == "brave":
result.append(tool_mgr.get_builtin_tool(BraveWebSearchTool))
elif provider == "firecrawl":
result.append(tool_mgr.get_builtin_tool(FirecrawlWebSearchTool))
result.append(tool_mgr.get_builtin_tool(FirecrawlExtractWebPageTool))
elif provider == "baidu_ai_search":
result.append(tool_mgr.get_builtin_tool(BaiduWebSearchTool))
elif provider == "exa":
result.append(tool_mgr.get_builtin_tool(ExaWebSearchTool))
result.append(tool_mgr.get_builtin_tool(ExaGetContentsTool))
return result

@classmethod
def _build_handoff_toolset(
cls,
Expand All @@ -261,6 +304,7 @@ def _build_handoff_toolset(
tool_mgr,
provider_settings.get("sandbox", {}).get("booter"),
)
web_search_tools = cls._get_web_search_tools(cfg, tool_mgr)

# Keep persona semantics aligned with the main agent: tools=None means
# "all tools", including runtime computer-use tools.
Expand All @@ -278,6 +322,8 @@ def _build_handoff_toolset(
toolset.add_tool(registered_tool)
for runtime_tool in runtime_computer_tools.values():
toolset.add_tool(runtime_tool)
for web_tool in web_search_tools:
toolset.add_tool(web_tool)
return None if toolset.empty() else toolset

if not tools:
Expand All @@ -293,6 +339,13 @@ def _build_handoff_toolset(
runtime_tool = runtime_computer_tools.get(tool_name_or_obj)
if runtime_tool:
toolset.add_tool(runtime_tool)
continue
web_tool = next(
(t for t in web_search_tools if t.name == tool_name_or_obj),
None,
)
if web_tool:
toolset.add_tool(web_tool)
elif isinstance(tool_name_or_obj, FunctionTool):
toolset.add_tool(tool_name_or_obj)
return None if toolset.empty() else toolset
Expand Down