Spaces:
Running
Running
File size: 5,833 Bytes
2def93d 4060393 c645389 1c2dc95 e39a43f 4ef479c 4060393 e39a43f c645389 e69869b b1e9ba4 c0332bf 4060393 e39a43f e69869b 98f2c4f 691e8b4 5c03320 691e8b4 d4828d9 e69869b e39a43f db82163 d4828d9 db82163 e39a43f db82163 e39a43f 691e8b4 fa08413 691e8b4 1b961be fa08413 691e8b4 e39a43f fa08413 e39a43f 4867300 17e4a36 e39a43f fa08413 e39a43f fa08413 e39a43f 4867300 e39a43f 4867300 e39a43f 17e4a36 e39a43f 4867300 e39a43f 17e4a36 e39a43f 4867300 e39a43f 4867300 e39a43f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
import streamlit as st
from openai import OpenAI
import time
import os
import pandas as pd
import uuid
from datetime import datetime
# Firebase setup
import firebase_admin
from firebase_admin import credentials, firestore
if not firebase_admin._apps:
cred = credentials.Certificate("firebase-service-account.json")
firebase_admin.initialize_app(cred)
db = firestore.client()
# OpenAI setup
openai_key = os.getenv("openai_key")
assistant_id = os.getenv("ASSISTANT_ID")
st.set_page_config(page_title="Carfind.co.za AI Assistant", layout="wide")
# Session + Firebase user ID
if "user_id" not in st.session_state:
st.session_state["user_id"] = str(uuid.uuid4())
user_id = st.session_state["user_id"]
# Styling + Branding
st.markdown("""
<style>
.block-container {padding-top: 1rem; padding-bottom: 0rem;}
header {visibility: hidden;}
.stChatMessage { max-width: 85%; border-radius: 12px; padding: 8px; margin-bottom: 10px; }
.stChatMessage[data-testid="stChatMessage-user"] { background: #f0f0f0; color: #000000; }
.stChatMessage[data-testid="stChatMessage-assistant"] { background: #D6E9FE; color: #000000; }
div[data-testid="column"] button {
border: none;
background-color: transparent;
font-size: 1.4rem;
margin-top: 18px;
}
@keyframes bounceIn {
0% { transform: scale(0.7); opacity: 0; }
60% { transform: scale(1.1); opacity: 1; }
80% { transform: scale(0.95); }
100% { transform: scale(1); }
}
.carfind-logo {
animation: bounceIn 0.6s ease-out;
}
</style>
""", unsafe_allow_html=True)
st.markdown("""
<div style='text-align: center; margin-top: 20px; margin-bottom: -10px;'>
<span style='display: inline-flex; align-items: center; gap: 8px;'>
<img src='https://www.carfind.co.za/images/Carfind-Icon.svg' width='30' class='carfind-logo'/>
<span style='font-size: 14px; color: gray;'>Powered by Carfind</span>
</span>
</div>
""", unsafe_allow_html=True)
# Chat input + Clear Chat button
input_col, clear_col = st.columns([9, 1])
with input_col:
user_input = st.chat_input("Type your message here...")
with clear_col:
if st.button("🗑️", key="clear-chat", help="Clear Chat"):
try:
# Delete messages
user_doc_ref = db.collection("users").document(user_id)
message_collection = user_doc_ref.collection("messages").stream()
for msg in message_collection:
msg.reference.delete()
# Delete user doc
user_doc_ref.delete()
# Clear session and rerun
st.session_state.clear()
st.rerun()
except Exception as e:
st.error(f"Failed to clear chat: {e}")
# Create or load thread ID from Firebase
def get_or_create_thread_id():
doc_ref = db.collection("users").document(user_id)
doc = doc_ref.get()
if doc.exists:
return doc.to_dict()["thread_id"]
else:
client = OpenAI(api_key=openai_key)
thread = client.beta.threads.create()
doc_ref.set({
"thread_id": thread.id,
"created_at": firestore.SERVER_TIMESTAMP
})
return thread.id
# Save message to Firestore
def save_message(role, content):
db.collection("users").document(user_id).collection("messages").add({
"role": role,
"content": content,
"timestamp": firestore.SERVER_TIMESTAMP
})
# Display past chat messages (latest at the top)
def display_chat_history():
messages = db.collection("users").document(user_id).collection("messages") \
.order_by("timestamp").stream()
messages_list = list(messages)[::-1] # Reverse to show latest first
assistant_icon_html = "<img src='https://www.carfind.co.za/images/Carfind-Icon.svg' width='22' style='vertical-align:middle;'/>"
for msg in messages_list:
data = msg.to_dict()
if data["role"] == "user":
st.markdown(
f"<div class='stChatMessage' data-testid='stChatMessage-user'>"
f"👤 <strong>You:</strong> {data['content']}</div>", unsafe_allow_html=True
)
else:
st.markdown(
f"<div class='stChatMessage' data-testid='stChatMessage-assistant'>"
f"{assistant_icon_html} <strong>Carfind Assistant:</strong> {data['content']}</div>",
unsafe_allow_html=True
)
# OpenAI assistant interaction
if openai_key and assistant_id:
client = OpenAI(api_key=openai_key)
thread_id = get_or_create_thread_id()
display_chat_history()
if user_input:
client.beta.threads.messages.create(
thread_id=thread_id, role="user", content=user_input
)
save_message("user", user_input)
with st.spinner("Thinking and typing... 💭"):
run = client.beta.threads.runs.create(
thread_id=thread_id,
assistant_id=assistant_id
)
while True:
run_status = client.beta.threads.runs.retrieve(
thread_id=thread_id,
run_id=run.id
)
if run_status.status == "completed":
break
time.sleep(1)
messages_response = client.beta.threads.messages.list(thread_id=thread_id)
latest_response = sorted(messages_response.data, key=lambda x: x.created_at)[-1]
assistant_message = latest_response.content[0].text.value
save_message("assistant", assistant_message)
time.sleep(0.5) # Ensure Firestore timestamps sort properly
st.rerun()
else:
st.error("⚠️ OpenAI key or Assistant ID not found. Please set them as Hugging Face secrets.")
|