Abbasid commited on
Commit
f9b5dc1
·
verified ·
1 Parent(s): c442836

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +119 -28
app.py CHANGED
@@ -1,9 +1,7 @@
1
  """
2
  app.py
3
-
4
  This script provides the Gradio web interface to run the evaluation.
5
- This version has been corrected to be "file-aware" by checking for a 'file_url'
6
- in the task data and appending it to the agent's prompt.
7
  """
8
 
9
  import os
@@ -11,13 +9,14 @@ import re
11
  import gradio as gr
12
  import requests
13
  import pandas as pd
 
14
 
15
  from agent import create_agent_executor
16
 
17
  # --- Constants ---
18
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
19
 
20
- # --- Helper function to parse the agent's output (This is correct) ---
21
  def parse_final_answer(agent_response: str) -> str:
22
  match = re.search(r"FINAL ANSWER:\s*(.*)", agent_response, re.IGNORECASE | re.DOTALL)
23
  if match: return match.group(1).strip()
@@ -25,6 +24,74 @@ def parse_final_answer(agent_response: str) -> str:
25
  if lines: return lines[-1].strip()
26
  return "Could not parse a final answer."
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  def run_and_submit_all(profile: gr.OAuthProfile | None):
30
  """
@@ -45,7 +112,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
45
  # 1. Instantiate Agent
46
  print("Initializing your custom agent...")
47
  try:
48
- agent_executor = create_agent_executor(provider="groq") # Using Google for better tool use
49
  except Exception as e:
50
  return f"Fatal Error: Could not initialize agent. Check logs. Details: {e}", None
51
 
@@ -62,29 +129,29 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
62
  # 3. Run your Agent
63
  results_log, answers_payload = [], []
64
  print(f"Running agent on {len(questions_data)} questions...")
 
65
  for i, item in enumerate(questions_data):
66
  task_id = item.get("task_id")
67
  question_text = item.get("question")
68
- if not task_id or question_text is None: continue
 
69
 
70
  print(f"\n--- Running Task {i+1}/{len(questions_data)} (ID: {task_id}) ---")
71
 
72
- # --- THIS IS THE CRITICAL FIX ---
73
- # 1. Check if a 'file_url' key exists in the task data.
74
  file_url = item.get("file_url")
75
- full_question_text = question_text
76
-
77
- # 2. If a URL exists, append it to the question text.
 
78
  if file_url:
79
- print(f"File found for this task: {file_url}")
80
- # This gives the agent the context it needs to call the right tool.
81
- full_question_text = f"{question_text}\n\n[Attachment URL: {file_url}]"
82
 
83
- print(f"Full Prompt for Agent:\n{full_question_text}")
84
- # --- END CRITICAL FIX ---
85
 
86
  try:
87
- # 3. Pass the full, potentially enriched, question text to the agent.
88
  result = agent_executor.invoke({"messages": [("user", full_question_text)]})
89
 
90
  raw_answer = result['messages'][-1].content
@@ -94,10 +161,25 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
94
  print(f"PARSED FINAL ANSWER: '{submitted_answer}'")
95
 
96
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
97
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
 
 
 
 
 
 
98
  except Exception as e:
99
- print(f"!! AGENT ERROR on task {task_id}: {e}")
100
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT RUNTIME ERROR: {e}"})
 
 
 
 
 
 
 
 
101
 
102
  if not answers_payload:
103
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
@@ -109,23 +191,32 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
109
  response = requests.post(submit_url, json=submission_data, timeout=60)
110
  response.raise_for_status()
111
  result_data = response.json()
112
- final_status = (f"Submission Successful!\nUser: {result_data.get('username')}\nOverall Score: {result_data.get('score', 'N/A')}%")
 
 
113
  return final_status, pd.DataFrame(results_log)
114
  except Exception as e:
115
  status_message = f"Submission Failed: {e}"
116
  print(status_message)
117
  return status_message, pd.DataFrame(results_log)
118
 
119
- # --- Gradio UI (This part is correct) ---
120
- with gr.Blocks() as demo:
121
- gr.Markdown("# Agent Evaluation Runner")
122
- # ... (rest of the Gradio code is fine)
 
123
  gr.LoginButton()
124
  run_button = gr.Button("Run Evaluation & Submit All Answers", variant="primary")
125
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=4, interactive=False)
126
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True, row_count=10)
 
 
 
 
 
 
127
  run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table])
128
 
129
  if __name__ == "__main__":
130
- print("\n" + "-"*30 + " App Starting " + "-"*30)
131
  demo.launch()
 
1
  """
2
  app.py
 
3
  This script provides the Gradio web interface to run the evaluation.
4
+ This version properly handles multimodal inputs including images, videos, and audio.
 
5
  """
6
 
7
  import os
 
9
  import gradio as gr
10
  import requests
11
  import pandas as pd
12
+ from urllib.parse import urlparse
13
 
14
  from agent import create_agent_executor
15
 
16
  # --- Constants ---
17
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
18
 
19
+ # --- Helper function to parse the agent's output ---
20
  def parse_final_answer(agent_response: str) -> str:
21
  match = re.search(r"FINAL ANSWER:\s*(.*)", agent_response, re.IGNORECASE | re.DOTALL)
22
  if match: return match.group(1).strip()
 
24
  if lines: return lines[-1].strip()
25
  return "Could not parse a final answer."
26
 
27
+ def detect_file_type(url: str) -> str:
28
+ """Detect the type of file from URL."""
29
+ if not url:
30
+ return "unknown"
31
+
32
+ url_lower = url.lower()
33
+
34
+ # Image extensions
35
+ if any(ext in url_lower for ext in ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg']):
36
+ return "image"
37
+
38
+ # Video extensions and YouTube
39
+ if any(domain in url_lower for domain in ['youtube.com', 'youtu.be', 'vimeo.com']):
40
+ return "youtube"
41
+ if any(ext in url_lower for ext in ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.webm']):
42
+ return "video"
43
+
44
+ # Audio extensions
45
+ if any(ext in url_lower for ext in ['.mp3', '.wav', '.flac', '.aac', '.ogg', '.m4a']):
46
+ return "audio"
47
+
48
+ # Try to detect from headers if possible
49
+ try:
50
+ response = requests.head(url, timeout=5)
51
+ content_type = response.headers.get('content-type', '').lower()
52
+
53
+ if 'image' in content_type:
54
+ return "image"
55
+ elif 'audio' in content_type:
56
+ return "audio"
57
+ elif 'video' in content_type:
58
+ return "video"
59
+ except:
60
+ pass
61
+
62
+ return "unknown"
63
+
64
+ def create_enhanced_prompt(question_text: str, file_url: str = None) -> str:
65
+ """Create an enhanced prompt that guides the agent to use appropriate tools."""
66
+
67
+ if not file_url:
68
+ return question_text
69
+
70
+ file_type = detect_file_type(file_url)
71
+
72
+ if file_type == "image":
73
+ return f"""{question_text}
74
+
75
+ [IMAGE ATTACHMENT]: {file_url}
76
+ INSTRUCTION: There is an image attached to this question. You MUST use the 'describe_image' tool to analyze this image before answering the question."""
77
+
78
+ elif file_type == "youtube":
79
+ return f"""{question_text}
80
+
81
+ [YOUTUBE VIDEO]: {file_url}
82
+ INSTRUCTION: There is a YouTube video attached to this question. You MUST use the 'process_youtube_video' tool to analyze this video before answering the question."""
83
+
84
+ elif file_type == "audio":
85
+ return f"""{question_text}
86
+
87
+ [AUDIO FILE]: {file_url}
88
+ INSTRUCTION: There is an audio file attached to this question. You MUST use the 'process_audio_file' tool to analyze this audio before answering the question."""
89
+
90
+ else:
91
+ return f"""{question_text}
92
+
93
+ [ATTACHMENT]: {file_url}
94
+ INSTRUCTION: There is a file attachment. Analyze the URL and use the appropriate tool to process this content before answering the question."""
95
 
96
  def run_and_submit_all(profile: gr.OAuthProfile | None):
97
  """
 
112
  # 1. Instantiate Agent
113
  print("Initializing your custom agent...")
114
  try:
115
+ agent_executor = create_agent_executor(provider="google") # Using Google for better multimodal support
116
  except Exception as e:
117
  return f"Fatal Error: Could not initialize agent. Check logs. Details: {e}", None
118
 
 
129
  # 3. Run your Agent
130
  results_log, answers_payload = [], []
131
  print(f"Running agent on {len(questions_data)} questions...")
132
+
133
  for i, item in enumerate(questions_data):
134
  task_id = item.get("task_id")
135
  question_text = item.get("question")
136
+ if not task_id or question_text is None:
137
+ continue
138
 
139
  print(f"\n--- Running Task {i+1}/{len(questions_data)} (ID: {task_id}) ---")
140
 
141
+ # Get file URL if it exists
 
142
  file_url = item.get("file_url")
143
+
144
+ # Create enhanced prompt that instructs the agent to use appropriate tools
145
+ full_question_text = create_enhanced_prompt(question_text, file_url)
146
+
147
  if file_url:
148
+ file_type = detect_file_type(file_url)
149
+ print(f"File detected: {file_url} (Type: {file_type})")
 
150
 
151
+ print(f"Enhanced Prompt for Agent:\n{full_question_text}")
 
152
 
153
  try:
154
+ # Pass the enhanced question to the agent
155
  result = agent_executor.invoke({"messages": [("user", full_question_text)]})
156
 
157
  raw_answer = result['messages'][-1].content
 
161
  print(f"PARSED FINAL ANSWER: '{submitted_answer}'")
162
 
163
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
164
+ results_log.append({
165
+ "Task ID": task_id,
166
+ "Question": question_text,
167
+ "File URL": file_url or "None",
168
+ "File Type": detect_file_type(file_url) if file_url else "None",
169
+ "Submitted Answer": submitted_answer
170
+ })
171
+
172
  except Exception as e:
173
+ print(f"!! AGENT ERROR on task {task_id}: {e}")
174
+ error_msg = f"AGENT RUNTIME ERROR: {e}"
175
+ answers_payload.append({"task_id": task_id, "submitted_answer": error_msg})
176
+ results_log.append({
177
+ "Task ID": task_id,
178
+ "Question": question_text,
179
+ "File URL": file_url or "None",
180
+ "File Type": detect_file_type(file_url) if file_url else "None",
181
+ "Submitted Answer": error_msg
182
+ })
183
 
184
  if not answers_payload:
185
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
 
191
  response = requests.post(submit_url, json=submission_data, timeout=60)
192
  response.raise_for_status()
193
  result_data = response.json()
194
+ final_status = (f"Submission Successful!\nUser: {result_data.get('username')}\n"
195
+ f"Overall Score: {result_data.get('score', 'N/A')}%\n"
196
+ f"Processed {len([r for r in results_log if 'ERROR' not in r['Submitted Answer']])} successful tasks")
197
  return final_status, pd.DataFrame(results_log)
198
  except Exception as e:
199
  status_message = f"Submission Failed: {e}"
200
  print(status_message)
201
  return status_message, pd.DataFrame(results_log)
202
 
203
+ # --- Gradio UI ---
204
+ with gr.Blocks(title="Multimodal Agent Evaluation") as demo:
205
+ gr.Markdown("# Multimodal Agent Evaluation Runner")
206
+ gr.Markdown("This agent can process images, YouTube videos, audio files, and perform web searches.")
207
+
208
  gr.LoginButton()
209
  run_button = gr.Button("Run Evaluation & Submit All Answers", variant="primary")
210
+ status_output = gr.Textbox(label="Run Status / Submission Result", lines=6, interactive=False)
211
+ results_table = gr.DataFrame(
212
+ label="Questions and Agent Answers",
213
+ wrap=True,
214
+ row_count=10,
215
+ column_widths=[80, 200, 150, 80, 200]
216
+ )
217
+
218
  run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table])
219
 
220
  if __name__ == "__main__":
221
+ print("\n" + "-"*30 + " Multimodal App Starting " + "-"*30)
222
  demo.launch()