juanmaguitar commited on
Commit
4bf5aea
·
1 Parent(s): 00ebd28

lets try with secret HF_TOKEN

Browse files
Files changed (4) hide show
  1. _app.py +0 -218
  2. _requirements.txt +0 -9
  3. app.py +185 -93
  4. requirements.txt +9 -9
_app.py DELETED
@@ -1,218 +0,0 @@
1
- import os
2
- from dotenv import load_dotenv
3
- from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
4
- import datetime
5
- import requests
6
- import pytz
7
- import yaml
8
- from tools.final_answer import FinalAnswerTool
9
- from tools.wordpress_post import WordPressPostTool
10
- from tools.blog_generator import BlogGeneratorTool
11
- from tools.visit_webpage import VisitWebpageTool
12
- from tools.web_search import DuckDuckGoSearchTool
13
-
14
- from Gradio_UI import GradioUI
15
-
16
- # Load environment variables
17
- load_dotenv()
18
-
19
- # Verify required environment variables
20
- if not os.getenv("OPENWEATHER_API_KEY"):
21
- print("Warning: OPENWEATHER_API_KEY not set. Weather functionality will be limited.")
22
-
23
- # Load WordPress credentials from environment variables
24
- wordpress_credentials = {
25
- 'site_url': os.getenv('WORDPRESS_SITE_URL'),
26
- 'username': os.getenv('WORDPRESS_USERNAME'),
27
- 'app_password': os.getenv('WORDPRESS_APP_PASSWORD')
28
- }
29
-
30
- # Verify WordPress credentials
31
- if not all(wordpress_credentials.values()):
32
- print("Warning: WordPress credentials not fully set. Blog functionality will be limited.")
33
-
34
-
35
- @tool
36
- def get_current_time_in_timezone(timezone: str) -> str:
37
- """A tool that fetches the current local time in a specified timezone.
38
- Args:
39
- timezone: A string representing a valid timezone (e.g., 'America/New_York').
40
- """
41
- try:
42
- # Create timezone object
43
- tz = pytz.timezone(timezone)
44
- # Get current time in that timezone
45
- local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
46
- return f"The current local time in {timezone} is: {local_time}"
47
- except Exception as e:
48
- return f"Error fetching time for timezone '{timezone}': {str(e)}"
49
-
50
-
51
- @tool
52
- def quick_research(query: str, max_results: int = 3) -> str:
53
- """Searches the web for travel-related information and provides a concise summary.
54
- Args:
55
- query: The search query to look up (typically a destination or attraction)
56
- max_results: Maximum number of search results to consider (default: 3)
57
- """
58
- search_tool = DuckDuckGoSearchTool()
59
-
60
- try:
61
- # Add travel-specific terms to the query
62
- travel_query = f"{query} travel guide tourist attractions things to do"
63
- search_results = search_tool.search(
64
- travel_query, max_results=max_results)
65
-
66
- if not search_results:
67
- return "No travel information found for the given destination."
68
-
69
- # Format the results
70
- formatted_results = []
71
- for i, result in enumerate(search_results, 1):
72
- title = result.get('title', 'No title')
73
- snippet = result.get('snippet', 'No description available')
74
- url = result.get('link', 'No link available')
75
-
76
- formatted_results.append(
77
- f"{i}. {title}\n"
78
- f"Travel Info: {snippet}\n"
79
- f"Source: {url}\n"
80
- )
81
-
82
- return "Travel Research Results:\n\n" + "\n".join(formatted_results)
83
-
84
- except Exception as e:
85
- return f"Error performing travel research: {str(e)}"
86
-
87
-
88
- @tool
89
- def get_weather(city: str) -> str:
90
- """Fetches current weather information for a given city.
91
- Args:
92
- city: Name of the city to get weather for
93
- """
94
- try:
95
- # Using OpenWeatherMap API (you'll need to add your API key)
96
- # Get API key from environment variable
97
- API_KEY = os.getenv("OPENWEATHER_API_KEY")
98
- base_url = "http://api.openweathermap.org/data/2.5/weather"
99
-
100
- params = {
101
- 'q': city,
102
- 'appid': API_KEY,
103
- 'units': 'metric' # For Celsius
104
- }
105
-
106
- response = requests.get(base_url, params=params)
107
- data = response.json()
108
-
109
- if response.status_code == 200:
110
- temp = data['main']['temp']
111
- weather_desc = data['weather'][0]['description']
112
- humidity = data['main']['humidity']
113
-
114
- return (f"Weather in {city}:\n"
115
- f"Temperature: {temp}°C\n"
116
- f"Conditions: {weather_desc}\n"
117
- f"Humidity: {humidity}%")
118
- else:
119
- return f"Error: Could not fetch weather for {city}"
120
-
121
- except Exception as e:
122
- return f"Error fetching weather data: {str(e)}"
123
-
124
-
125
- final_answer = FinalAnswerTool()
126
- visit_webpage = VisitWebpageTool()
127
- web_search = DuckDuckGoSearchTool()
128
-
129
- # 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:
130
- # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
131
-
132
- # it is possible that this model may be overloaded
133
- # model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
134
-
135
- model = HfApiModel(
136
- max_tokens=1024,
137
- temperature=0.5,
138
- # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud',
139
- model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
140
- # model_id='mistralai/Mistral-7B-Instruct',
141
- token=os.getenv("HUGGINGFACEHUB_API_TOKEN"), # Ensure this is set
142
- custom_role_conversions=None,
143
- top_p=0.9,
144
- frequency_penalty=0.0,
145
- presence_penalty=0.0,
146
- )
147
-
148
- # Add error handling wrapper for the model
149
-
150
-
151
- def safe_model_call(*args, **kwargs):
152
- try:
153
- return model(*args, **kwargs)
154
- except Exception as e:
155
- print(f"Model error: {str(e)}")
156
- return "I apologize, but I encountered an error while processing your request. Please try again with a shorter or simpler query."
157
-
158
-
159
- # Override the model's forward method with our safe version
160
- model.forward = safe_model_call
161
-
162
- # Import tool from Hub
163
- image_generation_tool = load_tool(
164
- "agents-course/text-to-image", trust_remote_code=True)
165
-
166
- with open("prompts.yaml", 'r') as stream:
167
- prompt_templates = yaml.safe_load(stream)
168
-
169
- # Initialize WordPress tools
170
- wordpress_post = WordPressPostTool(wordpress_credentials)
171
- blog_generator = BlogGeneratorTool(model=model)
172
-
173
- agent = CodeAgent(
174
- model=model,
175
- tools=[
176
- final_answer,
177
- get_current_time_in_timezone,
178
- image_generation_tool,
179
- quick_research,
180
- get_weather,
181
- wordpress_post,
182
- blog_generator,
183
- visit_webpage,
184
- web_search
185
- ],
186
- max_steps=6,
187
- verbosity_level=1,
188
- grammar=None,
189
- planning_interval=None,
190
- name=None,
191
- description=None,
192
- prompt_templates=prompt_templates
193
- )
194
-
195
- # Update system prompt to include WordPress capabilities
196
- prompt_templates["system_prompt"] += """
197
-
198
- You are also capable of managing a WordPress blog through the following tools:
199
- - wordpress_auth: Manages WordPress authentication (site URL, username, password)
200
- - wordpress_post: Publishes posts to WordPress
201
- - blog_generator: Generates AI-written blog posts
202
-
203
- Before using WordPress features, you must ensure credentials are set using wordpress_auth.
204
- Always check credentials before attempting to post content.
205
-
206
- Example WordPress workflow:
207
- 1. Set credentials (first time only)
208
- 2. Generate blog content
209
- 3. Publish to WordPress
210
-
211
- Remember to:
212
- - Validate WordPress credentials before posting
213
- - Generate high-quality, relevant content
214
- - Handle errors gracefully
215
- - Provide clear status updates to the user
216
- """
217
-
218
- GradioUI(agent).launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_requirements.txt DELETED
@@ -1,9 +0,0 @@
1
- markdownify>=0.7.0
2
- smolagents>=0.1.0
3
- requests>=2.31.0
4
- duckduckgo_search>=4.1.0
5
- pandas>=2.0.0
6
- pytz>=2024.1
7
- pyyaml>=6.0.1
8
- gradio>=5.15.0
9
- python-dotenv>=1.0.0
 
 
 
 
 
 
 
 
 
 
app.py CHANGED
@@ -1,29 +1,35 @@
1
- from smolagents import CodeAgent, tool, OpenAIServerModel, FinalAnswerTool, ToolCallingAgent
 
 
2
  import datetime
 
3
  import pytz
4
- import yfinance as yf
5
- import os
 
 
 
 
 
6
  from Gradio_UI import GradioUI
7
 
8
- # Fetch the API key from the environment variable (if needed)
9
- API_KEY = os.getenv("HUGGINGFACEHUB_API_TOKEN")
10
 
 
 
 
11
 
12
- @tool
13
- def get_currency_rate(currency_pair: str) -> str:
14
- """Fetches the current exchange rate for a given currency pair (e.g., 'USD-EUR').
15
- Args:
16
- currency_pair: The currency pair to query, formatted as 'BASE-CURRENCY'.
17
- """
18
- try:
19
- base, target = currency_pair.split("-")
20
- # Use yfinance to get the exchange rate
21
- ticker = f"{base}{target}=X" # Format for yfinance (e.g., "USDEUR=X")
22
- data = yf.Ticker(ticker)
23
- rate = data.history(period="1d")["Close"].iloc[-1].astype(str)
24
- return f"Current {currency_pair} rate: {rate}"
25
- except Exception as e:
26
- return f"Error fetching rate: {str(e)}"
27
 
28
 
29
  @tool
@@ -42,85 +48,171 @@ def get_current_time_in_timezone(timezone: str) -> str:
42
  return f"Error fetching time for timezone '{timezone}': {str(e)}"
43
 
44
 
45
- # Set up the model
46
- model = OpenAIServerModel(
47
- model_id="deepseek-chat",
48
- api_base="https://api.deepseek.com",
49
- api_key=API_KEY
50
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- # Load tools
53
  final_answer = FinalAnswerTool()
54
- currency_tool = get_currency_rate
55
- time_tool = get_current_time_in_timezone
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
- # Create the agent
58
- agent = ToolCallingAgent(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  model=model,
60
- tools=[currency_tool, time_tool, final_answer],
61
- max_steps=2,
62
- verbosity_level=1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  )
64
 
65
- example_usage = """
66
- ### Example Usage
67
- 1. **Currency Rate**: Ask for the exchange rate of a currency pair.
68
- - Example: "What is the current exchange rate for USD to JPY?"
69
- - Example: "Get the EUR to GBP rate."
 
 
 
 
 
70
 
71
- 2. **Current Time**: Ask for the current time in a specific timezone.
72
- - Example: "What is the current time in America/New_York?"
73
- - Example: "Get the time in Asia/Tokyo."
 
 
 
 
 
 
 
74
  """
75
 
76
- # Extend the GradioUI class to include the example usage
77
-
78
-
79
- class CustomGradioUI(GradioUI):
80
- def __init__(self, agent, description: str = "", **kwargs):
81
- super().__init__(agent, **kwargs)
82
- self.description = description
83
-
84
- def launch(self, **kwargs):
85
- import gradio as gr
86
-
87
- with gr.Blocks(fill_height=True) as demo:
88
- # Add the description as a Markdown component
89
- if self.description:
90
- gr.Markdown(self.description)
91
-
92
- # Add the existing chatbot and input components
93
- stored_messages = gr.State([])
94
- file_uploads_log = gr.State([])
95
- chatbot = gr.Chatbot(
96
- label="Agent",
97
- type="messages",
98
- avatar_images=(
99
- None,
100
- "https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/communication/Alfred.png",
101
- ),
102
- resizeable=True,
103
- scale=1,
104
- )
105
- # If an upload folder is provided, enable the upload feature
106
- if self.file_upload_folder is not None:
107
- upload_file = gr.File(label="Upload a file")
108
- upload_status = gr.Textbox(
109
- label="Upload Status", interactive=False, visible=False)
110
- upload_file.change(
111
- self.upload_file,
112
- [upload_file, file_uploads_log],
113
- [upload_status, file_uploads_log],
114
- )
115
- text_input = gr.Textbox(lines=1, label="Chat Message")
116
- text_input.submit(
117
- self.log_user_message,
118
- [text_input, file_uploads_log],
119
- [stored_messages, text_input],
120
- ).then(self.interact_with_agent, [stored_messages, chatbot], [chatbot])
121
-
122
- demo.launch(debug=True, share=True, **kwargs)
123
-
124
-
125
- # Launch the Gradio UI with the example usage
126
- CustomGradioUI(agent, description=example_usage).launch()
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
4
  import datetime
5
+ import requests
6
  import pytz
7
+ import yaml
8
+ from tools.final_answer import FinalAnswerTool
9
+ from tools.wordpress_post import WordPressPostTool
10
+ from tools.blog_generator import BlogGeneratorTool
11
+ from tools.visit_webpage import VisitWebpageTool
12
+ from tools.web_search import DuckDuckGoSearchTool
13
+
14
  from Gradio_UI import GradioUI
15
 
16
+ # Load environment variables
17
+ load_dotenv()
18
 
19
+ # Verify required environment variables
20
+ if not os.getenv("OPENWEATHER_API_KEY"):
21
+ print("Warning: OPENWEATHER_API_KEY not set. Weather functionality will be limited.")
22
 
23
+ # Load WordPress credentials from environment variables
24
+ wordpress_credentials = {
25
+ 'site_url': os.getenv('WORDPRESS_SITE_URL'),
26
+ 'username': os.getenv('WORDPRESS_USERNAME'),
27
+ 'app_password': os.getenv('WORDPRESS_APP_PASSWORD')
28
+ }
29
+
30
+ # Verify WordPress credentials
31
+ if not all(wordpress_credentials.values()):
32
+ print("Warning: WordPress credentials not fully set. Blog functionality will be limited.")
 
 
 
 
 
33
 
34
 
35
  @tool
 
48
  return f"Error fetching time for timezone '{timezone}': {str(e)}"
49
 
50
 
51
+ @tool
52
+ def quick_research(query: str, max_results: int = 3) -> str:
53
+ """Searches the web for travel-related information and provides a concise summary.
54
+ Args:
55
+ query: The search query to look up (typically a destination or attraction)
56
+ max_results: Maximum number of search results to consider (default: 3)
57
+ """
58
+ search_tool = DuckDuckGoSearchTool()
59
+
60
+ try:
61
+ # Add travel-specific terms to the query
62
+ travel_query = f"{query} travel guide tourist attractions things to do"
63
+ search_results = search_tool.search(
64
+ travel_query, max_results=max_results)
65
+
66
+ if not search_results:
67
+ return "No travel information found for the given destination."
68
+
69
+ # Format the results
70
+ formatted_results = []
71
+ for i, result in enumerate(search_results, 1):
72
+ title = result.get('title', 'No title')
73
+ snippet = result.get('snippet', 'No description available')
74
+ url = result.get('link', 'No link available')
75
+
76
+ formatted_results.append(
77
+ f"{i}. {title}\n"
78
+ f"Travel Info: {snippet}\n"
79
+ f"Source: {url}\n"
80
+ )
81
+
82
+ return "Travel Research Results:\n\n" + "\n".join(formatted_results)
83
+
84
+ except Exception as e:
85
+ return f"Error performing travel research: {str(e)}"
86
+
87
+
88
+ @tool
89
+ def get_weather(city: str) -> str:
90
+ """Fetches current weather information for a given city.
91
+ Args:
92
+ city: Name of the city to get weather for
93
+ """
94
+ try:
95
+ # Using OpenWeatherMap API (you'll need to add your API key)
96
+ # Get API key from environment variable
97
+ API_KEY = os.getenv("OPENWEATHER_API_KEY")
98
+ base_url = "http://api.openweathermap.org/data/2.5/weather"
99
+
100
+ params = {
101
+ 'q': city,
102
+ 'appid': API_KEY,
103
+ 'units': 'metric' # For Celsius
104
+ }
105
+
106
+ response = requests.get(base_url, params=params)
107
+ data = response.json()
108
+
109
+ if response.status_code == 200:
110
+ temp = data['main']['temp']
111
+ weather_desc = data['weather'][0]['description']
112
+ humidity = data['main']['humidity']
113
+
114
+ return (f"Weather in {city}:\n"
115
+ f"Temperature: {temp}°C\n"
116
+ f"Conditions: {weather_desc}\n"
117
+ f"Humidity: {humidity}%")
118
+ else:
119
+ return f"Error: Could not fetch weather for {city}"
120
+
121
+ except Exception as e:
122
+ return f"Error fetching weather data: {str(e)}"
123
+
124
 
 
125
  final_answer = FinalAnswerTool()
126
+ visit_webpage = VisitWebpageTool()
127
+ web_search = DuckDuckGoSearchTool()
128
+
129
+ # 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:
130
+ # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
131
+
132
+ # it is possible that this model may be overloaded
133
+ # model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
134
+
135
+ model = HfApiModel(
136
+ max_tokens=1024,
137
+ temperature=0.5,
138
+ # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud',
139
+ model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
140
+ # model_id='mistralai/Mistral-7B-Instruct',
141
+ token=os.getenv("HUGGINGFACEHUB_API_TOKEN"), # Ensure this is set
142
+ custom_role_conversions=None,
143
+ top_p=0.9,
144
+ frequency_penalty=0.0,
145
+ presence_penalty=0.0,
146
+ )
147
+
148
+ # Add error handling wrapper for the model
149
+
150
 
151
+ def safe_model_call(*args, **kwargs):
152
+ try:
153
+ return model(*args, **kwargs)
154
+ except Exception as e:
155
+ print(f"Model error: {str(e)}")
156
+ return "I apologize, but I encountered an error while processing your request. Please try again with a shorter or simpler query."
157
+
158
+
159
+ # Override the model's forward method with our safe version
160
+ model.forward = safe_model_call
161
+
162
+ # Import tool from Hub
163
+ image_generation_tool = load_tool(
164
+ "agents-course/text-to-image", trust_remote_code=True)
165
+
166
+ with open("prompts.yaml", 'r') as stream:
167
+ prompt_templates = yaml.safe_load(stream)
168
+
169
+ # Initialize WordPress tools
170
+ wordpress_post = WordPressPostTool(wordpress_credentials)
171
+ blog_generator = BlogGeneratorTool(model=model)
172
+
173
+ agent = CodeAgent(
174
  model=model,
175
+ tools=[
176
+ final_answer,
177
+ get_current_time_in_timezone,
178
+ image_generation_tool,
179
+ quick_research,
180
+ get_weather,
181
+ wordpress_post,
182
+ blog_generator,
183
+ visit_webpage,
184
+ web_search
185
+ ],
186
+ max_steps=6,
187
+ verbosity_level=1,
188
+ grammar=None,
189
+ planning_interval=None,
190
+ name=None,
191
+ description=None,
192
+ prompt_templates=prompt_templates
193
  )
194
 
195
+ # Update system prompt to include WordPress capabilities
196
+ prompt_templates["system_prompt"] += """
197
+
198
+ You are also capable of managing a WordPress blog through the following tools:
199
+ - wordpress_auth: Manages WordPress authentication (site URL, username, password)
200
+ - wordpress_post: Publishes posts to WordPress
201
+ - blog_generator: Generates AI-written blog posts
202
+
203
+ Before using WordPress features, you must ensure credentials are set using wordpress_auth.
204
+ Always check credentials before attempting to post content.
205
 
206
+ Example WordPress workflow:
207
+ 1. Set credentials (first time only)
208
+ 2. Generate blog content
209
+ 3. Publish to WordPress
210
+
211
+ Remember to:
212
+ - Validate WordPress credentials before posting
213
+ - Generate high-quality, relevant content
214
+ - Handle errors gracefully
215
+ - Provide clear status updates to the user
216
  """
217
 
218
+ GradioUI(agent).launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,9 +1,9 @@
1
- markdownify
2
- smolagents
3
- requests
4
- duckduckgo_search
5
- pandas
6
- yfinance
7
- pytz
8
- gradio
9
- openai
 
1
+ markdownify>=0.7.0
2
+ smolagents>=0.1.0
3
+ requests>=2.31.0
4
+ duckduckgo_search>=4.1.0
5
+ pandas>=2.0.0
6
+ pytz>=2024.1
7
+ pyyaml>=6.0.1
8
+ gradio>=5.15.0
9
+ python-dotenv>=1.0.0