Building a Smart Travel Planner with crewai and Streamlit

Planning a trip can be time-consuming, but with the power of AI and Streamlit, you can build your own Smart Travel Planner. This tutorial will guide you step-by-step through creating a web app where intelligent agents handle tasks like finding flights, recommending accommodations, and planning activities.

By the end of this article, you’ll understand how the code works and how to customize it for your needs. Let’s dive in!

Project Structure

Our travel planner consists of four main components:

  1. Tools – for performing specific actions
  2. Agents – specialized AI personas with specific roles
  3. Travel Crew – coordinates the agents
  4. User Interface – built with Streamlit

Let’s break down each component and build them step by step

1. Creating the Tool Class

First, we’ll create a Tool class that represents different capabilities our agents can use:

class Tool:
    def __init__(self, name: str, func: callable, description: str):
        self.name = name
        self.func = func
        self.description = description

    def run(self, input_text: str) -> str:
        return self.func(input_text)

Each tool has a name, function, and description. This modular approach makes it easy to add new tools later.

2. Building the Agent Class

Next, we’ll create our Agent class. Each agent has a specific role, goal, and set of tools:

class Agent:
    def __init__(self, role: str, goal: str, backstory: str, tools: List[Tool]):
        self.role = role
        self.goal = goal
        self.backstory = backstory
        self.tools = tools

    def execute_task(self, task_description: str) -> str:
        prompt = f"""
        Role: {self.role}
        Goal: {self.goal}
        Background: {self.backstory}

        Available Tools:
        {self._format_tools()}

        Task: {task_description}

        Please provide a detailed response considering your role and available tools.
        """

        try:
            response = completion(
                model="groq/llama-3.3-70b-versatile",
                messages=[{
                    "role": "user",
                    "content": prompt
                }],
                temperature=0.1
            )
            return response['choices'][0]['message']['content']
        except Exception as e:
            return f"Error executing task: {str(e)}"

The agent uses LiteLLM to generate responses based on its role and the given task.

3. Implementing the Travel Crew

The TravelCrew class coordinates our agents:

class TravelCrew:
    def __init__(self, agents: List[Agent]):
        self.agents = agents

    def execute_plan(self, travel_details: Dict[str, Any]) -> Dict[str, str]:
        results = {}
        for agent in self.agents:
            task = self._generate_task(agent, travel_details)
            results[agent.role] = agent.execute_task(task)
        return results

    def _generate_task(self, agent: str, details: Dict[str, Any]) -> str:
        base_prompt = f"""
        Plan a trip from {details['from_location']} to {details['to']} with the following details:
        - Budget: ${details['budget']}
        - Dates: {details['dates']}
        - Travelers: {details['travelers']}
        - Preferences: {details['preferences']}
        """
        return base_prompt

4. Setting Up the Tools and Agents

Now let’s create our specific tools and agents:

# Initialize tools
search_tool = Tool(
    name="Search",
    func=lambda q: f"Searching for: {q}",
    description="Search for travel-related information online"
)

scrape_tool = Tool(
    name="Scraper",
    func=lambda url: f"Scraping data from: {url}",
    description="Extract information from travel websites"
)

# Initialize agents
agents = [
    Agent(
        role="Flight Specialist",
        goal="Find the best flight options within budget",
        backstory="Expert in flight research with deep knowledge of airlines, routes, and pricing patterns.",
        tools=[search_tool, scrape_tool]
    ),
    # Add other agents here...
]

# Initialize crew
crew = TravelCrew(agents)

5. Building the Streamlit Interface

Finally, let’s create our user interface with Streamlit:

# Configure page
st.set_page_config(page_title="Smart Travel Planner")

# Add custom styling
st.markdown("""
<style>
    .reportview-container { background-color: #f0f2f6; }
    .big-font { font-size: 20px !important; }
    .stButton>button {
        background-color: #021526;
        color: white;
        font-size: 18px;
        padding: 10px 24px;
        border-radius: 5px;
    }
</style>
""", unsafe_allow_html=True)

# Create input fields
col1, col2 = st.columns(2)

with col1:
    from_location = st.text_input("From", placeholder="e.g., New York, USA")
    to = st.text_input("To", placeholder="e.g., Paris, France")
    travel_dates = st.text_input("Travel Dates", placeholder="e.g., June 1-7, 2024")
    budget = st.number_input("Budget (USD)", min_value=100, value=1000)

with col2:
    travelers = st.number_input("Number of Travelers", min_value=1, value=2)
    preferences = st.text_area("Travel Preferences", placeholder="e.g., food, culture, adventure")

Handling User Input and Generating Plans

The final piece is handling the user’s input and generating the travel plan:

if st.button("Generate Travel Plan"):
    if not from_location or not to or not travel_dates:
        st.warning("Please fill in all required fields.")
    else:
        with st.spinner("Creating your personalized travel plan..."):
            travel_details = {
                "from_location": from_location,
                "to": to,
                "dates": travel_dates,
                "budget": budget,
                "travelers": travelers,
                "preferences": preferences
            }

            results = crew.execute_plan(travel_details)

            # Display results
            st.subheader("Your Travel Plan")
            for role, result in results.items():
                with st.expander(f"💡 {role} Recommendations"):
                    st.write(result)

Putting it all together

import os
from litellm import completion
from typing import List, Dict, Any
import streamlit as st

# Configure page
st.set_page_config(page_title="Smart Travel Planner")

# Styling
st.markdown("""
<style>
    .reportview-container { background-color: #f0f2f6; }
    .big-font { font-size: 20px !important; }
    .stButton>button {
        background-color: #021526;
        color: white;
        font-size: 18px;
        padding: 10px 24px;
        border-radius: 5px;
    }
</style>
""", unsafe_allow_html=True)

class Tool:
    def __init__(self, name: str, func: callable, description: str):
        self.name = name
        self.func = func
        self.description = description

    def run(self, input_text: str) -> str:
        return self.func(input_text)

class Agent:
    def __init__(self, role: str, goal: str, backstory: str, tools: List[Tool]):
        self.role = role
        self.goal = goal
        self.backstory = backstory
        self.tools = tools

    def execute_task(self, task_description: str) -> str:
        # Construct the prompt with agent context and tools
        prompt = f"""
        Role: {self.role}
        Goal: {self.goal}
        Background: {self.backstory}

        Available Tools:
        {self._format_tools()}

        Task: {task_description}

        Please provide a detailed response considering your role and available tools.
        """

        try:
            response = completion(
                model="groq/llama-3.3-70b-versatile",
                messages=[{
                    "role": "user",
                    "content": prompt
                }],
                temperature=0.7
            )
            return response['choices'][0]['message']['content']
        except Exception as e:
            return f"Error executing task: {str(e)}"

    def _format_tools(self) -> str:
        return "\n".join([f"- {tool.name}: {tool.description}" for tool in self.tools])

class TravelCrew:
    def __init__(self, agents: List[Agent]):
        self.agents = agents

    def execute_plan(self, travel_details: Dict[str, Any]) -> Dict[str, str]:
        results = {}
        for agent in self.agents:
            task = self._generate_task(agent, travel_details)
            results[agent.role] = agent.execute_task(task)
        return results

    def _generate_task(self, agent: str, details: Dict[str, Any]) -> str:
      base_prompt = f"""
      Plan a trip from {details['from_location']} to {details['to']} with the following details:
      - Budget: ${details['budget']}
      - Dates: {details['dates']}
      - Travelers: {details['travelers']}
      - Preferences: {details['preferences']}
      """
      return base_prompt


# Initialize tools
search_tool = Tool(
    name="Search",
    func=lambda q: f"Searching for: {q}",
    description="Search for travel-related information online"
)

scrape_tool = Tool(
    name="Scraper",
    func=lambda url: f"Scraping data from: {url}",
    description="Extract information from travel websites"
)

# Initialize agents
agents = [
    Agent(
        role="Flight Specialist",
        goal="Find the best flight options within budget",
        backstory="""Expert in flight research with deep knowledge of airlines, routes, and pricing patterns.
        Skilled at finding the best balance between cost and convenience.""",
        tools=[search_tool, scrape_tool]
    ),
    Agent(
        role="Accommodation Expert",
        goal="Recommend suitable accommodations",
        backstory="""Lodging expert with deep knowledge of hotels, vacation rentals, and unique stays.
        Focuses on value, location, and amenities.""",
        tools=[search_tool, scrape_tool]
    ),
    Agent(
        role="Activity Planner",
        goal="Create engaging itineraries",
        backstory="""Experienced travel coordinator who excels at crafting perfect day-by-day itineraries
        that balance activities, rest, and travel time.""",
        tools=[search_tool, scrape_tool]
    )
]

# Initialize crew
crew = TravelCrew(agents)

# Streamlit Interface
st.title("🌍 Smart Travel Planner")
st.markdown("Let AI agents help plan your perfect trip!")

# Input Collection
col1, col2 = st.columns(2)

with col1:
    from_location = st.text_input("From", placeholder="e.g., New York, USA")
    to = st.text_input("To", placeholder="e.g., Paris, France")
    travel_dates = st.text_input("Travel Dates", placeholder="e.g., June 1-7, 2024")
    budget = st.number_input("Budget (USD)", min_value=100, value=1000)

with col2:
    travelers = st.number_input("Number of Travelers", min_value=1, value=2)
    preferences = st.text_area("Travel Preferences", placeholder="e.g., food, culture, adventure")

if st.button("Generate Travel Plan"):
    if not from_location or not to or not travel_dates:
        st.warning("Please fill in all required fields.")
    else:
        with st.spinner("Creating your personalized travel plan..."):
            travel_details = {
                "from_location": from_location,
                "to": to,
                "dates": travel_dates,
                "budget": budget,
                "travelers": travelers,
                "preferences": preferences
            }

            results = crew.execute_plan(travel_details)

            # Display results
            st.subheader("Your Travel Plan")

            for role, result in results.items():
                with st.expander(f"💡 {role} Recommendations"):
                    st.write(result)

            st.info("Note: This is an AI-generated plan. Please verify all details before making reservations.")

Running the Application

To run your travel planner, save all the code in a file (e.g., travel_planner.py) and run:

streamlit run travel_planner.py

Key Features and Benefits

  • Modular Design: Easy to add new tools and agents
  • Role-Based Agents: Specialized expertise for different aspects of travel planning
  • User-Friendly Interface: Clean, intuitive design with Streamlit
  • AI-Powered Recommendations: Personalized travel plans based on user preferences
  • Expandable Architecture: Ready for additional features and improvements

Areas for Enhancement

  1. Add more sophisticated tools for real-time flight and hotel data
  2. Implement caching for faster responses
  3. Add support for multiple currencies
  4. Include weather data integration
  5. Add map visualization for itineraries

Conclusion

We’ve built a functional AI-powered travel planner that combines the power of large language models with a user-friendly interface. The modular design makes it easy to extend and improve the application as needed.

Remember to handle API keys securely and add proper error handling before deploying to production.

Author

  • Naveen Pandey Data Scientist Machine Learning Engineer

    Naveen Pandey has more than 2 years of experience in data science and machine learning. He is an experienced Machine Learning Engineer with a strong background in data analysis, natural language processing, and machine learning. Holding a Bachelor of Science in Information Technology from Sikkim Manipal University, he excels in leveraging cutting-edge technologies such as Large Language Models (LLMs), TensorFlow, PyTorch, and Hugging Face to develop innovative solutions.

    View all posts
Spread the knowledge
 
  

Leave a Reply

Your email address will not be published. Required fields are marked *