Spaces:
Sleeping
Sleeping
| import json | |
| import os | |
| from typing import Dict | |
| import gradio as gr | |
| from openai import OpenAI | |
| from opensearchpy import OpenSearch | |
| host = "localhost" | |
| port = 9200 | |
| OPENSEARCH_ADMIN_PASSWORD = os.getenv("OPENSEARCH_ADMIN_PASSWORD", "yw7L5u9nLs3a") | |
| auth = ( | |
| "admin", | |
| OPENSEARCH_ADMIN_PASSWORD, | |
| ) # For testing only. Don't store credentials in code. | |
| # Create the client with SSL/TLS enabled, but hostname verification disabled. | |
| os_client = OpenSearch( | |
| hosts=[{"host": host, "port": port}], | |
| http_compress=True, # enables gzip compression for request bodies | |
| http_auth=auth, | |
| use_ssl=True, | |
| verify_certs=False, | |
| ssl_assert_hostname=False, | |
| ssl_show_warn=False, | |
| ) | |
| all_props = json.load(open("all_properties.json")) | |
| props_core = [ | |
| { | |
| "property": prop["property"], | |
| "address": prop["address"], | |
| "school": prop["school"], | |
| "listPrice": prop["listPrice"], | |
| } | |
| for prop in all_props | |
| ] | |
| client = OpenAI( | |
| # This is the default and can be omitted | |
| api_key=os.environ.get("OPENAI_API_KEY"), | |
| ) | |
| REQUIREMENTS_KEYS = [ | |
| "location", | |
| "budget", | |
| "house type", | |
| "layout", | |
| ] | |
| requirements: Dict[str, str] = {} | |
| def get_requirement_prompt(): | |
| return f"Current collected requirements: {requirements}.\nPlease let me know your requirements: {[key for key in REQUIREMENTS_KEYS if key not in requirements.keys()]}" | |
| def get_requirements(input_str): | |
| global requirements | |
| chat_completion = client.chat.completions.create( | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": """ | |
| You are a real estate agent looking for properties for your clients. You are now extracting information to understand user's requests. | |
| Requirements are: | |
| * location. For example: | |
| - City: Mountainview, San Jose, Dublin, etc | |
| - Postal Code: 95134, etc | |
| - Work or Regular Destination: work at Google; regular business flight | |
| - School: a specific school name; specify a rating range for schools. | |
| * budget. For example: | |
| - around 1 million; no more than 1.5 million; between 800k to 1 million | |
| * layout. For example: | |
| - Bedroom: 3 bedrooms; no less than 2 bedrooms; single; married; 2 kids | |
| - Bathroom: same as above | |
| * house type (one or multiple choices). For example: | |
| - condo, townhouse, single family | |
| If user's input is a requirement, please provide the content in the format '{requirement_type}:{content}'. For example, 'location:Houston'. If multiple requirements are provided, separate them with |. For example, 'location:Houston|budget:1 million'. | |
| If multiple requirements for the same type are provided, separate them with ;. For example, 'location:Houston;San Francisco'. DO NOT output multiple pairs with the same requirement type. | |
| Otherwise please provide helpful response to the user | |
| """, | |
| }, | |
| { | |
| "role": "user", | |
| "content": input_str, | |
| }, | |
| ], | |
| model="gpt-4o-mini", | |
| ) | |
| output = chat_completion.choices[0].message.content | |
| print(f"model output {output}") | |
| message_out = "" | |
| def set_requirement(output): | |
| nonlocal message_out | |
| if ":" not in output: | |
| return | |
| parts = output.split(":") | |
| req = parts[0].strip() | |
| content = output[len(req) + 1 :].strip() | |
| if req in REQUIREMENTS_KEYS: | |
| message_out = ( | |
| message_out | |
| + f"\nThanks! Collected requirement: {req}\n{get_requirement_prompt()}" | |
| ) | |
| requirements[req] = content | |
| if "|" in output: | |
| all_requirements = output.split("|") | |
| for req in all_requirements: | |
| set_requirement(req) | |
| else: | |
| set_requirement(output) | |
| return message_out.strip() | |
| chat_history = [] | |
| def find_property(input_str): | |
| global requirements | |
| global chat_history | |
| chat_completion = client.chat.completions.create( | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": f"You are a real estate agent looking for properties for your clients. Here are some properties that might be of interest to you: {json.dumps(props_core)}. Client is looking for properties that meet the following requirements: {requirements}", | |
| }, | |
| ] | |
| + chat_history, | |
| model="gpt-4o-mini", | |
| ) | |
| output = chat_completion.choices[0].message.content | |
| chat_history.append( | |
| { | |
| "role": "assistant", | |
| "content": output, | |
| } | |
| ) | |
| return output | |
| def process_chat_message(message, history): | |
| global chat_history | |
| output = "" | |
| if len(requirements) < len(REQUIREMENTS_KEYS): | |
| output = get_requirements(message) | |
| if len(requirements) == len(REQUIREMENTS_KEYS): | |
| output += "\n" + find_property(message) | |
| else: | |
| chat_history.append( | |
| { | |
| "role": "user", | |
| "content": message, | |
| } | |
| ) | |
| output = find_property(message) | |
| return output | |
| demo = gr.ChatInterface( | |
| fn=process_chat_message, | |
| chatbot=gr.Chatbot(value=[[None, get_requirement_prompt()]]), | |
| examples=[ | |
| "I want a house near Houston", | |
| "I have two kids, what type of house would I need?", | |
| "I have a budget of 1 million dollars", | |
| ], | |
| title="Buyer Agent Bot", | |
| ) | |
| demo.launch(share=True) | |