feat: add duckduckgo img search, translate, ai chat (#5074)
This commit is contained in:
parent
4d2e6c3391
commit
3b36ba797f
@ -1,5 +1,5 @@
|
||||
from core.tools.errors import ToolProviderCredentialValidationError
|
||||
from core.tools.provider.builtin.duckduckgo.tools.duckduckgo_search import DuckDuckGoSearchTool
|
||||
from core.tools.provider.builtin.duckduckgo.tools.ddgo_search import DuckDuckGoSearchTool
|
||||
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
|
||||
|
||||
|
||||
|
20
api/core/tools/provider/builtin/duckduckgo/tools/ddgo_ai.py
Normal file
20
api/core/tools/provider/builtin/duckduckgo/tools/ddgo_ai.py
Normal file
@ -0,0 +1,20 @@
|
||||
from typing import Any
|
||||
|
||||
from duckduckgo_search import DDGS
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
|
||||
|
||||
class DuckDuckGoAITool(BuiltinTool):
|
||||
"""
|
||||
Tool for performing a search using DuckDuckGo search engine.
|
||||
"""
|
||||
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
query_dict = {
|
||||
"keywords": tool_parameters.get('query'),
|
||||
"model": tool_parameters.get('model'),
|
||||
}
|
||||
response = DDGS().chat(**query_dict)
|
||||
return self.create_text_message(text=response)
|
@ -0,0 +1,41 @@
|
||||
identity:
|
||||
name: ddgo_ai
|
||||
author: hjlarry
|
||||
label:
|
||||
en_US: DuckDuckGo AI Chat
|
||||
zh_Hans: DuckDuckGo AI聊天
|
||||
description:
|
||||
human:
|
||||
en_US: Use the anonymous private chat provided by DuckDuckGo.
|
||||
zh_Hans: 使用DuckDuckGo提供的匿名私密聊天。
|
||||
llm: Use the anonymous private chat provided by DuckDuckGo.
|
||||
parameters:
|
||||
- name: query
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Chat Content
|
||||
zh_Hans: 聊天内容
|
||||
human_description:
|
||||
en_US: The chat content.
|
||||
zh_Hans: 要聊天的内容。
|
||||
llm_description: Key words for chat
|
||||
form: llm
|
||||
- name: model
|
||||
type: select
|
||||
required: true
|
||||
options:
|
||||
- value: gpt-3.5
|
||||
label:
|
||||
en_US: GPT-3.5
|
||||
- value: claude-3-haiku
|
||||
label:
|
||||
en_US: Claude 3
|
||||
default: gpt-3.5
|
||||
label:
|
||||
en_US: Choose Model
|
||||
zh_Hans: 选择模型
|
||||
human_description:
|
||||
en_US: used to select the model for AI chat.
|
||||
zh_Hans: 用于选择使用AI聊天的模型
|
||||
form: form
|
25
api/core/tools/provider/builtin/duckduckgo/tools/ddgo_img.py
Normal file
25
api/core/tools/provider/builtin/duckduckgo/tools/ddgo_img.py
Normal file
@ -0,0 +1,25 @@
|
||||
from typing import Any
|
||||
|
||||
from duckduckgo_search import DDGS
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
|
||||
|
||||
class DuckDuckGoImageSearchTool(BuiltinTool):
|
||||
"""
|
||||
Tool for performing an image search using DuckDuckGo search engine.
|
||||
"""
|
||||
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> list[ToolInvokeMessage]:
|
||||
query_dict = {
|
||||
"keywords": tool_parameters.get('query'),
|
||||
"timelimit": tool_parameters.get('timelimit'),
|
||||
"size": tool_parameters.get('size'),
|
||||
"max_results": tool_parameters.get('max_results'),
|
||||
}
|
||||
response = DDGS().images(**query_dict)
|
||||
results = []
|
||||
for res in response:
|
||||
results.append(self.create_image_message(image=res.get("image")))
|
||||
return results
|
@ -0,0 +1,88 @@
|
||||
identity:
|
||||
name: ddgo_img
|
||||
author: hjlarry
|
||||
label:
|
||||
en_US: DuckDuckGo Image Search
|
||||
zh_Hans: DuckDuckGo 图片搜索
|
||||
description:
|
||||
human:
|
||||
en_US: Perform image searches on DuckDuckGo and get results.
|
||||
zh_Hans: 在 DuckDuckGo 上进行图片搜索并获取结果。
|
||||
llm: Perform image searches on DuckDuckGo and get results.
|
||||
parameters:
|
||||
- name: query
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Query string
|
||||
zh_Hans: 查询语句
|
||||
human_description:
|
||||
en_US: The search query.
|
||||
zh_Hans: 搜索查询语句。
|
||||
llm_description: Key words for searching
|
||||
form: llm
|
||||
- name: max_results
|
||||
type: number
|
||||
required: true
|
||||
default: 3
|
||||
label:
|
||||
en_US: Max results
|
||||
zh_Hans: 最大结果数量
|
||||
human_description:
|
||||
en_US: The max results.
|
||||
zh_Hans: 最大结果数量
|
||||
form: form
|
||||
- name: timelimit
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: Day
|
||||
label:
|
||||
en_US: current day
|
||||
zh_Hans: 当天
|
||||
- value: Week
|
||||
label:
|
||||
en_US: current week
|
||||
zh_Hans: 本周
|
||||
- value: Month
|
||||
label:
|
||||
en_US: current month
|
||||
zh_Hans: 当月
|
||||
- value: Year
|
||||
label:
|
||||
en_US: current year
|
||||
zh_Hans: 今年
|
||||
label:
|
||||
en_US: Result time limit
|
||||
zh_Hans: 结果时间限制
|
||||
human_description:
|
||||
en_US: Use when querying results within a specific time range only.
|
||||
zh_Hans: 只查询一定时间范围内的结果时使用
|
||||
form: form
|
||||
- name: size
|
||||
type: select
|
||||
required: false
|
||||
options:
|
||||
- value: Small
|
||||
label:
|
||||
en_US: small
|
||||
zh_Hans: 小
|
||||
- value: Medium
|
||||
label:
|
||||
en_US: medium
|
||||
zh_Hans: 中
|
||||
- value: Large
|
||||
label:
|
||||
en_US: large
|
||||
zh_Hans: 大
|
||||
- value: Wallpaper
|
||||
label:
|
||||
en_US: xl
|
||||
zh_Hans: 超大
|
||||
label:
|
||||
en_US: image size
|
||||
zh_Hans: 图片大小
|
||||
human_description:
|
||||
en_US: The size of the image to be searched.
|
||||
zh_Hans: 要搜索的图片的大小
|
||||
form: form
|
@ -0,0 +1,29 @@
|
||||
from typing import Any
|
||||
|
||||
from duckduckgo_search import DDGS
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
|
||||
|
||||
class DuckDuckGoSearchTool(BuiltinTool):
|
||||
"""
|
||||
Tool for performing a search using DuckDuckGo search engine.
|
||||
"""
|
||||
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
query = tool_parameters.get('query', '')
|
||||
result_type = tool_parameters.get('result_type', 'text')
|
||||
max_results = tool_parameters.get('max_results', 10)
|
||||
require_summary = tool_parameters.get('require_summary', False)
|
||||
response = DDGS().text(query, max_results=max_results)
|
||||
|
||||
if result_type == 'link':
|
||||
results = [f"[{res.get('title')}]({res.get('href')})" for res in response]
|
||||
results = "\n".join(results)
|
||||
return self.create_link_message(link=results)
|
||||
results = [res.get("body") for res in response]
|
||||
results = "\n".join(results)
|
||||
if require_summary:
|
||||
results = self.summary(user_id=user_id, content=results)
|
||||
return self.create_text_message(text=results)
|
@ -0,0 +1,65 @@
|
||||
identity:
|
||||
name: ddgo_search
|
||||
author: Yash Parmar
|
||||
label:
|
||||
en_US: DuckDuckGo Search
|
||||
zh_Hans: DuckDuckGo 搜索
|
||||
description:
|
||||
human:
|
||||
en_US: Perform searches on DuckDuckGo and get results.
|
||||
zh_Hans: 在 DuckDuckGo 上进行搜索并获取结果。
|
||||
llm: Perform searches on DuckDuckGo and get results.
|
||||
parameters:
|
||||
- name: query
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Query string
|
||||
zh_Hans: 查询语句
|
||||
human_description:
|
||||
en_US: The search query.
|
||||
zh_Hans: 搜索查询语句。
|
||||
llm_description: Key words for searching
|
||||
form: llm
|
||||
- name: max_results
|
||||
type: number
|
||||
required: true
|
||||
default: 5
|
||||
label:
|
||||
en_US: Max results
|
||||
zh_Hans: 最大结果数量
|
||||
human_description:
|
||||
en_US: The max results.
|
||||
zh_Hans: 最大结果数量
|
||||
form: form
|
||||
- name: result_type
|
||||
type: select
|
||||
required: true
|
||||
options:
|
||||
- value: text
|
||||
label:
|
||||
en_US: text
|
||||
zh_Hans: 文本
|
||||
- value: link
|
||||
label:
|
||||
en_US: link
|
||||
zh_Hans: 链接
|
||||
default: text
|
||||
label:
|
||||
en_US: Result type
|
||||
zh_Hans: 结果类型
|
||||
human_description:
|
||||
en_US: used for selecting the result type, text or link
|
||||
zh_Hans: 用于选择结果类型,使用文本还是链接进行展示
|
||||
form: form
|
||||
- name: require_summary
|
||||
type: boolean
|
||||
required: true
|
||||
default: false
|
||||
label:
|
||||
en_US: Require Summary
|
||||
zh_Hans: 是否总结
|
||||
human_description:
|
||||
en_US: Whether to pass the search results to llm for summarization.
|
||||
zh_Hans: 是否需要将搜索结果传给大模型总结
|
||||
form: form
|
@ -0,0 +1,20 @@
|
||||
from typing import Any
|
||||
|
||||
from duckduckgo_search import DDGS
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
|
||||
|
||||
class DuckDuckGoTranslateTool(BuiltinTool):
|
||||
"""
|
||||
Tool for performing a search using DuckDuckGo search engine.
|
||||
"""
|
||||
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
|
||||
query_dict = {
|
||||
"keywords": tool_parameters.get('query'),
|
||||
"to": tool_parameters.get('translate_to'),
|
||||
}
|
||||
response = DDGS().translate(**query_dict)[0].get('translated', 'Unable to translate!')
|
||||
return self.create_text_message(text=response)
|
@ -0,0 +1,51 @@
|
||||
identity:
|
||||
name: ddgo_translate
|
||||
author: hjlarry
|
||||
label:
|
||||
en_US: DuckDuckGo Translate
|
||||
zh_Hans: DuckDuckGo 翻译
|
||||
description:
|
||||
human:
|
||||
en_US: Use DuckDuckGo's translation feature.
|
||||
zh_Hans: 使用DuckDuckGo的翻译功能。
|
||||
llm: Use DuckDuckGo's translation feature.
|
||||
parameters:
|
||||
- name: query
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Translate Content
|
||||
zh_Hans: 翻译内容
|
||||
human_description:
|
||||
en_US: The translate content.
|
||||
zh_Hans: 要翻译的内容。
|
||||
llm_description: Key words for translate
|
||||
form: llm
|
||||
- name: translate_to
|
||||
type: select
|
||||
required: true
|
||||
options:
|
||||
- value: en
|
||||
label:
|
||||
en_US: English
|
||||
zh_Hans: 英语
|
||||
- value: zh-Hans
|
||||
label:
|
||||
en_US: Simplified Chinese
|
||||
zh_Hans: 简体中文
|
||||
- value: zh-Hant
|
||||
label:
|
||||
en_US: Traditional Chinese
|
||||
zh_Hans: 繁体中文
|
||||
- value: ja
|
||||
label:
|
||||
en_US: Japanese
|
||||
zh_Hans: 日语
|
||||
default: en
|
||||
label:
|
||||
en_US: Choose Language
|
||||
zh_Hans: 选择语言
|
||||
human_description:
|
||||
en_US: select the language to translate.
|
||||
zh_Hans: 选择要翻译的语言
|
||||
form: form
|
@ -1,171 +0,0 @@
|
||||
from typing import Any, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
|
||||
|
||||
class DuckDuckGoSearchAPIWrapper(BaseModel):
|
||||
"""Wrapper for DuckDuckGo Search API.
|
||||
|
||||
Free and does not require any setup.
|
||||
"""
|
||||
|
||||
region: Optional[str] = "wt-wt"
|
||||
safesearch: str = "moderate"
|
||||
time: Optional[str] = "y"
|
||||
max_results: int = 5
|
||||
|
||||
def get_snippets(self, query: str) -> list[str]:
|
||||
"""Run query through DuckDuckGo and return concatenated results."""
|
||||
from duckduckgo_search import DDGS
|
||||
|
||||
with DDGS() as ddgs:
|
||||
results = ddgs.text(
|
||||
query,
|
||||
region=self.region,
|
||||
safesearch=self.safesearch,
|
||||
timelimit=self.time,
|
||||
)
|
||||
if results is None:
|
||||
return ["No good DuckDuckGo Search Result was found"]
|
||||
snippets = []
|
||||
for i, res in enumerate(results, 1):
|
||||
if res is not None:
|
||||
snippets.append(res["body"])
|
||||
if len(snippets) == self.max_results:
|
||||
break
|
||||
return snippets
|
||||
|
||||
def run(self, query: str) -> str:
|
||||
snippets = self.get_snippets(query)
|
||||
return " ".join(snippets)
|
||||
|
||||
def results(
|
||||
self, query: str, num_results: int, backend: str = "api"
|
||||
) -> list[dict[str, str]]:
|
||||
"""Run query through DuckDuckGo and return metadata.
|
||||
|
||||
Args:
|
||||
query: The query to search for.
|
||||
num_results: The number of results to return.
|
||||
|
||||
Returns:
|
||||
A list of dictionaries with the following keys:
|
||||
snippet - The description of the result.
|
||||
title - The title of the result.
|
||||
link - The link to the result.
|
||||
"""
|
||||
from duckduckgo_search import DDGS
|
||||
|
||||
with DDGS() as ddgs:
|
||||
results = ddgs.text(
|
||||
query,
|
||||
region=self.region,
|
||||
safesearch=self.safesearch,
|
||||
timelimit=self.time,
|
||||
backend=backend,
|
||||
)
|
||||
if results is None:
|
||||
return [{"Result": "No good DuckDuckGo Search Result was found"}]
|
||||
|
||||
def to_metadata(result: dict) -> dict[str, str]:
|
||||
if backend == "news":
|
||||
return {
|
||||
"date": result["date"],
|
||||
"title": result["title"],
|
||||
"snippet": result["body"],
|
||||
"source": result["source"],
|
||||
"link": result["url"],
|
||||
}
|
||||
return {
|
||||
"snippet": result["body"],
|
||||
"title": result["title"],
|
||||
"link": result["href"],
|
||||
}
|
||||
|
||||
formatted_results = []
|
||||
for i, res in enumerate(results, 1):
|
||||
if res is not None:
|
||||
formatted_results.append(to_metadata(res))
|
||||
if len(formatted_results) == num_results:
|
||||
break
|
||||
return formatted_results
|
||||
|
||||
|
||||
class DuckDuckGoSearchRun(BaseModel):
|
||||
"""Tool that queries the DuckDuckGo search API."""
|
||||
|
||||
name = "duckduckgo_search"
|
||||
description = (
|
||||
"A wrapper around DuckDuckGo Search. "
|
||||
"Useful for when you need to answer questions about current events. "
|
||||
"Input should be a search query."
|
||||
)
|
||||
api_wrapper: DuckDuckGoSearchAPIWrapper = Field(
|
||||
default_factory=DuckDuckGoSearchAPIWrapper
|
||||
)
|
||||
|
||||
def _run(
|
||||
self,
|
||||
query: str,
|
||||
) -> str:
|
||||
"""Use the tool."""
|
||||
return self.api_wrapper.run(query)
|
||||
|
||||
|
||||
class DuckDuckGoSearchResults(BaseModel):
|
||||
"""Tool that queries the DuckDuckGo search API and gets back json."""
|
||||
|
||||
name = "DuckDuckGo Results JSON"
|
||||
description = (
|
||||
"A wrapper around Duck Duck Go Search. "
|
||||
"Useful for when you need to answer questions about current events. "
|
||||
"Input should be a search query. Output is a JSON array of the query results"
|
||||
)
|
||||
num_results: int = 4
|
||||
api_wrapper: DuckDuckGoSearchAPIWrapper = Field(
|
||||
default_factory=DuckDuckGoSearchAPIWrapper
|
||||
)
|
||||
backend: str = "api"
|
||||
|
||||
def _run(
|
||||
self,
|
||||
query: str,
|
||||
) -> str:
|
||||
"""Use the tool."""
|
||||
res = self.api_wrapper.results(query, self.num_results, backend=self.backend)
|
||||
res_strs = [", ".join([f"{k}: {v}" for k, v in d.items()]) for d in res]
|
||||
return ", ".join([f"[{rs}]" for rs in res_strs])
|
||||
|
||||
class DuckDuckGoInput(BaseModel):
|
||||
query: str = Field(..., description="Search query.")
|
||||
|
||||
class DuckDuckGoSearchTool(BuiltinTool):
|
||||
"""
|
||||
Tool for performing a search using DuckDuckGo search engine.
|
||||
"""
|
||||
|
||||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage | list[ToolInvokeMessage]:
|
||||
"""
|
||||
Invoke the DuckDuckGo search tool.
|
||||
|
||||
Args:
|
||||
user_id (str): The ID of the user invoking the tool.
|
||||
tool_parameters (dict[str, Any]): The parameters for the tool invocation.
|
||||
|
||||
Returns:
|
||||
ToolInvokeMessage | list[ToolInvokeMessage]: The result of the tool invocation.
|
||||
"""
|
||||
query = tool_parameters.get('query', '')
|
||||
|
||||
if not query:
|
||||
return self.create_text_message('Please input query')
|
||||
|
||||
tool = DuckDuckGoSearchRun(args_schema=DuckDuckGoInput)
|
||||
|
||||
result = tool._run(query)
|
||||
|
||||
return self.create_text_message(self.summary(user_id=user_id, content=result))
|
||||
|
@ -1,23 +0,0 @@
|
||||
identity:
|
||||
name: duckduckgo_search
|
||||
author: Yash Parmar
|
||||
label:
|
||||
en_US: DuckDuckGo Search
|
||||
zh_Hans: DuckDuckGo 搜索
|
||||
description:
|
||||
human:
|
||||
en_US: Perform searches on DuckDuckGo and get results.
|
||||
zh_Hans: 在 DuckDuckGo 上进行搜索并获取结果。
|
||||
llm: Perform searches on DuckDuckGo and get results.
|
||||
parameters:
|
||||
- name: query
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Query string
|
||||
zh_Hans: 查询语句
|
||||
human_description:
|
||||
en_US: The search query.
|
||||
zh_Hans: 搜索查询语句。
|
||||
llm_description: Key words for searching
|
||||
form: llm
|
Loading…
Reference in New Issue
Block a user