uumerrr684 commited on
Commit
f820b38
·
verified ·
1 Parent(s): ce6eb22

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +185 -560
app.py CHANGED
@@ -13,7 +13,7 @@ st.set_page_config(
13
  initial_sidebar_state="collapsed"
14
  )
15
 
16
- # Enhanced mobile-responsive CSS
17
  st.markdown("""
18
  <style>
19
  .stApp {
@@ -39,211 +39,6 @@ st.markdown("""
39
  font-size: 0.8em;
40
  font-style: italic;
41
  }
42
-
43
- .welcome-title {
44
- text-align: center;
45
- font-size: 2.5rem;
46
- font-weight: bold;
47
- margin-bottom: 0.5rem;
48
- }
49
-
50
- .welcome-subtitle {
51
- text-align: center;
52
- font-size: 1.2rem;
53
- color: #666;
54
- margin-bottom: 2rem;
55
- }
56
-
57
- /* Mobile optimizations */
58
- @media (max-width: 768px) {
59
- /* Reduce overall padding */
60
- .main .block-container {
61
- padding-top: 1rem;
62
- padding-left: 1rem;
63
- padding-right: 1rem;
64
- padding-bottom: 1rem;
65
- }
66
-
67
- /* Make titles smaller on mobile */
68
- .welcome-title {
69
- font-size: 1.8rem;
70
- margin-bottom: 0.3rem;
71
- }
72
-
73
- .welcome-subtitle {
74
- font-size: 1rem;
75
- margin-bottom: 1rem;
76
- }
77
-
78
- /* Compact chat messages */
79
- .stChatMessage {
80
- margin-bottom: 0.5rem !important;
81
- padding: 0.5rem !important;
82
- }
83
-
84
- /* Smaller chat message content */
85
- .stChatMessage > div {
86
- padding: 0.3rem 0.5rem !important;
87
- font-size: 0.9rem !important;
88
- line-height: 1.3 !important;
89
- }
90
-
91
- /* Compact chat input */
92
- .stChatInput > div {
93
- padding: 0.5rem !important;
94
- }
95
-
96
- .stChatInput input {
97
- font-size: 0.9rem !important;
98
- padding: 0.5rem !important;
99
- }
100
-
101
- /* Reduce spacing in chat container */
102
- .stChatFloatingInputContainer {
103
- padding: 0.5rem !important;
104
- }
105
-
106
- /* Make chat avatars smaller */
107
- .stChatMessage img {
108
- width: 24px !important;
109
- height: 24px !important;
110
- }
111
-
112
- /* Compact attribution text */
113
- .model-attribution {
114
- font-size: 0.7rem !important;
115
- margin-top: 0.2rem !important;
116
- }
117
-
118
- /* Reduce paragraph spacing in messages */
119
- .stChatMessage p {
120
- margin-bottom: 0.5rem !important;
121
- }
122
-
123
- /* Make buttons smaller */
124
- .stButton button {
125
- padding: 0.25rem 0.5rem !important;
126
- font-size: 0.8rem !important;
127
- }
128
-
129
- /* Compact sidebar */
130
- .css-1d391kg {
131
- padding: 0.5rem !important;
132
- }
133
-
134
- /* Smaller text in sidebar */
135
- .css-1d391kg .stMarkdown {
136
- font-size: 0.85rem !important;
137
- }
138
-
139
- /* Reduce spacing between elements */
140
- .element-container {
141
- margin-bottom: 0.5rem !important;
142
- }
143
-
144
- /* Compact selectbox and other inputs */
145
- .stSelectbox > div > div {
146
- font-size: 0.85rem !important;
147
- }
148
-
149
- /* Reduce caption size */
150
- .stCaption {
151
- font-size: 0.7rem !important;
152
- }
153
-
154
- /* Make status indicators smaller */
155
- .stSuccess, .stInfo, .stWarning, .stError {
156
- font-size: 0.8rem !important;
157
- padding: 0.3rem !important;
158
- }
159
-
160
- /* Compact dividers */
161
- hr {
162
- margin: 0.5rem 0 !important;
163
- }
164
-
165
- /* Reduce header sizes in sidebar */
166
- .css-1d391kg h1, .css-1d391kg h2, .css-1d391kg h3 {
167
- font-size: 1rem !important;
168
- margin-bottom: 0.3rem !important;
169
- }
170
-
171
- /* Make chat messages look more like mobile messages */
172
- .stChatMessage[data-testid="user-message"] {
173
- background-color: #007bff !important;
174
- color: white !important;
175
- border-radius: 1rem !important;
176
- margin-left: 20% !important;
177
- }
178
-
179
- .stChatMessage[data-testid="assistant-message"] {
180
- background-color: #f1f1f1 !important;
181
- color: black !important;
182
- border-radius: 1rem !important;
183
- margin-right: 20% !important;
184
- }
185
-
186
- /* Force AI message text to be black */
187
- .stChatMessage[data-testid="assistant-message"] * {
188
- color: black !important;
189
- }
190
-
191
- /* Make sure all AI message content is visible */
192
- .stChatMessage[data-testid="assistant-message"] .stMarkdown,
193
- .stChatMessage[data-testid="assistant-message"] p,
194
- .stChatMessage[data-testid="assistant-message"] div {
195
- color: black !important;
196
- }
197
-
198
- /* Reduce overall font size for mobile */
199
- body, .stApp {
200
- font-size: 14px !important;
201
- }
202
-
203
- /* Make expander more compact */
204
- .streamlit-expanderHeader {
205
- font-size: 0.8rem !important;
206
- padding: 0.3rem !important;
207
- }
208
-
209
- .streamlit-expanderContent {
210
- padding: 0.3rem !important;
211
- }
212
-
213
- /* Compact text areas */
214
- .stTextArea textarea {
215
- font-size: 0.8rem !important;
216
- }
217
- }
218
-
219
- /* Extra small screens (phones in portrait) */
220
- @media (max-width: 480px) {
221
- .main .block-container {
222
- padding: 0.5rem;
223
- }
224
-
225
- .welcome-title {
226
- font-size: 1.5rem;
227
- }
228
-
229
- .welcome-subtitle {
230
- font-size: 0.9rem;
231
- }
232
-
233
- .stChatMessage > div {
234
- font-size: 0.85rem !important;
235
- }
236
-
237
- .stChatInput input {
238
- font-size: 0.85rem !important;
239
- }
240
-
241
- /* Even more compact messages */
242
- .stChatMessage {
243
- margin-bottom: 0.3rem !important;
244
- padding: 0.3rem !important;
245
- }
246
- }
247
  </style>
248
  """, unsafe_allow_html=True)
249
 
@@ -251,8 +46,6 @@ st.markdown("""
251
  HISTORY_FILE = "chat_history.json"
252
  # NEW: File to store online users
253
  USERS_FILE = "online_users.json"
254
- # NEW: File to store chat sessions
255
- SESSIONS_FILE = "chat_sessions.json"
256
 
257
 
258
  def load_chat_history():
@@ -284,98 +77,6 @@ def clear_chat_history():
284
  except Exception as e:
285
  st.error(f"Error clearing chat history: {e}")
286
 
287
-
288
- # NEW: Chat Sessions Management
289
- def load_chat_sessions():
290
- """Load all chat sessions"""
291
- try:
292
- if os.path.exists(SESSIONS_FILE):
293
- with open(SESSIONS_FILE, 'r', encoding='utf-8') as f:
294
- return json.load(f)
295
- except Exception as e:
296
- st.error(f"Error loading chat sessions: {e}")
297
- return {}
298
-
299
-
300
- def save_chat_sessions(sessions):
301
- """Save chat sessions to file"""
302
- try:
303
- with open(SESSIONS_FILE, 'w', encoding='utf-8') as f:
304
- json.dump(sessions, f, ensure_ascii=False, indent=2)
305
- except Exception as e:
306
- st.error(f"Error saving chat sessions: {e}")
307
-
308
-
309
- def get_session_id():
310
- """Get or create session ID"""
311
- if 'session_id' not in st.session_state:
312
- st.session_state.session_id = str(uuid.uuid4())
313
- return st.session_state.session_id
314
-
315
-
316
- def get_chat_title(messages):
317
- """Generate a title for the chat based on first user message"""
318
- if not messages:
319
- return "New Chat"
320
-
321
- for msg in messages:
322
- if msg["role"] == "user":
323
- content = msg["content"]
324
- # Take first 30 characters and add ellipsis if longer
325
- if len(content) > 30:
326
- return content[:30] + "..."
327
- return content
328
- return "New Chat"
329
-
330
-
331
- def save_current_session():
332
- """Save current chat session"""
333
- if not st.session_state.messages:
334
- return
335
-
336
- sessions = load_chat_sessions()
337
- session_id = get_session_id()
338
-
339
- sessions[session_id] = {
340
- "title": get_chat_title(st.session_state.messages),
341
- "messages": st.session_state.messages,
342
- "created_at": datetime.now().isoformat(),
343
- "updated_at": datetime.now().isoformat()
344
- }
345
-
346
- save_chat_sessions(sessions)
347
-
348
-
349
- def load_session(session_id):
350
- """Load a specific chat session"""
351
- sessions = load_chat_sessions()
352
- if session_id in sessions:
353
- st.session_state.messages = sessions[session_id]["messages"]
354
- st.session_state.session_id = session_id
355
- return True
356
- return False
357
-
358
-
359
- def delete_session(session_id):
360
- """Delete a chat session"""
361
- sessions = load_chat_sessions()
362
- if session_id in sessions:
363
- del sessions[session_id]
364
- save_chat_sessions(sessions)
365
- return True
366
- return False
367
-
368
-
369
- def start_new_chat():
370
- """Start a new chat session"""
371
- # Save current session if it has messages
372
- if st.session_state.messages:
373
- save_current_session()
374
-
375
- # Clear current chat and create new session
376
- st.session_state.messages = []
377
- st.session_state.session_id = str(uuid.uuid4())
378
-
379
  # NEW: User tracking functions
380
 
381
 
@@ -446,10 +147,6 @@ def get_online_count():
446
  if "messages" not in st.session_state:
447
  st.session_state.messages = load_chat_history()
448
 
449
- # Initialize session ID
450
- if "session_id" not in st.session_state:
451
- st.session_state.session_id = str(uuid.uuid4())
452
-
453
  # Get API key
454
  OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY")
455
 
@@ -545,282 +242,210 @@ def get_ai_response(messages, model="openai/gpt-3.5-turbo"):
545
 
546
 
547
  # Header
548
- st.markdown('<div class="welcome-title">Welcome back!</div>', unsafe_allow_html=True)
549
- st.markdown('<div class="welcome-subtitle">Which AI model do you want to chat with today?</div>', unsafe_allow_html=True)
550
-
551
- # Create main layout with chat history sidebar
552
- col1, col2 = st.columns([1, 3])
 
 
 
 
 
 
 
 
 
 
553
 
554
- # Chat History Sidebar (Left Column)
555
- with col1:
556
- st.header("💬 Chat History")
557
-
558
- # New Chat Button
559
- if st.button("➕ New Chat", use_container_width=True, type="primary"):
560
- start_new_chat()
561
- st.rerun()
562
-
563
  st.divider()
564
-
565
- # Load and display chat sessions
566
- sessions = load_chat_sessions()
567
- current_session_id = get_session_id()
568
-
569
- if sessions:
570
- st.subheader("Previous Chats")
571
-
572
- # Sort sessions by updated_at (most recent first)
573
- sorted_sessions = sorted(
574
- sessions.items(),
575
- key=lambda x: x[1].get("updated_at", x[1].get("created_at", "")),
576
- reverse=True
577
- )
578
-
579
- for session_id, session_data in sorted_sessions:
580
- # Create container for each chat item
581
- chat_container = st.container()
582
-
583
- with chat_container:
584
- # Show current chat with different styling
585
- if session_id == current_session_id:
586
- st.markdown(f"🔹 **{session_data['title']}**")
587
- else:
588
- col_load, col_delete = st.columns([3, 1])
589
-
590
- with col_load:
591
- if st.button(
592
- f"💭 {session_data['title']}",
593
- key=f"load_{session_id}",
594
- use_container_width=True
595
- ):
596
- # Save current session before switching
597
- if st.session_state.messages:
598
- save_current_session()
599
-
600
- # Load selected session
601
- load_session(session_id)
602
- st.rerun()
603
-
604
- with col_delete:
605
- if st.button("🗑️", key=f"delete_{session_id}"):
606
- delete_session(session_id)
607
- # If deleted session was current, start new chat
608
- if session_id == current_session_id:
609
- start_new_chat()
610
- st.rerun()
611
-
612
- # Show session info
613
- if "updated_at" in session_data:
614
- update_time = datetime.fromisoformat(session_data["updated_at"])
615
- st.caption(f"Updated: {update_time.strftime('%m/%d %H:%M')}")
616
-
617
- st.markdown("---")
618
-
619
  else:
620
- st.info("No previous chats yet")
621
-
622
- # Auto-save current session periodically
623
- if st.session_state.messages:
624
- save_current_session()
625
-
626
- # Main Chat Area (Right Column)
627
- with col2:
628
- # Sidebar
629
- with st.sidebar:
630
- st.header("Settings")
631
-
632
- # API Status
633
- status = check_api_status()
634
- if status == "Connected":
635
- st.success("🟢 API Connected")
636
- elif status == "No API Key":
637
- st.error("No API Key")
 
 
 
638
  else:
639
- st.warning("Connection Issue")
 
640
 
641
- st.divider()
642
 
643
- # NEW: Live Users Section
644
- st.header("👥 Who's Online")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
 
646
- # Update that you're online
647
- online_count = update_online_users()
648
 
649
- # Show live count
650
- if online_count == 1:
651
- st.info("🟢 Just you online")
652
- else:
653
- st.success(f"🟢 {online_count} people online")
654
 
655
- # Show your session
656
- your_id = get_user_id()
657
- st.caption(f"You: User-{your_id}")
 
 
 
 
 
 
 
 
 
 
658
 
659
- # Quick refresh button
660
- if st.button("Refresh", use_container_width=True):
 
 
661
  st.rerun()
662
 
663
- # === NEW: DEBUG SECTION ===
664
- with st.expander("🔍 Debug Info"):
665
- if os.path.exists(USERS_FILE):
666
- with open(USERS_FILE, 'r') as f:
667
- users = json.load(f)
668
- st.write(f"Users in file: {len(users)}")
669
- for uid, data in users.items():
670
- last_seen_time = datetime.fromisoformat(data['last_seen'])
671
- time_ago = datetime.now() - last_seen_time
672
- minutes_ago = int(time_ago.total_seconds() / 60)
673
- st.write(f"- {uid}: {minutes_ago} min ago")
674
- else:
675
- st.write("No users file yet")
676
- # === END DEBUG SECTION ===
677
-
678
- st.divider()
679
-
680
- # All models including new ones
681
- models = [
682
- ("GPT-3.5 Turbo", "openai/gpt-3.5-turbo"),
683
- ("LLaMA 3.1 8B", "meta-llama/llama-3.1-8b-instruct"),
684
- ("LLaMA 3.1 70B", "meta-llama/llama-3.1-70b-instruct"),
685
- ("DeepSeek Chat v3", "deepseek/deepseek-chat-v3-0324:free"),
686
- ("DeepSeek R1", "deepseek/deepseek-r1-0528:free"),
687
- ("Qwen3 Coder", "qwen/qwen3-coder:free"),
688
- ("Microsoft MAI DS R1", "microsoft/mai-ds-r1:free"),
689
- ("Gemma 3 27B", "google/gemma-3-27b-it:free"),
690
- ("Gemma 3 4B", "google/gemma-3-4b-it:free"),
691
- ("Auto (Best Available)", "openrouter/auto")
692
- ]
693
-
694
- model_names = [name for name, _ in models]
695
- model_ids = [model_id for _, model_id in models]
696
-
697
- selected_index = st.selectbox("Model", range(len(model_names)),
698
- format_func=lambda x: model_names[x],
699
- index=0)
700
- selected_model = model_ids[selected_index]
701
-
702
- # Show selected model ID in green
703
- st.markdown(
704
- f"**Model ID:** <span class='model-id'>{selected_model}</span>", unsafe_allow_html=True)
705
-
706
- st.divider()
707
-
708
- # Chat History Controls
709
- st.header("Chat History")
710
-
711
- # Show number of messages
712
- if st.session_state.messages:
713
- st.info(f"Messages stored: {len(st.session_state.messages)}")
714
-
715
- # Auto-save toggle
716
- auto_save = st.checkbox("Auto-save messages", value=True)
717
-
718
- # Manual save/load buttons
719
- col1_sidebar, col2_sidebar = st.columns(2)
720
- with col1_sidebar:
721
- if st.button("Save History", use_container_width=True):
722
- save_chat_history(st.session_state.messages)
723
- st.success("History saved!")
724
-
725
- with col2_sidebar:
726
- if st.button("Load History", use_container_width=True):
727
- st.session_state.messages = load_chat_history()
728
- st.success("History loaded!")
729
- st.rerun()
730
-
731
- st.divider()
732
-
733
- # View History
734
- if st.button("View History File", use_container_width=True):
735
- if os.path.exists(HISTORY_FILE):
736
- with open(HISTORY_FILE, 'r', encoding='utf-8') as f:
737
- history_content = f.read()
738
- st.text_area("Chat History (JSON)", history_content, height=200)
739
- else:
740
- st.warning("No history file found")
741
 
742
- # Download History
 
743
  if os.path.exists(HISTORY_FILE):
744
- with open(HISTORY_FILE, 'rb') as f:
745
- st.download_button(
746
- label="Download History",
747
- data=f.read(),
748
- file_name=f"chat_history_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
749
- mime="application/json",
750
- use_container_width=True
751
- )
752
-
753
- st.divider()
754
-
755
- # Clear controls
756
- if st.button("Clear Chat", use_container_width=True, type="secondary"):
757
- clear_chat_history()
758
- st.success("Chat cleared!")
759
- st.rerun()
 
 
 
 
 
 
 
 
760
 
761
- # Display chat messages
762
- for message in st.session_state.messages:
763
- with st.chat_message(message["role"]):
764
- # Check if this is an assistant message with attribution
765
- if message["role"] == "assistant" and "Response created by:" in message["content"]:
766
- # Split content and attribution
767
- parts = message["content"].split("\n\n---\n*Response created by:")
768
- main_content = parts[0]
769
- if len(parts) > 1:
770
- model_name = parts[1].replace("***", "").replace("**", "")
771
- st.markdown(main_content)
772
- st.markdown(
773
- f"<div class='model-attribution'>Response created by: <strong>{model_name}</strong></div>", unsafe_allow_html=True)
774
- else:
775
- st.markdown(message["content"])
776
  else:
777
  st.markdown(message["content"])
 
 
778
 
779
- # Chat input
780
- if prompt := st.chat_input("Chat Smarter. Chat many Brains"):
781
- # NEW: Update online status when user sends message
782
- update_online_users()
783
 
784
- # Add user message
785
- user_message = {"role": "user", "content": prompt}
786
- st.session_state.messages.append(user_message)
787
 
788
- # Auto-save if enabled
789
- if auto_save:
790
- save_chat_history(st.session_state.messages)
 
 
 
791
 
792
- # Display user message
793
- with st.chat_message("user"):
794
- st.markdown(prompt)
795
 
796
- # Get AI response
797
- with st.chat_message("assistant"):
798
- placeholder = st.empty()
799
 
800
- full_response = ""
801
- try:
802
- for response in get_ai_response(st.session_state.messages, selected_model):
803
- full_response = response
804
- placeholder.markdown(full_response + "▌")
805
-
806
- # Remove cursor and show final response
807
- placeholder.markdown(full_response)
808
-
809
- except Exception as e:
810
- error_msg = f"An error occurred: {str(e)}"
811
- placeholder.markdown(error_msg)
812
- full_response = error_msg
813
-
814
- # Add AI response to messages with attribution
815
- full_response_with_attribution = full_response + \
816
- f"\n\n---\n*Response created by: **{model_names[selected_index]}***"
817
- assistant_message = {"role": "assistant",
818
- "content": full_response_with_attribution}
819
- st.session_state.messages.append(assistant_message)
820
-
821
- # Auto-save if enabled
822
- if auto_save:
823
- save_chat_history(st.session_state.messages)
824
-
825
- # Show currently using model
826
- st.caption(f"Currently using: **{model_names[selected_index]}**")
 
13
  initial_sidebar_state="collapsed"
14
  )
15
 
16
+ # White background
17
  st.markdown("""
18
  <style>
19
  .stApp {
 
39
  font-size: 0.8em;
40
  font-style: italic;
41
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  </style>
43
  """, unsafe_allow_html=True)
44
 
 
46
  HISTORY_FILE = "chat_history.json"
47
  # NEW: File to store online users
48
  USERS_FILE = "online_users.json"
 
 
49
 
50
 
51
  def load_chat_history():
 
77
  except Exception as e:
78
  st.error(f"Error clearing chat history: {e}")
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  # NEW: User tracking functions
81
 
82
 
 
147
  if "messages" not in st.session_state:
148
  st.session_state.messages = load_chat_history()
149
 
 
 
 
 
150
  # Get API key
151
  OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY")
152
 
 
242
 
243
 
244
  # Header
245
+ st.title("Chat Flow 🕷")
246
+ st.caption("10 powerful Models, one simple chat.")
247
+
248
+ # Sidebar
249
+ with st.sidebar:
250
+ st.header("Settings")
251
+
252
+ # API Status
253
+ status = check_api_status()
254
+ if status == "Connected":
255
+ st.success("🟢 API Connected")
256
+ elif status == "No API Key":
257
+ st.error("No API Key")
258
+ else:
259
+ st.warning("Connection Issue")
260
 
 
 
 
 
 
 
 
 
 
261
  st.divider()
262
+
263
+ # NEW: Live Users Section
264
+ st.header("👥 Who's Online")
265
+
266
+ # Update that you're online
267
+ online_count = update_online_users()
268
+
269
+ # Show live count
270
+ if online_count == 1:
271
+ st.info("🟢 Just you online")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  else:
273
+ st.success(f"🟢 {online_count} people online")
274
+
275
+ # Show your session
276
+ your_id = get_user_id()
277
+ st.caption(f"You: User-{your_id}")
278
+
279
+ # Quick refresh button
280
+ if st.button("Refresh", use_container_width=True):
281
+ st.rerun()
282
+
283
+ # === NEW: DEBUG SECTION ===
284
+ with st.expander("🔍 Debug Info"):
285
+ if os.path.exists(USERS_FILE):
286
+ with open(USERS_FILE, 'r') as f:
287
+ users = json.load(f)
288
+ st.write(f"Users in file: {len(users)}")
289
+ for uid, data in users.items():
290
+ last_seen_time = datetime.fromisoformat(data['last_seen'])
291
+ time_ago = datetime.now() - last_seen_time
292
+ minutes_ago = int(time_ago.total_seconds() / 60)
293
+ st.write(f"- {uid}: {minutes_ago} min ago")
294
  else:
295
+ st.write("No users file yet")
296
+ # === END DEBUG SECTION ===
297
 
298
+ st.divider()
299
 
300
+ # All models including new ones
301
+ models = [
302
+ ("GPT-3.5 Turbo", "openai/gpt-3.5-turbo"),
303
+ ("LLaMA 3.1 8B", "meta-llama/llama-3.1-8b-instruct"),
304
+ ("LLaMA 3.1 70B", "meta-llama/llama-3.1-70b-instruct"),
305
+ ("DeepSeek Chat v3", "deepseek/deepseek-chat-v3-0324:free"),
306
+ ("DeepSeek R1", "deepseek/deepseek-r1-0528:free"),
307
+ ("Qwen3 Coder", "qwen/qwen3-coder:free"),
308
+ ("Microsoft MAI DS R1", "microsoft/mai-ds-r1:free"),
309
+ ("Gemma 3 27B", "google/gemma-3-27b-it:free"),
310
+ ("Gemma 3 4B", "google/gemma-3-4b-it:free"),
311
+ ("Auto (Best Available)", "openrouter/auto")
312
+ ]
313
+
314
+ model_names = [name for name, _ in models]
315
+ model_ids = [model_id for _, model_id in models]
316
+
317
+ selected_index = st.selectbox("Model", range(len(model_names)),
318
+ format_func=lambda x: model_names[x],
319
+ index=0)
320
+ selected_model = model_ids[selected_index]
321
+
322
+ # Show selected model ID in green
323
+ st.markdown(
324
+ f"**Model ID:** <span class='model-id'>{selected_model}</span>", unsafe_allow_html=True)
325
 
326
+ st.divider()
 
327
 
328
+ # Chat History Controls
329
+ st.header("Chat History")
 
 
 
330
 
331
+ # Show number of messages
332
+ if st.session_state.messages:
333
+ st.info(f"Messages stored: {len(st.session_state.messages)}")
334
+
335
+ # Auto-save toggle
336
+ auto_save = st.checkbox("Auto-save messages", value=True)
337
+
338
+ # Manual save/load buttons
339
+ col1, col2 = st.columns(2)
340
+ with col1:
341
+ if st.button("Save History", use_container_width=True):
342
+ save_chat_history(st.session_state.messages)
343
+ st.success("History saved!")
344
 
345
+ with col2:
346
+ if st.button("Load History", use_container_width=True):
347
+ st.session_state.messages = load_chat_history()
348
+ st.success("History loaded!")
349
  st.rerun()
350
 
351
+ st.divider()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
 
353
+ # View History
354
+ if st.button("View History File", use_container_width=True):
355
  if os.path.exists(HISTORY_FILE):
356
+ with open(HISTORY_FILE, 'r', encoding='utf-8') as f:
357
+ history_content = f.read()
358
+ st.text_area("Chat History (JSON)", history_content, height=200)
359
+ else:
360
+ st.warning("No history file found")
361
+
362
+ # Download History
363
+ if os.path.exists(HISTORY_FILE):
364
+ with open(HISTORY_FILE, 'rb') as f:
365
+ st.download_button(
366
+ label="Download History",
367
+ data=f.read(),
368
+ file_name=f"chat_history_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
369
+ mime="application/json",
370
+ use_container_width=True
371
+ )
372
+
373
+ st.divider()
374
+
375
+ # Clear controls
376
+ if st.button("Clear Chat", use_container_width=True, type="secondary"):
377
+ clear_chat_history()
378
+ st.success("Chat cleared!")
379
+ st.rerun()
380
 
381
+ # Show welcome message when no messages
382
+
383
+ # Display chat messages
384
+ for message in st.session_state.messages:
385
+ with st.chat_message(message["role"]):
386
+ # Check if this is an assistant message with attribution
387
+ if message["role"] == "assistant" and "Response created by:" in message["content"]:
388
+ # Split content and attribution
389
+ parts = message["content"].split("\n\n---\n*Response created by:")
390
+ main_content = parts[0]
391
+ if len(parts) > 1:
392
+ model_name = parts[1].replace("***", "").replace("**", "")
393
+ st.markdown(main_content)
394
+ st.markdown(
395
+ f"<div class='model-attribution'>Response created by: <strong>{model_name}</strong></div>", unsafe_allow_html=True)
396
  else:
397
  st.markdown(message["content"])
398
+ else:
399
+ st.markdown(message["content"])
400
 
401
+ # Chat input - MUST be at the main level, not inside sidebar or columns
402
+ if prompt := st.chat_input("Chat Smarter. Chat many Brains"):
403
+ # NEW: Update online status when user sends message
404
+ update_online_users()
405
 
406
+ # Add user message
407
+ user_message = {"role": "user", "content": prompt}
408
+ st.session_state.messages.append(user_message)
409
 
410
+ # Auto-save if enabled
411
+ if 'auto_save' not in locals():
412
+ auto_save = True # Default value if not set in sidebar
413
+
414
+ if auto_save:
415
+ save_chat_history(st.session_state.messages)
416
 
417
+ # Display user message
418
+ with st.chat_message("user"):
419
+ st.markdown(prompt)
420
 
421
+ # Get AI response
422
+ with st.chat_message("assistant"):
423
+ placeholder = st.empty()
424
 
425
+ full_response = ""
426
+ try:
427
+ for response in get_ai_response(st.session_state.messages, selected_model):
428
+ full_response = response
429
+ placeholder.markdown(full_response + "▌")
430
+
431
+ # Remove cursor and show final response
432
+ placeholder.markdown(full_response)
433
+
434
+ except Exception as e:
435
+ error_msg = f"An error occurred: {str(e)}"
436
+ placeholder.markdown(error_msg)
437
+ full_response = error_msg
438
+
439
+ # Add AI response to messages with attribution
440
+ full_response_with_attribution = full_response + \
441
+ f"\n\n---\n*Response created by: **{model_names[selected_index]}***"
442
+ assistant_message = {"role": "assistant",
443
+ "content": full_response_with_attribution}
444
+ st.session_state.messages.append(assistant_message)
445
+
446
+ # Auto-save if enabled
447
+ if auto_save:
448
+ save_chat_history(st.session_state.messages)
449
+
450
+ # Show currently using model
451
+ st.caption(f"Currently using: **{model_names[selected_index]}**")