baibianxiaomage commited on
Commit
6522974
·
verified ·
1 Parent(s): 46e5e42

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +132 -52
app.py CHANGED
@@ -1,32 +1,76 @@
1
- from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
2
  import datetime
3
  import requests
4
  import pytz
5
  import yaml
6
- from tools.final_answer import FinalAnswerTool
7
 
 
 
8
  from Gradio_UI import GradioUI
9
 
10
- # Below is an example of a tool that does nothing. Amaze us with your creativity !
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  @tool
12
  def get_weather(location: str) -> str:
13
- """Get the current weather for a specified location.
 
14
  Args:
15
- location: A city, region, or country name, such as 'Beijing', 'Tokyo', or 'New York'.
16
  """
17
  try:
18
- url = f"https://wttr.in/{location}?format=j1"
19
- response = requests.get(url, timeout=10)
20
- response.raise_for_status()
21
- data = response.json()
 
22
 
23
- current = data["current_condition"][0]
 
 
24
 
 
25
  temp_c = current.get("temp_C", "Unknown")
26
  feels_like_c = current.get("FeelsLikeC", "Unknown")
27
  humidity = current.get("humidity", "Unknown")
28
- weather_desc = current.get("weatherDesc", [{}])[0].get("value", "Unknown")
29
  wind_kph = current.get("windspeedKmph", "Unknown")
 
 
 
 
 
 
 
 
30
 
31
  return (
32
  f"Current weather in {location}:\n"
@@ -34,7 +78,8 @@ def get_weather(location: str) -> str:
34
  f"- Temperature: {temp_c}°C\n"
35
  f"- Feels like: {feels_like_c}°C\n"
36
  f"- Humidity: {humidity}%\n"
37
- f"- Wind speed: {wind_kph} km/h"
 
38
  )
39
  except Exception as e:
40
  return f"Error fetching weather for '{location}': {str(e)}"
@@ -43,38 +88,48 @@ def get_weather(location: str) -> str:
43
  @tool
44
  def get_nba_games(date: str) -> str:
45
  """Get NBA game results for a specific date.
 
46
  Args:
47
  date: A date in YYYY-MM-DD format, for example '2026-03-08'.
48
  """
 
 
 
 
 
 
 
49
  try:
50
- url = "https://www.balldontlie.io/api/v1/games"
 
 
51
  params = {
52
  "dates[]": date,
53
- "per_page": 100
54
  }
55
 
56
- response = requests.get(url, params=params, timeout=10)
57
- response.raise_for_status()
58
- data = response.json()
59
-
60
  games = data.get("data", [])
61
  if not games:
62
  return f"No NBA games found for {date}."
63
 
64
  results = [f"NBA games on {date}:"]
65
  for game in games:
66
- home_team = game["home_team"]["full_name"]
67
- visitor_team = game["visitor_team"]["full_name"]
68
  home_score = game.get("home_team_score", 0)
69
  visitor_score = game.get("visitor_team_score", 0)
70
  status = game.get("status", "Unknown")
71
 
72
- if home_score > visitor_score:
73
- winner = home_team
74
- elif visitor_score > home_score:
75
- winner = visitor_team
 
 
 
76
  else:
77
- winner = "Tie / Not finished"
78
 
79
  results.append(
80
  f"- {visitor_team} {visitor_score} : {home_score} {home_team} "
@@ -82,58 +137,83 @@ def get_nba_games(date: str) -> str:
82
  )
83
 
84
  return "\n".join(results)
85
-
86
  except Exception as e:
87
  return f"Error fetching NBA games for '{date}': {str(e)}"
88
 
 
89
  @tool
90
  def get_current_time_in_timezone(timezone: str) -> str:
91
- """A tool that fetches the current local time in a specified timezone.
 
92
  Args:
93
- timezone: A string representing a valid timezone (e.g., 'America/New_York').
94
  """
95
  try:
96
- # Create timezone object
97
  tz = pytz.timezone(timezone)
98
- # Get current time in that timezone
99
  local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
100
  return f"The current local time in {timezone} is: {local_time}"
101
  except Exception as e:
102
  return f"Error fetching time for timezone '{timezone}': {str(e)}"
103
 
104
 
 
 
 
105
  final_answer = FinalAnswerTool()
106
 
107
- # 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:
108
- # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
109
 
 
 
 
110
  model = HfApiModel(
111
- max_tokens=2096,
112
- temperature=0.5,
113
- model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may be overloaded
114
- custom_role_conversions=None,
115
  )
116
 
117
- # Search tool
118
- search_tool = DuckDuckGoSearchTool()
119
-
120
- # Import tool from Hub
121
- image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
122
 
123
- with open("prompts.yaml", 'r') as stream:
124
- prompt_templates = yaml.safe_load(stream)
125
-
126
- agent = CodeAgent(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  model=model,
128
- tools=[final_answer, get_nba_games, get_weather, get_current_time_in_timezone, search_tool, image_generation_tool],
129
- max_steps=6,
130
- verbosity_level=1,
131
- grammar=None,
132
- planning_interval=None,
 
 
133
  name="Chen_Qiang",
134
- description=None,
135
- prompt_templates=prompt_templates
136
  )
137
 
138
 
 
 
 
139
  GradioUI(agent).launch()
 
1
+ import os
2
  import datetime
3
  import requests
4
  import pytz
5
  import yaml
 
6
 
7
+ from smolagents import ToolCallingAgent, HfApiModel, tool
8
+ from tools.final_answer import FinalAnswerTool
9
  from Gradio_UI import GradioUI
10
 
11
+
12
+ # -----------------------------
13
+ # Utilities
14
+ # -----------------------------
15
+ DEFAULT_TIMEOUT = 20
16
+
17
+
18
+ def safe_request_json(url: str, *, params=None, headers=None, timeout=DEFAULT_TIMEOUT):
19
+ """Send a GET request and return JSON data with clearer error messages."""
20
+ try:
21
+ response = requests.get(url, params=params, headers=headers, timeout=timeout)
22
+ response.raise_for_status()
23
+ return response.json()
24
+ except requests.exceptions.Timeout:
25
+ raise RuntimeError("The request timed out. Please try again later.")
26
+ except requests.exceptions.HTTPError as e:
27
+ status_code = getattr(e.response, "status_code", "unknown")
28
+ body = ""
29
+ try:
30
+ body = e.response.text[:300]
31
+ except Exception:
32
+ pass
33
+ raise RuntimeError(f"HTTP {status_code} error. {body}")
34
+ except requests.exceptions.RequestException as e:
35
+ raise RuntimeError(f"Network request failed: {str(e)}")
36
+ except ValueError:
37
+ raise RuntimeError("The server returned invalid JSON data.")
38
+
39
+
40
+ # -----------------------------
41
+ # Tools
42
+ # -----------------------------
43
  @tool
44
  def get_weather(location: str) -> str:
45
+ """Get the current weather for a specified city or region.
46
+ Use this tool whenever the user asks about weather, temperature, humidity, wind, or forecast.
47
  Args:
48
+ location: A city, region, or country name, such as Beijing, Tokyo, Shanghai, or New York.
49
  """
50
  try:
51
+ # wttr.in is convenient for demos, but can occasionally be slow in cloud environments.
52
+ # We keep a slightly longer timeout and return clear errors.
53
+ url = f"https://wttr.in/{location}"
54
+ params = {"format": "j1"}
55
+ data = safe_request_json(url, params=params, timeout=20)
56
 
57
+ current_list = data.get("current_condition", [])
58
+ if not current_list:
59
+ return f"Could not find weather data for '{location}'."
60
 
61
+ current = current_list[0]
62
  temp_c = current.get("temp_C", "Unknown")
63
  feels_like_c = current.get("FeelsLikeC", "Unknown")
64
  humidity = current.get("humidity", "Unknown")
 
65
  wind_kph = current.get("windspeedKmph", "Unknown")
66
+ weather_desc = current.get("weatherDesc", [{}])[0].get("value", "Unknown")
67
+
68
+ # Try to include today's high/low if available
69
+ weather_days = data.get("weather", [])
70
+ high_c = low_c = "Unknown"
71
+ if weather_days:
72
+ high_c = weather_days[0].get("maxtempC", "Unknown")
73
+ low_c = weather_days[0].get("mintempC", "Unknown")
74
 
75
  return (
76
  f"Current weather in {location}:\n"
 
78
  f"- Temperature: {temp_c}°C\n"
79
  f"- Feels like: {feels_like_c}°C\n"
80
  f"- Humidity: {humidity}%\n"
81
+ f"- Wind speed: {wind_kph} km/h\n"
82
+ f"- Today's high / low: {high_c}°C / {low_c}°C"
83
  )
84
  except Exception as e:
85
  return f"Error fetching weather for '{location}': {str(e)}"
 
88
  @tool
89
  def get_nba_games(date: str) -> str:
90
  """Get NBA game results for a specific date.
91
+ Use this tool whenever the user asks for NBA games, scores, or results on a given date.
92
  Args:
93
  date: A date in YYYY-MM-DD format, for example '2026-03-08'.
94
  """
95
+ api_key = os.getenv("BALLDONTLIE_API_KEY")
96
+ if not api_key:
97
+ return (
98
+ "BALLDONTLIE_API_KEY is not set. Please add your BALLDONTLIE API key "
99
+ "as an environment variable or Hugging Face Secret."
100
+ )
101
+
102
  try:
103
+ # Official authenticated endpoint style
104
+ url = "https://api.balldontlie.io/nba/v1/games"
105
+ headers = {"Authorization": api_key}
106
  params = {
107
  "dates[]": date,
108
+ "per_page": 100,
109
  }
110
 
111
+ data = safe_request_json(url, params=params, headers=headers, timeout=20)
 
 
 
112
  games = data.get("data", [])
113
  if not games:
114
  return f"No NBA games found for {date}."
115
 
116
  results = [f"NBA games on {date}:"]
117
  for game in games:
118
+ home_team = game.get("home_team", {}).get("full_name", "Unknown Home Team")
119
+ visitor_team = game.get("visitor_team", {}).get("full_name", "Unknown Visitor Team")
120
  home_score = game.get("home_team_score", 0)
121
  visitor_score = game.get("visitor_team_score", 0)
122
  status = game.get("status", "Unknown")
123
 
124
+ if isinstance(home_score, int) and isinstance(visitor_score, int):
125
+ if home_score > visitor_score:
126
+ winner = home_team
127
+ elif visitor_score > home_score:
128
+ winner = visitor_team
129
+ else:
130
+ winner = "Tie / Not finished"
131
  else:
132
+ winner = "Unknown"
133
 
134
  results.append(
135
  f"- {visitor_team} {visitor_score} : {home_score} {home_team} "
 
137
  )
138
 
139
  return "\n".join(results)
 
140
  except Exception as e:
141
  return f"Error fetching NBA games for '{date}': {str(e)}"
142
 
143
+
144
  @tool
145
  def get_current_time_in_timezone(timezone: str) -> str:
146
+ """Get the current local time in a specified timezone.
147
+ Use this tool whenever the user asks for the current time in a city or timezone.
148
  Args:
149
+ timezone: A valid timezone string, such as 'Asia/Shanghai' or 'America/New_York'.
150
  """
151
  try:
 
152
  tz = pytz.timezone(timezone)
 
153
  local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
154
  return f"The current local time in {timezone} is: {local_time}"
155
  except Exception as e:
156
  return f"Error fetching time for timezone '{timezone}': {str(e)}"
157
 
158
 
159
+ # -----------------------------
160
+ # Final answer tool
161
+ # -----------------------------
162
  final_answer = FinalAnswerTool()
163
 
 
 
164
 
165
+ # -----------------------------
166
+ # Model
167
+ # -----------------------------
168
  model = HfApiModel(
169
+ max_tokens=2048,
170
+ temperature=0.2,
171
+ model_id="Qwen/Qwen2.5-Coder-32B-Instruct",
172
+ custom_role_conversions=None,
173
  )
174
 
 
 
 
 
 
175
 
176
+ # -----------------------------
177
+ # Prompt templates
178
+ # -----------------------------
179
+ fallback_prompt_templates = {
180
+ "system_prompt": (
181
+ "You are a helpful assistant.\n"
182
+ "Rules:\n"
183
+ "1. If the user asks about weather, use the get_weather tool.\n"
184
+ "2. If the user asks about NBA games or scores, use the get_nba_games tool.\n"
185
+ "3. If the user asks about current time in a timezone, use the get_current_time_in_timezone tool.\n"
186
+ "4. Do not invent tools or functions that are not provided.\n"
187
+ "5. If a tool returns an error, explain the error clearly.\n"
188
+ )
189
+ }
190
+
191
+ if os.path.exists("prompts.yaml"):
192
+ with open("prompts.yaml", "r", encoding="utf-8") as stream:
193
+ prompt_templates = yaml.safe_load(stream)
194
+ else:
195
+ prompt_templates = fallback_prompt_templates
196
+
197
+
198
+ # -----------------------------
199
+ # Agent
200
+ # -----------------------------
201
+ agent = ToolCallingAgent(
202
  model=model,
203
+ tools=[
204
+ final_answer,
205
+ get_weather,
206
+ get_nba_games,
207
+ get_current_time_in_timezone,
208
+ ],
209
+ max_steps=4,
210
  name="Chen_Qiang",
211
+ description="An agent for weather, NBA results, and timezone queries.",
212
+ prompt_templates=prompt_templates,
213
  )
214
 
215
 
216
+ # -----------------------------
217
+ # Launch UI
218
+ # -----------------------------
219
  GradioUI(agent).launch()