diff --git a/libs/chatchat-server/chatchat/server/agent/tools_factory/weather_check.py b/libs/chatchat-server/chatchat/server/agent/tools_factory/weather_check.py index e2abc9d..510535a 100644 --- a/libs/chatchat-server/chatchat/server/agent/tools_factory/weather_check.py +++ b/libs/chatchat-server/chatchat/server/agent/tools_factory/weather_check.py @@ -12,14 +12,14 @@ from .tools_registry import BaseToolOutput, regist_tool @regist_tool(title="天气查询") def weather_check( - city: str = Field(description="City name,include city and county,like '厦门'"), + city: str = Field(description="城市名称,包括市和县,例如 '厦门'"), date: str = Field( default=None, description="日期参数,支持以下格式:\n" "- '今天':获取当前实时天气\n" "- '明天'/'后天':获取未来24/48小时预报\n" - "- '未来X天':获取最多X天预报(如'未来3天')\n" - "- 不支持其他参数,如果是其他参数,则时间参数为None" + "- '未来X天':获取最多X天预报(如'未来3天'),X的抽取要符合客户意图\n" + "- 不支持其他参数,如果是其他参数,则时间参数为None" ) ): """用这个工具获取指定地点和指定时间的天气""" @@ -39,86 +39,102 @@ def weather_check( print(f"city:{city}, date:{date}") try: - weatherType, number = parse_date_parameter(date) + weather_type, number = parse_date_parameter(date) except ValueError as e: - print(f"错误: {str(e)}") # 输出: 错误: 未来预报仅支持1-3天 + logging.error(f"日期参数解析失败: {str(e)}") return BaseToolOutput(str(e)) - print(f"weather_check tool内部调用,city{city},date:{date}") + # 获取API配置 tool_config = get_tool_config("weather_check") api_key = tool_config.get("api_key") - print(f"weatherType:{weatherType}, number:{number}") - url = '' - if weatherType == "daily": - url = f"http://api.seniverse.com/v3/weather/now.json?key={api_key}&location={city}&language=zh-Hans&unit=c" - logging.info(f"url:{url}") - response = requests.get(url) - if response.status_code == 200: - data = response.json() - logging.info(f"response.json():{data}") - weather = { - "temperature": data["results"][0]["now"]["temperature"], - "description": data["results"][0]["now"]["text"], - } - return BaseToolOutput(weather) - else: - logging.error(f"Failed to retrieve weather: {response.status_code}") - raise Exception(f"Failed to retrieve weather: {response.status_code}") - elif weatherType == "future": - url = f"http://api.seniverse.com/v3/weather/daily.json?key={api_key}&location={city}&language=zh-Hans&unit=c" - logging.info(f"url:{url}") - response = requests.get(url) - if response.status_code == 200: - data = response.json() - logging.info(f"response.json():{data}") - if number == 1: - weather = { - "date":"明天", - "low_temperature": data["results"][0]["daily"][1]["low"], - "high_temperature": data["results"][0]["daily"][1]["high"], - "description": data["results"][0]["daily"][1]["text_day"], - } - elif number == 2: - weather = { - "date":"后天", - "low_temperature": data["results"][0]["daily"][2]["low"], - "high_temperature": data["results"][0]["daily"][2]["high"], - "description": data["results"][0]["daily"][2]["text_day"], - } - elif number == 3: - weather = { - "今天天气": data["results"][0]["daily"][0]["text_day"], - "今天最低温度": data["results"][0]["daily"][0]["low"], - "今天最高温度": data["results"][0]["daily"][0]["high"], - "明天天气": data["results"][0]["daily"][1]["text_day"], - "明天最低温度": data["results"][0]["daily"][1]["low"], - "明天最高温度": data["results"][0]["daily"][1]["high"], - "后天天气": data["results"][0]["daily"][2]["text_day"], - "后天最低温度": data["results"][0]["daily"][2]["low"], - "后天最高温度": data["results"][0]["daily"][2]["high"], - } - return BaseToolOutput(weather) - else: - logging.error(f"Failed to retrieve weather: {response.status_code}") - raise Exception(f"Failed to retrieve weather: {response.status_code}") + if not api_key: + return BaseToolOutput("API密钥未配置,请联系管理员") + # 根据天气类型调用API + if weather_type == "daily": + return _get_current_weather(city, api_key) + elif weather_type == "future": + return _get_future_weather(city, api_key, number) + else: + return BaseToolOutput("不支持的天气类型") +def _get_current_weather(city: str, api_key: str) -> BaseToolOutput: + """获取当前实时天气""" + url = f"http://api.seniverse.com/v3/weather/now.json?key={api_key}&location={city}&language=zh-Hans&unit=c" + logging.info(f"请求URL: {url}") + response = requests.get(url) -def parse_date_parameter(date_str: str) -> tuple: - """解析日期参数返回API参数""" - # 处理自然语言 - if date_str in("今天", "今日"): - return "daily", 0 - elif date_str in("明天", "明日"): + if response.status_code != 200: + logging.error(f"天气查询失败: {response.status_code}") + return BaseToolOutput("天气查询API请求失败") + + data = response.json() + weather = { + "temperature": data["results"][0]["now"]["temperature"], + "description": data["results"][0]["now"]["text"], + } + return BaseToolOutput(weather) + +def _get_future_weather(city: str, api_key: str, days: int) -> BaseToolOutput: + """获取未来天气预报""" + url = f"http://api.seniverse.com/v3/weather/daily.json?key={api_key}&location={city}&language=zh-Hans&unit=c" + logging.info(f"请求URL: {url}") + response = requests.get(url) + + if response.status_code != 200: + logging.error(f"天气查询失败: {response.status_code}") + return BaseToolOutput("天气查询API请求失败") + + data = response.json() + daily_data = data["results"][0]["daily"] + + if days == 1: + weather = { + "date": "明天", + "low_temperature": daily_data[1]["low"], + "high_temperature": daily_data[1]["high"], + "description": daily_data[1]["text_day"], + } + elif days == 2: + weather = { + "date": "后天", + "low_temperature": daily_data[2]["low"], + "high_temperature": daily_data[2]["high"], + "description": daily_data[2]["text_day"], + } + elif days == 3: + weather = { + "今天天气": daily_data[0]["text_day"], + "今天最低温度": daily_data[0]["low"], + "今天最高温度": daily_data[0]["high"], + "明天天气": daily_data[1]["text_day"], + "明天最低温度": daily_data[1]["low"], + "明天最高温度": daily_data[1]["high"], + "后天天气": daily_data[2]["text_day"], + "后天最低温度": daily_data[2]["low"], + "后天最高温度": daily_data[2]["high"], + } + else: + return BaseToolOutput("不支持的天数参数") + + return BaseToolOutput(weather) + +def parse_date_parameter(date: str) -> tuple: + """解析日期参数,返回天气类型和天数""" + if date == "今天": + return "daily", 1 + elif date == "明天": return "future", 1 - elif date_str == "后天": + elif date == "后天": return "future", 2 - elif date_str.startswith("未来"): - days = int(date_str[2:-1]) - if days < 1 or days > 3: + elif date.startswith("未来") and date.endswith("天"): + days = int(date[2:-1]) + if 1 <= days <= 3: + return "future", days + else: raise ValueError("未来预报仅支持1-3天") - return "future", days - + else: + raise ValueError("不支持的日期参数") if __name__ == "__main__": weather_check("合肥","明天") \ No newline at end of file