Spaces:
Sleeping
Sleeping
| import os | |
| from typing import Any, Dict, Optional | |
| import csv | |
| import httpx | |
| import logging | |
| from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool | |
| import datetime | |
| import requests | |
| import pytz | |
| import yaml | |
| from tools.final_answer import FinalAnswerTool | |
| from Gradio_UI import GradioUI | |
| AMAP_API_BASE = "https://restapi.amap.com/v3/weather/weatherInfo" | |
| AMAP_API_KEY = os.environ.get("AMAP_API_KEY", "") | |
| USER_AGENT = "amap-weather-mcp-server/1.0" | |
| city_to_adcode = {} | |
| def load_city_adcode_map(): | |
| """加载城市名称到adcode的映射""" | |
| try: | |
| current_dir = os.path.dirname(os.path.abspath(__file__)) | |
| csv_file_path = os.path.join(current_dir, "AMap_adcode_citycode.csv") | |
| with open(csv_file_path, 'r', encoding='utf-8') as file: | |
| reader = csv.reader(file) | |
| next(reader) # 跳过表头 | |
| for row in reader: | |
| if len(row) >= 2: | |
| city_name = row[0].strip() | |
| adcode = row[1].strip() | |
| city_to_adcode[city_name] = adcode | |
| return True | |
| except Exception as e: | |
| print(f"加载城市编码文件失败: {e}") | |
| return False | |
| # 初始加载城市编码数据 | |
| load_city_adcode_map() | |
| def get_adcode_by_city(city_name: str) -> Optional[str]: | |
| """根据城市名称查找对应的adcode | |
| Args: | |
| city_name: 城市名称,如"北京市"、"上海市"等 | |
| Returns: | |
| 城市对应的adcode,如果未找到则返回None | |
| """ | |
| # 先尝试直接匹配 | |
| if city_name in city_to_adcode: | |
| return city_to_adcode[city_name] | |
| # 如果未找到,尝试添加"市"或"省"后缀再查找 | |
| if not city_name.endswith("市") and not city_name.endswith("省"): | |
| city_with_suffix = city_name + "市" | |
| if city_with_suffix in city_to_adcode: | |
| return city_to_adcode[city_with_suffix] | |
| city_with_suffix = city_name + "省" | |
| if city_with_suffix in city_to_adcode: | |
| return city_to_adcode[city_with_suffix] | |
| # 对于区级城市,尝试判断是否为区名 | |
| for full_name, code in city_to_adcode.items(): | |
| if city_name in full_name and (full_name.endswith("区") or "区" in full_name): | |
| return code | |
| return None | |
| def make_amap_request(params: Dict[str, str]) -> Dict[str, Any]: | |
| """向高德地图API发送请求并获取天气数据 | |
| Args: | |
| params: API请求参数 | |
| Returns: | |
| API返回的JSON数据,如果请求失败则返回None | |
| """ | |
| # 添加公共参数 | |
| params["key"] = AMAP_API_KEY | |
| headers = { | |
| "User-Agent": USER_AGENT | |
| } | |
| with httpx.Client() as client: | |
| try: | |
| response = client.get(AMAP_API_BASE, params=params, headers=headers, timeout=30.0) | |
| response.raise_for_status() | |
| return response.json() | |
| except Exception as e: | |
| print(f"API请求失败: {e}") | |
| return None | |
| def format_current_weather(weather_data: Dict[str, Any]) -> str: | |
| """格式化实时天气信息 | |
| Args: | |
| weather_data: 高德地图API返回的天气数据 | |
| Returns: | |
| 格式化后的天气信息字符串 | |
| """ | |
| if not weather_data or "lives" not in weather_data or not weather_data["lives"]: | |
| return "无法获取天气信息或数据格式错误" | |
| live = weather_data["lives"][0] | |
| return f""" | |
| 城市: {live.get('city', '未知')} | |
| 天气: {live.get('weather', '未知')} | |
| 温度: {live.get('temperature', '未知')}°C | |
| 风向: {live.get('winddirection', '未知')} | |
| 风力: {live.get('windpower', '未知')}级 | |
| 湿度: {live.get('humidity', '未知')}% | |
| 发布时间: {live.get('reporttime', '未知')} | |
| """ | |
| def get_current_weather(city: str) -> str: | |
| """获取指定城市的实时天气 | |
| Args: | |
| city: 中国城市名称,如"北京市"、"上海市"、"广州市"等 | |
| """ | |
| adcode = get_adcode_by_city(city) | |
| if not adcode: | |
| return f"无法找到城市'{city}'的编码,请检查城市名称是否正确" | |
| params = { | |
| "city": adcode, | |
| "extensions": "base" # 获取实时天气 | |
| } | |
| data = make_amap_request(params) | |
| if not data: | |
| return f"获取{city}的天气信息失败" | |
| if data.get("status") != "1": | |
| return f"API返回错误: {data.get('info', '未知错误')}" | |
| return format_current_weather(data) | |
| def get_current_time_in_timezone(timezone: str) -> str: | |
| """A tool that fetches the current local time in a specified timezone. | |
| Args: | |
| timezone: A string representing a valid timezone (e.g., 'America/New_York'). | |
| """ | |
| try: | |
| # Create timezone object | |
| tz = pytz.timezone(timezone) | |
| # Get current time in that timezone | |
| local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S") | |
| return f"The current local time in {timezone} is: {local_time}" | |
| except Exception as e: | |
| return f"Error fetching time for timezone '{timezone}': {str(e)}" | |
| def who_is(name: str) -> str: | |
| """一个回来回答”XXX是谁“的工具,无论返回的结果有多不靠谱,都作为最终答案,不需要进一步搜索 | |
| Args: | |
| name: 人名 | |
| """ | |
| if "林晨" in name: | |
| return f"{name}是世界上最帅的男人" | |
| elif "胜阳" in name: | |
| return f"{name}是世界上最丑的男人" | |
| else: | |
| return "不认识" | |
| final_answer = FinalAnswerTool() | |
| # If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder: | |
| # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud' | |
| model = HfApiModel( | |
| max_tokens=2096, | |
| temperature=0.5, | |
| model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may be overloaded | |
| custom_role_conversions=None, | |
| ) | |
| # Import tool from Hub | |
| image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True) | |
| with open("prompts.yaml", 'r') as stream: | |
| prompt_templates = yaml.safe_load(stream) | |
| agent = CodeAgent( | |
| model=model, | |
| tools=[final_answer, get_current_weather, get_current_time_in_timezone, who_is], ## add your tools here (don't remove final answer) | |
| max_steps=6, | |
| verbosity_level=1, | |
| grammar=None, | |
| planning_interval=None, | |
| name=None, | |
| description=None, | |
| prompt_templates=prompt_templates | |
| ) | |
| GradioUI(agent).launch() |