|
|
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.") |
|
|
|
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
os.environ["OPENAI_API_KEY"] = openai_api_key |
|
|
os.environ["SERPER_API_KEY"] = serper_api_key |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
search_tool = SerperDevTool() |
|
|
|
|
|
|
|
|
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: |
|
|
|
|
|
return str(eval(expression)) |
|
|
except: |
|
|
return "Error in calculation" |
|
|
|
|
|
calc_tool = CalculatorTool() |
|
|
|
|
|
|
|
|
gpt_4o_mini = ChatOpenAI( |
|
|
model="gpt-4o-mini", |
|
|
temperature=0.7 |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
) |
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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.") |