Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,28 +1,100 @@
|
|
1 |
-
from smolagents import CodeAgent,
|
2 |
import datetime
|
3 |
import requests
|
4 |
import pytz
|
5 |
import yaml
|
|
|
|
|
|
|
6 |
from tools.final_answer import FinalAnswerTool
|
7 |
-
import
|
|
|
|
|
|
|
|
|
8 |
|
9 |
from Gradio_UI import GradioUI
|
10 |
|
|
|
11 |
# Below is an example of a tool that does nothing. Amaze us with your creativity !
|
12 |
@tool
|
13 |
def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type
|
14 |
#Keep this format for the description / args / args description but feel free to modify the tool
|
15 |
-
"""A tool that does nothing yet
|
16 |
Args:
|
17 |
arg1: the first argument
|
18 |
arg2: the second argument
|
19 |
"""
|
20 |
return "What magic will you build ?"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
@tool
|
23 |
def search_flights(departure: str, destination: str, date: str) -> str:
|
24 |
"""Finds flights from departure to destination on the given date using DuckDuckGo.
|
25 |
-
|
26 |
Args:
|
27 |
departure: The city or airport code where the flight starts.
|
28 |
destination: The city or airport code where the flight ends.
|
@@ -35,12 +107,14 @@ def search_flights(departure: str, destination: str, date: str) -> str:
|
|
35 |
search_results = DuckDuckGoSearchTool()(query) # Calls DuckDuckGo search
|
36 |
return f"Here are some flight options:\n{search_results}"
|
37 |
|
38 |
-
|
|
|
|
|
39 |
|
40 |
@tool
|
41 |
def convert_currency(amount: float, from_currency: str, to_currency: str) -> str:
|
42 |
"""Converts currency from one to another using FreeCurrencyAPI.
|
43 |
-
|
44 |
Args:
|
45 |
amount: The amount to convert.
|
46 |
from_currency: The original currency (e.g., "USD").
|
@@ -64,6 +138,7 @@ def convert_currency(amount: float, from_currency: str, to_currency: str) -> str
|
|
64 |
|
65 |
except Exception as e:
|
66 |
return f"Error fetching exchange rates: {str(e)}"
|
|
|
67 |
|
68 |
chat_history = [] # Store conversation history
|
69 |
|
@@ -73,7 +148,7 @@ def chat_with_ai(message: str) -> str:
|
|
73 |
Args:
|
74 |
message: The user's message.
|
75 |
"""
|
76 |
-
global chat_history
|
77 |
|
78 |
# Keep the last 5 messages for context
|
79 |
if len(chat_history) > 5:
|
@@ -88,9 +163,9 @@ def chat_with_ai(message: str) -> str:
|
|
88 |
# ✅ Ensure AI response is handled correctly
|
89 |
try:
|
90 |
response = model(formatted_history) # Call model
|
91 |
-
|
92 |
# ✅ Handle both string and dictionary responses
|
93 |
-
if isinstance(response, dict):
|
94 |
response_text = response.get("text", str(response)) # Extract text if available
|
95 |
else:
|
96 |
response_text = str(response) # Convert non-dict responses to string
|
@@ -101,6 +176,7 @@ def chat_with_ai(message: str) -> str:
|
|
101 |
|
102 |
except Exception as e:
|
103 |
return f"Error processing chat: {str(e)}"
|
|
|
104 |
|
105 |
@tool
|
106 |
def get_current_time_in_timezone(timezone: str) -> str:
|
@@ -116,12 +192,14 @@ def get_current_time_in_timezone(timezone: str) -> str:
|
|
116 |
return f"The current local time in {timezone} is: {local_time}"
|
117 |
except Exception as e:
|
118 |
return f"Error fetching time for timezone '{timezone}': {str(e)}"
|
119 |
-
|
120 |
|
121 |
final_answer = FinalAnswerTool()
|
122 |
|
|
|
|
|
123 |
# If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
|
124 |
-
# model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
|
125 |
|
126 |
model = HfApiModel(
|
127 |
max_tokens=512,
|
@@ -129,14 +207,31 @@ temperature=0.5,
|
|
129 |
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may be overloaded
|
130 |
custom_role_conversions=None,
|
131 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
# Import tool from Hub
|
135 |
-
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
|
136 |
|
137 |
with open("prompts.yaml", 'r') as stream:
|
138 |
prompt_templates = yaml.safe_load(stream)
|
139 |
-
|
140 |
agent = CodeAgent(
|
141 |
model=model,
|
142 |
tools=[
|
@@ -145,13 +240,14 @@ agent = CodeAgent(
|
|
145 |
my_custom_tool,
|
146 |
chat_with_ai, # Regular chat tool
|
147 |
search_flights,
|
|
|
148 |
#scrape_webpage,
|
149 |
convert_currency,
|
150 |
#get_weather,
|
151 |
#generate_ai_image
|
152 |
],
|
153 |
-
max_steps=
|
154 |
-
verbosity_level=
|
155 |
prompt_templates=prompt_templates
|
156 |
)
|
157 |
|
|
|
1 |
+
from smolagents import CodeAgent, HfApiModel,load_tool,tool
|
2 |
import datetime
|
3 |
import requests
|
4 |
import pytz
|
5 |
import yaml
|
6 |
+
import os
|
7 |
+
import asyncio
|
8 |
+
import json
|
9 |
from tools.final_answer import FinalAnswerTool
|
10 |
+
from tools.web_search import DuckDuckGoSearchTool
|
11 |
+
from bs4 import BeautifulSoup
|
12 |
+
from duckduckgo_search import DDGS
|
13 |
+
import re
|
14 |
+
from typing import List, Dict, Any
|
15 |
|
16 |
from Gradio_UI import GradioUI
|
17 |
|
18 |
+
#################################################################
|
19 |
# Below is an example of a tool that does nothing. Amaze us with your creativity !
|
20 |
@tool
|
21 |
def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type
|
22 |
#Keep this format for the description / args / args description but feel free to modify the tool
|
23 |
+
"""A tool that does nothing yet
|
24 |
Args:
|
25 |
arg1: the first argument
|
26 |
arg2: the second argument
|
27 |
"""
|
28 |
return "What magic will you build ?"
|
29 |
+
##############################################################
|
30 |
+
|
31 |
+
@tool
|
32 |
+
def visit_webpage(url: str) -> Dict[str, Any]:
|
33 |
+
"""Visits a webpage and extracts ingredients and instructions.
|
34 |
+
Args:
|
35 |
+
url: The recipe URL.
|
36 |
+
Returns:
|
37 |
+
A dictionary containing 'ingredients' and 'instructions', or an error message if the URL is invalid.
|
38 |
+
"""
|
39 |
+
try:
|
40 |
+
# Validate URL format before making a request
|
41 |
+
if not url.startswith("http"):
|
42 |
+
return {"error": f"Invalid URL format: {url}"}
|
43 |
+
|
44 |
+
response = requests.get(url, timeout=10, headers={
|
45 |
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
46 |
+
})
|
47 |
+
response.raise_for_status() # Raise an error for 404, 403, etc.
|
48 |
+
|
49 |
+
soup = BeautifulSoup(response.content, 'html.parser')
|
50 |
+
|
51 |
+
# Extract ingredients
|
52 |
+
ingredients = [tag.get_text(strip=True) for tag in soup.select('ul li, .ingredient')]
|
53 |
+
if not ingredients:
|
54 |
+
ingredients = [tag.get_text(strip=True) for tag in soup.find_all('li') if "ingredient" in tag.get_text(strip=True).lower()]
|
55 |
+
|
56 |
+
# Extract instructions
|
57 |
+
instructions = [tag.get_text(strip=True) for tag in soup.select('ol li, .instruction, .step')]
|
58 |
+
if not instructions:
|
59 |
+
instructions = [tag.get_text(strip=True) for tag in soup.find_all('p') if "step" in tag.get_text(strip=True).lower()]
|
60 |
+
|
61 |
+
return {
|
62 |
+
"ingredients": ingredients if ingredients else [],
|
63 |
+
"instructions": instructions if instructions else []
|
64 |
+
}
|
65 |
+
|
66 |
+
except requests.exceptions.HTTPError as http_err:
|
67 |
+
return {"error": f"HTTP error {response.status_code}: {http_err}"}
|
68 |
+
|
69 |
+
except requests.exceptions.RequestException as req_err:
|
70 |
+
return {"error": f"Request failed: {req_err}"}
|
71 |
+
|
72 |
+
except Exception as e:
|
73 |
+
return {"error": f"Failed to scrape {url}: {str(e)}"}
|
74 |
+
|
75 |
+
###############################################################
|
76 |
+
|
77 |
+
@tool
|
78 |
+
def web_search(query: str) -> str:
|
79 |
+
"""Searches the web using DuckDuckGo and formats output in a code block.
|
80 |
+
|
81 |
+
Args:
|
82 |
+
query: The search query.
|
83 |
+
|
84 |
+
Returns:
|
85 |
+
A string formatted as Python code.
|
86 |
+
"""
|
87 |
+
result = DuckDuckGoSearchTool()(query)
|
88 |
+
|
89 |
+
# 🔹 Ensure the response is wrapped as Python code
|
90 |
+
return f"{result}"
|
91 |
+
|
92 |
+
###############################################################
|
93 |
|
94 |
@tool
|
95 |
def search_flights(departure: str, destination: str, date: str) -> str:
|
96 |
"""Finds flights from departure to destination on the given date using DuckDuckGo.
|
97 |
+
|
98 |
Args:
|
99 |
departure: The city or airport code where the flight starts.
|
100 |
destination: The city or airport code where the flight ends.
|
|
|
107 |
search_results = DuckDuckGoSearchTool()(query) # Calls DuckDuckGo search
|
108 |
return f"Here are some flight options:\n{search_results}"
|
109 |
|
110 |
+
################################################################
|
111 |
+
|
112 |
+
API_KEY = os.getenv("FREECURRENCYAPI_KEY") # 🔹 Your API key
|
113 |
|
114 |
@tool
|
115 |
def convert_currency(amount: float, from_currency: str, to_currency: str) -> str:
|
116 |
"""Converts currency from one to another using FreeCurrencyAPI.
|
117 |
+
|
118 |
Args:
|
119 |
amount: The amount to convert.
|
120 |
from_currency: The original currency (e.g., "USD").
|
|
|
138 |
|
139 |
except Exception as e:
|
140 |
return f"Error fetching exchange rates: {str(e)}"
|
141 |
+
########################################################################
|
142 |
|
143 |
chat_history = [] # Store conversation history
|
144 |
|
|
|
148 |
Args:
|
149 |
message: The user's message.
|
150 |
"""
|
151 |
+
global chat_history
|
152 |
|
153 |
# Keep the last 5 messages for context
|
154 |
if len(chat_history) > 5:
|
|
|
163 |
# ✅ Ensure AI response is handled correctly
|
164 |
try:
|
165 |
response = model(formatted_history) # Call model
|
166 |
+
|
167 |
# ✅ Handle both string and dictionary responses
|
168 |
+
if isinstance(response, dict):
|
169 |
response_text = response.get("text", str(response)) # Extract text if available
|
170 |
else:
|
171 |
response_text = str(response) # Convert non-dict responses to string
|
|
|
176 |
|
177 |
except Exception as e:
|
178 |
return f"Error processing chat: {str(e)}"
|
179 |
+
#########################################################################
|
180 |
|
181 |
@tool
|
182 |
def get_current_time_in_timezone(timezone: str) -> str:
|
|
|
192 |
return f"The current local time in {timezone} is: {local_time}"
|
193 |
except Exception as e:
|
194 |
return f"Error fetching time for timezone '{timezone}': {str(e)}"
|
195 |
+
#########################################################################
|
196 |
|
197 |
final_answer = FinalAnswerTool()
|
198 |
|
199 |
+
########################################################################
|
200 |
+
|
201 |
# If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
|
202 |
+
# model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
|
203 |
|
204 |
model = HfApiModel(
|
205 |
max_tokens=512,
|
|
|
207 |
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may be overloaded
|
208 |
custom_role_conversions=None,
|
209 |
)
|
210 |
+
#deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
|
211 |
+
#deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B
|
212 |
+
#Qwen/Qwen2.5-Coder-32B-Instruct
|
213 |
+
#deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
|
214 |
+
#oieieio/Qwen2.5-0.5B-Instruct
|
215 |
+
#oieieio/meta-llama-Llama-3.2-1B-Instruct
|
216 |
+
###############################################################################
|
217 |
+
|
218 |
+
|
219 |
+
|
220 |
|
221 |
|
222 |
+
##############################################################################
|
223 |
+
|
224 |
+
|
225 |
+
# web_search settings, specific/custom
|
226 |
+
hotels = web_search("Recommended hotels in Paris with pricing and location details")
|
227 |
+
restaurants = web_search("Top-rated local restaurants in Paris, different budgets and cuisines")
|
228 |
+
|
229 |
# Import tool from Hub
|
230 |
+
#image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
|
231 |
|
232 |
with open("prompts.yaml", 'r') as stream:
|
233 |
prompt_templates = yaml.safe_load(stream)
|
234 |
+
|
235 |
agent = CodeAgent(
|
236 |
model=model,
|
237 |
tools=[
|
|
|
240 |
my_custom_tool,
|
241 |
chat_with_ai, # Regular chat tool
|
242 |
search_flights,
|
243 |
+
web_search,
|
244 |
#scrape_webpage,
|
245 |
convert_currency,
|
246 |
#get_weather,
|
247 |
#generate_ai_image
|
248 |
],
|
249 |
+
max_steps=10,
|
250 |
+
verbosity_level=1,
|
251 |
prompt_templates=prompt_templates
|
252 |
)
|
253 |
|