upload my tools and updata the app.py

#1
by kingkaikai - opened
Files changed (2) hide show
  1. app.py +73 -52
  2. tools.py +61 -0
app.py CHANGED
@@ -1,34 +1,25 @@
1
  import os
 
2
  import gradio as gr
3
  import requests
4
  import inspect
5
  import pandas as pd
 
 
6
 
7
- # (Keep Constants as is)
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
 
10
 
11
- # --- Basic Agent Definition ---
12
- # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
13
- class BasicAgent:
14
- def __init__(self):
15
- print("BasicAgent initialized.")
16
- def __call__(self, question: str) -> str:
17
- print(f"Agent received question (first 50 chars): {question[:50]}...")
18
- fixed_answer = "This is a default answer."
19
- print(f"Agent returning fixed answer: {fixed_answer}")
20
- return fixed_answer
21
-
22
- def run_and_submit_all( profile: gr.OAuthProfile | None):
23
- """
24
- Fetches all questions, runs the BasicAgent on them, submits all answers,
25
- and displays the results.
26
- """
27
  # --- Determine HF Space Runtime URL and Repo URL ---
28
  space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
29
 
30
  if profile:
31
- username= f"{profile.username}"
32
  print(f"User logged in: {username}")
33
  else:
34
  print("User not logged in.")
@@ -38,13 +29,13 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
38
  questions_url = f"{api_url}/questions"
39
  submit_url = f"{api_url}/submit"
40
 
41
- # 1. Instantiate Agent ( modify this part to create your agent)
42
  try:
43
- agent = BasicAgent()
44
  except Exception as e:
45
  print(f"Error instantiating agent: {e}")
46
  return f"Error initializing agent: {e}", None
47
- # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
48
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
49
  print(agent_code)
50
 
@@ -55,16 +46,16 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
55
  response.raise_for_status()
56
  questions_data = response.json()
57
  if not questions_data:
58
- print("Fetched questions list is empty.")
59
- return "Fetched questions list is empty or invalid format.", None
60
  print(f"Fetched {len(questions_data)} questions.")
61
  except requests.exceptions.RequestException as e:
62
  print(f"Error fetching questions: {e}")
63
  return f"Error fetching questions: {e}", None
64
  except requests.exceptions.JSONDecodeError as e:
65
- print(f"Error decoding JSON response from questions endpoint: {e}")
66
- print(f"Response text: {response.text[:500]}")
67
- return f"Error decoding server response for questions: {e}", None
68
  except Exception as e:
69
  print(f"An unexpected error occurred fetching questions: {e}")
70
  return f"An unexpected error occurred fetching questions: {e}", None
@@ -80,19 +71,49 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
80
  print(f"Skipping item with missing task_id or question: {item}")
81
  continue
82
  try:
83
- submitted_answer = agent(question_text)
84
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
86
  except Exception as e:
87
- print(f"Error running agent on task {task_id}: {e}")
88
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
89
 
90
  if not answers_payload:
91
  print("Agent did not produce any answers to submit.")
92
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
93
 
 
 
 
 
 
 
 
 
 
 
 
94
  # 4. Prepare Submission
95
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
 
 
 
 
96
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
97
  print(status_update)
98
 
@@ -107,6 +128,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
107
  f"User: {result_data.get('username')}\n"
108
  f"Overall Score: {result_data.get('score', 'N/A')}% "
109
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
 
110
  f"Message: {result_data.get('message', 'No message received.')}"
111
  )
112
  print("Submission successful.")
@@ -119,51 +141,51 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
119
  error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
120
  except requests.exceptions.JSONDecodeError:
121
  error_detail += f" Response: {e.response.text[:500]}"
122
- status_message = f"Submission Failed: {error_detail}"
123
  print(status_message)
124
  results_df = pd.DataFrame(results_log)
125
  return status_message, results_df
126
  except requests.exceptions.Timeout:
127
- status_message = "Submission Failed: The request timed out."
128
  print(status_message)
129
  results_df = pd.DataFrame(results_log)
130
  return status_message, results_df
131
  except requests.exceptions.RequestException as e:
132
- status_message = f"Submission Failed: Network error - {e}"
133
  print(status_message)
134
  results_df = pd.DataFrame(results_log)
135
  return status_message, results_df
136
  except Exception as e:
137
- status_message = f"An unexpected error occurred during submission: {e}"
138
  print(status_message)
139
  results_df = pd.DataFrame(results_log)
140
  return status_message, results_df
141
 
142
-
143
  # --- Build Gradio Interface using Blocks ---
144
  with gr.Blocks() as demo:
145
- gr.Markdown("# Basic Agent Evaluation Runner")
146
  gr.Markdown(
147
  """
148
  **Instructions:**
149
 
150
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
151
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
152
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
153
-
154
- ---
155
- **Disclaimers:**
156
- 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).
157
- 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 seperate action or even to answer the questions in async.
 
 
 
 
158
  """
159
  )
160
 
161
  gr.LoginButton()
162
-
163
  run_button = gr.Button("Run Evaluation & Submit All Answers")
164
-
165
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
166
- # Removed max_rows=10 from DataFrame constructor
167
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
168
 
169
  run_button.click(
@@ -173,9 +195,8 @@ with gr.Blocks() as demo:
173
 
174
  if __name__ == "__main__":
175
  print("\n" + "-"*30 + " App Starting " + "-"*30)
176
- # Check for SPACE_HOST and SPACE_ID at startup for information
177
  space_host_startup = os.getenv("SPACE_HOST")
178
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
179
 
180
  if space_host_startup:
181
  print(f"✅ SPACE_HOST found: {space_host_startup}")
@@ -183,7 +204,7 @@ if __name__ == "__main__":
183
  else:
184
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
185
 
186
- if space_id_startup: # Print repo URLs if SPACE_ID is found
187
  print(f"✅ SPACE_ID found: {space_id_startup}")
188
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
189
  print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
@@ -192,5 +213,5 @@ if __name__ == "__main__":
192
 
193
  print("-"*(60 + len(" App Starting ")) + "\n")
194
 
195
- print("Launching Gradio Interface for Basic Agent Evaluation...")
196
  demo.launch(debug=True, share=False)
 
1
  import os
2
+ import json
3
  import gradio as gr
4
  import requests
5
  import inspect
6
  import pandas as pd
7
+ from agent import SmoalAgent
8
+ from tools import search_tool, rag_chain, extract_final_answer
9
 
 
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
+ SUBMISSION_FILE = "submission.jsonl"
13
 
14
+
15
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
16
+ """Fetches all questions, runs the SmoalAgent on them, submits all answers,
17
+ and displays the results."""
 
 
 
 
 
 
 
 
 
 
 
 
18
  # --- Determine HF Space Runtime URL and Repo URL ---
19
  space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
20
 
21
  if profile:
22
+ username = f"{profile.username}"
23
  print(f"User logged in: {username}")
24
  else:
25
  print("User not logged in.")
 
29
  questions_url = f"{api_url}/questions"
30
  submit_url = f"{api_url}/submit"
31
 
32
+ # 1. Instantiate Agent
33
  try:
34
+ agent = SmoalAgent()
35
  except Exception as e:
36
  print(f"Error instantiating agent: {e}")
37
  return f"Error initializing agent: {e}", None
38
+
39
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
40
  print(agent_code)
41
 
 
46
  response.raise_for_status()
47
  questions_data = response.json()
48
  if not questions_data:
49
+ print("Fetched questions list is empty.")
50
+ return "Fetched questions list is empty or invalid format.", None
51
  print(f"Fetched {len(questions_data)} questions.")
52
  except requests.exceptions.RequestException as e:
53
  print(f"Error fetching questions: {e}")
54
  return f"Error fetching questions: {e}", None
55
  except requests.exceptions.JSONDecodeError as e:
56
+ print(f"Error decoding JSON response from questions endpoint: {e}")
57
+ print(f"Response text: {response.text[:500]}")
58
+ return f"Error decoding server response for questions: {e}", None
59
  except Exception as e:
60
  print(f"An unexpected error occurred fetching questions: {e}")
61
  return f"An unexpected error occurred fetching questions: {e}", None
 
71
  print(f"Skipping item with missing task_id or question: {item}")
72
  continue
73
  try:
74
+ # 使用导入的搜索工具和RAG链
75
+ search_result = search_tool.run(question_text)
76
+ if rag_chain:
77
+ response = rag_chain.run(f"{question_text}\nSearch result: {search_result}")
78
+ submitted_answer = extract_final_answer(response)
79
+ # Format answer according to JSON-line submission requirements
80
+ answers_payload.append({
81
+ "task_id": task_id,
82
+ "model_answer": submitted_answer,
83
+ "reasoning_trace": response
84
+ })
85
+ else:
86
+ submitted_answer = agent(question_text)
87
+ answers_payload.append({
88
+ "task_id": task_id,
89
+ "model_answer": submitted_answer
90
+ })
91
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
92
  except Exception as e:
93
+ print(f"Error running agent on task {task_id}: {e}")
94
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
95
 
96
  if not answers_payload:
97
  print("Agent did not produce any answers to submit.")
98
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
99
 
100
+ # Generate JSON-line submission file
101
+ try:
102
+ with open(SUBMISSION_FILE, "w") as f:
103
+ for entry in answers_payload:
104
+ json.dump(entry, f)
105
+ f.write("\n")
106
+ print(f"Successfully generated submission file: {SUBMISSION_FILE}")
107
+ except Exception as e:
108
+ print(f"Error generating submission file: {e}")
109
+ return f"Error generating submission file: {e}", pd.DataFrame(results_log)
110
+
111
  # 4. Prepare Submission
112
+ submission_data = {
113
+ "username": username.strip(),
114
+ "agent_code": agent_code,
115
+ "answers": answers_payload
116
+ }
117
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
118
  print(status_update)
119
 
 
128
  f"User: {result_data.get('username')}\n"
129
  f"Overall Score: {result_data.get('score', 'N/A')}% "
130
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
131
+ f"Submission file generated: {SUBMISSION_FILE}\n"
132
  f"Message: {result_data.get('message', 'No message received.')}"
133
  )
134
  print("Submission successful.")
 
141
  error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
142
  except requests.exceptions.JSONDecodeError:
143
  error_detail += f" Response: {e.response.text[:500]}"
144
+ status_message = f"Submission Failed: {error_detail}\nSubmission file generated: {SUBMISSION_FILE}"
145
  print(status_message)
146
  results_df = pd.DataFrame(results_log)
147
  return status_message, results_df
148
  except requests.exceptions.Timeout:
149
+ status_message = f"Submission Failed: The request timed out.\nSubmission file generated: {SUBMISSION_FILE}"
150
  print(status_message)
151
  results_df = pd.DataFrame(results_log)
152
  return status_message, results_df
153
  except requests.exceptions.RequestException as e:
154
+ status_message = f"Submission Failed: Network error - {e}\nSubmission file generated: {SUBMISSION_FILE}"
155
  print(status_message)
156
  results_df = pd.DataFrame(results_log)
157
  return status_message, results_df
158
  except Exception as e:
159
+ status_message = f"An unexpected error occurred during submission: {e}\nSubmission file generated: {SUBMISSION_FILE}"
160
  print(status_message)
161
  results_df = pd.DataFrame(results_log)
162
  return status_message, results_df
163
 
 
164
  # --- Build Gradio Interface using Blocks ---
165
  with gr.Blocks() as demo:
166
+ gr.Markdown("# Smoal Agent Evaluation Runner")
167
  gr.Markdown(
168
  """
169
  **Instructions:**
170
 
171
+ 1. Log in to your Hugging Face account using the button below.
172
+ 2. Make sure you have set up the required environment variables:
173
+ - BING_API_KEY: For web search functionality
174
+ - OPENAI_API_KEY: For GPT-3.5 model access
175
+ - HUGGINGFACE_HUB_TOKEN: For GAIA dataset access
176
+ 3. Click 'Run Evaluation & Submit All Answers' to start the evaluation.
177
+
178
+ The agent will:
179
+ - Search the web for relevant information
180
+ - Use RAG to process and retrieve context from GAIA dataset
181
+ - Generate comprehensive answers
182
+ - Create JSON-line submission file: submission.jsonl
183
  """
184
  )
185
 
186
  gr.LoginButton()
 
187
  run_button = gr.Button("Run Evaluation & Submit All Answers")
 
188
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
 
189
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
190
 
191
  run_button.click(
 
195
 
196
  if __name__ == "__main__":
197
  print("\n" + "-"*30 + " App Starting " + "-"*30)
 
198
  space_host_startup = os.getenv("SPACE_HOST")
199
+ space_id_startup = os.getenv("SPACE_ID")
200
 
201
  if space_host_startup:
202
  print(f"✅ SPACE_HOST found: {space_host_startup}")
 
204
  else:
205
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
206
 
207
+ if space_id_startup:
208
  print(f"✅ SPACE_ID found: {space_id_startup}")
209
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
210
  print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
 
213
 
214
  print("-"*(60 + len(" App Starting ")) + "\n")
215
 
216
+ print("Launching Gradio Interface for Smoal Agent Evaluation...")
217
  demo.launch(debug=True, share=False)
tools.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ from langchain.tools import DuckDuckGoSearchRun
4
+ from langchain.chains import RetrievalQA
5
+ from langchain.embeddings import OpenAIEmbeddings
6
+ from langchain.vectorstores import FAISS
7
+ from langchain.prompts import PromptTemplate
8
+ from datasets import load_dataset
9
+ from agent import SmoalAgent
10
+
11
+ # System prompt for formatting answers
12
+ SYSTEM_PROMPT = """
13
+ You are a general AI assistant. I will ask you a question. Report your thoughts, and finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER]. YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings. If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless specified otherwise. If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in the list is a number or a string.
14
+ """
15
+
16
+ # Initialize web search tool
17
+ search_tool = DuckDuckGoSearchRun()
18
+
19
+ # Create custom prompt template with system instructions
20
+ prompt_template = SYSTEM_PROMPT + "\n\nContext: {context}\nQuestion: {question}\n"
21
+ PROMPT = PromptTemplate(
22
+ template=prompt_template,
23
+ input_variables=["context", "question"]
24
+ )
25
+
26
+ # Load GAIA dataset and setup RAG components
27
+ def load_gaia_and_setup_rag():
28
+ try:
29
+ # Load GAIA dataset (requires HUGGINGFACE_HUB_TOKEN)
30
+ dataset = load_dataset("GAIA", split="train")
31
+ texts = [item['text'] for item in dataset if 'text' in item]
32
+
33
+ # Create embeddings and vector store
34
+ embeddings = OpenAIEmbeddings()
35
+ vectorstore = FAISS.from_texts(texts, embeddings)
36
+
37
+ # Create retriever and QA chain with custom prompt
38
+ retriever = vectorstore.as_retriever()
39
+ qa_chain = RetrievalQA.from_chain_type(
40
+ llm=SmoalAgent(),
41
+ chain_type="stuff",
42
+ retriever=retriever,
43
+ chain_type_kwargs={"prompt": PROMPT}
44
+ )
45
+ return qa_chain
46
+ except Exception as e:
47
+ print(f"RAG initialization error: {str(e)}")
48
+ return None
49
+
50
+ # Extract final answer from model response
51
+ def extract_final_answer(response):
52
+ """Extracts the final answer using the specified template format"""
53
+ match = re.search(r"FINAL ANSWER: (.*)", response, re.IGNORECASE)
54
+ if match:
55
+ return match.group(1).strip()
56
+ # Fallback to return full response if pattern not found
57
+ return response
58
+
59
+ # Initialize RAG chain
60
+ global rag_chain
61
+ rag_chain = load_gaia_and_setup_rag()