cryogenic22 commited on
Commit
d39e016
·
verified ·
1 Parent(s): 4fb39db

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -346
app.py CHANGED
@@ -1,20 +1,11 @@
1
-
2
  # app.py
 
3
  import streamlit as st
4
  import os
5
  from pathlib import Path
6
  from typing import Dict, List, Optional, Any
7
  from datetime import datetime
8
  from threading import Lock
9
- from utils.storage_init import initialize_storage_structure, verify_storage_access
10
-
11
- # Components imports
12
- from components.chat import display_chat_interface
13
- from components.document_preview import enhanced_document_preview
14
- from components.collection_manager import (
15
- display_enhanced_collections,
16
- display_collection_content
17
- )
18
 
19
  from utils.database import (
20
  # Base database operations
@@ -36,20 +27,8 @@ from utils.database import (
36
 
37
  from components.chat import display_chat_interface
38
 
39
- # Message types
40
- from langchain_core.messages import (
41
- HumanMessage,
42
- AIMessage,
43
- SystemMessage,
44
- BaseMessage
45
- )
46
-
47
- import time
48
- from threading import Lock
49
-
50
  # Create locks for thread-safe operations
51
  conn_lock = Lock()
52
- vectorstore_lock = Lock()
53
 
54
  def initialize_database():
55
  """Initialize database with persistent storage."""
@@ -213,296 +192,46 @@ def display_collection_dialog():
213
  st.session_state.show_collection_dialog = False
214
  st.rerun()
215
 
216
- def display_chat_area():
217
- """Display the main chat interface."""
218
- if not st.session_state.chat_ready:
219
- st.title("🤖 Welcome to SYNAPTYX")
220
- st.markdown("### Your AI-powered RFP Analysis Assistant")
221
-
222
- col1, col2 = st.columns(2)
223
- with col1:
224
- st.markdown("""
225
- #### Getting Started:
226
- 1. Select or create a collection in the sidebar
227
- 2. Upload your RFP documents
228
- 3. Start analyzing with AI!
229
- """)
230
-
231
- with col2:
232
- st.markdown("#### Example Questions:")
233
- examples = [
234
- "📊 Summarize the main points of the document",
235
- "📝 Draft a 'Why Us' section based on the document",
236
- "🎯 Extract key success metrics and outcomes",
237
- "💡 What are the innovative solutions mentioned?",
238
- "🤝 Analyze the partnership benefits described"
239
- ]
240
- for example in examples:
241
- st.markdown(f"• {example}")
242
- else:
243
- display_chat_interface()
244
-
245
- # app.py
246
-
247
-
248
-
249
- def display_collections_tab():
250
- """Display the collections management interface."""
251
- col1, col2 = st.columns([1, 2])
252
 
 
253
  with col1:
254
- st.header("Collections")
255
-
256
- # New collection button
257
- if st.button("+ New Collection", use_container_width=True):
258
- st.session_state.show_collection_dialog = True
259
 
260
- # Collections list
261
- collections = get_collections(st.session_state.db_conn)
262
- for collection in collections:
263
- collection_button = st.button(
264
- f"📁 {collection['name']} ({collection['doc_count']})",
265
- key=f"col_{collection['id']}",
266
- use_container_width=True
267
- )
268
- if collection_button:
269
- st.session_state.selected_collection = collection
270
- st.rerun()
271
 
272
  with col2:
273
- if st.session_state.get('selected_collection'):
274
- display_collection_details(st.session_state.selected_collection)
275
-
276
- def show_collection_dialog():
277
- """Show dialog for creating/editing collections."""
278
- with st.sidebar:
279
- st.header("Collection Details")
280
-
281
- name = st.text_input("Collection Name")
282
- description = st.text_area("Description")
283
-
284
- col1, col2 = st.columns(2)
285
- with col1:
286
- if st.button("Save", type="primary"):
287
- if name:
288
- create_collection(
289
- st.session_state.db_conn,
290
- name,
291
- description
292
- )
293
- st.session_state.show_collection_dialog = False
294
- st.rerun()
295
- else:
296
- st.error("Please enter a collection name")
297
-
298
- with col2:
299
- if st.button("Cancel"):
300
- st.session_state.show_collection_dialog = False
301
- st.rerun()
302
-
303
- def display_collection_details(collection):
304
- """Display details and documents for a selected collection."""
305
- st.header(collection['name'])
306
- st.write(f"Created: {collection['created_at']}")
307
- st.write(f"Description: {collection.get('description', 'No description')}")
308
-
309
- # Documents in collection
310
- st.subheader("Documents")
311
- documents = get_collection_documents(st.session_state.db_conn, collection['id'])
312
-
313
- for doc in documents:
314
- with st.expander(f"📄 {doc['name']}", expanded=False):
315
- col1, col2 = st.columns([3, 1])
316
- with col1:
317
- st.write(f"Uploaded: {doc['upload_date']}")
318
- st.write(f"Size: {len(doc['content'])/1024:.1f} KB")
319
- with col2:
320
- st.button("Preview", key=f"preview_{doc['id']}",
321
- on_click=lambda: preview_document(doc))
322
- st.button("Remove", key=f"remove_{doc['id']}",
323
- on_click=lambda: remove_from_collection(doc['id'], collection['id']))
324
 
325
- def display_documents_tab():
326
- """Display all documents with metadata and collection management."""
327
- st.header("Document Library")
328
-
329
- # Upload section
330
- with st.expander("Upload New Documents", expanded=False):
331
- uploaded_files = st.file_uploader(
332
- "Upload PDF documents",
333
- type=['pdf'],
334
- accept_multiple_files=True,
335
- help="Limit 200MB per file • PDF"
336
- )
337
-
338
- if uploaded_files:
339
- st.subheader("Add to Collection")
340
- collections = get_collections(st.session_state.db_conn)
341
- collection_options = ["Create New Collection"] + [c['name'] for c in collections]
342
- selected_option = st.selectbox("Select Collection", collection_options)
343
-
344
- if selected_option == "Create New Collection":
345
- col1, col2 = st.columns([2, 1])
346
- with col1:
347
- new_collection_name = st.text_input("Collection Name")
348
- new_collection_desc = st.text_area("Description")
349
- with col2:
350
- if st.button("Create & Upload") and new_collection_name:
351
- collection_id = create_collection(
352
- st.session_state.db_conn,
353
- new_collection_name,
354
- new_collection_desc
355
- )
356
- if collection_id:
357
- handle_document_upload(uploaded_files, collection_id=collection_id)
358
- else:
359
- if st.button("Upload to Collection"):
360
- collection_id = next(
361
- c['id'] for c in collections if c['name'] == selected_option
362
- )
363
- handle_document_upload(uploaded_files, collection_id=collection_id)
364
-
365
- # Document list
366
- documents = get_all_documents(st.session_state.db_conn)
367
- for doc in documents:
368
- with st.expander(f"📄 {doc['name']}", expanded=False):
369
- col1, col2, col3 = st.columns([2, 1, 1])
370
-
371
- with col1:
372
- st.write("**Metadata:**")
373
- st.write(f"• Upload Date: {doc['upload_date']}")
374
- st.write(f"• Size: {len(doc['content'])/1024:.1f} KB")
375
- st.write(f"• Collections: {', '.join(doc['collections'])}")
376
-
377
- with col2:
378
- st.write("**Actions:**")
379
- st.button("Preview", key=f"doc_preview_{doc['id']}")
380
- collections = get_collections(st.session_state.db_conn)
381
- collection_options = [c['name'] for c in collections]
382
- selected_collection = st.selectbox(
383
- "Add to Collection",
384
- collection_options,
385
- key=f"add_to_col_{doc['id']}"
386
- )
387
- if st.button("Add", key=f"add_btn_{doc['id']}"):
388
- collection_id = next(
389
- c['id'] for c in collections if c['name'] == selected_collection
390
- )
391
- add_document_to_collection(
392
- st.session_state.db_conn,
393
- doc['id'],
394
- collection_id
395
- )
396
-
397
- with col3:
398
- st.write("**Preview:**")
399
- if st.button("Show Content", key=f"show_{doc['id']}"):
400
- st.text_area("Content Preview",
401
- doc['content'][:500] + "...",
402
- height=200)
403
-
404
- def display_chat_interface_with_sources():
405
- """Display chat interface with source references."""
406
  if not st.session_state.chat_ready:
407
  display_welcome_screen()
408
- return
409
-
410
- # Display chat history with sources
411
- for message in st.session_state.messages:
412
- if isinstance(message, HumanMessage):
413
- st.chat_message("user").write(message.content)
414
- elif isinstance(message, AIMessage):
415
- with st.chat_message("assistant"):
416
- st.write(message.content)
417
- if hasattr(message, 'metadata') and message.metadata.get('sources'):
418
- st.divider()
419
- st.caption("**Sources:**")
420
- for source in message.metadata['sources']:
421
- st.caption(f"• {source}")
422
-
423
- # Chat input
424
- if prompt := st.chat_input("Ask about your documents..."):
425
- with st.spinner("Analyzing..."):
426
- sources, response = get_response_with_sources(
427
- prompt,
428
- st.session_state.qa_system
429
- )
430
-
431
- # Add messages to history with metadata
432
- human_msg = HumanMessage(content=prompt)
433
- ai_msg = AIMessage(
434
- content=response,
435
- metadata={'sources': sources}
436
- )
437
-
438
- st.session_state.messages.extend([human_msg, ai_msg])
439
- st.rerun()
440
-
441
- def get_response_with_sources(prompt, qa_system):
442
- """Get response from QA system with source documents."""
443
- response = qa_system.invoke({
444
- "input": prompt,
445
- "chat_history": st.session_state.messages
446
- })
447
-
448
- # Extract sources from the chunks used
449
- sources = set()
450
- if hasattr(response, 'metadata'):
451
- for source in response.metadata.get('source_documents', []):
452
- sources.add(source.metadata.get('source', 'Unknown source'))
453
-
454
- return list(sources), response.content
455
-
456
- def display_documents_tab():
457
- """Enhanced documents tab with search and preview."""
458
- st.header("Document Library")
459
-
460
- # Search and filter section
461
- col1, col2, col3 = st.columns([2, 1, 1])
462
- with col1:
463
- search_query = st.text_input("🔍 Search documents")
464
- with col2:
465
- date_filter = st.date_input("Date Filter")
466
- with col3:
467
- sort_by = st.selectbox("Sort By", ["Name", "Date", "Size"])
468
-
469
- # Advanced filters
470
- with st.expander("Advanced Filters"):
471
- filter_cols = st.columns(3)
472
- with filter_cols[0]:
473
- collections_filter = st.multiselect(
474
- "Collections",
475
- options=[c['name'] for c in get_collections(st.session_state.db_conn)]
476
- )
477
- with filter_cols[1]:
478
- date_range = st.date_input("Date Range", value=())
479
- with filter_cols[2]:
480
- st.checkbox("Show only uncategorized")
481
-
482
- # Build filters dictionary
483
- filters = {
484
- 'collections': collections_filter,
485
- 'date_range': date_range if len(date_range) == 2 else None
486
- }
487
-
488
- # Get and display documents
489
- if search_query:
490
- documents = search_documents(
491
- st.session_state.db_conn,
492
- search_query,
493
- filters=filters
494
- )
495
- if documents:
496
- st.success(f"Found {len(documents)} matching documents")
497
- else:
498
- st.info("No documents found matching your search")
499
  else:
500
- documents = get_all_documents(st.session_state.db_conn)
501
-
502
- # Display documents
503
- for doc in documents:
504
- with st.expander(f"📄 {doc['name']}", expanded=False):
505
- enhanced_document_preview(doc)
506
 
507
  def main():
508
  st.set_page_config(
@@ -511,57 +240,25 @@ def main():
511
  initial_sidebar_state="expanded"
512
  )
513
 
514
- # Debug section to understand storage status
515
- with st.expander("Storage Debug Information", expanded=True):
516
- st.write("Current working directory:", os.getcwd())
517
- st.write("Contents of current directory:", os.listdir())
518
- if os.path.exists('/data'):
519
- st.write("Contents of /data:", os.listdir('/data'))
520
- else:
521
- st.write("/data directory not found")
522
-
523
- # Initialize storage
524
- base_path = initialize_storage_structure()
525
- if base_path:
526
- st.write("Storage base path:", str(base_path))
527
- if verify_storage_access(base_path):
528
- st.success("Storage system verified and ready!")
529
- else:
530
- st.error("Storage system verification failed!")
531
-
532
- # Store base_path in session state for other components to use
533
- if base_path:
534
- st.session_state['storage_path'] = base_path
535
-
536
- # Initialize database using verified storage path
537
  if not initialize_database():
538
  st.error("Failed to initialize database. Please check storage system.")
539
  return
540
-
541
- if not initialize_database():
542
- st.error("Failed to initialize database. Please contact support.")
543
- return
544
 
545
  initialize_session_state()
546
- display_top_bar()
547
-
548
- # Main tabs
549
- tab1, tab2, tab3 = st.tabs(["Chat", "Collections", "Documents"])
550
 
551
- with tab1:
552
- display_chat_interface_with_sources()
553
-
554
- with tab2:
555
- display_enhanced_collections()
556
-
557
- with tab3:
558
- display_documents_tab()
559
 
560
- # Handle collection dialog if needed
561
- if st.session_state.get('show_collection_dialog'):
562
- show_collection_dialog()
563
 
 
 
 
564
 
 
 
565
 
566
  if __name__ == "__main__":
567
- main()
 
 
1
  # app.py
2
+
3
  import streamlit as st
4
  import os
5
  from pathlib import Path
6
  from typing import Dict, List, Optional, Any
7
  from datetime import datetime
8
  from threading import Lock
 
 
 
 
 
 
 
 
 
9
 
10
  from utils.database import (
11
  # Base database operations
 
27
 
28
  from components.chat import display_chat_interface
29
 
 
 
 
 
 
 
 
 
 
 
 
30
  # Create locks for thread-safe operations
31
  conn_lock = Lock()
 
32
 
33
  def initialize_database():
34
  """Initialize database with persistent storage."""
 
192
  st.session_state.show_collection_dialog = False
193
  st.rerun()
194
 
195
+ def display_welcome_screen():
196
+ """Display the welcome screen with getting started information."""
197
+ st.title("🤖 Welcome to SYNAPTYX")
198
+ st.markdown("### Your AI-powered RFP Analysis Assistant")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
+ col1, col2 = st.columns(2)
201
  with col1:
202
+ st.markdown("""
203
+ #### Getting Started:
204
+ 1. Upload your RFP documents using the sidebar
205
+ 2. Organize documents into collections
206
+ 3. Start analyzing with AI!
207
 
208
+ You can:
209
+ - Create multiple collections
210
+ - Upload documents to specific collections
211
+ - Search across all documents
212
+ - Get AI-powered insights and summaries
213
+ """)
 
 
 
 
 
214
 
215
  with col2:
216
+ st.markdown("#### Example Questions:")
217
+ examples = [
218
+ "📊 Summarize the main points of the document",
219
+ "📝 Draft a 'Why Us' section based on the document",
220
+ "🎯 Extract key success metrics and outcomes",
221
+ "💡 What are the innovative solutions mentioned?",
222
+ "🤝 Analyze the partnership benefits described",
223
+ "📈 Compare requirements across documents",
224
+ "🔍 Find similar sections across RFPs"
225
+ ]
226
+ for example in examples:
227
+ st.markdown(f"• {example}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
 
229
+ def display_chat_area():
230
+ """Display the main chat interface or welcome screen."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  if not st.session_state.chat_ready:
232
  display_welcome_screen()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  else:
234
+ display_chat_interface()
 
 
 
 
 
235
 
236
  def main():
237
  st.set_page_config(
 
240
  initial_sidebar_state="expanded"
241
  )
242
 
243
+ # Initialize database and session state
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  if not initialize_database():
245
  st.error("Failed to initialize database. Please check storage system.")
246
  return
 
 
 
 
247
 
248
  initialize_session_state()
 
 
 
 
249
 
250
+ # Display the top navigation bar
251
+ display_top_bar()
 
 
 
 
 
 
252
 
253
+ # Display the collection sidebar
254
+ display_collection_sidebar()
 
255
 
256
+ # Show collection creation dialog if triggered
257
+ if st.session_state.get('show_collection_dialog', False):
258
+ display_collection_dialog()
259
 
260
+ # Display chat area
261
+ display_chat_area()
262
 
263
  if __name__ == "__main__":
264
+ main()