ahmadsanafarooq's picture
Update app.py
7a3b5ba verified
import streamlit as st
import os
import sys
from crewai import Agent, Task, Crew, Process
from crewai.tools import BaseTool
from crewai_tools import SerperDevTool
from langchain_openai import ChatOpenAI
st.set_page_config(page_title="Smart Relocation Assistant", page_icon="🏘️", layout="wide")
st.title("Smart Relocation Assistant")
st.markdown("Use AI Agents to find your perfect neighborhood based on budget and lifestyle.")
# --- 2. API KEY SETUP ---
# Fetch keys from environment variables (Hugging Face Secrets)
openai_api_key = os.getenv("OPENAI_API_KEY")
serper_api_key = os.getenv("SERPER_API_KEY")
if not (openai_api_key and serper_api_key):
st.error(" API Keys not found!")
st.warning("Please set OPENAI_API_KEY and SERPER_API_KEY in your Hugging Face Space 'Settings' -> 'Variables and secrets'.")
st.stop()
# Set keys back into environment for the tools/libraries
os.environ["OPENAI_API_KEY"] = openai_api_key
os.environ["SERPER_API_KEY"] = serper_api_key
# --- 3. TOOL DEFINITIONS ---
# The Search Tool is now initialized here
search_tool = SerperDevTool()
# Custom Calculator Tool
class CalculatorTool(BaseTool):
name: str = "Budget Calculator"
description: str = "Useful for calculating if a rent price fits within a budget. Input must be a mathematical expression."
def _run(self, expression: str) -> str:
try:
# Safe evaluation of simple math
return str(eval(expression))
except:
return "Error in calculation"
calc_tool = CalculatorTool()
# --- 4. LLM DEFINITION
gpt_4o_mini = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.7
)
# --- 5. STREAMLIT INPUTS ---
st.header("1. Enter Your Relocation Details")
col1, col2 = st.columns(2)
with col1:
city = st.text_input("Target City", "Austin, TX")
budget = st.number_input("Max Monthly Rent ($)", min_value=500, value=2500)
with col2:
work_location = st.text_input("Work Location", "Downtown")
preferences = st.text_area("Lifestyle Preferences", "Walkable, near coffee shops, safe, good for young professionals")
# --- 6. AGENT & TASK DEFINITIONS (Defined in the function for cleaner scope) ---
def run_crew_analysis(city, work_location, budget, preferences):
city_scout = Agent(
role='City Neighborhood Scout',
goal=f'Identify the top 3 neighborhoods in {city} that match these preferences: {preferences}.',
backstory="You are a local expert who knows every corner of the city. You prioritize safety, commute, and lifestyle fit.",
tools=[search_tool],
llm=gpt_4o_mini,
verbose=True,
allow_delegation=False
)
budget_analyst = Agent(
role='Relocation Financial Advisor',
goal=f'Assess the affordability of specific neighborhoods and ensure rent is within {budget}.',
backstory="You are a pragmatic financial advisor. You strictly filter out any options that exceed the user's budget.",
tools=[search_tool, calc_tool],
llm=gpt_4o_mini,
verbose=True,
allow_delegation=False
)
scout_task = Task(
description=f"Search for neighborhoods in {city} that are: {preferences}. Consider commute to {work_location}. Select top 5 candidates.",
expected_output="List of 5 neighborhoods with vibe descriptions.",
agent=city_scout
)
analysis_task = Task(
description=f"For the 5 neighborhoods found, search current average rent for a 1-bedroom. Filter out any where rent > {budget}. Calculate remaining budget.",
expected_output="Filtered list of affordable neighborhoods with costs.",
agent=budget_analyst
)
report_task = Task(
description="""Compile a final report. Rank top 3 affordable neighborhoods. Include: Neighborhood Name, Vibe, Rent Cost, Remaining Budget, and one Local Highlight. Format as clear Markdown.""",
expected_output="Markdown formatted relocation guide.",
agent=budget_analyst
)
# --- CREW EXECUTION ---
relocation_crew = Crew(
agents=[city_scout, budget_analyst],
tasks=[scout_task, analysis_task, report_task],
process=Process.sequential,
llm=gpt_4o_mini
)
return relocation_crew.kickoff()
# --- 7. BUTTON TRIGGER ---
if st.button("Start Research", type="primary"):
with st.spinner('AI Agents are scouting neighborhoods and crunching numbers...'):
try:
result = run_crew_analysis(city, work_location, budget, preferences)
# Display Results
st.success("Research Complete!")
st.markdown("### Your Relocation Plan")
st.markdown(result)
except Exception as e:
st.error("An error occurred during crew execution. This often means a temporary API issue or a failure to parse a search result.")
st.exception(e)
st.markdown("---")
st.warning("Please wait a few minutes (for rate limit cooldown) and try again, or check your API keys.")