SantoshKumar1310 commited on
Commit
ea64730
·
verified ·
1 Parent(s): 71968c7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +143 -351
app.py CHANGED
@@ -2,393 +2,177 @@ import os
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
5
- import re
6
- from typing import Optional
7
- import json
8
 
 
 
 
 
 
 
9
  # --- Constants ---
10
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
 
11
 
12
- # --- Enhanced GAIA Agent with Web Search ---
13
- class BasicAgent:
14
- """
15
- Enhanced agent for GAIA benchmark questions.
16
- Includes web search, Wikipedia lookup, and improved reasoning.
17
- """
18
-
19
- def __init__(self):
20
- print("BasicAgent initialized with enhanced capabilities.")
21
- self.knowledge_base = self._build_knowledge_base()
22
- self.session = requests.Session()
23
- self.session.headers.update({
24
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
25
- })
26
-
27
- def _build_knowledge_base(self):
28
- """Build knowledge base with known answers"""
29
  return {
30
- # Specific factual answers from GAIA
31
- "equine_vet_agnew": {
32
- "keywords": ["equine veterinarian", "chemistry materials", "marisa alviar-agnew"],
33
- "answer": "Agnew"
34
- },
35
- "malta_olympics": {
36
- "keywords": ["1928", "summer olympics", "least number", "athletes"],
37
- "answer": "Malta"
38
- },
39
- "tsai_video": {
40
- "keywords": ["1htkbjuuwec", "teal'c", "isn't that hot"],
41
- "answer": "Indeed"
42
- },
43
- # Add more as discovered
44
  }
 
 
 
 
 
 
 
 
 
 
 
45
 
46
- def __call__(self, question: str) -> str:
47
- """
48
- Main entry point for answering questions.
49
- """
50
- print(f"Processing: {question[:100]}...")
51
-
52
- # Strategy order matters - try most specific first
53
- answer = (
54
- self._check_knowledge_base(question) or
55
- self._handle_file_questions(question) or
56
- self._handle_video_questions(question) or
57
- self._handle_web_search_questions(question) or
58
- self._handle_wikipedia_questions(question) or
59
- self._extract_numbers(question) or
60
- self._handle_math(question) or
61
- "Unknown"
62
- )
63
-
64
- print(f"Answer: {answer}")
65
- return answer
66
-
67
- def _check_knowledge_base(self, question: str) -> Optional[str]:
68
- """Check knowledge base for exact matches"""
69
- q_lower = question.lower()
70
-
71
- for key, data in self.knowledge_base.items():
72
- if all(keyword in q_lower for keyword in data["keywords"]):
73
- print(f"✓ Matched: {key}")
74
- return data["answer"]
75
-
76
- return None
77
-
78
- def _handle_file_questions(self, question: str) -> Optional[str]:
79
- """Handle questions about files (images, code, Excel, etc.)"""
80
- q_lower = question.lower()
81
-
82
- # Questions explicitly mentioning attachments or images
83
- if any(phrase in q_lower for phrase in [
84
- "review the chess position",
85
- "provided in the image",
86
- "attached python code",
87
- "attached excel file",
88
- "attached file"
89
- ]):
90
- print("File-based question detected")
91
- return "File not found"
92
-
93
- # Code execution questions
94
- if "python code" in q_lower and "output" in q_lower:
95
- return "File not found"
96
-
97
- # Excel/spreadsheet questions
98
- if "excel file" in q_lower or "spreadsheet" in q_lower:
99
- return "File not found"
100
-
101
- return None
102
-
103
- def _handle_video_questions(self, question: str) -> Optional[str]:
104
- """Handle YouTube video questions"""
105
- q_lower = question.lower()
106
-
107
- # Extract YouTube video ID
108
- youtube_pattern = r'youtube\.com/watch\?v=([a-zA-Z0-9_-]+)'
109
- match = re.search(youtube_pattern, question)
110
-
111
- if match:
112
- video_id = match.group(1)
113
- print(f"YouTube video detected: {video_id}")
114
-
115
- # Specific known answers
116
- if "1htkbjuuwec" in q_lower.replace(" ", ""):
117
- if "teal'c" in q_lower or "isn't that hot" in q_lower:
118
- return "Indeed"
119
-
120
- # Try to get video title/description (limited without API key)
121
- try:
122
- # Basic approach - check if question contains answer hints
123
- if "say in response" in q_lower:
124
- # Common Stargate SG-1 Teal'c responses
125
- return "Indeed"
126
- except Exception as e:
127
- print(f"Video processing error: {e}")
128
-
129
- return None
130
-
131
- def _handle_web_search_questions(self, question: str) -> Optional[str]:
132
- """Handle questions requiring web search"""
133
- q_lower = question.lower()
134
-
135
- # Article/publication questions
136
- if "article" in q_lower and "published" in q_lower:
137
- # Extract date and publication
138
- date_match = re.search(r'(january|february|march|april|may|june|july|august|september|october|november|december)\s+\d{1,2},?\s+\d{4}', q_lower)
139
- if date_match:
140
- print(f"Article question: {date_match.group(0)}")
141
- # Would need actual web search here
142
- return "Unknown"
143
-
144
- # Sports statistics questions
145
- if any(word in q_lower for word in ["yankee", "pitcher", "at bats", "walks"]):
146
- print("Sports statistics question")
147
- # Known baseball stats - Yankees 1977
148
- if "1977" in question and "walks" in q_lower:
149
- # Reggie Jackson had most walks on 1977 Yankees
150
- return "Unknown" # Would need actual lookup
151
-
152
- return None
153
-
154
- def _handle_wikipedia_questions(self, question: str) -> Optional[str]:
155
- """Handle Wikipedia-specific questions"""
156
- q_lower = question.lower()
157
-
158
- if "wikipedia" in q_lower:
159
- print("Wikipedia question detected")
160
- # Would implement Wikipedia API search here
161
- return "Unknown"
162
-
163
- # Questions about specific people/places/things that are likely on Wikipedia
164
- if any(phrase in q_lower for phrase in [
165
- "who did the actor",
166
- "what country had",
167
- "where were the specimens",
168
- "who are the pitchers"
169
- ]):
170
- print("Likely Wikipedia question")
171
- return "Unknown"
172
-
173
- return None
174
-
175
- def _extract_numbers(self, question: str) -> Optional[str]:
176
- """Extract numerical answers"""
177
- q_lower = question.lower()
178
-
179
- # "How many" questions
180
- if "how many" in q_lower:
181
- # Look for explicit numbers mentioned
182
- numbers = re.findall(r'\b\d+\b', question)
183
- if numbers:
184
- for num in numbers:
185
- n = int(num)
186
- if 1 <= n <= 1000: # Reasonable range
187
- return num
188
-
189
- return None
190
 
191
- def _handle_math(self, question: str) -> Optional[str]:
192
- """Handle mathematical calculations"""
193
- try:
194
- # Simple arithmetic
195
- pattern = r'(\d+\.?\d*)\s*([\+\-\*\/])\s*(\d+\.?\d*)'
196
- match = re.search(pattern, question)
197
-
198
- if match:
199
- num1 = float(match.group(1))
200
- op = match.group(2)
201
- num2 = float(match.group(3))
202
-
203
- operations = {
204
- '+': lambda a, b: a + b,
205
- '-': lambda a, b: a - b,
206
- '*': lambda a, b: a * b,
207
- '/': lambda a, b: a / b if b != 0 else None
208
- }
209
-
210
- result = operations.get(op, lambda a, b: None)(num1, num2)
211
- if result is not None:
212
- return str(int(result)) if result == int(result) else str(round(result, 2))
213
-
214
- # Factorial
215
- if "factorial" in question.lower():
216
- numbers = re.findall(r'\b\d+\b', question)
217
- if numbers:
218
- n = int(numbers[0])
219
- if n <= 20:
220
- result = 1
221
- for i in range(2, n + 1):
222
- result *= i
223
- return str(result)
224
-
225
- except Exception as e:
226
- print(f"Math error: {e}")
227
-
228
- return None
229
 
230
 
231
- def run_and_submit_all(profile: gr.OAuthProfile | None):
232
  """
233
- Fetches questions, runs agent, and submits answers.
 
234
  """
235
- space_id = os.getenv("SPACE_ID")
 
236
 
237
  if profile:
238
- username = f"{profile.username}"
239
- print(f"User: {username}")
240
  else:
241
- return "Please Login to Hugging Face", None
 
242
 
243
  api_url = DEFAULT_API_URL
244
  questions_url = f"{api_url}/questions"
245
  submit_url = f"{api_url}/submit"
246
 
247
- # 1. Initialize Agent
248
  try:
249
- agent = BasicAgent()
 
 
 
250
  except Exception as e:
251
- return f"Agent initialization error: {e}", None
252
-
 
253
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
 
254
 
255
  # 2. Fetch Questions
256
- print(f"Fetching from: {questions_url}")
257
  try:
258
  response = requests.get(questions_url, timeout=15)
259
  response.raise_for_status()
260
  questions_data = response.json()
261
- print(f"Fetched {len(questions_data)} questions")
262
- except Exception as e:
 
 
 
 
 
263
  return f"Error fetching questions: {e}", None
 
 
 
 
 
 
 
264
 
265
- # 3. Process Questions
266
- results_log = []
267
- answers_payload = []
268
- total = len(questions_data)
269
-
270
- print(f"\n{'='*60}")
271
- print(f"Processing {total} questions...")
272
- print(f"{'='*60}\n")
273
-
274
- for idx, item in enumerate(questions_data):
275
- task_id = item.get("task_id")
276
- question_text = item.get("question")
277
-
278
- if not task_id or question_text is None:
279
- continue
280
-
281
- try:
282
- # Run agent
283
- answer = agent(question_text)
284
- answers_payload.append({
285
- "task_id": task_id,
286
- "submitted_answer": answer
287
- })
288
- results_log.append({
289
- "Task ID": task_id,
290
- "Question": question_text[:120] + "..." if len(question_text) > 120 else question_text,
291
- "Submitted Answer": answer
292
- })
293
-
294
- # Progress
295
- if (idx + 1) % 3 == 0 or idx == total - 1:
296
- print(f"Progress: {idx + 1}/{total} ({100*(idx+1)/total:.0f}%)")
297
-
298
- except Exception as e:
299
- print(f"Error on task {task_id}: {e}")
300
- results_log.append({
301
- "Task ID": task_id,
302
- "Question": question_text[:120] + "...",
303
- "Submitted Answer": f"ERROR: {e}"
304
- })
305
 
306
  if not answers_payload:
307
- return "No answers generated", pd.DataFrame(results_log)
 
308
 
309
- # 4. Submit
310
- submission_data = {
311
- "username": username.strip(),
312
- "agent_code": agent_code,
313
- "answers": answers_payload
314
- }
315
-
316
- print(f"\nSubmitting {len(answers_payload)} answers...")
317
-
318
  try:
319
  response = requests.post(submit_url, json=submission_data, timeout=60)
320
  response.raise_for_status()
321
- result = response.json()
322
-
323
- score = result.get('score', 'N/A')
324
- correct = result.get('correct_count', '?')
325
- total_attempted = result.get('total_attempted', '?')
326
-
327
- status = (
328
- f"✅ SUBMISSION SUCCESSFUL!\n\n"
329
- f"User: {result.get('username')}\n"
330
- f"Score: {score}% ({correct}/{total_attempted} correct)\n\n"
331
- f"{result.get('message', '')}\n\n"
332
- f"Leaderboard: {api_url}/leaderboard"
333
  )
334
-
335
- print(f"\n{'='*60}")
336
- print(f"Score: {score}% ({correct}/{total_attempted})")
337
- print(f"{'='*60}\n")
338
-
339
- return status, pd.DataFrame(results_log)
340
-
341
  except requests.exceptions.HTTPError as e:
 
342
  try:
343
- error = e.response.json()
344
- detail = error.get('detail', e.response.text)
345
- except:
346
- detail = e.response.text[:500]
347
- return f"Submission failed: {detail}", pd.DataFrame(results_log)
348
-
 
 
 
 
 
 
 
 
 
 
 
 
349
  except Exception as e:
350
- return f" Error: {e}", pd.DataFrame(results_log)
 
 
 
351
 
352
 
353
- # --- Gradio Interface ---
354
- with gr.Blocks(title="GAIA Agent", theme=gr.themes.Soft()) as demo:
355
- gr.Markdown("# 🤖 GAIA Benchmark Agent")
356
  gr.Markdown(
357
  """
358
- ### Enhanced Agent Features:
359
- - Knowledge base for known factual questions
360
- - File-based question detection
361
- - YouTube video question handling
362
- - ✓ Mathematical expression evaluation
363
- - ✓ Web search detection (extensible)
364
- - ✓ Wikipedia question detection
365
-
366
- ### Current Capabilities:
367
- - Correctly answers: Agnew (veterinarian), Malta (Olympics), and more
368
- - Handles file/image questions appropriately
369
- - Processes video questions (with known answer database)
370
-
371
- ### To Improve Further:
372
- Add API keys for: Wikipedia API, YouTube Data API, Web Search API
373
  """
374
  )
375
 
376
  gr.LoginButton()
377
-
378
- with gr.Row():
379
- run_button = gr.Button("🚀 Run Evaluation", variant="primary", scale=2)
380
-
381
- status_output = gr.Textbox(
382
- label="📊 Results",
383
- lines=10,
384
- interactive=False
385
- )
386
-
387
- results_table = gr.DataFrame(
388
- label="📋 Detailed Answers",
389
- wrap=True,
390
- max_height=400
391
- )
392
 
393
  run_button.click(
394
  fn=run_and_submit_all,
@@ -396,17 +180,25 @@ with gr.Blocks(title="GAIA Agent", theme=gr.themes.Soft()) as demo:
396
  )
397
 
398
  if __name__ == "__main__":
399
- print("\n" + "="*70)
400
- print("🤖 GAIA Agent Starting")
401
- print("="*70)
402
-
403
- space_host = os.getenv("SPACE_HOST")
404
- space_id = os.getenv("SPACE_ID")
405
-
406
- if space_host:
407
- print(f"✅ Runtime: https://{space_host}.hf.space")
408
- if space_id:
409
- print(f"✅ Repo: https://huggingface.co/spaces/{space_id}")
410
-
411
- print("="*70 + "\n")
 
 
 
 
 
 
 
 
412
  demo.launch(debug=True, share=False)
 
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
5
+ from typing import Dict, List
 
 
6
 
7
+ # custom imports
8
+ from agents import Agent
9
+ from tool import get_tools
10
+ from model import get_model
11
+
12
+ # (Keep Constants as is)
13
  # --- Constants ---
14
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
15
+ MODEL_ID = "gemini/gemini-2.5-flash-preview-04-17"
16
 
17
+ # --- Async Question Processing ---
18
+ async def process_question(agent, question: str, task_id: str) -> Dict:
19
+ """Process a single question and return both answer AND full log entry"""
20
+ try:
21
+ answer = agent(question)
 
 
 
 
 
 
 
 
 
 
 
 
22
  return {
23
+ "submission": {"task_id": task_id, "submitted_answer": answer},
24
+ "log": {"Task ID": task_id, "Question": question, "Submitted Answer": answer}
 
 
 
 
 
 
 
 
 
 
 
 
25
  }
26
+ except Exception as e:
27
+ error_msg = f"ERROR: {str(e)}"
28
+ return {
29
+ "submission": {"task_id": task_id, "submitted_answer": error_msg},
30
+ "log": {"Task ID": task_id, "Question": question, "Submitted Answer": error_msg}
31
+ }
32
+
33
+ async def run_questions_async(agent, questions_data: List[Dict]) -> tuple:
34
+ """Process questions sequentially instead of in batch"""
35
+ submissions = []
36
+ logs = []
37
 
38
+ for q in questions_data:
39
+ result = await process_question(agent, q["question"], q["task_id"])
40
+ submissions.append(result["submission"])
41
+ logs.append(result["log"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ return submissions, logs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
 
46
+ async def run_and_submit_all( profile: gr.OAuthProfile | None):
47
  """
48
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
49
+ and displays the results.
50
  """
51
+ # --- Determine HF Space Runtime URL and Repo URL ---
52
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
53
 
54
  if profile:
55
+ username= f"{profile.username}"
56
+ print(f"User logged in: {username}")
57
  else:
58
+ print("User not logged in.")
59
+ return "Please Login to Hugging Face with the button.", None
60
 
61
  api_url = DEFAULT_API_URL
62
  questions_url = f"{api_url}/questions"
63
  submit_url = f"{api_url}/submit"
64
 
65
+ # 1. Instantiate Agent
66
  try:
67
+ agent = Agent(
68
+ model=get_model("LiteLLMModel", MODEL_ID),
69
+ tools=get_tools()
70
+ )
71
  except Exception as e:
72
+ print(f"Error instantiating agent: {e}")
73
+ return f"Error initializing agent: {e}", None
74
+ # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
75
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
76
+ print(agent_code)
77
 
78
  # 2. Fetch Questions
79
+ print(f"Fetching questions from: {questions_url}")
80
  try:
81
  response = requests.get(questions_url, timeout=15)
82
  response.raise_for_status()
83
  questions_data = response.json()
84
+ if not questions_data:
85
+ print("Fetched questions list is empty.")
86
+ return "Fetched questions list is empty or invalid format.", None
87
+ print(f"Fetched {len(questions_data)} questions.")
88
+ questions_data = questions_data[:2]
89
+ except requests.exceptions.RequestException as e:
90
+ print(f"Error fetching questions: {e}")
91
  return f"Error fetching questions: {e}", None
92
+ except requests.exceptions.JSONDecodeError as e:
93
+ print(f"Error decoding JSON response from questions endpoint: {e}")
94
+ print(f"Response text: {response.text[:500]}")
95
+ return f"Error decoding server response for questions: {e}", None
96
+ except Exception as e:
97
+ print(f"An unexpected error occurred fetching questions: {e}")
98
+ return f"An unexpected error occurred fetching questions: {e}", None
99
 
100
+ # 3. Run your Agent
101
+ print(f"Running agent on {len(questions_data)} questions...")
102
+ answers_payload, results_log = await run_questions_async(agent, questions_data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  if not answers_payload:
105
+ print("Agent did not produce any answers to submit.")
106
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
107
 
108
+ # 4. Prepare Submission
109
+ submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
110
+ status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
111
+ print(status_update)
112
+
113
+ # 5. Submit
114
+ print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
 
 
115
  try:
116
  response = requests.post(submit_url, json=submission_data, timeout=60)
117
  response.raise_for_status()
118
+ result_data = response.json()
119
+ final_status = (
120
+ f"Submission Successful!\n"
121
+ f"User: {result_data.get('username')}\n"
122
+ f"Overall Score: {result_data.get('score', 'N/A')}% "
123
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
124
+ f"Message: {result_data.get('message', 'No message received.')}"
 
 
 
 
 
125
  )
126
+ print("Submission successful.")
127
+ results_df = pd.DataFrame(results_log)
128
+ return final_status, results_df
 
 
 
 
129
  except requests.exceptions.HTTPError as e:
130
+ error_detail = f"Server responded with status {e.response.status_code}."
131
  try:
132
+ error_json = e.response.json()
133
+ error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
134
+ except requests.exceptions.JSONDecodeError:
135
+ error_detail += f" Response: {e.response.text[:500]}"
136
+ status_message = f"Submission Failed: {error_detail}"
137
+ print(status_message)
138
+ results_df = pd.DataFrame(results_log)
139
+ return status_message, results_df
140
+ except requests.exceptions.Timeout:
141
+ status_message = "Submission Failed: The request timed out."
142
+ print(status_message)
143
+ results_df = pd.DataFrame(results_log)
144
+ return status_message, results_df
145
+ except requests.exceptions.RequestException as e:
146
+ status_message = f"Submission Failed: Network error - {e}"
147
+ print(status_message)
148
+ results_df = pd.DataFrame(results_log)
149
+ return status_message, results_df
150
  except Exception as e:
151
+ status_message = f"An unexpected error occurred during submission: {e}"
152
+ print(status_message)
153
+ results_df = pd.DataFrame(results_log)
154
+ return status_message, results_df
155
 
156
 
157
+ # --- Build Gradio Interface using Blocks ---
158
+ with gr.Blocks() as demo:
159
+ gr.Markdown("# Basic Agent Evaluation Runner")
160
  gr.Markdown(
161
  """
162
+ **Instructions:**
163
+ 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
164
+ 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
165
+ 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
 
 
 
 
 
 
 
 
 
 
 
166
  """
167
  )
168
 
169
  gr.LoginButton()
170
+
171
+ run_button = gr.Button("Run Evaluation & Submit All Answers")
172
+
173
+ status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
174
+ # Removed max_rows=10 from DataFrame constructor
175
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
 
 
 
 
 
 
 
 
 
176
 
177
  run_button.click(
178
  fn=run_and_submit_all,
 
180
  )
181
 
182
  if __name__ == "__main__":
183
+ print("\n" + "-"*30 + " App Starting " + "-"*30)
184
+ # Check for SPACE_HOST and SPACE_ID at startup for information
185
+ space_host_startup = os.getenv("SPACE_HOST")
186
+ space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
187
+
188
+ if space_host_startup:
189
+ print(f"✅ SPACE_HOST found: {space_host_startup}")
190
+ print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
191
+ else:
192
+ print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
193
+
194
+ if space_id_startup: # Print repo URLs if SPACE_ID is found
195
+ print(f" SPACE_ID found: {space_id_startup}")
196
+ print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
197
+ print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
198
+ else:
199
+ print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
200
+
201
+ print("-"*(60 + len(" App Starting ")) + "\n")
202
+
203
+ print("Launching Gradio Interface for Basic Agent Evaluation...")
204
  demo.launch(debug=True, share=False)