dalybuilds commited on
Commit
c0a6618
·
verified ·
1 Parent(s): f5413d1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +94 -137
app.py CHANGED
@@ -1,73 +1,95 @@
1
  import os
2
  import gradio as gr
3
  import requests
4
- import inspect
5
  import pandas as pd
6
  from groq import Groq
7
 
 
 
 
 
 
 
 
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
- # --- Groq Powered Agent Definition ---
12
- # This new agent uses the Groq API to generate answers.
13
- class GroqAgent:
14
- def __init__(self, api_key):
 
15
  """
16
- Initializes the GroqAgent with the Groq API client.
17
  """
18
- print("Initializing GroqAgent...")
19
- self.client = Groq(api_key=api_key)
20
- print("GroqAgent initialized successfully.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  def __call__(self, question: str) -> str:
23
  """
24
- This method is called to answer a question using the Groq API.
 
25
  """
26
- print(f"GroqAgent received question (first 50 chars): {question[:50]}...")
27
-
28
- # A system prompt is used to guide the model to provide concise, direct answers,
29
- # which is ideal for the GAIA benchmark's exact-match scoring.
30
- system_prompt = (
31
- "You are an expert AI agent. Your goal is to answer the following question as accurately "
32
- "and concisely as possible. Provide only the final answer, without any introductory text, "
33
- "explanations, or additional formatting."
34
- )
35
-
36
  try:
37
- chat_completion = self.client.chat.completions.create(
38
- messages=[
39
- {
40
- "role": "system",
41
- "content": system_prompt,
42
- },
43
- {
44
- "role": "user",
45
- "content": question,
46
- }
47
- ],
48
- model="llama3-70b-8192", # A powerful model available via Groq
49
- temperature=0.0, # Set to 0 for deterministic, factual answers
50
- )
51
-
52
- answer = chat_completion.choices[0].message.content.strip()
53
- print(f"GroqAgent generated answer: {answer}")
54
- return answer
55
-
56
  except Exception as e:
57
- print(f"An error occurred while calling Groq API: {e}")
58
- return f"Error generating answer: {e}"
 
 
 
59
 
60
 
61
  def run_and_submit_all(profile: gr.OAuthProfile | None):
62
  """
63
- Fetches all questions, runs the GroqAgent on them, submits all answers,
64
  and displays the results.
65
  """
66
- # --- Determine HF Space Runtime URL and Repo URL ---
67
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
68
-
69
  if profile:
70
- username= f"{profile.username}"
71
  print(f"User logged in: {username}")
72
  else:
73
  print("User not logged in.")
@@ -77,70 +99,45 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
77
  questions_url = f"{api_url}/questions"
78
  submit_url = f"{api_url}/submit"
79
 
80
- # 1. Instantiate Agent (Now using GroqAgent)
81
  try:
82
- # Securely get the API key from Hugging Face Space secrets
83
  groq_api_key = os.getenv("GROQ_API_KEY")
84
- if not groq_api_key:
85
- raise ValueError("GROQ_API_KEY secret not found! Please set it in your Space's settings.")
86
- agent = GroqAgent(api_key=groq_api_key)
 
87
  except Exception as e:
88
  print(f"Error instantiating agent: {e}")
89
  return f"Error initializing agent: {e}", None
90
 
91
- # The link to your codebase (useful for verification, so please keep your space public)
92
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
93
  print(f"Agent code link: {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)
99
  response.raise_for_status()
100
  questions_data = response.json()
101
- if not questions_data:
102
- print("Fetched questions list is empty.")
103
- return "Fetched questions list is empty or invalid format.", None
104
- print(f"Fetched {len(questions_data)} questions.")
105
- except requests.exceptions.RequestException as e:
106
- print(f"Error fetching questions: {e}")
107
- return f"Error fetching questions: {e}", None
108
- except requests.exceptions.JSONDecodeError as e:
109
- print(f"Error decoding JSON response from questions endpoint: {e}")
110
- print(f"Response text: {response.text[:500]}")
111
- return f"Error decoding server response for questions: {e}", None
112
  except Exception as e:
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:
131
- print(f"Error running agent on task {task_id}: {e}")
132
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
133
 
134
- if not answers_payload:
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
 
143
- # 5. Submit
144
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
145
  try:
146
  response = requests.post(submit_url, json=submission_data, timeout=60)
@@ -153,63 +150,28 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
153
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
154
  f"Message: {result_data.get('message', 'No message received.')}"
155
  )
156
- print("Submission successful.")
157
  results_df = pd.DataFrame(results_log)
158
  return final_status, results_df
159
- except requests.exceptions.HTTPError as e:
160
- error_detail = f"Server responded with status {e.response.status_code}."
161
- try:
162
- error_json = e.response.json()
163
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
164
- except requests.exceptions.JSONDecodeError:
165
- error_detail += f" Response: {e.response.text[:500]}"
166
- status_message = f"Submission Failed: {error_detail}"
167
- print(status_message)
168
- results_df = pd.DataFrame(results_log)
169
- return status_message, results_df
170
- except requests.exceptions.Timeout:
171
- status_message = "Submission Failed: The request timed out."
172
- print(status_message)
173
- results_df = pd.DataFrame(results_log)
174
- return status_message, results_df
175
- except requests.exceptions.RequestException as e:
176
- status_message = f"Submission Failed: Network error - {e}"
177
- print(status_message)
178
- results_df = pd.DataFrame(results_log)
179
- return status_message, results_df
180
  except Exception as e:
181
  status_message = f"An unexpected error occurred during submission: {e}"
182
- print(status_message)
183
  results_df = pd.DataFrame(results_log)
184
  return status_message, results_df
185
 
186
-
187
- # --- Build Gradio Interface using Blocks ---
188
  with gr.Blocks() as demo:
189
- gr.Markdown("# Groq-Powered Agent Evaluation Runner")
190
  gr.Markdown(
191
  """
192
  **Instructions:**
193
- 1. Make sure you have set your `GROQ_API_KEY` in the 'Secrets' section of your Space settings.
194
- 2. Log in to your Hugging Face account using the button below. This is required for submission.
195
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit your answers, and see your score.
196
- ---
197
- **Disclaimers:**
198
- Once you click the "submit" button, the process can take some time as the agent answers all the questions.
199
- This space provides a basic setup. You are encouraged to modify the `GroqAgent` class to experiment with different models, prompts, or even add tools to improve your score!
200
  """
201
  )
202
-
203
  gr.LoginButton()
204
-
205
  run_button = gr.Button("Run Evaluation & Submit All Answers")
206
-
207
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
208
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
209
-
210
- # CORRECTED LINE: The `inputs` argument is removed. Gradio passes the
211
- # OAuthProfile automatically to the `run_and_submit_all` function
212
- # because of the type hint in its definition.
213
  run_button.click(
214
  fn=run_and_submit_all,
215
  outputs=[status_output, results_table]
@@ -217,19 +179,14 @@ with gr.Blocks() as demo:
217
 
218
  if __name__ == "__main__":
219
  print("\n" + "-"*30 + " App Starting " + "-"*30)
220
- space_id_startup = os.getenv("SPACE_ID")
221
- if space_id_startup:
222
- print(f"✅ SPACE_ID found: {space_id_startup}")
223
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
224
- else:
225
- print("ℹ️ SPACE_ID environment variable not found (running locally?).")
226
-
227
  if not os.getenv("GROQ_API_KEY"):
228
- print("⚠️ WARNING: GROQ_API_KEY secret is not set. The app will fail if run.")
229
  else:
230
- print("✅ GROQ_API_KEY secret is set.")
231
-
232
-
 
 
233
  print("-"*(60 + len(" App Starting ")) + "\n")
234
- print("Launching Gradio Interface for Groq Agent Evaluation...")
235
  demo.launch(debug=True, share=False)
 
1
  import os
2
  import gradio as gr
3
  import requests
 
4
  import pandas as pd
5
  from groq import Groq
6
 
7
+ # --- New Imports for LangChain Agent ---
8
+ from langchain_groq import ChatGroq
9
+ from langchain.agents import AgentExecutor, create_tool_calling_agent
10
+ from langchain_community.tools.tavily_search import TavilySearchResults
11
+ from langchain_core.prompts import ChatPromptTemplate
12
+
13
+
14
  # --- Constants ---
15
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
16
 
17
+
18
+ # --- Agent Definition ---
19
+ # This new agent uses LangChain to orchestrate an LLM with tools.
20
+ class LangChainAgent:
21
+ def __init__(self, groq_api_key, tavily_api_key):
22
  """
23
+ Initializes the agent with an LLM and a set of tools.
24
  """
25
+ print("Initializing LangChainAgent...")
26
+
27
+ # 1. Initialize the LLM
28
+ # We use ChatGroq, the LangChain integration for Groq's API.
29
+ self.llm = ChatGroq(
30
+ model_name="llama3-70b-8192",
31
+ groq_api_key=groq_api_key,
32
+ temperature=0.0
33
+ )
34
+
35
+ # 2. Define the tools the agent can use
36
+ # For now, we'll just give it a web search tool.
37
+ self.tools = [
38
+ TavilySearchResults(max_results=3, tavily_api_key=tavily_api_key)
39
+ ]
40
+
41
+ # 3. Create the Agent Prompt
42
+ # This tells the agent how to behave and how to use the tools.
43
+ prompt = ChatPromptTemplate.from_messages(
44
+ [
45
+ ("system", "You are a helpful assistant. You have access to a web search tool. Respond with the final answer to the user's question."),
46
+ ("placeholder", "{chat_history}"),
47
+ ("human", "{input}"),
48
+ ("placeholder", "{agent_scratchpad}"),
49
+ ]
50
+ )
51
+
52
+ # 4. Create the Agent itself
53
+ agent = create_tool_calling_agent(self.llm, self.tools, prompt)
54
+
55
+ # 5. Create the Agent Executor
56
+ # This is the runtime that will actually execute the agent's logic.
57
+ self.agent_executor = AgentExecutor(
58
+ agent=agent,
59
+ tools=self.tools,
60
+ verbose=True # Set to True to see the agent's thought process
61
+ )
62
+ print("LangChainAgent initialized.")
63
+
64
 
65
  def __call__(self, question: str) -> str:
66
  """
67
+ This method is called to answer a question.
68
+ It invokes the agent executor.
69
  """
70
+ print(f"LangChainAgent received question (first 50 chars): {question[:50]}...")
71
+
72
+ # We need to handle the case where the agent makes a mistake
 
 
 
 
 
 
 
73
  try:
74
+ response = self.agent_executor.invoke({"input": question})
75
+ answer = response.get("output", "No answer found.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  except Exception as e:
77
+ print(f"An error occurred in the agent executor: {e}")
78
+ answer = f"Agent failed with an error: {e}"
79
+
80
+ print(f"LangChainAgent generated answer: {answer}")
81
+ return answer
82
 
83
 
84
  def run_and_submit_all(profile: gr.OAuthProfile | None):
85
  """
86
+ Fetches questions, runs the LangChainAgent on them, submits the answers,
87
  and displays the results.
88
  """
89
+ # --- Authentication and Setup ---
90
+ space_id = os.getenv("SPACE_ID")
 
91
  if profile:
92
+ username = f"{profile.username}"
93
  print(f"User logged in: {username}")
94
  else:
95
  print("User not logged in.")
 
99
  questions_url = f"{api_url}/questions"
100
  submit_url = f"{api_url}/submit"
101
 
102
+ # 1. Instantiate Agent (using the new LangChainAgent)
103
  try:
 
104
  groq_api_key = os.getenv("GROQ_API_KEY")
105
+ tavily_api_key = os.getenv("TAVILY_API_KEY")
106
+ if not groq_api_key or not tavily_api_key:
107
+ raise ValueError("API Keys (GROQ_API_KEY, TAVILY_API_KEY) not found in secrets.")
108
+ agent = LangChainAgent(groq_api_key=groq_api_key, tavily_api_key=tavily_api_key)
109
  except Exception as e:
110
  print(f"Error instantiating agent: {e}")
111
  return f"Error initializing agent: {e}", None
112
 
 
113
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
114
  print(f"Agent code link: {agent_code}")
115
 
116
+ # 2. Fetch Questions (same as before)
117
  print(f"Fetching questions from: {questions_url}")
118
  try:
119
+ response = requests.get(questions_url, timeout=20)
120
  response.raise_for_status()
121
  questions_data = response.json()
 
 
 
 
 
 
 
 
 
 
 
122
  except Exception as e:
123
+ return f"Error fetching questions: {e}", None
 
124
 
125
+ # 3. Run your Agent (same as before)
126
  results_log = []
127
  answers_payload = []
 
128
  for item in questions_data:
129
  task_id = item.get("task_id")
130
  question_text = item.get("question")
131
  if not task_id or question_text is None:
 
132
  continue
133
+ submitted_answer = agent(question_text)
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
 
137
+ # 4. Prepare Submission (same as before)
 
 
 
 
138
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
 
 
139
 
140
+ # 5. Submit (same as before)
141
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
142
  try:
143
  response = requests.post(submit_url, json=submission_data, timeout=60)
 
150
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
151
  f"Message: {result_data.get('message', 'No message received.')}"
152
  )
 
153
  results_df = pd.DataFrame(results_log)
154
  return final_status, results_df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  except Exception as e:
156
  status_message = f"An unexpected error occurred during submission: {e}"
 
157
  results_df = pd.DataFrame(results_log)
158
  return status_message, results_df
159
 
160
+ # --- Build Gradio Interface (Mostly the same) ---
 
161
  with gr.Blocks() as demo:
162
+ gr.Markdown("# LangChain Agent Evaluation Runner")
163
  gr.Markdown(
164
  """
165
  **Instructions:**
166
+ 1. Make sure you have set `GROQ_API_KEY` and `TAVILY_API_KEY` in your Space's secrets.
167
+ 2. Log in below. This is required for submission.
168
+ 3. Click 'Run Evaluation' to start the agent. You can see its thought process in the application logs!
 
 
 
 
169
  """
170
  )
 
171
  gr.LoginButton()
 
172
  run_button = gr.Button("Run Evaluation & Submit All Answers")
 
173
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
174
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
 
 
 
 
175
  run_button.click(
176
  fn=run_and_submit_all,
177
  outputs=[status_output, results_table]
 
179
 
180
  if __name__ == "__main__":
181
  print("\n" + "-"*30 + " App Starting " + "-"*30)
182
+ # Startup checks for secrets
 
 
 
 
 
 
183
  if not os.getenv("GROQ_API_KEY"):
184
+ print("⚠️ WARNING: GROQ_API_KEY secret not set.")
185
  else:
186
+ print("✅ GROQ_API_KEY secret is set.")
187
+ if not os.getenv("TAVILY_API_KEY"):
188
+ print("⚠️ WARNING: TAVILY_API_KEY secret not set.")
189
+ else:
190
+ print("✅ TAVILY_API_KEY secret is set.")
191
  print("-"*(60 + len(" App Starting ")) + "\n")
 
192
  demo.launch(debug=True, share=False)