josondev commited on
Commit
e25ef11
·
verified ·
1 Parent(s): 2a7d496

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -71
app.py CHANGED
@@ -2,82 +2,75 @@ import os
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
5
- import base64
6
  from dotenv import load_dotenv
7
- from groq import Groq
 
 
 
8
 
9
  # Load environment variables
10
  load_dotenv()
11
 
12
- # --- Groq Multimodal Agent ---
13
- class GroqMultimodalAgent:
14
- def __init__(self):
15
- self.client = Groq(api_key=os.getenv("GROQ_API_KEY"))
16
- self.llava_model = "llava-v1.5-7b-4096-preview" # For image Q&A
17
- self.llama_model = "meta-llama/llama-4-scout-17b-16e-instruct" # For text Q&A
18
- self.whisper_model = "whisper-large-v3" # For audio transcription
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  self.instructions = (
20
- "You are a helpful assistant. For every question or media, reply with only the answer—no explanation, "
21
  "no units, and no extra words. If the answer is a number, just return the number. "
22
  "If it is a word or phrase, return only that. If it is a list, return a comma-separated list with no extra words. "
23
  "Do not include any prefix, suffix, or explanation."
24
  )
 
25
 
26
- def _encode_image(self, image_path):
27
- with open(image_path, "rb") as img_file:
28
- return base64.b64encode(img_file.read()).decode("utf-8")
29
-
30
- def _process_image(self, image_path, question):
31
- base64_image = self._encode_image(image_path)
32
- prompt = f"{self.instructions}\n\n{question}"
33
- chat_completion = self.client.chat.completions.create(
34
- model=self.llava_model,
35
- messages=[
36
- {"role": "user", "content": [
37
- {"type": "text", "text": prompt},
38
- {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}
39
- ]}
40
- ]
41
- )
42
- answer = chat_completion.choices[0].message.content.strip()
43
- return self._extract_final_answer(answer)
44
-
45
- def _process_audio(self, audio_path):
46
- with open(audio_path, "rb") as audio_file:
47
- transcript = self.client.audio.transcriptions.create(
48
- model=self.whisper_model,
49
- file=audio_file
50
- )
51
- return transcript.text.strip()
52
-
53
- def _process_text(self, question):
54
  prompt = f"{self.instructions}\n\n{question}"
55
- chat_completion = self.client.chat.completions.create(
56
- model=self.llama_model,
57
- messages=[{"role": "user", "content": prompt}]
58
- )
59
- answer = chat_completion.choices[0].message.content.strip()
60
- return self._extract_final_answer(answer)
61
-
62
- def _extract_final_answer(self, llm_output: str) -> str:
63
  for prefix in ["FINAL ANSWER:", "Final answer:", "final answer:"]:
64
- if llm_output.lower().startswith(prefix.lower()):
65
- return llm_output[len(prefix):].strip()
66
- return llm_output
67
-
68
- def __call__(self, question: str, image_path: str = None, audio_path: str = None) -> str:
69
- if image_path:
70
- return self._process_image(image_path, question)
71
- elif audio_path:
72
- return self._process_audio(audio_path)
73
- else:
74
- return self._process_text(question)
75
 
76
- # --- Gradio Leaderboard Submission App ---
77
- DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
78
-
79
- def run_and_submit_all(profile: gr.OAuthProfile | None):
80
- space_id = os.getenv("SPACE_ID")
81
  if profile:
82
  username = f"{profile.username}"
83
  print(f"User logged in: {username}")
@@ -89,8 +82,9 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
89
  questions_url = f"{api_url}/questions"
90
  submit_url = f"{api_url}/submit"
91
 
 
92
  try:
93
- agent = GroqMultimodalAgent()
94
  except Exception as e:
95
  print(f"Error instantiating agent: {e}")
96
  return f"Error initializing agent: {e}", None
@@ -98,6 +92,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
98
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
99
  print(agent_code)
100
 
 
101
  print(f"Fetching questions from: {questions_url}")
102
  try:
103
  response = requests.get(questions_url, timeout=15)
@@ -118,19 +113,18 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
118
  print(f"An unexpected error occurred fetching questions: {e}")
119
  return f"An unexpected error occurred fetching questions: {e}", None
120
 
 
121
  results_log = []
122
  answers_payload = []
123
  print(f"Running agent on {len(questions_data)} questions...")
124
  for item in questions_data:
125
  task_id = item.get("task_id")
126
  question_text = item.get("question")
127
- image_path = item.get("image_path", None)
128
- audio_path = item.get("audio_path", None)
129
  if not task_id or question_text is None:
130
  print(f"Skipping item with missing task_id or question: {item}")
131
  continue
132
  try:
133
- submitted_answer = agent(question_text, image_path=image_path, audio_path=audio_path)
134
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
135
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
136
  except Exception as e:
@@ -141,10 +135,11 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
141
  print("Agent did not produce any answers to submit.")
142
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
143
 
 
144
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
145
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
146
  print(status_update)
147
-
148
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
149
  try:
150
  response = requests.post(submit_url, json=submission_data, timeout=60)
@@ -195,23 +190,30 @@ with gr.Blocks() as demo:
195
  **Instructions:**
196
  1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
197
  2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
198
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
199
  ---
200
  **Disclaimers:**
201
- 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).
202
- This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution. For instance for the delay process of the submit button, a solution could be to cache the answers and submit in a separate action or even to answer the questions in async.
203
  """
204
  )
205
 
206
  gr.LoginButton()
207
 
 
 
 
 
 
 
208
  run_button = gr.Button("Run Evaluation & Submit All Answers")
209
 
210
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
211
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
212
 
213
  run_button.click(
214
- fn=run_and_submit_all,
 
215
  outputs=[status_output, results_table]
216
  )
217
 
@@ -237,3 +239,4 @@ if __name__ == "__main__":
237
 
238
  print("Launching Gradio Interface for Basic Agent Evaluation...")
239
  demo.launch(debug=True, share=False)
 
 
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
 
5
  from dotenv import load_dotenv
6
+ from langchain_openai import ChatOpenAI
7
+ from langchain_nvidia_ai_endpoints import ChatNVIDIA
8
+ from langchain_groq import ChatGroq
9
+ from langchain_google_genai import ChatGoogleGenerativeAI
10
 
11
  # Load environment variables
12
  load_dotenv()
13
 
14
+ # --- Constants ---
15
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
16
+
17
+ # --- Basic Agent Definition ---
18
+ class BasicAgent:
19
+ def __init__(self, provider="nvidia"):
20
+ self.provider = provider.lower()
21
+ if self.provider == "nvidia":
22
+ self.llm = ChatNVIDIA(
23
+ model="meta/llama-3.3-70b-instruct",
24
+ nvidia_api_key=os.getenv("NVIDIA_API_KEY")
25
+ )
26
+ elif self.provider == "groq":
27
+ self.llm = ChatGroq(
28
+ model="llama3-70b-8192",
29
+ api_key=os.getenv("GROQ_API_KEY")
30
+ )
31
+ elif self.provider == "google":
32
+ self.llm = ChatGoogleGenerativeAI(
33
+ model="gemini-2.0-flash",
34
+ temperature=0.1,
35
+ max_tokens=1024,
36
+ api_key=os.getenv("GOOGLE_API_KEY"),
37
+ streaming=False
38
+ )
39
+ elif self.provider == "openai":
40
+ self.llm = ChatOpenAI(
41
+ model="gpt-3.5-turbo",
42
+ api_key=os.getenv("OPENAI_API_KEY")
43
+ )
44
+ else:
45
+ raise ValueError("Unsupported provider. Choose from: nvidia, groq, google, openai.")
46
+
47
  self.instructions = (
48
+ "You are a helpful assistant. For every question, reply with only the answer—no explanation, "
49
  "no units, and no extra words. If the answer is a number, just return the number. "
50
  "If it is a word or phrase, return only that. If it is a list, return a comma-separated list with no extra words. "
51
  "Do not include any prefix, suffix, or explanation."
52
  )
53
+ print(f"BasicAgent initialized with provider: {self.provider}")
54
 
55
+ def __call__(self, question: str) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  prompt = f"{self.instructions}\n\n{question}"
57
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
58
+ response = self.llm.invoke(prompt)
59
+ answer = response.content.strip() if hasattr(response, "content") else str(response)
60
+ # Remove "FINAL ANSWER:" or similar prefixes if present
 
 
 
 
61
  for prefix in ["FINAL ANSWER:", "Final answer:", "final answer:"]:
62
+ if answer.lower().startswith(prefix.lower()):
63
+ answer = answer[len(prefix):].strip()
64
+ print(f"Agent returning answer: {answer}")
65
+ return answer
66
+
67
+ def run_and_submit_all(profile: gr.OAuthProfile | None, provider="nvidia"):
68
+ """
69
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
70
+ and displays the results.
71
+ """
72
+ space_id = os.getenv("SPACE_ID") # For codebase link
73
 
 
 
 
 
 
74
  if profile:
75
  username = f"{profile.username}"
76
  print(f"User logged in: {username}")
 
82
  questions_url = f"{api_url}/questions"
83
  submit_url = f"{api_url}/submit"
84
 
85
+ # 1. Instantiate Agent
86
  try:
87
+ agent = BasicAgent(provider=provider)
88
  except Exception as e:
89
  print(f"Error instantiating agent: {e}")
90
  return f"Error initializing agent: {e}", None
 
92
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
93
  print(agent_code)
94
 
95
+ # 2. Fetch Questions
96
  print(f"Fetching questions from: {questions_url}")
97
  try:
98
  response = requests.get(questions_url, timeout=15)
 
113
  print(f"An unexpected error occurred fetching questions: {e}")
114
  return f"An unexpected error occurred fetching questions: {e}", None
115
 
116
+ # 3. Run your Agent
117
  results_log = []
118
  answers_payload = []
119
  print(f"Running agent on {len(questions_data)} questions...")
120
  for item in questions_data:
121
  task_id = item.get("task_id")
122
  question_text = item.get("question")
 
 
123
  if not task_id or question_text is None:
124
  print(f"Skipping item with missing task_id or question: {item}")
125
  continue
126
  try:
127
+ submitted_answer = agent(question_text)
128
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
129
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
130
  except Exception as e:
 
135
  print("Agent did not produce any answers to submit.")
136
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
137
 
138
+ # 4. Prepare Submission
139
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
140
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
141
  print(status_update)
142
+ # 5. Submit
143
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
144
  try:
145
  response = requests.post(submit_url, json=submission_data, timeout=60)
 
190
  **Instructions:**
191
  1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
192
  2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
193
+ 3. Select your preferred provider and click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
194
  ---
195
  **Disclaimers:**
196
+ 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).
197
+ This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution. For instance, for the delay process of the submit button, a solution could be to cache the answers and submit in a separate action or even to answer the questions in async.
198
  """
199
  )
200
 
201
  gr.LoginButton()
202
 
203
+ provider_dropdown = gr.Dropdown(
204
+ choices=["nvidia", "groq", "google", "openai"],
205
+ value="nvidia",
206
+ label="Choose LLM Provider"
207
+ )
208
+
209
  run_button = gr.Button("Run Evaluation & Submit All Answers")
210
 
211
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
212
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
213
 
214
  run_button.click(
215
+ fn=lambda profile, provider: run_and_submit_all(profile, provider),
216
+ inputs=[gr.OAuthProfile(), provider_dropdown],
217
  outputs=[status_output, results_table]
218
  )
219
 
 
239
 
240
  print("Launching Gradio Interface for Basic Agent Evaluation...")
241
  demo.launch(debug=True, share=False)
242
+