tomhflau commited on
Commit
01c826c
ยท
1 Parent(s): 72f6881

updated agent with more tools

Browse files
Files changed (2) hide show
  1. app.py +156 -51
  2. requirements.txt +0 -0
app.py CHANGED
@@ -4,7 +4,7 @@ import requests
4
  import inspect
5
  import pandas as pd
6
  from dotenv import load_dotenv
7
- from huggingface_hub import InferenceClient
8
 
9
  # Load environment variables
10
  load_dotenv()
@@ -12,9 +12,92 @@ load_dotenv()
12
  # --- Constants ---
13
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  class BasicAgent:
16
  def __init__(self):
17
- print("BasicAgent initialized - using HF Inference API.")
18
 
19
  # Get HF token from environment
20
  hf_token = os.getenv("HUGGINGFACE_HUB_TOKEN") or os.getenv("HF_TOKEN")
@@ -23,64 +106,80 @@ class BasicAgent:
23
  raise ValueError("โŒ No HF token found. Please set HF_TOKEN or HUGGINGFACE_HUB_TOKEN in your .env file\n"
24
  "You can get a token from: https://huggingface.co/settings/tokens")
25
 
26
- # Initialize the Inference Client
27
  try:
28
- self.client = InferenceClient(
29
- provider="hf-inference",
30
- api_key=hf_token,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  )
32
- print("โœ… HF Inference Client initialized successfully")
 
33
  except Exception as e:
34
- print(f"โŒ Error initializing HF Inference Client: {e}")
35
  raise e
36
 
37
  def __call__(self, question: str) -> str:
38
- print(f"๐Ÿค– Agent received question: {question[:100]}...")
39
 
40
  try:
41
- print("๐Ÿ”„ Making API call to HF Inference...")
42
 
43
- # Create a more detailed prompt for better responses
44
- system_prompt = "You are a helpful AI assistant. Provide clear, accurate, and concise answers to questions."
 
 
 
 
 
 
45
 
46
- completion = self.client.chat.completions.create(
47
- model="HuggingFaceTB/SmolLM3-3B",
48
- messages=[
49
- {
50
- "role": "system",
51
- "content": system_prompt
52
- },
53
- {
54
- "role": "user",
55
- "content": question
56
- }
57
- ],
58
- max_tokens=512,
59
- temperature=0.7,
60
- )
61
 
62
- print("โœ… API call successful!")
63
- answer = completion.choices[0].message.content.strip()
64
- print(f"๐Ÿ“ Agent returning answer: {answer[:200]}...")
 
 
 
 
65
 
66
- # Ensure we're not returning empty or None answers
 
 
67
  if not answer or answer.lower().strip() == "":
68
  return "I apologize, but I couldn't generate a proper response to your question."
69
 
70
  return answer
71
 
72
  except Exception as e:
73
- error_msg = f"โŒ HF API Error: {str(e)}"
74
  print(error_msg)
75
  print(f"๐Ÿ“‹ Full error details: {repr(e)}")
76
 
77
- # Return a more informative error message
78
  return f"Sorry, I encountered an error while processing your question: {str(e)}"
79
 
80
  def test_connection(self):
81
- """Test if the HF API connection is working"""
82
  try:
83
- test_response = self("What is 2+2?")
84
  print(f"๐Ÿงช Test response: {test_response}")
85
  return True, test_response
86
  except Exception as e:
@@ -116,7 +215,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
116
 
117
  # 1. Instantiate Agent
118
  try:
119
- print("๐Ÿš€ Initializing BasicAgent...")
120
  agent = BasicAgent()
121
 
122
  # Test the agent before proceeding
@@ -156,7 +255,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
156
  # 3. Run your Agent
157
  results_log = []
158
  answers_payload = []
159
- print(f"Running agent on {len(questions_data)} questions...")
160
 
161
  for i, item in enumerate(questions_data):
162
  task_id = item.get("task_id")
@@ -165,18 +264,19 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
165
  print(f"Skipping item with missing task_id or question: {item}")
166
  continue
167
 
168
- print(f"Processing question {i+1}/{len(questions_data)}: {task_id}")
169
  try:
170
  submitted_answer = agent(question_text)
171
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
172
  results_log.append({
173
  "Task ID": task_id,
174
  "Question": question_text[:100] + "..." if len(question_text) > 100 else question_text,
175
- "Submitted Answer": submitted_answer[:200] + "..." if len(submitted_answer) > 200 else submitted_answer
176
  })
 
177
  except Exception as e:
178
  error_msg = f"AGENT ERROR: {e}"
179
- print(f"Error running agent on task {task_id}: {e}")
180
  answers_payload.append({"task_id": task_id, "submitted_answer": error_msg})
181
  results_log.append({
182
  "Task ID": task_id,
@@ -194,7 +294,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
194
  "agent_code": agent_code,
195
  "answers": answers_payload
196
  }
197
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
198
  print(status_update)
199
 
200
  # 5. Submit
@@ -243,19 +343,24 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
243
 
244
  # --- Build Gradio Interface using Blocks ---
245
  with gr.Blocks() as demo:
246
- gr.Markdown("# Basic Agent Evaluation Runner")
247
  gr.Markdown(
248
  """
249
  **Instructions:**
250
 
251
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
252
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
253
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
 
 
 
 
 
 
 
254
 
255
  ---
256
- **Disclaimers:**
257
- 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).
258
- 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.
259
  """
260
  )
261
 
@@ -272,7 +377,7 @@ with gr.Blocks() as demo:
272
  )
273
 
274
  if __name__ == "__main__":
275
- print("\n" + "-"*30 + " App Starting " + "-"*30)
276
  # Check for SPACE_HOST and SPACE_ID at startup for information
277
  space_host_startup = os.getenv("SPACE_HOST")
278
  space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
@@ -290,7 +395,7 @@ if __name__ == "__main__":
290
  else:
291
  print("โ„น๏ธ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
292
 
293
- print("-"*(60 + len(" App Starting ")) + "\n")
294
 
295
- print("Launching Gradio Interface for Basic Agent Evaluation...")
296
  demo.launch(debug=True, share=False)
 
4
  import inspect
5
  import pandas as pd
6
  from dotenv import load_dotenv
7
+ from smolagents import CodeAgent, DuckDuckGoSearchTool, FinalAnswerTool, InferenceClientModel, Tool, tool, VisitWebpageTool
8
 
9
  # Load environment variables
10
  load_dotenv()
 
12
  # --- Constants ---
13
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
14
 
15
+ # --- Custom Tools for GAIA Dataset ---
16
+
17
+ @tool
18
+ def calculate_math(expression: str) -> str:
19
+ """
20
+ Calculates mathematical expressions safely.
21
+ Args:
22
+ expression: Mathematical expression to evaluate (e.g., "2 + 2", "sqrt(16)")
23
+ """
24
+ try:
25
+ import math
26
+ import re
27
+
28
+ # Replace common math functions
29
+ expression = expression.replace("sqrt", "math.sqrt")
30
+ expression = expression.replace("log", "math.log")
31
+ expression = expression.replace("sin", "math.sin")
32
+ expression = expression.replace("cos", "math.cos")
33
+ expression = expression.replace("tan", "math.tan")
34
+ expression = expression.replace("pi", "math.pi")
35
+ expression = expression.replace("e", "math.e")
36
+
37
+ # Safe evaluation
38
+ allowed_names = {
39
+ k: v for k, v in math.__dict__.items() if not k.startswith("__")
40
+ }
41
+ allowed_names.update({"abs": abs, "round": round, "min": min, "max": max})
42
+
43
+ result = eval(expression, {"__builtins__": {}}, allowed_names)
44
+ return str(result)
45
+ except Exception as e:
46
+ return f"Error calculating: {str(e)}"
47
+
48
+ @tool
49
+ def analyze_data(data_description: str) -> str:
50
+ """
51
+ Analyzes data patterns, statistics, or trends described in text.
52
+ Args:
53
+ data_description: Description of data to analyze
54
+ """
55
+ # This is a simplified analysis tool
56
+ # In a real scenario, this could connect to data analysis libraries
57
+ return f"Data analysis for: {data_description}. Please provide specific data or use web search for current statistics."
58
+
59
+ @tool
60
+ def fact_checker(claim: str) -> str:
61
+ """
62
+ Helps verify factual claims by suggesting verification approaches.
63
+ Args:
64
+ claim: The factual claim to verify
65
+ """
66
+ return f"To verify '{claim}', I recommend using web search for recent, authoritative sources. Cross-reference multiple reliable sources."
67
+
68
+ class AdvancedReasoningTool(Tool):
69
+ name = "advanced_reasoning"
70
+ description = """
71
+ This tool helps break down complex multi-step reasoning problems.
72
+ It provides structured thinking for complex questions."""
73
+
74
+ inputs = {
75
+ "problem": {
76
+ "type": "string",
77
+ "description": "A complex problem that requires step-by-step reasoning",
78
+ },
79
+ "problem_type": {
80
+ "type": "string",
81
+ "description": "Type of problem (e.g., 'logical', 'mathematical', 'analytical', 'research')",
82
+ }
83
+ }
84
+
85
+ output_type = "string"
86
+
87
+ def forward(self, problem: str, problem_type: str = "general"):
88
+ reasoning_frameworks = {
89
+ "logical": "1. Identify premises\n2. Apply logical rules\n3. Check for contradictions\n4. Draw conclusions",
90
+ "mathematical": "1. Understand what's being asked\n2. Identify known values\n3. Choose appropriate formulas\n4. Calculate step-by-step\n5. Verify the answer",
91
+ "analytical": "1. Break down into components\n2. Analyze each part\n3. Look for patterns/relationships\n4. Synthesize findings",
92
+ "research": "1. Define research question\n2. Identify reliable sources\n3. Gather information\n4. Cross-reference facts\n5. Form conclusion"
93
+ }
94
+
95
+ framework = reasoning_frameworks.get(problem_type.lower(), reasoning_frameworks["analytical"])
96
+ return f"Problem: {problem}\n\nSuggested approach ({problem_type}):\n{framework}"
97
+
98
  class BasicAgent:
99
  def __init__(self):
100
+ print("๐Ÿค– BasicAgent initialized with smolagents framework.")
101
 
102
  # Get HF token from environment
103
  hf_token = os.getenv("HUGGINGFACE_HUB_TOKEN") or os.getenv("HF_TOKEN")
 
106
  raise ValueError("โŒ No HF token found. Please set HF_TOKEN or HUGGINGFACE_HUB_TOKEN in your .env file\n"
107
  "You can get a token from: https://huggingface.co/settings/tokens")
108
 
 
109
  try:
110
+ # Initialize model with HF token
111
+ model = InferenceClientModel(
112
+ model_id="HuggingFaceTB/SmolLM3-3B",
113
+ token=hf_token
114
+ )
115
+
116
+ # Create agent with comprehensive tools
117
+ self.agent = CodeAgent(
118
+ tools=[
119
+ DuckDuckGoSearchTool(),
120
+ VisitWebpageTool(),
121
+ calculate_math,
122
+ analyze_data,
123
+ fact_checker,
124
+ AdvancedReasoningTool(),
125
+ FinalAnswerTool()
126
+ ],
127
+ model=model,
128
+ max_steps=15, # Increased for complex GAIA questions
129
+ verbosity_level=2
130
  )
131
+ print("โœ… SmolAgent initialized successfully with all tools")
132
+
133
  except Exception as e:
134
+ print(f"โŒ Error initializing SmolAgent: {e}")
135
  raise e
136
 
137
  def __call__(self, question: str) -> str:
138
+ print(f"๐Ÿค– SmolAgent received question: {question[:100]}...")
139
 
140
  try:
141
+ print("๐Ÿ”„ Running SmolAgent with tools...")
142
 
143
+ # Add context to help the agent understand it should provide a final answer
144
+ enhanced_question = f"""
145
+ Please answer the following question thoroughly and accurately. Use the available tools to search for information, visit websites, perform calculations, or analyze data as needed.
146
+
147
+ Question: {question}
148
+
149
+ Please provide a clear, specific final answer at the end.
150
+ """
151
 
152
+ result = self.agent.run(enhanced_question)
153
+
154
+ print("โœ… SmolAgent completed successfully!")
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
+ # Extract the final answer if it's wrapped in agent output
157
+ if hasattr(result, 'content'):
158
+ answer = result.content
159
+ elif isinstance(result, dict) and 'output' in result:
160
+ answer = result['output']
161
+ else:
162
+ answer = str(result)
163
 
164
+ print(f"๐Ÿ“ SmolAgent returning answer: {answer[:200]}...")
165
+
166
+ # Ensure we have a meaningful answer
167
  if not answer or answer.lower().strip() == "":
168
  return "I apologize, but I couldn't generate a proper response to your question."
169
 
170
  return answer
171
 
172
  except Exception as e:
173
+ error_msg = f"โŒ SmolAgent Error: {str(e)}"
174
  print(error_msg)
175
  print(f"๐Ÿ“‹ Full error details: {repr(e)}")
176
 
 
177
  return f"Sorry, I encountered an error while processing your question: {str(e)}"
178
 
179
  def test_connection(self):
180
+ """Test if the agent is working properly"""
181
  try:
182
+ test_response = self("What is the capital of France?")
183
  print(f"๐Ÿงช Test response: {test_response}")
184
  return True, test_response
185
  except Exception as e:
 
215
 
216
  # 1. Instantiate Agent
217
  try:
218
+ print("๐Ÿš€ Initializing SmolAgent...")
219
  agent = BasicAgent()
220
 
221
  # Test the agent before proceeding
 
255
  # 3. Run your Agent
256
  results_log = []
257
  answers_payload = []
258
+ print(f"Running SmolAgent on {len(questions_data)} questions...")
259
 
260
  for i, item in enumerate(questions_data):
261
  task_id = item.get("task_id")
 
264
  print(f"Skipping item with missing task_id or question: {item}")
265
  continue
266
 
267
+ print(f"๐Ÿ”„ Processing question {i+1}/{len(questions_data)}: {task_id}")
268
  try:
269
  submitted_answer = agent(question_text)
270
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
271
  results_log.append({
272
  "Task ID": task_id,
273
  "Question": question_text[:100] + "..." if len(question_text) > 100 else question_text,
274
+ "Submitted Answer": submitted_answer[:300] + "..." if len(submitted_answer) > 300 else submitted_answer
275
  })
276
+ print(f"โœ… Completed question {i+1}")
277
  except Exception as e:
278
  error_msg = f"AGENT ERROR: {e}"
279
+ print(f"โŒ Error running agent on task {task_id}: {e}")
280
  answers_payload.append({"task_id": task_id, "submitted_answer": error_msg})
281
  results_log.append({
282
  "Task ID": task_id,
 
294
  "agent_code": agent_code,
295
  "answers": answers_payload
296
  }
297
+ status_update = f"SmolAgent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
298
  print(status_update)
299
 
300
  # 5. Submit
 
343
 
344
  # --- Build Gradio Interface using Blocks ---
345
  with gr.Blocks() as demo:
346
+ gr.Markdown("# SmolAgent Evaluation Runner for GAIA")
347
  gr.Markdown(
348
  """
349
  **Instructions:**
350
 
351
+ 1. This agent uses smolagents framework with multiple tools:
352
+ - ๐Ÿ” **DuckDuckGoSearchTool**: Web search capabilities
353
+ - ๐ŸŒ **VisitWebpageTool**: Can visit and read web pages
354
+ - ๐Ÿงฎ **Math Calculator**: Handles mathematical calculations
355
+ - ๐Ÿ“Š **Data Analysis**: Basic data analysis capabilities
356
+ - โœ… **Fact Checker**: Helps verify claims
357
+ - ๐Ÿง  **Advanced Reasoning**: Structured problem-solving
358
+
359
+ 2. Log in to your Hugging Face account using the button below.
360
+ 3. Click 'Run Evaluation & Submit All Answers' to start the evaluation.
361
 
362
  ---
363
+ **Note:** This agent is designed for the GAIA dataset and can handle complex, multi-step reasoning tasks.
 
 
364
  """
365
  )
366
 
 
377
  )
378
 
379
  if __name__ == "__main__":
380
+ print("\n" + "-"*30 + " SmolAgent Starting " + "-"*30)
381
  # Check for SPACE_HOST and SPACE_ID at startup for information
382
  space_host_startup = os.getenv("SPACE_HOST")
383
  space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
 
395
  else:
396
  print("โ„น๏ธ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
397
 
398
+ print("-"*(60 + len(" SmolAgent Starting ")) + "\n")
399
 
400
+ print("Launching Gradio Interface for SmolAgent GAIA Evaluation...")
401
  demo.launch(debug=True, share=False)
requirements.txt CHANGED
Binary files a/requirements.txt and b/requirements.txt differ