Realstate / state_handler.py
amirshafiei's picture
add_data
b3a8a37
import os
from langchain.chains.router import MultiPromptChain
from langchain.chains.router.llm_router import LLMRouterChain,RouterOutputParser
# from langchain.prompts import PromptTemplate
from langchain.prompts import ChatPromptTemplate
from langchain import OpenAI, LLMChain, PromptTemplate
from langchain.memory import ConversationBufferMemory
import os
import openai
from langchain.chat_models import ChatOpenAI
from api_call import send_request
from langchain.llms import LlamaCpp
from langchain.callbacks.manager import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
# questions = {
# 'buy house or loan': 'Do you want to buy a house or loan for it?',
# 'zip code':'Could you please provide me with the zip code of the area where you are looking to buy a home?',
# 'home feature' : 'Can you describe the desired features of your dream home and your goals',
# 'budget' : 'What is your budget for buying a home?',
# 'first time buyer' : 'Are you a first-time buyer?',
# 'introduce' : 'Hi. I\'m here to assist you with buying a home or getting a loan. Could you please provide me with some information to help you better?',
# 'ignored' : 'I don\'t understand. Could you please rephrase your question?',
# 'ask_question' : 'Could you please provide me with the zip code of the area where you are looking to buy a home?'
# }
# questions = {
# 'buy house or loan': 'Which one are you more interested in? Buy a house or loan for it?',
# 'zip code':'Could you please provide me with the zip code of the area where you are looking to buy a home?',
# 'home feature' : 'Can you describe the desired features of your dream home and your goals',
# 'budget' : 'What is your budget for buying a home?',
# 'first time buyer' : 'Are you a first-time buyer?',
# 'introduce' : 'Hi I’m Samar, your real state assistant. In 60 seconds I can help you find a house or how to save $500 on your loans.',
# 'ignored' : 'I don\'t understand. Could you please rephrase your question?',
# 'ask_question' : 'Could you please provide me with the zip code of the area where you are looking to buy a home?'
# }
questions = {
'buy house or loan': 'Are you currently in the market to purchase or rent a home?',
'zip code':'Could you please provide me with the zip code of the area where you are looking to buy a home?',
'home feature' : 'Can you describe the desired features of your dream home and your goals',
'budget' : 'What is your budget for buying a home?',
'first time buyer' : 'Are you a first-time buyer?',
'introduce' : 'Hi, this is Samar from Royal Real State Agency. I hope you\'re doing well! I wanted to reach out because \
I noticed your interest in real estate and thought I could assist you in finding the perfect home.',
'ignored' : 'I don\'t understand. Could you please rephrase your question?',
'ask_question' : 'Could you please provide me with the zip code of the area where you are looking to buy a home?'
}
def init_chain():
budget_template = """ You are a compressor that get a question and answer aboute money/budget and extremly compress the answer into a number and return an integer number.
example: if input=600k then output=600000
Here is the question :
{question}
Here is the answer :
{answer}"""
zipcode_templet = """ You are a compressor that get a question and answer aboute zip code and extremly compress the answer into a number and return only a number.
Here is the question :
{question}
Here is the answer :
{answer}"""
feature_template = """ You are a compressor that get a question and answer about desiered home feature and extract home feature from the answer into a short term.
Here is the question :
{question}
Here is the answer :
{answer}"""
buy_loan_template = """ You are a compressor that get a question and answer a bout buy house or loan, and extremly compress the answer into short term.
Here is the question :
{question}
Here is the answer :
{answer}"""
first_buyer_template = """ You are a compressor that get a question and answer a bout buy house or loan, and extremly compress the answer into short term.
Here is the question :
{question}
Here is the answer :
{answer}"""
home_feature_template = """ You are a prompt generator to generate a sentence to describe a home property \
for a buyer based on the input_data. for example describe prices, floorSizeValue,numRoom \
numFloor, numBedroom, neighborhoods, floorSizeValue, feature item of input_data.
Here is the input_data :
{input_data}
"""
cat_task_template = """ You are a classifier to assign input_message into one of the below categoryis. \
categoryis Item: \
- `buy house or loan `: (example: Are you currently in the market to purchase or rent a home? yes. buy a house) \
- `budget`: (example: What is your budget for buying a home? 600k or 5000$ or 8000 or I have 36000$ money) \
- `first time buyer`: (example: Are you a first-time buyer? yes) \
- `zip code` : (example: Could you please provide me with the zip code of the area you are interested in? 19701 , 85412 , ...)
- `home feature' : (example : Can you describe the desired features of your dream home and your goals? 2 rooms)
- `ignored` : a message that don't related to any question and is a unusaul message.
Here is the input_message and question :
{input_message}
output:
return the detected category.
"""
prompt_infos = [
{
"name": "budget",
"prompt_template": budget_template
},
{
"name": "zip code",
"prompt_template": zipcode_templet
},
{
"name": "home feature",
"prompt_template": feature_template
},
{
"name": "buy house or loan",
"prompt_template": buy_loan_template
},
{
"name": "first time buyer",
"prompt_template": first_buyer_template
},
{
"name": "home_feature",
"prompt_template": home_feature_template
},
{
"name": "category",
"prompt_template": cat_task_template
},
]
destination_chains = {}
for p_info in prompt_infos:
name = p_info["name"]
prompt_template = p_info["prompt_template"]
prompt = ChatPromptTemplate.from_template(template=prompt_template,)
chain = LLMChain(llm=llm, prompt=prompt)
destination_chains[name] = chain
return destination_chains
#Age + Pricing
llm = ChatOpenAI(temperature=0.0)
# llm = LlamaCpp(
# model_path="/home/yaghoubian/yaghoubian/fast_avatar/hrviton/ControlNet-v1-1-nightly/lang_chain/aa/llama-2-7b-chat.ggmlv3.q6_K.bin",
# input={"temperature": 0.1, "max_length": 2000, "top_p": 1},
# callback_manager=callback_manager,)
# prompt_instruction = """
# Instructions: you are a classifier for classify input message into one of the below categoryis. \
# categoryis Item: \
# -`math_question` \
# -`Historical` \
# Here is the question: what is 1+1? \
# """
# print("before a")
# a = llm(prompt_instruction)
# print(a)
chains = init_chain()
def state_handler(message,user_state=None, user_info=None,gathered_info=None):
if user_info == None:
print("new_user")
user_state = ['introduce','buy house or loan','zip code','home feature','budget','first time buyer']
user_info = questions[user_state[0]] + "\n" + questions[user_state[1]]
gathered_info = {}
user_state.remove('introduce')
return user_state,user_info,gathered_info
else:
assigned_classes = category(input_message = user_info.split('\n')[-1] + " " + message)
for assigned_class in assigned_classes :
Short_response, user_state= compress_response(input_message=message,input_question=questions[assigned_class],\
user_state=user_state,assigned_class=assigned_class,user_info=user_info)
print (f"{assigned_class} : {Short_response}")
gathered_info[assigned_class] = Short_response
if len(user_state)>0:
if 'rephrase your answer for this question' in Short_response:
user_info = Short_response
else :
user_info = questions[user_state[0]]
else:
res,response = send_request(gathered_info['budget'],gathered_info['zip code'])
# print("Start Zillow scraping. ")
# res,response = send_zillow_request(gathered_info['budget'],gathered_info['zip code'])
if response == None:
user_info = "Sorry, there is an error in searching result. please try again."
else:
if res>0:
user_info = f"This is your information: \n{gathered_info}. \n we find {res} results." #\
# \n Here is the result specification: \n {response}."
for idx,i in enumerate(response):
in_feature =f" numBathroom: {i['numBathroom']} , numRoom: {i['numRoom']}, numFloor: {i['numFloor']}, yearBuilt:{i['yearBuilt']}, floorSizeValue: {i['floorSizeValue']} {i['floorSizeUnit']} "
home_feature_prompt = chains['home_feature'].run(input_data=in_feature)
print("home_feature_prompt: ",home_feature_prompt)
try:
user_info = user_info + f"\n{idx+1}- " +home_feature_prompt + f"\n {str(i['mostRecentPriceSourceURL'])} \n"
except:
user_info = user_info + f"\n{idx+1}- " +home_feature_prompt
else :
user_info = f"This is your information: \n{gathered_info}. \n Sorry. we can't find \
any case by the entered budget and zip code"
return user_state,user_info,gathered_info
def category(input_message):
# os.environ["OPENAI_API_KEY"] = "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"
# llm = ChatOpenAI(temperature=0.1)
# # You are a chatbot. you must read the input message and \
# # tag or categorize it to one of the below item
# new_task_template = """ You are a classifier to assign input_message into one (or more than one) of the below categoryis.\
# categoryis Item: \
# - `buy house or loan `: (example: do you want to buy a house ot loan for it? buy a house) \
# - `budget`: (example: What is your budget for buying a home? 5000$ or 8000 or I have 36000$ money) \
# - `first time buyer`: (example: Are you a first-time buyer? yes) \
# - `zip code` : (example: Could you please provide me with the zip code of the area you are interested in? 8542)
# - `home feature' : (example : Can you describe the desired features of your dream home and your goals? 2 rooms)
# - `introduce` : (example: Hi. I'm here to assist you with buying a home or getting a loan.)
# - `ignored` : a message that don't related to any question and is a unusaul message.
# - `ask_question` : (example: Could you please provide me with some information to help you better? Sure.).
# Here is the input message :
# {input_message}
# output:
# return the detected category.
# """
# prompt = ChatPromptTemplate.from_template(template=new_task_template,)
# cat_chain = LLMChain(llm=llm, prompt=prompt)
classe_list = ["buy house or loan","budget","first time buyer","zip code","home feature"]
message_classes = chains['category'].run(input_message=input_message)
detected_classes = []
for i in classe_list:
if i in message_classes.lower():
detected_classes.append(i)
print("detected_classes: ",detected_classes)
return detected_classes
def compress_response(input_message,input_question,user_state,assigned_class=None,user_info=None):
# new_task_template = """ You are a compressor that get a question and answer and extremly compress the answer into short term. \
# Here is the question :
# {question}
# Here is the answer :
# {answer}
# """
# prompt = ChatPromptTemplate.from_template(template=new_task_template)
# chain = LLMChain(llm=llm, prompt=prompt)
if "buy house or loan"in assigned_class.lower():
user_state.remove('buy house or loan')
chain = chains[assigned_class]
response = chain.run(question=input_question , answer=input_message)
elif 'zip code'in assigned_class.lower():
user_state.remove('zip code')
chain = chains[assigned_class]
response = chain.run(question=input_question , answer=input_message)
elif 'home feature'in assigned_class.lower():
user_state.remove('home feature')
chain = chains[assigned_class]
response = chain.run(question=input_question , answer=input_message)
elif 'budget' in assigned_class.lower():
user_state.remove('budget')
chain = chains[assigned_class]
response = chain.run(question=input_question , answer=input_message)
elif 'first time buyer' in assigned_class.lower():
user_state.remove('first time buyer')
chain = chains[assigned_class]
response = chain.run(question=input_question , answer=input_message)
elif 'ignored' in assigned_class.lower():
# user_state.remove('ignored')
response = f"I can't understand your answer. please rephrase your answer for this question. \n {user_info}"
return response ,user_state
# Great. You can see this website to see the house feature.
# https://www.zillow.com/homes/22201-wayside-Mission-viej-CA92692_ib/25614382_zpid