Spaces:
Sleeping
Sleeping
zhang-3000
commited on
Commit
·
ed3871a
1
Parent(s):
d97e391
- app.py +1 -1
- arxiv_search.py +79 -0
- weather_query.py +71 -0
app.py
CHANGED
@@ -2,7 +2,7 @@ import copy
|
|
2 |
import os
|
3 |
from typing import List
|
4 |
import streamlit as st
|
5 |
-
|
6 |
from lagent.prompts.parsers import PluginParser
|
7 |
from lagent.agents.stream import INTERPRETER_CN, META_CN, PLUGIN_CN, AgentForInternLM, get_plugin_prompt
|
8 |
from lagent.llms import GPTAPI
|
|
|
2 |
import os
|
3 |
from typing import List
|
4 |
import streamlit as st
|
5 |
+
import ArxivSearch, WeatherQuery
|
6 |
from lagent.prompts.parsers import PluginParser
|
7 |
from lagent.agents.stream import INTERPRETER_CN, META_CN, PLUGIN_CN, AgentForInternLM, get_plugin_prompt
|
8 |
from lagent.llms import GPTAPI
|
arxiv_search.py
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Optional, Type
|
2 |
+
|
3 |
+
from asyncer import asyncify
|
4 |
+
|
5 |
+
from lagent.actions.base_action import AsyncActionMixin, BaseAction, tool_api
|
6 |
+
from lagent.actions.parser import BaseParser, JsonParser
|
7 |
+
from lagent.schema import ActionReturn, ActionStatusCode
|
8 |
+
|
9 |
+
|
10 |
+
class ArxivSearch(BaseAction):
|
11 |
+
"""Search information from Arxiv.org. \
|
12 |
+
Useful for when you need to answer questions about Physics, Mathematics, \
|
13 |
+
Computer Science, Quantitative Biology, Quantitative Finance, Statistics, \
|
14 |
+
Electrical Engineering, and Economics from scientific articles on arxiv.org.
|
15 |
+
"""
|
16 |
+
|
17 |
+
def __init__(
|
18 |
+
self,
|
19 |
+
top_k_results: int = 3,
|
20 |
+
max_query_len: int = 300,
|
21 |
+
doc_content_chars_max: int = 1500,
|
22 |
+
description: Optional[dict] = None,
|
23 |
+
parser: Type[BaseParser] = JsonParser,
|
24 |
+
):
|
25 |
+
super().__init__(description, parser)
|
26 |
+
self.top_k_results = top_k_results
|
27 |
+
self.max_query_len = max_query_len
|
28 |
+
self.doc_content_chars_max = doc_content_chars_max
|
29 |
+
|
30 |
+
@tool_api(explode_return=True)
|
31 |
+
def get_arxiv_article_information(self, query: str) -> dict:
|
32 |
+
"""Run Arxiv search and get the article meta information.
|
33 |
+
|
34 |
+
Args:
|
35 |
+
query (:class:`str`): the content of search query
|
36 |
+
|
37 |
+
Returns:
|
38 |
+
:class:`dict`: article information
|
39 |
+
* content (str): a list of 3 arxiv search papers
|
40 |
+
"""
|
41 |
+
import arxiv
|
42 |
+
|
43 |
+
try:
|
44 |
+
results = arxiv.Search( # type: ignore
|
45 |
+
query[: self.max_query_len], max_results=self.top_k_results
|
46 |
+
).results()
|
47 |
+
except Exception as exc:
|
48 |
+
return ActionReturn(errmsg=f'Arxiv exception: {exc}', state=ActionStatusCode.HTTP_ERROR)
|
49 |
+
docs = [
|
50 |
+
f'Published: {result.updated.date()}\nTitle: {result.title}\n'
|
51 |
+
f'Authors: {", ".join(a.name for a in result.authors)}\n'
|
52 |
+
f'Summary: {result.summary[:self.doc_content_chars_max]}'
|
53 |
+
for result in results
|
54 |
+
]
|
55 |
+
if docs:
|
56 |
+
return {'content': '\n\n'.join(docs)}
|
57 |
+
return {'content': 'No good Arxiv Result was found'}
|
58 |
+
|
59 |
+
|
60 |
+
class AsyncArxivSearch(AsyncActionMixin, ArxivSearch):
|
61 |
+
"""Search information from Arxiv.org. \
|
62 |
+
Useful for when you need to answer questions about Physics, Mathematics, \
|
63 |
+
Computer Science, Quantitative Biology, Quantitative Finance, Statistics, \
|
64 |
+
Electrical Engineering, and Economics from scientific articles on arxiv.org.
|
65 |
+
"""
|
66 |
+
|
67 |
+
@tool_api(explode_return=True)
|
68 |
+
@asyncify
|
69 |
+
def get_arxiv_article_information(self, query: str) -> dict:
|
70 |
+
"""Run Arxiv search and get the article meta information.
|
71 |
+
|
72 |
+
Args:
|
73 |
+
query (:class:`str`): the content of search query
|
74 |
+
|
75 |
+
Returns:
|
76 |
+
:class:`dict`: article information
|
77 |
+
* content (str): a list of 3 arxiv search papers
|
78 |
+
"""
|
79 |
+
return super().get_arxiv_article_information(query)
|
weather_query.py
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import requests
|
3 |
+
from lagent.actions.base_action import BaseAction, tool_api
|
4 |
+
from lagent.schema import ActionReturn, ActionStatusCode
|
5 |
+
|
6 |
+
class WeatherQuery(BaseAction):
|
7 |
+
def __init__(self):
|
8 |
+
super().__init__()
|
9 |
+
self.api_key = os.getenv("weather_token")
|
10 |
+
print(self.api_key)
|
11 |
+
if not self.api_key:
|
12 |
+
raise EnvironmentError("未找到环境变量 'token'。请设置你的和风天气 API Key 到 'weather_token' 环境变量中,比如export weather_token='xxx' ")
|
13 |
+
|
14 |
+
@tool_api
|
15 |
+
def run(self, location: str) -> dict:
|
16 |
+
"""
|
17 |
+
查询实时天气信息。
|
18 |
+
|
19 |
+
Args:
|
20 |
+
location (str): 要查询的地点名称、LocationID 或经纬度坐标(如 "101010100" 或 "116.41,39.92")。
|
21 |
+
|
22 |
+
Returns:
|
23 |
+
dict: 包含天气信息的字典
|
24 |
+
* location: 地点名称
|
25 |
+
* weather: 天气状况
|
26 |
+
* temperature: 当前温度
|
27 |
+
* wind_direction: 风向
|
28 |
+
* wind_speed: 风速(公里/小时)
|
29 |
+
* humidity: 相对湿度(%)
|
30 |
+
* report_time: 数据报告时间
|
31 |
+
"""
|
32 |
+
try:
|
33 |
+
# 如果 location 不是坐标格式(例如 "116.41,39.92"),则调用 GeoAPI 获取 LocationID
|
34 |
+
if not ("," in location and location.replace(",", "").replace(".", "").isdigit()):
|
35 |
+
# 使用 GeoAPI 获取 LocationID
|
36 |
+
geo_url = f"https://geoapi.qweather.com/v2/city/lookup?location={location}&key={self.api_key}"
|
37 |
+
geo_response = requests.get(geo_url)
|
38 |
+
geo_data = geo_response.json()
|
39 |
+
|
40 |
+
if geo_data.get("code") != "200" or not geo_data.get("location"):
|
41 |
+
raise Exception(f"GeoAPI 返回错误码:{geo_data.get('code')} 或未找到位置")
|
42 |
+
|
43 |
+
location = geo_data["location"][0]["id"]
|
44 |
+
|
45 |
+
# 构建天气查询的 API 请求 URL
|
46 |
+
weather_url = f"https://devapi.qweather.com/v7/weather/now?location={location}&key={self.api_key}"
|
47 |
+
response = requests.get(weather_url)
|
48 |
+
data = response.json()
|
49 |
+
|
50 |
+
# 检查 API 响应码
|
51 |
+
if data.get("code") != "200":
|
52 |
+
raise Exception(f"Weather API 返回错误码:{data.get('code')}")
|
53 |
+
|
54 |
+
# 解析和组织天气信息
|
55 |
+
weather_info = {
|
56 |
+
"location": location,
|
57 |
+
"weather": data["now"]["text"],
|
58 |
+
"temperature": data["now"]["temp"] + "°C",
|
59 |
+
"wind_direction": data["now"]["windDir"],
|
60 |
+
"wind_speed": data["now"]["windSpeed"] + " km/h",
|
61 |
+
"humidity": data["now"]["humidity"] + "%",
|
62 |
+
"report_time": data["updateTime"]
|
63 |
+
}
|
64 |
+
|
65 |
+
return {"result": weather_info}
|
66 |
+
|
67 |
+
except Exception as exc:
|
68 |
+
return ActionReturn(
|
69 |
+
errmsg=f"WeatherQuery 异常:{exc}",
|
70 |
+
state=ActionStatusCode.HTTP_ERROR
|
71 |
+
)
|