Add New Tool: StackExchange (#3034)

Co-authored-by: crazywoola <427733928@qq.com>
This commit is contained in:
Richards Tu 2024-03-29 20:28:21 +08:00 committed by GitHub
parent 9d962053a2
commit 17af0de7b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 505 additions and 0 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120"><style>.st0{fill:#376db6}.st1{fill:#4ca2da}.st2{fill:#91d8f4}.st3{fill:#1e5397}</style><path class="st0" d="M22.4 57.5h74.8v15.4H22.4z"/><path class="st1" d="M22.4 37.6h74.8V53H22.4z"/><path class="st2" d="M85.5 17H34.4c-6.6 0-12 5.5-12 12.3v4h74.8v-4C97.2 22.5 92 17 85.5 17z"/><path class="st3" d="M22.4 77.3v4c0 6.8 5.4 12.3 12 12.3h32v16.3l15.8-16.3h3.5c6.6 0 12-5.5 12-12.3v-4H22.4z"/></svg>

After

Width:  |  Height:  |  Size: 458 B

View File

@ -0,0 +1,25 @@
from core.tools.errors import ToolProviderCredentialValidationError
from core.tools.provider.builtin.stackexchange.tools.searchStackExQuestions import SearchStackExQuestionsTool
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
class StackExchangeProvider(BuiltinToolProviderController):
def _validate_credentials(self, credentials: dict) -> None:
try:
SearchStackExQuestionsTool().fork_tool_runtime(
meta={
"credentials": credentials,
}
).invoke(
user_id='',
tool_parameters={
"intitle": "Test",
"sort": "relevance",
"order": "desc",
"site": "stackoverflow",
"accepted": True,
"pagesize": 1
},
)
except Exception as e:
raise ToolProviderCredentialValidationError(str(e))

View File

@ -0,0 +1,10 @@
identity:
author: Richards Tu
name: stackexchange
label:
en_US: Stack Exchange
zh_Hans: Stack Exchange
description:
en_US: Access questions and answers from the Stack Exchange and its sub-sites.
zh_Hans: 从Stack Exchange和其子论坛获取问题和答案。
icon: icon.svg

View File

@ -0,0 +1,37 @@
from typing import Any, Union
import requests
from pydantic import BaseModel, Field
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
class FetchAnsByStackExQuesIDInput(BaseModel):
id: int = Field(..., description="The question ID")
site: str = Field(..., description="The Stack Exchange site")
order: str = Field(..., description="asc or desc")
sort: str = Field(..., description="activity, votes, creation")
pagesize: int = Field(..., description="Number of answers per page")
page: int = Field(..., description="Page number")
class FetchAnsByStackExQuesIDTool(BuiltinTool):
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
input = FetchAnsByStackExQuesIDInput(**tool_parameters)
params = {
"site": input.site,
"filter": "!nNPvSNdWme",
"order": input.order,
"sort": input.sort,
"pagesize": input.pagesize,
"page": input.page
}
response = requests.get(f"https://api.stackexchange.com/2.3/questions/{input.id}/answers", params=params)
if response.status_code == 200:
return self.create_text_message(self.summary(user_id=user_id, content=response.text))
else:
return self.create_text_message(f"API request failed with status code {response.status_code}")

View File

@ -0,0 +1,189 @@
identity:
name: fetchAnsByStackExQuesID
author: Richards Tu
label:
en_US: Fetch Stack Exchange Answers
zh_Hans: 获取 Stack Exchange 答案
description:
human:
en_US: A tool for retrieving answers for a specific Stack Exchange question ID. Specify the question ID, Stack Exchange site, sorting order, number of results per page, and page number. Must be used with the searchStackExQuesID tool.
zh_Hans: 用于检索特定Stack Exchange问题ID的答案的工具。指定问题ID、Stack Exchange站点、排序顺序、每页结果数和页码。 必须与searchStackExQuesID工具一起使用。
llm: A tool for retrieving answers for a specific Stack Exchange question ID based on the provided parameters.
parameters:
- name: id
type: string
required: true
label:
en_US: Question ID
zh_Hans: 问题ID
human_description:
en_US: The ID of the Stack Exchange question to fetch answers for.
zh_Hans: 要获取答案的Stack Exchange问题的ID。
llm_description: The ID of the Stack Exchange question.
form: llm
- name: site
type: string
required: true
label:
en_US: Stack Exchange site
zh_Hans: Stack Exchange站点
human_description:
en_US: The Stack Exchange site the question is from, e.g. stackoverflow, unix, etc.
zh_Hans: 问题所在的Stack Exchange站点例如stackoverflow、unix等。
llm_description: The Stack Exchange site identifier.
options:
- value: stackoverflow
label:
en_US: stackoverflow
- value: serverfault
label:
en_US: serverfault
- value: superuser
label:
en_US: superuser
- value: askubuntu
label:
en_US: askubuntu
- value: unix
label:
en_US: unix
- value: cs
label:
en_US: cs
- value: softwareengineering
label:
en_US: softwareengineering
- value: codegolf
label:
en_US: codegolf
- value: codereview
label:
en_US: codereview
- value: cstheory
label:
en_US: cstheory
- value: security
label:
en_US: security
- value: cryptography
label:
en_US: cryptography
- value: reverseengineering
label:
en_US: reverseengineering
- value: datascience
label:
en_US: datascience
- value: devops
label:
en_US: devops
- value: ux
label:
en_US: ux
- value: dba
label:
en_US: dba
- value: gis
label:
en_US: gis
- value: webmasters
label:
en_US: webmasters
- value: arduino
label:
en_US: arduino
- value: raspberrypi
label:
en_US: raspberrypi
- value: networkengineering
label:
en_US: networkengineering
- value: iot
label:
en_US: iot
- value: tor
label:
en_US: tor
- value: sqa
label:
en_US: sqa
- value: mathoverflow
label:
en_US: mathoverflow
- value: math
label:
en_US: math
- value: mathematica
label:
en_US: mathematica
- value: dsp
label:
en_US: dsp
- value: gamedev
label:
en_US: gamedev
- value: robotics
label:
en_US: robotics
- value: genai
label:
en_US: genai
- value: computergraphics
label:
en_US: computergraphics
form: form
- name: filter
type: string
required: true
label:
en_US: Filter
zh_Hans: 过滤器
human_description:
en_US: This is required in order to actually get the body of the answer.
zh_Hans: 为了实际获取答案的正文,这是必需的。
llm_description: Required in order to actually get the body of the answer. Must be \"!nNPvSNdWme\".
form: llm
- name: order
type: string
required: true
label:
en_US: Sort direction
zh_Hans: 排序方向
human_description:
en_US: The direction to sort the answers - ascending or descending.
zh_Hans: 答案的排序方向 - 升序或降序。
llm_description: asc for ascending, desc for descending.
form: llm
- name: sort
type: string
required: true
label:
en_US: Sort order
zh_Hans: 排序
human_description:
en_US: The sort order for the answers - activity, votes, or creation date.
zh_Hans: 答案的排序顺序 - 活动、投票或创建日期。
llm_description: activity, votes, or creation.
form: llm
- name: pagesize
type: number
required: true
label:
en_US: Results per page
zh_Hans: 每页结果数
human_description:
en_US: The number of answers to return per page.
zh_Hans: 每页返回的答案数。
llm_description: The number of answers per page.
form: llm
- name: page
type: number
required: true
label:
en_US: Page number
zh_Hans: 页码
human_description:
en_US: The page number of answers to retrieve.
zh_Hans: 要检索的答案的页码。
llm_description: The page number to retrieve.
form: llm

View File

@ -0,0 +1,43 @@
from typing import Any, Union
import requests
from pydantic import BaseModel, Field
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
class SearchStackExQuestionsInput(BaseModel):
intitle: str = Field(..., description="The search query.")
sort: str = Field(..., description="The sort order - relevance, activity, votes, creation.")
order: str = Field(..., description="asc or desc")
site: str = Field(..., description="The Stack Exchange site.")
tagged: str = Field(None, description="Semicolon-separated tags to include.")
nottagged: str = Field(None, description="Semicolon-separated tags to exclude.")
accepted: bool = Field(..., description="true for only accepted answers, false otherwise")
pagesize: int = Field(..., description="Number of results per page")
class SearchStackExQuestionsTool(BuiltinTool):
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
input = SearchStackExQuestionsInput(**tool_parameters)
params = {
"intitle": input.intitle,
"sort": input.sort,
"order": input.order,
"site": input.site,
"accepted": input.accepted,
"pagesize": input.pagesize
}
if input.tagged:
params["tagged"] = input.tagged
if input.nottagged:
params["nottagged"] = input.nottagged
response = requests.get("https://api.stackexchange.com/2.3/search", params=params)
if response.status_code == 200:
return self.create_text_message(self.summary(user_id=user_id, content=response.text))
else:
return self.create_text_message(f"API request failed with status code {response.status_code}")

View File

@ -0,0 +1,200 @@
identity:
name: searchStackExQuestions
author: Richards Tu
label:
en_US: Search Stack Exchange Questions
zh_Hans: 搜索Stack Exchange问题
description:
human:
en_US: A tool for searching questions on a Stack Exchange site. Specify the search query, sorting order, tags to include or exclude, whether to search only for questions with accepted answers, the Stack Exchange site, and number of results per page.
zh_Hans: 在Stack Exchange站点上搜索问题的工具。指定搜索查询、排序顺序、要包含或排除的标签、是否仅搜索有已接受答案的问题、Stack Exchange站点以及每页结果数。
llm: A tool for searching questions on a Stack Exchange site based on the provided parameters.
parameters:
- name: intitle
type: string
required: true
label:
en_US: Search query
zh_Hans: 搜索查询
human_description:
en_US: The search query to use for finding questions.
zh_Hans: 用于查找问题的搜索查询。
llm_description: The search query to use.
form: llm
- name: sort
type: string
required: true
label:
en_US: Sort order
zh_Hans: 排序
human_description:
en_US: The sort order for the search results - relevance, activity, votes, or creation date.
zh_Hans: 搜索结果的排序顺序 - 相关性、活动、投票或创建日期。
llm_description: The sort order - relevance, activity, votes, or creation.
form: llm
- name: order
type: string
required: true
label:
en_US: Sort direction
zh_Hans: 排序方向
human_description:
en_US: The direction to sort - ascending or descending.
zh_Hans: 排序方向 - 升序或降序。
llm_description: asc for ascending, desc for descending.
form: llm
- name: site
type: string
required: true
label:
en_US: Stack Exchange site
zh_Hans: Stack Exchange 站点
human_description:
en_US: The Stack Exchange site to search, e.g. stackoverflow, unix, etc.
zh_Hans: 要搜索的Stack Exchange站点例如stackoverflow、unix等。
llm_description: The Stack Exchange site identifier.
options:
- value: stackoverflow
label:
en_US: stackoverflow
- value: serverfault
label:
en_US: serverfault
- value: superuser
label:
en_US: superuser
- value: askubuntu
label:
en_US: askubuntu
- value: unix
label:
en_US: unix
- value: cs
label:
en_US: cs
- value: softwareengineering
label:
en_US: softwareengineering
- value: codegolf
label:
en_US: codegolf
- value: codereview
label:
en_US: codereview
- value: cstheory
label:
en_US: cstheory
- value: security
label:
en_US: security
- value: cryptography
label:
en_US: cryptography
- value: reverseengineering
label:
en_US: reverseengineering
- value: datascience
label:
en_US: datascience
- value: devops
label:
en_US: devops
- value: ux
label:
en_US: ux
- value: dba
label:
en_US: dba
- value: gis
label:
en_US: gis
- value: webmasters
label:
en_US: webmasters
- value: arduino
label:
en_US: arduino
- value: raspberrypi
label:
en_US: raspberrypi
- value: networkengineering
label:
en_US: networkengineering
- value: iot
label:
en_US: iot
- value: tor
label:
en_US: tor
- value: sqa
label:
en_US: sqa
- value: mathoverflow
label:
en_US: mathoverflow
- value: math
label:
en_US: math
- value: mathematica
label:
en_US: mathematica
- value: dsp
label:
en_US: dsp
- value: gamedev
label:
en_US: gamedev
- value: robotics
label:
en_US: robotics
- value: genai
label:
en_US: genai
- value: computergraphics
label:
en_US: computergraphics
form: form
- name: tagged
type: string
required: false
label:
en_US: Include tags
zh_Hans: 包含标签
human_description:
en_US: A semicolon-separated list of tags that questions must have.
zh_Hans: 问题必须具有的标签的分号分隔列表。
llm_description: Semicolon-separated tags to include. Leave blank if not needed.
form: llm
- name: nottagged
type: string
required: false
label:
en_US: Exclude tags
zh_Hans: 排除标签
human_description:
en_US: A semicolon-separated list of tags to exclude from the search.
zh_Hans: 从搜索中排除的标签的分号分隔列表。
llm_description: Semicolon-separated tags to exclude. Leave blank if not needed.
form: llm
- name: accepted
type: boolean
required: true
label:
en_US: Has accepted answer
zh_Hans: 有已接受的答案
human_description:
en_US: Whether to limit to only questions that have an accepted answer.
zh_Hans: 是否限制为只有已接受答案的问题。
llm_description: true to limit to only questions with accepted answers, false otherwise.
form: llm
- name: pagesize
type: number
required: true
label:
en_US: Results per page
zh_Hans: 每页结果数
human_description:
en_US: The number of results to return per page.
zh_Hans: 每页返回的结果数。
llm_description: The number of results per page.
form: llm