Abbasid commited on
Commit
08f3bff
·
verified ·
1 Parent(s): a3e120b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -67
app.py CHANGED
@@ -1,44 +1,28 @@
1
  """
2
  app.py
3
 
4
- This script provides the Gradio web interface to run the evaluation for the
5
- Hugging Face Agents course. It fetches questions from a server, runs the
6
- agent defined in agent.py on them, and submits the answers for scoring.
7
  """
8
 
9
  import os
10
- import re # <-- 1. ADDED IMPORT for Regular Expressions
11
  import gradio as gr
12
  import requests
13
  import pandas as pd
14
 
15
- # --- Import your agent's factory function ---
16
- from agent import create_agent_executor # <-- 2. ADDED IMPORT for your agent
17
 
18
  # --- Constants ---
19
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
20
 
21
- # --- DELETED BasicAgent class as it's no longer needed ---
22
-
23
- # --- 3. ADDED HELPER FUNCTION TO PARSE THE AGENT'S OUTPUT ---
24
  def parse_final_answer(agent_response: str) -> str:
25
- """
26
- Extracts the final answer from the agent's full response string.
27
- The agent is prompted to return 'FINAL ANSWER: [answer]'.
28
- This function isolates and returns '[answer]'.
29
- """
30
- # Use a regular expression to find the text after "FINAL ANSWER:"
31
  match = re.search(r"FINAL ANSWER:\s*(.*)", agent_response, re.IGNORECASE | re.DOTALL)
32
- if match:
33
- # If a match is found, return the captured group, stripped of whitespace
34
- return match.group(1).strip()
35
-
36
- # As a fallback, if the specific format is not found, return the last non-empty line
37
  lines = [line for line in agent_response.split('\n') if line.strip()]
38
- if lines:
39
- return lines[-1].strip()
40
-
41
- # If all else fails, return a default message
42
  return "Could not parse a final answer."
43
 
44
 
@@ -48,7 +32,6 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
48
  and displays the results.
49
  """
50
  if not profile:
51
- print("User not logged in.")
52
  return "Please log in to Hugging Face with the button above to submit.", None
53
 
54
  username = profile.username
@@ -58,18 +41,15 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
58
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
59
  questions_url = f"{DEFAULT_API_URL}/questions"
60
  submit_url = f"{DEFAULT_API_URL}/submit"
61
-
62
- # --- 4. MODIFIED AGENT INSTANTIATION AND EXECUTION ---
63
 
64
- # 1. Instantiate Agent (using your factory function from agent.py)
65
  print("Initializing your custom agent...")
66
  try:
67
- agent_executor = create_agent_executor(provider="groq") # or "groq"
68
  except Exception as e:
69
- print(f"Error instantiating agent: {e}")
70
  return f"Fatal Error: Could not initialize agent. Check logs. Details: {e}", None
71
 
72
- # 2. Fetch Questions (this part is correct)
73
  print(f"Fetching questions from: {questions_url}")
74
  try:
75
  response = requests.get(questions_url, timeout=20)
@@ -77,32 +57,37 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
77
  questions_data = response.json()
78
  print(f"Fetched {len(questions_data)} questions.")
79
  except Exception as e:
80
- return f"Error fetching questions: {e}", None
81
 
82
- # 3. Run your Agent (THIS IS THE MOST IMPORTANTLY CORRECTED SECTION)
83
- results_log = []
84
- answers_payload = []
85
  print(f"Running agent on {len(questions_data)} questions...")
86
  for i, item in enumerate(questions_data):
87
  task_id = item.get("task_id")
88
  question_text = item.get("question")
89
-
90
- if not task_id or question_text is None:
91
- print(f"Skipping item with missing data: {item}")
92
- continue
93
 
94
  print(f"\n--- Running Task {i+1}/{len(questions_data)} (ID: {task_id}) ---")
95
- print(f"Question: {question_text}")
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  try:
98
- # CORRECT INVOCATION: Use the agent_executor with the .invoke() method
99
- # The input must be a dictionary with a "messages" key
100
- result = agent_executor.invoke({"messages": [("user", question_text)]})
101
 
102
- # The agent's final response is in the 'messages' list of the output
103
  raw_answer = result['messages'][-1].content
104
-
105
- # Use our helper function to extract the clean answer
106
  submitted_answer = parse_final_answer(raw_answer)
107
 
108
  print(f"Raw LLM Response: '{raw_answer}'")
@@ -112,37 +97,29 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
112
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
113
  except Exception as e:
114
  print(f"!! AGENT ERROR on task {task_id}: {e}")
115
- # It's important to log errors so you can see them in the UI
116
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT RUNTIME ERROR: {e}"})
117
 
118
  if not answers_payload:
119
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
120
 
121
- # 4. Prepare and 5. Submit (these parts are correct)
122
  submission_data = {"username": username, "agent_code": agent_code, "answers": answers_payload}
123
  print(f"\nSubmitting {len(answers_payload)} answers for user '{username}'...")
124
  try:
125
  response = requests.post(submit_url, json=submission_data, timeout=60)
126
  response.raise_for_status()
127
  result_data = response.json()
128
- final_status = (
129
- f"Submission Successful!\n"
130
- f"User: {result_data.get('username')}\n"
131
- f"Overall Score: {result_data.get('score', 'N/A')}% "
132
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)"
133
- )
134
- print("Submission successful.")
135
  return final_status, pd.DataFrame(results_log)
136
  except Exception as e:
137
  status_message = f"Submission Failed: {e}"
138
  print(status_message)
139
  return status_message, pd.DataFrame(results_log)
140
 
141
-
142
- # --- Build Gradio Interface using Blocks (This part is correct) ---
143
  with gr.Blocks() as demo:
144
  gr.Markdown("# Agent Evaluation Runner")
145
- gr.Markdown("Run your custom agent against the evaluation questions and submit for a score.")
146
  gr.LoginButton()
147
  run_button = gr.Button("Run Evaluation & Submit All Answers", variant="primary")
148
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=4, interactive=False)
@@ -151,13 +128,4 @@ with gr.Blocks() as demo:
151
 
152
  if __name__ == "__main__":
153
  print("\n" + "-"*30 + " App Starting " + "-"*30)
154
- # The startup info logs are helpful, so we keep them.
155
- space_id_startup = os.getenv("SPACE_ID")
156
- if space_id_startup:
157
- print(f"✅ SPACE_ID found: {space_id_startup}")
158
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
159
- else:
160
- print("ℹ️ SPACE_ID environment variable not found (likely running locally).")
161
- print("-"*(60 + len(" App Starting ")) + "\n")
162
- print("Launching Gradio Interface...")
163
  demo.launch()
 
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
10
+ 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()
 
 
 
 
24
  lines = [line for line in agent_response.split('\n') if line.strip()]
25
+ if lines: return lines[-1].strip()
 
 
 
26
  return "Could not parse a final answer."
27
 
28
 
 
32
  and displays the results.
33
  """
34
  if not profile:
 
35
  return "Please log in to Hugging Face with the button above to submit.", None
36
 
37
  username = profile.username
 
41
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
42
  questions_url = f"{DEFAULT_API_URL}/questions"
43
  submit_url = f"{DEFAULT_API_URL}/submit"
 
 
44
 
45
+ # 1. Instantiate Agent
46
  print("Initializing your custom agent...")
47
  try:
48
+ agent_executor = create_agent_executor(provider="google") # 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
 
52
+ # 2. Fetch Questions
53
  print(f"Fetching questions from: {questions_url}")
54
  try:
55
  response = requests.get(questions_url, timeout=20)
 
57
  questions_data = response.json()
58
  print(f"Fetched {len(questions_data)} questions.")
59
  except Exception as e:
60
+ return f"Error fetching questions: {e}", pd.DataFrame()
61
 
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
 
 
91
  submitted_answer = parse_final_answer(raw_answer)
92
 
93
  print(f"Raw LLM Response: '{raw_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)
104
 
105
+ # 4. Prepare and 5. Submit
106
  submission_data = {"username": username, "agent_code": agent_code, "answers": answers_payload}
107
  print(f"\nSubmitting {len(answers_payload)} answers for user '{username}'...")
108
  try:
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)
 
128
 
129
  if __name__ == "__main__":
130
  print("\n" + "-"*30 + " App Starting " + "-"*30)
 
 
 
 
 
 
 
 
 
131
  demo.launch()