quyk67uet commited on
Commit
b15b3d8
·
1 Parent(s): d9b1e6c

Update 100

Browse files
Files changed (2) hide show
  1. app.py +64 -44
  2. pages/multiagent_system.py +0 -62
app.py CHANGED
@@ -18,7 +18,6 @@ from sympy import Rem
18
  from PIL import Image
19
  import io
20
  from faster_whisper import WhisperModel
21
- from st_audiorec import st_audiorec
22
  import tempfile
23
 
24
  load_dotenv()
@@ -376,28 +375,31 @@ def load_resources():
376
  **NHIỆM VỤ:**
377
  Dựa trên **chủ đề yếu** của học sinh và **danh sách video** được cung cấp, hãy thực hiện 2 việc:
378
 
379
- 1. **Tạo 2 Bài tập Mới:**
380
- - Các bài tập phải liên quan trực tiếp đến chủ đề yếu.
381
- - Độ khó tương đương chương trình lớp 9.
382
- - Bài tập phải hoàn toàn mới, không được trùng lặp với các ví dụ phổ biến.
383
- 2. **Đề xuất 1 Video Phù hợp nhất:**
384
- - Chọn ra MỘT video từ danh sách có nội dung liên quan chặt chẽ nhất đến chủ đề yếu.
385
 
386
  **THÔNG TIN ĐẦU VÀO:**
387
- - **Chủ đề yếu của học sinh:** '{{ student_weakness }}'
388
- - **Danh sách video có sẵn (JSON):** {{ video_cheatsheet_json }}
389
 
390
  **YÊU CẦU OUTPUT:**
391
- Chỉ trả lời theo định dạng Markdown dưới đây, không thêm bất kỳ lời dẫn hay giải thích nào khác.
392
 
393
- ### 🎯 BÀI TẬP CỦNG CỐ
394
- 1. **Bài 1:** [Nội dung câu hỏi bài tập 1]
395
- 2. **Bài 2:** [Nội dung câu hỏi bài tập 2]
396
 
 
 
 
 
 
397
 
398
- ### 📹 VIDEO ĐỀ XUẤT
399
  **[Tên video]**
400
- 🎬 Link: https://www.youtube.com/playlist?list=PL5q2T2FxzK7XY4s9FqDi6KCFEpGr2LX2D"""
 
401
 
402
  insight_template = """
403
  Bạn là một chuyên gia phân tích giáo dục. Nhiệm vụ của bạn là đọc kỹ đoạn hội thoại và xác định chính xác những khái niệm toán học mà học sinh đang hiểu sai.
@@ -583,16 +585,19 @@ def load_resources():
583
  "whisper_model": whisper_model
584
  }
585
 
586
- def transcribe_audio(audio_bytes: bytes, whisper_model: WhisperModel) -> str:
587
  """
588
- Nhận dữ liệu audio bytes, lưu vào file tạm, chuyển đổi thành văn bản bằng Faster Whisper.
589
- Phiên bản này đã sửa lỗi Permission Denied trên Windows.
590
  """
591
- if not audio_bytes:
592
  return ""
593
 
594
  tmp_file_path = ""
595
  try:
 
 
 
596
  with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmpfile:
597
  tmpfile.write(audio_bytes)
598
  tmp_file_path = tmpfile.name
@@ -1132,6 +1137,10 @@ def main():
1132
  welcome_msg = "Xin chào! Tôi là gia sư AI của bạn 😊. Hôm nay chúng ta cùng học Toán nhé!"
1133
  st.session_state.messages.append({"role": "assistant", "content": welcome_msg, "intent": "greeting_social"})
1134
 
 
 
 
 
1135
  # Container để chứa các tin nhắn chat
1136
  chat_placeholder = st.container()
1137
  with chat_placeholder:
@@ -1140,13 +1149,17 @@ def main():
1140
  # Sử dụng hàm render tùy chỉnh
1141
  render_chat_message(msg_data["content"], is_user, key=f"msg_{i}")
1142
 
1143
-
1144
- st.markdown("#### Hoặc nói chuyện trực tiếp với gia sư:")
1145
- audio_bytes = st_audiorec() # Component ghi âm
1146
-
1147
- # Khởi tạo session state để theo dõi audio đã xử lý
1148
- if "processed_audio_hash" not in st.session_state:
1149
- st.session_state.processed_audio_hash = None
 
 
 
 
1150
 
1151
  # 2. Form Nhập liệu cho Text và Ảnh
1152
  with st.form(key="chat_form", clear_on_submit=True):
@@ -1159,26 +1172,32 @@ def main():
1159
 
1160
  submit_button = st.form_submit_button(label="Gửi")
1161
 
1162
-
1163
  final_user_text = ""
1164
  final_image_data = None
1165
 
1166
- current_audio_hash = None
1167
- is_new_audio = False
1168
-
1169
- if audio_bytes and len(audio_bytes) > 0:
1170
- current_audio_hash = hashlib.md5(audio_bytes).hexdigest()
1171
- is_new_audio = current_audio_hash != st.session_state.processed_audio_hash
1172
-
1173
- if is_new_audio and audio_bytes:
1174
- with st.spinner("🎧 Đang xử lý giọng nói..."):
1175
- transcribed_text = transcribe_audio(audio_bytes, resources["whisper_model"])
1176
- if transcribed_text and transcribed_text.strip() and len(transcribed_text.strip()) > 1:
1177
- final_user_text = transcribed_text
1178
- st.session_state.processed_audio_hash = current_audio_hash
1179
- else:
1180
- st.session_state.processed_audio_hash = current_audio_hash
 
 
 
 
 
 
1181
 
 
1182
  elif submit_button:
1183
  final_user_text = user_text
1184
  if uploaded_image:
@@ -1286,7 +1305,6 @@ def main():
1286
  print(f"ERROR: [Proactive Flow] Đã xảy ra lỗi: {str(e)}")
1287
  proactive_typing_placeholder.empty()
1288
 
1289
-
1290
  # Rerun để cập nhật giao diện
1291
  st.rerun()
1292
 
@@ -1298,7 +1316,7 @@ def main():
1298
  if st.button("Đăng xuất", use_container_width=True):
1299
  supabase.auth.sign_out()
1300
  # Xóa các session state liên quan đến user
1301
- keys_to_delete = ["user", "messages"]
1302
  for key in keys_to_delete:
1303
  if key in st.session_state:
1304
  del st.session_state[key]
@@ -1308,6 +1326,8 @@ def main():
1308
 
1309
  if st.button("🗑️ Xóa lịch sử chat", use_container_width=True):
1310
  st.session_state.messages = []
 
 
1311
  st.rerun()
1312
 
1313
  if __name__ == "__main__":
 
18
  from PIL import Image
19
  import io
20
  from faster_whisper import WhisperModel
 
21
  import tempfile
22
 
23
  load_dotenv()
 
375
  **NHIỆM VỤ:**
376
  Dựa trên **chủ đề yếu** của học sinh và **danh sách video** được cung cấp, hãy thực hiện 2 việc:
377
 
378
+ 1. **Tạo 2 Bài tập Mới:**
379
+ - Các bài tập phải liên quan trực tiếp đến chủ đề yếu.
380
+ - Độ khó tương đương chương trình lớp 9.
381
+ - Bài tập phải hoàn toàn mới, không được trùng lặp với các ví dụ phổ biến.
382
+ 2. **Đề xuất 1 Video Phù hợp nhất:**
383
+ - Chọn ra MỘT video từ danh sách có nội dung liên quan chặt chẽ nhất đến chủ đề yếu.
384
 
385
  **THÔNG TIN ĐẦU VÀO:**
386
+ - **Chủ đề yếu của học sinh:** '{{ student_weakness }}'
387
+ - **Danh sách video có sẵn (JSON):** {{ video_cheatsheet_json }}
388
 
389
  **YÊU CẦU OUTPUT:**
390
+ Trả lời theo định dạng sau (không thêm lời dẫn):
391
 
392
+ 🎯 **BÀI TẬP CỦNG CỐ**
 
 
393
 
394
+ **Bài 1:** [Nội dung câu hỏi bài tập 1]
395
+
396
+ **Bài 2:** [Nội dung câu hỏi bài tập 2]
397
+
398
+ 📹 **VIDEO ĐỀ XUẤT**
399
 
 
400
  **[Tên video]**
401
+ 🎬 Link: https://www.youtube.com/playlist?list=PL5q2T2FxzK7XY4s9FqDi6KCFEpGr2LX2D
402
+ """
403
 
404
  insight_template = """
405
  Bạn là một chuyên gia phân tích giáo dục. Nhiệm vụ của bạn là đọc kỹ đoạn hội thoại và xác định chính xác những khái niệm toán học mà học sinh đang hiểu sai.
 
585
  "whisper_model": whisper_model
586
  }
587
 
588
+ def transcribe_audio(audio_file, whisper_model: WhisperModel) -> str:
589
  """
590
+ Nhận audio file từ st.audio_input chuyển đổi thành văn bản bằng Faster Whisper.
591
+ Phiên bản được cập nhật cho môi trường deployment.
592
  """
593
+ if not audio_file:
594
  return ""
595
 
596
  tmp_file_path = ""
597
  try:
598
+ # Đọc audio file từ st.audio_input (UploadedFile object)
599
+ audio_bytes = audio_file.read()
600
+
601
  with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmpfile:
602
  tmpfile.write(audio_bytes)
603
  tmp_file_path = tmpfile.name
 
1137
  welcome_msg = "Xin chào! Tôi là gia sư AI của bạn 😊. Hôm nay chúng ta cùng học Toán nhé!"
1138
  st.session_state.messages.append({"role": "assistant", "content": welcome_msg, "intent": "greeting_social"})
1139
 
1140
+ # Khởi tạo session state để theo dõi audio đã xử lý
1141
+ if "processed_audio_ids" not in st.session_state:
1142
+ st.session_state.processed_audio_ids = set()
1143
+
1144
  # Container để chứa các tin nhắn chat
1145
  chat_placeholder = st.container()
1146
  with chat_placeholder:
 
1149
  # Sử dụng hàm render tùy chỉnh
1150
  render_chat_message(msg_data["content"], is_user, key=f"msg_{i}")
1151
 
1152
+ # Audio input section with better error handling
1153
+ st.markdown("#### Hoặc ghi âm giọng nói:")
1154
+
1155
+ # Check if running in secure context for microphone access
1156
+ audio_input = None
1157
+ try:
1158
+ # Use Streamlit's built-in audio_input which is more stable
1159
+ audio_input = st.audio_input("🎤 Nhấn để ghi âm", help="Ghi âm câu hỏi của bạn bằng tiếng Việt")
1160
+ except Exception as e:
1161
+ st.warning("⚠️ Không thể truy cập microphone. Vui lòng sử dụng form nhập text bên dưới.")
1162
+ print(f"DEBUG: Audio input error: {e}")
1163
 
1164
  # 2. Form Nhập liệu cho Text và Ảnh
1165
  with st.form(key="chat_form", clear_on_submit=True):
 
1172
 
1173
  submit_button = st.form_submit_button(label="Gửi")
1174
 
 
1175
  final_user_text = ""
1176
  final_image_data = None
1177
 
1178
+ # Handle audio input if available - với logic tránh xử lý lặp lại
1179
+ if audio_input is not None:
1180
+ # Tạo unique ID cho audio file dựa trên file_id và size
1181
+ audio_id = f"{audio_input.file_id}_{audio_input.size}" if hasattr(audio_input, 'file_id') and hasattr(audio_input, 'size') else f"{id(audio_input)}_{len(audio_input.getvalue())}"
1182
+
1183
+ # Chỉ xử nếu audio này chưa được xử lý
1184
+ if audio_id not in st.session_state.processed_audio_ids:
1185
+ with st.spinner("🎧 Đang xử lý giọng nói..."):
1186
+ transcribed_text = transcribe_audio(audio_input, resources["whisper_model"])
1187
+ if transcribed_text and transcribed_text.strip() and len(transcribed_text.strip()) > 1:
1188
+ final_user_text = transcribed_text
1189
+ st.success(f"✅ Đã nhận diện: {transcribed_text}")
1190
+ # Đánh dấu audio này đã được xử lý
1191
+ st.session_state.processed_audio_ids.add(audio_id)
1192
+ else:
1193
+ st.warning("⚠️ Không nhận diện được nội dung. Vui lòng thử lại hoặc sử dụng text input.")
1194
+ # Vẫn đánh dấu để tránh xử lý lại
1195
+ st.session_state.processed_audio_ids.add(audio_id)
1196
+ else:
1197
+ # Audio đã được xử lý, không làm gì cả
1198
+ print(f"DEBUG: Audio {audio_id} đã được xử lý trước đó, bỏ qua.")
1199
 
1200
+ # Handle form submission
1201
  elif submit_button:
1202
  final_user_text = user_text
1203
  if uploaded_image:
 
1305
  print(f"ERROR: [Proactive Flow] Đã xảy ra lỗi: {str(e)}")
1306
  proactive_typing_placeholder.empty()
1307
 
 
1308
  # Rerun để cập nhật giao diện
1309
  st.rerun()
1310
 
 
1316
  if st.button("Đăng xuất", use_container_width=True):
1317
  supabase.auth.sign_out()
1318
  # Xóa các session state liên quan đến user
1319
+ keys_to_delete = ["user", "messages", "processed_audio_ids"]
1320
  for key in keys_to_delete:
1321
  if key in st.session_state:
1322
  del st.session_state[key]
 
1326
 
1327
  if st.button("🗑️ Xóa lịch sử chat", use_container_width=True):
1328
  st.session_state.messages = []
1329
+ # Cũng xóa audio đã xử lý để có thể ghi âm lại
1330
+ st.session_state.processed_audio_ids = set()
1331
  st.rerun()
1332
 
1333
  if __name__ == "__main__":
pages/multiagent_system.py CHANGED
@@ -3,7 +3,6 @@ import os
3
  from supabase import create_client, Client
4
  from datetime import datetime
5
  import json
6
- import time
7
 
8
  # Thiết lập page config
9
  st.set_page_config(
@@ -12,52 +11,6 @@ st.set_page_config(
12
  layout="wide"
13
  )
14
 
15
- # Trick để fix layout issue khi deploy
16
- def fix_layout_trick():
17
- """
18
- Trick để fix layout issue trên Hugging Face Spaces
19
- """
20
- # Thêm JavaScript để force reflow sau khi page load
21
- st.markdown("""
22
- <script>
23
- // Force reflow after page loads
24
- setTimeout(function() {
25
- window.dispatchEvent(new Event('resize'));
26
- document.body.style.display = 'none';
27
- document.body.offsetHeight; // trigger reflow
28
- document.body.style.display = '';
29
- }, 100);
30
-
31
- // Additional reflow after 500ms
32
- setTimeout(function() {
33
- window.dispatchEvent(new Event('resize'));
34
- }, 500);
35
- </script>
36
- """, unsafe_allow_html=True)
37
-
38
- # CSS để đảm bảo smooth loading
39
- st.markdown("""
40
- <style>
41
- /* Ensure smooth loading */
42
- .main .block-container {
43
- opacity: 0;
44
- animation: fadeIn 0.5s ease-in-out forwards;
45
- animation-delay: 0.1s;
46
- }
47
-
48
- @keyframes fadeIn {
49
- from { opacity: 0; }
50
- to { opacity: 1; }
51
- }
52
-
53
- /* Force proper rendering */
54
- .stApp {
55
- transform: translateZ(0);
56
- backface-visibility: hidden;
57
- }
58
- </style>
59
- """, unsafe_allow_html=True)
60
-
61
  def init_supabase_client() -> Client:
62
  """
63
  Khởi tạo Supabase client
@@ -125,8 +78,6 @@ def display_agents():
125
  margin-bottom: 2rem;
126
  overflow: hidden;
127
  border: 1px solid rgba(0,0,0,0.05);
128
- transform: translateZ(0);
129
- will-change: transform;
130
  }
131
 
132
  .agent-header {
@@ -731,19 +682,6 @@ def main():
731
  """
732
  Hàm chính của trang Multi-Agent System
733
  """
734
- # Áp dụng trick fix layout ngay đầu
735
- fix_layout_trick()
736
-
737
- # Thêm một sidebar trick để trigger re-render
738
- with st.sidebar:
739
- st.markdown("""
740
- <div style="position: absolute; left: -9999px; opacity: 0;">
741
- <button id="layout-trigger" onclick="window.dispatchEvent(new Event('resize'));">
742
- Trigger Layout
743
- </button>
744
- </div>
745
- """, unsafe_allow_html=True)
746
-
747
  # Hiển thị kiến trúc hệ thống
748
  display_system_architecture()
749
 
 
3
  from supabase import create_client, Client
4
  from datetime import datetime
5
  import json
 
6
 
7
  # Thiết lập page config
8
  st.set_page_config(
 
11
  layout="wide"
12
  )
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def init_supabase_client() -> Client:
15
  """
16
  Khởi tạo Supabase client
 
78
  margin-bottom: 2rem;
79
  overflow: hidden;
80
  border: 1px solid rgba(0,0,0,0.05);
 
 
81
  }
82
 
83
  .agent-header {
 
682
  """
683
  Hàm chính của trang Multi-Agent System
684
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
685
  # Hiển thị kiến trúc hệ thống
686
  display_system_architecture()
687