minhahwang Copilot commited on
Commit
df70548
Β·
1 Parent(s): 97b533c

fix: remove trigger word, always auto-submit on recording stop

Browse files

- Remove trigger phrase logic (answer me, etc.)
- Wire both .stop_recording() and .change() for reliability
- Answer generates automatically when user stops talking
- No manual button click needed for voice questions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Files changed (1) hide show
  1. app.py +14 -32
app.py CHANGED
@@ -542,7 +542,7 @@ with gr.Blocks(title="MomsVoice", css=css_code) as demo:
542
  with gr.Group(visible=False) as qa_input_group:
543
  question_audio = gr.Audio(
544
  sources=["microphone"], type="filepath",
545
- label="🎀 Ask your question, then say 'answer me' to get the answer",
546
  show_label=True, streaming=False,
547
  elem_id="qa_audio_input",
548
  )
@@ -1019,10 +1019,7 @@ with gr.Blocks(title="MomsVoice", css=css_code) as demo:
1019
  }"""
1020
  )
1021
 
1022
- # 9. Submit question
1023
- # Trigger phrase: user says "answer me" to signal end of question
1024
- _TRIGGER_PHRASES = ["answer me", "answer this", "tell me"]
1025
-
1026
  def handle_question_submit(question_txt, question_audio_path, paragraphs, slider_val, profile_id):
1027
  q_txt = (question_txt or "").strip()
1028
  has_audio = question_audio_path is not None and question_audio_path != ""
@@ -1046,27 +1043,6 @@ with gr.Blocks(title="MomsVoice", css=css_code) as demo:
1046
  except Exception as e:
1047
  q_text = f"(transcription failed: {e})"
1048
 
1049
- # Check for trigger phrase β€” if not found in voice input, wait for it
1050
- q_lower = q_text.lower().strip()
1051
- has_trigger = any(trigger in q_lower for trigger in _TRIGGER_PHRASES)
1052
-
1053
- if has_audio and not q_txt and not has_trigger:
1054
- # No trigger phrase detected β€” show transcription and wait
1055
- safe_q = html.escape(q_text)
1056
- waiting_html = f"""
1057
- <div style="padding: 12px; background: rgba(245,132,31,0.1); border: 1px solid rgba(245,132,31,0.3); border-radius: 10px; font-size: 12px; color: #f5841f;">
1058
- 🎀 Heard: &ldquo;<em>{safe_q}</em>&rdquo;<br>
1059
- <span style="font-size: 11px; color: #94a3b8;">Say <strong>&ldquo;answer me&rdquo;</strong> to get the answer, or keep recording.</span>
1060
- </div>
1061
- """
1062
- return gr.HTML(value=waiting_html, visible=True), gr.Audio(visible=False)
1063
-
1064
- # Strip trigger phrase from the question text
1065
- for trigger in _TRIGGER_PHRASES:
1066
- q_text = re.sub(rf'\b{trigger}\b[.!?,\s]*', '', q_text, flags=re.IGNORECASE).strip()
1067
- if not q_text:
1068
- q_text = "What happens next in the story?"
1069
-
1070
  # Step 10: Generate grounded answer from story context using Qwen
1071
  current_idx = int(slider_val) if slider_val else 0
1072
  try:
@@ -1124,17 +1100,23 @@ with gr.Blocks(title="MomsVoice", css=css_code) as demo:
1124
  outputs=[answer_display, answer_audio]
1125
  )
1126
 
1127
- # Auto-submit when voice recording completes
1128
- # .stop_recording may fire before audio value is committed in Gradio 5.35
1129
- # .change fires after the value is set β€” use it with a guard to avoid triggering on clear
1130
- def auto_submit_on_audio_change(audio_path, question_txt, paragraphs, slider_val, profile_id):
1131
- """Auto-submit only when a new recording is available (not on clear)."""
1132
  if not audio_path:
1133
  return gr.update(), gr.update()
1134
  return handle_question_submit(question_txt, audio_path, paragraphs, slider_val, profile_id)
1135
 
 
 
 
 
 
 
 
 
1136
  question_audio.change(
1137
- auto_submit_on_audio_change,
1138
  inputs=[question_audio, question_text, paragraphs_state, timeline_slider, voice_profile_state],
1139
  outputs=[answer_display, answer_audio]
1140
  )
 
542
  with gr.Group(visible=False) as qa_input_group:
543
  question_audio = gr.Audio(
544
  sources=["microphone"], type="filepath",
545
+ label="🎀 Ask your question β€” answer generates automatically when you stop",
546
  show_label=True, streaming=False,
547
  elem_id="qa_audio_input",
548
  )
 
1019
  }"""
1020
  )
1021
 
1022
+ # 9. Submit question β€” always auto-submits when recording stops
 
 
 
1023
  def handle_question_submit(question_txt, question_audio_path, paragraphs, slider_val, profile_id):
1024
  q_txt = (question_txt or "").strip()
1025
  has_audio = question_audio_path is not None and question_audio_path != ""
 
1043
  except Exception as e:
1044
  q_text = f"(transcription failed: {e})"
1045
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1046
  # Step 10: Generate grounded answer from story context using Qwen
1047
  current_idx = int(slider_val) if slider_val else 0
1048
  try:
 
1100
  outputs=[answer_display, answer_audio]
1101
  )
1102
 
1103
+ # Auto-submit when voice recording completes β€” use BOTH events for reliability
1104
+ def auto_submit_on_audio(audio_path, question_txt, paragraphs, slider_val, profile_id):
1105
+ """Auto-submit when a recording is available."""
 
 
1106
  if not audio_path:
1107
  return gr.update(), gr.update()
1108
  return handle_question_submit(question_txt, audio_path, paragraphs, slider_val, profile_id)
1109
 
1110
+ # .stop_recording fires when user clicks stop or silence detected
1111
+ question_audio.stop_recording(
1112
+ auto_submit_on_audio,
1113
+ inputs=[question_audio, question_text, paragraphs_state, timeline_slider, voice_profile_state],
1114
+ outputs=[answer_display, answer_audio]
1115
+ )
1116
+
1117
+ # .change fires after audio value is committed β€” backup in case stop_recording misses
1118
  question_audio.change(
1119
+ auto_submit_on_audio,
1120
  inputs=[question_audio, question_text, paragraphs_state, timeline_slider, voice_profile_state],
1121
  outputs=[answer_display, answer_audio]
1122
  )