aniketqxp commited on
Commit
df528e3
·
verified ·
1 Parent(s): 7d135b7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +243 -19
app.py CHANGED
@@ -3,15 +3,20 @@ import gradio as gr
3
  import requests
4
  import pandas as pd
5
  import google.generativeai as genai
 
 
 
 
 
6
 
7
  # --- Constants ---
8
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
9
  MODEL_TO_USE = "gemini-1.5-flash"
10
 
11
  # --- Enhanced Agent Definition ---
12
- class BasicAgent:
13
  def __init__(self):
14
- print("BasicAgent initialized.")
15
  # Get API key from environment (set in HF Space secrets)
16
  api_key = os.getenv("GOOGLE_API_KEY")
17
  if not api_key:
@@ -19,29 +24,239 @@ class BasicAgent:
19
 
20
  genai.configure(api_key=api_key)
21
  self.model = genai.GenerativeModel(MODEL_TO_USE)
 
 
 
22
 
23
- def __call__(self, question: str) -> str:
24
- print(f"Agent received question (first 50 chars): {question[:50]}...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- # Add some basic prompt engineering to improve accuracy
27
- prompt = f"""Please answer this question directly and concisely. Provide only the final answer without explanation unless specifically asked for reasoning.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  Question: {question}
30
 
31
  Answer:"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  try:
34
  response = self.model.generate_content(prompt)
35
  answer = response.text.strip()
 
 
 
 
 
 
 
36
  print(f"Agent returning answer: {answer[:100]}...")
37
  return answer
 
38
  except Exception as e:
39
  print(f"Error calling Gemini API: {e}")
40
- return f"Error: Could not generate answer - {str(e)}"
 
 
 
 
 
 
 
41
 
42
  def run_and_submit_all(profile: gr.OAuthProfile | None):
43
  """
44
- Fetches all questions, runs the BasicAgent on them, submits all answers,
45
  and displays the results.
46
  """
47
  # --- Determine HF Space Runtime URL and Repo URL ---
@@ -60,7 +275,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
60
 
61
  # 1. Instantiate Agent (modify this part to create your agent)
62
  try:
63
- agent = BasicAgent()
64
  except Exception as e:
65
  print(f"Error instantiating agent: {e}")
66
  return f"Error initializing agent: {e}", None
@@ -93,13 +308,17 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
93
  # 3. Run your Agent
94
  results_log = []
95
  answers_payload = []
96
- print(f"Running agent on {len(questions_data)} questions...")
97
- for item in questions_data:
 
98
  task_id = item.get("task_id")
99
  question_text = item.get("question")
100
  if not task_id or question_text is None:
101
  print(f"Skipping item with missing task_id or question: {item}")
102
  continue
 
 
 
103
  try:
104
  submitted_answer = agent(question_text)
105
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
@@ -114,7 +333,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
114
 
115
  # 4. Prepare Submission
116
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
117
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
118
  print(status_update)
119
 
120
  # 5. Submit
@@ -163,20 +382,25 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
163
 
164
  # --- Build Gradio Interface using Blocks ---
165
  with gr.Blocks() as demo:
166
- gr.Markdown("# Gemini-Powered Agent Evaluation Runner")
167
  gr.Markdown(
168
  """
169
  **Instructions:**
170
 
171
  1. Make sure you've set your `GOOGLE_API_KEY` in the Space secrets (Settings tab)
172
  2. Log in to your Hugging Face account using the button below
173
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, and submit answers
174
 
175
- **Note:** This agent uses Google's Gemini 1.5 Flash model to answer questions.
 
 
 
 
 
176
 
177
  ---
178
  **Disclaimers:**
179
- Once clicking on the submit button, it can take quite some time (this is the time for the agent to go through all the questions).
180
  """
181
  )
182
 
@@ -193,7 +417,7 @@ with gr.Blocks() as demo:
193
  )
194
 
195
  if __name__ == "__main__":
196
- print("\n" + "-"*30 + " App Starting " + "-"*30)
197
  # Check for SPACE_HOST and SPACE_ID at startup for information
198
  space_host_startup = os.getenv("SPACE_HOST")
199
  space_id_startup = os.getenv("SPACE_ID")
@@ -211,7 +435,7 @@ if __name__ == "__main__":
211
  else:
212
  print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
213
 
214
- print("-"*(60 + len(" App Starting ")) + "\n")
215
 
216
- print("Launching Gradio Interface for Gemini Agent Evaluation...")
217
  demo.launch(debug=True, share=False)
 
3
  import requests
4
  import pandas as pd
5
  import google.generativeai as genai
6
+ import time
7
+ import re
8
+ from bs4 import BeautifulSoup
9
+ from urllib.parse import quote_plus
10
+ import json
11
 
12
  # --- Constants ---
13
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
14
  MODEL_TO_USE = "gemini-1.5-flash"
15
 
16
  # --- Enhanced Agent Definition ---
17
+ class EnhancedAgent:
18
  def __init__(self):
19
+ print("EnhancedAgent initialized.")
20
  # Get API key from environment (set in HF Space secrets)
21
  api_key = os.getenv("GOOGLE_API_KEY")
22
  if not api_key:
 
24
 
25
  genai.configure(api_key=api_key)
26
  self.model = genai.GenerativeModel(MODEL_TO_USE)
27
+ self.request_count = 0
28
+ self.last_request_time = 0
29
+ self.min_request_interval = 2 # Minimum seconds between requests
30
 
31
+ def _rate_limit(self):
32
+ """Simple rate limiting to avoid API restrictions"""
33
+ current_time = time.time()
34
+ time_since_last = current_time - self.last_request_time
35
+
36
+ if time_since_last < self.min_request_interval:
37
+ sleep_time = self.min_request_interval - time_since_last
38
+ print(f"Rate limiting: sleeping for {sleep_time:.2f} seconds")
39
+ time.sleep(sleep_time)
40
+
41
+ self.last_request_time = time.time()
42
+ self.request_count += 1
43
+
44
+ # Additional throttling after many requests
45
+ if self.request_count > 10:
46
+ time.sleep(1)
47
+ if self.request_count > 20:
48
+ time.sleep(2)
49
+
50
+ def _search_web(self, query, max_results=5):
51
+ """Simple web search using Google search results"""
52
+ try:
53
+ search_url = f"https://www.google.com/search?q={quote_plus(query)}"
54
+ headers = {
55
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
56
+ }
57
+
58
+ response = requests.get(search_url, headers=headers, timeout=10)
59
+ response.raise_for_status()
60
+
61
+ soup = BeautifulSoup(response.content, 'html.parser')
62
+ results = []
63
+
64
+ # Extract search result snippets
65
+ for result in soup.find_all('div', class_='BNeawe s3v9rd AP7Wnd')[:max_results]:
66
+ if result.text:
67
+ results.append(result.text)
68
+
69
+ # Also try different class names for search results
70
+ if not results:
71
+ for result in soup.find_all('span', class_='aCOpRe')[:max_results]:
72
+ if result.text:
73
+ results.append(result.text)
74
+
75
+ return results[:max_results]
76
+
77
+ except Exception as e:
78
+ print(f"Web search error: {e}")
79
+ return []
80
+
81
+ def _search_wikipedia(self, query):
82
+ """Search Wikipedia specifically"""
83
+ try:
84
+ search_url = f"https://en.wikipedia.org/w/api.php"
85
+ params = {
86
+ 'action': 'query',
87
+ 'format': 'json',
88
+ 'list': 'search',
89
+ 'srsearch': query,
90
+ 'srlimit': 3
91
+ }
92
+
93
+ response = requests.get(search_url, params=params, timeout=10)
94
+ response.raise_for_status()
95
+ data = response.json()
96
+
97
+ results = []
98
+ if 'query' in data and 'search' in data['query']:
99
+ for item in data['query']['search']:
100
+ results.append({
101
+ 'title': item['title'],
102
+ 'snippet': item['snippet']
103
+ })
104
+
105
+ return results
106
+
107
+ except Exception as e:
108
+ print(f"Wikipedia search error: {e}")
109
+ return []
110
+
111
+ def _classify_question(self, question):
112
+ """Classify question type to determine search strategy"""
113
+ question_lower = question.lower()
114
+
115
+ # Wikipedia-specific questions
116
+ if 'wikipedia' in question_lower or 'featured article' in question_lower:
117
+ return 'wikipedia'
118
+
119
+ # Historical/factual questions that benefit from web search
120
+ if any(keyword in question_lower for keyword in [
121
+ 'olympics', 'competition', 'award', 'published', 'album', 'season',
122
+ 'year', 'when', 'who', 'where', 'how many', 'what country'
123
+ ]):
124
+ return 'factual'
125
+
126
+ # Academic/scientific questions
127
+ if any(keyword in question_lower for keyword in [
128
+ 'paper', 'study', 'research', 'journal', 'university', 'professor'
129
+ ]):
130
+ return 'academic'
131
 
132
+ # Mathematical/logical questions
133
+ if any(keyword in question_lower for keyword in [
134
+ 'table', 'set', 'commutative', 'algebraic', 'notation'
135
+ ]):
136
+ return 'mathematical'
137
+
138
+ # Text manipulation questions
139
+ if 'sentence' in question_lower and 'understand' in question_lower:
140
+ return 'text_manipulation'
141
+
142
+ # Classification questions
143
+ if 'grocery' in question_lower or 'vegetables' in question_lower or 'fruits' in question_lower:
144
+ return 'classification'
145
+
146
+ return 'general'
147
+
148
+ def _create_specialized_prompt(self, question, question_type, search_results=None):
149
+ """Create specialized prompts based on question type"""
150
+
151
+ base_context = ""
152
+ if search_results:
153
+ base_context = f"\nRelevant information from search:\n" + "\n".join([f"- {result}" for result in search_results[:3]])
154
+
155
+ if question_type == 'wikipedia':
156
+ return f"""You are answering a question about Wikipedia. Be precise and factual.
157
+ {base_context}
158
+
159
+ Question: {question}
160
+
161
+ Provide only the exact answer requested, no explanations:"""
162
+
163
+ elif question_type == 'factual':
164
+ return f"""You are answering a factual question. Use the search results to provide an accurate answer.
165
+ {base_context}
166
+
167
+ Question: {question}
168
+
169
+ Provide only the exact answer requested (name, number, or short phrase):"""
170
+
171
+ elif question_type == 'mathematical':
172
+ return f"""You are solving a mathematical/logical problem. Work through it step by step but only provide the final answer.
173
+
174
+ Question: {question}
175
+
176
+ Analyze the problem carefully and provide only the final answer in the requested format:"""
177
+
178
+ elif question_type == 'text_manipulation':
179
+ return f"""You are working with text manipulation. Read the question carefully and follow the instructions exactly.
180
+
181
+ Question: {question}
182
+
183
+ Provide only the exact answer requested:"""
184
+
185
+ elif question_type == 'classification':
186
+ return f"""You are categorizing items. Be very precise about botanical vs. culinary classifications.
187
+
188
+ Question: {question}
189
+
190
+ Provide only the requested list in the exact format specified:"""
191
+
192
+ elif question_type == 'academic':
193
+ return f"""You are answering an academic question. Use the search results to find specific details.
194
+ {base_context}
195
+
196
+ Question: {question}
197
+
198
+ Provide only the exact answer requested (name, number, or specific detail):"""
199
+
200
+ else: # general
201
+ return f"""Answer this question directly and concisely. Provide only the final answer without explanation.
202
+ {base_context}
203
 
204
  Question: {question}
205
 
206
  Answer:"""
207
+
208
+ def __call__(self, question: str) -> str:
209
+ print(f"Agent received question (first 100 chars): {question[:100]}...")
210
+
211
+ # Rate limiting
212
+ self._rate_limit()
213
+
214
+ # Classify question type
215
+ question_type = self._classify_question(question)
216
+ print(f"Question classified as: {question_type}")
217
+
218
+ # Perform web search for certain question types
219
+ search_results = []
220
+ if question_type in ['wikipedia', 'factual', 'academic']:
221
+ if question_type == 'wikipedia':
222
+ wiki_results = self._search_wikipedia(question)
223
+ search_results = [f"{r['title']}: {r['snippet']}" for r in wiki_results]
224
+ else:
225
+ search_results = self._search_web(question)
226
+
227
+ if search_results:
228
+ print(f"Found {len(search_results)} search results")
229
+
230
+ # Create specialized prompt
231
+ prompt = self._create_specialized_prompt(question, question_type, search_results)
232
 
233
  try:
234
  response = self.model.generate_content(prompt)
235
  answer = response.text.strip()
236
+
237
+ # Clean up answer for specific question types
238
+ if question_type == 'classification' and ',' in answer:
239
+ # Ensure comma-separated lists are properly formatted
240
+ items = [item.strip() for item in answer.split(',')]
241
+ answer = ', '.join(items)
242
+
243
  print(f"Agent returning answer: {answer[:100]}...")
244
  return answer
245
+
246
  except Exception as e:
247
  print(f"Error calling Gemini API: {e}")
248
+ # Fallback to basic prompt if specialized approach fails
249
+ try:
250
+ basic_prompt = f"Answer this question directly and concisely: {question}"
251
+ response = self.model.generate_content(basic_prompt)
252
+ return response.text.strip()
253
+ except Exception as e2:
254
+ print(f"Fallback also failed: {e2}")
255
+ return f"Error: Could not generate answer - {str(e)}"
256
 
257
  def run_and_submit_all(profile: gr.OAuthProfile | None):
258
  """
259
+ Fetches all questions, runs the EnhancedAgent on them, submits all answers,
260
  and displays the results.
261
  """
262
  # --- Determine HF Space Runtime URL and Repo URL ---
 
275
 
276
  # 1. Instantiate Agent (modify this part to create your agent)
277
  try:
278
+ agent = EnhancedAgent()
279
  except Exception as e:
280
  print(f"Error instantiating agent: {e}")
281
  return f"Error initializing agent: {e}", None
 
308
  # 3. Run your Agent
309
  results_log = []
310
  answers_payload = []
311
+ print(f"Running enhanced agent on {len(questions_data)} questions...")
312
+
313
+ for i, item in enumerate(questions_data):
314
  task_id = item.get("task_id")
315
  question_text = item.get("question")
316
  if not task_id or question_text is None:
317
  print(f"Skipping item with missing task_id or question: {item}")
318
  continue
319
+
320
+ print(f"Processing question {i+1}/{len(questions_data)}: {task_id}")
321
+
322
  try:
323
  submitted_answer = agent(question_text)
324
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
 
333
 
334
  # 4. Prepare Submission
335
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
336
+ status_update = f"Enhanced agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
337
  print(status_update)
338
 
339
  # 5. Submit
 
382
 
383
  # --- Build Gradio Interface using Blocks ---
384
  with gr.Blocks() as demo:
385
+ gr.Markdown("# Enhanced Gemini Agent with Web Search")
386
  gr.Markdown(
387
  """
388
  **Instructions:**
389
 
390
  1. Make sure you've set your `GOOGLE_API_KEY` in the Space secrets (Settings tab)
391
  2. Log in to your Hugging Face account using the button below
392
+ 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your enhanced agent, and submit answers
393
 
394
+ **Enhanced Features:**
395
+ - Intelligent question classification
396
+ - Web search integration for factual questions
397
+ - Specialized prompting strategies
398
+ - Rate limiting to avoid API restrictions
399
+ - Wikipedia search for specific queries
400
 
401
  ---
402
  **Disclaimers:**
403
+ This process can take some time as the agent searches the web and processes each question carefully.
404
  """
405
  )
406
 
 
417
  )
418
 
419
  if __name__ == "__main__":
420
+ print("\n" + "-"*30 + " Enhanced App Starting " + "-"*30)
421
  # Check for SPACE_HOST and SPACE_ID at startup for information
422
  space_host_startup = os.getenv("SPACE_HOST")
423
  space_id_startup = os.getenv("SPACE_ID")
 
435
  else:
436
  print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
437
 
438
+ print("-"*(60 + len(" Enhanced App Starting ")) + "\n")
439
 
440
+ print("Launching Enhanced Gradio Interface for Gemini Agent Evaluation...")
441
  demo.launch(debug=True, share=False)