uumerrr684 commited on
Commit
e351eb9
Β·
verified Β·
1 Parent(s): 16f9a56

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +539 -56
app.py CHANGED
@@ -146,17 +146,162 @@ USERS_FILE = "online_users.json"
146
 
147
  # ================= PERSONALITY QUESTIONS =================
148
 
149
- PERSONALITY_QUESTIONS = [
150
- "What do you know about [name]?",
151
- "How would you describe [name]'s personality?",
152
- "Is [name] introvert or extrovert?",
153
- "What do you think are [name]'s strengths?",
154
- "Does [name] have any weaknesses?",
155
- "What advice would you give [name]?",
156
- "What is something you admire about [name]?",
157
- "Do you remember anything about [name]'s friends or ambitions?",
158
- "What words describe [name] best?"
159
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
  # ================= GITHUB INTEGRATION =================
162
 
@@ -758,59 +903,397 @@ def start_new_chat():
758
  st.session_state.messages = []
759
  st.session_state.session_id = str(uuid.uuid4())
760
 
761
- def process_chat_message(prompt, rag_system, use_ai_enhancement, unlimited_tokens, show_sources, show_confidence):
762
- """Process a chat message and return the assistant message"""
763
- # Update user tracking
764
- update_online_users()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765
 
766
- # Get RAG response
767
- if rag_system and rag_system.model and rag_system.get_collection_count() > 0:
768
- # Search documents first
769
- search_results = rag_system.search(prompt, n_results=5)
 
 
 
 
 
 
 
 
 
 
 
 
770
 
771
- # Debug output for troubleshooting
772
- if search_results:
773
- st.info(f"πŸ” Found {len(search_results)} potential matches. Best similarity: {search_results[0]['similarity']:.3f}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
  else:
775
- st.warning("πŸ” No search results returned from vector database")
776
-
777
- # Check if we found relevant documents (very low threshold)
778
- if search_results and search_results[0]['similarity'] > 0.001: # Ultra-low threshold
779
- # Generate document-based answer
780
- result = rag_system.generate_answer(
781
- prompt,
782
- search_results,
783
- use_ai_enhancement=use_ai_enhancement,
784
- unlimited_tokens=unlimited_tokens
785
- )
786
-
787
- # Display AI answer or extracted answer
788
- if use_ai_enhancement and result['has_both']:
789
- answer_text = result['ai_answer']
790
- st.markdown(f"πŸ€– **AI Enhanced Answer:** {answer_text}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
791
 
792
- # Also show extracted answer for comparison if different
793
- if result['extracted_answer'] != answer_text:
794
- with st.expander("πŸ“„ View Extracted Answer"):
795
- st.markdown(result['extracted_answer'])
796
- else:
797
- answer_text = result['extracted_answer']
798
- st.markdown(f"πŸ“„ **Document Answer:** {answer_text}")
799
 
800
- # Show why AI enhancement wasn't used
801
- if use_ai_enhancement and not result['has_both']:
802
- st.info("πŸ’‘ AI enhancement failed - showing extracted answer from documents")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
803
 
804
- # Show RAG info with more details
805
- if show_sources and result['sources']:
806
- confidence_text = f"{result['confidence']*100:.1f}%" if show_confidence else ""
 
 
807
  st.markdown(f"""
808
  <div class="rag-attribution">
809
- <strong>πŸ“ Sources:</strong> {', '.join(result['sources'])}<br>
810
- <strong>🎯 Confidence:</strong> {confidence_text}<br>
811
- <strong>πŸ“Š Found:</strong> {len(search_results)} relevant sections<br>
812
- <strong>πŸ” Best Match:</strong> {search_results[0]['similarity']:.3f} similarity
813
  </div>
814
  """, unsafe_allow_html=True)
815
 
816
- #
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
  # ================= PERSONALITY QUESTIONS =================
148
 
149
+ # Replace the personality questions section (around line 760-780) with this fixed version:
150
+
151
+ # Personality Questions Section
152
+ st.header("🎭 Personality Questions")
153
+
154
+ # Name input for personalizing questions
155
+ name_input = st.text_input("Enter name for personalized questions:", placeholder="e.g., Sarah, Ahmed", help="Replace [name] in questions with this name")
156
+
157
+ if name_input.strip():
158
+ name = name_input.strip()
159
+ st.markdown(f"""
160
+ <div class="personality-section">
161
+ <strong>πŸ’« Quick Questions for {name}:</strong><br>
162
+ <small>Click any question to ask about {name}</small>
163
+ </div>
164
+ """, unsafe_allow_html=True)
165
+
166
+ # Display personality questions as clickable buttons
167
+ for i, question in enumerate(PERSONALITY_QUESTIONS):
168
+ formatted_question = question.replace("[name]", name)
169
+ if st.button(formatted_question, key=f"pq_{i}", use_container_width=True):
170
+ # Add the question to chat and set flag to process it
171
+ user_message = {"role": "user", "content": formatted_question}
172
+ st.session_state.messages.append(user_message)
173
+ st.session_state.process_personality_question = formatted_question
174
+ st.rerun()
175
+ else:
176
+ st.markdown("""
177
+ <div class="personality-section">
178
+ <strong>πŸ’« Sample Questions:</strong><br>
179
+ <small>Enter a name above to personalize these questions</small>
180
+ </div>
181
+ """, unsafe_allow_html=True)
182
+
183
+ # Show sample questions without names
184
+ for question in PERSONALITY_QUESTIONS[:5]: # Show first 5 as examples
185
+ st.markdown(f"β€’ {question}")
186
+
187
+ # Then, modify the main chat processing section to handle personality questions
188
+ # Add this right after the chat input section and before the existing chat processing:
189
+
190
+ # Check if we need to process a personality question
191
+ if hasattr(st.session_state, 'process_personality_question'):
192
+ prompt = st.session_state.process_personality_question
193
+ del st.session_state.process_personality_question # Clear the flag
194
+
195
+ # Display user message
196
+ with st.chat_message("user"):
197
+ st.markdown(prompt)
198
+
199
+ # Process the question using the same logic as chat input
200
+ # Update user tracking
201
+ update_online_users()
202
+
203
+ # Get RAG response
204
+ with st.chat_message("assistant"):
205
+ if rag_system and rag_system.model and rag_system.get_collection_count() > 0:
206
+ # Search documents first
207
+ search_results = rag_system.search(prompt, n_results=5)
208
+
209
+ # Debug output for troubleshooting
210
+ if search_results:
211
+ st.info(f"πŸ” Found {len(search_results)} potential matches. Best similarity: {search_results[0]['similarity']:.3f}")
212
+ else:
213
+ st.warning("πŸ” No search results returned from vector database")
214
+
215
+ # Check if we found relevant documents (very low threshold)
216
+ if search_results and search_results[0]['similarity'] > 0.001: # Ultra-low threshold
217
+ # Generate document-based answer
218
+ result = rag_system.generate_answer(
219
+ prompt,
220
+ search_results,
221
+ use_ai_enhancement=use_ai_enhancement,
222
+ unlimited_tokens=unlimited_tokens
223
+ )
224
+
225
+ # Display AI answer or extracted answer
226
+ if use_ai_enhancement and result['has_both']:
227
+ answer_text = result['ai_answer']
228
+ st.markdown(f"πŸ€– **AI Enhanced Answer:** {answer_text}")
229
+
230
+ # Also show extracted answer for comparison if different
231
+ if result['extracted_answer'] != answer_text:
232
+ with st.expander("πŸ“„ View Extracted Answer"):
233
+ st.markdown(result['extracted_answer'])
234
+ else:
235
+ answer_text = result['extracted_answer']
236
+ st.markdown(f"πŸ“„ **Document Answer:** {answer_text}")
237
+
238
+ # Show why AI enhancement wasn't used
239
+ if use_ai_enhancement and not result['has_both']:
240
+ st.info("πŸ’‘ AI enhancement failed - showing extracted answer from documents")
241
+
242
+ # Show RAG info with more details
243
+ if show_sources and result['sources']:
244
+ confidence_text = f"{result['confidence']*100:.1f}%" if show_confidence else ""
245
+ st.markdown(f"""
246
+ <div class="rag-attribution">
247
+ <strong>πŸ“ Sources:</strong> {', '.join(result['sources'])}<br>
248
+ <strong>🎯 Confidence:</strong> {confidence_text}<br>
249
+ <strong>πŸ“Š Found:</strong> {len(search_results)} relevant sections<br>
250
+ <strong>πŸ” Best Match:</strong> {search_results[0]['similarity']:.3f} similarity
251
+ </div>
252
+ """, unsafe_allow_html=True)
253
+
254
+ # Add to messages with RAG info
255
+ assistant_message = {
256
+ "role": "assistant",
257
+ "content": answer_text,
258
+ "rag_info": {
259
+ "sources": result['sources'],
260
+ "confidence": result['confidence'],
261
+ "extracted_answer": result['extracted_answer'],
262
+ "has_ai": result['has_both']
263
+ }
264
+ }
265
+
266
+ else:
267
+ # No relevant documents found - show debug info
268
+ if search_results:
269
+ st.warning(f"πŸ“„ Found documents but similarity too low (best: {search_results[0]['similarity']:.3f}). Using general AI...")
270
+ else:
271
+ st.warning("πŸ“„ No documents found in search. Using general AI...")
272
+
273
+ general_response = get_general_ai_response(prompt, unlimited_tokens=unlimited_tokens)
274
+ st.markdown(f"πŸ’¬ **General AI:** {general_response}")
275
+
276
+ assistant_message = {
277
+ "role": "assistant",
278
+ "content": general_response,
279
+ "rag_info": {"sources": [], "confidence": 0, "mode": "general"}
280
+ }
281
+
282
+ else:
283
+ # RAG system not ready - use general AI
284
+ if rag_system and rag_system.get_collection_count() == 0:
285
+ st.warning("No documents indexed. Sync from GitHub or upload documents first...")
286
+ else:
287
+ st.error("RAG system not ready. Using general AI mode...")
288
+
289
+ general_response = get_general_ai_response(prompt, unlimited_tokens=unlimited_tokens)
290
+ st.markdown(f"πŸ’¬ **General AI:** {general_response}")
291
+
292
+ assistant_message = {
293
+ "role": "assistant",
294
+ "content": general_response,
295
+ "rag_info": {"sources": [], "confidence": 0, "mode": "general"}
296
+ }
297
+
298
+ # Add assistant message to history
299
+ st.session_state.messages.append(assistant_message)
300
+
301
+ # Auto-save
302
+ save_chat_history(st.session_state.messages)
303
+
304
+ # Continue with the existing chat input processing...
305
 
306
  # ================= GITHUB INTEGRATION =================
307
 
 
903
  st.session_state.messages = []
904
  st.session_state.session_id = str(uuid.uuid4())
905
 
906
+ # ================= MAIN APP =================
907
+
908
+ # Initialize session state
909
+ if "messages" not in st.session_state:
910
+ st.session_state.messages = load_chat_history()
911
+
912
+ if "session_id" not in st.session_state:
913
+ st.session_state.session_id = str(uuid.uuid4())
914
+
915
+ # Initialize RAG system
916
+ rag_system = initialize_rag_system()
917
+
918
+ # Header
919
+ st.title("RAG Chat Flow βœ©β‚ŠΛš.β‹†πŸ•ΈοΈβ‹†βΊβ‚Šβœ§")
920
+ st.caption("Ask questions about your documents with AI-powered retrieval")
921
+
922
+ # Sidebar
923
+ with st.sidebar:
924
+ # New Chat Button
925
+ if st.button("βž• New Chat", use_container_width=True, type="primary"):
926
+ start_new_chat()
927
+ st.rerun()
928
 
929
+ st.divider()
930
+
931
+ # Personality Questions Section
932
+ st.header("🎭 Personality Questions")
933
+
934
+ # Name input for personalizing questions
935
+ name_input = st.text_input("Enter name for personalized questions:", placeholder="e.g., Sarah, Ahmed", help="Replace [name] in questions with this name")
936
+
937
+ if name_input.strip():
938
+ name = name_input.strip()
939
+ st.markdown(f"""
940
+ <div class="personality-section">
941
+ <strong>πŸ’« Quick Questions for {name}:</strong><br>
942
+ <small>Click any question to ask about {name}</small>
943
+ </div>
944
+ """, unsafe_allow_html=True)
945
 
946
+ # Display personality questions as clickable buttons
947
+ for i, question in enumerate(PERSONALITY_QUESTIONS):
948
+ formatted_question = question.replace("[name]", name)
949
+ if st.button(formatted_question, key=f"pq_{i}", use_container_width=True):
950
+ # Add the question to chat
951
+ user_message = {"role": "user", "content": formatted_question}
952
+ st.session_state.messages.append(user_message)
953
+ st.rerun()
954
+ else:
955
+ st.markdown("""
956
+ <div class="personality-section">
957
+ <strong>πŸ’« Sample Questions:</strong><br>
958
+ <small>Enter a name above to personalize these questions</small>
959
+ </div>
960
+ """, unsafe_allow_html=True)
961
+
962
+ # Show sample questions without names
963
+ for question in PERSONALITY_QUESTIONS[:5]: # Show first 5 as examples
964
+ st.markdown(f"β€’ {question}")
965
+
966
+ st.divider()
967
+
968
+ # GitHub Integration
969
+ st.header("πŸ™ GitHub Integration")
970
+
971
+ github_status = check_github_status()
972
+
973
+ if github_status["status"] == "connected":
974
+ st.markdown(f"""
975
+ <div class="github-status">
976
+ <strong>🟒 GitHub:</strong> {github_status['message']}<br>
977
+ <strong>πŸ“‚ Repo:</strong> family-profiles (private)
978
+ </div>
979
+ """, unsafe_allow_html=True)
980
+
981
+ # Sync from GitHub button
982
+ if st.button("πŸ”„ Sync from GitHub", use_container_width=True):
983
+ if clone_github_repo():
984
+ # Auto-index after successful sync
985
+ if rag_system and rag_system.model:
986
+ with st.spinner("Auto-indexing synced documents..."):
987
+ if rag_system.index_documents("documents"):
988
+ st.success("βœ… Documents synced and indexed!")
989
+ st.rerun()
990
+ else:
991
+ st.warning("⚠️ Sync successful but indexing failed")
992
+ else:
993
+ color_map = {"red": "πŸ”΄", "orange": "🟠", "green": "🟒"}
994
+ color_icon = color_map.get(github_status["color"], "πŸ”΄")
995
+
996
+ st.markdown(f"""
997
+ <div class="github-status">
998
+ <strong>{color_icon} GitHub:</strong> {github_status['message']}<br>
999
+ <strong>πŸ“‹ Setup:</strong> Add GITHUB_TOKEN to Hugging Face secrets
1000
+ </div>
1001
+ """, unsafe_allow_html=True)
1002
+
1003
+ st.divider()
1004
+
1005
+ # Document Management
1006
+ st.header("πŸ“‚ Document Management")
1007
+
1008
+ if rag_system and rag_system.model:
1009
+ doc_count = rag_system.get_collection_count()
1010
+
1011
+ if doc_count > 0:
1012
+ st.markdown(f"""
1013
+ <div class="document-status">
1014
+ <strong>πŸ“Š Documents Indexed:</strong> {doc_count} chunks<br>
1015
+ <strong>πŸ” Status:</strong> Ready for queries
1016
+ </div>
1017
+ """, unsafe_allow_html=True)
1018
  else:
1019
+ st.warning("No documents indexed. Sync from GitHub or upload documents to get started.")
1020
+
1021
+ # Document indexing
1022
+ if st.button("πŸ”„ Re-index Documents", use_container_width=True):
1023
+ with st.spinner("Indexing documents..."):
1024
+ if rag_system.index_documents("documents"):
1025
+ st.success("Documents indexed successfully!")
1026
+ st.rerun()
1027
+ else:
1028
+ st.error("Failed to index documents. Check your documents folder.")
1029
+
1030
+ # Show document count only (hidden)
1031
+ if os.path.exists("documents"):
1032
+ txt_files = [f for f in os.listdir("documents") if f.endswith('.txt')]
1033
+ if txt_files:
1034
+ st.info(f"πŸ“„ {len(txt_files)} documents loaded (hidden)")
1035
+
1036
+ # Manual upload interface (fallback)
1037
+ st.subheader("πŸ“€ Manual Upload")
1038
+ uploaded_files = st.file_uploader(
1039
+ "Upload text files (fallback)",
1040
+ type=['txt'],
1041
+ accept_multiple_files=True,
1042
+ help="Upload .txt files if GitHub sync is not available"
1043
+ )
1044
+
1045
+ if uploaded_files:
1046
+ if st.button("πŸ’Ύ Save & Index Files"):
1047
+ os.makedirs("documents", exist_ok=True)
1048
+ saved_files = []
1049
 
1050
+ for uploaded_file in uploaded_files:
1051
+ file_path = os.path.join("documents", uploaded_file.name)
1052
+ with open(file_path, "wb") as f:
1053
+ f.write(uploaded_file.getbuffer())
1054
+ saved_files.append(uploaded_file.name)
 
 
1055
 
1056
+ st.success(f"Saved {len(saved_files)} files!")
1057
+
1058
+ # Auto-index
1059
+ with st.spinner("Auto-indexing new documents..."):
1060
+ if rag_system.index_documents("documents"):
1061
+ st.success("Documents indexed successfully!")
1062
+ st.rerun()
1063
+ else:
1064
+ st.error("RAG system initialization failed. Check your setup.")
1065
+
1066
+ st.divider()
1067
+
1068
+ # Online Users
1069
+ st.header("πŸ‘₯ Online Users")
1070
+ online_count = update_online_users()
1071
+
1072
+ if online_count == 1:
1073
+ st.success("🟒 Just you online")
1074
+ else:
1075
+ st.success(f"🟒 {online_count} people online")
1076
+
1077
+ st.divider()
1078
+
1079
+ # Settings
1080
+ st.header("βš™οΈ Settings")
1081
+
1082
+ # API Status with better checking
1083
+ openrouter_key = os.environ.get("OPENROUTER_API_KEY")
1084
+ if openrouter_key:
1085
+ st.success(" βœ… API Connected")
1086
+ # Quick API test
1087
+ if st.button("Test API Connection", use_container_width=True):
1088
+ try:
1089
+ test_response = requests.post(
1090
+ "https://openrouter.ai/api/v1/chat/completions",
1091
+ headers={
1092
+ "Authorization": f"Bearer {openrouter_key}",
1093
+ "Content-Type": "application/json"
1094
+ },
1095
+ json={
1096
+ "model": "openai/gpt-3.5-turbo",
1097
+ "messages": [{"role": "user", "content": "test"}],
1098
+ "max_tokens": 5
1099
+ },
1100
+ timeout=5
1101
+ )
1102
+ if test_response.status_code == 200:
1103
+ st.success("βœ… API working correctly!")
1104
+ elif test_response.status_code == 402:
1105
+ st.error("❌ Credits exhausted")
1106
+ elif test_response.status_code == 429:
1107
+ st.warning("⏱️ Rate limited")
1108
+ else:
1109
+ st.error(f"❌ API Error: {test_response.status_code}")
1110
+ except Exception as e:
1111
+ st.error(f"❌ API Test Failed: {str(e)}")
1112
+ else:
1113
+ st.error("❌ No OpenRouter API Key")
1114
+ st.info("Add OPENROUTER_API_KEY in Hugging Face Space settings β†’ Variables and secrets")
1115
+
1116
+ # Enhanced Settings
1117
+ st.subheader("πŸš€ Token Settings")
1118
+ unlimited_tokens = st.checkbox("πŸ”₯ Unlimited Tokens Mode", value=True, help="Use higher token limits for detailed responses")
1119
+ use_ai_enhancement = st.checkbox("πŸ€– AI Enhancement", value=bool(openrouter_key), help="Enhance answers with AI when documents are found")
1120
+
1121
+ st.subheader("πŸŽ›οΈ Display Settings")
1122
+ show_sources = st.checkbox("πŸ“ Show Sources", value=True)
1123
+ show_confidence = st.checkbox("🎯 Show Confidence Scores", value=True)
1124
+
1125
+ # Token mode indicator
1126
+ if unlimited_tokens:
1127
+ st.success("πŸ”₯ Unlimited mode: Detailed responses enabled")
1128
+ else:
1129
+ st.info("πŸ’° Conservative mode: Limited tokens to save credits")
1130
+
1131
+ st.divider()
1132
+
1133
+ # Chat History Controls
1134
+ st.header("πŸ’Ύ Chat History")
1135
+
1136
+ if st.session_state.messages:
1137
+ st.info(f"Messages: {len(st.session_state.messages)}")
1138
+
1139
+ col1, col2 = st.columns(2)
1140
+ with col1:
1141
+ if st.button("πŸ’Ύ Save", use_container_width=True):
1142
+ save_chat_history(st.session_state.messages)
1143
+ st.success("Saved!")
1144
+
1145
+ with col2:
1146
+ if st.button("πŸ—‘οΈ Clear", use_container_width=True):
1147
+ start_new_chat()
1148
+ st.success("Cleared!")
1149
+ st.rerun()
1150
+
1151
+ # ================= MAIN CHAT AREA =================
1152
+
1153
+ # Display chat messages
1154
+ for message in st.session_state.messages:
1155
+ with st.chat_message(message["role"]):
1156
+ if message["role"] == "assistant" and "rag_info" in message:
1157
+ # Display AI answer
1158
+ st.markdown(message["content"])
1159
 
1160
+ # Display RAG information
1161
+ rag_info = message["rag_info"]
1162
+
1163
+ if show_sources and rag_info.get("sources"):
1164
+ confidence_text = f"{rag_info['confidence']*100:.1f}%" if show_confidence else ""
1165
  st.markdown(f"""
1166
  <div class="rag-attribution">
1167
+ <strong>πŸ“ Sources:</strong> {', '.join(rag_info['sources'])}<br>
1168
+ <strong>🎯 Confidence:</strong> {confidence_text}
 
 
1169
  </div>
1170
  """, unsafe_allow_html=True)
1171
 
1172
+ # Show extracted answer if different
1173
+ if rag_info.get("extracted_answer") and rag_info["extracted_answer"] != message["content"]:
1174
+ st.markdown("**πŸ“„ Extracted Answer:**")
1175
+ st.markdown(f"_{rag_info['extracted_answer']}_")
1176
+ else:
1177
+ st.markdown(message["content"])
1178
+
1179
+ # Chat input
1180
+ if prompt := st.chat_input("Ask questions about your documents..."):
1181
+ # Update user tracking
1182
+ update_online_users()
1183
+
1184
+ # Add user message
1185
+ user_message = {"role": "user", "content": prompt}
1186
+ st.session_state.messages.append(user_message)
1187
+
1188
+ # Display user message
1189
+ with st.chat_message("user"):
1190
+ st.markdown(prompt)
1191
+
1192
+ # Get RAG response
1193
+ with st.chat_message("assistant"):
1194
+ if rag_system and rag_system.model and rag_system.get_collection_count() > 0:
1195
+ # Search documents first
1196
+ search_results = rag_system.search(prompt, n_results=5)
1197
+
1198
+ # Debug output for troubleshooting
1199
+ if search_results:
1200
+ st.info(f"πŸ” Found {len(search_results)} potential matches. Best similarity: {search_results[0]['similarity']:.3f}")
1201
+ else:
1202
+ st.warning("πŸ” No search results returned from vector database")
1203
+
1204
+ # Check if we found relevant documents (very low threshold)
1205
+ if search_results and search_results[0]['similarity'] > 0.001: # Ultra-low threshold
1206
+ # Generate document-based answer
1207
+ result = rag_system.generate_answer(
1208
+ prompt,
1209
+ search_results,
1210
+ use_ai_enhancement=use_ai_enhancement,
1211
+ unlimited_tokens=unlimited_tokens
1212
+ )
1213
+
1214
+ # Display AI answer or extracted answer
1215
+ if use_ai_enhancement and result['has_both']:
1216
+ answer_text = result['ai_answer']
1217
+ st.markdown(f"πŸ€– **AI Enhanced Answer:** {answer_text}")
1218
+
1219
+ # Also show extracted answer for comparison if different
1220
+ if result['extracted_answer'] != answer_text:
1221
+ with st.expander("πŸ“„ View Extracted Answer"):
1222
+ st.markdown(result['extracted_answer'])
1223
+ else:
1224
+ answer_text = result['extracted_answer']
1225
+ st.markdown(f"πŸ“„ **Document Answer:** {answer_text}")
1226
+
1227
+ # Show why AI enhancement wasn't used
1228
+ if use_ai_enhancement and not result['has_both']:
1229
+ st.info("πŸ’‘ AI enhancement failed - showing extracted answer from documents")
1230
+
1231
+ # Show RAG info with more details
1232
+ if show_sources and result['sources']:
1233
+ confidence_text = f"{result['confidence']*100:.1f}%" if show_confidence else ""
1234
+ st.markdown(f"""
1235
+ <div class="rag-attribution">
1236
+ <strong>πŸ“ Sources:</strong> {', '.join(result['sources'])}<br>
1237
+ <strong>🎯 Confidence:</strong> {confidence_text}<br>
1238
+ <strong>πŸ“Š Found:</strong> {len(search_results)} relevant sections<br>
1239
+ <strong>πŸ” Best Match:</strong> {search_results[0]['similarity']:.3f} similarity
1240
+ </div>
1241
+ """, unsafe_allow_html=True)
1242
+
1243
+ # Add to messages with RAG info
1244
+ assistant_message = {
1245
+ "role": "assistant",
1246
+ "content": answer_text,
1247
+ "rag_info": {
1248
+ "sources": result['sources'],
1249
+ "confidence": result['confidence'],
1250
+ "extracted_answer": result['extracted_answer'],
1251
+ "has_ai": result['has_both']
1252
+ }
1253
+ }
1254
+
1255
+ else:
1256
+ # No relevant documents found - show debug info
1257
+ if search_results:
1258
+ st.warning(f"πŸ“„ Found documents but similarity too low (best: {search_results[0]['similarity']:.3f}). Using general AI...")
1259
+ else:
1260
+ st.warning("πŸ“„ No documents found in search. Using general AI...")
1261
+
1262
+ general_response = get_general_ai_response(prompt, unlimited_tokens=unlimited_tokens)
1263
+ st.markdown(f"πŸ’¬ **General AI:** {general_response}")
1264
+
1265
+ assistant_message = {
1266
+ "role": "assistant",
1267
+ "content": general_response,
1268
+ "rag_info": {"sources": [], "confidence": 0, "mode": "general"}
1269
+ }
1270
+
1271
+ else:
1272
+ # RAG system not ready - use general AI
1273
+ if rag_system and rag_system.get_collection_count() == 0:
1274
+ st.warning("No documents indexed. Sync from GitHub or upload documents first...")
1275
+ else:
1276
+ st.error("RAG system not ready. Using general AI mode...")
1277
+
1278
+ general_response = get_general_ai_response(prompt, unlimited_tokens=unlimited_tokens)
1279
+ st.markdown(f"πŸ’¬ **General AI:** {general_response}")
1280
+
1281
+ assistant_message = {
1282
+ "role": "assistant",
1283
+ "content": general_response,
1284
+ "rag_info": {"sources": [], "confidence": 0, "mode": "general"}
1285
+ }
1286
+
1287
+ # Add assistant message to history
1288
+ st.session_state.messages.append(assistant_message)
1289
+
1290
+ # Auto-save
1291
+ save_chat_history(st.session_state.messages)
1292
+
1293
+ # Footer info
1294
+ if rag_system and rag_system.model:
1295
+ doc_count = rag_system.get_collection_count()
1296
+ token_mode = "πŸ”₯ Unlimited" if unlimited_tokens else "πŸ’° Conservative"
1297
+ github_status = check_github_status()
1298
+ github_icon = "🟒" if github_status["status"] == "connected" else "πŸ”΄"
1299
+ st.caption(f"πŸ“š Knowledge Base: {doc_count} indexed chunks | πŸ” RAG System Active | {token_mode} Token Mode | {github_icon} GitHub {github_status['status'].title()}")