File size: 4,625 Bytes
2def93d
4060393
 
c645389
e39a43f
 
 
 
2060f4b
e39a43f
 
 
 
 
 
2060f4b
c645389
e69869b
2060f4b
 
 
d93083e
4060393
2060f4b
e39a43f
 
 
 
0bfec63
e69869b
 
98f2c4f
 
691e8b4
5c03320
0bfec63
 
e69869b
 
 
e39a43f
db82163
d4828d9
0bfec63
 
d4828d9
db82163
e39a43f
db82163
a12df8d
e39a43f
 
 
 
 
 
 
087e42a
e39a43f
 
a12df8d
e39a43f
 
 
 
 
 
 
a12df8d
e39a43f
53b56c5
0bfec63
2060f4b
e39a43f
 
53b56c5
e39a43f
0bfec63
e39a43f
a12df8d
c6c3d34
 
 
a12df8d
c6c3d34
 
 
 
 
 
 
 
 
 
 
2060f4b
c6c3d34
 
2060f4b
c6c3d34
0bfec63
c6c3d34
 
a12df8d
c6c3d34
 
 
 
 
 
 
a12df8d
c6c3d34
 
 
a12df8d
c6c3d34
 
 
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
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="LOR Technologies 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"]

# πŸ–ΌοΈ LOR Branding + Styling
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: #e3f2fd; color: #000000; }
    .lor-logo { vertical-align: middle; }
    </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://lortechnologies.com/wp-content/uploads/2023/03/LOR-Online-Logo.svg' width='100' class='lor-logo'/>
            <span style='font-size: 12px; color: gray;'>Powered by LOR Technologies</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()
    assistant_icon_html = "<img src='https://lortechnologies.com/wp-content/uploads/2023/03/LOR-Online-Logo.svg' width='20' style='vertical-align:middle;'/>"
    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'>{assistant_icon_html} <strong>LOR 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:
    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}")

thread_id = get_or_create_thread_id()
display_chat_history()

if user_input:
    # Send user message to OpenAI thread
    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()