haepa_mac commited on
Commit
19faf7a
·
1 Parent(s): 698b201

Simplify chat tab: Replace persona list with JSON upload for easy testing

Browse files
Files changed (1) hide show
  1. app.py +100 -103
app.py CHANGED
@@ -379,84 +379,13 @@ def export_persona_to_json(persona):
379
  print(f"JSON 내보내기 오류: {error_msg}")
380
  return None, f"❌ JSON 내보내기 중 오류 발생: {str(e)}"
381
 
382
- def get_saved_personas():
383
- """저장된 페르소나 목록 가져오기"""
384
- try:
385
- personas = list_personas()
386
- df_data = []
387
- for i, persona in enumerate(personas):
388
- df_data.append([
389
- i,
390
- persona["name"],
391
- persona["type"],
392
- persona["created_at"]
393
- ])
394
- return df_data, personas
395
- except Exception as e:
396
- print(f"페르소나 목록 로딩 오류: {str(e)}")
397
- return [], []
398
 
399
- def load_persona_from_selection(selected_row, personas_list):
400
- """선택된 페르소나 로드"""
401
- if selected_row is None or len(selected_row) == 0:
402
- return None, "선택된 페르소나가 없습니다.", {}, {}, None, [], [], [], ""
403
-
404
- try:
405
- # DataFrame에서 선택된 행의 인덱스 추출
406
- if hasattr(selected_row, 'index'):
407
- selected_index = selected_row.index[0]
408
- else:
409
- selected_index = 0
410
-
411
- if selected_index >= len(personas_list):
412
- return None, "잘못된 선택입니다.", {}, {}, None, [], [], [], ""
413
-
414
- filepath = personas_list[selected_index]["filepath"]
415
- persona = load_persona(filepath)
416
-
417
- if not persona:
418
- return None, "페르소나 로딩에 실패했습니다.", {}, {}, None, [], [], [], ""
419
-
420
- basic_info = {
421
- "이름": persona.get("기본정보", {}).get("이름", "Unknown"),
422
- "유형": persona.get("기본정보", {}).get("유형", "Unknown"),
423
- "설명": persona.get("기본정보", {}).get("설명", "")
424
- }
425
-
426
- personality_traits = persona.get("성격특성", {})
427
- humor_chart = plot_humor_matrix(persona.get("유머매트릭스", {}))
428
-
429
- attractive_flaws_df = []
430
- contradictions_df = []
431
- personality_variables_df = []
432
-
433
- if "매력적결함" in persona:
434
- flaws = persona["매력적결함"]
435
- attractive_flaws_df = [[flaw, "매력 증가"] for flaw in flaws]
436
-
437
- if "모순적특성" in persona:
438
- contradictions = persona["모순적특성"]
439
- contradictions_df = [[contradiction, "복잡성 증가"] for contradiction in contradictions]
440
-
441
- if "성격변수127" in persona:
442
- variables = persona["성격변수127"]
443
- if isinstance(variables, dict):
444
- personality_variables_df = [[var_name, score, VARIABLE_DESCRIPTIONS.get(var_name, "")]
445
- for var_name, score in variables.items()]
446
-
447
- # 로드된 페르소나 인사말
448
- persona_name = basic_info.get("이름", "친구")
449
- greeting = f"반가워! 나는 {persona_name}이야. 다시 만나서 기뻐! 😊"
450
-
451
- return (persona, f"✅ {persona['기본정보']['이름']}을(를) 로드했습니다.",
452
- basic_info, personality_traits, humor_chart, attractive_flaws_df,
453
- contradictions_df, personality_variables_df, greeting)
454
-
455
- except Exception as e:
456
- import traceback
457
- error_msg = traceback.format_exc()
458
- print(f"로딩 오류: {error_msg}")
459
- return None, f"❌ 로딩 중 오류 발생: {str(e)}", {}, {}, None, [], [], [], ""
460
 
461
  def chat_with_loaded_persona(persona, user_message, chat_history=None):
462
  """페르소나와 대화"""
@@ -478,6 +407,48 @@ def chat_with_loaded_persona(persona, user_message, chat_history=None):
478
  chat_history.append([user_message, f"대화 중 오류가 발생했습니다: {str(e)}"])
479
  return chat_history, ""
480
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  # 메인 인터페이스 생성
482
  def create_main_interface():
483
  # State 변수들 - 올바른 방식으로 생성
@@ -567,18 +538,25 @@ def create_main_interface():
567
  with gr.Tab("대화하기", id="chat"):
568
  with gr.Row():
569
  with gr.Column(scale=1):
570
- gr.Markdown("### 페르소나 불러오기")
571
- refresh_btn = gr.Button("목록 고침", variant="secondary")
572
- persona_table = gr.Dataframe(
573
- headers=["ID", "이름", "유형", "생성날짜"],
574
- label="저장된 페르소나",
575
- interactive=False
 
576
  )
577
- load_btn = gr.Button("선택한 페르소나 불러오기", variant="primary")
578
  load_status = gr.Markdown("")
 
 
 
 
 
 
579
 
580
  with gr.Column(scale=1):
581
- gr.Markdown("### 대화")
582
  # Gradio 4.x 호환을 위해 명시적으로 type 지정
583
  chatbot = gr.Chatbot(height=400, label="대화", type="tuples")
584
  with gr.Row():
@@ -588,6 +566,13 @@ def create_main_interface():
588
  lines=2
589
  )
590
  send_btn = gr.Button("전송", variant="primary")
 
 
 
 
 
 
 
591
 
592
  # 이벤트 핸들러
593
  create_btn.click(
@@ -622,25 +607,15 @@ def create_main_interface():
622
  outputs=[download_file]
623
  )
624
 
625
- refresh_btn.click(
626
- fn=get_saved_personas,
627
- outputs=[persona_table, personas_list]
628
- )
629
-
630
- load_btn.click(
631
- fn=load_persona_from_selection,
632
- inputs=[persona_table, personas_list],
633
  outputs=[
634
- current_persona, load_status, basic_info_output, personality_traits_output,
635
- humor_chart_output, attractive_flaws_output, contradictions_output,
636
- personality_variables_output, persona_greeting
637
  ]
638
- ).then(
639
- fn=generate_personality_chart,
640
- inputs=[current_persona],
641
- outputs=[personality_chart_output]
642
  )
643
 
 
644
  send_btn.click(
645
  fn=chat_with_loaded_persona,
646
  inputs=[current_persona, message_input, chatbot],
@@ -653,10 +628,32 @@ def create_main_interface():
653
  outputs=[chatbot, message_input]
654
  )
655
 
656
- # 로드 시 페르소나 목록 로드
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
657
  app.load(
658
- fn=get_saved_personas,
659
- outputs=[persona_table, personas_list]
660
  )
661
 
662
  return app
 
379
  print(f"JSON 내보내기 오류: {error_msg}")
380
  return None, f"❌ JSON 내보내기 중 오류 발생: {str(e)}"
381
 
382
+ # def get_saved_personas():
383
+ # """저장된 페르소나 목록 가져오기 - 더 이상 사용하지 않음"""
384
+ # return [], []
 
 
 
 
 
 
 
 
 
 
 
 
 
385
 
386
+ # def load_persona_from_selection(selected_row, personas_list):
387
+ # """선택된 페르소나 로드 - 더 이상 사용하지 않음"""
388
+ # return None, "이 기능은 더 이상 사용하지 않습니다. JSON 업로드를 사용하세요.", {}, {}, None, [], [], [], ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
 
390
  def chat_with_loaded_persona(persona, user_message, chat_history=None):
391
  """페르소나와 대화"""
 
407
  chat_history.append([user_message, f"대화 중 오류가 발생했습니다: {str(e)}"])
408
  return chat_history, ""
409
 
410
+ def import_persona_from_json(json_file):
411
+ """JSON 파일에서 페르소나 가져오기"""
412
+ if json_file is None:
413
+ return None, "JSON 파일을 업로드해주세요.", "", {}
414
+
415
+ try:
416
+ # JSON 파일 읽기
417
+ if hasattr(json_file, 'name'):
418
+ # 파일 객체인 경우
419
+ with open(json_file.name, 'r', encoding='utf-8') as f:
420
+ persona_data = json.load(f)
421
+ else:
422
+ # 파일 경로인 경우
423
+ with open(json_file, 'r', encoding='utf-8') as f:
424
+ persona_data = json.load(f)
425
+
426
+ # 페르소나 데이터 검증
427
+ if not isinstance(persona_data, dict) or "기본정보" not in persona_data:
428
+ return None, "❌ 올바른 페르소나 JSON 파일이 아닙니다.", "", {}
429
+
430
+ # 기본 정보 추출
431
+ basic_info = {
432
+ "이름": persona_data.get("기본정보", {}).get("이름", "Unknown"),
433
+ "유형": persona_data.get("기본정보", {}).get("유형", "Unknown"),
434
+ "설명": persona_data.get("기본정보", {}).get("설명", "")
435
+ }
436
+
437
+ # 로드된 페르소나 인사말
438
+ persona_name = basic_info.get("이름", "친구")
439
+ greeting = f"### 🤖 {persona_name}\n\n안녕! 나는 **{persona_name}**이야. JSON에서 다시 깨어났어! 대화해보자~ 😊"
440
+
441
+ return (persona_data, f"✅ {persona_name} 페르소나를 JSON에서 불러왔습니다!",
442
+ greeting, basic_info)
443
+
444
+ except json.JSONDecodeError:
445
+ return None, "❌ JSON 파일 형식이 올바르지 않습니다.", "", {}
446
+ except Exception as e:
447
+ import traceback
448
+ error_msg = traceback.format_exc()
449
+ print(f"JSON 불러오기 오류: {error_msg}")
450
+ return None, f"❌ JSON 불러오기 중 오류 발생: {str(e)}", "", {}
451
+
452
  # 메인 인터페이스 생성
453
  def create_main_interface():
454
  # State 변수들 - 올바른 방식으로 생성
 
538
  with gr.Tab("대화하기", id="chat"):
539
  with gr.Row():
540
  with gr.Column(scale=1):
541
+ gr.Markdown("### 📁 페르소나 불러오기")
542
+ gr.Markdown("JSON 파일을 업드하여 페르소나를 불러와 대화를 시작하세요.")
543
+
544
+ json_upload = gr.File(
545
+ label="페르소나 JSON 파일 업로드",
546
+ file_types=[".json"],
547
+ type="filepath"
548
  )
549
+ import_btn = gr.Button("JSON에서 페르소나 불러오기", variant="primary", size="lg")
550
  load_status = gr.Markdown("")
551
+
552
+ # 현재 로드된 페르소나 정보 표시
553
+ with gr.Group():
554
+ gr.Markdown("### 🤖 현재 페르소나")
555
+ chat_persona_greeting = gr.Markdown("", elem_classes=["persona-greeting"])
556
+ current_persona_info = gr.JSON(label="현재 페르소나 정보", visible=False)
557
 
558
  with gr.Column(scale=1):
559
+ gr.Markdown("### 💬 대화")
560
  # Gradio 4.x 호환을 위해 명시적으로 type 지정
561
  chatbot = gr.Chatbot(height=400, label="대화", type="tuples")
562
  with gr.Row():
 
566
  lines=2
567
  )
568
  send_btn = gr.Button("전송", variant="primary")
569
+
570
+ # 대화 관련 버튼들
571
+ with gr.Row():
572
+ clear_btn = gr.Button("대화 초기화", variant="secondary", size="sm")
573
+ example_btn1 = gr.Button("\"안녕!\"", variant="outline", size="sm")
574
+ example_btn2 = gr.Button("\"너는 누구야?\"", variant="outline", size="sm")
575
+ example_btn3 = gr.Button("\"뭘 좋아해?\"", variant="outline", size="sm")
576
 
577
  # 이벤트 핸들러
578
  create_btn.click(
 
607
  outputs=[download_file]
608
  )
609
 
610
+ import_btn.click(
611
+ fn=import_persona_from_json,
612
+ inputs=[json_upload],
 
 
 
 
 
613
  outputs=[
614
+ current_persona, load_status, chat_persona_greeting, current_persona_info
 
 
615
  ]
 
 
 
 
616
  )
617
 
618
+ # 대화 관련 이벤트 핸들러
619
  send_btn.click(
620
  fn=chat_with_loaded_persona,
621
  inputs=[current_persona, message_input, chatbot],
 
628
  outputs=[chatbot, message_input]
629
  )
630
 
631
+ # 대화 초기화
632
+ clear_btn.click(
633
+ fn=lambda: [],
634
+ outputs=[chatbot]
635
+ )
636
+
637
+ # 예시 메시지 버튼들
638
+ example_btn1.click(
639
+ fn=lambda: "안녕!",
640
+ outputs=[message_input]
641
+ )
642
+
643
+ example_btn2.click(
644
+ fn=lambda: "너는 누구야?",
645
+ outputs=[message_input]
646
+ )
647
+
648
+ example_btn3.click(
649
+ fn=lambda: "뭘 좋아해?",
650
+ outputs=[message_input]
651
+ )
652
+
653
+ # 앱 로드 시 페르소나 목록 로드 (백엔드에서 사용)
654
  app.load(
655
+ fn=lambda: [],
656
+ outputs=[personas_list]
657
  )
658
 
659
  return app