| @@ -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 | |||
| @@ -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 | |||
| @@ -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 | |||