Spaces:
Sleeping
Sleeping
File size: 4,886 Bytes
acc6be8 0e1b8a9 e89f4e8 0e1b8a9 e89f4e8 0e1b8a9 06f7794 e89f4e8 06f7794 0e1b8a9 06f7794 4654974 06f7794 0e1b8a9 e89f4e8 0e1b8a9 06f7794 0e1b8a9 06f7794 0e1b8a9 06f7794 |
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 |
import streamlit as st
from openai import OpenAI
import time
import os
import uuid
import firebase_admin
from firebase_admin import credentials, firestore
# π Firebase setup
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")
client = OpenAI(api_key=openai_key)
# π Streamlit Config
st.set_page_config(page_title="Motus AI Assistant", layout="wide")
# π― Session + 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"]
# πΌοΈ Motus Branding + Styling
st.markdown("""
<style>
.block-container {padding-top: 1rem; padding-bottom: 0rem;}
header {visibility: hidden;}
.stChatMessage {
max-width: 85%;
border-radius: 12px;
padding: 10px;
margin-bottom: 12px;
}
.stChatMessage[data-testid="stChatMessage-user"] {
background: #f4f4f4; color: #000000;
}
.stChatMessage[data-testid="stChatMessage-assistant"] {
background: #013D52; color: #ffffff;
}
.stChatMessage strong { color: #E2003C; }
@media screen and (max-width: 768px) {
.stChatInputContainer {
width: 95% !important;
margin: auto;
display: block;
}
.clear-chat-container {
display: none !important;
}
}
</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; flex-direction: column;'>
<img src='https://image.pitchbook.com/FSCikPkJGVVk4dj1N7FPajiBkjg1726492204281_200x200' width='120' style='margin-bottom: 5px;' />
<span style='font-size: 13px; color: gray;'>Powered by Motus Holdings</span>
</span>
</div>
""", unsafe_allow_html=True)
# π Get or create a thread ID
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:
thread = client.beta.threads.create()
doc_ref.set({"thread_id": thread.id, "created_at": firestore.SERVER_TIMESTAMP})
return thread.id
# πΎ Save a message
def save_message(role, content):
db.collection("users").document(user_id).collection("messages").add({
"role": role,
"content": content,
"timestamp": firestore.SERVER_TIMESTAMP
})
# π¬ Display chat history
def display_chat_history():
messages = db.collection("users").document(user_id).collection("messages").order_by("timestamp").stream()
for msg in list(messages)[::-1]:
data = msg.to_dict()
if data["role"] == "user":
st.markdown(f"<div class='stChatMessage' data-testid='stChatMessage-user'>π€ <strong>You:</strong> {data['content']}</div>", unsafe_allow_html=True)
else:
st.markdown(f"<div class='stChatMessage' data-testid='stChatMessage-assistant'><strong>Motus Assistant:</strong> {data['content']}</div>", unsafe_allow_html=True)
# π Main Chat UI
input_col, clear_col = st.columns([9, 1])
with input_col:
user_input = st.chat_input("Type your message here...")
with clear_col:
st.markdown("<div class='clear-chat-container'>", unsafe_allow_html=True)
if st.button("ποΈ", key="clear-chat", help="Clear Chat"):
try:
user_doc_ref = db.collection("users").document(user_id)
for msg in user_doc_ref.collection("messages").stream():
msg.reference.delete()
user_doc_ref.delete()
st.session_state.clear()
st.rerun()
except Exception as e:
st.error(f"Failed to clear chat: {e}")
st.markdown("</div>", unsafe_allow_html=True)
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)
st.rerun()
|