qwendashcoder commited on
Commit
cde3cf9
·
verified ·
1 Parent(s): 130c26b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +94 -12
app.py CHANGED
@@ -109,6 +109,40 @@ def save_chat_context(new_context, user_chats, current_chat_title, logged_in_use
109
  save_chats(logged_in_username, user_chats, auth_globals)
110
  return user_chats, "✅ Context saved!"
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  # ================== HELPER: No conversion needed (Gradio expects messages format) ==================
113
  def format_history_for_chatbot(history):
114
  """Return history as-is (already dict format)"""
@@ -177,27 +211,37 @@ def handle_chat(msg, chatbot, current_model, logged_in_username, user_chats_stat
177
  if not current_model:
178
  gr.Warning("⚠️ Load a model first!")
179
  return chatbot
180
- # Ensure the message is being passed as expected
181
- if not msg or not isinstance(msg, str):
182
- gr.Warning("⚠️ Invalid input message format!")
 
183
  return chatbot
184
-
185
- if file_upload and len(file_upload) > 5:
186
- gr.Warning("⚠️ Max 5 files allowed! Ignoring extras.")
187
- file_upload = file_upload[:5]
188
 
189
- # Chatbot is already in correct dict format (no conversion needed)
190
  internal_history = chatbot[:] if chatbot else []
191
 
192
- # Call chat_stream with internal dict history
193
  try:
194
  stream_gen = chat_stream(msg, internal_history, current_model, logged_in_username, user_chats_state, current_chat_title, mode_radio, auth_globals_state, file_upload, current_chat_context)
195
 
196
  for updated_history in stream_gen:
197
- yield updated_history # ← direct yield, no formatter
 
 
 
 
 
 
198
  except Exception as e:
199
- gr.Warning(f"⚠️ An error occurred in the chat processing: {str(e)}")
200
- return chatbot # Gracefully return the existing chatbot state
 
 
 
 
 
201
 
202
 
203
  # ================== GUI ==================
@@ -216,6 +260,8 @@ with gr.Blocks(title="NVIDIA AI Chat") as demo:
216
  auth_globals_state = gr.State(auth_globals)
217
  coding_files_state = gr.State({}) # { "filename.py": {"content": "...", "language": "python"} }
218
  current_file_name = gr.State(None)
 
 
219
  status_label = gr.Markdown("⚠️ No model loaded. Login + create/select a chat to begin.", elem_id="status-bold") # Made more prominent
220
 
221
 
@@ -289,6 +335,14 @@ with gr.Blocks(title="NVIDIA AI Chat") as demo:
289
  )
290
  send_btn = gr.Button("➤", variant="primary", scale=1)
291
 
 
 
 
 
 
 
 
 
292
  # Authentication (clean version - no phone/OTP)
293
  with gr.Row():
294
  username_input = gr.Textbox(label="Username (will be forced lowercase)", scale=2, placeholder="admin")
@@ -333,6 +387,34 @@ with gr.Blocks(title="NVIDIA AI Chat") as demo:
333
  confirm_delete_btn.click(delete_account, [confirm_username_input, logged_in_username, auth_globals_state], [status_label, logged_in_username, logout_btn, delete_acc_btn, confirm_row, user_chats_state, current_chat_title, chatbot, chat_dropdown, chat_context_tb, save_context_btn])
334
 
335
  save_context_btn.click(save_chat_context, [chat_context_tb, user_chats_state, current_chat_title, logged_in_username], [user_chats_state, status_label])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
 
337
  msg.submit(
338
  handle_chat,
 
109
  save_chats(logged_in_username, user_chats, auth_globals)
110
  return user_chats, "✅ Context saved!"
111
 
112
+ def enforce_cooldown(last_time):
113
+ now = time.time()
114
+ if now - last_time < 3:
115
+ gr.Warning("⏳ Please wait 3 seconds before clicking again.")
116
+ return False, last_time
117
+ return True, now
118
+
119
+ def delete_last_message(user_chats, current_title, logged_in_username, auth_globals):
120
+ if not current_title or not user_chats:
121
+ return user_chats, "Nothing to delete"
122
+ for chat in user_chats:
123
+ if chat["title"] == current_title and len(chat["history"]) >= 2:
124
+ chat["history"] = chat["history"][:-2] # remove last user + assistant
125
+ break
126
+ save_chats(logged_in_username, user_chats, auth_globals)
127
+ return user_chats, "🗑️ Last message deleted"
128
+
129
+ def edit_last_prompt(user_chats, current_title):
130
+ if not current_title or not user_chats:
131
+ return "", "No previous prompt"
132
+ for chat in user_chats:
133
+ if chat["title"] == current_title and len(chat["history"]) >= 2:
134
+ last_user_msg = chat["history"][-2]["content"]
135
+ return last_user_msg, "Ready to edit & re-run"
136
+ return "", "No previous prompt"
137
+
138
+ def update_token_display(user_chats, current_title):
139
+ total = 0
140
+ for chat in user_chats or []:
141
+ if chat["title"] == current_title:
142
+ for msg in chat.get("history", []):
143
+ total += msg.get("tokens", 0)
144
+ return f"**Tokens used this chat:** {total:,}"
145
+
146
  # ================== HELPER: No conversion needed (Gradio expects messages format) ==================
147
  def format_history_for_chatbot(history):
148
  """Return history as-is (already dict format)"""
 
211
  if not current_model:
212
  gr.Warning("⚠️ Load a model first!")
213
  return chatbot
214
+
215
+ # Cooldown check
216
+ ok, new_time = enforce_cooldown(last_interaction_time.value)
217
+ if not ok:
218
  return chatbot
219
+ last_interaction_time.value = new_time
220
+
221
+ is_generating.value = True
222
+ stop_btn.visible = True
223
 
 
224
  internal_history = chatbot[:] if chatbot else []
225
 
 
226
  try:
227
  stream_gen = chat_stream(msg, internal_history, current_model, logged_in_username, user_chats_state, current_chat_title, mode_radio, auth_globals_state, file_upload, current_chat_context)
228
 
229
  for updated_history in stream_gen:
230
+ # Add approximate token count to last assistant message
231
+ if updated_history and updated_history[-1]["role"] == "assistant":
232
+ content = updated_history[-1]["content"]
233
+ tokens = len(content) // 4 + 50 # simple but good enough approximation
234
+ updated_history[-1]["tokens"] = tokens
235
+ yield updated_history
236
+
237
  except Exception as e:
238
+ gr.Warning(f"⚠️ Error: {str(e)[:200]}")
239
+ finally:
240
+ is_generating.value = False
241
+ stop_btn.visible = False
242
+
243
+ # Update token display
244
+ return token_display.update(value=update_token_display(user_chats_state, current_chat_title))
245
 
246
 
247
  # ================== GUI ==================
 
260
  auth_globals_state = gr.State(auth_globals)
261
  coding_files_state = gr.State({}) # { "filename.py": {"content": "...", "language": "python"} }
262
  current_file_name = gr.State(None)
263
+ last_interaction_time = gr.State(0.0) # for 3-second cooldown
264
+ is_generating = gr.State(False) # for Stop button
265
  status_label = gr.Markdown("⚠️ No model loaded. Login + create/select a chat to begin.", elem_id="status-bold") # Made more prominent
266
 
267
 
 
335
  )
336
  send_btn = gr.Button("➤", variant="primary", scale=1)
337
 
338
+ with gr.Row():
339
+ delete_last_btn = gr.Button("🗑️ Delete Last Message", variant="stop", size="sm")
340
+ edit_last_btn = gr.Button("✏️ Edit & Re-run Last Prompt", variant="secondary", size="sm")
341
+ stop_btn = gr.Button("⏹️ Stop Generation", variant="stop", visible=False)
342
+
343
+ # Token display (optional but useful)
344
+ token_display = gr.Markdown("**Tokens used this chat:** 0", visible=False)
345
+
346
  # Authentication (clean version - no phone/OTP)
347
  with gr.Row():
348
  username_input = gr.Textbox(label="Username (will be forced lowercase)", scale=2, placeholder="admin")
 
387
  confirm_delete_btn.click(delete_account, [confirm_username_input, logged_in_username, auth_globals_state], [status_label, logged_in_username, logout_btn, delete_acc_btn, confirm_row, user_chats_state, current_chat_title, chatbot, chat_dropdown, chat_context_tb, save_context_btn])
388
 
389
  save_context_btn.click(save_chat_context, [chat_context_tb, user_chats_state, current_chat_title, logged_in_username], [user_chats_state, status_label])
390
+
391
+ # Cooldown + action buttons
392
+ delete_last_btn.click(
393
+ delete_last_message,
394
+ [user_chats_state, current_chat_title, logged_in_username, auth_globals_state],
395
+ [user_chats_state, status_label]
396
+ ).then(
397
+ lambda: gr.update(visible=True), None, token_display
398
+ ).then(update_token_display, [user_chats_state, current_chat_title], token_display)
399
+
400
+ edit_last_btn.click(
401
+ edit_last_prompt,
402
+ [user_chats_state, current_chat_title],
403
+ [msg, status_label]
404
+ )
405
+
406
+ stop_btn.click(
407
+ lambda: (False, gr.update(visible=False)),
408
+ None,
409
+ [is_generating, stop_btn]
410
+ )
411
+
412
+ # Show token display in Coding Mode and after first message
413
+ mode_radio.change(
414
+ lambda m: gr.update(visible=(m == "💻 Coding Mode")),
415
+ mode_radio,
416
+ token_display
417
+ )
418
 
419
  msg.submit(
420
  handle_chat,