cryogenic22 commited on
Commit
5f439e5
Β·
verified Β·
1 Parent(s): febd5df

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +238 -155
app.py CHANGED
@@ -1,179 +1,262 @@
1
  import streamlit as st
2
  import backend
3
  from langchain.schema import HumanMessage, AIMessage
 
 
4
 
5
- # Streamlit App Interface
6
- def main():
7
- st.title("**SYNAPTYX - RFP Analysis Agent**")
8
- st.markdown(
9
- "<h3 style='color: #1E3A8A;'>Upload RFP documents, provide a URL, search, and get intelligent answers.</h3>",
10
- unsafe_allow_html=True,
11
- )
 
 
 
 
 
12
 
13
- # Database Initialization
14
- database = "rfp_agent.db"
15
- conn = backend.create_connection(database)
16
- if conn is not None:
17
- backend.create_tables(conn) # Use backend.create_tables(conn)
18
- else:
19
- st.error("Error! Cannot create the database connection.")
20
-
21
- # Dashboard Overview Tab
22
- st.sidebar.markdown(
23
- "<h2 style='color: #1E3A8A;'>Dashboard Overview</h2>",
24
- unsafe_allow_html=True,
 
 
 
 
 
 
25
  )
26
- if conn is not None:
 
 
 
 
27
  try:
28
- cursor = conn.cursor()
29
- cursor.execute("SELECT COUNT(*) FROM documents")
30
- total_documents = cursor.fetchone()[0]
31
-
32
- cursor.execute("SELECT COUNT(*) FROM queries")
33
- total_queries = cursor.fetchone()[0]
34
-
35
- st.sidebar.write(f"Total Documents: {total_documents}")
36
- st.sidebar.write(f"Total Queries: {total_queries}")
 
 
 
37
  except Exception as e:
38
- st.error(f"Error retrieving dashboard data: {e}")
39
 
40
- # Sidebar Knowledge Base Tab
41
- st.sidebar.markdown(
42
- "<h2 style='color: #1E3A8A;'>Knowledge Base</h2>", unsafe_allow_html=True
43
- )
44
- st.sidebar.markdown(
45
- "<p style='color: #1E3A8A;'>View and select documents for search.</p>",
46
- unsafe_allow_html=True,
47
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
- # Retrieve Documents from Database
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  if conn is not None:
51
  try:
52
  cursor = conn.cursor()
53
- cursor.execute("SELECT id, name FROM documents")
54
  documents_in_db = cursor.fetchall()
55
-
56
  if documents_in_db:
57
- # Use st.multiselect instead of st.selectbox
58
- selected_doc_ids = st.sidebar.multiselect(
59
- "Select documents to include in the search:",
60
- options=[doc[0] for doc in documents_in_db],
61
- format_func=lambda doc_id: next(
62
- doc[1] for doc in documents_in_db if doc[0] == doc_id
63
- ),
64
- default=[
65
- doc[0] for doc in documents_in_db
66
- ], # Select all documents by default
67
- )
68
-
69
- if selected_doc_ids:
70
- selected_documents = []
71
- selected_doc_names = [] # Also keep track of the document names
72
- for doc_id in selected_doc_ids:
73
- cursor.execute(
74
- "SELECT content, name FROM documents WHERE id = ?",
75
- (doc_id,),
76
- )
77
- result = cursor.fetchone()
78
- selected_documents.append(result[0])
79
- selected_doc_names.append(result[1]) # Add the name to the list
80
-
81
- # Initialize FAISS and Store Embeddings for Selected Documents
82
- embeddings = backend.get_embeddings_model()
83
- if embeddings:
84
- st.sidebar.write(
85
- "Creating embeddings..."
86
- ) # Indicate embedding creation
87
- vector_store = backend.initialize_faiss(
88
- embeddings,
89
- selected_documents,
90
- selected_doc_names,
91
- ) # Use selected_doc_names here
92
- if vector_store:
93
- st.sidebar.success(
94
- "Embeddings for selected documents stored successfully.",
95
- icon="πŸ“",
96
  )
97
-
98
- # Initialize QA System for Selected Documents
99
- qa_system = backend.initialize_qa_system(
100
- vector_store
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  )
102
- if qa_system:
103
- chat_history = [] # Initialize chat history
104
- user_query = st.text_input(
105
- "Enter your query about the RFPs:",
106
- placeholder="e.g., What are the evaluation criteria?",
107
- label_visibility="visible",
108
- )
109
- if user_query:
110
- st.markdown(
111
- "<p style='color: #1E3A8A;'>Retrieving answer...</p>",
112
- unsafe_allow_html=True,
113
- )
114
- try:
115
- # Add user message to chat history
116
- chat_history.append(
117
- HumanMessage(content=user_query)
118
- )
119
-
120
- # Use agent_executor.invoke() to run the agent with chat history
121
- response = qa_system.invoke(
122
- {
123
- "input": user_query,
124
- "chat_history": chat_history,
125
- }
126
- )
127
-
128
- # Add AI message to chat history
129
- chat_history.append(
130
- AIMessage(content=response["output"])
131
- )
132
-
133
- st.markdown(
134
- "<h4 style='color: #1E3A8A;'>Answer:</h4>",
135
- unsafe_allow_html=True,
136
- )
137
- st.write(
138
- response["output"]
139
- ) # Access the answer text
140
-
141
- except Exception as e:
142
- st.error(f"Error generating response: {e}")
143
  except Exception as e:
144
- st.error(f"Error retrieving documents from database: {e}")
145
 
146
- # Document Upload Section
147
- st.markdown(
148
- "<h2 style='color: #1E3A8A;'>Upload RFP Documents</h2>",
149
- unsafe_allow_html=True,
 
 
150
  )
151
- uploaded_documents = st.file_uploader(
152
- "Upload PDF documents", type="pdf", accept_multiple_files=True
 
 
 
 
 
 
 
 
 
 
 
153
  )
154
- if uploaded_documents:
155
- st.write(f"Uploaded {len(uploaded_documents)} documents.")
156
- (
157
- all_texts,
158
- document_names,
159
- document_pages,
160
- ) = backend.upload_and_parse_documents(uploaded_documents)
161
- if all_texts:
162
- # Store Documents in Database
163
- if conn is not None:
164
- try:
165
- with conn:
166
- for doc, doc_name in zip(all_texts, document_names):
167
- conn.execute(
168
- "INSERT INTO documents (name, content) VALUES (?, ?)",
169
- (doc_name, doc),
170
- )
171
- st.success(
172
- "Documents uploaded and parsed successfully.", icon="βœ…"
173
- )
174
- except Exception as e:
175
- st.error(f"Error saving documents to database: {e}")
176
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
  if __name__ == "__main__":
179
  main()
 
1
  import streamlit as st
2
  import backend
3
  from langchain.schema import HumanMessage, AIMessage
4
+ import time
5
+ from datetime import datetime
6
 
7
+ def initialize_session_state():
8
+ """Initialize session state variables"""
9
+ if 'chat_history' not in st.session_state:
10
+ st.session_state.chat_history = []
11
+ if 'current_chat' not in st.session_state:
12
+ st.session_state.current_chat = False
13
+ if 'selected_docs' not in st.session_state:
14
+ st.session_state.selected_docs = []
15
+ if 'qa_system' not in st.session_state:
16
+ st.session_state.qa_system = None
17
+ if 'documents_initialized' not in st.session_state:
18
+ st.session_state.documents_initialized = False
19
 
20
+ def display_chat_interface():
21
+ """Display the chat interface"""
22
+ st.markdown("### πŸ’¬ RFP Analysis Chat")
23
+
24
+ # Display chat history
25
+ chat_container = st.container()
26
+ with chat_container:
27
+ for message in st.session_state.chat_history:
28
+ if isinstance(message, HumanMessage):
29
+ st.markdown(f"πŸ§‘β€πŸ’Ό **You**: {message.content}")
30
+ else:
31
+ st.markdown(f"πŸ€– **Assistant**: {message.content}")
32
+
33
+ # Chat input
34
+ user_query = st.text_input(
35
+ "Ask about the RFPs:",
36
+ placeholder="e.g., What are the key requirements?",
37
+ key="chat_input"
38
  )
39
+
40
+ if user_query:
41
+ # Add user message to chat history
42
+ st.session_state.chat_history.append(HumanMessage(content=user_query))
43
+
44
  try:
45
+ with st.spinner("Analyzing documents..."):
46
+ response = st.session_state.qa_system.invoke({
47
+ "input": user_query,
48
+ "chat_history": st.session_state.chat_history
49
+ })
50
+
51
+ # Add AI message to chat history
52
+ st.session_state.chat_history.append(AIMessage(content=response["output"]))
53
+
54
+ # Force refresh to show new messages
55
+ st.experimental_rerun()
56
+
57
  except Exception as e:
58
+ st.error(f"Error generating response: {e}")
59
 
60
+ def display_document_stats(conn):
61
+ """Display document statistics"""
62
+ try:
63
+ cursor = conn.cursor()
64
+ cursor.execute("SELECT COUNT(*) FROM documents")
65
+ total_documents = cursor.fetchone()[0]
66
+
67
+ cursor.execute("SELECT COUNT(*) FROM queries")
68
+ total_queries = cursor.fetchone()[0]
69
+
70
+ cursor.execute("SELECT COUNT(*) FROM annotations")
71
+ total_annotations = cursor.fetchone()[0]
72
+
73
+ # Create three columns for metrics
74
+ col1, col2, col3 = st.columns(3)
75
+
76
+ with col1:
77
+ st.metric("πŸ“š Documents", total_documents)
78
+ with col2:
79
+ st.metric("❓ Queries", total_queries)
80
+ with col3:
81
+ st.metric("πŸ“ Annotations", total_annotations)
82
+
83
+ except Exception as e:
84
+ st.error(f"Error retrieving statistics: {e}")
85
 
86
+ def handle_document_upload(conn, uploaded_documents):
87
+ """Handle document upload process"""
88
+ if uploaded_documents:
89
+ with st.spinner(f"Processing {len(uploaded_documents)} documents..."):
90
+ all_texts, document_names, document_pages = backend.upload_and_parse_documents(uploaded_documents)
91
+
92
+ if all_texts:
93
+ try:
94
+ with conn:
95
+ for doc, doc_name in zip(all_texts, document_names):
96
+ conn.execute(
97
+ "INSERT INTO documents (name, content) VALUES (?, ?)",
98
+ (doc_name, doc)
99
+ )
100
+ st.success(f"Successfully uploaded {len(uploaded_documents)} documents!", icon="βœ…")
101
+ time.sleep(1) # Give users time to see the success message
102
+ st.experimental_rerun() # Refresh the page to update the knowledge base
103
+ except Exception as e:
104
+ st.error(f"Error saving documents to database: {e}")
105
+
106
+ def display_knowledge_base(conn):
107
+ """Display and manage knowledge base"""
108
+ st.markdown("### πŸ“š Knowledge Base")
109
+
110
  if conn is not None:
111
  try:
112
  cursor = conn.cursor()
113
+ cursor.execute("SELECT id, name, upload_date FROM documents ORDER BY upload_date DESC")
114
  documents_in_db = cursor.fetchall()
115
+
116
  if documents_in_db:
117
+ st.markdown("#### Available Documents")
118
+
119
+ # Create a container for the document list
120
+ doc_container = st.container()
121
+ with doc_container:
122
+ for doc_id, name, upload_date in documents_in_db:
123
+ col1, col2, col3 = st.columns([3, 2, 1])
124
+
125
+ # Document name and checkbox
126
+ with col1:
127
+ selected = st.checkbox(
128
+ name,
129
+ value=doc_id in st.session_state.selected_docs,
130
+ key=f"doc_{doc_id}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  )
132
+ if selected and doc_id not in st.session_state.selected_docs:
133
+ st.session_state.selected_docs.append(doc_id)
134
+ elif not selected and doc_id in st.session_state.selected_docs:
135
+ st.session_state.selected_docs.remove(doc_id)
136
+
137
+ # Upload date
138
+ with col2:
139
+ upload_date = datetime.strptime(upload_date, '%Y-%m-%d %H:%M:%S')
140
+ st.text(upload_date.strftime('%Y-%m-%d %H:%M'))
141
+
142
+ # Document actions
143
+ with col3:
144
+ st.button("πŸ“", key=f"annotate_{doc_id}", help="Add annotations")
145
+
146
+ # Initialize selected documents
147
+ if st.session_state.selected_docs and not st.session_state.documents_initialized:
148
+ with st.spinner("Initializing document analysis..."):
149
+ selected_documents = []
150
+ selected_doc_names = []
151
+
152
+ for doc_id in st.session_state.selected_docs:
153
+ cursor.execute(
154
+ "SELECT content, name FROM documents WHERE id = ?",
155
+ (doc_id,)
156
  )
157
+ result = cursor.fetchone()
158
+ selected_documents.append(result[0])
159
+ selected_doc_names.append(result[1])
160
+
161
+ # Initialize FAISS and QA system
162
+ embeddings = backend.get_embeddings_model()
163
+ if embeddings:
164
+ vector_store = backend.initialize_faiss(
165
+ embeddings,
166
+ selected_documents,
167
+ selected_doc_names
168
+ )
169
+ if vector_store:
170
+ st.session_state.qa_system = backend.initialize_qa_system(vector_store)
171
+ st.session_state.documents_initialized = True
172
+ st.success("Documents initialized successfully!")
173
+
174
+ # Start Chat button
175
+ if st.session_state.selected_docs:
176
+ if st.button("πŸš€ Start New Chat", use_container_width=True):
177
+ st.session_state.current_chat = True
178
+ st.session_state.chat_history = []
179
+ st.experimental_rerun()
180
+ else:
181
+ st.info("No documents in the knowledge base. Upload some documents to get started!")
182
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  except Exception as e:
184
+ st.error(f"Error accessing knowledge base: {e}")
185
 
186
+ def main():
187
+ # Page configuration
188
+ st.set_page_config(
189
+ page_title="SYNAPTYX - RFP Analysis Agent",
190
+ page_icon="πŸ€–",
191
+ layout="wide"
192
  )
193
+
194
+ # Initialize session state
195
+ initialize_session_state()
196
+
197
+ # Main title and description
198
+ st.title("πŸ€– SYNAPTYX - RFP Analysis Agent")
199
+ st.markdown(
200
+ """
201
+ <p style='color: #1E3A8A;'>
202
+ Upload RFP documents, analyze requirements, and get intelligent answers powered by AI.
203
+ </p>
204
+ """,
205
+ unsafe_allow_html=True
206
  )
207
+
208
+ # Database initialization
209
+ database = "rfp_agent.db"
210
+ conn = backend.create_connection(database)
211
+ if conn is not None:
212
+ backend.create_tables(conn)
213
+ else:
214
+ st.error("Error! Cannot create the database connection.")
215
+ return
216
+
217
+ # Create two columns for layout
218
+ col1, col2 = st.columns([1, 2])
219
+
220
+ with col1:
221
+ # Document upload section
222
+ st.markdown("### πŸ“€ Upload Documents")
223
+ uploaded_documents = st.file_uploader(
224
+ "Upload PDF documents",
225
+ type="pdf",
226
+ accept_multiple_files=True,
227
+ help="Select one or more PDF files to upload"
228
+ )
229
+ handle_document_upload(conn, uploaded_documents)
230
+
231
+ # Display document statistics
232
+ st.markdown("### πŸ“Š Statistics")
233
+ display_document_stats(conn)
234
+
235
+ # Knowledge base management
236
+ display_knowledge_base(conn)
237
+
238
+ with col2:
239
+ # Chat interface
240
+ if st.session_state.current_chat and st.session_state.qa_system:
241
+ display_chat_interface()
242
+ else:
243
+ st.markdown(
244
+ """
245
+ ### πŸ‘‹ Welcome to SYNAPTYX!
246
+
247
+ To get started:
248
+ 1. Upload your RFP documents using the upload section
249
+ 2. Select the documents you want to analyze from the knowledge base
250
+ 3. Click "Start New Chat" to begin asking questions
251
+
252
+ Features:
253
+ - πŸ“š Document Management
254
+ - πŸ’¬ Intelligent Chat Interface
255
+ - πŸ“ Document Annotations
256
+ - πŸ“Š Analytics Dashboard
257
+ - πŸ” Advanced Search Capabilities
258
+ """
259
+ )
260
 
261
  if __name__ == "__main__":
262
  main()