Spaces:
Build error
Build error
File size: 17,317 Bytes
b19cd83 af57c82 b19cd83 7648ae7 b19cd83 7648ae7 b19cd83 7648ae7 b19cd83 7648ae7 b19cd83 7648ae7 b19cd83 7648ae7 b19cd83 7648ae7 b19cd83 7648ae7 b19cd83 7648ae7 b19cd83 7648ae7 b19cd83 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
import re
import uuid
from typing import Any, Dict, Union, Optional
from langchain_core.callbacks import Callbacks
from langchain_core.runnables import RunnableConfig
from openai import OpenAI
import requests
from bs4 import BeautifulSoup
from config import selected_language
from serpapi import GoogleSearch
from langchain.tools import BaseTool
import json
def DailyNews():
dailynews = ""
url = "https://v.api.aa1.cn/api/zhihu-news/"
result = requests.get(url, verify=False).json()
for index in result['news']:
dailynews = dailynews + index['title'] + "\n"
# print(index['title'])
return dailynews
# selected_language = "ch"
class GetLocation(BaseTool):
# global selected_language
# language: str = selected_language
name: str = "获取ip地址"
description: str = (
"获取本机IP归属地的工具,输入参数是本机IP地址"
if selected_language == "ch"
else "A tool to get the location of the local IP address. The input parameter is the local IP address."
)
def _run(self, ip_address: str) -> str:
api_key = "f962beaf785545d0a90b76d105996cdb"
url = f"https://ipgeolocation.abstractapi.com/v1/?api_key={api_key}&ip_address={ip_address}"
try:
response = requests.get(url)
response.raise_for_status()
return response.text
except requests.exceptions.RequestException as e:
return f"请求失败: {e}"
class CurrencyConversion(BaseTool):
name: str = "货币换算"
description: str =(
"获取指定基准货币和目标货币之间的实时汇率。输入参数包括基准货币代码和目标货币代码。传参格式:'USD|EUR'(第一个参数为基准货币代码,第二个参数为目标货币代码)。"
if selected_language == "ch"
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)."
)
def _run(self, _input: str) -> str:
pattern = r"(?P<base_currency>\S+)\|(?P<target_currency>\S+)"
match = re.match(pattern, _input)
base = match.group("base_currency")
target = match.group("target_currency")
api_key = "3599c1514c554f6da2ae8916151e5770"
url = f"https://exchange-rates.abstractapi.com/v1/live/?api_key={api_key}&base={base}&target={target}"
try:
response = requests.get(url)
response.raise_for_status()
return response.content
except requests.exceptions.RequestException as e:
return f"请求失败: {e}"
class GetHoliday(BaseTool):
name: str = "获取假日信息"
description: str = (
"获取指定国家在某一天的假期信息。输入参数包括国家代码和日期(年、月、日)。传参格式:'US|2025|1|1'(第一个参数为国家代码,后续三个参数为年份、月份和日期)。"if selected_language == "ch"
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)."
)
def _run(self, _input: str) -> str:
pattern = r"(?P<country>[A-Za-z]{2,3})\|(?P<year>\d{4})\|(?P<month>\d{1,2})\|(?P<day>\d{1,2})"
match = re.match(pattern, _input)
country = match.group("country")
year = match.group("year")
month = match.group("month")
day = match.group("day")
base_url = "https://holidays.abstractapi.com/v1/"
api_key = "fa1dbc3bf696406db3412a7d034ba531"
params = {"api_key": api_key, "country": country}
if year:
params["year"] = year
if month:
params["month"] = month
if day:
params["day"] = day
query_string = "&".join([f"{key}={value}" for key, value in params.items() if value is not None])
url = f"{base_url}?{query_string}"
try:
response = requests.get(url)
response.raise_for_status() # 检查 HTTP 响应状态
data = response.json()
if data:
holidays = "\n".join(
[f"{holiday['name']} - {holiday['type']}" for holiday in data]
)
return f"查询日期的节日信息:\n{holidays}"
else:
return f"{year}-{month}-{day} 在 {country} 没有节日。"
except requests.exceptions.RequestException as e:
return f"请求失败: {e}"
def holiday2(country, year):
url = f"https://calendarific.com/api/v2/holidays?&api_key=O7fuldKDDJgpl9ckui8lduMWNjx4bCDf&country={country}&year={year}"
response = requests.get(url).json()
print(response)
class SafeExpressionEvaluator(BaseTool):
name: str = "safe expression evaluator"
description: str = (
"安全地计算 Python 表达式,输入参数为表达式字符串。"
if selected_language == "ch"
else "Safely evaluate Python expressions, with input being an expression string."
)
safe_globals: dict = None # 声明类型
safe_locals: dict = None
def __init__(self, **kwargs):
super().__init__(**kwargs)
# 定义安全的执行环境
self.safe_globals = {
"__builtins__": {
"abs": abs,
"min": min,
"max": max,
"sum": sum,
"len": len,
"round": round,
"pow": pow,
"divmod": divmod,
},
"math":__import__("math"),
}
self.safe_locals = {}
def _run(self, expression: str) -> Dict[str, Any]:
"""安全地计算一个表达式,并返回结果"""
try:
result = eval(expression, self.safe_globals, self.safe_locals)
return {"result": result, "error": None}
except Exception as e:
return {"result": None, "error": str(e)}
class SafeCodeExecutor(BaseTool):
name: str = "safe code executor"
description: str = (
"安全地执行 Python 代码块,输入参数为代码字符串。"
if selected_language == "ch"
else "Safely execute Python code blocks, with input being a code string."
)
safe_globals: dict = None # 声明类型
safe_locals: dict = None
def __init__(self, **kwargs):
super().__init__()
self.safe_globals = {
"__builtins__": {
"abs": abs,
"min": min,
"max": max,
"sum": sum,
"len": len,
"round": round,
"pow": pow,
"divmod": divmod,
"print" : print
# 添加更多安全函数
},
"math": __import__("math"),
}
self.safe_locals = {}
def _run(self, code: str) -> Dict[str, Any]:
"""安全地执行一段 Python 代码(包括函数、类定义等),无返回值"""
try:
exec(code, self.safe_globals, self.safe_locals)
return {"result": "Code executed successfully.", "error": None}
except Exception as e:
return {"result": None, "error": str(e)}
def weather(city):
"""
高德天气,查询当天的天气
"""
url = f"https://restapi.amap.com/v3/weather/weatherInfo?city={city}&key=e7ff59e1de1573456145f0d736cc3a2f"
response = requests.get(url).json()
print(response)
class WeatherCrossing(BaseTool):
name: str = "天气查询"
description: str = "使用 Visual Crossing API 查询指定城市的天气信息,输入参数包括城市名称,以及可选的开始日期和结束日期(格式为 yyyy-MM-dd)。" if selected_language == "ch" 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)."
def _run(self, city: str, date1: str = None, date2: str = None) -> dict:
base_url = "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline"
api_key = "6LX8E4LWX7ZFSCCA5S3JLFVPS"
if date1 and date2:
url = f"{base_url}/{city}/{date1}/{date2}?key={api_key}"
elif date1:
url = f"{base_url}/{city}/{date1}?key={api_key}"
else:
url = f"{base_url}/{city}?key={api_key}"
try:
response = requests.get(url)
response.raise_for_status() # 检查 HTTP 响应状态
data = response.json()
return {"result": data, "error": None}
except requests.exceptions.RequestException as e:
return {"result": None, "error": f"请求失败: {e}"}
except ValueError:
return {"result": None, "error": "无法解析返回的 JSON 数据。"}
class RegionInquiryTool(BaseTool):
name: str = "行政区查询" # 添加类型注解
description: str = ("获取指定行政区的信息,包括名称、描述(行政级别)。根据 subdistrict 参数,返回该行政区的下级行政区信息。输入参数包括行政区名称和下级行政区级数(0 - 3)。传参格式:'北京|1'(第一个参数为行政区名称,第二个参数为下级行政区级数)。 "
if selected_language == "ch"
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)")
def _run(self, _input: str) -> Dict[str, Any]:
pattern = r"(?P<district>.+?)\|(?P<level>\d{1,3})"
match = re.match(pattern, _input)
district = match.group("district")
level = match.group("level")
# keywords = kwargs.get("keywords")
# subdistrict = kwargs.get("subdistrict", 0)
api_key = "e7ff59e1de1573456145f0d736cc3a2f"
base_url = "https://restapi.amap.com/v3/config/district"
params = {
"keywords": district,
"subdistrict": level,
"key": api_key
}
try:
response = requests.get(base_url, params=params)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
return {"error": str(e)}
class HTMLTextExtractor(BaseTool):
name: str = "html提取"
description: str = "提取 HTML 文档中的纯文本内容,输入参数为 HTML 文档的字符串内容,返回去除标签后的纯文本。" if selected_language == "ch" 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."
def _run(self, html_content: str) -> dict:
if not html_content:
return {"result": None, "error": "HTML 内容不能为空。"}
try:
soup = BeautifulSoup(html_content, 'lxml')
text = soup.get_text()
return {"result": text.strip(), "error": None}
except Exception as e:
return {"result": None, "error": f"提取文本失败: {e}"}
class BaiduNewsSearchTool(BaseTool):
name: str = "Baidu News Search" # 添加类型注解
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"# 添加类型注解
def _run(self, query: str) -> str:
"""
使用百度新闻引擎进行查询。
"""
params = {
"engine": "baidu_news",
"q": query,
"ct": "1",
"api_key": "dcc98b22d5f7d413979a175ff7d75b721c5992a3ee1e2363020b2bbdf4f82404"
}
search = GoogleSearch(params) # 使用GoogleSearch库进行查询
results = search.get_dict()
organic_results = results.get("organic_results", [])
if not organic_results:
return "No results found."
return organic_results
class BoChaSearchTool(BaseTool):
name: str = "网页搜索" # 添加类型注解
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." # 添加类型注解
def _run(self, query: str) -> str:
url = "https://api.bochaai.com/v1/web-search"
payload = json.dumps({
"query": query,
"count": 3,
"summary": True
})
headers = {
'Authorization': 'Bearer sk-adeb0353f3434158934a841ac0f8d4a4',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.json())
return response.json()
class ImageSearchTool(BaseTool):
name: str = "图片搜索"
description: str = "搜索图片引擎,当你需要检索相关图片的时候调用,输入是检索query,输出是与query有关的图片的信息" if selected_language == "ch" 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"
def _run(self, query: str) -> str:
params = {
"engine": "google_images",
"q": query,
"gl": "cn",
}
search = GoogleSearch(params)
results = search.get_dict()
suggested_searches = results.get('suggested_searches', [])
if suggested_searches:
thumbnails = [search['thumbnail'] for search in suggested_searches][:3]
else:
thumbnails = []
information = ""
client = OpenAI()
for idx, thumbnail in enumerate(thumbnails):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "What’s in this image?Give a brief answer"},
{
"type": "image_url",
"image_url": {
"url": thumbnail,
},
},
],
}
],
max_tokens=100,
)
response_content = response.choices[0].message.content
information = information + str(idx + 1) + ": " + response_content + "\n"
return information
# tool = CurrencyConversion()
# print(tool.run("USD|EUR"))
class LocationSearch(BaseTool):
name: str = "地点查询"
description: str = (
"搜索地点的工具,调用参数为一个关键词" if selected_language == "ch"
else "A tool for searching locations, with a call parameter of a keyword"
)
def _run(self, keyword: str) -> str:
key = "e7ff59e1de1573456145f0d736cc3a2f"
url = f"https://restapi.amap.com/v3/place/text?keywords={keyword}&offset=20&page=1&key={key}"
response = requests.get(url)
return response.json()
class ReverseGeocodingTool(BaseTool):
name: str = "经纬度获取"
description: str = (
"通过给定结构化地址来获取地址经纬度的工具,调用参数为结构化地址信息(规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。)"
if selected_language == "ch"
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)"
)
def _run(self, address: str) -> str:
key = "e7ff59e1de1573456145f0d736cc3a2f"
url = f"https://restapi.amap.com/v3/geocode/geo?address={address}&output=JSON&key={key}"
response = requests.get(url)
return response.json()['geocodes'][0]['location'] |