Carolzinha2010 commited on
Commit
21d92ed
·
verified ·
1 Parent(s): 72e96fc

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +144 -166
app.py CHANGED
@@ -6,23 +6,16 @@ import requests
6
  import inspect
7
  import pandas as pd
8
  import cv2 # Import opencv-python for video processing
9
- import speech_recognition as sr # Import SpeechRecognition for audio processing
10
- from pydub import AudioSegment # Import pydub for audio manipulation
11
- import tempfile # Import tempfile for temporary file handling
12
- import numpy as np # Import numpy for image processing
13
 
14
-
15
- # Import libraries for SerpAPI
16
  from serpapi import GoogleSearch
17
- import google.generativeai as genai # Keep the import as the user might add LLM functionality back later
18
-
19
 
20
  # --- Get API Keys from Environment Variables ---
21
  # SERPAPI_API_KEY and GOOGLE_API_KEY should be set as secrets in your Hugging Face Space
22
  SERPAPI_API_KEY = os.getenv('SERPAPI_API_KEY')
23
  print(f"SERPAPI_API_KEY (first 5 chars): {SERPAPI_API_KEY[:5] if SERPAPI_API_KEY else 'None'}...") # Debugging API key
24
 
25
- # Keep GOOGLE_API_KEY handling as the user might add LLM functionality back later
26
  GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
27
  print(f"GOOGLE_API_KEY (first 5 chars): {GOOGLE_API_KEY[:5] if GOOGLE_API_KEY else 'None'}...") # Debugging API key
28
 
@@ -31,7 +24,6 @@ DEFAULT_API_URL = "https://agent-challenge.hf.space/agent_challenge" # Or the co
31
 
32
 
33
  # --- Google Generative AI LLM Initialization ---
34
- # Keep LLM initialization but handle potential errors and None state
35
  print("Attempting to initialize Google Generative AI model...") # Debugging print before loading
36
 
37
  gemini_model = None # Initialize to None
@@ -57,7 +49,7 @@ else:
57
 
58
  # --- Web Search Function (using SerpAPI) ---
59
  def web_search(query: str) -> list[dict]:
60
- # Removed global gemini_model declaration as it's not used here
61
  """
62
  Performs a web search using SerpAPI and returns relevant information.
63
 
@@ -87,11 +79,6 @@ def web_search(query: str) -> list[dict]:
87
  search_results_dict = search.get_dict() # Get results as a dictionary
88
  print(f"SerpAPI raw response keys: {search_results_dict.keys() if isinstance(search_results_dict, dict) else 'Response is not a dictionary'}") # Debugging response keys
89
 
90
- # Log the full SerpAPI response for debugging if organic_results is missing or empty
91
- if not isinstance(search_results_dict, dict) or "organic_results" not in search_results_dict or not isinstance(search_results_dict["organic_results"], list) or not search_results_dict["organic_results"]:
92
- print(f"SerpAPI response did not contain organic results or had invalid format. Response: {search_results_dict}")
93
-
94
-
95
  # Extract organic results
96
  # Add check that search_results_dict and organic_results are valid
97
  if isinstance(search_results_dict, dict) and "organic_results" in search_results_dict and isinstance(search_results_dict["organic_results"], list):
@@ -109,6 +96,8 @@ def web_search(query: str) -> list[dict]:
109
  results.append(item)
110
  else:
111
  print(f"No 'organic_results' key found or invalid format in SerpAPI response. Response type: {type(search_results_dict)}")
 
 
112
 
113
 
114
  except Exception as e:
@@ -120,17 +109,18 @@ def web_search(query: str) -> list[dict]:
120
  return results # Always return a list (empty or with results)
121
 
122
 
123
- # --- Basic Agent Definition (Modified to remove LLM dependency for now) ---
124
  class BasicAgent:
125
 
126
  def __init__(self):
127
  print("BasicAgent initialized.") # Debugging print before init
128
- # Removed LLM check as it's not used here
129
- # global gemini_model # Access global variable
130
- # if gemini_model is None:
131
- # print("Warning: Google Generative AI model not successfully loaded before agent initialization.")
132
- # else:
133
- # print("Google Generative AI model found and ready.") # Debugging print after successful init
 
134
 
135
  def process_video(self, video_source: str) -> str:
136
  """
@@ -147,11 +137,8 @@ class BasicAgent:
147
  cap = None
148
  try:
149
  # Attempt to open the video source
150
- # Using cv2.CAP_FFMPEG might help with URLs, but requires FFmpeg
151
- # cap = cv2.VideoCapture(video_source, cv2.CAP_FFMPEG)
152
  cap = cv2.VideoCapture(video_source)
153
 
154
-
155
  # Check if the video was opened successfully
156
  if not cap.isOpened():
157
  print(f"Error: Could not open video source {video_source}")
@@ -190,131 +177,158 @@ class BasicAgent:
190
  cap.release()
191
  print("Video capture released.")
192
 
193
- def process_audio(self, audio_source: str) -> str:
194
- """
195
- Processes an audio source (file path), extracts speech, and performs
196
- placeholder audio analysis.
197
-
198
- Args:
199
- audio_source: Path to the audio file.
200
-
201
- Returns:
202
- A string summarizing the audio processing result or an error message.
203
- """
204
- print(f"Processing audio source: {audio_source}")
205
- recognizer = sr.Recognizer()
206
- try:
207
- # Load the audio file
208
- audio = AudioSegment.from_file(audio_source)
209
- print(f"Audio loaded. Duration: {len(audio)} ms")
210
-
211
- # Export to a format SpeechRecognition can handle (e.g., WAV)
212
- with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as fp:
213
- audio.export(fp.name, format="wav")
214
- temp_wav_file = fp.name
215
- print(f"Audio exported to temporary WAV: {temp_wav_file}")
216
-
217
- # Use SpeechRecognition to transcribe the audio
218
- with sr.AudioFile(temp_wav_file) as source:
219
- print("Reading audio file for transcription...")
220
- audio_data = recognizer.record(source) # read the entire audio file
221
- print("Audio data recorded.")
222
-
223
- # Attempt to recognize speech
224
- try:
225
- print("Attempting speech recognition...")
226
- text = recognizer.recognize_google(audio_data) # Using Google Web Speech API
227
- print(f"Transcription result: {text}")
228
- return f"Audio processed. Transcription: '{text}'"
229
- except sr.UnknownValueError:
230
- print("Speech Recognition could not understand audio")
231
- return "Audio processed, but could not understand speech."
232
- except sr.RequestError as e:
233
- print(f"Could not request results from Google Speech Recognition service; {e}")
234
- return f"Audio processed, but speech recognition service failed: {e}"
235
- except Exception as e:
236
- print(f"An unexpected error occurred during speech recognition: {e}")
237
- return f"An unexpected error occurred during speech recognition: {e}"
238
-
239
- except Exception as e:
240
- print(f"An error occurred during audio processing: {e}")
241
- return f"An error occurred during audio processing: {e}"
242
- finally:
243
- # Clean up the temporary WAV file
244
- if 'temp_wav_file' in locals() and os.path.exists(temp_wav_file):
245
- os.remove(temp_wav_file)
246
- print(f"Temporary WAV file removed: {temp_wav_file}")
247
-
248
 
249
- def __call__(self, question: str, video_source: str | None = None, audio_source: str | None = None) -> str:
250
- # Removed global gemini_model declaration as it's not used here
251
  print(f"Agent received question (first 50 chars): {question[:50]}...")
252
  print(f"Video source provided: {video_source}")
253
- print(f"Audio source provided: {audio_source}")
254
 
255
- # --- Check for media processing tasks ---
256
- media_processing_results = []
257
  if video_source:
258
  print("Video source provided. Attempting video processing.")
259
  video_processing_result = self.process_video(video_source)
260
- media_processing_results.append(f"Video processing result: {video_processing_result}")
261
-
262
- if audio_source:
263
- print("Audio source provided. Attempting audio processing.")
264
- audio_processing_result = self.process_audio(audio_source)
265
- media_processing_results.append(f"Audio processing result: {audio_processing_result}")
266
-
267
- # If media was processed, return the results for now
268
- if media_processing_results:
269
- return "\n".join(media_processing_results)
270
 
271
 
272
- # Simple logic to determine if a web search is needed (only if no media source)
273
  question_lower = question.lower()
274
  search_keywords = ["what is", "how to", "where is", "who is", "when did", "define", "explain", "tell me about"]
275
  needs_search = any(keyword in question_lower for keyword in search_keywords) or "?" in question
276
  print(f"Needs search: {needs_search}") # Debugging search decision
277
 
278
  # --- Analyze question and refine search query ---
279
- # Simplified search query generation - removed LLM query generation
280
  search_query = question # Default search query is the original question
281
  if needs_search:
282
  print("Analyzing question for keywords and refining search query...")
283
- # Basic keyword extraction: split by common question words and take the rest
284
- parts = question_lower.split("what is", 1)
285
- if len(parts) > 1:
286
- search_query = parts[1].strip()
287
- else:
288
- parts = question_lower.split("how to", 1)
289
- if len(parts) > 1:
290
- search_query = parts[1].strip()
291
- else:
292
- parts = question_lower.split("where is", 1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  if len(parts) > 1:
294
  search_query = parts[1].strip()
295
  else:
296
- parts = question_lower.split("who is", 1)
297
- if len(parts) > 1:
298
- search_query = parts[1].strip()
299
- else:
300
- parts = question_lower.split("when did", 1)
301
  if len(parts) > 1:
302
  search_query = parts[1].strip()
303
  else:
304
- parts = question_lower.split("define", 1)
305
  if len(parts) > 1:
306
  search_query = parts[1].strip()
307
  else:
308
- parts = question_lower.split("explain", 1)
309
  if len(parts) > 1:
310
  search_query = parts[1].strip()
311
  else:
312
- parts = question_lower.split("tell me about", 1)
313
  if len(parts) > 1:
314
  search_query = parts[1].strip()
315
  else:
316
- # If no specific question keyword found, use the whole question
317
- search_query = question_lower.strip()
 
 
 
318
 
319
 
320
  # Optional: Add quotation marks for multi-word phrases if identified
@@ -345,8 +359,8 @@ class BasicAgent:
345
  print(f"An error occurred during web search: {e}")
346
  return f"An error occurred during web search: {e}"
347
 
348
- # --- Use LLM to process search results if available (Removed LLM Synthesis) ---
349
- # Check that search_results is a list and is not empty
350
  if isinstance(search_results, list) and search_results and gemini_model is not None:
351
  print("Using Google LLM to process search results.") # Debugging print before LLM call
352
 
@@ -588,25 +602,6 @@ def run_and_submit_all( profile: gr.OAuthProfile | None, other_arg=None): # Modi
588
  return status_message, results_df
589
 
590
 
591
- # Function to call process_video directly for testing
592
- def test_video_processing(video_source: str) -> str:
593
- print(f"Testing video processing with source: {video_source}")
594
- try:
595
- agent = BasicAgent()
596
- return agent.process_video(video_source)
597
- except Exception as e:
598
- return f"Error during video processing test: {e}"
599
-
600
- # Function to call process_audio directly for testing
601
- def test_audio_processing(audio_source: str) -> str:
602
- print(f"Testing audio processing with source: {audio_source}")
603
- try:
604
- agent = BasicAgent()
605
- return agent.process_audio(audio_source)
606
- except Exception as e:
607
- return f"Error during audio processing test: {e}"
608
-
609
-
610
  # Move Gradio interface definition and launch outside the function
611
  with gr.Blocks(theme=gr.themes.Soft(), title="Basic Agent Evaluation Runner") as demo:
612
  gr.Markdown(
@@ -619,8 +614,8 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Basic Agent Evaluation Runner") as
619
  1. Ensure your agent logic is defined in the `BasicAgent` class above.
620
  2. **Get a SerpAPI key and a Google AI API key and add them as environment variables in your runtime environment (e.g., as secrets in your Hugging Face Space settings).**
621
  3. Log in to Hugging Face using the button below.
622
- 4. Click the "Run Evaluation & Submit All Answers" button to run on predefined questions.
623
- 5. Use the "Test Video Processing" and "Test Audio Processing" sections to test media analysis.
624
  """
625
  )
626
  login_btn = gr.LoginButton()
@@ -631,35 +626,18 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Basic Agent Evaluation Runner") as
631
  status_output = gr.Textbox(label="Run Status", interactive=False, lines=5)
632
  results_output = gr.DataFrame(label="Evaluation Results")
633
 
 
 
 
634
  run_button.click(
635
  run_and_submit_all,
636
- inputs=[login_btn], # Pass the profile from the login button
 
637
  outputs=[status_output, results_output]
638
  )
639
-
640
- gr.Markdown("---") # Separator
641
- gr.Markdown("## Test Media Processing")
642
-
643
- video_test_input = gr.Video(label="Upload Video or Paste URL")
644
- video_test_button = gr.Button("Test Video Processing")
645
- video_test_output = gr.Textbox(label="Video Processing Result", interactive=False)
646
-
647
- video_test_button.click(
648
- test_video_processing,
649
- inputs=[video_test_input],
650
- outputs=[video_test_output]
651
- )
652
-
653
- audio_test_input = gr.Audio(label="Upload Audio or Paste URL")
654
- audio_test_button = gr.Button("Test Audio Processing")
655
- audio_test_output = gr.Textbox(label="Audio Processing Result", interactive=False)
656
-
657
- audio_test_button.click(
658
- test_audio_processing,
659
- inputs=[audio_test_input],
660
- outputs=[audio_test_output]
661
- )
662
-
663
 
664
  # Ensure the app launches when the script is run
665
  if __name__ == "__main__":
 
6
  import inspect
7
  import pandas as pd
8
  import cv2 # Import opencv-python for video processing
 
 
 
 
9
 
10
+ # Import libraries for SerpAPI and Google Generative AI
 
11
  from serpapi import GoogleSearch
12
+ import google.generativeai as genai
 
13
 
14
  # --- Get API Keys from Environment Variables ---
15
  # SERPAPI_API_KEY and GOOGLE_API_KEY should be set as secrets in your Hugging Face Space
16
  SERPAPI_API_KEY = os.getenv('SERPAPI_API_KEY')
17
  print(f"SERPAPI_API_KEY (first 5 chars): {SERPAPI_API_KEY[:5] if SERPAPI_API_KEY else 'None'}...") # Debugging API key
18
 
 
19
  GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
20
  print(f"GOOGLE_API_KEY (first 5 chars): {GOOGLE_API_KEY[:5] if GOOGLE_API_KEY else 'None'}...") # Debugging API key
21
 
 
24
 
25
 
26
  # --- Google Generative AI LLM Initialization ---
 
27
  print("Attempting to initialize Google Generative AI model...") # Debugging print before loading
28
 
29
  gemini_model = None # Initialize to None
 
49
 
50
  # --- Web Search Function (using SerpAPI) ---
51
  def web_search(query: str) -> list[dict]:
52
+ global gemini_model # Ensure global declaration is first
53
  """
54
  Performs a web search using SerpAPI and returns relevant information.
55
 
 
79
  search_results_dict = search.get_dict() # Get results as a dictionary
80
  print(f"SerpAPI raw response keys: {search_results_dict.keys() if isinstance(search_results_dict, dict) else 'Response is not a dictionary'}") # Debugging response keys
81
 
 
 
 
 
 
82
  # Extract organic results
83
  # Add check that search_results_dict and organic_results are valid
84
  if isinstance(search_results_dict, dict) and "organic_results" in search_results_dict and isinstance(search_results_dict["organic_results"], list):
 
96
  results.append(item)
97
  else:
98
  print(f"No 'organic_results' key found or invalid format in SerpAPI response. Response type: {type(search_results_dict)}")
99
+ # Print the whole response if no organic_results are found for debugging
100
+ # print(f"SerpAPI response (no organic results): {search_results_dict}")
101
 
102
 
103
  except Exception as e:
 
109
  return results # Always return a list (empty or with results)
110
 
111
 
112
+ # --- Basic Agent Definition (Updated to use Google LLM and add video processing) ---
113
  class BasicAgent:
114
 
115
  def __init__(self):
116
  print("BasicAgent initialized.") # Debugging print before init
117
+ # Check if LLM is loaded (optional but good practice)
118
+ global gemini_model # Access global variable
119
+ if gemini_model is None:
120
+ print("Warning: Google Generative AI model not successfully loaded before agent initialization.")
121
+ # The agent can still perform search but won't use the LLM for synthesis
122
+ else:
123
+ print("Google Generative AI model found and ready.") # Debugging print after successful init
124
 
125
  def process_video(self, video_source: str) -> str:
126
  """
 
137
  cap = None
138
  try:
139
  # Attempt to open the video source
 
 
140
  cap = cv2.VideoCapture(video_source)
141
 
 
142
  # Check if the video was opened successfully
143
  if not cap.isOpened():
144
  print(f"Error: Could not open video source {video_source}")
 
177
  cap.release()
178
  print("Video capture released.")
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
+ def __call__(self, question: str, video_source: str | None = None) -> str:
182
+ global gemini_model # Ensure global declaration is first
183
  print(f"Agent received question (first 50 chars): {question[:50]}...")
184
  print(f"Video source provided: {video_source}")
 
185
 
186
+
187
+ # --- Check for video processing task ---
188
  if video_source:
189
  print("Video source provided. Attempting video processing.")
190
  video_processing_result = self.process_video(video_source)
191
+ # For now, the agent just reports on video processing.
192
+ # Future versions could integrate this with the LLM.
193
+ return f"Video processing requested. Result: {video_processing_result}"
 
 
 
 
 
 
 
194
 
195
 
196
+ # Simple logic to determine if a web search is needed (only if no video source)
197
  question_lower = question.lower()
198
  search_keywords = ["what is", "how to", "where is", "who is", "when did", "define", "explain", "tell me about"]
199
  needs_search = any(keyword in question_lower for keyword in search_keywords) or "?" in question
200
  print(f"Needs search: {needs_search}") # Debugging search decision
201
 
202
  # --- Analyze question and refine search query ---
 
203
  search_query = question # Default search query is the original question
204
  if needs_search:
205
  print("Analyzing question for keywords and refining search query...")
206
+ # Use LLM to generate search query if available
207
+ if gemini_model is not None:
208
+ print("Using LLM to generate search query.")
209
+ query_prompt = f"""Given the following question, generate the most effective web search query to find information to answer it.
210
+ Focus on extracting key entities and concepts. Do not include question words like "what is" or "how to".
211
+
212
+ Question: {question}
213
+
214
+ Search Query:"""
215
+ try:
216
+ response = gemini_model.generate_content(query_prompt)
217
+ generated_query = response.text.strip()
218
+ # Add check for empty or single-word query from LLM
219
+ if generated_query and len(generated_query.split()) > 1: # Ensure it's not empty or just one word
220
+ search_query = generated_query
221
+ print(f"LLM generated search query: {search_query}")
222
+ else:
223
+ print(f"LLM generated empty or single-word query: '{generated_query}'. Falling back to basic extraction.")
224
+ # Fallback to basic extraction if LLM fails
225
+ parts = question_lower.split("what is", 1)
226
+ if len(parts) > 1:
227
+ search_query = parts[1].strip()
228
+ else:
229
+ parts = question_lower.split("how to", 1)
230
+ if len(parts) > 1:
231
+ search_query = parts[1].strip()
232
+ else:
233
+ parts = question_lower.split("where is", 1)
234
+ if len(parts) > 1:
235
+ search_query = parts[1].strip()
236
+ else:
237
+ parts = question_lower.split("who is", 1)
238
+ if len(parts) > 1:
239
+ search_query = parts[1].strip()
240
+ else:
241
+ parts = question_lower.split("when did", 1)
242
+ if len(parts) > 1:
243
+ search_query = parts[1].strip()
244
+ else:
245
+ parts = question_lower.split("define", 1)
246
+ if len(parts) > 1:
247
+ search_query = parts[1].strip()
248
+ else:
249
+ parts = question_lower.split("explain", 1)
250
+ if len(parts) > 1:
251
+ search_query = parts[1].strip()
252
+ else:
253
+ parts = question_lower.split("tell me about", 1)
254
+ if len(parts) > 1:
255
+ search_query = parts[1].strip()
256
+ else:
257
+ search_query = question_lower.strip() # Fallback to whole question
258
+
259
+
260
+ except Exception as llm_e:
261
+ print(f"An error occurred during LLM search query generation: {llm_e}. Falling back to basic extraction.")
262
+ # Fallback to basic extraction if LLM call fails
263
+ parts = question_lower.split("what is", 1)
264
+ if len(parts) > 1:
265
+ search_query = parts[1].strip()
266
+ else:
267
+ parts = question_lower.split("how to", 1)
268
+ if len(parts) > 1:
269
+ search_query = parts[1].strip()
270
+ else:
271
+ parts = question_lower.split("where is", 1)
272
+ if len(parts) > 1:
273
+ search_query = parts[1].strip()
274
+ else:
275
+ parts = question_lower.split("who is", 1)
276
+ if len(parts) > 1:
277
+ search_query = parts[1].strip()
278
+ else:
279
+ parts = question_lower.split("when did", 1)
280
+ if len(parts) > 1:
281
+ search_query = parts[1].strip()
282
+ else:
283
+ parts = question_lower.split("define", 1)
284
+ if len(parts) > 1:
285
+ search_query = parts[1].strip()
286
+ else:
287
+ parts = question_lower.split("explain", 1)
288
+ if len(parts) > 1:
289
+ search_query = parts[1].strip()
290
+ else:
291
+ parts = question_lower.split("tell me about", 1)
292
+ if len(parts) > 1:
293
+ search_query = parts[1].strip()
294
+ else:
295
+ search_query = question_lower.strip() # Fallback to whole question
296
+ else: # LLM not available for query generation
297
+ print("LLM not available for query generation. Using basic search query extraction.")
298
+ # Fallback to basic extraction if LLM is not initialized
299
+ parts = question_lower.split("what is", 1)
300
+ if len(parts) > 1:
301
+ search_query = parts[1].strip()
302
+ else:
303
+ parts = question_lower.split("how to", 1)
304
  if len(parts) > 1:
305
  search_query = parts[1].strip()
306
  else:
307
+ parts = question_lower.split("where is", 1)
308
+ if len(parts) > 1:
309
+ search_query = parts[1].strip()
310
+ else:
311
+ parts = question_lower.split("who is", 1)
312
  if len(parts) > 1:
313
  search_query = parts[1].strip()
314
  else:
315
+ parts = question_lower.split("when did", 1)
316
  if len(parts) > 1:
317
  search_query = parts[1].strip()
318
  else:
319
+ parts = question_lower.split("define", 1)
320
  if len(parts) > 1:
321
  search_query = parts[1].strip()
322
  else:
323
+ parts = question_lower.split("explain", 1)
324
  if len(parts) > 1:
325
  search_query = parts[1].strip()
326
  else:
327
+ parts = question_lower.split("tell me about", 1)
328
+ if len(parts) > 1:
329
+ search_query = parts[1].strip()
330
+ else:
331
+ search_query = question_lower.strip() # Fallback to whole question
332
 
333
 
334
  # Optional: Add quotation marks for multi-word phrases if identified
 
359
  print(f"An error occurred during web search: {e}")
360
  return f"An error occurred during web search: {e}"
361
 
362
+ # --- Use LLM to process search results if available ---
363
+ # Add check that search_results is a list and not empty before proceeding
364
  if isinstance(search_results, list) and search_results and gemini_model is not None:
365
  print("Using Google LLM to process search results.") # Debugging print before LLM call
366
 
 
602
  return status_message, results_df
603
 
604
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605
  # Move Gradio interface definition and launch outside the function
606
  with gr.Blocks(theme=gr.themes.Soft(), title="Basic Agent Evaluation Runner") as demo:
607
  gr.Markdown(
 
614
  1. Ensure your agent logic is defined in the `BasicAgent` class above.
615
  2. **Get a SerpAPI key and a Google AI API key and add them as environment variables in your runtime environment (e.g., as secrets in your Hugging Face Space settings).**
616
  3. Log in to Hugging Face using the button below.
617
+ 4. Click the "Run Evaluation & Submit All Answers" button.
618
+ 5. The application will fetch questions, run your agent, submit answers, and display the results below.
619
  """
620
  )
621
  login_btn = gr.LoginButton()
 
626
  status_output = gr.Textbox(label="Run Status", interactive=False, lines=5)
627
  results_output = gr.DataFrame(label="Evaluation Results")
628
 
629
+ # Add Gradio components for video input
630
+ video_input = gr.Video(label="Upload Video or Paste URL (Optional)")
631
+
632
  run_button.click(
633
  run_and_submit_all,
634
+ # Pass the video_input to the function
635
+ inputs=[login_btn], # Modified to exclude video_input for now as run_and_submit_all doesn't use it
636
  outputs=[status_output, results_output]
637
  )
638
+ # Add a separate button or modify the existing one to handle video processing
639
+ # For this subtask, we are just adding the video processing capability to the agent,
640
+ # not fully integrating it into the Gradio submission flow yet.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
 
642
  # Ensure the app launches when the script is run
643
  if __name__ == "__main__":