LearningnRunning commited on
Commit
72123d0
Β·
1 Parent(s): 7df763f

feat: Enhance chat message handling in app.py with improved session ID validation and error handling. Update SupabaseService to log session creation attempts and handle exceptions gracefully. Ensure user and AI messages are only saved when session ID is present.

Browse files
Files changed (2) hide show
  1. app.py +60 -20
  2. services/supabase_service.py +12 -5
app.py CHANGED
@@ -394,6 +394,9 @@ def handle_chat_message(message, chat_history, session_id, student_id, scenario_
394
  if not message or not message.strip():
395
  return chat_history, ""
396
 
 
 
 
397
  # μ‹œλ‚˜λ¦¬μ˜€κ°€ μ„ νƒλ˜μ§€ μ•Šμ€ 경우
398
  if not scenario_id or scenario_id == "":
399
  warning_msg = """
@@ -422,8 +425,15 @@ EMR 정보 쑰회 νƒ­μ—μ„œ μ‹œλ‚˜λ¦¬μ˜€λ₯Ό λ‹€μ‹œ μ„ νƒν•΄μ£Όμ„Έμš”.
422
  """
423
  return chat_history + [[message, error_msg]], ""
424
 
425
- # μ‚¬μš©μž λ©”μ‹œμ§€ μ €μž₯
426
- supabase_service.save_chat_message(session_id, student_id, scenario_id, "user", message)
 
 
 
 
 
 
 
427
 
428
  # μ‹œλ‚˜λ¦¬μ˜€ 및 ν™˜μž 데이터 μ€€λΉ„
429
  scenario_data = {
@@ -456,8 +466,15 @@ EMR 정보 쑰회 νƒ­μ—μ„œ μ‹œλ‚˜λ¦¬μ˜€λ₯Ό λ‹€μ‹œ μ„ νƒν•΄μ£Όμ„Έμš”.
456
  # Gemini AI ν”Όλ“œλ°± 생성
457
  ai_response = evaluator.chat_feedback(message, history_for_gemini, scenario_data, patient_data)
458
 
459
- # AI 응닡 μ €μž₯
460
- supabase_service.save_chat_message(session_id, student_id, scenario_id, "assistant", ai_response)
 
 
 
 
 
 
 
461
 
462
  # μ±„νŒ… νžˆμŠ€ν† λ¦¬ μ—…λ°μ΄νŠΈ
463
  updated_history = chat_history + [[message, ai_response]]
@@ -779,12 +796,19 @@ with gr.Blocks(title="κ°„ν˜Έ μΈμˆ˜μΈκ³„ ꡐ윑 ν”Œλž«νΌ", theme=gr.themes.Sof
779
 
780
  if scenario:
781
  # μƒˆ μ±„νŒ… μ„Έμ…˜ 생성
782
- supabase_service = SupabaseService()
783
- new_session_id = supabase_service.create_chat_session(student_id, scenario_id)
784
-
785
- scenario_info = f"**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: {scenario.title}"
786
-
787
- return emr_html, new_session_id, scenario_id, scenario_info
 
 
 
 
 
 
 
788
 
789
  return emr_html, "", scenario_id, "**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: μ„ νƒλ˜μ§€ μ•ŠμŒ"
790
 
@@ -819,10 +843,15 @@ with gr.Blocks(title="κ°„ν˜Έ μΈμˆ˜μΈκ³„ ꡐ윑 ν”Œλž«νΌ", theme=gr.themes.Sof
819
  # λŒ€ν™” μ΄ˆκΈ°ν™”
820
  def clear_chat(student_id, scenario_id):
821
  """λŒ€ν™” μ΄ˆκΈ°ν™” 및 μƒˆ μ„Έμ…˜ 생성"""
822
- supabase_service = SupabaseService()
823
- new_session_id = supabase_service.create_chat_session(student_id, scenario_id)
824
-
825
- return [], new_session_id
 
 
 
 
 
826
 
827
  clear_btn.click(
828
  fn=clear_chat,
@@ -864,8 +893,9 @@ with gr.Blocks(title="κ°„ν˜Έ μΈμˆ˜μΈκ³„ ꡐ윑 ν”Œλž«νΌ", theme=gr.themes.Sof
864
  """μ•± 초기 λ‘œλ“œ μ‹œ μ‹€ν–‰"""
865
  default_scenario = "S001_D0_ER_WARD"
866
 
867
- # student_id_stateλ₯Ό 초기 ID둜 μ„€μ •
868
- initial_student_id = student_id_input.value
 
869
 
870
  # Supabase μ„œλΉ„μŠ€κ°€ 있으면 μ‹œλ‚˜λ¦¬μ˜€ 데이터 λ‘œλ“œ
871
  if supabase_service:
@@ -874,16 +904,26 @@ with gr.Blocks(title="κ°„ν˜Έ μΈμˆ˜μΈκ³„ ꡐ윑 ν”Œλž«νΌ", theme=gr.themes.Sof
874
  if scenario:
875
  # κΈ°λ³Έ μ‹œλ‚˜λ¦¬μ˜€ 정보 ν‘œμ‹œ
876
  scenario_info = f"**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: {scenario.title}"
877
- return emr_html, default_scenario, scenario_info, initial_student_id, "student"
 
 
 
 
 
 
 
 
 
 
878
  else:
879
- return emr_html, default_scenario, "**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: μ„ νƒλ˜μ§€ μ•ŠμŒ", initial_student_id, "student"
880
  else:
881
- return "", default_scenario, "**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: μ„ νƒλ˜μ§€ μ•ŠμŒ", initial_student_id, "student"
882
 
883
  # 초기 λ‘œλ“œ
884
  app.load(
885
  fn=initialize_app,
886
- outputs=[emr_display, scenario_id_state, current_scenario_display, student_id_state, user_role_state]
887
  )
888
 
889
 
 
394
  if not message or not message.strip():
395
  return chat_history, ""
396
 
397
+ # μ„Έμ…˜ ID 확인
398
+ print(f"πŸ’¬ μ±„νŒ… λ©”μ‹œμ§€ 처리: session_id={session_id}, student_id={student_id}, scenario_id={scenario_id}")
399
+
400
  # μ‹œλ‚˜λ¦¬μ˜€κ°€ μ„ νƒλ˜μ§€ μ•Šμ€ 경우
401
  if not scenario_id or scenario_id == "":
402
  warning_msg = """
 
425
  """
426
  return chat_history + [[message, error_msg]], ""
427
 
428
+ # μ‚¬μš©μž λ©”μ‹œμ§€ μ €μž₯ (session_idκ°€ μžˆλŠ” κ²½μš°μ—λ§Œ)
429
+ if session_id:
430
+ try:
431
+ supabase_service.save_chat_message(session_id, student_id, scenario_id, "user", message)
432
+ print(f"βœ… μ‚¬μš©μž λ©”μ‹œμ§€ μ €μž₯ μ™„λ£Œ: session_id={session_id}")
433
+ except Exception as e:
434
+ print(f"⚠️ μ‚¬μš©μž λ©”μ‹œμ§€ μ €μž₯ μ‹€νŒ¨: {e}")
435
+ else:
436
+ print(f"⚠️ session_idκ°€ λΉ„μ–΄μžˆμ–΄ λ©”μ‹œμ§€ μ €μž₯ μ‹€νŒ¨")
437
 
438
  # μ‹œλ‚˜λ¦¬μ˜€ 및 ν™˜μž 데이터 μ€€λΉ„
439
  scenario_data = {
 
466
  # Gemini AI ν”Όλ“œλ°± 생성
467
  ai_response = evaluator.chat_feedback(message, history_for_gemini, scenario_data, patient_data)
468
 
469
+ # AI 응닡 μ €μž₯ (session_idκ°€ μžˆλŠ” κ²½μš°μ—λ§Œ)
470
+ if session_id:
471
+ try:
472
+ supabase_service.save_chat_message(session_id, student_id, scenario_id, "assistant", ai_response)
473
+ print(f"βœ… AI 응닡 μ €μž₯ μ™„λ£Œ: session_id={session_id}")
474
+ except Exception as e:
475
+ print(f"⚠️ AI 응닡 μ €μž₯ μ‹€νŒ¨: {e}")
476
+ else:
477
+ print(f"⚠️ session_idκ°€ λΉ„μ–΄μžˆμ–΄ AI 응닡 μ €μž₯ μ‹€νŒ¨")
478
 
479
  # μ±„νŒ… νžˆμŠ€ν† λ¦¬ μ—…λ°μ΄νŠΈ
480
  updated_history = chat_history + [[message, ai_response]]
 
796
 
797
  if scenario:
798
  # μƒˆ μ±„νŒ… μ„Έμ…˜ 생성
799
+ try:
800
+ supabase_service = SupabaseService()
801
+ new_session_id = supabase_service.create_chat_session(student_id, scenario_id)
802
+ print(f"πŸ“ μ‹œλ‚˜λ¦¬μ˜€ 선택 μ‹œ μ„Έμ…˜ 생성: session_id={new_session_id}")
803
+
804
+ scenario_info = f"**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: {scenario.title}"
805
+
806
+ return emr_html, new_session_id, scenario_id, scenario_info
807
+ except Exception as e:
808
+ print(f"⚠️ μ„Έμ…˜ 생성 μ‹€νŒ¨: {e}")
809
+ import traceback
810
+ traceback.print_exc()
811
+ return emr_html, "", scenario_id, "**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: μ„ νƒλ˜μ§€ μ•ŠμŒ"
812
 
813
  return emr_html, "", scenario_id, "**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: μ„ νƒλ˜μ§€ μ•ŠμŒ"
814
 
 
843
  # λŒ€ν™” μ΄ˆκΈ°ν™”
844
  def clear_chat(student_id, scenario_id):
845
  """λŒ€ν™” μ΄ˆκΈ°ν™” 및 μƒˆ μ„Έμ…˜ 생성"""
846
+ try:
847
+ supabase_service = SupabaseService()
848
+ new_session_id = supabase_service.create_chat_session(student_id, scenario_id)
849
+ print(f"πŸ”„ λŒ€ν™” μ΄ˆκΈ°ν™” - μƒˆ μ„Έμ…˜ 생성: {new_session_id}")
850
+
851
+ return [], new_session_id
852
+ except Exception as e:
853
+ print(f"⚠️ λŒ€ν™” μ΄ˆκΈ°ν™” 쀑 μ„Έμ…˜ 생성 μ‹€νŒ¨: {e}")
854
+ return [], ""
855
 
856
  clear_btn.click(
857
  fn=clear_chat,
 
893
  """μ•± 초기 λ‘œλ“œ μ‹œ μ‹€ν–‰"""
894
  default_scenario = "S001_D0_ER_WARD"
895
 
896
+ # student_id_stateλ₯Ό 초기 ID둜 μ„€μ • (λͺ¨λ“ˆ 레벨 λ³€μˆ˜ μ‚¬μš©)
897
+ current_student_id = initial_student_id
898
+ initial_session_id = ""
899
 
900
  # Supabase μ„œλΉ„μŠ€κ°€ 있으면 μ‹œλ‚˜λ¦¬μ˜€ 데이터 λ‘œλ“œ
901
  if supabase_service:
 
904
  if scenario:
905
  # κΈ°λ³Έ μ‹œλ‚˜λ¦¬μ˜€ 정보 ν‘œμ‹œ
906
  scenario_info = f"**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: {scenario.title}"
907
+
908
+ # 초기 μ„Έμ…˜ 생성
909
+ try:
910
+ initial_session_id = supabase_service.create_chat_session(current_student_id, default_scenario)
911
+ print(f"βœ… 초기 μ„Έμ…˜ 생성 μ™„λ£Œ: {initial_session_id}")
912
+ except Exception as e:
913
+ print(f"⚠️ 초기 μ„Έμ…˜ 생성 μ‹€νŒ¨: {e}")
914
+ import traceback
915
+ traceback.print_exc()
916
+
917
+ return emr_html, default_scenario, scenario_info, current_student_id, "student", initial_session_id
918
  else:
919
+ return emr_html, default_scenario, "**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: μ„ νƒλ˜μ§€ μ•ŠμŒ", current_student_id, "student", ""
920
  else:
921
+ return "", default_scenario, "**ν˜„μž¬ μ‹œλ‚˜λ¦¬μ˜€**: μ„ νƒλ˜μ§€ μ•ŠμŒ", current_student_id, "student", ""
922
 
923
  # 초기 λ‘œλ“œ
924
  app.load(
925
  fn=initialize_app,
926
+ outputs=[emr_display, scenario_id_state, current_scenario_display, student_id_state, user_role_state, session_id_state]
927
  )
928
 
929
 
services/supabase_service.py CHANGED
@@ -518,19 +518,26 @@ class SupabaseService:
518
  'session_id': session_id,
519
  'student_id': student_id,
520
  'scenario_id': scenario_id,
521
- 'status': 'active',
522
- 'started_at': 'now()'
523
  }
524
 
 
 
525
  # μ„Έμ…˜ ν…Œμ΄λΈ”μ΄ μžˆλ‹€λ©΄ μ €μž₯ (μ—†μœΌλ©΄ κ·Έλƒ₯ ID만 λ°˜ν™˜)
526
  try:
527
- self.client.table('sessions').insert(session_data).execute()
528
- except Exception:
 
529
  # sessions ν…Œμ΄λΈ”μ΄ 없을 경우 λ¬΄μ‹œ
530
- pass
 
 
531
 
532
  except Exception as e:
533
  print(f"⚠️ μ„Έμ…˜ μ €μž₯ μ‹€νŒ¨ (ID만 μ‚¬μš©): {e}")
 
 
534
 
535
  return session_id
536
 
 
518
  'session_id': session_id,
519
  'student_id': student_id,
520
  'scenario_id': scenario_id,
521
+ 'status': 'active'
522
+ # started_at은 ν…Œμ΄λΈ” DEFAULT NOW()둜 μžλ™ 섀정됨
523
  }
524
 
525
+ print(f"πŸ“ μ„Έμ…˜ 생성 μ‹œλ„: session_id={session_id}, student_id={student_id}, scenario_id={scenario_id}")
526
+
527
  # μ„Έμ…˜ ν…Œμ΄λΈ”μ΄ μžˆλ‹€λ©΄ μ €μž₯ (μ—†μœΌλ©΄ κ·Έλƒ₯ ID만 λ°˜ν™˜)
528
  try:
529
+ result = self.client.table('sessions').insert(session_data).execute()
530
+ print(f"βœ… μ„Έμ…˜ μ €μž₯ 성곡: {result.data}")
531
+ except Exception as insert_error:
532
  # sessions ν…Œμ΄λΈ”μ΄ 없을 경우 λ¬΄μ‹œ
533
+ print(f"⚠️ sessions ν…Œμ΄λΈ” insert μ‹€νŒ¨ (계속 μ§„ν–‰): {insert_error}")
534
+ import traceback
535
+ traceback.print_exc()
536
 
537
  except Exception as e:
538
  print(f"⚠️ μ„Έμ…˜ μ €μž₯ μ‹€νŒ¨ (ID만 μ‚¬μš©): {e}")
539
+ import traceback
540
+ traceback.print_exc()
541
 
542
  return session_id
543