Spaces:
Running
Running
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") |