Snaseem2026 commited on
Commit
a12043d
Β·
verified Β·
1 Parent(s): 64d5cdc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +213 -158
app.py CHANGED
@@ -2,138 +2,152 @@ import os
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
 
5
 
6
  # --- Constants ---
7
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
8
 
9
- # --- Intelligent Agent with Web Search ---
10
- class IntelligentAgent:
11
  def __init__(self):
12
- print("Initializing IntelligentAgent...")
13
- self.search_tool = self._create_search_function()
14
 
15
- def _create_search_function(self):
16
- """Create a simple DuckDuckGo search function"""
 
 
 
 
 
 
 
 
 
 
 
17
  try:
18
  from duckduckgo_search import DDGS
19
- return DDGS()
20
- except:
21
- return None
 
 
22
 
23
- def search_web(self, query: str, max_results: int = 5) -> str:
24
- """Search the web using DuckDuckGo"""
25
- if self.search_tool is None:
26
- return "Search unavailable"
27
 
28
- try:
29
- results = list(self.search_tool. text(query, max_results=max_results))
30
- if not results:
31
- return "No results found"
32
 
33
- # Format results
34
  formatted = []
35
- for i, r in enumerate(results[: max_results], 1):
36
- formatted.append(f"{i}. {r. get('title', 'N/A')}: {r.get('body', 'N/A')}")
 
 
 
37
 
38
- return "\n\n".join(formatted)
39
  except Exception as e:
40
  print(f"Search error: {e}")
41
- return "Search failed"
42
-
43
- def __call__(self, question: str) -> str:
44
- print(f"Processing question: {question[:100]}...")
45
-
46
- # For questions that likely need web search
47
- if any(keyword in question.lower() for keyword in ['current', 'latest', 'recent', 'today', 'now', '2024', '2025', '2026']):
48
- print("Searching web for current information...")
49
- search_results = self.search_web(question, max_results=3)
50
-
51
- # Try to extract relevant answer from search results
52
- if search_results and search_results != "No results found":
53
- # Return first meaningful snippet
54
- lines = search_results.split('\n')
55
- for line in lines:
56
- if len(line) > 20:
57
- return line[:500]
58
-
59
- # Basic knowledge-based responses
60
- question_lower = question.lower()
61
 
62
- # Geography
63
- if "capital" in question_lower:
64
- capitals = {
65
- "france": "Paris", "germany": "Berlin", "italy": "Rome",
66
- "spain": "Madrid", "japan": "Tokyo", "china": "Beijing",
67
- "india": "New Delhi", "brazil": "BrasΓ­lia", "canada": "Ottawa",
68
- "australia": "Canberra", "russia": "Moscow", "uk": "London",
69
- "united kingdom": "London", "usa": "Washington, D.C.",
70
- "united states": "Washington, D.C.", "mexico": "Mexico City"
71
- }
72
- for country, capital in capitals.items():
73
- if country in question_lower:
74
- return capital
75
 
76
- # Companies and CEOs
77
- if "ceo" in question_lower or "chief executive" in question_lower:
78
- ceos = {
79
- "tesla": "Elon Musk", "spacex": "Elon Musk", "apple": "Tim Cook",
80
- "microsoft": "Satya Nadella", "google": "Sundar Pichai",
81
- "amazon": "Andy Jassy", "meta": "Mark Zuckerberg",
82
- "facebook": "Mark Zuckerberg", "nvidia": "Jensen Huang"
83
- }
84
- for company, ceo in ceos.items():
85
- if company in question_lower:
86
- return ceo
 
 
 
 
 
87
 
88
- # Historical dates
89
- if "when" in question_lower or "what year" in question_lower:
90
- events = {
91
- "world war 2": "1939-1945", "world war ii": "1939-1945", "wwii": "1939-1945",
92
- "world war 1": "1914-1918", "world war i": "1914-1918", "wwi": "1914-1918",
93
- "moon landing": "1969", "first moon landing": "1969",
94
- "declared independence": "1776", "independence america": "1776"
95
- }
96
- for event, date in events.items():
97
- if event in question_lower:
98
- return date
99
 
100
- # Counting questions
101
- if "how many" in question_lower:
102
- counts = {
103
- "planets": "8", "continents": "7", "oceans": "5",
104
- "days in a week": "7", "months": "12", "states in usa": "50",
105
- "states in us": "50"
106
- }
107
- for thing, count in counts.items():
108
- if thing in question_lower:
109
- return count
110
 
111
- # Math questions
112
- if any(op in question for op in ['+', '-', '*', '/', 'Γ—', 'Γ·']):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  try:
114
- # Simple eval for basic math (be careful with this in production!)
115
- result = eval(question. replace('Γ—', '*').replace('Γ·', '/'))
116
- return str(result)
117
- except:
118
- pass
119
-
120
- # Try web search as fallback
121
- print("Using web search as fallback...")
122
- search_results = self.search_web(question, max_results=3)
123
- if search_results and "No results found" not in search_results:
124
- # Extract first meaningful content
125
- lines = search_results.split('\n')
126
- for line in lines:
127
- if len(line. strip()) > 30:
128
- # Return cleaned up snippet
129
- return line. strip()[:500]
130
-
131
- # Final fallback
132
- return "I don't have enough information to answer this question accurately."
133
 
134
  def run_and_submit_all(profile: gr.OAuthProfile | None):
135
  """
136
- Fetches all questions, runs the IntelligentAgent on them, submits all answers, and displays the results.
137
  """
138
  space_id = os.getenv("SPACE_ID")
139
 
@@ -141,50 +155,54 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
141
  print("User not logged in.")
142
  return "❌ Please login to Hugging Face using the button above.", None
143
 
144
- username = profile.username
 
145
  print(f"User logged in: {username}")
 
146
 
147
  api_url = DEFAULT_API_URL
148
  questions_url = f"{api_url}/questions"
149
  submit_url = f"{api_url}/submit"
150
 
151
  # 1. Instantiate Agent
152
- print("Creating agent instance...")
153
  try:
154
- agent = IntelligentAgent()
155
  except Exception as e:
156
- print(f"Error instantiating agent: {e}")
157
- return f"Error initializing agent: {e}", None
158
 
159
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
160
- print(f"Agent code: {agent_code}")
161
 
162
  # 2. Fetch Questions
163
- print(f"Fetching questions from: {questions_url}")
164
  try:
165
  response = requests.get(questions_url, timeout=30)
166
  response.raise_for_status()
167
  questions_data = response.json()
168
  if not questions_data:
169
  return "Fetched questions list is empty.", None
170
- print(f"βœ… Fetched {len(questions_data)} questions.")
171
  except Exception as e:
172
- print(f"Error fetching questions: {e}")
173
  return f"Error fetching questions: {e}", None
174
 
175
  # 3. Run Agent
176
  results_log = []
177
  answers_payload = []
178
- print(f"\nπŸ€– Running agent on {len(questions_data)} questions...")
 
179
 
180
  for idx, item in enumerate(questions_data, 1):
181
  task_id = item.get("task_id")
182
- question_text = item.get("question")
183
 
184
  if not task_id or question_text is None:
185
  continue
186
 
187
- print(f"\n[{idx}/{len(questions_data)}] Task: {task_id}")
 
188
 
189
  try:
190
  answer = agent(question_text)
@@ -192,80 +210,117 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
192
  "task_id": task_id,
193
  "submitted_answer": answer
194
  })
195
- results_log.append((task_id, question_text[:50], answer[:100]))
196
- print(f"βœ… Answer: {answer[:100]}")
197
- except Exception as e:
198
- print(f"❌ Error: {e}")
199
  answers_payload.append({
200
  "task_id": task_id,
201
- "submitted_answer": "Error processing question"
202
  })
 
 
 
 
 
203
 
204
  # 4. Submit answers
205
- print(f"\nπŸ“€ Submitting {len(answers_payload)} answers...")
206
  try:
207
  payload = {
208
  "username": username,
209
  "answers": answers_payload,
210
- "agent_code": agent_code
211
  }
212
 
213
- submit_response = requests. post(submit_url, json=payload, timeout=60)
214
  submit_response.raise_for_status()
215
  submission_result = submit_response.json()
216
- print(f"βœ… Submission successful: {submission_result}")
 
217
  except Exception as e:
218
- print(f"❌ Error submitting: {e}")
219
  return f"Error submitting answers: {e}", None
220
 
221
  # Display results
222
  results_df = pd.DataFrame(results_log, columns=["task_id", "question", "answer"])
223
  score = submission_result.get('score', 'N/A')
224
 
 
 
 
225
  result_message = f"""
226
- ## πŸŽ‰ Submission Successful!
 
 
 
 
227
 
228
- ### πŸ“Š Your Results:
229
- - **Score:** {score}
230
- - **Username:** {username}
231
- - **Questions Answered:** {len(answers_payload)}
 
232
 
233
- ### πŸ† Score Breakdown:
234
- - βœ… **Pass Threshold:** 30%
235
- - πŸ“ˆ **Your Score:** {score}
236
 
237
- {f"πŸŽ“ **Congratulations! You passed Unit 4! **" if isinstance(score, (int, float)) and score >= 30 else "πŸ“š Keep improving to reach 30%! "}
 
 
238
 
239
- ### πŸ”— Links:
240
- - [View Your Code]({agent_code})
241
- - [Course Unit 4](https://huggingface.co/learn/agents-course/en/unit4/hands-on)
242
  """
243
 
244
  return result_message, results_df
245
 
246
  # --- Gradio UI ---
247
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
248
- gr. Markdown("""
249
- # πŸ€– Intelligent Agent - Unit 4 Final Assignment
250
 
251
- This agent uses:
252
- - πŸ” **DuckDuckGo Search** for web information
253
- - 🧠 **Knowledge Base** for common questions
254
- - 🎯 **Smart fallbacks** for better coverage
 
255
 
256
- ## πŸ“‹ Instructions:
257
- 1. βœ… Sign in with Hugging Face
258
- 2. πŸš€ Click "Run Evaluation & Submit"
259
- 3. ⏳ Wait for your score
 
260
 
261
- **Target:** 30% or higher to pass!
 
 
 
262
  """)
263
 
264
- gr.LoginButton()
265
- submit_button = gr.Button("πŸš€ Run Evaluation & Submit All Answers", variant="primary", size="lg")
266
- output_text = gr.Markdown()
267
- output_table = gr. Dataframe(label="πŸ“ Results", wrap=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
 
269
- submit_button.click(run_and_submit_all, inputs=None, outputs=[output_text, output_table])
 
 
 
 
270
 
271
  demo.launch()
 
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
5
+ from huggingface_hub import InferenceClient
6
 
7
  # --- Constants ---
8
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
9
 
10
+ # --- Powerful Agent with HuggingFace ---
11
+ class PowerfulAgent:
12
  def __init__(self):
13
+ print("Initializing PowerfulAgent with HuggingFace Inference...")
 
14
 
15
+ # Get HF token
16
+ hf_token = os. getenv("HF_TOKEN")
17
+ if not hf_token:
18
+ print("⚠️ Warning: No HF_TOKEN found, using public endpoint")
19
+
20
+ # Initialize HF Inference Client
21
+ self.client = InferenceClient(token=hf_token)
22
+
23
+ # Use a powerful free model
24
+ self.model = "Qwen/Qwen2.5-72B-Instruct" # Very capable model
25
+ print(f"Using model: {self.model}")
26
+
27
+ # Initialize search
28
  try:
29
  from duckduckgo_search import DDGS
30
+ self.search = DDGS()
31
+ print("βœ… Search tool initialized")
32
+ except Exception as e:
33
+ self.search = None
34
+ print(f"⚠️ Search tool unavailable: {e}")
35
 
36
+ def search_web(self, query: str) -> str:
37
+ """Search web for information"""
38
+ if not self.search:
39
+ return ""
40
 
41
+ try:
42
+ results = list(self. search. text(query, max_results=5))
43
+ if not results:
44
+ return ""
45
 
 
46
  formatted = []
47
+ for r in results[:5]:
48
+ title = r.get('title', '')
49
+ body = r.get('body', '')
50
+ if title and body:
51
+ formatted.append(f"β€’ {title}: {body}")
52
 
53
+ return "\n". join(formatted)
54
  except Exception as e:
55
  print(f"Search error: {e}")
56
+ return ""
57
+
58
+ def __call__(self, question: str) -> str:
59
+ print(f"\n{'='*60}")
60
+ print(f"Question: {question[: 200]}")
61
+ print(f"{'='*60}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
+ # Search for context
64
+ search_context = ""
65
+ if self.search:
66
+ print("πŸ” Searching web...")
67
+ search_context = self.search_web(question)
68
+ if search_context:
69
+ print(f"βœ… Found search results ({len(search_context)} chars)")
 
 
 
 
 
 
70
 
71
+ # Build comprehensive prompt
72
+ system_prompt = """You are an expert AI assistant that provides accurate, concise answers.
73
+
74
+ INSTRUCTIONS:
75
+ 1. Read the question carefully
76
+ 2. Use web search results if provided
77
+ 3. Think step-by-step for complex problems
78
+ 4. Give ONLY the final answer - be direct and concise
79
+ 5. For numbers: provide just the number (e.g., "42" not "The answer is 42")
80
+ 6. For names: provide just the name (e.g., "Paris" not "The capital is Paris")
81
+ 7. For yes/no: provide just "Yes" or "No"
82
+ 8. Show calculations if needed, but end with clear final answer
83
+
84
+ Be precise, factual, and concise."""
85
+
86
+ user_prompt = f"Question: {question}"
87
 
88
+ if search_context:
89
+ user_prompt += f"\n\nWeb Search Results:\n{search_context[: 2500]}"
 
 
 
 
 
 
 
 
 
90
 
91
+ user_prompt += "\n\nAnswer (be direct and concise):"
 
 
 
 
 
 
 
 
 
92
 
93
+ # Call HF Inference
94
+ try:
95
+ print("πŸ€– Calling HuggingFace Inference API...")
96
+
97
+ messages = [
98
+ {"role": "system", "content": system_prompt},
99
+ {"role": "user", "content": user_prompt}
100
+ ]
101
+
102
+ # Use chat completion
103
+ response = self.client.chat_completion(
104
+ model=self. model,
105
+ messages=messages,
106
+ max_tokens=1000,
107
+ temperature=0.1 # Low for factual accuracy
108
+ )
109
+
110
+ answer = response.choices[0].message.content.strip()
111
+
112
+ # Clean up common verbose patterns
113
+ if answer.lower().startswith("according to"):
114
+ # Remove "According to the search results, " etc
115
+ parts = answer.split(",", 1)
116
+ if len(parts) > 1:
117
+ answer = parts[1].strip()
118
+
119
+ if answer.lower().startswith("the answer is"):
120
+ answer = answer[13:].strip()
121
+
122
+ if answer.lower().startswith("answer:"):
123
+ answer = answer[7:].strip()
124
+
125
+ print(f"βœ… Answer: {answer[: 200]}")
126
+ return answer
127
+
128
+ except Exception as e:
129
+ print(f"❌ Error with HF Inference: {e}")
130
+
131
+ # Fallback: try text generation API
132
  try:
133
+ print("Trying text generation fallback...")
134
+ full_prompt = f"{system_prompt}\n\n{user_prompt}"
135
+
136
+ response = self.client.text_generation(
137
+ full_prompt,
138
+ model=self.model,
139
+ max_new_tokens=500,
140
+ temperature=0.1
141
+ )
142
+
143
+ return response.strip()
144
+ except Exception as e2:
145
+ print(f"❌ Fallback also failed: {e2}")
146
+ return "Unable to process this question at this time."
 
 
 
 
 
147
 
148
  def run_and_submit_all(profile: gr.OAuthProfile | None):
149
  """
150
+ Fetches all questions, runs the PowerfulAgent on them, submits all answers, and displays the results.
151
  """
152
  space_id = os.getenv("SPACE_ID")
153
 
 
155
  print("User not logged in.")
156
  return "❌ Please login to Hugging Face using the button above.", None
157
 
158
+ username = profile. username
159
+ print(f"\n{'#'*60}")
160
  print(f"User logged in: {username}")
161
+ print(f"{'#'*60}\n")
162
 
163
  api_url = DEFAULT_API_URL
164
  questions_url = f"{api_url}/questions"
165
  submit_url = f"{api_url}/submit"
166
 
167
  # 1. Instantiate Agent
168
+ print("πŸš€ Creating agent instance...")
169
  try:
170
+ agent = PowerfulAgent()
171
  except Exception as e:
172
+ print(f"❌ Error instantiating agent: {e}")
173
+ return f"Error initializing agent: {e}", None
174
 
175
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
176
+ print(f"πŸ“ Agent code: {agent_code}\n")
177
 
178
  # 2. Fetch Questions
179
+ print(f"πŸ“₯ Fetching questions from: {questions_url}")
180
  try:
181
  response = requests.get(questions_url, timeout=30)
182
  response.raise_for_status()
183
  questions_data = response.json()
184
  if not questions_data:
185
  return "Fetched questions list is empty.", None
186
+ print(f"βœ… Fetched {len(questions_data)} questions.\n")
187
  except Exception as e:
188
+ print(f"❌ Error fetching questions: {e}")
189
  return f"Error fetching questions: {e}", None
190
 
191
  # 3. Run Agent
192
  results_log = []
193
  answers_payload = []
194
+ print(f"πŸ€– Running agent on {len(questions_data)} questions...")
195
+ print(f"⏳ This will take 3-5 minutes...\n")
196
 
197
  for idx, item in enumerate(questions_data, 1):
198
  task_id = item.get("task_id")
199
+ question_text = item. get("question")
200
 
201
  if not task_id or question_text is None:
202
  continue
203
 
204
+ print(f"\n{'─'*60}")
205
+ print(f"[{idx}/{len(questions_data)}] Task: {task_id}")
206
 
207
  try:
208
  answer = agent(question_text)
 
210
  "task_id": task_id,
211
  "submitted_answer": answer
212
  })
213
+ results_log.append((task_id, question_text[:50], answer[: 100]))
214
+ except Exception as e:
215
+ print(f"❌ Error: {e}")
216
+ error_msg = "Unable to process this question."
217
  answers_payload.append({
218
  "task_id": task_id,
219
+ "submitted_answer": error_msg
220
  })
221
+ results_log.append((task_id, question_text[:50], f"Error: {e}"))
222
+
223
+ print(f"\n{'='*60}")
224
+ print(f"βœ… Completed processing all {len(answers_payload)} questions!")
225
+ print(f"{'='*60}\n")
226
 
227
  # 4. Submit answers
228
+ print(f"πŸ“€ Submitting answers to scoring server...")
229
  try:
230
  payload = {
231
  "username": username,
232
  "answers": answers_payload,
233
+ "agent_code": agent_code
234
  }
235
 
236
+ submit_response = requests.post(submit_url, json=payload, timeout=60)
237
  submit_response.raise_for_status()
238
  submission_result = submit_response.json()
239
+ print(f"βœ… Submission successful!")
240
+ print(f"πŸ“Š Result: {submission_result}\n")
241
  except Exception as e:
242
+ print(f"❌ Error submitting: {e}")
243
  return f"Error submitting answers: {e}", None
244
 
245
  # Display results
246
  results_df = pd.DataFrame(results_log, columns=["task_id", "question", "answer"])
247
  score = submission_result.get('score', 'N/A')
248
 
249
+ # Determine pass/fail
250
+ passed = isinstance(score, (int, float)) and score >= 30
251
+
252
  result_message = f"""
253
+ ## {'πŸŽ‰ CONGRATULATIONS! YOU PASSED!' if passed else 'πŸ“Š Submission Complete'}
254
+
255
+ ### πŸ† Your Score: **{score}%**
256
+
257
+ {'### βœ… YOU PASSED UNIT 4!' if passed else '### ⚠️ Score below 30% threshold'}
258
 
259
+ **Submission Details:**
260
+ - πŸ‘€ Username: `{username}`
261
+ - πŸ“ Questions Answered: {len(answers_payload)}
262
+ - 🎯 Pass Threshold: 30%
263
+ - πŸ“Š Your Score: {score}%
264
 
265
+ {f"### πŸŽ“ Congratulations! You have successfully completed Unit 4 of the Hugging Face Agents Course!" if passed else "### πŸ’‘ Tips to improve: The agent uses Qwen 2.5 72B and web search. Try running again as results may vary. "}
 
 
266
 
267
+ ### πŸ”— Resources:
268
+ - [View Your Agent Code]({agent_code})
269
+ - [Unit 4 Course Material](https://huggingface.co/learn/agents-course/en/unit4/hands-on)
270
 
271
+ ---
272
+ *Agent: Qwen 2.5 72B-Instruct + DuckDuckGo Search*
 
273
  """
274
 
275
  return result_message, results_df
276
 
277
  # --- Gradio UI ---
278
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
279
+ gr.Markdown("""
280
+ # πŸ€– AI Agent - Unit 4 Final Assignment
281
 
282
+ ## πŸš€ Agent Capabilities:
283
+ - 🧠 **Qwen 2.5 72B-Instruct** - One of the most capable open models
284
+ - πŸ” **DuckDuckGo Web Search** - Real-time information retrieval
285
+ - 🎯 **Advanced Reasoning** - Step-by-step problem solving
286
+ - πŸ“Š **Optimized Prompts** - Engineered for GAIA benchmark
287
 
288
+ ## πŸ“‹ How to Use:
289
+ 1. βœ… Click "Sign in with Hugging Face" below (must be logged in)
290
+ 2. πŸš€ Click "Run Evaluation & Submit All Answers"
291
+ 3. ⏳ Wait 3-5 minutes for all questions to be processed
292
+ 4. πŸŽ‰ See your score!
293
 
294
+ ## 🎯 Goal:
295
+ **Get 30% or higher to pass Unit 4! **
296
+
297
+ The agent will process each question using web search and advanced reasoning.
298
  """)
299
 
300
+ with gr.Row():
301
+ gr.LoginButton()
302
+
303
+ with gr.Row():
304
+ submit_button = gr.Button(
305
+ "πŸš€ Run Evaluation & Submit All Answers",
306
+ variant="primary",
307
+ size="lg"
308
+ )
309
+
310
+ with gr.Row():
311
+ output_text = gr.Markdown()
312
+
313
+ with gr.Row():
314
+ output_table = gr. Dataframe(
315
+ label="πŸ“ Detailed Results",
316
+ wrap=True,
317
+ interactive=False
318
+ )
319
 
320
+ submit_button.click(
321
+ run_and_submit_all,
322
+ inputs=None,
323
+ outputs=[output_text, output_table]
324
+ )
325
 
326
  demo.launch()