rajaramesh commited on
Commit
3c84178
Β·
1 Parent(s): b483344

Add application files

Browse files
Files changed (6) hide show
  1. agent.py +28 -0
  2. app.py +34 -0
  3. requirements.txt +5 -0
  4. task.py +14 -0
  5. tools.py +298 -0
  6. trip.md +44 -0
agent.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from crewai import Agent, LLM
2
+ from tools import search
3
+
4
+ import os
5
+ from dotenv import load_dotenv
6
+
7
+ # Load environment variables
8
+ load_dotenv()
9
+
10
+ # Get API key
11
+ api_key = os.getenv('SAMBANOVA_API_KEY')
12
+ if not api_key:
13
+ raise ValueError("SAMBANOVA_API_KEY not found in environment variables")
14
+
15
+ llm = LLM(
16
+ model="sambanova/Meta-Llama-3.2-1B-Instruct",
17
+ api_key=api_key,
18
+ base_url="https://api.sambanova.ai/v1",
19
+ temperature=0.5
20
+ )
21
+
22
+ trip_planner_agent = Agent(
23
+ role="Trip Planner",
24
+ goal="Create a detailed, day-by-day travel itinerary for a given destination and date range, including top attractions and activities.",
25
+ backstory="You are an expert travel planner who crafts personalized itineraries based on user preferences and up-to-date information.",
26
+ tools=[search],
27
+ llm=llm
28
+ )
app.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from crewai import Crew
3
+ from task import trip_itinerary_task
4
+
5
+ def run_trip_planner(destination, arrival_date, departure_date):
6
+ crew = Crew(tasks=[trip_itinerary_task])
7
+ result = crew.kickoff(inputs={
8
+ "destination": destination,
9
+ "arrival_date": arrival_date,
10
+ "departure_date": departure_date
11
+ })
12
+ # Extract the string result for Gradio Markdown
13
+ if hasattr(result, "result"):
14
+ return result.result
15
+ elif hasattr(result, "output"):
16
+ return result.output
17
+ else:
18
+ return str(result)
19
+
20
+ with gr.Blocks() as demo:
21
+ gr.Markdown("# CrewAI Trip Planner\nEnter your trip details below:")
22
+ with gr.Row():
23
+ destination = gr.Textbox(label="Destination", placeholder="e.g. Vizag")
24
+ arrival = gr.Textbox(label="Arrival Date", placeholder="YYYY-MM-DD")
25
+ departure = gr.Textbox(label="Departure Date", placeholder="YYYY-MM-DD")
26
+ output = gr.Markdown(label="Itinerary")
27
+ btn = gr.Button("Generate Itinerary")
28
+ btn.click(run_trip_planner, inputs=[destination, arrival, departure], outputs=output)
29
+
30
+ def main():
31
+ demo.launch()
32
+
33
+ if __name__ == "__main__":
34
+ main()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ python-dotenv
2
+ crewai
3
+ crewai_tools
4
+ gradio
5
+ smolagents[mcp]
task.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from crewai import Task
2
+ from agent import trip_planner_agent
3
+
4
+ trip_itinerary_task = Task(
5
+ description=(
6
+ "Generate a travel itinerary for the destination: {destination} for the dates {arrival_date} to {departure_date}. "
7
+ "The output should be in the following format (as shown in my-itinerary1.md):\n"
8
+ "Top 10 places to visit in {destination}:\n1. ...\n...\n\nDay-by-day schedule with specific activities and attractions:\nDay 1: ...\n* Morning: ...\n* Afternoon: ...\n* Evening: ...\n...\n\nInclude specific attractions, activities, and local highlights for each day. "
9
+ "Use up-to-date information and tailor the plan to the number of days between arrival and departure."
10
+ ),
11
+ agent=trip_planner_agent,
12
+ expected_output="A markdown-formatted itinerary as described above.",
13
+ inputs=["destination", "arrival_date", "departure_date"]
14
+ )
tools.py ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from crewai.tools import BaseTool
2
+ from typing import Optional, Type, Any
3
+ from pydantic import BaseModel, Field
4
+ import logging
5
+
6
+ # Set up logging
7
+ logging.basicConfig(level=logging.INFO)
8
+ logger = logging.getLogger(__name__)
9
+
10
+ class SearchInput(BaseModel):
11
+ """Input schema for the search tool"""
12
+ query: str = Field(..., description="The search query to find information")
13
+
14
+ class DuckDuckGoSearchTool(BaseTool):
15
+ """DuckDuckGo search tool that uses MCP server"""
16
+
17
+ name: str = "duckduckgo_search"
18
+ description: str = "Search the web using DuckDuckGo search engine via MCP server. Use this tool to find current information about locations, attractions, restaurants, weather, and travel-related topics."
19
+ args_schema: Type[BaseModel] = SearchInput
20
+
21
+ def __init__(self, **kwargs):
22
+ super().__init__(**kwargs)
23
+ # Initialize MCP connection after parent initialization
24
+ self._initialize_mcp()
25
+
26
+ def _initialize_mcp(self) -> None:
27
+ """Initialize connection to MCP server and get search tool"""
28
+ try:
29
+ logger.info("πŸ”„ Initializing MCP client...")
30
+
31
+ # Try to import and initialize MCP client
32
+ try:
33
+ from smolagents.mcp_client import MCPClient
34
+
35
+ self._mcp_client = MCPClient(
36
+ {"url": "https://agents-mcp-hackathon-duckduckgo-mcp-server.hf.space/gradio_api/mcp/sse",
37
+ "transport": "sse"}
38
+ )
39
+
40
+ # Get available tools from MCP server
41
+ tools = self._mcp_client.get_tools()
42
+ logger.info(f"πŸ“‹ MCP returned {len(tools) if isinstance(tools, list) else 0} tools")
43
+
44
+ if isinstance(tools, list) and len(tools) > 0:
45
+ # Use the first tool (should be the DuckDuckGo search tool)
46
+ self._search_tool = tools[0]
47
+ logger.info("βœ… MCP search tool initialized successfully")
48
+ else:
49
+ raise Exception("No tools available from MCP server")
50
+
51
+ except ImportError:
52
+ logger.error("❌ smolagents not available")
53
+ self._mcp_client = None
54
+ self._search_tool = None
55
+
56
+ except Exception as e:
57
+ logger.error(f"❌ Failed to initialize MCP client: {e}")
58
+ self._mcp_client = None
59
+ self._search_tool = None
60
+
61
+ def _run(self, query: str, **kwargs: Any) -> str:
62
+ """Execute the search using MCP DuckDuckGo tool"""
63
+ try:
64
+ if not hasattr(self, '_mcp_client') or not self._mcp_client or not hasattr(self, '_search_tool') or not self._search_tool:
65
+ return f"❌ MCP server not available. Cannot search for: {query}"
66
+
67
+ logger.info(f"πŸ” Executing search for: {query}")
68
+
69
+ # Call the MCP search tool
70
+ result = self._search_tool(query=query, max_results=5)
71
+ logger.info(f"πŸ” Search completed, processing results...")
72
+
73
+ # Format the results for better readability
74
+ if isinstance(result, (list, tuple)):
75
+ if not result:
76
+ return f"πŸ” No results found for query: {query}"
77
+
78
+ formatted_results = []
79
+ for i, item in enumerate(result[:5], 1):
80
+ if isinstance(item, dict):
81
+ title = item.get('title', 'No title available')
82
+ url = item.get('url', item.get('link', 'No URL available'))
83
+ snippet = item.get('snippet', item.get('description', item.get('body', 'No description available')))
84
+
85
+ formatted_results.append(
86
+ f"πŸ”— Result {i}:\n"
87
+ f" πŸ“ Title: {title}\n"
88
+ f" 🌐 URL: {url}\n"
89
+ f" πŸ“„ Description: {snippet}\n"
90
+ )
91
+ else:
92
+ formatted_results.append(f"πŸ”— Result {i}: {str(item)}\n")
93
+
94
+ final_result = "\n".join(formatted_results)
95
+ logger.info(f"βœ… Formatted {len(formatted_results)} search results")
96
+ return final_result
97
+
98
+ elif isinstance(result, str):
99
+ return f"πŸ” Search Result:\n{result}"
100
+ else:
101
+ return f"πŸ” Search completed:\n{str(result)}"
102
+
103
+ except Exception as e:
104
+ error_msg = f"❌ Search failed: {str(e)}"
105
+ logger.error(error_msg)
106
+ return f"{error_msg}\nπŸ” Query: {query}"
107
+
108
+ # Fallback search tool for when MCP is not available
109
+ class FallbackSearchTool(BaseTool):
110
+ name: str = "fallback_search"
111
+ description: str = "Fallback search tool that provides general travel information"
112
+ args_schema: Type[BaseModel] = SearchInput
113
+
114
+ def _run(self, query: str, **kwargs: Any) -> str:
115
+ """Provide fallback search results with general travel information"""
116
+ logger.info(f"πŸ” Fallback search for: {query}")
117
+
118
+ # Basic travel information based on common queries
119
+ fallback_info = {
120
+ "vizag": {
121
+ "title": "Visakhapatnam (Vizag), Andhra Pradesh, India",
122
+ "info": """
123
+ ## Top Attractions
124
+ - **RK Beach (Ramakrishna Beach)** - Popular beach with shopping and dining
125
+ - **Submarine Museum (INS Kurusura)** - Unique submarine converted to museum
126
+ - **Kailasagiri Hill Park** - Scenic hilltop park with city views
127
+ - **Araku Valley** - Beautiful hill station 3 hours away
128
+ - **Borra Caves** - Stunning limestone caves near Araku
129
+ - **Simhachalam Temple** - Ancient temple dedicated to Lord Narasimha
130
+
131
+ ## Local Cuisine
132
+ - Andhra-style spicy seafood
133
+ - Traditional South Indian breakfast items
134
+ - Local street food at Beach Road
135
+
136
+ ## Best Time to Visit
137
+ October to March (pleasant weather)
138
+
139
+ ## Transportation
140
+ - Auto-rickshaws and taxis available
141
+ - Train connectivity to Araku Valley
142
+ - Airport: Visakhapatnam Airport (VTZ)
143
+ """
144
+ },
145
+ "goa": {
146
+ "title": "Goa, India",
147
+ "info": """
148
+ ## Popular Beaches
149
+ - **North Goa**: Baga, Calangute, Anjuna, Vagator
150
+ - **South Goa**: Palolem, Colva, Benaulim (quieter beaches)
151
+
152
+ ## Attractions
153
+ - **Old Goa Churches** - UNESCO World Heritage Sites
154
+ - **Dudhsagar Falls** - Spectacular waterfall (seasonal)
155
+ - **Spice Plantations** - Guided tours available
156
+ - **Flea Markets** - Anjuna and Mapusa markets
157
+
158
+ ## Activities
159
+ - Water sports, casino cruises, dolphin watching
160
+ - Portuguese heritage tours
161
+ - Beach parties and nightlife
162
+
163
+ ## Best Time
164
+ November to February (dry season)
165
+ """
166
+ },
167
+ "dubai": {
168
+ "title": "Dubai, United Arab Emirates",
169
+ "info": """
170
+ ## Iconic Attractions
171
+ - **Burj Khalifa** - World's tallest building with observation decks
172
+ - **Dubai Mall** - Massive shopping and entertainment complex
173
+ - **Palm Jumeirah** - Artificial palm-shaped island
174
+ - **Dubai Fountain** - World's largest choreographed fountain
175
+ - **Burj Al Arab** - Iconic sail-shaped luxury hotel
176
+ - **Dubai Marina** - Modern waterfront district
177
+
178
+ ## Activities
179
+ - Desert safari with dune bashing
180
+ - Dubai Creek dhow cruise
181
+ - Ski Dubai (indoor skiing)
182
+ - Gold and Spice Souks
183
+
184
+ ## Best Time
185
+ November to March (cooler weather)
186
+ """
187
+ }
188
+ }
189
+
190
+ # Try to match query with fallback info
191
+ query_lower = query.lower()
192
+ for location, info in fallback_info.items():
193
+ if location in query_lower:
194
+ return f"""
195
+ # Search Results for: {query}
196
+
197
+ ## {info['title']}
198
+
199
+ {info['info']}
200
+
201
+ ---
202
+
203
+ **Note**: This is fallback information as the live search service is currently unavailable.
204
+ For the most current information, please verify details from official tourism websites.
205
+
206
+ **Technical Note**: To enable live search, ensure MCP server is running on https://huggingface.co/spaces/Agents-MCP-Hackathon/DuckDuckGo-MCP-Server
207
+ """
208
+
209
+ # Generic fallback response
210
+ return f"""
211
+ # Search Results for: {query}
212
+
213
+ ## Search Service Currently Unavailable
214
+
215
+ The live search service is not currently available, but here are some general recommendations:
216
+
217
+ ### Planning Your Trip
218
+ 1. **Research official tourism websites** for your destination
219
+ 2. **Check travel advisories** and entry requirements
220
+ 3. **Compare prices** on multiple booking platforms
221
+ 4. **Read recent reviews** from other travelers
222
+ 5. **Contact local tourism boards** for current information
223
+
224
+ ### Popular Travel Resources
225
+ - **Booking Platforms**: Booking.com, Expedia, MakeMyTrip
226
+ - **Reviews**: TripAdvisor, Google Reviews
227
+ - **Transportation**: Official airline and railway websites
228
+ - **Local Info**: Tourism board websites
229
+
230
+ ---
231
+
232
+ **Technical Note**: To enable live search functionality, please ensure the MCP server is running on https://huggingface.co/spaces/Agents-MCP-Hackathon/DuckDuckGo-MCP-Server
233
+ """
234
+
235
+ # Create the search tool instance
236
+ try:
237
+ search = DuckDuckGoSearchTool()
238
+ logger.info("βœ… DuckDuckGoSearchTool created successfully")
239
+ except Exception as e:
240
+ logger.error(f"❌ Failed to create DuckDuckGoSearchTool: {e}")
241
+ search = FallbackSearchTool()
242
+ logger.warning("⚠️ Using fallback search tool")
243
+
244
+ # Test function for debugging
245
+ def test_mcp_connection():
246
+ """Test MCP connection independently"""
247
+ try:
248
+ logger.info("πŸ§ͺ Testing MCP connection...")
249
+
250
+ try:
251
+ from smolagents.mcp_client import MCPClient
252
+
253
+ mcp_client = MCPClient(
254
+ {"url": "https://agents-mcp-hackathon-duckduckgo-mcp-server.hf.space/gradio_api/mcp/sse",
255
+ "transport": "sse"}
256
+ )
257
+
258
+ tools = mcp_client.get_tools()
259
+ logger.info(f"πŸ§ͺ Test successful: {len(tools) if isinstance(tools, list) else 0} tools available")
260
+
261
+ if isinstance(tools, list) and len(tools) > 0:
262
+ # Test a simple search
263
+ search_func = tools[0]
264
+ result = search_func(query="test", max_results=2)
265
+ logger.info(f"πŸ§ͺ Test search result type: {type(result)}")
266
+ return True
267
+ else:
268
+ logger.warning("πŸ§ͺ No tools available in MCP server")
269
+ return False
270
+
271
+ except ImportError:
272
+ logger.error("πŸ§ͺ smolagents package not available")
273
+ return False
274
+
275
+ except Exception as e:
276
+ logger.error(f"πŸ§ͺ MCP connection test failed: {e}")
277
+ return False
278
+
279
+ if __name__ == "__main__":
280
+ print("πŸš€ Testing DuckDuckGo MCP Tool")
281
+ print("=" * 50)
282
+
283
+ # Test MCP connection
284
+ if test_mcp_connection():
285
+ print("βœ… MCP connection test passed")
286
+
287
+ # Test the actual tool
288
+ test_result = search._run("Vizag attractions")
289
+ print("\nπŸ” Tool Test Result:")
290
+ print(test_result)
291
+ else:
292
+ print("❌ MCP connection test failed")
293
+ print("πŸ’‘ Make sure your MCP server is running on https://huggingface.co/spaces/Agents-MCP-Hackathon/DuckDuckGo-MCP-Server")
294
+
295
+ # Test fallback tool
296
+ print("\nπŸ” Testing Fallback Tool:")
297
+ fallback_result = search._run("Vizag attractions")
298
+ print(fallback_result)
trip.md ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Top 10 Places to Visit in Vizag:
2
+
3
+ 1. **RK Beach (Ramakrishna Beach):** The most popular beach in Vizag, known for its scenic beauty and vibrant atmosphere.
4
+ 2. **Kailasagiri:** A hilltop park offering panoramic views of the city and coastline, featuring a giant Shiva-Parvati statue.
5
+ 3. **Borra Caves:** Ancient limestone caves with stunning stalactite and stalagmite formations.
6
+ 4. **Araku Valley:** A hill station known for its coffee plantations, scenic beauty, and tribal culture.
7
+ 5. **Submarine Museum:** INS Kursura (S20) is a Kalvari-class diesel-electric submarine of the Indian Navy. It was India's fourth submarine.
8
+ 6. **VUDA Park (Taraka Rama Tirtha):** A sprawling urban park with gardens, fountains, and recreational facilities.
9
+ 7. **Yarada Beach:** A serene and secluded beach known for its golden sands and clear waters.
10
+ 8. **Simhachalam Temple:** An ancient Hindu temple dedicated to Lord Narasimha.
11
+ 9. **Indira Gandhi Zoological Park:** A large zoo housing a diverse collection of animals.
12
+ 10. **Ross Hill Church:** A historic church located on a hilltop, offering stunning views.
13
+
14
+ ## Day-by-Day Schedule:
15
+
16
+ **Day 1: Arrival in Vizag & RK Beach Exploration (2025-07-01)**
17
+
18
+ * **Morning:** Arrive at Visakhapatnam Airport (VTZ) or Railway Station. Check into your hotel.
19
+ * **Afternoon:** Lunch at a local restaurant. Visit RK Beach. Enjoy a stroll along the beach, take a camel ride, or relax by the sea.
20
+ * **Evening:** Enjoy street food at RK Beach. Dinner at a restaurant with sea views.
21
+
22
+ **Day 2: Kailasagiri & City Views (2025-07-02)**
23
+
24
+ * **Morning:** Visit Kailasagiri. Take a ropeway ride to the top and enjoy panoramic views of Vizag. Explore the park and see the Shiva-Parvati statue.
25
+ * **Afternoon:** Lunch at a restaurant near Kailasagiri. Visit VUDA Park (Taraka Rama Tirtha), enjoy the gardens and fountains.
26
+ * **Evening:** Visit the Submarine Museum. Learn about the history of the INS Kursura submarine. Dinner at a restaurant in the city.
27
+
28
+ **Day 3: Borra Caves & Araku Valley (2025-07-03)**
29
+
30
+ * **Morning:** Early start for a day trip to Borra Caves and Araku Valley.
31
+ * **Afternoon:** Explore the Borra Caves, marvel at the stalactite and stalagmite formations. Have lunch at Araku Valley.
32
+ * **Evening:** Visit a coffee plantation in Araku Valley. Return to Vizag in the late evening. Dinner at a restaurant in Vizag.
33
+
34
+ **Day 4: Yarada Beach & Simhachalam Temple (2025-07-04)**
35
+
36
+ * **Morning:** Visit Yarada Beach. Enjoy the serene atmosphere and golden sands.
37
+ * **Afternoon:** Lunch at a restaurant near Yarada Beach. Visit Simhachalam Temple, an ancient Hindu temple.
38
+ * **Evening:** Explore the local markets for souvenirs. Dinner at a restaurant of your choice.
39
+
40
+ **Day 5: Zoo & Departure (2025-07-05)**
41
+
42
+ * **Morning:** Visit Indira Gandhi Zoological Park. Explore the diverse collection of animals.
43
+ * **Afternoon:** Lunch at a restaurant near the zoo.
44
+ * **Evening:** Depart from Visakhapatnam Airport (VTZ) or Railway Station.