akhaliq HF Staff commited on
Commit
221127d
·
verified ·
1 Parent(s): 98da568

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -18
app.py CHANGED
@@ -1,6 +1,6 @@
1
  import os
2
  import time
3
- from typing import List, Dict
4
 
5
  import torch
6
  import gradio as gr
@@ -32,6 +32,54 @@ if HF_TOKEN:
32
  print(f"Warning: Could not login to Hugging Face: {e}")
33
 
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  # =========================
36
  # Chat Model Wrapper
37
  # =========================
@@ -158,15 +206,14 @@ def clear_chat():
158
 
159
  def chat_fn(message, history, system_prompt, temperature):
160
  """Non-streaming chat handler (returns tuples)."""
 
 
 
161
  if not chat_model.model_loaded:
162
  return history + [[message, "Please wait for the model to load or reload the space."]]
163
 
164
- # Convert tuples history -> list of role dicts
165
- formatted_history = []
166
- for user_msg, assistant_msg in history:
167
- formatted_history.append({"role": "user", "content": user_msg})
168
- if assistant_msg:
169
- formatted_history.append({"role": "assistant", "content": assistant_msg})
170
 
171
  # Generate full response once
172
  response = chat_model.generate_response(message, formatted_history, system_prompt, temperature)
@@ -177,16 +224,15 @@ def chat_fn(message, history, system_prompt, temperature):
177
 
178
  def chat_stream_fn(message, history, system_prompt, temperature):
179
  """Streaming chat handler (tuples): generate once, then chunk out."""
 
 
 
180
  if not chat_model.model_loaded:
181
  yield history + [[message, "Please wait for the model to load or reload the space."]]
182
  return
183
 
184
- # Convert tuples history -> list of role dicts
185
- formatted_history = []
186
- for user_msg, assistant_msg in history:
187
- formatted_history.append({"role": "user", "content": user_msg})
188
- if assistant_msg:
189
- formatted_history.append({"role": "assistant", "content": assistant_msg})
190
 
191
  # Generate full response (GPU)
192
  full_response = chat_model.generate_response(
@@ -196,7 +242,6 @@ def chat_stream_fn(message, history, system_prompt, temperature):
196
  # Start new row and progressively fill assistant side
197
  base = history + [[message, ""]]
198
  if not isinstance(full_response, str):
199
- # In case of an error string (already str), we still stream it
200
  full_response = str(full_response)
201
 
202
  step = max(8, len(full_response) // 40) # ~40 chunks
@@ -274,8 +319,9 @@ with gr.Blocks(
274
  info="Show responses as they're being generated",
275
  )
276
 
277
- # Chatbot in TUPLES mode
278
  chatbot = gr.Chatbot(
 
279
  label="Chat History",
280
  height=500,
281
  show_copy_button=True,
@@ -291,17 +337,19 @@ with gr.Blocks(
291
  submit_btn = gr.Button("Send", variant="primary", scale=1)
292
  clear_btn = gr.Button("Clear", scale=0)
293
 
294
- # Wire events
295
  msg.submit(
296
  handle_chat,
297
  inputs=[msg, chatbot, system_prompt, temperature, streaming],
298
  outputs=[chatbot],
299
- )
 
300
  submit_btn.click(
301
  handle_chat,
302
  inputs=[msg, chatbot, system_prompt, temperature, streaming],
303
  outputs=[chatbot],
304
- )
 
305
  clear_btn.click(
306
  clear_chat,
307
  outputs=[chatbot, msg],
 
1
  import os
2
  import time
3
+ from typing import List, Dict, Tuple, Any
4
 
5
  import torch
6
  import gradio as gr
 
32
  print(f"Warning: Could not login to Hugging Face: {e}")
33
 
34
 
35
+ # =========================
36
+ # Utilities
37
+ # =========================
38
+ def tuples_from_messages(messages: List[Dict[str, Any]]) -> List[List[str]]:
39
+ """
40
+ Convert a Chatbot(type='messages') style history into tuples format
41
+ [[user, assistant], ...]. If already tuples-like, return as-is.
42
+ """
43
+ if not messages:
44
+ return []
45
+ # If already tuples-like (list with elements of length 2), return
46
+ if isinstance(messages[0], (list, tuple)) and len(messages[0]) == 2:
47
+ return [list(x) for x in messages]
48
+
49
+ # Otherwise, convert from [{"role": "...", "content": "..."}, ...]
50
+ pairs: List[List[str]] = []
51
+ last_user: str | None = None
52
+ for m in messages:
53
+ role = m.get("role")
54
+ content = m.get("content", "")
55
+ if role == "user":
56
+ last_user = content
57
+ elif role == "assistant":
58
+ if last_user is None:
59
+ # If assistant appears first (odd state), pair with empty user
60
+ pairs.append(["", content])
61
+ else:
62
+ pairs.append([last_user, content])
63
+ last_user = None
64
+ # If there's a dangling user without assistant, pair with empty string
65
+ if last_user is not None:
66
+ pairs.append([last_user, ""])
67
+ return pairs
68
+
69
+
70
+ def messages_from_tuples(history_tuples: List[List[str]]) -> List[Dict[str, str]]:
71
+ """
72
+ Convert tuples [[user, assistant], ...] into list of role dictionaries:
73
+ [{"role": "user", ...}, {"role": "assistant", ...}, ...]
74
+ """
75
+ messages: List[Dict[str, str]] = []
76
+ for u, a in history_tuples:
77
+ messages.append({"role": "user", "content": u})
78
+ if a:
79
+ messages.append({"role": "assistant", "content": a})
80
+ return messages
81
+
82
+
83
  # =========================
84
  # Chat Model Wrapper
85
  # =========================
 
206
 
207
  def chat_fn(message, history, system_prompt, temperature):
208
  """Non-streaming chat handler (returns tuples)."""
209
+ # DEFENSIVE: ensure tuples format
210
+ history = tuples_from_messages(history)
211
+
212
  if not chat_model.model_loaded:
213
  return history + [[message, "Please wait for the model to load or reload the space."]]
214
 
215
+ # Convert tuples -> role dicts for the model
216
+ formatted_history = messages_from_tuples(history)
 
 
 
 
217
 
218
  # Generate full response once
219
  response = chat_model.generate_response(message, formatted_history, system_prompt, temperature)
 
224
 
225
  def chat_stream_fn(message, history, system_prompt, temperature):
226
  """Streaming chat handler (tuples): generate once, then chunk out."""
227
+ # DEFENSIVE: ensure tuples format
228
+ history = tuples_from_messages(history)
229
+
230
  if not chat_model.model_loaded:
231
  yield history + [[message, "Please wait for the model to load or reload the space."]]
232
  return
233
 
234
+ # Convert tuples -> role dicts for the model
235
+ formatted_history = messages_from_tuples(history)
 
 
 
 
236
 
237
  # Generate full response (GPU)
238
  full_response = chat_model.generate_response(
 
242
  # Start new row and progressively fill assistant side
243
  base = history + [[message, ""]]
244
  if not isinstance(full_response, str):
 
245
  full_response = str(full_response)
246
 
247
  step = max(8, len(full_response) // 40) # ~40 chunks
 
319
  info="Show responses as they're being generated",
320
  )
321
 
322
+ # Chatbot in TUPLES mode (explicit)
323
  chatbot = gr.Chatbot(
324
+ type="tuples",
325
  label="Chat History",
326
  height=500,
327
  show_copy_button=True,
 
337
  submit_btn = gr.Button("Send", variant="primary", scale=1)
338
  clear_btn = gr.Button("Clear", scale=0)
339
 
340
+ # Wire events (also clear the input box after send)
341
  msg.submit(
342
  handle_chat,
343
  inputs=[msg, chatbot, system_prompt, temperature, streaming],
344
  outputs=[chatbot],
345
+ ).then(lambda: "", None, msg)
346
+
347
  submit_btn.click(
348
  handle_chat,
349
  inputs=[msg, chatbot, system_prompt, temperature, streaming],
350
  outputs=[chatbot],
351
+ ).then(lambda: "", None, msg)
352
+
353
  clear_btn.click(
354
  clear_chat,
355
  outputs=[chatbot, msg],