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

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +169 -145
app.py CHANGED
@@ -6,24 +6,32 @@ import requests
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
 
22
  # --- Define the default API URL ---
23
- DEFAULT_API_URL = "https://agent-challenge.hf.space/agent_challenge" # Or the correct API URL if different
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,7 +57,7 @@ else:
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,6 +87,11 @@ def web_search(query: str) -> list[dict]:
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):
@@ -109,18 +122,17 @@ def web_search(query: str) -> list[dict]:
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,8 +149,11 @@ class BasicAgent:
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,158 +192,131 @@ class BasicAgent:
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,8 +347,8 @@ Search Query:"""
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
 
@@ -473,8 +461,8 @@ def run_and_submit_all( profile: gr.OAuthProfile | None, other_arg=None): # Modi
473
  return "Please Login to Hugging Face with the button.", None
474
 
475
  api_url = DEFAULT_API_URL
476
- questions_url = f"{api_url}/questions"
477
- submit_url = f"{api_url}/submit"
478
 
479
  # 1. Instantiate Agent ( modify this part to create your agent)
480
  print("Attempting to instantiate BasicAgent...") # Debugging print before instantiation
@@ -602,6 +590,25 @@ def run_and_submit_all( profile: gr.OAuthProfile | None, other_arg=None): # Modi
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,8 +621,8 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Basic Agent Evaluation Runner") as
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,18 +633,35 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Basic Agent Evaluation Runner") as
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__":
 
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
 
29
  # --- Define the default API URL ---
30
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space" # Updated API URL
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
 
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
  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):
 
122
  return results # Always return a list (empty or with results)
123
 
124
 
125
+ # --- Basic Agent Definition (Modified to remove LLM dependency for now) ---
126
  class BasicAgent:
127
 
128
  def __init__(self):
129
  print("BasicAgent initialized.") # Debugging print before init
130
+ # Removed LLM check as it's not used here
131
+ # global gemini_model # Access global variable
132
+ # if gemini_model is None:
133
+ # print("Warning: Google Generative AI model not successfully loaded before agent initialization.")
134
+ # else:
135
+ # print("Google Generative AI model found and ready.") # Debugging print after successful init
 
136
 
137
  def process_video(self, video_source: str) -> str:
138
  """
 
149
  cap = None
150
  try:
151
  # Attempt to open the video source
152
+ # Using cv2.CAP_FFMPEG might help with URLs, but requires FFmpeg
153
+ # cap = cv2.VideoCapture(video_source, cv2.CAP_FFMPEG)
154
  cap = cv2.VideoCapture(video_source)
155
 
156
+
157
  # Check if the video was opened successfully
158
  if not cap.isOpened():
159
  print(f"Error: Could not open video source {video_source}")
 
192
  cap.release()
193
  print("Video capture released.")
194
 
195
+ def process_audio(self, audio_source: str) -> str:
196
+ """
197
+ Processes an audio source (file path), extracts speech, and performs
198
+ placeholder audio analysis.
199
+
200
+ Args:
201
+ audio_source: Path to the audio file.
202
+
203
+ Returns:
204
+ A string summarizing the audio processing result or an error message.
205
+ """
206
+ print(f"Processing audio source: {audio_source}")
207
+ recognizer = sr.Recognizer()
208
+ try:
209
+ # Load the audio file
210
+ audio = AudioSegment.from_file(audio_source)
211
+ print(f"Audio loaded. Duration: {len(audio)} ms")
212
+
213
+ # Export to a format SpeechRecognition can handle (e.g., WAV)
214
+ with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as fp:
215
+ audio.export(fp.name, format="wav")
216
+ temp_wav_file = fp.name
217
+ print(f"Audio exported to temporary WAV: {temp_wav_file}")
218
+
219
+ # Use SpeechRecognition to transcribe the audio
220
+ with sr.AudioFile(temp_wav_file) as source:
221
+ print("Reading audio file for transcription...")
222
+ audio_data = recognizer.record(source) # read the entire audio file
223
+ print("Audio data recorded.")
224
+
225
+ # Attempt to recognize speech
226
+ try:
227
+ print("Attempting speech recognition...")
228
+ text = recognizer.recognize_google(audio_data) # Using Google Web Speech API
229
+ print(f"Transcription result: {text}")
230
+ return f"Audio processed. Transcription: '{text}'"
231
+ except sr.UnknownValueError:
232
+ print("Speech Recognition could not understand audio")
233
+ return "Audio processed, but could not understand speech."
234
+ except sr.RequestError as e:
235
+ print(f"Could not request results from Google Speech Recognition service; {e}")
236
+ return f"Audio processed, but speech recognition service failed: {e}"
237
+ except Exception as e:
238
+ print(f"An unexpected error occurred during speech recognition: {e}")
239
+ return f"An unexpected error occurred during speech recognition: {e}"
240
+
241
+ except Exception as e:
242
+ print(f"An error occurred during audio processing: {e}")
243
+ return f"An error occurred during audio processing: {e}"
244
+ finally:
245
+ # Clean up the temporary WAV file
246
+ if 'temp_wav_file' in locals() and os.path.exists(temp_wav_file):
247
+ os.remove(temp_wav_file)
248
+ print(f"Temporary WAV file removed: {temp_wav_file}")
249
+
250
 
251
+ def __call__(self, question: str, video_source: str | None = None, audio_source: str | None = None) -> str:
252
+ # Removed global gemini_model declaration as it's not used here
253
  print(f"Agent received question (first 50 chars): {question[:50]}...")
254
  print(f"Video source provided: {video_source}")
255
+ print(f"Audio source provided: {audio_source}")
256
 
257
+ # --- Check for media processing tasks ---
258
+ media_processing_results = []
259
  if video_source:
260
  print("Video source provided. Attempting video processing.")
261
  video_processing_result = self.process_video(video_source)
262
+ media_processing_results.append(f"Video processing result: {video_processing_result}")
263
+
264
+ if audio_source:
265
+ print("Audio source provided. Attempting audio processing.")
266
+ audio_processing_result = self.process_audio(audio_source)
267
+ media_processing_results.append(f"Audio processing result: {audio_processing_result}")
268
+
269
+ # If media was processed, return the results for now
270
+ if media_processing_results:
271
+ return "\n".join(media_processing_results)
272
 
273
 
274
+ # Simple logic to determine if a web search is needed (only if no media source)
275
  question_lower = question.lower()
276
  search_keywords = ["what is", "how to", "where is", "who is", "when did", "define", "explain", "tell me about"]
277
  needs_search = any(keyword in question_lower for keyword in search_keywords) or "?" in question
278
  print(f"Needs search: {needs_search}") # Debugging search decision
279
 
280
  # --- Analyze question and refine search query ---
281
+ # Simplified search query generation - removed LLM query generation
282
  search_query = question # Default search query is the original question
283
  if needs_search:
284
  print("Analyzing question for keywords and refining search query...")
285
+ # Basic keyword extraction: split by common question words and take the rest
286
+ parts = question_lower.split("what is", 1)
287
+ if len(parts) > 1:
288
+ search_query = parts[1].strip()
289
+ else:
290
+ parts = question_lower.split("how to", 1)
291
+ if len(parts) > 1:
292
+ search_query = parts[1].strip()
293
+ else:
294
+ parts = question_lower.split("where is", 1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  if len(parts) > 1:
296
  search_query = parts[1].strip()
297
  else:
298
+ parts = question_lower.split("who is", 1)
299
+ if len(parts) > 1:
300
+ search_query = parts[1].strip()
301
+ else:
302
+ parts = question_lower.split("when did", 1)
303
  if len(parts) > 1:
304
  search_query = parts[1].strip()
305
  else:
306
+ parts = question_lower.split("define", 1)
307
  if len(parts) > 1:
308
  search_query = parts[1].strip()
309
  else:
310
+ parts = question_lower.split("explain", 1)
311
  if len(parts) > 1:
312
  search_query = parts[1].strip()
313
  else:
314
+ parts = question_lower.split("tell me about", 1)
315
  if len(parts) > 1:
316
  search_query = parts[1].strip()
317
  else:
318
+ # If no specific question keyword found, use the whole question
319
+ search_query = question_lower.strip()
 
 
 
320
 
321
 
322
  # Optional: Add quotation marks for multi-word phrases if identified
 
347
  print(f"An error occurred during web search: {e}")
348
  return f"An error occurred during web search: {e}"
349
 
350
+ # --- Use LLM to process search results if available (Removed LLM Synthesis) ---
351
+ # Check that search_results is a list and is not empty
352
  if isinstance(search_results, list) and search_results and gemini_model is not None:
353
  print("Using Google LLM to process search results.") # Debugging print before LLM call
354
 
 
461
  return "Please Login to Hugging Face with the button.", None
462
 
463
  api_url = DEFAULT_API_URL
464
+ questions_url = f"{api_url}/agent_challenge/questions" # Corrected endpoint
465
+ submit_url = f"{api_url}/agent_challenge/submit" # Corrected endpoint
466
 
467
  # 1. Instantiate Agent ( modify this part to create your agent)
468
  print("Attempting to instantiate BasicAgent...") # Debugging print before instantiation
 
590
  return status_message, results_df
591
 
592
 
593
+ # Function to call process_video directly for testing
594
+ def test_video_processing(video_source: str) -> str:
595
+ print(f"Testing video processing with source: {video_source}")
596
+ try:
597
+ agent = BasicAgent()
598
+ return agent.process_video(video_source)
599
+ except Exception as e:
600
+ return f"Error during video processing test: {e}"
601
+
602
+ # Function to call process_audio directly for testing
603
+ def test_audio_processing(audio_source: str) -> str:
604
+ print(f"Testing audio processing with source: {audio_source}")
605
+ try:
606
+ agent = BasicAgent()
607
+ return agent.process_audio(audio_source)
608
+ except Exception as e:
609
+ return f"Error during audio processing test: {e}"
610
+
611
+
612
  # Move Gradio interface definition and launch outside the function
613
  with gr.Blocks(theme=gr.themes.Soft(), title="Basic Agent Evaluation Runner") as demo:
614
  gr.Markdown(
 
621
  1. Ensure your agent logic is defined in the `BasicAgent` class above.
622
  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).**
623
  3. Log in to Hugging Face using the button below.
624
+ 4. Click the "Run Evaluation & Submit All Answers" button to run on predefined questions.
625
+ 5. Use the "Test Video Processing" and "Test Audio Processing" sections to test media analysis.
626
  """
627
  )
628
  login_btn = gr.LoginButton()
 
633
  status_output = gr.Textbox(label="Run Status", interactive=False, lines=5)
634
  results_output = gr.DataFrame(label="Evaluation Results")
635
 
 
 
 
636
  run_button.click(
637
  run_and_submit_all,
638
+ inputs=[login_btn], # Pass the profile from the login button
 
639
  outputs=[status_output, results_output]
640
  )
641
+
642
+ gr.Markdown("---") # Separator
643
+ gr.Markdown("## Test Media Processing")
644
+
645
+ video_test_input = gr.Video(label="Upload Video or Paste URL")
646
+ video_test_button = gr.Button("Test Video Processing")
647
+ video_test_output = gr.Textbox(label="Video Processing Result", interactive=False)
648
+
649
+ video_test_button.click(
650
+ test_video_processing,
651
+ inputs=[video_test_input],
652
+ outputs=[video_test_output]
653
+ )
654
+
655
+ audio_test_input = gr.Audio(label="Upload Audio or Paste URL")
656
+ audio_test_button = gr.Button("Test Audio Processing")
657
+ audio_test_output = gr.Textbox(label="Audio Processing Result", interactive=False)
658
+
659
+ audio_test_button.click(
660
+ test_audio_processing,
661
+ inputs=[audio_test_input],
662
+ outputs=[audio_test_output]
663
+ )
664
+
665
 
666
  # Ensure the app launches when the script is run
667
  if __name__ == "__main__":