cryogenic22 commited on
Commit
3ad6907
·
verified ·
1 Parent(s): 311a114

Update components/chat.py

Browse files
Files changed (1) hide show
  1. components/chat.py +161 -122
components/chat.py CHANGED
@@ -2,71 +2,75 @@ import streamlit as st
2
  from langchain_core.messages import HumanMessage, AIMessage
3
  from utils.database import verify_vector_store
4
 
5
- def format_assistant_response(content):
6
- """Format the assistant's response into a structured layout."""
7
- # Clean up the content first
8
  content = str(content)
9
 
10
- # Remove metadata and extra markers
11
  if "content='" in content:
12
- content = content.split("content='")[1].split("additional_kwargs")[0].strip("'")
13
-
14
- # Split into sections
15
- sections = {}
16
- current_section = "default"
17
- lines = content.replace('\\n', '\n').split('\n')
18
 
19
- for line in lines:
20
- line = line.strip()
21
- if not line:
22
- continue
23
-
24
- if line.startswith('**') and line.endswith('**'):
25
- current_section = line.strip('**')
26
- sections[current_section] = []
27
- elif line.startswith('*') or line.startswith('#'):
28
- current_section = "main"
29
- if current_section not in sections:
30
- sections[current_section] = []
31
- sections[current_section].append(line.strip('* '))
32
- else:
33
- if current_section not in sections:
34
- sections[current_section] = []
35
- sections[current_section].append(line)
36
 
37
- # Build formatted HTML
38
- formatted_html = """
39
- <div class="response-container">
40
- <div class="summary-section">
41
- <h4>Executive Summary</h4>
42
- <p>{}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  </div>
44
- """.format(' '.join(sections.get('Executive Summary', sections.get('default', ['']))))
45
-
46
- # Add key themes section
47
- if 'Key Themes' in sections:
48
- formatted_html += """
49
- <div class="themes-section">
50
- <h4>Key Themes</h4>
51
- <ul>
52
  """
53
- for theme in sections['Key Themes']:
54
- if theme.strip():
55
- formatted_html += f'<li class="theme-item">{theme}</li>'
56
- formatted_html += '</ul></div>'
57
-
58
- # Add any remaining sections
59
- for section, content in sections.items():
60
- if section not in ['Executive Summary', 'Key Themes', 'default']:
61
- formatted_html += f"""
62
- <div class="content-section">
63
- <h4>{section}</h4>
64
- <p>{'<br>'.join(content)}</p>
65
- </div>
66
- """
67
-
68
- formatted_html += '</div>'
69
- return formatted_html
70
 
71
  def display_chat_interface():
72
  """Display modern chat interface with clean formatting."""
@@ -74,103 +78,138 @@ def display_chat_interface():
74
  # Add custom CSS for modern chat styling
75
  st.markdown("""
76
  <style>
77
- .response-container {
78
- background-color: white;
 
 
 
 
 
 
 
 
79
  border-radius: 10px;
80
- padding: 20px;
81
- margin: 10px 0;
82
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
83
  }
84
 
85
- .summary-section {
86
- background-color: #f8f9fa;
87
- padding: 15px;
88
- border-radius: 8px;
89
- margin-bottom: 20px;
 
 
 
90
  }
91
 
92
- .themes-section {
93
- margin: 20px 0;
 
94
  }
95
 
96
- .theme-item {
97
- margin: 10px 0;
98
- padding: 5px 0;
99
- line-height: 1.5;
 
 
 
 
100
  }
101
 
102
- .content-section {
103
- margin: 15px 0;
104
- padding: 10px;
105
- border-left: 3px solid #0f52ba;
 
106
  }
107
 
108
- .content-section h4 {
 
 
 
 
 
 
 
 
 
109
  color: #0f52ba;
110
- margin-bottom: 10px;
111
  }
112
 
113
- .user-message {
114
- background-color: #f0f2f6;
115
- padding: 1rem;
116
- border-radius: 10px;
117
  margin: 1rem 0;
 
118
  }
119
 
120
- .assistant-message {
121
- background-color: #ffffff;
122
- border: 1px solid #e0e0e0;
123
- border-radius: 10px;
124
- margin: 1rem 0;
 
 
 
125
  }
126
  </style>
127
  """, unsafe_allow_html=True)
128
 
129
- # Check if QA system is initialized
130
- if 'qa_system' not in st.session_state or st.session_state.qa_system is None:
131
- st.warning("Please upload documents first to initialize the chat system.")
132
- return
133
-
134
- # Initialize chat history
135
- if 'messages' not in st.session_state:
136
- st.session_state.messages = []
137
-
138
- # Display chat history
139
- for message in st.session_state.messages:
140
- if isinstance(message, HumanMessage):
141
- st.markdown(f"""
142
- <div class="user-message">
143
- 🧑‍💼 <strong>You:</strong><br>{message.content}
144
- </div>
145
- """, unsafe_allow_html=True)
146
- elif isinstance(message, AIMessage):
147
- st.markdown(f"""
148
- <div class="assistant-message">
149
- 🤖 <strong>Assistant:</strong>
150
- {format_assistant_response(message.content)}
151
- </div>
152
- """, unsafe_allow_html=True)
153
-
154
- # Chat input at the bottom
155
- if prompt := st.chat_input("Ask about your documents..."):
156
- try:
157
  with st.spinner("Analyzing..."):
 
 
 
 
 
 
158
  human_message = HumanMessage(content=prompt)
159
  st.session_state.messages.append(human_message)
160
 
 
161
  response = st.session_state.qa_system.invoke({
162
  "input": prompt,
163
  "chat_history": st.session_state.messages
164
  })
165
 
 
166
  if response:
167
  ai_message = AIMessage(content=str(response))
168
  st.session_state.messages.append(ai_message)
169
  st.rerun()
170
  else:
171
- st.error("No valid response received")
172
 
173
- except Exception as e:
174
- st.error(f"Error: {e}")
175
- import traceback
176
- st.error(traceback.format_exc())
 
 
2
  from langchain_core.messages import HumanMessage, AIMessage
3
  from utils.database import verify_vector_store
4
 
5
+ def clean_ai_response(content):
6
+ """Clean up AI response content and remove technical artifacts."""
 
7
  content = str(content)
8
 
9
+ # Remove common technical artifacts
10
  if "content='" in content:
11
+ content = content.split("content='")[1]
12
+ if "additional_kwargs" in content:
13
+ content = content.split("additional_kwargs")[0]
 
 
 
14
 
15
+ # Clean up any remaining artifacts
16
+ content = content.strip("'")
17
+ content = content.replace('\\n', '\n')
18
+ content = content.replace('\\t', '\t')
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ return content
21
+
22
+ def format_assistant_response(content):
23
+ """Format the assistant's response into a structured layout."""
24
+ try:
25
+ # Clean the content first
26
+ content = clean_ai_response(content)
27
+
28
+ # Identify sections and structure
29
+ lines = [line.strip() for line in content.split('\n') if line.strip()]
30
+ formatted_sections = []
31
+ current_section = []
32
+
33
+ for line in lines:
34
+ # Handle bullet points and lists
35
+ if line.startswith(('•', '-', '*')):
36
+ line = f"<li>{line.lstrip('•-* ')}</li>"
37
+ if not current_section:
38
+ current_section.append("<ul>")
39
+ current_section.append(line)
40
+ # Handle section headers
41
+ elif line.startswith('**') and line.endswith('**'):
42
+ if current_section:
43
+ if current_section[0] == "<ul>":
44
+ current_section.append("</ul>")
45
+ formatted_sections.extend(current_section)
46
+ current_section = []
47
+ header = line.strip('**')
48
+ formatted_sections.append(f'<h4 class="section-header">{header}</h4>')
49
+ # Regular text
50
+ else:
51
+ if current_section and current_section[0] == "<ul>":
52
+ current_section.append("</ul>")
53
+ formatted_sections.extend(current_section)
54
+ current_section = []
55
+ formatted_sections.append(f'<p>{line}</p>')
56
+
57
+ # Add any remaining content
58
+ if current_section:
59
+ if current_section[0] == "<ul>":
60
+ current_section.append("</ul>")
61
+ formatted_sections.extend(current_section)
62
+
63
+ # Build the final HTML
64
+ formatted_html = f"""
65
+ <div class="response-content">
66
+ {''.join(formatted_sections)}
67
  </div>
 
 
 
 
 
 
 
 
68
  """
69
+
70
+ return formatted_html
71
+ except Exception as e:
72
+ st.error(f"Error formatting response: {str(e)}")
73
+ return str(content) # Return raw content if formatting fails
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  def display_chat_interface():
76
  """Display modern chat interface with clean formatting."""
 
78
  # Add custom CSS for modern chat styling
79
  st.markdown("""
80
  <style>
81
+ /* Chat container */
82
+ .chat-container {
83
+ max-width: 800px;
84
+ margin: auto;
85
+ }
86
+
87
+ /* User message */
88
+ .user-message {
89
+ background-color: #f0f2f6;
90
+ padding: 1rem;
91
  border-radius: 10px;
92
+ margin: 1rem 0;
93
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
 
94
  }
95
 
96
+ /* Assistant message */
97
+ .assistant-message {
98
+ background-color: #ffffff;
99
+ border: 1px solid #e0e0e0;
100
+ padding: 1.5rem;
101
+ border-radius: 10px;
102
+ margin: 1rem 0;
103
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
104
  }
105
 
106
+ /* Response content */
107
+ .response-content {
108
+ line-height: 1.6;
109
  }
110
 
111
+ /* Section headers */
112
+ .section-header {
113
+ color: #0f52ba;
114
+ margin: 1.5rem 0 1rem 0;
115
+ font-size: 1.1rem;
116
+ font-weight: 600;
117
+ border-bottom: 2px solid #e0e0e0;
118
+ padding-bottom: 0.5rem;
119
  }
120
 
121
+ /* Lists */
122
+ .response-content ul {
123
+ margin: 1rem 0;
124
+ padding-left: 1.5rem;
125
+ list-style-type: none;
126
  }
127
 
128
+ .response-content li {
129
+ margin: 0.5rem 0;
130
+ position: relative;
131
+ padding-left: 1rem;
132
+ }
133
+
134
+ .response-content li:before {
135
+ content: "•";
136
+ position: absolute;
137
+ left: -1rem;
138
  color: #0f52ba;
 
139
  }
140
 
141
+ /* Paragraphs */
142
+ .response-content p {
 
 
143
  margin: 1rem 0;
144
+ color: #2c3e50;
145
  }
146
 
147
+ /* Source citations */
148
+ .source-citation {
149
+ font-style: italic;
150
+ color: #666;
151
+ border-top: 1px solid #e0e0e0;
152
+ margin-top: 1rem;
153
+ padding-top: 0.5rem;
154
+ font-size: 0.9rem;
155
  }
156
  </style>
157
  """, unsafe_allow_html=True)
158
 
159
+ try:
160
+ # Check if QA system is initialized
161
+ if 'qa_system' not in st.session_state or st.session_state.qa_system is None:
162
+ st.warning("Please upload documents first to initialize the chat system.")
163
+ return
164
+
165
+ # Initialize chat history
166
+ if 'messages' not in st.session_state:
167
+ st.session_state.messages = []
168
+
169
+ # Display chat history
170
+ for message in st.session_state.messages:
171
+ if isinstance(message, HumanMessage):
172
+ st.markdown(f"""
173
+ <div class="user-message">
174
+ 🧑‍💼 <strong>You:</strong><br>{message.content}
175
+ </div>
176
+ """, unsafe_allow_html=True)
177
+ elif isinstance(message, AIMessage):
178
+ st.markdown(f"""
179
+ <div class="assistant-message">
180
+ 🤖 <strong>Assistant:</strong>
181
+ {format_assistant_response(message.content)}
182
+ </div>
183
+ """, unsafe_allow_html=True)
184
+
185
+ # Chat input
186
+ if prompt := st.chat_input("Ask about your documents..."):
187
  with st.spinner("Analyzing..."):
188
+ # Validate input
189
+ if not prompt.strip():
190
+ st.warning("Please enter a valid question.")
191
+ return
192
+
193
+ # Create and append human message
194
  human_message = HumanMessage(content=prompt)
195
  st.session_state.messages.append(human_message)
196
 
197
+ # Get response from QA system
198
  response = st.session_state.qa_system.invoke({
199
  "input": prompt,
200
  "chat_history": st.session_state.messages
201
  })
202
 
203
+ # Handle response
204
  if response:
205
  ai_message = AIMessage(content=str(response))
206
  st.session_state.messages.append(ai_message)
207
  st.rerun()
208
  else:
209
+ st.error("No valid response received. Please try again.")
210
 
211
+ except Exception as e:
212
+ st.error("An error occurred during chat processing.")
213
+ st.error(f"Error details: {str(e)}")
214
+ import traceback
215
+ st.error(traceback.format_exc())