Shubham170793 commited on
Commit
a5483fe
Β·
verified Β·
1 Parent(s): 2607352

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +52 -60
src/streamlit_app.py CHANGED
@@ -5,14 +5,14 @@ import streamlit as st
5
  import torch
6
 
7
  # ==========================================================
8
- # βœ… Page Configuration
9
  # ==========================================================
10
  st.set_page_config(page_title="Enterprise Knowledge Assistant", layout="wide")
 
11
 
12
  # ==========================================================
13
- # βš™οΈ Environment Setup
14
  # ==========================================================
15
- print("CUDA available:", torch.cuda.is_available())
16
  CACHE_DIR = "/tmp/hf_cache"
17
  os.makedirs(CACHE_DIR, exist_ok=True)
18
  os.environ.update({
@@ -23,14 +23,14 @@ os.environ.update({
23
  })
24
 
25
  # ==========================================================
26
- # πŸ“¦ Imports (Your existing modules)
27
  # ==========================================================
28
  from ingestion import extract_text_from_pdf, chunk_text
29
  from vectorstore import build_faiss_index
30
  from qa import retrieve_chunks, generate_answer, cache_embeddings, embed_chunks, genai_generate
31
 
32
  # ==========================================================
33
- # 🧠 Dynamic Suggestions (Document-Based)
34
  # ==========================================================
35
  def generate_dynamic_suggestions_from_toc(toc, chunks, doc_name="Document"):
36
  if not toc or not chunks:
@@ -52,7 +52,7 @@ def generate_dynamic_suggestions_from_toc(toc, chunks, doc_name="Document"):
52
  TEXT SAMPLE:
53
  {context_sample}
54
 
55
- Generate 5–7 questions that are short, relevant, and strictly document-based.
56
  Each question should be under 18 words.
57
  """
58
  try:
@@ -66,26 +66,15 @@ def generate_dynamic_suggestions_from_toc(toc, chunks, doc_name="Document"):
66
  final.append(q)
67
  return final[:7]
68
  except Exception:
69
- return ["What is this document about?", "How do I start using this process?"]
70
 
71
  # ==========================================================
72
- # 🎨 UI Styling (Subtle Enhancements)
73
  # ==========================================================
74
  st.markdown("""
75
  <style>
76
- div.block-container {
77
- padding-top: 1.2rem;
78
- max-width: 1080px;
79
- }
80
- h1, h2, h3 {
81
- color: #f3f4f6;
82
- font-weight: 600;
83
- }
84
- hr {
85
- border: none;
86
- border-top: 1px solid #2c2c2c;
87
- margin: 1rem 0;
88
- }
89
  .suggest-chip {
90
  background: #0f1724;
91
  border: 1px solid #374151;
@@ -98,10 +87,7 @@ hr {
98
  display: inline-block;
99
  transition: background 0.2s, transform 0.1s;
100
  }
101
- .suggest-chip:hover {
102
- background: #1e3a8a;
103
- transform: translateY(-2px);
104
- }
105
  .answer-box {
106
  background: linear-gradient(180deg,#0b1220,#071027);
107
  border-left: 4px solid #3b82f6;
@@ -122,7 +108,7 @@ hr {
122
  """, unsafe_allow_html=True)
123
 
124
  # ==========================================================
125
- # 🧭 Sidebar (Simplified for Users)
126
  # ==========================================================
127
  with st.sidebar:
128
  st.markdown("### 🧭 Response Mode")
@@ -130,35 +116,34 @@ with st.sidebar:
130
  "",
131
  ("Strict (Document-only)", "Extended (Document + general)"),
132
  index=0,
133
- help="Strict = answers only from the document. Extended = may include helpful general info.",
134
  )
 
135
  st.markdown("---")
136
- show_advanced = st.checkbox("Show advanced settings (for devs)", value=False)
137
  if show_advanced:
138
  st.markdown("### Developer Settings")
139
- chunk_size = st.slider("Chunk Size (chars)", 200, 1500, 1000, step=50)
140
- overlap = st.slider("Chunk Overlap (chars)", 50, 200, 120, step=10)
141
  top_k = st.slider("Top K Results", 1, 10, 5)
142
  else:
143
- chunk_size = 1000
144
- overlap = 120
145
- top_k = 5
146
  st.markdown("---")
147
  st.caption("✨ Built by Shubham Sharma")
148
 
149
  # ==========================================================
150
- # 🧠 Session State
151
  # ==========================================================
152
- if "user_query_input" not in st.session_state:
153
- st.session_state["user_query_input"] = ""
154
- if "show_more" not in st.session_state:
155
- st.session_state["show_more"] = False
156
- if "selected_suggestion" not in st.session_state:
157
- st.session_state["selected_suggestion"] = None
158
- if "query_suggestions_fixed" not in st.session_state:
159
- st.session_state["query_suggestions_fixed"] = None
160
- if "last_doc" not in st.session_state:
161
- st.session_state["last_doc"] = None
162
 
163
  def set_user_query(q, idx):
164
  st.session_state["user_query_input"] = q
@@ -166,26 +151,33 @@ def set_user_query(q, idx):
166
  st.experimental_rerun()
167
 
168
  # ==========================================================
169
- # πŸ“„ Main UI
170
  # ==========================================================
171
  st.title("πŸ“„ Enterprise Knowledge Assistant")
172
  st.caption("Query SAP documentation and enterprise PDFs β€” powered by reasoning and retrieval.")
173
 
174
- doc_choice = st.radio("Select a document:", ["-- Select --", "Sample PDF", "Upload Custom PDF"], index=0)
 
 
 
 
175
 
 
 
 
176
  if doc_choice == "-- Select --":
177
- st.info("⬅️ Please select a document to begin.")
178
  else:
179
  if doc_choice == "Sample PDF":
180
  temp_path = os.path.join(os.path.dirname(__file__), "sample.pdf")
181
- st.success("πŸ“˜ Using built-in Sample PDF.")
182
  else:
183
- uploaded_file = st.file_uploader("πŸ“‚ Upload your PDF", type="pdf")
184
  if uploaded_file:
185
  temp_path = os.path.join("/tmp", uploaded_file.name)
186
  with open(temp_path, "wb") as f:
187
  f.write(uploaded_file.getbuffer())
188
- st.success(f"βœ… '{uploaded_file.name}' uploaded successfully β€” ready to query below.")
189
  else:
190
  temp_path = None
191
 
@@ -193,10 +185,12 @@ else:
193
  with st.spinner("πŸ” Processing document..."):
194
  text, toc = extract_text_from_pdf(temp_path)
195
  chunks = chunk_text(text, chunk_size=chunk_size)
196
- with st.spinner("βš™οΈ Preparing search index..."):
 
197
  embeddings = cache_embeddings(os.path.basename(temp_path), chunks, embed_chunks)
198
  index = build_faiss_index(embeddings)
199
- st.success("βœ… Document ready β€” you can now ask questions below.")
 
200
 
201
  doc_name = os.path.basename(temp_path)
202
  if st.session_state["last_doc"] != doc_name:
@@ -207,15 +201,13 @@ else:
207
  query_suggestions = st.session_state["query_suggestions_fixed"]
208
 
209
  # ----------------------------------------------------------
210
- # πŸ’¬ Ask a Question Section
211
  # ----------------------------------------------------------
212
  st.markdown("### Ask the Assistant")
213
 
214
  if query_suggestions:
215
  visible = query_suggestions if st.session_state["show_more"] else query_suggestions[:3]
216
  cols = st.columns(min(3, len(visible)))
217
-
218
- # βœ… FIXED - Only display one instance of suggestions
219
  for i, q in enumerate(visible):
220
  if cols[i % 3].button(f"πŸ” {q}", key=f"sugg_{i}"):
221
  set_user_query(q, i)
@@ -227,18 +219,18 @@ else:
227
 
228
  user_query = st.text_input("Type your question or click one above:", key="user_query_input")
229
 
 
 
 
230
  if user_query.strip():
231
- with st.spinner("πŸ’­ Generating response..."):
232
  retrieved = retrieve_chunks(user_query, index, chunks, top_k=top_k)
233
  answer = generate_answer(user_query, retrieved)
234
  st.markdown("### Assistant")
235
  st.markdown(f"<div class='answer-box'>πŸ’‘ {answer}</div>", unsafe_allow_html=True)
236
 
237
- # πŸ‘‡ Smooth scroll to answer
238
  st.markdown("""
239
- <script>
240
- window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
241
- </script>
242
  """, unsafe_allow_html=True)
243
 
244
  with st.expander("πŸ“„ Supporting Context"):
 
5
  import torch
6
 
7
  # ==========================================================
8
+ # βœ… PAGE CONFIG
9
  # ==========================================================
10
  st.set_page_config(page_title="Enterprise Knowledge Assistant", layout="wide")
11
+ print("CUDA available:", torch.cuda.is_available())
12
 
13
  # ==========================================================
14
+ # βš™οΈ CACHE DIR
15
  # ==========================================================
 
16
  CACHE_DIR = "/tmp/hf_cache"
17
  os.makedirs(CACHE_DIR, exist_ok=True)
18
  os.environ.update({
 
23
  })
24
 
25
  # ==========================================================
26
+ # πŸ“¦ IMPORTS
27
  # ==========================================================
28
  from ingestion import extract_text_from_pdf, chunk_text
29
  from vectorstore import build_faiss_index
30
  from qa import retrieve_chunks, generate_answer, cache_embeddings, embed_chunks, genai_generate
31
 
32
  # ==========================================================
33
+ # 🧠 SMART SUGGESTION GENERATOR
34
  # ==========================================================
35
  def generate_dynamic_suggestions_from_toc(toc, chunks, doc_name="Document"):
36
  if not toc or not chunks:
 
52
  TEXT SAMPLE:
53
  {context_sample}
54
 
55
+ Generate 5–7 short, relevant, strictly document-based questions.
56
  Each question should be under 18 words.
57
  """
58
  try:
 
66
  final.append(q)
67
  return final[:7]
68
  except Exception:
69
+ return ["What is this document about?", "How do I begin using this guide?"]
70
 
71
  # ==========================================================
72
+ # 🎨 STYLING β€” MINIMAL, ENTERPRISE UI
73
  # ==========================================================
74
  st.markdown("""
75
  <style>
76
+ div.block-container {padding-top: 1.2rem; max-width: 1080px;}
77
+ h1, h2, h3 {color: #f3f4f6; font-weight: 600;}
 
 
 
 
 
 
 
 
 
 
 
78
  .suggest-chip {
79
  background: #0f1724;
80
  border: 1px solid #374151;
 
87
  display: inline-block;
88
  transition: background 0.2s, transform 0.1s;
89
  }
90
+ .suggest-chip:hover {background: #1e3a8a; transform: translateY(-2px);}
 
 
 
91
  .answer-box {
92
  background: linear-gradient(180deg,#0b1220,#071027);
93
  border-left: 4px solid #3b82f6;
 
108
  """, unsafe_allow_html=True)
109
 
110
  # ==========================================================
111
+ # 🧭 SIDEBAR β€” SIMPLE
112
  # ==========================================================
113
  with st.sidebar:
114
  st.markdown("### 🧭 Response Mode")
 
116
  "",
117
  ("Strict (Document-only)", "Extended (Document + general)"),
118
  index=0,
119
+ help="Strict = answers only from the document. Extended = may include general context.",
120
  )
121
+
122
  st.markdown("---")
123
+ show_advanced = st.checkbox("Show advanced settings (for developers)", value=False)
124
  if show_advanced:
125
  st.markdown("### Developer Settings")
126
+ chunk_size = st.slider("Chunk Size (characters)", 200, 1500, 1000, step=50)
127
+ overlap = st.slider("Chunk Overlap (characters)", 50, 200, 120, step=10)
128
  top_k = st.slider("Top K Results", 1, 10, 5)
129
  else:
130
+ chunk_size, overlap, top_k = 1000, 120, 5
131
+
 
132
  st.markdown("---")
133
  st.caption("✨ Built by Shubham Sharma")
134
 
135
  # ==========================================================
136
+ # 🧠 SESSION STATE
137
  # ==========================================================
138
+ for key, val in {
139
+ "user_query_input": "",
140
+ "show_more": False,
141
+ "selected_suggestion": None,
142
+ "query_suggestions_fixed": None,
143
+ "last_doc": None,
144
+ }.items():
145
+ if key not in st.session_state:
146
+ st.session_state[key] = val
 
147
 
148
  def set_user_query(q, idx):
149
  st.session_state["user_query_input"] = q
 
151
  st.experimental_rerun()
152
 
153
  # ==========================================================
154
+ # πŸ“„ MAIN LAYOUT
155
  # ==========================================================
156
  st.title("πŸ“„ Enterprise Knowledge Assistant")
157
  st.caption("Query SAP documentation and enterprise PDFs β€” powered by reasoning and retrieval.")
158
 
159
+ doc_choice = st.radio(
160
+ "Select a document:",
161
+ ["-- Select --", "Sample PDF", "Upload Custom PDF"],
162
+ index=0
163
+ )
164
 
165
+ # ==========================================================
166
+ # πŸ“‚ DOCUMENT HANDLING
167
+ # ==========================================================
168
  if doc_choice == "-- Select --":
169
+ st.info("⬅️ Select a document to begin.")
170
  else:
171
  if doc_choice == "Sample PDF":
172
  temp_path = os.path.join(os.path.dirname(__file__), "sample.pdf")
173
+ st.success("πŸ“˜ Sample PDF loaded successfully. Ask questions below.")
174
  else:
175
+ uploaded_file = st.file_uploader("", type="pdf", label_visibility="collapsed")
176
  if uploaded_file:
177
  temp_path = os.path.join("/tmp", uploaded_file.name)
178
  with open(temp_path, "wb") as f:
179
  f.write(uploaded_file.getbuffer())
180
+ st.success("βœ… Document loaded successfully. You can now ask questions below.")
181
  else:
182
  temp_path = None
183
 
 
185
  with st.spinner("πŸ” Processing document..."):
186
  text, toc = extract_text_from_pdf(temp_path)
187
  chunks = chunk_text(text, chunk_size=chunk_size)
188
+
189
+ with st.spinner("βš™οΈ Preparing index..."):
190
  embeddings = cache_embeddings(os.path.basename(temp_path), chunks, embed_chunks)
191
  index = build_faiss_index(embeddings)
192
+
193
+ st.success("βœ… Ready. Ask below!")
194
 
195
  doc_name = os.path.basename(temp_path)
196
  if st.session_state["last_doc"] != doc_name:
 
201
  query_suggestions = st.session_state["query_suggestions_fixed"]
202
 
203
  # ----------------------------------------------------------
204
+ # πŸ’¬ ASK ASSISTANT SECTION
205
  # ----------------------------------------------------------
206
  st.markdown("### Ask the Assistant")
207
 
208
  if query_suggestions:
209
  visible = query_suggestions if st.session_state["show_more"] else query_suggestions[:3]
210
  cols = st.columns(min(3, len(visible)))
 
 
211
  for i, q in enumerate(visible):
212
  if cols[i % 3].button(f"πŸ” {q}", key=f"sugg_{i}"):
213
  set_user_query(q, i)
 
219
 
220
  user_query = st.text_input("Type your question or click one above:", key="user_query_input")
221
 
222
+ # ----------------------------------------------------------
223
+ # πŸ’‘ RESPONSE
224
+ # ----------------------------------------------------------
225
  if user_query.strip():
226
+ with st.spinner("πŸ’­ Thinking..."):
227
  retrieved = retrieve_chunks(user_query, index, chunks, top_k=top_k)
228
  answer = generate_answer(user_query, retrieved)
229
  st.markdown("### Assistant")
230
  st.markdown(f"<div class='answer-box'>πŸ’‘ {answer}</div>", unsafe_allow_html=True)
231
 
 
232
  st.markdown("""
233
+ <script>window.scrollTo({top: document.body.scrollHeight, behavior: 'smooth'});</script>
 
 
234
  """, unsafe_allow_html=True)
235
 
236
  with st.expander("πŸ“„ Supporting Context"):