Update tools.py
Browse files
tools.py
CHANGED
|
@@ -1,41 +1,75 @@
|
|
| 1 |
import re
|
| 2 |
import uuid
|
| 3 |
from typing import Any, Dict, Union, Optional
|
| 4 |
-
|
| 5 |
-
from langchain_core.callbacks import Callbacks
|
| 6 |
-
from langchain_core.runnables import RunnableConfig
|
| 7 |
from openai import OpenAI
|
| 8 |
-
|
| 9 |
import requests
|
| 10 |
from bs4 import BeautifulSoup
|
| 11 |
-
from config import selected_language
|
| 12 |
from serpapi import GoogleSearch
|
| 13 |
from langchain.tools import BaseTool
|
| 14 |
import json
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
class GetLocation(BaseTool):
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
|
|
|
| 39 |
|
| 40 |
def _run(self, ip_address: str) -> str:
|
| 41 |
api_key = "f962beaf785545d0a90b76d105996cdb"
|
|
@@ -50,11 +84,19 @@ class GetLocation(BaseTool):
|
|
| 50 |
|
| 51 |
class CurrencyConversion(BaseTool):
|
| 52 |
name: str = "货币换算"
|
| 53 |
-
description: str =
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
def _run(self, _input: str) -> str:
|
| 60 |
pattern = r"(?P<base_currency>\S+)\|(?P<target_currency>\S+)"
|
|
@@ -72,14 +114,22 @@ class CurrencyConversion(BaseTool):
|
|
| 72 |
|
| 73 |
|
| 74 |
class GetHoliday(BaseTool):
|
| 75 |
-
name: str = "
|
| 76 |
-
description: str =
|
| 77 |
-
"获取指定国家在某一天的假期信息。输入参数包括国家代码和日期(年、月、日)。传参格式:'US|2025|1|1'(第一个参数为国家代码,后续三个参数为年份、月份和日期)。"if selected_language == "ch"
|
| 78 |
-
else "Retrieve holiday information for a specified country on a certain day. The input parameters include country code and date (year, month, day). Parameter transmission format: US | 2025 | 1 | 1 '(The first parameter is the country code, and the following three parameters are the year, month, and date)."
|
| 79 |
-
)
|
| 80 |
|
| 81 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
|
|
|
|
| 83 |
pattern = r"(?P<country>[A-Za-z]{2,3})\|(?P<year>\d{4})\|(?P<month>\d{1,2})\|(?P<day>\d{1,2})"
|
| 84 |
match = re.match(pattern, _input)
|
| 85 |
country = match.group("country")
|
|
@@ -120,15 +170,10 @@ def holiday2(country, year):
|
|
| 120 |
|
| 121 |
class SafeExpressionEvaluator(BaseTool):
|
| 122 |
name: str = "safe expression evaluator"
|
| 123 |
-
description: str = (
|
| 124 |
-
"安全地计算 Python 表达式,输入参数为表达式字符串。"
|
| 125 |
-
if selected_language == "ch"
|
| 126 |
-
else "Safely evaluate Python expressions, with input being an expression string."
|
| 127 |
-
)
|
| 128 |
safe_globals: dict = None # 声明类型
|
| 129 |
safe_locals: dict = None
|
| 130 |
-
|
| 131 |
-
def __init__(self, **kwargs):
|
| 132 |
super().__init__(**kwargs)
|
| 133 |
# 定义安全的执行环境
|
| 134 |
self.safe_globals = {
|
|
@@ -145,6 +190,11 @@ class SafeExpressionEvaluator(BaseTool):
|
|
| 145 |
"math":__import__("math"),
|
| 146 |
}
|
| 147 |
self.safe_locals = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
|
| 149 |
def _run(self, expression: str) -> Dict[str, Any]:
|
| 150 |
"""安全地计算一个表达式,并返回结果"""
|
|
@@ -157,15 +207,10 @@ class SafeExpressionEvaluator(BaseTool):
|
|
| 157 |
|
| 158 |
class SafeCodeExecutor(BaseTool):
|
| 159 |
name: str = "safe code executor"
|
| 160 |
-
description: str = (
|
| 161 |
-
"安全地执行 Python 代码块,输入参数为代码字符串。"
|
| 162 |
-
if selected_language == "ch"
|
| 163 |
-
else "Safely execute Python code blocks, with input being a code string."
|
| 164 |
-
)
|
| 165 |
safe_globals: dict = None # 声明类型
|
| 166 |
safe_locals: dict = None
|
| 167 |
-
|
| 168 |
-
def __init__(self, **kwargs):
|
| 169 |
super().__init__()
|
| 170 |
self.safe_globals = {
|
| 171 |
"__builtins__": {
|
|
@@ -183,6 +228,11 @@ class SafeCodeExecutor(BaseTool):
|
|
| 183 |
"math": __import__("math"),
|
| 184 |
}
|
| 185 |
self.safe_locals = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
|
| 187 |
def _run(self, code: str) -> Dict[str, Any]:
|
| 188 |
"""安全地执行一段 Python 代码(包括函数、类定义等),无返回值"""
|
|
@@ -203,8 +253,14 @@ def weather(city):
|
|
| 203 |
|
| 204 |
class WeatherCrossing(BaseTool):
|
| 205 |
name: str = "天气查询"
|
| 206 |
-
description: str = "使用 Visual Crossing API 查询指定城市的天气信息,输入参数包括城市名称,以及可选的开始日期和结束日期(格式为 yyyy-MM-dd)。"
|
| 207 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 208 |
def _run(self, city: str, date1: str = None, date2: str = None) -> dict:
|
| 209 |
base_url = "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline"
|
| 210 |
api_key = "6LX8E4LWX7ZFSCCA5S3JLFVPS"
|
|
@@ -226,10 +282,18 @@ class WeatherCrossing(BaseTool):
|
|
| 226 |
|
| 227 |
|
| 228 |
class RegionInquiryTool(BaseTool):
|
| 229 |
-
name: str = "
|
| 230 |
-
description: str =
|
| 231 |
-
|
| 232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 233 |
|
| 234 |
def _run(self, _input: str) -> Dict[str, Any]:
|
| 235 |
|
|
@@ -255,9 +319,15 @@ class RegionInquiryTool(BaseTool):
|
|
| 255 |
|
| 256 |
|
| 257 |
class HTMLTextExtractor(BaseTool):
|
| 258 |
-
name: str = "html
|
| 259 |
-
description: str = "提取 HTML 文档中的纯文本内容,输入参数为 HTML 文档的字符串内容,返回去除标签后的纯文本。"
|
| 260 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
def _run(self, html_content: str) -> dict:
|
| 262 |
if not html_content:
|
| 263 |
return {"result": None, "error": "HTML 内容不能为空。"}
|
|
@@ -271,8 +341,16 @@ class HTMLTextExtractor(BaseTool):
|
|
| 271 |
|
| 272 |
|
| 273 |
class BaiduNewsSearchTool(BaseTool):
|
| 274 |
-
name: str = "Baidu News Search"
|
| 275 |
-
description: str = "备用搜索引擎,当主要搜索引擎不返回结果时调用,输入是检索query"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 276 |
|
| 277 |
def _run(self, query: str) -> str:
|
| 278 |
"""
|
|
@@ -294,14 +372,24 @@ class BaiduNewsSearchTool(BaseTool):
|
|
| 294 |
|
| 295 |
|
| 296 |
class BoChaSearchTool(BaseTool):
|
| 297 |
-
name: str = "
|
| 298 |
-
description: str = "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
def _run(self, query: str) -> str:
|
| 300 |
|
| 301 |
url = "https://api.bochaai.com/v1/web-search"
|
| 302 |
payload = json.dumps({
|
| 303 |
"query": query,
|
| 304 |
-
"count":
|
| 305 |
"summary": True
|
| 306 |
})
|
| 307 |
headers = {
|
|
@@ -309,13 +397,26 @@ class BoChaSearchTool(BaseTool):
|
|
| 309 |
'Content-Type': 'application/json'
|
| 310 |
}
|
| 311 |
response = requests.request("POST", url, headers=headers, data=payload)
|
| 312 |
-
|
| 313 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 314 |
|
| 315 |
|
| 316 |
class ImageSearchTool(BaseTool):
|
| 317 |
-
name: str = "
|
| 318 |
-
description: str = "搜索图片引擎,当你需要检索相关图片的时候调用,输入是检索query,输出是与query有关的图片的信息"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
|
| 320 |
def _run(self, query: str) -> str:
|
| 321 |
params = {
|
|
@@ -360,11 +461,19 @@ class ImageSearchTool(BaseTool):
|
|
| 360 |
# print(tool.run("USD|EUR"))
|
| 361 |
|
| 362 |
class LocationSearch(BaseTool):
|
| 363 |
-
name: str = "
|
| 364 |
-
description: str =
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
|
| 369 |
def _run(self, keyword: str) -> str:
|
| 370 |
key = "e7ff59e1de1573456145f0d736cc3a2f"
|
|
@@ -374,15 +483,40 @@ class LocationSearch(BaseTool):
|
|
| 374 |
|
| 375 |
|
| 376 |
class ReverseGeocodingTool(BaseTool):
|
| 377 |
-
name: str = "
|
| 378 |
-
description: str =
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 383 |
|
| 384 |
def _run(self, address: str) -> str:
|
| 385 |
key = "e7ff59e1de1573456145f0d736cc3a2f"
|
| 386 |
url = f"https://restapi.amap.com/v3/geocode/geo?address={address}&output=JSON&key={key}"
|
| 387 |
response = requests.get(url)
|
| 388 |
-
return response.json()['geocodes'][0]['location']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import re
|
| 2 |
import uuid
|
| 3 |
from typing import Any, Dict, Union, Optional
|
| 4 |
+
import tldextract
|
|
|
|
|
|
|
| 5 |
from openai import OpenAI
|
|
|
|
| 6 |
import requests
|
| 7 |
from bs4 import BeautifulSoup
|
| 8 |
+
# from config import selected_language
|
| 9 |
from serpapi import GoogleSearch
|
| 10 |
from langchain.tools import BaseTool
|
| 11 |
import json
|
| 12 |
+
from langchain_community.tools.tavily_search import TavilySearchResults as OriginalTavilySearchResults
|
| 13 |
+
from trusted_url import *
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class ChineseTavilySearchResults(OriginalTavilySearchResults):
|
| 17 |
+
"""重写 description 为中文的版本"""
|
| 18 |
+
description :str = "备用搜索引擎,适用于需要回答当前事件问题的场景,输入应该是一个搜索查询。"
|
| 19 |
+
fact_checking : bool = False
|
| 20 |
+
def __init__(self, selected_language: str,fact_checking:bool = False, **kwargs):
|
| 21 |
+
super().__init__(max_results=10,**kwargs)
|
| 22 |
+
self.description = (
|
| 23 |
+
"备用搜索引擎,适用于需要回答当前事件问题的场景,输入应该是一个搜索查询。"
|
| 24 |
+
if selected_language == "ch"
|
| 25 |
+
else "Backup search engine, suitable for scenarios that require answering current event questions, the input should be a search query."
|
| 26 |
+
)
|
| 27 |
+
self.fact_checking = fact_checking
|
| 28 |
+
|
| 29 |
+
def _invoke(self, query: str, **kwargs) -> Dict:
|
| 30 |
+
# 1. 调用原始API获取数据
|
| 31 |
+
raw_response = super()._invoke({"query": query}, **kwargs)
|
| 32 |
+
result = raw_response
|
| 33 |
+
if self.fact_checking:
|
| 34 |
+
web_pages = result['results']
|
| 35 |
+
for i in range(len(web_pages) - 1, -1, -1):
|
| 36 |
+
url = web_pages[i].get('url', '')
|
| 37 |
+
if not IsTrusted(url):
|
| 38 |
+
del result['results'][i]
|
| 39 |
+
return result
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def IsTrusted(url: str) -> bool:
|
| 43 |
+
try:
|
| 44 |
+
extracted = tldextract.extract(url)
|
| 45 |
+
# subdomain = extracted.subdomain.lower()
|
| 46 |
+
domain = extracted.domain.lower()
|
| 47 |
+
suffix = extracted.suffix.lower()
|
| 48 |
+
if suffix in TRUSTED_SUFFIXES:
|
| 49 |
+
return True
|
| 50 |
+
elif domain in TRUSTED_DOMAINS_DOMESTIC:
|
| 51 |
+
return True
|
| 52 |
+
elif domain in TRUSTED_DOMAINS_ABOARD:
|
| 53 |
+
return True
|
| 54 |
+
else:
|
| 55 |
+
match = re.search(r'(?:/@|@)([^/?]+)', url)
|
| 56 |
+
if match and (match.group(1) in TRUSTED_PERSON):
|
| 57 |
+
return True
|
| 58 |
+
else:
|
| 59 |
+
return False
|
| 60 |
+
except Exception:
|
| 61 |
+
return False
|
| 62 |
|
| 63 |
class GetLocation(BaseTool):
|
| 64 |
+
name: str = "get ip location"
|
| 65 |
+
description: str = "获取本机IP归属地的工具,输入参数是本机IP地址"
|
| 66 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 67 |
+
super().__init__(**kwargs)
|
| 68 |
+
self.description = (
|
| 69 |
+
"获取本机IP归属地的工具,输入参数是本机IP地址"
|
| 70 |
+
if selected_language == "ch"
|
| 71 |
+
else "A tool to get the location of the local IP address. The input parameter is the local IP address."
|
| 72 |
+
)
|
| 73 |
|
| 74 |
def _run(self, ip_address: str) -> str:
|
| 75 |
api_key = "f962beaf785545d0a90b76d105996cdb"
|
|
|
|
| 84 |
|
| 85 |
class CurrencyConversion(BaseTool):
|
| 86 |
name: str = "货币换算"
|
| 87 |
+
description: str = "获取指定基准货币和目标货币之间的实时汇率。输入参数包括基准货币代码和目标货币代码。传参格式:'USD|EUR'(第一个参数为基准货币代码,第二个参数为目标货币代码)。"
|
| 88 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 89 |
+
super().__init__(**kwargs)
|
| 90 |
+
self.description = (
|
| 91 |
+
"获取指定基准货币和目标货币之间的实时汇率。输入参数包括基准货币代码和目标货币代码。传参���式:'USD|EUR'(第一个参数为基准货币代码,第二个参数为目标货币代码)。"
|
| 92 |
+
if selected_language == "ch"
|
| 93 |
+
else "Get the real-time exchange rate between the specified benchmark currency and target currency. The input parameters include the benchmark currency code and the target currency code. Parameter transmission format: USD | EUR '(the first parameter is the base currency code, and the second parameter is the target currency code)."
|
| 94 |
+
)
|
| 95 |
+
# description: str =(
|
| 96 |
+
# "获取指定基准货币和目标货币之间的实时汇率。输入参数包括基准货币代码和目标货币代码。传参格式:'USD|EUR'(第一个参数为基准货币代码,第二个参数为目标货币代码)。"
|
| 97 |
+
# if selected_language == "ch"
|
| 98 |
+
# else "Get the real-time exchange rate between the specified benchmark currency and target currency. The input parameters include the benchmark currency code and the target currency code. Parameter transmission format: USD | EUR '(the first parameter is the base currency code, and the second parameter is the target currency code)."
|
| 99 |
+
# )
|
| 100 |
|
| 101 |
def _run(self, _input: str) -> str:
|
| 102 |
pattern = r"(?P<base_currency>\S+)\|(?P<target_currency>\S+)"
|
|
|
|
| 114 |
|
| 115 |
|
| 116 |
class GetHoliday(BaseTool):
|
| 117 |
+
name: str = "假日查询"
|
| 118 |
+
description: str = "获取指定国家在某一天的假期信息。输入参数包括国家代码和日期(年、月、日)。传参格式:'US|2025|1|1'(第一个参数为国家代码,后续三个参数为年份、月份和日期)。"
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 121 |
+
super().__init__(**kwargs)
|
| 122 |
+
self.description = (
|
| 123 |
+
"获取指定国家在某一天的假期信息。输入参数包括国家代码和日期(年、月、日)。传参格式:'US|2025|1|1'(第一个参数为国家代码,后续三个参数为年份、月份和日期)。"
|
| 124 |
+
if selected_language == "ch"
|
| 125 |
+
else "Retrieve holiday information for a specified country on a certain day. The input parameters include country code and date (year, month, day). Parameter transmission format: US | 2025 | 1 | 1 '(The first parameter is the country code, and the following three parameters are the year, month, and date)."
|
| 126 |
+
)
|
| 127 |
+
# description: str = (
|
| 128 |
+
# "获取指定国家在某一天的假期信息。输入参数包括国家代码和日期(年、月、日)。传参格式:'US|2025|1|1'(第一个参数为国家代码,后续三个参数为年份、月份和日期)。"if selected_language == "ch"
|
| 129 |
+
# else "Retrieve holiday information for a specified country on a certain day. The input parameters include country code and date (year, month, day). Parameter transmission format: US | 2025 | 1 | 1 '(The first parameter is the country code, and the following three parameters are the year, month, and date)."
|
| 130 |
+
# )
|
| 131 |
|
| 132 |
+
def _run(self, _input: str) -> str:
|
| 133 |
pattern = r"(?P<country>[A-Za-z]{2,3})\|(?P<year>\d{4})\|(?P<month>\d{1,2})\|(?P<day>\d{1,2})"
|
| 134 |
match = re.match(pattern, _input)
|
| 135 |
country = match.group("country")
|
|
|
|
| 170 |
|
| 171 |
class SafeExpressionEvaluator(BaseTool):
|
| 172 |
name: str = "safe expression evaluator"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
safe_globals: dict = None # 声明类型
|
| 174 |
safe_locals: dict = None
|
| 175 |
+
description: str = "安全地计算 Python 表达式,输入参数为表达式字符串。"
|
| 176 |
+
def __init__(self, selected_language:str, **kwargs):
|
| 177 |
super().__init__(**kwargs)
|
| 178 |
# 定义安全的执行环境
|
| 179 |
self.safe_globals = {
|
|
|
|
| 190 |
"math":__import__("math"),
|
| 191 |
}
|
| 192 |
self.safe_locals = {}
|
| 193 |
+
self.description = (
|
| 194 |
+
"安全地计算 Python 表达式,输入参数为表达式字符串。"
|
| 195 |
+
if selected_language == "ch"
|
| 196 |
+
else "Safely evaluate Python expressions, with input being an expression string."
|
| 197 |
+
)
|
| 198 |
|
| 199 |
def _run(self, expression: str) -> Dict[str, Any]:
|
| 200 |
"""安全地计算一个表达式,并返回结果"""
|
|
|
|
| 207 |
|
| 208 |
class SafeCodeExecutor(BaseTool):
|
| 209 |
name: str = "safe code executor"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
safe_globals: dict = None # 声明类型
|
| 211 |
safe_locals: dict = None
|
| 212 |
+
description:str = "安全地执行 Python 代码块,输入参数为代码字符串。"
|
| 213 |
+
def __init__(self,selected_language: str, **kwargs):
|
| 214 |
super().__init__()
|
| 215 |
self.safe_globals = {
|
| 216 |
"__builtins__": {
|
|
|
|
| 228 |
"math": __import__("math"),
|
| 229 |
}
|
| 230 |
self.safe_locals = {}
|
| 231 |
+
self.description = (
|
| 232 |
+
"安全地执行 Python 代码块,输入参数为代码字符串。"
|
| 233 |
+
if selected_language == "ch"
|
| 234 |
+
else "Safely execute Python code blocks, with input being a code string."
|
| 235 |
+
)
|
| 236 |
|
| 237 |
def _run(self, code: str) -> Dict[str, Any]:
|
| 238 |
"""安全地执行一段 Python 代码(包括函数、类定义等),无返回值"""
|
|
|
|
| 253 |
|
| 254 |
class WeatherCrossing(BaseTool):
|
| 255 |
name: str = "天气查询"
|
| 256 |
+
description: str = "使用 Visual Crossing API 查询指定城市的天气信息,输入参数包括城市名称,以及可选的开始日期和结束日期(格式为 yyyy-MM-dd)。"
|
| 257 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 258 |
+
super().__init__(**kwargs)
|
| 259 |
+
self.description = (
|
| 260 |
+
"使用 Visual Crossing API 查询指定城市的天气信息,输入参数包括城市名称,以及可选的开始日期和结束日期(格式为 yyyy-MM-dd)。"
|
| 261 |
+
if selected_language == "ch"
|
| 262 |
+
else "Use the Visual Crossing API to query weather information for a specified city, with input parameters including the city name and optional start and end dates (in the format yyyy MM dd)."
|
| 263 |
+
)
|
| 264 |
def _run(self, city: str, date1: str = None, date2: str = None) -> dict:
|
| 265 |
base_url = "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline"
|
| 266 |
api_key = "6LX8E4LWX7ZFSCCA5S3JLFVPS"
|
|
|
|
| 282 |
|
| 283 |
|
| 284 |
class RegionInquiryTool(BaseTool):
|
| 285 |
+
name: str = "Region Inquiry Tool" # 添加类型注解
|
| 286 |
+
description : str = "获取指定行政区的信息,包括名称、描述(行政级别)。根据 subdistrict 参数,返回该行政区的下级行政区信息。输入参数包括行政区名称和下级行政区级数(0 - 3)。传参格式:'北京|1'(第一个参数为行政区名称,第二个参数为下级行政区级数)。"
|
| 287 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 288 |
+
super().__init__(**kwargs)
|
| 289 |
+
self.description = (
|
| 290 |
+
"获取指定行政区的信息,包括名称、描述(行政级别)。根据 subdistrict 参数,返回该行政区的下级行政区信息。输入参数包括行政区名称和下级行政区级数(0 - 3)。传参格式:'北京|1'(第一个参数为行政区名称,第二个参数为下级行政区级数)。"
|
| 291 |
+
if selected_language == "ch"
|
| 292 |
+
else "Retrieve information about the designated administrative region, including its name and description (administrative level). According to the subdistrict parameter, return the information of the subordinate administrative regions of the administrative region. The input parameters include the name of the administrative region and the level of the subordinate administrative region (0-3). Parameter format: 'Beijing | 1' (the first parameter is the name of the administrative region, and the second parameter is the level of the subordinate administrative region)"
|
| 293 |
+
)
|
| 294 |
+
# description: str = ("获取指定行政区的信息,包括名称、描述(行政级别)。根据 subdistrict 参数,返回该行政区的下级行政区信息。输入参数包括行政区名称和下级行政区级数(0 - 3)。传参格式:'北京|1'(第一个参数为行政区名称,第二个参数为下级行政区级数)。 "
|
| 295 |
+
# if selected_language == "ch"
|
| 296 |
+
# else "Retrieve information about the designated administrative region, including its name and description (administrative level). According to the subdistrict parameter, return the information of the subordinate administrative regions of the administrative region. The input parameters include the name of the administrative region and the level of the subordinate administrative region (0-3). Parameter format: 'Beijing | 1' (the first parameter is the name of the administrative region, and the second parameter is the level of the subordinate administrative region)")
|
| 297 |
|
| 298 |
def _run(self, _input: str) -> Dict[str, Any]:
|
| 299 |
|
|
|
|
| 319 |
|
| 320 |
|
| 321 |
class HTMLTextExtractor(BaseTool):
|
| 322 |
+
name: str = "html text extractor"
|
| 323 |
+
description: str = "提取 HTML 文档中的纯文本内容,输入参数为 HTML 文档的字符串内容,返回去除标签后的纯文本。"
|
| 324 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 325 |
+
super().__init__(**kwargs)
|
| 326 |
+
self.description = (
|
| 327 |
+
"提取 HTML 文档中的纯文本内容,输入参数为 HTML 文档的字符串内容,返回去除标签后的纯文本。"
|
| 328 |
+
if selected_language == "ch"
|
| 329 |
+
else "Extract plain text content from an HTML document, input the string content of the HTML document as the parameter, and return the plain text after removing tags."
|
| 330 |
+
)
|
| 331 |
def _run(self, html_content: str) -> dict:
|
| 332 |
if not html_content:
|
| 333 |
return {"result": None, "error": "HTML 内容不能为空。"}
|
|
|
|
| 341 |
|
| 342 |
|
| 343 |
class BaiduNewsSearchTool(BaseTool):
|
| 344 |
+
name: str = "Baidu News Search"
|
| 345 |
+
description: str = "备用搜索引擎,当主要搜索引擎不返回结果时调用,输入是检索query"
|
| 346 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 347 |
+
super().__init__(**kwargs)
|
| 348 |
+
self.description = (
|
| 349 |
+
"备用搜索引擎,当主要搜索引擎不返回结果时调用,输入是检索query"
|
| 350 |
+
if selected_language == "ch"
|
| 351 |
+
else "Backup search engine, called when the primary search engine does not return results, input is search query"
|
| 352 |
+
)
|
| 353 |
+
# description: str = "备用搜索引擎,当主要搜索引擎不返回结果时调用,输入是检索query" if selected_language == "ch" else "Backup search engine, called when the primary search engine does not return results, input is search query"# 添加类型注解
|
| 354 |
|
| 355 |
def _run(self, query: str) -> str:
|
| 356 |
"""
|
|
|
|
| 372 |
|
| 373 |
|
| 374 |
class BoChaSearchTool(BaseTool):
|
| 375 |
+
name: str = "BoCha Webs Search"
|
| 376 |
+
description: str = "首选搜索引擎,当需要检索信息时调用,输入是检索query。"
|
| 377 |
+
fact_checking: bool = False
|
| 378 |
+
def __init__(self, selected_language: str, fact_checking: bool = False,**kwargs):
|
| 379 |
+
super().__init__(**kwargs)
|
| 380 |
+
self.description = (
|
| 381 |
+
"首选搜索引擎,当需要检索信息时调用,输入是检索query。"
|
| 382 |
+
if selected_language == "ch"
|
| 383 |
+
else "The main search engine is called when information needs to be retrieved, with the input being a search query."
|
| 384 |
+
)
|
| 385 |
+
self.fact_checking= fact_checking
|
| 386 |
+
# description: str = "主力搜索引擎,当需要检索信息时调用,输入是检索query。" if selected_language == "ch" else "The main search engine is called when information needs to be retrieved, with the input being a search query." # 添加类型注解
|
| 387 |
def _run(self, query: str) -> str:
|
| 388 |
|
| 389 |
url = "https://api.bochaai.com/v1/web-search"
|
| 390 |
payload = json.dumps({
|
| 391 |
"query": query,
|
| 392 |
+
"count": 5,
|
| 393 |
"summary": True
|
| 394 |
})
|
| 395 |
headers = {
|
|
|
|
| 397 |
'Content-Type': 'application/json'
|
| 398 |
}
|
| 399 |
response = requests.request("POST", url, headers=headers, data=payload)
|
| 400 |
+
result = response.json()
|
| 401 |
+
if self.fact_checking:
|
| 402 |
+
web_pages = result['data']['webPages']['value']
|
| 403 |
+
for i in range(len(web_pages) - 1, -1, -1):
|
| 404 |
+
url = web_pages[i].get('url', '')
|
| 405 |
+
if not IsTrusted(url):
|
| 406 |
+
del result['data']['webPages']['value'][i]
|
| 407 |
+
return result
|
| 408 |
|
| 409 |
|
| 410 |
class ImageSearchTool(BaseTool):
|
| 411 |
+
name: str = "Image Search"
|
| 412 |
+
description: str = "搜索图片引擎,当你需要检索相关图片的时候调用,输入是检索query,输出是与query有关的图片的信息"
|
| 413 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 414 |
+
super().__init__(**kwargs)
|
| 415 |
+
self.description = (
|
| 416 |
+
"搜索图片引擎,当你需要检索相关图片的时候调用,输入是检索query,输出是与query有关的图片的信息"
|
| 417 |
+
if selected_language == "ch"
|
| 418 |
+
else "Search image engine, called when you need to retrieve relevant images. The input is the search query, and the output is information about the images related to the query"
|
| 419 |
+
)
|
| 420 |
|
| 421 |
def _run(self, query: str) -> str:
|
| 422 |
params = {
|
|
|
|
| 461 |
# print(tool.run("USD|EUR"))
|
| 462 |
|
| 463 |
class LocationSearch(BaseTool):
|
| 464 |
+
name: str = "location search"
|
| 465 |
+
description: str = "搜索地点的工具,调用参数为一个关键词"
|
| 466 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 467 |
+
super().__init__(**kwargs)
|
| 468 |
+
self.description = (
|
| 469 |
+
"搜索地点的工具,调用参数为一个关键词"
|
| 470 |
+
if selected_language == "ch"
|
| 471 |
+
else "A tool for searching locations, with a call parameter of a keyword"
|
| 472 |
+
)
|
| 473 |
+
# description: str = (
|
| 474 |
+
# "搜索地点的工具,调用参数为一个关键词" if selected_language == "ch"
|
| 475 |
+
# else "A tool for searching locations, with a call parameter of a keyword"
|
| 476 |
+
# )
|
| 477 |
|
| 478 |
def _run(self, keyword: str) -> str:
|
| 479 |
key = "e7ff59e1de1573456145f0d736cc3a2f"
|
|
|
|
| 483 |
|
| 484 |
|
| 485 |
class ReverseGeocodingTool(BaseTool):
|
| 486 |
+
name: str = "reverse geocoding api"
|
| 487 |
+
description: str = "通过给定结构化地址来获取地址经纬度的工具,调用参数为结构化地址信息(规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。)"
|
| 488 |
+
def __init__(self, selected_language: str, **kwargs):
|
| 489 |
+
super().__init__(**kwargs)
|
| 490 |
+
self.description = (
|
| 491 |
+
"通过给定结构化地址来获取地址经纬度的工具,调用参数为结构化地址信息(规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。)"
|
| 492 |
+
if selected_language == "ch"
|
| 493 |
+
else "A tool that obtains the latitude and longitude of an address by giving it a structured address, with the parameters being structured address information (following the rules: country, province, city, district, town, countryside, street, house number, housing estate, building, such as No. 6 Futong East Street, Chaoyang District, Beijing)"
|
| 494 |
+
)
|
| 495 |
+
# description: str = (
|
| 496 |
+
# "通过给定结构化地址来获取地址经纬度的工具,调用参数为结构化地址信息(规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。)"
|
| 497 |
+
# if selected_language == "ch"
|
| 498 |
+
# else "A tool that obtains the latitude and longitude of an address by giving it a structured address, with the parameters being structured address information (following the rules: country, province, city, district, town, countryside, street, house number, housing estate, building, such as No. 6 Futong East Street, Chaoyang District, Beijing)"
|
| 499 |
+
# )
|
| 500 |
|
| 501 |
def _run(self, address: str) -> str:
|
| 502 |
key = "e7ff59e1de1573456145f0d736cc3a2f"
|
| 503 |
url = f"https://restapi.amap.com/v3/geocode/geo?address={address}&output=JSON&key={key}"
|
| 504 |
response = requests.get(url)
|
| 505 |
+
return response.json()['geocodes'][0]['location']
|
| 506 |
+
|
| 507 |
+
|
| 508 |
+
# url = 'https://api.openai-sb.com/sb-api/user/status?api_key=sb-6a683cb3bd63a9b72040aa2dd08feff8b68f08a0e1d959f5'
|
| 509 |
+
# url = 'https://api.openai-sb.com/sb-api/user/card/use?api_key=sb-6a683cb3bd63a9b72040aa2dd08feff8b68f08a0e1d959f5&card=d7f0fff7-8473-49df-8c8e-01336842c0d2'
|
| 510 |
+
# requests = requests.get(url)
|
| 511 |
+
# print(requests.json())
|
| 512 |
+
# 282f7863-a32a-45a6-930d-f35059b1e75b
|
| 513 |
+
# 78575d8b-95de-470c-ac62-7be197911b2d
|
| 514 |
+
# c4502776-3167-4ebb-99a7-8c62bd0912b9
|
| 515 |
+
|
| 516 |
+
|
| 517 |
+
# 98f0a3b2-7594-49b5-b16e-6e4b3dbb1cfe
|
| 518 |
+
# f65e918c-0a33-45b8-8347-163acd71cd55
|
| 519 |
+
|
| 520 |
+
|
| 521 |
+
# 99fd2616-841e-43a9-b8bf-9162cacea17a
|
| 522 |
+
# 7ef7e48c-30d1-4ed2-98d7-6e838e5d1577
|