File size: 5,836 Bytes
4060393
 
 
c645389
1c2dc95
41458b2
b1e9ba4
4060393
b1e9ba4
f7e33cd
 
c645389
e69869b
b1e9ba4
 
 
4060393
c0332bf
2826a06
f7e33cd
4060393
e69869b
 
 
5c03320
 
e69869b
 
 
b1e9ba4
1c2dc95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b1e9ba4
 
 
 
 
 
 
 
 
 
 
1c2dc95
b1e9ba4
1c2dc95
b1e9ba4
6dad2a2
 
 
 
e69869b
6dad2a2
 
f7e33cd
 
6dad2a2
f7e33cd
 
 
 
b1e9ba4
f7e33cd
555e200
f88fdb3
 
e69869b
 
f88fdb3
e69869b
 
 
d6ba0ba
e69869b
 
 
 
 
1b961be
b1e9ba4
1b961be
fb4fbbe
1b961be
e69869b
 
 
 
b1e9ba4
e69869b
 
 
b1e9ba4
e69869b
 
4ed1135
d6ba0ba
e69869b
d6ba0ba
1b961be
d6ba0ba
e69869b
d6ba0ba
1b961be
 
 
 
e69869b
 
 
 
4ed1135
 
b1e9ba4
4ed1135
 
 
 
b1e9ba4
 
4ed1135
 
b1e9ba4
 
4ed1135
 
b1e9ba4
 
4ed1135
e69869b
 
1b961be
b1e9ba4
 
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
import streamlit as st
from openai import OpenAI
import time
import os
import pandas as pd
import datetime
from huggingface_hub import HfApi, upload_file

# Environment variables
generated_user = os.getenv("User")
generated_password = os.getenv("Password")
openai_key = os.getenv("openai_key")
assistant_id = os.getenv("ASSISTANT_ID")
hf_token = os.getenv("HF_TOKEN")

transcript_file = "transcripts.xlsx"

st.set_page_config(page_title="Carfind.co.za AI Assistant", layout="wide")
st.markdown("<h1 style='text-align: center;'>๐Ÿš— Carfind.co.za AI Assistant</h1>", unsafe_allow_html=True)
st.caption("Chat with Carfind.co.za and find your next car fast")

st.markdown("""
    <style>
    .stChatMessage { max-width: 85%; border-radius: 12px; padding: 8px; }
    .stChatMessage[data-testid="stChatMessage-user"] { background: #f0f0f0; color: #000000; }
    .stChatMessage[data-testid="stChatMessage-assistant"] { background: #D6E9FE; color: #000000; }
    </style>
""", unsafe_allow_html=True)

# Save chat to Excel and push to Hugging Face repo
def append_to_transcript(thread_id, role, message):
    timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    new_entry = {
        "Timestamp": timestamp,
        "Thread_ID": thread_id,
        "Role": role,
        "Message": message
    }
    try:
        if os.path.exists(transcript_file):
            df = pd.read_excel(transcript_file)
            df = pd.concat([df, pd.DataFrame([new_entry])], ignore_index=True)
        else:
            df = pd.DataFrame([new_entry])
        df.to_excel(transcript_file, index=False)
        
        # Upload updated transcripts.xlsx to Hugging Face
        api = HfApi(token=hf_token)
        upload_file(
            path_or_fileobj=transcript_file,
            path_in_repo="transcripts.xlsx",
            repo_id="IAMTFRMZA/cfaiassistant",
            repo_type="space",
            token=hf_token,
            commit_message=f"Transcript update {timestamp}"
        )
    except Exception as e:
        st.error(f"Transcript logging failed: {str(e)}")

# Authentication
if "authenticated" not in st.session_state:
    st.session_state.authenticated = False

if not st.session_state.authenticated:
    st.subheader("๐Ÿ”‘ Login")
    username = st.text_input("Username")
    password = st.text_input("Password", type="password")
    if username and password:
        if username == generated_user and password == generated_password:
            st.session_state.authenticated = True
            st.success("Login successful! Redirecting...")
            time.sleep(1)
            st.rerun()
        else:
            st.error("Incorrect username or password.")

else:
    st.divider()

    if "thread_id" not in st.session_state:
        st.session_state["thread_id"] = None

    input_col, clear_col = st.columns([8, 1])
    with input_col:
        user_input = st.text_input("Type your message here...", key="chat_input")

    with clear_col:
        if st.button("๐Ÿ—‘๏ธ", help="Clear Chat"):
            st.session_state["thread_id"] = None
            st.success("Chat cleared.")
            st.rerun()

    if openai_key and assistant_id and hf_token:
        client = OpenAI(api_key=openai_key)

        if user_input:
            if not st.session_state["thread_id"]:
                thread = client.beta.threads.create()
                st.session_state["thread_id"] = thread.id

            # Add user message and log
            client.beta.threads.messages.create(
                thread_id=st.session_state["thread_id"], role="user", content=user_input
            )
            append_to_transcript(st.session_state["thread_id"], "user", user_input)

            try:
                with st.spinner("Thinking and typing... ๐Ÿ’ญ"):
                    run = client.beta.threads.runs.create(
                        thread_id=st.session_state["thread_id"], assistant_id=assistant_id
                    )
                    while True:
                        run_status = client.beta.threads.runs.retrieve(
                            thread_id=st.session_state["thread_id"], run_id=run.id
                        )
                        if run_status.status == "completed":
                            break
                        time.sleep(1)

                messages_response = client.beta.threads.messages.list(
                    thread_id=st.session_state["thread_id"]
                )

                assistant_icon_html = "<img src='https://www.carfind.co.za/images/Carfind-Icon.svg' width='22' style='vertical-align:middle;'/>"

                # Display chat conversation
                for msg in reversed(messages_response.data):
                    if msg.role == "user":
                        st.markdown(
                            f"<div style='background-color:#f0f0f0; color:#000000; padding:10px; border-radius:8px; margin:5px 0;'>"
                            f"๐Ÿ‘ค <strong>You:</strong> {msg.content[0].text.value}"
                            f"</div>", unsafe_allow_html=True
                        )
                    else:
                        response_text = msg.content[0].text.value
                        append_to_transcript(st.session_state["thread_id"], "assistant", response_text)
                        st.markdown(
                            f"<div style='background-color:#D6E9FE; color:#000000; padding:10px; border-radius:8px; margin:5px 0;'>"
                            f"{assistant_icon_html} <strong>Carfind Assistant:</strong> {response_text}"
                            f"</div>", unsafe_allow_html=True
                        )
            except Exception as e:
                st.error(f"An error occurred: {str(e)}")
    else:
        st.error("โš ๏ธ Missing OpenAI key, Assistant ID or HF token. Please check Hugging Face secrets.")