fix: issues by pydantic2 upgrade (#5171)
This commit is contained in:
@@ -507,9 +507,9 @@ class AIPPTGenerateTool(BuiltinTool):
|
||||
colors, styles = self.get_styles(user_id='__dify_system__')
|
||||
except Exception as e:
|
||||
colors, styles = [
|
||||
{'id': -1, 'name': '__default__', 'en_name': '__default__'}
|
||||
{'id': '-1', 'name': '__default__', 'en_name': '__default__'}
|
||||
], [
|
||||
{'id': -1, 'name': '__default__', 'en_name': '__default__'}
|
||||
{'id': '-1', 'name': '__default__', 'en_name': '__default__'}
|
||||
]
|
||||
|
||||
return [
|
||||
|
@@ -263,7 +263,7 @@ parameters:
|
||||
en_US: New Zealand
|
||||
zh_Hans: 新西兰
|
||||
pt_BR: New Zealand
|
||||
- value: NO
|
||||
- value: 'NO'
|
||||
label:
|
||||
en_US: Norway
|
||||
zh_Hans: 挪威
|
||||
|
@@ -1,174 +0,0 @@
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
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: str = "duckduckgo_search"
|
||||
description: str = (
|
||||
"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: str = "DuckDuckGo Results JSON"
|
||||
description: str = (
|
||||
"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))
|
||||
|
||||
>>>>>>> 4c2ba442b (missing type in DuckDuckGoSearchAPIWrapper)
|
@@ -67,12 +67,12 @@ parameters:
|
||||
zh_Hans: 如果启用,爬虫将仅返回页面的主要内容,不包括标题、导航、页脚等。
|
||||
form: form
|
||||
options:
|
||||
- value: true
|
||||
- value: 'true'
|
||||
label:
|
||||
en_US: 'Yes'
|
||||
zh_Hans: 是
|
||||
- value: false
|
||||
- value: 'false'
|
||||
label:
|
||||
en_US: 'No'
|
||||
zh_Hans: 否
|
||||
default: false
|
||||
default: 'false'
|
||||
|
@@ -185,7 +185,7 @@ parameters:
|
||||
en_US: New Zealand
|
||||
zh_Hans: 新西兰
|
||||
pt_BR: New Zealand
|
||||
- value: NO
|
||||
- value: 'NO'
|
||||
label:
|
||||
en_US: Norway
|
||||
zh_Hans: 挪威
|
||||
|
@@ -185,7 +185,7 @@ parameters:
|
||||
en_US: New Zealand
|
||||
zh_Hans: 新西兰
|
||||
pt_BR: New Zealand
|
||||
- value: NO
|
||||
- value: 'NO'
|
||||
label:
|
||||
en_US: Norway
|
||||
zh_Hans: 挪威
|
||||
@@ -468,11 +468,11 @@ parameters:
|
||||
required: false
|
||||
form: form
|
||||
options:
|
||||
- value: true
|
||||
- value: 'true'
|
||||
label:
|
||||
en_US: "true"
|
||||
zh_Hans: "true"
|
||||
- value: false
|
||||
- value: 'false'
|
||||
label:
|
||||
en_US: "false"
|
||||
zh_Hans: "false"
|
||||
|
@@ -185,7 +185,7 @@ parameters:
|
||||
en_US: New Zealand
|
||||
zh_Hans: 新西兰
|
||||
pt_BR: New Zealand
|
||||
- value: NO
|
||||
- value: 'NO'
|
||||
label:
|
||||
en_US: Norway
|
||||
zh_Hans: 挪威
|
||||
|
@@ -6,7 +6,7 @@ identity:
|
||||
zh_Hans: Stack Exchange
|
||||
description:
|
||||
en_US: Access questions and answers from the Stack Exchange and its sub-sites.
|
||||
zh_Hans: 从Stack Exchange和其子论坛获取问题和答案。
|
||||
zh_Hans: 从 Stack Exchange 和其子论坛获取问题和答案。
|
||||
icon: icon.svg
|
||||
tags:
|
||||
- search
|
||||
|
@@ -96,15 +96,15 @@ parameters:
|
||||
zh_Hans: 是否限制为只有已接受答案的问题。
|
||||
form: form
|
||||
options:
|
||||
- value: true
|
||||
- value: 'true'
|
||||
label:
|
||||
en_US: 'Yes'
|
||||
zh_Hans: 是
|
||||
- value: false
|
||||
- value: 'false'
|
||||
label:
|
||||
en_US: 'No'
|
||||
zh_Hans: 否
|
||||
default: true
|
||||
default: 'true'
|
||||
- name: pagesize
|
||||
type: number
|
||||
required: true
|
||||
|
@@ -62,17 +62,17 @@ parameters:
|
||||
pt_BR: Include images in the search results
|
||||
form: form
|
||||
options:
|
||||
- value: true
|
||||
- value: 'true'
|
||||
label:
|
||||
en_US: 'Yes'
|
||||
zh_Hans: 是
|
||||
pt_BR: 'Yes'
|
||||
- value: false
|
||||
- value: 'false'
|
||||
label:
|
||||
en_US: 'No'
|
||||
zh_Hans: 否
|
||||
pt_BR: 'No'
|
||||
default: false
|
||||
default: 'false'
|
||||
- name: include_answer
|
||||
type: boolean
|
||||
required: false
|
||||
@@ -86,17 +86,17 @@ parameters:
|
||||
pt_BR: Include answers in the search results
|
||||
form: form
|
||||
options:
|
||||
- value: true
|
||||
- value: 'true'
|
||||
label:
|
||||
en_US: 'Yes'
|
||||
zh_Hans: 是
|
||||
pt_BR: 'Yes'
|
||||
- value: false
|
||||
- value: 'false'
|
||||
label:
|
||||
en_US: 'No'
|
||||
zh_Hans: 否
|
||||
pt_BR: 'No'
|
||||
default: false
|
||||
default: 'false'
|
||||
- name: include_raw_content
|
||||
type: boolean
|
||||
required: false
|
||||
@@ -110,17 +110,17 @@ parameters:
|
||||
pt_BR: Include raw content in the search results
|
||||
form: form
|
||||
options:
|
||||
- value: true
|
||||
- value: 'true'
|
||||
label:
|
||||
en_US: 'Yes'
|
||||
zh_Hans: 是
|
||||
pt_BR: 'Yes'
|
||||
- value: false
|
||||
- value: 'false'
|
||||
label:
|
||||
en_US: 'No'
|
||||
zh_Hans: 否
|
||||
pt_BR: 'No'
|
||||
default: false
|
||||
default: 'false'
|
||||
- name: max_results
|
||||
type: number
|
||||
required: false
|
||||
|
@@ -49,12 +49,12 @@ parameters:
|
||||
zh_Hans: 如果启用,爬虫将仅返回页面摘要内容。
|
||||
form: form
|
||||
options:
|
||||
- value: true
|
||||
- value: 'true'
|
||||
label:
|
||||
en_US: 'Yes'
|
||||
zh_Hans: 是
|
||||
- value: false
|
||||
- value: 'false'
|
||||
label:
|
||||
en_US: 'No'
|
||||
zh_Hans: 否
|
||||
default: false
|
||||
default: 'false'
|
||||
|
Reference in New Issue
Block a user