mramirez2001 commited on
Commit
4df54ca
verified
1 Parent(s): 343b081

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -17
app.py CHANGED
@@ -80,7 +80,12 @@ def extract_word_level_features(audio_path):
80
 
81
  def chat_interaction(audio_input, history_state):
82
  if not api_key_found: raise gr.Error("OpenAI API key not found.")
83
- if audio_input is None: return history_state, history_state, gr.Markdown(visible=False), gr.Markdown(visible=False)
 
 
 
 
 
84
 
85
  sr, y = audio_input; temp_audio_path = "temp_audio_chat.wav"; sf.write(temp_audio_path, y, sr)
86
  user_text = client.audio.transcriptions.create(model="whisper-1", file=open(temp_audio_path, "rb")).text
@@ -90,16 +95,17 @@ def chat_interaction(audio_input, history_state):
90
 
91
  history_state.append({"role": "user", "content": user_text})
92
 
93
- chat_display = [(history_state[i]['content'], history_state[i+1]['content']) for i in range(1, len(history_state), 2)]
94
-
95
- if len(history_state) < 10:
 
96
  response = client.chat.completions.create(model="gpt-4o", messages=history_state, temperature=0.7)
97
  ai_response = response.choices[0].message.content
98
  history_state.append({"role": "assistant", "content": ai_response})
99
- chat_display.append((user_text, ai_response))
100
- return chat_display, history_state, gr.Markdown(visible=False), gr.Markdown(visible=False)
101
- else:
102
- print("Generating final evaluation...");
103
  final_messages = [{"role": "system", "content": FINAL_EVALUATION_SYSTEM_PROMPT}] + history_state[1:]
104
  response = client.chat.completions.create(model="gpt-4o", response_format={"type": "json_object"}, messages=final_messages)
105
  try:
@@ -108,10 +114,16 @@ def chat_interaction(audio_input, history_state):
108
  for item in fb_en.get('word_by_word_feedback', []): md_en += f"- **{item['word']}**: {item['feedback']}\n"
109
  fb_es = result.get('feedback_es', {}); md_es = f"## Reporte Final (Nivel MCERL: {result.get('cefr_level', 'N/A')})\n### Fortalezas\n{fb_es.get('fortalezas', '')}\n### 脕reas a Mejorar\n{fb_es.get('areas_a_mejorar', '')}\n### Retroalimentaci贸n por Palabra\n"
110
  for item in fb_es.get('feedback_por_palabra', []): md_es += f"- **{item['palabra']}**: {item['feedback']}\n"
111
- chat_display.append((user_text, "Thank you for the conversation! Here is your final report below."))
112
- return chat_display, [], gr.Markdown(value=md_en, visible=True), gr.Markdown(value=md_es, visible=True)
113
- except (json.JSONDecodeError, KeyError) as e:
114
- print(f"Error parsing final report: {e}"); return [], [], gr.Markdown(value="Error generating report.", visible=True), gr.Markdown(visible=False)
 
 
 
 
 
 
115
 
116
  def run_sentence_evaluation(audio_input, reference_transcript):
117
  if not api_key_found: raise gr.Error("OpenAI API key not found.")
@@ -143,21 +155,54 @@ def run_sentence_evaluation(audio_input, reference_transcript):
143
  print(f"Error processing API response: {e}"); error_msg = "The API response was not in the expected format."
144
  return 0, "Error", error_msg, ""
145
 
146
- # --- 3. INTERFAZ DE GRADIO CON PESTA脩AS ---
147
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
148
  gr.Markdown("# 馃嚞馃嚙 AI English Speaking Practice & Assessment")
 
149
  with gr.Tabs():
150
- # --- PESTA脩A 1: CHAT AI ---
151
  with gr.TabItem("Pr谩ctica Conversacional (Chat AI)"):
152
  with gr.Row():
153
  with gr.Column(scale=2):
154
  chatbot = gr.Chatbot(value=[(None, "Hi there! I'm Alex. How are you doing today?")], label="Conversation with your AI Tutor", height=500)
155
  audio_in_chat = gr.Audio(sources=["microphone"], type="numpy", label="Record your response")
 
 
 
 
 
156
  with gr.Column(scale=1):
157
- gr.Markdown("### Final Report"); feedback_en_out = gr.Markdown(label="English Feedback", visible=False); feedback_es_out = gr.Markdown(label="Retroalimentaci贸n en Espa帽ol", visible=False)
158
- history = gr.State([])
159
- audio_in_chat.stop_recording(fn=chat_interaction, inputs=[audio_in_chat, history], outputs=[chatbot, history, feedback_en_out, feedback_es_out])
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  # --- PESTA脩A 2: EVALUACI脫N POR FRASE ---
162
  with gr.TabItem("Evaluaci贸n por Frase"):
163
  TONGUE_TWISTERS = ["Peter Piper picked a peck of pickled peppers.", "She sells seashells by the seashore.", "How much wood would a woodchuck chuck if a woodchuck could chuck wood?", "Betty Botter bought some butter but she said the butter鈥檚 bitter.", "A proper copper coffee pot."]
 
80
 
81
  def chat_interaction(audio_input, history_state):
82
  if not api_key_found: raise gr.Error("OpenAI API key not found.")
83
+ if audio_input is None:
84
+ user_turns = len(history_state[1:]) // 2 if history_state else 0
85
+ responses_remaining = 5 - user_turns
86
+ # Muestra el estado actual sin hacer nada si no hay audio
87
+ chat_display = [(history_state[i]['content'], history_state[i+1]['content']) for i in range(1, len(history_state), 2)]
88
+ return chat_display, history_state, f"Responses remaining: {responses_remaining}", gr.update(visible=False), gr.update(visible=False)
89
 
90
  sr, y = audio_input; temp_audio_path = "temp_audio_chat.wav"; sf.write(temp_audio_path, y, sr)
91
  user_text = client.audio.transcriptions.create(model="whisper-1", file=open(temp_audio_path, "rb")).text
 
95
 
96
  history_state.append({"role": "user", "content": user_text})
97
 
98
+ user_turns = (len(history_state) - 1) // 2
99
+ responses_remaining = 5 - user_turns
100
+
101
+ if user_turns < 5:
102
  response = client.chat.completions.create(model="gpt-4o", messages=history_state, temperature=0.7)
103
  ai_response = response.choices[0].message.content
104
  history_state.append({"role": "assistant", "content": ai_response})
105
+ chat_display = [(history_state[i]['content'], history_state[i+1]['content']) for i in range(1, len(history_state), 2)]
106
+ return chat_display, history_state, f"Responses remaining: {responses_remaining}", gr.update(visible=False), gr.update(visible=False)
107
+ else: # Turno 5: generar evaluaci贸n
108
+ print("Generating final evaluation...")
109
  final_messages = [{"role": "system", "content": FINAL_EVALUATION_SYSTEM_PROMPT}] + history_state[1:]
110
  response = client.chat.completions.create(model="gpt-4o", response_format={"type": "json_object"}, messages=final_messages)
111
  try:
 
114
  for item in fb_en.get('word_by_word_feedback', []): md_en += f"- **{item['word']}**: {item['feedback']}\n"
115
  fb_es = result.get('feedback_es', {}); md_es = f"## Reporte Final (Nivel MCERL: {result.get('cefr_level', 'N/A')})\n### Fortalezas\n{fb_es.get('fortalezas', '')}\n### 脕reas a Mejorar\n{fb_es.get('areas_a_mejorar', '')}\n### Retroalimentaci贸n por Palabra\n"
116
  for item in fb_es.get('feedback_por_palabra', []): md_es += f"- **{item['palabra']}**: {item['feedback']}\n"
117
+
118
+ chat_display = [(history_state[i]['content'], history_state[i+1]['content']) for i in range(1, len(history_state)-1, 2)]
119
+ chat_display.append((user_text, "Thank you! Your final report is now available on the right."))
120
+
121
+ # --- CAMBIO CLAVE: Reiniciamos el historial para la siguiente conversaci贸n ---
122
+ return chat_display, [], "Conversation finished!", gr.update(value=md_en, visible=True), gr.update(value=md_es, visible=True)
123
+ except Exception as e:
124
+ print(f"Error parsing final report: {e}")
125
+ chat_display = [(history_state[i]['content'], history_state[i+1]['content']) for i in range(1, len(history_state)-1, 2)]
126
+ return chat_display, [], "Error!", gr.update(value="Error generating report.", visible=True), gr.update(visible=False)
127
 
128
  def run_sentence_evaluation(audio_input, reference_transcript):
129
  if not api_key_found: raise gr.Error("OpenAI API key not found.")
 
155
  print(f"Error processing API response: {e}"); error_msg = "The API response was not in the expected format."
156
  return 0, "Error", error_msg, ""
157
 
158
+ # --- 3. INTERFAZ DE GRADIO CON PESTA脩AS (Con ajustes en la Pesta帽a 1) ---
159
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
160
  gr.Markdown("# 馃嚞馃嚙 AI English Speaking Practice & Assessment")
161
+
162
  with gr.Tabs():
163
+ # --- PESTA脩A 1: CHAT AI (CON MEJORAS) ---
164
  with gr.TabItem("Pr谩ctica Conversacional (Chat AI)"):
165
  with gr.Row():
166
  with gr.Column(scale=2):
167
  chatbot = gr.Chatbot(value=[(None, "Hi there! I'm Alex. How are you doing today?")], label="Conversation with your AI Tutor", height=500)
168
  audio_in_chat = gr.Audio(sources=["microphone"], type="numpy", label="Record your response")
169
+ with gr.Row():
170
+ counter_out = gr.Textbox(value="Responses remaining: 5", label="Conversation Progress", interactive=False)
171
+ # --- CAMBIO: Bot贸n para reiniciar la conversaci贸n completa ---
172
+ new_conversation_btn = gr.Button("New Conversation")
173
+
174
  with gr.Column(scale=1):
175
+ gr.Markdown("### Final Report")
176
+ feedback_en_out = gr.Markdown(label="English Feedback", visible=False)
177
+ feedback_es_out = gr.Markdown(label="Retroalimentaci贸n en Espa帽ol", visible=False)
178
 
179
+ history = gr.State([])
180
+
181
+ # Funci贸n para borrar el audio despu茅s de enviarlo (no es un bot贸n, es una acci贸n)
182
+ def clear_audio_input():
183
+ return None
184
+
185
+ # Funci贸n para reiniciar toda la conversaci贸n
186
+ def clear_conversation():
187
+ return [], [(None, "Hi there! I'm Alex. How are you doing today?")], "Responses remaining: 5", gr.update(visible=False), gr.update(visible=False), None
188
+
189
+ # --- CAMBIO: Se renombra el bot贸n y se conecta a la nueva funci贸n de reinicio ---
190
+ new_conversation_btn.click(
191
+ fn=clear_conversation,
192
+ inputs=[],
193
+ outputs=[history, chatbot, counter_out, feedback_en_out, feedback_es_out, audio_in_chat]
194
+ )
195
+
196
+ audio_in_chat.stop_recording(
197
+ fn=chat_interaction,
198
+ inputs=[audio_in_chat, history],
199
+ outputs=[chatbot, history, counter_out, feedback_en_out, feedback_es_out]
200
+ ).then(
201
+ fn=clear_audio_input,
202
+ inputs=[],
203
+ outputs=[audio_in_chat]
204
+ )
205
+
206
  # --- PESTA脩A 2: EVALUACI脫N POR FRASE ---
207
  with gr.TabItem("Evaluaci贸n por Frase"):
208
  TONGUE_TWISTERS = ["Peter Piper picked a peck of pickled peppers.", "She sells seashells by the seashore.", "How much wood would a woodchuck chuck if a woodchuck could chuck wood?", "Betty Botter bought some butter but she said the butter鈥檚 bitter.", "A proper copper coffee pot."]