File size: 5,542 Bytes
7d69c00
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
172
173
174
175
176
177
178
179
180
181
182
"""
Frontend Streamlit application for the chatbot (fixed version).
"""
import streamlit as st
import os
# Import the entire backend module instead of specific functions
import backend
from utils.logging_config import setup_logging
import config

# Setup logging
logger = setup_logging()

# Constants for memory optimization
MAX_MESSAGES = 50

# Set page config
st.set_page_config(
    page_title="Document Chatbot",
    page_icon="πŸ“š",
    layout="centered",
    initial_sidebar_state="collapsed"
)

# Hide Streamlit's default elements and style sidebar
st.markdown("""
<style>
/* Hide default elements */
button[kind="deploy"], 
[data-testid="stToolbar"],
.stDeployButton,
#MainMenu,
footer {
    display: none !important;
}

/* Style the sidebar */
[data-testid="stSidebar"] {
    width: 120px !important;
    background-color: #0e1117 !important;
    border-right: 1px solid #1e1e1e !important;
}

/* Style the collapse button to prevent movement and maintain size */
button[kind="menuButton"] {
    left: 120px !important;
    margin-left: 0 !important;
    position: fixed !important;
    transform: translateX(0) !important;
    transition: none !important;
    background-color: #0e1117 !important;
    color: #fff !important;
    z-index: 999 !important;
}

/* Button styling */
[data-testid="stSidebar"] [data-testid="stButton"] button {
    background-color: #262730 !important;
    color: white !important;
    padding: 8px 10px !important;
    width: 100px !important;
    font-size: 0.9rem !important;
    margin: 1rem auto !important;
    display: block !important;
    border-radius: 4px !important;
    white-space: nowrap !important;
}

[data-testid="stSidebar"] [data-testid="stButton"] button p {
    text-align: center !important;
    white-space: nowrap !important;
    overflow: visible !important;
}

[data-testid="stSidebar"] [data-testid="stButton"] button:hover {
    background-color: #1E2130 !important;
}
</style>
""", unsafe_allow_html=True)

# Helper function to add messages and maintain history length
def add_message(role, content):
    """Add message to session state and trim if needed."""
    st.session_state.messages.append({"role": role, "content": content})
    # Trim message history if it gets too large
    if len(st.session_state.messages) > MAX_MESSAGES:
        # Keep the most recent messages
        st.session_state.messages = st.session_state.messages[-MAX_MESSAGES:]
    logger.info(f"Added {role} message. History length: {len(st.session_state.messages)}")

# Create a sidebar with just the button
with st.sidebar:
    def clear_chat():
        st.session_state.messages = []
        logger.info("Chat history cleared via sidebar button")
        st.rerun()
        
    st.button("Clear Chat", on_click=clear_chat)

# Initialize session state for chat history
if "messages" not in st.session_state:
    st.session_state.messages = []

# Initialize cached resources for all sessions
@st.cache_resource
def initialize_resources():
    """Initialize shared resources once for all sessions."""
    logger.info("Initializing shared resources...")
    
    # Get configuration from config module
    chatbot_config = config.get_chatbot_config()
    api_key = os.getenv("ANTHROPIC_API_KEY")
    
    # Load models using cache
    # Use the functions from the backend module
    llm = backend.load_llm_model(
        api_key,
        chatbot_config.get("model", "claude-3-7-sonnet-20250219"),
        chatbot_config.get("temperature", 0.1),
        chatbot_config.get("max_tokens", 2048)
    )
    
    embed_model = backend.load_embedding_model(
        chatbot_config.get("embedding_model", "sentence-transformers/all-MiniLM-L6-v2"),
        chatbot_config.get("device", "cpu"),
        chatbot_config.get("embed_batch_size", 8)
    )
    
    # Load or create index (shared across sessions)
    index = backend.load_or_create_index()
    
    return {
        "config": chatbot_config,
        "llm": llm,
        "embed_model": embed_model,
        "index": index
    }

# Get shared resources
resources = initialize_resources()

# Initialize chatbot only in session state if it doesn't exist
if "chatbot" not in st.session_state:
    with st.spinner("Initializing chatbot..."):
        logger.info("Initializing chatbot with shared resources...")
        st.session_state.chatbot = backend.Chatbot(
            resources["config"],
            resources["llm"],
            resources["embed_model"],
            resources["index"]
        )
        # Initialize query engine
        st.session_state.chatbot.initialize_query_engine()
        logger.info("Chatbot initialized successfully")

# Title and description
st.title("πŸ“š Paul's Chatbot")
st.markdown("""
This chatbot can answer questions about your documents. 
Ask any question about the content in your documents!
""")

# Display chat messages
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

# Chat input
if prompt := st.chat_input("What would you like to know?"):
    # Add user message to chat history
    add_message("user", prompt)
    with st.chat_message("user"):
        st.markdown(prompt)

    # Get chatbot response
    with st.chat_message("assistant"):
        with st.spinner("Thinking..."):
            logger.info(f"User query: {prompt}")
            response = st.session_state.chatbot.query(prompt)
            st.markdown(response)
            add_message("assistant", response)
            logger.info("Response provided to user")