Aakash010 commited on
Commit
867e0ab
·
verified ·
1 Parent(s): 328b056

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -34
app.py CHANGED
@@ -3,38 +3,74 @@ import time
3
  import gradio as gr
4
  import requests
5
  import pandas as pd
6
- from smolagents import ToolCallingAgent, OpenAIServerModel, DuckDuckGoSearchTool, PythonInterpreterTool, Tool
7
 
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
  # --- Custom Tools ---
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  class WikipediaTool(Tool):
14
  name = "wikipedia_search"
15
- description = "Search Wikipedia and get article text. Use this when the question mentions Wikipedia or needs encyclopedic facts."
16
- inputs = {"query": {"type": "string", "description": "The topic to search on Wikipedia"}}
17
  output_type = "string"
18
 
19
  def forward(self, query: str) -> str:
20
  try:
 
21
  search_url = (
22
- f"https://en.wikipedia.org/w/api.php"
23
- f"?action=query&titles={query.replace(' ', '_')}"
24
- f"&prop=extracts&explaintext=true&format=json"
25
  )
26
  r = requests.get(search_url, timeout=10)
27
- pages = r.json()["query"]["pages"]
 
 
 
 
 
 
 
 
 
 
 
 
28
  page = next(iter(pages.values()))
29
  text = page.get("extract", "No content found")
30
- return text[:4000]
31
  except Exception as e:
32
  return f"Wikipedia error: {e}"
33
 
34
 
35
  class YouTubeTranscriptTool(Tool):
36
  name = "youtube_transcript"
37
- description = "Gets the transcript of a YouTube video. Use when the question contains a YouTube URL or asks about video content."
38
  inputs = {"url": {"type": "string", "description": "YouTube video URL or video ID"}}
39
  output_type = "string"
40
 
@@ -48,7 +84,7 @@ class YouTubeTranscriptTool(Tool):
48
  else:
49
  video_id = url.strip()
50
  transcript = YouTubeTranscriptApi.get_transcript(video_id)
51
- return " ".join([t["text"] for t in transcript])[:4000]
52
  except Exception as e:
53
  return f"Transcript error: {e}"
54
 
@@ -64,12 +100,31 @@ class FileDownloadTool(Tool):
64
  url = f"https://agents-course-unit4-scoring.hf.space/files/{task_id}"
65
  r = requests.get(url, timeout=15)
66
  if r.status_code == 200:
67
- return r.text[:4000]
68
  return f"No file found for task_id {task_id}"
69
  except Exception as e:
70
  return f"File download error: {e}"
71
 
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  # --- Agent ---
74
 
75
  class BasicAgent:
@@ -82,23 +137,27 @@ class BasicAgent:
82
  self.agent = ToolCallingAgent(
83
  model=model,
84
  tools=[
85
- DuckDuckGoSearchTool(),
86
- PythonInterpreterTool(),
87
  WikipediaTool(),
88
  YouTubeTranscriptTool(),
89
  FileDownloadTool(),
 
 
90
  ],
91
- max_steps=4,
92
  )
93
 
94
  def __call__(self, question: str, task_id: str = "") -> str:
95
  try:
96
  prompt = f"""Answer the following question accurately.
97
- Return ONLY the final answer no explanation, no punctuation, no extra words.
98
- If the answer is a number, return just the number.
99
- If the answer is a name, return just the name.
100
- If the answer is a list, return comma separated values.
101
- Task ID (use this with download_file tool if the question references a file): {task_id}
 
 
 
102
 
103
  Question: {question}"""
104
  result = self.agent.run(prompt)
@@ -117,24 +176,20 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
117
  username = f"{profile.username}"
118
  print(f"User logged in: {username}")
119
  else:
120
- print("User not logged in.")
121
  return "Please Login to Hugging Face with the button.", None
122
 
123
  api_url = DEFAULT_API_URL
124
  questions_url = f"{api_url}/questions"
125
  submit_url = f"{api_url}/submit"
126
 
127
- # 1. Instantiate Agent
128
  try:
129
  agent = BasicAgent()
130
  except Exception as e:
131
- print(f"Error instantiating agent: {e}")
132
  return f"Error initializing agent: {e}", None
133
 
134
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
135
  print(agent_code)
136
 
137
- # 2. Fetch Questions
138
  print(f"Fetching questions from: {questions_url}")
139
  try:
140
  response = requests.get(questions_url, timeout=15)
@@ -146,7 +201,6 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
146
  except Exception as e:
147
  return f"Error fetching questions: {e}", None
148
 
149
- # 3. Run Agent on each question
150
  results_log = []
151
  answers_payload = []
152
  print(f"Running agent on {len(questions_data)} questions...")
@@ -160,7 +214,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
160
  continue
161
 
162
  print(f"\n[{i+1}/{len(questions_data)}] Task: {task_id}")
163
- print(f"Question: {question_text[:100]}...")
164
 
165
  try:
166
  submitted_answer = agent(question_text, task_id)
@@ -171,15 +225,13 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
171
  print(f"Error on task {task_id}: {e}")
172
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
173
 
174
- # Rate limit protection — Groq free tier is 6000 tokens/min
175
  if i < len(questions_data) - 1:
176
- print("Waiting 12s to respect rate limits...")
177
- time.sleep(12)
178
 
179
  if not answers_payload:
180
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
181
 
182
- # 4. Submit
183
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
184
  print(f"\nSubmitting {len(answers_payload)} answers...")
185
 
@@ -217,7 +269,7 @@ with gr.Blocks() as demo:
217
  **Instructions:**
218
  1. Log in to your Hugging Face account using the button below.
219
  2. Click 'Run Evaluation & Submit All Answers' to start.
220
- 3. The agent will answer all 20 questions and submit. Takes ~5 minutes due to rate limits.
221
  """
222
  )
223
 
@@ -233,20 +285,16 @@ with gr.Blocks() as demo:
233
 
234
  if __name__ == "__main__":
235
  print("\n" + "-"*30 + " App Starting " + "-"*30)
236
-
237
  space_host_startup = os.getenv("SPACE_HOST")
238
  space_id_startup = os.getenv("SPACE_ID")
239
-
240
  if space_host_startup:
241
  print(f"✅ SPACE_HOST found: {space_host_startup}")
242
  else:
243
  print("ℹ️ SPACE_HOST not found (running locally).")
244
-
245
  if space_id_startup:
246
  print(f"✅ SPACE_ID found: {space_id_startup}")
247
  else:
248
  print("ℹ️ SPACE_ID not found (running locally).")
249
-
250
  print("-"*(60 + len(" App Starting ")) + "\n")
251
  print("Launching Gradio Interface...")
252
  demo.launch(debug=True, share=False)
 
3
  import gradio as gr
4
  import requests
5
  import pandas as pd
6
+ from smolagents import ToolCallingAgent, OpenAIServerModel, PythonInterpreterTool, Tool
7
 
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
  # --- Custom Tools ---
12
 
13
+ class WebSearchTool(Tool):
14
+ name = "web_search"
15
+ description = "Search the web for information. Use for any factual question."
16
+ inputs = {"query": {"type": "string", "description": "The search query"}}
17
+ output_type = "string"
18
+
19
+ def forward(self, query: str) -> str:
20
+ try:
21
+ from ddgs import DDGS
22
+ with DDGS() as ddgs:
23
+ results = list(ddgs.text(query, max_results=5))
24
+ if not results:
25
+ return "No results found."
26
+ output = ""
27
+ for r in results:
28
+ output += f"Title: {r.get('title', '')}\n"
29
+ output += f"URL: {r.get('href', '')}\n"
30
+ output += f"Summary: {r.get('body', '')}\n\n"
31
+ return output[:3000]
32
+ except Exception as e:
33
+ return f"Search error: {e}"
34
+
35
+
36
  class WikipediaTool(Tool):
37
  name = "wikipedia_search"
38
+ description = "Search Wikipedia directly. Use when the question mentions Wikipedia or needs encyclopedic facts like discographies, biographies, lists."
39
+ inputs = {"query": {"type": "string", "description": "The Wikipedia article title or topic to search"}}
40
  output_type = "string"
41
 
42
  def forward(self, query: str) -> str:
43
  try:
44
+ # First search for the right article
45
  search_url = (
46
+ "https://en.wikipedia.org/w/api.php"
47
+ f"?action=query&list=search&srsearch={requests.utils.quote(query)}"
48
+ "&format=json&srlimit=1"
49
  )
50
  r = requests.get(search_url, timeout=10)
51
+ results = r.json()["query"]["search"]
52
+ if not results:
53
+ return "No Wikipedia article found."
54
+ title = results[0]["title"]
55
+
56
+ # Then fetch full article text
57
+ content_url = (
58
+ "https://en.wikipedia.org/w/api.php"
59
+ f"?action=query&titles={requests.utils.quote(title)}"
60
+ "&prop=extracts&explaintext=true&format=json"
61
+ )
62
+ r2 = requests.get(content_url, timeout=10)
63
+ pages = r2.json()["query"]["pages"]
64
  page = next(iter(pages.values()))
65
  text = page.get("extract", "No content found")
66
+ return f"Article: {title}\n\n{text[:5000]}"
67
  except Exception as e:
68
  return f"Wikipedia error: {e}"
69
 
70
 
71
  class YouTubeTranscriptTool(Tool):
72
  name = "youtube_transcript"
73
+ description = "Gets the transcript/captions of a YouTube video. Use when the question contains a YouTube URL."
74
  inputs = {"url": {"type": "string", "description": "YouTube video URL or video ID"}}
75
  output_type = "string"
76
 
 
84
  else:
85
  video_id = url.strip()
86
  transcript = YouTubeTranscriptApi.get_transcript(video_id)
87
+ return " ".join([t["text"] for t in transcript])[:5000]
88
  except Exception as e:
89
  return f"Transcript error: {e}"
90
 
 
100
  url = f"https://agents-course-unit4-scoring.hf.space/files/{task_id}"
101
  r = requests.get(url, timeout=15)
102
  if r.status_code == 200:
103
+ return r.text[:5000]
104
  return f"No file found for task_id {task_id}"
105
  except Exception as e:
106
  return f"File download error: {e}"
107
 
108
 
109
+ class VisitWebpageTool(Tool):
110
+ name = "visit_webpage"
111
+ description = "Fetches the full content of a webpage given its URL. Use when you have a specific URL to read."
112
+ inputs = {"url": {"type": "string", "description": "The URL of the webpage to visit"}}
113
+ output_type = "string"
114
+
115
+ def forward(self, url: str) -> str:
116
+ try:
117
+ headers = {"User-Agent": "Mozilla/5.0"}
118
+ r = requests.get(url, timeout=10, headers=headers)
119
+ # strip html tags roughly
120
+ import re
121
+ text = re.sub(r'<[^>]+>', ' ', r.text)
122
+ text = re.sub(r'\s+', ' ', text).strip()
123
+ return text[:5000]
124
+ except Exception as e:
125
+ return f"Webpage error: {e}"
126
+
127
+
128
  # --- Agent ---
129
 
130
  class BasicAgent:
 
137
  self.agent = ToolCallingAgent(
138
  model=model,
139
  tools=[
140
+ WebSearchTool(),
 
141
  WikipediaTool(),
142
  YouTubeTranscriptTool(),
143
  FileDownloadTool(),
144
+ VisitWebpageTool(),
145
+ PythonInterpreterTool(),
146
  ],
147
+ max_steps=5,
148
  )
149
 
150
  def __call__(self, question: str, task_id: str = "") -> str:
151
  try:
152
  prompt = f"""Answer the following question accurately.
153
+ Return ONLY the final answer with no explanation, no punctuation, no extra words.
154
+ - If the answer is a number, return just the number.
155
+ - If the answer is a name, return just the name.
156
+ - If the answer is a list, return comma separated values in alphabetical order.
157
+ - If the question asks about a YouTube video, use the youtube_transcript tool.
158
+ - If the question mentions Wikipedia, use the wikipedia_search tool.
159
+ - If the question references an attached file, use download_file with the task_id below.
160
+ Task ID: {task_id}
161
 
162
  Question: {question}"""
163
  result = self.agent.run(prompt)
 
176
  username = f"{profile.username}"
177
  print(f"User logged in: {username}")
178
  else:
 
179
  return "Please Login to Hugging Face with the button.", None
180
 
181
  api_url = DEFAULT_API_URL
182
  questions_url = f"{api_url}/questions"
183
  submit_url = f"{api_url}/submit"
184
 
 
185
  try:
186
  agent = BasicAgent()
187
  except Exception as e:
 
188
  return f"Error initializing agent: {e}", None
189
 
190
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
191
  print(agent_code)
192
 
 
193
  print(f"Fetching questions from: {questions_url}")
194
  try:
195
  response = requests.get(questions_url, timeout=15)
 
201
  except Exception as e:
202
  return f"Error fetching questions: {e}", None
203
 
 
204
  results_log = []
205
  answers_payload = []
206
  print(f"Running agent on {len(questions_data)} questions...")
 
214
  continue
215
 
216
  print(f"\n[{i+1}/{len(questions_data)}] Task: {task_id}")
217
+ print(f"Question: {question_text[:120]}...")
218
 
219
  try:
220
  submitted_answer = agent(question_text, task_id)
 
225
  print(f"Error on task {task_id}: {e}")
226
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
227
 
 
228
  if i < len(questions_data) - 1:
229
+ print("Waiting 15s for rate limits...")
230
+ time.sleep(15)
231
 
232
  if not answers_payload:
233
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
234
 
 
235
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
236
  print(f"\nSubmitting {len(answers_payload)} answers...")
237
 
 
269
  **Instructions:**
270
  1. Log in to your Hugging Face account using the button below.
271
  2. Click 'Run Evaluation & Submit All Answers' to start.
272
+ 3. Takes ~6 minutes for all 20 questions due to rate limits.
273
  """
274
  )
275
 
 
285
 
286
  if __name__ == "__main__":
287
  print("\n" + "-"*30 + " App Starting " + "-"*30)
 
288
  space_host_startup = os.getenv("SPACE_HOST")
289
  space_id_startup = os.getenv("SPACE_ID")
 
290
  if space_host_startup:
291
  print(f"✅ SPACE_HOST found: {space_host_startup}")
292
  else:
293
  print("ℹ️ SPACE_HOST not found (running locally).")
 
294
  if space_id_startup:
295
  print(f"✅ SPACE_ID found: {space_id_startup}")
296
  else:
297
  print("ℹ️ SPACE_ID not found (running locally).")
 
298
  print("-"*(60 + len(" App Starting ")) + "\n")
299
  print("Launching Gradio Interface...")
300
  demo.launch(debug=True, share=False)