parent
9d962053a2
commit
17af0de7b6
@ -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 |
@ -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))
|
||||||
@ -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
|
||||||
@ -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}")
|
||||||
@ -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}")
|
||||||
Loading…
Reference in New Issue