Spaces:
Runtime error
Runtime error
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 , send_zillow_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 | |
os.environ["OPENAI_API_KEY"] = "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" | |
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 |