import streamlit as st
import requests
import time
# --- 1. PAGE CONFIG ---
st.set_page_config(
page_title="RAG Insight Assistant",
page_icon="🧠",
layout="wide",
initial_sidebar_state="expanded"
)
# --- 2. THE OFFICIAL UNIFIED UI (CSS) ---
st.markdown("""
""", unsafe_allow_html=True)
# --- 3. MAIN UI STRUCTURE ---
st.markdown("""
🧠 RAG Insight
""", unsafe_allow_html=True)
# Sidebar for Controls and Knowledge Base
with st.sidebar:
st.image("https://img.icons8.com/fluency/96/artificial-intelligence.png", width=80)
st.title("Knowledge Hub")
st.markdown("""
Engine: Cohere Command-R
Vector DB: Qdrant
RAG Protocol: Enabled
""", unsafe_allow_html=True)
# Document Topic Section
st.subheader("📄 Current Context")
st.markdown("""
Topic: employee handbook / Document Analysis
Source: sample.pdf
""", unsafe_allow_html=True)
st.subheader("📁 Document Management")
# Pre-requisite Note
st.warning("⚠️ **Note:** Please 'Upload Docs' before asking questions to process the document embeddings.")
if st.button("Upload document"):
with st.spinner("Processing document embeddings..."):
try:
# Adding a small delay for UI feel
time.sleep(1)
response = requests.post("http://localhost:8000/ingest")
if response.status_code == 200:
st.success("✅ System ready! Document indexed.")
else:
st.error(f"❌ Initialization failed: {response.text}")
except Exception as e:
st.error(f"⚠️ Connection error: {e}")
st.divider()
with st.expander("🔍 How it works"):
st.write("""
1. **Context Ingestion:** Documents are parsed and converted into high-dimensional vectors.
2. **Neural Search:** Your questions are compared against the document database to find relevant matches.
3. **Guided Synthesis:** The AI generates an answer restricted solely to the retrieved context for maximum accuracy.
""")
# Chat Interface Logic
if "messages" not in st.session_state:
st.session_state.messages = []
# Display chat history with custom styling
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# User Interaction
if prompt := st.chat_input("Ask a question about your documents..."):
# Store user message
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# Generate Response
with st.chat_message("assistant"):
message_placeholder = st.empty()
with st.spinner("Analyzing knowledge base..."):
try:
response = requests.post(
"http://localhost:8000/query",
json={"question": prompt}
)
if response.status_code == 200:
answer = response.json().get("answer", "I couldn't find a relevant answer in the provided documents.")
# Simulate typing effect for a better feel
full_response = ""
for chunk in answer.split():
full_response += chunk + " "
time.sleep(0.05)
message_placeholder.markdown(full_response + "▌")
message_placeholder.markdown(full_response)
st.session_state.messages.append({"role": "assistant", "content": full_response})
else:
st.error("The backend service is currently unreachable.")
except Exception as e:
st.error(f"An unexpected error occurred: {e}")
# Footer
st.markdown("---")
st.caption("Powered by Cohere and Qdrant • Developed for RAG Insights")