Arno' Francesco (GDS DS&G) commited on
Commit
cd6cf69
·
1 Parent(s): 81917a3

add tools to the agent

Browse files
Files changed (2) hide show
  1. agent_tools.py +55 -0
  2. app.py +61 -3
agent_tools.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from smolagents import tool
2
+ import numpy as np
3
+ import time
4
+ import datetime
5
+ import re
6
+ from markdownify import markdownify
7
+ import requests
8
+ from requests.exceptions import RequestException
9
+
10
+ @tool
11
+ def calculator_tool(expression: str) -> str:
12
+ """
13
+ A simple calculator that performs basic arithmetic operations.
14
+
15
+ Args:
16
+ expression: The mathematical expression to evaluate (e.g., '2 + 3 * 4').
17
+ """
18
+ # Remove any non-digit or non-operator characters from the expression
19
+ expression = re.sub(r'[^0-9+\-*/().]', '', expression)
20
+
21
+ try:
22
+ # Evaluate the expression using the built-in eval() function
23
+ result = eval(expression)
24
+ return str(result)
25
+ except (SyntaxError, ZeroDivisionError, NameError, TypeError, OverflowError):
26
+ return "Error: Invalid expression"
27
+
28
+ @tool
29
+ def visit_webpage(url: str) -> str:
30
+ """Visits a webpage at the given URL and returns its content as a markdown string.
31
+
32
+ Args:
33
+ url: The URL of the webpage to visit.
34
+
35
+ Returns:
36
+ The content of the webpage converted to Markdown, or an error message if the request fails.
37
+ """
38
+ try:
39
+ # Send a GET request to the URL
40
+ response = requests.get(url)
41
+ response.raise_for_status() # Raise an exception for bad status codes
42
+
43
+ # Convert the HTML content to Markdown
44
+ markdown_content = markdownify(response.text).strip()
45
+
46
+ # Remove multiple line breaks
47
+ markdown_content = re.sub(r"\n{3,}", "\n\n", markdown_content)
48
+
49
+ return markdown_content
50
+
51
+ except RequestException as e:
52
+ return f"Error fetching the webpage: {str(e)}"
53
+ except Exception as e:
54
+ return f"An unexpected error occurred: {str(e)}"
55
+
app.py CHANGED
@@ -3,6 +3,15 @@ import gradio as gr
3
  import requests
4
  import inspect
5
  import pandas as pd
 
 
 
 
 
 
 
 
 
6
 
7
  # (Keep Constants as is)
8
  # --- Constants ---
@@ -12,12 +21,61 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
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
  """
 
3
  import requests
4
  import inspect
5
  import pandas as pd
6
+ from smolagents import CodeAgent, HfApiModel, LiteLLMModel, Tool, DuckDuckGoSearchTool
7
+ from agent_tools import calculator_tool, visit_webpage, check_final_answer
8
+ import numpy as np
9
+ import time
10
+ import datetime
11
+ from smolagents import InferenceClientModel
12
+
13
+
14
+
15
 
16
  # (Keep Constants as is)
17
  # --- Constants ---
 
21
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
22
  class BasicAgent:
23
  def __init__(self):
24
+
25
  print("BasicAgent initialized.")
26
+ # Initialize the Hugging Face model
27
+ model = HfApiModel()
28
+ search_tool = DuckDuckGoSearchTool()
29
+
30
+ self.web_agent = CodeAgent(
31
+ tools=[search_tool, visit_webpage],
32
+ model=model,
33
+ max_steps=5,
34
+ name="web_search_agent",
35
+ description="Runs web searches for you.",
36
+ )
37
+
38
+ self.manager_agent = CodeAgent(
39
+ tools=[calculator_tool],
40
+ managed_agents=[self.web_agent],
41
+ model=model,
42
+ additional_authorized_imports=["pandas", "re", "requests", "json", "numpy"],
43
+ max_steps=10,
44
+ verbosity_level=2,
45
+ planning_interval=5,
46
+ add_base_tools=True,
47
+ final_answer_checks=[self.check_final_answer]
48
+ )
49
+
50
+ @staticmethod
51
+ def check_final_answer(final_answer, agent_memory):
52
+ prompt = f"""Here is a user-given task and the agent steps: {agent_memory.get_succinct_steps()}. \
53
+ Report your thoughts, and finish your answer with the following template:
54
+ FINAL ANSWER: [YOUR FINAL ANSWER].
55
+ YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings.
56
+ If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign \
57
+ unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), \
58
+ and write the digits in plain text unless specified otherwise. If you are asked for a comma separated list,\
59
+ apply the above rules depending of whether the element to be put in the list is a number or a string.
60
+ """
61
+ messages = [
62
+ {
63
+ "role": "user",
64
+ "content": prompt
65
+ }
66
+ ]
67
+
68
+ model = InferenceClientModel()
69
+
70
+ response = model(messages=messages)
71
+ return response
72
+
73
  def __call__(self, question: str) -> str:
74
  print(f"Agent received question (first 50 chars): {question[:50]}...")
75
+ #fixed_answer = "This is a default answer."
76
+ #print(f"Agent returning fixed answer: {fixed_answer}")
77
+ answer = self.manager_agent.run(question)
78
+ return answer
79
 
80
  def run_and_submit_all( profile: gr.OAuthProfile | None):
81
  """