Luigi commited on
Commit
fd70375
·
1 Parent(s): 9ac7f36
Files changed (1) hide show
  1. app.py +30 -18
app.py CHANGED
@@ -511,6 +511,9 @@ def chat_response(user_msg, chat_history, system_prompt,
511
  in_thought = False
512
  assistant_message_started = False
513
 
 
 
 
514
  # Stream tokens
515
  for chunk in streamer:
516
  # Check for cancellation signal
@@ -554,12 +557,12 @@ def chat_response(user_msg, chat_history, system_prompt,
554
  continue
555
 
556
  # Stream answer
557
- if not answer_buf and not assistant_message_started:
558
  history.append({'role': 'assistant', 'content': ''})
559
  assistant_message_started = True
560
 
561
  answer_buf += text
562
- history[-1]['content'] = answer_buf
563
  yield history, debug
564
 
565
  gen_thread.join()
@@ -625,27 +628,32 @@ with gr.Blocks(title="LLM Inference with ZeroGPU") as demo:
625
 
626
  # Group all inputs for cleaner event handling
627
  chat_inputs = [txt, chat, sys_prompt, search_chk, mr, mc, model_dd, max_tok, temp, k, p, rp, st]
628
- # Group all UI components that change state
629
- interactive_components = [txt, submit_btn, cancel_btn, chat, dbg]
630
 
631
  def submit_and_manage_ui(user_msg, chat_history, *args):
632
  """
633
- An orchestrator function that manages the UI state and calls the backend chat function.
634
  It uses a try...finally block to ensure the UI is always reset.
635
  """
636
- # Immediately update UI to a "generating" state
 
 
 
 
 
 
 
 
637
  yield {
638
- # Add the user's message to the chat and a placeholder for the response
639
- chat: chat_history + [[user_msg, None]],
640
  txt: gr.update(value="", interactive=False),
641
  submit_btn: gr.update(interactive=False),
642
  cancel_btn: gr.update(visible=True),
643
  }
644
 
645
  try:
646
- # Package the arguments for the backend function
647
  backend_args = [user_msg, chat_history] + list(args)
648
- # Stream the response from the backend
649
  for response_chunk in chat_response(*backend_args):
650
  yield {
651
  chat: response_chunk[0],
@@ -653,8 +661,14 @@ with gr.Blocks(title="LLM Inference with ZeroGPU") as demo:
653
  }
654
  except Exception as e:
655
  print(f"An error occurred during generation: {e}")
 
 
 
 
 
 
656
  finally:
657
- # Always reset the UI to an "idle" state, regardless of completion or cancellation
658
  print("Resetting UI state.")
659
  yield {
660
  txt: gr.update(interactive=True),
@@ -667,22 +681,20 @@ with gr.Blocks(title="LLM Inference with ZeroGPU") as demo:
667
  cancel_event.set()
668
  print("Cancellation signal sent.")
669
 
670
- # Event for submitting text via Enter key
671
  submit_event = txt.submit(
672
  fn=submit_and_manage_ui,
673
  inputs=chat_inputs,
674
- outputs=interactive_components,
675
  )
676
-
677
- # Event for submitting text via the "Submit" button
678
  submit_btn.click(
679
  fn=submit_and_manage_ui,
680
  inputs=chat_inputs,
681
- outputs=interactive_components,
682
  )
683
 
684
- # Event for the "Cancel" button. It calls the flag-setting function
685
- # and, crucially, cancels the long-running submit_event.
686
  cancel_btn.click(
687
  fn=set_cancel_flag,
688
  cancels=[submit_event]
 
511
  in_thought = False
512
  assistant_message_started = False
513
 
514
+ # First yield contains the user message
515
+ yield history, debug
516
+
517
  # Stream tokens
518
  for chunk in streamer:
519
  # Check for cancellation signal
 
557
  continue
558
 
559
  # Stream answer
560
+ if not assistant_message_started:
561
  history.append({'role': 'assistant', 'content': ''})
562
  assistant_message_started = True
563
 
564
  answer_buf += text
565
+ history[-1]['content'] = answer_buf.strip()
566
  yield history, debug
567
 
568
  gen_thread.join()
 
628
 
629
  # Group all inputs for cleaner event handling
630
  chat_inputs = [txt, chat, sys_prompt, search_chk, mr, mc, model_dd, max_tok, temp, k, p, rp, st]
631
+ # Group all UI components that can be updated.
632
+ ui_components = [chat, dbg, txt, submit_btn, cancel_btn]
633
 
634
  def submit_and_manage_ui(user_msg, chat_history, *args):
635
  """
636
+ Orchestrator function that manages UI state and calls the backend chat function.
637
  It uses a try...finally block to ensure the UI is always reset.
638
  """
639
+ if not user_msg.strip():
640
+ # If the message is empty, do nothing.
641
+ # We yield an empty dict to avoid any state changes.
642
+ yield {}
643
+ return
644
+
645
+ # 1. Update UI to "generating" state.
646
+ # Crucially, we do NOT update the `chat` component here, as the backend
647
+ # will provide the correctly formatted history in the first response chunk.
648
  yield {
 
 
649
  txt: gr.update(value="", interactive=False),
650
  submit_btn: gr.update(interactive=False),
651
  cancel_btn: gr.update(visible=True),
652
  }
653
 
654
  try:
655
+ # 2. Call the backend and stream updates
656
  backend_args = [user_msg, chat_history] + list(args)
 
657
  for response_chunk in chat_response(*backend_args):
658
  yield {
659
  chat: response_chunk[0],
 
661
  }
662
  except Exception as e:
663
  print(f"An error occurred during generation: {e}")
664
+ # If an error happens, add it to the chat history to inform the user.
665
+ error_history = (chat_history or []) + [
666
+ {'role': 'user', 'content': user_msg},
667
+ {'role': 'assistant', 'content': f"**An error occurred:** {str(e)}"}
668
+ ]
669
+ yield {chat: error_history}
670
  finally:
671
+ # 3. ALWAYS reset the UI to an "idle" state upon completion, error, or cancellation.
672
  print("Resetting UI state.")
673
  yield {
674
  txt: gr.update(interactive=True),
 
681
  cancel_event.set()
682
  print("Cancellation signal sent.")
683
 
684
+ # Event for submitting text via Enter key or Submit button
685
  submit_event = txt.submit(
686
  fn=submit_and_manage_ui,
687
  inputs=chat_inputs,
688
+ outputs=ui_components,
689
  )
 
 
690
  submit_btn.click(
691
  fn=submit_and_manage_ui,
692
  inputs=chat_inputs,
693
+ outputs=ui_components,
694
  )
695
 
696
+ # Event for the "Cancel" button.
697
+ # It calls the flag-setting function and cancels the long-running submit_event.
698
  cancel_btn.click(
699
  fn=set_cancel_flag,
700
  cancels=[submit_event]