-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
196 lines (161 loc) Β· 7.12 KB
/
Copy pathapp.py
File metadata and controls
196 lines (161 loc) Β· 7.12 KB
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import os
import streamlit as st
from ingest import ingest_pdfs
from retriever import LlamaIndexHybridRetriever
from agents.workflow import AgentWorkflow
from config import UPLOAD_DIR, INDEX_DIR
# -------------------------
# Streamlit Page Setup
# -------------------------
st.set_page_config(page_title="Multi-Agentic RAG", layout="wide")
st.title("π Multi-Agentic RAG Chatbot")
# -------------------------
# Settings Sidebar
# -------------------------
with st.sidebar:
st.header("βοΈ Settings")
enable_verification = st.checkbox(
"Enable Verification",
value=False,
help="π Slower but validates answer accuracy. β‘ Disable for 3x faster responses."
)
st.info(
"β‘ **Fast Mode (Default)**: ~2-3 seconds\n\n"
"π **Verification Mode**: ~6-10 seconds but checks answer quality"
)
# -------------------------
# Session State
# -------------------------
if "chat_history" not in st.session_state:
st.session_state.chat_history = []
if "retriever" not in st.session_state:
st.session_state.retriever = None
if "files_indexed" not in st.session_state:
st.session_state.files_indexed = False
if "uploaded_file_names" not in st.session_state:
st.session_state.uploaded_file_names = set()
# -------------------------
# PDF Upload Section
# -------------------------
st.markdown("### π Upload Documents")
st.info("π‘ **Tip**: For large PDFs (>50MB or >200 pages), consider splitting them into smaller files for faster processing.")
uploaded_files = st.file_uploader(
"Upload PDF documents",
type=["pdf"],
accept_multiple_files=True,
help="Upload one or more PDF files. Large files will be processed in batches."
)
if uploaded_files:
# Get current file names
current_files = {file.name for file in uploaded_files}
# Check if files have changed
files_changed = current_files != st.session_state.uploaded_file_names
if files_changed:
st.session_state.files_indexed = False
st.session_state.uploaded_file_names = current_files
# Show index button only if files haven't been indexed yet
if not st.session_state.files_indexed:
# Calculate total size
total_size_mb = sum(file.size for file in uploaded_files) / (1024 * 1024)
# Show warning for large files
if total_size_mb > 50:
st.warning(f"β οΈ Large upload detected ({total_size_mb:.1f} MB). Indexing may take 2-5 minutes.")
# Individual file size warnings
for file in uploaded_files:
file_size_mb = file.size / (1024 * 1024)
if file_size_mb > 100:
st.warning(f"β οΈ {file.name} is very large ({file_size_mb:.1f} MB). Consider splitting it.")
# Add button to start indexing
if st.button("π Index PDFs", type="primary", use_container_width=True):
os.makedirs(UPLOAD_DIR, exist_ok=True)
# Save files
for file in uploaded_files:
file_path = os.path.join(UPLOAD_DIR, file.name)
with open(file_path, "wb") as f:
f.write(file.getbuffer())
# Progress bar for indexing
progress_bar = st.progress(0)
status_text = st.empty()
def update_progress(progress, message):
progress_bar.progress(progress)
status_text.text(message)
try:
ingest_pdfs(progress_callback=update_progress)
# Reset retriever cache after new upload
st.session_state.retriever = None
st.session_state.files_indexed = True
progress_bar.empty()
status_text.empty()
st.success("β
PDFs indexed successfully! You can now ask questions.")
st.rerun()
except MemoryError:
progress_bar.empty()
status_text.empty()
st.error("β File too large! Try splitting the PDF into smaller parts (< 100 pages each).")
st.session_state.files_indexed = False
except Exception as e:
progress_bar.empty()
status_text.empty()
st.error(f"β Error indexing PDFs: {str(e)}")
st.session_state.files_indexed = False
else:
# Files already indexed
st.success(f"β
{len(uploaded_files)} file(s) already indexed. You can ask questions below.")
# Add button to re-index if needed
if st.button("π Re-index PDFs", help="Click to re-process the uploaded files"):
st.session_state.files_indexed = False
st.rerun()
# -------------------------
# Chat History Display (SAFE)
# -------------------------
for msg in st.session_state.chat_history:
if isinstance(msg, dict):
# New format
if "user" in msg and "assistant" in msg:
st.chat_message("user").write(msg["user"])
st.chat_message("assistant").write(msg["assistant"])
# Display verification report if available
if "verification" in msg and msg["verification"]:
with st.expander("π Verification Report", expanded=False):
st.markdown(msg["verification"])
# Old / fallback format
elif msg.get("role") == "user":
st.chat_message("user").write(msg.get("content", ""))
elif msg.get("role") == "assistant":
st.chat_message("assistant").write(msg.get("content", ""))
# -------------------------
# Chat Input
# -------------------------
question = st.chat_input("Ask a question about the uploaded PDFs")
if question:
# Guard: index must exist
if not os.path.exists(INDEX_DIR) or not os.listdir(INDEX_DIR):
st.warning("β οΈ Please upload and index PDFs first.")
st.stop()
# Initialize retriever only once (cache in session state)
if st.session_state.retriever is None:
with st.spinner("Loading retriever..."):
st.session_state.retriever = LlamaIndexHybridRetriever()
retriever = st.session_state.retriever
workflow = AgentWorkflow(enable_verification=enable_verification)
# Show processing message
with st.spinner("π€ Thinking..." if not enable_verification else "π€ Thinking and verifying..."):
# π₯ FIXED: Only pass question and retriever (2 arguments)
result = workflow.full_pipeline(
question,
retriever
)
# Save chat in NEW SAFE FORMAT
st.session_state.chat_history.append({
"user": question,
"assistant": result.get("draft_answer", ""),
"verification": result.get("verification_report", "")
})
# Display current turn
st.chat_message("user").write(question)
st.chat_message("assistant").write(result.get("draft_answer", ""))
# Display verification report if available
verification_report = result.get("verification_report", "")
if verification_report:
with st.expander("π Verification Report", expanded=False):
st.markdown(verification_report)