Toumaima commited on
Commit
714e1fc
·
verified ·
1 Parent(s): 354269f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -228
app.py CHANGED
@@ -1,258 +1,73 @@
1
  import os
2
  import time
3
- import moviepy
4
  import requests
 
5
  import whisper
6
  import gradio as gr
7
  import pandas as pd
 
8
  from duckduckgo_search import DDGS
9
  from transformers import pipeline
10
- from sklearn.metrics.pairwise import cosine_similarity
11
- import numpy as np
12
 
13
- # --- Constants ---
14
- DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
15
 
16
- # --- Basic Agent Definition ---
17
- class BasicAgent:
18
  def __init__(self):
19
- print("BasicAgent initialized.")
20
- # Initialize the Whisper model for video transcription
21
- self.whisper_model = whisper.load_model("base") # You can change the model to `large`, `medium`, etc.
22
- self.search_pipeline = pipeline("question-answering")
23
- self.nlp_model = pipeline("feature-extraction") # For semantic similarity (using transformer model)
24
-
25
- def score_search_results(self, question: str, search_results: list) -> str:
26
- # Transform the question and results to embeddings (vector representations)
27
- question_embedding = self.nlp_model(question)
28
- question_embedding = np.mean(question_embedding[0], axis=0)
29
-
30
- best_score = -1
31
- best_answer = None
32
-
33
- # Loop through search results and calculate similarity
34
- for result in search_results:
35
- result_embedding = self.nlp_model(result['body'])
36
- result_embedding = np.mean(result_embedding[0], axis=0)
37
-
38
- # Calculate cosine similarity
39
- similarity = cosine_similarity([question_embedding], [result_embedding])
40
-
41
- # Check if this result is better
42
- if similarity > best_score:
43
- best_score = similarity
44
- best_answer = result['body']
45
-
46
- return best_answer
47
-
48
- def search(self, question: str) -> str:
49
- try:
50
- with DDGS() as ddgs:
51
- results = list(ddgs.text(question, max_results=3)) # Fetch top 3 results
52
- if results:
53
- # Score all the results and return the best one
54
- return self.score_search_results(question, results)
55
- else:
56
- return "No relevant search results found."
57
- except Exception as e:
58
- return f"Search error: {e}"
59
 
60
  def call_whisper(self, video_path: str) -> str:
61
- # Transcribe the video to text using Whisper model
62
  video = moviepy.editor.VideoFileClip(video_path)
63
  audio_path = "temp_audio.wav"
64
  video.audio.write_audiofile(audio_path)
65
-
66
- # Transcribe audio to text
67
  result = self.whisper_model.transcribe(audio_path)
68
  return result["text"]
69
 
70
- def __call__(self, question: str, video_path: str = None) -> str:
71
- print(f"Agent received question (first 50 chars): {question[:50]}...")
72
-
73
- # If a video path is provided, use Whisper to transcribe the video
74
- if video_path:
75
- transcription = self.call_whisper(video_path)
76
- print(f"Transcribed video text: {transcription[:100]}...") # Print first 100 characters
77
- return transcription
78
-
79
- # If no video is provided, search the web for an answer
80
- search_answer = self.search(question)
81
- print(f"Agent returning search result: {search_answer[:100]}...")
82
- time.sleep(2)
83
- return search_answer
84
-
85
-
86
- def run_and_submit_all(profile: gr.OAuthProfile | None):
87
- """
88
- Fetches all questions, runs the BasicAgent on them, submits all answers,
89
- and displays the results.
90
- """
91
- # --- Determine HF Space Runtime URL and Repo URL ---
92
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
93
-
94
- if profile:
95
- username = f"{profile.username}"
96
- print(f"User logged in: {username}")
97
- else:
98
- print("User not logged in.")
99
- return "Please Login to Hugging Face with the button.", None
100
-
101
- api_url = DEFAULT_API_URL
102
- questions_url = f"{api_url}/questions"
103
- submit_url = f"{api_url}/submit"
104
-
105
- # 1. Instantiate Agent
106
- try:
107
- agent = BasicAgent()
108
- except Exception as e:
109
- print(f"Error instantiating agent: {e}")
110
- return f"Error initializing agent: {e}", None
111
-
112
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
113
- print(agent_code)
114
-
115
- # 2. Fetch Questions
116
- print(f"Fetching questions from: {questions_url}")
117
- try:
118
- response = requests.get(questions_url, timeout=15)
119
- response.raise_for_status()
120
- questions_data = response.json()
121
- if not questions_data:
122
- print("Fetched questions list is empty.")
123
- return "Fetched questions list is empty or invalid format.", None
124
- print(f"Fetched {len(questions_data)} questions.")
125
- except requests.exceptions.RequestException as e:
126
- print(f"Error fetching questions: {e}")
127
- return f"Error fetching questions: {e}", None
128
- except requests.exceptions.JSONDecodeError as e:
129
- print(f"Error decoding JSON response from questions endpoint: {e}")
130
- return f"Error decoding server response for questions: {e}", None
131
- except Exception as e:
132
- print(f"An unexpected error occurred fetching questions: {e}")
133
- return f"An unexpected error occurred fetching questions: {e}", None
134
-
135
- # 3. Run Agent
136
- results_log = []
137
- answers_payload = []
138
- print(f"Running agent on {len(questions_data)} questions...")
139
- for item in questions_data:
140
- task_id = item.get("task_id")
141
- question_text = item.get("question")
142
- video_link = item.get("video_link") # Assuming the question contains an optional video link
143
-
144
- if not task_id or question_text is None:
145
- print(f"Skipping item with missing task_id or question: {item}")
146
- continue
147
 
 
148
  try:
149
- # Pass video_link if available, else just the question text
150
- submitted_answer = agent(question_text, video_path=video_link)
151
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
152
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
153
  except Exception as e:
154
- print(f"Error running agent on task {task_id}: {e}")
155
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
156
 
157
- if not answers_payload:
158
- print("Agent did not produce any answers to submit.")
159
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
160
-
161
- # 4. Prepare Submission
162
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
163
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
164
- print(status_update)
165
-
166
- # 5. Submit
167
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
168
- try:
169
- response = requests.post(submit_url, json=submission_data, timeout=60)
170
- response.raise_for_status()
171
- result_data = response.json()
172
- final_status = (
173
- f"Submission Successful!\n"
174
- f"User: {result_data.get('username')}\n"
175
- f"Overall Score: {result_data.get('score', 'N/A')}% "
176
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
177
- f"Message: {result_data.get('message', 'No message received.')}"
178
- )
179
- print("Submission successful.")
180
- results_df = pd.DataFrame(results_log)
181
- return final_status, results_df
182
- except requests.exceptions.HTTPError as e:
183
- error_detail = f"Server responded with status {e.response.status_code}."
184
  try:
185
- error_json = e.response.json()
186
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
187
- except requests.exceptions.JSONDecodeError:
188
- error_detail += f" Response: {e.response.text[:500]}"
189
- status_message = f"Submission Failed: {error_detail}"
190
- print(status_message)
191
- results_df = pd.DataFrame(results_log)
192
- return status_message, results_df
193
- except requests.exceptions.Timeout:
194
- status_message = "Submission Failed: The request timed out."
195
- print(status_message)
196
- results_df = pd.DataFrame(results_log)
197
- return status_message, results_df
198
- except requests.exceptions.RequestException as e:
199
- status_message = f"Submission Failed: Network error - {e}"
200
- print(status_message)
201
- results_df = pd.DataFrame(results_log)
202
- return status_message, results_df
203
- except Exception as e:
204
- status_message = f"An unexpected error occurred during submission: {e}"
205
- print(status_message)
206
- results_df = pd.DataFrame(results_log)
207
- return status_message, results_df
208
-
209
-
210
- # --- Build Gradio Interface using Blocks ---
211
- with gr.Blocks() as demo:
212
- gr.Markdown("# Basic Agent Evaluation Runner")
213
- gr.Markdown(
214
- """
215
- **Instructions:**
216
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
217
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
218
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
219
- ---
220
- **Disclaimers:**
221
- 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).
222
- This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution.
223
- """
224
- )
225
-
226
- gr.LoginButton()
227
-
228
- run_button = gr.Button("Run Evaluation & Submit All Answers")
229
 
230
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
231
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
 
 
 
 
 
 
232
 
233
- run_button.click(
234
- fn=run_and_submit_all,
235
- outputs=[status_output, results_table]
236
- )
237
 
238
- if __name__ == "__main__":
239
- print("\n" + "-"*30 + " App Starting " + "-"*30)
240
- space_host_startup = os.getenv("SPACE_HOST")
241
- space_id_startup = os.getenv("SPACE_ID")
242
 
243
- if space_host_startup:
244
- print(f"✅ SPACE_HOST found: {space_host_startup}")
245
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
246
- else:
247
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
248
- if space_id_startup: # Print repo URLs if SPACE_ID is found
249
- print(f"✅ SPACE_ID found: {space_id_startup}")
250
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
251
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
252
- else:
253
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
254
 
255
- print("-"*(60 + len(" App Starting ")) + "\n")
 
 
256
 
257
- print("Launching Gradio Interface for Basic Agent Evaluation...")
258
- demo.launch(debug=True, share=False)
 
1
  import os
2
  import time
 
3
  import requests
4
+ import moviepy.editor
5
  import whisper
6
  import gradio as gr
7
  import pandas as pd
8
+ import wikipedia
9
  from duckduckgo_search import DDGS
10
  from transformers import pipeline
 
 
11
 
 
 
12
 
13
+ class SmartAgent:
 
14
  def __init__(self):
15
+ print("SmartAgent initialized.")
16
+ self.whisper_model = whisper.load_model("base")
17
+ self.qa_pipeline = pipeline("question-answering")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  def call_whisper(self, video_path: str) -> str:
 
20
  video = moviepy.editor.VideoFileClip(video_path)
21
  audio_path = "temp_audio.wav"
22
  video.audio.write_audiofile(audio_path)
 
 
23
  result = self.whisper_model.transcribe(audio_path)
24
  return result["text"]
25
 
26
+ def classify_question(self, question: str) -> str:
27
+ q = question.lower()
28
+ if "how many" in q or "number of" in q:
29
+ return "count"
30
+ elif "when" in q or "what year" in q:
31
+ return "date"
32
+ return "open"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ def wiki_search(self, question: str) -> str:
35
  try:
36
+ results = wikipedia.search(question, results=1)
37
+ if not results:
38
+ return ""
39
+ page = wikipedia.page(results[0])
40
+ return page.content
41
  except Exception as e:
42
+ return ""
 
43
 
44
+ def fallback_duckduckgo(self, question: str) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  try:
46
+ with DDGS() as ddgs:
47
+ results = list(ddgs.text(question, max_results=3))
48
+ return results[0]["body"] if results else ""
49
+ except Exception as e:
50
+ return ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
+ def answer_with_context(self, question: str, context: str) -> str:
53
+ try:
54
+ if not context.strip():
55
+ return "No reliable context found."
56
+ result = self.qa_pipeline(question=question, context=context)
57
+ return result["answer"]
58
+ except Exception as e:
59
+ return f"QA error: {e}"
60
 
61
+ def __call__(self, question: str, video_path: str = None) -> str:
62
+ print(f"Agent received question: {question[:60]}...")
 
 
63
 
64
+ if video_path:
65
+ return self.call_whisper(video_path)
 
 
66
 
67
+ classification = self.classify_question(question)
 
 
 
 
 
 
 
 
 
 
68
 
69
+ context = self.wiki_search(question)
70
+ if not context:
71
+ context = self.fallback_duckduckgo(question)
72
 
73
+ return self.answer_with_context(question, context)